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/netwerkbrabant.komma.pro/wwwroot/js/kms/attributes.js
function _createForOfIteratorHelper(o) { if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (o = _unsupportedIterableToArray(o))) { var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var it, normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }

function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }

function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }

function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(n); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); }

function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a 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); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

/**
 * Manages file inputs in a wrapper so that files
 *
 * @param {HTMLElement} wrapper
 * @param {HTML5Uploader} HTML5Uploader
 */
var DocumentManager = /*#__PURE__*/function () {
  function DocumentManager(wrapper, HTML5Uploader) {
    _classCallCheck(this, DocumentManager);

    //Initialize variables
    this.constructedSuccessFully = false;
    this.wrapper = wrapper;
    this.HTML5Uploader = HTML5Uploader;
    this.accept = "documentsAccept" in wrapper.dataset ? wrapper.dataset.documentsAccept : undefined;

    if ("documentsKey" in wrapper.dataset) {
      this.key = wrapper.dataset.documentsKey;
    } else {
      console.error('Make sure that the wrapper contains the attributes key');
      return;
    }

    this.isSortable = "documentsIsSortable" in wrapper.dataset ? wrapper.dataset.documentsIsSortable === "1" : false;
    this.extensionThumbsFolder = "documentsExtensionThumbsFolder" in wrapper.dataset ? wrapper.dataset.documentsExtensionThumbsFolder : '/img/kms/extension_thumbs/';
    this.availableExtensionThumbs = "documentsAvailableExtensionThumbs" in wrapper.dataset ? wrapper.dataset.documentsAvailableExtensionThumbs : ['svg', 'pdf', 'zip', 'rar', 'csv', 'xlsx', 'mp3', 'mp4', 'docx', 'doc', 'png', 'jpg', 'jpeg', 'gif'], this.enablePreviewsIfPossible = "documentsEnablePreviewsIfPossible" in wrapper.dataset ? wrapper.dataset.documentsEnablePreviewsIfPossible === "1" : false;
    this.maxDocuments = "documentsMaxDocuments" in wrapper.dataset ? wrapper.dataset.documentsMaxDocuments : undefined;
    this.eventMap = {};
    var form = document.getElementById('entity-form');

    if (form) {
      var maxUploadSizeInBytes = form.dataset.maxUploadSize;
      if (maxUploadSizeInBytes) this.maxUploadSizeInBytes = maxUploadSizeInBytes;
    }

    this.uploadSizeExceededMessage = 'You cannot upload more files right now. Please save these first before continuing. The limit is:';

    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="' + this.key + '-data"]');

    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 "' + this.key + '-data" in the given wrapper. It is used to keep track of the states of all documents. Stopping DocumentManager construction');
      return;
    }

    this.dataInput = dataInput;

    if (!"uploadedDocuments" in wrapper.dataset) {
      console.error('The wrapper must have a uploadedDocuments dataset attribute containing a json string representing the uploaded documents as an array of documents. Stopping DocumentManager construction');
    }

    var documents = JSON.parse(this.dataInput.value);
    this.constructedSuccessFully = true;
    this.initialize(documents);
  }
  /**
   * 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 length = documents.length;

        for (var index = 0; index < length; index++) {
          var initDocument = documents[index];
          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(initDocument);
          }
        }

        this.sortDocuments();
      }

      this.updateDataInput();
      this.setupHtml5Uploader();
    }
    /**
     * Set up the html 5 uploader. Hook to its events
     */

  }, {
    key: "setupHtml5Uploader",
    value: function setupHtml5Uploader() {
      var self = this;
      this.HTML5Uploader.on('uploadStart', this.HTML5UploadStarted.bind(this));
      this.HTML5Uploader.on('updateProgress', this.HTML5UploadProgress.bind(this));
      this.HTML5Uploader.on('uploadComplete', this.HTML5UploadedFile.bind(this));
      this.HTML5Uploader.on('uploadFailed', this.HTML5UploadFailedOrCanceled.bind(this));
      this.HTML5Uploader.on('uploadCanceled', this.HTML5UploadFailedOrCanceled.bind(this));
    }
    /**
     * Triggered when a HTML file upload failed to upload or was canceled.
     *
     * @constructor
     */

  }, {
    key: "HTML5UploadFailedOrCanceled",
    value: function HTML5UploadFailedOrCanceled(file) {
      var documentElement = file.documentElement;
      if (!documentElement) return;
      this.documentList.removeChild(documentElement);
      this.updateDataInput();
    }
    /**
     * Triggered when a file was uploaded successfully
     *
     * @param file
     * @param responseText
     * @constructor
     */

  }, {
    key: "HTML5UploadedFile",
    value: function HTML5UploadedFile(file, responseText) {
      var documentElement = file.documentElement;
      if (!documentElement) return;
      var trackerModel = JSON.parse(responseText);
      var documentModel = DocumentModel.fromJson(JSON.parse(documentElement.dataset.json));
      documentModel.upload_tracker_id = trackerModel.id; //TrackerModel as array.

      this.attachDocumentModelToDocumentElement(documentElement, documentModel);
      documentElement.querySelector('.drag-icon').classList.remove('is-hidden');
      documentElement.querySelector('.thumb').classList.remove('is-uploading');
      documentElement.querySelector('.percentage').remove();
      this.updateDataInput();
    }
    /**
     * Triggered when HTML5 Uploader made progress in uploading a file
     *
     * @param file
     * @param percentCompleteOrNull
     * @constructor
     */

  }, {
    key: "HTML5UploadProgress",
    value: function HTML5UploadProgress(file, percentCompleteOrNull) {
      var documentElement = file.documentElement;
      if (!documentElement) return;
      var progress = documentElement.querySelector('.percentage'); //There is still some backend processing time needed. So we don't show 100%. Only when the backend responds with a complete

      if (percentCompleteOrNull && percentCompleteOrNull === 100) percentCompleteOrNull = 99;else if (!percentCompleteOrNull) percentCompleteOrNull = 1; // Update the progress value

      progress.setAttribute("aria-valuenow", percentCompleteOrNull);
    }
    /**
     * Triggered when a HTML 5 upload was started.
     *
     * @param file
     * @constructor
     */

  }, {
    key: "HTML5UploadStarted",
    value: function HTML5UploadStarted(file) {
      var documentElement = this.createDocumentElement();
      this.attachDocumentModelToDocumentElement(documentElement);
      var documentModel = DocumentModel.fromJson(JSON.parse(documentElement.dataset.json));
      documentModel.state = DOCUMENT_STATE_NEW;
      documentModel.name = file.name;
      documentModel.path = file.name;
      documentElement = this.updateDocumentElementWithDocumentData(documentElement, documentModel);
      this.attachDocumentModelToDocumentElement(documentElement, documentModel); // Add the progress element to the thumb

      var progressPercentageString = '<span class="percentage" role="progressbar" aria-valuemin="0" aria-valuemax="100"></span>'; // let progressPercentage = document.createElement('span');
      // progressPercentage.setAttribute('class', 'percentage');
      // progressPercentage.setAttribute("role", "progressbar");
      // progressPercentage.setAttribute("aria-valuemin", 0);
      // progressPercentage.setAttribute("aria-valuemax", 100);

      documentElement.querySelector('.thumb').insertAdjacentHTML('afterbegin', progressPercentageString);
      this.documentList.appendChild(documentElement);
      documentElement.querySelector('.drag-icon').classList.add('is-hidden');
      documentElement.querySelector('.thumb').classList.add('is-uploading'); // documentElement.querySelector('.thumb').classList.add('has-image');

      file.documentElement = documentElement;
    }
    /**
     * Occurs when the user clicked the delete document button
     *
     * @param mouseEvent A javascript mouse event
     */

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

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

      this.updateDataInput();
      this.updateSortOrder();
    }
    /**
     * Occurs when the user modified the document
     *
     * @param event A javascript event
     */

  }, {
    key: "modifiedDocument",
    value: function modifiedDocument(event) {
      var wrapper = event.target.parentElement.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();
    }
    /**
     * Adds a new document element. When documentModel isn't specified, the document element wil give the user the
     * ability to upload a new document by transforming that document element to a document uploader (fancy fileinput)
     *
     * @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 documentElement = this.createDocumentElement();
      if (documentModel !== undefined) this.updateDocumentElementWithDocumentData(documentElement, documentModel);
      this.attachDocumentModelToDocumentElement(documentElement, documentModel); // if(documentModel === undefined) this.transformDocumentElementIntoADocumentUpload(documentElement);
      //Make it dragable if needed. With this it can be sorted

      if (documentModel) {
        this.makeElementRespondToDragging(documentElement, this.isSortable);
        this.makeElementRespondToDragOverAndLeave(documentElement, this.isSortable);
        this.makeElementRespondToDrop(documentElement, this.isSortable);
      } //Add the newly created HTMLElement to the document list


      this.documentList.appendChild(documentElement);
    }
    /**
     * @param documentElement {HTMLElement}
     * @param documentModel {DocumentModel|undefined}
     * @returns {HTMLElement} The document element
     */

  }, {
    key: "attachDocumentModelToDocumentElement",
    value: function attachDocumentModelToDocumentElement(documentElement) {
      var documentModel = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;

      if (documentModel !== undefined) {
        documentElement.dataset.json = JSON.stringify(documentModel);
      } else {
        documentModel = new DocumentModel();
        documentModel.sort_order = this.getCurrentDocumentsCount() + 1;
        documentElement.dataset.json = JSON.stringify(documentModel);
      }

      return documentElement;
    }
    /**
     *
     * @param documentElement {HTMLElement}
     * @param documentModel {DocumentModel}
     * @return {HTMLElement}
     */

  }, {
    key: "updateDocumentElementWithDocumentData",
    value: function updateDocumentElementWithDocumentData(documentElement, documentModel) {
      var nameInput = documentElement.querySelector('.name');
      var pathParagraph = documentElement.querySelector('.path');
      var thumbImageElement = documentElement.querySelector('.thumb'); //Set the path of the document

      if (pathParagraph) {
        pathParagraph.innerText = documentModel.path;
      } //Set the name of the document


      if (nameInput) {
        nameInput.setAttribute('value', documentModel.name);
      } //Set the thumb image


      if (thumbImageElement && documentModel.path) {
        var thumbUrl = this.getThumbUrlUsingDocumentModel(documentModel);
        var documentExtension = this.getExtensionFromFileName(documentModel.path);
        thumbImageElement.setAttribute('data-filetype', documentExtension);
        var thumbImage = thumbImageElement.querySelector('.thumb__image');

        if (thumbUrl && thumbImage && documentModel.state !== 'new') {
          thumbImage.style.backgroundImage = "url('" + thumbUrl + "')";
          thumbImageElement.classList.add('has-image');
        } else if (thumbImage && this.availableExtensionThumbs.indexOf(documentExtension) !== -1) {
          thumbImage.style.backgroundImage = "url('" + this.extensionThumbsFolder + documentExtension + ".svg')";
          thumbImageElement.classList.add('has-icon');
        }
      }

      return documentElement;
    }
    /**
     * Creates a li item with a name input, path text paragraph, delete button and a thumb image.
     *
     * @returns {HTMLElement}
     */

  }, {
    key: "createDocumentElement",
    value: function createDocumentElement() {
      var documentElement = document.createElement('li');
      documentElement.className = 'document';
      var nameInput = document.createElement('input');
      nameInput.setAttribute('class', 'name');
      nameInput.setAttribute('type', 'text');
      nameInput.addEventListener('change', this.modifiedDocument.bind(this));
      var pathText = document.createElement('p');
      pathText.setAttribute('class', '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';
      var thumbContainer = document.createElement('div');
      thumbContainer.className = 'thumb';
      thumbContainer.setAttribute('draggable', 'false'); //Prevent image from being dragged and interfering with what the makeElementDraggableIfNeeded method does

      var thumbImage = document.createElement('div');
      thumbImage.className = 'thumb__image';
      thumbContainer.appendChild(thumbImage);
      var fileInput = document.createElement('input');
      fileInput.setAttribute('type', 'file');
      fileInput.setAttribute('name', this.key + '-' + (this.getCurrentDocumentsCount() + 1));
      if (this.accept) fileInput.setAttribute('accept', this.accept);
      documentElement.appendChild(fileInput);
      fileInput.style.display = "none";
      documentElement.appendChild(dragIcon);
      documentElement.appendChild(thumbContainer);
      documentElement.appendChild(contentWrapper);
      documentElement.appendChild(deleteButton);
      return documentElement;
    }
    /**
     * Retrieves a javascript file instance and creates a documentElement for it.
     * Usually used by outside classes to inject a document from a file to upload.
     *
     * @param fileInstance {File}
     */

  }, {
    key: "receiveFile",
    value: function receiveFile(fileInstance) {
      if (!fileInstance) {
        console.warn('DocumentManager:receiveFile: Expected to get a file but did not get one');
        return;
      }

      console.log('this.getCurrentDocumentsCount() < this.maxDocuments: ', this.getCurrentDocumentsCount(), this.maxDocuments, 'File', fileInstance);

      if (this.getCurrentDocumentsCount() < this.maxDocuments) {
        var documentElement = this.createDocumentElement();
        this.attachDocumentModelToDocumentElement(documentElement);

        if (this.HTML5Uploader.isSupported() === false) {
          documentElement = this.giveDocumentElementAFile(documentElement, fileInstance); //Add the newly created HTMLElement to the document list

          this.documentList.appendChild(documentElement);

          if (this.formSizeExceeded()) {
            documentElement.parentElement.removeChild(documentElement); //Remove the documentElement
          }

          this.updateSortOrder();
        } else {
          console.log('Uploading via HTML5');
          this.HTML5Uploader.upload(fileInstance);
        }
      }
    }
    /**
     * Returns the amount of documents
     */

  }, {
    key: "getCurrentDocumentsCount",
    value: function getCurrentDocumentsCount() {
      return this.documentList.getElementsByClassName('document').length;
    }
    /**
     * Sets the file of an document element to the given one.
     * Makes the drag icon invisible since it was not uploaded yet
     * and cannot be positioned. Sets the file input to the files name and
     * loads the thumb with the appropiate extension
     *
     * @param {HTMLElement} documentElement
     * @param {File} file
     * @return {HTMLElement} the documentElement
     */

  }, {
    key: "giveDocumentElementAFile",
    value: function giveDocumentElementAFile(documentElement, file) {
      var filename = file.name;
      var extension = this.getExtensionFromFileName(filename);
      var thumbUrl = this.previewThumbUrlIsImage(filename); //Get the document element and some parts in it

      var nameInputElement = documentElement.querySelector('.name');
      var thumbImageElement = documentElement.querySelector('.thumb');
      var contentWrapper = documentElement.querySelector('.content-wrapper');
      var deleteButton = documentElement.querySelector('.delete');
      var dragIcon = documentElement.querySelector('.drag-icon');
      var fileInputElement = documentElement.querySelector('input[type="file"]'); //Hide the drag icon. Dragging is only supported after file upload

      dragIcon.style.display = 'none'; //Update file input with a file if the input does not have a file.

      if (fileInputElement && !fileInputElement.files[0]) {
        fileInputElement.files = new FileList(file);
      } //Make thumb visible and load extension image


      thumbImageElement.setAttribute('data-filetype', extension);

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

      nameInputElement.value = filename;
      return documentElement;
    }
    /**
     * 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;
      var nDocuments = documents.length;

      for (var documentsIndex = 0; documentsIndex < nDocuments; documentsIndex++) {
        var documentElement = documents[documentsIndex];

        if ("json" in documentElement.dataset) {
          documentsDataArray.push(JSON.parse(documentElement.dataset.json));
        }
      }

      if (nDocuments >= this.maxDocuments) {
        this.wrapper.querySelector('.drag-and-drop-area').classList.add('is-hidden');
      } else {
        this.wrapper.querySelector('.drag-and-drop-area').classList.remove('is-hidden');
      }

      this.dataInput.value = JSON.stringify(documentsDataArray);
    }
    /**
     * 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 nDocuments = documents.length;
      var currentSortNumber = 1;

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

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

        if (_document.state === DOCUMENT_STATE_DELETED) continue;
        _document.sort_order = currentSortNumber;
        if (_document.state !== DOCUMENT_STATE_NEW) _document.state = DOCUMENT_STATE_MODIFIED;
        documentElement.dataset.json = JSON.stringify(_document);
        documentElement.classList.add(DOCUMENT_STATE_MODIFIED);
        currentSortNumber++;
      }

      this.updateDataInput();
    }
    /**
     * 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++) {
        this.documentList.removeChild(documentElements[index]);
        if (this.documentList.length > 1) this.documentList.insertBefore(documentElements[index], this.documentList.firstChild);else this.documentList.appendChild(documentElements[index]);
      }
    }
    /**
     * @param element HTMLElement that needs to be draggable or not
     * @param respondOrNotBoolean
     * @return {DocumentManager}
     */

  }, {
    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.bind(this));
        element.addEventListener('dragstart', this.drag.bind(this));
      } else {
        element.removeEventListener('dragstart', this.drag.bind(this));
      }

      return this;
    }
    /**
     * @param element HTMLElement that needs to be draggable or not
     * @param respondOrNotBoolean
     * @return {DocumentManager}
     */

  }, {
    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));
      }

      return 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.

      var draggedElement = document.getElementById(dragEvent.target.id);
      this.triggerEvent('drag', draggedElement);
    }
    /**
     * 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;
      var draggedElementId = dragEvent.dataTransfer.getData("text");
      var draggedElement = document.getElementById(draggedElementId);
      this.enableOrDisablePointerEventsOnChildrenOfElement(dragEvent.target, false);
      dragEvent.target.classList.add('isDropTarget');
      this.triggerEvent('dragLeave', [draggedElement, dragEvent.target]);
    }
    /**
     * 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();
      var draggedElementId = dragEvent.dataTransfer.getData("text");
      var draggedElement = document.getElementById(draggedElementId);
      this.enableOrDisablePointerEventsOnChildrenOfElement(dragEvent.target, true);
      dragEvent.target.classList.remove('isDropTarget');
      this.triggerEvent('dragLeave', [draggedElement, dragEvent.target]);
    }
    /**
     * 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'); //Create a shim element that keeps track of where the dragged element was and where the target element must be inserted

      var shimElement = document.createElement('div');
      draggedElement.parentElement.insertBefore(shimElement, draggedElement); //Move the dragged element in just before the target element

      draggedElement.parentElement.insertBefore(draggedElement, targetElement); //Move the target element before the shim and then remove the shim since we only needed that to mark the dragged elements original position

      draggedElement.parentElement.insertBefore(targetElement, shimElement);
      shimElement.parentElement.removeChild(shimElement);
      this.triggerEvent('drop', [draggedElement, targetElement]);
      this.enableOrDisablePointerEventsOnChildrenOfElement(targetElement, true);
      this.updateSortOrder();
    }
    /**
     * 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);
        }
      }
    }
    /**
     * Registers a event to a callback and returns the a reference to the event handler for that specific event
     *
     * @param event (string)
     * @param callback (callable)
     */

  }, {
    key: "on",
    value: function on(event, callback) {
      if (!this.eventMap.hasOwnProperty(event)) this.eventMap[event] = [];
      return this.eventMap[event].push(callback);
    }
    /**
     * Call event callbacks
     *
     * @param event (string)
     * @param eventArgs (array) an array of arguments to pass to the callback
     */

  }, {
    key: "triggerEvent",
    value: function triggerEvent(event, eventArgs) {
      if (!this.eventMap.hasOwnProperty(event)) return;
      var nEvents = this.eventMap[event].length;

      for (var index = 0; index < nEvents; index++) {
        var callback = this.eventMap[event][index];

        if (eventArgs && eventArgs.length > 0) {
          callback.apply(this, eventArgs);
        } else {
          callback.call(this);
        }
      }
    }
  }]);

  return DocumentManager;
}();
/**
 * Represents a Document. It the equivalent of the laravel php version
 */


