/**
 * @license
 * Copyright Google LLC All Rights Reserved.
 *
 * Use of this source code is governed by an MIT-style license that can be
 * found in the LICENSE file at https://angular.io/license
 */
/**
 * Moves an item one index in an array to another.
 * @param array Array in which to move the item.
 * @param fromIndex Starting index of the item.
 * @param toIndex Index to which the item should be moved.
 */
export function moveItemInArray(array, fromIndex, toIndex) {
    const from = clamp(fromIndex, array.length - 1);
    const to = clamp(toIndex, array.length - 1);
    if (from === to) {
        return;
    }
    const target = array[from];
    const delta = to < from ? -1 : 1;
    for (let i = from; i !== to; i += delta) {
        array[i] = array[i + delta];
    }
    array[to] = target;
}
/**
 * Moves an item from one array to another.
 * @param currentArray Array from which to transfer the item.
 * @param targetArray Array into which to put the item.
 * @param currentIndex Index of the item in its current array.
 * @param targetIndex Index at which to insert the item.
 */
export function transferArrayItem(currentArray, targetArray, currentIndex, targetIndex) {
    const from = clamp(currentIndex, currentArray.length - 1);
    const to = clamp(targetIndex, targetArray.length);
    if (currentArray.length) {
        targetArray.splice(to, 0, currentArray.splice(from, 1)[0]);
    }
}
/**
 * Copies an item from one array to another, leaving it in its
 * original position in current array.
 * @param currentArray Array from which to copy the item.
 * @param targetArray Array into which is copy the item.
 * @param currentIndex Index of the item in its current array.
 * @param targetIndex Index at which to insert the item.
 *
 */
