/* @ds-bundle: {"format":4,"namespace":"EazyDesignSystem_019e08","components":[{"name":"EzButton","sourcePath":"components/EzButton/EzButton.jsx"}],"sourceHashes":{"components/EzButton/EzButton.jsx":"d9ee37b8d784","eazy-landing/doc-page.js":"62024d965071","eazy-landing/script.js":"79d70d9bff98","exports/eazy-math-diagnostic/app.js":"c2dbf692f7de","flashcards/Deck.jsx":"5797696c99cd","flashcards/Flashcard.jsx":"d89d2a57d2e5","flashcards/deck-data.js":"605ee8fc5290","flashcards/ios-frame.jsx":"d67eb3ffe562","flashcards/tweaks-panel.jsx":"a1107c630a56","quiz-game-export/QuizGameExport.jsx":"96b531136862","quiz-game-export/words.js":"35263fe45fb0","quiz-game-server/QuizGameServer.jsx":"590d586f60af","quiz-game/Game.standalone.jsx":"ccb27042040f","quiz-game/QuizGame.jsx":"57c1f54eb3c3","quiz-game/design-canvas.jsx":"c9095ef15594","quiz-game/dist/game.js":"0af452a8a961","quiz-game/dist/words.js":"35263fe45fb0","quiz-game/end-sketches.jsx":"344c4dbd2767","quiz-game/ios-frame.jsx":"911f9ccc95e7","quiz-game/words.js":"35263fe45fb0","quiz/Quiz.jsx":"eebec2992326","quiz/ios-frame.jsx":"d67eb3ffe562","quiz/quiz-data.js":"65c69e1a9cee","quiz/tweaks-panel.jsx":"a1107c630a56","role-game/RoleGame.jsx":"951d60cdd5d9","role-game/ios-frame.jsx":"d67eb3ffe562","role-game/levels.jsx":"50926fa55b23","role-game/levelup-sketches.jsx":"3eeab92f6555","role-game/levelup-variants.jsx":"90097990162b","role-game/questions.js":"7ccc83478f55","role-game/tweaks-panel.jsx":"a1107c630a56","tetri-psychometry-export/tetri-game.jsx":"0f0fbec59b26","tetri-psychometry-export/words.js":"35263fe45fb0","tetri-psychometry/TetriGame.jsx":"e3a6c86b8e20","tetri-psychometry/words.js":"35263fe45fb0","tetri-vocab/VocabGame.jsx":"818ad56f6fce","tetri-vocab/vocab-data.js":"704c9f66fcdf","ui_kits/flyer/FlyerBulletList.jsx":"c777714ad9ab","ui_kits/flyer/FlyerEventStamp.jsx":"51049c1d957d","ui_kits/flyer/FlyerFrame.jsx":"4657083a384b","ui_kits/flyer/FlyerHeadline.jsx":"7e70d6e424dc","ui_kits/flyer/FlyerLogoBlock.jsx":"226ec15611c3","ui_kits/web/BannerCTA.jsx":"c2cfe1aff5d6","ui_kits/web/CourseGrid.jsx":"3e5dd3062642","ui_kits/web/Footer.jsx":"ee1960cf5310","ui_kits/web/Hero.jsx":"39c9519cb9c6","ui_kits/web/Includes.jsx":"853a71769dcb","ui_kits/web/LeadForm.jsx":"56cd43f920cc","ui_kits/web/SiteHeader.jsx":"1cfdb3887752","word-game/design-canvas.jsx":"d3ddcf4241b9","workshop-followup/doc-page.js":"62024d965071","workshop-followup/habits-data.js":"4afdc952666e","workshop-followup/מקור-לעריכה/habits-data.js":"4afdc952666e"},"inlinedExternals":[],"unexposedExports":[]} */ (() => { const __ds_ns = (window.EazyDesignSystem_019e08 = window.EazyDesignSystem_019e08 || {}); const __ds_scope = {}; (__ds_ns.__errors = __ds_ns.__errors || []); // components/EzButton/EzButton.jsx try { (() => { /* global React */ const { useState } = React; /** * EzButton — the eazy brand button. * Solid fills only (no gradients), pill radius, Avigul display type. * Hover darkens the fill 8% per the brand spec; active presses to scale(.99). */ function EzButton({ children, variant = "primary", type = "button", disabled = false, onClick }) { const [hover, setHover] = useState(false); const [active, setActive] = useState(false); const base = { fontFamily: "var(--font-display, system-ui)", fontWeight: 700, fontSize: 16, lineHeight: 1, borderRadius: 999, padding: "12px 28px", cursor: disabled ? "not-allowed" : "pointer", opacity: disabled ? 0.4 : 1, border: 0, transition: "background .15s, color .15s, transform .08s", transform: active && !disabled ? "scale(.99)" : "none", outlineOffset: 2 }; const skins = { primary: { background: hover && !disabled ? "var(--ez-orange-deep)" : "var(--ez-orange)", color: "#fff" }, secondary: { background: hover && !disabled ? "var(--ez-lavender-deep)" : "var(--ez-lavender)", color: hover && !disabled ? "#fff" : "#1d1a3a" }, ghost: { background: hover && !disabled ? "var(--ez-ink)" : "transparent", color: hover && !disabled ? "#fff" : "var(--ez-ink)", border: "1.5px solid var(--ez-ink)", padding: "11px 26px" }, link: { background: "transparent", color: hover && !disabled ? "var(--ez-orange-deep)" : "var(--ez-lavender-deep)", padding: "12px 0" } }; return /*#__PURE__*/React.createElement("button", { type: type, disabled: disabled, onClick: onClick, onMouseEnter: () => setHover(true), onMouseLeave: () => { setHover(false); setActive(false); }, onMouseDown: () => setActive(true), onMouseUp: () => setActive(false), style: { ...base, ...skins[variant] } }, children); } Object.assign(__ds_scope, { EzButton }); })(); } catch (e) { __ds_ns.__errors.push({ path: "components/EzButton/EzButton.jsx", error: String((e && e.message) || e) }); } // eazy-landing/doc-page.js try { (() => { // @ds-adherence-ignore -- omelette starter scaffold (raw elements/hex/px by design) /* BEGIN USAGE */ /** * — paged-document shell for printable HTML. * * On screen the document renders as a single continuous sheet on a desk * background (Google Docs' pageless view): you scroll one tall page card. * There is no manual page-splitting — write the whole document as normal * flow inside and the browser's print engine paginates it at * export. * * At print the component injects `@page { size: …; margin: 0 }` (which * leaves Chrome no margin box to draw its date/URL/page-count header in) * and moves the visual margin onto the sheet's own padding, so the printed * page has the same inset you see on screen. Standard break-hygiene rules * (`break-inside: avoid` on figures, code blocks, images and table rows; * `orphans/widows: 3`) are applied so paragraphs and groups split cleanly. * On screen and at print, headings default to `text-wrap: balance` and * body text (p, li, blockquote, figcaption) to `text-wrap: pretty`, so * the document avoids widowed/orphaned words; the defaults have zero * specificity, so any text-wrap you declare on those elements wins. * * Usage: * * *

Title

*

…body…

*
* * * Attributes: * size — letter | a4 | legal (default letter) * width / height — explicit CSS lengths, override `size` * margin — printable inset on every page (default 0.75in) * * Running header/footer (optional): give an element `slot="header"` or * `slot="footer"` and it repeats on every printed page via * `position: fixed`. To keep body text from sliding under it, the * component prints inside a single-cell table whose / are * spacers sized to the header/footer height — browsers repeat thead/tfoot * on every page, so each sheet's content starts below the header and ends * above the footer. On screen the header/footer render once at the * top/bottom of the sheet. * * Author content as static HTML so the user can click-to-edit any text * directly. Do not set width/padding/background on the document body — * the component owns the sheet box. */ /* END USAGE */ (() => { const PAPER = { letter: ['8.5in', '11in'], a4: ['210mm', '297mm'], legal: ['8.5in', '14in'] }; const CSS_LENGTH = /^\d+(\.\d+)?(px|in|mm|cm|pt|pc)$/; const safeLen = (v, fb) => CSS_LENGTH.test((v || '').trim()) ? v.trim() : fb; const stylesheet = ` :host { position: relative; display: block; min-height: 100vh; background: #ece8dd; padding: 48px 24px; box-sizing: border-box; font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", Arial, sans-serif; --doc-page-w: 8.5in; --doc-page-h: 11in; --doc-page-margin: 0.75in; --doc-hdr-h: 0px; --doc-ftr-h: 0px; } .sheet { width: var(--doc-page-w); margin: 0 auto; background: #fff; box-shadow: 0 2px 14px rgba(20, 20, 19, 0.12); border-radius: 2px; box-sizing: border-box; padding: var(--doc-page-margin); } .frame { width: 100%; border-collapse: collapse; } .frame td, .frame th { padding: 0; text-align: left; font-weight: inherit; } .hdr-space { height: var(--doc-hdr-h); } .ftr-space { height: var(--doc-ftr-h); } ::slotted([slot="header"]), ::slotted([slot="footer"]) { display: block; box-sizing: border-box; } @media print { :host { background: none; padding: 0; min-height: 0; } .sheet { width: auto; margin: 0; box-shadow: none; border-radius: 0; padding: 0 var(--doc-page-margin); } /* The thead/tfoot spacers repeat on every page, so they carry the * vertical page margin (which the sheet's own padding cannot, since * that padding is consumed once on the first/last page). The running * header/footer are fixed inside that band. */ .hdr-space { height: max(var(--doc-page-margin), calc(var(--doc-hdr-h) + 0.35in)); } .ftr-space { height: max(var(--doc-page-margin), calc(var(--doc-ftr-h) + 0.35in)); } ::slotted([slot="header"]) { position: fixed; top: 0; left: 0; right: 0; margin: 0; padding: calc(var(--doc-page-margin) * 0.45) var(--doc-page-margin) 0; } ::slotted([slot="footer"]) { position: fixed; bottom: 0; left: 0; right: 0; margin: 0; padding: 0 var(--doc-page-margin) calc(var(--doc-page-margin) * 0.45); } } `; class DocPage extends HTMLElement { static get observedAttributes() { return ['size', 'width', 'height', 'margin']; } constructor() { super(); this._root = this.attachShadow({ mode: 'open' }); this._mo = typeof MutationObserver === 'function' ? new MutationObserver(() => this._scheduleMeasure()) : null; } get pageWidth() { const named = PAPER[(this.getAttribute('size') || '').toLowerCase()]; return safeLen(this.getAttribute('width'), named ? named[0] : PAPER.letter[0]); } get pageHeight() { const named = PAPER[(this.getAttribute('size') || '').toLowerCase()]; return safeLen(this.getAttribute('height'), named ? named[1] : PAPER.letter[1]); } get pageMargin() { return safeLen(this.getAttribute('margin'), '0.75in'); } connectedCallback() { if (!this._sheet) this._render(); this._syncSize(); this._syncPrintPageRule(); this._ensureTextWrapDefaults(); if (this._mo) this._mo.observe(this, { subtree: true, childList: true, characterData: true, attributes: true }); this._onResize = () => this._scheduleMeasure(); window.addEventListener('resize', this._onResize); if (document.fonts && document.fonts.ready) { document.fonts.ready.then(() => this._scheduleMeasure()); } this._scheduleMeasure(); } disconnectedCallback() { window.removeEventListener('resize', this._onResize); if (this._mo) this._mo.disconnect(); if (this._raf) { cancelAnimationFrame(this._raf); this._raf = null; } // Drop the head rules when the last doc-page leaves, so a deleted // document's @page geometry and text-wrap defaults can't apply to // whatever replaces it. if (!document.querySelector('doc-page')) { ['doc-page-print', 'doc-page-text-wrap'].forEach(id => { const tag = document.getElementById(id); if (tag) tag.remove(); }); } } attributeChangedCallback() { if (!this._sheet) return; this._syncSize(); this._syncPrintPageRule(); this._scheduleMeasure(); } _render() { this._root.innerHTML = `
`; this._sheet = this._root.querySelector('.sheet'); this._vars = this._root.getElementById('vars'); } /** Runtime sizing lives in a shadow ' : '') + '' + xml + ''; return save(new Blob([html], { type: 'text/html' }), 'html'); } // PNG: the SVG's own width/height must be the output resolution — an // -loaded SVG rasterizes at its intrinsic size, so sizing it at 1× // and ctx.scale()-ing up would just upscale a 1× bitmap. viewBox maps the // w×h foreignObject onto the px·w × px·h SVG canvas so the browser renders // the HTML at full resolution. const px = 3; const svg = '' + (fontCss ? '' : '') + xml + ''; const img = new Image(); await new Promise((res, rej) => { img.onload = res; img.onerror = () => rej(new Error('svg load failed')); img.src = 'data:image/svg+xml;charset=utf-8,' + encodeURIComponent(svg); }); const cv = document.createElement('canvas'); cv.width = w * px; cv.height = h * px; cv.getContext('2d').drawImage(img, 0, 0); cv.toBlob(blob => save(blob, 'png'), 'image/png'); } function DCArtboardFrame({ sectionId, artboard, label, order, onRename, onReorder, onFocus, onDelete }) { const { id: rawId, label: rawLabel, width = 260, height = 480, children, style = {} } = artboard.props; const id = rawId ?? rawLabel; const ref = React.useRef(null); const cardRef = React.useRef(null); const menuRef = React.useRef(null); const [menuOpen, setMenuOpen] = React.useState(false); const [confirming, setConfirming] = React.useState(false); // ⋯ menu: close on any outside pointerdown. Two-click delete lives inside // the menu — first click arms the row, second commits; closing disarms. React.useEffect(() => { if (!menuOpen) { setConfirming(false); return; } const off = e => { if (!menuRef.current || !menuRef.current.contains(e.target)) setMenuOpen(false); }; document.addEventListener('pointerdown', off, true); return () => document.removeEventListener('pointerdown', off, true); }, [menuOpen]); const doExport = kind => { setMenuOpen(false); if (!cardRef.current) return; const name = String(label || id || 'artboard').replace(/[^\w\s.-]+/g, '_'); dcExport(cardRef.current, width, height, name, kind).catch(e => console.error('[design-canvas] export failed:', e)); }; // Live drag-reorder: dragged card sticks to cursor; siblings slide into // their would-be slots in real time via transforms. DOM order only // changes on drop. const onGripDown = e => { e.preventDefault(); e.stopPropagation(); const me = ref.current; // translateX is applied in local (pre-scale) space but pointer deltas and // getBoundingClientRect().left are screen-space — divide by the viewport's // current scale so the dragged card tracks the cursor at any zoom level. const scale = me.getBoundingClientRect().width / me.offsetWidth || 1; const peers = Array.from(document.querySelectorAll(`[data-dc-section="${sectionId}"] [data-dc-slot]`)); const homes = peers.map(el => ({ el, id: el.dataset.dcSlot, x: el.getBoundingClientRect().left })); const slotXs = homes.map(h => h.x); const startIdx = order.indexOf(id); const startX = e.clientX; let liveOrder = order.slice(); me.classList.add('dc-dragging'); const layout = () => { for (const h of homes) { if (h.id === id) continue; const slot = liveOrder.indexOf(h.id); h.el.style.transform = `translateX(${(slotXs[slot] - h.x) / scale}px)`; } }; const move = ev => { const dx = ev.clientX - startX; me.style.transform = `translateX(${dx / scale}px)`; const cur = homes[startIdx].x + dx; let nearest = 0, best = Infinity; for (let i = 0; i < slotXs.length; i++) { const d = Math.abs(slotXs[i] - cur); if (d < best) { best = d; nearest = i; } } if (liveOrder.indexOf(id) !== nearest) { liveOrder = order.filter(k => k !== id); liveOrder.splice(nearest, 0, id); layout(); } }; const up = () => { document.removeEventListener('pointermove', move); document.removeEventListener('pointerup', up); const finalSlot = liveOrder.indexOf(id); me.classList.remove('dc-dragging'); me.style.transform = `translateX(${(slotXs[finalSlot] - homes[startIdx].x) / scale}px)`; // After the settle transition, kill transitions + clear transforms + // commit the reorder in the same frame so there's no visual snap-back. setTimeout(() => { for (const h of homes) { h.el.style.transition = 'none'; h.el.style.transform = ''; } if (liveOrder.join('|') !== order.join('|')) onReorder(liveOrder); requestAnimationFrame(() => requestAnimationFrame(() => { for (const h of homes) h.el.style.transition = ''; })); }, 180); }; document.addEventListener('pointermove', move); document.addEventListener('pointerup', up); }; return /*#__PURE__*/React.createElement("div", { ref: ref, "data-dc-slot": id, style: { position: 'relative', flexShrink: 0 } }, /*#__PURE__*/React.createElement("div", { className: "dc-header", "data-noncommentable": "", style: { color: DC.label }, onPointerDown: e => e.stopPropagation() }, /*#__PURE__*/React.createElement("div", { className: "dc-labelrow" }, /*#__PURE__*/React.createElement("div", { className: "dc-grip", onPointerDown: onGripDown, title: "Drag to reorder" }, /*#__PURE__*/React.createElement("svg", { width: "9", height: "13", viewBox: "0 0 9 13", fill: "currentColor" }, /*#__PURE__*/React.createElement("circle", { cx: "2", cy: "2", r: "1.1" }), /*#__PURE__*/React.createElement("circle", { cx: "7", cy: "2", r: "1.1" }), /*#__PURE__*/React.createElement("circle", { cx: "2", cy: "6.5", r: "1.1" }), /*#__PURE__*/React.createElement("circle", { cx: "7", cy: "6.5", r: "1.1" }), /*#__PURE__*/React.createElement("circle", { cx: "2", cy: "11", r: "1.1" }), /*#__PURE__*/React.createElement("circle", { cx: "7", cy: "11", r: "1.1" }))), /*#__PURE__*/React.createElement("div", { className: "dc-labeltext", onClick: onFocus, title: "Click to focus" }, /*#__PURE__*/React.createElement(DCEditable, { value: label, onChange: onRename, onClick: e => e.stopPropagation(), style: { fontSize: 15, fontWeight: 500, color: DC.label, lineHeight: 1 } }))), /*#__PURE__*/React.createElement("div", { className: "dc-btns" }, /*#__PURE__*/React.createElement("div", { ref: menuRef, style: { position: 'relative' } }, /*#__PURE__*/React.createElement("button", { className: "dc-kebab", title: "More", onClick: () => setMenuOpen(o => !o) }, /*#__PURE__*/React.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "currentColor" }, /*#__PURE__*/React.createElement("circle", { cx: "2.5", cy: "6", r: "1.1" }), /*#__PURE__*/React.createElement("circle", { cx: "6", cy: "6", r: "1.1" }), /*#__PURE__*/React.createElement("circle", { cx: "9.5", cy: "6", r: "1.1" }))), menuOpen && /*#__PURE__*/React.createElement("div", { className: "dc-menu", onPointerDown: e => e.stopPropagation() }, /*#__PURE__*/React.createElement("button", { onClick: () => doExport('png') }, "Download PNG"), /*#__PURE__*/React.createElement("button", { onClick: () => doExport('html') }, "Download HTML"), /*#__PURE__*/React.createElement("hr", null), /*#__PURE__*/React.createElement("button", { className: "dc-danger", onClick: () => { if (confirming) { setMenuOpen(false); onDelete(); } else setConfirming(true); } }, confirming ? 'Click again to delete' : 'Delete'))), /*#__PURE__*/React.createElement("button", { className: "dc-expand", onClick: onFocus, title: "Focus" }, /*#__PURE__*/React.createElement("svg", { width: "12", height: "12", viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round" }, /*#__PURE__*/React.createElement("path", { d: "M7 1h4v4M5 11H1V7M11 1L7.5 4.5M1 11l3.5-3.5" }))))), /*#__PURE__*/React.createElement("div", { ref: cardRef, className: "dc-card", style: { borderRadius: 2, boxShadow: '0 1px 3px rgba(0,0,0,.08),0 4px 16px rgba(0,0,0,.06)', overflow: 'hidden', width, height, background: '#fff', ...style } }, children || /*#__PURE__*/React.createElement("div", { style: { height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#bbb', fontSize: 13, fontFamily: DC.font } }, id))); } // Inline rename — commits on blur or Enter. function DCEditable({ value, onChange, style, tag = 'span', onClick }) { const T = tag; return /*#__PURE__*/React.createElement(T, { className: "dc-editable", contentEditable: true, suppressContentEditableWarning: true, onClick: onClick, onPointerDown: e => e.stopPropagation(), onBlur: e => onChange && onChange(e.currentTarget.textContent), onKeyDown: e => { if (e.key === 'Enter') { e.preventDefault(); e.currentTarget.blur(); } }, style: style }, value); } // ───────────────────────────────────────────────────────────── // Focus mode — overlay one artboard; ←/→ within section, ↑/↓ across // sections, Esc or backdrop click to exit. // ───────────────────────────────────────────────────────────── function DCFocusOverlay({ entry, sectionMeta, sectionOrder }) { const ctx = React.useContext(DCCtx); const { sectionId, artboard } = entry; const sec = ctx.section(sectionId); const meta = sectionMeta[sectionId]; const peers = meta.slotIds; const aid = artboard.props.id ?? artboard.props.label; const idx = peers.indexOf(aid); const secIdx = sectionOrder.indexOf(sectionId); const go = d => { const n = peers[(idx + d + peers.length) % peers.length]; if (n) ctx.setFocus(`${sectionId}/${n}`); }; const goSection = d => { // Sections whose artboards are all deleted have slotIds:[] — step past // them to the next non-empty section so ↑/↓ doesn't dead-end. const n = sectionOrder.length; for (let i = 1; i < n; i++) { const ns = sectionOrder[((secIdx + d * i) % n + n) % n]; const first = sectionMeta[ns] && sectionMeta[ns].slotIds[0]; if (first) { ctx.setFocus(`${ns}/${first}`); return; } } }; React.useEffect(() => { const k = e => { if (e.key === 'ArrowLeft') { e.preventDefault(); go(-1); } if (e.key === 'ArrowRight') { e.preventDefault(); go(1); } if (e.key === 'ArrowUp') { e.preventDefault(); goSection(-1); } if (e.key === 'ArrowDown') { e.preventDefault(); goSection(1); } }; document.addEventListener('keydown', k); return () => document.removeEventListener('keydown', k); }); const { width = 260, height = 480, children } = artboard.props; const [vp, setVp] = React.useState({ w: window.innerWidth, h: window.innerHeight }); React.useEffect(() => { const r = () => setVp({ w: window.innerWidth, h: window.innerHeight }); window.addEventListener('resize', r); return () => window.removeEventListener('resize', r); }, []); const scale = Math.max(0.1, Math.min((vp.w - 200) / width, (vp.h - 260) / height, 2)); const [ddOpen, setDd] = React.useState(false); const Arrow = ({ dir, onClick }) => /*#__PURE__*/React.createElement("button", { onClick: e => { e.stopPropagation(); onClick(); }, style: { position: 'absolute', top: '50%', [dir]: 28, transform: 'translateY(-50%)', border: 'none', background: 'rgba(255,255,255,.08)', color: 'rgba(255,255,255,.9)', width: 44, height: 44, borderRadius: 22, fontSize: 18, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', transition: 'background .15s' }, onMouseEnter: e => e.currentTarget.style.background = 'rgba(255,255,255,.18)', onMouseLeave: e => e.currentTarget.style.background = 'rgba(255,255,255,.08)' }, /*#__PURE__*/React.createElement("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }, /*#__PURE__*/React.createElement("path", { d: dir === 'left' ? 'M11 3L5 9l6 6' : 'M7 3l6 6-6 6' }))); // Portal to body so position:fixed is the real viewport regardless of any // transform on DesignCanvas's ancestors (including the canvas zoom itself). return ReactDOM.createPortal(/*#__PURE__*/React.createElement("div", { onClick: () => ctx.setFocus(null), onWheel: e => e.preventDefault(), style: { position: 'fixed', inset: 0, zIndex: 100, background: 'rgba(24,20,16,.6)', backdropFilter: 'blur(14px)', fontFamily: DC.font, color: '#fff' } }, /*#__PURE__*/React.createElement("div", { onClick: e => e.stopPropagation(), style: { position: 'absolute', top: 0, left: 0, right: 0, height: 72, display: 'flex', alignItems: 'flex-start', padding: '16px 20px 0', gap: 16 } }, /*#__PURE__*/React.createElement("div", { style: { position: 'relative' } }, /*#__PURE__*/React.createElement("button", { onClick: () => setDd(o => !o), style: { border: 'none', background: 'transparent', color: '#fff', cursor: 'pointer', padding: '6px 8px', borderRadius: 6, textAlign: 'left', fontFamily: 'inherit' } }, /*#__PURE__*/React.createElement("span", { style: { display: 'flex', alignItems: 'center', gap: 8 } }, /*#__PURE__*/React.createElement("span", { style: { fontSize: 18, fontWeight: 600, letterSpacing: -0.3 } }, meta.title), /*#__PURE__*/React.createElement("svg", { width: "11", height: "11", viewBox: "0 0 11 11", fill: "none", stroke: "currentColor", strokeWidth: "1.8", strokeLinecap: "round", style: { opacity: .7 } }, /*#__PURE__*/React.createElement("path", { d: "M2 4l3.5 3.5L9 4" }))), meta.subtitle && /*#__PURE__*/React.createElement("span", { style: { display: 'block', fontSize: 13, opacity: .6, fontWeight: 400, marginTop: 2 } }, meta.subtitle)), ddOpen && /*#__PURE__*/React.createElement("div", { style: { position: 'absolute', top: '100%', left: 0, marginTop: 4, background: '#2a251f', borderRadius: 8, boxShadow: '0 8px 32px rgba(0,0,0,.4)', padding: 4, minWidth: 200, zIndex: 10 } }, sectionOrder.filter(sid => sectionMeta[sid].slotIds.length).map(sid => /*#__PURE__*/React.createElement("button", { key: sid, onClick: () => { setDd(false); const f = sectionMeta[sid].slotIds[0]; if (f) ctx.setFocus(`${sid}/${f}`); }, style: { display: 'block', width: '100%', textAlign: 'left', border: 'none', cursor: 'pointer', background: sid === sectionId ? 'rgba(255,255,255,.1)' : 'transparent', color: '#fff', padding: '8px 12px', borderRadius: 5, fontSize: 14, fontWeight: sid === sectionId ? 600 : 400, fontFamily: 'inherit' } }, sectionMeta[sid].title)))), /*#__PURE__*/React.createElement("div", { style: { flex: 1 } }), /*#__PURE__*/React.createElement("button", { onClick: () => ctx.setFocus(null), onMouseEnter: e => e.currentTarget.style.background = 'rgba(255,255,255,.12)', onMouseLeave: e => e.currentTarget.style.background = 'transparent', style: { border: 'none', background: 'transparent', color: 'rgba(255,255,255,.7)', width: 32, height: 32, borderRadius: 16, fontSize: 20, cursor: 'pointer', lineHeight: 1, transition: 'background .12s' } }, "\xD7")), /*#__PURE__*/React.createElement("div", { style: { position: 'absolute', top: 64, bottom: 56, left: 100, right: 100, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 16 } }, /*#__PURE__*/React.createElement("div", { onClick: e => e.stopPropagation(), style: { width: width * scale, height: height * scale, position: 'relative' } }, /*#__PURE__*/React.createElement("div", { style: { width, height, transform: `scale(${scale})`, transformOrigin: 'top left', background: '#fff', borderRadius: 2, overflow: 'hidden', boxShadow: '0 20px 80px rgba(0,0,0,.4)' } }, children || /*#__PURE__*/React.createElement("div", { style: { height: '100%', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#bbb' } }, aid))), /*#__PURE__*/React.createElement("div", { onClick: e => e.stopPropagation(), style: { fontSize: 14, fontWeight: 500, opacity: .85, textAlign: 'center' } }, (sec.labels || {})[aid] ?? artboard.props.label, /*#__PURE__*/React.createElement("span", { style: { opacity: .5, marginLeft: 10, fontVariantNumeric: 'tabular-nums' } }, idx + 1, " / ", peers.length))), /*#__PURE__*/React.createElement(Arrow, { dir: "left", onClick: () => go(-1) }), /*#__PURE__*/React.createElement(Arrow, { dir: "right", onClick: () => go(1) }), /*#__PURE__*/React.createElement("div", { onClick: e => e.stopPropagation(), style: { position: 'absolute', bottom: 20, left: '50%', transform: 'translateX(-50%)', display: 'flex', gap: 8 } }, peers.map((p, i) => /*#__PURE__*/React.createElement("button", { key: p, onClick: () => ctx.setFocus(`${sectionId}/${p}`), style: { border: 'none', padding: 0, cursor: 'pointer', width: 6, height: 6, borderRadius: 3, background: i === idx ? '#fff' : 'rgba(255,255,255,.3)' } })))), document.body); } // ───────────────────────────────────────────────────────────── // Post-it — absolute-positioned sticky note // ───────────────────────────────────────────────────────────── function DCPostIt({ children, top, left, right, bottom, rotate = -2, width = 180 }) { return /*#__PURE__*/React.createElement("div", { style: { position: 'absolute', top, left, right, bottom, width, background: DC.postitBg, padding: '14px 16px', fontFamily: '"Comic Sans MS", "Marker Felt", "Segoe Print", cursive', fontSize: 14, lineHeight: 1.4, color: DC.postitText, boxShadow: '0 2px 8px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.08)', transform: `rotate(${rotate}deg)`, zIndex: 5 } }, children); } Object.assign(window, { DesignCanvas, DCSection, DCArtboard, DCPostIt }); })(); } catch (e) { __ds_ns.__errors.push({ path: "quiz-game/design-canvas.jsx", error: String((e && e.message) || e) }); } // quiz-game/dist/game.js try { (() => { "use strict"; function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i.return) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); } function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); } function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); } function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; } function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } } function _arrayWithHoles(r) { if (Array.isArray(r)) return r; } function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t.return || t.return(); } finally { if (u) throw o; } } }; } function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } } function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); } function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); } function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; } /* global React, XLSX */ var _React = React, useState = _React.useState, useEffect = _React.useEffect, useRef = _React.useRef, useCallback = _React.useCallback, useLayoutEffect = _React.useLayoutEffect, useMemo = _React.useMemo; /* ---------- built-in sample dictionary ---------- */ var SAMPLE_DICT = [{ en: "ENHANCE", he: "להעצים, לשפר", ipa: "/ɪnˈhæns/" }, { en: "MITIGATE", he: "להקל, למתן", ipa: "/ˈmɪtɪˌɡeɪt/" }, { en: "AMBIGUOUS", he: "דו-משמעי, עמום", ipa: "/æmˈbɪɡjuəs/" }, { en: "ADVOCATE", he: "לתמוך, להמליץ", ipa: "/ˈædvəˌkeɪt/" }, { en: "SCRUTINIZE", he: "לבחון בקפדנות", ipa: "/ˈskruːtəˌnaɪz/" }, { en: "INEVITABLE", he: "בלתי נמנע", ipa: "/ɪˈnɛvɪtəbəl/" }, { en: "DILIGENT", he: "חרוץ, שקדן", ipa: "/ˈdɪlɪdʒənt/" }, { en: "OBSOLETE", he: "מיושן, יצא משימוש", ipa: "/ˌabsəˈliːt/" }, { en: "CANDID", he: "הֵן, ישיר, ספונטני", ipa: "/ˈkændɪd/" }, { en: "TENACIOUS", he: "עיקש, דבק במטרה", ipa: "/təˈneɪʃəs/" }]; var STAGGER = [0, 40, 14, 56]; var DICT_STORAGE_KEY = "ez-mcq-dict-v2"; var DICT_NAME_KEY = "ez-mcq-dict-name-v2"; var MUTED_KEY = "ez-mcq-muted-v1"; var LB_KEY = "ez-mcq-leaderboard-v1"; /* ---------- sound engine (WebAudio FX + background music) ---------- */ var Sound = { ctx: null, muted: false, music: null, //