diff --git a/js/dist/admin.js b/js/dist/admin.js index 8c9b565..06abe72 100644 --- a/js/dist/admin.js +++ b/js/dist/admin.js @@ -1,2 +1,2 @@ -(()=>{var t={n:n=>{var i=n&&n.__esModule?()=>n.default:()=>n;return t.d(i,{a:i}),i},d:(n,i)=>{for(var e in i)t.o(i,e)&&!t.o(n,e)&&Object.defineProperty(n,e,{enumerable:!0,get:i[e]})},o:(t,n)=>Object.prototype.hasOwnProperty.call(t,n),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},n={};(()=>{"use strict";t.r(n),t.d(n,{components:()=>J,models:()=>Q,pages:()=>V,utils:()=>X});const i=flarum.core.compat["admin/app"];var e=t.n(i);function o(t,n){return o=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,n){return t.__proto__=n,t},o(t,n)}function a(t,n){t.prototype=Object.create(n.prototype),t.prototype.constructor=t,o(t,n)}const s=flarum.core.compat["common/Model"];var r=t.n(s),l=function(t){function n(){for(var n,i=arguments.length,e=new Array(i),o=0;o";function C(t,n){if(!n)return t;var i=n.toLowerCase(),e=new RegExp(i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"i");return t.replace(e,P+"$&"+P).split(P).map((function(t){return t.toLowerCase()===i?m("span.FoF-Linguist-Highlight",t):t}))}var S=function(){function t(){}var n=t.prototype;return n.oninit=function(t){var n=this;this.stringKey=t.attrs.stringKey,this.locale=t.attrs.locale,this.localeKey=this.locale?this.locale.key:null,this.originalString=this.localeKey&&this.stringKey.locales().hasOwnProperty(this.localeKey)?this.stringKey.locales()[this.localeKey]:null,this.string=e().store.all("fof-linguist-string").find((function(t){return t.key()===n.stringKey.key()&&t.locale()===n.localeKey})),this.value=this.string?this.string.value():"",this.dirty=!1,this.processing=!1;var i=Object.keys(this.stringKey.locales()).some((function(t){return-1!==n.stringKey.locales()[t].indexOf("\n")}));this.inputType="input",(i||-1!==this.value.indexOf("\n"))&&(this.inputType="textarea")},n.view=function(t){var n=this,i=this.originalString?this.originalString:"("+e().translator.trans("fof-linguist.admin.placeholder."+(this.localeKey?"not-translated":"all-locales"))+")";return m(".FoF-Linguist-Locale",[m("label.FoF-Linguist-Label",this.localeName()),m(".FoF-Linguist-Field",{className:(this.value?"FoF-Linguist-Field--with-value":"")+(this.originalString?" FoF-Linguist-Field--with-original-string":""),title:i},[m(".FoF-Linguist-Field-Wrap",[m(this.inputType,{className:"FormControl FoF-Linguist-Input",value:this.value,oninput:function(t){n.value=t.target.value,n.dirty=!0,n.value||n.string||(n.dirty=!1)},disabled:this.processing}),m(".FoF-Linguist-Placeholder",[m("span.FoF-Linguist-Placeholder-Hint",e().translator.trans("fof-linguist.admin.placeholder.hint"))," ",m("span",this.originalString?C(i,t.attrs.highlight):i)])])]),m(".FoF-Linguist-Controls",this.actions(t.attrs.onchange).toArray())])},n.localeName=function(){return this.locale?[this.locale.name+" (",m("code",this.locale.key),")"]:e().translator.trans("fof-linguist.admin.locales.all")},n.actions=function(t){var n=this,i=new(N());return i.add("apply",d().component({type:"button",className:"Button Button--primary",loading:this.processing,disabled:!this.dirty,onclick:function(){n.saveString(t)}},e().translator.trans("fof-linguist.admin.buttons.apply"))),i.add("reset",d().component({type:"button",className:"Button",loading:this.processing,disabled:!this.dirty&&!this.string,onclick:function(){n.deleteString(t)}},e().translator.trans("fof-linguist.admin.buttons.reset"))),this.originalString&&i.add("copy-original",d().component({type:"button",className:"Button",loading:this.processing,onclick:function(){n.value=n.originalString,n.dirty=!0}},e().translator.trans("fof-linguist.admin.buttons.copy-original"))),i},n.saveString=function(t){var n=this;this.value?(this.string||(this.string=e().store.createRecord("fof-linguist-string",{attributes:{key:this.stringKey.key(),locale:this.localeKey,value:""}})),this.string.data.attributes.value=this.value,this.string.locale()||delete this.string.data.attributes.locale,this.processing=!0,this.string.save(this.string.data.attributes).then((function(){n.processing=!1,n.dirty=!1,t(),m.redraw()})).catch((function(t){throw n.processing=!1,t}))):this.deleteString(t)},n.deleteString=function(t){var n=this;this.string?(this.processing=!0,this.string.delete().then((function(){n.processing=!1,n.dirty=!1,n.string=null,n.value="",t(),m.redraw()})).catch((function(t){throw n.processing=!1,t}))):(this.value="",this.dirty=!1)},t}(),I=function(){function t(){}return t.prototype.view=function(t){var n=t.attrs,i=n.stringKey,e=n.highlight,o=n.onchange;return m(".FoF-Linguist-Key",[m(".FoF-Linguist-Key-Code",m("code",C(i.key(),e))),m(".FoF-Linguist-Locales",[].concat(B().map((function(t){return m(S,{key:t.key,locale:t,stringKey:i,highlight:e,onchange:o})})),[m(S,{key:"all",locale:null,stringKey:i,highlight:e,onchange:o})]))])},t}();function _(t){return e().translator.translations["fof-linguist.admin.known-namespace."+t]||t}function K(t){return e().translator.translations["fof-linguist.admin.known-frontend."+t]||t}function A(t,n){return n.reduce((function(n,i){return"start"===n?i:"or"===t?n||i:n&&i}),"start")}var j=function(){function t(){}var n=t.prototype;return n.oninit=function(t){this.numberOfResultsToShow=20,this.filters=Object.assign({search:"",withOwnTranslations:!1,missingTranslationsNegation:"without",missingTranslationsType:"any",missingTranslationsOperation:"or",missingTranslationsInLocales:[],forExtension:null,frontend:null},t.attrs.initialBrowseFilters||{}),this.results=[],this.applyFilters()},n.view=function(t){var n=this,i=this.results.slice(0,this.numberOfResultsToShow);return[m("div",this.cacheClearInstructions()),m(".FoF-Linguist-Filters",[m("input.FormControl",{value:this.filters.search,oninput:function(t){n.filters.search=t.target.value,n.applyFilters()},placeholder:e().translator.trans("fof-linguist.admin.filters.search")}),d().component({className:"Button"+(this.filters.withOwnTranslations?" FoF-Linguist-Filter--Selected":""),icon:"far fa-"+(this.filters.withOwnTranslations?"check-square":"square"),onclick:function(){n.filters.withOwnTranslations=!n.filters.withOwnTranslations,n.applyFilters()}},e().translator.trans("fof-linguist.admin.filters.with-own-translations")),v().component({buttonClassName:"Button"+(this.filters.forExtension?" FoF-Linguist-Filter--Selected":""),label:e().translator.trans("fof-linguist.admin.filters.for-extension")},t.attrs.namespaces.map((function(t){return d().component({className:"Button",icon:"far fa-"+(n.filters.forExtension===t.namespace?"dot-circle":"circle"),onclick:function(){n.filters.forExtension===t.namespace?n.filters.forExtension=null:n.filters.forExtension=t.namespace,n.applyFilters()}},t.extension?t.extension.extra["flarum-extension"].title:_(t.namespace))}))),v().component({buttonClassName:"Button"+(this.filters.frontend?" FoF-Linguist-Filter--Selected":""),label:e().translator.trans("fof-linguist.admin.filters.frontend")},["_all_except_admin"].concat(t.attrs.frontends).map((function(t){return d().component({className:"Button",icon:"far fa-"+(n.filters.frontend===t?"dot-circle":"circle"),onclick:function(){n.filters.frontend===t?n.filters.frontend=null:n.filters.frontend=t,n.applyFilters()}},"_all_except_admin"===t?e().translator.trans("fof-linguist.admin.filters.frontend-all-except-admin"):K(t))}))),v().component({buttonClassName:"Button"+(this.filters.missingTranslationsInLocales.length?" FoF-Linguist-Filter--Selected":""),label:e().translator.trans("fof-linguist.admin.filters.missing")},[m(".FoF-Linguist-Missing-Filter",{onclick:function(t){t.stopPropagation()}},[x().component({value:this.filters.missingTranslationsNegation,onchange:function(t){n.filters.missingTranslationsNegation=t,n.filters.missingTranslationsInLocales.length&&n.applyFilters()},options:{without:e().translator.trans("fof-linguist.admin.filters.negation-options.without"),with:e().translator.trans("fof-linguist.admin.filters.negation-options.with")}}),x().component({value:this.filters.missingTranslationsType,onchange:function(t){n.filters.missingTranslationsType=t,n.filters.missingTranslationsInLocales.length&&n.applyFilters()},options:{any:e().translator.trans("fof-linguist.admin.filters.type-options.any"),original:e().translator.trans("fof-linguist.admin.filters.type-options.original"),own:e().translator.trans("fof-linguist.admin.filters.type-options.own")}}),m("p",e().translator.trans("fof-linguist.admin.filters.missing-middle-label")),x().component({value:this.filters.missingTranslationsOperation,onchange:function(t){n.filters.missingTranslationsOperation=t,n.filters.missingTranslationsInLocales.length&&n.applyFilters()},options:{or:e().translator.trans("fof-linguist.admin.filters.operation-options.or"),and:e().translator.trans("fof-linguist.admin.filters.operation-options.and")}})])].concat(B().map((function(t){return d().component({className:"Button",icon:"far fa-"+(-1!==n.filters.missingTranslationsInLocales.indexOf(t.key)?"check-square":"square"),onclick:function(){-1!==n.filters.missingTranslationsInLocales.indexOf(t.key)?n.filters.missingTranslationsInLocales=n.filters.missingTranslationsInLocales.filter((function(n){return n!==t.key})):n.filters.missingTranslationsInLocales.push(t.key),n.applyFilters()}},t.name+" ("+t.key+")")})))),v().component({buttonClassName:"Button",label:e().translator.trans("fof-linguist.admin.filters.mass-edit")},[d().component({icon:"far fa-clone",className:"Button",onclick:function(){var t=e().store.all("fof-linguist-string").filter((function(t){var n=e().store.getById("fof-linguist-string-key",t.key());return n&&n.locales()[t.locale()]===t.value()}));if(confirm(O()(e().translator.trans("fof-linguist.admin.buttons.delete-redundant-confirm",{count:t.length+""})))){if(0===t.length)return;e().modal.show(L()),Promise.all(t.map((function(t){return t.delete()}))).then((function(){window.location.reload()}))}}},e().translator.trans("fof-linguist.admin.buttons.delete-redundant")),d().component({icon:"fas fa-trash",className:"Button",onclick:function(){var t=e().store.all("fof-linguist-string");if(confirm(O()(e().translator.trans("fof-linguist.admin.buttons.delete-all-confirm",{count:t.length+""})))){if(0===t.length)return;e().modal.show(L()),Promise.all(t.map((function(t){return t.delete()}))).then((function(){window.location.reload()}))}}},e().translator.trans("fof-linguist.admin.buttons.delete-all"))])]),m("div",i.map((function(t){return m(I,{key:t.id(),stringKey:t,highlight:n.filters.search,onchange:function(){e().data.settings["fof.linguist.should-clear-cache"]="1"}})}))),m(".FoF-Linguist-Results",[e().translator.trans("fof-linguist.admin.filters.results",{shown:i.length+"",total:this.results.length+""})," ",this.results.length>i.length?d().component({className:"Button",onclick:function(){n.numberOfResultsToShow+=20}},e().translator.trans("fof-linguist.admin.buttons.load-more")):null])]},n.applyFilters=function(){var t=this;this.numberOfResultsToShow=20;var n=e().store.all("fof-linguist-string").map((function(t){return t.key()})),i={};B().forEach((function(t){i[t.key]=e().store.all("fof-linguist-string").filter((function(n){return n.locale()===t.key})).map((function(t){return t.key()}))}));var o="";this.filters.search&&(o=this.filters.search.toLowerCase()),this.results=e().store.all("fof-linguist-string-key").filter((function(e){if(t.filters.withOwnTranslations&&-1===n.indexOf(e.key()))return!1;if(t.filters.missingTranslationsInLocales.length){var a=t.filters.missingTranslationsOperation;"without"===t.filters.missingTranslationsNegation&&(a="or"===a?"and":"or");var s=A(a,t.filters.missingTranslationsInLocales.map((function(t){return e.locales().hasOwnProperty(t)}))),r=A(a,t.filters.missingTranslationsInLocales.map((function(t){return-1!==i[t].indexOf(e.key())}))),l=!1;switch(t.filters.missingTranslationsType){case"any":l=s||r;break;case"original":l=s;break;case"own":l=r}if("without"===t.filters.missingTranslationsNegation&&(l=!l),!l)return!1}if(t.filters.forExtension&&0!==e.key().indexOf(t.filters.forExtension+"."))return!1;if(t.filters.frontend){var c=e.key().split(".");if("_all_except_admin"===t.filters.frontend){if(c.length>=2&&"admin"===c[1])return!1}else if(c.length<2||c[1]!==t.filters.frontend)return!1}if(o){if(-1!==e.key().toLowerCase().indexOf(o))return!0;var u=e.locales();for(var f in u)if(u.hasOwnProperty(f)&&-1!==u[f].toLowerCase().indexOf(o))return!0;return!1}return!0})),m.redraw()},n.cacheClearInstructions=function(){return e().data.debugEnabled||"1"!==e().data.settings["fof.linguist.should-clear-cache"]?null:b().component({dismissible:!1,controls:[d().component({className:"Button Button--link",onclick:function(){e().modal.show(L()),e().request({method:"DELETE",url:e().forum.attribute("apiUrl")+"/cache"}).then((function(){return window.location.reload()}))}},e().translator.trans("fof-linguist.admin.clear-cache.button"))]},e().translator.trans("fof-linguist.admin.clear-cache.text"))},t}();const M=flarum.core.compat["common/helpers/icon"];var q=t.n(M),U=function(){function t(){}var n=t.prototype;return n.oninit=function(){this.columns="locale",this.showAllFrontends=!1,this.totalPercent=!0,this.locale=[];var t=B().find((function(t){return"en"!==t.key}));t&&(this.locale=t.key)},n.view=function(t){var n=this,i=t.attrs.frontends.slice(0,2);this.showAllFrontends&&(i=t.attrs.frontends);var o=t.attrs.browseWithFilters;return[m(".FoF-Linguist-Filters",[m(".ButtonGroup",[d().component({className:"Button"+(this.totalPercent?" active":""),onclick:function(){n.totalPercent=!0}},e().translator.trans("fof-linguist.admin.coverage.total-options.percent")),d().component({className:"Button"+(this.totalPercent?" ":" active"),onclick:function(){n.totalPercent=!1}},e().translator.trans("fof-linguist.admin.coverage.total-options.count"))]),m(".ButtonGroup",[d().component({className:"Button"+("locale"===this.columns?" active":""),onclick:function(){n.columns="locale"}},e().translator.trans("fof-linguist.admin.coverage.column-options.locale")),d().component({className:"Button"+("namespace"===this.columns?" active":""),onclick:function(){n.columns="namespace",n.showAllFrontends=!1}},e().translator.trans("fof-linguist.admin.coverage.column-options.namespace"))]),"namespace"===this.columns?m(".ButtonGroup",B().map((function(t){return d().component({className:"Button"+(n.locale===t.key?" active":""),onclick:function(){n.locale!==t.key&&(n.locale=t.key)}},t.name+" ("+t.key+")")}))):null]),m("table.FoF-Linguist-Coverage",[m("thead",m("tr",[m("th",e().translator.trans("fof-linguist.admin.coverage.columns.namespace")),"locale"===this.columns?B().map((function(t){return m("th",t.name+" ("+t.key+")")})):[this.showAllFrontends?i.map((function(t){return m("th",K(t))})):[m("th",e().translator.trans("fof-linguist.admin.coverage.columns.all-except-admin")),m("th",K("admin")),m("th",d().component({className:"Button",onclick:function(){n.showAllFrontends=!0}},e().translator.trans("fof-linguist.admin.coverage.columns.all-frontends")))]]])),m("tbody",["locale"===this.columns?m("tr",[m("td",[m("span.FoF-Linguist-Coverage-Extension-Icon.FoF-Linguist-Coverage-Namespace-Icon"),m("span.FoF-Linguist-Coverage-Extension-Title",e().translator.trans("fof-linguist.admin.coverage.all-namespaces"))]),B().map((function(t){return m("td",n.localeCoverage(o,t.key))}))]):null,t.attrs.namespaces.map((function(t){return m("tr",[m("td",t.extension?[m("span.FoF-Linguist-Coverage-Extension-Icon",{style:t.extension.icon},t.extension.icon?q()(t.extension.icon.name):""),m("span.FoF-Linguist-Coverage-Extension-Title",t.extension.extra["flarum-extension"].title)]:[m("span.FoF-Linguist-Coverage-Extension-Icon.FoF-Linguist-Coverage-Namespace-Icon"),m("span.FoF-Linguist-Coverage-Extension-Title",_(t.namespace))]),"locale"===n.columns?B().map((function(i){return m("td",n.localeCoverage(o,i.key,t.namespace))})):[n.showAllFrontends?i.map((function(i){return m("td",n.prefixCoverage(o,t.namespace,i))})):[m("td",n.prefixCoverage(o,t.namespace,"_all_except_admin")),m("td",n.prefixCoverage(o,t.namespace,"admin"))]]])}))])])]},n.prefixCoverage=function(t,n,i){return this.locale?this.localeCoverage(t,this.locale,n,i):null},n.localeCoverage=function(t,n,i,o){var a=e().store.all("fof-linguist-string-key").filter((function(t){if(!i)return!0;var n=t.key().split(".");if(n[0]!==i)return!1;if("_all_except_admin"===o){if(n.length>=2&&"admin"===n[1])return!1}else if(o&&(n.length<2||n[1]!==o))return!1;return!0}));if(0===a.length)return"-";var s=0,r=0;a.forEach((function(t){e().store.all("fof-linguist-string").find((function(i){return i.key()===t.key()&&i.locale()===n}))?s++:t.locales().hasOwnProperty(n)&&r++}));var l,c,u=Math.round((s+r)/a.length*100);return 100===u?l="full":u<5&&(l="low"),c=this.totalPercent?e().translator.trans("fof-linguist.admin.coverage.count.percent",{percent:u+""}):e().translator.trans("fof-linguist.admin.coverage.count.total",{translated:s+r+"",total:a.length}),m(".FoF-Linguist-Coverage-Progress-Wrap",[m(".FoF-Linguist-Progress",{className:l?"FoF-Linguist-Progress--"+l:""},[m(".FoF-Linguist-Progress-Bar",{style:{width:Math.max(u,5)+"%"}}),m(".FoF-Linguist-Progress-Label",c),m(".FoF-Linguist-Progress-More",e().translator.trans("fof-linguist.admin.coverage.count.details",{total:a.length,original:r+"",custom:s+""}))]),d().component({icon:"fas fa-filter",className:"Button Button--icon",onclick:function(){var e={missingTranslationsInLocales:[n]};i&&(e.forExtension=i),o&&(e.frontend=o),t(e)},title:e().translator.trans("fof-linguist.admin.coverage.apply-missing-filter")})])},t}();const R=flarum.core.compat["common/components/Switch"];var G=t.n(R);const W=flarum.core.compat["common/components/LinkButton"];var D=t.n(W),$=function(){function t(){}var n=t.prototype;return n.oninit=function(){this.locale="en",this.namespace=null,this.includeOriginals=!1,this.includeAll=!1,this.loading=!1,this.output="",this.fetchOutput()},n.view=function(t){var n=this,i={};B().forEach((function(t){i[t.key]=t.name+" ("+t.key+")"})),i.all=e().translator.trans("fof-linguist.admin.export.locale-all");var o={_all:e().translator.trans("fof-linguist.admin.export.namespace-all")};return t.attrs.namespaces.forEach((function(t){t.extension?o[t.namespace]=t.extension.extra["flarum-extension"].title:o[t.namespace]=_(t.namespace)})),[m("h2",e().translator.trans("fof-linguist.admin.export.title")),m(".Form-group",m(".Alert",e().translator.trans("fof-linguist.admin.export.warning"))),m(".Form-group",[m("label",e().translator.trans("fof-linguist.admin.export.locale")),x().component({options:i,value:this.locale,onchange:function(t){n.locale=t,n.fetchOutput()}})]),m(".Form-group",[m("label",e().translator.trans("fof-linguist.admin.export.namespace")),x().component({options:o,value:null===this.namespace?"_all":this.namespace,onchange:function(t){n.namespace="_all"===t?null:t,n.fetchOutput()}})]),m(".Form-group",[G().component({state:this.includeOriginals,onchange:function(t){n.includeOriginals=t,n.fetchOutput()}},e().translator.trans("fof-linguist.admin.export.include-originals"))]),m(".Form-group",[G().component({state:this.includeAll,onchange:function(t){n.includeAll=t,n.fetchOutput()}},e().translator.trans("fof-linguist.admin.export.include-all"))]),m(".Form-group",[m("label",[e().translator.trans("fof-linguist.admin.export.output")," ",D().component({className:"Button Button--primary",href:this.exportUrl(),external:!0,download:(this.namespace||this.locale)+".yml"},e().translator.trans("fof-linguist.admin.export.download"))]),m("textarea.FormControl.FoF-Export-Textarea",{readonly:!0,value:this.output,rows:10,placeholder:this.loading?e().translator.trans("fof-linguist.admin.export.output-loading"):e().translator.trans("fof-linguist.admin.export.output-empty")})])]},n.exportUrl=function(){return e().forum.attribute("apiUrl")+"/fof/linguist/export?"+m.buildQueryString({locale:this.locale,namespace:this.namespace,includeOriginals:this.includeOriginals?"1":"0",includeAll:this.includeAll?"1":"0"})},n.fetchOutput=function(){var t=this;this.loading=!0,this.output="",e().request({method:"GET",url:this.exportUrl(),extract:function(t){return JSON.stringify(t)}}).then((function(n){t.loading=!1,t.output=n,m.redraw()})).catch((function(n){throw t.loading=!1,m.redraw(),n}))},t}(),H=function(){function t(){}var n=t.prototype;return n.oninit=function(){this.locale="en",this.overrideExisting=!0,this.input="",this.loading=!1},n.view=function(){var t=this,n={};return B().forEach((function(t){n[t.key]=t.name+" ("+t.key+")"})),n.all=e().translator.trans("fof-linguist.admin.import.locale-all"),[m("h2",e().translator.trans("fof-linguist.admin.import.title")),m(".Form-group",[m("label",e().translator.trans("fof-linguist.admin.import.input")),m("textarea.FormControl",{value:this.input,oninput:function(n){t.input=n.target.value},rows:10,placeholder:e().translator.trans("fof-linguist.admin.import.input-placeholder")})]),m(".Form-group",[m("label",e().translator.trans("fof-linguist.admin.import.locale")),x().component({options:n,value:this.locale,onchange:function(n){t.locale=n,t.fetchOutput()}})]),m(".Form-group",[G().component({state:this.overrideExisting,onchange:function(n){t.overrideExisting=n}},e().translator.trans("fof-linguist.admin.import.override-existing"))]),m(".Form-group",d().component({className:"Button Button--primary",onclick:function(){t.loading=!0,e().request({method:"POST",url:e().forum.attribute("apiUrl")+"/fof/linguist/import",body:{input:t.input,locale:t.locale,ignoreExisting:!t.overrideExisting}}).then((function(n){t.loading=!1,m.redraw(),confirm(O()(e().translator.trans(t.overrideExisting?"fof-linguist.admin.import.results":"fof-linguist.admin.import.results-with-ignore",{imported:n.imported+"",ignored:n.ignored+"",identical:n.identical+""})))&&window.location.reload()})).catch((function(n){throw t.loading=!1,m.redraw(),n}))},disabled:this.loading||!this.input,loading:this.loading},e().translator.trans("fof-linguist.admin.import.submit")))]},t}(),z=function(t){function n(){return t.apply(this,arguments)||this}a(n,t);var i=n.prototype;return i.oninit=function(n){var i=this;t.prototype.oninit.call(this,n),this.tab="strings",this.ready=!1,this.namespaces=[],this.frontends=["forum","admin","lib","ref","api"],this.initialBrowseFilters={},Promise.all([e().request({method:"GET",url:e().forum.attribute("apiUrl")+"/fof/linguist/strings"}).then((function(t){e().store.pushPayload(t)})),e().request({method:"GET",url:e().forum.attribute("apiUrl")+"/fof/linguist/string-keys"}).then((function(t){var n=e().store.pushPayload(t),o=[];n.forEach((function(t){var n=t.key().split("."),e=n[0];if(-1===["core","validation"].indexOf(e)&&-1===o.indexOf(e)&&o.push(e),n.length>1&&"validation"!==e){var a=n[1];-1===i.frontends.indexOf(a)&&i.frontends.push(a)}})),o.sort(),i.namespaces=[{namespace:"core"},{namespace:"validation"}].concat(o.map((function(t){var n=e().data.extensions[t];return n||(n=Object.values(e().data.extensions).find((function(n){var i=n.name.replace("/","-");return t===i}))),{namespace:t,extension:n}})))}))]).then((function(){i.ready=!0,m.redraw()}))},i.content=function(){return m(".ExtensionPage-settings",m(".container",[this.contentTab()]))},i.infoItems=function(){var n=this,i=t.prototype.infoItems.call(this);return i.add("linguist-tabs",m("ul.FoF-Linguist-Tabs",[m("li",m("a",{className:"strings"===this.tab?"active":"",onclick:function(){n.tab="strings"}},e().translator.trans("fof-linguist.admin.tabs.strings"))),m("li",m("a",{className:"coverage"===this.tab?"active":"",onclick:function(){n.tab="coverage"}},e().translator.trans("fof-linguist.admin.tabs.coverage"))),m("li",m("a",{className:"export"===this.tab?"active":"",onclick:function(){n.tab="export"}},e().translator.trans("fof-linguist.admin.tabs.export"))),m("li",m("a",{className:"import"===this.tab?"active":"",onclick:function(){n.tab="import"}},e().translator.trans("fof-linguist.admin.tabs.import")))]),100),i},i.contentTab=function(){var t=this;if(!this.ready)return p().component();switch(this.tab){case"strings":return m(j,{namespaces:this.namespaces,frontends:this.frontends,initialBrowseFilters:this.initialBrowseFilters});case"coverage":return m(U,{namespaces:this.namespaces,frontends:this.frontends,browseWithFilters:function(n){t.initialBrowseFilters=n,t.tab="strings"}});case"export":return m($,{namespaces:this.namespaces});case"import":return m(H)}return null},n}(f()),J={StringKey:I,StringLocale:S},Q={StringKey:l,TextString:c},V={CoveragePage:U,ExportPage:$,ImportPage:H,LinguistPage:z,StringsPage:j},X={booleanCheck:A,frontendLabel:K,highlightMithril:C,localesAsArray:B,namespaceLabel:_};e().initializers.add("fof-linguist",(function(t){t.store.models["fof-linguist-string-key"]=l,t.store.models["fof-linguist-string"]=c,t.extensionData.for("fof-linguist").registerPage(z)}))})(),module.exports=n})(); +(()=>{var t={n:n=>{var i=n&&n.__esModule?()=>n.default:()=>n;return t.d(i,{a:i}),i},d:(n,i)=>{for(var e in i)t.o(i,e)&&!t.o(n,e)&&Object.defineProperty(n,e,{enumerable:!0,get:i[e]})},o:(t,n)=>Object.prototype.hasOwnProperty.call(t,n),r:t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})}},n={};(()=>{"use strict";t.r(n),t.d(n,{components:()=>J,models:()=>Q,pages:()=>V,utils:()=>X});const i=flarum.core.compat["admin/app"];var e=t.n(i);function o(t,n){return o=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,n){return t.__proto__=n,t},o(t,n)}function a(t,n){t.prototype=Object.create(n.prototype),t.prototype.constructor=t,o(t,n)}const s=flarum.core.compat["common/Model"];var r=t.n(s),l=function(t){function n(){for(var n,i=arguments.length,e=new Array(i),o=0;o";function C(t,n){if(!n)return t;var i=n.toLowerCase(),e=new RegExp(i.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),"i");return t.replace(e,P+"$&"+P).split(P).map((function(t){return t.toLowerCase()===i?m("span.FoF-Linguist-Highlight",t):t}))}var S=function(){function t(){}var n=t.prototype;return n.oninit=function(t){var n=this;this.stringKey=t.attrs.stringKey,this.locale=t.attrs.locale,this.localeKey=this.locale?this.locale.key:null,this.originalString=this.localeKey&&this.stringKey.locales().hasOwnProperty(this.localeKey)?this.stringKey.locales()[this.localeKey]:null,this.string=e().store.all("fof-linguist-string").find((function(t){return t.key()===n.stringKey.key()&&t.locale()===n.localeKey})),this.value=this.string?this.string.value():"",this.dirty=!1,this.processing=!1;var i=Object.keys(this.stringKey.locales()).some((function(t){return-1!==n.stringKey.locales()[t].indexOf("\n")}));this.inputType="input",(i||-1!==this.value.indexOf("\n"))&&(this.inputType="textarea")},n.view=function(t){var n=this,i=this.originalString?this.originalString:"("+e().translator.trans("fof-linguist.admin.placeholder."+(this.localeKey?"not-translated":"all-locales"))+")";return m(".FoF-Linguist-Locale",[m("label.FoF-Linguist-Label",this.localeName()),m(".FoF-Linguist-Field",{className:(this.value?"FoF-Linguist-Field--with-value":"")+(this.originalString?" FoF-Linguist-Field--with-original-string":""),title:i},[m(".FoF-Linguist-Field-Wrap",[m(this.inputType,{className:"FormControl FoF-Linguist-Input",value:this.value,oninput:function(t){n.value=t.target.value,n.dirty=!0,n.value||n.string||(n.dirty=!1)},disabled:this.processing}),m(".FoF-Linguist-Placeholder",[m("span.FoF-Linguist-Placeholder-Hint",e().translator.trans("fof-linguist.admin.placeholder.hint"))," ",m("span",this.originalString?C(i,t.attrs.highlight):i)])])]),m(".FoF-Linguist-Controls",this.actions(t.attrs.onchange).toArray())])},n.localeName=function(){return this.locale?[this.locale.name+" (",m("code",this.locale.key),")"]:e().translator.trans("fof-linguist.admin.locales.all")},n.actions=function(t){var n=this,i=new(N());return i.add("apply",d().component({type:"button",className:"Button Button--primary",loading:this.processing,disabled:!this.dirty,onclick:function(){n.saveString(t)}},e().translator.trans("fof-linguist.admin.buttons.apply"))),i.add("reset",d().component({type:"button",className:"Button",loading:this.processing,disabled:!this.dirty&&!this.string,onclick:function(){n.deleteString(t)}},e().translator.trans("fof-linguist.admin.buttons.reset"))),this.originalString&&i.add("copy-original",d().component({type:"button",className:"Button",loading:this.processing,onclick:function(){n.value=n.originalString,n.dirty=!0}},e().translator.trans("fof-linguist.admin.buttons.copy-original"))),i},n.saveString=function(t){var n=this;this.value?(this.string||(this.string=e().store.createRecord("fof-linguist-string",{attributes:{key:this.stringKey.key(),locale:this.localeKey,value:""}})),this.string.data.attributes.value=this.value,this.string.locale()||delete this.string.data.attributes.locale,this.processing=!0,this.string.save(this.string.data.attributes).then((function(){n.processing=!1,n.dirty=!1,t(),m.redraw()})).catch((function(t){throw n.processing=!1,t}))):this.deleteString(t)},n.deleteString=function(t){var n=this;this.string?(this.processing=!0,this.string.delete().then((function(){n.processing=!1,n.dirty=!1,n.string=null,n.value="",t(),m.redraw()})).catch((function(t){throw n.processing=!1,t}))):(this.value="",this.dirty=!1)},t}(),I=function(){function t(){}return t.prototype.view=function(t){var n=t.attrs,i=n.stringKey,e=n.highlight,o=n.onchange;return m(".FoF-Linguist-Key",[m(".FoF-Linguist-Key-Code",m("code",C(i.key(),e))),m(".FoF-Linguist-Locales",[].concat(B().map((function(t){return m(S,{key:t.key,locale:t,stringKey:i,highlight:e,onchange:o})})),[m(S,{key:"all",locale:null,stringKey:i,highlight:e,onchange:o})]))])},t}();function _(t){return e().translator.translations["fof-linguist.admin.known-namespace."+t]||t}function K(t){return e().translator.translations["fof-linguist.admin.known-frontend."+t]||t}function A(t,n){return n.reduce((function(n,i){return"start"===n?i:"or"===t?n||i:n&&i}),"start")}var j=function(){function t(){}var n=t.prototype;return n.oninit=function(t){this.numberOfResultsToShow=20,this.filters=Object.assign({search:"",withOwnTranslations:!1,missingTranslationsNegation:"without",missingTranslationsType:"any",missingTranslationsOperation:"or",missingTranslationsInLocales:[],forExtension:null,frontend:null},t.attrs.initialBrowseFilters||{}),this.results=[],this.applyFilters()},n.view=function(t){var n=this,i=this.results.slice(0,this.numberOfResultsToShow);return[m("div",this.cacheClearInstructions()),m(".FoF-Linguist-Filters",[m("input.FormControl",{value:this.filters.search,oninput:function(t){n.filters.search=t.target.value,n.applyFilters()},placeholder:e().translator.trans("fof-linguist.admin.filters.search")}),d().component({className:"Button"+(this.filters.withOwnTranslations?" FoF-Linguist-Filter--Selected":""),icon:"far fa-"+(this.filters.withOwnTranslations?"check-square":"square"),onclick:function(){n.filters.withOwnTranslations=!n.filters.withOwnTranslations,n.applyFilters()}},e().translator.trans("fof-linguist.admin.filters.with-own-translations")),v().component({buttonClassName:"Button"+(this.filters.forExtension?" FoF-Linguist-Filter--Selected":""),label:e().translator.trans("fof-linguist.admin.filters.for-extension")},t.attrs.namespaces.map((function(t){return d().component({className:"Button",icon:"far fa-"+(n.filters.forExtension===t.namespace?"dot-circle":"circle"),onclick:function(){n.filters.forExtension===t.namespace?n.filters.forExtension=null:n.filters.forExtension=t.namespace,n.applyFilters()}},t.extension?t.extension.extra["flarum-extension"].title:_(t.namespace))}))),v().component({buttonClassName:"Button"+(this.filters.frontend?" FoF-Linguist-Filter--Selected":""),label:e().translator.trans("fof-linguist.admin.filters.frontend")},["_all_except_admin"].concat(t.attrs.frontends).map((function(t){return d().component({className:"Button",icon:"far fa-"+(n.filters.frontend===t?"dot-circle":"circle"),onclick:function(){n.filters.frontend===t?n.filters.frontend=null:n.filters.frontend=t,n.applyFilters()}},"_all_except_admin"===t?e().translator.trans("fof-linguist.admin.filters.frontend-all-except-admin"):K(t))}))),v().component({buttonClassName:"Button"+(this.filters.missingTranslationsInLocales.length?" FoF-Linguist-Filter--Selected":""),label:e().translator.trans("fof-linguist.admin.filters.missing")},[m(".FoF-Linguist-Missing-Filter",{onclick:function(t){t.stopPropagation()}},[w().component({value:this.filters.missingTranslationsNegation,onchange:function(t){n.filters.missingTranslationsNegation=t,n.filters.missingTranslationsInLocales.length&&n.applyFilters()},options:{without:e().translator.trans("fof-linguist.admin.filters.negation-options.without"),with:e().translator.trans("fof-linguist.admin.filters.negation-options.with")}}),w().component({value:this.filters.missingTranslationsType,onchange:function(t){n.filters.missingTranslationsType=t,n.filters.missingTranslationsInLocales.length&&n.applyFilters()},options:{any:e().translator.trans("fof-linguist.admin.filters.type-options.any"),original:e().translator.trans("fof-linguist.admin.filters.type-options.original"),own:e().translator.trans("fof-linguist.admin.filters.type-options.own")}}),m("p",e().translator.trans("fof-linguist.admin.filters.missing-middle-label")),w().component({value:this.filters.missingTranslationsOperation,onchange:function(t){n.filters.missingTranslationsOperation=t,n.filters.missingTranslationsInLocales.length&&n.applyFilters()},options:{or:e().translator.trans("fof-linguist.admin.filters.operation-options.or"),and:e().translator.trans("fof-linguist.admin.filters.operation-options.and")}})])].concat(B().map((function(t){return d().component({className:"Button",icon:"far fa-"+(-1!==n.filters.missingTranslationsInLocales.indexOf(t.key)?"check-square":"square"),onclick:function(){-1!==n.filters.missingTranslationsInLocales.indexOf(t.key)?n.filters.missingTranslationsInLocales=n.filters.missingTranslationsInLocales.filter((function(n){return n!==t.key})):n.filters.missingTranslationsInLocales.push(t.key),n.applyFilters()}},t.name+" ("+t.key+")")})))),v().component({buttonClassName:"Button",label:e().translator.trans("fof-linguist.admin.filters.mass-edit")},[d().component({icon:"far fa-clone",className:"Button",onclick:function(){var t=e().store.all("fof-linguist-string").filter((function(t){var n=e().store.getById("fof-linguist-string-key",t.key());return n&&n.locales()[t.locale()]===t.value()}));if(confirm(O()(e().translator.trans("fof-linguist.admin.buttons.delete-redundant-confirm",{count:t.length+""})))){if(0===t.length)return;e().modal.show(L()),Promise.all(t.map((function(t){return t.delete()}))).then((function(){window.location.reload()}))}}},e().translator.trans("fof-linguist.admin.buttons.delete-redundant")),d().component({icon:"fas fa-trash",className:"Button",onclick:function(){var t=e().store.all("fof-linguist-string");if(confirm(O()(e().translator.trans("fof-linguist.admin.buttons.delete-all-confirm",{count:t.length+""})))){if(0===t.length)return;e().modal.show(L()),Promise.all(t.map((function(t){return t.delete()}))).then((function(){window.location.reload()}))}}},e().translator.trans("fof-linguist.admin.buttons.delete-all"))])]),m("div",i.map((function(t){return m(I,{key:t.id(),stringKey:t,highlight:n.filters.search,onchange:function(){e().data.settings["fof.linguist.should-clear-cache"]="1"}})}))),m(".FoF-Linguist-Results",[e().translator.trans("fof-linguist.admin.filters.results",{shown:i.length+"",total:this.results.length+""})," ",this.results.length>i.length?d().component({className:"Button",onclick:function(){n.numberOfResultsToShow+=20}},e().translator.trans("fof-linguist.admin.buttons.load-more")):null])]},n.applyFilters=function(){var t=this;this.numberOfResultsToShow=20;var n=e().store.all("fof-linguist-string").map((function(t){return t.key()})),i={};B().forEach((function(t){i[t.key]=e().store.all("fof-linguist-string").filter((function(n){return n.locale()===t.key})).map((function(t){return t.key()}))}));var o="";this.filters.search&&(o=this.filters.search.toLowerCase()),this.results=e().store.all("fof-linguist-string-key").filter((function(e){if(t.filters.withOwnTranslations&&-1===n.indexOf(e.key()))return!1;if(t.filters.missingTranslationsInLocales.length){var a=t.filters.missingTranslationsOperation;"without"===t.filters.missingTranslationsNegation&&(a="or"===a?"and":"or");var s=A(a,t.filters.missingTranslationsInLocales.map((function(t){return e.locales().hasOwnProperty(t)}))),r=A(a,t.filters.missingTranslationsInLocales.map((function(t){return-1!==i[t].indexOf(e.key())}))),l=!1;switch(t.filters.missingTranslationsType){case"any":l=s||r;break;case"original":l=s;break;case"own":l=r}if("without"===t.filters.missingTranslationsNegation&&(l=!l),!l)return!1}if(t.filters.forExtension&&0!==e.key().indexOf(t.filters.forExtension+"."))return!1;if(t.filters.frontend){var c=e.key().split(".");if("_all_except_admin"===t.filters.frontend){if(c.length>=2&&"admin"===c[1])return!1}else if(c.length<2||c[1]!==t.filters.frontend)return!1}if(o){if(-1!==e.key().toLowerCase().indexOf(o))return!0;var u=e.locales();for(var f in u)if(u.hasOwnProperty(f)&&-1!==u[f].toLowerCase().indexOf(o))return!0;return!1}return!0})),m.redraw()},n.cacheClearInstructions=function(){return e().data.debugEnabled||"1"!==e().data.settings["fof.linguist.should-clear-cache"]?null:b().component({dismissible:!1,controls:[d().component({className:"Button Button--link",onclick:function(){e().modal.show(L()),e().request({method:"DELETE",url:e().forum.attribute("apiUrl")+"/cache"}).then((function(){return window.location.reload()}))}},e().translator.trans("fof-linguist.admin.clear-cache.button"))]},e().translator.trans("fof-linguist.admin.clear-cache.text"))},t}();const M=flarum.core.compat["common/helpers/icon"];var q=t.n(M),U=function(){function t(){}var n=t.prototype;return n.oninit=function(){this.columns="locale",this.showAllFrontends=!1,this.totalPercent=!0,this.locale=[];var t=B().find((function(t){return"en"!==t.key}));t&&(this.locale=t.key)},n.view=function(t){var n=this,i=t.attrs.frontends.slice(0,2);this.showAllFrontends&&(i=t.attrs.frontends);var o=t.attrs.browseWithFilters;return[m(".FoF-Linguist-Filters",[m(".ButtonGroup",[d().component({className:"Button"+(this.totalPercent?" active":""),onclick:function(){n.totalPercent=!0}},e().translator.trans("fof-linguist.admin.coverage.total-options.percent")),d().component({className:"Button"+(this.totalPercent?" ":" active"),onclick:function(){n.totalPercent=!1}},e().translator.trans("fof-linguist.admin.coverage.total-options.count"))]),m(".ButtonGroup",[d().component({className:"Button"+("locale"===this.columns?" active":""),onclick:function(){n.columns="locale"}},e().translator.trans("fof-linguist.admin.coverage.column-options.locale")),d().component({className:"Button"+("namespace"===this.columns?" active":""),onclick:function(){n.columns="namespace",n.showAllFrontends=!1}},e().translator.trans("fof-linguist.admin.coverage.column-options.namespace"))]),"namespace"===this.columns?m(".ButtonGroup",B().map((function(t){return d().component({className:"Button"+(n.locale===t.key?" active":""),onclick:function(){n.locale!==t.key&&(n.locale=t.key)}},t.name+" ("+t.key+")")}))):null]),m("table.FoF-Linguist-Coverage",[m("thead",m("tr",[m("th",e().translator.trans("fof-linguist.admin.coverage.columns.namespace")),"locale"===this.columns?B().map((function(t){return m("th",t.name+" ("+t.key+")")})):[this.showAllFrontends?i.map((function(t){return m("th",K(t))})):[m("th",e().translator.trans("fof-linguist.admin.coverage.columns.all-except-admin")),m("th",K("admin")),m("th",d().component({className:"Button",onclick:function(){n.showAllFrontends=!0}},e().translator.trans("fof-linguist.admin.coverage.columns.all-frontends")))]]])),m("tbody",["locale"===this.columns?m("tr",[m("td",[m("span.FoF-Linguist-Coverage-Extension-Icon.FoF-Linguist-Coverage-Namespace-Icon"),m("span.FoF-Linguist-Coverage-Extension-Title",e().translator.trans("fof-linguist.admin.coverage.all-namespaces"))]),B().map((function(t){return m("td",n.localeCoverage(o,t.key))}))]):null,t.attrs.namespaces.map((function(t){return m("tr",[m("td",t.extension?[m("span.FoF-Linguist-Coverage-Extension-Icon",{style:t.extension.icon},t.extension.icon?q()(t.extension.icon.name):""),m("span.FoF-Linguist-Coverage-Extension-Title",t.extension.extra["flarum-extension"].title)]:[m("span.FoF-Linguist-Coverage-Extension-Icon.FoF-Linguist-Coverage-Namespace-Icon"),m("span.FoF-Linguist-Coverage-Extension-Title",_(t.namespace))]),"locale"===n.columns?B().map((function(i){return m("td",n.localeCoverage(o,i.key,t.namespace))})):[n.showAllFrontends?i.map((function(i){return m("td",n.prefixCoverage(o,t.namespace,i))})):[m("td",n.prefixCoverage(o,t.namespace,"_all_except_admin")),m("td",n.prefixCoverage(o,t.namespace,"admin"))]]])}))])])]},n.prefixCoverage=function(t,n,i){return this.locale?this.localeCoverage(t,this.locale,n,i):null},n.localeCoverage=function(t,n,i,o){var a=e().store.all("fof-linguist-string-key").filter((function(t){if(!i)return!0;var n=t.key().split(".");if(n[0]!==i)return!1;if("_all_except_admin"===o){if(n.length>=2&&"admin"===n[1])return!1}else if(o&&(n.length<2||n[1]!==o))return!1;return!0}));if(0===a.length)return"-";var s=0,r=0;a.forEach((function(t){e().store.all("fof-linguist-string").find((function(i){return i.key()===t.key()&&i.locale()===n}))?s++:t.locales().hasOwnProperty(n)&&r++}));var l,c,u=Math.round((s+r)/a.length*100);return 100===u?l="full":u<5&&(l="low"),c=this.totalPercent?e().translator.trans("fof-linguist.admin.coverage.count.percent",{percent:u+""}):e().translator.trans("fof-linguist.admin.coverage.count.total",{translated:s+r+"",total:a.length}),m(".FoF-Linguist-Coverage-Progress-Wrap",[m(".FoF-Linguist-Progress",{className:l?"FoF-Linguist-Progress--"+l:""},[m(".FoF-Linguist-Progress-Bar",{style:{width:Math.max(u,5)+"%"}}),m(".FoF-Linguist-Progress-Label",c),m(".FoF-Linguist-Progress-More",e().translator.trans("fof-linguist.admin.coverage.count.details",{total:a.length,original:r+"",custom:s+""}))]),d().component({icon:"fas fa-filter",className:"Button Button--icon",onclick:function(){var e={missingTranslationsInLocales:[n]};i&&(e.forExtension=i),o&&(e.frontend=o),t(e)},title:e().translator.trans("fof-linguist.admin.coverage.apply-missing-filter")})])},t}();const G=flarum.core.compat["common/components/Switch"];var R=t.n(G);const W=flarum.core.compat["common/components/LinkButton"];var D=t.n(W),$=function(){function t(){}var n=t.prototype;return n.oninit=function(){this.locale="en",this.namespace=null,this.includeOriginals=!1,this.includeAll=!1,this.loading=!1,this.output="",this.fetchOutput()},n.view=function(t){var n=this,i={};B().forEach((function(t){i[t.key]=t.name+" ("+t.key+")"})),i.all=e().translator.trans("fof-linguist.admin.export.locale-all");var o={_all:e().translator.trans("fof-linguist.admin.export.namespace-all")};return t.attrs.namespaces.forEach((function(t){t.extension?o[t.namespace]=t.extension.extra["flarum-extension"].title:o[t.namespace]=_(t.namespace)})),[m("h2",e().translator.trans("fof-linguist.admin.export.title")),m(".Form-group",m(".Alert",e().translator.trans("fof-linguist.admin.export.warning"))),m(".Form-group",[m("label",e().translator.trans("fof-linguist.admin.export.locale")),w().component({options:i,value:this.locale,onchange:function(t){n.locale=t,n.fetchOutput()}})]),m(".Form-group",[m("label",e().translator.trans("fof-linguist.admin.export.namespace")),w().component({options:o,value:null===this.namespace?"_all":this.namespace,onchange:function(t){n.namespace="_all"===t?null:t,n.fetchOutput()}})]),m(".Form-group",[R().component({state:this.includeOriginals,onchange:function(t){n.includeOriginals=t,n.fetchOutput()}},e().translator.trans("fof-linguist.admin.export.include-originals"))]),m(".Form-group",[R().component({state:this.includeAll,onchange:function(t){n.includeAll=t,n.fetchOutput()}},e().translator.trans("fof-linguist.admin.export.include-all"))]),m(".Form-group",[m("label",[e().translator.trans("fof-linguist.admin.export.output")," ",D().component({className:"Button Button--primary",href:this.exportUrl(),external:!0,download:(this.namespace||this.locale)+".yml"},e().translator.trans("fof-linguist.admin.export.download"))]),m("textarea.FormControl.FoF-Export-Textarea",{readonly:!0,value:this.output,rows:10,placeholder:this.loading?e().translator.trans("fof-linguist.admin.export.output-loading"):e().translator.trans("fof-linguist.admin.export.output-empty")})])]},n.exportUrl=function(){return e().forum.attribute("apiUrl")+"/fof/linguist/export?"+m.buildQueryString({locale:this.locale,namespace:this.namespace,includeOriginals:this.includeOriginals?"1":"0",includeAll:this.includeAll?"1":"0"})},n.fetchOutput=function(){var t=this;this.loading=!0,this.output="",e().request({method:"GET",url:this.exportUrl(),extract:function(t){return JSON.stringify(t)}}).then((function(n){t.loading=!1,t.output=n,m.redraw()})).catch((function(n){throw t.loading=!1,m.redraw(),n}))},t}(),H=function(){function t(){}var n=t.prototype;return n.oninit=function(){this.locale="en",this.overrideExisting=!0,this.input="",this.loading=!1},n.view=function(){var t=this,n={};return B().forEach((function(t){n[t.key]=t.name+" ("+t.key+")"})),n.all=e().translator.trans("fof-linguist.admin.import.locale-all"),[m("h2",e().translator.trans("fof-linguist.admin.import.title")),m(".Form-group",[m("label",e().translator.trans("fof-linguist.admin.import.input")),m("textarea.FormControl",{value:this.input,oninput:function(n){t.input=n.target.value},rows:10,placeholder:e().translator.trans("fof-linguist.admin.import.input-placeholder")})]),m(".Form-group",[m("label",e().translator.trans("fof-linguist.admin.import.locale")),w().component({options:n,value:this.locale,onchange:function(n){t.locale=n,t.fetchOutput()}})]),m(".Form-group",[R().component({state:this.overrideExisting,onchange:function(n){t.overrideExisting=n}},e().translator.trans("fof-linguist.admin.import.override-existing"))]),m(".Form-group",d().component({className:"Button Button--primary",onclick:function(){t.loading=!0,e().request({method:"POST",url:e().forum.attribute("apiUrl")+"/fof/linguist/import",body:{input:t.input,locale:t.locale,ignoreExisting:!t.overrideExisting}}).then((function(n){t.loading=!1,m.redraw(),confirm(O()(e().translator.trans(t.overrideExisting?"fof-linguist.admin.import.results":"fof-linguist.admin.import.results-with-ignore",{imported:n.imported+"",ignored:n.ignored+"",identical:n.identical+""})))&&window.location.reload()})).catch((function(n){throw t.loading=!1,m.redraw(),n}))},disabled:this.loading||!this.input,loading:this.loading},e().translator.trans("fof-linguist.admin.import.submit")))]},t}(),z=function(t){function n(){return t.apply(this,arguments)||this}a(n,t);var i=n.prototype;return i.oninit=function(n){var i=this;t.prototype.oninit.call(this,n),this.tab="strings",this.ready=!1,this.namespaces=[],this.frontends=["forum","admin","lib","ref","api"],this.initialBrowseFilters={},Promise.all([e().request({method:"GET",url:e().forum.attribute("apiUrl")+"/fof/linguist/strings"}).then((function(t){e().store.pushPayload(t)})),e().request({method:"GET",url:e().forum.attribute("apiUrl")+"/fof/linguist/string-keys"}).then((function(t){var n=e().store.pushPayload(t),o=[];n.forEach((function(t){var n=t.key().split("."),e=n[0];if(-1===["core","validation"].indexOf(e)&&-1===o.indexOf(e)&&o.push(e),n.length>1&&"validation"!==e){var a=n[1];-1===i.frontends.indexOf(a)&&i.frontends.push(a)}})),o.sort(),i.namespaces=[{namespace:"core"},{namespace:"validation"}].concat(o.map((function(t){var n=e().data.extensions[t];return n||(n=Object.values(e().data.extensions).find((function(n){var i=n.name.replace("/","-");return t===i}))),{namespace:t,extension:n}})))}))]).then((function(){i.ready=!0,m.redraw()}))},i.content=function(){return m(".ExtensionPage-settings",m(".container",[this.contentTab()]))},i.infoItems=function(){var n=this,i=t.prototype.infoItems.call(this);return i.add("linguist-tabs",m("ul.FoF-Linguist-Tabs",[m("li",m("a",{className:"strings"===this.tab?"active":"",onclick:function(){n.tab="strings"}},e().translator.trans("fof-linguist.admin.tabs.strings"))),m("li",m("a",{className:"coverage"===this.tab?"active":"",onclick:function(){n.tab="coverage"}},e().translator.trans("fof-linguist.admin.tabs.coverage"))),m("li",m("a",{className:"export"===this.tab?"active":"",onclick:function(){n.tab="export"}},e().translator.trans("fof-linguist.admin.tabs.export"))),m("li",m("a",{className:"import"===this.tab?"active":"",onclick:function(){n.tab="import"}},e().translator.trans("fof-linguist.admin.tabs.import")))]),100),i},i.contentTab=function(){var t=this;if(!this.ready)return p().component();switch(this.tab){case"strings":return m(j,{namespaces:this.namespaces,frontends:this.frontends,initialBrowseFilters:this.initialBrowseFilters});case"coverage":return m(U,{namespaces:this.namespaces,frontends:this.frontends,browseWithFilters:function(n){t.initialBrowseFilters=n,t.tab="strings"}});case"export":return m($,{namespaces:this.namespaces});case"import":return m(H)}return null},n}(f()),J={StringKey:I,StringLocale:S},Q={StringKey:l,TextString:c},V={CoveragePage:U,ExportPage:$,ImportPage:H,LinguistPage:z,StringsPage:j},X={booleanCheck:A,frontendLabel:K,highlightMithril:C,localesAsArray:B,namespaceLabel:_};e().initializers.add("fof-linguist",(function(t){t.store.models["fof-linguist-string-key"]=l,t.store.models["fof-linguist-string"]=c,t.extensionData.for("fof-linguist").registerPage(z).registerPermission({icon:"fas fa-italic",label:t.translator.trans("fof-linguist.admin.permissions.view_string_keys"),permission:"viewStringKeys",allowGuest:!0},"view")}))})(),module.exports=n})(); //# sourceMappingURL=admin.js.map \ No newline at end of file diff --git a/js/dist/admin.js.map b/js/dist/admin.js.map index f7f6819..5b1efa7 100644 --- a/js/dist/admin.js.map +++ b/js/dist/admin.js.map @@ -1 +1 @@ -{"version":3,"file":"admin.js","mappings":"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","sources":["webpack://@fof/linguist/webpack/bootstrap","webpack://@fof/linguist/webpack/runtime/compat get default export","webpack://@fof/linguist/webpack/runtime/define property getters","webpack://@fof/linguist/webpack/runtime/hasOwnProperty shorthand","webpack://@fof/linguist/webpack/runtime/make namespace object","webpack://@fof/linguist/external root \"flarum.core.compat['admin/app']\"","webpack://@fof/linguist/./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js","webpack://@fof/linguist/./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js","webpack://@fof/linguist/external root \"flarum.core.compat['common/Model']\"","webpack://@fof/linguist/./src/admin/models/StringKey.js","webpack://@fof/linguist/./src/admin/models/TextString.js","webpack://@fof/linguist/external root \"flarum.core.compat['admin/components/ExtensionPage']\"","webpack://@fof/linguist/external root \"flarum.core.compat['common/components/LoadingIndicator']\"","webpack://@fof/linguist/external root \"flarum.core.compat['common/components/Button']\"","webpack://@fof/linguist/external root \"flarum.core.compat['common/components/Dropdown']\"","webpack://@fof/linguist/external root \"flarum.core.compat['common/components/Select']\"","webpack://@fof/linguist/external root \"flarum.core.compat['common/components/Alert']\"","webpack://@fof/linguist/external root \"flarum.core.compat['admin/components/LoadingModal']\"","webpack://@fof/linguist/external root \"flarum.core.compat['common/utils/extractText']\"","webpack://@fof/linguist/./src/admin/utils/localesAsArray.js","webpack://@fof/linguist/external root \"flarum.core.compat['common/utils/ItemList']\"","webpack://@fof/linguist/./src/admin/utils/highlightMithril.js","webpack://@fof/linguist/./src/admin/components/StringLocale.js","webpack://@fof/linguist/./src/admin/components/StringKey.js","webpack://@fof/linguist/./src/admin/utils/namespaceLabel.js","webpack://@fof/linguist/./src/admin/utils/frontendLabel.js","webpack://@fof/linguist/./src/admin/utils/booleanCheck.js","webpack://@fof/linguist/./src/admin/pages/StringsPage.js","webpack://@fof/linguist/external root \"flarum.core.compat['common/helpers/icon']\"","webpack://@fof/linguist/./src/admin/pages/CoveragePage.js","webpack://@fof/linguist/external root \"flarum.core.compat['common/components/Switch']\"","webpack://@fof/linguist/external root \"flarum.core.compat['common/components/LinkButton']\"","webpack://@fof/linguist/./src/admin/pages/ExportPage.js","webpack://@fof/linguist/./src/admin/pages/ImportPage.js","webpack://@fof/linguist/./src/admin/pages/LinguistPage.js","webpack://@fof/linguist/./src/admin/components/index.js","webpack://@fof/linguist/./src/admin/models/index.js","webpack://@fof/linguist/./src/admin/pages/index.js","webpack://@fof/linguist/./src/admin/utils/index.js","webpack://@fof/linguist/./src/admin/index.js"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['admin/app'];","export default function _setPrototypeOf(o, p) {\n _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n return _setPrototypeOf(o, p);\n}","import setPrototypeOf from \"./setPrototypeOf.js\";\nexport default function _inheritsLoose(subClass, superClass) {\n subClass.prototype = Object.create(superClass.prototype);\n subClass.prototype.constructor = subClass;\n setPrototypeOf(subClass, superClass);\n}","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/Model'];","import Model from 'flarum/common/Model';\n\nexport default class StringKey extends Model {\n key = Model.attribute('key');\n locales = Model.attribute('locales');\n}\n","import Model from 'flarum/common/Model';\n\nexport default class TextString extends Model {\n key = Model.attribute('key');\n locale = Model.attribute('locale');\n value = Model.attribute('value');\n\n apiEndpoint() {\n return '/fof/linguist/strings' + (this.exists ? '/' + this.data.id : '');\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['admin/components/ExtensionPage'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/components/LoadingIndicator'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/components/Button'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/components/Dropdown'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/components/Select'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/components/Alert'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['admin/components/LoadingModal'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/utils/extractText'];","import app from 'flarum/admin/app';\n\nexport default function () {\n let locales = [];\n\n let englishFound = false;\n\n for (let key in app.data.locales) {\n if (!app.data.locales.hasOwnProperty(key)) {\n continue;\n }\n\n if (key === 'en') {\n englishFound = true;\n }\n\n locales.push({\n key,\n name: app.data.locales[key],\n });\n }\n\n // Always show English for the following reasons:\n // It's the fallback locale, so the translations are always active\n // It's the bundled locale for most extensions, so it makes sense to have access to it as reference\n if (!englishFound) {\n locales.unshift({\n key: 'en',\n // Hard-coded to the same value as in flarum/lang-english composer.json\n // Since other locale names won't be translated to the current language either it doesn't make sense to use a translation\n name: 'English',\n });\n }\n\n return locales;\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/utils/ItemList'];","/* global m */\n\nconst HIGHLIGHT_DELIMITER = '';\n\n// Takes a string and highlight a keyword with a span with mithril template\n// The output will be an array if a keyword is given\nexport default function (string, highlight) {\n if (!highlight) {\n return string;\n }\n\n const lowercaseHighliht = highlight.toLowerCase();\n\n // Regex to match the highlighted work in a case-insensitive manner\n const regex = new RegExp(lowercaseHighliht.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'), 'i');\n\n return string\n .replace(regex, HIGHLIGHT_DELIMITER + '$&' + HIGHLIGHT_DELIMITER)\n .split(HIGHLIGHT_DELIMITER)\n .map(text => {\n if (text.toLowerCase() === lowercaseHighliht) {\n return m('span.FoF-Linguist-Highlight', text);\n }\n\n return text;\n });\n}\n","import app from 'flarum/admin/app';\nimport ItemList from 'flarum/common/utils/ItemList';\nimport Button from 'flarum/common/components/Button';\nimport highlightMithril from '../utils/highlightMithril';\n\n/* global m */\n\nexport default class StringLocale {\n oninit(vnode) {\n this.stringKey = vnode.attrs.stringKey;\n this.locale = vnode.attrs.locale;\n this.localeKey = this.locale ? this.locale.key : null;\n this.originalString = this.localeKey && this.stringKey.locales().hasOwnProperty(this.localeKey) ? this.stringKey.locales()[this.localeKey] : null;\n\n this.string = app.store.all('fof-linguist-string').find(\n string => string.key() === this.stringKey.key() && string.locale() === this.localeKey\n );\n\n this.value = this.string ? this.string.value() : '';\n this.dirty = false;\n this.processing = false;\n\n // We check whether any original translation in any language has a newline\n // By not hard-coding to English, this should work pretty well even if the fallback locale is modified,\n // or if a text happens to not be available in the fallback language\n const originalHasNewLine = Object.keys(this.stringKey.locales()).some(key => this.stringKey.locales()[key].indexOf('\\n') !== -1);\n\n this.inputType = 'input';\n\n // We will enable multi-line editing if the original has a newline, or if the current custom value already has one\n if (originalHasNewLine || this.value.indexOf('\\n') !== -1) {\n this.inputType = 'textarea';\n }\n }\n\n view(vnode) {\n const placeholderText = this.originalString ? this.originalString : '(' + app.translator.trans('fof-linguist.admin.placeholder.' + (this.localeKey ? 'not-translated' : 'all-locales')) + ')';\n\n return m('.FoF-Linguist-Locale', [\n m('label.FoF-Linguist-Label', this.localeName()),\n m('.FoF-Linguist-Field', {\n className: (this.value ? 'FoF-Linguist-Field--with-value' : '') + (this.originalString ? ' FoF-Linguist-Field--with-original-string' : ''),\n title: placeholderText,\n }, [\n m('.FoF-Linguist-Field-Wrap', [\n m(this.inputType, {\n className: 'FormControl FoF-Linguist-Input',\n value: this.value,\n oninput: event => {\n this.value = event.target.value;\n this.dirty = true;\n\n // Remove dirty state if the user erased his text without saving\n if (!this.value && !this.string) {\n this.dirty = false;\n }\n },\n disabled: this.processing,\n }),\n m('.FoF-Linguist-Placeholder', [\n m('span.FoF-Linguist-Placeholder-Hint', app.translator.trans('fof-linguist.admin.placeholder.hint')),\n ' ',\n m('span', this.originalString ? highlightMithril(placeholderText, vnode.attrs.highlight) : placeholderText),\n ]),\n ]),\n ]),\n m('.FoF-Linguist-Controls', this.actions(vnode.attrs.onchange).toArray()),\n ]);\n }\n\n localeName() {\n if (this.locale) {\n return [this.locale.name + ' (', m('code', this.locale.key), ')'];\n } else {\n return app.translator.trans('fof-linguist.admin.locales.all');\n }\n }\n\n actions(onchange) {\n const items = new ItemList();\n\n items.add('apply', Button.component({\n type: 'button',\n className: 'Button Button--primary',\n loading: this.processing,\n disabled: !this.dirty,\n onclick: () => {\n this.saveString(onchange);\n },\n }, app.translator.trans('fof-linguist.admin.buttons.apply')));\n\n items.add('reset', Button.component({\n type: 'button',\n className: 'Button',\n loading: this.processing,\n disabled: !this.dirty && !this.string,\n onclick: () => {\n this.deleteString(onchange);\n },\n }, app.translator.trans('fof-linguist.admin.buttons.reset')));\n\n if (this.originalString) {\n items.add('copy-original', Button.component({\n type: 'button',\n className: 'Button',\n loading: this.processing,\n onclick: () => {\n this.value = this.originalString;\n this.dirty = true;\n },\n }, app.translator.trans('fof-linguist.admin.buttons.copy-original')));\n }\n\n return items;\n }\n\n saveString(onchange) {\n if (!this.value) {\n this.deleteString(onchange);\n\n return;\n }\n\n if (!this.string) {\n this.string = app.store.createRecord('fof-linguist-string', {\n attributes: {\n key: this.stringKey.key(),\n locale: this.localeKey,\n value: '',\n },\n });\n }\n\n this.string.data.attributes.value = this.value;\n\n if (!this.string.locale()) delete this.string.data.attributes.locale;\n\n this.processing = true;\n\n this.string.save(this.string.data.attributes).then(() => {\n this.processing = false;\n this.dirty = false;\n\n onchange();\n\n m.redraw();\n }).catch(err => {\n this.processing = false;\n\n throw err;\n });\n }\n\n deleteString(onchange) {\n if (this.string) {\n this.processing = true;\n\n this.string.delete().then(() => {\n this.processing = false;\n this.dirty = false;\n\n this.string = null;\n this.value = '';\n\n onchange();\n\n m.redraw();\n }).catch(err => {\n this.processing = false;\n\n throw err;\n });\n } else {\n this.value = '';\n this.dirty = false;\n }\n }\n}\n","import StringLocale from '../components/StringLocale';\nimport localesAsArray from '../utils/localesAsArray';\nimport highlightMithril from '../utils/highlightMithril';\n\n/* global m */\n\nexport default class StringKey {\n view(vnode) {\n const {\n stringKey,\n highlight,\n onchange,\n } = vnode.attrs;\n\n return m('.FoF-Linguist-Key', [\n m('.FoF-Linguist-Key-Code', m('code', highlightMithril(stringKey.key(), highlight))),\n m('.FoF-Linguist-Locales', [\n ...localesAsArray().map(locale => m(StringLocale, {\n key: locale.key,\n locale,\n stringKey,\n highlight,\n onchange,\n })),\n m(StringLocale, {\n key: 'all',\n locale: null,\n stringKey,\n highlight,\n onchange,\n }),\n ]),\n ]);\n }\n}\n","import app from 'flarum/admin/app';\n\nexport default function (namespace) {\n const translation = app.translator.translations['fof-linguist.admin.known-namespace.' + namespace];\n\n if (translation) {\n return translation;\n }\n\n return namespace;\n}\n","import app from 'flarum/admin/app';\n\nexport default function (frontend) {\n const translation = app.translator.translations['fof-linguist.admin.known-frontend.' + frontend];\n\n if (translation) {\n return translation;\n }\n\n return frontend;\n}\n","export default function (operation, booleans) {\n return booleans.reduce((a, b) => {\n if (a === 'start') {\n return b;\n }\n\n if (operation === 'or') {\n return a || b;\n }\n\n return a && b;\n }, 'start');\n}\n","import app from 'flarum/admin/app';\nimport Button from 'flarum/common/components/Button';\nimport Dropdown from 'flarum/common/components/Dropdown';\nimport Select from 'flarum/common/components/Select';\nimport Alert from 'flarum/common/components/Alert';\nimport LoadingModal from 'flarum/admin/components/LoadingModal';\nimport extractText from 'flarum/common/utils/extractText';\nimport localesAsArray from '../utils/localesAsArray';\nimport StringKey from '../components/StringKey';\nimport namespaceLabel from '../utils/namespaceLabel';\nimport frontendLabel from '../utils/frontendLabel';\nimport booleanCheck from '../utils/booleanCheck';\n\n/* global m */\n\nconst RESULTS_PER_PAGE = 20;\n\nexport default class StringsPage {\n oninit(vnode) {\n this.numberOfResultsToShow = RESULTS_PER_PAGE;\n\n this.filters = Object.assign({\n search: '',\n withOwnTranslations: false,\n missingTranslationsNegation: 'without',\n missingTranslationsType: 'any',\n missingTranslationsOperation: 'or',\n missingTranslationsInLocales: [],\n forExtension: null,\n frontend: null,\n }, vnode.attrs.initialBrowseFilters || {});\n\n this.results = [];\n\n this.applyFilters();\n }\n\n view(vnode) {\n const keys = this.results.slice(0, this.numberOfResultsToShow);\n\n return [\n // Additional divs are used to reduce Mithril redraws as much as possible when the conditional components appear\n m('div', this.cacheClearInstructions()),\n m('.FoF-Linguist-Filters', [\n m('input.FormControl', {\n value: this.filters.search,\n oninput: event => {\n this.filters.search = event.target.value;\n this.applyFilters();\n },\n placeholder: app.translator.trans('fof-linguist.admin.filters.search'),\n }),\n Button.component({\n className: 'Button' + (this.filters.withOwnTranslations ? ' FoF-Linguist-Filter--Selected' : ''),\n icon: `far fa-${this.filters.withOwnTranslations ? 'check-square' : 'square'}`,\n onclick: () => {\n this.filters.withOwnTranslations = !this.filters.withOwnTranslations;\n this.applyFilters();\n },\n }, app.translator.trans('fof-linguist.admin.filters.with-own-translations')),\n Dropdown.component({\n buttonClassName: 'Button' + (this.filters.forExtension ? ' FoF-Linguist-Filter--Selected' : ''),\n label: app.translator.trans('fof-linguist.admin.filters.for-extension'),\n }, vnode.attrs.namespaces.map(\n namespace => Button.component({\n className: 'Button',\n icon: `far fa-${this.filters.forExtension === namespace.namespace ? 'dot-circle' : 'circle'}`,\n onclick: () => {\n if (this.filters.forExtension === namespace.namespace) {\n this.filters.forExtension = null;\n } else {\n this.filters.forExtension = namespace.namespace;\n }\n\n this.applyFilters();\n },\n }, namespace.extension ? namespace.extension.extra['flarum-extension'].title : namespaceLabel(namespace.namespace))\n )),\n Dropdown.component({\n buttonClassName: 'Button' + (this.filters.frontend ? ' FoF-Linguist-Filter--Selected' : ''),\n label: app.translator.trans('fof-linguist.admin.filters.frontend'),\n }, [\n '_all_except_admin',\n ...vnode.attrs.frontends,\n ].map(\n frontend => Button.component({\n className: 'Button',\n icon: `far fa-${this.filters.frontend === frontend ? 'dot-circle' : 'circle'}`,\n onclick: () => {\n if (this.filters.frontend === frontend) {\n this.filters.frontend = null;\n } else {\n this.filters.frontend = frontend;\n }\n\n this.applyFilters();\n },\n }, frontend === '_all_except_admin' ? app.translator.trans('fof-linguist.admin.filters.frontend-all-except-admin') : frontendLabel(frontend))\n )),\n Dropdown.component({\n buttonClassName: 'Button' + (this.filters.missingTranslationsInLocales.length ? ' FoF-Linguist-Filter--Selected' : ''),\n label: app.translator.trans('fof-linguist.admin.filters.missing'),\n }, [\n m('.FoF-Linguist-Missing-Filter', {\n onclick(event) {\n // Prevent closing the dropdown\n event.stopPropagation();\n },\n }, [\n Select.component({\n value: this.filters.missingTranslationsNegation,\n onchange: value => {\n this.filters.missingTranslationsNegation = value;\n\n if (this.filters.missingTranslationsInLocales.length) {\n this.applyFilters();\n }\n },\n options: {\n without: app.translator.trans('fof-linguist.admin.filters.negation-options.without'),\n with: app.translator.trans('fof-linguist.admin.filters.negation-options.with'),\n },\n }),\n Select.component({\n value: this.filters.missingTranslationsType,\n onchange: value => {\n this.filters.missingTranslationsType = value;\n\n if (this.filters.missingTranslationsInLocales.length) {\n this.applyFilters();\n }\n },\n options: {\n any: app.translator.trans('fof-linguist.admin.filters.type-options.any'),\n original: app.translator.trans('fof-linguist.admin.filters.type-options.original'),\n own: app.translator.trans('fof-linguist.admin.filters.type-options.own'),\n },\n }),\n m('p', app.translator.trans('fof-linguist.admin.filters.missing-middle-label')),\n Select.component({\n value: this.filters.missingTranslationsOperation,\n onchange: value => {\n this.filters.missingTranslationsOperation = value;\n\n if (this.filters.missingTranslationsInLocales.length) {\n this.applyFilters();\n }\n },\n options: {\n or: app.translator.trans('fof-linguist.admin.filters.operation-options.or'),\n and: app.translator.trans('fof-linguist.admin.filters.operation-options.and'),\n },\n }),\n ]),\n ...localesAsArray().map(\n locale => Button.component({\n className: 'Button',\n icon: `far fa-${this.filters.missingTranslationsInLocales.indexOf(locale.key) !== -1 ? 'check-square' : 'square'}`,\n onclick: () => {\n if (this.filters.missingTranslationsInLocales.indexOf(locale.key) !== -1) {\n this.filters.missingTranslationsInLocales = this.filters.missingTranslationsInLocales.filter(key => key !== locale.key);\n } else {\n this.filters.missingTranslationsInLocales.push(locale.key);\n }\n\n this.applyFilters();\n },\n }, locale.name + ' (' + locale.key + ')')\n ),\n ]),\n Dropdown.component({\n buttonClassName: 'Button',\n label: app.translator.trans('fof-linguist.admin.filters.mass-edit'),\n }, [\n Button.component({\n icon: 'far fa-clone',\n className: 'Button',\n onclick: () => {\n const strings = app.store.all('fof-linguist-string').filter(string => {\n const key = app.store.getById('fof-linguist-string-key', string.key());\n\n return key && key.locales()[string.locale()] === string.value();\n });\n\n if (confirm(extractText(app.translator.trans('fof-linguist.admin.buttons.delete-redundant-confirm', {\n count: strings.length + '',\n })))) {\n if (strings.length === 0) {\n return;\n }\n\n app.modal.show(LoadingModal);\n\n Promise.all(strings.map(string => string.delete())).then(() => {\n window.location.reload();\n });\n }\n },\n }, app.translator.trans('fof-linguist.admin.buttons.delete-redundant')),\n Button.component({\n icon: 'fas fa-trash',\n className: 'Button',\n onclick: () => {\n const strings = app.store.all('fof-linguist-string');\n\n if (confirm(extractText(app.translator.trans('fof-linguist.admin.buttons.delete-all-confirm', {\n count: strings.length + '',\n })))) {\n if (strings.length === 0) {\n return;\n }\n\n app.modal.show(LoadingModal);\n\n Promise.all(strings.map(string => string.delete())).then(() => {\n window.location.reload();\n });\n }\n },\n }, app.translator.trans('fof-linguist.admin.buttons.delete-all')),\n ]),\n ]),\n m('div', keys.map(stringKey => m(StringKey, {\n key: stringKey.id(),\n stringKey,\n highlight: this.filters.search,\n onchange: () => {\n // We use the setting and not a local variable because we need to preserve state\n // if we navigate away and back to the Linguist page without refreshing the admin panel\n app.data.settings['fof.linguist.should-clear-cache'] = '1';\n },\n }))),\n m('.FoF-Linguist-Results', [\n app.translator.trans('fof-linguist.admin.filters.results', {\n shown: keys.length + '', // cast to string otherwise number isn't displayed\n total: this.results.length + '',\n }),\n ' ',\n (this.results.length > keys.length ? Button.component({\n className: 'Button',\n onclick: () => {\n this.numberOfResultsToShow += RESULTS_PER_PAGE;\n },\n }, app.translator.trans('fof-linguist.admin.buttons.load-more')) : null),\n ]),\n ];\n }\n\n applyFilters() {\n this.numberOfResultsToShow = RESULTS_PER_PAGE;\n\n const keysWithCustomTranslations = app.store.all('fof-linguist-string').map(string => string.key());\n\n const keysWithCustomTranslationsIn = {};\n localesAsArray().forEach(locale => {\n keysWithCustomTranslationsIn[locale.key] = app.store.all('fof-linguist-string')\n .filter(string => string.locale() === locale.key)\n .map(string => string.key());\n });\n\n let lowercaseSearch = '';\n\n if (this.filters.search) {\n lowercaseSearch = this.filters.search.toLowerCase();\n }\n\n this.results = app.store.all('fof-linguist-string-key').filter(key => {\n if (this.filters.withOwnTranslations && keysWithCustomTranslations.indexOf(key.key()) === -1) {\n return false;\n }\n\n if (this.filters.missingTranslationsInLocales.length) {\n let operation = this.filters.missingTranslationsOperation;\n\n // Because the whole operation is reversed at the end based on with or without,\n // we actually need to make the opposite boolean computation on the \"has\" variables\n if (this.filters.missingTranslationsNegation === 'without') {\n operation = operation === 'or' ? 'and' : 'or';\n }\n\n const hasOriginalTranslation = booleanCheck(operation, this.filters.missingTranslationsInLocales.map(locale => {\n return key.locales().hasOwnProperty(locale);\n }));\n const hasOwnTranslation = booleanCheck(operation, this.filters.missingTranslationsInLocales.map(locale => {\n return keysWithCustomTranslationsIn[locale].indexOf(key.key()) !== -1;\n }));\n\n let matchesType = false;\n\n switch (this.filters.missingTranslationsType) {\n case 'any':\n matchesType = hasOriginalTranslation || hasOwnTranslation;\n break;\n case 'original':\n matchesType = hasOriginalTranslation;\n break;\n case 'own':\n matchesType = hasOwnTranslation;\n break;\n }\n\n if (this.filters.missingTranslationsNegation === 'without') {\n matchesType = !matchesType;\n }\n\n if (!matchesType) {\n return false;\n }\n }\n\n if (this.filters.forExtension) {\n if (key.key().indexOf(this.filters.forExtension + '.') !== 0) {\n return false;\n }\n }\n\n if (this.filters.frontend) {\n const parts = key.key().split('.');\n\n if (this.filters.frontend === '_all_except_admin') {\n // We will keep everything that isn't admin, including if it's a single level deep\n if (parts.length >= 2 && parts[1] === 'admin') {\n return false;\n }\n } else {\n // Keep only parts with 2 levels or more where second level matches frontend\n if (parts.length < 2 || parts[1] !== this.filters.frontend) {\n return false;\n }\n }\n }\n\n if (lowercaseSearch) {\n if (key.key().toLowerCase().indexOf(lowercaseSearch) !== -1) {\n return true;\n }\n\n const locales = key.locales();\n\n for (let locale in locales) {\n if (locales.hasOwnProperty(locale) && locales[locale].toLowerCase().indexOf(lowercaseSearch) !== -1) {\n return true;\n }\n }\n\n return false;\n }\n\n return true;\n });\n\n m.redraw();\n }\n\n cacheClearInstructions() {\n // If debug is enabled, we hide the message here because even if we stop setting the flag,\n // an older flag might still be present from before debug mode was enabled\n if (app.data.debugEnabled) {\n return null;\n }\n\n // Check for flag that says cache should be cleared\n // This value is set both server-side and client-side in the onchange code above for immediate effect\n if (app.data.settings['fof.linguist.should-clear-cache'] !== '1') {\n return null;\n }\n\n return Alert.component({\n dismissible: false,\n controls: [Button.component({\n className: 'Button Button--link',\n onclick() {\n // Same logic as in core StatusWidget\n app.modal.show(LoadingModal);\n\n app.request({\n method: 'DELETE',\n url: app.forum.attribute('apiUrl') + '/cache',\n }).then(() => window.location.reload());\n },\n }, app.translator.trans('fof-linguist.admin.clear-cache.button'))],\n }, app.translator.trans('fof-linguist.admin.clear-cache.text'));\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/helpers/icon'];","import app from 'flarum/admin/app';\nimport Button from 'flarum/common/components/Button';\nimport icon from 'flarum/common/helpers/icon';\nimport localesAsArray from '../utils/localesAsArray';\nimport namespaceLabel from '../utils/namespaceLabel';\nimport frontendLabel from '../utils/frontendLabel';\n\n/* global m */\n\nexport default class CoveragePage {\n oninit() {\n this.columns = 'locale';\n this.showAllFrontends = false;\n this.totalPercent = true;\n this.locale = [];\n\n const firstNonEnglishLocale = localesAsArray().find(locale => locale.key !== 'en');\n\n if (firstNonEnglishLocale) {\n this.locale = firstNonEnglishLocale.key;\n }\n }\n\n view(vnode) {\n let visibleFrontends = vnode.attrs.frontends.slice(0, 2);\n\n if (this.showAllFrontends) {\n visibleFrontends = vnode.attrs.frontends;\n }\n\n const {browseWithFilters} = vnode.attrs;\n\n return [\n m('.FoF-Linguist-Filters', [\n m('.ButtonGroup', [\n Button.component({\n className: 'Button' + (this.totalPercent ? ' active' : ''),\n onclick: () => {\n this.totalPercent = true;\n },\n }, app.translator.trans('fof-linguist.admin.coverage.total-options.percent')),\n Button.component({\n className: 'Button' + (this.totalPercent ? ' ' : ' active'),\n onclick: () => {\n this.totalPercent = false;\n },\n }, app.translator.trans('fof-linguist.admin.coverage.total-options.count')),\n ]),\n m('.ButtonGroup', [\n Button.component({\n className: 'Button' + (this.columns === 'locale' ? ' active' : ''),\n onclick: () => {\n this.columns = 'locale';\n },\n }, app.translator.trans('fof-linguist.admin.coverage.column-options.locale')),\n Button.component({\n className: 'Button' + (this.columns === 'namespace' ? ' active' : ''),\n onclick: () => {\n this.columns = 'namespace';\n this.showAllFrontends = false;\n },\n }, app.translator.trans('fof-linguist.admin.coverage.column-options.namespace')),\n ]),\n this.columns === 'namespace' ? m('.ButtonGroup', localesAsArray().map(\n locale => Button.component({\n className: 'Button' + (this.locale === locale.key ? ' active' : ''),\n onclick: () => {\n if (this.locale !== locale.key) {\n this.locale = locale.key;\n }\n },\n }, locale.name + ' (' + locale.key + ')')\n )) : null,\n ]),\n m('table.FoF-Linguist-Coverage', [\n m('thead', m('tr', [\n m('th', app.translator.trans('fof-linguist.admin.coverage.columns.namespace')),\n this.columns === 'locale' ? localesAsArray().map(locale => m('th', locale.name + ' (' + locale.key + ')')) : [\n this.showAllFrontends ? visibleFrontends.map(frontend => m('th', frontendLabel(frontend))) : [\n m('th', app.translator.trans('fof-linguist.admin.coverage.columns.all-except-admin')),\n m('th', frontendLabel('admin')),\n m('th', Button.component({\n className: 'Button',\n onclick: () => {\n this.showAllFrontends = true;\n },\n }, app.translator.trans('fof-linguist.admin.coverage.columns.all-frontends'))),\n ],\n ],\n ])),\n m('tbody', [\n this.columns === 'locale' ? m('tr', [\n m('td', [\n m('span.FoF-Linguist-Coverage-Extension-Icon.FoF-Linguist-Coverage-Namespace-Icon'),\n m('span.FoF-Linguist-Coverage-Extension-Title', app.translator.trans('fof-linguist.admin.coverage.all-namespaces')),\n ]),\n localesAsArray().map(locale => m('td', this.localeCoverage(browseWithFilters, locale.key))),\n ]) : null,\n vnode.attrs.namespaces.map(namespace => {\n return m('tr', [\n m('td', namespace.extension ? [\n m('span.FoF-Linguist-Coverage-Extension-Icon', {\n style: namespace.extension.icon,\n }, namespace.extension.icon ? icon(namespace.extension.icon.name) : ''),\n m('span.FoF-Linguist-Coverage-Extension-Title', namespace.extension.extra['flarum-extension'].title),\n ] : [\n m('span.FoF-Linguist-Coverage-Extension-Icon.FoF-Linguist-Coverage-Namespace-Icon'),\n m('span.FoF-Linguist-Coverage-Extension-Title', namespaceLabel(namespace.namespace)),\n ]),\n this.columns === 'locale' ? localesAsArray().map(locale => m('td', this.localeCoverage(browseWithFilters, locale.key, namespace.namespace))) : [\n this.showAllFrontends ?\n visibleFrontends.map(frontend => m('td', this.prefixCoverage(browseWithFilters, namespace.namespace, frontend))) : [\n m('td', this.prefixCoverage(browseWithFilters, namespace.namespace, '_all_except_admin')),\n m('td', this.prefixCoverage(browseWithFilters, namespace.namespace, 'admin')),\n ],\n ],\n ]);\n }),\n ]),\n ]),\n ];\n }\n\n prefixCoverage(browseWithFilters, namespace, frontend) {\n if (!this.locale) {\n return null;\n }\n\n return this.localeCoverage(browseWithFilters, this.locale, namespace, frontend);\n }\n\n localeCoverage(browseWithFilters, locale, namespace, frontend) {\n const stringKeys = app.store.all('fof-linguist-string-key').filter(key => {\n if (!namespace) {\n return true;\n }\n\n const parts = key.key().split('.');\n\n if (parts[0] !== namespace) {\n return false;\n }\n\n if (frontend === '_all_except_admin') {\n if (parts.length >= 2 && parts[1] === 'admin') {\n return false;\n }\n } else if (frontend && (parts.length < 2 || parts[1] !== frontend)) {\n return false;\n }\n\n return true;\n });\n\n if (stringKeys.length === 0) {\n return '-';\n }\n\n let customCount = 0;\n let originalCount = 0;\n\n stringKeys.forEach(stringKey => {\n const customString = app.store.all('fof-linguist-string').find(\n string => string.key() === stringKey.key() && string.locale() === locale\n );\n\n if (customString) {\n customCount++;\n } else if (stringKey.locales().hasOwnProperty(locale)) {\n originalCount++;\n }\n });\n\n const percent = Math.round(((customCount + originalCount) / stringKeys.length) * 100);\n\n let specialStyle;\n\n if (percent === 100) {\n specialStyle = 'full';\n } else if (percent < 5) {\n specialStyle = 'low';\n }\n\n let label;\n\n if (this.totalPercent) {\n label = app.translator.trans('fof-linguist.admin.coverage.count.percent', {\n percent: percent + '', // Keeps zero as string\n });\n } else {\n label = app.translator.trans('fof-linguist.admin.coverage.count.total', {\n translated: (customCount + originalCount) + '', // Keeps zero as string\n total: stringKeys.length,\n });\n }\n\n return m('.FoF-Linguist-Coverage-Progress-Wrap', [\n m('.FoF-Linguist-Progress', {\n className: specialStyle ? 'FoF-Linguist-Progress--' + specialStyle : '',\n }, [\n m('.FoF-Linguist-Progress-Bar', {\n style: {\n width: Math.max(percent, 5) + '%', // Always show the progress bar even if very close to 0\n },\n }),\n m('.FoF-Linguist-Progress-Label', label),\n m('.FoF-Linguist-Progress-More', app.translator.trans('fof-linguist.admin.coverage.count.details', {\n total: stringKeys.length,\n original: originalCount + '', // Cast to string to preserve zero\n custom: customCount + '',\n })),\n ]),\n Button.component({\n icon: 'fas fa-filter',\n className: 'Button Button--icon',\n onclick: () => {\n const options = {\n missingTranslationsInLocales: [locale],\n };\n\n if (namespace) {\n options.forExtension = namespace;\n }\n\n if (frontend) {\n options.frontend = frontend;\n }\n\n browseWithFilters(options);\n },\n title: app.translator.trans('fof-linguist.admin.coverage.apply-missing-filter'),\n }),\n ]);\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/components/Switch'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/components/LinkButton'];","import app from 'flarum/admin/app';\nimport Select from 'flarum/common/components/Select';\nimport Switch from 'flarum/common/components/Switch';\nimport LinkButton from 'flarum/common/components/LinkButton';\nimport localesAsArray from '../utils/localesAsArray';\nimport namespaceLabel from '../utils/namespaceLabel';\n\n/* global m */\n\nexport default class ExportPage {\n oninit() {\n this.locale = 'en';\n this.namespace = null;\n this.includeOriginals = false;\n this.includeAll = false;\n this.loading = false;\n this.output = '';\n\n this.fetchOutput();\n }\n\n view(vnode) {\n const localeOptions = {};\n\n localesAsArray().forEach(locale => {\n localeOptions[locale.key] = locale.name + ' (' + locale.key + ')';\n });\n\n localeOptions.all = app.translator.trans('fof-linguist.admin.export.locale-all')\n\n const namespaceOptions = {\n _all: app.translator.trans('fof-linguist.admin.export.namespace-all'),\n };\n\n vnode.attrs.namespaces.forEach(namespace => {\n if (namespace.extension) {\n namespaceOptions[namespace.namespace] = namespace.extension.extra['flarum-extension'].title;\n } else {\n namespaceOptions[namespace.namespace] = namespaceLabel(namespace.namespace);\n\n }\n });\n\n return [\n m('h2', app.translator.trans('fof-linguist.admin.export.title')),\n m('.Form-group', m('.Alert', app.translator.trans('fof-linguist.admin.export.warning'))),\n m('.Form-group', [\n m('label', app.translator.trans('fof-linguist.admin.export.locale')),\n Select.component({\n options: localeOptions,\n value: this.locale,\n onchange: value => {\n this.locale = value;\n\n this.fetchOutput();\n },\n }),\n ]),\n m('.Form-group', [\n m('label', app.translator.trans('fof-linguist.admin.export.namespace')),\n Select.component({\n options: namespaceOptions,\n value: this.namespace === null ? '_all' : this.namespace,\n onchange: value => {\n this.namespace = value === '_all' ? null : value;\n\n this.fetchOutput();\n },\n }),\n ]),\n m('.Form-group', [\n Switch.component({\n state: this.includeOriginals,\n onchange: value => {\n this.includeOriginals = value;\n\n this.fetchOutput();\n }\n }, app.translator.trans('fof-linguist.admin.export.include-originals')),\n ]),\n m('.Form-group', [\n Switch.component({\n state: this.includeAll,\n onchange: value => {\n this.includeAll = value;\n\n this.fetchOutput();\n }\n }, app.translator.trans('fof-linguist.admin.export.include-all')),\n ]),\n m('.Form-group', [\n m('label', [\n app.translator.trans('fof-linguist.admin.export.output'),\n ' ',\n LinkButton.component({\n className: 'Button Button--primary',\n href: this.exportUrl(),\n external: true,\n // If a namespace is selected, we use it as filename (language pack convention)\n // otherwise we use the locale as filename (extension convention)\n download: (this.namespace || this.locale) + '.yml',\n }, app.translator.trans('fof-linguist.admin.export.download')),\n ]),\n m('textarea.FormControl.FoF-Export-Textarea', {\n readonly: true,\n value: this.output,\n rows: 10,\n placeholder: this.loading ? app.translator.trans('fof-linguist.admin.export.output-loading') : app.translator.trans('fof-linguist.admin.export.output-empty'),\n }),\n ]),\n ];\n }\n\n exportUrl() {\n return app.forum.attribute('apiUrl') + '/fof/linguist/export?' + m.buildQueryString({\n locale: this.locale,\n namespace: this.namespace,\n includeOriginals: this.includeOriginals ? '1' : '0',\n includeAll: this.includeAll ? '1' : '0',\n });\n }\n\n fetchOutput() {\n this.loading = true;\n this.output = '';\n\n app.request({\n method: 'GET',\n url: this.exportUrl(),\n // Flarum doesn't support a raw to have the raw text response\n // So we'll encode the response with JSON so Flarum can parse if afterwards\n extract: raw => JSON.stringify(raw),\n }).then(output => {\n this.loading = false;\n this.output = output;\n m.redraw();\n }).catch(error => {\n this.loading = false;\n m.redraw();\n throw error;\n });\n }\n}\n","import app from 'flarum/admin/app';\nimport Button from 'flarum/common/components/Button';\nimport Select from 'flarum/common/components/Select';\nimport Switch from 'flarum/common/components/Switch';\nimport extractText from 'flarum/common/utils/extractText';\nimport localesAsArray from '../utils/localesAsArray';\n\n/* global m */\n\nexport default class ImportPage {\n oninit() {\n this.locale = 'en';\n this.overrideExisting = true;\n this.input = '';\n this.loading = false;\n }\n\n view() {\n const localeOptions = {};\n\n localesAsArray().forEach(locale => {\n localeOptions[locale.key] = locale.name + ' (' + locale.key + ')';\n });\n\n localeOptions.all = app.translator.trans('fof-linguist.admin.import.locale-all')\n\n return [\n m('h2', app.translator.trans('fof-linguist.admin.import.title')),\n m('.Form-group', [\n m('label', app.translator.trans('fof-linguist.admin.import.input')),\n m('textarea.FormControl', {\n value: this.input,\n oninput: event => {\n this.input = event.target.value;\n },\n rows: 10,\n placeholder: app.translator.trans('fof-linguist.admin.import.input-placeholder'),\n }),\n ]),\n m('.Form-group', [\n m('label', app.translator.trans('fof-linguist.admin.import.locale')),\n Select.component({\n options: localeOptions,\n value: this.locale,\n onchange: value => {\n this.locale = value;\n\n this.fetchOutput();\n },\n }),\n ]),\n m('.Form-group', [\n Switch.component({\n state: this.overrideExisting,\n onchange: value => {\n this.overrideExisting = value;\n }\n }, app.translator.trans('fof-linguist.admin.import.override-existing')),\n ]),\n m('.Form-group', Button.component({\n className: 'Button Button--primary',\n onclick: () => {\n this.loading = true;\n\n app.request({\n method: 'POST',\n url: app.forum.attribute('apiUrl') + '/fof/linguist/import',\n body: {\n input: this.input,\n locale: this.locale,\n ignoreExisting: !this.overrideExisting,\n },\n }).then(data => {\n this.loading = false;\n m.redraw();\n\n if (confirm(extractText(app.translator.trans(this.overrideExisting ? 'fof-linguist.admin.import.results' : 'fof-linguist.admin.import.results-with-ignore', {\n imported: data.imported + '', // Cast to string to preserve zeros\n ignored: data.ignored + '',\n identical: data.identical + '',\n })))) {\n window.location.reload();\n }\n }).catch(error => {\n this.loading = false;\n m.redraw();\n throw error;\n });\n },\n disabled: this.loading || !this.input,\n loading: this.loading,\n }, app.translator.trans('fof-linguist.admin.import.submit'))),\n ];\n }\n}\n","import app from 'flarum/admin/app';\nimport ExtensionPage from 'flarum/admin/components/ExtensionPage';\nimport LoadingIndicator from 'flarum/common/components/LoadingIndicator';\nimport StringsPage from './StringsPage';\nimport CoveragePage from './CoveragePage';\nimport ExportPage from './ExportPage';\nimport ImportPage from './ImportPage';\n\n/* global m */\n\nexport default class LinguistPage extends ExtensionPage {\n oninit(vnode) {\n super.oninit(vnode);\n\n this.tab = 'strings';\n this.ready = false;\n this.namespaces = []; // First level of translation keys. Usually an extension ID, but also core and validation\n this.frontends = [\n 'forum',\n 'admin',\n 'lib',\n 'ref',\n 'api',\n ]; // Second level of translation keys: forum, admin, ...\n this.initialBrowseFilters = {};\n\n Promise.all([\n app.request({\n method: 'GET',\n url: app.forum.attribute('apiUrl') + '/fof/linguist/strings',\n }).then(result => {\n app.store.pushPayload(result);\n }),\n app.request({\n method: 'GET',\n url: app.forum.attribute('apiUrl') + '/fof/linguist/string-keys',\n }).then(result => {\n const keys = app.store.pushPayload(result);\n\n const namespaces = [];\n\n keys.forEach(key => {\n const parts = key.key().split('.');\n\n const namespace = parts[0];\n\n if (['core', 'validation'].indexOf(namespace) === -1 && namespaces.indexOf(namespace) === -1) {\n namespaces.push(namespace);\n }\n\n if (parts.length > 1 && namespace !== 'validation') {\n const frontend = parts[1];\n\n if (this.frontends.indexOf(frontend) === -1) {\n this.frontends.push(frontend);\n }\n }\n });\n\n namespaces.sort();\n\n this.namespaces = [\n {\n namespace: 'core',\n },\n {\n namespace: 'validation',\n },\n ...namespaces.map(namespace => {\n // First we look if the namespace matches an extension ID, that's the most common naming\n let extension = app.data.extensions[namespace];\n\n // If that's unsuccessful, we'll look if the full package name was used as namespace\n if (!extension) {\n extension = Object.values(app.data.extensions).find(extension => {\n const packageNameWithDash = extension.name.replace('/', '-');\n\n return namespace === packageNameWithDash;\n });\n }\n\n return {\n namespace,\n extension,\n };\n }),\n ];\n }),\n ]).then(() => {\n this.ready = true;\n m.redraw();\n });\n }\n\n content() {\n return m('.ExtensionPage-settings', m('.container', [\n this.contentTab(),\n ]));\n }\n\n infoItems() {\n const items = super.infoItems();\n\n items.add('linguist-tabs', m('ul.FoF-Linguist-Tabs', [\n m('li', m('a', {\n className: this.tab === 'strings' ? 'active' : '',\n onclick: () => {\n this.tab = 'strings';\n },\n }, app.translator.trans('fof-linguist.admin.tabs.strings'))),\n m('li', m('a', {\n className: this.tab === 'coverage' ? 'active' : '',\n onclick: () => {\n this.tab = 'coverage';\n },\n }, app.translator.trans('fof-linguist.admin.tabs.coverage'))),\n m('li', m('a', {\n className: this.tab === 'export' ? 'active' : '',\n onclick: () => {\n this.tab = 'export';\n },\n }, app.translator.trans('fof-linguist.admin.tabs.export'))),\n m('li', m('a', {\n className: this.tab === 'import' ? 'active' : '',\n onclick: () => {\n this.tab = 'import';\n },\n }, app.translator.trans('fof-linguist.admin.tabs.import'))),\n ]), 100);\n\n return items;\n }\n\n contentTab() {\n if (!this.ready) {\n return LoadingIndicator.component();\n }\n\n switch (this.tab) {\n case 'strings':\n return m(StringsPage, {\n namespaces: this.namespaces,\n frontends: this.frontends,\n initialBrowseFilters: this.initialBrowseFilters,\n });\n case 'coverage':\n return m(CoveragePage, {\n namespaces: this.namespaces,\n frontends: this.frontends,\n browseWithFilters: filters => {\n this.initialBrowseFilters = filters;\n this.tab = 'strings';\n },\n });\n case 'export':\n return m(ExportPage, {\n namespaces: this.namespaces,\n });\n case 'import':\n return m(ImportPage);\n }\n\n return null;\n }\n}\n","import StringKey from './StringKey';\nimport StringLocale from './StringLocale';\n\nexport const components = {\n StringKey,\n StringLocale,\n};\n","import StringKey from './StringKey';\nimport TextString from './TextString';\n\nexport const models = {\n StringKey,\n TextString,\n};\n","import CoveragePage from './CoveragePage';\nimport ExportPage from './ExportPage';\nimport ImportPage from './ImportPage';\nimport LinguistPage from './LinguistPage';\nimport StringsPage from './StringsPage';\n\nexport const pages = {\n CoveragePage,\n ExportPage,\n ImportPage,\n LinguistPage,\n StringsPage,\n};\n","import booleanCheck from './booleanCheck';\nimport frontendLabel from './frontendLabel';\nimport highlightMithril from './highlightMithril';\nimport localesAsArray from './localesAsArray';\nimport namespaceLabel from './namespaceLabel';\n\nexport const utils = {\n booleanCheck,\n frontendLabel,\n highlightMithril,\n localesAsArray,\n namespaceLabel,\n};\n","import app from 'flarum/admin/app';\nimport StringKey from './models/StringKey';\nimport TextString from './models/TextString';\nimport LinguistPage from './pages/LinguistPage';\n\nexport * from './components';\nexport * from './models';\nexport * from './pages';\nexport * from './utils';\n\napp.initializers.add('fof-linguist', app => {\n app.store.models['fof-linguist-string-key'] = StringKey;\n app.store.models['fof-linguist-string'] = TextString;\n\n app.extensionData.for('fof-linguist').registerPage(LinguistPage);\n});\n"],"names":["__webpack_require__","module","getter","__esModule","d","a","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","flarum","core","compat","_setPrototypeOf","p","setPrototypeOf","bind","__proto__","_inheritsLoose","subClass","superClass","create","constructor","StringKey","Model","locales","TextString","locale","apiEndpoint","this","exists","data","id","englishFound","app","push","name","unshift","HIGHLIGHT_DELIMITER","string","highlight","lowercaseHighliht","toLowerCase","regex","RegExp","replace","split","map","text","m","StringLocale","oninit","vnode","stringKey","attrs","localeKey","originalString","find","dirty","processing","originalHasNewLine","keys","some","indexOf","inputType","view","placeholderText","localeName","className","title","oninput","event","target","disabled","highlightMithril","actions","onchange","toArray","items","ItemList","add","Button","type","loading","onclick","saveString","deleteString","attributes","save","then","redraw","err","localesAsArray","namespace","frontend","operation","booleans","reduce","b","StringsPage","numberOfResultsToShow","filters","assign","search","withOwnTranslations","missingTranslationsNegation","missingTranslationsType","missingTranslationsOperation","missingTranslationsInLocales","forExtension","initialBrowseFilters","results","applyFilters","slice","cacheClearInstructions","placeholder","icon","Dropdown","buttonClassName","label","namespaces","extension","extra","namespaceLabel","frontends","frontendLabel","length","stopPropagation","Select","options","without","with","any","original","own","or","and","filter","strings","confirm","extractText","count","LoadingModal","Promise","all","window","location","reload","shown","total","keysWithCustomTranslations","keysWithCustomTranslationsIn","forEach","lowercaseSearch","hasOriginalTranslation","booleanCheck","hasOwnTranslation","matchesType","parts","Alert","dismissible","controls","method","url","CoveragePage","columns","showAllFrontends","totalPercent","firstNonEnglishLocale","visibleFrontends","browseWithFilters","localeCoverage","style","prefixCoverage","stringKeys","customCount","originalCount","specialStyle","percent","Math","round","translated","width","max","custom","ExportPage","includeOriginals","includeAll","output","fetchOutput","localeOptions","namespaceOptions","_all","Switch","state","LinkButton","href","exportUrl","external","download","readonly","rows","buildQueryString","extract","raw","JSON","stringify","error","ImportPage","overrideExisting","input","body","ignoreExisting","imported","ignored","identical","LinguistPage","tab","ready","result","sort","values","packageNameWithDash","content","contentTab","infoItems","LoadingIndicator","ExtensionPage","components","models","pages","utils","store","extensionData","registerPage"],"sourceRoot":""} \ No newline at end of file +{"version":3,"file":"admin.js","mappings":"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","sources":["webpack://@fof/linguist/webpack/bootstrap","webpack://@fof/linguist/webpack/runtime/compat get default export","webpack://@fof/linguist/webpack/runtime/define property getters","webpack://@fof/linguist/webpack/runtime/hasOwnProperty shorthand","webpack://@fof/linguist/webpack/runtime/make namespace object","webpack://@fof/linguist/external root \"flarum.core.compat['admin/app']\"","webpack://@fof/linguist/./node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js","webpack://@fof/linguist/./node_modules/@babel/runtime/helpers/esm/inheritsLoose.js","webpack://@fof/linguist/external root \"flarum.core.compat['common/Model']\"","webpack://@fof/linguist/./src/admin/models/StringKey.js","webpack://@fof/linguist/./src/admin/models/TextString.js","webpack://@fof/linguist/external root \"flarum.core.compat['admin/components/ExtensionPage']\"","webpack://@fof/linguist/external root \"flarum.core.compat['common/components/LoadingIndicator']\"","webpack://@fof/linguist/external root \"flarum.core.compat['common/components/Button']\"","webpack://@fof/linguist/external root \"flarum.core.compat['common/components/Dropdown']\"","webpack://@fof/linguist/external root \"flarum.core.compat['common/components/Select']\"","webpack://@fof/linguist/external root \"flarum.core.compat['common/components/Alert']\"","webpack://@fof/linguist/external root \"flarum.core.compat['admin/components/LoadingModal']\"","webpack://@fof/linguist/external root \"flarum.core.compat['common/utils/extractText']\"","webpack://@fof/linguist/./src/admin/utils/localesAsArray.js","webpack://@fof/linguist/external root \"flarum.core.compat['common/utils/ItemList']\"","webpack://@fof/linguist/./src/admin/utils/highlightMithril.js","webpack://@fof/linguist/./src/admin/components/StringLocale.js","webpack://@fof/linguist/./src/admin/components/StringKey.js","webpack://@fof/linguist/./src/admin/utils/namespaceLabel.js","webpack://@fof/linguist/./src/admin/utils/frontendLabel.js","webpack://@fof/linguist/./src/admin/utils/booleanCheck.js","webpack://@fof/linguist/./src/admin/pages/StringsPage.js","webpack://@fof/linguist/external root \"flarum.core.compat['common/helpers/icon']\"","webpack://@fof/linguist/./src/admin/pages/CoveragePage.js","webpack://@fof/linguist/external root \"flarum.core.compat['common/components/Switch']\"","webpack://@fof/linguist/external root \"flarum.core.compat['common/components/LinkButton']\"","webpack://@fof/linguist/./src/admin/pages/ExportPage.js","webpack://@fof/linguist/./src/admin/pages/ImportPage.js","webpack://@fof/linguist/./src/admin/pages/LinguistPage.js","webpack://@fof/linguist/./src/admin/components/index.js","webpack://@fof/linguist/./src/admin/models/index.js","webpack://@fof/linguist/./src/admin/pages/index.js","webpack://@fof/linguist/./src/admin/utils/index.js","webpack://@fof/linguist/./src/admin/index.js"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['admin/app'];","export default function _setPrototypeOf(o, p) {\n _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n return _setPrototypeOf(o, p);\n}","import setPrototypeOf from \"./setPrototypeOf.js\";\nexport default function _inheritsLoose(subClass, superClass) {\n subClass.prototype = Object.create(superClass.prototype);\n subClass.prototype.constructor = subClass;\n setPrototypeOf(subClass, superClass);\n}","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/Model'];","import Model from 'flarum/common/Model';\n\nexport default class StringKey extends Model {\n key = Model.attribute('key');\n locales = Model.attribute('locales');\n}\n","import Model from 'flarum/common/Model';\n\nexport default class TextString extends Model {\n key = Model.attribute('key');\n locale = Model.attribute('locale');\n value = Model.attribute('value');\n\n apiEndpoint() {\n return '/fof/linguist/strings' + (this.exists ? '/' + this.data.id : '');\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['admin/components/ExtensionPage'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/components/LoadingIndicator'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/components/Button'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/components/Dropdown'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/components/Select'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/components/Alert'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['admin/components/LoadingModal'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/utils/extractText'];","import app from 'flarum/admin/app';\n\nexport default function () {\n let locales = [];\n\n let englishFound = false;\n\n for (let key in app.data.locales) {\n if (!app.data.locales.hasOwnProperty(key)) {\n continue;\n }\n\n if (key === 'en') {\n englishFound = true;\n }\n\n locales.push({\n key,\n name: app.data.locales[key],\n });\n }\n\n // Always show English for the following reasons:\n // It's the fallback locale, so the translations are always active\n // It's the bundled locale for most extensions, so it makes sense to have access to it as reference\n if (!englishFound) {\n locales.unshift({\n key: 'en',\n // Hard-coded to the same value as in flarum/lang-english composer.json\n // Since other locale names won't be translated to the current language either it doesn't make sense to use a translation\n name: 'English',\n });\n }\n\n return locales;\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/utils/ItemList'];","/* global m */\n\nconst HIGHLIGHT_DELIMITER = '';\n\n// Takes a string and highlight a keyword with a span with mithril template\n// The output will be an array if a keyword is given\nexport default function (string, highlight) {\n if (!highlight) {\n return string;\n }\n\n const lowercaseHighliht = highlight.toLowerCase();\n\n // Regex to match the highlighted work in a case-insensitive manner\n const regex = new RegExp(lowercaseHighliht.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'), 'i');\n\n return string\n .replace(regex, HIGHLIGHT_DELIMITER + '$&' + HIGHLIGHT_DELIMITER)\n .split(HIGHLIGHT_DELIMITER)\n .map(text => {\n if (text.toLowerCase() === lowercaseHighliht) {\n return m('span.FoF-Linguist-Highlight', text);\n }\n\n return text;\n });\n}\n","import app from 'flarum/admin/app';\nimport ItemList from 'flarum/common/utils/ItemList';\nimport Button from 'flarum/common/components/Button';\nimport highlightMithril from '../utils/highlightMithril';\n\n/* global m */\n\nexport default class StringLocale {\n oninit(vnode) {\n this.stringKey = vnode.attrs.stringKey;\n this.locale = vnode.attrs.locale;\n this.localeKey = this.locale ? this.locale.key : null;\n this.originalString = this.localeKey && this.stringKey.locales().hasOwnProperty(this.localeKey) ? this.stringKey.locales()[this.localeKey] : null;\n\n this.string = app.store.all('fof-linguist-string').find(\n string => string.key() === this.stringKey.key() && string.locale() === this.localeKey\n );\n\n this.value = this.string ? this.string.value() : '';\n this.dirty = false;\n this.processing = false;\n\n // We check whether any original translation in any language has a newline\n // By not hard-coding to English, this should work pretty well even if the fallback locale is modified,\n // or if a text happens to not be available in the fallback language\n const originalHasNewLine = Object.keys(this.stringKey.locales()).some(key => this.stringKey.locales()[key].indexOf('\\n') !== -1);\n\n this.inputType = 'input';\n\n // We will enable multi-line editing if the original has a newline, or if the current custom value already has one\n if (originalHasNewLine || this.value.indexOf('\\n') !== -1) {\n this.inputType = 'textarea';\n }\n }\n\n view(vnode) {\n const placeholderText = this.originalString ? this.originalString : '(' + app.translator.trans('fof-linguist.admin.placeholder.' + (this.localeKey ? 'not-translated' : 'all-locales')) + ')';\n\n return m('.FoF-Linguist-Locale', [\n m('label.FoF-Linguist-Label', this.localeName()),\n m('.FoF-Linguist-Field', {\n className: (this.value ? 'FoF-Linguist-Field--with-value' : '') + (this.originalString ? ' FoF-Linguist-Field--with-original-string' : ''),\n title: placeholderText,\n }, [\n m('.FoF-Linguist-Field-Wrap', [\n m(this.inputType, {\n className: 'FormControl FoF-Linguist-Input',\n value: this.value,\n oninput: event => {\n this.value = event.target.value;\n this.dirty = true;\n\n // Remove dirty state if the user erased his text without saving\n if (!this.value && !this.string) {\n this.dirty = false;\n }\n },\n disabled: this.processing,\n }),\n m('.FoF-Linguist-Placeholder', [\n m('span.FoF-Linguist-Placeholder-Hint', app.translator.trans('fof-linguist.admin.placeholder.hint')),\n ' ',\n m('span', this.originalString ? highlightMithril(placeholderText, vnode.attrs.highlight) : placeholderText),\n ]),\n ]),\n ]),\n m('.FoF-Linguist-Controls', this.actions(vnode.attrs.onchange).toArray()),\n ]);\n }\n\n localeName() {\n if (this.locale) {\n return [this.locale.name + ' (', m('code', this.locale.key), ')'];\n } else {\n return app.translator.trans('fof-linguist.admin.locales.all');\n }\n }\n\n actions(onchange) {\n const items = new ItemList();\n\n items.add('apply', Button.component({\n type: 'button',\n className: 'Button Button--primary',\n loading: this.processing,\n disabled: !this.dirty,\n onclick: () => {\n this.saveString(onchange);\n },\n }, app.translator.trans('fof-linguist.admin.buttons.apply')));\n\n items.add('reset', Button.component({\n type: 'button',\n className: 'Button',\n loading: this.processing,\n disabled: !this.dirty && !this.string,\n onclick: () => {\n this.deleteString(onchange);\n },\n }, app.translator.trans('fof-linguist.admin.buttons.reset')));\n\n if (this.originalString) {\n items.add('copy-original', Button.component({\n type: 'button',\n className: 'Button',\n loading: this.processing,\n onclick: () => {\n this.value = this.originalString;\n this.dirty = true;\n },\n }, app.translator.trans('fof-linguist.admin.buttons.copy-original')));\n }\n\n return items;\n }\n\n saveString(onchange) {\n if (!this.value) {\n this.deleteString(onchange);\n\n return;\n }\n\n if (!this.string) {\n this.string = app.store.createRecord('fof-linguist-string', {\n attributes: {\n key: this.stringKey.key(),\n locale: this.localeKey,\n value: '',\n },\n });\n }\n\n this.string.data.attributes.value = this.value;\n\n if (!this.string.locale()) delete this.string.data.attributes.locale;\n\n this.processing = true;\n\n this.string.save(this.string.data.attributes).then(() => {\n this.processing = false;\n this.dirty = false;\n\n onchange();\n\n m.redraw();\n }).catch(err => {\n this.processing = false;\n\n throw err;\n });\n }\n\n deleteString(onchange) {\n if (this.string) {\n this.processing = true;\n\n this.string.delete().then(() => {\n this.processing = false;\n this.dirty = false;\n\n this.string = null;\n this.value = '';\n\n onchange();\n\n m.redraw();\n }).catch(err => {\n this.processing = false;\n\n throw err;\n });\n } else {\n this.value = '';\n this.dirty = false;\n }\n }\n}\n","import StringLocale from '../components/StringLocale';\nimport localesAsArray from '../utils/localesAsArray';\nimport highlightMithril from '../utils/highlightMithril';\n\n/* global m */\n\nexport default class StringKey {\n view(vnode) {\n const {\n stringKey,\n highlight,\n onchange,\n } = vnode.attrs;\n\n return m('.FoF-Linguist-Key', [\n m('.FoF-Linguist-Key-Code', m('code', highlightMithril(stringKey.key(), highlight))),\n m('.FoF-Linguist-Locales', [\n ...localesAsArray().map(locale => m(StringLocale, {\n key: locale.key,\n locale,\n stringKey,\n highlight,\n onchange,\n })),\n m(StringLocale, {\n key: 'all',\n locale: null,\n stringKey,\n highlight,\n onchange,\n }),\n ]),\n ]);\n }\n}\n","import app from 'flarum/admin/app';\n\nexport default function (namespace) {\n const translation = app.translator.translations['fof-linguist.admin.known-namespace.' + namespace];\n\n if (translation) {\n return translation;\n }\n\n return namespace;\n}\n","import app from 'flarum/admin/app';\n\nexport default function (frontend) {\n const translation = app.translator.translations['fof-linguist.admin.known-frontend.' + frontend];\n\n if (translation) {\n return translation;\n }\n\n return frontend;\n}\n","export default function (operation, booleans) {\n return booleans.reduce((a, b) => {\n if (a === 'start') {\n return b;\n }\n\n if (operation === 'or') {\n return a || b;\n }\n\n return a && b;\n }, 'start');\n}\n","import app from 'flarum/admin/app';\nimport Button from 'flarum/common/components/Button';\nimport Dropdown from 'flarum/common/components/Dropdown';\nimport Select from 'flarum/common/components/Select';\nimport Alert from 'flarum/common/components/Alert';\nimport LoadingModal from 'flarum/admin/components/LoadingModal';\nimport extractText from 'flarum/common/utils/extractText';\nimport localesAsArray from '../utils/localesAsArray';\nimport StringKey from '../components/StringKey';\nimport namespaceLabel from '../utils/namespaceLabel';\nimport frontendLabel from '../utils/frontendLabel';\nimport booleanCheck from '../utils/booleanCheck';\n\n/* global m */\n\nconst RESULTS_PER_PAGE = 20;\n\nexport default class StringsPage {\n oninit(vnode) {\n this.numberOfResultsToShow = RESULTS_PER_PAGE;\n\n this.filters = Object.assign({\n search: '',\n withOwnTranslations: false,\n missingTranslationsNegation: 'without',\n missingTranslationsType: 'any',\n missingTranslationsOperation: 'or',\n missingTranslationsInLocales: [],\n forExtension: null,\n frontend: null,\n }, vnode.attrs.initialBrowseFilters || {});\n\n this.results = [];\n\n this.applyFilters();\n }\n\n view(vnode) {\n const keys = this.results.slice(0, this.numberOfResultsToShow);\n\n return [\n // Additional divs are used to reduce Mithril redraws as much as possible when the conditional components appear\n m('div', this.cacheClearInstructions()),\n m('.FoF-Linguist-Filters', [\n m('input.FormControl', {\n value: this.filters.search,\n oninput: event => {\n this.filters.search = event.target.value;\n this.applyFilters();\n },\n placeholder: app.translator.trans('fof-linguist.admin.filters.search'),\n }),\n Button.component({\n className: 'Button' + (this.filters.withOwnTranslations ? ' FoF-Linguist-Filter--Selected' : ''),\n icon: `far fa-${this.filters.withOwnTranslations ? 'check-square' : 'square'}`,\n onclick: () => {\n this.filters.withOwnTranslations = !this.filters.withOwnTranslations;\n this.applyFilters();\n },\n }, app.translator.trans('fof-linguist.admin.filters.with-own-translations')),\n Dropdown.component({\n buttonClassName: 'Button' + (this.filters.forExtension ? ' FoF-Linguist-Filter--Selected' : ''),\n label: app.translator.trans('fof-linguist.admin.filters.for-extension'),\n }, vnode.attrs.namespaces.map(\n namespace => Button.component({\n className: 'Button',\n icon: `far fa-${this.filters.forExtension === namespace.namespace ? 'dot-circle' : 'circle'}`,\n onclick: () => {\n if (this.filters.forExtension === namespace.namespace) {\n this.filters.forExtension = null;\n } else {\n this.filters.forExtension = namespace.namespace;\n }\n\n this.applyFilters();\n },\n }, namespace.extension ? namespace.extension.extra['flarum-extension'].title : namespaceLabel(namespace.namespace))\n )),\n Dropdown.component({\n buttonClassName: 'Button' + (this.filters.frontend ? ' FoF-Linguist-Filter--Selected' : ''),\n label: app.translator.trans('fof-linguist.admin.filters.frontend'),\n }, [\n '_all_except_admin',\n ...vnode.attrs.frontends,\n ].map(\n frontend => Button.component({\n className: 'Button',\n icon: `far fa-${this.filters.frontend === frontend ? 'dot-circle' : 'circle'}`,\n onclick: () => {\n if (this.filters.frontend === frontend) {\n this.filters.frontend = null;\n } else {\n this.filters.frontend = frontend;\n }\n\n this.applyFilters();\n },\n }, frontend === '_all_except_admin' ? app.translator.trans('fof-linguist.admin.filters.frontend-all-except-admin') : frontendLabel(frontend))\n )),\n Dropdown.component({\n buttonClassName: 'Button' + (this.filters.missingTranslationsInLocales.length ? ' FoF-Linguist-Filter--Selected' : ''),\n label: app.translator.trans('fof-linguist.admin.filters.missing'),\n }, [\n m('.FoF-Linguist-Missing-Filter', {\n onclick(event) {\n // Prevent closing the dropdown\n event.stopPropagation();\n },\n }, [\n Select.component({\n value: this.filters.missingTranslationsNegation,\n onchange: value => {\n this.filters.missingTranslationsNegation = value;\n\n if (this.filters.missingTranslationsInLocales.length) {\n this.applyFilters();\n }\n },\n options: {\n without: app.translator.trans('fof-linguist.admin.filters.negation-options.without'),\n with: app.translator.trans('fof-linguist.admin.filters.negation-options.with'),\n },\n }),\n Select.component({\n value: this.filters.missingTranslationsType,\n onchange: value => {\n this.filters.missingTranslationsType = value;\n\n if (this.filters.missingTranslationsInLocales.length) {\n this.applyFilters();\n }\n },\n options: {\n any: app.translator.trans('fof-linguist.admin.filters.type-options.any'),\n original: app.translator.trans('fof-linguist.admin.filters.type-options.original'),\n own: app.translator.trans('fof-linguist.admin.filters.type-options.own'),\n },\n }),\n m('p', app.translator.trans('fof-linguist.admin.filters.missing-middle-label')),\n Select.component({\n value: this.filters.missingTranslationsOperation,\n onchange: value => {\n this.filters.missingTranslationsOperation = value;\n\n if (this.filters.missingTranslationsInLocales.length) {\n this.applyFilters();\n }\n },\n options: {\n or: app.translator.trans('fof-linguist.admin.filters.operation-options.or'),\n and: app.translator.trans('fof-linguist.admin.filters.operation-options.and'),\n },\n }),\n ]),\n ...localesAsArray().map(\n locale => Button.component({\n className: 'Button',\n icon: `far fa-${this.filters.missingTranslationsInLocales.indexOf(locale.key) !== -1 ? 'check-square' : 'square'}`,\n onclick: () => {\n if (this.filters.missingTranslationsInLocales.indexOf(locale.key) !== -1) {\n this.filters.missingTranslationsInLocales = this.filters.missingTranslationsInLocales.filter(key => key !== locale.key);\n } else {\n this.filters.missingTranslationsInLocales.push(locale.key);\n }\n\n this.applyFilters();\n },\n }, locale.name + ' (' + locale.key + ')')\n ),\n ]),\n Dropdown.component({\n buttonClassName: 'Button',\n label: app.translator.trans('fof-linguist.admin.filters.mass-edit'),\n }, [\n Button.component({\n icon: 'far fa-clone',\n className: 'Button',\n onclick: () => {\n const strings = app.store.all('fof-linguist-string').filter(string => {\n const key = app.store.getById('fof-linguist-string-key', string.key());\n\n return key && key.locales()[string.locale()] === string.value();\n });\n\n if (confirm(extractText(app.translator.trans('fof-linguist.admin.buttons.delete-redundant-confirm', {\n count: strings.length + '',\n })))) {\n if (strings.length === 0) {\n return;\n }\n\n app.modal.show(LoadingModal);\n\n Promise.all(strings.map(string => string.delete())).then(() => {\n window.location.reload();\n });\n }\n },\n }, app.translator.trans('fof-linguist.admin.buttons.delete-redundant')),\n Button.component({\n icon: 'fas fa-trash',\n className: 'Button',\n onclick: () => {\n const strings = app.store.all('fof-linguist-string');\n\n if (confirm(extractText(app.translator.trans('fof-linguist.admin.buttons.delete-all-confirm', {\n count: strings.length + '',\n })))) {\n if (strings.length === 0) {\n return;\n }\n\n app.modal.show(LoadingModal);\n\n Promise.all(strings.map(string => string.delete())).then(() => {\n window.location.reload();\n });\n }\n },\n }, app.translator.trans('fof-linguist.admin.buttons.delete-all')),\n ]),\n ]),\n m('div', keys.map(stringKey => m(StringKey, {\n key: stringKey.id(),\n stringKey,\n highlight: this.filters.search,\n onchange: () => {\n // We use the setting and not a local variable because we need to preserve state\n // if we navigate away and back to the Linguist page without refreshing the admin panel\n app.data.settings['fof.linguist.should-clear-cache'] = '1';\n },\n }))),\n m('.FoF-Linguist-Results', [\n app.translator.trans('fof-linguist.admin.filters.results', {\n shown: keys.length + '', // cast to string otherwise number isn't displayed\n total: this.results.length + '',\n }),\n ' ',\n (this.results.length > keys.length ? Button.component({\n className: 'Button',\n onclick: () => {\n this.numberOfResultsToShow += RESULTS_PER_PAGE;\n },\n }, app.translator.trans('fof-linguist.admin.buttons.load-more')) : null),\n ]),\n ];\n }\n\n applyFilters() {\n this.numberOfResultsToShow = RESULTS_PER_PAGE;\n\n const keysWithCustomTranslations = app.store.all('fof-linguist-string').map(string => string.key());\n\n const keysWithCustomTranslationsIn = {};\n localesAsArray().forEach(locale => {\n keysWithCustomTranslationsIn[locale.key] = app.store.all('fof-linguist-string')\n .filter(string => string.locale() === locale.key)\n .map(string => string.key());\n });\n\n let lowercaseSearch = '';\n\n if (this.filters.search) {\n lowercaseSearch = this.filters.search.toLowerCase();\n }\n\n this.results = app.store.all('fof-linguist-string-key').filter(key => {\n if (this.filters.withOwnTranslations && keysWithCustomTranslations.indexOf(key.key()) === -1) {\n return false;\n }\n\n if (this.filters.missingTranslationsInLocales.length) {\n let operation = this.filters.missingTranslationsOperation;\n\n // Because the whole operation is reversed at the end based on with or without,\n // we actually need to make the opposite boolean computation on the \"has\" variables\n if (this.filters.missingTranslationsNegation === 'without') {\n operation = operation === 'or' ? 'and' : 'or';\n }\n\n const hasOriginalTranslation = booleanCheck(operation, this.filters.missingTranslationsInLocales.map(locale => {\n return key.locales().hasOwnProperty(locale);\n }));\n const hasOwnTranslation = booleanCheck(operation, this.filters.missingTranslationsInLocales.map(locale => {\n return keysWithCustomTranslationsIn[locale].indexOf(key.key()) !== -1;\n }));\n\n let matchesType = false;\n\n switch (this.filters.missingTranslationsType) {\n case 'any':\n matchesType = hasOriginalTranslation || hasOwnTranslation;\n break;\n case 'original':\n matchesType = hasOriginalTranslation;\n break;\n case 'own':\n matchesType = hasOwnTranslation;\n break;\n }\n\n if (this.filters.missingTranslationsNegation === 'without') {\n matchesType = !matchesType;\n }\n\n if (!matchesType) {\n return false;\n }\n }\n\n if (this.filters.forExtension) {\n if (key.key().indexOf(this.filters.forExtension + '.') !== 0) {\n return false;\n }\n }\n\n if (this.filters.frontend) {\n const parts = key.key().split('.');\n\n if (this.filters.frontend === '_all_except_admin') {\n // We will keep everything that isn't admin, including if it's a single level deep\n if (parts.length >= 2 && parts[1] === 'admin') {\n return false;\n }\n } else {\n // Keep only parts with 2 levels or more where second level matches frontend\n if (parts.length < 2 || parts[1] !== this.filters.frontend) {\n return false;\n }\n }\n }\n\n if (lowercaseSearch) {\n if (key.key().toLowerCase().indexOf(lowercaseSearch) !== -1) {\n return true;\n }\n\n const locales = key.locales();\n\n for (let locale in locales) {\n if (locales.hasOwnProperty(locale) && locales[locale].toLowerCase().indexOf(lowercaseSearch) !== -1) {\n return true;\n }\n }\n\n return false;\n }\n\n return true;\n });\n\n m.redraw();\n }\n\n cacheClearInstructions() {\n // If debug is enabled, we hide the message here because even if we stop setting the flag,\n // an older flag might still be present from before debug mode was enabled\n if (app.data.debugEnabled) {\n return null;\n }\n\n // Check for flag that says cache should be cleared\n // This value is set both server-side and client-side in the onchange code above for immediate effect\n if (app.data.settings['fof.linguist.should-clear-cache'] !== '1') {\n return null;\n }\n\n return Alert.component({\n dismissible: false,\n controls: [Button.component({\n className: 'Button Button--link',\n onclick() {\n // Same logic as in core StatusWidget\n app.modal.show(LoadingModal);\n\n app.request({\n method: 'DELETE',\n url: app.forum.attribute('apiUrl') + '/cache',\n }).then(() => window.location.reload());\n },\n }, app.translator.trans('fof-linguist.admin.clear-cache.button'))],\n }, app.translator.trans('fof-linguist.admin.clear-cache.text'));\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/helpers/icon'];","import app from 'flarum/admin/app';\nimport Button from 'flarum/common/components/Button';\nimport icon from 'flarum/common/helpers/icon';\nimport localesAsArray from '../utils/localesAsArray';\nimport namespaceLabel from '../utils/namespaceLabel';\nimport frontendLabel from '../utils/frontendLabel';\n\n/* global m */\n\nexport default class CoveragePage {\n oninit() {\n this.columns = 'locale';\n this.showAllFrontends = false;\n this.totalPercent = true;\n this.locale = [];\n\n const firstNonEnglishLocale = localesAsArray().find(locale => locale.key !== 'en');\n\n if (firstNonEnglishLocale) {\n this.locale = firstNonEnglishLocale.key;\n }\n }\n\n view(vnode) {\n let visibleFrontends = vnode.attrs.frontends.slice(0, 2);\n\n if (this.showAllFrontends) {\n visibleFrontends = vnode.attrs.frontends;\n }\n\n const {browseWithFilters} = vnode.attrs;\n\n return [\n m('.FoF-Linguist-Filters', [\n m('.ButtonGroup', [\n Button.component({\n className: 'Button' + (this.totalPercent ? ' active' : ''),\n onclick: () => {\n this.totalPercent = true;\n },\n }, app.translator.trans('fof-linguist.admin.coverage.total-options.percent')),\n Button.component({\n className: 'Button' + (this.totalPercent ? ' ' : ' active'),\n onclick: () => {\n this.totalPercent = false;\n },\n }, app.translator.trans('fof-linguist.admin.coverage.total-options.count')),\n ]),\n m('.ButtonGroup', [\n Button.component({\n className: 'Button' + (this.columns === 'locale' ? ' active' : ''),\n onclick: () => {\n this.columns = 'locale';\n },\n }, app.translator.trans('fof-linguist.admin.coverage.column-options.locale')),\n Button.component({\n className: 'Button' + (this.columns === 'namespace' ? ' active' : ''),\n onclick: () => {\n this.columns = 'namespace';\n this.showAllFrontends = false;\n },\n }, app.translator.trans('fof-linguist.admin.coverage.column-options.namespace')),\n ]),\n this.columns === 'namespace' ? m('.ButtonGroup', localesAsArray().map(\n locale => Button.component({\n className: 'Button' + (this.locale === locale.key ? ' active' : ''),\n onclick: () => {\n if (this.locale !== locale.key) {\n this.locale = locale.key;\n }\n },\n }, locale.name + ' (' + locale.key + ')')\n )) : null,\n ]),\n m('table.FoF-Linguist-Coverage', [\n m('thead', m('tr', [\n m('th', app.translator.trans('fof-linguist.admin.coverage.columns.namespace')),\n this.columns === 'locale' ? localesAsArray().map(locale => m('th', locale.name + ' (' + locale.key + ')')) : [\n this.showAllFrontends ? visibleFrontends.map(frontend => m('th', frontendLabel(frontend))) : [\n m('th', app.translator.trans('fof-linguist.admin.coverage.columns.all-except-admin')),\n m('th', frontendLabel('admin')),\n m('th', Button.component({\n className: 'Button',\n onclick: () => {\n this.showAllFrontends = true;\n },\n }, app.translator.trans('fof-linguist.admin.coverage.columns.all-frontends'))),\n ],\n ],\n ])),\n m('tbody', [\n this.columns === 'locale' ? m('tr', [\n m('td', [\n m('span.FoF-Linguist-Coverage-Extension-Icon.FoF-Linguist-Coverage-Namespace-Icon'),\n m('span.FoF-Linguist-Coverage-Extension-Title', app.translator.trans('fof-linguist.admin.coverage.all-namespaces')),\n ]),\n localesAsArray().map(locale => m('td', this.localeCoverage(browseWithFilters, locale.key))),\n ]) : null,\n vnode.attrs.namespaces.map(namespace => {\n return m('tr', [\n m('td', namespace.extension ? [\n m('span.FoF-Linguist-Coverage-Extension-Icon', {\n style: namespace.extension.icon,\n }, namespace.extension.icon ? icon(namespace.extension.icon.name) : ''),\n m('span.FoF-Linguist-Coverage-Extension-Title', namespace.extension.extra['flarum-extension'].title),\n ] : [\n m('span.FoF-Linguist-Coverage-Extension-Icon.FoF-Linguist-Coverage-Namespace-Icon'),\n m('span.FoF-Linguist-Coverage-Extension-Title', namespaceLabel(namespace.namespace)),\n ]),\n this.columns === 'locale' ? localesAsArray().map(locale => m('td', this.localeCoverage(browseWithFilters, locale.key, namespace.namespace))) : [\n this.showAllFrontends ?\n visibleFrontends.map(frontend => m('td', this.prefixCoverage(browseWithFilters, namespace.namespace, frontend))) : [\n m('td', this.prefixCoverage(browseWithFilters, namespace.namespace, '_all_except_admin')),\n m('td', this.prefixCoverage(browseWithFilters, namespace.namespace, 'admin')),\n ],\n ],\n ]);\n }),\n ]),\n ]),\n ];\n }\n\n prefixCoverage(browseWithFilters, namespace, frontend) {\n if (!this.locale) {\n return null;\n }\n\n return this.localeCoverage(browseWithFilters, this.locale, namespace, frontend);\n }\n\n localeCoverage(browseWithFilters, locale, namespace, frontend) {\n const stringKeys = app.store.all('fof-linguist-string-key').filter(key => {\n if (!namespace) {\n return true;\n }\n\n const parts = key.key().split('.');\n\n if (parts[0] !== namespace) {\n return false;\n }\n\n if (frontend === '_all_except_admin') {\n if (parts.length >= 2 && parts[1] === 'admin') {\n return false;\n }\n } else if (frontend && (parts.length < 2 || parts[1] !== frontend)) {\n return false;\n }\n\n return true;\n });\n\n if (stringKeys.length === 0) {\n return '-';\n }\n\n let customCount = 0;\n let originalCount = 0;\n\n stringKeys.forEach(stringKey => {\n const customString = app.store.all('fof-linguist-string').find(\n string => string.key() === stringKey.key() && string.locale() === locale\n );\n\n if (customString) {\n customCount++;\n } else if (stringKey.locales().hasOwnProperty(locale)) {\n originalCount++;\n }\n });\n\n const percent = Math.round(((customCount + originalCount) / stringKeys.length) * 100);\n\n let specialStyle;\n\n if (percent === 100) {\n specialStyle = 'full';\n } else if (percent < 5) {\n specialStyle = 'low';\n }\n\n let label;\n\n if (this.totalPercent) {\n label = app.translator.trans('fof-linguist.admin.coverage.count.percent', {\n percent: percent + '', // Keeps zero as string\n });\n } else {\n label = app.translator.trans('fof-linguist.admin.coverage.count.total', {\n translated: (customCount + originalCount) + '', // Keeps zero as string\n total: stringKeys.length,\n });\n }\n\n return m('.FoF-Linguist-Coverage-Progress-Wrap', [\n m('.FoF-Linguist-Progress', {\n className: specialStyle ? 'FoF-Linguist-Progress--' + specialStyle : '',\n }, [\n m('.FoF-Linguist-Progress-Bar', {\n style: {\n width: Math.max(percent, 5) + '%', // Always show the progress bar even if very close to 0\n },\n }),\n m('.FoF-Linguist-Progress-Label', label),\n m('.FoF-Linguist-Progress-More', app.translator.trans('fof-linguist.admin.coverage.count.details', {\n total: stringKeys.length,\n original: originalCount + '', // Cast to string to preserve zero\n custom: customCount + '',\n })),\n ]),\n Button.component({\n icon: 'fas fa-filter',\n className: 'Button Button--icon',\n onclick: () => {\n const options = {\n missingTranslationsInLocales: [locale],\n };\n\n if (namespace) {\n options.forExtension = namespace;\n }\n\n if (frontend) {\n options.frontend = frontend;\n }\n\n browseWithFilters(options);\n },\n title: app.translator.trans('fof-linguist.admin.coverage.apply-missing-filter'),\n }),\n ]);\n }\n}\n","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/components/Switch'];","const __WEBPACK_NAMESPACE_OBJECT__ = flarum.core.compat['common/components/LinkButton'];","import app from 'flarum/admin/app';\nimport Select from 'flarum/common/components/Select';\nimport Switch from 'flarum/common/components/Switch';\nimport LinkButton from 'flarum/common/components/LinkButton';\nimport localesAsArray from '../utils/localesAsArray';\nimport namespaceLabel from '../utils/namespaceLabel';\n\n/* global m */\n\nexport default class ExportPage {\n oninit() {\n this.locale = 'en';\n this.namespace = null;\n this.includeOriginals = false;\n this.includeAll = false;\n this.loading = false;\n this.output = '';\n\n this.fetchOutput();\n }\n\n view(vnode) {\n const localeOptions = {};\n\n localesAsArray().forEach(locale => {\n localeOptions[locale.key] = locale.name + ' (' + locale.key + ')';\n });\n\n localeOptions.all = app.translator.trans('fof-linguist.admin.export.locale-all')\n\n const namespaceOptions = {\n _all: app.translator.trans('fof-linguist.admin.export.namespace-all'),\n };\n\n vnode.attrs.namespaces.forEach(namespace => {\n if (namespace.extension) {\n namespaceOptions[namespace.namespace] = namespace.extension.extra['flarum-extension'].title;\n } else {\n namespaceOptions[namespace.namespace] = namespaceLabel(namespace.namespace);\n\n }\n });\n\n return [\n m('h2', app.translator.trans('fof-linguist.admin.export.title')),\n m('.Form-group', m('.Alert', app.translator.trans('fof-linguist.admin.export.warning'))),\n m('.Form-group', [\n m('label', app.translator.trans('fof-linguist.admin.export.locale')),\n Select.component({\n options: localeOptions,\n value: this.locale,\n onchange: value => {\n this.locale = value;\n\n this.fetchOutput();\n },\n }),\n ]),\n m('.Form-group', [\n m('label', app.translator.trans('fof-linguist.admin.export.namespace')),\n Select.component({\n options: namespaceOptions,\n value: this.namespace === null ? '_all' : this.namespace,\n onchange: value => {\n this.namespace = value === '_all' ? null : value;\n\n this.fetchOutput();\n },\n }),\n ]),\n m('.Form-group', [\n Switch.component({\n state: this.includeOriginals,\n onchange: value => {\n this.includeOriginals = value;\n\n this.fetchOutput();\n }\n }, app.translator.trans('fof-linguist.admin.export.include-originals')),\n ]),\n m('.Form-group', [\n Switch.component({\n state: this.includeAll,\n onchange: value => {\n this.includeAll = value;\n\n this.fetchOutput();\n }\n }, app.translator.trans('fof-linguist.admin.export.include-all')),\n ]),\n m('.Form-group', [\n m('label', [\n app.translator.trans('fof-linguist.admin.export.output'),\n ' ',\n LinkButton.component({\n className: 'Button Button--primary',\n href: this.exportUrl(),\n external: true,\n // If a namespace is selected, we use it as filename (language pack convention)\n // otherwise we use the locale as filename (extension convention)\n download: (this.namespace || this.locale) + '.yml',\n }, app.translator.trans('fof-linguist.admin.export.download')),\n ]),\n m('textarea.FormControl.FoF-Export-Textarea', {\n readonly: true,\n value: this.output,\n rows: 10,\n placeholder: this.loading ? app.translator.trans('fof-linguist.admin.export.output-loading') : app.translator.trans('fof-linguist.admin.export.output-empty'),\n }),\n ]),\n ];\n }\n\n exportUrl() {\n return app.forum.attribute('apiUrl') + '/fof/linguist/export?' + m.buildQueryString({\n locale: this.locale,\n namespace: this.namespace,\n includeOriginals: this.includeOriginals ? '1' : '0',\n includeAll: this.includeAll ? '1' : '0',\n });\n }\n\n fetchOutput() {\n this.loading = true;\n this.output = '';\n\n app.request({\n method: 'GET',\n url: this.exportUrl(),\n // Flarum doesn't support a raw to have the raw text response\n // So we'll encode the response with JSON so Flarum can parse if afterwards\n extract: raw => JSON.stringify(raw),\n }).then(output => {\n this.loading = false;\n this.output = output;\n m.redraw();\n }).catch(error => {\n this.loading = false;\n m.redraw();\n throw error;\n });\n }\n}\n","import app from 'flarum/admin/app';\nimport Button from 'flarum/common/components/Button';\nimport Select from 'flarum/common/components/Select';\nimport Switch from 'flarum/common/components/Switch';\nimport extractText from 'flarum/common/utils/extractText';\nimport localesAsArray from '../utils/localesAsArray';\n\n/* global m */\n\nexport default class ImportPage {\n oninit() {\n this.locale = 'en';\n this.overrideExisting = true;\n this.input = '';\n this.loading = false;\n }\n\n view() {\n const localeOptions = {};\n\n localesAsArray().forEach(locale => {\n localeOptions[locale.key] = locale.name + ' (' + locale.key + ')';\n });\n\n localeOptions.all = app.translator.trans('fof-linguist.admin.import.locale-all')\n\n return [\n m('h2', app.translator.trans('fof-linguist.admin.import.title')),\n m('.Form-group', [\n m('label', app.translator.trans('fof-linguist.admin.import.input')),\n m('textarea.FormControl', {\n value: this.input,\n oninput: event => {\n this.input = event.target.value;\n },\n rows: 10,\n placeholder: app.translator.trans('fof-linguist.admin.import.input-placeholder'),\n }),\n ]),\n m('.Form-group', [\n m('label', app.translator.trans('fof-linguist.admin.import.locale')),\n Select.component({\n options: localeOptions,\n value: this.locale,\n onchange: value => {\n this.locale = value;\n\n this.fetchOutput();\n },\n }),\n ]),\n m('.Form-group', [\n Switch.component({\n state: this.overrideExisting,\n onchange: value => {\n this.overrideExisting = value;\n }\n }, app.translator.trans('fof-linguist.admin.import.override-existing')),\n ]),\n m('.Form-group', Button.component({\n className: 'Button Button--primary',\n onclick: () => {\n this.loading = true;\n\n app.request({\n method: 'POST',\n url: app.forum.attribute('apiUrl') + '/fof/linguist/import',\n body: {\n input: this.input,\n locale: this.locale,\n ignoreExisting: !this.overrideExisting,\n },\n }).then(data => {\n this.loading = false;\n m.redraw();\n\n if (confirm(extractText(app.translator.trans(this.overrideExisting ? 'fof-linguist.admin.import.results' : 'fof-linguist.admin.import.results-with-ignore', {\n imported: data.imported + '', // Cast to string to preserve zeros\n ignored: data.ignored + '',\n identical: data.identical + '',\n })))) {\n window.location.reload();\n }\n }).catch(error => {\n this.loading = false;\n m.redraw();\n throw error;\n });\n },\n disabled: this.loading || !this.input,\n loading: this.loading,\n }, app.translator.trans('fof-linguist.admin.import.submit'))),\n ];\n }\n}\n","import app from 'flarum/admin/app';\nimport ExtensionPage from 'flarum/admin/components/ExtensionPage';\nimport LoadingIndicator from 'flarum/common/components/LoadingIndicator';\nimport StringsPage from './StringsPage';\nimport CoveragePage from './CoveragePage';\nimport ExportPage from './ExportPage';\nimport ImportPage from './ImportPage';\n\n/* global m */\n\nexport default class LinguistPage extends ExtensionPage {\n oninit(vnode) {\n super.oninit(vnode);\n\n this.tab = 'strings';\n this.ready = false;\n this.namespaces = []; // First level of translation keys. Usually an extension ID, but also core and validation\n this.frontends = [\n 'forum',\n 'admin',\n 'lib',\n 'ref',\n 'api',\n ]; // Second level of translation keys: forum, admin, ...\n this.initialBrowseFilters = {};\n\n Promise.all([\n app.request({\n method: 'GET',\n url: app.forum.attribute('apiUrl') + '/fof/linguist/strings',\n }).then(result => {\n app.store.pushPayload(result);\n }),\n app.request({\n method: 'GET',\n url: app.forum.attribute('apiUrl') + '/fof/linguist/string-keys',\n }).then(result => {\n const keys = app.store.pushPayload(result);\n\n const namespaces = [];\n\n keys.forEach(key => {\n const parts = key.key().split('.');\n\n const namespace = parts[0];\n\n if (['core', 'validation'].indexOf(namespace) === -1 && namespaces.indexOf(namespace) === -1) {\n namespaces.push(namespace);\n }\n\n if (parts.length > 1 && namespace !== 'validation') {\n const frontend = parts[1];\n\n if (this.frontends.indexOf(frontend) === -1) {\n this.frontends.push(frontend);\n }\n }\n });\n\n namespaces.sort();\n\n this.namespaces = [\n {\n namespace: 'core',\n },\n {\n namespace: 'validation',\n },\n ...namespaces.map(namespace => {\n // First we look if the namespace matches an extension ID, that's the most common naming\n let extension = app.data.extensions[namespace];\n\n // If that's unsuccessful, we'll look if the full package name was used as namespace\n if (!extension) {\n extension = Object.values(app.data.extensions).find(extension => {\n const packageNameWithDash = extension.name.replace('/', '-');\n\n return namespace === packageNameWithDash;\n });\n }\n\n return {\n namespace,\n extension,\n };\n }),\n ];\n }),\n ]).then(() => {\n this.ready = true;\n m.redraw();\n });\n }\n\n content() {\n return m('.ExtensionPage-settings', m('.container', [\n this.contentTab(),\n ]));\n }\n\n infoItems() {\n const items = super.infoItems();\n\n items.add('linguist-tabs', m('ul.FoF-Linguist-Tabs', [\n m('li', m('a', {\n className: this.tab === 'strings' ? 'active' : '',\n onclick: () => {\n this.tab = 'strings';\n },\n }, app.translator.trans('fof-linguist.admin.tabs.strings'))),\n m('li', m('a', {\n className: this.tab === 'coverage' ? 'active' : '',\n onclick: () => {\n this.tab = 'coverage';\n },\n }, app.translator.trans('fof-linguist.admin.tabs.coverage'))),\n m('li', m('a', {\n className: this.tab === 'export' ? 'active' : '',\n onclick: () => {\n this.tab = 'export';\n },\n }, app.translator.trans('fof-linguist.admin.tabs.export'))),\n m('li', m('a', {\n className: this.tab === 'import' ? 'active' : '',\n onclick: () => {\n this.tab = 'import';\n },\n }, app.translator.trans('fof-linguist.admin.tabs.import'))),\n ]), 100);\n\n return items;\n }\n\n contentTab() {\n if (!this.ready) {\n return LoadingIndicator.component();\n }\n\n switch (this.tab) {\n case 'strings':\n return m(StringsPage, {\n namespaces: this.namespaces,\n frontends: this.frontends,\n initialBrowseFilters: this.initialBrowseFilters,\n });\n case 'coverage':\n return m(CoveragePage, {\n namespaces: this.namespaces,\n frontends: this.frontends,\n browseWithFilters: filters => {\n this.initialBrowseFilters = filters;\n this.tab = 'strings';\n },\n });\n case 'export':\n return m(ExportPage, {\n namespaces: this.namespaces,\n });\n case 'import':\n return m(ImportPage);\n }\n\n return null;\n }\n}\n","import StringKey from './StringKey';\nimport StringLocale from './StringLocale';\n\nexport const components = {\n StringKey,\n StringLocale,\n};\n","import StringKey from './StringKey';\nimport TextString from './TextString';\n\nexport const models = {\n StringKey,\n TextString,\n};\n","import CoveragePage from './CoveragePage';\nimport ExportPage from './ExportPage';\nimport ImportPage from './ImportPage';\nimport LinguistPage from './LinguistPage';\nimport StringsPage from './StringsPage';\n\nexport const pages = {\n CoveragePage,\n ExportPage,\n ImportPage,\n LinguistPage,\n StringsPage,\n};\n","import booleanCheck from './booleanCheck';\nimport frontendLabel from './frontendLabel';\nimport highlightMithril from './highlightMithril';\nimport localesAsArray from './localesAsArray';\nimport namespaceLabel from './namespaceLabel';\n\nexport const utils = {\n booleanCheck,\n frontendLabel,\n highlightMithril,\n localesAsArray,\n namespaceLabel,\n};\n","import app from 'flarum/admin/app';\nimport StringKey from './models/StringKey';\nimport TextString from './models/TextString';\nimport LinguistPage from './pages/LinguistPage';\n\nexport * from './components';\nexport * from './models';\nexport * from './pages';\nexport * from './utils';\n\napp.initializers.add('fof-linguist', app => {\n app.store.models['fof-linguist-string-key'] = StringKey;\n app.store.models['fof-linguist-string'] = TextString;\n\n app.extensionData\n .for('fof-linguist')\n .registerPage(LinguistPage)\n .registerPermission(\n {\n icon: 'fas fa-italic',\n label: app.translator.trans(\n 'fof-linguist.admin.permissions.view_string_keys'\n ),\n permission: 'viewStringKeys',\n allowGuest: true,\n },\n 'view'\n );\n});\n"],"names":["__webpack_require__","module","getter","__esModule","d","a","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","flarum","core","compat","_setPrototypeOf","p","setPrototypeOf","bind","__proto__","_inheritsLoose","subClass","superClass","create","constructor","StringKey","Model","locales","TextString","locale","apiEndpoint","this","exists","data","id","englishFound","app","push","name","unshift","HIGHLIGHT_DELIMITER","string","highlight","lowercaseHighliht","toLowerCase","regex","RegExp","replace","split","map","text","m","StringLocale","oninit","vnode","stringKey","attrs","localeKey","originalString","find","dirty","processing","originalHasNewLine","keys","some","indexOf","inputType","view","placeholderText","localeName","className","title","oninput","event","target","disabled","highlightMithril","actions","onchange","toArray","items","ItemList","add","Button","type","loading","onclick","saveString","deleteString","attributes","save","then","redraw","err","localesAsArray","namespace","frontend","operation","booleans","reduce","b","StringsPage","numberOfResultsToShow","filters","assign","search","withOwnTranslations","missingTranslationsNegation","missingTranslationsType","missingTranslationsOperation","missingTranslationsInLocales","forExtension","initialBrowseFilters","results","applyFilters","slice","cacheClearInstructions","placeholder","icon","Dropdown","buttonClassName","label","namespaces","extension","extra","namespaceLabel","frontends","frontendLabel","length","stopPropagation","Select","options","without","with","any","original","own","or","and","filter","strings","confirm","extractText","count","LoadingModal","Promise","all","window","location","reload","shown","total","keysWithCustomTranslations","keysWithCustomTranslationsIn","forEach","lowercaseSearch","hasOriginalTranslation","booleanCheck","hasOwnTranslation","matchesType","parts","Alert","dismissible","controls","method","url","CoveragePage","columns","showAllFrontends","totalPercent","firstNonEnglishLocale","visibleFrontends","browseWithFilters","localeCoverage","style","prefixCoverage","stringKeys","customCount","originalCount","specialStyle","percent","Math","round","translated","width","max","custom","ExportPage","includeOriginals","includeAll","output","fetchOutput","localeOptions","namespaceOptions","_all","Switch","state","LinkButton","href","exportUrl","external","download","readonly","rows","buildQueryString","extract","raw","JSON","stringify","error","ImportPage","overrideExisting","input","body","ignoreExisting","imported","ignored","identical","LinguistPage","tab","ready","result","sort","values","packageNameWithDash","content","contentTab","infoItems","LoadingIndicator","ExtensionPage","components","models","pages","utils","store","extensionData","registerPage","registerPermission","translator","trans","permission","allowGuest"],"sourceRoot":""} \ No newline at end of file