|   | 
| /* | 
| * 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; | 
| }(); | 
|   | 
| export default DataDiffer; |