@scalemule/news-publication 0.0.34 → 0.0.36

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.
@@ -0,0 +1,155 @@
1
+ "use client";
2
+ 'use strict';
3
+
4
+ var react = require('react');
5
+ var communityMaps = require('@scalemule/react/community-maps');
6
+ var jsxRuntime = require('react/jsx-runtime');
7
+
8
+ // src/community-maps.ts
9
+ function communityMapEmbeds(metadata) {
10
+ if (!metadata || typeof metadata !== "object") return [];
11
+ const value = metadata.community_maps;
12
+ if (!Array.isArray(value)) return [];
13
+ return value.slice(0, 5).flatMap((entry) => {
14
+ if (!entry || typeof entry !== "object" || typeof entry.collection_slug !== "string" || !/^[a-z0-9-]{1,191}$/.test(entry.collection_slug) || !["map", "cards", "features"].includes(entry.mode))
15
+ return [];
16
+ const ids = Array.isArray(entry.feature_ids) ? entry.feature_ids.filter(
17
+ (id) => typeof id === "string" && /^[0-9a-f-]{36}$/i.test(id)
18
+ ).slice(0, 20) : void 0;
19
+ return [
20
+ {
21
+ collection_slug: entry.collection_slug,
22
+ mode: entry.mode,
23
+ feature_ids: ids,
24
+ area_id: typeof entry.area_id === "string" && /^[0-9a-f-]{36}$/i.test(entry.area_id) ? entry.area_id : void 0
25
+ }
26
+ ];
27
+ });
28
+ }
29
+ function PublicationCommunityMapPage({
30
+ collection,
31
+ feature,
32
+ mode = "guide",
33
+ areaId,
34
+ correctionFor,
35
+ basePath,
36
+ apiPath
37
+ }) {
38
+ const client = react.useMemo(
39
+ () => communityMaps.createCommunityMapsBrowserClient(apiPath),
40
+ [apiPath]
41
+ );
42
+ const featureHref = (f) => `${basePath}/places/${f.id}`;
43
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "smcm", children: [
44
+ mode !== "guide" && /* @__PURE__ */ jsxRuntime.jsx("p", { children: /* @__PURE__ */ jsxRuntime.jsxs("a", { href: basePath, children: [
45
+ "\u2190 ",
46
+ collection.config.title
47
+ ] }) }),
48
+ mode === "submit" ? /* @__PURE__ */ jsxRuntime.jsx(
49
+ communityMaps.CommunitySubmissionForm,
50
+ {
51
+ client,
52
+ collection,
53
+ initialAreaId: areaId,
54
+ correctionFor
55
+ }
56
+ ) : mode === "feature" && feature ? /* @__PURE__ */ jsxRuntime.jsx(
57
+ communityMaps.CommunityFeatureDetail,
58
+ {
59
+ client,
60
+ collection,
61
+ feature,
62
+ correctionHref: `${basePath}/submit?correction=${feature.id}&area=${feature.area_id}`
63
+ }
64
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
65
+ communityMaps.CommunityGuide,
66
+ {
67
+ client,
68
+ collection,
69
+ featureHref,
70
+ communityHref: (a) => `${basePath}/map?area=${a.id}`,
71
+ submitHref: `${basePath}/submit${areaId ? `?area=${areaId}` : ""}`,
72
+ initialAreaId: areaId,
73
+ showMap: mode === "map"
74
+ }
75
+ )
76
+ ] });
77
+ }
78
+ function CommunityMapArticleEmbeds({
79
+ metadata,
80
+ apiPath = "/api/community-maps"
81
+ }) {
82
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: communityMapEmbeds(metadata).map((embed, index) => /* @__PURE__ */ jsxRuntime.jsx(
83
+ ArticleMap,
84
+ {
85
+ embed,
86
+ apiPath
87
+ },
88
+ `${embed.collection_slug}-${index}`
89
+ )) });
90
+ }
91
+ function ArticleMap({
92
+ embed,
93
+ apiPath
94
+ }) {
95
+ const client = react.useMemo(
96
+ () => communityMaps.createCommunityMapsBrowserClient(apiPath),
97
+ [apiPath]
98
+ );
99
+ const [data, setData] = react.useState(null);
100
+ const ids = embed.feature_ids?.join(",");
101
+ react.useEffect(() => {
102
+ const controller = new AbortController();
103
+ setData(null);
104
+ async function load() {
105
+ const collection = await client.collection(
106
+ embed.collection_slug,
107
+ controller.signal
108
+ );
109
+ const features = ids ? await Promise.all(
110
+ ids.split(",").map(
111
+ (id) => client.feature(embed.collection_slug, id, controller.signal)
112
+ )
113
+ ) : (await client.features(
114
+ embed.collection_slug,
115
+ { area_id: embed.area_id, limit: 20 },
116
+ controller.signal
117
+ )).items;
118
+ if (!controller.signal.aborted) setData({ collection, features });
119
+ }
120
+ void load().catch(() => setData(null));
121
+ return () => controller.abort();
122
+ }, [client, embed.collection_slug, embed.area_id, ids]);
123
+ if (!data) return null;
124
+ const path = `/community-maps/${data.collection.slug}`;
125
+ return /* @__PURE__ */ jsxRuntime.jsxs("aside", { className: "smcm", "aria-label": data.collection.config.title, children: [
126
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: path, children: data.collection.config.title }) }),
127
+ embed.mode === "cards" ? /* @__PURE__ */ jsxRuntime.jsx(
128
+ communityMaps.CommunityCards,
129
+ {
130
+ areas: data.collection.areas,
131
+ href: (a) => `${path}/map?area=${a.id}`
132
+ }
133
+ ) : embed.mode === "map" ? /* @__PURE__ */ jsxRuntime.jsx(
134
+ communityMaps.CommunityMap,
135
+ {
136
+ features: data.features,
137
+ areas: data.collection.areas,
138
+ styleUrl: data.collection.config.presentation.map_style_url
139
+ }
140
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "smcm-feature-grid", children: data.features.map((f) => /* @__PURE__ */ jsxRuntime.jsx(
141
+ communityMaps.CommunityFeatureCard,
142
+ {
143
+ feature: f,
144
+ href: `${path}/places/${f.id}`,
145
+ photoUrl: f.media[0] ? client.mediaUrl(data.collection.slug, f.media[0].id) : void 0
146
+ },
147
+ f.id
148
+ )) }),
149
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: `${path}/map`, children: "Explore the full map \u2197" }) })
150
+ ] });
151
+ }
152
+
153
+ exports.CommunityMapArticleEmbeds = CommunityMapArticleEmbeds;
154
+ exports.PublicationCommunityMapPage = PublicationCommunityMapPage;
155
+ exports.communityMapEmbeds = communityMapEmbeds;
@@ -0,0 +1,22 @@
1
+ import * as react from 'react';
2
+ import { CommunityMapCollection, CommunityMapFeature } from '@scalemule/react/community-maps';
3
+ export { c as communityMapEmbeds } from './community-maps-DKcYhQYN.cjs';
4
+
5
+ interface PublicationCommunityMapPageProps {
6
+ collection: CommunityMapCollection;
7
+ feature?: CommunityMapFeature;
8
+ mode?: "guide" | "map" | "submit" | "feature";
9
+ areaId?: string;
10
+ correctionFor?: string;
11
+ basePath: string;
12
+ apiPath?: string;
13
+ }
14
+ /** The newspaper supplies its chrome and inherited type. The platform owns map behavior. */
15
+ declare function PublicationCommunityMapPage({ collection, feature, mode, areaId, correctionFor, basePath, apiPath, }: PublicationCommunityMapPageProps): react.JSX.Element;
16
+
17
+ declare function CommunityMapArticleEmbeds({ metadata, apiPath, }: {
18
+ metadata: unknown;
19
+ apiPath?: string;
20
+ }): react.JSX.Element;
21
+
22
+ export { CommunityMapArticleEmbeds, PublicationCommunityMapPage, type PublicationCommunityMapPageProps };
@@ -0,0 +1,22 @@
1
+ import * as react from 'react';
2
+ import { CommunityMapCollection, CommunityMapFeature } from '@scalemule/react/community-maps';
3
+ export { c as communityMapEmbeds } from './community-maps-DKcYhQYN.js';
4
+
5
+ interface PublicationCommunityMapPageProps {
6
+ collection: CommunityMapCollection;
7
+ feature?: CommunityMapFeature;
8
+ mode?: "guide" | "map" | "submit" | "feature";
9
+ areaId?: string;
10
+ correctionFor?: string;
11
+ basePath: string;
12
+ apiPath?: string;
13
+ }
14
+ /** The newspaper supplies its chrome and inherited type. The platform owns map behavior. */
15
+ declare function PublicationCommunityMapPage({ collection, feature, mode, areaId, correctionFor, basePath, apiPath, }: PublicationCommunityMapPageProps): react.JSX.Element;
16
+
17
+ declare function CommunityMapArticleEmbeds({ metadata, apiPath, }: {
18
+ metadata: unknown;
19
+ apiPath?: string;
20
+ }): react.JSX.Element;
21
+
22
+ export { CommunityMapArticleEmbeds, PublicationCommunityMapPage, type PublicationCommunityMapPageProps };
@@ -0,0 +1,132 @@
1
+ "use client";
2
+ import { communityMapEmbeds } from './chunk-IMYBSG7J.js';
3
+ export { communityMapEmbeds } from './chunk-IMYBSG7J.js';
4
+ import { useMemo, useState, useEffect } from 'react';
5
+ import { createCommunityMapsBrowserClient, CommunitySubmissionForm, CommunityFeatureDetail, CommunityGuide, CommunityCards, CommunityMap, CommunityFeatureCard } from '@scalemule/react/community-maps';
6
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
7
+
8
+ function PublicationCommunityMapPage({
9
+ collection,
10
+ feature,
11
+ mode = "guide",
12
+ areaId,
13
+ correctionFor,
14
+ basePath,
15
+ apiPath
16
+ }) {
17
+ const client = useMemo(
18
+ () => createCommunityMapsBrowserClient(apiPath),
19
+ [apiPath]
20
+ );
21
+ const featureHref = (f) => `${basePath}/places/${f.id}`;
22
+ return /* @__PURE__ */ jsxs("div", { className: "smcm", children: [
23
+ mode !== "guide" && /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsxs("a", { href: basePath, children: [
24
+ "\u2190 ",
25
+ collection.config.title
26
+ ] }) }),
27
+ mode === "submit" ? /* @__PURE__ */ jsx(
28
+ CommunitySubmissionForm,
29
+ {
30
+ client,
31
+ collection,
32
+ initialAreaId: areaId,
33
+ correctionFor
34
+ }
35
+ ) : mode === "feature" && feature ? /* @__PURE__ */ jsx(
36
+ CommunityFeatureDetail,
37
+ {
38
+ client,
39
+ collection,
40
+ feature,
41
+ correctionHref: `${basePath}/submit?correction=${feature.id}&area=${feature.area_id}`
42
+ }
43
+ ) : /* @__PURE__ */ jsx(
44
+ CommunityGuide,
45
+ {
46
+ client,
47
+ collection,
48
+ featureHref,
49
+ communityHref: (a) => `${basePath}/map?area=${a.id}`,
50
+ submitHref: `${basePath}/submit${areaId ? `?area=${areaId}` : ""}`,
51
+ initialAreaId: areaId,
52
+ showMap: mode === "map"
53
+ }
54
+ )
55
+ ] });
56
+ }
57
+ function CommunityMapArticleEmbeds({
58
+ metadata,
59
+ apiPath = "/api/community-maps"
60
+ }) {
61
+ return /* @__PURE__ */ jsx(Fragment, { children: communityMapEmbeds(metadata).map((embed, index) => /* @__PURE__ */ jsx(
62
+ ArticleMap,
63
+ {
64
+ embed,
65
+ apiPath
66
+ },
67
+ `${embed.collection_slug}-${index}`
68
+ )) });
69
+ }
70
+ function ArticleMap({
71
+ embed,
72
+ apiPath
73
+ }) {
74
+ const client = useMemo(
75
+ () => createCommunityMapsBrowserClient(apiPath),
76
+ [apiPath]
77
+ );
78
+ const [data, setData] = useState(null);
79
+ const ids = embed.feature_ids?.join(",");
80
+ useEffect(() => {
81
+ const controller = new AbortController();
82
+ setData(null);
83
+ async function load() {
84
+ const collection = await client.collection(
85
+ embed.collection_slug,
86
+ controller.signal
87
+ );
88
+ const features = ids ? await Promise.all(
89
+ ids.split(",").map(
90
+ (id) => client.feature(embed.collection_slug, id, controller.signal)
91
+ )
92
+ ) : (await client.features(
93
+ embed.collection_slug,
94
+ { area_id: embed.area_id, limit: 20 },
95
+ controller.signal
96
+ )).items;
97
+ if (!controller.signal.aborted) setData({ collection, features });
98
+ }
99
+ void load().catch(() => setData(null));
100
+ return () => controller.abort();
101
+ }, [client, embed.collection_slug, embed.area_id, ids]);
102
+ if (!data) return null;
103
+ const path = `/community-maps/${data.collection.slug}`;
104
+ return /* @__PURE__ */ jsxs("aside", { className: "smcm", "aria-label": data.collection.config.title, children: [
105
+ /* @__PURE__ */ jsx("h2", { children: /* @__PURE__ */ jsx("a", { href: path, children: data.collection.config.title }) }),
106
+ embed.mode === "cards" ? /* @__PURE__ */ jsx(
107
+ CommunityCards,
108
+ {
109
+ areas: data.collection.areas,
110
+ href: (a) => `${path}/map?area=${a.id}`
111
+ }
112
+ ) : embed.mode === "map" ? /* @__PURE__ */ jsx(
113
+ CommunityMap,
114
+ {
115
+ features: data.features,
116
+ areas: data.collection.areas,
117
+ styleUrl: data.collection.config.presentation.map_style_url
118
+ }
119
+ ) : /* @__PURE__ */ jsx("div", { className: "smcm-feature-grid", children: data.features.map((f) => /* @__PURE__ */ jsx(
120
+ CommunityFeatureCard,
121
+ {
122
+ feature: f,
123
+ href: `${path}/places/${f.id}`,
124
+ photoUrl: f.media[0] ? client.mediaUrl(data.collection.slug, f.media[0].id) : void 0
125
+ },
126
+ f.id
127
+ )) }),
128
+ /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx("a", { href: `${path}/map`, children: "Explore the full map \u2197" }) })
129
+ ] });
130
+ }
131
+
132
+ export { CommunityMapArticleEmbeds, PublicationCommunityMapPage };
package/dist/index.cjs CHANGED
@@ -230,7 +230,26 @@ function composeEdition(items, selection = {}, now = Date.now()) {
230
230
  ...(pins.secondary_slugs ?? []).flatMap((slug) => remaining.find((item) => item.slug === slug) ?? []),
231
231
  ...remaining.filter((item) => !requested.has(item.slug))
232
232
  ];
