14d6c458bSopenharmony_ci/*
24d6c458bSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.
34d6c458bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44d6c458bSopenharmony_ci * you may not use this file except in compliance with the License.
54d6c458bSopenharmony_ci * You may obtain a copy of the License at
64d6c458bSopenharmony_ci *
74d6c458bSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84d6c458bSopenharmony_ci *
94d6c458bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104d6c458bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114d6c458bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124d6c458bSopenharmony_ci * See the License for the specific language governing permissions and
134d6c458bSopenharmony_ci * limitations under the License.
144d6c458bSopenharmony_ci */
154d6c458bSopenharmony_citype CompFun<T> = (firstValue: T, secondValue: T) => boolean;
164d6c458bSopenharmony_ci
174d6c458bSopenharmony_cifunction hashCode(element: Object): number {
184d6c458bSopenharmony_ci  let str: string = '';
194d6c458bSopenharmony_ci  str = String(element);
204d6c458bSopenharmony_ci  let hash: number = 0;
214d6c458bSopenharmony_ci  if (hash === 0 && str.length > 0) {
224d6c458bSopenharmony_ci    for (let i: number = 0; i < str.length; i++) {
234d6c458bSopenharmony_ci      let char: number = 0;
244d6c458bSopenharmony_ci      char = str.charCodeAt(i);
254d6c458bSopenharmony_ci      hash = ((hash << 5) - hash) + char; // 5 : means number
264d6c458bSopenharmony_ci      hash = hash & hash;
274d6c458bSopenharmony_ci    }
284d6c458bSopenharmony_ci  }
294d6c458bSopenharmony_ci  return hash;
304d6c458bSopenharmony_ci}
314d6c458bSopenharmony_cifunction insert<T>(a: Array<T>, index: number, value: T): void {
324d6c458bSopenharmony_ci  for (let i: number = a.length; i > index; i--) {
334d6c458bSopenharmony_ci    a[i] = a[i - 1];
344d6c458bSopenharmony_ci  }
354d6c458bSopenharmony_ci  a[index] = value;
364d6c458bSopenharmony_ci}
374d6c458bSopenharmony_cienum ComparResult {
384d6c458bSopenharmony_ci  LESS_THAN = -1,
394d6c458bSopenharmony_ci  BIGGER_THAN = 1,
404d6c458bSopenharmony_ci  EQUALS = 0
414d6c458bSopenharmony_ci}
424d6c458bSopenharmony_cifunction compareToString(string1: String, string2: String): number {
434d6c458bSopenharmony_ci  let len1: number = string1.length;
444d6c458bSopenharmony_ci  let len2: number = string2.length;
454d6c458bSopenharmony_ci  let lim: number = 0;
464d6c458bSopenharmony_ci  lim = (len1 > len2 ? len2 : len1);
474d6c458bSopenharmony_ci  let k: number = 0;
484d6c458bSopenharmony_ci  while (k < lim) {
494d6c458bSopenharmony_ci    if (string1.charCodeAt(k) === string2.charCodeAt(k)) {
504d6c458bSopenharmony_ci      k++;
514d6c458bSopenharmony_ci      if (k === lim) {
524d6c458bSopenharmony_ci        return len1 > len2 ? ComparResult.BIGGER_THAN : ComparResult.LESS_THAN;
534d6c458bSopenharmony_ci      }
544d6c458bSopenharmony_ci      continue;
554d6c458bSopenharmony_ci    }
564d6c458bSopenharmony_ci    return string1.charCodeAt(k) > string2.charCodeAt(k) ? ComparResult.BIGGER_THAN : ComparResult.LESS_THAN;
574d6c458bSopenharmony_ci  }
584d6c458bSopenharmony_ci  throw new Error('this compare function run error');
594d6c458bSopenharmony_ci}
604d6c458bSopenharmony_cifunction currencyCompare(a: string | Object, b: string | Object, compareFn?: CompFun<string | Object>): number {
614d6c458bSopenharmony_ci  if (a === b) {
624d6c458bSopenharmony_ci    return ComparResult.EQUALS;
634d6c458bSopenharmony_ci  }
644d6c458bSopenharmony_ci  if (a instanceof Pair && b instanceof Pair) {
654d6c458bSopenharmony_ci    return currencyCompare(a.key, b.key, compareFn);
664d6c458bSopenharmony_ci  }
674d6c458bSopenharmony_ci  if (compareFn !== undefined) {
684d6c458bSopenharmony_ci    return compareFn(a, b) ? ComparResult.BIGGER_THAN : ComparResult.LESS_THAN;
694d6c458bSopenharmony_ci  }
704d6c458bSopenharmony_ci  if (typeof a === 'number' && typeof b === 'number') {
714d6c458bSopenharmony_ci    if (a > b) {
724d6c458bSopenharmony_ci      return ComparResult.BIGGER_THAN;
734d6c458bSopenharmony_ci    } else {
744d6c458bSopenharmony_ci      return ComparResult.LESS_THAN;
754d6c458bSopenharmony_ci    }
764d6c458bSopenharmony_ci  } else if (typeof a === 'string' && typeof b === 'string') {
774d6c458bSopenharmony_ci    return compareToString(a, b);
784d6c458bSopenharmony_ci  } else if (typeof a === 'string' && typeof b === 'number') {
794d6c458bSopenharmony_ci    return ComparResult.BIGGER_THAN;
804d6c458bSopenharmony_ci  } else if (typeof a === 'number' && typeof b === 'string') {
814d6c458bSopenharmony_ci    return ComparResult.LESS_THAN;
824d6c458bSopenharmony_ci  }
834d6c458bSopenharmony_ci  throw new Error('This form of comparison is not supported');
844d6c458bSopenharmony_ci}
854d6c458bSopenharmony_cifunction isIncludeToArray(array1: Array<number>, array2: Array<number>): boolean {
864d6c458bSopenharmony_ci  let newList: number[] = [];
874d6c458bSopenharmony_ci  newList = array1.filter((val) => {
884d6c458bSopenharmony_ci    return array2.indexOf(val) > -1;
894d6c458bSopenharmony_ci  });
904d6c458bSopenharmony_ci  if (newList.length === array2.length) {
914d6c458bSopenharmony_ci    return true;
924d6c458bSopenharmony_ci  }
934d6c458bSopenharmony_ci  return false;
944d6c458bSopenharmony_ci}
954d6c458bSopenharmony_ciclass Pair<K, V> {
964d6c458bSopenharmony_ci  key: K;
974d6c458bSopenharmony_ci  value: V;
984d6c458bSopenharmony_ci  constructor(key: K, value: V = key as unknown as V) {
994d6c458bSopenharmony_ci    this.key = key;
1004d6c458bSopenharmony_ci    this.value = value;
1014d6c458bSopenharmony_ci  }
1024d6c458bSopenharmony_ci  entry(): [K, V] {
1034d6c458bSopenharmony_ci    return [this.key, this.value];
1044d6c458bSopenharmony_ci  }
1054d6c458bSopenharmony_ci  toString(): string {
1064d6c458bSopenharmony_ci    return `[#${this.key}: ${this.value}]`;
1074d6c458bSopenharmony_ci  }
1084d6c458bSopenharmony_ci}
1094d6c458bSopenharmony_ciclass PlainArrayMembers<T> {
1104d6c458bSopenharmony_ci  keys: Array<number>;
1114d6c458bSopenharmony_ci  values: Array<T>;
1124d6c458bSopenharmony_ci  constructor() {
1134d6c458bSopenharmony_ci    this.keys = [];
1144d6c458bSopenharmony_ci    this.values = [];
1154d6c458bSopenharmony_ci  }
1164d6c458bSopenharmony_ci}
1174d6c458bSopenharmony_ciclass PlainArrayClass<T> {
1184d6c458bSopenharmony_ci  protected memberNumber: number;
1194d6c458bSopenharmony_ci  protected members: PlainArrayMembers<T>;
1204d6c458bSopenharmony_ci  constructor() {
1214d6c458bSopenharmony_ci    this.memberNumber = 0;
1224d6c458bSopenharmony_ci    this.members = new PlainArrayMembers<T>();
1234d6c458bSopenharmony_ci  }
1244d6c458bSopenharmony_ci  protected addmember(key: number, value: T): void {
1254d6c458bSopenharmony_ci    let index: number = 0;
1264d6c458bSopenharmony_ci    index = this.binarySearchAtPlain(key);
1274d6c458bSopenharmony_ci    if (index >= 0) {
1284d6c458bSopenharmony_ci      this.members.keys[index] = key;
1294d6c458bSopenharmony_ci      this.members.values[index] = value;
1304d6c458bSopenharmony_ci    } else {
1314d6c458bSopenharmony_ci      index = ~index;
1324d6c458bSopenharmony_ci      insert(this.members.keys, index, key);
1334d6c458bSopenharmony_ci      insert(this.members.values, index, value);
1344d6c458bSopenharmony_ci      this.memberNumber++;
1354d6c458bSopenharmony_ci    }
1364d6c458bSopenharmony_ci  }
1374d6c458bSopenharmony_ci  protected deletemember(index: number, safeSize: number = 1): T {
1384d6c458bSopenharmony_ci    this.memberNumber -= safeSize;
1394d6c458bSopenharmony_ci    this.members.keys.splice(index, safeSize);
1404d6c458bSopenharmony_ci    let removeValue = this.members.values.splice(index, safeSize)[0];
1414d6c458bSopenharmony_ci    return removeValue;
1424d6c458bSopenharmony_ci  }
1434d6c458bSopenharmony_ci  protected binarySearchAtPlain(key: number, startIndex: number = 0, endIndex: number = this.memberNumber): number {
1444d6c458bSopenharmony_ci    let low: number = startIndex;
1454d6c458bSopenharmony_ci    let high: number = endIndex - 1;
1464d6c458bSopenharmony_ci    while (low <= high) {
1474d6c458bSopenharmony_ci      let mid: number = (low + high) >>> 1;
1484d6c458bSopenharmony_ci      let midVal: number = this.members.keys[mid];
1494d6c458bSopenharmony_ci      if (midVal < key) {
1504d6c458bSopenharmony_ci        low = mid + 1;
1514d6c458bSopenharmony_ci      } else {
1524d6c458bSopenharmony_ci        if (midVal <= key) {
1534d6c458bSopenharmony_ci          return mid;
1544d6c458bSopenharmony_ci        }
1554d6c458bSopenharmony_ci        high = mid - 1;
1564d6c458bSopenharmony_ci      }
1574d6c458bSopenharmony_ci    }
1584d6c458bSopenharmony_ci    return -(low + 1);
1594d6c458bSopenharmony_ci  }
1604d6c458bSopenharmony_ci}
1614d6c458bSopenharmony_ciclass LightWeightMembers<K, V> {
1624d6c458bSopenharmony_ci  hashs: Array<number>;
1634d6c458bSopenharmony_ci  keys: Array<K>;
1644d6c458bSopenharmony_ci  values: Array<V>;
1654d6c458bSopenharmony_ci  constructor() {
1664d6c458bSopenharmony_ci    this.hashs = [];
1674d6c458bSopenharmony_ci    this.keys = [];
1684d6c458bSopenharmony_ci    this.values = [];
1694d6c458bSopenharmony_ci  }
1704d6c458bSopenharmony_ci}
1714d6c458bSopenharmony_ciclass LightWeightClass<K, V> {
1724d6c458bSopenharmony_ci  protected memberNumber: number;
1734d6c458bSopenharmony_ci  protected members: LightWeightMembers<K, V>;
1744d6c458bSopenharmony_ci  protected capacity: number = 8; // 8 : means number
1754d6c458bSopenharmony_ci  constructor() {
1764d6c458bSopenharmony_ci    this.memberNumber = 0;
1774d6c458bSopenharmony_ci    this.members = new LightWeightMembers<K, V>();
1784d6c458bSopenharmony_ci  }
1794d6c458bSopenharmony_ci  protected addmember(key: K, value: V = key as unknown as V): void {
1804d6c458bSopenharmony_ci    let hash: number = 0;
1814d6c458bSopenharmony_ci    hash = hashCode(key);
1824d6c458bSopenharmony_ci    let index: number = 0;
1834d6c458bSopenharmony_ci    index = this.binarySearchAtLightWeight(hash);
1844d6c458bSopenharmony_ci    if (index >= 0) {
1854d6c458bSopenharmony_ci      this.members.keys[index] = key;
1864d6c458bSopenharmony_ci      this.members.values[index] = value;
1874d6c458bSopenharmony_ci    } else {
1884d6c458bSopenharmony_ci      index = ~index;
1894d6c458bSopenharmony_ci      insert(this.members.hashs, index, hash);
1904d6c458bSopenharmony_ci      insert(this.members.keys, index, key);
1914d6c458bSopenharmony_ci      insert(this.members.values, index, value);
1924d6c458bSopenharmony_ci      this.memberNumber++;
1934d6c458bSopenharmony_ci    }
1944d6c458bSopenharmony_ci    if (this.capacity < this.memberNumber) {
1954d6c458bSopenharmony_ci      this.ensureCapacity(1);
1964d6c458bSopenharmony_ci    }
1974d6c458bSopenharmony_ci  }
1984d6c458bSopenharmony_ci  protected getIndexByKey(key: K): number {
1994d6c458bSopenharmony_ci    let hash: number = 0;
2004d6c458bSopenharmony_ci    hash = hashCode(key);
2014d6c458bSopenharmony_ci    let index: number = 0;
2024d6c458bSopenharmony_ci    index = this.binarySearchAtLightWeight(hash);
2034d6c458bSopenharmony_ci    // js ( A negative number indicates an inverted number in the array )
2044d6c458bSopenharmony_ci    if (index < 0 || index >= this.memberNumber) {
2054d6c458bSopenharmony_ci      return -1;
2064d6c458bSopenharmony_ci    }
2074d6c458bSopenharmony_ci    return index;
2084d6c458bSopenharmony_ci  }
2094d6c458bSopenharmony_ci  protected deletemember(key: K): V {
2104d6c458bSopenharmony_ci    let result: V = undefined;
2114d6c458bSopenharmony_ci    let index: number = 0;
2124d6c458bSopenharmony_ci    index = this.getIndexByKey(key);
2134d6c458bSopenharmony_ci    if (index < 0) {
2144d6c458bSopenharmony_ci      return result;
2154d6c458bSopenharmony_ci    }
2164d6c458bSopenharmony_ci    this.memberNumber--;
2174d6c458bSopenharmony_ci    this.members.hashs.splice(index, 1);
2184d6c458bSopenharmony_ci    this.members.keys.splice(index, 1);
2194d6c458bSopenharmony_ci    return this.members.values.splice(index, 1)[0];
2204d6c458bSopenharmony_ci  }
2214d6c458bSopenharmony_ci  protected ensureCapacity(addCapacity: number = 1): void {
2224d6c458bSopenharmony_ci    let tempCapacity: number = 0;
2234d6c458bSopenharmony_ci    tempCapacity = this.capacity + addCapacity;
2244d6c458bSopenharmony_ci    while (this.capacity < tempCapacity) {
2254d6c458bSopenharmony_ci      this.capacity = 2 * this.capacity; // 2 : means number
2264d6c458bSopenharmony_ci    }
2274d6c458bSopenharmony_ci  }
2284d6c458bSopenharmony_ci  protected getIndex(key: K): number {
2294d6c458bSopenharmony_ci    let hash: number = 0;
2304d6c458bSopenharmony_ci    hash = hashCode(key);
2314d6c458bSopenharmony_ci    let index: number = 0;
2324d6c458bSopenharmony_ci    index = this.binarySearchAtLightWeight(hash);
2334d6c458bSopenharmony_ci    if (index < 0) {
2344d6c458bSopenharmony_ci      index = ~index;
2354d6c458bSopenharmony_ci    }
2364d6c458bSopenharmony_ci    return index;
2374d6c458bSopenharmony_ci  }
2384d6c458bSopenharmony_ci  protected keyValueStringArray(): Array<string> {
2394d6c458bSopenharmony_ci    let resultArray: Array<string> = [];
2404d6c458bSopenharmony_ci    for (let i: number = 0; i < this.memberNumber; i++) {
2414d6c458bSopenharmony_ci      resultArray.push(JSON.stringify(this.members.keys[i]) + ':' + JSON.stringify(this.members.values[i]));
2424d6c458bSopenharmony_ci    }
2434d6c458bSopenharmony_ci    return resultArray;
2444d6c458bSopenharmony_ci  }
2454d6c458bSopenharmony_ci  protected binarySearchAtLightWeight(hash: number, startIndex: number = 0, endIndex: number = this.memberNumber): number {
2464d6c458bSopenharmony_ci    let low: number = startIndex;
2474d6c458bSopenharmony_ci    let high: number = endIndex - 1;
2484d6c458bSopenharmony_ci    while (low <= high) {
2494d6c458bSopenharmony_ci      let mid: number = 0;
2504d6c458bSopenharmony_ci      mid = (low + high) >>> 1;
2514d6c458bSopenharmony_ci      let midVal: number = 0;
2524d6c458bSopenharmony_ci      midVal = this.members.hashs[mid];
2534d6c458bSopenharmony_ci      if (midVal < hash) {
2544d6c458bSopenharmony_ci        low = mid + 1;
2554d6c458bSopenharmony_ci      } else {
2564d6c458bSopenharmony_ci        if (midVal <= hash) {
2574d6c458bSopenharmony_ci          return mid;
2584d6c458bSopenharmony_ci        }
2594d6c458bSopenharmony_ci        high = mid - 1;
2604d6c458bSopenharmony_ci      }
2614d6c458bSopenharmony_ci    }
2624d6c458bSopenharmony_ci    return -(low + 1);
2634d6c458bSopenharmony_ci  }
2644d6c458bSopenharmony_ci}
2654d6c458bSopenharmony_citype RBTreeNodeColor = 0 | 1;
2664d6c458bSopenharmony_ciconst BLACK = 0;
2674d6c458bSopenharmony_ciconst RED = 1;
2684d6c458bSopenharmony_ciclass TreeNode<K, V> extends Pair<K, V> {
2694d6c458bSopenharmony_ci  color: RBTreeNodeColor;
2704d6c458bSopenharmony_ci  left: TreeNode<K, V> | undefined;
2714d6c458bSopenharmony_ci  right: TreeNode<K, V> | undefined;
2724d6c458bSopenharmony_ci  parent: TreeNode<K, V> | undefined;
2734d6c458bSopenharmony_ci  constructor(key: K,
2744d6c458bSopenharmony_ci    value?: V,
2754d6c458bSopenharmony_ci    color: RBTreeNodeColor = RED,
2764d6c458bSopenharmony_ci    parent?: TreeNode<K, V>,
2774d6c458bSopenharmony_ci    left?: TreeNode<K, V>,
2784d6c458bSopenharmony_ci    right?: TreeNode<K, V>) {
2794d6c458bSopenharmony_ci    super(key, value);
2804d6c458bSopenharmony_ci    this.color = color;
2814d6c458bSopenharmony_ci    this.left = left;
2824d6c458bSopenharmony_ci    this.right = right;
2834d6c458bSopenharmony_ci    this.parent = parent;
2844d6c458bSopenharmony_ci  }
2854d6c458bSopenharmony_ci}
2864d6c458bSopenharmony_ciclass TreeClass<K, V> {
2874d6c458bSopenharmony_ci  private root: TreeNode<K, V> | undefined;
2884d6c458bSopenharmony_ci  public memberNumber: number;
2894d6c458bSopenharmony_ci  private isChange: boolean;
2904d6c458bSopenharmony_ci  private treeNodeArray: Array<TreeNode<K, V>>;
2914d6c458bSopenharmony_ci  private compFun: CompFun<K> | undefined;
2924d6c458bSopenharmony_ci  constructor(comparator?: CompFun<K>, root?: TreeNode<K, V>) {
2934d6c458bSopenharmony_ci    this.root = root;
2944d6c458bSopenharmony_ci    this.compFun = comparator;
2954d6c458bSopenharmony_ci    this.memberNumber = 0;
2964d6c458bSopenharmony_ci    this.isChange = true;
2974d6c458bSopenharmony_ci    this.treeNodeArray = [];
2984d6c458bSopenharmony_ci  }
2994d6c458bSopenharmony_ci  get keyValueArray(): Array<TreeNode<K, V>> {
3004d6c458bSopenharmony_ci    let result: Array<TreeNode<K, V>> = [];
3014d6c458bSopenharmony_ci    result = this.recordByMinToMax();
3024d6c458bSopenharmony_ci    return result;
3034d6c458bSopenharmony_ci  }
3044d6c458bSopenharmony_ci  addNode(key: K, value: V = key as unknown as V): TreeClass<K, V> {
3054d6c458bSopenharmony_ci    if (this.root === undefined) {
3064d6c458bSopenharmony_ci      this.root = new TreeNode<K, V>(key, value);
3074d6c458bSopenharmony_ci      this.setColor(BLACK, this.root);
3084d6c458bSopenharmony_ci      this.memberNumber++;
3094d6c458bSopenharmony_ci      this.isChange = true;
3104d6c458bSopenharmony_ci    } else {
3114d6c458bSopenharmony_ci      this.addProcess(key, value);
3124d6c458bSopenharmony_ci    }
3134d6c458bSopenharmony_ci    return this;
3144d6c458bSopenharmony_ci  }
3154d6c458bSopenharmony_ci  addProcess(key: K, value: V): TreeClass<K, V> {
3164d6c458bSopenharmony_ci    let leafNode: TreeNode<K, V> | undefined = this.root;
3174d6c458bSopenharmony_ci    let parentNode: TreeNode<K, V> = this.root as TreeNode<K, V>;
3184d6c458bSopenharmony_ci    let comp: number = 0;
3194d6c458bSopenharmony_ci    while (leafNode !== undefined) {
3204d6c458bSopenharmony_ci      parentNode = leafNode;
3214d6c458bSopenharmony_ci      comp = currencyCompare(leafNode.key, key, this.compFun);
3224d6c458bSopenharmony_ci      if (comp === 0) {
3234d6c458bSopenharmony_ci        leafNode.value = value;
3244d6c458bSopenharmony_ci        return this;
3254d6c458bSopenharmony_ci      } else if (comp < 0) {
3264d6c458bSopenharmony_ci        leafNode = leafNode.right;
3274d6c458bSopenharmony_ci      } else {
3284d6c458bSopenharmony_ci        leafNode = leafNode.left;
3294d6c458bSopenharmony_ci      }
3304d6c458bSopenharmony_ci    }
3314d6c458bSopenharmony_ci    leafNode = new TreeNode<K, V>(key, value);
3324d6c458bSopenharmony_ci    leafNode.parent = parentNode;
3334d6c458bSopenharmony_ci    if (comp < 0) {
3344d6c458bSopenharmony_ci      parentNode.right = leafNode;
3354d6c458bSopenharmony_ci    } else {
3364d6c458bSopenharmony_ci      parentNode.left = leafNode;
3374d6c458bSopenharmony_ci    }
3384d6c458bSopenharmony_ci    this.insertRebalance(leafNode);
3394d6c458bSopenharmony_ci    this.memberNumber++;
3404d6c458bSopenharmony_ci    this.isChange = true;
3414d6c458bSopenharmony_ci    return this;
3424d6c458bSopenharmony_ci  }
3434d6c458bSopenharmony_ci  removeNode(key: K): V | undefined {
3444d6c458bSopenharmony_ci    let removeNode: TreeNode<K, V> | undefined = undefined;
3454d6c458bSopenharmony_ci    removeNode = this.getNode(key);
3464d6c458bSopenharmony_ci    if (removeNode === undefined) {
3474d6c458bSopenharmony_ci      return undefined;
3484d6c458bSopenharmony_ci    } else {
3494d6c458bSopenharmony_ci      let result: V = removeNode.value;
3504d6c458bSopenharmony_ci      this.removeNodeProcess(removeNode);
3514d6c458bSopenharmony_ci      return result;
3524d6c458bSopenharmony_ci    }
3534d6c458bSopenharmony_ci  }
3544d6c458bSopenharmony_ci  removeNodeProcess(removeNode: TreeNode<K, V>): void {
3554d6c458bSopenharmony_ci    if (removeNode.left !== undefined && removeNode.right !== undefined) {
3564d6c458bSopenharmony_ci      let successor: TreeNode<K, V> | undefined = removeNode.right;
3574d6c458bSopenharmony_ci      while (successor.left !== undefined) {
3584d6c458bSopenharmony_ci        successor = successor.left;
3594d6c458bSopenharmony_ci      }
3604d6c458bSopenharmony_ci      removeNode.key = successor.key;
3614d6c458bSopenharmony_ci      removeNode.value = successor.value;
3624d6c458bSopenharmony_ci      this.removeNodeProcess(successor); // only once
3634d6c458bSopenharmony_ci      return;
3644d6c458bSopenharmony_ci    } else { // one or zero child
3654d6c458bSopenharmony_ci      let child: TreeNode<K, V> | undefined = undefined;
3664d6c458bSopenharmony_ci      child = (removeNode.left === undefined ? removeNode.right : removeNode.left);
3674d6c458bSopenharmony_ci      if (removeNode.parent === undefined) { // remove is root
3684d6c458bSopenharmony_ci        if (child === undefined) {
3694d6c458bSopenharmony_ci          this.root = undefined;
3704d6c458bSopenharmony_ci        } else {
3714d6c458bSopenharmony_ci          child.parent = undefined;
3724d6c458bSopenharmony_ci          child.color = BLACK;
3734d6c458bSopenharmony_ci          this.root = child;
3744d6c458bSopenharmony_ci        }
3754d6c458bSopenharmony_ci      } else {
3764d6c458bSopenharmony_ci        if (child !== undefined) {
3774d6c458bSopenharmony_ci          // delete removeNode
3784d6c458bSopenharmony_ci          if (removeNode.parent.left === removeNode) {
3794d6c458bSopenharmony_ci            removeNode.parent.left = child;
3804d6c458bSopenharmony_ci          } else {
3814d6c458bSopenharmony_ci            removeNode.parent.right = child;
3824d6c458bSopenharmony_ci          }
3834d6c458bSopenharmony_ci          if (this.getColor(removeNode) === BLACK) {
3844d6c458bSopenharmony_ci            this.deleteRebalance(child);
3854d6c458bSopenharmony_ci          }
3864d6c458bSopenharmony_ci        } else {
3874d6c458bSopenharmony_ci          if (this.getColor(removeNode) === BLACK) {
3884d6c458bSopenharmony_ci            this.deleteRebalance(removeNode);
3894d6c458bSopenharmony_ci          }
3904d6c458bSopenharmony_ci          if (removeNode.parent.left === removeNode) {
3914d6c458bSopenharmony_ci            removeNode.parent.left = child;
3924d6c458bSopenharmony_ci          } else {
3934d6c458bSopenharmony_ci            removeNode.parent.right = child;
3944d6c458bSopenharmony_ci          }
3954d6c458bSopenharmony_ci        }
3964d6c458bSopenharmony_ci      }
3974d6c458bSopenharmony_ci      this.memberNumber--;
3984d6c458bSopenharmony_ci      this.isChange = true;
3994d6c458bSopenharmony_ci    }
4004d6c458bSopenharmony_ci  }
4014d6c458bSopenharmony_ci  getNode(key: K): TreeNode<K, V> | undefined {
4024d6c458bSopenharmony_ci    if (this.root === undefined) {
4034d6c458bSopenharmony_ci      return undefined;
4044d6c458bSopenharmony_ci    }
4054d6c458bSopenharmony_ci    let findNode: TreeNode<K, V> | undefined = this.root;
4064d6c458bSopenharmony_ci    while (findNode !== undefined && findNode.key !== key) {
4074d6c458bSopenharmony_ci      findNode = currencyCompare(findNode.key, key, this.compFun) === ComparResult.BIGGER_THAN ?
4084d6c458bSopenharmony_ci        findNode.left : findNode.right;
4094d6c458bSopenharmony_ci    }
4104d6c458bSopenharmony_ci    return findNode;
4114d6c458bSopenharmony_ci  }
4124d6c458bSopenharmony_ci  findNode(value: V): TreeNode<K, V> | undefined {
4134d6c458bSopenharmony_ci    let tempNode: TreeNode<K, V> | undefined = undefined;
4144d6c458bSopenharmony_ci    this.recordByMinToMax();
4154d6c458bSopenharmony_ci    for (let i: number = 0; i < this.memberNumber; i++) {
4164d6c458bSopenharmony_ci      if (this.treeNodeArray[i].value === value) {
4174d6c458bSopenharmony_ci        tempNode = this.treeNodeArray[i];
4184d6c458bSopenharmony_ci        break;
4194d6c458bSopenharmony_ci      }
4204d6c458bSopenharmony_ci    }
4214d6c458bSopenharmony_ci    return tempNode;
4224d6c458bSopenharmony_ci  }
4234d6c458bSopenharmony_ci  firstNode(): TreeNode<K, V> | undefined {
4244d6c458bSopenharmony_ci    let tempNode: TreeNode<K, V> | undefined = this.root;
4254d6c458bSopenharmony_ci    while (tempNode !== undefined && tempNode.left !== undefined) {
4264d6c458bSopenharmony_ci      tempNode = tempNode.left;
4274d6c458bSopenharmony_ci    }
4284d6c458bSopenharmony_ci    return tempNode;
4294d6c458bSopenharmony_ci  }
4304d6c458bSopenharmony_ci  lastNode(): TreeNode<K, V> | undefined {
4314d6c458bSopenharmony_ci    let tempNode: TreeNode<K, V> | undefined = this.root;
4324d6c458bSopenharmony_ci    while (tempNode !== undefined && tempNode.right !== undefined) {
4334d6c458bSopenharmony_ci      tempNode = tempNode.right;
4344d6c458bSopenharmony_ci    }
4354d6c458bSopenharmony_ci    return tempNode;
4364d6c458bSopenharmony_ci  }
4374d6c458bSopenharmony_ci  isEmpty(): boolean {
4384d6c458bSopenharmony_ci    return this.root === undefined;
4394d6c458bSopenharmony_ci  }
4404d6c458bSopenharmony_ci  setAll(map: TreeClass<K, V>): void {
4414d6c458bSopenharmony_ci    let tempArray: TreeNode<K, V>[] = [];
4424d6c458bSopenharmony_ci    tempArray = map.recordByMinToMax();
4434d6c458bSopenharmony_ci    for (let i: number = 0; i < map.memberNumber; i++) {
4444d6c458bSopenharmony_ci      this.addNode(tempArray[i].key, tempArray[i].value);
4454d6c458bSopenharmony_ci    }
4464d6c458bSopenharmony_ci  }
4474d6c458bSopenharmony_ci  clearTree(): void {
4484d6c458bSopenharmony_ci    this.root = undefined;
4494d6c458bSopenharmony_ci    this.memberNumber = 0;
4504d6c458bSopenharmony_ci  }
4514d6c458bSopenharmony_ci  private recordByMinToMax(): Array<TreeNode<K, V>> {
4524d6c458bSopenharmony_ci    if (!this.isChange) {
4534d6c458bSopenharmony_ci      return this.treeNodeArray;
4544d6c458bSopenharmony_ci    }
4554d6c458bSopenharmony_ci    let stack: Array<TreeNode<K, V>> = [];
4564d6c458bSopenharmony_ci    this.treeNodeArray = [];
4574d6c458bSopenharmony_ci    let node: TreeNode<K, V> | undefined = this.root;
4584d6c458bSopenharmony_ci    while (node !== undefined || stack.length) {
4594d6c458bSopenharmony_ci      while (node !== undefined) {
4604d6c458bSopenharmony_ci        stack.push(node);
4614d6c458bSopenharmony_ci        node = node.left;
4624d6c458bSopenharmony_ci      }
4634d6c458bSopenharmony_ci      let tempNode = stack.pop();
4644d6c458bSopenharmony_ci      if (tempNode === undefined) {
4654d6c458bSopenharmony_ci        throw new Error('this function run error');
4664d6c458bSopenharmony_ci      }
4674d6c458bSopenharmony_ci      node = tempNode;
4684d6c458bSopenharmony_ci      this.treeNodeArray.push(node);
4694d6c458bSopenharmony_ci      node = node.right;
4704d6c458bSopenharmony_ci    }
4714d6c458bSopenharmony_ci    this.isChange = false;
4724d6c458bSopenharmony_ci    this.memberNumber = this.treeNodeArray.length;
4734d6c458bSopenharmony_ci    return this.treeNodeArray;
4744d6c458bSopenharmony_ci  }
4754d6c458bSopenharmony_ci  private lRotate(datumPointNode: TreeNode<K, V>): TreeClass<K, V> {
4764d6c458bSopenharmony_ci    let newTopNode: TreeNode<K, V> | undefined = datumPointNode.right;
4774d6c458bSopenharmony_ci    if (newTopNode === undefined) {
4784d6c458bSopenharmony_ci      throw new Error('[rotate right error]: the right child node of the base node === undefined');
4794d6c458bSopenharmony_ci    }
4804d6c458bSopenharmony_ci    datumPointNode.right = newTopNode.left;
4814d6c458bSopenharmony_ci    datumPointNode.right !== undefined ? datumPointNode.right.parent = datumPointNode : '';
4824d6c458bSopenharmony_ci    newTopNode.parent = datumPointNode.parent;
4834d6c458bSopenharmony_ci    if (datumPointNode.parent === undefined) {
4844d6c458bSopenharmony_ci      this.root = newTopNode;
4854d6c458bSopenharmony_ci    } else if (datumPointNode.parent.left === datumPointNode) {
4864d6c458bSopenharmony_ci      datumPointNode.parent.left = newTopNode;
4874d6c458bSopenharmony_ci    } else if (datumPointNode.parent.right === datumPointNode) {
4884d6c458bSopenharmony_ci      datumPointNode.parent.right = newTopNode;
4894d6c458bSopenharmony_ci    }
4904d6c458bSopenharmony_ci    datumPointNode.parent = newTopNode;
4914d6c458bSopenharmony_ci    newTopNode.left = datumPointNode;
4924d6c458bSopenharmony_ci    return this;
4934d6c458bSopenharmony_ci  }
4944d6c458bSopenharmony_ci  private rRotate(datumPointNode: TreeNode<K, V>): TreeClass<K, V> {
4954d6c458bSopenharmony_ci    let newTopNode: TreeNode<K, V> | undefined = datumPointNode.left;
4964d6c458bSopenharmony_ci    if (newTopNode === undefined) {
4974d6c458bSopenharmony_ci      throw new Error('[rotate right error]: the left child node of the base node === undefined');
4984d6c458bSopenharmony_ci    }
4994d6c458bSopenharmony_ci    datumPointNode.left = newTopNode.right;
5004d6c458bSopenharmony_ci    datumPointNode.left !== undefined ? datumPointNode.left.parent = datumPointNode : '';
5014d6c458bSopenharmony_ci    newTopNode.parent = datumPointNode.parent;
5024d6c458bSopenharmony_ci    if (datumPointNode.parent === undefined) {
5034d6c458bSopenharmony_ci      this.root = newTopNode;
5044d6c458bSopenharmony_ci    } else if (datumPointNode === datumPointNode.parent.left) {
5054d6c458bSopenharmony_ci      datumPointNode.parent.left = newTopNode;
5064d6c458bSopenharmony_ci    } else if (datumPointNode === datumPointNode.parent.right) {
5074d6c458bSopenharmony_ci      datumPointNode.parent.right = newTopNode;
5084d6c458bSopenharmony_ci    }
5094d6c458bSopenharmony_ci    datumPointNode.parent = newTopNode;
5104d6c458bSopenharmony_ci    newTopNode.right = datumPointNode;
5114d6c458bSopenharmony_ci    return this;
5124d6c458bSopenharmony_ci  }
5134d6c458bSopenharmony_ci  private insertRebalance(fixNode: TreeNode<K, V>): TreeClass<K, V> {
5144d6c458bSopenharmony_ci    let parentNode: TreeNode<K, V> | undefined = fixNode.parent;
5154d6c458bSopenharmony_ci    while (this.getColor(parentNode) === RED &&
5164d6c458bSopenharmony_ci      parentNode !== undefined &&
5174d6c458bSopenharmony_ci      parentNode.parent !== undefined) {
5184d6c458bSopenharmony_ci      let grandpaNode = parentNode && parentNode.parent;
5194d6c458bSopenharmony_ci      if (parentNode === grandpaNode.left &&
5204d6c458bSopenharmony_ci        this.getColor(grandpaNode.right) === BLACK &&
5214d6c458bSopenharmony_ci        fixNode === parentNode.left) {
5224d6c458bSopenharmony_ci        this
5234d6c458bSopenharmony_ci          .setColor(BLACK, parentNode)
5244d6c458bSopenharmony_ci          .setColor(RED, grandpaNode)
5254d6c458bSopenharmony_ci          .rRotate(grandpaNode);
5264d6c458bSopenharmony_ci        break;
5274d6c458bSopenharmony_ci      } else if (parentNode === grandpaNode.left &&
5284d6c458bSopenharmony_ci        this.getColor(grandpaNode.right) === BLACK &&
5294d6c458bSopenharmony_ci        fixNode === parentNode.right) {
5304d6c458bSopenharmony_ci        this
5314d6c458bSopenharmony_ci          .setColor(BLACK, fixNode)
5324d6c458bSopenharmony_ci          .setColor(RED, grandpaNode)
5334d6c458bSopenharmony_ci          .lRotate(parentNode)
5344d6c458bSopenharmony_ci          .rRotate(grandpaNode);
5354d6c458bSopenharmony_ci        break;
5364d6c458bSopenharmony_ci      } else if (parentNode === grandpaNode.right &&
5374d6c458bSopenharmony_ci        this.getColor(grandpaNode.left) === BLACK &&
5384d6c458bSopenharmony_ci        fixNode === parentNode.left) {
5394d6c458bSopenharmony_ci        this
5404d6c458bSopenharmony_ci          .setColor(BLACK, fixNode)
5414d6c458bSopenharmony_ci          .setColor(RED, grandpaNode)
5424d6c458bSopenharmony_ci          .rRotate(parentNode)
5434d6c458bSopenharmony_ci          .lRotate(grandpaNode);
5444d6c458bSopenharmony_ci        break;
5454d6c458bSopenharmony_ci      } else if (parentNode === grandpaNode.right &&
5464d6c458bSopenharmony_ci        this.getColor(grandpaNode.left) === BLACK &&
5474d6c458bSopenharmony_ci        fixNode === parentNode.right) {
5484d6c458bSopenharmony_ci        this
5494d6c458bSopenharmony_ci          .setColor(BLACK, parentNode)
5504d6c458bSopenharmony_ci          .setColor(RED, grandpaNode)
5514d6c458bSopenharmony_ci          .lRotate(grandpaNode);
5524d6c458bSopenharmony_ci        break;
5534d6c458bSopenharmony_ci      } else if ((parentNode === grandpaNode.right && this.getColor(grandpaNode.left) === RED) ||
5544d6c458bSopenharmony_ci        (parentNode === grandpaNode.left && this.getColor(grandpaNode.right) === RED)) {
5554d6c458bSopenharmony_ci        this
5564d6c458bSopenharmony_ci          .setColor(BLACK, parentNode)
5574d6c458bSopenharmony_ci          .setColor(BLACK, parentNode === grandpaNode.left ? grandpaNode.right : grandpaNode.left)
5584d6c458bSopenharmony_ci          .setColor(RED, grandpaNode);
5594d6c458bSopenharmony_ci        fixNode = grandpaNode;
5604d6c458bSopenharmony_ci        parentNode = fixNode.parent;
5614d6c458bSopenharmony_ci      } else {
5624d6c458bSopenharmony_ci        throw new Error('Exceptions after adding');
5634d6c458bSopenharmony_ci      }
5644d6c458bSopenharmony_ci    }
5654d6c458bSopenharmony_ci    this.root ? this.root.color = BLACK : '';
5664d6c458bSopenharmony_ci    return this;
5674d6c458bSopenharmony_ci  }
5684d6c458bSopenharmony_ci  private deleteRebalance(fixNode: TreeNode<K, V>): void {
5694d6c458bSopenharmony_ci    while (this.getColor(fixNode) === BLACK && fixNode !== this.root && fixNode.parent) {
5704d6c458bSopenharmony_ci      let sibling: TreeNode<K, V> | undefined = undefined;
5714d6c458bSopenharmony_ci      if (fixNode === fixNode.parent.left) {
5724d6c458bSopenharmony_ci        sibling = fixNode.parent.right;
5734d6c458bSopenharmony_ci        if (this.getColor(sibling) === RED) {
5744d6c458bSopenharmony_ci          this
5754d6c458bSopenharmony_ci            .setColor(RED, fixNode.parent)
5764d6c458bSopenharmony_ci            .setColor(BLACK, sibling)
5774d6c458bSopenharmony_ci            .lRotate(fixNode.parent);
5784d6c458bSopenharmony_ci          sibling = fixNode.parent.right;
5794d6c458bSopenharmony_ci        }
5804d6c458bSopenharmony_ci        if (sibling === undefined) {
5814d6c458bSopenharmony_ci          throw new Error('Error sibling node is undefined');
5824d6c458bSopenharmony_ci        }
5834d6c458bSopenharmony_ci        if (this.getColor(sibling.left) === BLACK && this.getColor(sibling.right) === BLACK) {
5844d6c458bSopenharmony_ci          this.setColor(RED, sibling);
5854d6c458bSopenharmony_ci          fixNode = fixNode.parent;
5864d6c458bSopenharmony_ci        } else if (this.getColor(sibling.left) === RED && this.getColor(sibling.right) === BLACK) {
5874d6c458bSopenharmony_ci          this
5884d6c458bSopenharmony_ci            .setColor(RED, sibling)
5894d6c458bSopenharmony_ci            .setColor(BLACK, sibling.left)
5904d6c458bSopenharmony_ci            .rRotate(sibling);
5914d6c458bSopenharmony_ci          sibling = fixNode.parent.right;
5924d6c458bSopenharmony_ci          if (sibling === undefined) {
5934d6c458bSopenharmony_ci            throw new Error('Error sibling node is empty');
5944d6c458bSopenharmony_ci          }
5954d6c458bSopenharmony_ci          this
5964d6c458bSopenharmony_ci            .setColor(fixNode.parent.color, sibling)
5974d6c458bSopenharmony_ci            .setColor(BLACK, fixNode.parent)
5984d6c458bSopenharmony_ci            .setColor(BLACK, sibling.right)
5994d6c458bSopenharmony_ci            .lRotate(fixNode.parent);
6004d6c458bSopenharmony_ci          break;
6014d6c458bSopenharmony_ci        } else if (this.getColor(sibling.right) === RED) {
6024d6c458bSopenharmony_ci          this
6034d6c458bSopenharmony_ci            .setColor(fixNode.parent.color, sibling)
6044d6c458bSopenharmony_ci            .setColor(BLACK, fixNode.parent)
6054d6c458bSopenharmony_ci            .setColor(BLACK, sibling.right)
6064d6c458bSopenharmony_ci            .lRotate(fixNode.parent);
6074d6c458bSopenharmony_ci          break;
6084d6c458bSopenharmony_ci        } else {
6094d6c458bSopenharmony_ci          throw new Error('Adjust the error after the error is deleted');
6104d6c458bSopenharmony_ci        }
6114d6c458bSopenharmony_ci      } else {
6124d6c458bSopenharmony_ci        sibling = fixNode.parent.left;
6134d6c458bSopenharmony_ci        if (this.getColor(sibling) === RED) {
6144d6c458bSopenharmony_ci          this
6154d6c458bSopenharmony_ci            .setColor(BLACK, sibling)
6164d6c458bSopenharmony_ci            .setColor(RED, fixNode.parent)
6174d6c458bSopenharmony_ci            .rRotate(fixNode.parent);
6184d6c458bSopenharmony_ci          sibling = fixNode.parent.left;
6194d6c458bSopenharmony_ci        }
6204d6c458bSopenharmony_ci        if (sibling === undefined) {
6214d6c458bSopenharmony_ci          throw new Error('Error sibling node is undefined');
6224d6c458bSopenharmony_ci        }
6234d6c458bSopenharmony_ci        if (this.getColor(sibling.left) === BLACK && this.getColor(sibling.right) === BLACK) {
6244d6c458bSopenharmony_ci          this
6254d6c458bSopenharmony_ci            .setColor(RED, sibling);
6264d6c458bSopenharmony_ci          fixNode = fixNode.parent;
6274d6c458bSopenharmony_ci        } else if (this.getColor(sibling.left) === BLACK && this.getColor(sibling.right) === RED) {
6284d6c458bSopenharmony_ci          this
6294d6c458bSopenharmony_ci            .setColor(RED, sibling)
6304d6c458bSopenharmony_ci            .setColor(BLACK, sibling.right)
6314d6c458bSopenharmony_ci            .lRotate(sibling);
6324d6c458bSopenharmony_ci          sibling = fixNode.parent.left;
6334d6c458bSopenharmony_ci          if (sibling === undefined) {
6344d6c458bSopenharmony_ci            throw new Error('Adjust the error after the error is deleted');
6354d6c458bSopenharmony_ci          }
6364d6c458bSopenharmony_ci          this
6374d6c458bSopenharmony_ci            .setColor(fixNode.parent.color, sibling)
6384d6c458bSopenharmony_ci            .setColor(BLACK, fixNode.parent)
6394d6c458bSopenharmony_ci            .setColor(BLACK, sibling.left)
6404d6c458bSopenharmony_ci            .rRotate(fixNode.parent);
6414d6c458bSopenharmony_ci          break;
6424d6c458bSopenharmony_ci        } else if (this.getColor(sibling.left) === RED) {
6434d6c458bSopenharmony_ci          this
6444d6c458bSopenharmony_ci            .setColor(fixNode.parent.color, sibling)
6454d6c458bSopenharmony_ci            .setColor(BLACK, fixNode.parent,)
6464d6c458bSopenharmony_ci            .setColor(BLACK, sibling.left)
6474d6c458bSopenharmony_ci            .rRotate(fixNode.parent);
6484d6c458bSopenharmony_ci          break;
6494d6c458bSopenharmony_ci        } else {
6504d6c458bSopenharmony_ci          throw new Error('Adjust the error after the error is deleted');
6514d6c458bSopenharmony_ci        }
6524d6c458bSopenharmony_ci      }
6534d6c458bSopenharmony_ci    }
6544d6c458bSopenharmony_ci    this.setColor(BLACK, fixNode);
6554d6c458bSopenharmony_ci  }
6564d6c458bSopenharmony_ci  private getColor(node: TreeNode<K, V> | undefined): RBTreeNodeColor {
6574d6c458bSopenharmony_ci    return node === undefined ? BLACK : node.color;
6584d6c458bSopenharmony_ci  }
6594d6c458bSopenharmony_ci  private setColor(color: RBTreeNodeColor, node: TreeNode<K, V> | undefined): TreeClass<K, V> {
6604d6c458bSopenharmony_ci    if (node === undefined) {
6614d6c458bSopenharmony_ci      throw new Error('Wrong color setting');
6624d6c458bSopenharmony_ci    } else {
6634d6c458bSopenharmony_ci      node.color = color;
6644d6c458bSopenharmony_ci    }
6654d6c458bSopenharmony_ci    return this;
6664d6c458bSopenharmony_ci  }
6674d6c458bSopenharmony_ci}
6684d6c458bSopenharmony_ciconst MAX_CAPACITY = 1 << 30; // 30 : means number
6694d6c458bSopenharmony_ciconst LOADER_FACTOR = 0.75;
6704d6c458bSopenharmony_ciclass DictionaryClass<K, V> {
6714d6c458bSopenharmony_ci  private tableLink: { [hashIndex: number]: LinkedList<Pair<K, V>> | TreeClass<K, V> };
6724d6c458bSopenharmony_ci  protected memberNumber: number;
6734d6c458bSopenharmony_ci  private isChange: boolean;
6744d6c458bSopenharmony_ci  private memberArray: Array<Pair<K, V>>;
6754d6c458bSopenharmony_ci  private capacity: number;
6764d6c458bSopenharmony_ci  constructor() {
6774d6c458bSopenharmony_ci    this.tableLink = {};
6784d6c458bSopenharmony_ci    this.memberNumber = 0;
6794d6c458bSopenharmony_ci    this.isChange = true;
6804d6c458bSopenharmony_ci    this.memberArray = [];
6814d6c458bSopenharmony_ci    this.capacity = 16;
6824d6c458bSopenharmony_ci  }
6834d6c458bSopenharmony_ci  get keyValueArray(): Pair<K, V>[] {
6844d6c458bSopenharmony_ci    let result: Pair<K, V>[] = [];
6854d6c458bSopenharmony_ci    result = this.keyValues();
6864d6c458bSopenharmony_ci    return result;
6874d6c458bSopenharmony_ci  }
6884d6c458bSopenharmony_ci  protected getHashIndex(key: K): number {
6894d6c458bSopenharmony_ci    let h: number = 0;
6904d6c458bSopenharmony_ci    let hash: number = 0;
6914d6c458bSopenharmony_ci    hash = ((key === null) ? 0 : ((h = hashCode(key)) ^ (h >>> 16))); // 16 : means number
6924d6c458bSopenharmony_ci    if (this.expandCapacity()) {
6934d6c458bSopenharmony_ci      this.keyValues();
6944d6c458bSopenharmony_ci      this.memberNumber = 0;
6954d6c458bSopenharmony_ci      this.tableLink = {};
6964d6c458bSopenharmony_ci      this.isChange = true;
6974d6c458bSopenharmony_ci      for (let item of this.memberArray) {
6984d6c458bSopenharmony_ci        this.put(item.key, item.value);
6994d6c458bSopenharmony_ci      }
7004d6c458bSopenharmony_ci      this.memberNumber++;
7014d6c458bSopenharmony_ci    }
7024d6c458bSopenharmony_ci    let n: number = 0;
7034d6c458bSopenharmony_ci    n = this.power(this.capacity);
7044d6c458bSopenharmony_ci    return (n - 1) & hash;
7054d6c458bSopenharmony_ci  }
7064d6c458bSopenharmony_ci  private power(size: number): number {
7074d6c458bSopenharmony_ci    let n: number = 1;
7084d6c458bSopenharmony_ci    let temp: number = size;
7094d6c458bSopenharmony_ci    while (temp >>> 1 !== 1) {
7104d6c458bSopenharmony_ci      n++;
7114d6c458bSopenharmony_ci      temp = temp >>> 1;
7124d6c458bSopenharmony_ci    }
7134d6c458bSopenharmony_ci    return n;
7144d6c458bSopenharmony_ci  }
7154d6c458bSopenharmony_ci  private keyValues(): Pair<K, V>[] {
7164d6c458bSopenharmony_ci    if (!this.isChange) {
7174d6c458bSopenharmony_ci      return this.memberArray;
7184d6c458bSopenharmony_ci    }
7194d6c458bSopenharmony_ci    this.memberArray = [];
7204d6c458bSopenharmony_ci    let keys: number[] = [];
7214d6c458bSopenharmony_ci    keys = Object.keys(this.tableLink).map((item) => parseInt(item));
7224d6c458bSopenharmony_ci    for (let i: number = 0; i < keys.length; i++) {
7234d6c458bSopenharmony_ci      let members: TreeClass<K, V> | LinkedList<Pair<K, V>> = undefined;
7244d6c458bSopenharmony_ci      members = this.tableLink[keys[i]];
7254d6c458bSopenharmony_ci      if (members instanceof TreeClass) {
7264d6c458bSopenharmony_ci        let tempArray: TreeNode<K, V>[] = members.keyValueArray;
7274d6c458bSopenharmony_ci        for (let i: number = 0; i < members.memberNumber; i++) {
7284d6c458bSopenharmony_ci          this.memberArray.push(new Pair(tempArray[i].key, tempArray[i].value));
7294d6c458bSopenharmony_ci        }
7304d6c458bSopenharmony_ci      } else {
7314d6c458bSopenharmony_ci        if (members !== undefined && !members.isEmpty()) {
7324d6c458bSopenharmony_ci          let current: Node<Pair<K, V>> = members.getHead();
7334d6c458bSopenharmony_ci          while (current !== undefined) {
7344d6c458bSopenharmony_ci            this.memberArray.push(current.element);
7354d6c458bSopenharmony_ci            current = current.next;
7364d6c458bSopenharmony_ci          }
7374d6c458bSopenharmony_ci        }
7384d6c458bSopenharmony_ci      }
7394d6c458bSopenharmony_ci    }
7404d6c458bSopenharmony_ci    this.memberNumber = this.memberArray.length;
7414d6c458bSopenharmony_ci    let valuePairs: Pair<K, V>[] = this.memberArray;
7424d6c458bSopenharmony_ci    return valuePairs;
7434d6c458bSopenharmony_ci  }
7444d6c458bSopenharmony_ci  protected expandCapacity(): boolean {
7454d6c458bSopenharmony_ci    let capacityChange: boolean = false;
7464d6c458bSopenharmony_ci    while (this.capacity < this.memberNumber / LOADER_FACTOR && this.capacity < MAX_CAPACITY) {
7474d6c458bSopenharmony_ci      this.capacity = 2 * this.capacity; // 2 : means number
7484d6c458bSopenharmony_ci      capacityChange = true;
7494d6c458bSopenharmony_ci    }
7504d6c458bSopenharmony_ci    return capacityChange;
7514d6c458bSopenharmony_ci  }
7524d6c458bSopenharmony_ci  protected put(key: K, value: V = key as unknown as V): boolean {
7534d6c458bSopenharmony_ci    this.isChange = true;
7544d6c458bSopenharmony_ci    if (!this.hasKey(key)) {
7554d6c458bSopenharmony_ci      this.memberNumber++;
7564d6c458bSopenharmony_ci    }
7574d6c458bSopenharmony_ci    let position: number = 0;
7584d6c458bSopenharmony_ci    position = this.getHashIndex(key);
7594d6c458bSopenharmony_ci    let members: LinkedList<Pair<K, V>> | TreeClass<K, V> = undefined;
7604d6c458bSopenharmony_ci    members = this.tableLink[position];
7614d6c458bSopenharmony_ci    if (members instanceof LinkedList && members.count >= 8) { // 8 : means number
7624d6c458bSopenharmony_ci      let newElement: TreeClass<K, V> = new TreeClass<K, V>();
7634d6c458bSopenharmony_ci      let current: Node<Pair<K, V>> = undefined;
7644d6c458bSopenharmony_ci      current = members.getHead();
7654d6c458bSopenharmony_ci      while (current != null || current !== undefined) {
7664d6c458bSopenharmony_ci        if (!(current.element instanceof Pair)) {
7674d6c458bSopenharmony_ci          return false;
7684d6c458bSopenharmony_ci        }
7694d6c458bSopenharmony_ci        newElement.addNode(current.element.key, current.element.value);
7704d6c458bSopenharmony_ci        current = current.next;
7714d6c458bSopenharmony_ci      }
7724d6c458bSopenharmony_ci      newElement.addNode(key, value);
7734d6c458bSopenharmony_ci      this.tableLink[position] = newElement;
7744d6c458bSopenharmony_ci      return true;
7754d6c458bSopenharmony_ci    } else if (members instanceof TreeClass) {
7764d6c458bSopenharmony_ci      members.addNode(key, value);
7774d6c458bSopenharmony_ci      this.tableLink[position] = members;
7784d6c458bSopenharmony_ci      return true;
7794d6c458bSopenharmony_ci    } else {
7804d6c458bSopenharmony_ci      if (this.tableLink[position] === undefined) {
7814d6c458bSopenharmony_ci        members = new LinkedList<Pair<K, V>>();
7824d6c458bSopenharmony_ci      }
7834d6c458bSopenharmony_ci      if (!this.replaceMember(key, value)) {
7844d6c458bSopenharmony_ci        members.push(new Pair(key, value));
7854d6c458bSopenharmony_ci        this.tableLink[position] = members;
7864d6c458bSopenharmony_ci      }
7874d6c458bSopenharmony_ci      return true;
7884d6c458bSopenharmony_ci    }
7894d6c458bSopenharmony_ci  }
7904d6c458bSopenharmony_ci  protected replaceMember(key: K, value: V = key as unknown as V): boolean {
7914d6c458bSopenharmony_ci    let position: number = 0;
7924d6c458bSopenharmony_ci    position = this.getHashIndex(key);
7934d6c458bSopenharmony_ci    let members: LinkedList<Pair<K, V>> = undefined;
7944d6c458bSopenharmony_ci    members = this.tableLink[position] as LinkedList<Pair<K, V>>;
7954d6c458bSopenharmony_ci    if (members === null || members === undefined) {
7964d6c458bSopenharmony_ci      return false;
7974d6c458bSopenharmony_ci    }
7984d6c458bSopenharmony_ci    let current: Node<Pair<K, V>> = undefined;
7994d6c458bSopenharmony_ci    current = members.getHead();
8004d6c458bSopenharmony_ci    while (current !== undefined) {
8014d6c458bSopenharmony_ci      if (current.element.key === key) {
8024d6c458bSopenharmony_ci        current.element.value = value;
8034d6c458bSopenharmony_ci        return true;
8044d6c458bSopenharmony_ci      }
8054d6c458bSopenharmony_ci      current = current.next;
8064d6c458bSopenharmony_ci    }
8074d6c458bSopenharmony_ci    return false;
8084d6c458bSopenharmony_ci  }
8094d6c458bSopenharmony_ci  protected getValueByKey(key: K): V | undefined {
8104d6c458bSopenharmony_ci    let position: number = 0;
8114d6c458bSopenharmony_ci    position = this.getHashIndex(key);
8124d6c458bSopenharmony_ci    let members: LinkedList<Pair<K, V>> | TreeClass<K, V> = undefined;
8134d6c458bSopenharmony_ci    members = this.tableLink[position];
8144d6c458bSopenharmony_ci    if (members instanceof TreeClass) {
8154d6c458bSopenharmony_ci      let resultNode: TreeNode<K, V> | undefined = undefined;
8164d6c458bSopenharmony_ci      resultNode = members.getNode(key);
8174d6c458bSopenharmony_ci      if (resultNode === undefined) {
8184d6c458bSopenharmony_ci        return undefined;
8194d6c458bSopenharmony_ci      }
8204d6c458bSopenharmony_ci      return resultNode.value;
8214d6c458bSopenharmony_ci    } else {
8224d6c458bSopenharmony_ci      if (members !== undefined && !members.isEmpty()) {
8234d6c458bSopenharmony_ci        members as LinkedList<Pair<K, V>>;
8244d6c458bSopenharmony_ci        let current: Node<Pair<K, V>> = undefined;
8254d6c458bSopenharmony_ci        current = members.getHead();
8264d6c458bSopenharmony_ci        while (current !== undefined) {
8274d6c458bSopenharmony_ci          if (current.element.key === key) {
8284d6c458bSopenharmony_ci            return current.element.value;
8294d6c458bSopenharmony_ci          }
8304d6c458bSopenharmony_ci          current = current.next;
8314d6c458bSopenharmony_ci        }
8324d6c458bSopenharmony_ci      }
8334d6c458bSopenharmony_ci    }
8344d6c458bSopenharmony_ci    return undefined;
8354d6c458bSopenharmony_ci  }
8364d6c458bSopenharmony_ci  protected removeMember(key: K): V | undefined {
8374d6c458bSopenharmony_ci    let position: number = 0;
8384d6c458bSopenharmony_ci    position = this.getHashIndex(key);
8394d6c458bSopenharmony_ci    let members: LinkedList<Pair<K, V>> | TreeClass<K, V> = undefined;
8404d6c458bSopenharmony_ci    members = this.tableLink[position];
8414d6c458bSopenharmony_ci    if (members instanceof TreeClass) {
8424d6c458bSopenharmony_ci      let result: V | undefined = members.removeNode(key);
8434d6c458bSopenharmony_ci      if (result !== undefined) {
8444d6c458bSopenharmony_ci        this.isChange = true;
8454d6c458bSopenharmony_ci        this.memberNumber--;
8464d6c458bSopenharmony_ci        return result;
8474d6c458bSopenharmony_ci      }
8484d6c458bSopenharmony_ci    } else {
8494d6c458bSopenharmony_ci      if (members !== undefined && !members.isEmpty()) {
8504d6c458bSopenharmony_ci        let current: Node<Pair<K, V>> = undefined;
8514d6c458bSopenharmony_ci        current = members.getHead();
8524d6c458bSopenharmony_ci        while (current !== undefined) {
8534d6c458bSopenharmony_ci          if (current.element.key === key) {
8544d6c458bSopenharmony_ci            let result: V | undefined = current.element.value;
8554d6c458bSopenharmony_ci            members.remove(current.element);
8564d6c458bSopenharmony_ci            if (members.isEmpty()) {
8574d6c458bSopenharmony_ci              delete this.tableLink[position];
8584d6c458bSopenharmony_ci            }
8594d6c458bSopenharmony_ci            this.isChange = true;
8604d6c458bSopenharmony_ci            this.memberNumber--;
8614d6c458bSopenharmony_ci            return result;
8624d6c458bSopenharmony_ci          }
8634d6c458bSopenharmony_ci          current = current.next;
8644d6c458bSopenharmony_ci        }
8654d6c458bSopenharmony_ci      }
8664d6c458bSopenharmony_ci    }
8674d6c458bSopenharmony_ci    return undefined;
8684d6c458bSopenharmony_ci  }
8694d6c458bSopenharmony_ci  protected clear(): void {
8704d6c458bSopenharmony_ci    this.tableLink = {};
8714d6c458bSopenharmony_ci    this.memberNumber = 0;
8724d6c458bSopenharmony_ci    this.isChange = true;
8734d6c458bSopenharmony_ci    this.capacity = 16;
8744d6c458bSopenharmony_ci  }
8754d6c458bSopenharmony_ci  protected hasKey(key: K): boolean {
8764d6c458bSopenharmony_ci    let position: number = 0;
8774d6c458bSopenharmony_ci    position = this.getHashIndex(key);
8784d6c458bSopenharmony_ci    let members: LinkedList<Pair<K, V>> | TreeClass<K, V> = undefined;
8794d6c458bSopenharmony_ci    members = this.tableLink[position];
8804d6c458bSopenharmony_ci    if (members === undefined || members === undefined) {
8814d6c458bSopenharmony_ci      return false;
8824d6c458bSopenharmony_ci    }
8834d6c458bSopenharmony_ci    if (members instanceof TreeClass) {
8844d6c458bSopenharmony_ci      return members.getNode(key) !== undefined;
8854d6c458bSopenharmony_ci    }
8864d6c458bSopenharmony_ci    let current: Node<Pair<K, V>> = undefined;
8874d6c458bSopenharmony_ci    current = members.getHead();
8884d6c458bSopenharmony_ci    while (current !== undefined && current !== undefined) {
8894d6c458bSopenharmony_ci      if (current.element.key === key) {
8904d6c458bSopenharmony_ci        return true;
8914d6c458bSopenharmony_ci      }
8924d6c458bSopenharmony_ci      current = current.next;
8934d6c458bSopenharmony_ci    }
8944d6c458bSopenharmony_ci    return false;
8954d6c458bSopenharmony_ci  }
8964d6c458bSopenharmony_ci  protected setAll(map: DictionaryClass<K, V>): void {
8974d6c458bSopenharmony_ci    let memebers: Pair<K, V>[] = [];
8984d6c458bSopenharmony_ci    memebers = map.keyValues();
8994d6c458bSopenharmony_ci    for (let i: number = 0; i < memebers.length; i++) {
9004d6c458bSopenharmony_ci      this.put(memebers[i].key, memebers[i].value);
9014d6c458bSopenharmony_ci    }
9024d6c458bSopenharmony_ci  }
9034d6c458bSopenharmony_ci  protected values(): V[] {
9044d6c458bSopenharmony_ci    let values: Array<V> = [];
9054d6c458bSopenharmony_ci    let valuePairs: Pair<K, V>[] = [];
9064d6c458bSopenharmony_ci    valuePairs = this.keyValues();
9074d6c458bSopenharmony_ci    for (let i: number = 0; i < valuePairs.length; i++) {
9084d6c458bSopenharmony_ci      values.push(valuePairs[i].value);
9094d6c458bSopenharmony_ci    }
9104d6c458bSopenharmony_ci    return values;
9114d6c458bSopenharmony_ci  }
9124d6c458bSopenharmony_ci}
9134d6c458bSopenharmony_ciclass Node<T> {
9144d6c458bSopenharmony_ci  element: T;
9154d6c458bSopenharmony_ci  next: Node<T> | undefined;
9164d6c458bSopenharmony_ci  constructor(element: T, next?: Node<T>) {
9174d6c458bSopenharmony_ci    this.element = element;
9184d6c458bSopenharmony_ci    this.next = next;
9194d6c458bSopenharmony_ci  }
9204d6c458bSopenharmony_ci}
9214d6c458bSopenharmony_ciclass LinkedList<T> {
9224d6c458bSopenharmony_ci  public count: number;
9234d6c458bSopenharmony_ci  protected next: Node<T> | undefined;
9244d6c458bSopenharmony_ci  protected head: Node<T> | undefined;
9254d6c458bSopenharmony_ci  constructor() {
9264d6c458bSopenharmony_ci    this.count = 0;
9274d6c458bSopenharmony_ci    this.next = undefined;
9284d6c458bSopenharmony_ci    this.head = undefined;
9294d6c458bSopenharmony_ci  }
9304d6c458bSopenharmony_ci  push(element: T): void {
9314d6c458bSopenharmony_ci    let node: Node<T> = undefined;
9324d6c458bSopenharmony_ci    node = new Node(element);
9334d6c458bSopenharmony_ci    let current: undefined | Node<T>;
9344d6c458bSopenharmony_ci    if (this.head === undefined) {
9354d6c458bSopenharmony_ci      this.head = node;
9364d6c458bSopenharmony_ci    } else {
9374d6c458bSopenharmony_ci      current = this.head;
9384d6c458bSopenharmony_ci      while (current.next !== undefined) {
9394d6c458bSopenharmony_ci        current = current.next;
9404d6c458bSopenharmony_ci      }
9414d6c458bSopenharmony_ci      current.next = node;
9424d6c458bSopenharmony_ci    }
9434d6c458bSopenharmony_ci    this.count++;
9444d6c458bSopenharmony_ci  }
9454d6c458bSopenharmony_ci  removeAt(index: number): T {
9464d6c458bSopenharmony_ci    if (index >= 0 && index < this.count) {
9474d6c458bSopenharmony_ci      let current: Node<T> = this.head;
9484d6c458bSopenharmony_ci      if (index === 0 && current !== undefined) {
9494d6c458bSopenharmony_ci        this.head = current.next;
9504d6c458bSopenharmony_ci      } else {
9514d6c458bSopenharmony_ci        let previous: Node<T> = this.getElementAt(index--);
9524d6c458bSopenharmony_ci        if (previous !== undefined) {
9534d6c458bSopenharmony_ci          current = previous.next;
9544d6c458bSopenharmony_ci          previous.next = (current === undefined ? undefined : current.next);
9554d6c458bSopenharmony_ci        }
9564d6c458bSopenharmony_ci      }
9574d6c458bSopenharmony_ci      if (current !== undefined) {
9584d6c458bSopenharmony_ci        this.count--;
9594d6c458bSopenharmony_ci        return current.element;
9604d6c458bSopenharmony_ci      }
9614d6c458bSopenharmony_ci    }
9624d6c458bSopenharmony_ci    return undefined;
9634d6c458bSopenharmony_ci  }
9644d6c458bSopenharmony_ci  getElementAt(index: number): Node<T> {
9654d6c458bSopenharmony_ci    if (index > 0 && index < this.count) {
9664d6c458bSopenharmony_ci      let current: Node<T> = this.head;
9674d6c458bSopenharmony_ci      for (let i: number = 0; i < index && current !== undefined; i++) {
9684d6c458bSopenharmony_ci        current = current.next;
9694d6c458bSopenharmony_ci      }
9704d6c458bSopenharmony_ci      return current;
9714d6c458bSopenharmony_ci    }
9724d6c458bSopenharmony_ci    return undefined;
9734d6c458bSopenharmony_ci  }
9744d6c458bSopenharmony_ci  insert(element: T, index: number): boolean {
9754d6c458bSopenharmony_ci    if (index >= 0 && index <= this.count) {
9764d6c458bSopenharmony_ci      let node: Node<T> = undefined;
9774d6c458bSopenharmony_ci      node = new Node(element);
9784d6c458bSopenharmony_ci      if (index === 0) {
9794d6c458bSopenharmony_ci        node.next = this.head;
9804d6c458bSopenharmony_ci        this.head = node;
9814d6c458bSopenharmony_ci      } else {
9824d6c458bSopenharmony_ci        let previous: Node<T> = this.getElementAt(index--);
9834d6c458bSopenharmony_ci        if (previous === undefined) {
9844d6c458bSopenharmony_ci          throw new Error('data storage error');
9854d6c458bSopenharmony_ci        }
9864d6c458bSopenharmony_ci        node.next = previous.next;
9874d6c458bSopenharmony_ci        previous.next = node;
9884d6c458bSopenharmony_ci      }
9894d6c458bSopenharmony_ci      this.count++;
9904d6c458bSopenharmony_ci      return true;
9914d6c458bSopenharmony_ci    }
9924d6c458bSopenharmony_ci    return false;
9934d6c458bSopenharmony_ci  }
9944d6c458bSopenharmony_ci  indexOf(element: T, compareFn?: CompFun<T>): number {
9954d6c458bSopenharmony_ci    let current: Node<T> = this.head;
9964d6c458bSopenharmony_ci    for (let i: number = 0; i < this.count && current !== undefined; i++) {
9974d6c458bSopenharmony_ci      if (currencyCompare(element, current.element, compareFn) === ComparResult.EQUALS) {
9984d6c458bSopenharmony_ci        return i;
9994d6c458bSopenharmony_ci      }
10004d6c458bSopenharmony_ci      current = current.next;
10014d6c458bSopenharmony_ci    }
10024d6c458bSopenharmony_ci    return -1;
10034d6c458bSopenharmony_ci  }
10044d6c458bSopenharmony_ci  remove(element: T, compareFn?: CompFun<T>): void {
10054d6c458bSopenharmony_ci    this.removeAt(this.indexOf(element, compareFn));
10064d6c458bSopenharmony_ci  }
10074d6c458bSopenharmony_ci  clear(): void {
10084d6c458bSopenharmony_ci    this.head = undefined;
10094d6c458bSopenharmony_ci    this.count = 0;
10104d6c458bSopenharmony_ci  }
10114d6c458bSopenharmony_ci  isEmpty(): boolean {
10124d6c458bSopenharmony_ci    return this.count === 0;
10134d6c458bSopenharmony_ci  }
10144d6c458bSopenharmony_ci  getHead(): Node<T> {
10154d6c458bSopenharmony_ci    return this.head;
10164d6c458bSopenharmony_ci  }
10174d6c458bSopenharmony_ci  toString(): string {
10184d6c458bSopenharmony_ci    if (this.head === undefined) {
10194d6c458bSopenharmony_ci      return '';
10204d6c458bSopenharmony_ci    }
10214d6c458bSopenharmony_ci    let objString: string = '';
10224d6c458bSopenharmony_ci    objString = `${this.head.element}`;
10234d6c458bSopenharmony_ci    let current: Node<T> = undefined;
10244d6c458bSopenharmony_ci    current = this.head.next;
10254d6c458bSopenharmony_ci    for (let i: number = 1; i < this.count && current !== undefined; i++) {
10264d6c458bSopenharmony_ci      objString = `${objString}, ${current.element}`;
10274d6c458bSopenharmony_ci      current = current.next;
10284d6c458bSopenharmony_ci    }
10294d6c458bSopenharmony_ci    return objString;
10304d6c458bSopenharmony_ci  }
10314d6c458bSopenharmony_ci}
10324d6c458bSopenharmony_ci
10334d6c458bSopenharmony_ciconst NEWTARGET_IS_NULL_ERROR_CODE = 10200012;
10344d6c458bSopenharmony_ciconst BIND_ERROR_CODE = 10200011;
10354d6c458bSopenharmony_ciconst RANGE_ERROR_CODE = 10200001;
10364d6c458bSopenharmony_ciconst TYPE_ERROR_CODE = 401;
10374d6c458bSopenharmony_ciconst EMPTY_ERROR_CODE = 10200010;
10384d6c458bSopenharmony_ci
10394d6c458bSopenharmony_ciclass BusinessError extends Error {
10404d6c458bSopenharmony_ci  code: number;
10414d6c458bSopenharmony_ci  constructor(message, code) {
10424d6c458bSopenharmony_ci    super();
10434d6c458bSopenharmony_ci    this.name = 'BusinessError';
10444d6c458bSopenharmony_ci    this.message = message;
10454d6c458bSopenharmony_ci    this.code = code;
10464d6c458bSopenharmony_ci  }
10474d6c458bSopenharmony_ci}
10484d6c458bSopenharmony_ci
10494d6c458bSopenharmony_cifunction checkBindError(methodName: string, className: Function, self: unknown): void {
10504d6c458bSopenharmony_ci  if (!(self instanceof className)) {
10514d6c458bSopenharmony_ci    throw new BusinessError(`The ${methodName} method cannot be bound`, BIND_ERROR_CODE);
10524d6c458bSopenharmony_ci  }
10534d6c458bSopenharmony_ci}
10544d6c458bSopenharmony_ci
10554d6c458bSopenharmony_cifunction checkTypeError(paramName: string, type: string, receivedValue: unknown): void {
10564d6c458bSopenharmony_ci  let tmpType = '';
10574d6c458bSopenharmony_ci  if (typeof receivedValue === 'object') {
10584d6c458bSopenharmony_ci    tmpType = (receivedValue === null) ? 'Null' : receivedValue.constructor.name;
10594d6c458bSopenharmony_ci  } else {
10604d6c458bSopenharmony_ci    tmpType = typeof receivedValue;
10614d6c458bSopenharmony_ci  }
10624d6c458bSopenharmony_ci  if (tmpType === 'number' && type === 'Integer') {
10634d6c458bSopenharmony_ci    tmpType = Number.isInteger(receivedValue) ? 'Integer' : 'number';
10644d6c458bSopenharmony_ci  }
10654d6c458bSopenharmony_ci  if (tmpType === 'function' && type === 'callable') {
10664d6c458bSopenharmony_ci    tmpType = 'callable';
10674d6c458bSopenharmony_ci  }
10684d6c458bSopenharmony_ci  if (tmpType.toLocaleLowerCase() !== type.toLocaleLowerCase()) {
10694d6c458bSopenharmony_ci    type = (type === 'Integer') ? 'number' : type;
10704d6c458bSopenharmony_ci    throw new BusinessError(`The type of "${paramName}" must be ${type}. Received value is: ${receivedValue}`, TYPE_ERROR_CODE);
10714d6c458bSopenharmony_ci  }
10724d6c458bSopenharmony_ci}
10734d6c458bSopenharmony_ci
10744d6c458bSopenharmony_cifunction checkRangeError(paramName: string, receivedValue: unknown, min?: number, max?: number, options?: string): void {
10754d6c458bSopenharmony_ci  let range = [];
10764d6c458bSopenharmony_ci  let minFlag = true;
10774d6c458bSopenharmony_ci  let maxFlag = true;
10784d6c458bSopenharmony_ci  if (min !== undefined) {
10794d6c458bSopenharmony_ci    if (options === '!=min') {
10804d6c458bSopenharmony_ci      minFlag = (receivedValue > min);
10814d6c458bSopenharmony_ci      range.push(`> ${min}`);
10824d6c458bSopenharmony_ci    } else {
10834d6c458bSopenharmony_ci      minFlag = (receivedValue >= min);
10844d6c458bSopenharmony_ci      range.push(`>= ${min}`);
10854d6c458bSopenharmony_ci    }
10864d6c458bSopenharmony_ci  }
10874d6c458bSopenharmony_ci  if (max !== undefined) {
10884d6c458bSopenharmony_ci    max = (max < 0) ? 0 : max;
10894d6c458bSopenharmony_ci    maxFlag = (receivedValue <= max);
10904d6c458bSopenharmony_ci    range.push(`<= ${max}`);
10914d6c458bSopenharmony_ci  }
10924d6c458bSopenharmony_ci  if (!(minFlag && maxFlag)) {
10934d6c458bSopenharmony_ci    throw new BusinessError(
10944d6c458bSopenharmony_ci      `The value of "${paramName}" is out of range. It must be ${range.join(' && ')}. Received value is: ${receivedValue}`, RANGE_ERROR_CODE);
10954d6c458bSopenharmony_ci  }
10964d6c458bSopenharmony_ci}
10974d6c458bSopenharmony_ci
10984d6c458bSopenharmony_cifunction checkIsEmptyError(isEmpty: boolean): void {
10994d6c458bSopenharmony_ci  if (isEmpty) {
11004d6c458bSopenharmony_ci    throw new BusinessError('Container is empty', EMPTY_ERROR_CODE);
11014d6c458bSopenharmony_ci  }
11024d6c458bSopenharmony_ci}
11034d6c458bSopenharmony_ci
11044d6c458bSopenharmony_cifunction checkNewTargetIsNullError(className: string, isNull: boolean): void {
11054d6c458bSopenharmony_ci  if (isNull) {
11064d6c458bSopenharmony_ci    throw new BusinessError(`The ${className}'s constructor cannot be directly invoked`, NEWTARGET_IS_NULL_ERROR_CODE);
11074d6c458bSopenharmony_ci  }
11084d6c458bSopenharmony_ci}
11094d6c458bSopenharmony_ci
11104d6c458bSopenharmony_cilet errorUtil = {
11114d6c458bSopenharmony_ci  checkBindError,
11124d6c458bSopenharmony_ci  checkTypeError,
11134d6c458bSopenharmony_ci  checkRangeError,
11144d6c458bSopenharmony_ci  checkIsEmptyError,
11154d6c458bSopenharmony_ci  checkNewTargetIsNullError
11164d6c458bSopenharmony_ci};
11174d6c458bSopenharmony_ciexport default {
11184d6c458bSopenharmony_ci  isIncludeToArray,
11194d6c458bSopenharmony_ci  LightWeightClass,
11204d6c458bSopenharmony_ci  PlainArrayClass,
11214d6c458bSopenharmony_ci  TreeClass,
11224d6c458bSopenharmony_ci  DictionaryClass,
11234d6c458bSopenharmony_ci  errorUtil
11244d6c458bSopenharmony_ci};