@scalemule/news-publication 0.0.45 → 0.0.47
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 +69 -0
- package/dist/{chunk-OIEO2YVG.js → chunk-2XSW7JZS.js} +1 -1
- package/dist/chunk-66GI2IX6.js +65 -0
- package/dist/{chunk-2IYKWGVM.js → chunk-GOWOYMSG.js} +13 -45
- package/dist/{chunk-UTBV6JJX.js → chunk-JV76ZEIA.js} +12 -27
- package/dist/{chunk-72PKW2HM.js → chunk-UL2Q3N26.js} +1 -1
- package/dist/{chunk-GVLJ3HAI.js → chunk-WAC6ATNP.js} +1 -1
- package/dist/cookie-consent-banner.cjs +13 -78
- package/dist/cookie-consent-banner.js +2 -2
- package/dist/cookie-settings-view.cjs +11 -26
- package/dist/cookie-settings-view.js +2 -2
- package/dist/index.cjs +405 -180
- package/dist/index.d.cts +143 -4
- package/dist/index.d.ts +143 -4
- package/dist/index.js +318 -117
- package/dist/network-bar.js +2 -2
- package/dist/network-copyright.js +2 -2
- package/dist/network.js +1 -1
- package/dist/{snapshot-CxuyMF39.d.ts → snapshot-DmRw8G_B.d.ts} +1 -1
- package/dist/{snapshot-C0IGpt-B.d.cts → snapshot-Dx4Lv-lB.d.cts} +1 -1
- package/dist/snapshot-file.d.cts +2 -2
- package/dist/snapshot-file.d.ts +2 -2
- package/dist/sponsorship-view.cjs +75 -0
- package/dist/sponsorship-view.d.cts +11 -0
- package/dist/sponsorship-view.d.ts +11 -0
- package/dist/sponsorship-view.js +62 -0
- package/dist/sponsorships-CtnBe3S8.d.cts +137 -0
- package/dist/sponsorships-CtnBe3S8.d.ts +137 -0
- package/dist/{types-DFDCZHbS.d.cts → types-BJFCWWi0.d.cts} +1 -1
- package/dist/{types-DFDCZHbS.d.ts → types-BJFCWWi0.d.ts} +1 -1
- package/dist/verified-card.d.cts +1 -1
- package/dist/verified-card.d.ts +1 -1
- package/package.json +11 -4
- package/sponsorship.css +78 -0
package/dist/index.cjs
CHANGED
|
@@ -73,106 +73,6 @@ function resolveLayout(publication, cookieValue) {
|
|
|
73
73
|
return publication.layout;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
// src/preset.ts
|
|
77
|
-
var walnutCreekTimes = definePublication({
|
|
78
|
-
slug: "walnutcreektimes",
|
|
79
|
-
name: "Walnut Creek Times",
|
|
80
|
-
masthead: ["Walnut", "Creek", "Times"],
|
|
81
|
-
region: "Walnut Creek",
|
|
82
|
-
regionLabel: "Walnut Creek",
|
|
83
|
-
towns: ["Walnut Creek", "Rossmoor", "Saranap", "Pleasant Hill"],
|
|
84
|
-
nearbyTowns: ["Martinez", "Concord", "Contra Costa"],
|
|
85
|
-
sections: ["Civic life", "Community", "Local businesses", "Real Estate", "Food & places", "Events", "Health"],
|
|
86
|
-
description: "Independent local journalism covering civic decisions, downtown commerce, neighborhood life, and community achievements across Walnut Creek, Rossmoor, Saranap, and Pleasant Hill.",
|
|
87
|
-
tagline: "Local stories. Stronger communities.",
|
|
88
|
-
layout: "broadsheet",
|
|
89
|
-
layouts: ["broadsheet"],
|
|
90
|
-
features: { smile: true, jobs: true, classifieds: true },
|
|
91
|
-
modules: { home: ["daily-smile"] }
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
// src/cache.ts
|
|
95
|
-
var NEWS_CACHE = {
|
|
96
|
-
feedRevalidateSeconds: 30,
|
|
97
|
-
articleRevalidateSeconds: 60,
|
|
98
|
-
edgeMaxAgeSeconds: 60,
|
|
99
|
-
staleWhileRevalidateSeconds: 300,
|
|
100
|
-
feedTag: "news-feed",
|
|
101
|
-
articleTag: "news-article",
|
|
102
|
-
inventoryTag: "public-news-discovery-v2",
|
|
103
|
-
paths: ["/", "/news"]
|
|
104
|
-
};
|
|
105
|
-
var feedCacheOptions = {
|
|
106
|
-
revalidate: NEWS_CACHE.feedRevalidateSeconds,
|
|
107
|
-
tags: [NEWS_CACHE.feedTag]
|
|
108
|
-
};
|
|
109
|
-
var articleCacheOptions = {
|
|
110
|
-
revalidate: NEWS_CACHE.articleRevalidateSeconds,
|
|
111
|
-
tags: [NEWS_CACHE.articleTag]
|
|
112
|
-
};
|
|
113
|
-
var inventoryCacheOptions = {
|
|
114
|
-
revalidate: NEWS_CACHE.feedRevalidateSeconds,
|
|
115
|
-
tags: [NEWS_CACHE.feedTag, NEWS_CACHE.inventoryTag]
|
|
116
|
-
};
|
|
117
|
-
function edgeCacheControl() {
|
|
118
|
-
return `public, s-maxage=${NEWS_CACHE.edgeMaxAgeSeconds}, stale-while-revalidate=${NEWS_CACHE.staleWhileRevalidateSeconds}`;
|
|
119
|
-
}
|
|
120
|
-
function feedCacheKey(publicationId, before, section) {
|
|
121
|
-
return `${publicationId}:${before ?? ""}:${section ?? ""}`;
|
|
122
|
-
}
|
|
123
|
-
function articleCacheKey(publicationId, slug) {
|
|
124
|
-
return `${publicationId}:${slug}`;
|
|
125
|
-
}
|
|
126
|
-
var NewsError = class extends Error {
|
|
127
|
-
constructor(status, message) {
|
|
128
|
-
super(message);
|
|
129
|
-
this.status = status;
|
|
130
|
-
this.name = "NewsError";
|
|
131
|
-
}
|
|
132
|
-
status;
|
|
133
|
-
};
|
|
134
|
-
function shouldServeLastKnown(error) {
|
|
135
|
-
const status = error instanceof NewsError ? error.status : error && typeof error === "object" && "status" in error ? error.status : void 0;
|
|
136
|
-
return status !== 404;
|
|
137
|
-
}
|
|
138
|
-
async function withLastKnown(store, key, load, accept = () => true) {
|
|
139
|
-
try {
|
|
140
|
-
const value = await load();
|
|
141
|
-
if (accept(value)) store.set(key, value);
|
|
142
|
-
return value;
|
|
143
|
-
} catch (error) {
|
|
144
|
-
if (!shouldServeLastKnown(error)) throw error;
|
|
145
|
-
const cached = store.get(key);
|
|
146
|
-
if (cached) return cached;
|
|
147
|
-
throw error;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
function secretsMatch(provided, secret) {
|
|
151
|
-
if (!provided || !secret) return false;
|
|
152
|
-
const left = Array.from(provided);
|
|
153
|
-
const right = Array.from(secret);
|
|
154
|
-
let mismatch = left.length === right.length ? 0 : 1;
|
|
155
|
-
const length = Math.max(left.length, right.length);
|
|
156
|
-
for (let index = 0; index < length; index += 1) {
|
|
157
|
-
mismatch |= (left[index]?.codePointAt(0) ?? 0) ^ (right[index]?.codePointAt(0) ?? 0);
|
|
158
|
-
}
|
|
159
|
-
return mismatch === 0;
|
|
160
|
-
}
|
|
161
|
-
function revalidateDecision(input) {
|
|
162
|
-
if (!secretsMatch(input.providedSecret, input.configuredSecret)) {
|
|
163
|
-
return { status: 401, body: { error: "Unauthorized" } };
|
|
164
|
-
}
|
|
165
|
-
const tag = input.tag?.trim() || `${NEWS_CACHE.feedTag}, ${NEWS_CACHE.articleTag}`;
|
|
166
|
-
const path = input.path?.trim() || NEWS_CACHE.paths.join(", ");
|
|
167
|
-
return { status: 200, body: { revalidated: true, tag, path, now: input.now ?? Date.now() } };
|
|
168
|
-
}
|
|
169
|
-
function defaultRevalidateTargets() {
|
|
170
|
-
return {
|
|
171
|
-
tags: [NEWS_CACHE.feedTag, NEWS_CACHE.articleTag, NEWS_CACHE.inventoryTag],
|
|
172
|
-
paths: [...NEWS_CACHE.paths]
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
|
|
176
76
|
// src/editorial.ts
|
|
177
77
|
var labels = {
|
|
178
78
|
"Local businesses": "Business",
|
|
@@ -190,8 +90,8 @@ var EDITORIAL_SECTION_ORDER = [
|
|
|
190
90
|
"Schools",
|
|
191
91
|
"Opinion"
|
|
192
92
|
];
|
|
193
|
-
function orderedSections(
|
|
194
|
-
return
|
|
93
|
+
function orderedSections(sections2, order = EDITORIAL_SECTION_ORDER) {
|
|
94
|
+
return sections2.filter((section) => section.name !== "Local news").slice().sort((left, right) => {
|
|
195
95
|
const leftRank = order.indexOf(left.name);
|
|
196
96
|
const rightRank = order.indexOf(right.name);
|
|
197
97
|
const leftOrder = leftRank === -1 ? order.length : leftRank;
|
|
@@ -252,12 +152,12 @@ function composeEdition(items, selection = {}, now = Date.now()) {
|
|
|
252
152
|
secondary.push(deferredWithDuplicateImage.shift());
|
|
253
153
|
}
|
|
254
154
|
for (const item of secondary) remaining.splice(remaining.indexOf(item), 1);
|
|
255
|
-
const
|
|
155
|
+
const eligible2 = remaining.filter((item) => {
|
|
256
156
|
const age = now - Date.parse(item.published_at);
|
|
257
157
|
return item.excerpt?.trim() && age >= 0 && age <= 7 * 864e5;
|
|
258
158
|
});
|
|
259
|
-
const selected = (pins.brief_slugs ?? []).flatMap((slug) =>
|
|
260
|
-
const candidates = [...selected, ...editorialSections(
|
|
159
|
+
const selected = (pins.brief_slugs ?? []).flatMap((slug) => eligible2.find((item) => item.slug === slug) ?? []);
|
|
160
|
+
const candidates = [...selected, ...editorialSections(eligible2).map((group) => group.items[0]), ...eligible2];
|
|
261
161
|
const briefIds = /* @__PURE__ */ new Set();
|
|
262
162
|
const briefs = candidates.filter((item) => {
|
|
263
163
|
if (!item || briefIds.has(item.id) || briefIds.size >= 4) return false;
|
|
@@ -266,8 +166,8 @@ function composeEdition(items, selection = {}, now = Date.now()) {
|
|
|
266
166
|
});
|
|
267
167
|
const compact = [...briefs, ...remaining.filter((item) => !briefIds.has(item.id))].slice(0, 4);
|
|
268
168
|
const compactIds = new Set(compact.map((item) => item.id));
|
|
269
|
-
const
|
|
270
|
-
return { lead, secondary, briefs, compact, sections, navigation: editorialSections(inventory) };
|
|
169
|
+
const sections2 = editorialSections(remaining.filter((item) => !compactIds.has(item.id)));
|
|
170
|
+
return { lead, secondary, briefs, compact, sections: sections2, navigation: editorialSections(inventory) };
|
|
271
171
|
}
|
|
272
172
|
function displayHeadline(article, selection = {}) {
|
|
273
173
|
return selection.stories?.[article.slug]?.display_title?.trim() || article.title;
|
|
@@ -334,8 +234,8 @@ function shortDeck(value, limit = 160) {
|
|
|
334
234
|
return (space > opening.length / 2 ? opening.slice(0, space) : opening).trimEnd() + "\u2026";
|
|
335
235
|
}
|
|
336
236
|
function storyDate(value) {
|
|
337
|
-
const
|
|
338
|
-
return Number.isNaN(
|
|
237
|
+
const date2 = new Date(value);
|
|
238
|
+
return Number.isNaN(date2.getTime()) ? null : date2.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric", timeZone: "America/Los_Angeles" });
|
|
339
239
|
}
|
|
340
240
|
|
|
341
241
|
// src/seo.ts
|
|
@@ -432,6 +332,265 @@ function llmsText(publication, canonical) {
|
|
|
432
332
|
].join("\n");
|
|
433
333
|
}
|
|
434
334
|
|
|
335
|
+
// src/briefing.ts
|
|
336
|
+
var LOCAL_BRIEFING_POLICY_VERSION = "1";
|
|
337
|
+
var DAY = 864e5;
|
|
338
|
+
var verifications = /* @__PURE__ */ new Set([
|
|
339
|
+
"unverified",
|
|
340
|
+
"community_submitted",
|
|
341
|
+
"officially_confirmed",
|
|
342
|
+
"independently_verified",
|
|
343
|
+
"disputed"
|
|
344
|
+
]);
|
|
345
|
+
var sections = /* @__PURE__ */ new Set(["important", "around_you", "people", "discover", "participate", "following"]);
|
|
346
|
+
var overlaps = (a, b = []) => a.some((id) => id.trim() !== "" && b.includes(id));
|
|
347
|
+
function timestamp(value) {
|
|
348
|
+
if (!/^\d{4}-\d{2}-\d{2}T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d{1,3})?(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(value) || !validCalendarDate(value.slice(0, 10))) return NaN;
|
|
349
|
+
return Date.parse(value);
|
|
350
|
+
}
|
|
351
|
+
function sourcesFor(candidate) {
|
|
352
|
+
const seen = /* @__PURE__ */ new Set();
|
|
353
|
+
return candidate.sources.flatMap((source) => {
|
|
354
|
+
const url = publicHttps(source.url);
|
|
355
|
+
if (!source.id.trim() || !source.publisher.trim() || !source.title.trim() || !url || seen.has(source.id)) return [];
|
|
356
|
+
seen.add(source.id);
|
|
357
|
+
return [{ id: source.id, url, title: source.title, publisher: source.publisher }];
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
function eligible(candidate, coverage, now) {
|
|
361
|
+
if (candidate.publication_status !== "published" || candidate.visibility !== "public" || candidate.editorial_approval !== "approved" || candidate.lifecycle !== "current" || !candidate.article.id.trim() || !candidate.article.slug.trim() || !candidate.article.title.trim() || !verifications.has(candidate.verification) || !sections.has(candidate.section) || !overlaps(candidate.geography_ids, coverage)) return false;
|
|
362
|
+
const published = timestamp(candidate.article.published_at);
|
|
363
|
+
const expiry = timestamp(candidate.relevant_until);
|
|
364
|
+
if (!Number.isFinite(published) || published > now || !Number.isFinite(expiry) || expiry <= now) return false;
|
|
365
|
+
const verified = candidate.last_verified_at === null ? null : timestamp(candidate.last_verified_at);
|
|
366
|
+
const review = candidate.review_due_at === null ? null : timestamp(candidate.review_due_at);
|
|
367
|
+
if (verified !== null && (!Number.isFinite(verified) || verified > now)) return false;
|
|
368
|
+
if (review !== null && (!Number.isFinite(review) || review <= now || verified !== null && review <= verified)) return false;
|
|
369
|
+
const confirmed = candidate.verification === "officially_confirmed" || candidate.verification === "independently_verified";
|
|
370
|
+
return !confirmed || verified !== null && review !== null && sourcesFor(candidate).length > 0;
|
|
371
|
+
}
|
|
372
|
+
function projectionKey(candidate) {
|
|
373
|
+
const article = candidate.article;
|
|
374
|
+
return JSON.stringify([
|
|
375
|
+
article.id,
|
|
376
|
+
article.slug,
|
|
377
|
+
article.title,
|
|
378
|
+
article.excerpt,
|
|
379
|
+
article.published_at,
|
|
380
|
+
article.author_name,
|
|
381
|
+
publicHttps(article.canonical_url),
|
|
382
|
+
[...candidate.geography_ids].sort(),
|
|
383
|
+
[...candidate.topic_ids].sort(),
|
|
384
|
+
[...candidate.entity_ids].sort(),
|
|
385
|
+
[...candidate.issue_ids].sort(),
|
|
386
|
+
candidate.section,
|
|
387
|
+
candidate.civic_importance,
|
|
388
|
+
candidate.practical_value,
|
|
389
|
+
candidate.discovery_value,
|
|
390
|
+
candidate.why_it_matters,
|
|
391
|
+
candidate.relevant_until,
|
|
392
|
+
candidate.verification,
|
|
393
|
+
candidate.last_verified_at,
|
|
394
|
+
candidate.review_due_at,
|
|
395
|
+
sourcesFor(candidate).sort((a, b) => a.id < b.id ? -1 : a.id > b.id ? 1 : 0)
|
|
396
|
+
]);
|
|
397
|
+
}
|
|
398
|
+
function composeLocalBriefing(candidates, options) {
|
|
399
|
+
const now = options.now ?? Date.now();
|
|
400
|
+
const limit = options.limit ?? 6;
|
|
401
|
+
if (!options.sm_application_id.trim() || !options.publication_id.trim() || !Number.isFinite(now) || !Number.isFinite(new Date(now).getTime()) || !Number.isInteger(limit) || limit < 1 || limit > 12) {
|
|
402
|
+
throw new RangeError("A briefing requires application/publication scope, a valid time and a limit from 1 to 12");
|
|
403
|
+
}
|
|
404
|
+
const preferences = options.personalized === false ? {} : options.preferences ?? {};
|
|
405
|
+
const personalized = [preferences.community_ids, preferences.topic_ids, preferences.entity_ids, preferences.issue_ids].some((ids) => ids?.some((id) => id.trim() !== ""));
|
|
406
|
+
const newest = /* @__PURE__ */ new Map();
|
|
407
|
+
for (const candidate of candidates) {
|
|
408
|
+
if (candidate.sm_application_id !== options.sm_application_id || candidate.publication_id !== options.publication_id || !candidate.canonical_key.trim() || !Number.isSafeInteger(candidate.revision) || candidate.revision < 1) continue;
|
|
409
|
+
const group = newest.get(candidate.canonical_key);
|
|
410
|
+
if (!group || candidate.revision > group[0].revision) newest.set(candidate.canonical_key, [candidate]);
|
|
411
|
+
else if (candidate.revision === group[0].revision) group.push(candidate);
|
|
412
|
+
}
|
|
413
|
+
const ranked = [];
|
|
414
|
+
for (const group of newest.values()) {
|
|
415
|
+
if (group.some((candidate2) => !eligible(candidate2, options.coverage_area_ids, now))) continue;
|
|
416
|
+
const candidate = group[0];
|
|
417
|
+
if (group.length > 1 && group.some((copy) => projectionKey(copy) !== projectionKey(candidate))) continue;
|
|
418
|
+
const summary = candidate.article.excerpt?.trim() ?? "";
|
|
419
|
+
if (!summary || Array.from(summary).length > 280 || !/[.!?。!?][”’"']?$/u.test(summary)) continue;
|
|
420
|
+
const community = overlaps(candidate.geography_ids, preferences.community_ids);
|
|
421
|
+
const entity = overlaps(candidate.entity_ids, preferences.entity_ids);
|
|
422
|
+
const issue = overlaps(candidate.issue_ids, preferences.issue_ids);
|
|
423
|
+
const topic = overlaps(candidate.topic_ids, preferences.topic_ids);
|
|
424
|
+
const published = timestamp(candidate.article.published_at);
|
|
425
|
+
const age = now - published;
|
|
426
|
+
const important = candidate.civic_importance === "important";
|
|
427
|
+
const relevance = {
|
|
428
|
+
geographic: community ? 2 : 1,
|
|
429
|
+
practical: candidate.practical_value ? 1 : 0,
|
|
430
|
+
relationship: entity || issue ? 1 : 0,
|
|
431
|
+
interest: topic ? 1 : 0,
|
|
432
|
+
temporal: age < DAY ? 2 : age < 7 * DAY ? 1 : 0,
|
|
433
|
+
civic: important ? 1 : 0,
|
|
434
|
+
discovery: candidate.discovery_value ? 1 : 0
|
|
435
|
+
};
|
|
436
|
+
const reasons = [];
|
|
437
|
+
if (important) reasons.push("important_civic_information");
|
|
438
|
+
reasons.push(community ? "selected_community" : "publication_coverage");
|
|
439
|
+
if (candidate.practical_value) reasons.push("practical_value");
|
|
440
|
+
if (entity) reasons.push("following_entity");
|
|
441
|
+
if (issue) reasons.push("following_issue");
|
|
442
|
+
if (topic) reasons.push("selected_topic");
|
|
443
|
+
if (relevance.temporal > 0) reasons.push("recent_reporting");
|
|
444
|
+
if (candidate.discovery_value) reasons.push("local_discovery");
|
|
445
|
+
const article = candidate.article;
|
|
446
|
+
const item = {
|
|
447
|
+
canonical_key: candidate.canonical_key,
|
|
448
|
+
revision: candidate.revision,
|
|
449
|
+
article: {
|
|
450
|
+
id: article.id,
|
|
451
|
+
slug: article.slug,
|
|
452
|
+
title: article.title,
|
|
453
|
+
published_at: article.published_at,
|
|
454
|
+
author_name: article.author_name,
|
|
455
|
+
canonical_url: publicHttps(article.canonical_url) ?? null
|
|
456
|
+
},
|
|
457
|
+
summary,
|
|
458
|
+
section: important ? "important" : entity || issue ? "following" : candidate.section,
|
|
459
|
+
geography_ids: [...new Set(candidate.geography_ids)],
|
|
460
|
+
why_it_matters: candidate.why_it_matters?.trim() || void 0,
|
|
461
|
+
reasons,
|
|
462
|
+
relevance,
|
|
463
|
+
verification: candidate.verification,
|
|
464
|
+
freshness: candidate.last_verified_at !== null && candidate.review_due_at !== null ? "current" : "unknown",
|
|
465
|
+
last_verified_at: candidate.last_verified_at,
|
|
466
|
+
review_due_at: candidate.review_due_at,
|
|
467
|
+
relevant_until: candidate.relevant_until,
|
|
468
|
+
sources: sourcesFor(candidate)
|
|
469
|
+
};
|
|
470
|
+
const score = 4 * relevance.geographic + 3 * relevance.practical + 3 * relevance.relationship + 2 * relevance.interest + relevance.temporal + relevance.discovery;
|
|
471
|
+
ranked.push({ item, score, published, important });
|
|
472
|
+
}
|
|
473
|
+
ranked.sort((a, b) => Number(b.important) - Number(a.important) || b.score - a.score || b.published - a.published || (a.item.canonical_key < b.item.canonical_key ? -1 : a.item.canonical_key > b.item.canonical_key ? 1 : 0));
|
|
474
|
+
const seenArticles = /* @__PURE__ */ new Set();
|
|
475
|
+
const seenUrls = /* @__PURE__ */ new Set();
|
|
476
|
+
const deduplicated = ranked.filter(({ item }) => {
|
|
477
|
+
const url = item.article.canonical_url;
|
|
478
|
+
if (seenArticles.has(item.article.id) || url && seenUrls.has(url)) return false;
|
|
479
|
+
seenArticles.add(item.article.id);
|
|
480
|
+
if (url) seenUrls.add(url);
|
|
481
|
+
return true;
|
|
482
|
+
});
|
|
483
|
+
return {
|
|
484
|
+
schema_version: 1,
|
|
485
|
+
policy_version: LOCAL_BRIEFING_POLICY_VERSION,
|
|
486
|
+
publication_id: options.publication_id,
|
|
487
|
+
generated_at: new Date(now).toISOString(),
|
|
488
|
+
personalized,
|
|
489
|
+
items: deduplicated.slice(0, limit).map(({ item }) => item),
|
|
490
|
+
remaining_important_count: deduplicated.slice(limit).filter(({ important }) => important).length
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// src/preset.ts
|
|
495
|
+
var walnutCreekTimes = definePublication({
|
|
496
|
+
slug: "walnutcreektimes",
|
|
497
|
+
name: "Walnut Creek Times",
|
|
498
|
+
masthead: ["Walnut", "Creek", "Times"],
|
|
499
|
+
region: "Walnut Creek",
|
|
500
|
+
regionLabel: "Walnut Creek",
|
|
501
|
+
towns: ["Walnut Creek", "Rossmoor", "Saranap", "Pleasant Hill"],
|
|
502
|
+
nearbyTowns: ["Martinez", "Concord", "Contra Costa"],
|
|
503
|
+
sections: ["Civic life", "Community", "Local businesses", "Real Estate", "Food & places", "Events", "Health"],
|
|
504
|
+
description: "Independent local journalism covering civic decisions, downtown commerce, neighborhood life, and community achievements across Walnut Creek, Rossmoor, Saranap, and Pleasant Hill.",
|
|
505
|
+
tagline: "Local stories. Stronger communities.",
|
|
506
|
+
layout: "broadsheet",
|
|
507
|
+
layouts: ["broadsheet"],
|
|
508
|
+
features: { smile: true, jobs: true, classifieds: true },
|
|
509
|
+
modules: { home: ["daily-smile"] }
|
|
510
|
+
});
|
|
511
|
+
|
|
512
|
+
// src/cache.ts
|
|
513
|
+
var NEWS_CACHE = {
|
|
514
|
+
feedRevalidateSeconds: 30,
|
|
515
|
+
articleRevalidateSeconds: 60,
|
|
516
|
+
edgeMaxAgeSeconds: 60,
|
|
517
|
+
staleWhileRevalidateSeconds: 300,
|
|
518
|
+
feedTag: "news-feed",
|
|
519
|
+
articleTag: "news-article",
|
|
520
|
+
inventoryTag: "public-news-discovery-v2",
|
|
521
|
+
paths: ["/", "/news"]
|
|
522
|
+
};
|
|
523
|
+
var feedCacheOptions = {
|
|
524
|
+
revalidate: NEWS_CACHE.feedRevalidateSeconds,
|
|
525
|
+
tags: [NEWS_CACHE.feedTag]
|
|
526
|
+
};
|
|
527
|
+
var articleCacheOptions = {
|
|
528
|
+
revalidate: NEWS_CACHE.articleRevalidateSeconds,
|
|
529
|
+
tags: [NEWS_CACHE.articleTag]
|
|
530
|
+
};
|
|
531
|
+
var inventoryCacheOptions = {
|
|
532
|
+
revalidate: NEWS_CACHE.feedRevalidateSeconds,
|
|
533
|
+
tags: [NEWS_CACHE.feedTag, NEWS_CACHE.inventoryTag]
|
|
534
|
+
};
|
|
535
|
+
function edgeCacheControl() {
|
|
536
|
+
return `public, s-maxage=${NEWS_CACHE.edgeMaxAgeSeconds}, stale-while-revalidate=${NEWS_CACHE.staleWhileRevalidateSeconds}`;
|
|
537
|
+
}
|
|
538
|
+
function feedCacheKey(publicationId, before, section) {
|
|
539
|
+
return `${publicationId}:${before ?? ""}:${section ?? ""}`;
|
|
540
|
+
}
|
|
541
|
+
function articleCacheKey(publicationId, slug) {
|
|
542
|
+
return `${publicationId}:${slug}`;
|
|
543
|
+
}
|
|
544
|
+
var NewsError = class extends Error {
|
|
545
|
+
constructor(status, message) {
|
|
546
|
+
super(message);
|
|
547
|
+
this.status = status;
|
|
548
|
+
this.name = "NewsError";
|
|
549
|
+
}
|
|
550
|
+
status;
|
|
551
|
+
};
|
|
552
|
+
function shouldServeLastKnown(error) {
|
|
553
|
+
const status = error instanceof NewsError ? error.status : error && typeof error === "object" && "status" in error ? error.status : void 0;
|
|
554
|
+
return status !== 404;
|
|
555
|
+
}
|
|
556
|
+
async function withLastKnown(store, key, load, accept = () => true) {
|
|
557
|
+
try {
|
|
558
|
+
const value = await load();
|
|
559
|
+
if (accept(value)) store.set(key, value);
|
|
560
|
+
return value;
|
|
561
|
+
} catch (error) {
|
|
562
|
+
if (!shouldServeLastKnown(error)) throw error;
|
|
563
|
+
const cached = store.get(key);
|
|
564
|
+
if (cached) return cached;
|
|
565
|
+
throw error;
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
function secretsMatch(provided, secret) {
|
|
569
|
+
if (!provided || !secret) return false;
|
|
570
|
+
const left = Array.from(provided);
|
|
571
|
+
const right = Array.from(secret);
|
|
572
|
+
let mismatch = left.length === right.length ? 0 : 1;
|
|
573
|
+
const length = Math.max(left.length, right.length);
|
|
574
|
+
for (let index = 0; index < length; index += 1) {
|
|
575
|
+
mismatch |= (left[index]?.codePointAt(0) ?? 0) ^ (right[index]?.codePointAt(0) ?? 0);
|
|
576
|
+
}
|
|
577
|
+
return mismatch === 0;
|
|
578
|
+
}
|
|
579
|
+
function revalidateDecision(input) {
|
|
580
|
+
if (!secretsMatch(input.providedSecret, input.configuredSecret)) {
|
|
581
|
+
return { status: 401, body: { error: "Unauthorized" } };
|
|
582
|
+
}
|
|
583
|
+
const tag = input.tag?.trim() || `${NEWS_CACHE.feedTag}, ${NEWS_CACHE.articleTag}`;
|
|
584
|
+
const path = input.path?.trim() || NEWS_CACHE.paths.join(", ");
|
|
585
|
+
return { status: 200, body: { revalidated: true, tag, path, now: input.now ?? Date.now() } };
|
|
586
|
+
}
|
|
587
|
+
function defaultRevalidateTargets() {
|
|
588
|
+
return {
|
|
589
|
+
tags: [NEWS_CACHE.feedTag, NEWS_CACHE.articleTag, NEWS_CACHE.inventoryTag],
|
|
590
|
+
paths: [...NEWS_CACHE.paths]
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
|
|
435
594
|
// src/analytics.ts
|
|
436
595
|
var ANALYTICS_VERSION = 1;
|
|
437
596
|
var ANALYTICS_COOKIE = "napsite_analytics_v1";
|
|
@@ -1119,13 +1278,6 @@ var COOKIE_CATEGORIES = [
|
|
|
1119
1278
|
duration: "1 year",
|
|
1120
1279
|
type: "HTTP Cookie"
|
|
1121
1280
|
},
|
|
1122
|
-
{
|
|
1123
|
-
name: "napsite_session_v1",
|
|
1124
|
-
provider: "First-Party",
|
|
1125
|
-
purpose: "Maintains session continuity, security tokens, and server routing.",
|
|
1126
|
-
duration: "30 minutes (idle)",
|
|
1127
|
-
type: "Session Storage"
|
|
1128
|
-
},
|
|
1129
1281
|
{
|
|
1130
1282
|
name: "napsite_preview",
|
|
1131
1283
|
provider: "First-Party",
|
|
@@ -1139,9 +1291,16 @@ var COOKIE_CATEGORIES = [
|
|
|
1139
1291
|
id: "performance",
|
|
1140
1292
|
title: "Performance & Analytics Cookies",
|
|
1141
1293
|
shortDescription: "Help us measure reader engagement, story completion, and site reliability.",
|
|
1142
|
-
fullDescription: "
|
|
1294
|
+
fullDescription: "With your permission, first-party identifiers support page-visit and reading measurements. Aggregate reports help us improve the publication. Measurements are incomplete when readers decline consent and are not a count of unique people.",
|
|
1143
1295
|
required: false,
|
|
1144
1296
|
cookies: [
|
|
1297
|
+
{
|
|
1298
|
+
name: "napsite_session_v1",
|
|
1299
|
+
provider: "First-Party",
|
|
1300
|
+
purpose: "Groups consented reading measurements within a session.",
|
|
1301
|
+
duration: "30 minutes (idle)",
|
|
1302
|
+
type: "Session Storage"
|
|
1303
|
+
},
|
|
1145
1304
|
{
|
|
1146
1305
|
name: "napsite_visitor_v1",
|
|
1147
1306
|
provider: "First-Party",
|
|
@@ -1191,29 +1350,14 @@ var COOKIE_CATEGORIES = [
|
|
|
1191
1350
|
{
|
|
1192
1351
|
id: "advertising",
|
|
1193
1352
|
title: "Advertising & Local Sponsorship Cookies",
|
|
1194
|
-
shortDescription: "
|
|
1195
|
-
fullDescription: "
|
|
1353
|
+
shortDescription: "Measure clearly labeled community sponsorship views and link clicks.",
|
|
1354
|
+
fullDescription: "With your permission, we measure visible sponsor acknowledgments and link clicks. Repetition limits use temporary page-session memory. We do not use third-party advertising trackers or build behavioral advertising profiles.",
|
|
1196
1355
|
required: false,
|
|
1197
|
-
cookies: [
|
|
1198
|
-
{
|
|
1199
|
-
name: "napsite_sponsor_cap",
|
|
1200
|
-
provider: "First-Party",
|
|
1201
|
-
purpose: "Prevents repetitive display of identical local business announcements.",
|
|
1202
|
-
duration: "7 days",
|
|
1203
|
-
type: "Local Storage"
|
|
1204
|
-
},
|
|
1205
|
-
{
|
|
1206
|
-
name: "local_sponsor_ref",
|
|
1207
|
-
provider: "First-Party",
|
|
1208
|
-
purpose: "Attributes community inquiries directly to the sponsoring local merchant.",
|
|
1209
|
-
duration: "30 days",
|
|
1210
|
-
type: "Local Storage"
|
|
1211
|
-
}
|
|
1212
|
-
]
|
|
1356
|
+
cookies: []
|
|
1213
1357
|
}
|
|
1214
1358
|
];
|
|
1215
1359
|
function CookieConsentBanner({
|
|
1216
|
-
title = "
|
|
1360
|
+
title = "Your privacy choices",
|
|
1217
1361
|
text,
|
|
1218
1362
|
settingsUrl = "/cookies",
|
|
1219
1363
|
className = "",
|
|
@@ -1227,73 +1371,41 @@ function CookieConsentBanner({
|
|
|
1227
1371
|
const [visible, setVisible] = react.useState(false);
|
|
1228
1372
|
react.useEffect(() => {
|
|
1229
1373
|
setMounted(true);
|
|
1230
|
-
|
|
1231
|
-
if (
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
}
|
|
1239
|
-
if (!forceShow && !compliance.isGeoConsentRequired(countryCode)) {
|
|
1240
|
-
setVisible(false);
|
|
1241
|
-
void compliance.queryNetworkConsentHub(consentHubUrl, 1200).then((networkStatus) => {
|
|
1242
|
-
if (networkStatus === "accepted") {
|
|
1243
|
-
compliance.acceptAllCookies();
|
|
1244
|
-
} else if (networkStatus === "rejected") {
|
|
1245
|
-
compliance.rejectOptionalCookies();
|
|
1246
|
-
}
|
|
1247
|
-
});
|
|
1248
|
-
return;
|
|
1249
|
-
}
|
|
1250
|
-
let cancelled = false;
|
|
1251
|
-
void compliance.queryNetworkConsentHub(consentHubUrl, 1e3).then((networkStatus) => {
|
|
1252
|
-
if (cancelled) return;
|
|
1253
|
-
if (networkStatus === "accepted") {
|
|
1254
|
-
compliance.acceptAllCookies();
|
|
1255
|
-
setVisible(false);
|
|
1256
|
-
} else if (networkStatus === "rejected") {
|
|
1257
|
-
compliance.rejectOptionalCookies();
|
|
1258
|
-
setVisible(false);
|
|
1259
|
-
} else {
|
|
1260
|
-
setVisible(true);
|
|
1261
|
-
}
|
|
1262
|
-
});
|
|
1263
|
-
return () => {
|
|
1264
|
-
cancelled = true;
|
|
1265
|
-
};
|
|
1374
|
+
const url = new URL(window.location.href);
|
|
1375
|
+
if (url.searchParams.has("sm_consent")) {
|
|
1376
|
+
if (url.searchParams.get("sm_consent") === "0" && !compliance.hasConsented())
|
|
1377
|
+
compliance.rejectOptionalCookies({ hubUrl: consentHubUrl });
|
|
1378
|
+
url.searchParams.delete("sm_consent");
|
|
1379
|
+
window.history.replaceState(window.history.state, "", url);
|
|
1380
|
+
}
|
|
1381
|
+
setVisible(!compliance.hasConsented() && !compliance.isGpcActive());
|
|
1266
1382
|
}, [countryCode, forceShow, consentHubUrl]);
|
|
1267
1383
|
react.useEffect(() => {
|
|
1268
1384
|
const onConsentChange = () => {
|
|
1269
|
-
|
|
1270
|
-
setVisible(false);
|
|
1271
|
-
}
|
|
1385
|
+
setVisible(!compliance.hasConsented() && !compliance.isGpcActive());
|
|
1272
1386
|
};
|
|
1273
1387
|
window.addEventListener(compliance.COOKIE_CONSENT_EVENT, onConsentChange);
|
|
1274
1388
|
return () => window.removeEventListener(compliance.COOKIE_CONSENT_EVENT, onConsentChange);
|
|
1275
1389
|
}, []);
|
|
1276
1390
|
if (!mounted || !visible) return null;
|
|
1277
1391
|
const handleAccept = () => {
|
|
1278
|
-
const record = compliance.acceptAllCookies();
|
|
1392
|
+
const record = compliance.acceptAllCookies({ hubUrl: consentHubUrl });
|
|
1279
1393
|
setVisible(false);
|
|
1280
1394
|
void recordConsentToCompliance(record, {
|
|
1281
1395
|
endpoint: complianceEndpoint,
|
|
1282
1396
|
publicationSlug
|
|
1283
1397
|
});
|
|
1284
|
-
compliance.setNetworkConsentHub("accepted", consentHubUrl);
|
|
1285
1398
|
};
|
|
1286
1399
|
const handleReject = () => {
|
|
1287
|
-
const record = compliance.rejectOptionalCookies();
|
|
1400
|
+
const record = compliance.rejectOptionalCookies({ hubUrl: consentHubUrl });
|
|
1288
1401
|
setVisible(false);
|
|
1289
1402
|
void recordConsentToCompliance(record, {
|
|
1290
1403
|
endpoint: complianceEndpoint,
|
|
1291
1404
|
publicationSlug
|
|
1292
1405
|
});
|
|
1293
|
-
compliance.setNetworkConsentHub("rejected", consentHubUrl);
|
|
1294
1406
|
};
|
|
1295
1407
|
const defaultText = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
1296
|
-
"
|
|
1408
|
+
"With your permission, we measure reading activity and sponsor acknowledgments. You can read the publication with optional cookies turned off. View",
|
|
1297
1409
|
" ",
|
|
1298
1410
|
/* @__PURE__ */ jsxRuntime.jsx("a", { href: settingsUrl, className: "sm-cookie-banner-link", children: "Cookie Settings" }),
|
|
1299
1411
|
" ",
|
|
@@ -3075,6 +3187,111 @@ function renderArticleBlocksToHtml(blocks, mediaMap, options) {
|
|
|
3075
3187
|
return parts.join("\n");
|
|
3076
3188
|
}
|
|
3077
3189
|
|
|
3190
|
+
// src/sponsorships.ts
|
|
3191
|
+
var SPONSORSHIP_POLICY = "Sponsors receive clearly identified recognition. Sponsorship does not influence reporting, event selection, factual information, rankings or editorial recommendations.";
|
|
3192
|
+
var SPONSORSHIP_OFFERINGS = [
|
|
3193
|
+
{
|
|
3194
|
+
type: "community_partner",
|
|
3195
|
+
name: "Publication Community Partner",
|
|
3196
|
+
price_cents: 35e3,
|
|
3197
|
+
duration: "One calendar month; exact start and end dates in the agreement.",
|
|
3198
|
+
deliverables: "One acknowledgment on the publication's community partners page and one compact acknowledgment below the community calendar. No article placements.",
|
|
3199
|
+
acknowledgments: "Two defined web locations; recurring display during the campaign, subject to reader repetition limits.",
|
|
3200
|
+
creative: "Name, approved logo, up to 140 characters of copy and one HTTPS link.",
|
|
3201
|
+
max_sponsors: 2,
|
|
3202
|
+
product_path: "/community-partners"
|
|
3203
|
+
},
|
|
3204
|
+
{
|
|
3205
|
+
type: "community_calendar",
|
|
3206
|
+
name: "Community Calendar Sponsor",
|
|
3207
|
+
price_cents: 25e3,
|
|
3208
|
+
duration: "One calendar month; exact start and end dates in the agreement.",
|
|
3209
|
+
deliverables: "One acknowledgment above the independently curated community events calendar.",
|
|
3210
|
+
acknowledgments: "One web location; recurring display during the campaign, subject to reader repetition limits.",
|
|
3211
|
+
creative: "Name, approved logo, up to 140 characters of copy and one HTTPS link.",
|
|
3212
|
+
max_sponsors: 1,
|
|
3213
|
+
product_path: "/this-week"
|
|
3214
|
+
},
|
|
3215
|
+
{
|
|
3216
|
+
type: "daily_briefing",
|
|
3217
|
+
name: "Daily Briefing Sponsor",
|
|
3218
|
+
price_cents: 3e4,
|
|
3219
|
+
duration: "One calendar month after verified newsletter delivery is operational.",
|
|
3220
|
+
deliverables: "One acknowledgment per agreed briefing edition. Edition dates and count must be specified in the agreement before booking.",
|
|
3221
|
+
acknowledgments: "One per contracted edition; no minimum send count is promised before launch.",
|
|
3222
|
+
creative: "Name, optional logo, up to 140 characters of approved copy and one HTTPS link.",
|
|
3223
|
+
max_sponsors: 1,
|
|
3224
|
+
product_path: "/newsletter"
|
|
3225
|
+
},
|
|
3226
|
+
{
|
|
3227
|
+
type: "community_guide",
|
|
3228
|
+
name: "Community Guide Sponsor",
|
|
3229
|
+
price_cents: null,
|
|
3230
|
+
duration: "Fixed dates agreed for a named guide.",
|
|
3231
|
+
deliverables: "One acknowledgment on one named, independently edited community guide; scope and updates agreed in writing.",
|
|
3232
|
+
acknowledgments: "One web location per contracted guide.",
|
|
3233
|
+
creative: "Name, approved logo, up to 140 characters of copy and one HTTPS link.",
|
|
3234
|
+
max_sponsors: 1,
|
|
3235
|
+
product_path: "/guides"
|
|
3236
|
+
}
|
|
3237
|
+
];
|
|
3238
|
+
function safeSponsorUrl(value) {
|
|
3239
|
+
if (typeof value !== "string" || value.length > 2048) return void 0;
|
|
3240
|
+
try {
|
|
3241
|
+
const url = new URL(value);
|
|
3242
|
+
if (url.protocol !== "https:" || url.username || url.password)
|
|
3243
|
+
return void 0;
|
|
3244
|
+
return url.toString();
|
|
3245
|
+
} catch {
|
|
3246
|
+
return void 0;
|
|
3247
|
+
}
|
|
3248
|
+
}
|
|
3249
|
+
function placementAvailable(placement, now = Date.now()) {
|
|
3250
|
+
const verified = placement.verified_at && Date.parse(placement.verified_at);
|
|
3251
|
+
return placement.placement_type !== "daily_briefing" && placement.active && placement.availability === "available" && Boolean(safeSponsorUrl(placement.verification_url)) && typeof verified === "number" && Number.isFinite(verified) && verified <= now && now - verified <= 90 * 864e5;
|
|
3252
|
+
}
|
|
3253
|
+
|
|
3254
|
+
// src/measurement-consent.ts
|
|
3255
|
+
function measurementConsent(headers, sponsorship = false, now = Date.now()) {
|
|
3256
|
+
if (headers.get("dnt") === "1" || headers.get("sec-gpc") === "1")
|
|
3257
|
+
return false;
|
|
3258
|
+
const cookies = headers.get("cookie")?.split(";").map((value) => value.trim()) ?? [];
|
|
3259
|
+
const cookie = cookies.find((value) => value.startsWith("sm_cookie_consent_v1=")) ?? cookies.find((value) => value.startsWith("napsite_cookie_consent_v1="));
|
|
3260
|
+
if (!cookie) return false;
|
|
3261
|
+
try {
|
|
3262
|
+
const record = JSON.parse(
|
|
3263
|
+
decodeURIComponent(cookie.substring(cookie.indexOf("=") + 1))
|
|
3264
|
+
);
|
|
3265
|
+
const date2 = Date.parse(record.timestamp);
|
|
3266
|
+
return record.version === 1 && record.preferences?.essential === true && typeof record.preferences?.functional === "boolean" && typeof record.preferences?.advertising === "boolean" && record.preferences?.performance === true && (!sponsorship || record.preferences?.advertising === true) && Number.isFinite(date2) && date2 <= now + 3e5 && now - date2 < 365 * 864e5;
|
|
3267
|
+
} catch {
|
|
3268
|
+
return false;
|
|
3269
|
+
}
|
|
3270
|
+
}
|
|
3271
|
+
|
|
3272
|
+
// src/sponsorship-report.ts
|
|
3273
|
+
var escape = (text) => String(text ?? "").replace(
|
|
3274
|
+
/[&<>"']/g,
|
|
3275
|
+
(c) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[c]
|
|
3276
|
+
);
|
|
3277
|
+
var date = (value) => new Date(value).toLocaleString("en-US", {
|
|
3278
|
+
timeZone: "UTC",
|
|
3279
|
+
dateStyle: "medium",
|
|
3280
|
+
timeStyle: "short"
|
|
3281
|
+
}) + " UTC";
|
|
3282
|
+
function metric(value) {
|
|
3283
|
+
if (value.status === "unavailable" || value.value === null)
|
|
3284
|
+
return "Unavailable";
|
|
3285
|
+
return `${escape(value.value.toLocaleString("en-US"))} <small>${escape(value.status)}</small>${value.from && value.to ? `<small>Observed period:<br>${escape(date(value.from))}<br>to ${escape(date(value.to))}</small>` : ""}`;
|
|
3286
|
+
}
|
|
3287
|
+
function campaignReportHtml(report) {
|
|
3288
|
+
return `<!doctype html><html lang="en"><head><meta charset="utf-8"><title>${escape(report.campaign_name)} | Sponsorship report</title><style>
|
|
3289
|
+
@page{size:Letter;margin:18mm}*{box-sizing:border-box}body{font:11pt/1.5 Arial,sans-serif;color:#172d37;margin:0}h1,h2{font-family:Georgia,serif;font-weight:normal}h1{font-size:30pt;line-height:1.12;margin:16pt 0}h2{font-size:19pt;margin:0 0 8pt}header{border-bottom:2pt solid #173d32;padding-bottom:16pt}.brand{font-size:10pt;letter-spacing:1pt}p{margin:8pt 0}.meta{color:#4e5d64;font-size:10pt}section{break-inside:avoid;margin:24pt 0}table{width:100%;border-collapse:collapse;margin:12pt 0}td,th{text-align:left;border-bottom:1px solid #d8dedc;padding:8pt 5pt}th{font-size:9pt}small{display:block;color:#4e5d64;font-size:8pt}footer{border-top:1px solid #d8dedc;padding-top:12pt;font-size:9pt}.notes{font-size:9pt;color:#4e5d64}
|
|
3290
|
+
</style></head><body><header><div class="brand">BAY AREA NEWS NETWORK</div><p>Community sponsorship report</p><h1>${escape(report.campaign_name)}</h1><p>${escape(report.sponsor)}</p><p class="meta">Campaign period: ${escape(date(report.starts_at))} to ${escape(date(report.ends_at))}<br>Status: ${escape(report.status)}<br>Prepared: ${escape(date(report.generated_at))}</p></header>
|
|
3291
|
+
${report.placements.map((p) => `<section><h2>${escape(p.publication)}</h2><p>${escape(p.placement)} \xB7 ${escape(p.product_path)}</p><p class="meta">Community scope: ${escape(p.communities.length ? p.communities.join(", ") : "Publication-wide")}<br>Placement delivery: ${escape(p.delivery_status)}</p><table><thead><tr><th>Observed placement views</th><th>Observed sponsor link clicks</th><th>Newsletter deliveries</th></tr></thead><tbody><tr><td>${metric(p.views)}</td><td>${metric(p.clicks)}</td><td>${metric(p.newsletter_deliveries)}</td></tr></tbody></table><p class="notes">Views: ${escape(p.views.methodology)}<br>Clicks: ${escape(p.clicks.methodology)}<br>Newsletter: ${escape(p.newsletter_deliveries.methodology)}</p></section>`).join("")}
|
|
3292
|
+
<footer><p>${escape(report.reporting_note)}</p><p>${escape(report.editorial_independence)}</p><p>Campaign reference: ${escape(report.campaign_id)}</p></footer></body></html>`;
|
|
3293
|
+
}
|
|
3294
|
+
|
|
3078
3295
|
Object.defineProperty(exports, "COOKIE_CONSENT_BACKUP_KEY", {
|
|
3079
3296
|
enumerable: true,
|
|
3080
3297
|
get: function () { return compliance.COOKIE_CONSENT_BACKUP_KEY; }
|
|
@@ -3174,6 +3391,7 @@ exports.EVENTS = EVENTS;
|
|
|
3174
3391
|
exports.FEATURE_NAMES = FEATURE_NAMES;
|
|
3175
3392
|
exports.JOB_EMPLOYMENT_TYPES = JOB_EMPLOYMENT_TYPES;
|
|
3176
3393
|
exports.LAYOUT_COOKIE = LAYOUT_COOKIE;
|
|
3394
|
+
exports.LOCAL_BRIEFING_POLICY_VERSION = LOCAL_BRIEFING_POLICY_VERSION;
|
|
3177
3395
|
exports.LocalNetworkBar = LocalNetworkBar;
|
|
3178
3396
|
exports.MEET_ACTIVITIES = MEET_ACTIVITIES;
|
|
3179
3397
|
exports.NETWORK_PARENT = NETWORK_PARENT;
|
|
@@ -3181,6 +3399,8 @@ exports.NEWS_CACHE = NEWS_CACHE;
|
|
|
3181
3399
|
exports.NetworkCopyrightNotice = NetworkCopyrightNotice;
|
|
3182
3400
|
exports.NewsError = NewsError;
|
|
3183
3401
|
exports.SESSION_IDLE_MS = SESSION_IDLE_MS;
|
|
3402
|
+
exports.SPONSORSHIP_OFFERINGS = SPONSORSHIP_OFFERINGS;
|
|
3403
|
+
exports.SPONSORSHIP_POLICY = SPONSORSHIP_POLICY;
|
|
3184
3404
|
exports.THEME_COOKIE = THEME_COOKIE;
|
|
3185
3405
|
exports.THEME_EVENT = THEME_EVENT;
|
|
3186
3406
|
exports.THEME_MAX_AGE_SECONDS = THEME_MAX_AGE_SECONDS;
|
|
@@ -3201,6 +3421,7 @@ exports.articleMeta = articleMeta;
|
|
|
3201
3421
|
exports.articleUrl = articleUrl;
|
|
3202
3422
|
exports.attribution = attribution;
|
|
3203
3423
|
exports.briefSummary = briefSummary;
|
|
3424
|
+
exports.campaignReportHtml = campaignReportHtml;
|
|
3204
3425
|
exports.canHostMeetup = canHostMeetup;
|
|
3205
3426
|
exports.categoryLabel = categoryLabel;
|
|
3206
3427
|
exports.classifiedPath = classifiedPath;
|
|
@@ -3210,6 +3431,7 @@ exports.clipChars = clipChars;
|
|
|
3210
3431
|
exports.communityMapEmbeds = communityMapEmbeds;
|
|
3211
3432
|
exports.communityPublications = communityPublications;
|
|
3212
3433
|
exports.composeEdition = composeEdition;
|
|
3434
|
+
exports.composeLocalBriefing = composeLocalBriefing;
|
|
3213
3435
|
exports.dealDollars = dealDollars;
|
|
3214
3436
|
exports.dealGoPath = dealGoPath;
|
|
3215
3437
|
exports.dealsFeedPath = dealsFeedPath;
|
|
@@ -3242,12 +3464,14 @@ exports.listedPublications = listedPublications;
|
|
|
3242
3464
|
exports.llmsText = llmsText;
|
|
3243
3465
|
exports.localPublications = localPublications;
|
|
3244
3466
|
exports.matchesStoryTag = matchesStoryTag;
|
|
3467
|
+
exports.measurementConsent = measurementConsent;
|
|
3245
3468
|
exports.nearbyUpdates = nearbyUpdates;
|
|
3246
3469
|
exports.newsArticleJsonLd = newsArticleJsonLd;
|
|
3247
3470
|
exports.normalizedText = normalizedText;
|
|
3248
3471
|
exports.orderedSections = orderedSections;
|
|
3249
3472
|
exports.parseDocumentBlocks = parseDocumentBlocks;
|
|
3250
3473
|
exports.parseSnapshot = parseSnapshot;
|
|
3474
|
+
exports.placementAvailable = placementAvailable;
|
|
3251
3475
|
exports.prepareClassified = prepareClassified;
|
|
3252
3476
|
exports.prepareJobPost = prepareJobPost;
|
|
3253
3477
|
exports.prepareMeetup = prepareMeetup;
|
|
@@ -3269,6 +3493,7 @@ exports.resolveCoupon = resolveCoupon;
|
|
|
3269
3493
|
exports.resolveEffectiveTheme = resolveEffectiveTheme;
|
|
3270
3494
|
exports.resolveLayout = resolveLayout;
|
|
3271
3495
|
exports.revalidateDecision = revalidateDecision;
|
|
3496
|
+
exports.safeSponsorUrl = safeSponsorUrl;
|
|
3272
3497
|
exports.sanitizeInlineMarkdown = sanitizeInlineMarkdown;
|
|
3273
3498
|
exports.screenMessage = screenMessage;
|
|
3274
3499
|
exports.secretsMatch = secretsMatch;
|