(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/core'), require('@angular/common'), require('@angular/cdk/scrolling'), require('@angular/cdk/platform'), require('@angular/cdk/coercion'), require('rxjs'), require('rxjs/operators'), require('@angular/cdk/bidi')) :
    typeof define === 'function' && define.amd ? define('@angular/cdk/drag-drop', ['exports', '@angular/core', '@angular/common', '@angular/cdk/scrolling', '@angular/cdk/platform', '@angular/cdk/coercion', 'rxjs', 'rxjs/operators', '@angular/cdk/bidi'], factory) :
    (global = global || self, factory((global.ng = global.ng || {}, global.ng.cdk = global.ng.cdk || {}, global.ng.cdk.dragDrop = {}), global.ng.core, global.ng.common, global.ng.cdk.scrolling, global.ng.cdk.platform, global.ng.cdk.coercion, global.rxjs, global.rxjs.operators, global.ng.cdk.bidi));
}(this, (function (exports, i0, i1, i2, platform, coercion, rxjs, operators, bidi) { 'use strict';

    /**
     * @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
     */
    /**
     * Shallow-extends a stylesheet object with another stylesheet object.
     * @docs-private
     */
    function extendStyles(dest, source) {
        for (var key in source) {
            if (source.hasOwnProperty(key)) {
                dest[key] = source[key];
            }
        }
        return dest;
    }
    /**
     * Toggles whether the native drag interactions should be enabled for an element.
     * @param element Element on which to toggle the drag interactions.
     * @param enable Whether the drag interactions should be enabled.
     * @docs-private
     */
    function toggleNativeDragInteractions(element, enable) {
        var userSelect = enable ? '' : 'none';
        extendStyles(element.style, {
            touchAction: enable ? '' : 'none',
            webkitUserDrag: enable ? '' : 'none',
            webkitTapHighlightColor: enable ? '' : 'transparent',
            userSelect: userSelect,
            msUserSelect: userSelect,
            webkitUserSelect: userSelect,
            MozUserSelect: userSelect
        });
    }
    /**
     * Toggles whether an element is visible while preserving its dimensions.
     * @param element Element whose visibility to toggle
     * @param enable Whether the element should be visible.
     * @docs-private
     */
    function toggleVisibility(element, enable) {
        var styles = element.style;
        styles.position = enable ? '' : 'fixed';
        styles.top = styles.opacity = enable ? '' : '0';
        styles.left = enable ? '' : '-999em';
    }

    /**
     * @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
     */
    /** Parses a CSS time value to milliseconds. */
    function parseCssTimeUnitsToMs(value) {
        // Some browsers will return it in seconds, whereas others will return milliseconds.
        var multiplier = value.toLowerCase().indexOf('ms') > -1 ? 1 : 1000;
        return parseFloat(value) * multiplier;
    }
    /** Gets the transform transition duration, including the delay, of an element in milliseconds. */
    function getTransformTransitionDurationInMs(element) {
        var computedStyle = getComputedStyle(element);
        var transitionedProperties = parseCssPropertyValue(computedStyle, 'transition-property');
        var property = transitionedProperties.find(function (prop) { return prop === 'transform' || prop === 'all'; });
        // If there's no transition for `all` or `transform`, we shouldn't do anything.
        if (!property) {
            return 0;
        }
        // Get the index of the property that we're interested in and match
        // it up to the same index in `transition-delay` and `transition-duration`.
        var propertyIndex = transitionedProperties.indexOf(property);
        var rawDurations = parseCssPropertyValue(computedStyle, 'transition-duration');
        var rawDelays = parseCssPropertyValue(computedStyle, 'transition-delay');
        return parseCssTimeUnitsToMs(rawDurations[propertyIndex]) +
            parseCssTimeUnitsToMs(rawDelays[propertyIndex]);
    }
    /** Parses out multiple values from a computed style into an array. */
    function parseCssPropertyValue(computedStyle, name) {
        var value = computedStyle.getPropertyValue(name);
        return value.split(',').map(function (part) { return part.trim(); });
    }

    /**
     * @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
     */
    /** Gets a mutable version of an element's bounding `ClientRect`. */
    function getMutableClientRect(element) {
        var clientRect = element.getBoundingClientRect();
        // We need to clone the `clientRect` here, because all the values on it are readonly
        // and we need to be able to update them. Also we can't use a spread here, because
        // the values on a `ClientRect` aren't own properties. See:
        // https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect#Notes
        return {
            top: clientRect.top,
            right: clientRect.right,
            bottom: clientRect.bottom,
            left: clientRect.left,
            width: clientRect.width,
            height: clientRect.height
        };
    }
    /**
     * Checks whether some coordinates are within a `ClientRect`.
     * @param clientRect ClientRect that is being checked.
     * @param x Coordinates along the X axis.
     * @param y Coordinates along the Y axis.
     */
    function isInsideClientRect(clientRect, x, y) {
        var top = clientRect.top, bottom = clientRect.bottom, left = clientRect.left, right = clientRect.right;
        return y >= top && y <= bottom && x >= left && x <= right;
    }
    /**
     * Updates the top/left positions of a `ClientRect`, as well as their bottom/right counterparts.
     * @param clientRect `ClientRect` that should be updated.
     * @param top Amount to add to the `top` position.
     * @param left Amount to add to the `left` position.
     */
    function adjustClientRect(clientRect, top, left) {
        clientRect.top += top;
        clientRect.bottom = clientRect.top + clientRect.height;
        clientRect.left += left;
        clientRect.right = clientRect.left + clientRect.width;
    }
    /**
     * Checks whether the pointer coordinates are close to a ClientRect.
     * @param rect ClientRect to check against.
     * @param threshold Threshold around the ClientRect.
     * @param pointerX Coordinates along the X axis.
     * @param pointerY Coordinates along the Y axis.
     */
    function isPointerNearClientRect(rect, threshold, pointerX, pointerY) {
        var top = rect.top, right = rect.right, bottom = rect.bottom, left = rect.left, width = rect.width, height = rect.height;
        var xThreshold = width * threshold;
        var yThreshold = height * threshold;
        return pointerY > top - yThreshold && pointerY < bottom + yThreshold &&
            pointerX > left - xThreshold && pointerX < right + xThreshold;
    }

    /**
     * @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
     */
    /** Keeps track of the scroll position and dimensions of the parents of an element. */
    var ParentPositionTracker = /** @class */ (function () {
        function ParentPositionTracker(_document, _viewportRuler) {
            this._document = _document;
            this._viewportRuler = _viewportRuler;
            /** Cached positions of the scrollable parent elements. */
            this.positions = new Map();
        }
        /** Clears the cached positions. */
        ParentPositionTracker.prototype.clear = function () {
            this.positions.clear();
        };
        /** Caches the positions. Should be called at the beginning of a drag sequence. */
        ParentPositionTracker.prototype.cache = function (elements) {
            var _this = this;
            this.clear();
            this.positions.set(this._document, {
                scrollPosition: this._viewportRuler.getViewportScrollPosition(),
            });
            elements.forEach(function (element) {
                _this.positions.set(element, {
                    scrollPosition: { top: element.scrollTop, left: element.scrollLeft },
                    clientRect: getMutableClientRect(element)
                });
            });
        };
        /** Handles scrolling while a drag is taking place. */
        ParentPositionTracker.prototype.handleScroll = function (event) {
            var target = event.target;
            var cachedPosition = this.positions.get(target);
            if (!cachedPosition) {
                return null;
            }
            // Used when figuring out whether an element is inside the scroll parent. If the scrolled
            // parent is the `document`, we use the `documentElement`, because IE doesn't support
            // `contains` on the `document`.
            var scrolledParentNode = target === this._document ? target.documentElement : target;
            var scrollPosition = cachedPosition.scrollPosition;
            var newTop;
            var newLeft;
            if (target === this._document) {
                var viewportScrollPosition = this._viewportRuler.getViewportScrollPosition();
                newTop = viewportScrollPosition.top;
                newLeft = viewportScrollPosition.left;
            }
            else {
                newTop = target.scrollTop;
                newLeft = target.scrollLeft;
            }
            var topDifference = scrollPosition.top - newTop;
            var leftDifference = scrollPosition.left - newLeft;
            // Go through and update the cached positions of the scroll
            // parents that are inside the element that was scrolled.
            this.positions.forEach(function (position, node) {
                if (position.clientRect && target !== node && scrolledParentNode.contains(node)) {
                    adjustClientRect(position.clientRect, topDifference, leftDifference);
                }
            });
            scrollPosition.top = newTop;
            scrollPosition.left = newLeft;
            return { top: topDifference, left: leftDifference };
        };
        return ParentPositionTracker;
    }());

    /**
     * @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
     */
    /** Creates a deep clone of an element. */
    function deepCloneNode(node) {
        var clone = node.cloneNode(true);
        var descendantsWithId = clone.querySelectorAll('[id]');
        var nodeName = node.nodeName.toLowerCase();
        // Remove the `id` to avoid having multiple elements with the same id on the page.
        clone.removeAttribute('id');
        for (var i = 0; i < descendantsWithId.length; i++) {
            descendantsWithId[i].removeAttribute('id');
        }
        if (nodeName === 'canvas') {
            transferCanvasData(node, clone);
        }
        else if (nodeName === 'input' || nodeName === 'select' || nodeName === 'textarea') {
            transferInputData(node, clone);
        }
        transferData('canvas', node, clone, transferCanvasData);
        transferData('input, textarea, select', node, clone, transferInputData);
        return clone;
    }
    /** Matches elements between an element and its clone and allows for their data to be cloned. */
    function transferData(selector, node, clone, callback) {
        var descendantElements = node.querySelectorAll(selector);
        if (descendantElements.length) {
            var cloneElements = clone.querySelectorAll(selector);
            for (var i = 0; i < descendantElements.length; i++) {
                callback(descendantElements[i], cloneElements[i]);
            }
        }
    }
    // Counter for unique cloned radio button names.
    var cloneUniqueId = 0;
    /** Transfers the data of one input element to another. */
    function transferInputData(source, clone) {
        // Browsers throw an error when assigning the value of a file input programmatically.
        if (clone.type !== 'file') {
            clone.value = source.value;
        }
        // Radio button `name` attributes must be unique for radio button groups
        // otherwise original radio buttons can lose their checked state
        // once the clone is inserted in the DOM.
        if (clone.type === 'radio' && clone.name) {
            clone.name = "mat-clone-" + clone.name + "-" + cloneUniqueId++;
        }
    }
    /** Transfers the data of one canvas element to another. */
    function transferCanvasData(source, clone) {
        var context = clone.getContext('2d');
        if (context) {
            // In some cases `drawImage` can throw (e.g. if the canvas size is 0x0).
            // We can't do much about it so just ignore the error.
            try {
                context.drawImage(source, 0, 0);
            }
            catch (_a) { }
        }
    }

    /**
     * @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
     */
    /** Options that can be used to bind a passive event listener. */
    var passiveEventListenerOptions = platform.normalizePassiveListenerOptions({ passive: true });
    /** Options that can be used to bind an active event listener. */
    var activeEventListenerOptions = platform.normalizePassiveListenerOptions({ passive: false });
    /**
     * Time in milliseconds for which to ignore mouse events, after
     * receiving a touch event. Used to avoid doing double work for
     * touch devices where the browser fires fake mouse events, in
     * addition to touch events.
     */
    var MOUSE_EVENT_IGNORE_TIME = 800;
    /**
     * Reference to a draggable item. Used to manipulate or dispose of the item.
     */
    var DragRef = /** @class */ (function () {
        function DragRef(element, _config, _document, _ngZone, _viewportRuler, _dragDropRegistry) {
            var _this = this;
            this._config = _config;
            this._document = _document;
            this._ngZone = _ngZone;
            this._viewportRuler = _viewportRuler;
            this._dragDropRegistry = _dragDropRegistry;
            /**
             * CSS `transform` applied to the element when it isn't being dragged. We need a
             * passive transform in order for the dragged element to retain its new position
             * after the user has stopped dragging and because we need to know the relative
             * position in case they start dragging again. This corresponds to `element.style.transform`.
             */
            this._passiveTransform = { x: 0, y: 0 };
            /** CSS `transform` that is applied to the element while it's being dragged. */
            this._activeTransform = { x: 0, y: 0 };
            /** Emits when the item is being moved. */
            this._moveEvents = new rxjs.Subject();
            /** Subscription to pointer movement events. */
            this._pointerMoveSubscription = rxjs.Subscription.EMPTY;
            /** Subscription to the event that is dispatched when the user lifts their pointer. */
            this._pointerUpSubscription = rxjs.Subscription.EMPTY;
            /** Subscription to the viewport being scrolled. */
            this._scrollSubscription = rxjs.Subscription.EMPTY;
            /** Subscription to the viewport being resized. */
            this._resizeSubscription = rxjs.Subscription.EMPTY;
            /** Cached reference to the boundary element. */
            this._boundaryElement = null;
            /** Whether the native dragging interactions have been enabled on the root element. */
            this._nativeInteractionsEnabled = true;
            /** Elements that can be used to drag the draggable item. */
            this._handles = [];
            /** Registered handles that are currently disabled. */
            this._disabledHandles = new Set();
            /** Layout direction of the item. */
            this._direction = 'ltr';
            /**
             * Amount of milliseconds to wait after the user has put their
             * pointer down before starting to drag the element.
             */
            this.dragStartDelay = 0;
            this._disabled = false;
            /** Emits as the drag sequence is being prepared. */
            this.beforeStarted = new rxjs.Subject();
            /** Emits when the user starts dragging the item. */
            this.started = new rxjs.Subject();
            /** Emits when the user has released a drag item, before any animations have started. */
            this.released = new rxjs.Subject();
            /** Emits when the user stops dragging an item in the container. */
            this.ended = new rxjs.Subject();
            /** Emits when the user has moved the item into a new container. */
            this.entered = new rxjs.Subject();
            /** Emits when the user removes the item its container by dragging it into another container. */
            this.exited = new rxjs.Subject();
            /** Emits when the user drops the item inside a container. */
            this.dropped = new rxjs.Subject();
            /**
             * Emits as the user is dragging the item. Use with caution,
             * because this event will fire for every pixel that the user has dragged.
             */
            this.moved = this._moveEvents;
            /** Handler for the `mousedown`/`touchstart` events. */
            this._pointerDown = function (event) {
                _this.beforeStarted.next();
                // Delegate the event based on whether it started from a handle or the element itself.
                if (_this._handles.length) {
                    var targetHandle = _this._handles.find(function (handle) {
                        var target = event.target;
                        return !!target && (target === handle || handle.contains(target));
                    });
                    if (targetHandle && !_this._disabledHandles.has(targetHandle) && !_this.disabled) {
                        _this._initializeDragSequence(targetHandle, event);
                    }
                }
                else if (!_this.disabled) {
                    _this._initializeDragSequence(_this._rootElement, event);
                }
            };
            /** Handler that is invoked when the user moves their pointer after they've initiated a drag. */
            this._pointerMove = function (event) {
                var pointerPosition = _this._getPointerPositionOnPage(event);
                if (!_this._hasStartedDragging) {
                    var distanceX = Math.abs(pointerPosition.x - _this._pickupPositionOnPage.x);
                    var distanceY = Math.abs(pointerPosition.y - _this._pickupPositionOnPage.y);
                    var isOverThreshold = distanceX + distanceY >= _this._config.dragStartThreshold;
                    // Only start dragging after the user has moved more than the minimum distance in either
                    // direction. Note that this is preferrable over doing something like `skip(minimumDistance)`
                    // in the `pointerMove` subscription, because we're not guaranteed to have one move event
                    // per pixel of movement (e.g. if the user moves their pointer quickly).
                    if (isOverThreshold) {
                        var isDelayElapsed = Date.now() >= _this._dragStartTime + _this._getDragStartDelay(event);
                        var container = _this._dropContainer;
                        if (!isDelayElapsed) {
                            _this._endDragSequence(event);
                            return;
                        }
                        // Prevent other drag sequences from starting while something in the container is still
                        // being dragged. This can happen while we're waiting for the drop animation to finish
                        // and can cause errors, because some elements might still be moving around.
                        if (!container || (!container.isDragging() && !container.isReceiving())) {
                            // Prevent the default action as soon as the dragging sequence is considered as
                            // "started" since waiting for the next event can allow the device to begin scrolling.
                            event.preventDefault();
                            _this._hasStartedDragging = true;
                            _this._ngZone.run(function () { return _this._startDragSequence(event); });
                        }
                    }
                    return;
                }
                // We only need the preview dimensions if we have a boundary element.
                if (_this._boundaryElement) {
                    // Cache the preview element rect if we haven't cached it already or if
                    // we cached it too early before the element dimensions were computed.
                    if (!_this._previewRect || (!_this._previewRect.width && !_this._previewRect.height)) {
                        _this._previewRect = (_this._preview || _this._rootElement).getBoundingClientRect();
                    }
                }
                // We prevent the default action down here so that we know that dragging has started. This is
                // important for touch devices where doing this too early can unnecessarily block scrolling,
                // if there's a dragging delay.
                event.preventDefault();
                var constrainedPointerPosition = _this._getConstrainedPointerPosition(pointerPosition);
                _this._hasMoved = true;
                _this._lastKnownPointerPosition = pointerPosition;
                _this._updatePointerDirectionDelta(constrainedPointerPosition);
                if (_this._dropContainer) {
                    _this._updateActiveDropContainer(constrainedPointerPosition, pointerPosition);
                }
                else {
                    var activeTransform = _this._activeTransform;
                    activeTransform.x =
                        constrainedPointerPosition.x - _this._pickupPositionOnPage.x + _this._passiveTransform.x;
                    activeTransform.y =
                        constrainedPointerPosition.y - _this._pickupPositionOnPage.y + _this._passiveTransform.y;
                    _this._applyRootElementTransform(activeTransform.x, activeTransform.y);
                    // Apply transform as attribute if dragging and svg element to work for IE
                    if (typeof SVGElement !== 'undefined' && _this._rootElement instanceof SVGElement) {
                        var appliedTransform = "translate(" + activeTransform.x + " " + activeTransform.y + ")";
                        _this._rootElement.setAttribute('transform', appliedTransform);
                    }
                }
                // Since this event gets fired for every pixel while dragging, we only
                // want to fire it if the consumer opted into it. Also we have to
                // re-enter the zone because we run all of the events on the outside.
                if (_this._moveEvents.observers.length) {
                    _this._ngZone.run(function () {
                        _this._moveEvents.next({
                            source: _this,
                            pointerPosition: constrainedPointerPosition,
                            event: event,
                            distance: _this._getDragDistance(constrainedPointerPosition),
                            delta: _this._pointerDirectionDelta
                        });
                    });
                }
            };
            /** Handler that is invoked when the user lifts their pointer up, after initiating a drag. */
            this._pointerUp = function (event) {
                _this._endDragSequence(event);
            };
            this.withRootElement(element).withParent(_config.parentDragRef || null);
            this._parentPositions = new ParentPositionTracker(_document, _viewportRuler);
            _dragDropRegistry.registerDragItem(this);
        }
        Object.defineProperty(DragRef.prototype, "disabled", {
            /** Whether starting to drag this element is disabled. */
            get: function () {
                return this._disabled || !!(this._dropContainer && this._dropContainer.disabled);
            },
            set: function (value) {
                var newValue = coercion.coerceBooleanProperty(value);
                if (newValue !== this._disabled) {
                    this._disabled = newValue;
                    this._toggleNativeDragInteractions();
                    this._handles.forEach(function (handle) { return toggleNativeDragInteractions(handle, newValue); });
                }
            },
            enumerable: false,
            configurable: true
        });
        /**
         * Returns the element that is being used as a placeholder
         * while the current element is being dragged.
         */
        DragRef.prototype.getPlaceholderElement = function () {
            return this._placeholder;
        };
        /** Returns the root draggable element. */
        DragRef.prototype.getRootElement = function () {
            return this._rootElement;
        };
        /**
         * Gets the currently-visible element that represents the drag item.
         * While dragging this is the placeholder, otherwise it's the root element.
         */
        DragRef.prototype.getVisibleElement = function () {
            return this.isDragging() ? this.getPlaceholderElement() : this.getRootElement();
        };
        /** Registers the handles that can be used to drag the element. */
        DragRef.prototype.withHandles = function (handles) {
            var _this = this;
            this._handles = handles.map(function (handle) { return coercion.coerceElement(handle); });
            this._handles.forEach(function (handle) { return toggleNativeDragInteractions(handle, _this.disabled); });
            this._toggleNativeDragInteractions();
            // Delete any lingering disabled handles that may have been destroyed. Note that we re-create
            // the set, rather than iterate over it and filter out the destroyed handles, because while
            // the ES spec allows for sets to be modified while they're being iterated over, some polyfills
            // use an array internally which may throw an error.
            var disabledHandles = new Set();
            this._disabledHandles.forEach(function (handle) {
                if (_this._handles.indexOf(handle) > -1) {
                    disabledHandles.add(handle);
                }
            });
            this._disabledHandles = disabledHandles;
            return this;
        };
        /**
         * Registers the template that should be used for the drag preview.
         * @param template Template that from which to stamp out the preview.
         */
        DragRef.prototype.withPreviewTemplate = function (template) {
            this._previewTemplate = template;
            return this;
        };
        /**
         * Registers the template that should be used for the drag placeholder.
         * @param template Template that from which to stamp out the placeholder.
         */
        DragRef.prototype.withPlaceholderTemplate = function (template) {
            this._placeholderTemplate = template;
            return this;
        };
        /**
         * Sets an alternate drag root element. The root element is the element that will be moved as
         * the user is dragging. Passing an alternate root element is useful when trying to enable
         * dragging on an element that you might not have access to.
         */
        DragRef.prototype.withRootElement = function (rootElement) {
            var _this = this;
            var element = coercion.coerceElement(rootElement);
            if (element !== this._rootElement) {
                if (this._rootElement) {
                    this._removeRootElementListeners(this._rootElement);
                }
                this._ngZone.runOutsideAngular(function () {
                    element.addEventListener('mousedown', _this._pointerDown, activeEventListenerOptions);
                    element.addEventListener('touchstart', _this._pointerDown, passiveEventListenerOptions);
                });
                this._initialTransform = undefined;
                this._rootElement = element;
            }
            if (typeof SVGElement !== 'undefined' && this._rootElement instanceof SVGElement) {
                this._ownerSVGElement = this._rootElement.ownerSVGElement;
            }
            return this;
        };
        /**
         * Element to which the draggable's position will be constrained.
         */
        DragRef.prototype.withBoundaryElement = function (boundaryElement) {
            var _this = this;
            this._boundaryElement = boundaryElement ? coercion.coerceElement(boundaryElement) : null;
            this._resizeSubscription.unsubscribe();
            if (boundaryElement) {
                this._resizeSubscription = this._viewportRuler
                    .change(10)
                    .subscribe(function () { return _this._containInsideBoundaryOnResize(); });
            }
            return this;
        };
        /** Sets the parent ref that the ref is nested in.  */
        DragRef.prototype.withParent = function (parent) {
            this._parentDragRef = parent;
            return this;
        };
        /** Removes the dragging functionality from the DOM element. */
        DragRef.prototype.dispose = function () {
            this._removeRootElementListeners(this._rootElement);
            // Do this check before removing from the registry since it'll
            // stop being considered as dragged once it is removed.
            if (this.isDragging()) {
                // Since we move out the element to the end of the body while it's being
                // dragged, we have to make sure that it's removed if it gets destroyed.
                removeNode(this._rootElement);
            }
            removeNode(this._anchor);
            this._destroyPreview();
            this._destroyPlaceholder();
            this._dragDropRegistry.removeDragItem(this);
            this._removeSubscriptions();
            this.beforeStarted.complete();
            this.started.complete();
            this.released.complete();
            this.ended.complete();
            this.entered.complete();
            this.exited.complete();
            this.dropped.complete();
            this._moveEvents.complete();
            this._handles = [];
            this._disabledHandles.clear();
            this._dropContainer = undefined;
            this._resizeSubscription.unsubscribe();
            this._parentPositions.clear();
            this._boundaryElement = this._rootElement = this._ownerSVGElement = this._placeholderTemplate =
                this._previewTemplate = this._anchor = this._parentDragRef = null;
        };
        /** Checks whether the element is currently being dragged. */
        DragRef.prototype.isDragging = function () {
            return this._hasStartedDragging && this._dragDropRegistry.isDragging(this);
        };
        /** Resets a standalone drag item to its initial position. */
        DragRef.prototype.reset = function () {
            this._rootElement.style.transform = this._initialTransform || '';
            this._activeTransform = { x: 0, y: 0 };
            this._passiveTransform = { x: 0, y: 0 };
        };
        /**
         * Sets a handle as disabled. While a handle is disabled, it'll capture and interrupt dragging.
         * @param handle Handle element that should be disabled.
         */
        DragRef.prototype.disableHandle = function (handle) {
            if (!this._disabledHandles.has(handle) && this._handles.indexOf(handle) > -1) {
                this._disabledHandles.add(handle);
                toggleNativeDragInteractions(handle, true);
            }
        };
        /**
         * Enables a handle, if it has been disabled.
         * @param handle Handle element to be enabled.
         */
        DragRef.prototype.enableHandle = function (handle) {
            if (this._disabledHandles.has(handle)) {
                this._disabledHandles.delete(handle);
                toggleNativeDragInteractions(handle, this.disabled);
            }
        };
        /** Sets the layout direction of the draggable item. */
        DragRef.prototype.withDirection = function (direction) {
            this._direction = direction;
            return this;
        };
        /** Sets the container that the item is part of. */
        DragRef.prototype._withDropContainer = function (container) {
            this._dropContainer = container;
        };
        /**
         * Gets the current position in pixels the draggable outside of a drop container.
         */
        DragRef.prototype.getFreeDragPosition = function () {
            var position = this.isDragging() ? this._activeTransform : this._passiveTransform;
            return { x: position.x, y: position.y };
        };
        /**
         * Sets the current position in pixels the draggable outside of a drop container.
         * @param value New position to be set.
         */
        DragRef.prototype.setFreeDragPosition = function (value) {
            this._activeTransform = { x: 0, y: 0 };
            this._passiveTransform.x = value.x;
            this._passiveTransform.y = value.y;
            if (!this._dropContainer) {
                this._applyRootElementTransform(value.x, value.y);
            }
            return this;
        };
        /** Updates the item's sort order based on the last-known pointer position. */
        DragRef.prototype._sortFromLastPointerPosition = function () {
            var position = this._lastKnownPointerPosition;
            if (position && this._dropContainer) {
                this._updateActiveDropContainer(this._getConstrainedPointerPosition(position), position);
            }
        };
        /** Unsubscribes from the global subscriptions. */
        DragRef.prototype._removeSubscriptions = function () {
            this._pointerMoveSubscription.unsubscribe();
            this._pointerUpSubscription.unsubscribe();
            this._scrollSubscription.unsubscribe();
        };
        /** Destroys the preview element and its ViewRef. */
        DragRef.prototype._destroyPreview = function () {
            if (this._preview) {
                removeNode(this._preview);
            }
            if (this._previewRef) {
                this._previewRef.destroy();
            }
            this._preview = this._previewRef = null;
        };
        /** Destroys the placeholder element and its ViewRef. */
        DragRef.prototype._destroyPlaceholder = function () {
            if (this._placeholder) {
                removeNode(this._placeholder);
            }
            if (this._placeholderRef) {
                this._placeholderRef.destroy();
            }
            this._placeholder = this._placeholderRef = null;
        };
        /**
         * Clears subscriptions and stops the dragging sequence.
         * @param event Browser event object that ended the sequence.
         */
        DragRef.prototype._endDragSequence = function (event) {
            var _this = this;
            // Note that here we use `isDragging` from the service, rather than from `this`.
            // The difference is that the one from the service reflects whether a dragging sequence
            // has been initiated, whereas the one on `this` includes whether the user has passed
            // the minimum dragging threshold.
            if (!this._dragDropRegistry.isDragging(this)) {
                return;
            }
            this._removeSubscriptions();
            this._dragDropRegistry.stopDragging(this);
            this._toggleNativeDragInteractions();
            if (this._handles) {
                this._rootElement.style.webkitTapHighlightColor = this._rootElementTapHighlight;
            }
            if (!this._hasStartedDragging) {
                return;
            }
            this.released.next({ source: this });
            if (this._dropContainer) {
                // Stop scrolling immediately, instead of waiting for the animation to finish.
                this._dropContainer._stopScrolling();
                this._animatePreviewToPlaceholder().then(function () {
                    _this._cleanupDragArtifacts(event);
                    _this._cleanupCachedDimensions();
                    _this._dragDropRegistry.stopDragging(_this);
                });
            }
            else {
                // Convert the active transform into a passive one. This means that next time
                // the user starts dragging the item, its position will be calculated relatively
                // to the new passive transform.
                this._passiveTransform.x = this._activeTransform.x;
                this._passiveTransform.y = this._activeTransform.y;
                this._ngZone.run(function () {
                    _this.ended.next({
                        source: _this,
                        distance: _this._getDragDistance(_this._getPointerPositionOnPage(event))
                    });
                });
                this._cleanupCachedDimensions();
                this._dragDropRegistry.stopDragging(this);
            }
        };
        /** Starts the dragging sequence. */
        DragRef.prototype._startDragSequence = function (event) {
            if (isTouchEvent(event)) {
                this._lastTouchEventTime = Date.now();
            }
            this._toggleNativeDragInteractions();
            var dropContainer = this._dropContainer;
            if (dropContainer) {
                var element = this._rootElement;
                var parent = element.parentNode;
                var preview = this._preview = this._createPreviewElement();
                var placeholder = this._placeholder = this._createPlaceholderElement();
                var anchor = this._anchor = this._anchor || this._document.createComment('');
                // Needs to happen before the root element is moved.
                var shadowRoot = this._getShadowRoot();
                // Insert an anchor node so that we can restore the element's position in the DOM.
                parent.insertBefore(anchor, element);
                // We move the element out at the end of the body and we make it hidden, because keeping it in
                // place will throw off the consumer's `:last-child` selectors. We can't remove the element
                // from the DOM completely, because iOS will stop firing all subsequent events in the chain.
                toggleVisibility(element, false);
                this._document.body.appendChild(parent.replaceChild(placeholder, element));
                getPreviewInsertionPoint(this._document, shadowRoot).appendChild(preview);
                this.started.next({ source: this }); // Emit before notifying the container.
                dropContainer.start();
                this._initialContainer = dropContainer;
                this._initialIndex = dropContainer.getItemIndex(this);
            }
            else {
                this.started.next({ source: this });
                this._initialContainer = this._initialIndex = undefined;
            }
            // Important to run after we've called `start` on the parent container
            // so that it has had time to resolve its scrollable parents.
            this._parentPositions.cache(dropContainer ? dropContainer.getScrollableParents() : []);
        };
        /**
         * Sets up the different variables and subscriptions
         * that will be necessary for the dragging sequence.
         * @param referenceElement Element that started the drag sequence.
         * @param event Browser event object that started the sequence.
         */
        DragRef.prototype._initializeDragSequence = function (referenceElement, event) {
            var _this = this;
            // Stop propagation if the item is inside another
            // draggable so we don't start multiple drag sequences.
            if (this._parentDragRef) {
                event.stopPropagation();
            }
            var isDragging = this.isDragging();
            var isTouchSequence = isTouchEvent(event);
            var isAuxiliaryMouseButton = !isTouchSequence && event.button !== 0;
            var rootElement = this._rootElement;
            var isSyntheticEvent = !isTouchSequence && this._lastTouchEventTime &&
                this._lastTouchEventTime + MOUSE_EVENT_IGNORE_TIME > Date.now();
            // If the event started from an element with the native HTML drag&drop, it'll interfere
            // with our own dragging (e.g. `img` tags do it by default). Prevent the default action
            // to stop it from happening. Note that preventing on `dragstart` also seems to work, but
            // it's flaky and it fails if the user drags it away quickly. Also note that we only want
            // to do this for `mousedown` since doing the same for `touchstart` will stop any `click`
            // events from firing on touch devices.
            if (event.target && event.target.draggable && event.type === 'mousedown') {
                event.preventDefault();
            }
            // Abort if the user is already dragging or is using a mouse button other than the primary one.
            if (isDragging || isAuxiliaryMouseButton || isSyntheticEvent) {
                return;
            }
            // If we've got handles, we need to disable the tap highlight on the entire root element,
            // otherwise iOS will still add it, even though all the drag interactions on the handle
            // are disabled.
            if (this._handles.length) {
                this._rootElementTapHighlight = rootElement.style.webkitTapHighlightColor || '';
                rootElement.style.webkitTapHighlightColor = 'transparent';
            }
            this._hasStartedDragging = this._hasMoved = false;
            // Avoid multiple subscriptions and memory leaks when multi touch
            // (isDragging check above isn't enough because of possible temporal and/or dimensional delays)
            this._removeSubscriptions();
            this._pointerMoveSubscription = this._dragDropRegistry.pointerMove.subscribe(this._pointerMove);
            this._pointerUpSubscription = this._dragDropRegistry.pointerUp.subscribe(this._pointerUp);
            this._scrollSubscription = this._dragDropRegistry.scroll.subscribe(function (scrollEvent) {
                _this._updateOnScroll(scrollEvent);
            });
            if (this._boundaryElement) {
                this._boundaryRect = getMutableClientRect(this._boundaryElement);
            }
            // If we have a custom preview we can't know ahead of time how large it'll be so we position
            // it next to the cursor. The exception is when the consumer has opted into making the preview
            // the same size as the root element, in which case we do know the size.
            var previewTemplate = this._previewTemplate;
            this._pickupPositionInElement = previewTemplate && previewTemplate.template &&
                !previewTemplate.matchSize ? { x: 0, y: 0 } :
                this._getPointerPositionInElement(referenceElement, event);
            var pointerPosition = this._pickupPositionOnPage = this._lastKnownPointerPosition =
                this._getPointerPositionOnPage(event);
            this._pointerDirectionDelta = { x: 0, y: 0 };
            this._pointerPositionAtLastDirectionChange = { x: pointerPosition.x, y: pointerPosition.y };
            this._dragStartTime = Date.now();
            this._dragDropRegistry.startDragging(this, event);
        };
        /** Cleans up the DOM artifacts that were added to facilitate the element being dragged. */
        DragRef.prototype._cleanupDragArtifacts = function (event) {
            var _this = this;
            // Restore the element's visibility and insert it at its old position in the DOM.
            // It's important that we maintain the position, because moving the element around in the DOM
            // can throw off `NgFor` which does smart diffing and re-creates elements only when necessary,
            // while moving the existing elements in all other cases.
            toggleVisibility(this._rootElement, true);
            this._anchor.parentNode.replaceChild(this._rootElement, this._anchor);
            this._destroyPreview();
            this._destroyPlaceholder();
            this._boundaryRect = this._previewRect = undefined;
            // Re-enter the NgZone since we bound `document` events on the outside.
            this._ngZone.run(function () {
                var container = _this._dropContainer;
                var currentIndex = container.getItemIndex(_this);
                var pointerPosition = _this._getPointerPositionOnPage(event);
                var distance = _this._getDragDistance(_this._getPointerPositionOnPage(event));
                var isPointerOverContainer = container._isOverContainer(pointerPosition.x, pointerPosition.y);
                _this.ended.next({ source: _this, distance: distance });
                _this.dropped.next({
                    item: _this,
                    currentIndex: currentIndex,
                    previousIndex: _this._initialIndex,
                    container: container,
                    previousContainer: _this._initialContainer,
                    isPointerOverContainer: isPointerOverContainer,
                    distance: distance
                });
                container.drop(_this, currentIndex, _this._initialIndex, _this._initialContainer, isPointerOverContainer, distance);
                _this._dropContainer = _this._initialContainer;
            });
        };
        /**
         * Updates the item's position in its drop container, or moves it
         * into a new one, depending on its current drag position.
         */
        DragRef.prototype._updateActiveDropContainer = function (_a, _b) {
            var _this = this;
            var x = _a.x, y = _a.y;
            var rawX = _b.x, rawY = _b.y;
            // Drop container that draggable has been moved into.
            var newContainer = this._initialContainer._getSiblingContainerFromPosition(this, x, y);
            // If we couldn't find a new container to move the item into, and the item has left its
            // initial container, check whether the it's over the initial container. This handles the
            // case where two containers are connected one way and the user tries to undo dragging an
            // item into a new container.
            if (!newContainer && this._dropContainer !== this._initialContainer &&
                this._initialContainer._isOverContainer(x, y)) {
                newContainer = this._initialContainer;
            }
            if (newContainer && newContainer !== this._dropContainer) {
                this._ngZone.run(function () {
                    // Notify the old container that the item has left.
                    _this.exited.next({ item: _this, container: _this._dropContainer });
                    _this._dropContainer.exit(_this);
                    // Notify the new container that the item has entered.
                    _this._dropContainer = newContainer;
                    _this._dropContainer.enter(_this, x, y, newContainer === _this._initialContainer &&
                        // If we're re-entering the initial container and sorting is disabled,
                        // put item the into its starting index to begin with.
                        newContainer.sortingDisabled ? _this._initialIndex : undefined);
                    _this.entered.next({
                        item: _this,
                        container: newContainer,
                        currentIndex: newContainer.getItemIndex(_this)
                    });
                });
            }
            this._dropContainer._startScrollingIfNecessary(rawX, rawY);
            this._dropContainer._sortItem(this, x, y, this._pointerDirectionDelta);
            this._preview.style.transform =
                getTransform(x - this._pickupPositionInElement.x, y - this._pickupPositionInElement.y);
        };
        /**
         * Creates the element that will be rendered next to the user's pointer
         * and will be used as a preview of the element that is being dragged.
         */
        DragRef.prototype._createPreviewElement = function () {
            var previewConfig = this._previewTemplate;
            var previewClass = this.previewClass;
            var previewTemplate = previewConfig ? previewConfig.template : null;
            var preview;
            if (previewTemplate && previewConfig) {
                // Measure the element before we've inserted the preview
                // since the insertion could throw off the measurement.
                var rootRect = previewConfig.matchSize ? this._rootElement.getBoundingClientRect() : null;
                var viewRef = previewConfig.viewContainer.createEmbeddedView(previewTemplate, previewConfig.context);
                viewRef.detectChanges();
                preview = getRootNode(viewRef, this._document);
                this._previewRef = viewRef;
                if (previewConfig.matchSize) {
                    matchElementSize(preview, rootRect);
                }
                else {
                    preview.style.transform =
                        getTransform(this._pickupPositionOnPage.x, this._pickupPositionOnPage.y);
                }
            }
            else {
                var element = this._rootElement;
                preview = deepCloneNode(element);
                matchElementSize(preview, element.getBoundingClientRect());
            }
            extendStyles(preview.style, {
                // It's important that we disable the pointer events on the preview, because
                // it can throw off the `document.elementFromPoint` calls in the `CdkDropList`.
                pointerEvents: 'none',
                // We have to reset the margin, because it can throw off positioning relative to the viewport.
                margin: '0',
                position: 'fixed',
                top: '0',
                left: '0',
                zIndex: "" + (this._config.zIndex || 1000)
            });
            toggleNativeDragInteractions(preview, false);
            preview.classList.add('cdk-drag-preview');
            preview.setAttribute('dir', this._direction);
            if (previewClass) {
                if (Array.isArray(previewClass)) {
                    previewClass.forEach(function (className) { return preview.classList.add(className); });
                }
                else {
                    preview.classList.add(previewClass);
                }
            }
            return preview;
        };
        /**
         * Animates the preview element from its current position to the location of the drop placeholder.
         * @returns Promise that resolves when the animation completes.
         */
        DragRef.prototype._animatePreviewToPlaceholder = function () {
            var _this = this;
            // If the user hasn't moved yet, the transitionend event won't fire.
            if (!this._hasMoved) {
                return Promise.resolve();
            }
            var placeholderRect = this._placeholder.getBoundingClientRect();
            // Apply the class that adds a transition to the preview.
            this._preview.classList.add('cdk-drag-animating');
            // Move the preview to the placeholder position.
            this._preview.style.transform = getTransform(placeholderRect.left, placeholderRect.top);
            // If the element doesn't have a `transition`, the `transitionend` event won't fire. Since
            // we need to trigger a style recalculation in order for the `cdk-drag-animating` class to
            // apply its style, we take advantage of the available info to figure out whether we need to
            // bind the event in the first place.
            var duration = getTransformTransitionDurationInMs(this._preview);
            if (duration === 0) {
                return Promise.resolve();
            }
            return this._ngZone.runOutsideAngular(function () {
                return new Promise(function (resolve) {
                    var handler = (function (event) {
                        if (!event || (event.target === _this._preview && event.propertyName === 'transform')) {
                            _this._preview.removeEventListener('transitionend', handler);
                            resolve();
                            clearTimeout(timeout);
                        }
                    });
                    // If a transition is short enough, the browser might not fire the `transitionend` event.
                    // Since we know how long it's supposed to take, add a timeout with a 50% buffer that'll
                    // fire if the transition hasn't completed when it was supposed to.
                    var timeout = setTimeout(handler, duration * 1.5);
                    _this._preview.addEventListener('transitionend', handler);
                });
            });
        };
        /** Creates an element that will be shown instead of the current element while dragging. */
        DragRef.prototype._createPlaceholderElement = function () {
            var placeholderConfig = this._placeholderTemplate;
            var placeholderTemplate = placeholderConfig ? placeholderConfig.template : null;
            var placeholder;
            if (placeholderTemplate) {
                this._placeholderRef = placeholderConfig.viewContainer.createEmbeddedView(placeholderTemplate, placeholderConfig.context);
                this._placeholderRef.detectChanges();
                placeholder = getRootNode(this._placeholderRef, this._document);
            }
            else {
                placeholder = deepCloneNode(this._rootElement);
            }
            placeholder.classList.add('cdk-drag-placeholder');
            return placeholder;
        };
        /**
         * Figures out the coordinates at which an element was picked up.
         * @param referenceElement Element that initiated the dragging.
         * @param event Event that initiated the dragging.
         */
        DragRef.prototype._getPointerPositionInElement = function (referenceElement, event) {
            var elementRect = this._rootElement.getBoundingClientRect();
            var handleElement = referenceElement === this._rootElement ? null : referenceElement;
            var referenceRect = handleElement ? handleElement.getBoundingClientRect() : elementRect;
            var point = isTouchEvent(event) ? event.targetTouches[0] : event;
            var scrollPosition = this._getViewportScrollPosition();
            var x = point.pageX - referenceRect.left - scrollPosition.left;
            var y = point.pageY - referenceRect.top - scrollPosition.top;
            return {
                x: referenceRect.left - elementRect.left + x,
                y: referenceRect.top - elementRect.top + y
            };
        };
        /** Determines the point of the page that was touched by the user. */
        DragRef.prototype._getPointerPositionOnPage = function (event) {
            var scrollPosition = this._getViewportScrollPosition();
            var point = isTouchEvent(event) ?
                // `touches` will be empty for start/end events so we have to fall back to `changedTouches`.
                // Also note that on real devices we're guaranteed for either `touches` or `changedTouches`
                // to have a value, but Firefox in device emulation mode has a bug where both can be empty
                // for `touchstart` and `touchend` so we fall back to a dummy object in order to avoid
                // throwing an error. The value returned here will be incorrect, but since this only
                // breaks inside a developer tool and the value is only used for secondary information,
                // we can get away with it. See https://bugzilla.mozilla.org/show_bug.cgi?id=1615824.
                (event.touches[0] || event.changedTouches[0] || { pageX: 0, pageY: 0 }) : event;
            var x = point.pageX - scrollPosition.left;
            var y = point.pageY - scrollPosition.top;
            // if dragging SVG element, try to convert from the screen coordinate system to the SVG
            // coordinate system
            if (this._ownerSVGElement) {
                var svgMatrix = this._ownerSVGElement.getScreenCTM();
                if (svgMatrix) {
                    var svgPoint = this._ownerSVGElement.createSVGPoint();
                    svgPoint.x = x;
                    svgPoint.y = y;
                    return svgPoint.matrixTransform(svgMatrix.inverse());
                }
            }
            return { x: x, y: y };
        };
        /** Gets the pointer position on the page, accounting for any position constraints. */
        DragRef.prototype._getConstrainedPointerPosition = function (point) {
            var dropContainerLock = this._dropContainer ? this._dropContainer.lockAxis : null;
            var _a = this.constrainPosition ? this.constrainPosition(point, this) : point, x = _a.x, y = _a.y;
            if (this.lockAxis === 'x' || dropContainerLock === 'x') {
                y = this._pickupPositionOnPage.y;
            }
            else if (this.lockAxis === 'y' || dropContainerLock === 'y') {
                x = this._pickupPositionOnPage.x;
            }
            if (this._boundaryRect) {
                var _b = this._pickupPositionInElement, pickupX = _b.x, pickupY = _b.y;
                var boundaryRect = this._boundaryRect;
                var previewRect = this._previewRect;
                var minY = boundaryRect.top + pickupY;
                var maxY = boundaryRect.bottom - (previewRect.height - pickupY);
                var minX = boundaryRect.left + pickupX;
                var maxX = boundaryRect.right - (previewRect.width - pickupX);
                x = clamp(x, minX, maxX);
                y = clamp(y, minY, maxY);
            }
            return { x: x, y: y };
        };
        /** Updates the current drag delta, based on the user's current pointer position on the page. */
        DragRef.prototype._updatePointerDirectionDelta = function (pointerPositionOnPage) {
            var x = pointerPositionOnPage.x, y = pointerPositionOnPage.y;
            var delta = this._pointerDirectionDelta;
            var positionSinceLastChange = this._pointerPositionAtLastDirectionChange;
            // Amount of pixels the user has dragged since the last time the direction changed.
            var changeX = Math.abs(x - positionSinceLastChange.x);
            var changeY = Math.abs(y - positionSinceLastChange.y);
            // Because we handle pointer events on a per-pixel basis, we don't want the delta
            // to change for every pixel, otherwise anything that depends on it can look erratic.
            // To make the delta more consistent, we track how much the user has moved since the last
            // delta change and we only update it after it has reached a certain threshold.
            if (changeX > this._config.pointerDirectionChangeThreshold) {
                delta.x = x > positionSinceLastChange.x ? 1 : -1;
                positionSinceLastChange.x = x;
            }
            if (changeY > this._config.pointerDirectionChangeThreshold) {
                delta.y = y > positionSinceLastChange.y ? 1 : -1;
                positionSinceLastChange.y = y;
            }
            return delta;
        };
        /** Toggles the native drag interactions, based on how many handles are registered. */
        DragRef.prototype._toggleNativeDragInteractions = function () {
            if (!this._rootElement || !this._handles) {
                return;
            }
            var shouldEnable = this._handles.length > 0 || !this.isDragging();
            if (shouldEnable !== this._nativeInteractionsEnabled) {
                this._nativeInteractionsEnabled = shouldEnable;
                toggleNativeDragInteractions(this._rootElement, shouldEnable);
            }
        };
        /** Removes the manually-added event listeners from the root element. */
        DragRef.prototype._removeRootElementListeners = function (element) {
            element.removeEventListener('mousedown', this._pointerDown, activeEventListenerOptions);
            element.removeEventListener('touchstart', this._pointerDown, passiveEventListenerOptions);
        };
        /**
         * Applies a `transform` to the root element, taking into account any existing transforms on it.
         * @param x New transform value along the X axis.
         * @param y New transform value along the Y axis.
         */
        DragRef.prototype._applyRootElementTransform = function (x, y) {
            var transform = getTransform(x, y);
            // Cache the previous transform amount only after the first drag sequence, because
            // we don't want our own transforms to stack on top of each other.
            if (this._initialTransform == null) {
                this._initialTransform = this._rootElement.style.transform || '';
            }
            // Preserve the previous `transform` value, if there was one. Note that we apply our own
            // transform before the user's, because things like rotation can affect which direction
            // the element will be translated towards.
            this._rootElement.style.transform = this._initialTransform ?
                transform + ' ' + this._initialTransform : transform;
        };
        /**
         * Gets the distance that the user has dragged during the current drag sequence.
         * @param currentPosition Current position of the user's pointer.
         */
        DragRef.prototype._getDragDistance = function (currentPosition) {
            var pickupPosition = this._pickupPositionOnPage;
            if (pickupPosition) {
                return { x: currentPosition.x - pickupPosition.x, y: currentPosition.y - pickupPosition.y };
            }
            return { x: 0, y: 0 };
        };
        /** Cleans up any cached element dimensions that we don't need after dragging has stopped. */
        DragRef.prototype._cleanupCachedDimensions = function () {
            this._boundaryRect = this._previewRect = undefined;
            this._parentPositions.clear();
        };
        /**
         * Checks whether the element is still inside its boundary after the viewport has been resized.
         * If not, the position is adjusted so that the element fits again.
         */
        DragRef.prototype._containInsideBoundaryOnResize = function () {
            var _a = this._passiveTransform, x = _a.x, y = _a.y;
            if ((x === 0 && y === 0) || this.isDragging() || !this._boundaryElement) {
                return;
            }
            var boundaryRect = this._boundaryElement.getBoundingClientRect();
            var elementRect = this._rootElement.getBoundingClientRect();
            // It's possible that the element got hidden away after dragging (e.g. by switching to a
            // different tab). Don't do anything in this case so we don't clear the user's position.
            if ((boundaryRect.width === 0 && boundaryRect.height === 0) ||
                (elementRect.width === 0 && elementRect.height === 0)) {
                return;
            }
            var leftOverflow = boundaryRect.left - elementRect.left;
            var rightOverflow = elementRect.right - boundaryRect.right;
            var topOverflow = boundaryRect.top - elementRect.top;
            var bottomOverflow = elementRect.bottom - boundaryRect.bottom;
            // If the element has become wider than the boundary, we can't
            // do much to make it fit so we just anchor it to the left.
            if (boundaryRect.width > elementRect.width) {
                if (leftOverflow > 0) {
                    x += leftOverflow;
                }
                if (rightOverflow > 0) {
                    x -= rightOverflow;
                }
            }
            else {
                x = 0;
            }
            // If the element has become taller than the boundary, we can't
            // do much to make it fit so we just anchor it to the top.
            if (boundaryRect.height > elementRect.height) {
                if (topOverflow > 0) {
                    y += topOverflow;
                }
                if (bottomOverflow > 0) {
                    y -= bottomOverflow;
                }
            }
            else {
                y = 0;
            }
            if (x !== this._passiveTransform.x || y !== this._passiveTransform.y) {
                this.setFreeDragPosition({ y: y, x: x });
            }
        };
        /** Gets the drag start delay, based on the event type. */
        DragRef.prototype._getDragStartDelay = function (event) {
            var value = this.dragStartDelay;
            if (typeof value === 'number') {
                return value;
            }
            else if (isTouchEvent(event)) {
                return value.touch;
            }
            return value ? value.mouse : 0;
        };
        /** Updates the internal state of the draggable element when scrolling has occurred. */
        DragRef.prototype._updateOnScroll = function (event) {
            var scrollDifference = this._parentPositions.handleScroll(event);
            if (scrollDifference) {
                var target = event.target;
                // ClientRect dimensions are based on the scroll position of the page and its parent node so
                // we have to update the cached boundary ClientRect if the user has scrolled. Check for
                // the `document` specifically since IE doesn't support `contains` on it.
                if (this._boundaryRect && (target === this._document ||
                    (target !== this._boundaryElement && target.contains(this._boundaryElement)))) {
                    adjustClientRect(this._boundaryRect, scrollDifference.top, scrollDifference.left);
                }
                this._pickupPositionOnPage.x += scrollDifference.left;
                this._pickupPositionOnPage.y += scrollDifference.top;
                // If we're in free drag mode, we have to update the active transform, because
                // it isn't relative to the viewport like the preview inside a drop list.
                if (!this._dropContainer) {
                    this._activeTransform.x -= scrollDifference.left;
                    this._activeTransform.y -= scrollDifference.top;
                    this._applyRootElementTransform(this._activeTransform.x, this._activeTransform.y);
                }
            }
        };
        /** Gets the scroll position of the viewport. */
        DragRef.prototype._getViewportScrollPosition = function () {
            var cachedPosition = this._parentPositions.positions.get(this._document);
            return cachedPosition ? cachedPosition.scrollPosition :
                this._viewportRuler.getViewportScrollPosition();
        };
        /**
         * Lazily resolves and returns the shadow root of the element. We do this in a function, rather
         * than saving it in property directly on init, because we want to resolve it as late as possible
         * in order to ensure that the element has been moved into the shadow DOM. Doing it inside the
         * constructor might be too early if the element is inside of something like `ngFor` or `ngIf`.
         */
        DragRef.prototype._getShadowRoot = function () {
            if (this._cachedShadowRoot === undefined) {
                this._cachedShadowRoot = platform._getShadowRoot(this._rootElement);
            }
            return this._cachedShadowRoot;
        };
        return DragRef;
    }());
    /**
     * Gets a 3d `transform` that can be applied to an element.
     * @param x Desired position of the element along the X axis.
     * @param y Desired position of the element along the Y axis.
     */
    function getTransform(x, y) {
        // Round the transforms since some browsers will
        // blur the elements for sub-pixel transforms.
        return "translate3d(" + Math.round(x) + "px, " + Math.round(y) + "px, 0)";
    }
    /** Clamps a value between a minimum and a maximum. */
    function clamp(value, min, max) {
        return Math.max(min, Math.min(max, value));
    }
    /**
     * Helper to remove a node from the DOM and to do all the necessary null checks.
     * @param node Node to be removed.
     */
    function removeNode(node) {
        if (node && node.parentNode) {
            node.parentNode.removeChild(node);
        }
    }
    /** Determines whether an event is a touch event. */
    function isTouchEvent(event) {
        // This function is called for every pixel that the user has dragged so we need it to be
        // as fast as possible. Since we only bind mouse events and touch events, we can assume
        // that if the event's name starts with `t`, it's a touch event.
        return event.type[0] === 't';
    }
    /** Gets the element into which the drag preview should be inserted. */
    function getPreviewInsertionPoint(documentRef, shadowRoot) {
        // We can't use the body if the user is in fullscreen mode,
        // because the preview will render under the fullscreen element.
        // TODO(crisbeto): dedupe this with the `FullscreenOverlayContainer` eventually.
        return shadowRoot ||
            documentRef.fullscreenElement ||
            documentRef.webkitFullscreenElement ||
            documentRef.mozFullScreenElement ||
            documentRef.msFullscreenElement ||
            documentRef.body;
    }
    /**
     * Gets the root HTML element of an embedded view.
     * If the root is not an HTML element it gets wrapped in one.
     */
    function getRootNode(viewRef, _document) {
        var rootNodes = viewRef.rootNodes;
        if (rootNodes.length === 1 && rootNodes[0].nodeType === _document.ELEMENT_NODE) {
            return rootNodes[0];
        }
        var wrapper = _document.createElement('div');
        rootNodes.forEach(function (node) { return wrapper.appendChild(node); });
        return wrapper;
    }
    /**
     * Matches the target element's size to the source's size.
     * @param target Element that needs to be resized.
     * @param sourceRect Dimensions of the source element.
     */
    function matchElementSize(target, sourceRect) {
        target.style.width = sourceRect.width + "px";
        target.style.height = sourceRect.height + "px";
        target.style.transform = getTransform(sourceRect.left, sourceRect.top);
    }

    /*! *****************************************************************************
    Copyright (c) Microsoft Corporation.

    Permission to use, copy, modify, and/or distribute this software for any
    purpose with or without fee is hereby granted.

    THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
    REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
    AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
    INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
    LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
    OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
    PERFORMANCE OF THIS SOFTWARE.
    ***************************************************************************** */
    /* global Reflect, Promise */
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b)
                if (Object.prototype.hasOwnProperty.call(b, p))
                    d[p] = b[p]; };
        return extendStatics(d, b);
    };
    function __extends(d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    }
    var __assign = function () {
        __assign = Object.assign || function __assign(t) {
            for (var s, i = 1, n = arguments.length; i < n; i++) {
                s = arguments[i];
                for (var p in s)
                    if (Object.prototype.hasOwnProperty.call(s, p))
                        t[p] = s[p];
            }
            return t;
        };
        return __assign.apply(this, arguments);
    };
    function __rest(s, e) {
        var t = {};
        for (var p in s)
            if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
                t[p] = s[p];
        if (s != null && typeof Object.getOwnPropertySymbols === "function")
            for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
                if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                    t[p[i]] = s[p[i]];
            }
        return t;
    }
    function __decorate(decorators, target, key, desc) {
        var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
        if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
            r = Reflect.decorate(decorators, target, key, desc);
        else
            for (var i = decorators.length - 1; i >= 0; i--)
                if (d = decorators[i])
                    r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
        return c > 3 && r && Object.defineProperty(target, key, r), r;
    }
    function __param(paramIndex, decorator) {
        return function (target, key) { decorator(target, key, paramIndex); };
    }
    function __metadata(metadataKey, metadataValue) {
        if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
            return Reflect.metadata(metadataKey, metadataValue);
    }
    function __awaiter(thisArg, _arguments, P, generator) {
        function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
        return new (P || (P = Promise))(function (resolve, reject) {
            function fulfilled(value) { try {
                step(generator.next(value));
            }
            catch (e) {
                reject(e);
            } }
            function rejected(value) { try {
                step(generator["throw"](value));
            }
            catch (e) {
                reject(e);
            } }
            function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
            step((generator = generator.apply(thisArg, _arguments || [])).next());
        });
    }
    function __generator(thisArg, body) {
        var _ = { label: 0, sent: function () { if (t[0] & 1)
                throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
        return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g;
        function verb(n) { return function (v) { return step([n, v]); }; }
        function step(op) {
            if (f)
                throw new TypeError("Generator is already executing.");
            while (_)
                try {
                    if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done)
                        return t;
                    if (y = 0, t)
                        op = [op[0] & 2, t.value];
                    switch (op[0]) {
                        case 0:
                        case 1:
                            t = op;
                            break;
                        case 4:
                            _.label++;
                            return { value: op[1], done: false };
                        case 5:
                            _.label++;
                            y = op[1];
                            op = [0];
                            continue;
                        case 7:
                            op = _.ops.pop();
                            _.trys.pop();
                            continue;
                        default:
                            if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
                                _ = 0;
                                continue;
                            }
                            if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) {
                                _.label = op[1];
                                break;
                            }
                            if (op[0] === 6 && _.label < t[1]) {
                                _.label = t[1];
                                t = op;
                                break;
                            }
                            if (t && _.label < t[2]) {
                                _.label = t[2];
                                _.ops.push(op);
                                break;
                            }
                            if (t[2])
                                _.ops.pop();
                            _.trys.pop();
                            continue;
                    }
                    op = body.call(thisArg, _);
                }
                catch (e) {
                    op = [6, e];
                    y = 0;
                }
                finally {
                    f = t = 0;
                }
            if (op[0] & 5)
                throw op[1];
            return { value: op[0] ? op[1] : void 0, done: true };
        }
    }
    var __createBinding = Object.create ? (function (o, m, k, k2) {
        if (k2 === undefined)
            k2 = k;
        Object.defineProperty(o, k2, { enumerable: true, get: function () { return m[k]; } });
    }) : (function (o, m, k, k2) {
        if (k2 === undefined)
            k2 = k;
        o[k2] = m[k];
    });
    function __exportStar(m, o) {
        for (var p in m)
            if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p))
                __createBinding(o, m, p);
    }
    function __values(o) {
        var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
        if (m)
            return m.call(o);
        if (o && typeof o.length === "number")
            return {
                next: function () {
                    if (o && i >= o.length)
                        o = void 0;
                    return { value: o && o[i++], done: !o };
                }
            };
        throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
    }
    function __read(o, n) {
        var m = typeof Symbol === "function" && o[Symbol.iterator];
        if (!m)
            return o;
        var i = m.call(o), r, ar = [], e;
        try {
            while ((n === void 0 || n-- > 0) && !(r = i.next()).done)
                ar.push(r.value);
        }
        catch (error) {
            e = { error: error };
        }
        finally {
            try {
                if (r && !r.done && (m = i["return"]))
                    m.call(i);
            }
            finally {
                if (e)
                    throw e.error;
            }
        }
        return ar;
    }
    /** @deprecated */
    function __spread() {
        for (var ar = [], i = 0; i < arguments.length; i++)
            ar = ar.concat(__read(arguments[i]));
        return ar;
    }
    /** @deprecated */
    function __spreadArrays() {
        for (var s = 0, i = 0, il = arguments.length; i < il; i++)
            s += arguments[i].length;
        for (var r = Array(s), k = 0, i = 0; i < il; i++)
            for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
                r[k] = a[j];
        return r;
    }
    function __spreadArray(to, from) {
        for (var i = 0, il = from.length, j = to.length; i < il; i++, j++)
            to[j] = from[i];
        return to;
    }
    function __await(v) {
        return this instanceof __await ? (this.v = v, this) : new __await(v);
    }
    function __asyncGenerator(thisArg, _arguments, generator) {
        if (!Symbol.asyncIterator)
            throw new TypeError("Symbol.asyncIterator is not defined.");
        var g = generator.apply(thisArg, _arguments || []), i, q = [];
        return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
        function verb(n) { if (g[n])
            i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
        function resume(n, v) { try {
            step(g[n](v));
        }
        catch (e) {
            settle(q[0][3], e);
        } }
        function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
        function fulfill(value) { resume("next", value); }
        function reject(value) { resume("throw", value); }
        function settle(f, v) { if (f(v), q.shift(), q.length)
            resume(q[0][0], q[0][1]); }
    }
    function __asyncDelegator(o) {
        var i, p;
        return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
        function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
    }
    function __asyncValues(o) {
        if (!Symbol.asyncIterator)
            throw new TypeError("Symbol.asyncIterator is not defined.");
        var m = o[Symbol.asyncIterator], i;
        return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
        function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
        function settle(resolve, reject, d, v) { Promise.resolve(v).then(function (v) { resolve({ value: v, done: d }); }, reject); }
    }
    function __makeTemplateObject(cooked, raw) {
        if (Object.defineProperty) {
            Object.defineProperty(cooked, "raw", { value: raw });
        }
        else {
            cooked.raw = raw;
        }
        return cooked;
    }
    ;
    var __setModuleDefault = Object.create ? (function (o, v) {
        Object.defineProperty(o, "default", { enumerable: true, value: v });
    }) : function (o, v) {
        o["default"] = v;
    };
    function __importStar(mod) {
        if (mod && mod.__esModule)
            return mod;
        var result = {};
        if (mod != null)
            for (var k in mod)
                if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k))
                    __createBinding(result, mod, k);
        __setModuleDefault(result, mod);
        return result;
    }
    function __importDefault(mod) {
        return (mod && mod.__esModule) ? mod : { default: mod };
    }
    function __classPrivateFieldGet(receiver, privateMap) {
        if (!privateMap.has(receiver)) {
            throw new TypeError("attempted to get private field on non-instance");
        }
        return privateMap.get(receiver);
    }
    function __classPrivateFieldSet(receiver, privateMap, value) {
        if (!privateMap.has(receiver)) {
            throw new TypeError("attempted to set private field on non-instance");
        }
        privateMap.set(receiver, value);
        return value;
    }

    /**
     * @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.
     */
    function moveItemInArray(array, fromIndex, toIndex) {
        var from = clamp$1(fromIndex, array.length - 1);
        var to = clamp$1(toIndex, array.length - 1);
        if (from === to) {
            return;
        }
        var target = array[from];
        var delta = to < from ? -1 : 1;
        for (var 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.
     */
    function transferArrayItem(currentArray, targetArray, currentIndex, targetIndex) {
        var from = clamp$1(currentIndex, currentArray.length - 1);
        var to = clamp$1(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.
     *
     */
    function copyArrayItem(currentArray, targetArray, currentIndex, targetIndex) {
        var to = clamp$1(targetIndex, targetArray.length);
        if (currentArray.length) {
            targetArray.splice(to, 0, currentArray[currentIndex]);
        }
    }
    /** Clamps a number between zero and a maximum. */
    function clamp$1(value, max) {
        return Math.max(0, Math.min(max, value));
    }

    /**
     * Proximity, as a ratio to width/height, at which a
     * dragged item will affect the drop container.
     */
    var DROP_PROXIMITY_THRESHOLD = 0.05;
    /**
     * Proximity, as a ratio to width/height at which to start auto-scrolling the drop list or the
     * viewport. The value comes from trying it out manually until it feels right.
     */
    var SCROLL_PROXIMITY_THRESHOLD = 0.05;
    /**
     * Reference to a drop list. Used to manipulate or dispose of the container.
     */
    var DropListRef = /** @class */ (function () {
        function DropListRef(element, _dragDropRegistry, _document, _ngZone, _viewportRuler) {
            var _this = this;
            this._dragDropRegistry = _dragDropRegistry;
            this._ngZone = _ngZone;
            this._viewportRuler = _viewportRuler;
            /** Whether starting a dragging sequence from this container is disabled. */
            this.disabled = false;
            /** Whether sorting items within the list is disabled. */
            this.sortingDisabled = false;
            /**
             * Whether auto-scrolling the view when the user
             * moves their pointer close to the edges is disabled.
             */
            this.autoScrollDisabled = false;
            /** Number of pixels to scroll for each frame when auto-scrolling an element. */
            this.autoScrollStep = 2;
            /**
             * Function that is used to determine whether an item
             * is allowed to be moved into a drop container.
             */
            this.enterPredicate = function () { return true; };
            /** Functions that is used to determine whether an item can be sorted into a particular index. */
            this.sortPredicate = function () { return true; };
            /** Emits right before dragging has started. */
            this.beforeStarted = new rxjs.Subject();
            /**
             * Emits when the user has moved a new drag item into this container.
             */
            this.entered = new rxjs.Subject();
            /**
             * Emits when the user removes an item from the container
             * by dragging it into another container.
             */
            this.exited = new rxjs.Subject();
            /** Emits when the user drops an item inside the container. */
            this.dropped = new rxjs.Subject();
            /** Emits as the user is swapping items while actively dragging. */
            this.sorted = new rxjs.Subject();
            /** Whether an item in the list is being dragged. */
            this._isDragging = false;
            /** Cache of the dimensions of all the items inside the container. */
            this._itemPositions = [];
            /**
             * Keeps track of the item that was last swapped with the dragged item, as well as what direction
             * the pointer was moving in when the swap occured and whether the user's pointer continued to
             * overlap with the swapped item after the swapping occurred.
             */
            this._previousSwap = { drag: null, delta: 0, overlaps: false };
            /** Draggable items in the container. */
            this._draggables = [];
            /** Drop lists that are connected to the current one. */
            this._siblings = [];
            /** Direction in which the list is oriented. */
            this._orientation = 'vertical';
            /** Connected siblings that currently have a dragged item. */
            this._activeSiblings = new Set();
            /** Layout direction of the drop list. */
            this._direction = 'ltr';
            /** Subscription to the window being scrolled. */
            this._viewportScrollSubscription = rxjs.Subscription.EMPTY;
            /** Vertical direction in which the list is currently scrolling. */
            this._verticalScrollDirection = 0 /* NONE */;
            /** Horizontal direction in which the list is currently scrolling. */
            this._horizontalScrollDirection = 0 /* NONE */;
            /** Used to signal to the current auto-scroll sequence when to stop. */
            this._stopScrollTimers = new rxjs.Subject();
            /** Shadow root of the current element. Necessary for `elementFromPoint` to resolve correctly. */
            this._cachedShadowRoot = null;
            /** Starts the interval that'll auto-scroll the element. */
            this._startScrollInterval = function () {
                _this._stopScrolling();
                rxjs.interval(0, rxjs.animationFrameScheduler)
                    .pipe(operators.takeUntil(_this._stopScrollTimers))
                    .subscribe(function () {
                    var node = _this._scrollNode;
                    var scrollStep = _this.autoScrollStep;
                    if (_this._verticalScrollDirection === 1 /* UP */) {
                        incrementVerticalScroll(node, -scrollStep);
                    }
                    else if (_this._verticalScrollDirection === 2 /* DOWN */) {
                        incrementVerticalScroll(node, scrollStep);
                    }
                    if (_this._horizontalScrollDirection === 1 /* LEFT */) {
                        incrementHorizontalScroll(node, -scrollStep);
                    }
                    else if (_this._horizontalScrollDirection === 2 /* RIGHT */) {
                        incrementHorizontalScroll(node, scrollStep);
                    }
                });
            };
            this.element = coercion.coerceElement(element);
            this._document = _document;
            this.withScrollableParents([this.element]);
            _dragDropRegistry.registerDropContainer(this);
            this._parentPositions = new ParentPositionTracker(_document, _viewportRuler);
        }
        /** Removes the drop list functionality from the DOM element. */
        DropListRef.prototype.dispose = function () {
            this._stopScrolling();
            this._stopScrollTimers.complete();
            this._viewportScrollSubscription.unsubscribe();
            this.beforeStarted.complete();
            this.entered.complete();
            this.exited.complete();
            this.dropped.complete();
            this.sorted.complete();
            this._activeSiblings.clear();
            this._scrollNode = null;
            this._parentPositions.clear();
            this._dragDropRegistry.removeDropContainer(this);
        };
        /** Whether an item from this list is currently being dragged. */
        DropListRef.prototype.isDragging = function () {
            return this._isDragging;
        };
        /** Starts dragging an item. */
        DropListRef.prototype.start = function () {
            this._draggingStarted();
            this._notifyReceivingSiblings();
        };
        /**
         * Emits an event to indicate that the user moved an item into the container.
         * @param item Item that was moved into the container.
         * @param pointerX Position of the item along the X axis.
         * @param pointerY Position of the item along the Y axis.
         * @param index Index at which the item entered. If omitted, the container will try to figure it
         *   out automatically.
         */
        DropListRef.prototype.enter = function (item, pointerX, pointerY, index) {
            this._draggingStarted();
            // If sorting is disabled, we want the item to return to its starting
            // position if the user is returning it to its initial container.
            var newIndex;
            if (index == null) {
                newIndex = this.sortingDisabled ? this._draggables.indexOf(item) : -1;
                if (newIndex === -1) {
                    // We use the coordinates of where the item entered the drop
                    // zone to figure out at which index it should be inserted.
                    newIndex = this._getItemIndexFromPointerPosition(item, pointerX, pointerY);
                }
            }
            else {
                newIndex = index;
            }
            var activeDraggables = this._activeDraggables;
            var currentIndex = activeDraggables.indexOf(item);
            var placeholder = item.getPlaceholderElement();
            var newPositionReference = activeDraggables[newIndex];
            // If the item at the new position is the same as the item that is being dragged,
            // it means that we're trying to restore the item to its initial position. In this
            // case we should use the next item from the list as the reference.
            if (newPositionReference === item) {
                newPositionReference = activeDraggables[newIndex + 1];
            }
            // Since the item may be in the `activeDraggables` already (e.g. if the user dragged it
            // into another container and back again), we have to ensure that it isn't duplicated.
            if (currentIndex > -1) {
                activeDraggables.splice(currentIndex, 1);
            }
            // Don't use items that are being dragged as a reference, because
            // their element has been moved down to the bottom of the body.
            if (newPositionReference && !this._dragDropRegistry.isDragging(newPositionReference)) {
                var element = newPositionReference.getRootElement();
                element.parentElement.insertBefore(placeholder, element);
                activeDraggables.splice(newIndex, 0, item);
            }
            else if (this._shouldEnterAsFirstChild(pointerX, pointerY)) {
                var reference = activeDraggables[0].getRootElement();
                reference.parentNode.insertBefore(placeholder, reference);
                activeDraggables.unshift(item);
            }
            else {
                coercion.coerceElement(this.element).appendChild(placeholder);
                activeDraggables.push(item);
            }
            // The transform needs to be cleared so it doesn't throw off the measurements.
            placeholder.style.transform = '';
            // Note that the positions were already cached when we called `start` above,
            // but we need to refresh them since the amount of items has changed and also parent rects.
            this._cacheItemPositions();
            this._cacheParentPositions();
            // Notify siblings at the end so that the item has been inserted into the `activeDraggables`.
            this._notifyReceivingSiblings();
            this.entered.next({ item: item, container: this, currentIndex: this.getItemIndex(item) });
        };
        /**
         * Removes an item from the container after it was dragged into another container by the user.
         * @param item Item that was dragged out.
         */
        DropListRef.prototype.exit = function (item) {
            this._reset();
            this.exited.next({ item: item, container: this });
        };
        /**
         * Drops an item into this container.
         * @param item Item being dropped into the container.
         * @param currentIndex Index at which the item should be inserted.
         * @param previousIndex Index of the item when dragging started.
         * @param previousContainer Container from which the item got dragged in.
         * @param isPointerOverContainer Whether the user's pointer was over the
         *    container when the item was dropped.
         * @param distance Distance the user has dragged since the start of the dragging sequence.
         */
        DropListRef.prototype.drop = function (item, currentIndex, previousIndex, previousContainer, isPointerOverContainer, distance) {
            this._reset();
            this.dropped.next({
                item: item,
                currentIndex: currentIndex,
                previousIndex: previousIndex,
                container: this,
                previousContainer: previousContainer,
                isPointerOverContainer: isPointerOverContainer,
                distance: distance
            });
        };
        /**
         * Sets the draggable items that are a part of this list.
         * @param items Items that are a part of this list.
         */
        DropListRef.prototype.withItems = function (items) {
            var _this = this;
            var previousItems = this._draggables;
            this._draggables = items;
            items.forEach(function (item) { return item._withDropContainer(_this); });
            if (this.isDragging()) {
                var draggedItems = previousItems.filter(function (item) { return item.isDragging(); });
                // If all of the items being dragged were removed
                // from the list, abort the current drag sequence.
                if (draggedItems.every(function (item) { return items.indexOf(item) === -1; })) {
                    this._reset();
                }
                else {
                    this._cacheItems();
                }
            }
            return this;
        };
        /** Sets the layout direction of the drop list. */
        DropListRef.prototype.withDirection = function (direction) {
            this._direction = direction;
            return this;
        };
        /**
         * Sets the containers that are connected to this one. When two or more containers are
         * connected, the user will be allowed to transfer items between them.
         * @param connectedTo Other containers that the current containers should be connected to.
         */
        DropListRef.prototype.connectedTo = function (connectedTo) {
            this._siblings = connectedTo.slice();
            return this;
        };
        /**
         * Sets the orientation of the container.
         * @param orientation New orientation for the container.
         */
        DropListRef.prototype.withOrientation = function (orientation) {
            this._orientation = orientation;
            return this;
        };
        /**
         * Sets which parent elements are can be scrolled while the user is dragging.
         * @param elements Elements that can be scrolled.
         */
        DropListRef.prototype.withScrollableParents = function (elements) {
            var element = coercion.coerceElement(this.element);
            // We always allow the current element to be scrollable
            // so we need to ensure that it's in the array.
            this._scrollableElements =
                elements.indexOf(element) === -1 ? __spread([element], elements) : elements.slice();
            return this;
        };
        /** Gets the scrollable parents that are registered with this drop container. */
        DropListRef.prototype.getScrollableParents = function () {
            return this._scrollableElements;
        };
        /**
         * Figures out the index of an item in the container.
         * @param item Item whose index should be determined.
         */
        DropListRef.prototype.getItemIndex = function (item) {
            if (!this._isDragging) {
                return this._draggables.indexOf(item);
            }
            // Items are sorted always by top/left in the cache, however they flow differently in RTL.
            // The rest of the logic still stands no matter what orientation we're in, however
            // we need to invert the array when determining the index.
            var items = this._orientation === 'horizontal' && this._direction === 'rtl' ?
                this._itemPositions.slice().reverse() : this._itemPositions;
            return findIndex(items, function (currentItem) { return currentItem.drag === item; });
        };
        /**
         * Whether the list is able to receive the item that
         * is currently being dragged inside a connected drop list.
         */
        DropListRef.prototype.isReceiving = function () {
            return this._activeSiblings.size > 0;
        };
        /**
         * Sorts an item inside the container based on its position.
         * @param item Item to be sorted.
         * @param pointerX Position of the item along the X axis.
         * @param pointerY Position of the item along the Y axis.
         * @param pointerDelta Direction in which the pointer is moving along each axis.
         */
        DropListRef.prototype._sortItem = function (item, pointerX, pointerY, pointerDelta) {
            // Don't sort the item if sorting is disabled or it's out of range.
            if (this.sortingDisabled || !this._clientRect ||
                !isPointerNearClientRect(this._clientRect, DROP_PROXIMITY_THRESHOLD, pointerX, pointerY)) {
                return;
            }
            var siblings = this._itemPositions;
            var newIndex = this._getItemIndexFromPointerPosition(item, pointerX, pointerY, pointerDelta);
            if (newIndex === -1 && siblings.length > 0) {
                return;
            }
            var isHorizontal = this._orientation === 'horizontal';
            var currentIndex = findIndex(siblings, function (currentItem) { return currentItem.drag === item; });
            var siblingAtNewPosition = siblings[newIndex];
            var currentPosition = siblings[currentIndex].clientRect;
            var newPosition = siblingAtNewPosition.clientRect;
            var delta = currentIndex > newIndex ? 1 : -1;
            // How many pixels the item's placeholder should be offset.
            var itemOffset = this._getItemOffsetPx(currentPosition, newPosition, delta);
            // How many pixels all the other items should be offset.
            var siblingOffset = this._getSiblingOffsetPx(currentIndex, siblings, delta);
            // Save the previous order of the items before moving the item to its new index.
            // We use this to check whether an item has been moved as a result of the sorting.
            var oldOrder = siblings.slice();
            // Shuffle the array in place.
            moveItemInArray(siblings, currentIndex, newIndex);
            this.sorted.next({
                previousIndex: currentIndex,
                currentIndex: newIndex,
                container: this,
                item: item
            });
            siblings.forEach(function (sibling, index) {
                // Don't do anything if the position hasn't changed.
                if (oldOrder[index] === sibling) {
                    return;
                }
                var isDraggedItem = sibling.drag === item;
                var offset = isDraggedItem ? itemOffset : siblingOffset;
                var elementToOffset = isDraggedItem ? item.getPlaceholderElement() :
                    sibling.drag.getRootElement();
                // Update the offset to reflect the new position.
                sibling.offset += offset;
                // Since we're moving the items with a `transform`, we need to adjust their cached
                // client rects to reflect their new position, as well as swap their positions in the cache.
                // Note that we shouldn't use `getBoundingClientRect` here to update the cache, because the
                // elements may be mid-animation which will give us a wrong result.
                if (isHorizontal) {
                    // Round the transforms since some browsers will
                    // blur the elements, for sub-pixel transforms.
                    elementToOffset.style.transform = "translate3d(" + Math.round(sibling.offset) + "px, 0, 0)";
                    adjustClientRect(sibling.clientRect, 0, offset);
                }
                else {
                    elementToOffset.style.transform = "translate3d(0, " + Math.round(sibling.offset) + "px, 0)";
                    adjustClientRect(sibling.clientRect, offset, 0);
                }
            });
            // Note that it's important that we do this after the client rects have been adjusted.
            this._previousSwap.overlaps = isInsideClientRect(newPosition, pointerX, pointerY);
            this._previousSwap.drag = siblingAtNewPosition.drag;
            this._previousSwap.delta = isHorizontal ? pointerDelta.x : pointerDelta.y;
        };
        /**
         * Checks whether the user's pointer is close to the edges of either the
         * viewport or the drop list and starts the auto-scroll sequence.
         * @param pointerX User's pointer position along the x axis.
         * @param pointerY User's pointer position along the y axis.
         */
        DropListRef.prototype._startScrollingIfNecessary = function (pointerX, pointerY) {
            var _this = this;
            if (this.autoScrollDisabled) {
                return;
            }
            var scrollNode;
            var verticalScrollDirection = 0 /* NONE */;
            var horizontalScrollDirection = 0 /* NONE */;
            // Check whether we should start scrolling any of the parent containers.
            this._parentPositions.positions.forEach(function (position, element) {
                var _a;
                // We have special handling for the `document` below. Also this would be
                // nicer with a  for...of loop, but it requires changing a compiler flag.
                if (element === _this._document || !position.clientRect || scrollNode) {
                    return;
                }
                if (isPointerNearClientRect(position.clientRect, DROP_PROXIMITY_THRESHOLD, pointerX, pointerY)) {
                    _a = __read(getElementScrollDirections(element, position.clientRect, pointerX, pointerY), 2), verticalScrollDirection = _a[0], horizontalScrollDirection = _a[1];
                    if (verticalScrollDirection || horizontalScrollDirection) {
                        scrollNode = element;
                    }
                }
            });
            // Otherwise check if we can start scrolling the viewport.
            if (!verticalScrollDirection && !horizontalScrollDirection) {
                var _a = this._viewportRuler.getViewportSize(), width = _a.width, height = _a.height;
                var clientRect = { width: width, height: height, top: 0, right: width, bottom: height, left: 0 };
                verticalScrollDirection = getVerticalScrollDirection(clientRect, pointerY);
                horizontalScrollDirection = getHorizontalScrollDirection(clientRect, pointerX);
                scrollNode = window;
            }
            if (scrollNode && (verticalScrollDirection !== this._verticalScrollDirection ||
                horizontalScrollDirection !== this._horizontalScrollDirection ||
                scrollNode !== this._scrollNode)) {
                this._verticalScrollDirection = verticalScrollDirection;
                this._horizontalScrollDirection = horizontalScrollDirection;
                this._scrollNode = scrollNode;
                if ((verticalScrollDirection || horizontalScrollDirection) && scrollNode) {
                    this._ngZone.runOutsideAngular(this._startScrollInterval);
                }
                else {
                    this._stopScrolling();
                }
            }
        };
        /** Stops any currently-running auto-scroll sequences. */
        DropListRef.prototype._stopScrolling = function () {
            this._stopScrollTimers.next();
        };
        /** Starts the dragging sequence within the list. */
        DropListRef.prototype._draggingStarted = function () {
            var styles = coercion.coerceElement(this.element).style;
            this.beforeStarted.next();
            this._isDragging = true;
            // We need to disable scroll snapping while the user is dragging, because it breaks automatic
            // scrolling. The browser seems to round the value based on the snapping points which means
            // that we can't increment/decrement the scroll position.
            this._initialScrollSnap = styles.msScrollSnapType || styles.scrollSnapType || '';
            styles.scrollSnapType = styles.msScrollSnapType = 'none';
            this._cacheItems();
            this._viewportScrollSubscription.unsubscribe();
            this._listenToScrollEvents();
        };
        /** Caches the positions of the configured scrollable parents. */
        DropListRef.prototype._cacheParentPositions = function () {
            var element = coercion.coerceElement(this.element);
            this._parentPositions.cache(this._scrollableElements);
            // The list element is always in the `scrollableElements`
            // so we can take advantage of the cached `ClientRect`.
            this._clientRect = this._parentPositions.positions.get(element).clientRect;
        };
        /** Refreshes the position cache of the items and sibling containers. */
        DropListRef.prototype._cacheItemPositions = function () {
            var isHorizontal = this._orientation === 'horizontal';
            this._itemPositions = this._activeDraggables.map(function (drag) {
                var elementToMeasure = drag.getVisibleElement();
                return { drag: drag, offset: 0, clientRect: getMutableClientRect(elementToMeasure) };
            }).sort(function (a, b) {
                return isHorizontal ? a.clientRect.left - b.clientRect.left :
                    a.clientRect.top - b.clientRect.top;
            });
        };
        /** Resets the container to its initial state. */
        DropListRef.prototype._reset = function () {
            var _this = this;
            this._isDragging = false;
            var styles = coercion.coerceElement(this.element).style;
            styles.scrollSnapType = styles.msScrollSnapType = this._initialScrollSnap;
            // TODO(crisbeto): may have to wait for the animations to finish.
            this._activeDraggables.forEach(function (item) {
                var rootElement = item.getRootElement();
                if (rootElement) {
                    rootElement.style.transform = '';
                }
            });
            this._siblings.forEach(function (sibling) { return sibling._stopReceiving(_this); });
            this._activeDraggables = [];
            this._itemPositions = [];
            this._previousSwap.drag = null;
            this._previousSwap.delta = 0;
            this._previousSwap.overlaps = false;
            this._stopScrolling();
            this._viewportScrollSubscription.unsubscribe();
            this._parentPositions.clear();
        };
        /**
         * Gets the offset in pixels by which the items that aren't being dragged should be moved.
         * @param currentIndex Index of the item currently being dragged.
         * @param siblings All of the items in the list.
         * @param delta Direction in which the user is moving.
         */
        DropListRef.prototype._getSiblingOffsetPx = function (currentIndex, siblings, delta) {
            var isHorizontal = this._orientation === 'horizontal';
            var currentPosition = siblings[currentIndex].clientRect;
            var immediateSibling = siblings[currentIndex + delta * -1];
            var siblingOffset = currentPosition[isHorizontal ? 'width' : 'height'] * delta;
            if (immediateSibling) {
                var start = isHorizontal ? 'left' : 'top';
                var end = isHorizontal ? 'right' : 'bottom';
                // Get the spacing between the start of the current item and the end of the one immediately
                // after it in the direction in which the user is dragging, or vice versa. We add it to the
                // offset in order to push the element to where it will be when it's inline and is influenced
                // by the `margin` of its siblings.
                if (delta === -1) {
                    siblingOffset -= immediateSibling.clientRect[start] - currentPosition[end];
                }
                else {
                    siblingOffset += currentPosition[start] - immediateSibling.clientRect[end];
                }
            }
            return siblingOffset;
        };
        /**
         * Gets the offset in pixels by which the item that is being dragged should be moved.
         * @param currentPosition Current position of the item.
         * @param newPosition Position of the item where the current item should be moved.
         * @param delta Direction in which the user is moving.
         */
        DropListRef.prototype._getItemOffsetPx = function (currentPosition, newPosition, delta) {
            var isHorizontal = this._orientation === 'horizontal';
            var itemOffset = isHorizontal ? newPosition.left - currentPosition.left :
                newPosition.top - currentPosition.top;
            // Account for differences in the item width/height.
            if (delta === -1) {
                itemOffset += isHorizontal ? newPosition.width - currentPosition.width :
                    newPosition.height - currentPosition.height;
            }
            return itemOffset;
        };
        /**
         * Checks if pointer is entering in the first position
         * @param pointerX Position of the user's pointer along the X axis.
         * @param pointerY Position of the user's pointer along the Y axis.
         */
        DropListRef.prototype._shouldEnterAsFirstChild = function (pointerX, pointerY) {
            if (!this._activeDraggables.length) {
                return false;
            }
            var itemPositions = this._itemPositions;
            var isHorizontal = this._orientation === 'horizontal';
            // `itemPositions` are sorted by position while `activeDraggables` are sorted by child index
            // check if container is using some sort of "reverse" ordering (eg: flex-direction: row-reverse)
            var reversed = itemPositions[0].drag !== this._activeDraggables[0];
            if (reversed) {
                var lastItemRect = itemPositions[itemPositions.length - 1].clientRect;
                return isHorizontal ? pointerX >= lastItemRect.right : pointerY >= lastItemRect.bottom;
            }
            else {
                var firstItemRect = itemPositions[0].clientRect;
                return isHorizontal ? pointerX <= firstItemRect.left : pointerY <= firstItemRect.top;
            }
        };
        /**
         * Gets the index of an item in the drop container, based on the position of the user's pointer.
         * @param item Item that is being sorted.
         * @param pointerX Position of the user's pointer along the X axis.
         * @param pointerY Position of the user's pointer along the Y axis.
         * @param delta Direction in which the user is moving their pointer.
         */
        DropListRef.prototype._getItemIndexFromPointerPosition = function (item, pointerX, pointerY, delta) {
            var _this = this;
            var isHorizontal = this._orientation === 'horizontal';
            var index = findIndex(this._itemPositions, function (_a, _, array) {
                var drag = _a.drag, clientRect = _a.clientRect;
                if (drag === item) {
                    // If there's only one item left in the container, it must be
                    // the dragged item itself so we use it as a reference.
                    return array.length < 2;
                }
                if (delta) {
                    var direction = isHorizontal ? delta.x : delta.y;
                    // If the user is still hovering over the same item as last time, their cursor hasn't left
                    // the item after we made the swap, and they didn't change the direction in which they're
                    // dragging, we don't consider it a direction swap.
                    if (drag === _this._previousSwap.drag && _this._previousSwap.overlaps &&
                        direction === _this._previousSwap.delta) {
                        return false;
                    }
                }
                return isHorizontal ?
                    // Round these down since most browsers report client rects with
                    // sub-pixel precision, whereas the pointer coordinates are rounded to pixels.
                    pointerX >= Math.floor(clientRect.left) && pointerX < Math.floor(clientRect.right) :
                    pointerY >= Math.floor(clientRect.top) && pointerY < Math.floor(clientRect.bottom);
            });
            return (index === -1 || !this.sortPredicate(index, item, this)) ? -1 : index;
        };
        /** Caches the current items in the list and their positions. */
        DropListRef.prototype._cacheItems = function () {
            this._activeDraggables = this._draggables.slice();
            this._cacheItemPositions();
            this._cacheParentPositions();
        };
        /**
         * Checks whether the user's pointer is positioned over the container.
         * @param x Pointer position along the X axis.
         * @param y Pointer position along the Y axis.
         */
        DropListRef.prototype._isOverContainer = function (x, y) {
            return this._clientRect != null && isInsideClientRect(this._clientRect, x, y);
        };
        /**
         * Figures out whether an item should be moved into a sibling
         * drop container, based on its current position.
         * @param item Drag item that is being moved.
         * @param x Position of the item along the X axis.
         * @param y Position of the item along the Y axis.
         */
        DropListRef.prototype._getSiblingContainerFromPosition = function (item, x, y) {
            return this._siblings.find(function (sibling) { return sibling._canReceive(item, x, y); });
        };
        /**
         * Checks whether the drop list can receive the passed-in item.
         * @param item Item that is being dragged into the list.
         * @param x Position of the item along the X axis.
         * @param y Position of the item along the Y axis.
         */
        DropListRef.prototype._canReceive = function (item, x, y) {
            if (!this._clientRect || !isInsideClientRect(this._clientRect, x, y) ||
                !this.enterPredicate(item, this)) {
                return false;
            }
            var elementFromPoint = this._getShadowRoot().elementFromPoint(x, y);
            // If there's no element at the pointer position, then
            // the client rect is probably scrolled out of the view.
            if (!elementFromPoint) {
                return false;
            }
            var nativeElement = coercion.coerceElement(this.element);
            // The `ClientRect`, that we're using to find the container over which the user is
            // hovering, doesn't give us any information on whether the element has been scrolled
            // out of the view or whether it's overlapping with other containers. This means that
            // we could end up transferring the item into a container that's invisible or is positioned
            // below another one. We use the result from `elementFromPoint` to get the top-most element
            // at the pointer position and to find whether it's one of the intersecting drop containers.
            return elementFromPoint === nativeElement || nativeElement.contains(elementFromPoint);
        };
        /**
         * Called by one of the connected drop lists when a dragging sequence has started.
         * @param sibling Sibling in which dragging has started.
         */
        DropListRef.prototype._startReceiving = function (sibling, items) {
            var _this = this;
            var activeSiblings = this._activeSiblings;
            if (!activeSiblings.has(sibling) && items.every(function (item) {
                // Note that we have to add an exception to the `enterPredicate` for items that started off
                // in this drop list. The drag ref has logic that allows an item to return to its initial
                // container, if it has left the initial container and none of the connected containers
                // allow it to enter. See `DragRef._updateActiveDropContainer` for more context.
                return _this.enterPredicate(item, _this) || _this._draggables.indexOf(item) > -1;
            })) {
                activeSiblings.add(sibling);
                this._cacheParentPositions();
                this._listenToScrollEvents();
            }
        };
        /**
         * Called by a connected drop list when dragging has stopped.
         * @param sibling Sibling whose dragging has stopped.
         */
        DropListRef.prototype._stopReceiving = function (sibling) {
            this._activeSiblings.delete(sibling);
            this._viewportScrollSubscription.unsubscribe();
        };
        /**
         * Starts listening to scroll events on the viewport.
         * Used for updating the internal state of the list.
         */
        DropListRef.prototype._listenToScrollEvents = function () {
            var _this = this;
            this._viewportScrollSubscription = this._dragDropRegistry.scroll.subscribe(function (event) {
                if (_this.isDragging()) {
                    var scrollDifference_1 = _this._parentPositions.handleScroll(event);
                    if (scrollDifference_1) {
                        // Since we know the amount that the user has scrolled we can shift all of the
                        // client rectangles ourselves. This is cheaper than re-measuring everything and
                        // we can avoid inconsistent behavior where we might be measuring the element before
                        // its position has changed.
                        _this._itemPositions.forEach(function (_a) {
                            var clientRect = _a.clientRect;
                            adjustClientRect(clientRect, scrollDifference_1.top, scrollDifference_1.left);
                        });
                        // We need two loops for this, because we want all of the cached
                        // positions to be up-to-date before we re-sort the item.
                        _this._itemPositions.forEach(function (_a) {
                            var drag = _a.drag;
                            if (_this._dragDropRegistry.isDragging(drag)) {
                                // We need to re-sort the item manually, because the pointer move
                                // events won't be dispatched while the user is scrolling.
                                drag._sortFromLastPointerPosition();
                            }
                        });
                    }
                }
                else if (_this.isReceiving()) {
                    _this._cacheParentPositions();
                }
            });
        };
        /**
         * Lazily resolves and returns the shadow root of the element. We do this in a function, rather
         * than saving it in property directly on init, because we want to resolve it as late as possible
         * in order to ensure that the element has been moved into the shadow DOM. Doing it inside the
         * constructor might be too early if the element is inside of something like `ngFor` or `ngIf`.
         */
        DropListRef.prototype._getShadowRoot = function () {
            if (!this._cachedShadowRoot) {
                var shadowRoot = platform._getShadowRoot(coercion.coerceElement(this.element));
                this._cachedShadowRoot = shadowRoot || this._document;
            }
            return this._cachedShadowRoot;
        };
        /** Notifies any siblings that may potentially receive the item. */
        DropListRef.prototype._notifyReceivingSiblings = function () {
            var _this = this;
            var draggedItems = this._activeDraggables.filter(function (item) { return item.isDragging(); });
            this._siblings.forEach(function (sibling) { return sibling._startReceiving(_this, draggedItems); });
        };
        return DropListRef;
    }());
    /**
     * Finds the index of an item that matches a predicate function. Used as an equivalent
     * of `Array.prototype.findIndex` which isn't part of the standard Google typings.
     * @param array Array in which to look for matches.
     * @param predicate Function used to determine whether an item is a match.
     */
    function findIndex(array, predicate) {
        for (var i = 0; i < array.length; i++) {
            if (predicate(array[i], i, array)) {
                return i;
            }
        }
        return -1;
    }
    /**
     * Increments the vertical scroll position of a node.
     * @param node Node whose scroll position should change.
     * @param amount Amount of pixels that the `node` should be scrolled.
     */
    function incrementVerticalScroll(node, amount) {
        if (node === window) {
            node.scrollBy(0, amount);
        }
        else {
            // Ideally we could use `Element.scrollBy` here as well, but IE and Edge don't support it.
            node.scrollTop += amount;
        }
    }
    /**
     * Increments the horizontal scroll position of a node.
     * @param node Node whose scroll position should change.
     * @param amount Amount of pixels that the `node` should be scrolled.
     */
    function incrementHorizontalScroll(node, amount) {
        if (node === window) {
            node.scrollBy(amount, 0);
        }
        else {
            // Ideally we could use `Element.scrollBy` here as well, but IE and Edge don't support it.
            node.scrollLeft += amount;
        }
    }
    /**
     * Gets whether the vertical auto-scroll direction of a node.
     * @param clientRect Dimensions of the node.
     * @param pointerY Position of the user's pointer along the y axis.
     */
    function getVerticalScrollDirection(clientRect, pointerY) {
        var top = clientRect.top, bottom = clientRect.bottom, height = clientRect.height;
        var yThreshold = height * SCROLL_PROXIMITY_THRESHOLD;
        if (pointerY >= top - yThreshold && pointerY <= top + yThreshold) {
            return 1 /* UP */;
        }
        else if (pointerY >= bottom - yThreshold && pointerY <= bottom + yThreshold) {
            return 2 /* DOWN */;
        }
        return 0 /* NONE */;
    }
    /**
     * Gets whether the horizontal auto-scroll direction of a node.
     * @param clientRect Dimensions of the node.
     * @param pointerX Position of the user's pointer along the x axis.
     */
    function getHorizontalScrollDirection(clientRect, pointerX) {
        var left = clientRect.left, right = clientRect.right, width = clientRect.width;
        var xThreshold = width * SCROLL_PROXIMITY_THRESHOLD;
        if (pointerX >= left - xThreshold && pointerX <= left + xThreshold) {
            return 1 /* LEFT */;
        }
        else if (pointerX >= right - xThreshold && pointerX <= right + xThreshold) {
            return 2 /* RIGHT */;
        }
        return 0 /* NONE */;
    }
    /**
     * Gets the directions in which an element node should be scrolled,
     * assuming that the user's pointer is already within it scrollable region.
     * @param element Element for which we should calculate the scroll direction.
     * @param clientRect Bounding client rectangle of the element.
     * @param pointerX Position of the user's pointer along the x axis.
     * @param pointerY Position of the user's pointer along the y axis.
     */
    function getElementScrollDirections(element, clientRect, pointerX, pointerY) {
        var computedVertical = getVerticalScrollDirection(clientRect, pointerY);
        var computedHorizontal = getHorizontalScrollDirection(clientRect, pointerX);
        var verticalScrollDirection = 0 /* NONE */;
        var horizontalScrollDirection = 0 /* NONE */;
        // Note that we here we do some extra checks for whether the element is actually scrollable in
        // a certain direction and we only assign the scroll direction if it is. We do this so that we
        // can allow other elements to be scrolled, if the current element can't be scrolled anymore.
        // This allows us to handle cases where the scroll regions of two scrollable elements overlap.
        if (computedVertical) {
            var scrollTop = element.scrollTop;
            if (computedVertical === 1 /* UP */) {
                if (scrollTop > 0) {
                    verticalScrollDirection = 1 /* UP */;
                }
            }
            else if (element.scrollHeight - scrollTop > element.clientHeight) {
                verticalScrollDirection = 2 /* DOWN */;
            }
        }
        if (computedHorizontal) {
            var scrollLeft = element.scrollLeft;
            if (computedHorizontal === 1 /* LEFT */) {
                if (scrollLeft > 0) {
                    horizontalScrollDirection = 1 /* LEFT */;
                }
            }
            else if (element.scrollWidth - scrollLeft > element.clientWidth) {
                horizontalScrollDirection = 2 /* RIGHT */;
            }
        }
        return [verticalScrollDirection, horizontalScrollDirection];
    }

    /**
     * @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
     */
    /** Event options that can be used to bind an active, capturing event. */
    var activeCapturingEventOptions = platform.normalizePassiveListenerOptions({
        passive: false,
        capture: true
    });
    /**
     * Service that keeps track of all the drag item and drop container
     * instances, and manages global event listeners on the `document`.
     * @docs-private
     */
    // Note: this class is generic, rather than referencing CdkDrag and CdkDropList directly, in order
    // to avoid circular imports. If we were to reference them here, importing the registry into the
    // classes that are registering themselves will introduce a circular import.
    var DragDropRegistry = /** @class */ (function () {
        function DragDropRegistry(_ngZone, _document) {
            var _this = this;
            this._ngZone = _ngZone;
            /** Registered drop container instances. */
            this._dropInstances = new Set();
            /** Registered drag item instances. */
            this._dragInstances = new Set();
            /** Drag item instances that are currently being dragged. */
            this._activeDragInstances = [];
            /** Keeps track of the event listeners that we've bound to the `document`. */
            this._globalListeners = new Map();
            /**
             * Predicate function to check if an item is being dragged.  Moved out into a property,
             * because it'll be called a lot and we don't want to create a new function every time.
             */
            this._draggingPredicate = function (item) { return item.isDragging(); };
            /**
             * Emits the `touchmove` or `mousemove` events that are dispatched
             * while the user is dragging a drag item instance.
             */
            this.pointerMove = new rxjs.Subject();
            /**
             * Emits the `touchend` or `mouseup` events that are dispatched
             * while the user is dragging a drag item instance.
             */
            this.pointerUp = new rxjs.Subject();
            /** Emits when the viewport has been scrolled while the user is dragging an item. */
            this.scroll = new rxjs.Subject();
            /**
             * Event listener that will prevent the default browser action while the user is dragging.
             * @param event Event whose default action should be prevented.
             */
            this._preventDefaultWhileDragging = function (event) {
                if (_this._activeDragInstances.length > 0) {
                    event.preventDefault();
                }
            };
            /** Event listener for `touchmove` that is bound even if no dragging is happening. */
            this._persistentTouchmoveListener = function (event) {
                if (_this._activeDragInstances.length > 0) {
                    // Note that we only want to prevent the default action after dragging has actually started.
                    // Usually this is the same time at which the item is added to the `_activeDragInstances`,
                    // but it could be pushed back if the user has set up a drag delay or threshold.
                    if (_this._activeDragInstances.some(_this._draggingPredicate)) {
                        event.preventDefault();
                    }
                    _this.pointerMove.next(event);
                }
            };
            this._document = _document;
        }
        /** Adds a drop container to the registry. */
        DragDropRegistry.prototype.registerDropContainer = function (drop) {
            if (!this._dropInstances.has(drop)) {
                this._dropInstances.add(drop);
            }
        };
        /** Adds a drag item instance to the registry. */
        DragDropRegistry.prototype.registerDragItem = function (drag) {
            var _this = this;
            this._dragInstances.add(drag);
            // The `touchmove` event gets bound once, ahead of time, because WebKit
            // won't preventDefault on a dynamically-added `touchmove` listener.
            // See https://bugs.webkit.org/show_bug.cgi?id=184250.
            if (this._dragInstances.size === 1) {
                this._ngZone.runOutsideAngular(function () {
                    // The event handler has to be explicitly active,
                    // because newer browsers make it passive by default.
                    _this._document.addEventListener('touchmove', _this._persistentTouchmoveListener, activeCapturingEventOptions);
                });
            }
        };
        /** Removes a drop container from the registry. */
        DragDropRegistry.prototype.removeDropContainer = function (drop) {
            this._dropInstances.delete(drop);
        };
        /** Removes a drag item instance from the registry. */
        DragDropRegistry.prototype.removeDragItem = function (drag) {
            this._dragInstances.delete(drag);
            this.stopDragging(drag);
            if (this._dragInstances.size === 0) {
                this._document.removeEventListener('touchmove', this._persistentTouchmoveListener, activeCapturingEventOptions);
            }
        };
        /**
         * Starts the dragging sequence for a drag instance.
         * @param drag Drag instance which is being dragged.
         * @param event Event that initiated the dragging.
         */
        DragDropRegistry.prototype.startDragging = function (drag, event) {
            var _this = this;
            // Do not process the same drag twice to avoid memory leaks and redundant listeners
            if (this._activeDragInstances.indexOf(drag) > -1) {
                return;
            }
            this._activeDragInstances.push(drag);
            if (this._activeDragInstances.length === 1) {
                var isTouchEvent = event.type.startsWith('touch');
                // We explicitly bind __active__ listeners here, because newer browsers will default to
                // passive ones for `mousemove` and `touchmove`. The events need to be active, because we
                // use `preventDefault` to prevent the page from scrolling while the user is dragging.
                this._globalListeners
                    .set(isTouchEvent ? 'touchend' : 'mouseup', {
                    handler: function (e) { return _this.pointerUp.next(e); },
                    options: true
                })
                    .set('scroll', {
                    handler: function (e) { return _this.scroll.next(e); },
                    // Use capturing so that we pick up scroll changes in any scrollable nodes that aren't
                    // the document. See https://github.com/angular/components/issues/17144.
                    options: true
                })
                    // Preventing the default action on `mousemove` isn't enough to disable text selection
                    // on Safari so we need to prevent the selection event as well. Alternatively this can
                    // be done by setting `user-select: none` on the `body`, however it has causes a style
                    // recalculation which can be expensive on pages with a lot of elements.
                    .set('selectstart', {
                    handler: this._preventDefaultWhileDragging,
                    options: activeCapturingEventOptions
                });
                // We don't have to bind a move event for touch drag sequences, because
                // we already have a persistent global one bound from `registerDragItem`.
                if (!isTouchEvent) {
                    this._globalListeners.set('mousemove', {
                        handler: function (e) { return _this.pointerMove.next(e); },
                        options: activeCapturingEventOptions
                    });
                }
                this._ngZone.runOutsideAngular(function () {
                    _this._globalListeners.forEach(function (config, name) {
                        _this._document.addEventListener(name, config.handler, config.options);
                    });
                });
            }
        };
        /** Stops dragging a drag item instance. */
        DragDropRegistry.prototype.stopDragging = function (drag) {
            var index = this._activeDragInstances.indexOf(drag);
            if (index > -1) {
                this._activeDragInstances.splice(index, 1);
                if (this._activeDragInstances.length === 0) {
                    this._clearGlobalListeners();
                }
            }
        };
        /** Gets whether a drag item instance is currently being dragged. */
        DragDropRegistry.prototype.isDragging = function (drag) {
            return this._activeDragInstances.indexOf(drag) > -1;
        };
        DragDropRegistry.prototype.ngOnDestroy = function () {
            var _this = this;
            this._dragInstances.forEach(function (instance) { return _this.removeDragItem(instance); });
            this._dropInstances.forEach(function (instance) { return _this.removeDropContainer(instance); });
            this._clearGlobalListeners();
            this.pointerMove.complete();
            this.pointerUp.complete();
        };
        /** Clears out the global event listeners from the `document`. */
        DragDropRegistry.prototype._clearGlobalListeners = function () {
            var _this = this;
            this._globalListeners.forEach(function (config, name) {
                _this._document.removeEventListener(name, config.handler, config.options);
            });
            this._globalListeners.clear();
        };
        return DragDropRegistry;
    }());
    DragDropRegistry.ɵprov = i0.ɵɵdefineInjectable({ factory: function DragDropRegistry_Factory() { return new DragDropRegistry(i0.ɵɵinject(i0.NgZone), i0.ɵɵinject(i1.DOCUMENT)); }, token: DragDropRegistry, providedIn: "root" });
    DragDropRegistry.decorators = [
        { type: i0.Injectable, args: [{ providedIn: 'root' },] }
    ];
    DragDropRegistry.ctorParameters = function () { return [
        { type: i0.NgZone },
        { type: undefined, decorators: [{ type: i0.Inject, args: [i1.DOCUMENT,] }] }
    ]; };

    /**
     * @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
     */
    /** Default configuration to be used when creating a `DragRef`. */
    var DEFAULT_CONFIG = {
        dragStartThreshold: 5,
        pointerDirectionChangeThreshold: 5
    };
    /**
     * Service that allows for drag-and-drop functionality to be attached to DOM elements.
     */
    var DragDrop = /** @class */ (function () {
        function DragDrop(_document, _ngZone, _viewportRuler, _dragDropRegistry) {
            this._document = _document;
            this._ngZone = _ngZone;
            this._viewportRuler = _viewportRuler;
            this._dragDropRegistry = _dragDropRegistry;
        }
        /**
         * Turns an element into a draggable item.
         * @param element Element to which to attach the dragging functionality.
         * @param config Object used to configure the dragging behavior.
         */
        DragDrop.prototype.createDrag = function (element, config) {
            if (config === void 0) { config = DEFAULT_CONFIG; }
            return new DragRef(element, config, this._document, this._ngZone, this._viewportRuler, this._dragDropRegistry);
        };
        /**
         * Turns an element into a drop list.
         * @param element Element to which to attach the drop list functionality.
         */
        DragDrop.prototype.createDropList = function (element) {
            return new DropListRef(element, this._dragDropRegistry, this._document, this._ngZone, this._viewportRuler);
        };
        return DragDrop;
    }());
    DragDrop.ɵprov = i0.ɵɵdefineInjectable({ factory: function DragDrop_Factory() { return new DragDrop(i0.ɵɵinject(i1.DOCUMENT), i0.ɵɵinject(i0.NgZone), i0.ɵɵinject(i2.ViewportRuler), i0.ɵɵinject(DragDropRegistry)); }, token: DragDrop, providedIn: "root" });
    DragDrop.decorators = [
        { type: i0.Injectable, args: [{ providedIn: 'root' },] }
    ];
    DragDrop.ctorParameters = function () { return [
        { type: undefined, decorators: [{ type: i0.Inject, args: [i1.DOCUMENT,] }] },
        { type: i0.NgZone },
        { type: i2.ViewportRuler },
        { type: DragDropRegistry }
    ]; };

    /**
     * @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
     */
    /**
     * Injection token that can be used for a `CdkDrag` to provide itself as a parent to the
     * drag-specific child directive (`CdkDragHandle`, `CdkDragPreview` etc.). Used primarily
     * to avoid circular imports.
     * @docs-private
     */
    var CDK_DRAG_PARENT = new i0.InjectionToken('CDK_DRAG_PARENT');

    /**
     * @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
     */
    /**
     * Injection token that can be used to reference instances of `CdkDropListGroup`. It serves as
     * alternative token to the actual `CdkDropListGroup` class which could cause unnecessary
     * retention of the class and its directive metadata.
     */
    var CDK_DROP_LIST_GROUP = new i0.InjectionToken('CdkDropListGroup');
    /**
     * Declaratively connects sibling `cdkDropList` instances together. All of the `cdkDropList`
     * elements that are placed inside a `cdkDropListGroup` will be connected to each other
     * automatically. Can be used as an alternative to the `cdkDropListConnectedTo` input
     * from `cdkDropList`.
     */
    var CdkDropListGroup = /** @class */ (function () {
        function CdkDropListGroup() {
            /** Drop lists registered inside the group. */
            this._items = new Set();
            this._disabled = false;
        }
        Object.defineProperty(CdkDropListGroup.prototype, "disabled", {
            /** Whether starting a dragging sequence from inside this group is disabled. */
            get: function () { return this._disabled; },
            set: function (value) {
                this._disabled = coercion.coerceBooleanProperty(value);
            },
            enumerable: false,
            configurable: true
        });
        CdkDropListGroup.prototype.ngOnDestroy = function () {
            this._items.clear();
        };
        return CdkDropListGroup;
    }());
    CdkDropListGroup.decorators = [
        { type: i0.Directive, args: [{
                    selector: '[cdkDropListGroup]',
                    exportAs: 'cdkDropListGroup',
                    providers: [{ provide: CDK_DROP_LIST_GROUP, useExisting: CdkDropListGroup }],
                },] }
    ];
    CdkDropListGroup.propDecorators = {
        disabled: [{ type: i0.Input, args: ['cdkDropListGroupDisabled',] }]
    };

    /**
     * @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
     */
    /**
     * Injection token that can be used to configure the
     * behavior of the drag&drop-related components.
     */
    var CDK_DRAG_CONFIG = new i0.InjectionToken('CDK_DRAG_CONFIG');

    /**
     * @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
     */
    /**
     * Asserts that a particular node is an element.
     * @param node Node to be checked.
     * @param name Name to attach to the error message.
     */
    function assertElementNode(node, name) {
        if (node.nodeType !== 1) {
            throw Error(name + " must be attached to an element node. " +
                ("Currently attached to \"" + node.nodeName + "\"."));
        }
    }

    /**
     * @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
     */
    /** Counter used to generate unique ids for drop zones. */
    var _uniqueIdCounter = 0;
    /**
     * Injection token that can be used to reference instances of `CdkDropList`. It serves as
     * alternative token to the actual `CdkDropList` class which could cause unnecessary
     * retention of the class and its directive metadata.
     */
    var CDK_DROP_LIST = new i0.InjectionToken('CdkDropList');
    var ɵ0 = undefined;
    /** Container that wraps a set of draggable items. */
    var CdkDropList = /** @class */ (function () {
        function CdkDropList(
        /** Element that the drop list is attached to. */
        element, dragDrop, _changeDetectorRef, _scrollDispatcher, _dir, _group, config) {
            var _this = this;
            this.element = element;
            this._changeDetectorRef = _changeDetectorRef;
            this._scrollDispatcher = _scrollDispatcher;
            this._dir = _dir;
            this._group = _group;
            /** Emits when the list has been destroyed. */
            this._destroyed = new rxjs.Subject();
            /**
             * Other draggable containers that this container is connected to and into which the
             * container's items can be transferred. Can either be references to other drop containers,
             * or their unique IDs.
             */
            this.connectedTo = [];
            /**
             * Unique ID for the drop zone. Can be used as a reference
             * in the `connectedTo` of another `CdkDropList`.
             */
            this.id = "cdk-drop-list-" + _uniqueIdCounter++;
            /**
             * Function that is used to determine whether an item
             * is allowed to be moved into a drop container.
             */
            this.enterPredicate = function () { return true; };
            /** Functions that is used to determine whether an item can be sorted into a particular index. */
            this.sortPredicate = function () { return true; };
            /** Emits when the user drops an item inside the container. */
            this.dropped = new i0.EventEmitter();
            /**
             * Emits when the user has moved a new drag item into this container.
             */
            this.entered = new i0.EventEmitter();
            /**
             * Emits when the user removes an item from the container
             * by dragging it into another container.
             */
            this.exited = new i0.EventEmitter();
            /** Emits as the user is swapping items while actively dragging. */
            this.sorted = new i0.EventEmitter();
            /**
             * Keeps track of the items that are registered with this container. Historically we used to
             * do this with a `ContentChildren` query, however queries don't handle transplanted views very
             * well which means that we can't handle cases like dragging the headers of a `mat-table`
             * correctly. What we do instead is to have the items register themselves with the container
             * and then we sort them based on their position in the DOM.
             */
            this._unsortedItems = new Set();
            if (typeof ngDevMode === 'undefined' || ngDevMode) {
                assertElementNode(element.nativeElement, 'cdkDropList');
            }
            this._dropListRef = dragDrop.createDropList(element);
            this._dropListRef.data = this;
            if (config) {
                this._assignDefaults(config);
            }
            this._dropListRef.enterPredicate = function (drag, drop) {
                return _this.enterPredicate(drag.data, drop.data);
            };
            this._dropListRef.sortPredicate =
                function (index, drag, drop) {
                    return _this.sortPredicate(index, drag.data, drop.data);
                };
            this._setupInputSyncSubscription(this._dropListRef);
            this._handleEvents(this._dropListRef);
            CdkDropList._dropLists.push(this);
            if (_group) {
                _group._items.add(this);
            }
        }
        Object.defineProperty(CdkDropList.prototype, "disabled", {
            /** Whether starting a dragging sequence from this container is disabled. */
            get: function () {
                return this._disabled || (!!this._group && this._group.disabled);
            },
            set: function (value) {
                // Usually we sync the directive and ref state right before dragging starts, in order to have
                // a single point of failure and to avoid having to use setters for everything. `disabled` is
                // a special case, because it can prevent the `beforeStarted` event from firing, which can lock
                // the user in a disabled state, so we also need to sync it as it's being set.
                this._dropListRef.disabled = this._disabled = coercion.coerceBooleanProperty(value);
            },
            enumerable: false,
            configurable: true
        });
        /** Registers an items with the drop list. */
        CdkDropList.prototype.addItem = function (item) {
            this._unsortedItems.add(item);
            if (this._dropListRef.isDragging()) {
                this._syncItemsWithRef();
            }
        };
        /** Removes an item from the drop list. */
        CdkDropList.prototype.removeItem = function (item) {
            this._unsortedItems.delete(item);
            if (this._dropListRef.isDragging()) {
                this._syncItemsWithRef();
            }
        };
        /** Gets the registered items in the list, sorted by their position in the DOM. */
        CdkDropList.prototype.getSortedItems = function () {
            return Array.from(this._unsortedItems).sort(function (a, b) {
                var documentPosition = a._dragRef.getVisibleElement().compareDocumentPosition(b._dragRef.getVisibleElement());
                // `compareDocumentPosition` returns a bitmask so we have to use a bitwise operator.
                // https://developer.mozilla.org/en-US/docs/Web/API/Node/compareDocumentPosition
                // tslint:disable-next-line:no-bitwise
                return documentPosition & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
            });
        };
        CdkDropList.prototype.ngOnDestroy = function () {
            var index = CdkDropList._dropLists.indexOf(this);
            if (index > -1) {
                CdkDropList._dropLists.splice(index, 1);
            }
            if (this._group) {
                this._group._items.delete(this);
            }
            this._unsortedItems.clear();
            this._dropListRef.dispose();
            this._destroyed.next();
            this._destroyed.complete();
        };
        /** Syncs the inputs of the CdkDropList with the options of the underlying DropListRef. */
        CdkDropList.prototype._setupInputSyncSubscription = function (ref) {
            var _this = this;
            if (this._dir) {
                this._dir.change
                    .pipe(operators.startWith(this._dir.value), operators.takeUntil(this._destroyed))
                    .subscribe(function (value) { return ref.withDirection(value); });
            }
            ref.beforeStarted.subscribe(function () {
                var siblings = coercion.coerceArray(_this.connectedTo).map(function (drop) {
                    if (typeof drop === 'string') {
                        var correspondingDropList = CdkDropList._dropLists.find(function (list) { return list.id === drop; });
                        if (!correspondingDropList && (typeof ngDevMode === 'undefined' || ngDevMode)) {
                            console.warn("CdkDropList could not find connected drop list with id \"" + drop + "\"");
                        }
                        return correspondingDropList;
                    }
                    return drop;
                });
                if (_this._group) {
                    _this._group._items.forEach(function (drop) {
                        if (siblings.indexOf(drop) === -1) {
                            siblings.push(drop);
                        }
                    });
                }
                // Note that we resolve the scrollable parents here so that we delay the resolution
                // as long as possible, ensuring that the element is in its final place in the DOM.
                if (!_this._scrollableParentsResolved) {
                    var scrollableParents = _this._scrollDispatcher
                        .getAncestorScrollContainers(_this.element)
                        .map(function (scrollable) { return scrollable.getElementRef().nativeElement; });
                    _this._dropListRef.withScrollableParents(scrollableParents);
                    // Only do this once since it involves traversing the DOM and the parents
                    // shouldn't be able to change without the drop list being destroyed.
                    _this._scrollableParentsResolved = true;
                }
                ref.disabled = _this.disabled;
                ref.lockAxis = _this.lockAxis;
                ref.sortingDisabled = coercion.coerceBooleanProperty(_this.sortingDisabled);
                ref.autoScrollDisabled = coercion.coerceBooleanProperty(_this.autoScrollDisabled);
                ref.autoScrollStep = coercion.coerceNumberProperty(_this.autoScrollStep, 2);
                ref
                    .connectedTo(siblings.filter(function (drop) { return drop && drop !== _this; }).map(function (list) { return list._dropListRef; }))
                    .withOrientation(_this.orientation);
            });
        };
        /** Handles events from the underlying DropListRef. */
        CdkDropList.prototype._handleEvents = function (ref) {
            var _this = this;
            ref.beforeStarted.subscribe(function () {
                _this._syncItemsWithRef();
                _this._changeDetectorRef.markForCheck();
            });
            ref.entered.subscribe(function (event) {
                _this.entered.emit({
                    container: _this,
                    item: event.item.data,
                    currentIndex: event.currentIndex
                });
            });
            ref.exited.subscribe(function (event) {
                _this.exited.emit({
                    container: _this,
                    item: event.item.data
                });
                _this._changeDetectorRef.markForCheck();
            });
            ref.sorted.subscribe(function (event) {
                _this.sorted.emit({
                    previousIndex: event.previousIndex,
                    currentIndex: event.currentIndex,
                    container: _this,
                    item: event.item.data
                });
            });
            ref.dropped.subscribe(function (event) {
                _this.dropped.emit({
                    previousIndex: event.previousIndex,
                    currentIndex: event.currentIndex,
                    previousContainer: event.previousContainer.data,
                    container: event.container.data,
                    item: event.item.data,
                    isPointerOverContainer: event.isPointerOverContainer,
                    distance: event.distance
                });
                // Mark for check since all of these events run outside of change
                // detection and we're not guaranteed for something else to have triggered it.
                _this._changeDetectorRef.markForCheck();
            });
        };
        /** Assigns the default input values based on a provided config object. */
        CdkDropList.prototype._assignDefaults = function (config) {
            var lockAxis = config.lockAxis, draggingDisabled = config.draggingDisabled, sortingDisabled = config.sortingDisabled, listAutoScrollDisabled = config.listAutoScrollDisabled, listOrientation = config.listOrientation;
            this.disabled = draggingDisabled == null ? false : draggingDisabled;
            this.sortingDisabled = sortingDisabled == null ? false : sortingDisabled;
            this.autoScrollDisabled = listAutoScrollDisabled == null ? false : listAutoScrollDisabled;
            this.orientation = listOrientation || 'vertical';
            if (lockAxis) {
                this.lockAxis = lockAxis;
            }
        };
        /** Syncs up the registered drag items with underlying drop list ref. */
        CdkDropList.prototype._syncItemsWithRef = function () {
            this._dropListRef.withItems(this.getSortedItems().map(function (item) { return item._dragRef; }));
        };
        return CdkDropList;
    }());
    /** Keeps track of the drop lists that are currently on the page. */
    CdkDropList._dropLists = [];
    CdkDropList.decorators = [
        { type: i0.Directive, args: [{
                    selector: '[cdkDropList], cdk-drop-list',
                    exportAs: 'cdkDropList',
                    providers: [
                        // Prevent child drop lists from picking up the same group as their parent.
                        { provide: CDK_DROP_LIST_GROUP, useValue: ɵ0 },
                        { provide: CDK_DROP_LIST, useExisting: CdkDropList },
                    ],
                    host: {
                        'class': 'cdk-drop-list',
                        '[attr.id]': 'id',
                        '[class.cdk-drop-list-disabled]': 'disabled',
                        '[class.cdk-drop-list-dragging]': '_dropListRef.isDragging()',
                        '[class.cdk-drop-list-receiving]': '_dropListRef.isReceiving()',
                    }
                },] }
    ];
    CdkDropList.ctorParameters = function () { return [
        { type: i0.ElementRef },
        { type: DragDrop },
        { type: i0.ChangeDetectorRef },
        { type: i2.ScrollDispatcher },
        { type: bidi.Directionality, decorators: [{ type: i0.Optional }] },
        { type: CdkDropListGroup, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [CDK_DROP_LIST_GROUP,] }, { type: i0.SkipSelf }] },
        { type: undefined, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [CDK_DRAG_CONFIG,] }] }
    ]; };
    CdkDropList.propDecorators = {
        connectedTo: [{ type: i0.Input, args: ['cdkDropListConnectedTo',] }],
        data: [{ type: i0.Input, args: ['cdkDropListData',] }],
        orientation: [{ type: i0.Input, args: ['cdkDropListOrientation',] }],
        id: [{ type: i0.Input }],
        lockAxis: [{ type: i0.Input, args: ['cdkDropListLockAxis',] }],
        disabled: [{ type: i0.Input, args: ['cdkDropListDisabled',] }],
        sortingDisabled: [{ type: i0.Input, args: ['cdkDropListSortingDisabled',] }],
        enterPredicate: [{ type: i0.Input, args: ['cdkDropListEnterPredicate',] }],
        sortPredicate: [{ type: i0.Input, args: ['cdkDropListSortPredicate',] }],
        autoScrollDisabled: [{ type: i0.Input, args: ['cdkDropListAutoScrollDisabled',] }],
        autoScrollStep: [{ type: i0.Input, args: ['cdkDropListAutoScrollStep',] }],
        dropped: [{ type: i0.Output, args: ['cdkDropListDropped',] }],
        entered: [{ type: i0.Output, args: ['cdkDropListEntered',] }],
        exited: [{ type: i0.Output, args: ['cdkDropListExited',] }],
        sorted: [{ type: i0.Output, args: ['cdkDropListSorted',] }]
    };

    /**
     * @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
     */
    /**
     * Injection token that can be used to reference instances of `CdkDragHandle`. It serves as
     * alternative token to the actual `CdkDragHandle` class which could cause unnecessary
     * retention of the class and its directive metadata.
     */
    var CDK_DRAG_HANDLE = new i0.InjectionToken('CdkDragHandle');
    /** Handle that can be used to drag a CdkDrag instance. */
    var CdkDragHandle = /** @class */ (function () {
        function CdkDragHandle(element, parentDrag) {
            this.element = element;
            /** Emits when the state of the handle has changed. */
            this._stateChanges = new rxjs.Subject();
            this._disabled = false;
            if (typeof ngDevMode === 'undefined' || ngDevMode) {
                assertElementNode(element.nativeElement, 'cdkDragHandle');
            }
            this._parentDrag = parentDrag;
        }
        Object.defineProperty(CdkDragHandle.prototype, "disabled", {
            /** Whether starting to drag through this handle is disabled. */
            get: function () { return this._disabled; },
            set: function (value) {
                this._disabled = coercion.coerceBooleanProperty(value);
                this._stateChanges.next(this);
            },
            enumerable: false,
            configurable: true
        });
        CdkDragHandle.prototype.ngOnDestroy = function () {
            this._stateChanges.complete();
        };
        return CdkDragHandle;
    }());
    CdkDragHandle.decorators = [
        { type: i0.Directive, args: [{
                    selector: '[cdkDragHandle]',
                    host: {
                        'class': 'cdk-drag-handle'
                    },
                    providers: [{ provide: CDK_DRAG_HANDLE, useExisting: CdkDragHandle }],
                },] }
    ];
    CdkDragHandle.ctorParameters = function () { return [
        { type: i0.ElementRef },
        { type: undefined, decorators: [{ type: i0.Inject, args: [CDK_DRAG_PARENT,] }, { type: i0.Optional }, { type: i0.SkipSelf }] }
    ]; };
    CdkDragHandle.propDecorators = {
        disabled: [{ type: i0.Input, args: ['cdkDragHandleDisabled',] }]
    };

    /**
     * @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
     */
    /**
     * Injection token that can be used to reference instances of `CdkDragPlaceholder`. It serves as
     * alternative token to the actual `CdkDragPlaceholder` class which could cause unnecessary
     * retention of the class and its directive metadata.
     */
    var CDK_DRAG_PLACEHOLDER = new i0.InjectionToken('CdkDragPlaceholder');
    /**
     * Element that will be used as a template for the placeholder of a CdkDrag when
     * it is being dragged. The placeholder is displayed in place of the element being dragged.
     */
    var CdkDragPlaceholder = /** @class */ (function () {
        function CdkDragPlaceholder(templateRef) {
            this.templateRef = templateRef;
        }
        return CdkDragPlaceholder;
    }());
    CdkDragPlaceholder.decorators = [
        { type: i0.Directive, args: [{
                    selector: 'ng-template[cdkDragPlaceholder]',
                    providers: [{ provide: CDK_DRAG_PLACEHOLDER, useExisting: CdkDragPlaceholder }],
                },] }
    ];
    CdkDragPlaceholder.ctorParameters = function () { return [
        { type: i0.TemplateRef }
    ]; };
    CdkDragPlaceholder.propDecorators = {
        data: [{ type: i0.Input }]
    };

    /**
     * @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
     */
    /**
     * Injection token that can be used to reference instances of `CdkDragPreview`. It serves as
     * alternative token to the actual `CdkDragPreview` class which could cause unnecessary
     * retention of the class and its directive metadata.
     */
    var CDK_DRAG_PREVIEW = new i0.InjectionToken('CdkDragPreview');
    /**
     * Element that will be used as a template for the preview
     * of a CdkDrag when it is being dragged.
     */
    var CdkDragPreview = /** @class */ (function () {
        function CdkDragPreview(templateRef) {
            this.templateRef = templateRef;
            this._matchSize = false;
        }
        Object.defineProperty(CdkDragPreview.prototype, "matchSize", {
            /** Whether the preview should preserve the same size as the item that is being dragged. */
            get: function () { return this._matchSize; },
            set: function (value) { this._matchSize = coercion.coerceBooleanProperty(value); },
            enumerable: false,
            configurable: true
        });
        return CdkDragPreview;
    }());
    CdkDragPreview.decorators = [
        { type: i0.Directive, args: [{
                    selector: 'ng-template[cdkDragPreview]',
                    providers: [{ provide: CDK_DRAG_PREVIEW, useExisting: CdkDragPreview }],
                },] }
    ];
    CdkDragPreview.ctorParameters = function () { return [
        { type: i0.TemplateRef }
    ]; };
    CdkDragPreview.propDecorators = {
        data: [{ type: i0.Input }],
        matchSize: [{ type: i0.Input }]
    };

    var DRAG_HOST_CLASS = 'cdk-drag';
    /** Element that can be moved inside a CdkDropList container. */
    var CdkDrag = /** @class */ (function () {
        function CdkDrag(
        /** Element that the draggable is attached to. */
        element, 
        /** Droppable container that the draggable is a part of. */
        dropContainer, 
        /**
         * @deprecated `_document` parameter no longer being used and will be removed.
         * @breaking-change 12.0.0
         */
        _document, _ngZone, _viewContainerRef, config, _dir, dragDrop, _changeDetectorRef, _selfHandle, _parentDrag) {
            var _this = this;
            this.element = element;
            this.dropContainer = dropContainer;
            this._ngZone = _ngZone;
            this._viewContainerRef = _viewContainerRef;
            this._dir = _dir;
            this._changeDetectorRef = _changeDetectorRef;
            this._selfHandle = _selfHandle;
            this._parentDrag = _parentDrag;
            this._destroyed = new rxjs.Subject();
            /** Emits when the user starts dragging the item. */
            this.started = new i0.EventEmitter();
            /** Emits when the user has released a drag item, before any animations have started. */
            this.released = new i0.EventEmitter();
            /** Emits when the user stops dragging an item in the container. */
            this.ended = new i0.EventEmitter();
            /** Emits when the user has moved the item into a new container. */
            this.entered = new i0.EventEmitter();
            /** Emits when the user removes the item its container by dragging it into another container. */
            this.exited = new i0.EventEmitter();
            /** Emits when the user drops the item inside a container. */
            this.dropped = new i0.EventEmitter();
            /**
             * Emits as the user is dragging the item. Use with caution,
             * because this event will fire for every pixel that the user has dragged.
             */
            this.moved = new rxjs.Observable(function (observer) {
                var subscription = _this._dragRef.moved.pipe(operators.map(function (movedEvent) { return ({
                    source: _this,
                    pointerPosition: movedEvent.pointerPosition,
                    event: movedEvent.event,
                    delta: movedEvent.delta,
                    distance: movedEvent.distance
                }); })).subscribe(observer);
                return function () {
                    subscription.unsubscribe();
                };
            });
            this._dragRef = dragDrop.createDrag(element, {
                dragStartThreshold: config && config.dragStartThreshold != null ?
                    config.dragStartThreshold : 5,
                pointerDirectionChangeThreshold: config && config.pointerDirectionChangeThreshold != null ?
                    config.pointerDirectionChangeThreshold : 5,
                zIndex: config === null || config === void 0 ? void 0 : config.zIndex,
            });
            this._dragRef.data = this;
            // We have to keep track of the drag instances in order to be able to match an element to
            // a drag instance. We can't go through the global registry of `DragRef`, because the root
            // element could be different.
            CdkDrag._dragInstances.push(this);
            if (config) {
                this._assignDefaults(config);
            }
            // Note that usually the container is assigned when the drop list is picks up the item, but in
            // some cases (mainly transplanted views with OnPush, see #18341) we may end up in a situation
            // where there are no items on the first change detection pass, but the items get picked up as
            // soon as the user triggers another pass by dragging. This is a problem, because the item would
            // have to switch from standalone mode to drag mode in the middle of the dragging sequence which
            // is too late since the two modes save different kinds of information. We work around it by
            // assigning the drop container both from here and the list.
            if (dropContainer) {
                this._dragRef._withDropContainer(dropContainer._dropListRef);
                dropContainer.addItem(this);
            }
            this._syncInputs(this._dragRef);
            this._handleEvents(this._dragRef);
        }
        Object.defineProperty(CdkDrag.prototype, "disabled", {
            /** Whether starting to drag this element is disabled. */
            get: function () {
                return this._disabled || (this.dropContainer && this.dropContainer.disabled);
            },
            set: function (value) {
                this._disabled = coercion.coerceBooleanProperty(value);
                this._dragRef.disabled = this._disabled;
            },
            enumerable: false,
            configurable: true
        });
        /**
         * Returns the element that is being used as a placeholder
         * while the current element is being dragged.
         */
        CdkDrag.prototype.getPlaceholderElement = function () {
            return this._dragRef.getPlaceholderElement();
        };
        /** Returns the root draggable element. */
        CdkDrag.prototype.getRootElement = function () {
            return this._dragRef.getRootElement();
        };
        /** Resets a standalone drag item to its initial position. */
        CdkDrag.prototype.reset = function () {
            this._dragRef.reset();
        };
        /**
         * Gets the pixel coordinates of the draggable outside of a drop container.
         */
        CdkDrag.prototype.getFreeDragPosition = function () {
            return this._dragRef.getFreeDragPosition();
        };
        CdkDrag.prototype.ngAfterViewInit = function () {
            var _this = this;
            // We need to wait for the zone to stabilize, in order for the reference
            // element to be in the proper place in the DOM. This is mostly relevant
            // for draggable elements inside portals since they get stamped out in
            // their original DOM position and then they get transferred to the portal.
            this._ngZone.onStable
                .pipe(operators.take(1), operators.takeUntil(this._destroyed))
                .subscribe(function () {
                _this._updateRootElement();
                // Listen for any newly-added handles.
                _this._handles.changes.pipe(operators.startWith(_this._handles), 
                // Sync the new handles with the DragRef.
                operators.tap(function (handles) {
                    var childHandleElements = handles
                        .filter(function (handle) { return handle._parentDrag === _this; })
                        .map(function (handle) { return handle.element; });
                    // Usually handles are only allowed to be a descendant of the drag element, but if
                    // the consumer defined a different drag root, we should allow the drag element
                    // itself to be a handle too.
                    if (_this._selfHandle && _this.rootElementSelector) {
                        childHandleElements.push(_this.element);
                    }
                    _this._dragRef.withHandles(childHandleElements);
                }), 
                // Listen if the state of any of the handles changes.
                operators.switchMap(function (handles) {
                    return rxjs.merge.apply(void 0, __spread(handles.map(function (item) {
                        return item._stateChanges.pipe(operators.startWith(item));
                    })));
                }), operators.takeUntil(_this._destroyed)).subscribe(function (handleInstance) {
                    // Enabled/disable the handle that changed in the DragRef.
                    var dragRef = _this._dragRef;
                    var handle = handleInstance.element.nativeElement;
                    handleInstance.disabled ? dragRef.disableHandle(handle) : dragRef.enableHandle(handle);
                });
                if (_this.freeDragPosition) {
                    _this._dragRef.setFreeDragPosition(_this.freeDragPosition);
                }
            });
        };
        CdkDrag.prototype.ngOnChanges = function (changes) {
            var rootSelectorChange = changes['rootElementSelector'];
            var positionChange = changes['freeDragPosition'];
            // We don't have to react to the first change since it's being
            // handled in `ngAfterViewInit` where it needs to be deferred.
            if (rootSelectorChange && !rootSelectorChange.firstChange) {
                this._updateRootElement();
            }
            // Skip the first change since it's being handled in `ngAfterViewInit`.
            if (positionChange && !positionChange.firstChange && this.freeDragPosition) {
                this._dragRef.setFreeDragPosition(this.freeDragPosition);
            }
        };
        CdkDrag.prototype.ngOnDestroy = function () {
            if (this.dropContainer) {
                this.dropContainer.removeItem(this);
            }
            var index = CdkDrag._dragInstances.indexOf(this);
            if (index > -1) {
                CdkDrag._dragInstances.splice(index, 1);
            }
            this._destroyed.next();
            this._destroyed.complete();
            this._dragRef.dispose();
        };
        /** Syncs the root element with the `DragRef`. */
        CdkDrag.prototype._updateRootElement = function () {
            var element = this.element.nativeElement;
            var rootElement = this.rootElementSelector ?
                getClosestMatchingAncestor(element, this.rootElementSelector) : element;
            if (rootElement && (typeof ngDevMode === 'undefined' || ngDevMode)) {
                assertElementNode(rootElement, 'cdkDrag');
            }
            this._dragRef.withRootElement(rootElement || element);
        };
        /** Gets the boundary element, based on the `boundaryElement` value. */
        CdkDrag.prototype._getBoundaryElement = function () {
            var boundary = this.boundaryElement;
            if (!boundary) {
                return null;
            }
            if (typeof boundary === 'string') {
                return getClosestMatchingAncestor(this.element.nativeElement, boundary);
            }
            var element = coercion.coerceElement(boundary);
            if ((typeof ngDevMode === 'undefined' || ngDevMode) &&
                !element.contains(this.element.nativeElement)) {
                throw Error('Draggable element is not inside of the node passed into cdkDragBoundary.');
            }
            return element;
        };
        /** Syncs the inputs of the CdkDrag with the options of the underlying DragRef. */
        CdkDrag.prototype._syncInputs = function (ref) {
            var _this = this;
            ref.beforeStarted.subscribe(function () {
                if (!ref.isDragging()) {
                    var dir = _this._dir;
                    var dragStartDelay = _this.dragStartDelay;
                    var placeholder = _this._placeholderTemplate ? {
                        template: _this._placeholderTemplate.templateRef,
                        context: _this._placeholderTemplate.data,
                        viewContainer: _this._viewContainerRef
                    } : null;
                    var preview = _this._previewTemplate ? {
                        template: _this._previewTemplate.templateRef,
                        context: _this._previewTemplate.data,
                        matchSize: _this._previewTemplate.matchSize,
                        viewContainer: _this._viewContainerRef
                    } : null;
                    ref.disabled = _this.disabled;
                    ref.lockAxis = _this.lockAxis;
                    ref.dragStartDelay = (typeof dragStartDelay === 'object' && dragStartDelay) ?
                        dragStartDelay : coercion.coerceNumberProperty(dragStartDelay);
                    ref.constrainPosition = _this.constrainPosition;
                    ref.previewClass = _this.previewClass;
                    ref
                        .withBoundaryElement(_this._getBoundaryElement())
                        .withPlaceholderTemplate(placeholder)
                        .withPreviewTemplate(preview);
                    if (dir) {
                        ref.withDirection(dir.value);
                    }
                }
            });
            // This only needs to be resolved once.
            ref.beforeStarted.pipe(operators.take(1)).subscribe(function () {
                var _a, _b;
                // If we managed to resolve a parent through DI, use it.
                if (_this._parentDrag) {
                    ref.withParent(_this._parentDrag._dragRef);
                    return;
                }
                // Otherwise fall back to resolving the parent by looking up the DOM. This can happen if
                // the item was projected into another item by something like `ngTemplateOutlet`.
                var parent = _this.element.nativeElement.parentElement;
                while (parent) {
                    // `classList` needs to be null checked, because IE doesn't have it on some elements.
                    if ((_a = parent.classList) === null || _a === void 0 ? void 0 : _a.contains(DRAG_HOST_CLASS)) {
                        ref.withParent(((_b = CdkDrag._dragInstances.find(function (drag) {
                            return drag.element.nativeElement === parent;
                        })) === null || _b === void 0 ? void 0 : _b._dragRef) || null);
                        break;
                    }
                    parent = parent.parentElement;
                }
            });
        };
        /** Handles the events from the underlying `DragRef`. */
        CdkDrag.prototype._handleEvents = function (ref) {
            var _this = this;
            ref.started.subscribe(function () {
                _this.started.emit({ source: _this });
                // Since all of these events run outside of change detection,
                // we need to ensure that everything is marked correctly.
                _this._changeDetectorRef.markForCheck();
            });
            ref.released.subscribe(function () {
                _this.released.emit({ source: _this });
            });
            ref.ended.subscribe(function (event) {
                _this.ended.emit({ source: _this, distance: event.distance });
                // Since all of these events run outside of change detection,
                // we need to ensure that everything is marked correctly.
                _this._changeDetectorRef.markForCheck();
            });
            ref.entered.subscribe(function (event) {
                _this.entered.emit({
                    container: event.container.data,
                    item: _this,
                    currentIndex: event.currentIndex
                });
            });
            ref.exited.subscribe(function (event) {
                _this.exited.emit({
                    container: event.container.data,
                    item: _this
                });
            });
            ref.dropped.subscribe(function (event) {
                _this.dropped.emit({
                    previousIndex: event.previousIndex,
                    currentIndex: event.currentIndex,
                    previousContainer: event.previousContainer.data,
                    container: event.container.data,
                    isPointerOverContainer: event.isPointerOverContainer,
                    item: _this,
                    distance: event.distance
                });
            });
        };
        /** Assigns the default input values based on a provided config object. */
        CdkDrag.prototype._assignDefaults = function (config) {
            var lockAxis = config.lockAxis, dragStartDelay = config.dragStartDelay, constrainPosition = config.constrainPosition, previewClass = config.previewClass, boundaryElement = config.boundaryElement, draggingDisabled = config.draggingDisabled, rootElementSelector = config.rootElementSelector;
            this.disabled = draggingDisabled == null ? false : draggingDisabled;
            this.dragStartDelay = dragStartDelay || 0;
            if (lockAxis) {
                this.lockAxis = lockAxis;
            }
            if (constrainPosition) {
                this.constrainPosition = constrainPosition;
            }
            if (previewClass) {
                this.previewClass = previewClass;
            }
            if (boundaryElement) {
                this.boundaryElement = boundaryElement;
            }
            if (rootElementSelector) {
                this.rootElementSelector = rootElementSelector;
            }
        };
        return CdkDrag;
    }());
    CdkDrag._dragInstances = [];
    CdkDrag.decorators = [
        { type: i0.Directive, args: [{
                    selector: '[cdkDrag]',
                    exportAs: 'cdkDrag',
                    host: {
                        'class': DRAG_HOST_CLASS,
                        '[class.cdk-drag-disabled]': 'disabled',
                        '[class.cdk-drag-dragging]': '_dragRef.isDragging()',
                    },
                    providers: [{ provide: CDK_DRAG_PARENT, useExisting: CdkDrag }]
                },] }
    ];
    CdkDrag.ctorParameters = function () { return [
        { type: i0.ElementRef },
        { type: undefined, decorators: [{ type: i0.Inject, args: [CDK_DROP_LIST,] }, { type: i0.Optional }, { type: i0.SkipSelf }] },
        { type: undefined, decorators: [{ type: i0.Inject, args: [i1.DOCUMENT,] }] },
        { type: i0.NgZone },
        { type: i0.ViewContainerRef },
        { type: undefined, decorators: [{ type: i0.Optional }, { type: i0.Inject, args: [CDK_DRAG_CONFIG,] }] },
        { type: bidi.Directionality, decorators: [{ type: i0.Optional }] },
        { type: DragDrop },
        { type: i0.ChangeDetectorRef },
        { type: CdkDragHandle, decorators: [{ type: i0.Optional }, { type: i0.Self }, { type: i0.Inject, args: [CDK_DRAG_HANDLE,] }] },
        { type: CdkDrag, decorators: [{ type: i0.Optional }, { type: i0.SkipSelf }, { type: i0.Inject, args: [CDK_DRAG_PARENT,] }] }
    ]; };
    CdkDrag.propDecorators = {
        _handles: [{ type: i0.ContentChildren, args: [CDK_DRAG_HANDLE, { descendants: true },] }],
        _previewTemplate: [{ type: i0.ContentChild, args: [CDK_DRAG_PREVIEW,] }],
        _placeholderTemplate: [{ type: i0.ContentChild, args: [CDK_DRAG_PLACEHOLDER,] }],
        data: [{ type: i0.Input, args: ['cdkDragData',] }],
        lockAxis: [{ type: i0.Input, args: ['cdkDragLockAxis',] }],
        rootElementSelector: [{ type: i0.Input, args: ['cdkDragRootElement',] }],
        boundaryElement: [{ type: i0.Input, args: ['cdkDragBoundary',] }],
        dragStartDelay: [{ type: i0.Input, args: ['cdkDragStartDelay',] }],
        freeDragPosition: [{ type: i0.Input, args: ['cdkDragFreeDragPosition',] }],
        disabled: [{ type: i0.Input, args: ['cdkDragDisabled',] }],
        constrainPosition: [{ type: i0.Input, args: ['cdkDragConstrainPosition',] }],
        previewClass: [{ type: i0.Input, args: ['cdkDragPreviewClass',] }],
        started: [{ type: i0.Output, args: ['cdkDragStarted',] }],
        released: [{ type: i0.Output, args: ['cdkDragReleased',] }],
        ended: [{ type: i0.Output, args: ['cdkDragEnded',] }],
        entered: [{ type: i0.Output, args: ['cdkDragEntered',] }],
        exited: [{ type: i0.Output, args: ['cdkDragExited',] }],
        dropped: [{ type: i0.Output, args: ['cdkDragDropped',] }],
        moved: [{ type: i0.Output, args: ['cdkDragMoved',] }]
    };
    /** Gets the closest ancestor of an element that matches a selector. */
    function getClosestMatchingAncestor(element, selector) {
        var currentElement = element.parentElement;
        while (currentElement) {
            // IE doesn't support `matches` so we have to fall back to `msMatchesSelector`.
            if (currentElement.matches ? currentElement.matches(selector) :
                currentElement.msMatchesSelector(selector)) {
                return currentElement;
            }
            currentElement = currentElement.parentElement;
        }
        return null;
    }

    /**
     * @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
     */
    var DragDropModule = /** @class */ (function () {
        function DragDropModule() {
        }
        return DragDropModule;
    }());
    DragDropModule.decorators = [
        { type: i0.NgModule, args: [{
                    declarations: [
                        CdkDropList,
                        CdkDropListGroup,
                        CdkDrag,
                        CdkDragHandle,
                        CdkDragPreview,
                        CdkDragPlaceholder,
                    ],
                    exports: [
                        i2.CdkScrollableModule,
                        CdkDropList,
                        CdkDropListGroup,
                        CdkDrag,
                        CdkDragHandle,
                        CdkDragPreview,
                        CdkDragPlaceholder,
                    ],
                    providers: [
                        DragDrop,
                    ]
                },] }
    ];

    /**
     * @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
     */

    /**
     * Generated bundle index. Do not edit.
     */

    exports.CDK_DRAG_CONFIG = CDK_DRAG_CONFIG;
    exports.CDK_DRAG_HANDLE = CDK_DRAG_HANDLE;
    exports.CDK_DRAG_PARENT = CDK_DRAG_PARENT;
    exports.CDK_DRAG_PLACEHOLDER = CDK_DRAG_PLACEHOLDER;
    exports.CDK_DRAG_PREVIEW = CDK_DRAG_PREVIEW;
    exports.CDK_DROP_LIST = CDK_DROP_LIST;
    exports.CDK_DROP_LIST_GROUP = CDK_DROP_LIST_GROUP;
    exports.CdkDrag = CdkDrag;
    exports.CdkDragHandle = CdkDragHandle;
    exports.CdkDragPlaceholder = CdkDragPlaceholder;
    exports.CdkDragPreview = CdkDragPreview;
    exports.CdkDropList = CdkDropList;
    exports.CdkDropListGroup = CdkDropListGroup;
    exports.DragDrop = DragDrop;
    exports.DragDropModule = DragDropModule;
    exports.DragDropRegistry = DragDropRegistry;
    exports.DragRef = DragRef;
    exports.DropListRef = DropListRef;
    exports.copyArrayItem = copyArrayItem;
    exports.moveItemInArray = moveItemInArray;
    exports.transferArrayItem = transferArrayItem;

    Object.defineProperty(exports, '__esModule', { value: true });

})));
//# sourceMappingURL=cdk-drag-drop.umd.js.map
