@magic-translate/js 1.1.0 → 1.2.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 CHANGED
@@ -148,6 +148,15 @@ formality:
148
148
  <t data-lang="fr" data-formality="formal">How are you?</t>
149
149
  ```
150
150
 
151
+ `data-t-id` lets you edit one use of a text on its own in the webapp, e.g. to
152
+ translate the same "Save" differently on two buttons. Its edited translation
153
+ stays when the text changes. Ids are unique within your account and at most 128
154
+ characters. They apply to the element's content, not to its `data-t-attrs`.
155
+
156
+ ```html
157
+ <t data-t-id="checkout-save">Save</t>
158
+ ```
159
+
151
160
  ### Switching languages
152
161
 
153
162
  Call `setLanguage` to translate the page to another language:
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@magic-translate/core");var t=`t, mt-translate, [data-t]`,n=`[data-t-attrs]`;function r(e){let n=e;for(let e=n.parentElement?.closest(t);e;e=n.parentElement?.closest(t))n=e;return n}function i(e){let t={},n=e.getAttribute(`data-lang`),r=e.getAttribute(`data-formality`);return n&&(t.lang=n),r&&(t.formality=r),t}function a(t){let n=t.getAttribute(`data-v`);if(n!==null){try{let e=JSON.parse(n);if(e&&typeof e==`object`&&!Array.isArray(e))return e}catch{}return console.warn(`[${e.libraryName}]: data-v must be a JSON object, such as data-v='{"name": "Bob"}', but is ${n}`),null}}function o(t,n){if(n.length===0)return t;let r=document.createElement(`template`);return r.innerHTML=t,(0,e.fillElement)(r.content,n),r.innerHTML}var s=class{constructor(t){if(this.options=t,this.contents=new Map,this.attributes=new Map,this.listeners=new Set,!t.apiKey)throw Error(`Missing API key. Please get one at ${e.libraryWebsite}`);this.currentLanguage=t.language??(0,e.utsLocaleToLanguage)(typeof navigator>`u`?void 0:navigator.language),this.dataLoader=this.createDataLoader(),typeof document<`u`&&(this.root=t.root??document.documentElement,this.start(this.root))}get language(){return this.currentLanguage}setLanguage(e){e!==this.currentLanguage&&(this.currentLanguage=e,this.dataLoader=this.createDataLoader(),this.forget(e=>!e.isConnected||!this.root?.contains(e)),this.contents.forEach((e,t)=>this.translateContent(t,!0)),this.attributes.forEach((e,t)=>this.translateAttributes(t,!0)),this.listeners.forEach(t=>t(e)))}onLanguageChange(e){return this.listeners.add(e),()=>this.listeners.delete(e)}translate(t,{v:n,...r}={}){if(!n)return this.dataLoader.load({text:t,...r});let{template:i,values:a,unused:o}=(0,e.toTemplate)(t,n);return(0,e.warnAboutUnused)(o),this.dataLoader.load({text:i,...r}).then(t=>(0,e.fillPlaceholders)(t,a))}destroy(){this.observer?.disconnect(),this.contents.clear(),this.attributes.clear(),this.listeners.clear()}createDataLoader(){let{debug:t,apiKey:n,sourceLanguage:r,_apiUrl:i,formality:a}=this.options,o=this.options._loaderFactory??e.defaultLoaderFactory;return new e.DataLoader(o({debug:!!t,apiKey:n,lang:this.currentLanguage,sourceLang:r,apiUrl:i,formality:a}),{cacheKeyFn:(0,e.cacheKeyFn)(n,r,this.currentLanguage)})}start(e){let t=new Set,n=new Set;this.collect(e,t,n),t.forEach(e=>this.translateContent(e)),n.forEach(e=>this.translateAttributes(e)),this.observer=new MutationObserver(e=>this.handleMutations(e)),this.observer.observe(e,{subtree:!0,childList:!0,characterData:!0,attributes:!0})}collect(e,t,n){let i=[e,...Array.from(e.querySelectorAll(`*`))];for(let e of i)e.matches(`t, mt-translate, [data-t]`)?t.add(r(e)):e.matches(`[data-t-attrs]`)&&!e.closest(`t, mt-translate, [data-t]`)&&n.add(e)}handleMutations(e){let n=new Set,i=new Set;for(let a of e){let e=a.target.nodeType===Node.ELEMENT_NODE?a.target:a.target.parentElement;if(!e)continue;let o=e.closest(t);o?n.add(r(o)):(a.type===`attributes`&&e.matches(`[data-t-attrs]`)&&i.add(e),a.addedNodes.forEach(e=>{e.nodeType===Node.ELEMENT_NODE&&this.collect(e,n,i)}))}e.some(e=>e.removedNodes.length>0)&&this.forget(e=>!e.isConnected),n.forEach(e=>this.translateContent(e)),i.forEach(e=>this.translateAttributes(e))}forget(e){for(let t of this.contents.keys())e(t)&&this.contents.delete(t);for(let t of this.attributes.keys())e(t)&&this.attributes.delete(t)}translateContent(t,n=!1){let r=t.innerHTML,s=t.getAttribute(`data-v`),c=this.contents.get(t);if(!c)c={source:r,requestId:0,variables:s},this.contents.set(t,c);else if(r!==c.rendered&&r!==c.source)c.source=r,c.rendered=void 0,c.variables=s;else if(s!==c.variables)c.variables=s;else if(!n)return;let[,l,u,d]=/^(\s*)([\s\S]*?)(\s*)$/.exec(c.source.replace(/<!--[\s\S]*?-->/g,``));if(!u)return;let f=a(t);if(f===null)return;let{template:p,values:m,unused:h}=f?(0,e.toHtmlTemplate)(u,f):{template:u,values:[],unused:[]};p!==c.template&&(c.template=p,(0,e.warnAboutUnused)(h));let g=c,_=e=>{let n=`${l}${o(e,m)}${d}`;t.innerHTML!==n&&(t.innerHTML=n),g.rendered=t.innerHTML};f&&g.rendered===void 0&&_(p);let v=++g.requestId;this.translate(p,i(t)).then(e=>{v===g.requestId&&t.isConnected&&_(e)})}translateAttributes(t,n=!1){let r=(t.getAttribute(`data-t-attrs`)??``).split(/[\s,]+/).filter(Boolean),o=t.getAttribute(`data-v`),s=this.attributes.get(t);s||(s=new Map,this.attributes.set(t,s));for(let c of r){let r=t.getAttribute(c);if(!r?.trim())continue;let l=s.get(c);if(!l)l={source:r,requestId:0,variables:o},s.set(c,l);else if(r!==l.rendered&&r!==l.source)l.source=r,l.rendered=void 0,l.variables=o;else if(o!==l.variables)l.variables=o;else if(!n)continue;let u=a(t);if(u===null)continue;let{template:d,values:f,unused:p}=u?(0,e.toTemplate)(l.source,u):{template:l.source,values:[],unused:[]};d!==l.template&&(l.template=d,(0,e.warnAboutUnused)(p));let m=l,h=n=>{let r=(0,e.fillPlaceholders)(n,f);m.rendered=r,t.getAttribute(c)!==r&&t.setAttribute(c,r)};u&&m.rendered===void 0&&h(d);let g=++m.requestId;this.translate(d,i(t)).then(e=>{g===m.requestId&&t.isConnected&&h(e)})}}};function c(e){return new s(e)}exports.ATTRIBUTES_SELECTOR=n,exports.CONTENT_SELECTOR=t,exports.MagicTranslate=s,exports.createMagicTranslate=c,Object.keys(e).forEach(function(t){t!=="default"&&!Object.prototype.hasOwnProperty.call(exports,t)&&Object.defineProperty(exports,t,{enumerable:!0,get:function(){return e[t]}})});
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("@magic-translate/core");var t=`t, mt-translate, [data-t]`,n=`[data-t-attrs]`;function r(e){let n=e;for(let e=n.parentElement?.closest(t);e;e=n.parentElement?.closest(t))n=e;return n}function i(e){let t={},n=e.getAttribute(`data-lang`),r=e.getAttribute(`data-formality`),i=e.getAttribute(`data-t-id`);return n&&(t.lang=n),r&&(t.formality=r),i&&(t.id=i),t}function a(t){let n=t.getAttribute(`data-v`);if(n!==null){try{let e=JSON.parse(n);if(e&&typeof e==`object`&&!Array.isArray(e))return e}catch{}return console.warn(`[${e.libraryName}]: data-v must be a JSON object, such as data-v='{"name": "Bob"}', but is ${n}`),null}}function o(t,n){if(n.length===0)return t;let r=document.createElement(`template`);return r.innerHTML=t,(0,e.fillElement)(r.content,n),r.innerHTML}var s=class{constructor(t){if(this.options=t,this.contents=new Map,this.attributes=new Map,this.listeners=new Set,!t.apiKey)throw Error(`Missing API key. Please get one at ${e.libraryWebsite}`);this.currentLanguage=t.language??(0,e.utsLocaleToLanguage)(typeof navigator>`u`?void 0:navigator.language),this.dataLoader=this.createDataLoader(),typeof document<`u`&&(this.root=t.root??document.documentElement,this.start(this.root))}get language(){return this.currentLanguage}setLanguage(e){e!==this.currentLanguage&&(this.currentLanguage=e,this.dataLoader=this.createDataLoader(),this.forget(e=>!e.isConnected||!this.root?.contains(e)),this.contents.forEach((e,t)=>this.translateContent(t,!0)),this.attributes.forEach((e,t)=>this.translateAttributes(t,!0)),this.listeners.forEach(t=>t(e)))}onLanguageChange(e){return this.listeners.add(e),()=>this.listeners.delete(e)}translate(t,{v:n,...r}={}){if(!n)return this.dataLoader.load({text:t,...r});let{template:i,values:a,unused:o}=(0,e.toTemplate)(t,n);return(0,e.warnAboutUnused)(o),this.dataLoader.load({text:i,...r}).then(t=>(0,e.fillPlaceholders)(t,a))}destroy(){this.observer?.disconnect(),this.contents.clear(),this.attributes.clear(),this.listeners.clear()}createDataLoader(){let{debug:t,apiKey:n,sourceLanguage:r,_apiUrl:i,formality:a}=this.options,o=this.options._loaderFactory??e.defaultLoaderFactory;return new e.DataLoader(o({debug:!!t,apiKey:n,lang:this.currentLanguage,sourceLang:r,apiUrl:i,formality:a}),{cacheKeyFn:(0,e.cacheKeyFn)(n,r,this.currentLanguage)})}start(e){let t=new Set,n=new Set;this.collect(e,t,n),t.forEach(e=>this.translateContent(e)),n.forEach(e=>this.translateAttributes(e)),this.observer=new MutationObserver(e=>this.handleMutations(e)),this.observer.observe(e,{subtree:!0,childList:!0,characterData:!0,attributes:!0})}collect(e,t,n){let i=[e,...Array.from(e.querySelectorAll(`*`))];for(let e of i)e.matches(`t, mt-translate, [data-t]`)?t.add(r(e)):e.matches(`[data-t-attrs]`)&&!e.closest(`t, mt-translate, [data-t]`)&&n.add(e)}handleMutations(e){let n=new Set,i=new Set;for(let a of e){let e=a.target.nodeType===Node.ELEMENT_NODE?a.target:a.target.parentElement;if(!e)continue;let o=e.closest(t);o?n.add(r(o)):(a.type===`attributes`&&e.matches(`[data-t-attrs]`)&&i.add(e),a.addedNodes.forEach(e=>{e.nodeType===Node.ELEMENT_NODE&&this.collect(e,n,i)}))}e.some(e=>e.removedNodes.length>0)&&this.forget(e=>!e.isConnected),n.forEach(e=>this.translateContent(e)),i.forEach(e=>this.translateAttributes(e))}forget(e){for(let t of this.contents.keys())e(t)&&this.contents.delete(t);for(let t of this.attributes.keys())e(t)&&this.attributes.delete(t)}translateContent(t,n=!1){let r=t.innerHTML,s=t.getAttribute(`data-v`),c=this.contents.get(t);if(!c)c={source:r,requestId:0,variables:s},this.contents.set(t,c);else if(r!==c.rendered&&r!==c.source)c.source=r,c.rendered=void 0,c.variables=s;else if(s!==c.variables)c.variables=s;else if(!n)return;let[,l,u,d]=/^(\s*)([\s\S]*?)(\s*)$/.exec(c.source.replace(/<!--[\s\S]*?-->/g,``));if(!u)return;let f=a(t);if(f===null)return;let{template:p,values:m,unused:h}=f?(0,e.toHtmlTemplate)(u,f):{template:u,values:[],unused:[]};p!==c.template&&(c.template=p,(0,e.warnAboutUnused)(h));let g=c,_=e=>{let n=`${l}${o(e,m)}${d}`;t.innerHTML!==n&&(t.innerHTML=n),g.rendered=t.innerHTML};f&&g.rendered===void 0&&_(p);let v=++g.requestId;this.translate(p,i(t)).then(e=>{v===g.requestId&&t.isConnected&&_(e)})}translateAttributes(t,n=!1){let r=(t.getAttribute(`data-t-attrs`)??``).split(/[\s,]+/).filter(Boolean),o=t.getAttribute(`data-v`),s=this.attributes.get(t);s||(s=new Map,this.attributes.set(t,s));for(let c of r){let r=t.getAttribute(c);if(!r?.trim())continue;let l=s.get(c);if(!l)l={source:r,requestId:0,variables:o},s.set(c,l);else if(r!==l.rendered&&r!==l.source)l.source=r,l.rendered=void 0,l.variables=o;else if(o!==l.variables)l.variables=o;else if(!n)continue;let u=a(t);if(u===null)continue;let{template:d,values:f,unused:p}=u?(0,e.toTemplate)(l.source,u):{template:l.source,values:[],unused:[]};d!==l.template&&(l.template=d,(0,e.warnAboutUnused)(p));let m=l,h=n=>{let r=(0,e.fillPlaceholders)(n,f);m.rendered=r,t.getAttribute(c)!==r&&t.setAttribute(c,r)};u&&m.rendered===void 0&&h(d);let g=++m.requestId,{id:_,...v}=i(t);this.translate(d,v).then(e=>{g===m.requestId&&t.isConnected&&h(e)})}}};function c(e){return new s(e)}exports.ATTRIBUTES_SELECTOR=n,exports.CONTENT_SELECTOR=t,exports.MagicTranslate=s,exports.createMagicTranslate=c,Object.keys(e).forEach(function(t){t!=="default"&&!Object.prototype.hasOwnProperty.call(exports,t)&&Object.defineProperty(exports,t,{enumerable:!0,get:function(){return e[t]}})});
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["libraryName","libraryWebsite","utsLocaleToLanguage","toTemplate","fillPlaceholders","defaultLoaderFactory","DataLoader","cacheKeyFn","toHtmlTemplate","_magic_translate_core","CONTENT_SELECTOR","ATTRIBUTES_SELECTOR","outermost","current","element","parent","optionsOf","options","lang","formality","variablesOf","json","variables","fillHtml","values","html","container","MagicTranslate","language","listener","params","v","text","unused","template","translation","loaderFactory","debug","sourceLanguage","_apiUrl","apiKey","contents","attributes","root","records","all","record","target","content","node","predicate","variablesJson","force","leadingWhitespace","trailingWhitespace","show","rendered","translated","requestId","names","translations","name","value","createMagicTranslate","k"],"sources":["../src/magic-translate.ts"],"sourcesContent":["import {\n cacheKeyFn,\n DataLoader,\n DataLoaderLoadParams,\n defaultLoaderFactory,\n fillElement,\n fillPlaceholders,\n Language,\n libraryName,\n libraryWebsite,\n MagicTranslateConfig,\n toHtmlTemplate,\n toTemplate,\n TranslateOptions,\n utsLocaleToLanguage,\n Variables,\n warnAboutUnused,\n} from '@magic-translate/core';\n\n/**\n * Type alias to make the language enum more flexible to also allow passing language strings\n * instead of just the enum.\n */\nexport type Languages = `${Language}`;\n\nexport interface TranslateParams extends Omit<DataLoaderLoadParams, 'text'> {\n /**\n * Values that are not translated, referenced as `$name` in the text. The text\n * is translated once as a template and cached, whatever the values are.\n */\n v?: Variables;\n}\n\nexport interface MagicTranslateOptions extends Omit<\n MagicTranslateConfig,\n 'language'\n> {\n /**\n * The language content is translated to. Defaults to the browser's language.\n */\n language?: Languages;\n /**\n * The element whose content is translated. Defaults to the whole document.\n */\n root?: Element;\n}\n\n/** Elements whose content is translated. */\nexport const CONTENT_SELECTOR = 't, mt-translate, [data-t]';\n/** Elements with attributes to translate, e.g. `data-t-attrs=\"placeholder title\"`. */\nexport const ATTRIBUTES_SELECTOR = '[data-t-attrs]';\n\ninterface Translation {\n source: string;\n // what was last written to the DOM, to tell our own changes from others\n rendered?: string;\n requestId: number;\n // the `data-v` attribute the source was last translated with\n variables: string | null;\n // to warn about unused variables once per text, not on every render\n template?: string;\n}\n\nfunction outermost(element: Element): Element {\n let current = element;\n for (\n let parent = current.parentElement?.closest(CONTENT_SELECTOR);\n parent;\n parent = current.parentElement?.closest(CONTENT_SELECTOR)\n ) {\n current = parent;\n }\n return current;\n}\n\nfunction optionsOf(element: Element): TranslateOptions {\n const options: TranslateOptions = {};\n const lang = element.getAttribute('data-lang');\n const formality = element.getAttribute('data-formality');\n if (lang) {\n options.lang = lang as Languages;\n }\n if (formality) {\n options.formality = formality as TranslateOptions['formality'];\n }\n return options;\n}\n\n/**\n * Reads the values in `data-v`, a JSON object such as `{\"name\": \"Bob\"}`.\n * Returns `null` if the attribute is not valid, so the text is left as it is\n * rather than translated with `$name` in it.\n */\nfunction variablesOf(element: Element): Variables | undefined | null {\n const json = element.getAttribute('data-v');\n if (json === null) {\n return undefined;\n }\n try {\n const variables: unknown = JSON.parse(json);\n if (\n variables &&\n typeof variables === 'object' &&\n !Array.isArray(variables)\n ) {\n return variables as Variables;\n }\n } catch {\n // reported below\n }\n console.warn(\n `[${libraryName}]: data-v must be a JSON object, such as data-v='{\"name\": \"Bob\"}', but is ${json}`\n );\n return null;\n}\n\nfunction fillHtml(html: string, values: readonly string[]): string {\n if (values.length === 0) {\n return html;\n }\n const container = document.createElement('template');\n container.innerHTML = html;\n fillElement(container.content, values);\n return container.innerHTML;\n}\n\nexport class MagicTranslate {\n private currentLanguage: Languages;\n private dataLoader: DataLoader<DataLoaderLoadParams, string, string>;\n private readonly root?: Element;\n private readonly contents = new Map<Element, Translation>();\n private readonly attributes = new Map<Element, Map<string, Translation>>();\n private readonly listeners = new Set<(language: Languages) => void>();\n private observer?: MutationObserver;\n\n constructor(private readonly options: MagicTranslateOptions) {\n if (!options.apiKey) {\n throw new Error(`Missing API key. Please get one at ${libraryWebsite}`);\n }\n\n this.currentLanguage =\n options.language ??\n utsLocaleToLanguage(\n typeof navigator === 'undefined' ? undefined : navigator.language\n );\n this.dataLoader = this.createDataLoader();\n\n if (typeof document !== 'undefined') {\n this.root = options.root ?? document.documentElement;\n this.start(this.root);\n }\n }\n\n /**\n * The language content is currently translated to.\n */\n get language(): Languages {\n return this.currentLanguage;\n }\n\n /**\n * Translates the page to another language.\n */\n setLanguage(language: Languages): void {\n if (language === this.currentLanguage) {\n return;\n }\n\n this.currentLanguage = language;\n this.dataLoader = this.createDataLoader();\n\n this.forget(\n (element) => !element.isConnected || !this.root?.contains(element)\n );\n this.contents.forEach((_, element) => this.translateContent(element, true));\n this.attributes.forEach((_, element) =>\n this.translateAttributes(element, true)\n );\n this.listeners.forEach((listener) => listener(language));\n }\n\n /**\n * Calls `listener` whenever the language changes. Returns a function that\n * removes the listener again.\n */\n onLanguageChange(listener: (language: Languages) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Translates a string to the current language.\n */\n translate(\n text: string,\n { v, ...params }: TranslateParams = {}\n ): Promise<string> {\n if (!v) {\n return this.dataLoader.load({ text, ...params });\n }\n const { template, values, unused } = toTemplate(text, v);\n warnAboutUnused(unused);\n return this.dataLoader\n .load({ text: template, ...params })\n .then((translation) => fillPlaceholders(translation, values));\n }\n\n /**\n * Stops translating the page. Content that is already translated stays\n * translated.\n */\n destroy(): void {\n this.observer?.disconnect();\n this.contents.clear();\n this.attributes.clear();\n this.listeners.clear();\n }\n\n private createDataLoader() {\n const { debug, apiKey, sourceLanguage, _apiUrl, formality } = this.options;\n const loaderFactory = this.options._loaderFactory ?? defaultLoaderFactory;\n\n return new DataLoader<DataLoaderLoadParams, string, string>(\n loaderFactory({\n debug: !!debug,\n apiKey,\n lang: this.currentLanguage,\n sourceLang: sourceLanguage,\n apiUrl: _apiUrl,\n formality,\n }),\n {\n cacheKeyFn: cacheKeyFn(apiKey, sourceLanguage, this.currentLanguage),\n }\n );\n }\n\n private start(root: Element) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n this.collect(root, contents, attributes);\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n\n // Picks up content that is added or changed later.\n this.observer = new MutationObserver((records) =>\n this.handleMutations(records)\n );\n this.observer.observe(root, {\n subtree: true,\n childList: true,\n characterData: true,\n attributes: true,\n });\n }\n\n private collect(\n root: Element,\n contents: Set<Element>,\n attributes: Set<Element>\n ) {\n const all = [root, ...Array.from(root.querySelectorAll('*'))];\n for (const element of all) {\n if (element.matches(CONTENT_SELECTOR)) {\n contents.add(outermost(element));\n } else if (\n element.matches(ATTRIBUTES_SELECTOR) &&\n !element.closest(CONTENT_SELECTOR)\n ) {\n attributes.add(element);\n }\n }\n }\n\n private handleMutations(records: MutationRecord[]) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n\n for (const record of records) {\n const target =\n record.target.nodeType === Node.ELEMENT_NODE\n ? (record.target as Element)\n : record.target.parentElement;\n if (!target) {\n continue;\n }\n\n const content = target.closest(CONTENT_SELECTOR);\n if (content) {\n contents.add(outermost(content));\n continue;\n }\n\n if (record.type === 'attributes' && target.matches(ATTRIBUTES_SELECTOR)) {\n attributes.add(target);\n }\n record.addedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n this.collect(node as Element, contents, attributes);\n }\n });\n }\n\n if (records.some((record) => record.removedNodes.length > 0)) {\n this.forget((element) => !element.isConnected);\n }\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n }\n\n private forget(predicate: (element: Element) => boolean) {\n for (const element of this.contents.keys()) {\n if (predicate(element)) {\n this.contents.delete(element);\n }\n }\n for (const element of this.attributes.keys()) {\n if (predicate(element)) {\n this.attributes.delete(element);\n }\n }\n }\n\n private translateContent(element: Element, force = false) {\n const html = element.innerHTML;\n const variablesJson = element.getAttribute('data-v');\n let translation = this.contents.get(element);\n if (!translation) {\n translation = { source: html, requestId: 0, variables: variablesJson };\n this.contents.set(element, translation);\n } else if (html !== translation.rendered && html !== translation.source) {\n // changed by someone else, e.g. the page's own scripts\n translation.source = html;\n translation.rendered = undefined;\n translation.variables = variablesJson;\n } else if (variablesJson !== translation.variables) {\n // only the values changed, so the cached translation is reused\n translation.variables = variablesJson;\n } else if (!force) {\n return;\n }\n\n const [, leadingWhitespace, text, trailingWhitespace] =\n /^(\\s*)([\\s\\S]*?)(\\s*)$/.exec(\n translation.source.replace(/<!--[\\s\\S]*?-->/g, '')\n )!;\n if (!text) {\n return;\n }\n\n const variables = variablesOf(element);\n if (variables === null) {\n return;\n }\n const { template, values, unused } = variables\n ? toHtmlTemplate(text, variables)\n : { template: text, values: [], unused: [] };\n if (template !== translation.template) {\n translation.template = template;\n warnAboutUnused(unused);\n }\n\n const current = translation;\n const show = (translated: string) => {\n const rendered = `${leadingWhitespace}${fillHtml(translated, values)}${trailingWhitespace}`;\n if (element.innerHTML !== rendered) {\n element.innerHTML = rendered;\n }\n current.rendered = element.innerHTML;\n };\n // Until the first translation arrives, show the values instead of `$name`.\n if (variables && current.rendered === undefined) {\n show(template);\n }\n\n // make sure that we only ever use the response of the most recent request.\n const requestId = ++current.requestId;\n this.translate(template, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n show(translated);\n });\n }\n\n private translateAttributes(element: Element, force = false) {\n const names = (element.getAttribute('data-t-attrs') ?? '')\n .split(/[\\s,]+/)\n .filter(Boolean);\n const variablesJson = element.getAttribute('data-v');\n let translations = this.attributes.get(element);\n if (!translations) {\n translations = new Map();\n this.attributes.set(element, translations);\n }\n\n for (const name of names) {\n const value = element.getAttribute(name);\n if (!value?.trim()) {\n continue;\n }\n\n let translation = translations.get(name);\n if (!translation) {\n translation = { source: value, requestId: 0, variables: variablesJson };\n translations.set(name, translation);\n } else if (\n value !== translation.rendered &&\n value !== translation.source\n ) {\n translation.source = value;\n translation.rendered = undefined;\n translation.variables = variablesJson;\n } else if (variablesJson !== translation.variables) {\n translation.variables = variablesJson;\n } else if (!force) {\n continue;\n }\n\n const variables = variablesOf(element);\n if (variables === null) {\n continue;\n }\n const { template, values, unused } = variables\n ? toTemplate(translation.source, variables)\n : { template: translation.source, values: [], unused: [] };\n if (template !== translation.template) {\n translation.template = template;\n warnAboutUnused(unused);\n }\n\n const current = translation;\n const show = (translated: string) => {\n const rendered = fillPlaceholders(translated, values);\n current.rendered = rendered;\n if (element.getAttribute(name) !== rendered) {\n element.setAttribute(name, rendered);\n }\n };\n if (variables && current.rendered === undefined) {\n show(template);\n }\n\n const requestId = ++current.requestId;\n this.translate(template, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n show(translated);\n });\n }\n }\n}\n\n/**\n * Starts translating the page: the content of every `<t>` element (or element\n * with a `data-t` attribute), and the attributes listed in `data-t-attrs`.\n * Content added later is translated as well.\n */\nexport function createMagicTranslate(\n options: MagicTranslateOptions\n): MagicTranslate {\n return new MagicTranslate(options);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["libraryName","libraryWebsite","utsLocaleToLanguage","toTemplate","fillPlaceholders","defaultLoaderFactory","DataLoader","cacheKeyFn","toHtmlTemplate","_magic_translate_core","CONTENT_SELECTOR","ATTRIBUTES_SELECTOR","outermost","current","element","parent","optionsOf","options","lang","formality","id","variablesOf","json","variables","fillHtml","values","html","container","MagicTranslate","language","listener","params","v","text","unused","template","translation","loaderFactory","debug","sourceLanguage","_apiUrl","apiKey","contents","attributes","root","records","all","record","target","content","node","predicate","variablesJson","force","leadingWhitespace","trailingWhitespace","show","rendered","translated","requestId","names","translations","name","value","_id","createMagicTranslate","k"],"sources":["../src/magic-translate.ts"],"sourcesContent":["import {\n cacheKeyFn,\n DataLoader,\n DataLoaderLoadParams,\n defaultLoaderFactory,\n fillElement,\n fillPlaceholders,\n Language,\n libraryName,\n libraryWebsite,\n MagicTranslateConfig,\n toHtmlTemplate,\n toTemplate,\n TextOptions,\n TranslateOptions,\n utsLocaleToLanguage,\n Variables,\n warnAboutUnused,\n} from '@magic-translate/core';\n\n/**\n * Type alias to make the language enum more flexible to also allow passing language strings\n * instead of just the enum.\n */\nexport type Languages = `${Language}`;\n\nexport interface TranslateParams extends Omit<DataLoaderLoadParams, 'text'> {\n /**\n * Values that are not translated, referenced as `$name` in the text. The text\n * is translated once as a template and cached, whatever the values are.\n */\n v?: Variables;\n}\n\nexport interface MagicTranslateOptions extends Omit<\n MagicTranslateConfig,\n 'language'\n> {\n /**\n * The language content is translated to. Defaults to the browser's language.\n */\n language?: Languages;\n /**\n * The element whose content is translated. Defaults to the whole document.\n */\n root?: Element;\n}\n\n/** Elements whose content is translated. */\nexport const CONTENT_SELECTOR = 't, mt-translate, [data-t]';\n/** Elements with attributes to translate, e.g. `data-t-attrs=\"placeholder title\"`. */\nexport const ATTRIBUTES_SELECTOR = '[data-t-attrs]';\n\ninterface Translation {\n source: string;\n // what was last written to the DOM, to tell our own changes from others\n rendered?: string;\n requestId: number;\n // the `data-v` attribute the source was last translated with\n variables: string | null;\n // to warn about unused variables once per text, not on every render\n template?: string;\n}\n\nfunction outermost(element: Element): Element {\n let current = element;\n for (\n let parent = current.parentElement?.closest(CONTENT_SELECTOR);\n parent;\n parent = current.parentElement?.closest(CONTENT_SELECTOR)\n ) {\n current = parent;\n }\n return current;\n}\n\nfunction optionsOf(element: Element): TextOptions {\n const options: TextOptions = {};\n const lang = element.getAttribute('data-lang');\n const formality = element.getAttribute('data-formality');\n const id = element.getAttribute('data-t-id');\n if (lang) {\n options.lang = lang as Languages;\n }\n if (formality) {\n options.formality = formality as TranslateOptions['formality'];\n }\n if (id) {\n options.id = id;\n }\n return options;\n}\n\n/**\n * Reads the values in `data-v`, a JSON object such as `{\"name\": \"Bob\"}`.\n * Returns `null` if the attribute is not valid, so the text is left as it is\n * rather than translated with `$name` in it.\n */\nfunction variablesOf(element: Element): Variables | undefined | null {\n const json = element.getAttribute('data-v');\n if (json === null) {\n return undefined;\n }\n try {\n const variables: unknown = JSON.parse(json);\n if (\n variables &&\n typeof variables === 'object' &&\n !Array.isArray(variables)\n ) {\n return variables as Variables;\n }\n } catch {\n // reported below\n }\n console.warn(\n `[${libraryName}]: data-v must be a JSON object, such as data-v='{\"name\": \"Bob\"}', but is ${json}`\n );\n return null;\n}\n\nfunction fillHtml(html: string, values: readonly string[]): string {\n if (values.length === 0) {\n return html;\n }\n const container = document.createElement('template');\n container.innerHTML = html;\n fillElement(container.content, values);\n return container.innerHTML;\n}\n\nexport class MagicTranslate {\n private currentLanguage: Languages;\n private dataLoader: DataLoader<DataLoaderLoadParams, string, string>;\n private readonly root?: Element;\n private readonly contents = new Map<Element, Translation>();\n private readonly attributes = new Map<Element, Map<string, Translation>>();\n private readonly listeners = new Set<(language: Languages) => void>();\n private observer?: MutationObserver;\n\n constructor(private readonly options: MagicTranslateOptions) {\n if (!options.apiKey) {\n throw new Error(`Missing API key. Please get one at ${libraryWebsite}`);\n }\n\n this.currentLanguage =\n options.language ??\n utsLocaleToLanguage(\n typeof navigator === 'undefined' ? undefined : navigator.language\n );\n this.dataLoader = this.createDataLoader();\n\n if (typeof document !== 'undefined') {\n this.root = options.root ?? document.documentElement;\n this.start(this.root);\n }\n }\n\n /**\n * The language content is currently translated to.\n */\n get language(): Languages {\n return this.currentLanguage;\n }\n\n /**\n * Translates the page to another language.\n */\n setLanguage(language: Languages): void {\n if (language === this.currentLanguage) {\n return;\n }\n\n this.currentLanguage = language;\n this.dataLoader = this.createDataLoader();\n\n this.forget(\n (element) => !element.isConnected || !this.root?.contains(element)\n );\n this.contents.forEach((_, element) => this.translateContent(element, true));\n this.attributes.forEach((_, element) =>\n this.translateAttributes(element, true)\n );\n this.listeners.forEach((listener) => listener(language));\n }\n\n /**\n * Calls `listener` whenever the language changes. Returns a function that\n * removes the listener again.\n */\n onLanguageChange(listener: (language: Languages) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Translates a string to the current language.\n */\n translate(\n text: string,\n { v, ...params }: TranslateParams = {}\n ): Promise<string> {\n if (!v) {\n return this.dataLoader.load({ text, ...params });\n }\n const { template, values, unused } = toTemplate(text, v);\n warnAboutUnused(unused);\n return this.dataLoader\n .load({ text: template, ...params })\n .then((translation) => fillPlaceholders(translation, values));\n }\n\n /**\n * Stops translating the page. Content that is already translated stays\n * translated.\n */\n destroy(): void {\n this.observer?.disconnect();\n this.contents.clear();\n this.attributes.clear();\n this.listeners.clear();\n }\n\n private createDataLoader() {\n const { debug, apiKey, sourceLanguage, _apiUrl, formality } = this.options;\n const loaderFactory = this.options._loaderFactory ?? defaultLoaderFactory;\n\n return new DataLoader<DataLoaderLoadParams, string, string>(\n loaderFactory({\n debug: !!debug,\n apiKey,\n lang: this.currentLanguage,\n sourceLang: sourceLanguage,\n apiUrl: _apiUrl,\n formality,\n }),\n {\n cacheKeyFn: cacheKeyFn(apiKey, sourceLanguage, this.currentLanguage),\n }\n );\n }\n\n private start(root: Element) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n this.collect(root, contents, attributes);\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n\n // Picks up content that is added or changed later.\n this.observer = new MutationObserver((records) =>\n this.handleMutations(records)\n );\n this.observer.observe(root, {\n subtree: true,\n childList: true,\n characterData: true,\n attributes: true,\n });\n }\n\n private collect(\n root: Element,\n contents: Set<Element>,\n attributes: Set<Element>\n ) {\n const all = [root, ...Array.from(root.querySelectorAll('*'))];\n for (const element of all) {\n if (element.matches(CONTENT_SELECTOR)) {\n contents.add(outermost(element));\n } else if (\n element.matches(ATTRIBUTES_SELECTOR) &&\n !element.closest(CONTENT_SELECTOR)\n ) {\n attributes.add(element);\n }\n }\n }\n\n private handleMutations(records: MutationRecord[]) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n\n for (const record of records) {\n const target =\n record.target.nodeType === Node.ELEMENT_NODE\n ? (record.target as Element)\n : record.target.parentElement;\n if (!target) {\n continue;\n }\n\n const content = target.closest(CONTENT_SELECTOR);\n if (content) {\n contents.add(outermost(content));\n continue;\n }\n\n if (record.type === 'attributes' && target.matches(ATTRIBUTES_SELECTOR)) {\n attributes.add(target);\n }\n record.addedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n this.collect(node as Element, contents, attributes);\n }\n });\n }\n\n if (records.some((record) => record.removedNodes.length > 0)) {\n this.forget((element) => !element.isConnected);\n }\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n }\n\n private forget(predicate: (element: Element) => boolean) {\n for (const element of this.contents.keys()) {\n if (predicate(element)) {\n this.contents.delete(element);\n }\n }\n for (const element of this.attributes.keys()) {\n if (predicate(element)) {\n this.attributes.delete(element);\n }\n }\n }\n\n private translateContent(element: Element, force = false) {\n const html = element.innerHTML;\n const variablesJson = element.getAttribute('data-v');\n let translation = this.contents.get(element);\n if (!translation) {\n translation = { source: html, requestId: 0, variables: variablesJson };\n this.contents.set(element, translation);\n } else if (html !== translation.rendered && html !== translation.source) {\n // changed by someone else, e.g. the page's own scripts\n translation.source = html;\n translation.rendered = undefined;\n translation.variables = variablesJson;\n } else if (variablesJson !== translation.variables) {\n // only the values changed, so the cached translation is reused\n translation.variables = variablesJson;\n } else if (!force) {\n return;\n }\n\n const [, leadingWhitespace, text, trailingWhitespace] =\n /^(\\s*)([\\s\\S]*?)(\\s*)$/.exec(\n translation.source.replace(/<!--[\\s\\S]*?-->/g, '')\n )!;\n if (!text) {\n return;\n }\n\n const variables = variablesOf(element);\n if (variables === null) {\n return;\n }\n const { template, values, unused } = variables\n ? toHtmlTemplate(text, variables)\n : { template: text, values: [], unused: [] };\n if (template !== translation.template) {\n translation.template = template;\n warnAboutUnused(unused);\n }\n\n const current = translation;\n const show = (translated: string) => {\n const rendered = `${leadingWhitespace}${fillHtml(translated, values)}${trailingWhitespace}`;\n if (element.innerHTML !== rendered) {\n element.innerHTML = rendered;\n }\n current.rendered = element.innerHTML;\n };\n // Until the first translation arrives, show the values instead of `$name`.\n if (variables && current.rendered === undefined) {\n show(template);\n }\n\n // make sure that we only ever use the response of the most recent request.\n const requestId = ++current.requestId;\n this.translate(template, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n show(translated);\n });\n }\n\n private translateAttributes(element: Element, force = false) {\n const names = (element.getAttribute('data-t-attrs') ?? '')\n .split(/[\\s,]+/)\n .filter(Boolean);\n const variablesJson = element.getAttribute('data-v');\n let translations = this.attributes.get(element);\n if (!translations) {\n translations = new Map();\n this.attributes.set(element, translations);\n }\n\n for (const name of names) {\n const value = element.getAttribute(name);\n if (!value?.trim()) {\n continue;\n }\n\n let translation = translations.get(name);\n if (!translation) {\n translation = { source: value, requestId: 0, variables: variablesJson };\n translations.set(name, translation);\n } else if (\n value !== translation.rendered &&\n value !== translation.source\n ) {\n translation.source = value;\n translation.rendered = undefined;\n translation.variables = variablesJson;\n } else if (variablesJson !== translation.variables) {\n translation.variables = variablesJson;\n } else if (!force) {\n continue;\n }\n\n const variables = variablesOf(element);\n if (variables === null) {\n continue;\n }\n const { template, values, unused } = variables\n ? toTemplate(translation.source, variables)\n : { template: translation.source, values: [], unused: [] };\n if (template !== translation.template) {\n translation.template = template;\n warnAboutUnused(unused);\n }\n\n const current = translation;\n const show = (translated: string) => {\n const rendered = fillPlaceholders(translated, values);\n current.rendered = rendered;\n if (element.getAttribute(name) !== rendered) {\n element.setAttribute(name, rendered);\n }\n };\n if (variables && current.rendered === undefined) {\n show(template);\n }\n\n const requestId = ++current.requestId;\n // An id stands for one text, and an element's attributes are several.\n const { id: _id, ...options } = optionsOf(element);\n this.translate(template, options).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n show(translated);\n });\n }\n }\n}\n\n/**\n * Starts translating the page: the content of every `<t>` element (or element\n * with a `data-t` attribute), and the attributes listed in `data-t-attrs`.\n * Content added later is translated as well.\n */\nexport function createMagicTranslate(\n options: MagicTranslateOptions\n): MagicTranslate {\n return new MagicTranslate(options);\n}\n"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -8,8 +8,8 @@ function p(e) {
8
8
  return t;
9
9
  }
