1/** 2 * GriGsi â âG at a glanceâ chip + modal. Copy is keyed by URL (PAGES). 3 */ 4(function () { 5 var global = typeof window !== "undefined" ? window : globalThis; 6 var PREFIX = "G at a glance · "; 7 /** Compact chip glyph: ">" | "?" | "G" */ 8 var HELP_CHIP_GLYPH = ">"; 9 10 function helpLang() { 11 try { 12 if (global.GriGsiSiteI18n && typeof global.GriGsiSiteI18n.apply === "function") { 13 var ctl = global.GriGsiUiLang && global.localStorage.getItem("grigsi-site-ui-lang"); 14 if (ctl === "bg" || ctl === "en") return ctl; 15 } 16 var stored = global.localStorage.getItem("grigsi-site-ui-lang"); 17 if (stored === "bg" || stored === "en") return stored; 18 } catch (_) {} 19 var nav = String((global.navigator && global.navigator.language) || "").toLowerCase(); 20 return nav.startsWith("bg") ? "bg" : "en"; 21 } 22 23 function helpUi() { 24 var lang = helpLang(); 25 if (lang === "bg" && global.GriGsiHelpBgDefaults) { 26 return { 27 prefix: "G накÑаÑко · ", 28 chipLabel: global.GriGsiHelpBgDefaults.chipLabel || "G накÑаÑко", 29 chipAria: global.GriGsiHelpBgDefaults.chipAria || "ÐомоÑ", 30 ok: global.GriGsiHelpBgDefaults.ok || "ÐобÑе", 31 }; 32 } 33 return { 34 prefix: PREFIX, 35 chipLabel: "G at a glance", 36 chipAria: "Help â at a glance for this page", 37 ok: "OK", 38 }; 39 } 40 41 function glance(shortTitle, bodyHtml) { 42 return { title: PREFIX + shortTitle, body: bodyHtml }; 43 } 44 45 var siteDefault = glance( 46 "GriGsi", 47 "<p><strong>Trust layer</strong> for the open web: community trust signals, <strong>Trust Check</strong> (domains, links, text), and <strong>SENDi!</strong> without classic sign-up.</p>" + 48 "<p>Header: <strong>Tools</strong>, <strong>Solutions</strong>, <strong>Services</strong>, Pricing, About, More (Trust Index and indexes live under More).</p>" + 49 "<p>Built around <strong>hashes and minimal PII</strong>; you control what you share.</p>" 50 ); 51 52 var spaceEntryDefault = glance( 53 "SENDi! entry", 54 "<p><strong>SENDi!</strong> is for sending once and continuing only if needed: choose a type, optional password, then create or join with a code or link.</p>" + 55 "<p>A session runs until you leave â not a fixed 24-hour timer.</p>" + 56 "<p>Use the <strong>top menu</strong> for tools, docs, and indexes anytime.</p>" 57 ); 58 59 var spaceSpaceDefault = glance( 60 "SENDi!", 61 "<p>Youâre inside <strong>SENDi!</strong>: send a photo, file, link, text or voice once â continue if you need to. Chat, files, video, screen sharing, posts, polls, and Trust Check depending on what the host enabled.</p>" + 62 "<p><strong>Background painting:</strong> the chat backdrop is a <strong>public-domain masterpiece</strong> from Wikimedia Commons (one per SENDi! code). Tap <strong>GI</strong> on the caption chip for title, artist, year, and source â in English. GriGsi does not host the image; your browser loads it from the museum/Commons URL.</p>" + 63 "<p>Media is often <strong>peer-to-peer</strong> when the network allows; the server still coordinates signaling and session setup.</p>" + 64 "<p>Leave or close the tab to leave; use the <strong>site menu</strong> for tools elsewhere.</p>" 65 ); 66 67 var PAGES = { 68 "/": glance( 69 "Home", 70 "<p><strong>Start here</strong>: quick links to Space, Trust Check, and the main index tools â trust, sources, and learning.</p>" + 71 "<p>The purple bar is the hero; <strong>Index tools</strong> group the main products in one row.</p>" + 72 "<p>Everything is <strong>hash-first</strong>; no account is required for the core flows.</p>" 73 ), 74 75 "/check-index.html": glance( 76 "Trust Check", 77 "<p><strong>Vote</strong> Trust or Warn on a domain, URL, email, phone, IBAN, or text label â only a <strong>hash</strong> of your final label is stored for votes.</p>" + 78 "<p>This combines community votes with verification workflows for the same hash.</p>" + 79 "<p><strong>Open Trust Check</strong> to continue with source-style follow-up for the same text.</p>" 80 ), 81 82 "/trust-index.html": glance( 83 "Trust Index", 84 "<p>Hub for the <strong>trust layer</strong>: how voting works, links to Trust Check, Global Trust guide, Learn Index, and noise tools.</p>" + 85 "<p>Use this page to jump into the right product without mixing up <strong>community votes</strong> vs <strong>claim verification</strong>.</p>" + 86 "<p>Extension users: <strong>Sentinel</strong> (in-page prompt) is explained here â itâs not the same as the trust score alone.</p>" 87 ), 88 89 "/trust-index/global.html": glance( 90 "Global Trust Index (guide)", 91 "<p>Long-form guide: how <strong>Trust / Warn</strong> votes aggregate into a score and <strong>tier</strong> (Observation â Soft â Confirmed, plus Flagged when needed).</p>" + 92 "<p>Describes <strong>hash-first</strong> design, privacy, and how the browser extension fits in.</p>" + 93 "<p><strong>Sentinel</strong> vs <strong>trust score</strong> vs <strong>Trust Check</strong> trusted sources are clarified here.</p>" 94 ), 95 96 "/tools.html": glance( 97 "Tools", 98 "<p><strong>Tool catalog</strong>: verify, protect, collaborate, and understand â Trust Check, indexes, proof, SENDi!, LCI, extension, API.</p>" + 99 "<p>Grouped by job, not by account type. Most flows work <strong>without sign-up</strong>.</p>" + 100 "<p>See <strong>Solutions</strong> for use-case outcomes and <strong>Services</strong> for SENDi! and shares.</p>" 101 ), 102 103 "/solutions.html": glance( 104 "Solutions", 105 "<p><strong>Problem-first map</strong>: verify before action, coordinate privately, read pressure (LCI), govern with signal.</p>" + 106 "<p>Outcome pages â not the full tool list (<strong>Tools</strong>) or delivery layer (<strong>Services</strong>).</p>" + 107 "<p>Start with <strong>Trust Check</strong> when you need to decide now.</p>" 108 ), 109 110 "/services.html": glance( 111 "Services", 112 "<p><strong>Collaboration delivery</strong> on the trust layer: SENDi!, video, governance, community.</p>" + 113 "<p>Explains how people run SENDi! and group flows; media is often <strong>P2P</strong> with server signaling.</p>" + 114 "<p>Pair with <strong>Solutions</strong> for why and <strong>Tools</strong> for the full catalog.</p>" 115 ), 116 117 "/spaces.html": glance( 118 "SENDi! (saved)", 119 "<p>Legacy <strong>/spaces.html</strong> URL â opens <strong>SENDi!</strong> saved sessions on this device.</p>" + 120 "<p>Use <strong>SENDi!</strong> for join, recent, and new sessions.</p>" + 121 "<p>Organisation features: see <strong>Pricing</strong> and <strong>Community</strong>.</p>" 122 ), 123 124 "/privacy.html": glance( 125 "Privacy Policy", 126 "<p>How GriGsi handles <strong>PII</strong>, hashes, telemetry, servers, and third parties â in plain language.</p>" + 127 "<p>Explains what the trust layer stores vs what Spaces and media may involve.</p>" + 128 "<p><strong>Not legal advice</strong> â read the full policy for your jurisdiction.</p>" 129 ), 130 131 "/faq.html": glance( 132 "FAQ", 133 "<p>Short answers on <strong>trust tiers</strong>, Trust Check, SENDi!, voting, and how the hash-based network behaves.</p>" + 134 "<p>Use this when something in the product feels unclear before opening a support thread.</p>" + 135 "<p>Links out to <strong>Privacy</strong> and <strong>Solutions</strong> where deeper detail lives.</p>" 136 ), 137 138 "/developer.html": glance( 139 "API & Developer", 140 "<p><strong>HTTP APIs</strong> for trust checks, Trust Check search/saves, and related endpoints â with headers and limits.</p>" + 141 "<p>Intended for integrators who already understand <strong>hashes and rate limits</strong>.</p>" + 142 "<p>See <strong>Privacy</strong> and <strong>Proof</strong> for how signals are produced.</p>" 143 ), 144 145 "/pricing.html": glance( 146 "Pricing", 147 "<p><strong>Free vs Pro vs Community</strong>: ads, limits, Trust Check saves, Spaces, and device rules.</p>" + 148 "<p>Choose based on whether you need <strong>unlimited</strong> index use or <strong>multi-user</strong> Spaces.</p>" + 149 "<p>Payments unlock <strong>organisation features</strong> â not a personal data profile.</p>" 150 ), 151 152 "/community.html": glance( 153 "Community", 154 "<p>Create a <strong>community</strong> with ads or licence-backed revenue;
154 members can become admins of extensions and Spaces.</p>" + 155 "<p>Describes <strong>open vs closed</strong> communities and rules.</p>" + 156 "<p>Connects to <strong>GriGsi Proof</strong> and governance ideas.</p>" 157 ), 158 159 "/proof.html": glance( 160 "GriGsi Proof", 161 "<p>How the project explains <strong>integrity and transparency</strong> â not a substitute for your own verification.</p>" + 162 "<p>Explains where the system is <strong>hash-first</strong> and where servers still matter.</p>" + 163 "<p>Use alongside <strong>FAQ</strong> and <strong>Privacy</strong>.</p>" 164 ), 165 166 "/how.html": glance( 167 "How it works", 168 "<p>High-level tour of the <strong>trust layer</strong>, Spaces, and tools â for first-time readers.</p>" + 169 "<p>Explains why <strong>no sign-up</strong> is a default and how votes aggregate.</p>" + 170 "<p>Jump to <strong>Trust Check</strong> or <strong>Tools</strong> from the home page when youâre ready.</p>" 171 ), 172 173 "/extension-uninstalled.html": glance( 174 "Extension removed", 175 "<p>Youâre here because the <strong>extension</strong> was uninstalled or the browser sent you to this page.</p>" + 176 "<p>You can still use <strong>Trust Check</strong> and Spaces on the web.</p>" + 177 "<p>Reinstall from your browserâs store anytime â the site stays the same.</p>" 178 ), 179 180 "/container-unlock.html": glance( 181 "Container unlock", 182 "<p>Flow for <strong>unlocking</strong> or container-related licence steps â follow the on-page instructions.</p>" + 183 "<p>If something fails, check <strong>Pricing</strong> and your account/device limits.</p>" + 184 "<p>General trust tools stay on <strong>Tools</strong> and <strong>Trust Check</strong>.</p>" 185 ), 186 187 "/survey.html": glance( 188 "Survey", 189 "<p>On-site <strong>survey</strong> â answers help improve flows and wording.</p>" + 190 "<p>Not a substitute for <strong>support</strong> â use Contact on the home page if you need a reply.</p>" + 191 "<p><strong>Privacy Policy</strong> applies to what the server stores.</p>" 192 ), 193 194 "/noise-text-analyzer.html": glance( 195 "Noise (local text)", 196 "<p><strong>Runs in your browser</strong>: measures informational noise in pasted text (speculation, hooks, sourcing gaps).</p>" + 197 "<p>It is <strong>not</strong> the Trust Index score and <strong>not</strong> Trust Check claim verification.</p>" + 198 "<p>For full claim workflows use <strong>Trust Check</strong> after youâve read the wording here.</p>" 199 ), 200 201 "/learn-index": glance( 202 "Learn Index", 203 "<p><strong>Student practice</strong> first: short safe examples, reflection questions, and a <strong>local noise check</strong> in the browser.</p>" + 204 "<p>Below that: the <strong>practice checklist</strong> and longer EN/BG guides â Trust Check when youâre ready.</p>" + 205 "<p>Designed to complement <strong>not replace</strong> your own judgement.</p>" 206 ), 207 208 "/similarity": glance( 209 "Similarity", 210 "<p><strong>Similarity engine</strong> â compare text or media fingerprints for overlap and relatedness.</p>" + 211 "<p>Useful for spotting duplication or near-duplicates across submissions.</p>" + 212 "<p>Does not replace human review or <strong>Trust Check</strong> sourcing.</p>" 213 ), 214 215 "/similarity/embed.html": glance( 216 "Similarity (embed)", 217 "<p><strong>Embeddable</strong> similarity view for partners or internal pages â same engine as the main tool.</p>" + 218 "<p>Respect <strong>API</strong> and usage limits; see Developer docs.</p>" + 219 "<p><strong>Privacy</strong> applies to what you send in the query.</p>" 220 ), 221 222 "/poll.html": glance( 223 "Polls", 224 "<p>Create and run <strong>polls</strong> â quick counts, hash-friendly client ids, and optional Space context.</p>" + 225 "<p>Not the same as <strong>Trust Check</strong> voting (trust layer) â different purpose.</p>" + 226 "<p>For governance-style surveys see <strong>Public surveys</strong> under Solutions.</p>" 227 ), 228 229 "/SENDi!/": spaceEntryDefault,
230 "/sendi/quick.html": glance( 231 "Quick SENDi!", 232 "<p>Create a <strong>short-lived SENDi!</strong> for the session â chat, files, or media depending on what you open.</p>" + 233 "<p>Ideal for ad-hoc sending <strong>without</strong> a long-lived organisation session.</p>" + 234 "<p>When youâre done, leave; thereâs no classic profile tied to you.</p>" 235 ), 236 "/SENDi!/": glance( 237 "Enter (unified)", 238 "<p>Redirects to <strong>SENDi!</strong> â one field for codes and links.</p>" + 239 "<p>If the Space is password-protected, enter the password on the same page.</p>" + 240 "<p>Never share secrets in screenshots you donât trust.</p>" 241 ), 242 "/instant/": glance( 243 "SENDi!", 244 "<p><strong>SENDi!</strong>: send once â share a link or code; paste a code to join someone elseâs session.</p>" + 245 "<p><strong>Find Som</strong> and <strong>My Labels</strong> live in the SENDi! menu.</p>" + 246 "<p>Recent and saved sessions live on this device only.</p>" 247 ), 248 "/instant/?mode=find": glance( 249 "GriGsi Find", 250 "<p><strong>Find</strong> â locate a device without an account. Ring Space (pinned devices) or Quick Find (one-time code).</p>" + 251 "<p>Paste a peer ID in Space chat to add a device. Location stays peer-to-peer.</p>" + 252 "<p>See <strong>docs/GRIGSI-FIND.md</strong> on the repo for architecture.</p>" 253 ), 254 "/sendi/sendi-shell-find.html": glance( 255 "GriGsi Find session", 256 "<p>Minimal find shell â ring, vibrate, compass when GPS is available.</p>" + 257 "<p>Open from SENDi! or <code>?module=find</code> on a SENDi! link.</p>" + 258 "<p>Server stores signaling only â not your coordinates.</p>" 259 ), 260 "/communicator/enter.html": glance( 261 "Enter code or link", 262 "<p>Redirects to <strong>/SENDi!/</strong> â same join field for links and codes.</p>" + 263 "<p>Never share secrets in screenshots you donât trust.</p>" 264 ), 265 "/SENDi!/": spaceSpaceDefault, 266 "/sendi/waiting.html": glance( 267 "Waiting to join", 268 "<p><strong>Hold</strong> until the host admits you or the Space becomes ready â common for video or gated Spaces.</p>" + 269 "<p>Keep the tab open; if nothing happens, check the code or ask the host.</p>" + 270 "<p>Leaving returns you to normal browsing â no account required.</p>" 271 ), 272 "/sendi/payment-success.html": glance( 273 "Payment success", 274 "<p>Confirms a <strong>completed payment</strong> step for Space or plan upgrades â read the on-page details.</p>" + 275 "<p>If features donât unlock, refresh after a minute or check <strong>Pricing</strong>.</p>" + 276 "<p>Billing questions belong in your receipt or support channel.</p>" 277 ), 278 279 "/governance/index.html": glance( 280 "Governance", 281 "<p>Overview of <strong>governance</strong> tools: proposals, voting, and shared decision flows.</p>" + 282 "<p>Not the same as <strong>Trust Check</strong> trust votes â read each screenâs purpose.</p>" + 283 "<p>Community admins configure whatâs open vs closed.</p>" 284 ), 285 "/governance/create.html": glance( 286 "Create governance", 287 "<p>Start a <strong>governance item</strong> â follow fields for title, options, and timing.</p>" + 288 "<p>Double-check visibility; some ballots are public by link.</p>" + 289 "<p>Abuse reporting may be available via <strong>Community</strong> contacts.</p>" 290 ), 291 "/governance/vote.html": glance( 292 "Public vote", 293 "<p>Cast a <strong>vote</strong> in a governance flow â one client id per device in many modes.</p>" + 294 "<p>Results may aggregate in real time or after close â see the page.</p>" + 295 "<p>This is <strong>not</strong> the Trust Index tier for domains.</p>" 296 ), 297 298 "/admin.html": glance( 299 "Admin", 300 "<p><strong>Operator sign-in</strong> for internal dashboards â use only credentials you were given.</p>" + 301 "<p>All actions should follow your organisationâs policy and local law.</p>" + 302 "<p>Public trust tools remain on the main site for everyone else.</p>" 303 ), 304 "/admin-broadcast.html": glance( 305 "Admin â Live broadcast", 306 "<p><strong>Live broadcast</strong> â extension/apps tab and Space tab for banners and emergency messages.</p>" + 307 "<p>Misuse can affect users; use least privilege.</p>" + 308 "<p>Log out on shared machines.</p>" 309 ), 310 "/admin-live.html": glance( 311 "Admin â Live broadcast", 312 "<p>Redirects to <strong>Live broadcast</strong> (Extension tab).</p>" 313 ), 314 "/admin-signal-warnings.html": glance( 315 "Admin â Signal warnings", 316 "<p>Manage <strong>signal warning</strong> rules and in-browser display config â operator-only, not end-user trust voting.</p>" + 317 "<p>Keep brand safety and regional rules in mind.</p>" + 318 "<p>Separate from <strong>Community</strong> settings in the public product UI.</p>" 319 ), 320 "/org-admin.html": glance( 321 "Org admin", 322 "<p><strong>Organisation</strong> administration: members, Spaces, or domains depending on your licence.</p>" + 323 "<p>Invite and revoke access carefully; hashes donât replace good access hygiene.</p>" + 324 "<p>See <strong>Pricing</strong> for seat limits.</p>" 325 ), 326 "/admin-trusted-domains.html": glance( 327 "Admin â Trusted domains", 328 "<p>Review or edit <strong>trusted domain</strong> lists used in product flows â incorrect entries change user trust signals.</p>" + 329 "<p>Coordinate with editorial or security before bulk changes.</p>" + 330 "<p>Changes may take time to propagate.</p>" 331 ), 332 "/admin-surveys.html": glance( 333 "Admin â Surveys", 334 "<p>Configure <strong>surveys</strong> and ballots that appear to users â wording matters for consent.</p>" + 335 "<p>Align with <strong>Privacy</strong> for data retention.</p>" + 336 "<p>Test in staging when available.</p>" 337 ), 338 "/admin-stats.html": glance( 339 "Admin â Stats", 340 "<p>Aggregate <strong>statistics</strong> for operations â not personal dossiers; still treat exports as sensitive.</p>" + 341 "<p>Use for capacity and health, not for profiling individuals.</p>" + 342 "<p>Follow your orgâs data-handling policy.</p>" 343 ), 344 "/admin-spaces.html": glance(
345 "Admin â Spaces", 346 "<p>Inspect or manage <strong>Space</strong> records for support and abuse response.</p>" + 347 "<p>Prefer self-service tools for users where possible.</p>" + 348 "<p>Escalate legal requests through proper channels.</p>" 349 ), 350 "/admin-signals.html": glance( 351 "Admin â Signals", 352 "<p>Review <strong>signals</strong> feeding trust or safety systems â false positives hurt real users.</p>" + 353 "<p>Correlate with other admin views before acting.</p>" + 354 "<p>Document reasons for overrides.</p>" 355 ), 356 "/admin-licenses.html": glance( 357 "Admin â Licenses", 358 "<p>Manage <strong>licences</strong>, keys, or entitlements â financial and access sensitive.</p>" + 359 "<p>Never post screenshots of keys in public channels.</p>" + 360 "<p>Match records to <strong>Pricing</strong> in the product.</p>" 361 ), 362 "/admin-hashes.html": glance( 363 "Admin â Hashes", 364 "<p>Technical view of <strong>hash</strong> identifiers â used for support and integrity checks.</p>" + 365 "<p>Hashes are not anonymity on their own if combined with other logs.</p>" + 366 "<p>Minimise retention and access.</p>" 367 ), 368 "/admin-extensions.html": glance( 369 "Admin â Extensions", 370 "<p><strong>Extension</strong> rollout and compatibility â store listings vs dev builds.</p>" + 371 "<p>Coordinate releases with browser review times.</p>" + 372 "<p>User-facing help stays on <strong>Tools</strong> and extension stores.</p>" 373 ), 374 "/admin-contact.html": glance( 375 "Admin â Contact", 376 "<p>Inbound <strong>contact</strong> or ticket queues for operators â may contain personal data.</p>" + 377 "<p>Reply from official channels only; watch for phishing.</p>" + 378 "<p>Delete or archive per policy.</p>" 379 ), 380 "/admin-api-licenses.html": glance( 381 "Admin â API licences", 382 "<p><strong>API keys</strong> and partner licences â rotate on suspicion of leak.</p>" + 383 "<p>Rate limits protect everyone; document partner tiers clearly.</p>" + 384 "<p>See <strong>Developer</strong> for public API surface.</p>" 385 ), 386 "/live-check-index.html": glance( 387 "Labour Coverage Index (concept)", 388 "<p><strong>Concept page</strong> for LCI â why a live complement to official stats (spend, time, stress, access).</p>" + 389 "<p><strong>Not</strong> Global Trust Index; open the <strong>LCI dashboard</strong> for the live score, trends, and nominal strips.</p>" + 390 "<p>Methodology evolves â interpret low-sample regions carefully on the dashboard.</p>" 391 ), 392 393 "/air-check.html": glance( 394 "Air Check (demo)", 395 "<p><strong>Live talk â visual context.</strong> Paste what was said; GriGsi searches <strong>free public indexes</strong> (Wikipedia, Wikidata, OpenStreetMap) and returns up to three candidates.</p>" + 396 "<p><strong>Source icons above the quote</strong> toggle Wikipedia, Wikidata, and OSM on or off with one tap â no submenu. If a quote is already pasted, results refresh immediately.</p>" + 397 "<p><strong>Images from the web</strong> are thumbnails or Commons URLs from those sources â GriGsi does not host them; your browser loads them directly from the origin site. <strong>You choose</strong> what goes to air; metaphors and political nicknames often need a human pick.</p>" + 398 "<p><strong>To air</strong> updates the OBS overlay via local sync. Demo tier only â no paid image API or studio mic yet. Pair with <strong>Trust Check</strong> when a claim needs verification, not just a picture.</p>" 399 ), 400 401 "/air-check/overlay.html": glance( 402 "Air Check â OBS overlay", 403 "<p><strong>Producer output only.</strong> This page shows the quote and image the producer approved on <strong>Air Check</strong> â add it as an OBS <strong>Browser Source</strong> (1920Ã1080).</p>" + 404 "<p><strong>Net images</strong> load from Wikipedia/Wikimedia or other public URLs shown as the source; GriGsi stores only the last payload in <strong>local browser storage</strong> for sync, not on a profile.</p>" + 405 "<p>Check <strong>licensing and context</strong> before broadcast â especially for news and political formats.</p>" 406 ), 407 408 "/open-data-hub/": glance( 409 "Open Data Hub", 410 "<p><strong>Discover</strong> public institutional APIs and datasets GriGsi uses or plans â ECB/Frankfurter, Eurostat, World Bank, commodities.</p>" + 411 "<p><strong>
411Search runs in your browser</strong> â no account, no query text sent for ranking.</p>" + 412 "<p>Phase 1 is <strong>links and documentation</strong>, not live query execution on your behalf.</p>" 413 ), 414 415 "/official-data-hub/": glance( 416 "GriGsi Official Data", 417 "<p><strong>BG fiscal transparency</strong> â ministries, budget COFOG lines, municipalities, procurement portals.</p>" + 418 "<p><strong>Live figures</strong> from Eurostat/NSI and EOP open procurement aggregates; discovery links to ÐФ, ÐÐÐ, ЦÐÐ.</p>" + 419 "<p>Signals flag sharp YoY changes or supplier concentration â <strong>not</strong> legal findings. Pair with <a href=\"/check-index.html\">Trust Check</a> for claims.</p>" 420 ), 421 422 "/life-pressure-mirror.html": glance( 423 "How strong is your money?", 424 "<p>Enter what you earn and spend. Press <strong>Calculate</strong>.</p>" + 425 "<p>First you see <strong>how strong your money is</strong>. Then <strong>what's left after bills</strong>.</p>" + 426 "<p>Compare two or more moments to see if things are getting easier or harder.</p>" + 427 "<p>Sources and methods are at the bottom if you want them.</p>" 428 ), 429 430 "/instant/": glance( 431 "SENDi!", 432 "<p><strong>SENDi!</strong>: one tap creates a link and code; share via QR or copy.</p>" + 433 "<p><strong>Join</strong> accepts any GriGsi link or code on one page.</p>" + 434 "<p>One-time codes stop working after first redemption.</p>" 435 ), 436 437 "/about.html": glance( 438 "About", 439 "<p><strong>Mission, context, and contact</strong> â how GriGsi thinks about trust, privacy, and experiments on the open web.</p>" + 440 "<p>Home page <strong>Contact</strong> or links here for partnership, press, or feedback.</p>" + 441 "<p>Deeper detail: <strong>Tools</strong>, <strong>Solutions</strong>, <strong>Services</strong>, <strong>FAQ</strong>.</p>" 442 ), 443 444 "/payment.html": glance( 445 "Payment", 446 "<p>Checkout or upgrade for <strong>Pro</strong>, <strong>Community</strong>, or Space-related plans â follow the on-page steps.</p>" + 447 "<p>Compare limits on <strong>Pricing</strong> before paying.</p>" + 448 "<p>Payments unlock features â not a personal advertising profile.</p>" 449 ), 450 }; 451 452 PAGES["/SENDi!/"] = spaceSpaceDefault; 453 PAGES["/SENDi!"] = spaceSpaceDefault; 454 PAGES["/sendi/"] = spaceSpaceDefault; 455 PAGES["/sendi"] = spaceSpaceDefault; 456 PAGES["/governance"] = PAGES["/governance/index.html"]; 457 PAGES["/connect"] = spaceSpaceDefault; 458 PAGES["/instant"] = PAGES["/instant/"]; 459 PAGES["/privacy"] = PAGES["/privacy.html"]; 460 461 function ensureHelpStyles() { 462 if (document.getElementById("grigsi-help-styles-link")) return; 463 var l = document.createElement("link"); 464 l.id = "grigsi-help-styles-link"; 465 l.rel = "stylesheet"; 466 l.href = "/css/grigsi-help.css?v=8"; 467 document.head.appendChild(l); 468 } 469 470 /** Collect pathname variants to match static hosts and pretty URLs. */ 471 function pathKeys() { 472 var raw = location.pathname || "/"; 473 var out = []; 474 function add(x) { 475 if (!x) return; 476 if (out.indexOf(x) === -1) out.push(x); 477 } 478 add(raw); 479 try { 480 add(decodeURIComponent(raw)); 481 } catch (_) {} 482 var p = raw; 483 if (p.length > 1 && p.slice(-1) === "/") p = p.slice(0, -1); 484 add(p); 485 if (raw.length > 1 && raw.slice(-1) !== "/") add(raw + "/"); 486 if (p.endsWith("/index.html")) { 487 add(p.slice(0, -"/index.html".length) || "/"); 488 } 489 if (p === "/index.html") add("/"); 490 if (p.endsWith(".html")) add(p.slice(0, -5)); 491 return out; 492 } 493 494 function resolvePage() { 495 var lang = helpLang(); 496 var bgPages = lang === "bg" && global.GriGsiHelpBgPages ? global.GriGsiHelpBgPages : null; 497 var bgDefaults = 498 lang === "bg" && global.GriGsiHelpBgDefaults ? global.GriGsiHelpBgDefaults : null; 499 var keys = pathKeys(); 500 var i; 501 for (i = 0; i < keys.length; i++) { 502 if (bgPages && bgPages[keys[i]]) return bgPages[keys[i]]; 503 if (PAGES[keys[i]]) return PAGES[keys[i]]; 504 } 505 var p = keys[0] || ""; 506 if (p === "/SENDi!/" || p === "/SENDi!" || p === "/sendi/" || p === "/sendi") { 507 return bgDefaults ? bgDefaults.spaceEntry : spaceEntryDefault; 508 } 509 if (p.indexOf("/SENDi!/") === 0 || /SENDi!?/i.test(p) || /^\/se
509ndi/i.test(p)) { 510 return bgDefaults ? bgDefaults.spaceSpace : spaceSpaceDefault; 511 } 512 return bgDefaults ? bgDefaults.site : siteDefault; 513 } 514 515 function applyHelpContent(cfg, ui) { 516 var titleEl = document.getElementById("grigsi-help-dialog-title"); 517 var bodyEl = document.getElementById("grigsi-help-dialog-body"); 518 var closeBtn = document.querySelector("#grigsi-help-dialog .grigsi-help-close"); 519 var label = document.querySelector("#grigsi-help-launch .grigsi-help-label"); 520 var btn = document.getElementById("grigsi-help-launch"); 521 if (titleEl && cfg) titleEl.innerHTML = cfg.title; 522 if (bodyEl && cfg) bodyEl.innerHTML = cfg.body; 523 if (closeBtn) closeBtn.textContent = ui.ok || "OK"; 524 if (label) label.textContent = ui.chipLabel; 525 if (btn) btn.setAttribute("aria-label", ui.chipAria); 526 } 527 528 /** Chip surface is light glass â label/chevron stay black for contrast. */ 529 function applyChipTextColors(btn, glyph, label) { 530 var ink = "#000000"; 531 [btn, glyph, label].forEach(function (el) { 532 if (!el) return; 533 el.style.setProperty("color", ink, "important"); 534 el.style.setProperty("-webkit-text-fill-color", ink, "important"); 535 }); 536 if (btn) btn.classList.add("grigsi-help-chip--dark-label"); 537 } 538 539 function build() { 540 if (document.documentElement.getAttribute("data-grigsi-help") === "off") return; 541 if (document.getElementById("grigsi-help-launch")) return; 542 ensureHelpStyles(); 543 544 var cfg = resolvePage(); 545 var ui = helpUi(); 546 547 var wrap = document.createElement("div"); 548 wrap.className = "grigsi-help-wrap grigsi-help-wrap-edge"; 549 wrap.setAttribute("aria-hidden", "false"); 550 551 var btn = document.createElement("button"); 552 btn.type = "button"; 553 btn.className = "grigsi-help-chip grigsi-help-chip-compact grigsi-glass-surface"; 554 btn.id = "grigsi-help-launch"; 555 btn.setAttribute("aria-haspopup", "dialog"); 556 btn.setAttribute("aria-controls", "grigsi-help-dialog"); 557 btn.setAttribute("aria-label", ui.chipAria); 558 btn.setAttribute("aria-expanded", "false"); 559 560 var glyph = document.createElement("span"); 561 glyph.className = "grigsi-help-glyph"; 562 glyph.setAttribute("aria-hidden", "true"); 563 glyph.textContent = HELP_CHIP_GLYPH; 564 565 var label = document.createElement("span"); 566 label.className = "grigsi-help-label"; 567 label.textContent = ui.chipLabel; 568 569 btn.appendChild(label); 570 btn.appendChild(glyph); 571 applyChipTextColors(btn, glyph, label); 572 573 var dialog = document.createElement("dialog"); 574 dialog.id = "grigsi-help-dialog"; 575 dialog.className = "grigsi-help-dialog"; 576 dialog.setAttribute("aria-labelledby", "grigsi-help-dialog-title"); 577 578 dialog.innerHTML = 579 '<div class="grigsi-help-dialog-inner">' + 580 '<h2 id="grigsi-help-dialog-title">' + 581 cfg.title + 582 "</h2>" + 583 '<div id="grigsi-help-dialog-body">' + 584 cfg.body + 585 "</div>" + 586 '<div class="grigsi-help-dialog-actions">' + 587 '<button type="button" class="grigsi-help-close" data-grigsi-help-close>' + 588 ui.ok + 589 "</button>" + 590 "</div></div>"; 591 592 wrap.appendChild(btn); 593 document.body.appendChild(wrap); 594 document.body.appendChild(dialog); 595 596 function openDialog() { 597 btn.setAttribute("aria-expanded", "true"); 598 try { 599 if (typeof dialog.showModal === "function") { 600 dialog.showModal(); 601 } else { 602 dialog.setAttribute("open", ""); 603 dialog.style.display = "block"; 604 } 605 } catch (_) { 606 dialog.setAttribute("open", ""); 607 dialog.style.display = "block"; 608 } 609 try { 610 dialog.querySelector(".grigsi-help-close").focus(); 611 } catch (_) {} 612 } 613 614 function closeDialog() { 615 btn.setAttribute("aria-expanded", "false"); 616 try { 617 if (typeof dialog.close === "function") dialog.close(); 618 } catch (_) {} 619 dialog.removeAttribute("open"); 620 dialog.style.display = ""; 621 try { 622 btn.focus(); 623 } catch (_) {} 624 } 625 626 btn.addEventListener("click", function (e) { 627 e.preventDefault(); 628 openDialog(); 629 }); 630 631 dialog.addEventListener("click", function (e) { 632 if (e.target === dialog) closeDialog(); 633 }); 634 635 dialog.addEventListener("keydown", function (e) { 636 if (e.key === "Escape") { 637 e.preventDefault(); 638 closeDialog(); 639 } 640 }); 641 642 dialog.querySelectorAll("[data-grigsi-help-close]").forEach(function (el) { 643 el.addEventListener("click", closeDialog); 644 }); 645 646 global.addEventListener("grigsi-site-lang", function () { 647 var next = resolvePage(); 648 var nextUi = helpUi(); 649 applyHelpContent(next, nextUi); 650 }); 651 } 652 653 if (document.readyState === "loading") { 654 document.addEventListener("DOMContentLoaded", build); 655 } else { 656 build(); 657 } 658 659 (function () { 660 var s = document.createElement("script"); 661 s.src = "/js/grigsi-guide-loader.js?v=3"; 662 s.defer = true; 663 document.head.appendChild(s); 664 })(); 665 666 // sendi.js/sendi.html are frozen canon (see .cursor/rules/sendi-canon.mdc), so the SENDi-only 667 // media-analyze add-on can't get a <script> tag added there directly â it loads itself from here 668 // instead, same pathname check resolvePage() above already uses for SENDi's own help content. 669 (function () { 670 var p = ""; 671 try { p = global.location.pathname || ""; } catch (_) { return; } 672 if (!(p.indexOf("/SENDi!/") === 0 || /SENDi!?/i.test(p) || /^\/se
672ndi/i.test(p))) return; 673 var s = document.createElement("script"); 674 s.src = "/js/sendi-media-analyze.js?v=2"; 675 s.defer = true; 676 document.head.appendChild(s); 677 })(); 678})();
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.