var DocumentModel = /*#__PURE__*/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.upload_tracker_id = -1;
    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('upload_tracker_id') && 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.upload_tracker_id = jsonData.upload_tracker_id;
      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';
/**
 * Used for setting files
 */

var FileList = function FileList() {
  var _ref;

  for (var _len = arguments.length, items = new Array(_len), _key = 0; _key < _len; _key++) {
    items[_key] = arguments[_key];
  }

  _classCallCheck(this, FileList);

  // flatten rest parameter
  items = (_ref = []).concat.apply(_ref, _toConsumableArray(items)); // check if every element of array is an instance of `File`

  if (items.length && !items.every(function (file) {
    return file instanceof File;
  })) {
    throw new TypeError("expected argument to FileList is File or array of File objects");
  } // use `ClipboardEvent("").clipboardData` for Firefox, which returns `null` at Chromium
  // we just need the `DataTransfer` instance referenced by `.clipboardData`


  var dt = new ClipboardEvent("").clipboardData || new DataTransfer(); // add `File` objects to `DataTransfer` `.items`

  var _iterator = _createForOfIteratorHelper(items),
      _step;

  try {
    for (_iterator.s(); !(_step = _iterator.n()).done;) {
      var file = _step.value;
      dt.items.add(file);
    }
  } catch (err) {
    _iterator.e(err);
  } finally {
    _iterator.f();
  }

  return dt.files;
};

