@ssml-builder-js/ssml-editor-react 2.8.1 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -36,6 +36,7 @@ __export(index_exports, {
36
36
  SSML_HOVER_COPY: () => SSML_HOVER_COPY,
37
37
  SSML_INSERTIONS: () => SSML_INSERTIONS,
38
38
  SsmlEditor: () => SsmlEditor,
39
+ VisualSsmlEditor: () => VisualSsmlEditor,
39
40
  createSsmlEditorInsertionDefinition: () => createSsmlEditorInsertionDefinition,
40
41
  registerSsmlCodeLens: () => registerSsmlCodeLens,
41
42
  updateTagAttribute: () => updateTagAttribute
@@ -43,8 +44,8 @@ __export(index_exports, {
43
44
  module.exports = __toCommonJS(index_exports);
44
45
 
45
46
  // src/SsmlEditor.tsx
46
- var import_react3 = require("react");
47
- var import_react4 = __toESM(require("@monaco-editor/react"));
47
+ var import_react4 = require("react");
48
+ var import_react5 = __toESM(require("@monaco-editor/react"));
48
49
 
49
50
  // src/buttonVisibility.ts
50
51
  function isSsmlEditorButtonVisible(buttonVisibility, button) {
@@ -473,6 +474,11 @@ var SSML_ATTRIBUTE_PRESETS = {
473
474
  "mstts:audioduration": {
474
475
  value: AUDIO_DURATION_PRESETS
475
476
  },
477
+ "mstts:backgroundaudio": {
478
+ volume: PROSODY_VOLUME_PRESETS,
479
+ fadein: AUDIO_DURATION_PRESETS,
480
+ fadeout: AUDIO_DURATION_PRESETS
481
+ },
476
482
  silence: {
477
483
  type: SILENCE_TYPE_PRESETS,
478
484
  value: SILENCE_VALUE_PRESETS
@@ -1289,6 +1295,14 @@ var editorStyles = {
1289
1295
  display: "grid",
1290
1296
  gap: "0.5rem"
1291
1297
  },
1298
+ visual: {
1299
+ display: "grid",
1300
+ gap: "0.75rem",
1301
+ minHeight: "8rem",
1302
+ padding: "0.75rem",
1303
+ border: "1px solid var(--ssml-editor-control-border)",
1304
+ borderRadius: "0.25rem"
1305
+ },
1292
1306
  toolbarIconOnly: {
1293
1307
  justifyContent: "center",
1294
1308
  minWidth: "2.25rem",
@@ -3300,6 +3314,24 @@ var SSML_COMPLETION_SNIPPETS = [
3300
3314
  label: "mstts:audioduration",
3301
3315
  insertText: '<mstts:audioduration value="10s" />'
3302
3316
  },
3317
+ {
3318
+ label: "mstts:dialog",
3319
+ insertText: `<mstts:dialog>
3320
+ <mstts:turn voice="\${1:en-US-JennyNeural}">\${2:text}</mstts:turn>
3321
+ </mstts:dialog>`
3322
+ },
3323
+ {
3324
+ label: "mstts:turn",
3325
+ insertText: `<mstts:turn voice="\${1:en-US-JennyNeural}">\${2:text}</mstts:turn>`
3326
+ },
3327
+ {
3328
+ label: "mstts:backgroundaudio",
3329
+ insertText: `<mstts:backgroundaudio src="\${1:https://example.com/audio.mp3}" volume="\${2:-3dB}" />`
3330
+ },
3331
+ {
3332
+ label: "mstts:ttsembedding",
3333
+ insertText: `<mstts:ttsembedding>\${1:text}</mstts:ttsembedding>`
3334
+ },
3303
3335
  {
3304
3336
  label: "sub",
3305
3337
  insertText: `<sub alias="\${1:\u8AAD\u307F}">\${2:\u6F22\u5B57}</sub>`
@@ -3967,6 +3999,63 @@ var SSML_TAG_DEFINITIONS = [
3967
3999
  example: "10s"
3968
4000
  }
3969
4001
  ]
4002
+ },
4003
+ {
4004
+ name: "mstts:dialog",
4005
+ description: "Groups multiple Azure dialog turns that can use different voices.",
4006
+ parameters: []
4007
+ },
4008
+ {
4009
+ name: "mstts:turn",
4010
+ description: "Adds one dialog turn using the required Azure voice name.",
4011
+ parameters: [
4012
+ {
4013
+ name: "voice",
4014
+ description: "The Azure voice used for this turn, such as `en-US-JennyNeural`.",
4015
+ example: "en-US-JennyNeural"
4016
+ }
4017
+ ]
4018
+ },
4019
+ {
4020
+ name: "mstts:backgroundaudio",
4021
+ description: "Plays background audio while speech is synthesized.",
4022
+ parameters: [
4023
+ {
4024
+ name: "src",
4025
+ description: "An absolute HTTP(S) URL for the background audio file.",
4026
+ example: "https://example.com/music.mp3"
4027
+ },
4028
+ {
4029
+ name: "volume",
4030
+ description: "The background audio volume, for example `-3dB` or `medium`.",
4031
+ example: "-3dB"
4032
+ },
4033
+ {
4034
+ name: "fadein",
4035
+ description: "The fade-in duration, for example `1s`.",
4036
+ example: "1s"
4037
+ },
4038
+ {
4039
+ name: "fadeout",
4040
+ description: "The fade-out duration, for example `500ms`.",
4041
+ example: "500ms"
4042
+ }
4043
+ ]
4044
+ },
4045
+ {
4046
+ name: "mstts:ttsembedding",
4047
+ description: "Embeds custom voice or speaker profile metadata for Azure Speech.",
4048
+ parameters: []
4049
+ },
4050
+ {
4051
+ name: "mstts:embedding",
4052
+ description: "Specifies embedding metadata for custom voice scenarios.",
4053
+ parameters: []
4054
+ },
4055
+ {
4056
+ name: "mstts:voiceconversion",
4057
+ description: "Specifies voice conversion metadata for custom voice scenarios.",
4058
+ parameters: []
3970
4059
  }
3971
4060
  ];
3972
4061
  var definitionsByName = /* @__PURE__ */ new Map();
@@ -4571,8 +4660,180 @@ function useSsmlMonaco({
4571
4660
  return { editorRef, onMount };
4572
4661
  }
4573
4662
 
4574
- // src/SsmlEditor.tsx
4663
+ // src/components/VisualSsmlEditor.tsx
4664
+ var import_react3 = require("react");
4665
+ var import_ssml_core4 = require("@ssml-builder-js/ssml-core");
4575
4666
  var import_jsx_runtime6 = require("react/jsx-runtime");
4667
+ function isElement(node) {
4668
+ return typeof node !== "string" && node.type !== "text";
4669
+ }
4670
+ function elementLabel(element) {
4671
+ return element.type === "custom" || element.type === "element" ? element.name : element.type;
4672
+ }
4673
+ function collectTextLeaves(nodes, path = [], ancestors = []) {
4674
+ return nodes.flatMap((node, index) => {
4675
+ const currentPath = [...path, index];
4676
+ if (typeof node === "string") return [{ ancestors, path: currentPath, value: node }];
4677
+ if (node.type === "text") return [{ ancestors, path: currentPath, value: node.value }];
4678
+ return collectTextLeaves(node.children ?? [], currentPath, [...ancestors, elementLabel(node)]);
4679
+ });
4680
+ }
4681
+ function updateNodesAtPath(nodes, path, update) {
4682
+ if (path.length === 0) return nodes;
4683
+ const [index, ...rest] = path;
4684
+ return nodes.flatMap((node, nodeIndex) => {
4685
+ if (nodeIndex !== index) return [node];
4686
+ if (rest.length === 0) {
4687
+ const next = update(node);
4688
+ return Array.isArray(next) ? next : [next];
4689
+ }
4690
+ if (!isElement(node)) return [node];
4691
+ return [{ ...node, children: updateNodesAtPath(node.children ?? [], rest, update) }];
4692
+ });
4693
+ }
4694
+ function updateTextAtPath(document2, path, value) {
4695
+ return { ...document2, children: updateNodesAtPath(document2.children ?? [], path, () => value) };
4696
+ }
4697
+ function wrapTextAtPath(document2, path, start, end, tag, attributes) {
4698
+ return {
4699
+ ...document2,
4700
+ children: updateNodesAtPath(document2.children ?? [], path, (node) => {
4701
+ const value = typeof node === "string" ? node : node.type === "text" ? node.value : "";
4702
+ if (!value || start === end) return node;
4703
+ if (tag === "break") {
4704
+ return [
4705
+ value.slice(0, start),
4706
+ { type: tag, attributes, children: [] },
4707
+ value.slice(start)
4708
+ ].filter((part) => typeof part === "string" ? part.length > 0 : true);
4709
+ }
4710
+ const selected = value.slice(start, end);
4711
+ const wrapped = { type: tag, attributes, children: [selected] };
4712
+ return [value.slice(0, start), wrapped, value.slice(end)].filter(
4713
+ (part) => typeof part === "string" ? part.length > 0 : true
4714
+ );
4715
+ })
4716
+ };
4717
+ }
4718
+ function TreeNode({
4719
+ node,
4720
+ path,
4721
+ selectedPath,
4722
+ onSelect
4723
+ }) {
4724
+ if (!isElement(node)) return null;
4725
+ const name = elementLabel(node);
4726
+ const isSelected = selectedPath?.join(".") === path.join(".");
4727
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("li", { children: [
4728
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", "aria-current": isSelected ? "true" : void 0, onClick: () => onSelect(path), children: `<${name}>` }),
4729
+ (node.children ?? []).length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ul", { children: node.children?.map((child, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4730
+ TreeNode,
4731
+ {
4732
+ node: child,
4733
+ path: [...path, index],
4734
+ selectedPath,
4735
+ onSelect
4736
+ },
4737
+ `${path.join(".")}/${isElement(child) ? elementLabel(child) : JSON.stringify(child)}`
4738
+ )) })
4739
+ ] });
4740
+ }
4741
+ function VisualSsmlEditor({
4742
+ document: document2,
4743
+ readOnly = false,
4744
+ onChange,
4745
+ onPreviewSelection
4746
+ }) {
4747
+ const [selectedPath, setSelectedPath] = (0, import_react3.useState)(null);
4748
+ const [selection, setSelection] = (0, import_react3.useState)({ start: 0, end: 0 });
4749
+ const textLeaves = (0, import_react3.useMemo)(() => collectTextLeaves(document2.children ?? []), [document2]);
4750
+ const selectedLeaf = textLeaves.find((leaf) => leaf.path.join(".") === selectedPath?.join(".")) ?? textLeaves[0];
4751
+ const diagnostics = (0, import_react3.useMemo)(() => (0, import_ssml_core4.validateAzureSsml)((0, import_ssml_core4.buildSsml)(document2)), [document2]);
4752
+ const commit = (nextDocument) => onChange?.(nextDocument);
4753
+ const applyWrapper = (tag, attributes) => {
4754
+ if (readOnly || !selectedLeaf) return;
4755
+ const start = selection.start === selection.end ? 0 : selection.start;
4756
+ const end = selection.start === selection.end ? selectedLeaf.value.length : selection.end;
4757
+ commit(wrapTextAtPath(document2, selectedLeaf.path, start, end, tag, attributes));
4758
+ };
4759
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ssml-editor-visual", "data-ssml-editor-visual": "", children: [
4760
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("fieldset", { className: "ssml-editor-visual-breadcrumb", children: [
4761
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("legend", { children: "SSML structure breadcrumb" }),
4762
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: "<speak>" }),
4763
+ selectedLeaf?.ancestors.map((ancestor, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { children: [
4764
+ " / <",
4765
+ ancestor,
4766
+ ">"
4767
+ ] }, selectedLeaf?.ancestors.slice(0, index + 1).join("/"))),
4768
+ selectedPath && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", onClick: () => setSelectedPath(null), children: "Clear parent" })
4769
+ ] }),
4770
+ diagnostics.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { role: "alert", "aria-invalid": "true", className: "ssml-editor-visual-errors", children: diagnostics.map((diagnostic) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { children: diagnostic.message }, `${diagnostic.code}-${diagnostic.message}`)) }),
4771
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "ssml-editor-visual-layout", children: [
4772
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("nav", { "aria-label": "SSML structure tree", className: "ssml-editor-visual-tree", children: [
4773
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: "Structure" }),
4774
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ul", { children: document2.children?.map((node, index) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4775
+ TreeNode,
4776
+ {
4777
+ node,
4778
+ path: [index],
4779
+ selectedPath,
4780
+ onSelect: setSelectedPath
4781
+ },
4782
+ isElement(node) ? elementLabel(node) : JSON.stringify(node)
4783
+ )) })
4784
+ ] }),
4785
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "ssml-editor-visual-form", children: selectedLeaf ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
4786
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("label", { children: [
4787
+ "Text",
4788
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4789
+ "textarea",
4790
+ {
4791
+ value: selectedLeaf.value,
4792
+ readOnly,
4793
+ onSelect: (event) => setSelection({ start: event.currentTarget.selectionStart, end: event.currentTarget.selectionEnd }),
4794
+ onChange: (event) => commit(updateTextAtPath(document2, selectedLeaf.path, event.target.value))
4795
+ }
4796
+ )
4797
+ ] }),
4798
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("fieldset", { className: "ssml-editor-visual-actions", children: [
4799
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("legend", { children: "Apply SSML formatting" }),
4800
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", disabled: readOnly, onClick: () => applyWrapper("prosody", { rate: "slow" }), children: "Rate" }),
4801
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", disabled: readOnly, onClick: () => applyWrapper("prosody", { pitch: "high" }), children: "Pitch" }),
4802
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4803
+ "button",
4804
+ {
4805
+ type: "button",
4806
+ disabled: readOnly,
4807
+ onClick: () => applyWrapper("mstts:express-as", { style: "cheerful" }),
4808
+ children: "Emotion"
4809
+ }
4810
+ ),
4811
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("button", { type: "button", disabled: readOnly, onClick: () => applyWrapper("break", { time: "500ms" }), children: "Pause" }),
4812
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4813
+ "button",
4814
+ {
4815
+ type: "button",
4816
+ disabled: readOnly,
4817
+ onClick: () => applyWrapper("phoneme", { alphabet: "ipa", ph: selectedLeaf.value }),
4818
+ children: "Pronunciation"
4819
+ }
4820
+ ),
4821
+ onPreviewSelection && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
4822
+ "button",
4823
+ {
4824
+ type: "button",
4825
+ onClick: () => onPreviewSelection((0, import_ssml_core4.buildSsml)({ ...document2, children: [selectedLeaf.value] })),
4826
+ children: "Preview selection"
4827
+ }
4828
+ )
4829
+ ] })
4830
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { children: "Select an element or text node to edit it." }) })
4831
+ ] })
4832
+ ] });
4833
+ }
4834
+
4835
+ // src/SsmlEditor.tsx
4836
+ var import_jsx_runtime7 = require("react/jsx-runtime");
4576
4837
  var UNGROUPED_TOOLBAR_GROUP = "__ssml-editor-ungrouped__";
