diff --git a/Build/Sources/TypeScript/form/backend/form-editor/inspector-component.ts b/Build/Sources/TypeScript/form/backend/form-editor/inspector-component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..97e0a4edc760a6bc92a5135da2174d6a7105db48
--- /dev/null
+++ b/Build/Sources/TypeScript/form/backend/form-editor/inspector-component.ts
@@ -0,0 +1,2518 @@
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+/**
+ * Module: @typo3/form/backend/form-editor/inspector-component
+ */
+
+import $ from 'jquery';
+import * as Helper from '@typo3/form/backend/form-editor/helper';
+import Icons from '@typo3/backend/icons';
+import Modal from '@typo3/backend/modal';
+import { MessageUtility } from '@typo3/backend/utility/message-utility';
+import Sortable from 'sortablejs';
+
+import type {
+  FormEditor,
+  ViewModel,
+} from '@typo3/form/backend/form-editor';
+import type {
+  Utility,
+  EditorConfiguration,
+  FormEditorDefinitions,
+  FormElement,
+  FormElementDefinition,
+  PublisherSubscriber,
+} from '@typo3/form/backend/form-editor/core';
+import type {
+  Configuration as HelperConfiguration,
+} from '@typo3/form/backend/form-editor/helper';
+
+interface Configuration extends Partial<HelperConfiguration> {
+  isSortable: boolean,
+}
+
+type PropertyData = Array<{code: string, message: string}>;
+
+const defaultConfiguration: Configuration = {
+  domElementClassNames: {
+    buttonFormElementRemove: 't3-form-remove-element-button',
+    collectionElement: 't3-form-collection-element',
+    finisherEditorPrefix: 't3-form-inspector-finishers-editor-',
+    inspectorEditor: 'form-editor',
+    inspectorInputGroup: 'input-group',
+    validatorEditorPrefix: 't3-form-inspector-validators-editor-'
+  },
+  domElementDataAttributeNames: {
+    contentElementSelectorTarget: 'data-insert-target',
+    finisher: 'data-finisher-identifier',
+    validator: 'data-validator-identifier',
+    randomId: 'data-random-id',
+    randomIdTarget: 'data-random-id-attribute',
+    randomIdIndex: 'data-random-id-number',
+    maximumFileSize: 'data-maximumFileSize'
+  },
+  domElementDataAttributeValues: {
+    collapse: 'actions-view-table-expand',
+    editorControlsInputGroup: 'inspectorEditorControlsGroup',
+    editorWrapper: 'editorWrapper',
+    editorControlsWrapper: 'inspectorEditorControlsWrapper',
+    formElementHeaderEditor: 'inspectorFormElementHeaderEditor',
+    formElementSelectorControlsWrapper: 'inspectorEditorFormElementSelectorControlsWrapper',
+    formElementSelectorSplitButtonContainer: 'inspectorEditorFormElementSelectorSplitButtonContainer',
+    formElementSelectorSplitButtonListContainer: 'inspectorEditorFormElementSelectorSplitButtonListContainer',
+    iconNotAvailable: 'actions-close',
+    inspector: 'inspector',
+    'Inspector-CheckboxEditor': 'Inspector-CheckboxEditor',
+    'Inspector-CollectionElementHeaderEditor': 'Inspector-CollectionElementHeaderEditor',
+    'Inspector-FinishersEditor': 'Inspector-FinishersEditor',
+    'Inspector-FormElementHeaderEditor': 'Inspector-FormElementHeaderEditor',
+    'Inspector-PropertyGridEditor': 'Inspector-PropertyGridEditor',
+    'Inspector-RemoveElementEditor': 'Inspector-RemoveElementEditor',
+    'Inspector-RequiredValidatorEditor': 'Inspector-RequiredValidatorEditor',
+    'Inspector-SingleSelectEditor': 'Inspector-SingleSelectEditor',
+    'Inspector-MultiSelectEditor': 'Inspector-MultiSelectEditor',
+    'Inspector-GridColumnViewPortConfigurationEditor': 'Inspector-GridColumnViewPortConfigurationEditor',
+    'Inspector-TextareaEditor': 'Inspector-TextareaEditor',
+    'Inspector-TextEditor': 'Inspector-TextEditor',
+    'Inspector-Typo3WinBrowserEditor': 'Inspector-Typo3WinBrowserEditor',
+    'Inspector-ValidatorsEditor': 'Inspector-ValidatorsEditor',
+    'Inspector-ValidationErrorMessageEditor': 'Inspector-ValidationErrorMessageEditor',
+
+    inspectorFinishers: 'inspectorFinishers',
+    inspectorValidators: 'inspectorValidators',
+    propertyGridEditorHeaderRow: 'headerRow',
+    propertyGridEditorAddRow: 'addRow',
+    propertyGridEditorAddRowItem: 'addRowItem',
+    propertyGridEditorContainer: 'propertyGridContainer',
+    propertyGridEditorDeleteRow: 'deleteRow',
+    propertyGridEditorLabel: 'label',
+    propertyGridEditorRowItem: 'rowItem',
+    propertyGridEditorColumn: 'column',
+    propertyGridEditorSelectValue: 'selectValue',
+    propertyGridEditorSortRow: 'sortRow',
+    propertyGridEditorValue: 'value',
+    viewportButton: 'viewportButton'
+  },
+  domElementIdNames: {
+    finisherPrefix: 't3-form-inspector-finishers-',
+    validatorPrefix: 't3-form-inspector-validators-'
+  },
+  isSortable: true
+};
+
+let configuration: Configuration = null;
+
+let formEditorApp: FormEditor = null;
+
+function getFormEditorApp(): FormEditor {
+  return formEditorApp;
+}
+
+function getViewModel(): ViewModel {
+  return getFormEditorApp().getViewModel();
+}
+
+function getHelper(_configuration?: HelperConfiguration): typeof Helper {
+  if (getUtility().isUndefinedOrNull(_configuration)) {
+    return Helper.setConfiguration(configuration);
+  }
+  return Helper.setConfiguration(_configuration);
+}
+
+function getUtility(): Utility {
+  return getFormEditorApp().getUtility();
+}
+
+function assert(test: boolean|(() => boolean), message: string, messageCode: number): void {
+  return getFormEditorApp().assert(test, message, messageCode);
+}
+
+function getRootFormElement(): FormElement {
+  return getFormEditorApp().getRootFormElement();
+}
+
+function getCurrentlySelectedFormElement(): FormElement {
+  return getFormEditorApp().getCurrentlySelectedFormElement();
+}
+
+function getPublisherSubscriber(): PublisherSubscriber {
+  return getFormEditorApp().getPublisherSubscriber();
+}
+
+function getFormElementDefinition<T extends keyof FormElementDefinition>(
+  formElement: FormElement | string,
+  formElementDefinitionKey?: T
+): T extends keyof FormElementDefinition ? FormElementDefinition[T] : FormElementDefinition {
+  return getFormEditorApp().getFormElementDefinition(formElement, formElementDefinitionKey);
+}
+
+/**
+ * @publish view/inspector/editor/insert/perform
+ */
+function renderEditorDispatcher(
+  editorConfiguration: EditorConfiguration,
+  editorHtml: HTMLElement | JQuery,
+  collectionElementIdentifier?: string,
+  collectionName?: keyof FormEditorDefinitions
+): void {
+  switch (editorConfiguration.templateName) {
+    case 'Inspector-FormElementHeaderEditor':
+      renderFormElementHeaderEditor(
+        editorConfiguration,
+        editorHtml
+      );
+      break;
+    case 'Inspector-CollectionElementHeaderEditor':
+      renderCollectionElementHeaderEditor(
+        editorConfiguration,
+        editorHtml,
+        collectionElementIdentifier,
+        collectionName
+      );
+      break;
+    case 'Inspector-MaximumFileSizeEditor':
+      renderFileMaxSizeEditor(
+        editorConfiguration,
+        editorHtml
+      );
+      break;
+    case 'Inspector-TextEditor':
+      renderTextEditor(
+        editorConfiguration,
+        editorHtml,
+        collectionElementIdentifier,
+        collectionName
+      );
+      break;
+    case 'Inspector-FinishersEditor':
+      renderCollectionElementSelectionEditor(
+        'finishers',
+        editorConfiguration,
+        editorHtml
+      );
+      break;
+    case 'Inspector-ValidatorsEditor':
+      renderCollectionElementSelectionEditor(
+        'validators',
+        editorConfiguration,
+        editorHtml
+      );
+      break;
+    case 'Inspector-ValidationErrorMessageEditor':
+      renderValidationErrorMessageEditor(
+        editorConfiguration,
+        editorHtml
+      );
+      break;
+    case 'Inspector-RemoveElementEditor':
+      renderRemoveElementEditor(
+        editorConfiguration,
+        editorHtml,
+        collectionElementIdentifier,
+        collectionName
+      );
+      break;
+    case 'Inspector-RequiredValidatorEditor':
+      renderRequiredValidatorEditor(
+        editorConfiguration,
+        editorHtml,
+        collectionElementIdentifier,
+        collectionName
+      );
+      break;
+    case 'Inspector-CheckboxEditor':
+      renderCheckboxEditor(
+        editorConfiguration,
+        editorHtml,
+        collectionElementIdentifier,
+        collectionName
+      );
+      break;
+    case 'Inspector-CountrySelectEditor':
+      renderCountrySelectEditor(
+        editorConfiguration,
+        editorHtml,
+        collectionElementIdentifier,
+        collectionName
+      );
+      break;
+    case 'Inspector-SingleSelectEditor':
+      renderSingleSelectEditor(
+        editorConfiguration,
+        editorHtml,
+        collectionElementIdentifier,
+        collectionName
+      );
+      break;
+    case 'Inspector-MultiSelectEditor':
+      renderMultiSelectEditor(
+        editorConfiguration,
+        editorHtml,
+        collectionElementIdentifier,
+        collectionName
+      );
+      break;
+    case 'Inspector-GridColumnViewPortConfigurationEditor':
+      renderGridColumnViewPortConfigurationEditor(
+        editorConfiguration,
+        editorHtml
+      );
+      break;
+    case 'Inspector-PropertyGridEditor':
+      renderPropertyGridEditor(
+        editorConfiguration,
+        editorHtml,
+        collectionElementIdentifier,
+        collectionName
+      );
+      break;
+    case 'Inspector-TextareaEditor':
+      renderTextareaEditor(
+        editorConfiguration,
+        editorHtml,
+        collectionElementIdentifier,
+        collectionName
+      );
+      break;
+    case 'Inspector-Typo3WinBrowserEditor':
+      renderTypo3WinBrowserEditor(
+        editorConfiguration,
+        editorHtml,
+        collectionElementIdentifier,
+        collectionName
+      );
+      break;
+    default:
+      break;
+  }
+  getPublisherSubscriber().publish('view/inspector/editor/insert/perform', [
+    editorConfiguration, editorHtml, collectionElementIdentifier, collectionName
+  ]);
+}
+
+/**
+ * opens a popup window with the element browser
+ */
+function openTypo3WinBrowser(mode: string, params: string): void {
+  Modal.advanced({
+    type: Modal.types.iframe,
+    content: TYPO3.settings.FormEditor.typo3WinBrowserUrl + '&mode=' + mode + '&bparams=' + params,
+    size: Modal.sizes.large
+  });
+}
+
+/**
+ * Listens on messages sent by ElementBrowser
+ */
+function listenOnElementBrowser(): void {
+  window.addEventListener('message', function (e) {
+    if (!MessageUtility.verifyOrigin(e.origin)) {
+      throw 'Denied message sent by ' + e.origin;
+    }
+
+    if (e.data.actionName === 'typo3:elementBrowser:elementAdded') {
+      if (typeof e.data.fieldName === 'undefined') {
+        throw 'fieldName not defined in message';
+      }
+
+      if (typeof e.data.value === 'undefined') {
+        throw 'value not defined in message';
+      }
+
+      const result = e.data.value.split('_');
+      $(getHelper().getDomElementDataAttribute('contentElementSelectorTarget', 'bracesWithKeyValue', [e.data.fieldName]))
+        .val(result.pop())
+        .trigger('paste');
+    }
+  });
+}
+
+function getCollectionElementClass(
+  collectionName: keyof FormEditorDefinitions,
+  collectionElementIdentifier: string
+): string {
+  if (collectionName === 'finishers') {
+    return getHelper()
+      .getDomElementClassName('finisherEditorPrefix') + collectionElementIdentifier;
+  } else {
+    return getHelper()
+      .getDomElementClassName('validatorEditorPrefix') + collectionElementIdentifier;
+  }
+}
+
+function getCollectionElementId(
+  collectionName: keyof FormEditorDefinitions,
+  collectionElementIdentifier: string,
+  asSelector?: boolean
+): string {
+  if (collectionName === 'finishers') {
+    return getHelper()
+      .getDomElementIdName('finisherPrefix', asSelector) + collectionElementIdentifier;
+  } else {
+    return getHelper()
+      .getDomElementIdName('validatorPrefix', asSelector) + collectionElementIdentifier;
+  }
+}
+
+function addSortableCollectionElementsEvents(
+  sortableDomElement: JQuery,
+  collectionName: keyof FormEditorDefinitions,
+): void {
+  sortableDomElement.addClass(getHelper().getDomElementClassName('sortable'));
+  new Sortable(sortableDomElement.get(0), {
+    draggable: getHelper().getDomElementClassName('collectionElement', true),
+    filter: 'input,textarea,select',
+    preventOnFilter: false,
+    animation: 200,
+    fallbackTolerance: 200,
+    swapThreshold: 0.6,
+    dragClass: 'form-sortable-drag',
+    ghostClass: 'form-sortable-ghost',
+    onEnd: function (e) {
+      let dataAttributeName;
+
+      if (collectionName === 'finishers') {
+        dataAttributeName = getHelper().getDomElementDataAttribute('finisher');
+      } else {
+        dataAttributeName = getHelper().getDomElementDataAttribute('validator');
+      }
+
+      const movedCollectionElementIdentifier = $(e.item).attr(dataAttributeName);
+      const previousCollectionElementIdentifier = $(e.item)
+        .prevAll(getHelper().getDomElementClassName('collectionElement', true))
+        .first()
+        .attr(dataAttributeName);
+      const nextCollectionElementIdentifier = $(e.item)
+        .nextAll(getHelper().getDomElementClassName('collectionElement', true))
+        .first()
+        .attr(dataAttributeName);
+
+      getPublisherSubscriber().publish('view/inspector/collectionElements/dnd/update', [
+        movedCollectionElementIdentifier,
+        previousCollectionElementIdentifier,
+        nextCollectionElementIdentifier,
+        collectionName
+      ]);
+    }
+  });
+}
+
+function setPropertyGridData(
+  editorHtml: HTMLElement | JQuery,
+  multiSelection: boolean,
+  propertyPath: string,
+  propertyPathPrefix: string
+): void {
+  let value;
+
+  if (multiSelection) {
+    const defaultValue: number[] = [];
+
+    $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorContainer') + ' ' +
+      getHelper().getDomElementDataIdentifierSelector('propertyGridEditorSelectValue') + ':checked',
+    $(editorHtml)
+    ).each(function(this: HTMLElement) {
+      value = $(this)
+        .closest(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'))
+        .find(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'))
+        .val();
+
+      if (getUtility().canBeInterpretedAsInteger(value)) {
+        value = parseInt(value, 10);
+      }
+
+      defaultValue.push(value);
+    });
+    getCurrentlySelectedFormElement().set(propertyPathPrefix + 'defaultValue', defaultValue);
+  } else {
+    value = $(
+      getHelper().getDomElementDataIdentifierSelector('propertyGridEditorContainer') + ' ' +
+        getHelper().getDomElementDataIdentifierSelector('propertyGridEditorSelectValue') + ':checked',
+      $(editorHtml)
+    ).first()
+      .closest(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'))
+      .find(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'))
+      .val();
+
+    if (getUtility().canBeInterpretedAsInteger(value)) {
+      value = parseInt(value, 10);
+    }
+
+    getCurrentlySelectedFormElement().set(propertyPathPrefix + 'defaultValue', value, true);
+  }
+
+  const newPropertyData: Array<{_label: string, _value: string}> = [];
+  $(
+    getHelper().getDomElementDataIdentifierSelector('propertyGridEditorContainer') + ' ' +
+    getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'),
+    $(editorHtml)
+  ).each(function(this: HTMLElement) {
+    let value = $(this)
+      .find(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'))
+      .val();
+    const label = $(this)
+      .find(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorLabel'))
+      .val();
+
+    if ('' === value) {
+      value = label;
+    }
+
+    const tmpObject: Record<string, string> = {};
+    tmpObject[value] = label;
+    newPropertyData.push({
+      _label: label,
+      _value: value
+    });
+  });
+
+  getCurrentlySelectedFormElement().set(propertyPathPrefix + propertyPath, newPropertyData);
+  validateCollectionElement(propertyPathPrefix + propertyPath, editorHtml);
+}
+
+function getEditorWrapperDomElement(editorDomElement: HTMLElement | JQuery): JQuery {
+  return $(getHelper().getDomElementDataIdentifierSelector('editorWrapper'), $(editorDomElement));
+}
+
+function getEditorControlsWrapperDomElement(editorDomElement: HTMLElement | JQuery): JQuery {
+  return $(getHelper().getDomElementDataIdentifierSelector('editorControlsWrapper'), $(editorDomElement));
+}
+
+function validateCollectionElement(propertyPath: string, editorHtml: HTMLElement | JQuery): void {
+  let hasError, propertyPrefix, validationResults;
+
+  validationResults = getFormEditorApp().validateCurrentlySelectedFormElementProperty(propertyPath);
+
+  if (validationResults.length > 0) {
+    getHelper()
+      .getTemplatePropertyDomElement('validationErrors', editorHtml)
+      .text(validationResults[0]);
+    getViewModel().setElementValidationErrorClass(
+      getHelper().getTemplatePropertyDomElement('validationErrors', editorHtml)
+    );
+    getViewModel().setElementValidationErrorClass(
+      getEditorControlsWrapperDomElement(editorHtml),
+      'hasError'
+    );
+  } else {
+    getHelper().getTemplatePropertyDomElement('validationErrors', editorHtml).text('');
+    getViewModel().removeElementValidationErrorClass(
+      getHelper().getTemplatePropertyDomElement('validationErrors', editorHtml)
+    );
+    getViewModel().removeElementValidationErrorClass(
+      getEditorControlsWrapperDomElement(editorHtml),
+      'hasError'
+    );
+  }
+
+  validationResults = getFormEditorApp().validateFormElement(getCurrentlySelectedFormElement());
+  propertyPrefix = propertyPath.split('.');
+  propertyPrefix = propertyPrefix[0] + '.' + propertyPrefix[1];
+
+  hasError = false;
+  for (let i = 0, len = validationResults.length; i < len; ++i) {
+    if (
+      validationResults[i].propertyPath.indexOf(propertyPrefix, 0) === 0
+      && validationResults[i].validationResults
+      && validationResults[i].validationResults.length > 0
+    ) {
+      hasError = true;
+      break;
+    }
+  }
+
+  if (hasError) {
+    getViewModel().setElementValidationErrorClass(
+      getEditorControlsWrapperDomElement(editorHtml).closest(getHelper().getDomElementClassName('collectionElement', true))
+    );
+  } else {
+    getViewModel().removeElementValidationErrorClass(
+      getEditorControlsWrapperDomElement(editorHtml).closest(getHelper().getDomElementClassName('collectionElement', true))
+    );
+  }
+}
+
+/**
+ * @throws 1489932939
+ * @throws 1489932940
+ */
+function getFirstAvailableValidationErrorMessage(errorCodes: string[], propertyData: PropertyData): string | null {
+  assert(
+    'array' === $.type(errorCodes),
+    'Invalid configuration "errorCodes"',
+    1489932939
+  );
+  assert(
+    'array' === $.type(propertyData),
+    'Invalid configuration "propertyData"',
+    1489932940
+  );
+
+  for (let i = 0, len1 = errorCodes.length; i < len1; ++i) {
+    for (let j = 0, len2 = propertyData.length; j < len2; ++j) {
+      if (parseInt(errorCodes[i], 10) === parseInt(propertyData[j].code, 10)) {
+        if (getUtility().isNonEmptyString(propertyData[j].message)) {
+          return propertyData[j].message;
+        }
+      }
+    }
+  }
+
+  return null;
+}
+
+/**
+ * @throws 1489932942
+ */
+function renewValidationErrorMessages(
+  errorCodes: string[],
+  propertyData: PropertyData,
+  value: string
+): PropertyData {
+  assert(
+    'array' === $.type(propertyData),
+    'Invalid configuration "propertyData"',
+    1489932942
+  );
+
+  if (
+    !getUtility().isUndefinedOrNull(errorCodes)
+    && 'array' === $.type(errorCodes)
+  ) {
+    const errorCodeSubset: PropertyData = [];
+    for (let i = 0, len1 = errorCodes.length; i < len1; ++i) {
+      let errorCodeFound = false;
+
+      for (let j = 0, len2 = propertyData.length; j < len2; ++j) {
+        if (parseInt(errorCodes[i], 10) === parseInt(propertyData[j].code, 10)) {
+          errorCodeFound = true;
+          if (getUtility().isNonEmptyString(value)) {
+            // error code exists and should be updated because message is not empty
+            propertyData[j].message = value;
+          } else {
+            // error code exists but should be removed because message is empty
+            propertyData.splice(j, 1);
+            --len2;
+          }
+        }
+      }
+
+      if (!errorCodeFound) {
+        // add new codes because message is not empty
+        if (getUtility().isNonEmptyString(value)) {
+          errorCodeSubset.push({
+            code: errorCodes[i],
+            message: value
+          });
+        }
+      }
+    }
+
+    propertyData = propertyData.concat(errorCodeSubset);
+  }
+
+  return propertyData;
+}
+
+/**
+ * @throws 1523904699
+ */
+function setRandomIds(html: JQuery): void {
+  assert(
+    'object' === $.type(html),
+    'Invalid input "html"',
+    1523904699
+  );
+
+  $(getHelper().getDomElementClassName('inspectorEditor', true)).each(function(this: HTMLElement) {
+    const $parent = $(this);
+    const idReplacements: Record<string, string> = {};
+
+    $(getHelper().getDomElementDataAttribute('randomId', 'bracesWithKey'), $parent).each(function(this: HTMLElement) {
+      const $element = $(this),
+        targetAttribute = $element.attr(getHelper().getDomElementDataAttribute('randomIdTarget')),
+        randomIdIndex = $element.attr(getHelper().getDomElementDataAttribute('randomIdIndex'));
+
+      if ($element.is('[' + targetAttribute + ']')) {
+        return;
+      }
+
+      if (!(randomIdIndex in idReplacements)) {
+        idReplacements[randomIdIndex] = 'fe' + Math.floor(Math.random() * 42) + Date.now();
+      }
+      $element.attr(targetAttribute, idReplacements[randomIdIndex]);
+    });
+  });
+}
+
+export function getInspectorDomElement(): JQuery {
+  return $(getHelper().getDomElementDataIdentifierSelector('inspector'));
+}
+
+export function getFinishersContainerDomElement(): JQuery {
+  return $(getHelper().getDomElementDataIdentifierSelector('inspectorFinishers'), getInspectorDomElement());
+}
+
+export function getValidatorsContainerDomElement(): JQuery {
+  return $(getHelper().getDomElementDataIdentifierSelector('inspectorValidators'), getInspectorDomElement());
+}
+
+export function getCollectionElementDomElement(
+  collectionName: keyof FormEditorDefinitions,
+  collectionElementIdentifier: string
+): JQuery {
+  if (collectionName === 'finishers') {
+    return $(getHelper().getDomElementDataAttribute(
+      'finisher',
+      'bracesWithKeyValue',
+      [collectionElementIdentifier]
+    ), getFinishersContainerDomElement());
+  } else {
+    return $(getHelper().getDomElementDataAttribute(
+      'validator',
+      'bracesWithKeyValue',
+      [collectionElementIdentifier]
+    ), getValidatorsContainerDomElement());
+  }
+}
+
+export function renderEditors(
+  formElement?: FormElement | string,
+  callback?: () => void
+): void {
+  if (getUtility().isUndefinedOrNull(formElement)) {
+    formElement = getCurrentlySelectedFormElement();
+  }
+
+  getInspectorDomElement().off().empty();
+
+  const formElementTypeDefinition = getFormElementDefinition(formElement, undefined);
+  if ('array' !== $.type(formElementTypeDefinition.editors)) {
+    return;
+  }
+
+  for (let i = 0, len = formElementTypeDefinition.editors.length; i < len; ++i) {
+    const template = getHelper()
+      .getTemplate(formElementTypeDefinition.editors[i].templateName)
+      .clone();
+    if (!template.length) {
+      continue;
+    }
+    const html = $(template.html());
+
+    $(html)
+      .first()
+      .addClass(getHelper().getDomElementClassName('inspectorEditor'));
+    getInspectorDomElement().append($(html));
+
+    setRandomIds(html);
+    renderEditorDispatcher(formElementTypeDefinition.editors[i], html);
+  }
+
+  if ('function' === $.type(callback)) {
+    callback();
+  }
+}
+
+/**
+ * @publish view/inspector/collectionElements/dnd/update
+ * @throws 1478354853
+ * @throws 1478354854
+ */
+export function renderCollectionElementEditors(
+  collectionName: keyof FormEditorDefinitions,
+  collectionElementIdentifier: string
+): void {
+  let collapseWrapper, collectionContainer;
+
+  assert(
+    getUtility().isNonEmptyString(collectionName),
+    'Invalid parameter "collectionName"',
+    1478354853
+  );
+  assert(
+    getUtility().isNonEmptyString(collectionElementIdentifier),
+    'Invalid parameter "collectionElementIdentifier"',
+    1478354854
+  );
+
+  const collectionElementConfiguration = getFormEditorApp().getPropertyCollectionElementConfiguration(
+    collectionElementIdentifier,
+    collectionName
+  );
+  if ('array' !== $.type(collectionElementConfiguration.editors)) {
+    return;
+  }
+
+  const collectionContainerElementWrapper = $('<div></div>').addClass(getHelper().getDomElementClassName('collectionElement'));
+  if (collectionName === 'finishers') {
+    collectionContainer = getFinishersContainerDomElement();
+    collectionContainerElementWrapper
+      .attr(getHelper().getDomElementDataAttribute('finisher'), collectionElementIdentifier);
+  } else {
+    collectionContainer = getValidatorsContainerDomElement();
+    collectionContainerElementWrapper
+      .attr(getHelper().getDomElementDataAttribute('validator'), collectionElementIdentifier);
+  }
+  collectionContainer.append(collectionContainerElementWrapper);
+
+  const collectionElementEditorsLength = collectionElementConfiguration.editors.length;
+  if (
+    collectionElementEditorsLength > 0
+    && collectionElementConfiguration.editors[0].identifier === 'header'
+  ) {
+    collapseWrapper = $('<div role="tabpanel"></div>')
+      .addClass('panel-collapse collapse')
+      .prop('id', getCollectionElementId(
+        collectionName,
+        collectionElementIdentifier
+      ));
+  }
+
+  for (let i = 0; i < collectionElementEditorsLength; ++i) {
+    const template = getHelper()
+      .getTemplate(collectionElementConfiguration.editors[i].templateName)
+      .clone();
+    if (!template.length) {
+      continue;
+    }
+    const html = $(template.html());
+
+    $(html).first()
+      .addClass(getCollectionElementClass(
+        collectionName,
+        collectionElementConfiguration.editors[i].identifier
+      ))
+      .addClass(getHelper().getDomElementClassName('inspectorEditor'));
+
+    if (i === 0 && collapseWrapper) {
+      getCollectionElementDomElement(collectionName, collectionElementIdentifier)
+        .append(html)
+        .append(collapseWrapper);
+    } else if (
+      i === (collectionElementEditorsLength - 1)
+      && collapseWrapper
+      && collectionElementConfiguration.editors[i].identifier === 'removeButton'
+    ) {
+      getCollectionElementDomElement(collectionName, collectionElementIdentifier).append(html);
+    } else if (i > 0 && collapseWrapper) {
+      collapseWrapper.append(html);
+    } else {
+      getCollectionElementDomElement(collectionName, collectionElementIdentifier).append(html);
+    }
+
+    setRandomIds(html);
+    renderEditorDispatcher(
+      collectionElementConfiguration.editors[i],
+      html,
+      collectionElementIdentifier,
+      collectionName
+    );
+  }
+
+  if (
+    (
+      collectionElementEditorsLength === 2
+      && collectionElementConfiguration.editors[0].identifier === 'header'
+      && collectionElementConfiguration.editors[1].identifier === 'removeButton'
+    ) || (
+      collectionElementEditorsLength === 1
+      && collectionElementConfiguration.editors[0].identifier === 'header'
+    )
+  ) {
+    $(getHelper().getDomElementDataIdentifierSelector('collapse'), collectionContainerElementWrapper).remove();
+  }
+
+  if (configuration.isSortable) {
+    addSortableCollectionElementsEvents(collectionContainer, collectionName);
+  }
+}
+
+/**
+ * @publish view/inspector/collectionElement/existing/selected
+ * @publish view/inspector/collectionElement/new/selected
+ * @throws 1475423098
+ * @throws 1475423099
+ * @throws 1475423100
+ * @throws 1475423101
+ * @throws 1478362968
+ */
+export function renderCollectionElementSelectionEditor(
+  collectionName: keyof FormEditorDefinitions,
+  editorConfiguration: EditorConfiguration,
+  editorHtml: HTMLElement | JQuery,
+): void {
+  let alreadySelectedCollectionElements, collectionContainer,
+    removeSelectElement;
+  assert(
+    getUtility().isNonEmptyString(collectionName),
+    'Invalid configuration "collectionName"',
+    1478362968
+  );
+  assert(
+    'object' === $.type(editorConfiguration),
+    'Invalid parameter "editorConfiguration"',
+    1475423098
+  );
+  assert(
+    'object' === $.type(editorHtml),
+    'Invalid parameter "editorHtml"',
+    1475423099
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.label),
+    'Invalid configuration "label"',
+    1475423100
+  );
+  assert(
+    'array' === $.type(editorConfiguration.selectOptions),
+    'Invalid configuration "selectOptions"',
+    1475423101
+  );
+
+  if (collectionName === 'finishers') {
+    collectionContainer = getFinishersContainerDomElement();
+    alreadySelectedCollectionElements = getRootFormElement().get(collectionName);
+  } else {
+    collectionContainer = getValidatorsContainerDomElement();
+    alreadySelectedCollectionElements = getCurrentlySelectedFormElement().get(collectionName);
+  }
+
+  collectionContainer.off().empty();
+
+  getHelper().getTemplatePropertyDomElement('label', editorHtml).text(editorConfiguration.label);
+  const selectElement = getHelper().getTemplatePropertyDomElement('selectOptions', editorHtml);
+
+  if (!getUtility().isUndefinedOrNull(alreadySelectedCollectionElements)) {
+    for (let i = 0, len = alreadySelectedCollectionElements.length; i < len; ++i) {
+      getPublisherSubscriber().publish('view/inspector/collectionElement/existing/selected', [
+        alreadySelectedCollectionElements[i].identifier,
+        collectionName
+      ]);
+    }
+  }
+
+  removeSelectElement = true;
+  for (let i = 0, len1 = editorConfiguration.selectOptions.length; i < len1; ++i) {
+    let appendOption = true;
+    if (!getUtility().isUndefinedOrNull(alreadySelectedCollectionElements)) {
+      for (let j = 0, len2 = alreadySelectedCollectionElements.length; j < len2; ++j) {
+        if (alreadySelectedCollectionElements[j].identifier === editorConfiguration.selectOptions[i].value) {
+          appendOption = false;
+          break;
+        }
+      }
+    }
+    if (appendOption) {
+      selectElement.append(new Option(
+        editorConfiguration.selectOptions[i].label,
+        editorConfiguration.selectOptions[i].value
+      ));
+      if (editorConfiguration.selectOptions[i].value !== '') {
+        removeSelectElement = false;
+      }
+    }
+  }
+
+  if (removeSelectElement) {
+    selectElement.off().empty().remove();
+  }
+
+  selectElement.on('change', function(this: HTMLSelectElement) {
+    if ($(this).val() !== '') {
+      const value = $(this).val();
+      $('option[value="' + value + '"]', $(this)).remove();
+
+      getFormEditorApp().getPublisherSubscriber().publish(
+        'view/inspector/collectionElement/new/selected',
+        [value, collectionName]
+      );
+    }
+  });
+}
+
+/**
+ * @throws 1475421525
+ * @throws 1475421526
+ * @throws 1475421527
+ * @throws 1475421528
+ */
+export function renderFormElementHeaderEditor(
+  editorConfiguration: EditorConfiguration,
+  editorHtml: HTMLElement | JQuery,
+): void {
+  assert('object' === $.type(editorConfiguration), 'Invalid parameter "editorConfiguration"', 1475421525);
+  assert('object' === $.type(editorHtml), 'Invalid parameter "editorHtml"', 1475421526);
+
+  Icons.getIcon(
+    getFormElementDefinition(getCurrentlySelectedFormElement(), 'iconIdentifier'),
+    Icons.sizes.small,
+    null,
+    Icons.states.default
+  ).then(function(icon) {
+    getHelper().getTemplatePropertyDomElement('header-label', editorHtml)
+      .append($(icon).addClass(getHelper().getDomElementClassName('icon')))
+      .append(buildTitleByFormElement());
+  });
+}
+
+/**
+ * @throws 1475421257
+ * @throws 1475421258
+ * @throws 1475421259
+ */
+export function renderCollectionElementHeaderEditor(
+  editorConfiguration: EditorConfiguration,
+  editorHtml: HTMLElement | JQuery,
+  collectionElementIdentifier: string,
+  collectionName: keyof FormEditorDefinitions
+): void {
+  assert(
+    'object' === $.type(editorConfiguration),
+    'Invalid parameter "editorConfiguration"',
+    1475421258
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.label),
+    'Invalid configuration "label"',
+    1475421257
+  );
+  assert(
+    'object' === $.type(editorHtml),
+    'Invalid parameter "editorHtml"',
+    1475421259
+  );
+
+  const setData = function(icon?: string) {
+    if (icon) {
+      getHelper()
+        .getTemplatePropertyDomElement('header-label', editorHtml)
+        .prepend($(icon));
+    }
+
+    const editors = getFormEditorApp().getPropertyCollectionElementConfiguration(
+      collectionElementIdentifier,
+      collectionName
+    ).editors;
+
+    if (!(
+      (
+        editors.length === 2
+        && editors[0].identifier === 'header'
+        && editors[1].identifier === 'removeButton'
+      ) || (
+        editors.length === 1
+        && editors[0].identifier === 'header'
+      ))
+    ) {
+      Icons.getIcon(
+        getHelper().getDomElementDataAttributeValue('collapse'),
+        Icons.sizes.small,
+        null,
+        Icons.states.default,
+        Icons.markupIdentifiers.inline
+      ).then(function(icon) {
+        const iconWrap = $('<a></a>')
+          .attr('href', getCollectionElementId(collectionName, collectionElementIdentifier, true))
+          .attr('data-bs-toggle', 'collapse')
+          .attr('aria-expanded', 'false')
+          .attr('aria-controls', getCollectionElementId(collectionName, collectionElementIdentifier))
+          .addClass('collapsed')
+          .append($(icon));
+
+        getHelper()
+          .getTemplatePropertyDomElement('header-label', editorHtml)
+          .prepend(iconWrap);
+      });
+    }
+  }
+
+  const collectionElementConfiguration = getFormEditorApp().getFormEditorDefinition(collectionName, collectionElementIdentifier);
+  if ('iconIdentifier' in collectionElementConfiguration) {
+    Icons.getIcon(
+      collectionElementConfiguration.iconIdentifier,
+      Icons.sizes.small,
+      null,
+      Icons.states.default
+    ).then(function(icon) {
+      setData(icon);
+    });
+  } else {
+    setData();
+  }
+
+  if (editorConfiguration.label) {
+    getHelper().getTemplatePropertyDomElement('label', editorHtml).append(editorConfiguration.label);
+  }
+}
+
+export function renderFileMaxSizeEditor(
+  editorConfiguration: EditorConfiguration,
+  editorHtml: HTMLElement | JQuery,
+): void {
+  assert(
+    'object' === $.type(editorConfiguration),
+    'Invalid parameter "editorConfiguration"',
+    1475421258
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.label),
+    'Invalid configuration "label"',
+    1475421257
+  );
+  assert(
+    'object' === $.type(editorHtml),
+    'Invalid parameter "editorHtml"',
+    1475421259
+  );
+
+  if (editorConfiguration.label) {
+    const element = getHelper().getTemplatePropertyDomElement('label', editorHtml);
+    const maximumFileSize = element.attr(getHelper().getDomElementDataAttribute('maximumFileSize'));
+    element.append(editorConfiguration.label.replace('{0}', maximumFileSize));
+  }
+}
+
+/**
+ * @throws 1475421053
+ * @throws 1475421054
+ * @throws 1475421055
+ * @throws 1475421056
+ */
+export function renderTextEditor(
+  editorConfiguration: EditorConfiguration,
+  editorHtml: HTMLElement | JQuery,
+  collectionElementIdentifier: string,
+  collectionName: keyof FormEditorDefinitions
+): void {
+  assert(
+    'object' === $.type(editorConfiguration),
+    'Invalid parameter "editorConfiguration"',
+    1475421053
+  );
+  assert(
+    'object' === $.type(editorHtml),
+    'Invalid parameter "editorHtml"',
+    1475421054
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.label),
+    'Invalid configuration "label"',
+    1475421055
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.propertyPath),
+    'Invalid configuration "propertyPath"',
+    1475421056
+  );
+
+  getHelper()
+    .getTemplatePropertyDomElement('label', editorHtml)
+    .append(editorConfiguration.label);
+  if (getUtility().isNonEmptyString(editorConfiguration.fieldExplanationText)) {
+    getHelper()
+      .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
+      .text(editorConfiguration.fieldExplanationText);
+  } else {
+    getHelper()
+      .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
+      .remove();
+  }
+
+  if (getUtility().isNonEmptyString(editorConfiguration.placeholder)) {
+    getHelper()
+      .getTemplatePropertyDomElement('propertyPath', editorHtml)
+      .attr('placeholder', editorConfiguration.placeholder);
+  }
+
+  const propertyPath = getFormEditorApp().buildPropertyPath(
+    editorConfiguration.propertyPath,
+    collectionElementIdentifier,
+    collectionName
+  );
+  const propertyData = getCurrentlySelectedFormElement().get(propertyPath);
+
+  validateCollectionElement(propertyPath, editorHtml);
+
+  getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).val(propertyData);
+
+  if (
+    !getUtility().isUndefinedOrNull(editorConfiguration.additionalElementPropertyPaths)
+    && 'array' === $.type(editorConfiguration.additionalElementPropertyPaths)
+  ) {
+    for (let i = 0, len = editorConfiguration.additionalElementPropertyPaths.length; i < len; ++i) {
+      getCurrentlySelectedFormElement().set(editorConfiguration.additionalElementPropertyPaths[i], propertyData);
+    }
+  }
+
+  renderFormElementSelectorEditorAddition(editorConfiguration, editorHtml, propertyPath);
+
+  getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).on('keyup paste', function(this: HTMLInputElement) {
+    if (
+      !!editorConfiguration.doNotSetIfPropertyValueIsEmpty
+      && !getUtility().isNonEmptyString($(this).val())
+    ) {
+      getCurrentlySelectedFormElement().unset(propertyPath);
+    } else {
+      getCurrentlySelectedFormElement().set(propertyPath, $(this).val());
+    }
+    validateCollectionElement(propertyPath, editorHtml);
+    if (
+      !getUtility().isUndefinedOrNull(editorConfiguration.additionalElementPropertyPaths)
+      && 'array' === $.type(editorConfiguration.additionalElementPropertyPaths)
+    ) {
+      for (let i = 0, len = editorConfiguration.additionalElementPropertyPaths.length; i < len; ++i) {
+        if (
+          !!editorConfiguration.doNotSetIfPropertyValueIsEmpty
+          && !getUtility().isNonEmptyString($(this).val())
+        ) {
+          getCurrentlySelectedFormElement().unset(editorConfiguration.additionalElementPropertyPaths[i]);
+        } else {
+          getCurrentlySelectedFormElement().set(editorConfiguration.additionalElementPropertyPaths[i], $(this).val());
+        }
+      }
+    }
+  });
+}
+
+/**
+ * @throws 1489874120
+ * @throws 1489874121
+ * @throws 1489874122
+ * @throws 1489874123
+ */
+export function renderValidationErrorMessageEditor(
+  editorConfiguration: EditorConfiguration,
+  editorHtml: HTMLElement | JQuery
+): void {
+  assert(
+    'object' === $.type(editorConfiguration),
+    'Invalid parameter "editorConfiguration"',
+    1489874121
+  );
+  assert(
+    'object' === $.type(editorHtml),
+    'Invalid parameter "editorHtml"',
+    1489874122
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.label),
+    'Invalid configuration "label"',
+    1489874123
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.propertyPath),
+    'Invalid configuration "propertyPath"',
+    1489874124
+  );
+
+  getHelper()
+    .getTemplatePropertyDomElement('label', editorHtml)
+    .append(editorConfiguration.label);
+  if (getUtility().isNonEmptyString(editorConfiguration.fieldExplanationText)) {
+    getHelper()
+      .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
+      .text(editorConfiguration.fieldExplanationText);
+  } else {
+    getHelper()
+      .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
+      .remove();
+  }
+
+  const propertyPath = getFormEditorApp().buildPropertyPath(
+    editorConfiguration.propertyPath
+  );
+
+  let propertyData: PropertyData = getCurrentlySelectedFormElement().get(propertyPath);
+
+  if (
+    !getUtility().isUndefinedOrNull(propertyData)
+    && 'array' === $.type(propertyData)
+  ) {
+    const validationErrorMessage = getFirstAvailableValidationErrorMessage(editorConfiguration.errorCodes, propertyData);
+
+    if (!getUtility().isUndefinedOrNull(validationErrorMessage)) {
+      getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).val(validationErrorMessage);
+    }
+  }
+
+  getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).on('keyup paste', function(this: HTMLInputElement) {
+    propertyData = getCurrentlySelectedFormElement().get(propertyPath);
+    if (getUtility().isUndefinedOrNull(propertyData)) {
+      propertyData = [];
+    }
+    getCurrentlySelectedFormElement().set(propertyPath, renewValidationErrorMessages(
+      editorConfiguration.errorCodes,
+      propertyData,
+      $(this).val()
+    ));
+  });
+}
+
+/**
+ * @throws 1674826430
+ * @throws 1674826431
+ * @throws 1674826432
+ */
+export function renderCountrySelectEditor(
+  editorConfiguration: EditorConfiguration,
+  editorHtml: HTMLElement | JQuery,
+  collectionElementIdentifier: string,
+  collectionName: keyof FormEditorDefinitions
+): void {
+  assert(
+    'object' === $.type(editorConfiguration),
+    'Invalid parameter "editorConfiguration"',
+    1674826430
+  );
+  assert(
+    'object' === $.type(editorHtml),
+    'Invalid parameter "editorHtml"',
+    1674826431
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.label),
+    'Invalid configuration "label"',
+    1674826432
+  );
+
+  const propertyPath = getFormEditorApp().buildPropertyPath(
+    editorConfiguration.propertyPath,
+    collectionElementIdentifier,
+    collectionName
+  );
+
+  getHelper()
+    .getTemplatePropertyDomElement('label', editorHtml)
+    .append(editorConfiguration.label);
+
+  const selectElement = getHelper()
+    .getTemplatePropertyDomElement('selectOptions', editorHtml);
+
+  const propertyData: Record<string, string> = getCurrentlySelectedFormElement().get(propertyPath) || {};
+
+  const options = $('option', selectElement);
+  selectElement.empty();
+
+  for (let i = 0, len = options.length; i < len; ++i) {
+    let selected = false;
+
+    for (const propertyDataKey of Object.keys(propertyData)) {
+      if ((options[i] as HTMLOptionElement).value === propertyData[propertyDataKey]) {
+        selected = true;
+        break;
+      }
+    }
+
+    const option = new Option((options[i] as HTMLOptionElement).text, i.toString(), false, selected);
+    $(option).data({ value: (options[i] as HTMLOptionElement).value });
+    selectElement.append(option);
+  }
+
+  selectElement.on('change', function(this: HTMLSelectElement) {
+    const selectValues: string[] = [];
+    $('option:selected', $(this)).each(function(this: HTMLOptionElement) {
+      selectValues.push($(this).data('value'));
+    });
+
+    getCurrentlySelectedFormElement().set(propertyPath, selectValues);
+  });
+}
+
+/**
+ * @throws 1475421048
+ * @throws 1475421049
+ * @throws 1475421050
+ * @throws 1475421051
+ * @throws 1475421052
+ */
+export function renderSingleSelectEditor(
+  editorConfiguration: EditorConfiguration,
+  editorHtml: HTMLElement | JQuery,
+  collectionElementIdentifier: string,
+  collectionName: keyof FormEditorDefinitions
+): void {
+  assert(
+    'object' === $.type(editorConfiguration),
+    'Invalid parameter "editorConfiguration"',
+    1475421048
+  );
+  assert(
+    'object' === $.type(editorHtml),
+    'Invalid parameter "editorHtml"',
+    1475421049
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.label),
+    'Invalid configuration "label"',
+    1475421050
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.propertyPath),
+    'Invalid configuration "propertyPath"',
+    1475421051
+  );
+  assert(
+    'array' === $.type(editorConfiguration.selectOptions),
+    'Invalid configuration "selectOptions"',
+    1475421052
+  );
+
+  const propertyPath = getFormEditorApp().buildPropertyPath(
+    editorConfiguration.propertyPath,
+    collectionElementIdentifier,
+    collectionName
+  );
+
+  getHelper()
+    .getTemplatePropertyDomElement('label', editorHtml)
+    .append(editorConfiguration.label);
+
+  const selectElement = getHelper()
+    .getTemplatePropertyDomElement('selectOptions', editorHtml);
+
+  const propertyData = getCurrentlySelectedFormElement().get(propertyPath);
+
+  for (let i = 0, len = editorConfiguration.selectOptions.length; i < len; ++i) {
+    let option;
+
+    if (editorConfiguration.selectOptions[i].value === propertyData) {
+      option = new Option(editorConfiguration.selectOptions[i].label, i.toString(), false, true);
+    } else {
+      option = new Option(editorConfiguration.selectOptions[i].label, i.toString());
+    }
+    $(option).data({ value: editorConfiguration.selectOptions[i].value });
+    selectElement.append(option);
+  }
+
+  selectElement.on('change', function(this: HTMLSelectElement) {
+    getCurrentlySelectedFormElement().set(propertyPath, $('option:selected', $(this)).data('value'));
+  });
+}
+
+/**
+ * @throws 1485712399
+ * @throws 1485712400
+ * @throws 1485712401
+ * @throws 1485712402
+ * @throws 1485712403
+ */
+export function renderMultiSelectEditor(
+  editorConfiguration: EditorConfiguration,
+  editorHtml: HTMLElement | JQuery,
+  collectionElementIdentifier: string,
+  collectionName: keyof FormEditorDefinitions
+): void {
+  assert(
+    'object' === $.type(editorConfiguration),
+    'Invalid parameter "editorConfiguration"',
+    1485712399
+  );
+  assert(
+    'object' === $.type(editorHtml),
+    'Invalid parameter "editorHtml"',
+    1485712400
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.label),
+    'Invalid configuration "label"',
+    1485712401
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.propertyPath),
+    'Invalid configuration "propertyPath"',
+    1485712402
+  );
+  assert(
+    'array' === $.type(editorConfiguration.selectOptions),
+    'Invalid configuration "selectOptions"',
+    1485712403
+  );
+
+  const propertyPath = getFormEditorApp().buildPropertyPath(
+    editorConfiguration.propertyPath,
+    collectionElementIdentifier,
+    collectionName
+  );
+
+  getHelper()
+    .getTemplatePropertyDomElement('label', editorHtml)
+    .append(editorConfiguration.label);
+
+  const selectElement = getHelper()
+    .getTemplatePropertyDomElement('selectOptions', editorHtml);
+
+  const propertyData: Record<string, string> = getCurrentlySelectedFormElement().get(propertyPath) || {};
+
+  for (let i = 0, len1 = editorConfiguration.selectOptions.length; i < len1; ++i) {
+    let option = null;
+    for (const propertyDataKey of Object.keys(propertyData)) {
+      if (editorConfiguration.selectOptions[i].value === propertyData[propertyDataKey]) {
+        option = new Option(editorConfiguration.selectOptions[i].label, i.toString(), false, true);
+        break;
+      }
+    }
+
+    if (!option) {
+      option = new Option(editorConfiguration.selectOptions[i].label, i.toString());
+    }
+
+    $(option).data({ value: editorConfiguration.selectOptions[i].value });
+
+    selectElement.append(option);
+  }
+
+  selectElement.on('change', function(this: HTMLSelectElement) {
+    const selectValues: string[] = [];
+    $('option:selected', $(this)).each(function(this: HTMLOptionElement) {
+      selectValues.push($(this).data('value'));
+    });
+
+    getCurrentlySelectedFormElement().set(propertyPath, selectValues);
+  });
+}
+
+/**
+ * @throws 1489528242
+ * @throws 1489528243
+ * @throws 1489528244
+ * @throws 1489528245
+ * @throws 1489528246
+ * @throws 1489528247
+ */
+export function renderGridColumnViewPortConfigurationEditor(
+  editorConfiguration: EditorConfiguration,
+  editorHtml: HTMLElement | JQuery
+): void {
+  assert(
+    'object' === $.type(editorConfiguration),
+    'Invalid parameter "editorConfiguration"',
+    1489528242
+  );
+  assert(
+    'object' === $.type(editorHtml),
+    'Invalid parameter "editorHtml"',
+    1489528243
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.label),
+    'Invalid configuration "label"',
+    1489528244
+  );
+  assert(
+    'array' === $.type(editorConfiguration.configurationOptions.viewPorts),
+    'Invalid configurationOptions "viewPorts"',
+    1489528245
+  );
+  assert(
+    !getUtility().isUndefinedOrNull(editorConfiguration.configurationOptions.numbersOfColumnsToUse.label),
+    'Invalid configurationOptions "numbersOfColumnsToUse"',
+    1489528246
+  );
+  assert(
+    !getUtility().isUndefinedOrNull(editorConfiguration.configurationOptions.numbersOfColumnsToUse.propertyPath),
+    'Invalid configuration "selectOptions"',
+    1489528247
+  );
+
+  if (!getFormElementDefinition(getCurrentlySelectedFormElement().get('__parentRenderable'), '_isGridRowFormElement')) {
+    editorHtml.remove();
+    return;
+  }
+
+  getHelper()
+    .getTemplatePropertyDomElement('label', editorHtml)
+    .append(editorConfiguration.label);
+
+
+  const viewportButtonTemplate = $(getHelper()
+    .getDomElementDataIdentifierSelector('viewportButton'), $(editorHtml))
+    .clone();
+
+  $(getHelper()
+    .getDomElementDataIdentifierSelector('viewportButton'), $(editorHtml))
+    .remove();
+
+  const numbersOfColumnsTemplate = getHelper()
+    .getTemplatePropertyDomElement('numbersOfColumnsToUse', $(editorHtml))
+    .clone();
+
+  getHelper()
+    .getTemplatePropertyDomElement('numbersOfColumnsToUse', $(editorHtml))
+    .remove();
+
+  const editorControlsWrapper = getEditorControlsWrapperDomElement(editorHtml);
+
+  const initNumbersOfColumnsField = function(element: JQuery) {
+    getHelper().getTemplatePropertyDomElement('numbersOfColumnsToUse', $(editorHtml))
+      .off()
+      .empty()
+      .remove();
+
+    const numbersOfColumnsTemplateClone = $(numbersOfColumnsTemplate).clone(true, true);
+    getEditorWrapperDomElement(editorHtml).after(numbersOfColumnsTemplateClone);
+
+    $('input', numbersOfColumnsTemplateClone).focus();
+
+    getHelper()
+      .getTemplatePropertyDomElement('numbersOfColumnsToUse-label', numbersOfColumnsTemplateClone)
+      .append(
+        editorConfiguration.configurationOptions.numbersOfColumnsToUse.label
+          .replace('{@viewPortLabel}', element.data('viewPortLabel'))
+      );
+
+    getHelper()
+      .getTemplatePropertyDomElement('numbersOfColumnsToUse-fieldExplanationText', numbersOfColumnsTemplateClone)
+      .append(editorConfiguration.configurationOptions.numbersOfColumnsToUse.fieldExplanationText);
+
+    const propertyPath = editorConfiguration.configurationOptions.numbersOfColumnsToUse.propertyPath
+      .replace('{@viewPortIdentifier}', element.data('viewPortIdentifier'));
+
+    getHelper()
+      .getTemplatePropertyDomElement('numbersOfColumnsToUse-propertyPath', numbersOfColumnsTemplateClone)
+      .val(getCurrentlySelectedFormElement().get(propertyPath));
+
+    getHelper().getTemplatePropertyDomElement('numbersOfColumnsToUse-propertyPath', numbersOfColumnsTemplateClone).on('keyup paste change', function(this: HTMLInputElement) {
+      const that = $(this);
+      if (!$.isNumeric(that.val())) {
+        that.val('');
+      }
+      getCurrentlySelectedFormElement().set(propertyPath, that.val());
+    });
+  };
+
+  for (let i = 0, len = editorConfiguration.configurationOptions.viewPorts.length; i < len; ++i) {
+    const viewPortIdentifier = editorConfiguration.configurationOptions.viewPorts[i].viewPortIdentifier;
+    const viewPortLabel = editorConfiguration.configurationOptions.viewPorts[i].label;
+
+    const viewportButtonTemplateClone = $(viewportButtonTemplate).clone(true, true);
+    viewportButtonTemplateClone.text(viewPortIdentifier);
+    viewportButtonTemplateClone.data('viewPortIdentifier', viewPortIdentifier);
+    viewportButtonTemplateClone.data('viewPortLabel', viewPortLabel);
+    viewportButtonTemplateClone.attr('title', viewPortLabel);
+    editorControlsWrapper.append(viewportButtonTemplateClone);
+
+    if (i === (len - 1)) {
+      const numbersOfColumnsTemplateClone = $(numbersOfColumnsTemplate).clone(true, true);
+      getEditorWrapperDomElement(editorHtml).after(numbersOfColumnsTemplateClone);
+      initNumbersOfColumnsField(viewportButtonTemplateClone);
+      viewportButtonTemplateClone.addClass(getHelper().getDomElementClassName('active'));
+    }
+
+    $('button', editorControlsWrapper).on('click', function(this: HTMLButtonElement) {
+      const that = $(this);
+
+      $('button', editorControlsWrapper).removeClass(getHelper().getDomElementClassName('active'));
+      that.addClass(getHelper().getDomElementClassName('active'));
+
+      initNumbersOfColumnsField(that);
+    });
+  }
+}
+
+/**
+ * @throws 1475419226
+ * @throws 1475419227
+ * @throws 1475419228
+ * @throws 1475419229
+ * @throws 1475419230
+ * @throws 1475419231
+ * @throws 1475419232
+ */
+export function renderPropertyGridEditor(
+  editorConfiguration: EditorConfiguration,
+  editorHtml: HTMLElement | JQuery,
+  collectionElementIdentifier: string,
+  collectionName: keyof FormEditorDefinitions
+): void {
+  assert(
+    'object' === $.type(editorConfiguration),
+    'Invalid parameter "editorConfiguration"',
+    1475419226
+  );
+  assert(
+    'object' === $.type(editorHtml),
+    'Invalid parameter "editorHtml"',
+    1475419227
+  );
+  assert(
+    'boolean' === $.type(editorConfiguration.enableAddRow),
+    'Invalid configuration "enableAddRow"',
+    1475419228
+  );
+  assert(
+    'boolean' === $.type(editorConfiguration.enableDeleteRow),
+    'Invalid configuration "enableDeleteRow"',
+    1475419230
+  );
+  assert(
+    'boolean' === $.type(editorConfiguration.isSortable),
+    'Invalid configuration "isSortable"',
+    1475419229
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.propertyPath),
+    'Invalid configuration "propertyPath"',
+    1475419231
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.label),
+    'Invalid configuration "label"',
+    1475419232
+  );
+
+  getHelper().getTemplatePropertyDomElement('label', editorHtml)
+    .append(editorConfiguration.label);
+  if (getUtility().isNonEmptyString(editorConfiguration.fieldExplanationText)) {
+    getHelper()
+      .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
+      .text(editorConfiguration.fieldExplanationText);
+  } else {
+    getHelper()
+      .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
+      .remove();
+  }
+
+  let propertyPathPrefix = getFormEditorApp().buildPropertyPath(
+    undefined,
+    collectionElementIdentifier,
+    collectionName,
+    undefined,
+    true
+  );
+  if (getUtility().isNonEmptyString(propertyPathPrefix)) {
+    propertyPathPrefix = propertyPathPrefix + '.';
+  }
+
+  let useLabelAsFallbackValue: boolean;
+  if (getUtility().isUndefinedOrNull(editorConfiguration.useLabelAsFallbackValue)) {
+    useLabelAsFallbackValue = true;
+  } else {
+    useLabelAsFallbackValue = editorConfiguration.useLabelAsFallbackValue;
+  }
+
+  let gridColumns = [
+    { name: 'label', title: 'Label' },
+    { name: 'value', title: 'Value' },
+    { name: 'selected', title: 'Selected' },
+  ];
+  if (getUtility().isNonEmptyArray(editorConfiguration.gridColumns)) {
+    gridColumns = editorConfiguration.gridColumns;
+  }
+  const orderedGridColumnNames = gridColumns.map(function(item) {
+    return item.name;
+  });
+  const orderedGridColumnTitles = gridColumns.map(function(item) {
+    return item.title || null;
+  });
+
+  $([
+    getHelper().getDomElementDataIdentifierSelector('propertyGridEditorHeaderRow'),
+    getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'),
+    getHelper().getDomElementDataIdentifierSelector('propertyGridEditorAddRowItem'),
+  ].join(','), $(editorHtml)).each(function (i, row) {
+    const $columns = $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorColumn'), row);
+    const $columnsAfter = $columns.last().nextAll();
+    const columnsByName: Record<string, JQuery> = {};
+
+    // Collect columns by names, skip undesired columns
+    $columns
+      .detach()
+      .each(function(i, element) {
+        const $column = $(element);
+        const columnName = $column.data('column');
+
+        if (!orderedGridColumnNames.includes(columnName)) {
+          return;
+        }
+
+        columnsByName[columnName] = $column;
+      });
+
+    // Insert columns in desired order
+    orderedGridColumnNames.forEach(function(columnName, i) {
+      const $column = columnsByName[columnName];
+
+      if ($column.is('th')) {
+        $column.append(orderedGridColumnTitles[i]);
+      }
+
+      $column.appendTo(row);
+    });
+
+    // Insert remaining columns
+    $columnsAfter.appendTo(row);
+  });
+
+  let multiSelection: boolean;
+  if (getUtility().isUndefinedOrNull(editorConfiguration.multiSelection)) {
+    multiSelection = false;
+  } else {
+    multiSelection = !!editorConfiguration.multiSelection;
+  }
+
+  const rowItemTemplate = $(
+    getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'),
+    $(editorHtml)
+  ).clone();
+  $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'), $(editorHtml)).remove();
+
+  if (editorConfiguration.enableDeleteRow) {
+    $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorDeleteRow'),
+      $(rowItemTemplate)
+    ).on('click', function(this: HTMLElement) {
+      $(this)
+        .closest(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'))
+        .off()
+        .empty()
+        .remove();
+
+      setPropertyGridData(
+        $(editorHtml),
+        multiSelection,
+        editorConfiguration.propertyPath,
+        propertyPathPrefix
+      );
+    });
+  } else {
+    $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorDeleteRow'), $(rowItemTemplate))
+      .parent()
+      .off()
+      .empty();
+  }
+
+  if (editorConfiguration.isSortable) {
+    $(editorHtml).get(0).querySelectorAll(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorContainer') + ' tbody').forEach(function (sortableList: HTMLElement) {
+      new Sortable(sortableList, {
+        group: getHelper().getDomElementDataAttributeValue('propertyGridEditorContainer'),
+        handle: getHelper().getDomElementDataIdentifierSelector('propertyGridEditorSortRow'),
+        draggable: getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'),
+        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
+        // @ts-ignore
+        pull: 'clone',
+        swapThreshold: 0.6,
+        dragClass: 'form-sortable-drag',
+        ghostClass: 'form-sortable-ghost',
+        onUpdate: function() {
+          setPropertyGridData(
+            $(editorHtml),
+            multiSelection,
+            editorConfiguration.propertyPath,
+            propertyPathPrefix
+          );
+        }
+      });
+    });
+  } else {
+    $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorSortRow'), $(rowItemTemplate))
+      .parent()
+      .off()
+      .empty();
+  }
+
+  $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorSelectValue'),
+    $(rowItemTemplate)
+  ).on('change', function(this: HTMLElement) {
+    if (!multiSelection) {
+      $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorSelectValue') + ':checked', $(editorHtml))
+        .not($(this))
+        .prop('checked', false);
+    }
+    setPropertyGridData(
+      $(editorHtml),
+      multiSelection,
+      editorConfiguration.propertyPath,
+      propertyPathPrefix
+    );
+  });
+
+  $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorLabel') + ',' +
+    getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'),
+  $(rowItemTemplate)
+  ).on('keyup paste', function() {
+    setPropertyGridData(
+      $(editorHtml),
+      multiSelection,
+      editorConfiguration.propertyPath,
+      propertyPathPrefix
+    );
+  });
+
+  if (useLabelAsFallbackValue) {
+    $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorLabel'),
+      $(rowItemTemplate)
+    ).on('focusout', function(this: HTMLElement) {
+      if ('' === $(this)
+        .closest(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'))
+        .find(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'))
+        .val()
+      ) {
+        $(this)
+          .closest(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'))
+          .find(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'))
+          .val($(this).val());
+      }
+    });
+  }
+
+  if (editorConfiguration.enableAddRow) {
+    const addRowTemplate = $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorAddRowItem'), $(editorHtml)).clone();
+    $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorAddRowItem'), $(editorHtml)).remove();
+
+    $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorAddRow'), $(addRowTemplate)).on('click', function(this: HTMLElement) {
+      $(this)
+        .closest(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorAddRowItem'))
+        .before($(rowItemTemplate).clone(true, true));
+
+      setPropertyGridData(
+        $(editorHtml),
+        multiSelection,
+        editorConfiguration.propertyPath,
+        propertyPathPrefix
+      );
+    });
+    $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorContainer'), $(editorHtml))
+      .prepend($(addRowTemplate).clone(true, true));
+  } else {
+    $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorAddRowItem'), $(editorHtml)).remove();
+  }
+
+  let defaultValue: Record<string, string> = {};
+  if (multiSelection) {
+    if (!getUtility().isUndefinedOrNull(getCurrentlySelectedFormElement().get(propertyPathPrefix + 'defaultValue'))) {
+      defaultValue = getCurrentlySelectedFormElement().get(propertyPathPrefix + 'defaultValue');
+    }
+  } else {
+    if (!getUtility().isUndefinedOrNull(getCurrentlySelectedFormElement().get(propertyPathPrefix + 'defaultValue'))) {
+      defaultValue = { 0: getCurrentlySelectedFormElement().get(propertyPathPrefix + 'defaultValue') };
+    }
+  }
+  const propertyData = getCurrentlySelectedFormElement().get(propertyPathPrefix + editorConfiguration.propertyPath) || {};
+
+  const setData = function(label: string, value: string) {
+    let isPreselected = false;
+    const newRowTemplate = $(rowItemTemplate).clone(true, true);
+
+    for (const defaultValueKey of Object.keys(defaultValue)) {
+      if (defaultValue[defaultValueKey] === value) {
+        isPreselected = true;
+        break;
+      }
+    }
+
+    $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorLabel'), $(newRowTemplate)).val(label);
+    $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'), $(newRowTemplate)).val(value);
+
+    if (isPreselected) {
+      $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorSelectValue'), $(newRowTemplate))
+        .prop('checked', true);
+    }
+
+    if (editorConfiguration.enableAddRow) {
+      $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorAddRowItem'), $(editorHtml))
+        .before($(newRowTemplate));
+    } else {
+      $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorContainer'), $(editorHtml))
+        .prepend($(newRowTemplate));
+    }
+  };
+
+  if ('object' === $.type(propertyData)) {
+    for (const propertyDataKey of Object.keys(propertyData)) {
+      setData(propertyData[propertyDataKey], propertyDataKey);
+    }
+  } else if ('array' === $.type(propertyData)) {
+    for (const propertyDataKey in propertyData) {
+      // eslint-disable-next-line no-prototype-builtins
+      if (!propertyData.hasOwnProperty(propertyDataKey)) {
+        continue;
+      }
+      if (getUtility().isUndefinedOrNull(propertyData[propertyDataKey]._label)) {
+        setData(propertyData[propertyDataKey], propertyDataKey);
+      } else {
+        setData(propertyData[propertyDataKey]._label, propertyData[propertyDataKey]._value);
+      }
+    }
+  }
+
+  validateCollectionElement(propertyPathPrefix + editorConfiguration.propertyPath, editorHtml);
+}
+
+/**
+ * @publish view/inspector/collectionElement/new/selected
+ * @publish view/inspector/removeCollectionElement/perform
+ * @throws 1475417093
+ * @throws 1475417094
+ * @throws 1475417095
+ * @throws 1475417096
+ */
+export function renderRequiredValidatorEditor(
+  editorConfiguration: EditorConfiguration,
+  editorHtml: HTMLElement | JQuery,
+  collectionElementIdentifier: string,
+  collectionName: keyof FormEditorDefinitions
+): void {
+  assert(
+    'object' === $.type(editorConfiguration),
+    'Invalid parameter "editorConfiguration"',
+    1475417093
+  );
+  assert(
+    'object' === $.type(editorHtml),
+    'Invalid parameter "editorHtml"',
+    1475417094
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.validatorIdentifier),
+    'Invalid configuration "validatorIdentifier"',
+    1475417095
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.label),
+    'Invalid configuration "label"',
+    1475417096
+  );
+
+  const validatorIdentifier = editorConfiguration.validatorIdentifier;
+  getHelper().getTemplatePropertyDomElement('label', editorHtml).append(editorConfiguration.label);
+
+  let propertyValue: string;
+  let propertyPath: string;
+  let propertyData: PropertyData;
+  if (getUtility().isNonEmptyString(editorConfiguration.propertyPath)) {
+    propertyPath = getFormEditorApp()
+      .buildPropertyPath(editorConfiguration.propertyPath, collectionElementIdentifier, collectionName);
+  }
+  if (getUtility().isNonEmptyString(editorConfiguration.propertyValue)) {
+    propertyValue = editorConfiguration.propertyValue;
+  } else {
+    propertyValue = '';
+  }
+
+  const validationErrorMessagePropertyPath = getFormEditorApp()
+    .buildPropertyPath(editorConfiguration.configurationOptions.validationErrorMessage.propertyPath);
+
+  const validationErrorMessageTemplate = getHelper()
+    .getTemplatePropertyDomElement('validationErrorMessage', $(editorHtml))
+    .clone();
+
+  getHelper()
+    .getTemplatePropertyDomElement('validationErrorMessage', $(editorHtml))
+    .remove();
+
+  const showValidationErrorMessage = function() {
+    const validationErrorMessageTemplateClone = $(validationErrorMessageTemplate).clone(true, true);
+    getEditorWrapperDomElement(editorHtml).after(validationErrorMessageTemplateClone);
+
+    getHelper()
+      .getTemplatePropertyDomElement('validationErrorMessage-label', validationErrorMessageTemplateClone)
+      .append(editorConfiguration.configurationOptions.validationErrorMessage.label);
+
+    getHelper()
+      .getTemplatePropertyDomElement('validationErrorMessage-fieldExplanationText', validationErrorMessageTemplateClone)
+      .append(editorConfiguration.configurationOptions.validationErrorMessage.fieldExplanationText);
+
+    propertyData = getCurrentlySelectedFormElement().get(validationErrorMessagePropertyPath);
+    if (getUtility().isUndefinedOrNull(propertyData)) {
+      propertyData = [];
+    }
+
+    const validationErrorMessage = getFirstAvailableValidationErrorMessage(
+      editorConfiguration.configurationOptions.validationErrorMessage.errorCodes,
+      propertyData
+    );
+    if (!getUtility().isUndefinedOrNull(validationErrorMessage)) {
+      getHelper()
+        .getTemplatePropertyDomElement('validationErrorMessage-propertyPath', validationErrorMessageTemplateClone)
+        .val(validationErrorMessage);
+    }
+
+    getHelper().getTemplatePropertyDomElement('validationErrorMessage-propertyPath', validationErrorMessageTemplateClone).on('keyup paste', function(this: HTMLInputElement) {
+      let propertyData = getCurrentlySelectedFormElement().get(validationErrorMessagePropertyPath);
+      if (getUtility().isUndefinedOrNull(propertyData)) {
+        propertyData = [];
+      }
+
+      getCurrentlySelectedFormElement().set(validationErrorMessagePropertyPath, renewValidationErrorMessages(
+        editorConfiguration.configurationOptions.validationErrorMessage.errorCodes,
+        propertyData,
+        $(this).val()
+      ));
+    });
+  }
+
+  if (-1 !== getFormEditorApp().getIndexFromPropertyCollectionElement(validatorIdentifier, 'validators')) {
+    $('input[type="checkbox"]', $(editorHtml)).prop('checked', true);
+    if (getUtility().isNonEmptyString(propertyPath)) {
+      getCurrentlySelectedFormElement().set(propertyPath, propertyValue);
+    }
+    showValidationErrorMessage();
+  }
+
+  $('input[type="checkbox"]', $(editorHtml)).on('change', function(this: HTMLInputElement) {
+    getHelper().getTemplatePropertyDomElement('validationErrorMessage', $(editorHtml))
+      .off()
+      .empty()
+      .remove();
+
+    if ($(this).is(':checked')) {
+      showValidationErrorMessage();
+      getPublisherSubscriber().publish(
+        'view/inspector/collectionElement/new/selected',
+        [validatorIdentifier, 'validators']
+      );
+
+      if (getUtility().isNonEmptyString(propertyPath)) {
+        getCurrentlySelectedFormElement().set(propertyPath, propertyValue);
+      }
+    } else {
+      getPublisherSubscriber().publish(
+        'view/inspector/removeCollectionElement/perform',
+        [validatorIdentifier, 'validators']
+      );
+      if (getUtility().isNonEmptyString(propertyPath)) {
+        getCurrentlySelectedFormElement().unset(propertyPath);
+      }
+
+      propertyData = getCurrentlySelectedFormElement().get(validationErrorMessagePropertyPath);
+      if (getUtility().isUndefinedOrNull(propertyData)) {
+        propertyData = [];
+      }
+
+      getCurrentlySelectedFormElement().set(validationErrorMessagePropertyPath, renewValidationErrorMessages(
+        editorConfiguration.configurationOptions.validationErrorMessage.errorCodes,
+        propertyData,
+        ''
+      ));
+    }
+  });
+}
+
+/**
+ * @throws 1476218671
+ * @throws 1476218672
+ * @throws 1476218673
+ * @throws 1476218674
+ */
+export function renderCheckboxEditor(
+  editorConfiguration: EditorConfiguration,
+  editorHtml: HTMLElement | JQuery,
+  collectionElementIdentifier: string,
+  collectionName: keyof FormEditorDefinitions
+): void {
+  assert(
+    'object' === $.type(editorConfiguration),
+    'Invalid parameter "editorConfiguration"',
+    1476218671
+  );
+  assert(
+    'object' === $.type(editorHtml),
+    'Invalid parameter "editorHtml"',
+    1476218672
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.label),
+    'Invalid configuration "label"',
+    1476218673
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.propertyPath),
+    'Invalid configuration "propertyPath"',
+    1476218674
+  );
+
+  getHelper()
+    .getTemplatePropertyDomElement('label', editorHtml)
+    .append(editorConfiguration.label);
+  if (getUtility().isNonEmptyString(editorConfiguration.fieldExplanationText)) {
+    getHelper()
+      .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
+      .text(editorConfiguration.fieldExplanationText);
+  } else {
+    getHelper()
+      .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
+      .remove();
+  }
+
+  const propertyPath = getFormEditorApp()
+    .buildPropertyPath(editorConfiguration.propertyPath, collectionElementIdentifier, collectionName);
+  const propertyData = getCurrentlySelectedFormElement().get(propertyPath);
+
+  if (
+    ('boolean' === $.type(propertyData) && propertyData)
+    || propertyData === 'true'
+    || propertyData === 1
+    || propertyData === '1'
+  ) {
+    $('input[type="checkbox"]', $(editorHtml)).prop('checked', true);
+  }
+
+  $('input[type="checkbox"]', $(editorHtml)).on('change', function(this: HTMLInputElement) {
+    if ($(this).is(':checked')) {
+      getCurrentlySelectedFormElement().set(propertyPath, true);
+    } else {
+      getCurrentlySelectedFormElement().set(propertyPath, false);
+    }
+  });
+}
+
+/**
+ * @throws 1475412567
+ * @throws 1475412568
+ * @throws 1475416098
+ * @throws 1475416099
+ */
+export function renderTextareaEditor(
+  editorConfiguration: EditorConfiguration,
+  editorHtml: HTMLElement | JQuery,
+  collectionElementIdentifier: string,
+  collectionName: keyof FormEditorDefinitions
+): void {
+  assert(
+    'object' === $.type(editorConfiguration),
+    'Invalid parameter "editorConfiguration"',
+    1475412567
+  );
+  assert(
+    'object' === $.type(editorHtml),
+    'Invalid parameter "editorHtml"',
+    1475412568
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.propertyPath),
+    'Invalid configuration "propertyPath"',
+    1475416098
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.label),
+    'Invalid configuration "label"',
+    1475416099
+  );
+
+  const propertyPath = getFormEditorApp()
+    .buildPropertyPath(editorConfiguration.propertyPath, collectionElementIdentifier, collectionName);
+
+  getHelper()
+    .getTemplatePropertyDomElement('label', editorHtml).append(editorConfiguration.label);
+
+  if (getUtility().isNonEmptyString(editorConfiguration.fieldExplanationText)) {
+    getHelper()
+      .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
+      .text(editorConfiguration.fieldExplanationText);
+  } else {
+    getHelper()
+      .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
+      .remove();
+  }
+
+  const propertyData = getCurrentlySelectedFormElement().get(propertyPath);
+  $('textarea', $(editorHtml)).val(propertyData);
+
+  $('textarea', $(editorHtml)).on('keyup paste', function(this: HTMLTextAreaElement) {
+    getCurrentlySelectedFormElement().set(propertyPath, $(this).val());
+  });
+}
+
+/**
+ * @throws 1477300587
+ * @throws 1477300588
+ * @throws 1477300589
+ * @throws 1477300590
+ * @throws 1477318981
+ * @throws 1477319859
+ */
+export function renderTypo3WinBrowserEditor(
+  editorConfiguration: EditorConfiguration,
+  editorHtml: HTMLElement | JQuery,
+  collectionElementIdentifier: string,
+  collectionName: keyof FormEditorDefinitions
+): void {
+  assert(
+    'object' === $.type(editorConfiguration),
+    'Invalid parameter "editorConfiguration"',
+    1477300587
+  );
+  assert(
+    'object' === $.type(editorHtml),
+    'Invalid parameter "editorHtml"',
+    1477300588
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.label),
+    'Invalid configuration "label"',
+    1477300589
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.buttonLabel),
+    'Invalid configuration "buttonLabel"',
+    1477318981
+  );
+  assert(
+    getUtility().isNonEmptyString(editorConfiguration.propertyPath),
+    'Invalid configuration "propertyPath"',
+    1477300590
+  );
+
+  getHelper()
+    .getTemplatePropertyDomElement('label', editorHtml)
+    .append(editorConfiguration.label);
+  getHelper()
+    .getTemplatePropertyDomElement('buttonLabel', editorHtml)
+    .append(editorConfiguration.buttonLabel);
+
+  if (getUtility().isNonEmptyString(editorConfiguration.fieldExplanationText)) {
+    getHelper()
+      .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
+      .text(editorConfiguration.fieldExplanationText);
+  } else {
+    getHelper()
+      .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
+      .remove();
+  }
+
+  $('form', $(editorHtml)).prop('name', editorConfiguration.propertyPath);
+
+  Icons.getIcon(editorConfiguration.iconIdentifier, Icons.sizes.small).then(function(icon) {
+    getHelper().getTemplatePropertyDomElement('image', editorHtml).append($(icon));
+  });
+
+  getHelper().getTemplatePropertyDomElement('onclick', editorHtml).on('click', function(this: HTMLElement) {
+    const randomIdentifier = Math.floor((Math.random() * 100000) + 1);
+    const insertTarget = $(this)
+      .closest(getHelper().getDomElementDataIdentifierSelector('editorControlsWrapper'))
+      .find(getHelper().getDomElementDataAttribute('contentElementSelectorTarget', 'bracesWithKey'));
+
+    insertTarget.attr(getHelper().getDomElementDataAttribute('contentElementSelectorTarget'), randomIdentifier);
+    openTypo3WinBrowser('db', randomIdentifier + '|||' + editorConfiguration.browsableType);
+  });
+
+  listenOnElementBrowser();
+
+  const propertyPath = getFormEditorApp().buildPropertyPath(editorConfiguration.propertyPath, collectionElementIdentifier, collectionName);
+  const propertyData = getCurrentlySelectedFormElement().get(propertyPath);
+
+  validateCollectionElement(propertyPath, editorHtml);
+  getHelper()
+    .getTemplatePropertyDomElement('propertyPath', editorHtml)
+    .val(propertyData);
+
+  getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).on('keyup paste', function(this: HTMLInputElement) {
+    getCurrentlySelectedFormElement().set(propertyPath, $(this).val());
+    validateCollectionElement(propertyPath, editorHtml);
+  });
+}
+
+/**
+ * @throws 1475412563
+ * @throws 1475412564
+ */
+export function renderRemoveElementEditor(
+  editorConfiguration: EditorConfiguration,
+  editorHtml: HTMLElement | JQuery,
+  collectionElementIdentifier: string,
+  collectionName: keyof FormEditorDefinitions
+): void {
+  assert('object' === $.type(editorConfiguration), 'Invalid parameter "editorConfiguration"', 1475412563);
+  assert('object' === $.type(editorHtml), 'Invalid parameter "editorHtml"', 1475412564);
+
+  if (getUtility().isUndefinedOrNull(collectionElementIdentifier)) {
+
+    $('button', $(editorHtml))
+      .addClass(
+        getHelper().getDomElementClassName('buttonFormElementRemove') + ' ' +
+        getHelper().getDomElementClassName('buttonFormEditor')
+      );
+  } else {
+    $('button', $(editorHtml)).addClass(
+      getHelper().getDomElementClassName('buttonCollectionElementRemove')
+    );
+  }
+
+  $('button', $(editorHtml)).on('click', function() {
+    if (getUtility().isUndefinedOrNull(collectionElementIdentifier)) {
+      getViewModel().showRemoveFormElementModal();
+    } else {
+      getViewModel().showRemoveCollectionElementModal(collectionElementIdentifier, collectionName);
+    }
+  });
+}
+
+/**
+ * @throws 1484574704
+ * @throws 1484574705
+ * @throws 1484574706
+ */
+export function renderFormElementSelectorEditorAddition(
+  editorConfiguration: EditorConfiguration,
+  editorHtml: HTMLElement | JQuery,
+  propertyPath: string
+): void {
+  assert(
+    'object' === $.type(editorConfiguration),
+    'Invalid parameter "editorConfiguration"',
+    1484574704
+  );
+  assert(
+    'object' === $.type(editorHtml),
+    'Invalid parameter "editorHtml"',
+    1484574705
+  );
+  assert(
+    getUtility().isNonEmptyString(propertyPath),
+    'Invalid parameter "propertyPath"',
+    1484574706
+  );
+
+  const formElementSelectorControlsWrapper = $(
+    getHelper().getDomElementDataIdentifierSelector('formElementSelectorControlsWrapper'), editorHtml
+  );
+
+  if (editorConfiguration.enableFormelementSelectionButton === true) {
+    if (formElementSelectorControlsWrapper.length === 0) {
+      return;
+    }
+
+    const formElementSelectorSplitButtonListContainer = $(
+      getHelper().getDomElementDataIdentifierSelector('formElementSelectorSplitButtonListContainer'), editorHtml
+    );
+
+    formElementSelectorSplitButtonListContainer.off().empty();
+    const nonCompositeNonToplevelFormElements = getFormEditorApp().getNonCompositeNonToplevelFormElements();
+
+    if (nonCompositeNonToplevelFormElements.length === 0) {
+      Icons.getIcon(
+        getHelper().getDomElementDataAttributeValue('iconNotAvailable'),
+        Icons.sizes.small,
+        null,
+        Icons.states.default
+      ).then(function(icon) {
+        const itemTemplate = $('<li data-no-sorting>'
+          + '<a href="#"></a>'
+          + '</li>');
+
+        itemTemplate
+          .append($(icon))
+          .append(' ' + getFormElementDefinition(getRootFormElement(), 'inspectorEditorFormElementSelectorNoElements'));
+        formElementSelectorSplitButtonListContainer.append(itemTemplate);
+      });
+    } else {
+      $.each(nonCompositeNonToplevelFormElements, function(i, nonCompositeNonToplevelFormElement) {
+        Icons.getIcon(
+          getFormElementDefinition(nonCompositeNonToplevelFormElement, 'iconIdentifier'),
+          Icons.sizes.small,
+          null,
+          Icons.states.default
+        ).then(function(icon) {
+          const itemTemplate = $('<li data-no-sorting>'
+            + '<a href="#" class="dropdown-item" data-formelement-identifier="' + nonCompositeNonToplevelFormElement.get('identifier') + '">'
+            + '</a>'
+            + '</li>');
+
+          $('[data-formelement-identifier="' + nonCompositeNonToplevelFormElement.get('identifier') + '"]', itemTemplate)
+            .append($(icon))
+            .append(' ' + nonCompositeNonToplevelFormElement.get('label'));
+
+          $('a', itemTemplate).on('click', function(this: HTMLElement) {
+            let propertyData;
+
+            propertyData = getCurrentlySelectedFormElement().get(propertyPath) || '';
+
+            if (propertyData.length === 0) {
+              propertyData = '{' + $(this).attr('data-formelement-identifier') + '}';
+            } else {
+              propertyData = propertyData + ' ' + '{' + $(this).attr('data-formelement-identifier') + '}';
+            }
+
+            getCurrentlySelectedFormElement().set(propertyPath, propertyData);
+            getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).val(propertyData);
+            validateCollectionElement(propertyPath, editorHtml);
+          });
+
+          formElementSelectorSplitButtonListContainer.append(itemTemplate);
+        });
+      });
+    }
+  } else {
+    $(getHelper().getDomElementDataIdentifierSelector('editorControlsInputGroup'), editorHtml)
+      .removeClass(getHelper().getDomElementClassName('inspectorInputGroup'));
+    formElementSelectorControlsWrapper.off().empty().remove();
+  }
+}
+
+/**
+ * @throws 1478967319
+ */
+export function buildTitleByFormElement(formElement?: FormElement): HTMLElement {
+  if (getUtility().isUndefinedOrNull(formElement)) {
+    formElement = getCurrentlySelectedFormElement();
+  }
+  assert('object' === $.type(formElement), 'Invalid parameter "formElement"', 1478967319);
+
+  let label;
+  if (formElement.get('type') === 'Form') {
+    label = formElement.get('type');
+  } else {
+    label = getFormElementDefinition(formElement, 'label')
+      ? getFormElementDefinition(formElement, 'label')
+      : formElement.get('identifier');
+  }
+
+  const span = document.createElement('span');
+  span.textContent = label;
+  return span;
+}
+
+export function bootstrap(
+  this: typeof import('./inspector-component'),
+  _formEditorApp: FormEditor,
+  customConfiguration?: Configuration
+): typeof import('./inspector-component') {
+  formEditorApp = _formEditorApp;
+  configuration = $.extend(true, defaultConfiguration, customConfiguration || {});
+  Helper.bootstrap(formEditorApp);
+  return this;
+}
+
+declare global {
+  interface PublisherSubscriberTopicArgumentsMap {
+    'view/inspector/removeCollectionElement/perform': readonly [
+      validatorIdentifier: string,
+      info: 'validators',
+      // @todo formElement is never published, but used by
+      // media subscribe('view/inspector/removeCollectionElement/perform', .)
+      // Can this be removed or is it possibly used by extensions?
+      formElement?: FormElement,
+    ];
+    'view/inspector/collectionElement/new/selected': readonly [
+      value: string,
+      collectionName: keyof FormEditorDefinitions
+    ];
+    'view/inspector/collectionElement/existing/selected': readonly [
+      alreadySelectedCollectionElementIdentifier: string,
+      collectionName: keyof FormEditorDefinitions
+    ];
+    'view/inspector/collectionElements/dnd/update': readonly [
+      movedCollectionElementIdentifier: string,
+      previousCollectionElementIdentifier: string,
+      nextCollectionElementIdentifier: string,
+      collectionName: keyof FormEditorDefinitions
+    ];
+    'view/inspector/editor/insert/perform': readonly [
+      editorConfiguration: EditorConfiguration,
+      editorHtml: HTMLElement | JQuery,
+      collectionElementIdentifier: string,
+      collectionName: keyof FormEditorDefinitions
+    ];
+  }
+}
diff --git a/typo3/sysext/form/Resources/Public/JavaScript/backend/form-editor/inspector-component.js b/typo3/sysext/form/Resources/Public/JavaScript/backend/form-editor/inspector-component.js
index 411ef0e6b149b9f600e18832e729f1dd0d477160..ca9c70a8db01b40b35db977f2607b6a2cad1e220 100644
--- a/typo3/sysext/form/Resources/Public/JavaScript/backend/form-editor/inspector-component.js
+++ b/typo3/sysext/form/Resources/Public/JavaScript/backend/form-editor/inspector-component.js
@@ -10,2792 +10,4 @@
  *
  * The TYPO3 project - inspiring people to share!
  */