var FileDragAndDropHandler = /*#__PURE__*/function () {
  /**
   *
   *
   * @param areaElement {HTMLElement}
   */
  function FileDragAndDropHandler(areaElement) {
    _classCallCheck(this, FileDragAndDropHandler);

    this.hooks = [];
    this.selectButton = areaElement.querySelector('button.select');

    if (!this.selectButton) {
      console.log('FileDragAndDropHandler:constructor The document area must have a button in it with class select. But did not have one. Not responding to drag and drop');
      return;
    }

    this.fileCatcherInput = areaElement.querySelector('input[type="file"]');

    if (!this.fileCatcherInput) {
      console.log('FileDragAndDropHandler:constructor The document area must have file input. But did not have one. Not responding to drag and drop');
      return;
    }

    this.makeElementRespondToDragOverAndLeave(areaElement);
    this.makeElementRespondToDrop(areaElement);
    this.makeElementRespondToClick(areaElement);
    this.makeFileInputPassFilesToHooks();
  }
  /**
   * Adds an event listener to the file input and makes it pass its files to the document manager
   */


  _createClass(FileDragAndDropHandler, [{
    key: "makeFileInputPassFilesToHooks",
    value: function makeFileInputPassFilesToHooks() {
      var self = this;
      this.fileCatcherInput.addEventListener('change', function (event) {
        var nFiles = event.target.files.length;

        for (var index = 0; index < nFiles; index++) {
          var file = event.target.files[index]; // console.log(file);

          self.createFileListForFileAndPassToHooks(file);
        }

        event.target.value = '';
      });
    }
    /**
     * Catches click on the element and passes them trough to the file input
     */

  }, {
    key: "makeElementRespondToClick",
    value: function makeElementRespondToClick(element) {
      var self = this;
      element.addEventListener('click', function (event) {
        self.fileCatcherInput.click();
      });
    }
    /**
     * Hooks a hookable (an object that has a addFile method / function) to the drag and drop handler so that the drag and drop handler passes inputs to the
     * hookable
     * @param hookable {Class}
     */

  }, {
    key: "hookTo",
    value: function hookTo(hookable) {
      if (typeof hookable.receiveFile !== 'function') {
        console.error('The given hookable does not have a required receiveFile method / function. Not hooking the given "hookable".');
        return;
      }

      this.hooks.push(hookable);
    }
    /**
     * @param element HTMLElement that needs to be draggable or not
     * @param respondOrNotBoolean
     * @return {FileDragAndDropHandler}
     */

  }, {
    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));
      }

      return 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 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

      var targetElement = dragEvent.target;
      targetElement.classList.remove('isDropTarget');
      this.enableOrDisablePointerEventsOnChildrenOfElement(targetElement, true); // Prevent default behavior (Prevent file from being opened)

      dragEvent.preventDefault();

      if (dragEvent.dataTransfer.items) {
        // Use DataTransferItemList interface to access the file(s)
        for (var i = 0; i < dragEvent.dataTransfer.items.length; i++) {
          // If dropped items aren't files, reject them
          if (dragEvent.dataTransfer.items[i].kind === 'file') {
            var file = dragEvent.dataTransfer.items[i].getAsFile();
            this.createFileListForFileAndPassToHooks(file);
          }
        }
      } else {
        // Use DataTransfer interface to access the file(s)
        for (var _i = 0; _i < dragEvent.dataTransfer.files.length; _i++) {
          var _file = dragEvent.dataTransfer.files[_i];
          this.createFileListForFileAndPassToHooks(_file);
        }
      }
    }
  }, {
    key: "createFileListForFileAndPassToHooks",
    value: function createFileListForFileAndPassToHooks(file) {
      var length = this.hooks.length;

      for (var index = 0; index < length; index++) {
        this.hooks[index].receiveFile(file);
      }
    }
    /**
     * 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);
        }
      }
    }
  }]);

  return FileDragAndDropHandler;
}();
/**
 * HTML 5 file uploads that report progress while uploading
 */


var HTML5Uploader = /*#__PURE__*/function () {
  function HTML5Uploader(uploadUrl, maxPostSize, maxUploadSize, translations) {
    _classCallCheck(this, HTML5Uploader);

    this.constructedSuccessfully = false;

    if (!uploadUrl) {
      console.error('Did not get a valid upload url. Not initializing Html5Uploader');
      return;
    }

    this.uploadUrl = uploadUrl;

    if (!maxPostSize) {
      console.error('Did not get the maximum post size. Not initializing Html5Uploader');
      return;
    }

    this.maxPostSize = maxPostSize;

    if (!maxUploadSize) {
      console.error('Did not get the maximum upload size. Not initializing Html5Uploader');
      return;
    }

    this.maxUploadSize = maxUploadSize;

    if (!translations) {
      console.error('Did not get the translations. Not initializing Html5Uploader');
      return;
    }

    this.translations = JSON.parse(translations);
    this.eventMap = {};

    if (!this.isSupported()) {
      console.warn('HTML 5 file upload is not supported. Not initializing Html5Uploader');
      return;
    }

    this.constructedSuccessfully = true;
  }
  /**
   * Returns true if the browser supports HTML 5 uploading. false if not
   * @return {boolean}
   */


  _createClass(HTML5Uploader, [{
    key: "isSupported",
    value: function isSupported() {
      return window.FormData !== undefined;
    }
    /**
     * @param {File} file
     */

  }, {
    key: "receiveFile",
    value: function receiveFile(file) {
      if (!this.isSupported()) {
        console.error('HTML 5 file upload is not supported. Not uploading file.');
        return;
      }
    }
    /**
     * @param {File} file
     */

  }, {
    key: "upload",
    value: function upload(file) {
      if (!this.verifyFileSizeOrShowError(file)) return;
      if (this.constructedSuccessfully === false) return;
      var self = this;
      var formData = new FormData();
      formData.append(file.name, file);
      var request = new XMLHttpRequest();
      var uploadRequest = request.upload;
      uploadRequest.addEventListener("progress", function (file) {
        return function (event) {
          self.updateProgress(file, event);
        };
      }(file));
      request.addEventListener("loadstart", function (file) {
        return function () {
          self.uploadStart(file);
        };
      }(file));
      request.addEventListener("error", function (file) {
        return function () {
          self.uploadFailed(file);
        };
      }(file));
      request.addEventListener("abort", function (file) {
        return function () {
          self.uploadCanceled(file);
        };
      }(file));

      request.onreadystatechange = function (file) {
        return function () {
          if (request.readyState === 4 && request.status === 200) {
            self.uploadComplete(file, request.responseText);
          }
        };
      }(file);

      request.open('POST', this.uploadUrl);
      request.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
      var csfrTokenContainer = document.querySelector('meta[name="csrf-token"]');

      if (!csfrTokenContainer) {
        console.error('Not uploading file since not csrf-token could be found in a meta tag with name "csrf-token". Please add it');
        return;
      }

      request.setRequestHeader('X-CSRF-TOKEN', csfrTokenContainer.getAttribute('content'));
      request.send(formData);
    }
    /**
     * Returns true if the file size is lower then the maximum allowed server upload size.
     * Or shows an alert and returns false if it is bigger then the allowed server upload size.
     *
     * @param {File} file
     * @return {boolean}
     */

  }, {
    key: "verifyFileSizeOrShowError",
    value: function verifyFileSizeOrShowError(file) {
      if (file.size > this.maxPostSize || file.size > this.maxUploadSize) {
        //Calculate file size and max file size to megabytes
        var fileSizeInMegaBytes = file.size / (1024 * 1024);
        var maxSizeInMegaBytes = (this.maxUploadSize > this.maxPostSize ? this.maxPostSize : this.maxUploadSize) / (1024 * 1024); //Round this sizes to 2 decimals

        fileSizeInMegaBytes = Math.round(fileSizeInMegaBytes * 100) / 100;
        maxSizeInMegaBytes = Math.round(maxSizeInMegaBytes * 100) / 100; //Gather translation texts

        var introText = this.translations.file_to_big;
        var maxFileSizeUploadTranslation = this.translations.max_file_size_upload;
        var fileSizeUploadTranslation = this.translations.file_size_upload; //Assemble alert message

        var alertText = introText + '\n\n' + maxFileSizeUploadTranslation + maxSizeInMegaBytes + ' MB\n' + fileSizeUploadTranslation + fileSizeInMegaBytes + ' MB\n'; //Show alert message and return false

        alert(alertText);
        return false;
      } //File size is fine. Return true


      return true;
    }
  }, {
    key: "updateProgress",
    value: function updateProgress(file, event) {
      if (event.lengthComputable) {
        var percentComplete = Math.ceil(event.loaded / event.total * 100);
        this.triggerEvent('updateProgress', [file, percentComplete]);
      } else {
        // Unable to compute progress information since the total size is unknown
        this.triggerEvent('updateProgress', [file, null]);
      }
    }
  }, {
    key: "uploadStart",
    value: function uploadStart(file) {
      this.triggerEvent('uploadStart', [file]);
    }
  }, {
    key: "uploadComplete",
    value: function uploadComplete(file, responseText) {
      this.triggerEvent('uploadComplete', [file, responseText]);
    }
  }, {
    key: "uploadFailed",
    value: function uploadFailed(file) {
      this.triggerEvent('uploadFailed', [file]);
    }
  }, {
    key: "uploadCanceled",
    value: function uploadCanceled(file) {
      this.triggerEvent('uploadCanceled', [file]);
    }
    /**
     * Registers a event to a callback and returns the a reference to the event handler for that specific event
     *
     * @param event (string)
     * @param callback (callable)
     */

  }, {
    key: "on",
    value: function on(event, callback) {
      if (this.constructedSuccessfully === false) return;
      if (!this.eventMap.hasOwnProperty(event)) this.eventMap[event] = [];
      return this.eventMap[event].push(callback);
    }
    /**
     * Call event callbacks
     *
     * @param event (string)
     * @param eventArgs (array) an array of arguments to pass to the callback
     */

  }, {
    key: "triggerEvent",
    value: function triggerEvent(event, eventArgs) {
      if (!this.eventMap.hasOwnProperty(event)) return;
      var nEvents = this.eventMap[event].length;

      for (var index = 0; index < nEvents; index++) {
        var callback = this.eventMap[event][index];

        if (eventArgs && eventArgs.length > 0) {
          callback.apply(this, eventArgs);
        } else {
          callback.call(this);
        }
      }
    }
  }]);

  return HTML5Uploader;
}();

var ImageController = /*#__PURE__*/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;
}();