233
- const secondary = Array.from(new Map(ordered.map((item) => [item.id, item])).values()).slice(0, 3);
233
+ const uniqueOrdered = Array.from(new Map(ordered.map((item) => [item.id, item])).values());
234
+ const seenImages = /* @__PURE__ */ new Set();
235
+ if (lead?.cover_image_url?.trim()) {
236
+ seenImages.add(lead.cover_image_url.trim());
237
+ }
238
+ const secondary = [];
239
+ const deferredWithDuplicateImage = [];
240
+ for (const item of uniqueOrdered) {
241
+ if (secondary.length >= 3) break;
242
+ const img = item.cover_image_url?.trim();
243
+ if (img && seenImages.has(img)) {
244
+ deferredWithDuplicateImage.push(item);
245
+ } else {
246
+ secondary.push(item);
247
+ if (img) seenImages.add(img);
248
+ }
249
+ }
250
+ while (secondary.length < 3 && deferredWithDuplicateImage.length > 0) {
251
+ secondary.push(deferredWithDuplicateImage.shift());
252
+ }
234
253
  for (const item of secondary) remaining.splice(remaining.indexOf(item), 1);
235
254
  const eligible = remaining.filter((item) => {
236
255
  const age = now - Date.parse(item.published_at);
@@ -2678,6 +2697,28 @@ function VerifiedCardSection({
2678
2697
  );
2679
2698
  }
2680
2699
 
2700
+ // src/community-maps.ts
2701
+ function communityMapEmbeds(metadata) {
2702
+ if (!metadata || typeof metadata !== "object") return [];
2703
+ const value = metadata.community_maps;
2704
+ if (!Array.isArray(value)) return [];
2705
+ return value.slice(0, 5).flatMap((entry) => {
2706
+ if (!entry || typeof entry !== "object" || typeof entry.collection_slug !== "string" || !/^[a-z0-9-]{1,191}$/.test(entry.collection_slug) || !["map", "cards", "features"].includes(entry.mode))
2707
+ return [];
2708
+ const ids = Array.isArray(entry.feature_ids) ? entry.feature_ids.filter(
2709
+ (id) => typeof id === "string" && /^[0-9a-f-]{36}$/i.test(id)
2710
+ ).slice(0, 20) : void 0;
2711
+ return [
2712
+ {
2713
+ collection_slug: entry.collection_slug,
2714
+ mode: entry.mode,
2715
+ feature_ids: ids,
2716
+ area_id: typeof entry.area_id === "string" && /^[0-9a-f-]{36}$/i.test(entry.area_id) ? entry.area_id : void 0
2717
+ }
2718
+ ];
2719
+ });
2720
+ }
2721
+
2681
2722
  Object.defineProperty(exports, "COOKIE_CONSENT_BACKUP_KEY", {
2682
2723
  enumerable: true,
2683
2724
  get: function () { return compliance.COOKIE_CONSENT_BACKUP_KEY; }
@@ -2809,6 +2850,7 @@ exports.classifiedPath = classifiedPath;
2809
2850
  exports.classifiedSearchPath = classifiedSearchPath;
2810
2851
  exports.clearTheme = clearTheme;
2811
2852
  exports.clipChars = clipChars;
2853
+ exports.communityMapEmbeds = communityMapEmbeds;
2812
2854
  exports.communityPublications = communityPublications;
2813
2855
  exports.composeEdition = composeEdition;
2814
2856
  exports.dealDollars = dealDollars;
package/dist/index.d.cts CHANGED
@@ -13,6 +13,7 @@ export { LocalNetworkBar, LocalNetworkBarProps } from './network-bar.cjs';
13
13
  export { NetworkCopyrightNotice, NetworkCopyrightNoticeProps } from './network-copyright.cjs';
14
14
  import * as react from 'react';
15
15
  export { VerifiedCardComponent, VerifiedCardSection, getArticleCards, isSafeActionUrl } from './verified-card.cjs';
16
+ export { C as CommunityMapArticleEmbed, c as communityMapEmbeds } from './community-maps-DKcYhQYN.cjs';
16
17
 
17
18
  /** Walnut Creek Times broadsheet colors. A paper overrides only what it changes. */
18
19
  declare const BROADSHEET_THEME: PublicationTheme;
package/dist/index.d.ts CHANGED
@@ -13,6 +13,7 @@ export { LocalNetworkBar, LocalNetworkBarProps } from './network-bar.js';
13
13
  export { NetworkCopyrightNotice, NetworkCopyrightNoticeProps } from './network-copyright.js';
14
14
  import * as react from 'react';
15
15
  export { VerifiedCardComponent, VerifiedCardSection, getArticleCards, isSafeActionUrl } from './verified-card.js';
16
+ export { C as CommunityMapArticleEmbed, c as communityMapEmbeds } from './community-maps-DKcYhQYN.js';
16
17
 
17
18
  /** Walnut Creek Times broadsheet colors. A paper overrides only what it changes. */
18
19
  declare const BROADSHEET_THEME: PublicationTheme;
package/dist/index.js CHANGED
@@ -1,15 +1,16 @@
1
+ export { CURATED_COMMUNITY_CARDS, VerifiedCardComponent, VerifiedCardSection, getArticleCards, isSafeActionUrl } from './chunk-FMCHQI7K.js';
2
+ export { CookieConsentBanner } from './chunk-DC6RMIYL.js';
1
3
  export { CookieSettingsView } from './chunk-XDGBMMLD.js';
2
4
  export { THEME_COOKIE, THEME_EVENT, THEME_MAX_AGE_SECONDS, THEME_STORAGE_KEY, ThemeToggle, applyTheme, clearTheme, getStoredTheme, getSystemTheme, resolveEffectiveTheme, setTheme, subscribeTheme, themeInitScript } from './chunk-NQD3M7ZY.js';
3
5
  export { LocalNetworkBar } from './chunk-EVAGI7C5.js';
4
6
  export { NetworkCopyrightNotice } from './chunk-VRDUSIVG.js';
5
- export { CURATED_COMMUNITY_CARDS, VerifiedCardComponent, VerifiedCardSection, getArticleCards, isSafeActionUrl } from './chunk-FMCHQI7K.js';
7
+ import { localPublications } from './chunk-56TU57OO.js';
8
+ export { COOKIE_CATEGORIES, COOKIE_CONSENT_BACKUP_KEY, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, COOKIE_CONSENT_MAX_AGE_SECONDS, DEFAULT_CONSENT_HUB_URL, DEFAULT_PREFERENCES_ACCEPTED, DEFAULT_PREFERENCES_REJECTED, EU_EEA_UK_COUNTRIES, NETWORK_CONSENT_STORAGE_KEY, NETWORK_PARENT, acceptAllCookies, checkUrlConsentBridge, clearCookieConsent, communityPublications, decorateNetworkUrl, findPublicationByHost, findPublicationBySlug, getCookieConsent, getNetworkPublicationUrl, hasConsented, isCategoryAllowed, isGeoConsentRequired, listedPublications, localPublications, queryNetworkConsentHub, recordConsentToCompliance, rejectOptionalCookies, setCookieConsent, setNetworkConsentHub } from './chunk-56TU57OO.js';
9
+ export { communityMapEmbeds } from './chunk-IMYBSG7J.js';
6
10
  import { definePublication } from './chunk-C7JTEHTH.js';
7
11
  export { BROADSHEET_THEME, FEATURE_NAMES, LAYOUT_COOKIE, acceptRemoteRecord, acceptSnapshot, definePublication, featureEnabled, parseSnapshot, publicationFromSnapshot, publicationRecord, resolveLayout, snapshotFromRecord, syncPublication } from './chunk-C7JTEHTH.js';
8
12
  export { CLASSIFIED_CATEGORIES, JOB_EMPLOYMENT_TYPES, categoryLabel, classifiedPath, classifiedSearchPath, clipChars, dealDollars, dealGoPath, dealsFeedPath, employmentLabel, isClassifiedCategory, isEmploymentType, jobEmployerBody, jobOpeningBody, jobPostingBody, prepareClassified, prepareJobPost, publicJobPath, publicJobsPath } from './chunk-C7ZPLH2K.js';
9
13
  export { MEET_ACTIVITIES, activityLabel, canHostMeetup, isAdult, prepareMeetup, screenMessage } from './chunk-GB36YM56.js';
10
- export { CookieConsentBanner } from './chunk-DC6RMIYL.js';
11
- import { localPublications } from './chunk-56TU57OO.js';
12
- export { COOKIE_CATEGORIES, COOKIE_CONSENT_BACKUP_KEY, COOKIE_CONSENT_EVENT, COOKIE_CONSENT_KEY, COOKIE_CONSENT_MAX_AGE_SECONDS, DEFAULT_CONSENT_HUB_URL, DEFAULT_PREFERENCES_ACCEPTED, DEFAULT_PREFERENCES_REJECTED, EU_EEA_UK_COUNTRIES, NETWORK_CONSENT_STORAGE_KEY, NETWORK_PARENT, acceptAllCookies, checkUrlConsentBridge, clearCookieConsent, communityPublications, decorateNetworkUrl, findPublicationByHost, findPublicationBySlug, getCookieConsent, getNetworkPublicationUrl, hasConsented, isCategoryAllowed, isGeoConsentRequired, listedPublications, localPublications, queryNetworkConsentHub, recordConsentToCompliance, rejectOptionalCookies, setCookieConsent, setNetworkConsentHub } from './chunk-56TU57OO.js';
13
14
  import { jsxs, jsx } from 'react/jsx-runtime';
14
15
 
15
16
  // src/preset.ts
@@ -169,7 +170,26 @@ function composeEdition(items, selection = {}, now = Date.now()) {
169
170
  ...(pins.secondary_slugs ?? []).flatMap((slug) => remaining.find((item) => item.slug === slug) ?? []),
170
171
  ...remaining.filter((item) => !requested.has(item.slug))
171
172
  ];
172
- const secondary = Array.from(new Map(ordered.map((item) => [item.id, item])).values()).slice(0, 3);
173
+ const uniqueOrdered = Array.from(new Map(ordered.map((item) => [item.id, item])).values());
174
+ const seenImages = /* @__PURE__ */ new Set();
175
+ if (lead?.cover_image_url?.trim()) {
176
+ seenImages.add(lead.cover_image_url.trim());
177
+ }
178
+ const secondary = [];
179
+ const deferredWithDuplicateImage = [];
180
+ for (const item of uniqueOrdered) {
181
+ if (secondary.length >= 3) break;
182
+ const img = item.cover_image_url?.trim();
183
+ if (img && seenImages.has(img)) {
184
+ deferredWithDuplicateImage.push(item);
185
+ } else {
186
+ secondary.push(item);
187
+ if (img) seenImages.add(img);
188
+ }
189
+ }
190
+ while (secondary.length < 3 && deferredWithDuplicateImage.length > 0) {
191
+ secondary.push(deferredWithDuplicateImage.shift());
192
+ }
173
193
  for (const item of secondary) remaining.splice(remaining.indexOf(item), 1);
174
194
  const eligible = remaining.filter((item) => {
175
195
  const age = now - Date.parse(item.published_at);