4577
4838
  var TIMING_POPOVER_TAGS = /* @__PURE__ */ new Set(["break", "mstts:silence", "mstts:audioduration"]);
4578
4839
  var PROSODY_POPOVER_TAGS = /* @__PURE__ */ new Set(["prosody", "mstts:express-as", "voice", "emphasis"]);
@@ -5038,6 +5299,60 @@ var STYLE_CSS = `
5038
5299
  > .ssml-editor-help-settings-summary::before {
5039
5300
  content: "\u25BE";
5040
5301
  }
5302
+ [data-ssml-editor] .ssml-editor-visual-layout {
5303
+ display: grid;
5304
+ grid-template-columns: minmax(12rem, 0.35fr) minmax(16rem, 1fr);
5305
+ gap: 1rem;
5306
+ }
5307
+ [data-ssml-editor] .ssml-editor-visual-tree,
5308
+ [data-ssml-editor] .ssml-editor-visual-form {
5309
+ display: grid;
5310
+ gap: 0.5rem;
5311
+ align-content: start;
5312
+ }
5313
+ [data-ssml-editor] .ssml-editor-visual-tree ul {
5314
+ margin: 0;
5315
+ padding-left: 1.25rem;
5316
+ }
5317
+ [data-ssml-editor] .ssml-editor-visual-tree button,
5318
+ [data-ssml-editor] .ssml-editor-visual-breadcrumb button,
5319
+ [data-ssml-editor] .ssml-editor-visual-actions button {
5320
+ padding: 0.35rem 0.5rem;
5321
+ border: 1px solid var(--ssml-editor-control-border);
5322
+ border-radius: 0.25rem;
5323
+ color: var(--ssml-editor-color);
5324
+ background: var(--ssml-editor-control-bg);
5325
+ cursor: pointer;
5326
+ }
5327
+ [data-ssml-editor] .ssml-editor-visual-tree button[aria-current] {
5328
+ border-color: var(--ssml-editor-active-border);
5329
+ background: var(--ssml-editor-active-bg);
5330
+ }
5331
+ [data-ssml-editor] .ssml-editor-visual-breadcrumb,
5332
+ [data-ssml-editor] .ssml-editor-visual-actions {
5333
+ display: flex;
5334
+ flex-wrap: wrap;
5335
+ gap: 0.4rem;
5336
+ align-items: center;
5337
+ }
5338
+ [data-ssml-editor] .ssml-editor-visual-form textarea {
5339
+ box-sizing: border-box;
5340
+ width: 100%;
5341
+ min-height: 6rem;
5342
+ padding: 0.5rem;
5343
+ color: var(--ssml-editor-color);
5344
+ background: var(--ssml-editor-control-bg);
5345
+ border: 1px solid var(--ssml-editor-control-border);
5346
+ border-radius: 0.25rem;
5347
+ font: inherit;
5348
+ }
5349
+ [data-ssml-editor] .ssml-editor-visual-errors {
5350
+ padding: 0.5rem;
5351
+ color: var(--ssml-editor-error);
5352
+ background: var(--ssml-editor-error-bg);
5353
+ border: 1px solid var(--ssml-editor-error);
5354
+ border-radius: 0.25rem;
5355
+ }
5041
5356
  `.trim();
