
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License.  You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*/

(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
    typeof define === 'function' && define.amd ? define(['exports'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.echarts = {}));
}(this, (function (exports) { 'use strict';

    /*! *****************************************************************************
    Copyright (c) Microsoft Corporation.

    Permission to use, copy, modify, and/or distribute this software for any
    purpose with or without fee is hereby granted.

    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
    REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
    AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
    INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
    LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
    OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
    PERFORMANCE OF THIS SOFTWARE.
    ***************************************************************************** */
    /* global Reflect, Promise */

    var extendStatics = function(d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };

    function __extends(d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    }

    var Browser = (function () {
        function Browser() {
            this.firefox = false;
            this.ie = false;
            this.edge = false;
            this.newEdge = false;
            this.weChat = false;
        }
        return Browser;
    }());
    var Env = (function () {
        function Env() {
            this.browser = new Browser();
            this.node = false;
            this.wxa = false;
            this.worker = false;
            this.svgSupported = false;
            this.touchEventsSupported = false;
            this.pointerEventsSupported = false;
            this.domSupported = false;
            this.transformSupported = false;
            this.transform3dSupported = false;
            this.hasGlobalWindow = typeof window !== 'undefined';
        }
        return Env;
    }());
    var env = new Env();
    if (typeof wx === 'object' && typeof wx.getSystemInfoSync === 'function') {
        env.wxa = true;
        env.touchEventsSupported = true;
    }
    else if (typeof document === 'undefined' && typeof self !== 'undefined') {
        env.worker = true;
    }
    else if (typeof navigator === 'undefined') {
        env.node = true;
        env.svgSupported = true;
    }
    else {
        detect(navigator.userAgent, env);
    }
    function detect(ua, env) {
        var browser = env.browser;
        var firefox = ua.match(/Firefox\/([\d.]+)/);
        var ie = ua.match(/MSIE\s([\d.]+)/)
            || ua.match(/Trident\/.+?rv:(([\d.]+))/);
        var edge = ua.match(/Edge?\/([\d.]+)/);
        var weChat = (/micromessenger/i).test(ua);
        if (firefox) {
            browser.firefox = true;
            browser.version = firefox[1];
        }
        if (ie) {
            browser.ie = true;
            browser.version = ie[1];
        }
        if (edge) {
            browser.edge = true;
            browser.version = edge[1];
            browser.newEdge = +edge[1].split('.')[0] > 18;
        }
        if (weChat) {
            browser.weChat = true;
        }
        env.svgSupported = typeof SVGRect !== 'undefined';
        env.touchEventsSupported = 'ontouchstart' in window && !browser.ie && !browser.edge;
        env.pointerEventsSupported = 'onpointerdown' in window
            && (browser.edge || (browser.ie && +browser.version >= 11));
        env.domSupported = typeof document !== 'undefined';
        var style = document.documentElement.style;
        env.transform3dSupported = ((browser.ie && 'transition' in style)
            || browser.edge
            || (('WebKitCSSMatrix' in window) && ('m11' in new WebKitCSSMatrix()))
            || 'MozPerspective' in style)
            && !('OTransition' in style);
        env.transformSupported = env.transform3dSupported
            || (browser.ie && +browser.version >= 9);
    }

    var DEFAULT_FONT_SIZE = 12;
    var DEFAULT_FONT_FAMILY = 'sans-serif';
    var DEFAULT_FONT = DEFAULT_FONT_SIZE + "px " + DEFAULT_FONT_FAMILY;
    var OFFSET = 20;
    var SCALE = 100;
    var defaultWidthMapStr = "007LLmW'55;N0500LLLLLLLLLL00NNNLzWW\\\\WQb\\0FWLg\\bWb\\WQ\\WrWWQ000CL5LLFLL0LL**F*gLLLL5F0LF\\FFF5.5N";
    function getTextWidthMap(mapStr) {
        var map = {};
        if (typeof JSON === 'undefined') {
            return map;
        }
        for (var i = 0; i < mapStr.length; i++) {
            var char = String.fromCharCode(i + 32);
            var size = (mapStr.charCodeAt(i) - OFFSET) / SCALE;
            map[char] = size;
        }
        return map;
    }
    var DEFAULT_TEXT_WIDTH_MAP = getTextWidthMap(defaultWidthMapStr);
    var platformApi = {
        createCanvas: function () {
            return typeof document !== 'undefined'
                && document.createElement('canvas');
        },
        measureText: (function () {
            var _ctx;
            var _cachedFont;
            return function (text, font) {
                if (!_ctx) {
                    var canvas = platformApi.createCanvas();
                    _ctx = canvas && canvas.getContext('2d');
                }
                if (_ctx) {
                    if (_cachedFont !== font) {
                        _cachedFont = _ctx.font = font || DEFAULT_FONT;
                    }
                    return _ctx.measureText(text);
                }
                else {
                    text = text || '';
                    font = font || DEFAULT_FONT;
                    var res = /^([0-9]*?)px$/.exec(font);
                    var fontSize = +(res && res[1]) || DEFAULT_FONT_SIZE;
                    var width = 0;
                    if (font.indexOf('mono') >= 0) {
                        width = fontSize * text.length;
                    }
                    else {
                        for (var i = 0; i < text.length; i++) {
                            var preCalcWidth = DEFAULT_TEXT_WIDTH_MAP[text[i]];
                            width += preCalcWidth == null ? fontSize : (preCalcWidth * fontSize);
                        }
                    }
                    return { width: width };
                }
            };
        })(),
        loadImage: function (src, onload, onerror) {
            var image = new Image();
            image.onload = onload;
            image.onerror = onerror;
            image.src = src;
            return image;
        }
    };
    function setPlatformAPI(newPlatformApis) {
        for (var key in platformApi) {
            if (newPlatformApis[key]) {
                platformApi[key] = newPlatformApis[key];
            }
        }
    }

    var BUILTIN_OBJECT = reduce([
        'Function',
        'RegExp',
        'Date',
        'Error',
        'CanvasGradient',
        'CanvasPattern',
        'Image',
        'Canvas'
    ], function (obj, val) {
        obj['[object ' + val + ']'] = true;
        return obj;
    }, {});
    var TYPED_ARRAY = reduce([
        'Int8',
        'Uint8',
        'Uint8Clamped',
        'Int16',
        'Uint16',
        'Int32',
        'Uint32',
        'Float32',
        'Float64'
    ], function (obj, val) {
        obj['[object ' + val + 'Array]'] = true;
        return obj;
    }, {});
    var objToString = Object.prototype.toString;
    var arrayProto = Array.prototype;
    var nativeForEach = arrayProto.forEach;
    var nativeFilter = arrayProto.filter;
    var nativeSlice = arrayProto.slice;
    var nativeMap = arrayProto.map;
    var ctorFunction = function () { }.constructor;
    var protoFunction = ctorFunction ? ctorFunction.prototype : null;
    var protoKey = '__proto__';
    var idStart = 0x0907;
    function guid() {
        return idStart++;
    }
    function logError() {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        if (typeof console !== 'undefined') {
            console.error.apply(console, args);
        }
    }
    function clone(source) {
        if (source == null || typeof source !== 'object') {
            return source;
        }
        var result = source;
        var typeStr = objToString.call(source);
        if (typeStr === '[object Array]') {
            if (!isPrimitive(source)) {
                result = [];
                for (var i = 0, len = source.length; i < len; i++) {
                    result[i] = clone(source[i]);
                }
            }
        }
        else if (TYPED_ARRAY[typeStr]) {
            if (!isPrimitive(source)) {
                var Ctor = source.constructor;
                if (Ctor.from) {
                    result = Ctor.from(source);
                }
                else {
                    result = new Ctor(source.length);
                    for (var i = 0, len = source.length; i < len; i++) {
                        result[i] = source[i];
                    }
                }
            }
        }
        else if (!BUILTIN_OBJECT[typeStr] && !isPrimitive(source) && !isDom(source)) {
            result = {};
            for (var key in source) {
                if (source.hasOwnProperty(key) && key !== protoKey) {
                    result[key] = clone(source[key]);
                }
            }
        }
        return result;
    }
    function merge(target, source, overwrite) {
        if (!isObject(source) || !isObject(target)) {
            return overwrite ? clone(source) : target;
        }
        for (var key in source) {
            if (source.hasOwnProperty(key) && key !== protoKey) {
                var targetProp = target[key];
                var sourceProp = source[key];
                if (isObject(sourceProp)
                    && isObject(targetProp)
                    && !isArray(sourceProp)
                    && !isArray(targetProp)
                    && !isDom(sourceProp)
                    && !isDom(targetProp)
                    && !isBuiltInObject(sourceProp)
                    && !isBuiltInObject(targetProp)
                    && !isPrimitive(sourceProp)
                    && !isPrimitive(targetProp)) {
                    merge(targetProp, sourceProp, overwrite);
                }
                else if (overwrite || !(key in target)) {
                    target[key] = clone(source[key]);
                }
            }
        }
        return target;
    }
    function mergeAll(targetAndSources, overwrite) {
        var result = targetAndSources[0];
        for (var i = 1, len = targetAndSources.length; i < len; i++) {
            result = merge(result, targetAndSources[i], overwrite);
        }
        return result;
    }
    function extend(target, source) {
        if (Object.assign) {
            Object.assign(target, source);
        }
        else {
            for (var key in source) {
                if (source.hasOwnProperty(key) && key !== protoKey) {
                    target[key] = source[key];
                }
            }
        }
        return target;
    }
    function defaults(target, source, overlay) {
        var keysArr = keys(source);
        for (var i = 0; i < keysArr.length; i++) {
            var key = keysArr[i];
            if ((overlay ? source[key] != null : target[key] == null)) {
                target[key] = source[key];
            }
        }
        return target;
    }
    var createCanvas = platformApi.createCanvas;
    function indexOf(array, value) {
        if (array) {
            if (array.indexOf) {
                return array.indexOf(value);
            }
            for (var i = 0, len = array.length; i < len; i++) {
                if (array[i] === value) {
                    return i;
                }
            }
        }
        return -1;
    }
    function inherits(clazz, baseClazz) {
        var clazzPrototype = clazz.prototype;
        function F() { }
        F.prototype = baseClazz.prototype;
        clazz.prototype = new F();
        for (var prop in clazzPrototype) {
            if (clazzPrototype.hasOwnProperty(prop)) {
                clazz.prototype[prop] = clazzPrototype[prop];
            }
        }
        clazz.prototype.constructor = clazz;
        clazz.superClass = baseClazz;
    }
    function mixin(target, source, override) {
        target = 'prototype' in target ? target.prototype : target;
        source = 'prototype' in source ? source.prototype : source;
        if (Object.getOwnPropertyNames) {
            var keyList = Object.getOwnPropertyNames(source);
            for (var i = 0; i < keyList.length; i++) {
                var key = keyList[i];
                if (key !== 'constructor') {
                    if ((override ? source[key] != null : target[key] == null)) {
                        target[key] = source[key];
                    }
                }
            }
        }
        else {
            defaults(target, source, override);
        }
    }
    function isArrayLike(data) {
        if (!data) {
            return false;
        }
        if (typeof data === 'string') {
            return false;
        }
        return typeof data.length === 'number';
    }
    function each(arr, cb, context) {
        if (!(arr && cb)) {
            return;
        }
        if (arr.forEach && arr.forEach === nativeForEach) {
            arr.forEach(cb, context);
        }
        else if (arr.length === +arr.length) {
            for (var i = 0, len = arr.length; i < len; i++) {
                cb.call(context, arr[i], i, arr);
            }
        }
        else {
            for (var key in arr) {
                if (arr.hasOwnProperty(key)) {
                    cb.call(context, arr[key], key, arr);
                }
            }
        }
    }
    function map(arr, cb, context) {
        if (!arr) {
            return [];
        }
        if (!cb) {
            return slice(arr);
        }
        if (arr.map && arr.map === nativeMap) {
            return arr.map(cb, context);
        }
        else {
            var result = [];
            for (var i = 0, len = arr.length; i < len; i++) {
                result.push(cb.call(context, arr[i], i, arr));
            }
            return result;
        }
    }
    function reduce(arr, cb, memo, context) {
        if (!(arr && cb)) {
            return;
        }
        for (var i = 0, len = arr.length; i < len; i++) {
            memo = cb.call(context, memo, arr[i], i, arr);
        }
        return memo;
    }
    function filter(arr, cb, context) {
        if (!arr) {
            return [];
        }
        if (!cb) {
            return slice(arr);
        }
        if (arr.filter && arr.filter === nativeFilter) {
            return arr.filter(cb, context);
        }
        else {
            var result = [];
            for (var i = 0, len = arr.length; i < len; i++) {
                if (cb.call(context, arr[i], i, arr)) {
                    result.push(arr[i]);
                }
            }
            return result;
        }
    }
    function find(arr, cb, context) {
        if (!(arr && cb)) {
            return;
        }
        for (var i = 0, len = arr.length; i < len; i++) {
            if (cb.call(context, arr[i], i, arr)) {
                return arr[i];
            }
        }
    }
    function keys(obj) {
        if (!obj) {
            return [];
        }
        if (Object.keys) {
            return Object.keys(obj);
        }
        var keyList = [];
        for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
                keyList.push(key);
            }
        }
        return keyList;
    }
    function bindPolyfill(func, context) {
        var args = [];
        for (var _i = 2; _i < arguments.length; _i++) {
            args[_i - 2] = arguments[_i];
        }
        return function () {
            return func.apply(context, args.concat(nativeSlice.call(arguments)));
        };
    }
    var bind = (protoFunction && isFunction(protoFunction.bind))
        ? protoFunction.call.bind(protoFunction.bind)
        : bindPolyfill;
    function curry(func) {
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        return function () {
            return func.apply(this, args.concat(nativeSlice.call(arguments)));
        };
    }
    function isArray(value) {
        if (Array.isArray) {
            return Array.isArray(value);
        }
        return objToString.call(value) === '[object Array]';
    }
    function isFunction(value) {
        return typeof value === 'function';
    }
    function isString(value) {
        return typeof value === 'string';
    }
    function isStringSafe(value) {
        return objToString.call(value) === '[object String]';
    }
    function isNumber(value) {
        return typeof value === 'number';
    }
    function isObject(value) {
        var type = typeof value;
        return type === 'function' || (!!value && type === 'object');
    }
    function isBuiltInObject(value) {
        return !!BUILTIN_OBJECT[objToString.call(value)];
    }
    function isTypedArray(value) {
        return !!TYPED_ARRAY[objToString.call(value)];
    }
    function isDom(value) {
        return typeof value === 'object'
            && typeof value.nodeType === 'number'
            && typeof value.ownerDocument === 'object';
    }
    function isGradientObject(value) {
        return value.colorStops != null;
    }
    function isImagePatternObject(value) {
        return value.image != null;
    }
    function isRegExp(value) {
        return objToString.call(value) === '[object RegExp]';
    }
    function eqNaN(value) {
        return value !== value;
    }
    function retrieve() {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i] = arguments[_i];
        }
        for (var i = 0, len = args.length; i < len; i++) {
            if (args[i] != null) {
                return args[i];
            }
        }
    }
    function retrieve2(value0, value1) {
        return value0 != null
            ? value0
            : value1;
    }
    function retrieve3(value0, value1, value2) {
        return value0 != null
            ? value0
            : value1 != null
                ? value1
                : value2;
    }
    function slice(arr) {
        var args = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            args[_i - 1] = arguments[_i];
        }
        return nativeSlice.apply(arr, args);
    }
    function normalizeCssArray(val) {
        if (typeof (val) === 'number') {
            return [val, val, val, val];
        }
        var len = val.length;
        if (len === 2) {
            return [val[0], val[1], val[0], val[1]];
        }
        else if (len === 3) {
            return [val[0], val[1], val[2], val[1]];
        }
        return val;
    }
    function assert(condition, message) {
        if (!condition) {
            throw new Error(message);
        }
    }
    function trim(str) {
        if (str == null) {
            return null;
        }
        else if (typeof str.trim === 'function') {
            return str.trim();
        }
        else {
            return str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
        }
    }
    var primitiveKey = '__ec_primitive__';
    function setAsPrimitive(obj) {
        obj[primitiveKey] = true;
    }
    function isPrimitive(obj) {
        return obj[primitiveKey];
    }
    var MapPolyfill = (function () {
        function MapPolyfill() {
            this.data = {};
        }
        MapPolyfill.prototype["delete"] = function (key) {
            var existed = this.has(key);
            if (existed) {
                delete this.data[key];
            }
            return existed;
        };
        MapPolyfill.prototype.has = function (key) {
            return this.data.hasOwnProperty(key);
        };
        MapPolyfill.prototype.get = function (key) {
            return this.data[key];
        };
        MapPolyfill.prototype.set = function (key, value) {
            this.data[key] = value;
            return this;
        };
        MapPolyfill.prototype.keys = function () {
            return keys(this.data);
        };
        MapPolyfill.prototype.forEach = function (callback) {
            var data = this.data;
            for (var key in data) {
                if (data.hasOwnProperty(key)) {
                    callback(data[key], key);
                }
            }
        };
        return MapPolyfill;
    }());
    var isNativeMapSupported = typeof Map === 'function';
    function maybeNativeMap() {
        return (isNativeMapSupported ? new Map() : new MapPolyfill());
    }
    var HashMap = (function () {
        function HashMap(obj) {
            var isArr = isArray(obj);
            this.data = maybeNativeMap();
            var thisMap = this;
            (obj instanceof HashMap)
                ? obj.each(visit)
                : (obj && each(obj, visit));
            function visit(value, key) {
                isArr ? thisMap.set(value, key) : thisMap.set(key, value);
            }
        }
        HashMap.prototype.hasKey = function (key) {
            return this.data.has(key);
        };
        HashMap.prototype.get = function (key) {
            return this.data.get(key);
        };
        HashMap.prototype.set = function (key, value) {
            this.data.set(key, value);
            return value;
        };
        HashMap.prototype.each = function (cb, context) {
            this.data.forEach(function (value, key) {
                cb.call(context, value, key);
            });
        };
        HashMap.prototype.keys = function () {
            var keys = this.data.keys();
            return isNativeMapSupported
                ? Array.from(keys)
                : keys;
        };
        HashMap.prototype.removeKey = function (key) {
            this.data["delete"](key);
        };
        return HashMap;
    }());
    function createHashMap(obj) {
        return new HashMap(obj);
    }
    function concatArray(a, b) {
        var newArray = new a.constructor(a.length + b.length);
        for (var i = 0; i < a.length; i++) {
            newArray[i] = a[i];
        }
        var offset = a.length;
        for (var i = 0; i < b.length; i++) {
            newArray[i + offset] = b[i];
        }
        return newArray;
    }
    function createObject(proto, properties) {
        var obj;
        if (Object.create) {
            obj = Object.create(proto);
        }
        else {
            var StyleCtor = function () { };
            StyleCtor.prototype = proto;
            obj = new StyleCtor();
        }
        if (properties) {
            extend(obj, properties);
        }
        return obj;
    }
    function disableUserSelect(dom) {
        var domStyle = dom.style;
        domStyle.webkitUserSelect = 'none';
        domStyle.userSelect = 'none';
        domStyle.webkitTapHighlightColor = 'rgba(0,0,0,0)';
        domStyle['-webkit-touch-callout'] = 'none';
    }
    function hasOwn(own, prop) {
        return own.hasOwnProperty(prop);
    }
    function noop() { }
    var RADIAN_TO_DEGREE = 180 / Math.PI;

    var util = /*#__PURE__*/Object.freeze({
        __proto__: null,
        guid: guid,
        logError: logError,
        clone: clone,
        merge: merge,
        mergeAll: mergeAll,
        extend: extend,
        defaults: defaults,
        createCanvas: createCanvas,
        indexOf: indexOf,
        inherits: inherits,
        mixin: mixin,
        isArrayLike: isArrayLike,
        each: each,
        map: map,
        reduce: reduce,
        filter: filter,
        find: find,
        keys: keys,
        bind: bind,
        curry: curry,
        isArray: isArray,
        isFunction: isFunction,
        isString: isString,
        isStringSafe: isStringSafe,
        isNumber: isNumber,
        isObject: isObject,
        isBuiltInObject: isBuiltInObject,
        isTypedArray: isTypedArray,
        isDom: isDom,
        isGradientObject: isGradientObject,
        isImagePatternObject: isImagePatternObject,
        isRegExp: isRegExp,
        eqNaN: eqNaN,
        retrieve: retrieve,
        retrieve2: retrieve2,
        retrieve3: retrieve3,
        slice: slice,
        normalizeCssArray: normalizeCssArray,
        assert: assert,
        trim: trim,
        setAsPrimitive: setAsPrimitive,
        isPrimitive: isPrimitive,
        HashMap: HashMap,
        createHashMap: createHashMap,
        concatArray: concatArray,
        createObject: createObject,
        disableUserSelect: disableUserSelect,
        hasOwn: hasOwn,
        noop: noop,
        RADIAN_TO_DEGREE: RADIAN_TO_DEGREE
    });

    function create(x, y) {
        if (x == null) {
            x = 0;
        }
        if (y == null) {
            y = 0;
        }
        return [x, y];
    }
    function copy(out, v) {
        out[0] = v[0];
        out[1] = v[1];
        return out;
    }
    function clone$1(v) {
        return [v[0], v[1]];
    }
    function set(out, a, b) {
        out[0] = a;
        out[1] = b;
        return out;
    }
    function add(out, v1, v2) {
        out[0] = v1[0] + v2[0];
        out[1] = v1[1] + v2[1];
        return out;
    }
    function scaleAndAdd(out, v1, v2, a) {
        out[0] = v1[0] + v2[0] * a;
        out[1] = v1[1] + v2[1] * a;
        return out;
    }
    function sub(out, v1, v2) {
        out[0] = v1[0] - v2[0];
        out[1] = v1[1] - v2[1];
        return out;
    }
    function len(v) {
        return Math.sqrt(lenSquare(v));
    }
    var length = len;
    function lenSquare(v) {
        return v[0] * v[0] + v[1] * v[1];
    }
    var lengthSquare = lenSquare;
    function mul(out, v1, v2) {
        out[0] = v1[0] * v2[0];
        out[1] = v1[1] * v2[1];
        return out;
    }
    function div(out, v1, v2) {
        out[0] = v1[0] / v2[0];
        out[1] = v1[1] / v2[1];
        return out;
    }
    function dot(v1, v2) {
        return v1[0] * v2[0] + v1[1] * v2[1];
    }
    function scale(out, v, s) {
        out[0] = v[0] * s;
        out[1] = v[1] * s;
        return out;
    }
    function normalize(out, v) {
        var d = len(v);
        if (d === 0) {
            out[0] = 0;
            out[1] = 0;
        }
        else {
            out[0] = v[0] / d;
            out[1] = v[1] / d;
        }
        return out;
    }
    function distance(v1, v2) {
        return Math.sqrt((v1[0] - v2[0]) * (v1[0] - v2[0])
            + (v1[1] - v2[1]) * (v1[1] - v2[1]));
    }
    var dist = distance;
    function distanceSquare(v1, v2) {
        return (v1[0] - v2[0]) * (v1[0] - v2[0])
            + (v1[1] - v2[1]) * (v1[1] - v2[1]);
    }
    var distSquare = distanceSquare;
    function negate(out, v) {
        out[0] = -v[0];
        out[1] = -v[1];
        return out;
    }
    function lerp(out, v1, v2, t) {
        out[0] = v1[0] + t * (v2[0] - v1[0]);
        out[1] = v1[1] + t * (v2[1] - v1[1]);
        return out;
    }
    function applyTransform(out, v, m) {
        var x = v[0];
        var y = v[1];
        out[0] = m[0] * x + m[2] * y + m[4];
        out[1] = m[1] * x + m[3] * y + m[5];
        return out;
    }
    function min(out, v1, v2) {
        out[0] = Math.min(v1[0], v2[0]);
        out[1] = Math.min(v1[1], v2[1]);
        return out;
    }
    function max(out, v1, v2) {
        out[0] = Math.max(v1[0], v2[0]);
        out[1] = Math.max(v1[1], v2[1]);
        return out;
    }

    var vector = /*#__PURE__*/Object.freeze({
        __proto__: null,
        create: create,
        copy: copy,
        clone: clone$1,
        set: set,
        add: add,
        scaleAndAdd: scaleAndAdd,
        sub: sub,
        len: len,
        length: length,
        lenSquare: lenSquare,
        lengthSquare: lengthSquare,
        mul: mul,
        div: div,
        dot: dot,
        scale: scale,
        normalize: normalize,
        distance: distance,
        dist: dist,
        distanceSquare: distanceSquare,
        distSquare: distSquare,
        negate: negate,
        lerp: lerp,
        applyTransform: applyTransform,
        min: min,
        max: max
    });

    var Param = (function () {
        function Param(target, e) {
            this.target = target;
            this.topTarget = e && e.topTarget;
        }
        return Param;
    }());
    var Draggable = (function () {
        function Draggable(handler) {
            this.handler = handler;
            handler.on('mousedown', this._dragStart, this);
            handler.on('mousemove', this._drag, this);
            handler.on('mouseup', this._dragEnd, this);
        }
        Draggable.prototype._dragStart = function (e) {
            var draggingTarget = e.target;
            while (draggingTarget && !draggingTarget.draggable) {
                draggingTarget = draggingTarget.parent || draggingTarget.__hostTarget;
            }
            if (draggingTarget) {
                this._draggingTarget = draggingTarget;
                draggingTarget.dragging = true;
                this._x = e.offsetX;
                this._y = e.offsetY;
                this.handler.dispatchToElement(new Param(draggingTarget, e), 'dragstart', e.event);
            }
        };
        Draggable.prototype._drag = function (e) {
            var draggingTarget = this._draggingTarget;
            if (draggingTarget) {
                var x = e.offsetX;
                var y = e.offsetY;
                var dx = x - this._x;
                var dy = y - this._y;
                this._x = x;
                this._y = y;
                draggingTarget.drift(dx, dy, e);
                this.handler.dispatchToElement(new Param(draggingTarget, e), 'drag', e.event);
                var dropTarget = this.handler.findHover(x, y, draggingTarget).target;
                var lastDropTarget = this._dropTarget;
                this._dropTarget = dropTarget;
                if (draggingTarget !== dropTarget) {
                    if (lastDropTarget && dropTarget !== lastDropTarget) {
                        this.handler.dispatchToElement(new Param(lastDropTarget, e), 'dragleave', e.event);
                    }
                    if (dropTarget && dropTarget !== lastDropTarget) {
                        this.handler.dispatchToElement(new Param(dropTarget, e), 'dragenter', e.event);
                    }
                }
            }
        };
        Draggable.prototype._dragEnd = function (e) {
            var draggingTarget = this._draggingTarget;
            if (draggingTarget) {
                draggingTarget.dragging = false;
            }
            this.handler.dispatchToElement(new Param(draggingTarget, e), 'dragend', e.event);
            if (this._dropTarget) {
                this.handler.dispatchToElement(new Param(this._dropTarget, e), 'drop', e.event);
            }
            this._draggingTarget = null;
            this._dropTarget = null;
        };
        return Draggable;
    }());

    var Eventful = (function () {
        function Eventful(eventProcessors) {
            if (eventProcessors) {
                this._$eventProcessor = eventProcessors;
            }
        }
        Eventful.prototype.on = function (event, query, handler, context) {
            if (!this._$handlers) {
                this._$handlers = {};
            }
            var _h = this._$handlers;
            if (typeof query === 'function') {
                context = handler;
                handler = query;
                query = null;
            }
            if (!handler || !event) {
                return this;
            }
            var eventProcessor = this._$eventProcessor;
            if (query != null && eventProcessor && eventProcessor.normalizeQuery) {
                query = eventProcessor.normalizeQuery(query);
            }
            if (!_h[event]) {
                _h[event] = [];
            }
            for (var i = 0; i < _h[event].length; i++) {
                if (_h[event][i].h === handler) {
                    return this;
                }
            }
            var wrap = {
                h: handler,
                query: query,
                ctx: (context || this),
                callAtLast: handler.zrEventfulCallAtLast
            };
            var lastIndex = _h[event].length - 1;
            var lastWrap = _h[event][lastIndex];
            (lastWrap && lastWrap.callAtLast)
                ? _h[event].splice(lastIndex, 0, wrap)
                : _h[event].push(wrap);
            return this;
        };
        Eventful.prototype.isSilent = function (eventName) {
            var _h = this._$handlers;
            return !_h || !_h[eventName] || !_h[eventName].length;
        };
        Eventful.prototype.off = function (eventType, handler) {
            var _h = this._$handlers;
            if (!_h) {
                return this;
            }
            if (!eventType) {
                this._$handlers = {};
                return this;
            }
            if (handler) {
                if (_h[eventType]) {
                    var newList = [];
                    for (var i = 0, l = _h[eventType].length; i < l; i++) {
                        if (_h[eventType][i].h !== handler) {
                            newList.push(_h[eventType][i]);
                        }
                    }
                    _h[eventType] = newList;
                }
                if (_h[eventType] && _h[eventType].length === 0) {
                    delete _h[eventType];
                }
            }
            else {
                delete _h[eventType];
            }
            return this;
        };
        Eventful.prototype.trigger = function (eventType) {
            var args = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                args[_i - 1] = arguments[_i];
            }
            if (!this._$handlers) {
                return this;
            }
            var _h = this._$handlers[eventType];
            var eventProcessor = this._$eventProcessor;
            if (_h) {
                var argLen = args.length;
                var len = _h.length;
                for (var i = 0; i < len; i++) {
                    var hItem = _h[i];
                    if (eventProcessor
                        && eventProcessor.filter
                        && hItem.query != null
                        && !eventProcessor.filter(eventType, hItem.query)) {
                        continue;
                    }
                    switch (argLen) {
                        case 0:
                            hItem.h.call(hItem.ctx);
                            break;
                        case 1:
                            hItem.h.call(hItem.ctx, args[0]);
                            break;
                        case 2:
                            hItem.h.call(hItem.ctx, args[0], args[1]);
                            break;
                        default:
                            hItem.h.apply(hItem.ctx, args);
                            break;
                    }
                }
            }
            eventProcessor && eventProcessor.afterTrigger
                && eventProcessor.afterTrigger(eventType);
            return this;
        };
        Eventful.prototype.triggerWithContext = function (type) {
            var args = [];
            for (var _i = 1; _i < arguments.length; _i++) {
                args[_i - 1] = arguments[_i];
            }
            if (!this._$handlers) {
                return this;
            }
            var _h = this._$handlers[type];
            var eventProcessor = this._$eventProcessor;
            if (_h) {
                var argLen = args.length;
                var ctx = args[argLen - 1];
                var len = _h.length;
                for (var i = 0; i < len; i++) {
                    var hItem = _h[i];
                    if (eventProcessor
                        && eventProcessor.filter
                        && hItem.query != null
                        && !eventProcessor.filter(type, hItem.query)) {
                        continue;
                    }
                    switch (argLen) {
                        case 0:
                            hItem.h.call(ctx);
                            break;
                        case 1:
                            hItem.h.call(ctx, args[0]);
                            break;
                        case 2:
                            hItem.h.call(ctx, args[0], args[1]);
                            break;
                        default:
                            hItem.h.apply(ctx, args.slice(1, argLen - 1));
                            break;
                    }
                }
            }
            eventProcessor && eventProcessor.afterTrigger
                && eventProcessor.afterTrigger(type);
            return this;
        };
        return Eventful;
    }());

    var LN2 = Math.log(2);
    function determinant(rows, rank, rowStart, rowMask, colMask, detCache) {
        var cacheKey = rowMask + '-' + colMask;
        var fullRank = rows.length;
        if (detCache.hasOwnProperty(cacheKey)) {
            return detCache[cacheKey];
        }
        if (rank === 1) {
            var colStart = Math.round(Math.log(((1 << fullRank) - 1) & ~colMask) / LN2);
            return rows[rowStart][colStart];
        }
        var subRowMask = rowMask | (1 << rowStart);
        var subRowStart = rowStart + 1;
        while (rowMask & (1 << subRowStart)) {
            subRowStart++;
        }
        var sum = 0;
        for (var j = 0, colLocalIdx = 0; j < fullRank; j++) {
            var colTag = 1 << j;
            if (!(colTag & colMask)) {
                sum += (colLocalIdx % 2 ? -1 : 1) * rows[rowStart][j]
                    * determinant(rows, rank - 1, subRowStart, subRowMask, colMask | colTag, detCache);
                colLocalIdx++;
            }
        }
        detCache[cacheKey] = sum;
        return sum;
    }
    function buildTransformer(src, dest) {
        var mA = [
            [src[0], src[1], 1, 0, 0, 0, -dest[0] * src[0], -dest[0] * src[1]],
            [0, 0, 0, src[0], src[1], 1, -dest[1] * src[0], -dest[1] * src[1]],
            [src[2], src[3], 1, 0, 0, 0, -dest[2] * src[2], -dest[2] * src[3]],
            [0, 0, 0, src[2], src[3], 1, -dest[3] * src[2], -dest[3] * src[3]],
            [src[4], src[5], 1, 0, 0, 0, -dest[4] * src[4], -dest[4] * src[5]],
            [0, 0, 0, src[4], src[5], 1, -dest[5] * src[4], -dest[5] * src[5]],
            [src[6], src[7], 1, 0, 0, 0, -dest[6] * src[6], -dest[6] * src[7]],
            [0, 0, 0, src[6], src[7], 1, -dest[7] * src[6], -dest[7] * src[7]]
        ];
        var detCache = {};
        var det = determinant(mA, 8, 0, 0, 0, detCache);
        if (det === 0) {
            return;
        }
        var vh = [];
        for (var i = 0; i < 8; i++) {
            for (var j = 0; j < 8; j++) {
                vh[j] == null && (vh[j] = 0);
                vh[j] += ((i + j) % 2 ? -1 : 1)
                    * determinant(mA, 7, i === 0 ? 1 : 0, 1 << i, 1 << j, detCache)
                    / det * dest[i];
            }
        }
        return function (out, srcPointX, srcPointY) {
            var pk = srcPointX * vh[6] + srcPointY * vh[7] + 1;
            out[0] = (srcPointX * vh[0] + srcPointY * vh[1] + vh[2]) / pk;
            out[1] = (srcPointX * vh[3] + srcPointY * vh[4] + vh[5]) / pk;
        };
    }

    var EVENT_SAVED_PROP = '___zrEVENTSAVED';
    function transformCoordWithViewport(out, el, inX, inY, inverse) {
        if (el.getBoundingClientRect && env.domSupported && !isCanvasEl(el)) {
            var saved = el[EVENT_SAVED_PROP] || (el[EVENT_SAVED_PROP] = {});
            var markers = prepareCoordMarkers(el, saved);
            var transformer = preparePointerTransformer(markers, saved, inverse);
            if (transformer) {
                transformer(out, inX, inY);
                return true;
            }
        }
        return false;
    }
    function prepareCoordMarkers(el, saved) {
        var markers = saved.markers;
        if (markers) {
            return markers;
        }
        markers = saved.markers = [];
        var propLR = ['left', 'right'];
        var propTB = ['top', 'bottom'];
        for (var i = 0; i < 4; i++) {
            var marker = document.createElement('div');
            var stl = marker.style;
            var idxLR = i % 2;
            var idxTB = (i >> 1) % 2;
            stl.cssText = [
                'position: absolute',
                'visibility: hidden',
                'padding: 0',
                'margin: 0',
                'border-width: 0',
                'user-select: none',
                'width:0',
                'height:0',
                propLR[idxLR] + ':0',
                propTB[idxTB] + ':0',
                propLR[1 - idxLR] + ':auto',
                propTB[1 - idxTB] + ':auto',
                ''
            ].join('!important;');
            el.appendChild(marker);
            markers.push(marker);
        }
        return markers;
    }
    function preparePointerTransformer(markers, saved, inverse) {
        var transformerName = inverse ? 'invTrans' : 'trans';
        var transformer = saved[transformerName];
        var oldSrcCoords = saved.srcCoords;
        var srcCoords = [];
        var destCoords = [];
        var oldCoordTheSame = true;
        for (var i = 0; i < 4; i++) {
            var rect = markers[i].getBoundingClientRect();
            var ii = 2 * i;
            var x = rect.left;
            var y = rect.top;
            srcCoords.push(x, y);
            oldCoordTheSame = oldCoordTheSame && oldSrcCoords && x === oldSrcCoords[ii] && y === oldSrcCoords[ii + 1];
            destCoords.push(markers[i].offsetLeft, markers[i].offsetTop);
        }
        return (oldCoordTheSame && transformer)
            ? transformer
            : (saved.srcCoords = srcCoords,
                saved[transformerName] = inverse
                    ? buildTransformer(destCoords, srcCoords)
                    : buildTransformer(srcCoords, destCoords));
    }
    function isCanvasEl(el) {
        return el.nodeName.toUpperCase() === 'CANVAS';
    }
    var replaceReg = /([&<>"'])/g;
    var replaceMap = {
        '&': '&amp;',
        '<': '&lt;',
        '>': '&gt;',
        '"': '&quot;',
        '\'': '&#39;'
    };
    function encodeHTML(source) {
        return source == null
            ? ''
            : (source + '').replace(replaceReg, function (str, c) {
                return replaceMap[c];
            });
    }

    var MOUSE_EVENT_REG = /^(?:mouse|pointer|contextmenu|drag|drop)|click/;
    var _calcOut = [];
    var firefoxNotSupportOffsetXY = env.browser.firefox
        && +env.browser.version.split('.')[0] < 39;
    function clientToLocal(el, e, out, calculate) {
        out = out || {};
        if (calculate) {
            calculateZrXY(el, e, out);
        }
        else if (firefoxNotSupportOffsetXY
            && e.layerX != null
            && e.layerX !== e.offsetX) {
            out.zrX = e.layerX;
            out.zrY = e.layerY;
        }
        else if (e.offsetX != null) {
            out.zrX = e.offsetX;
            out.zrY = e.offsetY;
        }
        else {
            calculateZrXY(el, e, out);
        }
        return out;
    }
    function calculateZrXY(el, e, out) {
        if (env.domSupported && el.getBoundingClientRect) {
            var ex = e.clientX;
            var ey = e.clientY;
            if (isCanvasEl(el)) {
                var box = el.getBoundingClientRect();
                out.zrX = ex - box.left;
                out.zrY = ey - box.top;
                return;
            }
            else {
                if (transformCoordWithViewport(_calcOut, el, ex, ey)) {
                    out.zrX = _calcOut[0];
                    out.zrY = _calcOut[1];
                    return;
                }
            }
        }
        out.zrX = out.zrY = 0;
    }
    function getNativeEvent(e) {
        return e
            || window.event;
    }
    function normalizeEvent(el, e, calculate) {
        e = getNativeEvent(e);
        if (e.zrX != null) {
            return e;
        }
        var eventType = e.type;
        var isTouch = eventType && eventType.indexOf('touch') >= 0;
        if (!isTouch) {
            clientToLocal(el, e, e, calculate);
            var wheelDelta = getWheelDeltaMayPolyfill(e);
            e.zrDelta = wheelDelta ? wheelDelta / 120 : -(e.detail || 0) / 3;
        }
        else {
            var touch = eventType !== 'touchend'
                ? e.targetTouches[0]
                : e.changedTouches[0];
            touch && clientToLocal(el, touch, e, calculate);
        }
        var button = e.button;
        if (e.which == null && button !== undefined && MOUSE_EVENT_REG.test(e.type)) {
            e.which = (button & 1 ? 1 : (button & 2 ? 3 : (button & 4 ? 2 : 0)));
        }
        return e;
    }
    function getWheelDeltaMayPolyfill(e) {
        var rawWheelDelta = e.wheelDelta;
        if (rawWheelDelta) {
            return rawWheelDelta;
        }
        var deltaX = e.deltaX;
        var deltaY = e.deltaY;
        if (deltaX == null || deltaY == null) {
            return rawWheelDelta;
        }
        var delta = deltaY !== 0 ? Math.abs(deltaY) : Math.abs(deltaX);
        var sign = deltaY > 0 ? -1
            : deltaY < 0 ? 1
                : deltaX > 0 ? -1
                    : 1;
        return 3 * delta * sign;
    }
    function addEventListener(el, name, handler, opt) {
        el.addEventListener(name, handler, opt);
    }
    function removeEventListener(el, name, handler, opt) {
        el.removeEventListener(name, handler, opt);
    }
    var stop = function (e) {
        e.preventDefault();
        e.stopPropagation();
        e.cancelBubble = true;
    };

    var GestureMgr = (function () {
        function GestureMgr() {
            this._track = [];
        }
        GestureMgr.prototype.recognize = function (event, target, root) {
            this._doTrack(event, target, root);
            return this._recognize(event);
        };
        GestureMgr.prototype.clear = function () {
            this._track.length = 0;
            return this;
        };
        GestureMgr.prototype._doTrack = function (event, target, root) {
            var touches = event.touches;
            if (!touches) {
                return;
            }
            var trackItem = {
                points: [],
                touches: [],
                target: target,
                event: event
            };
            for (var i = 0, len = touches.length; i < len; i++) {
                var touch = touches[i];
                var pos = clientToLocal(root, touch, {});
                trackItem.points.push([pos.zrX, pos.zrY]);
                trackItem.touches.push(touch);
            }
            this._track.push(trackItem);
        };
        GestureMgr.prototype._recognize = function (event) {
            for (var eventName in recognizers) {
                if (recognizers.hasOwnProperty(eventName)) {
                    var gestureInfo = recognizers[eventName](this._track, event);
                    if (gestureInfo) {
                        return gestureInfo;
                    }
                }
            }
        };
        return GestureMgr;
    }());
    function dist$1(pointPair) {
        var dx = pointPair[1][0] - pointPair[0][0];
        var dy = pointPair[1][1] - pointPair[0][1];
        return Math.sqrt(dx * dx + dy * dy);
    }
    function center(pointPair) {
        return [
            (pointPair[0][0] + pointPair[1][0]) / 2,
            (pointPair[0][1] + pointPair[1][1]) / 2
        ];
    }
    var recognizers = {
        pinch: function (tracks, event) {
            var trackLen = tracks.length;
            if (!trackLen) {
                return;
            }
            var pinchEnd = (tracks[trackLen - 1] || {}).points;
            var pinchPre = (tracks[trackLen - 2] || {}).points || pinchEnd;
            if (pinchPre
                && pinchPre.length > 1
                && pinchEnd
                && pinchEnd.length > 1) {
                var pinchScale = dist$1(pinchEnd) / dist$1(pinchPre);
                !isFinite(pinchScale) && (pinchScale = 1);
                event.pinchScale = pinchScale;
                var pinchCenter = center(pinchEnd);
                event.pinchX = pinchCenter[0];
                event.pinchY = pinchCenter[1];
                return {
                    type: 'pinch',
                    target: tracks[0].target,
                    event: event
                };
            }
        }
    };

    function create$1() {
        return [1, 0, 0, 1, 0, 0];
    }
    function identity(out) {
        out[0] = 1;
        out[1] = 0;
        out[2] = 0;
        out[3] = 1;
        out[4] = 0;
        out[5] = 0;
        return out;
    }
    function copy$1(out, m) {
        out[0] = m[0];
        out[1] = m[1];
        out[2] = m[2];
        out[3] = m[3];
        out[4] = m[4];
        out[5] = m[5];
        return out;
    }
    function mul$1(out, m1, m2) {
        var out0 = m1[0] * m2[0] + m1[2] * m2[1];
        var out1 = m1[1] * m2[0] + m1[3] * m2[1];
        var out2 = m1[0] * m2[2] + m1[2] * m2[3];
        var out3 = m1[1] * m2[2] + m1[3] * m2[3];
        var out4 = m1[0] * m2[4] + m1[2] * m2[5] + m1[4];
        var out5 = m1[1] * m2[4] + m1[3] * m2[5] + m1[5];
        out[0] = out0;
        out[1] = out1;
        out[2] = out2;
        out[3] = out3;
        out[4] = out4;
        out[5] = out5;
        return out;
    }
    function translate(out, a, v) {
        out[0] = a[0];
        out[1] = a[1];
        out[2] = a[2];
        out[3] = a[3];
        out[4] = a[4] + v[0];
        out[5] = a[5] + v[1];
        return out;
    }
    function rotate(out, a, rad) {
        var aa = a[0];
        var ac = a[2];
        var atx = a[4];
        var ab = a[1];
        var ad = a[3];
        var aty = a[5];
        var st = Math.sin(rad);
        var ct = Math.cos(rad);
        out[0] = aa * ct + ab * st;
        out[1] = -aa * st + ab * ct;
        out[2] = ac * ct + ad * st;
        out[3] = -ac * st + ct * ad;
        out[4] = ct * atx + st * aty;
        out[5] = ct * aty - st * atx;
        return out;
    }
    function scale$1(out, a, v) {
        var vx = v[0];
        var vy = v[1];
        out[0] = a[0] * vx;
        out[1] = a[1] * vy;
        out[2] = a[2] * vx;
        out[3] = a[3] * vy;
        out[4] = a[4] * vx;
        out[5] = a[5] * vy;
        return out;
    }
    function invert(out, a) {
        var aa = a[0];
        var ac = a[2];
        var atx = a[4];
        var ab = a[1];
        var ad = a[3];
        var aty = a[5];
        var det = aa * ad - ab * ac;
        if (!det) {
            return null;
        }
        det = 1.0 / det;
        out[0] = ad * det;
        out[1] = -ab * det;
        out[2] = -ac * det;
        out[3] = aa * det;
        out[4] = (ac * aty - ad * atx) * det;
        out[5] = (ab * atx - aa * aty) * det;
        return out;
    }
    function clone$2(a) {
        var b = create$1();
        copy$1(b, a);
        return b;
    }

    var matrix = /*#__PURE__*/Object.freeze({
        __proto__: null,
        create: create$1,
        identity: identity,
        copy: copy$1,
        mul: mul$1,
        translate: translate,
        rotate: rotate,
        scale: scale$1,
        invert: invert,
        clone: clone$2
    });

    var Point = (function () {
        function Point(x, y) {
            this.x = x || 0;
            this.y = y || 0;
        }
        Point.prototype.copy = function (other) {
            this.x = other.x;
            this.y = other.y;
            return this;
        };
        Point.prototype.clone = function () {
            return new Point(this.x, this.y);
        };
        Point.prototype.set = function (x, y) {
            this.x = x;
            this.y = y;
            return this;
        };
        Point.prototype.equal = function (other) {
            return other.x === this.x && other.y === this.y;
        };
        Point.prototype.add = function (other) {
            this.x += other.x;
            this.y += other.y;
            return this;
        };
        Point.prototype.scale = function (scalar) {
            this.x *= scalar;
            this.y *= scalar;
        };
        Point.prototype.scaleAndAdd = function (other, scalar) {
            this.x += other.x * scalar;
            this.y += other.y * scalar;
        };
        Point.prototype.sub = function (other) {
            this.x -= other.x;
            this.y -= other.y;
            return this;
        };
        Point.prototype.dot = function (other) {
            return this.x * other.x + this.y * other.y;
        };
        Point.prototype.len = function () {
            return Math.sqrt(this.x * this.x + this.y * this.y);
        };
        Point.prototype.lenSquare = function () {
            return this.x * this.x + this.y * this.y;
        };
        Point.prototype.normalize = function () {
            var len = this.len();
            this.x /= len;
            this.y /= len;
            return this;
        };
        Point.prototype.distance = function (other) {
            var dx = this.x - other.x;
            var dy = this.y - other.y;
            return Math.sqrt(dx * dx + dy * dy);
        };
        Point.prototype.distanceSquare = function (other) {
            var dx = this.x - other.x;
            var dy = this.y - other.y;
            return dx * dx + dy * dy;
        };
        Point.prototype.negate = function () {
            this.x = -this.x;
            this.y = -this.y;
            return this;
        };
        Point.prototype.transform = function (m) {
            if (!m) {
                return;
            }
            var x = this.x;
            var y = this.y;
            this.x = m[0] * x + m[2] * y + m[4];
            this.y = m[1] * x + m[3] * y + m[5];
            return this;
        };
        Point.prototype.toArray = function (out) {
            out[0] = this.x;
            out[1] = this.y;
            return out;
        };
        Point.prototype.fromArray = function (input) {
            this.x = input[0];
            this.y = input[1];
        };
        Point.set = function (p, x, y) {
            p.x = x;
            p.y = y;
        };
        Point.copy = function (p, p2) {
            p.x = p2.x;
            p.y = p2.y;
        };
        Point.len = function (p) {
            return Math.sqrt(p.x * p.x + p.y * p.y);
        };
        Point.lenSquare = function (p) {
            return p.x * p.x + p.y * p.y;
        };
        Point.dot = function (p0, p1) {
            return p0.x * p1.x + p0.y * p1.y;
        };
        Point.add = function (out, p0, p1) {
            out.x = p0.x + p1.x;
            out.y = p0.y + p1.y;
        };
        Point.sub = function (out, p0, p1) {
            out.x = p0.x - p1.x;
            out.y = p0.y - p1.y;
        };
        Point.scale = function (out, p0, scalar) {
            out.x = p0.x * scalar;
            out.y = p0.y * scalar;
        };
        Point.scaleAndAdd = function (out, p0, p1, scalar) {
            out.x = p0.x + p1.x * scalar;
            out.y = p0.y + p1.y * scalar;
        };
        Point.lerp = function (out, p0, p1, t) {
            var onet = 1 - t;
            out.x = onet * p0.x + t * p1.x;
            out.y = onet * p0.y + t * p1.y;
        };
        return Point;
    }());

    var mathMin = Math.min;
    var mathMax = Math.max;
    var lt = new Point();
    var rb = new Point();
    var lb = new Point();
    var rt = new Point();
    var minTv = new Point();
    var maxTv = new Point();
    var BoundingRect = (function () {
        function BoundingRect(x, y, width, height) {
            if (width < 0) {
                x = x + width;
                width = -width;
            }
            if (height < 0) {
                y = y + height;
                height = -height;
            }
            this.x = x;
            this.y = y;
            this.width = width;
            this.height = height;
        }
        BoundingRect.prototype.union = function (other) {
            var x = mathMin(other.x, this.x);
            var y = mathMin(other.y, this.y);
            if (isFinite(this.x) && isFinite(this.width)) {
                this.width = mathMax(other.x + other.width, this.x + this.width) - x;
            }
            else {
                this.width = other.width;
            }
            if (isFinite(this.y) && isFinite(this.height)) {
                this.height = mathMax(other.y + other.height, this.y + this.height) - y;
            }
            else {
                this.height = other.height;
            }
            this.x = x;
            this.y = y;
        };
        BoundingRect.prototype.applyTransform = function (m) {
            BoundingRect.applyTransform(this, this, m);
        };
        BoundingRect.prototype.calculateTransform = function (b) {
            var a = this;
            var sx = b.width / a.width;
            var sy = b.height / a.height;
            var m = create$1();
            translate(m, m, [-a.x, -a.y]);
            scale$1(m, m, [sx, sy]);
            translate(m, m, [b.x, b.y]);
            return m;
        };
        BoundingRect.prototype.intersect = function (b, mtv) {
            if (!b) {
                return false;
            }
            if (!(b instanceof BoundingRect)) {
                b = BoundingRect.create(b);
            }
            var a = this;
            var ax0 = a.x;
            var ax1 = a.x + a.width;
            var ay0 = a.y;
            var ay1 = a.y + a.height;
            var bx0 = b.x;
            var bx1 = b.x + b.width;
            var by0 = b.y;
            var by1 = b.y + b.height;
            var overlap = !(ax1 < bx0 || bx1 < ax0 || ay1 < by0 || by1 < ay0);
            if (mtv) {
                var dMin = Infinity;
                var dMax = 0;
                var d0 = Math.abs(ax1 - bx0);
                var d1 = Math.abs(bx1 - ax0);
                var d2 = Math.abs(ay1 - by0);
                var d3 = Math.abs(by1 - ay0);
                var dx = Math.min(d0, d1);
                var dy = Math.min(d2, d3);
                if (ax1 < bx0 || bx1 < ax0) {
                    if (dx > dMax) {
                        dMax = dx;
                        if (d0 < d1) {
                            Point.set(maxTv, -d0, 0);
                        }
                        else {
                            Point.set(maxTv, d1, 0);
                        }
                    }
                }
                else {
                    if (dx < dMin) {
                        dMin = dx;
                        if (d0 < d1) {
                            Point.set(minTv, d0, 0);
                        }
                        else {
                            Point.set(minTv, -d1, 0);
                        }
                    }
                }
                if (ay1 < by0 || by1 < ay0) {
                    if (dy > dMax) {
                        dMax = dy;
                        if (d2 < d3) {
                            Point.set(maxTv, 0, -d2);
                        }
                        else {
                            Point.set(maxTv, 0, d3);
                        }
                    }
                }
                else {
                    if (dx < dMin) {
                        dMin = dx;
                        if (d2 < d3) {
                            Point.set(minTv, 0, d2);
                        }
                        else {
                            Point.set(minTv, 0, -d3);
                        }
                    }
                }
            }
            if (mtv) {
                Point.copy(mtv, overlap ? minTv : maxTv);
            }
            return overlap;
        };
        BoundingRect.prototype.contain = function (x, y) {
            var rect = this;
            return x >= rect.x
                && x <= (rect.x + rect.width)
                && y >= rect.y
                && y <= (rect.y + rect.height);
        };
        BoundingRect.prototype.clone = function () {
            return new BoundingRect(this.x, this.y, this.width, this.height);
        };
        BoundingRect.prototype.copy = function (other) {
            BoundingRect.copy(this, other);
        };
        BoundingRect.prototype.plain = function () {
            return {
                x: this.x,
                y: this.y,
                width: this.width,
                height: this.height
            };
        };
        BoundingRect.prototype.isFinite = function () {
            return isFinite(this.x)
                && isFinite(this.y)
                && isFinite(this.width)
                && isFinite(this.height);
        };
        BoundingRect.prototype.isZero = function () {
            return this.width === 0 || this.height === 0;
        };
        BoundingRect.create = function (rect) {
            return new BoundingRect(rect.x, rect.y, rect.width, rect.height);
        };
        BoundingRect.copy = function (target, source) {
            target.x = source.x;
            target.y = source.y;
            target.width = source.width;
            target.height = source.height;
        };
        BoundingRect.applyTransform = function (target, source, m) {
            if (!m) {
                if (target !== source) {
                    BoundingRect.copy(target, source);
                }
                return;
            }
            if (m[1] < 1e-5 && m[1] > -1e-5 && m[2] < 1e-5 && m[2] > -1e-5) {
                var sx = m[0];
                var sy = m[3];
                var tx = m[4];
                var ty = m[5];
                target.x = source.x * sx + tx;
                target.y = source.y * sy + ty;
                target.width = source.width * sx;
                target.height = source.height * sy;
                if (target.width < 0) {
                    target.x += target.width;
                    target.width = -target.width;
                }
                if (target.height < 0) {
                    target.y += target.height;
                    target.height = -target.height;
                }
                return;
            }
            lt.x = lb.x = source.x;
            lt.y = rt.y = source.y;
            rb.x = rt.x = source.x + source.width;
            rb.y = lb.y = source.y + source.height;
            lt.transform(m);
            rt.transform(m);
            rb.transform(m);
            lb.transform(m);
            target.x = mathMin(lt.x, rb.x, lb.x, rt.x);
            target.y = mathMin(lt.y, rb.y, lb.y, rt.y);
            var maxX = mathMax(lt.x, rb.x, lb.x, rt.x);
            var maxY = mathMax(lt.y, rb.y, lb.y, rt.y);
            target.width = maxX - target.x;
            target.height = maxY - target.y;
        };
        return BoundingRect;
    }());

    var SILENT = 'silent';
    function makeEventPacket(eveType, targetInfo, event) {
        return {
            type: eveType,
            event: event,
            target: targetInfo.target,
            topTarget: targetInfo.topTarget,
            cancelBubble: false,
            offsetX: event.zrX,
            offsetY: event.zrY,
            gestureEvent: event.gestureEvent,
            pinchX: event.pinchX,
            pinchY: event.pinchY,
            pinchScale: event.pinchScale,
            wheelDelta: event.zrDelta,
            zrByTouch: event.zrByTouch,
            which: event.which,
            stop: stopEvent
        };
    }
    function stopEvent() {
        stop(this.event);
    }
    var EmptyProxy = (function (_super) {
        __extends(EmptyProxy, _super);
        function EmptyProxy() {
            var _this = _super !== null && _super.apply(this, arguments) || this;
            _this.handler = null;
            return _this;
        }
        EmptyProxy.prototype.dispose = function () { };
        EmptyProxy.prototype.setCursor = function () { };
        return EmptyProxy;
    }(Eventful));
    var HoveredResult = (function () {
        function HoveredResult(x, y) {
            this.x = x;
            this.y = y;
        }
        return HoveredResult;
    }());
    var handlerNames = [
        'click', 'dblclick', 'mousewheel', 'mouseout',
        'mouseup', 'mousedown', 'mousemove', 'contextmenu'
    ];
    var tmpRect = new BoundingRect(0, 0, 0, 0);
    var Handler = (function (_super) {
        __extends(Handler, _super);
        function Handler(storage, painter, proxy, painterRoot, pointerSize) {
            var _this = _super.call(this) || this;
            _this._hovered = new HoveredResult(0, 0);
            _this.storage = storage;
            _this.painter = painter;
            _this.painterRoot = painterRoot;
            _this._pointerSize = pointerSize;
            proxy = proxy || new EmptyProxy();
            _this.proxy = null;
            _this.setHandlerProxy(proxy);
            _this._draggingMgr = new Draggable(_this);
            return _this;
        }
        Handler.prototype.setHandlerProxy = function (proxy) {
            if (this.proxy) {
                this.proxy.dispose();
            }
            if (proxy) {
                each(handlerNames, function (name) {
                    proxy.on && proxy.on(name, this[name], this);
                }, this);
                proxy.handler = this;
            }
            this.proxy = proxy;
        };
        Handler.prototype.mousemove = function (event) {
            var x = event.zrX;
            var y = event.zrY;
            var isOutside = isOutsideBoundary(this, x, y);
            var lastHovered = this._hovered;
            var lastHoveredTarget = lastHovered.target;
            if (lastHoveredTarget && !lastHoveredTarget.__zr) {
                lastHovered = this.findHover(lastHovered.x, lastHovered.y);
                lastHoveredTarget = lastHovered.target;
            }
            var hovered = this._hovered = isOutside ? new HoveredResult(x, y) : this.findHover(x, y);
            var hoveredTarget = hovered.target;
            var proxy = this.proxy;
            proxy.setCursor && proxy.setCursor(hoveredTarget ? hoveredTarget.cursor : 'default');
            if (lastHoveredTarget && hoveredTarget !== lastHoveredTarget) {
                this.dispatchToElement(lastHovered, 'mouseout', event);
            }
            this.dispatchToElement(hovered, 'mousemove', event);
            if (hoveredTarget && hoveredTarget !== lastHoveredTarget) {
                this.dispatchToElement(hovered, 'mouseover', event);
            }
        };
        Handler.prototype.mouseout = function (event) {
            var eventControl = event.zrEventControl;
            if (eventControl !== 'only_globalout') {
                this.dispatchToElement(this._hovered, 'mouseout', event);
            }
            if (eventControl !== 'no_globalout') {
                this.trigger('globalout', { type: 'globalout', event: event });
            }
        };
        Handler.prototype.resize = function () {
            this._hovered = new HoveredResult(0, 0);
        };
        Handler.prototype.dispatch = function (eventName, eventArgs) {
            var handler = this[eventName];
            handler && handler.call(this, eventArgs);
        };
        Handler.prototype.dispose = function () {
            this.proxy.dispose();
            this.storage = null;
            this.proxy = null;
            this.painter = null;
        };
        Handler.prototype.setCursorStyle = function (cursorStyle) {
            var proxy = this.proxy;
            proxy.setCursor && proxy.setCursor(cursorStyle);
        };
        Handler.prototype.dispatchToElement = function (targetInfo, eventName, event) {
            targetInfo = targetInfo || {};
            var el = targetInfo.target;
            if (el && el.silent) {
                return;
            }
            var eventKey = ('on' + eventName);
            var eventPacket = makeEventPacket(eventName, targetInfo, event);
            while (el) {
                el[eventKey]
                    && (eventPacket.cancelBubble = !!el[eventKey].call(el, eventPacket));
                el.trigger(eventName, eventPacket);
                el = el.__hostTarget ? el.__hostTarget : el.parent;
                if (eventPacket.cancelBubble) {
                    break;
                }
            }
            if (!eventPacket.cancelBubble) {
                this.trigger(eventName, eventPacket);
                if (this.painter && this.painter.eachOtherLayer) {
                    this.painter.eachOtherLayer(function (layer) {
                        if (typeof (layer[eventKey]) === 'function') {
                            layer[eventKey].call(layer, eventPacket);
                        }
                        if (layer.trigger) {
                            layer.trigger(eventName, eventPacket);
                        }
                    });
                }
            }
        };
        Handler.prototype.findHover = function (x, y, exclude) {
            var list = this.storage.getDisplayList();
            var out = new HoveredResult(x, y);
            setHoverTarget(list, out, x, y, exclude);
            if (this._pointerSize && !out.target) {
                var candidates = [];
                var pointerSize = this._pointerSize;
                var targetSizeHalf = pointerSize / 2;
                var pointerRect = new BoundingRect(x - targetSizeHalf, y - targetSizeHalf, pointerSize, pointerSize);
                for (var i = list.length - 1; i >= 0; i--) {
                    var el = list[i];
                    if (el !== exclude
                        && !el.ignore
                        && !el.ignoreCoarsePointer
                        && (!el.parent || !el.parent.ignoreCoarsePointer)) {
                        tmpRect.copy(el.getBoundingRect());
                        if (el.transform) {
                            tmpRect.applyTransform(el.transform);
                        }
                        if (tmpRect.intersect(pointerRect)) {
                            candidates.push(el);
                        }
                    }
                }
                if (candidates.length) {
                    var rStep = 4;
                    var thetaStep = Math.PI / 12;
                    var PI2 = Math.PI * 2;
                    for (var r = 0; r < targetSizeHalf; r += rStep) {
                        for (var theta = 0; theta < PI2; theta += thetaStep) {
                            var x1 = x + r * Math.cos(theta);
                            var y1 = y + r * Math.sin(theta);
                            setHoverTarget(candidates, out, x1, y1, exclude);
                            if (out.target) {
                                return out;
                            }
                        }
                    }
                }
            }
            return out;
        };
        Handler.prototype.processGesture = function (event, stage) {
            if (!this._gestureMgr) {
                this._gestureMgr = new GestureMgr();
            }
            var gestureMgr = this._gestureMgr;
            stage === 'start' && gestureMgr.clear();
            var gestureInfo = gestureMgr.recognize(event, this.findHover(event.zrX, event.zrY, null).target, this.proxy.dom);
            stage === 'end' && gestureMgr.clear();
            if (gestureInfo) {
                var type = gestureInfo.type;
                event.gestureEvent = type;
                var res = new HoveredResult();
                res.target = gestureInfo.target;
                this.dispatchToElement(res, type, gestureInfo.event);
            }
        };
        return Handler;
    }(Eventful));
    each(['click', 'mousedown', 'mouseup', 'mousewheel', 'dblclick', 'contextmenu'], function (name) {
        Handler.prototype[name] = function (event) {
            var x = event.zrX;
            var y = event.zrY;
            var isOutside = isOutsideBoundary(this, x, y);
            var hovered;
            var hoveredTarget;
            if (name !== 'mouseup' || !isOutside) {
                hovered = this.findHover(x, y);
                hoveredTarget = hovered.target;
            }
            if (name === 'mousedown') {
                this._downEl = hoveredTarget;
                this._downPoint = [event.zrX, event.zrY];
                this._upEl = hoveredTarget;
            }
            else if (name === 'mouseup') {
                this._upEl = hoveredTarget;
            }
            else if (name === 'click') {
                if (this._downEl !== this._upEl
                    || !this._downPoint
                    || dist(this._downPoint, [event.zrX, event.zrY]) > 4) {
                    return;
                }
                this._downPoint = null;
            }
            this.dispatchToElement(hovered, name, event);
        };
    });
    function isHover(displayable, x, y) {
        if (displayable[displayable.rectHover ? 'rectContain' : 'contain'](x, y)) {
            var el = displayable;
            var isSilent = void 0;
            var ignoreClip = false;
            while (el) {
                if (el.ignoreClip) {
                    ignoreClip = true;
                }
                if (!ignoreClip) {
                    var clipPath = el.getClipPath();
                    if (clipPath && !clipPath.contain(x, y)) {
                        return false;
                    }
                    if (el.silent) {
                        isSilent = true;
                    }
                }
                var hostEl = el.__hostTarget;
                el = hostEl ? hostEl : el.parent;
            }
            return isSilent ? SILENT : true;
        }
        return false;
    }
    function setHoverTarget(list, out, x, y, exclude) {
        for (var i = list.length - 1; i >= 0; i--) {
            var el = list[i];
            var hoverCheckResult = void 0;
            if (el !== exclude
                && !el.ignore
                && (hoverCheckResult = isHover(el, x, y))) {
                !out.topTarget && (out.topTarget = el);
                if (hoverCheckResult !== SILENT) {
                    out.target = el;
                    break;
                }
            }
        }
    }
    function isOutsideBoundary(handlerInstance, x, y) {
        var painter = handlerInstance.painter;
        return x < 0 || x > painter.getWidth() || y < 0 || y > painter.getHeight();
    }

    var DEFAULT_MIN_MERGE = 32;
    var DEFAULT_MIN_GALLOPING = 7;
    function minRunLength(n) {
        var r = 0;
        while (n >= DEFAULT_MIN_MERGE) {
            r |= n & 1;
            n >>= 1;
        }
        return n + r;
    }
    function makeAscendingRun(array, lo, hi, compare) {
        var runHi = lo + 1;
        if (runHi === hi) {
            return 1;
        }
        if (compare(array[runHi++], array[lo]) < 0) {
            while (runHi < hi && compare(array[runHi], array[runHi - 1]) < 0) {
                runHi++;
            }
            reverseRun(array, lo, runHi);
        }
        else {
            while (runHi < hi && compare(array[runHi], array[runHi - 1]) >= 0) {
                runHi++;
            }
        }
        return runHi - lo;
    }
    function reverseRun(array, lo, hi) {
        hi--;
        while (lo < hi) {
            var t = array[lo];
            array[lo++] = array[hi];
            array[hi--] = t;
        }
    }
    function binaryInsertionSort(array, lo, hi, start, compare) {
        if (start === lo) {
            start++;
        }
        for (; start < hi; start++) {
            var pivot = array[start];
            var left = lo;
            var right = start;
            var mid;
            while (left < right) {
                mid = left + right >>> 1;
                if (compare(pivot, array[mid]) < 0) {
                    right = mid;
                }
                else {
                    left = mid + 1;
                }
            }
            var n = start - left;
            switch (n) {
                case 3:
                    array[left + 3] = array[left + 2];
                case 2:
                    array[left + 2] = array[left + 1];
                case 1:
                    array[left + 1] = array[left];
                    break;
                default:
                    while (n > 0) {
                        array[left + n] = array[left + n - 1];
                        n--;
                    }
            }
            array[left] = pivot;
        }
    }
    function gallopLeft(value, array, start, length, hint, compare) {
        var lastOffset = 0;
        var maxOffset = 0;
        var offset = 1;
        if (compare(value, array[start + hint]) > 0) {
            maxOffset = length - hint;
            while (offset < maxOffset && compare(value, array[start + hint + offset]) > 0) {
                lastOffset = offset;
                offset = (offset << 1) + 1;
                if (offset <= 0) {
                    offset = maxOffset;
                }
            }
            if (offset > maxOffset) {
                offset = maxOffset;
            }
            lastOffset += hint;
            offset += hint;
        }
        else {
            maxOffset = hint + 1;
            while (offset < maxOffset && compare(value, array[start + hint - offset]) <= 0) {
                lastOffset = offset;
                offset = (offset << 1) + 1;
                if (offset <= 0) {
                    offset = maxOffset;
                }
            }
            if (offset > maxOffset) {
                offset = maxOffset;
            }
            var tmp = lastOffset;
            lastOffset = hint - offset;
            offset = hint - tmp;
        }
        lastOffset++;
        while (lastOffset < offset) {
            var m = lastOffset + (offset - lastOffset >>> 1);
            if (compare(value, array[start + m]) > 0) {
                lastOffset = m + 1;
            }
            else {
                offset = m;
            }
        }
        return offset;
    }
    function gallopRight(value, array, start, length, hint, compare) {
        var lastOffset = 0;
        var maxOffset = 0;
        var offset = 1;
        if (compare(value, array[start + hint]) < 0) {
            maxOffset = hint + 1;
            while (offset < maxOffset && compare(value, array[start + hint - offset]) < 0) {
                lastOffset = offset;
                offset = (offset << 1) + 1;
                if (offset <= 0) {
                    offset = maxOffset;
                }
            }
            if (offset > maxOffset) {
                offset = maxOffset;
            }
            var tmp = lastOffset;
            lastOffset = hint - offset;
            offset = hint - tmp;
        }
        else {
            maxOffset = length - hint;
            while (offset < maxOffset && compare(value, array[start + hint + offset]) >= 0) {
                lastOffset = offset;
                offset = (offset << 1) + 1;
                if (offset <= 0) {
                    offset = maxOffset;
                }
            }
            if (offset > maxOffset) {
                offset = maxOffset;
            }
            lastOffset += hint;
            offset += hint;
        }
        lastOffset++;
        while (lastOffset < offset) {
            var m = lastOffset + (offset - lastOffset >>> 1);
            if (compare(value, array[start + m]) < 0) {
                offset = m;
            }
            else {
                lastOffset = m + 1;
            }
        }
        return offset;
    }
    function TimSort(array, compare) {
        var minGallop = DEFAULT_MIN_GALLOPING;
        var length = 0;
        var runStart;
        var runLength;
        var stackSize = 0;
        length = array.length;
        var tmp = [];
        runStart = [];
        runLength = [];
        function pushRun(_runStart, _runLength) {
            runStart[stackSize] = _runStart;
            runLength[stackSize] = _runLength;
            stackSize += 1;
        }
        function mergeRuns() {
            while (stackSize > 1) {
                var n = stackSize - 2;
                if ((n >= 1 && runLength[n - 1] <= runLength[n] + runLength[n + 1])
                    || (n >= 2 && runLength[n - 2] <= runLength[n] + runLength[n - 1])) {
                    if (runLength[n - 1] < runLength[n + 1]) {
                        n--;
                    }
                }
                else if (runLength[n] > runLength[n + 1]) {
                    break;
                }
                mergeAt(n);
            }
        }
        function forceMergeRuns() {
            while (stackSize > 1) {
                var n = stackSize - 2;
                if (n > 0 && runLength[n - 1] < runLength[n + 1]) {
                    n--;
                }
                mergeAt(n);
            }
        }
        function mergeAt(i) {
            var start1 = runStart[i];
            var length1 = runLength[i];
            var start2 = runStart[i + 1];
            var length2 = runLength[i + 1];
            runLength[i] = length1 + length2;
            if (i === stackSize - 3) {
                runStart[i + 1] = runStart[i + 2];
                runLength[i + 1] = runLength[i + 2];
            }
            stackSize--;
            var k = gallopRight(array[start2], array, start1, length1, 0, compare);
            start1 += k;
            length1 -= k;
            if (length1 === 0) {
                return;
            }
            length2 = gallopLeft(array[start1 + length1 - 1], array, start2, length2, length2 - 1, compare);
            if (length2 === 0) {
                return;
            }
            if (length1 <= length2) {
                mergeLow(start1, length1, start2, length2);
            }
            else {
                mergeHigh(start1, length1, start2, length2);
            }
        }
        function mergeLow(start1, length1, start2, length2) {
            var i = 0;
            for (i = 0; i < length1; i++) {
                tmp[i] = array[start1 + i];
            }
            var cursor1 = 0;
            var cursor2 = start2;
            var dest = start1;
            array[dest++] = array[cursor2++];
            if (--length2 === 0) {
                for (i = 0; i < length1; i++) {
                    array[dest + i] = tmp[cursor1 + i];
                }
                return;
            }
            if (length1 === 1) {
                for (i = 0; i < length2; i++) {
                    array[dest + i] = array[cursor2 + i];
                }
                array[dest + length2] = tmp[cursor1];
                return;
            }
            var _minGallop = minGallop;
            var count1;
            var count2;
            var exit;
            while (1) {
                count1 = 0;
                count2 = 0;
                exit = false;
                do {
                    if (compare(array[cursor2], tmp[cursor1]) < 0) {
                        array[dest++] = array[cursor2++];
                        count2++;
                        count1 = 0;
                        if (--length2 === 0) {
                            exit = true;
                            break;
                        }
                    }
                    else {
                        array[dest++] = tmp[cursor1++];
                        count1++;
                        count2 = 0;
                        if (--length1 === 1) {
                            exit = true;
                            break;
                        }
                    }
                } while ((count1 | count2) < _minGallop);
                if (exit) {
                    break;
                }
                do {
                    count1 = gallopRight(array[cursor2], tmp, cursor1, length1, 0, compare);
                    if (count1 !== 0) {
                        for (i = 0; i < count1; i++) {
                            array[dest + i] = tmp[cursor1 + i];
                        }
                        dest += count1;
                        cursor1 += count1;
                        length1 -= count1;
                        if (length1 <= 1) {
                            exit = true;
                            break;
                        }
                    }
                    array[dest++] = array[cursor2++];
                    if (--length2 === 0) {
                        exit = true;
                        break;
                    }
                    count2 = gallopLeft(tmp[cursor1], array, cursor2, length2, 0, compare);
                    if (count2 !== 0) {
                        for (i = 0; i < count2; i++) {
                            array[dest + i] = array[cursor2 + i];
                        }
                        dest += count2;
                        cursor2 += count2;
                        length2 -= count2;
                        if (length2 === 0) {
                            exit = true;
                            break;
                        }
                    }
                    array[dest++] = tmp[cursor1++];
                    if (--length1 === 1) {
                        exit = true;
                        break;
                    }
                    _minGallop--;
                } while (count1 >= DEFAULT_MIN_GALLOPING || count2 >= DEFAULT_MIN_GALLOPING);
                if (exit) {
                    break;
                }
                if (_minGallop < 0) {
                    _minGallop = 0;
                }
                _minGallop += 2;
            }
            minGallop = _minGallop;
            minGallop < 1 && (minGallop = 1);
            if (length1 === 1) {
                for (i = 0; i < length2; i++) {
                    array[dest + i] = array[cursor2 + i];
                }
                array[dest + length2] = tmp[cursor1];
            }
            else if (length1 === 0) {
                throw new Error();
            }
            else {
                for (i = 0; i < length1; i++) {
                    array[dest + i] = tmp[cursor1 + i];
                }
            }
        }
        function mergeHigh(start1, length1, start2, length2) {
            var i = 0;
            for (i = 0; i < length2; i++) {
                tmp[i] = array[start2 + i];
            }
            var cursor1 = start1 + length1 - 1;
            var cursor2 = length2 - 1;
            var dest = start2 + length2 - 1;
            var customCursor = 0;
            var customDest = 0;
            array[dest--] = array[cursor1--];
            if (--length1 === 0) {
                customCursor = dest - (length2 - 1);
                for (i = 0; i < length2; i++) {
                    array[customCursor + i] = tmp[i];
                }
                return;
            }
            if (length2 === 1) {
                dest -= length1;
                cursor1 -= length1;
                customDest = dest + 1;
                customCursor = cursor1 + 1;
                for (i = length1 - 1; i >= 0; i--) {
                    array[customDest + i] = array[customCursor + i];
                }
                array[dest] = tmp[cursor2];
                return;
            }
            var _minGallop = minGallop;
            while (true) {
                var count1 = 0;
                var count2 = 0;
                var exit = false;
                do {
                    if (compare(tmp[cursor2], array[cursor1]) < 0) {
                        array[dest--] = array[cursor1--];
                        count1++;
                        count2 = 0;
                        if (--length1 === 0) {
                            exit = true;
                            break;
                        }
                    }
                    else {
                        array[dest--] = tmp[cursor2--];
                        count2++;
                        count1 = 0;
                        if (--length2 === 1) {
                            exit = true;
                            break;
                        }
                    }
                } while ((count1 | count2) < _minGallop);
                if (exit) {
                    break;
                }
                do {
                    count1 = length1 - gallopRight(tmp[cursor2], array, start1, length1, length1 - 1, compare);
                    if (count1 !== 0) {
                        dest -= count1;
                        cursor1 -= count1;
                        length1 -= count1;
                        customDest = dest + 1;
                        customCursor = cursor1 + 1;
                        for (i = count1 - 1; i >= 0; i--) {
                            array[customDest + i] = array[customCursor + i];
                        }
                        if (length1 === 0) {
                            exit = true;
                            break;
                        }
                    }
                    array[dest--] = tmp[cursor2--];
                    if (--length2 === 1) {
                        exit = true;
                        break;
                    }
                    count2 = length2 - gallopLeft(array[cursor1], tmp, 0, length2, length2 - 1, compare);
                    if (count2 !== 0) {
                        dest -= count2;
                        cursor2 -= count2;
                        length2 -= count2;
                        customDest = dest + 1;
                        customCursor = cursor2 + 1;
                        for (i = 0; i < count2; i++) {
                            array[customDest + i] = tmp[customCursor + i];
                        }
                        if (length2 <= 1) {
                            exit = true;
                            break;
                        }
                    }
                    array[dest--] = array[cursor1--];
                    if (--length1 === 0) {
                        exit = true;
                        break;
                    }
                    _minGallop--;
                } while (count1 >= DEFAULT_MIN_GALLOPING || count2 >= DEFAULT_MIN_GALLOPING);
                if (exit) {
                    break;
                }
                if (_minGallop < 0) {
                    _minGallop = 0;
                }
                _minGallop += 2;
            }
            minGallop = _minGallop;
            if (minGallop < 1) {
                minGallop = 1;
            }
            if (length2 === 1) {
                dest -= length1;
                cursor1 -= length1;
                customDest = dest + 1;
                customCursor = cursor1 + 1;
                for (i = length1 - 1; i >= 0; i--) {
                    array[customDest + i] = array[customCursor + i];
                }
                array[dest] = tmp[cursor2];
            }
            else if (length2 === 0) {
                throw new Error();
            }
            else {
                customCursor = dest - (length2 - 1);
                for (i = 0; i < length2; i++) {
                    array[customCursor + i] = tmp[i];
                }
            }
        }
        return {
            mergeRuns: mergeRuns,
            forceMergeRuns: forceMergeRuns,
            pushRun: pushRun
        };
    }
    function sort(array, compare, lo, hi) {
        if (!lo) {
            lo = 0;
        }
        if (!hi) {
            hi = array.length;
        }
        var remaining = hi - lo;
        if (remaining < 2) {
            return;
        }
        var runLength = 0;
        if (remaining < DEFAULT_MIN_MERGE) {
            runLength = makeAscendingRun(array, lo, hi, compare);
            binaryInsertionSort(array, lo, hi, lo + runLength, compare);
            return;
        }
        var ts = TimSort(array, compare);
        var minRun = minRunLength(remaining);
        do {
            runLength = makeAscendingRun(array, lo, hi, compare);
            if (runLength < minRun) {
                var force = remaining;
                if (force > minRun) {
                    force = minRun;
                }
                binaryInsertionSort(array, lo, lo + force, lo + runLength, compare);
                runLength = force;
            }
            ts.pushRun(lo, runLength);
            ts.mergeRuns();
            remaining -= runLength;
            lo += runLength;
        } while (remaining !== 0);
        ts.forceMergeRuns();
    }

    var REDRAW_BIT = 1;
    var STYLE_CHANGED_BIT = 2;
    var SHAPE_CHANGED_BIT = 4;

    var invalidZErrorLogged = false;
    function logInvalidZError() {
        if (invalidZErrorLogged) {
            return;
        }
        invalidZErrorLogged = true;
        console.warn('z / z2 / zlevel of displayable is invalid, which may cause unexpected errors');
    }
    function shapeCompareFunc(a, b) {
        if (a.zlevel === b.zlevel) {
            if (a.z === b.z) {
                return a.z2 - b.z2;
            }
            return a.z - b.z;
        }
        return a.zlevel - b.zlevel;
    }
    var Storage = (function () {
        function Storage() {
            this._roots = [];
            this._displayList = [];
            this._displayListLen = 0;
            this.displayableSortFunc = shapeCompareFunc;
        }
        Storage.prototype.traverse = function (cb, context) {
            for (var i = 0; i < this._roots.length; i++) {
                this._roots[i].traverse(cb, context);
            }
        };
        Storage.prototype.getDisplayList = function (update, includeIgnore) {
            includeIgnore = includeIgnore || false;
            var displayList = this._displayList;
            if (update || !displayList.length) {
                this.updateDisplayList(includeIgnore);
            }
            return displayList;
        };
        Storage.prototype.updateDisplayList = function (includeIgnore) {
            this._displayListLen = 0;
            var roots = this._roots;
            var displayList = this._displayList;
            for (var i = 0, len = roots.length; i < len; i++) {
                this._updateAndAddDisplayable(roots[i], null, includeIgnore);
            }
            displayList.length = this._displayListLen;
            sort(displayList, shapeCompareFunc);
        };
        Storage.prototype._updateAndAddDisplayable = function (el, clipPaths, includeIgnore) {
            if (el.ignore && !includeIgnore) {
                return;
            }
            el.beforeUpdate();
            el.update();
            el.afterUpdate();
            var userSetClipPath = el.getClipPath();
            if (el.ignoreClip) {
                clipPaths = null;
            }
            else if (userSetClipPath) {
                if (clipPaths) {
                    clipPaths = clipPaths.slice();
                }
                else {
                    clipPaths = [];
                }
                var currentClipPath = userSetClipPath;
                var parentClipPath = el;
                while (currentClipPath) {
                    currentClipPath.parent = parentClipPath;
                    currentClipPath.updateTransform();
                    clipPaths.push(currentClipPath);
                    parentClipPath = currentClipPath;
                    currentClipPath = currentClipPath.getClipPath();
                }
            }
            if (el.childrenRef) {
                var children = el.childrenRef();
                for (var i = 0; i < children.length; i++) {
                    var child = children[i];
                    if (el.__dirty) {
                        child.__dirty |= REDRAW_BIT;
                    }
                    this._updateAndAddDisplayable(child, clipPaths, includeIgnore);
                }
                el.__dirty = 0;
            }
            else {
                var disp = el;
                if (clipPaths && clipPaths.length) {
                    disp.__clipPaths = clipPaths;
                }
                else if (disp.__clipPaths && disp.__clipPaths.length > 0) {
                    disp.__clipPaths = [];
                }
                if (isNaN(disp.z)) {
                    logInvalidZError();
                    disp.z = 0;
                }
                if (isNaN(disp.z2)) {
                    logInvalidZError();
                    disp.z2 = 0;
                }
                if (isNaN(disp.zlevel)) {
                    logInvalidZError();
                    disp.zlevel = 0;
                }
                this._displayList[this._displayListLen++] = disp;
            }
            var decalEl = el.getDecalElement && el.getDecalElement();
            if (decalEl) {
                this._updateAndAddDisplayable(decalEl, clipPaths, includeIgnore);
            }
            var textGuide = el.getTextGuideLine();
            if (textGuide) {
                this._updateAndAddDisplayable(textGuide, clipPaths, includeIgnore);
            }
            var textEl = el.getTextContent();
            if (textEl) {
                this._updateAndAddDisplayable(textEl, clipPaths, includeIgnore);
            }
        };
        Storage.prototype.addRoot = function (el) {
            if (el.__zr && el.__zr.storage === this) {
                return;
            }
            this._roots.push(el);
        };
        Storage.prototype.delRoot = function (el) {
            if (el instanceof Array) {
                for (var i = 0, l = el.length; i < l; i++) {
                    this.delRoot(el[i]);
                }
                return;
            }
            var idx = indexOf(this._roots, el);
            if (idx >= 0) {
                this._roots.splice(idx, 1);
            }
        };
        Storage.prototype.delAllRoots = function () {
            this._roots = [];
            this._displayList = [];
            this._displayListLen = 0;
            return;
        };
        Storage.prototype.getRoots = function () {
            return this._roots;
        };
        Storage.prototype.dispose = function () {
            this._displayList = null;
            this._roots = null;
        };
        return Storage;
    }());

    var requestAnimationFrame;
    requestAnimationFrame = (env.hasGlobalWindow
        && ((window.requestAnimationFrame && window.requestAnimationFrame.bind(window))
            || (window.msRequestAnimationFrame && window.msRequestAnimationFrame.bind(window))
            || window.mozRequestAnimationFrame
            || window.webkitRequestAnimationFrame)) || function (func) {
        return setTimeout(func, 16);
    };
    var requestAnimationFrame$1 = requestAnimationFrame;

    var easingFuncs = {
        linear: function (k) {
            return k;
        },
        quadraticIn: function (k) {
            return k * k;
        },
        quadraticOut: function (k) {
            return k * (2 - k);
        },
        quadraticInOut: function (k) {
            if ((k *= 2) < 1) {
                return 0.5 * k * k;
            }
            return -0.5 * (--k * (k - 2) - 1);
        },
        cubicIn: function (k) {
            return k * k * k;
        },
        cubicOut: function (k) {
            return --k * k * k + 1;
        },
        cubicInOut: function (k) {
            if ((k *= 2) < 1) {
                return 0.5 * k * k * k;
            }
            return 0.5 * ((k -= 2) * k * k + 2);
        },
        quarticIn: function (k) {
            return k * k * k * k;
        },
        quarticOut: function (k) {
            return 1 - (--k * k * k * k);
        },
        quarticInOut: function (k) {
            if ((k *= 2) < 1) {
                return 0.5 * k * k * k * k;
            }
            return -0.5 * ((k -= 2) * k * k * k - 2);
        },
        quinticIn: function (k) {
            return k * k * k * k * k;
        },
        quinticOut: function (k) {
            return --k * k * k * k * k + 1;
        },
        quinticInOut: function (k) {
            if ((k *= 2) < 1) {
                return 0.5 * k * k * k * k * k;
            }
            return 0.5 * ((k -= 2) * k * k * k * k + 2);
        },
        sinusoidalIn: function (k) {
            return 1 - Math.cos(k * Math.PI / 2);
        },
        sinusoidalOut: function (k) {
            return Math.sin(k * Math.PI / 2);
        },
        sinusoidalInOut: function (k) {
            return 0.5 * (1 - Math.cos(Math.PI * k));
        },
        exponentialIn: function (k) {
            return k === 0 ? 0 : Math.pow(1024, k - 1);
        },
        exponentialOut: function (k) {
            return k === 1 ? 1 : 1 - Math.pow(2, -10 * k);
        },
        exponentialInOut: function (k) {
            if (k === 0) {
                return 0;
            }
            if (k === 1) {
                return 1;
            }
            if ((k *= 2) < 1) {
                return 0.5 * Math.pow(1024, k - 1);
            }
            return 0.5 * (-Math.pow(2, -10 * (k - 1)) + 2);
        },
        circularIn: function (k) {
            return 1 - Math.sqrt(1 - k * k);
        },
        circularOut: function (k) {
            return Math.sqrt(1 - (--k * k));
        },
        circularInOut: function (k) {
            if ((k *= 2) < 1) {
                return -0.5 * (Math.sqrt(1 - k * k) - 1);
            }
            return 0.5 * (Math.sqrt(1 - (k -= 2) * k) + 1);
        },
        elasticIn: function (k) {
            var s;
            var a = 0.1;
            var p = 0.4;
            if (k === 0) {
                return 0;
            }
            if (k === 1) {
                return 1;
            }
            if (!a || a < 1) {
                a = 1;
                s = p / 4;
            }
            else {
                s = p * Math.asin(1 / a) / (2 * Math.PI);
            }
            return -(a * Math.pow(2, 10 * (k -= 1))
                * Math.sin((k - s) * (2 * Math.PI) / p));
        },
        elasticOut: function (k) {
            var s;
            var a = 0.1;
            var p = 0.4;
            if (k === 0) {
                return 0;
            }
            if (k === 1) {
                return 1;
            }
            if (!a || a < 1) {
                a = 1;
                s = p / 4;
            }
            else {
                s = p * Math.asin(1 / a) / (2 * Math.PI);
            }
            return (a * Math.pow(2, -10 * k)
                * Math.sin((k - s) * (2 * Math.PI) / p) + 1);
        },
        elasticInOut: function (k) {
            var s;
            var a = 0.1;
            var p = 0.4;
            if (k === 0) {
                return 0;
            }
            if (k === 1) {
                return 1;
            }
            if (!a || a < 1) {
                a = 1;
                s = p / 4;
            }
            else {
                s = p * Math.asin(1 / a) / (2 * Math.PI);
            }
            if ((k *= 2) < 1) {
                return -0.5 * (a * Math.pow(2, 10 * (k -= 1))
                    * Math.sin((k - s) * (2 * Math.PI) / p));
            }
            return a * Math.pow(2, -10 * (k -= 1))
                * Math.sin((k - s) * (2 * Math.PI) / p) * 0.5 + 1;
        },
        backIn: function (k) {
            var s = 1.70158;
            return k * k * ((s + 1) * k - s);
        },
        backOut: function (k) {
            var s = 1.70158;
            return --k * k * ((s + 1) * k + s) + 1;
        },
        backInOut: function (k) {
            var s = 1.70158 * 1.525;
            if ((k *= 2) < 1) {
                return 0.5 * (k * k * ((s + 1) * k - s));
            }
            return 0.5 * ((k -= 2) * k * ((s + 1) * k + s) + 2);
        },
        bounceIn: function (k) {
            return 1 - easingFuncs.bounceOut(1 - k);
        },
        bounceOut: function (k) {
            if (k < (1 / 2.75)) {
                return 7.5625 * k * k;
            }
            else if (k < (2 / 2.75)) {
                return 7.5625 * (k -= (1.5 / 2.75)) * k + 0.75;
            }
            else if (k < (2.5 / 2.75)) {
                return 7.5625 * (k -= (2.25 / 2.75)) * k + 0.9375;
            }
            else {
                return 7.5625 * (k -= (2.625 / 2.75)) * k + 0.984375;
            }
        },
        bounceInOut: function (k) {
            if (k < 0.5) {
                return easingFuncs.bounceIn(k * 2) * 0.5;
            }
            return easingFuncs.bounceOut(k * 2 - 1) * 0.5 + 0.5;
        }
    };

    var mathPow = Math.pow;
    var mathSqrt = Math.sqrt;
    var EPSILON = 1e-8;
    var EPSILON_NUMERIC = 1e-4;
    var THREE_SQRT = mathSqrt(3);
    var ONE_THIRD = 1 / 3;
    var _v0 = create();
    var _v1 = create();
    var _v2 = create();
    function isAroundZero(val) {
        return val > -EPSILON && val < EPSILON;
    }
    function isNotAroundZero(val) {
        return val > EPSILON || val < -EPSILON;
    }
    function cubicAt(p0, p1, p2, p3, t) {
        var onet = 1 - t;
        return onet * onet * (onet * p0 + 3 * t * p1)
            + t * t * (t * p3 + 3 * onet * p2);
    }
    function cubicDerivativeAt(p0, p1, p2, p3, t) {
        var onet = 1 - t;
        return 3 * (((p1 - p0) * onet + 2 * (p2 - p1) * t) * onet
            + (p3 - p2) * t * t);
    }
    function cubicRootAt(p0, p1, p2, p3, val, roots) {
        var a = p3 + 3 * (p1 - p2) - p0;
        var b = 3 * (p2 - p1 * 2 + p0);
        var c = 3 * (p1 - p0);
        var d = p0 - val;
        var A = b * b - 3 * a * c;
        var B = b * c - 9 * a * d;
        var C = c * c - 3 * b * d;
        var n = 0;
        if (isAroundZero(A) && isAroundZero(B)) {
            if (isAroundZero(b)) {
                roots[0] = 0;
            }
            else {
                var t1 = -c / b;
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
            }
        }
        else {
            var disc = B * B - 4 * A * C;
            if (isAroundZero(disc)) {
                var K = B / A;
                var t1 = -b / a + K;
                var t2 = -K / 2;
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
                if (t2 >= 0 && t2 <= 1) {
                    roots[n++] = t2;
                }
            }
            else if (disc > 0) {
                var discSqrt = mathSqrt(disc);
                var Y1 = A * b + 1.5 * a * (-B + discSqrt);
                var Y2 = A * b + 1.5 * a * (-B - discSqrt);
                if (Y1 < 0) {
                    Y1 = -mathPow(-Y1, ONE_THIRD);
                }
                else {
                    Y1 = mathPow(Y1, ONE_THIRD);
                }
                if (Y2 < 0) {
                    Y2 = -mathPow(-Y2, ONE_THIRD);
                }
                else {
                    Y2 = mathPow(Y2, ONE_THIRD);
                }
                var t1 = (-b - (Y1 + Y2)) / (3 * a);
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
            }
            else {
                var T = (2 * A * b - 3 * a * B) / (2 * mathSqrt(A * A * A));
                var theta = Math.acos(T) / 3;
                var ASqrt = mathSqrt(A);
                var tmp = Math.cos(theta);
                var t1 = (-b - 2 * ASqrt * tmp) / (3 * a);
                var t2 = (-b + ASqrt * (tmp + THREE_SQRT * Math.sin(theta))) / (3 * a);
                var t3 = (-b + ASqrt * (tmp - THREE_SQRT * Math.sin(theta))) / (3 * a);
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
                if (t2 >= 0 && t2 <= 1) {
                    roots[n++] = t2;
                }
                if (t3 >= 0 && t3 <= 1) {
                    roots[n++] = t3;
                }
            }
        }
        return n;
    }
    function cubicExtrema(p0, p1, p2, p3, extrema) {
        var b = 6 * p2 - 12 * p1 + 6 * p0;
        var a = 9 * p1 + 3 * p3 - 3 * p0 - 9 * p2;
        var c = 3 * p1 - 3 * p0;
        var n = 0;
        if (isAroundZero(a)) {
            if (isNotAroundZero(b)) {
                var t1 = -c / b;
                if (t1 >= 0 && t1 <= 1) {
                    extrema[n++] = t1;
                }
            }
        }
        else {
            var disc = b * b - 4 * a * c;
            if (isAroundZero(disc)) {
                extrema[0] = -b / (2 * a);
            }
            else if (disc > 0) {
                var discSqrt = mathSqrt(disc);
                var t1 = (-b + discSqrt) / (2 * a);
                var t2 = (-b - discSqrt) / (2 * a);
                if (t1 >= 0 && t1 <= 1) {
                    extrema[n++] = t1;
                }
                if (t2 >= 0 && t2 <= 1) {
                    extrema[n++] = t2;
                }
            }
        }
        return n;
    }
    function cubicSubdivide(p0, p1, p2, p3, t, out) {
        var p01 = (p1 - p0) * t + p0;
        var p12 = (p2 - p1) * t + p1;
        var p23 = (p3 - p2) * t + p2;
        var p012 = (p12 - p01) * t + p01;
        var p123 = (p23 - p12) * t + p12;
        var p0123 = (p123 - p012) * t + p012;
        out[0] = p0;
        out[1] = p01;
        out[2] = p012;
        out[3] = p0123;
        out[4] = p0123;
        out[5] = p123;
        out[6] = p23;
        out[7] = p3;
    }
    function cubicProjectPoint(x0, y0, x1, y1, x2, y2, x3, y3, x, y, out) {
        var t;
        var interval = 0.005;
        var d = Infinity;
        var prev;
        var next;
        var d1;
        var d2;
        _v0[0] = x;
        _v0[1] = y;
        for (var _t = 0; _t < 1; _t += 0.05) {
            _v1[0] = cubicAt(x0, x1, x2, x3, _t);
            _v1[1] = cubicAt(y0, y1, y2, y3, _t);
            d1 = distSquare(_v0, _v1);
            if (d1 < d) {
                t = _t;
                d = d1;
            }
        }
        d = Infinity;
        for (var i = 0; i < 32; i++) {
            if (interval < EPSILON_NUMERIC) {
                break;
            }
            prev = t - interval;
            next = t + interval;
            _v1[0] = cubicAt(x0, x1, x2, x3, prev);
            _v1[1] = cubicAt(y0, y1, y2, y3, prev);
            d1 = distSquare(_v1, _v0);
            if (prev >= 0 && d1 < d) {
                t = prev;
                d = d1;
            }
            else {
                _v2[0] = cubicAt(x0, x1, x2, x3, next);
                _v2[1] = cubicAt(y0, y1, y2, y3, next);
                d2 = distSquare(_v2, _v0);
                if (next <= 1 && d2 < d) {
                    t = next;
                    d = d2;
                }
                else {
                    interval *= 0.5;
                }
            }
        }
        if (out) {
            out[0] = cubicAt(x0, x1, x2, x3, t);
            out[1] = cubicAt(y0, y1, y2, y3, t);
        }
        return mathSqrt(d);
    }
    function cubicLength(x0, y0, x1, y1, x2, y2, x3, y3, iteration) {
        var px = x0;
        var py = y0;
        var d = 0;
        var step = 1 / iteration;
        for (var i = 1; i <= iteration; i++) {
            var t = i * step;
            var x = cubicAt(x0, x1, x2, x3, t);
            var y = cubicAt(y0, y1, y2, y3, t);
            var dx = x - px;
            var dy = y - py;
            d += Math.sqrt(dx * dx + dy * dy);
            px = x;
            py = y;
        }
        return d;
    }
    function quadraticAt(p0, p1, p2, t) {
        var onet = 1 - t;
        return onet * (onet * p0 + 2 * t * p1) + t * t * p2;
    }
    function quadraticDerivativeAt(p0, p1, p2, t) {
        return 2 * ((1 - t) * (p1 - p0) + t * (p2 - p1));
    }
    function quadraticRootAt(p0, p1, p2, val, roots) {
        var a = p0 - 2 * p1 + p2;
        var b = 2 * (p1 - p0);
        var c = p0 - val;
        var n = 0;
        if (isAroundZero(a)) {
            if (isNotAroundZero(b)) {
                var t1 = -c / b;
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
            }
        }
        else {
            var disc = b * b - 4 * a * c;
            if (isAroundZero(disc)) {
                var t1 = -b / (2 * a);
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
            }
            else if (disc > 0) {
                var discSqrt = mathSqrt(disc);
                var t1 = (-b + discSqrt) / (2 * a);
                var t2 = (-b - discSqrt) / (2 * a);
                if (t1 >= 0 && t1 <= 1) {
                    roots[n++] = t1;
                }
                if (t2 >= 0 && t2 <= 1) {
                    roots[n++] = t2;
                }
            }
        }
        return n;
    }
    function quadraticExtremum(p0, p1, p2) {
        var divider = p0 + p2 - 2 * p1;
        if (divider === 0) {
            return 0.5;
        }
        else {
            return (p0 - p1) / divider;
        }
    }
    function quadraticSubdivide(p0, p1, p2, t, out) {
        var p01 = (p1 - p0) * t + p0;
        var p12 = (p2 - p1) * t + p1;
        var p012 = (p12 - p01) * t + p01;
        out[0] = p0;
        out[1] = p01;
        out[2] = p012;
        out[3] = p012;
        out[4] = p12;
        out[5] = p2;
    }
    function quadraticProjectPoint(x0, y0, x1, y1, x2, y2, x, y, out) {
        var t;
        var interval = 0.005;
        var d = Infinity;
        _v0[0] = x;
        _v0[1] = y;
        for (var _t = 0; _t < 1; _t += 0.05) {
            _v1[0] = quadraticAt(x0, x1, x2, _t);
            _v1[1] = quadraticAt(y0, y1, y2, _t);
            var d1 = distSquare(_v0, _v1);
            if (d1 < d) {
                t = _t;
                d = d1;
            }
        }
        d = Infinity;
        for (var i = 0; i < 32; i++) {
            if (interval < EPSILON_NUMERIC) {
                break;
            }
            var prev = t - interval;
            var next = t + interval;
            _v1[0] = quadraticAt(x0, x1, x2, prev);
            _v1[1] = quadraticAt(y0, y1, y2, prev);
            var d1 = distSquare(_v1, _v0);
            if (prev >= 0 && d1 < d) {
                t = prev;
                d = d1;
            }
            else {
                _v2[0] = quadraticAt(x0, x1, x2, next);
                _v2[1] = quadraticAt(y0, y1, y2, next);
                var d2 = distSquare(_v2, _v0);
                if (next <= 1 && d2 < d) {
                    t = next;
                    d = d2;
                }
                else {
                    interval *= 0.5;
                }
            }
        }
        if (out) {
            out[0] = quadraticAt(x0, x1, x2, t);
            out[1] = quadraticAt(y0, y1, y2, t);
        }
        return mathSqrt(d);
    }
    function quadraticLength(x0, y0, x1, y1, x2, y2, iteration) {
        var px = x0;
        var py = y0;
        var d = 0;
        var step = 1 / iteration;
        for (var i = 1; i <= iteration; i++) {
            var t = i * step;
            var x = quadraticAt(x0, x1, x2, t);
            var y = quadraticAt(y0, y1, y2, t);
            var dx = x - px;
            var dy = y - py;
            d += Math.sqrt(dx * dx + dy * dy);
            px = x;
            py = y;
        }
        return d;
    }

    var regexp = /cubic-bezier\(([0-9,\.e ]+)\)/;
    function createCubicEasingFunc(cubicEasingStr) {
        var cubic = cubicEasingStr && regexp.exec(cubicEasingStr);
        if (cubic) {
            var points = cubic[1].split(',');
            var a_1 = +trim(points[0]);
            var b_1 = +trim(points[1]);
            var c_1 = +trim(points[2]);
            var d_1 = +trim(points[3]);
            if (isNaN(a_1 + b_1 + c_1 + d_1)) {
                return;
            }
            var roots_1 = [];
            return function (p) {
                return p <= 0
                    ? 0 : p >= 1
                    ? 1
                    : cubicRootAt(0, a_1, c_1, 1, p, roots_1) && cubicAt(0, b_1, d_1, 1, roots_1[0]);
            };
        }
    }

    var Clip = (function () {
        function Clip(opts) {
            this._inited = false;
            this._startTime = 0;
            this._pausedTime = 0;
            this._paused = false;
            this._life = opts.life || 1000;
            this._delay = opts.delay || 0;
            this.loop = opts.loop || false;
            this.onframe = opts.onframe || noop;
            this.ondestroy = opts.ondestroy || noop;
            this.onrestart = opts.onrestart || noop;
            opts.easing && this.setEasing(opts.easing);
        }
        Clip.prototype.step = function (globalTime, deltaTime) {
            if (!this._inited) {
                this._startTime = globalTime + this._delay;
                this._inited = true;
            }
            if (this._paused) {
                this._pausedTime += deltaTime;
                return;
            }
            var life = this._life;
            var elapsedTime = globalTime - this._startTime - this._pausedTime;
            var percent = elapsedTime / life;
            if (percent < 0) {
                percent = 0;
            }
            percent = Math.min(percent, 1);
            var easingFunc = this.easingFunc;
            var schedule = easingFunc ? easingFunc(percent) : percent;
            this.onframe(schedule);
            if (percent === 1) {
                if (this.loop) {
                    var remainder = elapsedTime % life;
                    this._startTime = globalTime - remainder;
                    this._pausedTime = 0;
                    this.onrestart();
                }
                else {
                    return true;
                }
            }
            return false;
        };
        Clip.prototype.pause = function () {
            this._paused = true;
        };
        Clip.prototype.resume = function () {
            this._paused = false;
        };
        Clip.prototype.setEasing = function (easing) {
            this.easing = easing;
            this.easingFunc = isFunction(easing)
                ? easing
                : easingFuncs[easing] || createCubicEasingFunc(easing);
        };
        return Clip;
    }());

    var Entry = (function () {
        function Entry(val) {
            this.value = val;
        }
        return Entry;
    }());
    var LinkedList = (function () {
        function LinkedList() {
            this._len = 0;
        }
        LinkedList.prototype.insert = function (val) {
            var entry = new Entry(val);
            this.insertEntry(entry);
            return entry;
        };
        LinkedList.prototype.insertEntry = function (entry) {
            if (!this.head) {
                this.head = this.tail = entry;
            }
            else {
                this.tail.next = entry;
                entry.prev = this.tail;
                entry.next = null;
                this.tail = entry;
            }
            this._len++;
        };
        LinkedList.prototype.remove = function (entry) {
            var prev = entry.prev;
            var next = entry.next;
            if (prev) {
                prev.next = next;
            }
            else {
                this.head = next;
            }
            if (next) {
                next.prev = prev;
            }
            else {
                this.tail = prev;
            }
            entry.next = entry.prev = null;
            this._len--;
        };
        LinkedList.prototype.len = function () {
            return this._len;
        };
        LinkedList.prototype.clear = function () {
            this.head = this.tail = null;
            this._len = 0;
        };
        return LinkedList;
    }());
    var LRU = (function () {
        function LRU(maxSize) {
            this._list = new LinkedList();
            this._maxSize = 10;
            this._map = {};
            this._maxSize = maxSize;
        }
        LRU.prototype.put = function (key, value) {
            var list = this._list;
            var map = this._map;
            var removed = null;
            if (map[key] == null) {
                var len = list.len();
                var entry = this._lastRemovedEntry;
                if (len >= this._maxSize && len > 0) {
                    var leastUsedEntry = list.head;
                    list.remove(leastUsedEntry);
                    delete map[leastUsedEntry.key];
                    removed = leastUsedEntry.value;
                    this._lastRemovedEntry = leastUsedEntry;
                }
                if (entry) {
                    entry.value = value;
                }
                else {
                    entry = new Entry(value);
                }
                entry.key = key;
                list.insertEntry(entry);
                map[key] = entry;
            }
            return removed;
        };
        LRU.prototype.get = function (key) {
            var entry = this._map[key];
            var list = this._list;
            if (entry != null) {
                if (entry !== list.tail) {
                    list.remove(entry);
                    list.insertEntry(entry);
                }
                return entry.value;
            }
        };
        LRU.prototype.clear = function () {
            this._list.clear();
            this._map = {};
        };
        LRU.prototype.len = function () {
            return this._list.len();
        };
        return LRU;
    }());

    var kCSSColorTable = {
        'transparent': [0, 0, 0, 0], 'aliceblue': [240, 248, 255, 1],
        'antiquewhite': [250, 235, 215, 1], 'aqua': [0, 255, 255, 1],
        'aquamarine': [127, 255, 212, 1], 'azure': [240, 255, 255, 1],
        'beige': [245, 245, 220, 1], 'bisque': [255, 228, 196, 1],
        'black': [0, 0, 0, 1], 'blanchedalmond': [255, 235, 205, 1],
        'blue': [0, 0, 255, 1], 'blueviolet': [138, 43, 226, 1],
        'brown': [165, 42, 42, 1], 'burlywood': [222, 184, 135, 1],
        'cadetblue': [95, 158, 160, 1], 'chartreuse': [127, 255, 0, 1],
        'chocolate': [210, 105, 30, 1], 'coral': [255, 127, 80, 1],
        'cornflowerblue': [100, 149, 237, 1], 'cornsilk': [255, 248, 220, 1],
        'crimson': [220, 20, 60, 1], 'cyan': [0, 255, 255, 1],
        'darkblue': [0, 0, 139, 1], 'darkcyan': [0, 139, 139, 1],
        'darkgoldenrod': [184, 134, 11, 1], 'darkgray': [169, 169, 169, 1],
        'darkgreen': [0, 100, 0, 1], 'darkgrey': [169, 169, 169, 1],
        'darkkhaki': [189, 183, 107, 1], 'darkmagenta': [139, 0, 139, 1],
        'darkolivegreen': [85, 107, 47, 1], 'darkorange': [255, 140, 0, 1],
        'darkorchid': [153, 50, 204, 1], 'darkred': [139, 0, 0, 1],
        'darksalmon': [233, 150, 122, 1], 'darkseagreen': [143, 188, 143, 1],
        'darkslateblue': [72, 61, 139, 1], 'darkslategray': [47, 79, 79, 1],
        'darkslategrey': [47, 79, 79, 1], 'darkturquoise': [0, 206, 209, 1],
        'darkviolet': [148, 0, 211, 1], 'deeppink': [255, 20, 147, 1],
        'deepskyblue': [0, 191, 255, 1], 'dimgray': [105, 105, 105, 1],
        'dimgrey': [105, 105, 105, 1], 'dodgerblue': [30, 144, 255, 1],
        'firebrick': [178, 34, 34, 1], 'floralwhite': [255, 250, 240, 1],
        'forestgreen': [34, 139, 34, 1], 'fuchsia': [255, 0, 255, 1],
        'gainsboro': [220, 220, 220, 1], 'ghostwhite': [248, 248, 255, 1],
        'gold': [255, 215, 0, 1], 'goldenrod': [218, 165, 32, 1],
        'gray': [128, 128, 128, 1], 'green': [0, 128, 0, 1],
        'greenyellow': [173, 255, 47, 1], 'grey': [128, 128, 128, 1],
        'honeydew': [240, 255, 240, 1], 'hotpink': [255, 105, 180, 1],
        'indianred': [205, 92, 92, 1], 'indigo': [75, 0, 130, 1],
        'ivory': [255, 255, 240, 1], 'khaki': [240, 230, 140, 1],
        'lavender': [230, 230, 250, 1], 'lavenderblush': [255, 240, 245, 1],
        'lawngreen': [124, 252, 0, 1], 'lemonchiffon': [255, 250, 205, 1],
        'lightblue': [173, 216, 230, 1], 'lightcoral': [240, 128, 128, 1],
        'lightcyan': [224, 255, 255, 1], 'lightgoldenrodyellow': [250, 250, 210, 1],
        'lightgray': [211, 211, 211, 1], 'lightgreen': [144, 238, 144, 1],
        'lightgrey': [211, 211, 211, 1], 'lightpink': [255, 182, 193, 1],
        'lightsalmon': [255, 160, 122, 1], 'lightseagreen': [32, 178, 170, 1],
        'lightskyblue': [135, 206, 250, 1], 'lightslategray': [119, 136, 153, 1],
        'lightslategrey': [119, 136, 153, 1], 'lightsteelblue': [176, 196, 222, 1],
        'lightyellow': [255, 255, 224, 1], 'lime': [0, 255, 0, 1],
        'limegreen': [50, 205, 50, 1], 'linen': [250, 240, 230, 1],
        'magenta': [255, 0, 255, 1], 'maroon': [128, 0, 0, 1],
        'mediumaquamarine': [102, 205, 170, 1], 'mediumblue': [0, 0, 205, 1],
        'mediumorchid': [186, 85, 211, 1], 'mediumpurple': [147, 112, 219, 1],
        'mediumseagreen': [60, 179, 113, 1], 'mediumslateblue': [123, 104, 238, 1],
        'mediumspringgreen': [0, 250, 154, 1], 'mediumturquoise': [72, 209, 204, 1],
        'mediumvioletred': [199, 21, 133, 1], 'midnightblue': [25, 25, 112, 1],
        'mintcream': [245, 255, 250, 1], 'mistyrose': [255, 228, 225, 1],
        'moccasin': [255, 228, 181, 1], 'navajowhite': [255, 222, 173, 1],
        'navy': [0, 0, 128, 1], 'oldlace': [253, 245, 230, 1],
        'olive': [128, 128, 0, 1], 'olivedrab': [107, 142, 35, 1],
        'orange': [255, 165, 0, 1], 'orangered': [255, 69, 0, 1],
        'orchid': [218, 112, 214, 1], 'palegoldenrod': [238, 232, 170, 1],
        'palegreen': [152, 251, 152, 1], 'paleturquoise': [175, 238, 238, 1],
        'palevioletred': [219, 112, 147, 1], 'papayawhip': [255, 239, 213, 1],
        'peachpuff': [255, 218, 185, 1], 'peru': [205, 133, 63, 1],
        'pink': [255, 192, 203, 1], 'plum': [221, 160, 221, 1],
        'powderblue': [176, 224, 230, 1], 'purple': [128, 0, 128, 1],
        'red': [255, 0, 0, 1], 'rosybrown': [188, 143, 143, 1],
        'royalblue': [65, 105, 225, 1], 'saddlebrown': [139, 69, 19, 1],
        'salmon': [250, 128, 114, 1], 'sandybrown': [244, 164, 96, 1],
        'seagreen': [46, 139, 87, 1], 'seashell': [255, 245, 238, 1],
        'sienna': [160, 82, 45, 1], 'silver': [192, 192, 192, 1],
        'skyblue': [135, 206, 235, 1], 'slateblue': [106, 90, 205, 1],
        'slategray': [112, 128, 144, 1], 'slategrey': [112, 128, 144, 1],
        'snow': [255, 250, 250, 1], 'springgreen': [0, 255, 127, 1],
        'steelblue': [70, 130, 180, 1], 'tan': [210, 180, 140, 1],
        'teal': [0, 128, 128, 1], 'thistle': [216, 191, 216, 1],
        'tomato': [255, 99, 71, 1], 'turquoise': [64, 224, 208, 1],
        'violet': [238, 130, 238, 1], 'wheat': [245, 222, 179, 1],
        'white': [255, 255, 255, 1], 'whitesmoke': [245, 245, 245, 1],
        'yellow': [255, 255, 0, 1], 'yellowgreen': [154, 205, 50, 1]
    };
    function clampCssByte(i) {
        i = Math.round(i);
        return i < 0 ? 0 : i > 255 ? 255 : i;
    }
    function clampCssAngle(i) {
        i = Math.round(i);
        return i < 0 ? 0 : i > 360 ? 360 : i;
    }
    function clampCssFloat(f) {
        return f < 0 ? 0 : f > 1 ? 1 : f;
    }
    function parseCssInt(val) {
        var str = val;
        if (str.length && str.charAt(str.length - 1) === '%') {
            return clampCssByte(parseFloat(str) / 100 * 255);
        }
        return clampCssByte(parseInt(str, 10));
    }
    function parseCssFloat(val) {
        var str = val;
        if (str.length && str.charAt(str.length - 1) === '%') {
            return clampCssFloat(parseFloat(str) / 100);
        }
        return clampCssFloat(parseFloat(str));
    }
    function cssHueToRgb(m1, m2, h) {
        if (h < 0) {
            h += 1;
        }
        else if (h > 1) {
            h -= 1;
        }
        if (h * 6 < 1) {
            return m1 + (m2 - m1) * h * 6;
        }
        if (h * 2 < 1) {
            return m2;
        }
        if (h * 3 < 2) {
            return m1 + (m2 - m1) * (2 / 3 - h) * 6;
        }
        return m1;
    }
    function lerpNumber(a, b, p) {
        return a + (b - a) * p;
    }
    function setRgba(out, r, g, b, a) {
        out[0] = r;
        out[1] = g;
        out[2] = b;
        out[3] = a;
        return out;
    }
    function copyRgba(out, a) {
        out[0] = a[0];
        out[1] = a[1];
        out[2] = a[2];
        out[3] = a[3];
        return out;
    }
    var colorCache = new LRU(20);
    var lastRemovedArr = null;
    function putToCache(colorStr, rgbaArr) {
        if (lastRemovedArr) {
            copyRgba(lastRemovedArr, rgbaArr);
        }
        lastRemovedArr = colorCache.put(colorStr, lastRemovedArr || (rgbaArr.slice()));
    }
    function parse(colorStr, rgbaArr) {
        if (!colorStr) {
            return;
        }
        rgbaArr = rgbaArr || [];
        var cached = colorCache.get(colorStr);
        if (cached) {
            return copyRgba(rgbaArr, cached);
        }
        colorStr = colorStr + '';
        var str = colorStr.replace(/ /g, '').toLowerCase();
        if (str in kCSSColorTable) {
            copyRgba(rgbaArr, kCSSColorTable[str]);
            putToCache(colorStr, rgbaArr);
            return rgbaArr;
        }
        var strLen = str.length;
        if (str.charAt(0) === '#') {
            if (strLen === 4 || strLen === 5) {
                var iv = parseInt(str.slice(1, 4), 16);
                if (!(iv >= 0 && iv <= 0xfff)) {
                    setRgba(rgbaArr, 0, 0, 0, 1);
                    return;
                }
                setRgba(rgbaArr, ((iv & 0xf00) >> 4) | ((iv & 0xf00) >> 8), (iv & 0xf0) | ((iv & 0xf0) >> 4), (iv & 0xf) | ((iv & 0xf) << 4), strLen === 5 ? parseInt(str.slice(4), 16) / 0xf : 1);
                putToCache(colorStr, rgbaArr);
                return rgbaArr;
            }
            else if (strLen === 7 || strLen === 9) {
                var iv = parseInt(str.slice(1, 7), 16);
                if (!(iv >= 0 && iv <= 0xffffff)) {
                    setRgba(rgbaArr, 0, 0, 0, 1);
                    return;
                }
                setRgba(rgbaArr, (iv & 0xff0000) >> 16, (iv & 0xff00) >> 8, iv & 0xff, strLen === 9 ? parseInt(str.slice(7), 16) / 0xff : 1);
                putToCache(colorStr, rgbaArr);
                return rgbaArr;
            }
            return;
        }
        var op = str.indexOf('(');
        var ep = str.indexOf(')');
        if (op !== -1 && ep + 1 === strLen) {
            var fname = str.substr(0, op);
            var params = str.substr(op + 1, ep - (op + 1)).split(',');
            var alpha = 1;
            switch (fname) {
                case 'rgba':
                    if (params.length !== 4) {
                        return params.length === 3
                            ? setRgba(rgbaArr, +params[0], +params[1], +params[2], 1)
                            : setRgba(rgbaArr, 0, 0, 0, 1);
                    }
                    alpha = parseCssFloat(params.pop());
                case 'rgb':
                    if (params.length >= 3) {
                        setRgba(rgbaArr, parseCssInt(params[0]), parseCssInt(params[1]), parseCssInt(params[2]), params.length === 3 ? alpha : parseCssFloat(params[3]));
                        putToCache(colorStr, rgbaArr);
                        return rgbaArr;
                    }
                    else {
                        setRgba(rgbaArr, 0, 0, 0, 1);
                        return;
                    }
                case 'hsla':
                    if (params.length !== 4) {
                        setRgba(rgbaArr, 0, 0, 0, 1);
                        return;
                    }
                    params[3] = parseCssFloat(params[3]);
                    hsla2rgba(params, rgbaArr);
                    putToCache(colorStr, rgbaArr);
                    return rgbaArr;
                case 'hsl':
                    if (params.length !== 3) {
                        setRgba(rgbaArr, 0, 0, 0, 1);
                        return;
                    }
                    hsla2rgba(params, rgbaArr);
                    putToCache(colorStr, rgbaArr);
                    return rgbaArr;
                default:
                    return;
            }
        }
        setRgba(rgbaArr, 0, 0, 0, 1);
        return;
    }
    function hsla2rgba(hsla, rgba) {
        var h = (((parseFloat(hsla[0]) % 360) + 360) % 360) / 360;
        var s = parseCssFloat(hsla[1]);
        var l = parseCssFloat(hsla[2]);
        var m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;
        var m1 = l * 2 - m2;
        rgba = rgba || [];
        setRgba(rgba, clampCssByte(cssHueToRgb(m1, m2, h + 1 / 3) * 255), clampCssByte(cssHueToRgb(m1, m2, h) * 255), clampCssByte(cssHueToRgb(m1, m2, h - 1 / 3) * 255), 1);
        if (hsla.length === 4) {
            rgba[3] = hsla[3];
        }
        return rgba;
    }
    function rgba2hsla(rgba) {
        if (!rgba) {
            return;
        }
        var R = rgba[0] / 255;
        var G = rgba[1] / 255;
        var B = rgba[2] / 255;
        var vMin = Math.min(R, G, B);
        var vMax = Math.max(R, G, B);
        var delta = vMax - vMin;
        var L = (vMax + vMin) / 2;
        var H;
        var S;
        if (delta === 0) {
            H = 0;
            S = 0;
        }
        else {
            if (L < 0.5) {
                S = delta / (vMax + vMin);
            }
            else {
                S = delta / (2 - vMax - vMin);
            }
            var deltaR = (((vMax - R) / 6) + (delta / 2)) / delta;
            var deltaG = (((vMax - G) / 6) + (delta / 2)) / delta;
            var deltaB = (((vMax - B) / 6) + (delta / 2)) / delta;
            if (R === vMax) {
                H = deltaB - deltaG;
            }
            else if (G === vMax) {
                H = (1 / 3) + deltaR - deltaB;
            }
            else if (B === vMax) {
                H = (2 / 3) + deltaG - deltaR;
            }
            if (H < 0) {
                H += 1;
            }
            if (H > 1) {
                H -= 1;
            }
        }
        var hsla = [H * 360, S, L];
        if (rgba[3] != null) {
            hsla.push(rgba[3]);
        }
        return hsla;
    }
    function lift(color, level) {
        var colorArr = parse(color);
        if (colorArr) {
            for (var i = 0; i < 3; i++) {
                if (level < 0) {
                    colorArr[i] = colorArr[i] * (1 - level) | 0;
                }
                else {
                    colorArr[i] = ((255 - colorArr[i]) * level + colorArr[i]) | 0;
                }
                if (colorArr[i] > 255) {
                    colorArr[i] = 255;
                }
                else if (colorArr[i] < 0) {
                    colorArr[i] = 0;
                }
            }
            return stringify(colorArr, colorArr.length === 4 ? 'rgba' : 'rgb');
        }
    }
    function toHex(color) {
        var colorArr = parse(color);
        if (colorArr) {
            return ((1 << 24) + (colorArr[0] << 16) + (colorArr[1] << 8) + (+colorArr[2])).toString(16).slice(1);
        }
    }
    function fastLerp(normalizedValue, colors, out) {
        if (!(colors && colors.length)
            || !(normalizedValue >= 0 && normalizedValue <= 1)) {
            return;
        }
        out = out || [];
        var value = normalizedValue * (colors.length - 1);
        var leftIndex = Math.floor(value);
        var rightIndex = Math.ceil(value);
        var leftColor = colors[leftIndex];
        var rightColor = colors[rightIndex];
        var dv = value - leftIndex;
        out[0] = clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv));
        out[1] = clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv));
        out[2] = clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv));
        out[3] = clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv));
        return out;
    }
    var fastMapToColor = fastLerp;
    function lerp$1(normalizedValue, colors, fullOutput) {
        if (!(colors && colors.length)
            || !(normalizedValue >= 0 && normalizedValue <= 1)) {
            return;
        }
        var value = normalizedValue * (colors.length - 1);
        var leftIndex = Math.floor(value);
        var rightIndex = Math.ceil(value);
        var leftColor = parse(colors[leftIndex]);
        var rightColor = parse(colors[rightIndex]);
        var dv = value - leftIndex;
        var color = stringify([
            clampCssByte(lerpNumber(leftColor[0], rightColor[0], dv)),
            clampCssByte(lerpNumber(leftColor[1], rightColor[1], dv)),
            clampCssByte(lerpNumber(leftColor[2], rightColor[2], dv)),
            clampCssFloat(lerpNumber(leftColor[3], rightColor[3], dv))
        ], 'rgba');
        return fullOutput
            ? {
                color: color,
                leftIndex: leftIndex,
                rightIndex: rightIndex,
                value: value
            }
            : color;
    }
    var mapToColor = lerp$1;
    function modifyHSL(color, h, s, l) {
        var colorArr = parse(color);
        if (color) {
            colorArr = rgba2hsla(colorArr);
            h != null && (colorArr[0] = clampCssAngle(h));
            s != null && (colorArr[1] = parseCssFloat(s));
            l != null && (colorArr[2] = parseCssFloat(l));
            return stringify(hsla2rgba(colorArr), 'rgba');
        }
    }
    function modifyAlpha(color, alpha) {
        var colorArr = parse(color);
        if (colorArr && alpha != null) {
            colorArr[3] = clampCssFloat(alpha);
            return stringify(colorArr, 'rgba');
        }
    }
    function stringify(arrColor, type) {
        if (!arrColor || !arrColor.length) {
            return;
        }
        var colorStr = arrColor[0] + ',' + arrColor[1] + ',' + arrColor[2];
        if (type === 'rgba' || type === 'hsva' || type === 'hsla') {
            colorStr += ',' + arrColor[3];
        }
        return type + '(' + colorStr + ')';
    }
    function lum(color, backgroundLum) {
        var arr = parse(color);
        return arr
            ? (0.299 * arr[0] + 0.587 * arr[1] + 0.114 * arr[2]) * arr[3] / 255
                + (1 - arr[3]) * backgroundLum
            : 0;
    }
    function random() {
        return stringify([
            Math.round(Math.random() * 255),
            Math.round(Math.random() * 255),
            Math.round(Math.random() * 255)
        ], 'rgb');
    }

    var color = /*#__PURE__*/Object.freeze({
        __proto__: null,
        parse: parse,
        lift: lift,
        toHex: toHex,
        fastLerp: fastLerp,
        fastMapToColor: fastMapToColor,
        lerp: lerp$1,
        mapToColor: mapToColor,
        modifyHSL: modifyHSL,
        modifyAlpha: modifyAlpha,
        stringify: stringify,
        lum: lum,
        random: random
    });

    function isLinearGradient(val) {
        return val.type === 'linear';
    }
    function isRadialGradient(val) {
        return val.type === 'radial';
    }

    var arraySlice = Array.prototype.slice;
    function interpolateNumber(p0, p1, percent) {
        return (p1 - p0) * percent + p0;
    }
    function interpolate1DArray(out, p0, p1, percent) {
        var len = p0.length;
        for (var i = 0; i < len; i++) {
            out[i] = interpolateNumber(p0[i], p1[i], percent);
        }
        return out;
    }
    function interpolate2DArray(out, p0, p1, percent) {
        var len = p0.length;
        var len2 = len && p0[0].length;
        for (var i = 0; i < len; i++) {
            if (!out[i]) {
                out[i] = [];
            }
            for (var j = 0; j < len2; j++) {
                out[i][j] = interpolateNumber(p0[i][j], p1[i][j], percent);
            }
        }
        return out;
    }
    function add1DArray(out, p0, p1, sign) {
        var len = p0.length;
        for (var i = 0; i < len; i++) {
            out[i] = p0[i] + p1[i] * sign;
        }
        return out;
    }
    function add2DArray(out, p0, p1, sign) {
        var len = p0.length;
        var len2 = len && p0[0].length;
        for (var i = 0; i < len; i++) {
            if (!out[i]) {
                out[i] = [];
            }
            for (var j = 0; j < len2; j++) {
                out[i][j] = p0[i][j] + p1[i][j] * sign;
            }
        }
        return out;
    }
    function fillColorStops(val0, val1) {
        var len0 = val0.length;
        var len1 = val1.length;
        var shorterArr = len0 > len1 ? val1 : val0;
        var shorterLen = Math.min(len0, len1);
        var last = shorterArr[shorterLen - 1] || { color: [0, 0, 0, 0], offset: 0 };
        for (var i = shorterLen; i < Math.max(len0, len1); i++) {
            shorterArr.push({
                offset: last.offset,
                color: last.color.slice()
            });
        }
    }
    function fillArray(val0, val1, arrDim) {
        var arr0 = val0;
        var arr1 = val1;
        if (!arr0.push || !arr1.push) {
            return;
        }
        var arr0Len = arr0.length;
        var arr1Len = arr1.length;
        if (arr0Len !== arr1Len) {
            var isPreviousLarger = arr0Len > arr1Len;
            if (isPreviousLarger) {
                arr0.length = arr1Len;
            }
            else {
                for (var i = arr0Len; i < arr1Len; i++) {
                    arr0.push(arrDim === 1 ? arr1[i] : arraySlice.call(arr1[i]));
                }
            }
        }
        var len2 = arr0[0] && arr0[0].length;
        for (var i = 0; i < arr0.length; i++) {
            if (arrDim === 1) {
                if (isNaN(arr0[i])) {
                    arr0[i] = arr1[i];
                }
            }
            else {
                for (var j = 0; j < len2; j++) {
                    if (isNaN(arr0[i][j])) {
                        arr0[i][j] = arr1[i][j];
                    }
                }
            }
        }
    }
    function cloneValue(value) {
        if (isArrayLike(value)) {
            var len = value.length;
            if (isArrayLike(value[0])) {
                var ret = [];
                for (var i = 0; i < len; i++) {
                    ret.push(arraySlice.call(value[i]));
                }
                return ret;
            }
            return arraySlice.call(value);
        }
        return value;
    }
    function rgba2String(rgba) {
        rgba[0] = Math.floor(rgba[0]) || 0;
        rgba[1] = Math.floor(rgba[1]) || 0;
        rgba[2] = Math.floor(rgba[2]) || 0;
        rgba[3] = rgba[3] == null ? 1 : rgba[3];
        return 'rgba(' + rgba.join(',') + ')';
    }
    function guessArrayDim(value) {
        return isArrayLike(value && value[0]) ? 2 : 1;
    }
    var VALUE_TYPE_NUMBER = 0;
    var VALUE_TYPE_1D_ARRAY = 1;
    var VALUE_TYPE_2D_ARRAY = 2;
    var VALUE_TYPE_COLOR = 3;
    var VALUE_TYPE_LINEAR_GRADIENT = 4;
    var VALUE_TYPE_RADIAL_GRADIENT = 5;
    var VALUE_TYPE_UNKOWN = 6;
    function isGradientValueType(valType) {
        return valType === VALUE_TYPE_LINEAR_GRADIENT || valType === VALUE_TYPE_RADIAL_GRADIENT;
    }
    function isArrayValueType(valType) {
        return valType === VALUE_TYPE_1D_ARRAY || valType === VALUE_TYPE_2D_ARRAY;
    }
    var tmpRgba = [0, 0, 0, 0];
    var Track = (function () {
        function Track(propName) {
            this.keyframes = [];
            this.discrete = false;
            this._invalid = false;
            this._needsSort = false;
            this._lastFr = 0;
            this._lastFrP = 0;
            this.propName = propName;
        }
        Track.prototype.isFinished = function () {
            return this._finished;
        };
        Track.prototype.setFinished = function () {
            this._finished = true;
            if (this._additiveTrack) {
                this._additiveTrack.setFinished();
            }
        };
        Track.prototype.needsAnimate = function () {
            return this.keyframes.length >= 1;
        };
        Track.prototype.getAdditiveTrack = function () {
            return this._additiveTrack;
        };
        Track.prototype.addKeyframe = function (time, rawValue, easing) {
            this._needsSort = true;
            var keyframes = this.keyframes;
            var len = keyframes.length;
            var discrete = false;
            var valType = VALUE_TYPE_UNKOWN;
            var value = rawValue;
            if (isArrayLike(rawValue)) {
                var arrayDim = guessArrayDim(rawValue);
                valType = arrayDim;
                if (arrayDim === 1 && !isNumber(rawValue[0])
                    || arrayDim === 2 && !isNumber(rawValue[0][0])) {
                    discrete = true;
                }
            }
            else {
                if (isNumber(rawValue) && !eqNaN(rawValue)) {
                    valType = VALUE_TYPE_NUMBER;
                }
                else if (isString(rawValue)) {
                    if (!isNaN(+rawValue)) {
                        valType = VALUE_TYPE_NUMBER;
                    }
                    else {
                        var colorArray = parse(rawValue);
                        if (colorArray) {
                            value = colorArray;
                            valType = VALUE_TYPE_COLOR;
                        }
                    }
                }
                else if (isGradientObject(rawValue)) {
                    var parsedGradient = extend({}, value);
                    parsedGradient.colorStops = map(rawValue.colorStops, function (colorStop) { return ({
                        offset: colorStop.offset,
                        color: parse(colorStop.color)
                    }); });
                    if (isLinearGradient(rawValue)) {
                        valType = VALUE_TYPE_LINEAR_GRADIENT;
                    }
                    else if (isRadialGradient(rawValue)) {
                        valType = VALUE_TYPE_RADIAL_GRADIENT;
                    }
                    value = parsedGradient;
                }
            }
            if (len === 0) {
                this.valType = valType;
            }
            else if (valType !== this.valType || valType === VALUE_TYPE_UNKOWN) {
                discrete = true;
            }
            this.discrete = this.discrete || discrete;
            var kf = {
                time: time,
                value: value,
                rawValue: rawValue,
                percent: 0
            };
            if (easing) {
                kf.easing = easing;
                kf.easingFunc = isFunction(easing)
                    ? easing
                    : easingFuncs[easing] || createCubicEasingFunc(easing);
            }
            keyframes.push(kf);
            return kf;
        };
        Track.prototype.prepare = function (maxTime, additiveTrack) {
            var kfs = this.keyframes;
            if (this._needsSort) {
                kfs.sort(function (a, b) {
                    return a.time - b.time;
                });
            }
            var valType = this.valType;
            var kfsLen = kfs.length;
            var lastKf = kfs[kfsLen - 1];
            var isDiscrete = this.discrete;
            var isArr = isArrayValueType(valType);
            var isGradient = isGradientValueType(valType);
            for (var i = 0; i < kfsLen; i++) {
                var kf = kfs[i];
                var value = kf.value;
                var lastValue = lastKf.value;
                kf.percent = kf.time / maxTime;
                if (!isDiscrete) {
                    if (isArr && i !== kfsLen - 1) {
                        fillArray(value, lastValue, valType);
                    }
                    else if (isGradient) {
                        fillColorStops(value.colorStops, lastValue.colorStops);
                    }
                }
            }
            if (!isDiscrete
                && valType !== VALUE_TYPE_RADIAL_GRADIENT
                && additiveTrack
                && this.needsAnimate()
                && additiveTrack.needsAnimate()
                && valType === additiveTrack.valType
                && !additiveTrack._finished) {
                this._additiveTrack = additiveTrack;
                var startValue = kfs[0].value;
                for (var i = 0; i < kfsLen; i++) {
                    if (valType === VALUE_TYPE_NUMBER) {
                        kfs[i].additiveValue = kfs[i].value - startValue;
                    }
                    else if (valType === VALUE_TYPE_COLOR) {
                        kfs[i].additiveValue =
                            add1DArray([], kfs[i].value, startValue, -1);
                    }
                    else if (isArrayValueType(valType)) {
                        kfs[i].additiveValue = valType === VALUE_TYPE_1D_ARRAY
                            ? add1DArray([], kfs[i].value, startValue, -1)
                            : add2DArray([], kfs[i].value, startValue, -1);
                    }
                }
            }
        };
        Track.prototype.step = function (target, percent) {
            if (this._finished) {
                return;
            }
            if (this._additiveTrack && this._additiveTrack._finished) {
                this._additiveTrack = null;
            }
            var isAdditive = this._additiveTrack != null;
            var valueKey = isAdditive ? 'additiveValue' : 'value';
            var valType = this.valType;
            var keyframes = this.keyframes;
            var kfsNum = keyframes.length;
            var propName = this.propName;
            var isValueColor = valType === VALUE_TYPE_COLOR;
            var frameIdx;
            var lastFrame = this._lastFr;
            var mathMin = Math.min;
            var frame;
            var nextFrame;
            if (kfsNum === 1) {
                frame = nextFrame = keyframes[0];
            }
            else {
                if (percent < 0) {
                    frameIdx = 0;
                }
                else if (percent < this._lastFrP) {
                    var start = mathMin(lastFrame + 1, kfsNum - 1);
                    for (frameIdx = start; frameIdx >= 0; frameIdx--) {
                        if (keyframes[frameIdx].percent <= percent) {
                            break;
                        }
                    }
                    frameIdx = mathMin(frameIdx, kfsNum - 2);
                }
                else {
                    for (frameIdx = lastFrame; frameIdx < kfsNum; frameIdx++) {
                        if (keyframes[frameIdx].percent > percent) {
                            break;
                        }
                    }
                    frameIdx = mathMin(frameIdx - 1, kfsNum - 2);
                }
                nextFrame = keyframes[frameIdx + 1];
                frame = keyframes[frameIdx];
            }
            if (!(frame && nextFrame)) {
                return;
            }
            this._lastFr = frameIdx;
            this._lastFrP = percent;
            var interval = (nextFrame.percent - frame.percent);
            var w = interval === 0 ? 1 : mathMin((percent - frame.percent) / interval, 1);
            if (nextFrame.easingFunc) {
                w = nextFrame.easingFunc(w);
            }
            var targetArr = isAdditive ? this._additiveValue
                : (isValueColor ? tmpRgba : target[propName]);
            if ((isArrayValueType(valType) || isValueColor) && !targetArr) {
                targetArr = this._additiveValue = [];
            }
            if (this.discrete) {
                target[propName] = w < 1 ? frame.rawValue : nextFrame.rawValue;
            }
            else if (isArrayValueType(valType)) {
                valType === VALUE_TYPE_1D_ARRAY
                    ? interpolate1DArray(targetArr, frame[valueKey], nextFrame[valueKey], w)
                    : interpolate2DArray(targetArr, frame[valueKey], nextFrame[valueKey], w);
            }
            else if (isGradientValueType(valType)) {
                var val = frame[valueKey];
                var nextVal_1 = nextFrame[valueKey];
                var isLinearGradient_1 = valType === VALUE_TYPE_LINEAR_GRADIENT;
                target[propName] = {
                    type: isLinearGradient_1 ? 'linear' : 'radial',
                    x: interpolateNumber(val.x, nextVal_1.x, w),
                    y: interpolateNumber(val.y, nextVal_1.y, w),
                    colorStops: map(val.colorStops, function (colorStop, idx) {
                        var nextColorStop = nextVal_1.colorStops[idx];
                        return {
                            offset: interpolateNumber(colorStop.offset, nextColorStop.offset, w),
                            color: rgba2String(interpolate1DArray([], colorStop.color, nextColorStop.color, w))
                        };
                    }),
                    global: nextVal_1.global
                };
                if (isLinearGradient_1) {
                    target[propName].x2 = interpolateNumber(val.x2, nextVal_1.x2, w);
                    target[propName].y2 = interpolateNumber(val.y2, nextVal_1.y2, w);
                }
                else {
                    target[propName].r = interpolateNumber(val.r, nextVal_1.r, w);
                }
            }
            else if (isValueColor) {
                interpolate1DArray(targetArr, frame[valueKey], nextFrame[valueKey], w);
                if (!isAdditive) {
                    target[propName] = rgba2String(targetArr);
                }
            }
            else {
                var value = interpolateNumber(frame[valueKey], nextFrame[valueKey], w);
                if (isAdditive) {
                    this._additiveValue = value;
                }
                else {
                    target[propName] = value;
                }
            }
            if (isAdditive) {
                this._addToTarget(target);
            }
        };
        Track.prototype._addToTarget = function (target) {
            var valType = this.valType;
            var propName = this.propName;
            var additiveValue = this._additiveValue;
            if (valType === VALUE_TYPE_NUMBER) {
                target[propName] = target[propName] + additiveValue;
            }
            else if (valType === VALUE_TYPE_COLOR) {
                parse(target[propName], tmpRgba);
                add1DArray(tmpRgba, tmpRgba, additiveValue, 1);
                target[propName] = rgba2String(tmpRgba);
            }
            else if (valType === VALUE_TYPE_1D_ARRAY) {
                add1DArray(target[propName], target[propName], additiveValue, 1);
            }
            else if (valType === VALUE_TYPE_2D_ARRAY) {
                add2DArray(target[propName], target[propName], additiveValue, 1);
            }
        };
        return Track;
    }());
    var Animator = (function () {
        function Animator(target, loop, allowDiscreteAnimation, additiveTo) {
            this._tracks = {};
            this._trackKeys = [];
            this._maxTime = 0;
            this._started = 0;
            this._clip = null;
            this._target = target;
            this._loop = loop;
            if (loop && additiveTo) {
                logError('Can\' use additive animation on looped animation.');
                return;
            }
            this._additiveAnimators = additiveTo;
            this._allowDiscrete = allowDiscreteAnimation;
        }
        Animator.prototype.getMaxTime = function () {
            return this._maxTime;
        };
        Animator.prototype.getDelay = function () {
            return this._delay;
        };
        Animator.prototype.getLoop = function () {
            return this._loop;
        };
        Animator.prototype.getTarget = function () {
            return this._target;
        };
        Animator.prototype.changeTarget = function (target) {
            this._target = target;
        };
        Animator.prototype.when = function (time, props, easing) {
            return this.whenWithKeys(time, props, keys(props), easing);
        };
        Animator.prototype.whenWithKeys = function (time, props, propNames, easing) {
            var tracks = this._tracks;
            for (var i = 0; i < propNames.length; i++) {
                var propName = propNames[i];
                var track = tracks[propName];
                if (!track) {
                    track = tracks[propName] = new Track(propName);
                    var initialValue = void 0;
                    var additiveTrack = this._getAdditiveTrack(propName);
                    if (additiveTrack) {
                        var addtiveTrackKfs = additiveTrack.keyframes;
                        var lastFinalKf = addtiveTrackKfs[addtiveTrackKfs.length - 1];
                        initialValue = lastFinalKf && lastFinalKf.value;
                        if (additiveTrack.valType === VALUE_TYPE_COLOR && initialValue) {
                            initialValue = rgba2String(initialValue);
                        }
                    }
                    else {
                        initialValue = this._target[propName];
                    }
                    if (initialValue == null) {
                        continue;
                    }
                    if (time > 0) {
                        track.addKeyframe(0, cloneValue(initialValue), easing);
                    }
                    this._trackKeys.push(propName);
                }
                track.addKeyframe(time, cloneValue(props[propName]), easing);
            }
            this._maxTime = Math.max(this._maxTime, time);
            return this;
        };
        Animator.prototype.pause = function () {
            this._clip.pause();
            this._paused = true;
        };
        Animator.prototype.resume = function () {
            this._clip.resume();
            this._paused = false;
        };
        Animator.prototype.isPaused = function () {
            return !!this._paused;
        };
        Animator.prototype.duration = function (duration) {
            this._maxTime = duration;
            this._force = true;
            return this;
        };
        Animator.prototype._doneCallback = function () {
            this._setTracksFinished();
            this._clip = null;
            var doneList = this._doneCbs;
            if (doneList) {
                var len = doneList.length;
                for (var i = 0; i < len; i++) {
                    doneList[i].call(this);
                }
            }
        };
        Animator.prototype._abortedCallback = function () {
            this._setTracksFinished();
            var animation = this.animation;
            var abortedList = this._abortedCbs;
            if (animation) {
                animation.removeClip(this._clip);
            }
            this._clip = null;
            if (abortedList) {
                for (var i = 0; i < abortedList.length; i++) {
                    abortedList[i].call(this);
                }
            }
        };
        Animator.prototype._setTracksFinished = function () {
            var tracks = this._tracks;
            var tracksKeys = this._trackKeys;
            for (var i = 0; i < tracksKeys.length; i++) {
                tracks[tracksKeys[i]].setFinished();
            }
        };
        Animator.prototype._getAdditiveTrack = function (trackName) {
            var additiveTrack;
            var additiveAnimators = this._additiveAnimators;
            if (additiveAnimators) {
                for (var i = 0; i < additiveAnimators.length; i++) {
                    var track = additiveAnimators[i].getTrack(trackName);
                    if (track) {
                        additiveTrack = track;
                    }
                }
            }
            return additiveTrack;
        };
        Animator.prototype.start = function (easing) {
            if (this._started > 0) {
                return;
            }
            this._started = 1;
            var self = this;
            var tracks = [];
            var maxTime = this._maxTime || 0;
            for (var i = 0; i < this._trackKeys.length; i++) {
                var propName = this._trackKeys[i];
                var track = this._tracks[propName];
                var additiveTrack = this._getAdditiveTrack(propName);
                var kfs = track.keyframes;
                var kfsNum = kfs.length;
                track.prepare(maxTime, additiveTrack);
                if (track.needsAnimate()) {
                    if (!this._allowDiscrete && track.discrete) {
                        var lastKf = kfs[kfsNum - 1];
                        if (lastKf) {
                            self._target[track.propName] = lastKf.rawValue;
                        }
                        track.setFinished();
                    }
                    else {
                        tracks.push(track);
                    }
                }
            }
            if (tracks.length || this._force) {
                var clip = new Clip({
                    life: maxTime,
                    loop: this._loop,
                    delay: this._delay || 0,
                    onframe: function (percent) {
                        self._started = 2;
                        var additiveAnimators = self._additiveAnimators;
                        if (additiveAnimators) {
                            var stillHasAdditiveAnimator = false;
                            for (var i = 0; i < additiveAnimators.length; i++) {
                                if (additiveAnimators[i]._clip) {
                                    stillHasAdditiveAnimator = true;
                                    break;
                                }
                            }
                            if (!stillHasAdditiveAnimator) {
                                self._additiveAnimators = null;
                            }
                        }
                        for (var i = 0; i < tracks.length; i++) {
                            tracks[i].step(self._target, percent);
                        }
                        var onframeList = self._onframeCbs;
                        if (onframeList) {
                            for (var i = 0; i < onframeList.length; i++) {
                                onframeList[i](self._target, percent);
                            }
                        }
                    },
                    ondestroy: function () {
                        self._doneCallback();
                    }
                });
                this._clip = clip;
                if (this.animation) {
                    this.animation.addClip(clip);
                }
                if (easing) {
                    clip.setEasing(easing);
                }
            }
            else {
                this._doneCallback();
            }
            return this;
        };
        Animator.prototype.stop = function (forwardToLast) {
            if (!this._clip) {
                return;
            }
            var clip = this._clip;
            if (forwardToLast) {
                clip.onframe(1);
            }
            this._abortedCallback();
        };
        Animator.prototype.delay = function (time) {
            this._delay = time;
            return this;
        };
        Animator.prototype.during = function (cb) {
            if (cb) {
                if (!this._onframeCbs) {
                    this._onframeCbs = [];
                }
                this._onframeCbs.push(cb);
            }
            return this;
        };
        Animator.prototype.done = function (cb) {
            if (cb) {
                if (!this._doneCbs) {
                    this._doneCbs = [];
                }
                this._doneCbs.push(cb);
            }
            return this;
        };
        Animator.prototype.aborted = function (cb) {
            if (cb) {
                if (!this._abortedCbs) {
                    this._abortedCbs = [];
                }
                this._abortedCbs.push(cb);
            }
            return this;
        };
        Animator.prototype.getClip = function () {
            return this._clip;
        };
        Animator.prototype.getTrack = function (propName) {
            return this._tracks[propName];
        };
        Animator.prototype.getTracks = function () {
            var _this = this;
            return map(this._trackKeys, function (key) { return _this._tracks[key]; });
        };
        Animator.prototype.stopTracks = function (propNames, forwardToLast) {
            if (!propNames.length || !this._clip) {
                return true;
            }
            var tracks = this._tracks;
            var tracksKeys = this._trackKeys;
            for (var i = 0; i < propNames.length; i++) {
                var track = tracks[propNames[i]];
                if (track && !track.isFinished()) {
                    if (forwardToLast) {
                        track.step(this._target, 1);
                    }
                    else if (this._started === 1) {
                        track.step(this._target, 0);
                    }
                    track.setFinished();
                }
            }
            var allAborted = true;
            for (var i = 0; i < tracksKeys.length; i++) {
                if (!tracks[tracksKeys[i]].isFinished()) {
                    allAborted = false;
                    break;
                }
            }
            if (allAborted) {
                this._abortedCallback();
            }
            return allAborted;
        };
        Animator.prototype.saveTo = function (target, trackKeys, firstOrLast) {
            if (!target) {
                return;
            }
            trackKeys = trackKeys || this._trackKeys;
            for (var i = 0; i < trackKeys.length; i++) {
                var propName = trackKeys[i];
                var track = this._tracks[propName];
                if (!track || track.isFinished()) {
                    continue;
                }
                var kfs = track.keyframes;
                var kf = kfs[firstOrLast ? 0 : kfs.length - 1];
                if (kf) {
                    target[propName] = cloneValue(kf.rawValue);
                }
            }
        };
        Animator.prototype.__changeFinalValue = function (finalProps, trackKeys) {
            trackKeys = trackKeys || keys(finalProps);
            for (var i = 0; i < trackKeys.length; i++) {
                var propName = trackKeys[i];
                var track = this._tracks[propName];
                if (!track) {
                    continue;
                }
                var kfs = track.keyframes;
                if (kfs.length > 1) {
                    var lastKf = kfs.pop();
                    track.addKeyframe(lastKf.time, finalProps[propName]);
                    track.prepare(this._maxTime, track.getAdditiveTrack());
                }
            }
        };
        return Animator;
    }());

    function getTime() {
        return new Date().getTime();
    }
    var Animation = (function (_super) {
        __extends(Animation, _super);
        function Animation(opts) {
            var _this = _super.call(this) || this;
            _this._running = false;
            _this._time = 0;
            _this._pausedTime = 0;
            _this._pauseStart = 0;
            _this._paused = false;
            opts = opts || {};
            _this.stage = opts.stage || {};
            return _this;
        }
        Animation.prototype.addClip = function (clip) {
            if (clip.animation) {
                this.removeClip(clip);
            }
            if (!this._head) {
                this._head = this._tail = clip;
            }
            else {
                this._tail.next = clip;
                clip.prev = this._tail;
                clip.next = null;
                this._tail = clip;
            }
            clip.animation = this;
        };
        Animation.prototype.addAnimator = function (animator) {
            animator.animation = this;
            var clip = animator.getClip();
            if (clip) {
                this.addClip(clip);
            }
        };
        Animation.prototype.removeClip = function (clip) {
            if (!clip.animation) {
                return;
            }
            var prev = clip.prev;
            var next = clip.next;
            if (prev) {
                prev.next = next;
            }
            else {
                this._head = next;
            }
            if (next) {
                next.prev = prev;
            }
            else {
                this._tail = prev;
            }
            clip.next = clip.prev = clip.animation = null;
        };
        Animation.prototype.removeAnimator = function (animator) {
            var clip = animator.getClip();
            if (clip) {
                this.removeClip(clip);
            }
            animator.animation = null;
        };
        Animation.prototype.update = function (notTriggerFrameAndStageUpdate) {
            var time = getTime() - this._pausedTime;
            var delta = time - this._time;
            var clip = this._head;
            while (clip) {
                var nextClip = clip.next;
                var finished = clip.step(time, delta);
                if (finished) {
                    clip.ondestroy();
                    this.removeClip(clip);
                    clip = nextClip;
                }
                else {
                    clip = nextClip;
                }
            }
            this._time = time;
            if (!notTriggerFrameAndStageUpdate) {
                this.trigger('frame', delta);
                this.stage.update && this.stage.update();
            }
        };
        Animation.prototype._startLoop = function () {
            var self = this;
            this._running = true;
            function step() {
                if (self._running) {
                    requestAnimationFrame$1(step);
                    !self._paused && self.update();
                }
            }
            requestAnimationFrame$1(step);
        };
        Animation.prototype.start = function () {
            if (this._running) {
                return;
            }
            this._time = getTime();
            this._pausedTime = 0;
            this._startLoop();
        };
        Animation.prototype.stop = function () {
            this._running = false;
        };
        Animation.prototype.pause = function () {
            if (!this._paused) {
                this._pauseStart = getTime();
                this._paused = true;
            }
        };
        Animation.prototype.resume = function () {
            if (this._paused) {
                this._pausedTime += getTime() - this._pauseStart;
                this._paused = false;
            }
        };
        Animation.prototype.clear = function () {
            var clip = this._head;
            while (clip) {
                var nextClip = clip.next;
                clip.prev = clip.next = clip.animation = null;
                clip = nextClip;
            }
            this._head = this._tail = null;
        };
        Animation.prototype.isFinished = function () {
            return this._head == null;
        };
        Animation.prototype.animate = function (target, options) {
            options = options || {};
            this.start();
            var animator = new Animator(target, options.loop);
            this.addAnimator(animator);
            return animator;
        };
        return Animation;
    }(Eventful));

    var TOUCH_CLICK_DELAY = 300;
    var globalEventSupported = env.domSupported;
    var localNativeListenerNames = (function () {
        var mouseHandlerNames = [
            'click', 'dblclick', 'mousewheel', 'wheel', 'mouseout',
            'mouseup', 'mousedown', 'mousemove', 'contextmenu'
        ];
        var touchHandlerNames = [
            'touchstart', 'touchend', 'touchmove'
        ];
        var pointerEventNameMap = {
            pointerdown: 1, pointerup: 1, pointermove: 1, pointerout: 1
        };
        var pointerHandlerNames = map(mouseHandlerNames, function (name) {
            var nm = name.replace('mouse', 'pointer');
            return pointerEventNameMap.hasOwnProperty(nm) ? nm : name;
        });
        return {
            mouse: mouseHandlerNames,
            touch: touchHandlerNames,
            pointer: pointerHandlerNames
        };
    })();
    var globalNativeListenerNames = {
        mouse: ['mousemove', 'mouseup'],
        pointer: ['pointermove', 'pointerup']
    };
    var wheelEventSupported = false;
    function isPointerFromTouch(event) {
        var pointerType = event.pointerType;
        return pointerType === 'pen' || pointerType === 'touch';
    }
    function setTouchTimer(scope) {
        scope.touching = true;
        if (scope.touchTimer != null) {
            clearTimeout(scope.touchTimer);
            scope.touchTimer = null;
        }
        scope.touchTimer = setTimeout(function () {
            scope.touching = false;
            scope.touchTimer = null;
        }, 700);
    }
    function markTouch(event) {
        event && (event.zrByTouch = true);
    }
    function normalizeGlobalEvent(instance, event) {
        return normalizeEvent(instance.dom, new FakeGlobalEvent(instance, event), true);
    }
    function isLocalEl(instance, el) {
        var elTmp = el;
        var isLocal = false;
        while (elTmp && elTmp.nodeType !== 9
            && !(isLocal = elTmp.domBelongToZr
                || (elTmp !== el && elTmp === instance.painterRoot))) {
            elTmp = elTmp.parentNode;
        }
        return isLocal;
    }
    var FakeGlobalEvent = (function () {
        function FakeGlobalEvent(instance, event) {
            this.stopPropagation = noop;
            this.stopImmediatePropagation = noop;
            this.preventDefault = noop;
            this.type = event.type;
            this.target = this.currentTarget = instance.dom;
            this.pointerType = event.pointerType;
            this.clientX = event.clientX;
            this.clientY = event.clientY;
        }
        return FakeGlobalEvent;
    }());
    var localDOMHandlers = {
        mousedown: function (event) {
            event = normalizeEvent(this.dom, event);
            this.__mayPointerCapture = [event.zrX, event.zrY];
            this.trigger('mousedown', event);
        },
        mousemove: function (event) {
            event = normalizeEvent(this.dom, event);
            var downPoint = this.__mayPointerCapture;
            if (downPoint && (event.zrX !== downPoint[0] || event.zrY !== downPoint[1])) {
                this.__togglePointerCapture(true);
            }
            this.trigger('mousemove', event);
        },
        mouseup: function (event) {
            event = normalizeEvent(this.dom, event);
            this.__togglePointerCapture(false);
            this.trigger('mouseup', event);
        },
        mouseout: function (event) {
            event = normalizeEvent(this.dom, event);
            var element = event.toElement || event.relatedTarget;
            if (!isLocalEl(this, element)) {
                if (this.__pointerCapturing) {
                    event.zrEventControl = 'no_globalout';
                }
                this.trigger('mouseout', event);
            }
        },
        wheel: function (event) {
            wheelEventSupported = true;
            event = normalizeEvent(this.dom, event);
            this.trigger('mousewheel', event);
        },
        mousewheel: function (event) {
            if (wheelEventSupported) {
                return;
            }
            event = normalizeEvent(this.dom, event);
            this.trigger('mousewheel', event);
        },
        touchstart: function (event) {
            event = normalizeEvent(this.dom, event);
            markTouch(event);
            this.__lastTouchMoment = new Date();
            this.handler.processGesture(event, 'start');
            localDOMHandlers.mousemove.call(this, event);
            localDOMHandlers.mousedown.call(this, event);
        },
        touchmove: function (event) {
            event = normalizeEvent(this.dom, event);
            markTouch(event);
            this.handler.processGesture(event, 'change');
            localDOMHandlers.mousemove.call(this, event);
        },
        touchend: function (event) {
            event = normalizeEvent(this.dom, event);
            markTouch(event);
            this.handler.processGesture(event, 'end');
            localDOMHandlers.mouseup.call(this, event);
            if (+new Date() - (+this.__lastTouchMoment) < TOUCH_CLICK_DELAY) {
                localDOMHandlers.click.call(this, event);
            }
        },
        pointerdown: function (event) {
            localDOMHandlers.mousedown.call(this, event);
        },
        pointermove: function (event) {
            if (!isPointerFromTouch(event)) {
                localDOMHandlers.mousemove.call(this, event);
            }
        },
        pointerup: function (event) {
            localDOMHandlers.mouseup.call(this, event);
        },
        pointerout: function (event) {
            if (!isPointerFromTouch(event)) {
                localDOMHandlers.mouseout.call(this, event);
            }
        }
    };
    each(['click', 'dblclick', 'contextmenu'], function (name) {
        localDOMHandlers[name] = function (event) {
            event = normalizeEvent(this.dom, event);
            this.trigger(name, event);
        };
    });
    var globalDOMHandlers = {
        pointermove: function (event) {
            if (!isPointerFromTouch(event)) {
                globalDOMHandlers.mousemove.call(this, event);
            }
        },
        pointerup: function (event) {
            globalDOMHandlers.mouseup.call(this, event);
        },
        mousemove: function (event) {
            this.trigger('mousemove', event);
        },
        mouseup: function (event) {
            var pointerCaptureReleasing = this.__pointerCapturing;
            this.__togglePointerCapture(false);
            this.trigger('mouseup', event);
            if (pointerCaptureReleasing) {
                event.zrEventControl = 'only_globalout';
                this.trigger('mouseout', event);
            }
        }
    };
    function mountLocalDOMEventListeners(instance, scope) {
        var domHandlers = scope.domHandlers;
        if (env.pointerEventsSupported) {
            each(localNativeListenerNames.pointer, function (nativeEventName) {
                mountSingleDOMEventListener(scope, nativeEventName, function (event) {
                    domHandlers[nativeEventName].call(instance, event);
                });
            });
        }
        else {
            if (env.touchEventsSupported) {
                each(localNativeListenerNames.touch, function (nativeEventName) {
                    mountSingleDOMEventListener(scope, nativeEventName, function (event) {
                        domHandlers[nativeEventName].call(instance, event);
                        setTouchTimer(scope);
                    });
                });
            }
            each(localNativeListenerNames.mouse, function (nativeEventName) {
                mountSingleDOMEventListener(scope, nativeEventName, function (event) {
                    event = getNativeEvent(event);
                    if (!scope.touching) {
                        domHandlers[nativeEventName].call(instance, event);
                    }
                });
            });
        }
    }
    function mountGlobalDOMEventListeners(instance, scope) {
        if (env.pointerEventsSupported) {
            each(globalNativeListenerNames.pointer, mount);
        }
        else if (!env.touchEventsSupported) {
            each(globalNativeListenerNames.mouse, mount);
        }
        function mount(nativeEventName) {
            function nativeEventListener(event) {
                event = getNativeEvent(event);
                if (!isLocalEl(instance, event.target)) {
                    event = normalizeGlobalEvent(instance, event);
                    scope.domHandlers[nativeEventName].call(instance, event);
                }
            }
            mountSingleDOMEventListener(scope, nativeEventName, nativeEventListener, { capture: true });
        }
    }
    function mountSingleDOMEventListener(scope, nativeEventName, listener, opt) {
        scope.mounted[nativeEventName] = listener;
        scope.listenerOpts[nativeEventName] = opt;
        addEventListener(scope.domTarget, nativeEventName, listener, opt);
    }
    function unmountDOMEventListeners(scope) {
        var mounted = scope.mounted;
        for (var nativeEventName in mounted) {
            if (mounted.hasOwnProperty(nativeEventName)) {
                removeEventListener(scope.domTarget, nativeEventName, mounted[nativeEventName], scope.listenerOpts[nativeEventName]);
            }
        }
        scope.mounted = {};
    }
    var DOMHandlerScope = (function () {
        function DOMHandlerScope(domTarget, domHandlers) {
            this.mounted = {};
            this.listenerOpts = {};
            this.touching = false;
            this.domTarget = domTarget;
            this.domHandlers = domHandlers;
        }
        return DOMHandlerScope;
    }());
    var HandlerDomProxy = (function (_super) {
        __extends(HandlerDomProxy, _super);
        function HandlerDomProxy(dom, painterRoot) {
            var _this = _super.call(this) || this;
            _this.__pointerCapturing = false;
            _this.dom = dom;
            _this.painterRoot = painterRoot;
            _this._localHandlerScope = new DOMHandlerScope(dom, localDOMHandlers);
            if (globalEventSupported) {
                _this._globalHandlerScope = new DOMHandlerScope(document, globalDOMHandlers);
            }
            mountLocalDOMEventListeners(_this, _this._localHandlerScope);
            return _this;
        }
        HandlerDomProxy.prototype.dispose = function () {
            unmountDOMEventListeners(this._localHandlerScope);
            if (globalEventSupported) {
                unmountDOMEventListeners(this._globalHandlerScope);
            }
        };
        HandlerDomProxy.prototype.setCursor = function (cursorStyle) {
            this.dom.style && (this.dom.style.cursor = cursorStyle || 'default');
        };
        HandlerDomProxy.prototype.__togglePointerCapture = function (isPointerCapturing) {
            this.__mayPointerCapture = null;
            if (globalEventSupported
                && ((+this.__pointerCapturing) ^ (+isPointerCapturing))) {
                this.__pointerCapturing = isPointerCapturing;
                var globalHandlerScope = this._globalHandlerScope;
                isPointerCapturing
                    ? mountGlobalDOMEventListeners(this, globalHandlerScope)
                    : unmountDOMEventListeners(globalHandlerScope);
            }
        };
        return HandlerDomProxy;
    }(Eventful));

    var dpr = 1;
    if (env.hasGlobalWindow) {
        dpr = Math.max(window.devicePixelRatio
            || (window.screen && window.screen.deviceXDPI / window.screen.logicalXDPI)
            || 1, 1);
    }
    var devicePixelRatio = dpr;
    var DARK_MODE_THRESHOLD = 0.4;
    var DARK_LABEL_COLOR = '#333';
    var LIGHT_LABEL_COLOR = '#ccc';
    var LIGHTER_LABEL_COLOR = '#eee';

    var mIdentity = identity;
    var EPSILON$1 = 5e-5;
    function isNotAroundZero$1(val) {
        return val > EPSILON$1 || val < -EPSILON$1;
    }
    var scaleTmp = [];
    var tmpTransform = [];
    var originTransform = create$1();
    var abs = Math.abs;
    var Transformable = (function () {
        function Transformable() {
        }
        Transformable.prototype.getLocalTransform = function (m) {
            return Transformable.getLocalTransform(this, m);
        };
        Transformable.prototype.setPosition = function (arr) {
            this.x = arr[0];
            this.y = arr[1];
        };
        Transformable.prototype.setScale = function (arr) {
            this.scaleX = arr[0];
            this.scaleY = arr[1];
        };
        Transformable.prototype.setSkew = function (arr) {
            this.skewX = arr[0];
            this.skewY = arr[1];
        };
        Transformable.prototype.setOrigin = function (arr) {
            this.originX = arr[0];
            this.originY = arr[1];
        };
        Transformable.prototype.needLocalTransform = function () {
            return isNotAroundZero$1(this.rotation)
                || isNotAroundZero$1(this.x)
                || isNotAroundZero$1(this.y)
                || isNotAroundZero$1(this.scaleX - 1)
                || isNotAroundZero$1(this.scaleY - 1)
                || isNotAroundZero$1(this.skewX)
                || isNotAroundZero$1(this.skewY);
        };
        Transformable.prototype.updateTransform = function () {
            var parentTransform = this.parent && this.parent.transform;
            var needLocalTransform = this.needLocalTransform();
            var m = this.transform;
            if (!(needLocalTransform || parentTransform)) {
                m && mIdentity(m);
                return;
            }
            m = m || create$1();
            if (needLocalTransform) {
                this.getLocalTransform(m);
            }
            else {
                mIdentity(m);
            }
            if (parentTransform) {
                if (needLocalTransform) {
                    mul$1(m, parentTransform, m);
                }
                else {
                    copy$1(m, parentTransform);
                }
            }
            this.transform = m;
            this._resolveGlobalScaleRatio(m);
        };
        Transformable.prototype._resolveGlobalScaleRatio = function (m) {
            var globalScaleRatio = this.globalScaleRatio;
            if (globalScaleRatio != null && globalScaleRatio !== 1) {
                this.getGlobalScale(scaleTmp);
                var relX = scaleTmp[0] < 0 ? -1 : 1;
                var relY = scaleTmp[1] < 0 ? -1 : 1;
                var sx = ((scaleTmp[0] - relX) * globalScaleRatio + relX) / scaleTmp[0] || 0;
                var sy = ((scaleTmp[1] - relY) * globalScaleRatio + relY) / scaleTmp[1] || 0;
                m[0] *= sx;
                m[1] *= sx;
                m[2] *= sy;
                m[3] *= sy;
            }
            this.invTransform = this.invTransform || create$1();
            invert(this.invTransform, m);
        };
        Transformable.prototype.getComputedTransform = function () {
            var transformNode = this;
            var ancestors = [];
            while (transformNode) {
                ancestors.push(transformNode);
                transformNode = transformNode.parent;
            }
            while (transformNode = ancestors.pop()) {
                transformNode.updateTransform();
            }
            return this.transform;
        };
        Transformable.prototype.setLocalTransform = function (m) {
            if (!m) {
                return;
            }
            var sx = m[0] * m[0] + m[1] * m[1];
            var sy = m[2] * m[2] + m[3] * m[3];
            var rotation = Math.atan2(m[1], m[0]);
            var shearX = Math.PI / 2 + rotation - Math.atan2(m[3], m[2]);
            sy = Math.sqrt(sy) * Math.cos(shearX);
            sx = Math.sqrt(sx);
            this.skewX = shearX;
            this.skewY = 0;
            this.rotation = -rotation;
            this.x = +m[4];
            this.y = +m[5];
            this.scaleX = sx;
            this.scaleY = sy;
            this.originX = 0;
            this.originY = 0;
        };
        Transformable.prototype.decomposeTransform = function () {
            if (!this.transform) {
                return;
            }
            var parent = this.parent;
            var m = this.transform;
            if (parent && parent.transform) {
                mul$1(tmpTransform, parent.invTransform, m);
                m = tmpTransform;
            }
            var ox = this.originX;
            var oy = this.originY;
            if (ox || oy) {
                originTransform[4] = ox;
                originTransform[5] = oy;
                mul$1(tmpTransform, m, originTransform);
                tmpTransform[4] -= ox;
                tmpTransform[5] -= oy;
                m = tmpTransform;
            }
            this.setLocalTransform(m);
        };
        Transformable.prototype.getGlobalScale = function (out) {
            var m = this.transform;
            out = out || [];
            if (!m) {
                out[0] = 1;
                out[1] = 1;
                return out;
            }
            out[0] = Math.sqrt(m[0] * m[0] + m[1] * m[1]);
            out[1] = Math.sqrt(m[2] * m[2] + m[3] * m[3]);
            if (m[0] < 0) {
                out[0] = -out[0];
            }
            if (m[3] < 0) {
                out[1] = -out[1];
            }
            return out;
        };
        Transformable.prototype.transformCoordToLocal = function (x, y) {
            var v2 = [x, y];
            var invTransform = this.invTransform;
            if (invTransform) {
                applyTransform(v2, v2, invTransform);
            }
            return v2;
        };
        Transformable.prototype.transformCoordToGlobal = function (x, y) {
            var v2 = [x, y];
            var transform = this.transform;
            if (transform) {
                applyTransform(v2, v2, transform);
            }
            return v2;
        };
        Transformable.prototype.getLineScale = function () {
            var m = this.transform;
            return m && abs(m[0] - 1) > 1e-10 && abs(m[3] - 1) > 1e-10
                ? Math.sqrt(abs(m[0] * m[3] - m[2] * m[1]))
                : 1;
        };
        Transformable.prototype.copyTransform = function (source) {
            copyTransform(this, source);
        };
        Transformable.getLocalTransform = function (target, m) {
            m = m || [];
            var ox = target.originX || 0;
            var oy = target.originY || 0;
            var sx = target.scaleX;
            var sy = target.scaleY;
            var ax = target.anchorX;
            var ay = target.anchorY;
            var rotation = target.rotation || 0;
            var x = target.x;
            var y = target.y;
            var skewX = target.skewX ? Math.tan(target.skewX) : 0;
            var skewY = target.skewY ? Math.tan(-target.skewY) : 0;
            if (ox || oy || ax || ay) {
                var dx = ox + ax;
                var dy = oy + ay;
                m[4] = -dx * sx - skewX * dy * sy;
                m[5] = -dy * sy - skewY * dx * sx;
            }
            else {
                m[4] = m[5] = 0;
            }
            m[0] = sx;
            m[3] = sy;
            m[1] = skewY * sx;
            m[2] = skewX * sy;
            rotation && rotate(m, m, rotation);
            m[4] += ox + x;
            m[5] += oy + y;
            return m;
        };
        Transformable.initDefaultProps = (function () {
            var proto = Transformable.prototype;
            proto.scaleX =
                proto.scaleY =
                    proto.globalScaleRatio = 1;
            proto.x =
                proto.y =
                    proto.originX =
                        proto.originY =
                            proto.skewX =
                                proto.skewY =
                                    proto.rotation =
                                        proto.anchorX =
                                            proto.anchorY = 0;
        })();
        return Transformable;
    }());
    var TRANSFORMABLE_PROPS = [
        'x', 'y', 'originX', 'originY', 'anchorX', 'anchorY', 'rotation', 'scaleX', 'scaleY', 'skewX', 'skewY'
    ];
    function copyTransform(target, source) {
        for (var i = 0; i < TRANSFORMABLE_PROPS.length; i++) {
            var propName = TRANSFORMABLE_PROPS[i];
            target[propName] = source[propName];
        }
    }

    var textWidthCache = {};
    function getWidth(text, font) {
        font = font || DEFAULT_FONT;
        var cacheOfFont = textWidthCache[font];
        if (!cacheOfFont) {
            cacheOfFont = textWidthCache[font] = new LRU(500);
        }
        var width = cacheOfFont.get(text);
        if (width == null) {
            width = platformApi.measureText(text, font).width;
            cacheOfFont.put(text, width);
        }
        return width;
    }
    function innerGetBoundingRect(text, font, textAlign, textBaseline) {
        var width = getWidth(text, font);
        var height = getLineHeight(font);
        var x = adjustTextX(0, width, textAlign);
        var y = adjustTextY(0, height, textBaseline);
        var rect = new BoundingRect(x, y, width, height);
        return rect;
    }
    function getBoundingRect(text, font, textAlign, textBaseline) {
        var textLines = ((text || '') + '').split('\n');
        var len = textLines.length;
        if (len === 1) {
            return innerGetBoundingRect(textLines[0], font, textAlign, textBaseline);
        }
        else {
            var uniondRect = new BoundingRect(0, 0, 0, 0);
            for (var i = 0; i < textLines.length; i++) {
                var rect = innerGetBoundingRect(textLines[i], font, textAlign, textBaseline);
                i === 0 ? uniondRect.copy(rect) : uniondRect.union(rect);
            }
            return uniondRect;
        }
    }
    function adjustTextX(x, width, textAlign) {
        if (textAlign === 'right') {
            x -= width;
        }
        else if (textAlign === 'center') {
            x -= width / 2;
        }
        return x;
    }
    function adjustTextY(y, height, verticalAlign) {
        if (verticalAlign === 'middle') {
            y -= height / 2;
        }
        else if (verticalAlign === 'bottom') {
            y -= height;
        }
        return y;
    }
    function getLineHeight(font) {
        return getWidth('国', font);
    }
    function parsePercent(value, maxValue) {
        if (typeof value === 'string') {
            if (value.lastIndexOf('%') >= 0) {
                return parseFloat(value) / 100 * maxValue;
            }
            return parseFloat(value);
        }
        return value;
    }
    function calculateTextPosition(out, opts, rect) {
        var textPosition = opts.position || 'inside';
        var distance = opts.distance != null ? opts.distance : 5;
        var height = rect.height;
        var width = rect.width;
        var halfHeight = height / 2;
        var x = rect.x;
        var y = rect.y;
        var textAlign = 'left';
        var textVerticalAlign = 'top';
        if (textPosition instanceof Array) {
            x += parsePercent(textPosition[0], rect.width);
            y += parsePercent(textPosition[1], rect.height);
            textAlign = null;
            textVerticalAlign = null;
        }
        else {
            switch (textPosition) {
                case 'left':
                    x -= distance;
                    y += halfHeight;
                    textAlign = 'right';
                    textVerticalAlign = 'middle';
                    break;
                case 'right':
                    x += distance + width;
                    y += halfHeight;
                    textVerticalAlign = 'middle';
                    break;
                case 'top':
                    x += width / 2;
                    y -= distance;
                    textAlign = 'center';
                    textVerticalAlign = 'bottom';
                    break;
                case 'bottom':
                    x += width / 2;
                    y += height + distance;
                    textAlign = 'center';
                    break;
                case 'inside':
                    x += width / 2;
                    y += halfHeight;
                    textAlign = 'center';
                    textVerticalAlign = 'middle';
                    break;
                case 'insideLeft':
                    x += distance;
                    y += halfHeight;
                    textVerticalAlign = 'middle';
                    break;
                case 'insideRight':
                    x += width - distance;
                    y += halfHeight;
                    textAlign = 'right';
                    textVerticalAlign = 'middle';
                    break;
                case 'insideTop':
                    x += width / 2;
                    y += distance;
                    textAlign = 'center';
                    break;
                case 'insideBottom':
                    x += width / 2;
                    y += height - distance;
                    textAlign = 'center';
                    textVerticalAlign = 'bottom';
                    break;
                case 'insideTopLeft':
                    x += distance;
                    y += distance;
                    break;
                case 'insideTopRight':
                    x += width - distance;
                    y += distance;
                    textAlign = 'right';
                    break;
                case 'insideBottomLeft':
                    x += distance;
                    y += height - distance;
                    textVerticalAlign = 'bottom';
                    break;
                case 'insideBottomRight':
                    x += width - distance;
                    y += height - distance;
                    textAlign = 'right';
                    textVerticalAlign = 'bottom';
                    break;
            }
        }
        out = out || {};
        out.x = x;
        out.y = y;
        out.align = textAlign;
        out.verticalAlign = textVerticalAlign;
        return out;
    }

    var PRESERVED_NORMAL_STATE = '__zr_normal__';
    var PRIMARY_STATES_KEYS = TRANSFORMABLE_PROPS.concat(['ignore']);
    var DEFAULT_ANIMATABLE_MAP = reduce(TRANSFORMABLE_PROPS, function (obj, key) {
        obj[key] = true;
        return obj;
    }, { ignore: false });
    var tmpTextPosCalcRes = {};
    var tmpBoundingRect = new BoundingRect(0, 0, 0, 0);
    var Element = (function () {
        function Element(props) {
            this.id = guid();
            this.animators = [];
            this.currentStates = [];
            this.states = {};
            this._init(props);
        }
        Element.prototype._init = function (props) {
            this.attr(props);
        };
        Element.prototype.drift = function (dx, dy, e) {
            switch (this.draggable) {
                case 'horizontal':
                    dy = 0;
                    break;
                case 'vertical':
                    dx = 0;
                    break;
            }
            var m = this.transform;
            if (!m) {
                m = this.transform = [1, 0, 0, 1, 0, 0];
            }
            m[4] += dx;
            m[5] += dy;
            this.decomposeTransform();
            this.markRedraw();
        };
        Element.prototype.beforeUpdate = function () { };
        Element.prototype.afterUpdate = function () { };
        Element.prototype.update = function () {
            this.updateTransform();
            if (this.__dirty) {
                this.updateInnerText();
            }
        };
        Element.prototype.updateInnerText = function (forceUpdate) {
            var textEl = this._textContent;
            if (textEl && (!textEl.ignore || forceUpdate)) {
                if (!this.textConfig) {
                    this.textConfig = {};
                }
                var textConfig = this.textConfig;
                var isLocal = textConfig.local;
                var innerTransformable = textEl.innerTransformable;
                var textAlign = void 0;
                var textVerticalAlign = void 0;
                var textStyleChanged = false;
                innerTransformable.parent = isLocal ? this : null;
                var innerOrigin = false;
                innerTransformable.copyTransform(textEl);
                if (textConfig.position != null) {
                    var layoutRect = tmpBoundingRect;
                    if (textConfig.layoutRect) {
                        layoutRect.copy(textConfig.layoutRect);
                    }
                    else {
                        layoutRect.copy(this.getBoundingRect());
                    }
                    if (!isLocal) {
                        layoutRect.applyTransform(this.transform);
                    }
                    if (this.calculateTextPosition) {
                        this.calculateTextPosition(tmpTextPosCalcRes, textConfig, layoutRect);
                    }
                    else {
                        calculateTextPosition(tmpTextPosCalcRes, textConfig, layoutRect);
                    }
                    innerTransformable.x = tmpTextPosCalcRes.x;
                    innerTransformable.y = tmpTextPosCalcRes.y;
                    textAlign = tmpTextPosCalcRes.align;
                    textVerticalAlign = tmpTextPosCalcRes.verticalAlign;
                    var textOrigin = textConfig.origin;
                    if (textOrigin && textConfig.rotation != null) {
                        var relOriginX = void 0;
                        var relOriginY = void 0;
                        if (textOrigin === 'center') {
                            relOriginX = layoutRect.width * 0.5;
                            relOriginY = layoutRect.height * 0.5;
                        }
                        else {
                            relOriginX = parsePercent(textOrigin[0], layoutRect.width);
                            relOriginY = parsePercent(textOrigin[1], layoutRect.height);
                        }
                        innerOrigin = true;
                        innerTransformable.originX = -innerTransformable.x + relOriginX + (isLocal ? 0 : layoutRect.x);
                        innerTransformable.originY = -innerTransformable.y + relOriginY + (isLocal ? 0 : layoutRect.y);
                    }
                }
                if (textConfig.rotation != null) {
                    innerTransformable.rotation = textConfig.rotation;
                }
                var textOffset = textConfig.offset;
                if (textOffset) {
                    innerTransformable.x += textOffset[0];
                    innerTransformable.y += textOffset[1];
                    if (!innerOrigin) {
                        innerTransformable.originX = -textOffset[0];
                        innerTransformable.originY = -textOffset[1];
                    }
                }
                var isInside = textConfig.inside == null
                    ? (typeof textConfig.position === 'string' && textConfig.position.indexOf('inside') >= 0)
                    : textConfig.inside;
                var innerTextDefaultStyle = this._innerTextDefaultStyle || (this._innerTextDefaultStyle = {});
                var textFill = void 0;
                var textStroke = void 0;
                var autoStroke = void 0;
                if (isInside && this.canBeInsideText()) {
                    textFill = textConfig.insideFill;
                    textStroke = textConfig.insideStroke;
                    if (textFill == null || textFill === 'auto') {
                        textFill = this.getInsideTextFill();
                    }
                    if (textStroke == null || textStroke === 'auto') {
                        textStroke = this.getInsideTextStroke(textFill);
                        autoStroke = true;
                    }
                }
                else {
                    textFill = textConfig.outsideFill;
                    textStroke = textConfig.outsideStroke;
                    if (textFill == null || textFill === 'auto') {
                        textFill = this.getOutsideFill();
                    }
                    if (textStroke == null || textStroke === 'auto') {
                        textStroke = this.getOutsideStroke(textFill);
                        autoStroke = true;
                    }
                }
                textFill = textFill || '#000';
                if (textFill !== innerTextDefaultStyle.fill
                    || textStroke !== innerTextDefaultStyle.stroke
                    || autoStroke !== innerTextDefaultStyle.autoStroke
                    || textAlign !== innerTextDefaultStyle.align
                    || textVerticalAlign !== innerTextDefaultStyle.verticalAlign) {
                    textStyleChanged = true;
                    innerTextDefaultStyle.fill = textFill;
                    innerTextDefaultStyle.stroke = textStroke;
                    innerTextDefaultStyle.autoStroke = autoStroke;
                    innerTextDefaultStyle.align = textAlign;
                    innerTextDefaultStyle.verticalAlign = textVerticalAlign;
                    textEl.setDefaultTextStyle(innerTextDefaultStyle);
                }
                textEl.__dirty |= REDRAW_BIT;
                if (textStyleChanged) {
                    textEl.dirtyStyle(true);
                }
            }
        };
        Element.prototype.canBeInsideText = function () {
            return true;
        };
        Element.prototype.getInsideTextFill = function () {
            return '#fff';
        };
        Element.prototype.getInsideTextStroke = function (textFill) {
            return '#000';
        };
        Element.prototype.getOutsideFill = function () {
            return this.__zr && this.__zr.isDarkMode() ? LIGHT_LABEL_COLOR : DARK_LABEL_COLOR;
        };
        Element.prototype.getOutsideStroke = function (textFill) {
            var backgroundColor = this.__zr && this.__zr.getBackgroundColor();
            var colorArr = typeof backgroundColor === 'string' && parse(backgroundColor);
            if (!colorArr) {
                colorArr = [255, 255, 255, 1];
            }
            var alpha = colorArr[3];
            var isDark = this.__zr.isDarkMode();
            for (var i = 0; i < 3; i++) {
                colorArr[i] = colorArr[i] * alpha + (isDark ? 0 : 255) * (1 - alpha);
            }
            colorArr[3] = 1;
            return stringify(colorArr, 'rgba');
        };
        Element.prototype.traverse = function (cb, context) { };
        Element.prototype.attrKV = function (key, value) {
            if (key === 'textConfig') {
                this.setTextConfig(value);
            }
            else if (key === 'textContent') {
                this.setTextContent(value);
            }
            else if (key === 'clipPath') {
                this.setClipPath(value);
            }
            else if (key === 'extra') {
                this.extra = this.extra || {};
                extend(this.extra, value);
            }
            else {
                this[key] = value;
            }
        };
        Element.prototype.hide = function () {
            this.ignore = true;
            this.markRedraw();
        };
        Element.prototype.show = function () {
            this.ignore = false;
            this.markRedraw();
        };
        Element.prototype.attr = function (keyOrObj, value) {
            if (typeof keyOrObj === 'string') {
                this.attrKV(keyOrObj, value);
            }
            else if (isObject(keyOrObj)) {
                var obj = keyOrObj;
                var keysArr = keys(obj);
                for (var i = 0; i < keysArr.length; i++) {
                    var key = keysArr[i];
                    this.attrKV(key, keyOrObj[key]);
                }
            }
            this.markRedraw();
            return this;
        };
        Element.prototype.saveCurrentToNormalState = function (toState) {
            this._innerSaveToNormal(toState);
            var normalState = this._normalState;
            for (var i = 0; i < this.animators.length; i++) {
                var animator = this.animators[i];
                var fromStateTransition = animator.__fromStateTransition;
                if (animator.getLoop() || fromStateTransition && fromStateTransition !== PRESERVED_NORMAL_STATE) {
                    continue;
                }
                var targetName = animator.targetName;
                var target = targetName
                    ? normalState[targetName] : normalState;
                animator.saveTo(target);
            }
        };
        Element.prototype._innerSaveToNormal = function (toState) {
            var normalState = this._normalState;
            if (!normalState) {
                normalState = this._normalState = {};
            }
            if (toState.textConfig && !normalState.textConfig) {
                normalState.textConfig = this.textConfig;
            }
            this._savePrimaryToNormal(toState, normalState, PRIMARY_STATES_KEYS);
        };
        Element.prototype._savePrimaryToNormal = function (toState, normalState, primaryKeys) {
            for (var i = 0; i < primaryKeys.length; i++) {
                var key = primaryKeys[i];
                if (toState[key] != null && !(key in normalState)) {
                    normalState[key] = this[key];
                }
            }
        };
        Element.prototype.hasState = function () {
            return this.currentStates.length > 0;
        };
        Element.prototype.getState = function (name) {
            return this.states[name];
        };
        Element.prototype.ensureState = function (name) {
            var states = this.states;
            if (!states[name]) {
                states[name] = {};
            }
            return states[name];
        };
        Element.prototype.clearStates = function (noAnimation) {
            this.useState(PRESERVED_NORMAL_STATE, false, noAnimation);
        };
        Element.prototype.useState = function (stateName, keepCurrentStates, noAnimation, forceUseHoverLayer) {
            var toNormalState = stateName === PRESERVED_NORMAL_STATE;
            var hasStates = this.hasState();
            if (!hasStates && toNormalState) {
                return;
            }
            var currentStates = this.currentStates;
            var animationCfg = this.stateTransition;
            if (indexOf(currentStates, stateName) >= 0 && (keepCurrentStates || currentStates.length === 1)) {
                return;
            }
            var state;
            if (this.stateProxy && !toNormalState) {
                state = this.stateProxy(stateName);
            }
            if (!state) {
                state = (this.states && this.states[stateName]);
            }
            if (!state && !toNormalState) {
                logError("State " + stateName + " not exists.");
                return;
            }
            if (!toNormalState) {
                this.saveCurrentToNormalState(state);
            }
            var useHoverLayer = !!((state && state.hoverLayer) || forceUseHoverLayer);
            if (useHoverLayer) {
                this._toggleHoverLayerFlag(true);
            }
            this._applyStateObj(stateName, state, this._normalState, keepCurrentStates, !noAnimation && !this.__inHover && animationCfg && animationCfg.duration > 0, animationCfg);
            var textContent = this._textContent;
            var textGuide = this._textGuide;
            if (textContent) {
                textContent.useState(stateName, keepCurrentStates, noAnimation, useHoverLayer);
            }
            if (textGuide) {
                textGuide.useState(stateName, keepCurrentStates, noAnimation, useHoverLayer);
            }
            if (toNormalState) {
                this.currentStates = [];
                this._normalState = {};
            }
            else {
                if (!keepCurrentStates) {
                    this.currentStates = [stateName];
                }
                else {
                    this.currentStates.push(stateName);
                }
            }
            this._updateAnimationTargets();
            this.markRedraw();
            if (!useHoverLayer && this.__inHover) {
                this._toggleHoverLayerFlag(false);
                this.__dirty &= ~REDRAW_BIT;
            }
            return state;
        };
        Element.prototype.useStates = function (states, noAnimation, forceUseHoverLayer) {
            if (!states.length) {
                this.clearStates();
            }
            else {
                var stateObjects = [];
                var currentStates = this.currentStates;
                var len = states.length;
                var notChange = len === currentStates.length;
                if (notChange) {
                    for (var i = 0; i < len; i++) {
                        if (states[i] !== currentStates[i]) {
                            notChange = false;
                            break;
                        }
                    }
                }
                if (notChange) {
                    return;
                }
                for (var i = 0; i < len; i++) {
                    var stateName = states[i];
                    var stateObj = void 0;
                    if (this.stateProxy) {
                        stateObj = this.stateProxy(stateName, states);
                    }
                    if (!stateObj) {
                        stateObj = this.states[stateName];
                    }
                    if (stateObj) {
                        stateObjects.push(stateObj);
                    }
                }
                var lastStateObj = stateObjects[len - 1];
                var useHoverLayer = !!((lastStateObj && lastStateObj.hoverLayer) || forceUseHoverLayer);
                if (useHoverLayer) {
                    this._toggleHoverLayerFlag(true);
                }
                var mergedState = this._mergeStates(stateObjects);
                var animationCfg = this.stateTransition;
                this.saveCurrentToNormalState(mergedState);
                this._applyStateObj(states.join(','), mergedState, this._normalState, false, !noAnimation && !this.__inHover && animationCfg && animationCfg.duration > 0, animationCfg);
                var textContent = this._textContent;
                var textGuide = this._textGuide;
                if (textContent) {
                    textContent.useStates(states, noAnimation, useHoverLayer);
                }
                if (textGuide) {
                    textGuide.useStates(states, noAnimation, useHoverLayer);
                }
                this._updateAnimationTargets();
                this.currentStates = states.slice();
                this.markRedraw();
                if (!useHoverLayer && this.__inHover) {
                    this._toggleHoverLayerFlag(false);
                    this.__dirty &= ~REDRAW_BIT;
                }
            }
        };
        Element.prototype._updateAnimationTargets = function () {
            for (var i = 0; i < this.animators.length; i++) {
                var animator = this.animators[i];
                if (animator.targetName) {
                    animator.changeTarget(this[animator.targetName]);
                }
            }
        };
        Element.prototype.removeState = function (state) {
            var idx = indexOf(this.currentStates, state);
            if (idx >= 0) {
                var currentStates = this.currentStates.slice();
                currentStates.splice(idx, 1);
                this.useStates(currentStates);
            }
        };
        Element.prototype.replaceState = function (oldState, newState, forceAdd) {
            var currentStates = this.currentStates.slice();
            var idx = indexOf(currentStates, oldState);
            var newStateExists = indexOf(currentStates, newState) >= 0;
            if (idx >= 0) {
                if (!newStateExists) {
                    currentStates[idx] = newState;
                }
                else {
                    currentStates.splice(idx, 1);
                }
            }
            else if (forceAdd && !newStateExists) {
                currentStates.push(newState);
            }
            this.useStates(currentStates);
        };
        Element.prototype.toggleState = function (state, enable) {
            if (enable) {
                this.useState(state, true);
            }
            else {
                this.removeState(state);
            }
        };
        Element.prototype._mergeStates = function (states) {
            var mergedState = {};
            var mergedTextConfig;
            for (var i = 0; i < states.length; i++) {
                var state = states[i];
                extend(mergedState, state);
                if (state.textConfig) {
                    mergedTextConfig = mergedTextConfig || {};
                    extend(mergedTextConfig, state.textConfig);
                }
            }
            if (mergedTextConfig) {
                mergedState.textConfig = mergedTextConfig;
            }
            return mergedState;
        };
        Element.prototype._applyStateObj = function (stateName, state, normalState, keepCurrentStates, transition, animationCfg) {
            var needsRestoreToNormal = !(state && keepCurrentStates);
            if (state && state.textConfig) {
                this.textConfig = extend({}, keepCurrentStates ? this.textConfig : normalState.textConfig);
                extend(this.textConfig, state.textConfig);
            }
            else if (needsRestoreToNormal) {
                if (normalState.textConfig) {
                    this.textConfig = normalState.textConfig;
                }
            }
            var transitionTarget = {};
            var hasTransition = false;
            for (var i = 0; i < PRIMARY_STATES_KEYS.length; i++) {
                var key = PRIMARY_STATES_KEYS[i];
                var propNeedsTransition = transition && DEFAULT_ANIMATABLE_MAP[key];
                if (state && state[key] != null) {
                    if (propNeedsTransition) {
                        hasTransition = true;
                        transitionTarget[key] = state[key];
                    }
                    else {
                        this[key] = state[key];
                    }
                }
                else if (needsRestoreToNormal) {
                    if (normalState[key] != null) {
                        if (propNeedsTransition) {
                            hasTransition = true;
                            transitionTarget[key] = normalState[key];
                        }
                        else {
                            this[key] = normalState[key];
                        }
                    }
                }
            }
            if (!transition) {
                for (var i = 0; i < this.animators.length; i++) {
                    var animator = this.animators[i];
                    var targetName = animator.targetName;
                    if (!animator.getLoop()) {
                        animator.__changeFinalValue(targetName
                            ? (state || normalState)[targetName]
                            : (state || normalState));
                    }
                }
            }
            if (hasTransition) {
                this._transitionState(stateName, transitionTarget, animationCfg);
            }
        };
        Element.prototype._attachComponent = function (componentEl) {
            if (componentEl.__zr && !componentEl.__hostTarget) {
                if ("development" !== 'production') {
                    throw new Error('Text element has been added to zrender.');
                }
                return;
            }
            if (componentEl === this) {
                if ("development" !== 'production') {
                    throw new Error('Recursive component attachment.');
                }
                return;
            }
            var zr = this.__zr;
            if (zr) {
                componentEl.addSelfToZr(zr);
            }
            componentEl.__zr = zr;
            componentEl.__hostTarget = this;
        };
        Element.prototype._detachComponent = function (componentEl) {
            if (componentEl.__zr) {
                componentEl.removeSelfFromZr(componentEl.__zr);
            }
            componentEl.__zr = null;
            componentEl.__hostTarget = null;
        };
        Element.prototype.getClipPath = function () {
            return this._clipPath;
        };
        Element.prototype.setClipPath = function (clipPath) {
            if (this._clipPath && this._clipPath !== clipPath) {
                this.removeClipPath();
            }
            this._attachComponent(clipPath);
            this._clipPath = clipPath;
            this.markRedraw();
        };
        Element.prototype.removeClipPath = function () {
            var clipPath = this._clipPath;
            if (clipPath) {
                this._detachComponent(clipPath);
                this._clipPath = null;
                this.markRedraw();
            }
        };
        Element.prototype.getTextContent = function () {
            return this._textContent;
        };
        Element.prototype.setTextContent = function (textEl) {
            var previousTextContent = this._textContent;
            if (previousTextContent === textEl) {
                return;
            }
            if (previousTextContent && previousTextContent !== textEl) {
                this.removeTextContent();
            }
            if ("development" !== 'production') {
                if (textEl.__zr && !textEl.__hostTarget) {
                    throw new Error('Text element has been added to zrender.');
                }
            }
            textEl.innerTransformable = new Transformable();
            this._attachComponent(textEl);
            this._textContent = textEl;
            this.markRedraw();
        };
        Element.prototype.setTextConfig = function (cfg) {
            if (!this.textConfig) {
                this.textConfig = {};
            }
            extend(this.textConfig, cfg);
            this.markRedraw();
        };
        Element.prototype.removeTextConfig = function () {
            this.textConfig = null;
            this.markRedraw();
        };
        Element.prototype.removeTextContent = function () {
            var textEl = this._textContent;
            if (textEl) {
                textEl.innerTransformable = null;
                this._detachComponent(textEl);
                this._textContent = null;
                this._innerTextDefaultStyle = null;
                this.markRedraw();
            }
        };
        Element.prototype.getTextGuideLine = function () {
            return this._textGuide;
        };
        Element.prototype.setTextGuideLine = function (guideLine) {
            if (this._textGuide && this._textGuide !== guideLine) {
                this.removeTextGuideLine();
            }
            this._attachComponent(guideLine);
            this._textGuide = guideLine;
            this.markRedraw();
        };
        Element.prototype.removeTextGuideLine = function () {
            var textGuide = this._textGuide;
            if (textGuide) {
                this._detachComponent(textGuide);
                this._textGuide = null;
                this.markRedraw();
            }
        };
        Element.prototype.markRedraw = function () {
            this.__dirty |= REDRAW_BIT;
            var zr = this.__zr;
            if (zr) {
                if (this.__inHover) {
                    zr.refreshHover();
                }
                else {
                    zr.refresh();
                }
            }
            if (this.__hostTarget) {
                this.__hostTarget.markRedraw();
            }
        };
        Element.prototype.dirty = function () {
            this.markRedraw();
        };
        Element.prototype._toggleHoverLayerFlag = function (inHover) {
            this.__inHover = inHover;
            var textContent = this._textContent;
            var textGuide = this._textGuide;
            if (textContent) {
                textContent.__inHover = inHover;
            }
            if (textGuide) {
                textGuide.__inHover = inHover;
            }
        };
        Element.prototype.addSelfToZr = function (zr) {
            if (this.__zr === zr) {
                return;
            }
            this.__zr = zr;
            var animators = this.animators;
            if (animators) {
                for (var i = 0; i < animators.length; i++) {
                    zr.animation.addAnimator(animators[i]);
                }
            }
            if (this._clipPath) {
                this._clipPath.addSelfToZr(zr);
            }
            if (this._textContent) {
                this._textContent.addSelfToZr(zr);
            }
            if (this._textGuide) {
                this._textGuide.addSelfToZr(zr);
            }
        };
        Element.prototype.removeSelfFromZr = function (zr) {
            if (!this.__zr) {
                return;
            }
            this.__zr = null;
            var animators = this.animators;
            if (animators) {
                for (var i = 0; i < animators.length; i++) {
                    zr.animation.removeAnimator(animators[i]);
                }
            }
            if (this._clipPath) {
                this._clipPath.removeSelfFromZr(zr);
            }
            if (this._textContent) {
                this._textContent.removeSelfFromZr(zr);
            }
            if (this._textGuide) {
                this._textGuide.removeSelfFromZr(zr);
            }
        };
        Element.prototype.animate = function (key, loop, allowDiscreteAnimation) {
            var target = key ? this[key] : this;
            if ("development" !== 'production') {
                if (!target) {
                    logError('Property "'
                        + key
                        + '" is not existed in element '
                        + this.id);
                    return;
                }
            }
            var animator = new Animator(target, loop, allowDiscreteAnimation);
            key && (animator.targetName = key);
            this.addAnimator(animator, key);
            return animator;
        };
        Element.prototype.addAnimator = function (animator, key) {
            var zr = this.__zr;
            var el = this;
            animator.during(function () {
                el.updateDuringAnimation(key);
            }).done(function () {
                var animators = el.animators;
                var idx = indexOf(animators, animator);
                if (idx >= 0) {
                    animators.splice(idx, 1);
                }
            });
            this.animators.push(animator);
            if (zr) {
                zr.animation.addAnimator(animator);
            }
            zr && zr.wakeUp();
        };
        Element.prototype.updateDuringAnimation = function (key) {
            this.markRedraw();
        };
        Element.prototype.stopAnimation = function (scope, forwardToLast) {
            var animators = this.animators;
            var len = animators.length;
            var leftAnimators = [];
            for (var i = 0; i < len; i++) {
                var animator = animators[i];
                if (!scope || scope === animator.scope) {
                    animator.stop(forwardToLast);
                }
                else {
                    leftAnimators.push(animator);
                }
            }
            this.animators = leftAnimators;
            return this;
        };
        Element.prototype.animateTo = function (target, cfg, animationProps) {
            animateTo(this, target, cfg, animationProps);
        };
        Element.prototype.animateFrom = function (target, cfg, animationProps) {
            animateTo(this, target, cfg, animationProps, true);
        };
        Element.prototype._transitionState = function (stateName, target, cfg, animationProps) {
            var animators = animateTo(this, target, cfg, animationProps);
            for (var i = 0; i < animators.length; i++) {
                animators[i].__fromStateTransition = stateName;
            }
        };
        Element.prototype.getBoundingRect = function () {
            return null;
        };
        Element.prototype.getPaintRect = function () {
            return null;
        };
        Element.initDefaultProps = (function () {
            var elProto = Element.prototype;
            elProto.type = 'element';
            elProto.name = '';
            elProto.ignore =
                elProto.silent =
                    elProto.isGroup =
                        elProto.draggable =
                            elProto.dragging =
                                elProto.ignoreClip =
                                    elProto.__inHover = false;
            elProto.__dirty = REDRAW_BIT;
            var logs = {};
            function logDeprecatedError(key, xKey, yKey) {
                if (!logs[key + xKey + yKey]) {
                    console.warn("DEPRECATED: '" + key + "' has been deprecated. use '" + xKey + "', '" + yKey + "' instead");
                    logs[key + xKey + yKey] = true;
                }
            }
            function createLegacyProperty(key, privateKey, xKey, yKey) {
                Object.defineProperty(elProto, key, {
                    get: function () {
                        if ("development" !== 'production') {
                            logDeprecatedError(key, xKey, yKey);
                        }
                        if (!this[privateKey]) {
                            var pos = this[privateKey] = [];
                            enhanceArray(this, pos);
                        }
                        return this[privateKey];
                    },
                    set: function (pos) {
                        if ("development" !== 'production') {
                            logDeprecatedError(key, xKey, yKey);
                        }
                        this[xKey] = pos[0];
                        this[yKey] = pos[1];
                        this[privateKey] = pos;
                        enhanceArray(this, pos);
                    }
                });
                function enhanceArray(self, pos) {
                    Object.defineProperty(pos, 0, {
                        get: function () {
                            return self[xKey];
                        },
                        set: function (val) {
                            self[xKey] = val;
                        }
                    });
                    Object.defineProperty(pos, 1, {
                        get: function () {
                            return self[yKey];
                        },
                        set: function (val) {
                            self[yKey] = val;
                        }
                    });
                }
            }
            if (Object.defineProperty) {
                createLegacyProperty('position', '_legacyPos', 'x', 'y');
                createLegacyProperty('scale', '_legacyScale', 'scaleX', 'scaleY');
                createLegacyProperty('origin', '_legacyOrigin', 'originX', 'originY');
            }
        })();
        return Element;
    }());
    mixin(Element, Eventful);
    mixin(Element, Transformable);
    function animateTo(animatable, target, cfg, animationProps, reverse) {
        cfg = cfg || {};
        var animators = [];
        animateToShallow(animatable, '', animatable, target, cfg, animationProps, animators, reverse);
        var finishCount = animators.length;
        var doneHappened = false;
        var cfgDone = cfg.done;
        var cfgAborted = cfg.aborted;
        var doneCb = function () {
            doneHappened = true;
            finishCount--;
            if (finishCount <= 0) {
                doneHappened
                    ? (cfgDone && cfgDone())
                    : (cfgAborted && cfgAborted());
            }
        };
        var abortedCb = function () {
            finishCount--;
            if (finishCount <= 0) {
                doneHappened
                    ? (cfgDone && cfgDone())
                    : (cfgAborted && cfgAborted());
            }
        };
        if (!finishCount) {
            cfgDone && cfgDone();
        }
        if (animators.length > 0 && cfg.during) {
            animators[0].during(function (target, percent) {
                cfg.during(percent);
            });
        }
        for (var i = 0; i < animators.length; i++) {
            var animator = animators[i];
            if (doneCb) {
                animator.done(doneCb);
            }
            if (abortedCb) {
                animator.aborted(abortedCb);
            }
            if (cfg.force) {
                animator.duration(cfg.duration);
            }
            animator.start(cfg.easing);
        }
        return animators;
    }
    function copyArrShallow(source, target, len) {
        for (var i = 0; i < len; i++) {
            source[i] = target[i];
        }
    }
    function is2DArray(value) {
        return isArrayLike(value[0]);
    }
    function copyValue(target, source, key) {
        if (isArrayLike(source[key])) {
            if (!isArrayLike(target[key])) {
                target[key] = [];
            }
            if (isTypedArray(source[key])) {
                var len = source[key].length;
                if (target[key].length !== len) {
                    target[key] = new (source[key].constructor)(len);
                    copyArrShallow(target[key], source[key], len);
                }
            }
            else {
                var sourceArr = source[key];
                var targetArr = target[key];
                var len0 = sourceArr.length;
                if (is2DArray(sourceArr)) {
                    var len1 = sourceArr[0].length;
                    for (var i = 0; i < len0; i++) {
                        if (!targetArr[i]) {
                            targetArr[i] = Array.prototype.slice.call(sourceArr[i]);
                        }
                        else {
                            copyArrShallow(targetArr[i], sourceArr[i], len1);
                        }
                    }
                }
                else {
                    copyArrShallow(targetArr, sourceArr, len0);
                }
                targetArr.length = sourceArr.length;
            }
        }
        else {
            target[key] = source[key];
        }
    }
    function isValueSame(val1, val2) {
        return val1 === val2
            || isArrayLike(val1) && isArrayLike(val2) && is1DArraySame(val1, val2);
    }
    function is1DArraySame(arr0, arr1) {
        var len = arr0.length;
        if (len !== arr1.length) {
            return false;
        }
        for (var i = 0; i < len; i++) {
            if (arr0[i] !== arr1[i]) {
                return false;
            }
        }
        return true;
    }
    function animateToShallow(animatable, topKey, animateObj, target, cfg, animationProps, animators, reverse) {
        var targetKeys = keys(target);
        var duration = cfg.duration;
        var delay = cfg.delay;
        var additive = cfg.additive;
        var setToFinal = cfg.setToFinal;
        var animateAll = !isObject(animationProps);
        var existsAnimators = animatable.animators;
        var animationKeys = [];
        for (var k = 0; k < targetKeys.length; k++) {
            var innerKey = targetKeys[k];
            var targetVal = target[innerKey];
            if (targetVal != null && animateObj[innerKey] != null
                && (animateAll || animationProps[innerKey])) {
                if (isObject(targetVal)
                    && !isArrayLike(targetVal)
                    && !isGradientObject(targetVal)) {
                    if (topKey) {
                        if (!reverse) {
                            animateObj[innerKey] = targetVal;
                            animatable.updateDuringAnimation(topKey);
                        }
                        continue;
                    }
                    animateToShallow(animatable, innerKey, animateObj[innerKey], targetVal, cfg, animationProps && animationProps[innerKey], animators, reverse);
                }
                else {
                    animationKeys.push(innerKey);
                }
            }
            else if (!reverse) {
                animateObj[innerKey] = targetVal;
                animatable.updateDuringAnimation(topKey);
                animationKeys.push(innerKey);
            }
        }
        var keyLen = animationKeys.length;
        if (!additive && keyLen) {
            for (var i = 0; i < existsAnimators.length; i++) {
                var animator = existsAnimators[i];
                if (animator.targetName === topKey) {
                    var allAborted = animator.stopTracks(animationKeys);
                    if (allAborted) {
                        var idx = indexOf(existsAnimators, animator);
                        existsAnimators.splice(idx, 1);
                    }
                }
            }
        }
        if (!cfg.force) {
            animationKeys = filter(animationKeys, function (key) { return !isValueSame(target[key], animateObj[key]); });
            keyLen = animationKeys.length;
        }
        if (keyLen > 0
            || (cfg.force && !animators.length)) {
            var revertedSource = void 0;
            var reversedTarget = void 0;
            var sourceClone = void 0;
            if (reverse) {
                reversedTarget = {};
                if (setToFinal) {
                    revertedSource = {};
                }
                for (var i = 0; i < keyLen; i++) {
                    var innerKey = animationKeys[i];
                    reversedTarget[innerKey] = animateObj[innerKey];
                    if (setToFinal) {
                        revertedSource[innerKey] = target[innerKey];
                    }
                    else {
                        animateObj[innerKey] = target[innerKey];
                    }
                }
            }
            else if (setToFinal) {
                sourceClone = {};
                for (var i = 0; i < keyLen; i++) {
                    var innerKey = animationKeys[i];
                    sourceClone[innerKey] = cloneValue(animateObj[innerKey]);
                    copyValue(animateObj, target, innerKey);
                }
            }
            var animator = new Animator(animateObj, false, false, additive ? filter(existsAnimators, function (animator) { return animator.targetName === topKey; }) : null);
            animator.targetName = topKey;
            if (cfg.scope) {
                animator.scope = cfg.scope;
            }
            if (setToFinal && revertedSource) {
                animator.whenWithKeys(0, revertedSource, animationKeys);
            }
            if (sourceClone) {
                animator.whenWithKeys(0, sourceClone, animationKeys);
            }
            animator.whenWithKeys(duration == null ? 500 : duration, reverse ? reversedTarget : target, animationKeys).delay(delay || 0);
            animatable.addAnimator(animator, topKey);
            animators.push(animator);
        }
    }

    var Group = (function (_super) {
        __extends(Group, _super);
        function Group(opts) {
            var _this = _super.call(this) || this;
            _this.isGroup = true;
            _this._children = [];
            _this.attr(opts);
            return _this;
        }
        Group.prototype.childrenRef = function () {
            return this._children;
        };
        Group.prototype.children = function () {
            return this._children.slice();
        };
        Group.prototype.childAt = function (idx) {
            return this._children[idx];
        };
        Group.prototype.childOfName = function (name) {
            var children = this._children;
            for (var i = 0; i < children.length; i++) {
                if (children[i].name === name) {
                    return children[i];
                }
            }
        };
        Group.prototype.childCount = function () {
            return this._children.length;
        };
        Group.prototype.add = function (child) {
            if (child) {
                if (child !== this && child.parent !== this) {
                    this._children.push(child);
                    this._doAdd(child);
                }
                if ("development" !== 'production') {
                    if (child.__hostTarget) {
                        throw 'This elemenet has been used as an attachment';
                    }
                }
            }
            return this;
        };
        Group.prototype.addBefore = function (child, nextSibling) {
            if (child && child !== this && child.parent !== this
                && nextSibling && nextSibling.parent === this) {
                var children = this._children;
                var idx = children.indexOf(nextSibling);
                if (idx >= 0) {
                    children.splice(idx, 0, child);
                    this._doAdd(child);
                }
            }
            return this;
        };
        Group.prototype.replace = function (oldChild, newChild) {
            var idx = indexOf(this._children, oldChild);
            if (idx >= 0) {
                this.replaceAt(newChild, idx);
            }
            return this;
        };
        Group.prototype.replaceAt = function (child, index) {
            var children = this._children;
            var old = children[index];
            if (child && child !== this && child.parent !== this && child !== old) {
                children[index] = child;
                old.parent = null;
                var zr = this.__zr;
                if (zr) {
                    old.removeSelfFromZr(zr);
                }
                this._doAdd(child);
            }
            return this;
        };
        Group.prototype._doAdd = function (child) {
            if (child.parent) {
                child.parent.remove(child);
            }
            child.parent = this;
            var zr = this.__zr;
            if (zr && zr !== child.__zr) {
                child.addSelfToZr(zr);
            }
            zr && zr.refresh();
        };
        Group.prototype.remove = function (child) {
            var zr = this.__zr;
            var children = this._children;
            var idx = indexOf(children, child);
            if (idx < 0) {
                return this;
            }
            children.splice(idx, 1);
            child.parent = null;
            if (zr) {
                child.removeSelfFromZr(zr);
            }
            zr && zr.refresh();
            return this;
        };
        Group.prototype.removeAll = function () {
            var children = this._children;
            var zr = this.__zr;
            for (var i = 0; i < children.length; i++) {
                var child = children[i];
                if (zr) {
                    child.removeSelfFromZr(zr);
                }
                child.parent = null;
            }
            children.length = 0;
            return this;
        };
        Group.prototype.eachChild = function (cb, context) {
            var children = this._children;
            for (var i = 0; i < children.length; i++) {
                var child = children[i];
                cb.call(context, child, i);
            }
            return this;
        };
        Group.prototype.traverse = function (cb, context) {
            for (var i = 0; i < this._children.length; i++) {
                var child = this._children[i];
                var stopped = cb.call(context, child);
                if (child.isGroup && !stopped) {
                    child.traverse(cb, context);
                }
            }
            return this;
        };
        Group.prototype.addSelfToZr = function (zr) {
            _super.prototype.addSelfToZr.call(this, zr);
            for (var i = 0; i < this._children.length; i++) {
                var child = this._children[i];
                child.addSelfToZr(zr);
            }
        };
        Group.prototype.removeSelfFromZr = function (zr) {
            _super.prototype.removeSelfFromZr.call(this, zr);
            for (var i = 0; i < this._children.length; i++) {
                var child = this._children[i];
                child.removeSelfFromZr(zr);
            }
        };
        Group.prototype.getBoundingRect = function (includeChildren) {
            var tmpRect = new BoundingRect(0, 0, 0, 0);
            var children = includeChildren || this._children;
            var tmpMat = [];
            var rect = null;
            for (var i = 0; i < children.length; i++) {
                var child = children[i];
                if (child.ignore || child.invisible) {
                    continue;
                }
                var childRect = child.getBoundingRect();
                var transform = child.getLocalTransform(tmpMat);
                if (transform) {
                    BoundingRect.applyTransform(tmpRect, childRect, transform);
                    rect = rect || tmpRect.clone();
                    rect.union(tmpRect);
                }
                else {
                    rect = rect || childRect.clone();
                    rect.union(childRect);
                }
            }
            return rect || tmpRect;
        };
        return Group;
    }(Element));
    Group.prototype.type = 'group';

    /*!
    * ZRender, a high performance 2d drawing library.
    *
    * Copyright (c) 2013, Baidu Inc.
    * All rights reserved.
    *
    * LICENSE
    * https://github.com/ecomfe/zrender/blob/master/LICENSE.txt
    */
    var painterCtors = {};
    var instances = {};
    function delInstance(id) {
        delete instances[id];
    }
    function isDarkMode(backgroundColor) {
        if (!backgroundColor) {
            return false;
        }
        if (typeof backgroundColor === 'string') {
            return lum(backgroundColor, 1) < DARK_MODE_THRESHOLD;
        }
        else if (backgroundColor.colorStops) {
            var colorStops = backgroundColor.colorStops;
            var totalLum = 0;
            var len = colorStops.length;
            for (var i = 0; i < len; i++) {
                totalLum += lum(colorStops[i].color, 1);
            }
            totalLum /= len;
            return totalLum < DARK_MODE_THRESHOLD;
        }
        return false;
    }
    var ZRender = (function () {
        function ZRender(id, dom, opts) {
            var _this = this;
            this._sleepAfterStill = 10;
            this._stillFrameAccum = 0;
            this._needsRefresh = true;
            this._needsRefreshHover = true;
            this._darkMode = false;
            opts = opts || {};
            this.dom = dom;
            this.id = id;
            var storage = new Storage();
            var rendererType = opts.renderer || 'canvas';
            if (!painterCtors[rendererType]) {
                rendererType = keys(painterCtors)[0];
            }
            if ("development" !== 'production') {
                if (!painterCtors[rendererType]) {
                    throw new Error("Renderer '" + rendererType + "' is not imported. Please import it first.");
                }
            }
            opts.useDirtyRect = opts.useDirtyRect == null
                ? false
                : opts.useDirtyRect;
            var painter = new painterCtors[rendererType](dom, storage, opts, id);
            var ssrMode = opts.ssr || painter.ssrOnly;
            this.storage = storage;
            this.painter = painter;
            var handerProxy = (!env.node && !env.worker && !ssrMode)
                ? new HandlerDomProxy(painter.getViewportRoot(), painter.root)
                : null;
            var useCoarsePointer = opts.useCoarsePointer;
            var usePointerSize = (useCoarsePointer == null || useCoarsePointer === 'auto')
                ? env.touchEventsSupported
                : !!useCoarsePointer;
            var defaultPointerSize = 44;
            var pointerSize;
            if (usePointerSize) {
                pointerSize = retrieve2(opts.pointerSize, defaultPointerSize);
            }
            this.handler = new Handler(storage, painter, handerProxy, painter.root, pointerSize);
            this.animation = new Animation({
                stage: {
                    update: ssrMode ? null : function () { return _this._flush(true); }
                }
            });
            if (!ssrMode) {
                this.animation.start();
            }
        }
        ZRender.prototype.add = function (el) {
            if (!el) {
                return;
            }
            this.storage.addRoot(el);
            el.addSelfToZr(this);
            this.refresh();
        };
        ZRender.prototype.remove = function (el) {
            if (!el) {
                return;
            }
            this.storage.delRoot(el);
            el.removeSelfFromZr(this);
            this.refresh();
        };
        ZRender.prototype.configLayer = function (zLevel, config) {
            if (this.painter.configLayer) {
                this.painter.configLayer(zLevel, config);
            }
            this.refresh();
        };
        ZRender.prototype.setBackgroundColor = function (backgroundColor) {
            if (this.painter.setBackgroundColor) {
                this.painter.setBackgroundColor(backgroundColor);
            }
            this.refresh();
            this._backgroundColor = backgroundColor;
            this._darkMode = isDarkMode(backgroundColor);
        };
        ZRender.prototype.getBackgroundColor = function () {
            return this._backgroundColor;
        };
        ZRender.prototype.setDarkMode = function (darkMode) {
            this._darkMode = darkMode;
        };
        ZRender.prototype.isDarkMode = function () {
            return this._darkMode;
        };
        ZRender.prototype.refreshImmediately = function (fromInside) {
            if (!fromInside) {
                this.animation.update(true);
            }
            this._needsRefresh = false;
            this.painter.refresh();
            this._needsRefresh = false;
        };
        ZRender.prototype.refresh = function () {
            this._needsRefresh = true;
            this.animation.start();
        };
        ZRender.prototype.flush = function () {
            this._flush(false);
        };
        ZRender.prototype._flush = function (fromInside) {
            var triggerRendered;
            var start = getTime();
            if (this._needsRefresh) {
                triggerRendered = true;
                this.refreshImmediately(fromInside);
            }
            if (this._needsRefreshHover) {
                triggerRendered = true;
                this.refreshHoverImmediately();
            }
            var end = getTime();
            if (triggerRendered) {
                this._stillFrameAccum = 0;
                this.trigger('rendered', {
                    elapsedTime: end - start
                });
            }
            else if (this._sleepAfterStill > 0) {
                this._stillFrameAccum++;
                if (this._stillFrameAccum > this._sleepAfterStill) {
                    this.animation.stop();
                }
            }
        };
        ZRender.prototype.setSleepAfterStill = function (stillFramesCount) {
            this._sleepAfterStill = stillFramesCount;
        };
        ZRender.prototype.wakeUp = function () {
            this.animation.start();
            this._stillFrameAccum = 0;
        };
        ZRender.prototype.refreshHover = function () {
            this._needsRefreshHover = true;
        };
        ZRender.prototype.refreshHoverImmediately = function () {
            this._needsRefreshHover = false;
            if (this.painter.refreshHover && this.painter.getType() === 'canvas') {
                this.painter.refreshHover();
            }
        };
        ZRender.prototype.resize = function (opts) {
            opts = opts || {};
            this.painter.resize(opts.width, opts.height);
            this.handler.resize();
        };
        ZRender.prototype.clearAnimation = function () {
            this.animation.clear();
        };
        ZRender.prototype.getWidth = function () {
            return this.painter.getWidth();
        };
        ZRender.prototype.getHeight = function () {
            return this.painter.getHeight();
        };
        ZRender.prototype.setCursorStyle = function (cursorStyle) {
            this.handler.setCursorStyle(cursorStyle);
        };
        ZRender.prototype.findHover = function (x, y) {
            return this.handler.findHover(x, y);
        };
        ZRender.prototype.on = function (eventName, eventHandler, context) {
            this.handler.on(eventName, eventHandler, context);
            return this;
        };
        ZRender.prototype.off = function (eventName, eventHandler) {
            this.handler.off(eventName, eventHandler);
        };
        ZRender.prototype.trigger = function (eventName, event) {
            this.handler.trigger(eventName, event);
        };
        ZRender.prototype.clear = function () {
            var roots = this.storage.getRoots();
            for (var i = 0; i < roots.length; i++) {
                if (roots[i] instanceof Group) {
                    roots[i].removeSelfFromZr(this);
                }
            }
            this.storage.delAllRoots();
            this.painter.clear();
        };
        ZRender.prototype.dispose = function () {
            this.animation.stop();
            this.clear();
            this.storage.dispose();
            this.painter.dispose();
            this.handler.dispose();
            this.animation =
                this.storage =
                    this.painter =
                        this.handler = null;
            delInstance(this.id);
        };
        return ZRender;
    }());
    function init(dom, opts) {
        var zr = new ZRender(guid(), dom, opts);
        instances[zr.id] = zr;
        return zr;
    }
    function dispose(zr) {
        zr.dispose();
    }
    function disposeAll() {
        for (var key in instances) {
            if (instances.hasOwnProperty(key)) {
                instances[key].dispose();
            }
        }
        instances = {};
    }
    function getInstance(id) {
        return instances[id];
    }
    function registerPainter(name, Ctor) {
        painterCtors[name] = Ctor;
    }
    var version = '5.4.1-dev.20221104';

    var zrender = /*#__PURE__*/Object.freeze({
        __proto__: null,
        init: init,
        dispose: dispose,
        disposeAll: disposeAll,
        getInstance: getInstance,
        registerPainter: registerPainter,
        version: version
    });

    var RADIAN_EPSILON = 1e-4; // Although chrome already enlarge this number to 100 for `toFixed`, but
    // we sill follow the spec for compatibility.

    var ROUND_SUPPORTED_PRECISION_MAX = 20;

    function _trim(str) {
      return str.replace(/^\s+|\s+$/g, '');
    }
    /**
     * Linear mapping a value from domain to range
     * @param  val
     * @param  domain Domain extent domain[0] can be bigger than domain[1]
     * @param  range  Range extent range[0] can be bigger than range[1]
     * @param  clamp Default to be false
     */


    function linearMap(val, domain, range, clamp) {
      var d0 = domain[0];
      var d1 = domain[1];
      var r0 = range[0];
      var r1 = range[1];
      var subDomain = d1 - d0;
      var subRange = r1 - r0;

      if (subDomain === 0) {
        return subRange === 0 ? r0 : (r0 + r1) / 2;
      } // Avoid accuracy problem in edge, such as
      // 146.39 - 62.83 === 83.55999999999999.
      // See echarts/test/ut/spec/util/number.js#linearMap#accuracyError
      // It is a little verbose for efficiency considering this method
      // is a hotspot.


      if (clamp) {
        if (subDomain > 0) {
          if (val <= d0) {
            return r0;
          } else if (val >= d1) {
            return r1;
          }
        } else {
          if (val >= d0) {
            return r0;
          } else if (val <= d1) {
            return r1;
          }
        }
      } else {
        if (val === d0) {
          return r0;
        }

        if (val === d1) {
          return r1;
        }
      }

      return (val - d0) / subDomain * subRange + r0;
    }
    /**
     * Convert a percent string to absolute number.
     * Returns NaN if percent is not a valid string or number
     */

    function parsePercent$1(percent, all) {
      switch (percent) {
        case 'center':
        case 'middle':
          percent = '50%';
          break;

        case 'left':
        case 'top':
          percent = '0%';
          break;

        case 'right':
        case 'bottom':
          percent = '100%';
          break;
      }

      if (isString(percent)) {
        if (_trim(percent).match(/%$/)) {
          return parseFloat(percent) / 100 * all;
        }

        return parseFloat(percent);
      }

      return percent == null ? NaN : +percent;
    }
    function round(x, precision, returnStr) {
      if (precision == null) {
        precision = 10;
      } // Avoid range error


      precision = Math.min(Math.max(0, precision), ROUND_SUPPORTED_PRECISION_MAX); // PENDING: 1.005.toFixed(2) is '1.00' rather than '1.01'

      x = (+x).toFixed(precision);
      return returnStr ? x : +x;
    }
    /**
     * Inplacd asc sort arr.
     * The input arr will be modified.
     */

    function asc(arr) {
      arr.sort(function (a, b) {
        return a - b;
      });
      return arr;
    }
    /**
     * Get precision.
     */

    function getPrecision(val) {
      val = +val;

      if (isNaN(val)) {
        return 0;
      } // It is much faster than methods converting number to string as follows
      //      let tmp = val.toString();
      //      return tmp.length - 1 - tmp.indexOf('.');
      // especially when precision is low
      // Notice:
      // (1) If the loop count is over about 20, it is slower than `getPrecisionSafe`.
      //     (see https://jsbench.me/2vkpcekkvw/1)
      // (2) If the val is less than for example 1e-15, the result may be incorrect.
      //     (see test/ut/spec/util/number.test.ts `getPrecision_equal_random`)


      if (val > 1e-14) {
        var e = 1;

        for (var i = 0; i < 15; i++, e *= 10) {
          if (Math.round(val * e) / e === val) {
            return i;
          }
        }
      }

      return getPrecisionSafe(val);
    }
    /**
     * Get precision with slow but safe method
     */

    function getPrecisionSafe(val) {
      // toLowerCase for: '3.4E-12'
      var str = val.toString().toLowerCase(); // Consider scientific notation: '3.4e-12' '3.4e+12'

      var eIndex = str.indexOf('e');
      var exp = eIndex > 0 ? +str.slice(eIndex + 1) : 0;
      var significandPartLen = eIndex > 0 ? eIndex : str.length;
      var dotIndex = str.indexOf('.');
      var decimalPartLen = dotIndex < 0 ? 0 : significandPartLen - 1 - dotIndex;
      return Math.max(0, decimalPartLen - exp);
    }
    /**
     * Minimal dicernible data precisioin according to a single pixel.
     */

    function getPixelPrecision(dataExtent, pixelExtent) {
      var log = Math.log;
      var LN10 = Math.LN10;
      var dataQuantity = Math.floor(log(dataExtent[1] - dataExtent[0]) / LN10);
      var sizeQuantity = Math.round(log(Math.abs(pixelExtent[1] - pixelExtent[0])) / LN10); // toFixed() digits argument must be between 0 and 20.

      var precision = Math.min(Math.max(-dataQuantity + sizeQuantity, 0), 20);
      return !isFinite(precision) ? 20 : precision;
    }
    /**
     * Get a data of given precision, assuring the sum of percentages
     * in valueList is 1.
     * The largest remainder method is used.
     * https://en.wikipedia.org/wiki/Largest_remainder_method
     *
     * @param valueList a list of all data
     * @param idx index of the data to be processed in valueList
     * @param precision integer number showing digits of precision
     * @return percent ranging from 0 to 100
     */

    function getPercentWithPrecision(valueList, idx, precision) {
      if (!valueList[idx]) {
        return 0;
      }

      var seats = getPercentSeats(valueList, precision);
      return seats[idx] || 0;
    }
    /**
     * Get a data of given precision, assuring the sum of percentages
     * in valueList is 1.
     * The largest remainder method is used.
     * https://en.wikipedia.org/wiki/Largest_remainder_method
     *
     * @param valueList a list of all data
     * @param precision integer number showing digits of precision
     * @return {Array<number>}
     */

    function getPercentSeats(valueList, precision) {
      var sum = reduce(valueList, function (acc, val) {
        return acc + (isNaN(val) ? 0 : val);
      }, 0);

      if (sum === 0) {
        return [];
      }

      var digits = Math.pow(10, precision);
      var votesPerQuota = map(valueList, function (val) {
        return (isNaN(val) ? 0 : val) / sum * digits * 100;
      });
      var targetSeats = digits * 100;
      var seats = map(votesPerQuota, function (votes) {
        // Assign automatic seats.
        return Math.floor(votes);
      });
      var currentSum = reduce(seats, function (acc, val) {
        return acc + val;
      }, 0);
      var remainder = map(votesPerQuota, function (votes, idx) {
        return votes - seats[idx];
      }); // Has remainding votes.

      while (currentSum < targetSeats) {
        // Find next largest remainder.
        var max = Number.NEGATIVE_INFINITY;
        var maxId = null;

        for (var i = 0, len = remainder.length; i < len; ++i) {
          if (remainder[i] > max) {
            max = remainder[i];
            maxId = i;
          }
        } // Add a vote to max remainder.


        ++seats[maxId];
        remainder[maxId] = 0;
        ++currentSum;
      }

      return map(seats, function (seat) {
        return seat / digits;
      });
    }
    /**
     * Solve the floating point adding problem like 0.1 + 0.2 === 0.30000000000000004
     * See <http://0.30000000000000004.com/>
     */

    function addSafe(val0, val1) {
      var maxPrecision = Math.max(getPrecision(val0), getPrecision(val1)); // const multiplier = Math.pow(10, maxPrecision);
      // return (Math.round(val0 * multiplier) + Math.round(val1 * multiplier)) / multiplier;

      var sum = val0 + val1; // // PENDING: support more?

      return maxPrecision > ROUND_SUPPORTED_PRECISION_MAX ? sum : round(sum, maxPrecision);
    } // Number.MAX_SAFE_INTEGER, ie do not support.

    var MAX_SAFE_INTEGER = 9007199254740991;
    /**
     * To 0 - 2 * PI, considering negative radian.
     */

    function remRadian(radian) {
      var pi2 = Math.PI * 2;
      return (radian % pi2 + pi2) % pi2;
    }
    /**
     * @param {type} radian
     * @return {boolean}
     */

    function isRadianAroundZero(val) {
      return val > -RADIAN_EPSILON && val < RADIAN_EPSILON;
    } // eslint-disable-next-line

    var TIME_REG = /^(?:(\d{4})(?:[-\/](\d{1,2})(?:[-\/](\d{1,2})(?:[T ](\d{1,2})(?::(\d{1,2})(?::(\d{1,2})(?:[.,](\d+))?)?)?(Z|[\+\-]\d\d:?\d\d)?)?)?)?)?$/; // jshint ignore:line

    /**
     * @param value valid type: number | string | Date, otherwise return `new Date(NaN)`
     *   These values can be accepted:
     *   + An instance of Date, represent a time in its own time zone.
     *   + Or string in a subset of ISO 8601, only including:
     *     + only year, month, date: '2012-03', '2012-03-01', '2012-03-01 05', '2012-03-01 05:06',
     *     + separated with T or space: '2012-03-01T12:22:33.123', '2012-03-01 12:22:33.123',
     *     + time zone: '2012-03-01T12:22:33Z', '2012-03-01T12:22:33+8000', '2012-03-01T12:22:33-05:00',
     *     all of which will be treated as local time if time zone is not specified
     *     (see <https://momentjs.com/>).
     *   + Or other string format, including (all of which will be treated as local time):
     *     '2012', '2012-3-1', '2012/3/1', '2012/03/01',
     *     '2009/6/12 2:00', '2009/6/12 2:05:08', '2009/6/12 2:05:08.123'
     *   + a timestamp, which represent a time in UTC.
     * @return date Never be null/undefined. If invalid, return `new Date(NaN)`.
     */

    function parseDate(value) {
      if (value instanceof Date) {
        return value;
      } else if (isString(value)) {
        // Different browsers parse date in different way, so we parse it manually.
        // Some other issues:
        // new Date('1970-01-01') is UTC,
        // new Date('1970/01/01') and new Date('1970-1-01') is local.
        // See issue #3623
        var match = TIME_REG.exec(value);

        if (!match) {
          // return Invalid Date.
          return new Date(NaN);
        } // Use local time when no timezone offset is specified.


        if (!match[8]) {
          // match[n] can only be string or undefined.
          // But take care of '12' + 1 => '121'.
          return new Date(+match[1], +(match[2] || 1) - 1, +match[3] || 1, +match[4] || 0, +(match[5] || 0), +match[6] || 0, match[7] ? +match[7].substring(0, 3) : 0);
        } // Timezoneoffset of Javascript Date has considered DST (Daylight Saving Time,
        // https://tc39.github.io/ecma262/#sec-daylight-saving-time-adjustment).
        // For example, system timezone is set as "Time Zone: America/Toronto",
        // then these code will get different result:
        // `new Date(1478411999999).getTimezoneOffset();  // get 240`
        // `new Date(1478412000000).getTimezoneOffset();  // get 300`
        // So we should not use `new Date`, but use `Date.UTC`.
        else {
            var hour = +match[4] || 0;

            if (match[8].toUpperCase() !== 'Z') {
              hour -= +match[8].slice(0, 3);
            }

            return new Date(Date.UTC(+match[1], +(match[2] || 1) - 1, +match[3] || 1, hour, +(match[5] || 0), +match[6] || 0, match[7] ? +match[7].substring(0, 3) : 0));
          }
      } else if (value == null) {
        return new Date(NaN);
      }

      return new Date(Math.round(value));
    }
    /**
     * Quantity of a number. e.g. 0.1, 1, 10, 100
     *
     * @param val
     * @return
     */

    function quantity(val) {
      return Math.pow(10, quantityExponent(val));
    }
    /**
     * Exponent of the quantity of a number
     * e.g., 1234 equals to 1.234*10^3, so quantityExponent(1234) is 3
     *
     * @param val non-negative value
     * @return
     */

    function quantityExponent(val) {
      if (val === 0) {
        return 0;
      }

      var exp = Math.floor(Math.log(val) / Math.LN10);
      /**
       * exp is expected to be the rounded-down result of the base-10 log of val.
       * But due to the precision loss with Math.log(val), we need to restore it
       * using 10^exp to make sure we can get val back from exp. #11249
       */

      if (val / Math.pow(10, exp) >= 10) {
        exp++;
      }

      return exp;
    }
    /**
     * find a “nice” number approximately equal to x. Round the number if round = true,
     * take ceiling if round = false. The primary observation is that the “nicest”
     * numbers in decimal are 1, 2, and 5, and all power-of-ten multiples of these numbers.
     *
     * See "Nice Numbers for Graph Labels" of Graphic Gems.
     *
     * @param  val Non-negative value.
     * @param  round
     * @return Niced number
     */

    function nice(val, round) {
      var exponent = quantityExponent(val);
      var exp10 = Math.pow(10, exponent);
      var f = val / exp10; // 1 <= f < 10

      var nf;

      if (round) {
        if (f < 1.5) {
          nf = 1;
        } else if (f < 2.5) {
          nf = 2;
        } else if (f < 4) {
          nf = 3;
        } else if (f < 7) {
          nf = 5;
        } else {
          nf = 10;
        }
      } else {
        if (f < 1) {
          nf = 1;
        } else if (f < 2) {
          nf = 2;
        } else if (f < 3) {
          nf = 3;
        } else if (f < 5) {
          nf = 5;
        } else {
          nf = 10;
        }
      }

      val = nf * exp10; // Fix 3 * 0.1 === 0.30000000000000004 issue (see IEEE 754).
      // 20 is the uppper bound of toFixed.

      return exponent >= -20 ? +val.toFixed(exponent < 0 ? -exponent : 0) : val;
    }
    /**
     * This code was copied from "d3.js"
     * <https://github.com/d3/d3/blob/9cc9a875e636a1dcf36cc1e07bdf77e1ad6e2c74/src/arrays/quantile.js>.
     * See the license statement at the head of this file.
     * @param ascArr
     */

    function quantile(ascArr, p) {
      var H = (ascArr.length - 1) * p + 1;
      var h = Math.floor(H);
      var v = +ascArr[h - 1];
      var e = H - h;
      return e ? v + e * (ascArr[h] - v) : v;
    }
    /**
     * Order intervals asc, and split them when overlap.
     * expect(numberUtil.reformIntervals([
     *     {interval: [18, 62], close: [1, 1]},
     *     {interval: [-Infinity, -70], close: [0, 0]},
     *     {interval: [-70, -26], close: [1, 1]},
     *     {interval: [-26, 18], close: [1, 1]},
     *     {interval: [62, 150], close: [1, 1]},
     *     {interval: [106, 150], close: [1, 1]},
     *     {interval: [150, Infinity], close: [0, 0]}
     * ])).toEqual([
     *     {interval: [-Infinity, -70], close: [0, 0]},
     *     {interval: [-70, -26], close: [1, 1]},
     *     {interval: [-26, 18], close: [0, 1]},
     *     {interval: [18, 62], close: [0, 1]},
     *     {interval: [62, 150], close: [0, 1]},
     *     {interval: [150, Infinity], close: [0, 0]}
     * ]);
     * @param list, where `close` mean open or close
     *        of the interval, and Infinity can be used.
     * @return The origin list, which has been reformed.
     */

    function reformIntervals(list) {
      list.sort(function (a, b) {
        return littleThan(a, b, 0) ? -1 : 1;
      });
      var curr = -Infinity;
      var currClose = 1;

      for (var i = 0; i < list.length;) {
        var interval = list[i].interval;
        var close_1 = list[i].close;

        for (var lg = 0; lg < 2; lg++) {
          if (interval[lg] <= curr) {
            interval[lg] = curr;
            close_1[lg] = !lg ? 1 - currClose : 1;
          }

          curr = interval[lg];
          currClose = close_1[lg];
        }

        if (interval[0] === interval[1] && close_1[0] * close_1[1] !== 1) {
          list.splice(i, 1);
        } else {
          i++;
        }
      }

      return list;

      function littleThan(a, b, lg) {
        return a.interval[lg] < b.interval[lg] || a.interval[lg] === b.interval[lg] && (a.close[lg] - b.close[lg] === (!lg ? 1 : -1) || !lg && littleThan(a, b, 1));
      }
    }
    /**
     * [Numeric is defined as]:
     *     `parseFloat(val) == val`
     * For example:
     * numeric:
     *     typeof number except NaN, '-123', '123', '2e3', '-2e3', '011', 'Infinity', Infinity,
     *     and they rounded by white-spaces or line-terminal like ' -123 \n ' (see es spec)
     * not-numeric:
     *     null, undefined, [], {}, true, false, 'NaN', NaN, '123ab',
     *     empty string, string with only white-spaces or line-terminal (see es spec),
     *     0x12, '0x12', '-0x12', 012, '012', '-012',
     *     non-string, ...
     *
     * @test See full test cases in `test/ut/spec/util/number.js`.
     * @return Must be a typeof number. If not numeric, return NaN.
     */

    function numericToNumber(val) {
      var valFloat = parseFloat(val);
      return valFloat == val // eslint-disable-line eqeqeq
      && (valFloat !== 0 || !isString(val) || val.indexOf('x') <= 0) // For case ' 0x0 '.
      ? valFloat : NaN;
    }
    /**
     * Definition of "numeric": see `numericToNumber`.
     */

    function isNumeric(val) {
      return !isNaN(numericToNumber(val));
    }
    /**
     * Use random base to prevent users hard code depending on
     * this auto generated marker id.
     * @return An positive integer.
     */

    function getRandomIdBase() {
      return Math.round(Math.random() * 9);
    }
    /**
     * Get the greatest common divisor.
     *
     * @param {number} a one number
     * @param {number} b the other number
     */

    function getGreatestCommonDividor(a, b) {
      if (b === 0) {
        return a;
      }

      return getGreatestCommonDividor(b, a % b);
    }
    /**
     * Get the least common multiple.
     *
     * @param {number} a one number
     * @param {number} b the other number
     */

    function getLeastCommonMultiple(a, b) {
      if (a == null) {
        return b;
      }

      if (b == null) {
        return a;
      }

      return a * b / getGreatestCommonDividor(a, b);
    }

    var ECHARTS_PREFIX = '[ECharts] ';
    var storedLogs = {};
    var hasConsole = typeof console !== 'undefined' // eslint-disable-next-line
    && console.warn && console.log;

    function outputLog(type, str, onlyOnce) {
      if (hasConsole) {
        if (onlyOnce) {
          if (storedLogs[str]) {
            return;
          }

          storedLogs[str] = true;
        } // eslint-disable-next-line


        console[type](ECHARTS_PREFIX + str);
      }
    }

    function log(str, onlyOnce) {
      outputLog('log', str, onlyOnce);
    }
    function warn(str, onlyOnce) {
      outputLog('warn', str, onlyOnce);
    }
    function error(str, onlyOnce) {
      outputLog('error', str, onlyOnce);
    }
    function deprecateLog(str) {
      if ("development" !== 'production') {
        // Not display duplicate message.
        outputLog('warn', 'DEPRECATED: ' + str, true);
      }
    }
    function deprecateReplaceLog(oldOpt, newOpt, scope) {
      if ("development" !== 'production') {
        deprecateLog((scope ? "[" + scope + "]" : '') + (oldOpt + " is deprecated, use " + newOpt + " instead."));
      }
    }
    /**
     * If in __DEV__ environment, get console printable message for users hint.
     * Parameters are separated by ' '.
     * @usage
     * makePrintable('This is an error on', someVar, someObj);
     *
     * @param hintInfo anything about the current execution context to hint users.
     * @throws Error
     */

    function makePrintable() {
      var hintInfo = [];

      for (var _i = 0; _i < arguments.length; _i++) {
        hintInfo[_i] = arguments[_i];
      }

      var msg = '';

      if ("development" !== 'production') {
        // Fuzzy stringify for print.
        // This code only exist in dev environment.
        var makePrintableStringIfPossible_1 = function (val) {
          return val === void 0 ? 'undefined' : val === Infinity ? 'Infinity' : val === -Infinity ? '-Infinity' : eqNaN(val) ? 'NaN' : val instanceof Date ? 'Date(' + val.toISOString() + ')' : isFunction(val) ? 'function () { ... }' : isRegExp(val) ? val + '' : null;
        };

        msg = map(hintInfo, function (arg) {
          if (isString(arg)) {
            // Print without quotation mark for some statement.
            return arg;
          } else {
            var printableStr = makePrintableStringIfPossible_1(arg);

            if (printableStr != null) {
              return printableStr;
            } else if (typeof JSON !== 'undefined' && JSON.stringify) {
              try {
                return JSON.stringify(arg, function (n, val) {
                  var printableStr = makePrintableStringIfPossible_1(val);
                  return printableStr == null ? val : printableStr;
                }); // In most cases the info object is small, so do not line break.
              } catch (err) {
                return '?';
              }
            } else {
              return '?';
            }
          }
        }).join(' ');
      }

      return msg;
    }
    /**
     * @throws Error
     */

    function throwError(msg) {
      throw new Error(msg);
    }

    function interpolateNumber$1(p0, p1, percent) {
      return (p1 - p0) * percent + p0;
    }
    /**
     * Make the name displayable. But we should
     * make sure it is not duplicated with user
     * specified name, so use '\0';
     */


    var DUMMY_COMPONENT_NAME_PREFIX = 'series\0';
    var INTERNAL_COMPONENT_ID_PREFIX = '\0_ec_\0';
    /**
     * If value is not array, then translate it to array.
     * @param  {*} value
     * @return {Array} [value] or value
     */

    function normalizeToArray(value) {
      return value instanceof Array ? value : value == null ? [] : [value];
    }
    /**
     * Sync default option between normal and emphasis like `position` and `show`
     * In case some one will write code like
     *     label: {
     *          show: false,
     *          position: 'outside',
     *          fontSize: 18
     *     },
     *     emphasis: {
     *          label: { show: true }
     *     }
     */

    function defaultEmphasis(opt, key, subOpts) {
      // Caution: performance sensitive.
      if (opt) {
        opt[key] = opt[key] || {};
        opt.emphasis = opt.emphasis || {};
        opt.emphasis[key] = opt.emphasis[key] || {}; // Default emphasis option from normal

        for (var i = 0, len = subOpts.length; i < len; i++) {
          var subOptName = subOpts[i];

          if (!opt.emphasis[key].hasOwnProperty(subOptName) && opt[key].hasOwnProperty(subOptName)) {
            opt.emphasis[key][subOptName] = opt[key][subOptName];
          }
        }
      }
    }
    var TEXT_STYLE_OPTIONS = ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily', 'rich', 'tag', 'color', 'textBorderColor', 'textBorderWidth', 'width', 'height', 'lineHeight', 'align', 'verticalAlign', 'baseline', 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY', 'textShadowColor', 'textShadowBlur', 'textShadowOffsetX', 'textShadowOffsetY', 'backgroundColor', 'borderColor', 'borderWidth', 'borderRadius', 'padding']; // modelUtil.LABEL_OPTIONS = modelUtil.TEXT_STYLE_OPTIONS.concat([
    //     'position', 'offset', 'rotate', 'origin', 'show', 'distance', 'formatter',
    //     'fontStyle', 'fontWeight', 'fontSize', 'fontFamily',
    //     // FIXME: deprecated, check and remove it.
    //     'textStyle'
    // ]);

    /**
     * The method does not ensure performance.
     * data could be [12, 2323, {value: 223}, [1221, 23], {value: [2, 23]}]
     * This helper method retrieves value from data.
     */

    function getDataItemValue(dataItem) {
      return isObject(dataItem) && !isArray(dataItem) && !(dataItem instanceof Date) ? dataItem.value : dataItem;
    }
    /**
     * data could be [12, 2323, {value: 223}, [1221, 23], {value: [2, 23]}]
     * This helper method determine if dataItem has extra option besides value
     */

    function isDataItemOption(dataItem) {
      return isObject(dataItem) && !(dataItem instanceof Array); // // markLine data can be array
      // && !(dataItem[0] && isObject(dataItem[0]) && !(dataItem[0] instanceof Array));
    }
    /**
     * Mapping to existings for merge.
     *
     * Mode "normalMege":
     *     The mapping result (merge result) will keep the order of the existing
     *     component, rather than the order of new option. Because we should ensure
     *     some specified index reference (like xAxisIndex) keep work.
     *     And in most cases, "merge option" is used to update partial option but not
     *     be expected to change the order.
     *
     * Mode "replaceMege":
     *     (1) Only the id mapped components will be merged.
     *     (2) Other existing components (except internal components) will be removed.
     *     (3) Other new options will be used to create new component.
     *     (4) The index of the existing components will not be modified.
     *     That means their might be "hole" after the removal.
     *     The new components are created first at those available index.
     *
     * Mode "replaceAll":
     *     This mode try to support that reproduce an echarts instance from another
     *     echarts instance (via `getOption`) in some simple cases.
     *     In this scenario, the `result` index are exactly the consistent with the `newCmptOptions`,
     *     which ensures the component index referring (like `xAxisIndex: ?`) corrent. That is,
     *     the "hole" in `newCmptOptions` will also be kept.
     *     On the contrary, other modes try best to eliminate holes.
     *     PENDING: This is an experimental mode yet.
     *
     * @return See the comment of <MappingResult>.
     */

    function mappingToExists(existings, newCmptOptions, mode) {
      var isNormalMergeMode = mode === 'normalMerge';
      var isReplaceMergeMode = mode === 'replaceMerge';
      var isReplaceAllMode = mode === 'replaceAll';
      existings = existings || [];
      newCmptOptions = (newCmptOptions || []).slice();
      var existingIdIdxMap = createHashMap(); // Validate id and name on user input option.

      each(newCmptOptions, function (cmptOption, index) {
        if (!isObject(cmptOption)) {
          newCmptOptions[index] = null;
          return;
        }

        if ("development" !== 'production') {
          // There is some legacy case that name is set as `false`.
          // But should work normally rather than throw error.
          if (cmptOption.id != null && !isValidIdOrName(cmptOption.id)) {
            warnInvalidateIdOrName(cmptOption.id);
          }

          if (cmptOption.name != null && !isValidIdOrName(cmptOption.name)) {
            warnInvalidateIdOrName(cmptOption.name);
          }
        }
      });
      var result = prepareResult(existings, existingIdIdxMap, mode);

      if (isNormalMergeMode || isReplaceMergeMode) {
        mappingById(result, existings, existingIdIdxMap, newCmptOptions);
      }

      if (isNormalMergeMode) {
        mappingByName(result, newCmptOptions);
      }

      if (isNormalMergeMode || isReplaceMergeMode) {
        mappingByIndex(result, newCmptOptions, isReplaceMergeMode);
      } else if (isReplaceAllMode) {
        mappingInReplaceAllMode(result, newCmptOptions);
      }

      makeIdAndName(result); // The array `result` MUST NOT contain elided items, otherwise the
      // forEach will omit those items and result in incorrect result.

      return result;
    }

    function prepareResult(existings, existingIdIdxMap, mode) {
      var result = [];

      if (mode === 'replaceAll') {
        return result;
      } // Do not use native `map` to in case that the array `existings`
      // contains elided items, which will be omitted.


      for (var index = 0; index < existings.length; index++) {
        var existing = existings[index]; // Because of replaceMerge, `existing` may be null/undefined.

        if (existing && existing.id != null) {
          existingIdIdxMap.set(existing.id, index);
        } // For non-internal-componnets:
        //     Mode "normalMerge": all existings kept.
        //     Mode "replaceMerge": all existing removed unless mapped by id.
        // For internal-components:
        //     go with "replaceMerge" approach in both mode.


        result.push({
          existing: mode === 'replaceMerge' || isComponentIdInternal(existing) ? null : existing,
          newOption: null,
          keyInfo: null,
          brandNew: null
        });
      }

      return result;
    }

    function mappingById(result, existings, existingIdIdxMap, newCmptOptions) {
      // Mapping by id if specified.
      each(newCmptOptions, function (cmptOption, index) {
        if (!cmptOption || cmptOption.id == null) {
          return;
        }

        var optionId = makeComparableKey(cmptOption.id);
        var existingIdx = existingIdIdxMap.get(optionId);

        if (existingIdx != null) {
          var resultItem = result[existingIdx];
          assert(!resultItem.newOption, 'Duplicated option on id "' + optionId + '".');
          resultItem.newOption = cmptOption; // In both mode, if id matched, new option will be merged to
          // the existings rather than creating new component model.

          resultItem.existing = existings[existingIdx];
          newCmptOptions[index] = null;
        }
      });
    }

    function mappingByName(result, newCmptOptions) {
      // Mapping by name if specified.
      each(newCmptOptions, function (cmptOption, index) {
        if (!cmptOption || cmptOption.name == null) {
          return;
        }

        for (var i = 0; i < result.length; i++) {
          var existing = result[i].existing;

          if (!result[i].newOption // Consider name: two map to one.
          // Can not match when both ids existing but different.
          && existing && (existing.id == null || cmptOption.id == null) && !isComponentIdInternal(cmptOption) && !isComponentIdInternal(existing) && keyExistAndEqual('name', existing, cmptOption)) {
            result[i].newOption = cmptOption;
            newCmptOptions[index] = null;
            return;
          }
        }
      });
    }

    function mappingByIndex(result, newCmptOptions, brandNew) {
      each(newCmptOptions, function (cmptOption) {
        if (!cmptOption) {
          return;
        } // Find the first place that not mapped by id and not internal component (consider the "hole").


        var resultItem;
        var nextIdx = 0;

        while ( // Be `!resultItem` only when `nextIdx >= result.length`.
        (resultItem = result[nextIdx]) && ( // (1) Existing models that already have id should be able to mapped to. Because
        // after mapping performed, model will always be assigned with an id if user not given.
        // After that all models have id.
        // (2) If new option has id, it can only set to a hole or append to the last. It should
        // not be merged to the existings with different id. Because id should not be overwritten.
        // (3) Name can be overwritten, because axis use name as 'show label text'.
        resultItem.newOption || isComponentIdInternal(resultItem.existing) || // In mode "replaceMerge", here no not-mapped-non-internal-existing.
        resultItem.existing && cmptOption.id != null && !keyExistAndEqual('id', cmptOption, resultItem.existing))) {
          nextIdx++;
        }

        if (resultItem) {
          resultItem.newOption = cmptOption;
          resultItem.brandNew = brandNew;
        } else {
          result.push({
            newOption: cmptOption,
            brandNew: brandNew,
            existing: null,
            keyInfo: null
          });
        }

        nextIdx++;
      });
    }

    function mappingInReplaceAllMode(result, newCmptOptions) {
      each(newCmptOptions, function (cmptOption) {
        // The feature "reproduce" requires "hole" will also reproduced
        // in case that component index referring are broken.
        result.push({
          newOption: cmptOption,
          brandNew: true,
          existing: null,
          keyInfo: null
        });
      });
    }
    /**
     * Make id and name for mapping result (result of mappingToExists)
     * into `keyInfo` field.
     */


    function makeIdAndName(mapResult) {
      // We use this id to hash component models and view instances
      // in echarts. id can be specified by user, or auto generated.
      // The id generation rule ensures new view instance are able
      // to mapped to old instance when setOption are called in
      // no-merge mode. So we generate model id by name and plus
      // type in view id.
      // name can be duplicated among components, which is convenient
      // to specify multi components (like series) by one name.
      // Ensure that each id is distinct.
      var idMap = createHashMap();
      each(mapResult, function (item) {
        var existing = item.existing;
        existing && idMap.set(existing.id, item);
      });
      each(mapResult, function (item) {
        var opt = item.newOption; // Force ensure id not duplicated.

        assert(!opt || opt.id == null || !idMap.get(opt.id) || idMap.get(opt.id) === item, 'id duplicates: ' + (opt && opt.id));
        opt && opt.id != null && idMap.set(opt.id, item);
        !item.keyInfo && (item.keyInfo = {});
      }); // Make name and id.

      each(mapResult, function (item, index) {
        var existing = item.existing;
        var opt = item.newOption;
        var keyInfo = item.keyInfo;

        if (!isObject(opt)) {
          return;
        } // Name can be overwritten. Consider case: axis.name = '20km'.
        // But id generated by name will not be changed, which affect
        // only in that case: setOption with 'not merge mode' and view
        // instance will be recreated, which can be accepted.


        keyInfo.name = opt.name != null ? makeComparableKey(opt.name) : existing ? existing.name // Avoid that different series has the same name,
        // because name may be used like in color pallet.
        : DUMMY_COMPONENT_NAME_PREFIX + index;

        if (existing) {
          keyInfo.id = makeComparableKey(existing.id);
        } else if (opt.id != null) {
          keyInfo.id = makeComparableKey(opt.id);
        } else {
          // Consider this situatoin:
          //  optionA: [{name: 'a'}, {name: 'a'}, {..}]
          //  optionB [{..}, {name: 'a'}, {name: 'a'}]
          // Series with the same name between optionA and optionB
          // should be mapped.
          var idNum = 0;

          do {
            keyInfo.id = '\0' + keyInfo.name + '\0' + idNum++;
          } while (idMap.get(keyInfo.id));
        }

        idMap.set(keyInfo.id, item);
      });
    }

    function keyExistAndEqual(attr, obj1, obj2) {
      var key1 = convertOptionIdName(obj1[attr], null);
      var key2 = convertOptionIdName(obj2[attr], null); // See `MappingExistingItem`. `id` and `name` trade string equals to number.

      return key1 != null && key2 != null && key1 === key2;
    }
    /**
     * @return return null if not exist.
     */


    function makeComparableKey(val) {
      if ("development" !== 'production') {
        if (val == null) {
          throw new Error();
        }
      }

      return convertOptionIdName(val, '');
    }

    function convertOptionIdName(idOrName, defaultValue) {
      if (idOrName == null) {
        return defaultValue;
      }

      return isString(idOrName) ? idOrName : isNumber(idOrName) || isStringSafe(idOrName) ? idOrName + '' : defaultValue;
    }

    function warnInvalidateIdOrName(idOrName) {
      if ("development" !== 'production') {
        warn('`' + idOrName + '` is invalid id or name. Must be a string or number.');
      }
    }

    function isValidIdOrName(idOrName) {
      return isStringSafe(idOrName) || isNumeric(idOrName);
    }

    function isNameSpecified(componentModel) {
      var name = componentModel.name; // Is specified when `indexOf` get -1 or > 0.

      return !!(name && name.indexOf(DUMMY_COMPONENT_NAME_PREFIX));
    }
    /**
     * @public
     * @param {Object} cmptOption
     * @return {boolean}
     */

    function isComponentIdInternal(cmptOption) {
      return cmptOption && cmptOption.id != null && makeComparableKey(cmptOption.id).indexOf(INTERNAL_COMPONENT_ID_PREFIX) === 0;
    }
    function setComponentTypeToKeyInfo(mappingResult, mainType, componentModelCtor) {
      // Set mainType and complete subType.
      each(mappingResult, function (item) {
        var newOption = item.newOption;

        if (isObject(newOption)) {
          item.keyInfo.mainType = mainType;
          item.keyInfo.subType = determineSubType(mainType, newOption, item.existing, componentModelCtor);
        }
      });
    }

    function determineSubType(mainType, newCmptOption, existComponent, componentModelCtor) {
      var subType = newCmptOption.type ? newCmptOption.type : existComponent ? existComponent.subType // Use determineSubType only when there is no existComponent.
      : componentModelCtor.determineSubType(mainType, newCmptOption); // tooltip, markline, markpoint may always has no subType

      return subType;
    }
    /**
     * @param payload Contains dataIndex (means rawIndex) / dataIndexInside / name
     *                         each of which can be Array or primary type.
     * @return dataIndex If not found, return undefined/null.
     */

    function queryDataIndex(data, payload) {
      if (payload.dataIndexInside != null) {
        return payload.dataIndexInside;
      } else if (payload.dataIndex != null) {
        return isArray(payload.dataIndex) ? map(payload.dataIndex, function (value) {
          return data.indexOfRawIndex(value);
        }) : data.indexOfRawIndex(payload.dataIndex);
      } else if (payload.name != null) {
        return isArray(payload.name) ? map(payload.name, function (value) {
          return data.indexOfName(value);
        }) : data.indexOfName(payload.name);
      }
    }
    /**
     * Enable property storage to any host object.
     * Notice: Serialization is not supported.
     *
     * For example:
     * let inner = zrUitl.makeInner();
     *
     * function some1(hostObj) {
     *      inner(hostObj).someProperty = 1212;
     *      ...
     * }
     * function some2() {
     *      let fields = inner(this);
     *      fields.someProperty1 = 1212;
     *      fields.someProperty2 = 'xx';
     *      ...
     * }
     *
     * @return {Function}
     */

    function makeInner() {
      var key = '__ec_inner_' + innerUniqueIndex++;
      return function (hostObj) {
        return hostObj[key] || (hostObj[key] = {});
      };
    }
    var innerUniqueIndex = getRandomIdBase();
    /**
     * The same behavior as `component.getReferringComponents`.
     */

    function parseFinder(ecModel, finderInput, opt) {
      var _a = preParseFinder(finderInput, opt),
          mainTypeSpecified = _a.mainTypeSpecified,
          queryOptionMap = _a.queryOptionMap,
          others = _a.others;

      var result = others;
      var defaultMainType = opt ? opt.defaultMainType : null;

      if (!mainTypeSpecified && defaultMainType) {
        queryOptionMap.set(defaultMainType, {});
      }

      queryOptionMap.each(function (queryOption, mainType) {
        var queryResult = queryReferringComponents(ecModel, mainType, queryOption, {
          useDefault: defaultMainType === mainType,
          enableAll: opt && opt.enableAll != null ? opt.enableAll : true,
          enableNone: opt && opt.enableNone != null ? opt.enableNone : true
        });
        result[mainType + 'Models'] = queryResult.models;
        result[mainType + 'Model'] = queryResult.models[0];
      });
      return result;
    }
    function preParseFinder(finderInput, opt) {
      var finder;

      if (isString(finderInput)) {
        var obj = {};
        obj[finderInput + 'Index'] = 0;
        finder = obj;
      } else {
        finder = finderInput;
      }

      var queryOptionMap = createHashMap();
      var others = {};
      var mainTypeSpecified = false;
      each(finder, function (value, key) {
        // Exclude 'dataIndex' and other illgal keys.
        if (key === 'dataIndex' || key === 'dataIndexInside') {
          others[key] = value;
          return;
        }

        var parsedKey = key.match(/^(\w+)(Index|Id|Name)$/) || [];
        var mainType = parsedKey[1];
        var queryType = (parsedKey[2] || '').toLowerCase();

        if (!mainType || !queryType || opt && opt.includeMainTypes && indexOf(opt.includeMainTypes, mainType) < 0) {
          return;
        }

        mainTypeSpecified = mainTypeSpecified || !!mainType;
        var queryOption = queryOptionMap.get(mainType) || queryOptionMap.set(mainType, {});
        queryOption[queryType] = value;
      });
      return {
        mainTypeSpecified: mainTypeSpecified,
        queryOptionMap: queryOptionMap,
        others: others
      };
    }
    var SINGLE_REFERRING = {
      useDefault: true,
      enableAll: false,
      enableNone: false
    };
    function queryReferringComponents(ecModel, mainType, userOption, opt) {
      opt = opt || SINGLE_REFERRING;
      var indexOption = userOption.index;
      var idOption = userOption.id;
      var nameOption = userOption.name;
      var result = {
        models: null,
        specified: indexOption != null || idOption != null || nameOption != null
      };

      if (!result.specified) {
        // Use the first as default if `useDefault`.
        var firstCmpt = void 0;
        result.models = opt.useDefault && (firstCmpt = ecModel.getComponent(mainType)) ? [firstCmpt] : [];
        return result;
      }

      if (indexOption === 'none' || indexOption === false) {
        assert(opt.enableNone, '`"none"` or `false` is not a valid value on index option.');
        result.models = [];
        return result;
      } // `queryComponents` will return all components if
      // both all of index/id/name are null/undefined.


      if (indexOption === 'all') {
        assert(opt.enableAll, '`"all"` is not a valid value on index option.');
        indexOption = idOption = nameOption = null;
      }

      result.models = ecModel.queryComponents({
        mainType: mainType,
        index: indexOption,
        id: idOption,
        name: nameOption
      });
      return result;
    }
    function setAttribute(dom, key, value) {
      dom.setAttribute ? dom.setAttribute(key, value) : dom[key] = value;
    }
    function getAttribute(dom, key) {
      return dom.getAttribute ? dom.getAttribute(key) : dom[key];
    }
    /**
     * Interpolate raw values of a series with percent
     *
     * @param data         data
     * @param labelModel   label model of the text element
     * @param sourceValue  start value. May be null/undefined when init.
     * @param targetValue  end value
     * @param percent      0~1 percentage; 0 uses start value while 1 uses end value
     * @return             interpolated values
     *                     If `sourceValue` and `targetValue` are `number`, return `number`.
     *                     If `sourceValue` and `targetValue` are `string`, return `string`.
     *                     If `sourceValue` and `targetValue` are `(string | number)[]`, return `(string | number)[]`.
     *                     Other cases do not supported.
     */

    function interpolateRawValues(data, precision, sourceValue, targetValue, percent) {
      var isAutoPrecision = precision == null || precision === 'auto';

      if (targetValue == null) {
        return targetValue;
      }

      if (isNumber(targetValue)) {
        var value = interpolateNumber$1(sourceValue || 0, targetValue, percent);
        return round(value, isAutoPrecision ? Math.max(getPrecision(sourceValue || 0), getPrecision(targetValue)) : precision);
      } else if (isString(targetValue)) {
        return percent < 1 ? sourceValue : targetValue;
      } else {
        var interpolated = [];
        var leftArr = sourceValue;
        var rightArr = targetValue;
        var length_1 = Math.max(leftArr ? leftArr.length : 0, rightArr.length);

        for (var i = 0; i < length_1; ++i) {
          var info = data.getDimensionInfo(i); // Don't interpolate ordinal dims

          if (info && info.type === 'ordinal') {
            // In init, there is no `sourceValue`, but should better not to get undefined result.
            interpolated[i] = (percent < 1 && leftArr ? leftArr : rightArr)[i];
          } else {
            var leftVal = leftArr && leftArr[i] ? leftArr[i] : 0;
            var rightVal = rightArr[i];
            var value = interpolateNumber$1(leftVal, rightVal, percent);
            interpolated[i] = round(value, isAutoPrecision ? Math.max(getPrecision(leftVal), getPrecision(rightVal)) : precision);
          }
        }

        return interpolated;
      }
    }

    var TYPE_DELIMITER = '.';
    var IS_CONTAINER = '___EC__COMPONENT__CONTAINER___';
    var IS_EXTENDED_CLASS = '___EC__EXTENDED_CLASS___';
    /**
     * Notice, parseClassType('') should returns {main: '', sub: ''}
     * @public
     */

    function parseClassType(componentType) {
      var ret = {
        main: '',
        sub: ''
      };

      if (componentType) {
        var typeArr = componentType.split(TYPE_DELIMITER);
        ret.main = typeArr[0] || '';
        ret.sub = typeArr[1] || '';
      }

      return ret;
    }
    /**
     * @public
     */

    function checkClassType(componentType) {
      assert(/^[a-zA-Z0-9_]+([.][a-zA-Z0-9_]+)?$/.test(componentType), 'componentType "' + componentType + '" illegal');
    }

    function isExtendedClass(clz) {
      return !!(clz && clz[IS_EXTENDED_CLASS]);
    }
    /**
     * Implements `ExtendableConstructor` for `rootClz`.
     *
     * @usage
     * ```ts
     * class Xxx {}
     * type XxxConstructor = typeof Xxx & ExtendableConstructor
     * enableClassExtend(Xxx as XxxConstructor);
     * ```
     */

    function enableClassExtend(rootClz, mandatoryMethods) {
      rootClz.$constructor = rootClz; // FIXME: not necessary?

      rootClz.extend = function (proto) {
        if ("development" !== 'production') {
          each(mandatoryMethods, function (method) {
            if (!proto[method]) {
              console.warn('Method `' + method + '` should be implemented' + (proto.type ? ' in ' + proto.type : '') + '.');
            }
          });
        }

        var superClass = this;
        var ExtendedClass;

        if (isESClass(superClass)) {
          ExtendedClass =
          /** @class */
          function (_super) {
            __extends(class_1, _super);

            function class_1() {
              return _super.apply(this, arguments) || this;
            }

            return class_1;
          }(superClass);
        } else {
          // For backward compat, we both support ts class inheritance and this
          // "extend" approach.
          // The constructor should keep the same behavior as ts class inheritance:
          // If this constructor/$constructor is not declared, auto invoke the super
          // constructor.
          // If this constructor/$constructor is declared, it is responsible for
          // calling the super constructor.
          ExtendedClass = function () {
            (proto.$constructor || superClass).apply(this, arguments);
          };

          inherits(ExtendedClass, this);
        }

        extend(ExtendedClass.prototype, proto);
        ExtendedClass[IS_EXTENDED_CLASS] = true;
        ExtendedClass.extend = this.extend;
        ExtendedClass.superCall = superCall;
        ExtendedClass.superApply = superApply;
        ExtendedClass.superClass = superClass;
        return ExtendedClass;
      };
    }

    function isESClass(fn) {
      return isFunction(fn) && /^class\s/.test(Function.prototype.toString.call(fn));
    }
    /**
     * A work around to both support ts extend and this extend mechanism.
     * on sub-class.
     * @usage
     * ```ts
     * class Component { ... }
     * classUtil.enableClassExtend(Component);
     * classUtil.enableClassManagement(Component, {registerWhenExtend: true});
     *
     * class Series extends Component { ... }
     * // Without calling `markExtend`, `registerWhenExtend` will not work.
     * Component.markExtend(Series);
     * ```
     */


    function mountExtend(SubClz, SupperClz) {
      SubClz.extend = SupperClz.extend;
    } // A random offset.

    var classBase = Math.round(Math.random() * 10);
    /**
     * Implements `CheckableConstructor` for `target`.
     * Can not use instanceof, consider different scope by
     * cross domain or es module import in ec extensions.
     * Mount a method "isInstance()" to Clz.
     *
     * @usage
     * ```ts
     * class Xxx {}
     * type XxxConstructor = typeof Xxx & CheckableConstructor;
     * enableClassCheck(Xxx as XxxConstructor)
     * ```
     */

    function enableClassCheck(target) {
      var classAttr = ['__\0is_clz', classBase++].join('_');
      target.prototype[classAttr] = true;

      if ("development" !== 'production') {
        assert(!target.isInstance, 'The method "is" can not be defined.');
      }

      target.isInstance = function (obj) {
        return !!(obj && obj[classAttr]);
      };
    } // superCall should have class info, which can not be fetched from 'this'.
    // Consider this case:
    // class A has method f,
    // class B inherits class A, overrides method f, f call superApply('f'),
    // class C inherits class B, does not override method f,
    // then when method of class C is called, dead loop occurred.

    function superCall(context, methodName) {
      var args = [];

      for (var _i = 2; _i < arguments.length; _i++) {
        args[_i - 2] = arguments[_i];
      }

      return this.superClass.prototype[methodName].apply(context, args);
    }

    function superApply(context, methodName, args) {
      return this.superClass.prototype[methodName].apply(context, args);
    }
    /**
     * Implements `ClassManager` for `target`
     *
     * @usage
     * ```ts
     * class Xxx {}
     * type XxxConstructor = typeof Xxx & ClassManager
     * enableClassManagement(Xxx as XxxConstructor);
     * ```
     */


    function enableClassManagement(target) {
      /**
       * Component model classes
       * key: componentType,
       * value:
       *     componentClass, when componentType is 'a'
       *     or Object.<subKey, componentClass>, when componentType is 'a.b'
       */
      var storage = {};

      target.registerClass = function (clz) {
        // `type` should not be a "instance member".
        // If using TS class, should better declared as `static type = 'series.pie'`.
        // otherwise users have to mount `type` on prototype manually.
        // For backward compat and enable instance visit type via `this.type`,
        // we still support fetch `type` from prototype.
        var componentFullType = clz.type || clz.prototype.type;

        if (componentFullType) {
          checkClassType(componentFullType); // If only static type declared, we assign it to prototype mandatorily.

          clz.prototype.type = componentFullType;
          var componentTypeInfo = parseClassType(componentFullType);

          if (!componentTypeInfo.sub) {
            if ("development" !== 'production') {
              if (storage[componentTypeInfo.main]) {
                console.warn(componentTypeInfo.main + ' exists.');
              }
            }

            storage[componentTypeInfo.main] = clz;
          } else if (componentTypeInfo.sub !== IS_CONTAINER) {
            var container = makeContainer(componentTypeInfo);
            container[componentTypeInfo.sub] = clz;
          }
        }

        return clz;
      };

      target.getClass = function (mainType, subType, throwWhenNotFound) {
        var clz = storage[mainType];

        if (clz && clz[IS_CONTAINER]) {
          clz = subType ? clz[subType] : null;
        }

        if (throwWhenNotFound && !clz) {
          throw new Error(!subType ? mainType + '.' + 'type should be specified.' : 'Component ' + mainType + '.' + (subType || '') + ' is used but not imported.');
        }

        return clz;
      };

      target.getClassesByMainType = function (componentType) {
        var componentTypeInfo = parseClassType(componentType);
        var result = [];
        var obj = storage[componentTypeInfo.main];

        if (obj && obj[IS_CONTAINER]) {
          each(obj, function (o, type) {
            type !== IS_CONTAINER && result.push(o);
          });
        } else {
          result.push(obj);
        }

        return result;
      };

      target.hasClass = function (componentType) {
        // Just consider componentType.main.
        var componentTypeInfo = parseClassType(componentType);
        return !!storage[componentTypeInfo.main];
      };
      /**
       * @return Like ['aa', 'bb'], but can not be ['aa.xx']
       */


      target.getAllClassMainTypes = function () {
        var types = [];
        each(storage, function (obj, type) {
          types.push(type);
        });
        return types;
      };
      /**
       * If a main type is container and has sub types
       */


      target.hasSubTypes = function (componentType) {
        var componentTypeInfo = parseClassType(componentType);
        var obj = storage[componentTypeInfo.main];
        return obj && obj[IS_CONTAINER];
      };

      function makeContainer(componentTypeInfo) {
        var container = storage[componentTypeInfo.main];

        if (!container || !container[IS_CONTAINER]) {
          container = storage[componentTypeInfo.main] = {};
          container[IS_CONTAINER] = true;
        }

        return container;
      }
    } // /**
    //  * @param {string|Array.<string>} properties
    //  */
    // export function setReadOnly(obj, properties) {
    // FIXME It seems broken in IE8 simulation of IE11
    // if (!zrUtil.isArray(properties)) {
    //     properties = properties != null ? [properties] : [];
    // }
    // zrUtil.each(properties, function (prop) {
    //     let value = obj[prop];
    //     Object.defineProperty
    //         && Object.defineProperty(obj, prop, {
    //             value: value, writable: false
    //         });
    //     zrUtil.isArray(obj[prop])
    //         && Object.freeze
    //         && Object.freeze(obj[prop]);
    // });
    // }

    function makeStyleMapper(properties, ignoreParent) {
      // Normalize
      for (var i = 0; i < properties.length; i++) {
        if (!properties[i][1]) {
          properties[i][1] = properties[i][0];
        }
      }

      ignoreParent = ignoreParent || false;
      return function (model, excludes, includes) {
        var style = {};

        for (var i = 0; i < properties.length; i++) {
          var propName = properties[i][1];

          if (excludes && indexOf(excludes, propName) >= 0 || includes && indexOf(includes, propName) < 0) {
            continue;
          }

          var val = model.getShallow(propName, ignoreParent);

          if (val != null) {
            style[properties[i][0]] = val;
          }
        } // TODO Text or image?


        return style;
      };
    }

    var AREA_STYLE_KEY_MAP = [['fill', 'color'], ['shadowBlur'], ['shadowOffsetX'], ['shadowOffsetY'], ['opacity'], ['shadowColor'] // Option decal is in `DecalObject` but style.decal is in `PatternObject`.
    // So do not transfer decal directly.
    ];
    var getAreaStyle = makeStyleMapper(AREA_STYLE_KEY_MAP);

    var AreaStyleMixin =
    /** @class */
    function () {
      function AreaStyleMixin() {}

      AreaStyleMixin.prototype.getAreaStyle = function (excludes, includes) {
        return getAreaStyle(this, excludes, includes);
      };

      return AreaStyleMixin;
    }();

    var globalImageCache = new LRU(50);
    function findExistImage(newImageOrSrc) {
        if (typeof newImageOrSrc === 'string') {
            var cachedImgObj = globalImageCache.get(newImageOrSrc);
            return cachedImgObj && cachedImgObj.image;
        }
        else {
            return newImageOrSrc;
        }
    }
    function createOrUpdateImage(newImageOrSrc, image, hostEl, onload, cbPayload) {
        if (!newImageOrSrc) {
            return image;
        }
        else if (typeof newImageOrSrc === 'string') {
            if ((image && image.__zrImageSrc === newImageOrSrc) || !hostEl) {
                return image;
            }
            var cachedImgObj = globalImageCache.get(newImageOrSrc);
            var pendingWrap = { hostEl: hostEl, cb: onload, cbPayload: cbPayload };
            if (cachedImgObj) {
                image = cachedImgObj.image;
                !isImageReady(image) && cachedImgObj.pending.push(pendingWrap);
            }
            else {
                image = platformApi.loadImage(newImageOrSrc, imageOnLoad, imageOnLoad);
                image.__zrImageSrc = newImageOrSrc;
                globalImageCache.put(newImageOrSrc, image.__cachedImgObj = {
                    image: image,
                    pending: [pendingWrap]
                });
            }
            return image;
        }
        else {
            return newImageOrSrc;
        }
    }
    function imageOnLoad() {
        var cachedImgObj = this.__cachedImgObj;
        this.onload = this.onerror = this.__cachedImgObj = null;
        for (var i = 0; i < cachedImgObj.pending.length; i++) {
            var pendingWrap = cachedImgObj.pending[i];
            var cb = pendingWrap.cb;
            cb && cb(this, pendingWrap.cbPayload);
            pendingWrap.hostEl.dirty();
        }
        cachedImgObj.pending.length = 0;
    }
    function isImageReady(image) {
        return image && image.width && image.height;
    }

    var STYLE_REG = /\{([a-zA-Z0-9_]+)\|([^}]*)\}/g;
    function truncateText(text, containerWidth, font, ellipsis, options) {
        if (!containerWidth) {
            return '';
        }
        var textLines = (text + '').split('\n');
        options = prepareTruncateOptions(containerWidth, font, ellipsis, options);
        for (var i = 0, len = textLines.length; i < len; i++) {
            textLines[i] = truncateSingleLine(textLines[i], options);
        }
        return textLines.join('\n');
    }
    function prepareTruncateOptions(containerWidth, font, ellipsis, options) {
        options = options || {};
        var preparedOpts = extend({}, options);
        preparedOpts.font = font;
        ellipsis = retrieve2(ellipsis, '...');
        preparedOpts.maxIterations = retrieve2(options.maxIterations, 2);
        var minChar = preparedOpts.minChar = retrieve2(options.minChar, 0);
        preparedOpts.cnCharWidth = getWidth('国', font);
        var ascCharWidth = preparedOpts.ascCharWidth = getWidth('a', font);
        preparedOpts.placeholder = retrieve2(options.placeholder, '');
        var contentWidth = containerWidth = Math.max(0, containerWidth - 1);
        for (var i = 0; i < minChar && contentWidth >= ascCharWidth; i++) {
            contentWidth -= ascCharWidth;
        }
        var ellipsisWidth = getWidth(ellipsis, font);
        if (ellipsisWidth > contentWidth) {
            ellipsis = '';
            ellipsisWidth = 0;
        }
        contentWidth = containerWidth - ellipsisWidth;
        preparedOpts.ellipsis = ellipsis;
        preparedOpts.ellipsisWidth = ellipsisWidth;
        preparedOpts.contentWidth = contentWidth;
        preparedOpts.containerWidth = containerWidth;
        return preparedOpts;
    }
    function truncateSingleLine(textLine, options) {
        var containerWidth = options.containerWidth;
        var font = options.font;
        var contentWidth = options.contentWidth;
        if (!containerWidth) {
            return '';
        }
        var lineWidth = getWidth(textLine, font);
        if (lineWidth <= containerWidth) {
            return textLine;
        }
        for (var j = 0;; j++) {
            if (lineWidth <= contentWidth || j >= options.maxIterations) {
                textLine += options.ellipsis;
                break;
            }
            var subLength = j === 0
                ? estimateLength(textLine, contentWidth, options.ascCharWidth, options.cnCharWidth)
                : lineWidth > 0
                    ? Math.floor(textLine.length * contentWidth / lineWidth)
                    : 0;
            textLine = textLine.substr(0, subLength);
            lineWidth = getWidth(textLine, font);
        }
        if (textLine === '') {
            textLine = options.placeholder;
        }
        return textLine;
    }
    function estimateLength(text, contentWidth, ascCharWidth, cnCharWidth) {
        var width = 0;
        var i = 0;
        for (var len = text.length; i < len && width < contentWidth; i++) {
            var charCode = text.charCodeAt(i);
            width += (0 <= charCode && charCode <= 127) ? ascCharWidth : cnCharWidth;
        }
        return i;
    }
    function parsePlainText(text, style) {
        text != null && (text += '');
        var overflow = style.overflow;
        var padding = style.padding;
        var font = style.font;
        var truncate = overflow === 'truncate';
        var calculatedLineHeight = getLineHeight(font);
        var lineHeight = retrieve2(style.lineHeight, calculatedLineHeight);
        var bgColorDrawn = !!(style.backgroundColor);
        var truncateLineOverflow = style.lineOverflow === 'truncate';
        var width = style.width;
        var lines;
        if (width != null && (overflow === 'break' || overflow === 'breakAll')) {
            lines = text ? wrapText(text, style.font, width, overflow === 'breakAll', 0).lines : [];
        }
        else {
            lines = text ? text.split('\n') : [];
        }
        var contentHeight = lines.length * lineHeight;
        var height = retrieve2(style.height, contentHeight);
        if (contentHeight > height && truncateLineOverflow) {
            var lineCount = Math.floor(height / lineHeight);
            lines = lines.slice(0, lineCount);
        }
        if (text && truncate && width != null) {
            var options = prepareTruncateOptions(width, font, style.ellipsis, {
                minChar: style.truncateMinChar,
                placeholder: style.placeholder
            });
            for (var i = 0; i < lines.length; i++) {
                lines[i] = truncateSingleLine(lines[i], options);
            }
        }
        var outerHeight = height;
        var contentWidth = 0;
        for (var i = 0; i < lines.length; i++) {
            contentWidth = Math.max(getWidth(lines[i], font), contentWidth);
        }
        if (width == null) {
            width = contentWidth;
        }
        var outerWidth = contentWidth;
        if (padding) {
            outerHeight += padding[0] + padding[2];
            outerWidth += padding[1] + padding[3];
            width += padding[1] + padding[3];
        }
        if (bgColorDrawn) {
            outerWidth = width;
        }
        return {
            lines: lines,
            height: height,
            outerWidth: outerWidth,
            outerHeight: outerHeight,
            lineHeight: lineHeight,
            calculatedLineHeight: calculatedLineHeight,
            contentWidth: contentWidth,
            contentHeight: contentHeight,
            width: width
        };
    }
    var RichTextToken = (function () {
        function RichTextToken() {
        }
        return RichTextToken;
    }());
    var RichTextLine = (function () {
        function RichTextLine(tokens) {
            this.tokens = [];
            if (tokens) {
                this.tokens = tokens;
            }
        }
        return RichTextLine;
    }());
    var RichTextContentBlock = (function () {
        function RichTextContentBlock() {
            this.width = 0;
            this.height = 0;
            this.contentWidth = 0;
            this.contentHeight = 0;
            this.outerWidth = 0;
            this.outerHeight = 0;
            this.lines = [];
        }
        return RichTextContentBlock;
    }());
    function parseRichText(text, style) {
        var contentBlock = new RichTextContentBlock();
        text != null && (text += '');
        if (!text) {
            return contentBlock;
        }
        var topWidth = style.width;
        var topHeight = style.height;
        var overflow = style.overflow;
        var wrapInfo = (overflow === 'break' || overflow === 'breakAll') && topWidth != null
            ? { width: topWidth, accumWidth: 0, breakAll: overflow === 'breakAll' }
            : null;
        var lastIndex = STYLE_REG.lastIndex = 0;
        var result;
        while ((result = STYLE_REG.exec(text)) != null) {
            var matchedIndex = result.index;
            if (matchedIndex > lastIndex) {
                pushTokens(contentBlock, text.substring(lastIndex, matchedIndex), style, wrapInfo);
            }
            pushTokens(contentBlock, result[2], style, wrapInfo, result[1]);
            lastIndex = STYLE_REG.lastIndex;
        }
        if (lastIndex < text.length) {
            pushTokens(contentBlock, text.substring(lastIndex, text.length), style, wrapInfo);
        }
        var pendingList = [];
        var calculatedHeight = 0;
        var calculatedWidth = 0;
        var stlPadding = style.padding;
        var truncate = overflow === 'truncate';
        var truncateLine = style.lineOverflow === 'truncate';
        function finishLine(line, lineWidth, lineHeight) {
            line.width = lineWidth;
            line.lineHeight = lineHeight;
            calculatedHeight += lineHeight;
            calculatedWidth = Math.max(calculatedWidth, lineWidth);
        }
        outer: for (var i = 0; i < contentBlock.lines.length; i++) {
            var line = contentBlock.lines[i];
            var lineHeight = 0;
            var lineWidth = 0;
            for (var j = 0; j < line.tokens.length; j++) {
                var token = line.tokens[j];
                var tokenStyle = token.styleName && style.rich[token.styleName] || {};
                var textPadding = token.textPadding = tokenStyle.padding;
                var paddingH = textPadding ? textPadding[1] + textPadding[3] : 0;
                var font = token.font = tokenStyle.font || style.font;
                token.contentHeight = getLineHeight(font);
                var tokenHeight = retrieve2(tokenStyle.height, token.contentHeight);
                token.innerHeight = tokenHeight;
                textPadding && (tokenHeight += textPadding[0] + textPadding[2]);
                token.height = tokenHeight;
                token.lineHeight = retrieve3(tokenStyle.lineHeight, style.lineHeight, tokenHeight);
                token.align = tokenStyle && tokenStyle.align || style.align;
                token.verticalAlign = tokenStyle && tokenStyle.verticalAlign || 'middle';
                if (truncateLine && topHeight != null && calculatedHeight + token.lineHeight > topHeight) {
                    if (j > 0) {
                        line.tokens = line.tokens.slice(0, j);
                        finishLine(line, lineWidth, lineHeight);
                        contentBlock.lines = contentBlock.lines.slice(0, i + 1);
                    }
                    else {
                        contentBlock.lines = contentBlock.lines.slice(0, i);
                    }
                    break outer;
                }
                var styleTokenWidth = tokenStyle.width;
                var tokenWidthNotSpecified = styleTokenWidth == null || styleTokenWidth === 'auto';
                if (typeof styleTokenWidth === 'string' && styleTokenWidth.charAt(styleTokenWidth.length - 1) === '%') {
                    token.percentWidth = styleTokenWidth;
                    pendingList.push(token);
                    token.contentWidth = getWidth(token.text, font);
                }
                else {
                    if (tokenWidthNotSpecified) {
                        var textBackgroundColor = tokenStyle.backgroundColor;
                        var bgImg = textBackgroundColor && textBackgroundColor.image;
                        if (bgImg) {
                            bgImg = findExistImage(bgImg);
                            if (isImageReady(bgImg)) {
                                token.width = Math.max(token.width, bgImg.width * tokenHeight / bgImg.height);
                            }
                        }
                    }
                    var remainTruncWidth = truncate && topWidth != null
                        ? topWidth - lineWidth : null;
                    if (remainTruncWidth != null && remainTruncWidth < token.width) {
                        if (!tokenWidthNotSpecified || remainTruncWidth < paddingH) {
                            token.text = '';
                            token.width = token.contentWidth = 0;
                        }
                        else {
                            token.text = truncateText(token.text, remainTruncWidth - paddingH, font, style.ellipsis, { minChar: style.truncateMinChar });
                            token.width = token.contentWidth = getWidth(token.text, font);
                        }
                    }
                    else {
                        token.contentWidth = getWidth(token.text, font);
                    }
                }
                token.width += paddingH;
                lineWidth += token.width;
                tokenStyle && (lineHeight = Math.max(lineHeight, token.lineHeight));
            }
            finishLine(line, lineWidth, lineHeight);
        }
        contentBlock.outerWidth = contentBlock.width = retrieve2(topWidth, calculatedWidth);
        contentBlock.outerHeight = contentBlock.height = retrieve2(topHeight, calculatedHeight);
        contentBlock.contentHeight = calculatedHeight;
        contentBlock.contentWidth = calculatedWidth;
        if (stlPadding) {
            contentBlock.outerWidth += stlPadding[1] + stlPadding[3];
            contentBlock.outerHeight += stlPadding[0] + stlPadding[2];
        }
        for (var i = 0; i < pendingList.length; i++) {
            var token = pendingList[i];
            var percentWidth = token.percentWidth;
            token.width = parseInt(percentWidth, 10) / 100 * contentBlock.width;
        }
        return contentBlock;
    }
    function pushTokens(block, str, style, wrapInfo, styleName) {
        var isEmptyStr = str === '';
        var tokenStyle = styleName && style.rich[styleName] || {};
        var lines = block.lines;
        var font = tokenStyle.font || style.font;
        var newLine = false;
        var strLines;
        var linesWidths;
        if (wrapInfo) {
            var tokenPadding = tokenStyle.padding;
            var tokenPaddingH = tokenPadding ? tokenPadding[1] + tokenPadding[3] : 0;
            if (tokenStyle.width != null && tokenStyle.width !== 'auto') {
                var outerWidth_1 = parsePercent(tokenStyle.width, wrapInfo.width) + tokenPaddingH;
                if (lines.length > 0) {
                    if (outerWidth_1 + wrapInfo.accumWidth > wrapInfo.width) {
                        strLines = str.split('\n');
                        newLine = true;
                    }
                }
                wrapInfo.accumWidth = outerWidth_1;
            }
            else {
                var res = wrapText(str, font, wrapInfo.width, wrapInfo.breakAll, wrapInfo.accumWidth);
                wrapInfo.accumWidth = res.accumWidth + tokenPaddingH;
                linesWidths = res.linesWidths;
                strLines = res.lines;
            }
        }
        else {
            strLines = str.split('\n');
        }
        for (var i = 0; i < strLines.length; i++) {
            var text = strLines[i];
            var token = new RichTextToken();
            token.styleName = styleName;
            token.text = text;
            token.isLineHolder = !text && !isEmptyStr;
            if (typeof tokenStyle.width === 'number') {
                token.width = tokenStyle.width;
            }
            else {
                token.width = linesWidths
                    ? linesWidths[i]
                    : getWidth(text, font);
            }
            if (!i && !newLine) {
                var tokens = (lines[lines.length - 1] || (lines[0] = new RichTextLine())).tokens;
                var tokensLen = tokens.length;
                (tokensLen === 1 && tokens[0].isLineHolder)
                    ? (tokens[0] = token)
                    : ((text || !tokensLen || isEmptyStr) && tokens.push(token));
            }
            else {
                lines.push(new RichTextLine([token]));
            }
        }
    }
    function isLatin(ch) {
        var code = ch.charCodeAt(0);
        return code >= 0x21 && code <= 0x17F;
    }
    var breakCharMap = reduce(',&?/;] '.split(''), function (obj, ch) {
        obj[ch] = true;
        return obj;
    }, {});
    function isWordBreakChar(ch) {
        if (isLatin(ch)) {
            if (breakCharMap[ch]) {
                return true;
            }
            return false;
        }
        return true;
    }
    function wrapText(text, font, lineWidth, isBreakAll, lastAccumWidth) {
        var lines = [];
        var linesWidths = [];
        var line = '';
        var currentWord = '';
        var currentWordWidth = 0;
        var accumWidth = 0;
        for (var i = 0; i < text.length; i++) {
            var ch = text.charAt(i);
            if (ch === '\n') {
                if (currentWord) {
                    line += currentWord;
                    accumWidth += currentWordWidth;
                }
                lines.push(line);
                linesWidths.push(accumWidth);
                line = '';
                currentWord = '';
                currentWordWidth = 0;
                accumWidth = 0;
                continue;
            }
            var chWidth = getWidth(ch, font);
            var inWord = isBreakAll ? false : !isWordBreakChar(ch);
            if (!lines.length
                ? lastAccumWidth + accumWidth + chWidth > lineWidth
                : accumWidth + chWidth > lineWidth) {
                if (!accumWidth) {
                    if (inWord) {
                        lines.push(currentWord);
                        linesWidths.push(currentWordWidth);
                        currentWord = ch;
                        currentWordWidth = chWidth;
                    }
                    else {
                        lines.push(ch);
                        linesWidths.push(chWidth);
                    }
                }
                else if (line || currentWord) {
                    if (inWord) {
                        if (!line) {
                            line = currentWord;
                            currentWord = '';
                            currentWordWidth = 0;
                            accumWidth = currentWordWidth;
                        }
                        lines.push(line);
                        linesWidths.push(accumWidth - currentWordWidth);
                        currentWord += ch;
                        currentWordWidth += chWidth;
                        line = '';
                        accumWidth = currentWordWidth;
                    }
                    else {
                        if (currentWord) {
                            line += currentWord;
                            currentWord = '';
                            currentWordWidth = 0;
                        }
                        lines.push(line);
                        linesWidths.push(accumWidth);
                        line = ch;
                        accumWidth = chWidth;
                    }
                }
                continue;
            }
            accumWidth += chWidth;
            if (inWord) {
                currentWord += ch;
                currentWordWidth += chWidth;
            }
            else {
                if (currentWord) {
                    line += currentWord;
                    currentWord = '';
                    currentWordWidth = 0;
                }
                line += ch;
            }
        }
        if (!lines.length && !line) {
            line = text;
            currentWord = '';
            currentWordWidth = 0;
        }
        if (currentWord) {
            line += currentWord;
        }
        if (line) {
            lines.push(line);
            linesWidths.push(accumWidth);
        }
        if (lines.length === 1) {
            accumWidth += lastAccumWidth;
        }
        return {
            accumWidth: accumWidth,
            lines: lines,
            linesWidths: linesWidths
        };
    }

    var STYLE_MAGIC_KEY = '__zr_style_' + Math.round((Math.random() * 10));
    var DEFAULT_COMMON_STYLE = {
        shadowBlur: 0,
        shadowOffsetX: 0,
        shadowOffsetY: 0,
        shadowColor: '#000',
        opacity: 1,
        blend: 'source-over'
    };
    var DEFAULT_COMMON_ANIMATION_PROPS = {
        style: {
            shadowBlur: true,
            shadowOffsetX: true,
            shadowOffsetY: true,
            shadowColor: true,
            opacity: true
        }
    };
    DEFAULT_COMMON_STYLE[STYLE_MAGIC_KEY] = true;
    var PRIMARY_STATES_KEYS$1 = ['z', 'z2', 'invisible'];
    var PRIMARY_STATES_KEYS_IN_HOVER_LAYER = ['invisible'];
    var Displayable = (function (_super) {
        __extends(Displayable, _super);
        function Displayable(props) {
            return _super.call(this, props) || this;
        }
        Displayable.prototype._init = function (props) {
            var keysArr = keys(props);
            for (var i = 0; i < keysArr.length; i++) {
                var key = keysArr[i];
                if (key === 'style') {
                    this.useStyle(props[key]);
                }
                else {
                    _super.prototype.attrKV.call(this, key, props[key]);
                }
            }
            if (!this.style) {
                this.useStyle({});
            }
        };
        Displayable.prototype.beforeBrush = function () { };
        Displayable.prototype.afterBrush = function () { };
        Displayable.prototype.innerBeforeBrush = function () { };
        Displayable.prototype.innerAfterBrush = function () { };
        Displayable.prototype.shouldBePainted = function (viewWidth, viewHeight, considerClipPath, considerAncestors) {
            var m = this.transform;
            if (this.ignore
                || this.invisible
                || this.style.opacity === 0
                || (this.culling
                    && isDisplayableCulled(this, viewWidth, viewHeight))
                || (m && !m[0] && !m[3])) {
                return false;
            }
            if (considerClipPath && this.__clipPaths) {
                for (var i = 0; i < this.__clipPaths.length; ++i) {
                    if (this.__clipPaths[i].isZeroArea()) {
                        return false;
                    }
                }
            }
            if (considerAncestors && this.parent) {
                var parent_1 = this.parent;
                while (parent_1) {
                    if (parent_1.ignore) {
                        return false;
                    }
                    parent_1 = parent_1.parent;
                }
            }
            return true;
        };
        Displayable.prototype.contain = function (x, y) {
            return this.rectContain(x, y);
        };
        Displayable.prototype.traverse = function (cb, context) {
            cb.call(context, this);
        };
        Displayable.prototype.rectContain = function (x, y) {
            var coord = this.transformCoordToLocal(x, y);
            var rect = this.getBoundingRect();
            return rect.contain(coord[0], coord[1]);
        };
        Displayable.prototype.getPaintRect = function () {
            var rect = this._paintRect;
            if (!this._paintRect || this.__dirty) {
                var transform = this.transform;
                var elRect = this.getBoundingRect();
                var style = this.style;
                var shadowSize = style.shadowBlur || 0;
                var shadowOffsetX = style.shadowOffsetX || 0;
                var shadowOffsetY = style.shadowOffsetY || 0;
                rect = this._paintRect || (this._paintRect = new BoundingRect(0, 0, 0, 0));
                if (transform) {
                    BoundingRect.applyTransform(rect, elRect, transform);
                }
                else {
                    rect.copy(elRect);
                }
                if (shadowSize || shadowOffsetX || shadowOffsetY) {
                    rect.width += shadowSize * 2 + Math.abs(shadowOffsetX);
                    rect.height += shadowSize * 2 + Math.abs(shadowOffsetY);
                    rect.x = Math.min(rect.x, rect.x + shadowOffsetX - shadowSize);
                    rect.y = Math.min(rect.y, rect.y + shadowOffsetY - shadowSize);
                }
                var tolerance = this.dirtyRectTolerance;
                if (!rect.isZero()) {
                    rect.x = Math.floor(rect.x - tolerance);
                    rect.y = Math.floor(rect.y - tolerance);
                    rect.width = Math.ceil(rect.width + 1 + tolerance * 2);
                    rect.height = Math.ceil(rect.height + 1 + tolerance * 2);
                }
            }
            return rect;
        };
        Displayable.prototype.setPrevPaintRect = function (paintRect) {
            if (paintRect) {
                this._prevPaintRect = this._prevPaintRect || new BoundingRect(0, 0, 0, 0);
                this._prevPaintRect.copy(paintRect);
            }
            else {
                this._prevPaintRect = null;
            }
        };
        Displayable.prototype.getPrevPaintRect = function () {
            return this._prevPaintRect;
        };
        Displayable.prototype.animateStyle = function (loop) {
            return this.animate('style', loop);
        };
        Displayable.prototype.updateDuringAnimation = function (targetKey) {
            if (targetKey === 'style') {
                this.dirtyStyle();
            }
            else {
                this.markRedraw();
            }
        };
        Displayable.prototype.attrKV = function (key, value) {
            if (key !== 'style') {
                _super.prototype.attrKV.call(this, key, value);
            }
            else {
                if (!this.style) {
                    this.useStyle(value);
                }
                else {
                    this.setStyle(value);
                }
            }
        };
        Displayable.prototype.setStyle = function (keyOrObj, value) {
            if (typeof keyOrObj === 'string') {
                this.style[keyOrObj] = value;
            }
            else {
                extend(this.style, keyOrObj);
            }
            this.dirtyStyle();
            return this;
        };
        Displayable.prototype.dirtyStyle = function (notRedraw) {
            if (!notRedraw) {
                this.markRedraw();
            }
            this.__dirty |= STYLE_CHANGED_BIT;
            if (this._rect) {
                this._rect = null;
            }
        };
        Displayable.prototype.dirty = function () {
            this.dirtyStyle();
        };
        Displayable.prototype.styleChanged = function () {
            return !!(this.__dirty & STYLE_CHANGED_BIT);
        };
        Displayable.prototype.styleUpdated = function () {
            this.__dirty &= ~STYLE_CHANGED_BIT;
        };
        Displayable.prototype.createStyle = function (obj) {
            return createObject(DEFAULT_COMMON_STYLE, obj);
        };
        Displayable.prototype.useStyle = function (obj) {
            if (!obj[STYLE_MAGIC_KEY]) {
                obj = this.createStyle(obj);
            }
            if (this.__inHover) {
                this.__hoverStyle = obj;
            }
            else {
                this.style = obj;
            }
            this.dirtyStyle();
        };
        Displayable.prototype.isStyleObject = function (obj) {
            return obj[STYLE_MAGIC_KEY];
        };
        Displayable.prototype._innerSaveToNormal = function (toState) {
            _super.prototype._innerSaveToNormal.call(this, toState);
            var normalState = this._normalState;
            if (toState.style && !normalState.style) {
                normalState.style = this._mergeStyle(this.createStyle(), this.style);
            }
            this._savePrimaryToNormal(toState, normalState, PRIMARY_STATES_KEYS$1);
        };
        Displayable.prototype._applyStateObj = function (stateName, state, normalState, keepCurrentStates, transition, animationCfg) {
            _super.prototype._applyStateObj.call(this, stateName, state, normalState, keepCurrentStates, transition, animationCfg);
            var needsRestoreToNormal = !(state && keepCurrentStates);
            var targetStyle;
            if (state && state.style) {
                if (transition) {
                    if (keepCurrentStates) {
                        targetStyle = state.style;
                    }
                    else {
                        targetStyle = this._mergeStyle(this.createStyle(), normalState.style);
                        this._mergeStyle(targetStyle, state.style);
                    }
                }
                else {
                    targetStyle = this._mergeStyle(this.createStyle(), keepCurrentStates ? this.style : normalState.style);
                    this._mergeStyle(targetStyle, state.style);
                }
            }
            else if (needsRestoreToNormal) {
                targetStyle = normalState.style;
            }
            if (targetStyle) {
                if (transition) {
                    var sourceStyle = this.style;
                    this.style = this.createStyle(needsRestoreToNormal ? {} : sourceStyle);
                    if (needsRestoreToNormal) {
                        var changedKeys = keys(sourceStyle);
                        for (var i = 0; i < changedKeys.length; i++) {
                            var key = changedKeys[i];
                            if (key in targetStyle) {
                                targetStyle[key] = targetStyle[key];
                                this.style[key] = sourceStyle[key];
                            }
                        }
                    }
                    var targetKeys = keys(targetStyle);
                    for (var i = 0; i < targetKeys.length; i++) {
                        var key = targetKeys[i];
                        this.style[key] = this.style[key];
                    }
                    this._transitionState(stateName, {
                        style: targetStyle
                    }, animationCfg, this.getAnimationStyleProps());
                }
                else {
                    this.useStyle(targetStyle);
                }
            }
            var statesKeys = this.__inHover ? PRIMARY_STATES_KEYS_IN_HOVER_LAYER : PRIMARY_STATES_KEYS$1;
            for (var i = 0; i < statesKeys.length; i++) {
                var key = statesKeys[i];
                if (state && state[key] != null) {
                    this[key] = state[key];
                }
                else if (needsRestoreToNormal) {
                    if (normalState[key] != null) {
                        this[key] = normalState[key];
                    }
                }
            }
        };
        Displayable.prototype._mergeStates = function (states) {
            var mergedState = _super.prototype._mergeStates.call(this, states);
            var mergedStyle;
            for (var i = 0; i < states.length; i++) {
                var state = states[i];
                if (state.style) {
                    mergedStyle = mergedStyle || {};
                    this._mergeStyle(mergedStyle, state.style);
                }
            }
            if (mergedStyle) {
                mergedState.style = mergedStyle;
            }
            return mergedState;
        };
        Displayable.prototype._mergeStyle = function (targetStyle, sourceStyle) {
            extend(targetStyle, sourceStyle);
            return targetStyle;
        };
        Displayable.prototype.getAnimationStyleProps = function () {
            return DEFAULT_COMMON_ANIMATION_PROPS;
        };
        Displayable.initDefaultProps = (function () {
            var dispProto = Displayable.prototype;
            dispProto.type = 'displayable';
            dispProto.invisible = false;
            dispProto.z = 0;
            dispProto.z2 = 0;
            dispProto.zlevel = 0;
            dispProto.culling = false;
            dispProto.cursor = 'pointer';
            dispProto.rectHover = false;
            dispProto.incremental = false;
            dispProto._rect = null;
            dispProto.dirtyRectTolerance = 0;
            dispProto.__dirty = REDRAW_BIT | STYLE_CHANGED_BIT;
        })();
        return Displayable;
    }(Element));
    var tmpRect$1 = new BoundingRect(0, 0, 0, 0);
    var viewRect = new BoundingRect(0, 0, 0, 0);
    function isDisplayableCulled(el, width, height) {
        tmpRect$1.copy(el.getBoundingRect());
        if (el.transform) {
            tmpRect$1.applyTransform(el.transform);
        }
        viewRect.width = width;
        viewRect.height = height;
        return !tmpRect$1.intersect(viewRect);
    }

    var mathMin$1 = Math.min;
    var mathMax$1 = Math.max;
    var mathSin = Math.sin;
    var mathCos = Math.cos;
    var PI2 = Math.PI * 2;
    var start = create();
    var end = create();
    var extremity = create();
    function fromLine(x0, y0, x1, y1, min, max) {
        min[0] = mathMin$1(x0, x1);
        min[1] = mathMin$1(y0, y1);
        max[0] = mathMax$1(x0, x1);
        max[1] = mathMax$1(y0, y1);
    }
    var xDim = [];
    var yDim = [];
    function fromCubic(x0, y0, x1, y1, x2, y2, x3, y3, min, max) {
        var cubicExtrema$1 = cubicExtrema;
        var cubicAt$1 = cubicAt;
        var n = cubicExtrema$1(x0, x1, x2, x3, xDim);
        min[0] = Infinity;
        min[1] = Infinity;
        max[0] = -Infinity;
        max[1] = -Infinity;
        for (var i = 0; i < n; i++) {
            var x = cubicAt$1(x0, x1, x2, x3, xDim[i]);
            min[0] = mathMin$1(x, min[0]);
            max[0] = mathMax$1(x, max[0]);
        }
        n = cubicExtrema$1(y0, y1, y2, y3, yDim);
        for (var i = 0; i < n; i++) {
            var y = cubicAt$1(y0, y1, y2, y3, yDim[i]);
            min[1] = mathMin$1(y, min[1]);
            max[1] = mathMax$1(y, max[1]);
        }
        min[0] = mathMin$1(x0, min[0]);
        max[0] = mathMax$1(x0, max[0]);
        min[0] = mathMin$1(x3, min[0]);
        max[0] = mathMax$1(x3, max[0]);
        min[1] = mathMin$1(y0, min[1]);
        max[1] = mathMax$1(y0, max[1]);
        min[1] = mathMin$1(y3, min[1]);
        max[1] = mathMax$1(y3, max[1]);
    }
    function fromQuadratic(x0, y0, x1, y1, x2, y2, min, max) {
        var quadraticExtremum$1 = quadraticExtremum;
        var quadraticAt$1 = quadraticAt;
        var tx = mathMax$1(mathMin$1(quadraticExtremum$1(x0, x1, x2), 1), 0);
        var ty = mathMax$1(mathMin$1(quadraticExtremum$1(y0, y1, y2), 1), 0);
        var x = quadraticAt$1(x0, x1, x2, tx);
        var y = quadraticAt$1(y0, y1, y2, ty);
        min[0] = mathMin$1(x0, x2, x);
        min[1] = mathMin$1(y0, y2, y);
        max[0] = mathMax$1(x0, x2, x);
        max[1] = mathMax$1(y0, y2, y);
    }
    function fromArc(x, y, rx, ry, startAngle, endAngle, anticlockwise, min$1, max$1) {
        var vec2Min = min;
        var vec2Max = max;
        var diff = Math.abs(startAngle - endAngle);
        if (diff % PI2 < 1e-4 && diff > 1e-4) {
            min$1[0] = x - rx;
            min$1[1] = y - ry;
            max$1[0] = x + rx;
            max$1[1] = y + ry;
            return;
        }
        start[0] = mathCos(startAngle) * rx + x;
        start[1] = mathSin(startAngle) * ry + y;
        end[0] = mathCos(endAngle) * rx + x;
        end[1] = mathSin(endAngle) * ry + y;
        vec2Min(min$1, start, end);
        vec2Max(max$1, start, end);
        startAngle = startAngle % (PI2);
        if (startAngle < 0) {
            startAngle = startAngle + PI2;
        }
        endAngle = endAngle % (PI2);
        if (endAngle < 0) {
            endAngle = endAngle + PI2;
        }
        if (startAngle > endAngle && !anticlockwise) {
            endAngle += PI2;
        }
        else if (startAngle < endAngle && anticlockwise) {
            startAngle += PI2;
        }
        if (anticlockwise) {
            var tmp = endAngle;
            endAngle = startAngle;
            startAngle = tmp;
        }
        for (var angle = 0; angle < endAngle; angle += Math.PI / 2) {
            if (angle > startAngle) {
                extremity[0] = mathCos(angle) * rx + x;
                extremity[1] = mathSin(angle) * ry + y;
                vec2Min(min$1, extremity, min$1);
                vec2Max(max$1, extremity, max$1);
            }
        }
    }

    var CMD = {
        M: 1,
        L: 2,
        C: 3,
        Q: 4,
        A: 5,
        Z: 6,
        R: 7
    };
    var tmpOutX = [];
    var tmpOutY = [];
    var min$1 = [];
    var max$1 = [];
    var min2 = [];
    var max2 = [];
    var mathMin$2 = Math.min;
    var mathMax$2 = Math.max;
    var mathCos$1 = Math.cos;
    var mathSin$1 = Math.sin;
    var mathAbs = Math.abs;
    var PI = Math.PI;
    var PI2$1 = PI * 2;
    var hasTypedArray = typeof Float32Array !== 'undefined';
    var tmpAngles = [];
    function modPI2(radian) {
        var n = Math.round(radian / PI * 1e8) / 1e8;
        return (n % 2) * PI;
    }
    function normalizeArcAngles(angles, anticlockwise) {
        var newStartAngle = modPI2(angles[0]);
        if (newStartAngle < 0) {
            newStartAngle += PI2$1;
        }
        var delta = newStartAngle - angles[0];
        var newEndAngle = angles[1];
        newEndAngle += delta;
        if (!anticlockwise && newEndAngle - newStartAngle >= PI2$1) {
            newEndAngle = newStartAngle + PI2$1;
        }
        else if (anticlockwise && newStartAngle - newEndAngle >= PI2$1) {
            newEndAngle = newStartAngle - PI2$1;
        }
        else if (!anticlockwise && newStartAngle > newEndAngle) {
            newEndAngle = newStartAngle + (PI2$1 - modPI2(newStartAngle - newEndAngle));
        }
        else if (anticlockwise && newStartAngle < newEndAngle) {
            newEndAngle = newStartAngle - (PI2$1 - modPI2(newEndAngle - newStartAngle));
        }
        angles[0] = newStartAngle;
        angles[1] = newEndAngle;
    }
    var PathProxy = (function () {
        function PathProxy(notSaveData) {
            this.dpr = 1;
            this._xi = 0;
            this._yi = 0;
            this._x0 = 0;
            this._y0 = 0;
            this._len = 0;
            if (notSaveData) {
                this._saveData = false;
            }
            if (this._saveData) {
                this.data = [];
            }
        }
        PathProxy.prototype.increaseVersion = function () {
            this._version++;
        };
        PathProxy.prototype.getVersion = function () {
            return this._version;
        };
        PathProxy.prototype.setScale = function (sx, sy, segmentIgnoreThreshold) {
            segmentIgnoreThreshold = segmentIgnoreThreshold || 0;
            if (segmentIgnoreThreshold > 0) {
                this._ux = mathAbs(segmentIgnoreThreshold / devicePixelRatio / sx) || 0;
                this._uy = mathAbs(segmentIgnoreThreshold / devicePixelRatio / sy) || 0;
            }
        };
        PathProxy.prototype.setDPR = function (dpr) {
            this.dpr = dpr;
        };
        PathProxy.prototype.setContext = function (ctx) {
            this._ctx = ctx;
        };
        PathProxy.prototype.getContext = function () {
            return this._ctx;
        };
        PathProxy.prototype.beginPath = function () {
            this._ctx && this._ctx.beginPath();
            this.reset();
            return this;
        };
        PathProxy.prototype.reset = function () {
            if (this._saveData) {
                this._len = 0;
            }
            if (this._pathSegLen) {
                this._pathSegLen = null;
                this._pathLen = 0;
            }
            this._version++;
        };
        PathProxy.prototype.moveTo = function (x, y) {
            this._drawPendingPt();
            this.addData(CMD.M, x, y);
            this._ctx && this._ctx.moveTo(x, y);
            this._x0 = x;
            this._y0 = y;
            this._xi = x;
            this._yi = y;
            return this;
        };
        PathProxy.prototype.lineTo = function (x, y) {
            var dx = mathAbs(x - this._xi);
            var dy = mathAbs(y - this._yi);
            var exceedUnit = dx > this._ux || dy > this._uy;
            this.addData(CMD.L, x, y);
            if (this._ctx && exceedUnit) {
                this._ctx.lineTo(x, y);
            }
            if (exceedUnit) {
                this._xi = x;
                this._yi = y;
                this._pendingPtDist = 0;
            }
            else {
                var d2 = dx * dx + dy * dy;
                if (d2 > this._pendingPtDist) {
                    this._pendingPtX = x;
                    this._pendingPtY = y;
                    this._pendingPtDist = d2;
                }
            }
            return this;
        };
        PathProxy.prototype.bezierCurveTo = function (x1, y1, x2, y2, x3, y3) {
            this._drawPendingPt();
            this.addData(CMD.C, x1, y1, x2, y2, x3, y3);
            if (this._ctx) {
                this._ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3);
            }
            this._xi = x3;
            this._yi = y3;
            return this;
        };
        PathProxy.prototype.quadraticCurveTo = function (x1, y1, x2, y2) {
            this._drawPendingPt();
            this.addData(CMD.Q, x1, y1, x2, y2);
            if (this._ctx) {
                this._ctx.quadraticCurveTo(x1, y1, x2, y2);
            }
            this._xi = x2;
            this._yi = y2;
            return this;
        };
        PathProxy.prototype.arc = function (cx, cy, r, startAngle, endAngle, anticlockwise) {
            this._drawPendingPt();
            tmpAngles[0] = startAngle;
            tmpAngles[1] = endAngle;
            normalizeArcAngles(tmpAngles, anticlockwise);
            startAngle = tmpAngles[0];
            endAngle = tmpAngles[1];
            var delta = endAngle - startAngle;
            this.addData(CMD.A, cx, cy, r, r, startAngle, delta, 0, anticlockwise ? 0 : 1);
            this._ctx && this._ctx.arc(cx, cy, r, startAngle, endAngle, anticlockwise);
            this._xi = mathCos$1(endAngle) * r + cx;
            this._yi = mathSin$1(endAngle) * r + cy;
            return this;
        };
        PathProxy.prototype.arcTo = function (x1, y1, x2, y2, radius) {
            this._drawPendingPt();
            if (this._ctx) {
                this._ctx.arcTo(x1, y1, x2, y2, radius);
            }
            return this;
        };
        PathProxy.prototype.rect = function (x, y, w, h) {
            this._drawPendingPt();
            this._ctx && this._ctx.rect(x, y, w, h);
            this.addData(CMD.R, x, y, w, h);
            return this;
        };
        PathProxy.prototype.closePath = function () {
            this._drawPendingPt();
            this.addData(CMD.Z);
            var ctx = this._ctx;
            var x0 = this._x0;
            var y0 = this._y0;
            if (ctx) {
                ctx.closePath();
            }
            this._xi = x0;
            this._yi = y0;
            return this;
        };
        PathProxy.prototype.fill = function (ctx) {
            ctx && ctx.fill();
            this.toStatic();
        };
        PathProxy.prototype.stroke = function (ctx) {
            ctx && ctx.stroke();
            this.toStatic();
        };
        PathProxy.prototype.len = function () {
            return this._len;
        };
        PathProxy.prototype.setData = function (data) {
            var len = data.length;
            if (!(this.data && this.data.length === len) && hasTypedArray) {
                this.data = new Float32Array(len);
            }
            for (var i = 0; i < len; i++) {
                this.data[i] = data[i];
            }
            this._len = len;
        };
        PathProxy.prototype.appendPath = function (path) {
            if (!(path instanceof Array)) {
                path = [path];
            }
            var len = path.length;
            var appendSize = 0;
            var offset = this._len;
            for (var i = 0; i < len; i++) {
                appendSize += path[i].len();
            }
            if (hasTypedArray && (this.data instanceof Float32Array)) {
                this.data = new Float32Array(offset + appendSize);
            }
            for (var i = 0; i < len; i++) {
                var appendPathData = path[i].data;
                for (var k = 0; k < appendPathData.length; k++) {
                    this.data[offset++] = appendPathData[k];
                }
            }
            this._len = offset;
        };
        PathProxy.prototype.addData = function (cmd, a, b, c, d, e, f, g, h) {
            if (!this._saveData) {
                return;
            }
            var data = this.data;
            if (this._len + arguments.length > data.length) {
                this._expandData();
                data = this.data;
            }
            for (var i = 0; i < arguments.length; i++) {
                data[this._len++] = arguments[i];
            }
        };
        PathProxy.prototype._drawPendingPt = function () {
            if (this._pendingPtDist > 0) {
                this._ctx && this._ctx.lineTo(this._pendingPtX, this._pendingPtY);
                this._pendingPtDist = 0;
            }
        };
        PathProxy.prototype._expandData = function () {
            if (!(this.data instanceof Array)) {
                var newData = [];
                for (var i = 0; i < this._len; i++) {
                    newData[i] = this.data[i];
                }
                this.data = newData;
            }
        };
        PathProxy.prototype.toStatic = function () {
            if (!this._saveData) {
                return;
            }
            this._drawPendingPt();
            var data = this.data;
            if (data instanceof Array) {
                data.length = this._len;
                if (hasTypedArray && this._len > 11) {
                    this.data = new Float32Array(data);
                }
            }
        };
        PathProxy.prototype.getBoundingRect = function () {
            min$1[0] = min$1[1] = min2[0] = min2[1] = Number.MAX_VALUE;
            max$1[0] = max$1[1] = max2[0] = max2[1] = -Number.MAX_VALUE;
            var data = this.data;
            var xi = 0;
            var yi = 0;
            var x0 = 0;
            var y0 = 0;
            var i;
            for (i = 0; i < this._len;) {
                var cmd = data[i++];
                var isFirst = i === 1;
                if (isFirst) {
                    xi = data[i];
                    yi = data[i + 1];
                    x0 = xi;
                    y0 = yi;
                }
                switch (cmd) {
                    case CMD.M:
                        xi = x0 = data[i++];
                        yi = y0 = data[i++];
                        min2[0] = x0;
                        min2[1] = y0;
                        max2[0] = x0;
                        max2[1] = y0;
                        break;
                    case CMD.L:
                        fromLine(xi, yi, data[i], data[i + 1], min2, max2);
                        xi = data[i++];
                        yi = data[i++];
                        break;
                    case CMD.C:
                        fromCubic(xi, yi, data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1], min2, max2);
                        xi = data[i++];
                        yi = data[i++];
                        break;
                    case CMD.Q:
                        fromQuadratic(xi, yi, data[i++], data[i++], data[i], data[i + 1], min2, max2);
                        xi = data[i++];
                        yi = data[i++];
                        break;
                    case CMD.A:
                        var cx = data[i++];
                        var cy = data[i++];
                        var rx = data[i++];
                        var ry = data[i++];
                        var startAngle = data[i++];
                        var endAngle = data[i++] + startAngle;
                        i += 1;
                        var anticlockwise = !data[i++];
                        if (isFirst) {
                            x0 = mathCos$1(startAngle) * rx + cx;
                            y0 = mathSin$1(startAngle) * ry + cy;
                        }
                        fromArc(cx, cy, rx, ry, startAngle, endAngle, anticlockwise, min2, max2);
                        xi = mathCos$1(endAngle) * rx + cx;
                        yi = mathSin$1(endAngle) * ry + cy;
                        break;
                    case CMD.R:
                        x0 = xi = data[i++];
                        y0 = yi = data[i++];
                        var width = data[i++];
                        var height = data[i++];
                        fromLine(x0, y0, x0 + width, y0 + height, min2, max2);
                        break;
                    case CMD.Z:
                        xi = x0;
                        yi = y0;
                        break;
                }
                min(min$1, min$1, min2);
                max(max$1, max$1, max2);
            }
            if (i === 0) {
                min$1[0] = min$1[1] = max$1[0] = max$1[1] = 0;
            }
            return new BoundingRect(min$1[0], min$1[1], max$1[0] - min$1[0], max$1[1] - min$1[1]);
        };
        PathProxy.prototype._calculateLength = function () {
            var data = this.data;
            var len = this._len;
            var ux = this._ux;
            var uy = this._uy;
            var xi = 0;
            var yi = 0;
            var x0 = 0;
            var y0 = 0;
            if (!this._pathSegLen) {
                this._pathSegLen = [];
            }
            var pathSegLen = this._pathSegLen;
            var pathTotalLen = 0;
            var segCount = 0;
            for (var i = 0; i < len;) {
                var cmd = data[i++];
                var isFirst = i === 1;
                if (isFirst) {
                    xi = data[i];
                    yi = data[i + 1];
                    x0 = xi;
                    y0 = yi;
                }
                var l = -1;
                switch (cmd) {
                    case CMD.M:
                        xi = x0 = data[i++];
                        yi = y0 = data[i++];
                        break;
                    case CMD.L: {
                        var x2 = data[i++];
                        var y2 = data[i++];
                        var dx = x2 - xi;
                        var dy = y2 - yi;
                        if (mathAbs(dx) > ux || mathAbs(dy) > uy || i === len - 1) {
                            l = Math.sqrt(dx * dx + dy * dy);
                            xi = x2;
                            yi = y2;
                        }
                        break;
                    }
                    case CMD.C: {
                        var x1 = data[i++];
                        var y1 = data[i++];
                        var x2 = data[i++];
                        var y2 = data[i++];
                        var x3 = data[i++];
                        var y3 = data[i++];
                        l = cubicLength(xi, yi, x1, y1, x2, y2, x3, y3, 10);
                        xi = x3;
                        yi = y3;
                        break;
                    }
                    case CMD.Q: {
                        var x1 = data[i++];
                        var y1 = data[i++];
                        var x2 = data[i++];
                        var y2 = data[i++];
                        l = quadraticLength(xi, yi, x1, y1, x2, y2, 10);
                        xi = x2;
                        yi = y2;
                        break;
                    }
                    case CMD.A:
                        var cx = data[i++];
                        var cy = data[i++];
                        var rx = data[i++];
                        var ry = data[i++];
                        var startAngle = data[i++];
                        var delta = data[i++];
                        var endAngle = delta + startAngle;
                        i += 1;
                        var anticlockwise = !data[i++];
                        if (isFirst) {
                            x0 = mathCos$1(startAngle) * rx + cx;
                            y0 = mathSin$1(startAngle) * ry + cy;
                        }
                        l = mathMax$2(rx, ry) * mathMin$2(PI2$1, Math.abs(delta));
                        xi = mathCos$1(endAngle) * rx + cx;
                        yi = mathSin$1(endAngle) * ry + cy;
                        break;
                    case CMD.R: {
                        x0 = xi = data[i++];
                        y0 = yi = data[i++];
                        var width = data[i++];
                        var height = data[i++];
                        l = width * 2 + height * 2;
                        break;
                    }
                    case CMD.Z: {
                        var dx = x0 - xi;
                        var dy = y0 - yi;
                        l = Math.sqrt(dx * dx + dy * dy);
                        xi = x0;
                        yi = y0;
                        break;
                    }
                }
                if (l >= 0) {
                    pathSegLen[segCount++] = l;
                    pathTotalLen += l;
                }
            }
            this._pathLen = pathTotalLen;
            return pathTotalLen;
        };
        PathProxy.prototype.rebuildPath = function (ctx, percent) {
            var d = this.data;
            var ux = this._ux;
            var uy = this._uy;
            var len = this._len;
            var x0;
            var y0;
            var xi;
            var yi;
            var x;
            var y;
            var drawPart = percent < 1;
            var pathSegLen;
            var pathTotalLen;
            var accumLength = 0;
            var segCount = 0;
            var displayedLength;
            var pendingPtDist = 0;
            var pendingPtX;
            var pendingPtY;
            if (drawPart) {
                if (!this._pathSegLen) {
                    this._calculateLength();
                }
                pathSegLen = this._pathSegLen;
                pathTotalLen = this._pathLen;
                displayedLength = percent * pathTotalLen;
                if (!displayedLength) {
                    return;
                }
            }
            lo: for (var i = 0; i < len;) {
                var cmd = d[i++];
                var isFirst = i === 1;
                if (isFirst) {
                    xi = d[i];
                    yi = d[i + 1];
                    x0 = xi;
                    y0 = yi;
                }
                if (cmd !== CMD.L && pendingPtDist > 0) {
                    ctx.lineTo(pendingPtX, pendingPtY);
                    pendingPtDist = 0;
                }
                switch (cmd) {
                    case CMD.M:
                        x0 = xi = d[i++];
                        y0 = yi = d[i++];
                        ctx.moveTo(xi, yi);
                        break;
                    case CMD.L: {
                        x = d[i++];
                        y = d[i++];
                        var dx = mathAbs(x - xi);
                        var dy = mathAbs(y - yi);
                        if (dx > ux || dy > uy) {
                            if (drawPart) {
                                var l = pathSegLen[segCount++];
                                if (accumLength + l > displayedLength) {
                                    var t = (displayedLength - accumLength) / l;
                                    ctx.lineTo(xi * (1 - t) + x * t, yi * (1 - t) + y * t);
                                    break lo;
                                }
                                accumLength += l;
                            }
                            ctx.lineTo(x, y);
                            xi = x;
                            yi = y;
                            pendingPtDist = 0;
                        }
                        else {
                            var d2 = dx * dx + dy * dy;
                            if (d2 > pendingPtDist) {
                                pendingPtX = x;
                                pendingPtY = y;
                                pendingPtDist = d2;
                            }
                        }
                        break;
                    }
                    case CMD.C: {
                        var x1 = d[i++];
                        var y1 = d[i++];
                        var x2 = d[i++];
                        var y2 = d[i++];
                        var x3 = d[i++];
                        var y3 = d[i++];
                        if (drawPart) {
                            var l = pathSegLen[segCount++];
                            if (accumLength + l > displayedLength) {
                                var t = (displayedLength - accumLength) / l;
                                cubicSubdivide(xi, x1, x2, x3, t, tmpOutX);
                                cubicSubdivide(yi, y1, y2, y3, t, tmpOutY);
                                ctx.bezierCurveTo(tmpOutX[1], tmpOutY[1], tmpOutX[2], tmpOutY[2], tmpOutX[3], tmpOutY[3]);
                                break lo;
                            }
                            accumLength += l;
                        }
                        ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3);
                        xi = x3;
                        yi = y3;
                        break;
                    }
                    case CMD.Q: {
                        var x1 = d[i++];
                        var y1 = d[i++];
                        var x2 = d[i++];
                        var y2 = d[i++];
                        if (drawPart) {
                            var l = pathSegLen[segCount++];
                            if (accumLength + l > displayedLength) {
                                var t = (displayedLength - accumLength) / l;
                                quadraticSubdivide(xi, x1, x2, t, tmpOutX);
                                quadraticSubdivide(yi, y1, y2, t, tmpOutY);
                                ctx.quadraticCurveTo(tmpOutX[1], tmpOutY[1], tmpOutX[2], tmpOutY[2]);
                                break lo;
                            }
                            accumLength += l;
                        }
                        ctx.quadraticCurveTo(x1, y1, x2, y2);
                        xi = x2;
                        yi = y2;
                        break;
                    }
                    case CMD.A:
                        var cx = d[i++];
                        var cy = d[i++];
                        var rx = d[i++];
                        var ry = d[i++];
                        var startAngle = d[i++];
                        var delta = d[i++];
                        var psi = d[i++];
                        var anticlockwise = !d[i++];
                        var r = (rx > ry) ? rx : ry;
                        var isEllipse = mathAbs(rx - ry) > 1e-3;
                        var endAngle = startAngle + delta;
                        var breakBuild = false;
                        if (drawPart) {
                            var l = pathSegLen[segCount++];
                            if (accumLength + l > displayedLength) {
                                endAngle = startAngle + delta * (displayedLength - accumLength) / l;
                                breakBuild = true;
                            }
                            accumLength += l;
                        }
                        if (isEllipse && ctx.ellipse) {
                            ctx.ellipse(cx, cy, rx, ry, psi, startAngle, endAngle, anticlockwise);
                        }
                        else {
                            ctx.arc(cx, cy, r, startAngle, endAngle, anticlockwise);
                        }
                        if (breakBuild) {
                            break lo;
                        }
                        if (isFirst) {
                            x0 = mathCos$1(startAngle) * rx + cx;
                            y0 = mathSin$1(startAngle) * ry + cy;
                        }
                        xi = mathCos$1(endAngle) * rx + cx;
                        yi = mathSin$1(endAngle) * ry + cy;
                        break;
                    case CMD.R:
                        x0 = xi = d[i];
                        y0 = yi = d[i + 1];
                        x = d[i++];
                        y = d[i++];
                        var width = d[i++];
                        var height = d[i++];
                        if (drawPart) {
                            var l = pathSegLen[segCount++];
                            if (accumLength + l > displayedLength) {
                                var d_1 = displayedLength - accumLength;
                                ctx.moveTo(x, y);
                                ctx.lineTo(x + mathMin$2(d_1, width), y);
                                d_1 -= width;
                                if (d_1 > 0) {
                                    ctx.lineTo(x + width, y + mathMin$2(d_1, height));
                                }
                                d_1 -= height;
                                if (d_1 > 0) {
                                    ctx.lineTo(x + mathMax$2(width - d_1, 0), y + height);
                                }
                                d_1 -= width;
                                if (d_1 > 0) {
                                    ctx.lineTo(x, y + mathMax$2(height - d_1, 0));
                                }
                                break lo;
                            }
                            accumLength += l;
                        }
                        ctx.rect(x, y, width, height);
                        break;
                    case CMD.Z:
                        if (drawPart) {
                            var l = pathSegLen[segCount++];
                            if (accumLength + l > displayedLength) {
                                var t = (displayedLength - accumLength) / l;
                                ctx.lineTo(xi * (1 - t) + x0 * t, yi * (1 - t) + y0 * t);
                                break lo;
                            }
                            accumLength += l;
                        }
                        ctx.closePath();
                        xi = x0;
                        yi = y0;
                }
            }
        };
        PathProxy.prototype.clone = function () {
            var newProxy = new PathProxy();
            var data = this.data;
            newProxy.data = data.slice ? data.slice()
                : Array.prototype.slice.call(data);
            newProxy._len = this._len;
            return newProxy;
        };
        PathProxy.CMD = CMD;
        PathProxy.initDefaultProps = (function () {
            var proto = PathProxy.prototype;
            proto._saveData = true;
            proto._ux = 0;
            proto._uy = 0;
            proto._pendingPtDist = 0;
            proto._version = 0;
        })();
        return PathProxy;
    }());

    function containStroke(x0, y0, x1, y1, lineWidth, x, y) {
        if (lineWidth === 0) {
            return false;
        }
        var _l = lineWidth;
        var _a = 0;
        var _b = x0;
        if ((y > y0 + _l && y > y1 + _l)
            || (y < y0 - _l && y < y1 - _l)
            || (x > x0 + _l && x > x1 + _l)
            || (x < x0 - _l && x < x1 - _l)) {
            return false;
        }
        if (x0 !== x1) {
            _a = (y0 - y1) / (x0 - x1);
            _b = (x0 * y1 - x1 * y0) / (x0 - x1);
        }
        else {
            return Math.abs(x - x0) <= _l / 2;
        }
        var tmp = _a * x - y + _b;
        var _s = tmp * tmp / (_a * _a + 1);
        return _s <= _l / 2 * _l / 2;
    }

    function containStroke$1(x0, y0, x1, y1, x2, y2, x3, y3, lineWidth, x, y) {
        if (lineWidth === 0) {
            return false;
        }
        var _l = lineWidth;
        if ((y > y0 + _l && y > y1 + _l && y > y2 + _l && y > y3 + _l)
            || (y < y0 - _l && y < y1 - _l && y < y2 - _l && y < y3 - _l)
            || (x > x0 + _l && x > x1 + _l && x > x2 + _l && x > x3 + _l)
            || (x < x0 - _l && x < x1 - _l && x < x2 - _l && x < x3 - _l)) {
            return false;
        }
        var d = cubicProjectPoint(x0, y0, x1, y1, x2, y2, x3, y3, x, y, null);
        return d <= _l / 2;
    }

    function containStroke$2(x0, y0, x1, y1, x2, y2, lineWidth, x, y) {
        if (lineWidth === 0) {
            return false;
        }
        var _l = lineWidth;
        if ((y > y0 + _l && y > y1 + _l && y > y2 + _l)
            || (y < y0 - _l && y < y1 - _l && y < y2 - _l)
            || (x > x0 + _l && x > x1 + _l && x > x2 + _l)
            || (x < x0 - _l && x < x1 - _l && x < x2 - _l)) {
            return false;
        }
        var d = quadraticProjectPoint(x0, y0, x1, y1, x2, y2, x, y, null);
        return d <= _l / 2;
    }

    var PI2$2 = Math.PI * 2;
    function normalizeRadian(angle) {
        angle %= PI2$2;
        if (angle < 0) {
            angle += PI2$2;
        }
        return angle;
    }

    var PI2$3 = Math.PI * 2;
    function containStroke$3(cx, cy, r, startAngle, endAngle, anticlockwise, lineWidth, x, y) {
        if (lineWidth === 0) {
            return false;
        }
        var _l = lineWidth;
        x -= cx;
        y -= cy;
        var d = Math.sqrt(x * x + y * y);
        if ((d - _l > r) || (d + _l < r)) {
            return false;
        }
        if (Math.abs(startAngle - endAngle) % PI2$3 < 1e-4) {
            return true;
        }
        if (anticlockwise) {
            var tmp = startAngle;
            startAngle = normalizeRadian(endAngle);
            endAngle = normalizeRadian(tmp);
        }
        else {
            startAngle = normalizeRadian(startAngle);
            endAngle = normalizeRadian(endAngle);
        }
        if (startAngle > endAngle) {
            endAngle += PI2$3;
        }
        var angle = Math.atan2(y, x);
        if (angle < 0) {
            angle += PI2$3;
        }
        return (angle >= startAngle && angle <= endAngle)
            || (angle + PI2$3 >= startAngle && angle + PI2$3 <= endAngle);
    }

    function windingLine(x0, y0, x1, y1, x, y) {
        if ((y > y0 && y > y1) || (y < y0 && y < y1)) {
            return 0;
        }
        if (y1 === y0) {
            return 0;
        }
        var t = (y - y0) / (y1 - y0);
        var dir = y1 < y0 ? 1 : -1;
        if (t === 1 || t === 0) {
            dir = y1 < y0 ? 0.5 : -0.5;
        }
        var x_ = t * (x1 - x0) + x0;
        return x_ === x ? Infinity : x_ > x ? dir : 0;
    }

    var CMD$1 = PathProxy.CMD;
    var PI2$4 = Math.PI * 2;
    var EPSILON$2 = 1e-4;
    function isAroundEqual(a, b) {
        return Math.abs(a - b) < EPSILON$2;
    }
    var roots = [-1, -1, -1];
    var extrema = [-1, -1];
    function swapExtrema() {
        var tmp = extrema[0];
        extrema[0] = extrema[1];
        extrema[1] = tmp;
    }
    function windingCubic(x0, y0, x1, y1, x2, y2, x3, y3, x, y) {
        if ((y > y0 && y > y1 && y > y2 && y > y3)
            || (y < y0 && y < y1 && y < y2 && y < y3)) {
            return 0;
        }
        var nRoots = cubicRootAt(y0, y1, y2, y3, y, roots);
        if (nRoots === 0) {
            return 0;
        }
        else {
            var w = 0;
            var nExtrema = -1;
            var y0_ = void 0;
            var y1_ = void 0;
            for (var i = 0; i < nRoots; i++) {
                var t = roots[i];
                var unit = (t === 0 || t === 1) ? 0.5 : 1;
                var x_ = cubicAt(x0, x1, x2, x3, t);
                if (x_ < x) {
                    continue;
                }
                if (nExtrema < 0) {
                    nExtrema = cubicExtrema(y0, y1, y2, y3, extrema);
                    if (extrema[1] < extrema[0] && nExtrema > 1) {
                        swapExtrema();
                    }
                    y0_ = cubicAt(y0, y1, y2, y3, extrema[0]);
                    if (nExtrema > 1) {
                        y1_ = cubicAt(y0, y1, y2, y3, extrema[1]);
                    }
                }
                if (nExtrema === 2) {
                    if (t < extrema[0]) {
                        w += y0_ < y0 ? unit : -unit;
                    }
                    else if (t < extrema[1]) {
                        w += y1_ < y0_ ? unit : -unit;
                    }
                    else {
                        w += y3 < y1_ ? unit : -unit;
                    }
                }
                else {
                    if (t < extrema[0]) {
                        w += y0_ < y0 ? unit : -unit;
                    }
                    else {
                        w += y3 < y0_ ? unit : -unit;
                    }
                }
            }
            return w;
        }
    }
    function windingQuadratic(x0, y0, x1, y1, x2, y2, x, y) {
        if ((y > y0 && y > y1 && y > y2)
            || (y < y0 && y < y1 && y < y2)) {
            return 0;
        }
        var nRoots = quadraticRootAt(y0, y1, y2, y, roots);
        if (nRoots === 0) {
            return 0;
        }
        else {
            var t = quadraticExtremum(y0, y1, y2);
            if (t >= 0 && t <= 1) {
                var w = 0;
                var y_ = quadraticAt(y0, y1, y2, t);
                for (var i = 0; i < nRoots; i++) {
                    var unit = (roots[i] === 0 || roots[i] === 1) ? 0.5 : 1;
                    var x_ = quadraticAt(x0, x1, x2, roots[i]);
                    if (x_ < x) {
                        continue;
                    }
                    if (roots[i] < t) {
                        w += y_ < y0 ? unit : -unit;
                    }
                    else {
                        w += y2 < y_ ? unit : -unit;
                    }
                }
                return w;
            }
            else {
                var unit = (roots[0] === 0 || roots[0] === 1) ? 0.5 : 1;
                var x_ = quadraticAt(x0, x1, x2, roots[0]);
                if (x_ < x) {
                    return 0;
                }
                return y2 < y0 ? unit : -unit;
            }
        }
    }
    function windingArc(cx, cy, r, startAngle, endAngle, anticlockwise, x, y) {
        y -= cy;
        if (y > r || y < -r) {
            return 0;
        }
        var tmp = Math.sqrt(r * r - y * y);
        roots[0] = -tmp;
        roots[1] = tmp;
        var dTheta = Math.abs(startAngle - endAngle);
        if (dTheta < 1e-4) {
            return 0;
        }
        if (dTheta >= PI2$4 - 1e-4) {
            startAngle = 0;
            endAngle = PI2$4;
            var dir = anticlockwise ? 1 : -1;
            if (x >= roots[0] + cx && x <= roots[1] + cx) {
                return dir;
            }
            else {
                return 0;
            }
        }
        if (startAngle > endAngle) {
            var tmp_1 = startAngle;
            startAngle = endAngle;
            endAngle = tmp_1;
        }
        if (startAngle < 0) {
            startAngle += PI2$4;
            endAngle += PI2$4;
        }
        var w = 0;
        for (var i = 0; i < 2; i++) {
            var x_ = roots[i];
            if (x_ + cx > x) {
                var angle = Math.atan2(y, x_);
                var dir = anticlockwise ? 1 : -1;
                if (angle < 0) {
                    angle = PI2$4 + angle;
                }
                if ((angle >= startAngle && angle <= endAngle)
                    || (angle + PI2$4 >= startAngle && angle + PI2$4 <= endAngle)) {
                    if (angle > Math.PI / 2 && angle < Math.PI * 1.5) {
                        dir = -dir;
                    }
                    w += dir;
                }
            }
        }
        return w;
    }
    function containPath(path, lineWidth, isStroke, x, y) {
        var data = path.data;
        var len = path.len();
        var w = 0;
        var xi = 0;
        var yi = 0;
        var x0 = 0;
        var y0 = 0;
        var x1;
        var y1;
        for (var i = 0; i < len;) {
            var cmd = data[i++];
            var isFirst = i === 1;
            if (cmd === CMD$1.M && i > 1) {
                if (!isStroke) {
                    w += windingLine(xi, yi, x0, y0, x, y);
                }
            }
            if (isFirst) {
                xi = data[i];
                yi = data[i + 1];
                x0 = xi;
                y0 = yi;
            }
            switch (cmd) {
                case CMD$1.M:
                    x0 = data[i++];
                    y0 = data[i++];
                    xi = x0;
                    yi = y0;
                    break;
                case CMD$1.L:
                    if (isStroke) {
                        if (containStroke(xi, yi, data[i], data[i + 1], lineWidth, x, y)) {
                            return true;
                        }
                    }
                    else {
                        w += windingLine(xi, yi, data[i], data[i + 1], x, y) || 0;
                    }
                    xi = data[i++];
                    yi = data[i++];
                    break;
                case CMD$1.C:
                    if (isStroke) {
                        if (containStroke$1(xi, yi, data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1], lineWidth, x, y)) {
                            return true;
                        }
                    }
                    else {
                        w += windingCubic(xi, yi, data[i++], data[i++], data[i++], data[i++], data[i], data[i + 1], x, y) || 0;
                    }
                    xi = data[i++];
                    yi = data[i++];
                    break;
                case CMD$1.Q:
                    if (isStroke) {
                        if (containStroke$2(xi, yi, data[i++], data[i++], data[i], data[i + 1], lineWidth, x, y)) {
                            return true;
                        }
                    }
                    else {
                        w += windingQuadratic(xi, yi, data[i++], data[i++], data[i], data[i + 1], x, y) || 0;
                    }
                    xi = data[i++];
                    yi = data[i++];
                    break;
                case CMD$1.A:
                    var cx = data[i++];
                    var cy = data[i++];
                    var rx = data[i++];
                    var ry = data[i++];
                    var theta = data[i++];
                    var dTheta = data[i++];
                    i += 1;
                    var anticlockwise = !!(1 - data[i++]);
                    x1 = Math.cos(theta) * rx + cx;
                    y1 = Math.sin(theta) * ry + cy;
                    if (!isFirst) {
                        w += windingLine(xi, yi, x1, y1, x, y);
                    }
                    else {
                        x0 = x1;
                        y0 = y1;
                    }
                    var _x = (x - cx) * ry / rx + cx;
                    if (isStroke) {
                        if (containStroke$3(cx, cy, ry, theta, theta + dTheta, anticlockwise, lineWidth, _x, y)) {
                            return true;
                        }
                    }
                    else {
                        w += windingArc(cx, cy, ry, theta, theta + dTheta, anticlockwise, _x, y);
                    }
                    xi = Math.cos(theta + dTheta) * rx + cx;
                    yi = Math.sin(theta + dTheta) * ry + cy;
                    break;
                case CMD$1.R:
                    x0 = xi = data[i++];
                    y0 = yi = data[i++];
                    var width = data[i++];
                    var height = data[i++];
                    x1 = x0 + width;
                    y1 = y0 + height;
                    if (isStroke) {
                        if (containStroke(x0, y0, x1, y0, lineWidth, x, y)
                            || containStroke(x1, y0, x1, y1, lineWidth, x, y)
                            || containStroke(x1, y1, x0, y1, lineWidth, x, y)
                            || containStroke(x0, y1, x0, y0, lineWidth, x, y)) {
                            return true;
                        }
                    }
                    else {
                        w += windingLine(x1, y0, x1, y1, x, y);
                        w += windingLine(x0, y1, x0, y0, x, y);
                    }
                    break;
                case CMD$1.Z:
                    if (isStroke) {
                        if (containStroke(xi, yi, x0, y0, lineWidth, x, y)) {
                            return true;
                        }
                    }
                    else {
                        w += windingLine(xi, yi, x0, y0, x, y);
                    }
                    xi = x0;
                    yi = y0;
                    break;
            }
        }
        if (!isStroke && !isAroundEqual(yi, y0)) {
            w += windingLine(xi, yi, x0, y0, x, y) || 0;
        }
        return w !== 0;
    }
    function contain(pathProxy, x, y) {
        return containPath(pathProxy, 0, false, x, y);
    }
    function containStroke$4(pathProxy, lineWidth, x, y) {
        return containPath(pathProxy, lineWidth, true, x, y);
    }

    var DEFAULT_PATH_STYLE = defaults({
        fill: '#000',
        stroke: null,
        strokePercent: 1,
        fillOpacity: 1,
        strokeOpacity: 1,
        lineDashOffset: 0,
        lineWidth: 1,
        lineCap: 'butt',
        miterLimit: 10,
        strokeNoScale: false,
        strokeFirst: false
    }, DEFAULT_COMMON_STYLE);
    var DEFAULT_PATH_ANIMATION_PROPS = {
        style: defaults({
            fill: true,
            stroke: true,
            strokePercent: true,
            fillOpacity: true,
            strokeOpacity: true,
            lineDashOffset: true,
            lineWidth: true,
            miterLimit: true
        }, DEFAULT_COMMON_ANIMATION_PROPS.style)
    };
    var pathCopyParams = TRANSFORMABLE_PROPS.concat(['invisible',
        'culling', 'z', 'z2', 'zlevel', 'parent'
    ]);
    var Path = (function (_super) {
        __extends(Path, _super);
        function Path(opts) {
            return _super.call(this, opts) || this;
        }
        Path.prototype.update = function () {
            var _this = this;
            _super.prototype.update.call(this);
            var style = this.style;
            if (style.decal) {
                var decalEl = this._decalEl = this._decalEl || new Path();
                if (decalEl.buildPath === Path.prototype.buildPath) {
                    decalEl.buildPath = function (ctx) {
                        _this.buildPath(ctx, _this.shape);
                    };
                }
                decalEl.silent = true;
                var decalElStyle = decalEl.style;
                for (var key in style) {
                    if (decalElStyle[key] !== style[key]) {
                        decalElStyle[key] = style[key];
                    }
                }
                decalElStyle.fill = style.fill ? style.decal : null;
                decalElStyle.decal = null;
                decalElStyle.shadowColor = null;
                style.strokeFirst && (decalElStyle.stroke = null);
                for (var i = 0; i < pathCopyParams.length; ++i) {
                    decalEl[pathCopyParams[i]] = this[pathCopyParams[i]];
                }
                decalEl.__dirty |= REDRAW_BIT;
            }
            else if (this._decalEl) {
                this._decalEl = null;
            }
        };
        Path.prototype.getDecalElement = function () {
            return this._decalEl;
        };
        Path.prototype._init = function (props) {
            var keysArr = keys(props);
            this.shape = this.getDefaultShape();
            var defaultStyle = this.getDefaultStyle();
            if (defaultStyle) {
                this.useStyle(defaultStyle);
            }
            for (var i = 0; i < keysArr.length; i++) {
                var key = keysArr[i];
                var value = props[key];
                if (key === 'style') {
                    if (!this.style) {
                        this.useStyle(value);
                    }
                    else {
                        extend(this.style, value);
                    }
                }
                else if (key === 'shape') {
                    extend(this.shape, value);
                }
                else {
                    _super.prototype.attrKV.call(this, key, value);
                }
            }
            if (!this.style) {
                this.useStyle({});
            }
        };
        Path.prototype.getDefaultStyle = function () {
            return null;
        };
        Path.prototype.getDefaultShape = function () {
            return {};
        };
        Path.prototype.canBeInsideText = function () {
            return this.hasFill();
        };
        Path.prototype.getInsideTextFill = function () {
            var pathFill = this.style.fill;
            if (pathFill !== 'none') {
                if (isString(pathFill)) {
                    var fillLum = lum(pathFill, 0);
                    if (fillLum > 0.5) {
                        return DARK_LABEL_COLOR;
                    }
                    else if (fillLum > 0.2) {
                        return LIGHTER_LABEL_COLOR;
                    }
                    return LIGHT_LABEL_COLOR;
                }
                else if (pathFill) {
                    return LIGHT_LABEL_COLOR;
                }
            }
            return DARK_LABEL_COLOR;
        };
        Path.prototype.getInsideTextStroke = function (textFill) {
            var pathFill = this.style.fill;
            if (isString(pathFill)) {
                var zr = this.__zr;
                var isDarkMode = !!(zr && zr.isDarkMode());
                var isDarkLabel = lum(textFill, 0) < DARK_MODE_THRESHOLD;
                if (isDarkMode === isDarkLabel) {
                    return pathFill;
                }
            }
        };
        Path.prototype.buildPath = function (ctx, shapeCfg, inBatch) { };
        Path.prototype.pathUpdated = function () {
            this.__dirty &= ~SHAPE_CHANGED_BIT;
        };
        Path.prototype.getUpdatedPathProxy = function (inBatch) {
            !this.path && this.createPathProxy();
            this.path.beginPath();
            this.buildPath(this.path, this.shape, inBatch);
            return this.path;
        };
        Path.prototype.createPathProxy = function () {
            this.path = new PathProxy(false);
        };
        Path.prototype.hasStroke = function () {
            var style = this.style;
            var stroke = style.stroke;
            return !(stroke == null || stroke === 'none' || !(style.lineWidth > 0));
        };
        Path.prototype.hasFill = function () {
            var style = this.style;
            var fill = style.fill;
            return fill != null && fill !== 'none';
        };
        Path.prototype.getBoundingRect = function () {
            var rect = this._rect;
            var style = this.style;
            var needsUpdateRect = !rect;
            if (needsUpdateRect) {
                var firstInvoke = false;
                if (!this.path) {
                    firstInvoke = true;
                    this.createPathProxy();
                }
                var path = this.path;
                if (firstInvoke || (this.__dirty & SHAPE_CHANGED_BIT)) {
                    path.beginPath();
                    this.buildPath(path, this.shape, false);
                    this.pathUpdated();
                }
                rect = path.getBoundingRect();
            }
            this._rect = rect;
            if (this.hasStroke() && this.path && this.path.len() > 0) {
                var rectStroke = this._rectStroke || (this._rectStroke = rect.clone());
                if (this.__dirty || needsUpdateRect) {
                    rectStroke.copy(rect);
                    var lineScale = style.strokeNoScale ? this.getLineScale() : 1;
                    var w = style.lineWidth;
                    if (!this.hasFill()) {
                        var strokeContainThreshold = this.strokeContainThreshold;
                        w = Math.max(w, strokeContainThreshold == null ? 4 : strokeContainThreshold);
                    }
                    if (lineScale > 1e-10) {
                        rectStroke.width += w / lineScale;
                        rectStroke.height += w / lineScale;
                        rectStroke.x -= w / lineScale / 2;
                        rectStroke.y -= w / lineScale / 2;
                    }
                }
                return rectStroke;
            }
            return rect;
        };
        Path.prototype.contain = function (x, y) {
            var localPos = this.transformCoordToLocal(x, y);
            var rect = this.getBoundingRect();
            var style = this.style;
            x = localPos[0];
            y = localPos[1];
            if (rect.contain(x, y)) {
                var pathProxy = this.path;
                if (this.hasStroke()) {
                    var lineWidth = style.lineWidth;
                    var lineScale = style.strokeNoScale ? this.getLineScale() : 1;
                    if (lineScale > 1e-10) {
                        if (!this.hasFill()) {
                            lineWidth = Math.max(lineWidth, this.strokeContainThreshold);
                        }
                        if (containStroke$4(pathProxy, lineWidth / lineScale, x, y)) {
                            return true;
                        }
                    }
                }
                if (this.hasFill()) {
                    return contain(pathProxy, x, y);
                }
            }
            return false;
        };
        Path.prototype.dirtyShape = function () {
            this.__dirty |= SHAPE_CHANGED_BIT;
            if (this._rect) {
                this._rect = null;
            }
            if (this._decalEl) {
                this._decalEl.dirtyShape();
            }
            this.markRedraw();
        };
        Path.prototype.dirty = function () {
            this.dirtyStyle();
            this.dirtyShape();
        };
        Path.prototype.animateShape = function (loop) {
            return this.animate('shape', loop);
        };
        Path.prototype.updateDuringAnimation = function (targetKey) {
            if (targetKey === 'style') {
                this.dirtyStyle();
            }
            else if (targetKey === 'shape') {
                this.dirtyShape();
            }
            else {
                this.markRedraw();
            }
        };
        Path.prototype.attrKV = function (key, value) {
            if (key === 'shape') {
                this.setShape(value);
            }
            else {
                _super.prototype.attrKV.call(this, key, value);
            }
        };
        Path.prototype.setShape = function (keyOrObj, value) {
            var shape = this.shape;
            if (!shape) {
                shape = this.shape = {};
            }
            if (typeof keyOrObj === 'string') {
                shape[keyOrObj] = value;
            }
            else {
                extend(shape, keyOrObj);
            }
            this.dirtyShape();
            return this;
        };
        Path.prototype.shapeChanged = function () {
            return !!(this.__dirty & SHAPE_CHANGED_BIT);
        };
        Path.prototype.createStyle = function (obj) {
            return createObject(DEFAULT_PATH_STYLE, obj);
        };
        Path.prototype._innerSaveToNormal = function (toState) {
            _super.prototype._innerSaveToNormal.call(this, toState);
            var normalState = this._normalState;
            if (toState.shape && !normalState.shape) {
                normalState.shape = extend({}, this.shape);
            }
        };
        Path.prototype._applyStateObj = function (stateName, state, normalState, keepCurrentStates, transition, animationCfg) {
            _super.prototype._applyStateObj.call(this, stateName, state, normalState, keepCurrentStates, transition, animationCfg);
            var needsRestoreToNormal = !(state && keepCurrentStates);
            var targetShape;
            if (state && state.shape) {
                if (transition) {
                    if (keepCurrentStates) {
                        targetShape = state.shape;
                    }
                    else {
                        targetShape = extend({}, normalState.shape);
                        extend(targetShape, state.shape);
                    }
                }
                else {
                    targetShape = extend({}, keepCurrentStates ? this.shape : normalState.shape);
                    extend(targetShape, state.shape);
                }
            }
            else if (needsRestoreToNormal) {
                targetShape = normalState.shape;
            }
            if (targetShape) {
                if (transition) {
                    this.shape = extend({}, this.shape);
                    var targetShapePrimaryProps = {};
                    var shapeKeys = keys(targetShape);
                    for (var i = 0; i < shapeKeys.length; i++) {
                        var key = shapeKeys[i];
                        if (typeof targetShape[key] === 'object') {
                            this.shape[key] = targetShape[key];
                        }
                        else {
                            targetShapePrimaryProps[key] = targetShape[key];
                        }
                    }
                    this._transitionState(stateName, {
                        shape: targetShapePrimaryProps
                    }, animationCfg);
                }
                else {
                    this.shape = targetShape;
                    this.dirtyShape();
                }
            }
        };
        Path.prototype._mergeStates = function (states) {
            var mergedState = _super.prototype._mergeStates.call(this, states);
            var mergedShape;
            for (var i = 0; i < states.length; i++) {
                var state = states[i];
                if (state.shape) {
                    mergedShape = mergedShape || {};
                    this._mergeStyle(mergedShape, state.shape);
                }
            }
            if (mergedShape) {
                mergedState.shape = mergedShape;
            }
            return mergedState;
        };
        Path.prototype.getAnimationStyleProps = function () {
            return DEFAULT_PATH_ANIMATION_PROPS;
        };
        Path.prototype.isZeroArea = function () {
            return false;
        };
        Path.extend = function (defaultProps) {
            var Sub = (function (_super) {
                __extends(Sub, _super);
                function Sub(opts) {
                    var _this = _super.call(this, opts) || this;
                    defaultProps.init && defaultProps.init.call(_this, opts);
                    return _this;
                }
                Sub.prototype.getDefaultStyle = function () {
                    return clone(defaultProps.style);
                };
                Sub.prototype.getDefaultShape = function () {
                    return clone(defaultProps.shape);
                };
                return Sub;
            }(Path));
            for (var key in defaultProps) {
                if (typeof defaultProps[key] === 'function') {
                    Sub.prototype[key] = defaultProps[key];
                }
            }
            return Sub;
        };
        Path.initDefaultProps = (function () {
            var pathProto = Path.prototype;
            pathProto.type = 'path';
            pathProto.strokeContainThreshold = 5;
            pathProto.segmentIgnoreThreshold = 0;
            pathProto.subPixelOptimize = false;
            pathProto.autoBatch = false;
            pathProto.__dirty = REDRAW_BIT | STYLE_CHANGED_BIT | SHAPE_CHANGED_BIT;
        })();
        return Path;
    }(Displayable));

    var DEFAULT_TSPAN_STYLE = defaults({
        strokeFirst: true,
        font: DEFAULT_FONT,
        x: 0,
        y: 0,
        textAlign: 'left',
        textBaseline: 'top',
        miterLimit: 2
    }, DEFAULT_PATH_STYLE);
    var TSpan = (function (_super) {
        __extends(TSpan, _super);
        function TSpan() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        TSpan.prototype.hasStroke = function () {
            var style = this.style;
            var stroke = style.stroke;
            return stroke != null && stroke !== 'none' && style.lineWidth > 0;
        };
        TSpan.prototype.hasFill = function () {
            var style = this.style;
            var fill = style.fill;
            return fill != null && fill !== 'none';
        };
        TSpan.prototype.createStyle = function (obj) {
            return createObject(DEFAULT_TSPAN_STYLE, obj);
        };
        TSpan.prototype.setBoundingRect = function (rect) {
            this._rect = rect;
        };
        TSpan.prototype.getBoundingRect = function () {
            var style = this.style;
            if (!this._rect) {
                var text = style.text;
                text != null ? (text += '') : (text = '');
                var rect = getBoundingRect(text, style.font, style.textAlign, style.textBaseline);
                rect.x += style.x || 0;
                rect.y += style.y || 0;
                if (this.hasStroke()) {
                    var w = style.lineWidth;
                    rect.x -= w / 2;
                    rect.y -= w / 2;
                    rect.width += w;
                    rect.height += w;
                }
                this._rect = rect;
            }
            return this._rect;
        };
        TSpan.initDefaultProps = (function () {
            var tspanProto = TSpan.prototype;
            tspanProto.dirtyRectTolerance = 10;
        })();
        return TSpan;
    }(Displayable));
    TSpan.prototype.type = 'tspan';

    var DEFAULT_IMAGE_STYLE = defaults({
        x: 0,
        y: 0
    }, DEFAULT_COMMON_STYLE);
    var DEFAULT_IMAGE_ANIMATION_PROPS = {
        style: defaults({
            x: true,
            y: true,
            width: true,
            height: true,
            sx: true,
            sy: true,
            sWidth: true,
            sHeight: true
        }, DEFAULT_COMMON_ANIMATION_PROPS.style)
    };
    function isImageLike(source) {
        return !!(source
            && typeof source !== 'string'
            && source.width && source.height);
    }
    var ZRImage = (function (_super) {
        __extends(ZRImage, _super);
        function ZRImage() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        ZRImage.prototype.createStyle = function (obj) {
            return createObject(DEFAULT_IMAGE_STYLE, obj);
        };
        ZRImage.prototype._getSize = function (dim) {
            var style = this.style;
            var size = style[dim];
            if (size != null) {
                return size;
            }
            var imageSource = isImageLike(style.image)
                ? style.image : this.__image;
            if (!imageSource) {
                return 0;
            }
            var otherDim = dim === 'width' ? 'height' : 'width';
            var otherDimSize = style[otherDim];
            if (otherDimSize == null) {
                return imageSource[dim];
            }
            else {
                return imageSource[dim] / imageSource[otherDim] * otherDimSize;
            }
        };
        ZRImage.prototype.getWidth = function () {
            return this._getSize('width');
        };
        ZRImage.prototype.getHeight = function () {
            return this._getSize('height');
        };
        ZRImage.prototype.getAnimationStyleProps = function () {
            return DEFAULT_IMAGE_ANIMATION_PROPS;
        };
        ZRImage.prototype.getBoundingRect = function () {
            var style = this.style;
            if (!this._rect) {
                this._rect = new BoundingRect(style.x || 0, style.y || 0, this.getWidth(), this.getHeight());
            }
            return this._rect;
        };
        return ZRImage;
    }(Displayable));
    ZRImage.prototype.type = 'image';

    function buildPath(ctx, shape) {
        var x = shape.x;
        var y = shape.y;
        var width = shape.width;
        var height = shape.height;
        var r = shape.r;
        var r1;
        var r2;
        var r3;
        var r4;
        if (width < 0) {
            x = x + width;
            width = -width;
        }
        if (height < 0) {
            y = y + height;
            height = -height;
        }
        if (typeof r === 'number') {
            r1 = r2 = r3 = r4 = r;
        }
        else if (r instanceof Array) {
            if (r.length === 1) {
                r1 = r2 = r3 = r4 = r[0];
            }
            else if (r.length === 2) {
                r1 = r3 = r[0];
                r2 = r4 = r[1];
            }
            else if (r.length === 3) {
                r1 = r[0];
                r2 = r4 = r[1];
                r3 = r[2];
            }
            else {
                r1 = r[0];
                r2 = r[1];
                r3 = r[2];
                r4 = r[3];
            }
        }
        else {
            r1 = r2 = r3 = r4 = 0;
        }
        var total;
        if (r1 + r2 > width) {
            total = r1 + r2;
            r1 *= width / total;
            r2 *= width / total;
        }
        if (r3 + r4 > width) {
            total = r3 + r4;
            r3 *= width / total;
            r4 *= width / total;
        }
        if (r2 + r3 > height) {
            total = r2 + r3;
            r2 *= height / total;
            r3 *= height / total;
        }
        if (r1 + r4 > height) {
            total = r1 + r4;
            r1 *= height / total;
            r4 *= height / total;
        }
        ctx.moveTo(x + r1, y);
        ctx.lineTo(x + width - r2, y);
        r2 !== 0 && ctx.arc(x + width - r2, y + r2, r2, -Math.PI / 2, 0);
        ctx.lineTo(x + width, y + height - r3);
        r3 !== 0 && ctx.arc(x + width - r3, y + height - r3, r3, 0, Math.PI / 2);
        ctx.lineTo(x + r4, y + height);
        r4 !== 0 && ctx.arc(x + r4, y + height - r4, r4, Math.PI / 2, Math.PI);
        ctx.lineTo(x, y + r1);
        r1 !== 0 && ctx.arc(x + r1, y + r1, r1, Math.PI, Math.PI * 1.5);
    }

    var round$1 = Math.round;
    function subPixelOptimizeLine(outputShape, inputShape, style) {
        if (!inputShape) {
            return;
        }
        var x1 = inputShape.x1;
        var x2 = inputShape.x2;
        var y1 = inputShape.y1;
        var y2 = inputShape.y2;
        outputShape.x1 = x1;
        outputShape.x2 = x2;
        outputShape.y1 = y1;
        outputShape.y2 = y2;
        var lineWidth = style && style.lineWidth;
        if (!lineWidth) {
            return outputShape;
        }
        if (round$1(x1 * 2) === round$1(x2 * 2)) {
            outputShape.x1 = outputShape.x2 = subPixelOptimize(x1, lineWidth, true);
        }
        if (round$1(y1 * 2) === round$1(y2 * 2)) {
            outputShape.y1 = outputShape.y2 = subPixelOptimize(y1, lineWidth, true);
        }
        return outputShape;
    }
    function subPixelOptimizeRect(outputShape, inputShape, style) {
        if (!inputShape) {
            return;
        }
        var originX = inputShape.x;
        var originY = inputShape.y;
        var originWidth = inputShape.width;
        var originHeight = inputShape.height;
        outputShape.x = originX;
        outputShape.y = originY;
        outputShape.width = originWidth;
        outputShape.height = originHeight;
        var lineWidth = style && style.lineWidth;
        if (!lineWidth) {
            return outputShape;
        }
        outputShape.x = subPixelOptimize(originX, lineWidth, true);
        outputShape.y = subPixelOptimize(originY, lineWidth, true);
        outputShape.width = Math.max(subPixelOptimize(originX + originWidth, lineWidth, false) - outputShape.x, originWidth === 0 ? 0 : 1);
        outputShape.height = Math.max(subPixelOptimize(originY + originHeight, lineWidth, false) - outputShape.y, originHeight === 0 ? 0 : 1);
        return outputShape;
    }
    function subPixelOptimize(position, lineWidth, positiveOrNegative) {
        if (!lineWidth) {
            return position;
        }
        var doubledPosition = round$1(position * 2);
        return (doubledPosition + round$1(lineWidth)) % 2 === 0
            ? doubledPosition / 2
            : (doubledPosition + (positiveOrNegative ? 1 : -1)) / 2;
    }

    var RectShape = (function () {
        function RectShape() {
            this.x = 0;
            this.y = 0;
            this.width = 0;
            this.height = 0;
        }
        return RectShape;
    }());
    var subPixelOptimizeOutputShape = {};
    var Rect = (function (_super) {
        __extends(Rect, _super);
        function Rect(opts) {
            return _super.call(this, opts) || this;
        }
        Rect.prototype.getDefaultShape = function () {
            return new RectShape();
        };
        Rect.prototype.buildPath = function (ctx, shape) {
            var x;
            var y;
            var width;
            var height;
            if (this.subPixelOptimize) {
                var optimizedShape = subPixelOptimizeRect(subPixelOptimizeOutputShape, shape, this.style);
                x = optimizedShape.x;
                y = optimizedShape.y;
                width = optimizedShape.width;
                height = optimizedShape.height;
                optimizedShape.r = shape.r;
                shape = optimizedShape;
            }
            else {
                x = shape.x;
                y = shape.y;
                width = shape.width;
                height = shape.height;
            }
            if (!shape.r) {
                ctx.rect(x, y, width, height);
            }
            else {
                buildPath(ctx, shape);
            }
        };
        Rect.prototype.isZeroArea = function () {
            return !this.shape.width || !this.shape.height;
        };
        return Rect;
    }(Path));
    Rect.prototype.type = 'rect';

    var DEFAULT_RICH_TEXT_COLOR = {
        fill: '#000'
    };
    var DEFAULT_STROKE_LINE_WIDTH = 2;
    var DEFAULT_TEXT_ANIMATION_PROPS = {
        style: defaults({
            fill: true,
            stroke: true,
            fillOpacity: true,
            strokeOpacity: true,
            lineWidth: true,
            fontSize: true,
            lineHeight: true,
            width: true,
            height: true,
            textShadowColor: true,
            textShadowBlur: true,
            textShadowOffsetX: true,
            textShadowOffsetY: true,
            backgroundColor: true,
            padding: true,
            borderColor: true,
            borderWidth: true,
            borderRadius: true
        }, DEFAULT_COMMON_ANIMATION_PROPS.style)
    };
    var ZRText = (function (_super) {
        __extends(ZRText, _super);
        function ZRText(opts) {
            var _this = _super.call(this) || this;
            _this.type = 'text';
            _this._children = [];
            _this._defaultStyle = DEFAULT_RICH_TEXT_COLOR;
            _this.attr(opts);
            return _this;
        }
        ZRText.prototype.childrenRef = function () {
            return this._children;
        };
        ZRText.prototype.update = function () {
            _super.prototype.update.call(this);
            if (this.styleChanged()) {
                this._updateSubTexts();
            }
            for (var i = 0; i < this._children.length; i++) {
                var child = this._children[i];
                child.zlevel = this.zlevel;
                child.z = this.z;
                child.z2 = this.z2;
                child.culling = this.culling;
                child.cursor = this.cursor;
                child.invisible = this.invisible;
            }
        };
        ZRText.prototype.updateTransform = function () {
            var innerTransformable = this.innerTransformable;
            if (innerTransformable) {
                innerTransformable.updateTransform();
                if (innerTransformable.transform) {
                    this.transform = innerTransformable.transform;
                }
            }
            else {
                _super.prototype.updateTransform.call(this);
            }
        };
        ZRText.prototype.getLocalTransform = function (m) {
            var innerTransformable = this.innerTransformable;
            return innerTransformable
                ? innerTransformable.getLocalTransform(m)
                : _super.prototype.getLocalTransform.call(this, m);
        };
        ZRText.prototype.getComputedTransform = function () {
            if (this.__hostTarget) {
                this.__hostTarget.getComputedTransform();
                this.__hostTarget.updateInnerText(true);
            }
            return _super.prototype.getComputedTransform.call(this);
        };
        ZRText.prototype._updateSubTexts = function () {
            this._childCursor = 0;
            normalizeTextStyle(this.style);
            this.style.rich
                ? this._updateRichTexts()
                : this._updatePlainTexts();
            this._children.length = this._childCursor;
            this.styleUpdated();
        };
        ZRText.prototype.addSelfToZr = function (zr) {
            _super.prototype.addSelfToZr.call(this, zr);
            for (var i = 0; i < this._children.length; i++) {
                this._children[i].__zr = zr;
            }
        };
        ZRText.prototype.removeSelfFromZr = function (zr) {
            _super.prototype.removeSelfFromZr.call(this, zr);
            for (var i = 0; i < this._children.length; i++) {
                this._children[i].__zr = null;
            }
        };
        ZRText.prototype.getBoundingRect = function () {
            if (this.styleChanged()) {
                this._updateSubTexts();
            }
            if (!this._rect) {
                var tmpRect = new BoundingRect(0, 0, 0, 0);
                var children = this._children;
                var tmpMat = [];
                var rect = null;
                for (var i = 0; i < children.length; i++) {
                    var child = children[i];
                    var childRect = child.getBoundingRect();
                    var transform = child.getLocalTransform(tmpMat);
                    if (transform) {
                        tmpRect.copy(childRect);
                        tmpRect.applyTransform(transform);
                        rect = rect || tmpRect.clone();
                        rect.union(tmpRect);
                    }
                    else {
                        rect = rect || childRect.clone();
                        rect.union(childRect);
                    }
                }
                this._rect = rect || tmpRect;
            }
            return this._rect;
        };
        ZRText.prototype.setDefaultTextStyle = function (defaultTextStyle) {
            this._defaultStyle = defaultTextStyle || DEFAULT_RICH_TEXT_COLOR;
        };
        ZRText.prototype.setTextContent = function (textContent) {
            if ("development" !== 'production') {
                throw new Error('Can\'t attach text on another text');
            }
        };
        ZRText.prototype._mergeStyle = function (targetStyle, sourceStyle) {
            if (!sourceStyle) {
                return targetStyle;
            }
            var sourceRich = sourceStyle.rich;
            var targetRich = targetStyle.rich || (sourceRich && {});
            extend(targetStyle, sourceStyle);
            if (sourceRich && targetRich) {
                this._mergeRich(targetRich, sourceRich);
                targetStyle.rich = targetRich;
            }
            else if (targetRich) {
                targetStyle.rich = targetRich;
            }
            return targetStyle;
        };
        ZRText.prototype._mergeRich = function (targetRich, sourceRich) {
            var richNames = keys(sourceRich);
            for (var i = 0; i < richNames.length; i++) {
                var richName = richNames[i];
                targetRich[richName] = targetRich[richName] || {};
                extend(targetRich[richName], sourceRich[richName]);
            }
        };
        ZRText.prototype.getAnimationStyleProps = function () {
            return DEFAULT_TEXT_ANIMATION_PROPS;
        };
        ZRText.prototype._getOrCreateChild = function (Ctor) {
            var child = this._children[this._childCursor];
            if (!child || !(child instanceof Ctor)) {
                child = new Ctor();
            }
            this._children[this._childCursor++] = child;
            child.__zr = this.__zr;
            child.parent = this;
            return child;
        };
        ZRText.prototype._updatePlainTexts = function () {
            var style = this.style;
            var textFont = style.font || DEFAULT_FONT;
            var textPadding = style.padding;
            var text = getStyleText(style);
            var contentBlock = parsePlainText(text, style);
            var needDrawBg = needDrawBackground(style);
            var bgColorDrawn = !!(style.backgroundColor);
            var outerHeight = contentBlock.outerHeight;
            var outerWidth = contentBlock.outerWidth;
            var contentWidth = contentBlock.contentWidth;
            var textLines = contentBlock.lines;
            var lineHeight = contentBlock.lineHeight;
            var defaultStyle = this._defaultStyle;
            var baseX = style.x || 0;
            var baseY = style.y || 0;
            var textAlign = style.align || defaultStyle.align || 'left';
            var verticalAlign = style.verticalAlign || defaultStyle.verticalAlign || 'top';
            var textX = baseX;
            var textY = adjustTextY(baseY, contentBlock.contentHeight, verticalAlign);
            if (needDrawBg || textPadding) {
                var boxX = adjustTextX(baseX, outerWidth, textAlign);
                var boxY = adjustTextY(baseY, outerHeight, verticalAlign);
                needDrawBg && this._renderBackground(style, style, boxX, boxY, outerWidth, outerHeight);
            }
            textY += lineHeight / 2;
            if (textPadding) {
                textX = getTextXForPadding(baseX, textAlign, textPadding);
                if (verticalAlign === 'top') {
                    textY += textPadding[0];
                }
                else if (verticalAlign === 'bottom') {
                    textY -= textPadding[2];
                }
            }
            var defaultLineWidth = 0;
            var useDefaultFill = false;
            var textFill = getFill('fill' in style
                ? style.fill
                : (useDefaultFill = true, defaultStyle.fill));
            var textStroke = getStroke('stroke' in style
                ? style.stroke
                : (!bgColorDrawn
                    && (!defaultStyle.autoStroke || useDefaultFill))
                    ? (defaultLineWidth = DEFAULT_STROKE_LINE_WIDTH, defaultStyle.stroke)
                    : null);
            var hasShadow = style.textShadowBlur > 0;
            var fixedBoundingRect = style.width != null
                && (style.overflow === 'truncate' || style.overflow === 'break' || style.overflow === 'breakAll');
            var calculatedLineHeight = contentBlock.calculatedLineHeight;
            for (var i = 0; i < textLines.length; i++) {
                var el = this._getOrCreateChild(TSpan);
                var subElStyle = el.createStyle();
                el.useStyle(subElStyle);
                subElStyle.text = textLines[i];
                subElStyle.x = textX;
                subElStyle.y = textY;
                if (textAlign) {
                    subElStyle.textAlign = textAlign;
                }
                subElStyle.textBaseline = 'middle';
                subElStyle.opacity = style.opacity;
                subElStyle.strokeFirst = true;
                if (hasShadow) {
                    subElStyle.shadowBlur = style.textShadowBlur || 0;
                    subElStyle.shadowColor = style.textShadowColor || 'transparent';
                    subElStyle.shadowOffsetX = style.textShadowOffsetX || 0;
                    subElStyle.shadowOffsetY = style.textShadowOffsetY || 0;
                }
                subElStyle.stroke = textStroke;
                subElStyle.fill = textFill;
                if (textStroke) {
                    subElStyle.lineWidth = style.lineWidth || defaultLineWidth;
                    subElStyle.lineDash = style.lineDash;
                    subElStyle.lineDashOffset = style.lineDashOffset || 0;
                }
                subElStyle.font = textFont;
                setSeparateFont(subElStyle, style);
                textY += lineHeight;
                if (fixedBoundingRect) {
                    el.setBoundingRect(new BoundingRect(adjustTextX(subElStyle.x, style.width, subElStyle.textAlign), adjustTextY(subElStyle.y, calculatedLineHeight, subElStyle.textBaseline), contentWidth, calculatedLineHeight));
                }
            }
        };
        ZRText.prototype._updateRichTexts = function () {
            var style = this.style;
            var text = getStyleText(style);
            var contentBlock = parseRichText(text, style);
            var contentWidth = contentBlock.width;
            var outerWidth = contentBlock.outerWidth;
            var outerHeight = contentBlock.outerHeight;
            var textPadding = style.padding;
            var baseX = style.x || 0;
            var baseY = style.y || 0;
            var defaultStyle = this._defaultStyle;
            var textAlign = style.align || defaultStyle.align;
            var verticalAlign = style.verticalAlign || defaultStyle.verticalAlign;
            var boxX = adjustTextX(baseX, outerWidth, textAlign);
            var boxY = adjustTextY(baseY, outerHeight, verticalAlign);
            var xLeft = boxX;
            var lineTop = boxY;
            if (textPadding) {
                xLeft += textPadding[3];
                lineTop += textPadding[0];
            }
            var xRight = xLeft + contentWidth;
            if (needDrawBackground(style)) {
                this._renderBackground(style, style, boxX, boxY, outerWidth, outerHeight);
            }
            var bgColorDrawn = !!(style.backgroundColor);
            for (var i = 0; i < contentBlock.lines.length; i++) {
                var line = contentBlock.lines[i];
                var tokens = line.tokens;
                var tokenCount = tokens.length;
                var lineHeight = line.lineHeight;
                var remainedWidth = line.width;
                var leftIndex = 0;
                var lineXLeft = xLeft;
                var lineXRight = xRight;
                var rightIndex = tokenCount - 1;
                var token = void 0;
                while (leftIndex < tokenCount
                    && (token = tokens[leftIndex], !token.align || token.align === 'left')) {
                    this._placeToken(token, style, lineHeight, lineTop, lineXLeft, 'left', bgColorDrawn);
                    remainedWidth -= token.width;
                    lineXLeft += token.width;
                    leftIndex++;
                }
                while (rightIndex >= 0
                    && (token = tokens[rightIndex], token.align === 'right')) {
                    this._placeToken(token, style, lineHeight, lineTop, lineXRight, 'right', bgColorDrawn);
                    remainedWidth -= token.width;
                    lineXRight -= token.width;
                    rightIndex--;
                }
                lineXLeft += (contentWidth - (lineXLeft - xLeft) - (xRight - lineXRight) - remainedWidth) / 2;
                while (leftIndex <= rightIndex) {
                    token = tokens[leftIndex];
                    this._placeToken(token, style, lineHeight, lineTop, lineXLeft + token.width / 2, 'center', bgColorDrawn);
                    lineXLeft += token.width;
                    leftIndex++;
                }
                lineTop += lineHeight;
            }
        };
        ZRText.prototype._placeToken = function (token, style, lineHeight, lineTop, x, textAlign, parentBgColorDrawn) {
            var tokenStyle = style.rich[token.styleName] || {};
            tokenStyle.text = token.text;
            var verticalAlign = token.verticalAlign;
            var y = lineTop + lineHeight / 2;
            if (verticalAlign === 'top') {
                y = lineTop + token.height / 2;
            }
            else if (verticalAlign === 'bottom') {
                y = lineTop + lineHeight - token.height / 2;
            }
            var needDrawBg = !token.isLineHolder && needDrawBackground(tokenStyle);
            needDrawBg && this._renderBackground(tokenStyle, style, textAlign === 'right'
                ? x - token.width
                : textAlign === 'center'
                    ? x - token.width / 2
                    : x, y - token.height / 2, token.width, token.height);
            var bgColorDrawn = !!tokenStyle.backgroundColor;
            var textPadding = token.textPadding;
            if (textPadding) {
                x = getTextXForPadding(x, textAlign, textPadding);
                y -= token.height / 2 - textPadding[0] - token.innerHeight / 2;
            }
            var el = this._getOrCreateChild(TSpan);
            var subElStyle = el.createStyle();
            el.useStyle(subElStyle);
            var defaultStyle = this._defaultStyle;
            var useDefaultFill = false;
            var defaultLineWidth = 0;
            var textFill = getFill('fill' in tokenStyle ? tokenStyle.fill
                : 'fill' in style ? style.fill
                    : (useDefaultFill = true, defaultStyle.fill));
            var textStroke = getStroke('stroke' in tokenStyle ? tokenStyle.stroke
                : 'stroke' in style ? style.stroke
                    : (!bgColorDrawn
                        && !parentBgColorDrawn
                        && (!defaultStyle.autoStroke || useDefaultFill)) ? (defaultLineWidth = DEFAULT_STROKE_LINE_WIDTH, defaultStyle.stroke)
                        : null);
            var hasShadow = tokenStyle.textShadowBlur > 0
                || style.textShadowBlur > 0;
            subElStyle.text = token.text;
            subElStyle.x = x;
            subElStyle.y = y;
            if (hasShadow) {
                subElStyle.shadowBlur = tokenStyle.textShadowBlur || style.textShadowBlur || 0;
                subElStyle.shadowColor = tokenStyle.textShadowColor || style.textShadowColor || 'transparent';
                subElStyle.shadowOffsetX = tokenStyle.textShadowOffsetX || style.textShadowOffsetX || 0;
                subElStyle.shadowOffsetY = tokenStyle.textShadowOffsetY || style.textShadowOffsetY || 0;
            }
            subElStyle.textAlign = textAlign;
            subElStyle.textBaseline = 'middle';
            subElStyle.font = token.font || DEFAULT_FONT;
            subElStyle.opacity = retrieve3(tokenStyle.opacity, style.opacity, 1);
            setSeparateFont(subElStyle, tokenStyle);
            if (textStroke) {
                subElStyle.lineWidth = retrieve3(tokenStyle.lineWidth, style.lineWidth, defaultLineWidth);
                subElStyle.lineDash = retrieve2(tokenStyle.lineDash, style.lineDash);
                subElStyle.lineDashOffset = style.lineDashOffset || 0;
                subElStyle.stroke = textStroke;
            }
            if (textFill) {
                subElStyle.fill = textFill;
            }
            var textWidth = token.contentWidth;
            var textHeight = token.contentHeight;
            el.setBoundingRect(new BoundingRect(adjustTextX(subElStyle.x, textWidth, subElStyle.textAlign), adjustTextY(subElStyle.y, textHeight, subElStyle.textBaseline), textWidth, textHeight));
        };
        ZRText.prototype._renderBackground = function (style, topStyle, x, y, width, height) {
            var textBackgroundColor = style.backgroundColor;
            var textBorderWidth = style.borderWidth;
            var textBorderColor = style.borderColor;
            var isImageBg = textBackgroundColor && textBackgroundColor.image;
            var isPlainOrGradientBg = textBackgroundColor && !isImageBg;
            var textBorderRadius = style.borderRadius;
            var self = this;
            var rectEl;
            var imgEl;
            if (isPlainOrGradientBg || style.lineHeight || (textBorderWidth && textBorderColor)) {
                rectEl = this._getOrCreateChild(Rect);
                rectEl.useStyle(rectEl.createStyle());
                rectEl.style.fill = null;
                var rectShape = rectEl.shape;
                rectShape.x = x;
                rectShape.y = y;
                rectShape.width = width;
                rectShape.height = height;
                rectShape.r = textBorderRadius;
                rectEl.dirtyShape();
            }
            if (isPlainOrGradientBg) {
                var rectStyle = rectEl.style;
                rectStyle.fill = textBackgroundColor || null;
                rectStyle.fillOpacity = retrieve2(style.fillOpacity, 1);
            }
            else if (isImageBg) {
                imgEl = this._getOrCreateChild(ZRImage);
                imgEl.onload = function () {
                    self.dirtyStyle();
                };
                var imgStyle = imgEl.style;
                imgStyle.image = textBackgroundColor.image;
                imgStyle.x = x;
                imgStyle.y = y;
                imgStyle.width = width;
                imgStyle.height = height;
            }
            if (textBorderWidth && textBorderColor) {
                var rectStyle = rectEl.style;
                rectStyle.lineWidth = textBorderWidth;
                rectStyle.stroke = textBorderColor;
                rectStyle.strokeOpacity = retrieve2(style.strokeOpacity, 1);
                rectStyle.lineDash = style.borderDash;
                rectStyle.lineDashOffset = style.borderDashOffset || 0;
                rectEl.strokeContainThreshold = 0;
                if (rectEl.hasFill() && rectEl.hasStroke()) {
                    rectStyle.strokeFirst = true;
                    rectStyle.lineWidth *= 2;
                }
            }
            var commonStyle = (rectEl || imgEl).style;
            commonStyle.shadowBlur = style.shadowBlur || 0;
            commonStyle.shadowColor = style.shadowColor || 'transparent';
            commonStyle.shadowOffsetX = style.shadowOffsetX || 0;
            commonStyle.shadowOffsetY = style.shadowOffsetY || 0;
            commonStyle.opacity = retrieve3(style.opacity, topStyle.opacity, 1);
        };
        ZRText.makeFont = function (style) {
            var font = '';
            if (hasSeparateFont(style)) {
                font = [
                    style.fontStyle,
                    style.fontWeight,
                    parseFontSize(style.fontSize),
                    style.fontFamily || 'sans-serif'
                ].join(' ');
            }
            return font && trim(font) || style.textFont || style.font;
        };
        return ZRText;
    }(Displayable));
    var VALID_TEXT_ALIGN = { left: true, right: 1, center: 1 };
    var VALID_TEXT_VERTICAL_ALIGN = { top: 1, bottom: 1, middle: 1 };
    var FONT_PARTS = ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily'];
    function parseFontSize(fontSize) {
        if (typeof fontSize === 'string'
            && (fontSize.indexOf('px') !== -1
                || fontSize.indexOf('rem') !== -1
                || fontSize.indexOf('em') !== -1)) {
            return fontSize;
        }
        else if (!isNaN(+fontSize)) {
            return fontSize + 'px';
        }
        else {
            return DEFAULT_FONT_SIZE + 'px';
        }
    }
    function setSeparateFont(targetStyle, sourceStyle) {
        for (var i = 0; i < FONT_PARTS.length; i++) {
            var fontProp = FONT_PARTS[i];
            var val = sourceStyle[fontProp];
            if (val != null) {
                targetStyle[fontProp] = val;
            }
        }
    }
    function hasSeparateFont(style) {
        return style.fontSize != null || style.fontFamily || style.fontWeight;
    }
    function normalizeTextStyle(style) {
        normalizeStyle(style);
        each(style.rich, normalizeStyle);
        return style;
    }
    function normalizeStyle(style) {
        if (style) {
            style.font = ZRText.makeFont(style);
            var textAlign = style.align;
            textAlign === 'middle' && (textAlign = 'center');
            style.align = (textAlign == null || VALID_TEXT_ALIGN[textAlign]) ? textAlign : 'left';
            var verticalAlign = style.verticalAlign;
            verticalAlign === 'center' && (verticalAlign = 'middle');
            style.verticalAlign = (verticalAlign == null || VALID_TEXT_VERTICAL_ALIGN[verticalAlign]) ? verticalAlign : 'top';
            var textPadding = style.padding;
            if (textPadding) {
                style.padding = normalizeCssArray(style.padding);
            }
        }
    }
    function getStroke(stroke, lineWidth) {
        return (stroke == null || lineWidth <= 0 || stroke === 'transparent' || stroke === 'none')
            ? null
            : (stroke.image || stroke.colorStops)
                ? '#000'
                : stroke;
    }
    function getFill(fill) {
        return (fill == null || fill === 'none')
            ? null
            : (fill.image || fill.colorStops)
                ? '#000'
                : fill;
    }
    function getTextXForPadding(x, textAlign, textPadding) {
        return textAlign === 'right'
            ? (x - textPadding[1])
            : textAlign === 'center'
                ? (x + textPadding[3] / 2 - textPadding[1] / 2)
                : (x + textPadding[3]);
    }
    function getStyleText(style) {
        var text = style.text;
        text != null && (text += '');
        return text;
    }
    function needDrawBackground(style) {
        return !!(style.backgroundColor
            || style.lineHeight
            || (style.borderWidth && style.borderColor));
    }

    var getECData = makeInner();
    var setCommonECData = function (seriesIndex, dataType, dataIdx, el) {
      if (el) {
        var ecData = getECData(el); // Add data index and series index for indexing the data by element
        // Useful in tooltip

        ecData.dataIndex = dataIdx;
        ecData.dataType = dataType;
        ecData.seriesIndex = seriesIndex; // TODO: not store dataIndex on children.

        if (el.type === 'group') {
          el.traverse(function (child) {
            var childECData = getECData(child);
            childECData.seriesIndex = seriesIndex;
            childECData.dataIndex = dataIdx;
            childECData.dataType = dataType;
          });
        }
      }
    };

    var _highlightNextDigit = 1;
    var _highlightKeyMap = {};
    var getSavedStates = makeInner();
    var getComponentStates = makeInner();
    var HOVER_STATE_NORMAL = 0;
    var HOVER_STATE_BLUR = 1;
    var HOVER_STATE_EMPHASIS = 2;
    var SPECIAL_STATES = ['emphasis', 'blur', 'select'];
    var DISPLAY_STATES = ['normal', 'emphasis', 'blur', 'select'];
    var Z2_EMPHASIS_LIFT = 10;
    var Z2_SELECT_LIFT = 9;
    var HIGHLIGHT_ACTION_TYPE = 'highlight';
    var DOWNPLAY_ACTION_TYPE = 'downplay';
    var SELECT_ACTION_TYPE = 'select';
    var UNSELECT_ACTION_TYPE = 'unselect';
    var TOGGLE_SELECT_ACTION_TYPE = 'toggleSelect';

    function hasFillOrStroke(fillOrStroke) {
      return fillOrStroke != null && fillOrStroke !== 'none';
    } // Most lifted color are duplicated.


    var liftedColorCache = new LRU(100);

    function liftColor(color$1) {
      if (isString(color$1)) {
        var liftedColor = liftedColorCache.get(color$1);

        if (!liftedColor) {
          liftedColor = lift(color$1, -0.1);
          liftedColorCache.put(color$1, liftedColor);
        }

        return liftedColor;
      } else if (isGradientObject(color$1)) {
        var ret = extend({}, color$1);
        ret.colorStops = map(color$1.colorStops, function (stop) {
          return {
            offset: stop.offset,
            color: lift(stop.color, -0.1)
          };
        });
        return ret;
      } // Change nothing.


      return color$1;
    }

    function doChangeHoverState(el, stateName, hoverStateEnum) {
      if (el.onHoverStateChange && (el.hoverState || 0) !== hoverStateEnum) {
        el.onHoverStateChange(stateName);
      }

      el.hoverState = hoverStateEnum;
    }

    function singleEnterEmphasis(el) {
      // Only mark the flag.
      // States will be applied in the echarts.ts in next frame.
      doChangeHoverState(el, 'emphasis', HOVER_STATE_EMPHASIS);
    }

    function singleLeaveEmphasis(el) {
      // Only mark the flag.
      // States will be applied in the echarts.ts in next frame.
      if (el.hoverState === HOVER_STATE_EMPHASIS) {
        doChangeHoverState(el, 'normal', HOVER_STATE_NORMAL);
      }
    }

    function singleEnterBlur(el) {
      doChangeHoverState(el, 'blur', HOVER_STATE_BLUR);
    }

    function singleLeaveBlur(el) {
      if (el.hoverState === HOVER_STATE_BLUR) {
        doChangeHoverState(el, 'normal', HOVER_STATE_NORMAL);
      }
    }

    function singleEnterSelect(el) {
      el.selected = true;
    }

    function singleLeaveSelect(el) {
      el.selected = false;
    }

    function updateElementState(el, updater, commonParam) {
      updater(el, commonParam);
    }

    function traverseUpdateState(el, updater, commonParam) {
      updateElementState(el, updater, commonParam);
      el.isGroup && el.traverse(function (child) {
        updateElementState(child, updater, commonParam);
      });
    }

    function setStatesFlag(el, stateName) {
      switch (stateName) {
        case 'emphasis':
          el.hoverState = HOVER_STATE_EMPHASIS;
          break;

        case 'normal':
          el.hoverState = HOVER_STATE_NORMAL;
          break;

        case 'blur':
          el.hoverState = HOVER_STATE_BLUR;
          break;

        case 'select':
          el.selected = true;
      }
    }

    function getFromStateStyle(el, props, toStateName, defaultValue) {
      var style = el.style;
      var fromState = {};

      for (var i = 0; i < props.length; i++) {
        var propName = props[i];
        var val = style[propName];
        fromState[propName] = val == null ? defaultValue && defaultValue[propName] : val;
      }

      for (var i = 0; i < el.animators.length; i++) {
        var animator = el.animators[i];

        if (animator.__fromStateTransition // Don't consider the animation to emphasis state.
        && animator.__fromStateTransition.indexOf(toStateName) < 0 && animator.targetName === 'style') {
          animator.saveTo(fromState, props);
        }
      }

      return fromState;
    }

    function createEmphasisDefaultState(el, stateName, targetStates, state) {
      var hasSelect = targetStates && indexOf(targetStates, 'select') >= 0;
      var cloned = false;

      if (el instanceof Path) {
        var store = getSavedStates(el);
        var fromFill = hasSelect ? store.selectFill || store.normalFill : store.normalFill;
        var fromStroke = hasSelect ? store.selectStroke || store.normalStroke : store.normalStroke;

        if (hasFillOrStroke(fromFill) || hasFillOrStroke(fromStroke)) {
          state = state || {};
          var emphasisStyle = state.style || {}; // inherit case

          if (emphasisStyle.fill === 'inherit') {
            cloned = true;
            state = extend({}, state);
            emphasisStyle = extend({}, emphasisStyle);
            emphasisStyle.fill = fromFill;
          } // Apply default color lift
          else if (!hasFillOrStroke(emphasisStyle.fill) && hasFillOrStroke(fromFill)) {
              cloned = true; // Not modify the original value.

              state = extend({}, state);
              emphasisStyle = extend({}, emphasisStyle); // Already being applied 'emphasis'. DON'T lift color multiple times.

              emphasisStyle.fill = liftColor(fromFill);
            } // Not highlight stroke if fill has been highlighted.
            else if (!hasFillOrStroke(emphasisStyle.stroke) && hasFillOrStroke(fromStroke)) {
                if (!cloned) {
                  state = extend({}, state);
                  emphasisStyle = extend({}, emphasisStyle);
                }

                emphasisStyle.stroke = liftColor(fromStroke);
              }

          state.style = emphasisStyle;
        }
      }

      if (state) {
        // TODO Share with textContent?
        if (state.z2 == null) {
          if (!cloned) {
            state = extend({}, state);
          }

          var z2EmphasisLift = el.z2EmphasisLift;
          state.z2 = el.z2 + (z2EmphasisLift != null ? z2EmphasisLift : Z2_EMPHASIS_LIFT);
        }
      }

      return state;
    }

    function createSelectDefaultState(el, stateName, state) {
      // const hasSelect = indexOf(el.currentStates, stateName) >= 0;
      if (state) {
        // TODO Share with textContent?
        if (state.z2 == null) {
          state = extend({}, state);
          var z2SelectLift = el.z2SelectLift;
          state.z2 = el.z2 + (z2SelectLift != null ? z2SelectLift : Z2_SELECT_LIFT);
        }
      }

      return state;
    }

    function createBlurDefaultState(el, stateName, state) {
      var hasBlur = indexOf(el.currentStates, stateName) >= 0;
      var currentOpacity = el.style.opacity;
      var fromState = !hasBlur ? getFromStateStyle(el, ['opacity'], stateName, {
        opacity: 1
      }) : null;
      state = state || {};
      var blurStyle = state.style || {};

      if (blurStyle.opacity == null) {
        // clone state
        state = extend({}, state);
        blurStyle = extend({
          // Already being applied 'emphasis'. DON'T mul opacity multiple times.
          opacity: hasBlur ? currentOpacity : fromState.opacity * 0.1
        }, blurStyle);
        state.style = blurStyle;
      }

      return state;
    }

    function elementStateProxy(stateName, targetStates) {
      var state = this.states[stateName];

      if (this.style) {
        if (stateName === 'emphasis') {
          return createEmphasisDefaultState(this, stateName, targetStates, state);
        } else if (stateName === 'blur') {
          return createBlurDefaultState(this, stateName, state);
        } else if (stateName === 'select') {
          return createSelectDefaultState(this, stateName, state);
        }
      }

      return state;
    }
    /**
     * Set hover style (namely "emphasis style") of element.
     * @param el Should not be `zrender/graphic/Group`.
     * @param focus 'self' | 'selfInSeries' | 'series'
     */


    function setDefaultStateProxy(el) {
      el.stateProxy = elementStateProxy;
      var textContent = el.getTextContent();
      var textGuide = el.getTextGuideLine();

      if (textContent) {
        textContent.stateProxy = elementStateProxy;
      }

      if (textGuide) {
        textGuide.stateProxy = elementStateProxy;
      }
    }
    function enterEmphasisWhenMouseOver(el, e) {
      !shouldSilent(el, e) // "emphasis" event highlight has higher priority than mouse highlight.
      && !el.__highByOuter && traverseUpdateState(el, singleEnterEmphasis);
    }
    function leaveEmphasisWhenMouseOut(el, e) {
      !shouldSilent(el, e) // "emphasis" event highlight has higher priority than mouse highlight.
      && !el.__highByOuter && traverseUpdateState(el, singleLeaveEmphasis);
    }
    function enterEmphasis(el, highlightDigit) {
      el.__highByOuter |= 1 << (highlightDigit || 0);
      traverseUpdateState(el, singleEnterEmphasis);
    }
    function leaveEmphasis(el, highlightDigit) {
      !(el.__highByOuter &= ~(1 << (highlightDigit || 0))) && traverseUpdateState(el, singleLeaveEmphasis);
    }
    function enterBlur(el) {
      traverseUpdateState(el, singleEnterBlur);
    }
    function leaveBlur(el) {
      traverseUpdateState(el, singleLeaveBlur);
    }
    function enterSelect(el) {
      traverseUpdateState(el, singleEnterSelect);
    }
    function leaveSelect(el) {
      traverseUpdateState(el, singleLeaveSelect);
    }

    function shouldSilent(el, e) {
      return el.__highDownSilentOnTouch && e.zrByTouch;
    }

    function allLeaveBlur(api) {
      var model = api.getModel();
      var leaveBlurredSeries = [];
      var allComponentViews = [];
      model.eachComponent(function (componentType, componentModel) {
        var componentStates = getComponentStates(componentModel);
        var isSeries = componentType === 'series';
        var view = isSeries ? api.getViewOfSeriesModel(componentModel) : api.getViewOfComponentModel(componentModel);
        !isSeries && allComponentViews.push(view);

        if (componentStates.isBlured) {
          // Leave blur anyway
          view.group.traverse(function (child) {
            singleLeaveBlur(child);
          });
          isSeries && leaveBlurredSeries.push(componentModel);
        }

        componentStates.isBlured = false;
      });
      each(allComponentViews, function (view) {
        if (view && view.toggleBlurSeries) {
          view.toggleBlurSeries(leaveBlurredSeries, false, model);
        }
      });
    }
    function blurSeries(targetSeriesIndex, focus, blurScope, api) {
      var ecModel = api.getModel();
      blurScope = blurScope || 'coordinateSystem';

      function leaveBlurOfIndices(data, dataIndices) {
        for (var i = 0; i < dataIndices.length; i++) {
          var itemEl = data.getItemGraphicEl(dataIndices[i]);
          itemEl && leaveBlur(itemEl);
        }
      }

      if (targetSeriesIndex == null) {
        return;
      }

      if (!focus || focus === 'none') {
        return;
      }

      var targetSeriesModel = ecModel.getSeriesByIndex(targetSeriesIndex);
      var targetCoordSys = targetSeriesModel.coordinateSystem;

      if (targetCoordSys && targetCoordSys.master) {
        targetCoordSys = targetCoordSys.master;
      }

      var blurredSeries = [];
      ecModel.eachSeries(function (seriesModel) {
        var sameSeries = targetSeriesModel === seriesModel;
        var coordSys = seriesModel.coordinateSystem;

        if (coordSys && coordSys.master) {
          coordSys = coordSys.master;
        }

        var sameCoordSys = coordSys && targetCoordSys ? coordSys === targetCoordSys : sameSeries; // If there is no coordinate system. use sameSeries instead.

        if (!( // Not blur other series if blurScope series
        blurScope === 'series' && !sameSeries // Not blur other coordinate system if blurScope is coordinateSystem
        || blurScope === 'coordinateSystem' && !sameCoordSys // Not blur self series if focus is series.
        || focus === 'series' && sameSeries // TODO blurScope: coordinate system
        )) {
          var view = api.getViewOfSeriesModel(seriesModel);
          view.group.traverse(function (child) {
            singleEnterBlur(child);
          });

          if (isArrayLike(focus)) {
            leaveBlurOfIndices(seriesModel.getData(), focus);
          } else if (isObject(focus)) {
            var dataTypes = keys(focus);

            for (var d = 0; d < dataTypes.length; d++) {
              leaveBlurOfIndices(seriesModel.getData(dataTypes[d]), focus[dataTypes[d]]);
            }
          }

          blurredSeries.push(seriesModel);
          getComponentStates(seriesModel).isBlured = true;
        }
      });
      ecModel.eachComponent(function (componentType, componentModel) {
        if (componentType === 'series') {
          return;
        }

        var view = api.getViewOfComponentModel(componentModel);

        if (view && view.toggleBlurSeries) {
          view.toggleBlurSeries(blurredSeries, true, ecModel);
        }
      });
    }
    function blurComponent(componentMainType, componentIndex, api) {
      if (componentMainType == null || componentIndex == null) {
        return;
      }

      var componentModel = api.getModel().getComponent(componentMainType, componentIndex);

      if (!componentModel) {
        return;
      }

      getComponentStates(componentModel).isBlured = true;
      var view = api.getViewOfComponentModel(componentModel);

      if (!view || !view.focusBlurEnabled) {
        return;
      }

      view.group.traverse(function (child) {
        singleEnterBlur(child);
      });
    }
    function blurSeriesFromHighlightPayload(seriesModel, payload, api) {
      var seriesIndex = seriesModel.seriesIndex;
      var data = seriesModel.getData(payload.dataType);

      if (!data) {
        if ("development" !== 'production') {
          error("Unknown dataType " + payload.dataType);
        }

        return;
      }

      var dataIndex = queryDataIndex(data, payload); // Pick the first one if there is multiple/none exists.

      dataIndex = (isArray(dataIndex) ? dataIndex[0] : dataIndex) || 0;
      var el = data.getItemGraphicEl(dataIndex);

      if (!el) {
        var count = data.count();
        var current = 0; // If data on dataIndex is NaN.

        while (!el && current < count) {
          el = data.getItemGraphicEl(current++);
        }
      }

      if (el) {
        var ecData = getECData(el);
        blurSeries(seriesIndex, ecData.focus, ecData.blurScope, api);
      } else {
        // If there is no element put on the data. Try getting it from raw option
        // TODO Should put it on seriesModel?
        var focus_1 = seriesModel.get(['emphasis', 'focus']);
        var blurScope = seriesModel.get(['emphasis', 'blurScope']);

        if (focus_1 != null) {
          blurSeries(seriesIndex, focus_1, blurScope, api);
        }
      }
    }
    function findComponentHighDownDispatchers(componentMainType, componentIndex, name, api) {
      var ret = {
        focusSelf: false,
        dispatchers: null
      };

      if (componentMainType == null || componentMainType === 'series' || componentIndex == null || name == null) {
        return ret;
      }

      var componentModel = api.getModel().getComponent(componentMainType, componentIndex);

      if (!componentModel) {
        return ret;
      }

      var view = api.getViewOfComponentModel(componentModel);

      if (!view || !view.findHighDownDispatchers) {
        return ret;
      }

      var dispatchers = view.findHighDownDispatchers(name); // At presnet, the component (like Geo) only blur inside itself.
      // So we do not use `blurScope` in component.

      var focusSelf;

      for (var i = 0; i < dispatchers.length; i++) {
        if ("development" !== 'production' && !isHighDownDispatcher(dispatchers[i])) {
          error('param should be highDownDispatcher');
        }

        if (getECData(dispatchers[i]).focus === 'self') {
          focusSelf = true;
          break;
        }
      }

      return {
        focusSelf: focusSelf,
        dispatchers: dispatchers
      };
    }
    function handleGlobalMouseOverForHighDown(dispatcher, e, api) {
      if ("development" !== 'production' && !isHighDownDispatcher(dispatcher)) {
        error('param should be highDownDispatcher');
      }

      var ecData = getECData(dispatcher);

      var _a = findComponentHighDownDispatchers(ecData.componentMainType, ecData.componentIndex, ecData.componentHighDownName, api),
          dispatchers = _a.dispatchers,
          focusSelf = _a.focusSelf; // If `findHighDownDispatchers` is supported on the component,
      // highlight/downplay elements with the same name.


      if (dispatchers) {
        if (focusSelf) {
          blurComponent(ecData.componentMainType, ecData.componentIndex, api);
        }

        each(dispatchers, function (dispatcher) {
          return enterEmphasisWhenMouseOver(dispatcher, e);
        });
      } else {
        // Try blur all in the related series. Then emphasis the hoverred.
        // TODO. progressive mode.
        blurSeries(ecData.seriesIndex, ecData.focus, ecData.blurScope, api);

        if (ecData.focus === 'self') {
          blurComponent(ecData.componentMainType, ecData.componentIndex, api);
        } // Other than series, component that not support `findHighDownDispatcher` will
        // also use it. But in this case, highlight/downplay are only supported in
        // mouse hover but not in dispatchAction.


        enterEmphasisWhenMouseOver(dispatcher, e);
      }
    }
    function handleGlobalMouseOutForHighDown(dispatcher, e, api) {
      if ("development" !== 'production' && !isHighDownDispatcher(dispatcher)) {
        error('param should be highDownDispatcher');
      }

      allLeaveBlur(api);
      var ecData = getECData(dispatcher);
      var dispatchers = findComponentHighDownDispatchers(ecData.componentMainType, ecData.componentIndex, ecData.componentHighDownName, api).dispatchers;

      if (dispatchers) {
        each(dispatchers, function (dispatcher) {
          return leaveEmphasisWhenMouseOut(dispatcher, e);
        });
      } else {
        leaveEmphasisWhenMouseOut(dispatcher, e);
      }
    }
    function toggleSelectionFromPayload(seriesModel, payload, api) {
      if (!isSelectChangePayload(payload)) {
        return;
      }

      var dataType = payload.dataType;
      var data = seriesModel.getData(dataType);
      var dataIndex = queryDataIndex(data, payload);

      if (!isArray(dataIndex)) {
        dataIndex = [dataIndex];
      }

      seriesModel[payload.type === TOGGLE_SELECT_ACTION_TYPE ? 'toggleSelect' : payload.type === SELECT_ACTION_TYPE ? 'select' : 'unselect'](dataIndex, dataType);
    }
    function updateSeriesElementSelection(seriesModel) {
      var allData = seriesModel.getAllData();
      each(allData, function (_a) {
        var data = _a.data,
            type = _a.type;
        data.eachItemGraphicEl(function (el, idx) {
          seriesModel.isSelected(idx, type) ? enterSelect(el) : leaveSelect(el);
        });
      });
    }
    function getAllSelectedIndices(ecModel) {
      var ret = [];
      ecModel.eachSeries(function (seriesModel) {
        var allData = seriesModel.getAllData();
        each(allData, function (_a) {
          var data = _a.data,
              type = _a.type;
          var dataIndices = seriesModel.getSelectedDataIndices();

          if (dataIndices.length > 0) {
            var item = {
              dataIndex: dataIndices,
              seriesIndex: seriesModel.seriesIndex
            };

            if (type != null) {
              item.dataType = type;
            }

            ret.push(item);
          }
        });
      });
      return ret;
    }
    /**
     * Enable the function that mouseover will trigger the emphasis state.
     *
     * NOTE:
     * This function should be used on the element with dataIndex, seriesIndex.
     *
     */

    function enableHoverEmphasis(el, focus, blurScope) {
      setAsHighDownDispatcher(el, true);
      traverseUpdateState(el, setDefaultStateProxy);
      enableHoverFocus(el, focus, blurScope);
    }
    function disableHoverEmphasis(el) {
      setAsHighDownDispatcher(el, false);
    }
    function toggleHoverEmphasis(el, focus, blurScope, isDisabled) {
      isDisabled ? disableHoverEmphasis(el) : enableHoverEmphasis(el, focus, blurScope);
    }
    function enableHoverFocus(el, focus, blurScope) {
      var ecData = getECData(el);

      if (focus != null) {
        // TODO dataIndex may be set after this function. This check is not useful.
        // if (ecData.dataIndex == null) {
        //     if (__DEV__) {
        //         console.warn('focus can only been set on element with dataIndex');
        //     }
        // }
        // else {
        ecData.focus = focus;
        ecData.blurScope = blurScope; // }
      } else if (ecData.focus) {
        ecData.focus = null;
      }
    }
    var OTHER_STATES = ['emphasis', 'blur', 'select'];
    var defaultStyleGetterMap = {
      itemStyle: 'getItemStyle',
      lineStyle: 'getLineStyle',
      areaStyle: 'getAreaStyle'
    };
    /**
     * Set emphasis/blur/selected states of element.
     */

    function setStatesStylesFromModel(el, itemModel, styleType, // default itemStyle
    getter) {
      styleType = styleType || 'itemStyle';

      for (var i = 0; i < OTHER_STATES.length; i++) {
        var stateName = OTHER_STATES[i];
        var model = itemModel.getModel([stateName, styleType]);
        var state = el.ensureState(stateName); // Let it throw error if getterType is not found.

        state.style = getter ? getter(model) : model[defaultStyleGetterMap[styleType]]();
      }
    }
    /**
     *
     * Set element as highlight / downplay dispatcher.
     * It will be checked when element received mouseover event or from highlight action.
     * It's in change of all highlight/downplay behavior of it's children.
     *
     * @param el
     * @param el.highDownSilentOnTouch
     *        In touch device, mouseover event will be trigger on touchstart event
     *        (see module:zrender/dom/HandlerProxy). By this mechanism, we can
     *        conveniently use hoverStyle when tap on touch screen without additional
     *        code for compatibility.
     *        But if the chart/component has select feature, which usually also use
     *        hoverStyle, there might be conflict between 'select-highlight' and
     *        'hover-highlight' especially when roam is enabled (see geo for example).
     *        In this case, `highDownSilentOnTouch` should be used to disable
     *        hover-highlight on touch device.
     * @param asDispatcher If `false`, do not set as "highDownDispatcher".
     */

    function setAsHighDownDispatcher(el, asDispatcher) {
      var disable = asDispatcher === false;
      var extendedEl = el; // Make `highDownSilentOnTouch` and `onStateChange` only work after
      // `setAsHighDownDispatcher` called. Avoid it is modified by user unexpectedly.

      if (el.highDownSilentOnTouch) {
        extendedEl.__highDownSilentOnTouch = el.highDownSilentOnTouch;
      } // Simple optimize, since this method might be
      // called for each elements of a group in some cases.


      if (!disable || extendedEl.__highDownDispatcher) {
        // Emphasis, normal can be triggered manually by API or other components like hover link.
        // el[method]('emphasis', onElementEmphasisEvent)[method]('normal', onElementNormalEvent);
        // Also keep previous record.
        extendedEl.__highByOuter = extendedEl.__highByOuter || 0;
        extendedEl.__highDownDispatcher = !disable;
      }
    }
    function isHighDownDispatcher(el) {
      return !!(el && el.__highDownDispatcher);
    }
    /**
     * Support highlight/downplay record on each elements.
     * For the case: hover highlight/downplay (legend, visualMap, ...) and
     * user triggered highlight/downplay should not conflict.
     * Only all of the highlightDigit cleared, return to normal.
     * @param {string} highlightKey
     * @return {number} highlightDigit
     */

    function getHighlightDigit(highlightKey) {
      var highlightDigit = _highlightKeyMap[highlightKey];

      if (highlightDigit == null && _highlightNextDigit <= 32) {
        highlightDigit = _highlightKeyMap[highlightKey] = _highlightNextDigit++;
      }

      return highlightDigit;
    }
    function isSelectChangePayload(payload) {
      var payloadType = payload.type;
      return payloadType === SELECT_ACTION_TYPE || payloadType === UNSELECT_ACTION_TYPE || payloadType === TOGGLE_SELECT_ACTION_TYPE;
    }
    function isHighDownPayload(payload) {
      var payloadType = payload.type;
      return payloadType === HIGHLIGHT_ACTION_TYPE || payloadType === DOWNPLAY_ACTION_TYPE;
    }
    function savePathStates(el) {
      var store = getSavedStates(el);
      store.normalFill = el.style.fill;
      store.normalStroke = el.style.stroke;
      var selectState = el.states.select || {};
      store.selectFill = selectState.style && selectState.style.fill || null;
      store.selectStroke = selectState.style && selectState.style.stroke || null;
    }

    var CMD$2 = PathProxy.CMD;
    var points = [[], [], []];
    var mathSqrt$1 = Math.sqrt;
    var mathAtan2 = Math.atan2;
    function transformPath(path, m) {
        if (!m) {
            return;
        }
        var data = path.data;
        var len = path.len();
        var cmd;
        var nPoint;
        var i;
        var j;
        var k;
        var p;
        var M = CMD$2.M;
        var C = CMD$2.C;
        var L = CMD$2.L;
        var R = CMD$2.R;
        var A = CMD$2.A;
        var Q = CMD$2.Q;
        for (i = 0, j = 0; i < len;) {
            cmd = data[i++];
            j = i;
            nPoint = 0;
            switch (cmd) {
                case M:
                    nPoint = 1;
                    break;
                case L:
                    nPoint = 1;
                    break;
                case C:
                    nPoint = 3;
                    break;
                case Q:
                    nPoint = 2;
                    break;
                case A:
                    var x = m[4];
                    var y = m[5];
                    var sx = mathSqrt$1(m[0] * m[0] + m[1] * m[1]);
                    var sy = mathSqrt$1(m[2] * m[2] + m[3] * m[3]);
                    var angle = mathAtan2(-m[1] / sy, m[0] / sx);
                    data[i] *= sx;
                    data[i++] += x;
                    data[i] *= sy;
                    data[i++] += y;
                    data[i++] *= sx;
                    data[i++] *= sy;
                    data[i++] += angle;
                    data[i++] += angle;
                    i += 2;
                    j = i;
                    break;
                case R:
                    p[0] = data[i++];
                    p[1] = data[i++];
                    applyTransform(p, p, m);
                    data[j++] = p[0];
                    data[j++] = p[1];
                    p[0] += data[i++];
                    p[1] += data[i++];
                    applyTransform(p, p, m);
                    data[j++] = p[0];
                    data[j++] = p[1];
            }
            for (k = 0; k < nPoint; k++) {
                var p_1 = points[k];
                p_1[0] = data[i++];
                p_1[1] = data[i++];
                applyTransform(p_1, p_1, m);
                data[j++] = p_1[0];
                data[j++] = p_1[1];
            }
        }
        path.increaseVersion();
    }

    var mathSqrt$2 = Math.sqrt;
    var mathSin$2 = Math.sin;
    var mathCos$2 = Math.cos;
    var PI$1 = Math.PI;
    function vMag(v) {
        return Math.sqrt(v[0] * v[0] + v[1] * v[1]);
    }
    function vRatio(u, v) {
        return (u[0] * v[0] + u[1] * v[1]) / (vMag(u) * vMag(v));
    }
    function vAngle(u, v) {
        return (u[0] * v[1] < u[1] * v[0] ? -1 : 1)
            * Math.acos(vRatio(u, v));
    }
    function processArc(x1, y1, x2, y2, fa, fs, rx, ry, psiDeg, cmd, path) {
        var psi = psiDeg * (PI$1 / 180.0);
        var xp = mathCos$2(psi) * (x1 - x2) / 2.0
            + mathSin$2(psi) * (y1 - y2) / 2.0;
        var yp = -1 * mathSin$2(psi) * (x1 - x2) / 2.0
            + mathCos$2(psi) * (y1 - y2) / 2.0;
        var lambda = (xp * xp) / (rx * rx) + (yp * yp) / (ry * ry);
        if (lambda > 1) {
            rx *= mathSqrt$2(lambda);
            ry *= mathSqrt$2(lambda);
        }
        var f = (fa === fs ? -1 : 1)
            * mathSqrt$2((((rx * rx) * (ry * ry))
                - ((rx * rx) * (yp * yp))
                - ((ry * ry) * (xp * xp))) / ((rx * rx) * (yp * yp)
                + (ry * ry) * (xp * xp))) || 0;
        var cxp = f * rx * yp / ry;
        var cyp = f * -ry * xp / rx;
        var cx = (x1 + x2) / 2.0
            + mathCos$2(psi) * cxp
            - mathSin$2(psi) * cyp;
        var cy = (y1 + y2) / 2.0
            + mathSin$2(psi) * cxp
            + mathCos$2(psi) * cyp;
        var theta = vAngle([1, 0], [(xp - cxp) / rx, (yp - cyp) / ry]);
        var u = [(xp - cxp) / rx, (yp - cyp) / ry];
        var v = [(-1 * xp - cxp) / rx, (-1 * yp - cyp) / ry];
        var dTheta = vAngle(u, v);
        if (vRatio(u, v) <= -1) {
            dTheta = PI$1;
        }
        if (vRatio(u, v) >= 1) {
            dTheta = 0;
        }
        if (dTheta < 0) {
            var n = Math.round(dTheta / PI$1 * 1e6) / 1e6;
            dTheta = PI$1 * 2 + (n % 2) * PI$1;
        }
        path.addData(cmd, cx, cy, rx, ry, theta, dTheta, psi, fs);
    }
    var commandReg = /([mlvhzcqtsa])([^mlvhzcqtsa]*)/ig;
    var numberReg = /-?([0-9]*\.)?[0-9]+([eE]-?[0-9]+)?/g;
    function createPathProxyFromString(data) {
        var path = new PathProxy();
        if (!data) {
            return path;
        }
        var cpx = 0;
        var cpy = 0;
        var subpathX = cpx;
        var subpathY = cpy;
        var prevCmd;
        var CMD = PathProxy.CMD;
        var cmdList = data.match(commandReg);
        if (!cmdList) {
            return path;
        }
        for (var l = 0; l < cmdList.length; l++) {
            var cmdText = cmdList[l];
            var cmdStr = cmdText.charAt(0);
            var cmd = void 0;
            var p = cmdText.match(numberReg) || [];
            var pLen = p.length;
            for (var i = 0; i < pLen; i++) {
                p[i] = parseFloat(p[i]);
            }
            var off = 0;
            while (off < pLen) {
                var ctlPtx = void 0;
                var ctlPty = void 0;
                var rx = void 0;
                var ry = void 0;
                var psi = void 0;
                var fa = void 0;
                var fs = void 0;
                var x1 = cpx;
                var y1 = cpy;
                var len = void 0;
                var pathData = void 0;
                switch (cmdStr) {
                    case 'l':
                        cpx += p[off++];
                        cpy += p[off++];
                        cmd = CMD.L;
                        path.addData(cmd, cpx, cpy);
                        break;
                    case 'L':
                        cpx = p[off++];
                        cpy = p[off++];
                        cmd = CMD.L;
                        path.addData(cmd, cpx, cpy);
                        break;
                    case 'm':
                        cpx += p[off++];
                        cpy += p[off++];
                        cmd = CMD.M;
                        path.addData(cmd, cpx, cpy);
                        subpathX = cpx;
                        subpathY = cpy;
                        cmdStr = 'l';
                        break;
                    case 'M':
                        cpx = p[off++];
                        cpy = p[off++];
                        cmd = CMD.M;
                        path.addData(cmd, cpx, cpy);
                        subpathX = cpx;
                        subpathY = cpy;
                        cmdStr = 'L';
                        break;
                    case 'h':
                        cpx += p[off++];
                        cmd = CMD.L;
                        path.addData(cmd, cpx, cpy);
                        break;
                    case 'H':
                        cpx = p[off++];
                        cmd = CMD.L;
                        path.addData(cmd, cpx, cpy);
                        break;
                    case 'v':
                        cpy += p[off++];
                        cmd = CMD.L;
                        path.addData(cmd, cpx, cpy);
                        break;
                    case 'V':
                        cpy = p[off++];
                        cmd = CMD.L;
                        path.addData(cmd, cpx, cpy);
                        break;
                    case 'C':
                        cmd = CMD.C;
                        path.addData(cmd, p[off++], p[off++], p[off++], p[off++], p[off++], p[off++]);
                        cpx = p[off - 2];
                        cpy = p[off - 1];
                        break;
                    case 'c':
                        cmd = CMD.C;
                        path.addData(cmd, p[off++] + cpx, p[off++] + cpy, p[off++] + cpx, p[off++] + cpy, p[off++] + cpx, p[off++] + cpy);
                        cpx += p[off - 2];
                        cpy += p[off - 1];
                        break;
                    case 'S':
                        ctlPtx = cpx;
                        ctlPty = cpy;
                        len = path.len();
                        pathData = path.data;
                        if (prevCmd === CMD.C) {
                            ctlPtx += cpx - pathData[len - 4];
                            ctlPty += cpy - pathData[len - 3];
                        }
                        cmd = CMD.C;
                        x1 = p[off++];
                        y1 = p[off++];
                        cpx = p[off++];
                        cpy = p[off++];
                        path.addData(cmd, ctlPtx, ctlPty, x1, y1, cpx, cpy);
                        break;
                    case 's':
                        ctlPtx = cpx;
                        ctlPty = cpy;
                        len = path.len();
                        pathData = path.data;
                        if (prevCmd === CMD.C) {
                            ctlPtx += cpx - pathData[len - 4];
                            ctlPty += cpy - pathData[len - 3];
                        }
                        cmd = CMD.C;
                        x1 = cpx + p[off++];
                        y1 = cpy + p[off++];
                        cpx += p[off++];
                        cpy += p[off++];
                        path.addData(cmd, ctlPtx, ctlPty, x1, y1, cpx, cpy);
                        break;
                    case 'Q':
                        x1 = p[off++];
                        y1 = p[off++];
                        cpx = p[off++];
                        cpy = p[off++];
                        cmd = CMD.Q;
                        path.addData(cmd, x1, y1, cpx, cpy);
                        break;
                    case 'q':
                        x1 = p[off++] + cpx;
                        y1 = p[off++] + cpy;
                        cpx += p[off++];
                        cpy += p[off++];
                        cmd = CMD.Q;
                        path.addData(cmd, x1, y1, cpx, cpy);
                        break;
                    case 'T':
                        ctlPtx = cpx;
                        ctlPty = cpy;
                        len = path.len();
                        pathData = path.data;
                        if (prevCmd === CMD.Q) {
                            ctlPtx += cpx - pathData[len - 4];
                            ctlPty += cpy - pathData[len - 3];
                        }
                        cpx = p[off++];
                        cpy = p[off++];
                        cmd = CMD.Q;
                        path.addData(cmd, ctlPtx, ctlPty, cpx, cpy);
                        break;
                    case 't':
                        ctlPtx = cpx;
                        ctlPty = cpy;
                        len = path.len();
                        pathData = path.data;
                        if (prevCmd === CMD.Q) {
                            ctlPtx += cpx - pathData[len - 4];
                            ctlPty += cpy - pathData[len - 3];
                        }
                        cpx += p[off++];
                        cpy += p[off++];
                        cmd = CMD.Q;
                        path.addData(cmd, ctlPtx, ctlPty, cpx, cpy);
                        break;
                    case 'A':
                        rx = p[off++];
                        ry = p[off++];
                        psi = p[off++];
                        fa = p[off++];
                        fs = p[off++];
                        x1 = cpx, y1 = cpy;
                        cpx = p[off++];
                        cpy = p[off++];
                        cmd = CMD.A;
                        processArc(x1, y1, cpx, cpy, fa, fs, rx, ry, psi, cmd, path);
                        break;
                    case 'a':
                        rx = p[off++];
                        ry = p[off++];
                        psi = p[off++];
                        fa = p[off++];
                        fs = p[off++];
                        x1 = cpx, y1 = cpy;
                        cpx += p[off++];
                        cpy += p[off++];
                        cmd = CMD.A;
                        processArc(x1, y1, cpx, cpy, fa, fs, rx, ry, psi, cmd, path);
                        break;
                }
            }
            if (cmdStr === 'z' || cmdStr === 'Z') {
                cmd = CMD.Z;
                path.addData(cmd);
                cpx = subpathX;
                cpy = subpathY;
            }
            prevCmd = cmd;
        }
        path.toStatic();
        return path;
    }
    var SVGPath = (function (_super) {
        __extends(SVGPath, _super);
        function SVGPath() {
            return _super !== null && _super.apply(this, arguments) || this;
        }
        SVGPath.prototype.applyTransform = function (m) { };
        return SVGPath;
    }(Path));
    function isPathProxy(path) {
        return path.setData != null;
    }
    function createPathOptions(str, opts) {
        var pathProxy = createPathProxyFromString(str);
        var innerOpts = extend({}, opts);
        innerOpts.buildPath = function (path) {
            if (isPathProxy(path)) {
                path.setData(pathProxy.data);
                var ctx = path.getContext();
                if (ctx) {
                    path.rebuildPath(ctx, 1);
                }
            }
            else {
                var ctx = path;
                pathProxy.rebuildPath(ctx, 1);
            }
        };
        innerOpts.applyTransform = function (m) {
            transformPath(pathProxy, m);
            this.dirtyShape();
        };
        return innerOpts;
    }
    function createFromString(str, opts) {
        return new SVGPath(createPathOptions(str, opts));
    }
    function extendFromString(str, defaultOpts) {
        var innerOpts = createPathOptions(str, defaultOpts);
        var Sub = (function (_super) {
            __extends(Sub, _super);
            function Sub(opts) {
                var _this = _super.call(this, opts) || this;
                _this.applyTransform = innerOpts.applyTransform;
                _this.buildPath = innerOpts.buildPath;
                return _this;
            }
            return Sub;
        }(SVGPath));
        return Sub;
    }
    function mergePath(pathEls, opts) {
        var pathList = [];
        var len = pathEls.length;
        for (var i = 0; i < len; i++) {
            var pathEl = pathEls[i];
            pathList.push(pathEl.getUpdatedPathProxy(true));
        }
        var pathBundle = new Path(opts);
        pathBundle.createPathProxy();
        pathBundle.buildPath = function (path) {
            if (isPathProxy(path)) {
                path.appendPath(pathList);
                var ctx = path.getContext();
                if (ctx) {
                    path.rebuildPath(ctx, 1);
                }
            }
        };
        return pathBundle;
    }

    var CircleShape = (function () {
        function CircleShape() {
            this.cx = 0;
            this.cy = 0;
            this.r = 0;
        }
        return CircleShape;
    }());
    var Circle = (function (_super) {
        __extends(Circle, _super);
        function Circle(opts) {
            return _super.call(this, opts) || this;
        }
        Circle.prototype.getDefaultShape = function () {
            return new CircleShape();
        };
        Circle.prototype.buildPath = function (ctx, shape) {
            ctx.moveTo(shape.cx + shape.r, shape.cy);
            ctx.arc(shape.cx, shape.cy, shape.r, 0, Math.PI * 2);
        };
        return Circle;
    }(Path));
    Circle.prototype.type = 'circle';

    var EllipseShape = (function () {
        function EllipseShape() {
            this.cx = 0;
            this.cy = 0;
            this.rx = 0;
            this.ry = 0;
        }
        return EllipseShape;
    }());
    var Ellipse = (function (_super) {
        __extends(Ellipse, _super);
        function Ellipse(opts) {
            return _super.call(this, opts) || this;
        }
        Ellipse.prototype.getDefaultShape = function () {
            return new EllipseShape();
        };
        Ellipse.prototype.buildPath = function (ctx, shape) {
            var k = 0.5522848;
            var x = shape.cx;
            var y = shape.cy;
            var a = shape.rx;
            var b = shape.ry;
            var ox = a * k;
            var oy = b * k;
            ctx.moveTo(x - a, y);
            ctx.bezierCurveTo(x - a, y - oy, x - ox, y - b, x, y - b);
            ctx.bezierCurveTo(x + ox, y - b, x + a, y - oy, x + a, y);
            ctx.bezierCurveTo(x + a, y + oy, x + ox, y + b, x, y + b);
            ctx.bezierCurveTo(x - ox, y + b, x - a, y + oy, x - a, y);
            ctx.closePath();
        };
        return Ellipse;
    }(Path));
    Ellipse.prototype.type = 'ellipse';

    var PI$2 = Math.PI;
    var PI2$5 = PI$2 * 2;
    var mathSin$3 = Math.sin;
    var mathCos$3 = Math.cos;
    var mathACos = Math.acos;
    var mathATan2 = Math.atan2;
    var mathAbs$1 = Math.abs;
    var mathSqrt$3 = Math.sqrt;
    var mathMax$3 = Math.max;
    var mathMin$3 = Math.min;
    var e = 1e-4;
    function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
        var dx10 = x1 - x0;
        var dy10 = y1 - y0;
        var dx32 = x3 - x2;
        var dy32 = y3 - y2;
        var t = dy32 * dx10 - dx32 * dy10;
        if (t * t < e) {
            return;
        }
        t = (dx32 * (y0 - y2) - dy32 * (x0 - x2)) / t;
        return [x0 + t * dx10, y0 + t * dy10];
    }
    function computeCornerTangents(x0, y0, x1, y1, radius, cr, clockwise) {
        var x01 = x0 - x1;
        var y01 = y0 - y1;
        var lo = (clockwise ? cr : -cr) / mathSqrt$3(x01 * x01 + y01 * y01);
        var ox = lo * y01;
        var oy = -lo * x01;
        var x11 = x0 + ox;
        var y11 = y0 + oy;
        var x10 = x1 + ox;
        var y10 = y1 + oy;
        var x00 = (x11 + x10) / 2;
        var y00 = (y11 + y10) / 2;
        var dx = x10 - x11;
        var dy = y10 - y11;
        var d2 = dx * dx + dy * dy;
        var r = radius - cr;
        var s = x11 * y10 - x10 * y11;
        var d = (dy < 0 ? -1 : 1) * mathSqrt$3(mathMax$3(0, r * r * d2 - s * s));
        var cx0 = (s * dy - dx * d) / d2;
        var cy0 = (-s * dx - dy * d) / d2;
        var cx1 = (s * dy + dx * d) / d2;
        var cy1 = (-s * dx + dy * d) / d2;
        var dx0 = cx0 - x00;
        var dy0 = cy0 - y00;
        var dx1 = cx1 - x00;
        var dy1 = cy1 - y00;
        if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) {
            cx0 = cx1;
            cy0 = cy1;
        }
        return {
            cx: cx0,
            cy: cy0,
            x0: -ox,
            y0: -oy,
            x1: cx0 * (radius / r - 1),
            y1: cy0 * (radius / r - 1)
        };
    }
    function normalizeCornerRadius(cr) {
        var arr;
        if (isArray(cr)) {
            var len = cr.length;
            if (!len) {
                return cr;
            }
            if (len === 1) {
                arr = [cr[0], cr[0], 0, 0];
            }
            else if (len === 2) {
                arr = [cr[0], cr[0], cr[1], cr[1]];
            }
            else if (len === 3) {
                arr = cr.concat(cr[2]);
            }
            else {
                arr = cr;
            }
        }
        else {
            arr = [cr, cr, cr, cr];
        }
        return arr;
    }
    function buildPath$1(ctx, shape) {
        var _a;
        var radius = mathMax$3(shape.r, 0);
        var innerRadius = mathMax$3(shape.r0 || 0, 0);
        var hasRadius = radius > 0;
        var hasInnerRadius = innerRadius > 0;
        if (!hasRadius && !hasInnerRadius) {
            return;
        }
        if (!hasRadius) {
            radius = innerRadius;
            innerRadius = 0;
        }
        if (innerRadius > radius) {
            var tmp = radius;
            radius = innerRadius;
            innerRadius = tmp;
        }
        var startAngle = shape.startAngle, endAngle = shape.endAngle;
        if (isNaN(startAngle) || isNaN(endAngle)) {
            return;
        }
        var cx = shape.cx, cy = shape.cy;
        var clockwise = !!shape.clockwise;
        var arc = mathAbs$1(endAngle - startAngle);
        var mod = arc > PI2$5 && arc % PI2$5;
        mod > e && (arc = mod);
        if (!(radius > e)) {
            ctx.moveTo(cx, cy);
        }
        else if (arc > PI2$5 - e) {
            ctx.moveTo(cx + radius * mathCos$3(startAngle), cy + radius * mathSin$3(startAngle));
            ctx.arc(cx, cy, radius, startAngle, endAngle, !clockwise);
            if (innerRadius > e) {
                ctx.moveTo(cx + innerRadius * mathCos$3(endAngle), cy + innerRadius * mathSin$3(endAngle));
                ctx.arc(cx, cy, innerRadius, endAngle, startAngle, clockwise);
            }
        }
        else {
            var icrStart = void 0;
            var icrEnd = void 0;
            var ocrStart = void 0;
            var ocrEnd = void 0;
            var ocrs = void 0;
            var ocre = void 0;
            var icrs = void 0;
            var icre = void 0;
            var ocrMax = void 0;
            var icrMax = void 0;
            var limitedOcrMax = void 0;
            var limitedIcrMax = void 0;
            var xre = void 0;
            var yre = void 0;
            var xirs = void 0;
            var yirs = void 0;
            var xrs = radius * mathCos$3(startAngle);
            var yrs = radius * mathSin$3(startAngle);
            var xire = innerRadius * mathCos$3(endAngle);
            var yire = innerRadius * mathSin$3(endAngle);
            var hasArc = arc > e;
            if (hasArc) {
                var cornerRadius = shape.cornerRadius;
                if (cornerRadius) {
                    _a = normalizeCornerRadius(cornerRadius), icrStart = _a[0], icrEnd = _a[1], ocrStart = _a[2], ocrEnd = _a[3];
                }
                var halfRd = mathAbs$1(radius - innerRadius) / 2;
                ocrs = mathMin$3(halfRd, ocrStart);
                ocre = mathMin$3(halfRd, ocrEnd);
                icrs = mathMin$3(halfRd, icrStart);
                icre = mathMin$3(halfRd, icrEnd);
                limitedOcrMax = ocrMax = mathMax$3(ocrs, ocre);
                limitedIcrMax = icrMax = mathMax$3(icrs, icre);
                if (ocrMax > e || icrMax > e) {
                    xre = radius * mathCos$3(endAngle);
                    yre = radius * mathSin$3(endAngle);
                    xirs = innerRadius * mathCos$3(startAngle);
                    yirs = innerRadius * mathSin$3(startAngle);
                    if (arc < PI$2) {
                        var it_1 = intersect(xrs, yrs, xirs, yirs, xre, yre, xire, yire);
                        if (it_1) {
                            var x0 = xrs - it_1[0];
                            var y0 = yrs - it_1[1];
                            var x1 = xre - it_1[0];
                            var y1 = yre - it_1[1];
                            var a = 1 / mathSin$3(mathACos((x0 * x1 + y0 * y1) / (mathSqrt$3(x0 * x0 + y0 * y0) * mathSqrt$3(x1 * x1 + y1 * y1))) / 2);
                            var b = mathSqrt$3(it_1[0] * it_1[0] + it_1[1] * it_1[1]);
                            limitedOcrMax = mathMin$3(ocrMax, (radius - b) / (a + 1));
                            limitedIcrMax = mathMin$3(icrMax, (innerRadius - b) / (a - 1));
                        }
                    }
                }
            }
            if (!hasArc) {
                ctx.moveTo(cx + xrs, cy + yrs);
            }
            else if (limitedOcrMax > e) {
                var crStart = mathMin$3(ocrStart, limitedOcrMax);
                var crEnd = mathMin$3(ocrEnd, limitedOcrMax);
                var ct0 = computeCornerTangents(xirs, yirs, xrs, yrs, radius, crStart, clockwise);
                var ct1 = computeCornerTangents(xre, yre, xire, yire, radius, crEnd, clockwise);
                ctx.moveTo(cx + ct0.cx + ct0.x0, cy + ct0.cy + ct0.y0);
                if (limitedOcrMax < ocrMax && crStart === crEnd) {
                    ctx.arc(cx + ct0.cx, cy + ct0.cy, limitedOcrMax, mathATan2(ct0.y0, ct0.x0), mathATan2(ct1.y0, ct1.x0), !clockwise);
                }
                else {
                    crStart > 0 && ctx.arc(cx + ct0.cx, cy + ct0.cy, crStart, mathATan2(ct0.y0, ct0.x0), mathATan2(ct0.y1, ct0.x1), !clockwise);
                    ctx.arc(cx, cy, radius, mathATan2(ct0.cy + ct0.y1, ct0.cx + ct0.x1), mathATan2(ct1.cy + ct1.y1, ct1.cx + ct1.x1), !clockwise);
                    crEnd > 0 && ctx.arc(cx + ct1.cx, cy + ct1.cy, crEnd, mathATan2(ct1.y1, ct1.x1), mathATan2(ct1.y0, ct1.x0), !clockwise);
                }
            }
            else {
                ctx.moveTo(cx + xrs, cy + yrs);
                ctx.arc(cx, cy, radius, startAngle, endAngle, !clockwise);
            }
            if (!(innerRadius > e) || !hasArc) {
                ctx.lineTo(cx + xire, cy + yire);
            }
            else if (limitedIcrMax > e) {
                var crStart = mathMin$3(icrStart, limitedIcrMax);
                var crEnd = mathMin$3(icrEnd, limitedIcrMax);
                var ct0 = computeCornerTangents(xire, yire, xre, yre, innerRadius, -crEnd, clockwise);
                var ct1 = computeCornerTangents(xrs, yrs, xirs, yirs, innerRadius, -crStart, clockwise);
                ctx.lineTo(cx + ct0.cx + ct0.x0, cy + ct0.cy + ct0.y0);
                if (limitedIcrMax < icrMax && crStart === crEnd) {
                    ctx.arc(cx + ct0.cx, cy + ct0.cy, limitedIcrMax, mathATan2(ct0.y0, ct0.x0), mathATan2(ct1.y0, ct1.x0), !clockwise);
                }
                else {
                    crEnd > 0 && ctx.arc(cx + ct0.cx, cy + ct0.cy, crEnd, mathATan2(ct0.y0, ct0.x0), mathATan2(ct0.y1, ct0.x1), !clockwise);
                    ctx.arc(cx, cy, innerRadius, mathATan2(ct0.cy + ct0.y1, ct0.cx + ct0.x1), mathATan2(ct1.cy + ct1.y1, ct1.cx + ct1.x1), clockwise);
                    crStart > 0 && ctx.arc(cx + ct1.cx, cy + ct1.cy, crStart, mathATan2(ct1.y1, ct1.x1), mathATan2(ct1.y0, ct1.x0), !clockwise);
                }
            }
            else {
                ctx.lineTo(cx + xire, cy + yire);
                ctx.arc(cx, cy, innerRadius, endAngle, startAngle, clockwise);
            }
        }
        ctx.closePath();
    }

    var SectorShape = (function () {
        function SectorShape() {
            this.cx = 0;
            this.cy = 0;
            this.r0 = 0;
            this.r = 0;
            this.startAngle = 0;
            this.endAngle = Math.PI * 2;
            this.clockwise = true;
            this.cornerRadius = 0;
        }
        return SectorShape;
    }());
    var Sector = (function (_super) {
        __extends(Sector, _super);
        function Sector(opts) {
            return _super.call(this, opts) || this;
        }
        Sector.prototype.getDefaultShape = function () {
            return new SectorShape();
        };
        Sector.prototype.buildPath = function (ctx, shape) {
            buildPath$1(ctx, shape);
        };
        Sector.prototype.isZeroArea = function () {
            return this.shape.startAngle === this.shape.endAngle
                || this.shape.r === this.shape.r0;
        };
        return Sector;
    }(Path));
    Sector.prototype.type = 'sector';

    var RingShape = (function () {
        function RingShape() {
            this.cx = 0;
            this.cy = 0;
            this.r = 0;
            this.r0 = 0;
        }
        return RingShape;
    }());
    var Ring = (function (_super) {
        __extends(Ring, _super);
        function Ring(opts) {
            return _super.call(this, opts) || this;
        }
        Ring.prototype.getDefaultShape = function () {
            return new RingShape();
        };
        Ring.prototype.buildPath = function (ctx, shape) {
            var x = shape.cx;
            var y = shape.cy;
            var PI2 = Math.PI * 2;
            ctx.moveTo(x + shape.r, y);
            ctx.arc(x, y, shape.r, 0, PI2, false);
            ctx.moveTo(x + shape.r0, y);
            ctx.arc(x, y, shape.r0, 0, PI2, true);
        };
        return Ring;
    }(Path));
    Ring.prototype.type = 'ring';

    function smoothBezier(points, smooth, isLoop, constraint) {
        var cps = [];
        var v = [];
        var v1 = [];
        var v2 = [];
        var prevPoint;
        var nextPoint;
        var min$1;
        var max$1;
        if (constraint) {
            min$1 = [Infinity, Infinity];
            max$1 = [-Infinity, -Infinity];
            for (var i = 0, len = points.length; i < len; i++) {
                min(min$1, min$1, points[i]);
                max(max$1, max$1, points[i]);
            }
            min(min$1, min$1, constraint[0]);
            max(max$1, max$1, constraint[1]);
        }
        for (var i = 0, len = points.length; i < len; i++) {
            var point = points[i];
            if (isLoop) {
                prevPoint = points[i ? i - 1 : len - 1];
                nextPoint = points[(i + 1) % len];
            }
            else {
                if (i === 0 || i === len - 1) {
                    cps.push(clone$1(points[i]));
                    continue;
                }
                else {
                    prevPoint = points[i - 1];
                    nextPoint = points[i + 1];
                }
            }
            sub(v, nextPoint, prevPoint);
            scale(v, v, smooth);
            var d0 = distance(point, prevPoint);
            var d1 = distance(point, nextPoint);
            var sum = d0 + d1;
            if (sum !== 0) {
                d0 /= sum;
                d1 /= sum;
            }
            scale(v1, v, -d0);
            scale(v2, v, d1);
            var cp0 = add([], point, v1);
            var cp1 = add([], point, v2);
            if (constraint) {
                max(cp0, cp0, min$1);
                min(cp0, cp0, max$1);
                max(cp1, cp1, min$1);
                min(cp1, cp1, max$1);
            }
            cps.push(cp0);
            cps.push(cp1);
        }
        if (isLoop) {
            cps.push(cps.shift());
        }
        return cps;
    }

    function buildPath$2(ctx, shape, closePath) {
        var smooth = shape.smooth;
        var points = shape.points;
        if (points && points.length >= 2) {
            if (smooth) {
                var controlPoints = smoothBezier(points, smooth, closePath, shape.smoothConstraint);
                ctx.moveTo(points[0][0], points[0][1]);
                var len = points.length;
                for (var i = 0; i < (closePath ? len : len - 1); i++) {
                    var cp1 = controlPoints[i * 2];
                    var cp2 = controlPoints[i * 2 + 1];
                    var p = points[(i + 1) % len];
                    ctx.bezierCurveTo(cp1[0], cp1[1], cp2[0], cp2[1], p[0], p[1]);
                }
            }
            else {
                ctx.moveTo(points[0][0], points[0][1]);
                for (var i = 1, l = points.length; i < l; i++) {
                    ctx.lineTo(points[i][0], points[i][1]);
                }
            }
            closePath && ctx.closePath();
        }
    }

    var PolygonShape = (function () {
        function PolygonShape() {
            this.points = null;
            this.smooth = 0;
            this.smoothConstraint = null;
        }
        return PolygonShape;
    }());
    var Polygon = (function (_super) {
        __extends(Polygon, _super);
        function Polygon(opts) {
            return _super.call(this, opts) || this;
        }
        Polygon.prototype.getDefaultShape = function () {
            return new PolygonShape();
        };
        Polygon.prototype.buildPath = function (ctx, shape) {
            buildPath$2(ctx, shape, true);
        };
        return Polygon;
    }(Path));
    Polygon.prototype.type = 'polygon';

    var PolylineShape = (function () {
        function PolylineShape() {
            this.points = null;
            this.percent = 1;
            this.smooth = 0;
            this.smoothConstraint = null;
        }
        return PolylineShape;
    }());
    var Polyline = (function (_super) {
        __extends(Polyline, _super);
        function Polyline(opts) {
            return _super.call(this, opts) || this;
        }
        Polyline.prototype.getDefaultStyle = function () {
            return {
                stroke: '#000',
                fill: null
            };
        };
        Polyline.prototype.getDefaultShape = function () {
            return new PolylineShape();
        };
        Polyline.prototype.buildPath = function (ctx, shape) {
            buildPath$2(ctx, shape, false);
        };
        return Polyline;
    }(Path));
    Polyline.prototype.type = 'polyline';

    var subPixelOptimizeOutputShape$1 = {};
    var LineShape = (function () {
        function LineShape() {
            this.x1 = 0;
            this.y1 = 0;
            this.x2 = 0;
            this.y2 = 0;
            this.percent = 1;
        }
        return LineShape;
    }());
    var Line = (function (_super) {
        __extends(Line, _super);
        function Line(opts) {
            return _super.call(this, opts) || this;
        }
        Line.prototype.getDefaultStyle = function () {
            return {
                stroke: '#000',
                fill: null
            };
        };
        Line.prototype.getDefaultShape = function () {
            return new LineShape();
        };
        Line.prototype.buildPath = function (ctx, shape) {
            var x1;
            var y1;
            var x2;
            var y2;
            if (this.subPixelOptimize) {
                var optimizedShape = subPixelOptimizeLine(subPixelOptimizeOutputShape$1, shape, this.style);
                x1 = optimizedShape.x1;
                y1 = optimizedShape.y1;
                x2 = optimizedShape.x2;
                y2 = optimizedShape.y2;
            }
            else {
                x1 = shape.x1;
                y1 = shape.y1;
                x2 = shape.x2;
                y2 = shape.y2;
            }
            var percent = shape.percent;
            if (percent === 0) {
                return;
            }
            ctx.moveTo(x1, y1);
            if (percent < 1) {
                x2 = x1 * (1 - percent) + x2 * percent;
                y2 = y1 * (1 - percent) + y2 * percent;
            }
            ctx.lineTo(x2, y2);
        };
        Line.prototype.pointAt = function (p) {
            var shape = this.shape;
            return [
                shape.x1 * (1 - p) + shape.x2 * p,
                shape.y1 * (1 - p) + shape.y2 * p
            ];
        };
        return Line;
    }(Path));
    Line.prototype.type = 'line';

    var out = [];
    var BezierCurveShape = (function () {
        function BezierCurveShape() {
            this.x1 = 0;
            this.y1 = 0;
            this.x2 = 0;
            this.y2 = 0;
            this.cpx1 = 0;
            this.cpy1 = 0;
            this.percent = 1;
        }
        return BezierCurveShape;
    }());
    function someVectorAt(shape, t, isTangent) {
        var cpx2 = shape.cpx2;
        var cpy2 = shape.cpy2;
        if (cpx2 != null || cpy2 != null) {
            return [
                (isTangent ? cubicDerivativeAt : cubicAt)(shape.x1, shape.cpx1, shape.cpx2, shape.x2, t),
                (isTangent ? cubicDerivativeAt : cubicAt)(shape.y1, shape.cpy1, shape.cpy2, shape.y2, t)
            ];
        }
        else {
            return [
                (isTangent ? quadraticDerivativeAt : quadraticAt)(shape.x1, shape.cpx1, shape.x2, t),
                (isTangent ? quadraticDerivativeAt : quadraticAt)(shape.y1, shape.cpy1, shape.y2, t)
            ];
        }
    }
    var BezierCurve = (function (_super) {
        __extends(BezierCurve, _super);
        function BezierCurve(opts) {
            return _super.call(this, opts) || this;
        }
        BezierCurve.prototype.getDefaultStyle = function () {
            return {
                stroke: '#000',
                fill: null
            };
        };
        BezierCurve.prototype.getDefaultShape = function () {
            return new BezierCurveShape();
        };
        BezierCurve.prototype.buildPath = function (ctx, shape) {
            var x1 = shape.x1;
            var y1 = shape.y1;
            var x2 = shape.x2;
            var y2 = shape.y2;
            var cpx1 = shape.cpx1;
            var cpy1 = shape.cpy1;
            var cpx2 = shape.cpx2;
            var cpy2 = shape.cpy2;
            var percent = shape.percent;
            if (percent === 0) {
                return;
            }
            ctx.moveTo(x1, y1);
            if (cpx2 == null || cpy2 == null) {
                if (percent < 1) {
                    quadraticSubdivide(x1, cpx1, x2, percent, out);
                    cpx1 = out[1];
                    x2 = out[2];
                    quadraticSubdivide(y1, cpy1, y2, percent, out);
                    cpy1 = out[1];
                    y2 = out[2];
                }
                ctx.quadraticCurveTo(cpx1, cpy1, x2, y2);
            }
            else {
                if (percent < 1) {
                    cubicSubdivide(x1, cpx1, cpx2, x2, percent, out);
                    cpx1 = out[1];
                    cpx2 = out[2];
                    x2 = out[3];
                    cubicSubdivide(y1, cpy1, cpy2, y2, percent, out);
                    cpy1 = out[1];
                    cpy2 = out[2];
                    y2 = out[3];
                }
                ctx.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x2, y2);
            }
        };
        BezierCurve.prototype.pointAt = function (t) {
            return someVectorAt(this.shape, t, false);
        };
        BezierCurve.prototype.tangentAt = function (t) {
            var p = someVectorAt(this.shape, t, true);
            return normalize(p, p);
        };
        return BezierCurve;
    }(Path));
    BezierCurve.prototype.type = 'bezier-curve';

    var ArcShape = (function () {
        function ArcShape() {
            this.cx = 0;
            this.cy = 0;
            this.r = 0;
            this.startAngle = 0;
            this.endAngle = Math.PI * 2;
            this.clockwise = true;
        }
        return ArcShape;
    }());
    var Arc = (function (_super) {
        __extends(Arc, _super);
        function Arc(opts) {
            return _super.call(this, opts) || this;
        }
        Arc.prototype.getDefaultStyle = function () {
            return {
                stroke: '#000',
                fill: null
            };
        };
        Arc.prototype.getDefaultShape = function () {
            return new ArcShape();
        };
        Arc.prototype.buildPath = function (ctx, shape) {
            var x = shape.cx;
            var y = shape.cy;
            var r = Math.max(shape.r, 0);
            var startAngle = shape.startAngle;
            var endAngle = shape.endAngle;
            var clockwise = shape.clockwise;
            var unitX = Math.cos(startAngle);
            var unitY = Math.sin(startAngle);
            ctx.moveTo(unitX * r + x, unitY * r + y);
            ctx.arc(x, y, r, startAngle, endAngle, !clockwise);
        };
        return Arc;
    }(Path));
    Arc.prototype.type = 'arc';

    var CompoundPath = (function (_super) {
        __extends(CompoundPath, _super);
        function CompoundPath() {
            var _this = _super !== null && _super.apply(this, arguments) || this;
            _this.type = 'compound';
            return _this;
        }
        CompoundPath.prototype._updatePathDirty = function () {
            var paths = this.shape.paths;
            var dirtyPath = this.shapeChanged();
            for (var i = 0; i < paths.length; i++) {
                dirtyPath = dirtyPath || paths[i].shapeChanged();
            }
            if (dirtyPath) {
                this.dirtyShape();
            }
        };
        CompoundPath.prototype.beforeBrush = function () {
            this._updatePathDirty();
            var paths = this.shape.paths || [];
            var scale = this.getGlobalScale();
            for (var i = 0; i < paths.length; i++) {
                if (!paths[i].path) {
                    paths[i].createPathProxy();
                }
                paths[i].path.setScale(scale[0], scale[1], paths[i].segmentIgnoreThreshold);
            }
        };
        CompoundPath.prototype.buildPath = function (ctx, shape) {
            var paths = shape.paths || [];
            for (var i = 0; i < paths.length; i++) {
                paths[i].buildPath(ctx, paths[i].shape, true);
            }
        };
        CompoundPath.prototype.afterBrush = function () {
            var paths = this.shape.paths || [];
            for (var i = 0; i < paths.length; i++) {
                paths[i].pathUpdated();
            }
        };
        CompoundPath.prototype.getBoundingRect = function () {
            this._updatePathDirty.call(this);
            return Path.prototype.getBoundingRect.call(this);
        };
        return CompoundPath;
    }(Path));

    var Gradient = (function () {
        function Gradient(colorStops) {
            this.colorStops = colorStops || [];
        }
        Gradient.prototype.addColorStop = function (offset, color) {
            this.colorStops.push({
                offset: offset,
                color: color
            });
        };
        return Gradient;
    }());

    var LinearGradient = (function (_super) {
        __extends(LinearGradient, _super);
        function LinearGradient(x, y, x2, y2, colorStops, globalCoord) {
            var _this = _super.call(this, colorStops) || this;
            _this.x = x == null ? 0 : x;
            _this.y = y == null ? 0 : y;
            _this.x2 = x2 == null ? 1 : x2;
            _this.y2 = y2 == null ? 0 : y2;
            _this.type = 'linear';
            _this.global = globalCoord || false;
            return _this;
        }
        return LinearGradient;
    }(Gradient));

    var RadialGradient = (function (_super) {
        __extends(RadialGradient, _super);
        function RadialGradient(x, y, r, colorStops, globalCoord) {
            var _this = _super.call(this, colorStops) || this;
            _this.x = x == null ? 0.5 : x;
            _this.y = y == null ? 0.5 : y;
            _this.r = r == null ? 0.5 : r;
            _this.type = 'radial';
            _this.global = globalCoord || false;
            return _this;
        }
        return RadialGradient;
    }(Gradient));

    var extent = [0, 0];
    var extent2 = [0, 0];
    var minTv$1 = new Point();
    var maxTv$1 = new Point();
    var OrientedBoundingRect = (function () {
        function OrientedBoundingRect(rect, transform) {
            this._corners = [];
            this._axes = [];
            this._origin = [0, 0];
            for (var i = 0; i < 4; i++) {
                this._corners[i] = new Point();
            }
            for (var i = 0; i < 2; i++) {
                this._axes[i] = new Point();
            }
            if (rect) {
                this.fromBoundingRect(rect, transform);
            }
        }
        OrientedBoundingRect.prototype.fromBoundingRect = function (rect, transform) {
            var corners = this._corners;
            var axes = this._axes;
            var x = rect.x;
            var y = rect.y;
            var x2 = x + rect.width;
            var y2 = y + rect.height;
            corners[0].set(x, y);
            corners[1].set(x2, y);
            corners[2].set(x2, y2);
            corners[3].set(x, y2);
            if (transform) {
                for (var i = 0; i < 4; i++) {
                    corners[i].transform(transform);
                }
            }
            Point.sub(axes[0], corners[1], corners[0]);
            Point.sub(axes[1], corners[3], corners[0]);
            axes[0].normalize();
            axes[1].normalize();
            for (var i = 0; i < 2; i++) {
                this._origin[i] = axes[i].dot(corners[0]);
            }
        };
        OrientedBoundingRect.prototype.intersect = function (other, mtv) {
            var overlapped = true;
            var noMtv = !mtv;
            minTv$1.set(Infinity, Infinity);
            maxTv$1.set(0, 0);
            if (!this._intersectCheckOneSide(this, other, minTv$1, maxTv$1, noMtv, 1)) {
                overlapped = false;
                if (noMtv) {
                    return overlapped;
                }
            }
            if (!this._intersectCheckOneSide(other, this, minTv$1, maxTv$1, noMtv, -1)) {
                overlapped = false;
                if (noMtv) {
                    return overlapped;
                }
            }
            if (!noMtv) {
                Point.copy(mtv, overlapped ? minTv$1 : maxTv$1);
            }
            return overlapped;
        };
        OrientedBoundingRect.prototype._intersectCheckOneSide = function (self, other, minTv, maxTv, noMtv, inverse) {
            var overlapped = true;
            for (var i = 0; i < 2; i++) {
                var axis = this._axes[i];
                this._getProjMinMaxOnAxis(i, self._corners, extent);
                this._getProjMinMaxOnAxis(i, other._corners, extent2);
                if (extent[1] < extent2[0] || extent[0] > extent2[1]) {
                    overlapped = false;
                    if (noMtv) {
                        return overlapped;
                    }
                    var dist0 = Math.abs(extent2[0] - extent[1]);
                    var dist1 = Math.abs(extent[0] - extent2[1]);
                    if (Math.min(dist0, dist1) > maxTv.len()) {
                        if (dist0 < dist1) {
                            Point.scale(maxTv, axis, -dist0 * inverse);
                        }
                        else {
                            Point.scale(maxTv, axis, dist1 * inverse);
                        }
                    }
                }
                else if (minTv) {
                    var dist0 = Math.abs(extent2[0] - extent[1]);
                    var dist1 = Math.abs(extent[0] - extent2[1]);
                    if (Math.min(dist0, dist1) < minTv.len()) {
                        if (dist0 < dist1) {
                            Point.scale(minTv, axis, dist0 * inverse);
                        }
                        else {
                            Point.scale(minTv, axis, -dist1 * inverse);
                        }
                    }
                }
            }
            return overlapped;
        };
        OrientedBoundingRect.prototype._getProjMinMaxOnAxis = function (dim, corners, out) {
            var axis = this._axes[dim];
            var origin = this._origin;
            var proj = corners[0].dot(axis) + origin[dim];
            var min = proj;
            var max = proj;
            for (var i = 1; i < corners.length; i++) {
                var proj_1 = corners[i].dot(axis) + origin[dim];
                min = Math.min(proj_1, min);
                max = Math.max(proj_1, max);
            }
            out[0] = min;
            out[1] = max;
        };
        return OrientedBoundingRect;
    }());

    var m = [];
    var IncrementalDisplayable = (function (_super) {
        __extends(IncrementalDisplayable, _super);
        function IncrementalDisplayable() {
            var _this = _super !== null && _super.apply(this, arguments) || this;
            _this.notClear = true;
            _this.incremental = true;
            _this._displayables = [];
            _this._temporaryDisplayables = [];
            _this._cursor = 0;
            return _this;
        }
        IncrementalDisplayable.prototype.traverse = function (cb, context) {
            cb.call(context, this);
        };
        IncrementalDisplayable.prototype.useStyle = function () {
            this.style = {};
        };
        IncrementalDisplayable.prototype.getCursor = function () {
            return this._cursor;
        };
        IncrementalDisplayable.prototype.innerAfterBrush = function () {
            this._cursor = this._displayables.length;
        };
        IncrementalDisplayable.prototype.clearDisplaybles = function () {
            this._displayables = [];
            this._temporaryDisplayables = [];
            this._cursor = 0;
            this.markRedraw();
            this.notClear = false;
        };
        IncrementalDisplayable.prototype.clearTemporalDisplayables = function () {
            this._temporaryDisplayables = [];
        };
        IncrementalDisplayable.prototype.addDisplayable = function (displayable, notPersistent) {
            if (notPersistent) {
                this._temporaryDisplayables.push(displayable);
            }
            else {
                this._displayables.push(displayable);
            }
            this.markRedraw();
        };
        IncrementalDisplayable.prototype.addDisplayables = function (displayables, notPersistent) {
            notPersistent = notPersistent || false;
            for (var i = 0; i < displayables.length; i++) {
                this.addDisplayable(displayables[i], notPersistent);
            }
        };
        IncrementalDisplayable.prototype.getDisplayables = function () {
            return this._displayables;
        };
        IncrementalDisplayable.prototype.getTemporalDisplayables = function () {
            return this._temporaryDisplayables;
        };
        IncrementalDisplayable.prototype.eachPendingDisplayable = function (cb) {
            for (var i = this._cursor; i < this._displayables.length; i++) {
                cb && cb(this._displayables[i]);
            }
            for (var i = 0; i < this._temporaryDisplayables.length; i++) {
                cb && cb(this._temporaryDisplayables[i]);
            }
        };
        IncrementalDisplayable.prototype.update = function () {
            this.updateTransform();
            for (var i = this._cursor; i < this._displayables.length; i++) {
                var displayable = this._displayables[i];
                displayable.parent = this;
                displayable.update();
                displayable.parent = null;
            }
            for (var i = 0; i < this._temporaryDisplayables.length; i++) {
                var displayable = this._temporaryDisplayables[i];
                displayable.parent = this;
                displayable.update();
                displayable.parent = null;
            }
        };
        IncrementalDisplayable.prototype.getBoundingRect = function () {
            if (!this._rect) {
                var rect = new BoundingRect(Infinity, Infinity, -Infinity, -Infinity);
                for (var i = 0; i < this._displayables.length; i++) {
                    var displayable = this._displayables[i];
                    var childRect = displayable.getBoundingRect().clone();
                    if (displayable.needLocalTransform()) {
                        childRect.applyTransform(displayable.getLocalTransform(m));
                    }
                    rect.union(childRect);
                }
                this._rect = rect;
            }
            return this._rect;
        };
        IncrementalDisplayable.prototype.contain = function (x, y) {
            var localPos = this.transformCoordToLocal(x, y);
            var rect = this.getBoundingRect();
            if (rect.contain(localPos[0], localPos[1])) {
                for (var i = 0; i < this._displayables.length; i++) {
                    var displayable = this._displayables[i];
                    if (displayable.contain(x, y)) {
                        return true;
                    }
                }
            }
            return false;
        };
        return IncrementalDisplayable;
    }(Displayable));

    var transitionStore = makeInner();
    /**
     * Return null if animation is disabled.
     */

    function getAnimationConfig(animationType, animatableModel, dataIndex, // Extra opts can override the option in animatable model.
    extraOpts, // TODO It's only for pictorial bar now.
    extraDelayParams) {
      var animationPayload; // Check if there is global animation configuration from dataZoom/resize can override the config in option.
      // If animation is enabled. Will use this animation config in payload.
      // If animation is disabled. Just ignore it.

      if (animatableModel && animatableModel.ecModel) {
        var updatePayload = animatableModel.ecModel.getUpdatePayload();
        animationPayload = updatePayload && updatePayload.animation;
      }

      var animationEnabled = animatableModel && animatableModel.isAnimationEnabled();
      var isUpdate = animationType === 'update';

      if (animationEnabled) {
        var duration = void 0;
        var easing = void 0;
        var delay = void 0;

        if (extraOpts) {
          duration = retrieve2(extraOpts.duration, 200);
          easing = retrieve2(extraOpts.easing, 'cubicOut');
          delay = 0;
        } else {
          duration = animatableModel.getShallow(isUpdate ? 'animationDurationUpdate' : 'animationDuration');
          easing = animatableModel.getShallow(isUpdate ? 'animationEasingUpdate' : 'animationEasing');
          delay = animatableModel.getShallow(isUpdate ? 'animationDelayUpdate' : 'animationDelay');
        } // animation from payload has highest priority.


        if (animationPayload) {
          animationPayload.duration != null && (duration = animationPayload.duration);
          animationPayload.easing != null && (easing = animationPayload.easing);
          animationPayload.delay != null && (delay = animationPayload.delay);
        }

        if (isFunction(delay)) {
          delay = delay(dataIndex, extraDelayParams);
        }

        if (isFunction(duration)) {
          duration = duration(dataIndex);
        }

        var config = {
          duration: duration || 0,
          delay: delay,
          easing: easing
        };
        return config;
      } else {
        return null;
      }
    }

    function animateOrSetProps(animationType, el, props, animatableModel, dataIndex, cb, during) {
      var isFrom = false;
      var removeOpt;

      if (isFunction(dataIndex)) {
        during = cb;
        cb = dataIndex;
        dataIndex = null;
      } else if (isObject(dataIndex)) {
        cb = dataIndex.cb;
        during = dataIndex.during;
        isFrom = dataIndex.isFrom;
        removeOpt = dataIndex.removeOpt;
        dataIndex = dataIndex.dataIndex;
      }

      var isRemove = animationType === 'leave';

      if (!isRemove) {
        // Must stop the remove animation.
        el.stopAnimation('leave');
      }

      var animationConfig = getAnimationConfig(animationType, animatableModel, dataIndex, isRemove ? removeOpt || {} : null, animatableModel && animatableModel.getAnimationDelayParams ? animatableModel.getAnimationDelayParams(el, dataIndex) : null);

      if (animationConfig && animationConfig.duration > 0) {
        var duration = animationConfig.duration;
        var animationDelay = animationConfig.delay;
        var animationEasing = animationConfig.easing;
        var animateConfig = {
          duration: duration,
          delay: animationDelay || 0,
          easing: animationEasing,
          done: cb,
          force: !!cb || !!during,
          // Set to final state in update/init animation.
          // So the post processing based on the path shape can be done correctly.
          setToFinal: !isRemove,
          scope: animationType,
          during: during
        };
        isFrom ? el.animateFrom(props, animateConfig) : el.animateTo(props, animateConfig);
      } else {
        el.stopAnimation(); // If `isFrom`, the props is the "from" props.

        !isFrom && el.attr(props); // Call during at least once.

        during && during(1);
        cb && cb();
      }
    }
    /**
     * Update graphic element properties with or without animation according to the
     * configuration in series.
     *
     * Caution: this method will stop previous animation.
     * So do not use this method to one element twice before
     * animation starts, unless you know what you are doing.
     * @example
     *     graphic.updateProps(el, {
     *         position: [100, 100]
     *     }, seriesModel, dataIndex, function () { console.log('Animation done!'); });
     *     // Or
     *     graphic.updateProps(el, {
     *         position: [100, 100]
     *     }, seriesModel, function () { console.log('Animation done!'); });
     */


    function updateProps(el, props, // TODO: TYPE AnimatableModel
    animatableModel, dataIndex, cb, during) {
      animateOrSetProps('update', el, props, animatableModel, dataIndex, cb, during);
    }
    /**
     * Init graphic element properties with or without animation according to the
     * configuration in series.
     *
     * Caution: this method will stop previous animation.
     * So do not use this method to one element twice before
     * animation starts, unless you know what you are doing.
     */

    function initProps(el, props, animatableModel, dataIndex, cb, during) {
      animateOrSetProps('enter', el, props, animatableModel, dataIndex, cb, during);
    }
    /**
     * If element is removed.
     * It can determine if element is having remove animation.
     */

    function isElementRemoved(el) {
      if (!el.__zr) {
        return true;
      }

      for (var i = 0; i < el.animators.length; i++) {
        var animator = el.animators[i];

        if (animator.scope === 'leave') {
          return true;
        }
      }

      return false;
    }
    /**
     * Remove graphic element
     */

    function removeElement(el, props, animatableModel, dataIndex, cb, during) {
      // Don't do remove animation twice.
      if (isElementRemoved(el)) {
        return;
      }

      animateOrSetProps('leave', el, props, animatableModel, dataIndex, cb, during);
    }

    function fadeOutDisplayable(el, animatableModel, dataIndex, done) {
      el.removeTextContent();
      el.removeTextGuideLine();
      removeElement(el, {
        style: {
          opacity: 0
        }
      }, animatableModel, dataIndex, done);
    }

    function removeElementWithFadeOut(el, animatableModel, dataIndex) {
      function doRemove() {
        el.parent && el.parent.remove(el);
      } // Hide label and labelLine first
      // TODO Also use fade out animation?


      if (!el.isGroup) {
        fadeOutDisplayable(el, animatableModel, dataIndex, doRemove);
      } else {
        el.traverse(function (disp) {
          if (!disp.isGroup) {
            // Can invoke doRemove multiple times.
            fadeOutDisplayable(disp, animatableModel, dataIndex, doRemove);
          }
        });
      }
    }
    /**
     * Save old style for style transition in universalTransition module.
     * It's used when element will be reused in each render.
     * For chart like map, heatmap, which will always create new element.
     * We don't need to save this because universalTransition can get old style from the old element
     */

    function saveOldStyle(el) {
      transitionStore(el).oldStyle = el.style;
    }

    var mathMax$4 = Math.max;
    var mathMin$4 = Math.min;
    var _customShapeMap = {};
    /**
     * Extend shape with parameters
     */

    function extendShape(opts) {
      return Path.extend(opts);
    }
    var extendPathFromString = extendFromString;
    /**
     * Extend path
     */

    function extendPath(pathData, opts) {
      return extendPathFromString(pathData, opts);
    }
    /**
     * Register a user defined shape.
     * The shape class can be fetched by `getShapeClass`
     * This method will overwrite the registered shapes, including
     * the registered built-in shapes, if using the same `name`.
     * The shape can be used in `custom series` and
     * `graphic component` by declaring `{type: name}`.
     *
     * @param name
     * @param ShapeClass Can be generated by `extendShape`.
     */

    function registerShape(name, ShapeClass) {
      _customShapeMap[name] = ShapeClass;
    }
    /**
     * Find shape class registered by `registerShape`. Usually used in
     * fetching user defined shape.
     *
     * [Caution]:
     * (1) This method **MUST NOT be used inside echarts !!!**, unless it is prepared
     * to use user registered shapes.
     * Because the built-in shape (see `getBuiltInShape`) will be registered by
     * `registerShape` by default. That enables users to get both built-in
     * shapes as well as the shapes belonging to themsleves. But users can overwrite
     * the built-in shapes by using names like 'circle', 'rect' via calling
     * `registerShape`. So the echarts inner featrues should not fetch shapes from here
     * in case that it is overwritten by users, except that some features, like
     * `custom series`, `graphic component`, do it deliberately.
     *
     * (2) In the features like `custom series`, `graphic component`, the user input
     * `{tpye: 'xxx'}` does not only specify shapes but also specify other graphic
     * elements like `'group'`, `'text'`, `'image'` or event `'path'`. Those names
     * are reserved names, that is, if some user registers a shape named `'image'`,
     * the shape will not be used. If we intending to add some more reserved names
     * in feature, that might bring break changes (disable some existing user shape
     * names). But that case probably rarely happens. So we don't make more mechanism
     * to resolve this issue here.
     *
     * @param name
     * @return The shape class. If not found, return nothing.
     */

    function getShapeClass(name) {
      if (_customShapeMap.hasOwnProperty(name)) {
        return _customShapeMap[name];
      }
    }
    /**
     * Create a path element from path data string
     * @param pathData
     * @param opts
     * @param rect
     * @param layout 'center' or 'cover' default to be cover
     */

    function makePath(pathData, opts, rect, layout) {
      var path = createFromString(pathData, opts);

      if (rect) {
        if (layout === 'center') {
          rect = centerGraphic(rect, path.getBoundingRect());
        }

        resizePath(path, rect);
      }

      return path;
    }
    /**
     * Create a image element from image url
     * @param imageUrl image url
     * @param opts options
     * @param rect constrain rect
     * @param layout 'center' or 'cover'. Default to be 'cover'
     */

    function makeImage(imageUrl, rect, layout) {
      var zrImg = new ZRImage({
        style: {
          image: imageUrl,
          x: rect.x,
          y: rect.y,
          width: rect.width,
          height: rect.height
        },
        onload: function (img) {
          if (layout === 'center') {
            var boundingRect = {
              width: img.width,
              height: img.height
            };
            zrImg.setStyle(centerGraphic(rect, boundingRect));
          }
        }
      });
      return zrImg;
    }
    /**
     * Get position of centered element in bounding box.
     *
     * @param  rect         element local bounding box
     * @param  boundingRect constraint bounding box
     * @return element position containing x, y, width, and height
     */

    function centerGraphic(rect, boundingRect) {
      // Set rect to center, keep width / height ratio.
      var aspect = boundingRect.width / boundingRect.height;
      var width = rect.height * aspect;
      var height;

      if (width <= rect.width) {
        height = rect.height;
      } else {
        width = rect.width;
        height = width / aspect;
      }

      var cx = rect.x + rect.width / 2;
      var cy = rect.y + rect.height / 2;
      return {
        x: cx - width / 2,
        y: cy - height / 2,
        width: width,
        height: height
      };
    }

    var mergePath$1 = mergePath;
    /**
     * Resize a path to fit the rect
     * @param path
     * @param rect
     */

    function resizePath(path, rect) {
      if (!path.applyTransform) {
        return;
      }

      var pathRect = path.getBoundingRect();
      var m = pathRect.calculateTransform(rect);
      path.applyTransform(m);
    }
    /**
     * Sub pixel optimize line for canvas
     */

    function subPixelOptimizeLine$1(shape, lineWidth) {
      subPixelOptimizeLine(shape, shape, {
        lineWidth: lineWidth
      });
      return shape;
    }
    /**
     * Get transform matrix of target (param target),
     * in coordinate of its ancestor (param ancestor)
     *
     * @param target
     * @param [ancestor]
     */

    function getTransform(target, ancestor) {
      var mat = identity([]);

      while (target && target !== ancestor) {
        mul$1(mat, target.getLocalTransform(), mat);
        target = target.parent;
      }

      return mat;
    }

    function isNotGroup(el) {
      return !el.isGroup;
    }

    function isPath(el) {
      return el.shape != null;
    }
    /**
     * Apply group transition animation from g1 to g2.
     * If no animatableModel, no animation.
     */


    function groupTransition(g1, g2, animatableModel) {
      if (!g1 || !g2) {
        return;
      }

      function getElMap(g) {
        var elMap = {};
        g.traverse(function (el) {
          if (isNotGroup(el) && el.anid) {
            elMap[el.anid] = el;
          }
        });
        return elMap;
      }

      function getAnimatableProps(el) {
        var obj = {
          x: el.x,
          y: el.y,
          rotation: el.rotation
        };

        if (isPath(el)) {
          obj.shape = extend({}, el.shape);
        }

        return obj;
      }

      var elMap1 = getElMap(g1);
      g2.traverse(function (el) {
        if (isNotGroup(el) && el.anid) {
          var oldEl = elMap1[el.anid];

          if (oldEl) {
            var newProp = getAnimatableProps(el);
            el.attr(getAnimatableProps(oldEl));
            updateProps(el, newProp, animatableModel, getECData(el).dataIndex);
          }
        }
      });
    }
    function clipPointsByRect(points, rect) {
      // FIXME: This way might be incorrect when graphic clipped by a corner
      // and when element has a border.
      return map(points, function (point) {
        var x = point[0];
        x = mathMax$4(x, rect.x);
        x = mathMin$4(x, rect.x + rect.width);
        var y = point[1];
        y = mathMax$4(y, rect.y);
        y = mathMin$4(y, rect.y + rect.height);
        return [x, y];
      });
    }
    /**
     * Return a new clipped rect. If rect size are negative, return undefined.
     */

    function clipRectByRect(targetRect, rect) {
      var x = mathMax$4(targetRect.x, rect.x);
      var x2 = mathMin$4(targetRect.x + targetRect.width, rect.x + rect.width);
      var y = mathMax$4(targetRect.y, rect.y);
      var y2 = mathMin$4(targetRect.y + targetRect.height, rect.y + rect.height); // If the total rect is cliped, nothing, including the border,
      // should be painted. So return undefined.

      if (x2 >= x && y2 >= y) {
        return {
          x: x,
          y: y,
          width: x2 - x,
          height: y2 - y
        };
      }
    }
    function createIcon(iconStr, // Support 'image://' or 'path://' or direct svg path.
    opt, rect) {
      var innerOpts = extend({
        rectHover: true
      }, opt);
      var style = innerOpts.style = {
        strokeNoScale: true
      };
      rect = rect || {
        x: -1,
        y: -1,
        width: 2,
        height: 2
      };

      if (iconStr) {
        return iconStr.indexOf('image://') === 0 ? (style.image = iconStr.slice(8), defaults(style, rect), new ZRImage(innerOpts)) : makePath(iconStr.replace('path://', ''), innerOpts, rect, 'center');
      }
    }

    function setTooltipConfig(opt) {
      var itemTooltipOption = opt.itemTooltipOption;
      var componentModel = opt.componentModel;
      var itemName = opt.itemName;
      var itemTooltipOptionObj = isString(itemTooltipOption) ? {
        formatter: itemTooltipOption
      } : itemTooltipOption;
      var mainType = componentModel.mainType;
      var componentIndex = componentModel.componentIndex;
      var formatterParams = {
        componentType: mainType,
        name: itemName,
        $vars: ['name']
      };
      formatterParams[mainType + 'Index'] = componentIndex;
      var formatterParamsExtra = opt.formatterParamsExtra;

      if (formatterParamsExtra) {
        each(keys(formatterParamsExtra), function (key) {
          if (!hasOwn(formatterParams, key)) {
            formatterParams[key] = formatterParamsExtra[key];
            formatterParams.$vars.push(key);
          }
        });
      }

      var ecData = getECData(opt.el);
      ecData.componentMainType = mainType;
      ecData.componentIndex = componentIndex;
      ecData.tooltipConfig = {
        name: itemName,
        option: defaults({
          content: itemName,
          formatterParams: formatterParams
        }, itemTooltipOptionObj)
      };
    }

    function traverseElement(el, cb) {
      var stopped; // TODO
      // Polyfill for fixing zrender group traverse don't visit it's root issue.

      if (el.isGroup) {
        stopped = cb(el);
      }

      if (!stopped) {
        el.traverse(cb);
      }
    }

    function traverseElements(els, cb) {
      if (els) {
        if (isArray(els)) {
          for (var i = 0; i < els.length; i++) {
            traverseElement(els[i], cb);
          }
        } else {
          traverseElement(els, cb);
        }
      }
    } // Register built-in shapes. These shapes might be overwritten
    // by users, although we do not recommend that.

    registerShape('circle', Circle);
    registerShape('ellipse', Ellipse);
    registerShape('sector', Sector);
    registerShape('ring', Ring);
    registerShape('polygon', Polygon);
    registerShape('polyline', Polyline);
    registerShape('rect', Rect);
    registerShape('line', Line);
    registerShape('bezierCurve', BezierCurve);
    registerShape('arc', Arc);

    var EMPTY_OBJ = {};
    function setLabelText(label, labelTexts) {
      for (var i = 0; i < SPECIAL_STATES.length; i++) {
        var stateName = SPECIAL_STATES[i];
        var text = labelTexts[stateName];
        var state = label.ensureState(stateName);
        state.style = state.style || {};
        state.style.text = text;
      }

      var oldStates = label.currentStates.slice();
      label.clearStates(true);
      label.setStyle({
        text: labelTexts.normal
      });
      label.useStates(oldStates, true);
    }

    function getLabelText(opt, stateModels, interpolatedValue) {
      var labelFetcher = opt.labelFetcher;
      var labelDataIndex = opt.labelDataIndex;
      var labelDimIndex = opt.labelDimIndex;
      var normalModel = stateModels.normal;
      var baseText;

      if (labelFetcher) {
        baseText = labelFetcher.getFormattedLabel(labelDataIndex, 'normal', null, labelDimIndex, normalModel && normalModel.get('formatter'), interpolatedValue != null ? {
          interpolatedValue: interpolatedValue
        } : null);
      }

      if (baseText == null) {
        baseText = isFunction(opt.defaultText) ? opt.defaultText(labelDataIndex, opt, interpolatedValue) : opt.defaultText;
      }

      var statesText = {
        normal: baseText
      };

      for (var i = 0; i < SPECIAL_STATES.length; i++) {
        var stateName = SPECIAL_STATES[i];
        var stateModel = stateModels[stateName];
        statesText[stateName] = retrieve2(labelFetcher ? labelFetcher.getFormattedLabel(labelDataIndex, stateName, null, labelDimIndex, stateModel && stateModel.get('formatter')) : null, baseText);
      }

      return statesText;
    }

    function setLabelStyle(targetEl, labelStatesModels, opt, stateSpecified // TODO specified position?
    ) {
      opt = opt || EMPTY_OBJ;
      var isSetOnText = targetEl instanceof ZRText;
      var needsCreateText = false;

      for (var i = 0; i < DISPLAY_STATES.length; i++) {
        var stateModel = labelStatesModels[DISPLAY_STATES[i]];

        if (stateModel && stateModel.getShallow('show')) {
          needsCreateText = true;
          break;
        }
      }

      var textContent = isSetOnText ? targetEl : targetEl.getTextContent();

      if (needsCreateText) {
        if (!isSetOnText) {
          // Reuse the previous
          if (!textContent) {
            textContent = new ZRText();
            targetEl.setTextContent(textContent);
          } // Use same state proxy


          if (targetEl.stateProxy) {
            textContent.stateProxy = targetEl.stateProxy;
          }
        }

        var labelStatesTexts = getLabelText(opt, labelStatesModels);
        var normalModel = labelStatesModels.normal;
        var showNormal = !!normalModel.getShallow('show');
        var normalStyle = createTextStyle(normalModel, stateSpecified && stateSpecified.normal, opt, false, !isSetOnText);
        normalStyle.text = labelStatesTexts.normal;

        if (!isSetOnText) {
          // Always create new
          targetEl.setTextConfig(createTextConfig(normalModel, opt, false));
        }

        for (var i = 0; i < SPECIAL_STATES.length; i++) {
          var stateName = SPECIAL_STATES[i];
          var stateModel = labelStatesModels[stateName];

          if (stateModel) {
            var stateObj = textContent.ensureState(stateName);
            var stateShow = !!retrieve2(stateModel.getShallow('show'), showNormal);

            if (stateShow !== showNormal) {
              stateObj.ignore = !stateShow;
            }

            stateObj.style = createTextStyle(stateModel, stateSpecified && stateSpecified[stateName], opt, true, !isSetOnText);
            stateObj.style.text = labelStatesTexts[stateName];

            if (!isSetOnText) {
              var targetElEmphasisState = targetEl.ensureState(stateName);
              targetElEmphasisState.textConfig = createTextConfig(stateModel, opt, true);
            }
          }
        } // PENDING: if there is many requirements that emphasis position
        // need to be different from normal position, we might consider
        // auto silent is those cases.


        textContent.silent = !!normalModel.getShallow('silent'); // Keep x and y

        if (textContent.style.x != null) {
          normalStyle.x = textContent.style.x;
        }

        if (textContent.style.y != null) {
          normalStyle.y = textContent.style.y;
        }

        textContent.ignore = !showNormal; // Always create new style.

        textContent.useStyle(normalStyle);
        textContent.dirty();

        if (opt.enableTextSetter) {
          labelInner(textContent).setLabelText = function (interpolatedValue) {
            var labelStatesTexts = getLabelText(opt, labelStatesModels, interpolatedValue);
            setLabelText(textContent, labelStatesTexts);
          };
        }
      } else if (textContent) {
        // Not display rich text.
        textContent.ignore = true;
      }

      targetEl.dirty();
    }
    function getLabelStatesModels(itemModel, labelName) {
      labelName = labelName || 'label';
      var statesModels = {
        normal: itemModel.getModel(labelName)
      };

      for (var i = 0; i < SPECIAL_STATES.length; i++) {
        var stateName = SPECIAL_STATES[i];
        statesModels[stateName] = itemModel.getModel([stateName, labelName]);
      }

      return statesModels;
    }
    /**
     * Set basic textStyle properties.
     */

    function createTextStyle(textStyleModel, specifiedTextStyle, // Fixed style in the code. Can't be set by model.
    opt, isNotNormal, isAttached // If text is attached on an element. If so, auto color will handling in zrender.
    ) {
      var textStyle = {};
      setTextStyleCommon(textStyle, textStyleModel, opt, isNotNormal, isAttached);
      specifiedTextStyle && extend(textStyle, specifiedTextStyle); // textStyle.host && textStyle.host.dirty && textStyle.host.dirty(false);

      return textStyle;
    }
    function createTextConfig(textStyleModel, opt, isNotNormal) {
      opt = opt || {};
      var textConfig = {};
      var labelPosition;
      var labelRotate = textStyleModel.getShallow('rotate');
      var labelDistance = retrieve2(textStyleModel.getShallow('distance'), isNotNormal ? null : 5);
      var labelOffset = textStyleModel.getShallow('offset');
      labelPosition = textStyleModel.getShallow('position') || (isNotNormal ? null : 'inside'); // 'outside' is not a valid zr textPostion value, but used
      // in bar series, and magric type should be considered.

      labelPosition === 'outside' && (labelPosition = opt.defaultOutsidePosition || 'top');

      if (labelPosition != null) {
        textConfig.position = labelPosition;
      }

      if (labelOffset != null) {
        textConfig.offset = labelOffset;
      }

      if (labelRotate != null) {
        labelRotate *= Math.PI / 180;
        textConfig.rotation = labelRotate;
      }

      if (labelDistance != null) {
        textConfig.distance = labelDistance;
      } // fill and auto is determined by the color of path fill if it's not specified by developers.


      textConfig.outsideFill = textStyleModel.get('color') === 'inherit' ? opt.inheritColor || null : 'auto';
      return textConfig;
    }
    /**
     * The uniform entry of set text style, that is, retrieve style definitions
     * from `model` and set to `textStyle` object.
     *
     * Never in merge mode, but in overwrite mode, that is, all of the text style
     * properties will be set. (Consider the states of normal and emphasis and
     * default value can be adopted, merge would make the logic too complicated
     * to manage.)
     */

    function setTextStyleCommon(textStyle, textStyleModel, opt, isNotNormal, isAttached) {
      // Consider there will be abnormal when merge hover style to normal style if given default value.
      opt = opt || EMPTY_OBJ;
      var ecModel = textStyleModel.ecModel;
      var globalTextStyle = ecModel && ecModel.option.textStyle; // Consider case:
      // {
      //     data: [{
      //         value: 12,
      //         label: {
      //             rich: {
      //                 // no 'a' here but using parent 'a'.
      //             }
      //         }
      //     }],
      //     rich: {
      //         a: { ... }
      //     }
      // }

      var richItemNames = getRichItemNames(textStyleModel);
      var richResult;

      if (richItemNames) {
        richResult = {};

        for (var name_1 in richItemNames) {
          if (richItemNames.hasOwnProperty(name_1)) {
            // Cascade is supported in rich.
            var richTextStyle = textStyleModel.getModel(['rich', name_1]); // In rich, never `disableBox`.
            // FIXME: consider `label: {formatter: '{a|xx}', color: 'blue', rich: {a: {}}}`,
            // the default color `'blue'` will not be adopted if no color declared in `rich`.
            // That might confuses users. So probably we should put `textStyleModel` as the
            // root ancestor of the `richTextStyle`. But that would be a break change.

            setTokenTextStyle(richResult[name_1] = {}, richTextStyle, globalTextStyle, opt, isNotNormal, isAttached, false, true);
          }
        }
      }

      if (richResult) {
        textStyle.rich = richResult;
      }

      var overflow = textStyleModel.get('overflow');

      if (overflow) {
        textStyle.overflow = overflow;
      }

      var margin = textStyleModel.get('minMargin');

      if (margin != null) {
        textStyle.margin = margin;
      }

      setTokenTextStyle(textStyle, textStyleModel, globalTextStyle, opt, isNotNormal, isAttached, true, false);
    } // Consider case:
    // {
    //     data: [{
    //         value: 12,
    //         label: {
    //             rich: {
    //                 // no 'a' here but using parent 'a'.
    //             }
    //         }
    //     }],
    //     rich: {
    //         a: { ... }
    //     }
    // }
    // TODO TextStyleModel


    function getRichItemNames(textStyleModel) {
      // Use object to remove duplicated names.
      var richItemNameMap;

      while (textStyleModel && textStyleModel !== textStyleModel.ecModel) {
        var rich = (textStyleModel.option || EMPTY_OBJ).rich;

        if (rich) {
          richItemNameMap = richItemNameMap || {};
          var richKeys = keys(rich);

          for (var i = 0; i < richKeys.length; i++) {
            var richKey = richKeys[i];
            richItemNameMap[richKey] = 1;
          }
        }

        textStyleModel = textStyleModel.parentModel;
      }

      return richItemNameMap;
    }

    var TEXT_PROPS_WITH_GLOBAL = ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily', 'textShadowColor', 'textShadowBlur', 'textShadowOffsetX', 'textShadowOffsetY'];
    var TEXT_PROPS_SELF = ['align', 'lineHeight', 'width', 'height', 'tag', 'verticalAlign'];
    var TEXT_PROPS_BOX = ['padding', 'borderWidth', 'borderRadius', 'borderDashOffset', 'backgroundColor', 'borderColor', 'shadowColor', 'shadowBlur', 'shadowOffsetX', 'shadowOffsetY'];

    function setTokenTextStyle(textStyle, textStyleModel, globalTextStyle, opt, isNotNormal, isAttached, isBlock, inRich) {
      // In merge mode, default value should not be given.
      globalTextStyle = !isNotNormal && globalTextStyle || EMPTY_OBJ;
      var inheritColor = opt && opt.inheritColor;
      var fillColor = textStyleModel.getShallow('color');
      var strokeColor = textStyleModel.getShallow('textBorderColor');
      var opacity = retrieve2(textStyleModel.getShallow('opacity'), globalTextStyle.opacity);

      if (fillColor === 'inherit' || fillColor === 'auto') {
        if ("development" !== 'production') {
          if (fillColor === 'auto') {
            deprecateReplaceLog('color: \'auto\'', 'color: \'inherit\'');
          }
        }

        if (inheritColor) {
          fillColor = inheritColor;
        } else {
          fillColor = null;
        }
      }

      if (strokeColor === 'inherit' || strokeColor === 'auto') {
        if ("development" !== 'production') {
          if (strokeColor === 'auto') {
            deprecateReplaceLog('color: \'auto\'', 'color: \'inherit\'');
          }
        }

        if (inheritColor) {
          strokeColor = inheritColor;
        } else {
          strokeColor = null;
        }
      }

      if (!isAttached) {
        // Only use default global textStyle.color if text is individual.
        // Otherwise it will use the strategy of attached text color because text may be on a path.
        fillColor = fillColor || globalTextStyle.color;
        strokeColor = strokeColor || globalTextStyle.textBorderColor;
      }

      if (fillColor != null) {
        textStyle.fill = fillColor;
      }

      if (strokeColor != null) {
        textStyle.stroke = strokeColor;
      }

      var textBorderWidth = retrieve2(textStyleModel.getShallow('textBorderWidth'), globalTextStyle.textBorderWidth);

      if (textBorderWidth != null) {
        textStyle.lineWidth = textBorderWidth;
      }

      var textBorderType = retrieve2(textStyleModel.getShallow('textBorderType'), globalTextStyle.textBorderType);

      if (textBorderType != null) {
        textStyle.lineDash = textBorderType;
      }

      var textBorderDashOffset = retrieve2(textStyleModel.getShallow('textBorderDashOffset'), globalTextStyle.textBorderDashOffset);

      if (textBorderDashOffset != null) {
        textStyle.lineDashOffset = textBorderDashOffset;
      }

      if (!isNotNormal && opacity == null && !inRich) {
        opacity = opt && opt.defaultOpacity;
      }

      if (opacity != null) {
        textStyle.opacity = opacity;
      } // TODO


      if (!isNotNormal && !isAttached) {
        // Set default finally.
        if (textStyle.fill == null && opt.inheritColor) {
          textStyle.fill = opt.inheritColor;
        }
      } // Do not use `getFont` here, because merge should be supported, where
      // part of these properties may be changed in emphasis style, and the
      // others should remain their original value got from normal style.


      for (var i = 0; i < TEXT_PROPS_WITH_GLOBAL.length; i++) {
        var key = TEXT_PROPS_WITH_GLOBAL[i];
        var val = retrieve2(textStyleModel.getShallow(key), globalTextStyle[key]);

        if (val != null) {
          textStyle[key] = val;
        }
      }

      for (var i = 0; i < TEXT_PROPS_SELF.length; i++) {
        var key = TEXT_PROPS_SELF[i];
        var val = textStyleModel.getShallow(key);

        if (val != null) {
          textStyle[key] = val;
        }
      }

      if (textStyle.verticalAlign == null) {
        var baseline = textStyleModel.getShallow('baseline');

        if (baseline != null) {
          textStyle.verticalAlign = baseline;
        }
      }

      if (!isBlock || !opt.disableBox) {
        for (var i = 0; i < TEXT_PROPS_BOX.length; i++) {
          var key = TEXT_PROPS_BOX[i];
          var val = textStyleModel.getShallow(key);

          if (val != null) {
            textStyle[key] = val;
          }
        }

        var borderType = textStyleModel.getShallow('borderType');

        if (borderType != null) {
          textStyle.borderDash = borderType;
        }

        if ((textStyle.backgroundColor === 'auto' || textStyle.backgroundColor === 'inherit') && inheritColor) {
          if ("development" !== 'production') {
            if (textStyle.backgroundColor === 'auto') {
              deprecateReplaceLog('backgroundColor: \'auto\'', 'backgroundColor: \'inherit\'');
            }
          }

          textStyle.backgroundColor = inheritColor;
        }

        if ((textStyle.borderColor === 'auto' || textStyle.borderColor === 'inherit') && inheritColor) {
          if ("development" !== 'production') {
            if (textStyle.borderColor === 'auto') {
              deprecateReplaceLog('borderColor: \'auto\'', 'borderColor: \'inherit\'');
            }
          }

          textStyle.borderColor = inheritColor;
        }
      }
    }

    function getFont(opt, ecModel) {
      var gTextStyleModel = ecModel && ecModel.getModel('textStyle');
      return trim([// FIXME in node-canvas fontWeight is before fontStyle
      opt.fontStyle || gTextStyleModel && gTextStyleModel.getShallow('fontStyle') || '', opt.fontWeight || gTextStyleModel && gTextStyleModel.getShallow('fontWeight') || '', (opt.fontSize || gTextStyleModel && gTextStyleModel.getShallow('fontSize') || 12) + 'px', opt.fontFamily || gTextStyleModel && gTextStyleModel.getShallow('fontFamily') || 'sans-serif'].join(' '));
    }
    var labelInner = makeInner();
    function setLabelValueAnimation(label, labelStatesModels, value, getDefaultText) {
      if (!label) {
        return;
      }

      var obj = labelInner(label);
      obj.prevValue = obj.value;
      obj.value = value;
      var normalLabelModel = labelStatesModels.normal;
      obj.valueAnimation = normalLabelModel.get('valueAnimation');

      if (obj.valueAnimation) {
        obj.precision = normalLabelModel.get('precision');
        obj.defaultInterpolatedText = getDefaultText;
        obj.statesModels = labelStatesModels;
      }
    }

    var PATH_COLOR = ['textStyle', 'color'];
    var textStyleParams = ['fontStyle', 'fontWeight', 'fontSize', 'fontFamily', 'padding', 'lineHeight', 'rich', 'width', 'height', 'overflow']; // TODO Performance improvement?

    var tmpText = new ZRText();

    var TextStyleMixin =
    /** @class */
    function () {
      function TextStyleMixin() {}
      /**
       * Get color property or get color from option.textStyle.color
       */
      // TODO Callback


      TextStyleMixin.prototype.getTextColor = function (isEmphasis) {
        var ecModel = this.ecModel;
        return this.getShallow('color') || (!isEmphasis && ecModel ? ecModel.get(PATH_COLOR) : null);
      };
      /**
       * Create font string from fontStyle, fontWeight, fontSize, fontFamily
       * @return {string}
       */


      TextStyleMixin.prototype.getFont = function () {
        return getFont({
          fontStyle: this.getShallow('fontStyle'),
          fontWeight: this.getShallow('fontWeight'),
          fontSize: this.getShallow('fontSize'),
          fontFamily: this.getShallow('fontFamily')
        }, this.ecModel);
      };

      TextStyleMixin.prototype.getTextRect = function (text) {
        var style = {
          text: text,
          verticalAlign: this.getShallow('verticalAlign') || this.getShallow('baseline')
        };

        for (var i = 0; i < textStyleParams.length; i++) {
          style[textStyleParams[i]] = this.getShallow(textStyleParams[i]);
        }

        tmpText.useStyle(style);
        tmpText.update();
        return tmpText.getBoundingRect();
      };

      return TextStyleMixin;
    }();

    var LINE_STYLE_KEY_MAP = [['lineWidth', 'width'], ['stroke', 'color'], ['opacity'], ['shadowBlur'], ['shadowOffsetX'], ['shadowOffsetY'], ['shadowColor'], ['lineDash', 'type'], ['lineDashOffset', 'dashOffset'], ['lineCap', 'cap'], ['lineJoin', 'join'], ['miterLimit'] // Option decal is in `DecalObject` but style.decal is in `PatternObject`.
    // So do not transfer decal directly.
    ];
    var getLineStyle = makeStyleMapper(LINE_STYLE_KEY_MAP);

    var LineStyleMixin =
    /** @class */
    function () {
      function LineStyleMixin() {}

      LineStyleMixin.prototype.getLineStyle = function (excludes) {
        return getLineStyle(this, excludes);
      };

      return LineStyleMixin;
    }();

    var ITEM_STYLE_KEY_MAP = [['fill', 'color'], ['stroke', 'borderColor'], ['lineWidth', 'borderWidth'], ['opacity'], ['shadowBlur'], ['shadowOffsetX'], ['shadowOffsetY'], ['shadowColor'], ['lineDash', 'borderType'], ['lineDashOffset', 'borderDashOffset'], ['lineCap', 'borderCap'], ['lineJoin', 'borderJoin'], ['miterLimit', 'borderMiterLimit'] // Option decal is in `DecalObject` but style.decal is in `PatternObject`.
    // So do not transfer decal directly.
    ];
    var getItemStyle = makeStyleMapper(ITEM_STYLE_KEY_MAP);

    var ItemStyleMixin =
    /** @class */
    function () {
      function ItemStyleMixin() {}

      ItemStyleMixin.prototype.getItemStyle = function (excludes, includes) {
        return getItemStyle(this, excludes, includes);
      };

      return ItemStyleMixin;
    }();

    var Model =
    /** @class */
    function () {
      function Model(option, parentModel, ecModel) {
        this.parentModel = parentModel;
        this.ecModel = ecModel;
        this.option = option; // Simple optimization
        // if (this.init) {
        //     if (arguments.length <= 4) {
        //         this.init(option, parentModel, ecModel, extraOpt);
        //     }
        //     else {
        //         this.init.apply(this, arguments);
        //     }
        // }
      }

      Model.prototype.init = function (option, parentModel, ecModel) {
        var rest = [];

        for (var _i = 3; _i < arguments.length; _i++) {
          rest[_i - 3] = arguments[_i];
        }
      };
      /**
       * Merge the input option to me.
       */


      Model.prototype.mergeOption = function (option, ecModel) {
        merge(this.option, option, true);
      }; // `path` can be 'a.b.c', so the return value type have to be `ModelOption`
      // TODO: TYPE strict key check?
      // get(path: string | string[], ignoreParent?: boolean): ModelOption;


      Model.prototype.get = function (path, ignoreParent) {
        if (path == null) {
          return this.option;
        }

        return this._doGet(this.parsePath(path), !ignoreParent && this.parentModel);
      };

      Model.prototype.getShallow = function (key, ignoreParent) {
        var option = this.option;
        var val = option == null ? option : option[key];

        if (val == null && !ignoreParent) {
          var parentModel = this.parentModel;

          if (parentModel) {
            // FIXME:TS do not know how to make it works
            val = parentModel.getShallow(key);
          }
        }

        return val;
      }; // `path` can be 'a.b.c', so the return value type have to be `Model<ModelOption>`
      // getModel(path: string | string[], parentModel?: Model): Model;
      // TODO 'a.b.c' is deprecated


      Model.prototype.getModel = function (path, parentModel) {
        var hasPath = path != null;
        var pathFinal = hasPath ? this.parsePath(path) : null;
        var obj = hasPath ? this._doGet(pathFinal) : this.option;
        parentModel = parentModel || this.parentModel && this.parentModel.getModel(this.resolveParentPath(pathFinal));
        return new Model(obj, parentModel, this.ecModel);
      };
      /**
       * If model has option
       */


      Model.prototype.isEmpty = function () {
        return this.option == null;
      };

      Model.prototype.restoreData = function () {}; // Pending


      Model.prototype.clone = function () {
        var Ctor = this.constructor;
        return new Ctor(clone(this.option));
      }; // setReadOnly(properties): void {
      // clazzUtil.setReadOnly(this, properties);
      // }
      // If path is null/undefined, return null/undefined.


      Model.prototype.parsePath = function (path) {
        if (typeof path === 'string') {
          return path.split('.');
        }

        return path;
      }; // Resolve path for parent. Perhaps useful when parent use a different property.
      // Default to be a identity resolver.
      // Can be modified to a different resolver.


      Model.prototype.resolveParentPath = function (path) {
        return path;
      }; // FIXME:TS check whether put this method here


      Model.prototype.isAnimationEnabled = function () {
        if (!env.node && this.option) {
          if (this.option.animation != null) {
            return !!this.option.animation;
          } else if (this.parentModel) {
            return this.parentModel.isAnimationEnabled();
          }
        }
      };

      Model.prototype._doGet = function (pathArr, parentModel) {
        var obj = this.option;

        if (!pathArr) {
          return obj;
        }

        for (var i = 0; i < pathArr.length; i++) {
          // Ignore empty
          if (!pathArr[i]) {
            continue;
          } // obj could be number/string/... (like 0)


          obj = obj && typeof obj === 'object' ? obj[pathArr[i]] : null;

          if (obj == null) {
            break;
          }
        }

        if (obj == null && parentModel) {
          obj = parentModel._doGet(this.resolveParentPath(pathArr), parentModel.parentModel);
        }

        return obj;
      };

      return Model;
    }();

    enableClassExtend(Model);
    enableClassCheck(Model);
    mixin(Model, LineStyleMixin);
    mixin(Model, ItemStyleMixin);
    mixin(Model, AreaStyleMixin);
    mixin(Model, TextStyleMixin);

    var base = Math.round(Math.random() * 10);
    /**
     * @public
     * @param {string} type
     * @return {string}
     */

    function getUID(type) {
      // Considering the case of crossing js context,
      // use Math.random to make id as unique as possible.
      return [type || '', base++].join('_');
    }
    /**
     * Implements `SubTypeDefaulterManager` for `target`.
     */

    function enableSubTypeDefaulter(target) {
      var subTypeDefaulters = {};

      target.registerSubTypeDefaulter = function (componentType, defaulter) {
        var componentTypeInfo = parseClassType(componentType);
        subTypeDefaulters[componentTypeInfo.main] = defaulter;
      };

      target.determineSubType = function (componentType, option) {
        var type = option.type;

        if (!type) {
          var componentTypeMain = parseClassType(componentType).main;

          if (target.hasSubTypes(componentType) && subTypeDefaulters[componentTypeMain]) {
            type = subTypeDefaulters[componentTypeMain](option);
          }
        }

        return type;
      };
    }
    /**
     * Implements `TopologicalTravelable<any>` for `entity`.
     *
     * Topological travel on Activity Network (Activity On Vertices).
     * Dependencies is defined in Model.prototype.dependencies, like ['xAxis', 'yAxis'].
     * If 'xAxis' or 'yAxis' is absent in componentTypeList, just ignore it in topology.
     * If there is circular dependencey, Error will be thrown.
     */

    function enableTopologicalTravel(entity, dependencyGetter) {
      /**
       * @param targetNameList Target Component type list.
       *                       Can be ['aa', 'bb', 'aa.xx']
       * @param fullNameList By which we can build dependency graph.
       * @param callback Params: componentType, dependencies.
       * @param context Scope of callback.
       */
      entity.topologicalTravel = function (targetNameList, fullNameList, callback, context) {
        if (!targetNameList.length) {
          return;
        }

        var result = makeDepndencyGraph(fullNameList);
        var graph = result.graph;
        var noEntryList = result.noEntryList;
        var targetNameSet = {};
        each(targetNameList, function (name) {
          targetNameSet[name] = true;
        });

        while (noEntryList.length) {
          var currComponentType = noEntryList.pop();
          var currVertex = graph[currComponentType];
          var isInTargetNameSet = !!targetNameSet[currComponentType];

          if (isInTargetNameSet) {
            callback.call(context, currComponentType, currVertex.originalDeps.slice());
            delete targetNameSet[currComponentType];
          }

          each(currVertex.successor, isInTargetNameSet ? removeEdgeAndAdd : removeEdge);
        }

        each(targetNameSet, function () {
          var errMsg = '';

          if ("development" !== 'production') {
            errMsg = makePrintable('Circular dependency may exists: ', targetNameSet, targetNameList, fullNameList);
          }

          throw new Error(errMsg);
        });

        function removeEdge(succComponentType) {
          graph[succComponentType].entryCount--;

          if (graph[succComponentType].entryCount === 0) {
            noEntryList.push(succComponentType);
          }
        } // Consider this case: legend depends on series, and we call
        // chart.setOption({series: [...]}), where only series is in option.
        // If we do not have 'removeEdgeAndAdd', legendModel.mergeOption will
        // not be called, but only sereis.mergeOption is called. Thus legend
        // have no chance to update its local record about series (like which
        // name of series is available in legend).


        function removeEdgeAndAdd(succComponentType) {
          targetNameSet[succComponentType] = true;
          removeEdge(succComponentType);
        }
      };

      function makeDepndencyGraph(fullNameList) {
        var graph = {};
        var noEntryList = [];
        each(fullNameList, function (name) {
          var thisItem = createDependencyGraphItem(graph, name);
          var originalDeps = thisItem.originalDeps = dependencyGetter(name);
          var availableDeps = getAvailableDependencies(originalDeps, fullNameList);
          thisItem.entryCount = availableDeps.length;

          if (thisItem.entryCount === 0) {
            noEntryList.push(name);
          }

          each(availableDeps, function (dependentName) {
            if (indexOf(thisItem.predecessor, dependentName) < 0) {
              thisItem.predecessor.push(dependentName);
            }

            var thatItem = createDependencyGraphItem(graph, dependentName);

            if (indexOf(thatItem.successor, dependentName) < 0) {
              thatItem.successor.push(name);
            }
          });
        });
        return {
          graph: graph,
          noEntryList: noEntryList
        };
      }

      function createDependencyGraphItem(graph, name) {
        if (!graph[name]) {
          graph[name] = {
            predecessor: [],
            successor: []
          };
        }

        return graph[name];
      }

      function getAvailableDependencies(originalDeps, fullNameList) {
        var availableDeps = [];
        each(originalDeps, function (dep) {
          indexOf(fullNameList, dep) >= 0 && availableDeps.push(dep);
        });
        return availableDeps;
      }
    }
    function inheritDefaultOption(superOption, subOption) {
      // See also `model/Component.ts#getDefaultOption`
      return merge(merge({}, superOption, true), subOption, true);
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */

    /**
     * Language: English.
     */
    var langEN = {
      time: {
        month: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
        monthAbbr: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
        dayOfWeek: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
        dayOfWeekAbbr: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
      },
      legend: {
        selector: {
          all: 'All',
          inverse: 'Inv'
        }
      },
      toolbox: {
        brush: {
          title: {
            rect: 'Box Select',
            polygon: 'Lasso Select',
            lineX: 'Horizontally Select',
            lineY: 'Vertically Select',
            keep: 'Keep Selections',
            clear: 'Clear Selections'
          }
        },
        dataView: {
          title: 'Data View',
          lang: ['Data View', 'Close', 'Refresh']
        },
        dataZoom: {
          title: {
            zoom: 'Zoom',
            back: 'Zoom Reset'
          }
        },
        magicType: {
          title: {
            line: 'Switch to Line Chart',
            bar: 'Switch to Bar Chart',
            stack: 'Stack',
            tiled: 'Tile'
          }
        },
        restore: {
          title: 'Restore'
        },
        saveAsImage: {
          title: 'Save as Image',
          lang: ['Right Click to Save Image']
        }
      },
      series: {
        typeNames: {
          pie: 'Pie chart',
          bar: 'Bar chart',
          line: 'Line chart',
          scatter: 'Scatter plot',
          effectScatter: 'Ripple scatter plot',
          radar: 'Radar chart',
          tree: 'Tree',
          treemap: 'Treemap',
          boxplot: 'Boxplot',
          candlestick: 'Candlestick',
          k: 'K line chart',
          heatmap: 'Heat map',
          map: 'Map',
          parallel: 'Parallel coordinate map',
          lines: 'Line graph',
          graph: 'Relationship graph',
          sankey: 'Sankey diagram',
          funnel: 'Funnel chart',
          gauge: 'Gauge',
          pictorialBar: 'Pictorial bar',
          themeRiver: 'Theme River Map',
          sunburst: 'Sunburst'
        }
      },
      aria: {
        general: {
          withTitle: 'This is a chart about "{title}"',
          withoutTitle: 'This is a chart'
        },
        series: {
          single: {
            prefix: '',
            withName: ' with type {seriesType} named {seriesName}.',
            withoutName: ' with type {seriesType}.'
          },
          multiple: {
            prefix: '. It consists of {seriesCount} series count.',
            withName: ' The {seriesId} series is a {seriesType} representing {seriesName}.',
            withoutName: ' The {seriesId} series is a {seriesType}.',
            separator: {
              middle: '',
              end: ''
            }
          }
        },
        data: {
          allData: 'The data is as follows: ',
          partialData: 'The first {displayCnt} items are: ',
          withName: 'the data for {name} is {value}',
          withoutName: '{value}',
          separator: {
            middle: ', ',
            end: '. '
          }
        }
      }
    };

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
     * Licensed to the Apache Software Foundation (ASF) under one
     * or more contributor license agreements.  See the NOTICE file
     * distributed with this work for additional information
     * regarding copyright ownership.  The ASF licenses this file
     * to you under the Apache License, Version 2.0 (the
     * "License"); you may not use this file except in compliance
     * with the License.  You may obtain a copy of the License at
     *
     *   http://www.apache.org/licenses/LICENSE-2.0
     *
     * Unless required by applicable law or agreed to in writing,
     * software distributed under the License is distributed on an
     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     * KIND, either express or implied.  See the License for the
     * specific language governing permissions and limitations
     * under the License.
     */
    var langZH = {
      time: {
        month: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月'],
        monthAbbr: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
        dayOfWeek: ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],
        dayOfWeekAbbr: ['日', '一', '二', '三', '四', '五', '六']
      },
      legend: {
        selector: {
          all: '全选',
          inverse: '反选'
        }
      },
      toolbox: {
        brush: {
          title: {
            rect: '矩形选择',
            polygon: '圈选',
            lineX: '横向选择',
            lineY: '纵向选择',
            keep: '保持选择',
            clear: '清除选择'
          }
        },
        dataView: {
          title: '数据视图',
          lang: ['数据视图', '关闭', '刷新']
        },
        dataZoom: {
          title: {
            zoom: '区域缩放',
            back: '区域缩放还原'
          }
        },
        magicType: {
          title: {
            line: '切换为折线图',
            bar: '切换为柱状图',
            stack: '切换为堆叠',
            tiled: '切换为平铺'
          }
        },
        restore: {
          title: '还原'
        },
        saveAsImage: {
          title: '保存为图片',
          lang: ['右键另存为图片']
        }
      },
      series: {
        typeNames: {
          pie: '饼图',
          bar: '柱状图',
          line: '折线图',
          scatter: '散点图',
          effectScatter: '涟漪散点图',
          radar: '雷达图',
          tree: '树图',
          treemap: '矩形树图',
          boxplot: '箱型图',
          candlestick: 'K线图',
          k: 'K线图',
          heatmap: '热力图',
          map: '地图',
          parallel: '平行坐标图',
          lines: '线图',
          graph: '关系图',
          sankey: '桑基图',
          funnel: '漏斗图',
          gauge: '仪表盘图',
          pictorialBar: '象形柱图',
          themeRiver: '主题河流图',
          sunburst: '旭日图'
        }
      },
      aria: {
        general: {
          withTitle: '这是一个关于“{title}”的图表。',
          withoutTitle: '这是一个图表，'
        },
        series: {
          single: {
            prefix: '',
            withName: '图表类型是{seriesType}，表示{seriesName}。',
            withoutName: '图表类型是{seriesType}。'
          },
          multiple: {
            prefix: '它由{seriesCount}个图表系列组成。',
            withName: '第{seriesId}个系列是一个表示{seriesName}的{seriesType}，',
            withoutName: '第{seriesId}个系列是一个{seriesType}，',
            separator: {
              middle: '；',
              end: '。'
            }
          }
        },
        data: {
          allData: '其数据是——',
          partialData: '其中，前{displayCnt}项是——',
          withName: '{name}的数据是{value}',
          withoutName: '{value}',
          separator: {
            middle: '，',
            end: ''
          }
        }
      }
    };

    var LOCALE_ZH = 'ZH';
    var LOCALE_EN = 'EN';
    var DEFAULT_LOCALE = LOCALE_EN;
    var localeStorage = {};
    var localeModels = {};
    var SYSTEM_LANG = !env.domSupported ? DEFAULT_LOCALE : function () {
      var langStr = (
      /* eslint-disable-next-line */
      document.documentElement.lang || navigator.language || navigator.browserLanguage).toUpperCase();
      return langStr.indexOf(LOCALE_ZH) > -1 ? LOCALE_ZH : DEFAULT_LOCALE;
    }();
    function registerLocale(locale, localeObj) {
      locale = locale.toUpperCase();
      localeModels[locale] = new Model(localeObj);
      localeStorage[locale] = localeObj;
    } // export function getLocale(locale: string) {
    //     return localeStorage[locale];
    // }

    function createLocaleObject(locale) {
      if (isString(locale)) {
        var localeObj = localeStorage[locale.toUpperCase()] || {};

        if (locale === LOCALE_ZH || locale === LOCALE_EN) {
          return clone(localeObj);
        } else {
          return merge(clone(localeObj), clone(localeStorage[DEFAULT_LOCALE]), false);
        }
      } else {
        return merge(clone(locale), clone(localeStorage[DEFAULT_LOCALE]), false);
      }
    }
    function getLocaleModel(lang) {
      return localeModels[lang];
    }
    function getDefaultLocaleModel() {
      return localeModels[DEFAULT_LOCALE];
    } // Default locale

    registerLocale(LOCALE_EN, langEN);
    registerLocale(LOCALE_ZH, langZH);

    var ONE_SECOND = 1000;
    var ONE_MINUTE = ONE_SECOND * 60;
    var ONE_HOUR = ONE_MINUTE * 60;
    var ONE_DAY = ONE_HOUR * 24;
    var ONE_YEAR = ONE_DAY * 365;
    var defaultLeveledFormatter = {
      year: '{yyyy}',
      month: '{MMM}',
      day: '{d}',
      hour: '{HH}:{mm}',
      minute: '{HH}:{mm}',
      second: '{HH}:{mm}:{ss}',
      millisecond: '{HH}:{mm}:{ss} {SSS}',
      none: '{yyyy}-{MM}-{dd} {HH}:{mm}:{ss} {SSS}'
    };
    var fullDayFormatter = '{yyyy}-{MM}-{dd}';
    var fullLeveledFormatter = {
      year: '{yyyy}',
      month: '{yyyy}-{MM}',
      day: fullDayFormatter,
      hour: fullDayFormatter + ' ' + defaultLeveledFormatter.hour,
      minute: fullDayFormatter + ' ' + defaultLeveledFormatter.minute,
      second: fullDayFormatter + ' ' + defaultLeveledFormatter.second,
      millisecond: defaultLeveledFormatter.none
    };
    var primaryTimeUnits = ['year', 'month', 'day', 'hour', 'minute', 'second', 'millisecond'];
    var timeUnits = ['year', 'half-year', 'quarter', 'month', 'week', 'half-week', 'day', 'half-day', 'quarter-day', 'hour', 'minute', 'second', 'millisecond'];
    function pad(str, len) {
      str += '';
      return '0000'.substr(0, len - str.length) + str;
    }
    function getPrimaryTimeUnit(timeUnit) {
      switch (timeUnit) {
        case 'half-year':
        case 'quarter':
          return 'month';

        case 'week':
        case 'half-week':
          return 'day';

        case 'half-day':
        case 'quarter-day':
          return 'hour';

        default:
          // year, minutes, second, milliseconds
          return timeUnit;
      }
    }
    function isPrimaryTimeUnit(timeUnit) {
      return timeUnit === getPrimaryTimeUnit(timeUnit);
    }
    function getDefaultFormatPrecisionOfInterval(timeUnit) {
      switch (timeUnit) {
        case 'year':
        case 'month':
          return 'day';

        case 'millisecond':
          return 'millisecond';

        default:
          // Also for day, hour, minute, second
          return 'second';
      }
    }
    function format( // Note: The result based on `isUTC` are totally different, which can not be just simply
    // substituted by the result without `isUTC`. So we make the param `isUTC` mandatory.
    time, template, isUTC, lang) {
      var date = parseDate(time);
      var y = date[fullYearGetterName(isUTC)]();
      var M = date[monthGetterName(isUTC)]() + 1;
      var q = Math.floor((M - 1) / 3) + 1;
      var d = date[dateGetterName(isUTC)]();
      var e = date['get' + (isUTC ? 'UTC' : '') + 'Day']();
      var H = date[hoursGetterName(isUTC)]();
      var h = (H - 1) % 12 + 1;
      var m = date[minutesGetterName(isUTC)]();
      var s = date[secondsGetterName(isUTC)]();
      var S = date[millisecondsGetterName(isUTC)]();
      var localeModel = lang instanceof Model ? lang : getLocaleModel(lang || SYSTEM_LANG) || getDefaultLocaleModel();
      var timeModel = localeModel.getModel('time');
      var month = timeModel.get('month');
      var monthAbbr = timeModel.get('monthAbbr');
      var dayOfWeek = timeModel.get('dayOfWeek');
      var dayOfWeekAbbr = timeModel.get('dayOfWeekAbbr');
      return (template || '').replace(/{yyyy}/g, y + '').replace(/{yy}/g, y % 100 + '').replace(/{Q}/g, q + '').replace(/{MMMM}/g, month[M - 1]).replace(/{MMM}/g, monthAbbr[M - 1]).replace(/{MM}/g, pad(M, 2)).replace(/{M}/g, M + '').replace(/{dd}/g, pad(d, 2)).replace(/{d}/g, d + '').replace(/{eeee}/g, dayOfWeek[e]).replace(/{ee}/g, dayOfWeekAbbr[e]).replace(/{e}/g, e + '').replace(/{HH}/g, pad(H, 2)).replace(/{H}/g, H + '').replace(/{hh}/g, pad(h + '', 2)).replace(/{h}/g, h + '').replace(/{mm}/g, pad(m, 2)).replace(/{m}/g, m + '').replace(/{ss}/g, pad(s, 2)).replace(/{s}/g, s + '').replace(/{SSS}/g, pad(S, 3)).replace(/{S}/g, S + '');
    }
    function leveledFormat(tick, idx, formatter, lang, isUTC) {
      var template = null;

      if (isString(formatter)) {
        // Single formatter for all units at all levels
        template = formatter;
      } else if (isFunction(formatter)) {
        // Callback formatter
        template = formatter(tick.value, idx, {
          level: tick.level
        });
      } else {
        var defaults$1 = extend({}, defaultLeveledFormatter);

        if (tick.level > 0) {
          for (var i = 0; i < primaryTimeUnits.length; ++i) {
            defaults$1[primaryTimeUnits[i]] = "{primary|" + defaults$1[primaryTimeUnits[i]] + "}";
          }
        }

        var mergedFormatter = formatter ? formatter.inherit === false ? formatter // Use formatter with bigger units
        : defaults(formatter, defaults$1) : defaults$1;
        var unit = getUnitFromValue(tick.value, isUTC);

        if (mergedFormatter[unit]) {
          template = mergedFormatter[unit];
        } else if (mergedFormatter.inherit) {
          // Unit formatter is not defined and should inherit from bigger units
          var targetId = timeUnits.indexOf(unit);

          for (var i = targetId - 1; i >= 0; --i) {
            if (mergedFormatter[unit]) {
              template = mergedFormatter[unit];
              break;
            }
          }

          template = template || defaults$1.none;
        }

        if (isArray(template)) {
          var levelId = tick.level == null ? 0 : tick.level >= 0 ? tick.level : template.length + tick.level;
          levelId = Math.min(levelId, template.length - 1);
          template = template[levelId];
        }
      }

      return format(new Date(tick.value), template, isUTC, lang);
    }
    function getUnitFromValue(value, isUTC) {
      var date = parseDate(value);
      var M = date[monthGetterName(isUTC)]() + 1;
      var d = date[dateGetterName(isUTC)]();
      var h = date[hoursGetterName(isUTC)]();
      var m = date[minutesGetterName(isUTC)]();
      var s = date[secondsGetterName(isUTC)]();
      var S = date[millisecondsGetterName(isUTC)]();
      var isSecond = S === 0;
      var isMinute = isSecond && s === 0;
      var isHour = isMinute && m === 0;
      var isDay = isHour && h === 0;
      var isMonth = isDay && d === 1;
      var isYear = isMonth && M === 1;

      if (isYear) {
        return 'year';
      } else if (isMonth) {
        return 'month';
      } else if (isDay) {
        return 'day';
      } else if (isHour) {
        return 'hour';
      } else if (isMinute) {
        return 'minute';
      } else if (isSecond) {
        return 'second';
      } else {
        return 'millisecond';
      }
    }
    function getUnitValue(value, unit, isUTC) {
      var date = isNumber(value) ? parseDate(value) : value;
      unit = unit || getUnitFromValue(value, isUTC);

      switch (unit) {
        case 'year':
          return date[fullYearGetterName(isUTC)]();

        case 'half-year':
          return date[monthGetterName(isUTC)]() >= 6 ? 1 : 0;

        case 'quarter':
          return Math.floor((date[monthGetterName(isUTC)]() + 1) / 4);

        case 'month':
          return date[monthGetterName(isUTC)]();

        case 'day':
          return date[dateGetterName(isUTC)]();

        case 'half-day':
          return date[hoursGetterName(isUTC)]() / 24;

        case 'hour':
          return date[hoursGetterName(isUTC)]();

        case 'minute':
          return date[minutesGetterName(isUTC)]();

        case 'second':
          return date[secondsGetterName(isUTC)]();

        case 'millisecond':
          return date[millisecondsGetterName(isUTC)]();
      }
    }
    function fullYearGetterName(isUTC) {
      return isUTC ? 'getUTCFullYear' : 'getFullYear';
    }
    function monthGetterName(isUTC) {
      return isUTC ? 'getUTCMonth' : 'getMonth';
    }
    function dateGetterName(isUTC) {
      return isUTC ? 'getUTCDate' : 'getDate';
    }
    function hoursGetterName(isUTC) {
      return isUTC ? 'getUTCHours' : 'getHours';
    }
    function minutesGetterName(isUTC) {
      return isUTC ? 'getUTCMinutes' : 'getMinutes';
    }
    function secondsGetterName(isUTC) {
      return isUTC ? 'getUTCSeconds' : 'getSeconds';
    }
    function millisecondsGetterName(isUTC) {
      return isUTC ? 'getUTCMilliseconds' : 'getMilliseconds';
    }
    function fullYearSetterName(isUTC) {
      return isUTC ? 'setUTCFullYear' : 'setFullYear';
    }
    function monthSetterName(isUTC) {
      return isUTC ? 'setUTCMonth' : 'setMonth';
    }
    function dateSetterName(isUTC) {
      return isUTC ? 'setUTCDate' : 'setDate';
    }
    function hoursSetterName(isUTC) {
      return isUTC ? 'setUTCHours' : 'setHours';
    }
    function minutesSetterName(isUTC) {
      return isUTC ? 'setUTCMinutes' : 'setMinutes';
    }
    function secondsSetterName(isUTC) {
      return isUTC ? 'setUTCSeconds' : 'setSeconds';
    }
    function millisecondsSetterName(isUTC) {
      return isUTC ? 'setUTCMilliseconds' : 'setMilliseconds';
    }

    function getTextRect(text, font, align, verticalAlign, padding, rich, truncate, lineHeight) {
      var textEl = new ZRText({
        style: {
          text: text,
          font: font,
          align: align,
          verticalAlign: verticalAlign,
          padding: padding,
          rich: rich,
          overflow: truncate ? 'truncate' : null,
          lineHeight: lineHeight
        }
      });
      return textEl.getBoundingRect();
    }

    /**
     * Add a comma each three digit.
     */

    function addCommas(x) {
      if (!isNumeric(x)) {
        return isString(x) ? x : '-';
      }

      var parts = (x + '').split('.');
      return parts[0].replace(/(\d{1,3})(?=(?:\d{3})+(?!\d))/g, '$1,') + (parts.length > 1 ? '.' + parts[1] : '');
    }
    function toCamelCase(str, upperCaseFirst) {
      str = (str || '').toLowerCase().replace(/-(.)/g, function (match, group1) {
        return group1.toUpperCase();
      });

      if (upperCaseFirst && str) {
        str = str.charAt(0).toUpperCase() + str.slice(1);
      }

      return str;
    }
    var normalizeCssArray$1 = normalizeCssArray;
    var TPL_VAR_ALIAS = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];

    var wrapVar = function (varName, seriesIdx) {
      return '{' + varName + (seriesIdx == null ? '' : seriesIdx) + '}';
    };
    /**
     * Template formatter
     * @param {Array.<Object>|Object} paramsList
     */


    function formatTpl(tpl, paramsList, encode) {
      if (!isArray(paramsList)) {
        paramsList = [paramsList];
      }

      var seriesLen = paramsList.length;

      if (!seriesLen) {
        return '';
      }

      var $vars = paramsList[0].$vars || [];

      for (var i = 0; i < $vars.length; i++) {
        var alias = TPL_VAR_ALIAS[i];
        tpl = tpl.replace(wrapVar(alias), wrapVar(alias, 0));
      }

      for (var seriesIdx = 0; seriesIdx < seriesLen; seriesIdx++) {
        for (var k = 0; k < $vars.length; k++) {
          var val = paramsList[seriesIdx][$vars[k]];
          tpl = tpl.replace(wrapVar(TPL_VAR_ALIAS[k], seriesIdx), encode ? encodeHTML(val) : val);
        }
      }

      return tpl;
    }
    function getTooltipMarker(inOpt, extraCssText) {
      var opt = isString(inOpt) ? {
        color: inOpt,
        extraCssText: extraCssText
      } : inOpt || {};
      var color = opt.color;
      var type = opt.type;
      extraCssText = opt.extraCssText;
      var renderMode = opt.renderMode || 'html';

      if (!color) {
        return '';
      }

      if (renderMode === 'html') {
        return type === 'subItem' ? '<span style="display:inline-block;vertical-align:middle;margin-right:8px;margin-left:3px;' + 'border-radius:4px;width:4px;height:4px;background-color:' // Only support string
        + encodeHTML(color) + ';' + (extraCssText || '') + '"></span>' : '<span style="display:inline-block;margin-right:4px;' + 'border-radius:10px;width:10px;height:10px;background-color:' + encodeHTML(color) + ';' + (extraCssText || '') + '"></span>';
      } else {
        // Should better not to auto generate style name by auto-increment number here.
        // Because this util is usually called in tooltip formatter, which is probably
        // called repeatedly when mouse move and the auto-increment number increases fast.
        // Users can make their own style name by theirselves, make it unique and readable.
        var markerId = opt.markerId || 'markerX';
        return {
          renderMode: renderMode,
          content: '{' + markerId + '|}  ',
          style: type === 'subItem' ? {
            width: 4,
            height: 4,
            borderRadius: 2,
            backgroundColor: color
          } : {
            width: 10,
            height: 10,
            borderRadius: 5,
            backgroundColor: color
          }
        };
      }
    }
    /**
     * @deprecated Use `time/format` instead.
     * ISO Date format
     * @param {string} tpl
     * @param {number} value
     * @param {boolean} [isUTC=false] Default in local time.
     *           see `module:echarts/scale/Time`
     *           and `module:echarts/util/number#parseDate`.
     * @inner
     */

    function formatTime(tpl, value, isUTC) {
      if ("development" !== 'production') {
        deprecateReplaceLog('echarts.format.formatTime', 'echarts.time.format');
      }

      if (tpl === 'week' || tpl === 'month' || tpl === 'quarter' || tpl === 'half-year' || tpl === 'year') {
        tpl = 'MM-dd\nyyyy';
      }

      var date = parseDate(value);
      var getUTC = isUTC ? 'getUTC' : 'get';
      var y = date[getUTC + 'FullYear']();
      var M = date[getUTC + 'Month']() + 1;
      var d = date[getUTC + 'Date']();
      var h = date[getUTC + 'Hours']();
      var m = date[getUTC + 'Minutes']();
      var s = date[getUTC + 'Seconds']();
      var S = date[getUTC + 'Milliseconds']();
      tpl = tpl.replace('MM', pad(M, 2)).replace('M', M).replace('yyyy', y).replace('yy', pad(y % 100 + '', 2)).replace('dd', pad(d, 2)).replace('d', d).replace('hh', pad(h, 2)).replace('h', h).replace('mm', pad(m, 2)).replace('m', m).replace('ss', pad(s, 2)).replace('s', s).replace('SSS', pad(S, 3));
      return tpl;
    }
    /**
     * Capital first
     * @param {string} str
     * @return {string}
     */

    function capitalFirst(str) {
      return str ? str.charAt(0).toUpperCase() + str.substr(1) : str;
    }
    /**
     * @return Never be null/undefined.
     */

    function convertToColorString(color, defaultColor) {
      defaultColor = defaultColor || 'transparent';
      return isString(color) ? color : isObject(color) ? color.colorStops && (color.colorStops[0] || {}).color || defaultColor : defaultColor;
    }

    var each$1 = each;
    /**
     * @public
     */

    var LOCATION_PARAMS = ['left', 'right', 'top', 'bottom', 'width', 'height'];
    /**
     * @public
     */

    var HV_NAMES = [['width', 'left', 'right'], ['height', 'top', 'bottom']];

    function boxLayout(orient, group, gap, maxWidth, maxHeight) {
      var x = 0;
      var y = 0;

      if (maxWidth == null) {
        maxWidth = Infinity;
      }

      if (maxHeight == null) {
        maxHeight = Infinity;
      }

      var currentLineMaxSize = 0;
      group.eachChild(function (child, idx) {
        var rect = child.getBoundingRect();
        var nextChild = group.childAt(idx + 1);
        var nextChildRect = nextChild && nextChild.getBoundingRect();
        var nextX;
        var nextY;

        if (orient === 'horizontal') {
          var moveX = rect.width + (nextChildRect ? -nextChildRect.x + rect.x : 0);
          nextX = x + moveX; // Wrap when width exceeds maxWidth or meet a `newline` group
          // FIXME compare before adding gap?

          if (nextX > maxWidth || child.newline) {
            x = 0;
            nextX = moveX;
            y += currentLineMaxSize + gap;
            currentLineMaxSize = rect.height;
          } else {
            // FIXME: consider rect.y is not `0`?
            currentLineMaxSize = Math.max(currentLineMaxSize, rect.height);
          }
        } else {
          var moveY = rect.height + (nextChildRect ? -nextChildRect.y + rect.y : 0);
          nextY = y + moveY; // Wrap when width exceeds maxHeight or meet a `newline` group

          if (nextY > maxHeight || child.newline) {
            x += currentLineMaxSize + gap;
            y = 0;
            nextY = moveY;
            currentLineMaxSize = rect.width;
          } else {
            currentLineMaxSize = Math.max(currentLineMaxSize, rect.width);
          }
        }

        if (child.newline) {
          return;
        }

        child.x = x;
        child.y = y;
        child.markRedraw();
        orient === 'horizontal' ? x = nextX + gap : y = nextY + gap;
      });
    }
    /**
     * VBox layouting
     * @param {module:zrender/graphic/Group} group
     * @param {number} gap
     * @param {number} [width=Infinity]
     * @param {number} [height=Infinity]
     */

    var vbox = curry(boxLayout, 'vertical');
    /**
     * HBox layouting
     * @param {module:zrender/graphic/Group} group
     * @param {number} gap
     * @param {number} [width=Infinity]
     * @param {number} [height=Infinity]
     */

    var hbox = curry(boxLayout, 'horizontal');
    /**
     * Parse position info.
     */

    function getLayoutRect(positionInfo, containerRect, margin) {
      margin = normalizeCssArray$1(margin || 0);
      var containerWidth = containerRect.width;
      var containerHeight = containerRect.height;
      var left = parsePercent$1(positionInfo.left, containerWidth);
      var top = parsePercent$1(positionInfo.top, containerHeight);
      var right = parsePercent$1(positionInfo.right, containerWidth);
      var bottom = parsePercent$1(positionInfo.bottom, containerHeight);
      var width = parsePercent$1(positionInfo.width, containerWidth);
      var height = parsePercent$1(positionInfo.height, containerHeight);
      var verticalMargin = margin[2] + margin[0];
      var horizontalMargin = margin[1] + margin[3];
      var aspect = positionInfo.aspect; // If width is not specified, calculate width from left and right

      if (isNaN(width)) {
        width = containerWidth - right - horizontalMargin - left;
      }

      if (isNaN(height)) {
        height = containerHeight - bottom - verticalMargin - top;
      }

      if (aspect != null) {
        // If width and height are not given
        // 1. Graph should not exceeds the container
        // 2. Aspect must be keeped
        // 3. Graph should take the space as more as possible
        // FIXME
        // Margin is not considered, because there is no case that both
        // using margin and aspect so far.
        if (isNaN(width) && isNaN(height)) {
          if (aspect > containerWidth / containerHeight) {
            width = containerWidth * 0.8;
          } else {
            height = containerHeight * 0.8;
          }
        } // Calculate width or height with given aspect


        if (isNaN(width)) {
          width = aspect * height;
        }

        if (isNaN(height)) {
          height = width / aspect;
        }
      } // If left is not specified, calculate left from right and width


      if (isNaN(left)) {
        left = containerWidth - right - width - horizontalMargin;
      }

      if (isNaN(top)) {
        top = containerHeight - bottom - height - verticalMargin;
      } // Align left and top


      switch (positionInfo.left || positionInfo.right) {
        case 'center':
          left = containerWidth / 2 - width / 2 - margin[3];
          break;

        case 'right':
          left = containerWidth - width - horizontalMargin;
          break;
      }

      switch (positionInfo.top || positionInfo.bottom) {
        case 'middle':
        case 'center':
          top = containerHeight / 2 - height / 2 - margin[0];
          break;

        case 'bottom':
          top = containerHeight - height - verticalMargin;
          break;
      } // If something is wrong and left, top, width, height are calculated as NaN


      left = left || 0;
      top = top || 0;

      if (isNaN(width)) {
        // Width may be NaN if only one value is given except width
        width = containerWidth - horizontalMargin - left - (right || 0);
      }

      if (isNaN(height)) {
        // Height may be NaN if only one value is given except height
        height = containerHeight - verticalMargin - top - (bottom || 0);
      }

      var rect = new BoundingRect(left + margin[3], top + margin[0], width, height);
      rect.margin = margin;
      return rect;
    }
    function fetchLayoutMode(ins) {
      var layoutMode = ins.layoutMode || ins.constructor.layoutMode;
      return isObject(layoutMode) ? layoutMode : layoutMode ? {
        type: layoutMode
      } : null;
    }
    /**
     * Consider Case:
     * When default option has {left: 0, width: 100}, and we set {right: 0}
     * through setOption or media query, using normal zrUtil.merge will cause
     * {right: 0} does not take effect.
     *
     * @example
     * ComponentModel.extend({
     *     init: function () {
     *         ...
     *         let inputPositionParams = layout.getLayoutParams(option);
     *         this.mergeOption(inputPositionParams);
     *     },
     *     mergeOption: function (newOption) {
     *         newOption && zrUtil.merge(thisOption, newOption, true);
     *         layout.mergeLayoutParam(thisOption, newOption);
     *     }
     * });
     *
     * @param targetOption
     * @param newOption
     * @param opt
     */

    function mergeLayoutParam(targetOption, newOption, opt) {
      var ignoreSize = opt && opt.ignoreSize;
      !isArray(ignoreSize) && (ignoreSize = [ignoreSize, ignoreSize]);
      var hResult = merge(HV_NAMES[0], 0);
      var vResult = merge(HV_NAMES[1], 1);
      copy(HV_NAMES[0], targetOption, hResult);
      copy(HV_NAMES[1], targetOption, vResult);

      function merge(names, hvIdx) {
        var newParams = {};
        var newValueCount = 0;
        var merged = {};
        var mergedValueCount = 0;
        var enoughParamNumber = 2;
        each$1(names, function (name) {
          merged[name] = targetOption[name];
        });
        each$1(names, function (name) {
          // Consider case: newOption.width is null, which is
          // set by user for removing width setting.
          hasProp(newOption, name) && (newParams[name] = merged[name] = newOption[name]);
          hasValue(newParams, name) && newValueCount++;
          hasValue(merged, name) && mergedValueCount++;
        });

        if (ignoreSize[hvIdx]) {
          // Only one of left/right is premitted to exist.
          if (hasValue(newOption, names[1])) {
            merged[names[2]] = null;
          } else if (hasValue(newOption, names[2])) {
            merged[names[1]] = null;
          }

          return merged;
        } // Case: newOption: {width: ..., right: ...},
        // or targetOption: {right: ...} and newOption: {width: ...},
        // There is no conflict when merged only has params count
        // little than enoughParamNumber.


        if (mergedValueCount === enoughParamNumber || !newValueCount) {
          return merged;
        } // Case: newOption: {width: ..., right: ...},
        // Than we can make sure user only want those two, and ignore
        // all origin params in targetOption.
        else if (newValueCount >= enoughParamNumber) {
            return newParams;
          } else {
            // Chose another param from targetOption by priority.
            for (var i = 0; i < names.length; i++) {
              var name_1 = names[i];

              if (!hasProp(newParams, name_1) && hasProp(targetOption, name_1)) {
                newParams[name_1] = targetOption[name_1];
                break;
              }
            }

            return newParams;
          }
      }

      function hasProp(obj, name) {
        return obj.hasOwnProperty(name);
      }

      function hasValue(obj, name) {
        return obj[name] != null && obj[name] !== 'auto';
      }

      function copy(names, target, source) {
        each$1(names, function (name) {
          target[name] = source[name];
        });
      }
    }
    /**
     * Retrieve 'left', 'right', 'top', 'bottom', 'width', 'height' from object.
     */

    function getLayoutParams(source) {
      return copyLayoutParams({}, source);
    }
    /**
     * Retrieve 'left', 'right', 'top', 'bottom', 'width', 'height' from object.
     * @param {Object} source
     * @return {Object} Result contains those props.
     */

    function copyLayoutParams(target, source) {
      source && target && each$1(LOCATION_PARAMS, function (name) {
        source.hasOwnProperty(name) && (target[name] = source[name]);
      });
      return target;
    }

    var inner = makeInner();

    var ComponentModel =
    /** @class */
    function (_super) {
      __extends(ComponentModel, _super);

      function ComponentModel(option, parentModel, ecModel) {
        var _this = _super.call(this, option, parentModel, ecModel) || this;

        _this.uid = getUID('ec_cpt_model');
        return _this;
      }

      ComponentModel.prototype.init = function (option, parentModel, ecModel) {
        this.mergeDefaultAndTheme(option, ecModel);
      };

      ComponentModel.prototype.mergeDefaultAndTheme = function (option, ecModel) {
        var layoutMode = fetchLayoutMode(this);
        var inputPositionParams = layoutMode ? getLayoutParams(option) : {};
        var themeModel = ecModel.getTheme();
        merge(option, themeModel.get(this.mainType));
        merge(option, this.getDefaultOption());

        if (layoutMode) {
          mergeLayoutParam(option, inputPositionParams, layoutMode);
        }
      };

      ComponentModel.prototype.mergeOption = function (option, ecModel) {
        merge(this.option, option, true);
        var layoutMode = fetchLayoutMode(this);

        if (layoutMode) {
          mergeLayoutParam(this.option, option, layoutMode);
        }
      };
      /**
       * Called immediately after `init` or `mergeOption` of this instance called.
       */


      ComponentModel.prototype.optionUpdated = function (newCptOption, isInit) {};
      /**
       * [How to declare defaultOption]:
       *
       * (A) If using class declaration in typescript (since echarts 5):
       * ```ts
       * import {ComponentOption} from '../model/option.js';
       * export interface XxxOption extends ComponentOption {
       *     aaa: number
       * }
       * export class XxxModel extends Component {
       *     static type = 'xxx';
       *     static defaultOption: XxxOption = {
       *         aaa: 123
       *     }
       * }
       * Component.registerClass(XxxModel);
       * ```
       * ```ts
       * import {inheritDefaultOption} from '../util/component.js';
       * import {XxxModel, XxxOption} from './XxxModel.js';
       * export interface XxxSubOption extends XxxOption {
       *     bbb: number
       * }
       * class XxxSubModel extends XxxModel {
       *     static defaultOption: XxxSubOption = inheritDefaultOption(XxxModel.defaultOption, {
       *         bbb: 456
       *     })
       *     fn() {
       *         let opt = this.getDefaultOption();
       *         // opt is {aaa: 123, bbb: 456}
       *     }
       * }
       * ```
       *
       * (B) If using class extend (previous approach in echarts 3 & 4):
       * ```js
       * let XxxComponent = Component.extend({
       *     defaultOption: {
       *         xx: 123
       *     }
       * })
       * ```
       * ```js
       * let XxxSubComponent = XxxComponent.extend({
       *     defaultOption: {
       *         yy: 456
       *     },
       *     fn: function () {
       *         let opt = this.getDefaultOption();
       *         // opt is {xx: 123, yy: 456}
       *     }
       * })
       * ```
       */


      ComponentModel.prototype.getDefaultOption = function () {
        var ctor = this.constructor; // If using class declaration, it is different to travel super class
        // in legacy env and auto merge defaultOption. So if using class
        // declaration, defaultOption should be merged manually.

        if (!isExtendedClass(ctor)) {
          // When using ts class, defaultOption must be declared as static.
          return ctor.defaultOption;
        } // FIXME: remove this approach?


        var fields = inner(this);

        if (!fields.defaultOption) {
          var optList = [];
          var clz = ctor;

          while (clz) {
            var opt = clz.prototype.defaultOption;
            opt && optList.push(opt);
            clz = clz.superClass;
          }

          var defaultOption = {};

          for (var i = optList.length - 1; i >= 0; i--) {
            defaultOption = merge(defaultOption, optList[i], true);
          }

          fields.defaultOption = defaultOption;
        }

        return fields.defaultOption;
      };
      /**
       * Notice: always force to input param `useDefault` in case that forget to consider it.
       * The same behavior as `modelUtil.parseFinder`.
       *
       * @param useDefault In many cases like series refer axis and axis refer grid,
       *        If axis index / axis id not specified, use the first target as default.
       *        In other cases like dataZoom refer axis, if not specified, measn no refer.
       */


      ComponentModel.prototype.getReferringComponents = function (mainType, opt) {
        var indexKey = mainType + 'Index';
        var idKey = mainType + 'Id';
        return queryReferringComponents(this.ecModel, mainType, {
          index: this.get(indexKey, true),
          id: this.get(idKey, true)
        }, opt);
      };

      ComponentModel.prototype.getBoxLayoutParams = function () {
        // Consider itself having box layout configs.
        var boxLayoutModel = this;
        return {
          left: boxLayoutModel.get('left'),
          top: boxLayoutModel.get('top'),
          right: boxLayoutModel.get('right'),
          bottom: boxLayoutModel.get('bottom'),
          width: boxLayoutModel.get('width'),
          height: boxLayoutModel.get('height')
        };
      };
      /**
       * Get key for zlevel.
       * If developers don't configure zlevel. We will assign zlevel to series based on the key.
       * For example, lines with trail effect and progressive series will in an individual zlevel.
       */


      ComponentModel.prototype.getZLevelKey = function () {
        return '';
      };

      ComponentModel.prototype.setZLevel = function (zlevel) {
        this.option.zlevel = zlevel;
      };

      ComponentModel.protoInitialize = function () {
        var proto = ComponentModel.prototype;
        proto.type = 'component';
        proto.id = '';
        proto.name = '';
        proto.mainType = '';
        proto.subType = '';
        proto.componentIndex = 0;
      }();

      return ComponentModel;
    }(Model);

    mountExtend(ComponentModel, Model);
    enableClassManagement(ComponentModel);
    enableSubTypeDefaulter(ComponentModel);
    enableTopologicalTravel(ComponentModel, getDependencies);

    function getDependencies(componentType) {
      var deps = [];
      each(ComponentModel.getClassesByMainType(componentType), function (clz) {
        deps = deps.concat(clz.dependencies || clz.prototype.dependencies || []);
      }); // Ensure main type.

      deps = map(deps, function (type) {
        return parseClassType(type).main;
      }); // Hack dataset for convenience.

      if (componentType !== 'dataset' && indexOf(deps, 'dataset') <= 0) {
        deps.unshift('dataset');
      }

      return deps;
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    var platform = ''; // Navigator not exists in node

    if (typeof navigator !== 'undefined') {
      /* global navigator */
      platform = navigator.platform || '';
    }

    var decalColor = 'rgba(0, 0, 0, 0.2)';
    var globalDefault = {
      darkMode: 'auto',
      // backgroundColor: 'rgba(0,0,0,0)',
      colorBy: 'series',
      color: ['#5470c6', '#91cc75', '#fac858', '#ee6666', '#73c0de', '#3ba272', '#fc8452', '#9a60b4', '#ea7ccc'],
      gradientColor: ['#f6efa6', '#d88273', '#bf444c'],
      aria: {
        decal: {
          decals: [{
            color: decalColor,
            dashArrayX: [1, 0],
            dashArrayY: [2, 5],
            symbolSize: 1,
            rotation: Math.PI / 6
          }, {
            color: decalColor,
            symbol: 'circle',
            dashArrayX: [[8, 8], [0, 8, 8, 0]],
            dashArrayY: [6, 0],
            symbolSize: 0.8
          }, {
            color: decalColor,
            dashArrayX: [1, 0],
            dashArrayY: [4, 3],
            rotation: -Math.PI / 4
          }, {
            color: decalColor,
            dashArrayX: [[6, 6], [0, 6, 6, 0]],
            dashArrayY: [6, 0]
          }, {
            color: decalColor,
            dashArrayX: [[1, 0], [1, 6]],
            dashArrayY: [1, 0, 6, 0],
            rotation: Math.PI / 4
          }, {
            color: decalColor,
            symbol: 'triangle',
            dashArrayX: [[9, 9], [0, 9, 9, 0]],
            dashArrayY: [7, 2],
            symbolSize: 0.75
          }]
        }
      },
      // If xAxis and yAxis declared, grid is created by default.
      // grid: {},
      textStyle: {
        // color: '#000',
        // decoration: 'none',
        // PENDING
        fontFamily: platform.match(/^Win/) ? 'Microsoft YaHei' : 'sans-serif',
        // fontFamily: 'Arial, Verdana, sans-serif',
        fontSize: 12,
        fontStyle: 'normal',
        fontWeight: 'normal'
      },
      // http://blogs.adobe.com/webplatform/2014/02/24/using-blend-modes-in-html-canvas/
      // https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
      // Default is source-over
      blendMode: null,
      stateAnimation: {
        duration: 300,
        easing: 'cubicOut'
      },
      animation: 'auto',
      animationDuration: 1000,
      animationDurationUpdate: 500,
      animationEasing: 'cubicInOut',
      animationEasingUpdate: 'cubicInOut',
      animationThreshold: 2000,
      // Configuration for progressive/incremental rendering
      progressiveThreshold: 3000,
      progressive: 400,
      // Threshold of if use single hover layer to optimize.
      // It is recommended that `hoverLayerThreshold` is equivalent to or less than
      // `progressiveThreshold`, otherwise hover will cause restart of progressive,
      // which is unexpected.
      // see example <echarts/test/heatmap-large.html>.
      hoverLayerThreshold: 3000,
      // See: module:echarts/scale/Time
      useUTC: false
    };

    var VISUAL_DIMENSIONS = createHashMap(['tooltip', 'label', 'itemName', 'itemId', 'itemGroupId', 'seriesName']);
    var SOURCE_FORMAT_ORIGINAL = 'original';
    var SOURCE_FORMAT_ARRAY_ROWS = 'arrayRows';
    var SOURCE_FORMAT_OBJECT_ROWS = 'objectRows';
    var SOURCE_FORMAT_KEYED_COLUMNS = 'keyedColumns';
    var SOURCE_FORMAT_TYPED_ARRAY = 'typedArray';
    var SOURCE_FORMAT_UNKNOWN = 'unknown';
    var SERIES_LAYOUT_BY_COLUMN = 'column';
    var SERIES_LAYOUT_BY_ROW = 'row';

    var BE_ORDINAL = {
      Must: 1,
      Might: 2,
      Not: 3 // Other cases

    };
    var innerGlobalModel = makeInner();
    /**
     * MUST be called before mergeOption of all series.
     */

    function resetSourceDefaulter(ecModel) {
      // `datasetMap` is used to make default encode.
      innerGlobalModel(ecModel).datasetMap = createHashMap();
    }
    /**
     * [The strategy of the arrengment of data dimensions for dataset]:
     * "value way": all axes are non-category axes. So series one by one take
     *     several (the number is coordSysDims.length) dimensions from dataset.
     *     The result of data arrengment of data dimensions like:
     *     | ser0_x | ser0_y | ser1_x | ser1_y | ser2_x | ser2_y |
     * "category way": at least one axis is category axis. So the the first data
     *     dimension is always mapped to the first category axis and shared by
     *     all of the series. The other data dimensions are taken by series like
     *     "value way" does.
     *     The result of data arrengment of data dimensions like:
     *     | ser_shared_x | ser0_y | ser1_y | ser2_y |
     *
     * @return encode Never be `null/undefined`.
     */

    function makeSeriesEncodeForAxisCoordSys(coordDimensions, seriesModel, source) {
      var encode = {};
      var datasetModel = querySeriesUpstreamDatasetModel(seriesModel); // Currently only make default when using dataset, util more reqirements occur.

      if (!datasetModel || !coordDimensions) {
        return encode;
      }

      var encodeItemName = [];
      var encodeSeriesName = [];
      var ecModel = seriesModel.ecModel;
      var datasetMap = innerGlobalModel(ecModel).datasetMap;
      var key = datasetModel.uid + '_' + source.seriesLayoutBy;
      var baseCategoryDimIndex;
      var categoryWayValueDimStart;
      coordDimensions = coordDimensions.slice();
      each(coordDimensions, function (coordDimInfoLoose, coordDimIdx) {
        var coordDimInfo = isObject(coordDimInfoLoose) ? coordDimInfoLoose : coordDimensions[coordDimIdx] = {
          name: coordDimInfoLoose
        };

        if (coordDimInfo.type === 'ordinal' && baseCategoryDimIndex == null) {
          baseCategoryDimIndex = coordDimIdx;
          categoryWayValueDimStart = getDataDimCountOnCoordDim(coordDimInfo);
        }

        encode[coordDimInfo.name] = [];
      });
      var datasetRecord = datasetMap.get(key) || datasetMap.set(key, {
        categoryWayDim: categoryWayValueDimStart,
        valueWayDim: 0
      }); // TODO
      // Auto detect first time axis and do arrangement.

      each(coordDimensions, function (coordDimInfo, coordDimIdx) {
        var coordDimName = coordDimInfo.name;
        var count = getDataDimCountOnCoordDim(coordDimInfo); // In value way.

        if (baseCategoryDimIndex == null) {
          var start = datasetRecord.valueWayDim;
          pushDim(encode[coordDimName], start, count);
          pushDim(encodeSeriesName, start, count);
          datasetRecord.valueWayDim += count; // ??? TODO give a better default series name rule?
          // especially when encode x y specified.
          // consider: when multiple series share one dimension
          // category axis, series name should better use
          // the other dimension name. On the other hand, use
          // both dimensions name.
        } // In category way, the first category axis.
        else if (baseCategoryDimIndex === coordDimIdx) {
            pushDim(encode[coordDimName], 0, count);
            pushDim(encodeItemName, 0, count);
          } // In category way, the other axis.
          else {
              var start = datasetRecord.categoryWayDim;
              pushDim(encode[coordDimName], start, count);
              pushDim(encodeSeriesName, start, count);
              datasetRecord.categoryWayDim += count;
            }
      });

      function pushDim(dimIdxArr, idxFrom, idxCount) {
        for (var i = 0; i < idxCount; i++) {
          dimIdxArr.push(idxFrom + i);
        }
      }

      function getDataDimCountOnCoordDim(coordDimInfo) {
        var dimsDef = coordDimInfo.dimsDef;
        return dimsDef ? dimsDef.length : 1;
      }

      encodeItemName.length && (encode.itemName = encodeItemName);
      encodeSeriesName.length && (encode.seriesName = encodeSeriesName);
      return encode;
    }
    /**
     * Work for data like [{name: ..., value: ...}, ...].
     *
     * @return encode Never be `null/undefined`.
     */

    function makeSeriesEncodeForNameBased(seriesModel, source, dimCount) {
      var encode = {};
      var datasetModel = querySeriesUpstreamDatasetModel(seriesModel); // Currently only make default when using dataset, util more reqirements occur.

      if (!datasetModel) {
        return encode;
      }

      var sourceFormat = source.sourceFormat;
      var dimensionsDefine = source.dimensionsDefine;
      var potentialNameDimIndex;

      if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS || sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) {
        each(dimensionsDefine, function (dim, idx) {
          if ((isObject(dim) ? dim.name : dim) === 'name') {
            potentialNameDimIndex = idx;
          }
        });
      }

      var idxResult = function () {
        var idxRes0 = {};
        var idxRes1 = {};
        var guessRecords = []; // 5 is an experience value.

        for (var i = 0, len = Math.min(5, dimCount); i < len; i++) {
          var guessResult = doGuessOrdinal(source.data, sourceFormat, source.seriesLayoutBy, dimensionsDefine, source.startIndex, i);
          guessRecords.push(guessResult);
          var isPureNumber = guessResult === BE_ORDINAL.Not; // [Strategy of idxRes0]: find the first BE_ORDINAL.Not as the value dim,
          // and then find a name dim with the priority:
          // "BE_ORDINAL.Might|BE_ORDINAL.Must" > "other dim" > "the value dim itself".

          if (isPureNumber && idxRes0.v == null && i !== potentialNameDimIndex) {
            idxRes0.v = i;
          }

          if (idxRes0.n == null || idxRes0.n === idxRes0.v || !isPureNumber && guessRecords[idxRes0.n] === BE_ORDINAL.Not) {
            idxRes0.n = i;
          }

          if (fulfilled(idxRes0) && guessRecords[idxRes0.n] !== BE_ORDINAL.Not) {
            return idxRes0;
          } // [Strategy of idxRes1]: if idxRes0 not satisfied (that is, no BE_ORDINAL.Not),
          // find the first BE_ORDINAL.Might as the value dim,
          // and then find a name dim with the priority:
          // "other dim" > "the value dim itself".
          // That is for backward compat: number-like (e.g., `'3'`, `'55'`) can be
          // treated as number.


          if (!isPureNumber) {
            if (guessResult === BE_ORDINAL.Might && idxRes1.v == null && i !== potentialNameDimIndex) {
              idxRes1.v = i;
            }

            if (idxRes1.n == null || idxRes1.n === idxRes1.v) {
              idxRes1.n = i;
            }
          }
        }

        function fulfilled(idxResult) {
          return idxResult.v != null && idxResult.n != null;
        }

        return fulfilled(idxRes0) ? idxRes0 : fulfilled(idxRes1) ? idxRes1 : null;
      }();

      if (idxResult) {
        encode.value = [idxResult.v]; // `potentialNameDimIndex` has highest priority.

        var nameDimIndex = potentialNameDimIndex != null ? potentialNameDimIndex : idxResult.n; // By default, label uses itemName in charts.
        // So we don't set encodeLabel here.

        encode.itemName = [nameDimIndex];
        encode.seriesName = [nameDimIndex];
      }

      return encode;
    }
    /**
     * @return If return null/undefined, indicate that should not use datasetModel.
     */

    function querySeriesUpstreamDatasetModel(seriesModel) {
      // Caution: consider the scenario:
      // A dataset is declared and a series is not expected to use the dataset,
      // and at the beginning `setOption({series: { noData })` (just prepare other
      // option but no data), then `setOption({series: {data: [...]}); In this case,
      // the user should set an empty array to avoid that dataset is used by default.
      var thisData = seriesModel.get('data', true);

      if (!thisData) {
        return queryReferringComponents(seriesModel.ecModel, 'dataset', {
          index: seriesModel.get('datasetIndex', true),
          id: seriesModel.get('datasetId', true)
        }, SINGLE_REFERRING).models[0];
      }
    }
    /**
     * @return Always return an array event empty.
     */

    function queryDatasetUpstreamDatasetModels(datasetModel) {
      // Only these attributes declared, we by defualt reference to `datasetIndex: 0`.
      // Otherwise, no reference.
      if (!datasetModel.get('transform', true) && !datasetModel.get('fromTransformResult', true)) {
        return [];
      }

      return queryReferringComponents(datasetModel.ecModel, 'dataset', {
        index: datasetModel.get('fromDatasetIndex', true),
        id: datasetModel.get('fromDatasetId', true)
      }, SINGLE_REFERRING).models;
    }
    /**
     * The rule should not be complex, otherwise user might not
     * be able to known where the data is wrong.
     * The code is ugly, but how to make it neat?
     */

    function guessOrdinal(source, dimIndex) {
      return doGuessOrdinal(source.data, source.sourceFormat, source.seriesLayoutBy, source.dimensionsDefine, source.startIndex, dimIndex);
    } // dimIndex may be overflow source data.
    // return {BE_ORDINAL}

    function doGuessOrdinal(data, sourceFormat, seriesLayoutBy, dimensionsDefine, startIndex, dimIndex) {
      var result; // Experience value.

      var maxLoop = 5;

      if (isTypedArray(data)) {
        return BE_ORDINAL.Not;
      } // When sourceType is 'objectRows' or 'keyedColumns', dimensionsDefine
      // always exists in source.


      var dimName;
      var dimType;

      if (dimensionsDefine) {
        var dimDefItem = dimensionsDefine[dimIndex];

        if (isObject(dimDefItem)) {
          dimName = dimDefItem.name;
          dimType = dimDefItem.type;
        } else if (isString(dimDefItem)) {
          dimName = dimDefItem;
        }
      }

      if (dimType != null) {
        return dimType === 'ordinal' ? BE_ORDINAL.Must : BE_ORDINAL.Not;
      }

      if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) {
        var dataArrayRows = data;

        if (seriesLayoutBy === SERIES_LAYOUT_BY_ROW) {
          var sample = dataArrayRows[dimIndex];

          for (var i = 0; i < (sample || []).length && i < maxLoop; i++) {
            if ((result = detectValue(sample[startIndex + i])) != null) {
              return result;
            }
          }
        } else {
          for (var i = 0; i < dataArrayRows.length && i < maxLoop; i++) {
            var row = dataArrayRows[startIndex + i];

            if (row && (result = detectValue(row[dimIndex])) != null) {
              return result;
            }
          }
        }
      } else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) {
        var dataObjectRows = data;

        if (!dimName) {
          return BE_ORDINAL.Not;
        }

        for (var i = 0; i < dataObjectRows.length && i < maxLoop; i++) {
          var item = dataObjectRows[i];

          if (item && (result = detectValue(item[dimName])) != null) {
            return result;
          }
        }
      } else if (sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) {
        var dataKeyedColumns = data;

        if (!dimName) {
          return BE_ORDINAL.Not;
        }

        var sample = dataKeyedColumns[dimName];

        if (!sample || isTypedArray(sample)) {
          return BE_ORDINAL.Not;
        }

        for (var i = 0; i < sample.length && i < maxLoop; i++) {
          if ((result = detectValue(sample[i])) != null) {
            return result;
          }
        }
      } else if (sourceFormat === SOURCE_FORMAT_ORIGINAL) {
        var dataOriginal = data;

        for (var i = 0; i < dataOriginal.length && i < maxLoop; i++) {
          var item = dataOriginal[i];
          var val = getDataItemValue(item);

          if (!isArray(val)) {
            return BE_ORDINAL.Not;
          }

          if ((result = detectValue(val[dimIndex])) != null) {
            return result;
          }
        }
      }

      function detectValue(val) {
        var beStr = isString(val); // Consider usage convenience, '1', '2' will be treated as "number".
        // `isFinit('')` get `true`.

        if (val != null && isFinite(val) && val !== '') {
          return beStr ? BE_ORDINAL.Might : BE_ORDINAL.Not;
        } else if (beStr && val !== '-') {
          return BE_ORDINAL.Must;
        }
      }

      return BE_ORDINAL.Not;
    }

    var internalOptionCreatorMap = createHashMap();
    function concatInternalOptions(ecModel, mainType, newCmptOptionList) {
      var internalOptionCreator = internalOptionCreatorMap.get(mainType);

      if (!internalOptionCreator) {
        return newCmptOptionList;
      }

      var internalOptions = internalOptionCreator(ecModel);

      if (!internalOptions) {
        return newCmptOptionList;
      }

      if ("development" !== 'production') {
        for (var i = 0; i < internalOptions.length; i++) {
          assert(isComponentIdInternal(internalOptions[i]));
        }
      }

      return newCmptOptionList.concat(internalOptions);
    }

    var innerColor = makeInner();
    var innerDecal = makeInner();

    var PaletteMixin =
    /** @class */
    function () {
      function PaletteMixin() {}

      PaletteMixin.prototype.getColorFromPalette = function (name, scope, requestNum) {
        var defaultPalette = normalizeToArray(this.get('color', true));
        var layeredPalette = this.get('colorLayer', true);
        return getFromPalette(this, innerColor, defaultPalette, layeredPalette, name, scope, requestNum);
      };

      PaletteMixin.prototype.clearColorPalette = function () {
        clearPalette(this, innerColor);
      };

      return PaletteMixin;
    }();

    function getDecalFromPalette(ecModel, name, scope, requestNum) {
      var defaultDecals = normalizeToArray(ecModel.get(['aria', 'decal', 'decals']));
      return getFromPalette(ecModel, innerDecal, defaultDecals, null, name, scope, requestNum);
    }

    function getNearestPalette(palettes, requestColorNum) {
      var paletteNum = palettes.length; // TODO palettes must be in order

      for (var i = 0; i < paletteNum; i++) {
        if (palettes[i].length > requestColorNum) {
          return palettes[i];
        }
      }

      return palettes[paletteNum - 1];
    }
    /**
     * @param name MUST NOT be null/undefined. Otherwise call this function
     *             twise with the same parameters will get different result.
     * @param scope default this.
     * @return Can be null/undefined
     */


    function getFromPalette(that, inner, defaultPalette, layeredPalette, name, scope, requestNum) {
      scope = scope || that;
      var scopeFields = inner(scope);
      var paletteIdx = scopeFields.paletteIdx || 0;
      var paletteNameMap = scopeFields.paletteNameMap = scopeFields.paletteNameMap || {}; // Use `hasOwnProperty` to avoid conflict with Object.prototype.

      if (paletteNameMap.hasOwnProperty(name)) {
        return paletteNameMap[name];
      }

      var palette = requestNum == null || !layeredPalette ? defaultPalette : getNearestPalette(layeredPalette, requestNum); // In case can't find in layered color palette.

      palette = palette || defaultPalette;

      if (!palette || !palette.length) {
        return;
      }

      var pickedPaletteItem = palette[paletteIdx];

      if (name) {
        paletteNameMap[name] = pickedPaletteItem;
      }

      scopeFields.paletteIdx = (paletteIdx + 1) % palette.length;
      return pickedPaletteItem;
    }

    function clearPalette(that, inner) {
      inner(that).paletteIdx = 0;
      inner(that).paletteNameMap = {};
    }

    // Internal method names:
    // -----------------------

    var reCreateSeriesIndices;
    var assertSeriesInitialized;
    var initBase;
    var OPTION_INNER_KEY = '\0_ec_inner';
    var OPTION_INNER_VALUE = 1;
    var BUITIN_COMPONENTS_MAP = {
      grid: 'GridComponent',
      polar: 'PolarComponent',
      geo: 'GeoComponent',
      singleAxis: 'SingleAxisComponent',
      parallel: 'ParallelComponent',
      calendar: 'CalendarComponent',
      graphic: 'GraphicComponent',
      toolbox: 'ToolboxComponent',
      tooltip: 'TooltipComponent',
      axisPointer: 'AxisPointerComponent',
      brush: 'BrushComponent',
      title: 'TitleComponent',
      timeline: 'TimelineComponent',
      markPoint: 'MarkPointComponent',
      markLine: 'MarkLineComponent',
      markArea: 'MarkAreaComponent',
      legend: 'LegendComponent',
      dataZoom: 'DataZoomComponent',
      visualMap: 'VisualMapComponent',
      // aria: 'AriaComponent',
      // dataset: 'DatasetComponent',
      // Dependencies
      xAxis: 'GridComponent',
      yAxis: 'GridComponent',
      angleAxis: 'PolarComponent',
      radiusAxis: 'PolarComponent'
    };
    var BUILTIN_CHARTS_MAP = {
      line: 'LineChart',
      bar: 'BarChart',
      pie: 'PieChart',
      scatter: 'ScatterChart',
      radar: 'RadarChart',
      map: 'MapChart',
      tree: 'TreeChart',
      treemap: 'TreemapChart',
      graph: 'GraphChart',
      gauge: 'GaugeChart',
      funnel: 'FunnelChart',
      parallel: 'ParallelChart',
      sankey: 'SankeyChart',
      boxplot: 'BoxplotChart',
      candlestick: 'CandlestickChart',
      effectScatter: 'EffectScatterChart',
      lines: 'LinesChart',
      heatmap: 'HeatmapChart',
      pictorialBar: 'PictorialBarChart',
      themeRiver: 'ThemeRiverChart',
      sunburst: 'SunburstChart',
      custom: 'CustomChart'
    };
    var componetsMissingLogPrinted = {};

    function checkMissingComponents(option) {
      each(option, function (componentOption, mainType) {
        if (!ComponentModel.hasClass(mainType)) {
          var componentImportName = BUITIN_COMPONENTS_MAP[mainType];

          if (componentImportName && !componetsMissingLogPrinted[componentImportName]) {
            error("Component " + mainType + " is used but not imported.\nimport { " + componentImportName + " } from 'echarts/components';\necharts.use([" + componentImportName + "]);");
            componetsMissingLogPrinted[componentImportName] = true;
          }
        }
      });
    }

    var GlobalModel =
    /** @class */
    function (_super) {
      __extends(GlobalModel, _super);

      function GlobalModel() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      GlobalModel.prototype.init = function (option, parentModel, ecModel, theme, locale, optionManager) {
        theme = theme || {};
        this.option = null; // Mark as not initialized.

        this._theme = new Model(theme);
        this._locale = new Model(locale);
        this._optionManager = optionManager;
      };

      GlobalModel.prototype.setOption = function (option, opts, optionPreprocessorFuncs) {
        if ("development" !== 'production') {
          assert(option != null, 'option is null/undefined');
          assert(option[OPTION_INNER_KEY] !== OPTION_INNER_VALUE, 'please use chart.getOption()');
        }

        var innerOpt = normalizeSetOptionInput(opts);

        this._optionManager.setOption(option, optionPreprocessorFuncs, innerOpt);

        this._resetOption(null, innerOpt);
      };
      /**
       * @param type null/undefined: reset all.
       *        'recreate': force recreate all.
       *        'timeline': only reset timeline option
       *        'media': only reset media query option
       * @return Whether option changed.
       */


      GlobalModel.prototype.resetOption = function (type, opt) {
        return this._resetOption(type, normalizeSetOptionInput(opt));
      };

      GlobalModel.prototype._resetOption = function (type, opt) {
        var optionChanged = false;
        var optionManager = this._optionManager;

        if (!type || type === 'recreate') {
          var baseOption = optionManager.mountOption(type === 'recreate');

          if ("development" !== 'production') {
            checkMissingComponents(baseOption);
          }

          if (!this.option || type === 'recreate') {
            initBase(this, baseOption);
          } else {
            this.restoreData();

            this._mergeOption(baseOption, opt);
          }

          optionChanged = true;
        }

        if (type === 'timeline' || type === 'media') {
          this.restoreData();
        } // By design, if `setOption(option2)` at the second time, and `option2` is a `ECUnitOption`,
        // it should better not have the same props with `MediaUnit['option']`.
        // Because either `option2` or `MediaUnit['option']` will be always merged to "current option"
        // rather than original "baseOption". If they both override a prop, the result might be
        // unexpected when media state changed after `setOption` called.
        // If we really need to modify a props in each `MediaUnit['option']`, use the full version
        // (`{baseOption, media}`) in `setOption`.
        // For `timeline`, the case is the same.


        if (!type || type === 'recreate' || type === 'timeline') {
          var timelineOption = optionManager.getTimelineOption(this);

          if (timelineOption) {
            optionChanged = true;

            this._mergeOption(timelineOption, opt);
          }
        }

        if (!type || type === 'recreate' || type === 'media') {
          var mediaOptions = optionManager.getMediaOption(this);

          if (mediaOptions.length) {
            each(mediaOptions, function (mediaOption) {
              optionChanged = true;

              this._mergeOption(mediaOption, opt);
            }, this);
          }
        }

        return optionChanged;
      };

      GlobalModel.prototype.mergeOption = function (option) {
        this._mergeOption(option, null);
      };

      GlobalModel.prototype._mergeOption = function (newOption, opt) {
        var option = this.option;
        var componentsMap = this._componentsMap;
        var componentsCount = this._componentsCount;
        var newCmptTypes = [];
        var newCmptTypeMap = createHashMap();
        var replaceMergeMainTypeMap = opt && opt.replaceMergeMainTypeMap;
        resetSourceDefaulter(this); // If no component class, merge directly.
        // For example: color, animaiton options, etc.

        each(newOption, function (componentOption, mainType) {
          if (componentOption == null) {
            return;
          }

          if (!ComponentModel.hasClass(mainType)) {
            // globalSettingTask.dirty();
            option[mainType] = option[mainType] == null ? clone(componentOption) : merge(option[mainType], componentOption, true);
          } else if (mainType) {
            newCmptTypes.push(mainType);
            newCmptTypeMap.set(mainType, true);
          }
        });

        if (replaceMergeMainTypeMap) {
          // If there is a mainType `xxx` in `replaceMerge` but not declared in option,
          // we trade it as it is declared in option as `{xxx: []}`. Because:
          // (1) for normal merge, `{xxx: null/undefined}` are the same meaning as `{xxx: []}`.
          // (2) some preprocessor may convert some of `{xxx: null/undefined}` to `{xxx: []}`.
          replaceMergeMainTypeMap.each(function (val, mainTypeInReplaceMerge) {
            if (ComponentModel.hasClass(mainTypeInReplaceMerge) && !newCmptTypeMap.get(mainTypeInReplaceMerge)) {
              newCmptTypes.push(mainTypeInReplaceMerge);
              newCmptTypeMap.set(mainTypeInReplaceMerge, true);
            }
          });
        }

        ComponentModel.topologicalTravel(newCmptTypes, ComponentModel.getAllClassMainTypes(), visitComponent, this);

        function visitComponent(mainType) {
          var newCmptOptionList = concatInternalOptions(this, mainType, normalizeToArray(newOption[mainType]));
          var oldCmptList = componentsMap.get(mainType);
          var mergeMode = // `!oldCmptList` means init. See the comment in `mappingToExists`
          !oldCmptList ? 'replaceAll' : replaceMergeMainTypeMap && replaceMergeMainTypeMap.get(mainType) ? 'replaceMerge' : 'normalMerge';
          var mappingResult = mappingToExists(oldCmptList, newCmptOptionList, mergeMode); // Set mainType and complete subType.

          setComponentTypeToKeyInfo(mappingResult, mainType, ComponentModel); // Empty it before the travel, in order to prevent `this._componentsMap`
          // from being used in the `init`/`mergeOption`/`optionUpdated` of some
          // components, which is probably incorrect logic.

          option[mainType] = null;
          componentsMap.set(mainType, null);
          componentsCount.set(mainType, 0);
          var optionsByMainType = [];
          var cmptsByMainType = [];
          var cmptsCountByMainType = 0;
          var tooltipExists;
          var tooltipWarningLogged;
          each(mappingResult, function (resultItem, index) {
            var componentModel = resultItem.existing;
            var newCmptOption = resultItem.newOption;

            if (!newCmptOption) {
              if (componentModel) {
                // Consider where is no new option and should be merged using {},
                // see removeEdgeAndAdd in topologicalTravel and
                // ComponentModel.getAllClassMainTypes.
                componentModel.mergeOption({}, this);
                componentModel.optionUpdated({}, false);
              } // If no both `resultItem.exist` and `resultItem.option`,
              // either it is in `replaceMerge` and not matched by any id,
              // or it has been removed in previous `replaceMerge` and left a "hole" in this component index.

            } else {
              var isSeriesType = mainType === 'series';
              var ComponentModelClass = ComponentModel.getClass(mainType, resultItem.keyInfo.subType, !isSeriesType // Give a more detailed warn later if series don't exists
              );

              if (!ComponentModelClass) {
                if ("development" !== 'production') {
                  var subType = resultItem.keyInfo.subType;
                  var seriesImportName = BUILTIN_CHARTS_MAP[subType];

                  if (!componetsMissingLogPrinted[subType]) {
                    componetsMissingLogPrinted[subType] = true;

                    if (seriesImportName) {
                      error("Series " + subType + " is used but not imported.\nimport { " + seriesImportName + " } from 'echarts/charts';\necharts.use([" + seriesImportName + "]);");
                    } else {
                      error("Unknown series " + subType);
                    }
                  }
                }

                return;
              } // TODO Before multiple tooltips get supported, we do this check to avoid unexpected exception.


              if (mainType === 'tooltip') {
                if (tooltipExists) {
                  if ("development" !== 'production') {
                    if (!tooltipWarningLogged) {
                      warn('Currently only one tooltip component is allowed.');
                      tooltipWarningLogged = true;
                    }
                  }

                  return;
                }

                tooltipExists = true;
              }

              if (componentModel && componentModel.constructor === ComponentModelClass) {
                componentModel.name = resultItem.keyInfo.name; // componentModel.settingTask && componentModel.settingTask.dirty();

                componentModel.mergeOption(newCmptOption, this);
                componentModel.optionUpdated(newCmptOption, false);
              } else {
                // PENDING Global as parent ?
                var extraOpt = extend({
                  componentIndex: index
                }, resultItem.keyInfo);
                componentModel = new ComponentModelClass(newCmptOption, this, this, extraOpt); // Assign `keyInfo`

                extend(componentModel, extraOpt);

                if (resultItem.brandNew) {
                  componentModel.__requireNewView = true;
                }

                componentModel.init(newCmptOption, this, this); // Call optionUpdated after init.
                // newCmptOption has been used as componentModel.option
                // and may be merged with theme and default, so pass null
                // to avoid confusion.

                componentModel.optionUpdated(null, true);
              }
            }

            if (componentModel) {
              optionsByMainType.push(componentModel.option);
              cmptsByMainType.push(componentModel);
              cmptsCountByMainType++;
            } else {
              // Always do assign to avoid elided item in array.
              optionsByMainType.push(void 0);
              cmptsByMainType.push(void 0);
            }
          }, this);
          option[mainType] = optionsByMainType;
          componentsMap.set(mainType, cmptsByMainType);
          componentsCount.set(mainType, cmptsCountByMainType); // Backup series for filtering.

          if (mainType === 'series') {
            reCreateSeriesIndices(this);
          }
        } // If no series declared, ensure `_seriesIndices` initialized.


        if (!this._seriesIndices) {
          reCreateSeriesIndices(this);
        }
      };
      /**
       * Get option for output (cloned option and inner info removed)
       */


      GlobalModel.prototype.getOption = function () {
        var option = clone(this.option);
        each(option, function (optInMainType, mainType) {
          if (ComponentModel.hasClass(mainType)) {
            var opts = normalizeToArray(optInMainType); // Inner cmpts need to be removed.
            // Inner cmpts might not be at last since ec5.0, but still
            // compatible for users: if inner cmpt at last, splice the returned array.

            var realLen = opts.length;
            var metNonInner = false;

            for (var i = realLen - 1; i >= 0; i--) {
              // Remove options with inner id.
              if (opts[i] && !isComponentIdInternal(opts[i])) {
                metNonInner = true;
              } else {
                opts[i] = null;
                !metNonInner && realLen--;
              }
            }

            opts.length = realLen;
            option[mainType] = opts;
          }
        });
        delete option[OPTION_INNER_KEY];
        return option;
      };

      GlobalModel.prototype.getTheme = function () {
        return this._theme;
      };

      GlobalModel.prototype.getLocaleModel = function () {
        return this._locale;
      };

      GlobalModel.prototype.setUpdatePayload = function (payload) {
        this._payload = payload;
      };

      GlobalModel.prototype.getUpdatePayload = function () {
        return this._payload;
      };
      /**
       * @param idx If not specified, return the first one.
       */


      GlobalModel.prototype.getComponent = function (mainType, idx) {
        var list = this._componentsMap.get(mainType);

        if (list) {
          var cmpt = list[idx || 0];

          if (cmpt) {
            return cmpt;
          } else if (idx == null) {
            for (var i = 0; i < list.length; i++) {
              if (list[i]) {
                return list[i];
              }
            }
          }
        }
      };
      /**
       * @return Never be null/undefined.
       */


      GlobalModel.prototype.queryComponents = function (condition) {
        var mainType = condition.mainType;

        if (!mainType) {
          return [];
        }

        var index = condition.index;
        var id = condition.id;
        var name = condition.name;

        var cmpts = this._componentsMap.get(mainType);

        if (!cmpts || !cmpts.length) {
          return [];
        }

        var result;

        if (index != null) {
          result = [];
          each(normalizeToArray(index), function (idx) {
            cmpts[idx] && result.push(cmpts[idx]);
          });
        } else if (id != null) {
          result = queryByIdOrName('id', id, cmpts);
        } else if (name != null) {
          result = queryByIdOrName('name', name, cmpts);
        } else {
          // Return all non-empty components in that mainType
          result = filter(cmpts, function (cmpt) {
            return !!cmpt;
          });
        }

        return filterBySubType(result, condition);
      };
      /**
       * The interface is different from queryComponents,
       * which is convenient for inner usage.
       *
       * @usage
       * let result = findComponents(
       *     {mainType: 'dataZoom', query: {dataZoomId: 'abc'}}
       * );
       * let result = findComponents(
       *     {mainType: 'series', subType: 'pie', query: {seriesName: 'uio'}}
       * );
       * let result = findComponents(
       *     {mainType: 'series',
       *     filter: function (model, index) {...}}
       * );
       * // result like [component0, componnet1, ...]
       */


      GlobalModel.prototype.findComponents = function (condition) {
        var query = condition.query;
        var mainType = condition.mainType;
        var queryCond = getQueryCond(query);
        var result = queryCond ? this.queryComponents(queryCond) // Retrieve all non-empty components.
        : filter(this._componentsMap.get(mainType), function (cmpt) {
          return !!cmpt;
        });
        return doFilter(filterBySubType(result, condition));

        function getQueryCond(q) {
          var indexAttr = mainType + 'Index';
          var idAttr = mainType + 'Id';
          var nameAttr = mainType + 'Name';
          return q && (q[indexAttr] != null || q[idAttr] != null || q[nameAttr] != null) ? {
            mainType: mainType,
            // subType will be filtered finally.
            index: q[indexAttr],
            id: q[idAttr],
            name: q[nameAttr]
          } : null;
        }

        function doFilter(res) {
          return condition.filter ? filter(res, condition.filter) : res;
        }
      };

      GlobalModel.prototype.eachComponent = function (mainType, cb, context) {
        var componentsMap = this._componentsMap;

        if (isFunction(mainType)) {
          var ctxForAll_1 = cb;
          var cbForAll_1 = mainType;
          componentsMap.each(function (cmpts, componentType) {
            for (var i = 0; cmpts && i < cmpts.length; i++) {
              var cmpt = cmpts[i];
              cmpt && cbForAll_1.call(ctxForAll_1, componentType, cmpt, cmpt.componentIndex);
            }
          });
        } else {
          var cmpts = isString(mainType) ? componentsMap.get(mainType) : isObject(mainType) ? this.findComponents(mainType) : null;

          for (var i = 0; cmpts && i < cmpts.length; i++) {
            var cmpt = cmpts[i];
            cmpt && cb.call(context, cmpt, cmpt.componentIndex);
          }
        }
      };
      /**
       * Get series list before filtered by name.
       */


      GlobalModel.prototype.getSeriesByName = function (name) {
        var nameStr = convertOptionIdName(name, null);
        return filter(this._componentsMap.get('series'), function (oneSeries) {
          return !!oneSeries && nameStr != null && oneSeries.name === nameStr;
        });
      };
      /**
       * Get series list before filtered by index.
       */


      GlobalModel.prototype.getSeriesByIndex = function (seriesIndex) {
        return this._componentsMap.get('series')[seriesIndex];
      };
      /**
       * Get series list before filtered by type.
       * FIXME: rename to getRawSeriesByType?
       */


      GlobalModel.prototype.getSeriesByType = function (subType) {
        return filter(this._componentsMap.get('series'), function (oneSeries) {
          return !!oneSeries && oneSeries.subType === subType;
        });
      };
      /**
       * Get all series before filtered.
       */


      GlobalModel.prototype.getSeries = function () {
        return filter(this._componentsMap.get('series'), function (oneSeries) {
          return !!oneSeries;
        });
      };
      /**
       * Count series before filtered.
       */


      GlobalModel.prototype.getSeriesCount = function () {
        return this._componentsCount.get('series');
      };
      /**
       * After filtering, series may be different
       * from raw series.
       */


      GlobalModel.prototype.eachSeries = function (cb, context) {
        assertSeriesInitialized(this);
        each(this._seriesIndices, function (rawSeriesIndex) {
          var series = this._componentsMap.get('series')[rawSeriesIndex];

          cb.call(context, series, rawSeriesIndex);
        }, this);
      };
      /**
       * Iterate raw series before filtered.
       *
       * @param {Function} cb
       * @param {*} context
       */


      GlobalModel.prototype.eachRawSeries = function (cb, context) {
        each(this._componentsMap.get('series'), function (series) {
          series && cb.call(context, series, series.componentIndex);
        });
      };
      /**
       * After filtering, series may be different.
       * from raw series.
       */


      GlobalModel.prototype.eachSeriesByType = function (subType, cb, context) {
        assertSeriesInitialized(this);
        each(this._seriesIndices, function (rawSeriesIndex) {
          var series = this._componentsMap.get('series')[rawSeriesIndex];

          if (series.subType === subType) {
            cb.call(context, series, rawSeriesIndex);
          }
        }, this);
      };
      /**
       * Iterate raw series before filtered of given type.
       */


      GlobalModel.prototype.eachRawSeriesByType = function (subType, cb, context) {
        return each(this.getSeriesByType(subType), cb, context);
      };

      GlobalModel.prototype.isSeriesFiltered = function (seriesModel) {
        assertSeriesInitialized(this);
        return this._seriesIndicesMap.get(seriesModel.componentIndex) == null;
      };

      GlobalModel.prototype.getCurrentSeriesIndices = function () {
        return (this._seriesIndices || []).slice();
      };

      GlobalModel.prototype.filterSeries = function (cb, context) {
        assertSeriesInitialized(this);
        var newSeriesIndices = [];
        each(this._seriesIndices, function (seriesRawIdx) {
          var series = this._componentsMap.get('series')[seriesRawIdx];

          cb.call(context, series, seriesRawIdx) && newSeriesIndices.push(seriesRawIdx);
        }, this);
        this._seriesIndices = newSeriesIndices;
        this._seriesIndicesMap = createHashMap(newSeriesIndices);
      };

      GlobalModel.prototype.restoreData = function (payload) {
        reCreateSeriesIndices(this);
        var componentsMap = this._componentsMap;
        var componentTypes = [];
        componentsMap.each(function (components, componentType) {
          if (ComponentModel.hasClass(componentType)) {
            componentTypes.push(componentType);
          }
        });
        ComponentModel.topologicalTravel(componentTypes, ComponentModel.getAllClassMainTypes(), function (componentType) {
          each(componentsMap.get(componentType), function (component) {
            if (component && (componentType !== 'series' || !isNotTargetSeries(component, payload))) {
              component.restoreData();
            }
          });
        });
      };

      GlobalModel.internalField = function () {
        reCreateSeriesIndices = function (ecModel) {
          var seriesIndices = ecModel._seriesIndices = [];
          each(ecModel._componentsMap.get('series'), function (series) {
            // series may have been removed by `replaceMerge`.
            series && seriesIndices.push(series.componentIndex);
          });
          ecModel._seriesIndicesMap = createHashMap(seriesIndices);
        };

        assertSeriesInitialized = function (ecModel) {
          // Components that use _seriesIndices should depends on series component,
          // which make sure that their initialization is after series.
          if ("development" !== 'production') {
            if (!ecModel._seriesIndices) {
              throw new Error('Option should contains series.');
            }
          }
        };

        initBase = function (ecModel, baseOption) {
          // Using OPTION_INNER_KEY to mark that this option cannot be used outside,
          // i.e. `chart.setOption(chart.getModel().option);` is forbidden.
          ecModel.option = {};
          ecModel.option[OPTION_INNER_KEY] = OPTION_INNER_VALUE; // Init with series: [], in case of calling findSeries method
          // before series initialized.

          ecModel._componentsMap = createHashMap({
            series: []
          });
          ecModel._componentsCount = createHashMap(); // If user spefied `option.aria`, aria will be enable. This detection should be
          // performed before theme and globalDefault merge.

          var airaOption = baseOption.aria;

          if (isObject(airaOption) && airaOption.enabled == null) {
            airaOption.enabled = true;
          }

          mergeTheme(baseOption, ecModel._theme.option); // TODO Needs clone when merging to the unexisted property

          merge(baseOption, globalDefault, false);

          ecModel._mergeOption(baseOption, null);
        };
      }();

      return GlobalModel;
    }(Model);

    function isNotTargetSeries(seriesModel, payload) {
      if (payload) {
        var index = payload.seriesIndex;
        var id = payload.seriesId;
        var name_1 = payload.seriesName;
        return index != null && seriesModel.componentIndex !== index || id != null && seriesModel.id !== id || name_1 != null && seriesModel.name !== name_1;
      }
    }

    function mergeTheme(option, theme) {
      // PENDING
      // NOT use `colorLayer` in theme if option has `color`
      var notMergeColorLayer = option.color && !option.colorLayer;
      each(theme, function (themeItem, name) {
        if (name === 'colorLayer' && notMergeColorLayer) {
          return;
        } // If it is component model mainType, the model handles that merge later.
        // otherwise, merge them here.


        if (!ComponentModel.hasClass(name)) {
          if (typeof themeItem === 'object') {
            option[name] = !option[name] ? clone(themeItem) : merge(option[name], themeItem, false);
          } else {
            if (option[name] == null) {
              option[name] = themeItem;
            }
          }
        }
      });
    }

    function queryByIdOrName(attr, idOrName, cmpts) {
      // Here is a break from echarts4: string and number are
      // treated as equal.
      if (isArray(idOrName)) {
        var keyMap_1 = createHashMap();
        each(idOrName, function (idOrNameItem) {
          if (idOrNameItem != null) {
            var idName = convertOptionIdName(idOrNameItem, null);
            idName != null && keyMap_1.set(idOrNameItem, true);
          }
        });
        return filter(cmpts, function (cmpt) {
          return cmpt && keyMap_1.get(cmpt[attr]);
        });
      } else {
        var idName_1 = convertOptionIdName(idOrName, null);
        return filter(cmpts, function (cmpt) {
          return cmpt && idName_1 != null && cmpt[attr] === idName_1;
        });
      }
    }

    function filterBySubType(components, condition) {
      // Using hasOwnProperty for restrict. Consider
      // subType is undefined in user payload.
      return condition.hasOwnProperty('subType') ? filter(components, function (cmpt) {
        return cmpt && cmpt.subType === condition.subType;
      }) : components;
    }

    function normalizeSetOptionInput(opts) {
      var replaceMergeMainTypeMap = createHashMap();
      opts && each(normalizeToArray(opts.replaceMerge), function (mainType) {
        if ("development" !== 'production') {
          assert(ComponentModel.hasClass(mainType), '"' + mainType + '" is not valid component main type in "replaceMerge"');
        }

        replaceMergeMainTypeMap.set(mainType, true);
      });
      return {
        replaceMergeMainTypeMap: replaceMergeMainTypeMap
      };
    }

    mixin(GlobalModel, PaletteMixin);

    var availableMethods = ['getDom', 'getZr', 'getWidth', 'getHeight', 'getDevicePixelRatio', 'dispatchAction', 'isSSR', 'isDisposed', 'on', 'off', 'getDataURL', 'getConnectedDataURL', // 'getModel',
    'getOption', // 'getViewOfComponentModel',
    // 'getViewOfSeriesModel',
    'getId', 'updateLabelLayout'];

    var ExtensionAPI =
    /** @class */
    function () {
      function ExtensionAPI(ecInstance) {
        each(availableMethods, function (methodName) {
          this[methodName] = bind(ecInstance[methodName], ecInstance);
        }, this);
      }

      return ExtensionAPI;
    }();

    var coordinateSystemCreators = {};

    var CoordinateSystemManager =
    /** @class */
    function () {
      function CoordinateSystemManager() {
        this._coordinateSystems = [];
      }

      CoordinateSystemManager.prototype.create = function (ecModel, api) {
        var coordinateSystems = [];
        each(coordinateSystemCreators, function (creator, type) {
          var list = creator.create(ecModel, api);
          coordinateSystems = coordinateSystems.concat(list || []);
        });
        this._coordinateSystems = coordinateSystems;
      };

      CoordinateSystemManager.prototype.update = function (ecModel, api) {
        each(this._coordinateSystems, function (coordSys) {
          coordSys.update && coordSys.update(ecModel, api);
        });
      };

      CoordinateSystemManager.prototype.getCoordinateSystems = function () {
        return this._coordinateSystems.slice();
      };

      CoordinateSystemManager.register = function (type, creator) {
        coordinateSystemCreators[type] = creator;
      };

      CoordinateSystemManager.get = function (type) {
        return coordinateSystemCreators[type];
      };

      return CoordinateSystemManager;
    }();

    var QUERY_REG = /^(min|max)?(.+)$/; // Key: mainType
    // type FakeComponentsMap = HashMap<(MappingExistingItem & { subType: string })[]>;

    /**
     * TERM EXPLANATIONS:
     * See `ECOption` and `ECUnitOption` in `src/util/types.ts`.
     */

    var OptionManager =
    /** @class */
    function () {
      // timeline.notMerge is not supported in ec3. Firstly there is rearly
      // case that notMerge is needed. Secondly supporting 'notMerge' requires
      // rawOption cloned and backuped when timeline changed, which does no
      // good to performance. What's more, that both timeline and setOption
      // method supply 'notMerge' brings complex and some problems.
      // Consider this case:
      // (step1) chart.setOption({timeline: {notMerge: false}, ...}, false);
      // (step2) chart.setOption({timeline: {notMerge: true}, ...}, false);
      function OptionManager(api) {
        this._timelineOptions = [];
        this._mediaList = [];
        /**
         * -1, means default.
         * empty means no media.
         */

        this._currentMediaIndices = [];
        this._api = api;
      }

      OptionManager.prototype.setOption = function (rawOption, optionPreprocessorFuncs, opt) {
        if (rawOption) {
          // That set dat primitive is dangerous if user reuse the data when setOption again.
          each(normalizeToArray(rawOption.series), function (series) {
            series && series.data && isTypedArray(series.data) && setAsPrimitive(series.data);
          });
          each(normalizeToArray(rawOption.dataset), function (dataset) {
            dataset && dataset.source && isTypedArray(dataset.source) && setAsPrimitive(dataset.source);
          });
        } // Caution: some series modify option data, if do not clone,
        // it should ensure that the repeat modify correctly
        // (create a new object when modify itself).


        rawOption = clone(rawOption); // FIXME
        // If some property is set in timeline options or media option but
        // not set in baseOption, a warning should be given.

        var optionBackup = this._optionBackup;
        var newParsedOption = parseRawOption(rawOption, optionPreprocessorFuncs, !optionBackup);
        this._newBaseOption = newParsedOption.baseOption; // For setOption at second time (using merge mode);

        if (optionBackup) {
          // FIXME
          // the restore merge solution is essentially incorrect.
          // the mapping can not be 100% consistent with ecModel, which probably brings
          // potential bug!
          // The first merge is delayed, because in most cases, users do not call `setOption` twice.
          // let fakeCmptsMap = this._fakeCmptsMap;
          // if (!fakeCmptsMap) {
          //     fakeCmptsMap = this._fakeCmptsMap = createHashMap();
          //     mergeToBackupOption(fakeCmptsMap, null, optionBackup.baseOption, null);
          // }
          // mergeToBackupOption(
          //     fakeCmptsMap, optionBackup.baseOption, newParsedOption.baseOption, opt
          // );
          // For simplicity, timeline options and media options do not support merge,
          // that is, if you `setOption` twice and both has timeline options, the latter
          // timeline options will not be merged to the former, but just substitute them.
          if (newParsedOption.timelineOptions.length) {
            optionBackup.timelineOptions = newParsedOption.timelineOptions;
          }

          if (newParsedOption.mediaList.length) {
            optionBackup.mediaList = newParsedOption.mediaList;
          }

          if (newParsedOption.mediaDefault) {
            optionBackup.mediaDefault = newParsedOption.mediaDefault;
          }
        } else {
          this._optionBackup = newParsedOption;
        }
      };

      OptionManager.prototype.mountOption = function (isRecreate) {
        var optionBackup = this._optionBackup;
        this._timelineOptions = optionBackup.timelineOptions;
        this._mediaList = optionBackup.mediaList;
        this._mediaDefault = optionBackup.mediaDefault;
        this._currentMediaIndices = [];
        return clone(isRecreate // this._optionBackup.baseOption, which is created at the first `setOption`
        // called, and is merged into every new option by inner method `mergeToBackupOption`
        // each time `setOption` called, can be only used in `isRecreate`, because
        // its reliability is under suspicion. In other cases option merge is
        // performed by `model.mergeOption`.
        ? optionBackup.baseOption : this._newBaseOption);
      };

      OptionManager.prototype.getTimelineOption = function (ecModel) {
        var option;
        var timelineOptions = this._timelineOptions;

        if (timelineOptions.length) {
          // getTimelineOption can only be called after ecModel inited,
          // so we can get currentIndex from timelineModel.
          var timelineModel = ecModel.getComponent('timeline');

          if (timelineModel) {
            option = clone( // FIXME:TS as TimelineModel or quivlant interface
            timelineOptions[timelineModel.getCurrentIndex()]);
          }
        }

        return option;
      };

      OptionManager.prototype.getMediaOption = function (ecModel) {
        var ecWidth = this._api.getWidth();

        var ecHeight = this._api.getHeight();

        var mediaList = this._mediaList;
        var mediaDefault = this._mediaDefault;
        var indices = [];
        var result = []; // No media defined.

        if (!mediaList.length && !mediaDefault) {
          return result;
        } // Multi media may be applied, the latter defined media has higher priority.


        for (var i = 0, len = mediaList.length; i < len; i++) {
          if (applyMediaQuery(mediaList[i].query, ecWidth, ecHeight)) {
            indices.push(i);
          }
        } // FIXME
        // Whether mediaDefault should force users to provide? Otherwise
        // the change by media query can not be recorvered.


        if (!indices.length && mediaDefault) {
          indices = [-1];
        }

        if (indices.length && !indicesEquals(indices, this._currentMediaIndices)) {
          result = map(indices, function (index) {
            return clone(index === -1 ? mediaDefault.option : mediaList[index].option);
          });
        } // Otherwise return nothing.


        this._currentMediaIndices = indices;
        return result;
      };

      return OptionManager;
    }();
    /**
     * [RAW_OPTION_PATTERNS]
     * (Note: "series: []" represents all other props in `ECUnitOption`)
     *
     * (1) No prop "baseOption" declared:
     * Root option is used as "baseOption" (except prop "options" and "media").
     * ```js
     * option = {
     *     series: [],
     *     timeline: {},
     *     options: [],
     * };
     * option = {
     *     series: [],
     *     media: {},
     * };
     * option = {
     *     series: [],
     *     timeline: {},
     *     options: [],
     *     media: {},
     * }
     * ```
     *
     * (2) Prop "baseOption" declared:
     * If "baseOption" declared, `ECUnitOption` props can only be declared
     * inside "baseOption" except prop "timeline" (compat ec2).
     * ```js
     * option = {
     *     baseOption: {
     *         timeline: {},
     *         series: [],
     *     },
     *     options: []
     * };
     * option = {
     *     baseOption: {
     *         series: [],
     *     },
     *     media: []
     * };
     * option = {
     *     baseOption: {
     *         timeline: {},
     *         series: [],
     *     },
     *     options: []
     *     media: []
     * };
     * option = {
     *     // ec3 compat ec2: allow (only) `timeline` declared
     *     // outside baseOption. Keep this setting for compat.
     *     timeline: {},
     *     baseOption: {
     *         series: [],
     *     },
     *     options: [],
     *     media: []
     * };
     * ```
     */


    function parseRawOption( // `rawOption` May be modified
    rawOption, optionPreprocessorFuncs, isNew) {
      var mediaList = [];
      var mediaDefault;
      var baseOption;
      var declaredBaseOption = rawOption.baseOption; // Compatible with ec2, [RAW_OPTION_PATTERNS] above.

      var timelineOnRoot = rawOption.timeline;
      var timelineOptionsOnRoot = rawOption.options;
      var mediaOnRoot = rawOption.media;
      var hasMedia = !!rawOption.media;
      var hasTimeline = !!(timelineOptionsOnRoot || timelineOnRoot || declaredBaseOption && declaredBaseOption.timeline);

      if (declaredBaseOption) {
        baseOption = declaredBaseOption; // For merge option.

        if (!baseOption.timeline) {
          baseOption.timeline = timelineOnRoot;
        }
      } // For convenience, enable to use the root option as the `baseOption`:
      // `{ ...normalOptionProps, media: [{ ... }, { ... }] }`
      else {
          if (hasTimeline || hasMedia) {
            rawOption.options = rawOption.media = null;
          }

          baseOption = rawOption;
        }

      if (hasMedia) {
        if (isArray(mediaOnRoot)) {
          each(mediaOnRoot, function (singleMedia) {
            if ("development" !== 'production') {
              // Real case of wrong config.
              if (singleMedia && !singleMedia.option && isObject(singleMedia.query) && isObject(singleMedia.query.option)) {
                error('Illegal media option. Must be like { media: [ { query: {}, option: {} } ] }');
              }
            }

            if (singleMedia && singleMedia.option) {
              if (singleMedia.query) {
                mediaList.push(singleMedia);
              } else if (!mediaDefault) {
                // Use the first media default.
                mediaDefault = singleMedia;
              }
            }
          });
        } else {
          if ("development" !== 'production') {
            // Real case of wrong config.
            error('Illegal media option. Must be an array. Like { media: [ {...}, {...} ] }');
          }
        }
      }

      doPreprocess(baseOption);
      each(timelineOptionsOnRoot, function (option) {
        return doPreprocess(option);
      });
      each(mediaList, function (media) {
        return doPreprocess(media.option);
      });

      function doPreprocess(option) {
        each(optionPreprocessorFuncs, function (preProcess) {
          preProcess(option, isNew);
        });
      }

      return {
        baseOption: baseOption,
        timelineOptions: timelineOptionsOnRoot || [],
        mediaDefault: mediaDefault,
        mediaList: mediaList
      };
    }
    /**
     * @see <http://www.w3.org/TR/css3-mediaqueries/#media1>
     * Support: width, height, aspectRatio
     * Can use max or min as prefix.
     */


    function applyMediaQuery(query, ecWidth, ecHeight) {
      var realMap = {
        width: ecWidth,
        height: ecHeight,
        aspectratio: ecWidth / ecHeight // lower case for convenience.

      };
      var applicable = true;
      each(query, function (value, attr) {
        var matched = attr.match(QUERY_REG);

        if (!matched || !matched[1] || !matched[2]) {
          return;
        }

        var operator = matched[1];
        var realAttr = matched[2].toLowerCase();

        if (!compare(realMap[realAttr], value, operator)) {
          applicable = false;
        }
      });
      return applicable;
    }

    function compare(real, expect, operator) {
      if (operator === 'min') {
        return real >= expect;
      } else if (operator === 'max') {
        return real <= expect;
      } else {
        // Equals
        return real === expect;
      }
    }

    function indicesEquals(indices1, indices2) {
      // indices is always order by asc and has only finite number.
      return indices1.join(',') === indices2.join(',');
    }

    var each$2 = each;
    var isObject$1 = isObject;
    var POSSIBLE_STYLES = ['areaStyle', 'lineStyle', 'nodeStyle', 'linkStyle', 'chordStyle', 'label', 'labelLine'];

    function compatEC2ItemStyle(opt) {
      var itemStyleOpt = opt && opt.itemStyle;

      if (!itemStyleOpt) {
        return;
      }

      for (var i = 0, len = POSSIBLE_STYLES.length; i < len; i++) {
        var styleName = POSSIBLE_STYLES[i];
        var normalItemStyleOpt = itemStyleOpt.normal;
        var emphasisItemStyleOpt = itemStyleOpt.emphasis;

        if (normalItemStyleOpt && normalItemStyleOpt[styleName]) {
          if ("development" !== 'production') {
            deprecateReplaceLog("itemStyle.normal." + styleName, styleName);
          }

          opt[styleName] = opt[styleName] || {};

          if (!opt[styleName].normal) {
            opt[styleName].normal = normalItemStyleOpt[styleName];
          } else {
            merge(opt[styleName].normal, normalItemStyleOpt[styleName]);
          }

          normalItemStyleOpt[styleName] = null;
        }

        if (emphasisItemStyleOpt && emphasisItemStyleOpt[styleName]) {
          if ("development" !== 'production') {
            deprecateReplaceLog("itemStyle.emphasis." + styleName, "emphasis." + styleName);
          }

          opt[styleName] = opt[styleName] || {};

          if (!opt[styleName].emphasis) {
            opt[styleName].emphasis = emphasisItemStyleOpt[styleName];
          } else {
            merge(opt[styleName].emphasis, emphasisItemStyleOpt[styleName]);
          }

          emphasisItemStyleOpt[styleName] = null;
        }
      }
    }

    function convertNormalEmphasis(opt, optType, useExtend) {
      if (opt && opt[optType] && (opt[optType].normal || opt[optType].emphasis)) {
        var normalOpt = opt[optType].normal;
        var emphasisOpt = opt[optType].emphasis;

        if (normalOpt) {
          if ("development" !== 'production') {
            // eslint-disable-next-line max-len
            deprecateLog("'normal' hierarchy in " + optType + " has been removed since 4.0. All style properties are configured in " + optType + " directly now.");
          } // Timeline controlStyle has other properties besides normal and emphasis


          if (useExtend) {
            opt[optType].normal = opt[optType].emphasis = null;
            defaults(opt[optType], normalOpt);
          } else {
            opt[optType] = normalOpt;
          }
        }

        if (emphasisOpt) {
          if ("development" !== 'production') {
            deprecateLog(optType + ".emphasis has been changed to emphasis." + optType + " since 4.0");
          }

          opt.emphasis = opt.emphasis || {};
          opt.emphasis[optType] = emphasisOpt; // Also compat the case user mix the style and focus together in ec3 style
          // for example: { itemStyle: { normal: {}, emphasis: {focus, shadowBlur} } }

          if (emphasisOpt.focus) {
            opt.emphasis.focus = emphasisOpt.focus;
          }

          if (emphasisOpt.blurScope) {
            opt.emphasis.blurScope = emphasisOpt.blurScope;
          }
        }
      }
    }

    function removeEC3NormalStatus(opt) {
      convertNormalEmphasis(opt, 'itemStyle');
      convertNormalEmphasis(opt, 'lineStyle');
      convertNormalEmphasis(opt, 'areaStyle');
      convertNormalEmphasis(opt, 'label');
      convertNormalEmphasis(opt, 'labelLine'); // treemap

      convertNormalEmphasis(opt, 'upperLabel'); // graph

      convertNormalEmphasis(opt, 'edgeLabel');
    }

    function compatTextStyle(opt, propName) {
      // Check whether is not object (string\null\undefined ...)
      var labelOptSingle = isObject$1(opt) && opt[propName];
      var textStyle = isObject$1(labelOptSingle) && labelOptSingle.textStyle;

      if (textStyle) {
        if ("development" !== 'production') {
          // eslint-disable-next-line max-len
          deprecateLog("textStyle hierarchy in " + propName + " has been removed since 4.0. All textStyle properties are configured in " + propName + " directly now.");
        }

        for (var i = 0, len = TEXT_STYLE_OPTIONS.length; i < len; i++) {
          var textPropName = TEXT_STYLE_OPTIONS[i];

          if (textStyle.hasOwnProperty(textPropName)) {
            labelOptSingle[textPropName] = textStyle[textPropName];
          }
        }
      }
    }

    function compatEC3CommonStyles(opt) {
      if (opt) {
        removeEC3NormalStatus(opt);
        compatTextStyle(opt, 'label');
        opt.emphasis && compatTextStyle(opt.emphasis, 'label');
      }
    }

    function processSeries(seriesOpt) {
      if (!isObject$1(seriesOpt)) {
        return;
      }

      compatEC2ItemStyle(seriesOpt);
      removeEC3NormalStatus(seriesOpt);
      compatTextStyle(seriesOpt, 'label'); // treemap

      compatTextStyle(seriesOpt, 'upperLabel'); // graph

      compatTextStyle(seriesOpt, 'edgeLabel');

      if (seriesOpt.emphasis) {
        compatTextStyle(seriesOpt.emphasis, 'label'); // treemap

        compatTextStyle(seriesOpt.emphasis, 'upperLabel'); // graph

        compatTextStyle(seriesOpt.emphasis, 'edgeLabel');
      }

      var markPoint = seriesOpt.markPoint;

      if (markPoint) {
        compatEC2ItemStyle(markPoint);
        compatEC3CommonStyles(markPoint);
      }

      var markLine = seriesOpt.markLine;

      if (markLine) {
        compatEC2ItemStyle(markLine);
        compatEC3CommonStyles(markLine);
      }

      var markArea = seriesOpt.markArea;

      if (markArea) {
        compatEC3CommonStyles(markArea);
      }

      var data = seriesOpt.data; // Break with ec3: if `setOption` again, there may be no `type` in option,
      // then the backward compat based on option type will not be performed.

      if (seriesOpt.type === 'graph') {
        data = data || seriesOpt.nodes;
        var edgeData = seriesOpt.links || seriesOpt.edges;

        if (edgeData && !isTypedArray(edgeData)) {
          for (var i = 0; i < edgeData.length; i++) {
            compatEC3CommonStyles(edgeData[i]);
          }
        }

        each(seriesOpt.categories, function (opt) {
          removeEC3NormalStatus(opt);
        });
      }

      if (data && !isTypedArray(data)) {
        for (var i = 0; i < data.length; i++) {
          compatEC3CommonStyles(data[i]);
        }
      } // mark point data


      markPoint = seriesOpt.markPoint;

      if (markPoint && markPoint.data) {
        var mpData = markPoint.data;

        for (var i = 0; i < mpData.length; i++) {
          compatEC3CommonStyles(mpData[i]);
        }
      } // mark line data


      markLine = seriesOpt.markLine;

      if (markLine && markLine.data) {
        var mlData = markLine.data;

        for (var i = 0; i < mlData.length; i++) {
          if (isArray(mlData[i])) {
            compatEC3CommonStyles(mlData[i][0]);
            compatEC3CommonStyles(mlData[i][1]);
          } else {
            compatEC3CommonStyles(mlData[i]);
          }
        }
      } // Series


      if (seriesOpt.type === 'gauge') {
        compatTextStyle(seriesOpt, 'axisLabel');
        compatTextStyle(seriesOpt, 'title');
        compatTextStyle(seriesOpt, 'detail');
      } else if (seriesOpt.type === 'treemap') {
        convertNormalEmphasis(seriesOpt.breadcrumb, 'itemStyle');
        each(seriesOpt.levels, function (opt) {
          removeEC3NormalStatus(opt);
        });
      } else if (seriesOpt.type === 'tree') {
        removeEC3NormalStatus(seriesOpt.leaves);
      } // sunburst starts from ec4, so it does not need to compat levels.

    }

    function toArr(o) {
      return isArray(o) ? o : o ? [o] : [];
    }

    function toObj(o) {
      return (isArray(o) ? o[0] : o) || {};
    }

    function globalCompatStyle(option, isTheme) {
      each$2(toArr(option.series), function (seriesOpt) {
        isObject$1(seriesOpt) && processSeries(seriesOpt);
      });
      var axes = ['xAxis', 'yAxis', 'radiusAxis', 'angleAxis', 'singleAxis', 'parallelAxis', 'radar'];
      isTheme && axes.push('valueAxis', 'categoryAxis', 'logAxis', 'timeAxis');
      each$2(axes, function (axisName) {
        each$2(toArr(option[axisName]), function (axisOpt) {
          if (axisOpt) {
            compatTextStyle(axisOpt, 'axisLabel');
            compatTextStyle(axisOpt.axisPointer, 'label');
          }
        });
      });
      each$2(toArr(option.parallel), function (parallelOpt) {
        var parallelAxisDefault = parallelOpt && parallelOpt.parallelAxisDefault;
        compatTextStyle(parallelAxisDefault, 'axisLabel');
        compatTextStyle(parallelAxisDefault && parallelAxisDefault.axisPointer, 'label');
      });
      each$2(toArr(option.calendar), function (calendarOpt) {
        convertNormalEmphasis(calendarOpt, 'itemStyle');
        compatTextStyle(calendarOpt, 'dayLabel');
        compatTextStyle(calendarOpt, 'monthLabel');
        compatTextStyle(calendarOpt, 'yearLabel');
      }); // radar.name.textStyle

      each$2(toArr(option.radar), function (radarOpt) {
        compatTextStyle(radarOpt, 'name'); // Use axisName instead of name because component has name property

        if (radarOpt.name && radarOpt.axisName == null) {
          radarOpt.axisName = radarOpt.name;
          delete radarOpt.name;

          if ("development" !== 'production') {
            deprecateLog('name property in radar component has been changed to axisName');
          }
        }

        if (radarOpt.nameGap != null && radarOpt.axisNameGap == null) {
          radarOpt.axisNameGap = radarOpt.nameGap;
          delete radarOpt.nameGap;

          if ("development" !== 'production') {
            deprecateLog('nameGap property in radar component has been changed to axisNameGap');
          }
        }

        if ("development" !== 'production') {
          each$2(radarOpt.indicator, function (indicatorOpt) {
            if (indicatorOpt.text) {
              deprecateReplaceLog('text', 'name', 'radar.indicator');
            }
          });
        }
      });
      each$2(toArr(option.geo), function (geoOpt) {
        if (isObject$1(geoOpt)) {
          compatEC3CommonStyles(geoOpt);
          each$2(toArr(geoOpt.regions), function (regionObj) {
            compatEC3CommonStyles(regionObj);
          });
        }
      });
      each$2(toArr(option.timeline), function (timelineOpt) {
        compatEC3CommonStyles(timelineOpt);
        convertNormalEmphasis(timelineOpt, 'label');
        convertNormalEmphasis(timelineOpt, 'itemStyle');
        convertNormalEmphasis(timelineOpt, 'controlStyle', true);
        var data = timelineOpt.data;
        isArray(data) && each(data, function (item) {
          if (isObject(item)) {
            convertNormalEmphasis(item, 'label');
            convertNormalEmphasis(item, 'itemStyle');
          }
        });
      });
      each$2(toArr(option.toolbox), function (toolboxOpt) {
        convertNormalEmphasis(toolboxOpt, 'iconStyle');
        each$2(toolboxOpt.feature, function (featureOpt) {
          convertNormalEmphasis(featureOpt, 'iconStyle');
        });
      });
      compatTextStyle(toObj(option.axisPointer), 'label');
      compatTextStyle(toObj(option.tooltip).axisPointer, 'label'); // Clean logs
      // storedLogs = {};
    }

    function get(opt, path) {
      var pathArr = path.split(',');
      var obj = opt;

      for (var i = 0; i < pathArr.length; i++) {
        obj = obj && obj[pathArr[i]];

        if (obj == null) {
          break;
        }
      }

      return obj;
    }

    function set$1(opt, path, val, overwrite) {
      var pathArr = path.split(',');
      var obj = opt;
      var key;
      var i = 0;

      for (; i < pathArr.length - 1; i++) {
        key = pathArr[i];

        if (obj[key] == null) {
          obj[key] = {};
        }

        obj = obj[key];
      }

      if (overwrite || obj[pathArr[i]] == null) {
        obj[pathArr[i]] = val;
      }
    }

    function compatLayoutProperties(option) {
      option && each(LAYOUT_PROPERTIES, function (prop) {
        if (prop[0] in option && !(prop[1] in option)) {
          option[prop[1]] = option[prop[0]];
        }
      });
    }

    var LAYOUT_PROPERTIES = [['x', 'left'], ['y', 'top'], ['x2', 'right'], ['y2', 'bottom']];
    var COMPATITABLE_COMPONENTS = ['grid', 'geo', 'parallel', 'legend', 'toolbox', 'title', 'visualMap', 'dataZoom', 'timeline'];
    var BAR_ITEM_STYLE_MAP = [['borderRadius', 'barBorderRadius'], ['borderColor', 'barBorderColor'], ['borderWidth', 'barBorderWidth']];

    function compatBarItemStyle(option) {
      var itemStyle = option && option.itemStyle;

      if (itemStyle) {
        for (var i = 0; i < BAR_ITEM_STYLE_MAP.length; i++) {
          var oldName = BAR_ITEM_STYLE_MAP[i][1];
          var newName = BAR_ITEM_STYLE_MAP[i][0];

          if (itemStyle[oldName] != null) {
            itemStyle[newName] = itemStyle[oldName];

            if ("development" !== 'production') {
              deprecateReplaceLog(oldName, newName);
            }
          }
        }
      }
    }

    function compatPieLabel(option) {
      if (!option) {
        return;
      }

      if (option.alignTo === 'edge' && option.margin != null && option.edgeDistance == null) {
        if ("development" !== 'production') {
          deprecateReplaceLog('label.margin', 'label.edgeDistance', 'pie');
        }

        option.edgeDistance = option.margin;
      }
    }

    function compatSunburstState(option) {
      if (!option) {
        return;
      }

      if (option.downplay && !option.blur) {
        option.blur = option.downplay;

        if ("development" !== 'production') {
          deprecateReplaceLog('downplay', 'blur', 'sunburst');
        }
      }
    }

    function compatGraphFocus(option) {
      if (!option) {
        return;
      }

      if (option.focusNodeAdjacency != null) {
        option.emphasis = option.emphasis || {};

        if (option.emphasis.focus == null) {
          if ("development" !== 'production') {
            deprecateReplaceLog('focusNodeAdjacency', 'emphasis: { focus: \'adjacency\'}', 'graph/sankey');
          }

          option.emphasis.focus = 'adjacency';
        }
      }
    }

    function traverseTree(data, cb) {
      if (data) {
        for (var i = 0; i < data.length; i++) {
          cb(data[i]);
          data[i] && traverseTree(data[i].children, cb);
        }
      }
    }

    function globalBackwardCompat(option, isTheme) {
      globalCompatStyle(option, isTheme); // Make sure series array for model initialization.

      option.series = normalizeToArray(option.series);
      each(option.series, function (seriesOpt) {
        if (!isObject(seriesOpt)) {
          return;
        }

        var seriesType = seriesOpt.type;

        if (seriesType === 'line') {
          if (seriesOpt.clipOverflow != null) {
            seriesOpt.clip = seriesOpt.clipOverflow;

            if ("development" !== 'production') {
              deprecateReplaceLog('clipOverflow', 'clip', 'line');
            }
          }
        } else if (seriesType === 'pie' || seriesType === 'gauge') {
          if (seriesOpt.clockWise != null) {
            seriesOpt.clockwise = seriesOpt.clockWise;

            if ("development" !== 'production') {
              deprecateReplaceLog('clockWise', 'clockwise');
            }
          }

          compatPieLabel(seriesOpt.label);
          var data = seriesOpt.data;

          if (data && !isTypedArray(data)) {
            for (var i = 0; i < data.length; i++) {
              compatPieLabel(data[i]);
            }
          }

          if (seriesOpt.hoverOffset != null) {
            seriesOpt.emphasis = seriesOpt.emphasis || {};

            if (seriesOpt.emphasis.scaleSize = null) {
              if ("development" !== 'production') {
                deprecateReplaceLog('hoverOffset', 'emphasis.scaleSize');
              }

              seriesOpt.emphasis.scaleSize = seriesOpt.hoverOffset;
            }
          }
        } else if (seriesType === 'gauge') {
          var pointerColor = get(seriesOpt, 'pointer.color');
          pointerColor != null && set$1(seriesOpt, 'itemStyle.color', pointerColor);
        } else if (seriesType === 'bar') {
          compatBarItemStyle(seriesOpt);
          compatBarItemStyle(seriesOpt.backgroundStyle);
          compatBarItemStyle(seriesOpt.emphasis);
          var data = seriesOpt.data;

          if (data && !isTypedArray(data)) {
            for (var i = 0; i < data.length; i++) {
              if (typeof data[i] === 'object') {
                compatBarItemStyle(data[i]);
                compatBarItemStyle(data[i] && data[i].emphasis);
              }
            }
          }
        } else if (seriesType === 'sunburst') {
          var highlightPolicy = seriesOpt.highlightPolicy;

          if (highlightPolicy) {
            seriesOpt.emphasis = seriesOpt.emphasis || {};

            if (!seriesOpt.emphasis.focus) {
              seriesOpt.emphasis.focus = highlightPolicy;

              if ("development" !== 'production') {
                deprecateReplaceLog('highlightPolicy', 'emphasis.focus', 'sunburst');
              }
            }
          }

          compatSunburstState(seriesOpt);
          traverseTree(seriesOpt.data, compatSunburstState);
        } else if (seriesType === 'graph' || seriesType === 'sankey') {
          compatGraphFocus(seriesOpt); // TODO nodes, edges?
        } else if (seriesType === 'map') {
          if (seriesOpt.mapType && !seriesOpt.map) {
            if ("development" !== 'production') {
              deprecateReplaceLog('mapType', 'map', 'map');
            }

            seriesOpt.map = seriesOpt.mapType;
          }

          if (seriesOpt.mapLocation) {
            if ("development" !== 'production') {
              deprecateLog('`mapLocation` is not used anymore.');
            }

            defaults(seriesOpt, seriesOpt.mapLocation);
          }
        }

        if (seriesOpt.hoverAnimation != null) {
          seriesOpt.emphasis = seriesOpt.emphasis || {};

          if (seriesOpt.emphasis && seriesOpt.emphasis.scale == null) {
            if ("development" !== 'production') {
              deprecateReplaceLog('hoverAnimation', 'emphasis.scale');
            }

            seriesOpt.emphasis.scale = seriesOpt.hoverAnimation;
          }
        }

        compatLayoutProperties(seriesOpt);
      }); // dataRange has changed to visualMap

      if (option.dataRange) {
        option.visualMap = option.dataRange;
      }

      each(COMPATITABLE_COMPONENTS, function (componentName) {
        var options = option[componentName];

        if (options) {
          if (!isArray(options)) {
            options = [options];
          }

          each(options, function (option) {
            compatLayoutProperties(option);
          });
        }
      });
    }

    //     data processing stage is blocked in stream.
    //     See <module:echarts/stream/Scheduler#performDataProcessorTasks>
    // (2) Only register once when import repeatedly.
    //     Should be executed after series is filtered and before stack calculation.

    function dataStack(ecModel) {
      var stackInfoMap = createHashMap();
      ecModel.eachSeries(function (seriesModel) {
        var stack = seriesModel.get('stack'); // Compatible: when `stack` is set as '', do not stack.

        if (stack) {
          var stackInfoList = stackInfoMap.get(stack) || stackInfoMap.set(stack, []);
          var data = seriesModel.getData();
          var stackInfo = {
            // Used for calculate axis extent automatically.
            // TODO: Type getCalculationInfo return more specific type?
            stackResultDimension: data.getCalculationInfo('stackResultDimension'),
            stackedOverDimension: data.getCalculationInfo('stackedOverDimension'),
            stackedDimension: data.getCalculationInfo('stackedDimension'),
            stackedByDimension: data.getCalculationInfo('stackedByDimension'),
            isStackedByIndex: data.getCalculationInfo('isStackedByIndex'),
            data: data,
            seriesModel: seriesModel
          }; // If stacked on axis that do not support data stack.

          if (!stackInfo.stackedDimension || !(stackInfo.isStackedByIndex || stackInfo.stackedByDimension)) {
            return;
          }

          stackInfoList.length && data.setCalculationInfo('stackedOnSeries', stackInfoList[stackInfoList.length - 1].seriesModel);
          stackInfoList.push(stackInfo);
        }
      });
      stackInfoMap.each(calculateStack);
    }

    function calculateStack(stackInfoList) {
      each(stackInfoList, function (targetStackInfo, idxInStack) {
        var resultVal = [];
        var resultNaN = [NaN, NaN];
        var dims = [targetStackInfo.stackResultDimension, targetStackInfo.stackedOverDimension];
        var targetData = targetStackInfo.data;
        var isStackedByIndex = targetStackInfo.isStackedByIndex;
        var stackStrategy = targetStackInfo.seriesModel.get('stackStrategy') || 'samesign'; // Should not write on raw data, because stack series model list changes
        // depending on legend selection.

        targetData.modify(dims, function (v0, v1, dataIndex) {
          var sum = targetData.get(targetStackInfo.stackedDimension, dataIndex); // Consider `connectNulls` of line area, if value is NaN, stackedOver
          // should also be NaN, to draw a appropriate belt area.

          if (isNaN(sum)) {
            return resultNaN;
          }

          var byValue;
          var stackedDataRawIndex;

          if (isStackedByIndex) {
            stackedDataRawIndex = targetData.getRawIndex(dataIndex);
          } else {
            byValue = targetData.get(targetStackInfo.stackedByDimension, dataIndex);
          } // If stackOver is NaN, chart view will render point on value start.


          var stackedOver = NaN;

          for (var j = idxInStack - 1; j >= 0; j--) {
            var stackInfo = stackInfoList[j]; // Has been optimized by inverted indices on `stackedByDimension`.

            if (!isStackedByIndex) {
              stackedDataRawIndex = stackInfo.data.rawIndexOf(stackInfo.stackedByDimension, byValue);
            }

            if (stackedDataRawIndex >= 0) {
              var val = stackInfo.data.getByRawIndex(stackInfo.stackResultDimension, stackedDataRawIndex); // Considering positive stack, negative stack and empty data

              if (stackStrategy === 'all' // single stack group
              || stackStrategy === 'positive' && val > 0 || stackStrategy === 'negative' && val < 0 || stackStrategy === 'samesign' && sum > 0 && val > 0 // All positive stack
              || stackStrategy === 'samesign' && sum < 0 && val < 0 // All negative stack
              ) {
                  // The sum has to be very small to be affected by the
                  // floating arithmetic problem. An incorrect result will probably
                  // cause axis min/max to be filtered incorrectly.
                  sum = addSafe(sum, val);
                  stackedOver = val;
                  break;
                }
            }
          }

          resultVal[0] = sum;
          resultVal[1] = stackedOver;
          return resultVal;
        });
      });
    }

    var SourceImpl =
    /** @class */
    function () {
      function SourceImpl(fields) {
        this.data = fields.data || (fields.sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS ? {} : []);
        this.sourceFormat = fields.sourceFormat || SOURCE_FORMAT_UNKNOWN; // Visit config

        this.seriesLayoutBy = fields.seriesLayoutBy || SERIES_LAYOUT_BY_COLUMN;
        this.startIndex = fields.startIndex || 0;
        this.dimensionsDetectedCount = fields.dimensionsDetectedCount;
        this.metaRawOption = fields.metaRawOption;
        var dimensionsDefine = this.dimensionsDefine = fields.dimensionsDefine;

        if (dimensionsDefine) {
          for (var i = 0; i < dimensionsDefine.length; i++) {
            var dim = dimensionsDefine[i];

            if (dim.type == null) {
              if (guessOrdinal(this, i) === BE_ORDINAL.Must) {
                dim.type = 'ordinal';
              }
            }
          }
        }
      }

      return SourceImpl;
    }();

    function isSourceInstance(val) {
      return val instanceof SourceImpl;
    }
    /**
     * Create a source from option.
     * NOTE: Created source is immutable. Don't change any properties in it.
     */

    function createSource(sourceData, thisMetaRawOption, // can be null. If not provided, auto detect it from `sourceData`.
    sourceFormat) {
      sourceFormat = sourceFormat || detectSourceFormat(sourceData);
      var seriesLayoutBy = thisMetaRawOption.seriesLayoutBy;
      var determined = determineSourceDimensions(sourceData, sourceFormat, seriesLayoutBy, thisMetaRawOption.sourceHeader, thisMetaRawOption.dimensions);
      var source = new SourceImpl({
        data: sourceData,
        sourceFormat: sourceFormat,
        seriesLayoutBy: seriesLayoutBy,
        dimensionsDefine: determined.dimensionsDefine,
        startIndex: determined.startIndex,
        dimensionsDetectedCount: determined.dimensionsDetectedCount,
        metaRawOption: clone(thisMetaRawOption)
      });
      return source;
    }
    /**
     * Wrap original series data for some compatibility cases.
     */

    function createSourceFromSeriesDataOption(data) {
      return new SourceImpl({
        data: data,
        sourceFormat: isTypedArray(data) ? SOURCE_FORMAT_TYPED_ARRAY : SOURCE_FORMAT_ORIGINAL
      });
    }
    /**
     * Clone source but excludes source data.
     */

    function cloneSourceShallow(source) {
      return new SourceImpl({
        data: source.data,
        sourceFormat: source.sourceFormat,
        seriesLayoutBy: source.seriesLayoutBy,
        dimensionsDefine: clone(source.dimensionsDefine),
        startIndex: source.startIndex,
        dimensionsDetectedCount: source.dimensionsDetectedCount
      });
    }
    /**
     * Note: An empty array will be detected as `SOURCE_FORMAT_ARRAY_ROWS`.
     */

    function detectSourceFormat(data) {
      var sourceFormat = SOURCE_FORMAT_UNKNOWN;

      if (isTypedArray(data)) {
        sourceFormat = SOURCE_FORMAT_TYPED_ARRAY;
      } else if (isArray(data)) {
        // FIXME Whether tolerate null in top level array?
        if (data.length === 0) {
          sourceFormat = SOURCE_FORMAT_ARRAY_ROWS;
        }

        for (var i = 0, len = data.length; i < len; i++) {
          var item = data[i];

          if (item == null) {
            continue;
          } else if (isArray(item)) {
            sourceFormat = SOURCE_FORMAT_ARRAY_ROWS;
            break;
          } else if (isObject(item)) {
            sourceFormat = SOURCE_FORMAT_OBJECT_ROWS;
            break;
          }
        }
      } else if (isObject(data)) {
        for (var key in data) {
          if (hasOwn(data, key) && isArrayLike(data[key])) {
            sourceFormat = SOURCE_FORMAT_KEYED_COLUMNS;
            break;
          }
        }
      }

      return sourceFormat;
    }
    /**
     * Determine the source definitions from data standalone dimensions definitions
     * are not specified.
     */

    function determineSourceDimensions(data, sourceFormat, seriesLayoutBy, sourceHeader, // standalone raw dimensions definition, like:
    // {
    //     dimensions: ['aa', 'bb', { name: 'cc', type: 'time' }]
    // }
    // in `dataset` or `series`
    dimensionsDefine) {
      var dimensionsDetectedCount;
      var startIndex; // PENDING: Could data be null/undefined here?
      // currently, if `dataset.source` not specified, error thrown.
      // if `series.data` not specified, nothing rendered without error thrown.
      // Should test these cases.

      if (!data) {
        return {
          dimensionsDefine: normalizeDimensionsOption(dimensionsDefine),
          startIndex: startIndex,
          dimensionsDetectedCount: dimensionsDetectedCount
        };
      }

      if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) {
        var dataArrayRows = data; // Rule: Most of the first line are string: it is header.
        // Caution: consider a line with 5 string and 1 number,
        // it still can not be sure it is a head, because the
        // 5 string may be 5 values of category columns.

        if (sourceHeader === 'auto' || sourceHeader == null) {
          arrayRowsTravelFirst(function (val) {
            // '-' is regarded as null/undefined.
            if (val != null && val !== '-') {
              if (isString(val)) {
                startIndex == null && (startIndex = 1);
              } else {
                startIndex = 0;
              }
            } // 10 is an experience number, avoid long loop.

          }, seriesLayoutBy, dataArrayRows, 10);
        } else {
          startIndex = isNumber(sourceHeader) ? sourceHeader : sourceHeader ? 1 : 0;
        }

        if (!dimensionsDefine && startIndex === 1) {
          dimensionsDefine = [];
          arrayRowsTravelFirst(function (val, index) {
            dimensionsDefine[index] = val != null ? val + '' : '';
          }, seriesLayoutBy, dataArrayRows, Infinity);
        }

        dimensionsDetectedCount = dimensionsDefine ? dimensionsDefine.length : seriesLayoutBy === SERIES_LAYOUT_BY_ROW ? dataArrayRows.length : dataArrayRows[0] ? dataArrayRows[0].length : null;
      } else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) {
        if (!dimensionsDefine) {
          dimensionsDefine = objectRowsCollectDimensions(data);
        }
      } else if (sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS) {
        if (!dimensionsDefine) {
          dimensionsDefine = [];
          each(data, function (colArr, key) {
            dimensionsDefine.push(key);
          });
        }
      } else if (sourceFormat === SOURCE_FORMAT_ORIGINAL) {
        var value0 = getDataItemValue(data[0]);
        dimensionsDetectedCount = isArray(value0) && value0.length || 1;
      } else if (sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) {
        if ("development" !== 'production') {
          assert(!!dimensionsDefine, 'dimensions must be given if data is TypedArray.');
        }
      }

      return {
        startIndex: startIndex,
        dimensionsDefine: normalizeDimensionsOption(dimensionsDefine),
        dimensionsDetectedCount: dimensionsDetectedCount
      };
    }

    function objectRowsCollectDimensions(data) {
      var firstIndex = 0;
      var obj;

      while (firstIndex < data.length && !(obj = data[firstIndex++])) {} // jshint ignore: line


      if (obj) {
        var dimensions_1 = [];
        each(obj, function (value, key) {
          dimensions_1.push(key);
        });
        return dimensions_1;
      }
    } // Consider dimensions defined like ['A', 'price', 'B', 'price', 'C', 'price'],
    // which is reasonable. But dimension name is duplicated.
    // Returns undefined or an array contains only object without null/undefined or string.


    function normalizeDimensionsOption(dimensionsDefine) {
      if (!dimensionsDefine) {
        // The meaning of null/undefined is different from empty array.
        return;
      }

      var nameMap = createHashMap();
      return map(dimensionsDefine, function (rawItem, index) {
        rawItem = isObject(rawItem) ? rawItem : {
          name: rawItem
        }; // Other fields will be discarded.

        var item = {
          name: rawItem.name,
          displayName: rawItem.displayName,
          type: rawItem.type
        }; // User can set null in dimensions.
        // We don't auto specify name, otherwise a given name may
        // cause it to be referred unexpectedly.

        if (item.name == null) {
          return item;
        } // Also consider number form like 2012.


        item.name += ''; // User may also specify displayName.
        // displayName will always exists except user not
        // specified or dim name is not specified or detected.
        // (A auto generated dim name will not be used as
        // displayName).

        if (item.displayName == null) {
          item.displayName = item.name;
        }

        var exist = nameMap.get(item.name);

        if (!exist) {
          nameMap.set(item.name, {
            count: 1
          });
        } else {
          item.name += '-' + exist.count++;
        }

        return item;
      });
    }

    function arrayRowsTravelFirst(cb, seriesLayoutBy, data, maxLoop) {
      if (seriesLayoutBy === SERIES_LAYOUT_BY_ROW) {
        for (var i = 0; i < data.length && i < maxLoop; i++) {
          cb(data[i] ? data[i][0] : null, i);
        }
      } else {
        var value0 = data[0] || [];

        for (var i = 0; i < value0.length && i < maxLoop; i++) {
          cb(value0[i], i);
        }
      }
    }

    function shouldRetrieveDataByName(source) {
      var sourceFormat = source.sourceFormat;
      return sourceFormat === SOURCE_FORMAT_OBJECT_ROWS || sourceFormat === SOURCE_FORMAT_KEYED_COLUMNS;
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    var _a, _b, _c; // TODO
    var providerMethods;
    var mountMethods;
    /**
     * If normal array used, mutable chunk size is supported.
     * If typed array used, chunk size must be fixed.
     */

    var DefaultDataProvider =
    /** @class */
    function () {
      function DefaultDataProvider(sourceParam, dimSize) {
        // let source: Source;
        var source = !isSourceInstance(sourceParam) ? createSourceFromSeriesDataOption(sourceParam) : sourceParam; // declare source is Source;

        this._source = source;
        var data = this._data = source.data; // Typed array. TODO IE10+?

        if (source.sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) {
          if ("development" !== 'production') {
            if (dimSize == null) {
              throw new Error('Typed array data must specify dimension size');
            }
          }

          this._offset = 0;
          this._dimSize = dimSize;
          this._data = data;
        }

        mountMethods(this, data, source);
      }

      DefaultDataProvider.prototype.getSource = function () {
        return this._source;
      };

      DefaultDataProvider.prototype.count = function () {
        return 0;
      };

      DefaultDataProvider.prototype.getItem = function (idx, out) {
        return;
      };

      DefaultDataProvider.prototype.appendData = function (newData) {};

      DefaultDataProvider.prototype.clean = function () {};

      DefaultDataProvider.protoInitialize = function () {
        // PENDING: To avoid potential incompat (e.g., prototype
        // is visited somewhere), still init them on prototype.
        var proto = DefaultDataProvider.prototype;
        proto.pure = false;
        proto.persistent = true;
      }();

      DefaultDataProvider.internalField = function () {
        var _a;

        mountMethods = function (provider, data, source) {
          var sourceFormat = source.sourceFormat;
          var seriesLayoutBy = source.seriesLayoutBy;
          var startIndex = source.startIndex;
          var dimsDef = source.dimensionsDefine;
          var methods = providerMethods[getMethodMapKey(sourceFormat, seriesLayoutBy)];

          if ("development" !== 'production') {
            assert(methods, 'Invalide sourceFormat: ' + sourceFormat);
          }

          extend(provider, methods);

          if (sourceFormat === SOURCE_FORMAT_TYPED_ARRAY) {
            provider.getItem = getItemForTypedArray;
            provider.count = countForTypedArray;
            provider.fillStorage = fillStorageForTypedArray;
          } else {
            var rawItemGetter = getRawSourceItemGetter(sourceFormat, seriesLayoutBy);
            provider.getItem = bind(rawItemGetter, null, data, startIndex, dimsDef);
            var rawCounter = getRawSourceDataCounter(sourceFormat, seriesLayoutBy);
            provider.count = bind(rawCounter, null, data, startIndex, dimsDef);
          }
        };

        var getItemForTypedArray = function (idx, out) {
          idx = idx - this._offset;
          out = out || [];
          var data = this._data;
          var dimSize = this._dimSize;
          var offset = dimSize * idx;

          for (var i = 0; i < dimSize; i++) {
            out[i] = data[offset + i];
          }

          return out;
        };

        var fillStorageForTypedArray = function (start, end, storage, extent) {
          var data = this._data;
          var dimSize = this._dimSize;

          for (var dim = 0; dim < dimSize; dim++) {
            var dimExtent = extent[dim];
            var min = dimExtent[0] == null ? Infinity : dimExtent[0];
            var max = dimExtent[1] == null ? -Infinity : dimExtent[1];
            var count = end - start;
            var arr = storage[dim];

            for (var i = 0; i < count; i++) {
              // appendData with TypedArray will always do replace in provider.
              var val = data[i * dimSize + dim];
              arr[start + i] = val;
              val < min && (min = val);
              val > max && (max = val);
            }

            dimExtent[0] = min;
            dimExtent[1] = max;
          }
        };

        var countForTypedArray = function () {
          return this._data ? this._data.length / this._dimSize : 0;
        };

        providerMethods = (_a = {}, _a[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_COLUMN] = {
          pure: true,
          appendData: appendDataSimply
        }, _a[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_ROW] = {
          pure: true,
          appendData: function () {
            throw new Error('Do not support appendData when set seriesLayoutBy: "row".');
          }
        }, _a[SOURCE_FORMAT_OBJECT_ROWS] = {
          pure: true,
          appendData: appendDataSimply
        }, _a[SOURCE_FORMAT_KEYED_COLUMNS] = {
          pure: true,
          appendData: function (newData) {
            var data = this._data;
            each(newData, function (newCol, key) {
              var oldCol = data[key] || (data[key] = []);

              for (var i = 0; i < (newCol || []).length; i++) {
                oldCol.push(newCol[i]);
              }
            });
          }
        }, _a[SOURCE_FORMAT_ORIGINAL] = {
          appendData: appendDataSimply
        }, _a[SOURCE_FORMAT_TYPED_ARRAY] = {
          persistent: false,
          pure: true,
          appendData: function (newData) {
            if ("development" !== 'production') {
              assert(isTypedArray(newData), 'Added data must be TypedArray if data in initialization is TypedArray');
            }

            this._data = newData;
          },
          // Clean self if data is already used.
          clean: function () {
            // PENDING
            this._offset += this.count();
            this._data = null;
          }
        }, _a);

        function appendDataSimply(newData) {
          for (var i = 0; i < newData.length; i++) {
            this._data.push(newData[i]);
          }
        }
      }();

      return DefaultDataProvider;
    }();

    var getItemSimply = function (rawData, startIndex, dimsDef, idx) {
      return rawData[idx];
    };

    var rawSourceItemGetterMap = (_a = {}, _a[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_COLUMN] = function (rawData, startIndex, dimsDef, idx) {
      return rawData[idx + startIndex];
    }, _a[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_ROW] = function (rawData, startIndex, dimsDef, idx, out) {
      idx += startIndex;
      var item = out || [];
      var data = rawData;

      for (var i = 0; i < data.length; i++) {
        var row = data[i];
        item[i] = row ? row[idx] : null;
      }

      return item;
    }, _a[SOURCE_FORMAT_OBJECT_ROWS] = getItemSimply, _a[SOURCE_FORMAT_KEYED_COLUMNS] = function (rawData, startIndex, dimsDef, idx, out) {
      var item = out || [];

      for (var i = 0; i < dimsDef.length; i++) {
        var dimName = dimsDef[i].name;

        if ("development" !== 'production') {
          if (dimName == null) {
            throw new Error();
          }
        }

        var col = rawData[dimName];
        item[i] = col ? col[idx] : null;
      }

      return item;
    }, _a[SOURCE_FORMAT_ORIGINAL] = getItemSimply, _a);
    function getRawSourceItemGetter(sourceFormat, seriesLayoutBy) {
      var method = rawSourceItemGetterMap[getMethodMapKey(sourceFormat, seriesLayoutBy)];

      if ("development" !== 'production') {
        assert(method, 'Do not support get item on "' + sourceFormat + '", "' + seriesLayoutBy + '".');
      }

      return method;
    }

    var countSimply = function (rawData, startIndex, dimsDef) {
      return rawData.length;
    };

    var rawSourceDataCounterMap = (_b = {}, _b[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_COLUMN] = function (rawData, startIndex, dimsDef) {
      return Math.max(0, rawData.length - startIndex);
    }, _b[SOURCE_FORMAT_ARRAY_ROWS + '_' + SERIES_LAYOUT_BY_ROW] = function (rawData, startIndex, dimsDef) {
      var row = rawData[0];
      return row ? Math.max(0, row.length - startIndex) : 0;
    }, _b[SOURCE_FORMAT_OBJECT_ROWS] = countSimply, _b[SOURCE_FORMAT_KEYED_COLUMNS] = function (rawData, startIndex, dimsDef) {
      var dimName = dimsDef[0].name;

      if ("development" !== 'production') {
        if (dimName == null) {
          throw new Error();
        }
      }

      var col = rawData[dimName];
      return col ? col.length : 0;
    }, _b[SOURCE_FORMAT_ORIGINAL] = countSimply, _b);
    function getRawSourceDataCounter(sourceFormat, seriesLayoutBy) {
      var method = rawSourceDataCounterMap[getMethodMapKey(sourceFormat, seriesLayoutBy)];

      if ("development" !== 'production') {
        assert(method, 'Do not support count on "' + sourceFormat + '", "' + seriesLayoutBy + '".');
      }

      return method;
    }

    var getRawValueSimply = function (dataItem, dimIndex, property) {
      return dataItem[dimIndex];
    };

    var rawSourceValueGetterMap = (_c = {}, _c[SOURCE_FORMAT_ARRAY_ROWS] = getRawValueSimply, _c[SOURCE_FORMAT_OBJECT_ROWS] = function (dataItem, dimIndex, property) {
      return dataItem[property];
    }, _c[SOURCE_FORMAT_KEYED_COLUMNS] = getRawValueSimply, _c[SOURCE_FORMAT_ORIGINAL] = function (dataItem, dimIndex, property) {
      // FIXME: In some case (markpoint in geo (geo-map.html)),
      // dataItem is {coord: [...]}
      var value = getDataItemValue(dataItem);
      return !(value instanceof Array) ? value : value[dimIndex];
    }, _c[SOURCE_FORMAT_TYPED_ARRAY] = getRawValueSimply, _c);
    function getRawSourceValueGetter(sourceFormat) {
      var method = rawSourceValueGetterMap[sourceFormat];

      if ("development" !== 'production') {
        assert(method, 'Do not support get value on "' + sourceFormat + '".');
      }

      return method;
    }

    function getMethodMapKey(sourceFormat, seriesLayoutBy) {
      return sourceFormat === SOURCE_FORMAT_ARRAY_ROWS ? sourceFormat + '_' + seriesLayoutBy : sourceFormat;
    } // ??? FIXME can these logic be more neat: getRawValue, getRawDataItem,
    // Consider persistent.
    // Caution: why use raw value to display on label or tooltip?
    // A reason is to avoid format. For example time value we do not know
    // how to format is expected. More over, if stack is used, calculated
    // value may be 0.91000000001, which have brings trouble to display.
    // TODO: consider how to treat null/undefined/NaN when display?


    function retrieveRawValue(data, dataIndex, // If dimIndex is null/undefined, return OptionDataItem.
    // Otherwise, return OptionDataValue.
    dim) {
      if (!data) {
        return;
      } // Consider data may be not persistent.


      var dataItem = data.getRawDataItem(dataIndex);

      if (dataItem == null) {
        return;
      }

      var store = data.getStore();
      var sourceFormat = store.getSource().sourceFormat;

      if (dim != null) {
        var dimIndex = data.getDimensionIndex(dim);
        var property = store.getDimensionProperty(dimIndex);
        return getRawSourceValueGetter(sourceFormat)(dataItem, dimIndex, property);
      } else {
        var result = dataItem;

        if (sourceFormat === SOURCE_FORMAT_ORIGINAL) {
          result = getDataItemValue(dataItem);
        }

        return result;
      }
    }

    var DIMENSION_LABEL_REG = /\{@(.+?)\}/g;

    var DataFormatMixin =
    /** @class */
    function () {
      function DataFormatMixin() {}
      /**
       * Get params for formatter
       */


      DataFormatMixin.prototype.getDataParams = function (dataIndex, dataType) {
        var data = this.getData(dataType);
        var rawValue = this.getRawValue(dataIndex, dataType);
        var rawDataIndex = data.getRawIndex(dataIndex);
        var name = data.getName(dataIndex);
        var itemOpt = data.getRawDataItem(dataIndex);
        var style = data.getItemVisual(dataIndex, 'style');
        var color = style && style[data.getItemVisual(dataIndex, 'drawType') || 'fill'];
        var borderColor = style && style.stroke;
        var mainType = this.mainType;
        var isSeries = mainType === 'series';
        var userOutput = data.userOutput && data.userOutput.get();
        return {
          componentType: mainType,
          componentSubType: this.subType,
          componentIndex: this.componentIndex,
          seriesType: isSeries ? this.subType : null,
          seriesIndex: this.seriesIndex,
          seriesId: isSeries ? this.id : null,
          seriesName: isSeries ? this.name : null,
          name: name,
          dataIndex: rawDataIndex,
          data: itemOpt,
          dataType: dataType,
          value: rawValue,
          color: color,
          borderColor: borderColor,
          dimensionNames: userOutput ? userOutput.fullDimensions : null,
          encode: userOutput ? userOutput.encode : null,
          // Param name list for mapping `a`, `b`, `c`, `d`, `e`
          $vars: ['seriesName', 'name', 'value']
        };
      };
      /**
       * Format label
       * @param dataIndex
       * @param status 'normal' by default
       * @param dataType
       * @param labelDimIndex Only used in some chart that
       *        use formatter in different dimensions, like radar.
       * @param formatter Formatter given outside.
       * @return return null/undefined if no formatter
       */


      DataFormatMixin.prototype.getFormattedLabel = function (dataIndex, status, dataType, labelDimIndex, formatter, extendParams) {
        status = status || 'normal';
        var data = this.getData(dataType);
        var params = this.getDataParams(dataIndex, dataType);

        if (extendParams) {
          params.value = extendParams.interpolatedValue;
        }

        if (labelDimIndex != null && isArray(params.value)) {
          params.value = params.value[labelDimIndex];
        }

        if (!formatter) {
          var itemModel = data.getItemModel(dataIndex); // @ts-ignore

          formatter = itemModel.get(status === 'normal' ? ['label', 'formatter'] : [status, 'label', 'formatter']);
        }

        if (isFunction(formatter)) {
          params.status = status;
          params.dimensionIndex = labelDimIndex;
          return formatter(params);
        } else if (isString(formatter)) {
          var str = formatTpl(formatter, params); // Support 'aaa{@[3]}bbb{@product}ccc'.
          // Do not support '}' in dim name util have to.

          return str.replace(DIMENSION_LABEL_REG, function (origin, dimStr) {
            var len = dimStr.length;
            var dimLoose = dimStr;

            if (dimLoose.charAt(0) === '[' && dimLoose.charAt(len - 1) === ']') {
              dimLoose = +dimLoose.slice(1, len - 1); // Also support: '[]' => 0

              if ("development" !== 'production') {
                if (isNaN(dimLoose)) {
                  error("Invalide label formatter: @" + dimStr + ", only support @[0], @[1], @[2], ...");
                }
              }
            }

            var val = retrieveRawValue(data, dataIndex, dimLoose);

            if (extendParams && isArray(extendParams.interpolatedValue)) {
              var dimIndex = data.getDimensionIndex(dimLoose);

              if (dimIndex >= 0) {
                val = extendParams.interpolatedValue[dimIndex];
              }
            }

            return val != null ? val + '' : '';
          });
        }
      };
      /**
       * Get raw value in option
       */


      DataFormatMixin.prototype.getRawValue = function (idx, dataType) {
        return retrieveRawValue(this.getData(dataType), idx);
      };
      /**
       * Should be implemented.
       * @param {number} dataIndex
       * @param {boolean} [multipleSeries=false]
       * @param {string} [dataType]
       */


      DataFormatMixin.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) {
        // Empty function
        return;
      };

      return DataFormatMixin;
    }();

    /**
     * @param {Object} define
     * @return See the return of `createTask`.
     */

    function createTask(define) {
      return new Task(define);
    }

    var Task =
    /** @class */
    function () {
      function Task(define) {
        define = define || {};
        this._reset = define.reset;
        this._plan = define.plan;
        this._count = define.count;
        this._onDirty = define.onDirty;
        this._dirty = true;
      }
      /**
       * @param step Specified step.
       * @param skip Skip customer perform call.
       * @param modBy Sampling window size.
       * @param modDataCount Sampling count.
       * @return whether unfinished.
       */


      Task.prototype.perform = function (performArgs) {
        var upTask = this._upstream;
        var skip = performArgs && performArgs.skip; // TODO some refactor.
        // Pull data. Must pull data each time, because context.data
        // may be updated by Series.setData.

        if (this._dirty && upTask) {
          var context = this.context;
          context.data = context.outputData = upTask.context.outputData;
        }

        if (this.__pipeline) {
          this.__pipeline.currentTask = this;
        }

        var planResult;

        if (this._plan && !skip) {
          planResult = this._plan(this.context);
        } // Support sharding by mod, which changes the render sequence and makes the rendered graphic
        // elements uniformed distributed when progress, especially when moving or zooming.


        var lastModBy = normalizeModBy(this._modBy);
        var lastModDataCount = this._modDataCount || 0;
        var modBy = normalizeModBy(performArgs && performArgs.modBy);
        var modDataCount = performArgs && performArgs.modDataCount || 0;

        if (lastModBy !== modBy || lastModDataCount !== modDataCount) {
          planResult = 'reset';
        }

        function normalizeModBy(val) {
          !(val >= 1) && (val = 1); // jshint ignore:line

          return val;
        }

        var forceFirstProgress;

        if (this._dirty || planResult === 'reset') {
          this._dirty = false;
          forceFirstProgress = this._doReset(skip);
        }

        this._modBy = modBy;
        this._modDataCount = modDataCount;
        var step = performArgs && performArgs.step;

        if (upTask) {
          if ("development" !== 'production') {
            assert(upTask._outputDueEnd != null);
          }

          this._dueEnd = upTask._outputDueEnd;
        } // DataTask or overallTask
        else {
            if ("development" !== 'production') {
              assert(!this._progress || this._count);
            }

            this._dueEnd = this._count ? this._count(this.context) : Infinity;
          } // Note: Stubs, that its host overall task let it has progress, has progress.
        // If no progress, pass index from upstream to downstream each time plan called.


        if (this._progress) {
          var start = this._dueIndex;
          var end = Math.min(step != null ? this._dueIndex + step : Infinity, this._dueEnd);

          if (!skip && (forceFirstProgress || start < end)) {
            var progress = this._progress;

            if (isArray(progress)) {
              for (var i = 0; i < progress.length; i++) {
                this._doProgress(progress[i], start, end, modBy, modDataCount);
              }
            } else {
              this._doProgress(progress, start, end, modBy, modDataCount);
            }
          }

          this._dueIndex = end; // If no `outputDueEnd`, assume that output data and
          // input data is the same, so use `dueIndex` as `outputDueEnd`.

          var outputDueEnd = this._settedOutputEnd != null ? this._settedOutputEnd : end;

          if ("development" !== 'production') {
            // ??? Can not rollback.
            assert(outputDueEnd >= this._outputDueEnd);
          }

          this._outputDueEnd = outputDueEnd;
        } else {
          // (1) Some overall task has no progress.
          // (2) Stubs, that its host overall task do not let it has progress, has no progress.
          // This should always be performed so it can be passed to downstream.
          this._dueIndex = this._outputDueEnd = this._settedOutputEnd != null ? this._settedOutputEnd : this._dueEnd;
        }

        return this.unfinished();
      };

      Task.prototype.dirty = function () {
        this._dirty = true;
        this._onDirty && this._onDirty(this.context);
      };

      Task.prototype._doProgress = function (progress, start, end, modBy, modDataCount) {
        iterator.reset(start, end, modBy, modDataCount);
        this._callingProgress = progress;

        this._callingProgress({
          start: start,
          end: end,
          count: end - start,
          next: iterator.next
        }, this.context);
      };

      Task.prototype._doReset = function (skip) {
        this._dueIndex = this._outputDueEnd = this._dueEnd = 0;
        this._settedOutputEnd = null;
        var progress;
        var forceFirstProgress;

        if (!skip && this._reset) {
          progress = this._reset(this.context);

          if (progress && progress.progress) {
            forceFirstProgress = progress.forceFirstProgress;
            progress = progress.progress;
          } // To simplify no progress checking, array must has item.


          if (isArray(progress) && !progress.length) {
            progress = null;
          }
        }

        this._progress = progress;
        this._modBy = this._modDataCount = null;
        var downstream = this._downstream;
        downstream && downstream.dirty();
        return forceFirstProgress;
      };

      Task.prototype.unfinished = function () {
        return this._progress && this._dueIndex < this._dueEnd;
      };
      /**
       * @param downTask The downstream task.
       * @return The downstream task.
       */


      Task.prototype.pipe = function (downTask) {
        if ("development" !== 'production') {
          assert(downTask && !downTask._disposed && downTask !== this);
        } // If already downstream, do not dirty downTask.


        if (this._downstream !== downTask || this._dirty) {
          this._downstream = downTask;
          downTask._upstream = this;
          downTask.dirty();
        }
      };

      Task.prototype.dispose = function () {
        if (this._disposed) {
          return;
        }

        this._upstream && (this._upstream._downstream = null);
        this._downstream && (this._downstream._upstream = null);
        this._dirty = false;
        this._disposed = true;
      };

      Task.prototype.getUpstream = function () {
        return this._upstream;
      };

      Task.prototype.getDownstream = function () {
        return this._downstream;
      };

      Task.prototype.setOutputEnd = function (end) {
        // This only happens in dataTask, dataZoom, map, currently.
        // where dataZoom do not set end each time, but only set
        // when reset. So we should record the set end, in case
        // that the stub of dataZoom perform again and earse the
        // set end by upstream.
        this._outputDueEnd = this._settedOutputEnd = end;
      };

      return Task;
    }();

    var iterator = function () {
      var end;
      var current;
      var modBy;
      var modDataCount;
      var winCount;
      var it = {
        reset: function (s, e, sStep, sCount) {
          current = s;
          end = e;
          modBy = sStep;
          modDataCount = sCount;
          winCount = Math.ceil(modDataCount / modBy);
          it.next = modBy > 1 && modDataCount > 0 ? modNext : sequentialNext;
        }
      };
      return it;

      function sequentialNext() {
        return current < end ? current++ : null;
      }

      function modNext() {
        var dataIndex = current % winCount * modBy + Math.ceil(current / winCount);
        var result = current >= end ? null : dataIndex < modDataCount ? dataIndex // If modDataCount is smaller than data.count() (consider `appendData` case),
        // Use normal linear rendering mode.
        : current;
        current++;
        return result;
      }
    }(); // -----------------------------------------------------------------------------
    // For stream debug (Should be commented out after used!)
    // @usage: printTask(this, 'begin');
    // @usage: printTask(this, null, {someExtraProp});
    // @usage: Use `__idxInPipeline` as conditional breakpiont.
    //
    // window.printTask = function (task: any, prefix: string, extra: { [key: string]: unknown }): void {
    //     window.ecTaskUID == null && (window.ecTaskUID = 0);
    //     task.uidDebug == null && (task.uidDebug = `task_${window.ecTaskUID++}`);
    //     task.agent && task.agent.uidDebug == null && (task.agent.uidDebug = `task_${window.ecTaskUID++}`);
    //     let props = [];
    //     if (task.__pipeline) {
    //         let val = `${task.__idxInPipeline}/${task.__pipeline.tail.__idxInPipeline} ${task.agent ? '(stub)' : ''}`;
    //         props.push({text: '__idxInPipeline/total', value: val});
    //     } else {
    //         let stubCount = 0;
    //         task.agentStubMap.each(() => stubCount++);
    //         props.push({text: 'idx', value: `overall (stubs: ${stubCount})`});
    //     }
    //     props.push({text: 'uid', value: task.uidDebug});
    //     if (task.__pipeline) {
    //         props.push({text: 'pipelineId', value: task.__pipeline.id});
    //         task.agent && props.push(
    //             {text: 'stubFor', value: task.agent.uidDebug}
    //         );
    //     }
    //     props.push(
    //         {text: 'dirty', value: task._dirty},
    //         {text: 'dueIndex', value: task._dueIndex},
    //         {text: 'dueEnd', value: task._dueEnd},
    //         {text: 'outputDueEnd', value: task._outputDueEnd}
    //     );
    //     if (extra) {
    //         Object.keys(extra).forEach(key => {
    //             props.push({text: key, value: extra[key]});
    //         });
    //     }
    //     let args = ['color: blue'];
    //     let msg = `%c[${prefix || 'T'}] %c` + props.map(item => (
    //         args.push('color: green', 'color: red'),
    //         `${item.text}: %c${item.value}`
    //     )).join('%c, ');
    //     console.log.apply(console, [msg].concat(args));
    //     // console.log(this);
    // };
    // window.printPipeline = function (task: any, prefix: string) {
    //     const pipeline = task.__pipeline;
    //     let currTask = pipeline.head;
    //     while (currTask) {
    //         window.printTask(currTask, prefix);
    //         currTask = currTask._downstream;
    //     }
    // };
    // window.showChain = function (chainHeadTask) {
    //     var chain = [];
    //     var task = chainHeadTask;
    //     while (task) {
    //         chain.push({
    //             task: task,
    //             up: task._upstream,
    //             down: task._downstream,
    //             idxInPipeline: task.__idxInPipeline
    //         });
    //         task = task._downstream;
    //     }
    //     return chain;
    // };
    // window.findTaskInChain = function (task, chainHeadTask) {
    //     let chain = window.showChain(chainHeadTask);
    //     let result = [];
    //     for (let i = 0; i < chain.length; i++) {
    //         let chainItem = chain[i];
    //         if (chainItem.task === task) {
    //             result.push(i);
    //         }
    //     }
    //     return result;
    // };
    // window.printChainAEachInChainB = function (chainHeadTaskA, chainHeadTaskB) {
    //     let chainA = window.showChain(chainHeadTaskA);
    //     for (let i = 0; i < chainA.length; i++) {
    //         console.log('chainAIdx:', i, 'inChainB:', window.findTaskInChain(chainA[i].task, chainHeadTaskB));
    //     }
    // };

    /**
     * Convert raw the value in to inner value in List.
     *
     * [Performance sensitive]
     *
     * [Caution]: this is the key logic of user value parser.
     * For backward compatibility, do not modify it until you have to!
     */

    function parseDataValue(value, // For high performance, do not omit the second param.
    opt) {
      // Performance sensitive.
      var dimType = opt && opt.type;

      if (dimType === 'ordinal') {
        // If given value is a category string
        return value;
      }

      if (dimType === 'time' // spead up when using timestamp
      && !isNumber(value) && value != null && value !== '-') {
        value = +parseDate(value);
      } // dimType defaults 'number'.
      // If dimType is not ordinal and value is null or undefined or NaN or '-',
      // parse to NaN.
      // number-like string (like ' 123 ') can be converted to a number.
      // where null/undefined or other string will be converted to NaN.


      return value == null || value === '' ? NaN // If string (like '-'), using '+' parse to NaN
      // If object, also parse to NaN
      : +value;
    }
    var valueParserMap = createHashMap({
      'number': function (val) {
        // Do not use `numericToNumber` here. We have `numericToNumber` by default.
        // Here the number parser can have loose rule:
        // enable to cut suffix: "120px" => 120, "14%" => 14.
        return parseFloat(val);
      },
      'time': function (val) {
        // return timestamp.
        return +parseDate(val);
      },
      'trim': function (val) {
        return isString(val) ? trim(val) : val;
      }
    });

    /**
     * TODO: disable writable.
     * This structure will be exposed to users.
     */

    var ExternalSource =
    /** @class */
    function () {
      function ExternalSource() {}

      ExternalSource.prototype.getRawData = function () {
        // Only built-in transform available.
        throw new Error('not supported');
      };

      ExternalSource.prototype.getRawDataItem = function (dataIndex) {
        // Only built-in transform available.
        throw new Error('not supported');
      };

      ExternalSource.prototype.cloneRawData = function () {
        return;
      };
      /**
       * @return If dimension not found, return null/undefined.
       */


      ExternalSource.prototype.getDimensionInfo = function (dim) {
        return;
      };
      /**
       * dimensions defined if and only if either:
       * (a) dataset.dimensions are declared.
       * (b) dataset data include dimensions definitions in data (detected or via specified `sourceHeader`).
       * If dimensions are defined, `dimensionInfoAll` is corresponding to
       * the defined dimensions.
       * Otherwise, `dimensionInfoAll` is determined by data columns.
       * @return Always return an array (even empty array).
       */


      ExternalSource.prototype.cloneAllDimensionInfo = function () {
        return;
      };

      ExternalSource.prototype.count = function () {
        return;
      };
      /**
       * Only support by dimension index.
       * No need to support by dimension name in transform function,
       * because transform function is not case-specific, no need to use name literally.
       */


      ExternalSource.prototype.retrieveValue = function (dataIndex, dimIndex) {
        return;
      };

      ExternalSource.prototype.retrieveValueFromItem = function (dataItem, dimIndex) {
        return;
      };

      ExternalSource.prototype.convertValue = function (rawVal, dimInfo) {
        return parseDataValue(rawVal, dimInfo);
      };

      return ExternalSource;
    }();

    function createExternalSource(internalSource, externalTransform) {
      var extSource = new ExternalSource();
      var data = internalSource.data;
      var sourceFormat = extSource.sourceFormat = internalSource.sourceFormat;
      var sourceHeaderCount = internalSource.startIndex;
      var errMsg = '';

      if (internalSource.seriesLayoutBy !== SERIES_LAYOUT_BY_COLUMN) {
        // For the logic simplicity in transformer, only 'culumn' is
        // supported in data transform. Otherwise, the `dimensionsDefine`
        // might be detected by 'row', which probably confuses users.
        if ("development" !== 'production') {
          errMsg = '`seriesLayoutBy` of upstream dataset can only be "column" in data transform.';
        }

        throwError(errMsg);
      } // [MEMO]
      // Create a new dimensions structure for exposing.
      // Do not expose all dimension info to users directly.
      // Because the dimension is probably auto detected from data and not might reliable.
      // Should not lead the transformers to think that is reliable and return it.
      // See [DIMENSION_INHERIT_RULE] in `sourceManager.ts`.


      var dimensions = [];
      var dimsByName = {};
      var dimsDef = internalSource.dimensionsDefine;

      if (dimsDef) {
        each(dimsDef, function (dimDef, idx) {
          var name = dimDef.name;
          var dimDefExt = {
            index: idx,
            name: name,
            displayName: dimDef.displayName
          };
          dimensions.push(dimDefExt); // Users probably do not specify dimension name. For simplicity, data transform
          // does not generate dimension name.

          if (name != null) {
            // Dimension name should not be duplicated.
            // For simplicity, data transform forbids name duplication, do not generate
            // new name like module `completeDimensions.ts` did, but just tell users.
            var errMsg_1 = '';

            if (hasOwn(dimsByName, name)) {
              if ("development" !== 'production') {
                errMsg_1 = 'dimension name "' + name + '" duplicated.';
              }

              throwError(errMsg_1);
            }

            dimsByName[name] = dimDefExt;
          }
        });
      } // If dimension definitions are not defined and can not be detected.
      // e.g., pure data `[[11, 22], ...]`.
      else {
          for (var i = 0; i < internalSource.dimensionsDetectedCount || 0; i++) {
            // Do not generete name or anything others. The consequence process in
            // `transform` or `series` probably have there own name generation strategry.
            dimensions.push({
              index: i
            });
          }
        } // Implement public methods:


      var rawItemGetter = getRawSourceItemGetter(sourceFormat, SERIES_LAYOUT_BY_COLUMN);

      if (externalTransform.__isBuiltIn) {
        extSource.getRawDataItem = function (dataIndex) {
          return rawItemGetter(data, sourceHeaderCount, dimensions, dataIndex);
        };

        extSource.getRawData = bind(getRawData, null, internalSource);
      }

      extSource.cloneRawData = bind(cloneRawData, null, internalSource);
      var rawCounter = getRawSourceDataCounter(sourceFormat, SERIES_LAYOUT_BY_COLUMN);
      extSource.count = bind(rawCounter, null, data, sourceHeaderCount, dimensions);
      var rawValueGetter = getRawSourceValueGetter(sourceFormat);

      extSource.retrieveValue = function (dataIndex, dimIndex) {
        var rawItem = rawItemGetter(data, sourceHeaderCount, dimensions, dataIndex);
        return retrieveValueFromItem(rawItem, dimIndex);
      };

      var retrieveValueFromItem = extSource.retrieveValueFromItem = function (dataItem, dimIndex) {
        if (dataItem == null) {
          return;
        }

        var dimDef = dimensions[dimIndex]; // When `dimIndex` is `null`, `rawValueGetter` return the whole item.

        if (dimDef) {
          return rawValueGetter(dataItem, dimIndex, dimDef.name);
        }
      };

      extSource.getDimensionInfo = bind(getDimensionInfo, null, dimensions, dimsByName);
      extSource.cloneAllDimensionInfo = bind(cloneAllDimensionInfo, null, dimensions);
      return extSource;
    }

    function getRawData(upstream) {
      var sourceFormat = upstream.sourceFormat;

      if (!isSupportedSourceFormat(sourceFormat)) {
        var errMsg = '';

        if ("development" !== 'production') {
          errMsg = '`getRawData` is not supported in source format ' + sourceFormat;
        }

        throwError(errMsg);
      }

      return upstream.data;
    }

    function cloneRawData(upstream) {
      var sourceFormat = upstream.sourceFormat;
      var data = upstream.data;

      if (!isSupportedSourceFormat(sourceFormat)) {
        var errMsg = '';

        if ("development" !== 'production') {
          errMsg = '`cloneRawData` is not supported in source format ' + sourceFormat;
        }

        throwError(errMsg);
      }

      if (sourceFormat === SOURCE_FORMAT_ARRAY_ROWS) {
        var result = [];

        for (var i = 0, len = data.length; i < len; i++) {
          // Not strictly clone for performance
          result.push(data[i].slice());
        }

        return result;
      } else if (sourceFormat === SOURCE_FORMAT_OBJECT_ROWS) {
        var result = [];

        for (var i = 0, len = data.length; i < len; i++) {
          // Not strictly clone for performance
          result.push(extend({}, data[i]));
        }

        return result;
      }
    }

    function getDimensionInfo(dimensions, dimsByName, dim) {
      if (dim == null) {
        return;
      } // Keep the same logic as `List::getDimension` did.


      if (isNumber(dim) // If being a number-like string but not being defined a dimension name.
      || !isNaN(dim) && !hasOwn(dimsByName, dim)) {
        return dimensions[dim];
      } else if (hasOwn(dimsByName, dim)) {
        return dimsByName[dim];
      }
    }

    function cloneAllDimensionInfo(dimensions) {
      return clone(dimensions);
    }

    var externalTransformMap = createHashMap();
    function registerExternalTransform(externalTransform) {
      externalTransform = clone(externalTransform);
      var type = externalTransform.type;
      var errMsg = '';

      if (!type) {
        if ("development" !== 'production') {
          errMsg = 'Must have a `type` when `registerTransform`.';
        }

        throwError(errMsg);
      }

      var typeParsed = type.split(':');

      if (typeParsed.length !== 2) {
        if ("development" !== 'production') {
          errMsg = 'Name must include namespace like "ns:regression".';
        }

        throwError(errMsg);
      } // Namespace 'echarts:xxx' is official namespace, where the transforms should
      // be called directly via 'xxx' rather than 'echarts:xxx'.


      var isBuiltIn = false;

      if (typeParsed[0] === 'echarts') {
        type = typeParsed[1];
        isBuiltIn = true;
      }

      externalTransform.__isBuiltIn = isBuiltIn;
      externalTransformMap.set(type, externalTransform);
    }
    function applyDataTransform(rawTransOption, sourceList, infoForPrint) {
      var pipedTransOption = normalizeToArray(rawTransOption);
      var pipeLen = pipedTransOption.length;
      var errMsg = '';

      if (!pipeLen) {
        if ("development" !== 'production') {
          errMsg = 'If `transform` declared, it should at least contain one transform.';
        }

        throwError(errMsg);
      }

      for (var i = 0, len = pipeLen; i < len; i++) {
        var transOption = pipedTransOption[i];
        sourceList = applySingleDataTransform(transOption, sourceList, infoForPrint, pipeLen === 1 ? null : i); // piped transform only support single input, except the fist one.
        // piped transform only support single output, except the last one.

        if (i !== len - 1) {
          sourceList.length = Math.max(sourceList.length, 1);
        }
      }

      return sourceList;
    }

    function applySingleDataTransform(transOption, upSourceList, infoForPrint, // If `pipeIndex` is null/undefined, no piped transform.
    pipeIndex) {
      var errMsg = '';

      if (!upSourceList.length) {
        if ("development" !== 'production') {
          errMsg = 'Must have at least one upstream dataset.';
        }

        throwError(errMsg);
      }

      if (!isObject(transOption)) {
        if ("development" !== 'production') {
          errMsg = 'transform declaration must be an object rather than ' + typeof transOption + '.';
        }

        throwError(errMsg);
      }

      var transType = transOption.type;
      var externalTransform = externalTransformMap.get(transType);

      if (!externalTransform) {
        if ("development" !== 'production') {
          errMsg = 'Can not find transform on type "' + transType + '".';
        }

        throwError(errMsg);
      } // Prepare source


      var extUpSourceList = map(upSourceList, function (upSource) {
        return createExternalSource(upSource, externalTransform);
      });
      var resultList = normalizeToArray(externalTransform.transform({
        upstream: extUpSourceList[0],
        upstreamList: extUpSourceList,
        config: clone(transOption.config)
      }));

      if ("development" !== 'production') {
        if (transOption.print) {
          var printStrArr = map(resultList, function (extSource) {
            var pipeIndexStr = pipeIndex != null ? ' === pipe index: ' + pipeIndex : '';
            return ['=== dataset index: ' + infoForPrint.datasetIndex + pipeIndexStr + ' ===', '- transform result data:', makePrintable(extSource.data), '- transform result dimensions:', makePrintable(extSource.dimensions)].join('\n');
          }).join('\n');
          log(printStrArr);
        }
      }

      return map(resultList, function (result, resultIndex) {
        var errMsg = '';

        if (!isObject(result)) {
          if ("development" !== 'production') {
            errMsg = 'A transform should not return some empty results.';
          }

          throwError(errMsg);
        }

        if (!result.data) {
          if ("development" !== 'production') {
            errMsg = 'Transform result data should be not be null or undefined';
          }

          throwError(errMsg);
        }

        var sourceFormat = detectSourceFormat(result.data);

        if (!isSupportedSourceFormat(sourceFormat)) {
          if ("development" !== 'production') {
            errMsg = 'Transform result data should be array rows or object rows.';
          }

          throwError(errMsg);
        }

        var resultMetaRawOption;
        var firstUpSource = upSourceList[0];
        /**
         * Intuitively, the end users known the content of the original `dataset.source`,
         * calucating the transform result in mind.
         * Suppose the original `dataset.source` is:
         * ```js
         * [
         *     ['product', '2012', '2013', '2014', '2015'],
         *     ['AAA', 41.1, 30.4, 65.1, 53.3],
         *     ['BBB', 86.5, 92.1, 85.7, 83.1],
         *     ['CCC', 24.1, 67.2, 79.5, 86.4]
         * ]
         * ```
         * The dimension info have to be detected from the source data.
         * Some of the transformers (like filter, sort) will follow the dimension info
         * of upstream, while others use new dimensions (like aggregate).
         * Transformer can output a field `dimensions` to define the its own output dimensions.
         * We also allow transformers to ignore the output `dimensions` field, and
         * inherit the upstream dimensions definition. It can reduce the burden of handling
         * dimensions in transformers.
         *
         * See also [DIMENSION_INHERIT_RULE] in `sourceManager.ts`.
         */

        if (firstUpSource && resultIndex === 0 // If transformer returns `dimensions`, it means that the transformer has different
        // dimensions definitions. We do not inherit anything from upstream.
        && !result.dimensions) {
          var startIndex = firstUpSource.startIndex; // We copy the header of upstream to the result, because:
          // (1) The returned data always does not contain header line and can not be used
          // as dimension-detection. In this case we can not use "detected dimensions" of
          // upstream directly, because it might be detected based on different `seriesLayoutBy`.
          // (2) We should support that the series read the upstream source in `seriesLayoutBy: 'row'`.
          // So the original detected header should be add to the result, otherwise they can not be read.

          if (startIndex) {
            result.data = firstUpSource.data.slice(0, startIndex).concat(result.data);
          }

          resultMetaRawOption = {
            seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN,
            sourceHeader: startIndex,
            dimensions: firstUpSource.metaRawOption.dimensions
          };
        } else {
          resultMetaRawOption = {
            seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN,
            sourceHeader: 0,
            dimensions: result.dimensions
          };
        }

        return createSource(result.data, resultMetaRawOption, null);
      });
    }

    function isSupportedSourceFormat(sourceFormat) {
      return sourceFormat === SOURCE_FORMAT_ARRAY_ROWS || sourceFormat === SOURCE_FORMAT_OBJECT_ROWS;
    }

    var UNDEFINED = 'undefined';
    /* global Float64Array, Int32Array, Uint32Array, Uint16Array */
    // Caution: MUST not use `new CtorUint32Array(arr, 0, len)`, because the Ctor of array is
    // different from the Ctor of typed array.

    var CtorUint32Array = typeof Uint32Array === UNDEFINED ? Array : Uint32Array;
    var CtorUint16Array = typeof Uint16Array === UNDEFINED ? Array : Uint16Array;
    var CtorInt32Array = typeof Int32Array === UNDEFINED ? Array : Int32Array;
    var CtorFloat64Array = typeof Float64Array === UNDEFINED ? Array : Float64Array;
    /**
     * Multi dimensional data store
     */

    var dataCtors = {
      'float': CtorFloat64Array,
      'int': CtorInt32Array,
      // Ordinal data type can be string or int
      'ordinal': Array,
      'number': Array,
      'time': CtorFloat64Array
    };
    var defaultDimValueGetters;

    function getIndicesCtor(rawCount) {
      // The possible max value in this._indicies is always this._rawCount despite of filtering.
      return rawCount > 65535 ? CtorUint32Array : CtorUint16Array;
    }

    function getInitialExtent() {
      return [Infinity, -Infinity];
    }

    function cloneChunk(originalChunk) {
      var Ctor = originalChunk.constructor; // Only shallow clone is enough when Array.

      return Ctor === Array ? originalChunk.slice() : new Ctor(originalChunk);
    }

    function prepareStore(store, dimIdx, dimType, end, append) {
      var DataCtor = dataCtors[dimType || 'float'];

      if (append) {
        var oldStore = store[dimIdx];
        var oldLen = oldStore && oldStore.length;

        if (!(oldLen === end)) {
          var newStore = new DataCtor(end); // The cost of the copy is probably inconsiderable
          // within the initial chunkSize.

          for (var j = 0; j < oldLen; j++) {
            newStore[j] = oldStore[j];
          }

          store[dimIdx] = newStore;
        }
      } else {
        store[dimIdx] = new DataCtor(end);
      }
    }
    /**
     * Basically, DataStore API keep immutable.
     */

    var DataStore =
    /** @class */
    function () {
      function DataStore() {
        this._chunks = []; // It will not be calculated util needed.

        this._rawExtent = [];
        this._extent = [];
        this._count = 0;
        this._rawCount = 0;
        this._calcDimNameToIdx = createHashMap();
      }
      /**
       * Initialize from data
       */


      DataStore.prototype.initData = function (provider, inputDimensions, dimValueGetter) {
        if ("development" !== 'production') {
          assert(isFunction(provider.getItem) && isFunction(provider.count), 'Invalid data provider.');
        }

        this._provider = provider; // Clear

        this._chunks = [];
        this._indices = null;
        this.getRawIndex = this._getRawIdxIdentity;
        var source = provider.getSource();
        var defaultGetter = this.defaultDimValueGetter = defaultDimValueGetters[source.sourceFormat]; // Default dim value getter

        this._dimValueGetter = dimValueGetter || defaultGetter; // Reset raw extent.

        this._rawExtent = [];
        var willRetrieveDataByName = shouldRetrieveDataByName(source);
        this._dimensions = map(inputDimensions, function (dim) {
          if ("development" !== 'production') {
            if (willRetrieveDataByName) {
              assert(dim.property != null);
            }
          }

          return {
            // Only pick these two props. Not leak other properties like orderMeta.
            type: dim.type,
            property: dim.property
          };
        });

        this._initDataFromProvider(0, provider.count());
      };

      DataStore.prototype.getProvider = function () {
        return this._provider;
      };
      /**
       * Caution: even when a `source` instance owned by a series, the created data store
       * may still be shared by different sereis (the source hash does not use all `source`
       * props, see `sourceManager`). In this case, the `source` props that are not used in
       * hash (like `source.dimensionDefine`) probably only belongs to a certain series and
       * thus should not be fetch here.
       */


      DataStore.prototype.getSource = function () {
        return this._provider.getSource();
      };
      /**
       * @caution Only used in dataStack.
       */


      DataStore.prototype.ensureCalculationDimension = function (dimName, type) {
        var calcDimNameToIdx = this._calcDimNameToIdx;
        var dimensions = this._dimensions;
        var calcDimIdx = calcDimNameToIdx.get(dimName);

        if (calcDimIdx != null) {
          if (dimensions[calcDimIdx].type === type) {
            return calcDimIdx;
          }
        } else {
          calcDimIdx = dimensions.length;
        }

        dimensions[calcDimIdx] = {
          type: type
        };
        calcDimNameToIdx.set(dimName, calcDimIdx);
        this._chunks[calcDimIdx] = new dataCtors[type || 'float'](this._rawCount);
        this._rawExtent[calcDimIdx] = getInitialExtent();
        return calcDimIdx;
      };

      DataStore.prototype.collectOrdinalMeta = function (dimIdx, ordinalMeta) {
        var chunk = this._chunks[dimIdx];
        var dim = this._dimensions[dimIdx];
        var rawExtents = this._rawExtent;
        var offset = dim.ordinalOffset || 0;
        var len = chunk.length;

        if (offset === 0) {
          // We need to reset the rawExtent if collect is from start.
          // Because this dimension may be guessed as number and calcuating a wrong extent.
          rawExtents[dimIdx] = getInitialExtent();
        }

        var dimRawExtent = rawExtents[dimIdx]; // Parse from previous data offset. len may be changed after appendData

        for (var i = offset; i < len; i++) {
          var val = chunk[i] = ordinalMeta.parseAndCollect(chunk[i]);

          if (!isNaN(val)) {
            dimRawExtent[0] = Math.min(val, dimRawExtent[0]);
            dimRawExtent[1] = Math.max(val, dimRawExtent[1]);
          }
        }

        dim.ordinalMeta = ordinalMeta;
        dim.ordinalOffset = len;
        dim.type = 'ordinal'; // Force to be ordinal
      };

      DataStore.prototype.getOrdinalMeta = function (dimIdx) {
        var dimInfo = this._dimensions[dimIdx];
        var ordinalMeta = dimInfo.ordinalMeta;
        return ordinalMeta;
      };

      DataStore.prototype.getDimensionProperty = function (dimIndex) {
        var item = this._dimensions[dimIndex];
        return item && item.property;
      };
      /**
       * Caution: Can be only called on raw data (before `this._indices` created).
       */


      DataStore.prototype.appendData = function (data) {
        if ("development" !== 'production') {
          assert(!this._indices, 'appendData can only be called on raw data.');
        }

        var provider = this._provider;
        var start = this.count();
        provider.appendData(data);
        var end = provider.count();

        if (!provider.persistent) {
          end += start;
        }

        if (start < end) {
          this._initDataFromProvider(start, end, true);
        }

        return [start, end];
      };

      DataStore.prototype.appendValues = function (values, minFillLen) {
        var chunks = this._chunks;
        var dimensions = this._dimensions;
        var dimLen = dimensions.length;
        var rawExtent = this._rawExtent;
        var start = this.count();
        var end = start + Math.max(values.length, minFillLen || 0);

        for (var i = 0; i < dimLen; i++) {
          var dim = dimensions[i];
          prepareStore(chunks, i, dim.type, end, true);
        }

        var emptyDataItem = [];

        for (var idx = start; idx < end; idx++) {
          var sourceIdx = idx - start; // Store the data by dimensions

          for (var dimIdx = 0; dimIdx < dimLen; dimIdx++) {
            var dim = dimensions[dimIdx];
            var val = defaultDimValueGetters.arrayRows.call(this, values[sourceIdx] || emptyDataItem, dim.property, sourceIdx, dimIdx);
            chunks[dimIdx][idx] = val;
            var dimRawExtent = rawExtent[dimIdx];
            val < dimRawExtent[0] && (dimRawExtent[0] = val);
            val > dimRawExtent[1] && (dimRawExtent[1] = val);
          }
        }

        this._rawCount = this._count = end;
        return {
          start: start,
          end: end
        };
      };

      DataStore.prototype._initDataFromProvider = function (start, end, append) {
        var provider = this._provider;
        var chunks = this._chunks;
        var dimensions = this._dimensions;
        var dimLen = dimensions.length;
        var rawExtent = this._rawExtent;
        var dimNames = map(dimensions, function (dim) {
          return dim.property;
        });

        for (var i = 0; i < dimLen; i++) {
          var dim = dimensions[i];

          if (!rawExtent[i]) {
            rawExtent[i] = getInitialExtent();
          }

          prepareStore(chunks, i, dim.type, end, append);
        }

        if (provider.fillStorage) {
          provider.fillStorage(start, end, chunks, rawExtent);
        } else {
          var dataItem = [];

          for (var idx = start; idx < end; idx++) {
            // NOTICE: Try not to write things into dataItem
            dataItem = provider.getItem(idx, dataItem); // Each data item is value
            // [1, 2]
            // 2
            // Bar chart, line chart which uses category axis
            // only gives the 'y' value. 'x' value is the indices of category
            // Use a tempValue to normalize the value to be a (x, y) value
            // Store the data by dimensions

            for (var dimIdx = 0; dimIdx < dimLen; dimIdx++) {
              var dimStorage = chunks[dimIdx]; // PENDING NULL is empty or zero

              var val = this._dimValueGetter(dataItem, dimNames[dimIdx], idx, dimIdx);

              dimStorage[idx] = val;
              var dimRawExtent = rawExtent[dimIdx];
              val < dimRawExtent[0] && (dimRawExtent[0] = val);
              val > dimRawExtent[1] && (dimRawExtent[1] = val);
            }
          }
        }

        if (!provider.persistent && provider.clean) {
          // Clean unused data if data source is typed array.
          provider.clean();
        }

        this._rawCount = this._count = end; // Reset data extent

        this._extent = [];
      };

      DataStore.prototype.count = function () {
        return this._count;
      };
      /**
       * Get value. Return NaN if idx is out of range.
       */


      DataStore.prototype.get = function (dim, idx) {
        if (!(idx >= 0 && idx < this._count)) {
          return NaN;
        }

        var dimStore = this._chunks[dim];
        return dimStore ? dimStore[this.getRawIndex(idx)] : NaN;
      };

      DataStore.prototype.getValues = function (dimensions, idx) {
        var values = [];
        var dimArr = [];

        if (idx == null) {
          idx = dimensions; // TODO get all from store?

          dimensions = []; // All dimensions

          for (var i = 0; i < this._dimensions.length; i++) {
            dimArr.push(i);
          }
        } else {
          dimArr = dimensions;
        }

        for (var i = 0, len = dimArr.length; i < len; i++) {
          values.push(this.get(dimArr[i], idx));
        }

        return values;
      };
      /**
       * @param dim concrete dim
       */


      DataStore.prototype.getByRawIndex = function (dim, rawIdx) {
        if (!(rawIdx >= 0 && rawIdx < this._rawCount)) {
          return NaN;
        }

        var dimStore = this._chunks[dim];
        return dimStore ? dimStore[rawIdx] : NaN;
      };
      /**
       * Get sum of data in one dimension
       */


      DataStore.prototype.getSum = function (dim) {
        var dimData = this._chunks[dim];
        var sum = 0;

        if (dimData) {
          for (var i = 0, len = this.count(); i < len; i++) {
            var value = this.get(dim, i);

            if (!isNaN(value)) {
              sum += value;
            }
          }
        }

        return sum;
      };
      /**
       * Get median of data in one dimension
       */


      DataStore.prototype.getMedian = function (dim) {
        var dimDataArray = []; // map all data of one dimension

        this.each([dim], function (val) {
          if (!isNaN(val)) {
            dimDataArray.push(val);
          }
        }); // TODO
        // Use quick select?

        var sortedDimDataArray = dimDataArray.sort(function (a, b) {
          return a - b;
        });
        var len = this.count(); // calculate median

        return len === 0 ? 0 : len % 2 === 1 ? sortedDimDataArray[(len - 1) / 2] : (sortedDimDataArray[len / 2] + sortedDimDataArray[len / 2 - 1]) / 2;
      };
      /**
       * Retrieve the index with given raw data index.
       */


      DataStore.prototype.indexOfRawIndex = function (rawIndex) {
        if (rawIndex >= this._rawCount || rawIndex < 0) {
          return -1;
        }

        if (!this._indices) {
          return rawIndex;
        } // Indices are ascending


        var indices = this._indices; // If rawIndex === dataIndex

        var rawDataIndex = indices[rawIndex];

        if (rawDataIndex != null && rawDataIndex < this._count && rawDataIndex === rawIndex) {
          return rawIndex;
        }

        var left = 0;
        var right = this._count - 1;

        while (left <= right) {
          var mid = (left + right) / 2 | 0;

          if (indices[mid] < rawIndex) {
            left = mid + 1;
          } else if (indices[mid] > rawIndex) {
            right = mid - 1;
          } else {
            return mid;
          }
        }

        return -1;
      };
      /**
       * Retrieve the index of nearest value.
       * @param dim
       * @param value
       * @param [maxDistance=Infinity]
       * @return If and only if multiple indices have
       *         the same value, they are put to the result.
       */


      DataStore.prototype.indicesOfNearest = function (dim, value, maxDistance) {
        var chunks = this._chunks;
        var dimData = chunks[dim];
        var nearestIndices = [];

        if (!dimData) {
          return nearestIndices;
        }

        if (maxDistance == null) {
          maxDistance = Infinity;
        }

        var minDist = Infinity;
        var minDiff = -1;
        var nearestIndicesLen = 0; // Check the test case of `test/ut/spec/data/SeriesData.js`.

        for (var i = 0, len = this.count(); i < len; i++) {
          var dataIndex = this.getRawIndex(i);
          var diff = value - dimData[dataIndex];
          var dist = Math.abs(diff);

          if (dist <= maxDistance) {
            // When the `value` is at the middle of `this.get(dim, i)` and `this.get(dim, i+1)`,
            // we'd better not push both of them to `nearestIndices`, otherwise it is easy to
            // get more than one item in `nearestIndices` (more specifically, in `tooltip`).
            // So we chose the one that `diff >= 0` in this csae.
            // But if `this.get(dim, i)` and `this.get(dim, j)` get the same value, both of them
            // should be push to `nearestIndices`.
            if (dist < minDist || dist === minDist && diff >= 0 && minDiff < 0) {
              minDist = dist;
              minDiff = diff;
              nearestIndicesLen = 0;
            }

            if (diff === minDiff) {
              nearestIndices[nearestIndicesLen++] = i;
            }
          }
        }

        nearestIndices.length = nearestIndicesLen;
        return nearestIndices;
      };

      DataStore.prototype.getIndices = function () {
        var newIndices;
        var indices = this._indices;

        if (indices) {
          var Ctor = indices.constructor;
          var thisCount = this._count; // `new Array(a, b, c)` is different from `new Uint32Array(a, b, c)`.

          if (Ctor === Array) {
            newIndices = new Ctor(thisCount);

            for (var i = 0; i < thisCount; i++) {
              newIndices[i] = indices[i];
            }
          } else {
            newIndices = new Ctor(indices.buffer, 0, thisCount);
          }
        } else {
          var Ctor = getIndicesCtor(this._rawCount);
          newIndices = new Ctor(this.count());

          for (var i = 0; i < newIndices.length; i++) {
            newIndices[i] = i;
          }
        }

        return newIndices;
      };
      /**
       * Data filter.
       */


      DataStore.prototype.filter = function (dims, cb) {
        if (!this._count) {
          return this;
        }

        var newStore = this.clone();
        var count = newStore.count();
        var Ctor = getIndicesCtor(newStore._rawCount);
        var newIndices = new Ctor(count);
        var value = [];
        var dimSize = dims.length;
        var offset = 0;
        var dim0 = dims[0];
        var chunks = newStore._chunks;

        for (var i = 0; i < count; i++) {
          var keep = void 0;
          var rawIdx = newStore.getRawIndex(i); // Simple optimization

          if (dimSize === 0) {
            keep = cb(i);
          } else if (dimSize === 1) {
            var val = chunks[dim0][rawIdx];
            keep = cb(val, i);
          } else {
            var k = 0;

            for (; k < dimSize; k++) {
              value[k] = chunks[dims[k]][rawIdx];
            }

            value[k] = i;
            keep = cb.apply(null, value);
          }

          if (keep) {
            newIndices[offset++] = rawIdx;
          }
        } // Set indices after filtered.


        if (offset < count) {
          newStore._indices = newIndices;
        }

        newStore._count = offset; // Reset data extent

        newStore._extent = [];

        newStore._updateGetRawIdx();

        return newStore;
      };
      /**
       * Select data in range. (For optimization of filter)
       * (Manually inline code, support 5 million data filtering in data zoom.)
       */


      DataStore.prototype.selectRange = function (range) {
        var newStore = this.clone();
        var len = newStore._count;

        if (!len) {
          return this;
        }

        var dims = keys(range);
        var dimSize = dims.length;

        if (!dimSize) {
          return this;
        }

        var originalCount = newStore.count();
        var Ctor = getIndicesCtor(newStore._rawCount);
        var newIndices = new Ctor(originalCount);
        var offset = 0;
        var dim0 = dims[0];
        var min = range[dim0][0];
        var max = range[dim0][1];
        var storeArr = newStore._chunks;
        var quickFinished = false;

        if (!newStore._indices) {
          // Extreme optimization for common case. About 2x faster in chrome.
          var idx = 0;

          if (dimSize === 1) {
            var dimStorage = storeArr[dims[0]];

            for (var i = 0; i < len; i++) {
              var val = dimStorage[i]; // NaN will not be filtered. Consider the case, in line chart, empty
              // value indicates the line should be broken. But for the case like
              // scatter plot, a data item with empty value will not be rendered,
              // but the axis extent may be effected if some other dim of the data
              // item has value. Fortunately it is not a significant negative effect.

              if (val >= min && val <= max || isNaN(val)) {
                newIndices[offset++] = idx;
              }

              idx++;
            }

            quickFinished = true;
          } else if (dimSize === 2) {
            var dimStorage = storeArr[dims[0]];
            var dimStorage2 = storeArr[dims[1]];
            var min2 = range[dims[1]][0];
            var max2 = range[dims[1]][1];

            for (var i = 0; i < len; i++) {
              var val = dimStorage[i];
              var val2 = dimStorage2[i]; // Do not filter NaN, see comment above.

              if ((val >= min && val <= max || isNaN(val)) && (val2 >= min2 && val2 <= max2 || isNaN(val2))) {
                newIndices[offset++] = idx;
              }

              idx++;
            }

            quickFinished = true;
          }
        }

        if (!quickFinished) {
          if (dimSize === 1) {
            for (var i = 0; i < originalCount; i++) {
              var rawIndex = newStore.getRawIndex(i);
              var val = storeArr[dims[0]][rawIndex]; // Do not filter NaN, see comment above.

              if (val >= min && val <= max || isNaN(val)) {
                newIndices[offset++] = rawIndex;
              }
            }
          } else {
            for (var i = 0; i < originalCount; i++) {
              var keep = true;
              var rawIndex = newStore.getRawIndex(i);

              for (var k = 0; k < dimSize; k++) {
                var dimk = dims[k];
                var val = storeArr[dimk][rawIndex]; // Do not filter NaN, see comment above.

                if (val < range[dimk][0] || val > range[dimk][1]) {
                  keep = false;
                }
              }

              if (keep) {
                newIndices[offset++] = newStore.getRawIndex(i);
              }
            }
          }
        } // Set indices after filtered.


        if (offset < originalCount) {
          newStore._indices = newIndices;
        }

        newStore._count = offset; // Reset data extent

        newStore._extent = [];

        newStore._updateGetRawIdx();

        return newStore;
      }; // /**
      //  * Data mapping to a plain array
      //  */
      // mapArray(dims: DimensionIndex[], cb: MapArrayCb): any[] {
      //     const result: any[] = [];
      //     this.each(dims, function () {
      //         result.push(cb && (cb as MapArrayCb).apply(null, arguments));
      //     });
      //     return result;
      // }

      /**
       * Data mapping to a new List with given dimensions
       */


      DataStore.prototype.map = function (dims, cb) {
        // TODO only clone picked chunks.
        var target = this.clone(dims);

        this._updateDims(target, dims, cb);

        return target;
      };
      /**
       * @caution Danger!! Only used in dataStack.
       */


      DataStore.prototype.modify = function (dims, cb) {
        this._updateDims(this, dims, cb);
      };

      DataStore.prototype._updateDims = function (target, dims, cb) {
        var targetChunks = target._chunks;
        var tmpRetValue = [];
        var dimSize = dims.length;
        var dataCount = target.count();
        var values = [];
        var rawExtent = target._rawExtent;

        for (var i = 0; i < dims.length; i++) {
          rawExtent[dims[i]] = getInitialExtent();
        }

        for (var dataIndex = 0; dataIndex < dataCount; dataIndex++) {
          var rawIndex = target.getRawIndex(dataIndex);

          for (var k = 0; k < dimSize; k++) {
            values[k] = targetChunks[dims[k]][rawIndex];
          }

          values[dimSize] = dataIndex;
          var retValue = cb && cb.apply(null, values);

          if (retValue != null) {
            // a number or string (in oridinal dimension)?
            if (typeof retValue !== 'object') {
              tmpRetValue[0] = retValue;
              retValue = tmpRetValue;
            }

            for (var i = 0; i < retValue.length; i++) {
              var dim = dims[i];
              var val = retValue[i];
              var rawExtentOnDim = rawExtent[dim];
              var dimStore = targetChunks[dim];

              if (dimStore) {
                dimStore[rawIndex] = val;
              }

              if (val < rawExtentOnDim[0]) {
                rawExtentOnDim[0] = val;
              }

              if (val > rawExtentOnDim[1]) {
                rawExtentOnDim[1] = val;
              }
            }
          }
        }
      };
      /**
       * Large data down sampling using largest-triangle-three-buckets
       * @param {string} valueDimension
       * @param {number} targetCount
       */


      DataStore.prototype.lttbDownSample = function (valueDimension, rate) {
        var target = this.clone([valueDimension], true);
        var targetStorage = target._chunks;
        var dimStore = targetStorage[valueDimension];
        var len = this.count();
        var sampledIndex = 0;
        var frameSize = Math.floor(1 / rate);
        var currentRawIndex = this.getRawIndex(0);
        var maxArea;
        var area;
        var nextRawIndex;
        var newIndices = new (getIndicesCtor(this._rawCount))(Math.min((Math.ceil(len / frameSize) + 2) * 2, len)); // First frame use the first data.

        newIndices[sampledIndex++] = currentRawIndex;

        for (var i = 1; i < len - 1; i += frameSize) {
          var nextFrameStart = Math.min(i + frameSize, len - 1);
          var nextFrameEnd = Math.min(i + frameSize * 2, len);
          var avgX = (nextFrameEnd + nextFrameStart) / 2;
          var avgY = 0;

          for (var idx = nextFrameStart; idx < nextFrameEnd; idx++) {
            var rawIndex = this.getRawIndex(idx);
            var y = dimStore[rawIndex];

            if (isNaN(y)) {
              continue;
            }

            avgY += y;
          }

          avgY /= nextFrameEnd - nextFrameStart;
          var frameStart = i;
          var frameEnd = Math.min(i + frameSize, len);
          var pointAX = i - 1;
          var pointAY = dimStore[currentRawIndex];
          maxArea = -1;
          nextRawIndex = frameStart;
          var firstNaNIndex = -1;
          var countNaN = 0; // Find a point from current frame that construct a triangel with largest area with previous selected point
          // And the average of next frame.

          for (var idx = frameStart; idx < frameEnd; idx++) {
            var rawIndex = this.getRawIndex(idx);
            var y = dimStore[rawIndex];

            if (isNaN(y)) {
              countNaN++;

              if (firstNaNIndex < 0) {
                firstNaNIndex = rawIndex;
              }

              continue;
            } // Calculate triangle area over three buckets


            area = Math.abs((pointAX - avgX) * (y - pointAY) - (pointAX - idx) * (avgY - pointAY));

            if (area > maxArea) {
              maxArea = area;
              nextRawIndex = rawIndex; // Next a is this b
            }
          }

          if (countNaN > 0 && countNaN < frameEnd - frameStart) {
            // Append first NaN point in every bucket.
            // It is necessary to ensure the correct order of indices.
            newIndices[sampledIndex++] = Math.min(firstNaNIndex, nextRawIndex);
            nextRawIndex = Math.max(firstNaNIndex, nextRawIndex);
          }

          newIndices[sampledIndex++] = nextRawIndex;
          currentRawIndex = nextRawIndex; // This a is the next a (chosen b)
        } // First frame use the last data.


        newIndices[sampledIndex++] = this.getRawIndex(len - 1);
        target._count = sampledIndex;
        target._indices = newIndices;
        target.getRawIndex = this._getRawIdx;
        return target;
      };
      /**
       * Large data down sampling on given dimension
       * @param sampleIndex Sample index for name and id
       */


      DataStore.prototype.downSample = function (dimension, rate, sampleValue, sampleIndex) {
        var target = this.clone([dimension], true);
        var targetStorage = target._chunks;
        var frameValues = [];
        var frameSize = Math.floor(1 / rate);
        var dimStore = targetStorage[dimension];
        var len = this.count();
        var rawExtentOnDim = target._rawExtent[dimension] = getInitialExtent();
        var newIndices = new (getIndicesCtor(this._rawCount))(Math.ceil(len / frameSize));
        var offset = 0;

        for (var i = 0; i < len; i += frameSize) {
          // Last frame
          if (frameSize > len - i) {
            frameSize = len - i;
            frameValues.length = frameSize;
          }

          for (var k = 0; k < frameSize; k++) {
            var dataIdx = this.getRawIndex(i + k);
            frameValues[k] = dimStore[dataIdx];
          }

          var value = sampleValue(frameValues);
          var sampleFrameIdx = this.getRawIndex(Math.min(i + sampleIndex(frameValues, value) || 0, len - 1)); // Only write value on the filtered data

          dimStore[sampleFrameIdx] = value;

          if (value < rawExtentOnDim[0]) {
            rawExtentOnDim[0] = value;
          }

          if (value > rawExtentOnDim[1]) {
            rawExtentOnDim[1] = value;
          }

          newIndices[offset++] = sampleFrameIdx;
        }

        target._count = offset;
        target._indices = newIndices;

        target._updateGetRawIdx();

        return target;
      };
      /**
       * Data iteration
       * @param ctx default this
       * @example
       *  list.each('x', function (x, idx) {});
       *  list.each(['x', 'y'], function (x, y, idx) {});
       *  list.each(function (idx) {})
       */


      DataStore.prototype.each = function (dims, cb) {
        if (!this._count) {
          return;
        }

        var dimSize = dims.length;
        var chunks = this._chunks;

        for (var i = 0, len = this.count(); i < len; i++) {
          var rawIdx = this.getRawIndex(i); // Simple optimization

          switch (dimSize) {
            case 0:
              cb(i);
              break;

            case 1:
              cb(chunks[dims[0]][rawIdx], i);
              break;

            case 2:
              cb(chunks[dims[0]][rawIdx], chunks[dims[1]][rawIdx], i);
              break;

            default:
              var k = 0;
              var value = [];

              for (; k < dimSize; k++) {
                value[k] = chunks[dims[k]][rawIdx];
              } // Index


              value[k] = i;
              cb.apply(null, value);
          }
        }
      };
      /**
       * Get extent of data in one dimension
       */


      DataStore.prototype.getDataExtent = function (dim) {
        // Make sure use concrete dim as cache name.
        var dimData = this._chunks[dim];
        var initialExtent = getInitialExtent();

        if (!dimData) {
          return initialExtent;
        } // Make more strict checkings to ensure hitting cache.


        var currEnd = this.count(); // Consider the most cases when using data zoom, `getDataExtent`
        // happened before filtering. We cache raw extent, which is not
        // necessary to be cleared and recalculated when restore data.

        var useRaw = !this._indices;
        var dimExtent;

        if (useRaw) {
          return this._rawExtent[dim].slice();
        }

        dimExtent = this._extent[dim];

        if (dimExtent) {
          return dimExtent.slice();
        }

        dimExtent = initialExtent;
        var min = dimExtent[0];
        var max = dimExtent[1];

        for (var i = 0; i < currEnd; i++) {
          var rawIdx = this.getRawIndex(i);
          var value = dimData[rawIdx];
          value < min && (min = value);
          value > max && (max = value);
        }

        dimExtent = [min, max];
        this._extent[dim] = dimExtent;
        return dimExtent;
      };
      /**
       * Get raw data item
       */


      DataStore.prototype.getRawDataItem = function (idx) {
        var rawIdx = this.getRawIndex(idx);

        if (!this._provider.persistent) {
          var val = [];
          var chunks = this._chunks;

          for (var i = 0; i < chunks.length; i++) {
            val.push(chunks[i][rawIdx]);
          }

          return val;
        } else {
          return this._provider.getItem(rawIdx);
        }
      };
      /**
       * Clone shallow.
       *
       * @param clonedDims Determine which dims to clone. Will share the data if not specified.
       */


      DataStore.prototype.clone = function (clonedDims, ignoreIndices) {
        var target = new DataStore();
        var chunks = this._chunks;
        var clonedDimsMap = clonedDims && reduce(clonedDims, function (obj, dimIdx) {
          obj[dimIdx] = true;
          return obj;
        }, {});

        if (clonedDimsMap) {
          for (var i = 0; i < chunks.length; i++) {
            // Not clone if dim is not picked.
            target._chunks[i] = !clonedDimsMap[i] ? chunks[i] : cloneChunk(chunks[i]);
          }
        } else {
          target._chunks = chunks;
        }

        this._copyCommonProps(target);

        if (!ignoreIndices) {
          target._indices = this._cloneIndices();
        }

        target._updateGetRawIdx();

        return target;
      };

      DataStore.prototype._copyCommonProps = function (target) {
        target._count = this._count;
        target._rawCount = this._rawCount;
        target._provider = this._provider;
        target._dimensions = this._dimensions;
        target._extent = clone(this._extent);
        target._rawExtent = clone(this._rawExtent);
      };

      DataStore.prototype._cloneIndices = function () {
        if (this._indices) {
          var Ctor = this._indices.constructor;
          var indices = void 0;

          if (Ctor === Array) {
            var thisCount = this._indices.length;
            indices = new Ctor(thisCount);

            for (var i = 0; i < thisCount; i++) {
              indices[i] = this._indices[i];
            }
          } else {
            indices = new Ctor(this._indices);
          }

          return indices;
        }

        return null;
      };

      DataStore.prototype._getRawIdxIdentity = function (idx) {
        return idx;
      };

      DataStore.prototype._getRawIdx = function (idx) {
        if (idx < this._count && idx >= 0) {
          return this._indices[idx];
        }

        return -1;
      };

      DataStore.prototype._updateGetRawIdx = function () {
        this.getRawIndex = this._indices ? this._getRawIdx : this._getRawIdxIdentity;
      };

      DataStore.internalField = function () {
        function getDimValueSimply(dataItem, property, dataIndex, dimIndex) {
          return parseDataValue(dataItem[dimIndex], this._dimensions[dimIndex]);
        }

        defaultDimValueGetters = {
          arrayRows: getDimValueSimply,
          objectRows: function (dataItem, property, dataIndex, dimIndex) {
            return parseDataValue(dataItem[property], this._dimensions[dimIndex]);
          },
          keyedColumns: getDimValueSimply,
          original: function (dataItem, property, dataIndex, dimIndex) {
            // Performance sensitive, do not use modelUtil.getDataItemValue.
            // If dataItem is an plain object with no value field, the let `value`
            // will be assigned with the object, but it will be tread correctly
            // in the `convertValue`.
            var value = dataItem && (dataItem.value == null ? dataItem : dataItem.value);
            return parseDataValue(value instanceof Array ? value[dimIndex] // If value is a single number or something else not array.
            : value, this._dimensions[dimIndex]);
          },
          typedArray: function (dataItem, property, dataIndex, dimIndex) {
            return dataItem[dimIndex];
          }
        };
      }();

      return DataStore;
    }();

    /**
     * [REQUIREMENT_MEMO]:
     * (0) `metaRawOption` means `dimensions`/`sourceHeader`/`seriesLayoutBy` in raw option.
     * (1) Keep support the feature: `metaRawOption` can be specified both on `series` and
     * `root-dataset`. Them on `series` has higher priority.
     * (2) Do not support to set `metaRawOption` on a `non-root-dataset`, because it might
     * confuse users: whether those props indicate how to visit the upstream source or visit
     * the transform result source, and some transforms has nothing to do with these props,
     * and some transforms might have multiple upstream.
     * (3) Transforms should specify `metaRawOption` in each output, just like they can be
     * declared in `root-dataset`.
     * (4) At present only support visit source in `SERIES_LAYOUT_BY_COLUMN` in transforms.
     * That is for reducing complexity in transforms.
     * PENDING: Whether to provide transposition transform?
     *
     * [IMPLEMENTAION_MEMO]:
     * "sourceVisitConfig" are calculated from `metaRawOption` and `data`.
     * They will not be calculated until `source` is about to be visited (to prevent from
     * duplicate calcuation). `source` is visited only in series and input to transforms.
     *
     * [DIMENSION_INHERIT_RULE]:
     * By default the dimensions are inherited from ancestors, unless a transform return
     * a new dimensions definition.
     * Consider the case:
     * ```js
     * dataset: [{
     *     source: [ ['Product', 'Sales', 'Prise'], ['Cookies', 321, 44.21], ...]
     * }, {
     *     transform: { type: 'filter', ... }
     * }]
     * dataset: [{
     *     dimension: ['Product', 'Sales', 'Prise'],
     *     source: [ ['Cookies', 321, 44.21], ...]
     * }, {
     *     transform: { type: 'filter', ... }
     * }]
     * ```
     * The two types of option should have the same behavior after transform.
     *
     *
     * [SCENARIO]:
     * (1) Provide source data directly:
     * ```js
     * series: {
     *     encode: {...},
     *     dimensions: [...]
     *     seriesLayoutBy: 'row',
     *     data: [[...]]
     * }
     * ```
     * (2) Series refer to dataset.
     * ```js
     * series: [{
     *     encode: {...}
     *     // Ignore datasetIndex means `datasetIndex: 0`
     *     // and the dimensions defination in dataset is used
     * }, {
     *     encode: {...},
     *     seriesLayoutBy: 'column',
     *     datasetIndex: 1
     * }]
     * ```
     * (3) dataset transform
     * ```js
     * dataset: [{
     *     source: [...]
     * }, {
     *     source: [...]
     * }, {
     *     // By default from 0.
     *     transform: { type: 'filter', config: {...} }
     * }, {
     *     // Piped.
     *     transform: [
     *         { type: 'filter', config: {...} },
     *         { type: 'sort', config: {...} }
     *     ]
     * }, {
     *     id: 'regressionData',
     *     fromDatasetIndex: 1,
     *     // Third-party transform
     *     transform: { type: 'ecStat:regression', config: {...} }
     * }, {
     *     // retrieve the extra result.
     *     id: 'regressionFormula',
     *     fromDatasetId: 'regressionData',
     *     fromTransformResult: 1
     * }]
     * ```
     */

    var SourceManager =
    /** @class */
    function () {
      function SourceManager(sourceHost) {
        // Cached source. Do not repeat calculating if not dirty.
        this._sourceList = [];
        this._storeList = []; // version sign of each upstream source manager.

        this._upstreamSignList = [];
        this._versionSignBase = 0;
        this._dirty = true;
        this._sourceHost = sourceHost;
      }
      /**
       * Mark dirty.
       */


      SourceManager.prototype.dirty = function () {
        this._setLocalSource([], []);

        this._storeList = [];
        this._dirty = true;
      };

      SourceManager.prototype._setLocalSource = function (sourceList, upstreamSignList) {
        this._sourceList = sourceList;
        this._upstreamSignList = upstreamSignList;
        this._versionSignBase++;

        if (this._versionSignBase > 9e10) {
          this._versionSignBase = 0;
        }
      };
      /**
       * For detecting whether the upstream source is dirty, so that
       * the local cached source (in `_sourceList`) should be discarded.
       */


      SourceManager.prototype._getVersionSign = function () {
        return this._sourceHost.uid + '_' + this._versionSignBase;
      };
      /**
       * Always return a source instance. Otherwise throw error.
       */


      SourceManager.prototype.prepareSource = function () {
        // For the case that call `setOption` multiple time but no data changed,
        // cache the result source to prevent from repeating transform.
        if (this._isDirty()) {
          this._createSource();

          this._dirty = false;
        }
      };

      SourceManager.prototype._createSource = function () {
        this._setLocalSource([], []);

        var sourceHost = this._sourceHost;

        var upSourceMgrList = this._getUpstreamSourceManagers();

        var hasUpstream = !!upSourceMgrList.length;
        var resultSourceList;
        var upstreamSignList;

        if (isSeries(sourceHost)) {
          var seriesModel = sourceHost;
          var data = void 0;
          var sourceFormat = void 0;
          var upSource = void 0; // Has upstream dataset

          if (hasUpstream) {
            var upSourceMgr = upSourceMgrList[0];
            upSourceMgr.prepareSource();
            upSource = upSourceMgr.getSource();
            data = upSource.data;
            sourceFormat = upSource.sourceFormat;
            upstreamSignList = [upSourceMgr._getVersionSign()];
          } // Series data is from own.
          else {
              data = seriesModel.get('data', true);
              sourceFormat = isTypedArray(data) ? SOURCE_FORMAT_TYPED_ARRAY : SOURCE_FORMAT_ORIGINAL;
              upstreamSignList = [];
            } // See [REQUIREMENT_MEMO], merge settings on series and parent dataset if it is root.


          var newMetaRawOption = this._getSourceMetaRawOption() || {};
          var upMetaRawOption = upSource && upSource.metaRawOption || {};
          var seriesLayoutBy = retrieve2(newMetaRawOption.seriesLayoutBy, upMetaRawOption.seriesLayoutBy) || null;
          var sourceHeader = retrieve2(newMetaRawOption.sourceHeader, upMetaRawOption.sourceHeader); // Note here we should not use `upSource.dimensionsDefine`. Consider the case:
          // `upSource.dimensionsDefine` is detected by `seriesLayoutBy: 'column'`,
          // but series need `seriesLayoutBy: 'row'`.

          var dimensions = retrieve2(newMetaRawOption.dimensions, upMetaRawOption.dimensions); // We share source with dataset as much as possible
          // to avoid extra memory cost of high dimensional data.

          var needsCreateSource = seriesLayoutBy !== upMetaRawOption.seriesLayoutBy || !!sourceHeader !== !!upMetaRawOption.sourceHeader || dimensions;
          resultSourceList = needsCreateSource ? [createSource(data, {
            seriesLayoutBy: seriesLayoutBy,
            sourceHeader: sourceHeader,
            dimensions: dimensions
          }, sourceFormat)] : [];
        } else {
          var datasetModel = sourceHost; // Has upstream dataset.

          if (hasUpstream) {
            var result = this._applyTransform(upSourceMgrList);

            resultSourceList = result.sourceList;
            upstreamSignList = result.upstreamSignList;
          } // Is root dataset.
          else {
              var sourceData = datasetModel.get('source', true);
              resultSourceList = [createSource(sourceData, this._getSourceMetaRawOption(), null)];
              upstreamSignList = [];
            }
        }

        if ("development" !== 'production') {
          assert(resultSourceList && upstreamSignList);
        }

        this._setLocalSource(resultSourceList, upstreamSignList);
      };

      SourceManager.prototype._applyTransform = function (upMgrList) {
        var datasetModel = this._sourceHost;
        var transformOption = datasetModel.get('transform', true);
        var fromTransformResult = datasetModel.get('fromTransformResult', true);

        if ("development" !== 'production') {
          assert(fromTransformResult != null || transformOption != null);
        }

        if (fromTransformResult != null) {
          var errMsg = '';

          if (upMgrList.length !== 1) {
            if ("development" !== 'production') {
              errMsg = 'When using `fromTransformResult`, there should be only one upstream dataset';
            }

            doThrow(errMsg);
          }
        }

        var sourceList;
        var upSourceList = [];
        var upstreamSignList = [];
        each(upMgrList, function (upMgr) {
          upMgr.prepareSource();
          var upSource = upMgr.getSource(fromTransformResult || 0);
          var errMsg = '';

          if (fromTransformResult != null && !upSource) {
            if ("development" !== 'production') {
              errMsg = 'Can not retrieve result by `fromTransformResult`: ' + fromTransformResult;
            }

            doThrow(errMsg);
          }

          upSourceList.push(upSource);
          upstreamSignList.push(upMgr._getVersionSign());
        });

        if (transformOption) {
          sourceList = applyDataTransform(transformOption, upSourceList, {
            datasetIndex: datasetModel.componentIndex
          });
        } else if (fromTransformResult != null) {
          sourceList = [cloneSourceShallow(upSourceList[0])];
        }

        return {
          sourceList: sourceList,
          upstreamSignList: upstreamSignList
        };
      };

      SourceManager.prototype._isDirty = function () {
        if (this._dirty) {
          return true;
        } // All sourceList is from the some upstream.


        var upSourceMgrList = this._getUpstreamSourceManagers();

        for (var i = 0; i < upSourceMgrList.length; i++) {
          var upSrcMgr = upSourceMgrList[i];

          if ( // Consider the case that there is ancestor diry, call it recursively.
          // The performance is probably not an issue because usually the chain is not long.
          upSrcMgr._isDirty() || this._upstreamSignList[i] !== upSrcMgr._getVersionSign()) {
            return true;
          }
        }
      };
      /**
       * @param sourceIndex By default 0, means "main source".
       *                    In most cases there is only one source.
       */


      SourceManager.prototype.getSource = function (sourceIndex) {
        sourceIndex = sourceIndex || 0;
        var source = this._sourceList[sourceIndex];

        if (!source) {
          // Series may share source instance with dataset.
          var upSourceMgrList = this._getUpstreamSourceManagers();

          return upSourceMgrList[0] && upSourceMgrList[0].getSource(sourceIndex);
        }

        return source;
      };
      /**
       *
       * Get a data store which can be shared across series.
       * Only available for series.
       *
       * @param seriesDimRequest Dimensions that are generated in series.
       *        Should have been sorted by `storeDimIndex` asc.
       */


      SourceManager.prototype.getSharedDataStore = function (seriesDimRequest) {
        if ("development" !== 'production') {
          assert(isSeries(this._sourceHost), 'Can only call getDataStore on series source manager.');
        }

        var schema = seriesDimRequest.makeStoreSchema();
        return this._innerGetDataStore(schema.dimensions, seriesDimRequest.source, schema.hash);
      };

      SourceManager.prototype._innerGetDataStore = function (storeDims, seriesSource, sourceReadKey) {
        // TODO Can use other sourceIndex?
        var sourceIndex = 0;
        var storeList = this._storeList;
        var cachedStoreMap = storeList[sourceIndex];

        if (!cachedStoreMap) {
          cachedStoreMap = storeList[sourceIndex] = {};
        }

        var cachedStore = cachedStoreMap[sourceReadKey];

        if (!cachedStore) {
          var upSourceMgr = this._getUpstreamSourceManagers()[0];

          if (isSeries(this._sourceHost) && upSourceMgr) {
            cachedStore = upSourceMgr._innerGetDataStore(storeDims, seriesSource, sourceReadKey);
          } else {
            cachedStore = new DataStore(); // Always create store from source of series.

            cachedStore.initData(new DefaultDataProvider(seriesSource, storeDims.length), storeDims);
          }

          cachedStoreMap[sourceReadKey] = cachedStore;
        }

        return cachedStore;
      };
      /**
       * PENDING: Is it fast enough?
       * If no upstream, return empty array.
       */


      SourceManager.prototype._getUpstreamSourceManagers = function () {
        // Always get the relationship from the raw option.
        // Do not cache the link of the dependency graph, so that
        // there is no need to update them when change happens.
        var sourceHost = this._sourceHost;

        if (isSeries(sourceHost)) {
          var datasetModel = querySeriesUpstreamDatasetModel(sourceHost);
          return !datasetModel ? [] : [datasetModel.getSourceManager()];
        } else {
          return map(queryDatasetUpstreamDatasetModels(sourceHost), function (datasetModel) {
            return datasetModel.getSourceManager();
          });
        }
      };

      SourceManager.prototype._getSourceMetaRawOption = function () {
        var sourceHost = this._sourceHost;
        var seriesLayoutBy;
        var sourceHeader;
        var dimensions;

        if (isSeries(sourceHost)) {
          seriesLayoutBy = sourceHost.get('seriesLayoutBy', true);
          sourceHeader = sourceHost.get('sourceHeader', true);
          dimensions = sourceHost.get('dimensions', true);
        } // See [REQUIREMENT_MEMO], `non-root-dataset` do not support them.
        else if (!this._getUpstreamSourceManagers().length) {
            var model = sourceHost;
            seriesLayoutBy = model.get('seriesLayoutBy', true);
            sourceHeader = model.get('sourceHeader', true);
            dimensions = model.get('dimensions', true);
          }

        return {
          seriesLayoutBy: seriesLayoutBy,
          sourceHeader: sourceHeader,
          dimensions: dimensions
        };
      };

      return SourceManager;
    }();
    // disable the transform merge, but do not disable transform clone from rawOption.

    function disableTransformOptionMerge(datasetModel) {
      var transformOption = datasetModel.option.transform;
      transformOption && setAsPrimitive(datasetModel.option.transform);
    }

    function isSeries(sourceHost) {
      // Avoid circular dependency with Series.ts
      return sourceHost.mainType === 'series';
    }

    function doThrow(errMsg) {
      throw new Error(errMsg);
    }

    function createTooltipMarkup(type, option) {
      option.type = type;
      return option;
    }

    function retrieveVisualColorForTooltipMarker(series, dataIndex) {
      var style = series.getData().getItemVisual(dataIndex, 'style');
      var color = style[series.visualDrawType];
      return convertToColorString(color);
    }

    function defaultSeriesFormatTooltip(opt) {
      var series = opt.series;
      var dataIndex = opt.dataIndex;
      var multipleSeries = opt.multipleSeries;
      var data = series.getData();
      var tooltipDims = data.mapDimensionsAll('defaultedTooltip');
      var tooltipDimLen = tooltipDims.length;
      var value = series.getRawValue(dataIndex);
      var isValueArr = isArray(value);
      var markerColor = retrieveVisualColorForTooltipMarker(series, dataIndex); // Complicated rule for pretty tooltip.

      var inlineValue;
      var inlineValueType;
      var subBlocks;
      var sortParam;

      if (tooltipDimLen > 1 || isValueArr && !tooltipDimLen) {
        var formatArrResult = formatTooltipArrayValue(value, series, dataIndex, tooltipDims, markerColor);
        inlineValue = formatArrResult.inlineValues;
        inlineValueType = formatArrResult.inlineValueTypes;
        subBlocks = formatArrResult.blocks; // Only support tooltip sort by the first inline value. It's enough in most cases.

        sortParam = formatArrResult.inlineValues[0];
      } else if (tooltipDimLen) {
        var dimInfo = data.getDimensionInfo(tooltipDims[0]);
        sortParam = inlineValue = retrieveRawValue(data, dataIndex, tooltipDims[0]);
        inlineValueType = dimInfo.type;
      } else {
        sortParam = inlineValue = isValueArr ? value[0] : value;
      } // Do not show generated series name. It might not be readable.


      var seriesNameSpecified = isNameSpecified(series);
      var seriesName = seriesNameSpecified && series.name || '';
      var itemName = data.getName(dataIndex);
      var inlineName = multipleSeries ? seriesName : itemName;
      return createTooltipMarkup('section', {
        header: seriesName,
        // When series name not specified, do not show a header line with only '-'.
        // This case alway happen in tooltip.trigger: 'item'.
        noHeader: multipleSeries || !seriesNameSpecified,
        sortParam: sortParam,
        blocks: [createTooltipMarkup('nameValue', {
          markerType: 'item',
          markerColor: markerColor,
          // Do not mix display seriesName and itemName in one tooltip,
          // which might confuses users.
          name: inlineName,
          // name dimension might be auto assigned, where the name might
          // be not readable. So we check trim here.
          noName: !trim(inlineName),
          value: inlineValue,
          valueType: inlineValueType
        })].concat(subBlocks || [])
      });
    }

    function formatTooltipArrayValue(value, series, dataIndex, tooltipDims, colorStr) {
      // check: category-no-encode-has-axis-data in dataset.html
      var data = series.getData();
      var isValueMultipleLine = reduce(value, function (isValueMultipleLine, val, idx) {
        var dimItem = data.getDimensionInfo(idx);
        return isValueMultipleLine = isValueMultipleLine || dimItem && dimItem.tooltip !== false && dimItem.displayName != null;
      }, false);
      var inlineValues = [];
      var inlineValueTypes = [];
      var blocks = [];
      tooltipDims.length ? each(tooltipDims, function (dim) {
        setEachItem(retrieveRawValue(data, dataIndex, dim), dim);
      }) // By default, all dims is used on tooltip.
      : each(value, setEachItem);

      function setEachItem(val, dim) {
        var dimInfo = data.getDimensionInfo(dim); // If `dimInfo.tooltip` is not set, show tooltip.

        if (!dimInfo || dimInfo.otherDims.tooltip === false) {
          return;
        }

        if (isValueMultipleLine) {
          blocks.push(createTooltipMarkup('nameValue', {
            markerType: 'subItem',
            markerColor: colorStr,
            name: dimInfo.displayName,
            value: val,
            valueType: dimInfo.type
          }));
        } else {
          inlineValues.push(val);
          inlineValueTypes.push(dimInfo.type);
        }
      }

      return {
        inlineValues: inlineValues,
        inlineValueTypes: inlineValueTypes,
        blocks: blocks
      };
    }

    var inner$1 = makeInner();

    function getSelectionKey(data, dataIndex) {
      return data.getName(dataIndex) || data.getId(dataIndex);
    }

    var SERIES_UNIVERSAL_TRANSITION_PROP = '__universalTransitionEnabled';

    var SeriesModel =
    /** @class */
    function (_super) {
      __extends(SeriesModel, _super);

      function SeriesModel() {
        // [Caution]: Because this class or desecendants can be used as `XXX.extend(subProto)`,
        // the class members must not be initialized in constructor or declaration place.
        // Otherwise there is bad case:
        //   class A {xxx = 1;}
        //   enableClassExtend(A);
        //   class B extends A {}
        //   var C = B.extend({xxx: 5});
        //   var c = new C();
        //   console.log(c.xxx); // expect 5 but always 1.
        var _this = _super !== null && _super.apply(this, arguments) || this; // ---------------------------------------
        // Props about data selection
        // ---------------------------------------


        _this._selectedDataIndicesMap = {};
        return _this;
      }

      SeriesModel.prototype.init = function (option, parentModel, ecModel) {
        this.seriesIndex = this.componentIndex;
        this.dataTask = createTask({
          count: dataTaskCount,
          reset: dataTaskReset
        });
        this.dataTask.context = {
          model: this
        };
        this.mergeDefaultAndTheme(option, ecModel);
        var sourceManager = inner$1(this).sourceManager = new SourceManager(this);
        sourceManager.prepareSource();
        var data = this.getInitialData(option, ecModel);
        wrapData(data, this);
        this.dataTask.context.data = data;

        if ("development" !== 'production') {
          assert(data, 'getInitialData returned invalid data.');
        }

        inner$1(this).dataBeforeProcessed = data; // If we reverse the order (make data firstly, and then make
        // dataBeforeProcessed by cloneShallow), cloneShallow will
        // cause data.graph.data !== data when using
        // module:echarts/data/Graph or module:echarts/data/Tree.
        // See module:echarts/data/helper/linkSeriesData
        // Theoretically, it is unreasonable to call `seriesModel.getData()` in the model
        // init or merge stage, because the data can be restored. So we do not `restoreData`
        // and `setData` here, which forbids calling `seriesModel.getData()` in this stage.
        // Call `seriesModel.getRawData()` instead.
        // this.restoreData();

        autoSeriesName(this);

        this._initSelectedMapFromData(data);
      };
      /**
       * Util for merge default and theme to option
       */


      SeriesModel.prototype.mergeDefaultAndTheme = function (option, ecModel) {
        var layoutMode = fetchLayoutMode(this);
        var inputPositionParams = layoutMode ? getLayoutParams(option) : {}; // Backward compat: using subType on theme.
        // But if name duplicate between series subType
        // (for example: parallel) add component mainType,
        // add suffix 'Series'.

        var themeSubType = this.subType;

        if (ComponentModel.hasClass(themeSubType)) {
          themeSubType += 'Series';
        }

        merge(option, ecModel.getTheme().get(this.subType));
        merge(option, this.getDefaultOption()); // Default label emphasis `show`

        defaultEmphasis(option, 'label', ['show']);
        this.fillDataTextStyle(option.data);

        if (layoutMode) {
          mergeLayoutParam(option, inputPositionParams, layoutMode);
        }
      };

      SeriesModel.prototype.mergeOption = function (newSeriesOption, ecModel) {
        // this.settingTask.dirty();
        newSeriesOption = merge(this.option, newSeriesOption, true);
        this.fillDataTextStyle(newSeriesOption.data);
        var layoutMode = fetchLayoutMode(this);

        if (layoutMode) {
          mergeLayoutParam(this.option, newSeriesOption, layoutMode);
        }

        var sourceManager = inner$1(this).sourceManager;
        sourceManager.dirty();
        sourceManager.prepareSource();
        var data = this.getInitialData(newSeriesOption, ecModel);
        wrapData(data, this);
        this.dataTask.dirty();
        this.dataTask.context.data = data;
        inner$1(this).dataBeforeProcessed = data;
        autoSeriesName(this);

        this._initSelectedMapFromData(data);
      };

      SeriesModel.prototype.fillDataTextStyle = function (data) {
        // Default data label emphasis `show`
        // FIXME Tree structure data ?
        // FIXME Performance ?
        if (data && !isTypedArray(data)) {
          var props = ['show'];

          for (var i = 0; i < data.length; i++) {
            if (data[i] && data[i].label) {
              defaultEmphasis(data[i], 'label', props);
            }
          }
        }
      };
      /**
       * Init a data structure from data related option in series
       * Must be overridden.
       */


      SeriesModel.prototype.getInitialData = function (option, ecModel) {
        return;
      };
      /**
       * Append data to list
       */


      SeriesModel.prototype.appendData = function (params) {
        // FIXME ???
        // (1) If data from dataset, forbidden append.
        // (2) support append data of dataset.
        var data = this.getRawData();
        data.appendData(params.data);
      };
      /**
       * Consider some method like `filter`, `map` need make new data,
       * We should make sure that `seriesModel.getData()` get correct
       * data in the stream procedure. So we fetch data from upstream
       * each time `task.perform` called.
       */


      SeriesModel.prototype.getData = function (dataType) {
        var task = getCurrentTask(this);

        if (task) {
          var data = task.context.data;
          return dataType == null ? data : data.getLinkedData(dataType);
        } else {
          // When series is not alive (that may happen when click toolbox
          // restore or setOption with not merge mode), series data may
          // be still need to judge animation or something when graphic
          // elements want to know whether fade out.
          return inner$1(this).data;
        }
      };

      SeriesModel.prototype.getAllData = function () {
        var mainData = this.getData();
        return mainData && mainData.getLinkedDataAll ? mainData.getLinkedDataAll() : [{
          data: mainData
        }];
      };

      SeriesModel.prototype.setData = function (data) {
        var task = getCurrentTask(this);

        if (task) {
          var context = task.context; // Consider case: filter, data sample.
          // FIXME:TS never used, so comment it
          // if (context.data !== data && task.modifyOutputEnd) {
          //     task.setOutputEnd(data.count());
          // }

          context.outputData = data; // Caution: setData should update context.data,
          // Because getData may be called multiply in a
          // single stage and expect to get the data just
          // set. (For example, AxisProxy, x y both call
          // getData and setDate sequentially).
          // So the context.data should be fetched from
          // upstream each time when a stage starts to be
          // performed.

          if (task !== this.dataTask) {
            context.data = data;
          }
        }

        inner$1(this).data = data;
      };

      SeriesModel.prototype.getEncode = function () {
        var encode = this.get('encode', true);

        if (encode) {
          return createHashMap(encode);
        }
      };

      SeriesModel.prototype.getSourceManager = function () {
        return inner$1(this).sourceManager;
      };

      SeriesModel.prototype.getSource = function () {
        return this.getSourceManager().getSource();
      };
      /**
       * Get data before processed
       */


      SeriesModel.prototype.getRawData = function () {
        return inner$1(this).dataBeforeProcessed;
      };

      SeriesModel.prototype.getColorBy = function () {
        var colorBy = this.get('colorBy');
        return colorBy || 'series';
      };

      SeriesModel.prototype.isColorBySeries = function () {
        return this.getColorBy() === 'series';
      };
      /**
       * Get base axis if has coordinate system and has axis.
       * By default use coordSys.getBaseAxis();
       * Can be overridden for some chart.
       * @return {type} description
       */


      SeriesModel.prototype.getBaseAxis = function () {
        var coordSys = this.coordinateSystem; // @ts-ignore

        return coordSys && coordSys.getBaseAxis && coordSys.getBaseAxis();
      };
      /**
       * Default tooltip formatter
       *
       * @param dataIndex
       * @param multipleSeries
       * @param dataType
       * @param renderMode valid values: 'html'(by default) and 'richText'.
       *        'html' is used for rendering tooltip in extra DOM form, and the result
       *        string is used as DOM HTML content.
       *        'richText' is used for rendering tooltip in rich text form, for those where
       *        DOM operation is not supported.
       * @return formatted tooltip with `html` and `markers`
       *        Notice: The override method can also return string
       */


      SeriesModel.prototype.formatTooltip = function (dataIndex, multipleSeries, dataType) {
        return defaultSeriesFormatTooltip({
          series: this,
          dataIndex: dataIndex,
          multipleSeries: multipleSeries
        });
      };

      SeriesModel.prototype.isAnimationEnabled = function () {
        var ecModel = this.ecModel; // Disable animation if using echarts in node but not give ssr flag.
        // In ssr mode, renderToString will generate svg with css animation.

        if (env.node && !(ecModel && ecModel.ssr)) {
          return false;
        }

        var animationEnabled = this.getShallow('animation');

        if (animationEnabled) {
          if (this.getData().count() > this.getShallow('animationThreshold')) {
            animationEnabled = false;
          }
        }

        return !!animationEnabled;
      };

      SeriesModel.prototype.restoreData = function () {
        this.dataTask.dirty();
      };

      SeriesModel.prototype.getColorFromPalette = function (name, scope, requestColorNum) {
        var ecModel = this.ecModel; // PENDING

        var color = PaletteMixin.prototype.getColorFromPalette.call(this, name, scope, requestColorNum);

        if (!color) {
          color = ecModel.getColorFromPalette(name, scope, requestColorNum);
        }

        return color;
      };
      /**
       * Use `data.mapDimensionsAll(coordDim)` instead.
       * @deprecated
       */


      SeriesModel.prototype.coordDimToDataDim = function (coordDim) {
        return this.getRawData().mapDimensionsAll(coordDim);
      };
      /**
       * Get progressive rendering count each step
       */


      SeriesModel.prototype.getProgressive = function () {
        return this.get('progressive');
      };
      /**
       * Get progressive rendering count each step
       */


      SeriesModel.prototype.getProgressiveThreshold = function () {
        return this.get('progressiveThreshold');
      }; // PENGING If selectedMode is null ?


      SeriesModel.prototype.select = function (innerDataIndices, dataType) {
        this._innerSelect(this.getData(dataType), innerDataIndices);
      };

      SeriesModel.prototype.unselect = function (innerDataIndices, dataType) {
        var selectedMap = this.option.selectedMap;

        if (!selectedMap) {
          return;
        }

        var selectedMode = this.option.selectedMode;
        var data = this.getData(dataType);

        if (selectedMode === 'series' || selectedMap === 'all') {
          this.option.selectedMap = {};
          this._selectedDataIndicesMap = {};
          return;
        }

        for (var i = 0; i < innerDataIndices.length; i++) {
          var dataIndex = innerDataIndices[i];
          var nameOrId = getSelectionKey(data, dataIndex);
          selectedMap[nameOrId] = false;
          this._selectedDataIndicesMap[nameOrId] = -1;
        }
      };

      SeriesModel.prototype.toggleSelect = function (innerDataIndices, dataType) {
        var tmpArr = [];

        for (var i = 0; i < innerDataIndices.length; i++) {
          tmpArr[0] = innerDataIndices[i];
          this.isSelected(innerDataIndices[i], dataType) ? this.unselect(tmpArr, dataType) : this.select(tmpArr, dataType);
        }
      };

      SeriesModel.prototype.getSelectedDataIndices = function () {
        if (this.option.selectedMap === 'all') {
          return [].slice.call(this.getData().getIndices());
        }

        var selectedDataIndicesMap = this._selectedDataIndicesMap;
        var nameOrIds = keys(selectedDataIndicesMap);
        var dataIndices = [];

        for (var i = 0; i < nameOrIds.length; i++) {
          var dataIndex = selectedDataIndicesMap[nameOrIds[i]];

          if (dataIndex >= 0) {
            dataIndices.push(dataIndex);
          }
        }

        return dataIndices;
      };

      SeriesModel.prototype.isSelected = function (dataIndex, dataType) {
        var selectedMap = this.option.selectedMap;

        if (!selectedMap) {
          return false;
        }

        var data = this.getData(dataType);
        return (selectedMap === 'all' || selectedMap[getSelectionKey(data, dataIndex)]) && !data.getItemModel(dataIndex).get(['select', 'disabled']);
      };

      SeriesModel.prototype.isUniversalTransitionEnabled = function () {
        if (this[SERIES_UNIVERSAL_TRANSITION_PROP]) {
          return true;
        }

        var universalTransitionOpt = this.option.universalTransition; // Quick reject

        if (!universalTransitionOpt) {
          return false;
        }

        if (universalTransitionOpt === true) {
          return true;
        } // Can be simply 'universalTransition: true'


        return universalTransitionOpt && universalTransitionOpt.enabled;
      };

      SeriesModel.prototype._innerSelect = function (data, innerDataIndices) {
        var _a, _b;

        var option = this.option;
        var selectedMode = option.selectedMode;
        var len = innerDataIndices.length;

        if (!selectedMode || !len) {
          return;
        }

        if (selectedMode === 'series') {
          option.selectedMap = 'all';
        } else if (selectedMode === 'multiple') {
          if (!isObject(option.selectedMap)) {
            option.selectedMap = {};
          }

          var selectedMap = option.selectedMap;

          for (var i = 0; i < len; i++) {
            var dataIndex = innerDataIndices[i]; // TODO different types of data share same object.

            var nameOrId = getSelectionKey(data, dataIndex);
            selectedMap[nameOrId] = true;
            this._selectedDataIndicesMap[nameOrId] = data.getRawIndex(dataIndex);
          }
        } else if (selectedMode === 'single' || selectedMode === true) {
          var lastDataIndex = innerDataIndices[len - 1];
          var nameOrId = getSelectionKey(data, lastDataIndex);
          option.selectedMap = (_a = {}, _a[nameOrId] = true, _a);
          this._selectedDataIndicesMap = (_b = {}, _b[nameOrId] = data.getRawIndex(lastDataIndex), _b);
        }
      };

      SeriesModel.prototype._initSelectedMapFromData = function (data) {
        // Ignore select info in data if selectedMap exists.
        // NOTE It's only for legacy usage. edge data is not supported.
        if (this.option.selectedMap) {
          return;
        }

        var dataIndices = [];

        if (data.hasItemOption) {
          data.each(function (idx) {
            var rawItem = data.getRawDataItem(idx);

            if (rawItem && rawItem.selected) {
              dataIndices.push(idx);
            }
          });
        }

        if (dataIndices.length > 0) {
          this._innerSelect(data, dataIndices);
        }
      }; // /**
      //  * @see {module:echarts/stream/Scheduler}
      //  */
      // abstract pipeTask: null


      SeriesModel.registerClass = function (clz) {
        return ComponentModel.registerClass(clz);
      };

      SeriesModel.protoInitialize = function () {
        var proto = SeriesModel.prototype;
        proto.type = 'series.__base__';
        proto.seriesIndex = 0;
        proto.ignoreStyleOnData = false;
        proto.hasSymbolVisual = false;
        proto.defaultSymbol = 'circle'; // Make sure the values can be accessed!

        proto.visualStyleAccessPath = 'itemStyle';
        proto.visualDrawType = 'fill';
      }();

      return SeriesModel;
    }(ComponentModel);

    mixin(SeriesModel, DataFormatMixin);
    mixin(SeriesModel, PaletteMixin);
    mountExtend(SeriesModel, ComponentModel);
    /**
     * MUST be called after `prepareSource` called
     * Here we need to make auto series, especially for auto legend. But we
     * do not modify series.name in option to avoid side effects.
     */

    function autoSeriesName(seriesModel) {
      // User specified name has higher priority, otherwise it may cause
      // series can not be queried unexpectedly.
      var name = seriesModel.name;

      if (!isNameSpecified(seriesModel)) {
        seriesModel.name = getSeriesAutoName(seriesModel) || name;
      }
    }

    function getSeriesAutoName(seriesModel) {
      var data = seriesModel.getRawData();
      var dataDims = data.mapDimensionsAll('seriesName');
      var nameArr = [];
      each(dataDims, function (dataDim) {
        var dimInfo = data.getDimensionInfo(dataDim);
        dimInfo.displayName && nameArr.push(dimInfo.displayName);
      });
      return nameArr.join(' ');
    }

    function dataTaskCount(context) {
      return context.model.getRawData().count();
    }

    function dataTaskReset(context) {
      var seriesModel = context.model;
      seriesModel.setData(seriesModel.getRawData().cloneShallow());
      return dataTaskProgress;
    }

    function dataTaskProgress(param, context) {
      // Avoid repead cloneShallow when data just created in reset.
      if (context.outputData && param.end > context.outputData.count()) {
        context.model.getRawData().cloneShallow(context.outputData);
      }
    } // TODO refactor


    function wrapData(data, seriesModel) {
      each(concatArray(data.CHANGABLE_METHODS, data.DOWNSAMPLE_METHODS), function (methodName) {
        data.wrapMethod(methodName, curry(onDataChange, seriesModel));
      });
    }

    function onDataChange(seriesModel, newList) {
      var task = getCurrentTask(seriesModel);

      if (task) {
        // Consider case: filter, selectRange
        task.setOutputEnd((newList || this).count());
      }

      return newList;
    }

    function getCurrentTask(seriesModel) {
      var scheduler = (seriesModel.ecModel || {}).scheduler;
      var pipeline = scheduler && scheduler.getPipeline(seriesModel.uid);

      if (pipeline) {
        // When pipline finished, the currrentTask keep the last
        // task (renderTask).
        var task = pipeline.currentTask;

        if (task) {
          var agentStubMap = task.agentStubMap;

          if (agentStubMap) {
            task = agentStubMap.get(seriesModel.uid);
          }
        }

        return task;
      }
    }

    var ComponentView =
    /** @class */
    function () {
      function ComponentView() {
        this.group = new Group();
        this.uid = getUID('viewComponent');
      }

      ComponentView.prototype.init = function (ecModel, api) {};

      ComponentView.prototype.render = function (model, ecModel, api, payload) {};

      ComponentView.prototype.dispose = function (ecModel, api) {};

      ComponentView.prototype.updateView = function (model, ecModel, api, payload) {// Do nothing;
      };

      ComponentView.prototype.updateLayout = function (model, ecModel, api, payload) {// Do nothing;
      };

      ComponentView.prototype.updateVisual = function (model, ecModel, api, payload) {// Do nothing;
      };
      /**
       * Hook for toggle blur target series.
       * Can be used in marker for blur or leave blur the markers
       */


      ComponentView.prototype.toggleBlurSeries = function (seriesModels, isBlur, ecModel) {// Do nothing;
      };
      /**
       * Traverse the new rendered elements.
       *
       * It will traverse the new added element in progressive rendering.
       * And traverse all in normal rendering.
       */


      ComponentView.prototype.eachRendered = function (cb) {
        var group = this.group;

        if (group) {
          group.traverse(cb);
        }
      };

      return ComponentView;
    }();
    enableClassExtend(ComponentView);
    enableClassManagement(ComponentView);

    /**
     * @return {string} If large mode changed, return string 'reset';
     */

    function createRenderPlanner() {
      var inner = makeInner();
      return function (seriesModel) {
        var fields = inner(seriesModel);
        var pipelineContext = seriesModel.pipelineContext;
        var originalLarge = !!fields.large;
        var originalProgressive = !!fields.progressiveRender; // FIXME: if the planner works on a filtered series, `pipelineContext` does not
        // exists. See #11611 . Probably we need to modify this structure, see the comment
        // on `performRawSeries` in `Schedular.js`.

        var large = fields.large = !!(pipelineContext && pipelineContext.large);
        var progressive = fields.progressiveRender = !!(pipelineContext && pipelineContext.progressiveRender);
        return !!(originalLarge !== large || originalProgressive !== progressive) && 'reset';
      };
    }

    var inner$2 = makeInner();
    var renderPlanner = createRenderPlanner();

    var ChartView =
    /** @class */
    function () {
      function ChartView() {
        this.group = new Group();
        this.uid = getUID('viewChart');
        this.renderTask = createTask({
          plan: renderTaskPlan,
          reset: renderTaskReset
        });
        this.renderTask.context = {
          view: this
        };
      }

      ChartView.prototype.init = function (ecModel, api) {};

      ChartView.prototype.render = function (seriesModel, ecModel, api, payload) {
        if ("development" !== 'production') {
          throw new Error('render method must been implemented');
        }
      };
      /**
       * Highlight series or specified data item.
       */


      ChartView.prototype.highlight = function (seriesModel, ecModel, api, payload) {
        var data = seriesModel.getData(payload && payload.dataType);

        if (!data) {
          if ("development" !== 'production') {
            error("Unknown dataType " + payload.dataType);
          }

          return;
        }

        toggleHighlight(data, payload, 'emphasis');
      };
      /**
       * Downplay series or specified data item.
       */


      ChartView.prototype.downplay = function (seriesModel, ecModel, api, payload) {
        var data = seriesModel.getData(payload && payload.dataType);

        if (!data) {
          if ("development" !== 'production') {
            error("Unknown dataType " + payload.dataType);
          }

          return;
        }

        toggleHighlight(data, payload, 'normal');
      };
      /**
       * Remove self.
       */


      ChartView.prototype.remove = function (ecModel, api) {
        this.group.removeAll();
      };
      /**
       * Dispose self.
       */


      ChartView.prototype.dispose = function (ecModel, api) {};

      ChartView.prototype.updateView = function (seriesModel, ecModel, api, payload) {
        this.render(seriesModel, ecModel, api, payload);
      }; // FIXME never used?


      ChartView.prototype.updateLayout = function (seriesModel, ecModel, api, payload) {
        this.render(seriesModel, ecModel, api, payload);
      }; // FIXME never used?


      ChartView.prototype.updateVisual = function (seriesModel, ecModel, api, payload) {
        this.render(seriesModel, ecModel, api, payload);
      };
      /**
       * Traverse the new rendered elements.
       *
       * It will traverse the new added element in progressive rendering.
       * And traverse all in normal rendering.
       */


      ChartView.prototype.eachRendered = function (cb) {
        traverseElements(this.group, cb);
      };

      ChartView.markUpdateMethod = function (payload, methodName) {
        inner$2(payload).updateMethod = methodName;
      };

      ChartView.protoInitialize = function () {
        var proto = ChartView.prototype;
        proto.type = 'chart';
      }();

      return ChartView;
    }();
    /**
     * Set state of single element
     */

    function elSetState(el, state, highlightDigit) {
      if (el && isHighDownDispatcher(el)) {
        (state === 'emphasis' ? enterEmphasis : leaveEmphasis)(el, highlightDigit);
      }
    }

    function toggleHighlight(data, payload, state) {
      var dataIndex = queryDataIndex(data, payload);
      var highlightDigit = payload && payload.highlightKey != null ? getHighlightDigit(payload.highlightKey) : null;

      if (dataIndex != null) {
        each(normalizeToArray(dataIndex), function (dataIdx) {
          elSetState(data.getItemGraphicEl(dataIdx), state, highlightDigit);
        });
      } else {
        data.eachItemGraphicEl(function (el) {
          elSetState(el, state, highlightDigit);
        });
      }
    }

    enableClassExtend(ChartView, ['dispose']);
    enableClassManagement(ChartView);

    function renderTaskPlan(context) {
      return renderPlanner(context.model);
    }

    function renderTaskReset(context) {
      var seriesModel = context.model;
      var ecModel = context.ecModel;
      var api = context.api;
      var payload = context.payload; // FIXME: remove updateView updateVisual

      var progressiveRender = seriesModel.pipelineContext.progressiveRender;
      var view = context.view;
      var updateMethod = payload && inner$2(payload).updateMethod;
      var methodName = progressiveRender ? 'incrementalPrepareRender' : updateMethod && view[updateMethod] ? updateMethod // `appendData` is also supported when data amount
      // is less than progressive threshold.
      : 'render';

      if (methodName !== 'render') {
        view[methodName](seriesModel, ecModel, api, payload);
      }

      return progressMethodMap[methodName];
    }

    var progressMethodMap = {
      incrementalPrepareRender: {
        progress: function (params, context) {
          context.view.incrementalRender(params, context.model, context.ecModel, context.api, context.payload);
        }
      },
      render: {
        // Put view.render in `progress` to support appendData. But in this case
        // view.render should not be called in reset, otherwise it will be called
        // twise. Use `forceFirstProgress` to make sure that view.render is called
        // in any cases.
        forceFirstProgress: true,
        progress: function (params, context) {
          context.view.render(context.model, context.ecModel, context.api, context.payload);
        }
      }
    };

    /**
     * @public
     * @param {(Function)} fn
     * @param {number} [delay=0] Unit: ms.
     * @param {boolean} [debounce=false]
     *        true: If call interval less than `delay`, only the last call works.
     *        false: If call interval less than `delay, call works on fixed rate.
     * @return {(Function)} throttled fn.
     */

    function throttle(fn, delay, debounce) {
      var currCall;
      var lastCall = 0;
      var lastExec = 0;
      var timer = null;
      var diff;
      var scope;
      var args;
      var debounceNextCall;
      delay = delay || 0;

      function exec() {
        lastExec = new Date().getTime();
        timer = null;
        fn.apply(scope, args || []);
      }

      var cb = function () {
        var cbArgs = [];

        for (var _i = 0; _i < arguments.length; _i++) {
          cbArgs[_i] = arguments[_i];
        }

        currCall = new Date().getTime();
        scope = this;
        args = cbArgs;
        var thisDelay = debounceNextCall || delay;
        var thisDebounce = debounceNextCall || debounce;
        debounceNextCall = null;
        diff = currCall - (thisDebounce ? lastCall : lastExec) - thisDelay;
        clearTimeout(timer); // Here we should make sure that: the `exec` SHOULD NOT be called later
        // than a new call of `cb`, that is, preserving the command order. Consider
        // calculating "scale rate" when roaming as an example. When a call of `cb`
        // happens, either the `exec` is called dierectly, or the call is delayed.
        // But the delayed call should never be later than next call of `cb`. Under
        // this assurance, we can simply update view state each time `dispatchAction`
        // triggered by user roaming, but not need to add extra code to avoid the
        // state being "rolled-back".

        if (thisDebounce) {
          timer = setTimeout(exec, thisDelay);
        } else {
          if (diff >= 0) {
            exec();
          } else {
            timer = setTimeout(exec, -diff);
          }
        }

        lastCall = currCall;
      };
      /**
       * Clear throttle.
       * @public
       */


      cb.clear = function () {
        if (timer) {
          clearTimeout(timer);
          timer = null;
        }
      };
      /**
       * Enable debounce once.
       */


      cb.debounceNextCall = function (debounceDelay) {
        debounceNextCall = debounceDelay;
      };

      return cb;
    }

    var inner$3 = makeInner();
    var defaultStyleMappers = {
      itemStyle: makeStyleMapper(ITEM_STYLE_KEY_MAP, true),
      lineStyle: makeStyleMapper(LINE_STYLE_KEY_MAP, true)
    };
    var defaultColorKey = {
      lineStyle: 'stroke',
      itemStyle: 'fill'
    };

    function getStyleMapper(seriesModel, stylePath) {
      var styleMapper = seriesModel.visualStyleMapper || defaultStyleMappers[stylePath];

      if (!styleMapper) {
        console.warn("Unknown style type '" + stylePath + "'.");
        return defaultStyleMappers.itemStyle;
      }

      return styleMapper;
    }

    function getDefaultColorKey(seriesModel, stylePath) {
      // return defaultColorKey[stylePath] ||
      var colorKey = seriesModel.visualDrawType || defaultColorKey[stylePath];

      if (!colorKey) {
        console.warn("Unknown style type '" + stylePath + "'.");
        return 'fill';
      }

      return colorKey;
    }

    var seriesStyleTask = {
      createOnAllSeries: true,
      performRawSeries: true,
      reset: function (seriesModel, ecModel) {
        var data = seriesModel.getData();
        var stylePath = seriesModel.visualStyleAccessPath || 'itemStyle'; // Set in itemStyle

        var styleModel = seriesModel.getModel(stylePath);
        var getStyle = getStyleMapper(seriesModel, stylePath);
        var globalStyle = getStyle(styleModel);
        var decalOption = styleModel.getShallow('decal');

        if (decalOption) {
          data.setVisual('decal', decalOption);
          decalOption.dirty = true;
        } // TODO


        var colorKey = getDefaultColorKey(seriesModel, stylePath);
        var color = globalStyle[colorKey]; // TODO style callback

        var colorCallback = isFunction(color) ? color : null;
        var hasAutoColor = globalStyle.fill === 'auto' || globalStyle.stroke === 'auto'; // Get from color palette by default.

        if (!globalStyle[colorKey] || colorCallback || hasAutoColor) {
          // Note: If some series has color specified (e.g., by itemStyle.color), we DO NOT
          // make it effect palette. Because some scenarios users need to make some series
          // transparent or as background, which should better not effect the palette.
          var colorPalette = seriesModel.getColorFromPalette( // TODO series count changed.
          seriesModel.name, null, ecModel.getSeriesCount());

          if (!globalStyle[colorKey]) {
            globalStyle[colorKey] = colorPalette;
            data.setVisual('colorFromPalette', true);
          }

          globalStyle.fill = globalStyle.fill === 'auto' || isFunction(globalStyle.fill) ? colorPalette : globalStyle.fill;
          globalStyle.stroke = globalStyle.stroke === 'auto' || isFunction(globalStyle.stroke) ? colorPalette : globalStyle.stroke;
        }

        data.setVisual('style', globalStyle);
        data.setVisual('drawType', colorKey); // Only visible series has each data be visual encoded

        if (!ecModel.isSeriesFiltered(seriesModel) && colorCallback) {
          data.setVisual('colorFromPalette', false);
          return {
            dataEach: function (data, idx) {
              var dataParams = seriesModel.getDataParams(idx);
              var itemStyle = extend({}, globalStyle);
              itemStyle[colorKey] = colorCallback(dataParams);
              data.setItemVisual(idx, 'style', itemStyle);
            }
          };
        }
      }
    };
    var sharedModel = new Model();
    var dataStyleTask = {
      createOnAllSeries: true,
      performRawSeries: true,
      reset: function (seriesModel, ecModel) {
        if (seriesModel.ignoreStyleOnData || ecModel.isSeriesFiltered(seriesModel)) {
          return;
        }

        var data = seriesModel.getData();
        var stylePath = seriesModel.visualStyleAccessPath || 'itemStyle'; // Set in itemStyle

        var getStyle = getStyleMapper(seriesModel, stylePath);
        var colorKey = data.getVisual('drawType');
        return {
          dataEach: data.hasItemOption ? function (data, idx) {
            // Not use getItemModel for performance considuration
            var rawItem = data.getRawDataItem(idx);

            if (rawItem && rawItem[stylePath]) {
              sharedModel.option = rawItem[stylePath];
              var style = getStyle(sharedModel);
              var existsStyle = data.ensureUniqueItemVisual(idx, 'style');
              extend(existsStyle, style);

              if (sharedModel.option.decal) {
                data.setItemVisual(idx, 'decal', sharedModel.option.decal);
                sharedModel.option.decal.dirty = true;
              }

              if (colorKey in style) {
                data.setItemVisual(idx, 'colorFromPalette', false);
              }
            }
          } : null
        };
      }
    }; // Pick color from palette for the data which has not been set with color yet.
    // Note: do not support stream rendering. No such cases yet.

    var dataColorPaletteTask = {
      performRawSeries: true,
      overallReset: function (ecModel) {
        // Each type of series uses one scope.
        // Pie and funnel are using different scopes.
        var paletteScopeGroupByType = createHashMap();
        ecModel.eachSeries(function (seriesModel) {
          var colorBy = seriesModel.getColorBy();

          if (seriesModel.isColorBySeries()) {
            return;
          }

          var key = seriesModel.type + '-' + colorBy;
          var colorScope = paletteScopeGroupByType.get(key);

          if (!colorScope) {
            colorScope = {};
            paletteScopeGroupByType.set(key, colorScope);
          }

          inner$3(seriesModel).scope = colorScope;
        });
        ecModel.eachSeries(function (seriesModel) {
          if (seriesModel.isColorBySeries() || ecModel.isSeriesFiltered(seriesModel)) {
            return;
          }

          var dataAll = seriesModel.getRawData();
          var idxMap = {};
          var data = seriesModel.getData();
          var colorScope = inner$3(seriesModel).scope;
          var stylePath = seriesModel.visualStyleAccessPath || 'itemStyle';
          var colorKey = getDefaultColorKey(seriesModel, stylePath);
          data.each(function (idx) {
            var rawIdx = data.getRawIndex(idx);
            idxMap[rawIdx] = idx;
          }); // Iterate on data before filtered. To make sure color from palette can be
          // Consistent when toggling legend.

          dataAll.each(function (rawIdx) {
            var idx = idxMap[rawIdx];
            var fromPalette = data.getItemVisual(idx, 'colorFromPalette'); // Get color from palette for each data only when the color is inherited from series color, which is
            // also picked from color palette. So following situation is not in the case:
            // 1. series.itemStyle.color is set
            // 2. color is encoded by visualMap

            if (fromPalette) {
              var itemStyle = data.ensureUniqueItemVisual(idx, 'style');
              var name_1 = dataAll.getName(rawIdx) || rawIdx + '';
              var dataCount = dataAll.count();
              itemStyle[colorKey] = seriesModel.getColorFromPalette(name_1, colorScope, dataCount);
            }
          });
        });
      }
    };

    var PI$3 = Math.PI;
    /**
     * @param {module:echarts/ExtensionAPI} api
     * @param {Object} [opts]
     * @param {string} [opts.text]
     * @param {string} [opts.color]
     * @param {string} [opts.textColor]
     * @return {module:zrender/Element}
     */

    function defaultLoading(api, opts) {
      opts = opts || {};
      defaults(opts, {
        text: 'loading',
        textColor: '#000',
        fontSize: 12,
        fontWeight: 'normal',
        fontStyle: 'normal',
        fontFamily: 'sans-serif',
        maskColor: 'rgba(255, 255, 255, 0.8)',
        showSpinner: true,
        color: '#5470c6',
        spinnerRadius: 10,
        lineWidth: 5,
        zlevel: 0
      });
      var group = new Group();
      var mask = new Rect({
        style: {
          fill: opts.maskColor
        },
        zlevel: opts.zlevel,
        z: 10000
      });
      group.add(mask);
      var textContent = new ZRText({
        style: {
          text: opts.text,
          fill: opts.textColor,
          fontSize: opts.fontSize,
          fontWeight: opts.fontWeight,
          fontStyle: opts.fontStyle,
          fontFamily: opts.fontFamily
        },
        zlevel: opts.zlevel,
        z: 10001
      });
      var labelRect = new Rect({
        style: {
          fill: 'none'
        },
        textContent: textContent,
        textConfig: {
          position: 'right',
          distance: 10
        },
        zlevel: opts.zlevel,
        z: 10001
      });
      group.add(labelRect);
      var arc;

      if (opts.showSpinner) {
        arc = new Arc({
          shape: {
            startAngle: -PI$3 / 2,
            endAngle: -PI$3 / 2 + 0.1,
            r: opts.spinnerRadius
          },
          style: {
            stroke: opts.color,
            lineCap: 'round',
            lineWidth: opts.lineWidth
          },
          zlevel: opts.zlevel,
          z: 10001
        });
        arc.animateShape(true).when(1000, {
          endAngle: PI$3 * 3 / 2
        }).start('circularInOut');
        arc.animateShape(true).when(1000, {
          startAngle: PI$3 * 3 / 2
        }).delay(300).start('circularInOut');
        group.add(arc);
      } // Inject resize


      group.resize = function () {
        var textWidth = textContent.getBoundingRect().width;
        var r = opts.showSpinner ? opts.spinnerRadius : 0; // cx = (containerWidth - arcDiameter - textDistance - textWidth) / 2
        // textDistance needs to be calculated when both animation and text exist

        var cx = (api.getWidth() - r * 2 - (opts.showSpinner && textWidth ? 10 : 0) - textWidth) / 2 - (opts.showSpinner && textWidth ? 0 : 5 + textWidth / 2) // only show the text
        + (opts.showSpinner ? 0 : textWidth / 2) // only show the spinner
        + (textWidth ? 0 : r);
        var cy = api.getHeight() / 2;
        opts.showSpinner && arc.setShape({
          cx: cx,
          cy: cy
        });
        labelRect.setShape({
          x: cx - r,
          y: cy - r,
          width: r * 2,
          height: r * 2
        });
        mask.setShape({
          x: 0,
          y: 0,
          width: api.getWidth(),
          height: api.getHeight()
        });
      };

      group.resize();
      return group;
    }

    var Scheduler =
    /** @class */
    function () {
      function Scheduler(ecInstance, api, dataProcessorHandlers, visualHandlers) {
        // key: handlerUID
        this._stageTaskMap = createHashMap();
        this.ecInstance = ecInstance;
        this.api = api; // Fix current processors in case that in some rear cases that
        // processors might be registered after echarts instance created.
        // Register processors incrementally for a echarts instance is
        // not supported by this stream architecture.

        dataProcessorHandlers = this._dataProcessorHandlers = dataProcessorHandlers.slice();
        visualHandlers = this._visualHandlers = visualHandlers.slice();
        this._allHandlers = dataProcessorHandlers.concat(visualHandlers);
      }

      Scheduler.prototype.restoreData = function (ecModel, payload) {
        // TODO: Only restore needed series and components, but not all components.
        // Currently `restoreData` of all of the series and component will be called.
        // But some independent components like `title`, `legend`, `graphic`, `toolbox`,
        // `tooltip`, `axisPointer`, etc, do not need series refresh when `setOption`,
        // and some components like coordinate system, axes, dataZoom, visualMap only
        // need their target series refresh.
        // (1) If we are implementing this feature some day, we should consider these cases:
        // if a data processor depends on a component (e.g., dataZoomProcessor depends
        // on the settings of `dataZoom`), it should be re-performed if the component
        // is modified by `setOption`.
        // (2) If a processor depends on sevral series, speicified by its `getTargetSeries`,
        // it should be re-performed when the result array of `getTargetSeries` changed.
        // We use `dependencies` to cover these issues.
        // (3) How to update target series when coordinate system related components modified.
        // TODO: simply the dirty mechanism? Check whether only the case here can set tasks dirty,
        // and this case all of the tasks will be set as dirty.
        ecModel.restoreData(payload); // Theoretically an overall task not only depends on each of its target series, but also
        // depends on all of the series.
        // The overall task is not in pipeline, and `ecModel.restoreData` only set pipeline tasks
        // dirty. If `getTargetSeries` of an overall task returns nothing, we should also ensure
        // that the overall task is set as dirty and to be performed, otherwise it probably cause
        // state chaos. So we have to set dirty of all of the overall tasks manually, otherwise it
        // probably cause state chaos (consider `dataZoomProcessor`).

        this._stageTaskMap.each(function (taskRecord) {
          var overallTask = taskRecord.overallTask;
          overallTask && overallTask.dirty();
        });
      }; // If seriesModel provided, incremental threshold is check by series data.


      Scheduler.prototype.getPerformArgs = function (task, isBlock) {
        // For overall task
        if (!task.__pipeline) {
          return;
        }

        var pipeline = this._pipelineMap.get(task.__pipeline.id);

        var pCtx = pipeline.context;
        var incremental = !isBlock && pipeline.progressiveEnabled && (!pCtx || pCtx.progressiveRender) && task.__idxInPipeline > pipeline.blockIndex;
        var step = incremental ? pipeline.step : null;
        var modDataCount = pCtx && pCtx.modDataCount;
        var modBy = modDataCount != null ? Math.ceil(modDataCount / step) : null;
        return {
          step: step,
          modBy: modBy,
          modDataCount: modDataCount
        };
      };

      Scheduler.prototype.getPipeline = function (pipelineId) {
        return this._pipelineMap.get(pipelineId);
      };
      /**
       * Current, progressive rendering starts from visual and layout.
       * Always detect render mode in the same stage, avoiding that incorrect
       * detection caused by data filtering.
       * Caution:
       * `updateStreamModes` use `seriesModel.getData()`.
       */


      Scheduler.prototype.updateStreamModes = function (seriesModel, view) {
        var pipeline = this._pipelineMap.get(seriesModel.uid);

        var data = seriesModel.getData();
        var dataLen = data.count(); // `progressiveRender` means that can render progressively in each
        // animation frame. Note that some types of series do not provide
        // `view.incrementalPrepareRender` but support `chart.appendData`. We
        // use the term `incremental` but not `progressive` to describe the
        // case that `chart.appendData`.

        var progressiveRender = pipeline.progressiveEnabled && view.incrementalPrepareRender && dataLen >= pipeline.threshold;
        var large = seriesModel.get('large') && dataLen >= seriesModel.get('largeThreshold'); // TODO: modDataCount should not updated if `appendData`, otherwise cause whole repaint.
        // see `test/candlestick-large3.html`

        var modDataCount = seriesModel.get('progressiveChunkMode') === 'mod' ? dataLen : null;
        seriesModel.pipelineContext = pipeline.context = {
          progressiveRender: progressiveRender,
          modDataCount: modDataCount,
          large: large
        };
      };

      Scheduler.prototype.restorePipelines = function (ecModel) {
        var scheduler = this;
        var pipelineMap = scheduler._pipelineMap = createHashMap();
        ecModel.eachSeries(function (seriesModel) {
          var progressive = seriesModel.getProgressive();
          var pipelineId = seriesModel.uid;
          pipelineMap.set(pipelineId, {
            id: pipelineId,
            head: null,
            tail: null,
            threshold: seriesModel.getProgressiveThreshold(),
            progressiveEnabled: progressive && !(seriesModel.preventIncremental && seriesModel.preventIncremental()),
            blockIndex: -1,
            step: Math.round(progressive || 700),
            count: 0
          });

          scheduler._pipe(seriesModel, seriesModel.dataTask);
        });
      };

      Scheduler.prototype.prepareStageTasks = function () {
        var stageTaskMap = this._stageTaskMap;
        var ecModel = this.api.getModel();
        var api = this.api;
        each(this._allHandlers, function (handler) {
          var record = stageTaskMap.get(handler.uid) || stageTaskMap.set(handler.uid, {});
          var errMsg = '';

          if ("development" !== 'production') {
            // Currently do not need to support to sepecify them both.
            errMsg = '"reset" and "overallReset" must not be both specified.';
          }

          assert(!(handler.reset && handler.overallReset), errMsg);
          handler.reset && this._createSeriesStageTask(handler, record, ecModel, api);
          handler.overallReset && this._createOverallStageTask(handler, record, ecModel, api);
        }, this);
      };

      Scheduler.prototype.prepareView = function (view, model, ecModel, api) {
        var renderTask = view.renderTask;
        var context = renderTask.context;
        context.model = model;
        context.ecModel = ecModel;
        context.api = api;
        renderTask.__block = !view.incrementalPrepareRender;

        this._pipe(model, renderTask);
      };

      Scheduler.prototype.performDataProcessorTasks = function (ecModel, payload) {
        // If we do not use `block` here, it should be considered when to update modes.
        this._performStageTasks(this._dataProcessorHandlers, ecModel, payload, {
          block: true
        });
      };

      Scheduler.prototype.performVisualTasks = function (ecModel, payload, opt) {
        this._performStageTasks(this._visualHandlers, ecModel, payload, opt);
      };

      Scheduler.prototype._performStageTasks = function (stageHandlers, ecModel, payload, opt) {
        opt = opt || {};
        var unfinished = false;
        var scheduler = this;
        each(stageHandlers, function (stageHandler, idx) {
          if (opt.visualType && opt.visualType !== stageHandler.visualType) {
            return;
          }

          var stageHandlerRecord = scheduler._stageTaskMap.get(stageHandler.uid);

          var seriesTaskMap = stageHandlerRecord.seriesTaskMap;
          var overallTask = stageHandlerRecord.overallTask;

          if (overallTask) {
            var overallNeedDirty_1;
            var agentStubMap = overallTask.agentStubMap;
            agentStubMap.each(function (stub) {
              if (needSetDirty(opt, stub)) {
                stub.dirty();
                overallNeedDirty_1 = true;
              }
            });
            overallNeedDirty_1 && overallTask.dirty();
            scheduler.updatePayload(overallTask, payload);
            var performArgs_1 = scheduler.getPerformArgs(overallTask, opt.block); // Execute stubs firstly, which may set the overall task dirty,
            // then execute the overall task. And stub will call seriesModel.setData,
            // which ensures that in the overallTask seriesModel.getData() will not
            // return incorrect data.

            agentStubMap.each(function (stub) {
              stub.perform(performArgs_1);
            });

            if (overallTask.perform(performArgs_1)) {
              unfinished = true;
            }
          } else if (seriesTaskMap) {
            seriesTaskMap.each(function (task, pipelineId) {
              if (needSetDirty(opt, task)) {
                task.dirty();
              }

              var performArgs = scheduler.getPerformArgs(task, opt.block); // FIXME
              // if intending to declare `performRawSeries` in handlers, only
              // stream-independent (specifically, data item independent) operations can be
              // performed. Because if a series is filtered, most of the tasks will not
              // be performed. A stream-dependent operation probably cause wrong biz logic.
              // Perhaps we should not provide a separate callback for this case instead
              // of providing the config `performRawSeries`. The stream-dependent operations
              // and stream-independent operations should better not be mixed.

              performArgs.skip = !stageHandler.performRawSeries && ecModel.isSeriesFiltered(task.context.model);
              scheduler.updatePayload(task, payload);

              if (task.perform(performArgs)) {
                unfinished = true;
              }
            });
          }
        });

        function needSetDirty(opt, task) {
          return opt.setDirty && (!opt.dirtyMap || opt.dirtyMap.get(task.__pipeline.id));
        }

        this.unfinished = unfinished || this.unfinished;
      };

      Scheduler.prototype.performSeriesTasks = function (ecModel) {
        var unfinished;
        ecModel.eachSeries(function (seriesModel) {
          // Progress to the end for dataInit and dataRestore.
          unfinished = seriesModel.dataTask.perform() || unfinished;
        });
        this.unfinished = unfinished || this.unfinished;
      };

      Scheduler.prototype.plan = function () {
        // Travel pipelines, check block.
        this._pipelineMap.each(function (pipeline) {
          var task = pipeline.tail;

          do {
            if (task.__block) {
              pipeline.blockIndex = task.__idxInPipeline;
              break;
            }

            task = task.getUpstream();
          } while (task);
        });
      };

      Scheduler.prototype.updatePayload = function (task, payload) {
        payload !== 'remain' && (task.context.payload = payload);
      };

      Scheduler.prototype._createSeriesStageTask = function (stageHandler, stageHandlerRecord, ecModel, api) {
        var scheduler = this;
        var oldSeriesTaskMap = stageHandlerRecord.seriesTaskMap; // The count of stages are totally about only several dozen, so
        // do not need to reuse the map.

        var newSeriesTaskMap = stageHandlerRecord.seriesTaskMap = createHashMap();
        var seriesType = stageHandler.seriesType;
        var getTargetSeries = stageHandler.getTargetSeries; // If a stageHandler should cover all series, `createOnAllSeries` should be declared mandatorily,
        // to avoid some typo or abuse. Otherwise if an extension do not specify a `seriesType`,
        // it works but it may cause other irrelevant charts blocked.

        if (stageHandler.createOnAllSeries) {
          ecModel.eachRawSeries(create);
        } else if (seriesType) {
          ecModel.eachRawSeriesByType(seriesType, create);
        } else if (getTargetSeries) {
          getTargetSeries(ecModel, api).each(create);
        }

        function create(seriesModel) {
          var pipelineId = seriesModel.uid; // Init tasks for each seriesModel only once.
          // Reuse original task instance.

          var task = newSeriesTaskMap.set(pipelineId, oldSeriesTaskMap && oldSeriesTaskMap.get(pipelineId) || createTask({
            plan: seriesTaskPlan,
            reset: seriesTaskReset,
            count: seriesTaskCount
          }));
          task.context = {
            model: seriesModel,
            ecModel: ecModel,
            api: api,
            // PENDING: `useClearVisual` not used?
            useClearVisual: stageHandler.isVisual && !stageHandler.isLayout,
            plan: stageHandler.plan,
            reset: stageHandler.reset,
            scheduler: scheduler
          };

          scheduler._pipe(seriesModel, task);
        }
      };

      Scheduler.prototype._createOverallStageTask = function (stageHandler, stageHandlerRecord, ecModel, api) {
        var scheduler = this;
        var overallTask = stageHandlerRecord.overallTask = stageHandlerRecord.overallTask // For overall task, the function only be called on reset stage.
        || createTask({
          reset: overallTaskReset
        });
        overallTask.context = {
          ecModel: ecModel,
          api: api,
          overallReset: stageHandler.overallReset,
          scheduler: scheduler
        };
        var oldAgentStubMap = overallTask.agentStubMap; // The count of stages are totally about only several dozen, so
        // do not need to reuse the map.

        var newAgentStubMap = overallTask.agentStubMap = createHashMap();
        var seriesType = stageHandler.seriesType;
        var getTargetSeries = stageHandler.getTargetSeries;
        var overallProgress = true;
        var shouldOverallTaskDirty = false; // FIXME:TS never used, so comment it
        // let modifyOutputEnd = stageHandler.modifyOutputEnd;
        // An overall task with seriesType detected or has `getTargetSeries`, we add
        // stub in each pipelines, it will set the overall task dirty when the pipeline
        // progress. Moreover, to avoid call the overall task each frame (too frequent),
        // we set the pipeline block.

        var errMsg = '';

        if ("development" !== 'production') {
          errMsg = '"createOnAllSeries" is not supported for "overallReset", ' + 'because it will block all streams.';
        }

        assert(!stageHandler.createOnAllSeries, errMsg);

        if (seriesType) {
          ecModel.eachRawSeriesByType(seriesType, createStub);
        } else if (getTargetSeries) {
          getTargetSeries(ecModel, api).each(createStub);
        } // Otherwise, (usually it is legacy case), the overall task will only be
        // executed when upstream is dirty. Otherwise the progressive rendering of all
        // pipelines will be disabled unexpectedly. But it still needs stubs to receive
        // dirty info from upstream.
        else {
            overallProgress = false;
            each(ecModel.getSeries(), createStub);
          }

        function createStub(seriesModel) {
          var pipelineId = seriesModel.uid;
          var stub = newAgentStubMap.set(pipelineId, oldAgentStubMap && oldAgentStubMap.get(pipelineId) || ( // When the result of `getTargetSeries` changed, the overallTask
          // should be set as dirty and re-performed.
          shouldOverallTaskDirty = true, createTask({
            reset: stubReset,
            onDirty: stubOnDirty
          })));
          stub.context = {
            model: seriesModel,
            overallProgress: overallProgress // FIXME:TS never used, so comment it
            // modifyOutputEnd: modifyOutputEnd

          };
          stub.agent = overallTask;
          stub.__block = overallProgress;

          scheduler._pipe(seriesModel, stub);
        }

        if (shouldOverallTaskDirty) {
          overallTask.dirty();
        }
      };

      Scheduler.prototype._pipe = function (seriesModel, task) {
        var pipelineId = seriesModel.uid;

        var pipeline = this._pipelineMap.get(pipelineId);

        !pipeline.head && (pipeline.head = task);
        pipeline.tail && pipeline.tail.pipe(task);
        pipeline.tail = task;
        task.__idxInPipeline = pipeline.count++;
        task.__pipeline = pipeline;
      };

      Scheduler.wrapStageHandler = function (stageHandler, visualType) {
        if (isFunction(stageHandler)) {
          stageHandler = {
            overallReset: stageHandler,
            seriesType: detectSeriseType(stageHandler)
          };
        }

        stageHandler.uid = getUID('stageHandler');
        visualType && (stageHandler.visualType = visualType);
        return stageHandler;
      };
      return Scheduler;
    }();

    function overallTaskReset(context) {
      context.overallReset(context.ecModel, context.api, context.payload);
    }

    function stubReset(context) {
      return context.overallProgress && stubProgress;
    }

    function stubProgress() {
      this.agent.dirty();
      this.getDownstream().dirty();
    }

    function stubOnDirty() {
      this.agent && this.agent.dirty();
    }

    function seriesTaskPlan(context) {
      return context.plan ? context.plan(context.model, context.ecModel, context.api, context.payload) : null;
    }

    function seriesTaskReset(context) {
      if (context.useClearVisual) {
        context.data.clearAllVisual();
      }

      var resetDefines = context.resetDefines = normalizeToArray(context.reset(context.model, context.ecModel, context.api, context.payload));
      return resetDefines.length > 1 ? map(resetDefines, function (v, idx) {
        return makeSeriesTaskProgress(idx);
      }) : singleSeriesTaskProgress;
    }

    var singleSeriesTaskProgress = makeSeriesTaskProgress(0);

    function makeSeriesTaskProgress(resetDefineIdx) {
      return function (params, context) {
        var data = context.data;
        var resetDefine = context.resetDefines[resetDefineIdx];

        if (resetDefine && resetDefine.dataEach) {
          for (var i = params.start; i < params.end; i++) {
            resetDefine.dataEach(data, i);
          }
        } else if (resetDefine && resetDefine.progress) {
          resetDefine.progress(params, data);
        }
      };
    }

    function seriesTaskCount(context) {
      return context.data.count();
    }
    /**
     * Only some legacy stage handlers (usually in echarts extensions) are pure function.
     * To ensure that they can work normally, they should work in block mode, that is,
     * they should not be started util the previous tasks finished. So they cause the
     * progressive rendering disabled. We try to detect the series type, to narrow down
     * the block range to only the series type they concern, but not all series.
     */


    function detectSeriseType(legacyFunc) {
      seriesType = null;

      try {
        // Assume there is no async when calling `eachSeriesByType`.
        legacyFunc(ecModelMock, apiMock);
      } catch (e) {}

      return seriesType;
    }

    var ecModelMock = {};
    var apiMock = {};
    var seriesType;
    mockMethods(ecModelMock, GlobalModel);
    mockMethods(apiMock, ExtensionAPI);

    ecModelMock.eachSeriesByType = ecModelMock.eachRawSeriesByType = function (type) {
      seriesType = type;
    };

    ecModelMock.eachComponent = function (cond) {
      if (cond.mainType === 'series' && cond.subType) {
        seriesType = cond.subType;
      }
    };

    function mockMethods(target, Clz) {
      /* eslint-disable */
      for (var name_1 in Clz.prototype) {
        // Do not use hasOwnProperty
        target[name_1] = noop;
      }
      /* eslint-enable */

    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    var colorAll = ['#37A2DA', '#32C5E9', '#67E0E3', '#9FE6B8', '#FFDB5C', '#ff9f7f', '#fb7293', '#E062AE', '#E690D1', '#e7bcf3', '#9d96f5', '#8378EA', '#96BFFF'];
    var lightTheme = {
      color: colorAll,
      colorLayer: [['#37A2DA', '#ffd85c', '#fd7b5f'], ['#37A2DA', '#67E0E3', '#FFDB5C', '#ff9f7f', '#E062AE', '#9d96f5'], ['#37A2DA', '#32C5E9', '#9FE6B8', '#FFDB5C', '#ff9f7f', '#fb7293', '#e7bcf3', '#8378EA', '#96BFFF'], colorAll]
    };

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    var contrastColor = '#B9B8CE';
    var backgroundColor = '#100C2A';

    var axisCommon = function () {
      return {
        axisLine: {
          lineStyle: {
            color: contrastColor
          }
        },
        splitLine: {
          lineStyle: {
            color: '#484753'
          }
        },
        splitArea: {
          areaStyle: {
            color: ['rgba(255,255,255,0.02)', 'rgba(255,255,255,0.05)']
          }
        },
        minorSplitLine: {
          lineStyle: {
            color: '#20203B'
          }
        }
      };
    };

    var colorPalette = ['#4992ff', '#7cffb2', '#fddd60', '#ff6e76', '#58d9f9', '#05c091', '#ff8a45', '#8d48e3', '#dd79ff'];
    var theme = {
      darkMode: true,
      color: colorPalette,
      backgroundColor: backgroundColor,
      axisPointer: {
        lineStyle: {
          color: '#817f91'
        },
        crossStyle: {
          color: '#817f91'
        },
        label: {
          // TODO Contrast of label backgorundColor
          color: '#fff'
        }
      },
      legend: {
        textStyle: {
          color: contrastColor
        }
      },
      textStyle: {
        color: contrastColor
      },
      title: {
        textStyle: {
          color: '#EEF1FA'
        },
        subtextStyle: {
          color: '#B9B8CE'
        }
      },
      toolbox: {
        iconStyle: {
          borderColor: contrastColor
        }
      },
      dataZoom: {
        borderColor: '#71708A',
        textStyle: {
          color: contrastColor
        },
        brushStyle: {
          color: 'rgba(135,163,206,0.3)'
        },
        handleStyle: {
          color: '#353450',
          borderColor: '#C5CBE3'
        },
        moveHandleStyle: {
          color: '#B0B6C3',
          opacity: 0.3
        },
        fillerColor: 'rgba(135,163,206,0.2)',
        emphasis: {
          handleStyle: {
            borderColor: '#91B7F2',
            color: '#4D587D'
          },
          moveHandleStyle: {
            color: '#636D9A',
            opacity: 0.7
          }
        },
        dataBackground: {
          lineStyle: {
            color: '#71708A',
            width: 1
          },
          areaStyle: {
            color: '#71708A'
          }
        },
        selectedDataBackground: {
          lineStyle: {
            color: '#87A3CE'
          },
          areaStyle: {
            color: '#87A3CE'
          }
        }
      },
      visualMap: {
        textStyle: {
          color: contrastColor
        }
      },
      timeline: {
        lineStyle: {
          color: contrastColor
        },
        label: {
          color: contrastColor
        },
        controlStyle: {
          color: contrastColor,
          borderColor: contrastColor
        }
      },
      calendar: {
        itemStyle: {
          color: backgroundColor
        },
        dayLabel: {
          color: contrastColor
        },
        monthLabel: {
          color: contrastColor
        },
        yearLabel: {
          color: contrastColor
        }
      },
      timeAxis: axisCommon(),
      logAxis: axisCommon(),
      valueAxis: axisCommon(),
      categoryAxis: axisCommon(),
      line: {
        symbol: 'circle'
      },
      graph: {
        color: colorPalette
      },
      gauge: {
        title: {
          color: contrastColor
        },
        axisLine: {
          lineStyle: {
            color: [[1, 'rgba(207,212,219,0.2)']]
          }
        },
        axisLabel: {
          color: contrastColor
        },
        detail: {
          color: '#EEF1FA'
        }
      },
      candlestick: {
        itemStyle: {
          color: '#f64e56',
          color0: '#54ea92',
          borderColor: '#f64e56',
          borderColor0: '#54ea92' // borderColor: '#ca2824',
          // borderColor0: '#09a443'

        }
      }
    };
    theme.categoryAxis.splitLine.show = false;

    /**
     * Usage of query:
     * `chart.on('click', query, handler);`
     * The `query` can be:
     * + The component type query string, only `mainType` or `mainType.subType`,
     *   like: 'xAxis', 'series', 'xAxis.category' or 'series.line'.
     * + The component query object, like:
     *   `{seriesIndex: 2}`, `{seriesName: 'xx'}`, `{seriesId: 'some'}`,
     *   `{xAxisIndex: 2}`, `{xAxisName: 'xx'}`, `{xAxisId: 'some'}`.
     * + The data query object, like:
     *   `{dataIndex: 123}`, `{dataType: 'link'}`, `{name: 'some'}`.
     * + The other query object (cmponent customized query), like:
     *   `{element: 'some'}` (only available in custom series).
     *
     * Caveat: If a prop in the `query` object is `null/undefined`, it is the
     * same as there is no such prop in the `query` object.
     */

    var ECEventProcessor =
    /** @class */
    function () {
      function ECEventProcessor() {}

      ECEventProcessor.prototype.normalizeQuery = function (query) {
        var cptQuery = {};
        var dataQuery = {};
        var otherQuery = {}; // `query` is `mainType` or `mainType.subType` of component.

        if (isString(query)) {
          var condCptType = parseClassType(query); // `.main` and `.sub` may be ''.

          cptQuery.mainType = condCptType.main || null;
          cptQuery.subType = condCptType.sub || null;
        } // `query` is an object, convert to {mainType, index, name, id}.
        else {
            // `xxxIndex`, `xxxName`, `xxxId`, `name`, `dataIndex`, `dataType` is reserved,
            // can not be used in `compomentModel.filterForExposedEvent`.
            var suffixes_1 = ['Index', 'Name', 'Id'];
            var dataKeys_1 = {
              name: 1,
              dataIndex: 1,
              dataType: 1
            };
            each(query, function (val, key) {
              var reserved = false;

              for (var i = 0; i < suffixes_1.length; i++) {
                var propSuffix = suffixes_1[i];
                var suffixPos = key.lastIndexOf(propSuffix);

                if (suffixPos > 0 && suffixPos === key.length - propSuffix.length) {
                  var mainType = key.slice(0, suffixPos); // Consider `dataIndex`.

                  if (mainType !== 'data') {
                    cptQuery.mainType = mainType;
                    cptQuery[propSuffix.toLowerCase()] = val;
                    reserved = true;
                  }
                }
              }

              if (dataKeys_1.hasOwnProperty(key)) {
                dataQuery[key] = val;
                reserved = true;
              }

              if (!reserved) {
                otherQuery[key] = val;
              }
            });
          }

        return {
          cptQuery: cptQuery,
          dataQuery: dataQuery,
          otherQuery: otherQuery
        };
      };

      ECEventProcessor.prototype.filter = function (eventType, query) {
        // They should be assigned before each trigger call.
        var eventInfo = this.eventInfo;

        if (!eventInfo) {
          return true;
        }

        var targetEl = eventInfo.targetEl;
        var packedEvent = eventInfo.packedEvent;
        var model = eventInfo.model;
        var view = eventInfo.view; // For event like 'globalout'.

        if (!model || !view) {
          return true;
        }

        var cptQuery = query.cptQuery;
        var dataQuery = query.dataQuery;
        return check(cptQuery, model, 'mainType') && check(cptQuery, model, 'subType') && check(cptQuery, model, 'index', 'componentIndex') && check(cptQuery, model, 'name') && check(cptQuery, model, 'id') && check(dataQuery, packedEvent, 'name') && check(dataQuery, packedEvent, 'dataIndex') && check(dataQuery, packedEvent, 'dataType') && (!view.filterForExposedEvent || view.filterForExposedEvent(eventType, query.otherQuery, targetEl, packedEvent));

        function check(query, host, prop, propOnHost) {
          return query[prop] == null || host[propOnHost || prop] === query[prop];
        }
      };

      ECEventProcessor.prototype.afterTrigger = function () {
        // Make sure the eventInfo won't be used in next trigger.
        this.eventInfo = null;
      };

      return ECEventProcessor;
    }();

    var SYMBOL_PROPS_WITH_CB = ['symbol', 'symbolSize', 'symbolRotate', 'symbolOffset'];
    var SYMBOL_PROPS = SYMBOL_PROPS_WITH_CB.concat(['symbolKeepAspect']); // Encoding visual for all series include which is filtered for legend drawing

    var seriesSymbolTask = {
      createOnAllSeries: true,
      // For legend.
      performRawSeries: true,
      reset: function (seriesModel, ecModel) {
        var data = seriesModel.getData();

        if (seriesModel.legendIcon) {
          data.setVisual('legendIcon', seriesModel.legendIcon);
        }

        if (!seriesModel.hasSymbolVisual) {
          return;
        }

        var symbolOptions = {};
        var symbolOptionsCb = {};
        var hasCallback = false;

        for (var i = 0; i < SYMBOL_PROPS_WITH_CB.length; i++) {
          var symbolPropName = SYMBOL_PROPS_WITH_CB[i];
          var val = seriesModel.get(symbolPropName);

          if (isFunction(val)) {
            hasCallback = true;
            symbolOptionsCb[symbolPropName] = val;
          } else {
            symbolOptions[symbolPropName] = val;
          }
        }

        symbolOptions.symbol = symbolOptions.symbol || seriesModel.defaultSymbol;
        data.setVisual(extend({
          legendIcon: seriesModel.legendIcon || symbolOptions.symbol,
          symbolKeepAspect: seriesModel.get('symbolKeepAspect')
        }, symbolOptions)); // Only visible series has each data be visual encoded

        if (ecModel.isSeriesFiltered(seriesModel)) {
          return;
        }

        var symbolPropsCb = keys(symbolOptionsCb);

        function dataEach(data, idx) {
          var rawValue = seriesModel.getRawValue(idx);
          var params = seriesModel.getDataParams(idx);

          for (var i = 0; i < symbolPropsCb.length; i++) {
            var symbolPropName = symbolPropsCb[i];
            data.setItemVisual(idx, symbolPropName, symbolOptionsCb[symbolPropName](rawValue, params));
          }
        }

        return {
          dataEach: hasCallback ? dataEach : null
        };
      }
    };
    var dataSymbolTask = {
      createOnAllSeries: true,
      // For legend.
      performRawSeries: true,
      reset: function (seriesModel, ecModel) {
        if (!seriesModel.hasSymbolVisual) {
          return;
        } // Only visible series has each data be visual encoded


        if (ecModel.isSeriesFiltered(seriesModel)) {
          return;
        }

        var data = seriesModel.getData();

        function dataEach(data, idx) {
          var itemModel = data.getItemModel(idx);

          for (var i = 0; i < SYMBOL_PROPS.length; i++) {
            var symbolPropName = SYMBOL_PROPS[i];
            var val = itemModel.getShallow(symbolPropName, true);

            if (val != null) {
              data.setItemVisual(idx, symbolPropName, val);
            }
          }
        }

        return {
          dataEach: data.hasItemOption ? dataEach : null
        };
      }
    };

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    function getItemVisualFromData(data, dataIndex, key) {
      switch (key) {
        case 'color':
          var style = data.getItemVisual(dataIndex, 'style');
          return style[data.getVisual('drawType')];

        case 'opacity':
          return data.getItemVisual(dataIndex, 'style').opacity;

        case 'symbol':
        case 'symbolSize':
        case 'liftZ':
          return data.getItemVisual(dataIndex, key);

        default:
          if ("development" !== 'production') {
            console.warn("Unknown visual type " + key);
          }

      }
    }
    function getVisualFromData(data, key) {
      switch (key) {
        case 'color':
          var style = data.getVisual('style');
          return style[data.getVisual('drawType')];

        case 'opacity':
          return data.getVisual('style').opacity;

        case 'symbol':
        case 'symbolSize':
        case 'liftZ':
          return data.getVisual(key);

        default:
          if ("development" !== 'production') {
            console.warn("Unknown visual type " + key);
          }

      }
    }

    // Inlucdes: pieSelect, pieUnSelect, pieToggleSelect, mapSelect, mapUnSelect, mapToggleSelect

    function createLegacyDataSelectAction(seriesType, ecRegisterAction) {
      function getSeriesIndices(ecModel, payload) {
        var seriesIndices = [];
        ecModel.eachComponent({
          mainType: 'series',
          subType: seriesType,
          query: payload
        }, function (seriesModel) {
          seriesIndices.push(seriesModel.seriesIndex);
        });
        return seriesIndices;
      }

      each([[seriesType + 'ToggleSelect', 'toggleSelect'], [seriesType + 'Select', 'select'], [seriesType + 'UnSelect', 'unselect']], function (eventsMap) {
        ecRegisterAction(eventsMap[0], function (payload, ecModel, api) {
          payload = extend({}, payload);

          if ("development" !== 'production') {
            deprecateReplaceLog(payload.type, eventsMap[1]);
          }

          api.dispatchAction(extend(payload, {
            type: eventsMap[1],
            seriesIndex: getSeriesIndices(ecModel, payload)
          }));
        });
      });
    }

    function handleSeriesLegacySelectEvents(type, eventPostfix, ecIns, ecModel, payload) {
      var legacyEventName = type + eventPostfix;

      if (!ecIns.isSilent(legacyEventName)) {
        if ("development" !== 'production') {
          deprecateLog("event " + legacyEventName + " is deprecated.");
        }

        ecModel.eachComponent({
          mainType: 'series',
          subType: 'pie'
        }, function (seriesModel) {
          var seriesIndex = seriesModel.seriesIndex;
          var selectedMap = seriesModel.option.selectedMap;
          var selected = payload.selected;

          for (var i = 0; i < selected.length; i++) {
            if (selected[i].seriesIndex === seriesIndex) {
              var data = seriesModel.getData();
              var dataIndex = queryDataIndex(data, payload.fromActionPayload);
              ecIns.trigger(legacyEventName, {
                type: legacyEventName,
                seriesId: seriesModel.id,
                name: isArray(dataIndex) ? data.getName(dataIndex[0]) : data.getName(dataIndex),
                selected: isString(selectedMap) ? selectedMap : extend({}, selectedMap)
              });
            }
          }
        });
      }
    }

    function handleLegacySelectEvents(messageCenter, ecIns, api) {
      messageCenter.on('selectchanged', function (params) {
        var ecModel = api.getModel();

        if (params.isFromClick) {
          handleSeriesLegacySelectEvents('map', 'selectchanged', ecIns, ecModel, params);
          handleSeriesLegacySelectEvents('pie', 'selectchanged', ecIns, ecModel, params);
        } else if (params.fromAction === 'select') {
          handleSeriesLegacySelectEvents('map', 'selected', ecIns, ecModel, params);
          handleSeriesLegacySelectEvents('pie', 'selected', ecIns, ecModel, params);
        } else if (params.fromAction === 'unselect') {
          handleSeriesLegacySelectEvents('map', 'unselected', ecIns, ecModel, params);
          handleSeriesLegacySelectEvents('pie', 'unselected', ecIns, ecModel, params);
        }
      });
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    function findEventDispatcher(target, det, returnFirstMatch) {
      var found;

      while (target) {
        if (det(target)) {
          found = target;

          if (returnFirstMatch) {
            break;
          }
        }

        target = target.__hostTarget || target.parent;
      }

      return found;
    }

    var wmUniqueIndex = Math.round(Math.random() * 9);
    var supportDefineProperty = typeof Object.defineProperty === 'function';
    var WeakMap = (function () {
        function WeakMap() {
            this._id = '__ec_inner_' + wmUniqueIndex++;
        }
        WeakMap.prototype.get = function (key) {
            return this._guard(key)[this._id];
        };
        WeakMap.prototype.set = function (key, value) {
            var target = this._guard(key);
            if (supportDefineProperty) {
                Object.defineProperty(target, this._id, {
                    value: value,
                    enumerable: false,
                    configurable: true
                });
            }
            else {
                target[this._id] = value;
            }
            return this;
        };
        WeakMap.prototype["delete"] = function (key) {
            if (this.has(key)) {
                delete this._guard(key)[this._id];
                return true;
            }
            return false;
        };
        WeakMap.prototype.has = function (key) {
            return !!this._guard(key)[this._id];
        };
        WeakMap.prototype._guard = function (key) {
            if (key !== Object(key)) {
                throw TypeError('Value of WeakMap is not a non-null object.');
            }
            return key;
        };
        return WeakMap;
    }());

    /**
     * Triangle shape
     * @inner
     */

    var Triangle = Path.extend({
      type: 'triangle',
      shape: {
        cx: 0,
        cy: 0,
        width: 0,
        height: 0
      },
      buildPath: function (path, shape) {
        var cx = shape.cx;
        var cy = shape.cy;
        var width = shape.width / 2;
        var height = shape.height / 2;
        path.moveTo(cx, cy - height);
        path.lineTo(cx + width, cy + height);
        path.lineTo(cx - width, cy + height);
        path.closePath();
      }
    });
    /**
     * Diamond shape
     * @inner
     */

    var Diamond = Path.extend({
      type: 'diamond',
      shape: {
        cx: 0,
        cy: 0,
        width: 0,
        height: 0
      },
      buildPath: function (path, shape) {
        var cx = shape.cx;
        var cy = shape.cy;
        var width = shape.width / 2;
        var height = shape.height / 2;
        path.moveTo(cx, cy - height);
        path.lineTo(cx + width, cy);
        path.lineTo(cx, cy + height);
        path.lineTo(cx - width, cy);
        path.closePath();
      }
    });
    /**
     * Pin shape
     * @inner
     */

    var Pin = Path.extend({
      type: 'pin',
      shape: {
        // x, y on the cusp
        x: 0,
        y: 0,
        width: 0,
        height: 0
      },
      buildPath: function (path, shape) {
        var x = shape.x;
        var y = shape.y;
        var w = shape.width / 5 * 3; // Height must be larger than width

        var h = Math.max(w, shape.height);
        var r = w / 2; // Dist on y with tangent point and circle center

        var dy = r * r / (h - r);
        var cy = y - h + r + dy;
        var angle = Math.asin(dy / r); // Dist on x with tangent point and circle center

        var dx = Math.cos(angle) * r;
        var tanX = Math.sin(angle);
        var tanY = Math.cos(angle);
        var cpLen = r * 0.6;
        var cpLen2 = r * 0.7;
        path.moveTo(x - dx, cy + dy);
        path.arc(x, cy, r, Math.PI - angle, Math.PI * 2 + angle);
        path.bezierCurveTo(x + dx - tanX * cpLen, cy + dy + tanY * cpLen, x, y - cpLen2, x, y);
        path.bezierCurveTo(x, y - cpLen2, x - dx + tanX * cpLen, cy + dy + tanY * cpLen, x - dx, cy + dy);
        path.closePath();
      }
    });
    /**
     * Arrow shape
     * @inner
     */

    var Arrow = Path.extend({
      type: 'arrow',
      shape: {
        x: 0,
        y: 0,
        width: 0,
        height: 0
      },
      buildPath: function (ctx, shape) {
        var height = shape.height;
        var width = shape.width;
        var x = shape.x;
        var y = shape.y;
        var dx = width / 3 * 2;
        ctx.moveTo(x, y);
        ctx.lineTo(x + dx, y + height);
        ctx.lineTo(x, y + height / 4 * 3);
        ctx.lineTo(x - dx, y + height);
        ctx.lineTo(x, y);
        ctx.closePath();
      }
    });
    /**
     * Map of path constructors
     */
    // TODO Use function to build symbol path.

    var symbolCtors = {
      line: Line,
      rect: Rect,
      roundRect: Rect,
      square: Rect,
      circle: Circle,
      diamond: Diamond,
      pin: Pin,
      arrow: Arrow,
      triangle: Triangle
    };
    var symbolShapeMakers = {
      line: function (x, y, w, h, shape) {
        shape.x1 = x;
        shape.y1 = y + h / 2;
        shape.x2 = x + w;
        shape.y2 = y + h / 2;
      },
      rect: function (x, y, w, h, shape) {
        shape.x = x;
        shape.y = y;
        shape.width = w;
        shape.height = h;
      },
      roundRect: function (x, y, w, h, shape) {
        shape.x = x;
        shape.y = y;
        shape.width = w;
        shape.height = h;
        shape.r = Math.min(w, h) / 4;
      },
      square: function (x, y, w, h, shape) {
        var size = Math.min(w, h);
        shape.x = x;
        shape.y = y;
        shape.width = size;
        shape.height = size;
      },
      circle: function (x, y, w, h, shape) {
        // Put circle in the center of square
        shape.cx = x + w / 2;
        shape.cy = y + h / 2;
        shape.r = Math.min(w, h) / 2;
      },
      diamond: function (x, y, w, h, shape) {
        shape.cx = x + w / 2;
        shape.cy = y + h / 2;
        shape.width = w;
        shape.height = h;
      },
      pin: function (x, y, w, h, shape) {
        shape.x = x + w / 2;
        shape.y = y + h / 2;
        shape.width = w;
        shape.height = h;
      },
      arrow: function (x, y, w, h, shape) {
        shape.x = x + w / 2;
        shape.y = y + h / 2;
        shape.width = w;
        shape.height = h;
      },
      triangle: function (x, y, w, h, shape) {
        shape.cx = x + w / 2;
        shape.cy = y + h / 2;
        shape.width = w;
        shape.height = h;
      }
    };
    var symbolBuildProxies = {};
    each(symbolCtors, function (Ctor, name) {
      symbolBuildProxies[name] = new Ctor();
    });
    var SymbolClz = Path.extend({
      type: 'symbol',
      shape: {
        symbolType: '',
        x: 0,
        y: 0,
        width: 0,
        height: 0
      },
      calculateTextPosition: function (out, config, rect) {
        var res = calculateTextPosition(out, config, rect);
        var shape = this.shape;

        if (shape && shape.symbolType === 'pin' && config.position === 'inside') {
          res.y = rect.y + rect.height * 0.4;
        }

        return res;
      },
      buildPath: function (ctx, shape, inBundle) {
        var symbolType = shape.symbolType;

        if (symbolType !== 'none') {
          var proxySymbol = symbolBuildProxies[symbolType];

          if (!proxySymbol) {
            // Default rect
            symbolType = 'rect';
            proxySymbol = symbolBuildProxies[symbolType];
          }

          symbolShapeMakers[symbolType](shape.x, shape.y, shape.width, shape.height, proxySymbol.shape);
          proxySymbol.buildPath(ctx, proxySymbol.shape, inBundle);
        }
      }
    }); // Provide setColor helper method to avoid determine if set the fill or stroke outside

    function symbolPathSetColor(color, innerColor) {
      if (this.type !== 'image') {
        var symbolStyle = this.style;

        if (this.__isEmptyBrush) {
          symbolStyle.stroke = color;
          symbolStyle.fill = innerColor || '#fff'; // TODO Same width with lineStyle in LineView

          symbolStyle.lineWidth = 2;
        } else if (this.shape.symbolType === 'line') {
          symbolStyle.stroke = color;
        } else {
          symbolStyle.fill = color;
        }

        this.markRedraw();
      }
    }
    /**
     * Create a symbol element with given symbol configuration: shape, x, y, width, height, color
     */


    function createSymbol(symbolType, x, y, w, h, color, // whether to keep the ratio of w/h,
    keepAspect) {
      // TODO Support image object, DynamicImage.
      var isEmpty = symbolType.indexOf('empty') === 0;

      if (isEmpty) {
        symbolType = symbolType.substr(5, 1).toLowerCase() + symbolType.substr(6);
      }

      var symbolPath;

      if (symbolType.indexOf('image://') === 0) {
        symbolPath = makeImage(symbolType.slice(8), new BoundingRect(x, y, w, h), keepAspect ? 'center' : 'cover');
      } else if (symbolType.indexOf('path://') === 0) {
        symbolPath = makePath(symbolType.slice(7), {}, new BoundingRect(x, y, w, h), keepAspect ? 'center' : 'cover');
      } else {
        symbolPath = new SymbolClz({
          shape: {
            symbolType: symbolType,
            x: x,
            y: y,
            width: w,
            height: h
          }
        });
      }

      symbolPath.__isEmptyBrush = isEmpty; // TODO Should deprecate setColor

      symbolPath.setColor = symbolPathSetColor;

      if (color) {
        symbolPath.setColor(color);
      }

      return symbolPath;
    }
    function normalizeSymbolSize(symbolSize) {
      if (!isArray(symbolSize)) {
        symbolSize = [+symbolSize, +symbolSize];
      }

      return [symbolSize[0] || 0, symbolSize[1] || 0];
    }
    function normalizeSymbolOffset(symbolOffset, symbolSize) {
      if (symbolOffset == null) {
        return;
      }

      if (!isArray(symbolOffset)) {
        symbolOffset = [symbolOffset, symbolOffset];
      }

      return [parsePercent$1(symbolOffset[0], symbolSize[0]) || 0, parsePercent$1(retrieve2(symbolOffset[1], symbolOffset[0]), symbolSize[1]) || 0];
    }

    function isSafeNum(num) {
        return isFinite(num);
    }
    function createLinearGradient(ctx, obj, rect) {
        var x = obj.x == null ? 0 : obj.x;
        var x2 = obj.x2 == null ? 1 : obj.x2;
        var y = obj.y == null ? 0 : obj.y;
        var y2 = obj.y2 == null ? 0 : obj.y2;
        if (!obj.global) {
            x = x * rect.width + rect.x;
            x2 = x2 * rect.width + rect.x;
            y = y * rect.height + rect.y;
            y2 = y2 * rect.height + rect.y;
        }
        x = isSafeNum(x) ? x : 0;
        x2 = isSafeNum(x2) ? x2 : 1;
        y = isSafeNum(y) ? y : 0;
        y2 = isSafeNum(y2) ? y2 : 0;
        var canvasGradient = ctx.createLinearGradient(x, y, x2, y2);
        return canvasGradient;
    }
    function createRadialGradient(ctx, obj, rect) {
        var width = rect.width;
        var height = rect.height;
        var min = Math.min(width, height);
        var x = obj.x == null ? 0.5 : obj.x;
        var y = obj.y == null ? 0.5 : obj.y;
        var r = obj.r == null ? 0.5 : obj.r;
        if (!obj.global) {
            x = x * width + rect.x;
            y = y * height + rect.y;
            r = r * min;
        }
        x = isSafeNum(x) ? x : 0.5;
        y = isSafeNum(y) ? y : 0.5;
        r = r >= 0 && isSafeNum(r) ? r : 0.5;
        var canvasGradient = ctx.createRadialGradient(x, y, 0, x, y, r);
        return canvasGradient;
    }
    function getCanvasGradient(ctx, obj, rect) {
        var canvasGradient = obj.type === 'radial'
            ? createRadialGradient(ctx, obj, rect)
            : createLinearGradient(ctx, obj, rect);
        var colorStops = obj.colorStops;
        for (var i = 0; i < colorStops.length; i++) {
            canvasGradient.addColorStop(colorStops[i].offset, colorStops[i].color);
        }
        return canvasGradient;
    }
    function isClipPathChanged(clipPaths, prevClipPaths) {
        if (clipPaths === prevClipPaths || (!clipPaths && !prevClipPaths)) {
            return false;
        }
        if (!clipPaths || !prevClipPaths || (clipPaths.length !== prevClipPaths.length)) {
            return true;
        }
        for (var i = 0; i < clipPaths.length; i++) {
            if (clipPaths[i] !== prevClipPaths[i]) {
                return true;
            }
        }
        return false;
    }
    function parseInt10(val) {
        return parseInt(val, 10);
    }
    function getSize(root, whIdx, opts) {
        var wh = ['width', 'height'][whIdx];
        var cwh = ['clientWidth', 'clientHeight'][whIdx];
        var plt = ['paddingLeft', 'paddingTop'][whIdx];
        var prb = ['paddingRight', 'paddingBottom'][whIdx];
        if (opts[wh] != null && opts[wh] !== 'auto') {
            return parseFloat(opts[wh]);
        }
        var stl = document.defaultView.getComputedStyle(root);
        return ((root[cwh] || parseInt10(stl[wh]) || parseInt10(root.style[wh]))
            - (parseInt10(stl[plt]) || 0)
            - (parseInt10(stl[prb]) || 0)) | 0;
    }

    function normalizeLineDash(lineType, lineWidth) {
        if (!lineType || lineType === 'solid' || !(lineWidth > 0)) {
            return null;
        }
        return lineType === 'dashed'
            ? [4 * lineWidth, 2 * lineWidth]
            : lineType === 'dotted'
                ? [lineWidth]
                : isNumber(lineType)
                    ? [lineType] : isArray(lineType) ? lineType : null;
    }
    function getLineDash(el) {
        var style = el.style;
        var lineDash = style.lineDash && style.lineWidth > 0 && normalizeLineDash(style.lineDash, style.lineWidth);
        var lineDashOffset = style.lineDashOffset;
        if (lineDash) {
            var lineScale_1 = (style.strokeNoScale && el.getLineScale) ? el.getLineScale() : 1;
            if (lineScale_1 && lineScale_1 !== 1) {
                lineDash = map(lineDash, function (rawVal) {
                    return rawVal / lineScale_1;
                });
                lineDashOffset /= lineScale_1;
            }
        }
        return [lineDash, lineDashOffset];
    }

    var pathProxyForDraw = new PathProxy(true);
    function styleHasStroke(style) {
        var stroke = style.stroke;
        return !(stroke == null || stroke === 'none' || !(style.lineWidth > 0));
    }
    function isValidStrokeFillStyle(strokeOrFill) {
        return typeof strokeOrFill === 'string' && strokeOrFill !== 'none';
    }
    function styleHasFill(style) {
        var fill = style.fill;
        return fill != null && fill !== 'none';
    }
    function doFillPath(ctx, style) {
        if (style.fillOpacity != null && style.fillOpacity !== 1) {
            var originalGlobalAlpha = ctx.globalAlpha;
            ctx.globalAlpha = style.fillOpacity * style.opacity;
            ctx.fill();
            ctx.globalAlpha = originalGlobalAlpha;
        }
        else {
            ctx.fill();
        }
    }
    function doStrokePath(ctx, style) {
        if (style.strokeOpacity != null && style.strokeOpacity !== 1) {
            var originalGlobalAlpha = ctx.globalAlpha;
            ctx.globalAlpha = style.strokeOpacity * style.opacity;
            ctx.stroke();
            ctx.globalAlpha = originalGlobalAlpha;
        }
        else {
            ctx.stroke();
        }
    }
    function createCanvasPattern(ctx, pattern, el) {
        var image = createOrUpdateImage(pattern.image, pattern.__image, el);
        if (isImageReady(image)) {
            var canvasPattern = ctx.createPattern(image, pattern.repeat || 'repeat');
            if (typeof DOMMatrix === 'function'
                && canvasPattern
                && canvasPattern.setTransform) {
                var matrix = new DOMMatrix();
                matrix.translateSelf((pattern.x || 0), (pattern.y || 0));
                matrix.rotateSelf(0, 0, (pattern.rotation || 0) * RADIAN_TO_DEGREE);
                matrix.scaleSelf((pattern.scaleX || 1), (pattern.scaleY || 1));
                canvasPattern.setTransform(matrix);
            }
            return canvasPattern;
        }
    }
    function brushPath(ctx, el, style, inBatch) {
        var _a;
        var hasStroke = styleHasStroke(style);
        var hasFill = styleHasFill(style);
        var strokePercent = style.strokePercent;
        var strokePart = strokePercent < 1;
        var firstDraw = !el.path;
        if ((!el.silent || strokePart) && firstDraw) {
            el.createPathProxy();
        }
        var path = el.path || pathProxyForDraw;
        var dirtyFlag = el.__dirty;
        if (!inBatch) {
            var fill = style.fill;
            var stroke = style.stroke;
            var hasFillGradient = hasFill && !!fill.colorStops;
            var hasStrokeGradient = hasStroke && !!stroke.colorStops;
            var hasFillPattern = hasFill && !!fill.image;
            var hasStrokePattern = hasStroke && !!stroke.image;
            var fillGradient = void 0;
            var strokeGradient = void 0;
            var fillPattern = void 0;
            var strokePattern = void 0;
            var rect = void 0;
            if (hasFillGradient || hasStrokeGradient) {
                rect = el.getBoundingRect();
            }
            if (hasFillGradient) {
                fillGradient = dirtyFlag
                    ? getCanvasGradient(ctx, fill, rect)
                    : el.__canvasFillGradient;
                el.__canvasFillGradient = fillGradient;
            }
            if (hasStrokeGradient) {
                strokeGradient = dirtyFlag
                    ? getCanvasGradient(ctx, stroke, rect)
                    : el.__canvasStrokeGradient;
                el.__canvasStrokeGradient = strokeGradient;
            }
            if (hasFillPattern) {
                fillPattern = (dirtyFlag || !el.__canvasFillPattern)
                    ? createCanvasPattern(ctx, fill, el)
                    : el.__canvasFillPattern;
                el.__canvasFillPattern = fillPattern;
            }
            if (hasStrokePattern) {
                strokePattern = (dirtyFlag || !el.__canvasStrokePattern)
                    ? createCanvasPattern(ctx, stroke, el)
                    : el.__canvasStrokePattern;
                el.__canvasStrokePattern = fillPattern;
            }
            if (hasFillGradient) {
                ctx.fillStyle = fillGradient;
            }
            else if (hasFillPattern) {
                if (fillPattern) {
                    ctx.fillStyle = fillPattern;
                }
                else {
                    hasFill = false;
                }
            }
            if (hasStrokeGradient) {
                ctx.strokeStyle = strokeGradient;
            }
            else if (hasStrokePattern) {
                if (strokePattern) {
                    ctx.strokeStyle = strokePattern;
                }
                else {
                    hasStroke = false;
                }
            }
        }
        var scale = el.getGlobalScale();
        path.setScale(scale[0], scale[1], el.segmentIgnoreThreshold);
        var lineDash;
        var lineDashOffset;
        if (ctx.setLineDash && style.lineDash) {
            _a = getLineDash(el), lineDash = _a[0], lineDashOffset = _a[1];
        }
        var needsRebuild = true;
        if (firstDraw || (dirtyFlag & SHAPE_CHANGED_BIT)) {
            path.setDPR(ctx.dpr);
            if (strokePart) {
                path.setContext(null);
            }
            else {
                path.setContext(ctx);
                needsRebuild = false;
            }
            path.reset();
            el.buildPath(path, el.shape, inBatch);
            path.toStatic();
            el.pathUpdated();
        }
        if (needsRebuild) {
            path.rebuildPath(ctx, strokePart ? strokePercent : 1);
        }
        if (lineDash) {
            ctx.setLineDash(lineDash);
            ctx.lineDashOffset = lineDashOffset;
        }
        if (!inBatch) {
            if (style.strokeFirst) {
                if (hasStroke) {
                    doStrokePath(ctx, style);
                }
                if (hasFill) {
                    doFillPath(ctx, style);
                }
            }
            else {
                if (hasFill) {
                    doFillPath(ctx, style);
                }
                if (hasStroke) {
                    doStrokePath(ctx, style);
                }
            }
        }
        if (lineDash) {
            ctx.setLineDash([]);
        }
    }
    function brushImage(ctx, el, style) {
        var image = el.__image = createOrUpdateImage(style.image, el.__image, el, el.onload);
        if (!image || !isImageReady(image)) {
            return;
        }
        var x = style.x || 0;
        var y = style.y || 0;
        var width = el.getWidth();
        var height = el.getHeight();
        var aspect = image.width / image.height;
        if (width == null && height != null) {
            width = height * aspect;
        }
        else if (height == null && width != null) {
            height = width / aspect;
        }
        else if (width == null && height == null) {
            width = image.width;
            height = image.height;
        }
        if (style.sWidth && style.sHeight) {
            var sx = style.sx || 0;
            var sy = style.sy || 0;
            ctx.drawImage(image, sx, sy, style.sWidth, style.sHeight, x, y, width, height);
        }
        else if (style.sx && style.sy) {
            var sx = style.sx;
            var sy = style.sy;
            var sWidth = width - sx;
            var sHeight = height - sy;
            ctx.drawImage(image, sx, sy, sWidth, sHeight, x, y, width, height);
        }
        else {
            ctx.drawImage(image, x, y, width, height);
        }
    }
    function brushText(ctx, el, style) {
        var _a;
        var text = style.text;
        text != null && (text += '');
        if (text) {
            ctx.font = style.font || DEFAULT_FONT;
            ctx.textAlign = style.textAlign;
            ctx.textBaseline = style.textBaseline;
            var lineDash = void 0;
            var lineDashOffset = void 0;
            if (ctx.setLineDash && style.lineDash) {
                _a = getLineDash(el), lineDash = _a[0], lineDashOffset = _a[1];
            }
            if (lineDash) {
                ctx.setLineDash(lineDash);
                ctx.lineDashOffset = lineDashOffset;
            }
            if (style.strokeFirst) {
                if (styleHasStroke(style)) {
                    ctx.strokeText(text, style.x, style.y);
                }
                if (styleHasFill(style)) {
                    ctx.fillText(text, style.x, style.y);
                }
            }
            else {
                if (styleHasFill(style)) {
                    ctx.fillText(text, style.x, style.y);
                }
                if (styleHasStroke(style)) {
                    ctx.strokeText(text, style.x, style.y);
                }
            }
            if (lineDash) {
                ctx.setLineDash([]);
            }
        }
    }
    var SHADOW_NUMBER_PROPS = ['shadowBlur', 'shadowOffsetX', 'shadowOffsetY'];
    var STROKE_PROPS = [
        ['lineCap', 'butt'], ['lineJoin', 'miter'], ['miterLimit', 10]
    ];
    function bindCommonProps(ctx, style, prevStyle, forceSetAll, scope) {
        var styleChanged = false;
        if (!forceSetAll) {
            prevStyle = prevStyle || {};
            if (style === prevStyle) {
                return false;
            }
        }
        if (forceSetAll || style.opacity !== prevStyle.opacity) {
            flushPathDrawn(ctx, scope);
            styleChanged = true;
            var opacity = Math.max(Math.min(style.opacity, 1), 0);
            ctx.globalAlpha = isNaN(opacity) ? DEFAULT_COMMON_STYLE.opacity : opacity;
        }
        if (forceSetAll || style.blend !== prevStyle.blend) {
            if (!styleChanged) {
                flushPathDrawn(ctx, scope);
                styleChanged = true;
            }
            ctx.globalCompositeOperation = style.blend || DEFAULT_COMMON_STYLE.blend;
        }
        for (var i = 0; i < SHADOW_NUMBER_PROPS.length; i++) {
            var propName = SHADOW_NUMBER_PROPS[i];
            if (forceSetAll || style[propName] !== prevStyle[propName]) {
                if (!styleChanged) {
                    flushPathDrawn(ctx, scope);
                    styleChanged = true;
                }
                ctx[propName] = ctx.dpr * (style[propName] || 0);
            }
        }
        if (forceSetAll || style.shadowColor !== prevStyle.shadowColor) {
            if (!styleChanged) {
                flushPathDrawn(ctx, scope);
                styleChanged = true;
            }
            ctx.shadowColor = style.shadowColor || DEFAULT_COMMON_STYLE.shadowColor;
        }
        return styleChanged;
    }
    function bindPathAndTextCommonStyle(ctx, el, prevEl, forceSetAll, scope) {
        var style = getStyle(el, scope.inHover);
        var prevStyle = forceSetAll
            ? null
            : (prevEl && getStyle(prevEl, scope.inHover) || {});
        if (style === prevStyle) {
            return false;
        }
        var styleChanged = bindCommonProps(ctx, style, prevStyle, forceSetAll, scope);
        if (forceSetAll || style.fill !== prevStyle.fill) {
            if (!styleChanged) {
                flushPathDrawn(ctx, scope);
                styleChanged = true;
            }
            isValidStrokeFillStyle(style.fill) && (ctx.fillStyle = style.fill);
        }
        if (forceSetAll || style.stroke !== prevStyle.stroke) {
            if (!styleChanged) {
                flushPathDrawn(ctx, scope);
                styleChanged = true;
            }
            isValidStrokeFillStyle(style.stroke) && (ctx.strokeStyle = style.stroke);
        }
        if (forceSetAll || style.opacity !== prevStyle.opacity) {
            if (!styleChanged) {
                flushPathDrawn(ctx, scope);
                styleChanged = true;
            }
            ctx.globalAlpha = style.opacity == null ? 1 : style.opacity;
        }
        if (el.hasStroke()) {
            var lineWidth = style.lineWidth;
            var newLineWidth = lineWidth / ((style.strokeNoScale && el.getLineScale) ? el.getLineScale() : 1);
            if (ctx.lineWidth !== newLineWidth) {
                if (!styleChanged) {
                    flushPathDrawn(ctx, scope);
                    styleChanged = true;
                }
                ctx.lineWidth = newLineWidth;
            }
        }
        for (var i = 0; i < STROKE_PROPS.length; i++) {
            var prop = STROKE_PROPS[i];
            var propName = prop[0];
            if (forceSetAll || style[propName] !== prevStyle[propName]) {
                if (!styleChanged) {
                    flushPathDrawn(ctx, scope);
                    styleChanged = true;
                }
                ctx[propName] = style[propName] || prop[1];
            }
        }
        return styleChanged;
    }
    function bindImageStyle(ctx, el, prevEl, forceSetAll, scope) {
        return bindCommonProps(ctx, getStyle(el, scope.inHover), prevEl && getStyle(prevEl, scope.inHover), forceSetAll, scope);
    }
    function setContextTransform(ctx, el) {
        var m = el.transform;
        var dpr = ctx.dpr || 1;
        if (m) {
            ctx.setTransform(dpr * m[0], dpr * m[1], dpr * m[2], dpr * m[3], dpr * m[4], dpr * m[5]);
        }
        else {
            ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
        }
    }
    function updateClipStatus(clipPaths, ctx, scope) {
        var allClipped = false;
        for (var i = 0; i < clipPaths.length; i++) {
            var clipPath = clipPaths[i];
            allClipped = allClipped || clipPath.isZeroArea();
            setContextTransform(ctx, clipPath);
            ctx.beginPath();
            clipPath.buildPath(ctx, clipPath.shape);
            ctx.clip();
        }
        scope.allClipped = allClipped;
    }
    function isTransformChanged(m0, m1) {
        if (m0 && m1) {
            return m0[0] !== m1[0]
                || m0[1] !== m1[1]
                || m0[2] !== m1[2]
                || m0[3] !== m1[3]
                || m0[4] !== m1[4]
                || m0[5] !== m1[5];
        }
        else if (!m0 && !m1) {
            return false;
        }
        return true;
    }
    var DRAW_TYPE_PATH = 1;
    var DRAW_TYPE_IMAGE = 2;
    var DRAW_TYPE_TEXT = 3;
    var DRAW_TYPE_INCREMENTAL = 4;
    function canPathBatch(style) {
        var hasFill = styleHasFill(style);
        var hasStroke = styleHasStroke(style);
        return !(style.lineDash
            || !(+hasFill ^ +hasStroke)
            || (hasFill && typeof style.fill !== 'string')
            || (hasStroke && typeof style.stroke !== 'string')
            || style.strokePercent < 1
            || style.strokeOpacity < 1
            || style.fillOpacity < 1);
    }
    function flushPathDrawn(ctx, scope) {
        scope.batchFill && ctx.fill();
        scope.batchStroke && ctx.stroke();
        scope.batchFill = '';
        scope.batchStroke = '';
    }
    function getStyle(el, inHover) {
        return inHover ? (el.__hoverStyle || el.style) : el.style;
    }
    function brushSingle(ctx, el) {
        brush(ctx, el, { inHover: false, viewWidth: 0, viewHeight: 0 }, true);
    }
    function brush(ctx, el, scope, isLast) {
        var m = el.transform;
        if (!el.shouldBePainted(scope.viewWidth, scope.viewHeight, false, false)) {
            el.__dirty &= ~REDRAW_BIT;
            el.__isRendered = false;
            return;
        }
        var clipPaths = el.__clipPaths;
        var prevElClipPaths = scope.prevElClipPaths;
        var forceSetTransform = false;
        var forceSetStyle = false;
        if (!prevElClipPaths || isClipPathChanged(clipPaths, prevElClipPaths)) {
            if (prevElClipPaths && prevElClipPaths.length) {
                flushPathDrawn(ctx, scope);
                ctx.restore();
                forceSetStyle = forceSetTransform = true;
                scope.prevElClipPaths = null;
                scope.allClipped = false;
                scope.prevEl = null;
            }
            if (clipPaths && clipPaths.length) {
                flushPathDrawn(ctx, scope);
                ctx.save();
                updateClipStatus(clipPaths, ctx, scope);
                forceSetTransform = true;
            }
            scope.prevElClipPaths = clipPaths;
        }
        if (scope.allClipped) {
            el.__isRendered = false;
            return;
        }
        el.beforeBrush && el.beforeBrush();
        el.innerBeforeBrush();
        var prevEl = scope.prevEl;
        if (!prevEl) {
            forceSetStyle = forceSetTransform = true;
        }
        var canBatchPath = el instanceof Path
            && el.autoBatch
            && canPathBatch(el.style);
        if (forceSetTransform || isTransformChanged(m, prevEl.transform)) {
            flushPathDrawn(ctx, scope);
            setContextTransform(ctx, el);
        }
        else if (!canBatchPath) {
            flushPathDrawn(ctx, scope);
        }
        var style = getStyle(el, scope.inHover);
        if (el instanceof Path) {
            if (scope.lastDrawType !== DRAW_TYPE_PATH) {
                forceSetStyle = true;
                scope.lastDrawType = DRAW_TYPE_PATH;
            }
            bindPathAndTextCommonStyle(ctx, el, prevEl, forceSetStyle, scope);
            if (!canBatchPath || (!scope.batchFill && !scope.batchStroke)) {
                ctx.beginPath();
            }
            brushPath(ctx, el, style, canBatchPath);
            if (canBatchPath) {
                scope.batchFill = style.fill || '';
                scope.batchStroke = style.stroke || '';
            }
        }
        else {
            if (el instanceof TSpan) {
                if (scope.lastDrawType !== DRAW_TYPE_TEXT) {
                    forceSetStyle = true;
                    scope.lastDrawType = DRAW_TYPE_TEXT;
                }
                bindPathAndTextCommonStyle(ctx, el, prevEl, forceSetStyle, scope);
                brushText(ctx, el, style);
            }
            else if (el instanceof ZRImage) {
                if (scope.lastDrawType !== DRAW_TYPE_IMAGE) {
                    forceSetStyle = true;
                    scope.lastDrawType = DRAW_TYPE_IMAGE;
                }
                bindImageStyle(ctx, el, prevEl, forceSetStyle, scope);
                brushImage(ctx, el, style);
            }
            else if (el.getTemporalDisplayables) {
                if (scope.lastDrawType !== DRAW_TYPE_INCREMENTAL) {
                    forceSetStyle = true;
                    scope.lastDrawType = DRAW_TYPE_INCREMENTAL;
                }
                brushIncremental(ctx, el, scope);
            }
        }
        if (canBatchPath && isLast) {
            flushPathDrawn(ctx, scope);
        }
        el.innerAfterBrush();
        el.afterBrush && el.afterBrush();
        scope.prevEl = el;
        el.__dirty = 0;
        el.__isRendered = true;
    }
    function brushIncremental(ctx, el, scope) {
        var displayables = el.getDisplayables();
        var temporalDisplayables = el.getTemporalDisplayables();
        ctx.save();
        var innerScope = {
            prevElClipPaths: null,
            prevEl: null,
            allClipped: false,
            viewWidth: scope.viewWidth,
            viewHeight: scope.viewHeight,
            inHover: scope.inHover
        };
        var i;
        var len;
        for (i = el.getCursor(), len = displayables.length; i < len; i++) {
            var displayable = displayables[i];
            displayable.beforeBrush && displayable.beforeBrush();
            displayable.innerBeforeBrush();
            brush(ctx, displayable, innerScope, i === len - 1);
            displayable.innerAfterBrush();
            displayable.afterBrush && displayable.afterBrush();
            innerScope.prevEl = displayable;
        }
        for (var i_1 = 0, len_1 = temporalDisplayables.length; i_1 < len_1; i_1++) {
            var displayable = temporalDisplayables[i_1];
            displayable.beforeBrush && displayable.beforeBrush();
            displayable.innerBeforeBrush();
            brush(ctx, displayable, innerScope, i_1 === len_1 - 1);
            displayable.innerAfterBrush();
            displayable.afterBrush && displayable.afterBrush();
            innerScope.prevEl = displayable;
        }
        el.clearTemporalDisplayables();
        el.notClear = true;
        ctx.restore();
    }

    var decalMap = new WeakMap();
    var decalCache = new LRU(100);
    var decalKeys = ['symbol', 'symbolSize', 'symbolKeepAspect', 'color', 'backgroundColor', 'dashArrayX', 'dashArrayY', 'maxTileWidth', 'maxTileHeight'];
    /**
     * Create or update pattern image from decal options
     *
     * @param {InnerDecalObject | 'none'} decalObject decal options, 'none' if no decal
     * @return {Pattern} pattern with generated image, null if no decal
     */

    function createOrUpdatePatternFromDecal(decalObject, api) {
      if (decalObject === 'none') {
        return null;
      }

      var dpr = api.getDevicePixelRatio();
      var zr = api.getZr();
      var isSVG = zr.painter.type === 'svg';

      if (decalObject.dirty) {
        decalMap["delete"](decalObject);
      }

      var oldPattern = decalMap.get(decalObject);

      if (oldPattern) {
        return oldPattern;
      }

      var decalOpt = defaults(decalObject, {
        symbol: 'rect',
        symbolSize: 1,
        symbolKeepAspect: true,
        color: 'rgba(0, 0, 0, 0.2)',
        backgroundColor: null,
        dashArrayX: 5,
        dashArrayY: 5,
        rotation: 0,
        maxTileWidth: 512,
        maxTileHeight: 512
      });

      if (decalOpt.backgroundColor === 'none') {
        decalOpt.backgroundColor = null;
      }

      var pattern = {
        repeat: 'repeat'
      };
      setPatternnSource(pattern);
      pattern.rotation = decalOpt.rotation;
      pattern.scaleX = pattern.scaleY = isSVG ? 1 : 1 / dpr;
      decalMap.set(decalObject, pattern);
      decalObject.dirty = false;
      return pattern;

      function setPatternnSource(pattern) {
        var keys = [dpr];
        var isValidKey = true;

        for (var i = 0; i < decalKeys.length; ++i) {
          var value = decalOpt[decalKeys[i]];

          if (value != null && !isArray(value) && !isString(value) && !isNumber(value) && typeof value !== 'boolean') {
            isValidKey = false;
            break;
          }

          keys.push(value);
        }

        var cacheKey;

        if (isValidKey) {
          cacheKey = keys.join(',') + (isSVG ? '-svg' : '');
          var cache = decalCache.get(cacheKey);

          if (cache) {
            isSVG ? pattern.svgElement = cache : pattern.image = cache;
          }
        }

        var dashArrayX = normalizeDashArrayX(decalOpt.dashArrayX);
        var dashArrayY = normalizeDashArrayY(decalOpt.dashArrayY);
        var symbolArray = normalizeSymbolArray(decalOpt.symbol);
        var lineBlockLengthsX = getLineBlockLengthX(dashArrayX);
        var lineBlockLengthY = getLineBlockLengthY(dashArrayY);
        var canvas = !isSVG && platformApi.createCanvas();
        var svgRoot = isSVG && {
          tag: 'g',
          attrs: {},
          key: 'dcl',
          children: []
        };
        var pSize = getPatternSize();
        var ctx;

        if (canvas) {
          canvas.width = pSize.width * dpr;
          canvas.height = pSize.height * dpr;
          ctx = canvas.getContext('2d');
        }

        brushDecal();

        if (isValidKey) {
          decalCache.put(cacheKey, canvas || svgRoot);
        }

        pattern.image = canvas;
        pattern.svgElement = svgRoot;
        pattern.svgWidth = pSize.width;
        pattern.svgHeight = pSize.height;
        /**
         * Get minimum length that can make a repeatable pattern.
         *
         * @return {Object} pattern width and height
         */

        function getPatternSize() {
          /**
           * For example, if dash is [[3, 2], [2, 1]] for X, it looks like
           * |---  ---  ---  ---  --- ...
           * |-- -- -- -- -- -- -- -- ...
           * |---  ---  ---  ---  --- ...
           * |-- -- -- -- -- -- -- -- ...
           * So the minimum length of X is 15,
           * which is the least common multiple of `3 + 2` and `2 + 1`
           * |---  ---  ---  |---  --- ...
           * |-- -- -- -- -- |-- -- -- ...
           */
          var width = 1;

          for (var i = 0, xlen = lineBlockLengthsX.length; i < xlen; ++i) {
            width = getLeastCommonMultiple(width, lineBlockLengthsX[i]);
          }

          var symbolRepeats = 1;

          for (var i = 0, xlen = symbolArray.length; i < xlen; ++i) {
            symbolRepeats = getLeastCommonMultiple(symbolRepeats, symbolArray[i].length);
          }

          width *= symbolRepeats;
          var height = lineBlockLengthY * lineBlockLengthsX.length * symbolArray.length;

          if ("development" !== 'production') {
            var warn = function (attrName) {
              /* eslint-disable-next-line */
              console.warn("Calculated decal size is greater than " + attrName + " due to decal option settings so " + attrName + " is used for the decal size. Please consider changing the decal option to make a smaller decal or set " + attrName + " to be larger to avoid incontinuity.");
            };

            if (width > decalOpt.maxTileWidth) {
              warn('maxTileWidth');
            }

            if (height > decalOpt.maxTileHeight) {
              warn('maxTileHeight');
            }
          }

          return {
            width: Math.max(1, Math.min(width, decalOpt.maxTileWidth)),
            height: Math.max(1, Math.min(height, decalOpt.maxTileHeight))
          };
        }

        function brushDecal() {
          if (ctx) {
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            if (decalOpt.backgroundColor) {
              ctx.fillStyle = decalOpt.backgroundColor;
              ctx.fillRect(0, 0, canvas.width, canvas.height);
            }
          }

          var ySum = 0;

          for (var i = 0; i < dashArrayY.length; ++i) {
            ySum += dashArrayY[i];
          }

          if (ySum <= 0) {
            // dashArrayY is 0, draw nothing
            return;
          }

          var y = -lineBlockLengthY;
          var yId = 0;
          var yIdTotal = 0;
          var xId0 = 0;

          while (y < pSize.height) {
            if (yId % 2 === 0) {
              var symbolYId = yIdTotal / 2 % symbolArray.length;
              var x = 0;
              var xId1 = 0;
              var xId1Total = 0;

              while (x < pSize.width * 2) {
                var xSum = 0;

                for (var i = 0; i < dashArrayX[xId0].length; ++i) {
                  xSum += dashArrayX[xId0][i];
                }

                if (xSum <= 0) {
                  // Skip empty line
                  break;
                } // E.g., [15, 5, 20, 5] draws only for 15 and 20


                if (xId1 % 2 === 0) {
                  var size = (1 - decalOpt.symbolSize) * 0.5;
                  var left = x + dashArrayX[xId0][xId1] * size;
                  var top_1 = y + dashArrayY[yId] * size;
                  var width = dashArrayX[xId0][xId1] * decalOpt.symbolSize;
                  var height = dashArrayY[yId] * decalOpt.symbolSize;
                  var symbolXId = xId1Total / 2 % symbolArray[symbolYId].length;
                  brushSymbol(left, top_1, width, height, symbolArray[symbolYId][symbolXId]);
                }

                x += dashArrayX[xId0][xId1];
                ++xId1Total;
                ++xId1;

                if (xId1 === dashArrayX[xId0].length) {
                  xId1 = 0;
                }
              }

              ++xId0;

              if (xId0 === dashArrayX.length) {
                xId0 = 0;
              }
            }

            y += dashArrayY[yId];
            ++yIdTotal;
            ++yId;

            if (yId === dashArrayY.length) {
              yId = 0;
            }
          }

          function brushSymbol(x, y, width, height, symbolType) {
            var scale = isSVG ? 1 : dpr;
            var symbol = createSymbol(symbolType, x * scale, y * scale, width * scale, height * scale, decalOpt.color, decalOpt.symbolKeepAspect);

            if (isSVG) {
              var symbolVNode = zr.painter.renderOneToVNode(symbol);

              if (symbolVNode) {
                svgRoot.children.push(symbolVNode);
              }
            } else {
              // Paint to canvas for all other renderers.
              brushSingle(ctx, symbol);
            }
          }
        }
      }
    }
    /**
     * Convert symbol array into normalized array
     *
     * @param {string | (string | string[])[]} symbol symbol input
     * @return {string[][]} normolized symbol array
     */

    function normalizeSymbolArray(symbol) {
      if (!symbol || symbol.length === 0) {
        return [['rect']];
      }

      if (isString(symbol)) {
        return [[symbol]];
      }

      var isAllString = true;

      for (var i = 0; i < symbol.length; ++i) {
        if (!isString(symbol[i])) {
          isAllString = false;
          break;
        }
      }

      if (isAllString) {
        return normalizeSymbolArray([symbol]);
      }

      var result = [];

      for (var i = 0; i < symbol.length; ++i) {
        if (isString(symbol[i])) {
          result.push([symbol[i]]);
        } else {
          result.push(symbol[i]);
        }
      }

      return result;
    }
    /**
     * Convert dash input into dashArray
     *
     * @param {DecalDashArrayX} dash dash input
     * @return {number[][]} normolized dash array
     */


    function normalizeDashArrayX(dash) {
      if (!dash || dash.length === 0) {
        return [[0, 0]];
      }

      if (isNumber(dash)) {
        var dashValue = Math.ceil(dash);
        return [[dashValue, dashValue]];
      }
      /**
       * [20, 5] should be normalized into [[20, 5]],
       * while [20, [5, 10]] should be normalized into [[20, 20], [5, 10]]
       */


      var isAllNumber = true;

      for (var i = 0; i < dash.length; ++i) {
        if (!isNumber(dash[i])) {
          isAllNumber = false;
          break;
        }
      }

      if (isAllNumber) {
        return normalizeDashArrayX([dash]);
      }

      var result = [];

      for (var i = 0; i < dash.length; ++i) {
        if (isNumber(dash[i])) {
          var dashValue = Math.ceil(dash[i]);
          result.push([dashValue, dashValue]);
        } else {
          var dashValue = map(dash[i], function (n) {
            return Math.ceil(n);
          });

          if (dashValue.length % 2 === 1) {
            // [4, 2, 1] means |----  -    -- |----  -    -- |
            // so normalize it to be [4, 2, 1, 4, 2, 1]
            result.push(dashValue.concat(dashValue));
          } else {
            result.push(dashValue);
          }
        }
      }

      return result;
    }
    /**
     * Convert dash input into dashArray
     *
     * @param {DecalDashArrayY} dash dash input
     * @return {number[]} normolized dash array
     */


    function normalizeDashArrayY(dash) {
      if (!dash || typeof dash === 'object' && dash.length === 0) {
        return [0, 0];
      }

      if (isNumber(dash)) {
        var dashValue_1 = Math.ceil(dash);
        return [dashValue_1, dashValue_1];
      }

      var dashValue = map(dash, function (n) {
        return Math.ceil(n);
      });
      return dash.length % 2 ? dashValue.concat(dashValue) : dashValue;
    }
    /**
     * Get block length of each line. A block is the length of dash line and space.
     * For example, a line with [4, 1] has a dash line of 4 and a space of 1 after
     * that, so the block length of this line is 5.
     *
     * @param {number[][]} dash dash array of X or Y
     * @return {number[]} block length of each line
     */


    function getLineBlockLengthX(dash) {
      return map(dash, function (line) {
        return getLineBlockLengthY(line);
      });
    }

    function getLineBlockLengthY(dash) {
      var blockLength = 0;

      for (var i = 0; i < dash.length; ++i) {
        blockLength += dash[i];
      }

      if (dash.length % 2 === 1) {
        // [4, 2, 1] means |----  -    -- |----  -    -- |
        // So total length is (4 + 2 + 1) * 2
        return blockLength * 2;
      }

      return blockLength;
    }

    function decalVisual(ecModel, api) {
      ecModel.eachRawSeries(function (seriesModel) {
        if (ecModel.isSeriesFiltered(seriesModel)) {
          return;
        }

        var data = seriesModel.getData();

        if (data.hasItemVisual()) {
          data.each(function (idx) {
            var decal = data.getItemVisual(idx, 'decal');

            if (decal) {
              var itemStyle = data.ensureUniqueItemVisual(idx, 'style');
              itemStyle.decal = createOrUpdatePatternFromDecal(decal, api);
            }
          });
        }

        var decal = data.getVisual('decal');

        if (decal) {
          var style = data.getVisual('style');
          style.decal = createOrUpdatePatternFromDecal(decal, api);
        }
      });
    }

    var lifecycle = new Eventful();

    // The implementations will be registered when installing the component.
    // Avoid these code being bundled to the core module.

    var implsStore = {}; // TODO Type

    function registerImpl(name, impl) {
      if ("development" !== 'production') {
        if (implsStore[name]) {
          error("Already has an implementation of " + name + ".");
        }
      }

      implsStore[name] = impl;
    }
    function getImpl(name) {
      if ("development" !== 'production') {
        if (!implsStore[name]) {
          error("Implementation of " + name + " doesn't exists.");
        }
      }

      return implsStore[name];
    }

    var hasWindow = typeof window !== 'undefined';
    var version$1 = '5.4.0';
    var dependencies = {
      zrender: '5.4.0'
    };
    var TEST_FRAME_REMAIN_TIME = 1;
    var PRIORITY_PROCESSOR_SERIES_FILTER = 800; // Some data processors depends on the stack result dimension (to calculate data extent).
    // So data stack stage should be in front of data processing stage.

    var PRIORITY_PROCESSOR_DATASTACK = 900; // "Data filter" will block the stream, so it should be
    // put at the beginning of data processing.

    var PRIORITY_PROCESSOR_FILTER = 1000;
    var PRIORITY_PROCESSOR_DEFAULT = 2000;
    var PRIORITY_PROCESSOR_STATISTIC = 5000;
    var PRIORITY_VISUAL_LAYOUT = 1000;
    var PRIORITY_VISUAL_PROGRESSIVE_LAYOUT = 1100;
    var PRIORITY_VISUAL_GLOBAL = 2000;
    var PRIORITY_VISUAL_CHART = 3000;
    var PRIORITY_VISUAL_COMPONENT = 4000; // Visual property in data. Greater than `PRIORITY_VISUAL_COMPONENT` to enable to
    // overwrite the viusal result of component (like `visualMap`)
    // using data item specific setting (like itemStyle.xxx on data item)

    var PRIORITY_VISUAL_CHART_DATA_CUSTOM = 4500; // Greater than `PRIORITY_VISUAL_CHART_DATA_CUSTOM` to enable to layout based on
    // visual result like `symbolSize`.

    var PRIORITY_VISUAL_POST_CHART_LAYOUT = 4600;
    var PRIORITY_VISUAL_BRUSH = 5000;
    var PRIORITY_VISUAL_ARIA = 6000;
    var PRIORITY_VISUAL_DECAL = 7000;
    var PRIORITY = {
      PROCESSOR: {
        FILTER: PRIORITY_PROCESSOR_FILTER,
        SERIES_FILTER: PRIORITY_PROCESSOR_SERIES_FILTER,
        STATISTIC: PRIORITY_PROCESSOR_STATISTIC
      },
      VISUAL: {
        LAYOUT: PRIORITY_VISUAL_LAYOUT,
        PROGRESSIVE_LAYOUT: PRIORITY_VISUAL_PROGRESSIVE_LAYOUT,
        GLOBAL: PRIORITY_VISUAL_GLOBAL,
        CHART: PRIORITY_VISUAL_CHART,
        POST_CHART_LAYOUT: PRIORITY_VISUAL_POST_CHART_LAYOUT,
        COMPONENT: PRIORITY_VISUAL_COMPONENT,
        BRUSH: PRIORITY_VISUAL_BRUSH,
        CHART_ITEM: PRIORITY_VISUAL_CHART_DATA_CUSTOM,
        ARIA: PRIORITY_VISUAL_ARIA,
        DECAL: PRIORITY_VISUAL_DECAL
      }
    }; // Main process have three entries: `setOption`, `dispatchAction` and `resize`,
    // where they must not be invoked nestedly, except the only case: invoke
    // dispatchAction with updateMethod "none" in main process.
    // This flag is used to carry out this rule.
    // All events will be triggered out side main process (i.e. when !this[IN_MAIN_PROCESS]).

    var IN_MAIN_PROCESS_KEY = '__flagInMainProcess';
    var PENDING_UPDATE = '__pendingUpdate';
    var STATUS_NEEDS_UPDATE_KEY = '__needsUpdateStatus';
    var ACTION_REG = /^[a-zA-Z0-9_]+$/;
    var CONNECT_STATUS_KEY = '__connectUpdateStatus';
    var CONNECT_STATUS_PENDING = 0;
    var CONNECT_STATUS_UPDATING = 1;
    var CONNECT_STATUS_UPDATED = 2;

    function createRegisterEventWithLowercaseECharts(method) {
      return function () {
        var args = [];

        for (var _i = 0; _i < arguments.length; _i++) {
          args[_i] = arguments[_i];
        }

        if (this.isDisposed()) {
          disposedWarning(this.id);
          return;
        }

        return toLowercaseNameAndCallEventful(this, method, args);
      };
    }

    function createRegisterEventWithLowercaseMessageCenter(method) {
      return function () {
        var args = [];

        for (var _i = 0; _i < arguments.length; _i++) {
          args[_i] = arguments[_i];
        }

        return toLowercaseNameAndCallEventful(this, method, args);
      };
    }

    function toLowercaseNameAndCallEventful(host, method, args) {
      // `args[0]` is event name. Event name is all lowercase.
      args[0] = args[0] && args[0].toLowerCase();
      return Eventful.prototype[method].apply(host, args);
    }

    var MessageCenter =
    /** @class */
    function (_super) {
      __extends(MessageCenter, _super);

      function MessageCenter() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      return MessageCenter;
    }(Eventful);

    var messageCenterProto = MessageCenter.prototype;
    messageCenterProto.on = createRegisterEventWithLowercaseMessageCenter('on');
    messageCenterProto.off = createRegisterEventWithLowercaseMessageCenter('off'); // ---------------------------------------
    // Internal method names for class ECharts
    // ---------------------------------------

    var prepare;
    var prepareView;
    var updateDirectly;
    var updateMethods;
    var doConvertPixel;
    var updateStreamModes;
    var doDispatchAction;
    var flushPendingActions;
    var triggerUpdatedEvent;
    var bindRenderedEvent;
    var bindMouseEvent;
    var render;
    var renderComponents;
    var renderSeries;
    var createExtensionAPI;
    var enableConnect;
    var markStatusToUpdate;
    var applyChangedStates;

    var ECharts =
    /** @class */
    function (_super) {
      __extends(ECharts, _super);

      function ECharts(dom, // Theme name or themeOption.
      theme, opts) {
        var _this = _super.call(this, new ECEventProcessor()) || this;

        _this._chartsViews = [];
        _this._chartsMap = {};
        _this._componentsViews = [];
        _this._componentsMap = {}; // Can't dispatch action during rendering procedure

        _this._pendingActions = [];
        opts = opts || {}; // Get theme by name

        if (isString(theme)) {
          theme = themeStorage[theme];
        }

        _this._dom = dom;
        var defaultRenderer = 'canvas';
        var defaultCoarsePointer = 'auto';
        var defaultUseDirtyRect = false;

        if ("development" !== 'production') {
          var root =
          /* eslint-disable-next-line */
          hasWindow ? window : global;
          defaultRenderer = root.__ECHARTS__DEFAULT__RENDERER__ || defaultRenderer;
          defaultCoarsePointer = retrieve2(root.__ECHARTS__DEFAULT__COARSE_POINTER, defaultCoarsePointer);
          var devUseDirtyRect = root.__ECHARTS__DEFAULT__USE_DIRTY_RECT__;
          defaultUseDirtyRect = devUseDirtyRect == null ? defaultUseDirtyRect : devUseDirtyRect;
        }

        var zr = _this._zr = init(dom, {
          renderer: opts.renderer || defaultRenderer,
          devicePixelRatio: opts.devicePixelRatio,
          width: opts.width,
          height: opts.height,
          ssr: opts.ssr,
          useDirtyRect: retrieve2(opts.useDirtyRect, defaultUseDirtyRect),
          useCoarsePointer: retrieve2(opts.useCoarsePointer, defaultCoarsePointer),
          pointerSize: opts.pointerSize
        });
        _this._ssr = opts.ssr; // Expect 60 fps.

        _this._throttledZrFlush = throttle(bind(zr.flush, zr), 17);
        theme = clone(theme);
        theme && globalBackwardCompat(theme, true);
        _this._theme = theme;
        _this._locale = createLocaleObject(opts.locale || SYSTEM_LANG);
        _this._coordSysMgr = new CoordinateSystemManager();
        var api = _this._api = createExtensionAPI(_this); // Sort on demand

        function prioritySortFunc(a, b) {
          return a.__prio - b.__prio;
        }

        sort(visualFuncs, prioritySortFunc);
        sort(dataProcessorFuncs, prioritySortFunc);
        _this._scheduler = new Scheduler(_this, api, dataProcessorFuncs, visualFuncs);
        _this._messageCenter = new MessageCenter(); // Init mouse events

        _this._initEvents(); // In case some people write `window.onresize = chart.resize`


        _this.resize = bind(_this.resize, _this);
        zr.animation.on('frame', _this._onframe, _this);
        bindRenderedEvent(zr, _this);
        bindMouseEvent(zr, _this); // ECharts instance can be used as value.

        setAsPrimitive(_this);
        return _this;
      }

      ECharts.prototype._onframe = function () {
        if (this._disposed) {
          return;
        }

        applyChangedStates(this);
        var scheduler = this._scheduler; // Lazy update

        if (this[PENDING_UPDATE]) {
          var silent = this[PENDING_UPDATE].silent;
          this[IN_MAIN_PROCESS_KEY] = true;

          try {
            prepare(this);
            updateMethods.update.call(this, null, this[PENDING_UPDATE].updateParams);
          } catch (e) {
            this[IN_MAIN_PROCESS_KEY] = false;
            this[PENDING_UPDATE] = null;
            throw e;
          } // At present, in each frame, zrender performs:
          //   (1) animation step forward.
          //   (2) trigger('frame') (where this `_onframe` is called)
          //   (3) zrender flush (render).
          // If we do nothing here, since we use `setToFinal: true`, the step (3) above
          // will render the final state of the elements before the real animation started.


          this._zr.flush();

          this[IN_MAIN_PROCESS_KEY] = false;
          this[PENDING_UPDATE] = null;
          flushPendingActions.call(this, silent);
          triggerUpdatedEvent.call(this, silent);
        } // Avoid do both lazy update and progress in one frame.
        else if (scheduler.unfinished) {
            // Stream progress.
            var remainTime = TEST_FRAME_REMAIN_TIME;
            var ecModel = this._model;
            var api = this._api;
            scheduler.unfinished = false;

            do {
              var startTime = +new Date();
              scheduler.performSeriesTasks(ecModel); // Currently dataProcessorFuncs do not check threshold.

              scheduler.performDataProcessorTasks(ecModel);
              updateStreamModes(this, ecModel); // Do not update coordinate system here. Because that coord system update in
              // each frame is not a good user experience. So we follow the rule that
              // the extent of the coordinate system is determined in the first frame (the
              // frame is executed immediately after task reset.
              // this._coordSysMgr.update(ecModel, api);
              // console.log('--- ec frame visual ---', remainTime);

              scheduler.performVisualTasks(ecModel);
              renderSeries(this, this._model, api, 'remain', {});
              remainTime -= +new Date() - startTime;
            } while (remainTime > 0 && scheduler.unfinished); // Call flush explicitly for trigger finished event.


            if (!scheduler.unfinished) {
              this._zr.flush();
            } // Else, zr flushing be ensue within the same frame,
            // because zr flushing is after onframe event.

          }
      };

      ECharts.prototype.getDom = function () {
        return this._dom;
      };

      ECharts.prototype.getId = function () {
        return this.id;
      };

      ECharts.prototype.getZr = function () {
        return this._zr;
      };

      ECharts.prototype.isSSR = function () {
        return this._ssr;
      };
      /* eslint-disable-next-line */


      ECharts.prototype.setOption = function (option, notMerge, lazyUpdate) {
        if (this[IN_MAIN_PROCESS_KEY]) {
          if ("development" !== 'production') {
            error('`setOption` should not be called during main process.');
          }

          return;
        }

        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        var silent;
        var replaceMerge;
        var transitionOpt;

        if (isObject(notMerge)) {
          lazyUpdate = notMerge.lazyUpdate;
          silent = notMerge.silent;
          replaceMerge = notMerge.replaceMerge;
          transitionOpt = notMerge.transition;
          notMerge = notMerge.notMerge;
        }

        this[IN_MAIN_PROCESS_KEY] = true;

        if (!this._model || notMerge) {
          var optionManager = new OptionManager(this._api);
          var theme = this._theme;
          var ecModel = this._model = new GlobalModel();
          ecModel.scheduler = this._scheduler;
          ecModel.ssr = this._ssr;
          ecModel.init(null, null, null, theme, this._locale, optionManager);
        }

        this._model.setOption(option, {
          replaceMerge: replaceMerge
        }, optionPreprocessorFuncs);

        var updateParams = {
          seriesTransition: transitionOpt,
          optionChanged: true
        };

        if (lazyUpdate) {
          this[PENDING_UPDATE] = {
            silent: silent,
            updateParams: updateParams
          };
          this[IN_MAIN_PROCESS_KEY] = false; // `setOption(option, {lazyMode: true})` may be called when zrender has been slept.
          // It should wake it up to make sure zrender start to render at the next frame.

          this.getZr().wakeUp();
        } else {
          try {
            prepare(this);
            updateMethods.update.call(this, null, updateParams);
          } catch (e) {
            this[PENDING_UPDATE] = null;
            this[IN_MAIN_PROCESS_KEY] = false;
            throw e;
          } // Ensure zr refresh sychronously, and then pixel in canvas can be
          // fetched after `setOption`.


          if (!this._ssr) {
            // not use flush when using ssr mode.
            this._zr.flush();
          }

          this[PENDING_UPDATE] = null;
          this[IN_MAIN_PROCESS_KEY] = false;
          flushPendingActions.call(this, silent);
          triggerUpdatedEvent.call(this, silent);
        }
      };
      /**
       * @deprecated
       */


      ECharts.prototype.setTheme = function () {
        deprecateLog('ECharts#setTheme() is DEPRECATED in ECharts 3.0');
      }; // We don't want developers to use getModel directly.


      ECharts.prototype.getModel = function () {
        return this._model;
      };

      ECharts.prototype.getOption = function () {
        return this._model && this._model.getOption();
      };

      ECharts.prototype.getWidth = function () {
        return this._zr.getWidth();
      };

      ECharts.prototype.getHeight = function () {
        return this._zr.getHeight();
      };

      ECharts.prototype.getDevicePixelRatio = function () {
        return this._zr.painter.dpr
        /* eslint-disable-next-line */
        || hasWindow && window.devicePixelRatio || 1;
      };
      /**
       * Get canvas which has all thing rendered
       * @deprecated Use renderToCanvas instead.
       */


      ECharts.prototype.getRenderedCanvas = function (opts) {
        if ("development" !== 'production') {
          deprecateReplaceLog('getRenderedCanvas', 'renderToCanvas');
        }

        return this.renderToCanvas(opts);
      };

      ECharts.prototype.renderToCanvas = function (opts) {
        opts = opts || {};
        var painter = this._zr.painter;

        if ("development" !== 'production') {
          if (painter.type !== 'canvas') {
            throw new Error('renderToCanvas can only be used in the canvas renderer.');
          }
        }

        return painter.getRenderedCanvas({
          backgroundColor: opts.backgroundColor || this._model.get('backgroundColor'),
          pixelRatio: opts.pixelRatio || this.getDevicePixelRatio()
        });
      };

      ECharts.prototype.renderToSVGString = function (opts) {
        opts = opts || {};
        var painter = this._zr.painter;

        if ("development" !== 'production') {
          if (painter.type !== 'svg') {
            throw new Error('renderToSVGString can only be used in the svg renderer.');
          }
        }

        return painter.renderToString({
          useViewBox: opts.useViewBox
        });
      };
      /**
       * Get svg data url
       */


      ECharts.prototype.getSvgDataURL = function () {
        if (!env.svgSupported) {
          return;
        }

        var zr = this._zr;
        var list = zr.storage.getDisplayList(); // Stop animations

        each(list, function (el) {
          el.stopAnimation(null, true);
        });
        return zr.painter.toDataURL();
      };

      ECharts.prototype.getDataURL = function (opts) {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        opts = opts || {};
        var excludeComponents = opts.excludeComponents;
        var ecModel = this._model;
        var excludesComponentViews = [];
        var self = this;
        each(excludeComponents, function (componentType) {
          ecModel.eachComponent({
            mainType: componentType
          }, function (component) {
            var view = self._componentsMap[component.__viewId];

            if (!view.group.ignore) {
              excludesComponentViews.push(view);
              view.group.ignore = true;
            }
          });
        });
        var url = this._zr.painter.getType() === 'svg' ? this.getSvgDataURL() : this.renderToCanvas(opts).toDataURL('image/' + (opts && opts.type || 'png'));
        each(excludesComponentViews, function (view) {
          view.group.ignore = false;
        });
        return url;
      };

      ECharts.prototype.getConnectedDataURL = function (opts) {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        var isSvg = opts.type === 'svg';
        var groupId = this.group;
        var mathMin = Math.min;
        var mathMax = Math.max;
        var MAX_NUMBER = Infinity;

        if (connectedGroups[groupId]) {
          var left_1 = MAX_NUMBER;
          var top_1 = MAX_NUMBER;
          var right_1 = -MAX_NUMBER;
          var bottom_1 = -MAX_NUMBER;
          var canvasList_1 = [];
          var dpr_1 = opts && opts.pixelRatio || this.getDevicePixelRatio();
          each(instances$1, function (chart, id) {
            if (chart.group === groupId) {
              var canvas = isSvg ? chart.getZr().painter.getSvgDom().innerHTML : chart.renderToCanvas(clone(opts));
              var boundingRect = chart.getDom().getBoundingClientRect();
              left_1 = mathMin(boundingRect.left, left_1);
              top_1 = mathMin(boundingRect.top, top_1);
              right_1 = mathMax(boundingRect.right, right_1);
              bottom_1 = mathMax(boundingRect.bottom, bottom_1);
              canvasList_1.push({
                dom: canvas,
                left: boundingRect.left,
                top: boundingRect.top
              });
            }
          });
          left_1 *= dpr_1;
          top_1 *= dpr_1;
          right_1 *= dpr_1;
          bottom_1 *= dpr_1;
          var width = right_1 - left_1;
          var height = bottom_1 - top_1;
          var targetCanvas = platformApi.createCanvas();
          var zr_1 = init(targetCanvas, {
            renderer: isSvg ? 'svg' : 'canvas'
          });
          zr_1.resize({
            width: width,
            height: height
          });

          if (isSvg) {
            var content_1 = '';
            each(canvasList_1, function (item) {
              var x = item.left - left_1;
              var y = item.top - top_1;
              content_1 += '<g transform="translate(' + x + ',' + y + ')">' + item.dom + '</g>';
            });
            zr_1.painter.getSvgRoot().innerHTML = content_1;

            if (opts.connectedBackgroundColor) {
              zr_1.painter.setBackgroundColor(opts.connectedBackgroundColor);
            }

            zr_1.refreshImmediately();
            return zr_1.painter.toDataURL();
          } else {
            // Background between the charts
            if (opts.connectedBackgroundColor) {
              zr_1.add(new Rect({
                shape: {
                  x: 0,
                  y: 0,
                  width: width,
                  height: height
                },
                style: {
                  fill: opts.connectedBackgroundColor
                }
              }));
            }

            each(canvasList_1, function (item) {
              var img = new ZRImage({
                style: {
                  x: item.left * dpr_1 - left_1,
                  y: item.top * dpr_1 - top_1,
                  image: item.dom
                }
              });
              zr_1.add(img);
            });
            zr_1.refreshImmediately();
            return targetCanvas.toDataURL('image/' + (opts && opts.type || 'png'));
          }
        } else {
          return this.getDataURL(opts);
        }
      };

      ECharts.prototype.convertToPixel = function (finder, value) {
        return doConvertPixel(this, 'convertToPixel', finder, value);
      };

      ECharts.prototype.convertFromPixel = function (finder, value) {
        return doConvertPixel(this, 'convertFromPixel', finder, value);
      };
      /**
       * Is the specified coordinate systems or components contain the given pixel point.
       * @param {Array|number} value
       * @return {boolean} result
       */


      ECharts.prototype.containPixel = function (finder, value) {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        var ecModel = this._model;
        var result;
        var findResult = parseFinder(ecModel, finder);
        each(findResult, function (models, key) {
          key.indexOf('Models') >= 0 && each(models, function (model) {
            var coordSys = model.coordinateSystem;

            if (coordSys && coordSys.containPoint) {
              result = result || !!coordSys.containPoint(value);
            } else if (key === 'seriesModels') {
              var view = this._chartsMap[model.__viewId];

              if (view && view.containPoint) {
                result = result || view.containPoint(value, model);
              } else {
                if ("development" !== 'production') {
                  console.warn(key + ': ' + (view ? 'The found component do not support containPoint.' : 'No view mapping to the found component.'));
                }
              }
            } else {
              if ("development" !== 'production') {
                console.warn(key + ': containPoint is not supported');
              }
            }
          }, this);
        }, this);
        return !!result;
      };
      /**
       * Get visual from series or data.
       * @param finder
       *        If string, e.g., 'series', means {seriesIndex: 0}.
       *        If Object, could contain some of these properties below:
       *        {
       *            seriesIndex / seriesId / seriesName,
       *            dataIndex / dataIndexInside
       *        }
       *        If dataIndex is not specified, series visual will be fetched,
       *        but not data item visual.
       *        If all of seriesIndex, seriesId, seriesName are not specified,
       *        visual will be fetched from first series.
       * @param visualType 'color', 'symbol', 'symbolSize'
       */


      ECharts.prototype.getVisual = function (finder, visualType) {
        var ecModel = this._model;
        var parsedFinder = parseFinder(ecModel, finder, {
          defaultMainType: 'series'
        });
        var seriesModel = parsedFinder.seriesModel;

        if ("development" !== 'production') {
          if (!seriesModel) {
            console.warn('There is no specified seires model');
          }
        }

        var data = seriesModel.getData();
        var dataIndexInside = parsedFinder.hasOwnProperty('dataIndexInside') ? parsedFinder.dataIndexInside : parsedFinder.hasOwnProperty('dataIndex') ? data.indexOfRawIndex(parsedFinder.dataIndex) : null;
        return dataIndexInside != null ? getItemVisualFromData(data, dataIndexInside, visualType) : getVisualFromData(data, visualType);
      };
      /**
       * Get view of corresponding component model
       */


      ECharts.prototype.getViewOfComponentModel = function (componentModel) {
        return this._componentsMap[componentModel.__viewId];
      };
      /**
       * Get view of corresponding series model
       */


      ECharts.prototype.getViewOfSeriesModel = function (seriesModel) {
        return this._chartsMap[seriesModel.__viewId];
      };

      ECharts.prototype._initEvents = function () {
        var _this = this;

        each(MOUSE_EVENT_NAMES, function (eveName) {
          var handler = function (e) {
            var ecModel = _this.getModel();

            var el = e.target;
            var params;
            var isGlobalOut = eveName === 'globalout'; // no e.target when 'globalout'.

            if (isGlobalOut) {
              params = {};
            } else {
              el && findEventDispatcher(el, function (parent) {
                var ecData = getECData(parent);

                if (ecData && ecData.dataIndex != null) {
                  var dataModel = ecData.dataModel || ecModel.getSeriesByIndex(ecData.seriesIndex);
                  params = dataModel && dataModel.getDataParams(ecData.dataIndex, ecData.dataType) || {};
                  return true;
                } // If element has custom eventData of components
                else if (ecData.eventData) {
                    params = extend({}, ecData.eventData);
                    return true;
                  }
              }, true);
            } // Contract: if params prepared in mouse event,
            // these properties must be specified:
            // {
            //    componentType: string (component main type)
            //    componentIndex: number
            // }
            // Otherwise event query can not work.


            if (params) {
              var componentType = params.componentType;
              var componentIndex = params.componentIndex; // Special handling for historic reason: when trigger by
              // markLine/markPoint/markArea, the componentType is
              // 'markLine'/'markPoint'/'markArea', but we should better
              // enable them to be queried by seriesIndex, since their
              // option is set in each series.

              if (componentType === 'markLine' || componentType === 'markPoint' || componentType === 'markArea') {
                componentType = 'series';
                componentIndex = params.seriesIndex;
              }

              var model = componentType && componentIndex != null && ecModel.getComponent(componentType, componentIndex);
              var view = model && _this[model.mainType === 'series' ? '_chartsMap' : '_componentsMap'][model.__viewId];

              if ("development" !== 'production') {
                // `event.componentType` and `event[componentTpype + 'Index']` must not
                // be missed, otherwise there is no way to distinguish source component.
                // See `dataFormat.getDataParams`.
                if (!isGlobalOut && !(model && view)) {
                  console.warn('model or view can not be found by params');
                }
              }

              params.event = e;
              params.type = eveName;
              _this._$eventProcessor.eventInfo = {
                targetEl: el,
                packedEvent: params,
                model: model,
                view: view
              };

              _this.trigger(eveName, params);
            }
          }; // Consider that some component (like tooltip, brush, ...)
          // register zr event handler, but user event handler might
          // do anything, such as call `setOption` or `dispatchAction`,
          // which probably update any of the content and probably
          // cause problem if it is called previous other inner handlers.


          handler.zrEventfulCallAtLast = true;

          _this._zr.on(eveName, handler, _this);
        });
        each(eventActionMap, function (actionType, eventType) {
          _this._messageCenter.on(eventType, function (event) {
            this.trigger(eventType, event);
          }, _this);
        }); // Extra events
        // TODO register?

        each(['selectchanged'], function (eventType) {
          _this._messageCenter.on(eventType, function (event) {
            this.trigger(eventType, event);
          }, _this);
        });
        handleLegacySelectEvents(this._messageCenter, this, this._api);
      };

      ECharts.prototype.isDisposed = function () {
        return this._disposed;
      };

      ECharts.prototype.clear = function () {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        this.setOption({
          series: []
        }, true);
      };

      ECharts.prototype.dispose = function () {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        this._disposed = true;
        var dom = this.getDom();

        if (dom) {
          setAttribute(this.getDom(), DOM_ATTRIBUTE_KEY, '');
        }

        var chart = this;
        var api = chart._api;
        var ecModel = chart._model;
        each(chart._componentsViews, function (component) {
          component.dispose(ecModel, api);
        });
        each(chart._chartsViews, function (chart) {
          chart.dispose(ecModel, api);
        }); // Dispose after all views disposed

        chart._zr.dispose(); // Set properties to null.
        // To reduce the memory cost in case the top code still holds this instance unexpectedly.


        chart._dom = chart._model = chart._chartsMap = chart._componentsMap = chart._chartsViews = chart._componentsViews = chart._scheduler = chart._api = chart._zr = chart._throttledZrFlush = chart._theme = chart._coordSysMgr = chart._messageCenter = null;
        delete instances$1[chart.id];
      };
      /**
       * Resize the chart
       */


      ECharts.prototype.resize = function (opts) {
        if (this[IN_MAIN_PROCESS_KEY]) {
          if ("development" !== 'production') {
            error('`resize` should not be called during main process.');
          }

          return;
        }

        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        this._zr.resize(opts);

        var ecModel = this._model; // Resize loading effect

        this._loadingFX && this._loadingFX.resize();

        if (!ecModel) {
          return;
        }

        var needPrepare = ecModel.resetOption('media');
        var silent = opts && opts.silent; // There is some real cases that:
        // chart.setOption(option, { lazyUpdate: true });
        // chart.resize();

        if (this[PENDING_UPDATE]) {
          if (silent == null) {
            silent = this[PENDING_UPDATE].silent;
          }

          needPrepare = true;
          this[PENDING_UPDATE] = null;
        }

        this[IN_MAIN_PROCESS_KEY] = true;

        try {
          needPrepare && prepare(this);
          updateMethods.update.call(this, {
            type: 'resize',
            animation: extend({
              // Disable animation
              duration: 0
            }, opts && opts.animation)
          });
        } catch (e) {
          this[IN_MAIN_PROCESS_KEY] = false;
          throw e;
        }

        this[IN_MAIN_PROCESS_KEY] = false;
        flushPendingActions.call(this, silent);
        triggerUpdatedEvent.call(this, silent);
      };

      ECharts.prototype.showLoading = function (name, cfg) {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        if (isObject(name)) {
          cfg = name;
          name = '';
        }

        name = name || 'default';
        this.hideLoading();

        if (!loadingEffects[name]) {
          if ("development" !== 'production') {
            console.warn('Loading effects ' + name + ' not exists.');
          }

          return;
        }

        var el = loadingEffects[name](this._api, cfg);
        var zr = this._zr;
        this._loadingFX = el;
        zr.add(el);
      };
      /**
       * Hide loading effect
       */


      ECharts.prototype.hideLoading = function () {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        this._loadingFX && this._zr.remove(this._loadingFX);
        this._loadingFX = null;
      };

      ECharts.prototype.makeActionFromEvent = function (eventObj) {
        var payload = extend({}, eventObj);
        payload.type = eventActionMap[eventObj.type];
        return payload;
      };
      /**
       * @param opt If pass boolean, means opt.silent
       * @param opt.silent Default `false`. Whether trigger events.
       * @param opt.flush Default `undefined`.
       *        true: Flush immediately, and then pixel in canvas can be fetched
       *            immediately. Caution: it might affect performance.
       *        false: Not flush.
       *        undefined: Auto decide whether perform flush.
       */


      ECharts.prototype.dispatchAction = function (payload, opt) {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        if (!isObject(opt)) {
          opt = {
            silent: !!opt
          };
        }

        if (!actions[payload.type]) {
          return;
        } // Avoid dispatch action before setOption. Especially in `connect`.


        if (!this._model) {
          return;
        } // May dispatchAction in rendering procedure


        if (this[IN_MAIN_PROCESS_KEY]) {
          this._pendingActions.push(payload);

          return;
        }

        var silent = opt.silent;
        doDispatchAction.call(this, payload, silent);
        var flush = opt.flush;

        if (flush) {
          this._zr.flush();
        } else if (flush !== false && env.browser.weChat) {
          // In WeChat embedded browser, `requestAnimationFrame` and `setInterval`
          // hang when sliding page (on touch event), which cause that zr does not
          // refresh until user interaction finished, which is not expected.
          // But `dispatchAction` may be called too frequently when pan on touch
          // screen, which impacts performance if do not throttle them.
          this._throttledZrFlush();
        }

        flushPendingActions.call(this, silent);
        triggerUpdatedEvent.call(this, silent);
      };

      ECharts.prototype.updateLabelLayout = function () {
        lifecycle.trigger('series:layoutlabels', this._model, this._api, {
          // Not adding series labels.
          // TODO
          updatedSeries: []
        });
      };

      ECharts.prototype.appendData = function (params) {
        if (this._disposed) {
          disposedWarning(this.id);
          return;
        }

        var seriesIndex = params.seriesIndex;
        var ecModel = this.getModel();
        var seriesModel = ecModel.getSeriesByIndex(seriesIndex);

        if ("development" !== 'production') {
          assert(params.data && seriesModel);
        }

        seriesModel.appendData(params); // Note: `appendData` does not support that update extent of coordinate
        // system, util some scenario require that. In the expected usage of
        // `appendData`, the initial extent of coordinate system should better
        // be fixed by axis `min`/`max` setting or initial data, otherwise if
        // the extent changed while `appendData`, the location of the painted
        // graphic elements have to be changed, which make the usage of
        // `appendData` meaningless.

        this._scheduler.unfinished = true;
        this.getZr().wakeUp();
      }; // A work around for no `internal` modifier in ts yet but
      // need to strictly hide private methods to JS users.


      ECharts.internalField = function () {
        prepare = function (ecIns) {
          var scheduler = ecIns._scheduler;
          scheduler.restorePipelines(ecIns._model);
          scheduler.prepareStageTasks();
          prepareView(ecIns, true);
          prepareView(ecIns, false);
          scheduler.plan();
        };
        /**
         * Prepare view instances of charts and components
         */


        prepareView = function (ecIns, isComponent) {
          var ecModel = ecIns._model;
          var scheduler = ecIns._scheduler;
          var viewList = isComponent ? ecIns._componentsViews : ecIns._chartsViews;
          var viewMap = isComponent ? ecIns._componentsMap : ecIns._chartsMap;
          var zr = ecIns._zr;
          var api = ecIns._api;

          for (var i = 0; i < viewList.length; i++) {
            viewList[i].__alive = false;
          }

          isComponent ? ecModel.eachComponent(function (componentType, model) {
            componentType !== 'series' && doPrepare(model);
          }) : ecModel.eachSeries(doPrepare);

          function doPrepare(model) {
            // By default view will be reused if possible for the case that `setOption` with "notMerge"
            // mode and need to enable transition animation. (Usually, when they have the same id, or
            // especially no id but have the same type & name & index. See the `model.id` generation
            // rule in `makeIdAndName` and `viewId` generation rule here).
            // But in `replaceMerge` mode, this feature should be able to disabled when it is clear that
            // the new model has nothing to do with the old model.
            var requireNewView = model.__requireNewView; // This command should not work twice.

            model.__requireNewView = false; // Consider: id same and type changed.

            var viewId = '_ec_' + model.id + '_' + model.type;
            var view = !requireNewView && viewMap[viewId];

            if (!view) {
              var classType = parseClassType(model.type);
              var Clazz = isComponent ? ComponentView.getClass(classType.main, classType.sub) : // FIXME:TS
              // (ChartView as ChartViewConstructor).getClass('series', classType.sub)
              // For backward compat, still support a chart type declared as only subType
              // like "liquidfill", but recommend "series.liquidfill"
              // But need a base class to make a type series.
              ChartView.getClass(classType.sub);

              if ("development" !== 'production') {
                assert(Clazz, classType.sub + ' does not exist.');
              }

              view = new Clazz();
              view.init(ecModel, api);
              viewMap[viewId] = view;
              viewList.push(view);
              zr.add(view.group);
            }

            model.__viewId = view.__id = viewId;
            view.__alive = true;
            view.__model = model;
            view.group.__ecComponentInfo = {
              mainType: model.mainType,
              index: model.componentIndex
            };
            !isComponent && scheduler.prepareView(view, model, ecModel, api);
          }

          for (var i = 0; i < viewList.length;) {
            var view = viewList[i];

            if (!view.__alive) {
              !isComponent && view.renderTask.dispose();
              zr.remove(view.group);
              view.dispose(ecModel, api);
              viewList.splice(i, 1);

              if (viewMap[view.__id] === view) {
                delete viewMap[view.__id];
              }

              view.__id = view.group.__ecComponentInfo = null;
            } else {
              i++;
            }
          }
        };

        updateDirectly = function (ecIns, method, payload, mainType, subType) {
          var ecModel = ecIns._model;
          ecModel.setUpdatePayload(payload); // broadcast

          if (!mainType) {
            // FIXME
            // Chart will not be update directly here, except set dirty.
            // But there is no such scenario now.
            each([].concat(ecIns._componentsViews).concat(ecIns._chartsViews), callView);
            return;
          }

          var query = {};
          query[mainType + 'Id'] = payload[mainType + 'Id'];
          query[mainType + 'Index'] = payload[mainType + 'Index'];
          query[mainType + 'Name'] = payload[mainType + 'Name'];
          var condition = {
            mainType: mainType,
            query: query
          };
          subType && (condition.subType = subType); // subType may be '' by parseClassType;

          var excludeSeriesId = payload.excludeSeriesId;
          var excludeSeriesIdMap;

          if (excludeSeriesId != null) {
            excludeSeriesIdMap = createHashMap();
            each(normalizeToArray(excludeSeriesId), function (id) {
              var modelId = convertOptionIdName(id, null);

              if (modelId != null) {
                excludeSeriesIdMap.set(modelId, true);
              }
            });
          } // If dispatchAction before setOption, do nothing.


          ecModel && ecModel.eachComponent(condition, function (model) {
            var isExcluded = excludeSeriesIdMap && excludeSeriesIdMap.get(model.id) !== null;

            if (isExcluded) {
              return;
            }

            if (isHighDownPayload(payload)) {
              if (model instanceof SeriesModel) {
                if (payload.type === HIGHLIGHT_ACTION_TYPE && !payload.notBlur && !model.get(['emphasis', 'disabled'])) {
                  blurSeriesFromHighlightPayload(model, payload, ecIns._api);
                }
              } else {
                var _a = findComponentHighDownDispatchers(model.mainType, model.componentIndex, payload.name, ecIns._api),
                    focusSelf = _a.focusSelf,
                    dispatchers = _a.dispatchers;

                if (payload.type === HIGHLIGHT_ACTION_TYPE && focusSelf && !payload.notBlur) {
                  blurComponent(model.mainType, model.componentIndex, ecIns._api);
                } // PENDING:
                // Whether to put this "enter emphasis" code in `ComponentView`,
                // which will be the same as `ChartView` but might be not necessary
                // and will be far from this logic.


                if (dispatchers) {
                  each(dispatchers, function (dispatcher) {
                    payload.type === HIGHLIGHT_ACTION_TYPE ? enterEmphasis(dispatcher) : leaveEmphasis(dispatcher);
                  });
                }
              }
            } else if (isSelectChangePayload(payload)) {
              // TODO geo
              if (model instanceof SeriesModel) {
                toggleSelectionFromPayload(model, payload, ecIns._api);
                updateSeriesElementSelection(model);
                markStatusToUpdate(ecIns);
              }
            }
          }, ecIns);
          ecModel && ecModel.eachComponent(condition, function (model) {
            var isExcluded = excludeSeriesIdMap && excludeSeriesIdMap.get(model.id) !== null;

            if (isExcluded) {
              return;
            }
            callView(ecIns[mainType === 'series' ? '_chartsMap' : '_componentsMap'][model.__viewId]);
          }, ecIns);

          function callView(view) {
            view && view.__alive && view[method] && view[method](view.__model, ecModel, ecIns._api, payload);
          }
        };

        updateMethods = {
          prepareAndUpdate: function (payload) {
            prepare(this);
            updateMethods.update.call(this, payload, {
              // Needs to mark option changed if newOption is given.
              // It's from MagicType.
              // TODO If use a separate flag optionChanged in payload?
              optionChanged: payload.newOption != null
            });
          },
          update: function (payload, updateParams) {
            var ecModel = this._model;
            var api = this._api;
            var zr = this._zr;
            var coordSysMgr = this._coordSysMgr;
            var scheduler = this._scheduler; // update before setOption

            if (!ecModel) {
              return;
            }

            ecModel.setUpdatePayload(payload);
            scheduler.restoreData(ecModel, payload);
            scheduler.performSeriesTasks(ecModel); // TODO
            // Save total ecModel here for undo/redo (after restoring data and before processing data).
            // Undo (restoration of total ecModel) can be carried out in 'action' or outside API call.
            // Create new coordinate system each update
            // In LineView may save the old coordinate system and use it to get the original point.

            coordSysMgr.create(ecModel, api);
            scheduler.performDataProcessorTasks(ecModel, payload); // Current stream render is not supported in data process. So we can update
            // stream modes after data processing, where the filtered data is used to
            // determine whether to use progressive rendering.

            updateStreamModes(this, ecModel); // We update stream modes before coordinate system updated, then the modes info
            // can be fetched when coord sys updating (consider the barGrid extent fix). But
            // the drawback is the full coord info can not be fetched. Fortunately this full
            // coord is not required in stream mode updater currently.

            coordSysMgr.update(ecModel, api);
            clearColorPalette(ecModel);
            scheduler.performVisualTasks(ecModel, payload);
            render(this, ecModel, api, payload, updateParams); // Set background

            var backgroundColor = ecModel.get('backgroundColor') || 'transparent';
            var darkMode = ecModel.get('darkMode');
            zr.setBackgroundColor(backgroundColor); // Force set dark mode.

            if (darkMode != null && darkMode !== 'auto') {
              zr.setDarkMode(darkMode);
            }

            lifecycle.trigger('afterupdate', ecModel, api);
          },
          updateTransform: function (payload) {
            var _this = this;

            var ecModel = this._model;
            var api = this._api; // update before setOption

            if (!ecModel) {
              return;
            }

            ecModel.setUpdatePayload(payload); // ChartView.markUpdateMethod(payload, 'updateTransform');

            var componentDirtyList = [];
            ecModel.eachComponent(function (componentType, componentModel) {
              if (componentType === 'series') {
                return;
              }

              var componentView = _this.getViewOfComponentModel(componentModel);

              if (componentView && componentView.__alive) {
                if (componentView.updateTransform) {
                  var result = componentView.updateTransform(componentModel, ecModel, api, payload);
                  result && result.update && componentDirtyList.push(componentView);
                } else {
                  componentDirtyList.push(componentView);
                }
              }
            });
            var seriesDirtyMap = createHashMap();
            ecModel.eachSeries(function (seriesModel) {
              var chartView = _this._chartsMap[seriesModel.__viewId];

              if (chartView.updateTransform) {
                var result = chartView.updateTransform(seriesModel, ecModel, api, payload);
                result && result.update && seriesDirtyMap.set(seriesModel.uid, 1);
              } else {
                seriesDirtyMap.set(seriesModel.uid, 1);
              }
            });
            clearColorPalette(ecModel); // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.
            // this._scheduler.performVisualTasks(ecModel, payload, 'layout', true);

            this._scheduler.performVisualTasks(ecModel, payload, {
              setDirty: true,
              dirtyMap: seriesDirtyMap
            }); // Currently, not call render of components. Geo render cost a lot.
            // renderComponents(ecIns, ecModel, api, payload, componentDirtyList);


            renderSeries(this, ecModel, api, payload, {}, seriesDirtyMap);
            lifecycle.trigger('afterupdate', ecModel, api);
          },
          updateView: function (payload) {
            var ecModel = this._model; // update before setOption

            if (!ecModel) {
              return;
            }

            ecModel.setUpdatePayload(payload);
            ChartView.markUpdateMethod(payload, 'updateView');
            clearColorPalette(ecModel); // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.

            this._scheduler.performVisualTasks(ecModel, payload, {
              setDirty: true
            });

            render(this, ecModel, this._api, payload, {});
            lifecycle.trigger('afterupdate', ecModel, this._api);
          },
          updateVisual: function (payload) {
            // updateMethods.update.call(this, payload);
            var _this = this;

            var ecModel = this._model; // update before setOption

            if (!ecModel) {
              return;
            }

            ecModel.setUpdatePayload(payload); // clear all visual

            ecModel.eachSeries(function (seriesModel) {
              seriesModel.getData().clearAllVisual();
            }); // Perform visual

            ChartView.markUpdateMethod(payload, 'updateVisual');
            clearColorPalette(ecModel); // Keep pipe to the exist pipeline because it depends on the render task of the full pipeline.

            this._scheduler.performVisualTasks(ecModel, payload, {
              visualType: 'visual',
              setDirty: true
            });

            ecModel.eachComponent(function (componentType, componentModel) {
              if (componentType !== 'series') {
                var componentView = _this.getViewOfComponentModel(componentModel);

                componentView && componentView.__alive && componentView.updateVisual(componentModel, ecModel, _this._api, payload);
              }
            });
            ecModel.eachSeries(function (seriesModel) {
              var chartView = _this._chartsMap[seriesModel.__viewId];
              chartView.updateVisual(seriesModel, ecModel, _this._api, payload);
            });
            lifecycle.trigger('afterupdate', ecModel, this._api);
          },
          updateLayout: function (payload) {
            updateMethods.update.call(this, payload);
          }
        };

        doConvertPixel = function (ecIns, methodName, finder, value) {
          if (ecIns._disposed) {
            disposedWarning(ecIns.id);
            return;
          }

          var ecModel = ecIns._model;

          var coordSysList = ecIns._coordSysMgr.getCoordinateSystems();

          var result;
          var parsedFinder = parseFinder(ecModel, finder);

          for (var i = 0; i < coordSysList.length; i++) {
            var coordSys = coordSysList[i];

            if (coordSys[methodName] && (result = coordSys[methodName](ecModel, parsedFinder, value)) != null) {
              return result;
            }
          }

          if ("development" !== 'production') {
            console.warn('No coordinate system that supports ' + methodName + ' found by the given finder.');
          }
        };

        updateStreamModes = function (ecIns, ecModel) {
          var chartsMap = ecIns._chartsMap;
          var scheduler = ecIns._scheduler;
          ecModel.eachSeries(function (seriesModel) {
            scheduler.updateStreamModes(seriesModel, chartsMap[seriesModel.__viewId]);
          });
        };

        doDispatchAction = function (payload, silent) {
          var _this = this;

          var ecModel = this.getModel();
          var payloadType = payload.type;
          var escapeConnect = payload.escapeConnect;
          var actionWrap = actions[payloadType];
          var actionInfo = actionWrap.actionInfo;
          var cptTypeTmp = (actionInfo.update || 'update').split(':');
          var updateMethod = cptTypeTmp.pop();
          var cptType = cptTypeTmp[0] != null && parseClassType(cptTypeTmp[0]);
          this[IN_MAIN_PROCESS_KEY] = true;
          var payloads = [payload];
          var batched = false; // Batch action

          if (payload.batch) {
            batched = true;
            payloads = map(payload.batch, function (item) {
              item = defaults(extend({}, item), payload);
              item.batch = null;
              return item;
            });
          }

          var eventObjBatch = [];
          var eventObj;
          var isSelectChange = isSelectChangePayload(payload);
          var isHighDown = isHighDownPayload(payload); // Only leave blur once if there are multiple batches.

          if (isHighDown) {
            allLeaveBlur(this._api);
          }

          each(payloads, function (batchItem) {
            // Action can specify the event by return it.
            eventObj = actionWrap.action(batchItem, _this._model, _this._api); // Emit event outside

            eventObj = eventObj || extend({}, batchItem); // Convert type to eventType

            eventObj.type = actionInfo.event || eventObj.type;
            eventObjBatch.push(eventObj); // light update does not perform data process, layout and visual.

            if (isHighDown) {
              var _a = preParseFinder(payload),
                  queryOptionMap = _a.queryOptionMap,
                  mainTypeSpecified = _a.mainTypeSpecified;

              var componentMainType = mainTypeSpecified ? queryOptionMap.keys()[0] : 'series';
              updateDirectly(_this, updateMethod, batchItem, componentMainType);
              markStatusToUpdate(_this);
            } else if (isSelectChange) {
              // At present `dispatchAction({ type: 'select', ... })` is not supported on components.
              // geo still use 'geoselect'.
              updateDirectly(_this, updateMethod, batchItem, 'series');
              markStatusToUpdate(_this);
            } else if (cptType) {
              updateDirectly(_this, updateMethod, batchItem, cptType.main, cptType.sub);
            }
          });

          if (updateMethod !== 'none' && !isHighDown && !isSelectChange && !cptType) {
            try {
              // Still dirty
              if (this[PENDING_UPDATE]) {
                prepare(this);
                updateMethods.update.call(this, payload);
                this[PENDING_UPDATE] = null;
              } else {
                updateMethods[updateMethod].call(this, payload);
              }
            } catch (e) {
              this[IN_MAIN_PROCESS_KEY] = false;
              throw e;
            }
          } // Follow the rule of action batch


          if (batched) {
            eventObj = {
              type: actionInfo.event || payloadType,
              escapeConnect: escapeConnect,
              batch: eventObjBatch
            };
          } else {
            eventObj = eventObjBatch[0];
          }

          this[IN_MAIN_PROCESS_KEY] = false;

          if (!silent) {
            var messageCenter = this._messageCenter;
            messageCenter.trigger(eventObj.type, eventObj); // Extra triggered 'selectchanged' event

            if (isSelectChange) {
              var newObj = {
                type: 'selectchanged',
                escapeConnect: escapeConnect,
                selected: getAllSelectedIndices(ecModel),
                isFromClick: payload.isFromClick || false,
                fromAction: payload.type,
                fromActionPayload: payload
              };
              messageCenter.trigger(newObj.type, newObj);
            }
          }
        };

        flushPendingActions = function (silent) {
          var pendingActions = this._pendingActions;

          while (pendingActions.length) {
            var payload = pendingActions.shift();
            doDispatchAction.call(this, payload, silent);
          }
        };

        triggerUpdatedEvent = function (silent) {
          !silent && this.trigger('updated');
        };
        /**
         * Event `rendered` is triggered when zr
         * rendered. It is useful for realtime
         * snapshot (reflect animation).
         *
         * Event `finished` is triggered when:
         * (1) zrender rendering finished.
         * (2) initial animation finished.
         * (3) progressive rendering finished.
         * (4) no pending action.
         * (5) no delayed setOption needs to be processed.
         */


        bindRenderedEvent = function (zr, ecIns) {
          zr.on('rendered', function (params) {
            ecIns.trigger('rendered', params); // The `finished` event should not be triggered repeatedly,
            // so it should only be triggered when rendering indeed happens
            // in zrender. (Consider the case that dipatchAction is keep
            // triggering when mouse move).

            if ( // Although zr is dirty if initial animation is not finished
            // and this checking is called on frame, we also check
            // animation finished for robustness.
            zr.animation.isFinished() && !ecIns[PENDING_UPDATE] && !ecIns._scheduler.unfinished && !ecIns._pendingActions.length) {
              ecIns.trigger('finished');
            }
          });
        };

        bindMouseEvent = function (zr, ecIns) {
          zr.on('mouseover', function (e) {
            var el = e.target;
            var dispatcher = findEventDispatcher(el, isHighDownDispatcher);

            if (dispatcher) {
              handleGlobalMouseOverForHighDown(dispatcher, e, ecIns._api);
              markStatusToUpdate(ecIns);
            }
          }).on('mouseout', function (e) {
            var el = e.target;
            var dispatcher = findEventDispatcher(el, isHighDownDispatcher);

            if (dispatcher) {
              handleGlobalMouseOutForHighDown(dispatcher, e, ecIns._api);
              markStatusToUpdate(ecIns);
            }
          }).on('click', function (e) {
            var el = e.target;
            var dispatcher = findEventDispatcher(el, function (target) {
              return getECData(target).dataIndex != null;
            }, true);

            if (dispatcher) {
              var actionType = dispatcher.selected ? 'unselect' : 'select';
              var ecData = getECData(dispatcher);

              ecIns._api.dispatchAction({
                type: actionType,
                dataType: ecData.dataType,
                dataIndexInside: ecData.dataIndex,
                seriesIndex: ecData.seriesIndex,
                isFromClick: true
              });
            }
          });
        };

        function clearColorPalette(ecModel) {
          ecModel.clearColorPalette();
          ecModel.eachSeries(function (seriesModel) {
            seriesModel.clearColorPalette();
          });
        }

        function allocateZlevels(ecModel) {
          var componentZLevels = [];
          var seriesZLevels = [];
          var hasSeperateZLevel = false;
          ecModel.eachComponent(function (componentType, componentModel) {
            var zlevel = componentModel.get('zlevel') || 0;
            var z = componentModel.get('z') || 0;
            var zlevelKey = componentModel.getZLevelKey();
            hasSeperateZLevel = hasSeperateZLevel || !!zlevelKey;
            (componentType === 'series' ? seriesZLevels : componentZLevels).push({
              zlevel: zlevel,
              z: z,
              idx: componentModel.componentIndex,
              type: componentType,
              key: zlevelKey
            });
          });

          if (hasSeperateZLevel) {
            // Series after component
            var zLevels = componentZLevels.concat(seriesZLevels);
            var lastSeriesZLevel_1;
            var lastSeriesKey_1;
            sort(zLevels, function (a, b) {
              if (a.zlevel === b.zlevel) {
                return a.z - b.z;
              }

              return a.zlevel - b.zlevel;
            });
            each(zLevels, function (item) {
              var componentModel = ecModel.getComponent(item.type, item.idx);
              var zlevel = item.zlevel;
              var key = item.key;

              if (lastSeriesZLevel_1 != null) {
                zlevel = Math.max(lastSeriesZLevel_1, zlevel);
              }

              if (key) {
                if (zlevel === lastSeriesZLevel_1 && key !== lastSeriesKey_1) {
                  zlevel++;
                }

                lastSeriesKey_1 = key;
              } else if (lastSeriesKey_1) {
                if (zlevel === lastSeriesZLevel_1) {
                  zlevel++;
                }

                lastSeriesKey_1 = '';
              }

              lastSeriesZLevel_1 = zlevel;
              componentModel.setZLevel(zlevel);
            });
          }
        }

        render = function (ecIns, ecModel, api, payload, updateParams) {
          allocateZlevels(ecModel);
          renderComponents(ecIns, ecModel, api, payload, updateParams);
          each(ecIns._chartsViews, function (chart) {
            chart.__alive = false;
          });
          renderSeries(ecIns, ecModel, api, payload, updateParams); // Remove groups of unrendered charts

          each(ecIns._chartsViews, function (chart) {
            if (!chart.__alive) {
              chart.remove(ecModel, api);
            }
          });
        };

        renderComponents = function (ecIns, ecModel, api, payload, updateParams, dirtyList) {
          each(dirtyList || ecIns._componentsViews, function (componentView) {
            var componentModel = componentView.__model;
            clearStates(componentModel, componentView);
            componentView.render(componentModel, ecModel, api, payload);
            updateZ(componentModel, componentView);
            updateStates(componentModel, componentView);
          });
        };
        /**
         * Render each chart and component
         */


        renderSeries = function (ecIns, ecModel, api, payload, updateParams, dirtyMap) {
          // Render all charts
          var scheduler = ecIns._scheduler;
          updateParams = extend(updateParams || {}, {
            updatedSeries: ecModel.getSeries()
          }); // TODO progressive?

          lifecycle.trigger('series:beforeupdate', ecModel, api, updateParams);
          var unfinished = false;
          ecModel.eachSeries(function (seriesModel) {
            var chartView = ecIns._chartsMap[seriesModel.__viewId];
            chartView.__alive = true;
            var renderTask = chartView.renderTask;
            scheduler.updatePayload(renderTask, payload); // TODO states on marker.

            clearStates(seriesModel, chartView);

            if (dirtyMap && dirtyMap.get(seriesModel.uid)) {
              renderTask.dirty();
            }

            if (renderTask.perform(scheduler.getPerformArgs(renderTask))) {
              unfinished = true;
            }

            chartView.group.silent = !!seriesModel.get('silent'); // Should not call markRedraw on group, because it will disable zrender
            // incremental render (always render from the __startIndex each frame)
            // chartView.group.markRedraw();

            updateBlend(seriesModel, chartView);
            updateSeriesElementSelection(seriesModel);
          });
          scheduler.unfinished = unfinished || scheduler.unfinished;
          lifecycle.trigger('series:layoutlabels', ecModel, api, updateParams); // transition after label is layouted.

          lifecycle.trigger('series:transition', ecModel, api, updateParams);
          ecModel.eachSeries(function (seriesModel) {
            var chartView = ecIns._chartsMap[seriesModel.__viewId]; // Update Z after labels updated. Before applying states.

            updateZ(seriesModel, chartView); // NOTE: Update states after label is updated.
            // label should be in normal status when layouting.

            updateStates(seriesModel, chartView);
          }); // If use hover layer

          updateHoverLayerStatus(ecIns, ecModel);
          lifecycle.trigger('series:afterupdate', ecModel, api, updateParams);
        };

        markStatusToUpdate = function (ecIns) {
          ecIns[STATUS_NEEDS_UPDATE_KEY] = true; // Wake up zrender if it's sleep. Let it update states in the next frame.

          ecIns.getZr().wakeUp();
        };

        applyChangedStates = function (ecIns) {
          if (!ecIns[STATUS_NEEDS_UPDATE_KEY]) {
            return;
          }

          ecIns.getZr().storage.traverse(function (el) {
            // Not applied on removed elements, it may still in fading.
            if (isElementRemoved(el)) {
              return;
            }

            applyElementStates(el);
          });
          ecIns[STATUS_NEEDS_UPDATE_KEY] = false;
        };

        function applyElementStates(el) {
          var newStates = [];
          var oldStates = el.currentStates; // Keep other states.

          for (var i = 0; i < oldStates.length; i++) {
            var stateName = oldStates[i];

            if (!(stateName === 'emphasis' || stateName === 'blur' || stateName === 'select')) {
              newStates.push(stateName);
            }
          } // Only use states when it's exists.


          if (el.selected && el.states.select) {
            newStates.push('select');
          }

          if (el.hoverState === HOVER_STATE_EMPHASIS && el.states.emphasis) {
            newStates.push('emphasis');
          } else if (el.hoverState === HOVER_STATE_BLUR && el.states.blur) {
            newStates.push('blur');
          }

          el.useStates(newStates);
        }

        function updateHoverLayerStatus(ecIns, ecModel) {
          var zr = ecIns._zr;
          var storage = zr.storage;
          var elCount = 0;
          storage.traverse(function (el) {
            if (!el.isGroup) {
              elCount++;
            }
          });

          if (elCount > ecModel.get('hoverLayerThreshold') && !env.node && !env.worker) {
            ecModel.eachSeries(function (seriesModel) {
              if (seriesModel.preventUsingHoverLayer) {
                return;
              }

              var chartView = ecIns._chartsMap[seriesModel.__viewId];

              if (chartView.__alive) {
                chartView.eachRendered(function (el) {
                  if (el.states.emphasis) {
                    el.states.emphasis.hoverLayer = true;
                  }
                });
              }
            });
          }
        }
        /**
         * Update chart and blend.
         */

        function updateBlend(seriesModel, chartView) {
          var blendMode = seriesModel.get('blendMode') || null;
          chartView.eachRendered(function (el) {
            // FIXME marker and other components
            if (!el.isGroup) {
              // DON'T mark the element dirty. In case element is incremental and don't want to rerender.
              el.style.blend = blendMode;
            }
          });
        }

        function updateZ(model, view) {
          if (model.preventAutoZ) {
            return;
          }

          var z = model.get('z') || 0;
          var zlevel = model.get('zlevel') || 0; // Set z and zlevel

          view.eachRendered(function (el) {
            doUpdateZ(el, z, zlevel, -Infinity); // Don't traverse the children because it has been traversed in _updateZ.

            return true;
          });
        }

        function doUpdateZ(el, z, zlevel, maxZ2) {
          // Group may also have textContent
          var label = el.getTextContent();
          var labelLine = el.getTextGuideLine();
          var isGroup = el.isGroup;

          if (isGroup) {
            // set z & zlevel of children elements of Group
            var children = el.childrenRef();

            for (var i = 0; i < children.length; i++) {
              maxZ2 = Math.max(doUpdateZ(children[i], z, zlevel, maxZ2), maxZ2);
            }
          } else {
            // not Group
            el.z = z;
            el.zlevel = zlevel;
            maxZ2 = Math.max(el.z2, maxZ2);
          } // always set z and zlevel if label/labelLine exists


          if (label) {
            label.z = z;
            label.zlevel = zlevel; // lift z2 of text content
            // TODO if el.emphasis.z2 is spcefied, what about textContent.

            isFinite(maxZ2) && (label.z2 = maxZ2 + 2);
          }

          if (labelLine) {
            var textGuideLineConfig = el.textGuideLineConfig;
            labelLine.z = z;
            labelLine.zlevel = zlevel;
            isFinite(maxZ2) && (labelLine.z2 = maxZ2 + (textGuideLineConfig && textGuideLineConfig.showAbove ? 1 : -1));
          }

          return maxZ2;
        } // Clear states without animation.
        // TODO States on component.


        function clearStates(model, view) {
          view.eachRendered(function (el) {
            // Not applied on removed elements, it may still in fading.
            if (isElementRemoved(el)) {
              return;
            }

            var textContent = el.getTextContent();
            var textGuide = el.getTextGuideLine();

            if (el.stateTransition) {
              el.stateTransition = null;
            }

            if (textContent && textContent.stateTransition) {
              textContent.stateTransition = null;
            }

            if (textGuide && textGuide.stateTransition) {
              textGuide.stateTransition = null;
            } // TODO If el is incremental.


            if (el.hasState()) {
              el.prevStates = el.currentStates;
              el.clearStates();
            } else if (el.prevStates) {
              el.prevStates = null;
            }
          });
        }

        function updateStates(model, view) {
          var stateAnimationModel = model.getModel('stateAnimation');
          var enableAnimation = model.isAnimationEnabled();
          var duration = stateAnimationModel.get('duration');
          var stateTransition = duration > 0 ? {
            duration: duration,
            delay: stateAnimationModel.get('delay'),
            easing: stateAnimationModel.get('easing') // additive: stateAnimationModel.get('additive')

          } : null;
          view.eachRendered(function (el) {
            if (el.states && el.states.emphasis) {
              // Not applied on removed elements, it may still in fading.
              if (isElementRemoved(el)) {
                return;
              }

              if (el instanceof Path) {
                savePathStates(el);
              } // Only updated on changed element. In case element is incremental and don't want to rerender.
              // TODO, a more proper way?


              if (el.__dirty) {
                var prevStates = el.prevStates; // Restore states without animation

                if (prevStates) {
                  el.useStates(prevStates);
                }
              } // Update state transition and enable animation again.


              if (enableAnimation) {
                el.stateTransition = stateTransition;
                var textContent = el.getTextContent();
                var textGuide = el.getTextGuideLine(); // TODO Is it necessary to animate label?

                if (textContent) {
                  textContent.stateTransition = stateTransition;
                }

                if (textGuide) {
                  textGuide.stateTransition = stateTransition;
                }
              } // Use highlighted and selected flag to toggle states.


              if (el.__dirty) {
                applyElementStates(el);
              }
            }
          });
        }

        createExtensionAPI = function (ecIns) {
          return new (
          /** @class */
          function (_super) {
            __extends(class_1, _super);

            function class_1() {
              return _super !== null && _super.apply(this, arguments) || this;
            }

            class_1.prototype.getCoordinateSystems = function () {
              return ecIns._coordSysMgr.getCoordinateSystems();
            };

            class_1.prototype.getComponentByElement = function (el) {
              while (el) {
                var modelInfo = el.__ecComponentInfo;

                if (modelInfo != null) {
                  return ecIns._model.getComponent(modelInfo.mainType, modelInfo.index);
                }

                el = el.parent;
              }
            };

            class_1.prototype.enterEmphasis = function (el, highlightDigit) {
              enterEmphasis(el, highlightDigit);
              markStatusToUpdate(ecIns);
            };

            class_1.prototype.leaveEmphasis = function (el, highlightDigit) {
              leaveEmphasis(el, highlightDigit);
              markStatusToUpdate(ecIns);
            };

            class_1.prototype.enterBlur = function (el) {
              enterBlur(el);
              markStatusToUpdate(ecIns);
            };

            class_1.prototype.leaveBlur = function (el) {
              leaveBlur(el);
              markStatusToUpdate(ecIns);
            };

            class_1.prototype.enterSelect = function (el) {
              enterSelect(el);
              markStatusToUpdate(ecIns);
            };

            class_1.prototype.leaveSelect = function (el) {
              leaveSelect(el);
              markStatusToUpdate(ecIns);
            };

            class_1.prototype.getModel = function () {
              return ecIns.getModel();
            };

            class_1.prototype.getViewOfComponentModel = function (componentModel) {
              return ecIns.getViewOfComponentModel(componentModel);
            };

            class_1.prototype.getViewOfSeriesModel = function (seriesModel) {
              return ecIns.getViewOfSeriesModel(seriesModel);
            };

            return class_1;
          }(ExtensionAPI))(ecIns);
        };

        enableConnect = function (chart) {
          function updateConnectedChartsStatus(charts, status) {
            for (var i = 0; i < charts.length; i++) {
              var otherChart = charts[i];
              otherChart[CONNECT_STATUS_KEY] = status;
            }
          }

          each(eventActionMap, function (actionType, eventType) {
            chart._messageCenter.on(eventType, function (event) {
              if (connectedGroups[chart.group] && chart[CONNECT_STATUS_KEY] !== CONNECT_STATUS_PENDING) {
                if (event && event.escapeConnect) {
                  return;
                }

                var action_1 = chart.makeActionFromEvent(event);
                var otherCharts_1 = [];
                each(instances$1, function (otherChart) {
                  if (otherChart !== chart && otherChart.group === chart.group) {
                    otherCharts_1.push(otherChart);
                  }
                });
                updateConnectedChartsStatus(otherCharts_1, CONNECT_STATUS_PENDING);
                each(otherCharts_1, function (otherChart) {
                  if (otherChart[CONNECT_STATUS_KEY] !== CONNECT_STATUS_UPDATING) {
                    otherChart.dispatchAction(action_1);
                  }
                });
                updateConnectedChartsStatus(otherCharts_1, CONNECT_STATUS_UPDATED);
              }
            });
          });
        };
      }();

      return ECharts;
    }(Eventful);

    var echartsProto = ECharts.prototype;
    echartsProto.on = createRegisterEventWithLowercaseECharts('on');
    echartsProto.off = createRegisterEventWithLowercaseECharts('off');
    /**
     * @deprecated
     */
    // @ts-ignore

    echartsProto.one = function (eventName, cb, ctx) {
      var self = this;
      deprecateLog('ECharts#one is deprecated.');

      function wrapped() {
        var args2 = [];

        for (var _i = 0; _i < arguments.length; _i++) {
          args2[_i] = arguments[_i];
        }

        cb && cb.apply && cb.apply(this, args2); // @ts-ignore

        self.off(eventName, wrapped);
      }

      this.on.call(this, eventName, wrapped, ctx);
    };

    var MOUSE_EVENT_NAMES = ['click', 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mousedown', 'mouseup', 'globalout', 'contextmenu'];

    function disposedWarning(id) {
      if ("development" !== 'production') {
        console.warn('Instance ' + id + ' has been disposed');
      }
    }

    var actions = {};
    /**
     * Map eventType to actionType
     */

    var eventActionMap = {};
    var dataProcessorFuncs = [];
    var optionPreprocessorFuncs = [];
    var visualFuncs = [];
    var themeStorage = {};
    var loadingEffects = {};
    var instances$1 = {};
    var connectedGroups = {};
    var idBase = +new Date() - 0;
    var groupIdBase = +new Date() - 0;
    var DOM_ATTRIBUTE_KEY = '_echarts_instance_';
    /**
     * @param opts.devicePixelRatio Use window.devicePixelRatio by default
     * @param opts.renderer Can choose 'canvas' or 'svg' to render the chart.
     * @param opts.width Use clientWidth of the input `dom` by default.
     *        Can be 'auto' (the same as null/undefined)
     * @param opts.height Use clientHeight of the input `dom` by default.
     *        Can be 'auto' (the same as null/undefined)
     * @param opts.locale Specify the locale.
     * @param opts.useDirtyRect Enable dirty rectangle rendering or not.
     */

    function init$1(dom, theme, opts) {
      var isClient = !(opts && opts.ssr);

      if (isClient) {
        if ("development" !== 'production') {
          if (!dom) {
            throw new Error('Initialize failed: invalid dom.');
          }
        }

        var existInstance = getInstanceByDom(dom);

        if (existInstance) {
          if ("development" !== 'production') {
            console.warn('There is a chart instance already initialized on the dom.');
          }

          return existInstance;
        }

        if ("development" !== 'production') {
          if (isDom(dom) && dom.nodeName.toUpperCase() !== 'CANVAS' && (!dom.clientWidth && (!opts || opts.width == null) || !dom.clientHeight && (!opts || opts.height == null))) {
            console.warn('Can\'t get DOM width or height. Please check ' + 'dom.clientWidth and dom.clientHeight. They should not be 0.' + 'For example, you may need to call this in the callback ' + 'of window.onload.');
          }
        }
      }

      var chart = new ECharts(dom, theme, opts);
      chart.id = 'ec_' + idBase++;
      instances$1[chart.id] = chart;
      isClient && setAttribute(dom, DOM_ATTRIBUTE_KEY, chart.id);
      enableConnect(chart);
      lifecycle.trigger('afterinit', chart);
      return chart;
    }
    /**
     * @usage
     * (A)
     * ```js
     * let chart1 = echarts.init(dom1);
     * let chart2 = echarts.init(dom2);
     * chart1.group = 'xxx';
     * chart2.group = 'xxx';
     * echarts.connect('xxx');
     * ```
     * (B)
     * ```js
     * let chart1 = echarts.init(dom1);
     * let chart2 = echarts.init(dom2);
     * echarts.connect('xxx', [chart1, chart2]);
     * ```
     */

    function connect(groupId) {
      // Is array of charts
      if (isArray(groupId)) {
        var charts = groupId;
        groupId = null; // If any chart has group

        each(charts, function (chart) {
          if (chart.group != null) {
            groupId = chart.group;
          }
        });
        groupId = groupId || 'g_' + groupIdBase++;
        each(charts, function (chart) {
          chart.group = groupId;
        });
      }

      connectedGroups[groupId] = true;
      return groupId;
    }
    /**
     * @deprecated
     */

    function disConnect(groupId) {
      connectedGroups[groupId] = false;
    }
    /**
     * Alias and backward compatibility
     */

    var disconnect = disConnect;
    /**
     * Dispose a chart instance
     */

    function dispose$1(chart) {
      if (isString(chart)) {
        chart = instances$1[chart];
      } else if (!(chart instanceof ECharts)) {
        // Try to treat as dom
        chart = getInstanceByDom(chart);
      }

      if (chart instanceof ECharts && !chart.isDisposed()) {
        chart.dispose();
      }
    }
    function getInstanceByDom(dom) {
      return instances$1[getAttribute(dom, DOM_ATTRIBUTE_KEY)];
    }
    function getInstanceById(key) {
      return instances$1[key];
    }
    /**
     * Register theme
     */

    function registerTheme(name, theme) {
      themeStorage[name] = theme;
    }
    /**
     * Register option preprocessor
     */

    function registerPreprocessor(preprocessorFunc) {
      if (indexOf(optionPreprocessorFuncs, preprocessorFunc) < 0) {
        optionPreprocessorFuncs.push(preprocessorFunc);
      }
    }
    function registerProcessor(priority, processor) {
      normalizeRegister(dataProcessorFuncs, priority, processor, PRIORITY_PROCESSOR_DEFAULT);
    }
    /**
     * Register postIniter
     * @param {Function} postInitFunc
     */

    function registerPostInit(postInitFunc) {
      registerUpdateLifecycle('afterinit', postInitFunc);
    }
    /**
     * Register postUpdater
     * @param {Function} postUpdateFunc
     */

    function registerPostUpdate(postUpdateFunc) {
      registerUpdateLifecycle('afterupdate', postUpdateFunc);
    }
    function registerUpdateLifecycle(name, cb) {
      lifecycle.on(name, cb);
    }
    function registerAction(actionInfo, eventName, action) {
      if (isFunction(eventName)) {
        action = eventName;
        eventName = '';
      }

      var actionType = isObject(actionInfo) ? actionInfo.type : [actionInfo, actionInfo = {
        event: eventName
      }][0]; // Event name is all lowercase

      actionInfo.event = (actionInfo.event || actionType).toLowerCase();
      eventName = actionInfo.event;

      if (eventActionMap[eventName]) {
        // Already registered.
        return;
      } // Validate action type and event name.


      assert(ACTION_REG.test(actionType) && ACTION_REG.test(eventName));

      if (!actions[actionType]) {
        actions[actionType] = {
          action: action,
          actionInfo: actionInfo
        };
      }

      eventActionMap[eventName] = actionType;
    }
    function registerCoordinateSystem(type, coordSysCreator) {
      CoordinateSystemManager.register(type, coordSysCreator);
    }
    /**
     * Get dimensions of specified coordinate system.
     * @param {string} type
     * @return {Array.<string|Object>}
     */

    function getCoordinateSystemDimensions(type) {
      var coordSysCreator = CoordinateSystemManager.get(type);

      if (coordSysCreator) {
        return coordSysCreator.getDimensionsInfo ? coordSysCreator.getDimensionsInfo() : coordSysCreator.dimensions.slice();
      }
    }

    function registerLayout(priority, layoutTask) {
      normalizeRegister(visualFuncs, priority, layoutTask, PRIORITY_VISUAL_LAYOUT, 'layout');
    }

    function registerVisual(priority, visualTask) {
      normalizeRegister(visualFuncs, priority, visualTask, PRIORITY_VISUAL_CHART, 'visual');
    }
    var registeredTasks = [];

    function normalizeRegister(targetList, priority, fn, defaultPriority, visualType) {
      if (isFunction(priority) || isObject(priority)) {
        fn = priority;
        priority = defaultPriority;
      }

      if ("development" !== 'production') {
        if (isNaN(priority) || priority == null) {
          throw new Error('Illegal priority');
        } // Check duplicate


        each(targetList, function (wrap) {
          assert(wrap.__raw !== fn);
        });
      } // Already registered


      if (indexOf(registeredTasks, fn) >= 0) {
        return;
      }

      registeredTasks.push(fn);
      var stageHandler = Scheduler.wrapStageHandler(fn, visualType);
      stageHandler.__prio = priority;
      stageHandler.__raw = fn;
      targetList.push(stageHandler);
    }

    function registerLoading(name, loadingFx) {
      loadingEffects[name] = loadingFx;
    }
    /**
     * ZRender need a canvas context to do measureText.
     * But in node environment canvas may be created by node-canvas.
     * So we need to specify how to create a canvas instead of using document.createElement('canvas')
     *
     *
     * @deprecated use setPlatformAPI({ createCanvas }) instead.
     *
     * @example
     *     let Canvas = require('canvas');
     *     let echarts = require('echarts');
     *     echarts.setCanvasCreator(function () {
     *         // Small size is enough.
     *         return new Canvas(32, 32);
     *     });
     */

    function setCanvasCreator(creator) {
      if ("development" !== 'production') {
        deprecateLog('setCanvasCreator is deprecated. Use setPlatformAPI({ createCanvas }) instead.');
      }

      setPlatformAPI({
        createCanvas: creator
      });
    }
    /**
     * The parameters and usage: see `geoSourceManager.registerMap`.
     * Compatible with previous `echarts.registerMap`.
     */

    function registerMap(mapName, geoJson, specialAreas) {
      var registerMap = getImpl('registerMap');
      registerMap && registerMap(mapName, geoJson, specialAreas);
    }
    function getMap(mapName) {
      var getMap = getImpl('getMap');
      return getMap && getMap(mapName);
    }
    var registerTransform = registerExternalTransform;
    /**
     * Globa dispatchAction to a specified chart instance.
     */
    // export function dispatchAction(payload: { chartId: string } & Payload, opt?: Parameters<ECharts['dispatchAction']>[1]) {
    //     if (!payload || !payload.chartId) {
    //         // Must have chartId to find chart
    //         return;
    //     }
    //     const chart = instances[payload.chartId];
    //     if (chart) {
    //         chart.dispatchAction(payload, opt);
    //     }
    // }
    // Builtin global visual

    registerVisual(PRIORITY_VISUAL_GLOBAL, seriesStyleTask);
    registerVisual(PRIORITY_VISUAL_CHART_DATA_CUSTOM, dataStyleTask);
    registerVisual(PRIORITY_VISUAL_CHART_DATA_CUSTOM, dataColorPaletteTask);
    registerVisual(PRIORITY_VISUAL_GLOBAL, seriesSymbolTask);
    registerVisual(PRIORITY_VISUAL_CHART_DATA_CUSTOM, dataSymbolTask);
    registerVisual(PRIORITY_VISUAL_DECAL, decalVisual);
    registerPreprocessor(globalBackwardCompat);
    registerProcessor(PRIORITY_PROCESSOR_DATASTACK, dataStack);
    registerLoading('default', defaultLoading); // Default actions

    registerAction({
      type: HIGHLIGHT_ACTION_TYPE,
      event: HIGHLIGHT_ACTION_TYPE,
      update: HIGHLIGHT_ACTION_TYPE
    }, noop);
    registerAction({
      type: DOWNPLAY_ACTION_TYPE,
      event: DOWNPLAY_ACTION_TYPE,
      update: DOWNPLAY_ACTION_TYPE
    }, noop);
    registerAction({
      type: SELECT_ACTION_TYPE,
      event: SELECT_ACTION_TYPE,
      update: SELECT_ACTION_TYPE
    }, noop);
    registerAction({
      type: UNSELECT_ACTION_TYPE,
      event: UNSELECT_ACTION_TYPE,
      update: UNSELECT_ACTION_TYPE
    }, noop);
    registerAction({
      type: TOGGLE_SELECT_ACTION_TYPE,
      event: TOGGLE_SELECT_ACTION_TYPE,
      update: TOGGLE_SELECT_ACTION_TYPE
    }, noop); // Default theme

    registerTheme('light', lightTheme);
    registerTheme('dark', theme); // For backward compatibility, where the namespace `dataTool` will
    // be mounted on `echarts` is the extension `dataTool` is imported.

    var dataTool = {};

    var extensions = [];
    var extensionRegisters = {
      registerPreprocessor: registerPreprocessor,
      registerProcessor: registerProcessor,
      registerPostInit: registerPostInit,
      registerPostUpdate: registerPostUpdate,
      registerUpdateLifecycle: registerUpdateLifecycle,
      registerAction: registerAction,
      registerCoordinateSystem: registerCoordinateSystem,
      registerLayout: registerLayout,
      registerVisual: registerVisual,
      registerTransform: registerTransform,
      registerLoading: registerLoading,
      registerMap: registerMap,
      registerImpl: registerImpl,
      PRIORITY: PRIORITY,
      ComponentModel: ComponentModel,
      ComponentView: ComponentView,
      SeriesModel: SeriesModel,
      ChartView: ChartView,
      // TODO Use ComponentModel and SeriesModel instead of Constructor
      registerComponentModel: function (ComponentModelClass) {
        ComponentModel.registerClass(ComponentModelClass);
      },
      registerComponentView: function (ComponentViewClass) {
        ComponentView.registerClass(ComponentViewClass);
      },
      registerSeriesModel: function (SeriesModelClass) {
        SeriesModel.registerClass(SeriesModelClass);
      },
      registerChartView: function (ChartViewClass) {
        ChartView.registerClass(ChartViewClass);
      },
      registerSubTypeDefaulter: function (componentType, defaulter) {
        ComponentModel.registerSubTypeDefaulter(componentType, defaulter);
      },
      registerPainter: function (painterType, PainterCtor) {
        registerPainter(painterType, PainterCtor);
      }
    };
    function use(ext) {
      if (isArray(ext)) {
        // use([ChartLine, ChartBar]);
        each(ext, function (singleExt) {
          use(singleExt);
        });
        return;
      }

      if (indexOf(extensions, ext) >= 0) {
        return;
      }

      extensions.push(ext);

      if (isFunction(ext)) {
        ext = {
          install: ext
        };
      }

      ext.install(extensionRegisters);
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    function dataIndexMapValueLength(valNumOrArrLengthMoreThan2) {
      return valNumOrArrLengthMoreThan2 == null ? 0 : valNumOrArrLengthMoreThan2.length || 1;
    }

    function defaultKeyGetter(item) {
      return item;
    }

    var DataDiffer =
    /** @class */
    function () {
      /**
       * @param context Can be visited by this.context in callback.
       */
      function DataDiffer(oldArr, newArr, oldKeyGetter, newKeyGetter, context, // By default: 'oneToOne'.
      diffMode) {
        this._old = oldArr;
        this._new = newArr;
        this._oldKeyGetter = oldKeyGetter || defaultKeyGetter;
        this._newKeyGetter = newKeyGetter || defaultKeyGetter; // Visible in callback via `this.context`;

        this.context = context;
        this._diffModeMultiple = diffMode === 'multiple';
      }
      /**
       * Callback function when add a data
       */


      DataDiffer.prototype.add = function (func) {
        this._add = func;
        return this;
      };
      /**
       * Callback function when update a data
       */


      DataDiffer.prototype.update = function (func) {
        this._update = func;
        return this;
      };
      /**
       * Callback function when update a data and only work in `cbMode: 'byKey'`.
       */


      DataDiffer.prototype.updateManyToOne = function (func) {
        this._updateManyToOne = func;
        return this;
      };
      /**
       * Callback function when update a data and only work in `cbMode: 'byKey'`.
       */


      DataDiffer.prototype.updateOneToMany = function (func) {
        this._updateOneToMany = func;
        return this;
      };
      /**
       * Callback function when update a data and only work in `cbMode: 'byKey'`.
       */


      DataDiffer.prototype.updateManyToMany = function (func) {
        this._updateManyToMany = func;
        return this;
      };
      /**
       * Callback function when remove a data
       */


      DataDiffer.prototype.remove = function (func) {
        this._remove = func;
        return this;
      };

      DataDiffer.prototype.execute = function () {
        this[this._diffModeMultiple ? '_executeMultiple' : '_executeOneToOne']();
      };

      DataDiffer.prototype._executeOneToOne = function () {
        var oldArr = this._old;
        var newArr = this._new;
        var newDataIndexMap = {};
        var oldDataKeyArr = new Array(oldArr.length);
        var newDataKeyArr = new Array(newArr.length);

        this._initIndexMap(oldArr, null, oldDataKeyArr, '_oldKeyGetter');

        this._initIndexMap(newArr, newDataIndexMap, newDataKeyArr, '_newKeyGetter');

        for (var i = 0; i < oldArr.length; i++) {
          var oldKey = oldDataKeyArr[i];
          var newIdxMapVal = newDataIndexMap[oldKey];
          var newIdxMapValLen = dataIndexMapValueLength(newIdxMapVal); // idx can never be empty array here. see 'set null' logic below.

          if (newIdxMapValLen > 1) {
            // Consider there is duplicate key (for example, use dataItem.name as key).
            // We should make sure every item in newArr and oldArr can be visited.
            var newIdx = newIdxMapVal.shift();

            if (newIdxMapVal.length === 1) {
              newDataIndexMap[oldKey] = newIdxMapVal[0];
            }

            this._update && this._update(newIdx, i);
          } else if (newIdxMapValLen === 1) {
            newDataIndexMap[oldKey] = null;
            this._update && this._update(newIdxMapVal, i);
          } else {
            this._remove && this._remove(i);
          }
        }

        this._performRestAdd(newDataKeyArr, newDataIndexMap);
      };
      /**
       * For example, consider the case:
       * oldData: [o0, o1, o2, o3, o4, o5, o6, o7],
       * newData: [n0, n1, n2, n3, n4, n5, n6, n7, n8],
       * Where:
       *     o0, o1, n0 has key 'a' (many to one)
       *     o5, n4, n5, n6 has key 'b' (one to many)
       *     o2, n1 has key 'c' (one to one)
       *     n2, n3 has key 'd' (add)
       *     o3, o4 has key 'e' (remove)
       *     o6, o7, n7, n8 has key 'f' (many to many, treated as add and remove)
       * Then:
       *     (The order of the following directives are not ensured.)
       *     this._updateManyToOne(n0, [o0, o1]);
       *     this._updateOneToMany([n4, n5, n6], o5);
       *     this._update(n1, o2);
       *     this._remove(o3);
       *     this._remove(o4);
       *     this._remove(o6);
       *     this._remove(o7);
       *     this._add(n2);
       *     this._add(n3);
       *     this._add(n7);
       *     this._add(n8);
       */


      DataDiffer.prototype._executeMultiple = function () {
        var oldArr = this._old;
        var newArr = this._new;
        var oldDataIndexMap = {};
        var newDataIndexMap = {};
        var oldDataKeyArr = [];
        var newDataKeyArr = [];

        this._initIndexMap(oldArr, oldDataIndexMap, oldDataKeyArr, '_oldKeyGetter');

        this._initIndexMap(newArr, newDataIndexMap, newDataKeyArr, '_newKeyGetter');

        for (var i = 0; i < oldDataKeyArr.length; i++) {
          var oldKey = oldDataKeyArr[i];
          var oldIdxMapVal = oldDataIndexMap[oldKey];
          var newIdxMapVal = newDataIndexMap[oldKey];
          var oldIdxMapValLen = dataIndexMapValueLength(oldIdxMapVal);
          var newIdxMapValLen = dataIndexMapValueLength(newIdxMapVal);

          if (oldIdxMapValLen > 1 && newIdxMapValLen === 1) {
            this._updateManyToOne && this._updateManyToOne(newIdxMapVal, oldIdxMapVal);
            newDataIndexMap[oldKey] = null;
          } else if (oldIdxMapValLen === 1 && newIdxMapValLen > 1) {
            this._updateOneToMany && this._updateOneToMany(newIdxMapVal, oldIdxMapVal);
            newDataIndexMap[oldKey] = null;
          } else if (oldIdxMapValLen === 1 && newIdxMapValLen === 1) {
            this._update && this._update(newIdxMapVal, oldIdxMapVal);
            newDataIndexMap[oldKey] = null;
          } else if (oldIdxMapValLen > 1 && newIdxMapValLen > 1) {
            this._updateManyToMany && this._updateManyToMany(newIdxMapVal, oldIdxMapVal);
            newDataIndexMap[oldKey] = null;
          } else if (oldIdxMapValLen > 1) {
            for (var i_1 = 0; i_1 < oldIdxMapValLen; i_1++) {
              this._remove && this._remove(oldIdxMapVal[i_1]);
            }
          } else {
            this._remove && this._remove(oldIdxMapVal);
          }
        }

        this._performRestAdd(newDataKeyArr, newDataIndexMap);
      };

      DataDiffer.prototype._performRestAdd = function (newDataKeyArr, newDataIndexMap) {
        for (var i = 0; i < newDataKeyArr.length; i++) {
          var newKey = newDataKeyArr[i];
          var newIdxMapVal = newDataIndexMap[newKey];
          var idxMapValLen = dataIndexMapValueLength(newIdxMapVal);

          if (idxMapValLen > 1) {
            for (var j = 0; j < idxMapValLen; j++) {
              this._add && this._add(newIdxMapVal[j]);
            }
          } else if (idxMapValLen === 1) {
            this._add && this._add(newIdxMapVal);
          } // Support both `newDataKeyArr` are duplication removed or not removed.


          newDataIndexMap[newKey] = null;
        }
      };

      DataDiffer.prototype._initIndexMap = function (arr, // Can be null.
      map, // In 'byKey', the output `keyArr` is duplication removed.
      // In 'byIndex', the output `keyArr` is not duplication removed and
      //     its indices are accurately corresponding to `arr`.
      keyArr, keyGetterName) {
        var cbModeMultiple = this._diffModeMultiple;

        for (var i = 0; i < arr.length; i++) {
          // Add prefix to avoid conflict with Object.prototype.
          var key = '_ec_' + this[keyGetterName](arr[i], i);

          if (!cbModeMultiple) {
            keyArr[i] = key;
          }

          if (!map) {
            continue;
          }

          var idxMapVal = map[key];
          var idxMapValLen = dataIndexMapValueLength(idxMapVal);

          if (idxMapValLen === 0) {
            // Simple optimize: in most cases, one index has one key,
            // do not need array.
            map[key] = i;

            if (cbModeMultiple) {
              keyArr.push(key);
            }
          } else if (idxMapValLen === 1) {
            map[key] = [idxMapVal, i];
          } else {
            idxMapVal.push(i);
          }
        }
      };

      return DataDiffer;
    }();

    var DimensionUserOuput =
    /** @class */
    function () {
      function DimensionUserOuput(encode, dimRequest) {
        this._encode = encode;
        this._schema = dimRequest;
      }

      DimensionUserOuput.prototype.get = function () {
        return {
          // Do not generate full dimension name until fist used.
          fullDimensions: this._getFullDimensionNames(),
          encode: this._encode
        };
      };
      /**
       * Get all data store dimension names.
       * Theoretically a series data store is defined both by series and used dataset (if any).
       * If some dimensions are omitted for performance reason in `this.dimensions`,
       * the dimension name may not be auto-generated if user does not specify a dimension name.
       * In this case, the dimension name is `null`/`undefined`.
       */


      DimensionUserOuput.prototype._getFullDimensionNames = function () {
        if (!this._cachedDimNames) {
          this._cachedDimNames = this._schema ? this._schema.makeOutputDimensionNames() : [];
        }

        return this._cachedDimNames;
      };

      return DimensionUserOuput;
    }();
    function summarizeDimensions(data, schema) {
      var summary = {};
      var encode = summary.encode = {};
      var notExtraCoordDimMap = createHashMap();
      var defaultedLabel = [];
      var defaultedTooltip = [];
      var userOutputEncode = {};
      each(data.dimensions, function (dimName) {
        var dimItem = data.getDimensionInfo(dimName);
        var coordDim = dimItem.coordDim;

        if (coordDim) {
          if ("development" !== 'production') {
            assert(VISUAL_DIMENSIONS.get(coordDim) == null);
          }

          var coordDimIndex = dimItem.coordDimIndex;
          getOrCreateEncodeArr(encode, coordDim)[coordDimIndex] = dimName;

          if (!dimItem.isExtraCoord) {
            notExtraCoordDimMap.set(coordDim, 1); // Use the last coord dim (and label friendly) as default label,
            // because when dataset is used, it is hard to guess which dimension
            // can be value dimension. If both show x, y on label is not look good,
            // and conventionally y axis is focused more.

            if (mayLabelDimType(dimItem.type)) {
              defaultedLabel[0] = dimName;
            } // User output encode do not contain generated coords.
            // And it only has index. User can use index to retrieve value from the raw item array.


            getOrCreateEncodeArr(userOutputEncode, coordDim)[coordDimIndex] = data.getDimensionIndex(dimItem.name);
          }

          if (dimItem.defaultTooltip) {
            defaultedTooltip.push(dimName);
          }
        }

        VISUAL_DIMENSIONS.each(function (v, otherDim) {
          var encodeArr = getOrCreateEncodeArr(encode, otherDim);
          var dimIndex = dimItem.otherDims[otherDim];

          if (dimIndex != null && dimIndex !== false) {
            encodeArr[dimIndex] = dimItem.name;
          }
        });
      });
      var dataDimsOnCoord = [];
      var encodeFirstDimNotExtra = {};
      notExtraCoordDimMap.each(function (v, coordDim) {
        var dimArr = encode[coordDim];
        encodeFirstDimNotExtra[coordDim] = dimArr[0]; // Not necessary to remove duplicate, because a data
        // dim canot on more than one coordDim.

        dataDimsOnCoord = dataDimsOnCoord.concat(dimArr);
      });
      summary.dataDimsOnCoord = dataDimsOnCoord;
      summary.dataDimIndicesOnCoord = map(dataDimsOnCoord, function (dimName) {
        return data.getDimensionInfo(dimName).storeDimIndex;
      });
      summary.encodeFirstDimNotExtra = encodeFirstDimNotExtra;
      var encodeLabel = encode.label; // FIXME `encode.label` is not recommended, because formatter cannot be set
      // in this way. Use label.formatter instead. Maybe remove this approach someday.

      if (encodeLabel && encodeLabel.length) {
        defaultedLabel = encodeLabel.slice();
      }

      var encodeTooltip = encode.tooltip;

      if (encodeTooltip && encodeTooltip.length) {
        defaultedTooltip = encodeTooltip.slice();
      } else if (!defaultedTooltip.length) {
        defaultedTooltip = defaultedLabel.slice();
      }

      encode.defaultedLabel = defaultedLabel;
      encode.defaultedTooltip = defaultedTooltip;
      summary.userOutput = new DimensionUserOuput(userOutputEncode, schema);
      return summary;
    }

    function getOrCreateEncodeArr(encode, dim) {
      if (!encode.hasOwnProperty(dim)) {
        encode[dim] = [];
      }

      return encode[dim];
    } // FIXME:TS should be type `AxisType`


    function getDimensionTypeByAxis(axisType) {
      return axisType === 'category' ? 'ordinal' : axisType === 'time' ? 'time' : 'float';
    }

    function mayLabelDimType(dimType) {
      // In most cases, ordinal and time do not suitable for label.
      // Ordinal info can be displayed on axis. Time is too long.
      return !(dimType === 'ordinal' || dimType === 'time');
    } // function findTheLastDimMayLabel(data) {
    //     // Get last value dim
    //     let dimensions = data.dimensions.slice();
    //     let valueType;
    //     let valueDim;
    //     while (dimensions.length && (
    //         valueDim = dimensions.pop(),
    //         valueType = data.getDimensionInfo(valueDim).type,
    //         valueType === 'ordinal' || valueType === 'time'
    //     )) {} // jshint ignore:line
    //     return valueDim;
    // }

    var SeriesDimensionDefine =
    /** @class */
    function () {
      /**
       * @param opt All of the fields will be shallow copied.
       */
      function SeriesDimensionDefine(opt) {
        /**
         * The format of `otherDims` is:
         * ```js
         * {
         *     tooltip?: number
         *     label?: number
         *     itemName?: number
         *     seriesName?: number
         * }
         * ```
         *
         * A `series.encode` can specified these fields:
         * ```js
         * encode: {
         *     // "3, 1, 5" is the index of data dimension.
         *     tooltip: [3, 1, 5],
         *     label: [0, 3],
         *     ...
         * }
         * ```
         * `otherDims` is the parse result of the `series.encode` above, like:
         * ```js
         * // Suppose the index of this data dimension is `3`.
         * this.otherDims = {
         *     // `3` is at the index `0` of the `encode.tooltip`
         *     tooltip: 0,
         *     // `3` is at the index `1` of the `encode.label`
         *     label: 1
         * };
         * ```
         *
         * This prop should never be `null`/`undefined` after initialized.
         */
        this.otherDims = {};

        if (opt != null) {
          extend(this, opt);
        }
      }

      return SeriesDimensionDefine;
    }();

    var inner$4 = makeInner();
    var dimTypeShort = {
      float: 'f',
      int: 'i',
      ordinal: 'o',
      number: 'n',
      time: 't'
    };
    /**
     * Represents the dimension requirement of a series.
     *
     * NOTICE:
     * When there are too many dimensions in dataset and many series, only the used dimensions
     * (i.e., used by coord sys and declared in `series.encode`) are add to `dimensionDefineList`.
     * But users may query data by other unused dimension names.
     * In this case, users can only query data if and only if they have defined dimension names
     * via ec option, so we provide `getDimensionIndexFromSource`, which only query them from
     * `source` dimensions.
     */

    var SeriesDataSchema =
    /** @class */
    function () {
      function SeriesDataSchema(opt) {
        this.dimensions = opt.dimensions;
        this._dimOmitted = opt.dimensionOmitted;
        this.source = opt.source;
        this._fullDimCount = opt.fullDimensionCount;

        this._updateDimOmitted(opt.dimensionOmitted);
      }

      SeriesDataSchema.prototype.isDimensionOmitted = function () {
        return this._dimOmitted;
      };

      SeriesDataSchema.prototype._updateDimOmitted = function (dimensionOmitted) {
        this._dimOmitted = dimensionOmitted;

        if (!dimensionOmitted) {
          return;
        }

        if (!this._dimNameMap) {
          this._dimNameMap = ensureSourceDimNameMap(this.source);
        }
      };
      /**
       * @caution Can only be used when `dimensionOmitted: true`.
       *
       * Get index by user defined dimension name (i.e., not internal generate name).
       * That is, get index from `dimensionsDefine`.
       * If no `dimensionsDefine`, or no name get, return -1.
       */


      SeriesDataSchema.prototype.getSourceDimensionIndex = function (dimName) {
        return retrieve2(this._dimNameMap.get(dimName), -1);
      };
      /**
       * @caution Can only be used when `dimensionOmitted: true`.
       *
       * Notice: may return `null`/`undefined` if user not specify dimension names.
       */


      SeriesDataSchema.prototype.getSourceDimension = function (dimIndex) {
        var dimensionsDefine = this.source.dimensionsDefine;

        if (dimensionsDefine) {
          return dimensionsDefine[dimIndex];
        }
      };

      SeriesDataSchema.prototype.makeStoreSchema = function () {
        var dimCount = this._fullDimCount;
        var willRetrieveDataByName = shouldRetrieveDataByName(this.source);
        var makeHashStrict = !shouldOmitUnusedDimensions(dimCount); // If source don't have dimensions or series don't omit unsed dimensions.
        // Generate from seriesDimList directly

        var dimHash = '';
        var dims = [];

        for (var fullDimIdx = 0, seriesDimIdx = 0; fullDimIdx < dimCount; fullDimIdx++) {
          var property = void 0;
          var type = void 0;
          var ordinalMeta = void 0;
          var seriesDimDef = this.dimensions[seriesDimIdx]; // The list has been sorted by `storeDimIndex` asc.

          if (seriesDimDef && seriesDimDef.storeDimIndex === fullDimIdx) {
            property = willRetrieveDataByName ? seriesDimDef.name : null;
            type = seriesDimDef.type;
            ordinalMeta = seriesDimDef.ordinalMeta;
            seriesDimIdx++;
          } else {
            var sourceDimDef = this.getSourceDimension(fullDimIdx);

            if (sourceDimDef) {
              property = willRetrieveDataByName ? sourceDimDef.name : null;
              type = sourceDimDef.type;
            }
          }

          dims.push({
            property: property,
            type: type,
            ordinalMeta: ordinalMeta
          }); // If retrieving data by index,
          //   use <index, type, ordinalMeta> to determine whether data can be shared.
          //   (Because in this case there might be no dimension name defined in dataset, but indices always exists).
          //   (Indices are always 0, 1, 2, ..., so we can ignore them to shorten the hash).
          // Otherwise if retrieving data by property name (like `data: [{aa: 123, bb: 765}, ...]`),
          //   use <property, type, ordinalMeta> in hash.

          if (willRetrieveDataByName && property != null // For data stack, we have make sure each series has its own dim on this store.
          // So we do not add property to hash to make sure they can share this store.
          && (!seriesDimDef || !seriesDimDef.isCalculationCoord)) {
            dimHash += makeHashStrict // Use escape character '`' in case that property name contains '$'.
            ? property.replace(/\`/g, '`1').replace(/\$/g, '`2') // For better performance, when there are large dimensions, tolerant this defects that hardly meet.
            : property;
          }

          dimHash += '$';
          dimHash += dimTypeShort[type] || 'f';

          if (ordinalMeta) {
            dimHash += ordinalMeta.uid;
          }

          dimHash += '$';
        } // Source from endpoint(usually series) will be read differently
        // when seriesLayoutBy or startIndex(which is affected by sourceHeader) are different.
        // So we use this three props as key.


        var source = this.source;
        var hash = [source.seriesLayoutBy, source.startIndex, dimHash].join('$$');
        return {
          dimensions: dims,
          hash: hash
        };
      };

      SeriesDataSchema.prototype.makeOutputDimensionNames = function () {
        var result = [];

        for (var fullDimIdx = 0, seriesDimIdx = 0; fullDimIdx < this._fullDimCount; fullDimIdx++) {
          var name_1 = void 0;
          var seriesDimDef = this.dimensions[seriesDimIdx]; // The list has been sorted by `storeDimIndex` asc.

          if (seriesDimDef && seriesDimDef.storeDimIndex === fullDimIdx) {
            if (!seriesDimDef.isCalculationCoord) {
              name_1 = seriesDimDef.name;
            }

            seriesDimIdx++;
          } else {
            var sourceDimDef = this.getSourceDimension(fullDimIdx);

            if (sourceDimDef) {
              name_1 = sourceDimDef.name;
            }
          }

          result.push(name_1);
        }

        return result;
      };

      SeriesDataSchema.prototype.appendCalculationDimension = function (dimDef) {
        this.dimensions.push(dimDef);
        dimDef.isCalculationCoord = true;
        this._fullDimCount++; // If append dimension on a data store, consider the store
        // might be shared by different series, series dimensions not
        // really map to store dimensions.

        this._updateDimOmitted(true);
      };

      return SeriesDataSchema;
    }();
    function isSeriesDataSchema(schema) {
      return schema instanceof SeriesDataSchema;
    }
    function createDimNameMap(dimsDef) {
      var dataDimNameMap = createHashMap();

      for (var i = 0; i < (dimsDef || []).length; i++) {
        var dimDefItemRaw = dimsDef[i];
        var userDimName = isObject(dimDefItemRaw) ? dimDefItemRaw.name : dimDefItemRaw;

        if (userDimName != null && dataDimNameMap.get(userDimName) == null) {
          dataDimNameMap.set(userDimName, i);
        }
      }

      return dataDimNameMap;
    }
    function ensureSourceDimNameMap(source) {
      var innerSource = inner$4(source);
      return innerSource.dimNameMap || (innerSource.dimNameMap = createDimNameMap(source.dimensionsDefine));
    }
    function shouldOmitUnusedDimensions(dimCount) {
      return dimCount > 30;
    }

    var isObject$2 = isObject;
    var map$1 = map;
    var CtorInt32Array$1 = typeof Int32Array === 'undefined' ? Array : Int32Array; // Use prefix to avoid index to be the same as otherIdList[idx],
    // which will cause weird update animation.

    var ID_PREFIX = 'e\0\0';
    var INDEX_NOT_FOUND = -1; // type SeriesDimensionIndex = DimensionIndex;

    var TRANSFERABLE_PROPERTIES = ['hasItemOption', '_nameList', '_idList', '_invertedIndicesMap', '_dimSummary', 'userOutput', '_rawData', '_dimValueGetter', '_nameDimIdx', '_idDimIdx', '_nameRepeatCount'];
    var CLONE_PROPERTIES = ['_approximateExtent']; // -----------------------------
    // Internal method declarations:
    // -----------------------------

    var prepareInvertedIndex;
    var getId;
    var getIdNameFromStore;
    var normalizeDimensions;
    var transferProperties;
    var cloneListForMapAndSample;
    var makeIdFromName;

    var SeriesData =
    /** @class */
    function () {
      /**
       * @param dimensionsInput.dimensions
       *        For example, ['someDimName', {name: 'someDimName', type: 'someDimType'}, ...].
       *        Dimensions should be concrete names like x, y, z, lng, lat, angle, radius
       */
      function SeriesData(dimensionsInput, hostModel) {
        this.type = 'list';
        this._dimOmitted = false;
        this._nameList = [];
        this._idList = []; // Models of data option is stored sparse for optimizing memory cost
        // Never used yet (not used yet).
        // private _optionModels: Model[] = [];
        // Global visual properties after visual coding

        this._visual = {}; // Global layout properties.

        this._layout = {}; // Item visual properties after visual coding

        this._itemVisuals = []; // Item layout properties after layout

        this._itemLayouts = []; // Graphic elements

        this._graphicEls = []; // key: dim, value: extent

        this._approximateExtent = {};
        this._calculationInfo = {}; // Having detected that there is data item is non primitive type
        // (in type `OptionDataItemObject`).
        // Like `data: [ { value: xx, itemStyle: {...} }, ...]`
        // At present it only happen in `SOURCE_FORMAT_ORIGINAL`.

        this.hasItemOption = false; // Methods that create a new list based on this list should be listed here.
        // Notice that those method should `RETURN` the new list.

        this.TRANSFERABLE_METHODS = ['cloneShallow', 'downSample', 'lttbDownSample', 'map']; // Methods that change indices of this list should be listed here.

        this.CHANGABLE_METHODS = ['filterSelf', 'selectRange'];
        this.DOWNSAMPLE_METHODS = ['downSample', 'lttbDownSample'];
        var dimensions;
        var assignStoreDimIdx = false;

        if (isSeriesDataSchema(dimensionsInput)) {
          dimensions = dimensionsInput.dimensions;
          this._dimOmitted = dimensionsInput.isDimensionOmitted();
          this._schema = dimensionsInput;
        } else {
          assignStoreDimIdx = true;
          dimensions = dimensionsInput;
        }

        dimensions = dimensions || ['x', 'y'];
        var dimensionInfos = {};
        var dimensionNames = [];
        var invertedIndicesMap = {};
        var needsHasOwn = false;
        var emptyObj = {};

        for (var i = 0; i < dimensions.length; i++) {
          // Use the original dimensions[i], where other flag props may exists.
          var dimInfoInput = dimensions[i];
          var dimensionInfo = isString(dimInfoInput) ? new SeriesDimensionDefine({
            name: dimInfoInput
          }) : !(dimInfoInput instanceof SeriesDimensionDefine) ? new SeriesDimensionDefine(dimInfoInput) : dimInfoInput;
          var dimensionName = dimensionInfo.name;
          dimensionInfo.type = dimensionInfo.type || 'float';

          if (!dimensionInfo.coordDim) {
            dimensionInfo.coordDim = dimensionName;
            dimensionInfo.coordDimIndex = 0;
          }

          var otherDims = dimensionInfo.otherDims = dimensionInfo.otherDims || {};
          dimensionNames.push(dimensionName);
          dimensionInfos[dimensionName] = dimensionInfo;

          if (emptyObj[dimensionName] != null) {
            needsHasOwn = true;
          }

          if (dimensionInfo.createInvertedIndices) {
            invertedIndicesMap[dimensionName] = [];
          }

          if (otherDims.itemName === 0) {
            this._nameDimIdx = i;
          }

          if (otherDims.itemId === 0) {
            this._idDimIdx = i;
          }

          if ("development" !== 'production') {
            assert(assignStoreDimIdx || dimensionInfo.storeDimIndex >= 0);
          }

          if (assignStoreDimIdx) {
            dimensionInfo.storeDimIndex = i;
          }
        }

        this.dimensions = dimensionNames;
        this._dimInfos = dimensionInfos;

        this._initGetDimensionInfo(needsHasOwn);

        this.hostModel = hostModel;
        this._invertedIndicesMap = invertedIndicesMap;

        if (this._dimOmitted) {
          var dimIdxToName_1 = this._dimIdxToName = createHashMap();
          each(dimensionNames, function (dimName) {
            dimIdxToName_1.set(dimensionInfos[dimName].storeDimIndex, dimName);
          });
        }
      }
      /**
       *
       * Get concrete dimension name by dimension name or dimension index.
       * If input a dimension name, do not validate whether the dimension name exits.
       *
       * @caution
       * @param dim Must make sure the dimension is `SeriesDimensionLoose`.
       * Because only those dimensions will have auto-generated dimension names if not
       * have a user-specified name, and other dimensions will get a return of null/undefined.
       *
       * @notice Because of this reason, should better use `getDimensionIndex` instead, for examples:
       * ```js
       * const val = data.getStore().get(data.getDimensionIndex(dim), dataIdx);
       * ```
       *
       * @return Concrete dim name.
       */


      SeriesData.prototype.getDimension = function (dim) {
        var dimIdx = this._recognizeDimIndex(dim);

        if (dimIdx == null) {
          return dim;
        }

        dimIdx = dim;

        if (!this._dimOmitted) {
          return this.dimensions[dimIdx];
        } // Retrieve from series dimension definition because it probably contains
        // generated dimension name (like 'x', 'y').


        var dimName = this._dimIdxToName.get(dimIdx);

        if (dimName != null) {
          return dimName;
        }

        var sourceDimDef = this._schema.getSourceDimension(dimIdx);

        if (sourceDimDef) {
          return sourceDimDef.name;
        }
      };
      /**
       * Get dimension index in data store. Return -1 if not found.
       * Can be used to index value from getRawValue.
       */


      SeriesData.prototype.getDimensionIndex = function (dim) {
        var dimIdx = this._recognizeDimIndex(dim);

        if (dimIdx != null) {
          return dimIdx;
        }

        if (dim == null) {
          return -1;
        }

        var dimInfo = this._getDimInfo(dim);

        return dimInfo ? dimInfo.storeDimIndex : this._dimOmitted ? this._schema.getSourceDimensionIndex(dim) : -1;
      };
      /**
       * The meanings of the input parameter `dim`:
       *
       * + If dim is a number (e.g., `1`), it means the index of the dimension.
       *   For example, `getDimension(0)` will return 'x' or 'lng' or 'radius'.
       * + If dim is a number-like string (e.g., `"1"`):
       *     + If there is the same concrete dim name defined in `series.dimensions` or `dataset.dimensions`,
       *        it means that concrete name.
       *     + If not, it will be converted to a number, which means the index of the dimension.
       *        (why? because of the backward compatibility. We have been tolerating number-like string in
       *        dimension setting, although now it seems that it is not a good idea.)
       *     For example, `visualMap[i].dimension: "1"` is the same meaning as `visualMap[i].dimension: 1`,
       *     if no dimension name is defined as `"1"`.
       * + If dim is a not-number-like string, it means the concrete dim name.
       *   For example, it can be be default name `"x"`, `"y"`, `"z"`, `"lng"`, `"lat"`, `"angle"`, `"radius"`,
       *   or customized in `dimensions` property of option like `"age"`.
       *
       * @return recognized `DimensionIndex`. Otherwise return null/undefined (means that dim is `DimensionName`).
       */


      SeriesData.prototype._recognizeDimIndex = function (dim) {
        if (isNumber(dim) // If being a number-like string but not being defined as a dimension name.
        || dim != null && !isNaN(dim) && !this._getDimInfo(dim) && (!this._dimOmitted || this._schema.getSourceDimensionIndex(dim) < 0)) {
          return +dim;
        }
      };

      SeriesData.prototype._getStoreDimIndex = function (dim) {
        var dimIdx = this.getDimensionIndex(dim);

        if ("development" !== 'production') {
          if (dimIdx == null) {
            throw new Error('Unknown dimension ' + dim);
          }
        }

        return dimIdx;
      };
      /**
       * Get type and calculation info of particular dimension
       * @param dim
       *        Dimension can be concrete names like x, y, z, lng, lat, angle, radius
       *        Or a ordinal number. For example getDimensionInfo(0) will return 'x' or 'lng' or 'radius'
       */


      SeriesData.prototype.getDimensionInfo = function (dim) {
        // Do not clone, because there may be categories in dimInfo.
        return this._getDimInfo(this.getDimension(dim));
      };

      SeriesData.prototype._initGetDimensionInfo = function (needsHasOwn) {
        var dimensionInfos = this._dimInfos;
        this._getDimInfo = needsHasOwn ? function (dimName) {
          return dimensionInfos.hasOwnProperty(dimName) ? dimensionInfos[dimName] : undefined;
        } : function (dimName) {
          return dimensionInfos[dimName];
        };
      };
      /**
       * concrete dimension name list on coord.
       */


      SeriesData.prototype.getDimensionsOnCoord = function () {
        return this._dimSummary.dataDimsOnCoord.slice();
      };

      SeriesData.prototype.mapDimension = function (coordDim, idx) {
        var dimensionsSummary = this._dimSummary;

        if (idx == null) {
          return dimensionsSummary.encodeFirstDimNotExtra[coordDim];
        }

        var dims = dimensionsSummary.encode[coordDim];
        return dims ? dims[idx] : null;
      };

      SeriesData.prototype.mapDimensionsAll = function (coordDim) {
        var dimensionsSummary = this._dimSummary;
        var dims = dimensionsSummary.encode[coordDim];
        return (dims || []).slice();
      };

      SeriesData.prototype.getStore = function () {
        return this._store;
      };
      /**
       * Initialize from data
       * @param data source or data or data store.
       * @param nameList The name of a datum is used on data diff and
       *        default label/tooltip.
       *        A name can be specified in encode.itemName,
       *        or dataItem.name (only for series option data),
       *        or provided in nameList from outside.
       */


      SeriesData.prototype.initData = function (data, nameList, dimValueGetter) {
        var _this = this;

        var store;

        if (data instanceof DataStore) {
          store = data;
        }

        if (!store) {
          var dimensions = this.dimensions;
          var provider = isSourceInstance(data) || isArrayLike(data) ? new DefaultDataProvider(data, dimensions.length) : data;
          store = new DataStore();
          var dimensionInfos = map$1(dimensions, function (dimName) {
            return {
              type: _this._dimInfos[dimName].type,
              property: dimName
            };
          });
          store.initData(provider, dimensionInfos, dimValueGetter);
        }

        this._store = store; // Reset

        this._nameList = (nameList || []).slice();
        this._idList = [];
        this._nameRepeatCount = {};

        this._doInit(0, store.count()); // Cache summary info for fast visit. See "dimensionHelper".
        // Needs to be initialized after store is prepared.


        this._dimSummary = summarizeDimensions(this, this._schema);
        this.userOutput = this._dimSummary.userOutput;
      };
      /**
       * Caution: Can be only called on raw data (before `this._indices` created).
       */


      SeriesData.prototype.appendData = function (data) {
        var range = this._store.appendData(data);

        this._doInit(range[0], range[1]);
      };
      /**
       * Caution: Can be only called on raw data (before `this._indices` created).
       * This method does not modify `rawData` (`dataProvider`), but only
       * add values to store.
       *
       * The final count will be increased by `Math.max(values.length, names.length)`.
       *
       * @param values That is the SourceType: 'arrayRows', like
       *        [
       *            [12, 33, 44],
       *            [NaN, 43, 1],
       *            ['-', 'asdf', 0]
       *        ]
       *        Each item is exactly corresponding to a dimension.
       */


      SeriesData.prototype.appendValues = function (values, names) {
        var _a = this._store.appendValues(values, names.length),
            start = _a.start,
            end = _a.end;

        var shouldMakeIdFromName = this._shouldMakeIdFromName();

        this._updateOrdinalMeta();

        if (names) {
          for (var idx = start; idx < end; idx++) {
            var sourceIdx = idx - start;
            this._nameList[idx] = names[sourceIdx];

            if (shouldMakeIdFromName) {
              makeIdFromName(this, idx);
            }
          }
        }
      };

      SeriesData.prototype._updateOrdinalMeta = function () {
        var store = this._store;
        var dimensions = this.dimensions;

        for (var i = 0; i < dimensions.length; i++) {
          var dimInfo = this._dimInfos[dimensions[i]];

          if (dimInfo.ordinalMeta) {
            store.collectOrdinalMeta(dimInfo.storeDimIndex, dimInfo.ordinalMeta);
          }
        }
      };

      SeriesData.prototype._shouldMakeIdFromName = function () {
        var provider = this._store.getProvider();

        return this._idDimIdx == null && provider.getSource().sourceFormat !== SOURCE_FORMAT_TYPED_ARRAY && !provider.fillStorage;
      };

      SeriesData.prototype._doInit = function (start, end) {
        if (start >= end) {
          return;
        }

        var store = this._store;
        var provider = store.getProvider();

        this._updateOrdinalMeta();

        var nameList = this._nameList;
        var idList = this._idList;
        var sourceFormat = provider.getSource().sourceFormat;
        var isFormatOriginal = sourceFormat === SOURCE_FORMAT_ORIGINAL; // Each data item is value
        // [1, 2]
        // 2
        // Bar chart, line chart which uses category axis
        // only gives the 'y' value. 'x' value is the indices of category
        // Use a tempValue to normalize the value to be a (x, y) value
        // If dataItem is {name: ...} or {id: ...}, it has highest priority.
        // This kind of ids and names are always stored `_nameList` and `_idList`.

        if (isFormatOriginal && !provider.pure) {
          var sharedDataItem = [];

          for (var idx = start; idx < end; idx++) {
            // NOTICE: Try not to write things into dataItem
            var dataItem = provider.getItem(idx, sharedDataItem);

            if (!this.hasItemOption && isDataItemOption(dataItem)) {
              this.hasItemOption = true;
            }

            if (dataItem) {
              var itemName = dataItem.name;

              if (nameList[idx] == null && itemName != null) {
                nameList[idx] = convertOptionIdName(itemName, null);
              }

              var itemId = dataItem.id;

              if (idList[idx] == null && itemId != null) {
                idList[idx] = convertOptionIdName(itemId, null);
              }
            }
          }
        }

        if (this._shouldMakeIdFromName()) {
          for (var idx = start; idx < end; idx++) {
            makeIdFromName(this, idx);
          }
        }

        prepareInvertedIndex(this);
      };
      /**
       * PENDING: In fact currently this function is only used to short-circuit
       * the calling of `scale.unionExtentFromData` when data have been filtered by modules
       * like "dataZoom". `scale.unionExtentFromData` is used to calculate data extent for series on
       * an axis, but if a "axis related data filter module" is used, the extent of the axis have
       * been fixed and no need to calling `scale.unionExtentFromData` actually.
       * But if we add "custom data filter" in future, which is not "axis related", this method may
       * be still needed.
       *
       * Optimize for the scenario that data is filtered by a given extent.
       * Consider that if data amount is more than hundreds of thousand,
       * extent calculation will cost more than 10ms and the cache will
       * be erased because of the filtering.
       */


      SeriesData.prototype.getApproximateExtent = function (dim) {
        return this._approximateExtent[dim] || this._store.getDataExtent(this._getStoreDimIndex(dim));
      };
      /**
       * Calculate extent on a filtered data might be time consuming.
       * Approximate extent is only used for: calculate extent of filtered data outside.
       */


      SeriesData.prototype.setApproximateExtent = function (extent, dim) {
        dim = this.getDimension(dim);
        this._approximateExtent[dim] = extent.slice();
      };

      SeriesData.prototype.getCalculationInfo = function (key) {
        return this._calculationInfo[key];
      };

      SeriesData.prototype.setCalculationInfo = function (key, value) {
        isObject$2(key) ? extend(this._calculationInfo, key) : this._calculationInfo[key] = value;
      };
      /**
       * @return Never be null/undefined. `number` will be converted to string. Because:
       * In most cases, name is used in display, where returning a string is more convenient.
       * In other cases, name is used in query (see `indexOfName`), where we can keep the
       * rule that name `2` equals to name `'2'`.
       */


      SeriesData.prototype.getName = function (idx) {
        var rawIndex = this.getRawIndex(idx);
        var name = this._nameList[rawIndex];

        if (name == null && this._nameDimIdx != null) {
          name = getIdNameFromStore(this, this._nameDimIdx, rawIndex);
        }

        if (name == null) {
          name = '';
        }

        return name;
      };

      SeriesData.prototype._getCategory = function (dimIdx, idx) {
        var ordinal = this._store.get(dimIdx, idx);

        var ordinalMeta = this._store.getOrdinalMeta(dimIdx);

        if (ordinalMeta) {
          return ordinalMeta.categories[ordinal];
        }

        return ordinal;
      };
      /**
       * @return Never null/undefined. `number` will be converted to string. Because:
       * In all cases having encountered at present, id is used in making diff comparison, which
       * are usually based on hash map. We can keep the rule that the internal id are always string
       * (treat `2` is the same as `'2'`) to make the related logic simple.
       */


      SeriesData.prototype.getId = function (idx) {
        return getId(this, this.getRawIndex(idx));
      };

      SeriesData.prototype.count = function () {
        return this._store.count();
      };
      /**
       * Get value. Return NaN if idx is out of range.
       *
       * @notice Should better to use `data.getStore().get(dimIndex, dataIdx)` instead.
       */


      SeriesData.prototype.get = function (dim, idx) {
        var store = this._store;
        var dimInfo = this._dimInfos[dim];

        if (dimInfo) {
          return store.get(dimInfo.storeDimIndex, idx);
        }
      };
      /**
       * @notice Should better to use `data.getStore().getByRawIndex(dimIndex, dataIdx)` instead.
       */


      SeriesData.prototype.getByRawIndex = function (dim, rawIdx) {
        var store = this._store;
        var dimInfo = this._dimInfos[dim];

        if (dimInfo) {
          return store.getByRawIndex(dimInfo.storeDimIndex, rawIdx);
        }
      };

      SeriesData.prototype.getIndices = function () {
        return this._store.getIndices();
      };

      SeriesData.prototype.getDataExtent = function (dim) {
        return this._store.getDataExtent(this._getStoreDimIndex(dim));
      };

      SeriesData.prototype.getSum = function (dim) {
        return this._store.getSum(this._getStoreDimIndex(dim));
      };

      SeriesData.prototype.getMedian = function (dim) {
        return this._store.getMedian(this._getStoreDimIndex(dim));
      };

      SeriesData.prototype.getValues = function (dimensions, idx) {
        var _this = this;

        var store = this._store;
        return isArray(dimensions) ? store.getValues(map$1(dimensions, function (dim) {
          return _this._getStoreDimIndex(dim);
        }), idx) : store.getValues(dimensions);
      };
      /**
       * If value is NaN. Including '-'
       * Only check the coord dimensions.
       */


      SeriesData.prototype.hasValue = function (idx) {
        var dataDimIndicesOnCoord = this._dimSummary.dataDimIndicesOnCoord;

        for (var i = 0, len = dataDimIndicesOnCoord.length; i < len; i++) {
          // Ordinal type originally can be string or number.
          // But when an ordinal type is used on coord, it can
          // not be string but only number. So we can also use isNaN.
          if (isNaN(this._store.get(dataDimIndicesOnCoord[i], idx))) {
            return false;
          }
        }

        return true;
      };
      /**
       * Retrieve the index with given name
       */


      SeriesData.prototype.indexOfName = function (name) {
        for (var i = 0, len = this._store.count(); i < len; i++) {
          if (this.getName(i) === name) {
            return i;
          }
        }

        return -1;
      };

      SeriesData.prototype.getRawIndex = function (idx) {
        return this._store.getRawIndex(idx);
      };

      SeriesData.prototype.indexOfRawIndex = function (rawIndex) {
        return this._store.indexOfRawIndex(rawIndex);
      };
      /**
       * Only support the dimension which inverted index created.
       * Do not support other cases until required.
       * @param dim concrete dim
       * @param value ordinal index
       * @return rawIndex
       */


      SeriesData.prototype.rawIndexOf = function (dim, value) {
        var invertedIndices = dim && this._invertedIndicesMap[dim];

        if ("development" !== 'production') {
          if (!invertedIndices) {
            throw new Error('Do not supported yet');
          }
        }

        var rawIndex = invertedIndices[value];

        if (rawIndex == null || isNaN(rawIndex)) {
          return INDEX_NOT_FOUND;
        }

        return rawIndex;
      };
      /**
       * Retrieve the index of nearest value
       * @param dim
       * @param value
       * @param [maxDistance=Infinity]
       * @return If and only if multiple indices has
       *         the same value, they are put to the result.
       */


      SeriesData.prototype.indicesOfNearest = function (dim, value, maxDistance) {
        return this._store.indicesOfNearest(this._getStoreDimIndex(dim), value, maxDistance);
      };

      SeriesData.prototype.each = function (dims, cb, ctx) {

        if (isFunction(dims)) {
          ctx = cb;
          cb = dims;
          dims = [];
        } // ctxCompat just for compat echarts3


        var fCtx = ctx || this;
        var dimIndices = map$1(normalizeDimensions(dims), this._getStoreDimIndex, this);

        this._store.each(dimIndices, fCtx ? bind(cb, fCtx) : cb);
      };

      SeriesData.prototype.filterSelf = function (dims, cb, ctx) {

        if (isFunction(dims)) {
          ctx = cb;
          cb = dims;
          dims = [];
        } // ctxCompat just for compat echarts3


        var fCtx = ctx || this;
        var dimIndices = map$1(normalizeDimensions(dims), this._getStoreDimIndex, this);
        this._store = this._store.filter(dimIndices, fCtx ? bind(cb, fCtx) : cb);
        return this;
      };
      /**
       * Select data in range. (For optimization of filter)
       * (Manually inline code, support 5 million data filtering in data zoom.)
       */


      SeriesData.prototype.selectRange = function (range) {

        var _this = this;

        var innerRange = {};
        var dims = keys(range);
        each(dims, function (dim) {
          var dimIdx = _this._getStoreDimIndex(dim);

          innerRange[dimIdx] = range[dim];
        });
        this._store = this._store.selectRange(innerRange);
        return this;
      };
      /* eslint-enable max-len */


      SeriesData.prototype.mapArray = function (dims, cb, ctx) {

        if (isFunction(dims)) {
          ctx = cb;
          cb = dims;
          dims = [];
        } // ctxCompat just for compat echarts3


        ctx = ctx || this;
        var result = [];
        this.each(dims, function () {
          result.push(cb && cb.apply(this, arguments));
        }, ctx);
        return result;
      };

      SeriesData.prototype.map = function (dims, cb, ctx, ctxCompat) {

        var fCtx = ctx || ctxCompat || this;
        var dimIndices = map$1(normalizeDimensions(dims), this._getStoreDimIndex, this);
        var list = cloneListForMapAndSample(this);
        list._store = this._store.map(dimIndices, fCtx ? bind(cb, fCtx) : cb);
        return list;
      };

      SeriesData.prototype.modify = function (dims, cb, ctx, ctxCompat) {
        var _this = this; // ctxCompat just for compat echarts3


        var fCtx = ctx || ctxCompat || this;

        if ("development" !== 'production') {
          each(normalizeDimensions(dims), function (dim) {
            var dimInfo = _this.getDimensionInfo(dim);

            if (!dimInfo.isCalculationCoord) {
              console.error('Danger: only stack dimension can be modified');
            }
          });
        }

        var dimIndices = map$1(normalizeDimensions(dims), this._getStoreDimIndex, this); // If do shallow clone here, if there are too many stacked series,
        // it still cost lots of memory, because `_store.dimensions` are not shared.
        // We should consider there probably be shallow clone happen in each series
        // in consequent filter/map.

        this._store.modify(dimIndices, fCtx ? bind(cb, fCtx) : cb);
      };
      /**
       * Large data down sampling on given dimension
       * @param sampleIndex Sample index for name and id
       */


      SeriesData.prototype.downSample = function (dimension, rate, sampleValue, sampleIndex) {
        var list = cloneListForMapAndSample(this);
        list._store = this._store.downSample(this._getStoreDimIndex(dimension), rate, sampleValue, sampleIndex);
        return list;
      };
      /**
       * Large data down sampling using largest-triangle-three-buckets
       * @param {string} valueDimension
       * @param {number} targetCount
       */


      SeriesData.prototype.lttbDownSample = function (valueDimension, rate) {
        var list = cloneListForMapAndSample(this);
        list._store = this._store.lttbDownSample(this._getStoreDimIndex(valueDimension), rate);
        return list;
      };

      SeriesData.prototype.getRawDataItem = function (idx) {
        return this._store.getRawDataItem(idx);
      };
      /**
       * Get model of one data item.
       */
      // TODO: Type of data item


      SeriesData.prototype.getItemModel = function (idx) {
        var hostModel = this.hostModel;
        var dataItem = this.getRawDataItem(idx);
        return new Model(dataItem, hostModel, hostModel && hostModel.ecModel);
      };
      /**
       * Create a data differ
       */


      SeriesData.prototype.diff = function (otherList) {
        var thisList = this;
        return new DataDiffer(otherList ? otherList.getStore().getIndices() : [], this.getStore().getIndices(), function (idx) {
          return getId(otherList, idx);
        }, function (idx) {
          return getId(thisList, idx);
        });
      };
      /**
       * Get visual property.
       */


      SeriesData.prototype.getVisual = function (key) {
        var visual = this._visual;
        return visual && visual[key];
      };

      SeriesData.prototype.setVisual = function (kvObj, val) {
        this._visual = this._visual || {};

        if (isObject$2(kvObj)) {
          extend(this._visual, kvObj);
        } else {
          this._visual[kvObj] = val;
        }
      };
      /**
       * Get visual property of single data item
       */
      // eslint-disable-next-line


      SeriesData.prototype.getItemVisual = function (idx, key) {
        var itemVisual = this._itemVisuals[idx];
        var val = itemVisual && itemVisual[key];

        if (val == null) {
          // Use global visual property
          return this.getVisual(key);
        }

        return val;
      };
      /**
       * If exists visual property of single data item
       */


      SeriesData.prototype.hasItemVisual = function () {
        return this._itemVisuals.length > 0;
      };
      /**
       * Make sure itemVisual property is unique
       */
      // TODO: use key to save visual to reduce memory.


      SeriesData.prototype.ensureUniqueItemVisual = function (idx, key) {
        var itemVisuals = this._itemVisuals;
        var itemVisual = itemVisuals[idx];

        if (!itemVisual) {
          itemVisual = itemVisuals[idx] = {};
        }

        var val = itemVisual[key];

        if (val == null) {
          val = this.getVisual(key); // TODO Performance?

          if (isArray(val)) {
            val = val.slice();
          } else if (isObject$2(val)) {
            val = extend({}, val);
          }

          itemVisual[key] = val;
        }

        return val;
      }; // eslint-disable-next-line


      SeriesData.prototype.setItemVisual = function (idx, key, value) {
        var itemVisual = this._itemVisuals[idx] || {};
        this._itemVisuals[idx] = itemVisual;

        if (isObject$2(key)) {
          extend(itemVisual, key);
        } else {
          itemVisual[key] = value;
        }
      };
      /**
       * Clear itemVisuals and list visual.
       */


      SeriesData.prototype.clearAllVisual = function () {
        this._visual = {};
        this._itemVisuals = [];
      };

      SeriesData.prototype.setLayout = function (key, val) {
        isObject$2(key) ? extend(this._layout, key) : this._layout[key] = val;
      };
      /**
       * Get layout property.
       */


      SeriesData.prototype.getLayout = function (key) {
        return this._layout[key];
      };
      /**
       * Get layout of single data item
       */


      SeriesData.prototype.getItemLayout = function (idx) {
        return this._itemLayouts[idx];
      };
      /**
       * Set layout of single data item
       */


      SeriesData.prototype.setItemLayout = function (idx, layout, merge) {
        this._itemLayouts[idx] = merge ? extend(this._itemLayouts[idx] || {}, layout) : layout;
      };
      /**
       * Clear all layout of single data item
       */


      SeriesData.prototype.clearItemLayouts = function () {
        this._itemLayouts.length = 0;
      };
      /**
       * Set graphic element relative to data. It can be set as null
       */


      SeriesData.prototype.setItemGraphicEl = function (idx, el) {
        var seriesIndex = this.hostModel && this.hostModel.seriesIndex;
        setCommonECData(seriesIndex, this.dataType, idx, el);
        this._graphicEls[idx] = el;
      };

      SeriesData.prototype.getItemGraphicEl = function (idx) {
        return this._graphicEls[idx];
      };

      SeriesData.prototype.eachItemGraphicEl = function (cb, context) {
        each(this._graphicEls, function (el, idx) {
          if (el) {
            cb && cb.call(context, el, idx);
          }
        });
      };
      /**
       * Shallow clone a new list except visual and layout properties, and graph elements.
       * New list only change the indices.
       */


      SeriesData.prototype.cloneShallow = function (list) {
        if (!list) {
          list = new SeriesData(this._schema ? this._schema : map$1(this.dimensions, this._getDimInfo, this), this.hostModel);
        }

        transferProperties(list, this);
        list._store = this._store;
        return list;
      };
      /**
       * Wrap some method to add more feature
       */


      SeriesData.prototype.wrapMethod = function (methodName, injectFunction) {
        var originalMethod = this[methodName];

        if (!isFunction(originalMethod)) {
          return;
        }

        this.__wrappedMethods = this.__wrappedMethods || [];

        this.__wrappedMethods.push(methodName);

        this[methodName] = function () {
          var res = originalMethod.apply(this, arguments);
          return injectFunction.apply(this, [res].concat(slice(arguments)));
        };
      }; // ----------------------------------------------------------
      // A work around for internal method visiting private member.
      // ----------------------------------------------------------


      SeriesData.internalField = function () {
        prepareInvertedIndex = function (data) {
          var invertedIndicesMap = data._invertedIndicesMap;
          each(invertedIndicesMap, function (invertedIndices, dim) {
            var dimInfo = data._dimInfos[dim]; // Currently, only dimensions that has ordinalMeta can create inverted indices.

            var ordinalMeta = dimInfo.ordinalMeta;
            var store = data._store;

            if (ordinalMeta) {
              invertedIndices = invertedIndicesMap[dim] = new CtorInt32Array$1(ordinalMeta.categories.length); // The default value of TypedArray is 0. To avoid miss
              // mapping to 0, we should set it as INDEX_NOT_FOUND.

              for (var i = 0; i < invertedIndices.length; i++) {
                invertedIndices[i] = INDEX_NOT_FOUND;
              }

              for (var i = 0; i < store.count(); i++) {
                // Only support the case that all values are distinct.
                invertedIndices[store.get(dimInfo.storeDimIndex, i)] = i;
              }
            }
          });
        };

        getIdNameFromStore = function (data, dimIdx, idx) {
          return convertOptionIdName(data._getCategory(dimIdx, idx), null);
        };
        /**
         * @see the comment of `List['getId']`.
         */


        getId = function (data, rawIndex) {
          var id = data._idList[rawIndex];

          if (id == null && data._idDimIdx != null) {
            id = getIdNameFromStore(data, data._idDimIdx, rawIndex);
          }

          if (id == null) {
            id = ID_PREFIX + rawIndex;
          }

          return id;
        };

        normalizeDimensions = function (dimensions) {
          if (!isArray(dimensions)) {
            dimensions = dimensions != null ? [dimensions] : [];
          }

          return dimensions;
        };
        /**
         * Data in excludeDimensions is copied, otherwise transferred.
         */


        cloneListForMapAndSample = function (original) {
          var list = new SeriesData(original._schema ? original._schema : map$1(original.dimensions, original._getDimInfo, original), original.hostModel); // FIXME If needs stackedOn, value may already been stacked

          transferProperties(list, original);
          return list;
        };

        transferProperties = function (target, source) {
          each(TRANSFERABLE_PROPERTIES.concat(source.__wrappedMethods || []), function (propName) {
            if (source.hasOwnProperty(propName)) {
              target[propName] = source[propName];
            }
          });
          target.__wrappedMethods = source.__wrappedMethods;
          each(CLONE_PROPERTIES, function (propName) {
            target[propName] = clone(source[propName]);
          });
          target._calculationInfo = extend({}, source._calculationInfo);
        };

        makeIdFromName = function (data, idx) {
          var nameList = data._nameList;
          var idList = data._idList;
          var nameDimIdx = data._nameDimIdx;
          var idDimIdx = data._idDimIdx;
          var name = nameList[idx];
          var id = idList[idx];

          if (name == null && nameDimIdx != null) {
            nameList[idx] = name = getIdNameFromStore(data, nameDimIdx, idx);
          }

          if (id == null && idDimIdx != null) {
            idList[idx] = id = getIdNameFromStore(data, idDimIdx, idx);
          }

          if (id == null && name != null) {
            var nameRepeatCount = data._nameRepeatCount;
            var nmCnt = nameRepeatCount[name] = (nameRepeatCount[name] || 0) + 1;
            id = name;

            if (nmCnt > 1) {
              id += '__ec__' + nmCnt;
            }

            idList[idx] = id;
          }
        };
      }();

      return SeriesData;
    }();

    /**
     * For outside usage compat (like echarts-gl are using it).
     */

    function createDimensions(source, opt) {
      return prepareSeriesDataSchema(source, opt).dimensions;
    }
    /**
     * This method builds the relationship between:
     * + "what the coord sys or series requires (see `coordDimensions`)",
     * + "what the user defines (in `encode` and `dimensions`, see `opt.dimensionsDefine` and `opt.encodeDefine`)"
     * + "what the data source provids (see `source`)".
     *
     * Some guess strategy will be adapted if user does not define something.
     * If no 'value' dimension specified, the first no-named dimension will be
     * named as 'value'.
     *
     * @return The results are always sorted by `storeDimIndex` asc.
     */

    function prepareSeriesDataSchema( // TODO: TYPE completeDimensions type
    source, opt) {
      if (!isSourceInstance(source)) {
        source = createSourceFromSeriesDataOption(source);
      }

      opt = opt || {};
      var sysDims = opt.coordDimensions || [];
      var dimsDef = opt.dimensionsDefine || source.dimensionsDefine || [];
      var coordDimNameMap = createHashMap();
      var resultList = [];
      var dimCount = getDimCount(source, sysDims, dimsDef, opt.dimensionsCount); // Try to ignore unused dimensions if sharing a high dimension datastore
      // 30 is an experience value.

      var omitUnusedDimensions = opt.canOmitUnusedDimensions && shouldOmitUnusedDimensions(dimCount);
      var isUsingSourceDimensionsDef = dimsDef === source.dimensionsDefine;
      var dataDimNameMap = isUsingSourceDimensionsDef ? ensureSourceDimNameMap(source) : createDimNameMap(dimsDef);
      var encodeDef = opt.encodeDefine;

      if (!encodeDef && opt.encodeDefaulter) {
        encodeDef = opt.encodeDefaulter(source, dimCount);
      }

      var encodeDefMap = createHashMap(encodeDef);
      var indicesMap = new CtorInt32Array(dimCount);

      for (var i = 0; i < indicesMap.length; i++) {
        indicesMap[i] = -1;
      }

      function getResultItem(dimIdx) {
        var idx = indicesMap[dimIdx];

        if (idx < 0) {
          var dimDefItemRaw = dimsDef[dimIdx];
          var dimDefItem = isObject(dimDefItemRaw) ? dimDefItemRaw : {
            name: dimDefItemRaw
          };
          var resultItem = new SeriesDimensionDefine();
          var userDimName = dimDefItem.name;

          if (userDimName != null && dataDimNameMap.get(userDimName) != null) {
            // Only if `series.dimensions` is defined in option
            // displayName, will be set, and dimension will be displayed vertically in
            // tooltip by default.
            resultItem.name = resultItem.displayName = userDimName;
          }

          dimDefItem.type != null && (resultItem.type = dimDefItem.type);
          dimDefItem.displayName != null && (resultItem.displayName = dimDefItem.displayName);
          var newIdx = resultList.length;
          indicesMap[dimIdx] = newIdx;
          resultItem.storeDimIndex = dimIdx;
          resultList.push(resultItem);
          return resultItem;
        }

        return resultList[idx];
      }

      if (!omitUnusedDimensions) {
        for (var i = 0; i < dimCount; i++) {
          getResultItem(i);
        }
      } // Set `coordDim` and `coordDimIndex` by `encodeDefMap` and normalize `encodeDefMap`.


      encodeDefMap.each(function (dataDimsRaw, coordDim) {
        var dataDims = normalizeToArray(dataDimsRaw).slice(); // Note: It is allowed that `dataDims.length` is `0`, e.g., options is
        // `{encode: {x: -1, y: 1}}`. Should not filter anything in
        // this case.

        if (dataDims.length === 1 && !isString(dataDims[0]) && dataDims[0] < 0) {
          encodeDefMap.set(coordDim, false);
          return;
        }

        var validDataDims = encodeDefMap.set(coordDim, []);
        each(dataDims, function (resultDimIdxOrName, idx) {
          // The input resultDimIdx can be dim name or index.
          var resultDimIdx = isString(resultDimIdxOrName) ? dataDimNameMap.get(resultDimIdxOrName) : resultDimIdxOrName;

          if (resultDimIdx != null && resultDimIdx < dimCount) {
            validDataDims[idx] = resultDimIdx;
            applyDim(getResultItem(resultDimIdx), coordDim, idx);
          }
        });
      }); // Apply templates and default order from `sysDims`.

      var availDimIdx = 0;
      each(sysDims, function (sysDimItemRaw) {
        var coordDim;
        var sysDimItemDimsDef;
        var sysDimItemOtherDims;
        var sysDimItem;

        if (isString(sysDimItemRaw)) {
          coordDim = sysDimItemRaw;
          sysDimItem = {};
        } else {
          sysDimItem = sysDimItemRaw;
          coordDim = sysDimItem.name;
          var ordinalMeta = sysDimItem.ordinalMeta;
          sysDimItem.ordinalMeta = null;
          sysDimItem = extend({}, sysDimItem);
          sysDimItem.ordinalMeta = ordinalMeta; // `coordDimIndex` should not be set directly.

          sysDimItemDimsDef = sysDimItem.dimsDef;
          sysDimItemOtherDims = sysDimItem.otherDims;
          sysDimItem.name = sysDimItem.coordDim = sysDimItem.coordDimIndex = sysDimItem.dimsDef = sysDimItem.otherDims = null;
        }

        var dataDims = encodeDefMap.get(coordDim); // negative resultDimIdx means no need to mapping.

        if (dataDims === false) {
          return;
        }

        dataDims = normalizeToArray(dataDims); // dimensions provides default dim sequences.

        if (!dataDims.length) {
          for (var i = 0; i < (sysDimItemDimsDef && sysDimItemDimsDef.length || 1); i++) {
            while (availDimIdx < dimCount && getResultItem(availDimIdx).coordDim != null) {
              availDimIdx++;
            }

            availDimIdx < dimCount && dataDims.push(availDimIdx++);
          }
        } // Apply templates.


        each(dataDims, function (resultDimIdx, coordDimIndex) {
          var resultItem = getResultItem(resultDimIdx); // Coordinate system has a higher priority on dim type than source.

          if (isUsingSourceDimensionsDef && sysDimItem.type != null) {
            resultItem.type = sysDimItem.type;
          }

          applyDim(defaults(resultItem, sysDimItem), coordDim, coordDimIndex);

          if (resultItem.name == null && sysDimItemDimsDef) {
            var sysDimItemDimsDefItem = sysDimItemDimsDef[coordDimIndex];
            !isObject(sysDimItemDimsDefItem) && (sysDimItemDimsDefItem = {
              name: sysDimItemDimsDefItem
            });
            resultItem.name = resultItem.displayName = sysDimItemDimsDefItem.name;
            resultItem.defaultTooltip = sysDimItemDimsDefItem.defaultTooltip;
          } // FIXME refactor, currently only used in case: {otherDims: {tooltip: false}}


          sysDimItemOtherDims && defaults(resultItem.otherDims, sysDimItemOtherDims);
        });
      });

      function applyDim(resultItem, coordDim, coordDimIndex) {
        if (VISUAL_DIMENSIONS.get(coordDim) != null) {
          resultItem.otherDims[coordDim] = coordDimIndex;
        } else {
          resultItem.coordDim = coordDim;
          resultItem.coordDimIndex = coordDimIndex;
          coordDimNameMap.set(coordDim, true);
        }
      } // Make sure the first extra dim is 'value'.


      var generateCoord = opt.generateCoord;
      var generateCoordCount = opt.generateCoordCount;
      var fromZero = generateCoordCount != null;
      generateCoordCount = generateCoord ? generateCoordCount || 1 : 0;
      var extra = generateCoord || 'value';

      function ifNoNameFillWithCoordName(resultItem) {
        if (resultItem.name == null) {
          // Duplication will be removed in the next step.
          resultItem.name = resultItem.coordDim;
        }
      } // Set dim `name` and other `coordDim` and other props.


      if (!omitUnusedDimensions) {
        for (var resultDimIdx = 0; resultDimIdx < dimCount; resultDimIdx++) {
          var resultItem = getResultItem(resultDimIdx);
          var coordDim = resultItem.coordDim;

          if (coordDim == null) {
            // TODO no need to generate coordDim for isExtraCoord?
            resultItem.coordDim = genCoordDimName(extra, coordDimNameMap, fromZero);
            resultItem.coordDimIndex = 0; // Series specified generateCoord is using out.

            if (!generateCoord || generateCoordCount <= 0) {
              resultItem.isExtraCoord = true;
            }

            generateCoordCount--;
          }

          ifNoNameFillWithCoordName(resultItem);

          if (resultItem.type == null && (guessOrdinal(source, resultDimIdx) === BE_ORDINAL.Must // Consider the case:
          // {
          //    dataset: {source: [
          //        ['2001', 123],
          //        ['2002', 456],
          //        ...
          //        ['The others', 987],
          //    ]},
          //    series: {type: 'pie'}
          // }
          // The first column should better be treated as a "ordinal" although it
          // might not be detected as an "ordinal" by `guessOrdinal`.
          || resultItem.isExtraCoord && (resultItem.otherDims.itemName != null || resultItem.otherDims.seriesName != null))) {
            resultItem.type = 'ordinal';
          }
        }
      } else {
        each(resultList, function (resultItem) {
          // PENDING: guessOrdinal or let user specify type: 'ordinal' manually?
          ifNoNameFillWithCoordName(resultItem);
        }); // Sort dimensions: there are some rule that use the last dim as label,
        // and for some latter travel process easier.

        resultList.sort(function (item0, item1) {
          return item0.storeDimIndex - item1.storeDimIndex;
        });
      }

      removeDuplication(resultList);
      return new SeriesDataSchema({
        source: source,
        dimensions: resultList,
        fullDimensionCount: dimCount,
        dimensionOmitted: omitUnusedDimensions
      });
    }

    function removeDuplication(result) {
      var duplicationMap = createHashMap();

      for (var i = 0; i < result.length; i++) {
        var dim = result[i];
        var dimOriginalName = dim.name;
        var count = duplicationMap.get(dimOriginalName) || 0;

        if (count > 0) {
          // Starts from 0.
          dim.name = dimOriginalName + (count - 1);
        }

        count++;
        duplicationMap.set(dimOriginalName, count);
      }
    } // ??? TODO
    // Originally detect dimCount by data[0]. Should we
    // optimize it to only by sysDims and dimensions and encode.
    // So only necessary dims will be initialized.
    // But
    // (1) custom series should be considered. where other dims
    // may be visited.
    // (2) sometimes user need to calculate bubble size or use visualMap
    // on other dimensions besides coordSys needed.
    // So, dims that is not used by system, should be shared in data store?


    function getDimCount(source, sysDims, dimsDef, optDimCount) {
      // Note that the result dimCount should not small than columns count
      // of data, otherwise `dataDimNameMap` checking will be incorrect.
      var dimCount = Math.max(source.dimensionsDetectedCount || 1, sysDims.length, dimsDef.length, optDimCount || 0);
      each(sysDims, function (sysDimItem) {
        var sysDimItemDimsDef;

        if (isObject(sysDimItem) && (sysDimItemDimsDef = sysDimItem.dimsDef)) {
          dimCount = Math.max(dimCount, sysDimItemDimsDef.length);
        }
      });
      return dimCount;
    }

    function genCoordDimName(name, map, fromZero) {
      if (fromZero || map.hasKey(name)) {
        var i = 0;

        while (map.hasKey(name + i)) {
          i++;
        }

        name += i;
      }

      map.set(name, true);
      return name;
    }

    /**
     * @class
     * For example:
     * {
     *     coordSysName: 'cartesian2d',
     *     coordSysDims: ['x', 'y', ...],
     *     axisMap: HashMap({
     *         x: xAxisModel,
     *         y: yAxisModel
     *     }),
     *     categoryAxisMap: HashMap({
     *         x: xAxisModel,
     *         y: undefined
     *     }),
     *     // The index of the first category axis in `coordSysDims`.
     *     // `null/undefined` means no category axis exists.
     *     firstCategoryDimIndex: 1,
     *     // To replace user specified encode.
     * }
     */

    var CoordSysInfo =
    /** @class */
    function () {
      function CoordSysInfo(coordSysName) {
        this.coordSysDims = [];
        this.axisMap = createHashMap();
        this.categoryAxisMap = createHashMap();
        this.coordSysName = coordSysName;
      }

      return CoordSysInfo;
    }();

    function getCoordSysInfoBySeries(seriesModel) {
      var coordSysName = seriesModel.get('coordinateSystem');
      var result = new CoordSysInfo(coordSysName);
      var fetch = fetchers[coordSysName];

      if (fetch) {
        fetch(seriesModel, result, result.axisMap, result.categoryAxisMap);
        return result;
      }
    }
    var fetchers = {
      cartesian2d: function (seriesModel, result, axisMap, categoryAxisMap) {
        var xAxisModel = seriesModel.getReferringComponents('xAxis', SINGLE_REFERRING).models[0];
        var yAxisModel = seriesModel.getReferringComponents('yAxis', SINGLE_REFERRING).models[0];

        if ("development" !== 'production') {
          if (!xAxisModel) {
            throw new Error('xAxis "' + retrieve(seriesModel.get('xAxisIndex'), seriesModel.get('xAxisId'), 0) + '" not found');
          }

          if (!yAxisModel) {
            throw new Error('yAxis "' + retrieve(seriesModel.get('xAxisIndex'), seriesModel.get('yAxisId'), 0) + '" not found');
          }
        }

        result.coordSysDims = ['x', 'y'];
        axisMap.set('x', xAxisModel);
        axisMap.set('y', yAxisModel);

        if (isCategory(xAxisModel)) {
          categoryAxisMap.set('x', xAxisModel);
          result.firstCategoryDimIndex = 0;
        }

        if (isCategory(yAxisModel)) {
          categoryAxisMap.set('y', yAxisModel);
          result.firstCategoryDimIndex == null && (result.firstCategoryDimIndex = 1);
        }
      },
      singleAxis: function (seriesModel, result, axisMap, categoryAxisMap) {
        var singleAxisModel = seriesModel.getReferringComponents('singleAxis', SINGLE_REFERRING).models[0];

        if ("development" !== 'production') {
          if (!singleAxisModel) {
            throw new Error('singleAxis should be specified.');
          }
        }

        result.coordSysDims = ['single'];
        axisMap.set('single', singleAxisModel);

        if (isCategory(singleAxisModel)) {
          categoryAxisMap.set('single', singleAxisModel);
          result.firstCategoryDimIndex = 0;
        }
      },
      polar: function (seriesModel, result, axisMap, categoryAxisMap) {
        var polarModel = seriesModel.getReferringComponents('polar', SINGLE_REFERRING).models[0];
        var radiusAxisModel = polarModel.findAxisModel('radiusAxis');
        var angleAxisModel = polarModel.findAxisModel('angleAxis');

        if ("development" !== 'production') {
          if (!angleAxisModel) {
            throw new Error('angleAxis option not found');
          }

          if (!radiusAxisModel) {
            throw new Error('radiusAxis option not found');
          }
        }

        result.coordSysDims = ['radius', 'angle'];
        axisMap.set('radius', radiusAxisModel);
        axisMap.set('angle', angleAxisModel);

        if (isCategory(radiusAxisModel)) {
          categoryAxisMap.set('radius', radiusAxisModel);
          result.firstCategoryDimIndex = 0;
        }

        if (isCategory(angleAxisModel)) {
          categoryAxisMap.set('angle', angleAxisModel);
          result.firstCategoryDimIndex == null && (result.firstCategoryDimIndex = 1);
        }
      },
      geo: function (seriesModel, result, axisMap, categoryAxisMap) {
        result.coordSysDims = ['lng', 'lat'];
      },
      parallel: function (seriesModel, result, axisMap, categoryAxisMap) {
        var ecModel = seriesModel.ecModel;
        var parallelModel = ecModel.getComponent('parallel', seriesModel.get('parallelIndex'));
        var coordSysDims = result.coordSysDims = parallelModel.dimensions.slice();
        each(parallelModel.parallelAxisIndex, function (axisIndex, index) {
          var axisModel = ecModel.getComponent('parallelAxis', axisIndex);
          var axisDim = coordSysDims[index];
          axisMap.set(axisDim, axisModel);

          if (isCategory(axisModel)) {
            categoryAxisMap.set(axisDim, axisModel);

            if (result.firstCategoryDimIndex == null) {
              result.firstCategoryDimIndex = index;
            }
          }
        });
      }
    };

    function isCategory(axisModel) {
      return axisModel.get('type') === 'category';
    }

    /**
     * Note that it is too complicated to support 3d stack by value
     * (have to create two-dimension inverted index), so in 3d case
     * we just support that stacked by index.
     *
     * @param seriesModel
     * @param dimensionsInput The same as the input of <module:echarts/data/SeriesData>.
     *        The input will be modified.
     * @param opt
     * @param opt.stackedCoordDimension Specify a coord dimension if needed.
     * @param opt.byIndex=false
     * @return calculationInfo
     * {
     *     stackedDimension: string
     *     stackedByDimension: string
     *     isStackedByIndex: boolean
     *     stackedOverDimension: string
     *     stackResultDimension: string
     * }
     */

    function enableDataStack(seriesModel, dimensionsInput, opt) {
      opt = opt || {};
      var byIndex = opt.byIndex;
      var stackedCoordDimension = opt.stackedCoordDimension;
      var dimensionDefineList;
      var schema;
      var store;

      if (isLegacyDimensionsInput(dimensionsInput)) {
        dimensionDefineList = dimensionsInput;
      } else {
        schema = dimensionsInput.schema;
        dimensionDefineList = schema.dimensions;
        store = dimensionsInput.store;
      } // Compatibal: when `stack` is set as '', do not stack.


      var mayStack = !!(seriesModel && seriesModel.get('stack'));
      var stackedByDimInfo;
      var stackedDimInfo;
      var stackResultDimension;
      var stackedOverDimension;
      each(dimensionDefineList, function (dimensionInfo, index) {
        if (isString(dimensionInfo)) {
          dimensionDefineList[index] = dimensionInfo = {
            name: dimensionInfo
          };
        }

        if (mayStack && !dimensionInfo.isExtraCoord) {
          // Find the first ordinal dimension as the stackedByDimInfo.
          if (!byIndex && !stackedByDimInfo && dimensionInfo.ordinalMeta) {
            stackedByDimInfo = dimensionInfo;
          } // Find the first stackable dimension as the stackedDimInfo.


          if (!stackedDimInfo && dimensionInfo.type !== 'ordinal' && dimensionInfo.type !== 'time' && (!stackedCoordDimension || stackedCoordDimension === dimensionInfo.coordDim)) {
            stackedDimInfo = dimensionInfo;
          }
        }
      });

      if (stackedDimInfo && !byIndex && !stackedByDimInfo) {
        // Compatible with previous design, value axis (time axis) only stack by index.
        // It may make sense if the user provides elaborately constructed data.
        byIndex = true;
      } // Add stack dimension, they can be both calculated by coordinate system in `unionExtent`.
      // That put stack logic in List is for using conveniently in echarts extensions, but it
      // might not be a good way.


      if (stackedDimInfo) {
        // Use a weird name that not duplicated with other names.
        // Also need to use seriesModel.id as postfix because different
        // series may share same data store. The stack dimension needs to be distinguished.
        stackResultDimension = '__\0ecstackresult_' + seriesModel.id;
        stackedOverDimension = '__\0ecstackedover_' + seriesModel.id; // Create inverted index to fast query index by value.

        if (stackedByDimInfo) {
          stackedByDimInfo.createInvertedIndices = true;
        }

        var stackedDimCoordDim_1 = stackedDimInfo.coordDim;
        var stackedDimType = stackedDimInfo.type;
        var stackedDimCoordIndex_1 = 0;
        each(dimensionDefineList, function (dimensionInfo) {
          if (dimensionInfo.coordDim === stackedDimCoordDim_1) {
            stackedDimCoordIndex_1++;
          }
        });
        var stackedOverDimensionDefine = {
          name: stackResultDimension,
          coordDim: stackedDimCoordDim_1,
          coordDimIndex: stackedDimCoordIndex_1,
          type: stackedDimType,
          isExtraCoord: true,
          isCalculationCoord: true,
          storeDimIndex: dimensionDefineList.length
        };
        var stackResultDimensionDefine = {
          name: stackedOverDimension,
          // This dimension contains stack base (generally, 0), so do not set it as
          // `stackedDimCoordDim` to avoid extent calculation, consider log scale.
          coordDim: stackedOverDimension,
          coordDimIndex: stackedDimCoordIndex_1 + 1,
          type: stackedDimType,
          isExtraCoord: true,
          isCalculationCoord: true,
          storeDimIndex: dimensionDefineList.length + 1
        };

        if (schema) {
          if (store) {
            stackedOverDimensionDefine.storeDimIndex = store.ensureCalculationDimension(stackedOverDimension, stackedDimType);
            stackResultDimensionDefine.storeDimIndex = store.ensureCalculationDimension(stackResultDimension, stackedDimType);
          }

          schema.appendCalculationDimension(stackedOverDimensionDefine);
          schema.appendCalculationDimension(stackResultDimensionDefine);
        } else {
          dimensionDefineList.push(stackedOverDimensionDefine);
          dimensionDefineList.push(stackResultDimensionDefine);
        }
      }

      return {
        stackedDimension: stackedDimInfo && stackedDimInfo.name,
        stackedByDimension: stackedByDimInfo && stackedByDimInfo.name,
        isStackedByIndex: byIndex,
        stackedOverDimension: stackedOverDimension,
        stackResultDimension: stackResultDimension
      };
    }

    function isLegacyDimensionsInput(dimensionsInput) {
      return !isSeriesDataSchema(dimensionsInput.schema);
    }

    function isDimensionStacked(data, stackedDim) {
      // Each single series only maps to one pair of axis. So we do not need to
      // check stackByDim, whatever stacked by a dimension or stacked by index.
      return !!stackedDim && stackedDim === data.getCalculationInfo('stackedDimension');
    }
    function getStackedDimension(data, targetDim) {
      return isDimensionStacked(data, targetDim) ? data.getCalculationInfo('stackResultDimension') : targetDim;
    }

    function getCoordSysDimDefs(seriesModel, coordSysInfo) {
      var coordSysName = seriesModel.get('coordinateSystem');
      var registeredCoordSys = CoordinateSystemManager.get(coordSysName);
      var coordSysDimDefs;

      if (coordSysInfo && coordSysInfo.coordSysDims) {
        coordSysDimDefs = map(coordSysInfo.coordSysDims, function (dim) {
          var dimInfo = {
            name: dim
          };
          var axisModel = coordSysInfo.axisMap.get(dim);

          if (axisModel) {
            var axisType = axisModel.get('type');
            dimInfo.type = getDimensionTypeByAxis(axisType);
          }

          return dimInfo;
        });
      }

      if (!coordSysDimDefs) {
        // Get dimensions from registered coordinate system
        coordSysDimDefs = registeredCoordSys && (registeredCoordSys.getDimensionsInfo ? registeredCoordSys.getDimensionsInfo() : registeredCoordSys.dimensions.slice()) || ['x', 'y'];
      }

      return coordSysDimDefs;
    }

    function injectOrdinalMeta(dimInfoList, createInvertedIndices, coordSysInfo) {
      var firstCategoryDimIndex;
      var hasNameEncode;
      coordSysInfo && each(dimInfoList, function (dimInfo, dimIndex) {
        var coordDim = dimInfo.coordDim;
        var categoryAxisModel = coordSysInfo.categoryAxisMap.get(coordDim);

        if (categoryAxisModel) {
          if (firstCategoryDimIndex == null) {
            firstCategoryDimIndex = dimIndex;
          }

          dimInfo.ordinalMeta = categoryAxisModel.getOrdinalMeta();

          if (createInvertedIndices) {
            dimInfo.createInvertedIndices = true;
          }
        }

        if (dimInfo.otherDims.itemName != null) {
          hasNameEncode = true;
        }
      });

      if (!hasNameEncode && firstCategoryDimIndex != null) {
        dimInfoList[firstCategoryDimIndex].otherDims.itemName = 0;
      }

      return firstCategoryDimIndex;
    }
    /**
     * Caution: there are side effects to `sourceManager` in this method.
     * Should better only be called in `Series['getInitialData']`.
     */


    function createSeriesData(sourceRaw, seriesModel, opt) {
      opt = opt || {};
      var sourceManager = seriesModel.getSourceManager();
      var source;
      var isOriginalSource = false;

      if (sourceRaw) {
        isOriginalSource = true;
        source = createSourceFromSeriesDataOption(sourceRaw);
      } else {
        source = sourceManager.getSource(); // Is series.data. not dataset.

        isOriginalSource = source.sourceFormat === SOURCE_FORMAT_ORIGINAL;
      }

      var coordSysInfo = getCoordSysInfoBySeries(seriesModel);
      var coordSysDimDefs = getCoordSysDimDefs(seriesModel, coordSysInfo);
      var useEncodeDefaulter = opt.useEncodeDefaulter;
      var encodeDefaulter = isFunction(useEncodeDefaulter) ? useEncodeDefaulter : useEncodeDefaulter ? curry(makeSeriesEncodeForAxisCoordSys, coordSysDimDefs, seriesModel) : null;
      var createDimensionOptions = {
        coordDimensions: coordSysDimDefs,
        generateCoord: opt.generateCoord,
        encodeDefine: seriesModel.getEncode(),
        encodeDefaulter: encodeDefaulter,
        canOmitUnusedDimensions: !isOriginalSource
      };
      var schema = prepareSeriesDataSchema(source, createDimensionOptions);
      var firstCategoryDimIndex = injectOrdinalMeta(schema.dimensions, opt.createInvertedIndices, coordSysInfo);
      var store = !isOriginalSource ? sourceManager.getSharedDataStore(schema) : null;
      var stackCalculationInfo = enableDataStack(seriesModel, {
        schema: schema,
        store: store
      });
      var data = new SeriesData(schema, seriesModel);
      data.setCalculationInfo(stackCalculationInfo);
      var dimValueGetter = firstCategoryDimIndex != null && isNeedCompleteOrdinalData(source) ? function (itemOpt, dimName, dataIndex, dimIndex) {
        // Use dataIndex as ordinal value in categoryAxis
        return dimIndex === firstCategoryDimIndex ? dataIndex : this.defaultDimValueGetter(itemOpt, dimName, dataIndex, dimIndex);
      } : null;
      data.hasItemOption = false;
      data.initData( // Try to reuse the data store in sourceManager if using dataset.
      isOriginalSource ? source : store, null, dimValueGetter);
      return data;
    }

    function isNeedCompleteOrdinalData(source) {
      if (source.sourceFormat === SOURCE_FORMAT_ORIGINAL) {
        var sampleItem = firstDataNotNull(source.data || []);
        return !isArray(getDataItemValue(sampleItem));
      }
    }

    function firstDataNotNull(arr) {
      var i = 0;

      while (i < arr.length && arr[i] == null) {
        i++;
      }

      return arr[i];
    }

    var Scale =
    /** @class */
    function () {
      function Scale(setting) {
        this._setting = setting || {};
        this._extent = [Infinity, -Infinity];
      }

      Scale.prototype.getSetting = function (name) {
        return this._setting[name];
      };
      /**
       * Set extent from data
       */


      Scale.prototype.unionExtent = function (other) {
        var extent = this._extent;
        other[0] < extent[0] && (extent[0] = other[0]);
        other[1] > extent[1] && (extent[1] = other[1]); // not setExtent because in log axis it may transformed to power
        // this.setExtent(extent[0], extent[1]);
      };
      /**
       * Set extent from data
       */


      Scale.prototype.unionExtentFromData = function (data, dim) {
        this.unionExtent(data.getApproximateExtent(dim));
      };
      /**
       * Get extent
       *
       * Extent is always in increase order.
       */


      Scale.prototype.getExtent = function () {
        return this._extent.slice();
      };
      /**
       * Set extent
       */


      Scale.prototype.setExtent = function (start, end) {
        var thisExtent = this._extent;

        if (!isNaN(start)) {
          thisExtent[0] = start;
        }

        if (!isNaN(end)) {
          thisExtent[1] = end;
        }
      };
      /**
       * If value is in extent range
       */


      Scale.prototype.isInExtentRange = function (value) {
        return this._extent[0] <= value && this._extent[1] >= value;
      };
      /**
       * When axis extent depends on data and no data exists,
       * axis ticks should not be drawn, which is named 'blank'.
       */


      Scale.prototype.isBlank = function () {
        return this._isBlank;
      };
      /**
       * When axis extent depends on data and no data exists,
       * axis ticks should not be drawn, which is named 'blank'.
       */


      Scale.prototype.setBlank = function (isBlank) {
        this._isBlank = isBlank;
      };

      return Scale;
    }();

    enableClassManagement(Scale);

    var uidBase = 0;

    var OrdinalMeta =
    /** @class */
    function () {
      function OrdinalMeta(opt) {
        this.categories = opt.categories || [];
        this._needCollect = opt.needCollect;
        this._deduplication = opt.deduplication;
        this.uid = ++uidBase;
      }

      OrdinalMeta.createByAxisModel = function (axisModel) {
        var option = axisModel.option;
        var data = option.data;
        var categories = data && map(data, getName);
        return new OrdinalMeta({
          categories: categories,
          needCollect: !categories,
          // deduplication is default in axis.
          deduplication: option.dedplication !== false
        });
      };

      OrdinalMeta.prototype.getOrdinal = function (category) {
        // @ts-ignore
        return this._getOrCreateMap().get(category);
      };
      /**
       * @return The ordinal. If not found, return NaN.
       */


      OrdinalMeta.prototype.parseAndCollect = function (category) {
        var index;
        var needCollect = this._needCollect; // The value of category dim can be the index of the given category set.
        // This feature is only supported when !needCollect, because we should
        // consider a common case: a value is 2017, which is a number but is
        // expected to be tread as a category. This case usually happen in dataset,
        // where it happent to be no need of the index feature.

        if (!isString(category) && !needCollect) {
          return category;
        } // Optimize for the scenario:
        // category is ['2012-01-01', '2012-01-02', ...], where the input
        // data has been ensured not duplicate and is large data.
        // Notice, if a dataset dimension provide categroies, usually echarts
        // should remove duplication except user tell echarts dont do that
        // (set axis.deduplication = false), because echarts do not know whether
        // the values in the category dimension has duplication (consider the
        // parallel-aqi example)


        if (needCollect && !this._deduplication) {
          index = this.categories.length;
          this.categories[index] = category;
          return index;
        }

        var map = this._getOrCreateMap(); // @ts-ignore


        index = map.get(category);

        if (index == null) {
          if (needCollect) {
            index = this.categories.length;
            this.categories[index] = category; // @ts-ignore

            map.set(category, index);
          } else {
            index = NaN;
          }
        }

        return index;
      }; // Consider big data, do not create map until needed.


      OrdinalMeta.prototype._getOrCreateMap = function () {
        return this._map || (this._map = createHashMap(this.categories));
      };

      return OrdinalMeta;
    }();

    function getName(obj) {
      if (isObject(obj) && obj.value != null) {
        return obj.value;
      } else {
        return obj + '';
      }
    }

    function isValueNice(val) {
      var exp10 = Math.pow(10, quantityExponent(Math.abs(val)));
      var f = Math.abs(val / exp10);
      return f === 0 || f === 1 || f === 2 || f === 3 || f === 5;
    }
    function isIntervalOrLogScale(scale) {
      return scale.type === 'interval' || scale.type === 'log';
    }
    /**
     * @param extent Both extent[0] and extent[1] should be valid number.
     *               Should be extent[0] < extent[1].
     * @param splitNumber splitNumber should be >= 1.
     */

    function intervalScaleNiceTicks(extent, splitNumber, minInterval, maxInterval) {
      var result = {};
      var span = extent[1] - extent[0];
      var interval = result.interval = nice(span / splitNumber, true);

      if (minInterval != null && interval < minInterval) {
        interval = result.interval = minInterval;
      }

      if (maxInterval != null && interval > maxInterval) {
        interval = result.interval = maxInterval;
      } // Tow more digital for tick.


      var precision = result.intervalPrecision = getIntervalPrecision(interval); // Niced extent inside original extent

      var niceTickExtent = result.niceTickExtent = [round(Math.ceil(extent[0] / interval) * interval, precision), round(Math.floor(extent[1] / interval) * interval, precision)];
      fixExtent(niceTickExtent, extent);
      return result;
    }
    function increaseInterval(interval) {
      var exp10 = Math.pow(10, quantityExponent(interval)); // Increase interval

      var f = interval / exp10;

      if (!f) {
        f = 1;
      } else if (f === 2) {
        f = 3;
      } else if (f === 3) {
        f = 5;
      } else {
        // f is 1 or 5
        f *= 2;
      }

      return round(f * exp10);
    }
    /**
     * @return interval precision
     */

    function getIntervalPrecision(interval) {
      // Tow more digital for tick.
      return getPrecision(interval) + 2;
    }

    function clamp(niceTickExtent, idx, extent) {
      niceTickExtent[idx] = Math.max(Math.min(niceTickExtent[idx], extent[1]), extent[0]);
    } // In some cases (e.g., splitNumber is 1), niceTickExtent may be out of extent.


    function fixExtent(niceTickExtent, extent) {
      !isFinite(niceTickExtent[0]) && (niceTickExtent[0] = extent[0]);
      !isFinite(niceTickExtent[1]) && (niceTickExtent[1] = extent[1]);
      clamp(niceTickExtent, 0, extent);
      clamp(niceTickExtent, 1, extent);

      if (niceTickExtent[0] > niceTickExtent[1]) {
        niceTickExtent[0] = niceTickExtent[1];
      }
    }
    function contain$1(val, extent) {
      return val >= extent[0] && val <= extent[1];
    }
    function normalize$1(val, extent) {
      if (extent[1] === extent[0]) {
        return 0.5;
      }

      return (val - extent[0]) / (extent[1] - extent[0]);
    }
    function scale$2(val, extent) {
      return val * (extent[1] - extent[0]) + extent[0];
    }

    var OrdinalScale =
    /** @class */
    function (_super) {
      __extends(OrdinalScale, _super);

      function OrdinalScale(setting) {
        var _this = _super.call(this, setting) || this;

        _this.type = 'ordinal';

        var ordinalMeta = _this.getSetting('ordinalMeta'); // Caution: Should not use instanceof, consider ec-extensions using
        // import approach to get OrdinalMeta class.


        if (!ordinalMeta) {
          ordinalMeta = new OrdinalMeta({});
        }

        if (isArray(ordinalMeta)) {
          ordinalMeta = new OrdinalMeta({
            categories: map(ordinalMeta, function (item) {
              return isObject(item) ? item.value : item;
            })
          });
        }

        _this._ordinalMeta = ordinalMeta;
        _this._extent = _this.getSetting('extent') || [0, ordinalMeta.categories.length - 1];
        return _this;
      }

      OrdinalScale.prototype.parse = function (val) {
        // Caution: Math.round(null) will return `0` rather than `NaN`
        if (val == null) {
          return NaN;
        }

        return isString(val) ? this._ordinalMeta.getOrdinal(val) // val might be float.
        : Math.round(val);
      };

      OrdinalScale.prototype.contain = function (rank) {
        rank = this.parse(rank);
        return contain$1(rank, this._extent) && this._ordinalMeta.categories[rank] != null;
      };
      /**
       * Normalize given rank or name to linear [0, 1]
       * @param val raw ordinal number.
       * @return normalized value in [0, 1].
       */


      OrdinalScale.prototype.normalize = function (val) {
        val = this._getTickNumber(this.parse(val));
        return normalize$1(val, this._extent);
      };
      /**
       * @param val normalized value in [0, 1].
       * @return raw ordinal number.
       */


      OrdinalScale.prototype.scale = function (val) {
        val = Math.round(scale$2(val, this._extent));
        return this.getRawOrdinalNumber(val);
      };

      OrdinalScale.prototype.getTicks = function () {
        var ticks = [];
        var extent = this._extent;
        var rank = extent[0];

        while (rank <= extent[1]) {
          ticks.push({
            value: rank
          });
          rank++;
        }

        return ticks;
      };

      OrdinalScale.prototype.getMinorTicks = function (splitNumber) {
        // Not support.
        return;
      };
      /**
       * @see `Ordinal['_ordinalNumbersByTick']`
       */


      OrdinalScale.prototype.setSortInfo = function (info) {
        if (info == null) {
          this._ordinalNumbersByTick = this._ticksByOrdinalNumber = null;
          return;
        }

        var infoOrdinalNumbers = info.ordinalNumbers;
        var ordinalsByTick = this._ordinalNumbersByTick = [];
        var ticksByOrdinal = this._ticksByOrdinalNumber = []; // Unnecessary support negative tick in `realtimeSort`.

        var tickNum = 0;
        var allCategoryLen = this._ordinalMeta.categories.length;

        for (var len = Math.min(allCategoryLen, infoOrdinalNumbers.length); tickNum < len; ++tickNum) {
          var ordinalNumber = infoOrdinalNumbers[tickNum];
          ordinalsByTick[tickNum] = ordinalNumber;
          ticksByOrdinal[ordinalNumber] = tickNum;
        } // Handle that `series.data` only covers part of the `axis.category.data`.


        var unusedOrdinal = 0;

        for (; tickNum < allCategoryLen; ++tickNum) {
          while (ticksByOrdinal[unusedOrdinal] != null) {
            unusedOrdinal++;
          }
          ordinalsByTick.push(unusedOrdinal);
          ticksByOrdinal[unusedOrdinal] = tickNum;
        }
      };

      OrdinalScale.prototype._getTickNumber = function (ordinal) {
        var ticksByOrdinalNumber = this._ticksByOrdinalNumber; // also support ordinal out of range of `ordinalMeta.categories.length`,
        // where ordinal numbers are used as tick value directly.

        return ticksByOrdinalNumber && ordinal >= 0 && ordinal < ticksByOrdinalNumber.length ? ticksByOrdinalNumber[ordinal] : ordinal;
      };
      /**
       * @usage
       * ```js
       * const ordinalNumber = ordinalScale.getRawOrdinalNumber(tickVal);
       *
       * // case0
       * const rawOrdinalValue = axisModel.getCategories()[ordinalNumber];
       * // case1
       * const rawOrdinalValue = this._ordinalMeta.categories[ordinalNumber];
       * // case2
       * const coord = axis.dataToCoord(ordinalNumber);
       * ```
       *
       * @param {OrdinalNumber} tickNumber index of display
       */


      OrdinalScale.prototype.getRawOrdinalNumber = function (tickNumber) {
        var ordinalNumbersByTick = this._ordinalNumbersByTick; // tickNumber may be out of range, e.g., when axis max is larger than `ordinalMeta.categories.length`.,
        // where ordinal numbers are used as tick value directly.

        return ordinalNumbersByTick && tickNumber >= 0 && tickNumber < ordinalNumbersByTick.length ? ordinalNumbersByTick[tickNumber] : tickNumber;
      };
      /**
       * Get item on tick
       */


      OrdinalScale.prototype.getLabel = function (tick) {
        if (!this.isBlank()) {
          var ordinalNumber = this.getRawOrdinalNumber(tick.value);
          var cateogry = this._ordinalMeta.categories[ordinalNumber]; // Note that if no data, ordinalMeta.categories is an empty array.
          // Return empty if it's not exist.

          return cateogry == null ? '' : cateogry + '';
        }
      };

      OrdinalScale.prototype.count = function () {
        return this._extent[1] - this._extent[0] + 1;
      };

      OrdinalScale.prototype.unionExtentFromData = function (data, dim) {
        this.unionExtent(data.getApproximateExtent(dim));
      };
      /**
       * @override
       * If value is in extent range
       */


      OrdinalScale.prototype.isInExtentRange = function (value) {
        value = this._getTickNumber(value);
        return this._extent[0] <= value && this._extent[1] >= value;
      };

      OrdinalScale.prototype.getOrdinalMeta = function () {
        return this._ordinalMeta;
      };

      OrdinalScale.prototype.calcNiceTicks = function () {};

      OrdinalScale.prototype.calcNiceExtent = function () {};

      OrdinalScale.type = 'ordinal';
      return OrdinalScale;
    }(Scale);

    Scale.registerClass(OrdinalScale);

    var roundNumber = round;

    var IntervalScale =
    /** @class */
    function (_super) {
      __extends(IntervalScale, _super);

      function IntervalScale() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'interval'; // Step is calculated in adjustExtent.

        _this._interval = 0;
        _this._intervalPrecision = 2;
        return _this;
      }

      IntervalScale.prototype.parse = function (val) {
        return val;
      };

      IntervalScale.prototype.contain = function (val) {
        return contain$1(val, this._extent);
      };

      IntervalScale.prototype.normalize = function (val) {
        return normalize$1(val, this._extent);
      };

      IntervalScale.prototype.scale = function (val) {
        return scale$2(val, this._extent);
      };

      IntervalScale.prototype.setExtent = function (start, end) {
        var thisExtent = this._extent; // start,end may be a Number like '25',so...

        if (!isNaN(start)) {
          thisExtent[0] = parseFloat(start);
        }

        if (!isNaN(end)) {
          thisExtent[1] = parseFloat(end);
        }
      };

      IntervalScale.prototype.unionExtent = function (other) {
        var extent = this._extent;
        other[0] < extent[0] && (extent[0] = other[0]);
        other[1] > extent[1] && (extent[1] = other[1]); // unionExtent may called by it's sub classes

        this.setExtent(extent[0], extent[1]);
      };

      IntervalScale.prototype.getInterval = function () {
        return this._interval;
      };

      IntervalScale.prototype.setInterval = function (interval) {
        this._interval = interval; // Dropped auto calculated niceExtent and use user-set extent.
        // We assume user wants to set both interval, min, max to get a better result.

        this._niceExtent = this._extent.slice();
        this._intervalPrecision = getIntervalPrecision(interval);
      };
      /**
       * @param expandToNicedExtent Whether expand the ticks to niced extent.
       */


      IntervalScale.prototype.getTicks = function (expandToNicedExtent) {
        var interval = this._interval;
        var extent = this._extent;
        var niceTickExtent = this._niceExtent;
        var intervalPrecision = this._intervalPrecision;
        var ticks = []; // If interval is 0, return [];

        if (!interval) {
          return ticks;
        } // Consider this case: using dataZoom toolbox, zoom and zoom.


        var safeLimit = 10000;

        if (extent[0] < niceTickExtent[0]) {
          if (expandToNicedExtent) {
            ticks.push({
              value: roundNumber(niceTickExtent[0] - interval, intervalPrecision)
            });
          } else {
            ticks.push({
              value: extent[0]
            });
          }
        }

        var tick = niceTickExtent[0];

        while (tick <= niceTickExtent[1]) {
          ticks.push({
            value: tick
          }); // Avoid rounding error

          tick = roundNumber(tick + interval, intervalPrecision);

          if (tick === ticks[ticks.length - 1].value) {
            // Consider out of safe float point, e.g.,
            // -3711126.9907707 + 2e-10 === -3711126.9907707
            break;
          }

          if (ticks.length > safeLimit) {
            return [];
          }
        } // Consider this case: the last item of ticks is smaller
        // than niceTickExtent[1] and niceTickExtent[1] === extent[1].


        var lastNiceTick = ticks.length ? ticks[ticks.length - 1].value : niceTickExtent[1];

        if (extent[1] > lastNiceTick) {
          if (expandToNicedExtent) {
            ticks.push({
              value: roundNumber(lastNiceTick + interval, intervalPrecision)
            });
          } else {
            ticks.push({
              value: extent[1]
            });
          }
        }

        return ticks;
      };

      IntervalScale.prototype.getMinorTicks = function (splitNumber) {
        var ticks = this.getTicks(true);
        var minorTicks = [];
        var extent = this.getExtent();

        for (var i = 1; i < ticks.length; i++) {
          var nextTick = ticks[i];
          var prevTick = ticks[i - 1];
          var count = 0;
          var minorTicksGroup = [];
          var interval = nextTick.value - prevTick.value;
          var minorInterval = interval / splitNumber;

          while (count < splitNumber - 1) {
            var minorTick = roundNumber(prevTick.value + (count + 1) * minorInterval); // For the first and last interval. The count may be less than splitNumber.

            if (minorTick > extent[0] && minorTick < extent[1]) {
              minorTicksGroup.push(minorTick);
            }

            count++;
          }

          minorTicks.push(minorTicksGroup);
        }

        return minorTicks;
      };
      /**
       * @param opt.precision If 'auto', use nice presision.
       * @param opt.pad returns 1.50 but not 1.5 if precision is 2.
       */


      IntervalScale.prototype.getLabel = function (data, opt) {
        if (data == null) {
          return '';
        }

        var precision = opt && opt.precision;

        if (precision == null) {
          precision = getPrecision(data.value) || 0;
        } else if (precision === 'auto') {
          // Should be more precise then tick.
          precision = this._intervalPrecision;
        } // (1) If `precision` is set, 12.005 should be display as '12.00500'.
        // (2) Use roundNumber (toFixed) to avoid scientific notation like '3.5e-7'.


        var dataNum = roundNumber(data.value, precision, true);
        return addCommas(dataNum);
      };
      /**
       * @param splitNumber By default `5`.
       */


      IntervalScale.prototype.calcNiceTicks = function (splitNumber, minInterval, maxInterval) {
        splitNumber = splitNumber || 5;
        var extent = this._extent;
        var span = extent[1] - extent[0];

        if (!isFinite(span)) {
          return;
        } // User may set axis min 0 and data are all negative
        // FIXME If it needs to reverse ?


        if (span < 0) {
          span = -span;
          extent.reverse();
        }

        var result = intervalScaleNiceTicks(extent, splitNumber, minInterval, maxInterval);
        this._intervalPrecision = result.intervalPrecision;
        this._interval = result.interval;
        this._niceExtent = result.niceTickExtent;
      };

      IntervalScale.prototype.calcNiceExtent = function (opt) {
        var extent = this._extent; // If extent start and end are same, expand them

        if (extent[0] === extent[1]) {
          if (extent[0] !== 0) {
            // Expand extent
            // Note that extents can be both negative. See #13154
            var expandSize = Math.abs(extent[0]); // In the fowllowing case
            //      Axis has been fixed max 100
            //      Plus data are all 100 and axis extent are [100, 100].
            // Extend to the both side will cause expanded max is larger than fixed max.
            // So only expand to the smaller side.

            if (!opt.fixMax) {
              extent[1] += expandSize / 2;
              extent[0] -= expandSize / 2;
            } else {
              extent[0] -= expandSize / 2;
            }
          } else {
            extent[1] = 1;
          }
        }

        var span = extent[1] - extent[0]; // If there are no data and extent are [Infinity, -Infinity]

        if (!isFinite(span)) {
          extent[0] = 0;
          extent[1] = 1;
        }

        this.calcNiceTicks(opt.splitNumber, opt.minInterval, opt.maxInterval); // let extent = this._extent;

        var interval = this._interval;

        if (!opt.fixMin) {
          extent[0] = roundNumber(Math.floor(extent[0] / interval) * interval);
        }

        if (!opt.fixMax) {
          extent[1] = roundNumber(Math.ceil(extent[1] / interval) * interval);
        }
      };

      IntervalScale.prototype.setNiceExtent = function (min, max) {
        this._niceExtent = [min, max];
      };

      IntervalScale.type = 'interval';
      return IntervalScale;
    }(Scale);

    Scale.registerClass(IntervalScale);

    /* global Float32Array */

    var supportFloat32Array = typeof Float32Array !== 'undefined';
    var Float32ArrayCtor = !supportFloat32Array ? Array : Float32Array;
    function createFloat32Array(arg) {
      if (isArray(arg)) {
        // Return self directly if don't support TypedArray.
        return supportFloat32Array ? new Float32Array(arg) : arg;
      } // Else is number


      return new Float32ArrayCtor(arg);
    }

    var STACK_PREFIX = '__ec_stack_';

    function getSeriesStackId(seriesModel) {
      return seriesModel.get('stack') || STACK_PREFIX + seriesModel.seriesIndex;
    }

    function getAxisKey(axis) {
      return axis.dim + axis.index;
    }
    function prepareLayoutBarSeries(seriesType, ecModel) {
      var seriesModels = [];
      ecModel.eachSeriesByType(seriesType, function (seriesModel) {
        // Check series coordinate, do layout for cartesian2d only
        if (isOnCartesian(seriesModel)) {
          seriesModels.push(seriesModel);
        }
      });
      return seriesModels;
    }
    /**
     * Map from (baseAxis.dim + '_' + baseAxis.index) to min gap of two adjacent
     * values.
     * This works for time axes, value axes, and log axes.
     * For a single time axis, return value is in the form like
     * {'x_0': [1000000]}.
     * The value of 1000000 is in milliseconds.
     */

    function getValueAxesMinGaps(barSeries) {
      /**
       * Map from axis.index to values.
       * For a single time axis, axisValues is in the form like
       * {'x_0': [1495555200000, 1495641600000, 1495728000000]}.
       * Items in axisValues[x], e.g. 1495555200000, are time values of all
       * series.
       */
      var axisValues = {};
      each(barSeries, function (seriesModel) {
        var cartesian = seriesModel.coordinateSystem;
        var baseAxis = cartesian.getBaseAxis();

        if (baseAxis.type !== 'time' && baseAxis.type !== 'value') {
          return;
        }

        var data = seriesModel.getData();
        var key = baseAxis.dim + '_' + baseAxis.index;
        var dimIdx = data.getDimensionIndex(data.mapDimension(baseAxis.dim));
        var store = data.getStore();

        for (var i = 0, cnt = store.count(); i < cnt; ++i) {
          var value = store.get(dimIdx, i);

          if (!axisValues[key]) {
            // No previous data for the axis
            axisValues[key] = [value];
          } else {
            // No value in previous series
            axisValues[key].push(value);
          } // Ignore duplicated time values in the same axis

        }
      });
      var axisMinGaps = {};

      for (var key in axisValues) {
        if (axisValues.hasOwnProperty(key)) {
          var valuesInAxis = axisValues[key];

          if (valuesInAxis) {
            // Sort axis values into ascending order to calculate gaps
            valuesInAxis.sort(function (a, b) {
              return a - b;
            });
            var min = null;

            for (var j = 1; j < valuesInAxis.length; ++j) {
              var delta = valuesInAxis[j] - valuesInAxis[j - 1];

              if (delta > 0) {
                // Ignore 0 delta because they are of the same axis value
                min = min === null ? delta : Math.min(min, delta);
              }
            } // Set to null if only have one data


            axisMinGaps[key] = min;
          }
        }
      }

      return axisMinGaps;
    }

    function makeColumnLayout(barSeries) {
      var axisMinGaps = getValueAxesMinGaps(barSeries);
      var seriesInfoList = [];
      each(barSeries, function (seriesModel) {
        var cartesian = seriesModel.coordinateSystem;
        var baseAxis = cartesian.getBaseAxis();
        var axisExtent = baseAxis.getExtent();
        var bandWidth;

        if (baseAxis.type === 'category') {
          bandWidth = baseAxis.getBandWidth();
        } else if (baseAxis.type === 'value' || baseAxis.type === 'time') {
          var key = baseAxis.dim + '_' + baseAxis.index;
          var minGap = axisMinGaps[key];
          var extentSpan = Math.abs(axisExtent[1] - axisExtent[0]);
          var scale = baseAxis.scale.getExtent();
          var scaleSpan = Math.abs(scale[1] - scale[0]);
          bandWidth = minGap ? extentSpan / scaleSpan * minGap : extentSpan; // When there is only one data value
        } else {
          var data = seriesModel.getData();
          bandWidth = Math.abs(axisExtent[1] - axisExtent[0]) / data.count();
        }

        var barWidth = parsePercent$1(seriesModel.get('barWidth'), bandWidth);
        var barMaxWidth = parsePercent$1(seriesModel.get('barMaxWidth'), bandWidth);
        var barMinWidth = parsePercent$1( // barMinWidth by default is 0.5 / 1 in cartesian. Because in value axis,
        // the auto-calculated bar width might be less than 0.5 / 1.
        seriesModel.get('barMinWidth') || (isInLargeMode(seriesModel) ? 0.5 : 1), bandWidth);
        var barGap = seriesModel.get('barGap');
        var barCategoryGap = seriesModel.get('barCategoryGap');
        seriesInfoList.push({
          bandWidth: bandWidth,
          barWidth: barWidth,
          barMaxWidth: barMaxWidth,
          barMinWidth: barMinWidth,
          barGap: barGap,
          barCategoryGap: barCategoryGap,
          axisKey: getAxisKey(baseAxis),
          stackId: getSeriesStackId(seriesModel)
        });
      });
      return doCalBarWidthAndOffset(seriesInfoList);
    }

    function doCalBarWidthAndOffset(seriesInfoList) {
      // Columns info on each category axis. Key is cartesian name
      var columnsMap = {};
      each(seriesInfoList, function (seriesInfo, idx) {
        var axisKey = seriesInfo.axisKey;
        var bandWidth = seriesInfo.bandWidth;
        var columnsOnAxis = columnsMap[axisKey] || {
          bandWidth: bandWidth,
          remainedWidth: bandWidth,
          autoWidthCount: 0,
          categoryGap: null,
          gap: '20%',
          stacks: {}
        };
        var stacks = columnsOnAxis.stacks;
        columnsMap[axisKey] = columnsOnAxis;
        var stackId = seriesInfo.stackId;

        if (!stacks[stackId]) {
          columnsOnAxis.autoWidthCount++;
        }

        stacks[stackId] = stacks[stackId] || {
          width: 0,
          maxWidth: 0
        }; // Caution: In a single coordinate system, these barGrid attributes
        // will be shared by series. Consider that they have default values,
        // only the attributes set on the last series will work.
        // Do not change this fact unless there will be a break change.

        var barWidth = seriesInfo.barWidth;

        if (barWidth && !stacks[stackId].width) {
          // See #6312, do not restrict width.
          stacks[stackId].width = barWidth;
          barWidth = Math.min(columnsOnAxis.remainedWidth, barWidth);
          columnsOnAxis.remainedWidth -= barWidth;
        }

        var barMaxWidth = seriesInfo.barMaxWidth;
        barMaxWidth && (stacks[stackId].maxWidth = barMaxWidth);
        var barMinWidth = seriesInfo.barMinWidth;
        barMinWidth && (stacks[stackId].minWidth = barMinWidth);
        var barGap = seriesInfo.barGap;
        barGap != null && (columnsOnAxis.gap = barGap);
        var barCategoryGap = seriesInfo.barCategoryGap;
        barCategoryGap != null && (columnsOnAxis.categoryGap = barCategoryGap);
      });
      var result = {};
      each(columnsMap, function (columnsOnAxis, coordSysName) {
        result[coordSysName] = {};
        var stacks = columnsOnAxis.stacks;
        var bandWidth = columnsOnAxis.bandWidth;
        var categoryGapPercent = columnsOnAxis.categoryGap;

        if (categoryGapPercent == null) {
          var columnCount = keys(stacks).length; // More columns in one group
          // the spaces between group is smaller. Or the column will be too thin.

          categoryGapPercent = Math.max(35 - columnCount * 4, 15) + '%';
        }

        var categoryGap = parsePercent$1(categoryGapPercent, bandWidth);
        var barGapPercent = parsePercent$1(columnsOnAxis.gap, 1);
        var remainedWidth = columnsOnAxis.remainedWidth;
        var autoWidthCount = columnsOnAxis.autoWidthCount;
        var autoWidth = (remainedWidth - categoryGap) / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);
        autoWidth = Math.max(autoWidth, 0); // Find if any auto calculated bar exceeded maxBarWidth

        each(stacks, function (column) {
          var maxWidth = column.maxWidth;
          var minWidth = column.minWidth;

          if (!column.width) {
            var finalWidth = autoWidth;

            if (maxWidth && maxWidth < finalWidth) {
              finalWidth = Math.min(maxWidth, remainedWidth);
            } // `minWidth` has higher priority. `minWidth` decide that whether the
            // bar is able to be visible. So `minWidth` should not be restricted
            // by `maxWidth` or `remainedWidth` (which is from `bandWidth`). In
            // the extreme cases for `value` axis, bars are allowed to overlap
            // with each other if `minWidth` specified.


            if (minWidth && minWidth > finalWidth) {
              finalWidth = minWidth;
            }

            if (finalWidth !== autoWidth) {
              column.width = finalWidth;
              remainedWidth -= finalWidth + barGapPercent * finalWidth;
              autoWidthCount--;
            }
          } else {
            // `barMinWidth/barMaxWidth` has higher priority than `barWidth`, as
            // CSS does. Because barWidth can be a percent value, where
            // `barMaxWidth` can be used to restrict the final width.
            var finalWidth = column.width;

            if (maxWidth) {
              finalWidth = Math.min(finalWidth, maxWidth);
            } // `minWidth` has higher priority, as described above


            if (minWidth) {
              finalWidth = Math.max(finalWidth, minWidth);
            }

            column.width = finalWidth;
            remainedWidth -= finalWidth + barGapPercent * finalWidth;
            autoWidthCount--;
          }
        }); // Recalculate width again

        autoWidth = (remainedWidth - categoryGap) / (autoWidthCount + (autoWidthCount - 1) * barGapPercent);
        autoWidth = Math.max(autoWidth, 0);
        var widthSum = 0;
        var lastColumn;
        each(stacks, function (column, idx) {
          if (!column.width) {
            column.width = autoWidth;
          }

          lastColumn = column;
          widthSum += column.width * (1 + barGapPercent);
        });

        if (lastColumn) {
          widthSum -= lastColumn.width * barGapPercent;
        }

        var offset = -widthSum / 2;
        each(stacks, function (column, stackId) {
          result[coordSysName][stackId] = result[coordSysName][stackId] || {
            bandWidth: bandWidth,
            offset: offset,
            width: column.width
          };
          offset += column.width * (1 + barGapPercent);
        });
      });
      return result;
    }

    function retrieveColumnLayout(barWidthAndOffset, axis, seriesModel) {
      if (barWidthAndOffset && axis) {
        var result = barWidthAndOffset[getAxisKey(axis)];

        if (result != null && seriesModel != null) {
          return result[getSeriesStackId(seriesModel)];
        }

        return result;
      }
    }
    function layout(seriesType, ecModel) {
      var seriesModels = prepareLayoutBarSeries(seriesType, ecModel);
      var barWidthAndOffset = makeColumnLayout(seriesModels);
      each(seriesModels, function (seriesModel) {
        var data = seriesModel.getData();
        var cartesian = seriesModel.coordinateSystem;
        var baseAxis = cartesian.getBaseAxis();
        var stackId = getSeriesStackId(seriesModel);
        var columnLayoutInfo = barWidthAndOffset[getAxisKey(baseAxis)][stackId];
        var columnOffset = columnLayoutInfo.offset;
        var columnWidth = columnLayoutInfo.width;
        data.setLayout({
          bandWidth: columnLayoutInfo.bandWidth,
          offset: columnOffset,
          size: columnWidth
        });
      });
    } // TODO: Do not support stack in large mode yet.

    function createProgressiveLayout(seriesType) {
      return {
        seriesType: seriesType,
        plan: createRenderPlanner(),
        reset: function (seriesModel) {
          if (!isOnCartesian(seriesModel)) {
            return;
          }

          var data = seriesModel.getData();
          var cartesian = seriesModel.coordinateSystem;
          var baseAxis = cartesian.getBaseAxis();
          var valueAxis = cartesian.getOtherAxis(baseAxis);
          var valueDimIdx = data.getDimensionIndex(data.mapDimension(valueAxis.dim));
          var baseDimIdx = data.getDimensionIndex(data.mapDimension(baseAxis.dim));
          var drawBackground = seriesModel.get('showBackground', true);
          var valueDim = data.mapDimension(valueAxis.dim);
          var stackResultDim = data.getCalculationInfo('stackResultDimension');
          var stacked = isDimensionStacked(data, valueDim) && !!data.getCalculationInfo('stackedOnSeries');
          var isValueAxisH = valueAxis.isHorizontal();
          var valueAxisStart = getValueAxisStart(baseAxis, valueAxis);
          var isLarge = isInLargeMode(seriesModel);
          var barMinHeight = seriesModel.get('barMinHeight') || 0;
          var stackedDimIdx = stackResultDim && data.getDimensionIndex(stackResultDim); // Layout info.

          var columnWidth = data.getLayout('size');
          var columnOffset = data.getLayout('offset');
          return {
            progress: function (params, data) {
              var count = params.count;
              var largePoints = isLarge && createFloat32Array(count * 3);
              var largeBackgroundPoints = isLarge && drawBackground && createFloat32Array(count * 3);
              var largeDataIndices = isLarge && createFloat32Array(count);
              var coordLayout = cartesian.master.getRect();
              var bgSize = isValueAxisH ? coordLayout.width : coordLayout.height;
              var dataIndex;
              var store = data.getStore();
              var idxOffset = 0;

              while ((dataIndex = params.next()) != null) {
                var value = store.get(stacked ? stackedDimIdx : valueDimIdx, dataIndex);
                var baseValue = store.get(baseDimIdx, dataIndex);
                var baseCoord = valueAxisStart;
                var startValue = void 0; // Because of the barMinHeight, we can not use the value in
                // stackResultDimension directly.

                if (stacked) {
                  startValue = +value - store.get(valueDimIdx, dataIndex);
                }

                var x = void 0;
                var y = void 0;
                var width = void 0;
                var height = void 0;

                if (isValueAxisH) {
                  var coord = cartesian.dataToPoint([value, baseValue]);

                  if (stacked) {
                    var startCoord = cartesian.dataToPoint([startValue, baseValue]);
                    baseCoord = startCoord[0];
                  }

                  x = baseCoord;
                  y = coord[1] + columnOffset;
                  width = coord[0] - baseCoord;
                  height = columnWidth;

                  if (Math.abs(width) < barMinHeight) {
                    width = (width < 0 ? -1 : 1) * barMinHeight;
                  }
                } else {
                  var coord = cartesian.dataToPoint([baseValue, value]);

                  if (stacked) {
                    var startCoord = cartesian.dataToPoint([baseValue, startValue]);
                    baseCoord = startCoord[1];
                  }

                  x = coord[0] + columnOffset;
                  y = baseCoord;
                  width = columnWidth;
                  height = coord[1] - baseCoord;

                  if (Math.abs(height) < barMinHeight) {
                    // Include zero to has a positive bar
                    height = (height <= 0 ? -1 : 1) * barMinHeight;
                  }
                }

                if (!isLarge) {
                  data.setItemLayout(dataIndex, {
                    x: x,
                    y: y,
                    width: width,
                    height: height
                  });
                } else {
                  largePoints[idxOffset] = x;
                  largePoints[idxOffset + 1] = y;
                  largePoints[idxOffset + 2] = isValueAxisH ? width : height;

                  if (largeBackgroundPoints) {
                    largeBackgroundPoints[idxOffset] = isValueAxisH ? coordLayout.x : x;
                    largeBackgroundPoints[idxOffset + 1] = isValueAxisH ? y : coordLayout.y;
                    largeBackgroundPoints[idxOffset + 2] = bgSize;
                  }

                  largeDataIndices[dataIndex] = dataIndex;
                }

                idxOffset += 3;
              }

              if (isLarge) {
                data.setLayout({
                  largePoints: largePoints,
                  largeDataIndices: largeDataIndices,
                  largeBackgroundPoints: largeBackgroundPoints,
                  valueAxisHorizontal: isValueAxisH
                });
              }
            }
          };
        }
      };
    }

    function isOnCartesian(seriesModel) {
      return seriesModel.coordinateSystem && seriesModel.coordinateSystem.type === 'cartesian2d';
    }

    function isInLargeMode(seriesModel) {
      return seriesModel.pipelineContext && seriesModel.pipelineContext.large;
    } // See cases in `test/bar-start.html` and `#7412`, `#8747`.


    function getValueAxisStart(baseAxis, valueAxis) {
      return valueAxis.toGlobalCoord(valueAxis.dataToCoord(valueAxis.type === 'log' ? 1 : 0));
    }

    var bisect = function (a, x, lo, hi) {
      while (lo < hi) {
        var mid = lo + hi >>> 1;

        if (a[mid][1] < x) {
          lo = mid + 1;
        } else {
          hi = mid;
        }
      }

      return lo;
    };

    var TimeScale =
    /** @class */
    function (_super) {
      __extends(TimeScale, _super);

      function TimeScale(settings) {
        var _this = _super.call(this, settings) || this;

        _this.type = 'time';
        return _this;
      }
      /**
       * Get label is mainly for other components like dataZoom, tooltip.
       */


      TimeScale.prototype.getLabel = function (tick) {
        var useUTC = this.getSetting('useUTC');
        return format(tick.value, fullLeveledFormatter[getDefaultFormatPrecisionOfInterval(getPrimaryTimeUnit(this._minLevelUnit))] || fullLeveledFormatter.second, useUTC, this.getSetting('locale'));
      };

      TimeScale.prototype.getFormattedLabel = function (tick, idx, labelFormatter) {
        var isUTC = this.getSetting('useUTC');
        var lang = this.getSetting('locale');
        return leveledFormat(tick, idx, labelFormatter, lang, isUTC);
      };
      /**
       * @override
       */


      TimeScale.prototype.getTicks = function () {
        var interval = this._interval;
        var extent = this._extent;
        var ticks = []; // If interval is 0, return [];

        if (!interval) {
          return ticks;
        }

        ticks.push({
          value: extent[0],
          level: 0
        });
        var useUTC = this.getSetting('useUTC');
        var innerTicks = getIntervalTicks(this._minLevelUnit, this._approxInterval, useUTC, extent);
        ticks = ticks.concat(innerTicks);
        ticks.push({
          value: extent[1],
          level: 0
        });
        return ticks;
      };

      TimeScale.prototype.calcNiceExtent = function (opt) {
        var extent = this._extent; // If extent start and end are same, expand them

        if (extent[0] === extent[1]) {
          // Expand extent
          extent[0] -= ONE_DAY;
          extent[1] += ONE_DAY;
        } // If there are no data and extent are [Infinity, -Infinity]


        if (extent[1] === -Infinity && extent[0] === Infinity) {
          var d = new Date();
          extent[1] = +new Date(d.getFullYear(), d.getMonth(), d.getDate());
          extent[0] = extent[1] - ONE_DAY;
        }

        this.calcNiceTicks(opt.splitNumber, opt.minInterval, opt.maxInterval);
      };

      TimeScale.prototype.calcNiceTicks = function (approxTickNum, minInterval, maxInterval) {
        approxTickNum = approxTickNum || 10;
        var extent = this._extent;
        var span = extent[1] - extent[0];
        this._approxInterval = span / approxTickNum;

        if (minInterval != null && this._approxInterval < minInterval) {
          this._approxInterval = minInterval;
        }

        if (maxInterval != null && this._approxInterval > maxInterval) {
          this._approxInterval = maxInterval;
        }

        var scaleIntervalsLen = scaleIntervals.length;
        var idx = Math.min(bisect(scaleIntervals, this._approxInterval, 0, scaleIntervalsLen), scaleIntervalsLen - 1); // Interval that can be used to calculate ticks

        this._interval = scaleIntervals[idx][1]; // Min level used when picking ticks from top down.
        // We check one more level to avoid the ticks are to sparse in some case.

        this._minLevelUnit = scaleIntervals[Math.max(idx - 1, 0)][0];
      };

      TimeScale.prototype.parse = function (val) {
        // val might be float.
        return isNumber(val) ? val : +parseDate(val);
      };

      TimeScale.prototype.contain = function (val) {
        return contain$1(this.parse(val), this._extent);
      };

      TimeScale.prototype.normalize = function (val) {
        return normalize$1(this.parse(val), this._extent);
      };

      TimeScale.prototype.scale = function (val) {
        return scale$2(val, this._extent);
      };

      TimeScale.type = 'time';
      return TimeScale;
    }(IntervalScale);
    /**
     * This implementation was originally copied from "d3.js"
     * <https://github.com/d3/d3/blob/b516d77fb8566b576088e73410437494717ada26/src/time/scale.js>
     * with some modifications made for this program.
     * See the license statement at the head of this file.
     */


    var scaleIntervals = [// Format                           interval
    ['second', ONE_SECOND], ['minute', ONE_MINUTE], ['hour', ONE_HOUR], ['quarter-day', ONE_HOUR * 6], ['half-day', ONE_HOUR * 12], ['day', ONE_DAY * 1.2], ['half-week', ONE_DAY * 3.5], ['week', ONE_DAY * 7], ['month', ONE_DAY * 31], ['quarter', ONE_DAY * 95], ['half-year', ONE_YEAR / 2], ['year', ONE_YEAR] // 1Y
    ];

    function isUnitValueSame(unit, valueA, valueB, isUTC) {
      var dateA = parseDate(valueA);
      var dateB = parseDate(valueB);

      var isSame = function (unit) {
        return getUnitValue(dateA, unit, isUTC) === getUnitValue(dateB, unit, isUTC);
      };

      var isSameYear = function () {
        return isSame('year');
      }; // const isSameHalfYear = () => isSameYear() && isSame('half-year');
      // const isSameQuater = () => isSameYear() && isSame('quarter');


      var isSameMonth = function () {
        return isSameYear() && isSame('month');
      };

      var isSameDay = function () {
        return isSameMonth() && isSame('day');
      }; // const isSameHalfDay = () => isSameDay() && isSame('half-day');


      var isSameHour = function () {
        return isSameDay() && isSame('hour');
      };

      var isSameMinute = function () {
        return isSameHour() && isSame('minute');
      };

      var isSameSecond = function () {
        return isSameMinute() && isSame('second');
      };

      var isSameMilliSecond = function () {
        return isSameSecond() && isSame('millisecond');
      };

      switch (unit) {
        case 'year':
          return isSameYear();

        case 'month':
          return isSameMonth();

        case 'day':
          return isSameDay();

        case 'hour':
          return isSameHour();

        case 'minute':
          return isSameMinute();

        case 'second':
          return isSameSecond();

        case 'millisecond':
          return isSameMilliSecond();
      }
    } // const primaryUnitGetters = {
    //     year: fullYearGetterName(),
    //     month: monthGetterName(),
    //     day: dateGetterName(),
    //     hour: hoursGetterName(),
    //     minute: minutesGetterName(),
    //     second: secondsGetterName(),
    //     millisecond: millisecondsGetterName()
    // };
    // const primaryUnitUTCGetters = {
    //     year: fullYearGetterName(true),
    //     month: monthGetterName(true),
    //     day: dateGetterName(true),
    //     hour: hoursGetterName(true),
    //     minute: minutesGetterName(true),
    //     second: secondsGetterName(true),
    //     millisecond: millisecondsGetterName(true)
    // };
    // function moveTick(date: Date, unitName: TimeUnit, step: number, isUTC: boolean) {
    //     step = step || 1;
    //     switch (getPrimaryTimeUnit(unitName)) {
    //         case 'year':
    //             date[fullYearSetterName(isUTC)](date[fullYearGetterName(isUTC)]() + step);
    //             break;
    //         case 'month':
    //             date[monthSetterName(isUTC)](date[monthGetterName(isUTC)]() + step);
    //             break;
    //         case 'day':
    //             date[dateSetterName(isUTC)](date[dateGetterName(isUTC)]() + step);
    //             break;
    //         case 'hour':
    //             date[hoursSetterName(isUTC)](date[hoursGetterName(isUTC)]() + step);
    //             break;
    //         case 'minute':
    //             date[minutesSetterName(isUTC)](date[minutesGetterName(isUTC)]() + step);
    //             break;
    //         case 'second':
    //             date[secondsSetterName(isUTC)](date[secondsGetterName(isUTC)]() + step);
    //             break;
    //         case 'millisecond':
    //             date[millisecondsSetterName(isUTC)](date[millisecondsGetterName(isUTC)]() + step);
    //             break;
    //     }
    //     return date.getTime();
    // }
    // const DATE_INTERVALS = [[8, 7.5], [4, 3.5], [2, 1.5]];
    // const MONTH_INTERVALS = [[6, 5.5], [3, 2.5], [2, 1.5]];
    // const MINUTES_SECONDS_INTERVALS = [[30, 30], [20, 20], [15, 15], [10, 10], [5, 5], [2, 2]];


    function getDateInterval(approxInterval, daysInMonth) {
      approxInterval /= ONE_DAY;
      return approxInterval > 16 ? 16 // Math.floor(daysInMonth / 2) + 1  // In this case we only want one tick between two months.
      : approxInterval > 7.5 ? 7 // TODO week 7 or day 8?
      : approxInterval > 3.5 ? 4 : approxInterval > 1.5 ? 2 : 1;
    }

    function getMonthInterval(approxInterval) {
      var APPROX_ONE_MONTH = 30 * ONE_DAY;
      approxInterval /= APPROX_ONE_MONTH;
      return approxInterval > 6 ? 6 : approxInterval > 3 ? 3 : approxInterval > 2 ? 2 : 1;
    }

    function getHourInterval(approxInterval) {
      approxInterval /= ONE_HOUR;
      return approxInterval > 12 ? 12 : approxInterval > 6 ? 6 : approxInterval > 3.5 ? 4 : approxInterval > 2 ? 2 : 1;
    }

    function getMinutesAndSecondsInterval(approxInterval, isMinutes) {
      approxInterval /= isMinutes ? ONE_MINUTE : ONE_SECOND;
      return approxInterval > 30 ? 30 : approxInterval > 20 ? 20 : approxInterval > 15 ? 15 : approxInterval > 10 ? 10 : approxInterval > 5 ? 5 : approxInterval > 2 ? 2 : 1;
    }

    function getMillisecondsInterval(approxInterval) {
      return nice(approxInterval, true);
    }

    function getFirstTimestampOfUnit(date, unitName, isUTC) {
      var outDate = new Date(date);

      switch (getPrimaryTimeUnit(unitName)) {
        case 'year':
        case 'month':
          outDate[monthSetterName(isUTC)](0);

        case 'day':
          outDate[dateSetterName(isUTC)](1);

        case 'hour':
          outDate[hoursSetterName(isUTC)](0);

        case 'minute':
          outDate[minutesSetterName(isUTC)](0);

        case 'second':
          outDate[secondsSetterName(isUTC)](0);
          outDate[millisecondsSetterName(isUTC)](0);
      }

      return outDate.getTime();
    }

    function getIntervalTicks(bottomUnitName, approxInterval, isUTC, extent) {
      var safeLimit = 10000;
      var unitNames = timeUnits;
      var iter = 0;

      function addTicksInSpan(interval, minTimestamp, maxTimestamp, getMethodName, setMethodName, isDate, out) {
        var date = new Date(minTimestamp);
        var dateTime = minTimestamp;
        var d = date[getMethodName](); // if (isDate) {
        //     d -= 1; // Starts with 0;   PENDING
        // }

        while (dateTime < maxTimestamp && dateTime <= extent[1]) {
          out.push({
            value: dateTime
          });
          d += interval;
          date[setMethodName](d);
          dateTime = date.getTime();
        } // This extra tick is for calcuating ticks of next level. Will not been added to the final result


        out.push({
          value: dateTime,
          notAdd: true
        });
      }

      function addLevelTicks(unitName, lastLevelTicks, levelTicks) {
        var newAddedTicks = [];
        var isFirstLevel = !lastLevelTicks.length;

        if (isUnitValueSame(getPrimaryTimeUnit(unitName), extent[0], extent[1], isUTC)) {
          return;
        }

        if (isFirstLevel) {
          lastLevelTicks = [{
            // TODO Optimize. Not include so may ticks.
            value: getFirstTimestampOfUnit(new Date(extent[0]), unitName, isUTC)
          }, {
            value: extent[1]
          }];
        }

        for (var i = 0; i < lastLevelTicks.length - 1; i++) {
          var startTick = lastLevelTicks[i].value;
          var endTick = lastLevelTicks[i + 1].value;

          if (startTick === endTick) {
            continue;
          }

          var interval = void 0;
          var getterName = void 0;
          var setterName = void 0;
          var isDate = false;

          switch (unitName) {
            case 'year':
              interval = Math.max(1, Math.round(approxInterval / ONE_DAY / 365));
              getterName = fullYearGetterName(isUTC);
              setterName = fullYearSetterName(isUTC);
              break;

            case 'half-year':
            case 'quarter':
            case 'month':
              interval = getMonthInterval(approxInterval);
              getterName = monthGetterName(isUTC);
              setterName = monthSetterName(isUTC);
              break;

            case 'week': // PENDING If week is added. Ignore day.

            case 'half-week':
            case 'day':
              interval = getDateInterval(approxInterval); // Use 32 days and let interval been 16

              getterName = dateGetterName(isUTC);
              setterName = dateSetterName(isUTC);
              isDate = true;
              break;

            case 'half-day':
            case 'quarter-day':
            case 'hour':
              interval = getHourInterval(approxInterval);
              getterName = hoursGetterName(isUTC);
              setterName = hoursSetterName(isUTC);
              break;

            case 'minute':
              interval = getMinutesAndSecondsInterval(approxInterval, true);
              getterName = minutesGetterName(isUTC);
              setterName = minutesSetterName(isUTC);
              break;

            case 'second':
              interval = getMinutesAndSecondsInterval(approxInterval, false);
              getterName = secondsGetterName(isUTC);
              setterName = secondsSetterName(isUTC);
              break;

            case 'millisecond':
              interval = getMillisecondsInterval(approxInterval);
              getterName = millisecondsGetterName(isUTC);
              setterName = millisecondsSetterName(isUTC);
              break;
          }

          addTicksInSpan(interval, startTick, endTick, getterName, setterName, isDate, newAddedTicks);

          if (unitName === 'year' && levelTicks.length > 1 && i === 0) {
            // Add nearest years to the left extent.
            levelTicks.unshift({
              value: levelTicks[0].value - interval
            });
          }
        }

        for (var i = 0; i < newAddedTicks.length; i++) {
          levelTicks.push(newAddedTicks[i]);
        } // newAddedTicks.length && console.log(unitName, newAddedTicks);


        return newAddedTicks;
      }

      var levelsTicks = [];
      var currentLevelTicks = [];
      var tickCount = 0;
      var lastLevelTickCount = 0;

      for (var i = 0; i < unitNames.length && iter++ < safeLimit; ++i) {
        var primaryTimeUnit = getPrimaryTimeUnit(unitNames[i]);

        if (!isPrimaryTimeUnit(unitNames[i])) {
          // TODO
          continue;
        }

        addLevelTicks(unitNames[i], levelsTicks[levelsTicks.length - 1] || [], currentLevelTicks);
        var nextPrimaryTimeUnit = unitNames[i + 1] ? getPrimaryTimeUnit(unitNames[i + 1]) : null;

        if (primaryTimeUnit !== nextPrimaryTimeUnit) {
          if (currentLevelTicks.length) {
            lastLevelTickCount = tickCount; // Remove the duplicate so the tick count can be precisely.

            currentLevelTicks.sort(function (a, b) {
              return a.value - b.value;
            });
            var levelTicksRemoveDuplicated = [];

            for (var i_1 = 0; i_1 < currentLevelTicks.length; ++i_1) {
              var tickValue = currentLevelTicks[i_1].value;

              if (i_1 === 0 || currentLevelTicks[i_1 - 1].value !== tickValue) {
                levelTicksRemoveDuplicated.push(currentLevelTicks[i_1]);

                if (tickValue >= extent[0] && tickValue <= extent[1]) {
                  tickCount++;
                }
              }
            }

            var targetTickNum = (extent[1] - extent[0]) / approxInterval; // Added too much in this level and not too less in last level

            if (tickCount > targetTickNum * 1.5 && lastLevelTickCount > targetTickNum / 1.5) {
              break;
            } // Only treat primary time unit as one level.


            levelsTicks.push(levelTicksRemoveDuplicated);

            if (tickCount > targetTickNum || bottomUnitName === unitNames[i]) {
              break;
            }
          } // Reset if next unitName is primary


          currentLevelTicks = [];
        }
      }

      if ("development" !== 'production') {
        if (iter >= safeLimit) {
          warn('Exceed safe limit.');
        }
      }

      var levelsTicksInExtent = filter(map(levelsTicks, function (levelTicks) {
        return filter(levelTicks, function (tick) {
          return tick.value >= extent[0] && tick.value <= extent[1] && !tick.notAdd;
        });
      }), function (levelTicks) {
        return levelTicks.length > 0;
      });
      var ticks = [];
      var maxLevel = levelsTicksInExtent.length - 1;

      for (var i = 0; i < levelsTicksInExtent.length; ++i) {
        var levelTicks = levelsTicksInExtent[i];

        for (var k = 0; k < levelTicks.length; ++k) {
          ticks.push({
            value: levelTicks[k].value,
            level: maxLevel - i
          });
        }
      }

      ticks.sort(function (a, b) {
        return a.value - b.value;
      }); // Remove duplicates

      var result = [];

      for (var i = 0; i < ticks.length; ++i) {
        if (i === 0 || ticks[i].value !== ticks[i - 1].value) {
          result.push(ticks[i]);
        }
      }

      return result;
    }

    Scale.registerClass(TimeScale);

    var scaleProto = Scale.prototype; // FIXME:TS refactor: not good to call it directly with `this`?

    var intervalScaleProto = IntervalScale.prototype;
    var roundingErrorFix = round;
    var mathFloor = Math.floor;
    var mathCeil = Math.ceil;
    var mathPow$1 = Math.pow;
    var mathLog = Math.log;

    var LogScale =
    /** @class */
    function (_super) {
      __extends(LogScale, _super);

      function LogScale() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'log';
        _this.base = 10;
        _this._originalScale = new IntervalScale(); // FIXME:TS actually used by `IntervalScale`

        _this._interval = 0;
        return _this;
      }
      /**
       * @param Whether expand the ticks to niced extent.
       */


      LogScale.prototype.getTicks = function (expandToNicedExtent) {
        var originalScale = this._originalScale;
        var extent = this._extent;
        var originalExtent = originalScale.getExtent();
        var ticks = intervalScaleProto.getTicks.call(this, expandToNicedExtent);
        return map(ticks, function (tick) {
          var val = tick.value;
          var powVal = round(mathPow$1(this.base, val)); // Fix #4158

          powVal = val === extent[0] && this._fixMin ? fixRoundingError(powVal, originalExtent[0]) : powVal;
          powVal = val === extent[1] && this._fixMax ? fixRoundingError(powVal, originalExtent[1]) : powVal;
          return {
            value: powVal
          };
        }, this);
      };

      LogScale.prototype.setExtent = function (start, end) {
        var base = mathLog(this.base); // log(-Infinity) is NaN, so safe guard here

        start = mathLog(Math.max(0, start)) / base;
        end = mathLog(Math.max(0, end)) / base;
        intervalScaleProto.setExtent.call(this, start, end);
      };
      /**
       * @return {number} end
       */


      LogScale.prototype.getExtent = function () {
        var base = this.base;
        var extent = scaleProto.getExtent.call(this);
        extent[0] = mathPow$1(base, extent[0]);
        extent[1] = mathPow$1(base, extent[1]); // Fix #4158

        var originalScale = this._originalScale;
        var originalExtent = originalScale.getExtent();
        this._fixMin && (extent[0] = fixRoundingError(extent[0], originalExtent[0]));
        this._fixMax && (extent[1] = fixRoundingError(extent[1], originalExtent[1]));
        return extent;
      };

      LogScale.prototype.unionExtent = function (extent) {
        this._originalScale.unionExtent(extent);

        var base = this.base;
        extent[0] = mathLog(extent[0]) / mathLog(base);
        extent[1] = mathLog(extent[1]) / mathLog(base);
        scaleProto.unionExtent.call(this, extent);
      };

      LogScale.prototype.unionExtentFromData = function (data, dim) {
        // TODO
        // filter value that <= 0
        this.unionExtent(data.getApproximateExtent(dim));
      };
      /**
       * Update interval and extent of intervals for nice ticks
       * @param approxTickNum default 10 Given approx tick number
       */


      LogScale.prototype.calcNiceTicks = function (approxTickNum) {
        approxTickNum = approxTickNum || 10;
        var extent = this._extent;
        var span = extent[1] - extent[0];

        if (span === Infinity || span <= 0) {
          return;
        }

        var interval = quantity(span);
        var err = approxTickNum / span * interval; // Filter ticks to get closer to the desired count.

        if (err <= 0.5) {
          interval *= 10;
        } // Interval should be integer


        while (!isNaN(interval) && Math.abs(interval) < 1 && Math.abs(interval) > 0) {
          interval *= 10;
        }

        var niceExtent = [round(mathCeil(extent[0] / interval) * interval), round(mathFloor(extent[1] / interval) * interval)];
        this._interval = interval;
        this._niceExtent = niceExtent;
      };

      LogScale.prototype.calcNiceExtent = function (opt) {
        intervalScaleProto.calcNiceExtent.call(this, opt);
        this._fixMin = opt.fixMin;
        this._fixMax = opt.fixMax;
      };

      LogScale.prototype.parse = function (val) {
        return val;
      };

      LogScale.prototype.contain = function (val) {
        val = mathLog(val) / mathLog(this.base);
        return contain$1(val, this._extent);
      };

      LogScale.prototype.normalize = function (val) {
        val = mathLog(val) / mathLog(this.base);
        return normalize$1(val, this._extent);
      };

      LogScale.prototype.scale = function (val) {
        val = scale$2(val, this._extent);
        return mathPow$1(this.base, val);
      };

      LogScale.type = 'log';
      return LogScale;
    }(Scale);

    var proto = LogScale.prototype;
    proto.getMinorTicks = intervalScaleProto.getMinorTicks;
    proto.getLabel = intervalScaleProto.getLabel;

    function fixRoundingError(val, originalVal) {
      return roundingErrorFix(val, getPrecision(originalVal));
    }

    Scale.registerClass(LogScale);

    var ScaleRawExtentInfo =
    /** @class */
    function () {
      function ScaleRawExtentInfo(scale, model, // Usually: data extent from all series on this axis.
      originalExtent) {
        this._prepareParams(scale, model, originalExtent);
      }
      /**
       * Parameters depending on outside (like model, user callback)
       * are prepared and fixed here.
       */


      ScaleRawExtentInfo.prototype._prepareParams = function (scale, model, // Usually: data extent from all series on this axis.
      dataExtent) {
        if (dataExtent[1] < dataExtent[0]) {
          dataExtent = [NaN, NaN];
        }

        this._dataMin = dataExtent[0];
        this._dataMax = dataExtent[1];
        var isOrdinal = this._isOrdinal = scale.type === 'ordinal';
        this._needCrossZero = scale.type === 'interval' && model.getNeedCrossZero && model.getNeedCrossZero();
        var modelMinRaw = this._modelMinRaw = model.get('min', true);

        if (isFunction(modelMinRaw)) {
          // This callback always provides users the full data extent (before data is filtered).
          this._modelMinNum = parseAxisModelMinMax(scale, modelMinRaw({
            min: dataExtent[0],
            max: dataExtent[1]
          }));
        } else if (modelMinRaw !== 'dataMin') {
          this._modelMinNum = parseAxisModelMinMax(scale, modelMinRaw);
        }

        var modelMaxRaw = this._modelMaxRaw = model.get('max', true);

        if (isFunction(modelMaxRaw)) {
          // This callback always provides users the full data extent (before data is filtered).
          this._modelMaxNum = parseAxisModelMinMax(scale, modelMaxRaw({
            min: dataExtent[0],
            max: dataExtent[1]
          }));
        } else if (modelMaxRaw !== 'dataMax') {
          this._modelMaxNum = parseAxisModelMinMax(scale, modelMaxRaw);
        }

        if (isOrdinal) {
          // FIXME: there is a flaw here: if there is no "block" data processor like `dataZoom`,
          // and progressive rendering is using, here the category result might just only contain
          // the processed chunk rather than the entire result.
          this._axisDataLen = model.getCategories().length;
        } else {
          var boundaryGap = model.get('boundaryGap');
          var boundaryGapArr = isArray(boundaryGap) ? boundaryGap : [boundaryGap || 0, boundaryGap || 0];

          if (typeof boundaryGapArr[0] === 'boolean' || typeof boundaryGapArr[1] === 'boolean') {
            if ("development" !== 'production') {
              console.warn('Boolean type for boundaryGap is only ' + 'allowed for ordinal axis. Please use string in ' + 'percentage instead, e.g., "20%". Currently, ' + 'boundaryGap is set to be 0.');
            }

            this._boundaryGapInner = [0, 0];
          } else {
            this._boundaryGapInner = [parsePercent(boundaryGapArr[0], 1), parsePercent(boundaryGapArr[1], 1)];
          }
        }
      };
      /**
       * Calculate extent by prepared parameters.
       * This method has no external dependency and can be called duplicatedly,
       * getting the same result.
       * If parameters changed, should call this method to recalcuate.
       */


      ScaleRawExtentInfo.prototype.calculate = function () {
        // Notice: When min/max is not set (that is, when there are null/undefined,
        // which is the most common case), these cases should be ensured:
        // (1) For 'ordinal', show all axis.data.
        // (2) For others:
        //      + `boundaryGap` is applied (if min/max set, boundaryGap is
        //      disabled).
        //      + If `needCrossZero`, min/max should be zero, otherwise, min/max should
        //      be the result that originalExtent enlarged by boundaryGap.
        // (3) If no data, it should be ensured that `scale.setBlank` is set.
        var isOrdinal = this._isOrdinal;
        var dataMin = this._dataMin;
        var dataMax = this._dataMax;
        var axisDataLen = this._axisDataLen;
        var boundaryGapInner = this._boundaryGapInner;
        var span = !isOrdinal ? dataMax - dataMin || Math.abs(dataMin) : null; // Currently if a `'value'` axis model min is specified as 'dataMin'/'dataMax',
        // `boundaryGap` will not be used. It's the different from specifying as `null`/`undefined`.

        var min = this._modelMinRaw === 'dataMin' ? dataMin : this._modelMinNum;
        var max = this._modelMaxRaw === 'dataMax' ? dataMax : this._modelMaxNum; // If `_modelMinNum`/`_modelMaxNum` is `null`/`undefined`, should not be fixed.

        var minFixed = min != null;
        var maxFixed = max != null;

        if (min == null) {
          min = isOrdinal ? axisDataLen ? 0 : NaN : dataMin - boundaryGapInner[0] * span;
        }

        if (max == null) {
          max = isOrdinal ? axisDataLen ? axisDataLen - 1 : NaN : dataMax + boundaryGapInner[1] * span;
        }

        (min == null || !isFinite(min)) && (min = NaN);
        (max == null || !isFinite(max)) && (max = NaN);
        var isBlank = eqNaN(min) || eqNaN(max) || isOrdinal && !axisDataLen; // If data extent modified, need to recalculated to ensure cross zero.

        if (this._needCrossZero) {
          // Axis is over zero and min is not set
          if (min > 0 && max > 0 && !minFixed) {
            min = 0; // minFixed = true;
          } // Axis is under zero and max is not set


          if (min < 0 && max < 0 && !maxFixed) {
            max = 0; // maxFixed = true;
          } // PENDING:
          // When `needCrossZero` and all data is positive/negative, should it be ensured
          // that the results processed by boundaryGap are positive/negative?
          // If so, here `minFixed`/`maxFixed` need to be set.

        }

        var determinedMin = this._determinedMin;
        var determinedMax = this._determinedMax;

        if (determinedMin != null) {
          min = determinedMin;
          minFixed = true;
        }

        if (determinedMax != null) {
          max = determinedMax;
          maxFixed = true;
        } // Ensure min/max be finite number or NaN here. (not to be null/undefined)
        // `NaN` means min/max axis is blank.


        return {
          min: min,
          max: max,
          minFixed: minFixed,
          maxFixed: maxFixed,
          isBlank: isBlank
        };
      };

      ScaleRawExtentInfo.prototype.modifyDataMinMax = function (minMaxName, val) {
        if ("development" !== 'production') {
          assert(!this.frozen);
        }

        this[DATA_MIN_MAX_ATTR[minMaxName]] = val;
      };

      ScaleRawExtentInfo.prototype.setDeterminedMinMax = function (minMaxName, val) {
        var attr = DETERMINED_MIN_MAX_ATTR[minMaxName];

        if ("development" !== 'production') {
          assert(!this.frozen // Earse them usually means logic flaw.
          && this[attr] == null);
        }

        this[attr] = val;
      };

      ScaleRawExtentInfo.prototype.freeze = function () {
        // @ts-ignore
        this.frozen = true;
      };

      return ScaleRawExtentInfo;
    }();
    var DETERMINED_MIN_MAX_ATTR = {
      min: '_determinedMin',
      max: '_determinedMax'
    };
    var DATA_MIN_MAX_ATTR = {
      min: '_dataMin',
      max: '_dataMax'
    };
    /**
     * Get scale min max and related info only depends on model settings.
     * This method can be called after coordinate system created.
     * For example, in data processing stage.
     *
     * Scale extent info probably be required multiple times during a workflow.
     * For example:
     * (1) `dataZoom` depends it to get the axis extent in "100%" state.
     * (2) `processor/extentCalculator` depends it to make sure whether axis extent is specified.
     * (3) `coordSys.update` use it to finally decide the scale extent.
     * But the callback of `min`/`max` should not be called multiple times.
     * The code below should not be implemented repeatedly either.
     * So we cache the result in the scale instance, which will be recreated at the beginning
     * of the workflow (because `scale` instance will be recreated each round of the workflow).
     */

    function ensureScaleRawExtentInfo(scale, model, // Usually: data extent from all series on this axis.
    originalExtent) {
      // Do not permit to recreate.
      var rawExtentInfo = scale.rawExtentInfo;

      if (rawExtentInfo) {
        return rawExtentInfo;
      }

      rawExtentInfo = new ScaleRawExtentInfo(scale, model, originalExtent); // @ts-ignore

      scale.rawExtentInfo = rawExtentInfo;
      return rawExtentInfo;
    }
    function parseAxisModelMinMax(scale, minMax) {
      return minMax == null ? null : eqNaN(minMax) ? NaN : scale.parse(minMax);
    }

    /**
     * Get axis scale extent before niced.
     * Item of returned array can only be number (including Infinity and NaN).
     *
     * Caution:
     * Precondition of calling this method:
     * The scale extent has been initialized using series data extent via
     * `scale.setExtent` or `scale.unionExtentFromData`;
     */

    function getScaleExtent(scale, model) {
      var scaleType = scale.type;
      var rawExtentResult = ensureScaleRawExtentInfo(scale, model, scale.getExtent()).calculate();
      scale.setBlank(rawExtentResult.isBlank);
      var min = rawExtentResult.min;
      var max = rawExtentResult.max; // If bars are placed on a base axis of type time or interval account for axis boundary overflow and current axis
      // is base axis
      // FIXME
      // (1) Consider support value axis, where below zero and axis `onZero` should be handled properly.
      // (2) Refactor the logic with `barGrid`. Is it not need to `makeBarWidthAndOffsetInfo` twice with different extent?
      //     Should not depend on series type `bar`?
      // (3) Fix that might overlap when using dataZoom.
      // (4) Consider other chart types using `barGrid`?
      // See #6728, #4862, `test/bar-overflow-time-plot.html`

      var ecModel = model.ecModel;

      if (ecModel && scaleType === 'time'
      /* || scaleType === 'interval' */
      ) {
        var barSeriesModels = prepareLayoutBarSeries('bar', ecModel);
        var isBaseAxisAndHasBarSeries_1 = false;
        each(barSeriesModels, function (seriesModel) {
          isBaseAxisAndHasBarSeries_1 = isBaseAxisAndHasBarSeries_1 || seriesModel.getBaseAxis() === model.axis;
        });

        if (isBaseAxisAndHasBarSeries_1) {
          // Calculate placement of bars on axis. TODO should be decoupled
          // with barLayout
          var barWidthAndOffset = makeColumnLayout(barSeriesModels); // Adjust axis min and max to account for overflow

          var adjustedScale = adjustScaleForOverflow(min, max, model, barWidthAndOffset);
          min = adjustedScale.min;
          max = adjustedScale.max;
        }
      }

      return {
        extent: [min, max],
        // "fix" means "fixed", the value should not be
        // changed in the subsequent steps.
        fixMin: rawExtentResult.minFixed,
        fixMax: rawExtentResult.maxFixed
      };
    }

    function adjustScaleForOverflow(min, max, model, // Only support cartesian coord yet.
    barWidthAndOffset) {
      // Get Axis Length
      var axisExtent = model.axis.getExtent();
      var axisLength = axisExtent[1] - axisExtent[0]; // Get bars on current base axis and calculate min and max overflow

      var barsOnCurrentAxis = retrieveColumnLayout(barWidthAndOffset, model.axis);

      if (barsOnCurrentAxis === undefined) {
        return {
          min: min,
          max: max
        };
      }

      var minOverflow = Infinity;
      each(barsOnCurrentAxis, function (item) {
        minOverflow = Math.min(item.offset, minOverflow);
      });
      var maxOverflow = -Infinity;
      each(barsOnCurrentAxis, function (item) {
        maxOverflow = Math.max(item.offset + item.width, maxOverflow);
      });
      minOverflow = Math.abs(minOverflow);
      maxOverflow = Math.abs(maxOverflow);
      var totalOverFlow = minOverflow + maxOverflow; // Calculate required buffer based on old range and overflow

      var oldRange = max - min;
      var oldRangePercentOfNew = 1 - (minOverflow + maxOverflow) / axisLength;
      var overflowBuffer = oldRange / oldRangePercentOfNew - oldRange;
      max += overflowBuffer * (maxOverflow / totalOverFlow);
      min -= overflowBuffer * (minOverflow / totalOverFlow);
      return {
        min: min,
        max: max
      };
    } // Precondition of calling this method:
    // The scale extent has been initialized using series data extent via
    // `scale.setExtent` or `scale.unionExtentFromData`;


    function niceScaleExtent(scale, inModel) {
      var model = inModel;
      var extentInfo = getScaleExtent(scale, model);
      var extent = extentInfo.extent;
      var splitNumber = model.get('splitNumber');

      if (scale instanceof LogScale) {
        scale.base = model.get('logBase');
      }

      var scaleType = scale.type;
      var interval = model.get('interval');
      var isIntervalOrTime = scaleType === 'interval' || scaleType === 'time';
      scale.setExtent(extent[0], extent[1]);
      scale.calcNiceExtent({
        splitNumber: splitNumber,
        fixMin: extentInfo.fixMin,
        fixMax: extentInfo.fixMax,
        minInterval: isIntervalOrTime ? model.get('minInterval') : null,
        maxInterval: isIntervalOrTime ? model.get('maxInterval') : null
      }); // If some one specified the min, max. And the default calculated interval
      // is not good enough. He can specify the interval. It is often appeared
      // in angle axis with angle 0 - 360. Interval calculated in interval scale is hard
      // to be 60.
      // FIXME

      if (interval != null) {
        scale.setInterval && scale.setInterval(interval);
      }
    }
    /**
     * @param axisType Default retrieve from model.type
     */

    function createScaleByModel(model, axisType) {
      axisType = axisType || model.get('type');

      if (axisType) {
        switch (axisType) {
          // Buildin scale
          case 'category':
            return new OrdinalScale({
              ordinalMeta: model.getOrdinalMeta ? model.getOrdinalMeta() : model.getCategories(),
              extent: [Infinity, -Infinity]
            });

          case 'time':
            return new TimeScale({
              locale: model.ecModel.getLocaleModel(),
              useUTC: model.ecModel.get('useUTC')
            });

          default:
            // case 'value'/'interval', 'log', or others.
            return new (Scale.getClass(axisType) || IntervalScale)();
        }
      }
    }
    /**
     * Check if the axis cross 0
     */

    function ifAxisCrossZero(axis) {
      var dataExtent = axis.scale.getExtent();
      var min = dataExtent[0];
      var max = dataExtent[1];
      return !(min > 0 && max > 0 || min < 0 && max < 0);
    }
    /**
     * @param axis
     * @return Label formatter function.
     *         param: {number} tickValue,
     *         param: {number} idx, the index in all ticks.
     *                         If category axis, this param is not required.
     *         return: {string} label string.
     */

    function makeLabelFormatter(axis) {
      var labelFormatter = axis.getLabelModel().get('formatter');
      var categoryTickStart = axis.type === 'category' ? axis.scale.getExtent()[0] : null;

      if (axis.scale.type === 'time') {
        return function (tpl) {
          return function (tick, idx) {
            return axis.scale.getFormattedLabel(tick, idx, tpl);
          };
        }(labelFormatter);
      } else if (isString(labelFormatter)) {
        return function (tpl) {
          return function (tick) {
            // For category axis, get raw value; for numeric axis,
            // get formatted label like '1,333,444'.
            var label = axis.scale.getLabel(tick);
            var text = tpl.replace('{value}', label != null ? label : '');
            return text;
          };
        }(labelFormatter);
      } else if (isFunction(labelFormatter)) {
        return function (cb) {
          return function (tick, idx) {
            // The original intention of `idx` is "the index of the tick in all ticks".
            // But the previous implementation of category axis do not consider the
            // `axisLabel.interval`, which cause that, for example, the `interval` is
            // `1`, then the ticks "name5", "name7", "name9" are displayed, where the
            // corresponding `idx` are `0`, `2`, `4`, but not `0`, `1`, `2`. So we keep
            // the definition here for back compatibility.
            if (categoryTickStart != null) {
              idx = tick.value - categoryTickStart;
            }

            return cb(getAxisRawValue(axis, tick), idx, tick.level != null ? {
              level: tick.level
            } : null);
          };
        }(labelFormatter);
      } else {
        return function (tick) {
          return axis.scale.getLabel(tick);
        };
      }
    }
    function getAxisRawValue(axis, tick) {
      // In category axis with data zoom, tick is not the original
      // index of axis.data. So tick should not be exposed to user
      // in category axis.
      return axis.type === 'category' ? axis.scale.getLabel(tick) : tick.value;
    }
    /**
     * @param axis
     * @return Be null/undefined if no labels.
     */

    function estimateLabelUnionRect(axis) {
      var axisModel = axis.model;
      var scale = axis.scale;

      if (!axisModel.get(['axisLabel', 'show']) || scale.isBlank()) {
        return;
      }

      var realNumberScaleTicks;
      var tickCount;
      var categoryScaleExtent = scale.getExtent(); // Optimize for large category data, avoid call `getTicks()`.

      if (scale instanceof OrdinalScale) {
        tickCount = scale.count();
      } else {
        realNumberScaleTicks = scale.getTicks();
        tickCount = realNumberScaleTicks.length;
      }

      var axisLabelModel = axis.getLabelModel();
      var labelFormatter = makeLabelFormatter(axis);
      var rect;
      var step = 1; // Simple optimization for large amount of labels

      if (tickCount > 40) {
        step = Math.ceil(tickCount / 40);
      }

      for (var i = 0; i < tickCount; i += step) {
        var tick = realNumberScaleTicks ? realNumberScaleTicks[i] : {
          value: categoryScaleExtent[0] + i
        };
        var label = labelFormatter(tick, i);
        var unrotatedSingleRect = axisLabelModel.getTextRect(label);
        var singleRect = rotateTextRect(unrotatedSingleRect, axisLabelModel.get('rotate') || 0);
        rect ? rect.union(singleRect) : rect = singleRect;
      }

      return rect;
    }

    function rotateTextRect(textRect, rotate) {
      var rotateRadians = rotate * Math.PI / 180;
      var beforeWidth = textRect.width;
      var beforeHeight = textRect.height;
      var afterWidth = beforeWidth * Math.abs(Math.cos(rotateRadians)) + Math.abs(beforeHeight * Math.sin(rotateRadians));
      var afterHeight = beforeWidth * Math.abs(Math.sin(rotateRadians)) + Math.abs(beforeHeight * Math.cos(rotateRadians));
      var rotatedRect = new BoundingRect(textRect.x, textRect.y, afterWidth, afterHeight);
      return rotatedRect;
    }
    /**
     * @param model axisLabelModel or axisTickModel
     * @return {number|String} Can be null|'auto'|number|function
     */


    function getOptionCategoryInterval(model) {
      var interval = model.get('interval');
      return interval == null ? 'auto' : interval;
    }
    /**
     * Set `categoryInterval` as 0 implicitly indicates that
     * show all labels regardless of overlap.
     * @param {Object} axis axisModel.axis
     */

    function shouldShowAllLabels(axis) {
      return axis.type === 'category' && getOptionCategoryInterval(axis.getLabelModel()) === 0;
    }
    function getDataDimensionsOnAxis(data, axisDim) {
      // Remove duplicated dat dimensions caused by `getStackedDimension`.
      var dataDimMap = {}; // Currently `mapDimensionsAll` will contain stack result dimension ('__\0ecstackresult').
      // PENDING: is it reasonable? Do we need to remove the original dim from "coord dim" since
      // there has been stacked result dim?

      each(data.mapDimensionsAll(axisDim), function (dataDim) {
        // For example, the extent of the original dimension
        // is [0.1, 0.5], the extent of the `stackResultDimension`
        // is [7, 9], the final extent should NOT include [0.1, 0.5],
        // because there is no graphic corresponding to [0.1, 0.5].
        // See the case in `test/area-stack.html` `main1`, where area line
        // stack needs `yAxis` not start from 0.
        dataDimMap[getStackedDimension(data, dataDim)] = true;
      });
      return keys(dataDimMap);
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    var AxisModelCommonMixin =
    /** @class */
    function () {
      function AxisModelCommonMixin() {}

      AxisModelCommonMixin.prototype.getNeedCrossZero = function () {
        var option = this.option;
        return !option.scale;
      };
      /**
       * Should be implemented by each axis model if necessary.
       * @return coordinate system model
       */


      AxisModelCommonMixin.prototype.getCoordSysModel = function () {
        return;
      };

      return AxisModelCommonMixin;
    }();

    /**
     * Create a multi dimension List structure from seriesModel.
     */

    function createList(seriesModel) {
      return createSeriesData(null, seriesModel);
    } // export function createGraph(seriesModel) {
    var dataStack$1 = {
      isDimensionStacked: isDimensionStacked,
      enableDataStack: enableDataStack,
      getStackedDimension: getStackedDimension
    };
    /**
     * Create scale
     * @param {Array.<number>} dataExtent
     * @param {Object|module:echarts/Model} option If `optoin.type`
     *        is secified, it can only be `'value'` currently.
     */

    function createScale(dataExtent, option) {
      var axisModel = option;

      if (!(option instanceof Model)) {
        axisModel = new Model(option); // FIXME
        // Currently AxisModelCommonMixin has nothing to do with the
        // the requirements of `axisHelper.createScaleByModel`. For
        // example the methods `getCategories` and `getOrdinalMeta`
        // are required for `'category'` axis, and ecModel is required
        // for `'time'` axis. But occasionally echarts-gl happened
        // to only use `'value'` axis.
        // zrUtil.mixin(axisModel, AxisModelCommonMixin);
      }

      var scale = createScaleByModel(axisModel);
      scale.setExtent(dataExtent[0], dataExtent[1]);
      niceScaleExtent(scale, axisModel);
      return scale;
    }
    /**
     * Mixin common methods to axis model,
     *
     * Include methods
     * `getFormattedLabels() => Array.<string>`
     * `getCategories() => Array.<string>`
     * `getMin(origin: boolean) => number`
     * `getMax(origin: boolean) => number`
     * `getNeedCrossZero() => boolean`
     */

    function mixinAxisModelCommonMethods(Model) {
      mixin(Model, AxisModelCommonMixin);
    }
    function createTextStyle$1(textStyleModel, opts) {
      opts = opts || {};
      return createTextStyle(textStyleModel, null, null, opts.state !== 'normal');
    }

    var helper = /*#__PURE__*/Object.freeze({
        __proto__: null,
        createList: createList,
        getLayoutRect: getLayoutRect,
        dataStack: dataStack$1,
        createScale: createScale,
        mixinAxisModelCommonMethods: mixinAxisModelCommonMethods,
        getECData: getECData,
        createTextStyle: createTextStyle$1,
        createDimensions: createDimensions,
        createSymbol: createSymbol,
        enableHoverEmphasis: enableHoverEmphasis
    });

    var EPSILON$3 = 1e-8;
    function isAroundEqual$1(a, b) {
        return Math.abs(a - b) < EPSILON$3;
    }
    function contain$2(points, x, y) {
        var w = 0;
        var p = points[0];
        if (!p) {
            return false;
        }
        for (var i = 1; i < points.length; i++) {
            var p2 = points[i];
            w += windingLine(p[0], p[1], p2[0], p2[1], x, y);
            p = p2;
        }
        var p0 = points[0];
        if (!isAroundEqual$1(p[0], p0[0]) || !isAroundEqual$1(p[1], p0[1])) {
            w += windingLine(p[0], p[1], p0[0], p0[1], x, y);
        }
        return w !== 0;
    }

    var TMP_TRANSFORM = [];

    function transformPoints(points, transform) {
      for (var p = 0; p < points.length; p++) {
        applyTransform(points[p], points[p], transform);
      }
    }

    function updateBBoxFromPoints(points, min$1, max$1, projection) {
      for (var i = 0; i < points.length; i++) {
        var p = points[i];

        if (projection) {
          // projection may return null point.
          p = projection.project(p);
        }

        if (p && isFinite(p[0]) && isFinite(p[1])) {
          min(min$1, min$1, p);
          max(max$1, max$1, p);
        }
      }
    }

    function centroid(points) {
      var signedArea = 0;
      var cx = 0;
      var cy = 0;
      var len = points.length;
      var x0 = points[len - 1][0];
      var y0 = points[len - 1][1]; // Polygon should been closed.

      for (var i = 0; i < len; i++) {
        var x1 = points[i][0];
        var y1 = points[i][1];
        var a = x0 * y1 - x1 * y0;
        signedArea += a;
        cx += (x0 + x1) * a;
        cy += (y0 + y1) * a;
        x0 = x1;
        y0 = y1;
      }

      return signedArea ? [cx / signedArea / 3, cy / signedArea / 3, signedArea] : [points[0][0] || 0, points[0][1] || 0];
    }

    var Region =
    /** @class */
    function () {
      function Region(name) {
        this.name = name;
      }

      Region.prototype.setCenter = function (center) {
        this._center = center;
      };
      /**
       * Get center point in data unit. That is,
       * for GeoJSONRegion, the unit is lat/lng,
       * for GeoSVGRegion, the unit is SVG local coord.
       */


      Region.prototype.getCenter = function () {
        var center = this._center;

        if (!center) {
          // In most cases there are no need to calculate this center.
          // So calculate only when called.
          center = this._center = this.calcCenter();
        }

        return center;
      };

      return Region;
    }();

    var GeoJSONPolygonGeometry =
    /** @class */
    function () {
      function GeoJSONPolygonGeometry(exterior, interiors) {
        this.type = 'polygon';
        this.exterior = exterior;
        this.interiors = interiors;
      }

      return GeoJSONPolygonGeometry;
    }();

    var GeoJSONLineStringGeometry =
    /** @class */
    function () {
      function GeoJSONLineStringGeometry(points) {
        this.type = 'linestring';
        this.points = points;
      }

      return GeoJSONLineStringGeometry;
    }();

    var GeoJSONRegion =
    /** @class */
    function (_super) {
      __extends(GeoJSONRegion, _super);

      function GeoJSONRegion(name, geometries, cp) {
        var _this = _super.call(this, name) || this;

        _this.type = 'geoJSON';
        _this.geometries = geometries;
        _this._center = cp && [cp[0], cp[1]];
        return _this;
      }

      GeoJSONRegion.prototype.calcCenter = function () {
        var geometries = this.geometries;
        var largestGeo;
        var largestGeoSize = 0;

        for (var i = 0; i < geometries.length; i++) {
          var geo = geometries[i];
          var exterior = geo.exterior; // Simple trick to use points count instead of polygon area as region size.
          // Ignore linestring

          var size = exterior && exterior.length;

          if (size > largestGeoSize) {
            largestGeo = geo;
            largestGeoSize = size;
          }
        }

        if (largestGeo) {
          return centroid(largestGeo.exterior);
        } // from bounding rect by default.


        var rect = this.getBoundingRect();
        return [rect.x + rect.width / 2, rect.y + rect.height / 2];
      };

      GeoJSONRegion.prototype.getBoundingRect = function (projection) {
        var rect = this._rect; // Always recalculate if using projection.

        if (rect && !projection) {
          return rect;
        }

        var min = [Infinity, Infinity];
        var max = [-Infinity, -Infinity];
        var geometries = this.geometries;
        each(geometries, function (geo) {
          if (geo.type === 'polygon') {
            // Doesn't consider hole
            updateBBoxFromPoints(geo.exterior, min, max, projection);
          } else {
            each(geo.points, function (points) {
              updateBBoxFromPoints(points, min, max, projection);
            });
          }
        }); // Normalie invalid bounding.

        if (!(isFinite(min[0]) && isFinite(min[1]) && isFinite(max[0]) && isFinite(max[1]))) {
          min[0] = min[1] = max[0] = max[1] = 0;
        }

        rect = new BoundingRect(min[0], min[1], max[0] - min[0], max[1] - min[1]);

        if (!projection) {
          this._rect = rect;
        }

        return rect;
      };

      GeoJSONRegion.prototype.contain = function (coord) {
        var rect = this.getBoundingRect();
        var geometries = this.geometries;

        if (!rect.contain(coord[0], coord[1])) {
          return false;
        }

        loopGeo: for (var i = 0, len = geometries.length; i < len; i++) {
          var geo = geometries[i]; // Only support polygon.

          if (geo.type !== 'polygon') {
            continue;
          }

          var exterior = geo.exterior;
          var interiors = geo.interiors;

          if (contain$2(exterior, coord[0], coord[1])) {
            // Not in the region if point is in the hole.
            for (var k = 0; k < (interiors ? interiors.length : 0); k++) {
              if (contain$2(interiors[k], coord[0], coord[1])) {
                continue loopGeo;
              }
            }

            return true;
          }
        }

        return false;
      };
      /**
       * Transform the raw coords to target bounding.
       * @param x
       * @param y
       * @param width
       * @param height
       */


      GeoJSONRegion.prototype.transformTo = function (x, y, width, height) {
        var rect = this.getBoundingRect();
        var aspect = rect.width / rect.height;

        if (!width) {
          width = aspect * height;
        } else if (!height) {
          height = width / aspect;
        }

        var target = new BoundingRect(x, y, width, height);
        var transform = rect.calculateTransform(target);
        var geometries = this.geometries;

        for (var i = 0; i < geometries.length; i++) {
          var geo = geometries[i];

          if (geo.type === 'polygon') {
            transformPoints(geo.exterior, transform);
            each(geo.interiors, function (interior) {
              transformPoints(interior, transform);
            });
          } else {
            each(geo.points, function (points) {
              transformPoints(points, transform);
            });
          }
        }

        rect = this._rect;
        rect.copy(target); // Update center

        this._center = [rect.x + rect.width / 2, rect.y + rect.height / 2];
      };

      GeoJSONRegion.prototype.cloneShallow = function (name) {
        name == null && (name = this.name);
        var newRegion = new GeoJSONRegion(name, this.geometries, this._center);
        newRegion._rect = this._rect;
        newRegion.transformTo = null; // Simply avoid to be called.

        return newRegion;
      };

      return GeoJSONRegion;
    }(Region);

    var GeoSVGRegion =
    /** @class */
    function (_super) {
      __extends(GeoSVGRegion, _super);

      function GeoSVGRegion(name, elOnlyForCalculate) {
        var _this = _super.call(this, name) || this;

        _this.type = 'geoSVG';
        _this._elOnlyForCalculate = elOnlyForCalculate;
        return _this;
      }

      GeoSVGRegion.prototype.calcCenter = function () {
        var el = this._elOnlyForCalculate;
        var rect = el.getBoundingRect();
        var center = [rect.x + rect.width / 2, rect.y + rect.height / 2];
        var mat = identity(TMP_TRANSFORM);
        var target = el;

        while (target && !target.isGeoSVGGraphicRoot) {
          mul$1(mat, target.getLocalTransform(), mat);
          target = target.parent;
        }

        invert(mat, mat);
        applyTransform(center, center, mat);
        return center;
      };

      return GeoSVGRegion;
    }(Region);

    function decode(json) {
      if (!json.UTF8Encoding) {
        return json;
      }

      var jsonCompressed = json;
      var encodeScale = jsonCompressed.UTF8Scale;

      if (encodeScale == null) {
        encodeScale = 1024;
      }

      var features = jsonCompressed.features;
      each(features, function (feature) {
        var geometry = feature.geometry;
        var encodeOffsets = geometry.encodeOffsets;
        var coordinates = geometry.coordinates; // Geometry may be appeded manually in the script after json loaded.
        // In this case this geometry is usually not encoded.

        if (!encodeOffsets) {
          return;
        }

        switch (geometry.type) {
          case 'LineString':
            geometry.coordinates = decodeRing(coordinates, encodeOffsets, encodeScale);
            break;

          case 'Polygon':
            decodeRings(coordinates, encodeOffsets, encodeScale);
            break;

          case 'MultiLineString':
            decodeRings(coordinates, encodeOffsets, encodeScale);
            break;

          case 'MultiPolygon':
            each(coordinates, function (rings, idx) {
              return decodeRings(rings, encodeOffsets[idx], encodeScale);
            });
        }
      }); // Has been decoded

      jsonCompressed.UTF8Encoding = false;
      return jsonCompressed;
    }

    function decodeRings(rings, encodeOffsets, encodeScale) {
      for (var c = 0; c < rings.length; c++) {
        rings[c] = decodeRing(rings[c], encodeOffsets[c], encodeScale);
      }
    }

    function decodeRing(coordinate, encodeOffsets, encodeScale) {
      var result = [];
      var prevX = encodeOffsets[0];
      var prevY = encodeOffsets[1];

      for (var i = 0; i < coordinate.length; i += 2) {
        var x = coordinate.charCodeAt(i) - 64;
        var y = coordinate.charCodeAt(i + 1) - 64; // ZigZag decoding

        x = x >> 1 ^ -(x & 1);
        y = y >> 1 ^ -(y & 1); // Delta deocding

        x += prevX;
        y += prevY;
        prevX = x;
        prevY = y; // Dequantize

        result.push([x / encodeScale, y / encodeScale]);
      }

      return result;
    }

    function parseGeoJSON(geoJson, nameProperty) {
      geoJson = decode(geoJson);
      return map(filter(geoJson.features, function (featureObj) {
        // Output of mapshaper may have geometry null
        return featureObj.geometry && featureObj.properties && featureObj.geometry.coordinates.length > 0;
      }), function (featureObj) {
        var properties = featureObj.properties;
        var geo = featureObj.geometry;
        var geometries = [];

        switch (geo.type) {
          case 'Polygon':
            var coordinates = geo.coordinates; // According to the GeoJSON specification.
            // First must be exterior, and the rest are all interior(holes).

            geometries.push(new GeoJSONPolygonGeometry(coordinates[0], coordinates.slice(1)));
            break;

          case 'MultiPolygon':
            each(geo.coordinates, function (item) {
              if (item[0]) {
                geometries.push(new GeoJSONPolygonGeometry(item[0], item.slice(1)));
              }
            });
            break;

          case 'LineString':
            geometries.push(new GeoJSONLineStringGeometry([geo.coordinates]));
            break;

          case 'MultiLineString':
            geometries.push(new GeoJSONLineStringGeometry(geo.coordinates));
        }

        var region = new GeoJSONRegion(properties[nameProperty || 'name'], geometries, properties.cp);
        region.properties = properties;
        return region;
      });
    }

    var number = /*#__PURE__*/Object.freeze({
        __proto__: null,
        linearMap: linearMap,
        round: round,
        asc: asc,
        getPrecision: getPrecision,
        getPrecisionSafe: getPrecisionSafe,
        getPixelPrecision: getPixelPrecision,
        getPercentWithPrecision: getPercentWithPrecision,
        MAX_SAFE_INTEGER: MAX_SAFE_INTEGER,
        remRadian: remRadian,
        isRadianAroundZero: isRadianAroundZero,
        parseDate: parseDate,
        quantity: quantity,
        quantityExponent: quantityExponent,
        nice: nice,
        quantile: quantile,
        reformIntervals: reformIntervals,
        isNumeric: isNumeric,
        numericToNumber: numericToNumber
    });

    var time = /*#__PURE__*/Object.freeze({
        __proto__: null,
        parse: parseDate,
        format: format
    });

    var graphic = /*#__PURE__*/Object.freeze({
        __proto__: null,
        extendShape: extendShape,
        extendPath: extendPath,
        makePath: makePath,
        makeImage: makeImage,
        mergePath: mergePath$1,
        resizePath: resizePath,
        createIcon: createIcon,
        updateProps: updateProps,
        initProps: initProps,
        getTransform: getTransform,
        clipPointsByRect: clipPointsByRect,
        clipRectByRect: clipRectByRect,
        registerShape: registerShape,
        getShapeClass: getShapeClass,
        Group: Group,
        Image: ZRImage,
        Text: ZRText,
        Circle: Circle,
        Ellipse: Ellipse,
        Sector: Sector,
        Ring: Ring,
        Polygon: Polygon,
        Polyline: Polyline,
        Rect: Rect,
        Line: Line,
        BezierCurve: BezierCurve,
        Arc: Arc,
        IncrementalDisplayable: IncrementalDisplayable,
        CompoundPath: CompoundPath,
        LinearGradient: LinearGradient,
        RadialGradient: RadialGradient,
        BoundingRect: BoundingRect
    });

    var format$1 = /*#__PURE__*/Object.freeze({
        __proto__: null,
        addCommas: addCommas,
        toCamelCase: toCamelCase,
        normalizeCssArray: normalizeCssArray$1,
        encodeHTML: encodeHTML,
        formatTpl: formatTpl,
        getTooltipMarker: getTooltipMarker,
        formatTime: formatTime,
        capitalFirst: capitalFirst,
        truncateText: truncateText,
        getTextRect: getTextRect
    });

    var util$1 = /*#__PURE__*/Object.freeze({
        __proto__: null,
        map: map,
        each: each,
        indexOf: indexOf,
        inherits: inherits,
        reduce: reduce,
        filter: filter,
        bind: bind,
        curry: curry,
        isArray: isArray,
        isString: isString,
        isObject: isObject,
        isFunction: isFunction,
        extend: extend,
        defaults: defaults,
        clone: clone,
        merge: merge
    });

    var inner$5 = makeInner();
    function createAxisLabels(axis) {
      // Only ordinal scale support tick interval
      return axis.type === 'category' ? makeCategoryLabels(axis) : makeRealNumberLabels(axis);
    }
    /**
     * @param {module:echats/coord/Axis} axis
     * @param {module:echarts/model/Model} tickModel For example, can be axisTick, splitLine, splitArea.
     * @return {Object} {
     *     ticks: Array.<number>
     *     tickCategoryInterval: number
     * }
     */

    function createAxisTicks(axis, tickModel) {
      // Only ordinal scale support tick interval
      return axis.type === 'category' ? makeCategoryTicks(axis, tickModel) : {
        ticks: map(axis.scale.getTicks(), function (tick) {
          return tick.value;
        })
      };
    }

    function makeCategoryLabels(axis) {
      var labelModel = axis.getLabelModel();
      var result = makeCategoryLabelsActually(axis, labelModel);
      return !labelModel.get('show') || axis.scale.isBlank() ? {
        labels: [],
        labelCategoryInterval: result.labelCategoryInterval
      } : result;
    }

    function makeCategoryLabelsActually(axis, labelModel) {
      var labelsCache = getListCache(axis, 'labels');
      var optionLabelInterval = getOptionCategoryInterval(labelModel);
      var result = listCacheGet(labelsCache, optionLabelInterval);

      if (result) {
        return result;
      }

      var labels;
      var numericLabelInterval;

      if (isFunction(optionLabelInterval)) {
        labels = makeLabelsByCustomizedCategoryInterval(axis, optionLabelInterval);
      } else {
        numericLabelInterval = optionLabelInterval === 'auto' ? makeAutoCategoryInterval(axis) : optionLabelInterval;
        labels = makeLabelsByNumericCategoryInterval(axis, numericLabelInterval);
      } // Cache to avoid calling interval function repeatedly.


      return listCacheSet(labelsCache, optionLabelInterval, {
        labels: labels,
        labelCategoryInterval: numericLabelInterval
      });
    }

    function makeCategoryTicks(axis, tickModel) {
      var ticksCache = getListCache(axis, 'ticks');
      var optionTickInterval = getOptionCategoryInterval(tickModel);
      var result = listCacheGet(ticksCache, optionTickInterval);

      if (result) {
        return result;
      }

      var ticks;
      var tickCategoryInterval; // Optimize for the case that large category data and no label displayed,
      // we should not return all ticks.

      if (!tickModel.get('show') || axis.scale.isBlank()) {
        ticks = [];
      }

      if (isFunction(optionTickInterval)) {
        ticks = makeLabelsByCustomizedCategoryInterval(axis, optionTickInterval, true);
      } // Always use label interval by default despite label show. Consider this
      // scenario, Use multiple grid with the xAxis sync, and only one xAxis shows
      // labels. `splitLine` and `axisTick` should be consistent in this case.
      else if (optionTickInterval === 'auto') {
          var labelsResult = makeCategoryLabelsActually(axis, axis.getLabelModel());
          tickCategoryInterval = labelsResult.labelCategoryInterval;
          ticks = map(labelsResult.labels, function (labelItem) {
            return labelItem.tickValue;
          });
        } else {
          tickCategoryInterval = optionTickInterval;
          ticks = makeLabelsByNumericCategoryInterval(axis, tickCategoryInterval, true);
        } // Cache to avoid calling interval function repeatedly.


      return listCacheSet(ticksCache, optionTickInterval, {
        ticks: ticks,
        tickCategoryInterval: tickCategoryInterval
      });
    }

    function makeRealNumberLabels(axis) {
      var ticks = axis.scale.getTicks();
      var labelFormatter = makeLabelFormatter(axis);
      return {
        labels: map(ticks, function (tick, idx) {
          return {
            level: tick.level,
            formattedLabel: labelFormatter(tick, idx),
            rawLabel: axis.scale.getLabel(tick),
            tickValue: tick.value
          };
        })
      };
    }

    function getListCache(axis, prop) {
      // Because key can be a function, and cache size always is small, we use array cache.
      return inner$5(axis)[prop] || (inner$5(axis)[prop] = []);
    }

    function listCacheGet(cache, key) {
      for (var i = 0; i < cache.length; i++) {
        if (cache[i].key === key) {
          return cache[i].value;
        }
      }
    }

    function listCacheSet(cache, key, value) {
      cache.push({
        key: key,
        value: value
      });
      return value;
    }

    function makeAutoCategoryInterval(axis) {
      var result = inner$5(axis).autoInterval;
      return result != null ? result : inner$5(axis).autoInterval = axis.calculateCategoryInterval();
    }
    /**
     * Calculate interval for category axis ticks and labels.
     * To get precise result, at least one of `getRotate` and `isHorizontal`
     * should be implemented in axis.
     */


    function calculateCategoryInterval(axis) {
      var params = fetchAutoCategoryIntervalCalculationParams(axis);
      var labelFormatter = makeLabelFormatter(axis);
      var rotation = (params.axisRotate - params.labelRotate) / 180 * Math.PI;
      var ordinalScale = axis.scale;
      var ordinalExtent = ordinalScale.getExtent(); // Providing this method is for optimization:
      // avoid generating a long array by `getTicks`
      // in large category data case.

      var tickCount = ordinalScale.count();

      if (ordinalExtent[1] - ordinalExtent[0] < 1) {
        return 0;
      }

      var step = 1; // Simple optimization. Empirical value: tick count should less than 40.

      if (tickCount > 40) {
        step = Math.max(1, Math.floor(tickCount / 40));
      }

      var tickValue = ordinalExtent[0];
      var unitSpan = axis.dataToCoord(tickValue + 1) - axis.dataToCoord(tickValue);
      var unitW = Math.abs(unitSpan * Math.cos(rotation));
      var unitH = Math.abs(unitSpan * Math.sin(rotation));
      var maxW = 0;
      var maxH = 0; // Caution: Performance sensitive for large category data.
      // Consider dataZoom, we should make appropriate step to avoid O(n) loop.

      for (; tickValue <= ordinalExtent[1]; tickValue += step) {
        var width = 0;
        var height = 0; // Not precise, do not consider align and vertical align
        // and each distance from axis line yet.

        var rect = getBoundingRect(labelFormatter({
          value: tickValue
        }), params.font, 'center', 'top'); // Magic number

        width = rect.width * 1.3;
        height = rect.height * 1.3; // Min size, void long loop.

        maxW = Math.max(maxW, width, 7);
        maxH = Math.max(maxH, height, 7);
      }

      var dw = maxW / unitW;
      var dh = maxH / unitH; // 0/0 is NaN, 1/0 is Infinity.

      isNaN(dw) && (dw = Infinity);
      isNaN(dh) && (dh = Infinity);
      var interval = Math.max(0, Math.floor(Math.min(dw, dh)));
      var cache = inner$5(axis.model);
      var axisExtent = axis.getExtent();
      var lastAutoInterval = cache.lastAutoInterval;
      var lastTickCount = cache.lastTickCount; // Use cache to keep interval stable while moving zoom window,
      // otherwise the calculated interval might jitter when the zoom
      // window size is close to the interval-changing size.
      // For example, if all of the axis labels are `a, b, c, d, e, f, g`.
      // The jitter will cause that sometimes the displayed labels are
      // `a, d, g` (interval: 2) sometimes `a, c, e`(interval: 1).

      if (lastAutoInterval != null && lastTickCount != null && Math.abs(lastAutoInterval - interval) <= 1 && Math.abs(lastTickCount - tickCount) <= 1 // Always choose the bigger one, otherwise the critical
      // point is not the same when zooming in or zooming out.
      && lastAutoInterval > interval // If the axis change is caused by chart resize, the cache should not
      // be used. Otherwise some hidden labels might not be shown again.
      && cache.axisExtent0 === axisExtent[0] && cache.axisExtent1 === axisExtent[1]) {
        interval = lastAutoInterval;
      } // Only update cache if cache not used, otherwise the
      // changing of interval is too insensitive.
      else {
          cache.lastTickCount = tickCount;
          cache.lastAutoInterval = interval;
          cache.axisExtent0 = axisExtent[0];
          cache.axisExtent1 = axisExtent[1];
        }

      return interval;
    }

    function fetchAutoCategoryIntervalCalculationParams(axis) {
      var labelModel = axis.getLabelModel();
      return {
        axisRotate: axis.getRotate ? axis.getRotate() : axis.isHorizontal && !axis.isHorizontal() ? 90 : 0,
        labelRotate: labelModel.get('rotate') || 0,
        font: labelModel.getFont()
      };
    }

    function makeLabelsByNumericCategoryInterval(axis, categoryInterval, onlyTick) {
      var labelFormatter = makeLabelFormatter(axis);
      var ordinalScale = axis.scale;
      var ordinalExtent = ordinalScale.getExtent();
      var labelModel = axis.getLabelModel();
      var result = []; // TODO: axisType: ordinalTime, pick the tick from each month/day/year/...

      var step = Math.max((categoryInterval || 0) + 1, 1);
      var startTick = ordinalExtent[0];
      var tickCount = ordinalScale.count(); // Calculate start tick based on zero if possible to keep label consistent
      // while zooming and moving while interval > 0. Otherwise the selection
      // of displayable ticks and symbols probably keep changing.
      // 3 is empirical value.

      if (startTick !== 0 && step > 1 && tickCount / step > 2) {
        startTick = Math.round(Math.ceil(startTick / step) * step);
      } // (1) Only add min max label here but leave overlap checking
      // to render stage, which also ensure the returned list
      // suitable for splitLine and splitArea rendering.
      // (2) Scales except category always contain min max label so
      // do not need to perform this process.


      var showAllLabel = shouldShowAllLabels(axis);
      var includeMinLabel = labelModel.get('showMinLabel') || showAllLabel;
      var includeMaxLabel = labelModel.get('showMaxLabel') || showAllLabel;

      if (includeMinLabel && startTick !== ordinalExtent[0]) {
        addItem(ordinalExtent[0]);
      } // Optimize: avoid generating large array by `ordinalScale.getTicks()`.


      var tickValue = startTick;

      for (; tickValue <= ordinalExtent[1]; tickValue += step) {
        addItem(tickValue);
      }

      if (includeMaxLabel && tickValue - step !== ordinalExtent[1]) {
        addItem(ordinalExtent[1]);
      }

      function addItem(tickValue) {
        var tickObj = {
          value: tickValue
        };
        result.push(onlyTick ? tickValue : {
          formattedLabel: labelFormatter(tickObj),
          rawLabel: ordinalScale.getLabel(tickObj),
          tickValue: tickValue
        });
      }

      return result;
    }

    function makeLabelsByCustomizedCategoryInterval(axis, categoryInterval, onlyTick) {
      var ordinalScale = axis.scale;
      var labelFormatter = makeLabelFormatter(axis);
      var result = [];
      each(ordinalScale.getTicks(), function (tick) {
        var rawLabel = ordinalScale.getLabel(tick);
        var tickValue = tick.value;

        if (categoryInterval(tick.value, rawLabel)) {
          result.push(onlyTick ? tickValue : {
            formattedLabel: labelFormatter(tick),
            rawLabel: rawLabel,
            tickValue: tickValue
          });
        }
      });
      return result;
    }

    var NORMALIZED_EXTENT = [0, 1];
    /**
     * Base class of Axis.
     */

    var Axis =
    /** @class */
    function () {
      function Axis(dim, scale, extent) {
        this.onBand = false;
        this.inverse = false;
        this.dim = dim;
        this.scale = scale;
        this._extent = extent || [0, 0];
      }
      /**
       * If axis extent contain given coord
       */


      Axis.prototype.contain = function (coord) {
        var extent = this._extent;
        var min = Math.min(extent[0], extent[1]);
        var max = Math.max(extent[0], extent[1]);
        return coord >= min && coord <= max;
      };
      /**
       * If axis extent contain given data
       */


      Axis.prototype.containData = function (data) {
        return this.scale.contain(data);
      };
      /**
       * Get coord extent.
       */


      Axis.prototype.getExtent = function () {
        return this._extent.slice();
      };
      /**
       * Get precision used for formatting
       */


      Axis.prototype.getPixelPrecision = function (dataExtent) {
        return getPixelPrecision(dataExtent || this.scale.getExtent(), this._extent);
      };
      /**
       * Set coord extent
       */


      Axis.prototype.setExtent = function (start, end) {
        var extent = this._extent;
        extent[0] = start;
        extent[1] = end;
      };
      /**
       * Convert data to coord. Data is the rank if it has an ordinal scale
       */


      Axis.prototype.dataToCoord = function (data, clamp) {
        var extent = this._extent;
        var scale = this.scale;
        data = scale.normalize(data);

        if (this.onBand && scale.type === 'ordinal') {
          extent = extent.slice();
          fixExtentWithBands(extent, scale.count());
        }

        return linearMap(data, NORMALIZED_EXTENT, extent, clamp);
      };
      /**
       * Convert coord to data. Data is the rank if it has an ordinal scale
       */


      Axis.prototype.coordToData = function (coord, clamp) {
        var extent = this._extent;
        var scale = this.scale;

        if (this.onBand && scale.type === 'ordinal') {
          extent = extent.slice();
          fixExtentWithBands(extent, scale.count());
        }

        var t = linearMap(coord, extent, NORMALIZED_EXTENT, clamp);
        return this.scale.scale(t);
      };
      /**
       * Convert pixel point to data in axis
       */


      Axis.prototype.pointToData = function (point, clamp) {
        // Should be implemented in derived class if necessary.
        return;
      };
      /**
       * Different from `zrUtil.map(axis.getTicks(), axis.dataToCoord, axis)`,
       * `axis.getTicksCoords` considers `onBand`, which is used by
       * `boundaryGap:true` of category axis and splitLine and splitArea.
       * @param opt.tickModel default: axis.model.getModel('axisTick')
       * @param opt.clamp If `true`, the first and the last
       *        tick must be at the axis end points. Otherwise, clip ticks
       *        that outside the axis extent.
       */


      Axis.prototype.getTicksCoords = function (opt) {
        opt = opt || {};
        var tickModel = opt.tickModel || this.getTickModel();
        var result = createAxisTicks(this, tickModel);
        var ticks = result.ticks;
        var ticksCoords = map(ticks, function (tickVal) {
          return {
            coord: this.dataToCoord(this.scale.type === 'ordinal' ? this.scale.getRawOrdinalNumber(tickVal) : tickVal),
            tickValue: tickVal
          };
        }, this);
        var alignWithLabel = tickModel.get('alignWithLabel');
        fixOnBandTicksCoords(this, ticksCoords, alignWithLabel, opt.clamp);
        return ticksCoords;
      };

      Axis.prototype.getMinorTicksCoords = function () {
        if (this.scale.type === 'ordinal') {
          // Category axis doesn't support minor ticks
          return [];
        }

        var minorTickModel = this.model.getModel('minorTick');
        var splitNumber = minorTickModel.get('splitNumber'); // Protection.

        if (!(splitNumber > 0 && splitNumber < 100)) {
          splitNumber = 5;
        }

        var minorTicks = this.scale.getMinorTicks(splitNumber);
        var minorTicksCoords = map(minorTicks, function (minorTicksGroup) {
          return map(minorTicksGroup, function (minorTick) {
            return {
              coord: this.dataToCoord(minorTick),
              tickValue: minorTick
            };
          }, this);
        }, this);
        return minorTicksCoords;
      };

      Axis.prototype.getViewLabels = function () {
        return createAxisLabels(this).labels;
      };

      Axis.prototype.getLabelModel = function () {
        return this.model.getModel('axisLabel');
      };
      /**
       * Notice here we only get the default tick model. For splitLine
       * or splitArea, we should pass the splitLineModel or splitAreaModel
       * manually when calling `getTicksCoords`.
       * In GL, this method may be overridden to:
       * `axisModel.getModel('axisTick', grid3DModel.getModel('axisTick'));`
       */


      Axis.prototype.getTickModel = function () {
        return this.model.getModel('axisTick');
      };
      /**
       * Get width of band
       */


      Axis.prototype.getBandWidth = function () {
        var axisExtent = this._extent;
        var dataExtent = this.scale.getExtent();
        var len = dataExtent[1] - dataExtent[0] + (this.onBand ? 1 : 0); // Fix #2728, avoid NaN when only one data.

        len === 0 && (len = 1);
        var size = Math.abs(axisExtent[1] - axisExtent[0]);
        return Math.abs(size) / len;
      };
      /**
       * Only be called in category axis.
       * Can be overridden, consider other axes like in 3D.
       * @return Auto interval for cateogry axis tick and label
       */


      Axis.prototype.calculateCategoryInterval = function () {
        return calculateCategoryInterval(this);
      };

      return Axis;
    }();

    function fixExtentWithBands(extent, nTick) {
      var size = extent[1] - extent[0];
      var len = nTick;
      var margin = size / len / 2;
      extent[0] += margin;
      extent[1] -= margin;
    } // If axis has labels [1, 2, 3, 4]. Bands on the axis are
    // |---1---|---2---|---3---|---4---|.
    // So the displayed ticks and splitLine/splitArea should between
    // each data item, otherwise cause misleading (e.g., split tow bars
    // of a single data item when there are two bar series).
    // Also consider if tickCategoryInterval > 0 and onBand, ticks and
    // splitLine/spliteArea should layout appropriately corresponding
    // to displayed labels. (So we should not use `getBandWidth` in this
    // case).


    function fixOnBandTicksCoords(axis, ticksCoords, alignWithLabel, clamp) {
      var ticksLen = ticksCoords.length;

      if (!axis.onBand || alignWithLabel || !ticksLen) {
        return;
      }

      var axisExtent = axis.getExtent();
      var last;
      var diffSize;

      if (ticksLen === 1) {
        ticksCoords[0].coord = axisExtent[0];
        last = ticksCoords[1] = {
          coord: axisExtent[0]
        };
      } else {
        var crossLen = ticksCoords[ticksLen - 1].tickValue - ticksCoords[0].tickValue;
        var shift_1 = (ticksCoords[ticksLen - 1].coord - ticksCoords[0].coord) / crossLen;
        each(ticksCoords, function (ticksItem) {
          ticksItem.coord -= shift_1 / 2;
        });
        var dataExtent = axis.scale.getExtent();
        diffSize = 1 + dataExtent[1] - ticksCoords[ticksLen - 1].tickValue;
        last = {
          coord: ticksCoords[ticksLen - 1].coord + shift_1 * diffSize
        };
        ticksCoords.push(last);
      }

      var inverse = axisExtent[0] > axisExtent[1]; // Handling clamp.

      if (littleThan(ticksCoords[0].coord, axisExtent[0])) {
        clamp ? ticksCoords[0].coord = axisExtent[0] : ticksCoords.shift();
      }

      if (clamp && littleThan(axisExtent[0], ticksCoords[0].coord)) {
        ticksCoords.unshift({
          coord: axisExtent[0]
        });
      }

      if (littleThan(axisExtent[1], last.coord)) {
        clamp ? last.coord = axisExtent[1] : ticksCoords.pop();
      }

      if (clamp && littleThan(last.coord, axisExtent[1])) {
        ticksCoords.push({
          coord: axisExtent[1]
        });
      }

      function littleThan(a, b) {
        // Avoid rounding error cause calculated tick coord different with extent.
        // It may cause an extra unnecessary tick added.
        a = round(a);
        b = round(b);
        return inverse ? a > b : a < b;
      }
    }

    // Should use `ComponentModel.extend` or `class XXXX extend ComponentModel` to create class.
    // Then use `registerComponentModel` in `install` parameter when `use` this extension. For example:
    // class Bar3DModel extends ComponentModel {}
    // export function install(registers) { registers.registerComponentModel(Bar3DModel); }
    // echarts.use(install);

    function extendComponentModel(proto) {
      var Model = ComponentModel.extend(proto);
      ComponentModel.registerClass(Model);
      return Model;
    }
    function extendComponentView(proto) {
      var View = ComponentView.extend(proto);
      ComponentView.registerClass(View);
      return View;
    }
    function extendSeriesModel(proto) {
      var Model = SeriesModel.extend(proto);
      SeriesModel.registerClass(Model);
      return Model;
    }
    function extendChartView(proto) {
      var View = ChartView.extend(proto);
      ChartView.registerClass(View);
      return View;
    }

    function projectPointToLine(x1, y1, x2, y2, x, y, out, limitToEnds) {
      var dx = x - x1;
      var dy = y - y1;
      var dx1 = x2 - x1;
      var dy1 = y2 - y1;
      var lineLen = Math.sqrt(dx1 * dx1 + dy1 * dy1);
      dx1 /= lineLen;
      dy1 /= lineLen; // dot product

      var projectedLen = dx * dx1 + dy * dy1;
      var t = projectedLen / lineLen;

      if (limitToEnds) {
        t = Math.min(Math.max(t, 0), 1);
      }

      t *= lineLen;
      var ox = out[0] = x1 + t * dx1;
      var oy = out[1] = y1 + t * dy1;
      return Math.sqrt((ox - x) * (ox - x) + (oy - y) * (oy - y));
    }


    var pt0 = new Point();
    var pt1 = new Point();
    var pt2 = new Point();
    var dir = new Point();
    var dir2 = new Point();

    var tmpArr = [];
    var tmpProjPoint = new Point();
    /**
     * Reduce the line segment attached to the label to limit the turn angle between two segments.
     * @param linePoints
     * @param minTurnAngle Radian of minimum turn angle. 0 - 180
     */

    function limitTurnAngle(linePoints, minTurnAngle) {
      if (!(minTurnAngle <= 180 && minTurnAngle > 0)) {
        return;
      }

      minTurnAngle = minTurnAngle / 180 * Math.PI; // The line points can be
      //      /pt1----pt2 (label)
      //     /
      // pt0/

      pt0.fromArray(linePoints[0]);
      pt1.fromArray(linePoints[1]);
      pt2.fromArray(linePoints[2]);
      Point.sub(dir, pt0, pt1);
      Point.sub(dir2, pt2, pt1);
      var len1 = dir.len();
      var len2 = dir2.len();

      if (len1 < 1e-3 || len2 < 1e-3) {
        return;
      }

      dir.scale(1 / len1);
      dir2.scale(1 / len2);
      var angleCos = dir.dot(dir2);
      var minTurnAngleCos = Math.cos(minTurnAngle);

      if (minTurnAngleCos < angleCos) {
        // Smaller than minTurnAngle
        // Calculate project point of pt0 on pt1-pt2
        var d = projectPointToLine(pt1.x, pt1.y, pt2.x, pt2.y, pt0.x, pt0.y, tmpArr, false);
        tmpProjPoint.fromArray(tmpArr); // Calculate new projected length with limited minTurnAngle and get the new connect point

        tmpProjPoint.scaleAndAdd(dir2, d / Math.tan(Math.PI - minTurnAngle)); // Limit the new calculated connect point between pt1 and pt2.

        var t = pt2.x !== pt1.x ? (tmpProjPoint.x - pt1.x) / (pt2.x - pt1.x) : (tmpProjPoint.y - pt1.y) / (pt2.y - pt1.y);

        if (isNaN(t)) {
          return;
        }

        if (t < 0) {
          Point.copy(tmpProjPoint, pt1);
        } else if (t > 1) {
          Point.copy(tmpProjPoint, pt2);
        }

        tmpProjPoint.toArray(linePoints[1]);
      }
    }
    /**
     * Limit the angle of line and the surface
     * @param maxSurfaceAngle Radian of minimum turn angle. 0 - 180. 0 is same direction to normal. 180 is opposite
     */

    function limitSurfaceAngle(linePoints, surfaceNormal, maxSurfaceAngle) {
      if (!(maxSurfaceAngle <= 180 && maxSurfaceAngle > 0)) {
        return;
      }

      maxSurfaceAngle = maxSurfaceAngle / 180 * Math.PI;
      pt0.fromArray(linePoints[0]);
      pt1.fromArray(linePoints[1]);
      pt2.fromArray(linePoints[2]);
      Point.sub(dir, pt1, pt0);
      Point.sub(dir2, pt2, pt1);
      var len1 = dir.len();
      var len2 = dir2.len();

      if (len1 < 1e-3 || len2 < 1e-3) {
        return;
      }

      dir.scale(1 / len1);
      dir2.scale(1 / len2);
      var angleCos = dir.dot(surfaceNormal);
      var maxSurfaceAngleCos = Math.cos(maxSurfaceAngle);

      if (angleCos < maxSurfaceAngleCos) {
        // Calculate project point of pt0 on pt1-pt2
        var d = projectPointToLine(pt1.x, pt1.y, pt2.x, pt2.y, pt0.x, pt0.y, tmpArr, false);
        tmpProjPoint.fromArray(tmpArr);
        var HALF_PI = Math.PI / 2;
        var angle2 = Math.acos(dir2.dot(surfaceNormal));
        var newAngle = HALF_PI + angle2 - maxSurfaceAngle;

        if (newAngle >= HALF_PI) {
          // parallel
          Point.copy(tmpProjPoint, pt2);
        } else {
          // Calculate new projected length with limited minTurnAngle and get the new connect point
          tmpProjPoint.scaleAndAdd(dir2, d / Math.tan(Math.PI / 2 - newAngle)); // Limit the new calculated connect point between pt1 and pt2.

          var t = pt2.x !== pt1.x ? (tmpProjPoint.x - pt1.x) / (pt2.x - pt1.x) : (tmpProjPoint.y - pt1.y) / (pt2.y - pt1.y);

          if (isNaN(t)) {
            return;
          }

          if (t < 0) {
            Point.copy(tmpProjPoint, pt1);
          } else if (t > 1) {
            Point.copy(tmpProjPoint, pt2);
          }
        }

        tmpProjPoint.toArray(linePoints[1]);
      }
    }

    function setLabelLineState(labelLine, ignore, stateName, stateModel) {
      var isNormal = stateName === 'normal';
      var stateObj = isNormal ? labelLine : labelLine.ensureState(stateName); // Make sure display.

      stateObj.ignore = ignore; // Set smooth

      var smooth = stateModel.get('smooth');

      if (smooth && smooth === true) {
        smooth = 0.3;
      }

      stateObj.shape = stateObj.shape || {};

      if (smooth > 0) {
        stateObj.shape.smooth = smooth;
      }

      var styleObj = stateModel.getModel('lineStyle').getLineStyle();
      isNormal ? labelLine.useStyle(styleObj) : stateObj.style = styleObj;
    }

    function buildLabelLinePath(path, shape) {
      var smooth = shape.smooth;
      var points = shape.points;

      if (!points) {
        return;
      }

      path.moveTo(points[0][0], points[0][1]);

      if (smooth > 0 && points.length >= 3) {
        var len1 = dist(points[0], points[1]);
        var len2 = dist(points[1], points[2]);

        if (!len1 || !len2) {
          path.lineTo(points[1][0], points[1][1]);
          path.lineTo(points[2][0], points[2][1]);
          return;
        }

        var moveLen = Math.min(len1, len2) * smooth;
        var midPoint0 = lerp([], points[1], points[0], moveLen / len1);
        var midPoint2 = lerp([], points[1], points[2], moveLen / len2);
        var midPoint1 = lerp([], midPoint0, midPoint2, 0.5);
        path.bezierCurveTo(midPoint0[0], midPoint0[1], midPoint0[0], midPoint0[1], midPoint1[0], midPoint1[1]);
        path.bezierCurveTo(midPoint2[0], midPoint2[1], midPoint2[0], midPoint2[1], points[2][0], points[2][1]);
      } else {
        for (var i = 1; i < points.length; i++) {
          path.lineTo(points[i][0], points[i][1]);
        }
      }
    }
    /**
     * Create a label line if necessary and set it's style.
     */


    function setLabelLineStyle(targetEl, statesModels, defaultStyle) {
      var labelLine = targetEl.getTextGuideLine();
      var label = targetEl.getTextContent();

      if (!label) {
        // Not show label line if there is no label.
        if (labelLine) {
          targetEl.removeTextGuideLine();
        }

        return;
      }

      var normalModel = statesModels.normal;
      var showNormal = normalModel.get('show');
      var labelIgnoreNormal = label.ignore;

      for (var i = 0; i < DISPLAY_STATES.length; i++) {
        var stateName = DISPLAY_STATES[i];
        var stateModel = statesModels[stateName];
        var isNormal = stateName === 'normal';

        if (stateModel) {
          var stateShow = stateModel.get('show');
          var isLabelIgnored = isNormal ? labelIgnoreNormal : retrieve2(label.states[stateName] && label.states[stateName].ignore, labelIgnoreNormal);

          if (isLabelIgnored // Not show when label is not shown in this state.
          || !retrieve2(stateShow, showNormal) // Use normal state by default if not set.
          ) {
              var stateObj = isNormal ? labelLine : labelLine && labelLine.states[stateName];

              if (stateObj) {
                stateObj.ignore = true;
              }

              continue;
            } // Create labelLine if not exists


          if (!labelLine) {
            labelLine = new Polyline();
            targetEl.setTextGuideLine(labelLine); // Reset state of normal because it's new created.
            // NOTE: NORMAL should always been the first!

            if (!isNormal && (labelIgnoreNormal || !showNormal)) {
              setLabelLineState(labelLine, true, 'normal', statesModels.normal);
            } // Use same state proxy.


            if (targetEl.stateProxy) {
              labelLine.stateProxy = targetEl.stateProxy;
            }
          }

          setLabelLineState(labelLine, false, stateName, stateModel);
        }
      }

      if (labelLine) {
        defaults(labelLine.style, defaultStyle); // Not fill.

        labelLine.style.fill = null;
        var showAbove = normalModel.get('showAbove');
        var labelLineConfig = targetEl.textGuideLineConfig = targetEl.textGuideLineConfig || {};
        labelLineConfig.showAbove = showAbove || false; // Custom the buildPath.

        labelLine.buildPath = buildLabelLinePath;
      }
    }
    function getLabelLineStatesModels(itemModel, labelLineName) {
      labelLineName = labelLineName || 'labelLine';
      var statesModels = {
        normal: itemModel.getModel(labelLineName)
      };

      for (var i = 0; i < SPECIAL_STATES.length; i++) {
        var stateName = SPECIAL_STATES[i];
        statesModels[stateName] = itemModel.getModel([stateName, labelLineName]);
      }

      return statesModels;
    }

    function prepareLayoutList(input) {
      var list = [];

      for (var i = 0; i < input.length; i++) {
        var rawItem = input[i];

        if (rawItem.defaultAttr.ignore) {
          continue;
        }

        var label = rawItem.label;
        var transform = label.getComputedTransform(); // NOTE: Get bounding rect after getComputedTransform, or label may not been updated by the host el.

        var localRect = label.getBoundingRect();
        var isAxisAligned = !transform || transform[1] < 1e-5 && transform[2] < 1e-5;
        var minMargin = label.style.margin || 0;
        var globalRect = localRect.clone();
        globalRect.applyTransform(transform);
        globalRect.x -= minMargin / 2;
        globalRect.y -= minMargin / 2;
        globalRect.width += minMargin;
        globalRect.height += minMargin;
        var obb = isAxisAligned ? new OrientedBoundingRect(localRect, transform) : null;
        list.push({
          label: label,
          labelLine: rawItem.labelLine,
          rect: globalRect,
          localRect: localRect,
          obb: obb,
          priority: rawItem.priority,
          defaultAttr: rawItem.defaultAttr,
          layoutOption: rawItem.computedLayoutOption,
          axisAligned: isAxisAligned,
          transform: transform
        });
      }

      return list;
    }

    function shiftLayout(list, xyDim, sizeDim, minBound, maxBound, balanceShift) {
      var len = list.length;

      if (len < 2) {
        return;
      }

      list.sort(function (a, b) {
        return a.rect[xyDim] - b.rect[xyDim];
      });
      var lastPos = 0;
      var delta;
      var adjusted = false;
      var totalShifts = 0;

      for (var i = 0; i < len; i++) {
        var item = list[i];
        var rect = item.rect;
        delta = rect[xyDim] - lastPos;

        if (delta < 0) {
          // shiftForward(i, len, -delta);
          rect[xyDim] -= delta;
          item.label[xyDim] -= delta;
          adjusted = true;
        }

        var shift = Math.max(-delta, 0);
        totalShifts += shift;
        lastPos = rect[xyDim] + rect[sizeDim];
      }

      if (totalShifts > 0 && balanceShift) {
        // Shift back to make the distribution more equally.
        shiftList(-totalShifts / len, 0, len);
      } // TODO bleedMargin?


      var first = list[0];
      var last = list[len - 1];
      var minGap;
      var maxGap;
      updateMinMaxGap(); // If ends exceed two bounds, squeeze at most 80%, then take the gap of two bounds.

      minGap < 0 && squeezeGaps(-minGap, 0.8);
      maxGap < 0 && squeezeGaps(maxGap, 0.8);
      updateMinMaxGap();
      takeBoundsGap(minGap, maxGap, 1);
      takeBoundsGap(maxGap, minGap, -1); // Handle bailout when there is not enough space.

      updateMinMaxGap();

      if (minGap < 0) {
        squeezeWhenBailout(-minGap);
      }

      if (maxGap < 0) {
        squeezeWhenBailout(maxGap);
      }

      function updateMinMaxGap() {
        minGap = first.rect[xyDim] - minBound;
        maxGap = maxBound - last.rect[xyDim] - last.rect[sizeDim];
      }

      function takeBoundsGap(gapThisBound, gapOtherBound, moveDir) {
        if (gapThisBound < 0) {
          // Move from other gap if can.
          var moveFromMaxGap = Math.min(gapOtherBound, -gapThisBound);

          if (moveFromMaxGap > 0) {
            shiftList(moveFromMaxGap * moveDir, 0, len);
            var remained = moveFromMaxGap + gapThisBound;

            if (remained < 0) {
              squeezeGaps(-remained * moveDir, 1);
            }
          } else {
            squeezeGaps(-gapThisBound * moveDir, 1);
          }
        }
      }

      function shiftList(delta, start, end) {
        if (delta !== 0) {
          adjusted = true;
        }

        for (var i = start; i < end; i++) {
          var item = list[i];
          var rect = item.rect;
          rect[xyDim] += delta;
          item.label[xyDim] += delta;
        }
      } // Squeeze gaps if the labels exceed margin.


      function squeezeGaps(delta, maxSqeezePercent) {
        var gaps = [];
        var totalGaps = 0;

        for (var i = 1; i < len; i++) {
          var prevItemRect = list[i - 1].rect;
          var gap = Math.max(list[i].rect[xyDim] - prevItemRect[xyDim] - prevItemRect[sizeDim], 0);
          gaps.push(gap);
          totalGaps += gap;
        }

        if (!totalGaps) {
          return;
        }

        var squeezePercent = Math.min(Math.abs(delta) / totalGaps, maxSqeezePercent);

        if (delta > 0) {
          for (var i = 0; i < len - 1; i++) {
            // Distribute the shift delta to all gaps.
            var movement = gaps[i] * squeezePercent; // Forward

            shiftList(movement, 0, i + 1);
          }
        } else {
          // Backward
          for (var i = len - 1; i > 0; i--) {
            // Distribute the shift delta to all gaps.
            var movement = gaps[i - 1] * squeezePercent;
            shiftList(-movement, i, len);
          }
        }
      }
      /**
       * Squeeze to allow overlap if there is no more space available.
       * Let other overlapping strategy like hideOverlap do the job instead of keep exceeding the bounds.
       */


      function squeezeWhenBailout(delta) {
        var dir = delta < 0 ? -1 : 1;
        delta = Math.abs(delta);
        var moveForEachLabel = Math.ceil(delta / (len - 1));

        for (var i = 0; i < len - 1; i++) {
          if (dir > 0) {
            // Forward
            shiftList(moveForEachLabel, 0, i + 1);
          } else {
            // Backward
            shiftList(-moveForEachLabel, len - i - 1, len);
          }

          delta -= moveForEachLabel;

          if (delta <= 0) {
            return;
          }
        }
      }

      return adjusted;
    }
    /**
     * Adjust labels on y direction to avoid overlap.
     */

    function shiftLayoutOnY(list, topBound, bottomBound, // If average the shifts on all labels and add them to 0
    balanceShift) {
      return shiftLayout(list, 'y', 'height', topBound, bottomBound, balanceShift);
    }
    function hideOverlap(labelList) {
      var displayedLabels = []; // TODO, render overflow visible first, put in the displayedLabels.

      labelList.sort(function (a, b) {
        return b.priority - a.priority;
      });
      var globalRect = new BoundingRect(0, 0, 0, 0);

      function hideEl(el) {
        if (!el.ignore) {
          // Show on emphasis.
          var emphasisState = el.ensureState('emphasis');

          if (emphasisState.ignore == null) {
            emphasisState.ignore = false;
          }
        }

        el.ignore = true;
      }

      for (var i = 0; i < labelList.length; i++) {
        var labelItem = labelList[i];
        var isAxisAligned = labelItem.axisAligned;
        var localRect = labelItem.localRect;
        var transform = labelItem.transform;
        var label = labelItem.label;
        var labelLine = labelItem.labelLine;
        globalRect.copy(labelItem.rect); // Add a threshold because layout may be aligned precisely.

        globalRect.width -= 0.1;
        globalRect.height -= 0.1;
        globalRect.x += 0.05;
        globalRect.y += 0.05;
        var obb = labelItem.obb;
        var overlapped = false;

        for (var j = 0; j < displayedLabels.length; j++) {
          var existsTextCfg = displayedLabels[j]; // Fast rejection.

          if (!globalRect.intersect(existsTextCfg.rect)) {
            continue;
          }

          if (isAxisAligned && existsTextCfg.axisAligned) {
            // Is overlapped
            overlapped = true;
            break;
          }

          if (!existsTextCfg.obb) {
            // If self is not axis aligned. But other is.
            existsTextCfg.obb = new OrientedBoundingRect(existsTextCfg.localRect, existsTextCfg.transform);
          }

          if (!obb) {
            // If self is axis aligned. But other is not.
            obb = new OrientedBoundingRect(localRect, transform);
          }

          if (obb.intersect(existsTextCfg.obb)) {
            overlapped = true;
            break;
          }
        } // TODO Callback to determine if this overlap should be handled?


        if (overlapped) {
          hideEl(label);
          labelLine && hideEl(labelLine);
        } else {
          label.attr('ignore', labelItem.defaultAttr.ignore);
          labelLine && labelLine.attr('ignore', labelItem.defaultAttr.labelGuideIgnore);
          displayedLabels.push(labelItem);
        }
      }
    }

    function createDom(id, painter, dpr) {
        var newDom = platformApi.createCanvas();
        var width = painter.getWidth();
        var height = painter.getHeight();
        var newDomStyle = newDom.style;
        if (newDomStyle) {
            newDomStyle.position = 'absolute';
            newDomStyle.left = '0';
            newDomStyle.top = '0';
            newDomStyle.width = width + 'px';
            newDomStyle.height = height + 'px';
            newDom.setAttribute('data-zr-dom-id', id);
        }
        newDom.width = width * dpr;
        newDom.height = height * dpr;
        return newDom;
    }
    var Layer = (function (_super) {
        __extends(Layer, _super);
        function Layer(id, painter, dpr) {
            var _this = _super.call(this) || this;
            _this.motionBlur = false;
            _this.lastFrameAlpha = 0.7;
            _this.dpr = 1;
            _this.virtual = false;
            _this.config = {};
            _this.incremental = false;
            _this.zlevel = 0;
            _this.maxRepaintRectCount = 5;
            _this.__dirty = true;
            _this.__firstTimePaint = true;
            _this.__used = false;
            _this.__drawIndex = 0;
            _this.__startIndex = 0;
            _this.__endIndex = 0;
            _this.__prevStartIndex = null;
            _this.__prevEndIndex = null;
            var dom;
            dpr = dpr || devicePixelRatio;
            if (typeof id === 'string') {
                dom = createDom(id, painter, dpr);
            }
            else if (isObject(id)) {
                dom = id;
                id = dom.id;
            }
            _this.id = id;
            _this.dom = dom;
            var domStyle = dom.style;
            if (domStyle) {
                disableUserSelect(dom);
                dom.onselectstart = function () { return false; };
                domStyle.padding = '0';
                domStyle.margin = '0';
                domStyle.borderWidth = '0';
            }
            _this.painter = painter;
            _this.dpr = dpr;
            return _this;
        }
        Layer.prototype.getElementCount = function () {
            return this.__endIndex - this.__startIndex;
        };
        Layer.prototype.afterBrush = function () {
            this.__prevStartIndex = this.__startIndex;
            this.__prevEndIndex = this.__endIndex;
        };
        Layer.prototype.initContext = function () {
            this.ctx = this.dom.getContext('2d');
            this.ctx.dpr = this.dpr;
        };
        Layer.prototype.setUnpainted = function () {
            this.__firstTimePaint = true;
        };
        Layer.prototype.createBackBuffer = function () {
            var dpr = this.dpr;
            this.domBack = createDom('back-' + this.id, this.painter, dpr);
            this.ctxBack = this.domBack.getContext('2d');
            if (dpr !== 1) {
                this.ctxBack.scale(dpr, dpr);
            }
        };
        Layer.prototype.createRepaintRects = function (displayList, prevList, viewWidth, viewHeight) {
            if (this.__firstTimePaint) {
                this.__firstTimePaint = false;
                return null;
            }
            var mergedRepaintRects = [];
            var maxRepaintRectCount = this.maxRepaintRectCount;
            var full = false;
            var pendingRect = new BoundingRect(0, 0, 0, 0);
            function addRectToMergePool(rect) {
                if (!rect.isFinite() || rect.isZero()) {
                    return;
                }
                if (mergedRepaintRects.length === 0) {
                    var boundingRect = new BoundingRect(0, 0, 0, 0);
                    boundingRect.copy(rect);
                    mergedRepaintRects.push(boundingRect);
                }
                else {
                    var isMerged = false;
                    var minDeltaArea = Infinity;
                    var bestRectToMergeIdx = 0;
                    for (var i = 0; i < mergedRepaintRects.length; ++i) {
                        var mergedRect = mergedRepaintRects[i];
                        if (mergedRect.intersect(rect)) {
                            var pendingRect_1 = new BoundingRect(0, 0, 0, 0);
                            pendingRect_1.copy(mergedRect);
                            pendingRect_1.union(rect);
                            mergedRepaintRects[i] = pendingRect_1;
                            isMerged = true;
                            break;
                        }
                        else if (full) {
                            pendingRect.copy(rect);
                            pendingRect.union(mergedRect);
                            var aArea = rect.width * rect.height;
                            var bArea = mergedRect.width * mergedRect.height;
                            var pendingArea = pendingRect.width * pendingRect.height;
                            var deltaArea = pendingArea - aArea - bArea;
                            if (deltaArea < minDeltaArea) {
                                minDeltaArea = deltaArea;
                                bestRectToMergeIdx = i;
                            }
                        }
                    }
                    if (full) {
                        mergedRepaintRects[bestRectToMergeIdx].union(rect);
                        isMerged = true;
                    }
                    if (!isMerged) {
                        var boundingRect = new BoundingRect(0, 0, 0, 0);
                        boundingRect.copy(rect);
                        mergedRepaintRects.push(boundingRect);
                    }
                    if (!full) {
                        full = mergedRepaintRects.length >= maxRepaintRectCount;
                    }
                }
            }
            for (var i = this.__startIndex; i < this.__endIndex; ++i) {
                var el = displayList[i];
                if (el) {
                    var shouldPaint = el.shouldBePainted(viewWidth, viewHeight, true, true);
                    var prevRect = el.__isRendered && ((el.__dirty & REDRAW_BIT) || !shouldPaint)
                        ? el.getPrevPaintRect()
                        : null;
                    if (prevRect) {
                        addRectToMergePool(prevRect);
                    }
                    var curRect = shouldPaint && ((el.__dirty & REDRAW_BIT) || !el.__isRendered)
                        ? el.getPaintRect()
                        : null;
                    if (curRect) {
                        addRectToMergePool(curRect);
                    }
                }
            }
            for (var i = this.__prevStartIndex; i < this.__prevEndIndex; ++i) {
                var el = prevList[i];
                var shouldPaint = el.shouldBePainted(viewWidth, viewHeight, true, true);
                if (el && (!shouldPaint || !el.__zr) && el.__isRendered) {
                    var prevRect = el.getPrevPaintRect();
                    if (prevRect) {
                        addRectToMergePool(prevRect);
                    }
                }
            }
            var hasIntersections;
            do {
                hasIntersections = false;
                for (var i = 0; i < mergedRepaintRects.length;) {
                    if (mergedRepaintRects[i].isZero()) {
                        mergedRepaintRects.splice(i, 1);
                        continue;
                    }
                    for (var j = i + 1; j < mergedRepaintRects.length;) {
                        if (mergedRepaintRects[i].intersect(mergedRepaintRects[j])) {
                            hasIntersections = true;
                            mergedRepaintRects[i].union(mergedRepaintRects[j]);
                            mergedRepaintRects.splice(j, 1);
                        }
                        else {
                            j++;
                        }
                    }
                    i++;
                }
            } while (hasIntersections);
            this._paintRects = mergedRepaintRects;
            return mergedRepaintRects;
        };
        Layer.prototype.debugGetPaintRects = function () {
            return (this._paintRects || []).slice();
        };
        Layer.prototype.resize = function (width, height) {
            var dpr = this.dpr;
            var dom = this.dom;
            var domStyle = dom.style;
            var domBack = this.domBack;
            if (domStyle) {
                domStyle.width = width + 'px';
                domStyle.height = height + 'px';
            }
            dom.width = width * dpr;
            dom.height = height * dpr;
            if (domBack) {
                domBack.width = width * dpr;
                domBack.height = height * dpr;
                if (dpr !== 1) {
                    this.ctxBack.scale(dpr, dpr);
                }
            }
        };
        Layer.prototype.clear = function (clearAll, clearColor, repaintRects) {
            var dom = this.dom;
            var ctx = this.ctx;
            var width = dom.width;
            var height = dom.height;
            clearColor = clearColor || this.clearColor;
            var haveMotionBLur = this.motionBlur && !clearAll;
            var lastFrameAlpha = this.lastFrameAlpha;
            var dpr = this.dpr;
            var self = this;
            if (haveMotionBLur) {
                if (!this.domBack) {
                    this.createBackBuffer();
                }
                this.ctxBack.globalCompositeOperation = 'copy';
                this.ctxBack.drawImage(dom, 0, 0, width / dpr, height / dpr);
            }
            var domBack = this.domBack;
            function doClear(x, y, width, height) {
                ctx.clearRect(x, y, width, height);
                if (clearColor && clearColor !== 'transparent') {
                    var clearColorGradientOrPattern = void 0;
                    if (isGradientObject(clearColor)) {
                        var shouldCache = clearColor.global || (clearColor.__width === width
                            && clearColor.__height === height);
                        clearColorGradientOrPattern = shouldCache
                            && clearColor.__canvasGradient
                            || getCanvasGradient(ctx, clearColor, {
                                x: 0,
                                y: 0,
                                width: width,
                                height: height
                            });
                        clearColor.__canvasGradient = clearColorGradientOrPattern;
                        clearColor.__width = width;
                        clearColor.__height = height;
                    }
                    else if (isImagePatternObject(clearColor)) {
                        clearColor.scaleX = clearColor.scaleX || dpr;
                        clearColor.scaleY = clearColor.scaleY || dpr;
                        clearColorGradientOrPattern = createCanvasPattern(ctx, clearColor, {
                            dirty: function () {
                                self.setUnpainted();
                                self.__painter.refresh();
                            }
                        });
                    }
                    ctx.save();
                    ctx.fillStyle = clearColorGradientOrPattern || clearColor;
                    ctx.fillRect(x, y, width, height);
                    ctx.restore();
                }
                if (haveMotionBLur) {
                    ctx.save();
                    ctx.globalAlpha = lastFrameAlpha;
                    ctx.drawImage(domBack, x, y, width, height);
                    ctx.restore();
                }
            }
            if (!repaintRects || haveMotionBLur) {
                doClear(0, 0, width, height);
            }
            else if (repaintRects.length) {
                each(repaintRects, function (rect) {
                    doClear(rect.x * dpr, rect.y * dpr, rect.width * dpr, rect.height * dpr);
                });
            }
        };
        return Layer;
    }(Eventful));

    var HOVER_LAYER_ZLEVEL = 1e5;
    var CANVAS_ZLEVEL = 314159;
    var EL_AFTER_INCREMENTAL_INC = 0.01;
    var INCREMENTAL_INC = 0.001;
    function isLayerValid(layer) {
        if (!layer) {
            return false;
        }
        if (layer.__builtin__) {
            return true;
        }
        if (typeof (layer.resize) !== 'function'
            || typeof (layer.refresh) !== 'function') {
            return false;
        }
        return true;
    }
    function createRoot(width, height) {
        var domRoot = document.createElement('div');
        domRoot.style.cssText = [
            'position:relative',
            'width:' + width + 'px',
            'height:' + height + 'px',
            'padding:0',
            'margin:0',
            'border-width:0'
        ].join(';') + ';';
        return domRoot;
    }
    var CanvasPainter = (function () {
        function CanvasPainter(root, storage, opts, id) {
            this.type = 'canvas';
            this._zlevelList = [];
            this._prevDisplayList = [];
            this._layers = {};
            this._layerConfig = {};
            this._needsManuallyCompositing = false;
            this.type = 'canvas';
            var singleCanvas = !root.nodeName
                || root.nodeName.toUpperCase() === 'CANVAS';
            this._opts = opts = extend({}, opts || {});
            this.dpr = opts.devicePixelRatio || devicePixelRatio;
            this._singleCanvas = singleCanvas;
            this.root = root;
            var rootStyle = root.style;
            if (rootStyle) {
                disableUserSelect(root);
                root.innerHTML = '';
            }
            this.storage = storage;
            var zlevelList = this._zlevelList;
            this._prevDisplayList = [];
            var layers = this._layers;
            if (!singleCanvas) {
                this._width = getSize(root, 0, opts);
                this._height = getSize(root, 1, opts);
                var domRoot = this._domRoot = createRoot(this._width, this._height);
                root.appendChild(domRoot);
            }
            else {
                var rootCanvas = root;
                var width = rootCanvas.width;
                var height = rootCanvas.height;
                if (opts.width != null) {
                    width = opts.width;
                }
                if (opts.height != null) {
                    height = opts.height;
                }
                this.dpr = opts.devicePixelRatio || 1;
                rootCanvas.width = width * this.dpr;
                rootCanvas.height = height * this.dpr;
                this._width = width;
                this._height = height;
                var mainLayer = new Layer(rootCanvas, this, this.dpr);
                mainLayer.__builtin__ = true;
                mainLayer.initContext();
                layers[CANVAS_ZLEVEL] = mainLayer;
                mainLayer.zlevel = CANVAS_ZLEVEL;
                zlevelList.push(CANVAS_ZLEVEL);
                this._domRoot = root;
            }
        }
        CanvasPainter.prototype.getType = function () {
            return 'canvas';
        };
        CanvasPainter.prototype.isSingleCanvas = function () {
            return this._singleCanvas;
        };
        CanvasPainter.prototype.getViewportRoot = function () {
            return this._domRoot;
        };
        CanvasPainter.prototype.getViewportRootOffset = function () {
            var viewportRoot = this.getViewportRoot();
            if (viewportRoot) {
                return {
                    offsetLeft: viewportRoot.offsetLeft || 0,
                    offsetTop: viewportRoot.offsetTop || 0
                };
            }
        };
        CanvasPainter.prototype.refresh = function (paintAll) {
            var list = this.storage.getDisplayList(true);
            var prevList = this._prevDisplayList;
            var zlevelList = this._zlevelList;
            this._redrawId = Math.random();
            this._paintList(list, prevList, paintAll, this._redrawId);
            for (var i = 0; i < zlevelList.length; i++) {
                var z = zlevelList[i];
                var layer = this._layers[z];
                if (!layer.__builtin__ && layer.refresh) {
                    var clearColor = i === 0 ? this._backgroundColor : null;
                    layer.refresh(clearColor);
                }
            }
            if (this._opts.useDirtyRect) {
                this._prevDisplayList = list.slice();
            }
            return this;
        };
        CanvasPainter.prototype.refreshHover = function () {
            this._paintHoverList(this.storage.getDisplayList(false));
        };
        CanvasPainter.prototype._paintHoverList = function (list) {
            var len = list.length;
            var hoverLayer = this._hoverlayer;
            hoverLayer && hoverLayer.clear();
            if (!len) {
                return;
            }
            var scope = {
                inHover: true,
                viewWidth: this._width,
                viewHeight: this._height
            };
            var ctx;
            for (var i = 0; i < len; i++) {
                var el = list[i];
                if (el.__inHover) {
                    if (!hoverLayer) {
                        hoverLayer = this._hoverlayer = this.getLayer(HOVER_LAYER_ZLEVEL);
                    }
                    if (!ctx) {
                        ctx = hoverLayer.ctx;
                        ctx.save();
                    }
                    brush(ctx, el, scope, i === len - 1);
                }
            }
            if (ctx) {
                ctx.restore();
            }
        };
        CanvasPainter.prototype.getHoverLayer = function () {
            return this.getLayer(HOVER_LAYER_ZLEVEL);
        };
        CanvasPainter.prototype.paintOne = function (ctx, el) {
            brushSingle(ctx, el);
        };
        CanvasPainter.prototype._paintList = function (list, prevList, paintAll, redrawId) {
            if (this._redrawId !== redrawId) {
                return;
            }
            paintAll = paintAll || false;
            this._updateLayerStatus(list);
            var _a = this._doPaintList(list, prevList, paintAll), finished = _a.finished, needsRefreshHover = _a.needsRefreshHover;
            if (this._needsManuallyCompositing) {
                this._compositeManually();
            }
            if (needsRefreshHover) {
                this._paintHoverList(list);
            }
            if (!finished) {
                var self_1 = this;
                requestAnimationFrame$1(function () {
                    self_1._paintList(list, prevList, paintAll, redrawId);
                });
            }
            else {
                this.eachLayer(function (layer) {
                    layer.afterBrush && layer.afterBrush();
                });
            }
        };
        CanvasPainter.prototype._compositeManually = function () {
            var ctx = this.getLayer(CANVAS_ZLEVEL).ctx;
            var width = this._domRoot.width;
            var height = this._domRoot.height;
            ctx.clearRect(0, 0, width, height);
            this.eachBuiltinLayer(function (layer) {
                if (layer.virtual) {
                    ctx.drawImage(layer.dom, 0, 0, width, height);
                }
            });
        };
        CanvasPainter.prototype._doPaintList = function (list, prevList, paintAll) {
            var _this = this;
            var layerList = [];
            var useDirtyRect = this._opts.useDirtyRect;
            for (var zi = 0; zi < this._zlevelList.length; zi++) {
                var zlevel = this._zlevelList[zi];
                var layer = this._layers[zlevel];
                if (layer.__builtin__
                    && layer !== this._hoverlayer
                    && (layer.__dirty || paintAll)) {
                    layerList.push(layer);
                }
            }
            var finished = true;
            var needsRefreshHover = false;
            var _loop_1 = function (k) {
                var layer = layerList[k];
                var ctx = layer.ctx;
                var repaintRects = useDirtyRect
                    && layer.createRepaintRects(list, prevList, this_1._width, this_1._height);
                var start = paintAll ? layer.__startIndex : layer.__drawIndex;
                var useTimer = !paintAll && layer.incremental && Date.now;
                var startTime = useTimer && Date.now();
                var clearColor = layer.zlevel === this_1._zlevelList[0]
                    ? this_1._backgroundColor : null;
                if (layer.__startIndex === layer.__endIndex) {
                    layer.clear(false, clearColor, repaintRects);
                }
                else if (start === layer.__startIndex) {
                    var firstEl = list[start];
                    if (!firstEl.incremental || !firstEl.notClear || paintAll) {
                        layer.clear(false, clearColor, repaintRects);
                    }
                }
                if (start === -1) {
                    console.error('For some unknown reason. drawIndex is -1');
                    start = layer.__startIndex;
                }
                var i;
                var repaint = function (repaintRect) {
                    var scope = {
                        inHover: false,
                        allClipped: false,
                        prevEl: null,
                        viewWidth: _this._width,
                        viewHeight: _this._height
                    };
                    for (i = start; i < layer.__endIndex; i++) {
                        var el = list[i];
                        if (el.__inHover) {
                            needsRefreshHover = true;
                        }
                        _this._doPaintEl(el, layer, useDirtyRect, repaintRect, scope, i === layer.__endIndex - 1);
                        if (useTimer) {
                            var dTime = Date.now() - startTime;
                            if (dTime > 15) {
                                break;
                            }
                        }
                    }
                    if (scope.prevElClipPaths) {
                        ctx.restore();
                    }
                };
                if (repaintRects) {
                    if (repaintRects.length === 0) {
                        i = layer.__endIndex;
                    }
                    else {
                        var dpr = this_1.dpr;
                        for (var r = 0; r < repaintRects.length; ++r) {
                            var rect = repaintRects[r];
                            ctx.save();
                            ctx.beginPath();
                            ctx.rect(rect.x * dpr, rect.y * dpr, rect.width * dpr, rect.height * dpr);
                            ctx.clip();
                            repaint(rect);
                            ctx.restore();
                        }
                    }
                }
                else {
                    ctx.save();
                    repaint();
                    ctx.restore();
                }
                layer.__drawIndex = i;
                if (layer.__drawIndex < layer.__endIndex) {
                    finished = false;
                }
            };
            var this_1 = this;
            for (var k = 0; k < layerList.length; k++) {
                _loop_1(k);
            }
            if (env.wxa) {
                each(this._layers, function (layer) {
                    if (layer && layer.ctx && layer.ctx.draw) {
                        layer.ctx.draw();
                    }
                });
            }
            return {
                finished: finished,
                needsRefreshHover: needsRefreshHover
            };
        };
        CanvasPainter.prototype._doPaintEl = function (el, currentLayer, useDirtyRect, repaintRect, scope, isLast) {
            var ctx = currentLayer.ctx;
            if (useDirtyRect) {
                var paintRect = el.getPaintRect();
                if (!repaintRect || paintRect && paintRect.intersect(repaintRect)) {
                    brush(ctx, el, scope, isLast);
                    el.setPrevPaintRect(paintRect);
                }
            }
            else {
                brush(ctx, el, scope, isLast);
            }
        };
        CanvasPainter.prototype.getLayer = function (zlevel, virtual) {
            if (this._singleCanvas && !this._needsManuallyCompositing) {
                zlevel = CANVAS_ZLEVEL;
            }
            var layer = this._layers[zlevel];
            if (!layer) {
                layer = new Layer('zr_' + zlevel, this, this.dpr);
                layer.zlevel = zlevel;
                layer.__builtin__ = true;
                if (this._layerConfig[zlevel]) {
                    merge(layer, this._layerConfig[zlevel], true);
                }
                else if (this._layerConfig[zlevel - EL_AFTER_INCREMENTAL_INC]) {
                    merge(layer, this._layerConfig[zlevel - EL_AFTER_INCREMENTAL_INC], true);
                }
                if (virtual) {
                    layer.virtual = virtual;
                }
                this.insertLayer(zlevel, layer);
                layer.initContext();
            }
            return layer;
        };
        CanvasPainter.prototype.insertLayer = function (zlevel, layer) {
            var layersMap = this._layers;
            var zlevelList = this._zlevelList;
            var len = zlevelList.length;
            var domRoot = this._domRoot;
            var prevLayer = null;
            var i = -1;
            if (layersMap[zlevel]) {
                if ("development" !== 'production') {
                    logError('ZLevel ' + zlevel + ' has been used already');
                }
                return;
            }
            if (!isLayerValid(layer)) {
                if ("development" !== 'production') {
                    logError('Layer of zlevel ' + zlevel + ' is not valid');
                }
                return;
            }
            if (len > 0 && zlevel > zlevelList[0]) {
                for (i = 0; i < len - 1; i++) {
                    if (zlevelList[i] < zlevel
                        && zlevelList[i + 1] > zlevel) {
                        break;
                    }
                }
                prevLayer = layersMap[zlevelList[i]];
            }
            zlevelList.splice(i + 1, 0, zlevel);
            layersMap[zlevel] = layer;
            if (!layer.virtual) {
                if (prevLayer) {
                    var prevDom = prevLayer.dom;
                    if (prevDom.nextSibling) {
                        domRoot.insertBefore(layer.dom, prevDom.nextSibling);
                    }
                    else {
                        domRoot.appendChild(layer.dom);
                    }
                }
                else {
                    if (domRoot.firstChild) {
                        domRoot.insertBefore(layer.dom, domRoot.firstChild);
                    }
                    else {
                        domRoot.appendChild(layer.dom);
                    }
                }
            }
            layer.__painter = this;
        };
        CanvasPainter.prototype.eachLayer = function (cb, context) {
            var zlevelList = this._zlevelList;
            for (var i = 0; i < zlevelList.length; i++) {
                var z = zlevelList[i];
                cb.call(context, this._layers[z], z);
            }
        };
        CanvasPainter.prototype.eachBuiltinLayer = function (cb, context) {
            var zlevelList = this._zlevelList;
            for (var i = 0; i < zlevelList.length; i++) {
                var z = zlevelList[i];
                var layer = this._layers[z];
                if (layer.__builtin__) {
                    cb.call(context, layer, z);
                }
            }
        };
        CanvasPainter.prototype.eachOtherLayer = function (cb, context) {
            var zlevelList = this._zlevelList;
            for (var i = 0; i < zlevelList.length; i++) {
                var z = zlevelList[i];
                var layer = this._layers[z];
                if (!layer.__builtin__) {
                    cb.call(context, layer, z);
                }
            }
        };
        CanvasPainter.prototype.getLayers = function () {
            return this._layers;
        };
        CanvasPainter.prototype._updateLayerStatus = function (list) {
            this.eachBuiltinLayer(function (layer, z) {
                layer.__dirty = layer.__used = false;
            });
            function updatePrevLayer(idx) {
                if (prevLayer) {
                    if (prevLayer.__endIndex !== idx) {
                        prevLayer.__dirty = true;
                    }
                    prevLayer.__endIndex = idx;
                }
            }
            if (this._singleCanvas) {
                for (var i_1 = 1; i_1 < list.length; i_1++) {
                    var el = list[i_1];
                    if (el.zlevel !== list[i_1 - 1].zlevel || el.incremental) {
                        this._needsManuallyCompositing = true;
                        break;
                    }
                }
            }
            var prevLayer = null;
            var incrementalLayerCount = 0;
            var prevZlevel;
            var i;
            for (i = 0; i < list.length; i++) {
                var el = list[i];
                var zlevel = el.zlevel;
                var layer = void 0;
                if (prevZlevel !== zlevel) {
                    prevZlevel = zlevel;
                    incrementalLayerCount = 0;
                }
                if (el.incremental) {
                    layer = this.getLayer(zlevel + INCREMENTAL_INC, this._needsManuallyCompositing);
                    layer.incremental = true;
                    incrementalLayerCount = 1;
                }
                else {
                    layer = this.getLayer(zlevel + (incrementalLayerCount > 0 ? EL_AFTER_INCREMENTAL_INC : 0), this._needsManuallyCompositing);
                }
                if (!layer.__builtin__) {
                    logError('ZLevel ' + zlevel + ' has been used by unkown layer ' + layer.id);
                }
                if (layer !== prevLayer) {
                    layer.__used = true;
                    if (layer.__startIndex !== i) {
                        layer.__dirty = true;
                    }
                    layer.__startIndex = i;
                    if (!layer.incremental) {
                        layer.__drawIndex = i;
                    }
                    else {
                        layer.__drawIndex = -1;
                    }
                    updatePrevLayer(i);
                    prevLayer = layer;
                }
                if ((el.__dirty & REDRAW_BIT) && !el.__inHover) {
                    layer.__dirty = true;
                    if (layer.incremental && layer.__drawIndex < 0) {
                        layer.__drawIndex = i;
                    }
                }
            }
            updatePrevLayer(i);
            this.eachBuiltinLayer(function (layer, z) {
                if (!layer.__used && layer.getElementCount() > 0) {
                    layer.__dirty = true;
                    layer.__startIndex = layer.__endIndex = layer.__drawIndex = 0;
                }
                if (layer.__dirty && layer.__drawIndex < 0) {
                    layer.__drawIndex = layer.__startIndex;
                }
            });
        };
        CanvasPainter.prototype.clear = function () {
            this.eachBuiltinLayer(this._clearLayer);
            return this;
        };
        CanvasPainter.prototype._clearLayer = function (layer) {
            layer.clear();
        };
        CanvasPainter.prototype.setBackgroundColor = function (backgroundColor) {
            this._backgroundColor = backgroundColor;
            each(this._layers, function (layer) {
                layer.setUnpainted();
            });
        };
        CanvasPainter.prototype.configLayer = function (zlevel, config) {
            if (config) {
                var layerConfig = this._layerConfig;
                if (!layerConfig[zlevel]) {
                    layerConfig[zlevel] = config;
                }
                else {
                    merge(layerConfig[zlevel], config, true);
                }
                for (var i = 0; i < this._zlevelList.length; i++) {
                    var _zlevel = this._zlevelList[i];
                    if (_zlevel === zlevel || _zlevel === zlevel + EL_AFTER_INCREMENTAL_INC) {
                        var layer = this._layers[_zlevel];
                        merge(layer, layerConfig[zlevel], true);
                    }
                }
            }
        };
        CanvasPainter.prototype.delLayer = function (zlevel) {
            var layers = this._layers;
            var zlevelList = this._zlevelList;
            var layer = layers[zlevel];
            if (!layer) {
                return;
            }
            layer.dom.parentNode.removeChild(layer.dom);
            delete layers[zlevel];
            zlevelList.splice(indexOf(zlevelList, zlevel), 1);
        };
        CanvasPainter.prototype.resize = function (width, height) {
            if (!this._domRoot.style) {
                if (width == null || height == null) {
                    return;
                }
                this._width = width;
                this._height = height;
                this.getLayer(CANVAS_ZLEVEL).resize(width, height);
            }
            else {
                var domRoot = this._domRoot;
                domRoot.style.display = 'none';
                var opts = this._opts;
                var root = this.root;
                width != null && (opts.width = width);
                height != null && (opts.height = height);
                width = getSize(root, 0, opts);
                height = getSize(root, 1, opts);
                domRoot.style.display = '';
                if (this._width !== width || height !== this._height) {
                    domRoot.style.width = width + 'px';
                    domRoot.style.height = height + 'px';
                    for (var id in this._layers) {
                        if (this._layers.hasOwnProperty(id)) {
                            this._layers[id].resize(width, height);
                        }
                    }
                    this.refresh(true);
                }
                this._width = width;
                this._height = height;
            }
            return this;
        };
        CanvasPainter.prototype.clearLayer = function (zlevel) {
            var layer = this._layers[zlevel];
            if (layer) {
                layer.clear();
            }
        };
        CanvasPainter.prototype.dispose = function () {
            this.root.innerHTML = '';
            this.root =
                this.storage =
                    this._domRoot =
                        this._layers = null;
        };
        CanvasPainter.prototype.getRenderedCanvas = function (opts) {
            opts = opts || {};
            if (this._singleCanvas && !this._compositeManually) {
                return this._layers[CANVAS_ZLEVEL].dom;
            }
            var imageLayer = new Layer('image', this, opts.pixelRatio || this.dpr);
            imageLayer.initContext();
            imageLayer.clear(false, opts.backgroundColor || this._backgroundColor);
            var ctx = imageLayer.ctx;
            if (opts.pixelRatio <= this.dpr) {
                this.refresh();
                var width_1 = imageLayer.dom.width;
                var height_1 = imageLayer.dom.height;
                this.eachLayer(function (layer) {
                    if (layer.__builtin__) {
                        ctx.drawImage(layer.dom, 0, 0, width_1, height_1);
                    }
                    else if (layer.renderToCanvas) {
                        ctx.save();
                        layer.renderToCanvas(ctx);
                        ctx.restore();
                    }
                });
            }
            else {
                var scope = {
                    inHover: false,
                    viewWidth: this._width,
                    viewHeight: this._height
                };
                var displayList = this.storage.getDisplayList(true);
                for (var i = 0, len = displayList.length; i < len; i++) {
                    var el = displayList[i];
                    brush(ctx, el, scope, i === len - 1);
                }
            }
            return imageLayer.dom;
        };
        CanvasPainter.prototype.getWidth = function () {
            return this._width;
        };
        CanvasPainter.prototype.getHeight = function () {
            return this._height;
        };
        return CanvasPainter;
    }());

    function install(registers) {
      registers.registerPainter('canvas', CanvasPainter);
    }

    var LineSeriesModel =
    /** @class */
    function (_super) {
      __extends(LineSeriesModel, _super);

      function LineSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = LineSeriesModel.type;
        _this.hasSymbolVisual = true;
        return _this;
      }

      LineSeriesModel.prototype.getInitialData = function (option) {
        if ("development" !== 'production') {
          var coordSys = option.coordinateSystem;

          if (coordSys !== 'polar' && coordSys !== 'cartesian2d') {
            throw new Error('Line not support coordinateSystem besides cartesian and polar');
          }
        }

        return createSeriesData(null, this, {
          useEncodeDefaulter: true
        });
      };

      LineSeriesModel.prototype.getLegendIcon = function (opt) {
        var group = new Group();
        var line = createSymbol('line', 0, opt.itemHeight / 2, opt.itemWidth, 0, opt.lineStyle.stroke, false);
        group.add(line);
        line.setStyle(opt.lineStyle);
        var visualType = this.getData().getVisual('symbol');
        var visualRotate = this.getData().getVisual('symbolRotate');
        var symbolType = visualType === 'none' ? 'circle' : visualType; // Symbol size is 80% when there is a line

        var size = opt.itemHeight * 0.8;
        var symbol = createSymbol(symbolType, (opt.itemWidth - size) / 2, (opt.itemHeight - size) / 2, size, size, opt.itemStyle.fill);
        group.add(symbol);
        symbol.setStyle(opt.itemStyle);
        var symbolRotate = opt.iconRotate === 'inherit' ? visualRotate : opt.iconRotate || 0;
        symbol.rotation = symbolRotate * Math.PI / 180;
        symbol.setOrigin([opt.itemWidth / 2, opt.itemHeight / 2]);

        if (symbolType.indexOf('empty') > -1) {
          symbol.style.stroke = symbol.style.fill;
          symbol.style.fill = '#fff';
          symbol.style.lineWidth = 2;
        }

        return group;
      };

      LineSeriesModel.type = 'series.line';
      LineSeriesModel.dependencies = ['grid', 'polar'];
      LineSeriesModel.defaultOption = {
        // zlevel: 0,
        z: 3,
        coordinateSystem: 'cartesian2d',
        legendHoverLink: true,
        clip: true,
        label: {
          position: 'top'
        },
        // itemStyle: {
        // },
        endLabel: {
          show: false,
          valueAnimation: true,
          distance: 8
        },
        lineStyle: {
          width: 2,
          type: 'solid'
        },
        emphasis: {
          scale: true
        },
        // areaStyle: {
        // origin of areaStyle. Valid values:
        // `'auto'/null/undefined`: from axisLine to data
        // `'start'`: from min to data
        // `'end'`: from data to max
        // origin: 'auto'
        // },
        // false, 'start', 'end', 'middle'
        step: false,
        // Disabled if step is true
        smooth: false,
        smoothMonotone: null,
        symbol: 'emptyCircle',
        symbolSize: 4,
        symbolRotate: null,
        showSymbol: true,
        // `false`: follow the label interval strategy.
        // `true`: show all symbols.
        // `'auto'`: If possible, show all symbols, otherwise
        //           follow the label interval strategy.
        showAllSymbol: 'auto',
        // Whether to connect break point.
        connectNulls: false,
        // Sampling for large data. Can be: 'average', 'max', 'min', 'sum', 'lttb'.
        sampling: 'none',
        animationEasing: 'linear',
        // Disable progressive
        progressive: 0,
        hoverLayerThreshold: Infinity,
        universalTransition: {
          divideShape: 'clone'
        },
        triggerLineEvent: false
      };
      return LineSeriesModel;
    }(SeriesModel);

    /**
     * @return label string. Not null/undefined
     */

    function getDefaultLabel(data, dataIndex) {
      var labelDims = data.mapDimensionsAll('defaultedLabel');
      var len = labelDims.length; // Simple optimization (in lots of cases, label dims length is 1)

      if (len === 1) {
        var rawVal = retrieveRawValue(data, dataIndex, labelDims[0]);
        return rawVal != null ? rawVal + '' : null;
      } else if (len) {
        var vals = [];

        for (var i = 0; i < labelDims.length; i++) {
          vals.push(retrieveRawValue(data, dataIndex, labelDims[i]));
        }

        return vals.join(' ');
      }
    }
    function getDefaultInterpolatedLabel(data, interpolatedValue) {
      var labelDims = data.mapDimensionsAll('defaultedLabel');

      if (!isArray(interpolatedValue)) {
        return interpolatedValue + '';
      }

      var vals = [];

      for (var i = 0; i < labelDims.length; i++) {
        var dimIndex = data.getDimensionIndex(labelDims[i]);

        if (dimIndex >= 0) {
          vals.push(interpolatedValue[dimIndex]);
        }
      }

      return vals.join(' ');
    }

    var Symbol =
    /** @class */
    function (_super) {
      __extends(Symbol, _super);

      function Symbol(data, idx, seriesScope, opts) {
        var _this = _super.call(this) || this;

        _this.updateData(data, idx, seriesScope, opts);

        return _this;
      }

      Symbol.prototype._createSymbol = function (symbolType, data, idx, symbolSize, keepAspect) {
        // Remove paths created before
        this.removeAll(); // let symbolPath = createSymbol(
        //     symbolType, -0.5, -0.5, 1, 1, color
        // );
        // If width/height are set too small (e.g., set to 1) on ios10
        // and macOS Sierra, a circle stroke become a rect, no matter what
        // the scale is set. So we set width/height as 2. See #4150.

        var symbolPath = createSymbol(symbolType, -1, -1, 2, 2, null, keepAspect);
        symbolPath.attr({
          z2: 100,
          culling: true,
          scaleX: symbolSize[0] / 2,
          scaleY: symbolSize[1] / 2
        }); // Rewrite drift method

        symbolPath.drift = driftSymbol;
        this._symbolType = symbolType;
        this.add(symbolPath);
      };
      /**
       * Stop animation
       * @param {boolean} toLastFrame
       */


      Symbol.prototype.stopSymbolAnimation = function (toLastFrame) {
        this.childAt(0).stopAnimation(null, toLastFrame);
      };

      Symbol.prototype.getSymbolType = function () {
        return this._symbolType;
      };
      /**
       * FIXME:
       * Caution: This method breaks the encapsulation of this module,
       * but it indeed brings convenience. So do not use the method
       * unless you detailedly know all the implements of `Symbol`,
       * especially animation.
       *
       * Get symbol path element.
       */


      Symbol.prototype.getSymbolPath = function () {
        return this.childAt(0);
      };
      /**
       * Highlight symbol
       */


      Symbol.prototype.highlight = function () {
        enterEmphasis(this.childAt(0));
      };
      /**
       * Downplay symbol
       */


      Symbol.prototype.downplay = function () {
        leaveEmphasis(this.childAt(0));
      };
      /**
       * @param {number} zlevel
       * @param {number} z
       */


      Symbol.prototype.setZ = function (zlevel, z) {
        var symbolPath = this.childAt(0);
        symbolPath.zlevel = zlevel;
        symbolPath.z = z;
      };

      Symbol.prototype.setDraggable = function (draggable, hasCursorOption) {
        var symbolPath = this.childAt(0);
        symbolPath.draggable = draggable;
        symbolPath.cursor = !hasCursorOption && draggable ? 'move' : symbolPath.cursor;
      };
      /**
       * Update symbol properties
       */


      Symbol.prototype.updateData = function (data, idx, seriesScope, opts) {
        this.silent = false;
        var symbolType = data.getItemVisual(idx, 'symbol') || 'circle';
        var seriesModel = data.hostModel;
        var symbolSize = Symbol.getSymbolSize(data, idx);
        var isInit = symbolType !== this._symbolType;
        var disableAnimation = opts && opts.disableAnimation;

        if (isInit) {
          var keepAspect = data.getItemVisual(idx, 'symbolKeepAspect');

          this._createSymbol(symbolType, data, idx, symbolSize, keepAspect);
        } else {
          var symbolPath = this.childAt(0);
          symbolPath.silent = false;
          var target = {
            scaleX: symbolSize[0] / 2,
            scaleY: symbolSize[1] / 2
          };
          disableAnimation ? symbolPath.attr(target) : updateProps(symbolPath, target, seriesModel, idx);
          saveOldStyle(symbolPath);
        }

        this._updateCommon(data, idx, symbolSize, seriesScope, opts);

        if (isInit) {
          var symbolPath = this.childAt(0);

          if (!disableAnimation) {
            var target = {
              scaleX: this._sizeX,
              scaleY: this._sizeY,
              style: {
                // Always fadeIn. Because it has fadeOut animation when symbol is removed..
                opacity: symbolPath.style.opacity
              }
            };
            symbolPath.scaleX = symbolPath.scaleY = 0;
            symbolPath.style.opacity = 0;
            initProps(symbolPath, target, seriesModel, idx);
          }
        }

        if (disableAnimation) {
          // Must stop leave transition manually if don't call initProps or updateProps.
          this.childAt(0).stopAnimation('leave');
        }
      };

      Symbol.prototype._updateCommon = function (data, idx, symbolSize, seriesScope, opts) {
        var symbolPath = this.childAt(0);
        var seriesModel = data.hostModel;
        var emphasisItemStyle;
        var blurItemStyle;
        var selectItemStyle;
        var focus;
        var blurScope;
        var emphasisDisabled;
        var labelStatesModels;
        var hoverScale;
        var cursorStyle;

        if (seriesScope) {
          emphasisItemStyle = seriesScope.emphasisItemStyle;
          blurItemStyle = seriesScope.blurItemStyle;
          selectItemStyle = seriesScope.selectItemStyle;
          focus = seriesScope.focus;
          blurScope = seriesScope.blurScope;
          labelStatesModels = seriesScope.labelStatesModels;
          hoverScale = seriesScope.hoverScale;
          cursorStyle = seriesScope.cursorStyle;
          emphasisDisabled = seriesScope.emphasisDisabled;
        }

        if (!seriesScope || data.hasItemOption) {
          var itemModel = seriesScope && seriesScope.itemModel ? seriesScope.itemModel : data.getItemModel(idx);
          var emphasisModel = itemModel.getModel('emphasis');
          emphasisItemStyle = emphasisModel.getModel('itemStyle').getItemStyle();
          selectItemStyle = itemModel.getModel(['select', 'itemStyle']).getItemStyle();
          blurItemStyle = itemModel.getModel(['blur', 'itemStyle']).getItemStyle();
          focus = emphasisModel.get('focus');
          blurScope = emphasisModel.get('blurScope');
          emphasisDisabled = emphasisModel.get('disabled');
          labelStatesModels = getLabelStatesModels(itemModel);
          hoverScale = emphasisModel.getShallow('scale');
          cursorStyle = itemModel.getShallow('cursor');
        }

        var symbolRotate = data.getItemVisual(idx, 'symbolRotate');
        symbolPath.attr('rotation', (symbolRotate || 0) * Math.PI / 180 || 0);
        var symbolOffset = normalizeSymbolOffset(data.getItemVisual(idx, 'symbolOffset'), symbolSize);

        if (symbolOffset) {
          symbolPath.x = symbolOffset[0];
          symbolPath.y = symbolOffset[1];
        }

        cursorStyle && symbolPath.attr('cursor', cursorStyle);
        var symbolStyle = data.getItemVisual(idx, 'style');
        var visualColor = symbolStyle.fill;

        if (symbolPath instanceof ZRImage) {
          var pathStyle = symbolPath.style;
          symbolPath.useStyle(extend({
            // TODO other properties like x, y ?
            image: pathStyle.image,
            x: pathStyle.x,
            y: pathStyle.y,
            width: pathStyle.width,
            height: pathStyle.height
          }, symbolStyle));
        } else {
          if (symbolPath.__isEmptyBrush) {
            // fill and stroke will be swapped if it's empty.
            // So we cloned a new style to avoid it affecting the original style in visual storage.
            // TODO Better implementation. No empty logic!
            symbolPath.useStyle(extend({}, symbolStyle));
          } else {
            symbolPath.useStyle(symbolStyle);
          } // Disable decal because symbol scale will been applied on the decal.


          symbolPath.style.decal = null;
          symbolPath.setColor(visualColor, opts && opts.symbolInnerColor);
          symbolPath.style.strokeNoScale = true;
        }

        var liftZ = data.getItemVisual(idx, 'liftZ');
        var z2Origin = this._z2;

        if (liftZ != null) {
          if (z2Origin == null) {
            this._z2 = symbolPath.z2;
            symbolPath.z2 += liftZ;
          }
        } else if (z2Origin != null) {
          symbolPath.z2 = z2Origin;
          this._z2 = null;
        }

        var useNameLabel = opts && opts.useNameLabel;
        setLabelStyle(symbolPath, labelStatesModels, {
          labelFetcher: seriesModel,
          labelDataIndex: idx,
          defaultText: getLabelDefaultText,
          inheritColor: visualColor,
          defaultOpacity: symbolStyle.opacity
        }); // Do not execute util needed.

        function getLabelDefaultText(idx) {
          return useNameLabel ? data.getName(idx) : getDefaultLabel(data, idx);
        }

        this._sizeX = symbolSize[0] / 2;
        this._sizeY = symbolSize[1] / 2;
        var emphasisState = symbolPath.ensureState('emphasis');
        emphasisState.style = emphasisItemStyle;
        symbolPath.ensureState('select').style = selectItemStyle;
        symbolPath.ensureState('blur').style = blurItemStyle; // null / undefined / true means to use default strategy.
        // 0 / false / negative number / NaN / Infinity means no scale.

        var scaleRatio = hoverScale == null || hoverScale === true ? Math.max(1.1, 3 / this._sizeY) // PENDING: restrict hoverScale > 1? It seems unreasonable to scale down
        : isFinite(hoverScale) && hoverScale > 0 ? +hoverScale : 1; // always set scale to allow resetting

        emphasisState.scaleX = this._sizeX * scaleRatio;
        emphasisState.scaleY = this._sizeY * scaleRatio;
        this.setSymbolScale(1);
        toggleHoverEmphasis(this, focus, blurScope, emphasisDisabled);
      };

      Symbol.prototype.setSymbolScale = function (scale) {
        this.scaleX = this.scaleY = scale;
      };

      Symbol.prototype.fadeOut = function (cb, seriesModel, opt) {
        var symbolPath = this.childAt(0);
        var dataIndex = getECData(this).dataIndex;
        var animationOpt = opt && opt.animation; // Avoid mistaken hover when fading out

        this.silent = symbolPath.silent = true; // Not show text when animating

        if (opt && opt.fadeLabel) {
          var textContent = symbolPath.getTextContent();

          if (textContent) {
            removeElement(textContent, {
              style: {
                opacity: 0
              }
            }, seriesModel, {
              dataIndex: dataIndex,
              removeOpt: animationOpt,
              cb: function () {
                symbolPath.removeTextContent();
              }
            });
          }
        } else {
          symbolPath.removeTextContent();
        }

        removeElement(symbolPath, {
          style: {
            opacity: 0
          },
          scaleX: 0,
          scaleY: 0
        }, seriesModel, {
          dataIndex: dataIndex,
          cb: cb,
          removeOpt: animationOpt
        });
      };

      Symbol.getSymbolSize = function (data, idx) {
        return normalizeSymbolSize(data.getItemVisual(idx, 'symbolSize'));
      };

      return Symbol;
    }(Group);

    function driftSymbol(dx, dy) {
      this.parent.drift(dx, dy);
    }

    function symbolNeedsDraw(data, point, idx, opt) {
      return point && !isNaN(point[0]) && !isNaN(point[1]) && !(opt.isIgnore && opt.isIgnore(idx)) // We do not set clipShape on group, because it will cut part of
      // the symbol element shape. We use the same clip shape here as
      // the line clip.
      && !(opt.clipShape && !opt.clipShape.contain(point[0], point[1])) && data.getItemVisual(idx, 'symbol') !== 'none';
    }

    function normalizeUpdateOpt(opt) {
      if (opt != null && !isObject(opt)) {
        opt = {
          isIgnore: opt
        };
      }

      return opt || {};
    }

    function makeSeriesScope(data) {
      var seriesModel = data.hostModel;
      var emphasisModel = seriesModel.getModel('emphasis');
      return {
        emphasisItemStyle: emphasisModel.getModel('itemStyle').getItemStyle(),
        blurItemStyle: seriesModel.getModel(['blur', 'itemStyle']).getItemStyle(),
        selectItemStyle: seriesModel.getModel(['select', 'itemStyle']).getItemStyle(),
        focus: emphasisModel.get('focus'),
        blurScope: emphasisModel.get('blurScope'),
        emphasisDisabled: emphasisModel.get('disabled'),
        hoverScale: emphasisModel.get('scale'),
        labelStatesModels: getLabelStatesModels(seriesModel),
        cursorStyle: seriesModel.get('cursor')
      };
    }

    var SymbolDraw =
    /** @class */
    function () {
      function SymbolDraw(SymbolCtor) {
        this.group = new Group();
        this._SymbolCtor = SymbolCtor || Symbol;
      }
      /**
       * Update symbols draw by new data
       */


      SymbolDraw.prototype.updateData = function (data, opt) {
        // Remove progressive els.
        this._progressiveEls = null;
        opt = normalizeUpdateOpt(opt);
        var group = this.group;
        var seriesModel = data.hostModel;
        var oldData = this._data;
        var SymbolCtor = this._SymbolCtor;
        var disableAnimation = opt.disableAnimation;
        var seriesScope = makeSeriesScope(data);
        var symbolUpdateOpt = {
          disableAnimation: disableAnimation
        };

        var getSymbolPoint = opt.getSymbolPoint || function (idx) {
          return data.getItemLayout(idx);
        }; // There is no oldLineData only when first rendering or switching from
        // stream mode to normal mode, where previous elements should be removed.


        if (!oldData) {
          group.removeAll();
        }

        data.diff(oldData).add(function (newIdx) {
          var point = getSymbolPoint(newIdx);

          if (symbolNeedsDraw(data, point, newIdx, opt)) {
            var symbolEl = new SymbolCtor(data, newIdx, seriesScope, symbolUpdateOpt);
            symbolEl.setPosition(point);
            data.setItemGraphicEl(newIdx, symbolEl);
            group.add(symbolEl);
          }
        }).update(function (newIdx, oldIdx) {
          var symbolEl = oldData.getItemGraphicEl(oldIdx);
          var point = getSymbolPoint(newIdx);

          if (!symbolNeedsDraw(data, point, newIdx, opt)) {
            group.remove(symbolEl);
            return;
          }

          var newSymbolType = data.getItemVisual(newIdx, 'symbol') || 'circle';
          var oldSymbolType = symbolEl && symbolEl.getSymbolType && symbolEl.getSymbolType();

          if (!symbolEl // Create a new if symbol type changed.
          || oldSymbolType && oldSymbolType !== newSymbolType) {
            group.remove(symbolEl);
            symbolEl = new SymbolCtor(data, newIdx, seriesScope, symbolUpdateOpt);
            symbolEl.setPosition(point);
          } else {
            symbolEl.updateData(data, newIdx, seriesScope, symbolUpdateOpt);
            var target = {
              x: point[0],
              y: point[1]
            };
            disableAnimation ? symbolEl.attr(target) : updateProps(symbolEl, target, seriesModel);
          } // Add back


          group.add(symbolEl);
          data.setItemGraphicEl(newIdx, symbolEl);
        }).remove(function (oldIdx) {
          var el = oldData.getItemGraphicEl(oldIdx);
          el && el.fadeOut(function () {
            group.remove(el);
          }, seriesModel);
        }).execute();
        this._getSymbolPoint = getSymbolPoint;
        this._data = data;
      };

      SymbolDraw.prototype.updateLayout = function () {
        var _this = this;

        var data = this._data;

        if (data) {
          // Not use animation
          data.eachItemGraphicEl(function (el, idx) {
            var point = _this._getSymbolPoint(idx);

            el.setPosition(point);
            el.markRedraw();
          });
        }
      };

      SymbolDraw.prototype.incrementalPrepareUpdate = function (data) {
        this._seriesScope = makeSeriesScope(data);
        this._data = null;
        this.group.removeAll();
      };
      /**
       * Update symbols draw by new data
       */

      SymbolDraw.prototype.incrementalUpdate = function (taskParams, data, opt) {
        // Clear
        this._progressiveEls = [];
        opt = normalizeUpdateOpt(opt);

        function updateIncrementalAndHover(el) {
          if (!el.isGroup) {
            el.incremental = true;
            el.ensureState('emphasis').hoverLayer = true;
          }
        }

        for (var idx = taskParams.start; idx < taskParams.end; idx++) {
          var point = data.getItemLayout(idx);

          if (symbolNeedsDraw(data, point, idx, opt)) {
            var el = new this._SymbolCtor(data, idx, this._seriesScope);
            el.traverse(updateIncrementalAndHover);
            el.setPosition(point);
            this.group.add(el);
            data.setItemGraphicEl(idx, el);

            this._progressiveEls.push(el);
          }
        }
      };

      SymbolDraw.prototype.eachRendered = function (cb) {
        traverseElements(this._progressiveEls || this.group, cb);
      };

      SymbolDraw.prototype.remove = function (enableAnimation) {
        var group = this.group;
        var data = this._data; // Incremental model do not have this._data.

        if (data && enableAnimation) {
          data.eachItemGraphicEl(function (el) {
            el.fadeOut(function () {
              group.remove(el);
            }, data.hostModel);
          });
        } else {
          group.removeAll();
        }
      };
      return SymbolDraw;
    }();

    function prepareDataCoordInfo(coordSys, data, valueOrigin) {
      var baseAxis = coordSys.getBaseAxis();
      var valueAxis = coordSys.getOtherAxis(baseAxis);
      var valueStart = getValueStart(valueAxis, valueOrigin);
      var baseAxisDim = baseAxis.dim;
      var valueAxisDim = valueAxis.dim;
      var valueDim = data.mapDimension(valueAxisDim);
      var baseDim = data.mapDimension(baseAxisDim);
      var baseDataOffset = valueAxisDim === 'x' || valueAxisDim === 'radius' ? 1 : 0;
      var dims = map(coordSys.dimensions, function (coordDim) {
        return data.mapDimension(coordDim);
      });
      var stacked = false;
      var stackResultDim = data.getCalculationInfo('stackResultDimension');

      if (isDimensionStacked(data, dims[0]
      /* , dims[1] */
      )) {
        // jshint ignore:line
        stacked = true;
        dims[0] = stackResultDim;
      }

      if (isDimensionStacked(data, dims[1]
      /* , dims[0] */
      )) {
        // jshint ignore:line
        stacked = true;
        dims[1] = stackResultDim;
      }

      return {
        dataDimsForPoint: dims,
        valueStart: valueStart,
        valueAxisDim: valueAxisDim,
        baseAxisDim: baseAxisDim,
        stacked: !!stacked,
        valueDim: valueDim,
        baseDim: baseDim,
        baseDataOffset: baseDataOffset,
        stackedOverDimension: data.getCalculationInfo('stackedOverDimension')
      };
    }

    function getValueStart(valueAxis, valueOrigin) {
      var valueStart = 0;
      var extent = valueAxis.scale.getExtent();

      if (valueOrigin === 'start') {
        valueStart = extent[0];
      } else if (valueOrigin === 'end') {
        valueStart = extent[1];
      } // If origin is specified as a number, use it as
      // valueStart directly
      else if (isNumber(valueOrigin) && !isNaN(valueOrigin)) {
          valueStart = valueOrigin;
        } // auto
        else {
            // Both positive
            if (extent[0] > 0) {
              valueStart = extent[0];
            } // Both negative
            else if (extent[1] < 0) {
                valueStart = extent[1];
              } // If is one positive, and one negative, onZero shall be true

          }

      return valueStart;
    }

    function getStackedOnPoint(dataCoordInfo, coordSys, data, idx) {
      var value = NaN;

      if (dataCoordInfo.stacked) {
        value = data.get(data.getCalculationInfo('stackedOverDimension'), idx);
      }

      if (isNaN(value)) {
        value = dataCoordInfo.valueStart;
      }

      var baseDataOffset = dataCoordInfo.baseDataOffset;
      var stackedData = [];
      stackedData[baseDataOffset] = data.get(dataCoordInfo.baseDim, idx);
      stackedData[1 - baseDataOffset] = value;
      return coordSys.dataToPoint(stackedData);
    }

    function diffData(oldData, newData) {
      var diffResult = [];
      newData.diff(oldData).add(function (idx) {
        diffResult.push({
          cmd: '+',
          idx: idx
        });
      }).update(function (newIdx, oldIdx) {
        diffResult.push({
          cmd: '=',
          idx: oldIdx,
          idx1: newIdx
        });
      }).remove(function (idx) {
        diffResult.push({
          cmd: '-',
          idx: idx
        });
      }).execute();
      return diffResult;
    }

    function lineAnimationDiff(oldData, newData, oldStackedOnPoints, newStackedOnPoints, oldCoordSys, newCoordSys, oldValueOrigin, newValueOrigin) {
      var diff = diffData(oldData, newData); // let newIdList = newData.mapArray(newData.getId);
      // let oldIdList = oldData.mapArray(oldData.getId);
      // convertToIntId(newIdList, oldIdList);
      // // FIXME One data ?
      // diff = arrayDiff(oldIdList, newIdList);

      var currPoints = [];
      var nextPoints = []; // Points for stacking base line

      var currStackedPoints = [];
      var nextStackedPoints = [];
      var status = [];
      var sortedIndices = [];
      var rawIndices = [];
      var newDataOldCoordInfo = prepareDataCoordInfo(oldCoordSys, newData, oldValueOrigin); // const oldDataNewCoordInfo = prepareDataCoordInfo(newCoordSys, oldData, newValueOrigin);

      var oldPoints = oldData.getLayout('points') || [];
      var newPoints = newData.getLayout('points') || [];

      for (var i = 0; i < diff.length; i++) {
        var diffItem = diff[i];
        var pointAdded = true;
        var oldIdx2 = void 0;
        var newIdx2 = void 0; // FIXME, animation is not so perfect when dataZoom window moves fast
        // Which is in case remvoing or add more than one data in the tail or head

        switch (diffItem.cmd) {
          case '=':
            oldIdx2 = diffItem.idx * 2;
            newIdx2 = diffItem.idx1 * 2;
            var currentX = oldPoints[oldIdx2];
            var currentY = oldPoints[oldIdx2 + 1];
            var nextX = newPoints[newIdx2];
            var nextY = newPoints[newIdx2 + 1]; // If previous data is NaN, use next point directly

            if (isNaN(currentX) || isNaN(currentY)) {
              currentX = nextX;
              currentY = nextY;
            }

            currPoints.push(currentX, currentY);
            nextPoints.push(nextX, nextY);
            currStackedPoints.push(oldStackedOnPoints[oldIdx2], oldStackedOnPoints[oldIdx2 + 1]);
            nextStackedPoints.push(newStackedOnPoints[newIdx2], newStackedOnPoints[newIdx2 + 1]);
            rawIndices.push(newData.getRawIndex(diffItem.idx1));
            break;

          case '+':
            var newIdx = diffItem.idx;
            var newDataDimsForPoint = newDataOldCoordInfo.dataDimsForPoint;
            var oldPt = oldCoordSys.dataToPoint([newData.get(newDataDimsForPoint[0], newIdx), newData.get(newDataDimsForPoint[1], newIdx)]);
            newIdx2 = newIdx * 2;
            currPoints.push(oldPt[0], oldPt[1]);
            nextPoints.push(newPoints[newIdx2], newPoints[newIdx2 + 1]);
            var stackedOnPoint = getStackedOnPoint(newDataOldCoordInfo, oldCoordSys, newData, newIdx);
            currStackedPoints.push(stackedOnPoint[0], stackedOnPoint[1]);
            nextStackedPoints.push(newStackedOnPoints[newIdx2], newStackedOnPoints[newIdx2 + 1]);
            rawIndices.push(newData.getRawIndex(newIdx));
            break;

          case '-':
            pointAdded = false;
        } // Original indices


        if (pointAdded) {
          status.push(diffItem);
          sortedIndices.push(sortedIndices.length);
        }
      } // Diff result may be crossed if all items are changed
      // Sort by data index


      sortedIndices.sort(function (a, b) {
        return rawIndices[a] - rawIndices[b];
      });
      var len = currPoints.length;
      var sortedCurrPoints = createFloat32Array(len);
      var sortedNextPoints = createFloat32Array(len);
      var sortedCurrStackedPoints = createFloat32Array(len);
      var sortedNextStackedPoints = createFloat32Array(len);
      var sortedStatus = [];

      for (var i = 0; i < sortedIndices.length; i++) {
        var idx = sortedIndices[i];
        var i2 = i * 2;
        var idx2 = idx * 2;
        sortedCurrPoints[i2] = currPoints[idx2];
        sortedCurrPoints[i2 + 1] = currPoints[idx2 + 1];
        sortedNextPoints[i2] = nextPoints[idx2];
        sortedNextPoints[i2 + 1] = nextPoints[idx2 + 1];
        sortedCurrStackedPoints[i2] = currStackedPoints[idx2];
        sortedCurrStackedPoints[i2 + 1] = currStackedPoints[idx2 + 1];
        sortedNextStackedPoints[i2] = nextStackedPoints[idx2];
        sortedNextStackedPoints[i2 + 1] = nextStackedPoints[idx2 + 1];
        sortedStatus[i] = status[idx];
      }

      return {
        current: sortedCurrPoints,
        next: sortedNextPoints,
        stackedOnCurrent: sortedCurrStackedPoints,
        stackedOnNext: sortedNextStackedPoints,
        status: sortedStatus
      };
    }

    var mathMin$5 = Math.min;
    var mathMax$5 = Math.max;

    function isPointNull(x, y) {
      return isNaN(x) || isNaN(y);
    }
    /**
     * Draw smoothed line in non-monotone, in may cause undesired curve in extreme
     * situations. This should be used when points are non-monotone neither in x or
     * y dimension.
     */


    function drawSegment(ctx, points, start, segLen, allLen, dir, smooth, smoothMonotone, connectNulls) {
      var prevX;
      var prevY;
      var cpx0;
      var cpy0;
      var cpx1;
      var cpy1;
      var idx = start;
      var k = 0;

      for (; k < segLen; k++) {
        var x = points[idx * 2];
        var y = points[idx * 2 + 1];

        if (idx >= allLen || idx < 0) {
          break;
        }

        if (isPointNull(x, y)) {
          if (connectNulls) {
            idx += dir;
            continue;
          }

          break;
        }

        if (idx === start) {
          ctx[dir > 0 ? 'moveTo' : 'lineTo'](x, y);
          cpx0 = x;
          cpy0 = y;
        } else {
          var dx = x - prevX;
          var dy = y - prevY; // Ignore tiny segment.

          if (dx * dx + dy * dy < 0.5) {
            idx += dir;
            continue;
          }

          if (smooth > 0) {
            var nextIdx = idx + dir;
            var nextX = points[nextIdx * 2];
            var nextY = points[nextIdx * 2 + 1]; // Ignore duplicate point

            while (nextX === x && nextY === y && k < segLen) {
              k++;
              nextIdx += dir;
              idx += dir;
              nextX = points[nextIdx * 2];
              nextY = points[nextIdx * 2 + 1];
              x = points[idx * 2];
              y = points[idx * 2 + 1];
              dx = x - prevX;
              dy = y - prevY;
            }

            var tmpK = k + 1;

            if (connectNulls) {
              // Find next point not null
              while (isPointNull(nextX, nextY) && tmpK < segLen) {
                tmpK++;
                nextIdx += dir;
                nextX = points[nextIdx * 2];
                nextY = points[nextIdx * 2 + 1];
              }
            }

            var ratioNextSeg = 0.5;
            var vx = 0;
            var vy = 0;
            var nextCpx0 = void 0;
            var nextCpy0 = void 0; // Is last point

            if (tmpK >= segLen || isPointNull(nextX, nextY)) {
              cpx1 = x;
              cpy1 = y;
            } else {
              vx = nextX - prevX;
              vy = nextY - prevY;
              var dx0 = x - prevX;
              var dx1 = nextX - x;
              var dy0 = y - prevY;
              var dy1 = nextY - y;
              var lenPrevSeg = void 0;
              var lenNextSeg = void 0;

              if (smoothMonotone === 'x') {
                lenPrevSeg = Math.abs(dx0);
                lenNextSeg = Math.abs(dx1);
                var dir_1 = vx > 0 ? 1 : -1;
                cpx1 = x - dir_1 * lenPrevSeg * smooth;
                cpy1 = y;
                nextCpx0 = x + dir_1 * lenNextSeg * smooth;
                nextCpy0 = y;
              } else if (smoothMonotone === 'y') {
                lenPrevSeg = Math.abs(dy0);
                lenNextSeg = Math.abs(dy1);
                var dir_2 = vy > 0 ? 1 : -1;
                cpx1 = x;
                cpy1 = y - dir_2 * lenPrevSeg * smooth;
                nextCpx0 = x;
                nextCpy0 = y + dir_2 * lenNextSeg * smooth;
              } else {
                lenPrevSeg = Math.sqrt(dx0 * dx0 + dy0 * dy0);
                lenNextSeg = Math.sqrt(dx1 * dx1 + dy1 * dy1); // Use ratio of seg length

                ratioNextSeg = lenNextSeg / (lenNextSeg + lenPrevSeg);
                cpx1 = x - vx * smooth * (1 - ratioNextSeg);
                cpy1 = y - vy * smooth * (1 - ratioNextSeg); // cp0 of next segment

                nextCpx0 = x + vx * smooth * ratioNextSeg;
                nextCpy0 = y + vy * smooth * ratioNextSeg; // Smooth constraint between point and next point.
                // Avoid exceeding extreme after smoothing.

                nextCpx0 = mathMin$5(nextCpx0, mathMax$5(nextX, x));
                nextCpy0 = mathMin$5(nextCpy0, mathMax$5(nextY, y));
                nextCpx0 = mathMax$5(nextCpx0, mathMin$5(nextX, x));
                nextCpy0 = mathMax$5(nextCpy0, mathMin$5(nextY, y)); // Reclaculate cp1 based on the adjusted cp0 of next seg.

                vx = nextCpx0 - x;
                vy = nextCpy0 - y;
                cpx1 = x - vx * lenPrevSeg / lenNextSeg;
                cpy1 = y - vy * lenPrevSeg / lenNextSeg; // Smooth constraint between point and prev point.
                // Avoid exceeding extreme after smoothing.

                cpx1 = mathMin$5(cpx1, mathMax$5(prevX, x));
                cpy1 = mathMin$5(cpy1, mathMax$5(prevY, y));
                cpx1 = mathMax$5(cpx1, mathMin$5(prevX, x));
                cpy1 = mathMax$5(cpy1, mathMin$5(prevY, y)); // Adjust next cp0 again.

                vx = x - cpx1;
                vy = y - cpy1;
                nextCpx0 = x + vx * lenNextSeg / lenPrevSeg;
                nextCpy0 = y + vy * lenNextSeg / lenPrevSeg;
              }
            }

            ctx.bezierCurveTo(cpx0, cpy0, cpx1, cpy1, x, y);
            cpx0 = nextCpx0;
            cpy0 = nextCpy0;
          } else {
            ctx.lineTo(x, y);
          }
        }

        prevX = x;
        prevY = y;
        idx += dir;
      }

      return k;
    }

    var ECPolylineShape =
    /** @class */
    function () {
      function ECPolylineShape() {
        this.smooth = 0;
        this.smoothConstraint = true;
      }

      return ECPolylineShape;
    }();

    var ECPolyline =
    /** @class */
    function (_super) {
      __extends(ECPolyline, _super);

      function ECPolyline(opts) {
        var _this = _super.call(this, opts) || this;

        _this.type = 'ec-polyline';
        return _this;
      }

      ECPolyline.prototype.getDefaultStyle = function () {
        return {
          stroke: '#000',
          fill: null
        };
      };

      ECPolyline.prototype.getDefaultShape = function () {
        return new ECPolylineShape();
      };

      ECPolyline.prototype.buildPath = function (ctx, shape) {
        var points = shape.points;
        var i = 0;
        var len = points.length / 2; // const result = getBoundingBox(points, shape.smoothConstraint);

        if (shape.connectNulls) {
          // Must remove first and last null values avoid draw error in polygon
          for (; len > 0; len--) {
            if (!isPointNull(points[len * 2 - 2], points[len * 2 - 1])) {
              break;
            }
          }

          for (; i < len; i++) {
            if (!isPointNull(points[i * 2], points[i * 2 + 1])) {
              break;
            }
          }
        }

        while (i < len) {
          i += drawSegment(ctx, points, i, len, len, 1, shape.smooth, shape.smoothMonotone, shape.connectNulls) + 1;
        }
      };

      ECPolyline.prototype.getPointOn = function (xOrY, dim) {
        if (!this.path) {
          this.createPathProxy();
          this.buildPath(this.path, this.shape);
        }

        var path = this.path;
        var data = path.data;
        var CMD = PathProxy.CMD;
        var x0;
        var y0;
        var isDimX = dim === 'x';
        var roots = [];

        for (var i = 0; i < data.length;) {
          var cmd = data[i++];
          var x = void 0;
          var y = void 0;
          var x2 = void 0;
          var y2 = void 0;
          var x3 = void 0;
          var y3 = void 0;
          var t = void 0;

          switch (cmd) {
            case CMD.M:
              x0 = data[i++];
              y0 = data[i++];
              break;

            case CMD.L:
              x = data[i++];
              y = data[i++];
              t = isDimX ? (xOrY - x0) / (x - x0) : (xOrY - y0) / (y - y0);

              if (t <= 1 && t >= 0) {
                var val = isDimX ? (y - y0) * t + y0 : (x - x0) * t + x0;
                return isDimX ? [xOrY, val] : [val, xOrY];
              }

              x0 = x;
              y0 = y;
              break;

            case CMD.C:
              x = data[i++];
              y = data[i++];
              x2 = data[i++];
              y2 = data[i++];
              x3 = data[i++];
              y3 = data[i++];
              var nRoot = isDimX ? cubicRootAt(x0, x, x2, x3, xOrY, roots) : cubicRootAt(y0, y, y2, y3, xOrY, roots);

              if (nRoot > 0) {
                for (var i_1 = 0; i_1 < nRoot; i_1++) {
                  var t_1 = roots[i_1];

                  if (t_1 <= 1 && t_1 >= 0) {
                    var val = isDimX ? cubicAt(y0, y, y2, y3, t_1) : cubicAt(x0, x, x2, x3, t_1);
                    return isDimX ? [xOrY, val] : [val, xOrY];
                  }
                }
              }

              x0 = x3;
              y0 = y3;
              break;
          }
        }
      };

      return ECPolyline;
    }(Path);

    var ECPolygonShape =
    /** @class */
    function (_super) {
      __extends(ECPolygonShape, _super);

      function ECPolygonShape() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      return ECPolygonShape;
    }(ECPolylineShape);

    var ECPolygon =
    /** @class */
    function (_super) {
      __extends(ECPolygon, _super);

      function ECPolygon(opts) {
        var _this = _super.call(this, opts) || this;

        _this.type = 'ec-polygon';
        return _this;
      }

      ECPolygon.prototype.getDefaultShape = function () {
        return new ECPolygonShape();
      };

      ECPolygon.prototype.buildPath = function (ctx, shape) {
        var points = shape.points;
        var stackedOnPoints = shape.stackedOnPoints;
        var i = 0;
        var len = points.length / 2;
        var smoothMonotone = shape.smoothMonotone;

        if (shape.connectNulls) {
          // Must remove first and last null values avoid draw error in polygon
          for (; len > 0; len--) {
            if (!isPointNull(points[len * 2 - 2], points[len * 2 - 1])) {
              break;
            }
          }

          for (; i < len; i++) {
            if (!isPointNull(points[i * 2], points[i * 2 + 1])) {
              break;
            }
          }
        }

        while (i < len) {
          var k = drawSegment(ctx, points, i, len, len, 1, shape.smooth, smoothMonotone, shape.connectNulls);
          drawSegment(ctx, stackedOnPoints, i + k - 1, k, len, -1, shape.stackedOnSmooth, smoothMonotone, shape.connectNulls);
          i += k + 1;
          ctx.closePath();
        }
      };

      return ECPolygon;
    }(Path);

    function createGridClipPath(cartesian, hasAnimation, seriesModel, done, during) {
      var rect = cartesian.getArea();
      var x = rect.x;
      var y = rect.y;
      var width = rect.width;
      var height = rect.height;
      var lineWidth = seriesModel.get(['lineStyle', 'width']) || 2; // Expand the clip path a bit to avoid the border is clipped and looks thinner

      x -= lineWidth / 2;
      y -= lineWidth / 2;
      width += lineWidth;
      height += lineWidth; // fix: https://github.com/apache/incubator-echarts/issues/11369

      x = Math.floor(x);
      width = Math.round(width);
      var clipPath = new Rect({
        shape: {
          x: x,
          y: y,
          width: width,
          height: height
        }
      });

      if (hasAnimation) {
        var baseAxis = cartesian.getBaseAxis();
        var isHorizontal = baseAxis.isHorizontal();
        var isAxisInversed = baseAxis.inverse;

        if (isHorizontal) {
          if (isAxisInversed) {
            clipPath.shape.x += width;
          }

          clipPath.shape.width = 0;
        } else {
          if (!isAxisInversed) {
            clipPath.shape.y += height;
          }

          clipPath.shape.height = 0;
        }

        var duringCb = isFunction(during) ? function (percent) {
          during(percent, clipPath);
        } : null;
        initProps(clipPath, {
          shape: {
            width: width,
            height: height,
            x: x,
            y: y
          }
        }, seriesModel, null, done, duringCb);
      }

      return clipPath;
    }

    function createPolarClipPath(polar, hasAnimation, seriesModel) {
      var sectorArea = polar.getArea(); // Avoid float number rounding error for symbol on the edge of axis extent.

      var r0 = round(sectorArea.r0, 1);
      var r = round(sectorArea.r, 1);
      var clipPath = new Sector({
        shape: {
          cx: round(polar.cx, 1),
          cy: round(polar.cy, 1),
          r0: r0,
          r: r,
          startAngle: sectorArea.startAngle,
          endAngle: sectorArea.endAngle,
          clockwise: sectorArea.clockwise
        }
      });

      if (hasAnimation) {
        var isRadial = polar.getBaseAxis().dim === 'angle';

        if (isRadial) {
          clipPath.shape.endAngle = sectorArea.startAngle;
        } else {
          clipPath.shape.r = r0;
        }

        initProps(clipPath, {
          shape: {
            endAngle: sectorArea.endAngle,
            r: r
          }
        }, seriesModel);
      }

      return clipPath;
    }

    function createClipPath(coordSys, hasAnimation, seriesModel, done, during) {
      if (!coordSys) {
        return null;
      } else if (coordSys.type === 'polar') {
        return createPolarClipPath(coordSys, hasAnimation, seriesModel);
      } else if (coordSys.type === 'cartesian2d') {
        return createGridClipPath(coordSys, hasAnimation, seriesModel, done, during);
      }

      return null;
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    function isCoordinateSystemType(coordSys, type) {
      return coordSys.type === type;
    }

    function isPointsSame(points1, points2) {
      if (points1.length !== points2.length) {
        return;
      }

      for (var i = 0; i < points1.length; i++) {
        if (points1[i] !== points2[i]) {
          return;
        }
      }

      return true;
    }

    function bboxFromPoints(points) {
      var minX = Infinity;
      var minY = Infinity;
      var maxX = -Infinity;
      var maxY = -Infinity;

      for (var i = 0; i < points.length;) {
        var x = points[i++];
        var y = points[i++];

        if (!isNaN(x)) {
          minX = Math.min(x, minX);
          maxX = Math.max(x, maxX);
        }

        if (!isNaN(y)) {
          minY = Math.min(y, minY);
          maxY = Math.max(y, maxY);
        }
      }

      return [[minX, minY], [maxX, maxY]];
    }

    function getBoundingDiff(points1, points2) {
      var _a = bboxFromPoints(points1),
          min1 = _a[0],
          max1 = _a[1];

      var _b = bboxFromPoints(points2),
          min2 = _b[0],
          max2 = _b[1]; // Get a max value from each corner of two boundings.


      return Math.max(Math.abs(min1[0] - min2[0]), Math.abs(min1[1] - min2[1]), Math.abs(max1[0] - max2[0]), Math.abs(max1[1] - max2[1]));
    }

    function getSmooth(smooth) {
      return isNumber(smooth) ? smooth : smooth ? 0.5 : 0;
    }

    function getStackedOnPoints(coordSys, data, dataCoordInfo) {
      if (!dataCoordInfo.valueDim) {
        return [];
      }

      var len = data.count();
      var points = createFloat32Array(len * 2);

      for (var idx = 0; idx < len; idx++) {
        var pt = getStackedOnPoint(dataCoordInfo, coordSys, data, idx);
        points[idx * 2] = pt[0];
        points[idx * 2 + 1] = pt[1];
      }

      return points;
    }

    function turnPointsIntoStep(points, coordSys, stepTurnAt, connectNulls) {
      var baseAxis = coordSys.getBaseAxis();
      var baseIndex = baseAxis.dim === 'x' || baseAxis.dim === 'radius' ? 0 : 1;
      var stepPoints = [];
      var i = 0;
      var stepPt = [];
      var pt = [];
      var nextPt = [];
      var filteredPoints = [];

      if (connectNulls) {
        for (i = 0; i < points.length; i += 2) {
          if (!isNaN(points[i]) && !isNaN(points[i + 1])) {
            filteredPoints.push(points[i], points[i + 1]);
          }
        }

        points = filteredPoints;
      }

      for (i = 0; i < points.length - 2; i += 2) {
        nextPt[0] = points[i + 2];
        nextPt[1] = points[i + 3];
        pt[0] = points[i];
        pt[1] = points[i + 1];
        stepPoints.push(pt[0], pt[1]);

        switch (stepTurnAt) {
          case 'end':
            stepPt[baseIndex] = nextPt[baseIndex];
            stepPt[1 - baseIndex] = pt[1 - baseIndex];
            stepPoints.push(stepPt[0], stepPt[1]);
            break;

          case 'middle':
            var middle = (pt[baseIndex] + nextPt[baseIndex]) / 2;
            var stepPt2 = [];
            stepPt[baseIndex] = stepPt2[baseIndex] = middle;
            stepPt[1 - baseIndex] = pt[1 - baseIndex];
            stepPt2[1 - baseIndex] = nextPt[1 - baseIndex];
            stepPoints.push(stepPt[0], stepPt[1]);
            stepPoints.push(stepPt2[0], stepPt2[1]);
            break;

          default:
            // default is start
            stepPt[baseIndex] = pt[baseIndex];
            stepPt[1 - baseIndex] = nextPt[1 - baseIndex];
            stepPoints.push(stepPt[0], stepPt[1]);
        }
      } // Last points


      stepPoints.push(points[i++], points[i++]);
      return stepPoints;
    }
    /**
     * Clip color stops to edge. Avoid creating too large gradients.
     * Which may lead to blurry when GPU acceleration is enabled. See #15680
     *
     * The stops has been sorted from small to large.
     */


    function clipColorStops(colorStops, maxSize) {
      var newColorStops = [];
      var len = colorStops.length; // coord will always < 0 in prevOutOfRangeColorStop.

      var prevOutOfRangeColorStop;
      var prevInRangeColorStop;

      function lerpStop(stop0, stop1, clippedCoord) {
        var coord0 = stop0.coord;
        var p = (clippedCoord - coord0) / (stop1.coord - coord0);
        var color = lerp$1(p, [stop0.color, stop1.color]);
        return {
          coord: clippedCoord,
          color: color
        };
      }

      for (var i = 0; i < len; i++) {
        var stop_1 = colorStops[i];
        var coord = stop_1.coord;

        if (coord < 0) {
          prevOutOfRangeColorStop = stop_1;
        } else if (coord > maxSize) {
          if (prevInRangeColorStop) {
            newColorStops.push(lerpStop(prevInRangeColorStop, stop_1, maxSize));
          } else if (prevOutOfRangeColorStop) {
            // If there are two stops and coord range is between these two stops
            newColorStops.push(lerpStop(prevOutOfRangeColorStop, stop_1, 0), lerpStop(prevOutOfRangeColorStop, stop_1, maxSize));
          } // All following stop will be out of range. So just ignore them.


          break;
        } else {
          if (prevOutOfRangeColorStop) {
            newColorStops.push(lerpStop(prevOutOfRangeColorStop, stop_1, 0)); // Reset

            prevOutOfRangeColorStop = null;
          }

          newColorStops.push(stop_1);
          prevInRangeColorStop = stop_1;
        }
      }

      return newColorStops;
    }

    function getVisualGradient(data, coordSys, api) {
      var visualMetaList = data.getVisual('visualMeta');

      if (!visualMetaList || !visualMetaList.length || !data.count()) {
        // When data.count() is 0, gradient range can not be calculated.
        return;
      }

      if (coordSys.type !== 'cartesian2d') {
        if ("development" !== 'production') {
          console.warn('Visual map on line style is only supported on cartesian2d.');
        }

        return;
      }

      var coordDim;
      var visualMeta;

      for (var i = visualMetaList.length - 1; i >= 0; i--) {
        var dimInfo = data.getDimensionInfo(visualMetaList[i].dimension);
        coordDim = dimInfo && dimInfo.coordDim; // Can only be x or y

        if (coordDim === 'x' || coordDim === 'y') {
          visualMeta = visualMetaList[i];
          break;
        }
      }

      if (!visualMeta) {
        if ("development" !== 'production') {
          console.warn('Visual map on line style only support x or y dimension.');
        }

        return;
      } // If the area to be rendered is bigger than area defined by LinearGradient,
      // the canvas spec prescribes that the color of the first stop and the last
      // stop should be used. But if two stops are added at offset 0, in effect
      // browsers use the color of the second stop to render area outside
      // LinearGradient. So we can only infinitesimally extend area defined in
      // LinearGradient to render `outerColors`.


      var axis = coordSys.getAxis(coordDim); // dataToCoord mapping may not be linear, but must be monotonic.

      var colorStops = map(visualMeta.stops, function (stop) {
        // offset will be calculated later.
        return {
          coord: axis.toGlobalCoord(axis.dataToCoord(stop.value)),
          color: stop.color
        };
      });
      var stopLen = colorStops.length;
      var outerColors = visualMeta.outerColors.slice();

      if (stopLen && colorStops[0].coord > colorStops[stopLen - 1].coord) {
        colorStops.reverse();
        outerColors.reverse();
      }

      var colorStopsInRange = clipColorStops(colorStops, coordDim === 'x' ? api.getWidth() : api.getHeight());
      var inRangeStopLen = colorStopsInRange.length;

      if (!inRangeStopLen && stopLen) {
        // All stops are out of range. All will be the same color.
        return colorStops[0].coord < 0 ? outerColors[1] ? outerColors[1] : colorStops[stopLen - 1].color : outerColors[0] ? outerColors[0] : colorStops[0].color;
      }

      var tinyExtent = 10; // Arbitrary value: 10px

      var minCoord = colorStopsInRange[0].coord - tinyExtent;
      var maxCoord = colorStopsInRange[inRangeStopLen - 1].coord + tinyExtent;
      var coordSpan = maxCoord - minCoord;

      if (coordSpan < 1e-3) {
        return 'transparent';
      }

      each(colorStopsInRange, function (stop) {
        stop.offset = (stop.coord - minCoord) / coordSpan;
      });
      colorStopsInRange.push({
        // NOTE: inRangeStopLen may still be 0 if stoplen is zero.
        offset: inRangeStopLen ? colorStopsInRange[inRangeStopLen - 1].offset : 0.5,
        color: outerColors[1] || 'transparent'
      });
      colorStopsInRange.unshift({
        offset: inRangeStopLen ? colorStopsInRange[0].offset : 0.5,
        color: outerColors[0] || 'transparent'
      });
      var gradient = new LinearGradient(0, 0, 0, 0, colorStopsInRange, true);
      gradient[coordDim] = minCoord;
      gradient[coordDim + '2'] = maxCoord;
      return gradient;
    }

    function getIsIgnoreFunc(seriesModel, data, coordSys) {
      var showAllSymbol = seriesModel.get('showAllSymbol');
      var isAuto = showAllSymbol === 'auto';

      if (showAllSymbol && !isAuto) {
        return;
      }

      var categoryAxis = coordSys.getAxesByScale('ordinal')[0];

      if (!categoryAxis) {
        return;
      } // Note that category label interval strategy might bring some weird effect
      // in some scenario: users may wonder why some of the symbols are not
      // displayed. So we show all symbols as possible as we can.


      if (isAuto // Simplify the logic, do not determine label overlap here.
      && canShowAllSymbolForCategory(categoryAxis, data)) {
        return;
      } // Otherwise follow the label interval strategy on category axis.


      var categoryDataDim = data.mapDimension(categoryAxis.dim);
      var labelMap = {};
      each(categoryAxis.getViewLabels(), function (labelItem) {
        var ordinalNumber = categoryAxis.scale.getRawOrdinalNumber(labelItem.tickValue);
        labelMap[ordinalNumber] = 1;
      });
      return function (dataIndex) {
        return !labelMap.hasOwnProperty(data.get(categoryDataDim, dataIndex));
      };
    }

    function canShowAllSymbolForCategory(categoryAxis, data) {
      // In most cases, line is monotonous on category axis, and the label size
      // is close with each other. So we check the symbol size and some of the
      // label size alone with the category axis to estimate whether all symbol
      // can be shown without overlap.
      var axisExtent = categoryAxis.getExtent();
      var availSize = Math.abs(axisExtent[1] - axisExtent[0]) / categoryAxis.scale.count();
      isNaN(availSize) && (availSize = 0); // 0/0 is NaN.
      // Sampling some points, max 5.

      var dataLen = data.count();
      var step = Math.max(1, Math.round(dataLen / 5));

      for (var dataIndex = 0; dataIndex < dataLen; dataIndex += step) {
        if (Symbol.getSymbolSize(data, dataIndex // Only for cartesian, where `isHorizontal` exists.
        )[categoryAxis.isHorizontal() ? 1 : 0] // Empirical number
        * 1.5 > availSize) {
          return false;
        }
      }

      return true;
    }

    function isPointNull$1(x, y) {
      return isNaN(x) || isNaN(y);
    }

    function getLastIndexNotNull(points) {
      var len = points.length / 2;

      for (; len > 0; len--) {
        if (!isPointNull$1(points[len * 2 - 2], points[len * 2 - 1])) {
          break;
        }
      }

      return len - 1;
    }

    function getPointAtIndex(points, idx) {
      return [points[idx * 2], points[idx * 2 + 1]];
    }

    function getIndexRange(points, xOrY, dim) {
      var len = points.length / 2;
      var dimIdx = dim === 'x' ? 0 : 1;
      var a;
      var b;
      var prevIndex = 0;
      var nextIndex = -1;

      for (var i = 0; i < len; i++) {
        b = points[i * 2 + dimIdx];

        if (isNaN(b) || isNaN(points[i * 2 + 1 - dimIdx])) {
          continue;
        }

        if (i === 0) {
          a = b;
          continue;
        }

        if (a <= xOrY && b >= xOrY || a >= xOrY && b <= xOrY) {
          nextIndex = i;
          break;
        }

        prevIndex = i;
        a = b;
      }

      return {
        range: [prevIndex, nextIndex],
        t: (xOrY - a) / (b - a)
      };
    }

    function anyStateShowEndLabel(seriesModel) {
      if (seriesModel.get(['endLabel', 'show'])) {
        return true;
      }

      for (var i = 0; i < SPECIAL_STATES.length; i++) {
        if (seriesModel.get([SPECIAL_STATES[i], 'endLabel', 'show'])) {
          return true;
        }
      }

      return false;
    }

    function createLineClipPath(lineView, coordSys, hasAnimation, seriesModel) {
      if (isCoordinateSystemType(coordSys, 'cartesian2d')) {
        var endLabelModel_1 = seriesModel.getModel('endLabel');
        var valueAnimation_1 = endLabelModel_1.get('valueAnimation');
        var data_1 = seriesModel.getData();
        var labelAnimationRecord_1 = {
          lastFrameIndex: 0
        };
        var during = anyStateShowEndLabel(seriesModel) ? function (percent, clipRect) {
          lineView._endLabelOnDuring(percent, clipRect, data_1, labelAnimationRecord_1, valueAnimation_1, endLabelModel_1, coordSys);
        } : null;
        var isHorizontal = coordSys.getBaseAxis().isHorizontal();
        var clipPath = createGridClipPath(coordSys, hasAnimation, seriesModel, function () {
          var endLabel = lineView._endLabel;

          if (endLabel && hasAnimation) {
            if (labelAnimationRecord_1.originalX != null) {
              endLabel.attr({
                x: labelAnimationRecord_1.originalX,
                y: labelAnimationRecord_1.originalY
              });
            }
          }
        }, during); // Expand clip shape to avoid clipping when line value exceeds axis

        if (!seriesModel.get('clip', true)) {
          var rectShape = clipPath.shape;
          var expandSize = Math.max(rectShape.width, rectShape.height);

          if (isHorizontal) {
            rectShape.y -= expandSize;
            rectShape.height += expandSize * 2;
          } else {
            rectShape.x -= expandSize;
            rectShape.width += expandSize * 2;
          }
        } // Set to the final frame. To make sure label layout is right.


        if (during) {
          during(1, clipPath);
        }

        return clipPath;
      } else {
        if ("development" !== 'production') {
          if (seriesModel.get(['endLabel', 'show'])) {
            console.warn('endLabel is not supported for lines in polar systems.');
          }
        }

        return createPolarClipPath(coordSys, hasAnimation, seriesModel);
      }
    }

    function getEndLabelStateSpecified(endLabelModel, coordSys) {
      var baseAxis = coordSys.getBaseAxis();
      var isHorizontal = baseAxis.isHorizontal();
      var isBaseInversed = baseAxis.inverse;
      var align = isHorizontal ? isBaseInversed ? 'right' : 'left' : 'center';
      var verticalAlign = isHorizontal ? 'middle' : isBaseInversed ? 'top' : 'bottom';
      return {
        normal: {
          align: endLabelModel.get('align') || align,
          verticalAlign: endLabelModel.get('verticalAlign') || verticalAlign
        }
      };
    }

    var LineView =
    /** @class */
    function (_super) {
      __extends(LineView, _super);

      function LineView() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      LineView.prototype.init = function () {
        var lineGroup = new Group();
        var symbolDraw = new SymbolDraw();
        this.group.add(symbolDraw.group);
        this._symbolDraw = symbolDraw;
        this._lineGroup = lineGroup;
      };

      LineView.prototype.render = function (seriesModel, ecModel, api) {
        var _this = this;

        var coordSys = seriesModel.coordinateSystem;
        var group = this.group;
        var data = seriesModel.getData();
        var lineStyleModel = seriesModel.getModel('lineStyle');
        var areaStyleModel = seriesModel.getModel('areaStyle');
        var points = data.getLayout('points') || [];
        var isCoordSysPolar = coordSys.type === 'polar';
        var prevCoordSys = this._coordSys;
        var symbolDraw = this._symbolDraw;
        var polyline = this._polyline;
        var polygon = this._polygon;
        var lineGroup = this._lineGroup;
        var hasAnimation = seriesModel.get('animation');
        var isAreaChart = !areaStyleModel.isEmpty();
        var valueOrigin = areaStyleModel.get('origin');
        var dataCoordInfo = prepareDataCoordInfo(coordSys, data, valueOrigin);
        var stackedOnPoints = isAreaChart && getStackedOnPoints(coordSys, data, dataCoordInfo);
        var showSymbol = seriesModel.get('showSymbol');
        var connectNulls = seriesModel.get('connectNulls');
        var isIgnoreFunc = showSymbol && !isCoordSysPolar && getIsIgnoreFunc(seriesModel, data, coordSys); // Remove temporary symbols

        var oldData = this._data;
        oldData && oldData.eachItemGraphicEl(function (el, idx) {
          if (el.__temp) {
            group.remove(el);
            oldData.setItemGraphicEl(idx, null);
          }
        }); // Remove previous created symbols if showSymbol changed to false

        if (!showSymbol) {
          symbolDraw.remove();
        }

        group.add(lineGroup); // FIXME step not support polar

        var step = !isCoordSysPolar ? seriesModel.get('step') : false;
        var clipShapeForSymbol;

        if (coordSys && coordSys.getArea && seriesModel.get('clip', true)) {
          clipShapeForSymbol = coordSys.getArea(); // Avoid float number rounding error for symbol on the edge of axis extent.
          // See #7913 and `test/dataZoom-clip.html`.

          if (clipShapeForSymbol.width != null) {
            clipShapeForSymbol.x -= 0.1;
            clipShapeForSymbol.y -= 0.1;
            clipShapeForSymbol.width += 0.2;
            clipShapeForSymbol.height += 0.2;
          } else if (clipShapeForSymbol.r0) {
            clipShapeForSymbol.r0 -= 0.5;
            clipShapeForSymbol.r += 0.5;
          }
        }

        this._clipShapeForSymbol = clipShapeForSymbol;
        var visualColor = getVisualGradient(data, coordSys, api) || data.getVisual('style')[data.getVisual('drawType')]; // Initialization animation or coordinate system changed

        if (!(polyline && prevCoordSys.type === coordSys.type && step === this._step)) {
          showSymbol && symbolDraw.updateData(data, {
            isIgnore: isIgnoreFunc,
            clipShape: clipShapeForSymbol,
            disableAnimation: true,
            getSymbolPoint: function (idx) {
              return [points[idx * 2], points[idx * 2 + 1]];
            }
          });
          hasAnimation && this._initSymbolLabelAnimation(data, coordSys, clipShapeForSymbol);

          if (step) {
            // TODO If stacked series is not step
            points = turnPointsIntoStep(points, coordSys, step, connectNulls);

            if (stackedOnPoints) {
              stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step, connectNulls);
            }
          }

          polyline = this._newPolyline(points);

          if (isAreaChart) {
            polygon = this._newPolygon(points, stackedOnPoints);
          } // If areaStyle is removed
          else if (polygon) {
              lineGroup.remove(polygon);
              polygon = this._polygon = null;
            } // NOTE: Must update _endLabel before setClipPath.


          if (!isCoordSysPolar) {
            this._initOrUpdateEndLabel(seriesModel, coordSys, convertToColorString(visualColor));
          }

          lineGroup.setClipPath(createLineClipPath(this, coordSys, true, seriesModel));
        } else {
          if (isAreaChart && !polygon) {
            // If areaStyle is added
            polygon = this._newPolygon(points, stackedOnPoints);
          } else if (polygon && !isAreaChart) {
            // If areaStyle is removed
            lineGroup.remove(polygon);
            polygon = this._polygon = null;
          } // NOTE: Must update _endLabel before setClipPath.


          if (!isCoordSysPolar) {
            this._initOrUpdateEndLabel(seriesModel, coordSys, convertToColorString(visualColor));
          } // Update clipPath


          var oldClipPath = lineGroup.getClipPath();

          if (oldClipPath) {
            var newClipPath = createLineClipPath(this, coordSys, false, seriesModel);
            initProps(oldClipPath, {
              shape: newClipPath.shape
            }, seriesModel);
          } else {
            lineGroup.setClipPath(createLineClipPath(this, coordSys, true, seriesModel));
          } // Always update, or it is wrong in the case turning on legend
          // because points are not changed.


          showSymbol && symbolDraw.updateData(data, {
            isIgnore: isIgnoreFunc,
            clipShape: clipShapeForSymbol,
            disableAnimation: true,
            getSymbolPoint: function (idx) {
              return [points[idx * 2], points[idx * 2 + 1]];
            }
          }); // In the case data zoom triggered refreshing frequently
          // Data may not change if line has a category axis. So it should animate nothing.

          if (!isPointsSame(this._stackedOnPoints, stackedOnPoints) || !isPointsSame(this._points, points)) {
            if (hasAnimation) {
              this._doUpdateAnimation(data, stackedOnPoints, coordSys, api, step, valueOrigin, connectNulls);
            } else {
              // Not do it in update with animation
              if (step) {
                // TODO If stacked series is not step
                points = turnPointsIntoStep(points, coordSys, step, connectNulls);

                if (stackedOnPoints) {
                  stackedOnPoints = turnPointsIntoStep(stackedOnPoints, coordSys, step, connectNulls);
                }
              }

              polyline.setShape({
                points: points
              });
              polygon && polygon.setShape({
                points: points,
                stackedOnPoints: stackedOnPoints
              });
            }
          }
        }

        var emphasisModel = seriesModel.getModel('emphasis');
        var focus = emphasisModel.get('focus');
        var blurScope = emphasisModel.get('blurScope');
        var emphasisDisabled = emphasisModel.get('disabled');
        polyline.useStyle(defaults( // Use color in lineStyle first
        lineStyleModel.getLineStyle(), {
          fill: 'none',
          stroke: visualColor,
          lineJoin: 'bevel'
        }));
        setStatesStylesFromModel(polyline, seriesModel, 'lineStyle');

        if (polyline.style.lineWidth > 0 && seriesModel.get(['emphasis', 'lineStyle', 'width']) === 'bolder') {
          var emphasisLineStyle = polyline.getState('emphasis').style;
          emphasisLineStyle.lineWidth = +polyline.style.lineWidth + 1;
        } // Needs seriesIndex for focus


        getECData(polyline).seriesIndex = seriesModel.seriesIndex;
        toggleHoverEmphasis(polyline, focus, blurScope, emphasisDisabled);
        var smooth = getSmooth(seriesModel.get('smooth'));
        var smoothMonotone = seriesModel.get('smoothMonotone');
        polyline.setShape({
          smooth: smooth,
          smoothMonotone: smoothMonotone,
          connectNulls: connectNulls
        });

        if (polygon) {
          var stackedOnSeries = data.getCalculationInfo('stackedOnSeries');
          var stackedOnSmooth = 0;
          polygon.useStyle(defaults(areaStyleModel.getAreaStyle(), {
            fill: visualColor,
            opacity: 0.7,
            lineJoin: 'bevel',
            decal: data.getVisual('style').decal
          }));

          if (stackedOnSeries) {
            stackedOnSmooth = getSmooth(stackedOnSeries.get('smooth'));
          }

          polygon.setShape({
            smooth: smooth,
            stackedOnSmooth: stackedOnSmooth,
            smoothMonotone: smoothMonotone,
            connectNulls: connectNulls
          });
          setStatesStylesFromModel(polygon, seriesModel, 'areaStyle'); // Needs seriesIndex for focus

          getECData(polygon).seriesIndex = seriesModel.seriesIndex;
          toggleHoverEmphasis(polygon, focus, blurScope, emphasisDisabled);
        }

        var changePolyState = function (toState) {
          _this._changePolyState(toState);
        };

        data.eachItemGraphicEl(function (el) {
          // Switch polyline / polygon state if element changed its state.
          el && (el.onHoverStateChange = changePolyState);
        });
        this._polyline.onHoverStateChange = changePolyState;
        this._data = data; // Save the coordinate system for transition animation when data changed

        this._coordSys = coordSys;
        this._stackedOnPoints = stackedOnPoints;
        this._points = points;
        this._step = step;
        this._valueOrigin = valueOrigin;

        if (seriesModel.get('triggerLineEvent')) {
          this.packEventData(seriesModel, polyline);
          polygon && this.packEventData(seriesModel, polygon);
        }
      };

      LineView.prototype.packEventData = function (seriesModel, el) {
        getECData(el).eventData = {
          componentType: 'series',
          componentSubType: 'line',
          componentIndex: seriesModel.componentIndex,
          seriesIndex: seriesModel.seriesIndex,
          seriesName: seriesModel.name,
          seriesType: 'line'
        };
      };

      LineView.prototype.highlight = function (seriesModel, ecModel, api, payload) {
        var data = seriesModel.getData();
        var dataIndex = queryDataIndex(data, payload);

        this._changePolyState('emphasis');

        if (!(dataIndex instanceof Array) && dataIndex != null && dataIndex >= 0) {
          var points = data.getLayout('points');
          var symbol = data.getItemGraphicEl(dataIndex);

          if (!symbol) {
            // Create a temporary symbol if it is not exists
            var x = points[dataIndex * 2];
            var y = points[dataIndex * 2 + 1];

            if (isNaN(x) || isNaN(y)) {
              // Null data
              return;
            } // fix #11360: shouldn't draw symbol outside clipShapeForSymbol


            if (this._clipShapeForSymbol && !this._clipShapeForSymbol.contain(x, y)) {
              return;
            }

            var zlevel = seriesModel.get('zlevel') || 0;
            var z = seriesModel.get('z') || 0;
            symbol = new Symbol(data, dataIndex);
            symbol.x = x;
            symbol.y = y;
            symbol.setZ(zlevel, z); // ensure label text of the temporary symbol is in front of line and area polygon

            var symbolLabel = symbol.getSymbolPath().getTextContent();

            if (symbolLabel) {
              symbolLabel.zlevel = zlevel;
              symbolLabel.z = z;
              symbolLabel.z2 = this._polyline.z2 + 1;
            }

            symbol.__temp = true;
            data.setItemGraphicEl(dataIndex, symbol); // Stop scale animation

            symbol.stopSymbolAnimation(true);
            this.group.add(symbol);
          }

          symbol.highlight();
        } else {
          // Highlight whole series
          ChartView.prototype.highlight.call(this, seriesModel, ecModel, api, payload);
        }
      };

      LineView.prototype.downplay = function (seriesModel, ecModel, api, payload) {
        var data = seriesModel.getData();
        var dataIndex = queryDataIndex(data, payload);

        this._changePolyState('normal');

        if (dataIndex != null && dataIndex >= 0) {
          var symbol = data.getItemGraphicEl(dataIndex);

          if (symbol) {
            if (symbol.__temp) {
              data.setItemGraphicEl(dataIndex, null);
              this.group.remove(symbol);
            } else {
              symbol.downplay();
            }
          }
        } else {
          // FIXME
          // can not downplay completely.
          // Downplay whole series
          ChartView.prototype.downplay.call(this, seriesModel, ecModel, api, payload);
        }
      };

      LineView.prototype._changePolyState = function (toState) {
        var polygon = this._polygon;
        setStatesFlag(this._polyline, toState);
        polygon && setStatesFlag(polygon, toState);
      };

      LineView.prototype._newPolyline = function (points) {
        var polyline = this._polyline; // Remove previous created polyline

        if (polyline) {
          this._lineGroup.remove(polyline);
        }

        polyline = new ECPolyline({
          shape: {
            points: points
          },
          segmentIgnoreThreshold: 2,
          z2: 10
        });

        this._lineGroup.add(polyline);

        this._polyline = polyline;
        return polyline;
      };

      LineView.prototype._newPolygon = function (points, stackedOnPoints) {
        var polygon = this._polygon; // Remove previous created polygon

        if (polygon) {
          this._lineGroup.remove(polygon);
        }

        polygon = new ECPolygon({
          shape: {
            points: points,
            stackedOnPoints: stackedOnPoints
          },
          segmentIgnoreThreshold: 2
        });

        this._lineGroup.add(polygon);

        this._polygon = polygon;
        return polygon;
      };

      LineView.prototype._initSymbolLabelAnimation = function (data, coordSys, clipShape) {
        var isHorizontalOrRadial;
        var isCoordSysPolar;
        var baseAxis = coordSys.getBaseAxis();
        var isAxisInverse = baseAxis.inverse;

        if (coordSys.type === 'cartesian2d') {
          isHorizontalOrRadial = baseAxis.isHorizontal();
          isCoordSysPolar = false;
        } else if (coordSys.type === 'polar') {
          isHorizontalOrRadial = baseAxis.dim === 'angle';
          isCoordSysPolar = true;
        }

        var seriesModel = data.hostModel;
        var seriesDuration = seriesModel.get('animationDuration');

        if (isFunction(seriesDuration)) {
          seriesDuration = seriesDuration(null);
        }

        var seriesDalay = seriesModel.get('animationDelay') || 0;
        var seriesDalayValue = isFunction(seriesDalay) ? seriesDalay(null) : seriesDalay;
        data.eachItemGraphicEl(function (symbol, idx) {
          var el = symbol;

          if (el) {
            var point = [symbol.x, symbol.y];
            var start = void 0;
            var end = void 0;
            var current = void 0;

            if (clipShape) {
              if (isCoordSysPolar) {
                var polarClip = clipShape;
                var coord = coordSys.pointToCoord(point);

                if (isHorizontalOrRadial) {
                  start = polarClip.startAngle;
                  end = polarClip.endAngle;
                  current = -coord[1] / 180 * Math.PI;
                } else {
                  start = polarClip.r0;
                  end = polarClip.r;
                  current = coord[0];
                }
              } else {
                var gridClip = clipShape;

                if (isHorizontalOrRadial) {
                  start = gridClip.x;
                  end = gridClip.x + gridClip.width;
                  current = symbol.x;
                } else {
                  start = gridClip.y + gridClip.height;
                  end = gridClip.y;
                  current = symbol.y;
                }
              }
            }

            var ratio = end === start ? 0 : (current - start) / (end - start);

            if (isAxisInverse) {
              ratio = 1 - ratio;
            }

            var delay = isFunction(seriesDalay) ? seriesDalay(idx) : seriesDuration * ratio + seriesDalayValue;
            var symbolPath = el.getSymbolPath();
            var text = symbolPath.getTextContent();
            el.attr({
              scaleX: 0,
              scaleY: 0
            });
            el.animateTo({
              scaleX: 1,
              scaleY: 1
            }, {
              duration: 200,
              setToFinal: true,
              delay: delay
            });

            if (text) {
              text.animateFrom({
                style: {
                  opacity: 0
                }
              }, {
                duration: 300,
                delay: delay
              });
            }

            symbolPath.disableLabelAnimation = true;
          }
        });
      };

      LineView.prototype._initOrUpdateEndLabel = function (seriesModel, coordSys, inheritColor) {
        var endLabelModel = seriesModel.getModel('endLabel');

        if (anyStateShowEndLabel(seriesModel)) {
          var data_2 = seriesModel.getData();
          var polyline = this._polyline; // series may be filtered.

          var points = data_2.getLayout('points');

          if (!points) {
            polyline.removeTextContent();
            this._endLabel = null;
            return;
          }

          var endLabel = this._endLabel;

          if (!endLabel) {
            endLabel = this._endLabel = new ZRText({
              z2: 200 // should be higher than item symbol

            });
            endLabel.ignoreClip = true;
            polyline.setTextContent(this._endLabel);
            polyline.disableLabelAnimation = true;
          } // Find last non-NaN data to display data


          var dataIndex = getLastIndexNotNull(points);

          if (dataIndex >= 0) {
            setLabelStyle(polyline, getLabelStatesModels(seriesModel, 'endLabel'), {
              inheritColor: inheritColor,
              labelFetcher: seriesModel,
              labelDataIndex: dataIndex,
              defaultText: function (dataIndex, opt, interpolatedValue) {
                return interpolatedValue != null ? getDefaultInterpolatedLabel(data_2, interpolatedValue) : getDefaultLabel(data_2, dataIndex);
              },
              enableTextSetter: true
            }, getEndLabelStateSpecified(endLabelModel, coordSys));
            polyline.textConfig.position = null;
          }
        } else if (this._endLabel) {
          this._polyline.removeTextContent();

          this._endLabel = null;
        }
      };

      LineView.prototype._endLabelOnDuring = function (percent, clipRect, data, animationRecord, valueAnimation, endLabelModel, coordSys) {
        var endLabel = this._endLabel;
        var polyline = this._polyline;

        if (endLabel) {
          // NOTE: Don't remove percent < 1. percent === 1 means the first frame during render.
          // The label is not prepared at this time.
          if (percent < 1 && animationRecord.originalX == null) {
            animationRecord.originalX = endLabel.x;
            animationRecord.originalY = endLabel.y;
          }

          var points = data.getLayout('points');
          var seriesModel = data.hostModel;
          var connectNulls = seriesModel.get('connectNulls');
          var precision = endLabelModel.get('precision');
          var distance = endLabelModel.get('distance') || 0;
          var baseAxis = coordSys.getBaseAxis();
          var isHorizontal = baseAxis.isHorizontal();
          var isBaseInversed = baseAxis.inverse;
          var clipShape = clipRect.shape;
          var xOrY = isBaseInversed ? isHorizontal ? clipShape.x : clipShape.y + clipShape.height : isHorizontal ? clipShape.x + clipShape.width : clipShape.y;
          var distanceX = (isHorizontal ? distance : 0) * (isBaseInversed ? -1 : 1);
          var distanceY = (isHorizontal ? 0 : -distance) * (isBaseInversed ? -1 : 1);
          var dim = isHorizontal ? 'x' : 'y';
          var dataIndexRange = getIndexRange(points, xOrY, dim);
          var indices = dataIndexRange.range;
          var diff = indices[1] - indices[0];
          var value = void 0;

          if (diff >= 1) {
            // diff > 1 && connectNulls, which is on the null data.
            if (diff > 1 && !connectNulls) {
              var pt = getPointAtIndex(points, indices[0]);
              endLabel.attr({
                x: pt[0] + distanceX,
                y: pt[1] + distanceY
              });
              valueAnimation && (value = seriesModel.getRawValue(indices[0]));
            } else {
              var pt = polyline.getPointOn(xOrY, dim);
              pt && endLabel.attr({
                x: pt[0] + distanceX,
                y: pt[1] + distanceY
              });
              var startValue = seriesModel.getRawValue(indices[0]);
              var endValue = seriesModel.getRawValue(indices[1]);
              valueAnimation && (value = interpolateRawValues(data, precision, startValue, endValue, dataIndexRange.t));
            }

            animationRecord.lastFrameIndex = indices[0];
          } else {
            // If diff <= 0, which is the range is not found(Include NaN)
            // Choose the first point or last point.
            var idx = percent === 1 || animationRecord.lastFrameIndex > 0 ? indices[0] : 0;
            var pt = getPointAtIndex(points, idx);
            valueAnimation && (value = seriesModel.getRawValue(idx));
            endLabel.attr({
              x: pt[0] + distanceX,
              y: pt[1] + distanceY
            });
          }

          if (valueAnimation) {
            labelInner(endLabel).setLabelText(value);
          }
        }
      };
      /**
       * @private
       */
      // FIXME Two value axis


      LineView.prototype._doUpdateAnimation = function (data, stackedOnPoints, coordSys, api, step, valueOrigin, connectNulls) {
        var polyline = this._polyline;
        var polygon = this._polygon;
        var seriesModel = data.hostModel;
        var diff = lineAnimationDiff(this._data, data, this._stackedOnPoints, stackedOnPoints, this._coordSys, coordSys, this._valueOrigin);
        var current = diff.current;
        var stackedOnCurrent = diff.stackedOnCurrent;
        var next = diff.next;
        var stackedOnNext = diff.stackedOnNext;

        if (step) {
          // TODO If stacked series is not step
          current = turnPointsIntoStep(diff.current, coordSys, step, connectNulls);
          stackedOnCurrent = turnPointsIntoStep(diff.stackedOnCurrent, coordSys, step, connectNulls);
          next = turnPointsIntoStep(diff.next, coordSys, step, connectNulls);
          stackedOnNext = turnPointsIntoStep(diff.stackedOnNext, coordSys, step, connectNulls);
        } // Don't apply animation if diff is large.
        // For better result and avoid memory explosion problems like
        // https://github.com/apache/incubator-echarts/issues/12229


        if (getBoundingDiff(current, next) > 3000 || polygon && getBoundingDiff(stackedOnCurrent, stackedOnNext) > 3000) {
          polyline.stopAnimation();
          polyline.setShape({
            points: next
          });

          if (polygon) {
            polygon.stopAnimation();
            polygon.setShape({
              points: next,
              stackedOnPoints: stackedOnNext
            });
          }

          return;
        }

        polyline.shape.__points = diff.current;
        polyline.shape.points = current;
        var target = {
          shape: {
            points: next
          }
        }; // Also animate the original points.
        // If points reference is changed when turning into step line.

        if (diff.current !== current) {
          target.shape.__points = diff.next;
        } // Stop previous animation.


        polyline.stopAnimation();
        updateProps(polyline, target, seriesModel);

        if (polygon) {
          polygon.setShape({
            // Reuse the points with polyline.
            points: current,
            stackedOnPoints: stackedOnCurrent
          });
          polygon.stopAnimation();
          updateProps(polygon, {
            shape: {
              stackedOnPoints: stackedOnNext
            }
          }, seriesModel); // If use attr directly in updateProps.

          if (polyline.shape.points !== polygon.shape.points) {
            polygon.shape.points = polyline.shape.points;
          }
        }

        var updatedDataInfo = [];
        var diffStatus = diff.status;

        for (var i = 0; i < diffStatus.length; i++) {
          var cmd = diffStatus[i].cmd;

          if (cmd === '=') {
            var el = data.getItemGraphicEl(diffStatus[i].idx1);

            if (el) {
              updatedDataInfo.push({
                el: el,
                ptIdx: i // Index of points

              });
            }
          }
        }

        if (polyline.animators && polyline.animators.length) {
          polyline.animators[0].during(function () {
            polygon && polygon.dirtyShape();
            var points = polyline.shape.__points;

            for (var i = 0; i < updatedDataInfo.length; i++) {
              var el = updatedDataInfo[i].el;
              var offset = updatedDataInfo[i].ptIdx * 2;
              el.x = points[offset];
              el.y = points[offset + 1];
              el.markRedraw();
            }
          });
        }
      };

      LineView.prototype.remove = function (ecModel) {
        var group = this.group;
        var oldData = this._data;

        this._lineGroup.removeAll();

        this._symbolDraw.remove(true); // Remove temporary created elements when highlighting


        oldData && oldData.eachItemGraphicEl(function (el, idx) {
          if (el.__temp) {
            group.remove(el);
            oldData.setItemGraphicEl(idx, null);
          }
        });
        this._polyline = this._polygon = this._coordSys = this._points = this._stackedOnPoints = this._endLabel = this._data = null;
      };

      LineView.type = 'line';
      return LineView;
    }(ChartView);

    function pointsLayout(seriesType, forceStoreInTypedArray) {
      return {
        seriesType: seriesType,
        plan: createRenderPlanner(),
        reset: function (seriesModel) {
          var data = seriesModel.getData();
          var coordSys = seriesModel.coordinateSystem;
          var pipelineContext = seriesModel.pipelineContext;
          var useTypedArray = forceStoreInTypedArray || pipelineContext.large;

          if (!coordSys) {
            return;
          }

          var dims = map(coordSys.dimensions, function (dim) {
            return data.mapDimension(dim);
          }).slice(0, 2);
          var dimLen = dims.length;
          var stackResultDim = data.getCalculationInfo('stackResultDimension');

          if (isDimensionStacked(data, dims[0])) {
            dims[0] = stackResultDim;
          }

          if (isDimensionStacked(data, dims[1])) {
            dims[1] = stackResultDim;
          }

          var store = data.getStore();
          var dimIdx0 = data.getDimensionIndex(dims[0]);
          var dimIdx1 = data.getDimensionIndex(dims[1]);
          return dimLen && {
            progress: function (params, data) {
              var segCount = params.end - params.start;
              var points = useTypedArray && createFloat32Array(segCount * dimLen);
              var tmpIn = [];
              var tmpOut = [];

              for (var i = params.start, offset = 0; i < params.end; i++) {
                var point = void 0;

                if (dimLen === 1) {
                  var x = store.get(dimIdx0, i); // NOTE: Make sure the second parameter is null to use default strategy.

                  point = coordSys.dataToPoint(x, null, tmpOut);
                } else {
                  tmpIn[0] = store.get(dimIdx0, i);
                  tmpIn[1] = store.get(dimIdx1, i); // Let coordinate system to handle the NaN data.

                  point = coordSys.dataToPoint(tmpIn, null, tmpOut);
                }

                if (useTypedArray) {
                  points[offset++] = point[0];
                  points[offset++] = point[1];
                } else {
                  data.setItemLayout(i, point.slice());
                }
              }

              useTypedArray && data.setLayout('points', points);
            }
          };
        }
      };
    }

    var samplers = {
      average: function (frame) {
        var sum = 0;
        var count = 0;

        for (var i = 0; i < frame.length; i++) {
          if (!isNaN(frame[i])) {
            sum += frame[i];
            count++;
          }
        } // Return NaN if count is 0


        return count === 0 ? NaN : sum / count;
      },
      sum: function (frame) {
        var sum = 0;

        for (var i = 0; i < frame.length; i++) {
          // Ignore NaN
          sum += frame[i] || 0;
        }

        return sum;
      },
      max: function (frame) {
        var max = -Infinity;

        for (var i = 0; i < frame.length; i++) {
          frame[i] > max && (max = frame[i]);
        } // NaN will cause illegal axis extent.


        return isFinite(max) ? max : NaN;
      },
      min: function (frame) {
        var min = Infinity;

        for (var i = 0; i < frame.length; i++) {
          frame[i] < min && (min = frame[i]);
        } // NaN will cause illegal axis extent.


        return isFinite(min) ? min : NaN;
      },
      // TODO
      // Median
      nearest: function (frame) {
        return frame[0];
      }
    };

    var indexSampler = function (frame) {
      return Math.round(frame.length / 2);
    };

    function dataSample(seriesType) {
      return {
        seriesType: seriesType,
        // FIXME:TS never used, so comment it
        // modifyOutputEnd: true,
        reset: function (seriesModel, ecModel, api) {
          var data = seriesModel.getData();
          var sampling = seriesModel.get('sampling');
          var coordSys = seriesModel.coordinateSystem;
          var count = data.count(); // Only cartesian2d support down sampling. Disable it when there is few data.

          if (count > 10 && coordSys.type === 'cartesian2d' && sampling) {
            var baseAxis = coordSys.getBaseAxis();
            var valueAxis = coordSys.getOtherAxis(baseAxis);
            var extent = baseAxis.getExtent();
            var dpr = api.getDevicePixelRatio(); // Coordinste system has been resized

            var size = Math.abs(extent[1] - extent[0]) * (dpr || 1);
            var rate = Math.round(count / size);

            if (isFinite(rate) && rate > 1) {
              if (sampling === 'lttb') {
                seriesModel.setData(data.lttbDownSample(data.mapDimension(valueAxis.dim), 1 / rate));
              }

              var sampler = void 0;

              if (isString(sampling)) {
                sampler = samplers[sampling];
              } else if (isFunction(sampling)) {
                sampler = sampling;
              }

              if (sampler) {
                // Only support sample the first dim mapped from value axis.
                seriesModel.setData(data.downSample(data.mapDimension(valueAxis.dim), 1 / rate, sampler, indexSampler));
              }
            }
          }
        }
      };
    }

    function install$1(registers) {
      registers.registerChartView(LineView);
      registers.registerSeriesModel(LineSeriesModel);
      registers.registerLayout(pointsLayout('line', true));
      registers.registerVisual({
        seriesType: 'line',
        reset: function (seriesModel) {
          var data = seriesModel.getData(); // Visual coding for legend

          var lineStyle = seriesModel.getModel('lineStyle').getLineStyle();

          if (lineStyle && !lineStyle.stroke) {
            // Fill in visual should be palette color if
            // has color callback
            lineStyle.stroke = data.getVisual('style').fill;
          }

          data.setVisual('legendLineStyle', lineStyle);
        }
      }); // Down sample after filter

      registers.registerProcessor(registers.PRIORITY.PROCESSOR.STATISTIC, dataSample('line'));
    }

    var BaseBarSeriesModel =
    /** @class */
    function (_super) {
      __extends(BaseBarSeriesModel, _super);

      function BaseBarSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = BaseBarSeriesModel.type;
        return _this;
      }

      BaseBarSeriesModel.prototype.getInitialData = function (option, ecModel) {
        return createSeriesData(null, this, {
          useEncodeDefaulter: true
        });
      };

      BaseBarSeriesModel.prototype.getMarkerPosition = function (value, dims, startingAtTick) {
        var coordSys = this.coordinateSystem;

        if (coordSys && coordSys.clampData) {
          // PENDING if clamp ?
          var pt_1 = coordSys.dataToPoint(coordSys.clampData(value));

          if (startingAtTick) {
            each(coordSys.getAxes(), function (axis, idx) {
              // If axis type is category, use tick coords instead
              if (axis.type === 'category') {
                var tickCoords = axis.getTicksCoords();
                var tickIdx = coordSys.clampData(value)[idx]; // The index of rightmost tick of markArea is 1 larger than x1/y1 index

                if (dims && (dims[idx] === 'x1' || dims[idx] === 'y1')) {
                  tickIdx += 1;
                }

                tickIdx > tickCoords.length - 1 && (tickIdx = tickCoords.length - 1);
                tickIdx < 0 && (tickIdx = 0);
                tickCoords[tickIdx] && (pt_1[idx] = axis.toGlobalCoord(tickCoords[tickIdx].coord));
              }
            });
          } else {
            var data = this.getData();
            var offset = data.getLayout('offset');
            var size = data.getLayout('size');
            var offsetIndex = coordSys.getBaseAxis().isHorizontal() ? 0 : 1;
            pt_1[offsetIndex] += offset + size / 2;
          }

          return pt_1;
        }

        return [NaN, NaN];
      };

      BaseBarSeriesModel.type = 'series.__base_bar__';
      BaseBarSeriesModel.defaultOption = {
        // zlevel: 0,
        z: 2,
        coordinateSystem: 'cartesian2d',
        legendHoverLink: true,
        // stack: null
        // Cartesian coordinate system
        // xAxisIndex: 0,
        // yAxisIndex: 0,
        barMinHeight: 0,
        barMinAngle: 0,
        // cursor: null,
        large: false,
        largeThreshold: 400,
        progressive: 3e3,
        progressiveChunkMode: 'mod'
      };
      return BaseBarSeriesModel;
    }(SeriesModel);

    SeriesModel.registerClass(BaseBarSeriesModel);

    var BarSeriesModel =
    /** @class */
    function (_super) {
      __extends(BarSeriesModel, _super);

      function BarSeriesModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = BarSeriesModel.type;
        return _this;
      }

      BarSeriesModel.prototype.getInitialData = function () {
        return createSeriesData(null, this, {
          useEncodeDefaulter: true,
          createInvertedIndices: !!this.get('realtimeSort', true) || null
        });
      };
      /**
       * @override
       */


      BarSeriesModel.prototype.getProgressive = function () {
        // Do not support progressive in normal mode.
        return this.get('large') ? this.get('progressive') : false;
      };
      /**
       * @override
       */


      BarSeriesModel.prototype.getProgressiveThreshold = function () {
        // Do not support progressive in normal mode.
        var progressiveThreshold = this.get('progressiveThreshold');
        var largeThreshold = this.get('largeThreshold');

        if (largeThreshold > progressiveThreshold) {
          progressiveThreshold = largeThreshold;
        }

        return progressiveThreshold;
      };

      BarSeriesModel.prototype.brushSelector = function (dataIndex, data, selectors) {
        return selectors.rect(data.getItemLayout(dataIndex));
      };

      BarSeriesModel.type = 'series.bar';
      BarSeriesModel.dependencies = ['grid', 'polar'];
      BarSeriesModel.defaultOption = inheritDefaultOption(BaseBarSeriesModel.defaultOption, {
        // If clipped
        // Only available on cartesian2d
        clip: true,
        roundCap: false,
        showBackground: false,
        backgroundStyle: {
          color: 'rgba(180, 180, 180, 0.2)',
          borderColor: null,
          borderWidth: 0,
          borderType: 'solid',
          borderRadius: 0,
          shadowBlur: 0,
          shadowColor: null,
          shadowOffsetX: 0,
          shadowOffsetY: 0,
          opacity: 1
        },
        select: {
          itemStyle: {
            borderColor: '#212121'
          }
        },
        realtimeSort: false
      });
      return BarSeriesModel;
    }(BaseBarSeriesModel);

    /**
     * Sausage: similar to sector, but have half circle on both sides
     */

    var SausageShape =
    /** @class */
    function () {
      function SausageShape() {
        this.cx = 0;
        this.cy = 0;
        this.r0 = 0;
        this.r = 0;
        this.startAngle = 0;
        this.endAngle = Math.PI * 2;
        this.clockwise = true;
      }

      return SausageShape;
    }();

    var SausagePath =
    /** @class */
    function (_super) {
      __extends(SausagePath, _super);

      function SausagePath(opts) {
        var _this = _super.call(this, opts) || this;

        _this.type = 'sausage';
        return _this;
      }

      SausagePath.prototype.getDefaultShape = function () {
        return new SausageShape();
      };

      SausagePath.prototype.buildPath = function (ctx, shape) {
        var cx = shape.cx;
        var cy = shape.cy;
        var r0 = Math.max(shape.r0 || 0, 0);
        var r = Math.max(shape.r, 0);
        var dr = (r - r0) * 0.5;
        var rCenter = r0 + dr;
        var startAngle = shape.startAngle;
        var endAngle = shape.endAngle;
        var clockwise = shape.clockwise;
        var PI2 = Math.PI * 2;
        var lessThanCircle = clockwise ? endAngle - startAngle < PI2 : startAngle - endAngle < PI2;

        if (!lessThanCircle) {
          // Normalize angles
          startAngle = endAngle - (clockwise ? PI2 : -PI2);
        }

        var unitStartX = Math.cos(startAngle);
        var unitStartY = Math.sin(startAngle);
        var unitEndX = Math.cos(endAngle);
        var unitEndY = Math.sin(endAngle);

        if (lessThanCircle) {
          ctx.moveTo(unitStartX * r0 + cx, unitStartY * r0 + cy);
          ctx.arc(unitStartX * rCenter + cx, unitStartY * rCenter + cy, dr, -Math.PI + startAngle, startAngle, !clockwise);
        } else {
          ctx.moveTo(unitStartX * r + cx, unitStartY * r + cy);
        }

        ctx.arc(cx, cy, r, startAngle, endAngle, !clockwise);
        ctx.arc(unitEndX * rCenter + cx, unitEndY * rCenter + cy, dr, endAngle - Math.PI * 2, endAngle - Math.PI, !clockwise);

        if (r0 !== 0) {
          ctx.arc(cx, cy, r0, endAngle, startAngle, clockwise);
        } // ctx.closePath();

      };

      return SausagePath;
    }(Path);

    function createSectorCalculateTextPosition(positionMapping, opts) {
      opts = opts || {};
      var isRoundCap = opts.isRoundCap;
      return function (out, opts, boundingRect) {
        var textPosition = opts.position;

        if (!textPosition || textPosition instanceof Array) {
          return calculateTextPosition(out, opts, boundingRect);
        }

        var mappedSectorPosition = positionMapping(textPosition);
        var distance = opts.distance != null ? opts.distance : 5;
        var sector = this.shape;
        var cx = sector.cx;
        var cy = sector.cy;
        var r = sector.r;
        var r0 = sector.r0;
        var middleR = (r + r0) / 2;
        var startAngle = sector.startAngle;
        var endAngle = sector.endAngle;
        var middleAngle = (startAngle + endAngle) / 2;
        var extraDist = isRoundCap ? Math.abs(r - r0) / 2 : 0;
        var mathCos = Math.cos;
        var mathSin = Math.sin; // base position: top-left

        var x = cx + r * mathCos(startAngle);
        var y = cy + r * mathSin(startAngle);
        var textAlign = 'left';
        var textVerticalAlign = 'top';

        switch (mappedSectorPosition) {
          case 'startArc':
            x = cx + (r0 - distance) * mathCos(middleAngle);
            y = cy + (r0 - distance) * mathSin(middleAngle);
            textAlign = 'center';
            textVerticalAlign = 'top';
            break;

          case 'insideStartArc':
            x = cx + (r0 + distance) * mathCos(middleAngle);
            y = cy + (r0 + distance) * mathSin(middleAngle);
            textAlign = 'center';
            textVerticalAlign = 'bottom';
            break;

          case 'startAngle':
            x = cx + middleR * mathCos(startAngle) + adjustAngleDistanceX(startAngle, distance + extraDist, false);
            y = cy + middleR * mathSin(startAngle) + adjustAngleDistanceY(startAngle, distance + extraDist, false);
            textAlign = 'right';
            textVerticalAlign = 'middle';
            break;

          case 'insideStartAngle':
            x = cx + middleR * mathCos(startAngle) + adjustAngleDistanceX(startAngle, -distance + extraDist, false);
            y = cy + middleR * mathSin(startAngle) + adjustAngleDistanceY(startAngle, -distance + extraDist, false);
            textAlign = 'left';
            textVerticalAlign = 'middle';
            break;

          case 'middle':
            x = cx + middleR * mathCos(middleAngle);
            y = cy + middleR * mathSin(middleAngle);
            textAlign = 'center';
            textVerticalAlign = 'middle';
            break;

          case 'endArc':
            x = cx + (r + distance) * mathCos(middleAngle);
            y = cy + (r + distance) * mathSin(middleAngle);
            textAlign = 'center';
            textVerticalAlign = 'bottom';
            break;

          case 'insideEndArc':
            x = cx + (r - distance) * mathCos(middleAngle);
            y = cy + (r - distance) * mathSin(middleAngle);
            textAlign = 'center';
            textVerticalAlign = 'top';
            break;

          case 'endAngle':
            x = cx + middleR * mathCos(endAngle) + adjustAngleDistanceX(endAngle, distance + extraDist, true);
            y = cy + middleR * mathSin(endAngle) + adjustAngleDistanceY(endAngle, distance + extraDist, true);
            textAlign = 'left';
            textVerticalAlign = 'middle';
            break;

          case 'insideEndAngle':
            x = cx + middleR * mathCos(endAngle) + adjustAngleDistanceX(endAngle, -distance + extraDist, true);
            y = cy + middleR * mathSin(endAngle) + adjustAngleDistanceY(endAngle, -distance + extraDist, true);
            textAlign = 'right';
            textVerticalAlign = 'middle';
            break;

          default:
            return calculateTextPosition(out, opts, boundingRect);
        }

        out = out || {};
        out.x = x;
        out.y = y;
        out.align = textAlign;
        out.verticalAlign = textVerticalAlign;
        return out;
      };
    }
    function setSectorTextRotation(sector, textPosition, positionMapping, rotateType) {
      if (isNumber(rotateType)) {
        // user-set rotation
        sector.setTextConfig({
          rotation: rotateType
        });
        return;
      } else if (isArray(textPosition)) {
        // user-set position, use 0 as auto rotation
        sector.setTextConfig({
          rotation: 0
        });
        return;
      }

      var shape = sector.shape;
      var startAngle = shape.clockwise ? shape.startAngle : shape.endAngle;
      var endAngle = shape.clockwise ? shape.endAngle : shape.startAngle;
      var middleAngle = (startAngle + endAngle) / 2;
      var anchorAngle;
      var mappedSectorPosition = positionMapping(textPosition);

      switch (mappedSectorPosition) {
        case 'startArc':
        case 'insideStartArc':
        case 'middle':
        case 'insideEndArc':
        case 'endArc':
          anchorAngle = middleAngle;
          break;

        case 'startAngle':
        case 'insideStartAngle':
          anchorAngle = startAngle;
          break;

        case 'endAngle':
        case 'insideEndAngle':
          anchorAngle = endAngle;
          break;

        default:
          sector.setTextConfig({
            rotation: 0
          });
          return;
      }

      var rotate = Math.PI * 1.5 - anchorAngle;
      /**
       * TODO: labels with rotate > Math.PI / 2 should be rotate another
       * half round flipped to increase readability. However, only middle
       * position supports this for now, because in other positions, the
       * anchor point is not at the center of the text, so the positions
       * after rotating is not as expected.
       */

      if (mappedSectorPosition === 'middle' && rotate > Math.PI / 2 && rotate < Math.PI * 1.5) {
        rotate -= Math.PI;
      }

      sector.setTextConfig({
        rotation: rotate
      });
    }

    function adjustAngleDistanceX(angle, distance, isEnd) {
      return distance * Math.sin(angle) * (isEnd ? -1 : 1);
    }

    function adjustAngleDistanceY(angle, distance, isEnd) {
      return distance * Math.cos(angle) * (isEnd ? 1 : -1);
    }

    var mathMax$6 = Math.max;
    var mathMin$6 = Math.min;

    function getClipArea(coord, data) {
      var coordSysClipArea = coord.getArea && coord.getArea();

      if (isCoordinateSystemType(coord, 'cartesian2d')) {
        var baseAxis = coord.getBaseAxis(); // When boundaryGap is false or using time axis. bar may exceed the grid.
        // We should not clip this part.
        // See test/bar2.html

        if (baseAxis.type !== 'category' || !baseAxis.onBand) {
          var expandWidth = data.getLayout('bandWidth');

          if (baseAxis.isHorizontal()) {
            coordSysClipArea.x -= expandWidth;
            coordSysClipArea.width += expandWidth * 2;
          } else {
            coordSysClipArea.y -= expandWidth;
            coordSysClipArea.height += expandWidth * 2;
          }
        }
      }

      return coordSysClipArea;
    }

    var BarView =
    /** @class */
    function (_super) {
      __extends(BarView, _super);

      function BarView() {
        var _this = _super.call(this) || this;

        _this.type = BarView.type;
        _this._isFirstFrame = true;
        return _this;
      }

      BarView.prototype.render = function (seriesModel, ecModel, api, payload) {
        this._model = seriesModel;

        this._removeOnRenderedListener(api);

        this._updateDrawMode(seriesModel);

        var coordinateSystemType = seriesModel.get('coordinateSystem');

        if (coordinateSystemType === 'cartesian2d' || coordinateSystemType === 'polar') {
          // Clear previously rendered progressive elements.
          this._progressiveEls = null;
          this._isLargeDraw ? this._renderLarge(seriesModel, ecModel, api) : this._renderNormal(seriesModel, ecModel, api, payload);
        } else if ("development" !== 'production') {
          warn('Only cartesian2d and polar supported for bar.');
        }
      };

      BarView.prototype.incrementalPrepareRender = function (seriesModel) {
        this._clear();

        this._updateDrawMode(seriesModel); // incremental also need to clip, otherwise might be overlow.
        // But must not set clip in each frame, otherwise all of the children will be marked redraw.


        this._updateLargeClip(seriesModel);
      };

      BarView.prototype.incrementalRender = function (params, seriesModel) {
        // Reset
        this._progressiveEls = []; // Do not support progressive in normal mode.

        this._incrementalRenderLarge(params, seriesModel);
      };

      BarView.prototype.eachRendered = function (cb) {
        traverseElements(this._progressiveEls || this.group, cb);
      };

      BarView.prototype._updateDrawMode = function (seriesModel) {
        var isLargeDraw = seriesModel.pipelineContext.large;

        if (this._isLargeDraw == null || isLargeDraw !== this._isLargeDraw) {
          this._isLargeDraw = isLargeDraw;

          this._clear();
        }
      };

      BarView.prototype._renderNormal = function (seriesModel, ecModel, api, payload) {
        var group = this.group;
        var data = seriesModel.getData();
        var oldData = this._data;
        var coord = seriesModel.coordinateSystem;
        var baseAxis = coord.getBaseAxis();
        var isHorizontalOrRadial;

        if (coord.type === 'cartesian2d') {
          isHorizontalOrRadial = baseAxis.isHorizontal();
        } else if (coord.type === 'polar') {
          isHorizontalOrRadial = baseAxis.dim === 'angle';
        }

        var animationModel = seriesModel.isAnimationEnabled() ? seriesModel : null;
        var realtimeSortCfg = shouldRealtimeSort(seriesModel, coord);

        if (realtimeSortCfg) {
          this._enableRealtimeSort(realtimeSortCfg, data, api);
        }

        var needsClip = seriesModel.get('clip', true) || realtimeSortCfg;
        var coordSysClipArea = getClipArea(coord, data); // If there is clipPath created in large mode. Remove it.

        group.removeClipPath(); // We don't use clipPath in normal mode because we needs a perfect animation
        // And don't want the label are clipped.

        var roundCap = seriesModel.get('roundCap', true);
        var drawBackground = seriesModel.get('showBackground', true);
        var backgroundModel = seriesModel.getModel('backgroundStyle');
        var barBorderRadius = backgroundModel.get('borderRadius') || 0;
        var bgEls = [];
        var oldBgEls = this._backgroundEls;
        var isInitSort = payload && payload.isInitSort;
        var isChangeOrder = payload && payload.type === 'changeAxisOrder';

        function createBackground(dataIndex) {
          var bgLayout = getLayout[coord.type](data, dataIndex);
          var bgEl = createBackgroundEl(coord, isHorizontalOrRadial, bgLayout);
          bgEl.useStyle(backgroundModel.getItemStyle()); // Only cartesian2d support borderRadius.

          if (coord.type === 'cartesian2d') {
            bgEl.setShape('r', barBorderRadius);
          }

          bgEls[dataIndex] = bgEl;
          return bgEl;
        }
        data.diff(oldData).add(function (dataIndex) {
          var itemModel = data.getItemModel(dataIndex);
          var layout = getLayout[coord.type](data, dataIndex, itemModel);

          if (drawBackground) {
            createBackground(dataIndex);
          } // If dataZoom in filteMode: 'empty', the baseValue can be set as NaN in "axisProxy".


          if (!data.hasValue(dataIndex) || !isValidLayout[coord.type](layout)) {
            return;
          }

          var isClipped = false;

          if (needsClip) {
            // Clip will modify the layout params.
            // And return a boolean to determine if the shape are fully clipped.
            isClipped = clip[coord.type](coordSysClipArea, layout);
          }

          var el = elementCreator[coord.type](seriesModel, data, dataIndex, layout, isHorizontalOrRadial, animationModel, baseAxis.model, false, roundCap);

          if (realtimeSortCfg) {
            /**
             * Force label animation because even if the element is
             * ignored because it's clipped, it may not be clipped after
             * changing order. Then, if not using forceLabelAnimation,
             * the label animation was never started, in which case,
             * the label will be the final value and doesn't have label
             * animation.
             */
            el.forceLabelAnimation = true;
          }

          updateStyle(el, data, dataIndex, itemModel, layout, seriesModel, isHorizontalOrRadial, coord.type === 'polar');

          if (isInitSort) {
            el.attr({
              shape: layout
            });
          } else if (realtimeSortCfg) {
            updateRealtimeAnimation(realtimeSortCfg, animationModel, el, layout, dataIndex, isHorizontalOrRadial, false, false);
          } else {
            initProps(el, {
              shape: layout
            }, seriesModel, dataIndex);
          }

          data.setItemGraphicEl(dataIndex, el);
          group.add(el);
          el.ignore = isClipped;
        }).update(function (newIndex, oldIndex) {
          var itemModel = data.getItemModel(newIndex);
          var layout = getLayout[coord.type](data, newIndex, itemModel);

          if (drawBackground) {
            var bgEl = void 0;

            if (oldBgEls.length === 0) {
              bgEl = createBackground(oldIndex);
            } else {
              bgEl = oldBgEls[oldIndex];
              bgEl.useStyle(backgroundModel.getItemStyle()); // Only cartesian2d support borderRadius.

              if (coord.type === 'cartesian2d') {
                bgEl.setShape('r', barBorderRadius);
              }

              bgEls[newIndex] = bgEl;
            }

            var bgLayout = getLayout[coord.type](data, newIndex);
            var shape = createBackgroundShape(isHorizontalOrRadial, bgLayout, coord);
            updateProps(bgEl, {
              shape: shape
            }, animationModel, newIndex);
          }

          var el = oldData.getItemGraphicEl(oldIndex);

          if (!data.hasValue(newIndex) || !isValidLayout[coord.type](layout)) {
            group.remove(el);
            return;
          }

          var isClipped = false;

          if (needsClip) {
            isClipped = clip[coord.type](coordSysClipArea, layout);

            if (isClipped) {
              group.remove(el);
            }
          }

          if (!el) {
            el = elementCreator[coord.type](seriesModel, data, newIndex, layout, isHorizontalOrRadial, animationModel, baseAxis.model, !!el, roundCap);
          } else {
            saveOldStyle(el);
          }

          if (realtimeSortCfg) {
            el.forceLabelAnimation = true;
          }

          if (isChangeOrder) {
            var textEl = el.getTextContent();

            if (textEl) {
              var labelInnerStore = labelInner(textEl);

              if (labelInnerStore.prevValue != null) {
                /**
                 * Set preValue to be value so that no new label
                 * should be started, otherwise, it will take a full
                 * `animationDurationUpdate` time to finish the
                 * animation, which is not expected.
                 */
                labelInnerStore.prevValue = labelInnerStore.value;
              }
            }
          } // Not change anything if only order changed.
          // Especially not change label.
          else {
              updateStyle(el, data, newIndex, itemModel, layout, seriesModel, isHorizontalOrRadial, coord.type === 'polar');
            }

          if (isInitSort) {
            el.attr({
              shape: layout
            });
          } else if (realtimeSortCfg) {
            updateRealtimeAnimation(realtimeSortCfg, animationModel, el, layout, newIndex, isHorizontalOrRadial, true, isChangeOrder);
          } else {
            updateProps(el, {
              shape: layout
            }, seriesModel, newIndex, null);
          }

          data.setItemGraphicEl(newIndex, el);
          el.ignore = isClipped;
          group.add(el);
        }).remove(function (dataIndex) {
          var el = oldData.getItemGraphicEl(dataIndex);
          el && removeElementWithFadeOut(el, seriesModel, dataIndex);
        }).execute();
        var bgGroup = this._backgroundGroup || (this._backgroundGroup = new Group());
        bgGroup.removeAll();

        for (var i = 0; i < bgEls.length; ++i) {
          bgGroup.add(bgEls[i]);
        }

        group.add(bgGroup);
        this._backgroundEls = bgEls;
        this._data = data;
      };

      BarView.prototype._renderLarge = function (seriesModel, ecModel, api) {
        this._clear();

        createLarge(seriesModel, this.group);

        this._updateLargeClip(seriesModel);
      };

      BarView.prototype._incrementalRenderLarge = function (params, seriesModel) {
        this._removeBackground();

        createLarge(seriesModel, this.group, this._progressiveEls, true);
      };

      BarView.prototype._updateLargeClip = function (seriesModel) {
        // Use clipPath in large mode.
        var clipPath = seriesModel.get('clip', true) && createClipPath(seriesModel.coordinateSystem, false, seriesModel);
        var group = this.group;

        if (clipPath) {
          group.setClipPath(clipPath);
        } else {
          group.removeClipPath();
        }
      };

      BarView.prototype._enableRealtimeSort = function (realtimeSortCfg, data, api) {
        var _this = this; // If no data in the first frame, wait for data to initSort


        if (!data.count()) {
          return;
        }

        var baseAxis = realtimeSortCfg.baseAxis;

        if (this._isFirstFrame) {
          this._dispatchInitSort(data, realtimeSortCfg, api);

          this._isFirstFrame = false;
        } else {
          var orderMapping_1 = function (idx) {
            var el = data.getItemGraphicEl(idx);
            var shape = el && el.shape;
            return shape && // The result should be consistent with the initial sort by data value.
            // Do not support the case that both positive and negative exist.
            Math.abs(baseAxis.isHorizontal() ? shape.height : shape.width) // If data is NaN, shape.xxx may be NaN, so use || 0 here in case
            || 0;
          };

          this._onRendered = function () {
            _this._updateSortWithinSameData(data, orderMapping_1, baseAxis, api);
          };

          api.getZr().on('rendered', this._onRendered);
        }
      };

      BarView.prototype._dataSort = function (data, baseAxis, orderMapping) {
        var info = [];
        data.each(data.mapDimension(baseAxis.dim), function (ordinalNumber, dataIdx) {
          var mappedValue = orderMapping(dataIdx);
          mappedValue = mappedValue == null ? NaN : mappedValue;
          info.push({
            dataIndex: dataIdx,
            mappedValue: mappedValue,
            ordinalNumber: ordinalNumber
          });
        });
        info.sort(function (a, b) {
          // If NaN, it will be treated as min val.
          return b.mappedValue - a.mappedValue;
        });
        return {
          ordinalNumbers: map(info, function (item) {
            return item.ordinalNumber;
          })
        };
      };

      BarView.prototype._isOrderChangedWithinSameData = function (data, orderMapping, baseAxis) {
        var scale = baseAxis.scale;
        var ordinalDataDim = data.mapDimension(baseAxis.dim);
        var lastValue = Number.MAX_VALUE;

        for (var tickNum = 0, len = scale.getOrdinalMeta().categories.length; tickNum < len; ++tickNum) {
          var rawIdx = data.rawIndexOf(ordinalDataDim, scale.getRawOrdinalNumber(tickNum));
          var value = rawIdx < 0 // If some tick have no bar, the tick will be treated as min.
          ? Number.MIN_VALUE // PENDING: if dataZoom on baseAxis exits, is it a performance issue?
          : orderMapping(data.indexOfRawIndex(rawIdx));

          if (value > lastValue) {
            return true;
          }

          lastValue = value;
        }

        return false;
      };
      /*
       * Consider the case when A and B changed order, whose representing
       * bars are both out of sight, we don't wish to trigger reorder action
       * as long as the order in the view doesn't change.
       */


      BarView.prototype._isOrderDifferentInView = function (orderInfo, baseAxis) {
        var scale = baseAxis.scale;
        var extent = scale.getExtent();
        var tickNum = Math.max(0, extent[0]);
        var tickMax = Math.min(extent[1], scale.getOrdinalMeta().categories.length - 1);

        for (; tickNum <= tickMax; ++tickNum) {
          if (orderInfo.ordinalNumbers[tickNum] !== scale.getRawOrdinalNumber(tickNum)) {
            return true;
          }
        }
      };

      BarView.prototype._updateSortWithinSameData = function (data, orderMapping, baseAxis, api) {
        if (!this._isOrderChangedWithinSameData(data, orderMapping, baseAxis)) {
          return;
        }

        var sortInfo = this._dataSort(data, baseAxis, orderMapping);

        if (this._isOrderDifferentInView(sortInfo, baseAxis)) {
          this._removeOnRenderedListener(api);

          api.dispatchAction({
            type: 'changeAxisOrder',
            componentType: baseAxis.dim + 'Axis',
            axisId: baseAxis.index,
            sortInfo: sortInfo
          });
        }
      };

      BarView.prototype._dispatchInitSort = function (data, realtimeSortCfg, api) {
        var baseAxis = realtimeSortCfg.baseAxis;

        var sortResult = this._dataSort(data, baseAxis, function (dataIdx) {
          return data.get(data.mapDimension(realtimeSortCfg.otherAxis.dim), dataIdx);
        });

        api.dispatchAction({
          type: 'changeAxisOrder',
          componentType: baseAxis.dim + 'Axis',
          isInitSort: true,
          axisId: baseAxis.index,
          sortInfo: sortResult
        });
      };

      BarView.prototype.remove = function (ecModel, api) {
        this._clear(this._model);

        this._removeOnRenderedListener(api);
      };

      BarView.prototype.dispose = function (ecModel, api) {
        this._removeOnRenderedListener(api);
      };

      BarView.prototype._removeOnRenderedListener = function (api) {
        if (this._onRendered) {
          api.getZr().off('rendered', this._onRendered);
          this._onRendered = null;
        }
      };

      BarView.prototype._clear = function (model) {
        var group = this.group;
        var data = this._data;

        if (model && model.isAnimationEnabled() && data && !this._isLargeDraw) {
          this._removeBackground();

          this._backgroundEls = [];
          data.eachItemGraphicEl(function (el) {
            removeElementWithFadeOut(el, model, getECData(el).dataIndex);
          });
        } else {
          group.removeAll();
        }

        this._data = null;
        this._isFirstFrame = true;
      };

      BarView.prototype._removeBackground = function () {
        this.group.remove(this._backgroundGroup);
        this._backgroundGroup = null;
      };

      BarView.type = 'bar';
      return BarView;
    }(ChartView);

    var clip = {
      cartesian2d: function (coordSysBoundingRect, layout) {
        var signWidth = layout.width < 0 ? -1 : 1;
        var signHeight = layout.height < 0 ? -1 : 1; // Needs positive width and height

        if (signWidth < 0) {
          layout.x += layout.width;
          layout.width = -layout.width;
        }

        if (signHeight < 0) {
          layout.y += layout.height;
          layout.height = -layout.height;
        }

        var coordSysX2 = coordSysBoundingRect.x + coordSysBoundingRect.width;
        var coordSysY2 = coordSysBoundingRect.y + coordSysBoundingRect.height;
        var x = mathMax$6(layout.x, coordSysBoundingRect.x);
        var x2 = mathMin$6(layout.x + layout.width, coordSysX2);
        var y = mathMax$6(layout.y, coordSysBoundingRect.y);
        var y2 = mathMin$6(layout.y + layout.height, coordSysY2);
        var xClipped = x2 < x;
        var yClipped = y2 < y; // When xClipped or yClipped, the element will be marked as `ignore`.
        // But we should also place the element at the edge of the coord sys bounding rect.
        // Because if data changed and the bar shows again, its transition animation
        // will begin at this place.

        layout.x = xClipped && x > coordSysX2 ? x2 : x;
        layout.y = yClipped && y > coordSysY2 ? y2 : y;
        layout.width = xClipped ? 0 : x2 - x;
        layout.height = yClipped ? 0 : y2 - y; // Reverse back

        if (signWidth < 0) {
          layout.x += layout.width;
          layout.width = -layout.width;
        }

        if (signHeight < 0) {
          layout.y += layout.height;
          layout.height = -layout.height;
        }

        return xClipped || yClipped;
      },
      polar: function (coordSysClipArea, layout) {
        var signR = layout.r0 <= layout.r ? 1 : -1; // Make sure r is larger than r0

        if (signR < 0) {
          var tmp = layout.r;
          layout.r = layout.r0;
          layout.r0 = tmp;
        }

        var r = mathMin$6(layout.r, coordSysClipArea.r);
        var r0 = mathMax$6(layout.r0, coordSysClipArea.r0);
        layout.r = r;
        layout.r0 = r0;
        var clipped = r - r0 < 0; // Reverse back

        if (signR < 0) {
          var tmp = layout.r;
          layout.r = layout.r0;
          layout.r0 = tmp;
        }

        return clipped;
      }
    };
    var elementCreator = {
      cartesian2d: function (seriesModel, data, newIndex, layout, isHorizontal, animationModel, axisModel, isUpdate, roundCap) {
        var rect = new Rect({
          shape: extend({}, layout),
          z2: 1
        });
        rect.__dataIndex = newIndex;
        rect.name = 'item';

        if (animationModel) {
          var rectShape = rect.shape;
          var animateProperty = isHorizontal ? 'height' : 'width';
          rectShape[animateProperty] = 0;
        }

        return rect;
      },
      polar: function (seriesModel, data, newIndex, layout, isRadial, animationModel, axisModel, isUpdate, roundCap) {
        var ShapeClass = !isRadial && roundCap ? SausagePath : Sector;
        var sector = new ShapeClass({
          shape: layout,
          z2: 1
        });
        sector.name = 'item';
        var positionMap = createPolarPositionMapping(isRadial);
        sector.calculateTextPosition = createSectorCalculateTextPosition(positionMap, {
          isRoundCap: ShapeClass === SausagePath
        }); // Animation

        if (animationModel) {
          var sectorShape = sector.shape;
          var animateProperty = isRadial ? 'r' : 'endAngle';
          var animateTarget = {};
          sectorShape[animateProperty] = isRadial ? 0 : layout.startAngle;
          animateTarget[animateProperty] = layout[animateProperty];
          (isUpdate ? updateProps : initProps)(sector, {
            shape: animateTarget // __value: typeof dataValue === 'string' ? parseInt(dataValue, 10) : dataValue

          }, animationModel);
        }

        return sector;
      }
    };

    function shouldRealtimeSort(seriesModel, coordSys) {
      var realtimeSortOption = seriesModel.get('realtimeSort', true);
      var baseAxis = coordSys.getBaseAxis();

      if ("development" !== 'production') {
        if (realtimeSortOption) {
          if (baseAxis.type !== 'category') {
            warn('`realtimeSort` will not work because this bar series is not based on a category axis.');
          }

          if (coordSys.type !== 'cartesian2d') {
            warn('`realtimeSort` will not work because this bar series is not on cartesian2d.');
          }
        }
      }

      if (realtimeSortOption && baseAxis.type === 'category' && coordSys.type === 'cartesian2d') {
        return {
          baseAxis: baseAxis,
          otherAxis: coordSys.getOtherAxis(baseAxis)
        };
      }
    }

    function updateRealtimeAnimation(realtimeSortCfg, seriesAnimationModel, el, layout, newIndex, isHorizontal, isUpdate, isChangeOrder) {
      var seriesTarget;
      var axisTarget;

      if (isHorizontal) {
        axisTarget = {
          x: layout.x,
          width: layout.width
        };
        seriesTarget = {
          y: layout.y,
          height: layout.height
        };
      } else {
        axisTarget = {
          y: layout.y,
          height: layout.height
        };
        seriesTarget = {
          x: layout.x,
          width: layout.width
        };
      }

      if (!isChangeOrder) {
        // Keep the original growth animation if only axis order changed.
        // Not start a new animation.
        (isUpdate ? updateProps : initProps)(el, {
          shape: seriesTarget
        }, seriesAnimationModel, newIndex, null);
      }

      var axisAnimationModel = seriesAnimationModel ? realtimeSortCfg.baseAxis.model : null;
      (isUpdate ? updateProps : initProps)(el, {
        shape: axisTarget
      }, axisAnimationModel, newIndex);
    }

    function checkPropertiesNotValid(obj, props) {
      for (var i = 0; i < props.length; i++) {
        if (!isFinite(obj[props[i]])) {
          return true;
        }
      }

      return false;
    }

    var rectPropties = ['x', 'y', 'width', 'height'];
    var polarPropties = ['cx', 'cy', 'r', 'startAngle', 'endAngle'];
    var isValidLayout = {
      cartesian2d: function (layout) {
        return !checkPropertiesNotValid(layout, rectPropties);
      },
      polar: function (layout) {
        return !checkPropertiesNotValid(layout, polarPropties);
      }
    };
    var getLayout = {
      // itemModel is only used to get borderWidth, which is not needed
      // when calculating bar background layout.
      cartesian2d: function (data, dataIndex, itemModel) {
        var layout = data.getItemLayout(dataIndex);
        var fixedLineWidth = itemModel ? getLineWidth(itemModel, layout) : 0; // fix layout with lineWidth

        var signX = layout.width > 0 ? 1 : -1;
        var signY = layout.height > 0 ? 1 : -1;
        return {
          x: layout.x + signX * fixedLineWidth / 2,
          y: layout.y + signY * fixedLineWidth / 2,
          width: layout.width - signX * fixedLineWidth,
          height: layout.height - signY * fixedLineWidth
        };
      },
      polar: function (data, dataIndex, itemModel) {
        var layout = data.getItemLayout(dataIndex);
        return {
          cx: layout.cx,
          cy: layout.cy,
          r0: layout.r0,
          r: layout.r,
          startAngle: layout.startAngle,
          endAngle: layout.endAngle,
          clockwise: layout.clockwise
        };
      }
    };

    function isZeroOnPolar(layout) {
      return layout.startAngle != null && layout.endAngle != null && layout.startAngle === layout.endAngle;
    }

    function createPolarPositionMapping(isRadial) {
      return function (isRadial) {
        var arcOrAngle = isRadial ? 'Arc' : 'Angle';
        return function (position) {
          switch (position) {
            case 'start':
            case 'insideStart':
            case 'end':
            case 'insideEnd':
              return position + arcOrAngle;

            default:
              return position;
          }
        };
      }(isRadial);
    }

    function updateStyle(el, data, dataIndex, itemModel, layout, seriesModel, isHorizontalOrRadial, isPolar) {
      var style = data.getItemVisual(dataIndex, 'style');

      if (!isPolar) {
        el.setShape('r', itemModel.get(['itemStyle', 'borderRadius']) || 0);
      }

      el.useStyle(style);
      var cursorStyle = itemModel.getShallow('cursor');
      cursorStyle && el.attr('cursor', cursorStyle);
      var labelPositionOutside = isPolar ? isHorizontalOrRadial ? layout.r >= layout.r0 ? 'endArc' : 'startArc' : layout.endAngle >= layout.startAngle ? 'endAngle' : 'startAngle' : isHorizontalOrRadial ? layout.height >= 0 ? 'bottom' : 'top' : layout.width >= 0 ? 'right' : 'left';
      var labelStatesModels = getLabelStatesModels(itemModel);
      setLabelStyle(el, labelStatesModels, {
        labelFetcher: seriesModel,
        labelDataIndex: dataIndex,
        defaultText: getDefaultLabel(seriesModel.getData(), dataIndex),
        inheritColor: style.fill,
        defaultOpacity: style.opacity,
        defaultOutsidePosition: labelPositionOutside
      });
      var label = el.getTextContent();

      if (isPolar && label) {
        var position = itemModel.get(['label', 'position']);
        el.textConfig.inside = position === 'middle' ? true : null;
        setSectorTextRotation(el, position === 'outside' ? labelPositionOutside : position, createPolarPositionMapping(isHorizontalOrRadial), itemModel.get(['label', 'rotate']));
      }

      setLabelValueAnimation(label, labelStatesModels, seriesModel.getRawValue(dataIndex), function (value) {
        return getDefaultInterpolatedLabel(data, value);
      });
      var emphasisModel = itemModel.getModel(['emphasis']);
      toggleHoverEmphasis(el, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
      setStatesStylesFromModel(el, itemModel);

      if (isZeroOnPolar(layout)) {
        el.style.fill = 'none';
        el.style.stroke = 'none';
        each(el.states, function (state) {
          if (state.style) {
            state.style.fill = state.style.stroke = 'none';
          }
        });
      }
    } // In case width or height are too small.


    function getLineWidth(itemModel, rawLayout) {
      // Has no border.
      var borderColor = itemModel.get(['itemStyle', 'borderColor']);

      if (!borderColor || borderColor === 'none') {
        return 0;
      }

      var lineWidth = itemModel.get(['itemStyle', 'borderWidth']) || 0; // width or height may be NaN for empty data

      var width = isNaN(rawLayout.width) ? Number.MAX_VALUE : Math.abs(rawLayout.width);
      var height = isNaN(rawLayout.height) ? Number.MAX_VALUE : Math.abs(rawLayout.height);
      return Math.min(lineWidth, width, height);
    }

    var LagePathShape =
    /** @class */
    function () {
      function LagePathShape() {}

      return LagePathShape;
    }();

    var LargePath =
    /** @class */
    function (_super) {
      __extends(LargePath, _super);

      function LargePath(opts) {
        var _this = _super.call(this, opts) || this;

        _this.type = 'largeBar';
        return _this;
      }

      LargePath.prototype.getDefaultShape = function () {
        return new LagePathShape();
      };

      LargePath.prototype.buildPath = function (ctx, shape) {
        // Drawing lines is more efficient than drawing
        // a whole line or drawing rects.
        var points = shape.points;
        var baseDimIdx = this.baseDimIdx;
        var valueDimIdx = 1 - this.baseDimIdx;
        var startPoint = [];
        var size = [];
        var barWidth = this.barWidth;

        for (var i = 0; i < points.length; i += 3) {
          size[baseDimIdx] = barWidth;
          size[valueDimIdx] = points[i + 2];
          startPoint[baseDimIdx] = points[i + baseDimIdx];
          startPoint[valueDimIdx] = points[i + valueDimIdx];
          ctx.rect(startPoint[0], startPoint[1], size[0], size[1]);
        }
      };

      return LargePath;
    }(Path);

    function createLarge(seriesModel, group, progressiveEls, incremental) {
      // TODO support polar
      var data = seriesModel.getData();
      var baseDimIdx = data.getLayout('valueAxisHorizontal') ? 1 : 0;
      var largeDataIndices = data.getLayout('largeDataIndices');
      var barWidth = data.getLayout('size');
      var backgroundModel = seriesModel.getModel('backgroundStyle');
      var bgPoints = data.getLayout('largeBackgroundPoints');

      if (bgPoints) {
        var bgEl = new LargePath({
          shape: {
            points: bgPoints
          },
          incremental: !!incremental,
          silent: true,
          z2: 0
        });
        bgEl.baseDimIdx = baseDimIdx;
        bgEl.largeDataIndices = largeDataIndices;
        bgEl.barWidth = barWidth;
        bgEl.useStyle(backgroundModel.getItemStyle());
        group.add(bgEl);
        progressiveEls && progressiveEls.push(bgEl);
      }

      var el = new LargePath({
        shape: {
          points: data.getLayout('largePoints')
        },
        incremental: !!incremental,
        ignoreCoarsePointer: true,
        z2: 1
      });
      el.baseDimIdx = baseDimIdx;
      el.largeDataIndices = largeDataIndices;
      el.barWidth = barWidth;
      group.add(el);
      el.useStyle(data.getVisual('style')); // Enable tooltip and user mouse/touch event handlers.

      getECData(el).seriesIndex = seriesModel.seriesIndex;

      if (!seriesModel.get('silent')) {
        el.on('mousedown', largePathUpdateDataIndex);
        el.on('mousemove', largePathUpdateDataIndex);
      }

      progressiveEls && progressiveEls.push(el);
    } // Use throttle to avoid frequently traverse to find dataIndex.


    var largePathUpdateDataIndex = throttle(function (event) {
      var largePath = this;
      var dataIndex = largePathFindDataIndex(largePath, event.offsetX, event.offsetY);
      getECData(largePath).dataIndex = dataIndex >= 0 ? dataIndex : null;
    }, 30, false);

    function largePathFindDataIndex(largePath, x, y) {
      var baseDimIdx = largePath.baseDimIdx;
      var valueDimIdx = 1 - baseDimIdx;
      var points = largePath.shape.points;
      var largeDataIndices = largePath.largeDataIndices;
      var startPoint = [];
      var size = [];
      var barWidth = largePath.barWidth;

      for (var i = 0, len = points.length / 3; i < len; i++) {
        var ii = i * 3;
        size[baseDimIdx] = barWidth;
        size[valueDimIdx] = points[ii + 2];
        startPoint[baseDimIdx] = points[ii + baseDimIdx];
        startPoint[valueDimIdx] = points[ii + valueDimIdx];

        if (size[valueDimIdx] < 0) {
          startPoint[valueDimIdx] += size[valueDimIdx];
          size[valueDimIdx] = -size[valueDimIdx];
        }

        if (x >= startPoint[0] && x <= startPoint[0] + size[0] && y >= startPoint[1] && y <= startPoint[1] + size[1]) {
          return largeDataIndices[i];
        }
      }

      return -1;
    }

    function createBackgroundShape(isHorizontalOrRadial, layout, coord) {
      if (isCoordinateSystemType(coord, 'cartesian2d')) {
        var rectShape = layout;
        var coordLayout = coord.getArea();
        return {
          x: isHorizontalOrRadial ? rectShape.x : coordLayout.x,
          y: isHorizontalOrRadial ? coordLayout.y : rectShape.y,
          width: isHorizontalOrRadial ? rectShape.width : coordLayout.width,
          height: isHorizontalOrRadial ? coordLayout.height : rectShape.height
        };
      } else {
        var coordLayout = coord.getArea();
        var sectorShape = layout;
        return {
          cx: coordLayout.cx,
          cy: coordLayout.cy,
          r0: isHorizontalOrRadial ? coordLayout.r0 : sectorShape.r0,
          r: isHorizontalOrRadial ? coordLayout.r : sectorShape.r,
          startAngle: isHorizontalOrRadial ? sectorShape.startAngle : 0,
          endAngle: isHorizontalOrRadial ? sectorShape.endAngle : Math.PI * 2
        };
      }
    }

    function createBackgroundEl(coord, isHorizontalOrRadial, layout) {
      var ElementClz = coord.type === 'polar' ? Sector : Rect;
      return new ElementClz({
        shape: createBackgroundShape(isHorizontalOrRadial, layout, coord),
        silent: true,
        z2: 0
      });
    }

    function install$2(registers) {
      registers.registerChartView(BarView);
      registers.registerSeriesModel(BarSeriesModel);
      registers.registerLayout(registers.PRIORITY.VISUAL.LAYOUT, curry(layout, 'bar')); // Do layout after other overall layout, which can prepare some information.

      registers.registerLayout(registers.PRIORITY.VISUAL.PROGRESSIVE_LAYOUT, createProgressiveLayout('bar')); // Down sample after filter

      registers.registerProcessor(registers.PRIORITY.PROCESSOR.STATISTIC, dataSample('bar'));
      /**
       * @payload
       * @property {string} [componentType=series]
       * @property {number} [dx]
       * @property {number} [dy]
       * @property {number} [zoom]
       * @property {number} [originX]
       * @property {number} [originY]
       */

      registers.registerAction({
        type: 'changeAxisOrder',
        event: 'changeAxisOrder',
        update: 'update'
      }, function (payload, ecModel) {
        var componentType = payload.componentType || 'series';
        ecModel.eachComponent({
          mainType: componentType,
          query: payload
        }, function (componentModel) {
          if (payload.sortInfo) {
            componentModel.axis.setCategorySortInfo(payload.sortInfo);
          }
        });
      });
    }

    var PI2$6 = Math.PI * 2;
    var RADIAN = Math.PI / 180;

    function getViewRect(seriesModel, api) {
      return getLayoutRect(seriesModel.getBoxLayoutParams(), {
        width: api.getWidth(),
        height: api.getHeight()
      });
    }

    function getBasicPieLayout(seriesModel, api) {
      var viewRect = getViewRect(seriesModel, api); // center can be string or number when coordinateSystem is specified

      var center = seriesModel.get('center');
      var radius = seriesModel.get('radius');

      if (!isArray(radius)) {
        radius = [0, radius];
      }

      var width = parsePercent$1(viewRect.width, api.getWidth());
      var height = parsePercent$1(viewRect.height, api.getHeight());
      var size = Math.min(width, height);
      var r0 = parsePercent$1(radius[0], size / 2);
      var r = parsePercent$1(radius[1], size / 2);
      var cx;
      var cy;
      var coordSys = seriesModel.coordinateSystem;

      if (coordSys) {
        // percentage is not allowed when coordinate system is specified
        var point = coordSys.dataToPoint(center);
        cx = point[0] || 0;
        cy = point[1] || 0;
      } else {
        if (!isArray(center)) {
          center = [center, center];
        }

        cx = parsePercent$1(center[0], width) + viewRect.x;
        cy = parsePercent$1(center[1], height) + viewRect.y;
      }

      return {
        cx: cx,
        cy: cy,
        r0: r0,
        r: r
      };
    }
    function pieLayout(seriesType, ecModel, api) {
      ecModel.eachSeriesByType(seriesType, function (seriesModel) {
        var data = seriesModel.getData();
        var valueDim = data.mapDimension('value');
        var viewRect = getViewRect(seriesModel, api);

        var _a = getBasicPieLayout(seriesModel, api),
            cx = _a.cx,
            cy = _a.cy,
            r = _a.r,
            r0 = _a.r0;

        var startAngle = -seriesModel.get('startAngle') * RADIAN;
        var minAngle = seriesModel.get('minAngle') * RADIAN;
        var validDataCount = 0;
        data.each(valueDim, function (value) {
          !isNaN(value) && validDataCount++;
        });
        var sum = data.getSum(valueDim); // Sum may be 0

        var unitRadian = Math.PI / (sum || validDataCount) * 2;
        var clockwise = seriesModel.get('clockwise');
        var roseType = seriesModel.get('roseType');
        var stillShowZeroSum = seriesModel.get('stillShowZeroSum'); // [0...max]

        var extent = data.getDataExtent(valueDim);
        extent[0] = 0; // In the case some sector angle is smaller than minAngle

        var restAngle = PI2$6;
        var valueSumLargerThanMinAngle = 0;
        var currentAngle = startAngle;
        var dir = clockwise ? 1 : -1;
        data.setLayout({
          viewRect: viewRect,
          r: r
        });
        data.each(valueDim, function (value, idx) {
          var angle;

          if (isNaN(value)) {
            data.setItemLayout(idx, {
              angle: NaN,
              startAngle: NaN,
              endAngle: NaN,
              clockwise: clockwise,
              cx: cx,
              cy: cy,
              r0: r0,
              r: roseType ? NaN : r
            });
            return;
          } // FIXME 兼容 2.0 但是 roseType 是 area 的时候才是这样？


          if (roseType !== 'area') {
            angle = sum === 0 && stillShowZeroSum ? unitRadian : value * unitRadian;
          } else {
            angle = PI2$6 / validDataCount;
          }

          if (angle < minAngle) {
            angle = minAngle;
            restAngle -= minAngle;
          } else {
            valueSumLargerThanMinAngle += value;
          }

          var endAngle = currentAngle + dir * angle;
          data.setItemLayout(idx, {
            angle: angle,
            startAngle: currentAngle,
            endAngle: endAngle,
            clockwise: clockwise,
            cx: cx,
            cy: cy,
            r0: r0,
            r: roseType ? linearMap(value, extent, [r0, r]) : r
          });
          currentAngle = endAngle;
        }); // Some sector is constrained by minAngle
        // Rest sectors needs recalculate angle

        if (restAngle < PI2$6 && validDataCount) {
          // Average the angle if rest angle is not enough after all angles is
          // Constrained by minAngle
          if (restAngle <= 1e-3) {
            var angle_1 = PI2$6 / validDataCount;
            data.each(valueDim, function (value, idx) {
              if (!isNaN(value)) {
                var layout_1 = data.getItemLayout(idx);
                layout_1.angle = angle_1;
                layout_1.startAngle = startAngle + dir * idx * angle_1;
                layout_1.endAngle = startAngle + dir * (idx + 1) * angle_1;
              }
            });
          } else {
            unitRadian = restAngle / valueSumLargerThanMinAngle;
            currentAngle = startAngle;
            data.each(valueDim, function (value, idx) {
              if (!isNaN(value)) {
                var layout_2 = data.getItemLayout(idx);
                var angle = layout_2.angle === minAngle ? minAngle : value * unitRadian;
                layout_2.startAngle = currentAngle;
                layout_2.endAngle = currentAngle + dir * angle;
                currentAngle += dir * angle;
              }
            });
          }
        }
      });
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    function dataFilter(seriesType) {
      return {
        seriesType: seriesType,
        reset: function (seriesModel, ecModel) {
          var legendModels = ecModel.findComponents({
            mainType: 'legend'
          });

          if (!legendModels || !legendModels.length) {
            return;
          }

          var data = seriesModel.getData();
          data.filterSelf(function (idx) {
            var name = data.getName(idx); // If in any legend component the status is not selected.

            for (var i = 0; i < legendModels.length; i++) {
              // @ts-ignore FIXME: LegendModel
              if (!legendModels[i].isSelected(name)) {
                return false;
              }
            }

            return true;
          });
        }
      };
    }

    var RADIAN$1 = Math.PI / 180;

    function adjustSingleSide(list, cx, cy, r, dir, viewWidth, viewHeight, viewLeft, viewTop, farthestX) {
      if (list.length < 2) {
        return;
      }

      function recalculateXOnSemiToAlignOnEllipseCurve(semi) {
        var rB = semi.rB;
        var rB2 = rB * rB;

        for (var i = 0; i < semi.list.length; i++) {
          var item = semi.list[i];
          var dy = Math.abs(item.label.y - cy); // horizontal r is always same with original r because x is not changed.

          var rA = r + item.len;
          var rA2 = rA * rA; // Use ellipse implicit function to calculate x

          var dx = Math.sqrt((1 - Math.abs(dy * dy / rB2)) * rA2);
          var newX = cx + (dx + item.len2) * dir;
          var deltaX = newX - item.label.x;
          var newTargetWidth = item.targetTextWidth - deltaX * dir; // text x is changed, so need to recalculate width.

          constrainTextWidth(item, newTargetWidth, true);
          item.label.x = newX;
        }
      } // Adjust X based on the shifted y. Make tight labels aligned on an ellipse curve.


      function recalculateX(items) {
        // Extremes of
        var topSemi = {
          list: [],
          maxY: 0
        };
        var bottomSemi = {
          list: [],
          maxY: 0
        };

        for (var i = 0; i < items.length; i++) {
          if (items[i].labelAlignTo !== 'none') {
            continue;
          }

          var item = items[i];
          var semi = item.label.y > cy ? bottomSemi : topSemi;
          var dy = Math.abs(item.label.y - cy);

          if (dy >= semi.maxY) {
            var dx = item.label.x - cx - item.len2 * dir; // horizontal r is always same with original r because x is not changed.

            var rA = r + item.len; // Canculate rB based on the topest / bottemest label.

            var rB = Math.abs(dx) < rA ? Math.sqrt(dy * dy / (1 - dx * dx / rA / rA)) : rA;
            semi.rB = rB;
            semi.maxY = dy;
          }

          semi.list.push(item);
        }

        recalculateXOnSemiToAlignOnEllipseCurve(topSemi);
        recalculateXOnSemiToAlignOnEllipseCurve(bottomSemi);
      }

      var len = list.length;

      for (var i = 0; i < len; i++) {
        if (list[i].position === 'outer' && list[i].labelAlignTo === 'labelLine') {
          var dx = list[i].label.x - farthestX;
          list[i].linePoints[1][0] += dx;
          list[i].label.x = farthestX;
        }
      }

      if (shiftLayoutOnY(list, viewTop, viewTop + viewHeight)) {
        recalculateX(list);
      }
    }

    function avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight, viewLeft, viewTop) {
      var leftList = [];
      var rightList = [];
      var leftmostX = Number.MAX_VALUE;
      var rightmostX = -Number.MAX_VALUE;

      for (var i = 0; i < labelLayoutList.length; i++) {
        var label = labelLayoutList[i].label;

        if (isPositionCenter(labelLayoutList[i])) {
          continue;
        }

        if (label.x < cx) {
          leftmostX = Math.min(leftmostX, label.x);
          leftList.push(labelLayoutList[i]);
        } else {
          rightmostX = Math.max(rightmostX, label.x);
          rightList.push(labelLayoutList[i]);
        }
      }

      for (var i = 0; i < labelLayoutList.length; i++) {
        var layout = labelLayoutList[i];

        if (!isPositionCenter(layout) && layout.linePoints) {
          if (layout.labelStyleWidth != null) {
            continue;
          }

          var label = layout.label;
          var linePoints = layout.linePoints;
          var targetTextWidth = void 0;

          if (layout.labelAlignTo === 'edge') {
            if (label.x < cx) {
              targetTextWidth = linePoints[2][0] - layout.labelDistance - viewLeft - layout.edgeDistance;
            } else {
              targetTextWidth = viewLeft + viewWidth - layout.edgeDistance - linePoints[2][0] - layout.labelDistance;
            }
          } else if (layout.labelAlignTo === 'labelLine') {
            if (label.x < cx) {
              targetTextWidth = leftmostX - viewLeft - layout.bleedMargin;
            } else {
              targetTextWidth = viewLeft + viewWidth - rightmostX - layout.bleedMargin;
            }
          } else {
            if (label.x < cx) {
              targetTextWidth = label.x - viewLeft - layout.bleedMargin;
            } else {
              targetTextWidth = viewLeft + viewWidth - label.x - layout.bleedMargin;
            }
          }

          layout.targetTextWidth = targetTextWidth;
          constrainTextWidth(layout, targetTextWidth);
        }
      }

      adjustSingleSide(rightList, cx, cy, r, 1, viewWidth, viewHeight, viewLeft, viewTop, rightmostX);
      adjustSingleSide(leftList, cx, cy, r, -1, viewWidth, viewHeight, viewLeft, viewTop, leftmostX);

      for (var i = 0; i < labelLayoutList.length; i++) {
        var layout = labelLayoutList[i];

        if (!isPositionCenter(layout) && layout.linePoints) {
          var label = layout.label;
          var linePoints = layout.linePoints;
          var isAlignToEdge = layout.labelAlignTo === 'edge';
          var padding = label.style.padding;
          var paddingH = padding ? padding[1] + padding[3] : 0; // textRect.width already contains paddingH if bgColor is set

          var extraPaddingH = label.style.backgroundColor ? 0 : paddingH;
          var realTextWidth = layout.rect.width + extraPaddingH;
          var dist = linePoints[1][0] - linePoints[2][0];

          if (isAlignToEdge) {
            if (label.x < cx) {
              linePoints[2][0] = viewLeft + layout.edgeDistance + realTextWidth + layout.labelDistance;
            } else {
              linePoints[2][0] = viewLeft + viewWidth - layout.edgeDistance - realTextWidth - layout.labelDistance;
            }
          } else {
            if (label.x < cx) {
              linePoints[2][0] = label.x + layout.labelDistance;
            } else {
              linePoints[2][0] = label.x - layout.labelDistance;
            }

            linePoints[1][0] = linePoints[2][0] + dist;
          }

          linePoints[1][1] = linePoints[2][1] = label.y;
        }
      }
    }
    /**
     * Set max width of each label, and then wrap each label to the max width.
     *
     * @param layout label layout
     * @param availableWidth max width for the label to display
     * @param forceRecalculate recaculate the text layout even if the current width
     * is smaller than `availableWidth`. This is useful when the text was previously
     * wrapped by calling `constrainTextWidth` but now `availableWidth` changed, in
     * which case, previous wrapping should be redo.
     */


    function constrainTextWidth(layout, availableWidth, forceRecalculate) {
      if (forceRecalculate === void 0) {
        forceRecalculate = false;
      }

      if (layout.labelStyleWidth != null) {
        // User-defined style.width has the highest priority.
        return;
      }

      var label = layout.label;
      var style = label.style;
      var textRect = layout.rect;
      var bgColor = style.backgroundColor;
      var padding = style.padding;
      var paddingH = padding ? padding[1] + padding[3] : 0;
      var overflow = style.overflow; // textRect.width already contains paddingH if bgColor is set

      var oldOuterWidth = textRect.width + (bgColor ? 0 : paddingH);

      if (availableWidth < oldOuterWidth || forceRecalculate) {
        var oldHeight = textRect.height;

        if (overflow && overflow.match('break')) {
          // Temporarily set background to be null to calculate
          // the bounding box without background.
          label.setStyle('backgroundColor', null); // Set constraining width

          label.setStyle('width', availableWidth - paddingH); // This is the real bounding box of the text without padding.

          var innerRect = label.getBoundingRect();
          label.setStyle('width', Math.ceil(innerRect.width));
          label.setStyle('backgroundColor', bgColor);
        } else {
          var availableInnerWidth = availableWidth - paddingH;
          var newWidth = availableWidth < oldOuterWidth // Current text is too wide, use `availableWidth` as max width.
          ? availableInnerWidth : // Current available width is enough, but the text may have
          // already been wrapped with a smaller available width.
          forceRecalculate ? availableInnerWidth > layout.unconstrainedWidth // Current available is larger than text width,
          // so don't constrain width (otherwise it may have
          // empty space in the background).
          ? null // Current available is smaller than text width, so
          // use the current available width as constraining
          // width.
          : availableInnerWidth : // Current available width is enough, so no need to
          // constrain.
          null;
          label.setStyle('width', newWidth);
        }

        var newRect = label.getBoundingRect();
        textRect.width = newRect.width;
        var margin = (label.style.margin || 0) + 2.1;
        textRect.height = newRect.height + margin;
        textRect.y -= (textRect.height - oldHeight) / 2;
      }
    }

    function isPositionCenter(sectorShape) {
      // Not change x for center label
      return sectorShape.position === 'center';
    }

    function pieLabelLayout(seriesModel) {
      var data = seriesModel.getData();
      var labelLayoutList = [];
      var cx;
      var cy;
      var hasLabelRotate = false;
      var minShowLabelRadian = (seriesModel.get('minShowLabelAngle') || 0) * RADIAN$1;
      var viewRect = data.getLayout('viewRect');
      var r = data.getLayout('r');
      var viewWidth = viewRect.width;
      var viewLeft = viewRect.x;
      var viewTop = viewRect.y;
      var viewHeight = viewRect.height;

      function setNotShow(el) {
        el.ignore = true;
      }

      function isLabelShown(label) {
        if (!label.ignore) {
          return true;
        }

        for (var key in label.states) {
          if (label.states[key].ignore === false) {
            return true;
          }
        }

        return false;
      }

      data.each(function (idx) {
        var sector = data.getItemGraphicEl(idx);
        var sectorShape = sector.shape;
        var label = sector.getTextContent();
        var labelLine = sector.getTextGuideLine();
        var itemModel = data.getItemModel(idx);
        var labelModel = itemModel.getModel('label'); // Use position in normal or emphasis

        var labelPosition = labelModel.get('position') || itemModel.get(['emphasis', 'label', 'position']);
        var labelDistance = labelModel.get('distanceToLabelLine');
        var labelAlignTo = labelModel.get('alignTo');
        var edgeDistance = parsePercent$1(labelModel.get('edgeDistance'), viewWidth);
        var bleedMargin = labelModel.get('bleedMargin');
        var labelLineModel = itemModel.getModel('labelLine');
        var labelLineLen = labelLineModel.get('length');
        labelLineLen = parsePercent$1(labelLineLen, viewWidth);
        var labelLineLen2 = labelLineModel.get('length2');
        labelLineLen2 = parsePercent$1(labelLineLen2, viewWidth);

        if (Math.abs(sectorShape.endAngle - sectorShape.startAngle) < minShowLabelRadian) {
          each(label.states, setNotShow);
          label.ignore = true;

          if (labelLine) {
            each(labelLine.states, setNotShow);
            labelLine.ignore = true;
          }

          return;
        }

        if (!isLabelShown(label)) {
          return;
        }

        var midAngle = (sectorShape.startAngle + sectorShape.endAngle) / 2;
        var nx = Math.cos(midAngle);
        var ny = Math.sin(midAngle);
        var textX;
        var textY;
        var linePoints;
        var textAlign;
        cx = sectorShape.cx;
        cy = sectorShape.cy;
        var isLabelInside = labelPosition === 'inside' || labelPosition === 'inner';

        if (labelPosition === 'center') {
          textX = sectorShape.cx;
          textY = sectorShape.cy;
          textAlign = 'center';
        } else {
          var x1 = (isLabelInside ? (sectorShape.r + sectorShape.r0) / 2 * nx : sectorShape.r * nx) + cx;
          var y1 = (isLabelInside ? (sectorShape.r + sectorShape.r0) / 2 * ny : sectorShape.r * ny) + cy;
          textX = x1 + nx * 3;
          textY = y1 + ny * 3;

          if (!isLabelInside) {
            // For roseType
            var x2 = x1 + nx * (labelLineLen + r - sectorShape.r);
            var y2 = y1 + ny * (labelLineLen + r - sectorShape.r);
            var x3 = x2 + (nx < 0 ? -1 : 1) * labelLineLen2;
            var y3 = y2;

            if (labelAlignTo === 'edge') {
              // Adjust textX because text align of edge is opposite
              textX = nx < 0 ? viewLeft + edgeDistance : viewLeft + viewWidth - edgeDistance;
            } else {
              textX = x3 + (nx < 0 ? -labelDistance : labelDistance);
            }

            textY = y3;
            linePoints = [[x1, y1], [x2, y2], [x3, y3]];
          }

          textAlign = isLabelInside ? 'center' : labelAlignTo === 'edge' ? nx > 0 ? 'right' : 'left' : nx > 0 ? 'left' : 'right';
        }

        var PI = Math.PI;
        var labelRotate = 0;
        var rotate = labelModel.get('rotate');

        if (isNumber(rotate)) {
          labelRotate = rotate * (PI / 180);
        } else if (labelPosition === 'center') {
          labelRotate = 0;
        } else if (rotate === 'radial' || rotate === true) {
          var radialAngle = nx < 0 ? -midAngle + PI : -midAngle;
          labelRotate = radialAngle;
        } else if (rotate === 'tangential' && labelPosition !== 'outside' && labelPosition !== 'outer') {
          var rad = Math.atan2(nx, ny);

          if (rad < 0) {
            rad = PI * 2 + rad;
          }

          var isDown = ny > 0;

          if (isDown) {
            rad = PI + rad;
          }

          labelRotate = rad - PI;
        }

        hasLabelRotate = !!labelRotate;
        label.x = textX;
        label.y = textY;
        label.rotation = labelRotate;
        label.setStyle({
          verticalAlign: 'middle'
        }); // Not sectorShape the inside label

        if (!isLabelInside) {
          var textRect = label.getBoundingRect().clone();
          textRect.applyTransform(label.getComputedTransform()); // Text has a default 1px stroke. Exclude this.

          var margin = (label.style.margin || 0) + 2.1;
          textRect.y -= margin / 2;
          textRect.height += margin;
          labelLayoutList.push({
            label: label,
            labelLine: labelLine,
            position: labelPosition,
            len: labelLineLen,
            len2: labelLineLen2,
            minTurnAngle: labelLineModel.get('minTurnAngle'),
            maxSurfaceAngle: labelLineModel.get('maxSurfaceAngle'),
            surfaceNormal: new Point(nx, ny),
            linePoints: linePoints,
            textAlign: textAlign,
            labelDistance: labelDistance,
            labelAlignTo: labelAlignTo,
            edgeDistance: edgeDistance,
            bleedMargin: bleedMargin,
            rect: textRect,
            unconstrainedWidth: textRect.width,
            labelStyleWidth: label.style.width
          });
        } else {
          label.setStyle({
            align: textAlign
          });
          var selectState = label.states.select;

          if (selectState) {
            selectState.x += label.x;
            selectState.y += label.y;
          }
        }

        sector.setTextConfig({
          inside: isLabelInside
        });
      });

      if (!hasLabelRotate && seriesModel.get('avoidLabelOverlap')) {
        avoidOverlap(labelLayoutList, cx, cy, r, viewWidth, viewHeight, viewLeft, viewTop);
      }

      for (var i = 0; i < labelLayoutList.length; i++) {
        var layout = labelLayoutList[i];
        var label = layout.label;
        var labelLine = layout.labelLine;
        var notShowLabel = isNaN(label.x) || isNaN(label.y);

        if (label) {
          label.setStyle({
            align: layout.textAlign
          });

          if (notShowLabel) {
            each(label.states, setNotShow);
            label.ignore = true;
          }

          var selectState = label.states.select;

          if (selectState) {
            selectState.x += label.x;
            selectState.y += label.y;
          }
        }

        if (labelLine) {
          var linePoints = layout.linePoints;

          if (notShowLabel || !linePoints) {
            each(labelLine.states, setNotShow);
            labelLine.ignore = true;
          } else {
            limitTurnAngle(linePoints, layout.minTurnAngle);
            limitSurfaceAngle(linePoints, layout.surfaceNormal, layout.maxSurfaceAngle);
            labelLine.setShape({
              points: linePoints
            }); // Set the anchor to the midpoint of sector

            label.__hostTarget.textGuideLineConfig = {
              anchor: new Point(linePoints[0][0], linePoints[0][1])
            };
          }
        }
      }
    }

    function getSectorCornerRadius(model, shape, zeroIfNull) {
      var cornerRadius = model.get('borderRadius');

      if (cornerRadius == null) {
        return zeroIfNull ? {
          cornerRadius: 0
        } : null;
      }

      if (!isArray(cornerRadius)) {
        cornerRadius = [cornerRadius, cornerRadius, cornerRadius, cornerRadius];
      }

      var dr = Math.abs(shape.r || 0 - shape.r0 || 0);
      return {
        cornerRadius: map(cornerRadius, function (cr) {
          return parsePercent(cr, dr);
        })
      };
    }

    /**
     * Piece of pie including Sector, Label, LabelLine
     */

    var PiePiece =
    /** @class */
    function (_super) {
      __extends(PiePiece, _super);

      function PiePiece(data, idx, startAngle) {
        var _this = _super.call(this) || this;

        _this.z2 = 2;
        var text = new ZRText();

        _this.setTextContent(text);

        _this.updateData(data, idx, startAngle, true);

        return _this;
      }

      PiePiece.prototype.updateData = function (data, idx, startAngle, firstCreate) {
        var sector = this;
        var seriesModel = data.hostModel;
        var itemModel = data.getItemModel(idx);
        var emphasisModel = itemModel.getModel('emphasis');
        var layout = data.getItemLayout(idx); // cornerRadius & innerCornerRadius doesn't exist in the item layout. Use `0` if null value is specified.
        // see `setItemLayout` in `pieLayout.ts`.

        var sectorShape = extend(getSectorCornerRadius(itemModel.getModel('itemStyle'), layout, true), layout); // Ignore NaN data.

        if (isNaN(sectorShape.startAngle)) {
          // Use NaN shape to avoid drawing shape.
          sector.setShape(sectorShape);
          return;
        }

        if (firstCreate) {
          sector.setShape(sectorShape);
          var animationType = seriesModel.getShallow('animationType');

          if (seriesModel.ecModel.ssr) {
            // Use scale animation in SSR mode(opacity?)
            // Because CSS SVG animation doesn't support very customized shape animation.
            initProps(sector, {
              scaleX: 0,
              scaleY: 0
            }, seriesModel, {
              dataIndex: idx,
              isFrom: true
            });
            sector.originX = sectorShape.cx;
            sector.originY = sectorShape.cy;
          } else if (animationType === 'scale') {
            sector.shape.r = layout.r0;
            initProps(sector, {
              shape: {
                r: layout.r
              }
            }, seriesModel, idx);
          } // Expansion
          else {
              if (startAngle != null) {
                sector.setShape({
                  startAngle: startAngle,
                  endAngle: startAngle
                });
                initProps(sector, {
                  shape: {
                    startAngle: layout.startAngle,
                    endAngle: layout.endAngle
                  }
                }, seriesModel, idx);
              } else {
                sector.shape.endAngle = layout.startAngle;
                updateProps(sector, {
                  shape: {
                    endAngle: layout.endAngle
                  }
                }, seriesModel, idx);
              }
            }
        } else {
          saveOldStyle(sector); // Transition animation from the old shape

          updateProps(sector, {
            shape: sectorShape
          }, seriesModel, idx);
        }

        sector.useStyle(data.getItemVisual(idx, 'style'));
        setStatesStylesFromModel(sector, itemModel);
        var midAngle = (layout.startAngle + layout.endAngle) / 2;
        var offset = seriesModel.get('selectedOffset');
        var dx = Math.cos(midAngle) * offset;
        var dy = Math.sin(midAngle) * offset;
        var cursorStyle = itemModel.getShallow('cursor');
        cursorStyle && sector.attr('cursor', cursorStyle);

        this._updateLabel(seriesModel, data, idx);

        sector.ensureState('emphasis').shape = extend({
          r: layout.r + (emphasisModel.get('scale') ? emphasisModel.get('scaleSize') || 0 : 0)
        }, getSectorCornerRadius(emphasisModel.getModel('itemStyle'), layout));
        extend(sector.ensureState('select'), {
          x: dx,
          y: dy,
          shape: getSectorCornerRadius(itemModel.getModel(['select', 'itemStyle']), layout)
        });
        extend(sector.ensureState('blur'), {
          shape: getSectorCornerRadius(itemModel.getModel(['blur', 'itemStyle']), layout)
        });
        var labelLine = sector.getTextGuideLine();
        var labelText = sector.getTextContent();
        labelLine && extend(labelLine.ensureState('select'), {
          x: dx,
          y: dy
        }); // TODO: needs dx, dy in zrender?

        extend(labelText.ensureState('select'), {
          x: dx,
          y: dy
        });
        toggleHoverEmphasis(this, emphasisModel.get('focus'), emphasisModel.get('blurScope'), emphasisModel.get('disabled'));
      };

      PiePiece.prototype._updateLabel = function (seriesModel, data, idx) {
        var sector = this;
        var itemModel = data.getItemModel(idx);
        var labelLineModel = itemModel.getModel('labelLine');
        var style = data.getItemVisual(idx, 'style');
        var visualColor = style && style.fill;
        var visualOpacity = style && style.opacity;
        setLabelStyle(sector, getLabelStatesModels(itemModel), {
          labelFetcher: data.hostModel,
          labelDataIndex: idx,
          inheritColor: visualColor,
          defaultOpacity: visualOpacity,
          defaultText: seriesModel.getFormattedLabel(idx, 'normal') || data.getName(idx)
        });
        var labelText = sector.getTextContent(); // Set textConfig on sector.

        sector.setTextConfig({
          // reset position, rotation
          position: null,
          rotation: null
        }); // Make sure update style on labelText after setLabelStyle.
        // Because setLabelStyle will replace a new style on it.

        labelText.attr({
          z2: 10
        });
        var labelPosition = seriesModel.get(['label', 'position']);

        if (labelPosition !== 'outside' && labelPosition !== 'outer') {
          sector.removeTextGuideLine();
        } else {
          var polyline = this.getTextGuideLine();

          if (!polyline) {
            polyline = new Polyline();
            this.setTextGuideLine(polyline);
          } // Default use item visual color


          setLabelLineStyle(this, getLabelLineStatesModels(itemModel), {
            stroke: visualColor,
            opacity: retrieve3(labelLineModel.get(['lineStyle', 'opacity']), visualOpacity, 1)
          });
        }
      };

      return PiePiece;
    }(Sector); // Pie view


    var PieView =
    /** @class */
    function (_super) {
      __extends(PieView, _super);

      function PieView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.ignoreLabelLineUpdate = true;
        return _this;
      }

      PieView.prototype.render = function (seriesModel, ecModel, api, payload) {
        var data = seriesModel.getData();
        var oldData = this._data;
        var group = this.group;
        var startAngle; // First render

        if (!oldData && data.count() > 0) {
          var shape = data.getItemLayout(0);

          for (var s = 1; isNaN(shape && shape.startAngle) && s < data.count(); ++s) {
            shape = data.getItemLayout(s);
          }

          if (shape) {
            startAngle = shape.startAngle;
          }
        } // remove empty-circle if it exists


        if (this._emptyCircleSector) {
          group.remove(this._emptyCircleSector);
        } // when all data are filtered, show lightgray empty circle


        if (data.count() === 0 && seriesModel.get('showEmptyCircle')) {
          var sector = new Sector({
            shape: getBasicPieLayout(seriesModel, api)
          });
          sector.useStyle(seriesModel.getModel('emptyCircleStyle').getItemStyle());
          this._emptyCircleSector = sector;
          group.add(sector);
        }

        data.diff(oldData).add(function (idx) {
          var piePiece = new PiePiece(data, idx, startAngle);
          data.setItemGraphicEl(idx, piePiece);
          group.add(piePiece);
        }).update(function (newIdx, oldIdx) {
          var piePiece = oldData.getItemGraphicEl(oldIdx);
          piePiece.updateData(data, newIdx, startAngle);
          piePiece.off('click');
          group.add(piePiece);
          data.setItemGraphicEl(newIdx, piePiece);
        }).remove(function (idx) {
          var piePiece = oldData.getItemGraphicEl(idx);
          removeElementWithFadeOut(piePiece, seriesModel, idx);
        }).execute();
        pieLabelLayout(seriesModel); // Always use initial animation.

        if (seriesModel.get('animationTypeUpdate') !== 'expansion') {
          this._data = data;
        }
      };

      PieView.prototype.dispose = function () {};

      PieView.prototype.containPoint = function (point, seriesModel) {
        var data = seriesModel.getData();
        var itemLayout = data.getItemLayout(0);

        if (itemLayout) {
          var dx = point[0] - itemLayout.cx;
          var dy = point[1] - itemLayout.cy;
          var radius = Math.sqrt(dx * dx + dy * dy);
          return radius <= itemLayout.r && radius >= itemLayout.r0;
        }
      };

      PieView.type = 'pie';
      return PieView;
    }(ChartView);

    /**
     * [Usage]:
     * (1)
     * createListSimply(seriesModel, ['value']);
     * (2)
     * createListSimply(seriesModel, {
     *     coordDimensions: ['value'],
     *     dimensionsCount: 5
     * });
     */

    function createSeriesDataSimply(seriesModel, opt, nameList) {
      opt = isArray(opt) && {
        coordDimensions: opt
      } || extend({
        encodeDefine: seriesModel.getEncode()
      }, opt);
      var source = seriesModel.getSource();
      var dimensions = prepareSeriesDataSchema(source, opt).dimensions;
      var list = new SeriesData(dimensions, seriesModel);
      list.initData(source, nameList);
      return list;
    }

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */

    /**
     * LegendVisualProvider is an bridge that pick encoded color from data and
     * provide to the legend component.
     */
    var LegendVisualProvider =
    /** @class */
    function () {
      function LegendVisualProvider( // Function to get data after filtered. It stores all the encoding info
      getDataWithEncodedVisual, // Function to get raw data before filtered.
      getRawData) {
        this._getDataWithEncodedVisual = getDataWithEncodedVisual;
        this._getRawData = getRawData;
      }

      LegendVisualProvider.prototype.getAllNames = function () {
        var rawData = this._getRawData(); // We find the name from the raw data. In case it's filtered by the legend component.
        // Normally, the name can be found in rawData, but can't be found in filtered data will display as gray.


        return rawData.mapArray(rawData.getName);
      };

      LegendVisualProvider.prototype.containName = function (name) {
        var rawData = this._getRawData();

        return rawData.indexOfName(name) >= 0;
      };

      LegendVisualProvider.prototype.indexOfName = function (name) {
        // Only get data when necessary.
        // Because LegendVisualProvider constructor may be new in the stage that data is not prepared yet.
        // Invoking Series#getData immediately will throw an error.
        var dataWithEncodedVisual = this._getDataWithEncodedVisual();

        return dataWithEncodedVisual.indexOfName(name);
      };

      LegendVisualProvider.prototype.getItemVisual = function (dataIndex, key) {
        // Get encoded visual properties from final filtered data.
        var dataWithEncodedVisual = this._getDataWithEncodedVisual();

        return dataWithEncodedVisual.getItemVisual(dataIndex, key);
      };

      return LegendVisualProvider;
    }();

    var innerData = makeInner();

    var PieSeriesModel =
    /** @class */
    function (_super) {
      __extends(PieSeriesModel, _super);

      function PieSeriesModel() {
        return _super !== null && _super.apply(this, arguments) || this;
      }
      /**
       * @overwrite
       */


      PieSeriesModel.prototype.init = function (option) {
        _super.prototype.init.apply(this, arguments); // Enable legend selection for each data item
        // Use a function instead of direct access because data reference may changed


        this.legendVisualProvider = new LegendVisualProvider(bind(this.getData, this), bind(this.getRawData, this));

        this._defaultLabelLine(option);
      };
      /**
       * @overwrite
       */


      PieSeriesModel.prototype.mergeOption = function () {
        _super.prototype.mergeOption.apply(this, arguments);
      };
      /**
       * @overwrite
       */


      PieSeriesModel.prototype.getInitialData = function () {
        return createSeriesDataSimply(this, {
          coordDimensions: ['value'],
          encodeDefaulter: curry(makeSeriesEncodeForNameBased, this)
        });
      };
      /**
       * @overwrite
       */


      PieSeriesModel.prototype.getDataParams = function (dataIndex) {
        var data = this.getData(); // update seats when data is changed

        var dataInner = innerData(data);
        var seats = dataInner.seats;

        if (!seats) {
          var valueList_1 = [];
          data.each(data.mapDimension('value'), function (value) {
            valueList_1.push(value);
          });
          seats = dataInner.seats = getPercentSeats(valueList_1, data.hostModel.get('percentPrecision'));
        }

        var params = _super.prototype.getDataParams.call(this, dataIndex); // seats may be empty when sum is 0


        params.percent = seats[dataIndex] || 0;
        params.$vars.push('percent');
        return params;
      };

      PieSeriesModel.prototype._defaultLabelLine = function (option) {
        // Extend labelLine emphasis
        defaultEmphasis(option, 'labelLine', ['show']);
        var labelLineNormalOpt = option.labelLine;
        var labelLineEmphasisOpt = option.emphasis.labelLine; // Not show label line if `label.normal.show = false`

        labelLineNormalOpt.show = labelLineNormalOpt.show && option.label.show;
        labelLineEmphasisOpt.show = labelLineEmphasisOpt.show && option.emphasis.label.show;
      };

      PieSeriesModel.type = 'series.pie';
      PieSeriesModel.defaultOption = {
        // zlevel: 0,
        z: 2,
        legendHoverLink: true,
        colorBy: 'data',
        // 默认全局居中
        center: ['50%', '50%'],
        radius: [0, '75%'],
        // 默认顺时针
        clockwise: true,
        startAngle: 90,
        // 最小角度改为0
        minAngle: 0,
        // If the angle of a sector less than `minShowLabelAngle`,
        // the label will not be displayed.
        minShowLabelAngle: 0,
        // 选中时扇区偏移量
        selectedOffset: 10,
        // 选择模式，默认关闭，可选single，multiple
        // selectedMode: false,
        // 南丁格尔玫瑰图模式，'radius'（半径） | 'area'（面积）
        // roseType: null,
        percentPrecision: 2,
        // If still show when all data zero.
        stillShowZeroSum: true,
        // cursor: null,
        left: 0,
        top: 0,
        right: 0,
        bottom: 0,
        width: null,
        height: null,
        label: {
          // color: 'inherit',
          // If rotate around circle
          rotate: 0,
          show: true,
          overflow: 'truncate',
          // 'outer', 'inside', 'center'
          position: 'outer',
          // 'none', 'labelLine', 'edge'. Works only when position is 'outer'
          alignTo: 'none',
          // Closest distance between label and chart edge.
          // Works only position is 'outer' and alignTo is 'edge'.
          edgeDistance: '25%',
          // Works only position is 'outer' and alignTo is not 'edge'.
          bleedMargin: 10,
          // Distance between text and label line.
          distanceToLabelLine: 5 // formatter: 标签文本格式器，同 tooltip.formatter，不支持异步回调
          // 默认使用全局文本样式，详见 textStyle
          // distance: 当position为inner时有效，为label位置到圆心的距离与圆半径(环状图为内外半径和)的比例系数

        },
        // Enabled when label.normal.position is 'outer'
        labelLine: {
          show: true,
          // 引导线两段中的第一段长度
          length: 15,
          // 引导线两段中的第二段长度
          length2: 15,
          smooth: false,
          minTurnAngle: 90,
          maxSurfaceAngle: 90,
          lineStyle: {
            // color: 各异,
            width: 1,
            type: 'solid'
          }
        },
        itemStyle: {
          borderWidth: 1,
          borderJoin: 'round'
        },
        showEmptyCircle: true,
        emptyCircleStyle: {
          color: 'lightgray',
          opacity: 1
        },
        labelLayout: {
          // Hide the overlapped label.
          hideOverlap: true
        },
        emphasis: {
          scale: true,
          scaleSize: 5
        },
        // If use strategy to avoid label overlapping
        avoidLabelOverlap: true,
        // Animation type. Valid values: expansion, scale
        animationType: 'expansion',
        animationDuration: 1000,
        // Animation type when update. Valid values: transition, expansion
        animationTypeUpdate: 'transition',
        animationEasingUpdate: 'cubicInOut',
        animationDurationUpdate: 500,
        animationEasing: 'cubicInOut'
      };
      return PieSeriesModel;
    }(SeriesModel);

    function negativeDataFilter(seriesType) {
      return {
        seriesType: seriesType,
        reset: function (seriesModel, ecModel) {
          var data = seriesModel.getData();
          data.filterSelf(function (idx) {
            // handle negative value condition
            var valueDim = data.mapDimension('value');
            var curValue = data.get(valueDim, idx);

            if (isNumber(curValue) && !isNaN(curValue) && curValue < 0) {
              return false;
            }

            return true;
          });
        }
      };
    }

    function install$3(registers) {
      registers.registerChartView(PieView);
      registers.registerSeriesModel(PieSeriesModel);
      createLegacyDataSelectAction('pie', registers.registerAction);
      registers.registerLayout(curry(pieLayout, 'pie'));
      registers.registerProcessor(dataFilter('pie'));
      registers.registerProcessor(negativeDataFilter('pie'));
    }

    var GridModel =
    /** @class */
    function (_super) {
      __extends(GridModel, _super);

      function GridModel() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      GridModel.type = 'grid';
      GridModel.dependencies = ['xAxis', 'yAxis'];
      GridModel.layoutMode = 'box';
      GridModel.defaultOption = {
        show: false,
        // zlevel: 0,
        z: 0,
        left: '10%',
        top: 60,
        right: '10%',
        bottom: 70,
        // If grid size contain label
        containLabel: false,
        // width: {totalWidth} - left - right,
        // height: {totalHeight} - top - bottom,
        backgroundColor: 'rgba(0,0,0,0)',
        borderWidth: 1,
        borderColor: '#ccc'
      };
      return GridModel;
    }(ComponentModel);

    var CartesianAxisModel =
    /** @class */
    function (_super) {
      __extends(CartesianAxisModel, _super);

      function CartesianAxisModel() {
        return _super !== null && _super.apply(this, arguments) || this;
      }

      CartesianAxisModel.prototype.getCoordSysModel = function () {
        return this.getReferringComponents('grid', SINGLE_REFERRING).models[0];
      };

      CartesianAxisModel.type = 'cartesian2dAxis';
      return CartesianAxisModel;
    }(ComponentModel);
    mixin(CartesianAxisModel, AxisModelCommonMixin);

    var defaultOption = {
      show: true,
      // zlevel: 0,
      z: 0,
      // Inverse the axis.
      inverse: false,
      // Axis name displayed.
      name: '',
      // 'start' | 'middle' | 'end'
      nameLocation: 'end',
      // By degree. By default auto rotate by nameLocation.
      nameRotate: null,
      nameTruncate: {
        maxWidth: null,
        ellipsis: '...',
        placeholder: '.'
      },
      // Use global text style by default.
      nameTextStyle: {},
      // The gap between axisName and axisLine.
      nameGap: 15,
      // Default `false` to support tooltip.
      silent: false,
      // Default `false` to avoid legacy user event listener fail.
      triggerEvent: false,
      tooltip: {
        show: false
      },
      axisPointer: {},
      axisLine: {
        show: true,
        onZero: true,
        onZeroAxisIndex: null,
        lineStyle: {
          color: '#6E7079',
          width: 1,
          type: 'solid'
        },
        // The arrow at both ends the the axis.
        symbol: ['none', 'none'],
        symbolSize: [10, 15]
      },
      axisTick: {
        show: true,
        // Whether axisTick is inside the grid or outside the grid.
        inside: false,
        // The length of axisTick.
        length: 5,
        lineStyle: {
          width: 1
        }
      },
      axisLabel: {
        show: true,
        // Whether axisLabel is inside the grid or outside the grid.
        inside: false,
        rotate: 0,
        // true | false | null/undefined (auto)
        showMinLabel: null,
        // true | false | null/undefined (auto)
        showMaxLabel: null,
        margin: 8,
        // formatter: null,
        fontSize: 12
      },
      splitLine: {
        show: true,
        lineStyle: {
          color: ['#E0E6F1'],
          width: 1,
          type: 'solid'
        }
      },
      splitArea: {
        show: false,
        areaStyle: {
          color: ['rgba(250,250,250,0.2)', 'rgba(210,219,238,0.2)']
        }
      }
    };
    var categoryAxis = merge({
      // The gap at both ends of the axis. For categoryAxis, boolean.
      boundaryGap: true,
      // Set false to faster category collection.
      deduplication: null,
      // splitArea: {
      // show: false
      // },
      splitLine: {
        show: false
      },
      axisTick: {
        // If tick is align with label when boundaryGap is true
        alignWithLabel: false,
        interval: 'auto'
      },
      axisLabel: {
        interval: 'auto'
      }
    }, defaultOption);
    var valueAxis = merge({
      boundaryGap: [0, 0],
      axisLine: {
        // Not shown when other axis is categoryAxis in cartesian
        show: 'auto'
      },
      axisTick: {
        // Not shown when other axis is categoryAxis in cartesian
        show: 'auto'
      },
      // TODO
      // min/max: [30, datamin, 60] or [20, datamin] or [datamin, 60]
      splitNumber: 5,
      minorTick: {
        // Minor tick, not available for cateogry axis.
        show: false,
        // Split number of minor ticks. The value should be in range of (0, 100)
        splitNumber: 5,
        // Length of minor tick
        length: 3,
        // Line style
        lineStyle: {// Default to be same with axisTick
        }
      },
      minorSplitLine: {
        show: false,
        lineStyle: {
          color: '#F4F7FD',
          width: 1
        }
      }
    }, defaultOption);
    var timeAxis = merge({
      splitNumber: 6,
      axisLabel: {
        // To eliminate labels that are not nice
        showMinLabel: false,
        showMaxLabel: false,
        rich: {
          primary: {
            fontWeight: 'bold'
          }
        }
      },
      splitLine: {
        show: false
      }
    }, valueAxis);
    var logAxis = defaults({
      logBase: 10
    }, valueAxis);
    var axisDefault = {
      category: categoryAxis,
      value: valueAxis,
      time: timeAxis,
      log: logAxis
    };

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */


    /**
     * AUTO-GENERATED FILE. DO NOT MODIFY.
     */

    /*
    * Licensed to the Apache Software Foundation (ASF) under one
    * or more contributor license agreements.  See the NOTICE file
    * distributed with this work for additional information
    * regarding copyright ownership.  The ASF licenses this file
    * to you under the Apache License, Version 2.0 (the
    * "License"); you may not use this file except in compliance
    * with the License.  You may obtain a copy of the License at
    *
    *   http://www.apache.org/licenses/LICENSE-2.0
    *
    * Unless required by applicable law or agreed to in writing,
    * software distributed under the License is distributed on an
    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    * KIND, either express or implied.  See the License for the
    * specific language governing permissions and limitations
    * under the License.
    */
    var AXIS_TYPES = {
      value: 1,
      category: 1,
      time: 1,
      log: 1
    };

    /**
     * Generate sub axis model class
     * @param axisName 'x' 'y' 'radius' 'angle' 'parallel' ...
     */

    function axisModelCreator(registers, axisName, BaseAxisModelClass, extraDefaultOption) {
      each(AXIS_TYPES, function (v, axisType) {
        var defaultOption = merge(merge({}, axisDefault[axisType], true), extraDefaultOption, true);

        var AxisModel =
        /** @class */
        function (_super) {
          __extends(AxisModel, _super);

          function AxisModel() {
            var _this = _super !== null && _super.apply(this, arguments) || this;

            _this.type = axisName + 'Axis.' + axisType;
            return _this;
          }

          AxisModel.prototype.mergeDefaultAndTheme = function (option, ecModel) {
            var layoutMode = fetchLayoutMode(this);
            var inputPositionParams = layoutMode ? getLayoutParams(option) : {};
            var themeModel = ecModel.getTheme();
            merge(option, themeModel.get(axisType + 'Axis'));
            merge(option, this.getDefaultOption());
            option.type = getAxisType(option);

            if (layoutMode) {
              mergeLayoutParam(option, inputPositionParams, layoutMode);
            }
          };

          AxisModel.prototype.optionUpdated = function () {
            var thisOption = this.option;

            if (thisOption.type === 'category') {
              this.__ordinalMeta = OrdinalMeta.createByAxisModel(this);
            }
          };
          /**
           * Should not be called before all of 'getInitailData' finished.
           * Because categories are collected during initializing data.
           */


          AxisModel.prototype.getCategories = function (rawData) {
            var option = this.option; // FIXME
            // warning if called before all of 'getInitailData' finished.

            if (option.type === 'category') {
              if (rawData) {
                return option.data;
              }

              return this.__ordinalMeta.categories;
            }
          };

          AxisModel.prototype.getOrdinalMeta = function () {
            return this.__ordinalMeta;
          };

          AxisModel.type = axisName + 'Axis.' + axisType;
          AxisModel.defaultOption = defaultOption;
          return AxisModel;
        }(BaseAxisModelClass);

        registers.registerComponentModel(AxisModel);
      });
      registers.registerSubTypeDefaulter(axisName + 'Axis', getAxisType);
    }

    function getAxisType(option) {
      // Default axis with data is category axis
      return option.type || (option.data ? 'category' : 'value');
    }

    var Cartesian =
    /** @class */
    function () {
      function Cartesian(name) {
        this.type = 'cartesian';
        this._dimList = [];
        this._axes = {};
        this.name = name || '';
      }

      Cartesian.prototype.getAxis = function (dim) {
        return this._axes[dim];
      };

      Cartesian.prototype.getAxes = function () {
        return map(this._dimList, function (dim) {
          return this._axes[dim];
        }, this);
      };

      Cartesian.prototype.getAxesByScale = function (scaleType) {
        scaleType = scaleType.toLowerCase();
        return filter(this.getAxes(), function (axis) {
          return axis.scale.type === scaleType;
        });
      };

      Cartesian.prototype.addAxis = function (axis) {
        var dim = axis.dim;
        this._axes[dim] = axis;

        this._dimList.push(dim);
      };

      return Cartesian;
    }();

    var cartesian2DDimensions = ['x', 'y'];

    function canCalculateAffineTransform(scale) {
      return scale.type === 'interval' || scale.type === 'time';
    }

    var Cartesian2D =
    /** @class */
    function (_super) {
      __extends(Cartesian2D, _super);

      function Cartesian2D() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'cartesian2d';
        _this.dimensions = cartesian2DDimensions;
        return _this;
      }
      /**
       * Calculate an affine transform matrix if two axes are time or value.
       * It's mainly for accelartion on the large time series data.
       */


      Cartesian2D.prototype.calcAffineTransform = function () {
        this._transform = this._invTransform = null;
        var xAxisScale = this.getAxis('x').scale;
        var yAxisScale = this.getAxis('y').scale;

        if (!canCalculateAffineTransform(xAxisScale) || !canCalculateAffineTransform(yAxisScale)) {
          return;
        }

        var xScaleExtent = xAxisScale.getExtent();
        var yScaleExtent = yAxisScale.getExtent();
        var start = this.dataToPoint([xScaleExtent[0], yScaleExtent[0]]);
        var end = this.dataToPoint([xScaleExtent[1], yScaleExtent[1]]);
        var xScaleSpan = xScaleExtent[1] - xScaleExtent[0];
        var yScaleSpan = yScaleExtent[1] - yScaleExtent[0];

        if (!xScaleSpan || !yScaleSpan) {
          return;
        } // Accelerate data to point calculation on the special large time series data.


        var scaleX = (end[0] - start[0]) / xScaleSpan;
        var scaleY = (end[1] - start[1]) / yScaleSpan;
        var translateX = start[0] - xScaleExtent[0] * scaleX;
        var translateY = start[1] - yScaleExtent[0] * scaleY;
        var m = this._transform = [scaleX, 0, 0, scaleY, translateX, translateY];
        this._invTransform = invert([], m);
      };
      /**
       * Base axis will be used on stacking.
       */


      Cartesian2D.prototype.getBaseAxis = function () {
        return this.getAxesByScale('ordinal')[0] || this.getAxesByScale('time')[0] || this.getAxis('x');
      };

      Cartesian2D.prototype.containPoint = function (point) {
        var axisX = this.getAxis('x');
        var axisY = this.getAxis('y');
        return axisX.contain(axisX.toLocalCoord(point[0])) && axisY.contain(axisY.toLocalCoord(point[1]));
      };

      Cartesian2D.prototype.containData = function (data) {
        return this.getAxis('x').containData(data[0]) && this.getAxis('y').containData(data[1]);
      };

      Cartesian2D.prototype.containZone = function (data1, data2) {
        var zoneDiag1 = this.dataToPoint(data1);
        var zoneDiag2 = this.dataToPoint(data2);
        var area = this.getArea();
        var zone = new BoundingRect(zoneDiag1[0], zoneDiag1[1], zoneDiag2[0] - zoneDiag1[0], zoneDiag2[1] - zoneDiag1[1]);
        return area.intersect(zone);
      };

      Cartesian2D.prototype.dataToPoint = function (data, clamp, out) {
        out = out || [];
        var xVal = data[0];
        var yVal = data[1]; // Fast path

        if (this._transform // It's supported that if data is like `[Inifity, 123]`, where only Y pixel calculated.
        && xVal != null && isFinite(xVal) && yVal != null && isFinite(yVal)) {
          return applyTransform(out, data, this._transform);
        }

        var xAxis = this.getAxis('x');
        var yAxis = this.getAxis('y');
        out[0] = xAxis.toGlobalCoord(xAxis.dataToCoord(xVal, clamp));
        out[1] = yAxis.toGlobalCoord(yAxis.dataToCoord(yVal, clamp));
        return out;
      };

      Cartesian2D.prototype.clampData = function (data, out) {
        var xScale = this.getAxis('x').scale;
        var yScale = this.getAxis('y').scale;
        var xAxisExtent = xScale.getExtent();
        var yAxisExtent = yScale.getExtent();
        var x = xScale.parse(data[0]);
        var y = yScale.parse(data[1]);
        out = out || [];
        out[0] = Math.min(Math.max(Math.min(xAxisExtent[0], xAxisExtent[1]), x), Math.max(xAxisExtent[0], xAxisExtent[1]));
        out[1] = Math.min(Math.max(Math.min(yAxisExtent[0], yAxisExtent[1]), y), Math.max(yAxisExtent[0], yAxisExtent[1]));
        return out;
      };

      Cartesian2D.prototype.pointToData = function (point, clamp) {
        var out = [];

        if (this._invTransform) {
          return applyTransform(out, point, this._invTransform);
        }

        var xAxis = this.getAxis('x');
        var yAxis = this.getAxis('y');
        out[0] = xAxis.coordToData(xAxis.toLocalCoord(point[0]), clamp);
        out[1] = yAxis.coordToData(yAxis.toLocalCoord(point[1]), clamp);
        return out;
      };

      Cartesian2D.prototype.getOtherAxis = function (axis) {
        return this.getAxis(axis.dim === 'x' ? 'y' : 'x');
      };
      /**
       * Get rect area of cartesian.
       * Area will have a contain function to determine if a point is in the coordinate system.
       */


      Cartesian2D.prototype.getArea = function () {
        var xExtent = this.getAxis('x').getGlobalExtent();
        var yExtent = this.getAxis('y').getGlobalExtent();
        var x = Math.min(xExtent[0], xExtent[1]);
        var y = Math.min(yExtent[0], yExtent[1]);
        var width = Math.max(xExtent[0], xExtent[1]) - x;
        var height = Math.max(yExtent[0], yExtent[1]) - y;
        return new BoundingRect(x, y, width, height);
      };

      return Cartesian2D;
    }(Cartesian);

    var Axis2D =
    /** @class */
    function (_super) {
      __extends(Axis2D, _super);

      function Axis2D(dim, scale, coordExtent, axisType, position) {
        var _this = _super.call(this, dim, scale, coordExtent) || this;
        /**
         * Index of axis, can be used as key
         * Injected outside.
         */


        _this.index = 0;
        _this.type = axisType || 'value';
        _this.position = position || 'bottom';
        return _this;
      }

      Axis2D.prototype.isHorizontal = function () {
        var position = this.position;
        return position === 'top' || position === 'bottom';
      };
      /**
       * Each item cooresponds to this.getExtent(), which
       * means globalExtent[0] may greater than globalExtent[1],
       * unless `asc` is input.
       *
       * @param {boolean} [asc]
       * @return {Array.<number>}
       */


      Axis2D.prototype.getGlobalExtent = function (asc) {
        var ret = this.getExtent();
        ret[0] = this.toGlobalCoord(ret[0]);
        ret[1] = this.toGlobalCoord(ret[1]);
        asc && ret[0] > ret[1] && ret.reverse();
        return ret;
      };

      Axis2D.prototype.pointToData = function (point, clamp) {
        return this.coordToData(this.toLocalCoord(point[this.dim === 'x' ? 0 : 1]), clamp);
      };
      /**
       * Set ordinalSortInfo
       * @param info new OrdinalSortInfo
       */


      Axis2D.prototype.setCategorySortInfo = function (info) {
        if (this.type !== 'category') {
          return false;
        }

        this.model.option.categorySortInfo = info;
        this.scale.setSortInfo(info);
      };

      return Axis2D;
    }(Axis);

    /**
     * Can only be called after coordinate system creation stage.
     * (Can be called before coordinate system update stage).
     */

    function layout$1(gridModel, axisModel, opt) {
      opt = opt || {};
      var grid = gridModel.coordinateSystem;
      var axis = axisModel.axis;
      var layout = {};
      var otherAxisOnZeroOf = axis.getAxesOnZeroOf()[0];
      var rawAxisPosition = axis.position;
      var axisPosition = otherAxisOnZeroOf ? 'onZero' : rawAxisPosition;
      var axisDim = axis.dim;
      var rect = grid.getRect();
      var rectBound = [rect.x, rect.x + rect.width, rect.y, rect.y + rect.height];
      var idx = {
        left: 0,
        right: 1,
        top: 0,
        bottom: 1,
        onZero: 2
      };
      var axisOffset = axisModel.get('offset') || 0;
      var posBound = axisDim === 'x' ? [rectBound[2] - axisOffset, rectBound[3] + axisOffset] : [rectBound[0] - axisOffset, rectBound[1] + axisOffset];

      if (otherAxisOnZeroOf) {
        var onZeroCoord = otherAxisOnZeroOf.toGlobalCoord(otherAxisOnZeroOf.dataToCoord(0));
        posBound[idx.onZero] = Math.max(Math.min(onZeroCoord, posBound[1]), posBound[0]);
      } // Axis position


      layout.position = [axisDim === 'y' ? posBound[idx[axisPosition]] : rectBound[0], axisDim === 'x' ? posBound[idx[axisPosition]] : rectBound[3]]; // Axis rotation

      layout.rotation = Math.PI / 2 * (axisDim === 'x' ? 0 : 1); // Tick and label direction, x y is axisDim

      var dirMap = {
        top: -1,
        bottom: 1,
        left: -1,
        right: 1
      };
      layout.labelDirection = layout.tickDirection = layout.nameDirection = dirMap[rawAxisPosition];
      layout.labelOffset = otherAxisOnZeroOf ? posBound[idx[rawAxisPosition]] - posBound[idx.onZero] : 0;

      if (axisModel.get(['axisTick', 'inside'])) {
        layout.tickDirection = -layout.tickDirection;
      }

      if (retrieve(opt.labelInside, axisModel.get(['axisLabel', 'inside']))) {
        layout.labelDirection = -layout.labelDirection;
      } // Special label rotation


      var labelRotate = axisModel.get(['axisLabel', 'rotate']);
      layout.labelRotate = axisPosition === 'top' ? -labelRotate : labelRotate; // Over splitLine and splitArea

      layout.z2 = 1;
      return layout;
    }
    function isCartesian2DSeries(seriesModel) {
      return seriesModel.get('coordinateSystem') === 'cartesian2d';
    }
    function findAxisModels(seriesModel) {
      var axisModelMap = {
        xAxisModel: null,
        yAxisModel: null
      };
      each(axisModelMap, function (v, key) {
        var axisType = key.replace(/Model$/, '');
        var axisModel = seriesModel.getReferringComponents(axisType, SINGLE_REFERRING).models[0];

        if ("development" !== 'production') {
          if (!axisModel) {
            throw new Error(axisType + ' "' + retrieve3(seriesModel.get(axisType + 'Index'), seriesModel.get(axisType + 'Id'), 0) + '" not found');
          }
        }

        axisModelMap[key] = axisModel;
      });
      return axisModelMap;
    }

    var mathLog$1 = Math.log;
    function alignScaleTicks(scale, axisModel, alignToScale) {
      var intervalScaleProto = IntervalScale.prototype; // NOTE: There is a precondition for log scale  here:
      // In log scale we store _interval and _extent of exponent value.
      // So if we use the method of InternalScale to set/get these data.
      // It process the exponent value, which is linear and what we want here.

      var alignToTicks = intervalScaleProto.getTicks.call(alignToScale);
      var alignToNicedTicks = intervalScaleProto.getTicks.call(alignToScale, true);
      var alignToSplitNumber = alignToTicks.length - 1;
      var alignToInterval = intervalScaleProto.getInterval.call(alignToScale);
      var scaleExtent = getScaleExtent(scale, axisModel);
      var rawExtent = scaleExtent.extent;
      var isMinFixed = scaleExtent.fixMin;
      var isMaxFixed = scaleExtent.fixMax;

      if (scale.type === 'log') {
        var logBase = mathLog$1(scale.base);
        rawExtent = [mathLog$1(rawExtent[0]) / logBase, mathLog$1(rawExtent[1]) / logBase];
      }

      scale.setExtent(rawExtent[0], rawExtent[1]);
      scale.calcNiceExtent({
        splitNumber: alignToSplitNumber,
        fixMin: isMinFixed,
        fixMax: isMaxFixed
      });
      var extent = intervalScaleProto.getExtent.call(scale); // Need to update the rawExtent.
      // Because value in rawExtent may be not parsed. e.g. 'dataMin', 'dataMax'

      if (isMinFixed) {
        rawExtent[0] = extent[0];
      }

      if (isMaxFixed) {
        rawExtent[1] = extent[1];
      }

      var interval = intervalScaleProto.getInterval.call(scale);
      var min = rawExtent[0];
      var max = rawExtent[1];

      if (isMinFixed && isMaxFixed) {
        // User set min, max, divide to get new interval
        interval = (max - min) / alignToSplitNumber;
      } else if (isMinFixed) {
        max = rawExtent[0] + interval * alignToSplitNumber; // User set min, expand extent on the other side

        while (max < rawExtent[1] && isFinite(max) && isFinite(rawExtent[1])) {
          interval = increaseInterval(interval);
          max = rawExtent[0] + interval * alignToSplitNumber;
        }
      } else if (isMaxFixed) {
        // User set max, expand extent on the other side
        min = rawExtent[1] - interval * alignToSplitNumber;

        while (min > rawExtent[0] && isFinite(min) && isFinite(rawExtent[0])) {
          interval = increaseInterval(interval);
          min = rawExtent[1] - interval * alignToSplitNumber;
        }
      } else {
        var nicedSplitNumber = scale.getTicks().length - 1;

        if (nicedSplitNumber > alignToSplitNumber) {
          interval = increaseInterval(interval);
        }

        var range = interval * alignToSplitNumber;
        max = Math.ceil(rawExtent[1] / interval) * interval;
        min = round(max - range); // Not change the result that crossing zero.

        if (min < 0 && rawExtent[0] >= 0) {
          min = 0;
          max = round(range);
        } else if (max > 0 && rawExtent[1] <= 0) {
          max = 0;
          min = -round(range);
        }
      } // Adjust min, max based on the extent of alignTo. When min or max is set in alignTo scale


      var t0 = (alignToTicks[0].value - alignToNicedTicks[0].value) / alignToInterval;
      var t1 = (alignToTicks[alignToSplitNumber].value - alignToNicedTicks[alignToSplitNumber].value) / alignToInterval; // NOTE: Must in setExtent -> setInterval -> setNiceExtent order.

      intervalScaleProto.setExtent.call(scale, min + interval * t0, max + interval * t1);
      intervalScaleProto.setInterval.call(scale, interval);

      if (t0 || t1) {
        intervalScaleProto.setNiceExtent.call(scale, min + interval, max - interval);
      }

      if ("development" !== 'production') {
        var ticks = intervalScaleProto.getTicks.call(scale);

        if (ticks[1] && (!isValueNice(interval) || getPrecisionSafe(ticks[1].value) > getPrecisionSafe(interval))) {
          warn( // eslint-disable-next-line
          "The ticks may be not readable when set min: " + axisModel.get('min') + ", max: " + axisModel.get('max') + " and alignTicks: true");
        }
      }
    }

    var Grid =
    /** @class */
    function () {
      function Grid(gridModel, ecModel, api) {
        // FIXME:TS where used (different from registered type 'cartesian2d')?
        this.type = 'grid';
        this._coordsMap = {};
        this._coordsList = [];
        this._axesMap = {};
        this._axesList = [];
        this.axisPointerEnabled = true;
        this.dimensions = cartesian2DDimensions;

        this._initCartesian(gridModel, ecModel, api);

        this.model = gridModel;
      }

      Grid.prototype.getRect = function () {
        return this._rect;
      };

      Grid.prototype.update = function (ecModel, api) {
        var axesMap = this._axesMap;

        this._updateScale(ecModel, this.model);

        function updateAxisTicks(axes) {
          var alignTo; // Axis is added in order of axisIndex.

          var axesIndices = keys(axes);
          var len = axesIndices.length;

          if (!len) {
            return;
          }

          var axisNeedsAlign = []; // Process once and calculate the ticks for those don't use alignTicks.

          for (var i = len - 1; i >= 0; i--) {
            var idx = +axesIndices[i]; // Convert to number.

            var axis = axes[idx];
            var model = axis.model;
            var scale = axis.scale;

            if ( // Only value and log axis without interval support alignTicks.
            isIntervalOrLogScale(scale) && model.get('alignTicks') && model.get('interval') == null) {
              axisNeedsAlign.push(axis);
            } else {
              niceScaleExtent(scale, model);

              if (isIntervalOrLogScale(scale)) {
                // Can only align to interval or log axis.
                alignTo = axis;
              }
            }
          }
          // PENDING. Should we find the axis that both set interval, min, max and align to this one?

          if (axisNeedsAlign.length) {
            if (!alignTo) {
              alignTo = axisNeedsAlign.pop();
              niceScaleExtent(alignTo.scale, alignTo.model);
            }

            each(axisNeedsAlign, function (axis) {
              alignScaleTicks(axis.scale, axis.model, alignTo.scale);
            });
          }
        }

        updateAxisTicks(axesMap.x);
        updateAxisTicks(axesMap.y); // Key: axisDim_axisIndex, value: boolean, whether onZero target.

        var onZeroRecords = {};
        each(axesMap.x, function (xAxis) {
          fixAxisOnZero(axesMap, 'y', xAxis, onZeroRecords);
        });
        each(axesMap.y, function (yAxis) {
          fixAxisOnZero(axesMap, 'x', yAxis, onZeroRecords);
        }); // Resize again if containLabel is enabled
        // FIXME It may cause getting wrong grid size in data processing stage

        this.resize(this.model, api);
      };
      /**
       * Resize the grid
       */


      Grid.prototype.resize = function (gridModel, api, ignoreContainLabel) {
        var boxLayoutParams = gridModel.getBoxLayoutParams();
        var isContainLabel = !ignoreContainLabel && gridModel.get('containLabel');
        var gridRect = getLayoutRect(boxLayoutParams, {
          width: api.getWidth(),
          height: api.getHeight()
        });
        this._rect = gridRect;
        var axesList = this._axesList;
        adjustAxes(); // Minus label size

        if (isContainLabel) {
          each(axesList, function (axis) {
            if (!axis.model.get(['axisLabel', 'inside'])) {
              var labelUnionRect = estimateLabelUnionRect(axis);

              if (labelUnionRect) {
                var dim = axis.isHorizontal() ? 'height' : 'width';
                var margin = axis.model.get(['axisLabel', 'margin']);
                gridRect[dim] -= labelUnionRect[dim] + margin;

                if (axis.position === 'top') {
                  gridRect.y += labelUnionRect.height + margin;
                } else if (axis.position === 'left') {
                  gridRect.x += labelUnionRect.width + margin;
                }
              }
            }
          });
          adjustAxes();
        }

        each(this._coordsList, function (coord) {
          // Calculate affine matrix to accelerate the data to point transform.
          // If all the axes scales are time or value.
          coord.calcAffineTransform();
        });

        function adjustAxes() {
          each(axesList, function (axis) {
            var isHorizontal = axis.isHorizontal();
            var extent = isHorizontal ? [0, gridRect.width] : [0, gridRect.height];
            var idx = axis.inverse ? 1 : 0;
            axis.setExtent(extent[idx], extent[1 - idx]);
            updateAxisTransform(axis, isHorizontal ? gridRect.x : gridRect.y);
          });
        }
      };

      Grid.prototype.getAxis = function (dim, axisIndex) {
        var axesMapOnDim = this._axesMap[dim];

        if (axesMapOnDim != null) {
          return axesMapOnDim[axisIndex || 0];
        }
      };

      Grid.prototype.getAxes = function () {
        return this._axesList.slice();
      };

      Grid.prototype.getCartesian = function (xAxisIndex, yAxisIndex) {
        if (xAxisIndex != null && yAxisIndex != null) {
          var key = 'x' + xAxisIndex + 'y' + yAxisIndex;
          return this._coordsMap[key];
        }

        if (isObject(xAxisIndex)) {
          yAxisIndex = xAxisIndex.yAxisIndex;
          xAxisIndex = xAxisIndex.xAxisIndex;
        }

        for (var i = 0, coordList = this._coordsList; i < coordList.length; i++) {
          if (coordList[i].getAxis('x').index === xAxisIndex || coordList[i].getAxis('y').index === yAxisIndex) {
            return coordList[i];
          }
        }
      };

      Grid.prototype.getCartesians = function () {
        return this._coordsList.slice();
      };
      /**
       * @implements
       */


      Grid.prototype.convertToPixel = function (ecModel, finder, value) {
        var target = this._findConvertTarget(finder);

        return target.cartesian ? target.cartesian.dataToPoint(value) : target.axis ? target.axis.toGlobalCoord(target.axis.dataToCoord(value)) : null;
      };
      /**
       * @implements
       */


      Grid.prototype.convertFromPixel = function (ecModel, finder, value) {
        var target = this._findConvertTarget(finder);

        return target.cartesian ? target.cartesian.pointToData(value) : target.axis ? target.axis.coordToData(target.axis.toLocalCoord(value)) : null;
      };

      Grid.prototype._findConvertTarget = function (finder) {
        var seriesModel = finder.seriesModel;
        var xAxisModel = finder.xAxisModel || seriesModel && seriesModel.getReferringComponents('xAxis', SINGLE_REFERRING).models[0];
        var yAxisModel = finder.yAxisModel || seriesModel && seriesModel.getReferringComponents('yAxis', SINGLE_REFERRING).models[0];
        var gridModel = finder.gridModel;
        var coordsList = this._coordsList;
        var cartesian;
        var axis;

        if (seriesModel) {
          cartesian = seriesModel.coordinateSystem;
          indexOf(coordsList, cartesian) < 0 && (cartesian = null);
        } else if (xAxisModel && yAxisModel) {
          cartesian = this.getCartesian(xAxisModel.componentIndex, yAxisModel.componentIndex);
        } else if (xAxisModel) {
          axis = this.getAxis('x', xAxisModel.componentIndex);
        } else if (yAxisModel) {
          axis = this.getAxis('y', yAxisModel.componentIndex);
        } // Lowest priority.
        else if (gridModel) {
            var grid = gridModel.coordinateSystem;

            if (grid === this) {
              cartesian = this._coordsList[0];
            }
          }

        return {
          cartesian: cartesian,
          axis: axis
        };
      };
      /**
       * @implements
       */


      Grid.prototype.containPoint = function (point) {
        var coord = this._coordsList[0];

        if (coord) {
          return coord.containPoint(point);
        }
      };
      /**
       * Initialize cartesian coordinate systems
       */


      Grid.prototype._initCartesian = function (gridModel, ecModel, api) {
        var _this = this;

        var grid = this;
        var axisPositionUsed = {
          left: false,
          right: false,
          top: false,
          bottom: false
        };
        var axesMap = {
          x: {},
          y: {}
        };
        var axesCount = {
          x: 0,
          y: 0
        }; // Create axis

        ecModel.eachComponent('xAxis', createAxisCreator('x'), this);
        ecModel.eachComponent('yAxis', createAxisCreator('y'), this);

        if (!axesCount.x || !axesCount.y) {
          // Roll back when there no either x or y axis
          this._axesMap = {};
          this._axesList = [];
          return;
        }

        this._axesMap = axesMap; // Create cartesian2d

        each(axesMap.x, function (xAxis, xAxisIndex) {
          each(axesMap.y, function (yAxis, yAxisIndex) {
            var key = 'x' + xAxisIndex + 'y' + yAxisIndex;
            var cartesian = new Cartesian2D(key);
            cartesian.master = _this;
            cartesian.model = gridModel;
            _this._coordsMap[key] = cartesian;

            _this._coordsList.push(cartesian);

            cartesian.addAxis(xAxis);
            cartesian.addAxis(yAxis);
          });
        });

        function createAxisCreator(dimName) {
          return function (axisModel, idx) {
            if (!isAxisUsedInTheGrid(axisModel, gridModel)) {
              return;
            }

            var axisPosition = axisModel.get('position');

            if (dimName === 'x') {
              // Fix position
              if (axisPosition !== 'top' && axisPosition !== 'bottom') {
                // Default bottom of X
                axisPosition = axisPositionUsed.bottom ? 'top' : 'bottom';
              }
            } else {
              // Fix position
              if (axisPosition !== 'left' && axisPosition !== 'right') {
                // Default left of Y
                axisPosition = axisPositionUsed.left ? 'right' : 'left';
              }
            }

            axisPositionUsed[axisPosition] = true;
            var axis = new Axis2D(dimName, createScaleByModel(axisModel), [0, 0], axisModel.get('type'), axisPosition);
            var isCategory = axis.type === 'category';
            axis.onBand = isCategory && axisModel.get('boundaryGap');
            axis.inverse = axisModel.get('inverse'); // Inject axis into axisModel

            axisModel.axis = axis; // Inject axisModel into axis

            axis.model = axisModel; // Inject grid info axis

            axis.grid = grid; // Index of axis, can be used as key

            axis.index = idx;

            grid._axesList.push(axis);

            axesMap[dimName][idx] = axis;
            axesCount[dimName]++;
          };
        }
      };
      /**
       * Update cartesian properties from series.
       */


      Grid.prototype._updateScale = function (ecModel, gridModel) {
        // Reset scale
        each(this._axesList, function (axis) {
          axis.scale.setExtent(Infinity, -Infinity);

          if (axis.type === 'category') {
            var categorySortInfo = axis.model.get('categorySortInfo');
            axis.scale.setSortInfo(categorySortInfo);
          }
        });
        ecModel.eachSeries(function (seriesModel) {
          if (isCartesian2DSeries(seriesModel)) {
            var axesModelMap = findAxisModels(seriesModel);
            var xAxisModel = axesModelMap.xAxisModel;
            var yAxisModel = axesModelMap.yAxisModel;

            if (!isAxisUsedInTheGrid(xAxisModel, gridModel) || !isAxisUsedInTheGrid(yAxisModel, gridModel)) {
              return;
            }

            var cartesian = this.getCartesian(xAxisModel.componentIndex, yAxisModel.componentIndex);
            var data = seriesModel.getData();
            var xAxis = cartesian.getAxis('x');
            var yAxis = cartesian.getAxis('y');
            unionExtent(data, xAxis);
            unionExtent(data, yAxis);
          }
        }, this);

        function unionExtent(data, axis) {
          each(getDataDimensionsOnAxis(data, axis.dim), function (dim) {
            axis.scale.unionExtentFromData(data, dim);
          });
        }
      };
      /**
       * @param dim 'x' or 'y' or 'auto' or null/undefined
       */


      Grid.prototype.getTooltipAxes = function (dim) {
        var baseAxes = [];
        var otherAxes = [];
        each(this.getCartesians(), function (cartesian) {
          var baseAxis = dim != null && dim !== 'auto' ? cartesian.getAxis(dim) : cartesian.getBaseAxis();
          var otherAxis = cartesian.getOtherAxis(baseAxis);
          indexOf(baseAxes, baseAxis) < 0 && baseAxes.push(baseAxis);
          indexOf(otherAxes, otherAxis) < 0 && otherAxes.push(otherAxis);
        });
        return {
          baseAxes: baseAxes,
          otherAxes: otherAxes
        };
      };

      Grid.create = function (ecModel, api) {
        var grids = [];
        ecModel.eachComponent('grid', function (gridModel, idx) {
          var grid = new Grid(gridModel, ecModel, api);
          grid.name = 'grid_' + idx; // dataSampling requires axis extent, so resize
          // should be performed in create stage.

          grid.resize(gridModel, api, true);
          gridModel.coordinateSystem = grid;
          grids.push(grid);
        }); // Inject the coordinateSystems into seriesModel

        ecModel.eachSeries(function (seriesModel) {
          if (!isCartesian2DSeries(seriesModel)) {
            return;
          }

          var axesModelMap = findAxisModels(seriesModel);
          var xAxisModel = axesModelMap.xAxisModel;
          var yAxisModel = axesModelMap.yAxisModel;
          var gridModel = xAxisModel.getCoordSysModel();

          if ("development" !== 'production') {
            if (!gridModel) {
              throw new Error('Grid "' + retrieve3(xAxisModel.get('gridIndex'), xAxisModel.get('gridId'), 0) + '" not found');
            }

            if (xAxisModel.getCoordSysModel() !== yAxisModel.getCoordSysModel()) {
              throw new Error('xAxis and yAxis must use the same grid');
            }
          }

          var grid = gridModel.coordinateSystem;
          seriesModel.coordinateSystem = grid.getCartesian(xAxisModel.componentIndex, yAxisModel.componentIndex);
        });
        return grids;
      }; // For deciding which dimensions to use when creating list data


      Grid.dimensions = cartesian2DDimensions;
      return Grid;
    }();
    /**
     * Check if the axis is used in the specified grid.
     */


    function isAxisUsedInTheGrid(axisModel, gridModel) {
      return axisModel.getCoordSysModel() === gridModel;
    }

    function fixAxisOnZero(axesMap, otherAxisDim, axis, // Key: see `getOnZeroRecordKey`
    onZeroRecords) {
      axis.getAxesOnZeroOf = function () {
        // TODO: onZero of multiple axes.
        return otherAxisOnZeroOf ? [otherAxisOnZeroOf] : [];
      }; // onZero can not be enabled in these two situations:
      // 1. When any other axis is a category axis.
      // 2. When no axis is cross 0 point.


      var otherAxes = axesMap[otherAxisDim];
      var otherAxisOnZeroOf;
      var axisModel = axis.model;
      var onZero = axisModel.get(['axisLine', 'onZero']);
      var onZeroAxisIndex = axisModel.get(['axisLine', 'onZeroAxisIndex']);

      if (!onZero) {
        return;
      } // If target axis is specified.


      if (onZeroAxisIndex != null) {
        if (canOnZeroToAxis(otherAxes[onZeroAxisIndex])) {
          otherAxisOnZeroOf = otherAxes[onZeroAxisIndex];
        }
      } else {
        // Find the first available other axis.
        for (var idx in otherAxes) {
          if (otherAxes.hasOwnProperty(idx) && canOnZeroToAxis(otherAxes[idx]) // Consider that two Y axes on one value axis,
          // if both onZero, the two Y axes overlap.
          && !onZeroRecords[getOnZeroRecordKey(otherAxes[idx])]) {
            otherAxisOnZeroOf = otherAxes[idx];
            break;
          }
        }
      }

      if (otherAxisOnZeroOf) {
        onZeroRecords[getOnZeroRecordKey(otherAxisOnZeroOf)] = true;
      }

      function getOnZeroRecordKey(axis) {
        return axis.dim + '_' + axis.index;
      }
    }

    function canOnZeroToAxis(axis) {
      return axis && axis.type !== 'category' && axis.type !== 'time' && ifAxisCrossZero(axis);
    }

    function updateAxisTransform(axis, coordBase) {
      var axisExtent = axis.getExtent();
      var axisExtentSum = axisExtent[0] + axisExtent[1]; // Fast transform

      axis.toGlobalCoord = axis.dim === 'x' ? function (coord) {
        return coord + coordBase;
      } : function (coord) {
        return axisExtentSum - coord + coordBase;
      };
      axis.toLocalCoord = axis.dim === 'x' ? function (coord) {
        return coord - coordBase;
      } : function (coord) {
        return axisExtentSum - coord + coordBase;
      };
    }

    var PI$4 = Math.PI;
    /**
     * A final axis is translated and rotated from a "standard axis".
     * So opt.position and opt.rotation is required.
     *
     * A standard axis is and axis from [0, 0] to [0, axisExtent[1]],
     * for example: (0, 0) ------------> (0, 50)
     *
     * nameDirection or tickDirection or labelDirection is 1 means tick
     * or label is below the standard axis, whereas is -1 means above
     * the standard axis. labelOffset means offset between label and axis,
     * which is useful when 'onZero', where axisLabel is in the grid and
     * label in outside grid.
     *
     * Tips: like always,
     * positive rotation represents anticlockwise, and negative rotation
     * represents clockwise.
     * The direction of position coordinate is the same as the direction
     * of screen coordinate.
     *
     * Do not need to consider axis 'inverse', which is auto processed by
     * axis extent.
     */

    var AxisBuilder =
    /** @class */
    function () {
      function AxisBuilder(axisModel, opt) {
        this.group = new Group();
        this.opt = opt;
        this.axisModel = axisModel; // Default value

        defaults(opt, {
          labelOffset: 0,
          nameDirection: 1,
          tickDirection: 1,
          labelDirection: 1,
          silent: true,
          handleAutoShown: function () {
            return true;
          }
        }); // FIXME Not use a seperate text group?

        var transformGroup = new Group({
          x: opt.position[0],
          y: opt.position[1],
          rotation: opt.rotation
        }); // this.group.add(transformGroup);
        // this._transformGroup = transformGroup;

        transformGroup.updateTransform();
        this._transformGroup = transformGroup;
      }

      AxisBuilder.prototype.hasBuilder = function (name) {
        return !!builders[name];
      };

      AxisBuilder.prototype.add = function (name) {
        builders[name](this.opt, this.axisModel, this.group, this._transformGroup);
      };

      AxisBuilder.prototype.getGroup = function () {
        return this.group;
      };

      AxisBuilder.innerTextLayout = function (axisRotation, textRotation, direction) {
        var rotationDiff = remRadian(textRotation - axisRotation);
        var textAlign;
        var textVerticalAlign;

        if (isRadianAroundZero(rotationDiff)) {
          // Label is parallel with axis line.
          textVerticalAlign = direction > 0 ? 'top' : 'bottom';
          textAlign = 'center';
        } else if (isRadianAroundZero(rotationDiff - PI$4)) {
          // Label is inverse parallel with axis line.
          textVerticalAlign = direction > 0 ? 'bottom' : 'top';
          textAlign = 'center';
        } else {
          textVerticalAlign = 'middle';

          if (rotationDiff > 0 && rotationDiff < PI$4) {
            textAlign = direction > 0 ? 'right' : 'left';
          } else {
            textAlign = direction > 0 ? 'left' : 'right';
          }
        }

        return {
          rotation: rotationDiff,
          textAlign: textAlign,
          textVerticalAlign: textVerticalAlign
        };
      };

      AxisBuilder.makeAxisEventDataBase = function (axisModel) {
        var eventData = {
          componentType: axisModel.mainType,
          componentIndex: axisModel.componentIndex
        };
        eventData[axisModel.mainType + 'Index'] = axisModel.componentIndex;
        return eventData;
      };

      AxisBuilder.isLabelSilent = function (axisModel) {
        var tooltipOpt = axisModel.get('tooltip');
        return axisModel.get('silent') // Consider mouse cursor, add these restrictions.
        || !(axisModel.get('triggerEvent') || tooltipOpt && tooltipOpt.show);
      };

      return AxisBuilder;
    }();
    var builders = {
      axisLine: function (opt, axisModel, group, transformGroup) {
        var shown = axisModel.get(['axisLine', 'show']);

        if (shown === 'auto' && opt.handleAutoShown) {
          shown = opt.handleAutoShown('axisLine');
        }

        if (!shown) {
          return;
        }

        var extent = axisModel.axis.getExtent();
        var matrix = transformGroup.transform;
        var pt1 = [extent[0], 0];
        var pt2 = [extent[1], 0];
        var inverse = pt1[0] > pt2[0];

        if (matrix) {
          applyTransform(pt1, pt1, matrix);
          applyTransform(pt2, pt2, matrix);
        }

        var lineStyle = extend({
          lineCap: 'round'
        }, axisModel.getModel(['axisLine', 'lineStyle']).getLineStyle());
        var line = new Line({
          shape: {
            x1: pt1[0],
            y1: pt1[1],
            x2: pt2[0],
            y2: pt2[1]
          },
          style: lineStyle,
          strokeContainThreshold: opt.strokeContainThreshold || 5,
          silent: true,
          z2: 1
        });
        subPixelOptimizeLine$1(line.shape, line.style.lineWidth);
        line.anid = 'line';
        group.add(line);
        var arrows = axisModel.get(['axisLine', 'symbol']);

        if (arrows != null) {
          var arrowSize = axisModel.get(['axisLine', 'symbolSize']);

          if (isString(arrows)) {
            // Use the same arrow for start and end point
            arrows = [arrows, arrows];
          }

          if (isString(arrowSize) || isNumber(arrowSize)) {
            // Use the same size for width and height
            arrowSize = [arrowSize, arrowSize];
          }

          var arrowOffset = normalizeSymbolOffset(axisModel.get(['axisLine', 'symbolOffset']) || 0, arrowSize);
          var symbolWidth_1 = arrowSize[0];
          var symbolHeight_1 = arrowSize[1];
          each([{
            rotate: opt.rotation + Math.PI / 2,
            offset: arrowOffset[0],
            r: 0
          }, {
            rotate: opt.rotation - Math.PI / 2,
            offset: arrowOffset[1],
            r: Math.sqrt((pt1[0] - pt2[0]) * (pt1[0] - pt2[0]) + (pt1[1] - pt2[1]) * (pt1[1] - pt2[1]))
          }], function (point, index) {
            if (arrows[index] !== 'none' && arrows[index] != null) {
              var symbol = createSymbol(arrows[index], -symbolWidth_1 / 2, -symbolHeight_1 / 2, symbolWidth_1, symbolHeight_1, lineStyle.stroke, true); // Calculate arrow position with offset

              var r = point.r + point.offset;
              var pt = inverse ? pt2 : pt1;
              symbol.attr({
                rotation: point.rotate,
                x: pt[0] + r * Math.cos(opt.rotation),
                y: pt[1] - r * Math.sin(opt.rotation),
                silent: true,
                z2: 11
              });
              group.add(symbol);
            }
          });
        }
      },
      axisTickLabel: function (opt, axisModel, group, transformGroup) {
        var ticksEls = buildAxisMajorTicks(group, transformGroup, axisModel, opt);
        var labelEls = buildAxisLabel(group, transformGroup, axisModel, opt);
        fixMinMaxLabelShow(axisModel, labelEls, ticksEls);
        buildAxisMinorTicks(group, transformGroup, axisModel, opt.tickDirection); // This bit fixes the label overlap issue for the time chart.
        // See https://github.com/apache/echarts/issues/14266 for more.

        if (axisModel.get(['axisLabel', 'hideOverlap'])) {
          var labelList = prepareLayoutList(map(labelEls, function (label) {
            return {
              label: label,
              priority: label.z2,
              defaultAttr: {
                ignore: label.ignore
              }
            };
          }));
          hideOverlap(labelList);
        }
      },
      axisName: function (opt, axisModel, group, transformGroup) {
        var name = retrieve(opt.axisName, axisModel.get('name'));

        if (!name) {
          return;
        }

        var nameLocation = axisModel.get('nameLocation');
        var nameDirection = opt.nameDirection;
        var textStyleModel = axisModel.getModel('nameTextStyle');
        var gap = axisModel.get('nameGap') || 0;
        var extent = axisModel.axis.getExtent();
        var gapSignal = extent[0] > extent[1] ? -1 : 1;
        var pos = [nameLocation === 'start' ? extent[0] - gapSignal * gap : nameLocation === 'end' ? extent[1] + gapSignal * gap : (extent[0] + extent[1]) / 2, // Reuse labelOffset.
        isNameLocationCenter(nameLocation) ? opt.labelOffset + nameDirection * gap : 0];
        var labelLayout;
        var nameRotation = axisModel.get('nameRotate');

        if (nameRotation != null) {
          nameRotation = nameRotation * PI$4 / 180; // To radian.
        }

        var axisNameAvailableWidth;

        if (isNameLocationCenter(nameLocation)) {
          labelLayout = AxisBuilder.innerTextLayout(opt.rotation, nameRotation != null ? nameRotation : opt.rotation, // Adapt to axis.
          nameDirection);
        } else {
          labelLayout = endTextLayout(opt.rotation, nameLocation, nameRotation || 0, extent);
          axisNameAvailableWidth = opt.axisNameAvailableWidth;

          if (axisNameAvailableWidth != null) {
            axisNameAvailableWidth = Math.abs(axisNameAvailableWidth / Math.sin(labelLayout.rotation));
            !isFinite(axisNameAvailableWidth) && (axisNameAvailableWidth = null);
          }
        }

        var textFont = textStyleModel.getFont();
        var truncateOpt = axisModel.get('nameTruncate', true) || {};
        var ellipsis = truncateOpt.ellipsis;
        var maxWidth = retrieve(opt.nameTruncateMaxWidth, truncateOpt.maxWidth, axisNameAvailableWidth);
        var textEl = new ZRText({
          x: pos[0],
          y: pos[1],
          rotation: labelLayout.rotation,
          silent: AxisBuilder.isLabelSilent(axisModel),
          style: createTextStyle(textStyleModel, {
            text: name,
            font: textFont,
            overflow: 'truncate',
            width: maxWidth,
            ellipsis: ellipsis,
            fill: textStyleModel.getTextColor() || axisModel.get(['axisLine', 'lineStyle', 'color']),
            align: textStyleModel.get('align') || labelLayout.textAlign,
            verticalAlign: textStyleModel.get('verticalAlign') || labelLayout.textVerticalAlign
          }),
          z2: 1
        });
        setTooltipConfig({
          el: textEl,
          componentModel: axisModel,
          itemName: name
        });
        textEl.__fullText = name; // Id for animation

        textEl.anid = 'name';

        if (axisModel.get('triggerEvent')) {
          var eventData = AxisBuilder.makeAxisEventDataBase(axisModel);
          eventData.targetType = 'axisName';
          eventData.name = name;
          getECData(textEl).eventData = eventData;
        } // FIXME


        transformGroup.add(textEl);
        textEl.updateTransform();
        group.add(textEl);
        textEl.decomposeTransform();
      }
    };

    function endTextLayout(rotation, textPosition, textRotate, extent) {
      var rotationDiff = remRadian(textRotate - rotation);
      var textAlign;
      var textVerticalAlign;
      var inverse = extent[0] > extent[1];
      var onLeft = textPosition === 'start' && !inverse || textPosition !== 'start' && inverse;

      if (isRadianAroundZero(rotationDiff - PI$4 / 2)) {
        textVerticalAlign = onLeft ? 'bottom' : 'top';
        textAlign = 'center';
      } else if (isRadianAroundZero(rotationDiff - PI$4 * 1.5)) {
        textVerticalAlign = onLeft ? 'top' : 'bottom';
        textAlign = 'center';
      } else {
        textVerticalAlign = 'middle';

        if (rotationDiff < PI$4 * 1.5 && rotationDiff > PI$4 / 2) {
          textAlign = onLeft ? 'left' : 'right';
        } else {
          textAlign = onLeft ? 'right' : 'left';
        }
      }

      return {
        rotation: rotationDiff,
        textAlign: textAlign,
        textVerticalAlign: textVerticalAlign
      };
    }

    function fixMinMaxLabelShow(axisModel, labelEls, tickEls) {
      if (shouldShowAllLabels(axisModel.axis)) {
        return;
      } // If min or max are user set, we need to check
      // If the tick on min(max) are overlap on their neighbour tick
      // If they are overlapped, we need to hide the min(max) tick label


      var showMinLabel = axisModel.get(['axisLabel', 'showMinLabel']);
      var showMaxLabel = axisModel.get(['axisLabel', 'showMaxLabel']); // FIXME
      // Have not consider onBand yet, where tick els is more than label els.

      labelEls = labelEls || [];
      tickEls = tickEls || [];
      var firstLabel = labelEls[0];
      var nextLabel = labelEls[1];
      var lastLabel = labelEls[labelEls.length - 1];
      var prevLabel = labelEls[labelEls.length - 2];
      var firstTick = tickEls[0];
      var nextTick = tickEls[1];
      var lastTick = tickEls[tickEls.length - 1];
      var prevTick = tickEls[tickEls.length - 2];

      if (showMinLabel === false) {
        ignoreEl(firstLabel);
        ignoreEl(firstTick);
      } else if (isTwoLabelOverlapped(firstLabel, nextLabel)) {
        if (showMinLabel) {
          ignoreEl(nextLabel);
          ignoreEl(nextTick);
        } else {
          ignoreEl(firstLabel);
          ignoreEl(firstTick);
        }
      }

      if (showMaxLabel === false) {
        ignoreEl(lastLabel);
        ignoreEl(lastTick);
      } else if (isTwoLabelOverlapped(prevLabel, lastLabel)) {
        if (showMaxLabel) {
          ignoreEl(prevLabel);
          ignoreEl(prevTick);
        } else {
          ignoreEl(lastLabel);
          ignoreEl(lastTick);
        }
      }
    }

    function ignoreEl(el) {
      el && (el.ignore = true);
    }

    function isTwoLabelOverlapped(current, next) {
      // current and next has the same rotation.
      var firstRect = current && current.getBoundingRect().clone();
      var nextRect = next && next.getBoundingRect().clone();

      if (!firstRect || !nextRect) {
        return;
      } // When checking intersect of two rotated labels, we use mRotationBack
      // to avoid that boundingRect is enlarge when using `boundingRect.applyTransform`.


      var mRotationBack = identity([]);
      rotate(mRotationBack, mRotationBack, -current.rotation);
      firstRect.applyTransform(mul$1([], mRotationBack, current.getLocalTransform()));
      nextRect.applyTransform(mul$1([], mRotationBack, next.getLocalTransform()));
      return firstRect.intersect(nextRect);
    }

    function isNameLocationCenter(nameLocation) {
      return nameLocation === 'middle' || nameLocation === 'center';
    }

    function createTicks(ticksCoords, tickTransform, tickEndCoord, tickLineStyle, anidPrefix) {
      var tickEls = [];
      var pt1 = [];
      var pt2 = [];

      for (var i = 0; i < ticksCoords.length; i++) {
        var tickCoord = ticksCoords[i].coord;
        pt1[0] = tickCoord;
        pt1[1] = 0;
        pt2[0] = tickCoord;
        pt2[1] = tickEndCoord;

        if (tickTransform) {
          applyTransform(pt1, pt1, tickTransform);
          applyTransform(pt2, pt2, tickTransform);
        } // Tick line, Not use group transform to have better line draw


        var tickEl = new Line({
          shape: {
            x1: pt1[0],
            y1: pt1[1],
            x2: pt2[0],
            y2: pt2[1]
          },
          style: tickLineStyle,
          z2: 2,
          autoBatch: true,
          silent: true
        });
        subPixelOptimizeLine$1(tickEl.shape, tickEl.style.lineWidth);
        tickEl.anid = anidPrefix + '_' + ticksCoords[i].tickValue;
        tickEls.push(tickEl);
      }

      return tickEls;
    }

    function buildAxisMajorTicks(group, transformGroup, axisModel, opt) {
      var axis = axisModel.axis;
      var tickModel = axisModel.getModel('axisTick');
      var shown = tickModel.get('show');

      if (shown === 'auto' && opt.handleAutoShown) {
        shown = opt.handleAutoShown('axisTick');
      }

      if (!shown || axis.scale.isBlank()) {
        return;
      }

      var lineStyleModel = tickModel.getModel('lineStyle');
      var tickEndCoord = opt.tickDirection * tickModel.get('length');
      var ticksCoords = axis.getTicksCoords();
      var ticksEls = createTicks(ticksCoords, transformGroup.transform, tickEndCoord, defaults(lineStyleModel.getLineStyle(), {
        stroke: axisModel.get(['axisLine', 'lineStyle', 'color'])
      }), 'ticks');

      for (var i = 0; i < ticksEls.length; i++) {
        group.add(ticksEls[i]);
      }

      return ticksEls;
    }

    function buildAxisMinorTicks(group, transformGroup, axisModel, tickDirection) {
      var axis = axisModel.axis;
      var minorTickModel = axisModel.getModel('minorTick');

      if (!minorTickModel.get('show') || axis.scale.isBlank()) {
        return;
      }

      var minorTicksCoords = axis.getMinorTicksCoords();

      if (!minorTicksCoords.length) {
        return;
      }

      var lineStyleModel = minorTickModel.getModel('lineStyle');
      var tickEndCoord = tickDirection * minorTickModel.get('length');
      var minorTickLineStyle = defaults(lineStyleModel.getLineStyle(), defaults(axisModel.getModel('axisTick').getLineStyle(), {
        stroke: axisModel.get(['axisLine', 'lineStyle', 'color'])
      }));

      for (var i = 0; i < minorTicksCoords.length; i++) {
        var minorTicksEls = createTicks(minorTicksCoords[i], transformGroup.transform, tickEndCoord, minorTickLineStyle, 'minorticks_' + i);

        for (var k = 0; k < minorTicksEls.length; k++) {
          group.add(minorTicksEls[k]);
        }
      }
    }

    function buildAxisLabel(group, transformGroup, axisModel, opt) {
      var axis = axisModel.axis;
      var show = retrieve(opt.axisLabelShow, axisModel.get(['axisLabel', 'show']));

      if (!show || axis.scale.isBlank()) {
        return;
      }

      var labelModel = axisModel.getModel('axisLabel');
      var labelMargin = labelModel.get('margin');
      var labels = axis.getViewLabels(); // Special label rotate.

      var labelRotation = (retrieve(opt.labelRotate, labelModel.get('rotate')) || 0) * PI$4 / 180;
      var labelLayout = AxisBuilder.innerTextLayout(opt.rotation, labelRotation, opt.labelDirection);
      var rawCategoryData = axisModel.getCategories && axisModel.getCategories(true);
      var labelEls = [];
      var silent = AxisBuilder.isLabelSilent(axisModel);
      var triggerEvent = axisModel.get('triggerEvent');
      each(labels, function (labelItem, index) {
        var tickValue = axis.scale.type === 'ordinal' ? axis.scale.getRawOrdinalNumber(labelItem.tickValue) : labelItem.tickValue;
        var formattedLabel = labelItem.formattedLabel;
        var rawLabel = labelItem.rawLabel;
        var itemLabelModel = labelModel;

        if (rawCategoryData && rawCategoryData[tickValue]) {
          var rawCategoryItem = rawCategoryData[tickValue];

          if (isObject(rawCategoryItem) && rawCategoryItem.textStyle) {
            itemLabelModel = new Model(rawCategoryItem.textStyle, labelModel, axisModel.ecModel);
          }
        }

        var textColor = itemLabelModel.getTextColor() || axisModel.get(['axisLine', 'lineStyle', 'color']);
        var tickCoord = axis.dataToCoord(tickValue);
        var textEl = new ZRText({
          x: tickCoord,
          y: opt.labelOffset + opt.labelDirection * labelMargin,
          rotation: labelLayout.rotation,
          silent: silent,
          z2: 10 + (labelItem.level || 0),
          style: createTextStyle(itemLabelModel, {
            text: formattedLabel,
            align: itemLabelModel.getShallow('align', true) || labelLayout.textAlign,
            verticalAlign: itemLabelModel.getShallow('verticalAlign', true) || itemLabelModel.getShallow('baseline', true) || labelLayout.textVerticalAlign,
            fill: isFunction(textColor) ? textColor( // (1) In category axis with data zoom, tick is not the original
            // index of axis.data. So tick should not be exposed to user
            // in category axis.
            // (2) Compatible with previous version, which always use formatted label as
            // input. But in interval scale the formatted label is like '223,445', which
            // maked user repalce ','. So we modify it to return original val but remain
            // it as 'string' to avoid error in replacing.
            axis.type === 'category' ? rawLabel : axis.type === 'value' ? tickValue + '' : tickValue, index) : textColor
          })
        });
        textEl.anid = 'label_' + tickValue; // Pack data for mouse event

        if (triggerEvent) {
          var eventData = AxisBuilder.makeAxisEventDataBase(axisModel);
          eventData.targetType = 'axisLabel';
          eventData.value = rawLabel;
          eventData.tickIndex = index;

          if (axis.type === 'category') {
            eventData.dataIndex = tickValue;
          }

          getECData(textEl).eventData = eventData;
        } // FIXME


        transformGroup.add(textEl);
        textEl.updateTransform();
        labelEls.push(textEl);
        group.add(textEl);
        textEl.decomposeTransform();
      });
      return labelEls;
    }

    function fixValue(axisModel) {
      var axisInfo = getAxisInfo(axisModel);

      if (!axisInfo) {
        return;
      }

      var axisPointerModel = axisInfo.axisPointerModel;
      var scale = axisInfo.axis.scale;
      var option = axisPointerModel.option;
      var status = axisPointerModel.get('status');
      var value = axisPointerModel.get('value'); // Parse init value for category and time axis.

      if (value != null) {
        value = scale.parse(value);
      }

      var useHandle = isHandleTrigger(axisPointerModel); // If `handle` used, `axisPointer` will always be displayed, so value
      // and status should be initialized.

      if (status == null) {
        option.status = useHandle ? 'show' : 'hide';
      }

      var extent = scale.getExtent().slice();
      extent[0] > extent[1] && extent.reverse();

      if ( // Pick a value on axis when initializing.
      value == null // If both `handle` and `dataZoom` are used, value may be out of axis extent,
      // where we should re-pick a value to keep `handle` displaying normally.
      || value > extent[1]) {
        // Make handle displayed on the end of the axis when init, which looks better.
        value = extent[1];
      }

      if (value < extent[0]) {
        value = extent[0];
      }

      option.value = value;

      if (useHandle) {
        option.status = axisInfo.axis.scale.isBlank() ? 'hide' : 'show';
      }
    }
    function getAxisInfo(axisModel) {
      var coordSysAxesInfo = (axisModel.ecModel.getComponent('axisPointer') || {}).coordSysAxesInfo;
      return coordSysAxesInfo && coordSysAxesInfo.axesInfo[makeKey(axisModel)];
    }
    function getAxisPointerModel(axisModel) {
      var axisInfo = getAxisInfo(axisModel);
      return axisInfo && axisInfo.axisPointerModel;
    }

    function isHandleTrigger(axisPointerModel) {
      return !!axisPointerModel.get(['handle', 'show']);
    }
    /**
     * @param {module:echarts/model/Model} model
     * @return {string} unique key
     */


    function makeKey(model) {
      return model.type + '||' + model.id;
    }

    var axisPointerClazz = {};
    /**
     * Base class of AxisView.
     */

    var AxisView =
    /** @class */
    function (_super) {
      __extends(AxisView, _super);

      function AxisView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = AxisView.type;
        return _this;
      }
      /**
       * @override
       */


      AxisView.prototype.render = function (axisModel, ecModel, api, payload) {
        // FIXME
        // This process should proformed after coordinate systems updated
        // (axis scale updated), and should be performed each time update.
        // So put it here temporarily, although it is not appropriate to
        // put a model-writing procedure in `view`.
        this.axisPointerClass && fixValue(axisModel);

        _super.prototype.render.apply(this, arguments);

        this._doUpdateAxisPointerClass(axisModel, api, true);
      };
      /**
       * Action handler.
       */


      AxisView.prototype.updateAxisPointer = function (axisModel, ecModel, api, payload) {
        this._doUpdateAxisPointerClass(axisModel, api, false);
      };
      /**
       * @override
       */


      AxisView.prototype.remove = function (ecModel, api) {
        var axisPointer = this._axisPointer;
        axisPointer && axisPointer.remove(api);
      };
      /**
       * @override
       */


      AxisView.prototype.dispose = function (ecModel, api) {
        this._disposeAxisPointer(api);

        _super.prototype.dispose.apply(this, arguments);
      };

      AxisView.prototype._doUpdateAxisPointerClass = function (axisModel, api, forceRender) {
        var Clazz = AxisView.getAxisPointerClass(this.axisPointerClass);

        if (!Clazz) {
          return;
        }

        var axisPointerModel = getAxisPointerModel(axisModel);
        axisPointerModel ? (this._axisPointer || (this._axisPointer = new Clazz())).render(axisModel, axisPointerModel, api, forceRender) : this._disposeAxisPointer(api);
      };

      AxisView.prototype._disposeAxisPointer = function (api) {
        this._axisPointer && this._axisPointer.dispose(api);
        this._axisPointer = null;
      };

      AxisView.registerAxisPointerClass = function (type, clazz) {
        if ("development" !== 'production') {
          if (axisPointerClazz[type]) {
            throw new Error('axisPointer ' + type + ' exists');
          }
        }

        axisPointerClazz[type] = clazz;
      };

      AxisView.getAxisPointerClass = function (type) {
        return type && axisPointerClazz[type];
      };
      AxisView.type = 'axis';
      return AxisView;
    }(ComponentView);

    var inner$6 = makeInner();
    function rectCoordAxisBuildSplitArea(axisView, axisGroup, axisModel, gridModel) {
      var axis = axisModel.axis;

      if (axis.scale.isBlank()) {
        return;
      } // TODO: TYPE


      var splitAreaModel = axisModel.getModel('splitArea');
      var areaStyleModel = splitAreaModel.getModel('areaStyle');
      var areaColors = areaStyleModel.get('color');
      var gridRect = gridModel.coordinateSystem.getRect();
      var ticksCoords = axis.getTicksCoords({
        tickModel: splitAreaModel,
        clamp: true
      });

      if (!ticksCoords.length) {
        return;
      } // For Making appropriate splitArea animation, the color and anid
      // should be corresponding to previous one if possible.


      var areaColorsLen = areaColors.length;
      var lastSplitAreaColors = inner$6(axisView).splitAreaColors;
      var newSplitAreaColors = createHashMap();
      var colorIndex = 0;

      if (lastSplitAreaColors) {
        for (var i = 0; i < ticksCoords.length; i++) {
          var cIndex = lastSplitAreaColors.get(ticksCoords[i].tickValue);

          if (cIndex != null) {
            colorIndex = (cIndex + (areaColorsLen - 1) * i) % areaColorsLen;
            break;
          }
        }
      }

      var prev = axis.toGlobalCoord(ticksCoords[0].coord);
      var areaStyle = areaStyleModel.getAreaStyle();
      areaColors = isArray(areaColors) ? areaColors : [areaColors];

      for (var i = 1; i < ticksCoords.length; i++) {
        var tickCoord = axis.toGlobalCoord(ticksCoords[i].coord);
        var x = void 0;
        var y = void 0;
        var width = void 0;
        var height = void 0;

        if (axis.isHorizontal()) {
          x = prev;
          y = gridRect.y;
          width = tickCoord - x;
          height = gridRect.height;
          prev = x + width;
        } else {
          x = gridRect.x;
          y = prev;
          width = gridRect.width;
          height = tickCoord - y;
          prev = y + height;
        }

        var tickValue = ticksCoords[i - 1].tickValue;
        tickValue != null && newSplitAreaColors.set(tickValue, colorIndex);
        axisGroup.add(new Rect({
          anid: tickValue != null ? 'area_' + tickValue : null,
          shape: {
            x: x,
            y: y,
            width: width,
            height: height
          },
          style: defaults({
            fill: areaColors[colorIndex]
          }, areaStyle),
          autoBatch: true,
          silent: true
        }));
        colorIndex = (colorIndex + 1) % areaColorsLen;
      }

      inner$6(axisView).splitAreaColors = newSplitAreaColors;
    }
    function rectCoordAxisHandleRemove(axisView) {
      inner$6(axisView).splitAreaColors = null;
    }

    var axisBuilderAttrs = ['axisLine', 'axisTickLabel', 'axisName'];
    var selfBuilderAttrs = ['splitArea', 'splitLine', 'minorSplitLine'];

    var CartesianAxisView =
    /** @class */
    function (_super) {
      __extends(CartesianAxisView, _super);

      function CartesianAxisView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = CartesianAxisView.type;
        _this.axisPointerClass = 'CartesianAxisPointer';
        return _this;
      }
      /**
       * @override
       */


      CartesianAxisView.prototype.render = function (axisModel, ecModel, api, payload) {
        this.group.removeAll();
        var oldAxisGroup = this._axisGroup;
        this._axisGroup = new Group();
        this.group.add(this._axisGroup);

        if (!axisModel.get('show')) {
          return;
        }

        var gridModel = axisModel.getCoordSysModel();
        var layout = layout$1(gridModel, axisModel);
        var axisBuilder = new AxisBuilder(axisModel, extend({
          handleAutoShown: function (elementType) {
            var cartesians = gridModel.coordinateSystem.getCartesians();

            for (var i = 0; i < cartesians.length; i++) {
              if (isIntervalOrLogScale(cartesians[i].getOtherAxis(axisModel.axis).scale)) {
                // Still show axis tick or axisLine if other axis is value / log
                return true;
              }
            } // Not show axisTick or axisLine if other axis is category / time


            return false;
          }
        }, layout));
        each(axisBuilderAttrs, axisBuilder.add, axisBuilder);

        this._axisGroup.add(axisBuilder.getGroup());

        each(selfBuilderAttrs, function (name) {
          if (axisModel.get([name, 'show'])) {
            axisElementBuilders[name](this, this._axisGroup, axisModel, gridModel);
          }
        }, this); // THIS is a special case for bar racing chart.
        // Update the axis label from the natural initial layout to
        // sorted layout should has no animation.

        var isInitialSortFromBarRacing = payload && payload.type === 'changeAxisOrder' && payload.isInitSort;

        if (!isInitialSortFromBarRacing) {
          groupTransition(oldAxisGroup, this._axisGroup, axisModel);
        }

        _super.prototype.render.call(this, axisModel, ecModel, api, payload);
      };

      CartesianAxisView.prototype.remove = function () {
        rectCoordAxisHandleRemove(this);
      };

      CartesianAxisView.type = 'cartesianAxis';
      return CartesianAxisView;
    }(AxisView);

    var axisElementBuilders = {
      splitLine: function (axisView, axisGroup, axisModel, gridModel) {
        var axis = axisModel.axis;

        if (axis.scale.isBlank()) {
          return;
        }

        var splitLineModel = axisModel.getModel('splitLine');
        var lineStyleModel = splitLineModel.getModel('lineStyle');
        var lineColors = lineStyleModel.get('color');
        lineColors = isArray(lineColors) ? lineColors : [lineColors];
        var gridRect = gridModel.coordinateSystem.getRect();
        var isHorizontal = axis.isHorizontal();
        var lineCount = 0;
        var ticksCoords = axis.getTicksCoords({
          tickModel: splitLineModel
        });
        var p1 = [];
        var p2 = [];
        var lineStyle = lineStyleModel.getLineStyle();

        for (var i = 0; i < ticksCoords.length; i++) {
          var tickCoord = axis.toGlobalCoord(ticksCoords[i].coord);

          if (isHorizontal) {
            p1[0] = tickCoord;
            p1[1] = gridRect.y;
            p2[0] = tickCoord;
            p2[1] = gridRect.y + gridRect.height;
          } else {
            p1[0] = gridRect.x;
            p1[1] = tickCoord;
            p2[0] = gridRect.x + gridRect.width;
            p2[1] = tickCoord;
          }

          var colorIndex = lineCount++ % lineColors.length;
          var tickValue = ticksCoords[i].tickValue;
          var line = new Line({
            anid: tickValue != null ? 'line_' + ticksCoords[i].tickValue : null,
            autoBatch: true,
            shape: {
              x1: p1[0],
              y1: p1[1],
              x2: p2[0],
              y2: p2[1]
            },
            style: defaults({
              stroke: lineColors[colorIndex]
            }, lineStyle),
            silent: true
          });
          subPixelOptimizeLine$1(line.shape, lineStyle.lineWidth);
          axisGroup.add(line);
        }
      },
      minorSplitLine: function (axisView, axisGroup, axisModel, gridModel) {
        var axis = axisModel.axis;
        var minorSplitLineModel = axisModel.getModel('minorSplitLine');
        var lineStyleModel = minorSplitLineModel.getModel('lineStyle');
        var gridRect = gridModel.coordinateSystem.getRect();
        var isHorizontal = axis.isHorizontal();
        var minorTicksCoords = axis.getMinorTicksCoords();

        if (!minorTicksCoords.length) {
          return;
        }

        var p1 = [];
        var p2 = [];
        var lineStyle = lineStyleModel.getLineStyle();

        for (var i = 0; i < minorTicksCoords.length; i++) {
          for (var k = 0; k < minorTicksCoords[i].length; k++) {
            var tickCoord = axis.toGlobalCoord(minorTicksCoords[i][k].coord);

            if (isHorizontal) {
              p1[0] = tickCoord;
              p1[1] = gridRect.y;
              p2[0] = tickCoord;
              p2[1] = gridRect.y + gridRect.height;
            } else {
              p1[0] = gridRect.x;
              p1[1] = tickCoord;
              p2[0] = gridRect.x + gridRect.width;
              p2[1] = tickCoord;
            }

            var line = new Line({
              anid: 'minor_line_' + minorTicksCoords[i][k].tickValue,
              autoBatch: true,
              shape: {
                x1: p1[0],
                y1: p1[1],
                x2: p2[0],
                y2: p2[1]
              },
              style: lineStyle,
              silent: true
            });
            subPixelOptimizeLine$1(line.shape, lineStyle.lineWidth);
            axisGroup.add(line);
          }
        }
      },
      splitArea: function (axisView, axisGroup, axisModel, gridModel) {
        rectCoordAxisBuildSplitArea(axisView, axisGroup, axisModel, gridModel);
      }
    };

    var CartesianXAxisView =
    /** @class */
    function (_super) {
      __extends(CartesianXAxisView, _super);

      function CartesianXAxisView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = CartesianXAxisView.type;
        return _this;
      }

      CartesianXAxisView.type = 'xAxis';
      return CartesianXAxisView;
    }(CartesianAxisView);

    var CartesianYAxisView =
    /** @class */
    function (_super) {
      __extends(CartesianYAxisView, _super);

      function CartesianYAxisView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = CartesianXAxisView.type;
        return _this;
      }

      CartesianYAxisView.type = 'yAxis';
      return CartesianYAxisView;
    }(CartesianAxisView);

    var GridView =
    /** @class */
    function (_super) {
      __extends(GridView, _super);

      function GridView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'grid';
        return _this;
      }

      GridView.prototype.render = function (gridModel, ecModel) {
        this.group.removeAll();

        if (gridModel.get('show')) {
          this.group.add(new Rect({
            shape: gridModel.coordinateSystem.getRect(),
            style: defaults({
              fill: gridModel.get('backgroundColor')
            }, gridModel.getItemStyle()),
            silent: true,
            z2: -1
          }));
        }
      };

      GridView.type = 'grid';
      return GridView;
    }(ComponentView);

    var extraOption = {
      // gridIndex: 0,
      // gridId: '',
      offset: 0
    };
    function install$4(registers) {
      registers.registerComponentView(GridView);
      registers.registerComponentModel(GridModel);
      registers.registerCoordinateSystem('cartesian2d', Grid);
      axisModelCreator(registers, 'x', CartesianAxisModel, extraOption);
      axisModelCreator(registers, 'y', CartesianAxisModel, extraOption);
      registers.registerComponentView(CartesianXAxisView);
      registers.registerComponentView(CartesianYAxisView);
      registers.registerPreprocessor(function (option) {
        // Only create grid when need
        if (option.xAxis && option.yAxis && !option.grid) {
          option.grid = {};
        }
      });
    }

    var DEFAULT_OPTION = {
      label: {
        enabled: true
      },
      decal: {
        show: false
      }
    };
    var inner$7 = makeInner();
    var decalPaletteScope = {};
    function ariaVisual(ecModel, api) {
      var ariaModel = ecModel.getModel('aria'); // See "area enabled" detection code in `GlobalModel.ts`.

      if (!ariaModel.get('enabled')) {
        return;
      }

      var defaultOption = clone(DEFAULT_OPTION);
      merge(defaultOption.label, ecModel.getLocaleModel().get('aria'), false);
      merge(ariaModel.option, defaultOption, false);
      setDecal();
      setLabel();

      function setDecal() {
        var decalModel = ariaModel.getModel('decal');
        var useDecal = decalModel.get('show');

        if (useDecal) {
          // Each type of series use one scope.
          // Pie and funnel are using different scopes.
          var paletteScopeGroupByType_1 = createHashMap();
          ecModel.eachSeries(function (seriesModel) {
            if (seriesModel.isColorBySeries()) {
              return;
            }

            var decalScope = paletteScopeGroupByType_1.get(seriesModel.type);

            if (!decalScope) {
              decalScope = {};
              paletteScopeGroupByType_1.set(seriesModel.type, decalScope);
            }

            inner$7(seriesModel).scope = decalScope;
          });
          ecModel.eachRawSeries(function (seriesModel) {
            if (ecModel.isSeriesFiltered(seriesModel)) {
              return;
            }

            if (isFunction(seriesModel.enableAriaDecal)) {
              // Let series define how to use decal palette on data
              seriesModel.enableAriaDecal();
              return;
            }

            var data = seriesModel.getData();

            if (!seriesModel.isColorBySeries()) {
              var dataAll_1 = seriesModel.getRawData();
              var idxMap_1 = {};
              var decalScope_1 = inner$7(seriesModel).scope;
              data.each(function (idx) {
                var rawIdx = data.getRawIndex(idx);
                idxMap_1[rawIdx] = idx;
              });
              var dataCount_1 = dataAll_1.count();
              dataAll_1.each(function (rawIdx) {
                var idx = idxMap_1[rawIdx];
                var name = dataAll_1.getName(rawIdx) || rawIdx + '';
                var paletteDecal = getDecalFromPalette(seriesModel.ecModel, name, decalScope_1, dataCount_1);
                var specifiedDecal = data.getItemVisual(idx, 'decal');
                data.setItemVisual(idx, 'decal', mergeDecal(specifiedDecal, paletteDecal));
              });
            } else {
              var paletteDecal = getDecalFromPalette(seriesModel.ecModel, seriesModel.name, decalPaletteScope, ecModel.getSeriesCount());
              var specifiedDecal = data.getVisual('decal');
              data.setVisual('decal', mergeDecal(specifiedDecal, paletteDecal));
            }

            function mergeDecal(specifiedDecal, paletteDecal) {
              // Merge decal from palette to decal from itemStyle.
              // User do not need to specify all of the decal props.
              var resultDecal = specifiedDecal ? extend(extend({}, paletteDecal), specifiedDecal) : paletteDecal;
              resultDecal.dirty = true;
              return resultDecal;
            }
          });
        }
      }

      function setLabel() {
        var labelLocale = ecModel.getLocaleModel().get('aria');
        var labelModel = ariaModel.getModel('label');
        labelModel.option = defaults(labelModel.option, labelLocale);

        if (!labelModel.get('enabled')) {
          return;
        }

        var dom = api.getZr().dom;

        if (labelModel.get('description')) {
          dom.setAttribute('aria-label', labelModel.get('description'));
          return;
        }

        var seriesCnt = ecModel.getSeriesCount();
        var maxDataCnt = labelModel.get(['data', 'maxCount']) || 10;
        var maxSeriesCnt = labelModel.get(['series', 'maxCount']) || 10;
        var displaySeriesCnt = Math.min(seriesCnt, maxSeriesCnt);
        var ariaLabel;

        if (seriesCnt < 1) {
          // No series, no aria label
          return;
        } else {
          var title = getTitle();

          if (title) {
            var withTitle = labelModel.get(['general', 'withTitle']);
            ariaLabel = replace(withTitle, {
              title: title
            });
          } else {
            ariaLabel = labelModel.get(['general', 'withoutTitle']);
          }

          var seriesLabels_1 = [];
          var prefix = seriesCnt > 1 ? labelModel.get(['series', 'multiple', 'prefix']) : labelModel.get(['series', 'single', 'prefix']);
          ariaLabel += replace(prefix, {
            seriesCount: seriesCnt
          });
          ecModel.eachSeries(function (seriesModel, idx) {
            if (idx < displaySeriesCnt) {
              var seriesLabel = void 0;
              var seriesName = seriesModel.get('name');
              var withName = seriesName ? 'withName' : 'withoutName';
              seriesLabel = seriesCnt > 1 ? labelModel.get(['series', 'multiple', withName]) : labelModel.get(['series', 'single', withName]);
              seriesLabel = replace(seriesLabel, {
                seriesId: seriesModel.seriesIndex,
                seriesName: seriesModel.get('name'),
                seriesType: getSeriesTypeName(seriesModel.subType)
              });
              var data = seriesModel.getData();

              if (data.count() > maxDataCnt) {
                // Show part of data
                var partialLabel = labelModel.get(['data', 'partialData']);
                seriesLabel += replace(partialLabel, {
                  displayCnt: maxDataCnt
                });
              } else {
                seriesLabel += labelModel.get(['data', 'allData']);
              }

              var middleSeparator_1 = labelModel.get(['data', 'separator', 'middle']);
              var endSeparator_1 = labelModel.get(['data', 'separator', 'end']);
              var dataLabels = [];

              for (var i = 0; i < data.count(); i++) {
                if (i < maxDataCnt) {
                  var name_1 = data.getName(i);
                  var value = data.getValues(i);
                  var dataLabel = labelModel.get(['data', name_1 ? 'withName' : 'withoutName']);
                  dataLabels.push(replace(dataLabel, {
                    name: name_1,
                    value: value.join(middleSeparator_1)
                  }));
                }
              }

              seriesLabel += dataLabels.join(middleSeparator_1) + endSeparator_1;
              seriesLabels_1.push(seriesLabel);
            }
          });
          var separatorModel = labelModel.getModel(['series', 'multiple', 'separator']);
          var middleSeparator = separatorModel.get('middle');
          var endSeparator = separatorModel.get('end');
          ariaLabel += seriesLabels_1.join(middleSeparator) + endSeparator;
          dom.setAttribute('aria-label', ariaLabel);
        }
      }

      function replace(str, keyValues) {
        if (!isString(str)) {
          return str;
        }

        var result = str;
        each(keyValues, function (value, key) {
          result = result.replace(new RegExp('\\{\\s*' + key + '\\s*\\}', 'g'), value);
        });
        return result;
      }

      function getTitle() {
        var title = ecModel.get('title');

        if (title && title.length) {
          title = title[0];
        }

        return title && title.text;
      }

      function getSeriesTypeName(type) {
        return ecModel.getLocaleModel().get(['series', 'typeNames'])[type] || '自定义图';
      }
    }

    function ariaPreprocessor(option) {
      if (!option || !option.aria) {
        return;
      }

      var aria = option.aria; // aria.show is deprecated and should use aria.enabled instead

      if (aria.show != null) {
        aria.enabled = aria.show;
      }

      aria.label = aria.label || {}; // move description, general, series, data to be under aria.label

      each(['description', 'general', 'series', 'data'], function (name) {
        if (aria[name] != null) {
          aria.label[name] = aria[name];
        }
      });
    }

    function install$5(registers) {
      registers.registerPreprocessor(ariaPreprocessor);
      registers.registerVisual(registers.PRIORITY.VISUAL.ARIA, ariaVisual);
    }

    var DatasetModel =
    /** @class */
    function (_super) {
      __extends(DatasetModel, _super);

      function DatasetModel() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'dataset';
        return _this;
      }

      DatasetModel.prototype.init = function (option, parentModel, ecModel) {
        _super.prototype.init.call(this, option, parentModel, ecModel);

        this._sourceManager = new SourceManager(this);
        disableTransformOptionMerge(this);
      };

      DatasetModel.prototype.mergeOption = function (newOption, ecModel) {
        _super.prototype.mergeOption.call(this, newOption, ecModel);

        disableTransformOptionMerge(this);
      };

      DatasetModel.prototype.optionUpdated = function () {
        this._sourceManager.dirty();
      };

      DatasetModel.prototype.getSourceManager = function () {
        return this._sourceManager;
      };

      DatasetModel.type = 'dataset';
      DatasetModel.defaultOption = {
        seriesLayoutBy: SERIES_LAYOUT_BY_COLUMN
      };
      return DatasetModel;
    }(ComponentModel);

    var DatasetView =
    /** @class */
    function (_super) {
      __extends(DatasetView, _super);

      function DatasetView() {
        var _this = _super !== null && _super.apply(this, arguments) || this;

        _this.type = 'dataset';
        return _this;
      }

      DatasetView.type = 'dataset';
      return DatasetView;
    }(ComponentView);

    function install$6(registers) {
      registers.registerComponentModel(DatasetModel);
      registers.registerComponentView(DatasetView);
    }

    use([install]);
    use([install$1, install$2, install$3]);
    use([install$4, install$5, install$6]);

    exports.Axis = Axis;
    exports.ChartView = ChartView;
    exports.ComponentModel = ComponentModel;
    exports.ComponentView = ComponentView;
    exports.List = SeriesData;
    exports.Model = Model;
    exports.PRIORITY = PRIORITY;
    exports.SeriesModel = SeriesModel;
    exports.color = color;
    exports.connect = connect;
    exports.dataTool = dataTool;
    exports.dependencies = dependencies;
    exports.disConnect = disConnect;
    exports.disconnect = disconnect;
    exports.dispose = dispose$1;
    exports.env = env;
    exports.extendChartView = extendChartView;
    exports.extendComponentModel = extendComponentModel;
    exports.extendComponentView = extendComponentView;
    exports.extendSeriesModel = extendSeriesModel;
    exports.format = format$1;
    exports.getCoordinateSystemDimensions = getCoordinateSystemDimensions;
    exports.getInstanceByDom = getInstanceByDom;
    exports.getInstanceById = getInstanceById;
    exports.getMap = getMap;
    exports.graphic = graphic;
    exports.helper = helper;
    exports.init = init$1;
    exports.innerDrawElementOnCanvas = brushSingle;
    exports.matrix = matrix;
    exports.number = number;
    exports.parseGeoJSON = parseGeoJSON;
    exports.parseGeoJson = parseGeoJSON;
    exports.registerAction = registerAction;
    exports.registerCoordinateSystem = registerCoordinateSystem;
    exports.registerLayout = registerLayout;
    exports.registerLoading = registerLoading;
    exports.registerLocale = registerLocale;
    exports.registerMap = registerMap;
    exports.registerPostInit = registerPostInit;
    exports.registerPostUpdate = registerPostUpdate;
    exports.registerPreprocessor = registerPreprocessor;
    exports.registerProcessor = registerProcessor;
    exports.registerTheme = registerTheme;
    exports.registerTransform = registerTransform;
    exports.registerUpdateLifecycle = registerUpdateLifecycle;
    exports.registerVisual = registerVisual;
    exports.setCanvasCreator = setCanvasCreator;
    exports.setPlatformAPI = setPlatformAPI;
    exports.throttle = throttle;
    exports.time = time;
    exports.use = use;
    exports.util = util$1;
    exports.vector = vector;
    exports.version = version$1;
    exports.zrUtil = util;
    exports.zrender = zrender;

    Object.defineProperty(exports, '__esModule', { value: true });

})));
//# sourceMappingURL=echarts.simple.js.map
