{"version":3,"sources":["menu-panels.mjs"],"sourcesContent":["// THE MENU PANELS' OWN RULES (the menu-panels plan the owner confirmed on Oct 6: Friends, Claims, Bookmarks, Marketplace,\n// Kubipedia, How to play, Send feedback and Settings, plus three choices across them). The panels are drawn in app.js;\n// what they DECIDE lives here, pure, so tests/menu-panels.test.mjs can hold each decision to what was picked without\n// a browser: which colour a panel's selected tabs wear, how a list is ordered, which sales count as \"usually\", what a\n// device string shortens to, which getting-started steps are done.\n//\n// No imports and no DOM: this file runs in the page, in node for the tests, and on Safari 15 (the iPad Air 2 floor),\n// so nothing newer than the rest of the game may appear in it.\n\n// ---- ACROSS THE PANELS: \"Each panel's menu colour\" -----------------------------------------------------------------\n// A panel's selected tab, chip and segment wear the colour of its row in the menu, as How to play already did, so the\n// menu and the panel it opens read as one thing. The values are the menu's own (app.js menuItems, chosen there for\n// contrast); tests/menu-panels.test.mjs checks the two lists agree. Bookmarks is coral, which also means \"kept\" there:\n// a selected control in that panel is the panel's own colour, and that is the same claim. Spectate stays scout blue and\n// confirm buttons stay blue in every panel: those colours are meanings, not decoration.\nexport const PANEL_ACCENT = Object.freeze({\n  friends: '#FFB6C1', claims: '#32CD32', bookmarks: '#FF7F50', marketplace: '#EE82EE',\n  kubipedia: '#FFDEAD', howto: '#AFEEEE', feedback: '#D2B48C', settings: '#E5E5E5',\n  search: '#FFFF00',   // the Navigation Overhaul's Search panel (Oct 7)\n});\n\n// ---- CLAIMS: \"Sort menu\" -------------------------------------------------------------------------------------------\n// Newest first is the default, and it never moves: the old most-built order took its counts from card metadata that\n// arrives one card at a time after the panel opens, so cards jumped under the pointer. Most built is still offered, and\n// waits until every count is in (claimOrder's `ready`) before it reorders anything.\nexport const CLAIM_SORTS = Object.freeze([['new', 'Newest'], ['built', 'Most built'], ['name', 'Name'], ['size', 'Size']]);\nconst tsOf = (t) => (t && t.toMillis ? t.toMillis() : (t && t.seconds ? t.seconds * 1000 : Number(t) || 0));\nexport function claimOrder(claims, key, builtOf, ready) {\n  const list = (claims || []).slice();\n  const newest = (a, b) => tsOf(b.claimedAt) - tsOf(a.claimedAt);\n  const nameOf = (c) => String(c.name || c.addr || '').toLowerCase();\n  if (key === 'built' && ready) return list.sort((a, b) => (builtOf(b) - builtOf(a)) || newest(a, b));\n  if (key === 'name') return list.sort((a, b) => nameOf(a).localeCompare(nameOf(b)) || newest(a, b));\n  if (key === 'size') return list.sort((a, b) => ((b.diameter || 0) - (a.diameter || 0)) || newest(a, b));\n  return list.sort(newest);\n}\n// The access chip on a claim card: who besides its owner may build there, from the claim itself.\nexport function accessOf(claim) {\n  const c = claim || {};\n  if (c.allowAllFriends) return { icon: 'friends', text: 'All friends' };\n  const n = Array.isArray(c.builders) ? c.builders.length : 0;\n  return n ? { icon: 'friends', text: n === 1 ? '1 builder' : n + ' builders' } : { icon: 'lock', text: 'Private' };\n}\n// The activity badge: world_log rows from the last week, one per editor per hour, folded into players per world.\nexport const ACTIVITY_DAYS = 7;\nexport function activityByWorld(rows, sinceMs) {\n  const out = new Map();\n  for (const r of rows || []) {\n    if (!r || !r.addr || !r.uid || !(Number(r.hour) >= sinceMs)) continue;\n    const addr = String(r.addr).replace(/_/g, '.');\n    if (!out.has(addr)) out.set(addr, new Set());\n    out.get(addr).add(r.uid);\n  }\n  return out;\n}\nexport const activityLine = (n) => (n === 1 ? '1 player this week' : n + ' players this week');\n// ONE PLAIN STATUS LINE PER CLAIM (the owner's play review, Oct 23, u6: \"show one plain status line per claim (\\\"2 builders ·\n// 340 kubes built · visited today\\\")\"). The owner's fourteen cards had seven \"Unnamed\" ones and five stat lines each in small\n// type, so the cards could not be told apart at a glance. One line now says the three things a world differs by: who builds\n// there besides you, how much is built, and when you were last there. `visitedAt` is this device's own record (the world\n// card's history, world-card.mjs visitRec), so a world never visited here says nothing about visits rather than \"never\".\n// A claim whose builds are hidden from visitors (f4) says so first.\nexport function visitWord(at, now) {\n  if (!(at > 0)) return '';\n  const t = now || Date.now();\n  const day = (ms) => { const d = new Date(ms); return Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()) / 86400000; };   // the local calendar day\n  const days = Math.max(0, Math.round(day(t) - day(at)));\n  if (days === 0) return 'visited today';\n  if (days === 1) return 'visited yesterday';\n  if (days < 14) return 'visited ' + days + ' days ago';\n  const weeks = Math.round(days / 7);\n  return weeks < 9 ? 'visited ' + weeks + ' weeks ago' : 'visited ' + Math.round(days / 30) + ' months ago';\n}\nexport function claimStatusLine(claim, built, visitedAt, now) {\n  const c = claim || {}, parts = [];\n  if (c.hidden === true) parts.push('Hidden');\n  const n = Array.isArray(c.builders) ? c.builders.length : 0;\n  parts.push(c.allowAllFriends ? 'all friends build' : n ? (n === 1 ? '1 builder' : n + ' builders') : 'only you build');\n  const b = Math.max(0, Math.floor(Number(built) || 0));\n  parts.push(b ? b.toLocaleString('en-US') + (b === 1 ? ' kube built' : ' kubes built') : 'nothing built yet');\n  const v = visitWord(visitedAt, now);\n  if (v) parts.push(v);\n  const line = parts.join(' · ');\n  return line.charAt(0).toUpperCase() + line.slice(1);\n}\n\n// ---- BOOKMARKS -----------------------------------------------------------------------------------------------------\n// Search matches a place by its name, its address or its kind (\"moon\", \"star\"), case-blind.\nexport function bmMatches(q, name, addr, cls) {\n  const s = String(q || '').trim().toLowerCase();\n  if (!s) return true;\n  return (String(name || '') + ' ' + String(addr || '') + ' ' + String(cls || '')).toLowerCase().includes(s);\n}\nexport const BM_NOTE_MAX = 60;\nexport const bmCleanNote = (s) => String(s == null ? '' : s).replace(/\\s+/g, ' ').trim().slice(0, BM_NOTE_MAX);\n// Who may read a group (firestore.rules bookmark_groups). A group from before sharing has no `share` and is private.\nexport const BM_SHARES = Object.freeze([['private', 'Only me'], ['friends', 'My friends'], ['public', 'Anyone with the link']]);\nexport const bmShareOf = (g) => (g && (g.share === 'friends' || g.share === 'public') ? g.share : 'private');\n// Moving a group up or down swaps its order with its neighbour's, and only those two documents are written.\nexport function bmSwapOrder(groups, id, dir) {\n  const list = (groups || []).slice().sort((a, b) => (a.order || 0) - (b.order || 0));\n  const i = list.findIndex((g) => g.id === id), j = i + (dir < 0 ? -1 : 1);\n  if (i < 0 || j < 0 || j >= list.length) return null;\n  const a = list[i], b = list[j];\n  // Equal orders (two groups made in one session both read their order from a stale count) swap to distinct ones.\n  const oa = a.order || 0, ob = b.order || 0;\n  return oa === ob ? [[a.id, ob + (dir < 0 ? -1 : 1)], [b.id, oa]] : [[a.id, ob], [b.id, oa]];\n}\n\n// ---- MARKETPLACE: \"Typical prices\" ---------------------------------------------------------------------------------\n// The Sold tab's last sales, banded by world size. \"Usually\" is the middle half of a band's prices (the 25th to the\n// 75th percentile), so one fire sale or one silly price does not set the line; a band with a single sale says so.\nexport const PRICE_BANDS = Object.freeze([[24, 31], [32, 47], [48, Infinity]]);\nfunction pct(sorted, p) {\n  if (!sorted.length) return 0;\n  const i = (sorted.length - 1) * p, lo = Math.floor(i), hi = Math.ceil(i);\n  return Math.round(sorted[lo] + (sorted[hi] - sorted[lo]) * (i - lo));\n}\nexport function priceBands(sales) {\n  return PRICE_BANDS.map(([lo, hi]) => {\n    const prices = (sales || []).filter((s) => {\n      const d = Number(s && s.worldMetadata && s.worldMetadata.diameter) || 0;\n      return d >= lo && d <= hi && Number(s.soldPrice) > 0;\n    }).map((s) => Number(s.soldPrice)).sort((a, b) => a - b);\n    return { label: hi === Infinity ? 'Ø' + lo + '+' : 'Ø' + lo + '–' + hi, n: prices.length,\n             lo: pct(prices, 0.25), hi: pct(prices, 0.75) };\n  }).filter((b) => b.n > 0);\n}\n// \"Kind and air chips\": a world's class word from its card metadata (\"Rocky Moon\" → moon), and whether it has air.\nexport const MKT_KINDS = Object.freeze([['planet', 'Planets'], ['moon', 'Moons'], ['air', 'Has air']]);\nexport function mktKindOk(kinds, meta) {\n  const m = meta || {}, cls = String(m.cls || '').toLowerCase();\n  for (const k of kinds || []) {\n    if (k === 'planet' && !/planet/.test(cls)) return false;\n    if (k === 'moon' && !/moon/.test(cls)) return false;\n    if (k === 'air' && !(m.atmo && Number(m.atmo.pressureMbar) > 0)) return false;\n  }\n  return true;\n}\n\n// ---- HOW TO PLAY: \"Checklist with ticks\" ---------------------------------------------------------------------------\n// Each getting-started step is ticked from the steps funnel() already keeps on this device, with or without analytics\n// consent (they only leave the device with it). \"Enter a system\" is ticked by 'dive', the first time a system view is\n// entered (QA F-69: it used to wait for a landing or a claim, so a player who had dived into a dozen systems was still\n// told to), and still by a landing or a claim, which an older device recorded before 'dive' existed. \"Travel\" is ticked\n// by a paid trip, a guest's included: a guest's energy is kept on the device, and their trips used to record nothing.\nexport const HOWTO_DONE_BY = Object.freeze([['arrive'], ['travel', 'land', 'claim'], ['dive', 'land', 'claim'], ['claim'], ['land'], ['craft']]);\nexport function howtoTicks(steps) {\n  const s = steps || {};\n  return HOWTO_DONE_BY.map((names) => names.some((n) => !!s[n]));\n}\n\n// ---- SEND FEEDBACK: \"Short details + Retake\" -----------------------------------------------------------------------\n// A user-agent string, shortened to what a person reads: the browser, its major version and the system. The whole\n// string still goes with the report; this is only what the panel shows unfolded.\nexport function uaShort(ua) {\n  const s = String(ua || '');\n  const pick = (re) => { const m = re.exec(s); return m ? m[1] : ''; };\n  let browser = '';\n  if (/Edg\\//.test(s)) browser = 'Edge ' + pick(/Edg\\/(\\d+)/);\n  else if (/OPR\\//.test(s)) browser = 'Opera ' + pick(/OPR\\/(\\d+)/);\n  else if (/Firefox\\//.test(s)) browser = 'Firefox ' + pick(/Firefox\\/(\\d+)/);\n  else if (/CriOS\\//.test(s)) browser = 'Chrome ' + pick(/CriOS\\/(\\d+)/);\n  else if (/Chrome\\//.test(s)) browser = 'Chrome ' + pick(/Chrome\\/(\\d+)/);\n  else if (/Version\\/[\\d.]+.*Safari/.test(s)) browser = 'Safari ' + pick(/Version\\/(\\d+(?:\\.\\d+)?)/);\n  const os = /iPad/.test(s) ? 'iPadOS' : /iPhone/.test(s) ? 'iOS' : /Android/.test(s) ? 'Android'\n           : /Mac OS X/.test(s) ? 'macOS' : /Windows/.test(s) ? 'Windows' : /CrOS/.test(s) ? 'ChromeOS' : /Linux/.test(s) ? 'Linux' : '';\n  return [browser.trim(), os].filter(Boolean).join(' · ') || s.slice(0, 40);\n}\n// The topic chips. 'player' is not among them: a report about a player goes to the Report dialog (SAFE-03) instead.\n// Account and privacy stay, because the Privacy Policy sends privacy requests to this inbox.\nexport const FEEDBACK_TOPICS = Object.freeze([['bug', 'Bug'], ['idea', 'Idea'], ['question', 'Question'], ['payment', 'Payment'],\n                                               ['account', 'Account'], ['privacy', 'Privacy'], ['other', 'Other']]);\n\n// ---- SETTINGS ------------------------------------------------------------------------------------------------------\n// \"Section tabs\", opening on the game's own settings. Contact us and Your data keep those names inside Account,\n// because the Terms and the Privacy Policy send players to them by name.\nexport const SETTINGS_TABS = Object.freeze([['game', 'palette', 'Game'], ['controls', 'game', 'Controls'], ['sound', 'sound', 'Sound'],\n                                             ['account', 'lock', 'Account'], ['about', 'info', 'About']]);\nexport const SETTINGS_FIRST = 'game';\n"],"mappings":"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","names":["a","b"],"file":"menu-panels.mjs"}