1010 < meta name ="robots " content ="index, follow ">
1111 < link rel ="canonical " href ="https://subs.js.org/ass-subset/ ">
1212 < link rel ="alternate " hreflang ="en " href ="https://subs.js.org/ass-subset/ ">
13- < link rel ="alternate " hreflang ="zh-CN " href ="https://subs.js.org/ass-subset/?lang=zh ">
13+ < link rel ="alternate " hreflang ="zh-CN " href ="https://subs.js.org/ass-subset/?lang=zh-CN ">
1414 < link rel ="alternate " hreflang ="zh-TW " href ="https://subs.js.org/ass-subset/?lang=zh-TW ">
1515 < link rel ="alternate " hreflang ="ja " href ="https://subs.js.org/ass-subset/?lang=ja ">
1616 < link rel ="alternate " hreflang ="ko " href ="https://subs.js.org/ass-subset/?lang=ko ">
2121 < link rel ="alternate " hreflang ="ar " href ="https://subs.js.org/ass-subset/?lang=ar ">
2222 < link rel ="alternate " hreflang ="x-default " href ="https://subs.js.org/ass-subset/ ">
2323 < link rel ="icon " type ="image/jpeg " href ="icons/icon-256.png ">
24- < meta name ="version " content ="2.4.19 ">
24+ < meta name ="version " content ="2.5 ">
2525 < meta property ="og:type " content ="website ">
2626 < meta property ="og:title " content ="ASS Subsetter· MontageSubs ">
2727 < meta property ="og:description " content ="Optimize ASS/SSA subtitle files with intelligent font subsetting and drawing command compression. Embed fonts with zero file bloat. Browser-based, free, open-source. ">
@@ -1342,7 +1342,7 @@ <h1 class="brand-title" data-i18n="app.title">ASS Subsetter</h1>
13421342 aria-label ="Switch language " aria-haspopup ="menu " aria-expanded ="false "> A/文</ button >
13431343 < div class ="lang-menu " id ="lang-menu " role ="menu ">
13441344 < button onclick ="setLang('ar') " id ="lang-ar " role ="menuitem "> Arabic · العربية</ button >
1345- < button onclick ="setLang('zh') " id ="lang-zh " class ="active " role ="menuitem "> Chinese Simplified · 简体中文</ button >
1345+ < button onclick ="setLang('zh-CN ') " id ="lang-zh-CN " class ="active " role ="menuitem "> Chinese Simplified · 简体中文</ button >
13461346 < button onclick ="setLang('zh-TW') " id ="lang-zh-TW " role ="menuitem "> Chinese Traditional · 繁體中文</ button >
13471347 < button onclick ="setLang('en') " id ="lang-en " role ="menuitem "> English</ button >
13481348 < button onclick ="setLang('ja') " id ="lang-ja " role ="menuitem "> Japanese · 日本語</ button >
@@ -1547,7 +1547,7 @@ <h3 id="preview-title" data-i18n="preview.title">Font Preview / Download</h3>
15471547 'use strict' ;
15481548
15491549 const I18N = {
1550- zh : {
1550+ 'zh-CN' : {
15511551 'analysis.draw.label' : '绘图指令(\\p1)' ,
15521552 'analysis.draw.none' : '未发现绘图指令' ,
15531553 'analysis.draw.status.existing' : '已子集化 {count} 个形状,当前无新绘图' ,
@@ -2871,28 +2871,46 @@ <h3 id="preview-title" data-i18n="preview.title">Font Preview / Download</h3>
28712871
28722872 function normFont ( name ) { return name . replace ( / ^ @ / , '' ) . trim ( ) ; }
28732873
2874- let currentLang = 'zh ' ;
2874+ let currentLang = 'en ' ;
28752875 ( function ( ) {
2876+ function normalizeLang ( raw ) {
2877+ const s = ( raw || '' ) . toLowerCase ( ) . trim ( ) ;
2878+ if ( ! s ) return null ;
2879+ if ( s . startsWith ( 'zh-tw' ) ) return 'zh-TW' ;
2880+ if ( s . startsWith ( 'zh-hk' ) || s . startsWith ( 'zh-mo' ) ) return 'zh-TW' ;
2881+ if ( s . startsWith ( 'zh' ) ) return 'zh-CN' ;
2882+ if ( s . startsWith ( 'en' ) ) return 'en' ;
2883+ if ( s . startsWith ( 'ja' ) ) return 'ja' ;
2884+ if ( s . startsWith ( 'ko' ) ) return 'ko' ;
2885+ if ( s . startsWith ( 'ar' ) ) return 'ar' ;
2886+ if ( s . startsWith ( 'ru' ) ) return 'ru' ;
2887+ if ( s . startsWith ( 'tr' ) ) return 'tr' ;
2888+ if ( s . startsWith ( 'pt' ) ) return 'pt-BR' ;
2889+ if ( s . startsWith ( 'es' ) ) return 'es' ;
2890+ return null ;
2891+ }
2892+ const VALID = { 'ar' :1 , 'zh-CN' :1 , 'zh-TW' :1 , 'en' :1 , 'ja' :1 , 'ko' :1 , 'pt-BR' :1 , 'ru' :1 , 'es' :1 , 'tr' :1 } ;
2893+ try {
2894+ const urlLang = new URLSearchParams ( window . location . search ) . get ( 'lang' ) ;
2895+ if ( urlLang ) {
2896+ const norm = normalizeLang ( urlLang ) ;
2897+ if ( norm && VALID [ norm ] ) {
2898+ currentLang = norm ;
2899+ try { localStorage . setItem ( 'ass-subset-lang' , norm ) ; } catch ( _ ) { }
2900+ return ;
2901+ }
2902+ }
2903+ } catch ( _ ) { }
28762904 try {
28772905 const saved = localStorage . getItem ( 'ass-subset-lang' ) ;
2878- if ( saved && I18N [ saved ] ) { currentLang = saved ; return ; }
2906+ if ( saved && VALID [ saved ] ) { currentLang = saved ; return ; }
28792907 } catch ( _ ) { }
28802908 const nav = ( navigator . language || '' ) . toLowerCase ( ) ;
2881- if ( nav . startsWith ( 'zh-tw' ) || nav . startsWith ( 'zh-hk' ) || nav . startsWith ( 'zh-mo' ) ) currentLang = 'zh-TW' ;
2882- else if ( nav . startsWith ( 'zh' ) ) currentLang = 'zh' ;
2883- else if ( nav . startsWith ( 'en' ) ) currentLang = 'en' ;
2884- else if ( nav . startsWith ( 'ja' ) ) currentLang = 'ja' ;
2885- else if ( nav . startsWith ( 'ko' ) ) currentLang = 'ko' ;
2886- else if ( nav . startsWith ( 'ar' ) ) currentLang = 'ar' ;
2887- else if ( nav . startsWith ( 'ru' ) ) currentLang = 'ru' ;
2888- else if ( nav . startsWith ( 'tr' ) ) currentLang = 'tr' ;
2889- else if ( nav . startsWith ( 'pt' ) ) currentLang = 'pt-BR' ;
2890- else if ( nav . startsWith ( 'es' ) ) currentLang = 'es' ;
2891- else currentLang = 'en' ;
2909+ currentLang = normalizeLang ( nav ) || 'en' ;
28922910 } ) ( ) ;
28932911
28942912 function t ( key , params ) {
2895- let str = ( I18N [ currentLang ] && I18N [ currentLang ] [ key ] ) || I18N . zh [ key ] || key ;
2913+ let str = ( I18N [ currentLang ] && I18N [ currentLang ] [ key ] ) || I18N . en [ key ] || key ;
28962914 if ( params ) {
28972915 for ( const [ k , v ] of Object . entries ( params ) ) str = str . replace ( new RegExp ( '\\{' + k + '\\}' , 'g' ) , v ) ;
28982916 }
@@ -2913,9 +2931,9 @@ <h3 id="preview-title" data-i18n="preview.title">Font Preview / Download</h3>
29132931 el . setAttribute ( 'aria-label' , t ( el . getAttribute ( 'data-i18n-aria' ) ) ) ;
29142932 } ) ;
29152933
2916- const langAttrMap = { zh : 'zh-CN' , 'zh-TW' : 'zh-TW' , en : 'en-US ' , ja : 'ja' , ko : 'ko' , ar : 'ar' , ru : 'ru' , tr : 'tr' , 'pt-BR' : 'pt-BR' , es : 'es-419 ' } ;
2934+ const langAttrMap = { 'zh-CN' : 'zh-CN' , 'zh-TW' : 'zh-TW' , en : 'en' , ja : 'ja' , ko : 'ko' , ar : 'ar' , ru : 'ru' , tr : 'tr' , 'pt-BR' : 'pt-BR' , es : 'es' } ;
29172935 document . documentElement . lang = langAttrMap [ currentLang ] || currentLang ;
2918- [ 'zh' , 'zh-TW' , 'en' , 'ja' , 'ko' , 'ar' , 'pt-BR' , 'ru' , 'es' , 'tr' ] . forEach ( l => {
2936+ [ 'zh-CN ' , 'zh-TW' , 'en' , 'ja' , 'ko' , 'ar' , 'pt-BR' , 'ru' , 'es' , 'tr' ] . forEach ( l => {
29192937 document . getElementById ( 'lang-' + l ) ?. classList . toggle ( 'active' , currentLang === l ) ;
29202938 } ) ;
29212939
@@ -2926,7 +2944,10 @@ <h3 id="preview-title" data-i18n="preview.title">Font Preview / Download</h3>
29262944 document . querySelector ( 'meta[property="og:title"]' ) ?. setAttribute ( 'content' , title ) ;
29272945 document . querySelector ( 'meta[property="og:description"]' ) ?. setAttribute ( 'content' , t ( 'app.subtitle' ) ) ;
29282946 const manifest = document . getElementById ( 'pwa-manifest' ) ;
2929- if ( manifest ) manifest . setAttribute ( 'href' , currentLang === 'zh' ? 'manifest.json' : 'manifest-en.json' ) ;
2947+ if ( manifest ) {
2948+ const mLangs = { 'zh-CN' :'manifest-zh-CN.json' , 'zh-TW' :'manifest-zh-TW.json' , 'ja' :'manifest-ja.json' , 'ko' :'manifest-ko.json' , 'es' :'manifest-es.json' , 'pt-BR' :'manifest-pt-BR.json' , 'ru' :'manifest-ru.json' , 'ar' :'manifest-ar.json' , 'tr' :'manifest-tr.json' } ;
2949+ manifest . setAttribute ( 'href' , mLangs [ currentLang ] || 'manifest.json' ) ;
2950+ }
29302951
29312952 const v = document . querySelector ( 'meta[name="version"]' ) ;
29322953 const verEl = document . getElementById ( 'ver' ) ;
@@ -4712,8 +4733,8 @@ <h3 id="preview-title" data-i18n="preview.title">Font Preview / Download</h3>
47124733 script . setAttribute ( 'data-reactions-enabled' , '0' ) ;
47134734 script . setAttribute ( 'data-emit-metadata' , '0' ) ;
47144735 script . setAttribute ( 'data-theme' , theme ) ;
4715- const langMap = { 'ar' : 'ar' , 'zh' : 'zh-CN' , 'zh-TW' : 'zh-TW' , 'en' : 'en' , 'ja' : 'ja' , 'ko' : 'ko' , 'pt-BR' : 'pt-BR' , 'ru' : 'ru' , 'es' : 'es' , 'tr' : 'tr' } ;
4716- script . setAttribute ( 'data-lang' , langMap [ currentLang ] || 'zh-CN ' ) ;
4736+ const langMap = { 'ar' : 'ar' , 'zh-CN ' : 'zh-CN' , 'zh-TW' : 'zh-TW' , 'en' : 'en' , 'ja' : 'ja' , 'ko' : 'ko' , 'pt-BR' : 'pt-BR' , 'ru' : 'ru' , 'es' : 'es' , 'tr' : 'tr' } ;
4737+ script . setAttribute ( 'data-lang' , langMap [ currentLang ] || 'en ' ) ;
47174738 script . crossOrigin = 'anonymous' ;
47184739 script . async = true ;
47194740 script . onload = ( ) => { const el = document . getElementById ( 'discuss-loading' ) ; if ( el ) el . remove ( ) ; } ;
0 commit comments