diff --git a/Build/Sources/TypeScript/form/backend/form-editor/stage-component.ts b/Build/Sources/TypeScript/form/backend/form-editor/stage-component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..0bc83bcc3e7a09410ed2c1b9bdc43c5fe13e781b
--- /dev/null
+++ b/Build/Sources/TypeScript/form/backend/form-editor/stage-component.ts
@@ -0,0 +1,901 @@
+/*
+ * 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/stage-component
+ */
+import $ from 'jquery';
+import * as Helper from '@typo3/form/backend/form-editor/helper';
+import Icons from '@typo3/backend/icons';
+import Sortable from 'sortablejs';
+
+import type {
+  FormEditor,
+  ViewModel,
+} from '@typo3/form/backend/form-editor';
+import type {
+  Utility,
+  FormElement,
+  FormElementDefinition,
+  PublisherSubscriber,
+} from '@typo3/form/backend/form-editor/core';
+import type {
+  Configuration as HelperConfiguration,
+} from '@typo3/form/backend/form-editor/helper';
+import type {
+  InsertElementsModalConfiguration
+} from '@typo3/form/backend/form-editor/modals-component';
+
+interface Configuration extends Partial<HelperConfiguration> {
+  isSortable: boolean,
+}
+
+const defaultConfiguration: Configuration = {
+  domElementClassNames: {
+    formElementIsComposit: 't3-form-element-composit',
+    formElementIsTopLevel: 't3-form-element-toplevel',
+    noNesting: 'mjs-nestedSortable-no-nesting',
+    selected: 'selected',
+    sortable: 'sortable',
+    previewViewPreviewElement: 't3-form-element-preview'
+  },
+  domElementDataAttributeNames: {
+    abstractType: 'data-element-abstract-type',
+    noSorting: 'data-no-sorting'
+  },
+  domElementDataAttributeValues: {
+    abstractViewToolbar: 'elementToolbar',
+    abstractViewToolbarNewElement: 'stageElementToolbarNewElement',
+    abstractViewToolbarNewElementSplitButton: 'stageElementToolbarNewElementSplitButton',
+    abstractViewToolbarNewElementSplitButtonAfter: 'stageElementToolbarNewElementSplitButtonAfter',
+    abstractViewToolbarNewElementSplitButtonInside: 'stageElementToolbarNewElementSplitButtonInside',
+    abstractViewToolbarRemoveElement: 'stageElementToolbarRemoveElement',
+    buttonHeaderRedo: 'redoButton',
+    buttonHeaderUndo: 'undoButton',
+    buttonPaginationPrevious: 'buttonPaginationPrevious',
+    buttonPaginationNext: 'buttonPaginationNext',
+    'FormElement-_ElementToolbar': 'FormElement-_ElementToolbar',
+    'FormElement-_UnknownElement': 'FormElement-_UnknownElement',
+    'FormElement-AdvancedPassword': 'FormElement-AdvancedPassword',
+    'FormElement-Checkbox': 'FormElement-Checkbox',
+    'FormElement-ContentElement': 'FormElement-ContentElement',
+    'FormElement-CountrySelect': 'FormElement-CountrySelect',
+    'FormElement-DatePicker': 'FormElement-DatePicker',
+    'FormElement-Fieldset': 'FormElement-Fieldset',
+    'FormElement-GridRow': 'FormElement-GridRow',
+    'FormElement-FileUpload': 'FormElement-FileUpload',
+    'FormElement-Hidden': 'FormElement-Hidden',
+    'FormElement-ImageUpload': 'FormElement-ImageUpload',
+    'FormElement-MultiCheckbox': 'FormElement-MultiCheckbox',
+    'FormElement-MultiSelect': 'FormElement-MultiSelect',
+    'FormElement-Page': 'FormElement-Page',
+    'FormElement-Password': 'FormElement-Password',
+    'FormElement-RadioButton': 'FormElement-RadioButton',
+    'FormElement-SingleSelect': 'FormElement-SingleSelect',
+    'FormElement-StaticText': 'FormElement-StaticText',
+    'FormElement-SummaryPage': 'FormElement-SummaryPage',
+    'FormElement-Text': 'FormElement-Text',
+    'FormElement-Textarea': 'FormElement-Textarea',
+    'FormElement-Email': 'FormElement-Email',
+    'FormElement-Url': 'FormElement-Url',
+    'FormElement-Telephone': 'FormElement-Telephone',
+    'FormElement-Number': 'FormElement-Number',
+    'FormElement-Date': 'FormElement-Date',
+    formElementIcon: 'elementIcon',
+    iconValidator: 'form-validator',
+    multiValueContainer: 'multiValueContainer',
+    paginationTitle: 'paginationTitle',
+    stageHeadline: 'formDefinitionLabel',
+    stagePanel: 'stagePanel',
+    validatorsContainer: 'validatorsContainer',
+    validatorIcon: 'validatorIcon'
+  },
+  isSortable: true
+};
+
+let configuration: Configuration = null;
+
+let formEditorApp: FormEditor = null;
+
+let stageDomElement: JQuery = null;
+
+function getFormEditorApp(): FormEditor {
+  return formEditorApp;
+}
+
+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 getViewModel(): ViewModel {
+  return getFormEditorApp().getViewModel();
+}
+
+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,
+  formElementDefinitionKey?: T
+): T extends keyof FormElementDefinition ? FormElementDefinition[T] : FormElementDefinition {
+  return getFormEditorApp().getFormElementDefinition(formElement, formElementDefinitionKey);
+}
+
+function setTemplateTextContent(domElement: HTMLElement, content: string): void {
+  if (getUtility().isNonEmptyString(content)) {
+    $(domElement).text(content);
+  }
+}
+
+/**
+ * @publish view/stage/abstract/render/template/perform
+ */
+function renderTemplateDispatcher(formElement: FormElement, template: JQuery): void {
+  switch (formElement.get('type')) {
+    case 'Checkbox':
+      renderCheckboxTemplate(formElement, template);
+      break;
+    case 'FileUpload':
+    case 'ImageUpload':
+      renderFileUploadTemplates(formElement, template);
+      break;
+    case 'CountrySelect':
+    case 'SingleSelect':
+    case 'RadioButton':
+    case 'MultiSelect':
+    case 'MultiCheckbox':
+      renderSelectTemplates(formElement, template);
+      break;
+    case 'Textarea':
+    case 'AdvancedPassword':
+    case 'Password':
+    case 'Text':
+    case 'Email':
+    case 'Url':
+    case 'Telephone':
+    case 'Number':
+    case 'DatePicker':
+    case 'Date':
+      renderSimpleTemplateWithValidators(formElement, template);
+      break;
+    case 'Fieldset':
+    case 'GridRow':
+    case 'SummaryPage':
+    case 'Page':
+    case 'StaticText':
+    case 'Hidden':
+    case 'ContentElement':
+      renderSimpleTemplate(formElement, template);
+      break;
+    default:
+      break;
+  }
+  getPublisherSubscriber().publish('view/stage/abstract/render/template/perform', [formElement, template]);
+}
+
+/**
+ * @throws 1478987818
+ */
+function renderNestedSortableListItem(formElement: FormElement): JQuery {
+  let childList, template;
+
+  const listItem = $('<li></li>');
+  if (!getFormElementDefinition(formElement, '_isCompositeFormElement')) {
+    listItem.addClass(getHelper().getDomElementClassName('noNesting'));
+  }
+
+  if (getFormElementDefinition(formElement, '_isTopLevelFormElement')) {
+    listItem.addClass(getHelper().getDomElementClassName('formElementIsTopLevel'));
+  }
+  if (getFormElementDefinition(formElement, '_isCompositeFormElement')) {
+    listItem.addClass(getHelper().getDomElementClassName('formElementIsComposit'));
+  }
+
+  try {
+    template = getHelper().getTemplate('FormElement-' + formElement.get('type')).clone();
+  } catch (error) {
+    template = getHelper().getTemplate('FormElement-_UnknownElement').clone();
+    assert(
+      template.length > 0,
+      'No template found for element "' + formElement.get('__identifierPath') + '"',
+      1478987818
+    );
+  }
+
+  template = $('<div></div>')
+    .attr(getHelper().getDomElementDataAttribute('elementIdentifier'), formElement.get('__identifierPath'))
+    .append($(template.html()));
+
+  if (getFormElementDefinition(formElement, '_isCompositeFormElement')) {
+    template.attr(getHelper().getDomElementDataAttribute('abstractType'), 'isCompositeFormElement');
+  }
+  if (getFormElementDefinition(formElement, '_isTopLevelFormElement')) {
+    template.attr(getHelper().getDomElementDataAttribute('abstractType'), 'isTopLevelFormElement');
+  }
+  listItem.append(template);
+
+  renderTemplateDispatcher(formElement, template);
+
+  const childFormElements = formElement.get('renderables');
+  childList = null;
+  if ('array' === $.type(childFormElements)) {
+    childList = $('<ol></ol>');
+    childList.addClass(getHelper().getDomElementClassName('sortable'));
+    for (let i = 0, len = childFormElements.length; i < len; ++i) {
+      childList.append(renderNestedSortableListItem(childFormElements[i]));
+    }
+  }
+
+  if (childList) {
+    listItem.append(childList);
+  }
+  return listItem;
+}
+
+/**
+ * @publish view/stage/abstract/dnd/start
+ * @publish view/stage/abstract/dnd/stop
+ * @publish view/stage/abstract/dnd/change
+ * @publish view/stage/abstract/dnd/update
+ */
+function addSortableEvents(): void {
+  const sortableLists = stageDomElement.get(0).querySelectorAll('ol.' + getHelper().getDomElementClassName('sortable'));
+  const draggableSelector = 'li:not(' + getHelper().getDomElementDataAttribute('noSorting', 'bracesWithKey') + ')';
+  const handleSelector = 'div' + getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKey');
+
+  sortableLists.forEach(function (sortableList: HTMLElement) {
+    sortableList.querySelectorAll(handleSelector).forEach(function (draggable) {
+      draggable.classList.add('form-sortable-handle');
+    });
+
+    new Sortable(sortableList, {
+      group: 'stage-nodes',
+      handle: handleSelector,
+      draggable: draggableSelector,
+      animation: 200,
+      swapThreshold: 0.6,
+      dragClass: 'form-sortable-drag',
+      ghostClass: 'form-sortable-ghost',
+      onStart: function (e) {
+        getPublisherSubscriber().publish('view/stage/abstract/dnd/start', [$(e.item), $(e.item)]);
+      },
+      onChange: function (e) {
+        let enclosingCompositeFormElement;
+        const parentFormElementIdentifierPath = getAbstractViewParentFormElementIdentifierPathWithinDomElement($(e.item));
+
+        if (parentFormElementIdentifierPath) {
+          enclosingCompositeFormElement = getFormEditorApp()
+            .findEnclosingCompositeFormElementWhichIsNotOnTopLevel(parentFormElementIdentifierPath);
+        }
+        getPublisherSubscriber().publish('view/stage/abstract/dnd/change', [
+          $(e.item),
+          parentFormElementIdentifierPath, enclosingCompositeFormElement
+        ]);
+      },
+      onEnd: function (e) {
+        const movedFormElementIdentifierPath = getAbstractViewFormElementIdentifierPathWithinDomElement($(e.item));
+        const previousFormElementIdentifierPath = getAbstractViewSiblingFormElementIdentifierPathWithinDomElement($(e.item), 'prev');
+        const nextFormElementIdentifierPath = getAbstractViewSiblingFormElementIdentifierPathWithinDomElement($(e.item), 'next');
+
+        getPublisherSubscriber().publish('view/stage/abstract/dnd/update', [
+          $(e.item),
+          movedFormElementIdentifierPath,
+          previousFormElementIdentifierPath,
+          nextFormElementIdentifierPath
+        ]);
+        getPublisherSubscriber().publish('view/stage/abstract/dnd/stop', [
+          getAbstractViewFormElementIdentifierPathWithinDomElement($(e.item))
+        ]);
+      },
+    });
+  });
+}
+
+export function getStageDomElement(): JQuery {
+  return stageDomElement;
+}
+
+/**
+ * @throws 1479037151
+ */
+export function buildTitleByFormElement(formElement?: FormElement): HTMLElement {
+  if (getUtility().isUndefinedOrNull(formElement)) {
+    formElement = getRootFormElement();
+  }
+  assert('object' === $.type(formElement), 'Invalid parameter "formElement"', 1479037151);
+
+  const span = document.createElement('span');
+  span.textContent = formElement.get('label') ? formElement.get('label') : formElement.get('identifier');
+  return span;
+}
+
+export function setStageHeadline(title: string): void {
+  if (getUtility().isUndefinedOrNull(title)) {
+    title = buildTitleByFormElement().textContent;
+  }
+
+  $(getHelper().getDomElementDataIdentifierSelector('stageHeadline')).text(title);
+}
+
+export function getStagePanelDomElement(): JQuery {
+  return $(getHelper().getDomElementDataIdentifierSelector('stagePanel'));
+}
+
+export function renderPagination(): void {
+  const pageCount = getRootFormElement().get('renderables').length;
+
+  getViewModel().enableButton($(getHelper().getDomElementDataIdentifierSelector('buttonPaginationPrevious')));
+  getViewModel().enableButton($(getHelper().getDomElementDataIdentifierSelector('buttonPaginationNext')));
+
+  if (getFormEditorApp().getCurrentlySelectedPageIndex() === 0) {
+    getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector('buttonPaginationPrevious')));
+  }
+
+  if (pageCount === 1 || getFormEditorApp().getCurrentlySelectedPageIndex() === (pageCount - 1)) {
+    getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector('buttonPaginationNext')));
+  }
+
+  const currentPage = getFormEditorApp().getCurrentlySelectedPageIndex() + 1;
+  $(getHelper().getDomElementDataIdentifierSelector('paginationTitle')).text(
+    getFormElementDefinition(getRootFormElement(), 'paginationTitle')
+      .replace('{0}', currentPage.toString())
+      .replace('{1}', pageCount)
+  );
+}
+
+export function renderUndoRedo(): void {
+  getViewModel().enableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderUndo')));
+  getViewModel().enableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderRedo')));
+
+  if (getFormEditorApp().getCurrentApplicationStatePosition() + 1 >= getFormEditorApp().getCurrentApplicationStates()) {
+    getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderUndo')));
+  }
+  if (getFormEditorApp().getCurrentApplicationStatePosition() === 0) {
+    getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderRedo')));
+  }
+}
+
+export function getAllFormElementDomElements(): JQuery {
+  return $(getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKey'),
+    stageDomElement
+  );
+}
+
+/* *************************************************************
+ * Abstract stage
+ * ************************************************************/
+
+/**
+ * @throws 1478721208
+ */
+export function renderFormDefinitionPageAsSortableList(pageIndex: number): JQuery {
+  assert(
+    'number' === $.type(pageIndex),
+    'Invalid parameter "pageIndex"',
+    1478721208
+  );
+
+  return $('<ol></ol>')
+    .append(renderNestedSortableListItem(getRootFormElement().get('renderables')[pageIndex]));
+}
+
+export function getAbstractViewParentFormElementWithinDomElement(element: HTMLElement | JQuery): JQuery {
+  return $(element)
+    .parent()
+    .closest('li')
+    .find(getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKey'))
+    .first();
+}
+
+export function getAbstractViewParentFormElementIdentifierPathWithinDomElement(element: HTMLElement | JQuery): string {
+  return getAbstractViewParentFormElementWithinDomElement(element)
+    .attr(getHelper().getDomElementDataAttribute('elementIdentifier'));
+}
+
+export function getAbstractViewFormElementWithinDomElement(element: HTMLElement | JQuery): JQuery {
+  return $(element)
+    .find(getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKey'))
+    .first();
+}
+
+export function getAbstractViewFormElementIdentifierPathWithinDomElement(element: HTMLElement | JQuery): string {
+  return getAbstractViewFormElementWithinDomElement($(element))
+    .attr(getHelper().getDomElementDataAttribute('elementIdentifier'));
+}
+
+export function getAbstractViewSiblingFormElementIdentifierPathWithinDomElement(element: HTMLElement | JQuery, position: string): string {
+  if (getUtility().isUndefinedOrNull(position)) {
+    position = 'prev';
+  }
+  const formElementIdentifierPath = getAbstractViewFormElementIdentifierPathWithinDomElement(element);
+  element = (position === 'prev') ? $(element).prev('li') : $(element).next('li');
+  return element.find(getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKey'))
+    .not(getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKeyValue', [formElementIdentifierPath]))
+    .first()
+    .attr(getHelper().getDomElementDataAttribute('elementIdentifier'));
+}
+
+export function getAbstractViewFormElementDomElement(formElement?: FormElement | string): JQuery {
+  let formElementIdentifierPath;
+
+  if (typeof formElement === 'string') {
+    formElementIdentifierPath = formElement;
+  } else {
+    if (getUtility().isUndefinedOrNull(formElement)) {
+      formElementIdentifierPath = getCurrentlySelectedFormElement().get('__identifierPath');
+    } else {
+      formElementIdentifierPath = formElement.get('__identifierPath');
+    }
+  }
+  return $(getHelper()
+    .getDomElementDataAttribute('elementIdentifier', 'bracesWithKeyValue', [formElementIdentifierPath]), stageDomElement);
+}
+
+export function removeAllStageToolbars(): void {
+  $(getHelper().getDomElementDataIdentifierSelector('abstractViewToolbar'), stageDomElement).off().empty().remove();
+}
+
+/**
+ * @publish view/insertElements/perform/after
+ * @publish view/insertElements/perform/inside
+ * @throws 1479035778
+ */
+export function createAbstractViewFormElementToolbar(formElement: FormElement): JQuery {
+  let template: JQuery;
+  assert('object' === $.type(formElement), 'Invalid parameter "formElement"', 1479035778);
+
+  const formElementTypeDefinition = getFormElementDefinition(formElement, undefined);
+  if (formElementTypeDefinition._isTopLevelFormElement) {
+    return $();
+  }
+
+  template = getHelper().getTemplate('FormElement-_ElementToolbar').clone();
+  if (!template.length) {
+    return $();
+  }
+
+  template = $($(template.html()));
+
+  getHelper().getTemplatePropertyDomElement('_type', template).text(getFormElementDefinition(formElement, 'label'));
+  getHelper().getTemplatePropertyDomElement('_identifier', template).text(formElement.get('identifier'));
+
+  if (formElementTypeDefinition._isCompositeFormElement) {
+    getViewModel().hideComponent($(getHelper().getDomElementDataIdentifierSelector('abstractViewToolbarNewElement'), template));
+
+    $(getHelper().getDomElementDataIdentifierSelector('abstractViewToolbarNewElementSplitButtonAfter'), template).on('click', function() {
+      getPublisherSubscriber().publish('view/stage/abstract/elementToolbar/button/newElement/clicked', [
+        'view/insertElements/perform/after',
+        {
+          disableElementTypes: [],
+          onlyEnableElementTypes: []
+        }
+      ]
+      );
+    });
+
+    $(getHelper().getDomElementDataIdentifierSelector('abstractViewToolbarNewElementSplitButtonInside'), template).on('click', function() {
+      getPublisherSubscriber().publish('view/stage/abstract/elementToolbar/button/newElement/clicked', [
+        'view/insertElements/perform/inside',
+        {
+          disableElementTypes: [],
+          onlyEnableElementTypes: []
+        }
+      ]
+      );
+    });
+  } else {
+    getViewModel().hideComponent($(getHelper().getDomElementDataIdentifierSelector('abstractViewToolbarNewElementSplitButton'), template));
+
+    $(getHelper().getDomElementDataIdentifierSelector('abstractViewToolbarNewElement'), template).on('click', function() {
+      getPublisherSubscriber().publish(
+        'view/stage/abstract/elementToolbar/button/newElement/clicked', [
+          'view/insertElements/perform/after',
+          {
+            disableElementTypes: []
+          }
+        ]
+      );
+    });
+  }
+
+  $(getHelper().getDomElementDataIdentifierSelector('abstractViewToolbarRemoveElement'), template).on('click', function() {
+    getViewModel().showRemoveFormElementModal();
+  });
+
+  return template;
+}
+
+export function createAndAddAbstractViewFormElementToolbar(
+  selectedFormElementDomElement: JQuery,
+  formElement: FormElement,
+  useFadeEffect: boolean
+): void {
+  if (getUtility().isUndefinedOrNull(formElement)) {
+    formElement = getCurrentlySelectedFormElement();
+  }
+
+  if (useFadeEffect) {
+    createAbstractViewFormElementToolbar(formElement).fadeOut(0, function(this: HTMLElement) {
+      selectedFormElementDomElement.prepend($(this));
+      $(getHelper().getDomElementDataIdentifierSelector('abstractViewToolbar'), selectedFormElementDomElement).fadeIn('fast');
+    });
+  } else {
+    selectedFormElementDomElement.prepend(createAbstractViewFormElementToolbar(formElement));
+  }
+}
+
+/**
+ * @publish view/stage/dnd/stop
+ * @publish view/stage/element/clicked
+ * @throws 1478169511
+ */
+export function renderAbstractStageArea(pageIndex: number, callback: () => void) {
+  if (getUtility().isUndefinedOrNull(pageIndex)) {
+    pageIndex = getFormEditorApp().getCurrentlySelectedPageIndex();
+  }
+  stageDomElement.off().empty().append(renderFormDefinitionPageAsSortableList(pageIndex));
+
+  stageDomElement.on('click', function(e) {
+    const formElementIdentifierPath = $(e.target)
+      .closest(getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKey'))
+      .attr(getHelper().getDomElementDataAttribute('elementIdentifier'));
+    if (
+      getUtility().isUndefinedOrNull(formElementIdentifierPath)
+      || !getUtility().isNonEmptyString(formElementIdentifierPath)
+    ) {
+      return;
+    }
+
+    getPublisherSubscriber().publish('view/stage/element/clicked', [formElementIdentifierPath]);
+  });
+
+  if (configuration.isSortable) {
+    addSortableEvents();
+  }
+
+  if ('function' === $.type(callback)) {
+    callback();
+  }
+}
+
+
+/* *************************************************************
+ * Preview stage
+ * ************************************************************/
+
+/**
+ * @throws 1475424409
+ */
+export function renderPreviewStageArea(html: string): void {
+  assert(getUtility().isNonEmptyString(html), 'Invalid parameter "html"', 1475424409);
+
+  stageDomElement.off().empty().html(html);
+
+  $(':input', stageDomElement).prop('disabled', 'disabled').on('click dblclick select focus keydown keypress keyup mousedown mouseup', function(e) {
+    return e.preventDefault();
+  });
+
+  $('form', stageDomElement).submit(function(e) {
+    return e.preventDefault();
+  });
+
+  getAllFormElementDomElements().each(function(this: HTMLElement) {
+    const formElement = getFormEditorApp()
+      .getFormElementByIdentifierPath($(this).data('elementIdentifierPath'));
+
+    if (
+      !getFormElementDefinition(formElement, '_isTopLevelFormElement')
+    ) {
+      $(this).attr('title', 'identifier: ' + formElement.get('identifier') + ' (type: ' + formElement.get('type') + ')');
+    }
+
+    if (getFormElementDefinition(formElement, '_isTopLevelFormElement')) {
+      $(this).addClass(getHelper().getDomElementClassName('formElementIsTopLevel'));
+    }
+    if (getFormElementDefinition(formElement, '_isCompositeFormElement')) {
+      $(this).addClass(getHelper().getDomElementClassName('formElementIsComposit'));
+    }
+  });
+
+}
+
+/* *************************************************************
+ * Template rendering
+ * ************************************************************/
+
+export function eachTemplateProperty(
+  formElement: FormElement,
+  template: JQuery,
+  callback?: (propertyPath: string, propertyValue: unknown, element: HTMLElement) => void
+) {
+  $(getHelper().getDomElementDataAttribute('templateProperty', 'bracesWithKey'), template).each(function(i, element) {
+    const propertyPath = $(element).attr(getHelper().getDomElementDataAttribute('templateProperty'));
+    const propertyValue = formElement.get(propertyPath);
+
+    if ('function' === $.type(callback)) {
+      callback(propertyPath, propertyValue, element as HTMLElement);
+    }
+  });
+}
+
+export function renderCheckboxTemplate(formElement: FormElement, template: JQuery) {
+  renderSimpleTemplateWithValidators(formElement, template);
+
+  eachTemplateProperty(formElement, template, function(propertyPath, propertyValue, domElement) {
+    if (
+      ('boolean' === $.type(propertyValue) && propertyValue)
+      || propertyValue === 'true'
+      || propertyValue === 1
+      || propertyValue === '1'
+    ) {
+      $(domElement).addClass(getHelper().getDomElementClassName('noNesting'));
+    }
+  });
+}
+
+/**
+ * @throws 1479035696
+ */
+export function renderSimpleTemplate(formElement: FormElement, template: JQuery): void {
+  assert('object' === $.type(formElement), 'Invalid parameter "formElement"', 1479035696);
+
+  eachTemplateProperty(formElement, template, (propertyPath, propertyValue: string, domElement) => {
+    setTemplateTextContent(domElement, propertyValue);
+  });
+
+  Icons.getIcon(
+    getFormElementDefinition(formElement, 'iconIdentifier'),
+    Icons.sizes.small,
+    null,
+    Icons.states.default,
+    Icons.markupIdentifiers.inline
+  ).then(function(icon) {
+    $(getHelper().getDomElementDataIdentifierSelector('formElementIcon'), template)
+      .append($(icon).addClass(getHelper().getDomElementClassName('icon')));
+  });
+
+  getHelper()
+    .getTemplatePropertyDomElement('_type', template)
+    .append(document.createTextNode(getFormElementDefinition(formElement, 'label')));
+  getHelper()
+    .getTemplatePropertyDomElement('_identifier', template)
+    .append(document.createTextNode(formElement.get('identifier')));
+}
+
+/**
+ * @throws 1479035674
+ */
+export function renderSimpleTemplateWithValidators(formElement: FormElement, template: JQuery): void {
+  assert('object' === $.type(formElement), 'Invalid parameter "formElement"', 1479035674);
+
+  renderSimpleTemplate(formElement, template);
+
+  const validatorsTemplateContent = $(
+    getHelper().getDomElementDataIdentifierSelector('validatorsContainer'),
+    $(template)
+  ).clone();
+
+  $(getHelper().getDomElementDataIdentifierSelector('validatorsContainer'), $(template)).empty();
+  const validators = formElement.get('validators');
+
+  if ('array' === $.type(validators)) {
+    let validatorsCountWithoutRequired = 0;
+    if (validators.length > 0) {
+      for (let i = 0, len = validators.length; i < len; ++i) {
+        if ('NotEmpty' === validators[i].identifier) {
+          getHelper()
+            .getTemplatePropertyDomElement('_required', template)
+            .text('*');
+          continue;
+        }
+        validatorsCountWithoutRequired++;
+
+        const collectionElementConfiguration = getFormEditorApp()
+          .getFormEditorDefinition('validators', validators[i].identifier);
+        const rowTemplate = $($(validatorsTemplateContent).clone());
+
+        getHelper()
+          .getTemplatePropertyDomElement('_label', rowTemplate)
+          .append(document.createTextNode(collectionElementConfiguration.label));
+        $(getHelper().getDomElementDataIdentifierSelector('validatorsContainer'), $(template))
+          .append(rowTemplate.html());
+      }
+
+      if (validatorsCountWithoutRequired > 0) {
+        Icons.getIcon(
+          getHelper().getDomElementDataAttributeValue('iconValidator'),
+          Icons.sizes.small,
+          null,
+          Icons.states.default,
+          Icons.markupIdentifiers.inline
+        ).then(function(icon) {
+          $(getHelper().getDomElementDataIdentifierSelector('validatorIcon'), $(template))
+            .append($(icon).addClass(getHelper().getDomElementClassName('icon')));
+        });
+      }
+    }
+  }
+}
+
+export function renderSelectTemplates(formElement: FormElement, template: JQuery): void {
+  const multiValueTemplateContent = $(
+    getHelper().getDomElementDataIdentifierSelector('multiValueContainer'),
+    $(template)
+  ).clone();
+  $(getHelper().getDomElementDataIdentifierSelector('multiValueContainer'), $(template)).empty();
+
+  renderSimpleTemplateWithValidators(formElement, template);
+
+  const propertyPath = $(getHelper().getDomElementDataIdentifierSelector('multiValueContainer'), $(template))
+    .attr(getHelper().getDomElementDataAttribute('templateProperty'));
+
+  const propertyValue = formElement.get(propertyPath);
+
+  const appendMultiValue = (label: string, value: string, defaultValue: Record<string, string>) => {
+    let isPreselected = false;
+    const rowTemplate = $($(multiValueTemplateContent).clone());
+
+    for (const defaultValueKey of Object.keys(defaultValue)) {
+      if (defaultValue[defaultValueKey] === value) {
+        isPreselected = true;
+        break;
+      }
+    }
+
+    getHelper().getTemplatePropertyDomElement('_label', rowTemplate).append(document.createTextNode(label));
+
+    if (isPreselected) {
+      getHelper().getTemplatePropertyDomElement('_label', rowTemplate).addClass(
+        getHelper().getDomElementClassName('selected')
+      );
+    }
+
+    $(getHelper().getDomElementDataIdentifierSelector('multiValueContainer'), $(template))
+      .append(rowTemplate.html());
+  };
+
+  let defaultValue = formElement.get('defaultValue');
+
+  if (getFormEditorApp().getUtility().isUndefinedOrNull(defaultValue)) {
+    defaultValue = {};
+  } else if ('string' === $.type(defaultValue)) {
+    defaultValue = { 0: defaultValue };
+  }
+
+  if ('object' === $.type(propertyValue)) {
+    for (const propertyValueKey of Object.keys(propertyValue)) {
+      appendMultiValue(propertyValue[propertyValueKey], propertyValueKey, defaultValue);
+    }
+  } else if ('array' === $.type(propertyValue)) {
+    for (const propertyValueKey of Object.keys(propertyValue)) {
+      if (getUtility().isUndefinedOrNull(propertyValue[propertyValueKey]._label)) {
+        appendMultiValue(propertyValue[propertyValueKey], propertyValueKey, defaultValue);
+      } else {
+        appendMultiValue(propertyValue[propertyValueKey]._label, propertyValue[propertyValueKey]._value, defaultValue);
+      }
+    }
+  }
+}
+
+export function renderFileUploadTemplates(formElement: FormElement, template: JQuery): void {
+  const multiValueTemplateContent = $(
+    getHelper().getDomElementDataIdentifierSelector('multiValueContainer'),
+    $(template)
+  ).clone();
+  $(getHelper().getDomElementDataIdentifierSelector('multiValueContainer'), $(template)).empty();
+
+  renderSimpleTemplateWithValidators(formElement, template);
+
+  const propertyPath = $(getHelper().getDomElementDataIdentifierSelector('multiValueContainer'), $(template))
+    .attr(getHelper().getDomElementDataAttribute('templateProperty'));
+  const propertyValue = formElement.get(propertyPath);
+
+  const appendMultiValue = function(value: string) {
+    const rowTemplate = $($(multiValueTemplateContent).clone());
+
+    getHelper().getTemplatePropertyDomElement('_value', rowTemplate).append(value);
+    $(getHelper().getDomElementDataIdentifierSelector('multiValueContainer'), $(template))
+      .append(rowTemplate.html());
+  };
+
+  if ('object' === $.type(propertyValue)) {
+    for (const propertyValueKey of Object.keys(propertyValue)) {
+      appendMultiValue(propertyValue[propertyValueKey]);
+    }
+  } else if ('array' === $.type(propertyValue)) {
+    for (let i = 0, len = propertyValue.length; i < len; ++i) {
+      appendMultiValue(propertyValue[i]);
+    }
+  }
+}
+
+/**
+ * @throws 1478992119
+ */
+export function bootstrap(
+  this: typeof import('./stage-component'),
+  _formEditorApp: FormEditor,
+  appendToDomElement: JQuery,
+  customConfiguration?: Configuration
+): typeof import('./stage-component') {
+  formEditorApp = _formEditorApp;
+  assert('object' === $.type(appendToDomElement), 'Invalid parameter "appendToDomElement"', 1478992119);
+  stageDomElement = $(appendToDomElement);
+  configuration = $.extend(true, defaultConfiguration, customConfiguration || {});
+  Helper.bootstrap(formEditorApp);
+  return this;
+}
+
+declare global {
+  interface PublisherSubscriberTopicArgumentsMap {
+    'view/stage/abstract/render/template/perform': readonly [
+      formElement: FormElement,
+      template: JQuery
+    ];
+    'view/stage/abstract/dnd/start': readonly [
+      draggedFormElementDomElement: HTMLElement | JQuery,
+      draggedFormPlaceholderDomElement: HTMLElement | JQuery,
+    ];
+    'view/stage/abstract/dnd/change': readonly [
+      placeholderDomElement: JQuery,
+      parentFormElementIdentifierPath: string,
+      enclosingCompositeFormElement: FormElement
+    ];
+    'view/stage/abstract/dnd/update': readonly [
+      movedDomElement: JQuery,
+      movedFormElementIdentifierPath: string,
+      previousFormElementIdentifierPath: string,
+      nextFormElementIdentifierPath: string,
+    ];
+    'view/stage/abstract/dnd/stop': readonly [
+      draggedFormElementIdentifierPath: string
+    ];
+    'view/stage/element/clicked': readonly [
+      formElementIdentifierPath: string
+    ];
+    'view/stage/abstract/elementToolbar/button/newElement/clicked': readonly [
+      targetEvent: 'view/insertElements/perform/after' | 'view/insertElements/perform/inside',
+      modalConfiguration: InsertElementsModalConfiguration
+    ];
+    // triggered by 'view/stage/abstract/elementToolbar/button/newElement/clicked' via
+    // ModalComponent.insertElementsModalSetup()
+    'view/insertElements/perform/after': readonly [
+      formElementType: string
+    ];
+    // triggered by 'view/stage/abstract/elementToolbar/button/newElement/clicked' via
+    // ModalComponent.insertElementsModalSetup()
+    'view/insertElements/perform/inside': readonly [
+      formElementType: string
+    ];
+  }
+}
diff --git a/typo3/sysext/form/Resources/Public/JavaScript/backend/form-editor/stage-component.js b/typo3/sysext/form/Resources/Public/JavaScript/backend/form-editor/stage-component.js
index b5eefdeea23d15775d2d7cdbcdf13f6b9c6af0e6..cc413f817c14abb04f917c17bceb4cdd4a146d91 100644
--- a/typo3/sysext/form/Resources/Public/JavaScript/backend/form-editor/stage-component.js
+++ b/typo3/sysext/form/Resources/Public/JavaScript/backend/form-editor/stage-component.js
@@ -10,1200 +10,4 @@
  *
  * The TYPO3 project - inspiring people to share!
  */
-
-/**
- * Module: @typo3/form/backend/form-editor/stage-component
- */
-import $ from 'jquery';
-import * as Helper from '@typo3/form/backend/form-editor/helper.js';
-import Icons from '@typo3/backend/icons.js';
-import Sortable from 'sortablejs';
-
-const {
-  bootstrap,
-  buildTitleByFormElement,
-  createAndAddAbstractViewFormElementToolbar,
-  createAbstractViewFormElementToolbar,
-  eachTemplateProperty,
-  getAbstractViewFormElementDomElement,
-  getAbstractViewFormElementWithinDomElement,
-  getAbstractViewFormElementIdentifierPathWithinDomElement,
-  getAbstractViewParentFormElementWithinDomElement,
-  getAbstractViewParentFormElementIdentifierPathWithinDomElement,
-  getAbstractViewSiblingFormElementIdentifierPathWithinDomElement,
-  getAllFormElementDomElements,
-  getStageDomElement,
-  getStagePanelDomElement,
-  removeAllStageToolbars,
-  renderAbstractStageArea,
-  renderCheckboxTemplate,
-  renderFileUploadTemplates,
-  renderFormDefinitionPageAsSortableList,
-  renderPagination,
-  renderPreviewStageArea,
-  renderSelectTemplates,
-  renderSimpleTemplate,
-  renderSimpleTemplateWithValidators,
-  renderUndoRedo,
-  setStageHeadline,
-} = factory($, Helper, Icons);
-
-export {
-  bootstrap,
-  buildTitleByFormElement,
-  createAndAddAbstractViewFormElementToolbar,
-  createAbstractViewFormElementToolbar,
-  eachTemplateProperty,
-  getAbstractViewFormElementDomElement,
-  getAbstractViewFormElementWithinDomElement,
-  getAbstractViewFormElementIdentifierPathWithinDomElement,
-  getAbstractViewParentFormElementWithinDomElement,
-  getAbstractViewParentFormElementIdentifierPathWithinDomElement,
-  getAbstractViewSiblingFormElementIdentifierPathWithinDomElement,
-  getAllFormElementDomElements,
-  getStageDomElement,
-  getStagePanelDomElement,
-  removeAllStageToolbars,
-  renderAbstractStageArea,
-  renderCheckboxTemplate,
-  renderFileUploadTemplates,
-  renderFormDefinitionPageAsSortableList,
-  renderPagination,
-  renderPreviewStageArea,
-  renderSelectTemplates,
-  renderSimpleTemplate,
-  renderSimpleTemplateWithValidators,
-  renderUndoRedo,
-  setStageHeadline,
-};
-
-
-function factory($, Helper, Icons) {
-  return (function($, Helper, Icons) {
-
-    /**
-     * @private
-     *
-     * @var object
-     */
-    var _configuration = null;
-
-    /**
-     * @private
-     *
-     * @var object
-     */
-    var _defaultConfiguration = {
-      domElementClassNames: {
-        formElementIsComposit: 't3-form-element-composit',
-        formElementIsTopLevel: 't3-form-element-toplevel',
-        noNesting: 'mjs-nestedSortable-no-nesting',
-        selected: 'selected',
-        sortable: 'sortable',
-        previewViewPreviewElement: 't3-form-element-preview'
-      },
-      domElementDataAttributeNames: {
-        abstractType: 'data-element-abstract-type',
-        noSorting: 'data-no-sorting'
-      },
-      domElementDataAttributeValues: {
-        abstractViewToolbar: 'elementToolbar',
-        abstractViewToolbarNewElement: 'stageElementToolbarNewElement',
-        abstractViewToolbarNewElementSplitButton: 'stageElementToolbarNewElementSplitButton',
-        abstractViewToolbarNewElementSplitButtonAfter: 'stageElementToolbarNewElementSplitButtonAfter',
-        abstractViewToolbarNewElementSplitButtonInside: 'stageElementToolbarNewElementSplitButtonInside',
-        abstractViewToolbarRemoveElement: 'stageElementToolbarRemoveElement',
-        buttonHeaderRedo: 'redoButton',
-        buttonHeaderUndo: 'undoButton',
-        buttonPaginationPrevious: 'buttonPaginationPrevious',
-        buttonPaginationNext: 'buttonPaginationNext',
-        'FormElement-_ElementToolbar': 'FormElement-_ElementToolbar',
-        'FormElement-_UnknownElement': 'FormElement-_UnknownElement',
-        'FormElement-AdvancedPassword': 'FormElement-AdvancedPassword',
-        'FormElement-Checkbox': 'FormElement-Checkbox',
-        'FormElement-ContentElement': 'FormElement-ContentElement',
-        'FormElement-CountrySelect': 'FormElement-CountrySelect',
-        'FormElement-DatePicker': 'FormElement-DatePicker',
-        'FormElement-Fieldset': 'FormElement-Fieldset',
-        'FormElement-GridRow': 'FormElement-GridRow',
-        'FormElement-FileUpload': 'FormElement-FileUpload',
-        'FormElement-Hidden': 'FormElement-Hidden',
-        'FormElement-ImageUpload': 'FormElement-ImageUpload',
-        'FormElement-MultiCheckbox': 'FormElement-MultiCheckbox',
-        'FormElement-MultiSelect': 'FormElement-MultiSelect',
-        'FormElement-Page': 'FormElement-Page',
-        'FormElement-Password': 'FormElement-Password',
-        'FormElement-RadioButton': 'FormElement-RadioButton',
-        'FormElement-SingleSelect': 'FormElement-SingleSelect',
-        'FormElement-StaticText': 'FormElement-StaticText',
-        'FormElement-SummaryPage': 'FormElement-SummaryPage',
-        'FormElement-Text': 'FormElement-Text',
-        'FormElement-Textarea': 'FormElement-Textarea',
-        'FormElement-Email': 'FormElement-Email',
-        'FormElement-Url': 'FormElement-Url',
-        'FormElement-Telephone': 'FormElement-Telephone',
-        'FormElement-Number': 'FormElement-Number',
-        'FormElement-Date': 'FormElement-Date',
-        formElementIcon: 'elementIcon',
-        iconValidator: 'form-validator',
-        multiValueContainer: 'multiValueContainer',
-        paginationTitle: 'paginationTitle',
-        stageHeadline: 'formDefinitionLabel',
-        stagePanel: 'stagePanel',
-        validatorsContainer: 'validatorsContainer',
-        validatorIcon: 'validatorIcon'
-      },
-      isSortable: true
-    };
-
-    /**
-     * @private
-     *
-     * @var object
-     */
-    var _formEditorApp = null;
-
-    /**
-     * @private
-     *
-     * @var object
-     */
-    var _stageDomElement = 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;
-    };
-
-    /**
-     * @public
-     *
-     * @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
-     *
-     * @return object
-     */
-    function getViewModel() {
-      return getFormEditorApp().getViewModel();
-    };
-
-    /**
-     * @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 getRootFormElement() {
-      return getFormEditorApp().getRootFormElement();
-    };
-
-    /**
-     * @private
-     *
-     * @return object
-     */
-    function getCurrentlySelectedFormElement() {
-      return getFormEditorApp().getCurrentlySelectedFormElement();
-    };
-
-    /**
-     * @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
-     *
-     * @return object
-     * @return string
-     * @return void
-     */
-    function _setTemplateTextContent(domElement, content) {
-      if (getUtility().isNonEmptyString(content)) {
-        $(domElement).text(content);
-      }
-    }
-
-    /**
-     * @private
-     *
-     * @param object
-     * @param object
-     * @return void
-     * @publish view/stage/abstract/render/template/perform
-     */
-    function _renderTemplateDispatcher(formElement, template) {
-      switch (formElement.get('type')) {
-        case 'Checkbox':
-          renderCheckboxTemplate(formElement, template);
-          break;
-        case 'FileUpload':
-        case 'ImageUpload':
-          renderFileUploadTemplates(formElement, template);
-          break;
-        case 'CountrySelect':
-        case 'SingleSelect':
-        case 'RadioButton':
-        case 'MultiSelect':
-        case 'MultiCheckbox':
-          renderSelectTemplates(formElement, template);
-          break;
-        case 'Textarea':
-        case 'AdvancedPassword':
-        case 'Password':
-        case 'Text':
-        case 'Email':
-        case 'Url':
-        case 'Telephone':
-        case 'Number':
-        case 'DatePicker':
-        case 'Date':
-          renderSimpleTemplateWithValidators(formElement, template);
-          break;
-        case 'Fieldset':
-        case 'GridRow':
-        case 'SummaryPage':
-        case 'Page':
-        case 'StaticText':
-        case 'Hidden':
-        case 'ContentElement':
-          renderSimpleTemplate(formElement, template);
-          break;
-      }
-      getPublisherSubscriber().publish('view/stage/abstract/render/template/perform', [formElement, template]);
-    };
-
-    /**
-     * @private
-     *
-     * @param object
-     * @return object
-     * @throws 1478987818
-     */
-    function _renderNestedSortableListItem(formElement) {
-      var childFormElements, childList, listItem, template;
-
-      listItem = $('<li></li>');
-      if (!getFormElementDefinition(formElement, '_isCompositeFormElement')) {
-        listItem.addClass(getHelper().getDomElementClassName('noNesting'));
-      }
-
-      if (getFormElementDefinition(formElement, '_isTopLevelFormElement')) {
-        listItem.addClass(getHelper().getDomElementClassName('formElementIsTopLevel'));
-      }
-      if (getFormElementDefinition(formElement, '_isCompositeFormElement')) {
-        listItem.addClass(getHelper().getDomElementClassName('formElementIsComposit'));
-      }
-
-      try {
-        template = getHelper().getTemplate('FormElement-' + formElement.get('type')).clone();
-      } catch (error) {
-        template = getHelper().getTemplate('FormElement-_UnknownElement').clone();
-        assert(
-          template.length,
-          'No template found for element "' + formElement.get('__identifierPath') + '"',
-          1478987818
-        );
-      }
-
-      template = $('<div></div>')
-        .attr(getHelper().getDomElementDataAttribute('elementIdentifier'), formElement.get('__identifierPath'))
-        .append($(template.html()));
-
-      if (getFormElementDefinition(formElement, '_isCompositeFormElement')) {
-        template.attr(getHelper().getDomElementDataAttribute('abstractType'), 'isCompositeFormElement');
-      }
-      if (getFormElementDefinition(formElement, '_isTopLevelFormElement')) {
-        template.attr(getHelper().getDomElementDataAttribute('abstractType'), 'isTopLevelFormElement');
-      }
-      listItem.append(template);
-
-      _renderTemplateDispatcher(formElement, template);
-
-      childFormElements = formElement.get('renderables');
-      childList = null;
-      if ('array' === $.type(childFormElements)) {
-        childList = $('<ol></ol>');
-        childList.addClass(getHelper().getDomElementClassName('sortable'));
-        for (var i = 0, len = childFormElements.length; i < len; ++i) {
-          childList.append(_renderNestedSortableListItem(childFormElements[i]));
-        }
-      }
-
-      if (childList) {
-        listItem.append(childList);
-      }
-      return listItem;
-    };
-
-    /**
-     * @private
-     *
-     * @return void
-     * @publish view/stage/abstract/dnd/start
-     * @publish view/stage/abstract/dnd/stop
-     * @publish view/stage/abstract/dnd/change
-     * @publish view/stage/abstract/dnd/update
-     */
-    function _addSortableEvents() {
-      const sortableLists = _stageDomElement.get(0).querySelectorAll('ol.' + getHelper().getDomElementClassName('sortable'));
-      const draggableSelector = 'li:not(' + getHelper().getDomElementDataAttribute('noSorting', 'bracesWithKey') + ')';
-      const handleSelector = 'div' + getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKey');
-
-      sortableLists.forEach(function (sortableList) {
-        sortableList.querySelectorAll(handleSelector).forEach(function (draggable) {
-          draggable.classList.add('form-sortable-handle');
-        });
-
-        new Sortable(sortableList, {
-          group: 'stage-nodes',
-          handle: handleSelector,
-          draggable: draggableSelector,
-          animation: 200,
-          swapThreshold: 0.6,
-          dragClass: 'form-sortable-drag',
-          ghostClass: 'form-sortable-ghost',
-          onStart: function (e) {
-            getPublisherSubscriber().publish('view/stage/abstract/dnd/start', [$(e.item), $(e.item)]);
-          },
-          onChange: function (e) {
-            let enclosingCompositeFormElement;
-            const parentFormElementIdentifierPath = getAbstractViewParentFormElementIdentifierPathWithinDomElement($(e.item));
-
-            if (parentFormElementIdentifierPath) {
-              enclosingCompositeFormElement = getFormEditorApp()
-                .findEnclosingCompositeFormElementWhichIsNotOnTopLevel(parentFormElementIdentifierPath);
-            }
-            getPublisherSubscriber().publish('view/stage/abstract/dnd/change', [
-              $(e.item),
-              parentFormElementIdentifierPath, enclosingCompositeFormElement
-            ]);
-          },
-          onEnd: function (e) {
-            const movedFormElementIdentifierPath = getAbstractViewFormElementIdentifierPathWithinDomElement($(e.item));
-            const previousFormElementIdentifierPath = getAbstractViewSiblingFormElementIdentifierPathWithinDomElement($(e.item), 'prev');
-            const nextFormElementIdentifierPath = getAbstractViewSiblingFormElementIdentifierPathWithinDomElement($(e.item), 'next');
-
-            getPublisherSubscriber().publish('view/stage/abstract/dnd/update', [
-              $(e.item),
-              movedFormElementIdentifierPath,
-              previousFormElementIdentifierPath,
-              nextFormElementIdentifierPath
-            ]);
-            getPublisherSubscriber().publish('view/stage/abstract/dnd/stop', [
-              getAbstractViewFormElementIdentifierPathWithinDomElement($(e.item))
-            ]);
-          },
-        });
-      });
-    };
-
-    /* *************************************************************
-     * Public Methods
-     * ************************************************************/
-
-    /**
-     * @public
-     *
-     * @return object
-     */
-    function getStageDomElement() {
-      return _stageDomElement;
-    };
-
-    /**
-     * @public
-     *
-     * @param object
-     * @return object
-     * @throws 1479037151
-     */
-    function buildTitleByFormElement(formElement) {
-      if (getUtility().isUndefinedOrNull(formElement)) {
-        formElement = getRootFormElement();
-      }
-      assert('object' === $.type(formElement), 'Invalid parameter "formElement"', 1479037151);
-
-      return $('<span></span>')
-        .text((formElement.get('label') ? formElement.get('label') : formElement.get('identifier')));
-    };
-
-    /**
-     * @public
-     *
-     * @param string title
-     * @return void
-     */
-    function setStageHeadline(title) {
-      if (getUtility().isUndefinedOrNull(title)) {
-        title = buildTitleByFormElement().text();
-      }
-
-      $(getHelper().getDomElementDataIdentifierSelector('stageHeadline')).text(title);
-    };
-
-    /**
-     * @public
-     *
-     * @return object
-     */
-    function getStagePanelDomElement() {
-      return $(getHelper().getDomElementDataIdentifierSelector('stagePanel'));
-    };
-
-    /**
-     * @public
-     *
-     * @return void
-     */
-    function renderPagination() {
-      var pageCount;
-
-      pageCount = getRootFormElement().get('renderables').length;
-
-      getViewModel().enableButton($(getHelper().getDomElementDataIdentifierSelector('buttonPaginationPrevious')));
-      getViewModel().enableButton($(getHelper().getDomElementDataIdentifierSelector('buttonPaginationNext')));
-
-      if (getFormEditorApp().getCurrentlySelectedPageIndex() === 0) {
-        getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector('buttonPaginationPrevious')));
-      }
-
-      if (pageCount === 1 || getFormEditorApp().getCurrentlySelectedPageIndex() === (pageCount - 1)) {
-        getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector('buttonPaginationNext')));
-      }
-
-      $(getHelper().getDomElementDataIdentifierSelector('paginationTitle')).text(
-        getFormElementDefinition(getRootFormElement(), 'paginationTitle')
-          .replace('{0}', getFormEditorApp().getCurrentlySelectedPageIndex() + 1)
-          .replace('{1}', pageCount)
-      );
-    };
-
-    /**
-     * @public
-     *
-     * @return void
-     */
-    function renderUndoRedo() {
-      getViewModel().enableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderUndo')));
-      getViewModel().enableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderRedo')));
-
-      if (getFormEditorApp().getCurrentApplicationStatePosition() + 1 >= getFormEditorApp().getCurrentApplicationStates()) {
-        getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderUndo')));
-      }
-      if (getFormEditorApp().getCurrentApplicationStatePosition() === 0) {
-        getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector('buttonHeaderRedo')));
-      }
-    };
-
-    /**
-     * @public
-     *
-     * @param object
-     * @return string
-     */
-    function getAllFormElementDomElements() {
-      return $(getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKey'),
-        _stageDomElement
-      );
-    };
-
-    /* *************************************************************
-     * Abstract stage
-     * ************************************************************/
-
-    /**
-     * @public
-     *
-     * @param int
-     * @return object
-     * @throws 1478721208
-     */
-    function renderFormDefinitionPageAsSortableList(pageIndex) {
-      assert(
-        'number' === $.type(pageIndex),
-        'Invalid parameter "pageIndex"',
-        1478721208
-      );
-
-      return $('<ol></ol>')
-        .append(_renderNestedSortableListItem(getRootFormElement().get('renderables')[pageIndex]));
-    };
-
-    /**
-     * @public
-     *
-     * @param object
-     * @return string
-     */
-    function getAbstractViewParentFormElementWithinDomElement(element) {
-      return $(element)
-        .parent()
-        .closest('li')
-        .find(getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKey'))
-        .first();
-    };
-
-    /**
-     * @public
-     *
-     * @param object
-     * @return string
-     */
-    function getAbstractViewParentFormElementIdentifierPathWithinDomElement(element) {
-      return getAbstractViewParentFormElementWithinDomElement(element)
-        .attr(getHelper().getDomElementDataAttribute('elementIdentifier'));
-    };
-
-    /**
-     * @public
-     *
-     * @param object
-     * @return string
-     */
-    function getAbstractViewFormElementWithinDomElement(element) {
-      return $(element)
-        .find(getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKey'))
-        .first();
-    };
-
-    /**
-     * @public
-     *
-     * @param object
-     * @return string
-     */
-    function getAbstractViewFormElementIdentifierPathWithinDomElement(element) {
-      return getAbstractViewFormElementWithinDomElement($(element))
-        .attr(getHelper().getDomElementDataAttribute('elementIdentifier'));
-    };
-
-    /**
-     * @private
-     *
-     * @param object
-     * @param string
-     * @return string
-     */
-    function getAbstractViewSiblingFormElementIdentifierPathWithinDomElement(element, position) {
-      var formElementIdentifierPath;
-
-      if (getUtility().isUndefinedOrNull(position)) {
-        position = 'prev';
-      }
-      formElementIdentifierPath = getAbstractViewFormElementIdentifierPathWithinDomElement(element);
-      element = (position === 'prev') ? $(element).prev('li') : $(element).next('li');
-      return element.find(getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKey'))
-        .not(getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKeyValue', [formElementIdentifierPath]))
-        .first()
-        .attr(getHelper().getDomElementDataAttribute('elementIdentifier'));
-    };
-
-    /**
-     * @public
-     *
-     * @param string|object
-     * @return object
-     */
-    function getAbstractViewFormElementDomElement(formElement) {
-      var formElementIdentifierPath;
-
-      if ('string' === $.type(formElement)) {
-        formElementIdentifierPath = formElement;
-      } else {
-        if (getUtility().isUndefinedOrNull(formElement)) {
-          formElementIdentifierPath = getCurrentlySelectedFormElement().get('__identifierPath');
-        } else {
-          formElementIdentifierPath = formElement.get('__identifierPath');
-        }
-      }
-      return $(getHelper()
-        .getDomElementDataAttribute('elementIdentifier', 'bracesWithKeyValue', [formElementIdentifierPath]), _stageDomElement);
-    };
-
-    /**
-     * @public
-     *
-     * @return void
-     */
-    function removeAllStageToolbars() {
-      $(getHelper().getDomElementDataIdentifierSelector('abstractViewToolbar'), _stageDomElement).off().empty().remove();
-    };
-
-    /**
-     * @public
-     *
-     * @param object
-     * @return object
-     * @publish view/insertElements/perform/after
-     * @publish view/insertElements/perform/inside
-     * @throws 1479035778
-     */
-    function createAbstractViewFormElementToolbar(formElement) {
-      var formElementTypeDefinition, template;
-      assert('object' === $.type(formElement), 'Invalid parameter "formElement"', 1479035778);
-
-      formElementTypeDefinition = getFormElementDefinition(formElement);
-      if (formElementTypeDefinition['_isTopLevelFormElement']) {
-        return $();
-      }
-
-      template = getHelper().getTemplate('FormElement-_ElementToolbar').clone();
-      if (!template.length) {
-        return $();
-      }
-
-      template = $($(template.html()));
-
-      getHelper().getTemplatePropertyDomElement('_type', template).text(getFormElementDefinition(formElement, 'label'));
-      getHelper().getTemplatePropertyDomElement('_identifier', template).text(formElement.get('identifier'));
-
-      if (formElementTypeDefinition['_isCompositeFormElement']) {
-        getViewModel().hideComponent($(getHelper().getDomElementDataIdentifierSelector('abstractViewToolbarNewElement'), template));
-
-        $(getHelper().getDomElementDataIdentifierSelector('abstractViewToolbarNewElementSplitButtonAfter'), template).on('click', function(e) {
-          getPublisherSubscriber().publish('view/stage/abstract/elementToolbar/button/newElement/clicked', [
-              'view/insertElements/perform/after',
-              {
-                disableElementTypes: [],
-                onlyEnableElementTypes: []
-              }
-            ]
-          );
-        });
-
-        $(getHelper().getDomElementDataIdentifierSelector('abstractViewToolbarNewElementSplitButtonInside'), template).on('click', function(e) {
-          getPublisherSubscriber().publish('view/stage/abstract/elementToolbar/button/newElement/clicked', [
-              'view/insertElements/perform/inside',
-              {
-                disableElementTypes: [],
-                onlyEnableElementTypes: []
-              }
-            ]
-          );
-        });
-      } else {
-        getViewModel().hideComponent($(getHelper().getDomElementDataIdentifierSelector('abstractViewToolbarNewElementSplitButton'), template));
-
-        $(getHelper().getDomElementDataIdentifierSelector('abstractViewToolbarNewElement'), template).on('click', function(e) {
-          getPublisherSubscriber().publish(
-            'view/stage/abstract/elementToolbar/button/newElement/clicked', [
-              'view/insertElements/perform/after',
-              {
-                disableElementTypes: []
-              }
-            ]
-          );
-        });
-      }
-
-      $(getHelper().getDomElementDataIdentifierSelector('abstractViewToolbarRemoveElement'), template).on('click', function(e) {
-        getViewModel().showRemoveFormElementModal();
-      });
-
-      return template;
-    };
-
-    /**
-     * @public
-     *
-     * @param object
-     * @param object
-     * @param bool
-     * @return void
-     */
-    function createAndAddAbstractViewFormElementToolbar(selectedFormElementDomElement, formElement, useFadeEffect) {
-      var toolbar;
-      if (getUtility().isUndefinedOrNull(formElement)) {
-        formElement = getCurrentlySelectedFormElement();
-      }
-
-      if (useFadeEffect) {
-        createAbstractViewFormElementToolbar(formElement).fadeOut(0, function() {
-          selectedFormElementDomElement.prepend($(this));
-          $(getHelper().getDomElementDataIdentifierSelector('abstractViewToolbar'), selectedFormElementDomElement).fadeIn('fast');
-        });
-      } else {
-        selectedFormElementDomElement.prepend(createAbstractViewFormElementToolbar(formElement));
-      }
-
-    };
-
-    /**
-     * @public
-     *
-     * @param int
-     * @param function
-     * @return void
-     * @publish view/stage/dnd/stop
-     * @publish view/stage/element/clicked
-     * @throws 1478169511
-     */
-    function renderAbstractStageArea(pageIndex, callback) {
-      if (getUtility().isUndefinedOrNull(pageIndex)) {
-        pageIndex = getFormEditorApp().getCurrentlySelectedPageIndex();
-      }
-      _stageDomElement.off().empty().append(renderFormDefinitionPageAsSortableList(pageIndex));
-
-      _stageDomElement.on("click", function(e) {
-        var formElementIdentifierPath;
-
-        formElementIdentifierPath = $(e.target)
-          .closest(getHelper().getDomElementDataAttribute('elementIdentifier', 'bracesWithKey'))
-          .attr(getHelper().getDomElementDataAttribute('elementIdentifier'));
-        if (
-          getUtility().isUndefinedOrNull(formElementIdentifierPath)
-          || !getUtility().isNonEmptyString(formElementIdentifierPath)
-        ) {
-          return;
-        }
-
-        getPublisherSubscriber().publish('view/stage/element/clicked', [formElementIdentifierPath]);
-      });
-
-      if (_configuration['isSortable']) {
-        _addSortableEvents();
-      }
-
-      if ('function' === $.type(callback)) {
-        callback();
-      }
-    };
-
-
-    /* *************************************************************
-     * Preview stage
-     * ************************************************************/
-
-    /**
-     * @public
-     *
-     * @param string html
-     * @return void
-     * @throws 1475424409
-     */
-    function renderPreviewStageArea(html) {
-      assert(getUtility().isNonEmptyString(html), 'Invalid parameter "html"', 1475424409);
-
-      _stageDomElement.off().empty().html(html);
-
-      $(':input', _stageDomElement).prop('disabled', 'disabled').on('click dblclick select focus keydown keypress keyup mousedown mouseup', function(e) {
-        return e.preventDefault();
-      });
-
-      $('form', _stageDomElement).submit(function(e) {
-        return e.preventDefault();
-      });
-
-      getAllFormElementDomElements().each(function(i, element) {
-        var formElement, metaLabel;
-
-        formElement = getFormEditorApp()
-          .getFormElementByIdentifierPath($(this).data('elementIdentifierPath'));
-
-        if (
-          !getFormElementDefinition(formElement, '_isTopLevelFormElement')
-        ) {
-          $(this).attr('title', 'identifier: ' + formElement.get('identifier') + ' (type: ' + formElement.get('type') + ')');
-        }
-
-        if (getFormElementDefinition(formElement, '_isTopLevelFormElement')) {
-          $(this).addClass(getHelper().getDomElementClassName('formElementIsTopLevel'));
-        }
-        if (getFormElementDefinition(formElement, '_isCompositeFormElement')) {
-          $(this).addClass(getHelper().getDomElementClassName('formElementIsComposit'));
-        }
-      });
-
-    };
-
-    /* *************************************************************
-     * Template rendering
-     * ************************************************************/
-
-    /**
-     * @public
-     *
-     * @param object
-     * @param template
-     * @param function
-     * @return void
-     */
-    function eachTemplateProperty(formElement, template, callback) {
-      $(getHelper().getDomElementDataAttribute('templateProperty', 'bracesWithKey'), template).each(function(i, element) {
-        var propertyPath, propertyValue;
-
-        propertyPath = $(element).attr(getHelper().getDomElementDataAttribute('templateProperty'));
-        propertyValue = formElement.get(propertyPath);
-
-        if ('function' === $.type(callback)) {
-          callback(propertyPath, propertyValue, element);
-        }
-      });
-    };
-
-    /**
-     * @private
-     *
-     * @return object
-     * @return object
-     * @return void
-     */
-    function renderCheckboxTemplate(formElement, template) {
-      renderSimpleTemplateWithValidators(formElement, template);
-
-      eachTemplateProperty(formElement, template, function(propertyPath, propertyValue, domElement) {
-        if (
-          ('boolean' === $.type(propertyValue) && propertyValue)
-          || propertyValue === 'true'
-          || propertyValue === 1
-          || propertyValue === "1"
-        ) {
-          $(domElement).addClass(getHelper().getDomElementClassName('noNesting'));
-        }
-      });
-    };
-
-    /**
-     * @public
-     *
-     * @return object
-     * @return object
-     * @return void
-     * @throws 1479035696
-     */
-    function renderSimpleTemplate(formElement, template) {
-      assert('object' === $.type(formElement), 'Invalid parameter "formElement"', 1479035696);
-
-      eachTemplateProperty(formElement, template, function(propertyPath, propertyValue, domElement) {
-        _setTemplateTextContent(domElement, propertyValue);
-      });
-
-      Icons.getIcon(
-        getFormElementDefinition(formElement, 'iconIdentifier'),
-        Icons.sizes.small,
-        null,
-        Icons.states.default,
-        Icons.markupIdentifiers.inline
-      ).then(function(icon) {
-        $(getHelper().getDomElementDataIdentifierSelector('formElementIcon'), template)
-          .append($(icon).addClass(getHelper().getDomElementClassName('icon')));
-      });
-
-      getHelper()
-        .getTemplatePropertyDomElement('_type', template)
-        .append(document.createTextNode(getFormElementDefinition(formElement, 'label')));
-      getHelper()
-        .getTemplatePropertyDomElement('_identifier', template)
-        .append(document.createTextNode(formElement.get('identifier')));
-    };
-
-    /**
-     * @public
-     *
-     * @return object
-     * @return object
-     * @return void
-     * @throws 1479035674
-     */
-    function renderSimpleTemplateWithValidators(formElement, template) {
-      var validators, validatorsCountWithoutRequired, validatorsTemplateContent;
-      assert('object' === $.type(formElement), 'Invalid parameter "formElement"', 1479035674);
-
-      renderSimpleTemplate(formElement, template);
-
-      validatorsTemplateContent = $(
-        getHelper().getDomElementDataIdentifierSelector('validatorsContainer'),
-        $(template)
-      ).clone();
-
-      $(getHelper().getDomElementDataIdentifierSelector('validatorsContainer'), $(template)).empty();
-      validators = formElement.get('validators');
-
-      if ('array' === $.type(validators)) {
-        validatorsCountWithoutRequired = 0;
-        if (validators.length > 0) {
-          for (var i = 0, len = validators.length; i < len; ++i) {
-            var collectionElementConfiguration, rowTemplate;
-
-            if ('NotEmpty' === validators[i]['identifier']) {
-              getHelper()
-                .getTemplatePropertyDomElement('_required', template)
-                .text('*');
-              continue;
-            }
-            validatorsCountWithoutRequired++;
-
-            collectionElementConfiguration = getFormEditorApp()
-              .getFormEditorDefinition('validators', validators[i]['identifier']);
-            rowTemplate = $($(validatorsTemplateContent).clone());
-
-            getHelper()
-              .getTemplatePropertyDomElement('_label', rowTemplate)
-              .append(document.createTextNode(collectionElementConfiguration['label']));
-            $(getHelper().getDomElementDataIdentifierSelector('validatorsContainer'), $(template))
-              .append(rowTemplate.html());
-          }
-
-          if (validatorsCountWithoutRequired > 0) {
-            Icons.getIcon(
-              getHelper().getDomElementDataAttributeValue('iconValidator'),
-              Icons.sizes.small,
-              null,
-              Icons.states.default,
-              Icons.markupIdentifiers.inline
-            ).then(function(icon) {
-              $(getHelper().getDomElementDataIdentifierSelector('validatorIcon'), $(template))
-                .append($(icon).addClass(getHelper().getDomElementClassName('icon')));
-            });
-          }
-        }
-      }
-    };
-
-    /**
-     * @public
-     *
-     * @return object
-     * @return object
-     * @return void
-     */
-    function renderSelectTemplates(formElement, template) {
-      var appendMultiValue, defaultValue, multiValueTemplateContent, propertyPath, propertyValue;
-
-      multiValueTemplateContent = $(
-        getHelper().getDomElementDataIdentifierSelector('multiValueContainer'),
-        $(template)
-      ).clone();
-      $(getHelper().getDomElementDataIdentifierSelector('multiValueContainer'), $(template)).empty();
-
-      renderSimpleTemplateWithValidators(formElement, template);
-
-      propertyPath = $(getHelper().getDomElementDataIdentifierSelector('multiValueContainer'), $(template))
-        .attr(getHelper().getDomElementDataAttribute('templateProperty'));
-
-      propertyValue = formElement.get(propertyPath);
-
-      appendMultiValue = function(label, value, defaultValue) {
-        var isPreselected, rowTemplate;
-
-        isPreselected = false;
-        rowTemplate = $($(multiValueTemplateContent).clone());
-
-        for (var defaultValueKey in defaultValue) {
-          if (!defaultValue.hasOwnProperty(defaultValueKey)) {
-            continue;
-          }
-          if (defaultValue[defaultValueKey] === value) {
-            isPreselected = true;
-            break;
-          }
-        }
-
-        getHelper().getTemplatePropertyDomElement('_label', rowTemplate).append(document.createTextNode(label));
-
-        if (isPreselected) {
-          getHelper().getTemplatePropertyDomElement('_label', rowTemplate).addClass(
-            getHelper().getDomElementClassName('selected')
-          );
-        }
-
-        $(getHelper().getDomElementDataIdentifierSelector('multiValueContainer'), $(template))
-          .append(rowTemplate.html());
-      };
-
-      defaultValue = formElement.get('defaultValue');
-
-      if (getFormEditorApp().getUtility().isUndefinedOrNull(defaultValue)) {
-        defaultValue = {};
-      } else if ('string' === $.type(defaultValue)) {
-        defaultValue = {0: defaultValue};
-      }
-
-      if ('object' === $.type(propertyValue)) {
-        for (var propertyValueKey in propertyValue) {
-          if (!propertyValue.hasOwnProperty(propertyValueKey)) {
-            continue;
-          }
-          appendMultiValue(propertyValue[propertyValueKey], propertyValueKey, defaultValue);
-        }
-      } else if ('array' === $.type(propertyValue)) {
-        for (var propertyValueKey in propertyValue) {
-          if (!propertyValue.hasOwnProperty(propertyValueKey)) {
-            continue;
-          }
-          if (getUtility().isUndefinedOrNull(propertyValue[propertyValueKey]['_label'])) {
-            appendMultiValue(propertyValue[propertyValueKey], propertyValueKey, defaultValue);
-          } else {
-            appendMultiValue(propertyValue[propertyValueKey]['_label'], propertyValue[propertyValueKey]['_value'], defaultValue);
-          }
-        }
-      }
-    };
-
-    /**
-     * @public
-     *
-     * @return object
-     * @return object
-     * @return void
-     */
-    function renderFileUploadTemplates(formElement, template) {
-      var appendMultiValue, multiValueTemplateContent, propertyPath, propertyValue;
-
-      multiValueTemplateContent = $(
-        getHelper().getDomElementDataIdentifierSelector('multiValueContainer'),
-        $(template)
-      ).clone();
-      $(getHelper().getDomElementDataIdentifierSelector('multiValueContainer'), $(template)).empty();
-
-      renderSimpleTemplateWithValidators(formElement, template);
-
-      propertyPath = $(getHelper().getDomElementDataIdentifierSelector('multiValueContainer'), $(template))
-        .attr(getHelper().getDomElementDataAttribute('templateProperty'));
-      propertyValue = formElement.get(propertyPath);
-
-      appendMultiValue = function(value) {
-        var rowTemplate;
-
-        rowTemplate = $($(multiValueTemplateContent).clone());
-
-        getHelper().getTemplatePropertyDomElement('_value', rowTemplate).append(value);
-        $(getHelper().getDomElementDataIdentifierSelector('multiValueContainer'), $(template))
-          .append(rowTemplate.html());
-      };
-
-      if ('object' === $.type(propertyValue)) {
-        for (var propertyValueKey in propertyValue) {
-          if (!propertyValue.hasOwnProperty(propertyValueKey)) {
-            continue;
-          }
-          appendMultiValue(propertyValue[propertyValueKey]);
-        }
-      } else if ('array' === $.type(propertyValue)) {
-        for (var i = 0, len = propertyValue.length; i < len; ++i) {
-          appendMultiValue(propertyValue[i]);
-        }
-      }
-    };
-
-    /**
-     * @public
-     *
-     * @param object
-     * @param object
-     * @param object
-     * @return this
-     * @throws 1478992119
-     */
-    function bootstrap(formEditorApp, appendToDomElement, configuration) {
-      _formEditorApp = formEditorApp;
-      assert('object' === $.type(appendToDomElement), 'Invalid parameter "appendToDomElement"', 1478992119);
-
-      _stageDomElement = $(appendToDomElement);
-      _configuration = $.extend(true, _defaultConfiguration, configuration || {});
-      _helperSetup();
-      return this;
-    };
-
-    /**
-     * Publish the public methods.
-     * Implements the "Revealing Module Pattern".
-     */
-    return {
-      bootstrap: bootstrap,
-      buildTitleByFormElement: buildTitleByFormElement,
-      createAndAddAbstractViewFormElementToolbar: createAndAddAbstractViewFormElementToolbar,
-      createAbstractViewFormElementToolbar: createAbstractViewFormElementToolbar,
-      eachTemplateProperty: eachTemplateProperty,
-      getAbstractViewFormElementDomElement: getAbstractViewFormElementDomElement,
-      getAbstractViewFormElementWithinDomElement: getAbstractViewFormElementWithinDomElement,
-      getAbstractViewFormElementIdentifierPathWithinDomElement: getAbstractViewFormElementIdentifierPathWithinDomElement,
-      getAbstractViewParentFormElementWithinDomElement: getAbstractViewParentFormElementWithinDomElement,
-      getAbstractViewParentFormElementIdentifierPathWithinDomElement: getAbstractViewParentFormElementIdentifierPathWithinDomElement,
-      getAbstractViewSiblingFormElementIdentifierPathWithinDomElement: getAbstractViewSiblingFormElementIdentifierPathWithinDomElement,
-      getAllFormElementDomElements: getAllFormElementDomElements,
-      getStageDomElement: getStageDomElement,
-      getStagePanelDomElement: getStagePanelDomElement,
-      removeAllStageToolbars: removeAllStageToolbars,
-      renderAbstractStageArea: renderAbstractStageArea,
-      renderCheckboxTemplate: renderCheckboxTemplate,
-      renderFileUploadTemplates: renderFileUploadTemplates,
-      renderFormDefinitionPageAsSortableList: renderFormDefinitionPageAsSortableList,
-      renderPagination: renderPagination,
-      renderPreviewStageArea: renderPreviewStageArea,
-      renderSelectTemplates: renderSelectTemplates,
-      renderSimpleTemplate: renderSimpleTemplate,
-      renderSimpleTemplateWithValidators: renderSimpleTemplateWithValidators,
-      renderUndoRedo: renderUndoRedo,
-      setStageHeadline: setStageHeadline
-    };
-  })($, Helper, Icons);
-}
+import $ from"jquery";import*as Helper from"@typo3/form/backend/form-editor/helper.js";import Icons from"@typo3/backend/icons.js";import Sortable from"sortablejs";const defaultConfiguration={domElementClassNames:{formElementIsComposit:"t3-form-element-composit",formElementIsTopLevel:"t3-form-element-toplevel",noNesting:"mjs-nestedSortable-no-nesting",selected:"selected",sortable:"sortable",previewViewPreviewElement:"t3-form-element-preview"},domElementDataAttributeNames:{abstractType:"data-element-abstract-type",noSorting:"data-no-sorting"},domElementDataAttributeValues:{abstractViewToolbar:"elementToolbar",abstractViewToolbarNewElement:"stageElementToolbarNewElement",abstractViewToolbarNewElementSplitButton:"stageElementToolbarNewElementSplitButton",abstractViewToolbarNewElementSplitButtonAfter:"stageElementToolbarNewElementSplitButtonAfter",abstractViewToolbarNewElementSplitButtonInside:"stageElementToolbarNewElementSplitButtonInside",abstractViewToolbarRemoveElement:"stageElementToolbarRemoveElement",buttonHeaderRedo:"redoButton",buttonHeaderUndo:"undoButton",buttonPaginationPrevious:"buttonPaginationPrevious",buttonPaginationNext:"buttonPaginationNext","FormElement-_ElementToolbar":"FormElement-_ElementToolbar","FormElement-_UnknownElement":"FormElement-_UnknownElement","FormElement-AdvancedPassword":"FormElement-AdvancedPassword","FormElement-Checkbox":"FormElement-Checkbox","FormElement-ContentElement":"FormElement-ContentElement","FormElement-CountrySelect":"FormElement-CountrySelect","FormElement-DatePicker":"FormElement-DatePicker","FormElement-Fieldset":"FormElement-Fieldset","FormElement-GridRow":"FormElement-GridRow","FormElement-FileUpload":"FormElement-FileUpload","FormElement-Hidden":"FormElement-Hidden","FormElement-ImageUpload":"FormElement-ImageUpload","FormElement-MultiCheckbox":"FormElement-MultiCheckbox","FormElement-MultiSelect":"FormElement-MultiSelect","FormElement-Page":"FormElement-Page","FormElement-Password":"FormElement-Password","FormElement-RadioButton":"FormElement-RadioButton","FormElement-SingleSelect":"FormElement-SingleSelect","FormElement-StaticText":"FormElement-StaticText","FormElement-SummaryPage":"FormElement-SummaryPage","FormElement-Text":"FormElement-Text","FormElement-Textarea":"FormElement-Textarea","FormElement-Email":"FormElement-Email","FormElement-Url":"FormElement-Url","FormElement-Telephone":"FormElement-Telephone","FormElement-Number":"FormElement-Number","FormElement-Date":"FormElement-Date",formElementIcon:"elementIcon",iconValidator:"form-validator",multiValueContainer:"multiValueContainer",paginationTitle:"paginationTitle",stageHeadline:"formDefinitionLabel",stagePanel:"stagePanel",validatorsContainer:"validatorsContainer",validatorIcon:"validatorIcon"},isSortable:!0};let configuration=null,formEditorApp=null,stageDomElement=null;function getFormEditorApp(){return formEditorApp}function getHelper(e){return getUtility().isUndefinedOrNull(e)?Helper.setConfiguration(configuration):Helper.setConfiguration(e)}function getUtility(){return getFormEditorApp().getUtility()}function getViewModel(){return getFormEditorApp().getViewModel()}function assert(e,t,n){return getFormEditorApp().assert(e,t,n)}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 setTemplateTextContent(e,t){getUtility().isNonEmptyString(t)&&$(e).text(t)}function renderTemplateDispatcher(e,t){switch(e.get("type")){case"Checkbox":renderCheckboxTemplate(e,t);break;case"FileUpload":case"ImageUpload":renderFileUploadTemplates(e,t);break;case"CountrySelect":case"SingleSelect":case"RadioButton":case"MultiSelect":case"MultiCheckbox":renderSelectTemplates(e,t);break;case"Textarea":case"AdvancedPassword":case"Password":case"Text":case"Email":case"Url":case"Telephone":case"Number":case"DatePicker":case"Date":renderSimpleTemplateWithValidators(e,t);break;case"Fieldset":case"GridRow":case"SummaryPage":case"Page":case"StaticText":case"Hidden":case"ContentElement":renderSimpleTemplate(e,t)}getPublisherSubscriber().publish("view/stage/abstract/render/template/perform",[e,t])}function renderNestedSortableListItem(e){let t,n;const r=$("<li></li>");getFormElementDefinition(e,"_isCompositeFormElement")||r.addClass(getHelper().getDomElementClassName("noNesting")),getFormElementDefinition(e,"_isTopLevelFormElement")&&r.addClass(getHelper().getDomElementClassName("formElementIsTopLevel")),getFormElementDefinition(e,"_isCompositeFormElement")&&r.addClass(getHelper().getDomElementClassName("formElementIsComposit"));try{n=getHelper().getTemplate("FormElement-"+e.get("type")).clone()}catch(t){n=getHelper().getTemplate("FormElement-_UnknownElement").clone(),assert(n.length>0,'No template found for element "'+e.get("__identifierPath")+'"',1478987818)}n=$("<div></div>").attr(getHelper().getDomElementDataAttribute("elementIdentifier"),e.get("__identifierPath")).append($(n.html())),getFormElementDefinition(e,"_isCompositeFormElement")&&n.attr(getHelper().getDomElementDataAttribute("abstractType"),"isCompositeFormElement"),getFormElementDefinition(e,"_isTopLevelFormElement")&&n.attr(getHelper().getDomElementDataAttribute("abstractType"),"isTopLevelFormElement"),r.append(n),renderTemplateDispatcher(e,n);const o=e.get("renderables");if(t=null,"array"===$.type(o)){t=$("<ol></ol>"),t.addClass(getHelper().getDomElementClassName("sortable"));for(let e=0,n=o.length;e<n;++e)t.append(renderNestedSortableListItem(o[e]))}return t&&r.append(t),r}function addSortableEvents(){const e=stageDomElement.get(0).querySelectorAll("ol."+getHelper().getDomElementClassName("sortable")),t="li:not("+getHelper().getDomElementDataAttribute("noSorting","bracesWithKey")+")",n="div"+getHelper().getDomElementDataAttribute("elementIdentifier","bracesWithKey");e.forEach((function(e){e.querySelectorAll(n).forEach((function(e){e.classList.add("form-sortable-handle")})),new Sortable(e,{group:"stage-nodes",handle:n,draggable:t,animation:200,swapThreshold:.6,dragClass:"form-sortable-drag",ghostClass:"form-sortable-ghost",onStart:function(e){getPublisherSubscriber().publish("view/stage/abstract/dnd/start",[$(e.item),$(e.item)])},onChange:function(e){let t;const n=getAbstractViewParentFormElementIdentifierPathWithinDomElement($(e.item));n&&(t=getFormEditorApp().findEnclosingCompositeFormElementWhichIsNotOnTopLevel(n)),getPublisherSubscriber().publish("view/stage/abstract/dnd/change",[$(e.item),n,t])},onEnd:function(e){const t=getAbstractViewFormElementIdentifierPathWithinDomElement($(e.item)),n=getAbstractViewSiblingFormElementIdentifierPathWithinDomElement($(e.item),"prev"),r=getAbstractViewSiblingFormElementIdentifierPathWithinDomElement($(e.item),"next");getPublisherSubscriber().publish("view/stage/abstract/dnd/update",[$(e.item),t,n,r]),getPublisherSubscriber().publish("view/stage/abstract/dnd/stop",[getAbstractViewFormElementIdentifierPathWithinDomElement($(e.item))])}})}))}export function getStageDomElement(){return stageDomElement}export function buildTitleByFormElement(e){getUtility().isUndefinedOrNull(e)&&(e=getRootFormElement()),assert("object"===$.type(e),'Invalid parameter "formElement"',1479037151);const t=document.createElement("span");return t.textContent=e.get("label")?e.get("label"):e.get("identifier"),t}export function setStageHeadline(e){getUtility().isUndefinedOrNull(e)&&(e=buildTitleByFormElement().textContent),$(getHelper().getDomElementDataIdentifierSelector("stageHeadline")).text(e)}export function getStagePanelDomElement(){return $(getHelper().getDomElementDataIdentifierSelector("stagePanel"))}export function renderPagination(){const e=getRootFormElement().get("renderables").length;getViewModel().enableButton($(getHelper().getDomElementDataIdentifierSelector("buttonPaginationPrevious"))),getViewModel().enableButton($(getHelper().getDomElementDataIdentifierSelector("buttonPaginationNext"))),0===getFormEditorApp().getCurrentlySelectedPageIndex()&&getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector("buttonPaginationPrevious"))),1!==e&&getFormEditorApp().getCurrentlySelectedPageIndex()!==e-1||getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector("buttonPaginationNext")));const t=getFormEditorApp().getCurrentlySelectedPageIndex()+1;$(getHelper().getDomElementDataIdentifierSelector("paginationTitle")).text(getFormElementDefinition(getRootFormElement(),"paginationTitle").replace("{0}",t.toString()).replace("{1}",e))}export function renderUndoRedo(){getViewModel().enableButton($(getHelper().getDomElementDataIdentifierSelector("buttonHeaderUndo"))),getViewModel().enableButton($(getHelper().getDomElementDataIdentifierSelector("buttonHeaderRedo"))),getFormEditorApp().getCurrentApplicationStatePosition()+1>=getFormEditorApp().getCurrentApplicationStates()&&getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector("buttonHeaderUndo"))),0===getFormEditorApp().getCurrentApplicationStatePosition()&&getViewModel().disableButton($(getHelper().getDomElementDataIdentifierSelector("buttonHeaderRedo")))}export function getAllFormElementDomElements(){return $(getHelper().getDomElementDataAttribute("elementIdentifier","bracesWithKey"),stageDomElement)}export function renderFormDefinitionPageAsSortableList(e){return assert("number"===$.type(e),'Invalid parameter "pageIndex"',1478721208),$("<ol></ol>").append(renderNestedSortableListItem(getRootFormElement().get("renderables")[e]))}export function getAbstractViewParentFormElementWithinDomElement(e){return $(e).parent().closest("li").find(getHelper().getDomElementDataAttribute("elementIdentifier","bracesWithKey")).first()}export function getAbstractViewParentFormElementIdentifierPathWithinDomElement(e){return getAbstractViewParentFormElementWithinDomElement(e).attr(getHelper().getDomElementDataAttribute("elementIdentifier"))}export function getAbstractViewFormElementWithinDomElement(e){return $(e).find(getHelper().getDomElementDataAttribute("elementIdentifier","bracesWithKey")).first()}export function getAbstractViewFormElementIdentifierPathWithinDomElement(e){return getAbstractViewFormElementWithinDomElement($(e)).attr(getHelper().getDomElementDataAttribute("elementIdentifier"))}export function getAbstractViewSiblingFormElementIdentifierPathWithinDomElement(e,t){getUtility().isUndefinedOrNull(t)&&(t="prev");const n=getAbstractViewFormElementIdentifierPathWithinDomElement(e);return(e="prev"===t?$(e).prev("li"):$(e).next("li")).find(getHelper().getDomElementDataAttribute("elementIdentifier","bracesWithKey")).not(getHelper().getDomElementDataAttribute("elementIdentifier","bracesWithKeyValue",[n])).first().attr(getHelper().getDomElementDataAttribute("elementIdentifier"))}export function getAbstractViewFormElementDomElement(e){let t;return t="string"==typeof e?e:getUtility().isUndefinedOrNull(e)?getCurrentlySelectedFormElement().get("__identifierPath"):e.get("__identifierPath"),$(getHelper().getDomElementDataAttribute("elementIdentifier","bracesWithKeyValue",[t]),stageDomElement)}export function removeAllStageToolbars(){$(getHelper().getDomElementDataIdentifierSelector("abstractViewToolbar"),stageDomElement).off().empty().remove()}export function createAbstractViewFormElementToolbar(e){let t;assert("object"===$.type(e),'Invalid parameter "formElement"',1479035778);const n=getFormElementDefinition(e,void 0);return n._isTopLevelFormElement?$():(t=getHelper().getTemplate("FormElement-_ElementToolbar").clone(),t.length?(t=$($(t.html())),getHelper().getTemplatePropertyDomElement("_type",t).text(getFormElementDefinition(e,"label")),getHelper().getTemplatePropertyDomElement("_identifier",t).text(e.get("identifier")),n._isCompositeFormElement?(getViewModel().hideComponent($(getHelper().getDomElementDataIdentifierSelector("abstractViewToolbarNewElement"),t)),$(getHelper().getDomElementDataIdentifierSelector("abstractViewToolbarNewElementSplitButtonAfter"),t).on("click",(function(){getPublisherSubscriber().publish("view/stage/abstract/elementToolbar/button/newElement/clicked",["view/insertElements/perform/after",{disableElementTypes:[],onlyEnableElementTypes:[]}])})),$(getHelper().getDomElementDataIdentifierSelector("abstractViewToolbarNewElementSplitButtonInside"),t).on("click",(function(){getPublisherSubscriber().publish("view/stage/abstract/elementToolbar/button/newElement/clicked",["view/insertElements/perform/inside",{disableElementTypes:[],onlyEnableElementTypes:[]}])}))):(getViewModel().hideComponent($(getHelper().getDomElementDataIdentifierSelector("abstractViewToolbarNewElementSplitButton"),t)),$(getHelper().getDomElementDataIdentifierSelector("abstractViewToolbarNewElement"),t).on("click",(function(){getPublisherSubscriber().publish("view/stage/abstract/elementToolbar/button/newElement/clicked",["view/insertElements/perform/after",{disableElementTypes:[]}])}))),$(getHelper().getDomElementDataIdentifierSelector("abstractViewToolbarRemoveElement"),t).on("click",(function(){getViewModel().showRemoveFormElementModal()})),t):$())}export function createAndAddAbstractViewFormElementToolbar(e,t,n){getUtility().isUndefinedOrNull(t)&&(t=getCurrentlySelectedFormElement()),n?createAbstractViewFormElementToolbar(t).fadeOut(0,(function(){e.prepend($(this)),$(getHelper().getDomElementDataIdentifierSelector("abstractViewToolbar"),e).fadeIn("fast")})):e.prepend(createAbstractViewFormElementToolbar(t))}export function renderAbstractStageArea(e,t){getUtility().isUndefinedOrNull(e)&&(e=getFormEditorApp().getCurrentlySelectedPageIndex()),stageDomElement.off().empty().append(renderFormDefinitionPageAsSortableList(e)),stageDomElement.on("click",(function(e){const t=$(e.target).closest(getHelper().getDomElementDataAttribute("elementIdentifier","bracesWithKey")).attr(getHelper().getDomElementDataAttribute("elementIdentifier"));!getUtility().isUndefinedOrNull(t)&&getUtility().isNonEmptyString(t)&&getPublisherSubscriber().publish("view/stage/element/clicked",[t])})),configuration.isSortable&&addSortableEvents(),"function"===$.type(t)&&t()}export function renderPreviewStageArea(e){assert(getUtility().isNonEmptyString(e),'Invalid parameter "html"',1475424409),stageDomElement.off().empty().html(e),$(":input",stageDomElement).prop("disabled","disabled").on("click dblclick select focus keydown keypress keyup mousedown mouseup",(function(e){return e.preventDefault()})),$("form",stageDomElement).submit((function(e){return e.preventDefault()})),getAllFormElementDomElements().each((function(){const e=getFormEditorApp().getFormElementByIdentifierPath($(this).data("elementIdentifierPath"));getFormElementDefinition(e,"_isTopLevelFormElement")||$(this).attr("title","identifier: "+e.get("identifier")+" (type: "+e.get("type")+")"),getFormElementDefinition(e,"_isTopLevelFormElement")&&$(this).addClass(getHelper().getDomElementClassName("formElementIsTopLevel")),getFormElementDefinition(e,"_isCompositeFormElement")&&$(this).addClass(getHelper().getDomElementClassName("formElementIsComposit"))}))}export function eachTemplateProperty(e,t,n){$(getHelper().getDomElementDataAttribute("templateProperty","bracesWithKey"),t).each((function(t,r){const o=$(r).attr(getHelper().getDomElementDataAttribute("templateProperty")),l=e.get(o);"function"===$.type(n)&&n(o,l,r)}))}export function renderCheckboxTemplate(e,t){renderSimpleTemplateWithValidators(e,t),eachTemplateProperty(e,t,(function(e,t,n){("boolean"===$.type(t)&&t||"true"===t||1===t||"1"===t)&&$(n).addClass(getHelper().getDomElementClassName("noNesting"))}))}export function renderSimpleTemplate(e,t){assert("object"===$.type(e),'Invalid parameter "formElement"',1479035696),eachTemplateProperty(e,t,((e,t,n)=>{setTemplateTextContent(n,t)})),Icons.getIcon(getFormElementDefinition(e,"iconIdentifier"),Icons.sizes.small,null,Icons.states.default,Icons.markupIdentifiers.inline).then((function(e){$(getHelper().getDomElementDataIdentifierSelector("formElementIcon"),t).append($(e).addClass(getHelper().getDomElementClassName("icon")))})),getHelper().getTemplatePropertyDomElement("_type",t).append(document.createTextNode(getFormElementDefinition(e,"label"))),getHelper().getTemplatePropertyDomElement("_identifier",t).append(document.createTextNode(e.get("identifier")))}export function renderSimpleTemplateWithValidators(e,t){assert("object"===$.type(e),'Invalid parameter "formElement"',1479035674),renderSimpleTemplate(e,t);const n=$(getHelper().getDomElementDataIdentifierSelector("validatorsContainer"),$(t)).clone();$(getHelper().getDomElementDataIdentifierSelector("validatorsContainer"),$(t)).empty();const r=e.get("validators");if("array"===$.type(r)){let e=0;if(r.length>0){for(let o=0,l=r.length;o<l;++o){if("NotEmpty"===r[o].identifier){getHelper().getTemplatePropertyDomElement("_required",t).text("*");continue}e++;const l=getFormEditorApp().getFormEditorDefinition("validators",r[o].identifier),i=$($(n).clone());getHelper().getTemplatePropertyDomElement("_label",i).append(document.createTextNode(l.label)),$(getHelper().getDomElementDataIdentifierSelector("validatorsContainer"),$(t)).append(i.html())}e>0&&Icons.getIcon(getHelper().getDomElementDataAttributeValue("iconValidator"),Icons.sizes.small,null,Icons.states.default,Icons.markupIdentifiers.inline).then((function(e){$(getHelper().getDomElementDataIdentifierSelector("validatorIcon"),$(t)).append($(e).addClass(getHelper().getDomElementClassName("icon")))}))}}}export function renderSelectTemplates(e,t){const n=$(getHelper().getDomElementDataIdentifierSelector("multiValueContainer"),$(t)).clone();$(getHelper().getDomElementDataIdentifierSelector("multiValueContainer"),$(t)).empty(),renderSimpleTemplateWithValidators(e,t);const r=$(getHelper().getDomElementDataIdentifierSelector("multiValueContainer"),$(t)).attr(getHelper().getDomElementDataAttribute("templateProperty")),o=e.get(r),l=(e,r,o)=>{let l=!1;const i=$($(n).clone());for(const e of Object.keys(o))if(o[e]===r){l=!0;break}getHelper().getTemplatePropertyDomElement("_label",i).append(document.createTextNode(e)),l&&getHelper().getTemplatePropertyDomElement("_label",i).addClass(getHelper().getDomElementClassName("selected")),$(getHelper().getDomElementDataIdentifierSelector("multiValueContainer"),$(t)).append(i.html())};let i=e.get("defaultValue");if(getFormEditorApp().getUtility().isUndefinedOrNull(i)?i={}:"string"===$.type(i)&&(i={0:i}),"object"===$.type(o))for(const e of Object.keys(o))l(o[e],e,i);else if("array"===$.type(o))for(const e of Object.keys(o))getUtility().isUndefinedOrNull(o[e]._label)?l(o[e],e,i):l(o[e]._label,o[e]._value,i)}export function renderFileUploadTemplates(e,t){const n=$(getHelper().getDomElementDataIdentifierSelector("multiValueContainer"),$(t)).clone();$(getHelper().getDomElementDataIdentifierSelector("multiValueContainer"),$(t)).empty(),renderSimpleTemplateWithValidators(e,t);const r=$(getHelper().getDomElementDataIdentifierSelector("multiValueContainer"),$(t)).attr(getHelper().getDomElementDataAttribute("templateProperty")),o=e.get(r),l=function(e){const r=$($(n).clone());getHelper().getTemplatePropertyDomElement("_value",r).append(e),$(getHelper().getDomElementDataIdentifierSelector("multiValueContainer"),$(t)).append(r.html())};if("object"===$.type(o))for(const e of Object.keys(o))l(o[e]);else if("array"===$.type(o))for(let e=0,t=o.length;e<t;++e)l(o[e])}export function bootstrap(e,t,n){return formEditorApp=e,assert("object"===$.type(t),'Invalid parameter "appendToDomElement"',1478992119),stageDomElement=$(t),configuration=$.extend(!0,defaultConfiguration,n||{}),Helper.bootstrap(formEditorApp),this}
\ No newline at end of file