10
10
  function m(e) {
11
- let t = {}, n = e.getAttribute("data-lang"), r = e.getAttribute("data-formality");
12
- return n && (t.lang = n), r && (t.formality = r), t;
11
+ let t = {}, n = e.getAttribute("data-lang"), r = e.getAttribute("data-formality"), i = e.getAttribute("data-t-id");
12
+ return n && (t.lang = n), r && (t.formality = r), i && (t.id = i), t;
13
13
  }
14
14
  function h(e) {
15
15
  let t = e.getAttribute("data-v");
@@ -152,8 +152,8 @@ var _ = class {
152
152
  g.rendered = n, e.getAttribute(o) !== n && e.setAttribute(o, n);
153
153
  };
154
154
  l && g.rendered === void 0 && _(d);
155
- let v = ++g.requestId;
156
- this.translate(d, m(e)).then((t) => {
155
+ let v = ++g.requestId, { id: y, ...b } = m(e);
156
+ this.translate(d, b).then((t) => {
157
157
  v === g.requestId && e.isConnected && _(t);
158
158
  });
159
159
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["CONTENT_SELECTOR","ATTRIBUTES_SELECTOR","outermost","current","element","parent","optionsOf","options","lang","formality","variablesOf","json","variables","libraryName","fillHtml","values","html","container","fillElement","MagicTranslate","libraryWebsite","utsLocaleToLanguage","language","listener","params","v","toTemplate","text","warnAboutUnused","unused","template","fillPlaceholders","translation","loaderFactory","defaultLoaderFactory","DataLoader","debug","sourceLanguage","_apiUrl","cacheKeyFn","apiKey","contents","attributes","root","records","all","record","target","content","node","predicate","variablesJson","force","leadingWhitespace","trailingWhitespace","toHtmlTemplate","show","rendered","translated","requestId","names","translations","name","value","createMagicTranslate"],"sources":["../src/magic-translate.ts"],"sourcesContent":["import {\n cacheKeyFn,\n DataLoader,\n DataLoaderLoadParams,\n defaultLoaderFactory,\n fillElement,\n fillPlaceholders,\n Language,\n libraryName,\n libraryWebsite,\n MagicTranslateConfig,\n toHtmlTemplate,\n toTemplate,\n TranslateOptions,\n utsLocaleToLanguage,\n Variables,\n warnAboutUnused,\n} from '@magic-translate/core';\n\n/**\n * Type alias to make the language enum more flexible to also allow passing language strings\n * instead of just the enum.\n */\nexport type Languages = `${Language}`;\n\nexport interface TranslateParams extends Omit<DataLoaderLoadParams, 'text'> {\n /**\n * Values that are not translated, referenced as `$name` in the text. The text\n * is translated once as a template and cached, whatever the values are.\n */\n v?: Variables;\n}\n\nexport interface MagicTranslateOptions extends Omit<\n MagicTranslateConfig,\n 'language'\n> {\n /**\n * The language content is translated to. Defaults to the browser's language.\n */\n language?: Languages;\n /**\n * The element whose content is translated. Defaults to the whole document.\n */\n root?: Element;\n}\n\n/** Elements whose content is translated. */\nexport const CONTENT_SELECTOR = 't, mt-translate, [data-t]';\n/** Elements with attributes to translate, e.g. `data-t-attrs=\"placeholder title\"`. */\nexport const ATTRIBUTES_SELECTOR = '[data-t-attrs]';\n\ninterface Translation {\n source: string;\n // what was last written to the DOM, to tell our own changes from others\n rendered?: string;\n requestId: number;\n // the `data-v` attribute the source was last translated with\n variables: string | null;\n // to warn about unused variables once per text, not on every render\n template?: string;\n}\n\nfunction outermost(element: Element): Element {\n let current = element;\n for (\n let parent = current.parentElement?.closest(CONTENT_SELECTOR);\n parent;\n parent = current.parentElement?.closest(CONTENT_SELECTOR)\n ) {\n current = parent;\n }\n return current;\n}\n\nfunction optionsOf(element: Element): TranslateOptions {\n const options: TranslateOptions = {};\n const lang = element.getAttribute('data-lang');\n const formality = element.getAttribute('data-formality');\n if (lang) {\n options.lang = lang as Languages;\n }\n if (formality) {\n options.formality = formality as TranslateOptions['formality'];\n }\n return options;\n}\n\n/**\n * Reads the values in `data-v`, a JSON object such as `{\"name\": \"Bob\"}`.\n * Returns `null` if the attribute is not valid, so the text is left as it is\n * rather than translated with `$name` in it.\n */\nfunction variablesOf(element: Element): Variables | undefined | null {\n const json = element.getAttribute('data-v');\n if (json === null) {\n return undefined;\n }\n try {\n const variables: unknown = JSON.parse(json);\n if (\n variables &&\n typeof variables === 'object' &&\n !Array.isArray(variables)\n ) {\n return variables as Variables;\n }\n } catch {\n // reported below\n }\n console.warn(\n `[${libraryName}]: data-v must be a JSON object, such as data-v='{\"name\": \"Bob\"}', but is ${json}`\n );\n return null;\n}\n\nfunction fillHtml(html: string, values: readonly string[]): string {\n if (values.length === 0) {\n return html;\n }\n const container = document.createElement('template');\n container.innerHTML = html;\n fillElement(container.content, values);\n return container.innerHTML;\n}\n\nexport class MagicTranslate {\n private currentLanguage: Languages;\n private dataLoader: DataLoader<DataLoaderLoadParams, string, string>;\n private readonly root?: Element;\n private readonly contents = new Map<Element, Translation>();\n private readonly attributes = new Map<Element, Map<string, Translation>>();\n private readonly listeners = new Set<(language: Languages) => void>();\n private observer?: MutationObserver;\n\n constructor(private readonly options: MagicTranslateOptions) {\n if (!options.apiKey) {\n throw new Error(`Missing API key. Please get one at ${libraryWebsite}`);\n }\n\n this.currentLanguage =\n options.language ??\n utsLocaleToLanguage(\n typeof navigator === 'undefined' ? undefined : navigator.language\n );\n this.dataLoader = this.createDataLoader();\n\n if (typeof document !== 'undefined') {\n this.root = options.root ?? document.documentElement;\n this.start(this.root);\n }\n }\n\n /**\n * The language content is currently translated to.\n */\n get language(): Languages {\n return this.currentLanguage;\n }\n\n /**\n * Translates the page to another language.\n */\n setLanguage(language: Languages): void {\n if (language === this.currentLanguage) {\n return;\n }\n\n this.currentLanguage = language;\n this.dataLoader = this.createDataLoader();\n\n this.forget(\n (element) => !element.isConnected || !this.root?.contains(element)\n );\n this.contents.forEach((_, element) => this.translateContent(element, true));\n this.attributes.forEach((_, element) =>\n this.translateAttributes(element, true)\n );\n this.listeners.forEach((listener) => listener(language));\n }\n\n /**\n * Calls `listener` whenever the language changes. Returns a function that\n * removes the listener again.\n */\n onLanguageChange(listener: (language: Languages) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Translates a string to the current language.\n */\n translate(\n text: string,\n { v, ...params }: TranslateParams = {}\n ): Promise<string> {\n if (!v) {\n return this.dataLoader.load({ text, ...params });\n }\n const { template, values, unused } = toTemplate(text, v);\n warnAboutUnused(unused);\n return this.dataLoader\n .load({ text: template, ...params })\n .then((translation) => fillPlaceholders(translation, values));\n }\n\n /**\n * Stops translating the page. Content that is already translated stays\n * translated.\n */\n destroy(): void {\n this.observer?.disconnect();\n this.contents.clear();\n this.attributes.clear();\n this.listeners.clear();\n }\n\n private createDataLoader() {\n const { debug, apiKey, sourceLanguage, _apiUrl, formality } = this.options;\n const loaderFactory = this.options._loaderFactory ?? defaultLoaderFactory;\n\n return new DataLoader<DataLoaderLoadParams, string, string>(\n loaderFactory({\n debug: !!debug,\n apiKey,\n lang: this.currentLanguage,\n sourceLang: sourceLanguage,\n apiUrl: _apiUrl,\n formality,\n }),\n {\n cacheKeyFn: cacheKeyFn(apiKey, sourceLanguage, this.currentLanguage),\n }\n );\n }\n\n private start(root: Element) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n this.collect(root, contents, attributes);\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n\n // Picks up content that is added or changed later.\n this.observer = new MutationObserver((records) =>\n this.handleMutations(records)\n );\n this.observer.observe(root, {\n subtree: true,\n childList: true,\n characterData: true,\n attributes: true,\n });\n }\n\n private collect(\n root: Element,\n contents: Set<Element>,\n attributes: Set<Element>\n ) {\n const all = [root, ...Array.from(root.querySelectorAll('*'))];\n for (const element of all) {\n if (element.matches(CONTENT_SELECTOR)) {\n contents.add(outermost(element));\n } else if (\n element.matches(ATTRIBUTES_SELECTOR) &&\n !element.closest(CONTENT_SELECTOR)\n ) {\n attributes.add(element);\n }\n }\n }\n\n private handleMutations(records: MutationRecord[]) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n\n for (const record of records) {\n const target =\n record.target.nodeType === Node.ELEMENT_NODE\n ? (record.target as Element)\n : record.target.parentElement;\n if (!target) {\n continue;\n }\n\n const content = target.closest(CONTENT_SELECTOR);\n if (content) {\n contents.add(outermost(content));\n continue;\n }\n\n if (record.type === 'attributes' && target.matches(ATTRIBUTES_SELECTOR)) {\n attributes.add(target);\n }\n record.addedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n this.collect(node as Element, contents, attributes);\n }\n });\n }\n\n if (records.some((record) => record.removedNodes.length > 0)) {\n this.forget((element) => !element.isConnected);\n }\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n }\n\n private forget(predicate: (element: Element) => boolean) {\n for (const element of this.contents.keys()) {\n if (predicate(element)) {\n this.contents.delete(element);\n }\n }\n for (const element of this.attributes.keys()) {\n if (predicate(element)) {\n this.attributes.delete(element);\n }\n }\n }\n\n private translateContent(element: Element, force = false) {\n const html = element.innerHTML;\n const variablesJson = element.getAttribute('data-v');\n let translation = this.contents.get(element);\n if (!translation) {\n translation = { source: html, requestId: 0, variables: variablesJson };\n this.contents.set(element, translation);\n } else if (html !== translation.rendered && html !== translation.source) {\n // changed by someone else, e.g. the page's own scripts\n translation.source = html;\n translation.rendered = undefined;\n translation.variables = variablesJson;\n } else if (variablesJson !== translation.variables) {\n // only the values changed, so the cached translation is reused\n translation.variables = variablesJson;\n } else if (!force) {\n return;\n }\n\n const [, leadingWhitespace, text, trailingWhitespace] =\n /^(\\s*)([\\s\\S]*?)(\\s*)$/.exec(\n translation.source.replace(/<!--[\\s\\S]*?-->/g, '')\n )!;\n if (!text) {\n return;\n }\n\n const variables = variablesOf(element);\n if (variables === null) {\n return;\n }\n const { template, values, unused } = variables\n ? toHtmlTemplate(text, variables)\n : { template: text, values: [], unused: [] };\n if (template !== translation.template) {\n translation.template = template;\n warnAboutUnused(unused);\n }\n\n const current = translation;\n const show = (translated: string) => {\n const rendered = `${leadingWhitespace}${fillHtml(translated, values)}${trailingWhitespace}`;\n if (element.innerHTML !== rendered) {\n element.innerHTML = rendered;\n }\n current.rendered = element.innerHTML;\n };\n // Until the first translation arrives, show the values instead of `$name`.\n if (variables && current.rendered === undefined) {\n show(template);\n }\n\n // make sure that we only ever use the response of the most recent request.\n const requestId = ++current.requestId;\n this.translate(template, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n show(translated);\n });\n }\n\n private translateAttributes(element: Element, force = false) {\n const names = (element.getAttribute('data-t-attrs') ?? '')\n .split(/[\\s,]+/)\n .filter(Boolean);\n const variablesJson = element.getAttribute('data-v');\n let translations = this.attributes.get(element);\n if (!translations) {\n translations = new Map();\n this.attributes.set(element, translations);\n }\n\n for (const name of names) {\n const value = element.getAttribute(name);\n if (!value?.trim()) {\n continue;\n }\n\n let translation = translations.get(name);\n if (!translation) {\n translation = { source: value, requestId: 0, variables: variablesJson };\n translations.set(name, translation);\n } else if (\n value !== translation.rendered &&\n value !== translation.source\n ) {\n translation.source = value;\n translation.rendered = undefined;\n translation.variables = variablesJson;\n } else if (variablesJson !== translation.variables) {\n translation.variables = variablesJson;\n } else if (!force) {\n continue;\n }\n\n const variables = variablesOf(element);\n if (variables === null) {\n continue;\n }\n const { template, values, unused } = variables\n ? toTemplate(translation.source, variables)\n : { template: translation.source, values: [], unused: [] };\n if (template !== translation.template) {\n translation.template = template;\n warnAboutUnused(unused);\n }\n\n const current = translation;\n const show = (translated: string) => {\n const rendered = fillPlaceholders(translated, values);\n current.rendered = rendered;\n if (element.getAttribute(name) !== rendered) {\n element.setAttribute(name, rendered);\n }\n };\n if (variables && current.rendered === undefined) {\n show(template);\n }\n\n const requestId = ++current.requestId;\n this.translate(template, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n show(translated);\n });\n }\n }\n}\n\n/**\n * Starts translating the page: the content of every `<t>` element (or element\n * with a `data-t` attribute), and the attributes listed in `data-t-attrs`.\n * Content added later is translated as well.\n */\nexport function createMagicTranslate(\n options: MagicTranslateOptions\n): MagicTranslate {\n return new MagicTranslate(options);\n}\n"],"mappings":";;;AAgDA,IAAaA,IAAmB,6BAEnBC,IAAsB;AAanC,SAASC,EAAU,GAA2B;CAC5C,IAAIC,IAAUC;CACd,KACE,IAAIC,IAASF,EAAQ,eAAe,QAAQH,CAAgB,GAC5DK,GACA,IAASF,EAAQ,eAAe,QAAQH,CAAgB,GAExD,IAAUK;CAEZ,OAAOF;AACT;AAEA,SAASG,EAAU,GAAoC;CACrD,IAAMC,IAA4B,CAAC,GAC7BC,IAAOJ,EAAQ,aAAa,WAAW,GACvCK,IAAYL,EAAQ,aAAa,gBAAgB;CAOvD,OANII,MACF,EAAQ,OAAOA,IAEbC,MACF,EAAQ,YAAYA,IAEfF;AACT;AAOA,SAASG,EAAY,GAAgD;CACnE,IAAMC,IAAOP,EAAQ,aAAa,QAAQ;CAC1C,IAAIO,MAAS,MAGb;MAAI;GACF,IAAMC,IAAqB,KAAK,MAAMD,CAAI;GAC1C,IACEC,KACA,OAAOA,KAAc,YACrB,CAAC,MAAM,QAAQA,CAAS,GAExB,OAAOA;EAEX,QAAQ,CAER;EAIA,OAHA,QAAQ,KACN,IAAIC,EAAY,4EAA4EF,GAC9F,GACO;CAJP;AAKF;AAEA,SAASG,EAAS,GAAc,GAAmC;CACjE,IAAIC,EAAO,WAAW,GACpB,OAAOC;CAET,IAAMC,IAAY,SAAS,cAAc,UAAU;CAGnD,OAFA,EAAU,YAAYD,GACtBE,EAAYD,EAAU,SAASF,CAAM,GAC9BE,EAAU;AACnB;AAEA,IAAaE,IAAb,MAA4B;CAS1B,YAAY,GAAiD;EAC3D,IAD2B,KAAA,UAAAZ,GALD,KAAA,2BAAA,IAAI,IAA0B,GAC5B,KAAA,6BAAA,IAAI,IAAuC,GAC5C,KAAA,4BAAA,IAAI,IAAmC,GAI9D,CAACA,EAAQ,QACX,MAAU,MAAM,sCAAsCa,GAAgB;EAUxE,AAPA,KAAK,kBACHb,EAAQ,YACRc,EACE,OAAO,YAAc,MAAc,KAAA,IAAY,UAAU,QAC3D,GACF,KAAK,aAAa,KAAK,iBAAiB,GAEpC,OAAO,WAAa,QACtB,KAAK,OAAOd,EAAQ,QAAQ,SAAS,iBACrC,KAAK,MAAM,KAAK,IAAI;CAExB;CAKA,IAAI,WAAsB;EACxB,OAAO,KAAK;CACd;CAKA,YAAY,GAA2B;EACrC,AAAIe,MAAa,KAAK,oBAItB,KAAK,kBAAkBA,GACvB,KAAK,aAAa,KAAK,iBAAiB,GAExC,KAAK,QACF,MAAY,CAAClB,EAAQ,eAAe,CAAC,KAAK,MAAM,SAASA,CAAO,CACnE,GACA,KAAK,SAAS,SAAS,GAAG,MAAY,KAAK,iBAAiBA,GAAS,EAAI,CAAC,GAC1E,KAAK,WAAW,SAAS,GAAG,MAC1B,KAAK,oBAAoBA,GAAS,EAAI,CACxC,GACA,KAAK,UAAU,SAAS,MAAamB,EAASD,CAAQ,CAAC;CACzD;CAMA,iBAAiB,GAAqD;EAEpE,OADA,KAAK,UAAU,IAAIC,CAAQ,SACd,KAAK,UAAU,OAAOA,CAAQ;CAC7C;CAKA,UACE,GACA,EAAE,MAAG,GAAGC,MAA4B,CAAC,GACpB;EACjB,IAAI,CAACC,GACH,OAAO,KAAK,WAAW,KAAK;GAAE;GAAM,GAAGD;EAAO,CAAC;EAEjD,IAAM,EAAE,aAAU,WAAQ,cAAWE,EAAWC,GAAMF,CAAC;EAEvD,OADAG,EAAgBC,CAAM,GACf,KAAK,WACT,KAAK;GAAE,MAAMC;GAAU,GAAGN;EAAO,CAAC,CAAC,CACnC,MAAM,MAAgBO,EAAiBC,GAAajB,CAAM,CAAC;CAChE;CAMA,UAAgB;EAId,AAHA,KAAK,UAAU,WAAW,GAC1B,KAAK,SAAS,MAAM,GACpB,KAAK,WAAW,MAAM,GACtB,KAAK,UAAU,MAAM;CACvB;CAEA,mBAA2B;EACzB,IAAM,EAAE,UAAO,WAAQ,mBAAgB,YAAS,iBAAc,KAAK,SAC7DkB,IAAgB,KAAK,QAAQ,kBAAkBC;EAErD,OAAO,IAAIC,EACTF,EAAc;GACZ,OAAO,CAAC,CAACG;GACT;GACA,MAAM,KAAK;GACX,YAAYC;GACZ,QAAQC;GACR;EACF,CAAC,GACD,EACE,YAAYC,EAAWC,GAAQH,GAAgB,KAAK,eAAe,EACrE,CACF;CACF;CAEA,MAAc,GAAe;EAC3B,IAAMI,oBAAW,IAAI,IAAa,GAC5BC,oBAAa,IAAI,IAAa;EASpC,AARA,KAAK,QAAQC,GAAMF,GAAUC,CAAU,GACvCD,EAAS,SAAS,MAAY,KAAK,iBAAiBrC,CAAO,CAAC,GAC5DsC,EAAW,SAAS,MAAY,KAAK,oBAAoBtC,CAAO,CAAC,GAGjE,KAAK,WAAW,IAAI,kBAAkB,MACpC,KAAK,gBAAgBwC,CAAO,CAC9B,GACA,KAAK,SAAS,QAAQD,GAAM;GAC1B,SAAS;GACT,WAAW;GACX,eAAe;GACf,YAAY;EACd,CAAC;CACH;CAEA,QACE,GACA,GACA,GACA;EACA,IAAME,IAAM,CAACF,GAAM,GAAG,MAAM,KAAKA,EAAK,iBAAiB,GAAG,CAAC,CAAC;EAC5D,KAAK,IAAMvC,KAAWyC,GACpB,AAAIzC,EAAQ,QAAA,2BAAwB,IAClCqC,EAAS,IAAIvC,EAAUE,CAAO,CAAC,IAE/BA,EAAQ,QAAA,gBAA2B,KACnC,CAACA,EAAQ,QAAA,2BAAwB,KAEjCsC,EAAW,IAAItC,CAAO;CAG5B;CAEA,gBAAwB,GAA2B;EACjD,IAAMqC,oBAAW,IAAI,IAAa,GAC5BC,oBAAa,IAAI,IAAa;EAEpC,KAAK,IAAMI,KAAUF,GAAS;GAC5B,IAAMG,IACJD,EAAO,OAAO,aAAa,KAAK,eAC3BA,EAAO,SACRA,EAAO,OAAO;GACpB,IAAI,CAACC,GACH;GAGF,IAAMC,IAAUD,EAAO,QAAQ/C,CAAgB;GAC/C,AAAIgD,IACFP,EAAS,IAAIvC,EAAU8C,CAAO,CAAC,KAI7BF,EAAO,SAAS,gBAAgBC,EAAO,QAAA,gBAA2B,KACpEL,EAAW,IAAIK,CAAM,GAEvBD,EAAO,WAAW,SAAS,MAAS;IAClC,AAAIG,EAAK,aAAa,KAAK,gBACzB,KAAK,QAAQA,GAAiBR,GAAUC,CAAU;GAEtD,CAAC;EACH;EAMA,AAJIE,EAAQ,MAAM,MAAWE,EAAO,aAAa,SAAS,CAAC,KACzD,KAAK,QAAQ,MAAY,CAAC1C,EAAQ,WAAW,GAE/CqC,EAAS,SAAS,MAAY,KAAK,iBAAiBrC,CAAO,CAAC,GAC5DsC,EAAW,SAAS,MAAY,KAAK,oBAAoBtC,CAAO,CAAC;CACnE;CAEA,OAAe,GAA0C;EACvD,KAAK,IAAMA,KAAW,KAAK,SAAS,KAAK,GACvC,AAAI8C,EAAU9C,CAAO,KACnB,KAAK,SAAS,OAAOA,CAAO;EAGhC,KAAK,IAAMA,KAAW,KAAK,WAAW,KAAK,GACzC,AAAI8C,EAAU9C,CAAO,KACnB,KAAK,WAAW,OAAOA,CAAO;CAGpC;CAEA,iBAAyB,GAAkB,IAAQ,IAAO;EACxD,IAAMY,IAAOZ,EAAQ,WACf+C,IAAgB/C,EAAQ,aAAa,QAAQ,GAC/C4B,IAAc,KAAK,SAAS,IAAI5B,CAAO;EAC3C,IAAI,CAAC4B,GAEH,AADA,IAAc;GAAE,QAAQhB;GAAM,WAAW;GAAG,WAAWmC;EAAc,GACrE,KAAK,SAAS,IAAI/C,GAAS4B,CAAW;OACjC,IAAIhB,MAASgB,EAAY,YAAYhB,MAASgB,EAAY,QAI/D,AAFA,EAAY,SAAShB,GACrB,EAAY,WAAW,KAAA,GACvB,EAAY,YAAYmC;OACnB,IAAIA,MAAkBnB,EAAY,WAEvC,EAAY,YAAYmB;OACnB,IAAI,CAACC,GACV;EAGF,IAAM,GAAGC,GAAmB1B,GAAM2B,KAChC,yBAAyB,KACvBtB,EAAY,OAAO,QAAQ,oBAAoB,EAAE,CACnD;EACF,IAAI,CAACL,GACH;EAGF,IAAMf,IAAYF,EAAYN,CAAO;EACrC,IAAIQ,MAAc,MAChB;EAEF,IAAM,EAAE,aAAU,WAAQ,cAAWA,IACjC2C,EAAe5B,GAAMf,CAAS,IAC9B;GAAE,UAAUe;GAAM,QAAQ,CAAC;GAAG,QAAQ,CAAC;EAAE;EAC7C,AAAIG,MAAaE,EAAY,aAC3B,EAAY,WAAWF,GACvBF,EAAgBC,CAAM;EAGxB,IAAM1B,IAAU6B,GACVwB,KAAQ,MAAuB;GACnC,IAAMC,IAAW,GAAGJ,IAAoBvC,EAAS4C,GAAY3C,CAAM,IAAIuC;GAIvE,AAHIlD,EAAQ,cAAcqD,MACxB,EAAQ,YAAYA,IAEtB,EAAQ,WAAWrD,EAAQ;EAC7B;EAEA,AAAIQ,KAAaT,EAAQ,aAAa,KAAA,KACpCqD,EAAK1B,CAAQ;EAIf,IAAM6B,IAAY,EAAExD,EAAQ;EAC5B,KAAK,UAAU2B,GAAUxB,EAAUF,CAAO,CAAC,CAAC,CAAC,MAAM,MAAe;GAChE,AAAIuD,MAAcxD,EAAQ,aAAcC,EAAQ,eAGhDoD,EAAKE,CAAU;EACjB,CAAC;CACH;CAEA,oBAA4B,GAAkB,IAAQ,IAAO;EAC3D,IAAME,KAASxD,EAAQ,aAAa,cAAc,KAAK,GAAA,CACpD,MAAM,QAAQ,CAAC,CACf,OAAO,OAAO,GACX+C,IAAgB/C,EAAQ,aAAa,QAAQ,GAC/CyD,IAAe,KAAK,WAAW,IAAIzD,CAAO;EAC9C,AAAKyD,MACH,oBAAe,IAAI,IAAI,GACvB,KAAK,WAAW,IAAIzD,GAASyD,CAAY;EAG3C,KAAK,IAAMC,KAAQF,GAAO;GACxB,IAAMG,IAAQ3D,EAAQ,aAAa0D,CAAI;GACvC,IAAI,CAACC,GAAO,KAAK,GACf;GAGF,IAAI/B,IAAc6B,EAAa,IAAIC,CAAI;GACvC,IAAI,CAAC9B,GAEH,AADA,IAAc;IAAE,QAAQ+B;IAAO,WAAW;IAAG,WAAWZ;GAAc,GACtEU,EAAa,IAAIC,GAAM9B,CAAW;QAC7B,IACL+B,MAAU/B,EAAY,YACtB+B,MAAU/B,EAAY,QAItB,AAFA,EAAY,SAAS+B,GACrB,EAAY,WAAW,KAAA,GACvB,EAAY,YAAYZ;QACnB,IAAIA,MAAkBnB,EAAY,WACvC,EAAY,YAAYmB;QACnB,IAAI,CAACC,GACV;GAGF,IAAMxC,IAAYF,EAAYN,CAAO;GACrC,IAAIQ,MAAc,MAChB;GAEF,IAAM,EAAE,aAAU,WAAQ,cAAWA,IACjCc,EAAWM,EAAY,QAAQpB,CAAS,IACxC;IAAE,UAAUoB,EAAY;IAAQ,QAAQ,CAAC;IAAG,QAAQ,CAAC;GAAE;GAC3D,AAAIF,MAAaE,EAAY,aAC3B,EAAY,WAAWF,GACvBF,EAAgBC,CAAM;GAGxB,IAAM1B,IAAU6B,GACVwB,KAAQ,MAAuB;IACnC,IAAMC,IAAW1B,EAAiB2B,GAAY3C,CAAM;IAEpD,AADA,EAAQ,WAAW0C,GACfrD,EAAQ,aAAa0D,CAAI,MAAML,KACjCrD,EAAQ,aAAa0D,GAAML,CAAQ;GAEvC;GACA,AAAI7C,KAAaT,EAAQ,aAAa,KAAA,KACpCqD,EAAK1B,CAAQ;GAGf,IAAM6B,IAAY,EAAExD,EAAQ;GAC5B,KAAK,UAAU2B,GAAUxB,EAAUF,CAAO,CAAC,CAAC,CAAC,MAAM,MAAe;IAChE,AAAIuD,MAAcxD,EAAQ,aAAcC,EAAQ,eAGhDoD,EAAKE,CAAU;GACjB,CAAC;EACH;CACF;AACF;AAOA,SAAgBM,EACd,GACgB;CAChB,OAAO,IAAI7C,EAAeZ,CAAO;AACnC"}
1
+ {"version":3,"file":"index.js","names":["CONTENT_SELECTOR","ATTRIBUTES_SELECTOR","outermost","current","element","parent","optionsOf","options","lang","formality","id","variablesOf","json","variables","libraryName","fillHtml","values","html","container","fillElement","MagicTranslate","libraryWebsite","utsLocaleToLanguage","language","listener","params","v","toTemplate","text","warnAboutUnused","unused","template","fillPlaceholders","translation","loaderFactory","defaultLoaderFactory","DataLoader","debug","sourceLanguage","_apiUrl","cacheKeyFn","apiKey","contents","attributes","root","records","all","record","target","content","node","predicate","variablesJson","force","leadingWhitespace","trailingWhitespace","toHtmlTemplate","show","rendered","translated","requestId","names","translations","name","value","_id","createMagicTranslate"],"sources":["../src/magic-translate.ts"],"sourcesContent":["import {\n cacheKeyFn,\n DataLoader,\n DataLoaderLoadParams,\n defaultLoaderFactory,\n fillElement,\n fillPlaceholders,\n Language,\n libraryName,\n libraryWebsite,\n MagicTranslateConfig,\n toHtmlTemplate,\n toTemplate,\n TextOptions,\n TranslateOptions,\n utsLocaleToLanguage,\n Variables,\n warnAboutUnused,\n} from '@magic-translate/core';\n\n/**\n * Type alias to make the language enum more flexible to also allow passing language strings\n * instead of just the enum.\n */\nexport type Languages = `${Language}`;\n\nexport interface TranslateParams extends Omit<DataLoaderLoadParams, 'text'> {\n /**\n * Values that are not translated, referenced as `$name` in the text. The text\n * is translated once as a template and cached, whatever the values are.\n */\n v?: Variables;\n}\n\nexport interface MagicTranslateOptions extends Omit<\n MagicTranslateConfig,\n 'language'\n> {\n /**\n * The language content is translated to. Defaults to the browser's language.\n */\n language?: Languages;\n /**\n * The element whose content is translated. Defaults to the whole document.\n */\n root?: Element;\n}\n\n/** Elements whose content is translated. */\nexport const CONTENT_SELECTOR = 't, mt-translate, [data-t]';\n/** Elements with attributes to translate, e.g. `data-t-attrs=\"placeholder title\"`. */\nexport const ATTRIBUTES_SELECTOR = '[data-t-attrs]';\n\ninterface Translation {\n source: string;\n // what was last written to the DOM, to tell our own changes from others\n rendered?: string;\n requestId: number;\n // the `data-v` attribute the source was last translated with\n variables: string | null;\n // to warn about unused variables once per text, not on every render\n template?: string;\n}\n\nfunction outermost(element: Element): Element {\n let current = element;\n for (\n let parent = current.parentElement?.closest(CONTENT_SELECTOR);\n parent;\n parent = current.parentElement?.closest(CONTENT_SELECTOR)\n ) {\n current = parent;\n }\n return current;\n}\n\nfunction optionsOf(element: Element): TextOptions {\n const options: TextOptions = {};\n const lang = element.getAttribute('data-lang');\n const formality = element.getAttribute('data-formality');\n const id = element.getAttribute('data-t-id');\n if (lang) {\n options.lang = lang as Languages;\n }\n if (formality) {\n options.formality = formality as TranslateOptions['formality'];\n }\n if (id) {\n options.id = id;\n }\n return options;\n}\n\n/**\n * Reads the values in `data-v`, a JSON object such as `{\"name\": \"Bob\"}`.\n * Returns `null` if the attribute is not valid, so the text is left as it is\n * rather than translated with `$name` in it.\n */\nfunction variablesOf(element: Element): Variables | undefined | null {\n const json = element.getAttribute('data-v');\n if (json === null) {\n return undefined;\n }\n try {\n const variables: unknown = JSON.parse(json);\n if (\n variables &&\n typeof variables === 'object' &&\n !Array.isArray(variables)\n ) {\n return variables as Variables;\n }\n } catch {\n // reported below\n }\n console.warn(\n `[${libraryName}]: data-v must be a JSON object, such as data-v='{\"name\": \"Bob\"}', but is ${json}`\n );\n return null;\n}\n\nfunction fillHtml(html: string, values: readonly string[]): string {\n if (values.length === 0) {\n return html;\n }\n const container = document.createElement('template');\n container.innerHTML = html;\n fillElement(container.content, values);\n return container.innerHTML;\n}\n\nexport class MagicTranslate {\n private currentLanguage: Languages;\n private dataLoader: DataLoader<DataLoaderLoadParams, string, string>;\n private readonly root?: Element;\n private readonly contents = new Map<Element, Translation>();\n private readonly attributes = new Map<Element, Map<string, Translation>>();\n private readonly listeners = new Set<(language: Languages) => void>();\n private observer?: MutationObserver;\n\n constructor(private readonly options: MagicTranslateOptions) {\n if (!options.apiKey) {\n throw new Error(`Missing API key. Please get one at ${libraryWebsite}`);\n }\n\n this.currentLanguage =\n options.language ??\n utsLocaleToLanguage(\n typeof navigator === 'undefined' ? undefined : navigator.language\n );\n this.dataLoader = this.createDataLoader();\n\n if (typeof document !== 'undefined') {\n this.root = options.root ?? document.documentElement;\n this.start(this.root);\n }\n }\n\n /**\n * The language content is currently translated to.\n */\n get language(): Languages {\n return this.currentLanguage;\n }\n\n /**\n * Translates the page to another language.\n */\n setLanguage(language: Languages): void {\n if (language === this.currentLanguage) {\n return;\n }\n\n this.currentLanguage = language;\n this.dataLoader = this.createDataLoader();\n\n this.forget(\n (element) => !element.isConnected || !this.root?.contains(element)\n );\n this.contents.forEach((_, element) => this.translateContent(element, true));\n this.attributes.forEach((_, element) =>\n this.translateAttributes(element, true)\n );\n this.listeners.forEach((listener) => listener(language));\n }\n\n /**\n * Calls `listener` whenever the language changes. Returns a function that\n * removes the listener again.\n */\n onLanguageChange(listener: (language: Languages) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Translates a string to the current language.\n */\n translate(\n text: string,\n { v, ...params }: TranslateParams = {}\n ): Promise<string> {\n if (!v) {\n return this.dataLoader.load({ text, ...params });\n }\n const { template, values, unused } = toTemplate(text, v);\n warnAboutUnused(unused);\n return this.dataLoader\n .load({ text: template, ...params })\n .then((translation) => fillPlaceholders(translation, values));\n }\n\n /**\n * Stops translating the page. Content that is already translated stays\n * translated.\n */\n destroy(): void {\n this.observer?.disconnect();\n this.contents.clear();\n this.attributes.clear();\n this.listeners.clear();\n }\n\n private createDataLoader() {\n const { debug, apiKey, sourceLanguage, _apiUrl, formality } = this.options;\n const loaderFactory = this.options._loaderFactory ?? defaultLoaderFactory;\n\n return new DataLoader<DataLoaderLoadParams, string, string>(\n loaderFactory({\n debug: !!debug,\n apiKey,\n lang: this.currentLanguage,\n sourceLang: sourceLanguage,\n apiUrl: _apiUrl,\n formality,\n }),\n {\n cacheKeyFn: cacheKeyFn(apiKey, sourceLanguage, this.currentLanguage),\n }\n );\n }\n\n private start(root: Element) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n this.collect(root, contents, attributes);\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n\n // Picks up content that is added or changed later.\n this.observer = new MutationObserver((records) =>\n this.handleMutations(records)\n );\n this.observer.observe(root, {\n subtree: true,\n childList: true,\n characterData: true,\n attributes: true,\n });\n }\n\n private collect(\n root: Element,\n contents: Set<Element>,\n attributes: Set<Element>\n ) {\n const all = [root, ...Array.from(root.querySelectorAll('*'))];\n for (const element of all) {\n if (element.matches(CONTENT_SELECTOR)) {\n contents.add(outermost(element));\n } else if (\n element.matches(ATTRIBUTES_SELECTOR) &&\n !element.closest(CONTENT_SELECTOR)\n ) {\n attributes.add(element);\n }\n }\n }\n\n private handleMutations(records: MutationRecord[]) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n\n for (const record of records) {\n const target =\n record.target.nodeType === Node.ELEMENT_NODE\n ? (record.target as Element)\n : record.target.parentElement;\n if (!target) {\n continue;\n }\n\n const content = target.closest(CONTENT_SELECTOR);\n if (content) {\n contents.add(outermost(content));\n continue;\n }\n\n if (record.type === 'attributes' && target.matches(ATTRIBUTES_SELECTOR)) {\n attributes.add(target);\n }\n record.addedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n this.collect(node as Element, contents, attributes);\n }\n });\n }\n\n if (records.some((record) => record.removedNodes.length > 0)) {\n this.forget((element) => !element.isConnected);\n }\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n }\n\n private forget(predicate: (element: Element) => boolean) {\n for (const element of this.contents.keys()) {\n if (predicate(element)) {\n this.contents.delete(element);\n }\n }\n for (const element of this.attributes.keys()) {\n if (predicate(element)) {\n this.attributes.delete(element);\n }\n }\n }\n\n private translateContent(element: Element, force = false) {\n const html = element.innerHTML;\n const variablesJson = element.getAttribute('data-v');\n let translation = this.contents.get(element);\n if (!translation) {\n translation = { source: html, requestId: 0, variables: variablesJson };\n this.contents.set(element, translation);\n } else if (html !== translation.rendered && html !== translation.source) {\n // changed by someone else, e.g. the page's own scripts\n translation.source = html;\n translation.rendered = undefined;\n translation.variables = variablesJson;\n } else if (variablesJson !== translation.variables) {\n // only the values changed, so the cached translation is reused\n translation.variables = variablesJson;\n } else if (!force) {\n return;\n }\n\n const [, leadingWhitespace, text, trailingWhitespace] =\n /^(\\s*)([\\s\\S]*?)(\\s*)$/.exec(\n translation.source.replace(/<!--[\\s\\S]*?-->/g, '')\n )!;\n if (!text) {\n return;\n }\n\n const variables = variablesOf(element);\n if (variables === null) {\n return;\n }\n const { template, values, unused } = variables\n ? toHtmlTemplate(text, variables)\n : { template: text, values: [], unused: [] };\n if (template !== translation.template) {\n translation.template = template;\n warnAboutUnused(unused);\n }\n\n const current = translation;\n const show = (translated: string) => {\n const rendered = `${leadingWhitespace}${fillHtml(translated, values)}${trailingWhitespace}`;\n if (element.innerHTML !== rendered) {\n element.innerHTML = rendered;\n }\n current.rendered = element.innerHTML;\n };\n // Until the first translation arrives, show the values instead of `$name`.\n if (variables && current.rendered === undefined) {\n show(template);\n }\n\n // make sure that we only ever use the response of the most recent request.\n const requestId = ++current.requestId;\n this.translate(template, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n show(translated);\n });\n }\n\n private translateAttributes(element: Element, force = false) {\n const names = (element.getAttribute('data-t-attrs') ?? '')\n .split(/[\\s,]+/)\n .filter(Boolean);\n const variablesJson = element.getAttribute('data-v');\n let translations = this.attributes.get(element);\n if (!translations) {\n translations = new Map();\n this.attributes.set(element, translations);\n }\n\n for (const name of names) {\n const value = element.getAttribute(name);\n if (!value?.trim()) {\n continue;\n }\n\n let translation = translations.get(name);\n if (!translation) {\n translation = { source: value, requestId: 0, variables: variablesJson };\n translations.set(name, translation);\n } else if (\n value !== translation.rendered &&\n value !== translation.source\n ) {\n translation.source = value;\n translation.rendered = undefined;\n translation.variables = variablesJson;\n } else if (variablesJson !== translation.variables) {\n translation.variables = variablesJson;\n } else if (!force) {\n continue;\n }\n\n const variables = variablesOf(element);\n if (variables === null) {\n continue;\n }\n const { template, values, unused } = variables\n ? toTemplate(translation.source, variables)\n : { template: translation.source, values: [], unused: [] };\n if (template !== translation.template) {\n translation.template = template;\n warnAboutUnused(unused);\n }\n\n const current = translation;\n const show = (translated: string) => {\n const rendered = fillPlaceholders(translated, values);\n current.rendered = rendered;\n if (element.getAttribute(name) !== rendered) {\n element.setAttribute(name, rendered);\n }\n };\n if (variables && current.rendered === undefined) {\n show(template);\n }\n\n const requestId = ++current.requestId;\n // An id stands for one text, and an element's attributes are several.\n const { id: _id, ...options } = optionsOf(element);\n this.translate(template, options).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n show(translated);\n });\n }\n }\n}\n\n/**\n * Starts translating the page: the content of every `<t>` element (or element\n * with a `data-t` attribute), and the attributes listed in `data-t-attrs`.\n * Content added later is translated as well.\n */\nexport function createMagicTranslate(\n options: MagicTranslateOptions\n): MagicTranslate {\n return new MagicTranslate(options);\n}\n"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
- var MagicTranslate=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=`Magic Translate`,n=`https://magictranslate.io`,r;function i(e){return Object.keys(e).filter(t=>e[t]!==void 0).reduce((t,n)=>({...t,[n]:e[n]}),{})}function a(e){let t=new URLSearchParams,n=(e,r=``)=>{Array.isArray(e)?e.forEach((e,t)=>{n(e,r?`${r}[${t}]`:`[${t}]`)}):typeof e==`object`&&e?Object.entries(e).forEach(([e,t])=>{n(t,r?`${r}.${e}`:e)}):t.append(r,e)};return n(e),t}(function(e){e.AF=`af`,e.SQ=`sq`,e.AM=`am`,e.AR=`ar`,e.HY=`hy`,e.AZ=`az`,e.BN=`bn`,e.BS=`bs`,e.BG=`bg`,e.CA=`ca`,e.ZH=`zh`,e.ZH_TW=`zh-TW`,e.HR=`hr`,e.CS=`cs`,e.DA=`da`,e.FA_AF=`fa-AF`,e.NL=`nl`,e.EN=`en`,e.ET=`et`,e.FA=`fa`,e.TL=`tl`,e.FI=`fi`,e.FR=`fr`,e.FR_CA=`fr-CA`,e.KA=`ka`,e.DE=`de`,e.EL=`el`,e.GU=`gu`,e.HT=`ht`,e.HA=`ha`,e.HE=`he`,e.HI=`hi`,e.HU=`hu`,e.IS=`is`,e.ID=`id`,e.GA=`ga`,e.IT=`it`,e.JA=`ja`,e.KN=`kn`,e.KK=`kk`,e.KO=`ko`,e.LV=`lv`,e.LT=`lt`,e.MK=`mk`,e.MS=`ms`,e.ML=`ml`,e.MT=`mt`,e.MR=`mr`,e.MN=`mn`,e.NO=`no`,e.PS=`ps`,e.PL=`pl`,e.PT=`pt`,e.PT_PT=`pt-PT`,e.PA=`pa`,e.RO=`ro`,e.RU=`ru`,e.SR=`sr`,e.SI=`si`,e.SK=`sk`,e.SL=`sl`,e.SO=`so`,e.ES=`es`,e.ES_MX=`es-MX`,e.SW=`sw`,e.SV=`sv`,e.TA=`ta`,e.TE=`te`,e.TH=`th`,e.TR=`tr`,e.UK=`uk`,e.UR=`ur`,e.UZ=`uz`,e.VI=`vi`,e.CY=`cy`})(r||={});var o={debug:!1,apiUrl:`https://api.magictranslate.io`,lang:r.DE},s;(function(e){e.QUOTA_EXCEEDED_ERROR=`QUOTA_EXCEEDED_ERROR`})(s||={});var c=(e,t,n)=>r=>Object.entries(i({apiKey:e,language:n,sourceLanguage:r.sourceLang??t??`auto`,...r})).sort(([e])=>e.localeCompare(e)).reduce((e,t)=>`${e};${t.join(`=`)}`,``),l=e=>async n=>{if(e.debug&&console.debug(`[Magic Translate]: batch function called with: `,n),e.lang===e.sourceLang)return n.map(e=>e.text);let{apiKey:r,lang:s,formality:c}=e,l=i({apiKey:r,lang:s,formality:c,items:n.map(({text:e,sourceLang:t,lang:n,...r})=>i({text:e,lang:n,sourceLang:t,...r}))});return fetch(`${e.apiUrl??o.apiUrl}/v1/translate`,{method:`POST`,body:e.useJson?JSON.stringify(l):a(l),headers:{"Content-Type":e.useJson?`application/json`:`application/x-www-form-urlencoded`}}).then(e=>e.json()).then(e=>`results`in e?e.results:(`code`in e?console.error(`[${t}]: ${e.message}`):console.error(`[${t}]: Unexpected payload from magic translate server: ${JSON.stringify(e)}`),n.map(e=>e.text))).catch(e=>(console.error(`[${t}]: Error while loading translations: `,e),n.map(e=>e.text)))};function u(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,`default`)?e.default:e}var d,f,p=u(function(){if(f)return d;f=1;var e,t=function(){function e(e,t){if(typeof e!=`function`)throw TypeError(`DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but got: `+e+`.`);this._batchLoadFn=e,this._maxBatchSize=function(e){if(e&&!1===e.batch)return 1;var t=e&&e.maxBatchSize;if(t===void 0)return 1/0;if(typeof t!=`number`||t<1)throw TypeError(`maxBatchSize must be a positive number: `+t);return t}(t),this._batchScheduleFn=function(e){var t=e&&e.batchScheduleFn;if(t===void 0)return n;if(typeof t!=`function`)throw TypeError(`batchScheduleFn must be a function: `+t);return t}(t),this._cacheKeyFn=function(e){var t=e&&e.cacheKeyFn;if(t===void 0)return function(e){return e};if(typeof t!=`function`)throw TypeError(`cacheKeyFn must be a function: `+t);return t}(t),this._cacheMap=function(e){if(e&&!1===e.cache)return null;var t=e&&e.cacheMap;if(t===void 0)return new Map;if(t!==null){var n=[`get`,`set`,`delete`,`clear`].filter(function(e){return t&&typeof t[e]!=`function`});if(n.length!==0)throw TypeError(`Custom cacheMap missing methods: `+n.join(`, `))}return t}(t),this._batch=null,this.name=function(e){return e&&e.name?e.name:null}(t)}var t=e.prototype;return t.load=function(e){if(e==null)throw TypeError(`The loader.load() function must be called with a value, but got: `+String(e)+`.`);var t,n=function(e){var t=e._batch;if(t!==null&&!t.hasDispatched&&t.keys.length<e._maxBatchSize)return t;var n={hasDispatched:!1,keys:[],callbacks:[]};return e._batch=n,e._batchScheduleFn(function(){(function(e,t){if(t.hasDispatched=!0,t.keys.length===0)return void i(t);var n;try{n=e._batchLoadFn(t.keys)}catch(n){return r(e,t,TypeError(`DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function errored synchronously: `+String(n)+`.`))}if(!n||typeof n.then!=`function`)return r(e,t,TypeError(`DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise: `+String(n)+`.`));n.then(function(e){if(!a(e))throw TypeError(`DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise of an Array: `+String(e)+`.`);if(e.length!==t.keys.length)throw TypeError(`DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise of an Array of the same length as the Array of keys.
1
+ var MagicTranslate=(function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=`Magic Translate`,n=`https://magictranslate.io`,r;function i(e){return Object.keys(e).filter(t=>e[t]!==void 0).reduce((t,n)=>({...t,[n]:e[n]}),{})}function a(e){let t=new URLSearchParams,n=(e,r=``)=>{Array.isArray(e)?e.forEach((e,t)=>{n(e,r?`${r}[${t}]`:`[${t}]`)}):typeof e==`object`&&e?Object.entries(e).forEach(([e,t])=>{n(t,r?`${r}.${e}`:e)}):t.append(r,e)};return n(e),t}(function(e){e.AF=`af`,e.SQ=`sq`,e.AM=`am`,e.AR=`ar`,e.HY=`hy`,e.AZ=`az`,e.BN=`bn`,e.BS=`bs`,e.BG=`bg`,e.CA=`ca`,e.ZH=`zh`,e.ZH_TW=`zh-TW`,e.HR=`hr`,e.CS=`cs`,e.DA=`da`,e.FA_AF=`fa-AF`,e.NL=`nl`,e.EN=`en`,e.ET=`et`,e.FA=`fa`,e.TL=`tl`,e.FI=`fi`,e.FR=`fr`,e.FR_CA=`fr-CA`,e.KA=`ka`,e.DE=`de`,e.EL=`el`,e.GU=`gu`,e.HT=`ht`,e.HA=`ha`,e.HE=`he`,e.HI=`hi`,e.HU=`hu`,e.IS=`is`,e.ID=`id`,e.GA=`ga`,e.IT=`it`,e.JA=`ja`,e.KN=`kn`,e.KK=`kk`,e.KO=`ko`,e.LV=`lv`,e.LT=`lt`,e.MK=`mk`,e.MS=`ms`,e.ML=`ml`,e.MT=`mt`,e.MR=`mr`,e.MN=`mn`,e.NO=`no`,e.PS=`ps`,e.PL=`pl`,e.PT=`pt`,e.PT_PT=`pt-PT`,e.PA=`pa`,e.RO=`ro`,e.RU=`ru`,e.SR=`sr`,e.SI=`si`,e.SK=`sk`,e.SL=`sl`,e.SO=`so`,e.ES=`es`,e.ES_MX=`es-MX`,e.SW=`sw`,e.SV=`sv`,e.TA=`ta`,e.TE=`te`,e.TH=`th`,e.TR=`tr`,e.UK=`uk`,e.UR=`ur`,e.UZ=`uz`,e.VI=`vi`,e.CY=`cy`})(r||={});var o=`MAGIC_TRANSLATE_SECRET_KEY`,s=e=>!!e?.startsWith(`p-`);function c(){let{process:e}=globalThis;return e?.env?.MAGIC_TRANSLATE_SECRET_KEY||void 0}var l=!1;function u({apiKey:e,secretKey:t}){return typeof window>`u`?t||c()||e:(!t&&!s(e)||l||(l=!0,console.error(`[Magic Translate]: Secret keys only work on servers, so this one was not sent. Use your public API key in the browser, and regenerate your secret key at https://magictranslate.io/account since it is exposed.`)),s(e)?void 0:e)}var d=128,f={debug:!1,apiUrl:`https://api.magictranslate.io`,lang:r.DE},p;function m(e){if(e!==void 0)return e.trim()&&e.length<=128?e:void console.error(`[${t}]: Ignoring the id "${e}". Ids must be 1 to 128 characters.`)}(function(e){e.QUOTA_EXCEEDED_ERROR=`QUOTA_EXCEEDED_ERROR`,e.SECRET_KEY_REQUIRED=`SECRET_KEY_REQUIRED`,e.SECRET_KEY_IN_BROWSER=`SECRET_KEY_IN_BROWSER`})(p||={});var h=(e,t,n)=>r=>Object.entries(i({apiKey:e,language:n,sourceLanguage:r.sourceLang??t??`auto`,...r})).sort(([e])=>e.localeCompare(e)).reduce((e,t)=>`${e};${t.join(`=`)}`,``),g=e=>async n=>{if(e.debug&&console.debug(`[Magic Translate]: batch function called with: `,n),e.lang===e.sourceLang)return n.map(e=>e.text);let{lang:r,formality:o}=e,s=u(e);if(!s)return e.apiKey||e.secretKey||console.error(`[Magic Translate]: Missing API key. Please get one at https://magictranslate.io`),n.map(e=>e.text);let c=i({apiKey:s,lang:r,formality:o,items:n.map(({text:e,sourceLang:t,lang:n,id:r,...a})=>i({text:e,lang:n,sourceLang:t,...a,id:m(r)}))});return fetch(`${e.apiUrl??f.apiUrl}/v1/translate`,{method:`POST`,body:e.useJson?JSON.stringify(c):a(c),headers:{"Content-Type":e.useJson?`application/json`:`application/x-www-form-urlencoded`}}).then(e=>e.json()).then(e=>`results`in e?e.results:(`code`in e?console.error(`[${t}]: ${e.message}`):console.error(`[${t}]: Unexpected payload from magic translate server: ${JSON.stringify(e)}`),n.map(e=>e.text))).catch(e=>(console.error(`[${t}]: Error while loading translations: `,e),n.map(e=>e.text)))};function _(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,`default`)?e.default:e}var v,y,b=_(function(){if(y)return v;y=1;var e,t=function(){function e(e,t){if(typeof e!=`function`)throw TypeError(`DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but got: `+e+`.`);this._batchLoadFn=e,this._maxBatchSize=function(e){if(e&&!1===e.batch)return 1;var t=e&&e.maxBatchSize;if(t===void 0)return 1/0;if(typeof t!=`number`||t<1)throw TypeError(`maxBatchSize must be a positive number: `+t);return t}(t),this._batchScheduleFn=function(e){var t=e&&e.batchScheduleFn;if(t===void 0)return n;if(typeof t!=`function`)throw TypeError(`batchScheduleFn must be a function: `+t);return t}(t),this._cacheKeyFn=function(e){var t=e&&e.cacheKeyFn;if(t===void 0)return function(e){return e};if(typeof t!=`function`)throw TypeError(`cacheKeyFn must be a function: `+t);return t}(t),this._cacheMap=function(e){if(e&&!1===e.cache)return null;var t=e&&e.cacheMap;if(t===void 0)return new Map;if(t!==null){var n=[`get`,`set`,`delete`,`clear`].filter(function(e){return t&&typeof t[e]!=`function`});if(n.length!==0)throw TypeError(`Custom cacheMap missing methods: `+n.join(`, `))}return t}(t),this._batch=null,this.name=function(e){return e&&e.name?e.name:null}(t)}var t=e.prototype;return t.load=function(e){if(e==null)throw TypeError(`The loader.load() function must be called with a value, but got: `+String(e)+`.`);var t,n=function(e){var t=e._batch;if(t!==null&&!t.hasDispatched&&t.keys.length<e._maxBatchSize)return t;var n={hasDispatched:!1,keys:[],callbacks:[]};return e._batch=n,e._batchScheduleFn(function(){(function(e,t){if(t.hasDispatched=!0,t.keys.length===0)return void i(t);var n;try{n=e._batchLoadFn(t.keys)}catch(n){return r(e,t,TypeError(`DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function errored synchronously: `+String(n)+`.`))}if(!n||typeof n.then!=`function`)return r(e,t,TypeError(`DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise: `+String(n)+`.`));n.then(function(e){if(!a(e))throw TypeError(`DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise of an Array: `+String(e)+`.`);if(e.length!==t.keys.length)throw TypeError(`DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise of an Array of the same length as the Array of keys.
2
2
 
3
3
  Keys:
4
4
  `+String(t.keys)+`
5
5
 
6
6
  Values:
7
- `+String(e));i(t);for(var n=0;n<t.callbacks.length;n++){var r=e[n];r instanceof Error?t.callbacks[n].reject(r):t.callbacks[n].resolve(r)}}).catch(function(n){r(e,t,n)})})(e,n)}),n}(this),o=this._cacheMap;if(o){t=this._cacheKeyFn(e);var s=o.get(t);if(s){var c=n.cacheHits||=[];return new Promise(function(e){c.push(function(){e(s)})})}}n.keys.push(e);var l=new Promise(function(e,t){n.callbacks.push({resolve:e,reject:t})});return o&&o.set(t,l),l},t.loadMany=function(e){if(!a(e))throw TypeError(`The loader.loadMany() function must be called with Array<key> but got: `+e+`.`);for(var t=[],n=0;n<e.length;n++)t.push(this.load(e[n]).catch(function(e){return e}));return Promise.all(t)},t.clear=function(e){var t=this._cacheMap;if(t){var n=this._cacheKeyFn(e);t.delete(n)}return this},t.clearAll=function(){var e=this._cacheMap;return e&&e.clear(),this},t.prime=function(e,t){var n=this._cacheMap;if(n){var r,i=this._cacheKeyFn(e);n.get(i)===void 0&&(t instanceof Error?(r=Promise.reject(t)).catch(function(){}):r=Promise.resolve(t),n.set(i,r))}return this},e}(),n=typeof process==`object`&&typeof process.nextTick==`function`?function(t){e||=Promise.resolve(),e.then(function(){process.nextTick(t)})}:typeof setImmediate==`function`?function(e){setImmediate(e)}:function(e){setTimeout(e)};function r(e,t,n){i(t);for(var r=0;r<t.keys.length;r++)e.clear(t.keys[r]),t.callbacks[r].reject(n)}function i(e){if(e.cacheHits)for(var t=0;t<e.cacheHits.length;t++)e.cacheHits[t]()}function a(e){return typeof e==`object`&&!!e&&typeof e.length==`number`&&(e.length===0||e.length>0&&Object.prototype.hasOwnProperty.call(e,e.length-1))}return d=t}());function m({debug:e,apiKey:t,sourceLanguage:n,_apiUrl:i,formality:a,_loaderFactory:o}){let s={debug:!!e,apiKey:t,lang:r.EN,sourceLang:n,apiUrl:i,formality:a},u=new p((o??l)(s),{cacheKeyFn:c(t,n)});return(e,t,n)=>u.load({text:t,...n,lang:e})}var h=m,g=r.EN;function _(e,t){if(!e)return t??g;if([r.FA_AF,r.FR_CA,r.PT_PT,r.ES_MX].includes(e))return e;let n=e.includes(`-`)?e.split(`-`)[0]:e;return Object.values(r).includes(n)?n:t||(console.warn(`Language not found for UTS locale "${e}" and no fallback provided was provided. Falling back to "${g}"`),g)}var v=/\{(\d+)\}/g,y=e=>e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`);function b(e){let t=Object.keys(e).sort((e,t)=>t.length-e.length),n=t.length>0?RegExp(`\\$(${t.map(y).join(`|`)})`,`g`):null,r=new Map,i=[];return{values:i,replace:t=>n?t.replace(n,(t,n)=>{let a=r.get(n);return a===void 0&&(a=i.push(String(e[n]??``))-1,r.set(n,a)),`{${a}}`}):t,unused:()=>t.filter(e=>!r.has(e))}}function x(e){e.length>0&&console.warn(`[Magic Translate]: ${e.map(e=>`$${e}`).join(`, `)} not found in the text. Check the spelling, or remove ${e.length===1?`it`:`them`} from the variables.`)}function S(e,t){let{replace:n,values:r,unused:i}=b(t);return{template:n(e),values:r,unused:i()}}function C(e,t){return e.replace(v,(e,n)=>Number(n)<t.length?t[Number(n)]:e)}function w(e){let t=document.createTreeWalker(e,NodeFilter.SHOW_TEXT),n=[];for(let e=t.nextNode();e;e=t.nextNode())n.push(e);return n}function T(e,t){let n=document.createElement(`template`);n.innerHTML=e;let{replace:r,values:i,unused:a}=b(t);return w(n.content).forEach(e=>{e.data=r(e.data)}),{template:n.innerHTML,values:i,unused:a()}}function E(e,t){w(e).forEach(e=>{let n=C(e.data,t);n!==e.data&&(e.data=n)})}var D=`t, mt-translate, [data-t]`,O=`[data-t-attrs]`;function k(e){let t=e;for(let e=t.parentElement?.closest(D);e;e=t.parentElement?.closest(D))t=e;return t}function A(e){let t={},n=e.getAttribute(`data-lang`),r=e.getAttribute(`data-formality`);return n&&(t.lang=n),r&&(t.formality=r),t}function j(e){let n=e.getAttribute(`data-v`);if(n!==null){try{let e=JSON.parse(n);if(e&&typeof e==`object`&&!Array.isArray(e))return e}catch{}return console.warn(`[${t}]: data-v must be a JSON object, such as data-v='{"name": "Bob"}', but is ${n}`),null}}function M(e,t){if(t.length===0)return e;let n=document.createElement(`template`);return n.innerHTML=e,E(n.content,t),n.innerHTML}var N=class{constructor(e){if(this.options=e,this.contents=new Map,this.attributes=new Map,this.listeners=new Set,!e.apiKey)throw Error(`Missing API key. Please get one at ${n}`);this.currentLanguage=e.language??_(typeof navigator>`u`?void 0:navigator.language),this.dataLoader=this.createDataLoader(),typeof document<`u`&&(this.root=e.root??document.documentElement,this.start(this.root))}get language(){return this.currentLanguage}setLanguage(e){e!==this.currentLanguage&&(this.currentLanguage=e,this.dataLoader=this.createDataLoader(),this.forget(e=>!e.isConnected||!this.root?.contains(e)),this.contents.forEach((e,t)=>this.translateContent(t,!0)),this.attributes.forEach((e,t)=>this.translateAttributes(t,!0)),this.listeners.forEach(t=>t(e)))}onLanguageChange(e){return this.listeners.add(e),()=>this.listeners.delete(e)}translate(e,{v:t,...n}={}){if(!t)return this.dataLoader.load({text:e,...n});let{template:r,values:i,unused:a}=S(e,t);return x(a),this.dataLoader.load({text:r,...n}).then(e=>C(e,i))}destroy(){this.observer?.disconnect(),this.contents.clear(),this.attributes.clear(),this.listeners.clear()}createDataLoader(){let{debug:e,apiKey:t,sourceLanguage:n,_apiUrl:r,formality:i}=this.options;return new p((this.options._loaderFactory??l)({debug:!!e,apiKey:t,lang:this.currentLanguage,sourceLang:n,apiUrl:r,formality:i}),{cacheKeyFn:c(t,n,this.currentLanguage)})}start(e){let t=new Set,n=new Set;this.collect(e,t,n),t.forEach(e=>this.translateContent(e)),n.forEach(e=>this.translateAttributes(e)),this.observer=new MutationObserver(e=>this.handleMutations(e)),this.observer.observe(e,{subtree:!0,childList:!0,characterData:!0,attributes:!0})}collect(e,t,n){let r=[e,...Array.from(e.querySelectorAll(`*`))];for(let e of r)e.matches(`t, mt-translate, [data-t]`)?t.add(k(e)):e.matches(`[data-t-attrs]`)&&!e.closest(`t, mt-translate, [data-t]`)&&n.add(e)}handleMutations(e){let t=new Set,n=new Set;for(let r of e){let e=r.target.nodeType===Node.ELEMENT_NODE?r.target:r.target.parentElement;if(!e)continue;let i=e.closest(D);i?t.add(k(i)):(r.type===`attributes`&&e.matches(`[data-t-attrs]`)&&n.add(e),r.addedNodes.forEach(e=>{e.nodeType===Node.ELEMENT_NODE&&this.collect(e,t,n)}))}e.some(e=>e.removedNodes.length>0)&&this.forget(e=>!e.isConnected),t.forEach(e=>this.translateContent(e)),n.forEach(e=>this.translateAttributes(e))}forget(e){for(let t of this.contents.keys())e(t)&&this.contents.delete(t);for(let t of this.attributes.keys())e(t)&&this.attributes.delete(t)}translateContent(e,t=!1){let n=e.innerHTML,r=e.getAttribute(`data-v`),i=this.contents.get(e);if(!i)i={source:n,requestId:0,variables:r},this.contents.set(e,i);else if(n!==i.rendered&&n!==i.source)i.source=n,i.rendered=void 0,i.variables=r;else if(r!==i.variables)i.variables=r;else if(!t)return;let[,a,o,s]=/^(\s*)([\s\S]*?)(\s*)$/.exec(i.source.replace(/<!--[\s\S]*?-->/g,``));if(!o)return;let c=j(e);if(c===null)return;let{template:l,values:u,unused:d}=c?T(o,c):{template:o,values:[],unused:[]};l!==i.template&&(i.template=l,x(d));let f=i,p=t=>{let n=`${a}${M(t,u)}${s}`;e.innerHTML!==n&&(e.innerHTML=n),f.rendered=e.innerHTML};c&&f.rendered===void 0&&p(l);let m=++f.requestId;this.translate(l,A(e)).then(t=>{m===f.requestId&&e.isConnected&&p(t)})}translateAttributes(e,t=!1){let n=(e.getAttribute(`data-t-attrs`)??``).split(/[\s,]+/).filter(Boolean),r=e.getAttribute(`data-v`),i=this.attributes.get(e);i||(i=new Map,this.attributes.set(e,i));for(let a of n){let n=e.getAttribute(a);if(!n?.trim())continue;let o=i.get(a);if(!o)o={source:n,requestId:0,variables:r},i.set(a,o);else if(n!==o.rendered&&n!==o.source)o.source=n,o.rendered=void 0,o.variables=r;else if(r!==o.variables)o.variables=r;else if(!t)continue;let s=j(e);if(s===null)continue;let{template:c,values:l,unused:u}=s?S(o.source,s):{template:o.source,values:[],unused:[]};c!==o.template&&(o.template=c,x(u));let d=o,f=t=>{let n=C(t,l);d.rendered=n,e.getAttribute(a)!==n&&e.setAttribute(a,n)};s&&d.rendered===void 0&&f(c);let p=++d.requestId;this.translate(c,A(e)).then(t=>{p===d.requestId&&e.isConnected&&f(t)})}}};function P(e){return new N(e)}var F=`magic-translate-language`;function I(){try{return localStorage.getItem(F)??void 0}catch{return}}var L=document.currentScript,R=L?.dataset.apiKey;if(L&&R){let{language:e,sourceLanguage:t,formality:n}=L.dataset,r=()=>{let r=P({apiKey:R,language:I()??e,sourceLanguage:t,formality:n,debug:L.hasAttribute(`data-debug`)});r.onLanguageChange(e=>{try{localStorage.setItem(F,e)}catch{}}),window.magicTranslate=r,document.dispatchEvent(new CustomEvent(`magictranslate:ready`,{detail:r}))};document.readyState===`loading`?document.addEventListener(`DOMContentLoaded`,r):r()}return e.ATTRIBUTES_SELECTOR=O,e.CONTENT_SELECTOR=D,e.DataLoader=p,Object.defineProperty(e,"Language",{enumerable:!0,get:function(){return r}}),e.MagicTranslate=N,e.cacheKeyFn=c,e.createMagicTranslate=P,e.defaultDataLoaderOptions=o,e.defaultLoaderFactory=l,e.fillElement=E,e.fillPlaceholders=C,e.libraryName=t,e.libraryWebsite=n,e.setupT=h,e.setupTranslate=m,e.templater=b,e.toHtmlTemplate=T,e.toTemplate=S,e.utsLocaleToLanguage=_,e.warnAboutUnused=x,e})({});
7
+ `+String(e));i(t);for(var n=0;n<t.callbacks.length;n++){var r=e[n];r instanceof Error?t.callbacks[n].reject(r):t.callbacks[n].resolve(r)}}).catch(function(n){r(e,t,n)})})(e,n)}),n}(this),o=this._cacheMap;if(o){t=this._cacheKeyFn(e);var s=o.get(t);if(s){var c=n.cacheHits||=[];return new Promise(function(e){c.push(function(){e(s)})})}}n.keys.push(e);var l=new Promise(function(e,t){n.callbacks.push({resolve:e,reject:t})});return o&&o.set(t,l),l},t.loadMany=function(e){if(!a(e))throw TypeError(`The loader.loadMany() function must be called with Array<key> but got: `+e+`.`);for(var t=[],n=0;n<e.length;n++)t.push(this.load(e[n]).catch(function(e){return e}));return Promise.all(t)},t.clear=function(e){var t=this._cacheMap;if(t){var n=this._cacheKeyFn(e);t.delete(n)}return this},t.clearAll=function(){var e=this._cacheMap;return e&&e.clear(),this},t.prime=function(e,t){var n=this._cacheMap;if(n){var r,i=this._cacheKeyFn(e);n.get(i)===void 0&&(t instanceof Error?(r=Promise.reject(t)).catch(function(){}):r=Promise.resolve(t),n.set(i,r))}return this},e}(),n=typeof process==`object`&&typeof process.nextTick==`function`?function(t){e||=Promise.resolve(),e.then(function(){process.nextTick(t)})}:typeof setImmediate==`function`?function(e){setImmediate(e)}:function(e){setTimeout(e)};function r(e,t,n){i(t);for(var r=0;r<t.keys.length;r++)e.clear(t.keys[r]),t.callbacks[r].reject(n)}function i(e){if(e.cacheHits)for(var t=0;t<e.cacheHits.length;t++)e.cacheHits[t]()}function a(e){return typeof e==`object`&&!!e&&typeof e.length==`number`&&(e.length===0||e.length>0&&Object.prototype.hasOwnProperty.call(e,e.length-1))}return v=t}());function x({debug:e,apiKey:t,secretKey:n,sourceLanguage:i,_apiUrl:a,formality:o,_loaderFactory:s}){let c={debug:!!e,apiKey:t,secretKey:n,lang:r.EN,sourceLang:i,apiUrl:a,formality:o},l=new b((s??g)(c),{cacheKeyFn:h(t,i)});return(e,t,n)=>l.load({text:t,...n,lang:e})}var S=x,C=r.EN;function w(e,t){if(!e)return t??C;if([r.FA_AF,r.FR_CA,r.PT_PT,r.ES_MX].includes(e))return e;let n=e.includes(`-`)?e.split(`-`)[0]:e;return Object.values(r).includes(n)?n:t||(console.warn(`Language not found for UTS locale "${e}" and no fallback provided was provided. Falling back to "${C}"`),C)}var T=/\{(\d+)\}/g,E=e=>e.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`);function D(e){let t=Object.keys(e).sort((e,t)=>t.length-e.length),n=t.length>0?RegExp(`\\$(${t.map(E).join(`|`)})`,`g`):null,r=new Map,i=[];return{values:i,replace:t=>n?t.replace(n,(t,n)=>{let a=r.get(n);return a===void 0&&(a=i.push(String(e[n]??``))-1,r.set(n,a)),`{${a}}`}):t,unused:()=>t.filter(e=>!r.has(e))}}function O(e){e.length>0&&console.warn(`[Magic Translate]: ${e.map(e=>`$${e}`).join(`, `)} not found in the text. Check the spelling, or remove ${e.length===1?`it`:`them`} from the variables.`)}function k(e,t){let{replace:n,values:r,unused:i}=D(t);return{template:n(e),values:r,unused:i()}}function A(e,t){return e.replace(T,(e,n)=>Number(n)<t.length?t[Number(n)]:e)}function j(e){let t=document.createTreeWalker(e,NodeFilter.SHOW_TEXT),n=[];for(let e=t.nextNode();e;e=t.nextNode())n.push(e);return n}function M(e,t){let n=document.createElement(`template`);n.innerHTML=e;let{replace:r,values:i,unused:a}=D(t);return j(n.content).forEach(e=>{e.data=r(e.data)}),{template:n.innerHTML,values:i,unused:a()}}function N(e,t){j(e).forEach(e=>{let n=A(e.data,t);n!==e.data&&(e.data=n)})}var P=`t, mt-translate, [data-t]`,F=`[data-t-attrs]`;function I(e){let t=e;for(let e=t.parentElement?.closest(P);e;e=t.parentElement?.closest(P))t=e;return t}function L(e){let t={},n=e.getAttribute(`data-lang`),r=e.getAttribute(`data-formality`),i=e.getAttribute(`data-t-id`);return n&&(t.lang=n),r&&(t.formality=r),i&&(t.id=i),t}function R(e){let n=e.getAttribute(`data-v`);if(n!==null){try{let e=JSON.parse(n);if(e&&typeof e==`object`&&!Array.isArray(e))return e}catch{}return console.warn(`[${t}]: data-v must be a JSON object, such as data-v='{"name": "Bob"}', but is ${n}`),null}}function z(e,t){if(t.length===0)return e;let n=document.createElement(`template`);return n.innerHTML=e,N(n.content,t),n.innerHTML}var B=class{constructor(e){if(this.options=e,this.contents=new Map,this.attributes=new Map,this.listeners=new Set,!e.apiKey)throw Error(`Missing API key. Please get one at ${n}`);this.currentLanguage=e.language??w(typeof navigator>`u`?void 0:navigator.language),this.dataLoader=this.createDataLoader(),typeof document<`u`&&(this.root=e.root??document.documentElement,this.start(this.root))}get language(){return this.currentLanguage}setLanguage(e){e!==this.currentLanguage&&(this.currentLanguage=e,this.dataLoader=this.createDataLoader(),this.forget(e=>!e.isConnected||!this.root?.contains(e)),this.contents.forEach((e,t)=>this.translateContent(t,!0)),this.attributes.forEach((e,t)=>this.translateAttributes(t,!0)),this.listeners.forEach(t=>t(e)))}onLanguageChange(e){return this.listeners.add(e),()=>this.listeners.delete(e)}translate(e,{v:t,...n}={}){if(!t)return this.dataLoader.load({text:e,...n});let{template:r,values:i,unused:a}=k(e,t);return O(a),this.dataLoader.load({text:r,...n}).then(e=>A(e,i))}destroy(){this.observer?.disconnect(),this.contents.clear(),this.attributes.clear(),this.listeners.clear()}createDataLoader(){let{debug:e,apiKey:t,sourceLanguage:n,_apiUrl:r,formality:i}=this.options;return new b((this.options._loaderFactory??g)({debug:!!e,apiKey:t,lang:this.currentLanguage,sourceLang:n,apiUrl:r,formality:i}),{cacheKeyFn:h(t,n,this.currentLanguage)})}start(e){let t=new Set,n=new Set;this.collect(e,t,n),t.forEach(e=>this.translateContent(e)),n.forEach(e=>this.translateAttributes(e)),this.observer=new MutationObserver(e=>this.handleMutations(e)),this.observer.observe(e,{subtree:!0,childList:!0,characterData:!0,attributes:!0})}collect(e,t,n){let r=[e,...Array.from(e.querySelectorAll(`*`))];for(let e of r)e.matches(`t, mt-translate, [data-t]`)?t.add(I(e)):e.matches(`[data-t-attrs]`)&&!e.closest(`t, mt-translate, [data-t]`)&&n.add(e)}handleMutations(e){let t=new Set,n=new Set;for(let r of e){let e=r.target.nodeType===Node.ELEMENT_NODE?r.target:r.target.parentElement;if(!e)continue;let i=e.closest(P);i?t.add(I(i)):(r.type===`attributes`&&e.matches(`[data-t-attrs]`)&&n.add(e),r.addedNodes.forEach(e=>{e.nodeType===Node.ELEMENT_NODE&&this.collect(e,t,n)}))}e.some(e=>e.removedNodes.length>0)&&this.forget(e=>!e.isConnected),t.forEach(e=>this.translateContent(e)),n.forEach(e=>this.translateAttributes(e))}forget(e){for(let t of this.contents.keys())e(t)&&this.contents.delete(t);for(let t of this.attributes.keys())e(t)&&this.attributes.delete(t)}translateContent(e,t=!1){let n=e.innerHTML,r=e.getAttribute(`data-v`),i=this.contents.get(e);if(!i)i={source:n,requestId:0,variables:r},this.contents.set(e,i);else if(n!==i.rendered&&n!==i.source)i.source=n,i.rendered=void 0,i.variables=r;else if(r!==i.variables)i.variables=r;else if(!t)return;let[,a,o,s]=/^(\s*)([\s\S]*?)(\s*)$/.exec(i.source.replace(/<!--[\s\S]*?-->/g,``));if(!o)return;let c=R(e);if(c===null)return;let{template:l,values:u,unused:d}=c?M(o,c):{template:o,values:[],unused:[]};l!==i.template&&(i.template=l,O(d));let f=i,p=t=>{let n=`${a}${z(t,u)}${s}`;e.innerHTML!==n&&(e.innerHTML=n),f.rendered=e.innerHTML};c&&f.rendered===void 0&&p(l);let m=++f.requestId;this.translate(l,L(e)).then(t=>{m===f.requestId&&e.isConnected&&p(t)})}translateAttributes(e,t=!1){let n=(e.getAttribute(`data-t-attrs`)??``).split(/[\s,]+/).filter(Boolean),r=e.getAttribute(`data-v`),i=this.attributes.get(e);i||(i=new Map,this.attributes.set(e,i));for(let a of n){let n=e.getAttribute(a);if(!n?.trim())continue;let o=i.get(a);if(!o)o={source:n,requestId:0,variables:r},i.set(a,o);else if(n!==o.rendered&&n!==o.source)o.source=n,o.rendered=void 0,o.variables=r;else if(r!==o.variables)o.variables=r;else if(!t)continue;let s=R(e);if(s===null)continue;let{template:c,values:l,unused:u}=s?k(o.source,s):{template:o.source,values:[],unused:[]};c!==o.template&&(o.template=c,O(u));let d=o,f=t=>{let n=A(t,l);d.rendered=n,e.getAttribute(a)!==n&&e.setAttribute(a,n)};s&&d.rendered===void 0&&f(c);let p=++d.requestId,{id:m,...h}=L(e);this.translate(c,h).then(t=>{p===d.requestId&&e.isConnected&&f(t)})}}};function V(e){return new B(e)}var H=`magic-translate-language`;function U(){try{return localStorage.getItem(H)??void 0}catch{return}}var W=document.currentScript,G=W?.dataset.apiKey;if(W&&G){let{language:e,sourceLanguage:t,formality:n}=W.dataset,r=()=>{let r=V({apiKey:G,language:U()??e,sourceLanguage:t,formality:n,debug:W.hasAttribute(`data-debug`)});r.onLanguageChange(e=>{try{localStorage.setItem(H,e)}catch{}}),window.magicTranslate=r,document.dispatchEvent(new CustomEvent(`magictranslate:ready`,{detail:r}))};document.readyState===`loading`?document.addEventListener(`DOMContentLoaded`,r):r()}return e.ATTRIBUTES_SELECTOR=F,e.CONTENT_SELECTOR=P,e.DataLoader=b,Object.defineProperty(e,"Language",{enumerable:!0,get:function(){return r}}),e.MagicTranslate=B,e.cacheKeyFn=h,e.createMagicTranslate=V,e.defaultDataLoaderOptions=f,e.defaultLoaderFactory=g,e.fillElement=N,e.fillPlaceholders=A,e.isSecretKey=s,e.libraryName=t,e.libraryWebsite=n,e.maxIdLength=d,e.resolveApiKey=u,e.secretKeyEnvVariable=o,e.secretKeyFromEnv=c,e.setupT=S,e.setupTranslate=x,e.templater=D,e.toHtmlTemplate=M,e.toTemplate=k,e.utsLocaleToLanguage=w,e.warnAboutUnused=O,e})({});
8
8
  //# sourceMappingURL=magic-translate.min.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"magic-translate.min.js","names":["libraryName","libraryWebsite","utsLocaleToLanguage","toTemplate","fillPlaceholders","defaultLoaderFactory","DataLoader","cacheKeyFn","toHtmlTemplate","exports","e","t","n","r","c","i","a","u","s","l","h","o","d","y","m","g","b","w","T","E","A","k","S","_","CONTENT_SELECTOR","ATTRIBUTES_SELECTOR","outermost","current","element","parent","optionsOf","options","lang","formality","variablesOf","json","variables","fillHtml","values","html","container","MagicTranslate","language","listener","params","v","text","unused","template","translation","debug","sourceLanguage","_apiUrl","apiKey","contents","attributes","root","records","all","record","target","content","node","predicate","variablesJson","force","leadingWhitespace","trailingWhitespace","show","rendered","translated","requestId","names","translations","name","value","createMagicTranslate","STORAGE_KEY","storedLanguage","script","start","magicTranslate"],"sources":["../../core/dist/index.es.js","../src/magic-translate.ts","../src/script.ts"],"sourcesContent":["/*\n * 'Magic Translate Core'\n * {@link https://https://magictranslate.io\n * @copyright i42 GmbH\n */\nconst e=\"Magic Translate\",t=\"https://magictranslate.io\";var n;function r(e){return Object.keys(e).filter(t=>void 0!==e[t]).reduce((t,n)=>({...t,[n]:e[n]}),{})}function a(e){const t=new URLSearchParams,n=(e,r=\"\")=>{Array.isArray(e)?e.forEach((e,t)=>{n(e,r?`${r}[${t}]`:`[${t}]`)}):\"object\"==typeof e&&null!==e?Object.entries(e).forEach(([e,t])=>{n(t,r?`${r}.${e}`:e)}):t.append(r,e)};return n(e),t}!function(e){e.AF=\"af\",e.SQ=\"sq\",e.AM=\"am\",e.AR=\"ar\",e.HY=\"hy\",e.AZ=\"az\",e.BN=\"bn\",e.BS=\"bs\",e.BG=\"bg\",e.CA=\"ca\",e.ZH=\"zh\",e.ZH_TW=\"zh-TW\",e.HR=\"hr\",e.CS=\"cs\",e.DA=\"da\",e.FA_AF=\"fa-AF\",e.NL=\"nl\",e.EN=\"en\",e.ET=\"et\",e.FA=\"fa\",e.TL=\"tl\",e.FI=\"fi\",e.FR=\"fr\",e.FR_CA=\"fr-CA\",e.KA=\"ka\",e.DE=\"de\",e.EL=\"el\",e.GU=\"gu\",e.HT=\"ht\",e.HA=\"ha\",e.HE=\"he\",e.HI=\"hi\",e.HU=\"hu\",e.IS=\"is\",e.ID=\"id\",e.GA=\"ga\",e.IT=\"it\",e.JA=\"ja\",e.KN=\"kn\",e.KK=\"kk\",e.KO=\"ko\",e.LV=\"lv\",e.LT=\"lt\",e.MK=\"mk\",e.MS=\"ms\",e.ML=\"ml\",e.MT=\"mt\",e.MR=\"mr\",e.MN=\"mn\",e.NO=\"no\",e.PS=\"ps\",e.PL=\"pl\",e.PT=\"pt\",e.PT_PT=\"pt-PT\",e.PA=\"pa\",e.RO=\"ro\",e.RU=\"ru\",e.SR=\"sr\",e.SI=\"si\",e.SK=\"sk\",e.SL=\"sl\",e.SO=\"so\",e.ES=\"es\",e.ES_MX=\"es-MX\",e.SW=\"sw\",e.SV=\"sv\",e.TA=\"ta\",e.TE=\"te\",e.TH=\"th\",e.TR=\"tr\",e.UK=\"uk\",e.UR=\"ur\",e.UZ=\"uz\",e.VI=\"vi\",e.CY=\"cy\"}(n||(n={}));const o={debug:!1,apiUrl:\"https://api.magictranslate.io\",lang:n.DE};var c;!function(e){e.QUOTA_EXCEEDED_ERROR=\"QUOTA_EXCEEDED_ERROR\"}(c||(c={}));const i=(e,t,n)=>a=>Object.entries(r({apiKey:e,language:n,sourceLanguage:a.sourceLang??t??\"auto\",...a})).sort(([e])=>e.localeCompare(e)).reduce((e,t)=>`${e};${t.join(\"=\")}`,\"\"),u=t=>async n=>{if(t.debug&&console.debug(`[${e}]: batch function called with: `,n),t.lang===t.sourceLang)return n.map(e=>e.text);const{apiKey:c,lang:i,formality:u}=t,s=r({apiKey:c,lang:i,formality:u,items:n.map(({text:e,sourceLang:t,lang:n,...a})=>r({text:e,lang:n,sourceLang:t,...a}))});return fetch(`${t.apiUrl??o.apiUrl}/v1/translate`,{method:\"POST\",body:t.useJson?JSON.stringify(s):a(s),headers:{\"Content-Type\":t.useJson?\"application/json\":\"application/x-www-form-urlencoded\"}}).then(e=>e.json()).then(t=>\"results\"in t?t.results:(\"code\"in t?console.error(`[${e}]: ${t.message}`):console.error(`[${e}]: Unexpected payload from magic translate server: ${JSON.stringify(t)}`),n.map(e=>e.text))).catch(t=>(console.error(`[${e}]: Error while loading translations: `,t),n.map(e=>e.text)))};function s(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,\"default\")?e.default:e}var l,h;var f=function(){if(h)return l;h=1;var e,t=function(){function e(e,t){if(\"function\"!=typeof e)throw new TypeError(\"DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but got: \"+e+\".\");this._batchLoadFn=e,this._maxBatchSize=function(e){var t=!e||!1!==e.batch;if(!t)return 1;var n=e&&e.maxBatchSize;if(void 0===n)return 1/0;if(\"number\"!=typeof n||n<1)throw new TypeError(\"maxBatchSize must be a positive number: \"+n);return n}(t),this._batchScheduleFn=function(e){var t=e&&e.batchScheduleFn;if(void 0===t)return n;if(\"function\"!=typeof t)throw new TypeError(\"batchScheduleFn must be a function: \"+t);return t}(t),this._cacheKeyFn=function(e){var t=e&&e.cacheKeyFn;if(void 0===t)return function(e){return e};if(\"function\"!=typeof t)throw new TypeError(\"cacheKeyFn must be a function: \"+t);return t}(t),this._cacheMap=function(e){var t=!e||!1!==e.cache;if(!t)return null;var n=e&&e.cacheMap;if(void 0===n)return new Map;if(null!==n){var r=[\"get\",\"set\",\"delete\",\"clear\"].filter(function(e){return n&&\"function\"!=typeof n[e]});if(0!==r.length)throw new TypeError(\"Custom cacheMap missing methods: \"+r.join(\", \"))}return n}(t),this._batch=null,this.name=function(e){if(e&&e.name)return e.name;return null}(t)}var t=e.prototype;return t.load=function(e){if(null==e)throw new TypeError(\"The loader.load() function must be called with a value, but got: \"+String(e)+\".\");var t,n=function(e){var t=e._batch;if(null!==t&&!t.hasDispatched&&t.keys.length<e._maxBatchSize)return t;var n={hasDispatched:!1,keys:[],callbacks:[]};return e._batch=n,e._batchScheduleFn(function(){!function(e,t){if(t.hasDispatched=!0,0===t.keys.length)return void a(t);var n;try{n=e._batchLoadFn(t.keys)}catch(n){return r(e,t,new TypeError(\"DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function errored synchronously: \"+String(n)+\".\"))}if(!n||\"function\"!=typeof n.then)return r(e,t,new TypeError(\"DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise: \"+String(n)+\".\"));n.then(function(e){if(!o(e))throw new TypeError(\"DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise of an Array: \"+String(e)+\".\");if(e.length!==t.keys.length)throw new TypeError(\"DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise of an Array of the same length as the Array of keys.\\n\\nKeys:\\n\"+String(t.keys)+\"\\n\\nValues:\\n\"+String(e));a(t);for(var n=0;n<t.callbacks.length;n++){var r=e[n];r instanceof Error?t.callbacks[n].reject(r):t.callbacks[n].resolve(r)}}).catch(function(n){r(e,t,n)})}(e,n)}),n}(this),c=this._cacheMap;if(c){t=this._cacheKeyFn(e);var i=c.get(t);if(i){var u=n.cacheHits||(n.cacheHits=[]);return new Promise(function(e){u.push(function(){e(i)})})}}n.keys.push(e);var s=new Promise(function(e,t){n.callbacks.push({resolve:e,reject:t})});return c&&c.set(t,s),s},t.loadMany=function(e){if(!o(e))throw new TypeError(\"The loader.loadMany() function must be called with Array<key> but got: \"+e+\".\");for(var t=[],n=0;n<e.length;n++)t.push(this.load(e[n]).catch(function(e){return e}));return Promise.all(t)},t.clear=function(e){var t=this._cacheMap;if(t){var n=this._cacheKeyFn(e);t.delete(n)}return this},t.clearAll=function(){var e=this._cacheMap;return e&&e.clear(),this},t.prime=function(e,t){var n=this._cacheMap;if(n){var r,a=this._cacheKeyFn(e);if(void 0===n.get(a))t instanceof Error?(r=Promise.reject(t)).catch(function(){}):r=Promise.resolve(t),n.set(a,r)}return this},e}(),n=\"object\"==typeof process&&\"function\"==typeof process.nextTick?function(t){e||(e=Promise.resolve()),e.then(function(){process.nextTick(t)})}:\"function\"==typeof setImmediate?function(e){setImmediate(e)}:function(e){setTimeout(e)};function r(e,t,n){a(t);for(var r=0;r<t.keys.length;r++)e.clear(t.keys[r]),t.callbacks[r].reject(n)}function a(e){if(e.cacheHits)for(var t=0;t<e.cacheHits.length;t++)e.cacheHits[t]()}function o(e){return\"object\"==typeof e&&null!==e&&\"number\"==typeof e.length&&(0===e.length||e.length>0&&Object.prototype.hasOwnProperty.call(e,e.length-1))}return l=t}(),p=s(f);function d({debug:e,apiKey:t,sourceLanguage:r,_apiUrl:a,formality:o,_loaderFactory:c}){const s={debug:!!e,apiKey:t,lang:n.EN,sourceLang:r,apiUrl:a,formality:o},l=new p((c??u)(s),{cacheKeyFn:i(t,r)});return(e,t,n)=>l.load({text:t,...n,lang:e})}const y=d,m=n.EN;function g(e,t){if(!e)return t??m;if([n.FA_AF,n.FR_CA,n.PT_PT,n.ES_MX].includes(e))return e;const r=e.includes(\"-\")?e.split(\"-\")[0]:e;return Object.values(n).includes(r)?r:t||(console.warn(`Language not found for UTS locale \"${e}\" and no fallback provided was provided. Falling back to \"${m}\"`),m)}const v=/\\{(\\d+)\\}/g,b=e=>e.replace(/[.*+?^${}()|[\\]\\\\]/g,\"\\\\$&\");function w(e){const t=Object.keys(e).sort((e,t)=>t.length-e.length),n=t.length>0?new RegExp(`\\\\$(${t.map(b).join(\"|\")})`,\"g\"):null,r=new Map,a=[];return{values:a,replace:t=>n?t.replace(n,(t,n)=>{let o=r.get(n);return void 0===o&&(o=a.push(String(e[n]??\"\"))-1,r.set(n,o)),`{${o}}`}):t,unused:()=>t.filter(e=>!r.has(e))}}function T(t){t.length>0&&console.warn(`[${e}]: ${t.map(e=>`$${e}`).join(\", \")} not found in the text. Check the spelling, or remove ${1===t.length?\"it\":\"them\"} from the variables.`)}function E(e,t){const{replace:n,values:r,unused:a}=w(t);return{template:n(e),values:r,unused:a()}}function A(e,t){return e.replace(v,(e,n)=>Number(n)<t.length?t[Number(n)]:e)}function k(e){const t=document.createTreeWalker(e,NodeFilter.SHOW_TEXT),n=[];for(let e=t.nextNode();e;e=t.nextNode())n.push(e);return n}function S(e,t){const n=document.createElement(\"template\");n.innerHTML=e;const{replace:r,values:a,unused:o}=w(t);return k(n.content).forEach(e=>{e.data=r(e.data)}),{template:n.innerHTML,values:a,unused:o()}}function _(e,t){k(e).forEach(e=>{const n=A(e.data,t);n!==e.data&&(e.data=n)})}export{p as DataLoader,n as Language,i as cacheKeyFn,o as defaultDataLoaderOptions,u as defaultLoaderFactory,_ as fillElement,A as fillPlaceholders,e as libraryName,t as libraryWebsite,y as setupT,d as setupTranslate,w as templater,S as toHtmlTemplate,E as toTemplate,g as utsLocaleToLanguage,T as warnAboutUnused};\n//# sourceMappingURL=index.es.js.map\n","import {\n cacheKeyFn,\n DataLoader,\n DataLoaderLoadParams,\n defaultLoaderFactory,\n fillElement,\n fillPlaceholders,\n Language,\n libraryName,\n libraryWebsite,\n MagicTranslateConfig,\n toHtmlTemplate,\n toTemplate,\n TranslateOptions,\n utsLocaleToLanguage,\n Variables,\n warnAboutUnused,\n} from '@magic-translate/core';\n\n/**\n * Type alias to make the language enum more flexible to also allow passing language strings\n * instead of just the enum.\n */\nexport type Languages = `${Language}`;\n\nexport interface TranslateParams extends Omit<DataLoaderLoadParams, 'text'> {\n /**\n * Values that are not translated, referenced as `$name` in the text. The text\n * is translated once as a template and cached, whatever the values are.\n */\n v?: Variables;\n}\n\nexport interface MagicTranslateOptions extends Omit<\n MagicTranslateConfig,\n 'language'\n> {\n /**\n * The language content is translated to. Defaults to the browser's language.\n */\n language?: Languages;\n /**\n * The element whose content is translated. Defaults to the whole document.\n */\n root?: Element;\n}\n\n/** Elements whose content is translated. */\nexport const CONTENT_SELECTOR = 't, mt-translate, [data-t]';\n/** Elements with attributes to translate, e.g. `data-t-attrs=\"placeholder title\"`. */\nexport const ATTRIBUTES_SELECTOR = '[data-t-attrs]';\n\ninterface Translation {\n source: string;\n // what was last written to the DOM, to tell our own changes from others\n rendered?: string;\n requestId: number;\n // the `data-v` attribute the source was last translated with\n variables: string | null;\n // to warn about unused variables once per text, not on every render\n template?: string;\n}\n\nfunction outermost(element: Element): Element {\n let current = element;\n for (\n let parent = current.parentElement?.closest(CONTENT_SELECTOR);\n parent;\n parent = current.parentElement?.closest(CONTENT_SELECTOR)\n ) {\n current = parent;\n }\n return current;\n}\n\nfunction optionsOf(element: Element): TranslateOptions {\n const options: TranslateOptions = {};\n const lang = element.getAttribute('data-lang');\n const formality = element.getAttribute('data-formality');\n if (lang) {\n options.lang = lang as Languages;\n }\n if (formality) {\n options.formality = formality as TranslateOptions['formality'];\n }\n return options;\n}\n\n/**\n * Reads the values in `data-v`, a JSON object such as `{\"name\": \"Bob\"}`.\n * Returns `null` if the attribute is not valid, so the text is left as it is\n * rather than translated with `$name` in it.\n */\nfunction variablesOf(element: Element): Variables | undefined | null {\n const json = element.getAttribute('data-v');\n if (json === null) {\n return undefined;\n }\n try {\n const variables: unknown = JSON.parse(json);\n if (\n variables &&\n typeof variables === 'object' &&\n !Array.isArray(variables)\n ) {\n return variables as Variables;\n }\n } catch {\n // reported below\n }\n console.warn(\n `[${libraryName}]: data-v must be a JSON object, such as data-v='{\"name\": \"Bob\"}', but is ${json}`\n );\n return null;\n}\n\nfunction fillHtml(html: string, values: readonly string[]): string {\n if (values.length === 0) {\n return html;\n }\n const container = document.createElement('template');\n container.innerHTML = html;\n fillElement(container.content, values);\n return container.innerHTML;\n}\n\nexport class MagicTranslate {\n private currentLanguage: Languages;\n private dataLoader: DataLoader<DataLoaderLoadParams, string, string>;\n private readonly root?: Element;\n private readonly contents = new Map<Element, Translation>();\n private readonly attributes = new Map<Element, Map<string, Translation>>();\n private readonly listeners = new Set<(language: Languages) => void>();\n private observer?: MutationObserver;\n\n constructor(private readonly options: MagicTranslateOptions) {\n if (!options.apiKey) {\n throw new Error(`Missing API key. Please get one at ${libraryWebsite}`);\n }\n\n this.currentLanguage =\n options.language ??\n utsLocaleToLanguage(\n typeof navigator === 'undefined' ? undefined : navigator.language\n );\n this.dataLoader = this.createDataLoader();\n\n if (typeof document !== 'undefined') {\n this.root = options.root ?? document.documentElement;\n this.start(this.root);\n }\n }\n\n /**\n * The language content is currently translated to.\n */\n get language(): Languages {\n return this.currentLanguage;\n }\n\n /**\n * Translates the page to another language.\n */\n setLanguage(language: Languages): void {\n if (language === this.currentLanguage) {\n return;\n }\n\n this.currentLanguage = language;\n this.dataLoader = this.createDataLoader();\n\n this.forget(\n (element) => !element.isConnected || !this.root?.contains(element)\n );\n this.contents.forEach((_, element) => this.translateContent(element, true));\n this.attributes.forEach((_, element) =>\n this.translateAttributes(element, true)\n );\n this.listeners.forEach((listener) => listener(language));\n }\n\n /**\n * Calls `listener` whenever the language changes. Returns a function that\n * removes the listener again.\n */\n onLanguageChange(listener: (language: Languages) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Translates a string to the current language.\n */\n translate(\n text: string,\n { v, ...params }: TranslateParams = {}\n ): Promise<string> {\n if (!v) {\n return this.dataLoader.load({ text, ...params });\n }\n const { template, values, unused } = toTemplate(text, v);\n warnAboutUnused(unused);\n return this.dataLoader\n .load({ text: template, ...params })\n .then((translation) => fillPlaceholders(translation, values));\n }\n\n /**\n * Stops translating the page. Content that is already translated stays\n * translated.\n */\n destroy(): void {\n this.observer?.disconnect();\n this.contents.clear();\n this.attributes.clear();\n this.listeners.clear();\n }\n\n private createDataLoader() {\n const { debug, apiKey, sourceLanguage, _apiUrl, formality } = this.options;\n const loaderFactory = this.options._loaderFactory ?? defaultLoaderFactory;\n\n return new DataLoader<DataLoaderLoadParams, string, string>(\n loaderFactory({\n debug: !!debug,\n apiKey,\n lang: this.currentLanguage,\n sourceLang: sourceLanguage,\n apiUrl: _apiUrl,\n formality,\n }),\n {\n cacheKeyFn: cacheKeyFn(apiKey, sourceLanguage, this.currentLanguage),\n }\n );\n }\n\n private start(root: Element) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n this.collect(root, contents, attributes);\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n\n // Picks up content that is added or changed later.\n this.observer = new MutationObserver((records) =>\n this.handleMutations(records)\n );\n this.observer.observe(root, {\n subtree: true,\n childList: true,\n characterData: true,\n attributes: true,\n });\n }\n\n private collect(\n root: Element,\n contents: Set<Element>,\n attributes: Set<Element>\n ) {\n const all = [root, ...Array.from(root.querySelectorAll('*'))];\n for (const element of all) {\n if (element.matches(CONTENT_SELECTOR)) {\n contents.add(outermost(element));\n } else if (\n element.matches(ATTRIBUTES_SELECTOR) &&\n !element.closest(CONTENT_SELECTOR)\n ) {\n attributes.add(element);\n }\n }\n }\n\n private handleMutations(records: MutationRecord[]) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n\n for (const record of records) {\n const target =\n record.target.nodeType === Node.ELEMENT_NODE\n ? (record.target as Element)\n : record.target.parentElement;\n if (!target) {\n continue;\n }\n\n const content = target.closest(CONTENT_SELECTOR);\n if (content) {\n contents.add(outermost(content));\n continue;\n }\n\n if (record.type === 'attributes' && target.matches(ATTRIBUTES_SELECTOR)) {\n attributes.add(target);\n }\n record.addedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n this.collect(node as Element, contents, attributes);\n }\n });\n }\n\n if (records.some((record) => record.removedNodes.length > 0)) {\n this.forget((element) => !element.isConnected);\n }\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n }\n\n private forget(predicate: (element: Element) => boolean) {\n for (const element of this.contents.keys()) {\n if (predicate(element)) {\n this.contents.delete(element);\n }\n }\n for (const element of this.attributes.keys()) {\n if (predicate(element)) {\n this.attributes.delete(element);\n }\n }\n }\n\n private translateContent(element: Element, force = false) {\n const html = element.innerHTML;\n const variablesJson = element.getAttribute('data-v');\n let translation = this.contents.get(element);\n if (!translation) {\n translation = { source: html, requestId: 0, variables: variablesJson };\n this.contents.set(element, translation);\n } else if (html !== translation.rendered && html !== translation.source) {\n // changed by someone else, e.g. the page's own scripts\n translation.source = html;\n translation.rendered = undefined;\n translation.variables = variablesJson;\n } else if (variablesJson !== translation.variables) {\n // only the values changed, so the cached translation is reused\n translation.variables = variablesJson;\n } else if (!force) {\n return;\n }\n\n const [, leadingWhitespace, text, trailingWhitespace] =\n /^(\\s*)([\\s\\S]*?)(\\s*)$/.exec(\n translation.source.replace(/<!--[\\s\\S]*?-->/g, '')\n )!;\n if (!text) {\n return;\n }\n\n const variables = variablesOf(element);\n if (variables === null) {\n return;\n }\n const { template, values, unused } = variables\n ? toHtmlTemplate(text, variables)\n : { template: text, values: [], unused: [] };\n if (template !== translation.template) {\n translation.template = template;\n warnAboutUnused(unused);\n }\n\n const current = translation;\n const show = (translated: string) => {\n const rendered = `${leadingWhitespace}${fillHtml(translated, values)}${trailingWhitespace}`;\n if (element.innerHTML !== rendered) {\n element.innerHTML = rendered;\n }\n current.rendered = element.innerHTML;\n };\n // Until the first translation arrives, show the values instead of `$name`.\n if (variables && current.rendered === undefined) {\n show(template);\n }\n\n // make sure that we only ever use the response of the most recent request.\n const requestId = ++current.requestId;\n this.translate(template, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n show(translated);\n });\n }\n\n private translateAttributes(element: Element, force = false) {\n const names = (element.getAttribute('data-t-attrs') ?? '')\n .split(/[\\s,]+/)\n .filter(Boolean);\n const variablesJson = element.getAttribute('data-v');\n let translations = this.attributes.get(element);\n if (!translations) {\n translations = new Map();\n this.attributes.set(element, translations);\n }\n\n for (const name of names) {\n const value = element.getAttribute(name);\n if (!value?.trim()) {\n continue;\n }\n\n let translation = translations.get(name);\n if (!translation) {\n translation = { source: value, requestId: 0, variables: variablesJson };\n translations.set(name, translation);\n } else if (\n value !== translation.rendered &&\n value !== translation.source\n ) {\n translation.source = value;\n translation.rendered = undefined;\n translation.variables = variablesJson;\n } else if (variablesJson !== translation.variables) {\n translation.variables = variablesJson;\n } else if (!force) {\n continue;\n }\n\n const variables = variablesOf(element);\n if (variables === null) {\n continue;\n }\n const { template, values, unused } = variables\n ? toTemplate(translation.source, variables)\n : { template: translation.source, values: [], unused: [] };\n if (template !== translation.template) {\n translation.template = template;\n warnAboutUnused(unused);\n }\n\n const current = translation;\n const show = (translated: string) => {\n const rendered = fillPlaceholders(translated, values);\n current.rendered = rendered;\n if (element.getAttribute(name) !== rendered) {\n element.setAttribute(name, rendered);\n }\n };\n if (variables && current.rendered === undefined) {\n show(template);\n }\n\n const requestId = ++current.requestId;\n this.translate(template, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n show(translated);\n });\n }\n }\n}\n\n/**\n * Starts translating the page: the content of every `<t>` element (or element\n * with a `data-t` attribute), and the attributes listed in `data-t-attrs`.\n * Content added later is translated as well.\n */\nexport function createMagicTranslate(\n options: MagicTranslateOptions\n): MagicTranslate {\n return new MagicTranslate(options);\n}\n","import {\n createMagicTranslate,\n Languages,\n MagicTranslate,\n TranslateParams,\n} from './magic-translate';\n\nexport * from './index';\n\ndeclare global {\n interface Window {\n magicTranslate?: MagicTranslate;\n }\n}\n\nconst STORAGE_KEY = 'magic-translate-language';\n\nfunction storedLanguage(): Languages | undefined {\n try {\n return (localStorage.getItem(STORAGE_KEY) as Languages | null) ?? undefined;\n } catch {\n return undefined;\n }\n}\n\n// `<script src=\".../magic-translate.min.js\" data-api-key=\"...\"></script>`\n// starts translating the page without any further code.\nconst script = document.currentScript as HTMLScriptElement | null;\nconst apiKey = script?.dataset.apiKey;\n\nif (script && apiKey) {\n const { language, sourceLanguage, formality } = script.dataset;\n\n const start = () => {\n const magicTranslate = createMagicTranslate({\n apiKey,\n // a language picked with the language switcher outlives page loads\n language: storedLanguage() ?? (language as Languages | undefined),\n sourceLanguage: sourceLanguage as Languages | undefined,\n formality: formality as TranslateParams['formality'],\n debug: script.hasAttribute('data-debug'),\n });\n magicTranslate.onLanguageChange((language) => {\n try {\n localStorage.setItem(STORAGE_KEY, language);\n } catch {\n // storage is unavailable, e.g. in some private windows\n }\n });\n window.magicTranslate = magicTranslate;\n document.dispatchEvent(\n new CustomEvent('magictranslate:ready', { detail: magicTranslate })\n );\n };\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', start);\n } else {\n start();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"magic-translate.min.js","names":["libraryName","libraryWebsite","utsLocaleToLanguage","toTemplate","fillPlaceholders","defaultLoaderFactory","DataLoader","cacheKeyFn","toHtmlTemplate","exports","e","t","n","r","c","i","\"MAGIC_TRANSLATE_SECRET_KEY\"","s","l","h","f","d","p","a","y","o","g","m","v","E","u","w","T","_","S","A","k","R","$","K","P","F","L","M","CONTENT_SELECTOR","ATTRIBUTES_SELECTOR","outermost","current","element","parent","optionsOf","options","lang","formality","id","variablesOf","json","variables","fillHtml","values","html","container","MagicTranslate","language","listener","params","text","unused","template","translation","debug","sourceLanguage","_apiUrl","apiKey","contents","attributes","root","records","all","record","target","content","node","predicate","variablesJson","force","leadingWhitespace","trailingWhitespace","show","rendered","translated","requestId","names","translations","name","value","_id","createMagicTranslate","STORAGE_KEY","storedLanguage","script","start","magicTranslate"],"sources":["../../core/dist/index.es.js","../src/magic-translate.ts","../src/script.ts"],"sourcesContent":["/*\n * 'Magic Translate Core'\n * {@link https://https://magictranslate.io\n * @copyright i42 GmbH\n */\nconst e=\"Magic Translate\",t=\"https://magictranslate.io\";var n;function r(e){return Object.keys(e).filter(t=>void 0!==e[t]).reduce((t,n)=>({...t,[n]:e[n]}),{})}function a(e){const t=new URLSearchParams,n=(e,r=\"\")=>{Array.isArray(e)?e.forEach((e,t)=>{n(e,r?`${r}[${t}]`:`[${t}]`)}):\"object\"==typeof e&&null!==e?Object.entries(e).forEach(([e,t])=>{n(t,r?`${r}.${e}`:e)}):t.append(r,e)};return n(e),t}!function(e){e.AF=\"af\",e.SQ=\"sq\",e.AM=\"am\",e.AR=\"ar\",e.HY=\"hy\",e.AZ=\"az\",e.BN=\"bn\",e.BS=\"bs\",e.BG=\"bg\",e.CA=\"ca\",e.ZH=\"zh\",e.ZH_TW=\"zh-TW\",e.HR=\"hr\",e.CS=\"cs\",e.DA=\"da\",e.FA_AF=\"fa-AF\",e.NL=\"nl\",e.EN=\"en\",e.ET=\"et\",e.FA=\"fa\",e.TL=\"tl\",e.FI=\"fi\",e.FR=\"fr\",e.FR_CA=\"fr-CA\",e.KA=\"ka\",e.DE=\"de\",e.EL=\"el\",e.GU=\"gu\",e.HT=\"ht\",e.HA=\"ha\",e.HE=\"he\",e.HI=\"hi\",e.HU=\"hu\",e.IS=\"is\",e.ID=\"id\",e.GA=\"ga\",e.IT=\"it\",e.JA=\"ja\",e.KN=\"kn\",e.KK=\"kk\",e.KO=\"ko\",e.LV=\"lv\",e.LT=\"lt\",e.MK=\"mk\",e.MS=\"ms\",e.ML=\"ml\",e.MT=\"mt\",e.MR=\"mr\",e.MN=\"mn\",e.NO=\"no\",e.PS=\"ps\",e.PL=\"pl\",e.PT=\"pt\",e.PT_PT=\"pt-PT\",e.PA=\"pa\",e.RO=\"ro\",e.RU=\"ru\",e.SR=\"sr\",e.SI=\"si\",e.SK=\"sk\",e.SL=\"sl\",e.SO=\"so\",e.ES=\"es\",e.ES_MX=\"es-MX\",e.SW=\"sw\",e.SV=\"sv\",e.TA=\"ta\",e.TE=\"te\",e.TH=\"th\",e.TR=\"tr\",e.UK=\"uk\",e.UR=\"ur\",e.UZ=\"uz\",e.VI=\"vi\",e.CY=\"cy\"}(n||(n={}));const o=\"MAGIC_TRANSLATE_SECRET_KEY\",c=e=>!!e?.startsWith(\"p-\");function i(){const{process:e}=globalThis;return e?.env?.[o]||void 0}let s=!1;function u({apiKey:n,secretKey:r}){return\"undefined\"==typeof window?r||i()||n:(!r&&!c(n)||s||(s=!0,console.error(`[${e}]: Secret keys only work on servers, so this one was not sent. Use your public API key in the browser, and regenerate your secret key at ${t}/account since it is exposed.`)),c(n)?void 0:n)}const l=128,h={debug:!1,apiUrl:\"https://api.magictranslate.io\",lang:n.DE};var f;function d(t){if(void 0!==t)return t.trim()&&t.length<=128?t:void console.error(`[${e}]: Ignoring the id \"${t}\". Ids must be 1 to 128 characters.`)}!function(e){e.QUOTA_EXCEEDED_ERROR=\"QUOTA_EXCEEDED_ERROR\",e.SECRET_KEY_REQUIRED=\"SECRET_KEY_REQUIRED\",e.SECRET_KEY_IN_BROWSER=\"SECRET_KEY_IN_BROWSER\"}(f||(f={}));const p=(e,t,n)=>a=>Object.entries(r({apiKey:e,language:n,sourceLanguage:a.sourceLang??t??\"auto\",...a})).sort(([e])=>e.localeCompare(e)).reduce((e,t)=>`${e};${t.join(\"=\")}`,\"\"),y=n=>async o=>{if(n.debug&&console.debug(`[${e}]: batch function called with: `,o),n.lang===n.sourceLang)return o.map(e=>e.text);const{lang:c,formality:i}=n,s=u(n);if(!s)return n.apiKey||n.secretKey||console.error(`[${e}]: Missing API key. Please get one at ${t}`),o.map(e=>e.text);const l=r({apiKey:s,lang:c,formality:i,items:o.map(({text:e,sourceLang:t,lang:n,id:a,...o})=>r({text:e,lang:n,sourceLang:t,...o,id:d(a)}))});return fetch(`${n.apiUrl??h.apiUrl}/v1/translate`,{method:\"POST\",body:n.useJson?JSON.stringify(l):a(l),headers:{\"Content-Type\":n.useJson?\"application/json\":\"application/x-www-form-urlencoded\"}}).then(e=>e.json()).then(t=>\"results\"in t?t.results:(\"code\"in t?console.error(`[${e}]: ${t.message}`):console.error(`[${e}]: Unexpected payload from magic translate server: ${JSON.stringify(t)}`),o.map(e=>e.text))).catch(t=>(console.error(`[${e}]: Error while loading translations: `,t),o.map(e=>e.text)))};function g(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,\"default\")?e.default:e}var m,v;var b=function(){if(v)return m;v=1;var e,t=function(){function e(e,t){if(\"function\"!=typeof e)throw new TypeError(\"DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but got: \"+e+\".\");this._batchLoadFn=e,this._maxBatchSize=function(e){var t=!e||!1!==e.batch;if(!t)return 1;var n=e&&e.maxBatchSize;if(void 0===n)return 1/0;if(\"number\"!=typeof n||n<1)throw new TypeError(\"maxBatchSize must be a positive number: \"+n);return n}(t),this._batchScheduleFn=function(e){var t=e&&e.batchScheduleFn;if(void 0===t)return n;if(\"function\"!=typeof t)throw new TypeError(\"batchScheduleFn must be a function: \"+t);return t}(t),this._cacheKeyFn=function(e){var t=e&&e.cacheKeyFn;if(void 0===t)return function(e){return e};if(\"function\"!=typeof t)throw new TypeError(\"cacheKeyFn must be a function: \"+t);return t}(t),this._cacheMap=function(e){var t=!e||!1!==e.cache;if(!t)return null;var n=e&&e.cacheMap;if(void 0===n)return new Map;if(null!==n){var r=[\"get\",\"set\",\"delete\",\"clear\"].filter(function(e){return n&&\"function\"!=typeof n[e]});if(0!==r.length)throw new TypeError(\"Custom cacheMap missing methods: \"+r.join(\", \"))}return n}(t),this._batch=null,this.name=function(e){if(e&&e.name)return e.name;return null}(t)}var t=e.prototype;return t.load=function(e){if(null==e)throw new TypeError(\"The loader.load() function must be called with a value, but got: \"+String(e)+\".\");var t,n=function(e){var t=e._batch;if(null!==t&&!t.hasDispatched&&t.keys.length<e._maxBatchSize)return t;var n={hasDispatched:!1,keys:[],callbacks:[]};return e._batch=n,e._batchScheduleFn(function(){!function(e,t){if(t.hasDispatched=!0,0===t.keys.length)return void a(t);var n;try{n=e._batchLoadFn(t.keys)}catch(n){return r(e,t,new TypeError(\"DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function errored synchronously: \"+String(n)+\".\"))}if(!n||\"function\"!=typeof n.then)return r(e,t,new TypeError(\"DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise: \"+String(n)+\".\"));n.then(function(e){if(!o(e))throw new TypeError(\"DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise of an Array: \"+String(e)+\".\");if(e.length!==t.keys.length)throw new TypeError(\"DataLoader must be constructed with a function which accepts Array<key> and returns Promise<Array<value>>, but the function did not return a Promise of an Array of the same length as the Array of keys.\\n\\nKeys:\\n\"+String(t.keys)+\"\\n\\nValues:\\n\"+String(e));a(t);for(var n=0;n<t.callbacks.length;n++){var r=e[n];r instanceof Error?t.callbacks[n].reject(r):t.callbacks[n].resolve(r)}}).catch(function(n){r(e,t,n)})}(e,n)}),n}(this),c=this._cacheMap;if(c){t=this._cacheKeyFn(e);var i=c.get(t);if(i){var s=n.cacheHits||(n.cacheHits=[]);return new Promise(function(e){s.push(function(){e(i)})})}}n.keys.push(e);var u=new Promise(function(e,t){n.callbacks.push({resolve:e,reject:t})});return c&&c.set(t,u),u},t.loadMany=function(e){if(!o(e))throw new TypeError(\"The loader.loadMany() function must be called with Array<key> but got: \"+e+\".\");for(var t=[],n=0;n<e.length;n++)t.push(this.load(e[n]).catch(function(e){return e}));return Promise.all(t)},t.clear=function(e){var t=this._cacheMap;if(t){var n=this._cacheKeyFn(e);t.delete(n)}return this},t.clearAll=function(){var e=this._cacheMap;return e&&e.clear(),this},t.prime=function(e,t){var n=this._cacheMap;if(n){var r,a=this._cacheKeyFn(e);if(void 0===n.get(a))t instanceof Error?(r=Promise.reject(t)).catch(function(){}):r=Promise.resolve(t),n.set(a,r)}return this},e}(),n=\"object\"==typeof process&&\"function\"==typeof process.nextTick?function(t){e||(e=Promise.resolve()),e.then(function(){process.nextTick(t)})}:\"function\"==typeof setImmediate?function(e){setImmediate(e)}:function(e){setTimeout(e)};function r(e,t,n){a(t);for(var r=0;r<t.keys.length;r++)e.clear(t.keys[r]),t.callbacks[r].reject(n)}function a(e){if(e.cacheHits)for(var t=0;t<e.cacheHits.length;t++)e.cacheHits[t]()}function o(e){return\"object\"==typeof e&&null!==e&&\"number\"==typeof e.length&&(0===e.length||e.length>0&&Object.prototype.hasOwnProperty.call(e,e.length-1))}return m=t}(),E=g(b);function w({debug:e,apiKey:t,secretKey:r,sourceLanguage:a,_apiUrl:o,formality:c,_loaderFactory:i}){const s={debug:!!e,apiKey:t,secretKey:r,lang:n.EN,sourceLang:a,apiUrl:o,formality:c},u=new E((i??y)(s),{cacheKeyFn:p(t,a)});return(e,t,n)=>u.load({text:t,...n,lang:e})}const T=w,_=n.EN;function S(e,t){if(!e)return t??_;if([n.FA_AF,n.FR_CA,n.PT_PT,n.ES_MX].includes(e))return e;const r=e.includes(\"-\")?e.split(\"-\")[0]:e;return Object.values(n).includes(r)?r:t||(console.warn(`Language not found for UTS locale \"${e}\" and no fallback provided was provided. Falling back to \"${_}\"`),_)}const A=/\\{(\\d+)\\}/g,k=e=>e.replace(/[.*+?^${}()|[\\]\\\\]/g,\"\\\\$&\");function R(e){const t=Object.keys(e).sort((e,t)=>t.length-e.length),n=t.length>0?new RegExp(`\\\\$(${t.map(k).join(\"|\")})`,\"g\"):null,r=new Map,a=[];return{values:a,replace:t=>n?t.replace(n,(t,n)=>{let o=r.get(n);return void 0===o&&(o=a.push(String(e[n]??\"\"))-1,r.set(n,o)),`{${o}}`}):t,unused:()=>t.filter(e=>!r.has(e))}}function $(t){t.length>0&&console.warn(`[${e}]: ${t.map(e=>`$${e}`).join(\", \")} not found in the text. Check the spelling, or remove ${1===t.length?\"it\":\"them\"} from the variables.`)}function K(e,t){const{replace:n,values:r,unused:a}=R(t);return{template:n(e),values:r,unused:a()}}function P(e,t){return e.replace(A,(e,n)=>Number(n)<t.length?t[Number(n)]:e)}function F(e){const t=document.createTreeWalker(e,NodeFilter.SHOW_TEXT),n=[];for(let e=t.nextNode();e;e=t.nextNode())n.push(e);return n}function L(e,t){const n=document.createElement(\"template\");n.innerHTML=e;const{replace:r,values:a,unused:o}=R(t);return F(n.content).forEach(e=>{e.data=r(e.data)}),{template:n.innerHTML,values:a,unused:o()}}function M(e,t){F(e).forEach(e=>{const n=P(e.data,t);n!==e.data&&(e.data=n)})}export{E as DataLoader,n as Language,p as cacheKeyFn,h as defaultDataLoaderOptions,y as defaultLoaderFactory,M as fillElement,P as fillPlaceholders,c as isSecretKey,e as libraryName,t as libraryWebsite,l as maxIdLength,u as resolveApiKey,o as secretKeyEnvVariable,i as secretKeyFromEnv,T as setupT,w as setupTranslate,R as templater,L as toHtmlTemplate,K as toTemplate,S as utsLocaleToLanguage,$ as warnAboutUnused};\n//# sourceMappingURL=index.es.js.map\n","import {\n cacheKeyFn,\n DataLoader,\n DataLoaderLoadParams,\n defaultLoaderFactory,\n fillElement,\n fillPlaceholders,\n Language,\n libraryName,\n libraryWebsite,\n MagicTranslateConfig,\n toHtmlTemplate,\n toTemplate,\n TextOptions,\n TranslateOptions,\n utsLocaleToLanguage,\n Variables,\n warnAboutUnused,\n} from '@magic-translate/core';\n\n/**\n * Type alias to make the language enum more flexible to also allow passing language strings\n * instead of just the enum.\n */\nexport type Languages = `${Language}`;\n\nexport interface TranslateParams extends Omit<DataLoaderLoadParams, 'text'> {\n /**\n * Values that are not translated, referenced as `$name` in the text. The text\n * is translated once as a template and cached, whatever the values are.\n */\n v?: Variables;\n}\n\nexport interface MagicTranslateOptions extends Omit<\n MagicTranslateConfig,\n 'language'\n> {\n /**\n * The language content is translated to. Defaults to the browser's language.\n */\n language?: Languages;\n /**\n * The element whose content is translated. Defaults to the whole document.\n */\n root?: Element;\n}\n\n/** Elements whose content is translated. */\nexport const CONTENT_SELECTOR = 't, mt-translate, [data-t]';\n/** Elements with attributes to translate, e.g. `data-t-attrs=\"placeholder title\"`. */\nexport const ATTRIBUTES_SELECTOR = '[data-t-attrs]';\n\ninterface Translation {\n source: string;\n // what was last written to the DOM, to tell our own changes from others\n rendered?: string;\n requestId: number;\n // the `data-v` attribute the source was last translated with\n variables: string | null;\n // to warn about unused variables once per text, not on every render\n template?: string;\n}\n\nfunction outermost(element: Element): Element {\n let current = element;\n for (\n let parent = current.parentElement?.closest(CONTENT_SELECTOR);\n parent;\n parent = current.parentElement?.closest(CONTENT_SELECTOR)\n ) {\n current = parent;\n }\n return current;\n}\n\nfunction optionsOf(element: Element): TextOptions {\n const options: TextOptions = {};\n const lang = element.getAttribute('data-lang');\n const formality = element.getAttribute('data-formality');\n const id = element.getAttribute('data-t-id');\n if (lang) {\n options.lang = lang as Languages;\n }\n if (formality) {\n options.formality = formality as TranslateOptions['formality'];\n }\n if (id) {\n options.id = id;\n }\n return options;\n}\n\n/**\n * Reads the values in `data-v`, a JSON object such as `{\"name\": \"Bob\"}`.\n * Returns `null` if the attribute is not valid, so the text is left as it is\n * rather than translated with `$name` in it.\n */\nfunction variablesOf(element: Element): Variables | undefined | null {\n const json = element.getAttribute('data-v');\n if (json === null) {\n return undefined;\n }\n try {\n const variables: unknown = JSON.parse(json);\n if (\n variables &&\n typeof variables === 'object' &&\n !Array.isArray(variables)\n ) {\n return variables as Variables;\n }\n } catch {\n // reported below\n }\n console.warn(\n `[${libraryName}]: data-v must be a JSON object, such as data-v='{\"name\": \"Bob\"}', but is ${json}`\n );\n return null;\n}\n\nfunction fillHtml(html: string, values: readonly string[]): string {\n if (values.length === 0) {\n return html;\n }\n const container = document.createElement('template');\n container.innerHTML = html;\n fillElement(container.content, values);\n return container.innerHTML;\n}\n\nexport class MagicTranslate {\n private currentLanguage: Languages;\n private dataLoader: DataLoader<DataLoaderLoadParams, string, string>;\n private readonly root?: Element;\n private readonly contents = new Map<Element, Translation>();\n private readonly attributes = new Map<Element, Map<string, Translation>>();\n private readonly listeners = new Set<(language: Languages) => void>();\n private observer?: MutationObserver;\n\n constructor(private readonly options: MagicTranslateOptions) {\n if (!options.apiKey) {\n throw new Error(`Missing API key. Please get one at ${libraryWebsite}`);\n }\n\n this.currentLanguage =\n options.language ??\n utsLocaleToLanguage(\n typeof navigator === 'undefined' ? undefined : navigator.language\n );\n this.dataLoader = this.createDataLoader();\n\n if (typeof document !== 'undefined') {\n this.root = options.root ?? document.documentElement;\n this.start(this.root);\n }\n }\n\n /**\n * The language content is currently translated to.\n */\n get language(): Languages {\n return this.currentLanguage;\n }\n\n /**\n * Translates the page to another language.\n */\n setLanguage(language: Languages): void {\n if (language === this.currentLanguage) {\n return;\n }\n\n this.currentLanguage = language;\n this.dataLoader = this.createDataLoader();\n\n this.forget(\n (element) => !element.isConnected || !this.root?.contains(element)\n );\n this.contents.forEach((_, element) => this.translateContent(element, true));\n this.attributes.forEach((_, element) =>\n this.translateAttributes(element, true)\n );\n this.listeners.forEach((listener) => listener(language));\n }\n\n /**\n * Calls `listener` whenever the language changes. Returns a function that\n * removes the listener again.\n */\n onLanguageChange(listener: (language: Languages) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n /**\n * Translates a string to the current language.\n */\n translate(\n text: string,\n { v, ...params }: TranslateParams = {}\n ): Promise<string> {\n if (!v) {\n return this.dataLoader.load({ text, ...params });\n }\n const { template, values, unused } = toTemplate(text, v);\n warnAboutUnused(unused);\n return this.dataLoader\n .load({ text: template, ...params })\n .then((translation) => fillPlaceholders(translation, values));\n }\n\n /**\n * Stops translating the page. Content that is already translated stays\n * translated.\n */\n destroy(): void {\n this.observer?.disconnect();\n this.contents.clear();\n this.attributes.clear();\n this.listeners.clear();\n }\n\n private createDataLoader() {\n const { debug, apiKey, sourceLanguage, _apiUrl, formality } = this.options;\n const loaderFactory = this.options._loaderFactory ?? defaultLoaderFactory;\n\n return new DataLoader<DataLoaderLoadParams, string, string>(\n loaderFactory({\n debug: !!debug,\n apiKey,\n lang: this.currentLanguage,\n sourceLang: sourceLanguage,\n apiUrl: _apiUrl,\n formality,\n }),\n {\n cacheKeyFn: cacheKeyFn(apiKey, sourceLanguage, this.currentLanguage),\n }\n );\n }\n\n private start(root: Element) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n this.collect(root, contents, attributes);\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n\n // Picks up content that is added or changed later.\n this.observer = new MutationObserver((records) =>\n this.handleMutations(records)\n );\n this.observer.observe(root, {\n subtree: true,\n childList: true,\n characterData: true,\n attributes: true,\n });\n }\n\n private collect(\n root: Element,\n contents: Set<Element>,\n attributes: Set<Element>\n ) {\n const all = [root, ...Array.from(root.querySelectorAll('*'))];\n for (const element of all) {\n if (element.matches(CONTENT_SELECTOR)) {\n contents.add(outermost(element));\n } else if (\n element.matches(ATTRIBUTES_SELECTOR) &&\n !element.closest(CONTENT_SELECTOR)\n ) {\n attributes.add(element);\n }\n }\n }\n\n private handleMutations(records: MutationRecord[]) {\n const contents = new Set<Element>();\n const attributes = new Set<Element>();\n\n for (const record of records) {\n const target =\n record.target.nodeType === Node.ELEMENT_NODE\n ? (record.target as Element)\n : record.target.parentElement;\n if (!target) {\n continue;\n }\n\n const content = target.closest(CONTENT_SELECTOR);\n if (content) {\n contents.add(outermost(content));\n continue;\n }\n\n if (record.type === 'attributes' && target.matches(ATTRIBUTES_SELECTOR)) {\n attributes.add(target);\n }\n record.addedNodes.forEach((node) => {\n if (node.nodeType === Node.ELEMENT_NODE) {\n this.collect(node as Element, contents, attributes);\n }\n });\n }\n\n if (records.some((record) => record.removedNodes.length > 0)) {\n this.forget((element) => !element.isConnected);\n }\n contents.forEach((element) => this.translateContent(element));\n attributes.forEach((element) => this.translateAttributes(element));\n }\n\n private forget(predicate: (element: Element) => boolean) {\n for (const element of this.contents.keys()) {\n if (predicate(element)) {\n this.contents.delete(element);\n }\n }\n for (const element of this.attributes.keys()) {\n if (predicate(element)) {\n this.attributes.delete(element);\n }\n }\n }\n\n private translateContent(element: Element, force = false) {\n const html = element.innerHTML;\n const variablesJson = element.getAttribute('data-v');\n let translation = this.contents.get(element);\n if (!translation) {\n translation = { source: html, requestId: 0, variables: variablesJson };\n this.contents.set(element, translation);\n } else if (html !== translation.rendered && html !== translation.source) {\n // changed by someone else, e.g. the page's own scripts\n translation.source = html;\n translation.rendered = undefined;\n translation.variables = variablesJson;\n } else if (variablesJson !== translation.variables) {\n // only the values changed, so the cached translation is reused\n translation.variables = variablesJson;\n } else if (!force) {\n return;\n }\n\n const [, leadingWhitespace, text, trailingWhitespace] =\n /^(\\s*)([\\s\\S]*?)(\\s*)$/.exec(\n translation.source.replace(/<!--[\\s\\S]*?-->/g, '')\n )!;\n if (!text) {\n return;\n }\n\n const variables = variablesOf(element);\n if (variables === null) {\n return;\n }\n const { template, values, unused } = variables\n ? toHtmlTemplate(text, variables)\n : { template: text, values: [], unused: [] };\n if (template !== translation.template) {\n translation.template = template;\n warnAboutUnused(unused);\n }\n\n const current = translation;\n const show = (translated: string) => {\n const rendered = `${leadingWhitespace}${fillHtml(translated, values)}${trailingWhitespace}`;\n if (element.innerHTML !== rendered) {\n element.innerHTML = rendered;\n }\n current.rendered = element.innerHTML;\n };\n // Until the first translation arrives, show the values instead of `$name`.\n if (variables && current.rendered === undefined) {\n show(template);\n }\n\n // make sure that we only ever use the response of the most recent request.\n const requestId = ++current.requestId;\n this.translate(template, optionsOf(element)).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n show(translated);\n });\n }\n\n private translateAttributes(element: Element, force = false) {\n const names = (element.getAttribute('data-t-attrs') ?? '')\n .split(/[\\s,]+/)\n .filter(Boolean);\n const variablesJson = element.getAttribute('data-v');\n let translations = this.attributes.get(element);\n if (!translations) {\n translations = new Map();\n this.attributes.set(element, translations);\n }\n\n for (const name of names) {\n const value = element.getAttribute(name);\n if (!value?.trim()) {\n continue;\n }\n\n let translation = translations.get(name);\n if (!translation) {\n translation = { source: value, requestId: 0, variables: variablesJson };\n translations.set(name, translation);\n } else if (\n value !== translation.rendered &&\n value !== translation.source\n ) {\n translation.source = value;\n translation.rendered = undefined;\n translation.variables = variablesJson;\n } else if (variablesJson !== translation.variables) {\n translation.variables = variablesJson;\n } else if (!force) {\n continue;\n }\n\n const variables = variablesOf(element);\n if (variables === null) {\n continue;\n }\n const { template, values, unused } = variables\n ? toTemplate(translation.source, variables)\n : { template: translation.source, values: [], unused: [] };\n if (template !== translation.template) {\n translation.template = template;\n warnAboutUnused(unused);\n }\n\n const current = translation;\n const show = (translated: string) => {\n const rendered = fillPlaceholders(translated, values);\n current.rendered = rendered;\n if (element.getAttribute(name) !== rendered) {\n element.setAttribute(name, rendered);\n }\n };\n if (variables && current.rendered === undefined) {\n show(template);\n }\n\n const requestId = ++current.requestId;\n // An id stands for one text, and an element's attributes are several.\n const { id: _id, ...options } = optionsOf(element);\n this.translate(template, options).then((translated) => {\n if (requestId !== current.requestId || !element.isConnected) {\n return;\n }\n show(translated);\n });\n }\n }\n}\n\n/**\n * Starts translating the page: the content of every `<t>` element (or element\n * with a `data-t` attribute), and the attributes listed in `data-t-attrs`.\n * Content added later is translated as well.\n */\nexport function createMagicTranslate(\n options: MagicTranslateOptions\n): MagicTranslate {\n return new MagicTranslate(options);\n}\n","import {\n createMagicTranslate,\n Languages,\n MagicTranslate,\n TranslateParams,\n} from './magic-translate';\n\nexport * from './index';\n\ndeclare global {\n interface Window {\n magicTranslate?: MagicTranslate;\n }\n}\n\nconst STORAGE_KEY = 'magic-translate-language';\n\nfunction storedLanguage(): Languages | undefined {\n try {\n return (localStorage.getItem(STORAGE_KEY) as Languages | null) ?? undefined;\n } catch {\n return undefined;\n }\n}\n\n// `<script src=\".../magic-translate.min.js\" data-api-key=\"...\"></script>`\n// starts translating the page without any further code.\nconst script = document.currentScript as HTMLScriptElement | null;\nconst apiKey = script?.dataset.apiKey;\n\nif (script && apiKey) {\n const { language, sourceLanguage, formality } = script.dataset;\n\n const start = () => {\n const magicTranslate = createMagicTranslate({\n apiKey,\n // a language picked with the language switcher outlives page loads\n language: storedLanguage() ?? (language as Languages | undefined),\n sourceLanguage: sourceLanguage as Languages | undefined,\n formality: formality as TranslateParams['formality'],\n debug: script.hasAttribute('data-debug'),\n });\n magicTranslate.onLanguageChange((language) => {\n try {\n localStorage.setItem(STORAGE_KEY, language);\n } catch {\n // storage is unavailable, e.g. in some private windows\n }\n });\n window.magicTranslate = magicTranslate;\n document.dispatchEvent(\n new CustomEvent('magictranslate:ready', { detail: magicTranslate })\n );\n };\n\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', start);\n } else {\n start();\n }\n}\n"],"mappings":"A,6FAKA,IAAMU,EAAE,kBAAkBC,EAAE,4BAAgCC,EAAE,SAASC,EAAE,EAAE,CAAC,OAAO,OAAO,KAAK,CAAC,CAAC,CAAC,OAAO,GAAY,EAAE,KAAX,IAAK,EAAQ,CAAC,CAAC,QAAQ,EAAE,KAAK,CAAC,GAAG,GAAG,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,IAAM,EAAE,IAAI,gBAAgB,GAAG,EAAE,EAAE,KAAK,CAAC,MAAM,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,CAAC,EAAY,OAAO,GAAjB,UAA2B,EAAE,OAAO,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,MAAM,QAAQ,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,MAAM,QAAQ,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,MAAM,QAAQ,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,MAAM,QAAQ,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,MAAM,QAAQ,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,IAAI,EAAA,CAAE,AAAID,IAAE,CAAC,CAAE,EAAE,IAAM,EAAE,6BAA6BE,EAAE,GAAG,CAAC,CAAC,GAAG,WAAW,IAAI,EAAE,SAASC,GAAG,CAAC,GAAK,CAAC,QAAQ,GAAG,WAAW,OAAO,GAAG,KAAAC,4BAAU,IAAK,EAAC,CAAC,IAAIC,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,OAAOL,EAAE,UAAUC,GAAG,CAAC,OAAmB,OAAO,OAApB,IAA2BA,GAAGE,EAAE,GAAGH,GAAG,CAACC,GAAG,CAACC,EAAEF,CAAC,GAAGK,IAAI,EAAE,CAAC,EAAE,QAAQ,MAAM,iNAAiL,GAAGH,EAAEF,CAAC,EAAE,IAAK,GAAEA,EAAE,CAAC,IAAMM,EAAE,IAAIC,EAAE,CAAC,MAAM,CAAC,EAAE,OAAO,gCAAgC,KAAKP,EAAE,EAAE,EAAMQ,EAAE,SAASC,EAAE,EAAE,CAAC,GAAYV,IAAT,IAAK,GAAM,OAAOA,EAAE,KAAK,GAAGA,EAAE,QAAQ,IAAIA,EAAE,KAAK,QAAQ,MAAM,IAAID,EAAE,sBAAsBC,EAAE,oCAAoC,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,qBAAqB,uBAAuB,EAAE,oBAAoB,sBAAsB,EAAE,sBAAsB,uBAAuB,EAAA,CAAE,AAAIS,IAAE,CAAC,CAAE,EAAE,IAAME,GAAG,EAAE,EAAE,IAAI,GAAG,OAAO,QAAQT,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,eAAeU,EAAE,YAAY,GAAG,OAAO,GAAGA,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,IAAI,GAAG,EAAE,GAAG,EAAE,KAAK,GAAG,IAAI,EAAE,EAAEC,EAAE,GAAG,KAAM,IAAG,CAAC,GAAGZ,EAAE,OAAO,QAAQ,MAAM,kDAAuCa,CAAC,EAAEb,EAAE,OAAOA,EAAE,WAAW,OAAOa,EAAE,IAAI,GAAG,EAAE,IAAI,EAAE,GAAK,CAAC,KAAKX,EAAE,UAAUC,GAAGH,EAAE,EAAE,EAAEA,CAAC,EAAE,GAAG,CAAC,EAAE,OAAOA,EAAE,QAAQA,EAAE,WAAW,QAAQ,MAAM,iFAAiD,EAAEa,EAAE,IAAI,GAAG,EAAE,IAAI,EAAE,IAAMP,EAAEL,EAAE,CAAC,OAAO,EAAE,KAAKC,EAAE,UAAUC,EAAE,MAAMU,EAAE,KAAK,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,GAAGF,EAAE,GAAGE,KAAKZ,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,GAAGY,EAAE,GAAGJ,EAAEE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,MAAM,GAAGX,EAAE,QAAQO,EAAE,OAAO,eAAe,CAAC,OAAO,OAAO,KAAKP,EAAE,QAAQ,KAAK,UAAUM,CAAC,EAAE,EAAEA,CAAC,EAAE,QAAQ,CAAC,eAAeN,EAAE,QAAQ,mBAAmB,mCAAmC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,YAAYD,EAAEA,EAAE,SAAS,SAASA,EAAE,QAAQ,MAAM,IAAID,EAAE,KAAKC,EAAE,SAAS,EAAE,QAAQ,MAAM,IAAID,EAAE,qDAAqD,KAAK,UAAUC,CAAC,GAAG,EAAEc,EAAE,IAAI,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,IAAI,QAAQ,MAAM,IAAIf,EAAE,uCAAuCC,CAAC,EAAEc,EAAE,IAAI,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,SAASC,EAAE,EAAE,CAAC,OAAO,GAAG,EAAE,YAAY,OAAO,UAAU,eAAe,KAAK,EAAE,SAAS,EAAE,EAAE,QAAQ,CAAC,CAAC,IAAIC,EAAEC,EAA6uIC,EAAEH,EAAvuI,UAAU,CAAC,GAAGE,EAAE,OAAOD,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,UAAU,CAAC,SAAS,EAAE,EAAE,EAAE,CAAC,GAAe,OAAO,GAAnB,WAAqB,MAAU,UAAU,uHAAuH,EAAE,GAAG,EAAE,KAAK,aAAa,EAAE,KAAK,cAAc,SAAS,EAAE,CAAwB,GAAhB,GAAG,CAAC,IAAI,EAAE,MAAY,MAAO,GAAE,IAAIf,EAAE,GAAG,EAAE,aAAa,GAAYA,IAAT,IAAK,GAAM,MAAO,GAAE,EAAE,GAAa,OAAOA,GAAjB,UAAoBA,EAAE,EAAE,MAAU,UAAU,2CAA2CA,CAAC,EAAE,OAAOA,CAAC,EAAE,CAAC,EAAE,KAAK,iBAAiB,SAAS,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,gBAAgB,GAAY,IAAT,IAAK,GAAM,OAAO,EAAE,GAAe,OAAO,GAAnB,WAAqB,MAAU,UAAU,uCAAuC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,KAAK,YAAY,SAAS,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,WAAW,GAAY,IAAT,IAAK,GAAM,OAAO,SAAS,EAAE,CAAC,OAAO,CAAC,EAAE,GAAe,OAAO,GAAnB,WAAqB,MAAU,UAAU,kCAAkC,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,EAAE,KAAK,UAAU,SAAS,EAAE,CAAwB,GAAhB,GAAG,CAAC,IAAI,EAAE,MAAY,OAAO,KAAK,IAAIA,EAAE,GAAG,EAAE,SAAS,GAAYA,IAAT,IAAK,GAAM,OAAO,IAAI,IAAI,GAAUA,IAAP,KAAS,CAAC,IAAIC,EAAE,CAAC,MAAM,MAAM,SAAS,OAAO,CAAC,CAAC,OAAO,SAAS,EAAE,CAAC,OAAOD,GAAe,OAAOA,EAAE,IAArB,UAAuB,CAAC,EAAE,GAAOC,EAAE,SAAN,EAAa,MAAU,UAAU,oCAAoCA,EAAE,KAAK,IAAI,CAAC,CAAC,CAAC,OAAOD,CAAC,EAAE,CAAC,EAAE,KAAK,OAAO,KAAK,KAAK,KAAK,SAAS,EAAE,CAA4B,OAAxB,GAAG,EAAE,KAAY,EAAE,KAAY,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,UAAU,MAAO,GAAE,KAAK,SAAS,EAAE,CAAC,GAAS,GAAN,KAAQ,MAAU,UAAU,oEAAoE,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,OAAO,GAAU,IAAP,MAAU,CAAC,EAAE,eAAe,EAAE,KAAK,OAAO,EAAE,cAAc,OAAO,EAAE,IAAI,EAAE,CAAC,cAAc,CAAC,EAAE,KAAK,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,MAAO,GAAE,OAAO,EAAE,EAAE,iBAAiB,UAAU,EAAE,SAAS,EAAE,EAAE,CAAC,GAAG,EAAE,cAAc,CAAC,EAAM,EAAE,KAAK,SAAX,EAAkB,OAAO,KAAKW,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,EAAE,EAAM,UAAU,sJAAsJ,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAe,OAAO,EAAE,MAArB,WAA0B,OAAO,EAAE,EAAE,EAAM,UAAU,yJAAyJ,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,SAAS,EAAE,CAAC,GAAG,CAACE,EAAE,CAAC,EAAE,MAAU,UAAU,qKAAqK,OAAO,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,SAAS,EAAE,KAAK,OAAO,MAAU,UAAU;;;EAAuN,OAAO,EAAE,IAAI,EAAE;;;EAAgB,OAAO,CAAC,CAAC,EAAEF,EAAE,CAAC,EAAE,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,UAAU,OAAO,IAAI,CAAC,IAAI,EAAE,EAAE,GAAG,aAAa,MAAM,EAAE,UAAU,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE,UAAU,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,SAAS,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAA,CAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAET,EAAE,KAAK,UAAU,GAAGA,EAAE,CAAC,EAAE,KAAK,YAAY,CAAC,EAAE,IAAIC,EAAED,EAAE,IAAI,CAAC,EAAE,GAAGC,EAAE,CAAC,IAAIE,EAAE,AAAc,EAAE,YAAU,CAAC,EAAG,OAAO,IAAI,QAAQ,SAAS,EAAE,CAACA,EAAE,KAAK,UAAU,CAAC,EAAEF,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,IAAIe,EAAE,IAAI,QAAQ,SAAS,EAAE,EAAE,CAAC,EAAE,UAAU,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,OAAOhB,GAAGA,EAAE,IAAI,EAAEgB,CAAC,EAAEA,CAAC,EAAE,EAAE,SAAS,SAAS,EAAE,CAAC,GAAG,CAACL,EAAE,CAAC,EAAE,MAAU,UAAU,0EAA0E,EAAE,GAAG,EAAE,IAAI,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,OAAO,IAAI,EAAE,KAAK,KAAK,KAAK,EAAE,EAAE,CAAC,CAAC,MAAM,SAAS,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,QAAQ,IAAI,CAAC,CAAC,EAAE,EAAE,MAAM,SAAS,EAAE,CAAC,IAAI,EAAE,KAAK,UAAU,GAAG,EAAE,CAAC,IAAI,EAAE,KAAK,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,EAAE,SAAS,UAAU,CAAC,IAAI,EAAE,KAAK,UAAU,OAAO,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,MAAM,SAAS,EAAE,EAAE,CAAC,IAAI,EAAE,KAAK,UAAU,GAAG,EAAE,CAAC,IAAI,EAAEF,EAAE,KAAK,YAAY,CAAC,EAAc,EAAE,IAAIA,CAAC,IAAhB,IAAK,KAAa,aAAa,OAAO,EAAE,QAAQ,OAAO,CAAC,EAAA,CAAG,MAAM,UAAU,CAAC,CAAC,EAAE,EAAE,QAAQ,QAAQ,CAAC,EAAE,EAAE,IAAIA,EAAE,CAAC,EAAC,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,EAAE,EAAY,OAAO,SAAjB,UAAsC,OAAO,QAAQ,UAA3B,WAAoC,SAAS,EAAE,CAAC,AAAI,IAAE,QAAQ,QAAQ,EAAG,EAAE,KAAK,UAAU,CAAC,QAAQ,SAAS,CAAC,CAAC,CAAC,CAAC,EAAc,OAAO,cAAnB,WAAgC,SAAS,EAAE,CAAC,aAAa,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,WAAW,CAAC,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,CAACA,EAAE,CAAC,EAAE,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,KAAK,OAAO,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,UAAU,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,SAASA,EAAE,EAAE,CAAC,GAAG,EAAE,UAAU,IAAI,IAAI,EAAE,EAAE,EAAE,EAAE,UAAU,OAAO,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,SAASE,EAAE,EAAE,CAAC,OAAgB,OAAO,GAAjB,YAA2B,GAAa,OAAO,EAAE,QAAnB,WAAgC,EAAE,SAAN,GAAc,EAAE,OAAO,GAAG,OAAO,UAAU,eAAe,KAAK,EAAE,EAAE,OAAO,CAAC,EAAE,CAAC,MAAO,GAAE,CAAC,EAAQ,CAAC,EAAE,SAASM,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,UAAUlB,EAAE,eAAeU,EAAE,QAAQE,EAAE,UAAUX,EAAE,eAAeC,GAAG,CAAC,IAAME,EAAE,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,EAAE,UAAUJ,EAAE,KAAKD,EAAE,GAAG,WAAWW,EAAE,OAAOE,EAAE,UAAUX,CAAC,EAAEgB,EAAE,IAAID,GAAGd,GAAGS,EAAA,CAAGP,CAAC,EAAE,CAAC,WAAWK,EAAE,EAAEC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,IAAIO,EAAE,KAAK,CAAC,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,IAAME,EAAED,EAAEE,EAAErB,EAAE,GAAG,SAASsB,EAAE,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,OAAO,GAAGD,EAAE,GAAG,CAACrB,EAAE,MAAMA,EAAE,MAAMA,EAAE,MAAMA,EAAE,KAAK,CAAC,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,IAAMC,EAAE,EAAE,SAAS,GAAG,EAAE,EAAE,MAAM,GAAG,CAAC,CAAC,GAAG,EAAE,OAAO,OAAO,OAAOD,CAAC,CAAC,CAAC,SAASC,CAAC,EAAEA,EAAE,IAAI,QAAQ,KAAK,sCAAsC,EAAE,4DAA4DoB,EAAE,EAAE,EAAEA,EAAE,CAAC,IAAME,EAAE,aAAaC,EAAE,GAAG,EAAE,QAAQ,sBAAsB,MAAM,EAAE,SAASC,EAAE,EAAE,CAAC,IAAM,EAAE,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAM,OAAO,OAAO,EAAE,IAAID,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,GAAG,GAAG,EAAE,KAAK,EAAE,IAAI,IAAIb,EAAE,CAAC,EAAE,MAAM,CAAC,OAAOA,EAAE,QAAQ,GAAG,EAAE,EAAE,QAAQ,GAAG,EAAE,IAAI,CAAC,IAAIE,EAAE,EAAE,IAAI,CAAC,EAAE,OAAgBA,IAAT,IAAK,KAAQ,EAAEF,EAAE,KAAK,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,IAAI,EAAEE,CAAC,GAAG,IAAIA,EAAE,EAAE,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAASa,EAAE,EAAE,CAAC3B,EAAE,OAAO,GAAG,QAAQ,KAAK,sBAAWA,EAAE,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,IAAI,EAAE,wDAA4DA,EAAE,SAAN,EAAa,KAAK,OAAO,qBAAqB,CAAC,CAAC,SAAS4B,EAAE,EAAE,EAAE,CAAC,GAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAOhB,GAAGc,EAAE,CAAC,EAAE,MAAM,CAAC,SAAS,EAAE,CAAC,EAAE,OAAO,EAAE,OAAOd,EAAE,CAAC,CAAC,CAAC,SAASiB,EAAE,EAAE,EAAE,CAAC,OAAO,EAAE,QAAQL,GAAG,EAAE,IAAI,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,SAASM,EAAE,EAAE,CAAC,IAAM,EAAE,SAAS,iBAAiB,EAAE,WAAW,SAAS,EAAE,EAAE,CAAC,EAAE,IAAI,IAAI,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC,SAASC,EAAE,EAAE,EAAE,CAAC,IAAM,EAAE,SAAS,cAAc,UAAU,EAAE,EAAE,UAAU,EAAE,GAAK,CAAC,QAAQ,EAAE,OAAOnB,EAAE,OAAOE,GAAGY,EAAE,CAAC,EAAE,OAAOI,EAAE,EAAE,OAAO,CAAC,CAAC,QAAQ,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,OAAOlB,EAAE,OAAOE,EAAE,CAAC,CAAC,CAAC,SAASkB,EAAE,EAAE,EAAE,CAACF,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,IAAM,EAAED,EAAE,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CC4CrnS,IAAaI,EAAmB,4BAEnBC,EAAsB,iBAanC,SAASC,EAAU,EAA2B,CAC5C,IAAIC,EAAUC,EACd,IACE,IAAIC,EAASF,EAAQ,eAAe,QAAQH,CAAgB,EAC5DK,EACA,EAASF,EAAQ,eAAe,QAAQH,CAAgB,EAExD,EAAUK,EAEZ,OAAOF,CACT,CAEA,SAASG,EAAU,EAA+B,CAChD,IAAMC,EAAuB,CAAC,EACxBC,EAAOJ,EAAQ,aAAa,WAAW,EACvCK,EAAYL,EAAQ,aAAa,gBAAgB,EACjDM,EAAKN,EAAQ,aAAa,WAAW,EAU3C,OATII,IACF,EAAQ,KAAOA,GAEbC,IACF,EAAQ,UAAYA,GAElBC,IACF,EAAQ,GAAKA,GAERH,CACT,CAOA,SAASI,EAAY,EAAgD,CACnE,IAAMC,EAAOR,EAAQ,aAAa,QAAQ,EAC1C,GAAIQ,IAAS,KAGb,IAAI,CACF,IAAMC,EAAqB,KAAK,MAAMD,CAAI,EAC1C,GACEC,GACA,OAAOA,GAAc,UACrB,CAAC,MAAM,QAAQA,CAAS,EAExB,OAAOA,CAEX,MAAQ,CAER,CAIA,OAHA,QAAQ,KACN,IAAIzD,EAAY,4EAA4EwD,GAC9F,EACO,IAJP,CAKF,CAEA,SAASE,EAAS,EAAc,EAAmC,CACjE,GAAIC,EAAO,SAAW,EACpB,OAAOC,EAET,IAAMC,EAAY,SAAS,cAAc,UAAU,EAGnD,MAFA,GAAU,UAAYD,EACtBjB,EAAYkB,EAAU,QAASF,CAAM,EAC9BE,EAAU,SACnB,CAEA,IAAaC,EAAb,KAA4B,CAS1B,YAAY,EAAiD,CAC3D,GAD2B,KAAA,QAAAX,EALD,KAAA,SAAA,IAAI,IACF,KAAA,WAAA,IAAI,IACL,KAAA,UAAA,IAAI,IAI3B,CAACA,EAAQ,OACX,MAAU,MAAM,sCAAsClD,GAAgB,EAGxE,KAAK,gBACHkD,EAAQ,UACRjD,EACE,OAAO,UAAc,IAAc,IAAA,GAAY,UAAU,QAC3D,EACF,KAAK,WAAa,KAAK,iBAAiB,EAEpC,OAAO,SAAa,MACtB,KAAK,KAAOiD,EAAQ,MAAQ,SAAS,gBACrC,KAAK,MAAM,KAAK,IAAI,EAExB,CAKA,IAAI,UAAsB,CACxB,OAAO,KAAK,eACd,CAKA,YAAY,EAA2B,CACjCY,IAAa,KAAK,kBAItB,KAAK,gBAAkBA,EACvB,KAAK,WAAa,KAAK,iBAAiB,EAExC,KAAK,OACF,GAAY,CAACf,EAAQ,aAAe,CAAC,KAAK,MAAM,SAASA,CAAO,CACnE,EACA,KAAK,SAAS,SAAS,EAAG,IAAY,KAAK,iBAAiBA,EAAS,EAAI,CAAC,EAC1E,KAAK,WAAW,SAAS,EAAG,IAC1B,KAAK,oBAAoBA,EAAS,EAAI,CACxC,EACA,KAAK,UAAU,QAAS,GAAagB,EAASD,CAAQ,CAAC,EACzD,CAMA,iBAAiB,EAAqD,CAEpE,OADA,KAAK,UAAU,IAAIC,CAAQ,MACd,KAAK,UAAU,OAAOA,CAAQ,CAC7C,CAKA,UACE,EACA,CAAE,IAAG,GAAGC,GAA4B,CAAC,EACpB,CACjB,GAAI,CAACrC,EACH,OAAO,KAAK,WAAW,KAAK,CAAE,OAAM,GAAGqC,CAAO,CAAC,EAEjD,GAAM,CAAE,WAAU,SAAQ,UAAW9D,EAAW+D,EAAMtC,CAAC,EAEvD,OADAU,EAAgB6B,CAAM,EACf,KAAK,WACT,KAAK,CAAE,KAAMC,EAAU,GAAGH,CAAO,CAAC,CAAC,CACnC,KAAM,GAAgB7D,EAAiBiE,EAAaV,CAAM,CAAC,CAChE,CAMA,SAAgB,CACd,KAAK,UAAU,WAAW,EAC1B,KAAK,SAAS,MAAM,EACpB,KAAK,WAAW,MAAM,EACtB,KAAK,UAAU,MAAM,CACvB,CAEA,kBAA2B,CACzB,GAAM,CAAE,QAAO,SAAQ,iBAAgB,UAAS,aAAc,KAAK,QAGnE,OAAO,IAAIrD,GAFW,KAAK,QAAQ,gBAAkBD,EAGnD,CAAc,CACZ,MAAO,CAAC,CAACiE,EACT,SACA,KAAM,KAAK,gBACX,WAAYC,EACZ,OAAQC,EACR,WACF,CAAC,EACD,CACE,WAAYjE,EAAWkE,EAAQF,EAAgB,KAAK,eAAe,CACrE,CACF,CACF,CAEA,MAAc,EAAe,CAC3B,IAAMG,EAAW,IAAI,IACfC,EAAa,IAAI,IACvB,KAAK,QAAQC,EAAMF,EAAUC,CAAU,EACvCD,EAAS,QAAS,GAAY,KAAK,iBAAiB1B,CAAO,CAAC,EAC5D2B,EAAW,QAAS,GAAY,KAAK,oBAAoB3B,CAAO,CAAC,EAGjE,KAAK,SAAW,IAAI,iBAAkB,GACpC,KAAK,gBAAgB6B,CAAO,CAC9B,EACA,KAAK,SAAS,QAAQD,EAAM,CAC1B,QAAS,GACT,UAAW,GACX,cAAe,GACf,WAAY,EACd,CAAC,CACH,CAEA,QACE,EACA,EACA,EACA,CACA,IAAME,EAAM,CAACF,EAAM,GAAG,MAAM,KAAKA,EAAK,iBAAiB,GAAG,CAAC,CAAC,EAC5D,IAAK,IAAM5B,KAAW8B,EAChB9B,EAAQ,QAAA,2BAAwB,EAClC0B,EAAS,IAAI5B,EAAUE,CAAO,CAAC,EAE/BA,EAAQ,QAAA,gBAA2B,GACnC,CAACA,EAAQ,QAAA,2BAAwB,GAEjC2B,EAAW,IAAI3B,CAAO,CAG5B,CAEA,gBAAwB,EAA2B,CACjD,IAAM0B,EAAW,IAAI,IACfC,EAAa,IAAI,IAEvB,IAAK,IAAMI,KAAUF,EAAS,CAC5B,IAAMG,EACJD,EAAO,OAAO,WAAa,KAAK,aAC3BA,EAAO,OACRA,EAAO,OAAO,cACpB,GAAI,CAACC,EACH,SAGF,IAAMC,EAAUD,EAAO,QAAQpC,CAAgB,EAC3CqC,EACFP,EAAS,IAAI5B,EAAUmC,CAAO,CAAC,GAI7BF,EAAO,OAAS,cAAgBC,EAAO,QAAA,gBAA2B,GACpEL,EAAW,IAAIK,CAAM,EAEvBD,EAAO,WAAW,QAAS,GAAS,CAC9BG,EAAK,WAAa,KAAK,cACzB,KAAK,QAAQA,EAAiBR,EAAUC,CAAU,CAEtD,CAAC,EACH,CAEIE,EAAQ,KAAM,GAAWE,EAAO,aAAa,OAAS,CAAC,GACzD,KAAK,OAAQ,GAAY,CAAC/B,EAAQ,WAAW,EAE/C0B,EAAS,QAAS,GAAY,KAAK,iBAAiB1B,CAAO,CAAC,EAC5D2B,EAAW,QAAS,GAAY,KAAK,oBAAoB3B,CAAO,CAAC,CACnE,CAEA,OAAe,EAA0C,CACvD,IAAK,IAAMA,KAAW,KAAK,SAAS,KAAK,EACnCmC,EAAUnC,CAAO,GACnB,KAAK,SAAS,OAAOA,CAAO,EAGhC,IAAK,IAAMA,KAAW,KAAK,WAAW,KAAK,EACrCmC,EAAUnC,CAAO,GACnB,KAAK,WAAW,OAAOA,CAAO,CAGpC,CAEA,iBAAyB,EAAkB,EAAQ,GAAO,CACxD,IAAMY,EAAOZ,EAAQ,UACfoC,EAAgBpC,EAAQ,aAAa,QAAQ,EAC/CqB,EAAc,KAAK,SAAS,IAAIrB,CAAO,EAC3C,GAAI,CAACqB,EACH,EAAc,CAAE,OAAQT,EAAM,UAAW,EAAG,UAAWwB,CAAc,EACrE,KAAK,SAAS,IAAIpC,EAASqB,CAAW,OACjC,GAAIT,IAASS,EAAY,UAAYT,IAASS,EAAY,OAE/D,EAAY,OAAST,EACrB,EAAY,SAAW,IAAA,GACvB,EAAY,UAAYwB,OACnB,GAAIA,IAAkBf,EAAY,UAEvC,EAAY,UAAYe,OACnB,GAAI,CAACC,EACV,OAGF,GAAM,EAAGC,EAAmBpB,EAAMqB,GAChC,yBAAyB,KACvBlB,EAAY,OAAO,QAAQ,mBAAoB,EAAE,CACnD,EACF,GAAI,CAACH,EACH,OAGF,IAAMT,EAAYF,EAAYP,CAAO,EACrC,GAAIS,IAAc,KAChB,OAEF,GAAM,CAAE,WAAU,SAAQ,UAAWA,EACjCjD,EAAe0D,EAAMT,CAAS,EAC9B,CAAE,SAAUS,EAAM,OAAQ,CAAC,EAAG,OAAQ,CAAC,CAAE,EACzCE,IAAaC,EAAY,WAC3B,EAAY,SAAWD,EACvB9B,EAAgB6B,CAAM,GAGxB,IAAMpB,EAAUsB,EACVmB,EAAQ,GAAuB,CACnC,IAAMC,EAAW,GAAGH,IAAoB5B,EAASgC,EAAY/B,CAAM,IAAI4B,IACnEvC,EAAQ,YAAcyC,IACxB,EAAQ,UAAYA,GAEtB,EAAQ,SAAWzC,EAAQ,SAC7B,EAEIS,GAAaV,EAAQ,WAAa,IAAA,IACpCyC,EAAKpB,CAAQ,EAIf,IAAMuB,EAAY,EAAE5C,EAAQ,UAC5B,KAAK,UAAUqB,EAAUlB,EAAUF,CAAO,CAAC,CAAC,CAAC,KAAM,GAAe,CAC5D2C,IAAc5C,EAAQ,WAAcC,EAAQ,aAGhDwC,EAAKE,CAAU,CACjB,CAAC,CACH,CAEA,oBAA4B,EAAkB,EAAQ,GAAO,CAC3D,IAAME,GAAS5C,EAAQ,aAAa,cAAc,GAAK,GAAA,CACpD,MAAM,QAAQ,CAAC,CACf,OAAO,OAAO,EACXoC,EAAgBpC,EAAQ,aAAa,QAAQ,EAC/C6C,EAAe,KAAK,WAAW,IAAI7C,CAAO,EACzC6C,IACH,EAAe,IAAI,IACnB,KAAK,WAAW,IAAI7C,EAAS6C,CAAY,GAG3C,IAAK,IAAMC,KAAQF,EAAO,CACxB,IAAMG,EAAQ/C,EAAQ,aAAa8C,CAAI,EACvC,GAAI,CAACC,GAAO,KAAK,EACf,SAGF,IAAI1B,EAAcwB,EAAa,IAAIC,CAAI,EACvC,GAAI,CAACzB,EACH,EAAc,CAAE,OAAQ0B,EAAO,UAAW,EAAG,UAAWX,CAAc,EACtES,EAAa,IAAIC,EAAMzB,CAAW,OAC7B,GACL0B,IAAU1B,EAAY,UACtB0B,IAAU1B,EAAY,OAEtB,EAAY,OAAS0B,EACrB,EAAY,SAAW,IAAA,GACvB,EAAY,UAAYX,OACnB,GAAIA,IAAkBf,EAAY,UACvC,EAAY,UAAYe,OACnB,GAAI,CAACC,EACV,SAGF,IAAM5B,EAAYF,EAAYP,CAAO,EACrC,GAAIS,IAAc,KAChB,SAEF,GAAM,CAAE,WAAU,SAAQ,UAAWA,EACjCtD,EAAWkE,EAAY,OAAQZ,CAAS,EACxC,CAAE,SAAUY,EAAY,OAAQ,OAAQ,CAAC,EAAG,OAAQ,CAAC,CAAE,EACvDD,IAAaC,EAAY,WAC3B,EAAY,SAAWD,EACvB9B,EAAgB6B,CAAM,GAGxB,IAAMpB,EAAUsB,EACVmB,EAAQ,GAAuB,CACnC,IAAMC,EAAWrF,EAAiBsF,EAAY/B,CAAM,EACpD,EAAQ,SAAW8B,EACfzC,EAAQ,aAAa8C,CAAI,IAAML,GACjCzC,EAAQ,aAAa8C,EAAML,CAAQ,CAEvC,EACIhC,GAAaV,EAAQ,WAAa,IAAA,IACpCyC,EAAKpB,CAAQ,EAGf,IAAMuB,EAAY,EAAE5C,EAAQ,UAEtB,CAAE,GAAIiD,EAAK,GAAG7C,GAAYD,EAAUF,CAAO,EACjD,KAAK,UAAUoB,EAAUjB,CAAO,CAAC,CAAC,KAAM,GAAe,CACjDwC,IAAc5C,EAAQ,WAAcC,EAAQ,aAGhDwC,EAAKE,CAAU,CACjB,CAAC,CACH,CACF,CACF,EAOA,SAAgBO,EACd,EACgB,CAChB,OAAO,IAAInC,EAAeX,CAAO,CACnC,CCvcA,IAAM+C,EAAc,2BAEpB,SAASC,GAAwC,CAC/C,GAAI,CACF,OAAQ,aAAa,QAAQD,CAAW,GAA0B,IAAA,EACpE,MAAQ,CACN,MACF,CACF,CAIA,IAAME,EAAS,SAAS,cAClB3B,EAAS2B,GAAQ,QAAQ,OAE/B,GAAIA,GAAU3B,EAAQ,CACpB,GAAM,CAAE,WAAU,iBAAgB,aAAc2B,EAAO,QAEjDC,MAAc,CAClB,IAAMC,EAAiBL,EAAqB,CAC1C,SAEA,SAAUE,EAAe,GAAMpC,EACf,iBACL,YACX,MAAOqC,EAAO,aAAa,YAAY,CACzC,CAAC,EACDE,EAAe,iBAAkB,GAAa,CAC5C,GAAI,CACF,aAAa,QAAQJ,EAAanC,CAAQ,CAC5C,MAAQ,CAER,CACF,CAAC,EACD,OAAO,eAAiBuC,EACxB,SAAS,cACP,IAAI,YAAY,uBAAwB,CAAE,OAAQA,CAAe,CAAC,CACpE,CACF,EAEI,SAAS,aAAe,UAC1B,SAAS,iBAAiB,mBAAoBD,CAAK,EAEnDA,EAAM,CAEV,C"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@magic-translate/js",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "keywords": [
5
5
  "javascript",
6
6
  "vanilla-js",
@@ -48,7 +48,7 @@
48
48
  "node": ">=22.22.1"
49
49
  },
50
50
  "dependencies": {
51
- "@magic-translate/core": "^1.5.0"
51
+ "@magic-translate/core": "^1.6.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@types/node": "^26.6.5",