@openrails/contentkit-ui 0.100.0 → 0.101.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -399,6 +399,13 @@ again. Supply `query.published_within` only when a release-age cutoff is wanted.
399
399
  optionally keep its state in the host's URL. For a homepage preview, pass
400
400
  `popularQuery("7d", { kind: "gallery", limit: 6 })` to a `ContentRail`'s `list`.
401
401
 
402
+ For a historical activity window, pass `period={{ from: "2026-04-01", until:
403
+ "2026-05-01" }}` and `query={{ kind: "gallery" }}`. Dates are UTC, with an
404
+ inclusive start and exclusive end. No preset tab is selected for a custom
405
+ range; selecting a tab calls `onPeriodChange` so the host can replace the range
406
+ in its URL with that rolling preset. `popularQuery` accepts the same range
407
+ object and sends `sort=popular&activity_from=...&activity_until=...`.
408
+
402
409
  ### MediaFolderEditor
403
410
 
404
411
  ```tsx
@@ -853,11 +860,27 @@ access revision current; signed-out viewers do not fetch an inbox.
853
860
  including loading and empty states. Set `presentation="header"` for a portal
854
861
  panel directly below the input, matching its width and following it on resize
855
862
  or scroll: a dimmed backdrop, text rows with colored type icons, and no
856
- thumbnails. Recent-search dates appear when the panel is wide enough. The panel
863
+ thumbnails. Recent searches omit dates. The panel
857
864
  slides downward when opened and honors reduced motion. Its mobile/desktop
858
865
  scroll limit is 70vh/60vh. The default inline
859
- presentation is unchanged. Both presentations keep the provider's result order;
860
- the host owns search-page navigation.
866
+ presentation is unchanged. Both presentations show prefix-matching recent
867
+ queries first (newest first), then matching entities, then content titles. A
868
+ recent query remains selectable while network suggestions debounce or load.
869
+ Guest history persists in localStorage across tabs; account history comes from
870
+ the server, fetched on opening rather than on every keystroke. `recent={false}`
871
+ omits history. Only completed searches are recorded.
872
+
873
+ `GET /v1/typeahead` matches the beginning of a title, entity name or direct
874
+ alias, using the keyword index's case/accent/whitespace normalization. It does
875
+ not expand associated entities, contextual keywords, interior words or typos:
876
+ Inazuma can suggest that artist, but not Business Question merely because
877
+ Inazuma created it. Full `GET /v1/search` retains broader keyword and typo
878
+ matching. Visibility, tenant, language and version eligibility still apply.
879
+ The host owns search-page navigation and suggestion links.
880
+
881
+ Core migration `0010_name_prefix_index` adds the name-only prefix index; apply
882
+ normal ContentKit migrations before serving the new core. Original keyword
883
+ indexes and full-search behavior remain in place.
861
884
  `ReaderSettings` combines language selection and content filters in one dialog:
862
885
 
863
886
  ```tsx
@@ -59,9 +59,14 @@ export type ContentQuery = ContentFilterQuery & ReaderQuery & CardQuery & PageQu
59
59
  activity_until?: string;
60
60
  };
61
61
  export type PopularPeriod = "7d" | "90d" | "365d" | "all";
62
+ /** Whole UTC dates: from inclusive, until exclusive. */
63
+ export interface PopularDateRange {
64
+ from: string;
65
+ until: string;
66
+ }
62
67
  export type PopularQuery = Omit<ContentQuery, "sort" | "activity_from" | "activity_until">;
63
68
  /** Rank activity in the selected window; publication age is an optional separate filter. */
64
- export declare function popularQuery(period?: PopularPeriod, filters?: PopularQuery): ContentQuery;
69
+ export declare function popularQuery(period?: PopularPeriod | PopularDateRange, filters?: PopularQuery): ContentQuery;
65
70
  /** Rank activity between two UTC dates: from inclusive, until exclusive. */
