{"version":3,"file":"main.BAwZu-.js","sources":["theme-146/virtual:theme","theme-146/discourse/components/sp-announcements.gjs","theme-146/discourse/components/sp-category-cards.gjs","theme-146/discourse/components/sp-featured-topics.gjs","theme-146/discourse/components/sp-hero-banner.gjs","theme-146/discourse/components/sp-hero.gjs","theme-146/discourse/components/sp-upcoming-events.gjs","theme-146/discourse/components/sp-video-library.gjs","theme-146/discourse/components/sp-homepage.gjs","theme-146/connectors/custom-homepage/sailpoint-home.gjs","theme-146/discourse/api-initializers/sailpoint-homepage.gjs","theme-146/virtual:entrypoint:main"],"sourcesContent":["import { getObjectForTheme } from \"discourse/lib/theme-settings-store\";\n\nexport const settings = getObjectForTheme(146);\n\nexport function themePrefix(key) {\n  return `theme_translations.146.${key}`;\n}\n","import Component from \"@glimmer/component\";\nimport { tracked } from \"@glimmer/tracking\";\nimport { trustHTML } from \"@ember/template\";\nimport { ajax } from \"discourse/lib/ajax\";\nimport getURL from \"discourse/lib/get-url\";\nimport { emojiUnescape } from \"discourse/lib/text\";\n\nexport default class SpAnnouncements extends Component {\n  @tracked pinnedTopic = null;\n  @tracked latestTopic = null;\n  @tracked loading = true;\n  @tracked failed = false;\n\n  constructor() {\n    super(...arguments);\n    this.#load();\n  }\n\n  get categorySlug() {\n    return settings?.announcements_category_slug ?? \"announcements\";\n  }\n\n  get pinnedTopicId() {\n    return settings?.pinned_announcement_topic_id ?? 0;\n  }\n\n  get viewAllUrl() {\n    return getURL(`/c/${this.categorySlug}`);\n  }\n\n  #mapTopic(t) {\n    return {\n      id: t.id,\n      title: trustHTML(emojiUnescape(t.fancy_title ?? t.title)),\n      url: getURL(`/t/${t.slug}/${t.id}`),\n      reply_count: t.reply_count,\n      views: t.views,\n      replyLabel: t.reply_count === 1 ? \"reply\" : \"replies\",\n    };\n  }\n\n  async #load() {\n    try {\n      // Always fetch the latest topics from the announcements category\n      const data = await ajax(`/c/${this.categorySlug}/l/latest.json`);\n      const topics = data.topic_list?.topics ?? [];\n\n      // Right card: always the most recent topic\n      this.latestTopic = topics[0] ? this.#mapTopic(topics[0]) : null;\n\n      const pinnedId = this.pinnedTopicId;\n\n      if (pinnedId && pinnedId > 0) {\n        // Left card: fetch the configured topic by ID\n        try {\n          const pinned = await ajax(`/t/${pinnedId}.json`);\n          this.pinnedTopic = {\n            id: pinned.id,\n            title: trustHTML(emojiUnescape(pinned.fancy_title ?? pinned.title)),\n            url: getURL(`/t/${pinned.slug}/${pinned.id}`),\n            reply_count: pinned.reply_count,\n            views: pinned.views,\n            replyLabel: pinned.reply_count === 1 ? \"reply\" : \"replies\",\n          };\n        } catch {\n          // Pinned topic unreachable — fall back to 2nd latest\n          this.pinnedTopic = topics[1] ? this.#mapTopic(topics[1]) : null;\n        }\n      } else {\n        // No pinned ID configured — show 2nd latest on the left\n        this.pinnedTopic = topics[1] ? this.#mapTopic(topics[1]) : null;\n      }\n    } catch {\n      this.failed = true;\n    } finally {\n      this.loading = false;\n    }\n  }\n\n  <template>\n    <section class=\"sp-announcements\">\n      <div class=\"sp-announcements__header\">\n        <h2 class=\"sp-announcements__heading\">Announcements</h2>\n        <a href={{this.viewAllUrl}} class=\"sp-announcements__all\">\n          View all\n        </a>\n      </div>\n\n      {{#if this.loading}}\n        <div class=\"sp-loading-placeholder\">\n          <div class=\"sp-loading-placeholder__bar\"></div>\n          <div class=\"sp-loading-placeholder__bar\"></div>\n          <div\n            class=\"sp-loading-placeholder__bar sp-loading-placeholder__bar--short\"\n          ></div>\n        </div>\n      {{else if this.failed}}\n        <p class=\"sp-empty-state\">Could not load announcements.</p>\n      {{else}}\n        <div class=\"sp-announcements__list\">\n          {{#if this.pinnedTopic}}\n            <a\n              href={{this.pinnedTopic.url}}\n              class=\"sp-announcement-card sp-announcement-card--pinned\"\n            >\n              <span\n                class=\"sp-announcement-card__title\"\n              >{{this.pinnedTopic.title}}</span>\n              <div class=\"sp-announcement-card__meta\">\n                <span class=\"sp-announcement-card__replies\">\n                  {{this.pinnedTopic.reply_count}}\n                  {{this.pinnedTopic.replyLabel}}\n                </span>\n                <span class=\"sp-announcement-card__views\">\n                  {{this.pinnedTopic.views}}\n                  views\n                </span>\n              </div>\n            </a>\n          {{/if}}\n\n          {{#if this.latestTopic}}\n            <a\n              href={{this.latestTopic.url}}\n              class=\"sp-announcement-card sp-announcement-card--latest\"\n            >\n              <span\n                class=\"sp-announcement-card__title\"\n              >{{this.latestTopic.title}}</span>\n              <div class=\"sp-announcement-card__meta\">\n                <span class=\"sp-announcement-card__replies\">\n                  {{this.latestTopic.reply_count}}\n                  {{this.latestTopic.replyLabel}}\n                </span>\n                <span class=\"sp-announcement-card__views\">\n                  {{this.latestTopic.views}}\n                  views\n                </span>\n              </div>\n            </a>\n          {{/if}}\n        </div>\n      {{/if}}\n    </section>\n  </template>\n}\n","import Component from \"@glimmer/component\";\nimport { tracked } from \"@glimmer/tracking\";\nimport { service } from \"@ember/service\";\nimport { trustHTML } from \"@ember/template\";\nimport { ajax } from \"discourse/lib/ajax\";\nimport getURL from \"discourse/lib/get-url\";\n\nexport default class SpCategoryCards extends Component {\n  @service site;\n\n  @tracked categories = [];\n\n  constructor() {\n    super(...arguments);\n    this.#load();\n  }\n\n  get gridStyle() {\n    const count = Math.max(this.categories.length, 1);\n    return trustHTML(`--cat-count: ${count}`);\n  }\n\n  get #configuredIds() {\n    const raw = settings?.featured_category_ids ?? \"\";\n    if (!raw.trim()) {\n      return null;\n    }\n    return raw\n      .split(\"|\")\n      .map((s) => parseInt(s.trim(), 10))\n      .filter((n) => !isNaN(n));\n  }\n\n  async #load() {\n    try {\n      const data = await ajax(\"/categories.json\");\n      const raw = data.category_list?.categories ?? [];\n      const configuredIds = this.#configuredIds;\n      const limit = settings?.max_category_cards ?? 5;\n\n      let source;\n      if (configuredIds?.length) {\n        source = configuredIds\n          .map((id) => raw.find((c) => c.id === id))\n          .filter(Boolean)\n          .slice(0, limit);\n      } else {\n        source = raw\n          .filter((c) => !c.parent_category_id && !c.read_restricted)\n          .slice(0, limit);\n      }\n\n      this.categories = source.map((cat) => ({\n        id: cat.id,\n        name: cat.name,\n        color: cat.color,\n        catStyle: trustHTML(`--cat-color: #${cat.color}`),\n        description_text: cat.description_text,\n        uploaded_logo: cat.uploaded_logo,\n        url: getURL(`/c/${cat.slug}/${cat.id}`),\n      }));\n    } catch {\n      const allSiteCats = this.site.categories ?? [];\n      const configuredIds = this.#configuredIds;\n      const limit = settings?.max_category_cards ?? 5;\n\n      let source;\n      if (configuredIds?.length) {\n        source = configuredIds\n          .map((id) => allSiteCats.find((c) => c.id === id))\n          .filter(Boolean)\n          .slice(0, limit);\n      } else {\n        source = allSiteCats\n          .filter((c) => !c.parent_category_id && !c.read_restricted)\n          .slice(0, limit);\n      }\n\n      this.categories = source.map((cat) => ({\n        id: cat.id,\n        name: cat.name,\n        color: cat.color,\n        catStyle: trustHTML(`--cat-color: #${cat.color}`),\n        description_text: cat.description_text,\n        uploaded_logo: cat.uploaded_logo,\n        url: getURL(`/c/${cat.slug}/${cat.id}`),\n      }));\n    }\n  }\n\n  <template>\n    <div class=\"sp-featured-categories\" style={{this.gridStyle}}>\n      {{#each this.categories as |category|}}\n        <a\n          href={{category.url}}\n          class=\"sp-featured-category\"\n          style={{category.catStyle}}\n        >\n          {{#if category.uploaded_logo}}\n            <div class=\"sp-featured-category__icon\">\n              <img src={{category.uploaded_logo.url}} alt=\"\" />\n            </div>\n          {{/if}}\n          <div class=\"sp-featured-category__body\">\n            <h3 class=\"sp-featured-category__name\">{{category.name}}</h3>\n            {{#if category.description_text}}\n              <p\n                class=\"sp-featured-category__desc\"\n              >{{category.description_text}}</p>\n            {{/if}}\n          </div>\n        </a>\n      {{/each}}\n    </div>\n  </template>\n}\n","import Component from \"@glimmer/component\";\nimport { tracked } from \"@glimmer/tracking\";\nimport { service } from \"@ember/service\";\nimport { trustHTML } from \"@ember/template\";\nimport { ajax } from \"discourse/lib/ajax\";\nimport getURL from \"discourse/lib/get-url\";\nimport { emojiUnescape } from \"discourse/lib/text\";\n\nexport default class SpFeaturedTopics extends Component {\n  @service site;\n\n  @tracked topics = [];\n  @tracked loading = true;\n  @tracked failed = false;\n\n  constructor() {\n    super(...arguments);\n    this.#load();\n  }\n\n  get maxTopics() {\n    return settings?.max_featured_topics ?? 20;\n  }\n\n  get latestUrl() {\n    return getURL(\"/latest\");\n  }\n\n  async #load() {\n    try {\n      const data = await ajax(\"/latest.json\");\n      const raw = data.topic_list?.topics ?? [];\n\n      // Build a set of read-restricted category IDs so we can exclude them\n      const restrictedCategoryIds = new Set(\n        (this.site.categories ?? [])\n          .filter((c) => c.read_restricted)\n          .map((c) => c.id)\n      );\n\n      this.topics = raw\n        .filter(\n          (t) =>\n            t.visible !== false &&\n            !t.archived &&\n            !restrictedCategoryIds.has(t.category_id)\n        )\n        .slice(0, this.maxTopics)\n        .map((t) => {\n          const category = (this.site.categories ?? []).find(\n            (c) => c.id === t.category_id\n          );\n          const lastPosted = t.last_posted_at\n            ? new Date(t.last_posted_at)\n            : null;\n          return {\n            id: t.id,\n            title: trustHTML(emojiUnescape(t.fancy_title ?? t.title)),\n            url: getURL(`/t/${t.slug}/${t.id}`),\n            reply_count: t.reply_count,\n            views: t.views,\n            replyLabel: t.reply_count === 1 ? \"reply\" : \"replies\",\n            closed: t.closed,\n            categoryName: category?.name ?? null,\n            categoryColor: category?.color ? `#${category.color}` : null,\n            catStyle: category?.color\n              ? trustHTML(`--cat-color: #${category.color}`)\n              : null,\n            categoryUrl: category\n              ? getURL(`/c/${category.slug}/${category.id}`)\n              : null,\n            relativeTime: lastPosted ? this.#relativeTime(lastPosted) : null,\n          };\n        });\n    } catch {\n      this.failed = true;\n    } finally {\n      this.loading = false;\n    }\n  }\n\n  #relativeTime(date) {\n    const diff = Math.floor((Date.now() - date.getTime()) / 1000);\n    if (diff < 60) {\n      return \"just now\";\n    }\n    if (diff < 3600) {\n      return `${Math.floor(diff / 60)}m ago`;\n    }\n    if (diff < 86400) {\n      return `${Math.floor(diff / 3600)}h ago`;\n    }\n    if (diff < 2592000) {\n      return `${Math.floor(diff / 86400)}d ago`;\n    }\n    return date.toLocaleDateString(undefined, {\n      month: \"short\",\n      day: \"numeric\",\n    });\n  }\n\n  <template>\n    <section class=\"sp-latest-discussions\">\n      <div class=\"sp-latest-discussions__header\">\n        <h2 class=\"sp-latest-discussions__heading\">Latest Discussions</h2>\n        <a href={{this.latestUrl}} class=\"sp-latest-discussions__view-all\">View\n          all</a>\n      </div>\n\n      {{#if this.loading}}\n        <div class=\"sp-loading-placeholder\">\n          <div class=\"sp-loading-placeholder__bar\"></div>\n          <div class=\"sp-loading-placeholder__bar\"></div>\n          <div\n            class=\"sp-loading-placeholder__bar sp-loading-placeholder__bar--short\"\n          ></div>\n          <div class=\"sp-loading-placeholder__bar\"></div>\n          <div\n            class=\"sp-loading-placeholder__bar sp-loading-placeholder__bar--short\"\n          ></div>\n        </div>\n      {{else if this.failed}}\n        <p class=\"sp-empty-state\">Could not load discussions.</p>\n      {{else if this.topics.length}}\n        <ul class=\"sp-latest-discussions__list\">\n          {{#each this.topics as |topic|}}\n            <li class=\"sp-discussion-item\">\n              <div class=\"sp-discussion-item__main\">\n                <a href={{topic.url}} class=\"sp-discussion-item__title\">\n                  {{topic.title}}\n                </a>\n\n                <div class=\"sp-discussion-item__meta\">\n                  {{#if topic.categoryName}}\n                    <a\n                      href={{topic.categoryUrl}}\n                      class=\"sp-discussion-item__category\"\n                      style={{topic.catStyle}}\n                    >\n                      {{topic.categoryName}}\n                    </a>\n                  {{/if}}\n\n                  {{#if topic.closed}}\n                    <span\n                      class=\"sp-discussion-item__badge sp-discussion-item__badge--closed\"\n                    >\n                      Closed\n                    </span>\n                  {{/if}}\n                </div>\n              </div>\n\n              <div class=\"sp-discussion-item__stats\">\n                <span class=\"sp-discussion-item__stat\" title=\"Replies\">\n                  <svg\n                    viewBox=\"0 0 24 24\"\n                    aria-hidden=\"true\"\n                    class=\"sp-discussion-item__stat-icon\"\n                  >\n                    <path\n                      d=\"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z\"\n                      fill=\"none\"\n                      stroke=\"currentColor\"\n                      stroke-width=\"1.75\"\n                      stroke-linejoin=\"round\"\n                    />\n                  </svg>\n                  {{topic.reply_count}}\n                </span>\n                {{#if topic.relativeTime}}\n                  <span\n                    class=\"sp-discussion-item__time\"\n                  >{{topic.relativeTime}}</span>\n                {{/if}}\n              </div>\n            </li>\n          {{/each}}\n        </ul>\n      {{else}}\n        <p class=\"sp-empty-state\">No public discussions yet.</p>\n      {{/if}}\n    </section>\n  </template>\n}\n","import Component from \"@glimmer/component\";\nimport { tracked } from \"@glimmer/tracking\";\nimport { on } from \"@ember/modifier\";\nimport { action } from \"@ember/object\";\nimport cookie, { removeCookie } from \"discourse/lib/cookie\";\nimport getURL from \"discourse/lib/get-url\";\n\nconst COOKIE_PREFIX = \"sp_hero_banner_dismiss_\";\nconst ENABLED_STATE_KEY = \"sp_hero_banner_enabled_state\";\nconst COLOR_PRESETS = {\n  \"SailPoint Blue (#0033A0)\": \"0033A0\",\n  \"Sky Blue (#2563EB)\": \"2563EB\",\n  \"Indigo (#4F46E5)\": \"4F46E5\",\n  \"Purple (#7C3AED)\": \"7C3AED\",\n  \"Teal (#0F766E)\": \"0F766E\",\n  \"Emerald (#047857)\": \"047857\",\n  \"Amber (#D97706)\": \"D97706\",\n  \"Rose (#E11D48)\": \"E11D48\",\n  \"Slate (#334155)\": \"334155\",\n};\n\nexport default class SpHeroBanner extends Component {\n  @tracked dismissed = false;\n\n  constructor() {\n    super(...arguments);\n    this.#syncEnableCycle();\n    this.dismissed = this.#isDismissed();\n  }\n\n  get version() {\n    return settings?.hero_banner_version ?? 1;\n  }\n\n  get enabled() {\n    return settings?.hero_banner_enabled ?? false;\n  }\n\n  get text() {\n    return settings?.hero_banner_text ?? \"\";\n  }\n\n  get linkUrl() {\n    const raw = settings?.hero_banner_link_url ?? \"\";\n    // Admins can set this to a relative internal path or a full external\n    // URL. getURL() only prefixes relative paths, leaving external links\n    // untouched, but middle-click needs the subfolder present either way.\n    return raw ? getURL(raw) : \"\";\n  }\n\n  get linkLabel() {\n    return settings?.hero_banner_link_label ?? \"Learn more\";\n  }\n\n  get badgeText() {\n    return settings?.hero_banner_badge_text ?? \"Featured\";\n  }\n\n  get dismissDays() {\n    return settings?.hero_banner_dismiss_days ?? 30;\n  }\n\n  get accentColor() {\n    const preset = settings?.hero_banner_accent_color?.trim();\n    const hex = COLOR_PRESETS[preset] ?? preset?.replace(/^#/, \"\");\n    return hex || \"0033A0\";\n  }\n\n  get bannerStyle() {\n    if (this.accentColor) {\n      return `--banner-accent: #${this.accentColor}`;\n    }\n    return null;\n  }\n\n  get isWithinSchedule() {\n    const now = new Date();\n\n    const startStr = settings?.hero_banner_start_date?.trim();\n    if (startStr) {\n      const start = new Date(`${startStr}T00:00:00`);\n      if (now < start) {\n        return false;\n      }\n    }\n\n    const endStr = settings?.hero_banner_end_date?.trim();\n    if (endStr) {\n      const end = new Date(`${endStr}T23:59:59`);\n      if (now > end) {\n        return false;\n      }\n      return true;\n    }\n\n    const duration = settings?.hero_banner_duration_days ?? 0;\n    if (duration > 0 && startStr) {\n      const start = new Date(`${startStr}T00:00:00`);\n      const end = new Date(start);\n      end.setDate(end.getDate() + duration);\n      end.setHours(23, 59, 59, 999);\n      if (now > end) {\n        return false;\n      }\n    }\n\n    return true;\n  }\n\n  get visible() {\n    return (\n      this.enabled &&\n      this.text.trim().length > 0 &&\n      this.isWithinSchedule &&\n      !this.dismissed\n    );\n  }\n\n  #cookieName() {\n    return `${COOKIE_PREFIX}${this.version}`;\n  }\n\n  #campaignId() {\n    return [\n      this.version,\n      this.text.trim(),\n      this.accentColor ?? \"\",\n      settings?.hero_banner_start_date?.trim() ?? \"\",\n      settings?.hero_banner_end_date?.trim() ?? \"\",\n    ].join(\"::\");\n  }\n\n  #syncEnableCycle() {\n    const isEnabled = this.enabled;\n    const prev = localStorage.getItem(ENABLED_STATE_KEY);\n\n    // Banner was turned off then back on — clear any prior dismiss\n    if (isEnabled && prev === \"0\") {\n      removeCookie(this.#cookieName(), { path: \"/\" });\n    }\n\n    localStorage.setItem(ENABLED_STATE_KEY, isEnabled ? \"1\" : \"0\");\n  }\n\n  #isDismissed() {\n    return cookie(this.#cookieName()) === this.#campaignId();\n  }\n\n  @action\n  dismiss(event) {\n    event.preventDefault();\n    event.stopPropagation();\n    cookie(this.#cookieName(), this.#campaignId(), {\n      path: \"/\",\n      expires: this.dismissDays,\n    });\n    this.dismissed = true;\n  }\n\n  <template>\n    {{#if this.visible}}\n      <div\n        class=\"sp-hero-banner\"\n        style={{this.bannerStyle}}\n        role=\"region\"\n        aria-label=\"Announcement\"\n      >\n        <div class=\"sp-hero-banner__body\">\n          {{#if this.badgeText}}\n            <span class=\"sp-hero-banner__badge\">{{this.badgeText}}</span>\n          {{/if}}\n\n          <p class=\"sp-hero-banner__text\">{{this.text}}</p>\n\n          {{#if this.linkUrl}}\n            <a href={{this.linkUrl}} class=\"sp-hero-banner__cta\">\n              {{this.linkLabel}}\n              <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n                <path\n                  d=\"M5 12h14M13 6l6 6-6 6\"\n                  fill=\"none\"\n                  stroke=\"currentColor\"\n                  stroke-width=\"2\"\n                  stroke-linecap=\"round\"\n                  stroke-linejoin=\"round\"\n                />\n              </svg>\n            </a>\n          {{/if}}\n        </div>\n\n        <button\n          type=\"button\"\n          class=\"sp-hero-banner__close\"\n          aria-label=\"Dismiss announcement\"\n          {{on \"click\" this.dismiss}}\n        >\n          <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n            <path\n              d=\"M18 6L6 18M6 6l12 12\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              stroke-width=\"2\"\n              stroke-linecap=\"round\"\n            />\n          </svg>\n        </button>\n      </div>\n    {{/if}}\n  </template>\n}\n","import Component from \"@glimmer/component\";\nimport { tracked } from \"@glimmer/tracking\";\nimport SearchMenu from \"discourse/components/search-menu\";\nimport { ajax } from \"discourse/lib/ajax\";\nimport getURL from \"discourse/lib/get-url\";\nimport SpHeroBanner from \"./sp-hero-banner\";\n\nconst DEFAULT_CHIPS = [\n  { label: \"SailPoint Human Fabric\", url: \"/c/identity-security-cloud/6\" },\n  { label: \"IdentityIQ\", url: \"/c/iiq\" },\n  { label: \"Events\", url: \"/upcoming-events\" },\n  { label: \"Announcements\", url: \"/c/announcements\" },\n];\n\nexport default class SpHero extends Component {\n  @tracked topicCount = null;\n  @tracked userCount = null;\n  @tracked postCount = null;\n\n  constructor() {\n    super(...arguments);\n    this.#loadStats();\n  }\n\n  async #loadStats() {\n    try {\n      const data = await ajax(\"/about.json\");\n      const stats = data.about?.stats ?? {};\n      this.topicCount = this.#formatCount(stats.topic_count);\n      this.userCount = this.#formatCount(stats.user_count);\n      this.postCount = this.#formatCount(stats.post_count);\n    } catch {\n      // silently ignore — stats are decorative\n    }\n  }\n\n  #formatCount(n) {\n    if (!n) {\n      return null;\n    }\n    if (n >= 1000) {\n      return `${(n / 1000).toFixed(n >= 10000 ? 0 : 1)}k`;\n    }\n    return String(n);\n  }\n\n  get heroTitle() {\n    return (\n      settings?.hero_title ?? \"Welcome to the SailPoint Developer Community\"\n    );\n  }\n\n  get heroSubtitle() {\n    return (\n      settings?.hero_subtitle ??\n      \"Connect with identity security experts, get answers, and share what you know.\"\n    );\n  }\n\n  get showSearch() {\n    return settings?.show_search ?? true;\n  }\n\n  get ctaLabel() {\n    return settings?.hero_cta_label ?? \"Browse All Topics\";\n  }\n\n  get ctaUrl() {\n    return getURL(settings?.hero_cta_url ?? \"/latest\");\n  }\n\n  // Left-click is handled by Discourse's router, which already knows about\n  // any subfolder the site is mounted under, so a plain relative href works\n  // fine there. But middle-click / open-in-new-tab does a raw browser\n  // navigation using the literal href, which needs the subfolder prefix\n  // added explicitly — otherwise it 404s on subfolder installs.\n  get chips() {\n    return DEFAULT_CHIPS.map((chip) => ({ ...chip, url: getURL(chip.url) }));\n  }\n\n  <template>\n    <section class=\"sp-hero\">\n      {{! decorative layer — clipped independently so the search dropdown is never cut off }}\n      <div class=\"sp-hero__decorations\" aria-hidden=\"true\">\n        <div class=\"sp-hero__blob sp-hero__blob--1\"></div>\n        <div class=\"sp-hero__blob sp-hero__blob--2\"></div>\n        <div class=\"sp-hero__blob sp-hero__blob--3\"></div>\n      </div>\n\n      <div class=\"sp-hero__content\">\n        <SpHeroBanner />\n\n        <h1 class=\"sp-hero__title\">{{this.heroTitle}}</h1>\n        <p class=\"sp-hero__subtitle\">{{this.heroSubtitle}}</p>\n\n        {{#if this.showSearch}}\n          <div class=\"sp-hero__search\">\n            <SearchMenu />\n          </div>\n        {{/if}}\n\n        <div class=\"sp-hero__chips\">\n          {{#each this.chips as |chip|}}\n            <a href={{chip.url}} class=\"sp-hero__chip\">{{chip.label}}</a>\n          {{/each}}\n        </div>\n\n        <a href={{this.ctaUrl}} class=\"sp-hero__cta btn btn-default\">\n          {{this.ctaLabel}}\n        </a>\n      </div>\n\n      <div class=\"sp-hero__bottom-fade\" aria-hidden=\"true\"></div>\n\n      {{#if this.topicCount}}\n        <div class=\"sp-hero__stats\">\n          <div class=\"sp-hero__stat\">\n            <span class=\"sp-hero__stat-value\">{{this.topicCount}}</span>\n            <span class=\"sp-hero__stat-label\">Topics</span>\n          </div>\n          <div class=\"sp-hero__stat-divider\" aria-hidden=\"true\"></div>\n          <div class=\"sp-hero__stat\">\n            <span class=\"sp-hero__stat-value\">{{this.postCount}}</span>\n            <span class=\"sp-hero__stat-label\">Posts</span>\n          </div>\n          <div class=\"sp-hero__stat-divider\" aria-hidden=\"true\"></div>\n          <div class=\"sp-hero__stat\">\n            <span class=\"sp-hero__stat-value\">{{this.userCount}}</span>\n            <span class=\"sp-hero__stat-label\">Members</span>\n          </div>\n        </div>\n      {{/if}}\n    </section>\n  </template>\n}\n","import Component from \"@glimmer/component\";\nimport { tracked } from \"@glimmer/tracking\";\nimport { concat } from \"@ember/helper\";\nimport { service } from \"@ember/service\";\nimport { trustHTML } from \"@ember/template\";\nimport { ajax } from \"discourse/lib/ajax\";\nimport getURL from \"discourse/lib/get-url\";\nimport { emojiUnescape } from \"discourse/lib/text\";\n\nconst MONTH_ABBR = [\n  \"JAN\",\n  \"FEB\",\n  \"MAR\",\n  \"APR\",\n  \"MAY\",\n  \"JUN\",\n  \"JUL\",\n  \"AUG\",\n  \"SEP\",\n  \"OCT\",\n  \"NOV\",\n  \"DEC\",\n];\n\nexport default class SpUpcomingEvents extends Component {\n  @service site;\n\n  @tracked events = [];\n  @tracked loading = true;\n  @tracked failed = false;\n\n  constructor() {\n    super(...arguments);\n    this.#load();\n  }\n\n  get maxEvents() {\n    return settings?.max_events ?? 50;\n  }\n\n  get showAllUrl() {\n    return getURL(settings?.events_show_all_url ?? \"/upcoming-events\");\n  }\n\n  async #load() {\n    try {\n      const now = new Date();\n\n      // The endpoint has a hard result limit (200) ordered by start date. On\n      // sites with a large backlog of past/ongoing events, an unfiltered\n      // request can fill that limit with old events and push genuinely\n      // upcoming ones out of the response entirely. Ask the server to only\n      // return events starting from now so we don't get truncated out.\n      const data = await ajax(\"/discourse-post-event/events.json\", {\n        data: { after: now.toISOString() },\n      });\n\n      const upcoming = (data.events ?? [])\n        .filter((e) => new Date(e.starts_at).getTime() >= now.getTime())\n        .slice(0, this.maxEvents);\n\n      const withColors = await Promise.all(\n        upcoming.map(async (e) => {\n          const date = new Date(e.starts_at);\n          const topicId = e.post?.topic?.id;\n          const topicSlug = e.post?.topic?.slug ?? topicId;\n          let categoryColor = null;\n\n          let categoryId = e.post?.topic?.category_id ?? e.category_id;\n\n          if (!categoryId && topicId) {\n            try {\n              const topicData = await ajax(`/t/${topicSlug}/${topicId}.json`);\n              categoryId = topicData.category_id;\n            } catch {\n              // ignore, badge will use default color\n            }\n          }\n\n          if (categoryId) {\n            const category = (this.site.categories ?? []).find(\n              (c) => c.id === categoryId\n            );\n            categoryColor = category?.color ? `#${category.color}` : null;\n          }\n\n          const rawTitle =\n            e.post?.topic?.fancy_title ??\n            e.post?.topic?.title ??\n            e.name ??\n            \"Untitled Event\";\n\n          return {\n            id: e.id,\n            title: trustHTML(emojiUnescape(rawTitle)),\n            url: topicId\n              ? getURL(`/t/${topicSlug}/${topicId}`)\n              : this.showAllUrl,\n            month: MONTH_ABBR[date.getMonth()],\n            day: date.getDate(),\n            categoryColor,\n          };\n        })\n      );\n\n      this.events = withColors;\n    } catch {\n      this.failed = true;\n    } finally {\n      this.loading = false;\n    }\n  }\n\n  <template>\n    <section class=\"sp-upcoming-events\">\n      <div class=\"sp-upcoming-events__header\">\n        <h2 class=\"sp-upcoming-events__heading\">\n          <svg\n            class=\"sp-upcoming-events__icon\"\n            viewBox=\"0 0 24 24\"\n            aria-hidden=\"true\"\n          >\n            <rect\n              x=\"3\"\n              y=\"4\"\n              width=\"18\"\n              height=\"18\"\n              rx=\"2\"\n              fill=\"none\"\n              stroke=\"currentColor\"\n              stroke-width=\"1.75\"\n            />\n            <line\n              x1=\"3\"\n              y1=\"9\"\n              x2=\"21\"\n              y2=\"9\"\n              stroke=\"currentColor\"\n              stroke-width=\"1.75\"\n            />\n            <line\n              x1=\"8\"\n              y1=\"2\"\n              x2=\"8\"\n              y2=\"6\"\n              stroke=\"currentColor\"\n              stroke-width=\"1.75\"\n              stroke-linecap=\"round\"\n            />\n            <line\n              x1=\"16\"\n              y1=\"2\"\n              x2=\"16\"\n              y2=\"6\"\n              stroke=\"currentColor\"\n              stroke-width=\"1.75\"\n              stroke-linecap=\"round\"\n            />\n          </svg>\n          Upcoming Events\n        </h2>\n      </div>\n\n      {{#if this.loading}}\n        <div class=\"sp-loading-placeholder\">\n          <div class=\"sp-loading-placeholder__bar\"></div>\n          <div class=\"sp-loading-placeholder__bar\"></div>\n          <div\n            class=\"sp-loading-placeholder__bar sp-loading-placeholder__bar--short\"\n          ></div>\n        </div>\n      {{else if this.failed}}\n        <p class=\"sp-empty-state\">Could not load events.</p>\n      {{else if this.events.length}}\n        <ul class=\"sp-upcoming-events__list\">\n          {{#each this.events as |event|}}\n            <li class=\"sp-event-item\">\n              <a href={{event.url}} class=\"sp-event-item__link\">\n                <div\n                  class=\"sp-event-item__badge\"\n                  style={{if\n                    event.categoryColor\n                    (concat \"--event-color: \" event.categoryColor)\n                  }}\n                >\n                  <span class=\"sp-event-item__month\">{{event.month}}</span>\n                  <span class=\"sp-event-item__day\">{{event.day}}</span>\n                </div>\n                <span class=\"sp-event-item__title\">{{event.title}}</span>\n              </a>\n            </li>\n          {{/each}}\n        </ul>\n\n        <a href={{this.showAllUrl}} class=\"sp-upcoming-events__show-all\">\n          Show all →\n        </a>\n      {{else}}\n        <p class=\"sp-empty-state\">No upcoming events.</p>\n      {{/if}}\n    </section>\n  </template>\n}\n","import Component from \"@glimmer/component\";\nimport { tracked } from \"@glimmer/tracking\";\nimport { trustHTML } from \"@ember/template\";\nimport { ajax } from \"discourse/lib/ajax\";\nimport getURL from \"discourse/lib/get-url\";\nimport { emojiUnescape } from \"discourse/lib/text\";\n\nexport default class SpVideoLibrary extends Component {\n  @tracked videos = [];\n  @tracked loading = true;\n  @tracked failed = false;\n\n  constructor() {\n    super(...arguments);\n    if (this.enabled) {\n      this.#load();\n    } else {\n      this.loading = false;\n    }\n  }\n\n  get enabled() {\n    return settings?.video_library_enabled ?? true;\n  }\n\n  get heading() {\n    return settings?.video_library_heading ?? \"From the Video Library\";\n  }\n\n  get categoryPath() {\n    return settings?.video_library_category_path ?? \"content/video-library\";\n  }\n\n  get categoryId() {\n    return settings?.video_library_category_id ?? 127;\n  }\n\n  get count() {\n    return settings?.video_library_count ?? 3;\n  }\n\n  get topicIds() {\n    const raw = settings?.video_library_topic_ids ?? \"\";\n    return raw\n      .split(\"|\")\n      .map((part) => parseInt(part.trim(), 10))\n      .filter((n) => Number.isInteger(n) && n > 0);\n  }\n\n  get viewAllUrl() {\n    return getURL(`/c/${this.categoryPath}/${this.categoryId}`);\n  }\n\n  async #load() {\n    try {\n      const ids = this.topicIds;\n      const needed = this.count;\n      let pinned = [];\n\n      // Step 1 — build cards for any explicitly pinned IDs.\n      if (ids.length) {\n        const built = await Promise.all(ids.map((id) => this.#buildById(id)));\n        pinned = built.filter(Boolean).slice(0, needed);\n      }\n\n      // Step 2 — if we still have open slots, fill them from the category.\n      const remaining = needed - pinned.length;\n      if (remaining > 0) {\n        const data = await ajax(\n          `/c/${this.categoryPath}/${this.categoryId}.json`\n        );\n        const topics = data.topic_list?.topics ?? [];\n        const pinnedIds = new Set(pinned.map((v) => v.id));\n\n        // Build fill cards directly from the list data — no per-topic fetch\n        // needed, and the list already has slug, title, and image_url. Skip\n        // topics without a thumbnail so we never show an image-less card.\n        const fill = topics\n          .filter((t) => !pinnedIds.has(t.id) && t.image_url)\n          .slice(0, remaining)\n          .map((t) => this.#videoCard(t));\n        this.videos = [...pinned, ...fill];\n      } else {\n        this.videos = pinned;\n      }\n    } catch {\n      this.failed = true;\n    } finally {\n      this.loading = false;\n    }\n  }\n\n  // Build a card from an explicit topic ID chosen in settings. The admin\n  // picked it, so we trust it's a video and don't run the video filter.\n  async #buildById(id) {\n    try {\n      const detail = await ajax(`/t/${id}.json`);\n      const cooked = detail.post_stream?.posts?.[0]?.cooked ?? \"\";\n      const doc = cooked\n        ? new DOMParser().parseFromString(cooked, \"text/html\")\n        : null;\n\n      let image = doc\n        ? this.#pickImage(doc, detail.image_url)\n        : detail.image_url || null;\n\n      if (!image) {\n        image = detail.image_url || null;\n      }\n\n      return {\n        id: detail.id,\n        hasVideo: true,\n        title: trustHTML(emojiUnescape(detail.fancy_title ?? detail.title)),\n        url: getURL(`/t/${detail.slug}/${detail.id}`),\n        image,\n      };\n    } catch {\n      return null;\n    }\n  }\n\n  #videoCard(topic) {\n    return {\n      id: topic.id,\n      hasVideo: true,\n      title: trustHTML(emojiUnescape(topic.fancy_title ?? topic.title)),\n      url: getURL(`/t/${topic.slug}/${topic.id}`),\n      image: topic.image_url || null,\n    };\n  }\n\n  // Choose the best thumbnail in priority order:\n  //   1. an image inside a hidden wrapper (the screenshot pattern)\n  //   2. the topic's representative image from the list JSON\n  //   3. the first real content image (oneboxes, lightboxes, etc.)\n  //   4. a derived YouTube/Vimeo thumbnail\n  #pickImage(doc, topicImageUrl) {\n    const imgs = Array.from(doc.querySelectorAll(\"img\"));\n\n    const srcOf = (img) =>\n      img.getAttribute(\"data-orig-src\") ||\n      img.getAttribute(\"src\") ||\n      img.getAttribute(\"data-src\");\n\n    const isReal = (img) => {\n      const src = srcOf(img);\n      if (!src) {\n        return false;\n      }\n      if (img.classList.contains(\"emoji\") || img.classList.contains(\"avatar\")) {\n        return false;\n      }\n      if (img.closest(\".avatar, .emoji\")) {\n        return false;\n      }\n      return true;\n    };\n\n    // 1. Hidden-wrapper screenshot\n    const hiddenSelector =\n      '[data-wrap=\"hidden\"], .d-wrap[data-wrap], .hidden, details, ' +\n      '.video-thumbnail, [style*=\"display:none\"], [style*=\"display: none\"]';\n    for (const img of imgs) {\n      if (isReal(img) && img.closest(hiddenSelector)) {\n        return srcOf(img);\n      }\n    }\n\n    // 2. Representative image from the topic list\n    if (topicImageUrl) {\n      return topicImageUrl;\n    }\n\n    // 3. First real content image\n    for (const img of imgs) {\n      if (isReal(img)) {\n        return srcOf(img);\n      }\n    }\n\n    // 4. Derived video thumbnail\n    const ytId = this.#youTubeId(doc);\n    if (ytId) {\n      return `https://i.ytimg.com/vi/${ytId}/hqdefault.jpg`;\n    }\n\n    return null;\n  }\n\n  #youTubeId(doc) {\n    const dataEl = doc.querySelector(\"[data-video-id], [data-youtube-id]\");\n    if (dataEl) {\n      const id =\n        dataEl.getAttribute(\"data-video-id\") ||\n        dataEl.getAttribute(\"data-youtube-id\");\n      if (id) {\n        return id;\n      }\n    }\n\n    const urls = [];\n    doc\n      .querySelectorAll(\"iframe[src]\")\n      .forEach((f) => urls.push(f.getAttribute(\"src\")));\n    doc\n      .querySelectorAll(\"a[href]\")\n      .forEach((a) => urls.push(a.getAttribute(\"href\")));\n\n    for (const url of urls) {\n      if (!url) {\n        continue;\n      }\n      const match = url.match(\n        /(?:youtube\\.com\\/(?:embed\\/|watch\\?v=)|youtu\\.be\\/)([\\w-]{11})/\n      );\n      if (match) {\n        return match[1];\n      }\n    }\n    return null;\n  }\n\n  <template>\n    {{#if this.enabled}}\n      <section class=\"sp-video-library\">\n        <div class=\"sp-video-library__header\">\n          <h2 class=\"sp-video-library__heading\">{{this.heading}}</h2>\n          <a href={{this.viewAllUrl}} class=\"sp-video-library__all\">View all</a>\n        </div>\n\n        {{#if this.loading}}\n          <div class=\"sp-video-library__grid\">\n            <div class=\"sp-video-card sp-video-card--skeleton\">\n              <div class=\"sp-video-card__thumb\"></div>\n              <div class=\"sp-video-card__body\">\n                <div class=\"sp-loading-placeholder__bar\"></div>\n                <div\n                  class=\"sp-loading-placeholder__bar sp-loading-placeholder__bar--short\"\n                ></div>\n              </div>\n            </div>\n            <div class=\"sp-video-card sp-video-card--skeleton\">\n              <div class=\"sp-video-card__thumb\"></div>\n              <div class=\"sp-video-card__body\">\n                <div class=\"sp-loading-placeholder__bar\"></div>\n                <div\n                  class=\"sp-loading-placeholder__bar sp-loading-placeholder__bar--short\"\n                ></div>\n              </div>\n            </div>\n            <div class=\"sp-video-card sp-video-card--skeleton\">\n              <div class=\"sp-video-card__thumb\"></div>\n              <div class=\"sp-video-card__body\">\n                <div class=\"sp-loading-placeholder__bar\"></div>\n                <div\n                  class=\"sp-loading-placeholder__bar sp-loading-placeholder__bar--short\"\n                ></div>\n              </div>\n            </div>\n          </div>\n        {{else if this.failed}}\n          <p class=\"sp-empty-state\">Could not load videos.</p>\n        {{else if this.videos.length}}\n          <div class=\"sp-video-library__grid\">\n            {{#each this.videos as |video|}}\n              <a href={{video.url}} class=\"sp-video-card\">\n                <div class=\"sp-video-card__thumb\">\n                  {{#if video.image}}\n                    <img src={{video.image}} alt=\"\" loading=\"lazy\" />\n                  {{/if}}\n                  <span class=\"sp-video-card__play\" aria-hidden=\"true\">\n                    <svg viewBox=\"0 0 24 24\">\n                      <path d=\"M8 5v14l11-7z\" fill=\"currentColor\" />\n                    </svg>\n                  </span>\n                </div>\n                <div class=\"sp-video-card__body\">\n                  <span class=\"sp-video-card__title\">{{video.title}}</span>\n                  <span class=\"sp-video-card__watch\">\n                    Watch video\n                    <svg viewBox=\"0 0 24 24\" aria-hidden=\"true\">\n                      <path\n                        d=\"M5 12h14M13 6l6 6-6 6\"\n                        fill=\"none\"\n                        stroke=\"currentColor\"\n                        stroke-width=\"2\"\n                        stroke-linecap=\"round\"\n                        stroke-linejoin=\"round\"\n                      />\n                    </svg>\n                  </span>\n                </div>\n              </a>\n            {{/each}}\n          </div>\n        {{else}}\n          <p class=\"sp-empty-state\">No videos yet.</p>\n        {{/if}}\n      </section>\n    {{/if}}\n  </template>\n}\n","import SpAnnouncements from \"./sp-announcements\";\nimport SpCategoryCards from \"./sp-category-cards\";\nimport SpFeaturedTopics from \"./sp-featured-topics\";\nimport SpHero from \"./sp-hero\";\nimport SpUpcomingEvents from \"./sp-upcoming-events\";\nimport SpVideoLibrary from \"./sp-video-library\";\n\nexport default <template>\n  <div class=\"sp-homepage\">\n    <SpHero />\n\n    <SpCategoryCards />\n\n    <SpAnnouncements />\n\n    <div class=\"sp-homepage__main\">\n      <div class=\"sp-homepage__primary\">\n        <SpFeaturedTopics />\n      </div>\n\n      <aside class=\"sp-homepage__secondary\">\n        <SpUpcomingEvents />\n      </aside>\n    </div>\n\n    <SpVideoLibrary />\n  </div>\n</template>\n","import SpHomepage from \"../../discourse/components/sp-homepage\";\n\nexport default <template><SpHomepage /></template>\n","import { apiInitializer } from \"discourse/lib/api\";\n\nexport default apiInitializer(() => {\n  // Initialization handled via component connectors.\n});\n","import * as Mod1 from \"./connectors/custom-homepage/sailpoint-home.gjs\";\nimport * as Mod2 from \"./discourse/api-initializers/sailpoint-homepage\";\nimport * as Mod3 from \"./discourse/components/sp-announcements\";\nimport * as Mod4 from \"./discourse/components/sp-category-cards\";\nimport * as Mod5 from \"./discourse/components/sp-featured-topics\";\nimport * as Mod6 from \"./discourse/components/sp-hero-banner\";\nimport * as Mod7 from \"./discourse/components/sp-hero\";\nimport * as Mod8 from \"./discourse/components/sp-homepage\";\nimport * as Mod9 from \"./discourse/components/sp-upcoming-events\";\nimport * as Mod10 from \"./discourse/components/sp-video-library\";\nconst compatModules = {\n  \"connectors/custom-homepage/sailpoint-home\": Mod1,\n  \"discourse/api-initializers/sailpoint-homepage\": Mod2,\n  \"discourse/components/sp-announcements\": Mod3,\n  \"discourse/components/sp-category-cards\": Mod4,\n  \"discourse/components/sp-featured-topics\": Mod5,\n  \"discourse/components/sp-hero-banner\": Mod6,\n  \"discourse/components/sp-hero\": Mod7,\n  \"discourse/components/sp-homepage\": Mod8,\n  \"discourse/components/sp-upcoming-events\": Mod9,\n  \"discourse/components/sp-video-library\": Mod10,\n};\nexport { compatModules };\nexport default compatModules;\n"],"names":["settings","getObjectForTheme","SpAnnouncements","Component","dt7948","g","this","prototype","tracked","pinnedTopic","i","latestTopic","loading","failed","constructor","super","arguments","load","categorySlug","announcements_category_slug","pinnedTopicId","pinned_announcement_topic_id","viewAllUrl","getURL","mapTopic","t","id","title","trustHTML","emojiUnescape","fancy_title","url","slug","reply_count","views","replyLabel","data","ajax","topics","topic_list","pinnedId","pinned","setComponentTemplate","createTemplateFactory","block","moduleName","isStrictMode","SpCategoryCards","service","site","categories","gridStyle","count","Math","max","length","configuredIds","raw","featured_category_ids","trim","split","map","s","parseInt","filter","n","isNaN","category_list","limit","max_category_cards","source","find","c","Boolean","slice","parent_category_id","read_restricted","cat","name","color","catStyle","description_text","uploaded_logo","allSiteCats","SpFeaturedTopics","maxTopics","max_featured_topics","latestUrl","restrictedCategoryIds","Set","visible","archived","has","category_id","category","lastPosted","last_posted_at","Date","closed","categoryName","categoryColor","categoryUrl","relativeTime","date","diff","floor","now","getTime","toLocaleDateString","undefined","month","day","ENABLED_STATE_KEY","COLOR_PRESETS","SpHeroBanner","dismissed","syncEnableCycle","isDismissed","version","hero_banner_version","enabled","hero_banner_enabled","text","hero_banner_text","linkUrl","hero_banner_link_url","linkLabel","hero_banner_link_label","badgeText","hero_banner_badge_text","dismissDays","hero_banner_dismiss_days","accentColor","preset","hero_banner_accent_color","replace","bannerStyle","isWithinSchedule","startStr","hero_banner_start_date","endStr","hero_banner_end_date","duration","hero_banner_duration_days","start","end","setDate","getDate","setHours","cookieName","campaignId","join","isEnabled","prev","localStorage","getItem","removeCookie","path","setItem","cookie","dismiss","event","preventDefault","stopPropagation","expires","action","scope","on","DEFAULT_CHIPS","label","SpHero","topicCount","userCount","postCount","loadStats","stats","about","formatCount","topic_count","user_count","post_count","toFixed","String","heroTitle","hero_title","heroSubtitle","hero_subtitle","showSearch","show_search","ctaLabel","hero_cta_label","ctaUrl","hero_cta_url","chips","chip","SearchMenu","MONTH_ABBR","SpUpcomingEvents","events","maxEvents","max_events","showAllUrl","events_show_all_url","upcoming","after","toISOString","e","starts_at","withColors","Promise","all","async","topicId","post","topic","topicSlug","categoryId","topicData","rawTitle","getMonth","concat","SpVideoLibrary","videos","video_library_enabled","heading","video_library_heading","categoryPath","video_library_category_path","video_library_category_id","video_library_count","topicIds","video_library_topic_ids","part","Number","isInteger","ids","needed","buildById","remaining","pinnedIds","v","fill","image_url","videoCard","detail","cooked","post_stream","posts","doc","DOMParser","parseFromString","image","pickImage","hasVideo","topicImageUrl","imgs","Array","from","querySelectorAll","srcOf","img","getAttribute","isReal","classList","contains","closest","ytId","youTubeId","dataEl","querySelector","urls","forEach","f","push","a","match","__discourseComponentClass","templateOnly","sailpointHome","SpHomepage","sailpointHomepage","apiInitializer","compatModules","Mod1","Mod3","Mod4","Mod5","Mod6","Mod7","Mod8","Mod9","Mod10"],"mappings":"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"}