5042
5357
  function injectEditorTheme() {
5043
5358
  if (typeof document !== "undefined" && !document.getElementById(STYLE_ID)) {
@@ -5054,10 +5369,10 @@ function ToolbarDecorationsSwitch({
5054
5369
  decorationsVisible,
5055
5370
  onVisibilityChange
5056
5371
  }) {
5057
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: editorStyles.toolbarSwitch, children: [
5058
- showToolbarIcons && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "\u2606" }),
5059
- showToolbarText && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: copy.decorations }),
5060
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
5372
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: editorStyles.toolbarSwitch, children: [
5373
+ showToolbarIcons && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "\u2606" }),
5374
+ showToolbarText && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: copy.decorations }),
5375
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5061
5376
  "button",
5062
5377
  {
5063
5378
  type: "button",
@@ -5068,12 +5383,12 @@ function ToolbarDecorationsSwitch({
5068
5383
  "aria-label": copy.decorations,
5069
5384
  title: decorationsVisible ? copy.decorationsHideTitle : copy.decorationsShowTitle,
5070
5385
  onClick: () => onVisibilityChange(!decorationsVisible),
5071
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "ssml-editor-switch-thumb", style: editorStyles.toolbarSwitchThumb, "aria-hidden": "true" })
5386
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "ssml-editor-switch-thumb", style: editorStyles.toolbarSwitchThumb, "aria-hidden": "true" })
5072
5387
  }
