From f15f26240cd5311fa9d07779f364b6639a501dec Mon Sep 17 00:00:00 2001
From: Yassine Doghri <yassine@doghri.fr>
Date: Wed, 11 Aug 2021 12:15:20 +0000
Subject: [PATCH] feat: add codemirror to display xml editor for custom rss
 field

- replace hardcoded label values for play_episode_button component
---
 app/Entities/Episode.php               |   3 +-
 app/Entities/Podcast.php               |   1 +
 app/Helpers/components_helper.php      |  29 +-
 app/Resources/js/admin.ts              |   1 +
 app/Resources/js/favicon.svg           |  15 -
 app/Resources/js/modules/xml-editor.ts |  68 +++
 app/Views/admin/episode/create.php     |   3 +-
 app/Views/admin/episode/edit.php       |   3 +-
 app/Views/admin/podcast/create.php     |   2 +-
 app/Views/admin/podcast/edit.php       |   2 +-
 package-lock.json                      | 615 ++++++++++++++++++++++++-
 package.json                           |   8 +-
 12 files changed, 726 insertions(+), 24 deletions(-)
 delete mode 100644 app/Resources/js/favicon.svg
 create mode 100644 app/Resources/js/modules/xml-editor.ts

diff --git a/app/Entities/Episode.php b/app/Entities/Episode.php
index cf9ba6ad25..31ae9da291 100644
--- a/app/Entities/Episode.php
+++ b/app/Entities/Episode.php
@@ -585,7 +585,8 @@ class Episode extends Entity
      */
     public function setCustomRssString(?string $customRssString = null): static
     {
-        if ($customRssString === null) {
+        if ($customRssString === '') {
+            $this->attributes['custom_rss'] = null;
             return $this;
         }
 
diff --git a/app/Entities/Podcast.php b/app/Entities/Podcast.php
index da72d6f4e2..e089f9ea8c 100644
--- a/app/Entities/Podcast.php
+++ b/app/Entities/Podcast.php
@@ -487,6 +487,7 @@ class Podcast extends Entity
     public function setCustomRssString(string $customRssString): static
     {
         if ($customRssString === '') {
+            $this->attributes['custom_rss'] = null;
             return $this;
         }
 
diff --git a/app/Helpers/components_helper.php b/app/Helpers/components_helper.php
index fc61c0cada..0391487dca 100644
--- a/app/Helpers/components_helper.php
+++ b/app/Helpers/components_helper.php
@@ -467,8 +467,8 @@ if (! function_exists('play_episode_button')) {
                 podcast="${podcastTitle}"
                 src="${source}"
                 mediaType="${mediaType}"
-                playLabel="Play"
-                playingLabel="Playing"
+                playLabel="${playLabel}"
+                playingLabel="${playingLabel}"
             ></play-episode-button>
         CODE_SAMPLE;
     }
@@ -535,3 +535,28 @@ if (! function_exists('relative_time')) {
 }
 
 // ------------------------------------------------------------------------
+
+if (! function_exists('xml_editor')) {
+    /**
+     * XML Editor field
+     *
+     * @param array<string, mixed> $customData
+     * @param array<string, mixed> $extra
+     */
+    function xml_editor(array $customData = [], string $value = '', array $extra = []): string
+    {
+        $defaultData = [
+            'slot' => 'textarea',
+            'rows' => 5,
+        ];
+        $data = array_merge($defaultData, $customData);
+
+        $textarea = form_textarea($data, $value, $extra);
+
+        return <<<CODE_SAMPLE
+            <xml-editor>${textarea}</time-ago>
+        CODE_SAMPLE;
+    }
+}
+
+// ------------------------------------------------------------------------
diff --git a/app/Resources/js/admin.ts b/app/Resources/js/admin.ts
index ac1ea0704d..60cb0214b3 100644
--- a/app/Resources/js/admin.ts
+++ b/app/Resources/js/admin.ts
@@ -16,6 +16,7 @@ import Soundbites from "./modules/Soundbites";
 import ThemePicker from "./modules/ThemePicker";
 import Time from "./modules/Time";
 import Tooltip from "./modules/Tooltip";
+import "./modules/xml-editor";
 
 Dropdown();
 Tooltip();
diff --git a/app/Resources/js/favicon.svg b/app/Resources/js/favicon.svg
deleted file mode 100644
index de4aeddc12..0000000000
--- a/app/Resources/js/favicon.svg
+++ /dev/null
@@ -1,15 +0,0 @@
-<svg width="410" height="404" viewBox="0 0 410 404" fill="none" xmlns="http://www.w3.org/2000/svg">
-<path d="M399.641 59.5246L215.643 388.545C211.844 395.338 202.084 395.378 198.228 388.618L10.5817 59.5563C6.38087 52.1896 12.6802 43.2665 21.0281 44.7586L205.223 77.6824C206.398 77.8924 207.601 77.8904 208.776 77.6763L389.119 44.8058C397.439 43.2894 403.768 52.1434 399.641 59.5246Z" fill="url(#paint0_linear)"/>
-<path d="M292.965 1.5744L156.801 28.2552C154.563 28.6937 152.906 30.5903 152.771 32.8664L144.395 174.33C144.198 177.662 147.258 180.248 150.51 179.498L188.42 170.749C191.967 169.931 195.172 173.055 194.443 176.622L183.18 231.775C182.422 235.487 185.907 238.661 189.532 237.56L212.947 230.446C216.577 229.344 220.065 232.527 219.297 236.242L201.398 322.875C200.278 328.294 207.486 331.249 210.492 326.603L212.5 323.5L323.454 102.072C325.312 98.3645 322.108 94.137 318.036 94.9228L279.014 102.454C275.347 103.161 272.227 99.746 273.262 96.1583L298.731 7.86689C299.767 4.27314 296.636 0.855181 292.965 1.5744Z" fill="url(#paint1_linear)"/>
-<defs>
-<linearGradient id="paint0_linear" x1="6.00017" y1="32.9999" x2="235" y2="344" gradientUnits="userSpaceOnUse">
-<stop stop-color="#41D1FF"/>
-<stop offset="1" stop-color="#BD34FE"/>
-</linearGradient>
-<linearGradient id="paint1_linear" x1="194.651" y1="8.81818" x2="236.076" y2="292.989" gradientUnits="userSpaceOnUse">
-<stop stop-color="#FFEA83"/>
-<stop offset="0.0833333" stop-color="#FFDD35"/>
-<stop offset="1" stop-color="#FFA800"/>
-</linearGradient>
-</defs>
-</svg>
diff --git a/app/Resources/js/modules/xml-editor.ts b/app/Resources/js/modules/xml-editor.ts
new file mode 100644
index 0000000000..6f521d5b1a
--- /dev/null
+++ b/app/Resources/js/modules/xml-editor.ts
@@ -0,0 +1,68 @@
+import { basicSetup } from "@codemirror/basic-setup";
+import { xml } from "@codemirror/lang-xml";
+import { EditorState } from "@codemirror/state";
+import { EditorView } from "@codemirror/view";
+import { css, html, LitElement, TemplateResult } from "lit";
+import { customElement, queryAssignedNodes, state } from "lit/decorators.js";
+import prettifyXML from "xml-formatter";
+
+@customElement("xml-editor")
+export class XMLEditor extends LitElement {
+  @queryAssignedNodes("textarea", true)
+  _textarea!: NodeListOf<HTMLTextAreaElement>;
+
+  @state()
+  editorState!: EditorState;
+
+  @state()
+  editorView!: EditorView;
+
+  firstUpdated(): void {
+    const minHeightEditor = EditorView.theme({
+      ".cm-content, .cm-gutter": {
+        minHeight: this._textarea[0].clientHeight + "px",
+      },
+    });
+
+    this.editorState = EditorState.create({
+      doc: this._textarea[0].value
+        ? prettifyXML(this._textarea[0].value, {
+            indentation: "  ",
+          })
+        : "",
+      extensions: [basicSetup, xml(), minHeightEditor],
+    });
+
+    this.editorView = new EditorView({
+      state: this.editorState,
+      root: this.shadowRoot as ShadowRoot,
+      parent: this.shadowRoot as ShadowRoot,
+    });
+
+    this._textarea[0].hidden = true;
+    if (this._textarea[0].form) {
+      this._textarea[0].form.addEventListener("submit", () => {
+        this._textarea[0].value = this.editorView.state.doc.toString();
+      });
+    }
+  }
+
+  disconnectedCallback(): void {
+    if (this._textarea[0].form) {
+      this._textarea[0].form.removeEventListener("submit", () => {
+        this._textarea[0].value = this.editorView.state.doc.toString();
+      });
+    }
+  }
+
+  static styles = css`
+    .cm-wrap {
+      border: 1px solid #6b7280;
+      background-color: #ffffff;
+    }
+  `;
+
+  render(): TemplateResult<1> {
+    return html`<slot name="textarea"></slot>`;
+  }
+}
diff --git a/app/Views/admin/episode/create.php b/app/Views/admin/episode/create.php
index 7602c1c89c..738b62272b 100644
--- a/app/Views/admin/episode/create.php
+++ b/app/Views/admin/episode/create.php
@@ -226,6 +226,7 @@
         [
             'id' => 'description_footer',
             'name' => 'description_footer',
+            'rows' => 6
         ],
         old(
             'description_footer',
@@ -401,7 +402,7 @@
     lang('Episode.form.custom_rss_hint'),
     true,
 ) ?>
-<?= form_textarea([
+<?= xml_editor([
     'id' => 'custom_rss',
     'name' => 'custom_rss',
     'class' => 'form-textarea',
diff --git a/app/Views/admin/episode/edit.php b/app/Views/admin/episode/edit.php
index 16bb381e81..1fd1e87d2c 100644
--- a/app/Views/admin/episode/edit.php
+++ b/app/Views/admin/episode/edit.php
@@ -236,6 +236,7 @@
         [
             'id' => 'description_footer',
             'name' => 'description_footer',
+            'rows' => 6
         ],
         old(
             'description_footer',
@@ -474,7 +475,7 @@
     lang('Episode.form.custom_rss_hint'),
     true,
 ) ?>
-<?= form_textarea([
+<?= xml_editor([
     'id' => 'custom_rss',
     'name' => 'custom_rss',
     'class' => 'form-textarea',
diff --git a/app/Views/admin/podcast/create.php b/app/Views/admin/podcast/create.php
index eb63ac93bf..3a5a9b94f8 100644
--- a/app/Views/admin/podcast/create.php
+++ b/app/Views/admin/podcast/create.php
@@ -340,7 +340,7 @@
     lang('Podcast.form.custom_rss_hint'),
     true,
 ) ?>
-<?= form_textarea([
+<?= xml_editor([
     'id' => 'custom_rss',
     'name' => 'custom_rss',
     'class' => 'form-textarea',
diff --git a/app/Views/admin/podcast/edit.php b/app/Views/admin/podcast/edit.php
index a49bdf17b0..a24413ae35 100644
--- a/app/Views/admin/podcast/edit.php
+++ b/app/Views/admin/podcast/edit.php
@@ -335,7 +335,7 @@
     lang('Podcast.form.custom_rss_hint'),
     true,
 ) ?>
-<?= form_textarea([
+<?= xml_editor([
     'id' => 'custom_rss',
     'name' => 'custom_rss',
     'class' => 'form-textarea',
diff --git a/package-lock.json b/package-lock.json
index 4ad9004a73..961f62c253 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,6 +11,11 @@
       "dependencies": {
         "@amcharts/amcharts4": "^4.10.21",
         "@amcharts/amcharts4-geodata": "^4.1.21",
+        "@codemirror/basic-setup": "^0.18.2",
+        "@codemirror/commands": "^0.18.3",
+        "@codemirror/lang-xml": "^0.18.0",
+        "@codemirror/state": "^0.18.7",
+        "@codemirror/view": "^0.18.19",
         "@github/clipboard-copy-element": "^1.1.2",
         "@github/markdown-toolbar-element": "^1.5.1",
         "@github/time-elements": "^3.1.2",
@@ -21,7 +26,8 @@
         "leaflet": "^1.7.1",
         "leaflet.markercluster": "^1.5.1",
         "lit": "^2.0.0-rc.2",
-        "marked": "^2.1.3"
+        "marked": "^2.1.3",
+        "xml-formatter": "^2.4.0"
       },
       "devDependencies": {
         "@commitlint/cli": "^13.1.0",
@@ -488,6 +494,242 @@
       "integrity": "sha512-np/lG3uARFybkoHokJUmf1QfEvRVCPbmQeUQpKow5cQ3xWrV9i3rUHodKDJPQfTVX61qKi+UdYk8kik84n7XOw==",
       "dev": true
     },
+    "node_modules/@codemirror/autocomplete": {
+      "version": "0.18.8",
+      "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-0.18.8.tgz",
+      "integrity": "sha512-Va1Q763Vu/rVmIazru/ZnO2kkWVq6SlmMEjeD0qmxLAypyP6j/QNdpmaPDI1qb/+Mb9VFZBbac6a0aLTTi8qxQ==",
+      "dependencies": {
+        "@codemirror/language": "^0.18.0",
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/text": "^0.18.0",
+        "@codemirror/tooltip": "^0.18.4",
+        "@codemirror/view": "^0.18.0",
+        "lezer-tree": "^0.13.0"
+      }
+    },
+    "node_modules/@codemirror/basic-setup": {
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/basic-setup/-/basic-setup-0.18.2.tgz",
+      "integrity": "sha512-4UNFQ4jhU7wKxJH23AJcZW6Ho54VXUpmbtFnN5amIdtGci4ZLvci4M7JKgKFraHmKfDIYQnSzN8d8ohXR7CRhw==",
+      "dependencies": {
+        "@codemirror/autocomplete": "^0.18.0",
+        "@codemirror/closebrackets": "^0.18.0",
+        "@codemirror/commands": "^0.18.0",
+        "@codemirror/comment": "^0.18.0",
+        "@codemirror/fold": "^0.18.0",
+        "@codemirror/gutter": "^0.18.3",
+        "@codemirror/highlight": "^0.18.0",
+        "@codemirror/history": "^0.18.0",
+        "@codemirror/language": "^0.18.0",
+        "@codemirror/lint": "^0.18.0",
+        "@codemirror/matchbrackets": "^0.18.0",
+        "@codemirror/rectangular-selection": "^0.18.0",
+        "@codemirror/search": "^0.18.0",
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/view": "^0.18.0"
+      }
+    },
+    "node_modules/@codemirror/closebrackets": {
+      "version": "0.18.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/closebrackets/-/closebrackets-0.18.0.tgz",
+      "integrity": "sha512-O1RAgUkzF4nq/B8IyXenZKZ1rJi2Mc7I6y4IhWhELiTnjyQy7YdAthTsJ40mNr8kZ6gRbasYe3K7TraITElZJA==",
+      "dependencies": {
+        "@codemirror/language": "^0.18.0",
+        "@codemirror/rangeset": "^0.18.0",
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/text": "^0.18.0",
+        "@codemirror/view": "^0.18.0"
+      }
+    },
+    "node_modules/@codemirror/commands": {
+      "version": "0.18.3",
+      "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-0.18.3.tgz",
+      "integrity": "sha512-nHYDG13qOirioXTAKmjl10W2L0eZ1ftvmTwvUTNY27UWVBPFSpk5zDXP3WqJ0mgMhQ4AOFLJaTjJEO3hmPComg==",
+      "dependencies": {
+        "@codemirror/language": "^0.18.0",
+        "@codemirror/matchbrackets": "^0.18.0",
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/text": "^0.18.0",
+        "@codemirror/view": "^0.18.0",
+        "lezer-tree": "^0.13.0"
+      }
+    },
+    "node_modules/@codemirror/comment": {
+      "version": "0.18.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/comment/-/comment-0.18.1.tgz",
+      "integrity": "sha512-Inhqs0F24WE28Fcp1dBZghwixBGv1HDwY9MjE0d5tpMY/IPGI6uT30fGyHAXrir6hUqk7eJRkO4UYnODGOnoIA==",
+      "dependencies": {
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/text": "^0.18.0",
+        "@codemirror/view": "^0.18.0"
+      }
+    },
+    "node_modules/@codemirror/fold": {
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/fold/-/fold-0.18.2.tgz",
+      "integrity": "sha512-kkQ+stpUbOAU0ASPP9NW5uLLhe5LVC46m47zJUnWDlsT9rS5NZW6NDiWzrDlN8dWQT8fePzkMA174BG4tr2GJw==",
+      "dependencies": {
+        "@codemirror/gutter": "^0.18.0",
+        "@codemirror/language": "^0.18.0",
+        "@codemirror/rangeset": "^0.18.0",
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/view": "^0.18.0"
+      }
+    },
+    "node_modules/@codemirror/gutter": {
+      "version": "0.18.4",
+      "resolved": "https://registry.npmjs.org/@codemirror/gutter/-/gutter-0.18.4.tgz",
+      "integrity": "sha512-Sf2IWshMi9zwVVqpGmd2NRplY0qfrE2IiBEII9n2gB9M8hgIMg5GCyhdnsUDsOm0gcSut65W62vV7/DfYJHQCA==",
+      "dependencies": {
+        "@codemirror/rangeset": "^0.18.3",
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/view": "^0.18.0"
+      }
+    },
+    "node_modules/@codemirror/highlight": {
+      "version": "0.18.4",
+      "resolved": "https://registry.npmjs.org/@codemirror/highlight/-/highlight-0.18.4.tgz",
+      "integrity": "sha512-3azJntqWrShOIq/0kVcdMc9k7ACL0LQErgK+A6aWXmCj5Mx0gShq+Iajy8AMQ2zB0v3nhCBgFaniL1LLD5m5hQ==",
+      "dependencies": {
+        "@codemirror/language": "^0.18.0",
+        "@codemirror/rangeset": "^0.18.0",
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/view": "^0.18.0",
+        "lezer-tree": "^0.13.0",
+        "style-mod": "^4.0.0"
+      }
+    },
+    "node_modules/@codemirror/history": {
+      "version": "0.18.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/history/-/history-0.18.1.tgz",
+      "integrity": "sha512-Aad3p4zs6UYKCUMXYjh7cvPK0ajuL+rMib9yBZ61w81LLl6OkM31Xrn9J6CLJmPxCwP3OJFiqBmNSBQ05oIsTw==",
+      "dependencies": {
+        "@codemirror/state": "^0.18.3",
+        "@codemirror/view": "^0.18.0"
+      }
+    },
+    "node_modules/@codemirror/lang-xml": {
+      "version": "0.18.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-xml/-/lang-xml-0.18.0.tgz",
+      "integrity": "sha512-zME4OKbi1oXFhCslUW2VxIPTJFUb102ZOxszzlYbqtwuxXZFAhf/273Wy3C2diAcILRySO7Pv1qxTPnoIsJYYg==",
+      "dependencies": {
+        "@codemirror/autocomplete": "^0.18.0",
+        "@codemirror/highlight": "^0.18.0",
+        "@codemirror/language": "^0.18.0",
+        "@codemirror/state": "^0.18.0",
+        "lezer-tree": "^0.13.0",
+        "lezer-xml": "^0.13.0"
+      }
+    },
+    "node_modules/@codemirror/language": {
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-0.18.2.tgz",
+      "integrity": "sha512-2Kz0Xyfvt1Ex2KfTUcYZ3IBxpnFCqHaJijwZknGBT7JXv9dwbOPs9SfPfL4oxVuDIHZx8JTPfoV3LTTJrm8M3Q==",
+      "dependencies": {
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/text": "^0.18.0",
+        "@codemirror/view": "^0.18.0",
+        "lezer": "^0.13.4",
+        "lezer-tree": "^0.13.0"
+      }
+    },
+    "node_modules/@codemirror/lint": {
+      "version": "0.18.6",
+      "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-0.18.6.tgz",
+      "integrity": "sha512-juE05YyDoLp9WCcR0hQagphOCIZ0r4WRocRFu9tbFwsMjfuForjn4m+wsLSDaDgp2Z9secMyOSGDpBNtVwM9lQ==",
+      "dependencies": {
+        "@codemirror/panel": "^0.18.1",
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/tooltip": "^0.18.4",
+        "@codemirror/view": "^0.18.0",
+        "crelt": "^1.0.5"
+      }
+    },
+    "node_modules/@codemirror/matchbrackets": {
+      "version": "0.18.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/matchbrackets/-/matchbrackets-0.18.0.tgz",
+      "integrity": "sha512-dPDopnZVkD54sSYdmQbyQbPdiuIA83p7XxX6Hp1ScEkOjukwCiFXiA/84x10FUTsQpUYp8bDzm7gwII119bGIw==",
+      "dependencies": {
+        "@codemirror/language": "^0.18.0",
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/view": "^0.18.0",
+        "lezer-tree": "^0.13.0"
+      }
+    },
+    "node_modules/@codemirror/panel": {
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/panel/-/panel-0.18.2.tgz",
+      "integrity": "sha512-ea/g2aAKtfmie1kD7C8GDutD/5u+uzRJr/varUiAbHKr1sAdjtz5xYvC3GBAMYMan1GOh0vD5zP1yEupJl3b3Q==",
+      "dependencies": {
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/view": "^0.18.0"
+      }
+    },
+    "node_modules/@codemirror/rangeset": {
+      "version": "0.18.5",
+      "resolved": "https://registry.npmjs.org/@codemirror/rangeset/-/rangeset-0.18.5.tgz",
+      "integrity": "sha512-gvYniNeEbGRp74MM8EQ+0tylK85pVody4r4N5bs94msPwHQSKFkEmosl8tVmS0Z4e8gRtlB37m8/cWoRiuSz5Q==",
+      "dependencies": {
+        "@codemirror/state": "^0.18.0"
+      }
+    },
+    "node_modules/@codemirror/rectangular-selection": {
+      "version": "0.18.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/rectangular-selection/-/rectangular-selection-0.18.1.tgz",
+      "integrity": "sha512-WpdIo6wyxamncvSZQEO1xsZArRnE5/NtNGnuLCjYUkW5JepdYtEJzIE9czaJqxVGrCBs//Lv58CbGX77/1GAoA==",
+      "dependencies": {
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/text": "^0.18.1",
+        "@codemirror/view": "^0.18.18"
+      }
+    },
+    "node_modules/@codemirror/search": {
+      "version": "0.18.4",
+      "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-0.18.4.tgz",
+      "integrity": "sha512-3chVkMPzl+pTUSqtimTicebhti4SLpvkj03pQx2aPZScXxIiYuDk4cLdIJK9omjmO1+oycRKbOrqvG7iZJJwMg==",
+      "dependencies": {
+        "@codemirror/panel": "^0.18.1",
+        "@codemirror/rangeset": "^0.18.0",
+        "@codemirror/state": "^0.18.6",
+        "@codemirror/text": "^0.18.0",
+        "@codemirror/view": "^0.18.0",
+        "crelt": "^1.0.5"
+      }
+    },
+    "node_modules/@codemirror/state": {
+      "version": "0.18.7",
+      "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-0.18.7.tgz",
+      "integrity": "sha512-cVyTiAC9vv90NKmGOfNtBjyIem3BqKui1L5Hfcxurp8K9votQj2oH9COcgWPnQ2Xs64yC70tEuTt9DF1pj5PFQ==",
+      "dependencies": {
+        "@codemirror/text": "^0.18.0"
+      }
+    },
+    "node_modules/@codemirror/text": {
+      "version": "0.18.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/text/-/text-0.18.1.tgz",
+      "integrity": "sha512-vjXs6mi1F418kucTPlFvnCt9glKnjtYssdXb8mm1oaY/F5O+tgGVepm9Z8F7AKWCQvW8Bns1D3uLz/DOIEywIw=="
+    },
+    "node_modules/@codemirror/tooltip": {
+      "version": "0.18.4",
+      "resolved": "https://registry.npmjs.org/@codemirror/tooltip/-/tooltip-0.18.4.tgz",
+      "integrity": "sha512-LDlDOSEfjoG24uapLN7exK3Z3JchYFKUwWqo1x/9YdlAkmD1ik7cMSQZboCquP1uJVcXhtbpKmaO6vENGVaarg==",
+      "dependencies": {
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/view": "^0.18.0"
+      }
+    },
+    "node_modules/@codemirror/view": {
+      "version": "0.18.19",
+      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-0.18.19.tgz",
+      "integrity": "sha512-TmazVl8H3L+aYwlNb8xk6qADRb8KiYOO047pz51R4mGCg4Ja2siSjXktZgUvklsyWbUY7h9q+oAf4piH+mQZTw==",
+      "dependencies": {
+        "@codemirror/rangeset": "^0.18.2",
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/text": "^0.18.1",
+        "style-mod": "^4.0.0",
+        "w3c-keyname": "^2.2.4"
+      }
+    },
     "node_modules/@commitlint/cli": {
       "version": "13.2.1",
       "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-13.2.1.tgz",
@@ -3958,11 +4200,18 @@
         "node": ">=0.8"
       }
     },
+<<<<<<< HEAD
     "node_modules/create-require": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
       "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
       "dev": true
+=======
+    "node_modules/crelt": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.5.tgz",
+      "integrity": "sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA=="
+>>>>>>> 260759b (feat: add codemirror to display xml editor for custom rss field)
     },
     "node_modules/cross-env": {
       "version": "7.0.3",
@@ -8006,6 +8255,30 @@
         "node": ">= 0.8.0"
       }
     },
+    "node_modules/lezer": {
+      "version": "0.13.5",
+      "resolved": "https://registry.npmjs.org/lezer/-/lezer-0.13.5.tgz",
+      "integrity": "sha512-cAiMQZGUo2BD8mpcz7Nv1TlKzWP7YIdIRrX41CiP5bk5t4GHxskOxWUx2iAOuHlz8dO+ivbuXr0J1bfHsWD+lQ==",
+      "deprecated": "This package has been replaced by @lezer/lr",
+      "dependencies": {
+        "lezer-tree": "^0.13.2"
+      }
+    },
+    "node_modules/lezer-tree": {
+      "version": "0.13.2",
+      "resolved": "https://registry.npmjs.org/lezer-tree/-/lezer-tree-0.13.2.tgz",
+      "integrity": "sha512-15ZxW8TxVNAOkHIo43Iouv4zbSkQQ5chQHBpwXcD2bBFz46RB4jYLEEww5l1V0xyIx9U2clSyyrLes+hAUFrGQ==",
+      "deprecated": "This package has been replaced by @lezer/common"
+    },
+    "node_modules/lezer-xml": {
+      "version": "0.13.4",
+      "resolved": "https://registry.npmjs.org/lezer-xml/-/lezer-xml-0.13.4.tgz",
+      "integrity": "sha512-mgA6ZfsxBWTG993vkVRonaHaSY4H78IChFI9+H6PiH8mJEG9OP2W1EiZmGbiv32OawF02vWzvTp3Lm3b9P1g9A==",
+      "deprecated": "This package has been replaced by @lezer/xml",
+      "dependencies": {
+        "lezer": "^0.13.3"
+      }
+    },
     "node_modules/lilconfig": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.3.tgz",
@@ -17501,6 +17774,11 @@
         "node": ">=8"
       }
     },
+    "node_modules/style-mod": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.0.tgz",
+      "integrity": "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw=="
+    },
     "node_modules/style-search": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz",
@@ -18964,6 +19242,11 @@
         "browser-process-hrtime": "^1.0.0"
       }
     },
+    "node_modules/w3c-keyname": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.4.tgz",
+      "integrity": "sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw=="
+    },
     "node_modules/w3c-xmlserializer": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz",
@@ -19230,11 +19513,30 @@
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz",
       "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg=="
     },
+    "node_modules/xml-formatter": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-2.4.1.tgz",
+      "integrity": "sha512-UFnFRNum4BxicU9U4DPhIlHAQqHtT/vTdCvC6fiD78xlpug8YLgawW3MHmT1+eCAM7YomvMGZziiMz9AnExZgQ==",
+      "dependencies": {
+        "xml-parser-xo": "^3.1.2"
+      },
+      "engines": {
+        "node": ">= 10"
+      }
+    },
     "node_modules/xml-name-validator": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
       "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw=="
     },
+    "node_modules/xml-parser-xo": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/xml-parser-xo/-/xml-parser-xo-3.1.2.tgz",
+      "integrity": "sha512-Qyttmiy305unyg1ONpArT4FPDL3J+ohXWpMI1ecopClGMw53lCRHJ4FV/fVYHFU6qfEzMV0frqSlNaLo2dw15Q==",
+      "engines": {
+        "node": ">= 10"
+      }
+    },
     "node_modules/xmlchars": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
@@ -19801,6 +20103,242 @@
         }
       }
     },
+    "@codemirror/autocomplete": {
+      "version": "0.18.8",
+      "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-0.18.8.tgz",
+      "integrity": "sha512-Va1Q763Vu/rVmIazru/ZnO2kkWVq6SlmMEjeD0qmxLAypyP6j/QNdpmaPDI1qb/+Mb9VFZBbac6a0aLTTi8qxQ==",
+      "requires": {
+        "@codemirror/language": "^0.18.0",
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/text": "^0.18.0",
+        "@codemirror/tooltip": "^0.18.4",
+        "@codemirror/view": "^0.18.0",
+        "lezer-tree": "^0.13.0"
+      }
+    },
+    "@codemirror/basic-setup": {
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/basic-setup/-/basic-setup-0.18.2.tgz",
+      "integrity": "sha512-4UNFQ4jhU7wKxJH23AJcZW6Ho54VXUpmbtFnN5amIdtGci4ZLvci4M7JKgKFraHmKfDIYQnSzN8d8ohXR7CRhw==",
+      "requires": {
+        "@codemirror/autocomplete": "^0.18.0",
+        "@codemirror/closebrackets": "^0.18.0",
+        "@codemirror/commands": "^0.18.0",
+        "@codemirror/comment": "^0.18.0",
+        "@codemirror/fold": "^0.18.0",
+        "@codemirror/gutter": "^0.18.3",
+        "@codemirror/highlight": "^0.18.0",
+        "@codemirror/history": "^0.18.0",
+        "@codemirror/language": "^0.18.0",
+        "@codemirror/lint": "^0.18.0",
+        "@codemirror/matchbrackets": "^0.18.0",
+        "@codemirror/rectangular-selection": "^0.18.0",
+        "@codemirror/search": "^0.18.0",
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/view": "^0.18.0"
+      }
+    },
+    "@codemirror/closebrackets": {
+      "version": "0.18.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/closebrackets/-/closebrackets-0.18.0.tgz",
+      "integrity": "sha512-O1RAgUkzF4nq/B8IyXenZKZ1rJi2Mc7I6y4IhWhELiTnjyQy7YdAthTsJ40mNr8kZ6gRbasYe3K7TraITElZJA==",
+      "requires": {
+        "@codemirror/language": "^0.18.0",
+        "@codemirror/rangeset": "^0.18.0",
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/text": "^0.18.0",
+        "@codemirror/view": "^0.18.0"
+      }
+    },
+    "@codemirror/commands": {
+      "version": "0.18.3",
+      "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-0.18.3.tgz",
+      "integrity": "sha512-nHYDG13qOirioXTAKmjl10W2L0eZ1ftvmTwvUTNY27UWVBPFSpk5zDXP3WqJ0mgMhQ4AOFLJaTjJEO3hmPComg==",
+      "requires": {
+        "@codemirror/language": "^0.18.0",
+        "@codemirror/matchbrackets": "^0.18.0",
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/text": "^0.18.0",
+        "@codemirror/view": "^0.18.0",
+        "lezer-tree": "^0.13.0"
+      }
+    },
+    "@codemirror/comment": {
+      "version": "0.18.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/comment/-/comment-0.18.1.tgz",
+      "integrity": "sha512-Inhqs0F24WE28Fcp1dBZghwixBGv1HDwY9MjE0d5tpMY/IPGI6uT30fGyHAXrir6hUqk7eJRkO4UYnODGOnoIA==",
+      "requires": {
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/text": "^0.18.0",
+        "@codemirror/view": "^0.18.0"
+      }
+    },
+    "@codemirror/fold": {
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/fold/-/fold-0.18.2.tgz",
+      "integrity": "sha512-kkQ+stpUbOAU0ASPP9NW5uLLhe5LVC46m47zJUnWDlsT9rS5NZW6NDiWzrDlN8dWQT8fePzkMA174BG4tr2GJw==",
+      "requires": {
+        "@codemirror/gutter": "^0.18.0",
+        "@codemirror/language": "^0.18.0",
+        "@codemirror/rangeset": "^0.18.0",
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/view": "^0.18.0"
+      }
+    },
+    "@codemirror/gutter": {
+      "version": "0.18.4",
+      "resolved": "https://registry.npmjs.org/@codemirror/gutter/-/gutter-0.18.4.tgz",
+      "integrity": "sha512-Sf2IWshMi9zwVVqpGmd2NRplY0qfrE2IiBEII9n2gB9M8hgIMg5GCyhdnsUDsOm0gcSut65W62vV7/DfYJHQCA==",
+      "requires": {
+        "@codemirror/rangeset": "^0.18.3",
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/view": "^0.18.0"
+      }
+    },
+    "@codemirror/highlight": {
+      "version": "0.18.4",
+      "resolved": "https://registry.npmjs.org/@codemirror/highlight/-/highlight-0.18.4.tgz",
+      "integrity": "sha512-3azJntqWrShOIq/0kVcdMc9k7ACL0LQErgK+A6aWXmCj5Mx0gShq+Iajy8AMQ2zB0v3nhCBgFaniL1LLD5m5hQ==",
+      "requires": {
+        "@codemirror/language": "^0.18.0",
+        "@codemirror/rangeset": "^0.18.0",
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/view": "^0.18.0",
+        "lezer-tree": "^0.13.0",
+        "style-mod": "^4.0.0"
+      }
+    },
+    "@codemirror/history": {
+      "version": "0.18.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/history/-/history-0.18.1.tgz",
+      "integrity": "sha512-Aad3p4zs6UYKCUMXYjh7cvPK0ajuL+rMib9yBZ61w81LLl6OkM31Xrn9J6CLJmPxCwP3OJFiqBmNSBQ05oIsTw==",
+      "requires": {
+        "@codemirror/state": "^0.18.3",
+        "@codemirror/view": "^0.18.0"
+      }
+    },
+    "@codemirror/lang-xml": {
+      "version": "0.18.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/lang-xml/-/lang-xml-0.18.0.tgz",
+      "integrity": "sha512-zME4OKbi1oXFhCslUW2VxIPTJFUb102ZOxszzlYbqtwuxXZFAhf/273Wy3C2diAcILRySO7Pv1qxTPnoIsJYYg==",
+      "requires": {
+        "@codemirror/autocomplete": "^0.18.0",
+        "@codemirror/highlight": "^0.18.0",
+        "@codemirror/language": "^0.18.0",
+        "@codemirror/state": "^0.18.0",
+        "lezer-tree": "^0.13.0",
+        "lezer-xml": "^0.13.0"
+      }
+    },
+    "@codemirror/language": {
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-0.18.2.tgz",
+      "integrity": "sha512-2Kz0Xyfvt1Ex2KfTUcYZ3IBxpnFCqHaJijwZknGBT7JXv9dwbOPs9SfPfL4oxVuDIHZx8JTPfoV3LTTJrm8M3Q==",
+      "requires": {
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/text": "^0.18.0",
+        "@codemirror/view": "^0.18.0",
+        "lezer": "^0.13.4",
+        "lezer-tree": "^0.13.0"
+      }
+    },
+    "@codemirror/lint": {
+      "version": "0.18.6",
+      "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-0.18.6.tgz",
+      "integrity": "sha512-juE05YyDoLp9WCcR0hQagphOCIZ0r4WRocRFu9tbFwsMjfuForjn4m+wsLSDaDgp2Z9secMyOSGDpBNtVwM9lQ==",
+      "requires": {
+        "@codemirror/panel": "^0.18.1",
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/tooltip": "^0.18.4",
+        "@codemirror/view": "^0.18.0",
+        "crelt": "^1.0.5"
+      }
+    },
+    "@codemirror/matchbrackets": {
+      "version": "0.18.0",
+      "resolved": "https://registry.npmjs.org/@codemirror/matchbrackets/-/matchbrackets-0.18.0.tgz",
+      "integrity": "sha512-dPDopnZVkD54sSYdmQbyQbPdiuIA83p7XxX6Hp1ScEkOjukwCiFXiA/84x10FUTsQpUYp8bDzm7gwII119bGIw==",
+      "requires": {
+        "@codemirror/language": "^0.18.0",
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/view": "^0.18.0",
+        "lezer-tree": "^0.13.0"
+      }
+    },
+    "@codemirror/panel": {
+      "version": "0.18.2",
+      "resolved": "https://registry.npmjs.org/@codemirror/panel/-/panel-0.18.2.tgz",
+      "integrity": "sha512-ea/g2aAKtfmie1kD7C8GDutD/5u+uzRJr/varUiAbHKr1sAdjtz5xYvC3GBAMYMan1GOh0vD5zP1yEupJl3b3Q==",
+      "requires": {
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/view": "^0.18.0"
+      }
+    },
+    "@codemirror/rangeset": {
+      "version": "0.18.5",
+      "resolved": "https://registry.npmjs.org/@codemirror/rangeset/-/rangeset-0.18.5.tgz",
+      "integrity": "sha512-gvYniNeEbGRp74MM8EQ+0tylK85pVody4r4N5bs94msPwHQSKFkEmosl8tVmS0Z4e8gRtlB37m8/cWoRiuSz5Q==",
+      "requires": {
+        "@codemirror/state": "^0.18.0"
+      }
+    },
+    "@codemirror/rectangular-selection": {
+      "version": "0.18.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/rectangular-selection/-/rectangular-selection-0.18.1.tgz",
+      "integrity": "sha512-WpdIo6wyxamncvSZQEO1xsZArRnE5/NtNGnuLCjYUkW5JepdYtEJzIE9czaJqxVGrCBs//Lv58CbGX77/1GAoA==",
+      "requires": {
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/text": "^0.18.1",
+        "@codemirror/view": "^0.18.18"
+      }
+    },
+    "@codemirror/search": {
+      "version": "0.18.4",
+      "resolved": "https://registry.npmjs.org/@codemirror/search/-/search-0.18.4.tgz",
+      "integrity": "sha512-3chVkMPzl+pTUSqtimTicebhti4SLpvkj03pQx2aPZScXxIiYuDk4cLdIJK9omjmO1+oycRKbOrqvG7iZJJwMg==",
+      "requires": {
+        "@codemirror/panel": "^0.18.1",
+        "@codemirror/rangeset": "^0.18.0",
+        "@codemirror/state": "^0.18.6",
+        "@codemirror/text": "^0.18.0",
+        "@codemirror/view": "^0.18.0",
+        "crelt": "^1.0.5"
+      }
+    },
+    "@codemirror/state": {
+      "version": "0.18.7",
+      "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-0.18.7.tgz",
+      "integrity": "sha512-cVyTiAC9vv90NKmGOfNtBjyIem3BqKui1L5Hfcxurp8K9votQj2oH9COcgWPnQ2Xs64yC70tEuTt9DF1pj5PFQ==",
+      "requires": {
+        "@codemirror/text": "^0.18.0"
+      }
+    },
+    "@codemirror/text": {
+      "version": "0.18.1",
+      "resolved": "https://registry.npmjs.org/@codemirror/text/-/text-0.18.1.tgz",
+      "integrity": "sha512-vjXs6mi1F418kucTPlFvnCt9glKnjtYssdXb8mm1oaY/F5O+tgGVepm9Z8F7AKWCQvW8Bns1D3uLz/DOIEywIw=="
+    },
+    "@codemirror/tooltip": {
+      "version": "0.18.4",
+      "resolved": "https://registry.npmjs.org/@codemirror/tooltip/-/tooltip-0.18.4.tgz",
+      "integrity": "sha512-LDlDOSEfjoG24uapLN7exK3Z3JchYFKUwWqo1x/9YdlAkmD1ik7cMSQZboCquP1uJVcXhtbpKmaO6vENGVaarg==",
+      "requires": {
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/view": "^0.18.0"
+      }
+    },
+    "@codemirror/view": {
+      "version": "0.18.19",
+      "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-0.18.19.tgz",
+      "integrity": "sha512-TmazVl8H3L+aYwlNb8xk6qADRb8KiYOO047pz51R4mGCg4Ja2siSjXktZgUvklsyWbUY7h9q+oAf4piH+mQZTw==",
+      "requires": {
+        "@codemirror/rangeset": "^0.18.2",
+        "@codemirror/state": "^0.18.0",
+        "@codemirror/text": "^0.18.1",
+        "style-mod": "^4.0.0",
+        "w3c-keyname": "^2.2.4"
+      }
+    },
     "@commitlint/cli": {
       "version": "13.2.1",
       "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-13.2.1.tgz",
@@ -22545,12 +23083,43 @@
         "printj": "~1.1.0"
       }
     },
