|   | 
| /* | 
| * 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. | 
| */ | 
| import { __extends } from "tslib"; | 
| /** | 
|  * Caution: If the mechanism should be changed some day, these cases | 
|  * should be considered: | 
|  * | 
|  * (1) In `merge option` mode, if using the same option to call `setOption` | 
|  * many times, the result should be the same (try our best to ensure that). | 
|  * (2) In `merge option` mode, if a component has no id/name specified, it | 
|  * will be merged by index, and the result sequence of the components is | 
|  * consistent to the original sequence. | 
|  * (3) In `replaceMerge` mode, keep the result sequence of the components is | 
|  * consistent to the original sequence, even though there might result in "hole". | 
|  * (4) `reset` feature (in toolbox). Find detailed info in comments about | 
|  * `mergeOption` in module:echarts/model/OptionManager. | 
|  */ | 
| import { each, filter, isArray, isObject, isString, createHashMap, assert, clone, merge, extend, mixin, isFunction } from 'zrender/lib/core/util.js'; | 
| import * as modelUtil from '../util/model.js'; | 
| import Model from './Model.js'; | 
| import ComponentModel from './Component.js'; | 
| import globalDefault from './globalDefault.js'; | 
| import { resetSourceDefaulter } from '../data/helper/sourceHelper.js'; | 
| import { concatInternalOptions } from './internalComponentCreator.js'; | 
| import { PaletteMixin } from './mixin/palette.js'; | 
| import { error, warn } from '../util/log.js'; | 
| // ----------------------- | 
| // 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 (process.env.NODE_ENV !== '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 (process.env.NODE_ENV !== '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, modelUtil.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 = modelUtil.mappingToExists(oldCmptList, newCmptOptionList, mergeMode); | 
|       // Set mainType and complete subType. | 
|       modelUtil.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 (process.env.NODE_ENV !== '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 (process.env.NODE_ENV !== '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 = modelUtil.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] && !modelUtil.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(modelUtil.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 = modelUtil.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 (process.env.NODE_ENV !== '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 = modelUtil.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 = modelUtil.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(modelUtil.normalizeToArray(opts.replaceMerge), function (mainType) { | 
|     if (process.env.NODE_ENV !== 'production') { | 
|       assert(ComponentModel.hasClass(mainType), '"' + mainType + '" is not valid component main type in "replaceMerge"'); | 
|     } | 
|     replaceMergeMainTypeMap.set(mainType, true); | 
|   }); | 
|   return { | 
|     replaceMergeMainTypeMap: replaceMergeMainTypeMap | 
|   }; | 
| } | 
| mixin(GlobalModel, PaletteMixin); | 
| export default GlobalModel; |