5073
5388
  )
5074
5389
  ] });
5075
5390
  }
5076
- var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5391
+ var SsmlEditor = (0, import_react4.forwardRef)(function SsmlEditor2({
5077
5392
  document: document2,
5078
5393
  onChange,
5079
5394
  onSsmlChange,
@@ -5111,8 +5426,11 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5111
5426
  toolbarStyle,
5112
5427
  displayClassName,
5113
5428
  displayStyle,
5114
- loadingFallback
5429
+ loadingFallback,
5430
+ editMode: editModeProp = "code"
5115
5431
  }, ref) {
5432
+ const [editMode, setEditMode] = (0, import_react4.useState)(editModeProp);
5433
+ (0, import_react4.useEffect)(() => setEditMode(editModeProp), [editModeProp]);
5116
5434
  const resolvedEditorOptions = {
5117
5435
  ...settings,
5118
5436
  ...editorOptions,
@@ -5190,6 +5508,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5190
5508
  );
5191
5509
  const {
5192
5510
  editorRef,
5511
+ draftDocument,
5193
5512
  text,
5194
5513
  selectionOverlay,
5195
5514
  activeTags,
@@ -5201,6 +5520,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5201
5520
  syntaxError,
5202
5521
  setSyntaxError,
5203
5522
  helpPanelId,
5523
+ commit,
5204
5524
  handleTextChange,
5205
5525
  handleInsert,
5206
5526
  handleInsertBreak,
@@ -5248,7 +5568,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5248
5568
  enableCodeLens,
5249
5569
  onOpenPopover: handleCodeLensAction
5250
5570
  });
5251
- (0, import_react3.useImperativeHandle)(
5571
+ (0, import_react4.useImperativeHandle)(
5252
5572
  ref,
5253
5573
  () => ({
5254
5574
  getSelectedSsml: getSelectedSsml2,
@@ -5278,15 +5598,15 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5278
5598
  onApply: isTimingPopover ? handleInsertBreak : isProsodyPopover ? handleInsertProsody : isTextPopover ? handleInsertText : handleInsert
5279
5599
  };
5280
5600
  if (isTimingPopover) {
5281
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(TimingPopovers, { ...props, insertions: [insertion] });
5601
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TimingPopovers, { ...props, insertions: [insertion] });
5282
5602
  }
5283
5603
  if (isProsodyPopover) {
5284
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ProsodyPopovers, { ...props, insertions: [insertion], voiceName: popoverVoiceName });
5604
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(ProsodyPopovers, { ...props, insertions: [insertion], voiceName: popoverVoiceName });
5285
5605
  }
5286
5606
  if (isTextPopover) {
5287
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(TextPopovers, { ...props, insertions: [insertion] });
5607
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(TextPopovers, { ...props, insertions: [insertion] });
5288
5608
  }
5289
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
5609
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5290
5610
  InsertionPopover,
5291
5611
  {
5292
5612
  ...props,
@@ -5299,7 +5619,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5299
5619
  const toolbarItemRenderers = /* @__PURE__ */ new Map([
5300
5620
  [
5301
5621
  "undo",
5302
- () => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
5622
+ () => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5303
5623
  "button",
5304
5624
  {
5305
5625
  type: "button",
@@ -5313,8 +5633,8 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5313
5633
  }
5314
5634
  },
5315
5635
  children: [
5316
- showToolbarIcons && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "\u21A9" }),
5317
- showToolbarText && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: copy.undo })
5636
+ showToolbarIcons && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "\u21A9" }),
5637
+ showToolbarText && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: copy.undo })
5318
5638
  ]