66
71
  export declare function popularBetween(from: string, until: string, filters: PopularQuery & {
67
72
  kind: string;
@@ -2,18 +2,21 @@ import { call as e, routeURL as t } from "./route.js";
2
2
  import { browserSearchHistory as n } from "./browser-search-history.js";
3
3
  //#region src/client/discovery.ts
4
4
  function r(e = "7d", t = {}) {
5
- return {
5
+ return typeof e == "string" ? {
6
6
  ...t,
7
7
  sort: `popular:${e}`
8
+ } : {
9
+ ...t,
10
+ sort: "popular",
11
+ activity_from: e.from,
12
+ activity_until: e.until
8
13
  };
9
14
  }
10
15
  function i(e, t, n) {
11
- return {
12
- ...n,
13
- sort: "popular",
14
- activity_from: e,
15
- activity_until: t
16
- };
16
+ return r({
17
+ from: e,
18
+ until: t
19
+ }, n);
17
20
  }
18
21
  var a = /* @__PURE__ */ new Set([
19
22
  "groups",
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.js","names":[],"sources":["../../src/client/discovery.ts"],"sourcesContent":["import type {\n ActivityContexts,\n ActivityContextsInput,\n ActivityTarget,\n ContentFilters,\n ContentFiltersUpdate,\n ContentPage,\n DailyReleases,\n ExposureInput,\n Exposures,\n RecentSearches,\n ReleaseDates,\n SignalInput,\n Signals,\n Typeahead,\n} from \"./generated/wire.js\";\nimport type { Http } from \"./http.js\";\nimport { call, routeURL } from \"./route.js\";\nimport { browserSearchHistory, type BrowserSearchHistory } from \"./browser-search-history.js\";\n\n/** A popularity period. */\nexport type Period = \"7d\" | \"30d\" | \"90d\" | \"365d\" | \"all\";\n/** A list's order; position orders by the first of `groups` (an ordered group). */\nexport type ListSort = \"newest\" | \"oldest\" | \"title\" | \"popular\" | `popular:${Period}` | \"top_rated\" | `top_rated:${Period}` | \"most_favorited\" | \"most_viewed\" | \"position\" | \"random\";\n/** How locked contents list: marked (lock, the default) or left out (hide). */\nexport type AccessMode = \"lock\" | \"hide\";\n\n/** Which contents a list holds. */\nexport interface ContentFilterQuery {\n kind?: string;\n /** Group ids every listed version is in. */\n groups?: readonly string[];\n /** Group ids no listed version is in. */\n exclude_groups?: readonly string[];\n /** Only contents this group owns: a channel's feed. */\n owner_group?: string;\n /** User ids: only contents one of them is credited on. */\n creators?: readonly string[];\n /** public (anyone opens it now) or the level it stays locked at. */\n access?: readonly (\"public\" | \"tier\" | \"group\" | \"ppv\" | \"group_ppv\")[];\n /** Only contents locked behind one of these tiers. */\n tiers?: readonly string[];\n /** Version traits every listed version has. */\n traits?: readonly string[];\n /** \"name:value\" of the kind's filterable attributes. */\n attribute?: readonly string[];\n /** Published on this day (YYYY-MM-DD) or month (YYYY-MM). */\n released_on?: string;\n /** Only contents published within this age window; independent of the popularity score window. */\n published_within?: Period;\n /** IANA time zone of released_on and release dates; UTC by default. */\n tz?: string;\n /** The signed-in reader's unseen, in-progress or completed contents. */\n view_status?: \"unseen\" | \"in_progress\" | \"completed\";\n}\n\n/** How a list reads to its reader. */\nexport interface ReaderQuery {\n /** Only content with a live version in this language. */\n language?: string;\n /** Titles, names and paths in this language, and each card's preferred version's; language by default. */\n display_language?: string;\n mode?: AccessMode;\n}\n\n/** The group kinds cards name; every kind with a page by default. */\nexport interface CardQuery {\n card_entities?: readonly string[];\n}\n\nexport interface PageQuery {\n cursor?: string;\n limit?: number;\n}\n\nexport type ContentQuery = ContentFilterQuery & ReaderQuery & CardQuery & PageQuery & {\n sort?: ListSort;\n /** Inclusive UTC date (YYYY-MM-DD); requires activity_until, kind and sort=popular. */\n activity_from?: string;\n /** Exclusive UTC date (YYYY-MM-DD); requires activity_from, kind and sort=popular. */\n activity_until?: string;\n};\nexport type PopularPeriod = \"7d\" | \"90d\" | \"365d\" | \"all\";\nexport type PopularQuery = Omit<ContentQuery, \"sort\" | \"activity_from\" | \"activity_until\">;\n\n/** Rank activity in the selected window; publication age is an optional separate filter. */\nexport function popularQuery(period: PopularPeriod = \"7d\", filters: PopularQuery = {}): ContentQuery {\n return { ...filters, sort: `popular:${period}` };\n}\n\n/** Rank activity between two UTC dates: from inclusive, until exclusive. */\nexport function popularBetween(from: string, until: string, filters: PopularQuery & { kind: string }): ContentQuery {\n return { ...filters, sort: \"popular\", activity_from: from, activity_until: until };\n}\n\nexport type SearchQuery = ContentFilterQuery &\n ReaderQuery &\n CardQuery &\n PageQuery & {\n q: string;\n sort?: \"relevance\" | ListSort;\n personalize?: boolean;\n /** Explicit legacy server-side anonymous history. Omit for public search without server history. */\n session?: string;\n };\nexport interface RecentSearchesQuery {\n /** Explicit legacy server-side anonymous history; no anonymous session is created by default. */\n session?: string;\n /** 10 by default, at most 100. */\n limit?: number;\n}\nexport type RailQuery = ContentFilterQuery & ReaderQuery & CardQuery & { limit?: number };\nexport type ReleaseDatesQuery = ContentFilterQuery & ReaderQuery & PageQuery & { by?: \"month\" | \"day\" };\n/** Complete daily metadata for one calendar window, without pagination. */\nexport type DailyReleasesQuery = Omit<ContentFilterQuery, \"released_on\" | \"tz\"> & ReaderQuery & CardQuery & { days?: number; time_zone?: string };\nexport type HistoryQuery = ReaderQuery & CardQuery & PageQuery & { kind?: string; status?: \"seen\" | \"in_progress\" | \"completed\" };\nexport interface TypeaheadQuery extends ReaderQuery {\n q: string;\n /** Only contents of this kind. */\n kind?: string;\n /** The group kinds suggested; every kind with a page by default. */\n entity_kinds?: readonly string[];\n /** Per section: 8 by default, at most 20. */\n limit?: number;\n}\n\n// Comma-joined list parameters; `attribute` repeats instead.\nconst LISTS = new Set([\"groups\", \"exclude_groups\", \"creators\", \"access\", \"tiers\", \"traits\", \"card_entities\", \"entity_kinds\"]);\n\n/** A query with its list parameters comma-joined, as discovery routes read them. */\nexport function query(q: object): Record<string, string | number | boolean | readonly string[] | undefined> {\n const out: Record<string, string | number | boolean | readonly string[] | undefined> = {};\n for (const [k, v] of Object.entries(q)) out[k] = LISTS.has(k) && Array.isArray(v) ? (v.length ? v.join(\",\") : undefined) : v;\n return out;\n}\n\n/**\n * Discovery: lists, search, typeahead, similar and recommended contents,\n * release dates, the reader's content filters and history, signals and exposures.\n */\nexport class DiscoveryClient {\n /** Local anonymous history, isolated from authenticated server history. */\n readonly browserSearches: BrowserSearchHistory;\n\n constructor(private readonly http: Http) {\n this.browserSearches = browserSearchHistory(http.mount(\"discovery\"));\n }\n\n /** Contents as cards, one per content item with the version that fits the reader. */\n list(q: ContentQuery = {}, signal?: AbortSignal): Promise<ContentPage> {\n return call(this.http, \"GET\", \"/contents\", { query: query(q) as never, signal });\n }\n /** A first page is kept among the reader's recent searches. */\n async search(q: SearchQuery, signal?: AbortSignal): Promise<ContentPage> {\n const emit = q.cursor ? null : this.http.captureChanges();\n const out: ContentPage = await call(this.http, \"GET\", \"/search\", { query: query(q) as never, signal });\n emit?.({ type: \"searches.changed\" });\n return out;\n }\n /** The reader's recent searches, newest first, since they last cleared them. */\n recentSearches(q: RecentSearchesQuery = {}, signal?: AbortSignal): Promise<RecentSearches> {\n return call(this.http, \"GET\", \"/me/searches\", { query: q, signal });\n }\n /** Clears one recent search, or all of them. */\n async clearSearches(o: { query?: string; session?: string } = {}): Promise<void> {\n const emit = this.http.captureChanges();\n await call(this.http, \"DELETE\", \"/me/searches\", { query: o });\n emit({ type: \"searches.changed\" });\n }\n /** Contents and groups while the reader types. */\n typeahead(q: TypeaheadQuery, signal?: AbortSignal): Promise<Typeahead> {\n return call(this.http, \"GET\", \"/typeahead\", { query: query(q) as never, signal });\n }\n /** Contents like one, of its kind unless q.kind names another. */\n similar(id: string, q: RailQuery = {}, signal?: AbortSignal): Promise<ContentPage> {\n return call(this.http, \"GET\", \"/contents/{id}/similar\", { params: { id }, query: query(q) as never, signal });\n }\n /** For the signed-in reader. */\n recommendations(q: RailQuery = {}, signal?: AbortSignal): Promise<ContentPage> {\n return call(this.http, \"GET\", \"/recommendations\", { query: query(q) as never, signal });\n }\n /** Per month or day, newest first: how many contents the reader's listing shows released then, and how many are free. */\n releaseDates(q: ReleaseDatesQuery = {}, signal?: AbortSignal): Promise<ReleaseDates> {\n return call(this.http, \"GET\", \"/release-dates\", { query: query(q) as never, signal });\n }\n /** Every visible card in each day; opening or expanding a day needs no further request. */\n releases(q: DailyReleasesQuery = {}, signal?: AbortSignal): Promise<DailyReleases> {\n return call(this.http, \"GET\", \"/releases\", { query: query(q) as never, signal });\n }\n /** Only the current domain's reader-toggleable entities, named in the requested language. */\n async contentFilters(language?: string, signal?: AbortSignal): Promise<ContentFilters> {\n const result = await this.http.request<ContentFilters>(routeURL(this.http, \"GET\", \"/content-filters\", { query: { language } }), { signal, guestPreferences: false });\n this.http.acceptGuestFilters(result.kinds);\n return result;\n }\n /** Replaces this domain's reader settings; other domains' choices remain intact. */\n async setContentFilters(update: ContentFiltersUpdate, language?: string): Promise<ContentFilters> {\n const emit = this.http.captureChanges();\n const out: ContentFilters = await call(this.http, \"PUT\", \"/me/content-filters\", { query: { language }, body: update });\n emit({ type: \"contentFilters.changed\" });\n return out;\n }\n /** What the reader engaged with, most recent first. */\n history(q: HistoryQuery = {}, signal?: AbortSignal): Promise<ContentPage> {\n return call(this.http, \"GET\", \"/me/history\", { query: query(q) as never, signal });\n }\n /** Erases the reader's history: of one content item, one kind or everything. */\n async forgetHistory(o: { kind?: string; content_id?: string } = {}): Promise<void> {\n const emit = this.http.captureChanges();\n await call(this.http, \"DELETE\", \"/me/history\", { query: o });\n emit({ type: \"history.changed\" });\n }\n /** Capture server-owned access and eligibility at an observation's start. */\n activityContexts(targets: readonly ActivityTarget[], session?: string, language = this.http.language()): Promise<ActivityContexts> {\n const body: ActivityContextsInput = { targets: [...targets], session, language };\n return call(this.http, \"POST\", \"/activity-contexts\", { body });\n }\n /** Views and clicks; signed out, of the session named. */\n signals(signals: SignalInput[], session?: string, o: { keepalive?: boolean } = {}): Promise<void> {\n const body: Signals = { session, signals };\n return call(this.http, \"POST\", \"/signals\", { body, keepalive: o.keepalive });\n }\n /** Result lists served, rendered or shown, for click attribution. */\n exposures(exposures: ExposureInput[], session?: string, o: { keepalive?: boolean } = {}): Promise<void> {\n const body: Exposures = { session, exposures };\n return call(this.http, \"POST\", \"/exposures\", { body, keepalive: o.keepalive });\n }\n}\n"],"mappings":";;;AAsFA,SAAgB,EAAa,IAAwB,MAAM,IAAwB,CAAC,GAAiB;CACnG,OAAO;EAAE,GAAG;EAAS,MAAM,WAAW;CAAS;AACjD;AAGA,SAAgB,EAAe,GAAc,GAAe,GAAwD;CAClH,OAAO;EAAE,GAAG;EAAS,MAAM;EAAW,eAAe;EAAM,gBAAgB;CAAM;AACnF;AAkCA,IAAM,oBAAQ,IAAI,IAAI;CAAC;CAAU;CAAkB;CAAY;CAAU;CAAS;CAAU;CAAiB;AAAc,CAAC;AAG5H,SAAgB,EAAM,GAAsF;CAC1G,IAAM,IAAiF,CAAC;CACxF,KAAK,IAAM,CAAC,GAAG,MAAM,OAAO,QAAQ,CAAC,GAAG,EAAI,KAAK,EAAM,IAAI,CAAC,KAAK,MAAM,QAAQ,CAAC,IAAK,EAAE,SAAS,EAAE,KAAK,GAAG,IAAI,KAAA,IAAa;CAC3H,OAAO;AACT;AAMA,IAAa,IAAb,MAA6B;CAIE;CAF7B;CAEA,YAAY,GAA6B;EACvC,AAD2B,KAAA,OAAA,GAC3B,KAAK,kBAAkB,EAAqB,EAAK,MAAM,WAAW,CAAC;CACrE;CAGA,KAAK,IAAkB,CAAC,GAAG,GAA4C;EACrE,OAAO,EAAK,KAAK,MAAM,OAAO,aAAa;GAAE,OAAO,EAAM,CAAC;GAAY;EAAO,CAAC;CACjF;CAEA,MAAM,OAAO,GAAgB,GAA4C;EACvE,IAAM,IAAO,EAAE,SAAS,OAAO,KAAK,KAAK,eAAe,GAClD,IAAmB,MAAM,EAAK,KAAK,MAAM,OAAO,WAAW;GAAE,OAAO,EAAM,CAAC;GAAY;EAAO,CAAC;EAErG,OADA,IAAO,EAAE,MAAM,mBAAmB,CAAC,GAC5B;CACT;CAEA,eAAe,IAAyB,CAAC,GAAG,GAA+C;EACzF,OAAO,EAAK,KAAK,MAAM,OAAO,gBAAgB;GAAE,OAAO;GAAG;EAAO,CAAC;CACpE;CAEA,MAAM,cAAc,IAA0C,CAAC,GAAkB;EAC/E,IAAM,IAAO,KAAK,KAAK,eAAe;EAEtC,AADA,MAAM,EAAK,KAAK,MAAM,UAAU,gBAAgB,EAAE,OAAO,EAAE,CAAC,GAC5D,EAAK,EAAE,MAAM,mBAAmB,CAAC;CACnC;CAEA,UAAU,GAAmB,GAA0C;EACrE,OAAO,EAAK,KAAK,MAAM,OAAO,cAAc;GAAE,OAAO,EAAM,CAAC;GAAY;EAAO,CAAC;CAClF;CAEA,QAAQ,GAAY,IAAe,CAAC,GAAG,GAA4C;EACjF,OAAO,EAAK,KAAK,MAAM,OAAO,0BAA0B;GAAE,QAAQ,EAAE,MAAG;GAAG,OAAO,EAAM,CAAC;GAAY;EAAO,CAAC;CAC9G;CAEA,gBAAgB,IAAe,CAAC,GAAG,GAA4C;EAC7E,OAAO,EAAK,KAAK,MAAM,OAAO,oBAAoB;GAAE,OAAO,EAAM,CAAC;GAAY;EAAO,CAAC;CACxF;CAEA,aAAa,IAAuB,CAAC,GAAG,GAA6C;EACnF,OAAO,EAAK,KAAK,MAAM,OAAO,kBAAkB;GAAE,OAAO,EAAM,CAAC;GAAY;EAAO,CAAC;CACtF;CAEA,SAAS,IAAwB,CAAC,GAAG,GAA8C;EACjF,OAAO,EAAK,KAAK,MAAM,OAAO,aAAa;GAAE,OAAO,EAAM,CAAC;GAAY;EAAO,CAAC;CACjF;CAEA,MAAM,eAAe,GAAmB,GAA+C;EACrF,IAAM,IAAS,MAAM,KAAK,KAAK,QAAwB,EAAS,KAAK,MAAM,OAAO,oBAAoB,EAAE,OAAO,EAAE,YAAS,EAAE,CAAC,GAAG;GAAE;GAAQ,kBAAkB;EAAM,CAAC;EAEnK,OADA,KAAK,KAAK,mBAAmB,EAAO,KAAK,GAClC;CACT;CAEA,MAAM,kBAAkB,GAA8B,GAA4C;EAChG,IAAM,IAAO,KAAK,KAAK,eAAe,GAChC,IAAsB,MAAM,EAAK,KAAK,MAAM,OAAO,uBAAuB;GAAE,OAAO,EAAE,YAAS;GAAG,MAAM;EAAO,CAAC;EAErH,OADA,EAAK,EAAE,MAAM,yBAAyB,CAAC,GAChC;CACT;CAEA,QAAQ,IAAkB,CAAC,GAAG,GAA4C;EACxE,OAAO,EAAK,KAAK,MAAM,OAAO,eAAe;GAAE,OAAO,EAAM,CAAC;GAAY;EAAO,CAAC;CACnF;CAEA,MAAM,cAAc,IAA4C,CAAC,GAAkB;EACjF,IAAM,IAAO,KAAK,KAAK,eAAe;EAEtC,AADA,MAAM,EAAK,KAAK,MAAM,UAAU,eAAe,EAAE,OAAO,EAAE,CAAC,GAC3D,EAAK,EAAE,MAAM,kBAAkB,CAAC;CAClC;CAEA,iBAAiB,GAAoC,GAAkB,IAAW,KAAK,KAAK,SAAS,GAA8B;EACjI,IAAM,IAA8B;GAAE,SAAS,CAAC,GAAG,CAAO;GAAG;GAAS;EAAS;EAC/E,OAAO,EAAK,KAAK,MAAM,QAAQ,sBAAsB,EAAE,QAAK,CAAC;CAC/D;CAEA,QAAQ,GAAwB,GAAkB,IAA6B,CAAC,GAAkB;EAChG,IAAM,IAAgB;GAAE;GAAS;EAAQ;EACzC,OAAO,EAAK,KAAK,MAAM,QAAQ,YAAY;GAAE;GAAM,WAAW,EAAE;EAAU,CAAC;CAC7E;CAEA,UAAU,GAA4B,GAAkB,IAA6B,CAAC,GAAkB;EACtG,IAAM,IAAkB;GAAE;GAAS;EAAU;EAC7C,OAAO,EAAK,KAAK,MAAM,QAAQ,cAAc;GAAE;GAAM,WAAW,EAAE;EAAU,CAAC;CAC/E;AACF"}
1
+ {"version":3,"file":"discovery.js","names":[],"sources":["../../src/client/discovery.ts"],"sourcesContent":["import type {\n ActivityContexts,\n ActivityContextsInput,\n ActivityTarget,\n ContentFilters,\n ContentFiltersUpdate,\n ContentPage,\n DailyReleases,\n ExposureInput,\n Exposures,\n RecentSearches,\n ReleaseDates,\n SignalInput,\n Signals,\n Typeahead,\n} from \"./generated/wire.js\";\nimport type { Http } from \"./http.js\";\nimport { call, routeURL } from \"./route.js\";\nimport { browserSearchHistory, type BrowserSearchHistory } from \"./browser-search-history.js\";\n\n/** A popularity period. */\nexport type Period = \"7d\" | \"30d\" | \"90d\" | \"365d\" | \"all\";\n/** A list's order; position orders by the first of `groups` (an ordered group). */\nexport type ListSort = \"newest\" | \"oldest\" | \"title\" | \"popular\" | `popular:${Period}` | \"top_rated\" | `top_rated:${Period}` | \"most_favorited\" | \"most_viewed\" | \"position\" | \"random\";\n/** How locked contents list: marked (lock, the default) or left out (hide). */\nexport type AccessMode = \"lock\" | \"hide\";\n\n/** Which contents a list holds. */\nexport interface ContentFilterQuery {\n kind?: string;\n /** Group ids every listed version is in. */\n groups?: readonly string[];\n /** Group ids no listed version is in. */\n exclude_groups?: readonly string[];\n /** Only contents this group owns: a channel's feed. */\n owner_group?: string;\n /** User ids: only contents one of them is credited on. */\n creators?: readonly string[];\n /** public (anyone opens it now) or the level it stays locked at. */\n access?: readonly (\"public\" | \"tier\" | \"group\" | \"ppv\" | \"group_ppv\")[];\n /** Only contents locked behind one of these tiers. */\n tiers?: readonly string[];\n /** Version traits every listed version has. */\n traits?: readonly string[];\n /** \"name:value\" of the kind's filterable attributes. */\n attribute?: readonly string[];\n /** Published on this day (YYYY-MM-DD) or month (YYYY-MM). */\n released_on?: string;\n /** Only contents published within this age window; independent of the popularity score window. */\n published_within?: Period;\n /** IANA time zone of released_on and release dates; UTC by default. */\n tz?: string;\n /** The signed-in reader's unseen, in-progress or completed contents. */\n view_status?: \"unseen\" | \"in_progress\" | \"completed\";\n}\n\n/** How a list reads to its reader. */\nexport interface ReaderQuery {\n /** Only content with a live version in this language. */\n language?: string;\n /** Titles, names and paths in this language, and each card's preferred version's; language by default. */\n display_language?: string;\n mode?: AccessMode;\n}\n\n/** The group kinds cards name; every kind with a page by default. */\nexport interface CardQuery {\n card_entities?: readonly string[];\n}\n\nexport interface PageQuery {\n cursor?: string;\n limit?: number;\n}\n\nexport type ContentQuery = ContentFilterQuery & ReaderQuery & CardQuery & PageQuery & {\n sort?: ListSort;\n /** Inclusive UTC date (YYYY-MM-DD); requires activity_until, kind and sort=popular. */\n activity_from?: string;\n /** Exclusive UTC date (YYYY-MM-DD); requires activity_from, kind and sort=popular. */\n activity_until?: string;\n};\nexport type PopularPeriod = \"7d\" | \"90d\" | \"365d\" | \"all\";\n/** Whole UTC dates: from inclusive, until exclusive. */\nexport interface PopularDateRange {\n from: string;\n until: string;\n}\nexport type PopularQuery = Omit<ContentQuery, \"sort\" | \"activity_from\" | \"activity_until\">;\n\n/** Rank activity in the selected window; publication age is an optional separate filter. */\nexport function popularQuery(period: PopularPeriod | PopularDateRange = \"7d\", filters: PopularQuery = {}): ContentQuery {\n return typeof period === \"string\"\n ? { ...filters, sort: `popular:${period}` }\n : { ...filters, sort: \"popular\", activity_from: period.from, activity_until: period.until };\n}\n\n/** Rank activity between two UTC dates: from inclusive, until exclusive. */\nexport function popularBetween(from: string, until: string, filters: PopularQuery & { kind: string }): ContentQuery {\n return popularQuery({ from, until }, filters);\n}\n\nexport type SearchQuery = ContentFilterQuery &\n ReaderQuery &\n CardQuery &\n PageQuery & {\n q: string;\n sort?: \"relevance\" | ListSort;\n personalize?: boolean;\n /** Explicit legacy server-side anonymous history. Omit for public search without server history. */\n session?: string;\n };\nexport interface RecentSearchesQuery {\n /** Explicit legacy server-side anonymous history; no anonymous session is created by default. */\n session?: string;\n /** 10 by default, at most 100. */\n limit?: number;\n}\nexport type RailQuery = ContentFilterQuery & ReaderQuery & CardQuery & { limit?: number };\nexport type ReleaseDatesQuery = ContentFilterQuery & ReaderQuery & PageQuery & { by?: \"month\" | \"day\" };\n/** Complete daily metadata for one calendar window, without pagination. */\nexport type DailyReleasesQuery = Omit<ContentFilterQuery, \"released_on\" | \"tz\"> & ReaderQuery & CardQuery & { days?: number; time_zone?: string };\nexport type HistoryQuery = ReaderQuery & CardQuery & PageQuery & { kind?: string; status?: \"seen\" | \"in_progress\" | \"completed\" };\nexport interface TypeaheadQuery extends ReaderQuery {\n q: string;\n /** Only contents of this kind. */\n kind?: string;\n /** The group kinds suggested; every kind with a page by default. */\n entity_kinds?: readonly string[];\n /** Per section: 8 by default, at most 20. */\n limit?: number;\n}\n\n// Comma-joined list parameters; `attribute` repeats instead.\nconst LISTS = new Set([\"groups\", \"exclude_groups\", \"creators\", \"access\", \"tiers\", \"traits\", \"card_entities\", \"entity_kinds\"]);\n\n/** A query with its list parameters comma-joined, as discovery routes read them. */\nexport function query(q: object): Record<string, string | number | boolean | readonly string[] | undefined> {\n const out: Record<string, string | number | boolean | readonly string[] | undefined> = {};\n for (const [k, v] of Object.entries(q)) out[k] = LISTS.has(k) && Array.isArray(v) ? (v.length ? v.join(\",\") : undefined) : v;\n return out;\n}\n\n/**\n * Discovery: lists, search, typeahead, similar and recommended contents,\n * release dates, the reader's content filters and history, signals and exposures.\n */\nexport class DiscoveryClient {\n /** Local anonymous history, isolated from authenticated server history. */\n readonly browserSearches: BrowserSearchHistory;\n\n constructor(private readonly http: Http) {\n this.browserSearches = browserSearchHistory(http.mount(\"discovery\"));\n }\n\n /** Contents as cards, one per content item with the version that fits the reader. */\n list(q: ContentQuery = {}, signal?: AbortSignal): Promise<ContentPage> {\n return call(this.http, \"GET\", \"/contents\", { query: query(q) as never, signal });\n }\n /** A first page is kept among the reader's recent searches. */\n async search(q: SearchQuery, signal?: AbortSignal): Promise<ContentPage> {\n const emit = q.cursor ? null : this.http.captureChanges();\n const out: ContentPage = await call(this.http, \"GET\", \"/search\", { query: query(q) as never, signal });\n emit?.({ type: \"searches.changed\" });\n return out;\n }\n /** The reader's recent searches, newest first, since they last cleared them. */\n recentSearches(q: RecentSearchesQuery = {}, signal?: AbortSignal): Promise<RecentSearches> {\n return call(this.http, \"GET\", \"/me/searches\", { query: q, signal });\n }\n /** Clears one recent search, or all of them. */\n async clearSearches(o: { query?: string; session?: string } = {}): Promise<void> {\n const emit = this.http.captureChanges();\n await call(this.http, \"DELETE\", \"/me/searches\", { query: o });\n emit({ type: \"searches.changed\" });\n }\n /** Contents and groups while the reader types. */\n typeahead(q: TypeaheadQuery, signal?: AbortSignal): Promise<Typeahead> {\n return call(this.http, \"GET\", \"/typeahead\", { query: query(q) as never, signal });\n }\n /** Contents like one, of its kind unless q.kind names another. */\n similar(id: string, q: RailQuery = {}, signal?: AbortSignal): Promise<ContentPage> {\n return call(this.http, \"GET\", \"/contents/{id}/similar\", { params: { id }, query: query(q) as never, signal });\n }\n /** For the signed-in reader. */\n recommendations(q: RailQuery = {}, signal?: AbortSignal): Promise<ContentPage> {\n return call(this.http, \"GET\", \"/recommendations\", { query: query(q) as never, signal });\n }\n /** Per month or day, newest first: how many contents the reader's listing shows released then, and how many are free. */\n releaseDates(q: ReleaseDatesQuery = {}, signal?: AbortSignal): Promise<ReleaseDates> {\n return call(this.http, \"GET\", \"/release-dates\", { query: query(q) as never, signal });\n }\n /** Every visible card in each day; opening or expanding a day needs no further request. */\n releases(q: DailyReleasesQuery = {}, signal?: AbortSignal): Promise<DailyReleases> {\n return call(this.http, \"GET\", \"/releases\", { query: query(q) as never, signal });\n }\n /** Only the current domain's reader-toggleable entities, named in the requested language. */\n async contentFilters(language?: string, signal?: AbortSignal): Promise<ContentFilters> {\n const result = await this.http.request<ContentFilters>(routeURL(this.http, \"GET\", \"/content-filters\", { query: { language } }), { signal, guestPreferences: false });\n this.http.acceptGuestFilters(result.kinds);\n return result;\n }\n /** Replaces this domain's reader settings; other domains' choices remain intact. */\n async setContentFilters(update: ContentFiltersUpdate, language?: string): Promise<ContentFilters> {\n const emit = this.http.captureChanges();\n const out: ContentFilters = await call(this.http, \"PUT\", \"/me/content-filters\", { query: { language }, body: update });\n emit({ type: \"contentFilters.changed\" });\n return out;\n }\n /** What the reader engaged with, most recent first. */\n history(q: HistoryQuery = {}, signal?: AbortSignal): Promise<ContentPage> {\n return call(this.http, \"GET\", \"/me/history\", { query: query(q) as never, signal });\n }\n /** Erases the reader's history: of one content item, one kind or everything. */\n async forgetHistory(o: { kind?: string; content_id?: string } = {}): Promise<void> {\n const emit = this.http.captureChanges();\n await call(this.http, \"DELETE\", \"/me/history\", { query: o });\n emit({ type: \"history.changed\" });\n }\n /** Capture server-owned access and eligibility at an observation's start. */\n activityContexts(targets: readonly ActivityTarget[], session?: string, language = this.http.language()): Promise<ActivityContexts> {\n const body: ActivityContextsInput = { targets: [...targets], session, language };\n return call(this.http, \"POST\", \"/activity-contexts\", { body });\n }\n /** Views and clicks; signed out, of the session named. */\n signals(signals: SignalInput[], session?: string, o: { keepalive?: boolean } = {}): Promise<void> {\n const body: Signals = { session, signals };\n return call(this.http, \"POST\", \"/signals\", { body, keepalive: o.keepalive });\n }\n /** Result lists served, rendered or shown, for click attribution. */\n exposures(exposures: ExposureInput[], session?: string, o: { keepalive?: boolean } = {}): Promise<void> {\n const body: Exposures = { session, exposures };\n return call(this.http, \"POST\", \"/exposures\", { body, keepalive: o.keepalive });\n }\n}\n"],"mappings":"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"}
@@ -11,7 +11,7 @@ export { BansClient } from './content/bans.js';
11
11
  export { ModerationClient, type HeldQuery } from './content/moderation.js';
12
12
  export { reactionVerb, sameTarget, type BanScope, type ContentChange, type Decision, type HeldKind, type Reaction, type RuleSet, type Sort, type Target } from './content/types.js';
13
13
  export { EntitiesClient, type EntityImageSlot, type EntityQuery, type ManageEntityQuery, type MemberQuery, type MyEntityQuery } from './entities.js';
14
- export { DiscoveryClient, popularQuery, popularBetween, type AccessMode, type CardQuery, type ContentFilterQuery, type ContentQuery, type HistoryQuery, type ListSort, type Period, type PopularPeriod, type PopularQuery, type RailQuery, type ReaderQuery, type RecentSearchesQuery, type ReleaseDatesQuery, type DailyReleasesQuery, type SearchQuery, type TypeaheadQuery, } from './discovery.js';
14
+ export { DiscoveryClient, popularQuery, popularBetween, type AccessMode, type CardQuery, type ContentFilterQuery, type ContentQuery, type HistoryQuery, type ListSort, type Period, type PopularPeriod, type PopularDateRange, type PopularQuery, type RailQuery, type ReaderQuery, type RecentSearchesQuery, type ReleaseDatesQuery, type DailyReleasesQuery, type SearchQuery, type TypeaheadQuery, } from './discovery.js';
15
15
  export { VersionsClient, isPending } from './versions.js';
16
16
  export { emptyReaderMeta, matchAudio, readerMetaProblems, readerNames, type AudioMatch, type ReaderMetaProblem, type ReaderNames } from './reader-meta.js';
17
17
  export { OffersClient } from './offers.js';
@@ -1,9 +1,9 @@
1
- import { PopularPeriod, PopularQuery } from '../../client/discovery.js';
1
+ import { PopularDateRange, PopularPeriod, PopularQuery } from '../../client/discovery.js';
2
2
  import { CardListProps, LockedCards } from './grid.js';
3
3
  export interface PopularContentGridProps extends Omit<CardListProps, "infinite"> {
4
4
  query?: PopularQuery;
5
- /** Controlled period; otherwise the selector starts at 7d. */
6
- period?: PopularPeriod;
5
+ /** Controlled activity window; otherwise the selector starts at 7d. Date ranges require query.kind. */
6
+ period?: PopularPeriod | PopularDateRange;
7
7
  onPeriodChange?: (period: PopularPeriod) => void;
8
8
  locked?: LockedCards;
9
9
  }
@@ -14,13 +14,13 @@ var p = [
14
14
  "all"
15
15
  ];
16
16
  function m({ query: m, period: h, onPeriodChange: g, locked: _, ...v }) {
17
- let y = e(), [b, x] = l("7d"), S = h ?? b, C = c(() => n(S, m), [S, m]), w = (e) => e === "all" ? y.t("listing.period_all") : y.plural("listing.pastDays", Number(e.slice(0, -1)));
17
+ let y = e(), [b, x] = l("7d"), S = h ?? b, C = typeof S == "string" ? S : "custom", w = c(() => n(S, m), [S, m]), T = (e) => e === "all" ? y.t("listing.period_all") : y.plural("listing.pastDays", Number(e.slice(0, -1)));
18
18
  return /* @__PURE__ */ u(t, {
19
19
  appearance: v.appearance,
20
20
  className: f("grid gap-4 text-sm", v.className),
21
21
  "data-ckui": "popular-grid",
22
22
  children: /* @__PURE__ */ d(r, {
23
- value: S,
23
+ value: C,
24
24
  onValueChange: (e) => {
25
25
  if (!e || !p.includes(e)) return;
26
26
  let t = e;
@@ -29,21 +29,27 @@ function m({ query: m, period: h, onPeriodChange: g, locked: _, ...v }) {
29
29
  className: "gap-4",
30
30
  children: [/* @__PURE__ */ u(a, {
31
31
  "aria-label": y.t("listing.popularPeriod"),
32
- className: "grid w-full grid-cols-4 group-data-horizontal/tabs:h-auto sm:w-fit",
32
+ className: "mx-auto grid w-full grid-cols-4 group-data-horizontal/tabs:h-auto sm:w-fit",
33
33
  children: p.map((e) => /* @__PURE__ */ u(o, {
34
34
  value: e,
35
35
  className: "min-h-10 whitespace-normal px-3 py-2 text-center",
36
- children: w(e)
36
+ children: T(e)
37
37
  }, e))
38
- }), /* @__PURE__ */ u(i, {
39
- value: S,
40
- children: /* @__PURE__ */ u(s, {
38
+ }), /* @__PURE__ */ d(i, {
39
+ value: C,
40
+ children: [typeof S != "string" && /* @__PURE__ */ u("p", {
41
+ className: "mb-4 text-center text-muted-foreground",
42
+ children: y.t("listing.activityRange", {
43
+ from: S.from,
44
+ until: S.until
45
+ })
46
+ }), /* @__PURE__ */ u(s, {
41
47
  ...v,
42
48
  surface: v.surface ?? "popular",
43
- query: C,
49
+ query: w,
44
50
  locked: _,
45
51
  infinite: !0
46
- })
52
+ })]
47
53
  })]
48
54
  })
49
55
  });
@@ -1 +1 @@
1
- {"version":3,"file":"popular.js","names":[],"sources":["../../../src/components/content/popular.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport { useMemo, useState } from \"react\";\nimport { popularQuery, type PopularPeriod, type PopularQuery } from \"../../client/discovery.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"#ckui/ui/tabs\";\nimport { ContentGrid, type CardListProps, type LockedCards } from \"./grid.js\";\n\nexport interface PopularContentGridProps extends Omit<CardListProps, \"infinite\"> {\n query?: PopularQuery;\n /** Controlled period; otherwise the selector starts at 7d. */\n period?: PopularPeriod;\n onPeriodChange?: (period: PopularPeriod) => void;\n locked?: LockedCards;\n}\n\nconst PERIODS: readonly PopularPeriod[] = [\"7d\", \"90d\", \"365d\", \"all\"];\n\n/** Rank activity in the selected window, across publication ages, with infinite paging. */\nexport function PopularContentGrid({ query, period, onPeriodChange, locked, ...p }: PopularContentGridProps) {\n const m = useMessages();\n const [ownPeriod, setOwnPeriod] = useState<PopularPeriod>(\"7d\");\n const current = period ?? ownPeriod;\n const list = useMemo(() => popularQuery(current, query), [current, query]);\n const label = (value: PopularPeriod) => value === \"all\" ? m.t(\"listing.period_all\") : m.plural(\"listing.pastDays\", Number(value.slice(0, -1)));\n return (\n <ContentKitUiRoot appearance={p.appearance} className={cn(\"grid gap-4 text-sm\", p.className)} data-ckui=\"popular-grid\">\n <Tabs value={current} onValueChange={(value) => {\n if (!value || !PERIODS.includes(value as PopularPeriod)) return;\n const next = value as PopularPeriod;\n if (period === undefined) setOwnPeriod(next);\n onPeriodChange?.(next);\n }} className=\"gap-4\">\n <TabsList aria-label={m.t(\"listing.popularPeriod\")} className=\"grid w-full grid-cols-4 group-data-horizontal/tabs:h-auto sm:w-fit\">\n {PERIODS.map((value) => (\n <TabsTrigger key={value} value={value} className=\"min-h-10 whitespace-normal px-3 py-2 text-center\">\n {label(value)}\n </TabsTrigger>\n ))}\n </TabsList>\n <TabsContent value={current}>\n <ContentGrid {...p} surface={p.surface ?? \"popular\"} query={list} locked={locked} infinite />\n </TabsContent>\n </Tabs>\n </ContentKitUiRoot>\n );\n}\n"],"mappings":";;;;;;;;;AAgBA,IAAM,IAAoC;CAAC;CAAM;CAAO;CAAQ;AAAK;AAGrE,SAAgB,EAAmB,EAAE,UAAO,WAAQ,mBAAgB,WAAQ,GAAG,KAA8B;CAC3G,IAAM,IAAI,EAAY,GAChB,CAAC,GAAW,KAAgB,EAAwB,IAAI,GACxD,IAAU,KAAU,GACpB,IAAO,QAAc,EAAa,GAAS,CAAK,GAAG,CAAC,GAAS,CAAK,CAAC,GACnE,KAAS,MAAyB,MAAU,QAAQ,EAAE,EAAE,oBAAoB,IAAI,EAAE,OAAO,oBAAoB,OAAO,EAAM,MAAM,GAAG,EAAE,CAAC,CAAC;CAC7I,OACE,kBAAC,GAAD;EAAkB,YAAY,EAAE;EAAY,WAAW,EAAG,sBAAsB,EAAE,SAAS;EAAG,aAAU;EACtG,UAAA,kBAAC,GAAD;GAAM,OAAO;GAAS,gBAAgB,MAAU;IAC9C,IAAI,CAAC,KAAS,CAAC,EAAQ,SAAS,CAAsB,GAAG;IACzD,IAAM,IAAO;IAEb,AADI,MAAW,KAAA,KAAW,EAAa,CAAI,GAC3C,IAAiB,CAAI;GACvB;GAAG,WAAU;GALb,UAAA,CAME,kBAAC,GAAD;IAAU,cAAY,EAAE,EAAE,uBAAuB;IAAG,WAAU;IAC3D,UAAA,EAAQ,KAAK,MACZ,kBAAC,GAAD;KAAgC;KAAO,WAAU;KAC9C,UAAA,EAAM,CAAK;IACD,GAFK,CAEL,CACd;GACO,CAAA,GACV,kBAAC,GAAD;IAAa,OAAO;IAClB,UAAA,kBAAC,GAAD;KAAa,GAAI;KAAG,SAAS,EAAE,WAAW;KAAW,OAAO;KAAc;KAAQ,UAAA;IAAU,CAAA;GACjF,CAAA,CACT;;CACU,CAAA;AAEtB"}
1
+ {"version":3,"file":"popular.js","names":[],"sources":["../../../src/components/content/popular.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport { useMemo, useState } from \"react\";\nimport { popularQuery, type PopularDateRange, type PopularPeriod, type PopularQuery } from \"../../client/discovery.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"#ckui/ui/tabs\";\nimport { ContentGrid, type CardListProps, type LockedCards } from \"./grid.js\";\n\nexport interface PopularContentGridProps extends Omit<CardListProps, \"infinite\"> {\n query?: PopularQuery;\n /** Controlled activity window; otherwise the selector starts at 7d. Date ranges require query.kind. */\n period?: PopularPeriod | PopularDateRange;\n onPeriodChange?: (period: PopularPeriod) => void;\n locked?: LockedCards;\n}\n\nconst PERIODS: readonly PopularPeriod[] = [\"7d\", \"90d\", \"365d\", \"all\"];\n\n/** Rank activity in the selected window, across publication ages, with infinite paging. */\nexport function PopularContentGrid({ query, period, onPeriodChange, locked, ...p }: PopularContentGridProps) {\n const m = useMessages();\n const [ownPeriod, setOwnPeriod] = useState<PopularPeriod>(\"7d\");\n const current = period ?? ownPeriod;\n const selected = typeof current === \"string\" ? current : \"custom\";\n const list = useMemo(() => popularQuery(current, query), [current, query]);\n const label = (value: PopularPeriod) => value === \"all\" ? m.t(\"listing.period_all\") : m.plural(\"listing.pastDays\", Number(value.slice(0, -1)));\n return (\n <ContentKitUiRoot appearance={p.appearance} className={cn(\"grid gap-4 text-sm\", p.className)} data-ckui=\"popular-grid\">\n <Tabs value={selected} onValueChange={(value) => {\n if (!value || !PERIODS.includes(value as PopularPeriod)) return;\n const next = value as PopularPeriod;\n if (period === undefined) setOwnPeriod(next);\n onPeriodChange?.(next);\n }} className=\"gap-4\">\n <TabsList aria-label={m.t(\"listing.popularPeriod\")} className=\"mx-auto grid w-full grid-cols-4 group-data-horizontal/tabs:h-auto sm:w-fit\">\n {PERIODS.map((value) => (\n <TabsTrigger key={value} value={value} className=\"min-h-10 whitespace-normal px-3 py-2 text-center\">\n {label(value)}\n </TabsTrigger>\n ))}\n </TabsList>\n <TabsContent value={selected}>\n {typeof current !== \"string\" && (\n <p className=\"mb-4 text-center text-muted-foreground\">\n {m.t(\"listing.activityRange\", { from: current.from, until: current.until })}\n </p>\n )}\n <ContentGrid {...p} surface={p.surface ?? \"popular\"} query={list} locked={locked} infinite />\n </TabsContent>\n </Tabs>\n </ContentKitUiRoot>\n );\n}\n"],"mappings":";;;;;;;;;AAgBA,IAAM,IAAoC;CAAC;CAAM;CAAO;CAAQ;AAAK;AAGrE,SAAgB,EAAmB,EAAE,UAAO,WAAQ,mBAAgB,WAAQ,GAAG,KAA8B;CAC3G,IAAM,IAAI,EAAY,GAChB,CAAC,GAAW,KAAgB,EAAwB,IAAI,GACxD,IAAU,KAAU,GACpB,IAAW,OAAO,KAAY,WAAW,IAAU,UACnD,IAAO,QAAc,EAAa,GAAS,CAAK,GAAG,CAAC,GAAS,CAAK,CAAC,GACnE,KAAS,MAAyB,MAAU,QAAQ,EAAE,EAAE,oBAAoB,IAAI,EAAE,OAAO,oBAAoB,OAAO,EAAM,MAAM,GAAG,EAAE,CAAC,CAAC;CAC7I,OACE,kBAAC,GAAD;EAAkB,YAAY,EAAE;EAAY,WAAW,EAAG,sBAAsB,EAAE,SAAS;EAAG,aAAU;EACtG,UAAA,kBAAC,GAAD;GAAM,OAAO;GAAU,gBAAgB,MAAU;IAC/C,IAAI,CAAC,KAAS,CAAC,EAAQ,SAAS,CAAsB,GAAG;IACzD,IAAM,IAAO;IAEb,AADI,MAAW,KAAA,KAAW,EAAa,CAAI,GAC3C,IAAiB,CAAI;GACvB;GAAG,WAAU;GALb,UAAA,CAME,kBAAC,GAAD;IAAU,cAAY,EAAE,EAAE,uBAAuB;IAAG,WAAU;IAC3D,UAAA,EAAQ,KAAK,MACZ,kBAAC,GAAD;KAAgC;KAAO,WAAU;KAC9C,UAAA,EAAM,CAAK;IACD,GAFK,CAEL,CACd;GACO,CAAA,GACV,kBAAC,GAAD;IAAa,OAAO;IAApB,UAAA,CACG,OAAO,KAAY,YAClB,kBAAC,KAAD;KAAG,WAAU;KACV,UAAA,EAAE,EAAE,yBAAyB;MAAE,MAAM,EAAQ;MAAM,OAAO,EAAQ;KAAM,CAAC;IACzE,CAAA,GAEL,kBAAC,GAAD;KAAa,GAAI;KAAG,SAAS,EAAE,WAAW;KAAW,OAAO;KAAc;KAAQ,UAAA;IAAU,CAAA,CACjF;GACT,CAAA,CAAA;;CACU,CAAA;AAEtB"}
@@ -14,7 +14,7 @@ export interface SearchBoxProps {
14
14
  /** A suggestion's link; default its canonical path. */
15
15
  href?: (item: Card | GroupCard) => string | undefined;
16
16
  labels?: Labels;
17
- /** The reader's recent searches while the box is empty. Default true. */
17
+ /** Recent searches first, prefix-filtered while typing. Default true. */
18
18
  recent?: boolean;
19
19
  /** A portal dropdown anchored to the header field; default stays inline. */
20
20
  presentation?: "inline" | "header";
@@ -23,7 +23,7 @@ export interface SearchBoxProps {
23
23
  appearance?: ContentKitUiAppearance;
24
24
  }
25
25
  /**
26
- * A search field suggesting contents and groups as the reader types, and
27
- * recent searches while it is empty; Enter searches, or opens the suggestion chosen.
26
+ * Recent query prefixes first, followed by entity and title prefixes. Enter
27
+ * searches, or opens the chosen suggestion; full search can match more deeply.
28
28
  */
29
29
  export declare function SearchBox(p: SearchBoxProps): import('react').JSX.Element;
@@ -5,54 +5,54 @@ import { ContentKitContext as r } from "../../react/context.js";
5
5
  import { Input as i } from "../../ui/input.js";
6
6
  import { useRecentSearches as a, useTypeahead as o } from "../../react/discovery.js";
7
7
  import { labelOf as s } from "../groups/parts.js";
8
- import { useContext as c, useEffect as l, useId as ee, useLayoutEffect as u, useMemo as te, useRef as d, useState as f } from "react";
9
- import { Fragment as p, jsx as m, jsxs as h } from "react/jsx-runtime";
10
- import { cn as g } from "cn";
11
- import { Cancel01Icon as _, Clock01Icon as v, File01Icon as y, Folder01Icon as b, Image01Icon as x, Search01Icon as S, TagsIcon as C, UserIcon as w } from "@hugeicons/core-free-icons";
12
- import { HugeiconsIcon as T } from "@hugeicons/react";
13
- import { createPortal as ne } from "react-dom";
8
+ import { useContext as c, useEffect as ee, useId as te, useLayoutEffect as l, useMemo as ne, useRef as u, useState as d } from "react";
9
+ import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
10
+ import { cn as h } from "cn";
11
+ import { Cancel01Icon as g, Clock01Icon as _, File01Icon as v, Folder01Icon as y, Image01Icon as b, Search01Icon as x, TagsIcon as S, UserIcon as C } from "@hugeicons/core-free-icons";
12
+ import { HugeiconsIcon as w } from "@hugeicons/react";
13
+ import { createPortal as re } from "react-dom";
14
14
  //#region src/components/content/search.tsx
15
- var E = {
15
+ var T = (e) => e.type === "content" ? `c:${e.card.id}` : e.type === "group" ? `g:${e.group.id}` : `r:${e.query}`, E = (e) => e.normalize("NFKD").replace(/[\u0300-\u036f]/g, "").normalize("NFC").toLowerCase().trim().replace(/\s+/g, " "), D = {
16
16
  artist: {
17
- icon: w,
17
+ icon: C,
18
18
  color: "text-blue-500 dark:text-blue-400"
19
19
  },
20
20
  series: {
21
- icon: b,
21
+ icon: y,
22
22
  color: "text-yellow-600 dark:text-yellow-400"
23
23
  },
24
24
  gallery: {
25
- icon: x,
25
+ icon: b,
26
26
  color: "text-green-600 dark:text-green-400"
27
27
  },
28
28
  post: {
29
- icon: y,
29
+ icon: v,
30
30
  color: "text-purple-500 dark:text-purple-400"
31
31
  },
32
32
  blog: {
33
- icon: y,
33
+ icon: v,
34
34
  color: "text-purple-500 dark:text-purple-400"
35
35
  },
36
36
  poll: {
37
- icon: y,
37
+ icon: v,
38
38
  color: "text-purple-500 dark:text-purple-400"
39
39
  },
40
40
  character: {
41
- icon: w,
41
+ icon: C,
42
42
  color: "text-purple-500 dark:text-purple-400"
43
43
  },
44
44
  tag: {
45
- icon: C,
45
+ icon: S,
46
46
  color: "text-orange-500 dark:text-orange-400"
47
47
  }
48
48
  };
49
- function D(e, t, n, r) {
50
- let [i, a] = f({
49
+ function O(e, t, n, r) {
50
+ let [i, a] = d({
51
51
  top: 0,
52
52
  left: 0,
53
53
  width: 0
54
54
  });
55
- return u(() => {
55
+ return l(() => {
56
56
  if (!e || !t || !n.current) return;
57
57
  let i = r.current ?? n.current, o = n.current.ownerDocument.defaultView;
58
58
  if (!o) return;
@@ -76,40 +76,46 @@ function D(e, t, n, r) {
76
76
  r
77
77
  ]), i;
78
78
  }
79
- function O({ kind: e }) {
80
- let t = E[e];
81
- return /* @__PURE__ */ m(T, {
82
- icon: t?.icon ?? S,
79
+ function ie({ kind: e }) {
80
+ let t = D[e];
81
+ return /* @__PURE__ */ p(w, {
82
+ icon: t?.icon ?? x,
83
83
  strokeWidth: 2,
84
- className: g("size-4 shrink-0", t?.color ?? "text-muted-foreground"),
84
+ className: h("size-4 shrink-0", t?.color ?? "text-muted-foreground"),
85
85
  "data-search-kind": e,
86
86
  "aria-hidden": !0
87
87
  });
88
88
  }
89
- function k(u) {
90
- let { t: y, error: b } = t(), x = ee(), C = c(r)?.navigate, [w, E] = f(u.defaultValue ?? ""), [k, A] = f(!1), [j, M] = f(-1), N = d(null), P = d(null), F = d(null), I = u.presentation === "header", L = D(k, I, N, F), { top: R } = L, z = !w.trim(), B = o(w, {
91
- kind: u.kind,
92
- entity_kinds: u.groupKinds,
93
- client: u.client
89
+ function k(l) {
90
+ let { t: v, error: y } = t(), b = te(), S = c(r)?.navigate, [C, D] = d(l.defaultValue ?? ""), [k, A] = d(!1), [j, M] = d(), N = u(null), P = u(null), F = u(null), I = l.presentation === "header", L = O(k, I, N, F), { top: R } = L, z = !C.trim(), B = o(C, {
91
+ kind: l.kind,
92
+ entity_kinds: l.groupKinds,
93
+ client: l.client
94
94
  }), V = a({
95
- enabled: u.recent !== !1 && k && z,
96
- client: u.client
97
- }), H = te(() => z ? V.searches.map((e) => ({
95
+ enabled: l.recent !== !1 && k,
96
+ client: l.client
97
+ }), H = E(C), U = B.query === C.trim(), W = ne(() => [...l.recent === !1 ? [] : V.searches.filter((e) => E(e.query).startsWith(H)).map((e) => ({
98
98
  type: "recent",
99
99
  query: e.query
100
- })) : [...B.contents.map((e) => ({
101
- type: "content",
102
- card: e
103
- })), ...B.entities.map((e) => ({
100
+ })), ...!z && U ? [...B.entities.map((e) => ({
104
101
  type: "group",
105
102
  group: e
106
- }))], [
103
+ })), ...B.contents.map((e) => ({
104
+ type: "content",
105
+ card: e
106
+ }))] : []], [
107
+ l.recent,
108
+ H,
107
109
  z,
110
+ U,
108
111
  V.searches,
109
112
  B.contents,
110
113
  B.entities
111
- ]), U = z || B.query === w.trim(), W = U ? H : [], G = W[j], K = z ? V.loading : !U || B.loading, q = z && u.recent !== !1, J = z ? !I && q && !V.error ? "contents.noRecentSearches" : "contents.searchHint" : "contents.noResults";
112
- l(() => {
114
+ ]), G = j === null ? Math.min(0, W.length - 1) : W.findIndex((e) => T(e) === j), K = W[G], q = (e) => {
115
+ let t = W[e];
116
+ M(t ? T(t) : e >= 0 ? null : void 0);
117
+ }, ae = V.loading || !z && (!U || B.loading), J = z && l.recent !== !1, oe = z ? !I && J && !V.error ? "contents.noRecentSearches" : "contents.searchHint" : "contents.noResults";
118
+ ee(() => {
113
119
  if (!k) return;
114
120
  let e = (e) => {
115
121
  !N.current?.contains(e.target) && !P.current?.contains(e.target) && A(!1);
@@ -119,216 +125,216 @@ function k(u) {
119
125
  let Y = () => {
120
126
  A(!0);
121
127
  }, X = (e) => {
122
- A(!1), e && u.onSearch(e);
128
+ A(!1), e && l.onSearch(e);
123
129
  }, Z = (e) => {
124
- if (e.type === "recent") return E(e.query), X(e.query);
125
- let t = u.href ? u.href(e.type === "content" ? e.card : e.group) : e.type === "content" ? e.card.path : e.group.path;
126
- A(!1), t && (C ? C(t) : location.assign(t));
130
+ if (e.type === "recent") return D(e.query), X(e.query);
131
+ let t = l.href ? l.href(e.type === "content" ? e.card : e.group) : e.type === "content" ? e.card.path : e.group.path;
132
+ A(!1), t && (S ? S(t) : location.assign(t));
127
133
  }, Q = (e) => {
128
- e.key === "Escape" && (e.preventDefault(), F.current?.focus(), A(!1), M(-1));
129
- }, $ = /* @__PURE__ */ h(p, { children: [
130
- q && /* @__PURE__ */ h("div", {
131
- className: g("flex items-center justify-between gap-2 text-muted-foreground", I ? "mb-4 text-base font-semibold" : "px-2 py-1 text-xs"),
132
- children: [/* @__PURE__ */ h("span", {
133
- id: `${x}-recent`,
134
+ e.key === "Escape" && (e.preventDefault(), F.current?.focus(), A(!1), M(void 0));
135
+ }, $ = /* @__PURE__ */ m(f, { children: [
136
+ J && /* @__PURE__ */ m("div", {
137
+ className: h("flex items-center justify-between gap-2 text-muted-foreground", I ? "mb-4 text-base font-semibold" : "px-2 py-1 text-xs"),
138
+ children: [/* @__PURE__ */ m("span", {
139
+ id: `${b}-recent`,
134
140
  className: "flex items-center gap-2",
135
- children: [I && /* @__PURE__ */ m(T, {
136
- icon: v,
141
+ children: [I && /* @__PURE__ */ p(w, {
142
+ icon: _,
137
143
  strokeWidth: 2,
138
144
  className: "size-5",
139
145
  "aria-hidden": !0
140
- }), y("contents.recentSearches")]
141
- }), W.length > 0 && /* @__PURE__ */ m("button", {
146
+ }), v("contents.recentSearches")]
147
+ }), W.length > 0 && /* @__PURE__ */ p("button", {
142
148
  type: "button",
143
149
  className: "rounded px-1 hover:text-foreground",
144
150
  onMouseDown: (e) => {
145
151
  e.preventDefault();
146
152
  },
147
153
  onClick: () => void V.clear(),
148
- children: y(I ? "contents.clearAllRecent" : "contents.clearRecent")
154
+ children: v(I ? "contents.clearAllRecent" : "contents.clearRecent")
149
155
  })]
150
156
  }),
151
- /* @__PURE__ */ m("ul", {
152
- id: `${x}-list`,
157
+ /* @__PURE__ */ p("ul", {
158
+ id: `${b}-list`,
153
159
  role: "listbox",
154
- "aria-label": y(z ? "contents.recentSearches" : "contents.suggestions"),
155
- className: g("grid", I && "gap-2"),
156
- children: W.map((t, n) => /* @__PURE__ */ m("li", {
157
- id: `${x}-${n}`,
160
+ "aria-label": v(z ? "contents.recentSearches" : "contents.suggestions"),
161
+ className: h("grid", I && "gap-2"),
162
+ children: W.map((t, n) => /* @__PURE__ */ p("li", {
163
+ id: `${b}-${n}`,
158
164
  role: "option",
159
- "aria-selected": n === j,
165
+ "aria-selected": n === G,
160
166
  "data-ckui": "suggestion",
161
167
  "data-type": t.type,
162
- className: g("flex cursor-pointer items-center", I ? t.type === "recent" ? "gap-2 rounded-md p-3 text-base hover:bg-foreground/10" : "gap-3 rounded-md px-4 py-1 text-base font-medium hover:bg-foreground/10" : "gap-2 px-2 py-1.5", n === j && "bg-accent text-accent-foreground"),
163
- onMouseEnter: () => M(n),
168
+ className: h("flex cursor-pointer items-center", I ? t.type === "recent" ? "gap-2 rounded-md p-3 text-base hover:bg-foreground/10" : "gap-3 rounded-md px-4 py-1 text-base font-medium hover:bg-foreground/10" : "gap-2 px-2 py-1.5", n === G && "bg-accent text-accent-foreground"),
169
+ onMouseEnter: () => M(T(t)),
164
170
  onMouseDown: (e) => {
165
171
  e.preventDefault(), Z(t);
166
172
  },
167
- children: I && t.type !== "recent" ? /* @__PURE__ */ h(p, { children: [
168
- /* @__PURE__ */ m(O, { kind: t.type === "content" ? t.card.kind : t.group.kind }),
169
- /* @__PURE__ */ m("span", {
173
+ children: I && t.type !== "recent" ? /* @__PURE__ */ m(f, { children: [
174
+ /* @__PURE__ */ p(ie, { kind: t.type === "content" ? t.card.kind : t.group.kind }),
175
+ /* @__PURE__ */ p("span", {
170
176
  className: "sr-only",
171
- children: s(u.labels, t.type === "content" ? t.card.kind : t.group.kind)
177
+ children: s(l.labels, t.type === "content" ? t.card.kind : t.group.kind)
172
178
  }),
173
- /* @__PURE__ */ m("span", {
179
+ /* @__PURE__ */ p("span", {
174
180
  className: "min-w-0 flex-1 truncate",
175
181
  children: t.type === "content" ? t.card.title || t.card.code : t.group.name || t.group.slug
176
182
  })
177
- ] }) : t.type === "content" ? /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m("span", {
183
+ ] }) : t.type === "content" ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p("span", {
178
184
  className: "h-10 w-8 shrink-0 overflow-hidden rounded bg-muted",
179
- children: /* @__PURE__ */ m(e, {
185
+ children: /* @__PURE__ */ p(e, {
180
186
  outputs: t.card.cover,
181
187
  alt: "",
182
188
  fit: "cover",
183
189
  className: "size-full"
184
190
  })
185
- }), /* @__PURE__ */ m("span", {
191
+ }), /* @__PURE__ */ p("span", {
186
192
  className: "min-w-0 truncate",
187
193
  children: t.card.title || t.card.code
188
- })] }) : t.type === "group" ? /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m("span", {
194
+ })] }) : t.type === "group" ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p("span", {
189
195
  className: "min-w-0 flex-1 truncate",
190
196
  children: t.group.name || t.group.slug
191
- }), /* @__PURE__ */ m("span", {
197
+ }), /* @__PURE__ */ p("span", {
192
198
  className: "text-xs text-muted-foreground",
193
- children: s(u.labels, t.group.kind)
194
- })] }) : /* @__PURE__ */ h(p, { children: [
195
- /* @__PURE__ */ m(T, {
196
- icon: I ? S : v,
199
+ children: s(l.labels, t.group.kind)
200
+ })] }) : /* @__PURE__ */ m(f, { children: [
201
+ /* @__PURE__ */ p(w, {
202
+ icon: I ? x : _,
197
203
  strokeWidth: 2,
198
204
  className: "size-4 shrink-0 text-muted-foreground",
199
205
  "aria-hidden": !0
200
206
  }),
201
- /* @__PURE__ */ m("span", {
207
+ /* @__PURE__ */ p("span", {
202
208
  className: "min-w-0 flex-1 truncate",
203
209
  children: t.query
204
210
  }),
205
- /* @__PURE__ */ m("button", {
211
+ /* @__PURE__ */ p("button", {
206
212
  type: "button",
207
213
  className: "rounded p-0.5 text-muted-foreground hover:text-foreground",
208
- "aria-label": y("contents.removeRecent", { q: t.query }),
214
+ "aria-label": v("contents.removeRecent", { q: t.query }),
209
215
  onMouseDown: (e) => {
210
216
  e.preventDefault(), e.stopPropagation();
211
217
  },
212
218
  onClick: () => void V.clear(t.query),
213
- children: /* @__PURE__ */ m(T, {
214
- icon: _,
219
+ children: /* @__PURE__ */ p(w, {
220
+ icon: g,
215
221
  strokeWidth: 2,
216
222
  className: "size-3.5",
217
223
  "aria-hidden": !0
218
224
  })
219
225
  })
220
226
  ] })
221
- }, t.type === "content" ? `c:${t.card.id}` : t.type === "group" ? `g:${t.group.id}` : `r:${t.query}`))
227
+ }, T(t)))
222
228
  }),
223
- K ? /* @__PURE__ */ m("div", {
229
+ ae ? /* @__PURE__ */ p("div", {
224
230
  role: "status",
225
- className: g("text-muted-foreground", I ? "flex justify-center py-4" : "px-3 py-2"),
226
- children: I ? /* @__PURE__ */ h(p, { children: [/* @__PURE__ */ m("span", {
231
+ className: h("text-muted-foreground", I ? "flex justify-center py-4" : "px-3 py-2"),
232
+ children: I ? /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p("span", {
227
233
  className: "size-6 animate-spin rounded-full border-2 border-muted border-t-foreground motion-reduce:animate-none",
228
234
  "aria-hidden": !0
229
- }), /* @__PURE__ */ m("span", {
235
+ }), /* @__PURE__ */ p("span", {
230
236
  className: "sr-only",
231
- children: y("contents.loading")
232
- })] }) : y("contents.loading")
233
- }) : !z && B.error ? /* @__PURE__ */ m("p", {
237
+ children: v("contents.loading")
238
+ })] }) : v("contents.loading")
239
+ }) : !z && B.error ? /* @__PURE__ */ p("p", {
234
240
  role: "alert",
235
- className: g("px-3 py-2 text-destructive", I && "text-center"),
236
- children: b(B.error)
237
- }) : W.length === 0 && /* @__PURE__ */ h("div", {
241
+ className: h("px-3 py-2 text-destructive", I && "text-center"),
242
+ children: y(B.error)
243
+ }) : W.length === 0 && /* @__PURE__ */ m("div", {
238
244
  role: "status",
239
- className: g("text-muted-foreground", I ? "flex flex-col items-center gap-2 py-8 text-center" : "px-3 py-2"),
240
- children: [I && /* @__PURE__ */ m(T, {
241
- icon: S,
245
+ className: h("text-muted-foreground", I ? "flex flex-col items-center gap-2 py-8 text-center" : "px-3 py-2"),
246
+ children: [I && /* @__PURE__ */ p(w, {
247
+ icon: x,
242
248
  strokeWidth: 2,
243
249
  className: "size-8",
244
250
  "aria-hidden": !0
245
- }), /* @__PURE__ */ m("p", { children: y(J, { q: w.trim() }) })]
251
+ }), /* @__PURE__ */ p("p", { children: v(oe, { q: C.trim() }) })]
246
252
  })
247
253
  ] });
248
- return /* @__PURE__ */ h(n, {
254
+ return /* @__PURE__ */ m(n, {
249
255
  ref: N,
250
- appearance: u.appearance,
251
- className: g("relative text-sm", u.className),
256
+ appearance: l.appearance,
257
+ className: h("relative text-sm", l.className),
252
258
  "data-ckui": "search-box",
253
259
  onBlur: (e) => {
254
260
  !e.currentTarget.contains(e.relatedTarget) && !P.current?.contains(e.relatedTarget) && A(!1);
255
261
  },
256
- children: [/* @__PURE__ */ h("form", {
262
+ children: [/* @__PURE__ */ m("form", {
257
263
  role: "search",
258
264
  className: "relative",
259
265
  onSubmit: (e) => {
260
- if (e.preventDefault(), k && G) return Z(G);
261
- X(w.trim());
266
+ if (e.preventDefault(), k && K) return Z(K);
267
+ X(C.trim());
262
268
  },
263
269
  children: [
264
- I ? /* @__PURE__ */ m("button", {
270
+ I ? /* @__PURE__ */ p("button", {
265
271
  type: "submit",
266
272
  className: "absolute top-1/2 left-2.5 -translate-y-1/2 rounded text-muted-foreground hover:text-foreground focus-visible:outline-2 focus-visible:outline-ring",
267
- "aria-label": y("contents.search"),
268
- children: /* @__PURE__ */ m(T, {
269
- icon: S,
273
+ "aria-label": v("contents.search"),
274
+ children: /* @__PURE__ */ p(w, {
275
+ icon: x,
270
276
  strokeWidth: 2,
271
277
  className: "size-4",
272
278
  "aria-hidden": !0
273
279
  })
274
- }) : /* @__PURE__ */ m(T, {
275
- icon: S,
280
+ }) : /* @__PURE__ */ p(w, {
281
+ icon: x,
276
282
  strokeWidth: 2,
277
283
  className: "pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground",
278
284
  "aria-hidden": !0
279
285
  }),
280
- /* @__PURE__ */ m(i, {
286
+ /* @__PURE__ */ p(i, {
281
287
  ref: F,
282
288
  type: I ? "text" : "search",
283
289
  role: "combobox",
284
- "aria-label": y("contents.search"),
290
+ "aria-label": v("contents.search"),
285
291
  "aria-expanded": k,
286
- "aria-controls": `${x}-list`,
287
- "aria-activedescendant": k && G ? `${x}-${j}` : void 0,
292
+ "aria-controls": `${b}-list`,
293
+ "aria-activedescendant": k && K ? `${b}-${G}` : void 0,
288
294
  "aria-autocomplete": "list",
289
295
  autoComplete: "off",
290
- className: g("h-9 ps-8", I && "rounded-full border-border/50 bg-foreground/10 pe-9 text-base shadow-none md:text-base"),
291
- value: w,
292
- placeholder: u.placeholder ?? y("contents.searchPlaceholder"),
296
+ className: h("h-9 ps-8", I && "rounded-full border-border/50 bg-foreground/10 pe-9 text-base shadow-none md:text-base"),
297
+ value: C,
298
+ placeholder: l.placeholder ?? v("contents.searchPlaceholder"),
293
299
  onChange: (e) => {
294
- E(e.target.value), A(!0), M(-1);
300
+ D(e.target.value), A(!0), M(void 0);
295
301
  },
296
302
  onFocus: Y,
297
303
  onClick: Y,
298
304
  onKeyDown: (e) => {
299
305
  if (e.key === "Escape") {
300
- e.preventDefault(), A(!1), M(-1);
306
+ e.preventDefault(), A(!1), M(void 0);
301
307
  return;
302
308
  }
303
- e.key === "ArrowDown" ? (e.preventDefault(), Y(), M((e) => k ? Math.min(W.length - 1, e + 1) : 0)) : e.key === "ArrowUp" && k && (e.preventDefault(), M((e) => Math.max(-1, e - 1)));
309
+ e.key === "ArrowDown" ? (e.preventDefault(), Y(), q(k ? Math.min(W.length - 1, G + 1) : 0)) : e.key === "ArrowUp" && k && (e.preventDefault(), q(Math.max(-1, G - 1)));
304
310
  }
305
311
  }),
306
- I && (w || k) && /* @__PURE__ */ m("button", {
312
+ I && (C || k) && /* @__PURE__ */ p("button", {
307
313
  type: "button",
308
314
  className: "absolute top-1/2 right-2.5 -translate-y-1/2 rounded p-0.5 text-muted-foreground hover:text-foreground focus-visible:outline-2 focus-visible:outline-ring",
309
- "aria-label": y(w ? "contents.clearSearch" : "common.close"),
315
+ "aria-label": v(C ? "contents.clearSearch" : "common.close"),
310
316
  onMouseDown: (e) => e.preventDefault(),
311
317
  onClick: () => {
312
- F.current?.focus(), M(-1), w ? (E(""), A(!0)) : A(!1);
318
+ F.current?.focus(), M(void 0), C ? (D(""), A(!0)) : A(!1);
313
319
  },
314
- children: /* @__PURE__ */ m(T, {
315
- icon: _,
320
+ children: /* @__PURE__ */ p(w, {
321
+ icon: g,
316
322
  strokeWidth: 2,
317
323
  className: "size-4",
318
324
  "aria-hidden": !0
319
325
  })
320
326
  })
321
327
  ]
322
- }), k && (I ? ne(/* @__PURE__ */ h(n, {
323
- appearance: u.appearance,
328
+ }), k && (I ? re(/* @__PURE__ */ m(n, {
329
+ appearance: l.appearance,
324
330
  className: "fixed inset-x-0 bottom-0 z-[70] text-sm",
325
331
  style: { top: R },
326
332
  "data-ckui": "search-layer",
327
- children: [/* @__PURE__ */ m("div", {
333
+ children: [/* @__PURE__ */ p("div", {
328
334
  className: "absolute inset-0 bg-black/30 backdrop-blur-sm",
329
335
  "data-ckui": "search-backdrop",
330
336
  "aria-hidden": !0
331
- }), /* @__PURE__ */ m("div", {
337
+ }), /* @__PURE__ */ p("div", {
332
338
  ref: P,
333
339
  style: {
334
340
  width: L.width,
@@ -337,16 +343,16 @@ function k(u) {
337
343
  className: "relative origin-top animate-[search-expand_300ms_ease-out] rounded-lg border border-border bg-background text-foreground shadow-lg transition-none motion-reduce:animate-none",
338
344
  "data-ckui": "search-panel",
339
345
  onKeyDown: Q,
340
- children: /* @__PURE__ */ m("div", {
346
+ children: /* @__PURE__ */ p("div", {
341
347
  className: "w-full px-3 pt-3",
342
- children: /* @__PURE__ */ m("div", {
348
+ children: /* @__PURE__ */ p("div", {
343
349
  className: "[--search-max-height:70vh] overflow-y-auto pb-7 md:[--search-max-height:60vh]",
344
350
  style: { maxHeight: `min(var(--search-max-height), calc(100dvh - ${R}px - 1.875rem))` },
345
- children: /* @__PURE__ */ m("div", { children: $ })
351
+ children: /* @__PURE__ */ p("div", { children: $ })
346
352
  })
347
353
  })
348
354
  })]
349
- }), document.body) : /* @__PURE__ */ m("div", {
355
+ }), document.body) : /* @__PURE__ */ p("div", {
350
356
  ref: P,
351
357
  className: "absolute top-full z-20 mt-1 grid max-h-96 w-full overflow-auto rounded-md border border-border bg-popover py-1 text-popover-foreground shadow-md",
352
358
  "data-ckui": "search-panel",
@@ -1 +1 @@
1
- {"version":3,"file":"search.js","names":[],"sources":["../../../src/components/content/search.tsx"],"sourcesContent":["import { Cancel01Icon, Clock01Icon, File01Icon, Folder01Icon, Image01Icon, Search01Icon, TagsIcon, UserIcon } from \"@hugeicons/core-free-icons\";\nimport { HugeiconsIcon, type IconSvgElement } from \"@hugeicons/react\";\nimport { cn } from \"cn\";\nimport { useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, type RefObject, type KeyboardEvent } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport type { ContentKitUiAppearance } from \"../../appearance.js\";\nimport type { ContentKitClient } from \"../../client/client.js\";\nimport type { Card, GroupCard } from \"../../client/generated/wire.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { ContentKitContext } from \"../../react/context.js\";\nimport { useRecentSearches, useTypeahead } from \"../../react/discovery.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Input } from \"#ckui/ui/input\";\nimport { RenditionImg } from \"../rendition-img.js\";\nimport { labelOf, type Labels } from \"../groups/parts.js\";\n\nexport interface SearchBoxProps {\n /** Submits the text: the host shows its search page. */\n onSearch: (q: string) => void;\n /** Suggest contents of this kind only. */\n kind?: string;\n /** The group kinds suggested; every kind with a page by default. */\n groupKinds?: readonly string[];\n defaultValue?: string;\n placeholder?: string;\n /** A suggestion's link; default its canonical path. */\n href?: (item: Card | GroupCard) => string | undefined;\n labels?: Labels;\n /** The reader's recent searches while the box is empty. Default true. */\n recent?: boolean;\n /** A portal dropdown anchored to the header field; default stays inline. */\n presentation?: \"inline\" | \"header\";\n client?: ContentKitClient;\n className?: string;\n appearance?: ContentKitUiAppearance;\n}\n\ntype Suggestion = { type: \"content\"; card: Card } | { type: \"group\"; group: GroupCard } | { type: \"recent\"; query: string };\n\nconst TYPE_ICONS: Record<string, { icon: IconSvgElement; color: string }> = {\n artist: { icon: UserIcon, color: \"text-blue-500 dark:text-blue-400\" },\n series: { icon: Folder01Icon, color: \"text-yellow-600 dark:text-yellow-400\" },\n gallery: { icon: Image01Icon, color: \"text-green-600 dark:text-green-400\" },\n post: { icon: File01Icon, color: \"text-purple-500 dark:text-purple-400\" },\n blog: { icon: File01Icon, color: \"text-purple-500 dark:text-purple-400\" },\n poll: { icon: File01Icon, color: \"text-purple-500 dark:text-purple-400\" },\n character: { icon: UserIcon, color: \"text-purple-500 dark:text-purple-400\" },\n tag: { icon: TagsIcon, color: \"text-orange-500 dark:text-orange-400\" },\n};\n\nfunction useHeaderAnchor(open: boolean, enabled: boolean, root: RefObject<HTMLDivElement | null>, input: RefObject<HTMLInputElement | null>) {\n const [position, setPosition] = useState({ top: 0, left: 0, width: 0 });\n useLayoutEffect(() => {\n if (!open || !enabled || !root.current) return;\n const anchor = input.current ?? root.current;\n const view = root.current.ownerDocument.defaultView;\n if (!view) return;\n const measure = () => {\n const rect = anchor.getBoundingClientRect();\n setPosition({ top: Math.max(0, Math.min(view.innerHeight, rect.bottom + 4)), left: rect.left, width: rect.width });\n };\n measure();\n const observer = typeof ResizeObserver === \"undefined\" ? undefined : new ResizeObserver(measure);\n observer?.observe(anchor);\n view.addEventListener(\"resize\", measure);\n view.addEventListener(\"scroll\", measure, true);\n view.visualViewport?.addEventListener(\"resize\", measure);\n view.visualViewport?.addEventListener(\"scroll\", measure);\n return () => {\n observer?.disconnect();\n view.removeEventListener(\"resize\", measure);\n view.removeEventListener(\"scroll\", measure, true);\n view.visualViewport?.removeEventListener(\"resize\", measure);\n view.visualViewport?.removeEventListener(\"scroll\", measure);\n };\n }, [open, enabled, root, input]);\n return position;\n}\n\nfunction SearchTypeIcon({ kind }: { kind: string }) {\n const type = TYPE_ICONS[kind];\n return <HugeiconsIcon icon={type?.icon ?? Search01Icon} strokeWidth={2} className={cn(\"size-4 shrink-0\", type?.color ?? \"text-muted-foreground\")} data-search-kind={kind} aria-hidden />;\n}\n\n/**\n * A search field suggesting contents and groups as the reader types, and\n * recent searches while it is empty; Enter searches, or opens the suggestion chosen.\n */\nexport function SearchBox(p: SearchBoxProps) {\n const { t, error } = useMessages();\n const id = useId();\n const navigate = useContext(ContentKitContext)?.navigate;\n const [text, setText] = useState(p.defaultValue ?? \"\");\n const [open, setOpen] = useState(false);\n const [active, setActive] = useState(-1);\n const root = useRef<HTMLDivElement>(null);\n const panel = useRef<HTMLDivElement>(null);\n const input = useRef<HTMLInputElement>(null);\n const header = p.presentation === \"header\";\n const anchor = useHeaderAnchor(open, header, root, input);\n const { top } = anchor;\n const empty = !text.trim();\n const found = useTypeahead(text, { kind: p.kind, entity_kinds: p.groupKinds, client: p.client });\n const recent = useRecentSearches({ enabled: p.recent !== false && open && empty, client: p.client });\n const items = useMemo<Suggestion[]>(\n () =>\n empty\n ? recent.searches.map((r) => ({ type: \"recent\" as const, query: r.query }))\n : [...found.contents.map((card) => ({ type: \"content\" as const, card })), ...found.entities.map((group) => ({ type: \"group\" as const, group }))],\n [empty, recent.searches, found.contents, found.entities],\n );\n const current = empty || found.query === text.trim();\n const visible = current ? items : [];\n const selected = visible[active];\n const loading = empty ? recent.loading : !current || found.loading;\n const showRecent = empty && p.recent !== false;\n const emptyMessage = empty ? !header && showRecent && !recent.error ? \"contents.noRecentSearches\" : \"contents.searchHint\" : \"contents.noResults\";\n useEffect(() => {\n if (!open) return;\n const outside = (event: PointerEvent) => {\n if (!root.current?.contains(event.target as Node) && !panel.current?.contains(event.target as Node)) setOpen(false);\n };\n document.addEventListener(\"pointerdown\", outside);\n return () => document.removeEventListener(\"pointerdown\", outside);\n }, [open]);\n const reveal = () => {\n setOpen(true);\n };\n const search = (q: string) => {\n setOpen(false);\n if (q) p.onSearch(q);\n };\n const go = (s: Suggestion) => {\n if (s.type === \"recent\") {\n setText(s.query);\n return search(s.query);\n }\n const url = p.href ? p.href(s.type === \"content\" ? s.card : s.group) : s.type === \"content\" ? s.card.path : s.group.path;\n setOpen(false);\n if (!url) return;\n if (navigate) navigate(url);\n else location.assign(url);\n };\n const panelKeyDown = (event: KeyboardEvent) => {\n if (event.key !== \"Escape\") return;\n event.preventDefault();\n input.current?.focus();\n setOpen(false);\n setActive(-1);\n };\n const results = (<>\n {showRecent && (\n <div className={cn(\"flex items-center justify-between gap-2 text-muted-foreground\", header ? \"mb-4 text-base font-semibold\" : \"px-2 py-1 text-xs\")}>\n <span id={`${id}-recent`} className=\"flex items-center gap-2\">{header && <HugeiconsIcon icon={Clock01Icon} strokeWidth={2} className=\"size-5\" aria-hidden />}{t(\"contents.recentSearches\")}</span>\n {visible.length > 0 && <button\n type=\"button\"\n className=\"rounded px-1 hover:text-foreground\"\n onMouseDown={(e) => {\n e.preventDefault();\n }}\n onClick={() => void recent.clear()}\n >\n {t(header ? \"contents.clearAllRecent\" : \"contents.clearRecent\")}\n </button>}\n </div>\n )}\n <ul id={`${id}-list`} role=\"listbox\" aria-label={empty ? t(\"contents.recentSearches\") : t(\"contents.suggestions\")} className={cn(\"grid\", header && \"gap-2\")}>\n {visible.map((s, i) => (\n <li\n key={s.type === \"content\" ? `c:${s.card.id}` : s.type === \"group\" ? `g:${s.group.id}` : `r:${s.query}`}\n id={`${id}-${i}`}\n role=\"option\"\n aria-selected={i === active}\n data-ckui=\"suggestion\"\n data-type={s.type}\n className={cn(\"flex cursor-pointer items-center\", header ? s.type === \"recent\" ? \"gap-2 rounded-md p-3 text-base hover:bg-foreground/10\" : \"gap-3 rounded-md px-4 py-1 text-base font-medium hover:bg-foreground/10\" : \"gap-2 px-2 py-1.5\", i === active && \"bg-accent text-accent-foreground\")}\n onMouseEnter={() => setActive(i)}\n onMouseDown={(e) => {\n e.preventDefault();\n go(s);\n }}\n >\n {header && s.type !== \"recent\" ? (\n <>\n <SearchTypeIcon kind={s.type === \"content\" ? s.card.kind : s.group.kind} />\n <span className=\"sr-only\">{labelOf(p.labels, s.type === \"content\" ? s.card.kind : s.group.kind)}</span>\n <span className=\"min-w-0 flex-1 truncate\">{s.type === \"content\" ? s.card.title || s.card.code : s.group.name || s.group.slug}</span>\n </>\n ) : s.type === \"content\" ? (\n <>\n <span className=\"h-10 w-8 shrink-0 overflow-hidden rounded bg-muted\">\n <RenditionImg outputs={s.card.cover} alt=\"\" fit=\"cover\" className=\"size-full\" />\n </span>\n <span className=\"min-w-0 truncate\">{s.card.title || s.card.code}</span>\n </>\n ) : s.type === \"group\" ? (\n <>\n <span className=\"min-w-0 flex-1 truncate\">{s.group.name || s.group.slug}</span>\n <span className=\"text-xs text-muted-foreground\">{labelOf(p.labels, s.group.kind)}</span>\n </>\n ) : (\n <>\n <HugeiconsIcon icon={header ? Search01Icon : Clock01Icon} strokeWidth={2} className=\"size-4 shrink-0 text-muted-foreground\" aria-hidden />\n <span className=\"min-w-0 flex-1 truncate\">{s.query}</span>\n <button\n type=\"button\"\n className=\"rounded p-0.5 text-muted-foreground hover:text-foreground\"\n aria-label={t(\"contents.removeRecent\", { q: s.query })}\n onMouseDown={(e) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n onClick={() => void recent.clear(s.query)}\n >\n <HugeiconsIcon icon={Cancel01Icon} strokeWidth={2} className=\"size-3.5\" aria-hidden />\n </button>\n </>\n )}\n </li>\n ))}\n </ul>\n {loading ? <div role=\"status\" className={cn(\"text-muted-foreground\", header ? \"flex justify-center py-4\" : \"px-3 py-2\")}>{header ? <><span className=\"size-6 animate-spin rounded-full border-2 border-muted border-t-foreground motion-reduce:animate-none\" aria-hidden /><span className=\"sr-only\">{t(\"contents.loading\")}</span></> : t(\"contents.loading\")}</div>\n : !empty && found.error ? <p role=\"alert\" className={cn(\"px-3 py-2 text-destructive\", header && \"text-center\")}>{error(found.error)}</p>\n : visible.length === 0 && <div role=\"status\" className={cn(\"text-muted-foreground\", header ? \"flex flex-col items-center gap-2 py-8 text-center\" : \"px-3 py-2\")}>{header && <HugeiconsIcon icon={Search01Icon} strokeWidth={2} className=\"size-8\" aria-hidden />}<p>{t(emptyMessage, { q: text.trim() })}</p></div>}\n </>);\n return (\n <ContentKitUiRoot ref={root} appearance={p.appearance} className={cn(\"relative text-sm\", p.className)} data-ckui=\"search-box\" onBlur={(event) => { if (!event.currentTarget.contains(event.relatedTarget) && !panel.current?.contains(event.relatedTarget)) setOpen(false); }}>\n <form\n role=\"search\"\n className=\"relative\"\n onSubmit={(e) => {\n e.preventDefault();\n if (open && selected) return go(selected);\n search(text.trim());\n }}\n >\n {header ? <button type=\"submit\" className=\"absolute top-1/2 left-2.5 -translate-y-1/2 rounded text-muted-foreground hover:text-foreground focus-visible:outline-2 focus-visible:outline-ring\" aria-label={t(\"contents.search\")}><HugeiconsIcon icon={Search01Icon} strokeWidth={2} className=\"size-4\" aria-hidden /></button>\n : <HugeiconsIcon icon={Search01Icon} strokeWidth={2} className=\"pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground\" aria-hidden />}\n <Input\n ref={input}\n type={header ? \"text\" : \"search\"}\n role=\"combobox\"\n aria-label={t(\"contents.search\")}\n aria-expanded={open}\n aria-controls={`${id}-list`}\n aria-activedescendant={open && selected ? `${id}-${active}` : undefined}\n aria-autocomplete=\"list\"\n autoComplete=\"off\"\n className={cn(\"h-9 ps-8\", header && \"rounded-full border-border/50 bg-foreground/10 pe-9 text-base shadow-none md:text-base\")}\n value={text}\n placeholder={p.placeholder ?? t(\"contents.searchPlaceholder\")}\n onChange={(e) => {\n setText(e.target.value);\n setOpen(true);\n setActive(-1);\n }}\n onFocus={reveal}\n onClick={reveal}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n setOpen(false);\n setActive(-1);\n return;\n }\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n reveal();\n setActive((a) => open ? Math.min(visible.length - 1, a + 1) : 0);\n } else if (e.key === \"ArrowUp\" && open) {\n e.preventDefault();\n setActive((a) => Math.max(-1, a - 1));\n }\n }}\n />\n {header && (text || open) && (\n <button\n type=\"button\"\n className=\"absolute top-1/2 right-2.5 -translate-y-1/2 rounded p-0.5 text-muted-foreground hover:text-foreground focus-visible:outline-2 focus-visible:outline-ring\"\n aria-label={text ? t(\"contents.clearSearch\") : t(\"common.close\")}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => {\n input.current?.focus();\n setActive(-1);\n if (text) { setText(\"\"); setOpen(true); }\n else setOpen(false);\n }}\n ><HugeiconsIcon icon={Cancel01Icon} strokeWidth={2} className=\"size-4\" aria-hidden /></button>\n )}\n </form>\n {open && (header ? createPortal(\n <ContentKitUiRoot appearance={p.appearance} className=\"fixed inset-x-0 bottom-0 z-[70] text-sm\" style={{ top }} data-ckui=\"search-layer\">\n <div className=\"absolute inset-0 bg-black/30 backdrop-blur-sm\" data-ckui=\"search-backdrop\" aria-hidden />\n <div ref={panel} style={{ width: anchor.width, marginLeft: anchor.left }} className=\"relative origin-top animate-[search-expand_300ms_ease-out] rounded-lg border border-border bg-background text-foreground shadow-lg transition-none motion-reduce:animate-none\" data-ckui=\"search-panel\" onKeyDown={panelKeyDown}>\n <div className=\"w-full px-3 pt-3\">\n <div className=\"[--search-max-height:70vh] overflow-y-auto pb-7 md:[--search-max-height:60vh]\" style={{ maxHeight: `min(var(--search-max-height), calc(100dvh - ${top}px - 1.875rem))` }}>\n <div>{results}</div>\n </div>\n </div>\n </div>\n </ContentKitUiRoot>, document.body,\n ) : <div ref={panel} className=\"absolute top-full z-20 mt-1 grid max-h-96 w-full overflow-auto rounded-md border border-border bg-popover py-1 text-popover-foreground shadow-md\" data-ckui=\"search-panel\" onKeyDown={panelKeyDown}>{results}</div>)}\n\n </ContentKitUiRoot>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"search.js","names":[],"sources":["../../../src/components/content/search.tsx"],"sourcesContent":["import { Cancel01Icon, Clock01Icon, File01Icon, Folder01Icon, Image01Icon, Search01Icon, TagsIcon, UserIcon } from \"@hugeicons/core-free-icons\";\nimport { HugeiconsIcon, type IconSvgElement } from \"@hugeicons/react\";\nimport { cn } from \"cn\";\nimport { useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, type RefObject, type KeyboardEvent } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport type { ContentKitUiAppearance } from \"../../appearance.js\";\nimport type { ContentKitClient } from \"../../client/client.js\";\nimport type { Card, GroupCard } from \"../../client/generated/wire.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { ContentKitContext } from \"../../react/context.js\";\nimport { useRecentSearches, useTypeahead } from \"../../react/discovery.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Input } from \"#ckui/ui/input\";\nimport { RenditionImg } from \"../rendition-img.js\";\nimport { labelOf, type Labels } from \"../groups/parts.js\";\n\nexport interface SearchBoxProps {\n /** Submits the text: the host shows its search page. */\n onSearch: (q: string) => void;\n /** Suggest contents of this kind only. */\n kind?: string;\n /** The group kinds suggested; every kind with a page by default. */\n groupKinds?: readonly string[];\n defaultValue?: string;\n placeholder?: string;\n /** A suggestion's link; default its canonical path. */\n href?: (item: Card | GroupCard) => string | undefined;\n labels?: Labels;\n /** Recent searches first, prefix-filtered while typing. Default true. */\n recent?: boolean;\n /** A portal dropdown anchored to the header field; default stays inline. */\n presentation?: \"inline\" | \"header\";\n client?: ContentKitClient;\n className?: string;\n appearance?: ContentKitUiAppearance;\n}\n\ntype Suggestion = { type: \"content\"; card: Card } | { type: \"group\"; group: GroupCard } | { type: \"recent\"; query: string };\nconst suggestionKey = (s: Suggestion) => s.type === \"content\" ? `c:${s.card.id}` : s.type === \"group\" ? `g:${s.group.id}` : `r:${s.query}`;\n\n// Match the keyword index's case, Latin accent and whitespace normalization.\nconst prefixText = (text: string) => text.normalize(\"NFKD\").replace(/[\\u0300-\\u036f]/g, \"\").normalize(\"NFC\").toLowerCase().trim().replace(/\\s+/g, \" \");\n\nconst TYPE_ICONS: Record<string, { icon: IconSvgElement; color: string }> = {\n artist: { icon: UserIcon, color: \"text-blue-500 dark:text-blue-400\" },\n series: { icon: Folder01Icon, color: \"text-yellow-600 dark:text-yellow-400\" },\n gallery: { icon: Image01Icon, color: \"text-green-600 dark:text-green-400\" },\n post: { icon: File01Icon, color: \"text-purple-500 dark:text-purple-400\" },\n blog: { icon: File01Icon, color: \"text-purple-500 dark:text-purple-400\" },\n poll: { icon: File01Icon, color: \"text-purple-500 dark:text-purple-400\" },\n character: { icon: UserIcon, color: \"text-purple-500 dark:text-purple-400\" },\n tag: { icon: TagsIcon, color: \"text-orange-500 dark:text-orange-400\" },\n};\n\nfunction useHeaderAnchor(open: boolean, enabled: boolean, root: RefObject<HTMLDivElement | null>, input: RefObject<HTMLInputElement | null>) {\n const [position, setPosition] = useState({ top: 0, left: 0, width: 0 });\n useLayoutEffect(() => {\n if (!open || !enabled || !root.current) return;\n const anchor = input.current ?? root.current;\n const view = root.current.ownerDocument.defaultView;\n if (!view) return;\n const measure = () => {\n const rect = anchor.getBoundingClientRect();\n setPosition({ top: Math.max(0, Math.min(view.innerHeight, rect.bottom + 4)), left: rect.left, width: rect.width });\n };\n measure();\n const observer = typeof ResizeObserver === \"undefined\" ? undefined : new ResizeObserver(measure);\n observer?.observe(anchor);\n view.addEventListener(\"resize\", measure);\n view.addEventListener(\"scroll\", measure, true);\n view.visualViewport?.addEventListener(\"resize\", measure);\n view.visualViewport?.addEventListener(\"scroll\", measure);\n return () => {\n observer?.disconnect();\n view.removeEventListener(\"resize\", measure);\n view.removeEventListener(\"scroll\", measure, true);\n view.visualViewport?.removeEventListener(\"resize\", measure);\n view.visualViewport?.removeEventListener(\"scroll\", measure);\n };\n }, [open, enabled, root, input]);\n return position;\n}\n\nfunction SearchTypeIcon({ kind }: { kind: string }) {\n const type = TYPE_ICONS[kind];\n return <HugeiconsIcon icon={type?.icon ?? Search01Icon} strokeWidth={2} className={cn(\"size-4 shrink-0\", type?.color ?? \"text-muted-foreground\")} data-search-kind={kind} aria-hidden />;\n}\n\n/**\n * Recent query prefixes first, followed by entity and title prefixes. Enter\n * searches, or opens the chosen suggestion; full search can match more deeply.\n */\nexport function SearchBox(p: SearchBoxProps) {\n const { t, error } = useMessages();\n const id = useId();\n const navigate = useContext(ContentKitContext)?.navigate;\n const [text, setText] = useState(p.defaultValue ?? \"\");\n const [open, setOpen] = useState(false);\n // null requests the first result when opening an as-yet-unloaded panel.\n const [active, setActive] = useState<string | null>();\n const root = useRef<HTMLDivElement>(null);\n const panel = useRef<HTMLDivElement>(null);\n const input = useRef<HTMLInputElement>(null);\n const header = p.presentation === \"header\";\n const anchor = useHeaderAnchor(open, header, root, input);\n const { top } = anchor;\n const empty = !text.trim();\n const found = useTypeahead(text, { kind: p.kind, entity_kinds: p.groupKinds, client: p.client });\n const recent = useRecentSearches({ enabled: p.recent !== false && open, client: p.client });\n const prefix = prefixText(text);\n const current = found.query === text.trim();\n const visible = useMemo<Suggestion[]>(\n () => [\n ...(p.recent === false ? [] : recent.searches.filter((r) => prefixText(r.query).startsWith(prefix)).map((r) => ({ type: \"recent\" as const, query: r.query }))),\n ...(!empty && current ? [\n ...found.entities.map((group) => ({ type: \"group\" as const, group })),\n ...found.contents.map((card) => ({ type: \"content\" as const, card })),\n ] : []),\n ],\n [p.recent, prefix, empty, current, recent.searches, found.contents, found.entities],\n );\n // History and live suggestions can arrive independently. Track identity so\n // prepending history never changes what Enter will open.\n const activeIndex = active === null ? Math.min(0, visible.length - 1) : visible.findIndex((s) => suggestionKey(s) === active);\n const selected = visible[activeIndex];\n const activate = (index: number) => {\n const suggestion = visible[index];\n setActive(suggestion ? suggestionKey(suggestion) : index >= 0 ? null : undefined);\n };\n const loading = recent.loading || (!empty && (!current || found.loading));\n const showRecent = empty && p.recent !== false;\n const emptyMessage = empty ? !header && showRecent && !recent.error ? \"contents.noRecentSearches\" : \"contents.searchHint\" : \"contents.noResults\";\n useEffect(() => {\n if (!open) return;\n const outside = (event: PointerEvent) => {\n if (!root.current?.contains(event.target as Node) && !panel.current?.contains(event.target as Node)) setOpen(false);\n };\n document.addEventListener(\"pointerdown\", outside);\n return () => document.removeEventListener(\"pointerdown\", outside);\n }, [open]);\n const reveal = () => {\n setOpen(true);\n };\n const search = (q: string) => {\n setOpen(false);\n if (q) p.onSearch(q);\n };\n const go = (s: Suggestion) => {\n if (s.type === \"recent\") {\n setText(s.query);\n return search(s.query);\n }\n const url = p.href ? p.href(s.type === \"content\" ? s.card : s.group) : s.type === \"content\" ? s.card.path : s.group.path;\n setOpen(false);\n if (!url) return;\n if (navigate) navigate(url);\n else location.assign(url);\n };\n const panelKeyDown = (event: KeyboardEvent) => {\n if (event.key !== \"Escape\") return;\n event.preventDefault();\n input.current?.focus();\n setOpen(false);\n setActive(undefined);\n };\n const results = (<>\n {showRecent && (\n <div className={cn(\"flex items-center justify-between gap-2 text-muted-foreground\", header ? \"mb-4 text-base font-semibold\" : \"px-2 py-1 text-xs\")}>\n <span id={`${id}-recent`} className=\"flex items-center gap-2\">{header && <HugeiconsIcon icon={Clock01Icon} strokeWidth={2} className=\"size-5\" aria-hidden />}{t(\"contents.recentSearches\")}</span>\n {visible.length > 0 && <button\n type=\"button\"\n className=\"rounded px-1 hover:text-foreground\"\n onMouseDown={(e) => {\n e.preventDefault();\n }}\n onClick={() => void recent.clear()}\n >\n {t(header ? \"contents.clearAllRecent\" : \"contents.clearRecent\")}\n </button>}\n </div>\n )}\n <ul id={`${id}-list`} role=\"listbox\" aria-label={empty ? t(\"contents.recentSearches\") : t(\"contents.suggestions\")} className={cn(\"grid\", header && \"gap-2\")}>\n {visible.map((s, i) => (\n <li\n key={suggestionKey(s)}\n id={`${id}-${i}`}\n role=\"option\"\n aria-selected={i === activeIndex}\n data-ckui=\"suggestion\"\n data-type={s.type}\n className={cn(\"flex cursor-pointer items-center\", header ? s.type === \"recent\" ? \"gap-2 rounded-md p-3 text-base hover:bg-foreground/10\" : \"gap-3 rounded-md px-4 py-1 text-base font-medium hover:bg-foreground/10\" : \"gap-2 px-2 py-1.5\", i === activeIndex && \"bg-accent text-accent-foreground\")}\n onMouseEnter={() => setActive(suggestionKey(s))}\n onMouseDown={(e) => {\n e.preventDefault();\n go(s);\n }}\n >\n {header && s.type !== \"recent\" ? (\n <>\n <SearchTypeIcon kind={s.type === \"content\" ? s.card.kind : s.group.kind} />\n <span className=\"sr-only\">{labelOf(p.labels, s.type === \"content\" ? s.card.kind : s.group.kind)}</span>\n <span className=\"min-w-0 flex-1 truncate\">{s.type === \"content\" ? s.card.title || s.card.code : s.group.name || s.group.slug}</span>\n </>\n ) : s.type === \"content\" ? (\n <>\n <span className=\"h-10 w-8 shrink-0 overflow-hidden rounded bg-muted\">\n <RenditionImg outputs={s.card.cover} alt=\"\" fit=\"cover\" className=\"size-full\" />\n </span>\n <span className=\"min-w-0 truncate\">{s.card.title || s.card.code}</span>\n </>\n ) : s.type === \"group\" ? (\n <>\n <span className=\"min-w-0 flex-1 truncate\">{s.group.name || s.group.slug}</span>\n <span className=\"text-xs text-muted-foreground\">{labelOf(p.labels, s.group.kind)}</span>\n </>\n ) : (\n <>\n <HugeiconsIcon icon={header ? Search01Icon : Clock01Icon} strokeWidth={2} className=\"size-4 shrink-0 text-muted-foreground\" aria-hidden />\n <span className=\"min-w-0 flex-1 truncate\">{s.query}</span>\n <button\n type=\"button\"\n className=\"rounded p-0.5 text-muted-foreground hover:text-foreground\"\n aria-label={t(\"contents.removeRecent\", { q: s.query })}\n onMouseDown={(e) => {\n e.preventDefault();\n e.stopPropagation();\n }}\n onClick={() => void recent.clear(s.query)}\n >\n <HugeiconsIcon icon={Cancel01Icon} strokeWidth={2} className=\"size-3.5\" aria-hidden />\n </button>\n </>\n )}\n </li>\n ))}\n </ul>\n {loading ? <div role=\"status\" className={cn(\"text-muted-foreground\", header ? \"flex justify-center py-4\" : \"px-3 py-2\")}>{header ? <><span className=\"size-6 animate-spin rounded-full border-2 border-muted border-t-foreground motion-reduce:animate-none\" aria-hidden /><span className=\"sr-only\">{t(\"contents.loading\")}</span></> : t(\"contents.loading\")}</div>\n : !empty && found.error ? <p role=\"alert\" className={cn(\"px-3 py-2 text-destructive\", header && \"text-center\")}>{error(found.error)}</p>\n : visible.length === 0 && <div role=\"status\" className={cn(\"text-muted-foreground\", header ? \"flex flex-col items-center gap-2 py-8 text-center\" : \"px-3 py-2\")}>{header && <HugeiconsIcon icon={Search01Icon} strokeWidth={2} className=\"size-8\" aria-hidden />}<p>{t(emptyMessage, { q: text.trim() })}</p></div>}\n </>);\n return (\n <ContentKitUiRoot ref={root} appearance={p.appearance} className={cn(\"relative text-sm\", p.className)} data-ckui=\"search-box\" onBlur={(event) => { if (!event.currentTarget.contains(event.relatedTarget) && !panel.current?.contains(event.relatedTarget)) setOpen(false); }}>\n <form\n role=\"search\"\n className=\"relative\"\n onSubmit={(e) => {\n e.preventDefault();\n if (open && selected) return go(selected);\n search(text.trim());\n }}\n >\n {header ? <button type=\"submit\" className=\"absolute top-1/2 left-2.5 -translate-y-1/2 rounded text-muted-foreground hover:text-foreground focus-visible:outline-2 focus-visible:outline-ring\" aria-label={t(\"contents.search\")}><HugeiconsIcon icon={Search01Icon} strokeWidth={2} className=\"size-4\" aria-hidden /></button>\n : <HugeiconsIcon icon={Search01Icon} strokeWidth={2} className=\"pointer-events-none absolute top-1/2 left-2.5 size-4 -translate-y-1/2 text-muted-foreground\" aria-hidden />}\n <Input\n ref={input}\n type={header ? \"text\" : \"search\"}\n role=\"combobox\"\n aria-label={t(\"contents.search\")}\n aria-expanded={open}\n aria-controls={`${id}-list`}\n aria-activedescendant={open && selected ? `${id}-${activeIndex}` : undefined}\n aria-autocomplete=\"list\"\n autoComplete=\"off\"\n className={cn(\"h-9 ps-8\", header && \"rounded-full border-border/50 bg-foreground/10 pe-9 text-base shadow-none md:text-base\")}\n value={text}\n placeholder={p.placeholder ?? t(\"contents.searchPlaceholder\")}\n onChange={(e) => {\n setText(e.target.value);\n setOpen(true);\n setActive(undefined);\n }}\n onFocus={reveal}\n onClick={reveal}\n onKeyDown={(e) => {\n if (e.key === \"Escape\") {\n e.preventDefault();\n setOpen(false);\n setActive(undefined);\n return;\n }\n if (e.key === \"ArrowDown\") {\n e.preventDefault();\n reveal();\n activate(open ? Math.min(visible.length - 1, activeIndex + 1) : 0);\n } else if (e.key === \"ArrowUp\" && open) {\n e.preventDefault();\n activate(Math.max(-1, activeIndex - 1));\n }\n }}\n />\n {header && (text || open) && (\n <button\n type=\"button\"\n className=\"absolute top-1/2 right-2.5 -translate-y-1/2 rounded p-0.5 text-muted-foreground hover:text-foreground focus-visible:outline-2 focus-visible:outline-ring\"\n aria-label={text ? t(\"contents.clearSearch\") : t(\"common.close\")}\n onMouseDown={(event) => event.preventDefault()}\n onClick={() => {\n input.current?.focus();\n setActive(undefined);\n if (text) { setText(\"\"); setOpen(true); }\n else setOpen(false);\n }}\n ><HugeiconsIcon icon={Cancel01Icon} strokeWidth={2} className=\"size-4\" aria-hidden /></button>\n )}\n </form>\n {open && (header ? createPortal(\n <ContentKitUiRoot appearance={p.appearance} className=\"fixed inset-x-0 bottom-0 z-[70] text-sm\" style={{ top }} data-ckui=\"search-layer\">\n <div className=\"absolute inset-0 bg-black/30 backdrop-blur-sm\" data-ckui=\"search-backdrop\" aria-hidden />\n <div ref={panel} style={{ width: anchor.width, marginLeft: anchor.left }} className=\"relative origin-top animate-[search-expand_300ms_ease-out] rounded-lg border border-border bg-background text-foreground shadow-lg transition-none motion-reduce:animate-none\" data-ckui=\"search-panel\" onKeyDown={panelKeyDown}>\n <div className=\"w-full px-3 pt-3\">\n <div className=\"[--search-max-height:70vh] overflow-y-auto pb-7 md:[--search-max-height:60vh]\" style={{ maxHeight: `min(var(--search-max-height), calc(100dvh - ${top}px - 1.875rem))` }}>\n <div>{results}</div>\n </div>\n </div>\n </div>\n </ContentKitUiRoot>, document.body,\n ) : <div ref={panel} className=\"absolute top-full z-20 mt-1 grid max-h-96 w-full overflow-auto rounded-md border border-border bg-popover py-1 text-popover-foreground shadow-md\" data-ckui=\"search-panel\" onKeyDown={panelKeyDown}>{results}</div>)}\n\n </ContentKitUiRoot>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAsCA,IAAM,KAAiB,MAAkB,EAAE,SAAS,YAAY,KAAK,EAAE,KAAK,OAAO,EAAE,SAAS,UAAU,KAAK,EAAE,MAAM,OAAO,KAAK,EAAE,SAG7H,KAAc,MAAiB,EAAK,UAAU,MAAM,CAAC,CAAC,QAAQ,oBAAoB,EAAE,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,CAAC,QAAQ,QAAQ,GAAG,GAE/I,IAAsE;CAC1E,QAAQ;EAAE,MAAM;EAAU,OAAO;CAAmC;CACpE,QAAQ;EAAE,MAAM;EAAc,OAAO;CAAuC;CAC5E,SAAS;EAAE,MAAM;EAAa,OAAO;CAAqC;CAC1E,MAAM;EAAE,MAAM;EAAY,OAAO;CAAuC;CACxE,MAAM;EAAE,MAAM;EAAY,OAAO;CAAuC;CACxE,MAAM;EAAE,MAAM;EAAY,OAAO;CAAuC;CACxE,WAAW;EAAE,MAAM;EAAU,OAAO;CAAuC;CAC3E,KAAK;EAAE,MAAM;EAAU,OAAO;CAAuC;AACvE;AAEA,SAAS,EAAgB,GAAe,GAAkB,GAAwC,GAA2C;CAC3I,IAAM,CAAC,GAAU,KAAe,EAAS;EAAE,KAAK;EAAG,MAAM;EAAG,OAAO;CAAE,CAAC;CAyBtE,OAxBA,QAAsB;EACpB,IAAI,CAAC,KAAQ,CAAC,KAAW,CAAC,EAAK,SAAS;EACxC,IAAM,IAAS,EAAM,WAAW,EAAK,SAC/B,IAAO,EAAK,QAAQ,cAAc;EACxC,IAAI,CAAC,GAAM;EACX,IAAM,UAAgB;GACpB,IAAM,IAAO,EAAO,sBAAsB;GAC1C,EAAY;IAAE,KAAK,KAAK,IAAI,GAAG,KAAK,IAAI,EAAK,aAAa,EAAK,SAAS,CAAC,CAAC;IAAG,MAAM,EAAK;IAAM,OAAO,EAAK;GAAM,CAAC;EACnH;EACA,EAAQ;EACR,IAAM,IAAW,OAAO,iBAAmB,MAAc,KAAA,IAAY,IAAI,eAAe,CAAO;EAM/F,OALA,GAAU,QAAQ,CAAM,GACxB,EAAK,iBAAiB,UAAU,CAAO,GACvC,EAAK,iBAAiB,UAAU,GAAS,EAAI,GAC7C,EAAK,gBAAgB,iBAAiB,UAAU,CAAO,GACvD,EAAK,gBAAgB,iBAAiB,UAAU,CAAO,SAC1C;GAKX,AAJA,GAAU,WAAW,GACrB,EAAK,oBAAoB,UAAU,CAAO,GAC1C,EAAK,oBAAoB,UAAU,GAAS,EAAI,GAChD,EAAK,gBAAgB,oBAAoB,UAAU,CAAO,GAC1D,EAAK,gBAAgB,oBAAoB,UAAU,CAAO;EAC5D;CACF,GAAG;EAAC;EAAM;EAAS;EAAM;CAAK,CAAC,GACxB;AACT;AAEA,SAAS,GAAe,EAAE,WAA0B;CAClD,IAAM,IAAO,EAAW;CACxB,OAAO,kBAAC,GAAD;EAAe,MAAM,GAAM,QAAQ;EAAc,aAAa;EAAG,WAAW,EAAG,mBAAmB,GAAM,SAAS,uBAAuB;EAAG,oBAAkB;EAAM,eAAA;CAAa,CAAA;AACzL;AAMA,SAAgB,EAAU,GAAmB;CAC3C,IAAM,EAAE,MAAG,aAAU,EAAY,GAC3B,IAAK,GAAM,GACX,IAAW,EAAW,CAAiB,CAAC,EAAE,UAC1C,CAAC,GAAM,KAAW,EAAS,EAAE,gBAAgB,EAAE,GAC/C,CAAC,GAAM,KAAW,EAAS,EAAK,GAEhC,CAAC,GAAQ,KAAa,EAAwB,GAC9C,IAAO,EAAuB,IAAI,GAClC,IAAQ,EAAuB,IAAI,GACnC,IAAQ,EAAyB,IAAI,GACrC,IAAS,EAAE,iBAAiB,UAC5B,IAAS,EAAgB,GAAM,GAAQ,GAAM,CAAK,GAClD,EAAE,WAAQ,GACV,IAAQ,CAAC,EAAK,KAAK,GACnB,IAAQ,EAAa,GAAM;EAAE,MAAM,EAAE;EAAM,cAAc,EAAE;EAAY,QAAQ,EAAE;CAAO,CAAC,GACzF,IAAS,EAAkB;EAAE,SAAS,EAAE,WAAW,MAAS;EAAM,QAAQ,EAAE;CAAO,CAAC,GACpF,IAAS,EAAW,CAAI,GACxB,IAAU,EAAM,UAAU,EAAK,KAAK,GACpC,IAAU,SACR,CACJ,GAAI,EAAE,WAAW,KAAQ,CAAC,IAAI,EAAO,SAAS,QAAQ,MAAM,EAAW,EAAE,KAAK,CAAC,CAAC,WAAW,CAAM,CAAC,CAAC,CAAC,KAAK,OAAO;EAAE,MAAM;EAAmB,OAAO,EAAE;CAAM,EAAE,GAC5J,GAAI,CAAC,KAAS,IAAU,CACtB,GAAG,EAAM,SAAS,KAAK,OAAW;EAAE,MAAM;EAAkB;CAAM,EAAE,GACpE,GAAG,EAAM,SAAS,KAAK,OAAU;EAAE,MAAM;EAAoB;CAAK,EAAE,CACtE,IAAI,CAAC,CACP,GACA;EAAC,EAAE;EAAQ;EAAQ;EAAO;EAAS,EAAO;EAAU,EAAM;EAAU,EAAM;CAAQ,CACpF,GAGM,IAAc,MAAW,OAAO,KAAK,IAAI,GAAG,EAAQ,SAAS,CAAC,IAAI,EAAQ,WAAW,MAAM,EAAc,CAAC,MAAM,CAAM,GACtH,IAAW,EAAQ,IACnB,KAAY,MAAkB;EAClC,IAAM,IAAa,EAAQ;EAC3B,EAAU,IAAa,EAAc,CAAU,IAAI,KAAS,IAAI,OAAO,KAAA,CAAS;CAClF,GACM,KAAU,EAAO,WAAY,CAAC,MAAU,CAAC,KAAW,EAAM,UAC1D,IAAa,KAAS,EAAE,WAAW,IACnC,KAAe,IAAQ,CAAC,KAAU,KAAc,CAAC,EAAO,QAAQ,8BAA8B,wBAAwB;CAC5H,SAAgB;EACd,IAAI,CAAC,GAAM;EACX,IAAM,KAAW,MAAwB;GACvC,AAAI,CAAC,EAAK,SAAS,SAAS,EAAM,MAAc,KAAK,CAAC,EAAM,SAAS,SAAS,EAAM,MAAc,KAAG,EAAQ,EAAK;EACpH;EAEA,OADA,SAAS,iBAAiB,eAAe,CAAO,SACnC,SAAS,oBAAoB,eAAe,CAAO;CAClE,GAAG,CAAC,CAAI,CAAC;CACT,IAAM,UAAe;EACnB,EAAQ,EAAI;CACd,GACM,KAAU,MAAc;EAE5B,AADA,EAAQ,EAAK,GACT,KAAG,EAAE,SAAS,CAAC;CACrB,GACM,KAAM,MAAkB;EAC5B,IAAI,EAAE,SAAS,UAEb,OADA,EAAQ,EAAE,KAAK,GACR,EAAO,EAAE,KAAK;EAEvB,IAAM,IAAM,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,YAAY,EAAE,OAAO,EAAE,KAAK,IAAI,EAAE,SAAS,YAAY,EAAE,KAAK,OAAO,EAAE,MAAM;EACpH,EAAQ,EAAK,GACR,MACD,IAAU,EAAS,CAAG,IACrB,SAAS,OAAO,CAAG;CAC1B,GACM,KAAgB,MAAyB;EACzC,EAAM,QAAQ,aAClB,EAAM,eAAe,GACrB,EAAM,SAAS,MAAM,GACrB,EAAQ,EAAK,GACb,EAAU,KAAA,CAAS;CACrB,GACM,IAAW,kBAAA,GAAA,EAAA,UAAA;EACd,KACC,kBAAC,OAAD;GAAK,WAAW,EAAG,iEAAiE,IAAS,iCAAiC,mBAAmB;GAAjJ,UAAA,CACE,kBAAC,QAAD;IAAM,IAAI,GAAG,EAAG;IAAU,WAAU;IAApC,UAAA,CAA+D,KAAU,kBAAC,GAAD;KAAe,MAAM;KAAa,aAAa;KAAG,WAAU;KAAS,eAAA;IAAa,CAAA,GAAG,EAAE,yBAAyB,CAAQ;GAChM,CAAA,GAAA,EAAQ,SAAS,KAAK,kBAAC,UAAD;IACrB,MAAK;IACL,WAAU;IACV,cAAc,MAAM;KAClB,EAAE,eAAe;IACnB;IACA,eAAe,KAAK,EAAO,MAAM;IAEhC,UAAA,EAAE,IAAS,4BAA4B,sBAAsB;GACxD,CAAA,CACL;;EAEP,kBAAC,MAAD;GAAI,IAAI,GAAG,EAAG;GAAQ,MAAK;GAAU,cAAoB,EAAR,IAAU,4BAA+B,sBAAsB;GAAG,WAAW,EAAG,QAAQ,KAAU,OAAO;GACvJ,UAAA,EAAQ,KAAK,GAAG,MACf,kBAAC,MAAD;IAEE,IAAI,GAAG,EAAG,GAAG;IACb,MAAK;IACL,iBAAe,MAAM;IACrB,aAAU;IACV,aAAW,EAAE;IACb,WAAW,EAAG,oCAAoC,IAAS,EAAE,SAAS,WAAW,0DAA0D,4EAA4E,qBAAqB,MAAM,KAAe,kCAAkC;IACnS,oBAAoB,EAAU,EAAc,CAAC,CAAC;IAC9C,cAAc,MAAM;KAElB,AADA,EAAE,eAAe,GACjB,EAAG,CAAC;IACN;IAEC,UAAA,KAAU,EAAE,SAAS,WACpB,kBAAA,GAAA,EAAA,UAAA;KACE,kBAAC,IAAD,EAAgB,MAAM,EAAE,SAAS,YAAY,EAAE,KAAK,OAAO,EAAE,MAAM,KAAO,CAAA;KAC1E,kBAAC,QAAD;MAAM,WAAU;MAAW,UAAA,EAAQ,EAAE,QAAQ,EAAE,SAAS,YAAY,EAAE,KAAK,OAAO,EAAE,MAAM,IAAI;KAAQ,CAAA;KACtG,kBAAC,QAAD;MAAM,WAAU;MAA2B,UAAA,EAAE,SAAS,YAAY,EAAE,KAAK,SAAS,EAAE,KAAK,OAAO,EAAE,MAAM,QAAQ,EAAE,MAAM;KAAW,CAAA;IACnI,EAAA,CAAA,IACA,EAAE,SAAS,YACb,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,QAAD;KAAM,WAAU;KACd,UAAA,kBAAC,GAAD;MAAc,SAAS,EAAE,KAAK;MAAO,KAAI;MAAG,KAAI;MAAQ,WAAU;KAAa,CAAA;IAC3E,CAAA,GACN,kBAAC,QAAD;KAAM,WAAU;KAAoB,UAAA,EAAE,KAAK,SAAS,EAAE,KAAK;IAAW,CAAA,CACtE,EAAA,CAAA,IACA,EAAE,SAAS,UACb,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,QAAD;KAAM,WAAU;KAA2B,UAAA,EAAE,MAAM,QAAQ,EAAE,MAAM;IAAW,CAAA,GAC9E,kBAAC,QAAD;KAAM,WAAU;KAAiC,UAAA,EAAQ,EAAE,QAAQ,EAAE,MAAM,IAAI;IAAQ,CAAA,CACvF,EAAA,CAAA,IAEF,kBAAA,GAAA,EAAA,UAAA;KACE,kBAAC,GAAD;MAAe,MAAM,IAAS,IAAe;MAAa,aAAa;MAAG,WAAU;MAAwC,eAAA;KAAa,CAAA;KACzI,kBAAC,QAAD;MAAM,WAAU;MAA2B,UAAA,EAAE;KAAY,CAAA;KACzD,kBAAC,UAAD;MACE,MAAK;MACL,WAAU;MACV,cAAY,EAAE,yBAAyB,EAAE,GAAG,EAAE,MAAM,CAAC;MACrD,cAAc,MAAM;OAElB,AADA,EAAE,eAAe,GACjB,EAAE,gBAAgB;MACpB;MACA,eAAe,KAAK,EAAO,MAAM,EAAE,KAAK;MAExC,UAAA,kBAAC,GAAD;OAAe,MAAM;OAAc,aAAa;OAAG,WAAU;OAAW,eAAA;MAAa,CAAA;KAC/E,CAAA;IACR,EAAA,CAAA;GAEF,GAjDG,EAAc,CAAC,CAiDlB,CACL;EACC,CAAA;EACH,KAAU,kBAAC,OAAD;GAAK,MAAK;GAAS,WAAW,EAAG,yBAAyB,IAAS,6BAA6B,WAAW;GAAI,UAAA,IAAS,kBAAA,GAAA,EAAA,UAAA,CAAE,kBAAC,QAAD;IAAM,WAAU;IAAwG,eAAA;GAAa,CAAA,GAAC,kBAAC,QAAD;IAAM,WAAU;IAAW,UAAA,EAAE,kBAAkB;GAAQ,CAAA,CAAG,EAAA,CAAA,IAAI,EAAE,kBAAkB;EAAO,CAAA,IAChW,CAAC,KAAS,EAAM,QAAQ,kBAAC,KAAD;GAAG,MAAK;GAAQ,WAAW,EAAG,8BAA8B,KAAU,aAAa;GAAI,UAAA,EAAM,EAAM,KAAK;EAAK,CAAA,IACrI,EAAQ,WAAW,KAAK,kBAAC,OAAD;GAAK,MAAK;GAAS,WAAW,EAAG,yBAAyB,IAAS,sDAAsD,WAAW;GAApI,UAAA,CAAwI,KAAU,kBAAC,GAAD;IAAe,MAAM;IAAc,aAAa;IAAG,WAAU;IAAS,eAAA;GAAa,CAAA,GAAE,kBAAC,KAAD,EAAA,UAAI,EAAE,IAAc,EAAE,GAAG,EAAK,KAAK,EAAE,CAAC,EAAK,CAAA,CAAM;;CACpT,EAAA,CAAA;CACF,OACE,kBAAC,GAAD;EAAkB,KAAK;EAAM,YAAY,EAAE;EAAY,WAAW,EAAG,oBAAoB,EAAE,SAAS;EAAG,aAAU;EAAa,SAAS,MAAU;GAAE,AAAI,CAAC,EAAM,cAAc,SAAS,EAAM,aAAa,KAAK,CAAC,EAAM,SAAS,SAAS,EAAM,aAAa,KAAG,EAAQ,EAAK;EAAG;EAA5Q,UAAA,CACE,kBAAC,QAAD;GACE,MAAK;GACL,WAAU;GACV,WAAW,MAAM;IAEf,IADA,EAAE,eAAe,GACb,KAAQ,GAAU,OAAO,EAAG,CAAQ;IACxC,EAAO,EAAK,KAAK,CAAC;GACpB;GAPF,UAAA;IASG,IAAS,kBAAC,UAAD;KAAQ,MAAK;KAAS,WAAU;KAAoJ,cAAY,EAAE,iBAAiB;KAAG,UAAA,kBAAC,GAAD;MAAe,MAAM;MAAc,aAAa;MAAG,WAAU;MAAS,eAAA;KAAa,CAAA;IAAS,CAAA,IACxT,kBAAC,GAAD;KAAe,MAAM;KAAc,aAAa;KAAG,WAAU;KAA8F,eAAA;IAAa,CAAA;IAC5K,kBAAC,GAAD;KACE,KAAK;KACL,MAAM,IAAS,SAAS;KACxB,MAAK;KACL,cAAY,EAAE,iBAAiB;KAC/B,iBAAe;KACf,iBAAe,GAAG,EAAG;KACrB,yBAAuB,KAAQ,IAAW,GAAG,EAAG,GAAG,MAAgB,KAAA;KACnE,qBAAkB;KAClB,cAAa;KACb,WAAW,EAAG,YAAY,KAAU,wFAAwF;KAC5H,OAAO;KACP,aAAa,EAAE,eAAe,EAAE,4BAA4B;KAC5D,WAAW,MAAM;MAGf,AAFA,EAAQ,EAAE,OAAO,KAAK,GACtB,EAAQ,EAAI,GACZ,EAAU,KAAA,CAAS;KACrB;KACA,SAAS;KACT,SAAS;KACT,YAAY,MAAM;MAChB,IAAI,EAAE,QAAQ,UAAU;OAGtB,AAFA,EAAE,eAAe,GACjB,EAAQ,EAAK,GACb,EAAU,KAAA,CAAS;OACnB;MACF;MACA,AAAI,EAAE,QAAQ,eACZ,EAAE,eAAe,GACjB,EAAO,GACP,EAAS,IAAO,KAAK,IAAI,EAAQ,SAAS,GAAG,IAAc,CAAC,IAAI,CAAC,KACxD,EAAE,QAAQ,aAAa,MAChC,EAAE,eAAe,GACjB,EAAS,KAAK,IAAI,IAAI,IAAc,CAAC,CAAC;KAE1C;IACD,CAAA;IACA,MAAW,KAAQ,MAClB,kBAAC,UAAD;KACE,MAAK;KACL,WAAU;KACV,cAAmB,EAAP,IAAS,yBAA4B,cAAc;KAC/D,cAAc,MAAU,EAAM,eAAe;KAC7C,eAAe;MAGb,AAFA,EAAM,SAAS,MAAM,GACrB,EAAU,KAAA,CAAS,GACf,KAAQ,EAAQ,EAAE,GAAG,EAAQ,EAAI,KAChC,EAAQ,EAAK;KACpB;KACD,UAAA,kBAAC,GAAD;MAAe,MAAM;MAAc,aAAa;MAAG,WAAU;MAAS,eAAA;KAAa,CAAA;IAAS,CAAA;GAE3F;EACL,CAAA,GAAA,MAAS,IAAS,GACjB,kBAAC,GAAD;GAAkB,YAAY,EAAE;GAAY,WAAU;GAA0C,OAAO,EAAE,OAAI;GAAG,aAAU;GAA1H,UAAA,CACE,kBAAC,OAAD;IAAK,WAAU;IAAgD,aAAU;IAAkB,eAAA;GAAa,CAAA,GACxG,kBAAC,OAAD;IAAK,KAAK;IAAO,OAAO;KAAE,OAAO,EAAO;KAAO,YAAY,EAAO;IAAK;IAAG,WAAU;IAAgL,aAAU;IAAe,WAAW;IACtS,UAAA,kBAAC,OAAD;KAAK,WAAU;KACb,UAAA,kBAAC,OAAD;MAAK,WAAU;MAAgF,OAAO,EAAE,WAAW,+CAA+C,EAAI,iBAAiB;MACrL,UAAA,kBAAC,OAAD,EAAA,UAAM,EAAa,CAAA;KAChB,CAAA;IACF,CAAA;GACF,CAAA,CACW;EAAG,CAAA,GAAA,SAAS,IAChC,IAAI,kBAAC,OAAD;GAAK,KAAK;GAAO,WAAU;GAAmJ,aAAU;GAAe,WAAW;GAAe,UAAA;EAAa,CAAA,EAElO;;AAEtB"}
@@ -67,6 +67,7 @@ var e = {
67
67
  removeRecent: "„{q}“ entfernen"
68
68
  },
69
69
  listing: {
70
+ activityRange: "Aktivität von {from} bis vor {until} (UTC)",
70
71
  popularPeriod: "Beliebtheitszeitraum",
71
72
  pastDays_one: "Letzter {count} Tag",
72
73
  pastDays_other: "Letzte {count} Tage",
@@ -1 +1 @@
1
- {"version":3,"file":"de.js","names":[],"sources":["../../../src/locales/discovery/de.ts"],"sourcesContent":["import type { discovery as en } from \"./en.js\";\n\nexport const discovery: typeof en = {\n readerSettings: {\n filterTitle: \"Inhaltsfilter\",\n filterDescription: \"Wähle die Inhalte, die du sehen möchtest.\",\n savingPreferences: \"Deine Einstellungen werden gespeichert…\",\n preferencesNotSaved: \"Deine Einstellungen wurden noch nicht gespeichert.\",\n title: \"Leseeinstellungen\",\n description: \"Wähle deine Sprache und die angezeigten Inhalte.\",\n filters: \"Inhalte anzeigen:\",\n },\n releases: {\n premiumMore_one: \"{count} weiterer Eintrag\",\n premiumMore_other: \"{count} weitere Einträge\",\n premiumHint: \"Vorschauen für Mitglieder · Zum Ansehen klicken\",\n filteredMore_one: \"{count} Eintrag ausgefiltert\",\n filteredMore_other: \"{count} Einträge ausgefiltert\",\n manageFilters: \"Inhaltsfilter ändern\",\n filterContext: \"Filter für {date}. Ein Eintrag kann mehreren Filtern entsprechen.\",\n },\n contents: {\n showMore: \"Mehr anzeigen\",\n unknownAccess: \"Gerade nicht verfügbar\",\n members: \"Mitglieder\",\n joinFree: \"Kostenlos beitreten\",\n forSale: \"Zu kaufen\",\n locked: \"Gesperrt\",\n pages_one: \"{count} Seite\",\n pages_other: \"{count} Seiten\",\n minutes_one: \"{count} Min.\",\n minutes_other: \"{count} Min.\",\n completed: \"Beendet\",\n freeFrom: \"Kostenlos ab {date}\",\n favorites: \"Favoriten\",\n likes: \"Likes\",\n empty: \"Hier ist noch nichts.\",\n loading: \"Wird geladen…\",\n loadMore: \"Mehr laden\",\n lockedShow_one: \"{count} gesperrten Eintrag zeigen\",\n lockedShow_other: \"{count} gesperrte Einträge zeigen\",\n lockedHide: \"Gesperrte Einträge ausblenden\",\n noResults: \"Nichts passt zu „{q}“.\",\n historySignedOut: \"Melde dich an, um deinen Verlauf zu sehen.\",\n clearHistory: \"Verlauf löschen\",\n historyEmpty: \"Dein Verlauf ist leer.\",\n removeFromHistory: \"Aus dem Verlauf entfernen\",\n search: \"Suche\",\n searchPlaceholder: \"Suchen…\",\n clearSearch: \"Suche löschen\",\n suggestions: \"Vorschläge\",\n filtersSignedOut: \"Melde dich an, um zu wählen, was du siehst.\",\n shown: \"Angezeigt\",\n hidden: \"Ausgeblendet\",\n useDefault: \"Standard verwenden\",\n noFilters: \"Diese Website hat keine Inhaltsfilter.\",\n includeDeleted: \"Entfernte Inhalte zeigen, die ich gekauft habe\",\n noDates: \"Keine Erscheinungsdaten.\",\n items_one: \"{count} Eintrag\",\n items_other: \"{count} Einträge\",\n free_one: \"{count} kostenlos\",\n free_other: \"{count} kostenlos\",\n recentSearches: \"Letzte Suchen\",\n noRecentSearches: \"Noch keine letzten Suchanfragen.\",\n searchHint: \"Tippe, um zu suchen.\",\n clearRecent: \"Löschen\",\n clearAllRecent: \"Alle löschen\",\n removeRecent: \"„{q}“ entfernen\",\n },\n listing: {\n popularPeriod: \"Beliebtheitszeitraum\",\n pastDays_one: \"Letzter {count} Tag\",\n pastDays_other: \"Letzte {count} Tage\",\n sort: \"Sortieren\",\n sort_newest: \"Neueste\",\n sort_oldest: \"Älteste\",\n sort_title: \"Titel\",\n sort_popular: \"Beliebt\",\n sort_top_rated: \"Bestbewertet\",\n sort_most_favorited: \"Meiste Favoriten\",\n sort_most_viewed: \"Meistgesehen\",\n sort_random: \"Zufällig\",\n sort_position: \"Reihenfolge\",\n period_7d: \"diese Woche\",\n period_30d: \"diesen Monat\",\n period_90d: \"letzte 3 Monate\",\n period_365d: \"dieses Jahr\",\n period_all: \"insgesamt\",\n sortPeriod: \"{sort}, {period}\",\n language: \"Sprache\",\n anyLanguage: \"Alle Sprachen\",\n any: \"Alle\",\n filters: \"Filter\",\n clear: \"Filter zurücksetzen\",\n },\n};\n"],"mappings":";AAEA,IAAa,IAAuB;CAClC,gBAAgB;EACd,aAAa;EACb,mBAAmB;EACnB,mBAAmB;EACnB,qBAAqB;EACrB,OAAO;EACP,aAAa;EACb,SAAS;CACX;CACA,UAAU;EACR,iBAAiB;EACjB,mBAAmB;EACnB,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,eAAe;EACf,eAAe;CACjB;CACA,UAAU;EACR,UAAU;EACV,eAAe;EACf,SAAS;EACT,UAAU;EACV,SAAS;EACT,QAAQ;EACR,WAAW;EACX,aAAa;EACb,aAAa;EACb,eAAe;EACf,WAAW;EACX,UAAU;EACV,WAAW;EACX,OAAO;EACP,OAAO;EACP,SAAS;EACT,UAAU;EACV,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,WAAW;EACX,kBAAkB;EAClB,cAAc;EACd,cAAc;EACd,mBAAmB;EACnB,QAAQ;EACR,mBAAmB;EACnB,aAAa;EACb,aAAa;EACb,kBAAkB;EAClB,OAAO;EACP,QAAQ;EACR,YAAY;EACZ,WAAW;EACX,gBAAgB;EAChB,SAAS;EACT,WAAW;EACX,aAAa;EACb,UAAU;EACV,YAAY;EACZ,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,aAAa;EACb,gBAAgB;EAChB,cAAc;CAChB;CACA,SAAS;EACP,eAAe;EACf,cAAc;EACd,gBAAgB;EAChB,MAAM;EACN,aAAa;EACb,aAAa;EACb,YAAY;EACZ,cAAc;EACd,gBAAgB;EAChB,qBAAqB;EACrB,kBAAkB;EAClB,aAAa;EACb,eAAe;EACf,WAAW;EACX,YAAY;EACZ,YAAY;EACZ,aAAa;EACb,YAAY;EACZ,YAAY;EACZ,UAAU;EACV,aAAa;EACb,KAAK;EACL,SAAS;EACT,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"de.js","names":[],"sources":["../../../src/locales/discovery/de.ts"],"sourcesContent":["import type { discovery as en } from \"./en.js\";\n\nexport const discovery: typeof en = {\n readerSettings: {\n filterTitle: \"Inhaltsfilter\",\n filterDescription: \"Wähle die Inhalte, die du sehen möchtest.\",\n savingPreferences: \"Deine Einstellungen werden gespeichert…\",\n preferencesNotSaved: \"Deine Einstellungen wurden noch nicht gespeichert.\",\n title: \"Leseeinstellungen\",\n description: \"Wähle deine Sprache und die angezeigten Inhalte.\",\n filters: \"Inhalte anzeigen:\",\n },\n releases: {\n premiumMore_one: \"{count} weiterer Eintrag\",\n premiumMore_other: \"{count} weitere Einträge\",\n premiumHint: \"Vorschauen für Mitglieder · Zum Ansehen klicken\",\n filteredMore_one: \"{count} Eintrag ausgefiltert\",\n filteredMore_other: \"{count} Einträge ausgefiltert\",\n manageFilters: \"Inhaltsfilter ändern\",\n filterContext: \"Filter für {date}. Ein Eintrag kann mehreren Filtern entsprechen.\",\n },\n contents: {\n showMore: \"Mehr anzeigen\",\n unknownAccess: \"Gerade nicht verfügbar\",\n members: \"Mitglieder\",\n joinFree: \"Kostenlos beitreten\",\n forSale: \"Zu kaufen\",\n locked: \"Gesperrt\",\n pages_one: \"{count} Seite\",\n pages_other: \"{count} Seiten\",\n minutes_one: \"{count} Min.\",\n minutes_other: \"{count} Min.\",\n completed: \"Beendet\",\n freeFrom: \"Kostenlos ab {date}\",\n favorites: \"Favoriten\",\n likes: \"Likes\",\n empty: \"Hier ist noch nichts.\",\n loading: \"Wird geladen…\",\n loadMore: \"Mehr laden\",\n lockedShow_one: \"{count} gesperrten Eintrag zeigen\",\n lockedShow_other: \"{count} gesperrte Einträge zeigen\",\n lockedHide: \"Gesperrte Einträge ausblenden\",\n noResults: \"Nichts passt zu „{q}“.\",\n historySignedOut: \"Melde dich an, um deinen Verlauf zu sehen.\",\n clearHistory: \"Verlauf löschen\",\n historyEmpty: \"Dein Verlauf ist leer.\",\n removeFromHistory: \"Aus dem Verlauf entfernen\",\n search: \"Suche\",\n searchPlaceholder: \"Suchen…\",\n clearSearch: \"Suche löschen\",\n suggestions: \"Vorschläge\",\n filtersSignedOut: \"Melde dich an, um zu wählen, was du siehst.\",\n shown: \"Angezeigt\",\n hidden: \"Ausgeblendet\",\n useDefault: \"Standard verwenden\",\n noFilters: \"Diese Website hat keine Inhaltsfilter.\",\n includeDeleted: \"Entfernte Inhalte zeigen, die ich gekauft habe\",\n noDates: \"Keine Erscheinungsdaten.\",\n items_one: \"{count} Eintrag\",\n items_other: \"{count} Einträge\",\n free_one: \"{count} kostenlos\",\n free_other: \"{count} kostenlos\",\n recentSearches: \"Letzte Suchen\",\n noRecentSearches: \"Noch keine letzten Suchanfragen.\",\n searchHint: \"Tippe, um zu suchen.\",\n clearRecent: \"Löschen\",\n clearAllRecent: \"Alle löschen\",\n removeRecent: \"„{q}“ entfernen\",\n },\n listing: {\n activityRange: \"Aktivität von {from} bis vor {until} (UTC)\",\n popularPeriod: \"Beliebtheitszeitraum\",\n pastDays_one: \"Letzter {count} Tag\",\n pastDays_other: \"Letzte {count} Tage\",\n sort: \"Sortieren\",\n sort_newest: \"Neueste\",\n sort_oldest: \"Älteste\",\n sort_title: \"Titel\",\n sort_popular: \"Beliebt\",\n sort_top_rated: \"Bestbewertet\",\n sort_most_favorited: \"Meiste Favoriten\",\n sort_most_viewed: \"Meistgesehen\",\n sort_random: \"Zufällig\",\n sort_position: \"Reihenfolge\",\n period_7d: \"diese Woche\",\n period_30d: \"diesen Monat\",\n period_90d: \"letzte 3 Monate\",\n period_365d: \"dieses Jahr\",\n period_all: \"insgesamt\",\n sortPeriod: \"{sort}, {period}\",\n language: \"Sprache\",\n anyLanguage: \"Alle Sprachen\",\n any: \"Alle\",\n filters: \"Filter\",\n clear: \"Filter zurücksetzen\",\n },\n};\n"],"mappings":";AAEA,IAAa,IAAuB;CAClC,gBAAgB;EACd,aAAa;EACb,mBAAmB;EACnB,mBAAmB;EACnB,qBAAqB;EACrB,OAAO;EACP,aAAa;EACb,SAAS;CACX;CACA,UAAU;EACR,iBAAiB;EACjB,mBAAmB;EACnB,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,eAAe;EACf,eAAe;CACjB;CACA,UAAU;EACR,UAAU;EACV,eAAe;EACf,SAAS;EACT,UAAU;EACV,SAAS;EACT,QAAQ;EACR,WAAW;EACX,aAAa;EACb,aAAa;EACb,eAAe;EACf,WAAW;EACX,UAAU;EACV,WAAW;EACX,OAAO;EACP,OAAO;EACP,SAAS;EACT,UAAU;EACV,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,WAAW;EACX,kBAAkB;EAClB,cAAc;EACd,cAAc;EACd,mBAAmB;EACnB,QAAQ;EACR,mBAAmB;EACnB,aAAa;EACb,aAAa;EACb,kBAAkB;EAClB,OAAO;EACP,QAAQ;EACR,YAAY;EACZ,WAAW;EACX,gBAAgB;EAChB,SAAS;EACT,WAAW;EACX,aAAa;EACb,UAAU;EACV,YAAY;EACZ,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,aAAa;EACb,gBAAgB;EAChB,cAAc;CAChB;CACA,SAAS;EACP,eAAe;EACf,eAAe;EACf,cAAc;EACd,gBAAgB;EAChB,MAAM;EACN,aAAa;EACb,aAAa;EACb,YAAY;EACZ,cAAc;EACd,gBAAgB;EAChB,qBAAqB;EACrB,kBAAkB;EAClB,aAAa;EACb,eAAe;EACf,WAAW;EACX,YAAY;EACZ,YAAY;EACZ,aAAa;EACb,YAAY;EACZ,YAAY;EACZ,UAAU;EACV,aAAa;EACb,KAAK;EACL,SAAS;EACT,OAAO;CACT;AACF"}
@@ -67,6 +67,7 @@ export declare const discovery: {
67
67
  };
68
68
  listing: {
69
69
  popularPeriod: string;
70
+ activityRange: string;
70
71
  pastDays_one: string;
71
72
  pastDays_other: string;
72
73
  sort: string;
@@ -68,6 +68,7 @@ var e = {
68
68
  },
69
69
  listing: {
70
70
  popularPeriod: "Popularity period",
71
+ activityRange: "Activity from {from} to before {until} (UTC)",
71
72
  pastDays_one: "Past {count} day",
72
73
  pastDays_other: "Past {count} days",
73
74
  sort: "Sort",
@@ -1 +1 @@
1
- {"version":3,"file":"en.js","names":[],"sources":["../../../src/locales/discovery/en.ts"],"sourcesContent":["// Discovery: cards, grids, rails, search, content filters, history, release dates.\nexport const discovery = {\n readerSettings: {\n filterTitle: \"Content filters\",\n filterDescription: \"Choose the content you want to see.\",\n savingPreferences: \"Saving your preferences…\",\n preferencesNotSaved: \"Your preferences haven't been saved yet.\",\n title: \"Reader settings\",\n description: \"Choose your language and the content you see.\",\n filters: \"Show Content:\",\n },\n releases: {\n premiumMore_one: \"{count} more item\",\n premiumMore_other: \"{count} more items\",\n premiumHint: \"Members-only previews · Click to view\",\n filteredMore_one: \"{count} item filtered out\",\n filteredMore_other: \"{count} items filtered out\",\n manageFilters: \"Change content filters\",\n filterContext: \"Filters for {date}. An item can match more than one filter.\",\n },\n contents: {\n showMore: \"Show more\",\n unknownAccess: \"Unavailable right now\",\n members: \"Members\",\n joinFree: \"Free to join\",\n forSale: \"For sale\",\n locked: \"Locked\",\n pages_one: \"{count} page\",\n pages_other: \"{count} pages\",\n minutes_one: \"{count} min\",\n minutes_other: \"{count} min\",\n completed: \"Finished\",\n freeFrom: \"Free from {date}\",\n favorites: \"Favorites\",\n likes: \"Likes\",\n empty: \"Nothing here yet.\",\n loading: \"Loading…\",\n loadMore: \"Load more\",\n lockedShow_one: \"Show {count} locked item\",\n lockedShow_other: \"Show {count} locked items\",\n lockedHide: \"Hide locked items\",\n noResults: \"Nothing matches “{q}”.\",\n historySignedOut: \"Sign in to see your history.\",\n clearHistory: \"Clear history\",\n historyEmpty: \"Your history is empty.\",\n removeFromHistory: \"Remove from history\",\n search: \"Search\",\n searchPlaceholder: \"Search…\",\n clearSearch: \"Clear search\",\n suggestions: \"Suggestions\",\n filtersSignedOut: \"Sign in to choose what you see.\",\n shown: \"Shown\",\n hidden: \"Hidden\",\n useDefault: \"Use the default\",\n noFilters: \"This site has no content filters.\",\n includeDeleted: \"Show removed content I bought\",\n noDates: \"No release dates.\",\n items_one: \"{count} item\",\n items_other: \"{count} items\",\n free_one: \"{count} free\",\n free_other: \"{count} free\",\n recentSearches: \"Recent searches\",\n noRecentSearches: \"No recent searches yet.\",\n searchHint: \"Start typing to search.\",\n clearRecent: \"Clear\",\n clearAllRecent: \"Clear all\",\n removeRecent: \"Remove “{q}”\",\n },\n listing: {\n popularPeriod: \"Popularity period\",\n pastDays_one: \"Past {count} day\",\n pastDays_other: \"Past {count} days\",\n sort: \"Sort\",\n sort_newest: \"Newest\",\n sort_oldest: \"Oldest\",\n sort_title: \"Title\",\n sort_popular: \"Popular\",\n sort_top_rated: \"Top rated\",\n sort_most_favorited: \"Most favorited\",\n sort_most_viewed: \"Most viewed\",\n sort_random: \"Random\",\n sort_position: \"In order\",\n period_7d: \"this week\",\n period_30d: \"this month\",\n period_90d: \"last 3 months\",\n period_365d: \"this year\",\n period_all: \"all time\",\n sortPeriod: \"{sort}, {period}\",\n language: \"Language\",\n anyLanguage: \"Any language\",\n any: \"Any\",\n filters: \"Filters\",\n clear: \"Clear filters\",\n },\n};\n"],"mappings":";AACA,IAAa,IAAY;CACvB,gBAAgB;EACd,aAAa;EACb,mBAAmB;EACnB,mBAAmB;EACnB,qBAAqB;EACrB,OAAO;EACP,aAAa;EACb,SAAS;CACX;CACA,UAAU;EACR,iBAAiB;EACjB,mBAAmB;EACnB,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,eAAe;EACf,eAAe;CACjB;CACA,UAAU;EACR,UAAU;EACV,eAAe;EACf,SAAS;EACT,UAAU;EACV,SAAS;EACT,QAAQ;EACR,WAAW;EACX,aAAa;EACb,aAAa;EACb,eAAe;EACf,WAAW;EACX,UAAU;EACV,WAAW;EACX,OAAO;EACP,OAAO;EACP,SAAS;EACT,UAAU;EACV,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,WAAW;EACX,kBAAkB;EAClB,cAAc;EACd,cAAc;EACd,mBAAmB;EACnB,QAAQ;EACR,mBAAmB;EACnB,aAAa;EACb,aAAa;EACb,kBAAkB;EAClB,OAAO;EACP,QAAQ;EACR,YAAY;EACZ,WAAW;EACX,gBAAgB;EAChB,SAAS;EACT,WAAW;EACX,aAAa;EACb,UAAU;EACV,YAAY;EACZ,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,aAAa;EACb,gBAAgB;EAChB,cAAc;CAChB;CACA,SAAS;EACP,eAAe;EACf,cAAc;EACd,gBAAgB;EAChB,MAAM;EACN,aAAa;EACb,aAAa;EACb,YAAY;EACZ,cAAc;EACd,gBAAgB;EAChB,qBAAqB;EACrB,kBAAkB;EAClB,aAAa;EACb,eAAe;EACf,WAAW;EACX,YAAY;EACZ,YAAY;EACZ,aAAa;EACb,YAAY;EACZ,YAAY;EACZ,UAAU;EACV,aAAa;EACb,KAAK;EACL,SAAS;EACT,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"en.js","names":[],"sources":["../../../src/locales/discovery/en.ts"],"sourcesContent":["// Discovery: cards, grids, rails, search, content filters, history, release dates.\nexport const discovery = {\n readerSettings: {\n filterTitle: \"Content filters\",\n filterDescription: \"Choose the content you want to see.\",\n savingPreferences: \"Saving your preferences…\",\n preferencesNotSaved: \"Your preferences haven't been saved yet.\",\n title: \"Reader settings\",\n description: \"Choose your language and the content you see.\",\n filters: \"Show Content:\",\n },\n releases: {\n premiumMore_one: \"{count} more item\",\n premiumMore_other: \"{count} more items\",\n premiumHint: \"Members-only previews · Click to view\",\n filteredMore_one: \"{count} item filtered out\",\n filteredMore_other: \"{count} items filtered out\",\n manageFilters: \"Change content filters\",\n filterContext: \"Filters for {date}. An item can match more than one filter.\",\n },\n contents: {\n showMore: \"Show more\",\n unknownAccess: \"Unavailable right now\",\n members: \"Members\",\n joinFree: \"Free to join\",\n forSale: \"For sale\",\n locked: \"Locked\",\n pages_one: \"{count} page\",\n pages_other: \"{count} pages\",\n minutes_one: \"{count} min\",\n minutes_other: \"{count} min\",\n completed: \"Finished\",\n freeFrom: \"Free from {date}\",\n favorites: \"Favorites\",\n likes: \"Likes\",\n empty: \"Nothing here yet.\",\n loading: \"Loading…\",\n loadMore: \"Load more\",\n lockedShow_one: \"Show {count} locked item\",\n lockedShow_other: \"Show {count} locked items\",\n lockedHide: \"Hide locked items\",\n noResults: \"Nothing matches “{q}”.\",\n historySignedOut: \"Sign in to see your history.\",\n clearHistory: \"Clear history\",\n historyEmpty: \"Your history is empty.\",\n removeFromHistory: \"Remove from history\",\n search: \"Search\",\n searchPlaceholder: \"Search…\",\n clearSearch: \"Clear search\",\n suggestions: \"Suggestions\",\n filtersSignedOut: \"Sign in to choose what you see.\",\n shown: \"Shown\",\n hidden: \"Hidden\",\n useDefault: \"Use the default\",\n noFilters: \"This site has no content filters.\",\n includeDeleted: \"Show removed content I bought\",\n noDates: \"No release dates.\",\n items_one: \"{count} item\",\n items_other: \"{count} items\",\n free_one: \"{count} free\",\n free_other: \"{count} free\",\n recentSearches: \"Recent searches\",\n noRecentSearches: \"No recent searches yet.\",\n searchHint: \"Start typing to search.\",\n clearRecent: \"Clear\",\n clearAllRecent: \"Clear all\",\n removeRecent: \"Remove “{q}”\",\n },\n listing: {\n popularPeriod: \"Popularity period\",\n activityRange: \"Activity from {from} to before {until} (UTC)\",\n pastDays_one: \"Past {count} day\",\n pastDays_other: \"Past {count} days\",\n sort: \"Sort\",\n sort_newest: \"Newest\",\n sort_oldest: \"Oldest\",\n sort_title: \"Title\",\n sort_popular: \"Popular\",\n sort_top_rated: \"Top rated\",\n sort_most_favorited: \"Most favorited\",\n sort_most_viewed: \"Most viewed\",\n sort_random: \"Random\",\n sort_position: \"In order\",\n period_7d: \"this week\",\n period_30d: \"this month\",\n period_90d: \"last 3 months\",\n period_365d: \"this year\",\n period_all: \"all time\",\n sortPeriod: \"{sort}, {period}\",\n language: \"Language\",\n anyLanguage: \"Any language\",\n any: \"Any\",\n filters: \"Filters\",\n clear: \"Clear filters\",\n },\n};\n"],"mappings":";AACA,IAAa,IAAY;CACvB,gBAAgB;EACd,aAAa;EACb,mBAAmB;EACnB,mBAAmB;EACnB,qBAAqB;EACrB,OAAO;EACP,aAAa;EACb,SAAS;CACX;CACA,UAAU;EACR,iBAAiB;EACjB,mBAAmB;EACnB,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,eAAe;EACf,eAAe;CACjB;CACA,UAAU;EACR,UAAU;EACV,eAAe;EACf,SAAS;EACT,UAAU;EACV,SAAS;EACT,QAAQ;EACR,WAAW;EACX,aAAa;EACb,aAAa;EACb,eAAe;EACf,WAAW;EACX,UAAU;EACV,WAAW;EACX,OAAO;EACP,OAAO;EACP,SAAS;EACT,UAAU;EACV,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,WAAW;EACX,kBAAkB;EAClB,cAAc;EACd,cAAc;EACd,mBAAmB;EACnB,QAAQ;EACR,mBAAmB;EACnB,aAAa;EACb,aAAa;EACb,kBAAkB;EAClB,OAAO;EACP,QAAQ;EACR,YAAY;EACZ,WAAW;EACX,gBAAgB;EAChB,SAAS;EACT,WAAW;EACX,aAAa;EACb,UAAU;EACV,YAAY;EACZ,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,aAAa;EACb,gBAAgB;EAChB,cAAc;CAChB;CACA,SAAS;EACP,eAAe;EACf,eAAe;EACf,cAAc;EACd,gBAAgB;EAChB,MAAM;EACN,aAAa;EACb,aAAa;EACb,YAAY;EACZ,cAAc;EACd,gBAAgB;EAChB,qBAAqB;EACrB,kBAAkB;EAClB,aAAa;EACb,eAAe;EACf,WAAW;EACX,YAAY;EACZ,YAAY;EACZ,aAAa;EACb,YAAY;EACZ,YAAY;EACZ,UAAU;EACV,aAAa;EACb,KAAK;EACL,SAAS;EACT,OAAO;CACT;AACF"}
@@ -67,6 +67,7 @@ var e = {
67
67
  removeRecent: "Quitar «{q}»"
68
68
  },
69
69
  listing: {
70
+ activityRange: "Actividad desde {from} hasta antes de {until} (UTC)",
70
71
  popularPeriod: "Período de popularidad",
71
72
  pastDays_one: "Último {count} día",
72
73
  pastDays_other: "Últimos {count} días",
@@ -1 +1 @@
1
- {"version":3,"file":"es.js","names":[],"sources":["../../../src/locales/discovery/es.ts"],"sourcesContent":["import type { discovery as en } from \"./en.js\";\n\nexport const discovery: typeof en = {\n readerSettings: {\n filterTitle: \"Filtros de contenido\",\n filterDescription: \"Elige el contenido que quieres ver.\",\n savingPreferences: \"Guardando tus preferencias…\",\n preferencesNotSaved: \"Tus preferencias aún no se han guardado.\",\n title: \"Ajustes de lectura\",\n description: \"Elige tu idioma y el contenido que ves.\",\n filters: \"Mostrar contenido:\",\n },\n releases: {\n premiumMore_one: \"{count} elemento más\",\n premiumMore_other: \"{count} elementos más\",\n premiumHint: \"Vistas previas para miembros · Haz clic para ver\",\n filteredMore_one: \"{count} elemento filtrado\",\n filteredMore_other: \"{count} elementos filtrados\",\n manageFilters: \"Cambiar filtros de contenido\",\n filterContext: \"Filtros para {date}. Un elemento puede coincidir con varios filtros.\",\n },\n contents: {\n showMore: \"Mostrar más\",\n unknownAccess: \"No disponible ahora\",\n members: \"Miembros\",\n joinFree: \"Unirse gratis\",\n forSale: \"A la venta\",\n locked: \"Bloqueado\",\n pages_one: \"{count} página\",\n pages_other: \"{count} páginas\",\n minutes_one: \"{count} min\",\n minutes_other: \"{count} min\",\n completed: \"Terminado\",\n freeFrom: \"Gratis desde el {date}\",\n favorites: \"Favoritos\",\n likes: \"Me gusta\",\n empty: \"Aún no hay nada aquí.\",\n loading: \"Cargando…\",\n loadMore: \"Cargar más\",\n lockedShow_one: \"Mostrar {count} elemento bloqueado\",\n lockedShow_other: \"Mostrar {count} elementos bloqueados\",\n lockedHide: \"Ocultar elementos bloqueados\",\n noResults: \"Nada coincide con «{q}».\",\n historySignedOut: \"Inicia sesión para ver tu historial.\",\n clearHistory: \"Borrar historial\",\n historyEmpty: \"Tu historial está vacío.\",\n removeFromHistory: \"Quitar del historial\",\n search: \"Buscar\",\n searchPlaceholder: \"Buscar…\",\n clearSearch: \"Borrar búsqueda\",\n suggestions: \"Sugerencias\",\n filtersSignedOut: \"Inicia sesión para elegir lo que ves.\",\n shown: \"Visible\",\n hidden: \"Oculto\",\n useDefault: \"Usar el predeterminado\",\n noFilters: \"Este sitio no tiene filtros de contenido.\",\n includeDeleted: \"Mostrar contenido retirado que compré\",\n noDates: \"No hay fechas de publicación.\",\n items_one: \"{count} elemento\",\n items_other: \"{count} elementos\",\n free_one: \"{count} gratis\",\n free_other: \"{count} gratis\",\n recentSearches: \"Búsquedas recientes\",\n noRecentSearches: \"Aún no hay búsquedas recientes.\",\n searchHint: \"Empieza a escribir para buscar.\",\n clearRecent: \"Borrar\",\n clearAllRecent: \"Borrar todo\",\n removeRecent: \"Quitar «{q}»\",\n },\n listing: {\n popularPeriod: \"Período de popularidad\",\n pastDays_one: \"Último {count} día\",\n pastDays_other: \"Últimos {count} días\",\n sort: \"Ordenar\",\n sort_newest: \"Más recientes\",\n sort_oldest: \"Más antiguos\",\n sort_title: \"Título\",\n sort_popular: \"Populares\",\n sort_top_rated: \"Mejor valorados\",\n sort_most_favorited: \"Más favoritos\",\n sort_most_viewed: \"Más vistos\",\n sort_random: \"Aleatorio\",\n sort_position: \"En orden\",\n period_7d: \"esta semana\",\n period_30d: \"este mes\",\n period_90d: \"últimos 3 meses\",\n period_365d: \"este año\",\n period_all: \"siempre\",\n sortPeriod: \"{sort}, {period}\",\n language: \"Idioma\",\n anyLanguage: \"Cualquier idioma\",\n any: \"Cualquiera\",\n filters: \"Filtros\",\n clear: \"Quitar filtros\",\n },\n};\n"],"mappings":";AAEA,IAAa,IAAuB;CAClC,gBAAgB;EACd,aAAa;EACb,mBAAmB;EACnB,mBAAmB;EACnB,qBAAqB;EACrB,OAAO;EACP,aAAa;EACb,SAAS;CACX;CACA,UAAU;EACR,iBAAiB;EACjB,mBAAmB;EACnB,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,eAAe;EACf,eAAe;CACjB;CACA,UAAU;EACR,UAAU;EACV,eAAe;EACf,SAAS;EACT,UAAU;EACV,SAAS;EACT,QAAQ;EACR,WAAW;EACX,aAAa;EACb,aAAa;EACb,eAAe;EACf,WAAW;EACX,UAAU;EACV,WAAW;EACX,OAAO;EACP,OAAO;EACP,SAAS;EACT,UAAU;EACV,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,WAAW;EACX,kBAAkB;EAClB,cAAc;EACd,cAAc;EACd,mBAAmB;EACnB,QAAQ;EACR,mBAAmB;EACnB,aAAa;EACb,aAAa;EACb,kBAAkB;EAClB,OAAO;EACP,QAAQ;EACR,YAAY;EACZ,WAAW;EACX,gBAAgB;EAChB,SAAS;EACT,WAAW;EACX,aAAa;EACb,UAAU;EACV,YAAY;EACZ,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,aAAa;EACb,gBAAgB;EAChB,cAAc;CAChB;CACA,SAAS;EACP,eAAe;EACf,cAAc;EACd,gBAAgB;EAChB,MAAM;EACN,aAAa;EACb,aAAa;EACb,YAAY;EACZ,cAAc;EACd,gBAAgB;EAChB,qBAAqB;EACrB,kBAAkB;EAClB,aAAa;EACb,eAAe;EACf,WAAW;EACX,YAAY;EACZ,YAAY;EACZ,aAAa;EACb,YAAY;EACZ,YAAY;EACZ,UAAU;EACV,aAAa;EACb,KAAK;EACL,SAAS;EACT,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"es.js","names":[],"sources":["../../../src/locales/discovery/es.ts"],"sourcesContent":["import type { discovery as en } from \"./en.js\";\n\nexport const discovery: typeof en = {\n readerSettings: {\n filterTitle: \"Filtros de contenido\",\n filterDescription: \"Elige el contenido que quieres ver.\",\n savingPreferences: \"Guardando tus preferencias…\",\n preferencesNotSaved: \"Tus preferencias aún no se han guardado.\",\n title: \"Ajustes de lectura\",\n description: \"Elige tu idioma y el contenido que ves.\",\n filters: \"Mostrar contenido:\",\n },\n releases: {\n premiumMore_one: \"{count} elemento más\",\n premiumMore_other: \"{count} elementos más\",\n premiumHint: \"Vistas previas para miembros · Haz clic para ver\",\n filteredMore_one: \"{count} elemento filtrado\",\n filteredMore_other: \"{count} elementos filtrados\",\n manageFilters: \"Cambiar filtros de contenido\",\n filterContext: \"Filtros para {date}. Un elemento puede coincidir con varios filtros.\",\n },\n contents: {\n showMore: \"Mostrar más\",\n unknownAccess: \"No disponible ahora\",\n members: \"Miembros\",\n joinFree: \"Unirse gratis\",\n forSale: \"A la venta\",\n locked: \"Bloqueado\",\n pages_one: \"{count} página\",\n pages_other: \"{count} páginas\",\n minutes_one: \"{count} min\",\n minutes_other: \"{count} min\",\n completed: \"Terminado\",\n freeFrom: \"Gratis desde el {date}\",\n favorites: \"Favoritos\",\n likes: \"Me gusta\",\n empty: \"Aún no hay nada aquí.\",\n loading: \"Cargando…\",\n loadMore: \"Cargar más\",\n lockedShow_one: \"Mostrar {count} elemento bloqueado\",\n lockedShow_other: \"Mostrar {count} elementos bloqueados\",\n lockedHide: \"Ocultar elementos bloqueados\",\n noResults: \"Nada coincide con «{q}».\",\n historySignedOut: \"Inicia sesión para ver tu historial.\",\n clearHistory: \"Borrar historial\",\n historyEmpty: \"Tu historial está vacío.\",\n removeFromHistory: \"Quitar del historial\",\n search: \"Buscar\",\n searchPlaceholder: \"Buscar…\",\n clearSearch: \"Borrar búsqueda\",\n suggestions: \"Sugerencias\",\n filtersSignedOut: \"Inicia sesión para elegir lo que ves.\",\n shown: \"Visible\",\n hidden: \"Oculto\",\n useDefault: \"Usar el predeterminado\",\n noFilters: \"Este sitio no tiene filtros de contenido.\",\n includeDeleted: \"Mostrar contenido retirado que compré\",\n noDates: \"No hay fechas de publicación.\",\n items_one: \"{count} elemento\",\n items_other: \"{count} elementos\",\n free_one: \"{count} gratis\",\n free_other: \"{count} gratis\",\n recentSearches: \"Búsquedas recientes\",\n noRecentSearches: \"Aún no hay búsquedas recientes.\",\n searchHint: \"Empieza a escribir para buscar.\",\n clearRecent: \"Borrar\",\n clearAllRecent: \"Borrar todo\",\n removeRecent: \"Quitar «{q}»\",\n },\n listing: {\n activityRange: \"Actividad desde {from} hasta antes de {until} (UTC)\",\n popularPeriod: \"Período de popularidad\",\n pastDays_one: \"Último {count} día\",\n pastDays_other: \"Últimos {count} días\",\n sort: \"Ordenar\",\n sort_newest: \"Más recientes\",\n sort_oldest: \"Más antiguos\",\n sort_title: \"Título\",\n sort_popular: \"Populares\",\n sort_top_rated: \"Mejor valorados\",\n sort_most_favorited: \"Más favoritos\",\n sort_most_viewed: \"Más vistos\",\n sort_random: \"Aleatorio\",\n sort_position: \"En orden\",\n period_7d: \"esta semana\",\n period_30d: \"este mes\",\n period_90d: \"últimos 3 meses\",\n period_365d: \"este año\",\n period_all: \"siempre\",\n sortPeriod: \"{sort}, {period}\",\n language: \"Idioma\",\n anyLanguage: \"Cualquier idioma\",\n any: \"Cualquiera\",\n filters: \"Filtros\",\n clear: \"Quitar filtros\",\n },\n};\n"],"mappings":";AAEA,IAAa,IAAuB;CAClC,gBAAgB;EACd,aAAa;EACb,mBAAmB;EACnB,mBAAmB;EACnB,qBAAqB;EACrB,OAAO;EACP,aAAa;EACb,SAAS;CACX;CACA,UAAU;EACR,iBAAiB;EACjB,mBAAmB;EACnB,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,eAAe;EACf,eAAe;CACjB;CACA,UAAU;EACR,UAAU;EACV,eAAe;EACf,SAAS;EACT,UAAU;EACV,SAAS;EACT,QAAQ;EACR,WAAW;EACX,aAAa;EACb,aAAa;EACb,eAAe;EACf,WAAW;EACX,UAAU;EACV,WAAW;EACX,OAAO;EACP,OAAO;EACP,SAAS;EACT,UAAU;EACV,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,WAAW;EACX,kBAAkB;EAClB,cAAc;EACd,cAAc;EACd,mBAAmB;EACnB,QAAQ;EACR,mBAAmB;EACnB,aAAa;EACb,aAAa;EACb,kBAAkB;EAClB,OAAO;EACP,QAAQ;EACR,YAAY;EACZ,WAAW;EACX,gBAAgB;EAChB,SAAS;EACT,WAAW;EACX,aAAa;EACb,UAAU;EACV,YAAY;EACZ,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,aAAa;EACb,gBAAgB;EAChB,cAAc;CAChB;CACA,SAAS;EACP,eAAe;EACf,eAAe;EACf,cAAc;EACd,gBAAgB;EAChB,MAAM;EACN,aAAa;EACb,aAAa;EACb,YAAY;EACZ,cAAc;EACd,gBAAgB;EAChB,qBAAqB;EACrB,kBAAkB;EAClB,aAAa;EACb,eAAe;EACf,WAAW;EACX,YAAY;EACZ,YAAY;EACZ,aAAa;EACb,YAAY;EACZ,YAAY;EACZ,UAAU;EACV,aAAa;EACb,KAAK;EACL,SAAS;EACT,OAAO;CACT;AACF"}
@@ -67,6 +67,7 @@ var e = {
67
67
  removeRecent: "「{q}」を削除"
68
68
  },
69
69
  listing: {
70
+ activityRange: "{from}から{until}より前までのアクティビティ (UTC)",
70
71
  popularPeriod: "人気の集計期間",
71
72
  pastDays_one: "過去{count}日間",
72
73
  pastDays_other: "過去{count}日間",
@@ -1 +1 @@
1
- {"version":3,"file":"ja.js","names":[],"sources":["../../../src/locales/discovery/ja.ts"],"sourcesContent":["import type { discovery as en } from \"./en.js\";\n\nexport const discovery: typeof en = {\n readerSettings: {\n filterTitle: \"コンテンツフィルター\",\n filterDescription: \"表示するコンテンツを選択してください。\",\n savingPreferences: \"設定を保存しています…\",\n preferencesNotSaved: \"設定はまだ保存されていません。\",\n title: \"閲覧設定\",\n description: \"言語と表示するコンテンツを選択します。\",\n filters: \"表示するコンテンツ:\",\n },\n releases: {\n premiumMore_one: \"ほか {count} 件\",\n premiumMore_other: \"ほか {count} 件\",\n premiumHint: \"会員向けプレビュー · クリックして表示\",\n filteredMore_one: \"{count} 件を非表示\",\n filteredMore_other: \"{count} 件を非表示\",\n manageFilters: \"コンテンツフィルターを変更\",\n filterContext: \"{date} のフィルター。1つのコンテンツが複数のフィルターに該当する場合があります。\",\n },\n contents: {\n showMore: \"もっと表示\",\n unknownAccess: \"現在利用できません\",\n members: \"メンバー限定\",\n joinFree: \"無料で参加\",\n forSale: \"販売中\",\n locked: \"ロック中\",\n pages_one: \"{count} ページ\",\n pages_other: \"{count} ページ\",\n minutes_one: \"{count} 分\",\n minutes_other: \"{count} 分\",\n completed: \"読了\",\n freeFrom: \"{date} から無料\",\n favorites: \"お気に入り\",\n likes: \"いいね\",\n empty: \"まだ何もありません。\",\n loading: \"読み込み中…\",\n loadMore: \"さらに読み込む\",\n lockedShow_one: \"ロック中の{count}件を表示\",\n lockedShow_other: \"ロック中の{count}件を表示\",\n lockedHide: \"ロック中の項目を隠す\",\n noResults: \"「{q}」に一致するものはありません。\",\n historySignedOut: \"履歴を見るにはサインインしてください。\",\n clearHistory: \"履歴を消去\",\n historyEmpty: \"履歴はありません。\",\n removeFromHistory: \"履歴から削除\",\n search: \"検索\",\n searchPlaceholder: \"検索…\",\n clearSearch: \"検索をクリア\",\n suggestions: \"候補\",\n filtersSignedOut: \"表示する内容を選ぶにはサインインしてください。\",\n shown: \"表示\",\n hidden: \"非表示\",\n useDefault: \"既定に戻す\",\n noFilters: \"このサイトにはコンテンツフィルターがありません。\",\n includeDeleted: \"購入済みの削除されたコンテンツを表示\",\n noDates: \"公開日はありません。\",\n items_one: \"{count} 件\",\n items_other: \"{count} 件\",\n free_one: \"無料 {count} 件\",\n free_other: \"無料 {count} 件\",\n recentSearches: \"最近の検索\",\n noRecentSearches: \"最近の検索はまだありません。\",\n searchHint: \"キーワードを入力して検索します。\",\n clearRecent: \"消去\",\n clearAllRecent: \"すべて消去\",\n removeRecent: \"「{q}」を削除\",\n },\n listing: {\n popularPeriod: \"人気の集計期間\",\n pastDays_one: \"過去{count}日間\",\n pastDays_other: \"過去{count}日間\",\n sort: \"並べ替え\",\n sort_newest: \"新着\",\n sort_oldest: \"古い順\",\n sort_title: \"タイトル\",\n sort_popular: \"人気\",\n sort_top_rated: \"高評価\",\n sort_most_favorited: \"お気に入り数\",\n sort_most_viewed: \"閲覧数\",\n sort_random: \"ランダム\",\n sort_position: \"順番\",\n period_7d: \"今週\",\n period_30d: \"今月\",\n period_90d: \"過去3か月\",\n period_365d: \"今年\",\n period_all: \"全期間\",\n sortPeriod: \"{sort}({period})\",\n language: \"言語\",\n anyLanguage: \"すべての言語\",\n any: \"すべて\",\n filters: \"絞り込み\",\n clear: \"絞り込みを解除\",\n },\n};\n"],"mappings":";AAEA,IAAa,IAAuB;CAClC,gBAAgB;EACd,aAAa;EACb,mBAAmB;EACnB,mBAAmB;EACnB,qBAAqB;EACrB,OAAO;EACP,aAAa;EACb,SAAS;CACX;CACA,UAAU;EACR,iBAAiB;EACjB,mBAAmB;EACnB,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,eAAe;EACf,eAAe;CACjB;CACA,UAAU;EACR,UAAU;EACV,eAAe;EACf,SAAS;EACT,UAAU;EACV,SAAS;EACT,QAAQ;EACR,WAAW;EACX,aAAa;EACb,aAAa;EACb,eAAe;EACf,WAAW;EACX,UAAU;EACV,WAAW;EACX,OAAO;EACP,OAAO;EACP,SAAS;EACT,UAAU;EACV,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,WAAW;EACX,kBAAkB;EAClB,cAAc;EACd,cAAc;EACd,mBAAmB;EACnB,QAAQ;EACR,mBAAmB;EACnB,aAAa;EACb,aAAa;EACb,kBAAkB;EAClB,OAAO;EACP,QAAQ;EACR,YAAY;EACZ,WAAW;EACX,gBAAgB;EAChB,SAAS;EACT,WAAW;EACX,aAAa;EACb,UAAU;EACV,YAAY;EACZ,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,aAAa;EACb,gBAAgB;EAChB,cAAc;CAChB;CACA,SAAS;EACP,eAAe;EACf,cAAc;EACd,gBAAgB;EAChB,MAAM;EACN,aAAa;EACb,aAAa;EACb,YAAY;EACZ,cAAc;EACd,gBAAgB;EAChB,qBAAqB;EACrB,kBAAkB;EAClB,aAAa;EACb,eAAe;EACf,WAAW;EACX,YAAY;EACZ,YAAY;EACZ,aAAa;EACb,YAAY;EACZ,YAAY;EACZ,UAAU;EACV,aAAa;EACb,KAAK;EACL,SAAS;EACT,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"ja.js","names":[],"sources":["../../../src/locales/discovery/ja.ts"],"sourcesContent":["import type { discovery as en } from \"./en.js\";\n\nexport const discovery: typeof en = {\n readerSettings: {\n filterTitle: \"コンテンツフィルター\",\n filterDescription: \"表示するコンテンツを選択してください。\",\n savingPreferences: \"設定を保存しています…\",\n preferencesNotSaved: \"設定はまだ保存されていません。\",\n title: \"閲覧設定\",\n description: \"言語と表示するコンテンツを選択します。\",\n filters: \"表示するコンテンツ:\",\n },\n releases: {\n premiumMore_one: \"ほか {count} 件\",\n premiumMore_other: \"ほか {count} 件\",\n premiumHint: \"会員向けプレビュー · クリックして表示\",\n filteredMore_one: \"{count} 件を非表示\",\n filteredMore_other: \"{count} 件を非表示\",\n manageFilters: \"コンテンツフィルターを変更\",\n filterContext: \"{date} のフィルター。1つのコンテンツが複数のフィルターに該当する場合があります。\",\n },\n contents: {\n showMore: \"もっと表示\",\n unknownAccess: \"現在利用できません\",\n members: \"メンバー限定\",\n joinFree: \"無料で参加\",\n forSale: \"販売中\",\n locked: \"ロック中\",\n pages_one: \"{count} ページ\",\n pages_other: \"{count} ページ\",\n minutes_one: \"{count} 分\",\n minutes_other: \"{count} 分\",\n completed: \"読了\",\n freeFrom: \"{date} から無料\",\n favorites: \"お気に入り\",\n likes: \"いいね\",\n empty: \"まだ何もありません。\",\n loading: \"読み込み中…\",\n loadMore: \"さらに読み込む\",\n lockedShow_one: \"ロック中の{count}件を表示\",\n lockedShow_other: \"ロック中の{count}件を表示\",\n lockedHide: \"ロック中の項目を隠す\",\n noResults: \"「{q}」に一致するものはありません。\",\n historySignedOut: \"履歴を見るにはサインインしてください。\",\n clearHistory: \"履歴を消去\",\n historyEmpty: \"履歴はありません。\",\n removeFromHistory: \"履歴から削除\",\n search: \"検索\",\n searchPlaceholder: \"検索…\",\n clearSearch: \"検索をクリア\",\n suggestions: \"候補\",\n filtersSignedOut: \"表示する内容を選ぶにはサインインしてください。\",\n shown: \"表示\",\n hidden: \"非表示\",\n useDefault: \"既定に戻す\",\n noFilters: \"このサイトにはコンテンツフィルターがありません。\",\n includeDeleted: \"購入済みの削除されたコンテンツを表示\",\n noDates: \"公開日はありません。\",\n items_one: \"{count} 件\",\n items_other: \"{count} 件\",\n free_one: \"無料 {count} 件\",\n free_other: \"無料 {count} 件\",\n recentSearches: \"最近の検索\",\n noRecentSearches: \"最近の検索はまだありません。\",\n searchHint: \"キーワードを入力して検索します。\",\n clearRecent: \"消去\",\n clearAllRecent: \"すべて消去\",\n removeRecent: \"「{q}」を削除\",\n },\n listing: {\n activityRange: \"{from}から{until}より前までのアクティビティ (UTC)\",\n popularPeriod: \"人気の集計期間\",\n pastDays_one: \"過去{count}日間\",\n pastDays_other: \"過去{count}日間\",\n sort: \"並べ替え\",\n sort_newest: \"新着\",\n sort_oldest: \"古い順\",\n sort_title: \"タイトル\",\n sort_popular: \"人気\",\n sort_top_rated: \"高評価\",\n sort_most_favorited: \"お気に入り数\",\n sort_most_viewed: \"閲覧数\",\n sort_random: \"ランダム\",\n sort_position: \"順番\",\n period_7d: \"今週\",\n period_30d: \"今月\",\n period_90d: \"過去3か月\",\n period_365d: \"今年\",\n period_all: \"全期間\",\n sortPeriod: \"{sort}({period})\",\n language: \"言語\",\n anyLanguage: \"すべての言語\",\n any: \"すべて\",\n filters: \"絞り込み\",\n clear: \"絞り込みを解除\",\n },\n};\n"],"mappings":";AAEA,IAAa,IAAuB;CAClC,gBAAgB;EACd,aAAa;EACb,mBAAmB;EACnB,mBAAmB;EACnB,qBAAqB;EACrB,OAAO;EACP,aAAa;EACb,SAAS;CACX;CACA,UAAU;EACR,iBAAiB;EACjB,mBAAmB;EACnB,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,eAAe;EACf,eAAe;CACjB;CACA,UAAU;EACR,UAAU;EACV,eAAe;EACf,SAAS;EACT,UAAU;EACV,SAAS;EACT,QAAQ;EACR,WAAW;EACX,aAAa;EACb,aAAa;EACb,eAAe;EACf,WAAW;EACX,UAAU;EACV,WAAW;EACX,OAAO;EACP,OAAO;EACP,SAAS;EACT,UAAU;EACV,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,WAAW;EACX,kBAAkB;EAClB,cAAc;EACd,cAAc;EACd,mBAAmB;EACnB,QAAQ;EACR,mBAAmB;EACnB,aAAa;EACb,aAAa;EACb,kBAAkB;EAClB,OAAO;EACP,QAAQ;EACR,YAAY;EACZ,WAAW;EACX,gBAAgB;EAChB,SAAS;EACT,WAAW;EACX,aAAa;EACb,UAAU;EACV,YAAY;EACZ,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,aAAa;EACb,gBAAgB;EAChB,cAAc;CAChB;CACA,SAAS;EACP,eAAe;EACf,eAAe;EACf,cAAc;EACd,gBAAgB;EAChB,MAAM;EACN,aAAa;EACb,aAAa;EACb,YAAY;EACZ,cAAc;EACd,gBAAgB;EAChB,qBAAqB;EACrB,kBAAkB;EAClB,aAAa;EACb,eAAe;EACf,WAAW;EACX,YAAY;EACZ,YAAY;EACZ,aAAa;EACb,YAAY;EACZ,YAAY;EACZ,UAAU;EACV,aAAa;EACb,KAAK;EACL,SAAS;EACT,OAAO;CACT;AACF"}
@@ -67,6 +67,7 @@ var e = {
67
67
  removeRecent: "“{q}” 삭제"
68
68
  },
69
69
  listing: {
70
+ activityRange: "{from}부터 {until} 전까지의 활동 (UTC)",
70
71
  popularPeriod: "인기 집계 기간",
71
72
  pastDays_one: "최근 {count}일",
72
73
  pastDays_other: "최근 {count}일",
@@ -1 +1 @@
1
- {"version":3,"file":"ko.js","names":[],"sources":["../../../src/locales/discovery/ko.ts"],"sourcesContent":["import type { discovery as en } from \"./en.js\";\n\nexport const discovery: typeof en = {\n readerSettings: {\n filterTitle: \"콘텐츠 필터\",\n filterDescription: \"표시할 콘텐츠를 선택하세요.\",\n savingPreferences: \"환경설정을 저장하는 중…\",\n preferencesNotSaved: \"환경설정이 아직 저장되지 않았습니다.\",\n title: \"열람 설정\",\n description: \"언어와 표시할 콘텐츠를 선택하세요.\",\n filters: \"표시할 콘텐츠:\",\n },\n releases: {\n premiumMore_one: \"{count}개 더 보기\",\n premiumMore_other: \"{count}개 더 보기\",\n premiumHint: \"회원 전용 미리보기 · 클릭하여 보기\",\n filteredMore_one: \"{count}개 필터링됨\",\n filteredMore_other: \"{count}개 필터링됨\",\n manageFilters: \"콘텐츠 필터 변경\",\n filterContext: \"{date}의 필터입니다. 하나의 콘텐츠가 여러 필터에 해당할 수 있습니다.\",\n },\n contents: {\n showMore: \"더 보기\",\n unknownAccess: \"지금은 이용할 수 없음\",\n members: \"멤버 전용\",\n joinFree: \"무료 가입\",\n forSale: \"판매 중\",\n locked: \"잠김\",\n pages_one: \"{count}쪽\",\n pages_other: \"{count}쪽\",\n minutes_one: \"{count}분\",\n minutes_other: \"{count}분\",\n completed: \"완료\",\n freeFrom: \"{date}부터 무료\",\n favorites: \"즐겨찾기\",\n likes: \"좋아요\",\n empty: \"아직 아무것도 없습니다.\",\n loading: \"불러오는 중…\",\n loadMore: \"더 불러오기\",\n lockedShow_one: \"잠긴 항목 {count}개 보기\",\n lockedShow_other: \"잠긴 항목 {count}개 보기\",\n lockedHide: \"잠긴 항목 숨기기\",\n noResults: \"“{q}”와(과) 일치하는 항목이 없습니다.\",\n historySignedOut: \"기록을 보려면 로그인하세요.\",\n clearHistory: \"기록 지우기\",\n historyEmpty: \"기록이 없습니다.\",\n removeFromHistory: \"기록에서 삭제\",\n search: \"검색\",\n searchPlaceholder: \"검색…\",\n clearSearch: \"검색 지우기\",\n suggestions: \"추천 검색어\",\n filtersSignedOut: \"볼 콘텐츠를 선택하려면 로그인하세요.\",\n shown: \"표시\",\n hidden: \"숨김\",\n useDefault: \"기본값 사용\",\n noFilters: \"이 사이트에는 콘텐츠 필터가 없습니다.\",\n includeDeleted: \"구매한 삭제된 콘텐츠 표시\",\n noDates: \"공개일이 없습니다.\",\n items_one: \"{count}개\",\n items_other: \"{count}개\",\n free_one: \"무료 {count}개\",\n free_other: \"무료 {count}개\",\n recentSearches: \"최근 검색\",\n noRecentSearches: \"최근 검색이 아직 없습니다.\",\n searchHint: \"검색어를 입력하세요.\",\n clearRecent: \"지우기\",\n clearAllRecent: \"모두 지우기\",\n removeRecent: \"“{q}” 삭제\",\n },\n listing: {\n popularPeriod: \"인기 집계 기간\",\n pastDays_one: \"최근 {count}일\",\n pastDays_other: \"최근 {count}일\",\n sort: \"정렬\",\n sort_newest: \"최신순\",\n sort_oldest: \"오래된순\",\n sort_title: \"제목\",\n sort_popular: \"인기\",\n sort_top_rated: \"높은 평점\",\n sort_most_favorited: \"즐겨찾기순\",\n sort_most_viewed: \"조회수순\",\n sort_random: \"무작위\",\n sort_position: \"순서\",\n period_7d: \"이번 주\",\n period_30d: \"이번 달\",\n period_90d: \"최근 3개월\",\n period_365d: \"올해\",\n period_all: \"전체 기간\",\n sortPeriod: \"{sort} ({period})\",\n language: \"언어\",\n anyLanguage: \"모든 언어\",\n any: \"전체\",\n filters: \"필터\",\n clear: \"필터 지우기\",\n },\n};\n"],"mappings":";AAEA,IAAa,IAAuB;CAClC,gBAAgB;EACd,aAAa;EACb,mBAAmB;EACnB,mBAAmB;EACnB,qBAAqB;EACrB,OAAO;EACP,aAAa;EACb,SAAS;CACX;CACA,UAAU;EACR,iBAAiB;EACjB,mBAAmB;EACnB,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,eAAe;EACf,eAAe;CACjB;CACA,UAAU;EACR,UAAU;EACV,eAAe;EACf,SAAS;EACT,UAAU;EACV,SAAS;EACT,QAAQ;EACR,WAAW;EACX,aAAa;EACb,aAAa;EACb,eAAe;EACf,WAAW;EACX,UAAU;EACV,WAAW;EACX,OAAO;EACP,OAAO;EACP,SAAS;EACT,UAAU;EACV,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,WAAW;EACX,kBAAkB;EAClB,cAAc;EACd,cAAc;EACd,mBAAmB;EACnB,QAAQ;EACR,mBAAmB;EACnB,aAAa;EACb,aAAa;EACb,kBAAkB;EAClB,OAAO;EACP,QAAQ;EACR,YAAY;EACZ,WAAW;EACX,gBAAgB;EAChB,SAAS;EACT,WAAW;EACX,aAAa;EACb,UAAU;EACV,YAAY;EACZ,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,aAAa;EACb,gBAAgB;EAChB,cAAc;CAChB;CACA,SAAS;EACP,eAAe;EACf,cAAc;EACd,gBAAgB;EAChB,MAAM;EACN,aAAa;EACb,aAAa;EACb,YAAY;EACZ,cAAc;EACd,gBAAgB;EAChB,qBAAqB;EACrB,kBAAkB;EAClB,aAAa;EACb,eAAe;EACf,WAAW;EACX,YAAY;EACZ,YAAY;EACZ,aAAa;EACb,YAAY;EACZ,YAAY;EACZ,UAAU;EACV,aAAa;EACb,KAAK;EACL,SAAS;EACT,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"ko.js","names":[],"sources":["../../../src/locales/discovery/ko.ts"],"sourcesContent":["import type { discovery as en } from \"./en.js\";\n\nexport const discovery: typeof en = {\n readerSettings: {\n filterTitle: \"콘텐츠 필터\",\n filterDescription: \"표시할 콘텐츠를 선택하세요.\",\n savingPreferences: \"환경설정을 저장하는 중…\",\n preferencesNotSaved: \"환경설정이 아직 저장되지 않았습니다.\",\n title: \"열람 설정\",\n description: \"언어와 표시할 콘텐츠를 선택하세요.\",\n filters: \"표시할 콘텐츠:\",\n },\n releases: {\n premiumMore_one: \"{count}개 더 보기\",\n premiumMore_other: \"{count}개 더 보기\",\n premiumHint: \"회원 전용 미리보기 · 클릭하여 보기\",\n filteredMore_one: \"{count}개 필터링됨\",\n filteredMore_other: \"{count}개 필터링됨\",\n manageFilters: \"콘텐츠 필터 변경\",\n filterContext: \"{date}의 필터입니다. 하나의 콘텐츠가 여러 필터에 해당할 수 있습니다.\",\n },\n contents: {\n showMore: \"더 보기\",\n unknownAccess: \"지금은 이용할 수 없음\",\n members: \"멤버 전용\",\n joinFree: \"무료 가입\",\n forSale: \"판매 중\",\n locked: \"잠김\",\n pages_one: \"{count}쪽\",\n pages_other: \"{count}쪽\",\n minutes_one: \"{count}분\",\n minutes_other: \"{count}분\",\n completed: \"완료\",\n freeFrom: \"{date}부터 무료\",\n favorites: \"즐겨찾기\",\n likes: \"좋아요\",\n empty: \"아직 아무것도 없습니다.\",\n loading: \"불러오는 중…\",\n loadMore: \"더 불러오기\",\n lockedShow_one: \"잠긴 항목 {count}개 보기\",\n lockedShow_other: \"잠긴 항목 {count}개 보기\",\n lockedHide: \"잠긴 항목 숨기기\",\n noResults: \"“{q}”와(과) 일치하는 항목이 없습니다.\",\n historySignedOut: \"기록을 보려면 로그인하세요.\",\n clearHistory: \"기록 지우기\",\n historyEmpty: \"기록이 없습니다.\",\n removeFromHistory: \"기록에서 삭제\",\n search: \"검색\",\n searchPlaceholder: \"검색…\",\n clearSearch: \"검색 지우기\",\n suggestions: \"추천 검색어\",\n filtersSignedOut: \"볼 콘텐츠를 선택하려면 로그인하세요.\",\n shown: \"표시\",\n hidden: \"숨김\",\n useDefault: \"기본값 사용\",\n noFilters: \"이 사이트에는 콘텐츠 필터가 없습니다.\",\n includeDeleted: \"구매한 삭제된 콘텐츠 표시\",\n noDates: \"공개일이 없습니다.\",\n items_one: \"{count}개\",\n items_other: \"{count}개\",\n free_one: \"무료 {count}개\",\n free_other: \"무료 {count}개\",\n recentSearches: \"최근 검색\",\n noRecentSearches: \"최근 검색이 아직 없습니다.\",\n searchHint: \"검색어를 입력하세요.\",\n clearRecent: \"지우기\",\n clearAllRecent: \"모두 지우기\",\n removeRecent: \"“{q}” 삭제\",\n },\n listing: {\n activityRange: \"{from}부터 {until} 전까지의 활동 (UTC)\",\n popularPeriod: \"인기 집계 기간\",\n pastDays_one: \"최근 {count}일\",\n pastDays_other: \"최근 {count}일\",\n sort: \"정렬\",\n sort_newest: \"최신순\",\n sort_oldest: \"오래된순\",\n sort_title: \"제목\",\n sort_popular: \"인기\",\n sort_top_rated: \"높은 평점\",\n sort_most_favorited: \"즐겨찾기순\",\n sort_most_viewed: \"조회수순\",\n sort_random: \"무작위\",\n sort_position: \"순서\",\n period_7d: \"이번 주\",\n period_30d: \"이번 달\",\n period_90d: \"최근 3개월\",\n period_365d: \"올해\",\n period_all: \"전체 기간\",\n sortPeriod: \"{sort} ({period})\",\n language: \"언어\",\n anyLanguage: \"모든 언어\",\n any: \"전체\",\n filters: \"필터\",\n clear: \"필터 지우기\",\n },\n};\n"],"mappings":";AAEA,IAAa,IAAuB;CAClC,gBAAgB;EACd,aAAa;EACb,mBAAmB;EACnB,mBAAmB;EACnB,qBAAqB;EACrB,OAAO;EACP,aAAa;EACb,SAAS;CACX;CACA,UAAU;EACR,iBAAiB;EACjB,mBAAmB;EACnB,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,eAAe;EACf,eAAe;CACjB;CACA,UAAU;EACR,UAAU;EACV,eAAe;EACf,SAAS;EACT,UAAU;EACV,SAAS;EACT,QAAQ;EACR,WAAW;EACX,aAAa;EACb,aAAa;EACb,eAAe;EACf,WAAW;EACX,UAAU;EACV,WAAW;EACX,OAAO;EACP,OAAO;EACP,SAAS;EACT,UAAU;EACV,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,WAAW;EACX,kBAAkB;EAClB,cAAc;EACd,cAAc;EACd,mBAAmB;EACnB,QAAQ;EACR,mBAAmB;EACnB,aAAa;EACb,aAAa;EACb,kBAAkB;EAClB,OAAO;EACP,QAAQ;EACR,YAAY;EACZ,WAAW;EACX,gBAAgB;EAChB,SAAS;EACT,WAAW;EACX,aAAa;EACb,UAAU;EACV,YAAY;EACZ,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,aAAa;EACb,gBAAgB;EAChB,cAAc;CAChB;CACA,SAAS;EACP,eAAe;EACf,eAAe;EACf,cAAc;EACd,gBAAgB;EAChB,MAAM;EACN,aAAa;EACb,aAAa;EACb,YAAY;EACZ,cAAc;EACd,gBAAgB;EAChB,qBAAqB;EACrB,kBAAkB;EAClB,aAAa;EACb,eAAe;EACf,WAAW;EACX,YAAY;EACZ,YAAY;EACZ,aAAa;EACb,YAAY;EACZ,YAAY;EACZ,UAAU;EACV,aAAa;EACb,KAAK;EACL,SAAS;EACT,OAAO;CACT;AACF"}
@@ -67,6 +67,7 @@ var e = {
67
67
  removeRecent: "移除“{q}”"
68
68
  },
69
69
  listing: {
70
+ activityRange: "UTC 时间 {from} 起至 {until} 前的活动",
70
71
  popularPeriod: "热门时间范围",
71
72
  pastDays_one: "过去{count}天",
72
73
  pastDays_other: "过去{count}天",
@@ -1 +1 @@
1
- {"version":3,"file":"zh.js","names":[],"sources":["../../../src/locales/discovery/zh.ts"],"sourcesContent":["import type { discovery as en } from \"./en.js\";\n\nexport const discovery: typeof en = {\n readerSettings: {\n filterTitle: \"内容筛选\",\n filterDescription: \"选择你想看到的内容。\",\n savingPreferences: \"正在保存偏好设置…\",\n preferencesNotSaved: \"偏好设置尚未保存。\",\n title: \"阅读设置\",\n description: \"选择语言和要显示的内容。\",\n filters: \"显示内容:\",\n },\n releases: {\n premiumMore_one: \"还有 {count} 项\",\n premiumMore_other: \"还有 {count} 项\",\n premiumHint: \"会员专属预览 · 点击查看\",\n filteredMore_one: \"已筛除 {count} 项\",\n filteredMore_other: \"已筛除 {count} 项\",\n manageFilters: \"更改内容筛选\",\n filterContext: \"{date}的筛选结果。一项内容可能符合多个筛选条件。\",\n },\n contents: {\n showMore: \"显示更多\",\n unknownAccess: \"暂时无法访问\",\n members: \"会员专享\",\n joinFree: \"免费加入\",\n forSale: \"可购买\",\n locked: \"已锁定\",\n pages_one: \"{count} 页\",\n pages_other: \"{count} 页\",\n minutes_one: \"{count} 分钟\",\n minutes_other: \"{count} 分钟\",\n completed: \"已完成\",\n freeFrom: \"{date} 起免费\",\n favorites: \"收藏\",\n likes: \"点赞\",\n empty: \"这里还没有内容。\",\n loading: \"加载中…\",\n loadMore: \"加载更多\",\n lockedShow_one: \"显示 {count} 个锁定项目\",\n lockedShow_other: \"显示 {count} 个锁定项目\",\n lockedHide: \"隐藏锁定项目\",\n noResults: \"没有与“{q}”匹配的内容。\",\n historySignedOut: \"登录后查看你的历史记录。\",\n clearHistory: \"清除历史记录\",\n historyEmpty: \"你的历史记录为空。\",\n removeFromHistory: \"从历史记录中移除\",\n search: \"搜索\",\n searchPlaceholder: \"搜索…\",\n clearSearch: \"清除搜索\",\n suggestions: \"建议\",\n filtersSignedOut: \"登录后选择你想看的内容。\",\n shown: \"显示\",\n hidden: \"隐藏\",\n useDefault: \"使用默认设置\",\n noFilters: \"此站点没有内容过滤器。\",\n includeDeleted: \"显示我已购买但已移除的内容\",\n noDates: \"没有发布日期。\",\n items_one: \"{count} 项\",\n items_other: \"{count} 项\",\n free_one: \"{count} 项免费\",\n free_other: \"{count} 项免费\",\n recentSearches: \"最近搜索\",\n noRecentSearches: \"还没有最近搜索。\",\n searchHint: \"输入关键词开始搜索。\",\n clearRecent: \"清除\",\n clearAllRecent: \"全部清除\",\n removeRecent: \"移除“{q}”\",\n },\n listing: {\n popularPeriod: \"热门时间范围\",\n pastDays_one: \"过去{count}天\",\n pastDays_other: \"过去{count}天\",\n sort: \"排序\",\n sort_newest: \"最新\",\n sort_oldest: \"最早\",\n sort_title: \"标题\",\n sort_popular: \"热门\",\n sort_top_rated: \"高分\",\n sort_most_favorited: \"最多收藏\",\n sort_most_viewed: \"最多观看\",\n sort_random: \"随机\",\n sort_position: \"顺序\",\n period_7d: \"本周\",\n period_30d: \"本月\",\n period_90d: \"近3个月\",\n period_365d: \"今年\",\n period_all: \"全部时间\",\n sortPeriod: \"{sort}({period})\",\n language: \"语言\",\n anyLanguage: \"所有语言\",\n any: \"全部\",\n filters: \"筛选\",\n clear: \"清除筛选\",\n },\n};\n"],"mappings":";AAEA,IAAa,IAAuB;CAClC,gBAAgB;EACd,aAAa;EACb,mBAAmB;EACnB,mBAAmB;EACnB,qBAAqB;EACrB,OAAO;EACP,aAAa;EACb,SAAS;CACX;CACA,UAAU;EACR,iBAAiB;EACjB,mBAAmB;EACnB,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,eAAe;EACf,eAAe;CACjB;CACA,UAAU;EACR,UAAU;EACV,eAAe;EACf,SAAS;EACT,UAAU;EACV,SAAS;EACT,QAAQ;EACR,WAAW;EACX,aAAa;EACb,aAAa;EACb,eAAe;EACf,WAAW;EACX,UAAU;EACV,WAAW;EACX,OAAO;EACP,OAAO;EACP,SAAS;EACT,UAAU;EACV,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,WAAW;EACX,kBAAkB;EAClB,cAAc;EACd,cAAc;EACd,mBAAmB;EACnB,QAAQ;EACR,mBAAmB;EACnB,aAAa;EACb,aAAa;EACb,kBAAkB;EAClB,OAAO;EACP,QAAQ;EACR,YAAY;EACZ,WAAW;EACX,gBAAgB;EAChB,SAAS;EACT,WAAW;EACX,aAAa;EACb,UAAU;EACV,YAAY;EACZ,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,aAAa;EACb,gBAAgB;EAChB,cAAc;CAChB;CACA,SAAS;EACP,eAAe;EACf,cAAc;EACd,gBAAgB;EAChB,MAAM;EACN,aAAa;EACb,aAAa;EACb,YAAY;EACZ,cAAc;EACd,gBAAgB;EAChB,qBAAqB;EACrB,kBAAkB;EAClB,aAAa;EACb,eAAe;EACf,WAAW;EACX,YAAY;EACZ,YAAY;EACZ,aAAa;EACb,YAAY;EACZ,YAAY;EACZ,UAAU;EACV,aAAa;EACb,KAAK;EACL,SAAS;EACT,OAAO;CACT;AACF"}
1
+ {"version":3,"file":"zh.js","names":[],"sources":["../../../src/locales/discovery/zh.ts"],"sourcesContent":["import type { discovery as en } from \"./en.js\";\n\nexport const discovery: typeof en = {\n readerSettings: {\n filterTitle: \"内容筛选\",\n filterDescription: \"选择你想看到的内容。\",\n savingPreferences: \"正在保存偏好设置…\",\n preferencesNotSaved: \"偏好设置尚未保存。\",\n title: \"阅读设置\",\n description: \"选择语言和要显示的内容。\",\n filters: \"显示内容:\",\n },\n releases: {\n premiumMore_one: \"还有 {count} 项\",\n premiumMore_other: \"还有 {count} 项\",\n premiumHint: \"会员专属预览 · 点击查看\",\n filteredMore_one: \"已筛除 {count} 项\",\n filteredMore_other: \"已筛除 {count} 项\",\n manageFilters: \"更改内容筛选\",\n filterContext: \"{date}的筛选结果。一项内容可能符合多个筛选条件。\",\n },\n contents: {\n showMore: \"显示更多\",\n unknownAccess: \"暂时无法访问\",\n members: \"会员专享\",\n joinFree: \"免费加入\",\n forSale: \"可购买\",\n locked: \"已锁定\",\n pages_one: \"{count} 页\",\n pages_other: \"{count} 页\",\n minutes_one: \"{count} 分钟\",\n minutes_other: \"{count} 分钟\",\n completed: \"已完成\",\n freeFrom: \"{date} 起免费\",\n favorites: \"收藏\",\n likes: \"点赞\",\n empty: \"这里还没有内容。\",\n loading: \"加载中…\",\n loadMore: \"加载更多\",\n lockedShow_one: \"显示 {count} 个锁定项目\",\n lockedShow_other: \"显示 {count} 个锁定项目\",\n lockedHide: \"隐藏锁定项目\",\n noResults: \"没有与“{q}”匹配的内容。\",\n historySignedOut: \"登录后查看你的历史记录。\",\n clearHistory: \"清除历史记录\",\n historyEmpty: \"你的历史记录为空。\",\n removeFromHistory: \"从历史记录中移除\",\n search: \"搜索\",\n searchPlaceholder: \"搜索…\",\n clearSearch: \"清除搜索\",\n suggestions: \"建议\",\n filtersSignedOut: \"登录后选择你想看的内容。\",\n shown: \"显示\",\n hidden: \"隐藏\",\n useDefault: \"使用默认设置\",\n noFilters: \"此站点没有内容过滤器。\",\n includeDeleted: \"显示我已购买但已移除的内容\",\n noDates: \"没有发布日期。\",\n items_one: \"{count} 项\",\n items_other: \"{count} 项\",\n free_one: \"{count} 项免费\",\n free_other: \"{count} 项免费\",\n recentSearches: \"最近搜索\",\n noRecentSearches: \"还没有最近搜索。\",\n searchHint: \"输入关键词开始搜索。\",\n clearRecent: \"清除\",\n clearAllRecent: \"全部清除\",\n removeRecent: \"移除“{q}”\",\n },\n listing: {\n activityRange: \"UTC 时间 {from} 起至 {until} 前的活动\",\n popularPeriod: \"热门时间范围\",\n pastDays_one: \"过去{count}天\",\n pastDays_other: \"过去{count}天\",\n sort: \"排序\",\n sort_newest: \"最新\",\n sort_oldest: \"最早\",\n sort_title: \"标题\",\n sort_popular: \"热门\",\n sort_top_rated: \"高分\",\n sort_most_favorited: \"最多收藏\",\n sort_most_viewed: \"最多观看\",\n sort_random: \"随机\",\n sort_position: \"顺序\",\n period_7d: \"本周\",\n period_30d: \"本月\",\n period_90d: \"近3个月\",\n period_365d: \"今年\",\n period_all: \"全部时间\",\n sortPeriod: \"{sort}({period})\",\n language: \"语言\",\n anyLanguage: \"所有语言\",\n any: \"全部\",\n filters: \"筛选\",\n clear: \"清除筛选\",\n },\n};\n"],"mappings":";AAEA,IAAa,IAAuB;CAClC,gBAAgB;EACd,aAAa;EACb,mBAAmB;EACnB,mBAAmB;EACnB,qBAAqB;EACrB,OAAO;EACP,aAAa;EACb,SAAS;CACX;CACA,UAAU;EACR,iBAAiB;EACjB,mBAAmB;EACnB,aAAa;EACb,kBAAkB;EAClB,oBAAoB;EACpB,eAAe;EACf,eAAe;CACjB;CACA,UAAU;EACR,UAAU;EACV,eAAe;EACf,SAAS;EACT,UAAU;EACV,SAAS;EACT,QAAQ;EACR,WAAW;EACX,aAAa;EACb,aAAa;EACb,eAAe;EACf,WAAW;EACX,UAAU;EACV,WAAW;EACX,OAAO;EACP,OAAO;EACP,SAAS;EACT,UAAU;EACV,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,WAAW;EACX,kBAAkB;EAClB,cAAc;EACd,cAAc;EACd,mBAAmB;EACnB,QAAQ;EACR,mBAAmB;EACnB,aAAa;EACb,aAAa;EACb,kBAAkB;EAClB,OAAO;EACP,QAAQ;EACR,YAAY;EACZ,WAAW;EACX,gBAAgB;EAChB,SAAS;EACT,WAAW;EACX,aAAa;EACb,UAAU;EACV,YAAY;EACZ,gBAAgB;EAChB,kBAAkB;EAClB,YAAY;EACZ,aAAa;EACb,gBAAgB;EAChB,cAAc;CAChB;CACA,SAAS;EACP,eAAe;EACf,eAAe;EACf,cAAc;EACd,gBAAgB;EAChB,MAAM;EACN,aAAa;EACb,aAAa;EACb,YAAY;EACZ,cAAc;EACd,gBAAgB;EAChB,qBAAqB;EACrB,kBAAkB;EAClB,aAAa;EACb,eAAe;EACf,WAAW;EACX,YAAY;EACZ,YAAY;EACZ,aAAa;EACb,YAAY;EACZ,YAAY;EACZ,UAAU;EACV,aAAa;EACb,KAAK;EACL,SAAS;EACT,OAAO;CACT;AACF"}
@@ -455,6 +455,7 @@ export declare const en: {
455
455
  };
456
456
  listing: {
457
457
  popularPeriod: string;
458
+ activityRange: string;
458
459
  pastDays_one: string;
459
460
  pastDays_other: string;
460
461
  sort: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openrails/contentkit-ui",
3
- "version": "0.100.0",
3
+ "version": "0.101.0",
4
4
  "description": "ContentKit in the browser: client, React hooks and styled components for media, uploads and content URLs.",
5
5
  "type": "module",
6
6
  "license": "MIT",