@getmicdrop/venue-calendar 4.0.127 → 4.0.129
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{CartView-DxD21kDr.js → CartView-C-NjOBzR.js} +10 -10
- package/dist/CartView-C-NjOBzR.js.map +1 -0
- package/dist/{Checkout-D3mmS4cy.js → Checkout-ChP80VIP.js} +9 -9
- package/dist/Checkout-ChP80VIP.js.map +1 -0
- package/dist/{Checkout-BRaI7OY7.js → Checkout-DaTZECFC.js} +10 -10
- package/dist/Checkout-DaTZECFC.js.map +1 -0
- package/dist/{CheckoutTimer-CRhI7pZK.js → CheckoutTimer-d0aoC593.js} +5 -5
- package/dist/{CheckoutTimer-CRhI7pZK.js.map → CheckoutTimer-d0aoC593.js.map} +1 -1
- package/dist/{ClockIcon-DGDxHgmO.js → ClockIcon-BaYkwRlk.js} +8 -8
- package/dist/ClockIcon-BaYkwRlk.js.map +1 -0
- package/dist/{CollectionView-S4uJ2wLg.js → CollectionView-b-IZOMeL.js} +5 -5
- package/dist/{CollectionView-S4uJ2wLg.js.map → CollectionView-b-IZOMeL.js.map} +1 -1
- package/dist/{Event-pzURHNSi.js → Event-CtpE-mzC.js} +162 -158
- package/dist/Event-CtpE-mzC.js.map +1 -0
- package/dist/{EventPage-fzfsDgHU.js → EventPage-DVO1vpj7.js} +96 -96
- package/dist/EventPage-DVO1vpj7.js.map +1 -0
- package/dist/{Heading-CxtpAlu5.js → Heading-BdN1Ht0e.js} +2 -2
- package/dist/{Heading-CxtpAlu5.js.map → Heading-BdN1Ht0e.js.map} +1 -1
- package/dist/{ScarcityBadge-BQdPp1pp.js → ScarcityBadge-4GVhzxq0.js} +41 -41
- package/dist/ScarcityBadge-4GVhzxq0.js.map +1 -0
- package/dist/{SeriesPage-DWbpSYCA.js → SeriesPage--e06RRFW.js} +5 -5
- package/dist/{SeriesPage-DWbpSYCA.js.map → SeriesPage--e06RRFW.js.map} +1 -1
- package/dist/{Spinner-C0UV0yLk.js → Spinner-BCL8SPFf.js} +2 -2
- package/dist/{Spinner-C0UV0yLk.js.map → Spinner-BCL8SPFf.js.map} +1 -1
- package/dist/{Success-CeQqi-83.js → Success-BOUw7rfW.js} +156 -156
- package/dist/Success-BOUw7rfW.js.map +1 -0
- package/dist/{Text-CAeBIFaG.js → Text-MKI6YYj1.js} +2 -2
- package/dist/{Text-CAeBIFaG.js.map → Text-MKI6YYj1.js.map} +1 -1
- package/dist/{VenueCalendar-Z3o1Q_1m.js → VenueCalendar-B7NJwKM-.js} +17 -19
- package/dist/VenueCalendar-B7NJwKM-.js.map +1 -0
- package/dist/{ViewTicketsEmbed-JQvQN8R2.js → ViewTicketsEmbed-_827ZCtN.js} +5 -5
- package/dist/{ViewTicketsEmbed-JQvQN8R2.js.map → ViewTicketsEmbed-_827ZCtN.js.map} +1 -1
- package/dist/{labels-C7WvkYI1.js → labels-DTDdXrGU.js} +4 -4
- package/dist/labels-DTDdXrGU.js.map +1 -0
- package/dist/{modalManager.svelte-DXzFxr7l.js → modalManager.svelte-BkbIxqh6.js} +2 -2
- package/dist/{modalManager.svelte-DXzFxr7l.js.map → modalManager.svelte-BkbIxqh6.js.map} +1 -1
- package/dist/{promo-B7xiyb84.js → promo-BE3T-hcB.js} +2 -2
- package/dist/{promo-B7xiyb84.js.map → promo-BE3T-hcB.js.map} +1 -1
- package/dist/{shareCopyFeedback.svelte-CJGSyRw6.js → shareCopyFeedback.svelte-CmMjtjDb.js} +31 -31
- package/dist/shareCopyFeedback.svelte-CmMjtjDb.js.map +1 -0
- package/dist/{showcase-state-options-HOZDtWBN.js → showcase-state-options-D3wJ9rXK.js} +2 -2
- package/dist/{showcase-state-options-HOZDtWBN.js.map → showcase-state-options-D3wJ9rXK.js.map} +1 -1
- package/dist/{transform-CjTzBTM9.js → transform-DP_B2tnC.js} +2 -2
- package/dist/{transform-CjTzBTM9.js.map → transform-DP_B2tnC.js.map} +1 -1
- package/dist/{utm-BjrvAc5o.js → utm-BAXDZxaq.js} +2 -2
- package/dist/{utm-BjrvAc5o.js.map → utm-BAXDZxaq.js.map} +1 -1
- package/dist/venue-calendar.css +1 -1
- package/dist/venue-calendar.es.js +2 -2
- package/dist/venue-calendar.iife.js +5 -5
- package/dist/venue-calendar.iife.js.map +1 -1
- package/dist/venue-calendar.umd.js +4 -4
- package/dist/venue-calendar.umd.js.map +1 -1
- package/package.json +2 -2
- package/dist/CartView-DxD21kDr.js.map +0 -1
- package/dist/Checkout-BRaI7OY7.js.map +0 -1
- package/dist/Checkout-D3mmS4cy.js.map +0 -1
- package/dist/ClockIcon-DGDxHgmO.js.map +0 -1
- package/dist/Event-pzURHNSi.js.map +0 -1
- package/dist/EventPage-fzfsDgHU.js.map +0 -1
- package/dist/ScarcityBadge-BQdPp1pp.js.map +0 -1
- package/dist/Success-CeQqi-83.js.map +0 -1
- package/dist/VenueCalendar-Z3o1Q_1m.js.map +0 -1
- package/dist/labels-C7WvkYI1.js.map +0 -1
- package/dist/shareCopyFeedback.svelte-CJGSyRw6.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"labels-C7WvkYI1.js","sources":["../node_modules/@getmicdrop/svelte-components/dist/primitives/Icons/phosphor/CalendarIcon.svelte","../src/lib/api/cta.ts","../src/lib/public-calendar-flow/defaults.ts","../src/lib/public-calendar-flow/OrderSummary.svelte","../src/lib/public-calendar-flow/i18n/labels.js"],"sourcesContent":["<script lang=\"ts\">\r\n /**\r\n * Calendar — Phosphor icon (canonical Micdrop icon family).\r\n * Outline by default; pass `weight=\"fill\"` for solid, or let a stateful parent\r\n * (NavItem / Tabs / BottomNav / status badge) drive it via icon-weight context.\r\n */\r\n import { useIconWeight, type IconWeight } from './iconWeight.js';\r\n\r\n interface Props {\r\n /** Pixel size (width + height). */\r\n size?: string;\r\n /** Icon color; defaults to `currentColor` (inherits text color). */\r\n color?: string;\r\n /** Extra classes. */\r\n class?: string;\r\n /** `regular` (outline) or `fill` (solid). Overrides ambient state weight. */\r\n weight?: IconWeight;\r\n }\r\n\r\n let { size = '24', color = 'currentColor', class: className = '', weight }: Props = $props();\r\n\r\n const ctx = useIconWeight();\r\n let resolved: IconWeight = $derived(weight ?? ctx?.weight ?? 'regular');\r\n</script>\r\n\r\n<svg\r\n class={className}\r\n aria-hidden=\"true\"\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 256 256\"\r\n fill=\"currentColor\"\r\n style:color={color}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n>\r\n {#if resolved === 'fill'}<path d=\"M208,32H184V24a8,8,0,0,0-16,0v8H88V24a8,8,0,0,0-16,0v8H48A16,16,0,0,0,32,48V208a16,16,0,0,0,16,16H208a16,16,0,0,0,16-16V48A16,16,0,0,0,208,32ZM112,184a8,8,0,0,1-16,0V132.94l-4.42,2.22a8,8,0,0,1-7.16-14.32l16-8A8,8,0,0,1,112,120Zm56-8a8,8,0,0,1,0,16H136a8,8,0,0,1-6.4-12.8l28.78-38.37A8,8,0,1,0,145.07,132a8,8,0,1,1-13.85-8A24,24,0,0,1,176,136a23.76,23.76,0,0,1-4.84,14.45L152,176ZM48,80V48H72v8a8,8,0,0,0,16,0V48h80v8a8,8,0,0,0,16,0V48h24V80Z\"/>{:else}<rect x=\"40\" y=\"40\" width=\"176\" height=\"176\" rx=\"8\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"/><line x1=\"176\" y1=\"24\" x2=\"176\" y2=\"56\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"/><line x1=\"80\" y1=\"24\" x2=\"80\" y2=\"56\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"/><line x1=\"40\" y1=\"88\" x2=\"216\" y2=\"88\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"/><polyline points=\"88 128 104 120 104 184\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"/><path d=\"M138.14,128a16,16,0,1,1,26.64,17.63L136,184h32\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"/>{/if}\r\n</svg>\r\n","/**\r\n * CTA state computation.\r\n *\r\n * Pure function (no I/O) — derives the buy-button state from an event and\r\n * its ticket list. Lives in `api/` because it is the canonical, single\r\n * source of truth that replaces the duplicate implementations previously\r\n * scattered across utils/api.js, core/api-client.js, and a few components.\r\n */\r\n\r\n// Import from the specific subpath (not the bare entry) so the api/\r\n// bundle doesn't pull in the entire SC component graph (Accordion etc.)\r\n// and break `npm run build:api`. `formatLocal` is the sanctioned browser-local\r\n// (no-timezone) Intl label home — these \"On sale …\" countdown labels render in\r\n// the viewer's own clock, so no venue timezone applies. The datetime subpath is\r\n// leaf/component-free; only `formatLocal` (→ Intl) is pulled, no date-fns.\r\nimport {\r\n browserNow,\r\n compareInstants,\r\n formatLocal,\r\n toInstantOrNull,\r\n} from '@getmicdrop/svelte-components/datetime';\r\n// Hidden-ticket predicate from the `/transforms` leaf subpath (no component\r\n// graph, so `npm run build:api` stays clean). SC's copy was pinned FROM this\r\n// body (dedup #392) and additionally honours the backend-resolved\r\n// `effectiveSales*` window for relative-offset tickets (#388). Imported (not\r\n// just re-exported) so it stays in local scope for `computeCtaState` below.\r\nimport { isHiddenTicketPurchasable } from '@getmicdrop/svelte-components/transforms';\r\n\r\nexport interface CtaStateOptions {\r\n cancelled?: boolean;\r\n isRegistration?: boolean;\r\n waitlistEnabled?: boolean;\r\n}\r\n\r\nexport interface CtaState {\r\n text: string;\r\n disabled: boolean;\r\n reason:\r\n | 'cancelled'\r\n | 'event_past'\r\n | 'no_tickets'\r\n | 'available'\r\n | 'coming_soon'\r\n | 'sold_out_waitlist'\r\n | 'sold_out'\r\n | 'sales_ended'\r\n | 'hidden_only';\r\n}\r\n\r\ninterface CtaEvent {\r\n startDateTime?: string | null;\r\n endDateTime?: string | null;\r\n hasPurchasableHiddenTickets?: boolean;\r\n}\r\n\r\ninterface CtaTicket {\r\n salesChannel?: number;\r\n salesBegin?: string | null;\r\n salesStart?: string | null;\r\n saleBegin?: string | null;\r\n onSaleStart?: string | null;\r\n salesEnd?: string | null;\r\n saleEnd?: string | null;\r\n onSaleEnd?: string | null;\r\n remainingCapacity?: number | null;\r\n quantityRemaining?: number | null;\r\n quantity?: number | null;\r\n soldOut?: boolean;\r\n isHidden?: boolean;\r\n visibility?: number;\r\n}\r\n\r\n// A hidden ticket (visibility>=2 or isHidden) that's still on sale drives the\r\n// \"Sales ended\" / \"Sold out\" / \"No tickets\" → \"Get tickets\" override. The user\r\n// just needs the promo code to see it. Re-exported from the SC canonical so\r\n// existing consumers (cta.test.ts, computeCtaState) keep their import path while\r\n// the single-source body lives in SC (dedup #392).\r\nexport { isHiddenTicketPurchasable };\r\n\r\nexport function computeCtaState(\r\n event: CtaEvent,\r\n tickets: CtaTicket[] | undefined,\r\n options: CtaStateOptions = {}\r\n): CtaState {\r\n const {\r\n cancelled = false,\r\n isRegistration = false,\r\n waitlistEnabled = false,\r\n } = options;\r\n const now = browserNow();\r\n\r\n if (cancelled)\r\n return { text: 'Cancelled', disabled: true, reason: 'cancelled' };\r\n\r\n const eventEnd = toInstantOrNull(event.endDateTime || event.startDateTime);\r\n if (eventEnd && compareInstants(eventEnd, now) < 0) {\r\n return { text: 'Sales ended', disabled: true, reason: 'event_past' };\r\n }\r\n\r\n const hiddenAvailable =\r\n event?.hasPurchasableHiddenTickets === true ||\r\n (Array.isArray(tickets) && tickets.some(isHiddenTicketPurchasable));\r\n\r\n const publicTickets = (tickets || []).filter(\r\n t =>\r\n t.salesChannel !== 2 &&\r\n !t.isHidden &&\r\n !(typeof t.visibility === 'number' && t.visibility >= 2)\r\n );\r\n if (publicTickets.length === 0) {\r\n if (hiddenAvailable) {\r\n return {\r\n text: isRegistration ? 'Reserve a spot' : 'Get tickets',\r\n disabled: false,\r\n reason: 'hidden_only',\r\n };\r\n }\r\n return {\r\n text: 'No tickets available',\r\n disabled: true,\r\n reason: 'no_tickets',\r\n };\r\n }\r\n\r\n let hasPurchasable = false;\r\n let allSoldOut = true;\r\n let allComingSoon = true;\r\n let earliestSalesStart: Date | null = null;\r\n\r\n for (const ticket of publicTickets) {\r\n const salesBegin = toInstantOrNull(\r\n ticket.salesBegin ||\r\n ticket.salesStart ||\r\n ticket.saleBegin ||\r\n ticket.onSaleStart\r\n );\r\n const salesEnd = toInstantOrNull(\r\n ticket.salesEnd || ticket.saleEnd || ticket.onSaleEnd\r\n );\r\n const remaining =\r\n ticket.remainingCapacity ?? ticket.quantityRemaining ?? ticket.quantity;\r\n const isSoldOut =\r\n ticket.soldOut ||\r\n (remaining !== null && remaining !== undefined && remaining <= 0);\r\n\r\n const isScheduled = salesBegin\r\n ? compareInstants(salesBegin, now) > 0\r\n : false;\r\n const hasSalesEnded = salesEnd ? compareInstants(salesEnd, now) < 0 : false;\r\n const isPurchasable = !isSoldOut && !isScheduled && !hasSalesEnded;\r\n\r\n if (isPurchasable) hasPurchasable = true;\r\n if (!isSoldOut) allSoldOut = false;\r\n if (!isScheduled) allComingSoon = false;\r\n\r\n if (isScheduled && salesBegin && !isSoldOut && !hasSalesEnded) {\r\n if (\r\n !earliestSalesStart ||\r\n compareInstants(salesBegin, earliestSalesStart) < 0\r\n ) {\r\n earliestSalesStart = salesBegin;\r\n }\r\n }\r\n }\r\n\r\n if (hasPurchasable) {\r\n return {\r\n text: isRegistration ? 'Reserve a spot' : 'Get tickets',\r\n disabled: false,\r\n reason: 'available',\r\n };\r\n }\r\n\r\n if (allComingSoon && earliestSalesStart) {\r\n if (hiddenAvailable) {\r\n return {\r\n text: isRegistration ? 'Reserve a spot' : 'Get tickets',\r\n disabled: false,\r\n reason: 'hidden_only',\r\n };\r\n }\r\n const diffMs = compareInstants(earliestSalesStart, now);\r\n const diffHours = diffMs / (1000 * 60 * 60);\r\n const diffDays = diffMs / (1000 * 60 * 60 * 24);\r\n // Viewer-local time label (\"8:00 PM\") — the shape shared by the <24h branch\r\n // and the >7d composite. Matches the deprecated `formatTime(d,{hour12:true})`\r\n // defaults-merge exactly.\r\n const timeLabel = (d: Date) =>\r\n formatLocal(\r\n d,\r\n { hour: 'numeric', minute: '2-digit', hour12: true },\r\n 'en-US'\r\n );\r\n let dateText: string;\r\n if (diffHours < 24) {\r\n dateText = timeLabel(earliestSalesStart);\r\n } else if (diffDays <= 7) {\r\n dateText = formatLocal(\r\n earliestSalesStart,\r\n { weekday: 'short', hour: 'numeric', minute: '2-digit', hour12: true },\r\n 'en-US'\r\n );\r\n } else {\r\n const d = formatLocal(\r\n earliestSalesStart,\r\n { month: 'short', day: 'numeric' },\r\n 'en-US'\r\n );\r\n dateText = `${d} ${timeLabel(earliestSalesStart)}`;\r\n }\r\n return {\r\n text: `On sale ${dateText}`,\r\n disabled: true,\r\n reason: 'coming_soon',\r\n };\r\n }\r\n\r\n if (allSoldOut) {\r\n if (hiddenAvailable) {\r\n return {\r\n text: isRegistration ? 'Reserve a spot' : 'Get tickets',\r\n disabled: false,\r\n reason: 'hidden_only',\r\n };\r\n }\r\n if (waitlistEnabled) {\r\n return {\r\n text: 'Join Waitlist',\r\n disabled: false,\r\n reason: 'sold_out_waitlist',\r\n };\r\n }\r\n return { text: 'Sold out', disabled: true, reason: 'sold_out' };\r\n }\r\n\r\n if (hiddenAvailable) {\r\n return {\r\n text: isRegistration ? 'Reserve a spot' : 'Get tickets',\r\n disabled: false,\r\n reason: 'hidden_only',\r\n };\r\n }\r\n\r\n return { text: 'Sales ended', disabled: true, reason: 'sales_ended' };\r\n}\r\n","// @currency-escape: feeCents / 100 in calculateServiceFee is arithmetic,\r\n// not display. Produces a dollar-magnitude number used in the fee formula\r\n// `price * (feePercentage / 100) + feeCents / 100`. Per Atlas\r\n// utility-currency convergence record; the no-handrolled-currency\r\n// ESLint rule's divideByHundred detector treats variable-name `Cents`\r\n// as drift but here it's real math.\r\n\r\n// Premium Ticket Experience — Constants & Defaults\r\n// Used by all design variants. DO NOT MODIFY per-variant.\r\n\r\n// This file is the canonical formatter module for public-calendar-flow: it\r\n// wraps + re-exports the timezone-aware production date/time formatters, plus\r\n// the shared sales-countdown formatter (formatSmartSalesDate) hoisted into\r\n// svelte-components (SC #471). No raw Intl date formatting lives here anymore.\r\n\r\nimport type {\r\n EventData,\r\n TicketTypeData,\r\n ScarcityLevel,\r\n CtaConfig,\r\n PromoCodeState,\r\n} from './types';\r\nimport { computeCtaState } from '$lib/api';\r\nimport {\r\n computeScarcityLevel,\r\n SCARCITY_THRESHOLDS,\r\n} from '$lib/constants/scarcity';\r\nimport type { Cents } from '@getmicdrop/svelte-components';\r\nimport { roundCurrency } from '@getmicdrop/svelte-components';\r\nimport {\r\n formatCurrency,\r\n formatSmartSalesDate,\r\n} from '@getmicdrop/svelte-components/utils/formatters';\r\nimport {\r\n formatFullDate,\r\n formatFullDateCompact,\r\n formatEventTime,\r\n formatTimeRange,\r\n formatDoorsTime,\r\n formatSalesDate,\r\n formatBrowseDate,\r\n formatEventDate,\r\n formatCleanTimeRange,\r\n getDateParts,\r\n} from '$lib/utils/datetime.js';\r\n\r\n// --- Re-export production date/time formatters (timezone-aware) ---\r\nexport {\r\n formatFullDate,\r\n formatFullDateCompact,\r\n formatEventTime,\r\n formatTimeRange,\r\n formatDoorsTime,\r\n formatSalesDate,\r\n formatBrowseDate,\r\n formatEventDate,\r\n formatCleanTimeRange,\r\n getDateParts,\r\n};\r\n\r\n// Shared sales-countdown formatter, adopted from svelte-components (SC #471).\r\n// Kept as a re-export so public-calendar-flow consumers import it from this\r\n// module unchanged. English defaults match VC's prior copy; the clock time,\r\n// weekday, and \"tomorrow\" calendar-day identity all resolve in the viewer's\r\n// timezone, or in `labels.timeZone` when a caller pins one (SC #772).\r\n//\r\n// This module used to document the clock as UTC. That was the vc#446 bug, not\r\n// a decision: the clock hardcoded UTC while the weekday beside it rendered\r\n// viewer-local, so the pair could name a wall clock the buyer never had.\r\nexport { formatSmartSalesDate };\r\n\r\n// --- Scarcity Badge Rules ---\r\n// Threshold logic lives in the ONE canonical computeScarcityLevel\r\n// ($lib/constants/scarcity) — including the sliding floor/cap that keeps a\r\n// 1,000-seat show from flagging \"Selling fast\" at 200 left. This module only\r\n// adapts the canon's tier enum ('sold-out'/'plenty') to public-calendar-flow's\r\n// display enum ('sold_out'/'none') and renders the copy.\r\nexport function getScarcityLevel(\r\n remaining: number,\r\n total: number\r\n): ScarcityLevel {\r\n const level = computeScarcityLevel(remaining, total);\r\n if (level === 'sold-out') return 'sold_out';\r\n if (level === 'plenty') return 'none';\r\n return level; // 'urgent' | 'low' — identical between the two enums\r\n}\r\n\r\nexport function getScarcityText(\r\n level: ScarcityLevel,\r\n remaining: number,\r\n context: 'browse' | 'event' | 'ticket',\r\n options?: { isFree?: boolean }\r\n): string | null {\r\n if (level === 'none') return null;\r\n if (level === 'sold_out') return 'Sold out';\r\n // No scarcity badges on free events/tickets — nothing to lose = no urgency\r\n if (options?.isFree) return null;\r\n if (\r\n level === 'urgent' &&\r\n context !== 'browse' &&\r\n remaining <= SCARCITY_THRESHOLDS.MAX_EXACT_COUNT\r\n ) {\r\n return `Only ${remaining} left`;\r\n }\r\n if (level === 'low' || level === 'urgent') return 'Selling fast';\r\n return null;\r\n}\r\n\r\n// --- CTA Rules ---\r\n// Delegates to production computeCtaState() but adapts our EventData shape.\r\n// Components keep calling getCtaConfig(event) — internal logic is production-aligned.\r\nexport function getCtaConfig(event: EventData): CtaConfig {\r\n // Map our EventData tickets to the shape computeCtaState expects.\r\n // `isHidden` flows through so computeCtaState can apply the hidden-only\r\n // \"Sales ended\" → \"Get tickets\" override (MIC-1039).\r\n const apiTickets = event.tickets.map(t => ({\r\n salesBegin: t.salesStartDate,\r\n salesEnd: t.salesEndDate,\r\n remainingCapacity: t.quantityAvailable,\r\n totalCapacity: t.quantityTotal,\r\n soldOut: t.status === 'sold_out',\r\n salesChannel: 1, // All our tickets are online (not \"at the door only\")\r\n isHidden: t.isHidden,\r\n }));\r\n\r\n // Handle statuses that computeCtaState doesn't compute from tickets\r\n if (event.status === 'cancelled') {\r\n return {\r\n text: 'Cancelled',\r\n disabled: true,\r\n reason: 'This event has been cancelled',\r\n };\r\n }\r\n if (event.status === 'past') {\r\n return {\r\n text: 'Event ended',\r\n disabled: true,\r\n reason: 'This event has ended',\r\n };\r\n }\r\n\r\n const result = computeCtaState(\r\n { startDateTime: event.startDateTime, endDateTime: event.endDateTime },\r\n apiTickets,\r\n {\r\n cancelled: false,\r\n isRegistration: event.isRegistrationEvent,\r\n waitlistEnabled: false,\r\n }\r\n );\r\n\r\n return {\r\n text: result.text,\r\n disabled: result.disabled,\r\n reason: result.disabled ? toFriendlyReason(result.reason) : undefined,\r\n };\r\n}\r\n\r\n/**\r\n * computeCtaState() returns machine-enum reasons ('event_past', 'sold_out',\r\n * 'coming_soon', etc) intended for branching, not display. The BookingWidget\r\n * and MobileCta render `reason` directly as supplementary copy below the\r\n * button text — which leaks raw enum strings to users.\r\n *\r\n * Map each enum to a friendly sentence, OR return undefined when the button\r\n * `text` already says everything (\"Sales ended\" / \"Sold out\" — no need for\r\n * a second line repeating it).\r\n */\r\nfunction toFriendlyReason(reason: string | undefined): string | undefined {\r\n if (!reason) return undefined;\r\n switch (reason) {\r\n case 'cancelled':\r\n return 'This event has been cancelled.';\r\n case 'event_past':\r\n return 'This event has already happened.';\r\n case 'no_tickets':\r\n return 'There are no tickets configured for this event.';\r\n case 'coming_soon':\r\n return undefined; // text already shows \"On sale <date>\"\r\n case 'sold_out':\r\n return undefined; // text already shows \"Sold out\"\r\n case 'sold_out_waitlist':\r\n return 'All tickets are claimed. Join the waitlist to be notified.';\r\n case 'sales_ended':\r\n return undefined; // text already shows \"Sales ended\"\r\n default:\r\n return undefined; // unknown enum — never leak it\r\n }\r\n}\r\n\r\n// --- Price Display Rules (from DECISIONS.md #1) ---\r\nexport function getPriceDisplay(event: EventData): string | null {\r\n const visibleTickets = event.tickets.filter(\r\n t => t.status === 'on_sale' && !t.isHidden\r\n );\r\n if (visibleTickets.length === 0) return null;\r\n\r\n const hasDonation = visibleTickets.some(\r\n t => t.isDonation || t.ticketType === 2\r\n );\r\n const paidTickets = visibleTickets.filter(\r\n t => !t.isDonation && t.ticketType !== 2\r\n );\r\n const hasFree = paidTickets.some(t => t.price === 0);\r\n const pricedTickets = paidTickets.filter(t => t.price > 0);\r\n\r\n // Only donation tickets → \"Donation\"\r\n if (pricedTickets.length === 0 && !hasFree && hasDonation) return 'Donation';\r\n\r\n // Only free tickets (no paid, no donation) → null (BookingWidget shows \"Free\" via isFreeEvent)\r\n if (pricedTickets.length === 0 && hasFree) return null;\r\n\r\n const minPrice = Math.min(...pricedTickets.map(t => t.price));\r\n\r\n // Free + paid → \"Free\" (free dominates the display). Non-donation free tickets\r\n // outrank the paid options in the headline, matching the shared \"Free\" label\r\n // every other price surface uses. Returning null here left the widget blank.\r\n if (hasFree) return 'Free';\r\n\r\n // Money display goes through the SC formatCurrency canonical (drift-c13 money\r\n // convergence), never a hand-rolled dollar template literal. Fraction digits\r\n // 0-2 reproduce the bare-dollar headline this surface has always shown (\"$25\",\r\n // \"$25.99\"), while gaining canonical thousands separators for >= $1,000 prices.\r\n const price = formatCurrency(minPrice, {\r\n minimumFractionDigits: 0,\r\n maximumFractionDigits: 2,\r\n });\r\n\r\n // Donation + paid → \"From $X\" (donation is an alternative option)\r\n if (hasDonation) return `From ${price}`;\r\n\r\n // Single paid ticket type → \"$X\"\r\n if (pricedTickets.length === 1) return price;\r\n\r\n // Multiple paid ticket types → \"From $X\"\r\n return `From ${price}`;\r\n}\r\n\r\n// --- Fee Calculation ---\r\nexport function calculateFee(\r\n price: number,\r\n feePercentage: number,\r\n feeCents: Cents\r\n): number {\r\n return roundCurrency(price * (feePercentage / 100) + feeCents / 100);\r\n}\r\n\r\nexport function calculateTax(amount: number, taxPercentage: number): number {\r\n return roundCurrency(amount * (taxPercentage / 100));\r\n}\r\n\r\n// --- Date Formatting ---\r\n// PREFERRED: Use the timezone-aware production formatters re-exported above:\r\n// formatBrowseDate(iso, tz) → \"Fri, Feb 20\"\r\n// formatFullDateCompact(iso, tz) → \"Friday, February 20\"\r\n// formatEventTime(iso, tz) → \"8:00 PM\"\r\n// formatTimeRange(start, end, tz) → \"8:00 PM - 10:00 PM\"\r\n// formatDoorsTime(doors, tz) → \"7:00 PM\"\r\n\r\n// --- Animation Durations ---\r\nexport const DURATION = {\r\n instant: 100,\r\n micro: 150,\r\n fast: 200,\r\n normal: 300,\r\n slow: 400,\r\n elaborate: 600,\r\n} as const;\r\n\r\n// --- Promo Code State Factory ---\r\nexport function createDefaultPromoState(): PromoCodeState {\r\n return {\r\n code: '',\r\n isApplied: false,\r\n isValidating: false,\r\n error: '',\r\n hint: '',\r\n discountAmount: 0,\r\n discountType: '',\r\n discountTicketIds: [],\r\n revealHiddenTickets: false,\r\n revealTicketIds: [],\r\n };\r\n}\r\n\r\n// --- Ticket helpers ---\r\nexport function getAvailableTickets(\r\n tickets: TicketTypeData[]\r\n): TicketTypeData[] {\r\n return tickets.filter(t => !t.isHidden && t.status === 'on_sale');\r\n}\r\n","<!-- @style-escape: widget-intentional. -->\r\n<script lang=\"ts\">\r\n import { Text, formatCurrency, toUSD } from '@getmicdrop/svelte-components';\r\n import type { OrderTotals } from '$lib/public-calendar-flow/types';\r\n import { formatPriceOrFree } from '$lib/core';\r\n import { DURATION } from '$lib/public-calendar-flow/defaults';\r\n\r\n interface Props {\r\n orderTotals: OrderTotals;\r\n labels?: Record<string, string>;\r\n /**\r\n * Which section to render.\r\n * - `full` (default): ticket lines + totals stacked together.\r\n * - `lines` : ticket-line items only. Use when the parent scrolls\r\n * this section in a flex column.\r\n * - `totals` : subtotal/fees/taxes/promo/total only. Use in a fixed\r\n * footer alongside the action button.\r\n *\r\n * Splitting via `lines` / `totals` lets the sticky sidebars scroll\r\n * just the variable-length ticket list while keeping the summary\r\n * block and CTA always visible.\r\n */\r\n mode?: 'full' | 'lines' | 'totals';\r\n }\r\n\r\n let { orderTotals, labels = {}, mode = 'full' }: Props = $props();\r\n\r\n // A missing wire price renders an em-dash, never a coerced $0 (mf#2383 /\r\n // vc#619). A genuine free/zero value is a real number and formats normally.\r\n const PRICE_DASH = '—';\r\n function moneyOrDash(value: number | null): string {\r\n return value == null ? PRICE_DASH : formatCurrency(toUSD(value));\r\n }\r\n</script>\r\n\r\n<div class=\"space-y-2\" style=\"transition-duration: {DURATION.normal}ms;\">\r\n {#if mode !== 'totals'}\r\n <!-- Line items -->\r\n {#each orderTotals.lines as line (line.ticketId)}\r\n <div class=\"flex justify-between\">\r\n <Text size=\"sm\">{line.quantity}x {line.ticketName}</Text>\r\n <Text size=\"sm\"\r\n >{#if line.subtotal == null}{PRICE_DASH}{:else if line.isDonation}{formatCurrency(\r\n toUSD(line.subtotal)\r\n )}{:else}{formatPriceOrFree(line.subtotal, labels)}{/if}</Text\r\n >\r\n </div>\r\n {/each}\r\n {/if}\r\n\r\n {#if mode !== 'lines'}\r\n <!-- Subtotal. In `totals` mode the parent supplies the separator above\r\n\t\t this block (BookingWidget wraps the totals block in border-t); a\r\n\t\t second internal border would render as a double line. Only show\r\n\t\t the internal border-t in `full` mode where lines + totals stack\r\n\t\t in one container with no external separator. -->\r\n {#if mode === 'full' && orderTotals.lines.length > 1}\r\n <div class=\"flex justify-between pt-1 border-t border-default\">\r\n <Text size=\"sm\" color=\"muted\">{labels.subtotal || 'Subtotal'}</Text>\r\n <Text size=\"sm\" color=\"muted\">{moneyOrDash(orderTotals.subtotal)}</Text>\r\n </div>\r\n {:else if orderTotals.lines.length > 1}\r\n <div class=\"flex justify-between\">\r\n <Text size=\"sm\" color=\"muted\">{labels.subtotal || 'Subtotal'}</Text>\r\n <Text size=\"sm\" color=\"muted\">{moneyOrDash(orderTotals.subtotal)}</Text>\r\n </div>\r\n {/if}\r\n\r\n <!-- Fees -->\r\n {#if orderTotals.fees > 0}\r\n <div class=\"flex justify-between\">\r\n <Text size=\"sm\" color=\"muted\"\r\n >{labels.serviceFees || 'Service fees'}</Text\r\n >\r\n <Text size=\"sm\" color=\"muted\"\r\n >{formatCurrency(toUSD(orderTotals.fees))}</Text\r\n >\r\n </div>\r\n {/if}\r\n\r\n <!-- Taxes -->\r\n {#if orderTotals.taxes > 0}\r\n <div class=\"flex justify-between\">\r\n <Text size=\"sm\" color=\"muted\">{labels.taxes || 'Taxes'}</Text>\r\n <Text size=\"sm\" color=\"muted\"\r\n >{formatCurrency(toUSD(orderTotals.taxes))}</Text\r\n >\r\n </div>\r\n {/if}\r\n\r\n <!-- Promo discount -->\r\n {#if orderTotals.promoDiscount > 0}\r\n <div class=\"flex justify-between\">\r\n <Text size=\"sm\" color=\"success\"\r\n >{labels.promoDiscount || 'Promo discount'}</Text\r\n >\r\n <Text size=\"sm\" color=\"success\"\r\n >-{formatCurrency(toUSD(orderTotals.promoDiscount))}</Text\r\n >\r\n </div>\r\n {/if}\r\n\r\n <!-- Gift card — deduction from the amount due; `total` already reflects it -->\r\n {#if orderTotals.giftCardAmount > 0}\r\n <div class=\"flex justify-between\">\r\n <Text size=\"sm\" color=\"success\">{labels.giftCard || 'Gift card'}</Text>\r\n <Text size=\"sm\" color=\"success\"\r\n >-{formatCurrency(toUSD(orderTotals.giftCardAmount))}</Text\r\n >\r\n </div>\r\n {/if}\r\n\r\n <!-- Total -->\r\n <div class=\"flex justify-between pt-2 border-t border-default\">\r\n <Text size=\"base\" weight=\"semibold\">{labels.total || 'Total'}</Text>\r\n <Text size=\"base\" weight=\"semibold\">{moneyOrDash(orderTotals.total)}</Text\r\n >\r\n </div>\r\n {/if}\r\n</div>\r\n","/**\r\n * Default English labels for public-calendar-flow components.\r\n * Consumers override via the `labels` prop on any *Main component.\r\n *\r\n * Label keys use flat camelCase. For composed strings (e.g. aria-labels),\r\n * components build them from atomic label parts.\r\n */\r\nexport const defaultLabels = {\r\n // ── Ticket quantity controls ──────────────────────────────────────\r\n // Stepper aria-labels compose these into \"Increase <name> quantity\" etc.\r\n // `quantityNoun` is deliberately its OWN key (not the main i18n's `quantity`,\r\n // whose value is the sr-only display PREFIX 'Quantity:') so the main-i18n\r\n // merge can't leak a capital-Q + trailing colon into the button labels.\r\n // Overridable, same as increase/decrease, which main i18n also doesn't define.\r\n decrease: 'Decrease',\r\n increase: 'Increase',\r\n quantityNoun: 'quantity',\r\n\r\n // ── Ticket states ─────────────────────────────────────────────────\r\n soldOut: 'Sold out',\r\n free: 'Free',\r\n unavailable: 'Unavailable',\r\n eventSoldOut: 'This event is sold out',\r\n\r\n // ── Event unavailable (canceled / postponed / sales closed) ───────\r\n // Headings sit above a disabled CTA; the *Banner pair is the live-flip\r\n // notice Event.svelte renders. `unavailable` above is the BUTTON word —\r\n // these are the sentence-level strings, so they stay their own keys.\r\n eventPostponed: 'Event postponed',\r\n eventUnavailable: 'Event unavailable',\r\n salesClosed: 'Sales closed',\r\n eventPostponedBanner:\r\n 'This event has been postponed. Ticket sales are paused',\r\n eventCanceledBanner: 'This event is no longer available for purchase',\r\n\r\n // ── Price display ─────────────────────────────────────────────────\r\n includesFees: 'Includes',\r\n fees: 'fees',\r\n fee: 'fee',\r\n\r\n // ── Checkout CTAs ─────────────────────────────────────────────────\r\n checkout: 'Checkout',\r\n getTickets: 'Get tickets',\r\n selectTickets: 'Select tickets',\r\n selectTicketsBelow: 'Select tickets below',\r\n selectTicketsToContinue: 'Select tickets to continue',\r\n reserveASpot: 'Reserve a spot',\r\n\r\n // ── Password modal / gate ─────────────────────────────────────────\r\n enterPassword: 'Enter password',\r\n enterEventPassword: 'Enter event password',\r\n passwordRequired: 'Password required',\r\n passwordRequiredShort: 'Password required',\r\n eventRequiresPassword: 'This event requires a password to purchase tickets',\r\n eventRequiresPasswordAccess:\r\n 'This event requires a password to access tickets',\r\n enterEventPasswordToView: 'Enter the event password to view tickets',\r\n enterEventPasswordToViewAvailable:\r\n 'Enter the event password to view available tickets',\r\n eventPassword: 'Event password',\r\n password: 'Password',\r\n pleaseEnterPassword: 'Please enter the event password',\r\n pleaseEnterAPassword: 'Please enter a password',\r\n eventRequiresPasswordShort: 'This event requires a password',\r\n unlockTickets: 'Unlock tickets',\r\n cancel: 'Cancel',\r\n continue: 'Continue',\r\n submit: 'Submit',\r\n\r\n // ── Order summary ─────────────────────────────────────────────────\r\n subtotal: 'Subtotal',\r\n serviceFees: 'Service fees',\r\n taxes: 'Taxes',\r\n tax: 'Tax',\r\n promoDiscount: 'Promo discount',\r\n giftCard: 'Gift card',\r\n total: 'Total',\r\n // English fallback for the flow catalogue; the main i18n catalogue carries the\r\n // translated copy (Spanish in locales/es.js). Shown under a blocked buy button\r\n // when the price can't be loaded (mf#2383 / vc#619).\r\n priceUnavailable:\r\n \"We couldn't load the price for this order — refresh the page or contact the venue\",\r\n orderSummary: 'Order summary',\r\n yourOrder: 'Your order',\r\n\r\n // ── Ticket counts (used in CTA buttons) ───────────────────────────\r\n ticket: 'ticket',\r\n tickets: 'tickets',\r\n\r\n // ── Checkout form (public-calendar-flow) ───────────────────────────────\r\n yourDetails: 'Your details',\r\n attendeeDetails: 'Attendee details',\r\n attendee: 'Attendee',\r\n sameAsPurchaser: 'Same as purchaser',\r\n payment: 'Payment',\r\n noPaymentRequired: 'No payment required',\r\n freeEventMessage:\r\n 'This is a free event. Complete the form above to reserve your spot',\r\n firstName: 'First name',\r\n lastName: 'Last name',\r\n emailAddress: 'Email address',\r\n email: 'Email',\r\n emailPlaceholder: 'you@example.com',\r\n attendeeEmailPlaceholder: 'attendee@example.com',\r\n cardNumber: 'Card number',\r\n cardPlaceholder: '4242 4242 4242 4242',\r\n expiryDate: 'Expiry date',\r\n expiryPlaceholder: 'MM / YY',\r\n cvc: 'CVC',\r\n cvcPlaceholder: '123',\r\n keepMeUpdated: 'Keep me updated about this event and similar events',\r\n // Split pair, matching `$lib/i18n/defaultLabels.js`: the checkbox sentence is\r\n // `agreeToTerms` + a linked `termsAndConditionsLink`. Both stay overridable.\r\n agreeToTerms: 'I agree to the',\r\n termsAndConditionsLink: 'terms and conditions',\r\n goBack: 'Go back',\r\n goBackToEventDetails: 'Go back to event details',\r\n loadingPaymentForm: 'Loading secure payment form...',\r\n\r\n // ── Ended event ───────────────────────────────────────────────────\r\n // Same strings as `$lib/i18n/defaultLabels.js`, which is where CartView\r\n // reads them — the two surfaces say the same thing about an ended event.\r\n thisEventHasEnded: 'This event has ended',\r\n ticketsNoLongerAvailable: 'Tickets are no longer available for this event',\r\n\r\n // ── Checkout form validation ──────────────────────────────────────\r\n firstNameRequired: 'First name is required',\r\n lastNameRequired: 'Last name is required',\r\n emailRequired: 'Email is required',\r\n emailInvalid: 'Enter a valid email address',\r\n emailInvalidShort: 'Enter a valid email',\r\n cardNumberRequired: 'Card number is required',\r\n expiryRequired: 'Expiry date is required',\r\n cvcRequired: 'CVC is required',\r\n mustAgreeTerms: 'You must agree to the terms',\r\n\r\n // ── Place order CTAs ──────────────────────────────────────────────\r\n placeOrder: 'Place order',\r\n completeOrder: 'Complete order',\r\n placingOrder: 'Placing order...',\r\n\r\n // ── Promo code ────────────────────────────────────────────────────\r\n havePromoCode: 'Have a promo code?',\r\n promoCode: 'Promo code',\r\n enterCode: 'Enter code',\r\n apply: 'Apply',\r\n remove: 'Remove',\r\n removePromoCode: 'Remove promo code',\r\n applyPromoCode: 'Apply promo code',\r\n checkingPromoCode: 'Checking promo code',\r\n checking: 'Checking...',\r\n promoApplied: 'Promo applied',\r\n\r\n // ── Navigation tabs (app-segments) ────────────────────────────────\r\n about: 'About',\r\n ticketsTab: 'Tickets',\r\n eventSections: 'Event sections',\r\n\r\n // ── Event details ─────────────────────────────────────────────────\r\n eventDetails: 'Event details',\r\n performers: 'Performers',\r\n faq: 'FAQ',\r\n frequentlyAskedQuestions: 'Frequently asked questions',\r\n doors: 'Doors',\r\n doorsOpenAt: 'Doors open at',\r\n\r\n // ── Series occurrences ────────────────────────────────────────────\r\n upcomingDates: 'Upcoming dates',\r\n\r\n // ── Close / dismiss ───────────────────────────────────────────────\r\n closeTicketSelection: 'Close ticket selection',\r\n closeTicketSelector: 'Close ticket selector',\r\n\r\n // ── Accessibility ─────────────────────────────────────────────────\r\n ticketSelection: 'ticket selection',\r\n ticketsSelected: 'tickets selected',\r\n view: 'View',\r\n\r\n // ── Success page (public-calendar-flow) ────────────────────────────────\r\n youreIn: \"You're in\",\r\n youreRegistered: \"You're registered\",\r\n confirmed: 'confirmed',\r\n viewTickets: 'View tickets',\r\n order: 'Order',\r\n confirmationSentTo: 'Confirmation sent to',\r\n addToCalendar: 'Add to calendar',\r\n googleCalendar: 'Google Calendar',\r\n appleCalendar: 'Apple Calendar (.ics)',\r\n share: 'Share',\r\n map: 'Map',\r\n backToEvent: 'Back to event',\r\n needHelp: 'Need help?',\r\n linkCopied: 'Link copied to clipboard',\r\n copyLink: 'Copy this link:',\r\n addToAppleWallet: 'Add to Apple Wallet',\r\n saveToGoogleWallet: 'Save to Google Wallet',\r\n walletComingSoon:\r\n 'Wallet passes are coming soon. Your ticket is confirmed — check your email',\r\n\r\n // ── Session timer / expiration modals ─────────────────────────────\r\n // CheckoutTimer's two states. English defaults live here (this is the\r\n // catalogue serving that component); the Spanish values live in the main\r\n // catalogue's \"Checkout timer\" section and win at merge, since\r\n // mergeLabels(flowDefaults, incomingLabels) lets the caller override. vc#706.\r\n reservationHeld: 'Reservation held',\r\n completeSoon: 'Complete soon',\r\n sessionExpiringSoon: 'Session expiring soon',\r\n sessionExpiringSoonMessage:\r\n 'Your checkout session will expire in {time}. Your selected tickets will be released back to inventory',\r\n extensionsRemaining: '{count} extension{plural} remaining',\r\n continueCheckout: 'Continue checkout',\r\n okIllHurry: \"OK, I'll hurry\",\r\n maxExtensionsReached: 'Maximum extensions reached',\r\n wantToKeepTickets: 'Want to keep your tickets?',\r\n sessionExpiredMessage:\r\n 'Your checkout session has expired and your selected tickets have been released',\r\n sessionExpired: 'Session expired',\r\n reservationTimedOut:\r\n 'Your reservation has timed out. Please select your tickets again to continue',\r\n keepMyTickets: 'Keep my tickets',\r\n selectTicketsAgain: 'Select tickets again',\r\n extendingSession: 'Extending...',\r\n\r\n // ── MobileCta ─────────────────────────────────────────────────────\r\n selectTicketsLabel: 'Select tickets',\r\n collapseOrderSummary: 'Collapse order summary',\r\n expandOrderSummary: 'Expand order summary',\r\n\r\n // ── Waitlist (sold-out gating + tokenized unlock) ─────────────────\r\n joinWaitlist: 'Join waitlist',\r\n getNotifiedWhenAvailable: 'Get notified when tickets are available',\r\n // Tokenized-link unlock outcomes (decisions #3/#22/#36). Mapped from the\r\n // server's failure enum; shown as a small dismissible notice near the CTA.\r\n waitlistLinkInvalid:\r\n \"This link isn't valid. You're still on the waitlist — we'll email you if tickets free up\",\r\n waitlistLinkExpired: \"This link has expired. You're still on the waitlist\",\r\n waitlistLinkUsed:\r\n \"This link has already been used. You're still on the waitlist\",\r\n waitlistLinkEmailMismatch:\r\n \"This link was sent to a different email address. You're still on the waitlist\",\r\n waitlistLinkInventoryExhausted:\r\n \"Those tickets were just claimed. You're still on the waitlist — we'll email you if more free up\",\r\n dismiss: 'Dismiss',\r\n};\r\n"],"names":["size","$","$$props","color","className","ctx","useIconWeight","resolved","svg","root_2","path","root","$$render","consequent","alternate","styles","computeCtaState","event","tickets","options","cancelled","isRegistration","waitlistEnabled","now","browserNow","eventEnd","toInstantOrNull","compareInstants","hiddenAvailable","isHiddenTicketPurchasable","publicTickets","t","hasPurchasable","allSoldOut","allComingSoon","earliestSalesStart","ticket","salesBegin","salesEnd","remaining","isSoldOut","isScheduled","hasSalesEnded","diffMs","diffHours","diffDays","timeLabel","d","formatLocal","dateText","getScarcityLevel","total","level","computeScarcityLevel","getScarcityText","context","SCARCITY_THRESHOLDS","getCtaConfig","apiTickets","result","toFriendlyReason","reason","getPriceDisplay","visibleTickets","hasDonation","paidTickets","hasFree","pricedTickets","minPrice","price","formatCurrency","calculateTax","amount","taxPercentage","roundCurrency","DURATION","createDefaultPromoState","labels","mode","PRICE_DASH","moneyOrDash","value","toUSD","div","root_3","node_1","line","div_1","Text","node_2","text","node_3","$0","text_2","text_3","formatPriceOrFree","consequent_1","consequent_2","div_2","root_1","node_7","node_8","text_5","div_3","node_9","node_10","text_7","consequent_3","consequent_4","div_4","node_12","node_13","consequent_5","div_5","node_15","node_16","consequent_6","div_6","node_18","node_19","consequent_7","div_7","node_21","node_22","consequent_8","div_8","node_20","node_23","node_24","text_17","consequent_9","defaultLabels"],"mappings":"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","x_google_ignoreList":[0]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"shareCopyFeedback.svelte-CJGSyRw6.js","sources":["../node_modules/@getmicdrop/svelte-components/dist/primitives/Icons/phosphor/ExportIcon.svelte","../node_modules/@getmicdrop/svelte-components/dist/primitives/Icons/phosphor/LocationIcon.svelte","../node_modules/@getmicdrop/svelte-components/dist/utils/copyToClipboard.js","../src/lib/public-calendar-flow/shareEventLink.ts","../src/lib/public-calendar-flow/shareCopyFeedback.svelte.ts"],"sourcesContent":["<script lang=\"ts\">\r\n /**\r\n * Export — Phosphor icon (canonical Micdrop icon family).\r\n * Outline by default; pass `weight=\"fill\"` for solid, or let a stateful parent\r\n * (NavItem / Tabs / BottomNav / status badge) drive it via icon-weight context.\r\n */\r\n import { useIconWeight, type IconWeight } from './iconWeight.js';\r\n\r\n interface Props {\r\n /** Pixel size (width + height). */\r\n size?: string;\r\n /** Icon color; defaults to `currentColor` (inherits text color). */\r\n color?: string;\r\n /** Extra classes. */\r\n class?: string;\r\n /** `regular` (outline) or `fill` (solid). Overrides ambient state weight. */\r\n weight?: IconWeight;\r\n }\r\n\r\n let { size = '24', color = 'currentColor', class: className = '', weight }: Props = $props();\r\n\r\n const ctx = useIconWeight();\r\n let resolved: IconWeight = $derived(weight ?? ctx?.weight ?? 'regular');\r\n</script>\r\n\r\n<svg\r\n class={className}\r\n aria-hidden=\"true\"\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 256 256\"\r\n fill=\"currentColor\"\r\n style:color={color}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n>\r\n {#if resolved === 'fill'}<path d=\"M216,112v96a16,16,0,0,1-16,16H56a16,16,0,0,1-16-16V112A16,16,0,0,1,56,96h64v48a8,8,0,0,0,16,0V96h64A16,16,0,0,1,216,112ZM136,43.31l26.34,26.35a8,8,0,0,0,11.32-11.32l-40-40a8,8,0,0,0-11.32,0l-40,40A8,8,0,0,0,93.66,69.66L120,43.31V96h16Z\"/>{:else}<path d=\"M176,104h24a8,8,0,0,1,8,8v96a8,8,0,0,1-8,8H56a8,8,0,0,1-8-8V112a8,8,0,0,1,8-8H80\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"/><polyline points=\"88 64 128 24 168 64\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"/><line x1=\"128\" y1=\"24\" x2=\"128\" y2=\"136\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"/>{/if}\r\n</svg>\r\n","<script lang=\"ts\">\r\n /**\r\n * Location — Phosphor icon (canonical Micdrop icon family).\r\n * Outline by default; pass `weight=\"fill\"` for solid, or let a stateful parent\r\n * (NavItem / Tabs / BottomNav / status badge) drive it via icon-weight context.\r\n */\r\n import { useIconWeight, type IconWeight } from './iconWeight.js';\r\n\r\n interface Props {\r\n /** Pixel size (width + height). */\r\n size?: string;\r\n /** Icon color; defaults to `currentColor` (inherits text color). */\r\n color?: string;\r\n /** Extra classes. */\r\n class?: string;\r\n /** `regular` (outline) or `fill` (solid). Overrides ambient state weight. */\r\n weight?: IconWeight;\r\n }\r\n\r\n let { size = '24', color = 'currentColor', class: className = '', weight }: Props = $props();\r\n\r\n const ctx = useIconWeight();\r\n let resolved: IconWeight = $derived(weight ?? ctx?.weight ?? 'regular');\r\n</script>\r\n\r\n<svg\r\n class={className}\r\n aria-hidden=\"true\"\r\n width={size}\r\n height={size}\r\n viewBox=\"0 0 256 256\"\r\n fill=\"currentColor\"\r\n style:color={color}\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n>\r\n {#if resolved === 'fill'}<path d=\"M128,16a88.1,88.1,0,0,0-88,88c0,75.3,80,132.17,83.41,134.55a8,8,0,0,0,9.18,0C136,236.17,216,179.3,216,104A88.1,88.1,0,0,0,128,16Zm0,56a32,32,0,1,1-32,32A32,32,0,0,1,128,72Z\"/>{:else}<circle cx=\"128\" cy=\"104\" r=\"32\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"/><path d=\"M208,104c0,72-80,128-80,128S48,176,48,104a80,80,0,0,1,160,0Z\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"16\"/>{/if}\r\n</svg>\r\n","/**\n * Copy-to-clipboard utility — resolves `true` ONLY on a real successful write.\n *\n * The whole point of this canonical: callers fire their own \"Copied!\" toast\n * ONLY when this resolves `true`. It NEVER resolves `true` unless the text\n * actually landed on the clipboard, so a permission-denied / insecure-context /\n * no-API failure can no longer masquerade as success — killing the \"lying\n * toast\" bug where a button claimed it copied when nothing was copied.\n *\n * Strategy (best → fallback, never throws):\n * 1. Async Clipboard API (`navigator.clipboard.writeText`) when available\n * (secure context, granted permission) — AWAITED; resolves `true` only\n * when that promise resolves. On rejection it falls through (2) rather\n * than reporting success.\n * 2. Legacy `document.execCommand('copy')` for older / insecure (non-HTTPS)\n * contexts — returns its REAL success boolean.\n * 3. `false` on any failure (rejected write, no clipboard API, no DOM,\n * thrown exception).\n *\n * @param text - The text to place on the clipboard.\n * @returns Promise resolving `true` iff the write actually succeeded, else `false`.\n *\n * @example\n * if (await copyToClipboard(shareUrl)) toast.success('Link copied');\n * else toast.error(\"Couldn't copy — try selecting and copying manually\");\n */\nexport async function copyToClipboard(text) {\n // 1. Async Clipboard API — preferred; only present in secure contexts.\n if (typeof navigator !== 'undefined' &&\n navigator.clipboard &&\n typeof navigator.clipboard.writeText === 'function') {\n try {\n await navigator.clipboard.writeText(text);\n return true;\n }\n catch {\n // Permission denied / insecure context / transient failure — do NOT\n // report success. Fall through to the legacy path and let it decide.\n }\n }\n // 2. Legacy execCommand fallback — older browsers / insecure (non-HTTPS).\n return copyViaExecCommand(text);\n}\n/**\n * Legacy `document.execCommand('copy')` path. Returns its real success boolean\n * and never throws. Used when the async Clipboard API is unavailable or its\n * write rejected.\n *\n * @param text - The text to copy.\n * @returns `true` iff `execCommand('copy')` reported success.\n */\nfunction copyViaExecCommand(text) {\n if (typeof document === 'undefined' ||\n typeof document.execCommand !== 'function') {\n return false;\n }\n // Preserve what the user had selected/focused — selecting our textarea would\n // otherwise blow away their current selection (e.g. text they were copying by hand).\n const prevActive = document.activeElement;\n const selection = document.getSelection();\n const savedRanges = selection\n ? Array.from({ length: selection.rangeCount }, (_, i) => selection.getRangeAt(i).cloneRange())\n : [];\n const textarea = document.createElement('textarea');\n try {\n textarea.value = text;\n // Read-only + off-screen so it never flashes, scrolls, or steals focus.\n textarea.setAttribute('readonly', '');\n textarea.style.position = 'fixed';\n textarea.style.top = '-9999px';\n textarea.style.left = '-9999px';\n textarea.style.opacity = '0';\n document.body.appendChild(textarea);\n textarea.select();\n textarea.setSelectionRange(0, text.length);\n return document.execCommand('copy');\n }\n catch {\n return false;\n }\n finally {\n textarea.remove();\n // Restore the user's prior selection + focus, on success AND failure.\n if (selection) {\n selection.removeAllRanges();\n for (const range of savedRanges)\n selection.addRange(range);\n }\n prevActive?.focus?.();\n }\n}\n","import { copyToClipboard } from '@getmicdrop/svelte-components';\r\n\r\n/**\r\n * Outcome of a share attempt, mapped by the caller to its own inline feedback.\r\n *\r\n * - `shared` — the native share sheet handled it (or the user cancelled). No\r\n * inline feedback: the OS UI already spoke, and a cancel must stay quiet.\r\n * - `copied` — the link landed on the clipboard via the SC canonical.\r\n * - `failed` — the clipboard write was blocked; surface the URL for manual copy.\r\n */\r\nexport type ShareLinkResult = 'shared' | 'copied' | 'failed';\r\n\r\n/**\r\n * Share-link decision — the ONE copy of the native-share/clipboard logic that\r\n * used to be duplicated across the event header and the confirmation sidebar.\r\n *\r\n * 1. Native share sheet when the browser exposes `navigator.share`. A user\r\n * cancel (AbortError) ends quietly — returns `shared`, no fallback.\r\n * 2. Otherwise (no share API, or a non-cancel share failure) copy the URL via\r\n * the SC canonical `copyToClipboard`, which resolves `true` ONLY on a real\r\n * write and falls back to `execCommand` on the insecure (http embed) hosts\r\n * where the async Clipboard API is unavailable — the exact context the old\r\n * raw `navigator.clipboard.writeText` threw in.\r\n *\r\n * VC has no toasts (standalone embeddable widget, no Toaster mounted), so this\r\n * returns a result the caller renders inline rather than firing feedback here.\r\n *\r\n * @param url - The link to share.\r\n */\r\nexport async function shareEventLink(url: string): Promise<ShareLinkResult> {\r\n if (\r\n typeof navigator !== 'undefined' &&\r\n typeof navigator.share === 'function'\r\n ) {\r\n try {\r\n await navigator.share({ url });\r\n return 'shared';\r\n } catch (err: unknown) {\r\n // User dismissed the share sheet — leave it there, no fallback. Browsers\r\n // reject with a DOMException named 'AbortError', and DOMException is NOT\r\n // `instanceof Error`, so match on the name alone (not the prototype).\r\n if ((err as { name?: string } | null)?.name === 'AbortError') {\r\n return 'shared';\r\n }\r\n // Any other failure falls through to the clipboard fallback below.\r\n }\r\n }\r\n\r\n return (await copyToClipboard(url)) ? 'copied' : 'failed';\r\n}\r\n","import { shareEventLink } from '$lib/public-calendar-flow/shareEventLink';\r\n\r\n/**\r\n * Share-link copy feedback — the ONE copy of the inline state machine that used\r\n * to be hand-rolled identically in the event header and the confirmation\r\n * sidebar. It owns the reactive `copyState`/`copyFailedUrl` and the reset timer,\r\n * delegating the native-share/clipboard decision to `shareEventLink`.\r\n *\r\n * VC has no toasts, so feedback is inline: `copied` briefly swaps the button\r\n * label, `failed` reveals the URL for manual copy. Native share (or a user\r\n * cancel) leaves the state untouched — the OS UI already spoke.\r\n *\r\n * Call `dispose()` from the consumer's `onDestroy` to clear the pending timer.\r\n */\r\nexport function createShareCopyFeedback() {\r\n let copyState = $state<'idle' | 'copied' | 'failed'>('idle');\r\n let copyFailedUrl = $state('');\r\n let resetTimer: ReturnType<typeof setTimeout> | undefined;\r\n\r\n async function share(url: string) {\r\n const result = await shareEventLink(url);\r\n if (result === 'copied') {\r\n copyFailedUrl = '';\r\n copyState = 'copied';\r\n clearTimeout(resetTimer);\r\n resetTimer = setTimeout(() => (copyState = 'idle'), 2500);\r\n } else if (result === 'failed') {\r\n // Copy blocked — reveal the URL inline so the buyer can select it manually.\r\n clearTimeout(resetTimer);\r\n copyState = 'failed';\r\n copyFailedUrl = url;\r\n }\r\n // 'shared' → native sheet handled it (or user cancelled); no inline feedback.\r\n }\r\n\r\n function dispose() {\r\n clearTimeout(resetTimer);\r\n }\r\n\r\n return {\r\n get copyState() {\r\n return copyState;\r\n },\r\n get copyFailedUrl() {\r\n return copyFailedUrl;\r\n },\r\n share,\r\n dispose,\r\n };\r\n}\r\n"],"names":["size","$","$$props","color","className","ctx","useIconWeight","resolved","svg","root_2","path","root","$$render","consequent","alternate","styles","copyToClipboard","text","copyViaExecCommand","prevActive","selection","savedRanges","_","i","textarea","range","shareEventLink","url","err","createShareCopyFeedback","copyState","copyFailedUrl","resetTimer","share","result","dispose"],"mappings":"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","x_google_ignoreList":[0,1,2]}
|