+<<<<<<< HEAD
+=======
+<<<<<<< HEAD
+<<<<<<< HEAD
+>>>>>>> 260759b (feat: add codemirror to display xml editor for custom rss field)
     "create-require": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz",
       "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==",
       "dev": true
     },
+<<<<<<< HEAD
+=======
+<<<<<<< HEAD
+    "crelt": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.4.tgz",
+      "integrity": "sha512-l1cwMUOssGLEj5zgbut4lxJq95ZabOXVZnDybNqQRUtXh1lvUK7e7kJNm8SfvTQzYpE3AVJhIVUJKf382lMA7A=="
+    },
+<<<<<<< HEAD
+    "@types/cacheable-request": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz",
+      "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==",
+=======
+=======
+>>>>>>> 87ca2cf (fix(md-editor): build new markdown editor with lit + github/markdown-toolbar-element)
+=======
+>>>>>>> 4e51bf2 (fix(persons): set person picture as optional for better ux)
+=======
+    "crelt": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.5.tgz",
+      "integrity": "sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA=="
+    },
+>>>>>>> e2aaf4f (feat: add codemirror to display xml editor for custom rss field)
+>>>>>>> 260759b (feat: add codemirror to display xml editor for custom rss field)
     "cross-env": {
       "version": "7.0.3",
       "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz",
@@ -25670,6 +26239,27 @@
         "type-check": "~0.4.0"
       }
     },
