@yander/translation-widget 1.1.4-yander.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/LICENSE +13 -0
- package/README.md +483 -0
- package/dist/constants/index.d.ts +18 -0
- package/dist/constants/languages.d.ts +2 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +3000 -0
- package/dist/index.min.js +1 -0
- package/dist/lib/dom/index.d.ts +19 -0
- package/dist/lib/storage/localstorage.d.ts +24 -0
- package/dist/lib/translation/index.d.ts +19 -0
- package/dist/types/index.d.ts +79 -0
- package/dist/utils/utils.d.ts +15 -0
- package/dist/widget/index.d.ts +163 -0
- package/package.json +55 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).TranslationWidget=e()}(this,function(){"use strict";var t=Object.defineProperty,e=(e,i,n)=>((e,i,n)=>i in e?t(e,i,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[i]=n)(e,"symbol"!=typeof i?i+"":i,n);const i="jss-",n="https://api.jigsawstack.com/v1/ai/translate",a={pageLanguage:"en",autoDetectLanguage:!1,adjustFontSize:!1,mockMode:!1,position:"top-right",targetLanguages:["zh"],apiUrl:n,requestHeaders:{},includeApiKeyHeader:!0};class s{constructor(t,i=1e3){e(this,"timestamps",[]),e(this,"pending",Promise.resolve()),this.maxRequests=t,this.intervalMs=i}acquire(){return this.pending=this.pending.then(()=>this._acquire()),this.pending}async _acquire(){const t=Date.now();if(this.timestamps=this.timestamps.filter(e=>t-e<this.intervalMs),this.timestamps.length<this.maxRequests)return void this.timestamps.push(Date.now());const e=this.intervalMs-(t-this.timestamps[0]);await new Promise(t=>setTimeout(t,e)),this.timestamps=this.timestamps.filter(t=>Date.now()-t<this.intervalMs),this.timestamps.push(Date.now())}}const r={ar:"AR",de:"DE",en:"EN",es:"ES",fr:"FR",hi:"HI",it:"IT",ja:"JA",ko:"KO",pt:"PT",zh:"ZH"},o={a:"á",e:"é",i:"í",o:"ó",u:"ú",A:"Á",E:"É",I:"Í",O:"Ó",U:"Ú"};function l(t,e){var i,n;const a=t.trim();if(!a)return t;const s=`【${r[e]||e.toUpperCase()}】`,l=a.replace(/[aeiouAEIOU]/g,t=>o[t]||t);return`${(null==(i=t.match(/^\s*/))?void 0:i[0])||""}${s} ${l}${(null==(n=t.match(/\s*$/))?void 0:n[0])||""}`}class g{constructor(t,i={}){e(this,"publicKey"),e(this,"apiUrl"),e(this,"rateLimiter"),e(this,"mockMode"),e(this,"requestHeaders"),e(this,"includeApiKeyHeader"),this.publicKey=t,this.rateLimiter=new s(45),this.mockMode=i.mockMode??!1,this.apiUrl=i.apiUrl||n,this.requestHeaders=i.requestHeaders??{},this.includeApiKeyHeader=i.includeApiKeyHeader??!0}normalizeTranslations(t){var e;return Array.isArray(null==(e=t.data)?void 0:e.translations)?t.data.translations.map(t=>(null==t?void 0:t.translatedText)||""):Array.isArray(t.translated_text)?t.translated_text:"string"==typeof t.translated_text?[t.translated_text]:[]}getRequestTargetLanguageCode(t){return"zh"===t?"zh-CN":t}async translateBatchText(t,e,i=2,n=100){if(this.mockMode)return await new Promise(t=>setTimeout(t,120)),t.map(t=>function(t,e){return t.includes("<")?t.split(/(<[^>]+>)/g).map(t=>t.startsWith("<")?t:l(t,e)).join(""):l(t,e)}(t,e));await this.rateLimiter.acquire();let a=0;for(;a<i;)try{const i={"Content-Type":"application/json",...this.requestHeaders};this.includeApiKeyHeader&&this.publicKey&&(i["x-api-key"]=this.publicKey);const n=await fetch(this.apiUrl,{method:"POST",headers:i,body:JSON.stringify({texts:t,targetLanguageCode:this.getRequestTargetLanguageCode(e),sourceLanguageCode:"en"})});if(!n.ok){const t=new Error(`Error translating text: ${n.statusText}`);throw t.status=n.status,t.response=n,t}const a=await n.json();if("number"==typeof a.code&&1e3!==a.code){throw new Error(a.message||"Translation service returned an invalid code")}const s=this.normalizeTranslations(a);if(0===s.length){throw new Error("Translation service returned empty translations")}return s}catch(s){if(a++,a>=i)return console.error("Translation error after retries:",s),null;await this.rateLimiter.acquire(),await new Promise(t=>setTimeout(t,n))}return null}}const c=[{code:"af",name:"Afrikaans",native:"Afrikaans",writing_system:"Latin"},{code:"am",name:"Amharic",native:"አማርኛ",writing_system:"Ethiopic"},{code:"ar",name:"Arabic",native:"العربية",rtl:1,writing_system:"Arabic"},{code:"as",name:"Assamese",native:"অসমীয়া",writing_system:"Bengali"},{code:"az",name:"Azerbaijani",native:"Azərbaycanca / آذربايجان",writing_system:"Latin"},{code:"ba",name:"Bashkir",native:"Башҡорт",writing_system:"Cyrillic"},{code:"be",name:"Belarusian",native:"Беларуская",writing_system:"Cyrillic"},{code:"bg",name:"Bulgarian",native:"Български",writing_system:"Cyrillic"},{code:"bn",name:"Bengali",native:"বাংলা",writing_system:"Bengali"},{code:"bo",name:"Tibetan",native:"བོད་ཡིག / Bod skad",writing_system:"Tibetan"},{code:"br",name:"Breton",native:"Brezhoneg",writing_system:"Latin"},{code:"bs",name:"Bosnian",native:"Bosanski",writing_system:"Latin"},{code:"ca",name:"Catalan",native:"Català",writing_system:"Latin"},{code:"ch",name:"Chamorro",native:"Chamoru",writing_system:"Latin"},{code:"co",name:"Corsican",native:"Corsu",writing_system:"Latin"},{code:"cs",name:"Czech",native:"Česky",writing_system:"Latin"},{code:"cy",name:"Welsh",native:"Cymraeg",writing_system:"Latin"},{code:"da",name:"Danish",native:"Dansk",writing_system:"Latin"},{code:"de",name:"German",native:"Deutsch",writing_system:"Latin"},{code:"dv",name:"Divehi",native:"ދިވެހިބަސް",rtl:1,writing_system:"Thaana"},{code:"dz",name:"Dzongkha",native:"ཇོང་ཁ",writing_system:"Tibetan"},{code:"el",name:"Greek",native:"Ελληνικά",writing_system:"Greek"},{code:"en",name:"English",native:"English",writing_system:"Latin"},{code:"eo",name:"Esperanto",native:"Esperanto",writing_system:"Latin"},{code:"es",name:"Spanish",native:"Español",writing_system:"Latin"},{code:"et",name:"Estonian",native:"Eesti",writing_system:"Latin"},{code:"eu",name:"Basque",native:"Euskara",writing_system:"Latin"},{code:"fa",name:"Persian",native:"فارسی",rtl:1,writing_system:"Arabic"},{code:"ff",name:"Peul",native:"Fulfulde",writing_system:"Latin"},{code:"fi",name:"Finnish",native:"Suomi",writing_system:"Latin"},{code:"fj",name:"Fijian",native:"Na Vosa Vakaviti",writing_system:"Latin"},{code:"fo",name:"Faroese",native:"Føroyskt",writing_system:"Latin"},{code:"fr",name:"French",native:"Français",writing_system:"Latin"},{code:"fy",name:"West Frisian",native:"Frysk",writing_system:"Latin"},{code:"ga",name:"Irish",native:"Gaeilge",writing_system:"Latin"},{code:"gd",name:"Scottish Gaelic",native:"Gàidhlig",writing_system:"Latin"},{code:"gl",name:"Galician",native:"Galego",writing_system:"Latin"},{code:"gn",name:"Guarani",native:"Avañe'ẽ",writing_system:"Latin"},{code:"gu",name:"Gujarati",native:"ગુજરાતી",writing_system:"Gujarati"},{code:"gv",name:"Manx",native:"Gaelg",writing_system:"Latin"},{code:"ha",name:"Hausa",native:"هَوُسَ",rtl:1,writing_system:"Latin"},{code:"he",name:"Hebrew",native:"עברית",rtl:1,writing_system:"Hebrew"},{code:"hi",name:"Hindi",native:"हिन्दी",writing_system:"Devanagari"},{code:"hr",name:"Croatian",native:"Hrvatski",writing_system:"Latin"},{code:"ht",name:"Haitian",native:"Krèyol ayisyen",writing_system:"Latin"},{code:"hu",name:"Hungarian",native:"Magyar",writing_system:"Latin"},{code:"hy",name:"Armenian",native:"Հայերեն",writing_system:"Armenian"},{code:"id",name:"Indonesian",native:"Bahasa Indonesia",writing_system:"Latin"},{code:"ig",name:"Igbo",native:"Igbo",writing_system:"Latin"},{code:"is",name:"Icelandic",native:"Íslenska",writing_system:"Latin"},{code:"it",name:"Italian",native:"Italiano",writing_system:"Latin"},{code:"iu",name:"Inuktitut",native:"ᐃᓄᒃᑎᑐᑦ",writing_system:"Unified Canadian Aboriginal Syllabics"},{code:"ja",name:"Japanese",native:"日本語",writing_system:"Japanese"},{code:"jv",name:"Javanese",native:"Basa Jawa",writing_system:"Javanese"},{code:"ka",name:"Georgian",native:"ქართული",writing_system:"Georgian"},{code:"kg",name:"Kongo",native:"KiKongo",writing_system:"Latin"},{code:"ki",name:"Kikuyu",native:"Gĩkũyũ",writing_system:"Latin"},{code:"kj",name:"Kuanyama",native:"Kuanyama",writing_system:"Latin"},{code:"kk",name:"Kazakh",native:"Қазақша",writing_system:"Cyrillic"},{code:"kl",name:"Greenlandic",native:"Kalaallisut",writing_system:"Latin"},{code:"km",name:"Cambodian",native:"ភាសាខ្មែរ",writing_system:"Khmer"},{code:"kn",name:"Kannada",native:"ಕನ್ನಡ",writing_system:"Kannada"},{code:"ko",name:"Korean",native:"한국어",writing_system:"Korean"},{code:"kr",name:"Kanuri",native:"Kanuri",writing_system:"Latin"},{code:"ks",name:"Kashmiri",native:"कश्मीरी / كشميري",rtl:1,writing_system:"Arabic"},{code:"ku",name:"Kurdish",native:"Kurdî / كوردی",rtl:1,writing_system:"Arabic"},{code:"kv",name:"Komi",native:"Коми",writing_system:"Cyrillic"},{code:"kw",name:"Cornish",native:"Kernewek",writing_system:"Latin"},{code:"ky",name:"Kirghiz",native:"Kırgızca / Кыргызча",writing_system:"Cyrillic"},{code:"la",name:"Latin",native:"Latina",writing_system:"Latin"},{code:"lb",name:"Luxembourgish",native:"Lëtzebuergesch",writing_system:"Latin"},{code:"lg",name:"Ganda",native:"Luganda",writing_system:"Latin"},{code:"li",name:"Limburgian",native:"Limburgs",writing_system:"Latin"},{code:"ln",name:"Lingala",native:"Lingála",writing_system:"Latin"},{code:"lo",name:"Laotian",native:"ລາວ / Pha xa lao",writing_system:"Lao"},{code:"lt",name:"Lithuanian",native:"Lietuvių",writing_system:"Latin"},{code:"lu",name:"Luba-Katanga",native:"Tshiluba",writing_system:"Latin"},{code:"lv",name:"Latvian",native:"Latviešu",writing_system:"Latin"},{code:"mg",name:"Malagasy",native:"Malagasy",writing_system:"Latin"},{code:"mh",name:"Marshallese",native:"Kajin Majel / Ebon",writing_system:"Latin"},{code:"mi",name:"Maori",native:"Māori",writing_system:"Latin"},{code:"mk",name:"Macedonian",native:"Македонски",writing_system:"Cyrillic"},{code:"ml",name:"Malayalam",native:"മലയാളം",writing_system:"Malayalam"},{code:"mn",name:"Mongolian",native:"Монгол",writing_system:"Mongolian"},{code:"mo",name:"Moldovan",native:"Moldovenească",writing_system:"Latin"},{code:"mr",name:"Marathi",native:"मराठी",writing_system:"Devanagari"},{code:"ms",name:"Malay",native:"Bahasa Melayu",writing_system:"Latin"},{code:"mt",name:"Maltese",native:"bil-Malti",writing_system:"Latin"},{code:"my",name:"Burmese",native:"မြန်မာစာ",writing_system:"Myanmar"},{code:"na",name:"Nauruan",native:"Dorerin Naoero",writing_system:"Latin"},{code:"nb",name:"Norwegian Bokmål",native:"Norsk bokmål",writing_system:"Latin"},{code:"nd",name:"North Ndebele",native:"Sindebele",writing_system:"Latin"},{code:"ne",name:"Nepali",native:"नेपाली",writing_system:"Devanagari"},{code:"ng",name:"Ndonga",native:"Oshiwambo",writing_system:"Latin"},{code:"nl",name:"Dutch",native:"Nederlands",writing_system:"Latin"},{code:"nn",name:"Norwegian Nynorsk",native:"Norsk nynorsk",writing_system:"Latin"},{code:"no",name:"Norwegian",native:"Norsk",writing_system:"Latin"},{code:"nr",name:"South Ndebele",native:"isiNdebele",writing_system:"Latin"},{code:"nv",name:"Navajo",native:"Diné bizaad",writing_system:"Latin"},{code:"ny",name:"Chichewa",native:"Chi-Chewa",writing_system:"Latin"},{code:"oc",name:"Occitan",native:"Occitan",writing_system:"Latin"},{code:"oj",name:"Ojibwa",native:"ᐊᓂᔑᓈᐯᒧᐎᓐ / Anishinaabemowin",writing_system:"Unified Canadian Aboriginal Syllabics"},{code:"om",name:"Oromo",native:"Oromoo",writing_system:"Latin"},{code:"or",name:"Oriya",native:"ଓଡ଼ିଆ",writing_system:"Odia"},{code:"os",name:"Ossetian / Ossetic",native:"Иронау",writing_system:"Cyrillic"},{code:"pa",name:"Panjabi / Punjabi",native:"ਪੰਜਾਬੀ / पंजाबी / پنجابي",writing_system:"Gurmukhi"},{code:"pi",name:"Pali",native:"Pāli / पाऴि",writing_system:"Devanagari"},{code:"pl",name:"Polish",native:"Polski",writing_system:"Latin"},{code:"ps",name:"Pashto",native:"پښتو",rtl:1,writing_system:"Arabic"},{code:"pt",name:"Portuguese",native:"Português",writing_system:"Latin"},{code:"qu",name:"Quechua",native:"Runa Simi",writing_system:"Latin"},{code:"rm",name:"Raeto Romance",native:"Rumantsch",writing_system:"Latin"},{code:"rn",name:"Kirundi",native:"Kirundi",writing_system:"Latin"},{code:"ro",name:"Romanian",native:"Română",writing_system:"Latin"},{code:"ru",name:"Russian",native:"Русский",writing_system:"Cyrillic"},{code:"rw",name:"Rwandi",native:"Kinyarwandi",writing_system:"Latin"},{code:"sa",name:"Sanskrit",native:"संस्कृतम्",writing_system:"Devanagari"},{code:"sc",name:"Sardinian",native:"Sardu",writing_system:"Latin"},{code:"sd",name:"Sindhi",native:"सिनधि",writing_system:"Arabic"},{code:"se",name:"Northern Sami",native:"Sámegiella",writing_system:"Latin"},{code:"sg",name:"Sango",native:"Sängö",writing_system:"Latin"},{code:"sh",name:"Serbo-Croatian",native:"Srpskohrvatski / Српскохрватски",writing_system:"Latin"},{code:"si",name:"Sinhalese",native:"සිංහල",writing_system:"Sinhala"},{code:"sk",name:"Slovak",native:"Slovenčina",writing_system:"Latin"},{code:"sl",name:"Slovenian",native:"Slovenščina",writing_system:"Latin"},{code:"sm",name:"Samoan",native:"Gagana Samoa",writing_system:"Latin"},{code:"sn",name:"Shona",native:"chiShona",writing_system:"Latin"},{code:"so",name:"Somalia",native:"Soomaaliga",writing_system:"Latin"},{code:"sq",name:"Albanian",native:"Shqip",writing_system:"Latin"},{code:"sr",name:"Serbian",native:"Српски",writing_system:"Cyrillic"},{code:"ss",name:"Swati",native:"SiSwati",writing_system:"Latin"},{code:"st",name:"Southern Sotho",native:"Sesotho",writing_system:"Latin"},{code:"su",name:"Sundanese",native:"Basa Sunda",writing_system:"Sundanese"},{code:"sv",name:"Swedish",native:"Svenska",writing_system:"Latin"},{code:"sw",name:"Swahili",native:"Kiswahili",writing_system:"Latin"},{code:"ta",name:"Tamil",native:"தமிழ்",writing_system:"Tamil"},{code:"te",name:"Telugu",native:"తెలుగు",writing_system:"Telugu"},{code:"tg",name:"Tajik",native:"Тоҷикӣ",writing_system:"Cyrillic"},{code:"th",name:"Thai",native:"ไทย / Phasa Thai",writing_system:"Thai"},{code:"ti",name:"Tigrinya",native:"ትግርኛ",writing_system:"Ethiopic"},{code:"tk",name:"Turkmen",native:"Туркмен / تركمن",writing_system:"Latin"},{code:"tl",name:"Tagalog / Filipino",native:"Tagalog",writing_system:"Latin"},{code:"tn",name:"Tswana",native:"Setswana",writing_system:"Latin"},{code:"to",name:"Tonga",native:"Lea Faka-Tonga",writing_system:"Latin"},{code:"tr",name:"Turkish",native:"Türkçe",writing_system:"Latin"},{code:"ts",name:"Tsonga",native:"Xitsonga",writing_system:"Latin"},{code:"tt",name:"Tatar",native:"Tatarça",writing_system:"Cyrillic"},{code:"tw",name:"Twi",native:"Twi",writing_system:"Latin"},{code:"ty",name:"Tahitian",native:"Reo Mā`ohi",writing_system:"Latin"},{code:"ug",name:"Uyghur",native:"Uyƣurqə / ئۇيغۇرچە",writing_system:"Arabic"},{code:"uk",name:"Ukrainian",native:"Українська",writing_system:"Cyrillic"},{code:"ur",name:"Urdu",native:"اردو",rtl:1,writing_system:"Arabic"},{code:"uz",name:"Uzbek",native:"Ўзбек",writing_system:"Latin"},{code:"ve",name:"Venda",native:"Tshivenḓa",writing_system:"Latin"},{code:"vi",name:"Vietnamese",native:"Tiếng Việt",writing_system:"Latin"},{code:"vo",name:"Volapük",native:"Volapük",writing_system:"Latin"},{code:"wo",name:"Wolof",native:"Wollof",writing_system:"Latin"},{code:"xh",name:"Xhosa",native:"isiXhosa",writing_system:"Latin"},{code:"yi",name:"Yiddish",native:"ייִדיש",rtl:1,writing_system:"Hebrew"},{code:"yo",name:"Yoruba",native:"Yorùbá",writing_system:"Latin"},{code:"zh",name:"Chinese (Simplified)",native:"简体中文",writing_system:"Simplied Han"},{code:"zh-TW",name:"Chinese (Traditional)",native:"繁體中文",writing_system:"Traditional Han"},{code:"zu",name:"Zulu",native:"isiZulu",writing_system:"Latin"}];function d(t){return function(t,e){let i=3&t.length,n=t.length-i,a=e,s=3432918353,r=461845907,o=0;for(;o<n;){let e=255&t.charCodeAt(o)|(255&t.charCodeAt(++o))<<8|(255&t.charCodeAt(++o))<<16|(255&t.charCodeAt(++o))<<24;++o,e=(65535&e)*s+(((e>>>16)*s&65535)<<16)&4294967295,e=e<<15|e>>>17,e=(65535&e)*r+(((e>>>16)*r&65535)<<16)&4294967295,a^=e,a=a<<13|a>>>19;const i=5*(65535&a)+((5*(a>>>16)&65535)<<16)&4294967295;a=27492+(65535&i)+(((i>>>16)+58964&65535)<<16)}let l=0;switch(i){case 3:l^=t.charCodeAt(o+2)<<16;case 2:l^=t.charCodeAt(o+1)<<8;case 1:l^=t.charCodeAt(o),l=(65535&l)*s+(((l>>>16)*s&65535)<<16)&4294967295,l=l<<15|l>>>17,l=(65535&l)*r+(((l>>>16)*r&65535)<<16)&4294967295,a^=l}return a^=t.length,a^=a>>>16,a=2246822507*(65535&a)+((2246822507*(a>>>16)&65535)<<16)&4294967295,a^=a>>>13,a=3266489909*(65535&a)+((3266489909*(a>>>16)&65535)<<16)&4294967295,a^=a>>>16,a>>>0}(t.map(t=>t.text.replace(/\s+/g," ").trim().toLocaleLowerCase()).join(" ").trim().toLowerCase(),42).toString(16)}const u=t=>t.replace(/[\p{Emoji_Presentation}\p{Extended_Pictographic}]/gu,"");class m{static findTranslatableContent(){var t;if("undefined"==typeof window)return[];const e={acceptNode(t){var e;if(t.nodeType!==Node.TEXT_NODE)return NodeFilter.FILTER_REJECT;const i=t.parentElement;if(!i)return NodeFilter.FILTER_REJECT;if(i.closest('[aria-hidden="true"]'))return NodeFilter.FILTER_REJECT;if(i.classList.contains("sr-only"))return NodeFilter.FILTER_REJECT;if(i.closest("script, style, code, noscript, next-route-announcer, .jigts-translation-widget, .jigts-widget-trigger, .jigts-widget-dropdown, .notranslate"))return NodeFilter.FILTER_REJECT;const n="SPAN"===i.tagName&&Array.from(i.childNodes).every(t=>t.nodeType===Node.TEXT_NODE),a=i.closest("button, input, select, textarea, [role='button'], [role='link']");if(a&&!n){if(Array.from(i.childNodes).some(e=>e.nodeType===Node.ELEMENT_NODE&&t.parentNode===i)&&a===i)return NodeFilter.FILTER_REJECT}return(null==(e=t.textContent)?void 0:e.trim())?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_REJECT}},i=document.createTreeWalker(document.body,NodeFilter.SHOW_TEXT,e),n=new Map;let a;for(;a=i.nextNode();){const t=a.parentElement;t&&(n.has(t)||n.set(t,[]),n.get(t).push(a))}const s=[];let r=!1;const o=new Set;for(const[l,g]of n.entries()){r=!1;let e="",i=!1;for(const t of o)if(t.contains(l)){i=!0;break}if(i)continue;const n=Array.from(l.childNodes),a=n.some(t=>{var e;return t.nodeType===Node.TEXT_NODE&&(null==(e=t.textContent)?void 0:e.trim())}),c=n.some(t=>t.nodeType===Node.ELEMENT_NODE&&["BUTTON","INPUT","TEXTAREA","SELECT"].includes(t.tagName));if(!(a&&c)){for(const i of g){let n=(null==(t=i.textContent)?void 0:t.trim())||"";const a=l.getAttribute("data-original-text");a&&(n=a);const s=u(n);if(0===n.length||1===n.length||0===s.length)continue;e+=(e?" ":"")+n;Array.from(l.childNodes).some(t=>t.nodeType!==Node.TEXT_NODE)&&(r=!0)}if(e.length>0)if(r){const t=l.outerHTML;s.push({element:l,text:t,isNested:r}),o.add(l)}else s.push({element:l,text:e,isNested:r})}}return s}static divideIntoGroups(t,e){const i=[];for(let n=0;n<t.length;n+=e)i.push(t.slice(n,n+e));return i}}var h=(t=>(t.PREFERRED_LANGUAGE="jss-pref",t))(h||{}),p=(t=>(t.TRANSLATED_LANG="data-translated-lang",t.ORIGINAL_TEXT="data-original-text",t.ORIGINAL_FONT_SIZE="data-original-font-size",t))(p||{});const v="lang";function y(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var w,f,L,j={exports:{}};const b=y((w||(w=1,f=j,L=function(){var t=String.fromCharCode,e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",i="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$",n={};function a(t,e){if(!n[t]){n[t]={};for(var i=0;i<t.length;i++)n[t][t.charAt(i)]=i}return n[t][e]}var s={compressToBase64:function(t){if(null==t)return"";var i=s._compress(t,6,function(t){return e.charAt(t)});switch(i.length%4){default:case 0:return i;case 1:return i+"===";case 2:return i+"==";case 3:return i+"="}},decompressFromBase64:function(t){return null==t?"":""==t?null:s._decompress(t.length,32,function(i){return a(e,t.charAt(i))})},compressToUTF16:function(e){return null==e?"":s._compress(e,15,function(e){return t(e+32)})+" "},decompressFromUTF16:function(t){return null==t?"":""==t?null:s._decompress(t.length,16384,function(e){return t.charCodeAt(e)-32})},compressToUint8Array:function(t){for(var e=s.compress(t),i=new Uint8Array(2*e.length),n=0,a=e.length;n<a;n++){var r=e.charCodeAt(n);i[2*n]=r>>>8,i[2*n+1]=r%256}return i},decompressFromUint8Array:function(e){if(null==e)return s.decompress(e);for(var i=new Array(e.length/2),n=0,a=i.length;n<a;n++)i[n]=256*e[2*n]+e[2*n+1];var r=[];return i.forEach(function(e){r.push(t(e))}),s.decompress(r.join(""))},compressToEncodedURIComponent:function(t){return null==t?"":s._compress(t,6,function(t){return i.charAt(t)})},decompressFromEncodedURIComponent:function(t){return null==t?"":""==t?null:(t=t.replace(/ /g,"+"),s._decompress(t.length,32,function(e){return a(i,t.charAt(e))}))},compress:function(e){return s._compress(e,16,function(e){return t(e)})},_compress:function(t,e,i){if(null==t)return"";var n,a,s,r={},o={},l="",g="",c="",d=2,u=3,m=2,h=[],p=0,v=0;for(s=0;s<t.length;s+=1)if(l=t.charAt(s),Object.prototype.hasOwnProperty.call(r,l)||(r[l]=u++,o[l]=!0),g=c+l,Object.prototype.hasOwnProperty.call(r,g))c=g;else{if(Object.prototype.hasOwnProperty.call(o,c)){if(c.charCodeAt(0)<256){for(n=0;n<m;n++)p<<=1,v==e-1?(v=0,h.push(i(p)),p=0):v++;for(a=c.charCodeAt(0),n=0;n<8;n++)p=p<<1|1&a,v==e-1?(v=0,h.push(i(p)),p=0):v++,a>>=1}else{for(a=1,n=0;n<m;n++)p=p<<1|a,v==e-1?(v=0,h.push(i(p)),p=0):v++,a=0;for(a=c.charCodeAt(0),n=0;n<16;n++)p=p<<1|1&a,v==e-1?(v=0,h.push(i(p)),p=0):v++,a>>=1}0==--d&&(d=Math.pow(2,m),m++),delete o[c]}else for(a=r[c],n=0;n<m;n++)p=p<<1|1&a,v==e-1?(v=0,h.push(i(p)),p=0):v++,a>>=1;0==--d&&(d=Math.pow(2,m),m++),r[g]=u++,c=String(l)}if(""!==c){if(Object.prototype.hasOwnProperty.call(o,c)){if(c.charCodeAt(0)<256){for(n=0;n<m;n++)p<<=1,v==e-1?(v=0,h.push(i(p)),p=0):v++;for(a=c.charCodeAt(0),n=0;n<8;n++)p=p<<1|1&a,v==e-1?(v=0,h.push(i(p)),p=0):v++,a>>=1}else{for(a=1,n=0;n<m;n++)p=p<<1|a,v==e-1?(v=0,h.push(i(p)),p=0):v++,a=0;for(a=c.charCodeAt(0),n=0;n<16;n++)p=p<<1|1&a,v==e-1?(v=0,h.push(i(p)),p=0):v++,a>>=1}0==--d&&(d=Math.pow(2,m),m++),delete o[c]}else for(a=r[c],n=0;n<m;n++)p=p<<1|1&a,v==e-1?(v=0,h.push(i(p)),p=0):v++,a>>=1;0==--d&&(d=Math.pow(2,m),m++)}for(a=2,n=0;n<m;n++)p=p<<1|1&a,v==e-1?(v=0,h.push(i(p)),p=0):v++,a>>=1;for(;;){if(p<<=1,v==e-1){h.push(i(p));break}v++}return h.join("")},decompress:function(t){return null==t?"":""==t?null:s._decompress(t.length,32768,function(e){return t.charCodeAt(e)})},_decompress:function(e,i,n){var a,s,r,o,l,g,c,d=[],u=4,m=4,h=3,p="",v=[],y={val:n(0),position:i,index:1};for(a=0;a<3;a+=1)d[a]=a;for(r=0,l=Math.pow(2,2),g=1;g!=l;)o=y.val&y.position,y.position>>=1,0==y.position&&(y.position=i,y.val=n(y.index++)),r|=(o>0?1:0)*g,g<<=1;switch(r){case 0:for(r=0,l=Math.pow(2,8),g=1;g!=l;)o=y.val&y.position,y.position>>=1,0==y.position&&(y.position=i,y.val=n(y.index++)),r|=(o>0?1:0)*g,g<<=1;c=t(r);break;case 1:for(r=0,l=Math.pow(2,16),g=1;g!=l;)o=y.val&y.position,y.position>>=1,0==y.position&&(y.position=i,y.val=n(y.index++)),r|=(o>0?1:0)*g,g<<=1;c=t(r);break;case 2:return""}for(d[3]=c,s=c,v.push(c);;){if(y.index>e)return"";for(r=0,l=Math.pow(2,h),g=1;g!=l;)o=y.val&y.position,y.position>>=1,0==y.position&&(y.position=i,y.val=n(y.index++)),r|=(o>0?1:0)*g,g<<=1;switch(c=r){case 0:for(r=0,l=Math.pow(2,8),g=1;g!=l;)o=y.val&y.position,y.position>>=1,0==y.position&&(y.position=i,y.val=n(y.index++)),r|=(o>0?1:0)*g,g<<=1;d[m++]=t(r),c=m-1,u--;break;case 1:for(r=0,l=Math.pow(2,16),g=1;g!=l;)o=y.val&y.position,y.position>>=1,0==y.position&&(y.position=i,y.val=n(y.index++)),r|=(o>0?1:0)*g,g<<=1;d[m++]=t(r),c=m-1,u--;break;case 2:return v.join("")}if(0==u&&(u=Math.pow(2,h),h++),d[c])p=d[c];else{if(c!==m)return null;p=s+s.charAt(0)}v.push(p),d[m++]=s+p.charAt(0),s=p,0==--u&&(u=Math.pow(2,h),h++)}}};return s}(),null!=f?f.exports=L:"undefined"!=typeof angular&&null!=angular&&angular.module("LZString",[]).factory("LZString",function(){return L})),j.exports));class T{constructor(t=""){e(this,"prefix"),e(this,"COMPRESSION_THRESHOLD",1e4),e(this,"COMPRESSION_MARKER","__COMPRESSED__"),e(this,"cache",{}),this.prefix=t}getPageKey(t){return`${this.prefix}${t}`}shouldCompress(t){return t.length>this.COMPRESSION_THRESHOLD}compress(t){try{return b.compressToBase64(t)}catch(e){return console.error("Compression failed:",e),t}}decompress(t){try{return b.decompressFromBase64(t)||t}catch(e){return console.error("Decompression failed:",e),t}}getItem(t){if(this.cache[t])return this.cache[t];const e=localStorage.getItem(t);if(!e)return null;try{const i=e.startsWith(this.COMPRESSION_MARKER)?this.decompress(e.slice(this.COMPRESSION_MARKER.length)):e,n=JSON.parse(i);return this.cache[t]=n,n}catch(i){return console.error("Error parsing cached item:",i),null}}setItem(t,e){const i=JSON.stringify(e),n=()=>{try{const n=this.shouldCompress(i)?`${this.COMPRESSION_MARKER}${this.compress(i)}`:i;localStorage.setItem(t,n),this.cache[t]=e}catch(n){console.error("Error storing item:",n),localStorage.setItem(t,i),this.cache[t]=e}};"undefined"!=typeof requestIdleCallback?requestIdleCallback(()=>n()):setTimeout(n,0)}getNodeTranslation(t,e){const i=this.getPageKey(e);return(this.getItem(i)||{})[t]||null}setNodeTranslation(t,e,i){const n=this.getPageKey(e);let a=this.getItem(n)||{};a[t]=i,this.setItem(n,a)}setBatchNodeTranslationsArray(t,e){const i=this.getPageKey(t),n=this.getItem(i)||{};e.forEach(({originalText:t,translatedText:e})=>{n[t]=e}),this.setItem(i,n)}removeItem(t){localStorage.removeItem(t),delete this.cache[t]}clear(t=[]){if(this.prefix)for(let e in localStorage)!e.startsWith(this.prefix)||t.length&&!t.includes(e.split("--")[1])||localStorage.removeItem(e);else if(t&&t.length>0)for(let e in localStorage)t.includes(e.split("--")[1])&&(localStorage.removeItem(e),delete this.cache[e]);else localStorage.clear(),this.cache={}}key(t){return localStorage.key(t)}get length(){return localStorage.length}}const x=class t{constructor(i,n={}){e(this,"config"),e(this,"translationService"),e(this,"targetLanguages"),e(this,"currentLanguage"),e(this,"widget"),e(this,"elements"),e(this,"autoDetectLanguage"),e(this,"isTranslated",!1),e(this,"userLanguage"),e(this,"isTranslating",!1),e(this,"observer",null),e(this,"translationScheduled",!1),e(this,"scheduleTimeout",null),e(this,"showUI",!0),e(this,"lastTranslated",null),e(this,"currentTranslationPromise",null),e(this,"lastRequestedLanguage",null),e(this,"translationRequestId",0),e(this,"onUrlChange",()=>{this.scheduleTranslation()});let s={...a,...n,targetLanguages:n.targetLanguages??[...a.targetLanguages],requestHeaders:{...a.requestHeaders,...n.requestHeaders??{}}};const r=s.mockMode?i||"pk_demo_frontend_only":i;if(s.position&&!["top-right","top-left","bottom-left","bottom-right"].includes(s.position)&&(console.warn(`Invalid position '${s.position}' passed to TranslationWidget. Falling back to 'top-right'.`),s.position="top-right"),this.config=s,this.targetLanguages=this.resolveTargetLanguages(this.config.targetLanguages),this.autoDetectLanguage=this.config.autoDetectLanguage||!1,this.currentLanguage=this.config.pageLanguage,this.userLanguage=(()=>{const t=window.navigator.languages,e=c.find(e=>t.includes(e.code));return(null==e?void 0:e.code)||"en"})(),this.widget=document.createElement("div"),this.showUI=this.config.showUI??!0,this.elements={trigger:null,dropdown:null,searchInput:null,clearSearch:null,languageItems:null,loadingIndicator:null},!this.config.mockMode&&this.config.includeApiKeyHeader){const t=function(t){return t?t.startsWith("sk_")?{isValid:!1,message:"Please use public api key for security reasons. You can get one from https://jigsawstack.com"}:t.startsWith("pk_")?{isValid:!0}:{isValid:!1,message:"Please use proper api key. You can get one from https://jigsawstack.com"}:{isValid:!1,message:"Public key is required to initialize the translation widget"}}(r);if(!t.isValid)return void console.error("Error initializing TranslationWidget: ",t.message)}this.translationService=new g(r,{mockMode:this.config.mockMode,apiUrl:this.config.apiUrl,requestHeaders:this.config.requestHeaders,includeApiKeyHeader:this.config.includeApiKeyHeader}),this.initialize(),t.instance=this}initialize(){var t;const e=this.getUrlParameter(v);let i=this.config.pageLanguage;if(this.isTargetLanguage(e))i=e;else{const t=localStorage.getItem(h.PREFERRED_LANGUAGE);this.isTargetLanguage(t)&&(i=t)}if(i===this.config.pageLanguage&&this.autoDetectLanguage&&this.isTargetLanguage(this.userLanguage))i=this.userLanguage;else if(!this.config.pageLanguage){const t=document.querySelector("html");i=t&&t.getAttribute(v)?t.getAttribute(v):"en"}if(this.currentLanguage=i,this.showUI){this.createWidget();const e=null==(t=this.elements.trigger)?void 0:t.querySelector(".jigts-trigger-icon");if(e&&this.currentLanguage!==this.config.pageLanguage){const t=this.findLanguageByCode(this.currentLanguage),i=t?t.name:this.currentLanguage.toUpperCase();e.innerHTML=`<span class="jigts-lang-code">${this.currentLanguage.toUpperCase()}</span><span class="jigts-lang-name">${i}</span>`}this.setupEventListeners(),this.setupURLObserver(),this.setupContentObserver()}this.currentLanguage!==this.config.pageLanguage&&this.translatePage(this.currentLanguage).catch(t=>{console.error("Initial translation error:",t)})}resolveTargetLanguages(t){const e=t.map(t=>this.findLanguageByCode(t)).filter(t=>Boolean(t));return e.length>0?e:c.filter(t=>"zh"===t.code)}findLanguageByCode(t){return c.find(e=>e.code===t)}isTargetLanguage(t){return Boolean(t)&&this.targetLanguages.some(e=>e.code===t)}getUrlParameter(t){return new URLSearchParams(window.location.search).get(t)}setupContentObserver(){this.observer?console.warn("Observer already exists. Skipping setupContentObserver"):(this.observer=new MutationObserver(t=>{if(this.isTranslating)return;const e=this.widget;t.filter(t=>{if(e.contains(t.target))return!1;if("childList"===t.type){const e=Array.from(t.addedNodes).some(t=>"SCRIPT"===t.nodeName),i=Array.from(t.removedNodes).some(t=>"SCRIPT"===t.nodeName);return!e&&!i}return!0}).length>0&&this.scheduleTranslation()}),this.observeBody())}observeBody(){var t;null==(t=this.observer)||t.observe(document.body,{childList:!0,subtree:!0,characterData:!0,attributes:!0})}setupURLObserver(){["pushState","replaceState"].forEach(t=>{const e=history[t];history[t]=function(i,n,a){const s=e.call(this,i,n,a);return window.dispatchEvent(new Event(t)),s},window.addEventListener(t,this.onUrlChange)}),window.addEventListener("popstate",this.onUrlChange)}createWidget(){var t;const e=this.getCurrentLanguageLabel();this.widget=document.createElement("div"),this.widget.className=`jigts-translation-widget jigts-position-${this.config.position||"top-right"}`,this.config.theme&&(this.config.theme.baseColor&&this.widget.style.setProperty("--jigts-custom-base-color",this.config.theme.baseColor),this.config.theme.textColor&&this.widget.style.setProperty("--jigts-custom-text-color",this.config.theme.textColor)),document.body.appendChild(this.widget),this.widget.innerHTML=this.createWidgetHTML(e),this.elements={trigger:this.widget.querySelector(".jigts-widget-trigger"),dropdown:this.widget.querySelector(".jigts-widget-dropdown"),searchInput:this.widget.querySelector(".jigts-search-input"),clearSearch:this.widget.querySelector(".jigts-clear-search"),languageItems:this.widget.querySelectorAll(".jigts-language-item"),loadingIndicator:this.widget.querySelector(".jigts-loading-spinner")};const i=null==(t=this.elements.trigger)?void 0:t.querySelector("span");i&&i.classList.add("jigts-fade-in")}getCurrentLanguageLabel(){var t;return(null==(t=this.findLanguageByCode(this.currentLanguage))?void 0:t.native)||"English"}createWidgetHTML(t){const e=this.createLanguageOptions(),i=this.targetLanguages.length,n=`${i} ${1===i?"language":"languages"}`,a=i>1?'\n \x3c!-- Search Input --\x3e\n <div class="jigts-search-container">\n <svg class="jigts-search-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"\n d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>\n </svg>\n <input type="text" class="jigts-search-input" placeholder="Search languages..." aria-label="Search languages">\n <svg class="jigts-clear-search" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12">\n </path>\n </svg>\n </div>\n ':"";return'\x3c!-- Widget Trigger Button --\x3e\r\n<div class="jigts-widget-trigger" tabindex="0" role="button" aria-label="Open translation menu" aria-expanded="false">\r\n \x3c!-- Normal State --\x3e\r\n <div class="jigts-trigger-content">\r\n <span class="jigts-trigger-icon">\r\n <svg class="jigts-languages-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">\r\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"\r\n d="M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10M12.751 5C11.783 10.77 8.07 15.61 3 18.129">\r\n </path>\r\n </svg>\r\n </span>\r\n </div>\r\n\r\n \x3c!-- Loading State (hidden by default) --\x3e\r\n <div class="jigts-trigger-loading" style="display: none;">\r\n <div class="jigts-loading-spinner"></div>\r\n </div>\r\n</div>\r\n\r\n\x3c!-- Dropdown Menu --\x3e\r\n<div class="jigts-widget-dropdown">\r\n \x3c!-- Header --\x3e\r\n <div class="jigts-dropdown-header">\r\n <div class="jigts-dropdown-title">\r\n <div class="jigts-title-left">\r\n <svg class="jigts-languages-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">\r\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"\r\n d="M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10M12.751 5C11.783 10.77 8.07 15.61 3 18.129">\r\n </path>\r\n </svg>\r\n <span class="jigts-title-text">Select Language</span>\r\n </div>\r\n <div class="jigts-language-count">{{languageCountLabel}}</div>\r\n </div>\r\n\r\n {{searchSection}}\r\n </div>\r\n\r\n \x3c!-- Reset Option --\x3e\r\n <div class="jigts-reset-option" tabindex="0" role="button" aria-label="Reset to original language">\r\n <svg class="jigts-reset-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">\r\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"\r\n d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6"></path>\r\n </svg>\r\n <div class="jigts-reset-text">\r\n <span class="jigts-reset-title">Original Language</span>\r\n <span class="jigts-reset-subtitle">Reset translation</span>\r\n </div>\r\n </div>\r\n\r\n \x3c!-- Language List --\x3e\r\n <div class="jigts-language-list">\r\n {{languageOptions}}\r\n <div class="jigts-no-results" style="display: none;">\r\n <svg class="jigts-no-results-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">\r\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"\r\n d="M9.172 16.172a4 4 0 015.656 0M9 10h.01M15 10h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>\r\n </svg>\r\n <span>No languages found</span>\r\n </div>\r\n </div>\r\n</div>\r\n'.replace("{{languageOptions}}",e).replace("{{currentLanguageLabel}}",t).replace("{{languageCountLabel}}",n).replace("{{searchSection}}",a)}createLanguageOptions(){const t=[...this.targetLanguages].sort((t,e)=>t.native.localeCompare(e.native));return t.map(t=>((t,e=!1)=>`\n <div class="jigts-language-item ${e?"jigts-selected":""}" tabindex="0" role="option" aria-selected="${e}" data-language-code="${t.code}">\n <div class="jigts-language-info">\n <div class="jigts-language-main">\n <span class="jigts-language-name">${t.name}</span>\n <div class="jigts-language-code">${t.code}</div>\n </div>\n <div class="jigts-language-details">\n <span class="jigts-language-native">${t.native}</span>\n </div>\n </div>\n <svg class="jigts-check-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>\n </svg>\n </div>\n `)(t,t.code===this.currentLanguage)).join("")}async updateTriggerText(t){var e;const i=null==(e=this.elements.trigger)?void 0:e.querySelector("span");i&&(i.offsetHeight,i.classList.remove("jigts-fade-in"),i.classList.add("jigts-fade-out"),await new Promise(t=>setTimeout(t,300)),i.textContent=t,i.offsetHeight,i.classList.remove("jigts-fade-out"),i.classList.add("jigts-fade-in"))}getTextToTranslate(t,e,i){var n,a;if(e.hasAttribute(p.ORIGINAL_TEXT)){const n=null==(a=t.text)?void 0:a.trim();if(this.currentLanguage!==i){e.setAttribute(p.TRANSLATED_LANG,i);let t=e.getAttribute(p.ORIGINAL_TEXT);if(t)return t}return n||null}{const a=null==(n=t.text)?void 0:n.trim();if(a){if(e.setAttribute(p.TRANSLATED_LANG,i),e.setAttribute(p.ORIGINAL_TEXT,a),this.config.adjustFontSize&&!e.hasAttribute(p.ORIGINAL_FONT_SIZE)){const t=window.getComputedStyle(e);e.setAttribute(p.ORIGINAL_FONT_SIZE,t.fontSize)}return a}}return null}calculateFontSize(t,e,i){const n=parseInt(e),a=t.length,s=i.length;if(a<=s)return e;const r=s/a;return`${Math.max(12,Math.round(n*r))}px`}updateLoadingState(t){var e,i;const n=null==(e=this.elements.trigger)?void 0:e.querySelector(".jigts-trigger-content"),a=null==(i=this.elements.trigger)?void 0:i.querySelector(".jigts-trigger-loading");n&&a&&(t?(n.style.display="none",a.style.display="flex"):(a.style.display="none",n.style.display="flex"))}async translatePage(t){const e=++this.translationRequestId;if(this.lastRequestedLanguage=t,this.updateLoadingState(!0),this.currentTranslationPromise&&await this.currentTranslationPromise,t===this.config.pageLanguage)return this.resetTranslations(),void(e===this.translationRequestId&&this.updateLoadingState(!1));this.currentTranslationPromise=this._translatePage(t);try{await this.currentTranslationPromise}catch(i){console.error("Translation failed:",i),this.resetToDefaultLanguage()}finally{e===this.translationRequestId&&(this.currentTranslationPromise=null,this.updateLoadingState(!1))}}resetToDefaultLanguage(){var t;if(this.isTranslating)return;this.resetTranslations(),this.lastRequestedLanguage=this.config.pageLanguage,this.currentLanguage=this.config.pageLanguage;this.widget.querySelectorAll(".jigts-language-item").forEach(t=>{const e=t.getAttribute("data-language-code")===this.config.pageLanguage;t.classList.toggle("jigts-selected",e),t.setAttribute("aria-selected",e.toString())}),localStorage.setItem(h.PREFERRED_LANGUAGE,this.config.pageLanguage);const e=null==(t=this.elements.trigger)?void 0:t.querySelector(".jigts-trigger-icon");e&&(e.innerHTML=this.getLanguageSVG()),this.isTranslated=!1,this.updateResetButtonVisibility()}async _translatePage(t){var e;this.isTranslating=!0,null==(e=this.observer)||e.disconnect();try{const e=m.findTranslatableContent(),n=e.filter(t=>{const e=t.element.getBoundingClientRect();return e.height>0&&e.top<window.innerHeight}),a=e.filter(t=>{const e=t.element.getBoundingClientRect();return 0===e.height||e.top>window.innerHeight}),s=m.divideIntoGroups(n,90),r=m.divideIntoGroups(a,90),o=new T(i),l=async e=>{const i=[],n=[];if(e.forEach(e=>{const a=[],s=[];e.forEach(e=>{const i=e.element;if(!i)return;const n=i.getAttribute(p.TRANSLATED_LANG);if(i.hasAttribute(p.ORIGINAL_TEXT)&&t===n)return;let r=this.getTextToTranslate(e,i,t);if(r=u(r||""),0!==r.length&&1!==r.length&&r){const n=(o.getItem(o.getPageKey(t))||{})[r]||null;if(n){if(this.lastRequestedLanguage===t){const t=r,e=n;if(this.config.adjustFontSize){const n=i.getAttribute(p.ORIGINAL_FONT_SIZE)||"16px",a=this.calculateFontSize(e,n,t);i.style.fontSize=a}this.setTranslatedContent(i,e)}return}a.push(r.trim()),s.push(e)}}),a.length>0&&(i.push(s),n.push(a))}),n.length>0){const e=await Promise.all(n.map(e=>{var i;return null==(i=this.translationService)?void 0:i.translateBatchText(e,t)})),a=[];if(e.forEach((t,e)=>{t&&t.length>0&&a.push({translations:t,nodes:i[e]})}),0===a.length)return this.updateLoadingState(!1),this.isTranslating=!1,void this.resetToDefaultLanguage();const s=[];a.forEach(({translations:e,nodes:i})=>{i.forEach((i,n)=>{const a=i.element;if(a&&e[n]){const r=i.text||"",o=e[n],l=u(r);if(l&&o&&(s.push({originalText:l,translatedText:o}),this.lastRequestedLanguage===t)){if(this.config.adjustFontSize){const t=a.getAttribute(p.ORIGINAL_FONT_SIZE)||"16px",e=this.calculateFontSize(o,t,r);a.style.fontSize=e}this.setTranslatedContent(a,o)}}})}),s.length>0&&o.setBatchNodeTranslationsArray(t,s)}};await Promise.allSettled([l(s),l(r)]),this.lastRequestedLanguage===t&&(this.isTranslated=!0,this.updateResetButtonVisibility())}finally{this.isTranslating=!1,this.observeBody()}}updateResetButtonVisibility(){const t=this.widget.querySelector(".jigts-reset-option");t&&(t.style.display=this.isTranslated?"flex":"none")}resetTranslations(){this.observer&&this.observer.disconnect();document.querySelectorAll(`[${p.ORIGINAL_TEXT}]`).forEach(t=>{if(Array.from(t.childNodes).filter(t=>t.nodeType===Node.TEXT_NODE).length>0){const e=t.getAttribute(p.ORIGINAL_TEXT);e&&this.setTranslatedContent(t,e)}const e=t.getAttribute(p.ORIGINAL_FONT_SIZE);e&&(t.style.fontSize=e),t.removeAttribute(p.ORIGINAL_TEXT),t.removeAttribute(p.TRANSLATED_LANG),t.removeAttribute(p.ORIGINAL_FONT_SIZE)}),this.isTranslated=!1,this.currentLanguage=this.config.pageLanguage;const t=d(m.findTranslatableContent());this.lastTranslated={url:window.location.href,lang:this.config.pageLanguage,hash:t},this.updateResetButtonVisibility(),this.observeBody()}adjustDropdownPosition(){const{dropdown:t,trigger:e}=this.elements;if(!t||!e)return;const i=e.getBoundingClientRect(),n=t.getBoundingClientRect(),a=window.innerWidth,s=window.innerHeight;t.style.top="",t.style.bottom="",t.style.left="",t.style.right="",t.style.transform="";const r=s-i.bottom,o=i.top,l=a-i.right,g=i.left;r<n.height&&o>r?(t.style.bottom="100%",t.style.top="auto",t.style.marginBottom="0.5rem",t.style.marginTop="0"):(t.style.top="100%",t.style.bottom="auto",t.style.marginTop="0.5rem",t.style.marginBottom="0"),l<n.width&&g>l?(t.style.right="0",t.style.left="auto"):(t.style.left="0",t.style.right="auto");const c=t.getBoundingClientRect();c.right>a&&(t.style.right="0",t.style.left="auto"),c.left<0&&(t.style.left="0",t.style.right="auto")}setupEventListeners(){const{trigger:t,dropdown:e,searchInput:i,clearSearch:n,languageItems:a}=this.elements;if(!t||!e||!a)return void console.error("Failed to find required elements");const s=this.widget.querySelector(".jigts-reset-option");s&&s.addEventListener("click",()=>{var i;if(this.isTranslating)return;this.resetToDefaultLanguage(),s.classList.remove("jigts-active"),this.isTranslated=!1,this.updateResetButtonVisibility();this.widget.querySelectorAll(".jigts-language-item").forEach(t=>{const e=t.getAttribute("data-language-code")===this.config.pageLanguage;t.classList.toggle("jigts-selected",e),t.setAttribute("aria-selected",e.toString())});const n=null==(i=this.elements.trigger)?void 0:i.querySelector(".jigts-trigger-icon");n&&(n.innerHTML=this.getLanguageSVG()),e.classList.remove("jigts-open"),t.setAttribute("aria-expanded","false");const a=t.querySelector(".jigts-trigger-content");a&&a.classList.remove("jigts-has-translation")}),this.updateResetButtonVisibility(),t.addEventListener("click",()=>{e.classList.toggle("jigts-open");const n=e.classList.contains("jigts-open");t.setAttribute("aria-expanded",n.toString()),n&&i&&(this.adjustDropdownPosition(),i.focus())}),window.addEventListener("resize",()=>{e.classList.contains("jigts-open")&&this.adjustDropdownPosition()}),document.addEventListener("click",i=>{i.target.closest(".jigts-translation-widget")||e.classList.contains("jigts-open")&&(e.classList.add("jigts-closing"),setTimeout(()=>{e.classList.remove("jigts-open","jigts-closing"),t.setAttribute("aria-expanded","false")},300))}),i&&n&&(i.addEventListener("input",()=>{const t=i.value.toLowerCase(),e=t.length>0;n.classList.toggle("jigts-visible",e);const a=this.widget.querySelectorAll(".jigts-language-item"),s=this.widget.querySelector(".jigts-no-results");let r=0;a.forEach(e=>{var i,n,a,s,o,l,g,c;const d=(null==(n=null==(i=e.querySelector(".jigts-language-name"))?void 0:i.textContent)?void 0:n.toLowerCase())||"",u=(null==(s=null==(a=e.querySelector(".jigts-language-native"))?void 0:a.textContent)?void 0:s.toLowerCase())||"",m=(null==(l=null==(o=e.querySelector(".jigts-language-code"))?void 0:o.textContent)?void 0:l.toLowerCase())||"",h=(null==(c=null==(g=e.querySelector(".jigts-language-region"))?void 0:g.textContent)?void 0:c.toLowerCase())||"",p=d.includes(t)||u.includes(t)||m.includes(t)||h.includes(t);e.style.display=p?"":"none",p&&r++}),s&&(s.style.display=0===r?"flex":"none")}),n.addEventListener("click",()=>{i.value="",n.classList.remove("jigts-visible"),i.focus();const t=this.widget.querySelectorAll(".jigts-language-item"),e=this.widget.querySelector(".jigts-no-results");t.forEach(t=>{t.style.display=""}),e&&(e.style.display="none")})),a.forEach(i=>{i.addEventListener("click",async()=>{var n,s;a.forEach(t=>{t.classList.remove("jigts-selected"),t.setAttribute("aria-selected","false")}),i.classList.add("jigts-selected"),i.setAttribute("aria-selected","true");const r=null==(n=i.querySelector(".jigts-language-name"))?void 0:n.textContent,o=i.getAttribute("data-language-code");e.classList.remove("jigts-open"),t.setAttribute("aria-expanded","false"),r&&await this.updateTriggerText(r),o&&localStorage.setItem(h.PREFERRED_LANGUAGE,o);const l=null==(s=this.elements.trigger)?void 0:s.querySelector(".jigts-trigger-icon");l&&o&&r&&(l.innerHTML=`<span class="jigts-lang-code">${o.toUpperCase()}</span><span class="jigts-lang-name">${r}</span>`);const g=t.querySelector(".jigts-trigger-content");if(o&&o!==this.currentLanguage){g&&g.classList.add("jigts-has-translation");const e=t.querySelector(".jigts-trigger-loading");g&&e&&(g.style.display="none",e.style.display="flex");try{await this.translatePage(o),this.currentLanguage=o}catch(c){console.error("Translation error:",c),alert("An error occurred during translation. Please try again.")}}else g&&g.classList.remove("jigts-has-translation")})}),document.addEventListener("keydown",i=>{e.classList.contains("jigts-open")&&"Escape"===i.key&&(e.classList.remove("jigts-open"),t.setAttribute("aria-expanded","false"),t.focus())})}scheduleTranslation(){if(this.translationScheduled)return;const t=window.location.href,e=this.currentLanguage,i=d(m.findTranslatableContent());this.lastTranslated&&this.lastTranslated.url===t&&this.lastTranslated.lang===e&&this.lastTranslated.hash===i||(this.translationScheduled=!0,this.scheduleTimeout&&clearTimeout(this.scheduleTimeout),this.scheduleTimeout=window.setTimeout(()=>{var n,a;if(this.translationScheduled=!1,this.currentLanguage!==this.config.pageLanguage){this.lastTranslated={url:t,lang:e,hash:i};const s=null==(n=this.elements.trigger)?void 0:n.querySelector(".jigts-trigger-content"),r=null==(a=this.elements.trigger)?void 0:a.querySelector(".jigts-trigger-loading");s&&r&&(s.style.display="none",r.style.display="flex"),this.translatePage(this.currentLanguage).then(()=>{this.widget.querySelectorAll(".jigts-language-item").forEach(t=>{const e=t.getAttribute("data-language-code")===this.currentLanguage;t.classList.toggle("jigts-selected",e),t.setAttribute("aria-selected",e.toString())})}).catch(t=>{console.error("Auto-translation error:",t)})}},200))}async translateTo(t,e,i){var n;const a=Date.now();if(this.isTranslating)return console.warn("Translation already in progress"),null==i||i(new Error("Translation already in progress")),{success:!1,targetLanguage:t,translatedNodes:0,error:"Translation already in progress",duration:0};const s=this.targetLanguages.find(e=>e.code===t);if(!s)return null==i||i(new Error(`Unsupported language code: ${t}`)),{success:!1,targetLanguage:t,translatedNodes:0,error:`Unsupported language code: ${t}`,duration:0};if(t===this.currentLanguage)return null==e||e({success:!0,targetLanguage:t,translatedNodes:0,duration:0}),{success:!0,targetLanguage:t,translatedNodes:0,duration:0};try{localStorage.setItem(h.PREFERRED_LANGUAGE,t),await this.translatePage(t),this.currentLanguage=t;const i=this.widget.querySelectorAll(".jigts-language-item");for(const e of i){const i=e.getAttribute("data-language-code")===t;e.classList.toggle("jigts-selected",i),e.setAttribute("aria-selected",i.toString())}const r=null==(n=this.elements.trigger)?void 0:n.querySelector(".jigts-trigger-content");if(r){r.classList.add("jigts-has-translation");const t=r.querySelector(".jigts-trigger-icon");t&&s&&(t.innerHTML=`<span class="jigts-lang-code">${s.code.toUpperCase()}</span><span class="jigts-lang-name">${s.name}</span>`)}const o=Date.now(),l=document.querySelectorAll(`[${p.TRANSLATED_LANG}]`).length;return null==e||e({success:!0,targetLanguage:t,translatedNodes:l,duration:o-a}),{success:!0,targetLanguage:t,translatedNodes:l,duration:o-a}}catch(r){return null==i||i(r),{success:!1,targetLanguage:t,translatedNodes:0,error:r instanceof Error?r.message:"Unknown error occurred",duration:0}}}static getInstance(){return t.instance}getLanguageSVG(){return'\n <svg class="jigts-languages-icon" fill="none" stroke="currentColor" viewBox="0 0 24 24">\n <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"\n d="M3 5h12M9 3v2m1.048 9.5A18.022 18.022 0 016.412 9m6.088 9h7M11 21l5-10 5 10M12.751 5C11.783 10.77 8.07 15.61 3 18.129">\n </path>\n </svg>\n '}setTranslatedContent(t,e){var i;if(/<[^>]*>/g.test(e)){const n=document.createElement("div");n.innerHTML=e,1===n.children.length&&(null==(i=n.firstElementChild)?void 0:i.tagName.toLowerCase())===t.tagName.toLowerCase()?t.innerHTML=n.firstElementChild.innerHTML:t.innerHTML=e}else t.textContent=e}};e(x,"instance",null);let _,S=x;"undefined"!=typeof window&&(window.resetTranslation=(t,e,i)=>{const n=S.getInstance();if(n)try{n.resetToDefaultLanguage(),null==e||e({success:!0,targetLanguage:t})}catch(a){null==i||i(a)}},window.translate=async(t,e,i)=>{const n=S.getInstance();if(!n)return null==i||i(new Error("Translation widget not initialized")),{success:!1,targetLanguage:t,translatedNodes:0,error:"Translation widget not initialized",duration:0};const a=Date.now();try{const a=await n.translateTo(t,e,i);return null==e||e(a),a}catch(s){return null==i||i(s),{success:!1,targetLanguage:t,translatedNodes:0,error:s instanceof Error?s.message:"Unknown error occurred",duration:Date.now()-a}}},window.clearCache=(t=[],e,n)=>{const a=new T(i);try{a.clear(t),null==e||e()}catch(s){null==n||n(s)}});return(()=>{const t=Node.prototype.removeChild;Node.prototype.removeChild=function(e){try{return t.call(this,e)}catch(i){if(i instanceof DOMException&&"NotFoundError"===i.name)return e;throw i}}})(),(t,e)=>{if("undefined"==typeof window)throw new Error("Translation widget can only be used in browser environment");const i=()=>{if(!_){if(!document.querySelector("style[data-translation-widget]")){const t=document.createElement("style");t.setAttribute("data-translation-widget",""),t.textContent='Base Styles :root{--jigts-base-color: white;--jigts-text-color: black;--jigts-bg-color: color-mix(in srgb, var(--jigts-base-color) 10%, white);--jigts-bg-hover: color-mix(in srgb, var(--jigts-text-color) 10%, white);--jigts-bg-active: color-mix(in srgb, var(--jigts-base-color) 30%, white)}*{box-sizing:border-box}.jigts-translation-widget{--jigts-base-color: var(--jigts-custom-base-color, white);--jigts-text-color: var(--jigts-custom-text-color, black);--jigts-bg-color: color-mix(in srgb, var(--jigts-base-color) 10%, white);--jigts-bg-hover: color-mix(in srgb, var(--jigts-text-color) 10%, white);--jigts-bg-active: color-mix(in srgb, var(--jigts-base-color) 30%, white);position:fixed;z-index:1000;color:var(--jigts-text-color)}.jigts-translation-widget.jigts-position-top-right{top:2rem;right:2rem}.jigts-translation-widget.jigts-position-top-left{top:2rem;left:2rem}.jigts-translation-widget.jigts-position-bottom-left{bottom:2rem;left:2rem}.jigts-translation-widget.jigts-position-bottom-right{bottom:2rem;right:2rem}.jigts-position-top-right .jigts-widget-dropdown,.jigts-position-top-left .jigts-widget-dropdown{top:calc(100% + .5rem)}.jigts-position-bottom-right .jigts-widget-dropdown,.jigts-position-bottom-left .jigts-widget-dropdown{bottom:calc(100% + .5rem)}.jigts-position-top-right .jigts-widget-dropdown,.jigts-position-bottom-right .jigts-widget-dropdown{right:0}.jigts-position-top-left .jigts-widget-dropdown,.jigts-position-bottom-left .jigts-widget-dropdown{left:0}.jigts-translation-widget{position:fixed}.jigts-translation-widget{max-width:fit-content}.jigts-trigger-content{display:flex;cursor:pointer;border-radius:6px;transition:all .2s ease}.jigts-trigger-icon{display:flex;align-items:center}.jigts-lang-code{font-weight:500;color:var(--jigts-text-color);font-size:14px}.jigts-lang-name{color:var(--jigts-text-color);font-size:14px;opacity:0;max-width:0;overflow:hidden;white-space:nowrap;transition:all .3s ease-in-out;display:inline-block}.jigts-lang-code{transition:all .3s ease-in-out}.jigts-widget-trigger:hover .jigts-lang-code{background:#e5e7eb;border-radius:50%;padding:.1rem .3rem;color:var(--jigts-text-color);font-weight:600;font-size:12px;transition:all .3s ease-in-out}.jigts-widget-trigger:hover .jigts-lang-name{opacity:1;margin-left:.5rem;max-width:150px}.jigts-widget-trigger{background:var(--jigts-bg-color);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border:1px solid color-mix(in srgb,var(--jigts-base-color) 30%,white);border-radius:.75rem;padding:.3rem .6rem;cursor:pointer;display:flex;align-items:center;gap:.2rem;font-size:.9rem;font-weight:500;color:var(--jigts-text-color);box-shadow:0 10px 25px -5px #0000001a,0 10px 10px -5px #0000000a;transition:all .3s cubic-bezier(.4,0,.2,1);position:relative;overflow:hidden;min-height:2.2rem;min-width:unset}.jigts-widget-trigger:hover{transform:scale(1.05) translateY(-2px);box-shadow:0 20px 40px -10px #00000026,0 10px 20px -5px #0000001a}.jigts-widget-trigger:active{transform:scale(.98)}.jigts-widget-trigger:before{content:"";position:absolute;top:0;left:-100%;width:100%;height:100%;background:linear-gradient(90deg,transparent,rgba(var(--jigts-base-color),.1),transparent);transition:left .6s ease}.jigts-widget-trigger:hover:before{left:100%}.jigts-widget-dropdown{position:absolute;width:20rem;background:var(--jigts-bg-color);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border:1px solid color-mix(in srgb,var(--jigts-base-color) 30%,white);border-radius:.75rem;box-shadow:0 25px 50px -12px #00000040;opacity:0;visibility:hidden;transform:scale(.95) translateY(10px);transition:all .3s cubic-bezier(.4,0,.2,1);max-height:28rem;overflow:hidden;display:none;flex-direction:column;z-index:1000}.jigts-widget-dropdown.jigts-open{opacity:1;visibility:visible;transform:scale(1) translateY(0);display:flex}.jigts-widget-dropdown.jigts-closing{opacity:0;transform:translateY(10px)}.jigts-dropdown-header{padding:1rem;border-bottom:1px solid color-mix(in srgb,var(--jigts-base-color) 20%,white);background:var(--jigts-bg-hover);border-radius:.75rem .75rem 0 0;animation:headerSlideDown .4s ease .1s both}.jigts-dropdown-title{display:flex;align-items:center;justify-content:space-between;margin-bottom:.75rem}.jigts-title-left{display:flex;align-items:center;gap:.5rem}.jigts-languages-icon{width:1rem;height:1rem;color:var(--jigts-text-color)}.jigts-title-text{font-size:.875rem;font-weight:600;color:var(--jigts-text-color)}.jigts-language-count{background:var(--jigts-bg-hover);border:1px solid color-mix(in srgb,var(--jigts-base-color) 30%,white);color:var(--jigts-text-color);padding:.125rem .5rem;border-radius:.375rem;font-size:.75rem;font-weight:500}.jigts-search-container{position:relative}.jigts-search-input{width:100%;padding:.5rem .75rem .5rem 2.5rem;border:1px solid #d1d5db;border-radius:.5rem;outline:none;font-size:.875rem;color:var(--jigts-text-color);background:#fff;transition:all .2s ease}.jigts-search-icon{position:absolute;left:.75rem;top:50%;transform:translateY(-50%);width:1rem;height:1rem;color:var(--jigts-text-color);opacity:.7}.jigts-clear-search{position:absolute;right:.75rem;top:50%;transform:translateY(-50%);width:1rem;height:1rem;color:var(--jigts-text-color);cursor:pointer;opacity:0;transition:all .2s ease}.jigts-clear-search.jigts-visible{opacity:.7}.jigts-clear-search:hover{opacity:1;transform:translateY(-50%) scale(1.1)}.jigts-reset-option{padding:.75rem 1rem;border-bottom:1px solid color-mix(in srgb,var(--jigts-base-color) 20%,white);cursor:pointer;display:flex;align-items:center;gap:.75rem;transition:background-color .2s ease;animation:resetSlideIn .4s ease .15s both;background:var(--jigts-bg-color)}.jigts-reset-option:hover{background:var(--jigts-bg-hover)}.jigts-reset-icon{width:1rem;height:1rem;color:var(--jigts-text-color);transition:transform .3s ease}.jigts-reset-option:hover .jigts-reset-icon{transform:rotate(-180deg)}.jigts-reset-text{display:flex;flex-direction:column}.jigts-reset-title{font-weight:500;color:var(--jigts-text-color);font-size:.875rem}.jigts-reset-subtitle{font-size:.75rem;color:var(--jigts-text-color);opacity:.7}.jigts-language-list{flex:1;overflow-y:auto;padding:.5rem;position:relative;min-height:200px}.jigts-language-item{display:flex;align-items:center;justify-content:space-between;margin-left:.5rem;margin-right:.5rem;margin-bottom:.5rem;padding:.625rem .75rem;border-radius:.5rem;cursor:pointer;transition:all .2s ease;border:1px solid transparent;animation:languageSlideIn .4s ease both;background:var(--jigts-bg-color)}.jigts-language-item.jigts-focused{background:var(--jigts-bg-hover);border-color:color-mix(in srgb,var(--jigts-base-color) 40%,white)}.jigts-language-item.jigts-selected{background:var(--jigts-bg-active)}.jigts-language-item:hover{background:var(--jigts-bg-hover)}.jigts-language-info{display:flex;flex-direction:column;align-items:flex-start;min-width:0;flex:1}.jigts-language-main{display:flex;align-items:center;gap:.5rem;width:100%}.jigts-language-name{font-weight:500;color:var(--jigts-text-color);font-size:.875rem;transition:color .2s ease;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.jigts-language-item:hover .jigts-language-name{color:var(--jigts-text-color);opacity:.8}.jigts-language-code{background:var(--jigts-bg-hover);color:var(--jigts-text-color);padding:.125rem .375rem;border-radius:.25rem;font-size:.75rem;font-weight:600;flex-shrink:0}.jigts-language-details{display:flex;align-items:center;gap:.25rem;font-size:.75rem;color:var(--jigts-text-color);opacity:.7;width:100%;margin-top:.125rem}.jigts-language-native{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.jigts-language-separator,.jigts-language-region{flex-shrink:0}.jigts-globe-icon{width:1rem;height:1rem;color:var(--jigts-text-color);transition:transform .5s ease}.jigts-widget-trigger:hover .jigts-globe-icon{transform:rotate(360deg)}.jigts-check-icon{width:1rem;height:1rem;color:var(--jigts-text-color);opacity:0;transform:scale(0);transition:all .3s cubic-bezier(.34,1.56,.64,1)}.jigts-language-item.jigts-selected .jigts-check-icon{opacity:1;transform:scale(1)}.jigts-loading-spinner{width:1rem;height:1rem;border:2px solid #e5e7eb;border-top:2px solid var(--jigts-base-color);border-radius:50%;animation:spin 1s linear infinite}.jigts-trigger-loading{display:none}.jigts-no-results{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);display:none;flex-direction:column;align-items:center;justify-content:center;color:var(--jigts-text-color);text-align:center;padding:24px;animation:fadeIn .4s ease}.jigts-no-results-icon{width:2rem;height:2rem;margin-bottom:.5rem;color:var(--jigts-text-color);opacity:.5}.jigts-no-results-title{font-size:.875rem;margin-bottom:.25rem}.jigts-no-results-subtitle{font-size:.75rem}.jigts-dropdown-footer{padding:.5rem 1rem;border-top:1px solid color-mix(in srgb,var(--jigts-base-color) 20%,white);background:var(--jigts-bg-hover);border-radius:0 0 .75rem .75rem;animation:footerSlideUp .4s ease .2s both}.jigts-footer-text{font-size:.75rem;color:var(--jigts-text-color);text-align:center;opacity:.7}.jigts-language-list::-webkit-scrollbar{width:6px}.jigts-language-list::-webkit-scrollbar-track{background:#f3f4f6;border-radius:3px}.jigts-language-list::-webkit-scrollbar-thumb{background:#d1d5db;border-radius:3px}.jigts-language-list::-webkit-scrollbar-thumb:hover{background:#9ca3af}@keyframes spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes badgeSlideIn{0%{transform:scale(0) translate(10px);opacity:0}to{transform:scale(1) translate(0);opacity:1}}@keyframes headerSlideDown{0%{transform:translateY(-20px);opacity:0}to{transform:translateY(0);opacity:1}}@keyframes resetSlideIn{0%{transform:translate(-20px);opacity:0}to{transform:translate(0);opacity:1}}@keyframes languageSlideIn{0%{transform:translate(-20px);opacity:0}to{transform:translate(0);opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes footerSlideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}.jigts-language-item:nth-child(1){animation-delay:.2s}.jigts-language-item:nth-child(2){animation-delay:.22s}.jigts-language-item:nth-child(3){animation-delay:.24s}.jigts-language-item:nth-child(4){animation-delay:.26s}.jigts-language-item:nth-child(5){animation-delay:.28s}.jigts-language-item:nth-child(6){animation-delay:.3s}.jigts-language-item:nth-child(7){animation-delay:.32s}.jigts-language-item:nth-child(8){animation-delay:.34s}.jigts-language-item:nth-child(9){animation-delay:.36s}.jigts-language-item:nth-child(10){animation-delay:.38s}@media(max-width:400px){.jigts-widget-dropdown{width:70vw;right:auto;left:50%;transform:translate(-59%) scale(.95) translateY(10px)}.jigts-widget-dropdown.jigts-open{transform:translate(-90%) scale(1) translateY(0)}}@media(prefers-contrast:high){.jigts-widget-trigger,.jigts-widget-dropdown{border:2px solid #000}}@media(prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}.jigts-translated-content{transition:all .3s ease}.jigts-translated-content.jigts-has-html{line-height:1.5}.jigts-translated-content.jigts-font-adjusted{transition:font-size .3s ease}.jigts-content-transition{animation:jigtsContentFade .3s ease-in-out}@keyframes jigtsContentFade{0%{opacity:.7;transform:translateY(2px)}to{opacity:1;transform:translateY(0)}}',document.head.appendChild(t)}_=new S(t,e)}return _};return"loading"===document.readyState?void window.addEventListener("DOMContentLoaded",i):i()}});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export type TranslatableContent = {
|
|
2
|
+
element: HTMLElement;
|
|
3
|
+
text: string;
|
|
4
|
+
isNested: boolean;
|
|
5
|
+
}[];
|
|
6
|
+
export declare class DocumentNavigator {
|
|
7
|
+
/**
|
|
8
|
+
* Retrieves text nodes eligible for translation from the document
|
|
9
|
+
* @returns Collection of text nodes ready for translation
|
|
10
|
+
*/
|
|
11
|
+
static findTranslatableContent(): TranslatableContent;
|
|
12
|
+
/**
|
|
13
|
+
* Divides a collection into smaller groups
|
|
14
|
+
* @param items Collection to divide
|
|
15
|
+
* @param groupSize Maximum size of each group
|
|
16
|
+
* @returns Array of item groups
|
|
17
|
+
*/
|
|
18
|
+
static divideIntoGroups<T>(items: T[], groupSize: number): T[][];
|
|
19
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { TranslationContent } from '../../types';
|
|
2
|
+
export declare class LocalStorageWrapper {
|
|
3
|
+
private prefix;
|
|
4
|
+
private readonly COMPRESSION_THRESHOLD;
|
|
5
|
+
private readonly COMPRESSION_MARKER;
|
|
6
|
+
private cache;
|
|
7
|
+
constructor(prefix?: string);
|
|
8
|
+
getPageKey(targetLang: string): string;
|
|
9
|
+
private shouldCompress;
|
|
10
|
+
private compress;
|
|
11
|
+
private decompress;
|
|
12
|
+
getItem(key: string): TranslationContent | null;
|
|
13
|
+
setItem(key: string, value: TranslationContent): void;
|
|
14
|
+
getNodeTranslation(originalText: string, targetLang: string): string | null;
|
|
15
|
+
setNodeTranslation(originalText: string, targetLang: string, translatedText: string): void;
|
|
16
|
+
setBatchNodeTranslationsArray(targetLang: string, batch: Array<{
|
|
17
|
+
originalText: string;
|
|
18
|
+
translatedText: string;
|
|
19
|
+
}>): void;
|
|
20
|
+
removeItem(key: string): void;
|
|
21
|
+
clear(lang_code?: string[]): void;
|
|
22
|
+
key(index: number): string | null;
|
|
23
|
+
get length(): number;
|
|
24
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
interface TranslationServiceOptions {
|
|
2
|
+
mockMode?: boolean;
|
|
3
|
+
apiUrl?: string;
|
|
4
|
+
requestHeaders?: Record<string, string>;
|
|
5
|
+
includeApiKeyHeader?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare class TranslationService {
|
|
8
|
+
private readonly publicKey;
|
|
9
|
+
private readonly apiUrl;
|
|
10
|
+
private readonly rateLimiter;
|
|
11
|
+
private readonly mockMode;
|
|
12
|
+
private readonly requestHeaders;
|
|
13
|
+
private readonly includeApiKeyHeader;
|
|
14
|
+
constructor(publicKey: string, options?: TranslationServiceOptions);
|
|
15
|
+
private normalizeTranslations;
|
|
16
|
+
private getRequestTargetLanguageCode;
|
|
17
|
+
translateBatchText(texts: string[], targetLang: string, maxRetries?: number, retryDelay?: number): Promise<string[] | null>;
|
|
18
|
+
}
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export interface Language {
|
|
2
|
+
code: string;
|
|
3
|
+
name: string;
|
|
4
|
+
native: string;
|
|
5
|
+
rtl?: number;
|
|
6
|
+
writing_system: string;
|
|
7
|
+
}
|
|
8
|
+
export interface TranslationConfig {
|
|
9
|
+
pageLanguage?: string;
|
|
10
|
+
position?: "top-right" | "top-left" | "bottom-left" | "bottom-right";
|
|
11
|
+
autoDetectLanguage?: boolean;
|
|
12
|
+
adjustFontSize?: boolean;
|
|
13
|
+
mockMode?: boolean;
|
|
14
|
+
targetLanguages?: string[];
|
|
15
|
+
apiUrl?: string;
|
|
16
|
+
requestHeaders?: Record<string, string>;
|
|
17
|
+
includeApiKeyHeader?: boolean;
|
|
18
|
+
theme?: {
|
|
19
|
+
baseColor?: string;
|
|
20
|
+
textColor?: string;
|
|
21
|
+
};
|
|
22
|
+
showUI?: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface CacheEntry {
|
|
25
|
+
text: string;
|
|
26
|
+
translation: string;
|
|
27
|
+
timestamp: number;
|
|
28
|
+
}
|
|
29
|
+
export interface TranslationResponseItem {
|
|
30
|
+
translatedText: string;
|
|
31
|
+
}
|
|
32
|
+
export interface TranslationResponse {
|
|
33
|
+
code?: number;
|
|
34
|
+
message?: string;
|
|
35
|
+
data?: {
|
|
36
|
+
translations?: TranslationResponseItem[];
|
|
37
|
+
};
|
|
38
|
+
translated_text?: string | string[];
|
|
39
|
+
source_language?: string;
|
|
40
|
+
detected_language?: string;
|
|
41
|
+
confidence?: number;
|
|
42
|
+
}
|
|
43
|
+
export interface TranslationWidgetOptions {
|
|
44
|
+
publicKey: string;
|
|
45
|
+
config?: TranslationConfig;
|
|
46
|
+
}
|
|
47
|
+
export interface WidgetElements {
|
|
48
|
+
trigger: HTMLDivElement | null;
|
|
49
|
+
dropdown: HTMLDivElement | null;
|
|
50
|
+
searchInput: HTMLInputElement | null;
|
|
51
|
+
clearSearch: HTMLDivElement | null;
|
|
52
|
+
languageItems: NodeListOf<HTMLDivElement> | null;
|
|
53
|
+
loadingIndicator: HTMLDivElement | null;
|
|
54
|
+
}
|
|
55
|
+
export interface TranslationResult {
|
|
56
|
+
success: boolean;
|
|
57
|
+
targetLanguage: string;
|
|
58
|
+
translatedNodes: number;
|
|
59
|
+
error?: string;
|
|
60
|
+
duration?: number;
|
|
61
|
+
}
|
|
62
|
+
export declare enum Position {
|
|
63
|
+
TopRight = "top-right",
|
|
64
|
+
TopLeft = "top-left",
|
|
65
|
+
BottomLeft = "bottom-left",
|
|
66
|
+
BottomRight = "bottom-right"
|
|
67
|
+
}
|
|
68
|
+
export declare enum LOCALSTORAGE_KEYS {
|
|
69
|
+
PREFERRED_LANGUAGE = "jss-pref"
|
|
70
|
+
}
|
|
71
|
+
export declare enum ATTRIBUTES {
|
|
72
|
+
TRANSLATED_LANG = "data-translated-lang",
|
|
73
|
+
ORIGINAL_TEXT = "data-original-text",
|
|
74
|
+
ORIGINAL_FONT_SIZE = "data-original-font-size"
|
|
75
|
+
}
|
|
76
|
+
export declare const LANG_PARAM = "lang";
|
|
77
|
+
export interface TranslationContent {
|
|
78
|
+
[key: string]: string;
|
|
79
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { TranslatableContent } from '../lib/dom';
|
|
2
|
+
declare function generateHashForContent(nodes: TranslatableContent): string;
|
|
3
|
+
declare function getVisibleTextContent(element: HTMLElement): string;
|
|
4
|
+
declare const removeEmojis: (text: string) => string;
|
|
5
|
+
declare const getUserLanguage: () => string;
|
|
6
|
+
declare function generateNodeHash(text: string): string;
|
|
7
|
+
declare function generateChunkHash(texts: string[]): string;
|
|
8
|
+
type ValidationResult = {
|
|
9
|
+
isValid: true;
|
|
10
|
+
} | {
|
|
11
|
+
isValid: false;
|
|
12
|
+
message: string;
|
|
13
|
+
};
|
|
14
|
+
declare function validatePublicApiKey(publicKey: string): ValidationResult;
|
|
15
|
+
export { generateHashForContent, generateNodeHash, generateChunkHash, getVisibleTextContent, removeEmojis, getUserLanguage, validatePublicApiKey };
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { TranslationConfig, TranslationResult } from '../types';
|
|
2
|
+
export declare class TranslationWidget {
|
|
3
|
+
private config;
|
|
4
|
+
private translationService?;
|
|
5
|
+
private targetLanguages;
|
|
6
|
+
private currentLanguage;
|
|
7
|
+
private widget;
|
|
8
|
+
private elements;
|
|
9
|
+
private autoDetectLanguage;
|
|
10
|
+
private isTranslated;
|
|
11
|
+
private userLanguage;
|
|
12
|
+
private isTranslating;
|
|
13
|
+
private observer;
|
|
14
|
+
private translationScheduled;
|
|
15
|
+
private scheduleTimeout;
|
|
16
|
+
private showUI;
|
|
17
|
+
private lastTranslated;
|
|
18
|
+
private static instance;
|
|
19
|
+
private currentTranslationPromise;
|
|
20
|
+
private lastRequestedLanguage;
|
|
21
|
+
private translationRequestId;
|
|
22
|
+
/**
|
|
23
|
+
* @param publicKey - The public api key for the translation widget
|
|
24
|
+
* @param config - The configuration for the translation widget
|
|
25
|
+
*/
|
|
26
|
+
constructor(publicKey: string, config?: Partial<TranslationConfig>);
|
|
27
|
+
/**
|
|
28
|
+
* Initializes the translation widget
|
|
29
|
+
*/
|
|
30
|
+
private initialize;
|
|
31
|
+
private resolveTargetLanguages;
|
|
32
|
+
private findLanguageByCode;
|
|
33
|
+
private isTargetLanguage;
|
|
34
|
+
/**
|
|
35
|
+
* Gets the value of a URL parameter
|
|
36
|
+
* @param name - The name of the URL parameter
|
|
37
|
+
* @returns The value of the URL parameter
|
|
38
|
+
*/
|
|
39
|
+
private getUrlParameter;
|
|
40
|
+
/**
|
|
41
|
+
* Sets up the content observer
|
|
42
|
+
*/
|
|
43
|
+
private setupContentObserver;
|
|
44
|
+
/**
|
|
45
|
+
* Observes the body for changes
|
|
46
|
+
*/
|
|
47
|
+
private observeBody;
|
|
48
|
+
/**
|
|
49
|
+
* Handles the URL change
|
|
50
|
+
*/
|
|
51
|
+
private onUrlChange;
|
|
52
|
+
/**
|
|
53
|
+
* Sets up the URL observer
|
|
54
|
+
*/
|
|
55
|
+
private setupURLObserver;
|
|
56
|
+
/**
|
|
57
|
+
* Creates the widget
|
|
58
|
+
*/
|
|
59
|
+
private createWidget;
|
|
60
|
+
/**
|
|
61
|
+
* Gets the current language label
|
|
62
|
+
* @returns The current language label
|
|
63
|
+
*/
|
|
64
|
+
private getCurrentLanguageLabel;
|
|
65
|
+
/**
|
|
66
|
+
* Creates the widget HTML
|
|
67
|
+
* @param currentLanguageLabel - The current language label
|
|
68
|
+
* @returns The widget HTML
|
|
69
|
+
*/
|
|
70
|
+
private createWidgetHTML;
|
|
71
|
+
/**
|
|
72
|
+
* Creates the language options
|
|
73
|
+
* @returns The language options
|
|
74
|
+
*/
|
|
75
|
+
private createLanguageOptions;
|
|
76
|
+
/**
|
|
77
|
+
* Updates the trigger text
|
|
78
|
+
* @param newText - The new text
|
|
79
|
+
*/
|
|
80
|
+
private updateTriggerText;
|
|
81
|
+
/**
|
|
82
|
+
* Gets the text to translate
|
|
83
|
+
* @param node - The node to translate
|
|
84
|
+
* @param parent - The parent element
|
|
85
|
+
* @param targetLang - The target language
|
|
86
|
+
* @returns The text to translate
|
|
87
|
+
*/
|
|
88
|
+
private getTextToTranslate;
|
|
89
|
+
/**
|
|
90
|
+
* Calculates the font size
|
|
91
|
+
* @param text - The text to calculate the font size for
|
|
92
|
+
* @param originalFontSize - The original font size
|
|
93
|
+
* @param originalText - The original text
|
|
94
|
+
* @returns The font size
|
|
95
|
+
*/
|
|
96
|
+
private calculateFontSize;
|
|
97
|
+
/**
|
|
98
|
+
* Updates the loading state
|
|
99
|
+
* @param isLoading - Whether the widget is loading
|
|
100
|
+
*/
|
|
101
|
+
private updateLoadingState;
|
|
102
|
+
/**
|
|
103
|
+
* Main function to translate the page
|
|
104
|
+
*
|
|
105
|
+
* Handles the translation of the page for multiple languages
|
|
106
|
+
*
|
|
107
|
+
* 1. Increments the request ID for each new translation
|
|
108
|
+
* 2. Waits for the current translation to complete
|
|
109
|
+
* 3. If the target language is the default page language, resets the translations
|
|
110
|
+
* 4. Creates a new promise for each translation and awaits it
|
|
111
|
+
*
|
|
112
|
+
* @param targetLang - The target language
|
|
113
|
+
*/
|
|
114
|
+
private translatePage;
|
|
115
|
+
/**
|
|
116
|
+
* Reset to default Page language
|
|
117
|
+
* @returns
|
|
118
|
+
*/
|
|
119
|
+
resetToDefaultLanguage(): void;
|
|
120
|
+
private _translatePage;
|
|
121
|
+
/**
|
|
122
|
+
* Updates the visibility of the reset button
|
|
123
|
+
*/
|
|
124
|
+
private updateResetButtonVisibility;
|
|
125
|
+
/**
|
|
126
|
+
* Resets the translations
|
|
127
|
+
*/
|
|
128
|
+
private resetTranslations;
|
|
129
|
+
/**
|
|
130
|
+
* Adjusts the dropdown position
|
|
131
|
+
*/
|
|
132
|
+
private adjustDropdownPosition;
|
|
133
|
+
/**
|
|
134
|
+
* Sets up the event listeners
|
|
135
|
+
*/
|
|
136
|
+
private setupEventListeners;
|
|
137
|
+
private scheduleTranslation;
|
|
138
|
+
/**
|
|
139
|
+
* Public method to translate the page to a specific language
|
|
140
|
+
* @param langCode The language code to translate to
|
|
141
|
+
* @returns Promise that resolves when translation is complete
|
|
142
|
+
*/
|
|
143
|
+
translateTo(langCode: string, onComplete?: (result: TranslationResult) => void, onError?: (error: Error) => void): Promise<TranslationResult>;
|
|
144
|
+
/**
|
|
145
|
+
* Get the current instance of TranslationWidget
|
|
146
|
+
* @returns The current TranslationWidget instance or null if not initialized
|
|
147
|
+
*/
|
|
148
|
+
static getInstance(): TranslationWidget | null;
|
|
149
|
+
private getLanguageSVG;
|
|
150
|
+
/**
|
|
151
|
+
* Safely sets HTML content for translated text, handling nested HTML structures
|
|
152
|
+
* @param element - The element to update
|
|
153
|
+
* @param translatedText - The translated text that may contain HTML
|
|
154
|
+
*/
|
|
155
|
+
private setTranslatedContent;
|
|
156
|
+
}
|
|
157
|
+
declare global {
|
|
158
|
+
interface Window {
|
|
159
|
+
resetTranslation: (defaultLang: string, onComplete?: (result: Pick<TranslationResult, "success" | "targetLanguage">) => void, onError?: (error: Error) => void) => void;
|
|
160
|
+
translate: (langCode: string, onComplete?: (result: TranslationResult) => void, onError?: (error: Error) => void) => Promise<TranslationResult>;
|
|
161
|
+
clearCache: (lang_code: string[], onComplete?: () => void, onError?: (error: Error) => void) => void;
|
|
162
|
+
}
|
|
163
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@yander/translation-widget",
|
|
3
|
+
"version": "1.1.4-yander.0",
|
|
4
|
+
"description": "Translation widget to automatically translate any website with a single script",
|
|
5
|
+
"homepage": "https://github.com/JigsawStack/translation-widget",
|
|
6
|
+
"author": "JigsawStack",
|
|
7
|
+
"license": "Apache-2.0",
|
|
8
|
+
"keywords": [
|
|
9
|
+
"translation",
|
|
10
|
+
"widget",
|
|
11
|
+
"translation-widget",
|
|
12
|
+
"google-translate",
|
|
13
|
+
"translation api",
|
|
14
|
+
"translation widget api"
|
|
15
|
+
],
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/JigsawStack/translation-widget.git"
|
|
19
|
+
},
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/JigsawStack/translation-widget/issues"
|
|
22
|
+
},
|
|
23
|
+
"packageManager": "yarn@1.22.22",
|
|
24
|
+
"type": "module",
|
|
25
|
+
"main": "./dist/index.cjs",
|
|
26
|
+
"module": "./dist/index.js",
|
|
27
|
+
"exports": {
|
|
28
|
+
"require": "./dist/index.cjs",
|
|
29
|
+
"import": "./dist/index.js"
|
|
30
|
+
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"registry": "https://registry.npmjs.org/",
|
|
33
|
+
"access": "public"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist"
|
|
37
|
+
],
|
|
38
|
+
"types": "./dist/index.d.ts",
|
|
39
|
+
"scripts": {
|
|
40
|
+
"format": "biome format --write ./src",
|
|
41
|
+
"dev": "vite",
|
|
42
|
+
"build": "tsc && vite build",
|
|
43
|
+
"prepublishOnly": "npm run build"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@types/node": "^22.13.4",
|
|
47
|
+
"terser": "^5.39.0",
|
|
48
|
+
"typescript": "~5.7.2",
|
|
49
|
+
"vite": "^6.1.0",
|
|
50
|
+
"vite-plugin-dts": "^4.5.0"
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"lz-string": "^1.5.0"
|
|
54
|
+
}
|
|
55
|
+
}
|