ssml-builder-js 2.14.0 → 2.16.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/README.md +10 -4
- package/dist/{chunk-UZSCXPC5.mjs → chunk-F2EMU3HM.mjs} +2 -2
- package/dist/{chunk-QFIBPCO4.mjs → chunk-HI74FTKY.mjs} +197 -21
- package/dist/chunk-HI74FTKY.mjs.map +1 -0
- package/dist/{chunk-AQ55MOPU.mjs → chunk-NKLZGITR.mjs} +354 -177
- package/dist/chunk-NKLZGITR.mjs.map +1 -0
- package/dist/core.d.mts +67 -17
- package/dist/core.d.ts +67 -17
- package/dist/core.js +353 -174
- package/dist/core.js.map +1 -1
- package/dist/core.mjs +5 -1
- package/dist/elements.js +70 -20
- package/dist/elements.js.map +1 -1
- package/dist/elements.mjs +2 -2
- package/dist/{index.d-CUXRwSw0.d.mts → index.d-DR5Qz43p.d.mts} +37 -2
- package/dist/{index.d-CUXRwSw0.d.ts → index.d-DR5Qz43p.d.ts} +37 -2
- package/dist/index.d.mts +162 -19
- package/dist/index.d.ts +162 -19
- package/dist/index.js +2060 -1128
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +752 -174
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +11 -2
- package/dist/react.d.ts +11 -2
- package/dist/react.js +147 -32
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +79 -14
- package/dist/react.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-AQ55MOPU.mjs.map +0 -1
- package/dist/chunk-QFIBPCO4.mjs.map +0 -1
- /package/dist/{chunk-UZSCXPC5.mjs.map → chunk-F2EMU3HM.mjs.map} +0 -0
package/dist/react.js
CHANGED
|
@@ -2960,34 +2960,51 @@ function createAzureUrlValidatorRunner(validator, options = {}) {
|
|
|
2960
2960
|
const inFlight = /* @__PURE__ */ new Map();
|
|
2961
2961
|
const waiters = [];
|
|
2962
2962
|
let active = 0;
|
|
2963
|
-
const
|
|
2963
|
+
const configuredSignal = options.signal ?? new AbortController().signal;
|
|
2964
|
+
const acquire = async (signal) => {
|
|
2965
|
+
if (signal.aborted) throw new Error("URL validation was aborted.");
|
|
2964
2966
|
if (active < concurrency) {
|
|
2965
2967
|
active += 1;
|
|
2966
2968
|
return;
|
|
2967
2969
|
}
|
|
2968
|
-
await new Promise((resolve) =>
|
|
2970
|
+
await new Promise((resolve, reject) => {
|
|
2971
|
+
let waiter;
|
|
2972
|
+
const abortHandler = () => {
|
|
2973
|
+
const index = waiters.indexOf(waiter);
|
|
2974
|
+
if (index >= 0) waiters.splice(index, 1);
|
|
2975
|
+
signal.removeEventListener("abort", abortHandler);
|
|
2976
|
+
reject(new Error("URL validation was aborted."));
|
|
2977
|
+
};
|
|
2978
|
+
signal.addEventListener("abort", abortHandler, { once: true });
|
|
2979
|
+
waiter = () => {
|
|
2980
|
+
signal.removeEventListener("abort", abortHandler);
|
|
2981
|
+
resolve();
|
|
2982
|
+
};
|
|
2983
|
+
waiters.push(waiter);
|
|
2984
|
+
});
|
|
2969
2985
|
active += 1;
|
|
2970
2986
|
};
|
|
2971
2987
|
const release = () => {
|
|
2972
2988
|
active -= 1;
|
|
2973
2989
|
waiters.shift()?.();
|
|
2974
2990
|
};
|
|
2975
|
-
const check = async (url, context) => {
|
|
2976
|
-
if (
|
|
2977
|
-
const
|
|
2991
|
+
const check = async (url, context, signal = configuredSignal) => {
|
|
2992
|
+
if (signal.aborted) throw new Error("URL validation was aborted.");
|
|
2993
|
+
const key = `${context.tag}:${context.attribute}:${url}`;
|
|
2994
|
+
const cached = cache.get(key);
|
|
2978
2995
|
if (cached !== void 0) return cached;
|
|
2979
|
-
const existing = inFlight.get(
|
|
2996
|
+
const existing = inFlight.get(key);
|
|
2980
2997
|
if (existing) return existing;
|
|
2981
2998
|
const promise = (async () => {
|
|
2982
|
-
await acquire();
|
|
2999
|
+
await acquire(signal);
|
|
2983
3000
|
try {
|
|
2984
|
-
if (
|
|
2985
|
-
const validation = Promise.resolve(validator(url, context));
|
|
3001
|
+
if (signal.aborted) throw new Error("URL validation was aborted.");
|
|
3002
|
+
const validation = Promise.resolve(validator(url, context, signal));
|
|
2986
3003
|
let timer;
|
|
2987
3004
|
let abortHandler;
|
|
2988
3005
|
const cancellation = new Promise((_resolve, reject) => {
|
|
2989
3006
|
abortHandler = () => reject(new Error("URL validation was aborted."));
|
|
2990
|
-
|
|
3007
|
+
signal.addEventListener("abort", abortHandler, { once: true });
|
|
2991
3008
|
if (options.timeoutMs !== void 0 && options.timeoutMs > 0) {
|
|
2992
3009
|
timer = setTimeout(
|
|
2993
3010
|
() => reject(new Error(`URL validation timed out after ${options.timeoutMs} ms.`)),
|
|
@@ -2997,24 +3014,24 @@ function createAzureUrlValidatorRunner(validator, options = {}) {
|
|
|
2997
3014
|
});
|
|
2998
3015
|
try {
|
|
2999
3016
|
const result = await (timer || abortHandler ? Promise.race([validation, cancellation]) : validation);
|
|
3000
|
-
cache.set(
|
|
3017
|
+
cache.set(key, result);
|
|
3001
3018
|
return result;
|
|
3002
3019
|
} finally {
|
|
3003
3020
|
if (timer) clearTimeout(timer);
|
|
3004
|
-
if (abortHandler)
|
|
3021
|
+
if (abortHandler) signal.removeEventListener("abort", abortHandler);
|
|
3005
3022
|
}
|
|
3006
3023
|
} finally {
|
|
3007
3024
|
release();
|
|
3008
3025
|
}
|
|
3009
3026
|
})();
|
|
3010
|
-
inFlight.set(
|
|
3027
|
+
inFlight.set(key, promise);
|
|
3011
3028
|
try {
|
|
3012
3029
|
return await promise;
|
|
3013
3030
|
} finally {
|
|
3014
|
-
inFlight.delete(
|
|
3031
|
+
inFlight.delete(key);
|
|
3015
3032
|
}
|
|
3016
3033
|
};
|
|
3017
|
-
return (url, context) => check(url, context);
|
|
3034
|
+
return (url, context, signal) => check(url, context, signal ?? configuredSignal);
|
|
3018
3035
|
}
|
|
3019
3036
|
var ALLOWED_BREAK_STRENGTHS = /* @__PURE__ */ new Set(["none", "x-weak", "weak", "medium", "strong", "x-strong"]);
|
|
3020
3037
|
var ALLOWED_SAY_AS = /* @__PURE__ */ new Set([
|
|
@@ -3127,6 +3144,7 @@ function tokenizeElements(source) {
|
|
|
3127
3144
|
if (parent) parent.childElementCount += 1;
|
|
3128
3145
|
const parentVoiceName = [...openElements].reverse().find((element) => element.voiceName)?.voiceName;
|
|
3129
3146
|
const tokenName = nameMatch[1];
|
|
3147
|
+
const path = parent ? [...parent.path, `${tokenName}[${childElementIndex ?? 0}]`] : [tokenName];
|
|
3130
3148
|
const tokenVoiceName = tokenName.toLowerCase() === "voice" ? attributes.get("name") : tokenName.toLowerCase() === "mstts:turn" ? attributes.get("voice") ?? parentVoiceName : parentVoiceName;
|
|
3131
3149
|
tokens.push({
|
|
3132
3150
|
attributes,
|
|
@@ -3137,12 +3155,14 @@ function tokenizeElements(source) {
|
|
|
3137
3155
|
parentName: parent?.name,
|
|
3138
3156
|
parentVoiceName,
|
|
3139
3157
|
selfClosing,
|
|
3140
|
-
start
|
|
3158
|
+
start,
|
|
3159
|
+
path
|
|
3141
3160
|
});
|
|
3142
3161
|
if (!selfClosing) {
|
|
3143
3162
|
openElements.push({
|
|
3144
3163
|
childElementCount: 0,
|
|
3145
3164
|
name: tokenName,
|
|
3165
|
+
path,
|
|
3146
3166
|
voiceName: tokenVoiceName
|
|
3147
3167
|
});
|
|
3148
3168
|
}
|
|
@@ -3155,13 +3175,14 @@ function location(source, offset) {
|
|
|
3155
3175
|
const line = before.split("\n").length;
|
|
3156
3176
|
return { line, column: before.length - (before.lastIndexOf("\n") + 1) + 1 };
|
|
3157
3177
|
}
|
|
3158
|
-
function addDiagnostic(diagnostics, source, offset, message, severity = "error", code2) {
|
|
3178
|
+
function addDiagnostic(diagnostics, source, offset, message, severity = "error", code2, metadata = {}) {
|
|
3159
3179
|
diagnostics.push({
|
|
3160
3180
|
...location(source, offset),
|
|
3161
3181
|
message,
|
|
3162
3182
|
severity,
|
|
3163
3183
|
source: "ssml-static-validator",
|
|
3164
|
-
...code2 ? { code: code2 } : {}
|
|
3184
|
+
...code2 ? { code: code2 } : {},
|
|
3185
|
+
...metadata
|
|
3165
3186
|
});
|
|
3166
3187
|
}
|
|
3167
3188
|
function isSupportedProsodyRate(value) {
|
|
@@ -3624,9 +3645,11 @@ function validateAzureSsmlStatic(ssml, options = {}) {
|
|
|
3624
3645
|
for (const token of tokens) {
|
|
3625
3646
|
const tokenName = token.name.toLowerCase();
|
|
3626
3647
|
const tokenVoiceName = tokenName === "voice" ? attr(token, "name")?.trim() : tokenName === "mstts:turn" ? attr(token, "voice")?.trim() || token.parentVoiceName : options.validateNestedVoices === false ? voiceName : token.parentVoiceName;
|
|
3648
|
+
const tokenDiagnosticStart = diagnostics.length;
|
|
3627
3649
|
validateElement(token, ssml, diagnostics, tokenVoiceName, options, voiceCatalog);
|
|
3628
3650
|
const definition = tokenVoiceName ? voiceCatalog.get(tokenVoiceName.toLowerCase()) : void 0;
|
|
3629
3651
|
validateVoiceFeatureMatrix(token, ssml, diagnostics, tokenVoiceName, definition);
|
|
3652
|
+
annotateTokenDiagnostics(diagnostics, tokenDiagnosticStart, token, options, tokenVoiceName);
|
|
3630
3653
|
if (tokenName === "voice" && options.model && definition?.models && !definition.models.some((model) => model.toLowerCase() === options.model?.toLowerCase())) {
|
|
3631
3654
|
addDiagnostic(
|
|
3632
3655
|
diagnostics,
|
|
@@ -3648,18 +3671,37 @@ function urlAttributes(token) {
|
|
|
3648
3671
|
return value === void 0 ? [] : [{ attribute, value }];
|
|
3649
3672
|
});
|
|
3650
3673
|
}
|
|
3674
|
+
function annotateTokenDiagnostics(diagnostics, startIndex, token, options, voiceName) {
|
|
3675
|
+
const attributes = [...token.attributes.keys()];
|
|
3676
|
+
for (const diagnostic of diagnostics.slice(startIndex)) {
|
|
3677
|
+
const attributeName = attributes.find(
|
|
3678
|
+
(attribute) => new RegExp(`(?:<[^> ]+\\s+|")${attribute}(?:"|>|\\s)`, "i").test(diagnostic.message)
|
|
3679
|
+
);
|
|
3680
|
+
const nodePath = options.sourceNodePath ? [...options.sourceNodePath] : [...token.path];
|
|
3681
|
+
Object.assign(diagnostic, {
|
|
3682
|
+
range: { start: token.start, end: token.end + 1 },
|
|
3683
|
+
tagName: token.name,
|
|
3684
|
+
...attributeName ? { attributeName } : {},
|
|
3685
|
+
...voiceName ? { voiceName } : {},
|
|
3686
|
+
...options.chunkIndex !== void 0 ? { chunkIndex: options.chunkIndex } : {},
|
|
3687
|
+
nodePath,
|
|
3688
|
+
targetNodePath: [...token.path]
|
|
3689
|
+
});
|
|
3690
|
+
}
|
|
3691
|
+
}
|
|
3651
3692
|
function validateAzureSsml(ssml, options = {}) {
|
|
3652
3693
|
const diagnostics = validateAzureSsmlStatic(ssml, options);
|
|
3653
3694
|
const validator = options.urlValidator ?? options.customUrlValidator;
|
|
3654
3695
|
if (!validator || typeof ssml !== "string") return diagnostics;
|
|
3655
3696
|
const runnerOptions = options.urlValidation ?? {};
|
|
3656
|
-
const boundedValidator = createAzureUrlValidatorRunner(validator, {
|
|
3697
|
+
const boundedValidator = options.urlValidatorRunner ?? createAzureUrlValidatorRunner(validator, {
|
|
3657
3698
|
...runnerOptions,
|
|
3658
3699
|
...options.urlValidatorConcurrency !== void 0 ? { concurrency: options.urlValidatorConcurrency } : {},
|
|
3659
3700
|
...options.urlValidatorTimeoutMs !== void 0 ? { timeoutMs: options.urlValidatorTimeoutMs } : {},
|
|
3660
3701
|
...options.urlValidatorSignal ? { signal: options.urlValidatorSignal } : {},
|
|
3661
3702
|
...options.urlValidatorCache ? { cache: options.urlValidatorCache } : {}
|
|
3662
3703
|
});
|
|
3704
|
+
const validationSignal = options.urlValidatorSignal ?? options.urlValidation?.signal ?? new AbortController().signal;
|
|
3663
3705
|
let tokens;
|
|
3664
3706
|
try {
|
|
3665
3707
|
tokens = tokenizeElements(ssml);
|
|
@@ -3669,25 +3711,33 @@ function validateAzureSsml(ssml, options = {}) {
|
|
|
3669
3711
|
const checks = tokens.flatMap(
|
|
3670
3712
|
(token) => urlAttributes(token).map(async ({ attribute, value }) => {
|
|
3671
3713
|
try {
|
|
3672
|
-
const result = await boundedValidator(
|
|
3714
|
+
const result = await boundedValidator(
|
|
3715
|
+
value,
|
|
3716
|
+
{ tag: token.name, attribute, ...options.sourceNodePath ? { sourceNodePath: options.sourceNodePath } : {} },
|
|
3717
|
+
validationSignal
|
|
3718
|
+
);
|
|
3673
3719
|
const valid = typeof result === "boolean" ? result : result.valid;
|
|
3674
3720
|
if (!valid) {
|
|
3675
3721
|
const reason = typeof result === "boolean" ? void 0 : result.reason;
|
|
3722
|
+
const diagnosticStart = diagnostics.length;
|
|
3676
3723
|
addDiagnostic(
|
|
3677
3724
|
diagnostics,
|
|
3678
3725
|
ssml,
|
|
3679
3726
|
token.start,
|
|
3680
3727
|
`<${token.name} ${attribute}> was rejected by the custom URL validator${reason ? `: ${reason}` : "."}`
|
|
3681
3728
|
);
|
|
3729
|
+
annotateTokenDiagnostics(diagnostics, diagnosticStart, token, options, token.parentVoiceName);
|
|
3682
3730
|
}
|
|
3683
3731
|
} catch (error) {
|
|
3684
3732
|
const reason = error instanceof Error ? error.message : String(error);
|
|
3733
|
+
const diagnosticStart = diagnostics.length;
|
|
3685
3734
|
addDiagnostic(
|
|
3686
3735
|
diagnostics,
|
|
3687
3736
|
ssml,
|
|
3688
3737
|
token.start,
|
|
3689
3738
|
`<${token.name} ${attribute}> could not be validated by the custom URL validator: ${reason}`
|
|
3690
3739
|
);
|
|
3740
|
+
annotateTokenDiagnostics(diagnostics, diagnosticStart, token, options, token.parentVoiceName);
|
|
3691
3741
|
}
|
|
3692
3742
|
})
|
|
3693
3743
|
);
|
|
@@ -6841,6 +6891,40 @@ function VoiceCapabilityMatrix({
|
|
|
6841
6891
|
const status = voice.status ?? (voice.preview ? "preview" : void 0);
|
|
6842
6892
|
return /* @__PURE__ */ React.createElement("div", { className: "ssml-editor-voice-capabilities", "data-voice-capabilities": "" }, /* @__PURE__ */ React.createElement("div", null, locale === "ja" ? "\u30B9\u30C6\u30FC\u30BF\u30B9" : "Status", ": ", status?.toUpperCase() ?? (locale === "ja" ? "GA" : "GA"), status === "preview" || status === "deprecated" ? /* @__PURE__ */ React.createElement("span", { role: "status", "aria-label": status, className: "ssml-editor-voice-warning-badge" }, status === "preview" ? "\u26A0 Preview" : "\u26A0 Deprecated") : null), (voice.regions?.length || voice.region) && /* @__PURE__ */ React.createElement("div", null, locale === "ja" ? "\u30EA\u30FC\u30B8\u30E7\u30F3" : "Regions", ":", " ", [...voice.regions ?? [], ...voice.region ? [voice.region] : []].filter((region, index, all) => all.indexOf(region) === index).join(", ")), voice.supportedTags && voice.supportedTags.length > 0 && /* @__PURE__ */ React.createElement("div", null, locale === "ja" ? "\u5BFE\u5FDC\u30BF\u30B0" : "Supported tags", ": ", voice.supportedTags.join(", ")), voice.unsupportedTags && voice.unsupportedTags.length > 0 && /* @__PURE__ */ React.createElement("div", { className: "ssml-editor-voice-unsupported" }, locale === "ja" ? "\u975E\u5BFE\u5FDC\u30BF\u30B0" : "Unsupported tags", ": ", voice.unsupportedTags.join(", ")));
|
|
6843
6893
|
}
|
|
6894
|
+
function diagnosticMatchesElement(diagnostic, element) {
|
|
6895
|
+
const name = elementLabel(element).toLowerCase().replace("expressas", "mstts:express-as");
|
|
6896
|
+
if (diagnostic.code === "azure-unsupported-style") return name === "mstts:express-as" || name === "express-as";
|
|
6897
|
+
if (diagnostic.code === "azure-unsupported-tag-for-voice") {
|
|
6898
|
+
return diagnostic.message.toLowerCase().includes(`<${name}>`) || diagnostic.message.toLowerCase().includes(`<${name.replace("mstts:", "")}>`);
|
|
6899
|
+
}
|
|
6900
|
+
if (diagnostic.code === "azure-locale-mismatch" || diagnostic.code === "azure-unsupported-model-for-voice")
|
|
6901
|
+
return name === "voice" || name === "mstts:turn";
|
|
6902
|
+
return false;
|
|
6903
|
+
}
|
|
6904
|
+
function elementWarnings(diagnostics, element) {
|
|
6905
|
+
return diagnostics.filter((diagnostic) => diagnosticMatchesElement(diagnostic, element));
|
|
6906
|
+
}
|
|
6907
|
+
function fieldWarnings(diagnostics, element, field) {
|
|
6908
|
+
return elementWarnings(diagnostics, element).filter((diagnostic) => {
|
|
6909
|
+
if (diagnostic.code === "azure-unsupported-style") return field.key === "style";
|
|
6910
|
+
return field.key === "name" || field.key === "voice";
|
|
6911
|
+
});
|
|
6912
|
+
}
|
|
6913
|
+
function WarningBadge({ messages }) {
|
|
6914
|
+
if (messages.length === 0) return null;
|
|
6915
|
+
return /* @__PURE__ */ React.createElement(
|
|
6916
|
+
"span",
|
|
6917
|
+
{
|
|
6918
|
+
role: "status",
|
|
6919
|
+
"aria-label": messages.map((message) => message.message).join(" "),
|
|
6920
|
+
title: messages.map((message) => message.message).join(" "),
|
|
6921
|
+
"data-ssml-warning-badge": "",
|
|
6922
|
+
"data-testid": "ssml-editor-warning-badge",
|
|
6923
|
+
className: "ssml-editor-warning-badge"
|
|
6924
|
+
},
|
|
6925
|
+
"\u26A0"
|
|
6926
|
+
);
|
|
6927
|
+
}
|
|
6844
6928
|
function DefaultVoiceSelector({
|
|
6845
6929
|
value,
|
|
6846
6930
|
voices,
|
|
@@ -6873,7 +6957,8 @@ function VisualElementInspector({
|
|
|
6873
6957
|
voiceCatalog,
|
|
6874
6958
|
voiceLocale,
|
|
6875
6959
|
voiceRegion,
|
|
6876
|
-
voiceStyle
|
|
6960
|
+
voiceStyle,
|
|
6961
|
+
diagnostics
|
|
6877
6962
|
}) {
|
|
6878
6963
|
if (customInspector) {
|
|
6879
6964
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, customInspector({ document: document2, element, path, readOnly, onChange: commit, locale }));
|
|
@@ -6884,7 +6969,7 @@ function VisualElementInspector({
|
|
|
6884
6969
|
(voice) => voice.name === (element.type === "voice" ? element.name : void 0)
|
|
6885
6970
|
);
|
|
6886
6971
|
const renderSelector = renderVoiceSelector ?? DefaultVoiceSelector;
|
|
6887
|
-
return /* @__PURE__ */ React.createElement("fieldset", null, /* @__PURE__ */ React.createElement("legend", null, `<${elementLabel(element)}
|
|
6972
|
+
return /* @__PURE__ */ React.createElement("fieldset", null, /* @__PURE__ */ React.createElement("legend", null, `<${elementLabel(element)}>`, " ", /* @__PURE__ */ React.createElement(WarningBadge, { messages: elementWarnings(diagnostics, element) })), fields.length === 0 ? /* @__PURE__ */ React.createElement("p", null, "This element is preserved in the visual tree. Edit its attributes in Code mode.") : fields.map((field) => {
|
|
6888
6973
|
const value = element[field.key];
|
|
6889
6974
|
const inputValue = value === void 0 ? "" : String(value);
|
|
6890
6975
|
const inputId = `ssml-visual-${field.key}`;
|
|
@@ -6921,7 +7006,7 @@ function VisualElementInspector({
|
|
|
6921
7006
|
speakerProfileId: "\u8A71\u8005\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB ID",
|
|
6922
7007
|
url: "\u97F3\u58F0\u5909\u63DB URL",
|
|
6923
7008
|
profile: "\u30D7\u30ED\u30D5\u30A1\u30A4\u30EB"
|
|
6924
|
-
}[field.key] ?? field.label : field.label, field.key === "name" && elementLabel(element) === "voice" && voiceCatalog ? renderSelector({
|
|
7009
|
+
}[field.key] ?? field.label : field.label, /* @__PURE__ */ React.createElement(WarningBadge, { messages: fieldWarnings(diagnostics, element, field) }), field.key === "name" && elementLabel(element) === "voice" && voiceCatalog ? renderSelector({
|
|
6925
7010
|
value: inputValue,
|
|
6926
7011
|
voices: availableVoices,
|
|
6927
7012
|
selectedVoice,
|
|
@@ -6999,19 +7084,21 @@ function TreeNode({
|
|
|
6999
7084
|
node,
|
|
7000
7085
|
path,
|
|
7001
7086
|
selectedPath,
|
|
7002
|
-
onSelect
|
|
7087
|
+
onSelect,
|
|
7088
|
+
getWarnings
|
|
7003
7089
|
}) {
|
|
7004
7090
|
if (!isElement(node)) return null;
|
|
7005
7091
|
const name = elementLabel(node);
|
|
7006
7092
|
const isSelected = selectedPath?.join(".") === path.join(".");
|
|
7007
|
-
return /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement("button", { type: "button", "aria-current": isSelected ? "true" : void 0, onClick: () => onSelect(path) }, `<${name}
|
|
7093
|
+
return /* @__PURE__ */ React.createElement("li", null, /* @__PURE__ */ React.createElement("button", { type: "button", "aria-current": isSelected ? "true" : void 0, onClick: () => onSelect(path) }, `<${name}>`, /* @__PURE__ */ React.createElement(WarningBadge, { messages: getWarnings(node) })), (node.children ?? []).length > 0 && /* @__PURE__ */ React.createElement("ul", null, node.children?.map((child, index) => /* @__PURE__ */ React.createElement(
|
|
7008
7094
|
TreeNode,
|
|
7009
7095
|
{
|
|
7010
7096
|
key: `${path.join(".")}/${isElement(child) ? elementLabel(child) : JSON.stringify(child)}`,
|
|
7011
7097
|
node: child,
|
|
7012
7098
|
path: [...path, index],
|
|
7013
7099
|
selectedPath,
|
|
7014
|
-
onSelect
|
|
7100
|
+
onSelect,
|
|
7101
|
+
getWarnings
|
|
7015
7102
|
}
|
|
7016
7103
|
))));
|
|
7017
7104
|
}
|
|
@@ -7026,7 +7113,9 @@ function VisualSsmlEditor({
|
|
|
7026
7113
|
voiceCatalog,
|
|
7027
7114
|
voiceLocale,
|
|
7028
7115
|
voiceRegion,
|
|
7029
|
-
voiceStyle
|
|
7116
|
+
voiceStyle,
|
|
7117
|
+
voiceModel,
|
|
7118
|
+
model
|
|
7030
7119
|
}) {
|
|
7031
7120
|
const [selectedPath, setSelectedPath] = (0, import_react3.useState)(null);
|
|
7032
7121
|
const [selection, setSelection] = (0, import_react3.useState)({ start: 0, end: 0 });
|
|
@@ -7034,7 +7123,27 @@ function VisualSsmlEditor({
|
|
|
7034
7123
|
const selectedLeaf = textLeaves.find((leaf) => leaf.path.join(".") === selectedPath?.join(".")) ?? textLeaves[0];
|
|
7035
7124
|
const selectedElement = selectedPath ? getNodeAtPath(document2.children ?? [], selectedPath) : void 0;
|
|
7036
7125
|
const selectedCustomInspector = selectedElement && isElement(selectedElement) ? customInspectors?.[elementLabel(selectedElement)] ?? customInspectors?.[selectedElement.type] : void 0;
|
|
7037
|
-
const
|
|
7126
|
+
const validationOptions = (0, import_react3.useMemo)(
|
|
7127
|
+
() => ({
|
|
7128
|
+
model: voiceModel ?? model,
|
|
7129
|
+
customVoiceDefinitions: voiceCatalog?.map((voice) => ({
|
|
7130
|
+
name: voice.name,
|
|
7131
|
+
locale: voice.locale,
|
|
7132
|
+
regions: voice.regions ?? (voice.region ? [voice.region] : void 0),
|
|
7133
|
+
styles: voice.styles,
|
|
7134
|
+
supportedTags: voice.supportedTags,
|
|
7135
|
+
unsupportedTags: voice.unsupportedTags,
|
|
7136
|
+
models: voice.models,
|
|
7137
|
+
status: voice.status ?? (voice.preview ? "preview" : "ga")
|
|
7138
|
+
}))
|
|
7139
|
+
}),
|
|
7140
|
+
[model, voiceCatalog, voiceModel]
|
|
7141
|
+
);
|
|
7142
|
+
const diagnostics = (0, import_react3.useMemo)(
|
|
7143
|
+
() => validateAzureSsml(buildSsml(document2), validationOptions),
|
|
7144
|
+
[document2, validationOptions]
|
|
7145
|
+
);
|
|
7146
|
+
const getWarnings = (element) => elementWarnings(diagnostics, element);
|
|
7038
7147
|
const commit = (nextDocument) => onChange?.(nextDocument);
|
|
7039
7148
|
const applyWrapper = (tag, attributes) => {
|
|
7040
7149
|
if (readOnly || !selectedLeaf) return;
|
|
@@ -7049,7 +7158,8 @@ function VisualSsmlEditor({
|
|
|
7049
7158
|
node,
|
|
7050
7159
|
path: [index],
|
|
7051
7160
|
selectedPath,
|
|
7052
|
-
onSelect: setSelectedPath
|
|
7161
|
+
onSelect: setSelectedPath,
|
|
7162
|
+
getWarnings
|
|
7053
7163
|
}
|
|
7054
7164
|
)))), /* @__PURE__ */ React.createElement("div", { className: "ssml-editor-visual-form" }, selectedCustomInspector && selectedElement && isElement(selectedElement) ? selectedCustomInspector({
|
|
7055
7165
|
document: document2,
|
|
@@ -7066,7 +7176,7 @@ function VisualSsmlEditor({
|
|
|
7066
7176
|
onClick: () => commit(addDialogTurn(document2, selectedPath ?? []))
|
|
7067
7177
|
},
|
|
7068
7178
|
locale === "ja" ? "\u30BF\u30FC\u30F3\u3092\u8FFD\u52A0" : "Add turn"
|
|
7069
|
-
)) : selectedElement && isElement(selectedElement) && selectedElement.type === "mstts:turn" ? /* @__PURE__ */ React.createElement("fieldset", null, /* @__PURE__ */ React.createElement("legend", null, localizedElementLabel(selectedElement, locale)), /* @__PURE__ */ React.createElement("label", { htmlFor: "ssml-visual-turn-voice" }, locale === "ja" ? "\u97F3\u58F0" : "Voice", voiceCatalog ? (renderVoiceSelector ?? DefaultVoiceSelector)({
|
|
7179
|
+
)) : selectedElement && isElement(selectedElement) && selectedElement.type === "mstts:turn" ? /* @__PURE__ */ React.createElement("fieldset", null, /* @__PURE__ */ React.createElement("legend", null, localizedElementLabel(selectedElement, locale)), /* @__PURE__ */ React.createElement("label", { htmlFor: "ssml-visual-turn-voice" }, locale === "ja" ? "\u97F3\u58F0" : "Voice", /* @__PURE__ */ React.createElement(WarningBadge, { messages: elementWarnings(diagnostics, selectedElement) }), voiceCatalog ? (renderVoiceSelector ?? DefaultVoiceSelector)({
|
|
7070
7180
|
value: selectedElement.voice ?? "",
|
|
7071
7181
|
voices: filteredVoices(voiceCatalog, voiceLocale, voiceRegion, voiceStyle),
|
|
7072
7182
|
selectedVoice: voiceCatalog?.find((voice) => voice.name === selectedElement.voice),
|
|
@@ -7143,7 +7253,8 @@ function VisualSsmlEditor({
|
|
|
7143
7253
|
voiceCatalog,
|
|
7144
7254
|
voiceLocale,
|
|
7145
7255
|
voiceRegion,
|
|
7146
|
-
voiceStyle
|
|
7256
|
+
voiceStyle,
|
|
7257
|
+
diagnostics
|
|
7147
7258
|
}
|
|
7148
7259
|
) : selectedLeaf ? /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("label", null, "Text", /* @__PURE__ */ React.createElement(
|
|
7149
7260
|
"textarea",
|
|
@@ -7767,6 +7878,8 @@ var SsmlEditor = (0, import_react4.forwardRef)(function SsmlEditor2({
|
|
|
7767
7878
|
voiceLocale,
|
|
7768
7879
|
voiceRegion,
|
|
7769
7880
|
voiceStyle,
|
|
7881
|
+
voiceModel,
|
|
7882
|
+
model,
|
|
7770
7883
|
emotionStyles,
|
|
7771
7884
|
className,
|
|
7772
7885
|
style,
|
|
@@ -8165,7 +8278,9 @@ var SsmlEditor = (0, import_react4.forwardRef)(function SsmlEditor2({
|
|
|
8165
8278
|
voiceCatalog,
|
|
8166
8279
|
voiceLocale,
|
|
8167
8280
|
voiceRegion,
|
|
8168
|
-
voiceStyle
|
|
8281
|
+
voiceStyle,
|
|
8282
|
+
voiceModel,
|
|
8283
|
+
model
|
|
8169
8284
|
}
|
|
8170
8285
|
)) : /* @__PURE__ */ React.createElement("div", { style: { ...editorStyles.editor, minHeight: editorMinHeight } }, /* @__PURE__ */ React.createElement(
|
|
8171
8286
|
import_react5.default,
|