export function copyArrayItem(currentArray, targetArray, currentIndex, targetIndex) {
    const to = clamp(targetIndex, targetArray.length);
    if (currentArray.length) {
        targetArray.splice(to, 0, currentArray[currentIndex]);
    }
}
/** Clamps a number between zero and a maximum. */
function clamp(value, max) {
    return Math.max(0, Math.min(max, value));
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJhZy11dGlscy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9jZGsvZHJhZy1kcm9wL2RyYWctdXRpbHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUg7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsZUFBZSxDQUFVLEtBQVUsRUFBRSxTQUFpQixFQUFFLE9BQWU7SUFDckYsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ2hELE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQztJQUU1QyxJQUFJLElBQUksS0FBSyxFQUFFLEVBQUU7UUFDZixPQUFPO0tBQ1I7SUFFRCxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDM0IsTUFBTSxLQUFLLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUVqQyxLQUFLLElBQUksQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsSUFBSSxLQUFLLEVBQUU7UUFDdkMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUM7S0FDN0I7SUFFRCxLQUFLLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDO0FBQ3JCLENBQUM7QUFHRDs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsaUJBQWlCLENBQVUsWUFBaUIsRUFDakIsV0FBZ0IsRUFDaEIsWUFBb0IsRUFDcEIsV0FBbUI7SUFDNUQsTUFBTSxJQUFJLEdBQUcsS0FBSyxDQUFDLFlBQVksRUFBRSxZQUFZLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQzFELE1BQU0sRUFBRSxHQUFHLEtBQUssQ0FBQyxXQUFXLEVBQUUsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRWxELElBQUksWUFBWSxDQUFDLE1BQU0sRUFBRTtRQUN2QixXQUFXLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsWUFBWSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztLQUM1RDtBQUNILENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxhQUFhLENBQVUsWUFBaUIsRUFDakIsV0FBZ0IsRUFDaEIsWUFBb0IsRUFDcEIsV0FBbUI7SUFDeEQsTUFBTSxFQUFFLEdBQUcsS0FBSyxDQUFDLFdBQVcsRUFBRSxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7SUFFbEQsSUFBSSxZQUFZLENBQUMsTUFBTSxFQUFFO1FBQ3ZCLFdBQVcsQ0FBQyxNQUFNLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxZQUFZLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQztLQUN2RDtBQUNILENBQUM7QUFFRCxrREFBa0Q7QUFDbEQsU0FBUyxLQUFLLENBQUMsS0FBYSxFQUFFLEdBQVc7SUFDdkMsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQzNDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuLyoqXG4gKiBNb3ZlcyBhbiBpdGVtIG9uZSBpbmRleCBpbiBhbiBhcnJheSB0byBhbm90aGVyLlxuICogQHBhcmFtIGFycmF5IEFycmF5IGluIHdoaWNoIHRvIG1vdmUgdGhlIGl0ZW0uXG4gKiBAcGFyYW0gZnJvbUluZGV4IFN0YXJ0aW5nIGluZGV4IG9mIHRoZSBpdGVtLlxuICogQHBhcmFtIHRvSW5kZXggSW5kZXggdG8gd2hpY2ggdGhlIGl0ZW0gc2hvdWxkIGJlIG1vdmVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbW92ZUl0ZW1JbkFycmF5PFQgPSBhbnk+KGFycmF5OiBUW10sIGZyb21JbmRleDogbnVtYmVyLCB0b0luZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgY29uc3QgZnJvbSA9IGNsYW1wKGZyb21JbmRleCwgYXJyYXkubGVuZ3RoIC0gMSk7XG4gIGNvbnN0IHRvID0gY2xhbXAodG9JbmRleCwgYXJyYXkubGVuZ3RoIC0gMSk7XG5cbiAgaWYgKGZyb20gPT09IHRvKSB7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgdGFyZ2V0ID0gYXJyYXlbZnJvbV07XG4gIGNvbnN0IGRlbHRhID0gdG8gPCBmcm9tID8gLTEgOiAxO1xuXG4gIGZvciAobGV0IGkgPSBmcm9tOyBpICE9PSB0bzsgaSArPSBkZWx0YSkge1xuICAgIGFycmF5W2ldID0gYXJyYXlbaSArIGRlbHRhXTtcbiAgfVxuXG4gIGFycmF5W3RvXSA9IHRhcmdldDtcbn1cblxuXG4vKipcbiAqIE1vdmVzIGFuIGl0ZW0gZnJvbSBvbmUgYXJyYXkgdG8gYW5vdGhlci5cbiAqIEBwYXJhbSBjdXJyZW50QXJyYXkgQXJyYXkgZnJvbSB3aGljaCB0byB0cmFuc2ZlciB0aGUgaXRlbS5cbiAqIEBwYXJhbSB0YXJnZXRBcnJheSBBcnJheSBpbnRvIHdoaWNoIHRvIHB1dCB0aGUgaXRlbS5cbiAqIEBwYXJhbSBjdXJyZW50SW5kZXggSW5kZXggb2YgdGhlIGl0ZW0gaW4gaXRzIGN1cnJlbnQgYXJyYXkuXG4gKiBAcGFyYW0gdGFyZ2V0SW5kZXggSW5kZXggYXQgd2hpY2ggdG8gaW5zZXJ0IHRoZSBpdGVtLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNmZXJBcnJheUl0ZW08VCA9IGFueT4oY3VycmVudEFycmF5OiBUW10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0QXJyYXk6IFRbXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50SW5kZXg6IG51bWJlcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gIGNvbnN0IGZyb20gPSBjbGFtcChjdXJyZW50SW5kZXgsIGN1cnJlbnRBcnJheS5sZW5ndGggLSAxKTtcbiAgY29uc3QgdG8gPSBjbGFtcCh0YXJnZXRJbmRleCwgdGFyZ2V0QXJyYXkubGVuZ3RoKTtcblxuICBpZiAoY3VycmVudEFycmF5Lmxlbmd0aCkge1xuICAgIHRhcmdldEFycmF5LnNwbGljZSh0bywgMCwgY3VycmVudEFycmF5LnNwbGljZShmcm9tLCAxKVswXSk7XG4gIH1cbn1cblxuLyoqXG4gKiBDb3BpZXMgYW4gaXRlbSBmcm9tIG9uZSBhcnJheSB0byBhbm90aGVyLCBsZWF2aW5nIGl0IGluIGl0c1xuICogb3JpZ2luYWwgcG9zaXRpb24gaW4gY3VycmVudCBhcnJheS5cbiAqIEBwYXJhbSBjdXJyZW50QXJyYXkgQXJyYXkgZnJvbSB3aGljaCB0byBjb3B5IHRoZSBpdGVtLlxuICogQHBhcmFtIHRhcmdldEFycmF5IEFycmF5IGludG8gd2hpY2ggaXMgY29weSB0aGUgaXRlbS5cbiAqIEBwYXJhbSBjdXJyZW50SW5kZXggSW5kZXggb2YgdGhlIGl0ZW0gaW4gaXRzIGN1cnJlbnQgYXJyYXkuXG4gKiBAcGFyYW0gdGFyZ2V0SW5kZXggSW5kZXggYXQgd2hpY2ggdG8gaW5zZXJ0IHRoZSBpdGVtLlxuICpcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvcHlBcnJheUl0ZW08VCA9IGFueT4oY3VycmVudEFycmF5OiBUW10sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRBcnJheTogVFtdLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudEluZGV4OiBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRJbmRleDogbnVtYmVyKTogdm9pZCB7XG4gIGNvbnN0IHRvID0gY2xhbXAodGFyZ2V0SW5kZXgsIHRhcmdldEFycmF5Lmxlbmd0aCk7XG5cbiAgaWYgKGN1cnJlbnRBcnJheS5sZW5ndGgpIHtcbiAgICB0YXJnZXRBcnJheS5zcGxpY2UodG8sIDAsIGN1cnJlbnRBcnJheVtjdXJyZW50SW5kZXhdKTtcbiAgfVxufVxuXG4vKiogQ2xhbXBzIGEgbnVtYmVyIGJldHdlZW4gemVybyBhbmQgYSBtYXhpbXVtLiAqL1xuZnVuY3Rpb24gY2xhbXAodmFsdWU6IG51bWJlciwgbWF4OiBudW1iZXIpOiBudW1iZXIge1xuICByZXR1cm4gTWF0aC5tYXgoMCwgTWF0aC5taW4obWF4LCB2YWx1ZSkpO1xufVxuIl19