-
-/**
- * Module: @typo3/form/backend/form-editor/inspector-component
- */
-
-import $ from 'jquery';
-import * as Helper from '@typo3/form/backend/form-editor/helper.js';
-import Icons from '@typo3/backend/icons.js';
-import Notification from '@typo3/backend/notification.js';
-import Modal from '@typo3/backend/modal.js';
-import {MessageUtility} from '@typo3/backend/utility/message-utility.js';
-import Sortable from 'sortablejs';
-
-const {
-  bootstrap,
-  buildTitleByFormElement,
-  getCollectionElementDomElement,
-  getFinishersContainerDomElement,
-  getInspectorDomElement,
-  getValidatorsContainerDomElement,
-  renderCheckboxEditor,
-  renderCollectionElementEditors,
-  renderCollectionElementHeaderEditor,
-  renderCountrySelectEditor,
-  renderFileMaxSizeEditor,
-  renderCollectionElementSelectionEditor,
-  renderEditors,
-  renderFormElementHeaderEditor,
-  renderFormElementSelectorEditorAddition,
-  renderPropertyGridEditor,
-  renderRemoveElementEditor,
-  renderRequiredValidatorEditor,
-  renderSingleSelectEditor,
-  renderMultiSelectEditor,
-  renderTextareaEditor,
-  renderTextEditor,
-  renderTypo3WinBrowserEditor
-} = factory($, Helper, Icons, Notification, Modal, MessageUtility);
-
-export {
-  bootstrap,
-  buildTitleByFormElement,
-  getCollectionElementDomElement,
-  getFinishersContainerDomElement,
-  getInspectorDomElement,
-  getValidatorsContainerDomElement,
-  renderCheckboxEditor,
-  renderCollectionElementEditors,
-  renderCollectionElementHeaderEditor,
-  renderFileMaxSizeEditor,
-  renderCollectionElementSelectionEditor,
-  renderEditors,
-  renderFormElementHeaderEditor,
-  renderFormElementSelectorEditorAddition,
-  renderPropertyGridEditor,
-  renderRemoveElementEditor,
-  renderRequiredValidatorEditor,
-  renderSingleSelectEditor,
-  renderMultiSelectEditor,
-  renderTextareaEditor,
-  renderTextEditor,
-  renderTypo3WinBrowserEditor
-};
-
-function factory($, Helper, Icons, Notification, Modal, MessageUtility) {
-  return (function($, Helper, Icons, Notification) {
-
-    /**
-     * @private
-     *
-     * @var object
-     */
-    var _configuration = null;
-
-    /**
-     * @private
-     *
-     * @var object
-     */
-    var _defaultConfiguration = {
-      domElementClassNames: {
-        buttonFormElementRemove: 't3-form-remove-element-button',
-        collectionElement: 't3-form-collection-element',
-        finisherEditorPrefix: 't3-form-inspector-finishers-editor-',
-        inspectorEditor: 'form-editor',
-        inspectorInputGroup: 'input-group',
-        validatorEditorPrefix: 't3-form-inspector-validators-editor-'
-      },
-      domElementDataAttributeNames: {
-        contentElementSelectorTarget: 'data-insert-target',
-        finisher: 'data-finisher-identifier',
-        validator: 'data-validator-identifier',
-        randomId: 'data-random-id',
-        randomIdTarget: 'data-random-id-attribute',
-        randomIdIndex: 'data-random-id-number',
-        maximumFileSize: 'data-maximumFileSize'
-      },
-      domElementDataAttributeValues: {
-        collapse: 'actions-view-table-expand',
-        editorControlsInputGroup: 'inspectorEditorControlsGroup',
-        editorWrapper: 'editorWrapper',
-        editorControlsWrapper: 'inspectorEditorControlsWrapper',
-        formElementHeaderEditor: 'inspectorFormElementHeaderEditor',
-        formElementSelectorControlsWrapper: 'inspectorEditorFormElementSelectorControlsWrapper',
-        formElementSelectorSplitButtonContainer: 'inspectorEditorFormElementSelectorSplitButtonContainer',
-        formElementSelectorSplitButtonListContainer: 'inspectorEditorFormElementSelectorSplitButtonListContainer',
-        iconNotAvailable: 'actions-close',
-        inspector: 'inspector',
-        'Inspector-CheckboxEditor': 'Inspector-CheckboxEditor',
-        'Inspector-CollectionElementHeaderEditor': 'Inspector-CollectionElementHeaderEditor',
-        'Inspector-FinishersEditor': 'Inspector-FinishersEditor',
-        'Inspector-FormElementHeaderEditor': 'Inspector-FormElementHeaderEditor',
-        'Inspector-PropertyGridEditor': 'Inspector-PropertyGridEditor',
-        'Inspector-RemoveElementEditor': 'Inspector-RemoveElementEditor',
-        'Inspector-RequiredValidatorEditor': 'Inspector-RequiredValidatorEditor',
-        'Inspector-SingleSelectEditor': 'Inspector-SingleSelectEditor',
-        'Inspector-MultiSelectEditor': 'Inspector-MultiSelectEditor',
-        'Inspector-GridColumnViewPortConfigurationEditor': 'Inspector-GridColumnViewPortConfigurationEditor',
-        'Inspector-TextareaEditor': 'Inspector-TextareaEditor',
-        'Inspector-TextEditor': 'Inspector-TextEditor',
-        'Inspector-Typo3WinBrowserEditor': 'Inspector-Typo3WinBrowserEditor',
-        'Inspector-ValidatorsEditor': 'Inspector-ValidatorsEditor',
-        'Inspector-ValidationErrorMessageEditor': 'Inspector-ValidationErrorMessageEditor',
-
-        inspectorFinishers: 'inspectorFinishers',
-        inspectorValidators: 'inspectorValidators',
-        propertyGridEditorHeaderRow: 'headerRow',
-        propertyGridEditorAddRow: 'addRow',
-        propertyGridEditorAddRowItem: 'addRowItem',
-        propertyGridEditorContainer: 'propertyGridContainer',
-        propertyGridEditorDeleteRow: 'deleteRow',
-        propertyGridEditorLabel: 'label',
-        propertyGridEditorRowItem: 'rowItem',
-        propertyGridEditorColumn: 'column',
-        propertyGridEditorSelectValue: 'selectValue',
-        propertyGridEditorSortRow: 'sortRow',
-        propertyGridEditorValue: 'value',
-        viewportButton: 'viewportButton'
-      },
-      domElementIdNames: {
-        finisherPrefix: 't3-form-inspector-finishers-',
-        validatorPrefix: 't3-form-inspector-validators-'
-      },
-      isSortable: true
-    };
-
-    /**
-     * @private
-     *
-     * @var object
-     */
-    var _formEditorApp = null;
-
-    /* *************************************************************
-     * Private Methods
-     * ************************************************************/
-
-    /**
-     * @private
-     *
-     * @return void
-     * @throws 1478268638
-     */
-    function _helperSetup() {
-      assert('function' === $.type(Helper.bootstrap),
-        'The view model helper does not implement the method "bootstrap"',
-        1478268638
-      );
-      Helper.bootstrap(getFormEditorApp());
-    };
-
-    /**
-     * @private
-     *
-     * @return object
-     */
-    function getFormEditorApp() {
-      return _formEditorApp;
-    };
-
-    /**
-     * @private
-     *
-     * @return object
-     */
-    function getViewModel() {
-      return getFormEditorApp().getViewModel();
-    };
-
-    /**
-     * @private
-     *
-     * @param object
-     * @return object
-     */
-    function getHelper(configuration) {
-      if (getUtility().isUndefinedOrNull(configuration)) {
-        return Helper.setConfiguration(_configuration);
-      }
-      return Helper.setConfiguration(configuration);
-    };
-
-    /**
-     * @private
-     *
-     * @return object
-     */
-    function getUtility() {
-      return getFormEditorApp().getUtility();
-    };
-
-    /**
-     * @private
-     *
-     * @param mixed test
-     * @param string message
-     * @param int messageCode
-     * @return void
-     */
-    function assert(test, message, messageCode) {
-      return getFormEditorApp().assert(test, message, messageCode);
-    };
-
-    /**
-     * @private
-     *
-     * @return object
-     */
-    function getCurrentlySelectedFormElement() {
-      return getFormEditorApp().getCurrentlySelectedFormElement();
-    };
-
-    /**
-     * @private
-     *
-     * @return object
-     */
-    function getRootFormElement() {
-      return getFormEditorApp().getRootFormElement();
-    };
-
-    /**
-     * @private
-     *
-     * @return object
-     */
-    function getPublisherSubscriber() {
-      return getFormEditorApp().getPublisherSubscriber();
-    };
-
-    /**
-     * @private
-     *
-     * @param object
-     * @param string
-     * @return mixed
-     */
-    function getFormElementDefinition(formElement, formElementDefinitionKey) {
-      return getFormEditorApp().getFormElementDefinition(formElement, formElementDefinitionKey);
-    };
-
-    /**
-     * @private
-     *
-     * @param object
-     * @param object
-     * @param string
-     * @param string
-     * @return void
-     * @publish view/inspector/editor/insert/perform
-     */
-    function _renderEditorDispatcher(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
-      switch (editorConfiguration['templateName']) {
-        case 'Inspector-FormElementHeaderEditor':
-          renderFormElementHeaderEditor(
-            editorConfiguration,
-            editorHtml,
-            collectionElementIdentifier,
-            collectionName
-          );
-          break;
-        case 'Inspector-CollectionElementHeaderEditor':
-          renderCollectionElementHeaderEditor(
-            editorConfiguration,
-            editorHtml,
-            collectionElementIdentifier,
-            collectionName
-          );
-          break;
-        case 'Inspector-MaximumFileSizeEditor':
-          renderMaximumFileSizeEditor(
-            editorConfiguration,
-            editorHtml
-          );
-          break;
-        case 'Inspector-TextEditor':
-          renderTextEditor(
-            editorConfiguration,
-            editorHtml,
-            collectionElementIdentifier,
-            collectionName
-          );
-          break;
-        case 'Inspector-FinishersEditor':
-          renderCollectionElementSelectionEditor(
-            'finishers',
-            editorConfiguration,
-            editorHtml,
-            collectionElementIdentifier,
-            collectionName
-          );
-          break;
-        case 'Inspector-ValidatorsEditor':
-          renderCollectionElementSelectionEditor(
-            'validators',
-            editorConfiguration,
-            editorHtml,
-            collectionElementIdentifier,
-            collectionName
-          );
-          break;
-        case 'Inspector-ValidationErrorMessageEditor':
-            renderValidationErrorMessageEditor(
-                editorConfiguration,
-                editorHtml,
-                collectionElementIdentifier,
-                collectionName
-            );
-            break;
-        case 'Inspector-RemoveElementEditor':
-          renderRemoveElementEditor(
-            editorConfiguration,
-            editorHtml,
-            collectionElementIdentifier,
-            collectionName
-          );
-          break;
-        case 'Inspector-RequiredValidatorEditor':
-          renderRequiredValidatorEditor(
-            editorConfiguration,
-            editorHtml,
-            collectionElementIdentifier,
-            collectionName
-          );
-          break;
-        case 'Inspector-CheckboxEditor':
-          renderCheckboxEditor(
-            editorConfiguration,
-            editorHtml,
-            collectionElementIdentifier,
-            collectionName
-          );
-          break;
-        case 'Inspector-CountrySelectEditor':
-          renderCountrySelectEditor(
-            editorConfiguration,
-            editorHtml,
-            collectionElementIdentifier,
-            collectionName
-          );
-          break;
-        case 'Inspector-SingleSelectEditor':
-          renderSingleSelectEditor(
-            editorConfiguration,
-            editorHtml,
-            collectionElementIdentifier,
-            collectionName
-          );
-          break;
-        case 'Inspector-MultiSelectEditor':
-          renderMultiSelectEditor(
-            editorConfiguration,
-            editorHtml,
-            collectionElementIdentifier,
-            collectionName
-          );
-          break;
-        case 'Inspector-GridColumnViewPortConfigurationEditor':
-          renderGridColumnViewPortConfigurationEditor(
-            editorConfiguration,
-            editorHtml,
-            collectionElementIdentifier,
-            collectionName
-          );
-          break;
-        case 'Inspector-PropertyGridEditor':
-          renderPropertyGridEditor(
-            editorConfiguration,
-            editorHtml,
-            collectionElementIdentifier,
-            collectionName
-          );
-          break;
-        case 'Inspector-TextareaEditor':
-          renderTextareaEditor(
-            editorConfiguration,
-            editorHtml,
-            collectionElementIdentifier,
-            collectionName
-          );
-          break;
-        case 'Inspector-Typo3WinBrowserEditor':
-          renderTypo3WinBrowserEditor(
-            editorConfiguration,
-            editorHtml,
-            collectionElementIdentifier,
-            collectionName
-          );
-          break;
-      }
-      getPublisherSubscriber().publish('view/inspector/editor/insert/perform', [
-        editorConfiguration, editorHtml, collectionElementIdentifier, collectionName
-      ]);
-    };
-
-    /**
-     * @private
-     *
-     * opens a popup window with the element browser
-     *
-     * @param string mode
-     * @param string params
-     */
-    function _openTypo3WinBrowser(mode, params) {
-      Modal.advanced({
-        type: Modal.types.iframe,
-        content: TYPO3.settings.FormEditor.typo3WinBrowserUrl + '&mode=' + mode + '&bparams=' + params,
-        size: Modal.sizes.large
-      });
-    };
-
-    /**
-     * @private
-     *
-     * Listens on messages sent by ElementBrowser
-     */
-    function _listenOnElementBrowser() {
-      window.addEventListener('message', function (e) {
-        if (!MessageUtility.verifyOrigin(e.origin)) {
-          throw 'Denied message sent by ' + e.origin;
-        }
-
-        if (e.data.actionName === 'typo3:elementBrowser:elementAdded') {
-          if (typeof e.data.fieldName === 'undefined') {
-            throw 'fieldName not defined in message';
-          }
-
-          if (typeof e.data.value === 'undefined') {
-            throw 'value not defined in message';
-          }
-
-          var result = e.data.value.split('_');
-          $(getHelper().getDomElementDataAttribute('contentElementSelectorTarget', 'bracesWithKeyValue', [e.data.fieldName]))
-            .val(result.pop())
-            .trigger('paste');
-        }
-      });
-    }
-
-    /**
-     * @private
-     *
-     * @param string
-     * @param string
-     * @return object
-     */
-    function _getCollectionElementClass(collectionName, collectionElementIdentifier) {
-      if (collectionName === 'finishers') {
-        return getHelper()
-          .getDomElementClassName('finisherEditorPrefix') + collectionElementIdentifier;
-      } else {
-        return getHelper()
-          .getDomElementClassName('validatorEditorPrefix') + collectionElementIdentifier;
-      }
-    };
-
-    /**
-     * @private
-     *
-     * @param string
-     * @param string
-     * @param bool
-     * @return object
-     */
-    function _getCollectionElementId(collectionName, collectionElementIdentifier, asSelector) {
-      if (collectionName === 'finishers') {
-        return getHelper()
-          .getDomElementIdName('finisherPrefix', asSelector) + collectionElementIdentifier;
-      } else {
-        return getHelper()
-          .getDomElementIdName('validatorPrefix', asSelector) + collectionElementIdentifier;
-      }
-    };
-
-    /**
-     * @private
-     *
-     * @param object
-     * @param string
-     * @return void
-     */
-    function _addSortableCollectionElementsEvents(sortableDomElement, collectionName) {
-      sortableDomElement.addClass(getHelper().getDomElementClassName('sortable'));
-      new Sortable(sortableDomElement.get(0), {
-        draggable: getHelper().getDomElementClassName('collectionElement', true),
-        filter: 'input,textarea,select',
-        preventOnFilter: false,
-        animation: 200,
-        fallbackTolerance: 200,
-        swapThreshold: 0.6,
-        dragClass: 'form-sortable-drag',
-        ghostClass: 'form-sortable-ghost',
-        onEnd: function (e) {
-          let dataAttributeName;
-
-          if (collectionName === 'finishers') {
-            dataAttributeName = getHelper().getDomElementDataAttribute('finisher');
-          } else {
-            dataAttributeName = getHelper().getDomElementDataAttribute('validator');
-          }
-
-          const movedCollectionElementIdentifier = $(e.item).attr(dataAttributeName);
-          const previousCollectionElementIdentifier = $(e.item)
-            .prevAll(getHelper().getDomElementClassName('collectionElement', true))
-            .first()
-            .attr(dataAttributeName);
-          const nextCollectionElementIdentifier = $(e.item)
-            .nextAll(getHelper().getDomElementClassName('collectionElement', true))
-            .first()
-            .attr(dataAttributeName);
-
-          getPublisherSubscriber().publish('view/inspector/collectionElements/dnd/update', [
-            movedCollectionElementIdentifier,
-            previousCollectionElementIdentifier,
-            nextCollectionElementIdentifier,
-            collectionName
-          ]);
-        }
-      });
-    };
-
-    /**
-     * @private
-     *
-     * @param object editorHtml
-     * @param bool multiSelection
-     * @param string propertyPath
-     * @param string propertyPathPrefix
-     * @return void
-     */
-    function _setPropertyGridData(editorHtml, multiSelection, propertyPath, propertyPathPrefix) {
-      var defaultValue, newPropertyData, value;
-
-      if (multiSelection) {
-        defaultValue = [];
-
-        $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorContainer') + ' ' +
-          getHelper().getDomElementDataIdentifierSelector('propertyGridEditorSelectValue') + ':checked',
-          $(editorHtml)
-        ).each(function(i) {
-          value = $(this)
-            .closest(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'))
-            .find(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'))
-            .val();
-
-          if (getUtility().canBeInterpretedAsInteger(value)) {
-              value = parseInt(value, 10);
-          }
-
-          defaultValue.push(value);
-        });
-        getCurrentlySelectedFormElement().set(propertyPathPrefix + 'defaultValue', defaultValue);
-      } else {
-        value = $(
-            getHelper().getDomElementDataIdentifierSelector('propertyGridEditorContainer') + ' ' +
-            getHelper().getDomElementDataIdentifierSelector('propertyGridEditorSelectValue') + ':checked',
-            $(editorHtml)
-          ).first()
-            .closest(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'))
-            .find(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'))
-            .val();
-
-        if (getUtility().canBeInterpretedAsInteger(value)) {
-            value = parseInt(value, 10);
-        }
-
-        getCurrentlySelectedFormElement().set(propertyPathPrefix + 'defaultValue', value, true);
-      }
-
-      newPropertyData = [];
-      $(
-        getHelper().getDomElementDataIdentifierSelector('propertyGridEditorContainer') + ' ' +
-        getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'),
-        $(editorHtml)
-      ).each(function(i) {
-        var value, label, tmpObject;
-
-        value = $(this)
-          .find(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'))
-          .val();
-        label = $(this)
-          .find(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorLabel'))
-          .val();
-
-        if ('' === value) {
-          value = label;
-        }
-
-        tmpObject = {};
-        tmpObject[value] = label;
-        newPropertyData.push({
-          _label: label,
-          _value: value
-        });
-      });
-
-      getCurrentlySelectedFormElement().set(propertyPathPrefix + propertyPath, newPropertyData);
-      _validateCollectionElement(propertyPathPrefix + propertyPath, editorHtml);
-    };
-
-    /**
-     * @private
-     *
-     * @param object
-     * @return object
-     */
-    function _getEditorWrapperDomElement(editorDomElement) {
-      return $(getHelper().getDomElementDataIdentifierSelector('editorWrapper'), $(editorDomElement));
-    };
-
-    /**
-     * @private
-     *
-     * @param object
-     * @return object
-     */
-    function _getEditorControlsWrapperDomElement(editorDomElement) {
-      return $(getHelper().getDomElementDataIdentifierSelector('editorControlsWrapper'), $(editorDomElement));
-    };
-
-    /**
-     * @private
-     *
-     * @param string
-     * @param object
-     * @return void
-     */
-    function _validateCollectionElement(propertyPath, editorHtml) {
-      var hasError, propertyPrefix, validationResults;
-
-      validationResults = getFormEditorApp().validateCurrentlySelectedFormElementProperty(propertyPath);
-
-      if (validationResults.length > 0) {
-        getHelper()
-          .getTemplatePropertyDomElement('validationErrors', editorHtml)
-          .text(validationResults[0]);
-        getViewModel().setElementValidationErrorClass(
-          getHelper().getTemplatePropertyDomElement('validationErrors', editorHtml)
-        );
-        getViewModel().setElementValidationErrorClass(
-          _getEditorControlsWrapperDomElement(editorHtml),
-          'hasError'
-        );
-      } else {
-        getHelper().getTemplatePropertyDomElement('validationErrors', editorHtml).text('');
-        getViewModel().removeElementValidationErrorClass(
-          getHelper().getTemplatePropertyDomElement('validationErrors', editorHtml)
-        );
-        getViewModel().removeElementValidationErrorClass(
-          _getEditorControlsWrapperDomElement(editorHtml),
-          'hasError'
-        );
-      }
-
-      validationResults = getFormEditorApp().validateFormElement(getCurrentlySelectedFormElement());
-      propertyPrefix = propertyPath.split('.');
-      propertyPrefix = propertyPrefix[0] + '.' + propertyPrefix[1];
-
-      hasError = false;
-      for (var i = 0, len = validationResults.length; i < len; ++i) {
-        if (
-          validationResults[i]['propertyPath'].indexOf(propertyPrefix, 0) === 0
-          && validationResults[i]['validationResults']
-          && validationResults[i]['validationResults'].length > 0
-        ) {
-          hasError = true;
-          break;
-        }
-      }
-
-      if (hasError) {
-        getViewModel().setElementValidationErrorClass(
-          _getEditorControlsWrapperDomElement(editorHtml).closest(getHelper().getDomElementClassName('collectionElement', true))
-        );
-      } else {
-        getViewModel().removeElementValidationErrorClass(
-          _getEditorControlsWrapperDomElement(editorHtml).closest(getHelper().getDomElementClassName('collectionElement', true))
-        );
-      }
-    };
-
-    /**
-     * @private
-     *
-     * @param object
-     * @param object
-     * @return null|string
-     * @throws 1489932939
-     * @throws 1489932940
-     */
-    function _getFirstAvailableValidationErrorMessage(errorCodes, propertyData) {
-      assert(
-        'array' === $.type(errorCodes),
-        'Invalid configuration "errorCodes"',
-        1489932939
-      );
-      assert(
-        'array' === $.type(propertyData),
-        'Invalid configuration "propertyData"',
-        1489932940
-      );
-
-      for (var i = 0, len1 = errorCodes.length; i < len1; ++i) {
-        for (var j = 0, len2 = propertyData.length; j < len2; ++j) {
-          if (parseInt(errorCodes[i]) === parseInt(propertyData[j]['code'])) {
-            if (getUtility().isNonEmptyString(propertyData[j]['message'])) {
-              return propertyData[j]['message'];
-            }
-          }
-        }
-      }
-
-      return null;
-    };
-
-    /**
-     * @private
-     *
-     * @param object
-     * @param object
-     * @param string
-     * @return object
-     * @throws 1489932942
-     */
-    function _renewValidationErrorMessages(errorCodes, propertyData, value) {
-      var errorCodeSubset;
-
-      assert(
-        'array' === $.type(propertyData),
-        'Invalid configuration "propertyData"',
-        1489932942
-      );
-
-      if (
-        !getUtility().isUndefinedOrNull(errorCodes)
-        && 'array' === $.type(errorCodes)
-      ) {
-        errorCodeSubset = [];
-        for (var i = 0, len1 = errorCodes.length; i < len1; ++i) {
-          var errorCodeFound = false;
-
-          for (var j = 0, len2 = propertyData.length; j < len2; ++j) {
-            if (parseInt(errorCodes[i]) === parseInt(propertyData[j]['code'])) {
-              errorCodeFound = true;
-              if (getUtility().isNonEmptyString(value)) {
-                // error code exists and should be updated because message is not empty
-                propertyData[j]['message'] = value;
-              } else {
-                // error code exists but should be removed because message is empty
-                propertyData.splice(j, 1);
-                --len2;
-              }
-            }
-          }
-
-          if (!errorCodeFound) {
-            // add new codes because message is not empty
-            if (getUtility().isNonEmptyString(value)) {
-              errorCodeSubset.push({
-                code: errorCodes[i],
-                message: value
-              });
-            }
-          }
-        }
-
-        propertyData = propertyData.concat(errorCodeSubset);
-      }
-
-      return propertyData;
-    };
-
-    /**
-     * @private
-     *
-     * @param object
-     * @throws 1523904699
-     */
-    function _setRandomIds(html) {
-      assert(
-        'object' === $.type(html),
-        'Invalid input "html"',
-        1523904699
-      );
-
-      $(getHelper().getDomElementClassName('inspectorEditor', true)).each(function(e) {
-        var $parent = $(this),
-            idReplacements = {};
-
-        $(getHelper().getDomElementDataAttribute('randomId', 'bracesWithKey'), $parent).each(function(e) {
-            var $element = $(this),
-                targetAttribute = $element.attr(getHelper().getDomElementDataAttribute('randomIdTarget')),
-                randomIdIndex = $element.attr(getHelper().getDomElementDataAttribute('randomIdIndex'));
-
-            if ($element.is('[' + targetAttribute + ']')) {
-                return true;
-            }
-
-            if (!idReplacements.hasOwnProperty(randomIdIndex)) {
-              idReplacements[randomIdIndex] = 'fe' + Math.floor(Math.random() * 42) + Date.now();
-            }
-            $element.attr(targetAttribute, idReplacements[randomIdIndex]);
-        });
-      });
-    };
-
-    /* *************************************************************
-     * Public Methods
-     * ************************************************************/
-
-    /**
-     * @public
-     *
-     * @return object
-     */
-    function getInspectorDomElement() {
-      return $(getHelper().getDomElementDataIdentifierSelector('inspector'));
-    };
-
-    /**
-     * @public
-     *
-     * @return object
-     */
-    function getFinishersContainerDomElement() {
-      return $(getHelper().getDomElementDataIdentifierSelector('inspectorFinishers'), getInspectorDomElement());
-    };
-
-    /**
-     * @public
-     *
-     * @return object
-     */
-    function getValidatorsContainerDomElement() {
-      return $(getHelper().getDomElementDataIdentifierSelector('inspectorValidators'), getInspectorDomElement());
-    };
-
-    /**
-     * @public
-     *
-     * @param string
-     * @param string
-     * @return object
-     */
-    function getCollectionElementDomElement(collectionName, collectionElementIdentifier) {
-      if (collectionName === 'finishers') {
-        return $(getHelper().getDomElementDataAttribute(
-          'finisher',
-          'bracesWithKeyValue',
-          [collectionElementIdentifier]
-        ), getFinishersContainerDomElement());
-      } else {
-        return $(getHelper().getDomElementDataAttribute(
-          'validator',
-          'bracesWithKeyValue',
-          [collectionElementIdentifier]
-        ), getValidatorsContainerDomElement());
-      }
-    };
-
-    /**
-     * @public
-     *
-     * @param object
-     * @param function
-     * @return void
-     */
-    function renderEditors(formElement, callback) {
-      var formElementTypeDefinition;
-      if (getUtility().isUndefinedOrNull(formElement)) {
-        formElement = getCurrentlySelectedFormElement();
-      }
-
-      getInspectorDomElement().off().empty();
-
-      formElementTypeDefinition = getFormElementDefinition(formElement);
-      if ('array' !== $.type(formElementTypeDefinition['editors'])) {
-        return;
-      }
-
-      for (var i = 0, len = formElementTypeDefinition['editors'].length; i < len; ++i) {
-        var html, template;
-
-        template = getHelper()
-          .getTemplate(formElementTypeDefinition['editors'][i]['templateName'])
-          .clone();
-        if (!template.length) {
-          continue;
-        }
-        html = $(template.html());
-
-        $(html)
-          .first()
-          .addClass(getHelper().getDomElementClassName('inspectorEditor'));
-        getInspectorDomElement().append($(html));
-
-        _setRandomIds(html);
-        _renderEditorDispatcher(formElementTypeDefinition['editors'][i], html);
-      }
-
-      if ('function' === $.type(callback)) {
-        callback();
-      }
-    };
-
-    /**
-     * @public
-     *
-     * @param string collectionName
-     * @param string collectionElementIdentifier
-     * @return void
-     * @publish view/inspector/collectionElements/dnd/update
-     * @throws 1478354853
-     * @throws 1478354854
-     */
-    function renderCollectionElementEditors(collectionName, collectionElementIdentifier) {
-      var collapseWrapper, collectionContainer, collectionContainerElementWrapper,
-        collectionElementConfiguration, collectionElementEditorsLength;
-
-      assert(
-        getUtility().isNonEmptyString(collectionName),
-        'Invalid parameter "collectionName"',
-        1478354853
-      );
-      assert(
-        getUtility().isNonEmptyString(collectionElementIdentifier),
-        'Invalid parameter "collectionElementIdentifier"',
-        1478354854
-      );
-
-      collectionElementConfiguration = getFormEditorApp().getPropertyCollectionElementConfiguration(
-        collectionElementIdentifier,
-        collectionName
-      );
-      if ('array' !== $.type(collectionElementConfiguration['editors'])) {
-        return;
-      }
-
-      collectionContainerElementWrapper = $('<div></div>').addClass(getHelper().getDomElementClassName('collectionElement'));
-      if (collectionName === 'finishers') {
-        collectionContainer = getFinishersContainerDomElement();
-        collectionContainerElementWrapper
-          .attr(getHelper().getDomElementDataAttribute('finisher'), collectionElementIdentifier);
-      } else {
-        collectionContainer = getValidatorsContainerDomElement();
-        collectionContainerElementWrapper
-          .attr(getHelper().getDomElementDataAttribute('validator'), collectionElementIdentifier);
-      }
-      collectionContainer.append(collectionContainerElementWrapper);
-
-      collectionElementEditorsLength = collectionElementConfiguration['editors'].length;
-      if (
-        collectionElementEditorsLength > 0
-        && collectionElementConfiguration['editors'][0]['identifier'] === 'header'
-      ) {
-        collapseWrapper = $('<div role="tabpanel"></div>')
-          .addClass('panel-collapse collapse')
-          .prop('id', _getCollectionElementId(
-            collectionName,
-            collectionElementIdentifier
-          ));
-      }
-
-      for (var i = 0; i < collectionElementEditorsLength; ++i) {
-        var html, template;
-
-        template = getHelper()
-          .getTemplate(collectionElementConfiguration['editors'][i]['templateName'])
-          .clone();
-        if (!template.length) {
-          continue;
-        }
-        html = $(template.html());
-
-        $(html).first()
-          .addClass(_getCollectionElementClass(
-            collectionName,
-            collectionElementConfiguration['editors'][i]['identifier']
-          ))
-          .addClass(getHelper().getDomElementClassName('inspectorEditor'));
-
-        if (i === 0 && collapseWrapper) {
-          getCollectionElementDomElement(collectionName, collectionElementIdentifier)
-            .append(html)
-            .append(collapseWrapper);
-        } else if (
-          i === (collectionElementEditorsLength - 1)
-          && collapseWrapper
-          && collectionElementConfiguration['editors'][i]['identifier'] === 'removeButton'
-        ) {
-          getCollectionElementDomElement(collectionName, collectionElementIdentifier).append(html);
-        } else if (i > 0 && collapseWrapper) {
-          collapseWrapper.append(html);
-        } else {
-          getCollectionElementDomElement(collectionName, collectionElementIdentifier).append(html);
-        }
-
-        _setRandomIds(html);
-        _renderEditorDispatcher(
-          collectionElementConfiguration['editors'][i],
-          html,
-          collectionElementIdentifier,
-          collectionName
-        );
-      }
-
-      if (
-        (
-          collectionElementEditorsLength === 2
-          && collectionElementConfiguration['editors'][0]['identifier'] === 'header'
-          && collectionElementConfiguration['editors'][1]['identifier'] === 'removeButton'
-        ) || (
-          collectionElementEditorsLength === 1
-          && collectionElementConfiguration['editors'][0]['identifier'] === 'header'
-        )
-      ) {
-        $(getHelper().getDomElementDataIdentifierSelector('collapse'), collectionContainerElementWrapper).remove();
-      }
-
-      if (_configuration['isSortable']) {
-        _addSortableCollectionElementsEvents(collectionContainer, collectionName);
-      }
-    };
-
-    /**
-     * @public
-     *
-     * @string collectionName
-     * @param object editorConfiguration
-     * @param object editorHtml
-     * @return void
-     * @publish view/inspector/collectionElement/existing/selected
-     * @publish view/inspector/collectionElement/new/selected
-     * @throws 1475423098
-     * @throws 1475423099
-     * @throws 1475423100
-     * @throws 1475423101
-     * @throws 1478362968
-     */
-    function renderCollectionElementSelectionEditor(collectionName, editorConfiguration, editorHtml) {
-      var alreadySelectedCollectionElements, selectElement, collectionContainer,
-        removeSelectElement;
-      assert(
-        getUtility().isNonEmptyString(collectionName),
-        'Invalid configuration "collectionName"',
-        1478362968
-      );
-      assert(
-        'object' === $.type(editorConfiguration),
-        'Invalid parameter "editorConfiguration"',
-        1475423098
-      );
-      assert(
-        'object' === $.type(editorHtml),
-        'Invalid parameter "editorHtml"',
-        1475423099
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['label']),
-        'Invalid configuration "label"',
-        1475423100
-      );
-      assert(
-        'array' === $.type(editorConfiguration['selectOptions']),
-        'Invalid configuration "selectOptions"',
-        1475423101
-      );
-
-      if (collectionName === 'finishers') {
-        collectionContainer = getFinishersContainerDomElement();
-        alreadySelectedCollectionElements = getRootFormElement().get(collectionName);
-      } else {
-        collectionContainer = getValidatorsContainerDomElement();
-        alreadySelectedCollectionElements = getCurrentlySelectedFormElement().get(collectionName);
-      }
-
-      collectionContainer.off().empty();
-
-      getHelper().getTemplatePropertyDomElement('label', editorHtml).text(editorConfiguration['label']);
-      selectElement = getHelper().getTemplatePropertyDomElement('selectOptions', editorHtml);
-
-      if (!getUtility().isUndefinedOrNull(alreadySelectedCollectionElements)) {
-        for (var i = 0, len = alreadySelectedCollectionElements.length; i < len; ++i) {
-          getPublisherSubscriber().publish('view/inspector/collectionElement/existing/selected', [
-            alreadySelectedCollectionElements[i]['identifier'],
-            collectionName
-          ]);
-        }
-      }
-
-      removeSelectElement = true;
-      for (var i = 0, len1 = editorConfiguration['selectOptions'].length; i < len1; ++i) {
-        var appendOption = true;
-        if (!getUtility().isUndefinedOrNull(alreadySelectedCollectionElements)) {
-          for (var j = 0, len2 = alreadySelectedCollectionElements.length; j < len2; ++j) {
-            if (alreadySelectedCollectionElements[j]['identifier'] === editorConfiguration['selectOptions'][i]['value']) {
-              appendOption = false;
-              break;
-            }
-          }
-        }
-        if (appendOption) {
-          selectElement.append(new Option(
-            editorConfiguration['selectOptions'][i]['label'],
-            editorConfiguration['selectOptions'][i]['value']
-          ));
-          if (editorConfiguration['selectOptions'][i]['value'] !== '') {
-            removeSelectElement = false;
-          }
-        }
-      }
-
-      if (removeSelectElement) {
-        selectElement.off().empty().remove();
-      }
-
-      selectElement.on('change', function() {
-        if ($(this).val() !== '') {
-          var value = $(this).val();
-          $('option[value="' + value + '"]', $(this)).remove();
-
-          getFormEditorApp().getPublisherSubscriber().publish(
-            'view/inspector/collectionElement/new/selected',
-            [value, collectionName]
-          );
-        }
-      });
-    };
-
-    /**
-     * @public
-     *
-     * @param object editorConfiguration
-     * @param object editorHtml
-     * @param string collectionElementIdentifier
-     * @param string collectionName
-     * @return void
-     * @throws 1475421525
-     * @throws 1475421526
-     * @throws 1475421527
-     * @throws 1475421528
-     */
-    function renderFormElementHeaderEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
-      assert('object' === $.type(editorConfiguration), 'Invalid parameter "editorConfiguration"', 1475421525);
-      assert('object' === $.type(editorHtml), 'Invalid parameter "editorHtml"', 1475421526);
-
-      Icons.getIcon(
-        getFormElementDefinition(getCurrentlySelectedFormElement(), 'iconIdentifier'),
-        Icons.sizes.small,
-        null,
-        Icons.states.default
-      ).then(function(icon) {
-        getHelper().getTemplatePropertyDomElement('header-label', editorHtml)
-          .append($(icon).addClass(getHelper().getDomElementClassName('icon')))
-          .append(buildTitleByFormElement());
-      });
-    };
-
-    /**
-     * @public
-     *
-     * @param object editorConfiguration
-     * @param object editorHtml
-     * @param string collectionElementIdentifier
-     * @param string collectionName
-     * @return void
-     * @throws 1475421257
-     * @throws 1475421258
-     * @throws 1475421259
-     */
-    function renderCollectionElementHeaderEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
-      var collectionElementConfiguration, setData;
-
-      assert(
-        'object' === $.type(editorConfiguration),
-        'Invalid parameter "editorConfiguration"',
-        1475421258
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['label']),
-        'Invalid configuration "label"',
-        1475421257
-      );
-      assert(
-        'object' === $.type(editorHtml),
-        'Invalid parameter "editorHtml"',
-        1475421259
-      );
-
-      setData = function(icon) {
-        getHelper()
-          .getTemplatePropertyDomElement('header-label', editorHtml)
-          .prepend($(icon));
-
-        const editors = getFormEditorApp().getPropertyCollectionElementConfiguration(
-          collectionElementIdentifier,
-          collectionName
-        ).editors;
-
-        if (!(
-          (
-            editors.length === 2
-            && editors[0]['identifier'] === 'header'
-            && editors[1]['identifier'] === 'removeButton'
-          ) || (
-            editors.length === 1
-            && editors[0]['identifier'] === 'header'
-          ))
-        ) {
-          Icons.getIcon(
-            getHelper().getDomElementDataAttributeValue('collapse'),
-            Icons.sizes.small,
-            null,
-            Icons.states.default,
-            Icons.markupIdentifiers.inline
-          ).then(function(icon) {
-            var iconWrap;
-            iconWrap = $('<a></a>')
-              .attr('href', _getCollectionElementId(collectionName, collectionElementIdentifier, true))
-              .attr('data-bs-toggle', 'collapse')
-              .attr('aria-expanded', 'false')
-              .attr('aria-controls', _getCollectionElementId(collectionName, collectionElementIdentifier))
-              .addClass('collapsed')
-              .append($(icon));
-
-            getHelper()
-              .getTemplatePropertyDomElement('header-label', editorHtml)
-              .prepend(iconWrap);
-          });
-        };
-      }
-
-      collectionElementConfiguration = getFormEditorApp().getFormEditorDefinition(collectionName, collectionElementIdentifier);
-      Icons.getIcon(
-        collectionElementConfiguration['iconIdentifier'],
-        Icons.sizes.small,
-        null,
-        Icons.states.default
-      ).then(function(icon) {
-        setData(icon);
-      });
-
-      if (editorConfiguration['label']) {
-        getHelper().getTemplatePropertyDomElement('label', editorHtml).append(editorConfiguration['label']);
-      }
-    };
-
-    function renderMaximumFileSizeEditor(editorConfiguration, editorHtml) {
-      assert(
-        'object' === $.type(editorConfiguration),
-        'Invalid parameter "editorConfiguration"',
-        1475421258
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['label']),
-        'Invalid configuration "label"',
-        1475421257
-      );
-      assert(
-        'object' === $.type(editorHtml),
-        'Invalid parameter "editorHtml"',
-        1475421259
-      );
-
-      if (editorConfiguration['label']) {
-        var element = getHelper().getTemplatePropertyDomElement('label', editorHtml);
-        var maximumFileSize = element.attr(getHelper().getDomElementDataAttribute('maximumFileSize'));
-        element.append(editorConfiguration['label'].replace('{0}', maximumFileSize));
-      }
-    };
-
-    /**
-     * @public
-     *
-     * @param object editorConfiguration
-     * @param object editorHtml
-     * @param string collectionElementIdentifier
-     * @param string collectionName
-     * @return void
-     * @throws 1475421053
-     * @throws 1475421054
-     * @throws 1475421055
-     * @throws 1475421056
-     */
-    function renderTextEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
-      var propertyData, propertyPath;
-      assert(
-        'object' === $.type(editorConfiguration),
-        'Invalid parameter "editorConfiguration"',
-        1475421053
-      );
-      assert(
-        'object' === $.type(editorHtml),
-        'Invalid parameter "editorHtml"',
-        1475421054
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['label']),
-        'Invalid configuration "label"',
-        1475421055
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['propertyPath']),
-        'Invalid configuration "propertyPath"',
-        1475421056
-      );
-
-      getHelper()
-        .getTemplatePropertyDomElement('label', editorHtml)
-        .append(editorConfiguration['label']);
-      if (getUtility().isNonEmptyString(editorConfiguration['fieldExplanationText'])) {
-        getHelper()
-          .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
-          .text(editorConfiguration['fieldExplanationText']);
-      } else {
-        getHelper()
-          .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
-          .remove();
-      }
-
-      if (getUtility().isNonEmptyString(editorConfiguration['placeholder'])) {
-        getHelper()
-          .getTemplatePropertyDomElement('propertyPath', editorHtml)
-          .attr('placeholder', editorConfiguration['placeholder']);
-      }
-
-      propertyPath = getFormEditorApp().buildPropertyPath(
-        editorConfiguration['propertyPath'],
-        collectionElementIdentifier,
-        collectionName
-      );
-      propertyData = getCurrentlySelectedFormElement().get(propertyPath);
-
-      _validateCollectionElement(propertyPath, editorHtml);
-
-      getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).val(propertyData);
-
-      if (
-        !getUtility().isUndefinedOrNull(editorConfiguration['additionalElementPropertyPaths'])
-        && 'array' === $.type(editorConfiguration['additionalElementPropertyPaths'])
-      ) {
-        for (var i = 0, len = editorConfiguration['additionalElementPropertyPaths'].length; i < len; ++i) {
-          getCurrentlySelectedFormElement().set(editorConfiguration['additionalElementPropertyPaths'][i], propertyData);
-        }
-      }
-
-      renderFormElementSelectorEditorAddition(editorConfiguration, editorHtml, propertyPath);
-
-      getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).on('keyup paste', function() {
-        if (
-          !!editorConfiguration['doNotSetIfPropertyValueIsEmpty']
-          && !getUtility().isNonEmptyString($(this).val())
-        ) {
-          getCurrentlySelectedFormElement().unset(propertyPath);
-        } else {
-          getCurrentlySelectedFormElement().set(propertyPath, $(this).val());
-        }
-        _validateCollectionElement(propertyPath, editorHtml);
-        if (
-          !getUtility().isUndefinedOrNull(editorConfiguration['additionalElementPropertyPaths'])
-          && 'array' === $.type(editorConfiguration['additionalElementPropertyPaths'])
-        ) {
-          for (var i = 0, len = editorConfiguration['additionalElementPropertyPaths'].length; i < len; ++i) {
-            if (
-              !!editorConfiguration['doNotSetIfPropertyValueIsEmpty']
-              && !getUtility().isNonEmptyString($(this).val())
-            ) {
-              getCurrentlySelectedFormElement().unset(editorConfiguration['additionalElementPropertyPaths'][i]);
-            } else {
-              getCurrentlySelectedFormElement().set(editorConfiguration['additionalElementPropertyPaths'][i], $(this).val());
-            }
-          }
-        }
-      });
-    };
-
-    /**
-     * @public
-     *
-     * @param object editorConfiguration
-     * @param object editorHtml
-     * @param string collectionElementIdentifier
-     * @param string collectionName
-     * @return void
-     * @throws 1489874120
-     * @throws 1489874121
-     * @throws 1489874122
-     * @throws 1489874123
-     */
-    function renderValidationErrorMessageEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
-      var propertyData, propertyPath, validationErrorMessage;
-      assert(
-        'object' === $.type(editorConfiguration),
-        'Invalid parameter "editorConfiguration"',
-        1489874121
-      );
-      assert(
-       'object' === $.type(editorHtml),
-       'Invalid parameter "editorHtml"',
-       1489874122
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['label']),
-        'Invalid configuration "label"',
-        1489874123
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['propertyPath']),
-        'Invalid configuration "propertyPath"',
-        1489874124
-      );
-
-      getHelper()
-        .getTemplatePropertyDomElement('label', editorHtml)
-        .append(editorConfiguration['label']);
-      if (getUtility().isNonEmptyString(editorConfiguration['fieldExplanationText'])) {
-        getHelper()
-          .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
-          .text(editorConfiguration['fieldExplanationText']);
-      } else {
-        getHelper()
-          .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
-          .remove();
-      }
-
-      propertyPath = getFormEditorApp().buildPropertyPath(
-        editorConfiguration['propertyPath']
-      );
-
-      propertyData = getCurrentlySelectedFormElement().get(propertyPath);
-
-      if (
-        !getUtility().isUndefinedOrNull(propertyData)
-        && 'array' === $.type(propertyData)
-      ) {
-        validationErrorMessage = _getFirstAvailableValidationErrorMessage(editorConfiguration['errorCodes'], propertyData);
-
-        if (!getUtility().isUndefinedOrNull(validationErrorMessage)) {
-          getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).val(validationErrorMessage);
-        }
-      }
-
-      getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).on('keyup paste', function() {
-        propertyData = getCurrentlySelectedFormElement().get(propertyPath);
-        if (getUtility().isUndefinedOrNull(propertyData)) {
-          propertyData = [];
-        }
-        getCurrentlySelectedFormElement().set(propertyPath, _renewValidationErrorMessages(
-          editorConfiguration['errorCodes'],
-          propertyData,
-          $(this).val()
-        ));
-      });
-    };
-
-    /**
-     * @public
-     *
-     * @param object editorConfiguration
-     * @param object editorHtml
-     * @param string collectionElementIdentifier
-     * @param string collectionName
-     * @return void
-     * @throws 1674826430
-     * @throws 1674826431
-     * @throws 1674826432
-     */
-    function renderCountrySelectEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
-      var propertyData, propertyPath, selectElement, options;
-      assert(
-        'object' === $.type(editorConfiguration),
-        'Invalid parameter "editorConfiguration"',
-        1674826430
-      );
-      assert(
-        'object' === $.type(editorHtml),
-        'Invalid parameter "editorHtml"',
-        1674826431
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['label']),
-        'Invalid configuration "label"',
-        1674826432
-      );
-
-      propertyPath = getFormEditorApp().buildPropertyPath(
-        editorConfiguration['propertyPath'],
-        collectionElementIdentifier,
-        collectionName
-      );
-
-      getHelper()
-        .getTemplatePropertyDomElement('label', editorHtml)
-        .append(editorConfiguration['label']);
-
-      selectElement = getHelper()
-        .getTemplatePropertyDomElement('selectOptions', editorHtml);
-
-      propertyData = getCurrentlySelectedFormElement().get(propertyPath);
-
-      options = $('option', selectElement);
-      selectElement.empty();
-
-      for (var i = 0, len = options.length; i < len; ++i) {
-        var option, selected = false;
-
-        for (var propertyDataKey in propertyData) {
-          if (!propertyData.hasOwnProperty(propertyDataKey)) {
-            continue;
-          }
-
-          if (options[i].value === propertyData[propertyDataKey]) {
-            selected = true;
-            break;
-          }
-        }
-
-        option = new Option(options[i].text, i, false, selected);
-        $(option).data({value: options[i].value});
-        selectElement.append(option);
-      }
-
-      selectElement.on('change', function() {
-        var selectValues = [];
-        $('option:selected', $(this)).each(function(i) {
-          selectValues.push($(this).data('value'));
-        });
-
-        getCurrentlySelectedFormElement().set(propertyPath, selectValues);
-      });
-    };
-
-    /**
-     * @public
-     *
-     * @param object editorConfiguration
-     * @param object editorHtml
-     * @param string collectionElementIdentifier
-     * @param string collectionName
-     * @return void
-     * @throws 1475421048
-     * @throws 1475421049
-     * @throws 1475421050
-     * @throws 1475421051
-     * @throws 1475421052
-     */
-    function renderSingleSelectEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
-      var propertyData, propertyPath, selectElement;
-      assert(
-        'object' === $.type(editorConfiguration),
-        'Invalid parameter "editorConfiguration"',
-        1475421048
-      );
-      assert(
-        'object' === $.type(editorHtml),
-        'Invalid parameter "editorHtml"',
-        1475421049
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['label']),
-        'Invalid configuration "label"',
-        1475421050
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['propertyPath']),
-        'Invalid configuration "propertyPath"',
-        1475421051
-      );
-      assert(
-        'array' === $.type(editorConfiguration['selectOptions']),
-        'Invalid configuration "selectOptions"',
-        1475421052
-      );
-
-      propertyPath = getFormEditorApp().buildPropertyPath(
-        editorConfiguration['propertyPath'],
-        collectionElementIdentifier,
-        collectionName
-      );
-
-      getHelper()
-        .getTemplatePropertyDomElement('label', editorHtml)
-        .append(editorConfiguration['label']);
-
-      selectElement = getHelper()
-        .getTemplatePropertyDomElement('selectOptions', editorHtml);
-
-      propertyData = getCurrentlySelectedFormElement().get(propertyPath);
-
-      for (var i = 0, len = editorConfiguration['selectOptions'].length; i < len; ++i) {
-        var option;
-
-        if (editorConfiguration['selectOptions'][i]['value'] === propertyData) {
-          option = new Option(editorConfiguration['selectOptions'][i]['label'], i, false, true);
-        } else {
-          option = new Option(editorConfiguration['selectOptions'][i]['label'], i);
-        }
-        $(option).data({value: editorConfiguration['selectOptions'][i]['value']});
-        selectElement.append(option);
-      }
-
-      selectElement.on('change', function() {
-        getCurrentlySelectedFormElement().set(propertyPath, $('option:selected', $(this)).data('value'));
-      });
-    };
-
-    /**
-     * @public
-     *
-     * @param object editorConfiguration
-     * @param object editorHtml
-     * @param string collectionElementIdentifier
-     * @param string collectionName
-     * @return void
-     * @throws 1485712399
-     * @throws 1485712400
-     * @throws 1485712401
-     * @throws 1485712402
-     * @throws 1485712403
-     */
-    function renderMultiSelectEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
-      var propertyData, propertyPath, selectElement;
-      assert(
-        'object' === $.type(editorConfiguration),
-        'Invalid parameter "editorConfiguration"',
-        1485712399
-      );
-      assert(
-        'object' === $.type(editorHtml),
-        'Invalid parameter "editorHtml"',
-        1485712400
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['label']),
-        'Invalid configuration "label"',
-        1485712401
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['propertyPath']),
-        'Invalid configuration "propertyPath"',
-        1485712402
-      );
-      assert(
-        'array' === $.type(editorConfiguration['selectOptions']),
-        'Invalid configuration "selectOptions"',
-        1485712403
-      );
-
-      propertyPath = getFormEditorApp().buildPropertyPath(
-        editorConfiguration['propertyPath'],
-        collectionElementIdentifier,
-        collectionName
-      );
-
-      getHelper()
-        .getTemplatePropertyDomElement('label', editorHtml)
-        .append(editorConfiguration['label']);
-
-      selectElement = getHelper()
-        .getTemplatePropertyDomElement('selectOptions', editorHtml);
-
-      propertyData = getCurrentlySelectedFormElement().get(propertyPath);
-
-      for (var i = 0, len1 = editorConfiguration['selectOptions'].length; i < len1; ++i) {
-        var option, value;
-
-        option = null;
-        for (var propertyDataKey in propertyData) {
-          if (!propertyData.hasOwnProperty(propertyDataKey)) {
-            continue;
-          }
-          if (editorConfiguration['selectOptions'][i]['value'] === propertyData[propertyDataKey]) {
-            option = new Option(editorConfiguration['selectOptions'][i]['label'], i, false, true);
-            break;
-          }
-        }
-
-        if (!option) {
-          option = new Option(editorConfiguration['selectOptions'][i]['label'], i);
-        }
-
-        $(option).data({value: editorConfiguration['selectOptions'][i]['value']});
-
-        selectElement.append(option);
-      }
-
-      selectElement.on('change', function() {
-        var selectValues = [];
-        $('option:selected', $(this)).each(function(i) {
-          selectValues.push($(this).data('value'));
-        });
-
-        getCurrentlySelectedFormElement().set(propertyPath, selectValues);
-      });
-    };
-
-    /**
-     * @public
-     *
-     * @param object editorConfiguration
-     * @param object editorHtml
-     * @param string collectionElementIdentifier
-     * @param string collectionName
-     * @return void
-     * @throws 1489528242
-     * @throws 1489528243
-     * @throws 1489528244
-     * @throws 1489528245
-     * @throws 1489528246
-     * @throws 1489528247
-     */
-    function renderGridColumnViewPortConfigurationEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
-      var editorControlsWrapper, initNumbersOfColumnsField, numbersOfColumnsTemplate, selectElement,
-        viewportButtonTemplate;
-      assert(
-        'object' === $.type(editorConfiguration),
-        'Invalid parameter "editorConfiguration"',
-        1489528242
-      );
-      assert(
-        'object' === $.type(editorHtml),
-        'Invalid parameter "editorHtml"',
-        1489528243
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['label']),
-        'Invalid configuration "label"',
-        1489528244
-      );
-      assert(
-        'array' === $.type(editorConfiguration['configurationOptions']['viewPorts']),
-        'Invalid configurationOptions "viewPorts"',
-        1489528245
-      );
-      assert(
-        !getUtility().isUndefinedOrNull(editorConfiguration['configurationOptions']['numbersOfColumnsToUse']['label']),
-        'Invalid configurationOptions "numbersOfColumnsToUse"',
-        1489528246
-      );
-      assert(
-        !getUtility().isUndefinedOrNull(editorConfiguration['configurationOptions']['numbersOfColumnsToUse']['propertyPath']),
-        'Invalid configuration "selectOptions"',
-        1489528247
-      );
-
-      if (!getFormElementDefinition(getCurrentlySelectedFormElement().get('__parentRenderable'), '_isGridRowFormElement')) {
-        editorHtml.remove();
-        return;
-      }
-
-      getHelper()
-        .getTemplatePropertyDomElement('label', editorHtml)
-        .append(editorConfiguration['label']);
-
-
-      viewportButtonTemplate = $(getHelper()
-        .getDomElementDataIdentifierSelector('viewportButton'), $(editorHtml))
-        .clone();
-
-      $(getHelper()
-        .getDomElementDataIdentifierSelector('viewportButton'), $(editorHtml))
-        .remove();
-
-      numbersOfColumnsTemplate = getHelper()
-        .getTemplatePropertyDomElement('numbersOfColumnsToUse', $(editorHtml))
-        .clone();
-
-      getHelper()
-        .getTemplatePropertyDomElement('numbersOfColumnsToUse', $(editorHtml))
-        .remove();
-
-      editorControlsWrapper = _getEditorControlsWrapperDomElement(editorHtml);
-
-      initNumbersOfColumnsField = function(element) {
-        var numbersOfColumnsTemplateClone, propertyPath;
-
-        getHelper().getTemplatePropertyDomElement('numbersOfColumnsToUse', $(editorHtml))
-          .off()
-          .empty()
-          .remove();
-
-        numbersOfColumnsTemplateClone = $(numbersOfColumnsTemplate).clone(true, true);
-        _getEditorWrapperDomElement(editorHtml).after(numbersOfColumnsTemplateClone);
-
-        $('input', numbersOfColumnsTemplateClone).focus();
-
-        getHelper()
-          .getTemplatePropertyDomElement('numbersOfColumnsToUse-label', numbersOfColumnsTemplateClone)
-          .append(
-            editorConfiguration['configurationOptions']['numbersOfColumnsToUse']['label']
-              .replace('{@viewPortLabel}', element.data('viewPortLabel'))
-          );
-
-        getHelper()
-          .getTemplatePropertyDomElement('numbersOfColumnsToUse-fieldExplanationText', numbersOfColumnsTemplateClone)
-          .append(editorConfiguration['configurationOptions']['numbersOfColumnsToUse']['fieldExplanationText']);
-
-        propertyPath = editorConfiguration['configurationOptions']['numbersOfColumnsToUse']['propertyPath']
-          .replace('{@viewPortIdentifier}', element.data('viewPortIdentifier'));
-
-        getHelper()
-          .getTemplatePropertyDomElement('numbersOfColumnsToUse-propertyPath', numbersOfColumnsTemplateClone)
-          .val(getCurrentlySelectedFormElement().get(propertyPath));
-
-        getHelper().getTemplatePropertyDomElement('numbersOfColumnsToUse-propertyPath', numbersOfColumnsTemplateClone).on('keyup paste change', function() {
-          var that = $(this);
-          if (!$.isNumeric(that.val())) {
-            that.val('');
-          }
-          getCurrentlySelectedFormElement().set(propertyPath, that.val());
-        });
-      };
-
-      for (var i = 0, len = editorConfiguration['configurationOptions']['viewPorts'].length; i < len; ++i) {
-        var numbersOfColumnsTemplateClone, viewportButtonTemplateClone, viewPortIdentifier,
-          viewPortLabel;
-
-        viewPortIdentifier = editorConfiguration['configurationOptions']['viewPorts'][i]['viewPortIdentifier'];
-        viewPortLabel = editorConfiguration['configurationOptions']['viewPorts'][i]['label'];
-
-        viewportButtonTemplateClone = $(viewportButtonTemplate).clone(true, true);
-        viewportButtonTemplateClone.text(viewPortIdentifier);
-        viewportButtonTemplateClone.data('viewPortIdentifier', viewPortIdentifier);
-        viewportButtonTemplateClone.data('viewPortLabel', viewPortLabel);
-        viewportButtonTemplateClone.attr('title', viewPortLabel);
-        editorControlsWrapper.append(viewportButtonTemplateClone);
-
-        if (i === (len - 1)) {
-          numbersOfColumnsTemplateClone = $(numbersOfColumnsTemplate).clone(true, true);
-          _getEditorWrapperDomElement(editorHtml).after(numbersOfColumnsTemplateClone);
-          initNumbersOfColumnsField(viewportButtonTemplateClone);
-          viewportButtonTemplateClone.addClass(getHelper().getDomElementClassName('active'));
-        }
-
-        $('button', editorControlsWrapper).on('click', function() {
-          var that = $(this);
-
-          $('button', editorControlsWrapper).removeClass(getHelper().getDomElementClassName('active'));
-          that.addClass(getHelper().getDomElementClassName('active'));
-
-          initNumbersOfColumnsField(that);
-        });
-      }
-    };
-
-    /**
-     * @public
-     *
-     * @param object editorConfiguration
-     * @param object editorHtml
-     * @param string collectionElementIdentifier
-     * @param string collectionName
-     * @return void
-     * @throws 1475419226
-     * @throws 1475419227
-     * @throws 1475419228
-     * @throws 1475419229
-     * @throws 1475419230
-     * @throws 1475419231
-     * @throws 1475419232
-     */
-    function renderPropertyGridEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
-      var addRowTemplate, gridColumns, defaultValue, multiSelection, propertyData, propertyPathPrefix,
-        rowItemTemplate, setData, useLabelAsFallbackValue;
-      assert(
-        'object' === $.type(editorConfiguration),
-        'Invalid parameter "editorConfiguration"',
-        1475419226
-      );
-      assert(
-        'object' === $.type(editorHtml),
-        'Invalid parameter "editorHtml"',
-        1475419227
-      );
-      assert(
-        'boolean' === $.type(editorConfiguration['enableAddRow']),
-        'Invalid configuration "enableAddRow"',
-        1475419228
-      );
-      assert(
-        'boolean' === $.type(editorConfiguration['enableDeleteRow']),
-        'Invalid configuration "enableDeleteRow"',
-        1475419230
-      );
-      assert(
-        'boolean' === $.type(editorConfiguration['isSortable']),
-        'Invalid configuration "isSortable"',
-        1475419229
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['propertyPath']),
-        'Invalid configuration "propertyPath"',
-        1475419231
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['label']),
-        'Invalid configuration "label"',
-        1475419232
-      );
-
-      getHelper().getTemplatePropertyDomElement('label', editorHtml)
-        .append(editorConfiguration['label']);
-      if (getUtility().isNonEmptyString(editorConfiguration['fieldExplanationText'])) {
-        getHelper()
-          .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
-          .text(editorConfiguration['fieldExplanationText']);
-      } else {
-        getHelper()
-          .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
-          .remove();
-      }
-
-      propertyPathPrefix = getFormEditorApp().buildPropertyPath(
-        undefined,
-        collectionElementIdentifier,
-        collectionName,
-        undefined,
-        true
-      );
-      if (getUtility().isNonEmptyString(propertyPathPrefix)) {
-        propertyPathPrefix = propertyPathPrefix + '.';
-      }
-
-      if (getUtility().isUndefinedOrNull(editorConfiguration['useLabelAsFallbackValue'])) {
-        useLabelAsFallbackValue = true;
-      } else {
-        useLabelAsFallbackValue = editorConfiguration['useLabelAsFallbackValue'];
-      }
-
-      gridColumns = [
-        {name: 'label', title: 'Label'},
-        {name: 'value', title: 'Value'},
-        {name: 'selected', title: 'Selected'},
-      ];
-      if (getUtility().isNonEmptyArray(editorConfiguration['gridColumns'])) {
-        gridColumns = editorConfiguration['gridColumns'];
-      }
-      var orderedGridColumnNames = gridColumns.map(function(item) {
-        return item.name;
-      });
-      var orderedGridColumnTitles = gridColumns.map(function(item) {
-        return item.title || null;
-      });
-
-      $([
-        getHelper().getDomElementDataIdentifierSelector('propertyGridEditorHeaderRow'),
-        getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'),
-        getHelper().getDomElementDataIdentifierSelector('propertyGridEditorAddRowItem'),
-      ].join(','), $(editorHtml)).each(function (i, row) {
-        var $columns = $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorColumn'), row);
-        var $columnsAfter = $columns.last().nextAll();
-        var columnsByName = {};
-
-        // Collect columns by names, skip undesired columns
-        $columns
-          .detach()
-          .each(function(i, element) {
-            var $column = $(element);
-            var columnName = $column.data('column');
-
-            if (!orderedGridColumnNames.includes(columnName)) {
-              return;
-            }
-
-            columnsByName[columnName] = $column;
-          });
-
-        // Insert columns in desired order
-        orderedGridColumnNames.forEach(function(columnName, i) {
-          var $column = columnsByName[columnName];
-
-          if ($column.is('th')) {
-            $column.append(orderedGridColumnTitles[i]);
-          }
-
-          $column.appendTo(row);
-        });
-
-        // Insert remaining columns
-        $columnsAfter.appendTo(row);
-      });
-
-      if (getUtility().isUndefinedOrNull(editorConfiguration['multiSelection'])) {
-        multiSelection = false;
-      } else {
-        multiSelection = !!editorConfiguration['multiSelection'];
-      }
-
-      rowItemTemplate = $(
-        getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'),
-        $(editorHtml)
-      ).clone();
-      $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'), $(editorHtml)).remove();
-
-      if (!!editorConfiguration['enableDeleteRow']) {
-        $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorDeleteRow'),
-          $(rowItemTemplate)
-        ).on('click', function() {
-          $(this)
-            .closest(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'))
-            .off()
-            .empty()
-            .remove();
-
-          _setPropertyGridData(
-            $(editorHtml),
-            multiSelection,
-            editorConfiguration['propertyPath'],
-            propertyPathPrefix
-          );
-        });
-      } else {
-        $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorDeleteRow'), $(rowItemTemplate))
-          .parent()
-          .off()
-          .empty();
-      }
-
-      if (!!editorConfiguration['isSortable']) {
-        editorHtml.get(0).querySelectorAll(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorContainer')  + ' tbody').forEach(function (sortableList) {
-          new Sortable(sortableList, {
-            group: getHelper().getDomElementDataAttributeValue('propertyGridEditorContainer'),
-            handle: getHelper().getDomElementDataIdentifierSelector('propertyGridEditorSortRow'),
-            draggable: getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'),
-            pull: 'clone',
-            swapThreshold: 0.6,
-            dragClass: 'form-sortable-drag',
-            ghostClass: 'form-sortable-ghost',
-            onUpdate: function() {
-              _setPropertyGridData(
-                $(editorHtml),
-                multiSelection,
-                editorConfiguration['propertyPath'],
-                propertyPathPrefix
-              );
-            }
-          });
-        });
-      } else {
-        $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorSortRow'), $(rowItemTemplate))
-          .parent()
-          .off()
-          .empty();
-      }
-
-      $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorSelectValue'),
-        $(rowItemTemplate)
-      ).on('change', function() {
-        if (!multiSelection) {
-          $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorSelectValue') + ':checked', $(editorHtml))
-            .not($(this))
-            .prop('checked', false);
-        }
-        _setPropertyGridData(
-          $(editorHtml),
-          multiSelection,
-          editorConfiguration['propertyPath'],
-          propertyPathPrefix
-        );
-      });
-
-      $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorLabel') + ',' +
-        getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'),
-        $(rowItemTemplate)
-      ).on('keyup paste', function() {
-        _setPropertyGridData(
-          $(editorHtml),
-          multiSelection,
-          editorConfiguration['propertyPath'],
-          propertyPathPrefix
-         );
-      });
-
-      if (useLabelAsFallbackValue) {
-        $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorLabel'),
-          $(rowItemTemplate)
-        ).on('focusout', function() {
-          if ('' === $(this)
-              .closest(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'))
-              .find(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'))
-              .val()
-          ) {
-            $(this)
-              .closest(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorRowItem'))
-              .find(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'))
-              .val($(this).val());
-          }
-        });
-      }
-
-      if (!!editorConfiguration['enableAddRow']) {
-        addRowTemplate = $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorAddRowItem'), $(editorHtml)).clone();
-        $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorAddRowItem'), $(editorHtml)).remove();
-
-        $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorAddRow'), $(addRowTemplate)).on('click', function() {
-          $(this)
-            .closest(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorAddRowItem'))
-            .before($(rowItemTemplate).clone(true, true));
-
-            _setPropertyGridData(
-              $(editorHtml),
-              multiSelection,
-              editorConfiguration['propertyPath'],
-              propertyPathPrefix
-            );
-        });
-        $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorContainer'), $(editorHtml))
-          .prepend($(addRowTemplate).clone(true, true));
-      } else {
-        $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorAddRowItem'), $(editorHtml)).remove();
-      }
-
-      defaultValue = {};
-      if (multiSelection) {
-        if (!getUtility().isUndefinedOrNull(getCurrentlySelectedFormElement().get(propertyPathPrefix + 'defaultValue'))) {
-          defaultValue = getCurrentlySelectedFormElement().get(propertyPathPrefix + 'defaultValue');
-        }
-      } else {
-        if (!getUtility().isUndefinedOrNull(getCurrentlySelectedFormElement().get(propertyPathPrefix + 'defaultValue'))) {
-          defaultValue = {0: getCurrentlySelectedFormElement().get(propertyPathPrefix + 'defaultValue')};
-        }
-      }
-      propertyData = getCurrentlySelectedFormElement().get(propertyPathPrefix + editorConfiguration['propertyPath']) || {};
-
-      setData = function(label, value) {
-        var isPreselected, newRowTemplate;
-
-        isPreselected = false;
-        newRowTemplate = $(rowItemTemplate).clone(true, true);
-
-        for (var defaultValueKey in defaultValue) {
-          if (!defaultValue.hasOwnProperty(defaultValueKey)) {
-            continue;
-          }
-          if (defaultValue[defaultValueKey] === value) {
-            isPreselected = true;
-            break;
-          }
-        }
-
-        $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorLabel'), $(newRowTemplate)).val(label);
-        $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorValue'), $(newRowTemplate)).val(value);
-
-        if (isPreselected) {
-          $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorSelectValue'), $(newRowTemplate))
-            .prop('checked', true);
-        }
-
-        if (!!editorConfiguration['enableAddRow']) {
-          $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorAddRowItem'), $(editorHtml))
-            .before($(newRowTemplate));
-        } else {
-          $(getHelper().getDomElementDataIdentifierSelector('propertyGridEditorContainer'), $(editorHtml))
-            .prepend($(newRowTemplate));
-        }
-      };
-
-      if ('object' === $.type(propertyData)) {
-        for (var propertyDataKey in propertyData) {
-          if (!propertyData.hasOwnProperty(propertyDataKey)) {
-            continue;
-          }
-          setData(propertyData[propertyDataKey], propertyDataKey);
-        }
-      } else if ('array' === $.type(propertyData)) {
-        for (var propertyDataKey in propertyData) {
-          if (!propertyData.hasOwnProperty(propertyDataKey)) {
-            continue;
-          }
-          if (getUtility().isUndefinedOrNull(propertyData[propertyDataKey]['_label'])) {
-            setData(propertyData[propertyDataKey], propertyDataKey);
-          } else {
-            setData(propertyData[propertyDataKey]['_label'], propertyData[propertyDataKey]['_value']);
-          }
-        }
-      }
-
-      _validateCollectionElement(propertyPathPrefix + editorConfiguration['propertyPath'], editorHtml);
-    };
-
-    /**
-     * @public
-     *
-     * @param object editorConfiguration
-     * @param object editorHtml
-     * @param string collectionElementIdentifier
-     * @param string collectionName
-     * @return void
-     * @publish view/inspector/collectionElement/new/selected
-     * @publish view/inspector/removeCollectionElement/perform
-     * @throws 1475417093
-     * @throws 1475417094
-     * @throws 1475417095
-     * @throws 1475417096
-     */
-    function renderRequiredValidatorEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
-      var propertyData, propertyPath, propertyValue, showValidationErrorMessage, validationErrorMessage, validationErrorMessagePropertyPath, validationErrorMessageTemplate, validationErrorMessageTemplateClone, validatorIdentifier;
-      assert(
-        'object' === $.type(editorConfiguration),
-        'Invalid parameter "editorConfiguration"',
-        1475417093
-      );
-      assert(
-        'object' === $.type(editorHtml),
-        'Invalid parameter "editorHtml"',
-        1475417094
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['validatorIdentifier']),
-        'Invalid configuration "validatorIdentifier"',
-        1475417095
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['label']),
-        'Invalid configuration "label"',
-        1475417096
-      );
-
-      validatorIdentifier = editorConfiguration['validatorIdentifier'];
-      getHelper().getTemplatePropertyDomElement('label', editorHtml).append(editorConfiguration['label']);
-
-      if (getUtility().isNonEmptyString(editorConfiguration['propertyPath'])) {
-        propertyPath = getFormEditorApp()
-          .buildPropertyPath(editorConfiguration['propertyPath'], collectionElementIdentifier, collectionName);
-      }
-      if (getUtility().isNonEmptyString(editorConfiguration['propertyValue'])) {
-        propertyValue = editorConfiguration['propertyValue'];
-      } else {
-        propertyValue = '';
-      }
-
-      validationErrorMessagePropertyPath = getFormEditorApp()
-        .buildPropertyPath(editorConfiguration['configurationOptions']['validationErrorMessage']['propertyPath']);
-
-      validationErrorMessageTemplate = getHelper()
-        .getTemplatePropertyDomElement('validationErrorMessage', $(editorHtml))
-        .clone();
-
-      getHelper()
-        .getTemplatePropertyDomElement('validationErrorMessage', $(editorHtml))
-        .remove();
-
-      showValidationErrorMessage = function() {
-        validationErrorMessageTemplateClone = $(validationErrorMessageTemplate).clone(true, true);
-        _getEditorWrapperDomElement(editorHtml).after(validationErrorMessageTemplateClone);
-
-        getHelper()
-          .getTemplatePropertyDomElement('validationErrorMessage-label', validationErrorMessageTemplateClone)
-          .append(editorConfiguration['configurationOptions']['validationErrorMessage']['label']);
-
-        getHelper()
-          .getTemplatePropertyDomElement('validationErrorMessage-fieldExplanationText', validationErrorMessageTemplateClone)
-          .append(editorConfiguration['configurationOptions']['validationErrorMessage']['fieldExplanationText']);
-
-        propertyData = getCurrentlySelectedFormElement().get(validationErrorMessagePropertyPath);
-        if (getUtility().isUndefinedOrNull(propertyData)) {
-          propertyData = [];
-        }
-
-        validationErrorMessage = _getFirstAvailableValidationErrorMessage(
-          editorConfiguration['configurationOptions']['validationErrorMessage']['errorCodes'],
-          propertyData
-        );
-        if (!getUtility().isUndefinedOrNull(validationErrorMessage)) {
-          getHelper()
-            .getTemplatePropertyDomElement('validationErrorMessage-propertyPath', validationErrorMessageTemplateClone)
-            .val(validationErrorMessage);
-        }
-
-        getHelper().getTemplatePropertyDomElement('validationErrorMessage-propertyPath', validationErrorMessageTemplateClone).on('keyup paste', function() {
-          propertyData = getCurrentlySelectedFormElement().get(validationErrorMessagePropertyPath);
-          if (getUtility().isUndefinedOrNull(propertyData)) {
-            propertyData = [];
-          }
-
-          getCurrentlySelectedFormElement().set(validationErrorMessagePropertyPath, _renewValidationErrorMessages(
-            editorConfiguration['configurationOptions']['validationErrorMessage']['errorCodes'],
-            propertyData,
-            $(this).val()
-          ));
-        });
-      }
-
-      if (-1 !== getFormEditorApp().getIndexFromPropertyCollectionElement(validatorIdentifier, 'validators')) {
-        $('input[type="checkbox"]', $(editorHtml)).prop('checked', true);
-        if (getUtility().isNonEmptyString(propertyPath)) {
-          getCurrentlySelectedFormElement().set(propertyPath, propertyValue);
-        }
-        showValidationErrorMessage();
-      }
-
-      $('input[type="checkbox"]', $(editorHtml)).on('change', function() {
-        getHelper().getTemplatePropertyDomElement('validationErrorMessage', $(editorHtml))
-          .off()
-          .empty()
-          .remove();
-
-        if ($(this).is(":checked")) {
-          showValidationErrorMessage();
-          getPublisherSubscriber().publish(
-            'view/inspector/collectionElement/new/selected',
-            [validatorIdentifier, 'validators']
-          );
-
-          if (getUtility().isNonEmptyString(propertyPath)) {
-            getCurrentlySelectedFormElement().set(propertyPath, propertyValue);
-          }
-        } else {
-          getPublisherSubscriber().publish(
-            'view/inspector/removeCollectionElement/perform',
-            [validatorIdentifier, 'validators']
-          );
-          if (getUtility().isNonEmptyString(propertyPath)) {
-            getCurrentlySelectedFormElement().unset(propertyPath);
-          }
-
-          propertyData = getCurrentlySelectedFormElement().get(validationErrorMessagePropertyPath);
-          if (getUtility().isUndefinedOrNull(propertyData)) {
-            propertyData = [];
-          }
-
-          getCurrentlySelectedFormElement().set(validationErrorMessagePropertyPath, _renewValidationErrorMessages(
-            editorConfiguration['configurationOptions']['validationErrorMessage']['errorCodes'],
-            propertyData,
-            ''
-          ));
-        }
-      });
-    };
-
-    /**
-     * @public
-     *
-     * @param object editorConfiguration
-     * @param object editorHtml
-     * @param string collectionElementIdentifier
-     * @param string collectionName
-     * @return void
-     * @throws 1476218671
-     * @throws 1476218672
-     * @throws 1476218673
-     * @throws 1476218674
-     */
-    function renderCheckboxEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
-      var propertyData, propertyPath;
-      assert(
-        'object' === $.type(editorConfiguration),
-        'Invalid parameter "editorConfiguration"',
-        1476218671
-      );
-      assert(
-        'object' === $.type(editorHtml),
-        'Invalid parameter "editorHtml"',
-        1476218672
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['label']),
-        'Invalid configuration "label"',
-        1476218673
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['propertyPath']),
-        'Invalid configuration "propertyPath"',
-        1476218674
-      );
-
-      getHelper()
-        .getTemplatePropertyDomElement('label', editorHtml)
-        .append(editorConfiguration['label']);
-      if (getUtility().isNonEmptyString(editorConfiguration['fieldExplanationText'])) {
-        getHelper()
-          .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
-          .text(editorConfiguration['fieldExplanationText']);
-      } else {
-        getHelper()
-          .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
-          .remove();
-      }
-
-      propertyPath = getFormEditorApp()
-        .buildPropertyPath(editorConfiguration['propertyPath'], collectionElementIdentifier, collectionName);
-      propertyData = getCurrentlySelectedFormElement().get(propertyPath);
-
-      if (
-        ('boolean' === $.type(propertyData) && propertyData)
-        || propertyData === 'true'
-        || propertyData === 1
-        || propertyData === "1"
-      ) {
-        $('input[type="checkbox"]', $(editorHtml)).prop('checked', true);
-      }
-
-      $('input[type="checkbox"]', $(editorHtml)).on('change', function() {
-        if ($(this).is(":checked")) {
-          getCurrentlySelectedFormElement().set(propertyPath, true);
-        } else {
-          getCurrentlySelectedFormElement().set(propertyPath, false);
-        }
-      });
-    };
-
-    /**
-     * @public
-     *
-     * @param object editorConfiguration
-     * @param object editorHtml
-     * @param string collectionElementIdentifier
-     * @param string collectionName
-     * @return void
-     * @throws 1475412567
-     * @throws 1475412568
-     * @throws 1475416098
-     * @throws 1475416099
-     */
-    function renderTextareaEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
-      var propertyPath, propertyData;
-      assert(
-        'object' === $.type(editorConfiguration),
-        'Invalid parameter "editorConfiguration"',
-        1475412567
-      );
-      assert(
-        'object' === $.type(editorHtml),
-        'Invalid parameter "editorHtml"',
-        1475412568
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['propertyPath']),
-        'Invalid configuration "propertyPath"',
-        1475416098
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['label']),
-        'Invalid configuration "label"',
-        1475416099
-      );
-
-      propertyPath = getFormEditorApp()
-        .buildPropertyPath(editorConfiguration['propertyPath'], collectionElementIdentifier, collectionName);
-
-      getHelper()
-        .getTemplatePropertyDomElement('label', editorHtml).append(editorConfiguration['label']);
-
-      if (getUtility().isNonEmptyString(editorConfiguration['fieldExplanationText'])) {
-        getHelper()
-          .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
-          .text(editorConfiguration['fieldExplanationText']);
-      } else {
-        getHelper()
-          .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
-          .remove();
-      }
-
-      propertyData = getCurrentlySelectedFormElement().get(propertyPath);
-      $('textarea', $(editorHtml)).val(propertyData);
-
-      $('textarea', $(editorHtml)).on('keyup paste', function() {
-        getCurrentlySelectedFormElement().set(propertyPath, $(this).val());
-      });
-    };
-
-    /**
-     * @public
-     *
-     * @param object editorConfiguration
-     * @param object editorHtml
-     * @param string collectionElementIdentifier
-     * @param string collectionName
-     * @return void
-     * @throws 1477300587
-     * @throws 1477300588
-     * @throws 1477300589
-     * @throws 1477300590
-     * @throws 1477318981
-     * @throws 1477319859
-     */
-    function renderTypo3WinBrowserEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
-      var propertyPath, propertyData;
-      assert(
-        'object' === $.type(editorConfiguration),
-        'Invalid parameter "editorConfiguration"',
-        1477300587
-      );
-      assert(
-        'object' === $.type(editorHtml),
-        'Invalid parameter "editorHtml"',
-        1477300588
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['label']),
-        'Invalid configuration "label"',
-        1477300589
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['buttonLabel']),
-        'Invalid configuration "buttonLabel"',
-        1477318981
-      );
-      assert(
-        getUtility().isNonEmptyString(editorConfiguration['propertyPath']),
-        'Invalid configuration "propertyPath"',
-        1477300590
-      );
-
-      getHelper()
-        .getTemplatePropertyDomElement('label', editorHtml)
-        .append(editorConfiguration['label']);
-      getHelper()
-        .getTemplatePropertyDomElement('buttonLabel', editorHtml)
-        .append(editorConfiguration['buttonLabel']);
-
-      if (getUtility().isNonEmptyString(editorConfiguration['fieldExplanationText'])) {
-        getHelper()
-          .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
-          .text(editorConfiguration['fieldExplanationText']);
-      } else {
-        getHelper()
-          .getTemplatePropertyDomElement('fieldExplanationText', editorHtml)
-          .remove();
-      }
-
-      $('form', $(editorHtml)).prop('name', editorConfiguration['propertyPath']);
-
-      Icons.getIcon(editorConfiguration['iconIdentifier'], Icons.sizes.small).then(function(icon) {
-        getHelper().getTemplatePropertyDomElement('image', editorHtml).append($(icon));
-      });
-
-      getHelper().getTemplatePropertyDomElement('onclick', editorHtml).on('click', function() {
-        var insertTarget, randomIdentifier;
-
-        randomIdentifier = Math.floor((Math.random() * 100000) + 1);
-        insertTarget = $(this)
-          .closest(getHelper().getDomElementDataIdentifierSelector('editorControlsWrapper'))
-          .find(getHelper().getDomElementDataAttribute('contentElementSelectorTarget', 'bracesWithKey'));
-
-        insertTarget.attr(getHelper().getDomElementDataAttribute('contentElementSelectorTarget'), randomIdentifier);
-        _openTypo3WinBrowser('db', randomIdentifier + '|||' + editorConfiguration['browsableType']);
-      });
-
-      _listenOnElementBrowser();
-
-      propertyPath = getFormEditorApp().buildPropertyPath(editorConfiguration['propertyPath'], collectionElementIdentifier, collectionName);
-      propertyData = getCurrentlySelectedFormElement().get(propertyPath);
-
-      _validateCollectionElement(propertyPath, editorHtml);
-      getHelper()
-        .getTemplatePropertyDomElement('propertyPath', editorHtml)
-        .val(propertyData);
-
-      getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).on('keyup paste', function() {
-        getCurrentlySelectedFormElement().set(propertyPath, $(this).val());
-        _validateCollectionElement(propertyPath, editorHtml);
-      });
-    };
-
-    /**
-     * @public
-     *
-     * @param object editorConfiguration
-     * @param object editorHtml
-     * @param string collectionElementIdentifier
-     * @param string collectionName
-     * @return void
-     * @throws 1475412563
-     * @throws 1475412564
-     */
-    function renderRemoveElementEditor(editorConfiguration, editorHtml, collectionElementIdentifier, collectionName) {
-      assert('object' === $.type(editorConfiguration), 'Invalid parameter "editorConfiguration"', 1475412563);
-      assert('object' === $.type(editorHtml), 'Invalid parameter "editorHtml"', 1475412564);
-
-      if (getUtility().isUndefinedOrNull(collectionElementIdentifier)) {
-
-        $('button', $(editorHtml))
-          .addClass(
-            getHelper().getDomElementClassName('buttonFormElementRemove') + ' ' +
-            getHelper().getDomElementClassName('buttonFormEditor')
-          );
-      } else {
-        $('button', $(editorHtml)).addClass(
-          getHelper().getDomElementClassName('buttonCollectionElementRemove')
-        );
-      }
-
-      $('button', $(editorHtml)).on('click', function(e) {
-        if (getUtility().isUndefinedOrNull(collectionElementIdentifier)) {
-          getViewModel().showRemoveFormElementModal();
-        } else {
-          getViewModel().showRemoveCollectionElementModal(collectionElementIdentifier, collectionName);
-        }
-      });
-    };
-
-    /**
-     * @public
-     *
-     * @param object editorConfiguration
-     * @param object editorHtml
-     * @param string propertyPath
-     * @return void
-     * @throws 1484574704
-     * @throws 1484574705
-     * @throws 1484574706
-     */
-    function renderFormElementSelectorEditorAddition(editorConfiguration, editorHtml, propertyPath) {
-      var nonCompositeNonToplevelFormElements, formElementSelectorControlsWrapper,
-        formElementSelectorSplitButtonListContainer, itemTemplate;
-
-      assert(
-        'object' === $.type(editorConfiguration),
-        'Invalid parameter "editorConfiguration"',
-        1484574704
-      );
-      assert(
-        'object' === $.type(editorHtml),
-        'Invalid parameter "editorHtml"',
-        1484574705
-      );
-      assert(
-        getUtility().isNonEmptyString(propertyPath),
-        'Invalid parameter "propertyPath"',
-        1484574706
-      );
-
-      formElementSelectorControlsWrapper = $(
-        getHelper().getDomElementDataIdentifierSelector('formElementSelectorControlsWrapper'), editorHtml
-      );
-
-      if (editorConfiguration['enableFormelementSelectionButton'] === true) {
-        if (formElementSelectorControlsWrapper.length === 0) {
-          return;
-        }
-
-        formElementSelectorSplitButtonListContainer = $(
-          getHelper().getDomElementDataIdentifierSelector('formElementSelectorSplitButtonListContainer'), editorHtml
-        );
-
-        formElementSelectorSplitButtonListContainer.off().empty();
-        nonCompositeNonToplevelFormElements = getFormEditorApp().getNonCompositeNonToplevelFormElements();
-
-        if (nonCompositeNonToplevelFormElements.length === 0) {
-          Icons.getIcon(
-            getHelper().getDomElementDataAttributeValue('iconNotAvailable'),
-            Icons.sizes.small,
-            null,
-            Icons.states.default
-          ).then(function(icon) {
-            itemTemplate = $('<li data-no-sorting>'
-              + '<a href="#"></a>'
-              + '</li>');
-
-            itemTemplate
-              .append($(icon))
-              .append(' ' + getFormElementDefinition(getRootFormElement(), 'inspectorEditorFormElementSelectorNoElements'));
-            formElementSelectorSplitButtonListContainer.append(itemTemplate);
-          });
-        } else {
-          $.each(nonCompositeNonToplevelFormElements, function(i, nonCompositeNonToplevelFormElement) {
-            Icons.getIcon(
-              getFormElementDefinition(nonCompositeNonToplevelFormElement, 'iconIdentifier'),
-              Icons.sizes.small,
-              null,
-              Icons.states.default
-            ).then(function(icon) {
-              itemTemplate = $('<li data-no-sorting>'
-                + '<a href="#" class="dropdown-item" data-formelement-identifier="' + nonCompositeNonToplevelFormElement.get('identifier') + '">'
-                + '</a>'
-                + '</li>');
-
-              $('[data-formelement-identifier="' + nonCompositeNonToplevelFormElement.get('identifier') + '"]', itemTemplate)
-                .append($(icon))
-                .append(' ' + nonCompositeNonToplevelFormElement.get('label'));
-
-              $('a', itemTemplate).on('click', function() {
-                var propertyData;
-
-                propertyData = getCurrentlySelectedFormElement().get(propertyPath) || '';
-
-                if (propertyData.length === 0) {
-                  propertyData = '{' + $(this).attr('data-formelement-identifier') + '}';
-                } else {
-                  propertyData = propertyData + ' ' + '{' + $(this).attr('data-formelement-identifier') + '}';
-                }
-
-                getCurrentlySelectedFormElement().set(propertyPath, propertyData);
-                getHelper().getTemplatePropertyDomElement('propertyPath', editorHtml).val(propertyData);
-                _validateCollectionElement(propertyPath, editorHtml);
-              });
-
-              formElementSelectorSplitButtonListContainer.append(itemTemplate);
-            });
-          });
-        }
-      } else {
-        $(getHelper().getDomElementDataIdentifierSelector('editorControlsInputGroup'), editorHtml)
-          .removeClass(getHelper().getDomElementClassName('inspectorInputGroup'));
-        formElementSelectorControlsWrapper.off().empty().remove();
-      }
-    }
-
-    /**
-     * @public
-     *
-     * @param object
-     * @return object
-     * @throws 1478967319
-     */
-    function buildTitleByFormElement(formElement) {
-      var label;
-      if (getUtility().isUndefinedOrNull(formElement)) {
-        formElement = getCurrentlySelectedFormElement();
-      }
-      assert('object' === $.type(formElement), 'Invalid parameter "formElement"', 1478967319);
-
-      if (formElement.get('type') === 'Form') {
-        label = formElement.get('type');
-      } else {
-        label = getFormElementDefinition(formElement, 'label')
-          ? getFormElementDefinition(formElement, 'label')
-          : formElement.get('identifier');
-      }
-
-      return $('<span></span>').text(label);
-    };
-
-    /**
-     * @public
-     *
-     * @param object
-     * @param object
-     * @return this
-     */
-    function bootstrap(formEditorApp, configuration) {
-      _formEditorApp = formEditorApp;
-      _configuration = $.extend(true, _defaultConfiguration, configuration || {});
-      _helperSetup();
-      return this;
-    };
-
-    /**
-     * Publish the public methods.
-     * Implements the "Revealing Module Pattern".
-     */
-    return {
-      bootstrap: bootstrap,
-      buildTitleByFormElement: buildTitleByFormElement,
-      getCollectionElementDomElement: getCollectionElementDomElement,
-      getFinishersContainerDomElement: getFinishersContainerDomElement,
-      getInspectorDomElement: getInspectorDomElement,
-      getValidatorsContainerDomElement: getValidatorsContainerDomElement,
-      renderCheckboxEditor: renderCheckboxEditor,
-      renderCollectionElementEditors: renderCollectionElementEditors,
-      renderCollectionElementHeaderEditor: renderCollectionElementHeaderEditor,
-      renderFileMaxSizeEditor: renderMaximumFileSizeEditor,
-      renderCollectionElementSelectionEditor: renderCollectionElementSelectionEditor,
-      renderEditors: renderEditors,
-      renderFormElementHeaderEditor: renderFormElementHeaderEditor,
-      renderFormElementSelectorEditorAddition: renderFormElementSelectorEditorAddition,
-      renderPropertyGridEditor: renderPropertyGridEditor,
-      renderRemoveElementEditor: renderRemoveElementEditor,
-      renderRequiredValidatorEditor: renderRequiredValidatorEditor,
-      renderCountrySelectEditor: renderCountrySelectEditor,
-      renderSingleSelectEditor: renderSingleSelectEditor,
-      renderMultiSelectEditor: renderMultiSelectEditor,
-      renderTextareaEditor: renderTextareaEditor,
-      renderTextEditor: renderTextEditor,
-      renderTypo3WinBrowserEditor: renderTypo3WinBrowserEditor
-    };
-  })($, Helper, Icons, Notification);
-}
+import $ from"jquery";import*as Helper from"@typo3/form/backend/form-editor/helper.js";import Icons from"@typo3/backend/icons.js";import Modal from"@typo3/backend/modal.js";import{MessageUtility}from"@typo3/backend/utility/message-utility.js";import Sortable from"sortablejs";const defaultConfiguration={domElementClassNames:{buttonFormElementRemove:"t3-form-remove-element-button",collectionElement:"t3-form-collection-element",finisherEditorPrefix:"t3-form-inspector-finishers-editor-",inspectorEditor:"form-editor",inspectorInputGroup:"input-group",validatorEditorPrefix:"t3-form-inspector-validators-editor-"},domElementDataAttributeNames:{contentElementSelectorTarget:"data-insert-target",finisher:"data-finisher-identifier",validator:"data-validator-identifier",randomId:"data-random-id",randomIdTarget:"data-random-id-attribute",randomIdIndex:"data-random-id-number",maximumFileSize:"data-maximumFileSize"},domElementDataAttributeValues:{collapse:"actions-view-table-expand",editorControlsInputGroup:"inspectorEditorControlsGroup",editorWrapper:"editorWrapper",editorControlsWrapper:"inspectorEditorControlsWrapper",formElementHeaderEditor:"inspectorFormElementHeaderEditor",formElementSelectorControlsWrapper:"inspectorEditorFormElementSelectorControlsWrapper",formElementSelectorSplitButtonContainer:"inspectorEditorFormElementSelectorSplitButtonContainer",formElementSelectorSplitButtonListContainer:"inspectorEditorFormElementSelectorSplitButtonListContainer",iconNotAvailable:"actions-close",inspector:"inspector","Inspector-CheckboxEditor":"Inspector-CheckboxEditor","Inspector-CollectionElementHeaderEditor":"Inspector-CollectionElementHeaderEditor","Inspector-FinishersEditor":"Inspector-FinishersEditor","Inspector-FormElementHeaderEditor":"Inspector-FormElementHeaderEditor","Inspector-PropertyGridEditor":"Inspector-PropertyGridEditor","Inspector-RemoveElementEditor":"Inspector-RemoveElementEditor","Inspector-RequiredValidatorEditor":"Inspector-RequiredValidatorEditor","Inspector-SingleSelectEditor":"Inspector-SingleSelectEditor","Inspector-MultiSelectEditor":"Inspector-MultiSelectEditor","Inspector-GridColumnViewPortConfigurationEditor":"Inspector-GridColumnViewPortConfigurationEditor","Inspector-TextareaEditor":"Inspector-TextareaEditor","Inspector-TextEditor":"Inspector-TextEditor","Inspector-Typo3WinBrowserEditor":"Inspector-Typo3WinBrowserEditor","Inspector-ValidatorsEditor":"Inspector-ValidatorsEditor","Inspector-ValidationErrorMessageEditor":"Inspector-ValidationErrorMessageEditor",inspectorFinishers:"inspectorFinishers",inspectorValidators:"inspectorValidators",propertyGridEditorHeaderRow:"headerRow",propertyGridEditorAddRow:"addRow",propertyGridEditorAddRowItem:"addRowItem",propertyGridEditorContainer:"propertyGridContainer",propertyGridEditorDeleteRow:"deleteRow",propertyGridEditorLabel:"label",propertyGridEditorRowItem:"rowItem",propertyGridEditorColumn:"column",propertyGridEditorSelectValue:"selectValue",propertyGridEditorSortRow:"sortRow",propertyGridEditorValue:"value",viewportButton:"viewportButton"},domElementIdNames:{finisherPrefix:"t3-form-inspector-finishers-",validatorPrefix:"t3-form-inspector-validators-"},isSortable:!0};let configuration=null,formEditorApp=null;function getFormEditorApp(){return formEditorApp}function getViewModel(){return getFormEditorApp().getViewModel()}function getHelper(e){return getUtility().isUndefinedOrNull(e)?Helper.setConfiguration(configuration):Helper.setConfiguration(e)}function getUtility(){return getFormEditorApp().getUtility()}function assert(e,t,r){return getFormEditorApp().assert(e,t,r)}function getRootFormElement(){return getFormEditorApp().getRootFormElement()}function getCurrentlySelectedFormElement(){return getFormEditorApp().getCurrentlySelectedFormElement()}function getPublisherSubscriber(){return getFormEditorApp().getPublisherSubscriber()}function getFormElementDefinition(e,t){return getFormEditorApp().getFormElementDefinition(e,t)}function renderEditorDispatcher(e,t,r,o){switch(e.templateName){case"Inspector-FormElementHeaderEditor":renderFormElementHeaderEditor(e,t);break;case"Inspector-CollectionElementHeaderEditor":renderCollectionElementHeaderEditor(e,t,r,o);break;case"Inspector-MaximumFileSizeEditor":renderFileMaxSizeEditor(e,t);break;case"Inspector-TextEditor":renderTextEditor(e,t,r,o);break;case"Inspector-FinishersEditor":renderCollectionElementSelectionEditor("finishers",e,t);break;case"Inspector-ValidatorsEditor":renderCollectionElementSelectionEditor("validators",e,t);break;case"Inspector-ValidationErrorMessageEditor":renderValidationErrorMessageEditor(e,t);break;case"Inspector-RemoveElementEditor":renderRemoveElementEditor(e,t,r,o);break;case"Inspector-RequiredValidatorEditor":renderRequiredValidatorEditor(e,t,r,o);break;case"Inspector-CheckboxEditor":renderCheckboxEditor(e,t,r,o);break;case"Inspector-CountrySelectEditor":renderCountrySelectEditor(e,t,r,o);break;case"Inspector-SingleSelectEditor":renderSingleSelectEditor(e,t,r,o);break;case"Inspector-MultiSelectEditor":renderMultiSelectEditor(e,t,r,o);break;case"Inspector-GridColumnViewPortConfigurationEditor":renderGridColumnViewPortConfigurationEditor(e,t);break;case"Inspector-PropertyGridEditor":renderPropertyGridEditor(e,t,r,o);break;case"Inspector-TextareaEditor":renderTextareaEditor(e,t,r,o);break;case"Inspector-Typo3WinBrowserEditor":renderTypo3WinBrowserEditor(e,t,r,o)}getPublisherSubscriber().publish("view/inspector/editor/insert/perform",[e,t,r,o])}function openTypo3WinBrowser(e,t){Modal.advanced({type:Modal.types.iframe,content:TYPO3.settings.FormEditor.typo3WinBrowserUrl+"&mode="+e+"&bparams="+t,size:Modal.sizes.large})}function listenOnElementBrowser(){window.addEventListener("message",(function(e){if(!MessageUtility.verifyOrigin(e.origin))throw"Denied message sent by "+e.origin;if("typo3:elementBrowser:elementAdded"===e.data.actionName){if(void 0===e.data.fieldName)throw"fieldName not defined in message";if(void 0===e.data.value)throw"value not defined in message";const t=e.data.value.split("_");$(getHelper().getDomElementDataAttribute("contentElementSelectorTarget","bracesWithKeyValue",[e.data.fieldName])).val(t.pop()).trigger("paste")}}))}function getCollectionElementClass(e,t){return"finishers"===e?getHelper().getDomElementClassName("finisherEditorPrefix")+t:getHelper().getDomElementClassName("validatorEditorPrefix")+t}function getCollectionElementId(e,t,r){return"finishers"===e?getHelper().getDomElementIdName("finisherPrefix",r)+t:getHelper().getDomElementIdName("validatorPrefix",r)+t}function addSortableCollectionElementsEvents(e,t){e.addClass(getHelper().getDomElementClassName("sortable")),new Sortable(e.get(0),{draggable:getHelper().getDomElementClassName("collectionElement",!0),filter:"input,textarea,select",preventOnFilter:!1,animation:200,fallbackTolerance:200,swapThreshold:.6,dragClass:"form-sortable-drag",ghostClass:"form-sortable-ghost",onEnd:function(e){let r;r="finishers"===t?getHelper().getDomElementDataAttribute("finisher"):getHelper().getDomElementDataAttribute("validator");const o=$(e.item).attr(r),n=$(e.item).prevAll(getHelper().getDomElementClassName("collectionElement",!0)).first().attr(r),i=$(e.item).nextAll(getHelper().getDomElementClassName("collectionElement",!0)).first().attr(r);getPublisherSubscriber().publish("view/inspector/collectionElements/dnd/update",[o,n,i,t])}})}function setPropertyGridData(e,t,r,o){let n;if(t){const t=[];$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorContainer")+" "+getHelper().getDomElementDataIdentifierSelector("propertyGridEditorSelectValue")+":checked",$(e)).each((function(){n=$(this).closest(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorRowItem")).find(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorValue")).val(),getUtility().canBeInterpretedAsInteger(n)&&(n=parseInt(n,10)),t.push(n)})),getCurrentlySelectedFormElement().set(o+"defaultValue",t)}else n=$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorContainer")+" "+getHelper().getDomElementDataIdentifierSelector("propertyGridEditorSelectValue")+":checked",$(e)).first().closest(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorRowItem")).find(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorValue")).val(),getUtility().canBeInterpretedAsInteger(n)&&(n=parseInt(n,10)),getCurrentlySelectedFormElement().set(o+"defaultValue",n,!0);const i=[];$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorContainer")+" "+getHelper().getDomElementDataIdentifierSelector("propertyGridEditorRowItem"),$(e)).each((function(){let e=$(this).find(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorValue")).val();const t=$(this).find(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorLabel")).val();""===e&&(e=t);i.push({_label:t,_value:e})})),getCurrentlySelectedFormElement().set(o+r,i),validateCollectionElement(o+r,e)}function getEditorWrapperDomElement(e){return $(getHelper().getDomElementDataIdentifierSelector("editorWrapper"),$(e))}function getEditorControlsWrapperDomElement(e){return $(getHelper().getDomElementDataIdentifierSelector("editorControlsWrapper"),$(e))}function validateCollectionElement(e,t){let r,o,n;n=getFormEditorApp().validateCurrentlySelectedFormElementProperty(e),n.length>0?(getHelper().getTemplatePropertyDomElement("validationErrors",t).text(n[0]),getViewModel().setElementValidationErrorClass(getHelper().getTemplatePropertyDomElement("validationErrors",t)),getViewModel().setElementValidationErrorClass(getEditorControlsWrapperDomElement(t),"hasError")):(getHelper().getTemplatePropertyDomElement("validationErrors",t).text(""),getViewModel().removeElementValidationErrorClass(getHelper().getTemplatePropertyDomElement("validationErrors",t)),getViewModel().removeElementValidationErrorClass(getEditorControlsWrapperDomElement(t),"hasError")),n=getFormEditorApp().validateFormElement(getCurrentlySelectedFormElement()),o=e.split("."),o=o[0]+"."+o[1],r=!1;for(let e=0,t=n.length;e<t;++e)if(0===n[e].propertyPath.indexOf(o,0)&&n[e].validationResults&&n[e].validationResults.length>0){r=!0;break}r?getViewModel().setElementValidationErrorClass(getEditorControlsWrapperDomElement(t).closest(getHelper().getDomElementClassName("collectionElement",!0))):getViewModel().removeElementValidationErrorClass(getEditorControlsWrapperDomElement(t).closest(getHelper().getDomElementClassName("collectionElement",!0)))}function getFirstAvailableValidationErrorMessage(e,t){assert("array"===$.type(e),'Invalid configuration "errorCodes"',1489932939),assert("array"===$.type(t),'Invalid configuration "propertyData"',1489932940);for(let r=0,o=e.length;r<o;++r)for(let o=0,n=t.length;o<n;++o)if(parseInt(e[r],10)===parseInt(t[o].code,10)&&getUtility().isNonEmptyString(t[o].message))return t[o].message;return null}function renewValidationErrorMessages(e,t,r){if(assert("array"===$.type(t),'Invalid configuration "propertyData"',1489932942),!getUtility().isUndefinedOrNull(e)&&"array"===$.type(e)){const o=[];for(let n=0,i=e.length;n<i;++n){let i=!1;for(let o=0,l=t.length;o<l;++o)parseInt(e[n],10)===parseInt(t[o].code,10)&&(i=!0,getUtility().isNonEmptyString(r)?t[o].message=r:(t.splice(o,1),--l));i||getUtility().isNonEmptyString(r)&&o.push({code:e[n],message:r})}t=t.concat(o)}return t}function setRandomIds(e){assert("object"===$.type(e),'Invalid input "html"',1523904699),$(getHelper().getDomElementClassName("inspectorEditor",!0)).each((function(){const e=$(this),t={};$(getHelper().getDomElementDataAttribute("randomId","bracesWithKey"),e).each((function(){const e=$(this),r=e.attr(getHelper().getDomElementDataAttribute("randomIdTarget")),o=e.attr(getHelper().getDomElementDataAttribute("randomIdIndex"));e.is("["+r+"]")||(o in t||(t[o]="fe"+Math.floor(42*Math.random())+Date.now()),e.attr(r,t[o]))}))}))}export function getInspectorDomElement(){return $(getHelper().getDomElementDataIdentifierSelector("inspector"))}export function getFinishersContainerDomElement(){return $(getHelper().getDomElementDataIdentifierSelector("inspectorFinishers"),getInspectorDomElement())}export function getValidatorsContainerDomElement(){return $(getHelper().getDomElementDataIdentifierSelector("inspectorValidators"),getInspectorDomElement())}export function getCollectionElementDomElement(e,t){return"finishers"===e?$(getHelper().getDomElementDataAttribute("finisher","bracesWithKeyValue",[t]),getFinishersContainerDomElement()):$(getHelper().getDomElementDataAttribute("validator","bracesWithKeyValue",[t]),getValidatorsContainerDomElement())}export function renderEditors(e,t){getUtility().isUndefinedOrNull(e)&&(e=getCurrentlySelectedFormElement()),getInspectorDomElement().off().empty();const r=getFormElementDefinition(e,void 0);if("array"===$.type(r.editors)){for(let e=0,t=r.editors.length;e<t;++e){const t=getHelper().getTemplate(r.editors[e].templateName).clone();if(!t.length)continue;const o=$(t.html());$(o).first().addClass(getHelper().getDomElementClassName("inspectorEditor")),getInspectorDomElement().append($(o)),setRandomIds(o),renderEditorDispatcher(r.editors[e],o)}"function"===$.type(t)&&t()}}export function renderCollectionElementEditors(e,t){let r,o;assert(getUtility().isNonEmptyString(e),'Invalid parameter "collectionName"',1478354853),assert(getUtility().isNonEmptyString(t),'Invalid parameter "collectionElementIdentifier"',1478354854);const n=getFormEditorApp().getPropertyCollectionElementConfiguration(t,e);if("array"!==$.type(n.editors))return;const i=$("<div></div>").addClass(getHelper().getDomElementClassName("collectionElement"));"finishers"===e?(o=getFinishersContainerDomElement(),i.attr(getHelper().getDomElementDataAttribute("finisher"),t)):(o=getValidatorsContainerDomElement(),i.attr(getHelper().getDomElementDataAttribute("validator"),t)),o.append(i);const l=n.editors.length;l>0&&"header"===n.editors[0].identifier&&(r=$('<div role="tabpanel"></div>').addClass("panel-collapse collapse").prop("id",getCollectionElementId(e,t)));for(let o=0;o<l;++o){const i=getHelper().getTemplate(n.editors[o].templateName).clone();if(!i.length)continue;const a=$(i.html());$(a).first().addClass(getCollectionElementClass(e,n.editors[o].identifier)).addClass(getHelper().getDomElementClassName("inspectorEditor")),0===o&&r?getCollectionElementDomElement(e,t).append(a).append(r):o===l-1&&r&&"removeButton"===n.editors[o].identifier?getCollectionElementDomElement(e,t).append(a):o>0&&r?r.append(a):getCollectionElementDomElement(e,t).append(a),setRandomIds(a),renderEditorDispatcher(n.editors[o],a,t,e)}(2===l&&"header"===n.editors[0].identifier&&"removeButton"===n.editors[1].identifier||1===l&&"header"===n.editors[0].identifier)&&$(getHelper().getDomElementDataIdentifierSelector("collapse"),i).remove(),configuration.isSortable&&addSortableCollectionElementsEvents(o,e)}export function renderCollectionElementSelectionEditor(e,t,r){let o,n,i;assert(getUtility().isNonEmptyString(e),'Invalid configuration "collectionName"',1478362968),assert("object"===$.type(t),'Invalid parameter "editorConfiguration"',1475423098),assert("object"===$.type(r),'Invalid parameter "editorHtml"',1475423099),assert(getUtility().isNonEmptyString(t.label),'Invalid configuration "label"',1475423100),assert("array"===$.type(t.selectOptions),'Invalid configuration "selectOptions"',1475423101),"finishers"===e?(n=getFinishersContainerDomElement(),o=getRootFormElement().get(e)):(n=getValidatorsContainerDomElement(),o=getCurrentlySelectedFormElement().get(e)),n.off().empty(),getHelper().getTemplatePropertyDomElement("label",r).text(t.label);const l=getHelper().getTemplatePropertyDomElement("selectOptions",r);if(!getUtility().isUndefinedOrNull(o))for(let t=0,r=o.length;t<r;++t)getPublisherSubscriber().publish("view/inspector/collectionElement/existing/selected",[o[t].identifier,e]);i=!0;for(let e=0,r=t.selectOptions.length;e<r;++e){let r=!0;if(!getUtility().isUndefinedOrNull(o))for(let n=0,i=o.length;n<i;++n)if(o[n].identifier===t.selectOptions[e].value){r=!1;break}r&&(l.append(new Option(t.selectOptions[e].label,t.selectOptions[e].value)),""!==t.selectOptions[e].value&&(i=!1))}i&&l.off().empty().remove(),l.on("change",(function(){if(""!==$(this).val()){const t=$(this).val();$('option[value="'+t+'"]',$(this)).remove(),getFormEditorApp().getPublisherSubscriber().publish("view/inspector/collectionElement/new/selected",[t,e])}}))}export function renderFormElementHeaderEditor(e,t){assert("object"===$.type(e),'Invalid parameter "editorConfiguration"',1475421525),assert("object"===$.type(t),'Invalid parameter "editorHtml"',1475421526),Icons.getIcon(getFormElementDefinition(getCurrentlySelectedFormElement(),"iconIdentifier"),Icons.sizes.small,null,Icons.states.default).then((function(e){getHelper().getTemplatePropertyDomElement("header-label",t).append($(e).addClass(getHelper().getDomElementClassName("icon"))).append(buildTitleByFormElement())}))}export function renderCollectionElementHeaderEditor(e,t,r,o){assert("object"===$.type(e),'Invalid parameter "editorConfiguration"',1475421258),assert(getUtility().isNonEmptyString(e.label),'Invalid configuration "label"',1475421257),assert("object"===$.type(t),'Invalid parameter "editorHtml"',1475421259);const n=function(e){e&&getHelper().getTemplatePropertyDomElement("header-label",t).prepend($(e));const n=getFormEditorApp().getPropertyCollectionElementConfiguration(r,o).editors;2===n.length&&"header"===n[0].identifier&&"removeButton"===n[1].identifier||1===n.length&&"header"===n[0].identifier||Icons.getIcon(getHelper().getDomElementDataAttributeValue("collapse"),Icons.sizes.small,null,Icons.states.default,Icons.markupIdentifiers.inline).then((function(e){const n=$("<a></a>").attr("href",getCollectionElementId(o,r,!0)).attr("data-bs-toggle","collapse").attr("aria-expanded","false").attr("aria-controls",getCollectionElementId(o,r)).addClass("collapsed").append($(e));getHelper().getTemplatePropertyDomElement("header-label",t).prepend(n)}))},i=getFormEditorApp().getFormEditorDefinition(o,r);"iconIdentifier"in i?Icons.getIcon(i.iconIdentifier,Icons.sizes.small,null,Icons.states.default).then((function(e){n(e)})):n(),e.label&&getHelper().getTemplatePropertyDomElement("label",t).append(e.label)}export function renderFileMaxSizeEditor(e,t){if(assert("object"===$.type(e),'Invalid parameter "editorConfiguration"',1475421258),assert(getUtility().isNonEmptyString(e.label),'Invalid configuration "label"',1475421257),assert("object"===$.type(t),'Invalid parameter "editorHtml"',1475421259),e.label){const r=getHelper().getTemplatePropertyDomElement("label",t),o=r.attr(getHelper().getDomElementDataAttribute("maximumFileSize"));r.append(e.label.replace("{0}",o))}}export function renderTextEditor(e,t,r,o){assert("object"===$.type(e),'Invalid parameter "editorConfiguration"',1475421053),assert("object"===$.type(t),'Invalid parameter "editorHtml"',1475421054),assert(getUtility().isNonEmptyString(e.label),'Invalid configuration "label"',1475421055),assert(getUtility().isNonEmptyString(e.propertyPath),'Invalid configuration "propertyPath"',1475421056),getHelper().getTemplatePropertyDomElement("label",t).append(e.label),getUtility().isNonEmptyString(e.fieldExplanationText)?getHelper().getTemplatePropertyDomElement("fieldExplanationText",t).text(e.fieldExplanationText):getHelper().getTemplatePropertyDomElement("fieldExplanationText",t).remove(),getUtility().isNonEmptyString(e.placeholder)&&getHelper().getTemplatePropertyDomElement("propertyPath",t).attr("placeholder",e.placeholder);const n=getFormEditorApp().buildPropertyPath(e.propertyPath,r,o),i=getCurrentlySelectedFormElement().get(n);if(validateCollectionElement(n,t),getHelper().getTemplatePropertyDomElement("propertyPath",t).val(i),!getUtility().isUndefinedOrNull(e.additionalElementPropertyPaths)&&"array"===$.type(e.additionalElementPropertyPaths))for(let t=0,r=e.additionalElementPropertyPaths.length;t<r;++t)getCurrentlySelectedFormElement().set(e.additionalElementPropertyPaths[t],i);renderFormElementSelectorEditorAddition(e,t,n),getHelper().getTemplatePropertyDomElement("propertyPath",t).on("keyup paste",(function(){if(e.doNotSetIfPropertyValueIsEmpty&&!getUtility().isNonEmptyString($(this).val())?getCurrentlySelectedFormElement().unset(n):getCurrentlySelectedFormElement().set(n,$(this).val()),validateCollectionElement(n,t),!getUtility().isUndefinedOrNull(e.additionalElementPropertyPaths)&&"array"===$.type(e.additionalElementPropertyPaths))for(let t=0,r=e.additionalElementPropertyPaths.length;t<r;++t)e.doNotSetIfPropertyValueIsEmpty&&!getUtility().isNonEmptyString($(this).val())?getCurrentlySelectedFormElement().unset(e.additionalElementPropertyPaths[t]):getCurrentlySelectedFormElement().set(e.additionalElementPropertyPaths[t],$(this).val())}))}export function renderValidationErrorMessageEditor(e,t){assert("object"===$.type(e),'Invalid parameter "editorConfiguration"',1489874121),assert("object"===$.type(t),'Invalid parameter "editorHtml"',1489874122),assert(getUtility().isNonEmptyString(e.label),'Invalid configuration "label"',1489874123),assert(getUtility().isNonEmptyString(e.propertyPath),'Invalid configuration "propertyPath"',1489874124),getHelper().getTemplatePropertyDomElement("label",t).append(e.label),getUtility().isNonEmptyString(e.fieldExplanationText)?getHelper().getTemplatePropertyDomElement("fieldExplanationText",t).text(e.fieldExplanationText):getHelper().getTemplatePropertyDomElement("fieldExplanationText",t).remove();const r=getFormEditorApp().buildPropertyPath(e.propertyPath);let o=getCurrentlySelectedFormElement().get(r);if(!getUtility().isUndefinedOrNull(o)&&"array"===$.type(o)){const r=getFirstAvailableValidationErrorMessage(e.errorCodes,o);getUtility().isUndefinedOrNull(r)||getHelper().getTemplatePropertyDomElement("propertyPath",t).val(r)}getHelper().getTemplatePropertyDomElement("propertyPath",t).on("keyup paste",(function(){o=getCurrentlySelectedFormElement().get(r),getUtility().isUndefinedOrNull(o)&&(o=[]),getCurrentlySelectedFormElement().set(r,renewValidationErrorMessages(e.errorCodes,o,$(this).val()))}))}export function renderCountrySelectEditor(e,t,r,o){assert("object"===$.type(e),'Invalid parameter "editorConfiguration"',1674826430),assert("object"===$.type(t),'Invalid parameter "editorHtml"',1674826431),assert(getUtility().isNonEmptyString(e.label),'Invalid configuration "label"',1674826432);const n=getFormEditorApp().buildPropertyPath(e.propertyPath,r,o);getHelper().getTemplatePropertyDomElement("label",t).append(e.label);const i=getHelper().getTemplatePropertyDomElement("selectOptions",t),l=getCurrentlySelectedFormElement().get(n)||{},a=$("option",i);i.empty();for(let e=0,t=a.length;e<t;++e){let t=!1;for(const r of Object.keys(l))if(a[e].value===l[r]){t=!0;break}const r=new Option(a[e].text,e.toString(),!1,t);$(r).data({value:a[e].value}),i.append(r)}i.on("change",(function(){const e=[];$("option:selected",$(this)).each((function(){e.push($(this).data("value"))})),getCurrentlySelectedFormElement().set(n,e)}))}export function renderSingleSelectEditor(e,t,r,o){assert("object"===$.type(e),'Invalid parameter "editorConfiguration"',1475421048),assert("object"===$.type(t),'Invalid parameter "editorHtml"',1475421049),assert(getUtility().isNonEmptyString(e.label),'Invalid configuration "label"',1475421050),assert(getUtility().isNonEmptyString(e.propertyPath),'Invalid configuration "propertyPath"',1475421051),assert("array"===$.type(e.selectOptions),'Invalid configuration "selectOptions"',1475421052);const n=getFormEditorApp().buildPropertyPath(e.propertyPath,r,o);getHelper().getTemplatePropertyDomElement("label",t).append(e.label);const i=getHelper().getTemplatePropertyDomElement("selectOptions",t),l=getCurrentlySelectedFormElement().get(n);for(let t=0,r=e.selectOptions.length;t<r;++t){let r;r=e.selectOptions[t].value===l?new Option(e.selectOptions[t].label,t.toString(),!1,!0):new Option(e.selectOptions[t].label,t.toString()),$(r).data({value:e.selectOptions[t].value}),i.append(r)}i.on("change",(function(){getCurrentlySelectedFormElement().set(n,$("option:selected",$(this)).data("value"))}))}export function renderMultiSelectEditor(e,t,r,o){assert("object"===$.type(e),'Invalid parameter "editorConfiguration"',1485712399),assert("object"===$.type(t),'Invalid parameter "editorHtml"',1485712400),assert(getUtility().isNonEmptyString(e.label),'Invalid configuration "label"',1485712401),assert(getUtility().isNonEmptyString(e.propertyPath),'Invalid configuration "propertyPath"',1485712402),assert("array"===$.type(e.selectOptions),'Invalid configuration "selectOptions"',1485712403);const n=getFormEditorApp().buildPropertyPath(e.propertyPath,r,o);getHelper().getTemplatePropertyDomElement("label",t).append(e.label);const i=getHelper().getTemplatePropertyDomElement("selectOptions",t),l=getCurrentlySelectedFormElement().get(n)||{};for(let t=0,r=e.selectOptions.length;t<r;++t){let r=null;for(const o of Object.keys(l))if(e.selectOptions[t].value===l[o]){r=new Option(e.selectOptions[t].label,t.toString(),!1,!0);break}r||(r=new Option(e.selectOptions[t].label,t.toString())),$(r).data({value:e.selectOptions[t].value}),i.append(r)}i.on("change",(function(){const e=[];$("option:selected",$(this)).each((function(){e.push($(this).data("value"))})),getCurrentlySelectedFormElement().set(n,e)}))}export function renderGridColumnViewPortConfigurationEditor(e,t){if(assert("object"===$.type(e),'Invalid parameter "editorConfiguration"',1489528242),assert("object"===$.type(t),'Invalid parameter "editorHtml"',1489528243),assert(getUtility().isNonEmptyString(e.label),'Invalid configuration "label"',1489528244),assert("array"===$.type(e.configurationOptions.viewPorts),'Invalid configurationOptions "viewPorts"',1489528245),assert(!getUtility().isUndefinedOrNull(e.configurationOptions.numbersOfColumnsToUse.label),'Invalid configurationOptions "numbersOfColumnsToUse"',1489528246),assert(!getUtility().isUndefinedOrNull(e.configurationOptions.numbersOfColumnsToUse.propertyPath),'Invalid configuration "selectOptions"',1489528247),!getFormElementDefinition(getCurrentlySelectedFormElement().get("__parentRenderable"),"_isGridRowFormElement"))return void t.remove();getHelper().getTemplatePropertyDomElement("label",t).append(e.label);const r=$(getHelper().getDomElementDataIdentifierSelector("viewportButton"),$(t)).clone();$(getHelper().getDomElementDataIdentifierSelector("viewportButton"),$(t)).remove();const o=getHelper().getTemplatePropertyDomElement("numbersOfColumnsToUse",$(t)).clone();getHelper().getTemplatePropertyDomElement("numbersOfColumnsToUse",$(t)).remove();const n=getEditorControlsWrapperDomElement(t),i=function(r){getHelper().getTemplatePropertyDomElement("numbersOfColumnsToUse",$(t)).off().empty().remove();const n=$(o).clone(!0,!0);getEditorWrapperDomElement(t).after(n),$("input",n).focus(),getHelper().getTemplatePropertyDomElement("numbersOfColumnsToUse-label",n).append(e.configurationOptions.numbersOfColumnsToUse.label.replace("{@viewPortLabel}",r.data("viewPortLabel"))),getHelper().getTemplatePropertyDomElement("numbersOfColumnsToUse-fieldExplanationText",n).append(e.configurationOptions.numbersOfColumnsToUse.fieldExplanationText);const i=e.configurationOptions.numbersOfColumnsToUse.propertyPath.replace("{@viewPortIdentifier}",r.data("viewPortIdentifier"));getHelper().getTemplatePropertyDomElement("numbersOfColumnsToUse-propertyPath",n).val(getCurrentlySelectedFormElement().get(i)),getHelper().getTemplatePropertyDomElement("numbersOfColumnsToUse-propertyPath",n).on("keyup paste change",(function(){const e=$(this);$.isNumeric(e.val())||e.val(""),getCurrentlySelectedFormElement().set(i,e.val())}))};for(let l=0,a=e.configurationOptions.viewPorts.length;l<a;++l){const p=e.configurationOptions.viewPorts[l].viewPortIdentifier,s=e.configurationOptions.viewPorts[l].label,d=$(r).clone(!0,!0);if(d.text(p),d.data("viewPortIdentifier",p),d.data("viewPortLabel",s),d.attr("title",s),n.append(d),l===a-1){const e=$(o).clone(!0,!0);getEditorWrapperDomElement(t).after(e),i(d),d.addClass(getHelper().getDomElementClassName("active"))}$("button",n).on("click",(function(){const e=$(this);$("button",n).removeClass(getHelper().getDomElementClassName("active")),e.addClass(getHelper().getDomElementClassName("active")),i(e)}))}}export function renderPropertyGridEditor(e,t,r,o){assert("object"===$.type(e),'Invalid parameter "editorConfiguration"',1475419226),assert("object"===$.type(t),'Invalid parameter "editorHtml"',1475419227),assert("boolean"===$.type(e.enableAddRow),'Invalid configuration "enableAddRow"',1475419228),assert("boolean"===$.type(e.enableDeleteRow),'Invalid configuration "enableDeleteRow"',1475419230),assert("boolean"===$.type(e.isSortable),'Invalid configuration "isSortable"',1475419229),assert(getUtility().isNonEmptyString(e.propertyPath),'Invalid configuration "propertyPath"',1475419231),assert(getUtility().isNonEmptyString(e.label),'Invalid configuration "label"',1475419232),getHelper().getTemplatePropertyDomElement("label",t).append(e.label),getUtility().isNonEmptyString(e.fieldExplanationText)?getHelper().getTemplatePropertyDomElement("fieldExplanationText",t).text(e.fieldExplanationText):getHelper().getTemplatePropertyDomElement("fieldExplanationText",t).remove();let n,i=getFormEditorApp().buildPropertyPath(void 0,r,o,void 0,!0);getUtility().isNonEmptyString(i)&&(i+="."),n=!!getUtility().isUndefinedOrNull(e.useLabelAsFallbackValue)||e.useLabelAsFallbackValue;let l=[{name:"label",title:"Label"},{name:"value",title:"Value"},{name:"selected",title:"Selected"}];getUtility().isNonEmptyArray(e.gridColumns)&&(l=e.gridColumns);const a=l.map((function(e){return e.name})),p=l.map((function(e){return e.title||null}));let s;$([getHelper().getDomElementDataIdentifierSelector("propertyGridEditorHeaderRow"),getHelper().getDomElementDataIdentifierSelector("propertyGridEditorRowItem"),getHelper().getDomElementDataIdentifierSelector("propertyGridEditorAddRowItem")].join(","),$(t)).each((function(e,t){const r=$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorColumn"),t),o=r.last().nextAll(),n={};r.detach().each((function(e,t){const r=$(t),o=r.data("column");a.includes(o)&&(n[o]=r)})),a.forEach((function(e,r){const o=n[e];o.is("th")&&o.append(p[r]),o.appendTo(t)})),o.appendTo(t)})),s=!getUtility().isUndefinedOrNull(e.multiSelection)&&!!e.multiSelection;const d=$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorRowItem"),$(t)).clone();if($(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorRowItem"),$(t)).remove(),e.enableDeleteRow?$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorDeleteRow"),$(d)).on("click",(function(){$(this).closest(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorRowItem")).off().empty().remove(),setPropertyGridData($(t),s,e.propertyPath,i)})):$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorDeleteRow"),$(d)).parent().off().empty(),e.isSortable?$(t).get(0).querySelectorAll(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorContainer")+" tbody").forEach((function(r){new Sortable(r,{group:getHelper().getDomElementDataAttributeValue("propertyGridEditorContainer"),handle:getHelper().getDomElementDataIdentifierSelector("propertyGridEditorSortRow"),draggable:getHelper().getDomElementDataIdentifierSelector("propertyGridEditorRowItem"),pull:"clone",swapThreshold:.6,dragClass:"form-sortable-drag",ghostClass:"form-sortable-ghost",onUpdate:function(){setPropertyGridData($(t),s,e.propertyPath,i)}})})):$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorSortRow"),$(d)).parent().off().empty(),$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorSelectValue"),$(d)).on("change",(function(){s||$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorSelectValue")+":checked",$(t)).not($(this)).prop("checked",!1),setPropertyGridData($(t),s,e.propertyPath,i)})),$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorLabel")+","+getHelper().getDomElementDataIdentifierSelector("propertyGridEditorValue"),$(d)).on("keyup paste",(function(){setPropertyGridData($(t),s,e.propertyPath,i)})),n&&$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorLabel"),$(d)).on("focusout",(function(){""===$(this).closest(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorRowItem")).find(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorValue")).val()&&$(this).closest(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorRowItem")).find(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorValue")).val($(this).val())})),e.enableAddRow){const r=$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorAddRowItem"),$(t)).clone();$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorAddRowItem"),$(t)).remove(),$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorAddRow"),$(r)).on("click",(function(){$(this).closest(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorAddRowItem")).before($(d).clone(!0,!0)),setPropertyGridData($(t),s,e.propertyPath,i)})),$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorContainer"),$(t)).prepend($(r).clone(!0,!0))}else $(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorAddRowItem"),$(t)).remove();let m={};s?getUtility().isUndefinedOrNull(getCurrentlySelectedFormElement().get(i+"defaultValue"))||(m=getCurrentlySelectedFormElement().get(i+"defaultValue")):getUtility().isUndefinedOrNull(getCurrentlySelectedFormElement().get(i+"defaultValue"))||(m={0:getCurrentlySelectedFormElement().get(i+"defaultValue")});const g=getCurrentlySelectedFormElement().get(i+e.propertyPath)||{},c=function(r,o){let n=!1;const i=$(d).clone(!0,!0);for(const e of Object.keys(m))if(m[e]===o){n=!0;break}$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorLabel"),$(i)).val(r),$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorValue"),$(i)).val(o),n&&$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorSelectValue"),$(i)).prop("checked",!0),e.enableAddRow?$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorAddRowItem"),$(t)).before($(i)):$(getHelper().getDomElementDataIdentifierSelector("propertyGridEditorContainer"),$(t)).prepend($(i))};if("object"===$.type(g))for(const e of Object.keys(g))c(g[e],e);else if("array"===$.type(g))for(const e in g)g.hasOwnProperty(e)&&(getUtility().isUndefinedOrNull(g[e]._label)?c(g[e],e):c(g[e]._label,g[e]._value));validateCollectionElement(i+e.propertyPath,t)}export function renderRequiredValidatorEditor(e,t,r,o){assert("object"===$.type(e),'Invalid parameter "editorConfiguration"',1475417093),assert("object"===$.type(t),'Invalid parameter "editorHtml"',1475417094),assert(getUtility().isNonEmptyString(e.validatorIdentifier),'Invalid configuration "validatorIdentifier"',1475417095),assert(getUtility().isNonEmptyString(e.label),'Invalid configuration "label"',1475417096);const n=e.validatorIdentifier;let i,l,a;getHelper().getTemplatePropertyDomElement("label",t).append(e.label),getUtility().isNonEmptyString(e.propertyPath)&&(l=getFormEditorApp().buildPropertyPath(e.propertyPath,r,o)),i=getUtility().isNonEmptyString(e.propertyValue)?e.propertyValue:"";const p=getFormEditorApp().buildPropertyPath(e.configurationOptions.validationErrorMessage.propertyPath),s=getHelper().getTemplatePropertyDomElement("validationErrorMessage",$(t)).clone();getHelper().getTemplatePropertyDomElement("validationErrorMessage",$(t)).remove();const d=function(){const r=$(s).clone(!0,!0);getEditorWrapperDomElement(t).after(r),getHelper().getTemplatePropertyDomElement("validationErrorMessage-label",r).append(e.configurationOptions.validationErrorMessage.label),getHelper().getTemplatePropertyDomElement("validationErrorMessage-fieldExplanationText",r).append(e.configurationOptions.validationErrorMessage.fieldExplanationText),a=getCurrentlySelectedFormElement().get(p),getUtility().isUndefinedOrNull(a)&&(a=[]);const o=getFirstAvailableValidationErrorMessage(e.configurationOptions.validationErrorMessage.errorCodes,a);getUtility().isUndefinedOrNull(o)||getHelper().getTemplatePropertyDomElement("validationErrorMessage-propertyPath",r).val(o),getHelper().getTemplatePropertyDomElement("validationErrorMessage-propertyPath",r).on("keyup paste",(function(){let t=getCurrentlySelectedFormElement().get(p);getUtility().isUndefinedOrNull(t)&&(t=[]),getCurrentlySelectedFormElement().set(p,renewValidationErrorMessages(e.configurationOptions.validationErrorMessage.errorCodes,t,$(this).val()))}))};-1!==getFormEditorApp().getIndexFromPropertyCollectionElement(n,"validators")&&($('input[type="checkbox"]',$(t)).prop("checked",!0),getUtility().isNonEmptyString(l)&&getCurrentlySelectedFormElement().set(l,i),d()),$('input[type="checkbox"]',$(t)).on("change",(function(){getHelper().getTemplatePropertyDomElement("validationErrorMessage",$(t)).off().empty().remove(),$(this).is(":checked")?(d(),getPublisherSubscriber().publish("view/inspector/collectionElement/new/selected",[n,"validators"]),getUtility().isNonEmptyString(l)&&getCurrentlySelectedFormElement().set(l,i)):(getPublisherSubscriber().publish("view/inspector/removeCollectionElement/perform",[n,"validators"]),getUtility().isNonEmptyString(l)&&getCurrentlySelectedFormElement().unset(l),a=getCurrentlySelectedFormElement().get(p),getUtility().isUndefinedOrNull(a)&&(a=[]),getCurrentlySelectedFormElement().set(p,renewValidationErrorMessages(e.configurationOptions.validationErrorMessage.errorCodes,a,"")))}))}export function renderCheckboxEditor(e,t,r,o){assert("object"===$.type(e),'Invalid parameter "editorConfiguration"',1476218671),assert("object"===$.type(t),'Invalid parameter "editorHtml"',1476218672),assert(getUtility().isNonEmptyString(e.label),'Invalid configuration "label"',1476218673),assert(getUtility().isNonEmptyString(e.propertyPath),'Invalid configuration "propertyPath"',1476218674),getHelper().getTemplatePropertyDomElement("label",t).append(e.label),getUtility().isNonEmptyString(e.fieldExplanationText)?getHelper().getTemplatePropertyDomElement("fieldExplanationText",t).text(e.fieldExplanationText):getHelper().getTemplatePropertyDomElement("fieldExplanationText",t).remove();const n=getFormEditorApp().buildPropertyPath(e.propertyPath,r,o),i=getCurrentlySelectedFormElement().get(n);("boolean"===$.type(i)&&i||"true"===i||1===i||"1"===i)&&$('input[type="checkbox"]',$(t)).prop("checked",!0),$('input[type="checkbox"]',$(t)).on("change",(function(){$(this).is(":checked")?getCurrentlySelectedFormElement().set(n,!0):getCurrentlySelectedFormElement().set(n,!1)}))}export function renderTextareaEditor(e,t,r,o){assert("object"===$.type(e),'Invalid parameter "editorConfiguration"',1475412567),assert("object"===$.type(t),'Invalid parameter "editorHtml"',1475412568),assert(getUtility().isNonEmptyString(e.propertyPath),'Invalid configuration "propertyPath"',1475416098),assert(getUtility().isNonEmptyString(e.label),'Invalid configuration "label"',1475416099);const n=getFormEditorApp().buildPropertyPath(e.propertyPath,r,o);getHelper().getTemplatePropertyDomElement("label",t).append(e.label),getUtility().isNonEmptyString(e.fieldExplanationText)?getHelper().getTemplatePropertyDomElement("fieldExplanationText",t).text(e.fieldExplanationText):getHelper().getTemplatePropertyDomElement("fieldExplanationText",t).remove();const i=getCurrentlySelectedFormElement().get(n);$("textarea",$(t)).val(i),$("textarea",$(t)).on("keyup paste",(function(){getCurrentlySelectedFormElement().set(n,$(this).val())}))}export function renderTypo3WinBrowserEditor(e,t,r,o){assert("object"===$.type(e),'Invalid parameter "editorConfiguration"',1477300587),assert("object"===$.type(t),'Invalid parameter "editorHtml"',1477300588),assert(getUtility().isNonEmptyString(e.label),'Invalid configuration "label"',1477300589),assert(getUtility().isNonEmptyString(e.buttonLabel),'Invalid configuration "buttonLabel"',1477318981),assert(getUtility().isNonEmptyString(e.propertyPath),'Invalid configuration "propertyPath"',1477300590),getHelper().getTemplatePropertyDomElement("label",t).append(e.label),getHelper().getTemplatePropertyDomElement("buttonLabel",t).append(e.buttonLabel),getUtility().isNonEmptyString(e.fieldExplanationText)?getHelper().getTemplatePropertyDomElement("fieldExplanationText",t).text(e.fieldExplanationText):getHelper().getTemplatePropertyDomElement("fieldExplanationText",t).remove(),$("form",$(t)).prop("name",e.propertyPath),Icons.getIcon(e.iconIdentifier,Icons.sizes.small).then((function(e){getHelper().getTemplatePropertyDomElement("image",t).append($(e))})),getHelper().getTemplatePropertyDomElement("onclick",t).on("click",(function(){const t=Math.floor(1e5*Math.random()+1);$(this).closest(getHelper().getDomElementDataIdentifierSelector("editorControlsWrapper")).find(getHelper().getDomElementDataAttribute("contentElementSelectorTarget","bracesWithKey")).attr(getHelper().getDomElementDataAttribute("contentElementSelectorTarget"),t),openTypo3WinBrowser("db",t+"|||"+e.browsableType)})),listenOnElementBrowser();const n=getFormEditorApp().buildPropertyPath(e.propertyPath,r,o),i=getCurrentlySelectedFormElement().get(n);validateCollectionElement(n,t),getHelper().getTemplatePropertyDomElement("propertyPath",t).val(i),getHelper().getTemplatePropertyDomElement("propertyPath",t).on("keyup paste",(function(){getCurrentlySelectedFormElement().set(n,$(this).val()),validateCollectionElement(n,t)}))}export function renderRemoveElementEditor(e,t,r,o){assert("object"===$.type(e),'Invalid parameter "editorConfiguration"',1475412563),assert("object"===$.type(t),'Invalid parameter "editorHtml"',1475412564),getUtility().isUndefinedOrNull(r)?$("button",$(t)).addClass(getHelper().getDomElementClassName("buttonFormElementRemove")+" "+getHelper().getDomElementClassName("buttonFormEditor")):$("button",$(t)).addClass(getHelper().getDomElementClassName("buttonCollectionElementRemove")),$("button",$(t)).on("click",(function(){getUtility().isUndefinedOrNull(r)?getViewModel().showRemoveFormElementModal():getViewModel().showRemoveCollectionElementModal(r,o)}))}export function renderFormElementSelectorEditorAddition(e,t,r){assert("object"===$.type(e),'Invalid parameter "editorConfiguration"',1484574704),assert("object"===$.type(t),'Invalid parameter "editorHtml"',1484574705),assert(getUtility().isNonEmptyString(r),'Invalid parameter "propertyPath"',1484574706);const o=$(getHelper().getDomElementDataIdentifierSelector("formElementSelectorControlsWrapper"),t);if(!0===e.enableFormelementSelectionButton){if(0===o.length)return;const e=$(getHelper().getDomElementDataIdentifierSelector("formElementSelectorSplitButtonListContainer"),t);e.off().empty();const n=getFormEditorApp().getNonCompositeNonToplevelFormElements();0===n.length?Icons.getIcon(getHelper().getDomElementDataAttributeValue("iconNotAvailable"),Icons.sizes.small,null,Icons.states.default).then((function(t){const r=$('<li data-no-sorting><a href="#"></a></li>');r.append($(t)).append(" "+getFormElementDefinition(getRootFormElement(),"inspectorEditorFormElementSelectorNoElements")),e.append(r)})):$.each(n,(function(o,n){Icons.getIcon(getFormElementDefinition(n,"iconIdentifier"),Icons.sizes.small,null,Icons.states.default).then((function(o){const i=$('<li data-no-sorting><a href="#" class="dropdown-item" data-formelement-identifier="'+n.get("identifier")+'"></a></li>');$('[data-formelement-identifier="'+n.get("identifier")+'"]',i).append($(o)).append(" "+n.get("label")),$("a",i).on("click",(function(){let e;e=getCurrentlySelectedFormElement().get(r)||"",e=0===e.length?"{"+$(this).attr("data-formelement-identifier")+"}":e+" {"+$(this).attr("data-formelement-identifier")+"}",getCurrentlySelectedFormElement().set(r,e),getHelper().getTemplatePropertyDomElement("propertyPath",t).val(e),validateCollectionElement(r,t)})),e.append(i)}))}))}else $(getHelper().getDomElementDataIdentifierSelector("editorControlsInputGroup"),t).removeClass(getHelper().getDomElementClassName("inspectorInputGroup")),o.off().empty().remove()}export function buildTitleByFormElement(e){let t;getUtility().isUndefinedOrNull(e)&&(e=getCurrentlySelectedFormElement()),assert("object"===$.type(e),'Invalid parameter "formElement"',1478967319),t="Form"===e.get("type")?e.get("type"):getFormElementDefinition(e,"label")?getFormElementDefinition(e,"label"):e.get("identifier");const r=document.createElement("span");return r.textContent=t,r}export function bootstrap(e,t){return formEditorApp=e,configuration=$.extend(!0,defaultConfiguration,t||{}),Helper.bootstrap(formEditorApp),this}
\ No newline at end of file