5319
5639
  },
5320
5640
  "undo"
@@ -5322,7 +5642,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5322
5642
  ],
5323
5643
  [
5324
5644
  "redo",
5325
- () => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
5645
+ () => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5326
5646
  "button",
5327
5647
  {
5328
5648
  type: "button",
@@ -5336,8 +5656,8 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5336
5656
  }
5337
5657
  },
5338
5658
  children: [
5339
- showToolbarIcons && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "\u21AA" }),
5340
- showToolbarText && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: copy.redo })
5659
+ showToolbarIcons && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "\u21AA" }),
5660
+ showToolbarText && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: copy.redo })
5341
5661
  ]
5342
5662
  },
5343
5663
  "redo"
@@ -5345,7 +5665,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5345
5665
  ],
5346
5666
  [
5347
5667
  "clearAll",
5348
- () => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
5668
+ () => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5349
5669
  "button",
5350
5670
  {
5351
5671
  type: "button",
@@ -5359,8 +5679,8 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5359
5679
  }
5360
5680
  },
5361
5681
  children: [
5362
- showToolbarIcons && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "\xD7" }),
5363
- showToolbarText && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: copy.clearAll })
5682
+ showToolbarIcons && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "\xD7" }),
5683
+ showToolbarText && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: copy.clearAll })
5364
5684
  ]
