{"version":3,"file":"main.RVRLo-.js","sources":["theme-21/virtual:theme","theme-21/discourse/api-initializers/theme-initializer.gjs","theme-21/virtual:entrypoint:main"],"sourcesContent":["import { getObjectForTheme } from \"discourse/lib/theme-settings-store\";\n\nexport const settings = getObjectForTheme(21);\n\nexport function themePrefix(key) {\n  return `theme_translations.21.${key}`;\n}\n","/**\n * Adds an interface font selector to the user preferences\n * interface page; preference is stored in localStorage\n * (per-browser, not synced).\n */\n\nimport { apiInitializer } from \"discourse/lib/api\";\nimport Component from \"@glimmer/component\";\nimport { tracked } from \"@glimmer/tracking\";\nimport { action } from \"@ember/object\";\nimport { modifier } from \"ember-modifier\";\nimport ComboBox from \"select-kit/components/combo-box\";\nimport SolvedSharedIssueButton from \"discourse/plugins/discourse-solved/discourse/components/solved-shared-issue-button\";\n\n// localStorage key for persisting the user's choice\nconst STORAGE_KEY = \"font-preference\";\n\n// All font classes on <html> use this prefix\nconst CLASS_PREFIX = \"font-\";\n\n// Available fonts shown in the select-kit dropdown;\n// Roboto and Roboto Mono are loaded via <head>, while\n// others require local install\nconst FONT_OPTIONS = [\n  { id: \"roboto\", name: \"Roboto\" },\n  { id: \"roboto-mono\", name: \"Roboto Mono\" },\n  { id: \"jetbrains-mono\", name: \"JetBrains Mono\" },\n  { id: \"fira-code\", name: \"Fira Code\" },\n  { id: \"inter\", name: \"Inter\" },\n  { id: \"open-sans\", name: \"Open Sans\" },\n  { id: \"space-grotesk\", name: \"Space Grotesk\" },\n  { id: \"ibm-plex-sans\", name: \"IBM Plex Sans\" },\n  { id: \"merriweather\", name: \"Merriweather\" },\n  { id: \"lora\", name: \"Lora\" },\n];\n\n// Set of valid font IDs for fast lookup during validation\nconst FONT_IDS = new Set(FONT_OPTIONS.map((f) => f.id));\n\n// Returns value if it's a known font ID, otherwise falls\n// back to \"roboto\"\nfunction normalizeFont(value) {\n  return FONT_IDS.has(value) ? value : \"roboto\";\n}\n\n// Reads and validates the stored font preference\nfunction getFont() {\n  return normalizeFont(localStorage.getItem(STORAGE_KEY) || \"roboto\");\n}\n\n// Removes any existing font-* class from <html> and applies\n// the current one\nfunction applyFont() {\n  const html = document.documentElement;\n\n  // Spread into array first by mutating classList while\n  // iterating can skip entries\n  for (const cls of [...html.classList]) {\n    if (cls.startsWith(CLASS_PREFIX)) {\n      html.classList.remove(cls);\n    }\n  }\n\n  const font = getFont();\n  if (font !== \"roboto\") {\n    html.classList.add(CLASS_PREFIX + font);\n  }\n}\n\n// Update footer copyright year placeholder to the current year\nfunction updateFooterYear() {\n  const el = document.querySelector(\".copyright-year\");\n  if (el) {\n    el.textContent = '-' + new Date().getFullYear();\n  }\n}\n\n// Ember modifier that repositions the font selector directly after\n// the \"Text Size\" control group on the interface preferences page\nconst placeAfterTextSize = modifier((element) => {\n  const textSizeBlock = document.querySelector(\n    '[data-setting-name=\"user-text-size\"]'\n  );\n  if (textSizeBlock && textSizeBlock.nextElementSibling !== element) {\n    textSizeBlock.insertAdjacentElement(\"afterend\", element);\n  }\n});\n\n// Glimmer component rendered into the user-preferences-interface outlet\nclass FontPreferenceField extends Component {\n  @tracked font = getFont();\n\n  get fontOptions() {\n    return FONT_OPTIONS;\n  }\n\n  @action\n  onChangeFont(value) {\n    this.font = normalizeFont(value);\n    localStorage.setItem(STORAGE_KEY, this.font);\n    applyFont();\n  }\n\n  <template>\n    <div class=\"control-group font-preference\" {{placeAfterTextSize}}>\n      <label class=\"control-label\">Interface font</label>\n      <div class=\"controls\">\n        <ComboBox\n          @value={{this.font}}\n          @content={{this.fontOptions}}\n          @onChange={{this.onChangeFont}}\n          class=\"font-select\"\n        />\n      </div>\n      <div class=\"instructions\">\n        This preference does not sync across browsers or devices. Roboto and\n        Roboto Mono are included, while other fonts must exist on the device.\n      </div>\n    </div>\n  </template>\n}\n\nexport default apiInitializer(\"1.13.0\", (api) => {\n  // Apply saved font immediately on first load\n  applyFont();\n\n  // Re-apply on Discourse's client-side page transitions\n  api.onPageChange(applyFont);\n\n  // Inject the font selector into the interface preferences page\n  api.renderInOutlet(\"user-preferences-interface\", FontPreferenceField);\n\n  // Update footer copyright year automatically\n  api.onPageChange(updateFooterYear);\n  \n  // Clone 'Me Too' button to the post controls\n  api.registerValueTransformer(\n    \"post-menu-buttons\",\n    ({ value: dag, context: { post, buttonKeys } }) => {\n      // The 'Me Too' and 'Shared Issue' buttons only belongs on the OP\n      if (post.post_number !== 1) {\n        return;\n      }\n      // Clone instance\n      dag.add(\n        \"sharedIssue\",\n        SolvedSharedIssueButton,\n        {\n          before: buttonKeys.LIKE,\n        }\n      );\n    }\n  );\n});\n","import * as Mod1 from \"./discourse/api-initializers/theme-initializer\";\nconst compatModules = {\n  \"discourse/api-initializers/theme-initializer\": Mod1,\n};\nexport { compatModules };\nexport default compatModules;\n"],"names":["getObjectForTheme","STORAGE_KEY","CLASS_PREFIX","FONT_OPTIONS","id","name","FONT_IDS","Set","map","f","normalizeFont","value","has","getFont","localStorage","getItem","applyFont","html","document","documentElement","cls","classList","startsWith","remove","font","add","updateFooterYear","el","querySelector","textContent","Date","getFullYear","placeAfterTextSize","modifier","element","textSizeBlock","nextElementSibling","insertAdjacentElement","FontPreferenceField","Component","dt7948","g","this","prototype","tracked","i","fontOptions","onChangeFont","setItem","n","action","setComponentTemplate","createTemplateFactory","block","moduleName","scope","ComboBox","isStrictMode","themeInitializer","apiInitializer","api","onPageChange","renderInOutlet","registerValueTransformer","dag","context","post","buttonKeys","post_number","_plugin_discourseSolved","default","before","LIKE","compatModules"],"mappings":";;AAEwBA,EAAkB;;ACa1C,MAAMC,EAAc,kBAGdC,EAAe,QAKfC,EAAe,CACnB,CAAEC,GAAI,SAAUC,KAAM,UACtB,CAAED,GAAI,cAAeC,KAAM,eAC3B,CAAED,GAAI,iBAAkBC,KAAM,kBAC9B,CAAED,GAAI,YAAaC,KAAM,aACzB,CAAED,GAAI,QAASC,KAAM,SACrB,CAAED,GAAI,YAAaC,KAAM,aACzB,CAAED,GAAI,gBAAiBC,KAAM,iBAC7B,CAAED,GAAI,gBAAiBC,KAAM,iBAC7B,CAAED,GAAI,eAAgBC,KAAM,gBAC5B,CAAED,GAAI,OAAQC,KAAM,SAIhBC,EAAW,IAAIC,IAAIJ,EAAaK,IAAKC,GAAMA,EAAEL;AAInD,SAASM,EAAcC,GACrB,OAAOL,EAASM,IAAID,GAASA,EAAQ,QACvC,CAGA,SAASE,IACP,OAAOH,EAAcI,aAAaC,QAAQd,IAAgB,SAC5D,CAIA,SAASe,IACP,MAAMC,EAAOC,SAASC;AAItB,IAAK,MAAMC,IAAO,IAAIH,EAAKI,WACrBD,EAAIE,WAAWpB,IACjBe,EAAKI,UAAUE,OAAOH;AAI1B,MAAMI,EAAOX;AACA,WAATW,GACFP,EAAKI,UAAUI,IAAIvB,EAAesB,EAEtC,CAGA,SAASE,IACP,MAAMC,EAAKT,SAASU,cAAc;AAC9BD,IACFA,EAAGE,YAAc,KAAM,IAAIC,MAAOC,cAEtC,CAIA,MAAMC,EAAqBC,EAAUC,IACnC,MAAMC,EAAgBjB,SAASU,cAC7B;AAEEO,GAAiBA,EAAcC,qBAAuBF,GACxDC,EAAcE,sBAAsB,WAAYH;AAKpD,MAAMI,UAA4BC,SAAAC,OAAAC,EAAAC,KAAAC,kBAC/BC,GAAA,WAAA,OAAe/B,GAAA,EAAA,CAAAW,QAAAgB,OAAAK,EAAAH,KAAA;AAEhB,eAAII,GACF,OAAO3C,CACT,CAGA4C,YAAAA,CAAapC,GACX+B,KAAKlB,KAAOd,EAAcC,GAC1BG,aAAakC,QAAQ/C,EAAayC,KAAKlB,MACvCR,GACF,QAAAwB,OAAAS,EAAAP,KAAAC,0BALCO,GAAA,QAODC,EAAAC,EAAA,CAAAhD,GAAA,KAAAiD,MAAA,6lBAAAC,WAAA,4BAAAC,MAAAA,KAAAA,CAAAvB,qBAAAwB,aAAAC,cAAA,IAgBAf,KAAU,EAGZ,IAAAgB;oCAAeC,CAAe,SAAWC,IAEvC5C,IAGA4C,EAAIC,aAAa7C,GAGjB4C,EAAIE,eAAe,6BAA8BxB,GAGjDsB,EAAIC,aAAanC,GAGjBkC,EAAIG,yBACF,oBACA,EAAGpD,MAAOqD,EAAKC,SAAWC,OAAMC,kBAEL,IAArBD,EAAKE,aAITJ,EAAIvC,IACF,eAAA4C,EAAA,oDAAAA,EAAA,0DAAAC,QAEA,CACEC,OAAQJ,EAAWK;ACnJxB,MAACC,EAAgB,CACpB;"}