@scalemule/news-publication 0.0.43 → 0.0.45
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/dist/article-blocks-DsabIDmH.d.cts +91 -0
- package/dist/article-blocks-DsabIDmH.d.ts +91 -0
- package/dist/{chunk-DC6RMIYL.js → chunk-2IYKWGVM.js} +1 -1
- package/dist/{chunk-C7JTEHTH.js → chunk-57YVL6BD.js} +1 -1
- package/dist/{chunk-XDGBMMLD.js → chunk-72PKW2HM.js} +1 -1
- package/dist/{chunk-VRDUSIVG.js → chunk-GVLJ3HAI.js} +4 -2
- package/dist/{chunk-EVAGI7C5.js → chunk-OIEO2YVG.js} +1 -1
- package/dist/chunk-OISLCYER.js +235 -0
- package/dist/chunk-UTBV6JJX.js +387 -0
- package/dist/cookie-consent-banner.cjs +38 -16
- package/dist/cookie-consent-banner.js +2 -2
- package/dist/cookie-settings-view.cjs +38 -16
- package/dist/cookie-settings-view.js +2 -2
- package/dist/index.cjs +382 -21
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +11 -9
- package/dist/network-bar.cjs +38 -16
- package/dist/network-bar.js +2 -2
- package/dist/network-copyright.cjs +43 -20
- package/dist/network-copyright.js +2 -2
- package/dist/network.cjs +138 -18
- package/dist/network.d.cts +20 -1
- package/dist/network.d.ts +20 -1
- package/dist/network.js +1 -1
- package/dist/snapshot-file.cjs +1 -1
- package/dist/snapshot-file.js +1 -1
- package/dist/story-review.cjs +890 -537
- package/dist/story-review.d.cts +11 -2
- package/dist/story-review.d.ts +11 -2
- package/dist/story-review.js +703 -537
- package/package.json +4 -4
- package/story-review.css +174 -0
- package/dist/chunk-56TU57OO.js +0 -268
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scalemule/news-publication",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.45",
|
|
4
4
|
"description": "Shared server framework for ScaleMule local news publications. Walnut Creek Times is the broadsheet default; each paper supplies its own identity and feature flags.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
"story-review.css"
|
|
110
110
|
],
|
|
111
111
|
"peerDependencies": {
|
|
112
|
-
"@scalemule/react": "0.0.
|
|
112
|
+
"@scalemule/react": "0.0.21",
|
|
113
113
|
"react": ">=18.0.0"
|
|
114
114
|
},
|
|
115
115
|
"peerDependenciesMeta": {
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
"prepublishOnly": "node -e \"const v=require('./package.json').version; if(!/^0\\.(0|1)\\.\\d+$/.test(v)){console.error('ERR: SDK '+v+' violates patch-only policy (0.0.x or 0.1.x only). See CONTRIBUTING.md SDK versioning section.');process.exit(1)}\" && npm run lint && npm test && npm run build"
|
|
130
130
|
},
|
|
131
131
|
"devDependencies": {
|
|
132
|
-
"@scalemule/react": "0.0.
|
|
132
|
+
"@scalemule/react": "0.0.21",
|
|
133
133
|
"@testing-library/react": "^16.3.3",
|
|
134
134
|
"@types/node": "^22.15.0",
|
|
135
135
|
"@types/react": "^19.1.0",
|
|
@@ -162,7 +162,7 @@
|
|
|
162
162
|
},
|
|
163
163
|
"dependencies": {
|
|
164
164
|
"@scalemule/compliance": "^0.0.5",
|
|
165
|
-
"@scalemule/react": "0.0.
|
|
165
|
+
"@scalemule/react": "0.0.21",
|
|
166
166
|
"@scalemule/sdk": "0.0.75"
|
|
167
167
|
}
|
|
168
168
|
}
|
package/story-review.css
CHANGED
|
@@ -635,3 +635,177 @@
|
|
|
635
635
|
.sm-review-question-list li { padding-left: .4rem; margin: 0 0 1.2rem; line-height: 1.6; }
|
|
636
636
|
.sm-review-email-alternative { border-top: 1px solid var(--sm-review-line, #d7d7d7); padding-top: 1rem; margin-top: 1.5rem; line-height: 1.6; }
|
|
637
637
|
.sm-review-email-alternative a { font-weight: 700; text-decoration: underline; text-underline-offset: .2em; }
|
|
638
|
+
|
|
639
|
+
/* Inline editorial media presentation & structured captions */
|
|
640
|
+
.sm-review-prose .sm-review-inline-figure {
|
|
641
|
+
margin: 36px 0 28px;
|
|
642
|
+
background: var(--pub-soft, #f8f9fa);
|
|
643
|
+
border: 1px solid var(--pub-rule, #e5e7eb);
|
|
644
|
+
border-radius: 8px;
|
|
645
|
+
overflow: hidden;
|
|
646
|
+
padding: 18px;
|
|
647
|
+
}
|
|
648
|
+
.sm-review-prose .sm-review-inline-figure img {
|
|
649
|
+
display: block;
|
|
650
|
+
width: 100%;
|
|
651
|
+
max-height: 720px;
|
|
652
|
+
object-fit: contain;
|
|
653
|
+
margin: 0 auto;
|
|
654
|
+
border-radius: 4px;
|
|
655
|
+
}
|
|
656
|
+
.sm-review-caption-text {
|
|
657
|
+
flex: 1 1 280px;
|
|
658
|
+
}
|
|
659
|
+
.sm-review-artwork-title {
|
|
660
|
+
font-family: var(--font-editorial), Georgia, serif;
|
|
661
|
+
font-size: 19px;
|
|
662
|
+
font-weight: 700;
|
|
663
|
+
color: var(--pub-ink, #171917);
|
|
664
|
+
margin-bottom: 2px;
|
|
665
|
+
}
|
|
666
|
+
.sm-review-artist-name {
|
|
667
|
+
font-size: 15px;
|
|
668
|
+
font-weight: 600;
|
|
669
|
+
color: var(--pub-ink, #171917);
|
|
670
|
+
margin-bottom: 2px;
|
|
671
|
+
}
|
|
672
|
+
.sm-review-artwork-medium {
|
|
673
|
+
font-size: 13px;
|
|
674
|
+
color: var(--pub-muted, #545c55);
|
|
675
|
+
font-style: italic;
|
|
676
|
+
margin-bottom: 4px;
|
|
677
|
+
}
|
|
678
|
+
.sm-review-photo-caption {
|
|
679
|
+
font-size: 14px;
|
|
680
|
+
color: var(--pub-muted, #496076);
|
|
681
|
+
margin-bottom: 4px;
|
|
682
|
+
line-height: 1.5;
|
|
683
|
+
}
|
|
684
|
+
.sm-review-photo-credit {
|
|
685
|
+
font-size: 12px;
|
|
686
|
+
color: var(--pub-muted, #6b7280);
|
|
687
|
+
}
|
|
688
|
+
.sm-review-photo-source {
|
|
689
|
+
font-size: 11px;
|
|
690
|
+
color: var(--pub-muted, #9ca3af);
|
|
691
|
+
margin-top: 2px;
|
|
692
|
+
}
|
|
693
|
+
.sm-review-photo-controls {
|
|
694
|
+
display: flex;
|
|
695
|
+
gap: 8px;
|
|
696
|
+
align-items: center;
|
|
697
|
+
flex-wrap: wrap;
|
|
698
|
+
margin-left: auto;
|
|
699
|
+
}
|
|
700
|
+
.sm-review-suggest-correction {
|
|
701
|
+
background: var(--pub-paper, #fff);
|
|
702
|
+
border: 1px solid var(--pub-rule, #d7dcd7);
|
|
703
|
+
color: var(--pub-ink, #171917);
|
|
704
|
+
border-radius: 4px;
|
|
705
|
+
padding: 8px 12px;
|
|
706
|
+
font-size: 13px;
|
|
707
|
+
font-weight: 600;
|
|
708
|
+
cursor: pointer;
|
|
709
|
+
min-height: 38px;
|
|
710
|
+
}
|
|
711
|
+
.sm-review-suggest-correction:hover {
|
|
712
|
+
background: #f0f2f5;
|
|
713
|
+
}
|
|
714
|
+
@media (max-width: 640px) {
|
|
715
|
+
.sm-review-prose .sm-review-inline-figure {
|
|
716
|
+
margin: 24px -16px;
|
|
717
|
+
padding: 12px;
|
|
718
|
+
border-radius: 0;
|
|
719
|
+
border-left: none;
|
|
720
|
+
border-right: none;
|
|
721
|
+
}
|
|
722
|
+
.sm-review-photo-controls {
|
|
723
|
+
width: 100%;
|
|
724
|
+
margin-top: 8px;
|
|
725
|
+
}
|
|
726
|
+
.sm-review-photo-controls button {
|
|
727
|
+
flex: 1 1 auto;
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
/* Modal overlay and responsive container */
|
|
732
|
+
.sm-review-modal-backdrop {
|
|
733
|
+
position: fixed;
|
|
734
|
+
inset: 0;
|
|
735
|
+
background: rgba(15, 23, 42, 0.65);
|
|
736
|
+
backdrop-filter: blur(4px);
|
|
737
|
+
-webkit-backdrop-filter: blur(4px);
|
|
738
|
+
z-index: 10000;
|
|
739
|
+
display: flex;
|
|
740
|
+
align-items: center;
|
|
741
|
+
justify-content: center;
|
|
742
|
+
padding: 16px;
|
|
743
|
+
overflow-y: auto;
|
|
744
|
+
box-sizing: border-box;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
.sm-review-modal-container {
|
|
748
|
+
width: 100%;
|
|
749
|
+
max-width: 680px;
|
|
750
|
+
max-height: 90vh;
|
|
751
|
+
margin: auto;
|
|
752
|
+
overflow-y: auto;
|
|
753
|
+
background: var(--pub-paper, #ffffff);
|
|
754
|
+
border-radius: 12px;
|
|
755
|
+
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.25), 0 10px 10px -5px rgba(0, 0, 0, 0.1);
|
|
756
|
+
box-sizing: border-box;
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
.sm-review-modal-container .sm-review-form {
|
|
760
|
+
max-width: 100%;
|
|
761
|
+
margin: 0;
|
|
762
|
+
padding: 24px 28px;
|
|
763
|
+
border: none;
|
|
764
|
+
background: transparent;
|
|
765
|
+
box-shadow: none;
|
|
766
|
+
}
|
|
767
|
+
|
|
768
|
+
.sm-review-form-heading {
|
|
769
|
+
display: flex;
|
|
770
|
+
align-items: center;
|
|
771
|
+
justify-content: space-between;
|
|
772
|
+
gap: 16px;
|
|
773
|
+
margin-bottom: 16px;
|
|
774
|
+
padding-bottom: 12px;
|
|
775
|
+
border-bottom: 1px solid var(--pub-rule, #e5e7eb);
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
.sm-review-form-heading h2 {
|
|
779
|
+
margin: 0;
|
|
780
|
+
font-size: 22px;
|
|
781
|
+
line-height: 1.3;
|
|
782
|
+
color: var(--pub-ink, #0f172a);
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
.sm-review-target-preview {
|
|
786
|
+
padding: 12px 16px;
|
|
787
|
+
background: #f8fafc;
|
|
788
|
+
border-radius: 8px;
|
|
789
|
+
border: 1px solid #e2e8f0;
|
|
790
|
+
margin: 10px 0 16px;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
.sm-review-target-preview-title {
|
|
794
|
+
font-size: 14px;
|
|
795
|
+
color: #334155;
|
|
796
|
+
line-height: 1.4;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
@media (max-width: 600px) {
|
|
800
|
+
.sm-review-modal-backdrop {
|
|
801
|
+
padding: 0;
|
|
802
|
+
align-items: flex-end;
|
|
803
|
+
}
|
|
804
|
+
.sm-review-modal-container {
|
|
805
|
+
max-height: 92vh;
|
|
806
|
+
border-radius: 16px 16px 0 0;
|
|
807
|
+
}
|
|
808
|
+
.sm-review-modal-container .sm-review-form {
|
|
809
|
+
padding: 20px 16px max(20px, env(safe-area-inset-bottom));
|
|
810
|
+
}
|
|
811
|
+
}
|
package/dist/chunk-56TU57OO.js
DELETED
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
import { recordConsentToCompliance as recordConsentToCompliance$1, getCookieConsent, decorateNetworkUrl } from '@scalemule/compliance';
|
|
2
|
-
export { 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, acceptAllCookies, checkUrlConsentBridge, clearCookieConsent, decorateNetworkUrl, getCookieConsent, hasConsented, isCategoryAllowed, isGeoConsentRequired, queryNetworkConsentHub, rejectOptionalCookies, setCookieConsent, setNetworkConsentHub } from '@scalemule/compliance';
|
|
3
|
-
|
|
4
|
-
// src/cookies.ts
|
|
5
|
-
async function recordConsentToCompliance(record, options) {
|
|
6
|
-
return recordConsentToCompliance$1(record, options);
|
|
7
|
-
}
|
|
8
|
-
var delegationInstalled = false;
|
|
9
|
-
function setupNetworkConsentDelegation() {
|
|
10
|
-
if (typeof window === "undefined" || delegationInstalled) return;
|
|
11
|
-
delegationInstalled = true;
|
|
12
|
-
document.addEventListener(
|
|
13
|
-
"click",
|
|
14
|
-
(e) => {
|
|
15
|
-
const target = e.target;
|
|
16
|
-
const anchor = target?.closest("a");
|
|
17
|
-
if (!anchor || !anchor.href) return;
|
|
18
|
-
try {
|
|
19
|
-
const url = new URL(anchor.href, window.location.href);
|
|
20
|
-
if (url.protocol !== "http:" && url.protocol !== "https:") return;
|
|
21
|
-
if (isNetworkHostname(url.hostname)) {
|
|
22
|
-
const consent = getCookieConsent();
|
|
23
|
-
if (consent) {
|
|
24
|
-
const decorated = decorateNetworkUrl(anchor.href);
|
|
25
|
-
if (decorated !== anchor.href) {
|
|
26
|
-
anchor.href = decorated;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
} catch {
|
|
31
|
-
}
|
|
32
|
-
},
|
|
33
|
-
{ capture: true }
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
var COOKIE_CATEGORIES = [
|
|
37
|
-
{
|
|
38
|
-
id: "essential",
|
|
39
|
-
title: "Strictly Necessary Cookies",
|
|
40
|
-
shortDescription: "Essential for site security, navigation, and privacy preference management.",
|
|
41
|
-
fullDescription: "These cookies are necessary for the website to function properly and securely. They enable core features such as load balancing, CSRF protection, secure session tokens, and remembering your cookie consent choice. Because the site cannot function without them, they cannot be turned off.",
|
|
42
|
-
required: true,
|
|
43
|
-
cookies: [
|
|
44
|
-
{
|
|
45
|
-
name: "sm_cookie_consent_v1",
|
|
46
|
-
provider: "First-Party (ScaleMule)",
|
|
47
|
-
purpose: "Stores your verified cookie privacy and category consent choices.",
|
|
48
|
-
duration: "1 year",
|
|
49
|
-
type: "HTTP Cookie"
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
name: "napsite_session_v1",
|
|
53
|
-
provider: "First-Party",
|
|
54
|
-
purpose: "Maintains session continuity, security tokens, and server routing.",
|
|
55
|
-
duration: "30 minutes (idle)",
|
|
56
|
-
type: "Session Storage"
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
name: "napsite_preview",
|
|
60
|
-
provider: "First-Party",
|
|
61
|
-
purpose: "Verifies preview access permissions when viewing unpublished newsroom editions.",
|
|
62
|
-
duration: "14 days",
|
|
63
|
-
type: "HTTP Cookie"
|
|
64
|
-
}
|
|
65
|
-
]
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
id: "performance",
|
|
69
|
-
title: "Performance & Analytics Cookies",
|
|
70
|
-
shortDescription: "Help us measure reader engagement, story completion, and site reliability.",
|
|
71
|
-
fullDescription: "These cookies collect anonymous information about how visitors navigate our news publication. They allow us to count article reads, understand scroll depth and reading completion, and identify broken links or slow-loading assets so we can keep our community reporting responsive and fast. All metrics are aggregated and never contain personal information.",
|
|
72
|
-
required: false,
|
|
73
|
-
cookies: [
|
|
74
|
-
{
|
|
75
|
-
name: "napsite_visitor_v1",
|
|
76
|
-
provider: "First-Party",
|
|
77
|
-
purpose: "A randomized anonymous UUIDv7 to count distinct readers without tracking personal identity.",
|
|
78
|
-
duration: "1 year",
|
|
79
|
-
type: "Local Storage"
|
|
80
|
-
},
|
|
81
|
-
{
|
|
82
|
-
name: "napsite_analytics_v1",
|
|
83
|
-
provider: "First-Party",
|
|
84
|
-
purpose: "Connects reading completion and web vitals to the anonymous session.",
|
|
85
|
-
duration: "30 minutes",
|
|
86
|
-
type: "HTTP Cookie"
|
|
87
|
-
}
|
|
88
|
-
]
|
|
89
|
-
},
|
|
90
|
-
{
|
|
91
|
-
id: "functional",
|
|
92
|
-
title: "Functional & Personalization Cookies",
|
|
93
|
-
shortDescription: "Remember your reading preferences, text size, and narration audio settings.",
|
|
94
|
-
fullDescription: "These cookies enable enhanced convenience features designed for readers. They remember your custom text sizing, keep your preferred audio narration playback speed (e.g., 1.0x vs 1.25x), and preserve your local town filters across the front page so you always see news closest to your neighborhood.",
|
|
95
|
-
required: false,
|
|
96
|
-
cookies: [
|
|
97
|
-
{
|
|
98
|
-
name: "reader_text_size",
|
|
99
|
-
provider: "First-Party",
|
|
100
|
-
purpose: "Remembers your preferred reading font size across articles.",
|
|
101
|
-
duration: "1 year",
|
|
102
|
-
type: "Local Storage"
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
name: "news_publication_theme",
|
|
106
|
-
provider: "First-Party",
|
|
107
|
-
purpose: "Remembers your reading theme preference (light, dark, or system).",
|
|
108
|
-
duration: "1 year",
|
|
109
|
-
type: "HTTP Cookie"
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
name: "audio_narration_speed",
|
|
113
|
-
provider: "First-Party",
|
|
114
|
-
purpose: "Stores your preferred audio player playback rate (e.g. 1.0x, 1.25x).",
|
|
115
|
-
duration: "1 year",
|
|
116
|
-
type: "Local Storage"
|
|
117
|
-
}
|
|
118
|
-
]
|
|
119
|
-
},
|
|
120
|
-
{
|
|
121
|
-
id: "advertising",
|
|
122
|
-
title: "Advertising & Local Sponsorship Cookies",
|
|
123
|
-
shortDescription: "Support local business sponsors by capping repetition and measuring notices.",
|
|
124
|
-
fullDescription: "Our journalism is supported by local business sponsors and community partners. These cookies ensure you do not see the same sponsor banner repeatedly (frequency capping) and help local merchants measure whether their announcement reached their community. They never track your activity across unrelated third-party websites or build external advertising profiles.",
|
|
125
|
-
required: false,
|
|
126
|
-
cookies: [
|
|
127
|
-
{
|
|
128
|
-
name: "napsite_sponsor_cap",
|
|
129
|
-
provider: "First-Party",
|
|
130
|
-
purpose: "Prevents repetitive display of identical local business announcements.",
|
|
131
|
-
duration: "7 days",
|
|
132
|
-
type: "Local Storage"
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
name: "local_sponsor_ref",
|
|
136
|
-
provider: "First-Party",
|
|
137
|
-
purpose: "Attributes community inquiries directly to the sponsoring local merchant.",
|
|
138
|
-
duration: "30 days",
|
|
139
|
-
type: "Local Storage"
|
|
140
|
-
}
|
|
141
|
-
]
|
|
142
|
-
}
|
|
143
|
-
];
|
|
144
|
-
|
|
145
|
-
// src/network.ts
|
|
146
|
-
var NETWORK_PARENT = {
|
|
147
|
-
name: "Bay Area News Network",
|
|
148
|
-
url: "https://bayareanewsnetwork.com",
|
|
149
|
-
tagline: "Local stories. Stronger communities.",
|
|
150
|
-
description: "The institutional network of independent local publications covering the San Francisco Bay Area."
|
|
151
|
-
};
|
|
152
|
-
var localPublications = [
|
|
153
|
-
{
|
|
154
|
-
slug: "bayareachronicle",
|
|
155
|
-
name: "Bay Area Chronicle",
|
|
156
|
-
url: "https://bayareachronicle.com",
|
|
157
|
-
area: "San Francisco Bay Area",
|
|
158
|
-
description: "Regional reporting and in-depth investigations covering the nine-county San Francisco Bay Area."
|
|
159
|
-
},
|
|
160
|
-
{
|
|
161
|
-
slug: "concordchronicle",
|
|
162
|
-
name: "Concord Chronicle",
|
|
163
|
-
url: "https://concordchronicle.com",
|
|
164
|
-
area: "Concord",
|
|
165
|
-
description: "A new place for Concord\u2019s local stories, independent businesses and community voices."
|
|
166
|
-
},
|
|
167
|
-
{
|
|
168
|
-
slug: "walnutcreektimes",
|
|
169
|
-
name: "Walnut Creek Times",
|
|
170
|
-
url: "https://walnutcreektimes.com",
|
|
171
|
-
area: "Walnut Creek \xB7 Rossmoor \xB7 Saranap \xB7 Pleasant Hill",
|
|
172
|
-
description: "A new place for Walnut Creek\u2019s local stories, independent businesses and community voices."
|
|
173
|
-
},
|
|
174
|
-
{
|
|
175
|
-
slug: "lamorindapost",
|
|
176
|
-
name: "Lamorinda Post",
|
|
177
|
-
url: "https://lamorindapost.com",
|
|
178
|
-
area: "Orinda \xB7 Lafayette \xB7 Moraga",
|
|
179
|
-
description: "A new home for the neighbors, businesses and community stories of Lamorinda."
|
|
180
|
-
},
|
|
181
|
-
{
|
|
182
|
-
slug: "alamoweekly",
|
|
183
|
-
name: "Alamo Weekly",
|
|
184
|
-
url: "https://alamoweekly.com",
|
|
185
|
-
area: "Alamo",
|
|
186
|
-
description: "A new place for Alamo\u2019s local stories, independent businesses and community voices."
|
|
187
|
-
},
|
|
188
|
-
{
|
|
189
|
-
slug: "danvilletimes",
|
|
190
|
-
name: "Danville Times",
|
|
191
|
-
url: "https://danvilletimes.com",
|
|
192
|
-
area: "Danville",
|
|
193
|
-
description: "A new place for Danville\u2019s local stories, independent businesses and community voices."
|
|
194
|
-
},
|
|
195
|
-
{
|
|
196
|
-
slug: "sanramontimes",
|
|
197
|
-
name: "San Ramon Times",
|
|
198
|
-
url: "https://sanramontimes.com",
|
|
199
|
-
area: "San Ramon",
|
|
200
|
-
description: "A new place for San Ramon\u2019s local stories, independent businesses and community voices."
|
|
201
|
-
},
|
|
202
|
-
{
|
|
203
|
-
slug: "diablovalleynews",
|
|
204
|
-
name: "Diablo Valley News",
|
|
205
|
-
url: "https://diablovalleynews.com",
|
|
206
|
-
area: "Concord \xB7 Walnut Creek \xB7 Pleasant Hill \xB7 Alamo \xB7 Danville \xB7 San Ramon",
|
|
207
|
-
description: "Local stories about the people, businesses and community life of the Diablo Valley."
|
|
208
|
-
},
|
|
209
|
-
{
|
|
210
|
-
slug: "trivalleyweekly",
|
|
211
|
-
name: "Tri-Valley Weekly",
|
|
212
|
-
url: "https://trivalleyweekly.com",
|
|
213
|
-
area: "Alamo \xB7 Danville \xB7 San Ramon \xB7 Dublin \xB7 Pleasanton \xB7 Livermore",
|
|
214
|
-
description: "Local stories about the businesses, people and community life of the Tri-Valley."
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
slug: "eastbaypost",
|
|
218
|
-
name: "East Bay Post",
|
|
219
|
-
url: "https://eastbaypost.com",
|
|
220
|
-
area: "The East Bay",
|
|
221
|
-
description: "A new publication connecting the people and neighborhoods of the East Bay."
|
|
222
|
-
},
|
|
223
|
-
{
|
|
224
|
-
slug: "napagate",
|
|
225
|
-
name: "Napa Gate",
|
|
226
|
-
url: "https://napagate.com",
|
|
227
|
-
area: "Napa Valley",
|
|
228
|
-
description: "A new local publication for the people, places and everyday life of Napa Valley.",
|
|
229
|
-
listed: false
|
|
230
|
-
}
|
|
231
|
-
];
|
|
232
|
-
var listedPublications = localPublications.filter(
|
|
233
|
-
(publication) => !("listed" in publication) || publication.listed
|
|
234
|
-
);
|
|
235
|
-
var communityPublications = listedPublications.filter(
|
|
236
|
-
(publication) => publication.slug !== "bayareachronicle"
|
|
237
|
-
);
|
|
238
|
-
function findPublicationBySlug(slug) {
|
|
239
|
-
return localPublications.find((p) => p.slug === slug);
|
|
240
|
-
}
|
|
241
|
-
function findPublicationByHost(host) {
|
|
242
|
-
const cleanHost = host.replace(/^https?:\/\//, "").replace(/\/.*$/, "").toLowerCase();
|
|
243
|
-
return localPublications.find((p) => {
|
|
244
|
-
const pubHost = p.url.replace(/^https?:\/\//, "").replace(/\/.*$/, "").toLowerCase();
|
|
245
|
-
return pubHost === cleanHost || cleanHost.startsWith(`${p.slug}.`);
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
function getNetworkPublicationUrl(slug) {
|
|
249
|
-
const pub = findPublicationBySlug(slug);
|
|
250
|
-
if (!pub) return null;
|
|
251
|
-
return decorateNetworkUrl(pub.url + "/");
|
|
252
|
-
}
|
|
253
|
-
var NETWORK_HOSTNAMES = new Set(
|
|
254
|
-
localPublications.map((p) => {
|
|
255
|
-
try {
|
|
256
|
-
return new URL(p.url).hostname.replace(/^www\./, "").toLowerCase();
|
|
257
|
-
} catch {
|
|
258
|
-
return `${p.slug}.com`;
|
|
259
|
-
}
|
|
260
|
-
})
|
|
261
|
-
);
|
|
262
|
-
function isNetworkHostname(hostname) {
|
|
263
|
-
if (!hostname) return false;
|
|
264
|
-
const clean = hostname.replace(/^www\./, "").toLowerCase();
|
|
265
|
-
return clean === "bayareanewsnetwork.com" || clean.endsWith(".bayareanewsnetwork.com") || NETWORK_HOSTNAMES.has(clean) || clean.endsWith(".bayareachronicle.com") || clean.endsWith(".napsite.com") || clean.endsWith(".site.scalemule.com");
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
export { COOKIE_CATEGORIES, NETWORK_PARENT, communityPublications, findPublicationByHost, findPublicationBySlug, getNetworkPublicationUrl, isNetworkHostname, listedPublications, localPublications, recordConsentToCompliance, setupNetworkConsentDelegation };
|