5365
5685
  },
5366
5686
  "clearAll"
@@ -5368,7 +5688,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5368
5688
  ],
5369
5689
  [
5370
5690
  "format",
5371
- () => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
5691
+ () => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5372
5692
  "button",
5373
5693
  {
5374
5694
  type: "button",
@@ -5382,8 +5702,8 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5382
5702
  }
5383
5703
  },
5384
5704
  children: [
5385
- showToolbarIcons && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "\u2261" }),
5386
- showToolbarText && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: copy.format })
5705
+ showToolbarIcons && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "\u2261" }),
5706
+ showToolbarText && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: copy.format })
5387
5707
  ]
5388
5708
  },
5389
5709
  "format"
@@ -5391,7 +5711,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5391
5711
  ],
5392
5712
  [
5393
5713
  "decorations",
5394
- () => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
5714
+ () => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5395
5715
  ToolbarDecorationsSwitch,
5396
5716
  {
5397
5717
  copy,
@@ -5405,7 +5725,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5405
5725
  ],
5406
5726
  [
5407
5727
  "help",
5408
- () => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
5728
+ () => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5409
5729
  "button",
5410
5730
  {
5411
5731
  type: "button",
@@ -5416,8 +5736,8 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5416
5736
  "aria-controls": helpPanelId,
5417
5737
  onClick: () => setIsHelpOpen((open) => !open),
5418
5738
  children: [
5419
- showToolbarIcons && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "?" }),
5420
- showToolbarText && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { children: copy.help })
5739
+ showToolbarIcons && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.toolbarIcon, "aria-hidden": "true", children: "?" }),
5740
+ showToolbarText && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { children: copy.help })
5421
5741
  ]
5422
5742
  },
5423
5743
  "help"
@@ -5441,15 +5761,15 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5441
5761
  previousRenderedGroupId = groupId;
5442
5762
  hasRenderedToolbarItem = true;
5443
5763
  renderedItems.push(
5444
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react3.Fragment, { children: [
5445
- showSeparator && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: editorStyles.toolbarSeparator, "aria-hidden": "true" }),
5764
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react4.Fragment, { children: [
5765
+ showSeparator && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.toolbarSeparator, "aria-hidden": "true" }),
5446
5766
  render()
5447
5767
  ] }, id)
5448
5768
  );
5449
5769
  }
