this.primevue = this.primevue || {};
this.primevue.utils = (function (exports, utils) {
    'use strict';

    class DomHandler {

        static innerWidth(el) {
            let width = el.offsetWidth;
            let style = getComputedStyle(el);

            width += parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);
            return width;
        }

        static width(el) {
            let width = el.offsetWidth;
            let style = getComputedStyle(el);

            width -= parseFloat(style.paddingLeft) + parseFloat(style.paddingRight);
            return width;
        }

        static getWindowScrollTop() {
            let doc = document.documentElement;
            return (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
        }

        static getWindowScrollLeft() {
            let doc = document.documentElement;
            return (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
        }

        static getOuterWidth(el, margin) {
            if (el) {
                let width = el.offsetWidth;

                if (margin) {
                    let style = getComputedStyle(el);
                    width += parseFloat(style.marginLeft) + parseFloat(style.marginRight);
                }

                return width;
            }
            else {
                return 0;
            }
        }

        static getOuterHeight(el, margin) {
            if (el) {
                let height = el.offsetHeight;

                if (margin) {
                    let style = getComputedStyle(el);
                    height += parseFloat(style.marginTop) + parseFloat(style.marginBottom);
                }

                return height;
            }
            else {
                return 0;
            }
        }

        static getClientHeight(el, margin) {
            if (el) {
                let height = el.clientHeight;

                if (margin) {
                    let style = getComputedStyle(el);
                    height += parseFloat(style.marginTop) + parseFloat(style.marginBottom);
                }

                return height;
            } else {
                return 0;
            }
        }

        static getViewport() {
            let win = window,
                d = document,
                e = d.documentElement,
                g = d.getElementsByTagName('body')[0],
                w = win.innerWidth || e.clientWidth || g.clientWidth,
                h = win.innerHeight || e.clientHeight || g.clientHeight;

            return {width: w, height: h};
        }

        static getOffset(el) {
            var rect = el.getBoundingClientRect();

            return {
                top: rect.top + (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0),
                left: rect.left + (window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0),
            };
        }

        static generateZIndex() {
            this.zindex = this.zindex||999;
            return ++this.zindex;
        }

        static getCurrentZIndex() {
            return this.zindex;
        }

        static index(element) {
            let children = element.parentNode.childNodes;
            let num = 0;
            for (var i = 0; i < children.length; i++) {
                if (children[i] === element) return num;
                if (children[i].nodeType === 1) num++;
            }
            return -1;
        }

        static addMultipleClasses(element, className) {
            if (element.classList) {
                let styles = className.split(' ');
                for (let i = 0; i < styles.length; i++) {
                    element.classList.add(styles[i]);
                }

            }
            else {
                let styles = className.split(' ');
                for (let i = 0; i < styles.length; i++) {
                    element.className += ' ' + styles[i];
                }
            }
        }

        static addClass(element, className) {
            if (element.classList)
                element.classList.add(className);
            else
                element.className += ' ' + className;
        }

        static removeClass(element, className) {
            if (element.classList)
                element.classList.remove(className);
            else
                element.className = element.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
        }

        static hasClass(element, className) {
            if (element) {
                if (element.classList)
                    return element.classList.contains(className);
                else
                    return new RegExp('(^| )' + className + '( |$)', 'gi').test(element.className);
            }
            
            return false;
        }

        static find(element, selector) {
            return element.querySelectorAll(selector);
        }

        static findSingle(element, selector) {
            return element.querySelector(selector);
        }

        static getHeight(el) {
            let height = el.offsetHeight;
            let style = getComputedStyle(el);

            height -= parseFloat(style.paddingTop) + parseFloat(style.paddingBottom) + parseFloat(style.borderTopWidth) + parseFloat(style.borderBottomWidth);

            return height;
        }

        static getWidth(el) {
            let width = el.offsetWidth;
            let style = getComputedStyle(el);

            width -= parseFloat(style.paddingLeft) + parseFloat(style.paddingRight) + parseFloat(style.borderLeftWidth) + parseFloat(style.borderRightWidth);

            return width;
        }

        static absolutePosition(element, target) {
            let elementDimensions = element.offsetParent ? { width: element.offsetWidth, height: element.offsetHeight } : this.getHiddenElementDimensions(element);
            let elementOuterHeight = elementDimensions.height;
            let elementOuterWidth = elementDimensions.width;
            let targetOuterHeight = target.offsetHeight;
            let targetOuterWidth = target.offsetWidth;
            let targetOffset = target.getBoundingClientRect();
            let windowScrollTop = this.getWindowScrollTop();
            let windowScrollLeft = this.getWindowScrollLeft();
            let viewport = this.getViewport();
            let top, left;

            if (targetOffset.top + targetOuterHeight + elementOuterHeight > viewport.height) {
                top = targetOffset.top + windowScrollTop - elementOuterHeight;
                element.style.transformOrigin = 'bottom';

                if (top < 0) {
                    top = windowScrollTop;
                }
            }
            else {
                top = targetOuterHeight + targetOffset.top + windowScrollTop;
                element.style.transformOrigin = 'top';
            }

            if (targetOffset.left + elementOuterWidth > viewport.width)
                left = Math.max(0, targetOffset.left + windowScrollLeft + targetOuterWidth - elementOuterWidth);
            else
                left = targetOffset.left + windowScrollLeft;

            element.style.top = top + 'px';
            element.style.left = left + 'px';
        }

        static relativePosition(element, target) {
            let elementDimensions = element.offsetParent ? { width: element.offsetWidth, height: element.offsetHeight } : this.getHiddenElementDimensions(element);
            const targetHeight = target.offsetHeight;
            const targetOffset = target.getBoundingClientRect();
            const viewport = this.getViewport();
            let top, left;

            if ((targetOffset.top + targetHeight + elementDimensions.height) > viewport.height) {
                top = -1 * (elementDimensions.height);
                element.style.transformOrigin = 'bottom';
                if (targetOffset.top + top < 0) {
                    top = -1 * targetOffset.top;
                }
            }
            else {
                top = targetHeight;
                element.style.transformOrigin = 'top';
            }

            if (elementDimensions.width > viewport.width) {
                // element wider then viewport and cannot fit on screen (align at left side of viewport)
                left = targetOffset.left * -1;
            }
            else if ((targetOffset.left + elementDimensions.width) > viewport.width) {
                // element wider then viewport but can be fit on screen (align at right side of viewport)
                left = (targetOffset.left + elementDimensions.width - viewport.width) * -1;
            }
            else {
                // element fits on screen (align with target)
                left = 0;
            }

            element.style.top = top + 'px';
            element.style.left = left + 'px';
        }

        static getParents(element, parents = []) {
            return element['parentNode'] === null ? parents : this.getParents(element.parentNode, parents.concat([element.parentNode]));
        }

        static getScrollableParents(element) {
            let scrollableParents = [];

            if (element) {
                let parents = this.getParents(element);
                const overflowRegex = /(auto|scroll)/;
                const overflowCheck = (node) => {
                    let styleDeclaration = window['getComputedStyle'](node, null);
                    return overflowRegex.test(styleDeclaration.getPropertyValue('overflow')) || overflowRegex.test(styleDeclaration.getPropertyValue('overflowX')) || overflowRegex.test(styleDeclaration.getPropertyValue('overflowY'));
                };

                for (let parent of parents) {
                    let scrollSelectors = parent.nodeType === 1 && parent.dataset['scrollselectors'];
                    if (scrollSelectors) {
                        let selectors = scrollSelectors.split(',');
                        for (let selector of selectors) {
                            let el = this.findSingle(parent, selector);
                            if (el && overflowCheck(el)) {
                                scrollableParents.push(el);
                            }
                        }
                    }

                    if (parent.nodeType !== 9 && overflowCheck(parent)) {
                        scrollableParents.push(parent);
                    }
                }
            }

            return scrollableParents;
        }

        static getHiddenElementOuterHeight(element) {
            element.style.visibility = 'hidden';
            element.style.display = 'block';
            let elementHeight = element.offsetHeight;
            element.style.display = 'none';
            element.style.visibility = 'visible';

            return elementHeight;
        }

        static getHiddenElementOuterWidth(element) {
            element.style.visibility = 'hidden';
            element.style.display = 'block';
            let elementWidth = element.offsetWidth;
            element.style.display = 'none';
            element.style.visibility = 'visible';

            return elementWidth;
        }

        static getHiddenElementDimensions(element) {
            var dimensions = {};
            element.style.visibility = 'hidden';
            element.style.display = 'block';
            dimensions.width = element.offsetWidth;
            dimensions.height = element.offsetHeight;
            element.style.display = 'none';
            element.style.visibility = 'visible';

            return dimensions;
        }

        static fadeIn(element, duration) {
            element.style.opacity = 0;

            var last = +new Date();
            var opacity = 0;
            var tick = function () {
                opacity = +element.style.opacity + (new Date().getTime() - last) / duration;
                element.style.opacity = opacity;
                last = +new Date();

                if (+opacity < 1) {
                    (window.requestAnimationFrame && requestAnimationFrame(tick)) || setTimeout(tick, 16);
                }
            };

            tick();
        }

        static fadeOut(element, ms) {
            var opacity = 1,
                interval = 50,
                duration = ms,
                gap = interval / duration;

            let fading = setInterval(() => {
                opacity -= gap;

                if (opacity <= 0) {
                    opacity = 0;
                    clearInterval(fading);
                }

                element.style.opacity = opacity;
            }, interval);
        }

        static getUserAgent() {
            return navigator.userAgent;
        }

        static appendChild(element, target) {
            if(this.isElement(target))
                target.appendChild(element);
            else if(target.el && target.elElement)
                target.elElement.appendChild(element);
            else
                throw new Error('Cannot append ' + target + ' to ' + element);
        }

        static scrollInView(container, item) {
            let borderTopValue = getComputedStyle(container).getPropertyValue('borderTopWidth');
            let borderTop = borderTopValue ? parseFloat(borderTopValue) : 0;
            let paddingTopValue = getComputedStyle(container).getPropertyValue('paddingTop');
            let paddingTop = paddingTopValue ? parseFloat(paddingTopValue) : 0;
            let containerRect = container.getBoundingClientRect();
            let itemRect = item.getBoundingClientRect();
            let offset = (itemRect.top + document.body.scrollTop) - (containerRect.top + document.body.scrollTop) - borderTop - paddingTop;
            let scroll = container.scrollTop;
            let elementHeight = container.clientHeight;
            let itemHeight = this.getOuterHeight(item);

            if (offset < 0) {
                container.scrollTop = scroll + offset;
            }
            else if ((offset + itemHeight) > elementHeight) {
                container.scrollTop = scroll + offset - elementHeight + itemHeight;
            }
        }

        static clearSelection() {
            if(window.getSelection) {
                if(window.getSelection().empty) {
                    window.getSelection().empty();
                } else if(window.getSelection().removeAllRanges && window.getSelection().rangeCount > 0 && window.getSelection().getRangeAt(0).getClientRects().length > 0) {
                    window.getSelection().removeAllRanges();
                }
            }
            else if(document['selection'] && document['selection'].empty) {
                try {
                    document['selection'].empty();
                } catch(error) {
                    //ignore IE bug
                }
            }
        }

        static calculateScrollbarWidth() {
            if(this.calculatedScrollbarWidth != null)
                return this.calculatedScrollbarWidth;

            let scrollDiv = document.createElement("div");
            scrollDiv.className = "p-scrollbar-measure";
            document.body.appendChild(scrollDiv);

            let scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth;
            document.body.removeChild(scrollDiv);

            this.calculatedScrollbarWidth = scrollbarWidth;

            return scrollbarWidth;
        }

        static getBrowser() {
            if(!this.browser) {
                let matched = this.resolveUserAgent();
                this.browser = {};

                if (matched.browser) {
                    this.browser[matched.browser] = true;
                    this.browser['version'] = matched.version;
                }

                if (this.browser['chrome']) {
                    this.browser['webkit'] = true;
                } else if (this.browser['webkit']) {
                    this.browser['safari'] = true;
                }
            }

            return this.browser;
        }

        static resolveUserAgent() {
            let ua = navigator.userAgent.toLowerCase();
            let match = /(chrome)[ ]([\w.]+)/.exec(ua) ||
                /(webkit)[ ]([\w.]+)/.exec(ua) ||
                /(opera)(?:.*version|)[ ]([\w.]+)/.exec(ua) ||
                /(msie) ([\w.]+)/.exec(ua) ||
                (ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua)) ||
                [];

            return {
                browser: match[1] || "",
                version: match[2] || "0"
            };
        }

        static isVisible(element) {
            return element.offsetParent != null;
        }

        static invokeElementMethod(element, methodName, args) {
            (element)[methodName].apply(element, args);
        }

        static getFocusableElements(element) {
            let focusableElements = DomHandler.find(element, `button:not([tabindex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden]),
                [href][clientHeight][clientWidth]:not([tabindex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden]),
                input:not([tabindex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden]), select:not([tabindex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden]),
                textarea:not([tabindex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden]), [tabIndex]:not([tabIndex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden]),
                [contenteditable]:not([tabIndex = "-1"]):not([disabled]):not([style*="display:none"]):not([hidden])`
                );

            let visibleFocusableElements = [];
            for (let focusableElement of focusableElements) {
                if (getComputedStyle(focusableElement).display != "none" && getComputedStyle(focusableElement).visibility != "hidden")
                    visibleFocusableElements.push(focusableElement);
            }

            return visibleFocusableElements;
        }

        static isClickable(element) {
            const targetNode = element.nodeName;
            const parentNode = element.parentElement && element.parentElement.nodeName;

            return (targetNode == 'INPUT' || targetNode == 'BUTTON' || targetNode == 'A' ||
                    parentNode == 'INPUT' || parentNode == 'BUTTON' || parentNode == 'A' ||
                    this.hasClass(element, 'p-button') || this.hasClass(element.parentElement, 'p-button') ||
                    this.hasClass(element.parentElement, 'p-checkbox') || this.hasClass(element.parentElement, 'p-radiobutton')
            );
        }

        static applyStyle(element, style) {
            if (typeof style === 'string') {
                element.style.cssText = this.style;
            }
            else {
                for (let prop in this.style) {
                    element.style[prop] = style[prop];
                }
            }
        }
    }

    class ConnectedOverlayScrollHandler {

        constructor(element, listener = () => {}) {
            this.element = element;
            this.listener = listener;
        }

        bindScrollListener() {
            this.scrollableParents = DomHandler.getScrollableParents(this.element);
            for (let i = 0; i < this.scrollableParents.length; i++) {
                this.scrollableParents[i].addEventListener('scroll', this.listener);
            }
        }

        unbindScrollListener() {
            if (this.scrollableParents) {
                for (let i = 0; i < this.scrollableParents.length; i++) {
                    this.scrollableParents[i].removeEventListener('scroll', this.listener);
                }
            }
        }

        destroy() {
            this.unbindScrollListener();
            this.element = null;
            this.listener = null;
            this.scrollableParents = null;
        }
    }

    class ObjectUtils {

        static equals(obj1, obj2, field) {
            if (field)
                return (this.resolveFieldData(obj1, field) === this.resolveFieldData(obj2, field));
            else
                return this.deepEquals(obj1, obj2);
        }

        static deepEquals(a, b) {
            if (a === b) return true;

            if (a && b && typeof a == 'object' && typeof b == 'object') {
                var arrA = Array.isArray(a)
                    , arrB = Array.isArray(b)
                    , i
                    , length
                    , key;

                if (arrA && arrB) {
                    length = a.length;
                    if (length != b.length) return false;
                    for (i = length; i-- !== 0;)
                        if (!this.deepEquals(a[i], b[i])) return false;
                    return true;
                }

                if (arrA != arrB) return false;

                var dateA = a instanceof Date
                    , dateB = b instanceof Date;
                if (dateA != dateB) return false;
                if (dateA && dateB) return a.getTime() == b.getTime();

                var regexpA = a instanceof RegExp
                    , regexpB = b instanceof RegExp;
                if (regexpA != regexpB) return false;
                if (regexpA && regexpB) return a.toString() == b.toString();

                var keys = Object.keys(a);
                length = keys.length;

                if (length !== Object.keys(b).length)
                    return false;

                for (i = length; i-- !== 0;)
                    if (!Object.prototype.hasOwnProperty.call(b, keys[i])) return false;

                for (i = length; i-- !== 0;) {
                    key = keys[i];
                    if (!this.deepEquals(a[key], b[key])) return false;
                }

                return true;
            }

            return a !== a && b !== b;
        }

        static resolveFieldData(data, field) {
            if (data && Object.keys(data).length && field) {
                if (this.isFunction(field)) {
                    return field(data);
                }
                else if(field.indexOf('.') === -1) {
                    return data[field];
                }
                else {
                    let fields = field.split('.');
                    let value = data;
                    for(var i = 0, len = fields.length; i < len; ++i) {
                        if (value == null) {
                            return null;
                        }
                        value = value[fields[i]];
                    }
                    return value;
                }
            }
            else {
                return null;
            }
        }

        static isFunction(obj) {
            return !!(obj && obj.constructor && obj.call && obj.apply);
        }

        static filter(value, fields, filterValue) {
            var filteredItems = [];

            if (value) {
                for (let item of value) {
                    for (let field of fields) {
                        if (String(this.resolveFieldData(item, field)).toLowerCase().indexOf(filterValue.toLowerCase()) > -1) {
                            filteredItems.push(item);
                            break;
                        }
                    }
                }
            }

            return filteredItems;
        }

        static reorderArray(value, from, to) {
            let target;
            if (value && (from !== to)) {
                if (to >= value.length) {
                    target = to - value.length;
                    while ((target--) + 1) {
                        value.push(undefined);
                    }
                }
                value.splice(to, 0, value.splice(from, 1)[0]);
            }
        }

        static findIndexInList(value, list) {
            let index = -1;

            if (list) {
                for (let i = 0; i < list.length; i++) {
                    if (list[i] === value) {
                        index = i;
                        break;
                    }
                }
            }

            return index;
        }

        static contains(value, list) {
            if (value != null && list && list.length) {
                for (let val of list) {
                    if (this.equals(value, val))
                        return true;
                }
            }

            return false;
        }

        static insertIntoOrderedArray(item, index, arr, sourceArr) {
            if (arr.length > 0) {
                let injected = false;
                for (let i = 0; i < arr.length; i++) {
                    let currentItemIndex = this.findIndexInList(arr[i], sourceArr);
                    if (currentItemIndex > index) {
                        arr.splice(i, 0, item);
                        injected = true;
                        break;
                    }
                }

                if (!injected) {
                    arr.push(item);
                }
            }
            else {
                arr.push(item);
            }
        }

        static removeAccents(str) {
            if (str && str.search(/[\xC0-\xFF]/g) > -1) {
                str = str
                        .replace(/[\xC0-\xC5]/g, "A")
                        .replace(/[\xC6]/g, "AE")
                        .replace(/[\xC7]/g, "C")
                        .replace(/[\xC8-\xCB]/g, "E")
                        .replace(/[\xCC-\xCF]/g, "I")
                        .replace(/[\xD0]/g, "D")
                        .replace(/[\xD1]/g, "N")
                        .replace(/[\xD2-\xD6\xD8]/g, "O")
                        .replace(/[\xD9-\xDC]/g, "U")
                        .replace(/[\xDD]/g, "Y")
                        .replace(/[\xDE]/g, "P")
                        .replace(/[\xE0-\xE5]/g, "a")
                        .replace(/[\xE6]/g, "ae")
                        .replace(/[\xE7]/g, "c")
                        .replace(/[\xE8-\xEB]/g, "e")
                        .replace(/[\xEC-\xEF]/g, "i")
                        .replace(/[\xF1]/g, "n")
                        .replace(/[\xF2-\xF6\xF8]/g, "o")
                        .replace(/[\xF9-\xFC]/g, "u")
                        .replace(/[\xFE]/g, "p")
                        .replace(/[\xFD\xFF]/g, "y");
            }

            return str;
        }
    }

    var lastId = 0;

    function UniqueComponentId (prefix = 'pv_id_') {
        lastId++;
        return `${prefix}${lastId}`;
    }

    function handler() {
        let eventTarget = document.body.appendChild(document.createComment(''));
        let eventListener, eventKey;

        return {
            on(type, listener, key) {
                eventKey = key;
                eventListener = function(e) { listener(e.detail); };
                eventTarget.addEventListener(type, eventListener);
            },
            once(type, listener, key) {
                eventKey = key;
                eventListener = function(e) { listener(e.detail); };
                eventTarget.addEventListener(type, eventListener, { once: true });
            },
            off(type, key) {
                if (eventListener && eventKey === key) {
                    eventTarget.removeEventListener(type, eventListener);
                }
            },
            emit(type, detail) {
                eventTarget.dispatchEvent(new CustomEvent(type, { detail }));
            }
        }
    }

    var OverlayEventBus = utils.EventBus();

    exports.ConnectedOverlayScrollHandler = ConnectedOverlayScrollHandler;
    exports.DomHandler = DomHandler;
    exports.EventBus = handler;
    exports.ObjectUtils = ObjectUtils;
    exports.OverlayEventBus = OverlayEventBus;
    exports.UniqueComponentId = UniqueComponentId;

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

    return exports;

}({}, primevue.utils));
