{"version":3,"file":"main.BxppGB.js","sources":["theme-599/virtual:theme","theme-599/discourse/components/modal/app-modal.gjs","theme-599/discourse/api-initializers/app-modal-init.js","theme-599/discourse/components/modal/app-installed-modal.gjs","theme-599/discourse/initializers/app-modal-init.js","theme-599/virtual:entrypoint:main"],"sourcesContent":["import { getObjectForTheme } from \"discourse/lib/theme-settings-store\";\n\nexport const settings = getObjectForTheme(599);\n\nexport function themePrefix(key) {\n  return `theme_translations.599.${key}`;\n}\n","import Component from \"@glimmer/component\";\nimport { action } from \"@ember/object\";\nimport { service } from \"@ember/service\";\nimport cookie from \"discourse/lib/cookie\";\nimport DButton from \"discourse/components/d-button\";\nimport DModal from \"discourse/components/d-modal\";\nimport I18n from \"discourse-i18n\";\n\nfunction t(key, fallback) {\n  let val = null;\n  try {\n    if (typeof themePrefix === \"function\") {\n      val = I18n.t(themePrefix(key));\n    }\n  } catch (_) {}\n\n  if (!val || (typeof val === \"string\" && val.startsWith(\"[\") && val.endsWith(\"]\"))) {\n    try {\n      val = I18n.t(key);\n    } catch (_) {}\n  }\n\n  if (!val || (typeof val === \"string\" && val.startsWith(\"[\") && val.endsWith(\"]\"))) {\n    return fallback;\n  }\n  return val;\n}\n\nfunction recordDismissal() {\n  const cookieName = settings.app_cookie_name || \"app_modal_closed\";\n  const lifespan = settings.app_cookie_lifespan || \"month\";\n\n  if (lifespan === \"none\") {\n    return;\n  }\n\n  let expiresDays = 30;\n  if (lifespan === \"day\") {\n    expiresDays = 1;\n  } else if (lifespan === \"week\") {\n    expiresDays = 7;\n  } else if (lifespan === \"month\") {\n    expiresDays = 30;\n  } else if (lifespan === \"year\") {\n    expiresDays = 365;\n  }\n\n  const expirationDate = moment().add(expiresDays, \"days\").toDate();\n\n  try {\n    cookie(cookieName, \"true\", {\n      expires: expirationDate,\n      path: \"/\"\n    });\n  } catch (_) {}\n\n  try {\n    if (typeof localStorage !== \"undefined\") {\n      localStorage.setItem(\n        cookieName,\n        JSON.stringify({ closed: true, expires: expirationDate.getTime() })\n      );\n    }\n  } catch (_) {}\n}\n\nexport default class AppModal extends Component {\n  @service capabilities;\n  @service modal;\n\n  get appName() {\n    return settings.app_name || t(\"labels.app_name\", \"Sorumatik\");\n  }\n\n  get appInitial() {\n    return (this.appName || \"S\").charAt(0).toUpperCase();\n  }\n\n  get appSubtitle() {\n    return (\n      settings.app_subtitle ||\n      t(\n        \"app_modal.subtitle\",\n        \"Daha hızlı ve pratik soru çözümü için uygulamayı açın.\"\n      )\n    );\n  }\n\n  get appBadge() {\n    return (\n      settings.app_badge_text || t(\"app_modal.badge\", \"★ 4.9 • Ücretsiz\")\n    );\n  }\n\n  get appLogo() {\n    return settings.app_logo_img || \"\";\n  }\n\n  get isAndroid() {\n    return (\n      this.capabilities?.isAndroid ||\n      (typeof navigator !== \"undefined\" && /Android/i.test(navigator.userAgent))\n    );\n  }\n\n  get isApple() {\n    return (\n      this.capabilities?.isIOS ||\n      this.capabilities?.isIpadOS ||\n      this.capabilities?.isApple ||\n      (typeof navigator !== \"undefined\" &&\n        /iPhone|iPad|iPod|Macintosh/i.test(navigator.userAgent))\n    );\n  }\n\n  get isPwaMode() {\n    return this.isAndroid && settings.android_app_type === \"pwa\";\n  }\n\n  get ctaButtonLabel() {\n    if (this.isPwaMode) {\n      return t(\"actions.install_pwa\", \"Uygulamayı Yükle\");\n    }\n    return t(\"actions.open_app\", \"Uygulamada Aç\");\n  }\n\n  get continueBrowserLabel() {\n    return t(\"actions.continue_browser\", \"Tarayıcıda Devam Et\");\n  }\n\n  get closeLabel() {\n    return t(\"labels.close\", \"Kapat\");\n  }\n\n  get appModalTitle() {\n    return this.appName || t(\"app_modal.title\", \"Sorumatik Uygulaması\");\n  }\n\n  get featureFast() {\n    return t(\"app_modal.features.fast\", \"Hızlı & Pratik\");\n  }\n\n  get featureNotifications() {\n    return t(\"app_modal.features.notifications\", \"Anlık Bildirimler\");\n  }\n\n  get featureVideoSolutions() {\n    return t(\"app_modal.features.video_solutions\", \"Video Çözüm\");\n  }\n\n  get featureAiTools() {\n    return t(\"app_modal.features.ai_tools\", \"Yapay Zeka Araçları\");\n  }\n\n  get featureFree() {\n    return t(\"app_modal.features.free\", \"Ücretsiz\");\n  }\n\n  @action\n  handleCtaAction() {\n    recordDismissal();\n\n    if (this.isPwaMode) {\n      const promptEvent = window.deferredPrompt;\n      if (promptEvent) {\n        promptEvent.prompt();\n        window.deferredPrompt = null;\n      }\n      this.closeModal();\n      return;\n    }\n\n    if (this.isAndroid) {\n      const link =\n        settings.android_appstore_link ||\n        \"https://play.google.com/store/apps/details?id=com.sorumatik\";\n      window.location.href = link;\n      this.closeModal();\n      return;\n    }\n\n    if (this.isApple) {\n      const link =\n        settings.apple_appstore_link ||\n        \"https://apps.apple.com/app/sorumatik/id6474668271\";\n      window.location.href = link;\n      this.closeModal();\n      return;\n    }\n\n    // Default fallback\n    const fallbackLink =\n      settings.apple_appstore_link ||\n      settings.android_appstore_link ||\n      \"https://sorumatik.co/t/app\";\n    window.location.href = fallbackLink;\n    this.closeModal();\n  }\n\n  @action\n  continueBrowser() {\n    recordDismissal();\n    this.closeModal();\n  }\n\n  @action\n  closeModal() {\n    recordDismissal();\n    if (typeof this.args?.closeModal === \"function\") {\n      this.args.closeModal();\n    } else {\n      this.modal.close();\n    }\n  }\n\n  <template>\n    <DModal\n      @closeModal={{this.closeModal}}\n      @title={{this.appModalTitle}}\n      class=\"app-modal discourse-app-promoter\"\n      @dismissable={{true}}\n    >\n      <:body>\n        <div class=\"promoter-sheet\">\n          <div class=\"promoter-drag-handle\" aria-hidden=\"true\"></div>\n\n          <DButton\n            @class=\"promoter-close-btn btn-flat\"\n            @action={{this.closeModal}}\n            aria-label={{this.closeLabel}}\n          >\n            <svg\n              width=\"14\"\n              height=\"14\"\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              stroke-width=\"2.5\"\n              stroke-linecap=\"round\"\n              stroke-linejoin=\"round\"\n            >\n              <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n              <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n            </svg>\n          </DButton>\n\n          <div class=\"promoter-header\">\n            {{#if this.appLogo}}\n              <img\n                src={{this.appLogo}}\n                alt={{this.appName}}\n                class=\"promoter-icon\"\n              />\n            {{else}}\n              <div class=\"promoter-icon promoter-icon-default\">\n                <span>{{this.appInitial}}</span>\n              </div>\n            {{/if}}\n\n            <div class=\"promoter-meta\">\n              <div class=\"promoter-title-row\">\n                <h3 class=\"promoter-app-name\">{{this.appName}}</h3>\n                {{#if this.appBadge}}\n                  <span class=\"promoter-badge\">{{this.appBadge}}</span>\n                {{/if}}\n              </div>\n              <p class=\"promoter-subtitle\">{{this.appSubtitle}}</p>\n            </div>\n          </div>\n\n          <div class=\"promoter-features\">\n            <span class=\"promoter-feature-pill pill--fast\">\n              <span class=\"pill-icon\" aria-hidden=\"true\">\n                <svg class=\"pill-svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n                  <path d=\"M13 2L3 14h9l-1 8 10-12h-9l1-8z\"/>\n                </svg>\n              </span>\n              <span class=\"pill-text\">{{this.featureFast}}</span>\n            </span>\n            <span class=\"promoter-feature-pill pill--notifications\">\n              <span class=\"pill-icon\" aria-hidden=\"true\">\n                <svg class=\"pill-svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n                  <path d=\"M12 22c1.1 0 2-.9 2-2h-4c0 1.1.9 2 2 2zm6-6v-5c0-3.07-1.63-5.64-4.5-6.32V4c0-.83-.67-1.5-1.5-1.5s-1.5.67-1.5 1.5v.68C7.64 5.36 6 7.92 6 11v5l-2 2v1h16v-1l-2-2z\"/>\n                </svg>\n              </span>\n              <span class=\"pill-text\">{{this.featureNotifications}}</span>\n            </span>\n            <span class=\"promoter-feature-pill pill--video\">\n              <span class=\"pill-icon\" aria-hidden=\"true\">\n                <svg class=\"pill-svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n                  <path d=\"M17 10.5V7c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4z\"/>\n                </svg>\n              </span>\n              <span class=\"pill-text\">{{this.featureVideoSolutions}}</span>\n            </span>\n            <span class=\"promoter-feature-pill pill--ai\">\n              <span class=\"pill-icon\" aria-hidden=\"true\">\n                <svg class=\"pill-svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n                  <path d=\"M12 2a2 2 0 0 1 2 2v1h1a3 3 0 0 1 3 3v1h1a2 2 0 0 1 2 2v4a2 2 0 0 1-2 2h-1v1a3 3 0 0 1-3 3h-1v1a2 2 0 0 1-4 0v-1H9a3 3 0 0 1-3-3v-1H5a2 2 0 0 1-2-2v-4a2 2 0 0 1 2-2h1V8a3 3 0 0 1 3-3h1V4a2 2 0 0 1 2-2zm-3 8a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3zm6 0a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3z\"/>\n                </svg>\n              </span>\n              <span class=\"pill-text\">{{this.featureAiTools}}</span>\n            </span>\n            <span class=\"promoter-feature-pill pill--free\">\n              <span class=\"pill-icon\" aria-hidden=\"true\">\n                <svg class=\"pill-svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\n                  <path d=\"M12 2l2.4 7.4H22l-6.2 4.5 2.4 7.4-6.2-4.5-6.2 4.5 2.4-7.4L2 9.4h7.6z\"/>\n                </svg>\n              </span>\n              <span class=\"pill-text\">{{this.featureFree}}</span>\n            </span>\n          </div>\n\n          <div class=\"promoter-actions\">\n            <DButton\n              @class=\"btn-primary promoter-btn-cta\"\n              @action={{this.handleCtaAction}}\n            >\n              <span class=\"btn-cta-content\">\n                {{#if this.isApple}}\n                  <svg\n                    class=\"btn-store-icon\"\n                    width=\"18\"\n                    height=\"18\"\n                    viewBox=\"0 0 24 24\"\n                    fill=\"currentColor\"\n                  >\n                    <path\n                      d=\"M18.71 19.5c-.83 1.24-1.71 2.45-3.05 2.47-1.34.03-1.77-.79-3.29-.79-1.53 0-2 .77-3.27.82-1.31.05-2.3-1.32-3.14-2.53C4.25 17 2.94 12.45 4.7 9.39c.87-1.52 2.43-2.48 4.12-2.51 1.28-.02 2.5.87 3.29.87.78 0 2.26-1.07 3.81-.91.65.03 2.47.26 3.64 1.98-.09.06-2.17 1.28-2.15 3.81.03 3.02 2.65 4.03 2.68 4.04-.03.07-.42 1.44-1.38 2.83M15.97 6.37c.63-.77 1.06-1.85.94-2.93-.91.04-2.02.61-2.67 1.38-.58.67-1.09 1.76-.95 2.81 1.02.08 2.05-.51 2.68-1.26z\"\n                    />\n                  </svg>\n                {{else if this.isAndroid}}\n                  <svg\n                    class=\"btn-store-icon\"\n                    width=\"18\"\n                    height=\"18\"\n                    viewBox=\"0 0 24 24\"\n                    fill=\"currentColor\"\n                  >\n                    <path\n                      d=\"M3.609 1.814L13.792 12 3.61 22.186a2.404 2.404 0 0 1-.22-.988V2.802c0-.36.08-.7.22-.988zm11.238 11.241l2.49 2.49-11.83 6.772 9.34-9.262zm0-2.11L5.507 1.683l11.83 6.772-2.49 2.49zm1.092 1.055l3.87 2.215c1.07.612 1.07 1.614 0 2.226l-3.87 2.215-2.57-2.57 2.57-2.57z\"\n                    />\n                  </svg>\n                {{else}}\n                  <svg\n                    class=\"btn-store-icon\"\n                    width=\"18\"\n                    height=\"18\"\n                    viewBox=\"0 0 24 24\"\n                    fill=\"none\"\n                    stroke=\"currentColor\"\n                    stroke-width=\"2\"\n                    stroke-linecap=\"round\"\n                    stroke-linejoin=\"round\"\n                  >\n                    <path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"></path>\n                    <polyline points=\"7 10 12 15 17 10\"></polyline>\n                    <line x1=\"12\" y1=\"15\" x2=\"12\" y2=\"3\"></line>\n                  </svg>\n                {{/if}}\n                <span class=\"btn-cta-text\">{{this.ctaButtonLabel}}</span>\n              </span>\n            </DButton>\n\n            <DButton\n              @class=\"btn-flat promoter-btn-browser\"\n              @translatedLabel={{this.continueBrowserLabel}}\n              @action={{this.continueBrowser}}\n            />\n          </div>\n        </div>\n      </:body>\n    </DModal>\n  </template>\n}\n","import { apiInitializer } from \"discourse/lib/api\";\nimport cookie from \"discourse/lib/cookie\";\nimport discourseLater from \"discourse-common/lib/later\";\nimport AppModal from \"../components/modal/app-modal\";\n\n// Global listener for PWA install prompt\nif (typeof window !== \"undefined\") {\n  window.addEventListener(\"beforeinstallprompt\", (event) => {\n    event.preventDefault();\n    window.deferredPrompt = event;\n  });\n}\n\n/**\n * Checks whether the user has dismissed the promoter previously.\n */\nexport function isDismissed() {\n  const cookieName = settings.app_cookie_name || \"app_modal_closed\";\n  const lifespan = settings.app_cookie_lifespan || \"month\";\n\n  if (lifespan === \"none\") {\n    return false;\n  }\n\n  // Check Discourse cookie\n  try {\n    const cookieVal = cookie(cookieName);\n    if (cookieVal) {\n      return true;\n    }\n  } catch (_) {}\n\n  // Check localStorage fallback\n  try {\n    if (typeof localStorage !== \"undefined\") {\n      const localItem = localStorage.getItem(cookieName);\n      if (localItem) {\n        const parsed = JSON.parse(localItem);\n        if (parsed && parsed.expires) {\n          if (Date.now() < parsed.expires) {\n            return true;\n          } else {\n            localStorage.removeItem(cookieName);\n          }\n        } else {\n          return true;\n        }\n      }\n    }\n  } catch (_) {}\n\n  return false;\n}\n\n/**\n * Checks whether the current URL or page is an excluded route (such as login or signup).\n */\nexport function isExcludedRoute(url, container) {\n  let currentPath = \"\";\n\n  if (url) {\n    currentPath = String(url).toLowerCase();\n  } else if (typeof window !== \"undefined\" && window.location) {\n    currentPath = (window.location.pathname || \"\").toLowerCase();\n  }\n\n  // Strip query/hash for path comparison\n  const pathOnly = currentPath.split(\"?\")[0].split(\"#\")[0];\n\n  // Specific authentication route prefixes\n  const authPrefixes = [\n    \"/login\",\n    \"/signup\",\n    \"/invites\",\n    \"/password-reset\",\n    \"/session\",\n    \"/auth\",\n    \"/u/account-created\",\n    \"/login-preferences\"\n  ];\n\n  for (const prefix of authPrefixes) {\n    if (pathOnly === prefix || pathOnly.startsWith(prefix + \"/\")) {\n      return true;\n    }\n  }\n\n  // Check query parameters\n  if (\n    typeof window !== \"undefined\" &&\n    window.location &&\n    window.location.search\n  ) {\n    const search = window.location.search.toLowerCase();\n    if (search.includes(\"login=true\") || search.includes(\"signup=true\")) {\n      return true;\n    }\n  }\n\n  // User-configured exclusions from settings.yml\n  if (settings.excluded_routes) {\n    const configured = settings.excluded_routes\n      .split(\",\")\n      .map((item) => item.trim().toLowerCase())\n      .filter(Boolean);\n\n    for (const item of configured) {\n      if (\n        pathOnly === item ||\n        pathOnly.startsWith(item + \"/\") ||\n        pathOnly.includes(item)\n      ) {\n        return true;\n      }\n    }\n  }\n\n  // Check if a modal is already active via Discourse's modal service\n  try {\n    const modal = container?.lookup(\"service:modal\");\n    if (modal?.activeModal) {\n      return true;\n    }\n  } catch (_) {}\n\n  // Check Discourse router's current route\n  try {\n    const router = container?.lookup(\"service:router\");\n    const currentRoute = (router?.currentRouteName || \"\").toLowerCase();\n    if (\n      currentRoute.includes(\"login\") ||\n      currentRoute.includes(\"signup\") ||\n      currentRoute.includes(\"create-account\") ||\n      currentRoute.includes(\"password-reset\") ||\n      currentRoute.includes(\"invite\")\n    ) {\n      return true;\n    }\n  } catch (_) {}\n\n  return false;\n}\n\n/**\n * Main initialization logic used by both modern apiInitializer and legacy initializers.\n */\nexport function initAppPromoter(api) {\n  if (api.container.lookup(\"service:site\")?.__appPromoterInitialized) {\n    return;\n  }\n  const site = api.container.lookup(\"service:site\");\n  if (site) {\n    site.__appPromoterInitialized = true;\n  }\n\n  const modal = api.container.lookup(\"service:modal\");\n  const capabilities = api.container.lookup(\"service:capabilities\");\n\n  let promptSequence = 0;\n\n  api.onPageChange((url) => {\n    promptSequence++;\n    const currentSeq = promptSequence;\n\n    // 1. If already installed as PWA or running inside Discourse Hub, don't show\n    if (capabilities?.isPwa || capabilities?.wasLaunchedFromDiscourseHub) {\n      return;\n    }\n\n    // 2. If user previously dismissed the prompt, don't show\n    if (isDismissed()) {\n      return;\n    }\n\n    // 3. Exclude login, signup, and auth pages\n    if (isExcludedRoute(url, api.container)) {\n      return;\n    }\n\n    // 4. Mobile device filter\n    const isMobileDevice =\n      site?.mobileView ||\n      capabilities?.isAndroid ||\n      capabilities?.isIOS ||\n      capabilities?.isIpadOS ||\n      (typeof navigator !== \"undefined\" &&\n        /Android|iPhone|iPad|iPod/i.test(navigator.userAgent)) ||\n      (typeof window !== \"undefined\" && window.innerWidth <= 768);\n\n    if (settings.show_on_mobile_only && !isMobileDevice) {\n      return;\n    }\n\n    // 5. Schedule prompt with delay\n    const delaySeconds = parseInt(settings.prompt_delay_seconds, 10);\n    const delayMs = Math.max(\n      200,\n      (!isNaN(delaySeconds) ? delaySeconds : 1) * 1000\n    );\n\n    discourseLater(() => {\n      // Abort if route changed during delay\n      if (currentSeq !== promptSequence) {\n        return;\n      }\n\n      // Re-verify conditions right before opening modal\n      if (isDismissed() || isExcludedRoute(url, api.container)) {\n        return;\n      }\n\n      if (modal?.activeModal) {\n        return;\n      }\n\n      modal.show(AppModal);\n    }, delayMs);\n  });\n}\n\nexport default apiInitializer(\"1.8.0\", (api) => {\n  initAppPromoter(api);\n});\n","import Component from \"@glimmer/component\";\nimport { action } from \"@ember/object\";\nimport { service } from \"@ember/service\";\nimport cookie from \"discourse/lib/cookie\";\nimport DButton from \"discourse/components/d-button\";\nimport DModal from \"discourse/components/d-modal\";\nimport I18n from \"discourse-i18n\";\n\nfunction t(key, fallback) {\n  let val = null;\n  try {\n    if (typeof themePrefix === \"function\") {\n      val = I18n.t(themePrefix(key));\n    }\n  } catch (_) {}\n\n  if (!val || (typeof val === \"string\" && val.startsWith(\"[\") && val.endsWith(\"]\"))) {\n    try {\n      val = I18n.t(key);\n    } catch (_) {}\n  }\n\n  if (!val || (typeof val === \"string\" && val.startsWith(\"[\") && val.endsWith(\"]\"))) {\n    return fallback;\n  }\n  return val;\n}\n\nfunction recordDismissal() {\n  const cookieName = settings.app_cookie_name || \"app_modal_closed\";\n  const lifespan = settings.app_cookie_lifespan || \"month\";\n\n  if (lifespan === \"none\") {\n    return;\n  }\n\n  let expiresDays = 30;\n  if (lifespan === \"day\") {\n    expiresDays = 1;\n  } else if (lifespan === \"week\") {\n    expiresDays = 7;\n  } else if (lifespan === \"month\") {\n    expiresDays = 30;\n  } else if (lifespan === \"year\") {\n    expiresDays = 365;\n  }\n\n  const expirationDate = moment().add(expiresDays, \"days\").toDate();\n\n  try {\n    cookie(cookieName, \"true\", {\n      expires: expirationDate,\n      path: \"/\"\n    });\n  } catch (_) {}\n\n  try {\n    if (typeof localStorage !== \"undefined\") {\n      localStorage.setItem(\n        cookieName,\n        JSON.stringify({ closed: true, expires: expirationDate.getTime() })\n      );\n    }\n  } catch (_) {}\n}\n\nexport default class AppInstalledModal extends Component {\n  @service modal;\n\n  get appName() {\n    return settings.app_name || t(\"labels.app_name\", \"Sorumatik\");\n  }\n\n  get appInitial() {\n    return (this.appName || \"S\").charAt(0).toUpperCase();\n  }\n\n  get appSubtitle() {\n    return (\n      settings.app_subtitle ||\n      t(\n        \"app_modal.subtitle\",\n        \"Daha hızlı ve pratik soru çözümü için uygulamayı açın.\"\n      )\n    );\n  }\n\n  get appBadge() {\n    return (\n      settings.app_badge_text || t(\"app_modal.badge\", \"★ 4.9 • Ücretsiz\")\n    );\n  }\n\n  get appLogo() {\n    return settings.app_logo_img || \"\";\n  }\n\n  get openAppLabel() {\n    return t(\"actions.open_app\", \"Uygulamada Aç\");\n  }\n\n  get continueBrowserLabel() {\n    return t(\"actions.continue_browser\", \"Tarayıcıda Devam Et\");\n  }\n\n  get closeLabel() {\n    return t(\"labels.close\", \"Kapat\");\n  }\n\n  get appModalTitle() {\n    return this.appName || t(\"app_modal.title\", \"Sorumatik Uygulaması\");\n  }\n\n  @action\n  openApp() {\n    recordDismissal();\n    this.closeModal();\n    const link =\n      settings.android_appstore_link ||\n      settings.apple_appstore_link ||\n      \"https://sorumatik.co/t/app\";\n    window.location.href = link;\n  }\n\n  @action\n  continueBrowser() {\n    recordDismissal();\n    this.closeModal();\n  }\n\n  @action\n  closeModal() {\n    recordDismissal();\n    if (typeof this.args?.closeModal === \"function\") {\n      this.args.closeModal();\n    } else {\n      this.modal.close();\n    }\n  }\n\n  <template>\n    <DModal\n      @closeModal={{this.closeModal}}\n      @title={{this.appModalTitle}}\n      class=\"app-modal discourse-app-promoter\"\n      @dismissable={{true}}\n    >\n      <:body>\n        <div class=\"promoter-sheet\">\n          <div class=\"promoter-drag-handle\" aria-hidden=\"true\"></div>\n\n          <DButton\n            @class=\"promoter-close-btn btn-flat\"\n            @action={{this.closeModal}}\n            aria-label={{this.closeLabel}}\n          >\n            <svg\n              width=\"14\"\n              height=\"14\"\n              viewBox=\"0 0 24 24\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              stroke-width=\"2.5\"\n              stroke-linecap=\"round\"\n              stroke-linejoin=\"round\"\n            >\n              <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"></line>\n              <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"></line>\n            </svg>\n          </DButton>\n\n          <div class=\"promoter-header\">\n            {{#if this.appLogo}}\n              <img\n                src={{this.appLogo}}\n                alt={{this.appName}}\n                class=\"promoter-icon\"\n              />\n            {{else}}\n              <div class=\"promoter-icon promoter-icon-default\">\n                <span>{{this.appInitial}}</span>\n              </div>\n            {{/if}}\n\n            <div class=\"promoter-meta\">\n              <div class=\"promoter-title-row\">\n                <h3 class=\"promoter-app-name\">{{this.appName}}</h3>\n                {{#if this.appBadge}}\n                  <span class=\"promoter-badge\">{{this.appBadge}}</span>\n                {{/if}}\n              </div>\n              <p class=\"promoter-subtitle\">{{this.appSubtitle}}</p>\n            </div>\n          </div>\n\n          <div class=\"promoter-actions\">\n            <DButton\n              @class=\"btn-primary promoter-btn-cta\"\n              @action={{this.openApp}}\n            >\n              <span class=\"btn-cta-content\">\n                <span class=\"btn-cta-text\">{{this.openAppLabel}}</span>\n              </span>\n            </DButton>\n\n            <DButton\n              @class=\"btn-flat promoter-btn-browser\"\n              @translatedLabel={{this.continueBrowserLabel}}\n              @action={{this.continueBrowser}}\n            />\n          </div>\n        </div>\n      </:body>\n    </DModal>\n  </template>\n}\n","import { withPluginApi } from \"discourse/lib/plugin-api\";\nimport { initAppPromoter } from \"../api-initializers/app-modal-init\";\n\nexport default {\n  name: \"app-modal\",\n\n  initialize() {\n    withPluginApi(\"0.8.7\", (api) => {\n      initAppPromoter(api);\n    });\n  }\n};\n","import * as Mod1 from \"./discourse/api-initializers/app-modal-init\";\nimport * as Mod2 from \"./discourse/components/modal/app-installed-modal\";\nimport * as Mod3 from \"./discourse/components/modal/app-modal\";\nimport * as Mod4 from \"./discourse/initializers/app-modal-init\";\nconst compatModules = {\n  \"discourse/api-initializers/app-modal-init\": Mod1,\n  \"discourse/components/modal/app-installed-modal\": Mod2,\n  \"discourse/components/modal/app-modal\": Mod3,\n  \"discourse/initializers/app-modal-init\": Mod4,\n};\nexport { compatModules };\nexport default compatModules;\n"],"names":["settings","getObjectForTheme","themePrefix","key","t","fallback","val","I18n","_","startsWith","endsWith","recordDismissal","cookieName","app_cookie_name","lifespan","app_cookie_lifespan","expiresDays","expirationDate","moment","add","toDate","cookie","expires","path","localStorage","setItem","JSON","stringify","closed","getTime","AppModal","Component","dt7948","g","this","prototype","service","capabilities","i","modal","appName","app_name","appInitial","charAt","toUpperCase","appSubtitle","app_subtitle","appBadge","app_badge_text","appLogo","app_logo_img","isAndroid","navigator","test","userAgent","isApple","isIOS","isIpadOS","isPwaMode","android_app_type","ctaButtonLabel","continueBrowserLabel","closeLabel","appModalTitle","featureFast","featureNotifications","featureVideoSolutions","featureAiTools","featureFree","handleCtaAction","promptEvent","window","deferredPrompt","prompt","closeModal","link","android_appstore_link","location","href","apple_appstore_link","fallbackLink","n","action","continueBrowser","args","close","setComponentTemplate","createTemplateFactory","id","block","moduleName","scope","DModal","DButton","isStrictMode","isDismissed","localItem","getItem","parsed","parse","Date","now","removeItem","isExcludedRoute","url","container","currentPath","String","toLowerCase","pathname","pathOnly","split","authPrefixes","prefix","search","includes","excluded_routes","configured","map","item","trim","filter","Boolean","lookup","activeModal","router","currentRoute","currentRouteName","initAppPromoter","api","__appPromoterInitialized","site","promptSequence","onPageChange","currentSeq","isPwa","wasLaunchedFromDiscourseHub","isMobileDevice","mobileView","innerWidth","show_on_mobile_only","delaySeconds","parseInt","prompt_delay_seconds","delayMs","Math","max","isNaN","discourseLater","show","addEventListener","event","preventDefault","appModalInit$1","apiInitializer","AppInstalledModal","openAppLabel","openApp","appModalInit","name","initialize","withPluginApi","compatModules","Mod1","Mod2","Mod3"],"mappings":"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"}