diff --git a/src/livecodes/i18n/locales/ar/language-info.lokalise.json b/src/livecodes/i18n/locales/ar/language-info.lokalise.json
index 54be4eed4..26d2173ef 100644
--- a/src/livecodes/i18n/locales/ar/language-info.lokalise.json
+++ b/src/livecodes/i18n/locales/ar/language-info.lokalise.json
@@ -648,6 +648,15 @@
"ocamlJs.name": {
"translation": "OCaml (JS)"
},
+ "odin-wasm.desc": {
+ "translation": "مترجم Odin الخاص، المُجمَّع إلى WebAssembly، يعمل بالكامل داخل المتصفح."
+ },
+ "odin-wasm.link": {
+ "translation": "
الموقع الرسمي لـ Odin نظرة عامة على Odin واجهة برمجة المكتبة القياسية تعلم X في Y دقيقة، حيث X = Odin وثائق LiveCodes تحميل قالب البدء "
+ },
+ "odin-wasm.name": {
+ "translation": "Odin (Wasm)"
+ },
"pascal.desc": {
"translation": "Pascal يعمل في المتصفح باستخدام pas2js (من فريق Free Pascal) ومُجمَّع إلى WebAssembly."
},
diff --git a/src/livecodes/i18n/locales/ar/language-info.ts b/src/livecodes/i18n/locales/ar/language-info.ts
index 902b978a4..7ef304336 100644
--- a/src/livecodes/i18n/locales/ar/language-info.ts
+++ b/src/livecodes/i18n/locales/ar/language-info.ts
@@ -358,6 +358,11 @@ const languageInfo: I18nLangInfoTranslation = {
link: '<1><2>موقع OCaml2>1> <3> <4>وثائق OCaml4> 3> <5> <6>تعلم X في Y دقائق، حيث X=OCaml6> 5> <7> <8>تحميل القالب الأولي8> 7>',
name: 'OCaml (JS)',
},
+ 'odin-wasm': {
+ desc: 'مترجم Odin الخاص، المُجمَّع إلى WebAssembly، يعمل بالكامل داخل المتصفح.',
+ link: '<1> <2>الموقع الرسمي لـ Odin2> 1> <3> <4>نظرة عامة على Odin4> 3> <5> <6>واجهة برمجة المكتبة القياسية6> 5> <7> <8>تعلم X في Y دقيقة، حيث X = Odin8> 7> <9> <10>وثائق LiveCodes10> 9> <11> <12>تحميل قالب البدء12> 11>',
+ name: 'Odin (Wasm)',
+ },
pascal: {
desc: 'Pascal يعمل في المتصفح باستخدام pas2js (من فريق Free Pascal) ومُجمَّع إلى WebAssembly.',
link: '<1> <2>الموقع الرسمي لـ Free Pascal2> 1> <3> <4>وثائق pas2js4> 3> <5> <6>pas2js wiki6> 5> <7> <8>وثائق LiveCodes8> 7> <9> <10>تحميل القالب الأولي10> 9>',
diff --git a/src/livecodes/i18n/locales/ar/translation.lokalise.json b/src/livecodes/i18n/locales/ar/translation.lokalise.json
index bce161586..f18218349 100644
--- a/src/livecodes/i18n/locales/ar/translation.lokalise.json
+++ b/src/livecodes/i18n/locales/ar/translation.lokalise.json
@@ -2100,6 +2100,9 @@
"templates.starter.ocaml-js": {
"translation": "قالب OCaml (JS)"
},
+ "templates.starter.odin-wasm": {
+ "translation": "قالب Odin"
+ },
"templates.starter.pascal": {
"translation": "قالب Pascal"
},
diff --git a/src/livecodes/i18n/locales/ar/translation.ts b/src/livecodes/i18n/locales/ar/translation.ts
index b69c1e35e..7ff51c18b 100644
--- a/src/livecodes/i18n/locales/ar/translation.ts
+++ b/src/livecodes/i18n/locales/ar/translation.ts
@@ -1038,6 +1038,7 @@ const translation: I18nTranslation = {
'objc-wasm': 'قالب Objective-C (Wasm)',
ocaml: 'قالب Ocaml',
'ocaml-js': 'قالب OCaml (JS)',
+ 'odin-wasm': 'قالب Odin',
pascal: 'قالب Pascal',
perl: 'قالب Perl',
phaser: 'قالب Phaser',
diff --git a/src/livecodes/i18n/locales/bn/language-info.lokalise.json b/src/livecodes/i18n/locales/bn/language-info.lokalise.json
index d2992dd1b..2e2cecc15 100644
--- a/src/livecodes/i18n/locales/bn/language-info.lokalise.json
+++ b/src/livecodes/i18n/locales/bn/language-info.lokalise.json
@@ -648,6 +648,15 @@
"ocamlJs.name": {
"translation": "OCaml (JS)"
},
+ "odin-wasm.desc": {
+ "translation": "Odin-এর নিজস্ব কম্পাইলার, WebAssembly-তে কম্পাইল করা, সম্পূর্ণভাবে ব্রাউজারে চলে।"
+ },
+ "odin-wasm.link": {
+ "translation": "
Odin অফিসিয়াল ওয়েবসাইট Odin-এর সংক্ষিপ্ত বিবরণ স্ট্যান্ডার্ড লাইব্রেরি API Y মিনিটে X শিখুন, যেখানে X=Odin লাইভকোড ডকুমেন্টেশন স্টার্টার টেমপ্লেট লোড করুন "
+ },
+ "odin-wasm.name": {
+ "translation": "Odin (Wasm)"
+ },
"pascal.desc": {
"translation": "Free Pascal দলের pas2js ব্যবহার করে ব্রাউজারে Pascal চলছে, যা WebAssembly-তে কম্পাইল করা।"
},
diff --git a/src/livecodes/i18n/locales/bn/language-info.ts b/src/livecodes/i18n/locales/bn/language-info.ts
index c286897d4..eafd2ec09 100644
--- a/src/livecodes/i18n/locales/bn/language-info.ts
+++ b/src/livecodes/i18n/locales/bn/language-info.ts
@@ -362,6 +362,11 @@ const languageInfo: I18nLangInfoTranslation = {
link: '<1><2>OCaml ওয়েবসাইট2>1> <3> <4>OCaml ডকুমেন্টেশন4> 3> <5> <6>Y মিনিটে X শিখুন, যেখানে X=OCaml6> 5> <7> <8>স্টার্টার টেমপ্লেট লোড করুন8> 7>',
name: 'OCaml (JS)',
},
+ 'odin-wasm': {
+ desc: 'Odin-এর নিজস্ব কম্পাইলার, WebAssembly-তে কম্পাইল করা, সম্পূর্ণভাবে ব্রাউজারে চলে।',
+ link: '<1> <2>Odin অফিসিয়াল ওয়েবসাইট2> 1> <3> <4>Odin-এর সংক্ষিপ্ত বিবরণ4> 3> <5> <6>স্ট্যান্ডার্ড লাইব্রেরি API6> 5> <7> <8>Y মিনিটে X শিখুন, যেখানে X=Odin8> 7> <9> <10>লাইভকোড ডকুমেন্টেশন10> 9> <11> <12>স্টার্টার টেমপ্লেট লোড করুন12> 11>',
+ name: 'Odin (Wasm)',
+ },
pascal: {
desc: 'Free Pascal দলের pas2js ব্যবহার করে ব্রাউজারে Pascal চলছে, যা WebAssembly-তে কম্পাইল করা।',
link: '<1> <2>Free Pascal অফিসিয়াল ওয়েবসাইট2> 1> <3> <4>pas2js ডকুমেন্টেশন4> 3> <5> <6>pas2js wiki6> 5> <7> <8>LiveCodes ডকুমেন্টেশন8> 7> <9> <10>স্টার্টার টেমপ্লেট লোড করুন10> 9>',
diff --git a/src/livecodes/i18n/locales/bn/translation.lokalise.json b/src/livecodes/i18n/locales/bn/translation.lokalise.json
index 35cb6a659..304fe216c 100644
--- a/src/livecodes/i18n/locales/bn/translation.lokalise.json
+++ b/src/livecodes/i18n/locales/bn/translation.lokalise.json
@@ -2100,6 +2100,9 @@
"templates.starter.ocaml-js": {
"translation": "OCaml (JS) স্টার্টার"
},
+ "templates.starter.odin-wasm": {
+ "translation": "Odin স্টার্টার"
+ },
"templates.starter.pascal": {
"translation": "Pascal স্টার্টার"
},
diff --git a/src/livecodes/i18n/locales/bn/translation.ts b/src/livecodes/i18n/locales/bn/translation.ts
index 261aff8d1..330bd4dd8 100644
--- a/src/livecodes/i18n/locales/bn/translation.ts
+++ b/src/livecodes/i18n/locales/bn/translation.ts
@@ -1038,6 +1038,7 @@ const translation: I18nTranslation = {
'objc-wasm': 'Objective-C (Wasm) স্টার্টার',
ocaml: 'Ocaml স্টার্টার',
'ocaml-js': 'OCaml (JS) স্টার্টার',
+ 'odin-wasm': 'Odin স্টার্টার',
pascal: 'Pascal স্টার্টার',
perl: 'Perl স্টার্টার',
phaser: 'Phaser স্টার্টার',
diff --git a/src/livecodes/i18n/locales/de/language-info.lokalise.json b/src/livecodes/i18n/locales/de/language-info.lokalise.json
index 07ea64207..8552ed6f9 100644
--- a/src/livecodes/i18n/locales/de/language-info.lokalise.json
+++ b/src/livecodes/i18n/locales/de/language-info.lokalise.json
@@ -648,6 +648,15 @@
"ocamlJs.name": {
"translation": "OCaml (JS)"
},
+ "odin-wasm.desc": {
+ "translation": "Odins eigener Compiler, zu WebAssembly kompiliert, läuft vollständig im Browser."
+ },
+ "odin-wasm.link": {
+ "translation": "
Offizielle Website von Odin Überblick über Odin Standardbibliothek-API Lerne X in Y Minuten, wobei X = Odin LiveCodes-Dokumentation Startervorlage laden "
+ },
+ "odin-wasm.name": {
+ "translation": "Odin (Wasm)"
+ },
"pascal.desc": {
"translation": "Pascal läuft im Browser mit pas2js (vom Free Pascal-Team) und wird zu WebAssembly kompiliert."
},
diff --git a/src/livecodes/i18n/locales/de/language-info.ts b/src/livecodes/i18n/locales/de/language-info.ts
index 4eadb5a4f..21621428c 100644
--- a/src/livecodes/i18n/locales/de/language-info.ts
+++ b/src/livecodes/i18n/locales/de/language-info.ts
@@ -364,6 +364,11 @@ const languageInfo: I18nLangInfoTranslation = {
link: '<1><2>OCaml Website2>1> <3> <4>OCaml Dokumentation4> 3> <5> <6>Lerne X in Y Minuten, wobei X=OCaml6> 5> <7> <8>Starter-Vorlage laden8> 7>',
name: 'OCaml (JS)',
},
+ 'odin-wasm': {
+ desc: 'Odins eigener Compiler, zu WebAssembly kompiliert, läuft vollständig im Browser.',
+ link: '<1> <2>Offizielle Website von Odin2> 1> <3> <4>Überblick über Odin4> 3> <5> <6>Standardbibliothek-API6> 5> <7> <8>Lerne X in Y Minuten, wobei X = Odin8> 7> <9> <10>LiveCodes-Dokumentation10> 9> <11> <12>Startervorlage laden12> 11>',
+ name: 'Odin (Wasm)',
+ },
pascal: {
desc: 'Pascal läuft im Browser mit pas2js (vom Free Pascal-Team) und wird zu WebAssembly kompiliert.',
link: '<1> <2>Offizielle Free Pascal-Website2> 1> <3> <4>pas2js-Dokumentation4> 3> <5> <6>pas2js wiki6> 5> <7> <8>LiveCodes-Dokumentationen8> 7> <9> <10>Starter-Vorlage laden10> 9>',
diff --git a/src/livecodes/i18n/locales/de/translation.lokalise.json b/src/livecodes/i18n/locales/de/translation.lokalise.json
index 275aad54b..f8162ebd1 100644
--- a/src/livecodes/i18n/locales/de/translation.lokalise.json
+++ b/src/livecodes/i18n/locales/de/translation.lokalise.json
@@ -2100,6 +2100,9 @@
"templates.starter.ocaml-js": {
"translation": "OCaml (JS)-Starter"
},
+ "templates.starter.odin-wasm": {
+ "translation": "Odin-Starter"
+ },
"templates.starter.pascal": {
"translation": "Pascal-Starter"
},
diff --git a/src/livecodes/i18n/locales/de/translation.ts b/src/livecodes/i18n/locales/de/translation.ts
index a53e89338..c1543f390 100644
--- a/src/livecodes/i18n/locales/de/translation.ts
+++ b/src/livecodes/i18n/locales/de/translation.ts
@@ -1040,6 +1040,7 @@ const translation: I18nTranslation = {
'objc-wasm': 'Objective-C (Wasm)-Starter',
ocaml: 'OCaml-Starter',
'ocaml-js': 'OCaml (JS)-Starter',
+ 'odin-wasm': 'Odin-Starter',
pascal: 'Pascal-Starter',
perl: 'Perl-Starter',
phaser: 'Phaser-Starter',
diff --git a/src/livecodes/i18n/locales/en/language-info.lokalise.json b/src/livecodes/i18n/locales/en/language-info.lokalise.json
index 9bdead6b5..90ca83dc2 100644
--- a/src/livecodes/i18n/locales/en/language-info.lokalise.json
+++ b/src/livecodes/i18n/locales/en/language-info.lokalise.json
@@ -864,6 +864,18 @@
"notes": "",
"translation": "OCaml (JS)"
},
+ "odin-wasm.desc": {
+ "notes": "",
+ "translation": "Odin's own compiler, compiled to WebAssembly, running entirely in the browser."
+ },
+ "odin-wasm.link": {
+ "notes": "###
###\n\n\n### ###\n\n\n### ###\n\n\n### ###\n\n\n### ###\n\n\n### ###\n\n\n### ###\n\n\n### ###\n\n\n### ###\n\n\n### ###\n\n\n### ###\n\n\n### ###\n\n\n",
+ "translation": " Odin official website Overview of Odin Standard library API Learn X in Y minutes, where X=Odin LiveCodes Documentation Load starter template "
+ },
+ "odin-wasm.name": {
+ "notes": "",
+ "translation": "Odin (Wasm)"
+ },
"pascal.desc": {
"notes": "",
"translation": "Pascal running in the browser using pas2js (by the Free Pascal team) compiled to WebAssembly."
diff --git a/src/livecodes/i18n/locales/en/language-info.ts b/src/livecodes/i18n/locales/en/language-info.ts
index fb94cc563..97da69a43 100644
--- a/src/livecodes/i18n/locales/en/language-info.ts
+++ b/src/livecodes/i18n/locales/en/language-info.ts
@@ -375,6 +375,11 @@ const languageInfo = {
link: '<1><2>OCaml website2>1> <3> <4>OCaml documentation4> 3> <5> <6>Learn X in Y minutes, where X=OCaml6> 5> <7> <8>Load starter template8> 7>',
name: 'OCaml (JS)',
},
+ 'odin-wasm': {
+ desc: "Odin's own compiler, compiled to WebAssembly, running entirely in the browser.",
+ link: '<1> <2>Odin official website2> 1> <3> <4>Overview of Odin4> 3> <5> <6>Standard library API6> 5> <7> <8>Learn X in Y minutes, where X=Odin8> 7> <9> <10>LiveCodes Documentation10> 9> <11> <12>Load starter template12> 11>',
+ name: 'Odin (Wasm)',
+ },
pascal: {
desc: 'Pascal running in the browser using pas2js (by the Free Pascal team) compiled to WebAssembly.',
link: '<1> <2>Free Pascal website2> 1> <3> <4>pas2js documentation4> 3> <5> <6>pas2js wiki6> 5> <7> <8>LiveCodes Documentation8> 7> <9> <10>Load starter template10> 9>',
diff --git a/src/livecodes/i18n/locales/en/translation.lokalise.json b/src/livecodes/i18n/locales/en/translation.lokalise.json
index 96ea43998..6ea7baf23 100644
--- a/src/livecodes/i18n/locales/en/translation.lokalise.json
+++ b/src/livecodes/i18n/locales/en/translation.lokalise.json
@@ -2800,6 +2800,10 @@
"notes": "",
"translation": "OCaml (JS) Starter"
},
+ "templates.starter.odin-wasm": {
+ "notes": "",
+ "translation": "Odin Starter"
+ },
"templates.starter.pascal": {
"notes": "",
"translation": "Pascal Starter"
diff --git a/src/livecodes/i18n/locales/en/translation.ts b/src/livecodes/i18n/locales/en/translation.ts
index e3940de1b..adc249477 100644
--- a/src/livecodes/i18n/locales/en/translation.ts
+++ b/src/livecodes/i18n/locales/en/translation.ts
@@ -1046,6 +1046,7 @@ const translation = {
'objc-wasm': 'Objective-C (Wasm) Starter',
ocaml: 'Ocaml Starter',
'ocaml-js': 'OCaml (JS) Starter',
+ 'odin-wasm': 'Odin Starter',
pascal: 'Pascal Starter',
perl: 'Perl Starter',
phaser: 'Phaser Starter',
diff --git a/src/livecodes/i18n/locales/es/language-info.lokalise.json b/src/livecodes/i18n/locales/es/language-info.lokalise.json
index 519fbe2df..ad6b6a9fb 100644
--- a/src/livecodes/i18n/locales/es/language-info.lokalise.json
+++ b/src/livecodes/i18n/locales/es/language-info.lokalise.json
@@ -648,6 +648,15 @@
"ocamlJs.name": {
"translation": "OCaml (JS)"
},
+ "odin-wasm.desc": {
+ "translation": "El propio compilador de Odin, compilado a WebAssembly, ejecutándose íntegramente en el navegador."
+ },
+ "odin-wasm.link": {
+ "translation": " Página web oficial de Odin Descripción general de Odin API de la biblioteca estándar Aprende X en Y minutos, donde X = Odin Documentación de LiveCodes Cargar plantilla de inicio "
+ },
+ "odin-wasm.name": {
+ "translation": "Odin (Wasm)"
+ },
"pascal.desc": {
"translation": "Pascal ejecutándose en el navegador usando pas2js (por el equipo de Free Pascal), compilado a WebAssembly."
},
diff --git a/src/livecodes/i18n/locales/es/language-info.ts b/src/livecodes/i18n/locales/es/language-info.ts
index 0deceb75a..8cb9d35bf 100644
--- a/src/livecodes/i18n/locales/es/language-info.ts
+++ b/src/livecodes/i18n/locales/es/language-info.ts
@@ -364,6 +364,11 @@ const languageInfo: I18nLangInfoTranslation = {
link: '<1><2>Sitio web de OCaml2>1> <3> <4>Documentación de OCaml4> 3> <5> <6>Aprende X en Y minutos, donde X=OCaml6> 5> <7> <8>Cargar plantilla inicial8> 7>',
name: 'OCaml (JS)',
},
+ 'odin-wasm': {
+ desc: 'El propio compilador de Odin, compilado a WebAssembly, ejecutándose íntegramente en el navegador.',
+ link: '<1> <2>Página web oficial de Odin2> 1> <3> <4>Descripción general de Odin4> 3> <5> <6>API de la biblioteca estándar6> 5> <7> <8>Aprende X en Y minutos, donde X = Odin8> 7> <9> <10>Documentación de LiveCodes10> 9> <11> <12>Cargar plantilla de inicio12> 11>',
+ name: 'Odin (Wasm)',
+ },
pascal: {
desc: 'Pascal ejecutándose en el navegador usando pas2js (por el equipo de Free Pascal), compilado a WebAssembly.',
link: '<1> <2>Sitio web oficial de Free Pascal2> 1> <3> <4>Documentación de pas2js4> 3> <5> <6>pas2js wiki6> 5> <7> <8>Documentación de LiveCodes8> 7> <9> <10>Cargar plantilla inicial10> 9>',
diff --git a/src/livecodes/i18n/locales/es/translation.lokalise.json b/src/livecodes/i18n/locales/es/translation.lokalise.json
index d283f3819..33bf4cf86 100644
--- a/src/livecodes/i18n/locales/es/translation.lokalise.json
+++ b/src/livecodes/i18n/locales/es/translation.lokalise.json
@@ -2100,6 +2100,9 @@
"templates.starter.ocaml-js": {
"translation": "Inicio OCaml (JS)"
},
+ "templates.starter.odin-wasm": {
+ "translation": "Inicio Odin"
+ },
"templates.starter.pascal": {
"translation": "Inicio Pascal"
},
diff --git a/src/livecodes/i18n/locales/es/translation.ts b/src/livecodes/i18n/locales/es/translation.ts
index c5f3a96fd..a53f3e6c0 100644
--- a/src/livecodes/i18n/locales/es/translation.ts
+++ b/src/livecodes/i18n/locales/es/translation.ts
@@ -1038,6 +1038,7 @@ const translation: I18nTranslation = {
'objc-wasm': 'Inicio Objective-C (Wasm)',
ocaml: 'Inicio Ocaml',
'ocaml-js': 'Inicio OCaml (JS)',
+ 'odin-wasm': 'Inicio Odin',
pascal: 'Inicio Pascal',
perl: 'Inicio Perl',
phaser: 'Inicio Phaser',
diff --git a/src/livecodes/i18n/locales/fa/language-info.lokalise.json b/src/livecodes/i18n/locales/fa/language-info.lokalise.json
index b38d70c44..698420cb6 100644
--- a/src/livecodes/i18n/locales/fa/language-info.lokalise.json
+++ b/src/livecodes/i18n/locales/fa/language-info.lokalise.json
@@ -648,6 +648,15 @@
"ocamlJs.name": {
"translation": "OCaml (JS)"
},
+ "odin-wasm.desc": {
+ "translation": "کامپایلر اختصاصی Odin، که به WebAssembly کامپایل شده، کاملاً در مرورگر اجرا میشود."
+ },
+ "odin-wasm.link": {
+ "translation": " وبسایت رسمی Odin مروری بر Odin API کتابخانه استاندارد یادگیری X در Y دقیقه، که X=Odin مستندات LiveCodes بارگیری قالب شروع "
+ },
+ "odin-wasm.name": {
+ "translation": "Odin (Wasm)"
+ },
"pascal.desc": {
"translation": "Pascal با استفاده از pas2js (توسط تیم Free Pascal) در مرورگر اجرا میشود و به WebAssembly کامپایل شده است."
},
diff --git a/src/livecodes/i18n/locales/fa/language-info.ts b/src/livecodes/i18n/locales/fa/language-info.ts
index fd34c3514..96cc510d0 100644
--- a/src/livecodes/i18n/locales/fa/language-info.ts
+++ b/src/livecodes/i18n/locales/fa/language-info.ts
@@ -363,6 +363,11 @@ const languageInfo: I18nLangInfoTranslation = {
link: '<1><2>وبسایت OCaml2>1> <3> <4>مستندات OCaml4> 3> <5> <6>یادگیری X در Y دقیقه، جایی که X=OCaml6> 5> <7> <8>بارگذاری قالب شروع کننده8> 7>',
name: 'OCaml (JS)',
},
+ 'odin-wasm': {
+ desc: 'کامپایلر اختصاصی Odin، که به WebAssembly کامپایل شده، کاملاً در مرورگر اجرا میشود.',
+ link: '<1> <2>وبسایت رسمی Odin2> 1> <3> <4>مروری بر Odin4> 3> <5> <6>API کتابخانه استاندارد6> 5> <7> <8>یادگیری X در Y دقیقه، که X=Odin8> 7> <9> <10>مستندات LiveCodes10> 9> <11> <12>بارگیری قالب شروع12> 11>',
+ name: 'Odin (Wasm)',
+ },
pascal: {
desc: 'Pascal با استفاده از pas2js (توسط تیم Free Pascal) در مرورگر اجرا میشود و به WebAssembly کامپایل شده است.',
link: '<1> <2>وبسایت رسمی Free Pascal2> 1> <3> <4>مستندات pas2js4> 3> <5> <6>pas2js wiki6> 5> <7> <8>مستندات LiveCodes8> 7> <9> <10>بارگذاری قالب شروع کننده10> 9>',
diff --git a/src/livecodes/i18n/locales/fa/translation.lokalise.json b/src/livecodes/i18n/locales/fa/translation.lokalise.json
index 35d3b127f..d526a7428 100644
--- a/src/livecodes/i18n/locales/fa/translation.lokalise.json
+++ b/src/livecodes/i18n/locales/fa/translation.lokalise.json
@@ -2100,6 +2100,9 @@
"templates.starter.ocaml-js": {
"translation": "شروع کننده OCaml (JS)"
},
+ "templates.starter.odin-wasm": {
+ "translation": "شروع کننده Odin"
+ },
"templates.starter.pascal": {
"translation": "شروع کننده Pascal"
},
diff --git a/src/livecodes/i18n/locales/fa/translation.ts b/src/livecodes/i18n/locales/fa/translation.ts
index 51b6c0b6f..08c0d6fc4 100644
--- a/src/livecodes/i18n/locales/fa/translation.ts
+++ b/src/livecodes/i18n/locales/fa/translation.ts
@@ -1039,6 +1039,7 @@ const translation: I18nTranslation = {
'objc-wasm': 'شروع کننده Objective-C (Wasm)',
ocaml: 'شروع کننده Ocaml',
'ocaml-js': 'شروع کننده OCaml (JS)',
+ 'odin-wasm': 'شروع کننده Odin',
pascal: 'شروع کننده Pascal',
perl: 'شروع کننده Perl',
phaser: 'شروع کننده Phaser',
diff --git a/src/livecodes/i18n/locales/fr/language-info.lokalise.json b/src/livecodes/i18n/locales/fr/language-info.lokalise.json
index 8e19867a1..c3407ec73 100644
--- a/src/livecodes/i18n/locales/fr/language-info.lokalise.json
+++ b/src/livecodes/i18n/locales/fr/language-info.lokalise.json
@@ -648,6 +648,15 @@
"ocamlJs.name": {
"translation": "OCaml (JS)"
},
+ "odin-wasm.desc": {
+ "translation": "Le compilateur propre à Odin, compilé en WebAssembly, s'exécutant entièrement dans le navigateur."
+ },
+ "odin-wasm.link": {
+ "translation": " Site officiel d'Odin Présentation d'Odin API de la bibliothèque standard Apprenez X en Y minutes, où X = Odin Documentation LiveCodes Charger un modèle de démarrage "
+ },
+ "odin-wasm.name": {
+ "translation": "Odin (Wasm)"
+ },
"pascal.desc": {
"translation": "Pascal s'exécutant dans le navigateur en utilisant pas2js (par l'équipe Free Pascal), compilé en WebAssembly."
},
diff --git a/src/livecodes/i18n/locales/fr/language-info.ts b/src/livecodes/i18n/locales/fr/language-info.ts
index 305e41403..0188e651e 100644
--- a/src/livecodes/i18n/locales/fr/language-info.ts
+++ b/src/livecodes/i18n/locales/fr/language-info.ts
@@ -364,6 +364,11 @@ const languageInfo: I18nLangInfoTranslation = {
link: '<1><2>Site web OCaml2>1> <3> <4>Documentation OCaml4> 3> <5> <6>Apprenez X en Y minutes, où X=OCaml6> 5> <7> <8>Charger le modèle de démarrage8> 7>',
name: 'OCaml (JS)',
},
+ 'odin-wasm': {
+ desc: "Le compilateur propre à Odin, compilé en WebAssembly, s'exécutant entièrement dans le navigateur.",
+ link: "<1> <2>Site officiel d'Odin2> 1> <3> <4>Présentation d'Odin4> 3> <5> <6>API de la bibliothèque standard6> 5> <7> <8>Apprenez X en Y minutes, où X = Odin8> 7> <9> <10>Documentation LiveCodes10> 9> <11> <12>Charger un modèle de démarrage12> 11>",
+ name: 'Odin (Wasm)',
+ },
pascal: {
desc: "Pascal s'exécutant dans le navigateur en utilisant pas2js (par l'équipe Free Pascal), compilé en WebAssembly.",
link: '<1> <2>Site officiel de Free Pascal2> 1> <3> <4>Documentation pas2js4> 3> <5> <6>pas2js wiki6> 5> <7> <8>Documentations LiveCodes8> 7> <9> <10>Charger le modèle de démarrage10> 9>',
diff --git a/src/livecodes/i18n/locales/fr/translation.lokalise.json b/src/livecodes/i18n/locales/fr/translation.lokalise.json
index 8d389cfed..0de06d0a4 100644
--- a/src/livecodes/i18n/locales/fr/translation.lokalise.json
+++ b/src/livecodes/i18n/locales/fr/translation.lokalise.json
@@ -2100,6 +2100,9 @@
"templates.starter.ocaml-js": {
"translation": "Démarrage OCaml (JS)"
},
+ "templates.starter.odin-wasm": {
+ "translation": "Démarrage Odin"
+ },
"templates.starter.pascal": {
"translation": "Démarrage Pascal"
},
diff --git a/src/livecodes/i18n/locales/fr/translation.ts b/src/livecodes/i18n/locales/fr/translation.ts
index 5dd8217e0..8bdb62ac8 100644
--- a/src/livecodes/i18n/locales/fr/translation.ts
+++ b/src/livecodes/i18n/locales/fr/translation.ts
@@ -1040,6 +1040,7 @@ const translation: I18nTranslation = {
'objc-wasm': 'Démarrage Objective-C (Wasm)',
ocaml: 'Démarrage OCaml',
'ocaml-js': 'Démarrage OCaml (JS)',
+ 'odin-wasm': 'Démarrage Odin',
pascal: 'Démarrage Pascal',
perl: 'Démarrage Perl',
phaser: 'Démarrage Phaser',
diff --git a/src/livecodes/i18n/locales/hi/language-info.lokalise.json b/src/livecodes/i18n/locales/hi/language-info.lokalise.json
index 659b0f087..df92603af 100644
--- a/src/livecodes/i18n/locales/hi/language-info.lokalise.json
+++ b/src/livecodes/i18n/locales/hi/language-info.lokalise.json
@@ -648,6 +648,15 @@
"ocamlJs.name": {
"translation": "OCaml (JS)"
},
+ "odin-wasm.desc": {
+ "translation": "Odin का अपना कंपाइलर, WebAssembly में संकलित, पूरी तरह से ब्राउज़र में चलता है।"
+ },
+ "odin-wasm.link": {
+ "translation": " Odin आधिकारिक वेबसाइट Odin का अवलोकन मानक पुस्तकालय API Y मिनट में X सीखें, जहाँ X=Odin लाइवकोड दस्तावेजीकरण स्टार्टर टेम्पलेट लोड करें "
+ },
+ "odin-wasm.name": {
+ "translation": "Odin (Wasm)"
+ },
"pascal.desc": {
"translation": "Free Pascal टीम द्वारा pas2js का उपयोग करके ब्राउज़र में चलने वाला Pascal, जो WebAssembly में संकलित है।"
},
diff --git a/src/livecodes/i18n/locales/hi/language-info.ts b/src/livecodes/i18n/locales/hi/language-info.ts
index b86018be3..ea4a44ebd 100644
--- a/src/livecodes/i18n/locales/hi/language-info.ts
+++ b/src/livecodes/i18n/locales/hi/language-info.ts
@@ -364,6 +364,11 @@ const languageInfo: I18nLangInfoTranslation = {
link: '<1><2>OCaml वेबसाइट2>1> <3> <4>OCaml दस्तावेज़ीकरण4> 3> <5> <6>X को Y मिनटों में सीखें, जहां X=OCaml6> 5> <7> <8>स्टार्टर टेम्पलेट लोड करें8> 7>',
name: 'OCaml (JS)',
},
+ 'odin-wasm': {
+ desc: 'Odin का अपना कंपाइलर, WebAssembly में संकलित, पूरी तरह से ब्राउज़र में चलता है।',
+ link: '<1> <2>Odin आधिकारिक वेबसाइट2> 1> <3> <4>Odin का अवलोकन4> 3> <5> <6>मानक पुस्तकालय API6> 5> <7> <8>Y मिनट में X सीखें, जहाँ X=Odin8> 7> <9> <10>लाइवकोड दस्तावेजीकरण10> 9> <11> <12>स्टार्टर टेम्पलेट लोड करें12> 11>',
+ name: 'Odin (Wasm)',
+ },
pascal: {
desc: 'Free Pascal टीम द्वारा pas2js का उपयोग करके ब्राउज़र में चलने वाला Pascal, जो WebAssembly में संकलित है।',
link: '<1> <2>Free Pascal आधिकारिक वेबसाइट2> 1> <3> <4>pas2js दस्तावेज़ीकरण4> 3> <5> <6>pas2js wiki6> 5> <7> <8>लाइवकोड्स (LiveCodes) दस्तावेज़8> 7> <9> <10>स्टार्टर टेम्पलेट लोड करें10> 9>',
diff --git a/src/livecodes/i18n/locales/hi/translation.lokalise.json b/src/livecodes/i18n/locales/hi/translation.lokalise.json
index 8f97d032b..42dcf5ecf 100644
--- a/src/livecodes/i18n/locales/hi/translation.lokalise.json
+++ b/src/livecodes/i18n/locales/hi/translation.lokalise.json
@@ -2100,6 +2100,9 @@
"templates.starter.ocaml-js": {
"translation": "OCaml (JS) स्टार्टर"
},
+ "templates.starter.odin-wasm": {
+ "translation": "Odin स्टार्टर"
+ },
"templates.starter.pascal": {
"translation": "Pascal स्टार्टर"
},
diff --git a/src/livecodes/i18n/locales/hi/translation.ts b/src/livecodes/i18n/locales/hi/translation.ts
index 9c4acc8b7..187c47afb 100644
--- a/src/livecodes/i18n/locales/hi/translation.ts
+++ b/src/livecodes/i18n/locales/hi/translation.ts
@@ -1038,6 +1038,7 @@ const translation: I18nTranslation = {
'objc-wasm': 'Objective-C (Wasm) स्टार्टर',
ocaml: 'OCaml स्टार्टर',
'ocaml-js': 'OCaml (JS) स्टार्टर',
+ 'odin-wasm': 'Odin स्टार्टर',
pascal: 'Pascal स्टार्टर',
perl: 'Perl स्टार्टर',
phaser: 'Phaser स्टार्टर',
diff --git a/src/livecodes/i18n/locales/hu/language-info.lokalise.json b/src/livecodes/i18n/locales/hu/language-info.lokalise.json
index eb61d66ee..638fb71df 100644
--- a/src/livecodes/i18n/locales/hu/language-info.lokalise.json
+++ b/src/livecodes/i18n/locales/hu/language-info.lokalise.json
@@ -648,6 +648,15 @@
"ocamlJs.name": {
"translation": "OCaml (JS)"
},
+ "odin-wasm.desc": {
+ "translation": "Az Odin saját fordítója WebAssembly-re fordítva, teljes egészében a böngészőben fut."
+ },
+ "odin-wasm.link": {
+ "translation": " Az Odin hivatalos weboldala Az Odin áttekintése Standard könyvtár API Tanulj meg X-et Y perc alatt, ahol X=Odin LiveCodes dokumentáció Kezdő sablon betöltése "
+ },
+ "odin-wasm.name": {
+ "translation": "Odin (Wasm)"
+ },
"pascal.desc": {
"translation": "A Pascal a pas2js (a Free Pascal csapatától) segítségével fut a böngészőben, WebAssembly-re fordítva."
},
diff --git a/src/livecodes/i18n/locales/hu/language-info.ts b/src/livecodes/i18n/locales/hu/language-info.ts
index bb4cedb9a..2cae07146 100644
--- a/src/livecodes/i18n/locales/hu/language-info.ts
+++ b/src/livecodes/i18n/locales/hu/language-info.ts
@@ -363,6 +363,11 @@ const languageInfo: I18nLangInfoTranslation = {
link: '<1><2>OCaml weboldal2>1> <3> <4>OCaml dokumentáció4> 3> <5> <6>Tanulj X-et Y perc alatt, ahol X=OCaml6> 5> <7> <8>Kezdő sablon betöltése8> 7>',
name: 'OCaml (JS)',
},
+ 'odin-wasm': {
+ desc: 'Az Odin saját fordítója WebAssembly-re fordítva, teljes egészében a böngészőben fut.',
+ link: '<1> <2>Az Odin hivatalos weboldala2> 1> <3> <4>Az Odin áttekintése4> 3> <5> <6>Standard könyvtár API6> 5> <7> <8>Tanulj meg X-et Y perc alatt, ahol X=Odin8> 7> <9> <10>LiveCodes dokumentáció10> 9> <11> <12>Kezdő sablon betöltése12> 11>',
+ name: 'Odin (Wasm)',
+ },
pascal: {
desc: 'A Pascal a pas2js (a Free Pascal csapatától) segítségével fut a böngészőben, WebAssembly-re fordítva.',
link: '<1> <2>Free Pascal hivatalos weboldal2> 1> <3> <4>pas2js dokumentáció4> 3> <5> <6>pas2js wiki6> 5> <7> <8>LiveCodes dokumentációk8> 7> <9> <10>Kezdő sablon betöltése10> 9>',
diff --git a/src/livecodes/i18n/locales/hu/translation.lokalise.json b/src/livecodes/i18n/locales/hu/translation.lokalise.json
index 5635b2b28..ef317333c 100644
--- a/src/livecodes/i18n/locales/hu/translation.lokalise.json
+++ b/src/livecodes/i18n/locales/hu/translation.lokalise.json
@@ -2100,6 +2100,9 @@
"templates.starter.ocaml-js": {
"translation": "OCaml (JS) kezdő"
},
+ "templates.starter.odin-wasm": {
+ "translation": "Odin kezdő"
+ },
"templates.starter.pascal": {
"translation": "Pascal kezdő"
},
diff --git a/src/livecodes/i18n/locales/hu/translation.ts b/src/livecodes/i18n/locales/hu/translation.ts
index 3a0efce1a..7a4fe5e11 100644
--- a/src/livecodes/i18n/locales/hu/translation.ts
+++ b/src/livecodes/i18n/locales/hu/translation.ts
@@ -1039,6 +1039,7 @@ const translation: I18nTranslation = {
'objc-wasm': 'Objective-C (Wasm) kezdő',
ocaml: 'OCaml kezdő',
'ocaml-js': 'OCaml (JS) kezdő',
+ 'odin-wasm': 'Odin kezdő',
pascal: 'Pascal kezdő',
perl: 'Perl kezdő',
phaser: 'Phaser kezdő',
diff --git a/src/livecodes/i18n/locales/id/language-info.lokalise.json b/src/livecodes/i18n/locales/id/language-info.lokalise.json
index 6b2534e82..d4e26d041 100644
--- a/src/livecodes/i18n/locales/id/language-info.lokalise.json
+++ b/src/livecodes/i18n/locales/id/language-info.lokalise.json
@@ -648,6 +648,15 @@
"ocamlJs.name": {
"translation": "OCaml (JS)"
},
+ "odin-wasm.desc": {
+ "translation": "Kompiler milik Odin sendiri, dikompilasi ke WebAssembly, berjalan sepenuhnya di dalam browser."
+ },
+ "odin-wasm.link": {
+ "translation": " Situs web resmi Odin Ikhtisar Odin API pustaka standar Belajar X dalam Y menit, di mana X = Odin Dokumentasi LiveCodes Muat templat awal "
+ },
+ "odin-wasm.name": {
+ "translation": "Odin (Wasm)"
+ },
"pascal.desc": {
"translation": "Pascal berjalan di browser menggunakan pas2js (oleh tim Free Pascal), dikompilasi ke WebAssembly."
},
diff --git a/src/livecodes/i18n/locales/id/language-info.ts b/src/livecodes/i18n/locales/id/language-info.ts
index d5501b3d8..71e6c6a45 100644
--- a/src/livecodes/i18n/locales/id/language-info.ts
+++ b/src/livecodes/i18n/locales/id/language-info.ts
@@ -364,6 +364,11 @@ const languageInfo: I18nLangInfoTranslation = {
link: '<1><2>Situs web OCaml2>1> <3> <4>Dokumentasi OCaml4> 3> <5> <6>Pelajari X dalam Y menit, dengan X=OCaml6> 5> <7> <8>Muat template pemula8> 7>',
name: 'OCaml (JS)',
},
+ 'odin-wasm': {
+ desc: 'Kompiler milik Odin sendiri, dikompilasi ke WebAssembly, berjalan sepenuhnya di dalam browser.',
+ link: '<1> <2>Situs web resmi Odin2> 1> <3> <4>Ikhtisar Odin4> 3> <5> <6>API pustaka standar6> 5> <7> <8>Belajar X dalam Y menit, di mana X = Odin8> 7> <9> <10>Dokumentasi LiveCodes10> 9> <11> <12>Muat templat awal12> 11>',
+ name: 'Odin (Wasm)',
+ },
pascal: {
desc: 'Pascal berjalan di browser menggunakan pas2js (oleh tim Free Pascal), dikompilasi ke WebAssembly.',
link: '<1> <2>Situs web resmi Free Pascal2> 1> <3> <4>Dokumentasi pas2js4> 3> <5> <6>pas2js wiki6> 5> <7> <8>Dokumentasi LiveCodes8> 7> <9> <10>Muat template pemula10> 9>',
diff --git a/src/livecodes/i18n/locales/id/translation.lokalise.json b/src/livecodes/i18n/locales/id/translation.lokalise.json
index 8bd8ef106..e9b4412f5 100644
--- a/src/livecodes/i18n/locales/id/translation.lokalise.json
+++ b/src/livecodes/i18n/locales/id/translation.lokalise.json
@@ -2100,6 +2100,9 @@
"templates.starter.ocaml-js": {
"translation": "Pemula OCaml (JS)"
},
+ "templates.starter.odin-wasm": {
+ "translation": "Pemula Odin"
+ },
"templates.starter.pascal": {
"translation": "Pemula Pascal"
},
diff --git a/src/livecodes/i18n/locales/id/translation.ts b/src/livecodes/i18n/locales/id/translation.ts
index ceca4fe3e..389c4a34b 100644
--- a/src/livecodes/i18n/locales/id/translation.ts
+++ b/src/livecodes/i18n/locales/id/translation.ts
@@ -1038,6 +1038,7 @@ const translation: I18nTranslation = {
'objc-wasm': 'Pemula Objective-C (Wasm)',
ocaml: 'Pemula Ocaml',
'ocaml-js': 'Pemula OCaml (JS)',
+ 'odin-wasm': 'Pemula Odin',
pascal: 'Pemula Pascal',
perl: 'Pemula Perl',
phaser: 'Pemula Phaser',
diff --git a/src/livecodes/i18n/locales/it/language-info.lokalise.json b/src/livecodes/i18n/locales/it/language-info.lokalise.json
index 2fabcfaf9..b3261bb67 100644
--- a/src/livecodes/i18n/locales/it/language-info.lokalise.json
+++ b/src/livecodes/i18n/locales/it/language-info.lokalise.json
@@ -648,6 +648,15 @@
"ocamlJs.name": {
"translation": "OCaml (JS)"
},
+ "odin-wasm.desc": {
+ "translation": "Il compilatore proprio di Odin, compilato in WebAssembly, eseguito interamente nel browser."
+ },
+ "odin-wasm.link": {
+ "translation": " Sito web ufficiale di Odin Panoramica di Odin API della libreria standard Impara X in Y minuti, dove X = Odin Documentazione di LiveCodes Carica il modello di avvio "
+ },
+ "odin-wasm.name": {
+ "translation": "Odin (Wasm)"
+ },
"pascal.desc": {
"translation": "Pascal in esecuzione nel browser utilizzando pas2js (del team Free Pascal), compilato in WebAssembly."
},
diff --git a/src/livecodes/i18n/locales/it/language-info.ts b/src/livecodes/i18n/locales/it/language-info.ts
index b451da494..e7b6cfe1c 100644
--- a/src/livecodes/i18n/locales/it/language-info.ts
+++ b/src/livecodes/i18n/locales/it/language-info.ts
@@ -363,6 +363,11 @@ const languageInfo: I18nLangInfoTranslation = {
link: '<1><2>Sito web di OCaml2>1> <3> <4>Documentazione di OCaml4> 3> <5> <6>Impara X in Y minuti, dove X=OCaml6> 5> <7> <8>Carica modello di partenza8> 7>',
name: 'OCaml (JS)',
},
+ 'odin-wasm': {
+ desc: 'Il compilatore proprio di Odin, compilato in WebAssembly, eseguito interamente nel browser.',
+ link: '<1> <2>Sito web ufficiale di Odin2> 1> <3> <4>Panoramica di Odin4> 3> <5> <6>API della libreria standard6> 5> <7> <8>Impara X in Y minuti, dove X = Odin8> 7> <9> <10>Documentazione di LiveCodes10> 9> <11> <12>Carica il modello di avvio12> 11>',
+ name: 'Odin (Wasm)',
+ },
pascal: {
desc: 'Pascal in esecuzione nel browser utilizzando pas2js (del team Free Pascal), compilato in WebAssembly.',
link: '<1> <2>Sito ufficiale di Free Pascal2> 1> <3> <4>Documentazione di pas2js4> 3> <5> <6>pas2js wiki6> 5> <7> <8>Documentazione LiveCodes8> 7> <9> <10>Carica modello di partenza10> 9>',
diff --git a/src/livecodes/i18n/locales/it/translation.lokalise.json b/src/livecodes/i18n/locales/it/translation.lokalise.json
index a63c0094b..55c046d46 100644
--- a/src/livecodes/i18n/locales/it/translation.lokalise.json
+++ b/src/livecodes/i18n/locales/it/translation.lokalise.json
@@ -2100,6 +2100,9 @@
"templates.starter.ocaml-js": {
"translation": "Starter OCaml (JS)"
},
+ "templates.starter.odin-wasm": {
+ "translation": "Starter Odin"
+ },
"templates.starter.pascal": {
"translation": "Starter Pascal"
},
diff --git a/src/livecodes/i18n/locales/it/translation.ts b/src/livecodes/i18n/locales/it/translation.ts
index cd499d518..ab3ff2108 100644
--- a/src/livecodes/i18n/locales/it/translation.ts
+++ b/src/livecodes/i18n/locales/it/translation.ts
@@ -1039,6 +1039,7 @@ const translation: I18nTranslation = {
'objc-wasm': 'Starter Objective-C (Wasm)',
ocaml: 'Starter OCaml',
'ocaml-js': 'Starter OCaml (JS)',
+ 'odin-wasm': 'Starter Odin',
pascal: 'Starter Pascal',
perl: 'Starter Perl',
phaser: 'Starter Phaser',
diff --git a/src/livecodes/i18n/locales/ja/language-info.lokalise.json b/src/livecodes/i18n/locales/ja/language-info.lokalise.json
index 1290fff80..d019b7d5a 100644
--- a/src/livecodes/i18n/locales/ja/language-info.lokalise.json
+++ b/src/livecodes/i18n/locales/ja/language-info.lokalise.json
@@ -648,6 +648,15 @@
"ocamlJs.name": {
"translation": "OCaml (JS)"
},
+ "odin-wasm.desc": {
+ "translation": "Odin 自身のコンパイラを WebAssembly にコンパイルしたもので、ブラウザ内で完全に実行されます。"
+ },
+ "odin-wasm.link": {
+ "translation": " Odin 公式サイト Odin の概要 標準ライブラリ API 「Y分でXを学ぶ」(X=Odin) LiveCodes ドキュメント スターターテンプレートの読み込み "
+ },
+ "odin-wasm.name": {
+ "translation": "Odin (Wasm)"
+ },
"pascal.desc": {
"translation": "pas2js(Free Pascal チームによる)を使用してブラウザで動作する Pascal。WebAssembly にコンパイルされます。"
},
diff --git a/src/livecodes/i18n/locales/ja/language-info.ts b/src/livecodes/i18n/locales/ja/language-info.ts
index d7162414a..6898af047 100644
--- a/src/livecodes/i18n/locales/ja/language-info.ts
+++ b/src/livecodes/i18n/locales/ja/language-info.ts
@@ -364,6 +364,11 @@ const languageInfo: I18nLangInfoTranslation = {
link: '<1><2>OCaml ウェブサイト2>1> <3> <4>OCaml ドキュメント4> 3> <5> <6>X分でYを学ぶ、X=OCaml6> 5> <7> <8>スターターテンプレートを読み込む8> 7>',
name: 'OCaml (JS)',
},
+ 'odin-wasm': {
+ desc: 'Odin 自身のコンパイラを WebAssembly にコンパイルしたもので、ブラウザ内で完全に実行されます。',
+ link: '<1> <2>Odin 公式サイト2> 1> <3> <4>Odin の概要4> 3> <5> <6>標準ライブラリ API6> 5> <7> <8>「Y分でXを学ぶ」(X=Odin)8> 7> <9> <10>LiveCodes ドキュメント10> 9> <11> <12>スターターテンプレートの読み込み12> 11>',
+ name: 'Odin (Wasm)',
+ },
pascal: {
desc: 'pas2js(Free Pascal チームによる)を使用してブラウザで動作する Pascal。WebAssembly にコンパイルされます。',
link: '<1> <2>Free Pascal 公式ウェブサイト2> 1> <3> <4>pas2js ドキュメント4> 3> <5> <6>pas2js wiki6> 5> <7> <8>LiveCodes ドキュメント8> 7> <9> <10>スターターテンプレートを読み込む10> 9>',
diff --git a/src/livecodes/i18n/locales/ja/translation.lokalise.json b/src/livecodes/i18n/locales/ja/translation.lokalise.json
index 02cab7c9d..43d30d259 100644
--- a/src/livecodes/i18n/locales/ja/translation.lokalise.json
+++ b/src/livecodes/i18n/locales/ja/translation.lokalise.json
@@ -2100,6 +2100,9 @@
"templates.starter.ocaml-js": {
"translation": "OCaml(JS)スターター"
},
+ "templates.starter.odin-wasm": {
+ "translation": "Odin スターター"
+ },
"templates.starter.pascal": {
"translation": "Pascalスターター"
},
diff --git a/src/livecodes/i18n/locales/ja/translation.ts b/src/livecodes/i18n/locales/ja/translation.ts
index 54c2e4354..d0c93956f 100644
--- a/src/livecodes/i18n/locales/ja/translation.ts
+++ b/src/livecodes/i18n/locales/ja/translation.ts
@@ -1039,6 +1039,7 @@ const translation: I18nTranslation = {
'objc-wasm': 'Objective-C(Wasm)スターター',
ocaml: 'OCamlスターター',
'ocaml-js': 'OCaml(JS)スターター',
+ 'odin-wasm': 'Odin スターター',
pascal: 'Pascalスターター',
perl: 'Perlスターター',
phaser: 'Phaserスターター',
diff --git a/src/livecodes/i18n/locales/nl/language-info.lokalise.json b/src/livecodes/i18n/locales/nl/language-info.lokalise.json
index 23635c8f1..7b52c073a 100644
--- a/src/livecodes/i18n/locales/nl/language-info.lokalise.json
+++ b/src/livecodes/i18n/locales/nl/language-info.lokalise.json
@@ -648,6 +648,15 @@
"ocamlJs.name": {
"translation": "OCaml (JS)"
},
+ "odin-wasm.desc": {
+ "translation": "Odins eigen compiler, gecompileerd naar WebAssembly, draait volledig in de browser."
+ },
+ "odin-wasm.link": {
+ "translation": " Officiële website van Odin Overzicht van Odin API van de standaardbibliotheek Leer X in Y minuten, waarbij X = Odin LiveCodes-documentatie Startersjabloon laden "
+ },
+ "odin-wasm.name": {
+ "translation": "Odin (Wasm)"
+ },
"pascal.desc": {
"translation": "Pascal draaiend in de browser met pas2js (van het Free Pascal-team), gecompileerd naar WebAssembly."
},
diff --git a/src/livecodes/i18n/locales/nl/language-info.ts b/src/livecodes/i18n/locales/nl/language-info.ts
index 07f21b04f..e69826894 100644
--- a/src/livecodes/i18n/locales/nl/language-info.ts
+++ b/src/livecodes/i18n/locales/nl/language-info.ts
@@ -363,6 +363,11 @@ const languageInfo: I18nLangInfoTranslation = {
link: '<1><2>OCaml website2>1> <3> <4>OCaml documentatie4> 3> <5> <6>Leer X in Y minuten, waarbij X=OCaml6> 5> <7> <8>Startsjabloon laden8> 7>',
name: 'OCaml (JS)',
},
+ 'odin-wasm': {
+ desc: 'Odins eigen compiler, gecompileerd naar WebAssembly, draait volledig in de browser.',
+ link: '<1> <2>Officiële website van Odin2> 1> <3> <4>Overzicht van Odin4> 3> <5> <6>API van de standaardbibliotheek6> 5> <7> <8>Leer X in Y minuten, waarbij X = Odin8> 7> <9> <10>LiveCodes-documentatie10> 9> <11> <12>Startersjabloon laden12> 11>',
+ name: 'Odin (Wasm)',
+ },
pascal: {
desc: 'Pascal draaiend in de browser met pas2js (van het Free Pascal-team), gecompileerd naar WebAssembly.',
link: '<1> <2>Free Pascal officiële website2> 1> <3> <4>pas2js-documentatie4> 3> <5> <6>pas2js wiki6> 5> <7> <8>LiveCodes-documentatie8> 7> <9> <10>Startsjabloon laden10> 9>',
diff --git a/src/livecodes/i18n/locales/nl/translation.lokalise.json b/src/livecodes/i18n/locales/nl/translation.lokalise.json
index 0bb23e27c..6fd6c46be 100644
--- a/src/livecodes/i18n/locales/nl/translation.lokalise.json
+++ b/src/livecodes/i18n/locales/nl/translation.lokalise.json
@@ -2100,6 +2100,9 @@
"templates.starter.ocaml-js": {
"translation": "OCaml (JS)-starter"
},
+ "templates.starter.odin-wasm": {
+ "translation": "Odin-starter"
+ },
"templates.starter.pascal": {
"translation": "Pascal-starter"
},
diff --git a/src/livecodes/i18n/locales/nl/translation.ts b/src/livecodes/i18n/locales/nl/translation.ts
index d802e8809..63c5ec581 100644
--- a/src/livecodes/i18n/locales/nl/translation.ts
+++ b/src/livecodes/i18n/locales/nl/translation.ts
@@ -1039,6 +1039,7 @@ const translation: I18nTranslation = {
'objc-wasm': 'Objective-C (Wasm)-starter',
ocaml: 'Ocaml-starter',
'ocaml-js': 'OCaml (JS)-starter',
+ 'odin-wasm': 'Odin-starter',
pascal: 'Pascal-starter',
perl: 'Perl-starter',
phaser: 'Phaser-starter',
diff --git a/src/livecodes/i18n/locales/pt/language-info.lokalise.json b/src/livecodes/i18n/locales/pt/language-info.lokalise.json
index 229555b5c..762e0fe91 100644
--- a/src/livecodes/i18n/locales/pt/language-info.lokalise.json
+++ b/src/livecodes/i18n/locales/pt/language-info.lokalise.json
@@ -648,6 +648,15 @@
"ocamlJs.name": {
"translation": "OCaml (JS)"
},
+ "odin-wasm.desc": {
+ "translation": "O compilador próprio do Odin, compilado para WebAssembly, sendo executado na íntegra no navegador."
+ },
+ "odin-wasm.link": {
+ "translation": " Site oficial do Odin Visão geral do Odin API da biblioteca padrão Aprenda X em Y minutos, onde X = Odin Documentação do LiveCodes Carregar modelo inicial "
+ },
+ "odin-wasm.name": {
+ "translation": "Odin (Wasm)"
+ },
"pascal.desc": {
"translation": "Pascal rodando no navegador usando pas2js (pela equipe do Free Pascal), compilado para WebAssembly."
},
diff --git a/src/livecodes/i18n/locales/pt/language-info.ts b/src/livecodes/i18n/locales/pt/language-info.ts
index 88c90bdd6..16414ece9 100644
--- a/src/livecodes/i18n/locales/pt/language-info.ts
+++ b/src/livecodes/i18n/locales/pt/language-info.ts
@@ -363,6 +363,11 @@ const languageInfo: I18nLangInfoTranslation = {
link: '<1><2>Site do OCaml2>1> <3> <4>Documentação do OCaml4> 3> <5> <6>Aprenda X em Y minutos, onde X=OCaml6> 5> <7> <8>Carregar modelo inicial8> 7>',
name: 'OCaml (JS)',
},
+ 'odin-wasm': {
+ desc: 'O compilador próprio do Odin, compilado para WebAssembly, sendo executado na íntegra no navegador.',
+ link: '<1> <2>Site oficial do Odin2> 1> <3> <4>Visão geral do Odin4> 3> <5> <6>API da biblioteca padrão6> 5> <7> <8>Aprenda X em Y minutos, onde X = Odin8> 7> <9> <10>Documentação do LiveCodes10> 9> <11> <12>Carregar modelo inicial12> 11>',
+ name: 'Odin (Wasm)',
+ },
pascal: {
desc: 'Pascal rodando no navegador usando pas2js (pela equipe do Free Pascal), compilado para WebAssembly.',
link: '<1> <2>Site oficial do Free Pascal2> 1> <3> <4>Documentação do pas2js4> 3> <5> <6>pas2js wiki6> 5> <7> <8>Documentação do LiveCodes8> 7> <9> <10>Carregar modelo inicial10> 9>',
diff --git a/src/livecodes/i18n/locales/pt/translation.lokalise.json b/src/livecodes/i18n/locales/pt/translation.lokalise.json
index 2a4a6f1bd..6fd016435 100644
--- a/src/livecodes/i18n/locales/pt/translation.lokalise.json
+++ b/src/livecodes/i18n/locales/pt/translation.lokalise.json
@@ -2100,6 +2100,9 @@
"templates.starter.ocaml-js": {
"translation": "Iniciante OCaml (JS)"
},
+ "templates.starter.odin-wasm": {
+ "translation": "Iniciante Odin"
+ },
"templates.starter.pascal": {
"translation": "Iniciante Pascal"
},
diff --git a/src/livecodes/i18n/locales/pt/translation.ts b/src/livecodes/i18n/locales/pt/translation.ts
index 66bff1e29..4af81696f 100644
--- a/src/livecodes/i18n/locales/pt/translation.ts
+++ b/src/livecodes/i18n/locales/pt/translation.ts
@@ -1039,6 +1039,7 @@ const translation: I18nTranslation = {
'objc-wasm': 'Iniciante Objective-C (Wasm)',
ocaml: 'Iniciante OCaml',
'ocaml-js': 'Iniciante OCaml (JS)',
+ 'odin-wasm': 'Iniciante Odin',
pascal: 'Iniciante Pascal',
perl: 'Iniciante Perl',
phaser: 'Iniciante Phaser',
diff --git a/src/livecodes/i18n/locales/ru/language-info.lokalise.json b/src/livecodes/i18n/locales/ru/language-info.lokalise.json
index b4125d6be..7e12fdb87 100644
--- a/src/livecodes/i18n/locales/ru/language-info.lokalise.json
+++ b/src/livecodes/i18n/locales/ru/language-info.lokalise.json
@@ -648,6 +648,15 @@
"ocamlJs.name": {
"translation": "OCaml (JS)"
},
+ "odin-wasm.desc": {
+ "translation": "Собственный компилятор Odin, скомпилированный в WebAssembly, полностью выполняется в браузере."
+ },
+ "odin-wasm.link": {
+ "translation": " Официальный сайт Odin Обзор Odin API стандартной библиотеки «Изучите X за Y минут», где X = Odin Документация LiveCodes Загрузить стартовый шаблон "
+ },
+ "odin-wasm.name": {
+ "translation": "Odin (Wasm)"
+ },
"pascal.desc": {
"translation": "Pascal, работающий в браузере с использованием pas2js (от команды Free Pascal), скомпилирован в WebAssembly."
},
diff --git a/src/livecodes/i18n/locales/ru/language-info.ts b/src/livecodes/i18n/locales/ru/language-info.ts
index d22bc60a2..73a5ec60f 100644
--- a/src/livecodes/i18n/locales/ru/language-info.ts
+++ b/src/livecodes/i18n/locales/ru/language-info.ts
@@ -365,6 +365,11 @@ const languageInfo: I18nLangInfoTranslation = {
link: '<1><2>Сайт OCaml2>1> <3> <4>Документация OCaml4> 3> <5> <6>Изучите X за Y минут, где X=OCaml6> 5> <7> <8>Загрузить стартовый шаблон8> 7>',
name: 'OCaml (JS)',
},
+ 'odin-wasm': {
+ desc: 'Собственный компилятор Odin, скомпилированный в WebAssembly, полностью выполняется в браузере.',
+ link: '<1> <2>Официальный сайт Odin2> 1> <3> <4>Обзор Odin4> 3> <5> <6>API стандартной библиотеки6> 5> <7> <8>«Изучите X за Y минут», где X = Odin8> 7> <9> <10>Документация LiveCodes10> 9> <11> <12>Загрузить стартовый шаблон12> 11>',
+ name: 'Odin (Wasm)',
+ },
pascal: {
desc: 'Pascal, работающий в браузере с использованием pas2js (от команды Free Pascal), скомпилирован в WebAssembly.',
link: '<1> <2>Официальный сайт Free Pascal2> 1> <3> <4>Документация pas2js4> 3> <5> <6>pas2js wiki6> 5> <7> <8>Документация LiveCodes8> 7> <9> <10>Загрузить стартовый шаблон10> 9>',
diff --git a/src/livecodes/i18n/locales/ru/translation.lokalise.json b/src/livecodes/i18n/locales/ru/translation.lokalise.json
index 33358355e..b10f0e896 100644
--- a/src/livecodes/i18n/locales/ru/translation.lokalise.json
+++ b/src/livecodes/i18n/locales/ru/translation.lokalise.json
@@ -2100,6 +2100,9 @@
"templates.starter.ocaml-js": {
"translation": "Стартер OCaml (JS)"
},
+ "templates.starter.odin-wasm": {
+ "translation": "Стартер Odin"
+ },
"templates.starter.pascal": {
"translation": "Стартер Pascal"
},
diff --git a/src/livecodes/i18n/locales/ru/translation.ts b/src/livecodes/i18n/locales/ru/translation.ts
index b85d575c4..d9e2fa957 100644
--- a/src/livecodes/i18n/locales/ru/translation.ts
+++ b/src/livecodes/i18n/locales/ru/translation.ts
@@ -1038,6 +1038,7 @@ const translation: I18nTranslation = {
'objc-wasm': 'Стартер Objective-C (Wasm)',
ocaml: 'Стартер OCaml',
'ocaml-js': 'Стартер OCaml (JS)',
+ 'odin-wasm': 'Стартер Odin',
pascal: 'Стартер Pascal',
perl: 'Стартер Perl',
phaser: 'Стартер Phaser',
diff --git a/src/livecodes/i18n/locales/tr/language-info.lokalise.json b/src/livecodes/i18n/locales/tr/language-info.lokalise.json
index a5f57575d..07090356f 100644
--- a/src/livecodes/i18n/locales/tr/language-info.lokalise.json
+++ b/src/livecodes/i18n/locales/tr/language-info.lokalise.json
@@ -648,6 +648,15 @@
"ocamlJs.name": {
"translation": "OCaml (JS)"
},
+ "odin-wasm.desc": {
+ "translation": "Odin'in kendi derleyicisi, WebAssembly'ye derlenmiş, tamamen tarayıcı içinde çalışır."
+ },
+ "odin-wasm.link": {
+ "translation": " Odin resmi web sitesi Odin'e genel bakış Standart kütüphane API'si Y dakikada X'i öğrenin, burada X=Odin LiveCodes Belgeleri Başlangıç şablonunu yükle "
+ },
+ "odin-wasm.name": {
+ "translation": "Odin (Wasm)"
+ },
"pascal.desc": {
"translation": "Pascal, Free Pascal ekibi tarafından pas2js kullanılarak tarayıcıda çalışır ve WebAssembly'ye derlenir."
},
diff --git a/src/livecodes/i18n/locales/tr/language-info.ts b/src/livecodes/i18n/locales/tr/language-info.ts
index 732cb4871..78f819644 100644
--- a/src/livecodes/i18n/locales/tr/language-info.ts
+++ b/src/livecodes/i18n/locales/tr/language-info.ts
@@ -364,6 +364,11 @@ const languageInfo: I18nLangInfoTranslation = {
link: '<1><2>OCaml web sitesi2>1> <3> <4>OCaml dokümantasyonu4> 3> <5> <6>Y Dakikada X Öğrenin, X=OCaml6> 5> <7> <8>Başlangıç şablonunu yükle8> 7>',
name: 'OCaml (JS)',
},
+ 'odin-wasm': {
+ desc: "Odin'in kendi derleyicisi, WebAssembly'ye derlenmiş, tamamen tarayıcı içinde çalışır.",
+ link: "<1> <2>Odin resmi web sitesi2> 1> <3> <4>Odin'e genel bakış4> 3> <5> <6>Standart kütüphane API'si6> 5> <7> <8>Y dakikada X'i öğrenin, burada X=Odin8> 7> <9> <10>LiveCodes Belgeleri10> 9> <11> <12>Başlangıç şablonunu yükle12> 11>",
+ name: 'Odin (Wasm)',
+ },
pascal: {
desc: "Pascal, Free Pascal ekibi tarafından pas2js kullanılarak tarayıcıda çalışır ve WebAssembly'ye derlenir.",
link: '<1> <2>Free Pascal resmi web sitesi2> 1> <3> <4>pas2js dokümantasyonu4> 3> <5> <6>pas2js wiki6> 5> <7> <8>LiveCodes Belgeleri8> 7> <9> <10>Başlangıç şablonunu yükle10> 9>',
diff --git a/src/livecodes/i18n/locales/tr/translation.lokalise.json b/src/livecodes/i18n/locales/tr/translation.lokalise.json
index f4661766e..936ddad18 100644
--- a/src/livecodes/i18n/locales/tr/translation.lokalise.json
+++ b/src/livecodes/i18n/locales/tr/translation.lokalise.json
@@ -2100,6 +2100,9 @@
"templates.starter.ocaml-js": {
"translation": "OCaml (JS) Başlangıç"
},
+ "templates.starter.odin-wasm": {
+ "translation": "Odin Başlangıç"
+ },
"templates.starter.pascal": {
"translation": "Pascal Başlangıç"
},
diff --git a/src/livecodes/i18n/locales/tr/translation.ts b/src/livecodes/i18n/locales/tr/translation.ts
index c33e0c0cd..59f318593 100644
--- a/src/livecodes/i18n/locales/tr/translation.ts
+++ b/src/livecodes/i18n/locales/tr/translation.ts
@@ -1039,6 +1039,7 @@ const translation: I18nTranslation = {
'objc-wasm': 'Objective-C (Wasm) Başlangıç',
ocaml: 'Ocaml Başlangıç',
'ocaml-js': 'OCaml (JS) Başlangıç',
+ 'odin-wasm': 'Odin Başlangıç',
pascal: 'Pascal Başlangıç',
perl: 'Perl Başlangıç',
phaser: 'Phaser Başlangıç',
diff --git a/src/livecodes/i18n/locales/ur/language-info.lokalise.json b/src/livecodes/i18n/locales/ur/language-info.lokalise.json
index 11cee31c5..d87e16b28 100644
--- a/src/livecodes/i18n/locales/ur/language-info.lokalise.json
+++ b/src/livecodes/i18n/locales/ur/language-info.lokalise.json
@@ -648,6 +648,15 @@
"ocamlJs.name": {
"translation": "OCaml (JS)"
},
+ "odin-wasm.desc": {
+ "translation": "Odin کا اپنا کمپائلر، WebAssembly میں مرتب شدہ، مکمل طور پر براؤزر میں چلتا ہے۔"
+ },
+ "odin-wasm.link": {
+ "translation": " Odin آفیشل ویب سائٹ Odin کا جائزہ معیاری لائبریری API Y منٹ میں X سیکھیں، جہاں X=Odin LiveCodes دستاویزی لوڈ اسٹارٹر ٹیمپلیٹ "
+ },
+ "odin-wasm.name": {
+ "translation": "Odin (Wasm)"
+ },
"pascal.desc": {
"translation": "Free Pascal ٹیم کے pas2js کا استعمال کرتے ہوئے براؤزر میں چلنے والا Pascal، جو WebAssembly میں مرتب کیا گیا ہے۔"
},
diff --git a/src/livecodes/i18n/locales/ur/language-info.ts b/src/livecodes/i18n/locales/ur/language-info.ts
index 8ecd10f1f..1956682c8 100644
--- a/src/livecodes/i18n/locales/ur/language-info.ts
+++ b/src/livecodes/i18n/locales/ur/language-info.ts
@@ -365,6 +365,11 @@ const languageInfo: I18nLangInfoTranslation = {
link: '<1><2>او کیمل ویب سائٹ2>1> <3> <4>او کیمل دستاویزات4> 3> <5> <6>X کو Y منٹ میں سیکھیں، جہاں X=او کیمل6> 5> <7> <8>ابتدائی سانچہ لوڈ کریں8> 7>',
name: 'OCaml (JS)',
},
+ 'odin-wasm': {
+ desc: 'Odin کا اپنا کمپائلر، WebAssembly میں مرتب شدہ، مکمل طور پر براؤزر میں چلتا ہے۔',
+ link: '<1> <2>Odin آفیشل ویب سائٹ2> 1> <3> <4>Odin کا جائزہ4> 3> <5> <6>معیاری لائبریری API6> 5> <7> <8>Y منٹ میں X سیکھیں، جہاں X=Odin8> 7> <9> <10>LiveCodes دستاویزی10> 9> <11> <12>لوڈ اسٹارٹر ٹیمپلیٹ12> 11>',
+ name: 'Odin (Wasm)',
+ },
pascal: {
desc: 'Free Pascal ٹیم کے pas2js کا استعمال کرتے ہوئے براؤزر میں چلنے والا Pascal، جو WebAssembly میں مرتب کیا گیا ہے۔',
link: '<1> <2>Free Pascal کی سرکاری ویب سائٹ2> 1> <3> <4>pas2js دستاویزات4> 3> <5> <6>pas2js wiki6> 5> <7> <8>لائیو کوڈز دستاویزات8> 7> <9> <10>ابتدائی سانچہ لوڈ کریں10> 9>',
diff --git a/src/livecodes/i18n/locales/ur/translation.lokalise.json b/src/livecodes/i18n/locales/ur/translation.lokalise.json
index 4d466e54a..cb54f11c3 100644
--- a/src/livecodes/i18n/locales/ur/translation.lokalise.json
+++ b/src/livecodes/i18n/locales/ur/translation.lokalise.json
@@ -2100,6 +2100,9 @@
"templates.starter.ocaml-js": {
"translation": "OCaml (JS) شروعاتی"
},
+ "templates.starter.odin-wasm": {
+ "translation": "Odin شروعاتی"
+ },
"templates.starter.pascal": {
"translation": "پاسکل شروعاتی"
},
diff --git a/src/livecodes/i18n/locales/ur/translation.ts b/src/livecodes/i18n/locales/ur/translation.ts
index 88479ceb5..024962bf3 100644
--- a/src/livecodes/i18n/locales/ur/translation.ts
+++ b/src/livecodes/i18n/locales/ur/translation.ts
@@ -1038,6 +1038,7 @@ const translation: I18nTranslation = {
'objc-wasm': 'Objective-C (واسم) شروعاتی',
ocaml: 'اوکامل شروعاتی',
'ocaml-js': 'OCaml (JS) شروعاتی',
+ 'odin-wasm': 'Odin شروعاتی',
pascal: 'پاسکل شروعاتی',
perl: 'پرل شروعاتی',
phaser: 'فیزر شروعاتی',
diff --git a/src/livecodes/i18n/locales/zh-CN/language-info.lokalise.json b/src/livecodes/i18n/locales/zh-CN/language-info.lokalise.json
index d42dabcb5..0f9bc4fb8 100644
--- a/src/livecodes/i18n/locales/zh-CN/language-info.lokalise.json
+++ b/src/livecodes/i18n/locales/zh-CN/language-info.lokalise.json
@@ -648,6 +648,15 @@
"ocamlJs.name": {
"translation": "OCaml (JS)"
},
+ "odin-wasm.desc": {
+ "translation": "Odin 自带的编译器,编译为 WebAssembly,完全在浏览器中运行。"
+ },
+ "odin-wasm.link": {
+ "translation": " Odin 官方网站 Odin 概览 标准库 API 《Y分钟学会X》,其中X=Odin LiveCodes 文档 加载入门模板 "
+ },
+ "odin-wasm.name": {
+ "translation": "Odin (Wasm)"
+ },
"pascal.desc": {
"translation": "使用 Free Pascal 团队的 pas2js 在浏览器中运行的 Pascal,并编译为 WebAssembly。"
},
diff --git a/src/livecodes/i18n/locales/zh-CN/language-info.ts b/src/livecodes/i18n/locales/zh-CN/language-info.ts
index ef1434308..85524aa7b 100644
--- a/src/livecodes/i18n/locales/zh-CN/language-info.ts
+++ b/src/livecodes/i18n/locales/zh-CN/language-info.ts
@@ -356,6 +356,11 @@ const languageInfo: I18nLangInfoTranslation = {
link: '<1><2>OCaml 官方网站2>1> <3> <4>OCaml 文档4> 3> <5> <6>在 Y 分钟内学习 X,其中 X=OCaml6> 5> <7> <8>加载启动模板8> 7>',
name: 'OCaml (JS)',
},
+ 'odin-wasm': {
+ desc: 'Odin 自带的编译器,编译为 WebAssembly,完全在浏览器中运行。',
+ link: '<1> <2>Odin 官方网站2> 1> <3> <4>Odin 概览4> 3> <5> <6>标准库 API6> 5> <7> <8>《Y分钟学会X》,其中X=Odin8> 7> <9> <10>LiveCodes 文档10> 9> <11> <12>加载入门模板12> 11>',
+ name: 'Odin (Wasm)',
+ },
pascal: {
desc: '使用 Free Pascal 团队的 pas2js 在浏览器中运行的 Pascal,并编译为 WebAssembly。',
link: '<1> <2>Free Pascal 官网2> 1> <3> <4>pas2js 文档4> 3> <5> <6>pas2js wiki6> 5> <7> <8>LiveCodes 文档8> 7> <9> <10>加载启动模板10> 9>',
diff --git a/src/livecodes/i18n/locales/zh-CN/translation.lokalise.json b/src/livecodes/i18n/locales/zh-CN/translation.lokalise.json
index ed3cdfc3a..9ded55011 100644
--- a/src/livecodes/i18n/locales/zh-CN/translation.lokalise.json
+++ b/src/livecodes/i18n/locales/zh-CN/translation.lokalise.json
@@ -2100,6 +2100,9 @@
"templates.starter.ocaml-js": {
"translation": "OCaml(JS)启动模板"
},
+ "templates.starter.odin-wasm": {
+ "translation": "Odin 启动模板"
+ },
"templates.starter.pascal": {
"translation": "Pascal 启动模板"
},
diff --git a/src/livecodes/i18n/locales/zh-CN/translation.ts b/src/livecodes/i18n/locales/zh-CN/translation.ts
index 6566987f1..1d141f848 100644
--- a/src/livecodes/i18n/locales/zh-CN/translation.ts
+++ b/src/livecodes/i18n/locales/zh-CN/translation.ts
@@ -1036,6 +1036,7 @@ const translation: I18nTranslation = {
'objc-wasm': 'Objective-C(WASM)启动模板',
ocaml: 'Ocaml 启动模板',
'ocaml-js': 'OCaml(JS)启动模板',
+ 'odin-wasm': 'Odin 启动模板',
pascal: 'Pascal 启动模板',
perl: 'Perl 启动模板',
phaser: 'Phaser 启动模板',
diff --git a/src/livecodes/languages/languages.ts b/src/livecodes/languages/languages.ts
index 72b5ac0b3..3fdabafea 100644
--- a/src/livecodes/languages/languages.ts
+++ b/src/livecodes/languages/languages.ts
@@ -66,6 +66,7 @@ import { nim, nimWasm } from './nim';
import { nunjucks } from './nunjucks';
import { ocaml } from './ocaml';
import { ocamlJs } from './ocaml-js';
+import { odinWasm } from './odin-wasm';
import { pascal } from './pascal';
import { perl } from './perl';
import { php } from './php';
@@ -170,6 +171,7 @@ export const languages: LanguageSpecs[] = [
nim,
nimWasm,
crystalWasm,
+ odinWasm,
janetWasm,
python,
pythonWasm,
diff --git a/src/livecodes/languages/odin-wasm/__tests__/lang-odin-wasm.spec.ts b/src/livecodes/languages/odin-wasm/__tests__/lang-odin-wasm.spec.ts
new file mode 100644
index 000000000..b40408de7
--- /dev/null
+++ b/src/livecodes/languages/odin-wasm/__tests__/lang-odin-wasm.spec.ts
@@ -0,0 +1,38 @@
+import { odinWasm } from '../lang-odin-wasm';
+
+describe('Odin (Wasm) language spec', () => {
+ test('is registered as odin-wasm, with the wasm compiler script', () => {
+ expect(odinWasm.name).toBe('odin-wasm');
+ expect(odinWasm.title).toBe('Odin (Wasm)');
+ expect(odinWasm.compiler).toMatchObject({
+ scriptType: 'text/odin-wasm',
+ compiledCodeLanguage: 'odin-wasm',
+ liveReload: true,
+ });
+ });
+
+ test('accepts the Odin extension', () => {
+ expect(odinWasm.extensions).toEqual(expect.arrayContaining(['odin']));
+ });
+
+ test('warns that the first run is a large download', () => {
+ // The compiler and the standard library are ~6 MB compressed; the app shows a loading
+ // indicator while they arrive.
+ expect(odinWasm.largeDownload).toBe(true);
+ });
+
+ test('loads the compiler script the build produces', () => {
+ const compiler = odinWasm.compiler as unknown as {
+ scripts: (options: { baseUrl: string }) => string[];
+ };
+ expect(compiler.scripts({ baseUrl: '/' })).toEqual(['/{{hash:lang-odin-wasm-script.js}}']);
+ });
+
+ test('highlights with the Odin grammars', () => {
+ expect(odinWasm.editorSupport?.monaco).toMatchObject({ language: 'odin' });
+ expect(odinWasm.editorSupport?.codemirror).toMatchObject({
+ languageSupport: expect.any(Function),
+ });
+ expect(odinWasm.editorSupport?.codejar).toEqual({ language: 'odin' });
+ });
+});
diff --git a/src/livecodes/languages/odin-wasm/index.ts b/src/livecodes/languages/odin-wasm/index.ts
new file mode 100644
index 000000000..99354402b
--- /dev/null
+++ b/src/livecodes/languages/odin-wasm/index.ts
@@ -0,0 +1 @@
+export * from './lang-odin-wasm';
diff --git a/src/livecodes/languages/odin-wasm/lang-odin-wasm-script.ts b/src/livecodes/languages/odin-wasm/lang-odin-wasm-script.ts
new file mode 100644
index 000000000..11e54e344
--- /dev/null
+++ b/src/livecodes/languages/odin-wasm/lang-odin-wasm-script.ts
@@ -0,0 +1,368 @@
+/* eslint-disable no-console */
+import { getErrorMessage } from '../../utils/utils';
+import { odinWasmBaseUrl } from '../../vendors';
+import { createLoadingReporter, runCompiler } from '../wasm-runtime';
+import { createWorkerRunner, type Runner } from '../worker-runner';
+
+// Odin's compiler is a WASI command module, built by wodin — the fork of Odin with a direct
+// WebAssembly backend that emits wasm with no LLVM and no linker — and packaged with the standard
+// library. The package (`@live-codes/odin-wasm`) is fetched from the CDN.
+//
+// Where the *program* runs depends on the target it was built for:
+//
+// wasi_wasm32 (the default) a WASI host inside the package, in this worker — which is what makes
+// stdin, stdout, stderr and the exit code work.
+// js_wasm32 this page, on Odin's own JS runtime. A worker has no `document`, and
+// that runtime is written for the page, so a program that touches the
+// DOM or a canvas can only run here.
+
+const SCRIPT_TYPE = 'text/odin-wasm';
+const DEFAULT_TARGET = 'wasi_wasm32';
+
+// A single compile + run is normally quick; a long timeout guards against hangs (e.g. an infinite
+// loop in the user program) by killing and respawning the worker. The wasm call cannot be
+// interrupted any other way.
+const RUN_TIMEOUT_MS = 120000;
+
+/**
+ * Options read from `config.customSettings`: `compileArgs` and `target` are fixed when the compiler
+ * is created, while `args` is a per-run option.
+ */
+interface OdinWasmSettings {
+ compileArgs?: string[];
+ args?: string[];
+ target?: string;
+}
+
+interface RunResult {
+ input: string;
+ output: string | null;
+ error: string | null;
+ exitCode: number | null;
+}
+
+interface OdinWasmApi {
+ ready: boolean;
+ failed: boolean;
+ input: string;
+ output: string | null;
+ error: string | null;
+ exitCode: number | null;
+ loaded: Promise;
+ init: Promise | null;
+ runner?: Runner;
+ settings?: Record;
+ run: (input?: string) => Promise;
+}
+
+/** The compiled module, as a `js_wasm32` compile hands it back. */
+interface CompiledModule {
+ wasm?: ArrayBuffer | null;
+ errors?: string[];
+}
+
+declare const window: Window & {
+ livecodes: Record;
+};
+
+const getWorkerSrc = () => `
+importScripts(${JSON.stringify(odinWasmBaseUrl + 'dist/odin-wasm.global.js')});
+
+let compiler = null;
+let compilerOptions = null;
+
+const getCompiler = (options = {}) => {
+ const key = JSON.stringify([options.compileArgs, options.target]);
+ if (compiler && compilerOptions === key) return compiler;
+ compilerOptions = key;
+ const previous = compiler;
+ const created = (async () => {
+ const next = await self.odinWasm.createCompiler({
+ baseUrl: ${JSON.stringify(odinWasmBaseUrl + 'assets/')},
+ compileArgs: options.compileArgs || [],
+ target: options.target,
+ });
+ // \`compileArgs\` and \`target\` are fixed when a compiler is created, so a change builds a new
+ // one and lets the old go; its assets are the browser's cache to keep.
+ if (previous) previous.then((old) => old.dispose()).catch(() => undefined);
+ return next;
+ })();
+ created.catch(() => {
+ if (compiler === created) {
+ compiler = null;
+ compilerOptions = null;
+ }
+ });
+ compiler = created;
+ return compiler;
+};
+
+addEventListener('message', async (event) => {
+ const { id, code, input, options } = event.data;
+ try {
+ const compiler = await getCompiler(options);
+ // The js target is compiled here but run by the page, which is the only place with a DOM.
+ if (options && options.kind === 'compile') {
+ const compiled = await compiler.compile(code, options);
+ const bytes = compiled.wasm ? compiled.wasm.slice() : null;
+ postMessage(
+ { id, result: { wasm: bytes ? bytes.buffer : null, errors: compiled.errors } },
+ bytes ? [bytes.buffer] : [],
+ );
+ return;
+ }
+ const result = await compiler.run(code, input, { args: options && options.args });
+ postMessage({
+ id,
+ result: {
+ output: result.output,
+ // The compiler's diagnostics; empty when the program built.
+ errors: result.errors,
+ exitCode: result.exitCode,
+ },
+ });
+ } catch (error) {
+ postMessage({ id, error: String((error && error.message) || error) });
+ }
+});
+
+getCompiler().then(
+ () => postMessage({ type: 'ready' }),
+ (error) => postMessage({ type: 'error', message: String((error && error.message) || error) }),
+);
+`;
+
+const reportLoading = createLoadingReporter();
+
+/**
+ * Records a run and, unless the caller logs the output itself (the js target streams it), reports it.
+ */
+const report = (
+ input: string,
+ output: string | null,
+ error: string | null,
+ exitCode: number | null,
+ log = true,
+): RunResult => {
+ odinWasm.input = input;
+ odinWasm.output = output;
+ odinWasm.error = error;
+ odinWasm.exitCode = exitCode;
+ odinWasm.ready = true;
+
+ if (log) {
+ if (error != null) {
+ console.error(error);
+ } else if (output != null) {
+ console.log(output);
+ }
+ }
+ return { input, output, error, exitCode };
+};
+
+window.livecodes.odinWasm ??= {} as OdinWasmApi;
+
+const odinWasm = window.livecodes.odinWasm;
+odinWasm.ready = false;
+odinWasm.failed = false;
+
+/** The custom settings of the running language, injected by the language's `inlineScript`. */
+const getSettings = (): OdinWasmSettings => {
+ const settings = odinWasm.settings?.['odin-wasm'];
+ return settings != null && typeof settings === 'object' ? settings : {};
+};
+
+/** The program, which the result page writes inline as a `text/odin-wasm` script. */
+const getCode = () => {
+ let code = '';
+ document.querySelectorAll(`script[type="${SCRIPT_TYPE}"]`).forEach((script) => {
+ code += `${script.textContent ?? ''}\n`;
+ });
+ return code;
+};
+
+/** Start (once) downloading the compiler, showing the loading indicator while it happens. */
+const ensureLoaded = (runner: Runner): Promise => {
+ let init = odinWasm.init;
+ if (!init) {
+ odinWasm.failed = false;
+ init = (async () => {
+ reportLoading(true);
+ try {
+ await runner.ensureReady();
+ } finally {
+ reportLoading(false);
+ }
+ })().catch((error: Error) => {
+ // Reset so a later run can retry the download, and let `loaded` reject.
+ odinWasm.init = null;
+ odinWasm.failed = true;
+ throw error;
+ });
+ // The failure is surfaced through `run`; do not also report it unhandled.
+ init.catch(() => undefined);
+ odinWasm.init = init;
+ }
+ return init;
+};
+
+/** Odin's own JS runtime, loaded into this page once. */
+let odinRuntime: Promise | null = null;
+const loadOdinRuntime = (): Promise => {
+ if ((window as any).odin) return Promise.resolve((window as any).odin);
+ odinRuntime ??= new Promise((resolve, reject) => {
+ const script = document.createElement('script');
+ script.src = odinWasmBaseUrl + 'assets/odin.js';
+ script.onload = () => resolve((window as any).odin);
+ script.onerror = () => reject(new Error('Failed to load the Odin JS runtime (assets/odin.js)'));
+ document.head.appendChild(script);
+ });
+ // A failed load must not be cached, so a later run can retry it.
+ odinRuntime.catch(() => {
+ odinRuntime = null;
+ });
+ return odinRuntime;
+};
+
+/**
+ * Instantiate a `js_wasm32` module on this page with Odin's runtime, so the program reaches the DOM
+ * and a canvas. Output is streamed to the console as the program writes it; a program that exports
+ * `step` is driven once per animation frame, as Odin's own runtime does.
+ */
+const runModuleOnPage = async (wasm: Uint8Array, input: string): Promise => {
+ const odin = await loadOdinRuntime();
+ const memory = new odin.WasmMemoryInterface();
+ memory.setIntSize(4);
+ const imports = odin.setupDefaultImports(memory, null, memory.memory);
+
+ const inputBytes = new TextEncoder().encode(input);
+ let inputOffset = 0;
+ const output: string[] = [];
+
+ imports.odin_env.write = (fd: number, ptr: number, len: number) => {
+ const text = memory.loadString(ptr, len);
+ if (fd === 2) {
+ console.error(text);
+ } else {
+ output.push(text);
+ console.log(text);
+ }
+ };
+ imports.odin_env.read = (fd: number, ptr: number, len: number) => {
+ if (fd !== 0) return 0;
+ const count = Math.max(0, Math.min(len, inputBytes.length - inputOffset));
+ if (count > 0) {
+ new Uint8Array(memory.memory.buffer, ptr, count).set(
+ inputBytes.subarray(inputOffset, inputOffset + count),
+ );
+ inputOffset += count;
+ }
+ return count;
+ };
+
+ const { instance } = await WebAssembly.instantiate(wasm.slice(), imports);
+ const exports = instance.exports as Record;
+ memory.setExports(exports);
+ if (exports.memory) memory.setMemory(exports.memory);
+
+ /** Call one of the runtime's own entry points by name (`_start`, `_end`) when it is there. */
+ const call = (name: string) => {
+ const fn = exports[name];
+ return typeof fn === 'function' ? fn() : undefined;
+ };
+
+ const finish = (exitCode: number, error: string | null = null) =>
+ report(input, output.join(''), error, exitCode, /* log = */ false);
+
+ try {
+ call('_start');
+ } catch (error) {
+ return finish(1, `The program trapped: ${getErrorMessage(error)}`);
+ }
+
+ if (exports.step) {
+ // An interactive program: drive it once per frame, and let it keep writing to the console.
+ const context = exports.default_context_ptr ? exports.default_context_ptr() : 0;
+ let previous: number | undefined;
+ const frame = (timestamp: number) => {
+ if (previous === undefined) previous = timestamp;
+ const dt = (timestamp - previous) * 0.001;
+ previous = timestamp;
+ let keepGoing = false;
+ try {
+ keepGoing = exports.step(dt, context);
+ } catch (error) {
+ odinWasm.error = `The program trapped: ${getErrorMessage(error)}`;
+ console.error(odinWasm.error);
+ return;
+ }
+ if (!keepGoing) {
+ call('_end');
+ odinWasm.output = output.join('');
+ return;
+ }
+ requestAnimationFrame(frame);
+ };
+ requestAnimationFrame(frame);
+ return finish(0);
+ }
+
+ call('_end');
+ return finish(0);
+};
+
+/** Compile in the worker, then run the module here — the only place with a DOM. */
+const runOnPage = async (
+ code: string,
+ input: string,
+ settings: OdinWasmSettings,
+ runner: Runner,
+): Promise => {
+ try {
+ await ensureLoaded(runner);
+ const compiled = (await runner.run(code, '', {
+ ...settings,
+ kind: 'compile',
+ })) as unknown as CompiledModule;
+ if (!compiled?.wasm) {
+ return report(input, null, (compiled?.errors ?? ['Odin produced no module']).join('\n'), 1);
+ }
+ return await runModuleOnPage(new Uint8Array(compiled.wasm), input);
+ } catch (error) {
+ return report(input, null, `Error: ${getErrorMessage(error)}`, 1);
+ }
+};
+
+odinWasm.loaded = new Promise((resolve, reject) => {
+ const interval = setInterval(() => {
+ if (odinWasm.failed) {
+ clearInterval(interval);
+ reject(new Error(odinWasm.error || 'Failed to initialize the Odin compiler'));
+ } else if (odinWasm.ready) {
+ clearInterval(interval);
+ resolve();
+ }
+ }, 50);
+});
+
+odinWasm.run = async (input?: string) => {
+ const stdin = `${input ?? odinWasm.input ?? ''}`;
+ const code = getCode();
+ if (!code.trim()) return report(stdin, null, null, null);
+
+ const settings = getSettings();
+ const runner = (odinWasm.runner =
+ odinWasm.runner ||
+ createWorkerRunner({ getWorkerSrc, label: 'Odin', timeoutMs: RUN_TIMEOUT_MS }));
+
+ if ((settings.target ?? DEFAULT_TARGET) === 'js_wasm32') {
+ return runOnPage(code, stdin, settings, runner);
+ }
+ return runCompiler(runner, ensureLoaded, code, stdin, report, settings);
+};
+
+window.addEventListener('load', async () => {
+ reportLoading(true);
+ await odinWasm.run(odinWasm.input);
+ reportLoading(false);
+});
diff --git a/src/livecodes/languages/odin-wasm/lang-odin-wasm.ts b/src/livecodes/languages/odin-wasm/lang-odin-wasm.ts
new file mode 100644
index 000000000..c484638a5
--- /dev/null
+++ b/src/livecodes/languages/odin-wasm/lang-odin-wasm.ts
@@ -0,0 +1,36 @@
+import type { Config, LanguageSpecs } from '../../models';
+import { getLanguageCustomSettings } from '../../utils';
+import { codeMirrorBaseUrl, monacoLanguagesBaseUrl } from '../../vendors';
+
+const getSettingsScript = (config: Config) => {
+ const settings = getLanguageCustomSettings('odin-wasm', config);
+ // `\u003c` keeps a `` in a setting (e.g. a compile argument) from closing the tag.
+ const serialized = JSON.stringify(settings).replace(/ async (code) => code,
+ scripts: ({ baseUrl }) => [baseUrl + '{{hash:lang-odin-wasm-script.js}}'],
+ inlineScript: ({ config }) => getSettingsScript(config),
+ scriptType: 'text/odin-wasm',
+ compiledCodeLanguage: 'odin-wasm',
+ liveReload: true,
+ },
+ extensions: ['odin'],
+ editor: 'script',
+ editorSupport: {
+ monaco: { languageSupport: monacoLanguagesBaseUrl + 'odin.js', language: 'odin' },
+ codemirror: {
+ languageSupport: async () =>
+ (await import(codeMirrorBaseUrl + 'codemirror-lang-odin.js')).odin(),
+ },
+ codejar: { language: 'odin' },
+ },
+ largeDownload: true,
+};
diff --git a/src/livecodes/models.ts b/src/livecodes/models.ts
index d4e3ca09a..c34664f85 100644
--- a/src/livecodes/models.ts
+++ b/src/livecodes/models.ts
@@ -208,6 +208,7 @@ export interface Compiler {
| 'text/cobol-wasm'
| 'text/rust-wasm'
| 'text/crystal-wasm'
+ | 'text/odin-wasm'
| 'text/zig-wasm'
| 'text/java'
| 'text/csharp-wasm'
@@ -297,6 +298,7 @@ export type TemplateAlias =
| 'janet'
| 'mzn'
| 'crystal'
+ | 'odin'
| 'dartlang';
export type Template = Pick &
diff --git a/src/livecodes/templates/starter/index.ts b/src/livecodes/templates/starter/index.ts
index 4fc6bd22a..c23b07f6e 100644
--- a/src/livecodes/templates/starter/index.ts
+++ b/src/livecodes/templates/starter/index.ts
@@ -60,6 +60,7 @@ import { nimStarter } from './nim-starter';
import { nimWasmStarter } from './nim-wasm-starter';
import { ocamlJsStarter } from './ocaml-js-starter';
import { ocamlStarter } from './ocaml-starter';
+import { odinWasmStarter } from './odin-wasm-starter';
import { pascalStarter } from './pascal-starter';
import { perlStarter } from './perl-starter';
import { phaserStarter } from './phaser-starter';
@@ -140,6 +141,7 @@ export const starterTemplates = [
nimStarter,
nimWasmStarter,
crystalWasmStarter,
+ odinWasmStarter,
janetWasmStarter,
pythonStarter,
pythonWasmStarter,
diff --git a/src/livecodes/templates/starter/odin-wasm-starter.ts b/src/livecodes/templates/starter/odin-wasm-starter.ts
new file mode 100644
index 000000000..3ba169df3
--- /dev/null
+++ b/src/livecodes/templates/starter/odin-wasm-starter.ts
@@ -0,0 +1,110 @@
+import type { Template } from '../../models';
+
+export const odinWasmStarter: Template = {
+ name: 'odin-wasm',
+ aliases: ['odin'],
+ title: window.deps.translateString('templates.starter.odin-wasm', 'Odin Starter'),
+ thumbnail: 'assets/templates/odin.svg',
+ activeEditor: 'script',
+ markup: {
+ language: 'html',
+ content: `
+
+
Hello, World!
+

+
You clicked 0 times.
+
+
+
+
+`.trimStart(),
+ },
+ style: {
+ language: 'css',
+ content: `
+.container,
+.container button {
+ text-align: center;
+ font: 1em sans-serif;
+}
+.logo {
+ width: 150px;
+}
+`.trimStart(),
+ },
+ script: {
+ language: 'odin',
+ content: `
+package main
+
+import "core:bufio"
+import "core:fmt"
+import "core:os"
+import "core:strconv"
+import "core:strings"
+
+main :: proc() {
+ reader: bufio.Reader
+ bufio.reader_init(&reader, os.to_reader(os.stdin))
+ defer bufio.reader_destroy(&reader)
+
+ fmt.println("Odin")
+
+ count := -1
+ for {
+ line, err := bufio.reader_read_string(&reader, '\\n')
+ // The last line may have no trailing newline, and that comes back as an
+ // error together with the data — read the data first, then stop.
+ if len(line) == 0 {
+ break
+ }
+ if value, ok := strconv.parse_int(strings.trim_space(line)); ok {
+ count = value
+ }
+ if err != nil {
+ break
+ }
+ }
+ fmt.println(count + 1)
+}
+`.trimStart(),
+ },
+};
diff --git a/src/livecodes/vendors.ts b/src/livecodes/vendors.ts
index 2aa4ae923..0993e9886 100644
--- a/src/livecodes/vendors.ts
+++ b/src/livecodes/vendors.ts
@@ -64,7 +64,7 @@ export const cjs2esUrl = /* @__PURE__ */ getUrl('cjs2es@1.1.1/dist/cjs2es.browse
export const clangWasmBaseUrl = /* @__PURE__ */ getUrl('@live-codes/clang-wasm@0.3.0/');
-export const crystalWasmBaseUrl = /* @__PURE__ */ getUrl('@live-codes/crystal-wasm@0.2.0/');
+export const crystalWasmBaseUrl = /* @__PURE__ */ getUrl('@live-codes/crystal-wasm@0.3.0/');
export const clioBaseUrl = /* @__PURE__ */ getUrl(
'@live-codes/clio-browser-compiler@0.0.3/public/build/',
@@ -110,7 +110,7 @@ export const codeiumProviderUrl = /* @__PURE__ */ getUrl(
'@live-codes/monaco-codeium-provider@0.2.2/dist/index.js',
);
-export const codeMirrorBaseUrl = /* @__PURE__ */ getUrl('@live-codes/codemirror@0.4.5/build/');
+export const codeMirrorBaseUrl = /* @__PURE__ */ getUrl('@live-codes/codemirror@0.4.6/build/');
export const codemirrorMinimapUrl = /* @__PURE__ */ getUrl(
'@replit/codemirror-minimap@0.5.2/dist/index.js',
@@ -372,7 +372,7 @@ export const monacoBaseUrl = /* @__PURE__ */ getUrl('@live-codes/monaco-editor@0
export const monacoEmacsUrl = /* @__PURE__ */ getUrl('monaco-emacs@0.3.0/dist/monaco-emacs.js');
export const monacoLanguagesBaseUrl = /* @__PURE__ */ getUrl(
- '@live-codes/monaco-languages@0.3.13/dist/',
+ '@live-codes/monaco-languages@0.3.14/dist/',
);
export const monacoThemesBaseUrl = /* @__PURE__ */ getUrl('monaco-themes@0.4.4/themes/');
@@ -479,6 +479,8 @@ export const reasonStdLibBaseUrl = /* @__PURE__ */ getUrl('@rescript/std@9.1.3/l
export const ocamlJsBaseUrl = /* @__PURE__ */ getUrl('@live-codes/ocaml@0.2.0/');
+export const odinWasmBaseUrl = /* @__PURE__ */ getUrl('@live-codes/odin-wasm@0.2.0/');
+
export const rescriptCdnBaseUrl = /* @__PURE__ */ getUrl('https://cdn.rescript-lang.org/v11.1.2/');
export const rescriptStdLibBaseUrl = /* @__PURE__ */ getUrl('@rescript/std@11.1.2/lib/es6/');
diff --git a/src/sdk/models.ts b/src/sdk/models.ts
index 9b29b0bda..a9f49980a 100644
--- a/src/sdk/models.ts
+++ b/src/sdk/models.ts
@@ -323,6 +323,8 @@ export type Language =
| 'cr'
| 'crystal'
| 'crystal-wasm'
+ | 'odin'
+ | 'odin-wasm'
| 'nim'
| 'nims'
| 'nimble'
@@ -530,6 +532,7 @@ export type TemplateName =
| 'fortran-wasm'
| 'd-wasm'
| 'crystal-wasm'
+ | 'odin-wasm'
| 'cobol-wasm'
| 'v-wasm'
| 'java'
diff --git a/storybook/_stories/EmbedOptions/template.ts b/storybook/_stories/EmbedOptions/template.ts
index 12d299bfc..59fbed84e 100644
--- a/storybook/_stories/EmbedOptions/template.ts
+++ b/storybook/_stories/EmbedOptions/template.ts
@@ -55,6 +55,7 @@ const storyDef: StoryDef = {
CWasm: { props: { template: 'c-wasm' } },
CppWasm: { props: { template: 'cpp-wasm' } },
CrystalWasm: { props: { template: 'crystal-wasm' }, storyName: 'Crystal (Wasm)' },
+ OdinWasm: { props: { template: 'odin-wasm' }, storyName: 'Odin (Wasm)' },
ObjcWasm: { props: { template: 'objc-wasm' } },
DWasm: { props: { template: 'd-wasm' } },
CobolWasm: { props: { template: 'cobol-wasm' }, storyName: 'COBOL (Wasm)' },
diff --git a/storybook/preact/stories/EmbedOptions/template.stories.ts b/storybook/preact/stories/EmbedOptions/template.stories.ts
index a0136e2ac..138f6369a 100644
--- a/storybook/preact/stories/EmbedOptions/template.stories.ts
+++ b/storybook/preact/stories/EmbedOptions/template.stories.ts
@@ -69,6 +69,8 @@ export const CWasm = livecodesStory({ template: 'c-wasm' });
export const CppWasm = livecodesStory({ template: 'cpp-wasm' });
export const CrystalWasm = livecodesStory({ template: 'crystal-wasm' });
CrystalWasm.storyName = 'Crystal (Wasm)';
+export const OdinWasm = livecodesStory({ template: 'odin-wasm' });
+OdinWasm.storyName = 'Odin (Wasm)';
export const ObjcWasm = livecodesStory({ template: 'objc-wasm' });
export const DWasm = livecodesStory({ template: 'd-wasm' });
export const CobolWasm = livecodesStory({ template: 'cobol-wasm' });
diff --git a/storybook/react/stories/EmbedOptions/template.stories.ts b/storybook/react/stories/EmbedOptions/template.stories.ts
index a0136e2ac..138f6369a 100644
--- a/storybook/react/stories/EmbedOptions/template.stories.ts
+++ b/storybook/react/stories/EmbedOptions/template.stories.ts
@@ -69,6 +69,8 @@ export const CWasm = livecodesStory({ template: 'c-wasm' });
export const CppWasm = livecodesStory({ template: 'cpp-wasm' });
export const CrystalWasm = livecodesStory({ template: 'crystal-wasm' });
CrystalWasm.storyName = 'Crystal (Wasm)';
+export const OdinWasm = livecodesStory({ template: 'odin-wasm' });
+OdinWasm.storyName = 'Odin (Wasm)';
export const ObjcWasm = livecodesStory({ template: 'objc-wasm' });
export const DWasm = livecodesStory({ template: 'd-wasm' });
export const CobolWasm = livecodesStory({ template: 'cobol-wasm' });
diff --git a/storybook/solid/stories/EmbedOptions/template.stories.ts b/storybook/solid/stories/EmbedOptions/template.stories.ts
index a0136e2ac..138f6369a 100644
--- a/storybook/solid/stories/EmbedOptions/template.stories.ts
+++ b/storybook/solid/stories/EmbedOptions/template.stories.ts
@@ -69,6 +69,8 @@ export const CWasm = livecodesStory({ template: 'c-wasm' });
export const CppWasm = livecodesStory({ template: 'cpp-wasm' });
export const CrystalWasm = livecodesStory({ template: 'crystal-wasm' });
CrystalWasm.storyName = 'Crystal (Wasm)';
+export const OdinWasm = livecodesStory({ template: 'odin-wasm' });
+OdinWasm.storyName = 'Odin (Wasm)';
export const ObjcWasm = livecodesStory({ template: 'objc-wasm' });
export const DWasm = livecodesStory({ template: 'd-wasm' });
export const CobolWasm = livecodesStory({ template: 'cobol-wasm' });
diff --git a/storybook/svelte/stories/EmbedOptions/template.stories.ts b/storybook/svelte/stories/EmbedOptions/template.stories.ts
index a0136e2ac..138f6369a 100644
--- a/storybook/svelte/stories/EmbedOptions/template.stories.ts
+++ b/storybook/svelte/stories/EmbedOptions/template.stories.ts
@@ -69,6 +69,8 @@ export const CWasm = livecodesStory({ template: 'c-wasm' });
export const CppWasm = livecodesStory({ template: 'cpp-wasm' });
export const CrystalWasm = livecodesStory({ template: 'crystal-wasm' });
CrystalWasm.storyName = 'Crystal (Wasm)';
+export const OdinWasm = livecodesStory({ template: 'odin-wasm' });
+OdinWasm.storyName = 'Odin (Wasm)';
export const ObjcWasm = livecodesStory({ template: 'objc-wasm' });
export const DWasm = livecodesStory({ template: 'd-wasm' });
export const CobolWasm = livecodesStory({ template: 'cobol-wasm' });
diff --git a/storybook/vue/stories/EmbedOptions/template.stories.ts b/storybook/vue/stories/EmbedOptions/template.stories.ts
index a0136e2ac..138f6369a 100644
--- a/storybook/vue/stories/EmbedOptions/template.stories.ts
+++ b/storybook/vue/stories/EmbedOptions/template.stories.ts
@@ -69,6 +69,8 @@ export const CWasm = livecodesStory({ template: 'c-wasm' });
export const CppWasm = livecodesStory({ template: 'cpp-wasm' });
export const CrystalWasm = livecodesStory({ template: 'crystal-wasm' });
CrystalWasm.storyName = 'Crystal (Wasm)';
+export const OdinWasm = livecodesStory({ template: 'odin-wasm' });
+OdinWasm.storyName = 'Odin (Wasm)';
export const ObjcWasm = livecodesStory({ template: 'objc-wasm' });
export const DWasm = livecodesStory({ template: 'd-wasm' });
export const CobolWasm = livecodesStory({ template: 'cobol-wasm' });
diff --git a/storybook/web-components/stories/EmbedOptions/template.stories.ts b/storybook/web-components/stories/EmbedOptions/template.stories.ts
index a0136e2ac..138f6369a 100644
--- a/storybook/web-components/stories/EmbedOptions/template.stories.ts
+++ b/storybook/web-components/stories/EmbedOptions/template.stories.ts
@@ -69,6 +69,8 @@ export const CWasm = livecodesStory({ template: 'c-wasm' });
export const CppWasm = livecodesStory({ template: 'cpp-wasm' });
export const CrystalWasm = livecodesStory({ template: 'crystal-wasm' });
CrystalWasm.storyName = 'Crystal (Wasm)';
+export const OdinWasm = livecodesStory({ template: 'odin-wasm' });
+OdinWasm.storyName = 'Odin (Wasm)';
export const ObjcWasm = livecodesStory({ template: 'objc-wasm' });
export const DWasm = livecodesStory({ template: 'd-wasm' });
export const CobolWasm = livecodesStory({ template: 'cobol-wasm' });
diff --git a/vendor-licenses.md b/vendor-licenses.md
index a7841eded..856b4f70d 100644
--- a/vendor-licenses.md
+++ b/vendor-licenses.md
@@ -360,6 +360,8 @@ wacl: [BSD 3-Clause License](https://github.com/ecky-l/wacl/blob/9daacabb0102a99
Crystal compiler and standard library: [Apache-2.0 License](https://github.com/crystal-lang/crystal/blob/master/LICENSE)
+Odin compiler and standard library: [zlib License](https://github.com/odin-lang/Odin/blob/e87445a582ba74f526670ed94d68d9be95de2f8b/LICENSE)
+
LLVM and the wasm sysroot libraries: [Apache-2.0 WITH LLVM-exception](https://github.com/llvm/llvm-project/blob/main/LICENSE.TXT) and [MIT](https://github.com/WebAssembly/wasi-libc/blob/main/LICENSE.md)
@live-codes/dlang-wasm: [MIT License](https://github.com/live-codes/browser-d/blob/main/LICENSE)