+    "lezer": {
+      "version": "0.13.5",
+      "resolved": "https://registry.npmjs.org/lezer/-/lezer-0.13.5.tgz",
+      "integrity": "sha512-cAiMQZGUo2BD8mpcz7Nv1TlKzWP7YIdIRrX41CiP5bk5t4GHxskOxWUx2iAOuHlz8dO+ivbuXr0J1bfHsWD+lQ==",
+      "requires": {
+        "lezer-tree": "^0.13.2"
+      }
+    },
+    "lezer-tree": {
+      "version": "0.13.2",
+      "resolved": "https://registry.npmjs.org/lezer-tree/-/lezer-tree-0.13.2.tgz",
+      "integrity": "sha512-15ZxW8TxVNAOkHIo43Iouv4zbSkQQ5chQHBpwXcD2bBFz46RB4jYLEEww5l1V0xyIx9U2clSyyrLes+hAUFrGQ=="
+    },
+    "lezer-xml": {
+      "version": "0.13.4",
+      "resolved": "https://registry.npmjs.org/lezer-xml/-/lezer-xml-0.13.4.tgz",
+      "integrity": "sha512-mgA6ZfsxBWTG993vkVRonaHaSY4H78IChFI9+H6PiH8mJEG9OP2W1EiZmGbiv32OawF02vWzvTp3Lm3b9P1g9A==",
+      "requires": {
+        "lezer": "^0.13.3"
+      }
+    },
     "lilconfig": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.3.tgz",