var MultiSelectController = /*#__PURE__*/function () {
  /**
   * @param multiSelectElement {HTMLInputElement}
   */
  function MultiSelectController(multiSelectElement) {
    _classCallCheck(this, MultiSelectController);

    if (multiSelectElement.tagName !== 'INPUT' || multiSelectElement.type !== 'text') {
      console.error('The given parameter must be an instance of HTMLInputElement');
      return;
    }

    this.multiSelectSelectField = multiSelectElement; //The input element that must multiSelect what you type

    var input = this.multiSelectSelectField.parentElement.querySelector('input[type="hidden"]'); //The input element that wil store the real value for the multiSelect Attribute

    if (!input) {
      console.error('Expected an HTMLInputElement as a sibling of the supplied multiSelect element (HTMLInputElement) to store the multiSelect\'s real value');
      return;
    }

    this.input = input;

    if (!'attributeKey' in this.multiSelectSelectField.dataset) {
      console.error('attributeKey dataset value not set');
      return;
    }

    this.attributeKey = this.multiSelectSelectField.dataset.attributeKey;

    if (!'autosaveUrl' in this.multiSelectSelectField.dataset) {
      console.error('autosaveUrl dataset value not set');
      return;
    }

    this.autosaveUrl = this.multiSelectSelectField.dataset.autosaveUrl;

    if (!'maxItemsToSelect' in this.multiSelectSelectField.dataset) {
      console.error('maxItemsToSelect dataset value not set');
      return;
    }

    this.maxItemsToSelect = this.multiSelectSelectField.dataset.maxItemsToSelect;

    if (!'itemData' in this.multiSelectSelectField.dataset) {
      console.error('itemData dataset value not set');
      return;
    }

    this.dataSet = JSON.parse(this.multiSelectSelectField.dataset.itemdata);

    if (!'values' in this.multiSelectSelectField.dataset) {
      console.error('values dataset value not set');
      return;
    }

    this.valuesFromAttribute = this.multiSelectSelectField.dataset.values.split(',');
    var openElement = this.input.parentElement.querySelector('.open');

    if (!openElement) {
      console.error('Could not find multiSelect open element. It should be a sibling of the input');
    }

    this.openbutton = openElement;
    var itemsWrapper = multiSelectElement.parentElement.parentElement.querySelector('div.items');

    if (!itemsWrapper) {
      console.error('Could not find a div HTMLElement with class "items" inside the multiSelectsInputElement\'s parent parent element');
    }

    this.itemsWrapper = itemsWrapper;
    this.sortable = this.multiSelectSelectField.dataset.sortable;

    if (this.sortable) {
      var _self = this;

      this.dragElement = null; // Sorting starts

      itemsWrapper.addEventListener('dragstart', function (evt) {
        _self.dragElement = evt.target; // Remembering an element that will be moved
        // Limiting the movement type

        evt.dataTransfer.effectAllowed = 'move';
        evt.dataTransfer.setData('Text', _self.dragElement.textContent); // Subscribing to the events at dnd

        _self.itemsWrapper.addEventListener('dragover', _self.onDragOver.bind(_self), false);

        _self.itemsWrapper.addEventListener('dragend', _self.onDragEnd.bind(_self), false);

        setTimeout(function () {
          // If this action is performed without setTimeout, then
          // the moved object will be of this class.
          _self.dragElement.classList.add('ghost');
        }, 0);
      }, false);
    }

    this.listenersEnabled = true;
    this.constructedSuccessfully = true;
    this.initialize();
  }

  _createClass(MultiSelectController, [{
    key: "initialize",
    value: function initialize() {
      if (this.constructedSuccessfully === false) {
        console.error('MultiSelectController was not constructed successfully. Could not initialize because of it');
        return;
      }

      this.makeMultiSelect();
      this.addItems();
      this.updateRealInput();
      this.enableListeners(true);
      this.enableMultiSelectOpenButton();
    }
  }, {
    key: "addItems",
    value: function addItems() {
      var dataSetLength = this.dataSet.length;
      var valueFromAttributeLength = this.valuesFromAttribute.length;

      for (var valuesIndex = 0; valuesIndex < valueFromAttributeLength; valuesIndex++) {
        var idFromAttribute = parseInt(this.valuesFromAttribute[valuesIndex]);

        for (var itemIndex = 0; itemIndex < dataSetLength; itemIndex++) {
          var item = this.dataSet[itemIndex];

          if (item.id === idFromAttribute) {
            this.addItem(item.id, item.value);
            break;
          }
        }
      }
    }
    /**
     * Makes the fake input field and multiSelect input field.
     * Focus method is triggered when you hover over items in the menu
     * select method is triggered when you click an item in the list.
     */

  }, {
    key: "makeMultiSelect",
    value: function makeMultiSelect() {
      var self = this;
      var jqueryElement = $(this.multiSelectSelectField);
      return jqueryElement.autocomplete({
        source: this.dataSet,
        minLength: 0,
        focus: function focus(event, ui) {
          return false;
        },
        select: function select(event, ui) {
          $(this.multiSelectSelectField).val("");
          self.addItem(ui.item.id, ui.item.value);
          self.updateRealInput();
          self.autosaveIfNeeded();
          self.enableListeners(true);
          return false;
        }
      });
    }
    /**
     * Make sure we can open the multiSelect field dropdown with the open button
     */

  }, {
    key: "enableMultiSelectOpenButton",
    value: function enableMultiSelectOpenButton() {
      var self = this;
      this.openbutton.addEventListener('click', function (event) {
        $(self.multiSelectSelectField).autocomplete("search", "");
      });
    }
    /**
     * Adds a span tag containing the value given and the data-id property set to id given to
     * the p tag with class items.
     */

  }, {
    key: "addItem",
    value: function addItem(id, value) {
      var self = this;
      if (this.itemsCount() > self.maxItemsToSelect) return;
      var itemElement = document.createElement('p');
      itemElement.classList.add('item');

      if (this.sortable) {
        itemElement.draggable = true;
        value = '<span class="drag-icon"></span><span class="text">' + value + '</span>';
      }

      itemElement.innerHTML = value;
      var removeButton = document.createElement('span');
      removeButton.classList.add('remove');
      itemElement.dataset.id = id;
      itemElement.dataset.sort_order = this.itemsCount();
      removeButton.addEventListener('click', function (itemToRemove) {
        return function () {
          if (!self.listenersEnabled) return;
          self.removeItem(itemToRemove);
        };
      }(id));
      this.itemsWrapper.appendChild(itemElement);
      itemElement.appendChild(removeButton);
    }
  }, {
    key: "itemsCount",
    value: function itemsCount() {
      return this.itemsWrapper.childNodes.length;
    }
  }, {
    key: "removeItem",

    /**
     * Iterates over the child elements of the p element with class items and removes the element that has
     * data-id set to the specified id. Then calls updateRealInput to update the hidden input
     */
    value: function removeItem(id) {
      var items = this.itemsWrapper.children;
      var itemsLength = this.itemsWrapper.children.length;

      for (var index = 0; index < itemsLength; index++) {
        var item = items[index];

        if (parseInt(item.dataset.id) === id) {
          this.itemsWrapper.removeChild(item);
          break;
        }
      }

      this.updateRealInput();
      this.autosaveIfNeeded();
    }
  }, {
    key: "updateRealInput",

    /**
     * Iterates over the child elements of the p element with class items and concatenates their data-id
     * values into a string. After that it sets the hidden input with the id string
     */
    value: function updateRealInput() {
      var ids = [];
      var items = this.itemsWrapper.children;
      var itemsLength = items.length;

      for (var i = 0; i < itemsLength; i++) {
        var item = items[i];
        ids[ids.length] = item.dataset.id;
      }

      var idString = ids.join(',');
      this.input.setAttribute('value', idString);
      var changeEvent = document.createEvent("Event");
      changeEvent.initEvent("change", false, true); // args: string type, boolean bubbles, boolean cancelable

      this.input.dispatchEvent(changeEvent);
    }
  }, {
    key: "autosaveIfNeeded",
    value: function autosaveIfNeeded() {
      if (!this.autosaveUrl) return;
      var itemIds = this.input.getAttribute('value');
      var self = this;
      $.ajax({
        type: "POST",
        url: this.autosaveUrl,
        data: {
          'itemIds': itemIds
        },
        success: function success(response, textStatus, xhr) {
          if (xhr.status === 200) {
            console.log('autosave successfull to url: ' + self.autosaveUrl);
          } else {
            console.error('autosave failure to url (no code 200): ' + self.autosaveUrl + '');
            console.error(response);
          }
        },
        error: function error(message) {
          console.error('autosave failure to url: ' + self.autosaveUrl + '');
          console.error(message);
        },
        headers: {
          'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        },
        dataType: 'json'
      });
    }
  }, {
    key: "enableListeners",
    value: function enableListeners(enable) {
      this.listenersEnabled = enable;
      var length = this.itemsWrapper.children.length; //Add / remove listeners to items

      for (var i = 0; i < length; i++) {
        var item = this.itemsWrapper.children[i];
        var id = item.dataset.id;
        item.classList.remove('readonly');
        this.multiSelectSelectField.classList.remove('hidden');

        if (!enable) {
          item.classList.add('readonly');
          this.multiSelectSelectField.classList.add('hidden');
          this.openbutton.classList.add('hidden');
        }
      }
    }
  }, {
    key: "onDragOver",
    value: function onDragOver(evt) {
      evt.preventDefault();
      evt.dataTransfer.dropEffect = 'move';
      var target = evt.target;

      if (target && target !== this.dragElement && target.nodeName === 'P') {
        // Sorting
        this.itemsWrapper.insertBefore(this.dragElement, target.nextSibling || target);
      }
    }
  }, {
    key: "onDragEnd",
    value: function onDragEnd(evt) {
      evt.preventDefault();
      this.dragElement.classList.remove('ghost');
      this.itemsWrapper.removeEventListener('dragover', this.onDragOver, false);
      this.itemsWrapper.removeEventListener('dragend', this.onDragEnd, false);
      console.log("dragEnd");
      this.updateRealInput();
    }
  }]);

  return MultiSelectController;
}(); //also @See onOff.blade.php


var OnOff = /*#__PURE__*/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 = /*#__PURE__*/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);
    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;
      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 () {
  if (!document.querySelector(".select-menu")) return;
  $(".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');
    }
  });
});
/**
 * Helps managing classes on a button.
 * You can request to add a class and for each time you request to add the class, it will increment a counter.
 * You can also request to remove a class and for each time you do that, it will decrement a counter.
 * When that counter hits 0 it will remove the class.
 * It will keep counter for each unique class you request to add.
 */

