1"use strict"; 2 3(function (global) { 4 const DEFAULT_TEMP_HOURS = 24; 5 const DEFAULT_BUSINESS_DAYS = 30; 6 /** User-facing copy for relation_kind === "one_time" (session-scoped, not a 24h timer). */ 7 const ONE_TIME_MODE_TITLE = "One-time session"; 8 const ONE_TIME_MODE_SUBTITLE = "Until session ends"; 9 const ONE_TIME_PANEL_META = 10 "Guest access for this session only. It ends when you or they leave the Space."; 11 const ONE_TIME_SUMMARY = ONE_TIME_MODE_TITLE + " · until session ends"; 12 const ACTION_MODE_TITLE = "Actions"; 13 /** User-facing copy for relation_kind === "fixed_term" (access until a set date). */ 14 const FIXED_TERM_MODE_TITLE = "Fixed-term"; 15 const FIXED_TERM_PANEL_META = 16 "Access until the date you choose. Files and history for ongoing work with a clear end."; 17 const FIXED_TERM_SUMMARY_PREFIX = FIXED_TERM_MODE_TITLE + " · "; 18 const ACTION_MODE_SUBTITLE = "Unlimited"; 19 const ACTION_SUMMARY = ACTION_MODE_TITLE + " · unlimited"; 20 21 let state = { tempHours: DEFAULT_TEMP_HOURS, businessDays: DEFAULT_BUSINESS_DAYS }; 22 23 function formatHoursLabel(hours) { 24 const n = Math.max(1, Math.round(Number(hours) || DEFAULT_TEMP_HOURS)); 25 return n === 1 ? "1 hour" : n + " hours"; 26 } 27 28 function formatDaysLabel(days) { 29 const n = Math.max(1, Math.round(Number(days) || DEFAULT_BUSINESS_DAYS)); 30 return n === 1 ? "1 day" : n + " days"; 31 } 32 33 function readTempHoursFromEl(el) { 34 const h = Number(el && el.value); 35 return Number.isFinite(h) && h > 0 ? h : DEFAULT_TEMP_HOURS; 36 } 37 38 function effectiveTempHours(hoursId, untilId) { 39 const hoursEl = hoursId ? document.getElementById(hoursId) : null; 40 const untilEl = untilId ? document.getElementById(untilId) : null; 41 const until = untilEl && untilEl.value ? new Date(untilEl.value).getTime() : 0; 42 if (Number.isFinite(until) && until > Date.now()) { 43 return Math.max(1, Math.round((until - Date.now()) / (60 * 60 * 1000))); 44 } 45 return readTempHoursFromEl(hoursEl); 46 } 47 48 function businessDaysFromDateEl(el) { 49 if (!el || !el.value) return DEFAULT_BUSINESS_DAYS; 50 const until = new Date(el.value + "T23:59:59").getTime(); 51 if (!Number.isFinite(until) || until <= Date.now()) return DEFAULT_BUSINESS_DAYS; 52 return Math.max(1, Math.round((until - Date.now()) / (24 * 60 * 60 * 1000))); 53 } 54 55 function setModeButtonSubtitle(btn, text) { 56 const span = btn.querySelector(":scope > span"); 57 if (span) span.textContent = text; 58 } 59 60 function setModeButtonTitle(btn, text) { 61 const strong = btn.querySelector(":scope > strong"); 62 if (strong) { 63 const count = strong.querySelector(".space-spacebook-filter-count"); 64 if (count) { 65 const countHtml = count.outerHTML; 66 strong.textContent = text + " "; 67 strong.insertAdjacentHTML("beforeend", countHtml); 68 } else { 69 strong.textContent = text; 70 } 71 } 72 } 73 74 function applyAccessModeButtonLabels() { 75 document.querySelectorAll('[data-access-mode="one_time"]').forEach((btn) => { 76 btn.textContent = ONE_TIME_MODE_TITLE; 77 }); 78 document.querySelectorAll('[data-access-mode="action"]').forEach((btn) => { 79 btn.textContent = ACTION_MODE_TITLE; 80 }); 81 } 82 83 function applyToDom() { 84 const bizLabel = formatDaysLabel(state.businessDays); 85 document.querySelectorAll('[data-rel-mode="one_time"]').forEach((btn) => { 86 setModeButtonTitle(btn, ONE_TIME_MODE_TITLE); 87 setModeButtonSubtitle(btn, ONE_TIME_MODE_SUBTITLE); 88 }); 89 document.querySelectorAll('[data-rel-mode="fixed_term"]').forEach((btn) => { 90 setModeButtonSubtitle(btn, bizLabel); 91 }); 92 document.querySelectorAll('[data-rel-mode="action"]').forEach((btn) => { 93 setModeButtonTitle(btn, ACTION_MODE_TITLE); 94 setModeButtonSubtitle(btn, ACTION_MODE_SUBTITLE); 95 }); 96 document.querySelectorAll('[data-spacebook-filter="action"]').forEach((btn) => { 97 setModeButtonTitle(btn, ACTION_MODE_TITLE); 98 const sub = btn.querySelector(":scope > span"); 99 if (sub) sub.textContent = ACTION_MODE_SUBTITLE; 100 }); 101 document.querySelectorAll('[data-spacebook-filter="one_time"]').forEach((btn) => { 102 setModeButtonTitle(btn, ONE_TIME_MODE_TITLE); 103 const sub = btn.querySelector(":scope > span");
104 if (sub) sub.textContent = ONE_TIME_MODE_SUBTITLE; 105 }); 106 applyAccessModeButtonLabels(); 107 document.querySelectorAll('[data-spacebook-filter="fixed_term"]').forEach((btn) => { 108 const sub = btn.querySelector(":scope > span"); 109 if (sub) sub.textContent = bizLabel; 110 }); 111 try { 112 global.dispatchEvent(new CustomEvent("grigsi-connect-mode-labels")); 113 } catch (_) {} 114 } 115 116 function apply(partial) { 117 if (partial && typeof partial.tempHours === "number") state.tempHours = partial.tempHours; 118 if (partial && typeof partial.businessDays === "number") state.businessDays = partial.businessDays; 119 applyToDom(); 120 } 121 122 function syncTempFromPair(hoursId, untilId) { 123 apply({ tempHours: effectiveTempHours(hoursId, untilId) }); 124 } 125 126 function syncBusinessFromDateInput(dateId) { 127 const el = dateId ? document.getElementById(dateId) : null; 128 apply({ businessDays: businessDaysFromDateEl(el) }); 129 } 130 131 const TEMP_BINDINGS = [ 132 { hoursId: "rel-temp-hours", untilId: "rel-temp-until" }, 133 { hoursId: "space-rel-temp-hours", untilId: "space-rel-temp-until" }, 134 { hoursId: "space-access-temp-hours", untilId: "space-access-temp-until" }, 135 ]; 136 137 const BUSINESS_BINDINGS = ["rel-business-until", "space-rel-business-until", "space-access-business-until"]; 138 139 function wire() { 140 TEMP_BINDINGS.forEach(({ hoursId, untilId }) => { 141 const onTemp = () => syncTempFromPair(hoursId, untilId); 142 const hoursEl = document.getElementById(hoursId); 143 const untilEl = document.getElementById(untilId); 144 hoursEl?.addEventListener("input", onTemp); 145 hoursEl?.addEventListener("change", onTemp); 146 untilEl?.addEventListener("input", onTemp); 147 untilEl?.addEventListener("change", onTemp); 148 }); 149 BUSINESS_BINDINGS.forEach((dateId) => { 150 const onBiz = () => syncBusinessFromDateInput(dateId); 151 const el = document.getElementById(dateId); 152 el?.addEventListener("input", onBiz); 153 el?.addEventListener("change", onBiz); 154 }); 155 const firstTemp = TEMP_BINDINGS.find((b) => document.getElementById(b.hoursId)); 156 if (firstTemp) syncTempFromPair(firstTemp.hoursId, firstTemp.untilId); 157 const firstBiz = BUSINESS_BINDINGS.find((id) => document.getElementById(id)); 158 if (firstBiz) syncBusinessFromDateInput(firstBiz); 159 else apply({}); 160 } 161 162 global.GriGsiConnectModeLabels = { 163 DEFAULT_TEMP_HOURS, 164 DEFAULT_BUSINESS_DAYS, 165 ONE_TIME_MODE_TITLE, 166 ONE_TIME_MODE_SUBTITLE, 167 ONE_TIME_PANEL_META, 168 ONE_TIME_SUMMARY, 169 FIXED_TERM_MODE_TITLE, 170 FIXED_TERM_PANEL_META, 171 FIXED_TERM_SUMMARY_PREFIX, 172 ACTION_MODE_TITLE, 173 ACTION_MODE_SUBTITLE, 174 ACTION_SUMMARY, 175 formatHoursLabel, 176 formatDaysLabel, 177 effectiveTempHours, 178 businessDaysFromDateEl, 179 getState: () => ({ ...state }), 180 apply, 181 syncTempFromPair, 182 syncBusinessFromDateInput, 183 wire, 184 }; 185 186 if (document.readyState === "loading") { 187 document.addEventListener("DOMContentLoaded", wire); 188 } else { 189 wire(); 190 } 191})(typeof window !== "undefined" ? window : globalThis);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.