@rathnasgala/theme 2.0.17 → 2.0.18

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rathnasgala/theme",
3
- "version": "2.0.17",
3
+ "version": "2.0.18",
4
4
  "description": "Managed Gala static-site theme payload",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -8,7 +8,7 @@
8
8
  "url": "git+https://github.com/rathnasgala/site-template.git"
9
9
  },
10
10
  "gala": {
11
- "sourceCommit": "b1016438e0838f2c17a6884e02f5070a40ebc092"
11
+ "sourceCommit": "1416a9c31af41c6f4634e84c67e9fbf20fa541ed"
12
12
  },
13
13
  "files": [
14
14
  "payload"
@@ -2,7 +2,7 @@
2
2
  "schemaVersion": 1,
3
3
  "themePackage": {
4
4
  "name": "@rathnasgala/theme",
5
- "version": "2.0.17",
5
+ "version": "2.0.18",
6
6
  "availableDesignThemes": [
7
7
  "editorial",
8
8
  "modern",
@@ -11,7 +11,7 @@
11
11
  "securityAdvisories": []
12
12
  },
13
13
  "requiredBudgets": {
14
- "managedJavaScriptBytes": 68608,
14
+ "managedJavaScriptBytes": 70973,
15
15
  "managedCssBytes": 34816
16
16
  },
17
17
  "files": {
@@ -53,10 +53,10 @@
53
53
  "src/assets/engagement-comments.js": "eda0fee471c7e42ee01a25b8aa14ed6ae9690d52b3fbb34027d97534ab62998b",
54
54
  "src/assets/engagement-transport.js": "7f69815c4eb4fc0e127a5c09702da4189130d47b73b4598fce4196d7d6f5cbe8",
55
55
  "src/assets/favicon.svg": "8615e3d96fe37ae9ed14afb1886e7c0e690eef5b10be66ca91cccfd085a74bb6",
56
- "src/assets/interactions.js": "5703833592835b898b47618cfc0e926366d40fb45c1d0468b796b2a6c69c083e",
56
+ "src/assets/interactions.js": "7b907aa0c05f0b5eb2e58cb410214a2129dcbdddc8c530d81f1d340fd90177db",
57
57
  "src/assets/preferences.js": "789127bee013ed6a1bbf8cefd7b9109291c16220e7a6e09314e3c93c54731d1d",
58
58
  "src/assets/prism-session.js": "1fab23725b843006c3f589af7669ef3ad6ad01f3264a3b00564e64b56738d2cd",
59
- "src/assets/reader.js": "6b3ef09e3e1ef00cf3ddfa55872b1c434322ab12a1f0c65908e2623c13d11f1a",
59
+ "src/assets/reader.js": "3afa06aea16d7b3883e34adb367dd73646b42459eab62dc9f6c3940b169c0064",
60
60
  "src/assets/search.js": "df425f0239277792ad39f2138bc89cb66cc4ecda5ed59042d46abc2f05372088",
61
61
  "src/assets/theme-mode.js": "d81af8317b59f6d94dc8154c1dcba9d3e16accb37348bc3fce127712141d6c63",
62
62
  "src/assets/theme.css": "7391086efd6f61791c47bbdf3523d7452e17b1cdb1fc91339861fe2f0a2c884b",
@@ -121,6 +121,15 @@ document.addEventListener('click', async (event) => {
121
121
  return;
122
122
  }
123
123
 
124
+ // FedCM requires the relying party to call navigator.credentials.get synchronously from a
125
+ // top-level user gesture. A click inside the cross-origin session frame followed by postMessage
126
+ // loses that activation before it reaches this page, so the account control owns sign-in.
127
+ const accountControl = event.target.closest('[data-user-control]');
128
+ if (accountControl && !sessionUser && sessionFrameToken) {
129
+ fedCmSession('active');
130
+ return;
131
+ }
132
+
124
133
  const dialogControl = event.target.closest('[data-open-dialog]');
125
134
  if (dialogControl) {
126
135
  const dialog = document.getElementById(dialogControl.dataset.openDialog);
@@ -328,6 +337,33 @@ const sessionOrigin = sessionFrame ? new URL(sessionFrame.src).origin : null;
328
337
  let sessionFrameReady = false;
329
338
  let pendingSessionTransferCode = null;
330
339
  let sessionFrameToken = null;
340
+ let fedCmController = null;
341
+ const FEDCM_GRANT_COOKIE = 'gala-fedcm-grant=1';
342
+
343
+ function hasFedCmGrant() {
344
+ try {
345
+ return document.cookie.split(';').some((value) => value.trim() === FEDCM_GRANT_COOKIE);
346
+ } catch (error) {
347
+ console.warn('Gala could not read this publication\'s FedCM grant marker.', error);
348
+ return false;
349
+ }
350
+ }
351
+
352
+ function rememberFedCmGrant() {
353
+ try {
354
+ document.cookie = 'gala-fedcm-grant=1; Max-Age=31536000; Path=/; SameSite=Strict; Secure';
355
+ } catch (error) {
356
+ console.warn('Gala could not remember this publication\'s FedCM grant.', error);
357
+ }
358
+ }
359
+
360
+ function forgetFedCmGrant() {
361
+ try {
362
+ document.cookie = 'gala-fedcm-grant=; Max-Age=0; Path=/; SameSite=Strict; Secure';
363
+ } catch (error) {
364
+ console.warn('Gala could not clear this publication\'s FedCM grant.', error);
365
+ }
366
+ }
331
367
 
332
368
  function deliverSessionTransfer() {
333
369
  if (!sessionFrameReady || !sessionFrame || !pendingSessionTransferCode) return;
@@ -355,26 +391,40 @@ async function fedCmSession(mode) {
355
391
  if (status) status.textContent = 'FedCM is not available in this browser. Use a current browser to sign in.';
356
392
  return false;
357
393
  }
394
+ if (fedCmController) {
395
+ if (mode === 'passive') return false;
396
+ fedCmController.abort();
397
+ }
398
+ const controller = new AbortController();
399
+ fedCmController = controller;
358
400
  try {
359
401
  const siteId = new URL(sessionFrame.src).searchParams.get('siteId') ?? '';
360
402
  const provider = {
361
403
  configURL: 'https://api.gala67.com/v1/fedcm/config.json',
362
404
  clientId: siteId,
405
+ fields: ['name', 'email'],
363
406
  params: { nonce: sessionFrameToken }
364
407
  };
365
- if (mode === 'active') provider.mode = 'active';
408
+ const identity = { providers: [provider] };
409
+ if (mode === 'active') identity.mode = 'active';
366
410
  const credential = await navigator.credentials.get({
367
- identity: { providers: [provider] },
368
- mediation: mode === 'active' ? 'required' : 'silent'
411
+ identity,
412
+ mediation: mode === 'active' ? 'required' : 'silent',
413
+ signal: controller.signal
369
414
  });
370
415
  if (typeof credential?.token !== 'string') return false;
416
+ if (mode === 'active') rememberFedCmGrant();
371
417
  pendingSessionTransferCode = credential.token;
372
418
  deliverSessionTransfer();
373
419
  return true;
374
420
  } catch (error) {
375
- if (error?.name !== 'NotAllowedError') console.error('Gala FedCM sign-in failed.', error);
421
+ if (mode === 'active' && error?.name !== 'NotAllowedError' && error?.name !== 'AbortError') {
422
+ console.error('Gala FedCM sign-in failed.', error);
423
+ }
376
424
  if (mode === 'active' && status) status.textContent = 'Sign-in did not finish. Try again.';
377
425
  return false;
426
+ } finally {
427
+ if (fedCmController === controller) fedCmController = null;
378
428
  }
379
429
  }
380
430
 
@@ -499,6 +549,13 @@ async function mutateEngagement(region, operation, payload) {
499
549
  if (sessionFrame) {
500
550
  window.addEventListener('message', (event) => {
501
551
  if (event.origin !== sessionOrigin || event.source !== sessionFrame.contentWindow) return;
552
+ if (event.data?.type === 'gala-fedcm-sign-out') {
553
+ forgetFedCmGrant();
554
+ navigator.credentials?.preventSilentAccess?.().catch((error) => {
555
+ console.error('Gala could not disable silent FedCM access after sign-out.', error);
556
+ });
557
+ return;
558
+ }
502
559
  if (event.data?.type === 'gala-engagement-result') {
503
560
  const pending = pendingEngagementWrites.get(event.data.requestId);
504
561
  if (!pending) return;
@@ -532,7 +589,10 @@ if (sessionFrame) {
532
589
  }
533
590
  if (event.data?.type !== 'gala-session') return;
534
591
  sessionFrameReady = true;
535
- if (typeof event.data.frameToken === 'string') sessionFrameToken = event.data.frameToken;
592
+ if (typeof event.data.frameToken === 'string') {
593
+ sessionFrameToken = event.data.frameToken;
594
+ document.querySelector('[data-user-control]')?.setAttribute('data-fedcm-ready', 'true');
595
+ }
536
596
  if (pendingSessionTransferCode) deliverSessionTransfer();
537
597
  sessionUser = event.data.user && typeof event.data.user.id === 'string' ? event.data.user : null;
538
598
  const control = document.querySelector('[data-user-control]');
@@ -564,11 +624,6 @@ if (sessionFrame) {
564
624
  });
565
625
  // Signed in on the back of an interrupted action: finish what they were doing.
566
626
  if (sessionUser && pendingIntent) resumeIntent();
567
- if (!sessionUser && sessionFrameToken) fedCmSession('passive');
627
+ if (!sessionUser && sessionFrameToken && hasFedCmGrant()) fedCmSession('passive');
568
628
  });
569
629
  }
570
-
571
- window.addEventListener('message', (event) => {
572
- if (event.origin !== sessionOrigin || event.source !== sessionFrame?.contentWindow) return;
573
- if (event.data?.type === 'gala-fedcm-sign-in') fedCmSession('active');
574
- });
@@ -1,2 +1,2 @@
1
- (()=>{var I=["system","light","dark"],G="gala-color-mode";function P(){let e=document.documentElement.dataset.mode;return I.includes(e)?e:"system"}function oe(){try{let e=localStorage.getItem(G);if(I.includes(e))return e}catch{return P()}return P()}function H(e){document.documentElement.dataset.mode=e;let n=I[(I.indexOf(e)+1)%I.length];document.querySelectorAll("[data-theme-mode-toggle]").forEach(t=>{let a=t.querySelector?.("[data-theme-mode-label]");a?a.textContent=`Theme: ${e}`:t.textContent=`Theme: ${e}`,t.setAttribute("aria-label",`Color mode: ${e}. Activate for ${n}.`)})}document.addEventListener("DOMContentLoaded",()=>{H(oe()),document.querySelectorAll("[data-theme-mode-toggle]").forEach(e=>{e.addEventListener("click",()=>{let n=I[(I.indexOf(document.documentElement.dataset.mode)+1)%I.length];try{localStorage.setItem(G,n)}catch{}H(n)})})});var j="gala-language-preference";function se(){try{return localStorage.getItem(j)}catch{return null}}function $(e,n){return[...e.options].find(t=>t.value===n)}document.addEventListener("DOMContentLoaded",()=>{let e=se();document.querySelectorAll("[data-language-preference]").forEach(n=>{e!=null&&$(n,e)!=null&&(n.value=e),n.addEventListener("change",()=>{try{localStorage.setItem(j,n.value)}catch{}if(!n.hasAttribute("data-navigate-on-selection"))return;let t=$(n,n.value);t?.dataset.url&&window.location.assign(t.dataset.url)})})});var B="gala.prism.session.v1";document.addEventListener("click",e=>{if(e.target.closest("[data-prism-restore]")){try{sessionStorage.removeItem(B)}catch{}return}let t=e.target.closest("[data-prism-select]");if(t)try{sessionStorage.setItem(B,JSON.stringify({articleId:t.dataset.prismArticleId,language:t.dataset.prismLanguage,configurationId:t.dataset.prismConfigurationId,sourceRevisionHash:t.dataset.prismSourceHash,selectedAt:new Date().toISOString()}))}catch{}});function L(e){let n=e.closest(".gala-share"),t=n?.querySelector(".gala-share__fallback");t?.classList.add("gala-share__fallback--visible"),t?.focus(),t?.select();let a=n?.querySelector(".gala-share__status");a&&(a.textContent="Select and copy the URL shown.")}var W=document.querySelector("[data-reading-progress]"),U=document.querySelector(".gala-markdown");if(W&&U){let e=null,n=()=>{e=null;let a=U.offsetTop,r=Math.max(1,U.offsetHeight-window.innerHeight),l=Math.min(1,Math.max(0,(window.scrollY-a)/r));W.value=l},t=()=>{e==null&&(e=requestAnimationFrame(n))};addEventListener("scroll",t,{passive:!0}),addEventListener("resize",t,{passive:!0}),t()}var T=document.querySelector(".gala-toc");if(T?.tagName==="DETAILS"){let e=T.querySelector("nav"),n=[...T.querySelectorAll('a[href^="#"]')],t=n.map(m=>document.getElementById(m.hash.slice(1))).filter(Boolean),a=null,r=()=>{if(a=null,T.classList.toggle("gala-toc--floating",T.getBoundingClientRect().top<=96),!t.length)return;let m=window.innerHeight*.42,f=t[0];for(let s of t)if(s.getBoundingClientRect().top<=m)f=s;else break;let E=n.find(s=>s.hash===`#${f.id}`);for(let s of n)s===E?s.setAttribute("aria-current","location"):s.removeAttribute("aria-current");if(e&&n.length){let s=n[0].getBoundingClientRect(),o=n[n.length-1].getBoundingClientRect();T.classList.toggle("gala-toc--overflowing",o.bottom-s.top>e.clientHeight)}if(E&&e&&e.scrollHeight>e.clientHeight){let s=e.getBoundingClientRect(),o=E.getBoundingClientRect(),i=e.scrollTop+o.top-s.top-(e.clientHeight-o.height)/2;e.scrollTo({top:Math.max(0,i),behavior:"auto"})}},l=()=>{a==null&&(a=requestAnimationFrame(r))};addEventListener("scroll",l,{passive:!0}),addEventListener("resize",l,{passive:!0}),l()}var Y=document.querySelector(".gala-action-rail"),V=document.querySelector("[data-action-dock]");if(Y&&V){let e=n=>{Y.classList.toggle("gala-action-rail--integrated",n[0].isIntersecting)};new IntersectionObserver(e,{rootMargin:"0px 0px 18% 0px",threshold:0}).observe(V)}function X(e,n){let t=n?"Unfollow article":"Follow article";e.setAttribute("aria-pressed",String(n)),e.setAttribute("aria-label",t),e.title=t;let a=e.querySelector("[data-follow-label]");a&&(a.textContent=t)}document.addEventListener("click",async e=>{if(e.target instanceof HTMLDialogElement&&e.target.open){let s=e.target.getBoundingClientRect();if(e.clientX<s.left||e.clientX>s.right||e.clientY<s.top||e.clientY>s.bottom){e.target.close();return}}let n=e.target.closest("[data-gala-embed-load]");if(n){let s=n.closest("[data-gala-embed]"),o=n.dataset.galaEmbedSrc,i=n.dataset.galaEmbedLoad;if(!s||!o||!["youtube","codepen"].includes(i))return;let d=document.createElement("iframe");d.src=o,d.title=i==="youtube"?"YouTube video":"CodePen example",d.loading="eager",d.referrerPolicy="strict-origin-when-cross-origin",d.setAttribute("sandbox","allow-forms allow-popups allow-presentation allow-same-origin allow-scripts"),d.setAttribute("allow",i==="youtube"?"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture; web-share":"fullscreen"),d.setAttribute("allowfullscreen",""),s.replaceChildren(d);return}let t=e.target.closest("[data-open-dialog]");if(t){let s=document.getElementById(t.dataset.openDialog);s instanceof HTMLDialogElement&&s.showModal();return}let a=e.target.closest("[data-reaction]");if(a){let s=a.closest("[data-engagement-url]");if(!s)return;if(!w)return k({kind:"reaction",region:s,selector:`[data-reaction="${a.dataset.reaction}"]`});let o=a.getAttribute("aria-pressed")!=="true";if(!await z(s,o?"reaction.add":"reaction.remove",{articleId:s.dataset.articleId,reaction:a.dataset.reaction}))return;a.setAttribute("aria-pressed",String(o));return}let r=e.target.closest("[data-follow-article]");if(r){let s=r.closest("[data-engagement-url]");if(!s)return;if(!w)return k({kind:"follow",region:s,selector:"[data-follow-article]"});let o=r.getAttribute("aria-pressed")!=="true";if(!await z(s,o?"follow.add":"follow.remove",{targetType:"articles",targetId:s.dataset.articleId}))return;X(r,o);return}let l=e.target.closest("[data-copy-url]");if(l){let s=l.dataset.copyUrl;if(!window.isSecureContext||!navigator.clipboard?.writeText){L(l);return}try{await navigator.clipboard.writeText(s);let o=l.closest(".gala-share")?.querySelector(".gala-share__status");o&&(o.textContent="Link copied.")}catch{L(l)}return}let m=e.target.closest("[data-native-share]");if(m){if(navigator.share)try{await navigator.share({title:document.title,url:m.dataset.nativeShare})}catch(s){s.name!=="AbortError"&&L(m)}else L(m);return}let f=e.target.closest("[data-copy-code]");if(!f)return;let E=f.closest(".gala-code-block")?.querySelector("code");if(!(!E||!navigator.clipboard?.writeText||!window.isSecureContext))try{await navigator.clipboard.writeText(E.textContent),f.textContent="Copied"}catch{f.textContent="Select code to copy"}});var ie=new Set([...document.querySelectorAll("pre code")].map(e=>e.closest("pre")).filter(Boolean));ie.forEach(e=>{let n=document.createElement("div");n.className="gala-code-block",e.before(n),n.append(e);let t=document.createElement("button");t.type="button",t.dataset.copyCode="",t.textContent="Copy code",t.setAttribute("aria-label","Copy code block"),n.prepend(t)});function ce(e){return[["Reactions",Object.values(e.reactions??{}).reduce((t,a)=>t+(Number.isSafeInteger(a)?a:0),0)],["Comments",Number.isSafeInteger(e.comments?.totalCount)?e.comments.totalCount:0],["Views",Number.isSafeInteger(e.views?.count)?e.views.count:0]]}function le(e){return e<1e3?"<1K":new Intl.NumberFormat("en",{notation:"compact",maximumFractionDigits:1}).format(e)}function de(e,n){let t=n?.data;if(!t||typeof t!="object")throw new TypeError("Engagement data is invalid");for(let[a,r]of ce(t))e.querySelectorAll(`[data-engagement-stat="${a.toLowerCase()}"]`).forEach(l=>{l.textContent=le(r),l.closest("div")?.setAttribute("title",`${r} ${a.toLowerCase()}`)});e.querySelector("[data-engagement-snapshot]")?.remove(),e.querySelector(".gala-engagement__placeholder")?.remove()}async function D(e,n="",t=!1,a=!1){let r=e.querySelector("[data-engagement-status]"),l=!!e.querySelector("[data-gala-comments]");try{let m=new URL(e.dataset.engagementUrl);n&&m.searchParams.set("commentsCursor",n);let f=await fetch(m,{headers:{Accept:"application/json"},credentials:"omit",cache:a?"no-store":"default"});if(!f.ok)throw new Error(`Engagement returned HTTP ${f.status}`);let E=await f.json();de(e,E),r&&!l&&(r.textContent=E.errors?.length?"Some engagement data is temporarily unavailable.":"")}catch{r&&!l&&(r.textContent="Engagement is temporarily unavailable.")}}function ue(){let e=new URL(window.location.href).searchParams,n={};for(let t of["utm_source","utm_medium","utm_campaign","utm_content","utm_term"]){let a=e.get(t);a&&[...a].length<=128&&(n[t]=a)}return n}function me(e){let n=new URL(e.dataset.engagementUrl);n.pathname=n.pathname.replace(/\/engagement$/,"/views"),fetch(n,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({language:document.documentElement.lang||void 0,referrer:document.referrer||void 0,campaign:ue()}),credentials:"omit",keepalive:!0}).catch(()=>{})}document.addEventListener("gala-request-sign-in",e=>{w||C||k({kind:e.detail?.kind??"comment"})});var w=null,Q=null,N=null,q=new Map,C=null,y=document.querySelector("[data-gala-session-frame]"),_=y?new URL(y.src).origin:null,J=!1,v=null,R=null;function Z(){!J||!y||!v||(y.contentWindow?.postMessage({type:"gala-session-transfer",transferCode:v},_),v=null)}function K(){y?.contentWindow?.postMessage({type:"gala-session-request"},_)}y&&(y.addEventListener("load",K),K());async function M(e){let n=document.querySelector("[data-engagement-status]");if(!R)return!1;if(!globalThis.IdentityCredential||typeof navigator.credentials?.get!="function")return n&&(n.textContent="FedCM is not available in this browser. Use a current browser to sign in."),!1;try{let a={configURL:"https://api.gala67.com/v1/fedcm/config.json",clientId:new URL(y.src).searchParams.get("siteId")??"",params:{nonce:R}};e==="active"&&(a.mode="active");let r=await navigator.credentials.get({identity:{providers:[a]},mediation:e==="active"?"required":"silent"});return typeof r?.token!="string"?!1:(v=r.token,Z(),!0)}catch(t){return t?.name!=="NotAllowedError"&&console.error("Gala FedCM sign-in failed.",t),e==="active"&&n&&(n.textContent="Sign-in did not finish. Try again."),!1}}function k(e){let n=e.field;C={kind:e.kind,region:e.region,selector:e.selector,draft:n?n.value:null,caret:n?n.selectionStart:null},n&&n.blur(),M("active").then(t=>{t||(C=null)})}function ge(){let e=C;if(!e||!document.hasFocus())return;let n=e.region?.querySelector(e.selector);if(n){if(C=null,e.kind==="comment"){e.draft!=null&&n.value===""&&(n.value=e.draft),n.focus(),e.caret!=null&&typeof n.setSelectionRange=="function"&&n.setSelectionRange(e.caret,e.caret);return}n.click()}}document.querySelectorAll("[data-engagement-url]").forEach(e=>{D(e),me(e)});function ee(e){return e==="AUTHENTICATION_REQUIRED"||e==="INVALID_BEARER_TOKEN"||e==="REAUTHENTICATION_REQUIRED"?"Sign in again to continue.":e==="ENGAGEMENT_RATE_LIMITED"?"You are posting too quickly; try again shortly.":e==="CONTACT_RATE_LIMITED"?"You are sending too quickly; try again later.":e==="RESOURCE_NOT_FOUND"?"That item is no longer available.":e==="INVALID_ENGAGEMENT_WRITE"||e==="INVALID_CONTACT_SUBMISSION"||e==="INVALID_REQUEST"?"Check your entry and try again.":e==="ACCESS_DENIED"?"That action is not available for this account.":e==="IDEMPOTENCY_CONFLICT"||e==="ENGAGEMENT_STATE_CONFLICT"?"The item changed; reload and try again.":"The action could not be completed. Try again."}function te(e,n){if(!y||!w)return Promise.reject(new Error("AUTHENTICATION_REQUIRED"));let t=crypto.randomUUID();return new Promise((a,r)=>{let l=setTimeout(()=>{q.delete(t),r(new Error("REQUEST_TIMEOUT"))},1e4);q.set(t,{resolve:m=>{clearTimeout(l),a(m)},reject:m=>{clearTimeout(l),r(m)}}),y.contentWindow.postMessage({type:"gala-engagement-write",requestId:t,operation:e,payload:n},new URL(y.src).origin)})}document.addEventListener("submit",async e=>{let n=e.target.closest("[data-contact-form] form");if(!n)return;e.preventDefault();let t=n.closest("[data-contact-form]"),a=t.querySelector("[data-contact-status]");if(!w){a.textContent="Sign in with the account button before sending.";return}let r=new FormData(n);try{a.textContent="Sending\u2026",await te("contact.submit",{siteId:t.dataset.siteId,subject:r.get("subject"),message:r.get("message"),website:r.get("website")||null,phone:r.get("phone")||null}),n.reset(),a.textContent="Message sent."}catch(l){a.textContent=ee(l.message)}});async function z(e,n,t){let a=e.querySelector("[data-engagement-status]");try{return a&&(a.textContent="Saving\u2026"),await te(n,t),a&&(a.textContent="Saved."),await D(e,"",!1,!0),!0}catch(r){return a&&(a.textContent=ee(r.message)),!1}}y&&window.addEventListener("message",e=>{if(e.origin!==_||e.source!==y.contentWindow)return;if(e.data?.type==="gala-engagement-result"){let r=q.get(e.data.requestId);if(!r)return;q.delete(e.data.requestId),e.data.ok===!0?r.resolve(e.data.result):r.reject(new Error(e.data.error?.code||"ENGAGEMENT_WRITE_FAILED"));return}if(e.data?.type==="gala-reader-state-result"){if(e.data.requestId!==N||e.data.ok!==!0)return;N=null;let r=new Set(Array.isArray(e.data.state?.reactions)?e.data.state.reactions:[]);document.querySelectorAll("[data-reaction]").forEach(l=>{l.setAttribute("aria-pressed",String(r.has(l.dataset.reaction)))}),document.querySelectorAll("[data-follow-article]").forEach(l=>{let m=e.data.state?.following===!0;X(l,m)});return}if(e.data?.type==="gala-session-height"){let r=Number(e.data.height);Number.isFinite(r)&&r>0&&r<2e3&&(y.height=String(Math.ceil(r)));return}if(e.data?.type!=="gala-session")return;J=!0,typeof e.data.frameToken=="string"&&(R=e.data.frameToken),v&&Z(),w=e.data.user&&typeof e.data.user.id=="string"?e.data.user:null;let n=document.querySelector("[data-user-control]"),t=w?.displayName;if(n){n.setAttribute("aria-label",t?`Account: ${t}`:"Sign in or view account"),n.title=t?`Account: ${t}`:"Account";let r=n.querySelector("[data-user-label]");r&&(r.textContent=t||"Sign in")}let a=Q!==(w?.id??null);if(Q=w?.id??null,w){let r=document.querySelector("[data-article-id]");r&&(N=crypto.randomUUID(),y.contentWindow.postMessage({type:"gala-reader-state-request",requestId:N,articleId:r.dataset.articleId},_))}document.querySelectorAll("[data-engagement-url]").forEach(r=>{a&&D(r)}),w&&C&&ge(),!w&&R&&M("passive")});window.addEventListener("message",e=>{e.origin!==_||e.source!==y?.contentWindow||e.data?.type==="gala-fedcm-sign-in"&&M("active")});document.querySelectorAll("[data-gala-search]").forEach(e=>{let n=e.querySelector("form"),t=n?.elements.namedItem("q"),a=e.querySelector("[data-search-status]"),r=e.querySelector("[data-search-results]"),l=e.dataset.indexUrl,m,f=i=>String(i??"").normalize("NFKC").toLocaleLowerCase();function E(i,d){r.replaceChildren();for(let u of i){let p=document.createElement("li"),c=document.createElement("article"),h=document.createElement("h2"),b=document.createElement("a");if(b.href=u.url,b.lang=u.language,b.textContent=u.title,h.append(b),c.append(h),u.description){let F=document.createElement("p");F.textContent=u.description,c.append(F)}p.append(c),r.append(p)}a.textContent=`${i.length} result${i.length===1?"":"s"} for \u201C${d}\u201D.`}async function s(i){let d=i.trim();if(d===""){r.replaceChildren(),a.textContent="Enter a search term.";return}a.textContent="Searching\u2026";try{m??=fetch(l,{headers:{Accept:"application/json"}}).then(async c=>{if(!c.ok)throw new Error(`Search index returned HTTP ${c.status}`);let h=await c.json();if(h?.schemaVersion!==1||!Array.isArray(h.entries))throw new TypeError("Search index schema is unsupported");return h.entries});let u=f(d),p=(await m).filter(c=>f([c.title,c.description,c.language,...Array.isArray(c.tags)?c.tags:[],c.body].join(`
2
- `)).includes(u));E(p,d)}catch{r.replaceChildren(),a.textContent="Search is temporarily unavailable."}}n?.addEventListener("submit",i=>{i.preventDefault();let d=t.value,u=new URL(window.location.href);d.trim()===""?u.searchParams.delete("q"):u.searchParams.set("q",d),window.history.replaceState(null,"",u),s(d)});let o=new URLSearchParams(window.location.search).get("q")??"";t&&(t.value=o),s(o)});var S={value:null},A=document.querySelector("[data-gala-session-frame]"),ne=A?new URL(A.src).origin:null,x=new Map;function ae(e){return e==="AUTHENTICATION_REQUIRED"||e==="INVALID_BEARER_TOKEN"||e==="REAUTHENTICATION_REQUIRED"?"Sign in again to continue.":e==="ENGAGEMENT_RATE_LIMITED"?"You are posting too quickly; try again shortly.":e==="CONTACT_RATE_LIMITED"?"You are sending too quickly; try again later.":e==="RESOURCE_NOT_FOUND"?"That item is no longer available.":e==="INVALID_ENGAGEMENT_WRITE"||e==="INVALID_CONTACT_SUBMISSION"||e==="INVALID_REQUEST"?"Check your entry and try again.":e==="ACCESS_DENIED"?"That action is not available for this account.":e==="IDEMPOTENCY_CONFLICT"||e==="ENGAGEMENT_STATE_CONFLICT"?"The item changed; reload and try again.":"The action could not be completed. Try again."}function re(e,n){if(!A||!S.value)return Promise.reject(new Error("AUTHENTICATION_REQUIRED"));let t=crypto.randomUUID();return new Promise((a,r)=>{let l=setTimeout(()=>{x.delete(t),r(new Error("REQUEST_TIMEOUT"))},1e4);x.set(t,{resolve:m=>{clearTimeout(l),a(m)},reject:m=>{clearTimeout(l),r(m)}}),A.contentWindow.postMessage({type:"gala-engagement-write",requestId:t,operation:e,payload:n},ne)})}function O(e){document.dispatchEvent(new CustomEvent("gala-request-sign-in",{detail:e}))}A&&window.addEventListener("message",e=>{if(e.origin!==ne||e.source!==A.contentWindow)return;if(e.data?.type==="gala-engagement-result"){let t=x.get(e.data.requestId);if(!t)return;x.delete(e.data.requestId),e.data.ok===!0?t.resolve(e.data.result):t.reject(new Error(e.data.error?.code||"ENGAGEMENT_WRITE_FAILED"));return}if(e.data?.type!=="gala-session")return;let n=e.data.user;S.value=n&&typeof n.id=="string"?n:null,window.dispatchEvent(new CustomEvent("gala-session-change"))});var fe=5,g=(e,n,t)=>{let a=document.createElement(e);return n&&(a.className=n),t!==void 0&&(a.textContent=t),a};function pe(e){let n=new Map;for(let a of e){let r=a.parentCommentId??"";n.has(r)||n.set(r,[]),n.get(r).push(a)}let t=(a,r)=>(n.get(a)??[]).map(l=>({...l,depth:r,replies:t(l.commentId,r+1)}));return t("",0)}function he(e,n){let t={items:[],cursor:null,total:0,busy:!1,status:"",phase:"loading"},a=/\/v1\/articles\/([^/]+)\/engagement/.exec(n)?.[1]??"",r=e.closest(".gala-conversation")?.querySelector("[data-engagement-status]");async function l(o="",{append:i=!1,fresh:d=!1}={}){let u=new URL(n);o&&u.searchParams.set("commentsCursor",o);let p=await fetch(u,{headers:{Accept:"application/json"},credentials:"omit",cache:d?"no-store":"default"});if(!p.ok)throw new Error(`Comments returned HTTP ${p.status}`);let c=(await p.json())?.data?.comments;if(!c||!Array.isArray(c.items))throw new TypeError("Comment page is invalid");t.items=i?[...t.items,...c.items]:c.items,t.cursor=c.nextCursor??null,Number.isSafeInteger(c.totalCount)&&(t.total=c.totalCount)}async function m(o,i){if(!S.value)return O({kind:"comment"}),!1;t.busy=!0,t.status="",s();try{return await re(o,i),await l("",{fresh:!0}),!0}catch(d){return t.status=ae(d.message),!1}finally{t.busy=!1,s()}}function f(o,i,d){let u=g("form","gala-comment__form"),p=g("textarea");p.rows=3,p.value=i,p.placeholder=o,p.setAttribute("aria-label",o);let c=g("button","","Post");return c.type="submit",c.disabled=t.busy,u.append(p,c),u.addEventListener("submit",async h=>{h.preventDefault();let b=p.value.trim();b&&await d(b)&&(p.value="")}),u}function E(o){let i=g("li","gala-comment");i.dataset.commentId=o.commentId,i.dataset.depth=o.depth;let d=g("p","gala-comment__meta");if(d.append(g("strong","",o.author?.displayName??"[deleted]")),o.createdAt){let u=g("time","",new Date(o.createdAt).toLocaleDateString());u.dateTime=o.createdAt,d.append(u)}if(i.append(d,g("p","gala-comment__body",o.deleted?"[deleted]":o.body)),!o.deleted){let u=g("div","gala-comment-actions");if(o.depth<fe){let c=g("button","","Reply");c.type="button",c.dataset.replyComment=o.commentId,c.addEventListener("click",()=>{let h=i.querySelector(":scope > .gala-comment__form");if(h){h.remove();return}u.after(f(`Reply to ${o.author?.displayName??"this comment"}`,"",b=>m("comment.create",{articleId:a,parentCommentId:o.commentId,body:b})))}),u.append(c)}if(S.value&&o.author?.userId===S.value.id){let c=g("button","","Edit");c.type="button",c.dataset.editComment=o.commentId,c.addEventListener("click",()=>u.after(f("Edit your comment",o.body??"",b=>m("comment.edit",{articleId:a,commentId:o.commentId,body:b}))));let h=g("button","","Delete");h.type="button",h.dataset.deleteComment=o.commentId,h.addEventListener("click",()=>m("comment.delete",{articleId:a,commentId:o.commentId})),u.append(c,h)}else{let c=g("button","","Report");c.type="button",c.dataset.reportComment=o.commentId,c.addEventListener("click",()=>m("comment.report",{articleId:a,commentId:o.commentId,reason:"OTHER"})),u.append(c)}i.append(u)}if(o.replies.length){let u=g("ol","gala-comment-replies");u.append(...o.replies.map(E)),i.append(u)}return i}function s(){if(r&&(r.textContent=t.phase==="loading"?"Loading comments\u2026":t.phase==="unavailable"?"Comments are temporarily unavailable.":t.status),t.phase!=="ready"){e.replaceChildren();return}let o=g("section","gala-comments-island");if(o.setAttribute("aria-label","Comments"),o.append(g("p","gala-comments__heading",t.total===1?"1 comment":`${t.total} comments`)),S.value)o.append(f("Add a comment","",i=>m("comment.create",{articleId:a,body:i})));else{let i=g("p","gala-comments__prompt"),d=g("button","","Sign in to join the conversation");d.type="button",d.addEventListener("click",()=>O({kind:"comment"})),i.append(d),o.append(i)}if(!t.items.length)o.append(g("p","gala-comments__empty","No comments yet."));else{let i=g("ol","gala-comments");i.append(...pe(t.items).map(E)),o.append(i)}if(t.cursor){let i=g("button","gala-comments__more","Show more comments");i.type="button",i.disabled=t.busy,i.addEventListener("click",async()=>{t.busy=!0,t.status="Loading more comments\u2026",s();try{await l(t.cursor,{append:!0}),t.status=""}catch{t.status="More comments couldn\u2019t be loaded. Try again."}t.busy=!1,s()}),o.append(i)}e.replaceChildren(o)}window.addEventListener("gala-session-change",s),s(),l().then(()=>{t.phase="ready"}).catch(()=>{t.phase="unavailable"}).finally(s)}document.querySelectorAll("[data-gala-comments]").forEach(e=>{let n=e.closest("[data-engagement-url]")?.dataset.engagementUrl;n&&he(e,n)});})();
1
+ (()=>{var S=["system","light","dark"],$="gala-color-mode";function P(){let e=document.documentElement.dataset.mode;return S.includes(e)?e:"system"}function se(){try{let e=localStorage.getItem($);if(S.includes(e))return e}catch{return P()}return P()}function H(e){document.documentElement.dataset.mode=e;let a=S[(S.indexOf(e)+1)%S.length];document.querySelectorAll("[data-theme-mode-toggle]").forEach(t=>{let r=t.querySelector?.("[data-theme-mode-label]");r?r.textContent=`Theme: ${e}`:t.textContent=`Theme: ${e}`,t.setAttribute("aria-label",`Color mode: ${e}. Activate for ${a}.`)})}document.addEventListener("DOMContentLoaded",()=>{H(se()),document.querySelectorAll("[data-theme-mode-toggle]").forEach(e=>{e.addEventListener("click",()=>{let a=S[(S.indexOf(document.documentElement.dataset.mode)+1)%S.length];try{localStorage.setItem($,a)}catch{}H(a)})})});var B="gala-language-preference";function ie(){try{return localStorage.getItem(B)}catch{return null}}function j(e,a){return[...e.options].find(t=>t.value===a)}document.addEventListener("DOMContentLoaded",()=>{let e=ie();document.querySelectorAll("[data-language-preference]").forEach(a=>{e!=null&&j(a,e)!=null&&(a.value=e),a.addEventListener("change",()=>{try{localStorage.setItem(B,a.value)}catch{}if(!a.hasAttribute("data-navigate-on-selection"))return;let t=j(a,a.value);t?.dataset.url&&window.location.assign(t.dataset.url)})})});var W="gala.prism.session.v1";document.addEventListener("click",e=>{if(e.target.closest("[data-prism-restore]")){try{sessionStorage.removeItem(W)}catch{}return}let t=e.target.closest("[data-prism-select]");if(t)try{sessionStorage.setItem(W,JSON.stringify({articleId:t.dataset.prismArticleId,language:t.dataset.prismLanguage,configurationId:t.dataset.prismConfigurationId,sourceRevisionHash:t.dataset.prismSourceHash,selectedAt:new Date().toISOString()}))}catch{}});function L(e){let a=e.closest(".gala-share"),t=a?.querySelector(".gala-share__fallback");t?.classList.add("gala-share__fallback--visible"),t?.focus(),t?.select();let r=a?.querySelector(".gala-share__status");r&&(r.textContent="Select and copy the URL shown.")}var Y=document.querySelector("[data-reading-progress]"),U=document.querySelector(".gala-markdown");if(Y&&U){let e=null,a=()=>{e=null;let r=U.offsetTop,o=Math.max(1,U.offsetHeight-window.innerHeight),i=Math.min(1,Math.max(0,(window.scrollY-r)/o));Y.value=i},t=()=>{e==null&&(e=requestAnimationFrame(a))};addEventListener("scroll",t,{passive:!0}),addEventListener("resize",t,{passive:!0}),t()}var I=document.querySelector(".gala-toc");if(I?.tagName==="DETAILS"){let e=I.querySelector("nav"),a=[...I.querySelectorAll('a[href^="#"]')],t=a.map(d=>document.getElementById(d.hash.slice(1))).filter(Boolean),r=null,o=()=>{if(r=null,I.classList.toggle("gala-toc--floating",I.getBoundingClientRect().top<=96),!t.length)return;let d=window.innerHeight*.42,f=t[0];for(let m of t)if(m.getBoundingClientRect().top<=d)f=m;else break;let h=a.find(m=>m.hash===`#${f.id}`);for(let m of a)m===h?m.setAttribute("aria-current","location"):m.removeAttribute("aria-current");if(e&&a.length){let m=a[0].getBoundingClientRect(),n=a[a.length-1].getBoundingClientRect();I.classList.toggle("gala-toc--overflowing",n.bottom-m.top>e.clientHeight)}if(h&&e&&e.scrollHeight>e.clientHeight){let m=e.getBoundingClientRect(),n=h.getBoundingClientRect(),s=e.scrollTop+n.top-m.top-(e.clientHeight-n.height)/2;e.scrollTo({top:Math.max(0,s),behavior:"auto"})}},i=()=>{r==null&&(r=requestAnimationFrame(o))};addEventListener("scroll",i,{passive:!0}),addEventListener("resize",i,{passive:!0}),i()}var V=document.querySelector(".gala-action-rail"),Q=document.querySelector("[data-action-dock]");if(V&&Q){let e=a=>{V.classList.toggle("gala-action-rail--integrated",a[0].isIntersecting)};new IntersectionObserver(e,{rootMargin:"0px 0px 18% 0px",threshold:0}).observe(Q)}function J(e,a){let t=a?"Unfollow article":"Follow article";e.setAttribute("aria-pressed",String(a)),e.setAttribute("aria-label",t),e.title=t;let r=e.querySelector("[data-follow-label]");r&&(r.textContent=t)}document.addEventListener("click",async e=>{if(e.target instanceof HTMLDialogElement&&e.target.open){let n=e.target.getBoundingClientRect();if(e.clientX<n.left||e.clientX>n.right||e.clientY<n.top||e.clientY>n.bottom){e.target.close();return}}let a=e.target.closest("[data-gala-embed-load]");if(a){let n=a.closest("[data-gala-embed]"),s=a.dataset.galaEmbedSrc,u=a.dataset.galaEmbedLoad;if(!n||!s||!["youtube","codepen"].includes(u))return;let l=document.createElement("iframe");l.src=s,l.title=u==="youtube"?"YouTube video":"CodePen example",l.loading="eager",l.referrerPolicy="strict-origin-when-cross-origin",l.setAttribute("sandbox","allow-forms allow-popups allow-presentation allow-same-origin allow-scripts"),l.setAttribute("allow",u==="youtube"?"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture; web-share":"fullscreen"),l.setAttribute("allowfullscreen",""),n.replaceChildren(l);return}if(e.target.closest("[data-user-control]")&&!w&&N){O("active");return}let r=e.target.closest("[data-open-dialog]");if(r){let n=document.getElementById(r.dataset.openDialog);n instanceof HTMLDialogElement&&n.showModal();return}let o=e.target.closest("[data-reaction]");if(o){let n=o.closest("[data-engagement-url]");if(!n)return;if(!w)return M({kind:"reaction",region:n,selector:`[data-reaction="${o.dataset.reaction}"]`});let s=o.getAttribute("aria-pressed")!=="true";if(!await X(n,s?"reaction.add":"reaction.remove",{articleId:n.dataset.articleId,reaction:o.dataset.reaction}))return;o.setAttribute("aria-pressed",String(s));return}let i=e.target.closest("[data-follow-article]");if(i){let n=i.closest("[data-engagement-url]");if(!n)return;if(!w)return M({kind:"follow",region:n,selector:"[data-follow-article]"});let s=i.getAttribute("aria-pressed")!=="true";if(!await X(n,s?"follow.add":"follow.remove",{targetType:"articles",targetId:n.dataset.articleId}))return;J(i,s);return}let d=e.target.closest("[data-copy-url]");if(d){let n=d.dataset.copyUrl;if(!window.isSecureContext||!navigator.clipboard?.writeText){L(d);return}try{await navigator.clipboard.writeText(n);let s=d.closest(".gala-share")?.querySelector(".gala-share__status");s&&(s.textContent="Link copied.")}catch{L(d)}return}let f=e.target.closest("[data-native-share]");if(f){if(navigator.share)try{await navigator.share({title:document.title,url:f.dataset.nativeShare})}catch(n){n.name!=="AbortError"&&L(f)}else L(f);return}let h=e.target.closest("[data-copy-code]");if(!h)return;let m=h.closest(".gala-code-block")?.querySelector("code");if(!(!m||!navigator.clipboard?.writeText||!window.isSecureContext))try{await navigator.clipboard.writeText(m.textContent),h.textContent="Copied"}catch{h.textContent="Select code to copy"}});var ce=new Set([...document.querySelectorAll("pre code")].map(e=>e.closest("pre")).filter(Boolean));ce.forEach(e=>{let a=document.createElement("div");a.className="gala-code-block",e.before(a),a.append(e);let t=document.createElement("button");t.type="button",t.dataset.copyCode="",t.textContent="Copy code",t.setAttribute("aria-label","Copy code block"),a.prepend(t)});function le(e){return[["Reactions",Object.values(e.reactions??{}).reduce((t,r)=>t+(Number.isSafeInteger(r)?r:0),0)],["Comments",Number.isSafeInteger(e.comments?.totalCount)?e.comments.totalCount:0],["Views",Number.isSafeInteger(e.views?.count)?e.views.count:0]]}function de(e){return e<1e3?"<1K":new Intl.NumberFormat("en",{notation:"compact",maximumFractionDigits:1}).format(e)}function ue(e,a){let t=a?.data;if(!t||typeof t!="object")throw new TypeError("Engagement data is invalid");for(let[r,o]of le(t))e.querySelectorAll(`[data-engagement-stat="${r.toLowerCase()}"]`).forEach(i=>{i.textContent=de(o),i.closest("div")?.setAttribute("title",`${o} ${r.toLowerCase()}`)});e.querySelector("[data-engagement-snapshot]")?.remove(),e.querySelector(".gala-engagement__placeholder")?.remove()}async function D(e,a="",t=!1,r=!1){let o=e.querySelector("[data-engagement-status]"),i=!!e.querySelector("[data-gala-comments]");try{let d=new URL(e.dataset.engagementUrl);a&&d.searchParams.set("commentsCursor",a);let f=await fetch(d,{headers:{Accept:"application/json"},credentials:"omit",cache:r?"no-store":"default"});if(!f.ok)throw new Error(`Engagement returned HTTP ${f.status}`);let h=await f.json();ue(e,h),o&&!i&&(o.textContent=h.errors?.length?"Some engagement data is temporarily unavailable.":"")}catch{o&&!i&&(o.textContent="Engagement is temporarily unavailable.")}}function me(){let e=new URL(window.location.href).searchParams,a={};for(let t of["utm_source","utm_medium","utm_campaign","utm_content","utm_term"]){let r=e.get(t);r&&[...r].length<=128&&(a[t]=r)}return a}function ge(e){let a=new URL(e.dataset.engagementUrl);a.pathname=a.pathname.replace(/\/engagement$/,"/views"),fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({language:document.documentElement.lang||void 0,referrer:document.referrer||void 0,campaign:me()}),credentials:"omit",keepalive:!0}).catch(()=>{})}document.addEventListener("gala-request-sign-in",e=>{w||T||M({kind:e.detail?.kind??"comment"})});var w=null,K=null,q=null,R=new Map,T=null,E=document.querySelector("[data-gala-session-frame]"),x=E?new URL(E.src).origin:null,Z=!1,_=null,N=null,v=null,fe="gala-fedcm-grant=1";function pe(){try{return document.cookie.split(";").some(e=>e.trim()===fe)}catch(e){return console.warn("Gala could not read this publication's FedCM grant marker.",e),!1}}function he(){try{document.cookie="gala-fedcm-grant=1; Max-Age=31536000; Path=/; SameSite=Strict; Secure"}catch(e){console.warn("Gala could not remember this publication's FedCM grant.",e)}}function ye(){try{document.cookie="gala-fedcm-grant=; Max-Age=0; Path=/; SameSite=Strict; Secure"}catch(e){console.warn("Gala could not clear this publication's FedCM grant.",e)}}function ee(){!Z||!E||!_||(E.contentWindow?.postMessage({type:"gala-session-transfer",transferCode:_},x),_=null)}function z(){E?.contentWindow?.postMessage({type:"gala-session-request"},x)}E&&(E.addEventListener("load",z),z());async function O(e){let a=document.querySelector("[data-engagement-status]");if(!N)return!1;if(!globalThis.IdentityCredential||typeof navigator.credentials?.get!="function")return a&&(a.textContent="FedCM is not available in this browser. Use a current browser to sign in."),!1;if(v){if(e==="passive")return!1;v.abort()}let t=new AbortController;v=t;try{let i={providers:[{configURL:"https://api.gala67.com/v1/fedcm/config.json",clientId:new URL(E.src).searchParams.get("siteId")??"",fields:["name","email"],params:{nonce:N}}]};e==="active"&&(i.mode="active");let d=await navigator.credentials.get({identity:i,mediation:e==="active"?"required":"silent",signal:t.signal});return typeof d?.token!="string"?!1:(e==="active"&&he(),_=d.token,ee(),!0)}catch(r){return e==="active"&&r?.name!=="NotAllowedError"&&r?.name!=="AbortError"&&console.error("Gala FedCM sign-in failed.",r),e==="active"&&a&&(a.textContent="Sign-in did not finish. Try again."),!1}finally{v===t&&(v=null)}}function M(e){let a=e.field;T={kind:e.kind,region:e.region,selector:e.selector,draft:a?a.value:null,caret:a?a.selectionStart:null},a&&a.blur(),O("active").then(t=>{t||(T=null)})}function Ee(){let e=T;if(!e||!document.hasFocus())return;let a=e.region?.querySelector(e.selector);if(a){if(T=null,e.kind==="comment"){e.draft!=null&&a.value===""&&(a.value=e.draft),a.focus(),e.caret!=null&&typeof a.setSelectionRange=="function"&&a.setSelectionRange(e.caret,e.caret);return}a.click()}}document.querySelectorAll("[data-engagement-url]").forEach(e=>{D(e),ge(e)});function te(e){return e==="AUTHENTICATION_REQUIRED"||e==="INVALID_BEARER_TOKEN"||e==="REAUTHENTICATION_REQUIRED"?"Sign in again to continue.":e==="ENGAGEMENT_RATE_LIMITED"?"You are posting too quickly; try again shortly.":e==="CONTACT_RATE_LIMITED"?"You are sending too quickly; try again later.":e==="RESOURCE_NOT_FOUND"?"That item is no longer available.":e==="INVALID_ENGAGEMENT_WRITE"||e==="INVALID_CONTACT_SUBMISSION"||e==="INVALID_REQUEST"?"Check your entry and try again.":e==="ACCESS_DENIED"?"That action is not available for this account.":e==="IDEMPOTENCY_CONFLICT"||e==="ENGAGEMENT_STATE_CONFLICT"?"The item changed; reload and try again.":"The action could not be completed. Try again."}function ae(e,a){if(!E||!w)return Promise.reject(new Error("AUTHENTICATION_REQUIRED"));let t=crypto.randomUUID();return new Promise((r,o)=>{let i=setTimeout(()=>{R.delete(t),o(new Error("REQUEST_TIMEOUT"))},1e4);R.set(t,{resolve:d=>{clearTimeout(i),r(d)},reject:d=>{clearTimeout(i),o(d)}}),E.contentWindow.postMessage({type:"gala-engagement-write",requestId:t,operation:e,payload:a},new URL(E.src).origin)})}document.addEventListener("submit",async e=>{let a=e.target.closest("[data-contact-form] form");if(!a)return;e.preventDefault();let t=a.closest("[data-contact-form]"),r=t.querySelector("[data-contact-status]");if(!w){r.textContent="Sign in with the account button before sending.";return}let o=new FormData(a);try{r.textContent="Sending\u2026",await ae("contact.submit",{siteId:t.dataset.siteId,subject:o.get("subject"),message:o.get("message"),website:o.get("website")||null,phone:o.get("phone")||null}),a.reset(),r.textContent="Message sent."}catch(i){r.textContent=te(i.message)}});async function X(e,a,t){let r=e.querySelector("[data-engagement-status]");try{return r&&(r.textContent="Saving\u2026"),await ae(a,t),r&&(r.textContent="Saved."),await D(e,"",!1,!0),!0}catch(o){return r&&(r.textContent=te(o.message)),!1}}E&&window.addEventListener("message",e=>{if(e.origin!==x||e.source!==E.contentWindow)return;if(e.data?.type==="gala-fedcm-sign-out"){ye(),navigator.credentials?.preventSilentAccess?.().catch(o=>{console.error("Gala could not disable silent FedCM access after sign-out.",o)});return}if(e.data?.type==="gala-engagement-result"){let o=R.get(e.data.requestId);if(!o)return;R.delete(e.data.requestId),e.data.ok===!0?o.resolve(e.data.result):o.reject(new Error(e.data.error?.code||"ENGAGEMENT_WRITE_FAILED"));return}if(e.data?.type==="gala-reader-state-result"){if(e.data.requestId!==q||e.data.ok!==!0)return;q=null;let o=new Set(Array.isArray(e.data.state?.reactions)?e.data.state.reactions:[]);document.querySelectorAll("[data-reaction]").forEach(i=>{i.setAttribute("aria-pressed",String(o.has(i.dataset.reaction)))}),document.querySelectorAll("[data-follow-article]").forEach(i=>{let d=e.data.state?.following===!0;J(i,d)});return}if(e.data?.type==="gala-session-height"){let o=Number(e.data.height);Number.isFinite(o)&&o>0&&o<2e3&&(E.height=String(Math.ceil(o)));return}if(e.data?.type!=="gala-session")return;Z=!0,typeof e.data.frameToken=="string"&&(N=e.data.frameToken,document.querySelector("[data-user-control]")?.setAttribute("data-fedcm-ready","true")),_&&ee(),w=e.data.user&&typeof e.data.user.id=="string"?e.data.user:null;let a=document.querySelector("[data-user-control]"),t=w?.displayName;if(a){a.setAttribute("aria-label",t?`Account: ${t}`:"Sign in or view account"),a.title=t?`Account: ${t}`:"Account";let o=a.querySelector("[data-user-label]");o&&(o.textContent=t||"Sign in")}let r=K!==(w?.id??null);if(K=w?.id??null,w){let o=document.querySelector("[data-article-id]");o&&(q=crypto.randomUUID(),E.contentWindow.postMessage({type:"gala-reader-state-request",requestId:q,articleId:o.dataset.articleId},x))}document.querySelectorAll("[data-engagement-url]").forEach(o=>{r&&D(o)}),w&&T&&Ee(),!w&&N&&pe()&&O("passive")});document.querySelectorAll("[data-gala-search]").forEach(e=>{let a=e.querySelector("form"),t=a?.elements.namedItem("q"),r=e.querySelector("[data-search-status]"),o=e.querySelector("[data-search-results]"),i=e.dataset.indexUrl,d,f=s=>String(s??"").normalize("NFKC").toLocaleLowerCase();function h(s,u){o.replaceChildren();for(let l of s){let p=document.createElement("li"),c=document.createElement("article"),y=document.createElement("h2"),b=document.createElement("a");if(b.href=l.url,b.lang=l.language,b.textContent=l.title,y.append(b),c.append(y),l.description){let G=document.createElement("p");G.textContent=l.description,c.append(G)}p.append(c),o.append(p)}r.textContent=`${s.length} result${s.length===1?"":"s"} for \u201C${u}\u201D.`}async function m(s){let u=s.trim();if(u===""){o.replaceChildren(),r.textContent="Enter a search term.";return}r.textContent="Searching\u2026";try{d??=fetch(i,{headers:{Accept:"application/json"}}).then(async c=>{if(!c.ok)throw new Error(`Search index returned HTTP ${c.status}`);let y=await c.json();if(y?.schemaVersion!==1||!Array.isArray(y.entries))throw new TypeError("Search index schema is unsupported");return y.entries});let l=f(u),p=(await d).filter(c=>f([c.title,c.description,c.language,...Array.isArray(c.tags)?c.tags:[],c.body].join(`
2
+ `)).includes(l));h(p,u)}catch{o.replaceChildren(),r.textContent="Search is temporarily unavailable."}}a?.addEventListener("submit",s=>{s.preventDefault();let u=t.value,l=new URL(window.location.href);u.trim()===""?l.searchParams.delete("q"):l.searchParams.set("q",u),window.history.replaceState(null,"",l),m(u)});let n=new URLSearchParams(window.location.search).get("q")??"";t&&(t.value=n),m(n)});var C={value:null},A=document.querySelector("[data-gala-session-frame]"),ne=A?new URL(A.src).origin:null,k=new Map;function re(e){return e==="AUTHENTICATION_REQUIRED"||e==="INVALID_BEARER_TOKEN"||e==="REAUTHENTICATION_REQUIRED"?"Sign in again to continue.":e==="ENGAGEMENT_RATE_LIMITED"?"You are posting too quickly; try again shortly.":e==="CONTACT_RATE_LIMITED"?"You are sending too quickly; try again later.":e==="RESOURCE_NOT_FOUND"?"That item is no longer available.":e==="INVALID_ENGAGEMENT_WRITE"||e==="INVALID_CONTACT_SUBMISSION"||e==="INVALID_REQUEST"?"Check your entry and try again.":e==="ACCESS_DENIED"?"That action is not available for this account.":e==="IDEMPOTENCY_CONFLICT"||e==="ENGAGEMENT_STATE_CONFLICT"?"The item changed; reload and try again.":"The action could not be completed. Try again."}function oe(e,a){if(!A||!C.value)return Promise.reject(new Error("AUTHENTICATION_REQUIRED"));let t=crypto.randomUUID();return new Promise((r,o)=>{let i=setTimeout(()=>{k.delete(t),o(new Error("REQUEST_TIMEOUT"))},1e4);k.set(t,{resolve:d=>{clearTimeout(i),r(d)},reject:d=>{clearTimeout(i),o(d)}}),A.contentWindow.postMessage({type:"gala-engagement-write",requestId:t,operation:e,payload:a},ne)})}function F(e){document.dispatchEvent(new CustomEvent("gala-request-sign-in",{detail:e}))}A&&window.addEventListener("message",e=>{if(e.origin!==ne||e.source!==A.contentWindow)return;if(e.data?.type==="gala-engagement-result"){let t=k.get(e.data.requestId);if(!t)return;k.delete(e.data.requestId),e.data.ok===!0?t.resolve(e.data.result):t.reject(new Error(e.data.error?.code||"ENGAGEMENT_WRITE_FAILED"));return}if(e.data?.type!=="gala-session")return;let a=e.data.user;C.value=a&&typeof a.id=="string"?a:null,window.dispatchEvent(new CustomEvent("gala-session-change"))});var we=5,g=(e,a,t)=>{let r=document.createElement(e);return a&&(r.className=a),t!==void 0&&(r.textContent=t),r};function be(e){let a=new Map;for(let r of e){let o=r.parentCommentId??"";a.has(o)||a.set(o,[]),a.get(o).push(r)}let t=(r,o)=>(a.get(r)??[]).map(i=>({...i,depth:o,replies:t(i.commentId,o+1)}));return t("",0)}function Se(e,a){let t={items:[],cursor:null,total:0,busy:!1,status:"",phase:"loading"},r=/\/v1\/articles\/([^/]+)\/engagement/.exec(a)?.[1]??"",o=e.closest(".gala-conversation")?.querySelector("[data-engagement-status]");async function i(n="",{append:s=!1,fresh:u=!1}={}){let l=new URL(a);n&&l.searchParams.set("commentsCursor",n);let p=await fetch(l,{headers:{Accept:"application/json"},credentials:"omit",cache:u?"no-store":"default"});if(!p.ok)throw new Error(`Comments returned HTTP ${p.status}`);let c=(await p.json())?.data?.comments;if(!c||!Array.isArray(c.items))throw new TypeError("Comment page is invalid");t.items=s?[...t.items,...c.items]:c.items,t.cursor=c.nextCursor??null,Number.isSafeInteger(c.totalCount)&&(t.total=c.totalCount)}async function d(n,s){if(!C.value)return F({kind:"comment"}),!1;t.busy=!0,t.status="",m();try{return await oe(n,s),await i("",{fresh:!0}),!0}catch(u){return t.status=re(u.message),!1}finally{t.busy=!1,m()}}function f(n,s,u){let l=g("form","gala-comment__form"),p=g("textarea");p.rows=3,p.value=s,p.placeholder=n,p.setAttribute("aria-label",n);let c=g("button","","Post");return c.type="submit",c.disabled=t.busy,l.append(p,c),l.addEventListener("submit",async y=>{y.preventDefault();let b=p.value.trim();b&&await u(b)&&(p.value="")}),l}function h(n){let s=g("li","gala-comment");s.dataset.commentId=n.commentId,s.dataset.depth=n.depth;let u=g("p","gala-comment__meta");if(u.append(g("strong","",n.author?.displayName??"[deleted]")),n.createdAt){let l=g("time","",new Date(n.createdAt).toLocaleDateString());l.dateTime=n.createdAt,u.append(l)}if(s.append(u,g("p","gala-comment__body",n.deleted?"[deleted]":n.body)),!n.deleted){let l=g("div","gala-comment-actions");if(n.depth<we){let c=g("button","","Reply");c.type="button",c.dataset.replyComment=n.commentId,c.addEventListener("click",()=>{let y=s.querySelector(":scope > .gala-comment__form");if(y){y.remove();return}l.after(f(`Reply to ${n.author?.displayName??"this comment"}`,"",b=>d("comment.create",{articleId:r,parentCommentId:n.commentId,body:b})))}),l.append(c)}if(C.value&&n.author?.userId===C.value.id){let c=g("button","","Edit");c.type="button",c.dataset.editComment=n.commentId,c.addEventListener("click",()=>l.after(f("Edit your comment",n.body??"",b=>d("comment.edit",{articleId:r,commentId:n.commentId,body:b}))));let y=g("button","","Delete");y.type="button",y.dataset.deleteComment=n.commentId,y.addEventListener("click",()=>d("comment.delete",{articleId:r,commentId:n.commentId})),l.append(c,y)}else{let c=g("button","","Report");c.type="button",c.dataset.reportComment=n.commentId,c.addEventListener("click",()=>d("comment.report",{articleId:r,commentId:n.commentId,reason:"OTHER"})),l.append(c)}s.append(l)}if(n.replies.length){let l=g("ol","gala-comment-replies");l.append(...n.replies.map(h)),s.append(l)}return s}function m(){if(o&&(o.textContent=t.phase==="loading"?"Loading comments\u2026":t.phase==="unavailable"?"Comments are temporarily unavailable.":t.status),t.phase!=="ready"){e.replaceChildren();return}let n=g("section","gala-comments-island");if(n.setAttribute("aria-label","Comments"),n.append(g("p","gala-comments__heading",t.total===1?"1 comment":`${t.total} comments`)),C.value)n.append(f("Add a comment","",s=>d("comment.create",{articleId:r,body:s})));else{let s=g("p","gala-comments__prompt"),u=g("button","","Sign in to join the conversation");u.type="button",u.addEventListener("click",()=>F({kind:"comment"})),s.append(u),n.append(s)}if(!t.items.length)n.append(g("p","gala-comments__empty","No comments yet."));else{let s=g("ol","gala-comments");s.append(...be(t.items).map(h)),n.append(s)}if(t.cursor){let s=g("button","gala-comments__more","Show more comments");s.type="button",s.disabled=t.busy,s.addEventListener("click",async()=>{t.busy=!0,t.status="Loading more comments\u2026",m();try{await i(t.cursor,{append:!0}),t.status=""}catch{t.status="More comments couldn\u2019t be loaded. Try again."}t.busy=!1,m()}),n.append(s)}e.replaceChildren(n)}window.addEventListener("gala-session-change",m),m(),i().then(()=>{t.phase="ready"}).catch(()=>{t.phase="unavailable"}).finally(m)}document.querySelectorAll("[data-gala-comments]").forEach(e=>{let a=e.closest("[data-engagement-url]")?.dataset.engagementUrl;a&&Se(e,a)});})();