HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/SBogers10/liempde.ehbo.today/wwwroot/js/kms/attributes.js
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Manages file inputs in a wrapper so that files
 */
var DocumentManager = function () {
    /**
     * The constructor
     *
     * @param wrapper HtmlElement in which an ul resides with class files which in turn holds documents
     * @param key The attributes key as a string
     * @param accept string A comma seperated string containing mime types that are allowed to be uploaded
     * @param extensionThumbsFolder
     * @param availableExtensionThumbs
     * @param maxUploadSizeInBytes
     * @param enablePreviewsIfPossible
     * @param isSortable
     * @param uploadSizeExceededMessage
     */
    function DocumentManager(wrapper, key) {
        var accept = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
        var maxUploadSizeInBytes = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined;
        var enablePreviewsIfPossible = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;
        var isSortable = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;
        var extensionThumbsFolder = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : '/img/kms/extension_thumbs/';
        var availableExtensionThumbs = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : ['svg', 'pdf', 'zip', 'rar', 'csv', 'xlsx', 'mp3', 'mp4', 'docx', 'doc', 'png', 'jpg', 'jpeg', 'gif'];
        var uploadSizeExceededMessage = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : 'The last document won\'t be uploaded because it exceeded the total form limit of';

        _classCallCheck(this, DocumentManager);

        //Initialize variables
        this.constructedSuccessFully = false;
        this.wrapper = wrapper;
        this.accept = accept;
        this.key = key;
        this.isSortable = isSortable;
        this.extensionThumbsFolder = extensionThumbsFolder;
        this.availableExtensionThumbs = availableExtensionThumbs;
        this.enablePreviewsIfPossible = enablePreviewsIfPossible;

        this.oldInputValue = undefined;
        this.maxUploadSizeInBytes = maxUploadSizeInBytes;
        this.uploadSizeExceededMessage = uploadSizeExceededMessage;

        if (wrapper == null) {
            console.error('The wrapper was not a valid html element. Stopping DocumentManager construction');
            return;
        }

        var documentList = wrapper.getElementsByClassName('files')[0];
        var dataInput = wrapper.querySelector('input[name="' + key + '-data"]');
        console.log(dataInput);

        if (!documentList) {
            console.error('The document uploader needs an ul element with class "files" in the given wrapper');
            return;
        }
        this.documentList = documentList;

        if (!dataInput) {
            console.error('The document uploader needs an input element with name "' + key + '-data" in the given wrapper');
            return;
        }
        this.dataInput = dataInput;

        this.constructedSuccessFully = true;
    }

    /**
     * Initializes the setup of the document uploader.
     * @param documents string Example structure:
     *  '[{
             *          "id": 3,
             *           "path": "uploads/products/Before 2018-01-25 at 14,48,23_1522928384.png",
             *          "documentable_id": 1,
             *          "documentable_type": "App\\KommaApp\\Shop\\Products\\Product\\Product",
             *          "created_at": "2018-04-05 11:39:44",
             *          "updated_at": "2018-04-05 11:39:44"
             *  }]'
     *
     */


    _createClass(DocumentManager, [{
        key: 'initialize',
        value: function initialize(documents) {
            if (!this.constructedSuccessFully) return;

            if (documents) {
                var _iteratorNormalCompletion = true;
                var _didIteratorError = false;
                var _iteratorError = undefined;

                try {
                    for (var _iterator = documents[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
                        var initDocument = _step.value;

                        var documentModel = DocumentModel.fromJson(initDocument);
                        if (documentModel) {
                            this.addDocumentElement(documentModel);
                        } else {
                            console.error("DocumentManager stumbled upon a document that is not valid upon initializing: ");
                            console.error(document);
                        }
                    }
                } catch (err) {
                    _didIteratorError = true;
                    _iteratorError = err;
                } finally {
                    try {
                        if (!_iteratorNormalCompletion && _iterator.return) {
                            _iterator.return();
                        }
                    } finally {
                        if (_didIteratorError) {
                            throw _iteratorError;
                        }
                    }
                }

                this.sortDocuments();
            }

            this.updateDataInput();
            this.addNewDocumentButton(undefined);
        }

        /**
         * Occurs when the user clicked the delete document button
         *
         * @param mouseEvent A javascript mouse event
         */

    }, {
        key: 'deleteDocumentButtonClicked',
        value: function deleteDocumentButtonClicked(mouseEvent) {
            var wrapper = mouseEvent.target.parentElement;
            var document = JSON.parse(wrapper.dataset.json);
            if (document.state === DOCUMENT_STATE_DELETED) return;

            if (document.state !== DOCUMENT_STATE_NEW) {
                document.state = DOCUMENT_STATE_DELETED;
                wrapper.classList.add(DOCUMENT_STATE_DELETED);
                wrapper.dataset.json = JSON.stringify(document);
            } else {
                this.documentList.removeChild(wrapper);
            }

            this.updateDataInput();
            this.updateSortOrder();
            this.addNewDocumentButtonIfNeeded();
        }

        /**
         * Occurs when the user modified the document
         *
         * @param event A javascript event
         */

    }, {
        key: 'modifiedDocument',
        value: function modifiedDocument(event) {
            var wrapper = event.target.parentElement;

            //Document exists. Updates its json state and hide it.
            var document = JSON.parse(wrapper.dataset.json);
            if (document.state === DOCUMENT_STATE_DELETED) return;

            if (document.state !== DOCUMENT_STATE_NEW) document.state = DOCUMENT_STATE_MODIFIED;

            //Check what is modified and update the document accordingly
            var nameInput = wrapper.getElementsByClassName('name')[0];
            document.name = nameInput.value;

            wrapper.dataset.json = JSON.stringify(document);
            wrapper.classList.add(DOCUMENT_STATE_MODIFIED);

            this.updateDataInput();
        }

        /**
         * Occurs when the user clicked the add document button
         */

    }, {
        key: 'addNewDocumentButton',
        value: function addNewDocumentButton() {
            this.addDocumentElement();
            this.updateDataInput();
        }

        /**
         * If there are no "new document" button, this method wil add one
         */

    }, {
        key: 'addNewDocumentButtonIfNeeded',
        value: function addNewDocumentButtonIfNeeded() {
            var documentElements = this.documentList.children;
            var foundAddDocumentButton = false;
            var _iteratorNormalCompletion2 = true;
            var _didIteratorError2 = false;
            var _iteratorError2 = undefined;

            try {
                for (var _iterator2 = documentElements[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
                    var documentElement = _step2.value;

                    var _document = JSON.parse(documentElement.dataset.json);
                    if (_document.state === DOCUMENT_STATE_NEW) {
                        foundAddDocumentButton = true;
                        break;
                    }
                }
            } catch (err) {
                _didIteratorError2 = true;
                _iteratorError2 = err;
            } finally {
                try {
                    if (!_iteratorNormalCompletion2 && _iterator2.return) {
                        _iterator2.return();
                    }
                } finally {
                    if (_didIteratorError2) {
                        throw _iteratorError2;
                    }
                }
            }

            console.log(foundAddDocumentButton);

            if (foundAddDocumentButton === false) this.addNewDocumentButton();
        }

        /**
         * Adds a new document element
         *
         * @param documentModel DocumentModel. You only need to specify it when it is an existing document.
         */

    }, {
        key: 'addDocumentElement',
        value: function addDocumentElement() {
            var documentModel = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined;

            //Create an fileInput wrapper in which we put the fileInput and delete / remove button
            var inputWrapper = document.createElement('li');
            inputWrapper.className = 'document';

            var fileInput = undefined;
            var thumbUrl = this.getThumbUrlUsingDocumentModel(documentModel);

            if (documentModel === undefined) {
                //Create a basic file input HtmlElement and add a listener to detect changes
                fileInput = document.createElement('input');
                fileInput.setAttribute('type', 'file');
                fileInput.setAttribute('name', this.key + '-' + (this.getCurrentDocumentsCount() + 1));
                fileInput.addEventListener('click', this.setOldInputvalue.bind(this));
                fileInput.addEventListener('change', this.selectedDocumentOnDevice.bind(this));
            } else {
                //Omit the file input since it is an existing file and rather store the json version of the document in the element.
                thumbUrl = this.getThumbUrlUsingDocumentModel(documentModel);
            }

            if (documentModel !== undefined) {
                inputWrapper.dataset.json = JSON.stringify(documentModel);
            } else {
                documentModel = new DocumentModel();
                documentModel.sort_order = this.documentList.childNodes.length + 1;
                inputWrapper.dataset.json = JSON.stringify(documentModel);
            }

            var nameInput = document.createElement('input');
            nameInput.setAttribute('class', 'name');
            nameInput.setAttribute('type', 'text');
            nameInput.setAttribute('value', documentModel.name);
            nameInput.addEventListener('change', this.modifiedDocument.bind(this));

            var pathText = document.createElement('p');
            pathText.setAttribute('class', 'path');
            pathText.innerText = documentModel.path;

            var contentWrapper = document.createElement('div');
            contentWrapper.setAttribute('class', 'content-wrapper');
            contentWrapper.appendChild(nameInput);
            contentWrapper.appendChild(pathText);

            var deleteButton = document.createElement('span');
            deleteButton.className = 'delete';
            // deleteButton.innerText = 'x';
            deleteButton.addEventListener('click', this.deleteDocumentButtonClicked.bind(this));

            var dragIcon = document.createElement('span');
            dragIcon.className = 'drag-icon';
            // dragIcon.addEventListener('click', this.deleteDocumentButtonClicked.bind(this)); // TODO initalize function for triggering drag and drop

            var thumbImage = document.createElement('div');
            thumbImage.className = 'thumb';
            thumbImage.setAttribute('draggable', 'false'); //Prevent image from being dragged and interfering with what the makeElementDraggableIfNeeded method does
            if (fileInput) {
                thumbImage.addEventListener('click', function (fileInput) {
                    return function (mouseEvent) {
                        fileInput.click(mouseEvent);
                    };
                }(fileInput));
            }

            var documentExtension = this.getExtensionFromFileName(documentModel.path);

            thumbImage.setAttribute('data-filetype', documentExtension);
            if (thumbUrl) {
                thumbImage.style.backgroundImage = "url('" + thumbUrl + "')";
                thumbImage.classList.add('has-image');
            } else if (this.availableExtensionThumbs.indexOf(documentExtension) !== -1) {
                thumbImage.style.backgroundImage = "url('" + this.extensionThumbsFolder + documentExtension + ".svg')";
                thumbImage.classList.add('has-icon');
            }

            //Set the accept and placeholder attributes if needed
            if (fileInput) {
                if (this.accept) fileInput.setAttribute('accept', this.accept);
            }

            //Give the input wrapper its input and delete button
            if (fileInput) inputWrapper.appendChild(fileInput);
            inputWrapper.appendChild(dragIcon);
            inputWrapper.appendChild(thumbImage);
            inputWrapper.appendChild(contentWrapper);
            inputWrapper.appendChild(deleteButton);

            //Make it dragable if needed. With this it can be sorted
            if (!fileInput) {
                this.makeElementRespondToDragging(inputWrapper, this.isSortable);
                this.makeElementRespondToDragOverAndLeave(inputWrapper, this.isSortable);
                this.makeElementRespondToDrop(inputWrapper, this.isSortable);
            }

            //Add the newly created HTMLElement to the document list
            this.documentList.appendChild(inputWrapper);
        }

        /**
         * Returns the amount of documents
         */

    }, {
        key: 'getCurrentDocumentsCount',
        value: function getCurrentDocumentsCount() {
            return this.documentList.getElementsByClassName('document').length;
        }

        /**
         * Triggered when the user did choose a file on the device
         */

    }, {
        key: 'selectedDocumentOnDevice',
        value: function selectedDocumentOnDevice(changeEvent) {
            var input = changeEvent.target;

            if (this.formSizeExceeded()) {
                input.parentElement.removeChild(input);
            } else {
                var file = input.files[0];
                var localFileUrl = input.value;
                var filename = input.value.split(/(\\|\/)/g).pop();

                console.log(input);
                console.log(input.files);

                var extension = this.getExtensionFromFileName(filename);
                var thumbUrl = this.previewThumbUrlIsImage(filename);

                wrapper = input.parentNode;
                var nameInputElement = wrapper.getElementsByClassName('name')[0];

                var thumbImageElement = wrapper.getElementsByClassName('thumb')[0];
                thumbImageElement.setAttribute('data-filetype', extension);

                if (this.availableExtensionThumbs.indexOf(extension) !== -1) {
                    thumbImageElement.style.backgroundImage = "url('" + this.extensionThumbsFolder + extension + ".svg')";
                    thumbImageElement.classList.add('has-icon');
                }

                nameInputElement.value = filename;

                if (input.value !== "" && input.value !== this.oldInputValue) {
                    this.addNewDocumentButton();
                }
            }
        }

        /**
         * Triggered when the user clicked a file input
         */

    }, {
        key: 'setOldInputvalue',
        value: function setOldInputvalue(mouseEvent) {
            this.oldInputValue = mouseEvent.target.value;
        }

        /**
         * Returns the thumbnail for the document or false if it isn't available
         */

    }, {
        key: 'getThumbUrlUsingDocumentModel',
        value: function getThumbUrlUsingDocumentModel(documentModel) {
            if (documentModel) {
                var filename = documentModel.path;
                if (documentModel.thumb_image_url !== '') filename = documentModel.thumb_image_url;
                if (this.previewThumbUrlIsImage(filename)) return filename;
            }

            return false;
        }

        /**
         * Returns the given preview thumb url for an extension if that extension is an image or false if it is not an image
         */

    }, {
        key: 'previewThumbUrlIsImage',
        value: function previewThumbUrlIsImage(url) {
            if (!this.enablePreviewsIfPossible) return false;

            var extension = this.getExtensionFromFileName(url);
            switch (extension) {
                case 'png':
                case 'jpg':
                case 'jpeg':
                case 'gif':
                    return url;
                case 'pdf':
                default:
                    return false;
            }
        }

        /**
         * Returns the extension without leading dot from a file name or '' when it did not have an extension.
         */

    }, {
        key: 'getExtensionFromFileName',
        value: function getExtensionFromFileName(filename) {
            var extension = filename.split(/[.]+/).pop();
            if (extension === filename) return '';
            return extension.toLowerCase();
        }

        /**
         * Check if the total form size isn't bigger then the maximum allowed upload size.
         * Warning: when maxUploadSizeInBytes isn't set this function wil always return false.
         */

    }, {
        key: 'formSizeExceeded',
        value: function formSizeExceeded() {
            if (this.maxUploadSizeInBytes) {
                var exceeded = false;

                var currentTotalInBytes = 0;

                //validate total
                this.documentList.querySelectorAll('input[type="file"]').forEach(function (fileInput) {
                    if (fileInput.files.length !== 1) return;

                    var document = fileInput.files[0];

                    currentTotalInBytes += document.size;
                });
                console.log('max upload size in bytes: ' + this.maxUploadSizeInBytes + ' current upload size in bytes: ' + currentTotalInBytes);

                if (currentTotalInBytes > this.maxUploadSizeInBytes) {
                    var maxUploadSizeInMegaBytes = this.maxUploadSizeInBytes / 1048576;
                    exceeded = true;
                    alert(this.uploadSizeExceededMessage + ' ' + maxUploadSizeInMegaBytes + ' MegaBytes');
                }

                return exceeded;
            } else {
                return false;
            }
        }

        /**
         * Update the data input with an array of json objects that are the data-json attribues of each "document" li.
         * This is used for the backend to determine what has changed and what did not.
         */

    }, {
        key: 'updateDataInput',
        value: function updateDataInput() {
            var documentsDataArray = [];

            //Please notice that the first document isnt a document but is the document add button. That's why we check for the json dataset
            var documents = this.documentList.children;
            for (var documentsIndex = 0; documentsIndex < documents.length; documentsIndex++) {
                var documentElement = documents[documentsIndex];
                if ("json" in documentElement.dataset) {
                    documentsDataArray.push(JSON.parse(documentElement.dataset.json));
                }
            }

            this.dataInput.value = JSON.stringify(documentsDataArray);
        }

        //Drag n drop sortable code
        /**
         * @param element HTMLElement that needs to be draggable or not
         * @param respondOrNotBoolean
         */

    }, {
        key: 'makeElementRespondToDragging',
        value: function makeElementRespondToDragging(element) {
            var respondOrNotBoolean = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;

            element.setAttribute('draggable', respondOrNotBoolean ? 'true' : 'false');
            element.id = this.key + '_' + this.getCurrentDocumentsCount();
            if (respondOrNotBoolean) {
                element.removeEventListener('dragstart', this.drag);
                element.addEventListener('dragstart', this.drag);
            } else {
                element.removeEventListener('dragstart', this.drag);
            }
        }

        /**
         * @param element HTMLElement that needs to be draggable or not
         * @param respondOrNotBoolean
         */

    }, {
        key: 'makeElementRespondToDrop',
        value: function makeElementRespondToDrop(element) {
            var respondOrNotBoolean = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;

            if (respondOrNotBoolean) {
                element.removeEventListener('drop', this.drop.bind(this));
                element.addEventListener('drop', this.drop.bind(this));
            } else {
                element.removeEventListener('drop', this.drop.bind(this));
            }
        }

        /**
         * Prepares the element so that it can receive items that are dropped onto it
         *
         * @param element HTMLElement that needs can be a drop target or not
         * @param respondOrNotBoolean wheter or not it should be a drop target
         */

    }, {
        key: 'makeElementRespondToDragOverAndLeave',
        value: function makeElementRespondToDragOverAndLeave(element) {
            var respondOrNotBoolean = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;

            if (respondOrNotBoolean) {
                element.removeEventListener('dragover', this.dragOver.bind(this));
                element.removeEventListener('dragleave', this.dragLeave.bind(this));
                element.addEventListener('dragover', this.dragOver.bind(this));
                element.addEventListener('dragleave', this.dragLeave.bind(this));
            } else {
                element.removeEventListener('dragover', this.dragOver.bind(this));
                element.removeEventListener('dragleave', this.dragLeave.bind(this));
            }
        }

        /**
         * Occurs when a document (li) HTMLElement is being dragged
         *
         * @param dragEvent
         */

    }, {
        key: 'drag',
        value: function drag(dragEvent) {
            if (!dragEvent.target.id) return;
            dragEvent.stopPropagation();
            dragEvent.dataTransfer.setData("text", dragEvent.target.id); //Set the id of the thing that is being dragged in the event.
        }

        /**
         * Occurs when a document (li) HTMLElement is being dragged over the target element.
         * So the dragEvent target is not the element that you drag, but the place / HTMLElement where it may be dropped.
         *
         * @param dragEvent
         */

    }, {
        key: 'dragOver',
        value: function dragOver(dragEvent) {
            dragEvent.preventDefault(); //Sets target HTMLElement to allow a drop
            dragEvent.stopPropagation();
            if (!dragEvent.target.id) return;

            this.enableOrDisablePointerEventsOnChildrenOfElement(dragEvent.target, false);
            dragEvent.target.classList.add('isDropTarget');
        }

        /**
         * Occurs when a document (li) HTMLElement is NOT being dragged anymore over the target element.
         *
         * @param dragEvent
         */

    }, {
        key: 'dragLeave',
        value: function dragLeave(dragEvent) {
            if (!dragEvent.target.id) return;
            dragEvent.stopPropagation();

            this.enableOrDisablePointerEventsOnChildrenOfElement(dragEvent.target, true);
            dragEvent.target.classList.remove('isDropTarget');
        }

        /**
         * Occurs when a document is being dropped
         *
         * @param dragEvent
         */

    }, {
        key: 'drop',
        value: function drop(dragEvent) {
            dragEvent.preventDefault(); //Prevent browser from activating links and buttons
            if (!dragEvent.target.id) return;

            var draggedElementId = dragEvent.dataTransfer.getData("text");
            var draggedElement = document.getElementById(draggedElementId);
            var targetElement = dragEvent.target;

            targetElement.classList.remove('isDropTarget');

            if (targetElement.nextSibling.nextSibling == null || draggedElement.nextSibling === targetElement) {
                targetElement.parentNode.insertBefore(draggedElement, targetElement.nextSibling); //newnode, reference node
            } else {
                targetElement.parentNode.insertBefore(draggedElement, targetElement); //newnode, reference node
            }

            this.updateSortOrder();

            this.enableOrDisablePointerEventsOnChildrenOfElement(targetElement, true);
        }

        /**
         * Updates the sort order of each document when needed and then updates the data input field
         */

    }, {
        key: 'updateSortOrder',
        value: function updateSortOrder() {
            //Please notice that the first document isnt a document but is the document add button. That's why we check for the json dataset
            var documents = this.documentList.children;
            var currentSortNumber = 1;

            for (var documentsIndex = 0; documentsIndex < documents.length; documentsIndex++) {
                var documentElement = documents[documentsIndex];
                if ("json" in documentElement.dataset === false) continue; //used to skip the add new document button

                var _document2 = JSON.parse(documentElement.dataset.json);

                if (_document2.state === DOCUMENT_STATE_DELETED) continue;

                _document2.sort_order = currentSortNumber;
                if (_document2.state !== DOCUMENT_STATE_NEW) _document2.state = DOCUMENT_STATE_MODIFIED;

                documentElement.dataset.json = JSON.stringify(_document2);
                documentElement.classList.add(DOCUMENT_STATE_MODIFIED);

                currentSortNumber++;
            }

            this.updateDataInput();
        }

        /**
         * Enables / disables the listening to pointer (example: mouse) events on an element
         * and all of it's children. This prevents for example the dragover event from beeing canceled
         * when dragging over an input that resides in an element which listens to the dragover event
         * because the input captures the mouse.
         */

    }, {
        key: 'enableOrDisablePointerEventsOnChildrenOfElement',
        value: function enableOrDisablePointerEventsOnChildrenOfElement(element, enable) {
            var length = element.children.length;
            for (var index = 1; index < length; index++) {
                if (enable === false) {
                    element.children[index].style.pointerEvents = 'none';
                } else {
                    element.children[index].style.pointerEvents = null;
                }

                var childrenLength = element.children.children;
                for (var childrenIndex = 1; childrenIndex < childrenLength; childrenIndex++) {
                    this.enableOrDisablePointerEventsOnChildrenOfElement(element.children.children[index], enable);
                }
            }
        }

        /**
         * Does have a look at the documentElements and sorts them by using their sort order values
         */

    }, {
        key: 'sortDocuments',
        value: function sortDocuments() {
            var documentElements = this.documentList.children;
            documentElements = Array.prototype.slice.call(documentElements); //Converts the htmlCollection of HTMLElement documentElements to an Array of documentElements

            documentElements.sort(function (itemA, itemB) {
                var itemADocument = JSON.parse(itemA.dataset.json);
                var itemBDocument = JSON.parse(itemB.dataset.json);
                console.log(itemADocument.sort_order, itemBDocument.sort_order);
                if (itemADocument.sort_order < itemBDocument.sort_order) return -1;
                return 1;
            });

            var sortedDocumentsLength = documentElements.length;

            for (var index = 1; index < sortedDocumentsLength; index++)
            // for(let index = sortedDocumentsLength-1; index > 0; index--)
            {
                this.documentList.removeChild(documentElements[index]);
                if (this.documentList.length > 1) this.documentList.insertBefore(documentElements[index], this.documentList.firstChild);else this.documentList.appendChild(documentElements[index]);
            }
        }
    }]);

    return DocumentManager;
}();

/**
 * Represents a Document. It the equivalent of the laravel php version
 */


var DocumentModel = function () {
    function DocumentModel() {
        _classCallCheck(this, DocumentModel);

        this.id = -1;
        this.path = '';
        this.state = DOCUMENT_STATE_NEW;
        this.name = '';
        this.sort_order = 1;
        this.thumb_image_url = '';
        this.small_image_url = '';
        this.medium_image_url = '';
        this.large_image_url = '';
        this.documentable_id = -1;
        this.documentable_type = '';
        this.created_at = '';
        this.updated_at = '';
    }

    _createClass(DocumentModel, null, [{
        key: 'isValidDocumentJson',
        value: function isValidDocumentJson(jsonData) {
            return jsonData.hasOwnProperty('id') && jsonData.hasOwnProperty('path') && jsonData.hasOwnProperty('state') && jsonData.hasOwnProperty('name') && jsonData.hasOwnProperty('sort_order') && jsonData.hasOwnProperty('thumb_image_url') && jsonData.hasOwnProperty('small_image_url') && jsonData.hasOwnProperty('medium_image_url') && jsonData.hasOwnProperty('large_image_url') && jsonData.hasOwnProperty('documentable_id') && jsonData.hasOwnProperty('documentable_type') && jsonData.hasOwnProperty('created_at') && jsonData.hasOwnProperty('updated_at');
        }
    }, {
        key: 'fromJson',
        value: function fromJson(jsonData) {
            if (!DocumentModel.isValidDocumentJson(jsonData)) return false;

            var documentModel = new DocumentModel();
            documentModel.id = jsonData.id;
            documentModel.path = jsonData.path;
            documentModel.state = jsonData.state;
            documentModel.name = jsonData.name;
            documentModel.sort_order = jsonData.sort_order;
            documentModel.thumb_image_url = jsonData.thumb_image_url;
            documentModel.small_image_url = jsonData.small_image_url;
            documentModel.medium_image_url = jsonData.medium_image_url;
            documentModel.large_image_url = jsonData.large_image_url;
            documentModel.documentable_id = jsonData.id;
            documentModel.documentable_type = jsonData.documentable_type;
            documentModel.created_at = jsonData.created_at;
            documentModel.updated_at = jsonData.updated_at;

            return documentModel;
        }
    }]);

    return DocumentModel;
}();

var DOCUMENT_STATE_NEW = 'new';
var DOCUMENT_STATE_PRISTINE = 'pristine';
var DOCUMENT_STATE_MODIFIED = 'modified';
var DOCUMENT_STATE_DELETED = 'deleted';

var ImageController = function () {
    function ImageController(key, images, maxImages) {
        _classCallCheck(this, ImageController);

        //console.log('Image controller got images: ');
        //console.log(images);

        //console.log('ImageController: key: '+key);
        //console.log('ImageController: maxImages: '+maxImages);
        //
        this.key = key;
        this.currentImageListId = "#image-list-" + key;
        this.fileCounter = 0;
        this.maxImages = maxImages;
        this.images = images;
        //
        this.initialize();
        this.checkNewButtonState();
    }

    _createClass(ImageController, [{
        key: 'initialize',
        value: function initialize() {
            var self = this;

            // Click on an existing image to remove it
            $(self.currentImageListId + ' .image-thumb-li').click(function () {
                $(this).remove();
                self.removeFromImages($('img', this).attr('data-image-id'));
            });

            // When a file is selected for uploading
            $(document).on('click', self.currentImageListId + ' .new-image input', function (e) {
                //console.log(self.countActiveImages());
                if (self.maxImages != '' && self.countActiveImages() >= self.maxImages) {
                    e.preventDefault();
                    return;
                }
            });

            $(document).on('change', self.currentImageListId + ' .new-image input', function () {
                //console.log("images.blade.php: Change event triggered");

                if (self.maxImages != '' && self.countActiveImages() >= self.maxImages) return;

                //console.log('Checking old input element: #'+self.key+'-'+self.fileCounter);
                var $oldInput = $('#' + self.key + '-' + self.fileCounter);
                //console.log("old input: ");
                //console.log($oldInput);
                //console.log("current image list element: "+self.currentImageListId + ' .uploads :');
                //console.log($(self.currentImageListId + ' .uploads'));

                $(self.currentImageListId + ' .uploads').append($oldInput);
                self.images.push({
                    id: null,
                    name: $oldInput.attr('id'),
                    delete: false
                });
                self.updateImages();
                $oldInput.unbind('change');
                //console.log("unbinded change event from the old input element");

                var files = $oldInput.prop('files');
                //console.log("files from property from the old input: ");
                //console.log(files);

                // Removing multiple files doesn't work yet, so it is disabled
                for (var i = 0; i < files.length; i++) {
                    self.insertImage(files[i], self.fileCounter, i);
                }

                self.fileCounter++;
                $(self.currentImageListId + ' .new-image').append('<input type="file" id="' + self.key + '-' + self.fileCounter + '" name="' + self.key + '-' + self.fileCounter + '" accept="image/*" />');
            });

            this.checkNewButtonState();
        }
    }, {
        key: 'insertImage',
        value: function insertImage(file, fileCounter, imageCounter) {
            var self = this;
            //console.log('insertImage');

            var reader = new FileReader();
            reader.onload = function (e) {
                var dataURL = e.target.result;
                $(self.currentImageListId + ' .thumbs').append('' + '<li id="image-thumb-' + this.key + '-' + fileCounter + '-' + imageCounter + '">' + '<img src="' + dataURL + '" />' + '<div class="deleteImage">тип</div>' + '</li>');
                var thumb = $('#image-thumb-' + self.key + '-' + fileCounter + '-' + imageCounter);
                // Remove image for uploading when clicked
                thumb.click(function () {
                    self.removeFromImages('' + self.key + '-' + fileCounter);
                    thumb.remove();
                    var element = $('#' + self.key + '-' + fileCounter);

                    element.val('');
                    element.remove();
                });
            };
            this.checkNewButtonState();
            reader.readAsDataURL(file);
        }
    }, {
        key: 'checkNewButtonState',
        value: function checkNewButtonState() {
            var button = $(self.currentImageListId + ' .new-image');
            if (this.maxImages !== undefined && this.countActiveImages() >= this.maxImages) {
                //hide the button
                button.hide();
                // //console.log("hide add new image button");
            } else {
                //show the button
                button.show();
                // //console.log("show add new image button");
            }
        }
    }, {
        key: 'updateImages',
        value: function updateImages() {
            var images = JSON.stringify(this.images, null, 2);
            //console.log('Update images: '+images);

            $('#' + this.key).val(images);
            //console.log("Updated images: id:"+'#'+this.key+" with json data:"+JSON.stringify(this.images, null, 2));
            //console.log($('#'+this.key));
            this.checkNewButtonState();
        }
    }, {
        key: 'countActiveImages',
        value: function countActiveImages() {
            //console.log("countActiveImages: ");
            //console.log(this.images);
            var count = 0;
            for (var i = 0; i < this.images.length; i++) {
                if (!this.images[i].delete) count++;
            }
            //console.log("countActiveImages thats: "+count+" length: "+this.images.length);
            return count;
        }
    }, {
        key: 'removeFromImages',
        value: function removeFromImages(idOrFileInputName) {
            //console.log('Removing image: '+idOrFileInputName);
            //console.log('this.images: ');
            //console.log(this.images);
            for (var i = 0; i < this.images.length; i++) {
                if (this.images[i].name == idOrFileInputName) {
                    this.images.splice(i, 1);
                    this.updateImages();
                    return;
                }
                if (this.images[i].id == idOrFileInputName) {
                    this.images[i].delete = true;
                    this.updateImages();
                    return;
                }
            }
        }
    }]);

    return ImageController;
}();

//also @See onOff.blade.php

var OnOff = function () {
    function OnOff() {
        _classCallCheck(this, OnOff);
    }

    _createClass(OnOff, [{
        key: 'toggleOnOff',
        value: function toggleOnOff($id) {
            var onOffBox = document.getElementById($id);
            var onOffSwitch = document.getElementById($id + '-switch');

            if (onOffBox.checked) {
                onOffBox.value = '1';
                onOffSwitch.classList.add('on');
                onOffBox.setAttribute('checked', true);
            } else {
                onOffBox.value = '0';
                onOffSwitch.classList.remove('on');
                onOffBox.removeAttribute('checked');
            }
        }
    }, {
        key: 'toggleOnOffSwitch',
        value: function toggleOnOffSwitch($id) {
            var onOffBox = document.getElementById($id);
            onOffBox.checked = onOffBox.checked ? onOffBox.checked = false : onOffBox.checked = true;
            this.toggleOnOff($id);
            var changeEvent = document.createEvent("Event");
            changeEvent.initEvent("change", false, true);
            // args: string type, boolean bubbles, boolean cancelable
            onOffBox.dispatchEvent(changeEvent);
        }
    }]);

    return OnOff;
}();

var PasswordController = function () {
    /**
     * Validates password fields.
     * The password fields values wil be imploded with a pipe symbol
     *
     * @param passwordInputSelector The css selector for selecting the password input fields
     * @param wrapperSelector The css selector for the wrapper div / element that wraps the first and second input fields along the validation helper
     * @param passwordDontMatchErrorText string
     * @param saveButtonId The id of a save button that needs to be disabled when the passwords are not valid
     * @param minPasswordLength int
     * @param wrapperHasTitleAttributeAndErrorClass Must be set to true if the wrapper (selected with the wrapper selector) has the ability to have an error class and title attribute for displaying an error
     */
    function PasswordController(passwordInputSelector, wrapperSelector, passwordDontMatchErrorText, saveButtonId) {
        var minPasswordLength = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 6;
        var wrapperHasTitleAttributeAndErrorClass = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : false;

        _classCallCheck(this, PasswordController);

        this.wrapperHasTitleAttributeAndErrorClass = wrapperHasTitleAttributeAndErrorClass;
        this.wrapper = document.querySelector(wrapperSelector);
        this.saveButton = document.querySelector("#" + saveButtonId);
        console.log(this.saveButton);

        this.firstPasswordInput = this.wrapper.querySelector('input[name=' + passwordInputSelector + '-1]');
        this.secondPasswordInput = this.wrapper.querySelector('input[name=' + passwordInputSelector + '-2]');
        this.realPasswordInput = this.wrapper.querySelector('input[name=' + passwordInputSelector + ']');

        this.validationMessageWrapperSelector = '.validationHelper';
        this.validationMessageWrapper = this.wrapper.querySelector(this.validationMessageWrapperSelector);

        this.minPasswordLength = minPasswordLength;

        //Used for validation
        this.letter = this.validationMessageWrapper.querySelector(".letter");
        this.capital = this.validationMessageWrapper.querySelector(".capital");
        this.number = this.validationMessageWrapper.querySelector(".number");
        this.length = this.validationMessageWrapper.querySelector(".length");
        this.match = this.validationMessageWrapper.querySelector(".match");
        // this.noPipe = document.querySelector(this.validationMessageWrapperSelector + " .noPipe");

        this.activateListeners(true);
    }

    /**
     * Activates listening for keyup events on the password fields to that the passwordChanged method is triggered
     *
     * @param state
     */


    _createClass(PasswordController, [{
        key: 'activateListeners',
        value: function activateListeners(state) {
            var self = this;
            var validationHelper = this.validationMessageWrapper;

            if (state) {
                this.firstPasswordInput.addEventListener('keyup', self.debounce(function () {
                    self.passwordChanged();
                }, 100));

                this.secondPasswordInput.addEventListener('keyup', self.debounce(function () {
                    self.passwordChanged();
                }, 100));

                this.firstPasswordInput.addEventListener('focus', function () {
                    if (!validationHelper.classList.contains('active')) validationHelper.classList.add('active');
                });
                this.secondPasswordInput.addEventListener('focus', function () {
                    if (!validationHelper.classList.contains('active')) validationHelper.classList.add('active');
                });

                this.firstPasswordInput.addEventListener('blur', function () {
                    if (validationHelper.classList.contains('active')) validationHelper.classList.remove('active');
                });
                this.secondPasswordInput.addEventListener('blur', function () {
                    if (validationHelper.classList.contains('active')) validationHelper.classList.remove('active');
                });
            } else {
                this.firstPasswordInput.removeEventListener('keyup', self.debounce);
                this.secondPasswordInput.removeEventListener('keyup', self.debounce);

                this.firstPasswordInput.removeEventListener('focus');
                this.secondPasswordInput.removeEventListener('focus');

                this.firstPasswordInput.removeEventListener('blur');
                this.secondPasswordInput.removeEventListener('blur');
            }
        }

        /**
         * Triggered when one of the password fields are changed and if the listeners for those fields are active
         */

    }, {
        key: 'passwordChanged',
        value: function passwordChanged() {
            console.log('password changed');

            var value1 = this.firstPasswordInput.value;
            var value2 = this.secondPasswordInput.value;

            var valid = this.validate(value1, value2);
            console.log(valid);

            if (valid) this.realPasswordInput.value = value2;else this.realPasswordInput.value = '';

            this.enableValidMessage(valid);
            this.enableSaveButton(valid);
            this.removeWrapperError();
        }
    }, {
        key: 'enableValidMessage',
        value: function enableValidMessage(enable) {
            var validationHelper = this.validationMessageWrapper;

            if (enable) {
                if (!validationHelper.classList.contains('valid')) validationHelper.classList.add('valid');
            } else {
                if (validationHelper.classList.contains('valid')) validationHelper.classList.remove('valid');
            }
        }
    }, {
        key: 'enableSaveButton',
        value: function enableSaveButton(enable) {
            console.log(enable);
            if (enable) {
                if (this.saveButton.classList.contains('disabled')) this.saveButton.classList.remove('disabled');
            } else {
                if (!this.saveButton.classList.contains('disabled')) this.saveButton.classList.add('disabled');
            }
        }

        /**
         * Removes the error that may be set on the wrapper
         */

    }, {
        key: 'removeWrapperError',
        value: function removeWrapperError() {
            if (!this.wrapperHasTitleAttributeAndErrorClass) return;

            if (this.wrapper.hasAttribute('title')) this.wrapper.setAttribute('title', '');
            if (this.wrapper.classList.contains('error')) this.wrapper.classList.remove('error');
        }

        /**
         * Validate two values and return true or false if respectively valid or not
         *
         * @param value1
         * @param value2
         * @returns {boolean}
         */

    }, {
        key: 'validate',
        value: function validate(value1, value2) {
            var valid = true;

            // Validate lowercase letters
            var lowerCaseLetters = /[a-z]/g;
            if (value1.match(lowerCaseLetters)) {
                this.letter.classList.remove("invalid");
                this.letter.classList.add("valid");
            } else {
                this.letter.classList.remove("valid");
                this.letter.classList.add("invalid");
                valid = false;
            }

            // Validate capital letters
            var upperCaseLetters = /[A-Z]/g;
            if (value1.match(upperCaseLetters)) {
                this.capital.classList.remove("invalid");
                this.capital.classList.add("valid");
            } else {
                this.capital.classList.remove("valid");
                this.capital.classList.add("invalid");
                valid = false;
            }

            // Validate numbers
            var numbers = /[0-9]/g;
            if (value1.match(numbers)) {
                this.number.classList.remove("invalid");
                this.number.classList.add("valid");
            } else {
                this.number.classList.remove("valid");
                this.number.classList.add("invalid");
                valid = false;
            }

            // Validate numbers
            // let pipe = /\|/g;
            // if(value1.match(pipe)) {
            //     this.noPipe.classList.remove("valid");
            //     this.noPipe.classList.add("invalid");
            //     valid = false;
            // } else {
            //     this.noPipe.classList.remove("invalid");
            //     this.noPipe.classList.add("valid");
            // }

            // Validate length
            if (value1.length >= this.minPasswordLength) {
                this.length.classList.remove("invalid");
                this.length.classList.add("valid");
            } else {
                this.length.classList.remove("valid");
                this.length.classList.add("invalid");
                valid = false;
            }

            // Validate password match
            if (value1 === value2 && (value1 !== '' || value2 !== '')) {
                this.match.classList.remove("invalid");
                this.match.classList.add("valid");
            } else {
                this.match.classList.remove("valid");
                this.match.classList.add("invalid");
                valid = false;
            }

            return valid;
        }

        /**
         * Triggers the function after the wait time (milliseconds) has expired and only
         * if the function is not triggered again before the wait time expired.
         *
         * @param func
         * @param wait
         * @param immediate
         * @returns {Function}
         */

    }, {
        key: 'debounce',
        value: function debounce(func, wait, immediate) {
            var timeout = void 0;

            return function () {
                var context = this,
                    args = arguments;
                var later = function later() {
                    timeout = null;
                    if (!immediate) func.apply(context, args);
                };
                var callNow = immediate && !timeout;
                clearTimeout(timeout);
                timeout = setTimeout(later, wait);
                if (callNow) func.apply(context, args);
            };
        }
    }]);

    return PasswordController;
}();
//Also See select.blade.php

$(function () {
    $(".select-menu").selectmenu({
        width: '100%',
        create: function create(event, ui) {
            buttonId = this.id + '-button';
            menuId = this.id + '-menu';
        },
        open: function open(event, ui) {
            var button = document.getElementById(this.id + '-button');
            var menu = document.getElementById(this.id + '-menu');
            menu.style.width = button.offsetWidth + 'px';
            menu.parentNode.style.width = button.offsetWidth + 'px';
            button.classList.add('dropdown-open');
        },
        change: function change(event, ui) {
            var button = document.getElementById(this.id + '-button');
            var buttonText = button.querySelector('.ui-selectmenu-text').innerHTML;
            button.querySelector('.ui-selectmenu-text').innerHTML = buttonText.replace(/&nbsp;/gi, '');
            var changeEvent = document.createEvent("Event");
            changeEvent.initEvent("change", false, true);
            // args: string type, boolean bubbles, boolean cancelable
            button.dispatchEvent(changeEvent);
        },
        close: function close(event, ui) {
            var button = document.getElementById(this.id + '-button');
            button.classList.remove('dropdown-open');
        }
    });
});