5450
5770
  return renderedItems;
5451
5771
  };
5452
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
5772
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5453
5773
  "section",
5454
5774
  {
5455
5775
  className,
@@ -5458,62 +5778,93 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5458
5778
  "data-ssml-editor": "",
5459
5779
  "data-theme": isDarkTheme ? "dark" : "light",
5460
5780
  children: [
5461
- showToolbar && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
5781
+ showToolbar && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5462
5782
  "div",
5463
5783
  {
5464
5784
  className: toolbarClassName,
5465
5785
  style: { ...editorStyles.toolbarContainer, ...toolbarStyle },
5466
5786
  "data-ssml-editor-toolbar": "",
5467
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
5787
+ children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5468
5788
  "div",
5469
5789
  {
5470
5790
  style: editorStyles.toolbarActions,
5471
5791
  role: "toolbar",
5472
5792
  "aria-label": copy.toolbarAriaLabel,
5473
5793
  "data-ssml-editor-toolbar-actions": "",
5474
- children: renderToolbarItems()
5794
+ children: [
5795
+ renderToolbarItems(),
5796
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.toolbarSeparator, "aria-hidden": "true" }),
5797
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5798
+ "button",
5799
+ {
5800
+ type: "button",
5801
+ style: editMode === "visual" ? { ...toolbarButtonStyle, ...editorStyles.toolbarButtonActive } : toolbarButtonStyle,
5802
+ "aria-pressed": editMode === "visual",
5803
+ onClick: () => setEditMode("visual"),
5804
+ children: "Visual"
5805
+ }
5806
+ ),
5807
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5808
+ "button",
5809
+ {
5810
+ type: "button",
5811
+ style: editMode === "code" ? { ...toolbarButtonStyle, ...editorStyles.toolbarButtonActive } : toolbarButtonStyle,
5812
+ "aria-pressed": editMode === "code",
5813
+ onClick: () => setEditMode("code"),
5814
+ children: "Code"
5815
+ }
5816
+ )
5817
+ ]
5475
5818
  }
5476
5819
  )
5477
5820
  }
5478
5821
  ),