var styleClassController = /*#__PURE__*/function () {
  /**
   * Constructor
   *
   * @param {HTMLElement} htmlElement
   */
  function styleClassController(htmlElement) {
    _classCallCheck(this, styleClassController);

    this.constructedSuccessFully = false;

    if (!htmlElement instanceof HTMLElement) {
      console.error('styleClassController: The given htmlElement must be, but was not a HTMLElement');
      return;
    }

    this.htmlElement = htmlElement;
    this.classCounts = {};
    this.constructedSuccessFully = true;
  }
  /**
   * @param {string} styleClass
   */


  _createClass(styleClassController, [{
    key: "requestAddClass",
    value: function requestAddClass(styleClass) {
      if (!this.htmlElement.classList.contains(styleClass)) this.htmlElement.classList.add(styleClass);
      if (!this.classCounts.hasOwnProperty(styleClass)) this.classCounts[styleClass] = 0;
      this.classCounts[styleClass]++;
      return true;
    }
  }, {
    key: "requestRemoveClass",
    value: function requestRemoveClass(styleClass) {
      if (!this.htmlElement.classList.contains(styleClass) || !this.classCounts.hasOwnProperty(styleClass)) return false;
      this.classCounts[styleClass]--;

      if (this.classCounts[styleClass] === 0) {
        delete this.classCounts[styleClass];
        this.htmlElement.classList.remove(styleClass);
      }
    }
  }]);

  return styleClassController;
}();