/*!
 * sweetalert2 v5.3.5
 * Released under the MIT License.
 */
(function(global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
        typeof define === 'function' && define.amd ? define(factory) :
        (global.Sweetalert2 = factory());
}(this, function() {
    'use strict';

    var swalPrefix = 'swal2-'

    var prefix = function(items) {
        var result = {}
        for (var i in items) {
            result[items[i]] = swalPrefix + items[i]
        }
        return result
    }

    var swalClasses = prefix([
        'container',
        'in',
        'iosfix',
        'modal',
        'overlay',
        'fade',
        'show',
        'hide',
        'noanimation',
        'close',
        'content',
        'spacer',
        'confirm',
        'cancel',
        'icon',
        'image',
        'input',
        'file',
        'range',
        'select',
        'radio',
        'checkbox',
        'textarea',
        'inputerror',
        'validationerror',
        'progresssteps',
        'activeprogressstep',
        'progresscircle',
        'progressline',
        'loading',
        'styled'
    ])

    var iconTypes = prefix([
        'success',
        'warning',
        'info',
        'question',
        'error'
    ])

    var defaultParams = {
        title: '',
        text: '',
        html: '',
        type: null,
        customClass: '',
        animation: true,
        allowOutsideClick: true,
        allowEscapeKey: true,
        showConfirmButton: true,
        showCancelButton: false,
        preConfirm: null,
        confirmButtonText: 'OK',
        confirmButtonColor: '#3085d6',
        confirmButtonClass: null,
        cancelButtonText: 'Cancel',
        cancelButtonColor: '#aaa',
        cancelButtonClass: null,
        buttonsStyling: true,
        reverseButtons: false,
        focusCancel: false,
        showCloseButton: false,
        showLoaderOnConfirm: false,
        imageUrl: null,
        imageWidth: null,
        imageHeight: null,
        imageClass: null,
        timer: null,
        width: 500,
        padding: 20,
        background: '#fff',
        input: null,
        inputPlaceholder: '',
        inputValue: '',
        inputOptions: {},
        inputAutoTrim: true,
        inputClass: null,
        inputAttributes: {},
        inputValidator: null,
        progressSteps: [],
        currentProgressStep: null,
        progressStepsDistance: '40px',
        onOpen: null,
        onClose: null
    }

    var sweetHTML = '<div class="' + swalClasses.modal + '" style="display: none" tabIndex="-1">' +
        '<ul class="' + swalClasses.progresssteps + '"></ul>' +
        '<div class="' + swalClasses.icon + ' ' + iconTypes.error + '">' +
        '<span class="x-mark"><span class="line left"></span><span class="line right"></span></span>' +
        '</div>' +
        '<div class="' + swalClasses.icon + ' ' + iconTypes.question + '">?</div>' +
        '<div class="' + swalClasses.icon + ' ' + iconTypes.warning + '">!</div>' +
        '<div class="' + swalClasses.icon + ' ' + iconTypes.info + '">i</div>' +
        '<div class="' + swalClasses.icon + ' ' + iconTypes.success + '">' +
        '<span class="line tip"></span> <span class="line long"></span>' +
        '<div class="placeholder"></div> <div class="fix"></div>' +
        '</div>' +
        '<img class="' + swalClasses.image + '">' +
        '<h2></h2>' +
        '<div class="' + swalClasses.content + '"></div>' +
        '<input class="' + swalClasses.input + '">' +
        '<input type="file" class="' + swalClasses.file + '">' +
        '<div class="' + swalClasses.range + '">' +
        '<output></output>' +
        '<input type="range">' +
        '</div>' +
        '<select class="' + swalClasses.select + '"></select>' +
        '<div class="' + swalClasses.radio + '"></div>' +
        '<label for="' + swalClasses.checkbox + '" class="' + swalClasses.checkbox + '">' +
        '<input type="checkbox">' +
        '</label>' +
        '<textarea class="' + swalClasses.textarea + '"></textarea>' +
        '<div class="' + swalClasses.validationerror + '"></div>' +
        '<hr class="' + swalClasses.spacer + '">' +
        '<button type="button" class="' + swalClasses.confirm + '">OK</button>' +
        '<button type="button" class="' + swalClasses.cancel + '">Cancel</button>' +
        '<span class="' + swalClasses.close + '">&times;</span>' +
        '</div>'

    var sweetContainer

    var existingSweetContainers = document.getElementsByClassName(swalClasses.container)

    if (existingSweetContainers.length) {
        sweetContainer = existingSweetContainers[0]
    } else {
        sweetContainer = document.createElement('div')
        sweetContainer.className = swalClasses.container
        sweetContainer.innerHTML = sweetHTML
    }

    var extend = function(a, b) {
        for (var key in b) {
            if (b.hasOwnProperty(key)) {
                a[key] = b[key]
            }
        }

        return a
    }

    /*
     * Set hover, active and focus-states for buttons (source: http://www.sitepoint.com/javascript-generate-lighter-darker-color)
     */
    var colorLuminance = function(hex, lum) {
        // Validate hex string
        hex = String(hex).replace(/[^0-9a-f]/gi, '')
        if (hex.length < 6) {
            hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]
        }
        lum = lum || 0

        // Convert to decimal and change luminosity
        var rgb = '#'
        for (var i = 0; i < 3; i++) {
            var c = parseInt(hex.substr(i * 2, 2), 16)
            c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16)
            rgb += ('00' + c).substr(c.length)
        }

        return rgb
    }

    // Remember state in cases where opening and handling a modal will fiddle with it.
    var states = {
        previousWindowKeyDown: null,
        previousActiveElement: null,
        previousBodyPadding: null
    }

    /*
     * Add modal + overlay to DOM
     */
    var init = function() {
        if (typeof document === 'undefined') {
            console.error('SweetAlert2 requires document to initialize')
            return
        } else if (document.getElementsByClassName(swalClasses.container).length) {
            return
        }

        document.body.appendChild(sweetContainer)

        var modal = getModal()
        var input = getChildByClass(modal, swalClasses.input)
        var file = getChildByClass(modal, swalClasses.file)
        var range = modal.querySelector('.' + swalClasses.range + ' input')
        var select = getChildByClass(modal, swalClasses.select)
        var checkbox = modal.querySelector('.' + swalClasses.checkbox + ' input')
        var textarea = getChildByClass(modal, swalClasses.textarea)

        input.oninput = function() {
            sweetAlert.resetValidationError()
        }

        input.onkeyup = function(event) {
            event.stopPropagation()
            if (event.keyCode === 13) {
                sweetAlert.clickConfirm()
            }
        }

        file.onchange = function() {
            sweetAlert.resetValidationError()
        }

        range.oninput = function() {
            sweetAlert.resetValidationError()
            range.previousSibling.value = range.value
        }

        range.onchange = function() {
            sweetAlert.resetValidationError()
            range.previousSibling.value = range.value
        }

        select.onchange = function() {
            sweetAlert.resetValidationError()
        }

        checkbox.onchange = function() {
            sweetAlert.resetValidationError()
        }

        textarea.oninput = function() {
            sweetAlert.resetValidationError()
        }

        return modal
    }

    /*
     * Manipulate DOM
     */
    var elementByClass = function(className) {
        return sweetContainer.querySelector('.' + className)
    }

    var getModal = function() {
        return document.body.querySelector('.' + swalClasses.modal) || init()
    }

    var getIcons = function() {
        var modal = getModal()
        return modal.querySelectorAll('.' + swalClasses.icon)
    }

    var getSpacer = function() {
        return elementByClass(swalClasses.spacer)
    }

    var getProgressSteps = function() {
        return elementByClass(swalClasses.progresssteps)
    }

    var getValidationError = function() {
        return elementByClass(swalClasses.validationerror)
    }

    var getConfirmButton = function() {
        return elementByClass(swalClasses.confirm)
    }

    var getCancelButton = function() {
        return elementByClass(swalClasses.cancel)
    }

    var getCloseButton = function() {
        return elementByClass(swalClasses.close)
    }

    var getFocusableElements = function(focusCancel) {
        var buttons = [getConfirmButton(), getCancelButton()]
        if (focusCancel) {
            buttons.reverse()
        }
        return buttons.concat(Array.prototype.slice.call(
            getModal().querySelectorAll('button:not([class^=' + swalPrefix + ']), input:not([type=hidden]), textarea, select')
        ))
    }

    var hasClass = function(elem, className) {
        return elem.classList.contains(className)
    }

    var focusInput = function(input) {
        input.focus()

        // place cursor at end of text in text input
        if (input.type !== 'file') {
            // http://stackoverflow.com/a/2345915/1331425
            var val = input.value
            input.value = ''
            input.value = val
        }
    }

    var addClass = function(elem, className) {
        if (!elem || !className) {
            return
        }
        var classes = className.split(/\s+/)
        classes.forEach(function(className) {
            elem.classList.add(className)
        })
    }

    var removeClass = function(elem, className) {
        if (!elem || !className) {
            return
        }
        var classes = className.split(/\s+/)
        classes.forEach(function(className) {
            elem.classList.remove(className)
        })
    }

    var getChildByClass = function(elem, className) {
        for (var i = 0; i < elem.childNodes.length; i++) {
            if (hasClass(elem.childNodes[i], className)) {
                return elem.childNodes[i]
            }
        }
    }

    var show = function(elem, display) {
        if (!display) {
            display = 'block'
        }
        elem.style.opacity = ''
        elem.style.display = display
    }

    var hide = function(elem) {
        elem.style.opacity = ''
        elem.style.display = 'none'
    }

    var empty = function(elem) {
        while (elem.firstChild) {
            elem.removeChild(elem.firstChild)
        }
    }

    // borrowed from jqeury $(elem).is(':visible') implementation
    var isVisible = function(elem) {
        return elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length
    }

    var removeStyleProperty = function(elem, property) {
        if (elem.style.removeProperty) {
            elem.style.removeProperty(property)
        } else {
            elem.style.removeAttribute(property)
        }
    }

    var fireClick = function(node) {
        // Taken from http://www.nonobtrusive.com/2011/11/29/programatically-fire-crossbrowser-click-event-with-javascript/
        // Then fixed for today's Chrome browser.
        if (typeof MouseEvent === 'function') {
            // Up-to-date approach
            var mevt = new MouseEvent('click', {
                view: window,
                bubbles: false,
                cancelable: true
            })
            node.dispatchEvent(mevt)
        } else if (document.createEvent) {
            // Fallback
            var evt = document.createEvent('MouseEvents')
            evt.initEvent('click', false, false)
            node.dispatchEvent(evt)
        } else if (document.createEventObject) {
            node.fireEvent('onclick')
        } else if (typeof node.onclick === 'function') {
            node.onclick()
        }
    }

    var stopEventPropagation = function(e) {
        // In particular, make sure the space bar doesn't scroll the main window.
        if (typeof e.stopPropagation === 'function') {
            e.stopPropagation()
            e.preventDefault()
        } else if (window.event && window.event.hasOwnProperty('cancelBubble')) {
            window.event.cancelBubble = true
        }
    }

    var animationEndEvent = (function() {
        var testEl = document.createElement('div')
        var transEndEventNames = {
            'WebkitAnimation': 'webkitAnimationEnd',
            'OAnimation': 'oAnimationEnd oanimationend',
            'msAnimation': 'MSAnimationEnd',
            'animation': 'animationend'
        }
        for (var i in transEndEventNames) {
            if (transEndEventNames.hasOwnProperty(i) &&
                testEl.style[i] !== undefined) {
                return transEndEventNames[i]
            }
        }

        return false
    })()

    // Reset the page to its previous state
    var resetPrevState = function() {
        var modal = getModal()
        window.onkeydown = states.previousWindowKeyDown
        if (states.previousActiveElement && states.previousActiveElement.focus) {
            states.previousActiveElement.focus()
        }
        clearTimeout(modal.timeout)
    }

    // Measure width of scrollbar
    // https://github.com/twbs/bootstrap/blob/master/js/modal.js#L279-L286
    var measureScrollbar = function() {
        var scrollDiv = document.createElement('div')
        scrollDiv.style.width = '50px'
        scrollDiv.style.height = '50px'
        scrollDiv.style.overflow = 'scroll'
        document.body.appendChild(scrollDiv)
        var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
        document.body.removeChild(scrollDiv)
        return scrollbarWidth
    }

    // JavaScript Debounce Function
    // https://davidwalsh.name/javascript-debounce-function
    var debounce = function(func, wait, immediate) {
        var timeout
        return function() {
            var context = this
            var args = arguments
            var later = function() {
                timeout = null
                if (!immediate) func.apply(context, args)
            }
            var callNow = immediate && !timeout
            clearTimeout(timeout)
            timeout = setTimeout(later, wait)
            if (callNow) func.apply(context, args)
        }
    }

    var modalParams = extend({}, defaultParams)
    var queue = []
    var swal2Observer

    /*
     * Set type, text and actions on modal
     */
    var setParameters = function(params) {
        var modal = getModal()

        for (var param in params) {
            if (!defaultParams.hasOwnProperty(param) && param !== 'extraParams') {
                console.warn('SweetAlert2: Unknown parameter "' + param + '"')
            }
        }

        // set modal width and margin-left
        modal.style.width = (typeof params.width === 'number') ? params.width + 'px' : params.width

        modal.style.padding = params.padding + 'px'
        modal.style.background = params.background

        var $title = modal.querySelector('h2')
        var $content = modal.querySelector('.' + swalClasses.content)
        var $confirmBtn = getConfirmButton()
        var $cancelBtn = getCancelButton()
        var $closeButton = modal.querySelector('.' + swalClasses.close)

        // Title
        $title.innerHTML = params.title.split('\n').join('<br>')

        // Content
        var i
        if (params.text || params.html) {
            if (typeof params.html === 'object') {
                $content.innerHTML = ''
                if (0 in params.html) {
                    for (i = 0; i in params.html; i++) {
                        $content.appendChild(params.html[i].cloneNode(true))
                    }
                } else {
                    $content.appendChild(params.html.cloneNode(true))
                }
            } else {
                $content.innerHTML = params.html || (params.text.split('\n').join('<br>'))
            }
            show($content)
        } else {
            hide($content)
        }

        // Close button
        if (params.showCloseButton) {
            show($closeButton)
        } else {
            hide($closeButton)
        }

        // Custom Class
        modal.className = swalClasses.modal
        if (params.customClass) {
            addClass(modal, params.customClass)
        }

        // Progress steps
        var progressStepsContainer = getProgressSteps()
        var currentProgressStep = parseInt(params.currentProgressStep === null ? sweetAlert.getQueueStep() : params.currentProgressStep, 10)
        if (params.progressSteps.length) {
            show(progressStepsContainer)
            empty(progressStepsContainer)
            if (currentProgressStep >= params.progressSteps.length) {
                console.warn(
                    'SweetAlert2: Invalid currentProgressStep parameter, it should be less than progressSteps.length ' +
                    '(currentProgressStep like JS arrays starts from 0)'
                )
            }
            params.progressSteps.forEach(function(step, index) {
                var circle = document.createElement('li')
                addClass(circle, swalClasses.progresscircle)
                circle.innerHTML = step
                if (index === currentProgressStep) {
                    addClass(circle, swalClasses.activeprogressstep)
                }
                progressStepsContainer.appendChild(circle)
                if (index !== params.progressSteps.length - 1) {
                    var line = document.createElement('li')
                    addClass(line, swalClasses.progressline)
                    line.style.width = params.progressStepsDistance
                    progressStepsContainer.appendChild(line)
                }
            })
        } else {
            hide(progressStepsContainer)
        }

        // Icon
        var icons = getIcons()
        for (i = 0; i < icons.length; i++) {
            hide(icons[i])
        }
        if (params.type) {
            var validType = false
            for (var iconType in iconTypes) {
                if (params.type === iconType) {
                    validType = true
                    break
                }
            }
            if (!validType) {
                console.error('SweetAlert2: Unknown alert type: ' + params.type)
                return false
            }
            var $icon = modal.querySelector('.' + swalClasses.icon + '.' + iconTypes[params.type])
            show($icon)

            // Animate icon
            switch (params.type) {
                case 'success':
                    addClass($icon, 'animate')
                    addClass($icon.querySelector('.tip'), 'animate-success-tip')
                    addClass($icon.querySelector('.long'), 'animate-success-long')
                    break
                case 'error':
                    addClass($icon, 'animate-error-icon')
                    addClass($icon.querySelector('.x-mark'), 'animate-x-mark')
                    break
                case 'warning':
                    addClass($icon, 'pulse-warning')
                    break
                default:
                    break
            }
        }

        // Custom image
        var $customImage = modal.querySelector('.' + swalClasses.image)
        if (params.imageUrl) {
            $customImage.setAttribute('src', params.imageUrl)
            show($customImage)

            if (params.imageWidth) {
                $customImage.setAttribute('width', params.imageWidth)
            } else {
                $customImage.removeAttribute('width')
            }

            if (params.imageHeight) {
                $customImage.setAttribute('height', params.imageHeight)
            } else {
                $customImage.removeAttribute('height')
            }

            $customImage.className = swalClasses.image
            if (params.imageClass) {
                addClass($customImage, params.imageClass)
            }
        } else {
            hide($customImage)
        }

        // Cancel button
        if (params.showCancelButton) {
            $cancelBtn.style.display = 'inline-block'
        } else {
            hide($cancelBtn)
        }

        // Confirm button
        if (params.showConfirmButton) {
            removeStyleProperty($confirmBtn, 'display')
        } else {
            hide($confirmBtn)
        }

        // Buttons spacer
        var spacer = getSpacer()
        if (!params.showConfirmButton && !params.showCancelButton) {
            hide(spacer)
        } else {
            show(spacer)
        }

        // Edit text on cancel and confirm buttons
        $confirmBtn.innerHTML = params.confirmButtonText
        $cancelBtn.innerHTML = params.cancelButtonText

        // Set buttons to selected background colors
        if (params.buttonsStyling) {
            $confirmBtn.style.backgroundColor = params.confirmButtonColor
            $cancelBtn.style.backgroundColor = params.cancelButtonColor
        }

        // Add buttons custom classes
        $confirmBtn.className = swalClasses.confirm
        addClass($confirmBtn, params.confirmButtonClass)
        $cancelBtn.className = swalClasses.cancel
        addClass($cancelBtn, params.cancelButtonClass)

        // Buttons styling
        if (params.buttonsStyling) {
            addClass($confirmBtn, swalClasses.styled)
            addClass($cancelBtn, swalClasses.styled)
        } else {
            removeClass($confirmBtn, swalClasses.styled)
            removeClass($cancelBtn, swalClasses.styled)

            $confirmBtn.style.backgroundColor = $confirmBtn.style.borderLeftColor = $confirmBtn.style.borderRightColor = ''
            $cancelBtn.style.backgroundColor = $cancelBtn.style.borderLeftColor = $cancelBtn.style.borderRightColor = ''
        }

        // CSS animation
        if (params.animation === true) {
            removeClass(modal, swalClasses.noanimation)
        } else {
            addClass(modal, swalClasses.noanimation)
        }
    }

    /*
     * Animations
     */
    var openModal = function(animation, onComplete) {
        var modal = getModal()
        if (animation) {
            addClass(modal, swalClasses.show)
            addClass(sweetContainer, swalClasses.fade)
            removeClass(modal, swalClasses.hide)
        } else {
            removeClass(modal, swalClasses.fade)
        }
        show(modal)

        // scrolling is 'hidden' until animation is done, after that 'auto'
        sweetContainer.style.overflowY = 'hidden'
        if (animationEndEvent && !hasClass(modal, swalClasses.noanimation)) {
            modal.addEventListener(animationEndEvent, function swalCloseEventFinished() {
                modal.removeEventListener(animationEndEvent, swalCloseEventFinished)
                sweetContainer.style.overflowY = 'auto'
            })
        } else {
            sweetContainer.style.overflowY = 'auto'
        }

        addClass(sweetContainer, swalClasses.in)
        addClass(document.body, swalClasses.in)
        fixScrollbar()
        iOSfix()
        states.previousActiveElement = document.activeElement
        if (onComplete !== null && typeof onComplete === 'function') {
            onComplete.call(this, modal)
        }
    }

    function fixScrollbar() {
        // for queues, do not do this more than once
        if (states.previousBodyPadding !== null) {
            return
        }
        // if the body has overflow
        if (document.body.scrollHeight > window.innerHeight) {
            // add padding so the content doesn't shift after removal of scrollbar
            states.previousBodyPadding = document.body.style.paddingRight
            document.body.style.paddingRight = measureScrollbar() + 'px'
        }
    }

    function undoScrollbar() {
        if (states.previousBodyPadding !== null) {
            document.body.style.paddingRight = states.previousBodyPadding
            states.previousBodyPadding = null
        }
    }

    // Fix iOS scrolling http://stackoverflow.com/q/39626302/1331425
    function iOSfix() {
        var iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream
        if (iOS && !hasClass(document.body, swalClasses.iosfix)) {
            var offset = document.body.scrollTop
            document.body.style.top = (offset * -1) + 'px'
            addClass(document.body, swalClasses.iosfix)
        }
    }

    function undoIOSfix() {
        if (hasClass(document.body, swalClasses.iosfix)) {
            var offset = parseInt(document.body.style.top, 10)
            removeClass(document.body, swalClasses.iosfix)
            document.body.scrollTop = (offset * -1)
        }
    }

    function modalDependant() {
        if (arguments[0] === undefined) {
            console.error('SweetAlert2 expects at least 1 attribute!')
            return false
        }

        var params = extend({}, modalParams)

        switch (typeof arguments[0]) {

            case 'string':
                params.title = arguments[0]
                params.text = arguments[1] || ''
                params.type = arguments[2] || ''

                break

            case 'object':
                extend(params, arguments[0])
                params.extraParams = arguments[0].extraParams

                if (params.input === 'email' && params.inputValidator === null) {
                    params.inputValidator = function(email) {
                        return new Promise(function(resolve, reject) {
                            var emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/
                            if (emailRegex.test(email)) {
                                resolve()
                            } else {
                                reject('Invalid email address')
                            }
                        })
                    }
                }

                break

            default:
                console.error('SweetAlert2: Unexpected type of argument! Expected "string" or "object", got ' + typeof arguments[0])
                return false
        }

        setParameters(params)

        // Modal interactions
        var modal = getModal()

        return new Promise(function(resolve, reject) {
            // Close on timer
            if (params.timer) {
                modal.timeout = setTimeout(function() {
                    sweetAlert.closeModal(params.onClose)
                    reject('timer')
                }, params.timer)
            }

            // Get input element by specified type or, if type isn't specified, by params.input
            var getInput = function(inputType) {
                inputType = inputType || params.input
                switch (inputType) {
                    case 'select':
                    case 'textarea':
                    case 'file':
                        return getChildByClass(modal, swalClasses[inputType])
                    case 'checkbox':
                        return modal.querySelector('.' + swalClasses.checkbox + ' input')
                    case 'radio':
                        return modal.querySelector('.' + swalClasses.radio + ' input:checked') ||
                            modal.querySelector('.' + swalClasses.radio + ' input:first-child')
                    case 'range':
                        return modal.querySelector('.' + swalClasses.range + ' input')
                    default:
                        return getChildByClass(modal, swalClasses.input)
                }
            }

            // Get the value of the modal input
            var getInputValue = function() {
                var input = getInput()
                if (!input) {
                    return null
                }
                switch (params.input) {
                    case 'checkbox':
                        return input.checked ? 1 : 0
                    case 'radio':
                        return input.checked ? input.value : null
                    case 'file':
                        return input.files.length ? input.files[0] : null
                    default:
                        return params.inputAutoTrim ? input.value.trim() : input.value
                }
            }

            // input autofocus
            if (params.input) {
                setTimeout(function() {
                    var input = getInput()
                    if (input) {
                        focusInput(input)
                    }
                }, 0)
            }

            var confirm = function(value) {
                if (params.showLoaderOnConfirm) {
                    sweetAlert.showLoading()
                }

                if (params.preConfirm) {
                    params.preConfirm(value, params.extraParams).then(
                        function(preConfirmValue) {
                            sweetAlert.closeModal(params.onClose)
                            resolve(preConfirmValue || value)
                        },
                        function(error) {
                            sweetAlert.hideLoading()
                            if (error) {
                                sweetAlert.showValidationError(error)
                            }
                        }
                    )
                } else {
                    sweetAlert.closeModal(params.onClose)
                    resolve(value)
                }
            }

            // Mouse interactions
            var onButtonEvent = function(event) {
                var e = event || window.event
                var target = e.target || e.srcElement
                var confirmBtn = getConfirmButton()
                var cancelBtn = getCancelButton()
                var targetedConfirm = confirmBtn === target || confirmBtn.contains(target)
                var targetedCancel = cancelBtn === target || cancelBtn.contains(target)

                switch (e.type) {
                    case 'mouseover':
                    case 'mouseup':
                        if (params.buttonsStyling) {
                            if (targetedConfirm) {
                                confirmBtn.style.backgroundColor = colorLuminance(params.confirmButtonColor, -0.1)
                            } else if (targetedCancel) {
                                cancelBtn.style.backgroundColor = colorLuminance(params.cancelButtonColor, -0.1)
                            }
                        }
                        break
                    case 'mouseout':
                        if (params.buttonsStyling) {
                            if (targetedConfirm) {
                                confirmBtn.style.backgroundColor = params.confirmButtonColor
                            } else if (targetedCancel) {
                                cancelBtn.style.backgroundColor = params.cancelButtonColor
                            }
                        }
                        break
                    case 'mousedown':
                        if (params.buttonsStyling) {
                            if (targetedConfirm) {
                                confirmBtn.style.backgroundColor = colorLuminance(params.confirmButtonColor, -0.2)
                            } else if (targetedCancel) {
                                cancelBtn.style.backgroundColor = colorLuminance(params.cancelButtonColor, -0.2)
                            }
                        }
                        break
                    case 'click':
                        // Clicked 'confirm'
                        if (targetedConfirm && sweetAlert.isVisible()) {
                            if (params.input) {
                                var inputValue = getInputValue()

                                if (params.inputValidator) {
                                    sweetAlert.disableInput()
                                    params.inputValidator(inputValue, params.extraParams).then(
                                        function() {
                                            sweetAlert.enableInput()
                                            confirm(inputValue)
                                        },
                                        function(error) {
                                            sweetAlert.enableInput()
                                            if (error) {
                                                sweetAlert.showValidationError(error)
                                            }
                                        }
                                    )
                                } else {
                                    confirm(inputValue)
                                }
                            } else {
                                confirm(true)
                            }

                            // Clicked 'cancel'
                        } else if (targetedCancel && sweetAlert.isVisible()) {
                            sweetAlert.closeModal(params.onClose)
                            reject('cancel')
                        }

                        break
                    default:
                }
            }

            var $buttons = modal.querySelectorAll('button')
            var i
            for (i = 0; i < $buttons.length; i++) {
                $buttons[i].onclick = onButtonEvent
                $buttons[i].onmouseover = onButtonEvent
                $buttons[i].onmouseout = onButtonEvent
                $buttons[i].onmousedown = onButtonEvent
            }

            // Closing modal by close button
            getCloseButton().onclick = function() {
                sweetAlert.closeModal(params.onClose)
                reject('close')
            }

            // Closing modal by overlay click
            sweetContainer.onclick = function(e) {
                if (e.target !== sweetContainer) {
                    return
                }
                if (params.allowOutsideClick) {
                    sweetAlert.closeModal(params.onClose)
                    reject('overlay')
                }
            }

            var $confirmButton = getConfirmButton()
            var $cancelButton = getCancelButton()

            // Reverse buttons if neede d
            if (params.reverseButtons) {
                $confirmButton.parentNode.insertBefore($cancelButton, $confirmButton)
            } else {
                $confirmButton.parentNode.insertBefore($confirmButton, $cancelButton)
            }

            // Focus handling
            function setFocus(index, increment) {
                var focusableElements = getFocusableElements(params.focusCancel)
                // search for visible elements and select the next possible match
                for (var i = 0; i < focusableElements.length; i++) {
                    index = index + increment

                    // rollover to first item
                    if (index === focusableElements.length) {
                        index = 0

                        // go to last item
                    } else if (index === -1) {
                        index = focusableElements.length - 1
                    }

                    // determine if element is visible
                    var el = focusableElements[index]
                    if (isVisible(el)) {
                        return el.focus()
                    }
                }
            }

            function handleKeyDown(event) {
                var e = event || window.event
                var keyCode = e.keyCode || e.which

                if ([9, 13, 32, 27].indexOf(keyCode) === -1) {
                    // Don't do work on keys we don't care about.
                    return
                }

                var $targetElement = e.target || e.srcElement

                var focusableElements = getFocusableElements(params.focusCancel)
                var btnIndex = -1 // Find the button - note, this is a nodelist, not an array.
                for (var i = 0; i < focusableElements.length; i++) {
                    if ($targetElement === focusableElements[i]) {
                        btnIndex = i
                        break
                    }
                }

                // TAB
                if (keyCode === 9) {
                    if (!e.shiftKey) {
                        // Cycle to the next button
                        setFocus(btnIndex, 1)
                    } else {
                        // Cycle to the prev button
                        setFocus(btnIndex, -1)
                    }

                    stopEventPropagation(e)
                } else {
                    if (keyCode === 13 || keyCode === 32) {
                        if (btnIndex === -1) {
                            // ENTER/SPACE clicked outside of a button.
                            if (params.focusCancel) {
                                fireClick($cancelButton, e)
                            } else {
                                fireClick($confirmButton, e)
                            }
                        }
                    } else if (keyCode === 27 && params.allowEscapeKey === true) {
                        sweetAlert.closeModal(params.onClose)
                        reject('esc')
                    }
                }
            }

            states.previousWindowKeyDown = window.onkeydown
            window.onkeydown = handleKeyDown

            // Loading state
            if (params.buttonsStyling) {
                $confirmButton.style.borderLeftColor = params.confirmButtonColor
                $confirmButton.style.borderRightColor = params.confirmButtonColor
            }

            /**
             * Show spinner instead of Confirm button and disable Cancel button
             */
            sweetAlert.showLoading = sweetAlert.enableLoading = function() {
                show(getSpacer())
                show($confirmButton, 'inline-block')
                addClass($confirmButton, swalClasses.loading)
                addClass(modal, swalClasses.loading)
                $confirmButton.disabled = true
                $cancelButton.disabled = true
            }

            /**
             * Show spinner instead of Confirm button and disable Cancel button
             */
            sweetAlert.hideLoading = sweetAlert.disableLoading = function() {
                if (!params.showConfirmButton) {
                    hide($confirmButton)
                    if (!params.showCancelButton) {
                        hide(getSpacer())
                    }
                }
                removeClass($confirmButton, swalClasses.loading)
                removeClass(modal, swalClasses.loading)
                $confirmButton.disabled = false
                $cancelButton.disabled = false
            }

            sweetAlert.enableButtons = function() {
                $confirmButton.disabled = false
                $cancelButton.disabled = false
            }

            sweetAlert.disableButtons = function() {
                $confirmButton.disabled = true
                $cancelButton.disabled = true
            }

            sweetAlert.enableConfirmButton = function() {
                $confirmButton.disabled = false
            }

            sweetAlert.disableConfirmButton = function() {
                $confirmButton.disabled = true
            }

            sweetAlert.enableInput = function() {
                var input = getInput()
                if (!input) {
                    return false
                }
                if (input.type === 'radio') {
                    var radiosContainer = input.parentNode.parentNode
                    var radios = radiosContainer.querySelectorAll('input')
                    for (var i = 0; i < radios.length; i++) {
                        radios[i].disabled = false
                    }
                } else {
                    input.disabled = false
                }
            }

            sweetAlert.disableInput = function() {
                var input = getInput()
                if (!input) {
                    return false
                }
                if (input && input.type === 'radio') {
                    var radiosContainer = input.parentNode.parentNode
                    var radios = radiosContainer.querySelectorAll('input')
                    for (var i = 0; i < radios.length; i++) {
                        radios[i].disabled = true
                    }
                } else {
                    input.disabled = true
                }
            }

            // Set modal min-height to disable scrolling inside the modal
            sweetAlert.recalculateHeight = debounce(function() {
                var modal = getModal()
                var prevState = modal.style.display
                modal.style.minHeight = ''
                show(modal)
                modal.style.minHeight = (modal.scrollHeight + 1) + 'px'
                modal.style.display = prevState
            }, 50)

            // Show block with validation error
            sweetAlert.showValidationError = function(error) {
                var validationError = getValidationError()
                validationError.innerHTML = error
                show(validationError)

                var input = getInput()
                focusInput(input)
                addClass(input, swalClasses.inputerror)
            }

            // Hide block with validation error
            sweetAlert.resetValidationError = function() {
                var validationError = getValidationError()
                hide(validationError)
                sweetAlert.recalculateHeight()

                var input = getInput()
                if (input) {
                    removeClass(input, swalClasses.inputerror)
                }
            }

            sweetAlert.getProgressSteps = function() {
                return params.progressSteps
            }

            sweetAlert.setProgressSteps = function(progressSteps) {
                params.progressSteps = progressSteps
                setParameters(params)
            }

            sweetAlert.showProgressSteps = function() {
                show(getProgressSteps())
            }

            sweetAlert.hideProgressSteps = function() {
                hide(getProgressSteps())
            }

            sweetAlert.enableButtons()
            sweetAlert.hideLoading()
            sweetAlert.resetValidationError()

            // inputs
            var inputTypes = ['input', 'file', 'range', 'select', 'radio', 'checkbox', 'textarea']
            var input
            for (i = 0; i < inputTypes.length; i++) {
                var inputClass = swalClasses[inputTypes[i]]
                var inputContainer = getChildByClass(modal, inputClass)
                input = getInput(inputTypes[i])

                // set attributes
                if (input) {
                    for (var j in input.attributes) {
                        if (input.attributes.hasOwnProperty(j)) {
                            var attrName = input.attributes[j].name
                            if (attrName !== 'type' && attrName !== 'value') {
                                input.removeAttribute(attrName)
                            }
                        }
                    }
                    for (var attr in params.inputAttributes) {
                        input.setAttribute(attr, params.inputAttributes[attr])
                    }
                }

                // set class
                inputContainer.className = inputClass
                if (params.inputClass) {
                    addClass(inputContainer, params.inputClass)
                }

                hide(inputContainer)
            }

            var populateInputOptions
            switch (params.input) {
                case 'text':
                case 'email':
                case 'password':
                case 'number':
                case 'tel':
                    input = getChildByClass(modal, swalClasses.input)
                    input.value = params.inputValue
                    input.placeholder = params.inputPlaceholder
                    input.type = params.input
                    show(input)
                    break
                case 'file':
                    input = getChildByClass(modal, swalClasses.file)
                    input.placeholder = params.inputPlaceholder
                    input.type = params.input
                    show(input)
                    break
                case 'range':
                    var range = getChildByClass(modal, swalClasses.range)
                    var rangeInput = range.querySelector('input')
                    var rangeOutput = range.querySelector('output')
                    rangeInput.value = params.inputValue
                    rangeInput.type = params.input
                    rangeOutput.value = params.inputValue
                    show(range)
                    break
                case 'select':
                    var select = getChildByClass(modal, swalClasses.select)
                    select.innerHTML = ''
                    if (params.inputPlaceholder) {
                        var placeholder = document.createElement('option')
                        placeholder.innerHTML = params.inputPlaceholder
                        placeholder.value = ''
                        placeholder.disabled = true
                        placeholder.selected = true
                        select.appendChild(placeholder)
                    }
                    populateInputOptions = function(inputOptions) {
                        for (var optionValue in inputOptions) {
                            var option = document.createElement('option')
                            option.value = optionValue
                            option.innerHTML = inputOptions[optionValue]
                            if (params.inputValue === optionValue) {
                                option.selected = true
                            }
                            select.appendChild(option)
                        }
                        show(select)
                        select.focus()
                    }
                    break
                case 'radio':
                    var radio = getChildByClass(modal, swalClasses.radio)
                    radio.innerHTML = ''
                    populateInputOptions = function(inputOptions) {
                        for (var radioValue in inputOptions) {
                            var id = 1
                            var radioInput = document.createElement('input')
                            var radioLabel = document.createElement('label')
                            var radioLabelSpan = document.createElement('span')
                            radioInput.type = 'radio'
                            radioInput.name = swalClasses.radio
                            radioInput.value = radioValue
                            radioInput.id = swalClasses.radio + '-' + (id++)
                            if (params.inputValue === radioValue) {
                                radioInput.checked = true
                            }
                            radioLabelSpan.innerHTML = inputOptions[radioValue]
                            radioLabel.appendChild(radioInput)
                            radioLabel.appendChild(radioLabelSpan)
                            radioLabel.for = radioInput.id
                            radio.appendChild(radioLabel)
                        }
                        show(radio)
                        var radios = radio.querySelectorAll('input')
                        if (radios.length) {
                            radios[0].focus()
                        }
                    }
                    break
                case 'checkbox':
                    var checkbox = getChildByClass(modal, swalClasses.checkbox)
                    var checkboxInput = getInput('checkbox')
                    checkboxInput.type = 'checkbox'
                    checkboxInput.value = 1
                    checkboxInput.id = swalClasses.checkbox
                    checkboxInput.checked = Boolean(params.inputValue)
                    var label = checkbox.getElementsByTagName('span')
                    if (label.length) {
                        checkbox.removeChild(label[0])
                    }
                    label = document.createElement('span')
                    label.innerHTML = params.inputPlaceholder
                    checkbox.appendChild(label)
                    show(checkbox)
                    break
                case 'textarea':
                    var textarea = getChildByClass(modal, swalClasses.textarea)
                    textarea.value = params.inputValue
                    textarea.placeholder = params.inputPlaceholder
                    show(textarea)
                    break
                case null:
                    break
                default:
                    console.error('SweetAlert2: Unexpected type of input! Expected "text" or "email" or "password", "select", "checkbox", "textarea" or "file", got "' + params.input + '"')
                    break
            }

            if (params.input === 'select' || params.input === 'radio') {
                if (params.inputOptions instanceof Promise) {
                    sweetAlert.showLoading()
                    params.inputOptions.then(function(inputOptions) {
                        sweetAlert.hideLoading()
                        populateInputOptions(inputOptions)
                    })
                } else if (typeof params.inputOptions === 'object') {
                    populateInputOptions(params.inputOptions)
                } else {
                    console.error('SweetAlert2: Unexpected type of inputOptions! Expected object or Promise, got ' + typeof params.inputOptions)
                }
            }

            openModal(params.animation, params.onOpen)

            // Focus the first element (input or button)
            setFocus(-1, 1)

            // fix scroll
            sweetContainer.scrollTop = 0

            // Observe changes inside the modal and adjust height
            if (typeof MutationObserver !== 'undefined' && !swal2Observer) {
                swal2Observer = new MutationObserver(sweetAlert.recalculateHeight)
                swal2Observer.observe(modal, {
                    childList: true,
                    characterData: true,
                    subtree: true
                })
            }
        })
    }

    // SweetAlert function
    function sweetAlert() {
        // Copy arguments to the local args variable
        var args = arguments

        if (sweetAlert.isVisible()) {
            sweetAlert.close()
        }

        return modalDependant.apply(this, args)
    }

    /*
     * Global function to determine if swal2 modal is visible
     */
    sweetAlert.isVisible = function() {
        var modal = getModal()
        return isVisible(modal)
    }

    /*
     * Global function for chaining sweetAlert modals
     */
    sweetAlert.queue = function(steps) {
        queue = steps
        var modal = getModal()
        var resetQueue = function() {
            queue = []
            modal.removeAttribute('data-queue-step')
        }
        return new Promise(function(resolve, reject) {
            (function step(i, callback) {
                if (i < queue.length) {
                    modal.setAttribute('data-queue-step', i)

                    sweetAlert(queue[i]).then(function() {
                        step(i + 1, callback)
                    }, function(dismiss) {
                        resetQueue()
                        reject(dismiss)
                    })
                } else {
                    resetQueue()
                    resolve()
                }
            })(0)
        })
    }

    /*
     * Global function for getting the index of current modal in queue
     */
    sweetAlert.getQueueStep = function() {
        return getModal().getAttribute('data-queue-step')
    }

    /*
     * Global function for inserting a modal to the queue
     */
    sweetAlert.insertQueueStep = function(step, index) {
        if (index && index < queue.length) {
            return queue.splice(index, 0, step)
        }
        return queue.push(step)
    }

    /*
     * Global function for deleting a modal from the queue
     */
    sweetAlert.deleteQueueStep = function(index) {
        if (typeof queue[index] !== 'undefined') {
            queue.splice(index, 1)
        }
    }

    /*
     * Global function to close sweetAlert
     */
    sweetAlert.close = sweetAlert.closeModal = function(onComplete) {
        var modal = getModal()
        removeClass(modal, swalClasses.show)
        addClass(modal, swalClasses.hide)

        // Reset icon animations
        var $successIcon = modal.querySelector('.' + swalClasses.icon + '.' + iconTypes.success)
        removeClass($successIcon, 'animate')
        removeClass($successIcon.querySelector('.tip'), 'animate-success-tip')
        removeClass($successIcon.querySelector('.long'), 'animate-success-long')

        var $errorIcon = modal.querySelector('.' + swalClasses.icon + '.' + iconTypes.error)
        removeClass($errorIcon, 'animate-error-icon')
        removeClass($errorIcon.querySelector('.x-mark'), 'animate-x-mark')

        var $warningIcon = modal.querySelector('.' + swalClasses.icon + '.' + iconTypes.warning)
        removeClass($warningIcon, 'pulse-warning')

        resetPrevState()

        var hideModalAndResetState = function() {
            hide(modal)
            modal.style.minHeight = ''
            removeClass(sweetContainer, swalClasses.in)
            removeClass(document.body, swalClasses.in)
            undoScrollbar()
            undoIOSfix()
        }

        // If animation is supported, animate
        if (animationEndEvent && !hasClass(modal, swalClasses.noanimation)) {
            modal.addEventListener(animationEndEvent, function swalCloseEventFinished() {
                modal.removeEventListener(animationEndEvent, swalCloseEventFinished)
                if (hasClass(modal, swalClasses.hide)) {
                    hideModalAndResetState()
                }
            })
        } else {
            // Otherwise, hide immediately
            hideModalAndResetState()
        }
        if (onComplete !== null && typeof onComplete === 'function') {
            onComplete.call(this, modal)
        }
    }

    /*
     * Global function to click 'Confirm' button
     */
    sweetAlert.clickConfirm = function() {
        getConfirmButton().click()
    }

    /*
     * Global function to click 'Cancel' button
     */
    sweetAlert.clickCancel = function() {
        getCancelButton().click()
    }

    /**
     * Set default params for each popup
     * @param {Object} userParams
     */
    sweetAlert.setDefaults = function(userParams) {
        if (!userParams) {
            throw new Error('userParams is required')
        }
        if (typeof userParams !== 'object') {
            throw new Error('userParams has to be a object')
        }

        extend(modalParams, userParams)
    }

    /**
     * Reset default params for each popup
     */
    sweetAlert.resetDefaults = function() {
        modalParams = extend({}, defaultParams)
    }

    sweetAlert.noop = function() {}

    sweetAlert.version = '5.3.5'

    if (typeof Promise === 'function') {
        Promise.prototype.done = Promise.prototype.done || function() { // eslint-disable-line
            return this.catch(function() {
                // Catch promise rejections silently.
                // https://github.com/limonte/sweetalert2/issues/177
            })
        }
    } else {
        console.warn('SweetAlert2: Please inlude Promise polyfill BEFORE including sweetalert2.js if IE10+ support needed.')
    }

    return sweetAlert;

}));
if (window.Sweetalert2) window.sweetAlert = window.swal = window.Sweetalert2;