@@ -34861,6 +35451,11 @@
       "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
       "dev": true
     },
+    "style-mod": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.0.tgz",
+      "integrity": "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw=="
+    },
     "style-search": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz",
@@ -36026,6 +36621,11 @@
         "browser-process-hrtime": "^1.0.0"
       }
     },
+    "w3c-keyname": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.4.tgz",
+      "integrity": "sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw=="
+    },
     "w3c-xmlserializer": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz",
@@ -36228,11 +36828,24 @@
         }
       }
     },
+    "xml-formatter": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/xml-formatter/-/xml-formatter-2.4.1.tgz",
+      "integrity": "sha512-UFnFRNum4BxicU9U4DPhIlHAQqHtT/vTdCvC6fiD78xlpug8YLgawW3MHmT1+eCAM7YomvMGZziiMz9AnExZgQ==",
+      "requires": {
+        "xml-parser-xo": "^3.1.2"
+      }
+    },
     "xml-name-validator": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
       "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw=="
     },
+    "xml-parser-xo": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/xml-parser-xo/-/xml-parser-xo-3.1.2.tgz",
+      "integrity": "sha512-Qyttmiy305unyg1ONpArT4FPDL3J+ohXWpMI1ecopClGMw53lCRHJ4FV/fVYHFU6qfEzMV0frqSlNaLo2dw15Q=="
+    },
     "xmlchars": {
       "version": "2.2.0",
       "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
diff --git a/package.json b/package.json
index b69dcc708c..fa95bf3835 100644
--- a/package.json
+++ b/package.json
@@ -29,6 +29,11 @@
   "dependencies": {
     "@amcharts/amcharts4-geodata": "^4.1.21",
     "@amcharts/amcharts4": "^4.10.21",
+    "@codemirror/basic-setup": "^0.18.2",
+    "@codemirror/commands": "^0.18.3",
+    "@codemirror/lang-xml": "^0.18.0",
+    "@codemirror/state": "^0.18.7",
+    "@codemirror/view": "^0.18.19",
     "@github/clipboard-copy-element": "^1.1.2",
     "@github/markdown-toolbar-element": "^1.5.1",
     "@github/time-elements": "^3.1.2",
@@ -39,7 +44,8 @@
     "leaflet.markercluster": "^1.5.1",
     "leaflet": "^1.7.1",
     "lit": "^2.0.0-rc.2",
-    "marked": "^2.1.3"
+    "marked": "^2.1.3",
+    "xml-formatter": "^2.4.0"
   },
   "devDependencies": {
     "@commitlint/cli": "^13.1.0",
-- 
GitLab