5479
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: displayClassName, style: { ...editorStyles.display, ...displayStyle }, "data-ssml-editor-display": "", children: [
5480
- isHelpOpen && isSsmlEditorButtonVisible(buttonVisibility, "help") && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("section", { id: helpPanelId, style: editorStyles.helpPanel, "aria-label": copy.helpHeading, children: [
5481
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("h3", { style: editorStyles.helpHeading, children: copy.helpHeading }),
5482
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { style: editorStyles.helpDescription, children: copy.helpDescription }),
5483
- helpInsertions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ul", { style: editorStyles.helpList, children: helpInsertions.map((insertion) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("li", { style: editorStyles.helpItem, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("details", { className: "ssml-editor-help-settings-accordion", style: editorStyles.helpSettingsAccordion, children: [
5484
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("summary", { className: "ssml-editor-help-settings-summary", style: editorStyles.helpSettingsSummary, children: [
5485
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: editorStyles.helpIcon, "aria-hidden": "true", children: insertion.icon }),
5486
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { style: editorStyles.helpSettingsSummaryContent, children: [
5487
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: insertion.labels[language] }),
5822
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: displayClassName, style: { ...editorStyles.display, ...displayStyle }, "data-ssml-editor-display": "", children: [
5823
+ isHelpOpen && isSsmlEditorButtonVisible(buttonVisibility, "help") && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("section", { id: helpPanelId, style: editorStyles.helpPanel, "aria-label": copy.helpHeading, children: [
5824
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("h3", { style: editorStyles.helpHeading, children: copy.helpHeading }),
5825
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { style: editorStyles.helpDescription, children: copy.helpDescription }),
5826
+ helpInsertions.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("ul", { style: editorStyles.helpList, children: helpInsertions.map((insertion) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("li", { style: editorStyles.helpItem, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("details", { className: "ssml-editor-help-settings-accordion", style: editorStyles.helpSettingsAccordion, children: [
5827
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("summary", { className: "ssml-editor-help-settings-summary", style: editorStyles.helpSettingsSummary, children: [
5828
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.helpIcon, "aria-hidden": "true", children: insertion.icon }),
5829
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { style: editorStyles.helpSettingsSummaryContent, children: [
5830
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: insertion.labels[language] }),
5488
5831
  " ",
5489
- insertion.tagName && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
5490
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("code", { children: `<${insertion.tagName}${insertion.selfClosing ? "/>" : ">"}` }),
5832
+ insertion.tagName && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
5833
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("code", { children: `<${insertion.tagName}${insertion.selfClosing ? "/>" : ">"}` }),
5491
5834
  " \u2014",
5492
5835
  " "
5493
5836
  ] }),
5494
5837
  insertion.descriptions[language]
5495
5838
  ] })
5496
5839
  ] }),
5497
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { style: editorStyles.helpSettingsDescription, children: [
5498
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("strong", { children: [
5840
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { style: editorStyles.helpSettingsDescription, children: [
5841
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("strong", { children: [
5499
5842
  copy.parameters,
5500
5843
  ":"
5501
5844
  ] }),
5502
5845
  " ",
5503
5846
  insertion.parameterDescription[language]
5504
5847
  ] }),
5505
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("ul", { style: editorStyles.helpSettingsList, children: insertion.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("li", { children: [
5506
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("strong", { children: option.labels[language] }),
5507
- option.descriptions && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_jsx_runtime6.Fragment, { children: [
5848
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("ul", { style: editorStyles.helpSettingsList, children: insertion.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("li", { children: [
5849
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("strong", { children: option.labels[language] }),
5850
+ option.descriptions && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
5508
5851
  " \u2014 ",
5509
5852
  option.descriptions[language]
5510
5853
  ] })
5511
5854
  ] }, option.value)) })
5512
5855
  ] }) }, insertion.id)) })
5513
5856
  ] }),
5514
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { style: { ...editorStyles.editor, minHeight: editorMinHeight }, children: [
5515
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
5516
- import_react4.default,
5857
+ editMode === "visual" ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { style: editorStyles.visual, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5858
+ VisualSsmlEditor,
5859
+ {
5860
+ document: draftDocument,
5861
+ readOnly: isReadOnly,
5862
+ onChange: commit,
5863
+ onPreviewSelection
5864
+ }
5865
+ ) }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { style: { ...editorStyles.editor, minHeight: editorMinHeight }, children: [
5866
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
5867
+ import_react5.default,
5517
5868
  {
5518
5869
  height: editorHeight,
5519
5870
  language: "xml",
@@ -5537,7 +5888,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5537
5888
  onChange: (value) => handleTextChange(value ?? "")
5538
5889
  }
5539
5890
  ),
5540
- selectionOverlay.hasSelection && selectionOverlay.position && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
5891
+ selectionOverlay.hasSelection && selectionOverlay.position && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5541
5892
  "div",
5542
5893
  {
5543
5894
  role: "toolbar",
@@ -5551,12 +5902,12 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5551
5902
  },
5552
5903
  onMouseDown: (event) => event.preventDefault(),
5553
5904
  children: [
5554
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { style: editorStyles.selectionCount, "aria-live": "polite", children: [
5905
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { style: editorStyles.selectionCount, "aria-live": "polite", children: [
5555
5906
  selectionOverlay.characterCount,
5556
5907
  copy.selectionCountSuffix
5557
5908
  ] }),
5558
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: editorStyles.selectionActionsDivider, "aria-hidden": "true" }),
5559
- /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
5909
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.selectionActionsDivider, "aria-hidden": "true" }),
5910
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
5560
5911
  "button",
5561
5912
  {
5562
5913
  type: "button",
@@ -5565,7 +5916,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5565
5916
  disabled: !canPreviewSelection,
5566
5917
  onClick: previewSelection,
5567
5918
  children: [
5568
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { style: editorStyles.selectionActionIcon, "aria-hidden": "true", children: "\u25B6" }),
5919
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { style: editorStyles.selectionActionIcon, "aria-hidden": "true", children: "\u25B6" }),
5569
5920
  copy.previewSelection
5570
5921
  ]
5571
5922
  }
@@ -5574,7 +5925,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5574
5925
  }
5575
5926
  )
5576
5927
  ] }),
5577
- syntaxError && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { style: editorStyles.error, role: "alert", children: [
5928
+ syntaxError && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("p", { style: editorStyles.error, role: "alert", children: [
5578
5929
  copy.syntaxError,
5579
5930
  ": ",
5580
5931
  syntaxError.message
@@ -5591,6 +5942,7 @@ var SsmlEditor = (0, import_react3.forwardRef)(function SsmlEditor2({
5591
5942
  SSML_HOVER_COPY,
5592
5943
  SSML_INSERTIONS,
5593
5944
  SsmlEditor,
5945
+ VisualSsmlEditor,
5594
5946
  createSsmlEditorInsertionDefinition,
5595
5947
  registerSsmlCodeLens,
5596
5948
  updateTagAttribute