efficient-shell 4.132.0 → 4.137.0

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.
Files changed (117) hide show
  1. package/README.md +142 -18
  2. package/dist/{Browser-XPVJ2K7B.js → Browser-ZNX4WFUH.js} +13 -13
  3. package/dist/{Browser-XPVJ2K7B.js.map → Browser-ZNX4WFUH.js.map} +1 -1
  4. package/dist/{Calculator-ZXJPXG7F.js → Calculator-6FGNKOXU.js} +11 -11
  5. package/dist/{Calculator-ZXJPXG7F.js.map → Calculator-6FGNKOXU.js.map} +1 -1
  6. package/dist/ConfirmDialog-NPQMIGUR.js +4 -0
  7. package/dist/{ConfirmDialog-MTC7QMUJ.js.map → ConfirmDialog-NPQMIGUR.js.map} +1 -1
  8. package/dist/{CurrencyConverter-WSJ2BBSX.js → CurrencyConverter-FF7EXRYL.js} +11 -11
  9. package/dist/{CurrencyConverter-WSJ2BBSX.js.map → CurrencyConverter-FF7EXRYL.js.map} +1 -1
  10. package/dist/{Documents-ONGSXUJI.js → Documents-H3R7XSBH.js} +13 -13
  11. package/dist/{Documents-ONGSXUJI.js.map → Documents-H3R7XSBH.js.map} +1 -1
  12. package/dist/{Files-GQZMFWXQ.js → Files-ZHJIAUC2.js} +19 -19
  13. package/dist/{Files-GQZMFWXQ.js.map → Files-ZHJIAUC2.js.map} +1 -1
  14. package/dist/{Notepad-HM73XAM4.js → Notepad-VE7ISWRQ.js} +14 -14
  15. package/dist/{Notepad-HM73XAM4.js.map → Notepad-VE7ISWRQ.js.map} +1 -1
  16. package/dist/PdfViewer-SQBFYAGW.js +5 -0
  17. package/dist/{PdfViewer-M2YGZIYX.js.map → PdfViewer-SQBFYAGW.js.map} +1 -1
  18. package/dist/{PomodoroTimer-DG3LI5CX.js → PomodoroTimer-IR3WREED.js} +13 -13
  19. package/dist/{PomodoroTimer-DG3LI5CX.js.map → PomodoroTimer-IR3WREED.js.map} +1 -1
  20. package/dist/{Preview-TUSV4UMO.js → Preview-DAQGRNRM.js} +16 -16
  21. package/dist/{Preview-TUSV4UMO.js.map → Preview-DAQGRNRM.js.map} +1 -1
  22. package/dist/{Sidebar-BPU7RCZP.js → Sidebar-YW6H4NDJ.js} +3 -3
  23. package/dist/{Sidebar-BPU7RCZP.js.map → Sidebar-YW6H4NDJ.js.map} +1 -1
  24. package/dist/{Spreadsheet-3WTXCHYQ.js → Spreadsheet-HOCPHJOC.js} +14 -14
  25. package/dist/{Spreadsheet-3WTXCHYQ.js.map → Spreadsheet-HOCPHJOC.js.map} +1 -1
  26. package/dist/{Stock-YMPOMUAW.js → Stock-LVRQPURG.js} +11 -11
  27. package/dist/{Stock-YMPOMUAW.js.map → Stock-LVRQPURG.js.map} +1 -1
  28. package/dist/{Weather-NZO3CWLH.js → Weather-LZQGVDJL.js} +11 -11
  29. package/dist/{Weather-NZO3CWLH.js.map → Weather-LZQGVDJL.js.map} +1 -1
  30. package/dist/{WorldClock-HUC6D3AD.js → WorldClock-XPD7WOZT.js} +11 -11
  31. package/dist/{WorldClock-HUC6D3AD.js.map → WorldClock-XPD7WOZT.js.map} +1 -1
  32. package/dist/apps/index.d.ts +2 -2
  33. package/dist/apps/index.js +30 -30
  34. package/dist/apps/index.js.map +1 -1
  35. package/dist/brand.css +1 -1
  36. package/dist/{chunk-CT3HVZRZ.js → chunk-5O42JXQE.js} +2 -2
  37. package/dist/chunk-5O42JXQE.js.map +1 -0
  38. package/dist/{chunk-CGXMWHQW.js → chunk-5RPTS3BT.js} +3 -3
  39. package/dist/{chunk-CGXMWHQW.js.map → chunk-5RPTS3BT.js.map} +1 -1
  40. package/dist/{chunk-D276EMXS.js → chunk-6XJEJWNJ.js} +7 -3
  41. package/dist/chunk-6XJEJWNJ.js.map +1 -0
  42. package/dist/{chunk-I464GYJJ.js → chunk-BE7FZOFU.js} +2 -2
  43. package/dist/chunk-BE7FZOFU.js.map +1 -0
  44. package/dist/{chunk-CJYO4RVV.js → chunk-COWYSHG2.js} +5 -5
  45. package/dist/chunk-COWYSHG2.js.map +1 -0
  46. package/dist/{chunk-3L463T5H.js → chunk-DVZWYWSD.js} +2 -2
  47. package/dist/chunk-DVZWYWSD.js.map +1 -0
  48. package/dist/{chunk-MQPX6ERJ.js → chunk-E7TB6WD2.js} +4 -4
  49. package/dist/{chunk-MQPX6ERJ.js.map → chunk-E7TB6WD2.js.map} +1 -1
  50. package/dist/{chunk-SEWF4O3H.js → chunk-FIHOGVUP.js} +3 -3
  51. package/dist/chunk-FIHOGVUP.js.map +1 -0
  52. package/dist/{chunk-TQURTLK2.js → chunk-HUBJAUGG.js} +5 -5
  53. package/dist/{chunk-TQURTLK2.js.map → chunk-HUBJAUGG.js.map} +1 -1
  54. package/dist/{chunk-XH3ELPQZ.js → chunk-I2TAAJHS.js} +3 -3
  55. package/dist/chunk-I2TAAJHS.js.map +1 -0
  56. package/dist/{chunk-ZKHD4J73.js → chunk-ICTRCKUE.js} +10 -10
  57. package/dist/chunk-ICTRCKUE.js.map +1 -0
  58. package/dist/{chunk-E3TWIN7Z.js → chunk-JOPU6WPY.js} +7 -6
  59. package/dist/chunk-JOPU6WPY.js.map +1 -0
  60. package/dist/{chunk-7MA5XBWD.js → chunk-PVPPAWVM.js} +5 -5
  61. package/dist/{chunk-7MA5XBWD.js.map → chunk-PVPPAWVM.js.map} +1 -1
  62. package/dist/{chunk-FONEQRBH.js → chunk-R7QGMK6N.js} +3 -3
  63. package/dist/{chunk-FONEQRBH.js.map → chunk-R7QGMK6N.js.map} +1 -1
  64. package/dist/{chunk-LQTVTOSY.js → chunk-RT6DSB5Y.js} +45 -19
  65. package/dist/chunk-RT6DSB5Y.js.map +1 -0
  66. package/dist/{chunk-BFBWLCO6.js → chunk-TW7LPMVR.js} +2 -2
  67. package/dist/chunk-TW7LPMVR.js.map +1 -0
  68. package/dist/{chunk-EENVXIVU.js → chunk-UTYKLGGT.js} +3 -3
  69. package/dist/{chunk-EENVXIVU.js.map → chunk-UTYKLGGT.js.map} +1 -1
  70. package/dist/{chunk-KWEX4ZAF.js → chunk-VNJJCH5A.js} +3 -3
  71. package/dist/{chunk-KWEX4ZAF.js.map → chunk-VNJJCH5A.js.map} +1 -1
  72. package/dist/{chunk-TFXJRHJV.js → chunk-XJHZWSKV.js} +3 -3
  73. package/dist/{chunk-TFXJRHJV.js.map → chunk-XJHZWSKV.js.map} +1 -1
  74. package/dist/{chunk-VWZIGZFF.js → chunk-Y3GYJ7YR.js} +4 -4
  75. package/dist/{chunk-VWZIGZFF.js.map → chunk-Y3GYJ7YR.js.map} +1 -1
  76. package/dist/{chunk-BJ34QOR3.js → chunk-YA4EE7ST.js} +842 -272
  77. package/dist/chunk-YA4EE7ST.js.map +1 -0
  78. package/dist/{chunk-CLGNTGC5.js → chunk-YDHXWCCJ.js} +3 -3
  79. package/dist/{chunk-CLGNTGC5.js.map → chunk-YDHXWCCJ.js.map} +1 -1
  80. package/dist/{chunk-7IN7YZAL.js → chunk-YE6GUDGP.js} +4 -3
  81. package/dist/chunk-YE6GUDGP.js.map +1 -0
  82. package/dist/chunk-ZS7PMGUW.js +7 -0
  83. package/dist/{chunk-JMKYYPOF.js.map → chunk-ZS7PMGUW.js.map} +1 -1
  84. package/dist/file-intake/index.js +2 -2
  85. package/dist/{index-COwksV6G.d.ts → index-DVI9DMSu.d.ts} +383 -20
  86. package/dist/index.d.ts +3 -3
  87. package/dist/index.js +39 -39
  88. package/dist/index.js.map +1 -1
  89. package/dist/map/index.js +1 -1
  90. package/dist/markdown/index.d.ts +4 -4
  91. package/dist/markdown/index.js.map +1 -1
  92. package/dist/markup/index.d.ts +2 -2
  93. package/dist/markup/index.js.map +1 -1
  94. package/dist/page-tabs/index.js +5 -5
  95. package/dist/shell.css +1 -1
  96. package/dist/styles.css +4 -4
  97. package/dist/themes.css +3 -3
  98. package/dist/ui/index.d.ts +1 -1
  99. package/dist/ui/index.js +14 -14
  100. package/dist/ui.css +311 -18
  101. package/package.json +1 -1
  102. package/dist/ConfirmDialog-MTC7QMUJ.js +0 -4
  103. package/dist/PdfViewer-M2YGZIYX.js +0 -5
  104. package/dist/chunk-3L463T5H.js.map +0 -1
  105. package/dist/chunk-7IN7YZAL.js.map +0 -1
  106. package/dist/chunk-BFBWLCO6.js.map +0 -1
  107. package/dist/chunk-BJ34QOR3.js.map +0 -1
  108. package/dist/chunk-CJYO4RVV.js.map +0 -1
  109. package/dist/chunk-CT3HVZRZ.js.map +0 -1
  110. package/dist/chunk-D276EMXS.js.map +0 -1
  111. package/dist/chunk-E3TWIN7Z.js.map +0 -1
  112. package/dist/chunk-I464GYJJ.js.map +0 -1
  113. package/dist/chunk-JMKYYPOF.js +0 -7
  114. package/dist/chunk-LQTVTOSY.js.map +0 -1
  115. package/dist/chunk-SEWF4O3H.js.map +0 -1
  116. package/dist/chunk-XH3ELPQZ.js.map +0 -1
  117. package/dist/chunk-ZKHD4J73.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/apps/Weather.tsx"],"names":["parts","h","m","t"],"mappings":"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","file":"Weather-NZO3CWLH.js","sourcesContent":["import { useState, useEffect, useCallback } from 'react';\nimport { useWidgetSettings } from '../shell/Modal';\nimport WidgetSettingsModal, { loadAppearance, type WidgetAppearance } from '../shell/WidgetSettingsModal';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport { AVAILABLE_CITIES, fetchCityWeather, getCondition, toFahrenheit, type CityWeather } from './_weatherData';\n\nconst STORAGE_KEY = 'weather_city';\nconst LEGACY_KEY = 'weather_cities';\nconst SETTINGS_KEY = 'weather_appearance';\n\ninterface WeatherPrefs { useFahrenheit: boolean; showLocalTime: boolean; use24Hour: boolean }\nconst DEFAULT_PREFS: WeatherPrefs = { useFahrenheit: false, showLocalTime: true, use24Hour: false };\n\nfunction detectLocalCity(): string {\n try {\n const userTz = Intl.DateTimeFormat().resolvedOptions().timeZone;\n for (const [name, info] of Object.entries(AVAILABLE_CITIES)) {\n if (info.tz === userTz) return name;\n }\n } catch {}\n return 'London';\n}\n\nfunction loadCity(): string {\n const v = typeof localStorage !== 'undefined' ? localStorage.getItem(STORAGE_KEY) : null;\n if (v && AVAILABLE_CITIES[v]) return v;\n try {\n const arr = JSON.parse(localStorage.getItem(LEGACY_KEY) || '');\n if (Array.isArray(arr) && arr[0] && AVAILABLE_CITIES[arr[0]]) {\n localStorage.setItem(STORAGE_KEY, arr[0]);\n return arr[0];\n }\n } catch {}\n return detectLocalCity();\n}\n\nconst toF = toFahrenheit;\n\nfunction getTimeInTz(timezone: string, use24Hour = false): string {\n try {\n if (use24Hour) {\n const parts = new Intl.DateTimeFormat('en-US', { timeZone: timezone, hour: 'numeric', minute: '2-digit', hour12: false }).formatToParts(new Date());\n const h = parseInt(parts.find(p => p.type === 'hour')?.value || '0');\n const m = parseInt(parts.find(p => p.type === 'minute')?.value || '0');\n return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`;\n }\n const parts = new Intl.DateTimeFormat('en-US', { timeZone: timezone, hour: 'numeric', minute: '2-digit', hour12: true }).formatToParts(new Date());\n const h = parseInt(parts.find(p => p.type === 'hour')?.value || '12');\n const m = parseInt(parts.find(p => p.type === 'minute')?.value || '0');\n const period = parts.find(p => p.type === 'dayPeriod')?.value || '';\n return `${h}:${String(m).padStart(2, '0')} ${period}`;\n } catch { return ''; }\n}\n\n/**\n * Effect keyframes — tuned for a ~110 px-tall card so drops/flakes fall\n * across the full height before recycling. Multiple snow/rain variants\n * give the impression of independent particles instead of a hypnotic\n * lock-step pattern.\n */\nconst WX_KEYFRAMES = `\n@keyframes wx-rain-a { 0% { transform: translate(0,-20px); opacity: 0; } 10% { opacity: 0.95; } 100% { transform: translate(8px,140px); opacity: 0; } }\n@keyframes wx-rain-b { 0% { transform: translate(0,-20px); opacity: 0; } 12% { opacity: 0.85; } 100% { transform: translate(12px,140px); opacity: 0; } }\n@keyframes wx-rain-c { 0% { transform: translate(0,-20px); opacity: 0; } 10% { opacity: 1; } 100% { transform: translate(5px,140px); opacity: 0; } }\n@keyframes wx-snow-a { 0% { transform: translate(0,-12px) rotate(0deg); opacity: 0; } 10% { opacity: 0.9; } 50% { transform: translate(10px,55px) rotate(180deg); } 100% { transform: translate(-4px,140px) rotate(360deg); opacity: 0; } }\n@keyframes wx-snow-b { 0% { transform: translate(0,-12px) rotate(0deg); opacity: 0; } 10% { opacity: 0.85; } 50% { transform: translate(-12px,55px) rotate(-180deg); } 100% { transform: translate(6px,140px) rotate(-360deg); opacity: 0; } }\n@keyframes wx-snow-c { 0% { transform: translate(0,-12px); opacity: 0; } 10% { opacity: 0.7; } 100% { transform: translate(2px,140px); opacity: 0; } }\n@keyframes wx-drift-cloud { 0% { transform: translateX(-40%); } 100% { transform: translateX(140%); } }\n@keyframes wx-twinkle { 0%, 100% { opacity: 0.25; transform: scale(1); } 50% { opacity: 1; transform: scale(1.6); } }\n@keyframes wx-flash { 0%, 86%, 100% { opacity: 0; } 87% { opacity: 0.95; } 88% { opacity: 0.15; } 89% { opacity: 0.85; } 90% { opacity: 0; } }\n@keyframes wx-bolt { 0%, 86%, 90%, 100% { opacity: 0; } 87% { opacity: 1; } 89% { opacity: 0.85; } }\n@keyframes wx-sun-pulse { 0%, 100% { transform: scale(1); opacity: 0.65; } 50% { transform: scale(1.12); opacity: 0.95; } }\n@keyframes wx-sun-rays { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }\n@keyframes wx-fog-drift { 0% { transform: translateX(-25%); opacity: 0.3; } 50% { opacity: 0.65; } 100% { transform: translateX(25%); opacity: 0.3; } }\n@keyframes wx-shooting-star { 0%, 95% { opacity: 0; transform: translate(0,0) scale(0); } 96% { opacity: 1; transform: translate(0,0) scale(1); } 100% { opacity: 0; transform: translate(40px,30px) scale(1); } }\n`;\n\nfunction SunEffect() {\n // Defined yellow-orange disc with halo + slowly-rotating ray sprite.\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n <div className=\"absolute -top-5 -right-5 w-24 h-24\" style={{ animation: 'wx-sun-rays 70s linear infinite' }}>\n <svg viewBox=\"0 0 100 100\" className=\"w-full h-full\">\n {Array.from({ length: 12 }).map((_, i) => (\n <rect key={i} x={49} y={3} width={2} height={14} rx={1}\n fill=\"rgba(255, 232, 130, 0.55)\"\n transform={`rotate(${i * 30} 50 50)`} />\n ))}\n </svg>\n </div>\n <div className=\"absolute top-1 right-1 w-10 h-10 rounded-full\"\n style={{\n background: 'radial-gradient(circle at 35% 35%, #fff8cc 0%, #ffd84a 55%, #ff9e2a 100%)',\n boxShadow: '0 0 18px 5px rgba(255, 200, 80, 0.55)',\n animation: 'wx-sun-pulse 4.5s ease-in-out infinite',\n }} />\n </div>\n );\n}\n\nfunction NightStarsEffect() {\n // Crescent moon (outer warm circle + offset dark circle to carve out the\n // bite) and a sparse scatter of stars twinkling at independent rates.\n // One slow-cycle shooting star adds a moment of motion without\n // distracting.\n const stars = Array.from({ length: 16 }).map((_, i) => ({\n left: `${(i * 53 + 11) % 95}%`,\n top: `${(i * 37 + 9) % 78}%`,\n size: 1 + ((i * 13) % 3),\n delay: `${(i * 0.41) % 4}s`,\n duration: `${2.5 + ((i * 7) % 5) * 0.6}s`,\n }));\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n {/* Crescent moon */}\n <div className=\"absolute top-1 right-1\">\n <svg viewBox=\"0 0 40 40\" className=\"w-9 h-9\" style={{ filter: 'drop-shadow(0 0 6px rgba(255,250,220,0.4))' }}>\n <defs>\n <radialGradient id=\"wx-moon-grad\" cx=\"35%\" cy=\"35%\">\n <stop offset=\"0\" stopColor=\"#fffae0\" />\n <stop offset=\"1\" stopColor=\"#d4c98a\" />\n </radialGradient>\n </defs>\n <circle cx={20} cy={20} r={13} fill=\"url(#wx-moon-grad)\" />\n <circle cx={26} cy={16} r={11} fill=\"rgba(15,23,42,1)\" />\n </svg>\n </div>\n {stars.map((s, i) => (\n <div key={i} className=\"absolute rounded-full bg-white\"\n style={{\n left: s.left, top: s.top, width: s.size, height: s.size,\n animation: `wx-twinkle ${s.duration} ease-in-out ${s.delay} infinite`,\n }} />\n ))}\n {/* Shooting star — appears once every ~12s */}\n <div className=\"absolute\" style={{ left: '15%', top: '20%', animation: 'wx-shooting-star 12s ease-out infinite' }}>\n <div className=\"w-12 h-px\"\n style={{ background: 'linear-gradient(to right, transparent, rgba(255,255,255,0.95))', boxShadow: '0 0 4px rgba(255,255,255,0.8)' }} />\n </div>\n </div>\n );\n}\n\nfunction CloudsEffect({ tone = 'light' as 'light' | 'dark' }) {\n const fill = tone === 'light' ? 'rgba(255,255,255,0.78)' : 'rgba(220,228,240,0.45)';\n const Cloud = ({ scale = 1 }) => (\n <svg viewBox=\"0 0 120 50\" className=\"w-32 h-12\" style={{ transform: `scale(${scale})`, filter: 'blur(0.6px)' }}>\n <ellipse cx={28} cy={36} rx={18} ry={11} fill={fill} />\n <ellipse cx={50} cy={28} rx={22} ry={15} fill={fill} />\n <ellipse cx={75} cy={32} rx={20} ry={12} fill={fill} />\n <ellipse cx={95} cy={38} rx={15} ry={9} fill={fill} />\n </svg>\n );\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n <div className=\"absolute\" style={{ top: '8%', animation: 'wx-drift-cloud 42s linear infinite' }}><Cloud scale={0.9} /></div>\n <div className=\"absolute\" style={{ top: '40%', animation: 'wx-drift-cloud 60s linear -22s infinite', opacity: 0.85 }}><Cloud scale={1.25} /></div>\n <div className=\"absolute\" style={{ top: '68%', animation: 'wx-drift-cloud 78s linear -45s infinite', opacity: 0.7 }}><Cloud scale={0.75} /></div>\n </div>\n );\n}\n\nfunction RainEffect({ heavy = false }: { heavy?: boolean }) {\n const count = heavy ? 26 : 16;\n const variants = ['wx-rain-a', 'wx-rain-b', 'wx-rain-c'];\n const drops = Array.from({ length: count }).map((_, i) => ({\n left: `${(i * 100 / count + (i * 11) % 7) % 100}%`,\n delay: `${(i * 0.087) % 1.3}s`,\n height: `${12 + (i % 4) * 5}px`,\n duration: `${0.7 + (i % 3) * 0.18}s`,\n variant: variants[i % variants.length],\n }));\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n {drops.map((d, i) => (\n <div key={i} className=\"absolute\"\n style={{\n left: d.left, top: '-20px',\n width: '1px', height: d.height,\n background: 'linear-gradient(180deg, rgba(180,210,255,0) 0%, rgba(220,235,255,0.85) 90%, rgba(255,255,255,0.95) 100%)',\n transform: 'rotate(8deg)',\n animation: `${d.variant} ${d.duration} linear ${d.delay} infinite`,\n transformOrigin: 'top',\n }} />\n ))}\n </div>\n );\n}\n\nfunction SnowEffect() {\n const variants = ['wx-snow-a', 'wx-snow-b', 'wx-snow-c'];\n const flakes = Array.from({ length: 16 }).map((_, i) => ({\n left: `${(i * 100 / 16 + (i * 13) % 5) % 100}%`,\n delay: `${(i * 0.43) % 5}s`,\n duration: `${4.5 + (i % 5)}s`,\n size: 3 + (i % 4) * 1.4,\n opacity: 0.65 + ((i * 7) % 4) * 0.08,\n variant: variants[i % variants.length],\n }));\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n {flakes.map((f, i) => (\n <div key={i} className=\"absolute rounded-full bg-white\"\n style={{\n left: f.left, top: '-12px',\n width: f.size, height: f.size,\n opacity: f.opacity,\n boxShadow: '0 0 4px rgba(255,255,255,0.65)',\n animation: `${f.variant} ${f.duration} linear ${f.delay} infinite`,\n }} />\n ))}\n </div>\n );\n}\n\nfunction ThunderEffect() {\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n <RainEffect heavy />\n {/* Sharp double-flash overlay */}\n <div className=\"absolute inset-0 bg-white\" style={{ animation: 'wx-flash 6s ease-out infinite' }} />\n {/* Lightning bolt — visible only during the flash peaks */}\n <div className=\"absolute inset-y-0 right-1/3 flex items-center justify-center pointer-events-none\"\n style={{ animation: 'wx-bolt 6s ease-out infinite' }}>\n <svg viewBox=\"0 0 18 60\" className=\"h-4/5\"\n style={{ filter: 'drop-shadow(0 0 6px rgba(255, 240, 150, 0.95)) drop-shadow(0 0 14px rgba(255, 220, 90, 0.7))' }}>\n <path d=\"M11 0 L2 28 L8 30 L4 60 L16 24 L9 22 Z\"\n fill=\"rgba(255, 250, 200, 0.98)\"\n stroke=\"rgba(255, 255, 255, 0.9)\" strokeWidth={0.3} />\n </svg>\n </div>\n </div>\n );\n}\n\nfunction FogEffect() {\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n {Array.from({ length: 4 }).map((_, i) => (\n <div key={i} className=\"absolute left-0 right-0\"\n style={{\n top: `${10 + i * 22}%`,\n height: '14px',\n background: 'linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.55) 50%, rgba(255,255,255,0) 100%)',\n filter: 'blur(2px)',\n animation: `wx-fog-drift ${10 + i * 3}s ease-in-out ${i * 0.7}s infinite alternate`,\n }} />\n ))}\n </div>\n );\n}\n\nfunction WeatherEffect({ code, isDay }: { code: number; isDay: boolean }) {\n if (code === 0 || code === 1) return isDay ? <SunEffect /> : <NightStarsEffect />;\n if (code === 2) return (\n <>\n {isDay ? <SunEffect /> : <NightStarsEffect />}\n <CloudsEffect tone={isDay ? 'light' : 'dark'} />\n </>\n );\n if (code === 3) return <CloudsEffect tone={isDay ? 'light' : 'dark'} />;\n if (code === 45 || code === 48) return <FogEffect />;\n if ([51, 53, 61, 80, 81].includes(code)) return <RainEffect />;\n if ([55, 63, 65, 82].includes(code)) return <RainEffect heavy />;\n if ([71, 73, 75].includes(code)) return <SnowEffect />;\n if ([95, 96, 99].includes(code)) return <ThunderEffect />;\n return null;\n}\n\nexport default function Weather() {\n const [city, setCity] = useState(loadCity);\n const [appearance, setAppearance] = useState(() => loadAppearance(SETTINGS_KEY));\n const [data, setData] = useState<CityWeather | null>(null);\n const [loading, setLoading] = useState(true);\n const [, setTick] = useState(0);\n useEffect(() => { const t = setInterval(() => setTick(n => n + 1), 60000); return () => clearInterval(t); }, []);\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [configCity, setConfigCity] = useState(city);\n const [configAppearance, setConfigAppearance] = useState<WidgetAppearance>(appearance);\n\n const { prefs: shellPrefs, save: saveShellPrefs } = useShellPrefs();\n const prefs: WeatherPrefs = { ...DEFAULT_PREFS, ...(shellPrefs.weather_prefs as WeatherPrefs | undefined ?? {}) };\n const [configPrefs, setConfigPrefs] = useState<WeatherPrefs>(prefs);\n\n useWidgetSettings(useCallback(() => {\n setConfigCity(city);\n setConfigAppearance({ ...appearance });\n setConfigPrefs({ ...prefs });\n setSettingsOpen(true);\n }, [city, appearance, prefs]));\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n fetchCityWeather(city).then(w => {\n if (cancelled) return;\n setData(w);\n setLoading(false);\n });\n return () => { cancelled = true; };\n }, [city]);\n\n const saveSettings = () => {\n setCity(configCity);\n setAppearance(configAppearance);\n saveShellPrefs({ weather_prefs: configPrefs });\n localStorage.setItem(STORAGE_KEY, configCity);\n localStorage.setItem(SETTINGS_KEY, JSON.stringify(configAppearance));\n setSettingsOpen(false);\n };\n\n const t = (c: number) => prefs.useFahrenheit ? `${toF(c)}°F` : `${c}°`;\n\n // Half-height — tile is now ~110 px tall. Effect keyframes are tuned for\n // this so drops/flakes traverse the full height before recycling.\n const TILE_HEIGHT = 110;\n\n if (loading && !data) {\n return <div className=\"flex items-center justify-center h-full bg-gradient-to-b from-sky-400 to-blue-500 rounded-lg text-white/80 text-xs\" style={{ minHeight: TILE_HEIGHT }}>Loading…</div>;\n }\n if (!data) {\n return <div className=\"flex items-center justify-center h-full bg-slate-700 rounded-lg text-white/80 text-xs\" style={{ minHeight: TILE_HEIGHT }}>Couldn't load weather</div>;\n }\n\n const [condition, emoji, gradient] = getCondition(data.code, data.isDay);\n\n return (\n <>\n <style>{WX_KEYFRAMES}</style>\n <div className=\"rounded-lg overflow-hidden\"\n style={{\n backgroundColor: `rgba(15, 23, 42, ${appearance.activeOpacity / 100})`,\n backdropFilter: appearance.activeBlur > 0 ? `blur(${appearance.activeBlur}px)` : undefined,\n }}>\n <div className={`relative rounded-lg overflow-hidden text-white bg-gradient-to-br ${gradient}`} style={{ height: TILE_HEIGHT }}>\n {/* Animated effects */}\n <WeatherEffect code={data.code} isDay={data.isDay} />\n\n {/* Compact two-row content */}\n <div className=\"relative z-10 px-3 py-2.5 flex flex-col h-full justify-between\">\n {/* Top: city + time | temp */}\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-base font-semibold leading-tight truncate drop-shadow-sm\">{data.city}</div>\n {prefs.showLocalTime && (\n <div className=\"text-[10px] opacity-90 leading-tight tabular-nums drop-shadow-sm\">\n {getTimeInTz(data.timezone, prefs.use24Hour)}\n </div>\n )}\n </div>\n <div className=\"text-3xl font-extralight leading-none tracking-tight tabular-nums shrink-0 drop-shadow-sm\">\n {t(data.temp)}\n </div>\n </div>\n\n {/* Bottom: condition | H/L */}\n <div className=\"flex items-end justify-between gap-2\">\n <div className=\"flex items-center gap-1.5 min-w-0\">\n <span className=\"text-lg leading-none drop-shadow-sm\">{emoji}</span>\n <span className=\"text-[11px] font-medium drop-shadow-sm truncate\">{condition}</span>\n </div>\n <span className=\"text-[10px] opacity-90 tabular-nums drop-shadow-sm shrink-0\">H:{t(data.high)} L:{t(data.low)}</span>\n </div>\n </div>\n </div>\n </div>\n\n <WidgetSettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} title=\"Weather Settings\"\n appearance={configAppearance} onAppearanceChange={setConfigAppearance} onSave={saveSettings}>\n <div className=\"space-y-3\">\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Display</h3>\n <div className=\"flex items-center gap-3 mb-2\">\n <span className=\"text-sm text-gray-600 w-24\">Temperature</span>\n <div className=\"flex gap-1\">\n {([{ key: false, label: '°C' }, { key: true, label: '°F' }] as const).map(o => (\n <button key={String(o.key)} onClick={() => setConfigPrefs(p => ({ ...p, useFahrenheit: o.key }))}\n className={`px-3 py-1 text-xs font-medium rounded-lg border transition-colors ${configPrefs.useFahrenheit === o.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'}`}>\n {o.label}\n </button>\n ))}\n </div>\n </div>\n <div className=\"flex items-center gap-3 mb-2\">\n <span className=\"text-sm text-gray-600 w-24\">Time Format</span>\n <div className=\"flex gap-1\">\n {([{ key: false, label: 'AM/PM' }, { key: true, label: '24H' }] as const).map(o => (\n <button key={String(o.key)} onClick={() => setConfigPrefs(p => ({ ...p, use24Hour: o.key }))}\n className={`px-3 py-1 text-xs font-medium rounded-lg border transition-colors ${configPrefs.use24Hour === o.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'}`}>\n {o.label}\n </button>\n ))}\n </div>\n </div>\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input type=\"checkbox\" checked={configPrefs.showLocalTime} onChange={e => setConfigPrefs(p => ({ ...p, showLocalTime: e.target.checked }))}\n className=\"rounded border-gray-300 text-blue-600 h-3.5 w-3.5\" />\n <span className=\"text-sm text-gray-600\">Show local time</span>\n </label>\n </div>\n </div>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">City</h3>\n <select value={configCity} onChange={e => setConfigCity(e.target.value)}\n className=\"w-full bg-gray-50 border border-gray-200 rounded px-2 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500\">\n {Object.keys(AVAILABLE_CITIES).map(name => (\n <option key={name} value={name}>{name}</option>\n ))}\n </select>\n <p className=\"mt-1 text-[10px] text-gray-400\">Auto-detected from your timezone; change if needed.</p>\n </div>\n </WidgetSettingsModal>\n </>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/apps/Weather.tsx"],"names":["parts","h","m","t"],"mappings":"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","file":"Weather-LZQGVDJL.js","sourcesContent":["import { useState, useEffect, useCallback } from 'react';\nimport { useWidgetSettings } from '../shell/Modal';\nimport WidgetSettingsModal, { loadAppearance, type WidgetAppearance } from '../shell/WidgetSettingsModal';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport { AVAILABLE_CITIES, fetchCityWeather, getCondition, toFahrenheit, type CityWeather } from './_weatherData';\n\nconst STORAGE_KEY = 'weather_city';\nconst LEGACY_KEY = 'weather_cities';\nconst SETTINGS_KEY = 'weather_appearance';\n\ninterface WeatherPrefs { useFahrenheit: boolean; showLocalTime: boolean; use24Hour: boolean }\nconst DEFAULT_PREFS: WeatherPrefs = { useFahrenheit: false, showLocalTime: true, use24Hour: false };\n\nfunction detectLocalCity(): string {\n try {\n const userTz = Intl.DateTimeFormat().resolvedOptions().timeZone;\n for (const [name, info] of Object.entries(AVAILABLE_CITIES)) {\n if (info.tz === userTz) return name;\n }\n } catch {}\n return 'London';\n}\n\nfunction loadCity(): string {\n const v = typeof localStorage !== 'undefined' ? localStorage.getItem(STORAGE_KEY) : null;\n if (v && AVAILABLE_CITIES[v]) return v;\n try {\n const arr = JSON.parse(localStorage.getItem(LEGACY_KEY) || '');\n if (Array.isArray(arr) && arr[0] && AVAILABLE_CITIES[arr[0]]) {\n localStorage.setItem(STORAGE_KEY, arr[0]);\n return arr[0];\n }\n } catch {}\n return detectLocalCity();\n}\n\nconst toF = toFahrenheit;\n\nfunction getTimeInTz(timezone: string, use24Hour = false): string {\n try {\n if (use24Hour) {\n const parts = new Intl.DateTimeFormat('en-US', { timeZone: timezone, hour: 'numeric', minute: '2-digit', hour12: false }).formatToParts(new Date());\n const h = parseInt(parts.find(p => p.type === 'hour')?.value || '0');\n const m = parseInt(parts.find(p => p.type === 'minute')?.value || '0');\n return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`;\n }\n const parts = new Intl.DateTimeFormat('en-US', { timeZone: timezone, hour: 'numeric', minute: '2-digit', hour12: true }).formatToParts(new Date());\n const h = parseInt(parts.find(p => p.type === 'hour')?.value || '12');\n const m = parseInt(parts.find(p => p.type === 'minute')?.value || '0');\n const period = parts.find(p => p.type === 'dayPeriod')?.value || '';\n return `${h}:${String(m).padStart(2, '0')} ${period}`;\n } catch { return ''; }\n}\n\n/**\n * Effect keyframes — tuned for a ~110 px-tall card so drops/flakes fall\n * across the full height before recycling. Multiple snow/rain variants\n * give the impression of independent particles instead of a hypnotic\n * lock-step pattern.\n */\nconst WX_KEYFRAMES = `\n@keyframes wx-rain-a { 0% { transform: translate(0,-20px); opacity: 0; } 10% { opacity: 0.95; } 100% { transform: translate(8px,140px); opacity: 0; } }\n@keyframes wx-rain-b { 0% { transform: translate(0,-20px); opacity: 0; } 12% { opacity: 0.85; } 100% { transform: translate(12px,140px); opacity: 0; } }\n@keyframes wx-rain-c { 0% { transform: translate(0,-20px); opacity: 0; } 10% { opacity: 1; } 100% { transform: translate(5px,140px); opacity: 0; } }\n@keyframes wx-snow-a { 0% { transform: translate(0,-12px) rotate(0deg); opacity: 0; } 10% { opacity: 0.9; } 50% { transform: translate(10px,55px) rotate(180deg); } 100% { transform: translate(-4px,140px) rotate(360deg); opacity: 0; } }\n@keyframes wx-snow-b { 0% { transform: translate(0,-12px) rotate(0deg); opacity: 0; } 10% { opacity: 0.85; } 50% { transform: translate(-12px,55px) rotate(-180deg); } 100% { transform: translate(6px,140px) rotate(-360deg); opacity: 0; } }\n@keyframes wx-snow-c { 0% { transform: translate(0,-12px); opacity: 0; } 10% { opacity: 0.7; } 100% { transform: translate(2px,140px); opacity: 0; } }\n@keyframes wx-drift-cloud { 0% { transform: translateX(-40%); } 100% { transform: translateX(140%); } }\n@keyframes wx-twinkle { 0%, 100% { opacity: 0.25; transform: scale(1); } 50% { opacity: 1; transform: scale(1.6); } }\n@keyframes wx-flash { 0%, 86%, 100% { opacity: 0; } 87% { opacity: 0.95; } 88% { opacity: 0.15; } 89% { opacity: 0.85; } 90% { opacity: 0; } }\n@keyframes wx-bolt { 0%, 86%, 90%, 100% { opacity: 0; } 87% { opacity: 1; } 89% { opacity: 0.85; } }\n@keyframes wx-sun-pulse { 0%, 100% { transform: scale(1); opacity: 0.65; } 50% { transform: scale(1.12); opacity: 0.95; } }\n@keyframes wx-sun-rays { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }\n@keyframes wx-fog-drift { 0% { transform: translateX(-25%); opacity: 0.3; } 50% { opacity: 0.65; } 100% { transform: translateX(25%); opacity: 0.3; } }\n@keyframes wx-shooting-star { 0%, 95% { opacity: 0; transform: translate(0,0) scale(0); } 96% { opacity: 1; transform: translate(0,0) scale(1); } 100% { opacity: 0; transform: translate(40px,30px) scale(1); } }\n`;\n\nfunction SunEffect() {\n // Defined yellow-orange disc with halo + slowly-rotating ray sprite.\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n <div className=\"absolute -top-5 -right-5 w-24 h-24\" style={{ animation: 'wx-sun-rays 70s linear infinite' }}>\n <svg viewBox=\"0 0 100 100\" className=\"w-full h-full\">\n {Array.from({ length: 12 }).map((_, i) => (\n <rect key={i} x={49} y={3} width={2} height={14} rx={1}\n fill=\"rgba(255, 232, 130, 0.55)\"\n transform={`rotate(${i * 30} 50 50)`} />\n ))}\n </svg>\n </div>\n <div className=\"absolute top-1 right-1 w-10 h-10 rounded-full\"\n style={{\n background: 'radial-gradient(circle at 35% 35%, #fff8cc 0%, #ffd84a 55%, #ff9e2a 100%)',\n boxShadow: '0 0 18px 5px rgba(255, 200, 80, 0.55)',\n animation: 'wx-sun-pulse 4.5s ease-in-out infinite',\n }} />\n </div>\n );\n}\n\nfunction NightStarsEffect() {\n // Crescent moon (outer warm circle + offset dark circle to carve out the\n // bite) and a sparse scatter of stars twinkling at independent rates.\n // One slow-cycle shooting star adds a moment of motion without\n // distracting.\n const stars = Array.from({ length: 16 }).map((_, i) => ({\n left: `${(i * 53 + 11) % 95}%`,\n top: `${(i * 37 + 9) % 78}%`,\n size: 1 + ((i * 13) % 3),\n delay: `${(i * 0.41) % 4}s`,\n duration: `${2.5 + ((i * 7) % 5) * 0.6}s`,\n }));\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n {/* Crescent moon */}\n <div className=\"absolute top-1 right-1\">\n <svg viewBox=\"0 0 40 40\" className=\"w-9 h-9\" style={{ filter: 'drop-shadow(0 0 6px rgba(255,250,220,0.4))' }}>\n <defs>\n <radialGradient id=\"wx-moon-grad\" cx=\"35%\" cy=\"35%\">\n <stop offset=\"0\" stopColor=\"#fffae0\" />\n <stop offset=\"1\" stopColor=\"#d4c98a\" />\n </radialGradient>\n </defs>\n <circle cx={20} cy={20} r={13} fill=\"url(#wx-moon-grad)\" />\n <circle cx={26} cy={16} r={11} fill=\"rgba(15,23,42,1)\" />\n </svg>\n </div>\n {stars.map((s, i) => (\n <div key={i} className=\"absolute rounded-full bg-white\"\n style={{\n left: s.left, top: s.top, width: s.size, height: s.size,\n animation: `wx-twinkle ${s.duration} ease-in-out ${s.delay} infinite`,\n }} />\n ))}\n {/* Shooting star — appears once every ~12s */}\n <div className=\"absolute\" style={{ left: '15%', top: '20%', animation: 'wx-shooting-star 12s ease-out infinite' }}>\n <div className=\"w-12 h-px\"\n style={{ background: 'linear-gradient(to right, transparent, rgba(255,255,255,0.95))', boxShadow: '0 0 4px rgba(255,255,255,0.8)' }} />\n </div>\n </div>\n );\n}\n\nfunction CloudsEffect({ tone = 'light' as 'light' | 'dark' }) {\n const fill = tone === 'light' ? 'rgba(255,255,255,0.78)' : 'rgba(220,228,240,0.45)';\n const Cloud = ({ scale = 1 }) => (\n <svg viewBox=\"0 0 120 50\" className=\"w-32 h-12\" style={{ transform: `scale(${scale})`, filter: 'blur(0.6px)' }}>\n <ellipse cx={28} cy={36} rx={18} ry={11} fill={fill} />\n <ellipse cx={50} cy={28} rx={22} ry={15} fill={fill} />\n <ellipse cx={75} cy={32} rx={20} ry={12} fill={fill} />\n <ellipse cx={95} cy={38} rx={15} ry={9} fill={fill} />\n </svg>\n );\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n <div className=\"absolute\" style={{ top: '8%', animation: 'wx-drift-cloud 42s linear infinite' }}><Cloud scale={0.9} /></div>\n <div className=\"absolute\" style={{ top: '40%', animation: 'wx-drift-cloud 60s linear -22s infinite', opacity: 0.85 }}><Cloud scale={1.25} /></div>\n <div className=\"absolute\" style={{ top: '68%', animation: 'wx-drift-cloud 78s linear -45s infinite', opacity: 0.7 }}><Cloud scale={0.75} /></div>\n </div>\n );\n}\n\nfunction RainEffect({ heavy = false }: { heavy?: boolean }) {\n const count = heavy ? 26 : 16;\n const variants = ['wx-rain-a', 'wx-rain-b', 'wx-rain-c'];\n const drops = Array.from({ length: count }).map((_, i) => ({\n left: `${(i * 100 / count + (i * 11) % 7) % 100}%`,\n delay: `${(i * 0.087) % 1.3}s`,\n height: `${12 + (i % 4) * 5}px`,\n duration: `${0.7 + (i % 3) * 0.18}s`,\n variant: variants[i % variants.length],\n }));\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n {drops.map((d, i) => (\n <div key={i} className=\"absolute\"\n style={{\n left: d.left, top: '-20px',\n width: '1px', height: d.height,\n background: 'linear-gradient(180deg, rgba(180,210,255,0) 0%, rgba(220,235,255,0.85) 90%, rgba(255,255,255,0.95) 100%)',\n transform: 'rotate(8deg)',\n animation: `${d.variant} ${d.duration} linear ${d.delay} infinite`,\n transformOrigin: 'top',\n }} />\n ))}\n </div>\n );\n}\n\nfunction SnowEffect() {\n const variants = ['wx-snow-a', 'wx-snow-b', 'wx-snow-c'];\n const flakes = Array.from({ length: 16 }).map((_, i) => ({\n left: `${(i * 100 / 16 + (i * 13) % 5) % 100}%`,\n delay: `${(i * 0.43) % 5}s`,\n duration: `${4.5 + (i % 5)}s`,\n size: 3 + (i % 4) * 1.4,\n opacity: 0.65 + ((i * 7) % 4) * 0.08,\n variant: variants[i % variants.length],\n }));\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n {flakes.map((f, i) => (\n <div key={i} className=\"absolute rounded-full bg-white\"\n style={{\n left: f.left, top: '-12px',\n width: f.size, height: f.size,\n opacity: f.opacity,\n boxShadow: '0 0 4px rgba(255,255,255,0.65)',\n animation: `${f.variant} ${f.duration} linear ${f.delay} infinite`,\n }} />\n ))}\n </div>\n );\n}\n\nfunction ThunderEffect() {\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n <RainEffect heavy />\n {/* Sharp double-flash overlay */}\n <div className=\"absolute inset-0 bg-white\" style={{ animation: 'wx-flash 6s ease-out infinite' }} />\n {/* Lightning bolt — visible only during the flash peaks */}\n <div className=\"absolute inset-y-0 right-1/3 flex items-center justify-center pointer-events-none\"\n style={{ animation: 'wx-bolt 6s ease-out infinite' }}>\n <svg viewBox=\"0 0 18 60\" className=\"h-4/5\"\n style={{ filter: 'drop-shadow(0 0 6px rgba(255, 240, 150, 0.95)) drop-shadow(0 0 14px rgba(255, 220, 90, 0.7))' }}>\n <path d=\"M11 0 L2 28 L8 30 L4 60 L16 24 L9 22 Z\"\n fill=\"rgba(255, 250, 200, 0.98)\"\n stroke=\"rgba(255, 255, 255, 0.9)\" strokeWidth={0.3} />\n </svg>\n </div>\n </div>\n );\n}\n\nfunction FogEffect() {\n return (\n <div className=\"absolute inset-0 overflow-hidden pointer-events-none\">\n {Array.from({ length: 4 }).map((_, i) => (\n <div key={i} className=\"absolute left-0 right-0\"\n style={{\n top: `${10 + i * 22}%`,\n height: '14px',\n background: 'linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.55) 50%, rgba(255,255,255,0) 100%)',\n filter: 'blur(2px)',\n animation: `wx-fog-drift ${10 + i * 3}s ease-in-out ${i * 0.7}s infinite alternate`,\n }} />\n ))}\n </div>\n );\n}\n\nfunction WeatherEffect({ code, isDay }: { code: number; isDay: boolean }) {\n if (code === 0 || code === 1) return isDay ? <SunEffect /> : <NightStarsEffect />;\n if (code === 2) return (\n <>\n {isDay ? <SunEffect /> : <NightStarsEffect />}\n <CloudsEffect tone={isDay ? 'light' : 'dark'} />\n </>\n );\n if (code === 3) return <CloudsEffect tone={isDay ? 'light' : 'dark'} />;\n if (code === 45 || code === 48) return <FogEffect />;\n if ([51, 53, 61, 80, 81].includes(code)) return <RainEffect />;\n if ([55, 63, 65, 82].includes(code)) return <RainEffect heavy />;\n if ([71, 73, 75].includes(code)) return <SnowEffect />;\n if ([95, 96, 99].includes(code)) return <ThunderEffect />;\n return null;\n}\n\nexport default function Weather() {\n const [city, setCity] = useState(loadCity);\n const [appearance, setAppearance] = useState(() => loadAppearance(SETTINGS_KEY));\n const [data, setData] = useState<CityWeather | null>(null);\n const [loading, setLoading] = useState(true);\n const [, setTick] = useState(0);\n useEffect(() => { const t = setInterval(() => setTick(n => n + 1), 60000); return () => clearInterval(t); }, []);\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [configCity, setConfigCity] = useState(city);\n const [configAppearance, setConfigAppearance] = useState<WidgetAppearance>(appearance);\n\n const { prefs: shellPrefs, save: saveShellPrefs } = useShellPrefs();\n const prefs: WeatherPrefs = { ...DEFAULT_PREFS, ...(shellPrefs.weather_prefs as WeatherPrefs | undefined ?? {}) };\n const [configPrefs, setConfigPrefs] = useState<WeatherPrefs>(prefs);\n\n useWidgetSettings(useCallback(() => {\n setConfigCity(city);\n setConfigAppearance({ ...appearance });\n setConfigPrefs({ ...prefs });\n setSettingsOpen(true);\n }, [city, appearance, prefs]));\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n fetchCityWeather(city).then(w => {\n if (cancelled) return;\n setData(w);\n setLoading(false);\n });\n return () => { cancelled = true; };\n }, [city]);\n\n const saveSettings = () => {\n setCity(configCity);\n setAppearance(configAppearance);\n saveShellPrefs({ weather_prefs: configPrefs });\n localStorage.setItem(STORAGE_KEY, configCity);\n localStorage.setItem(SETTINGS_KEY, JSON.stringify(configAppearance));\n setSettingsOpen(false);\n };\n\n const t = (c: number) => prefs.useFahrenheit ? `${toF(c)}°F` : `${c}°`;\n\n // Half-height — tile is now ~110 px tall. Effect keyframes are tuned for\n // this so drops/flakes traverse the full height before recycling.\n const TILE_HEIGHT = 110;\n\n if (loading && !data) {\n return <div className=\"flex items-center justify-center h-full bg-gradient-to-b from-sky-400 to-blue-500 rounded-lg text-white/80 text-xs\" style={{ minHeight: TILE_HEIGHT }}>Loading…</div>;\n }\n if (!data) {\n return <div className=\"flex items-center justify-center h-full bg-slate-700 rounded-lg text-white/80 text-xs\" style={{ minHeight: TILE_HEIGHT }}>Couldn't load weather</div>;\n }\n\n const [condition, emoji, gradient] = getCondition(data.code, data.isDay);\n\n return (\n <>\n <style>{WX_KEYFRAMES}</style>\n <div className=\"rounded-lg overflow-hidden\"\n style={{\n backgroundColor: `rgba(15, 23, 42, ${appearance.activeOpacity / 100})`,\n backdropFilter: appearance.activeBlur > 0 ? `blur(${appearance.activeBlur}px)` : undefined,\n }}>\n <div className={`relative rounded-lg overflow-hidden text-white bg-gradient-to-br ${gradient}`} style={{ height: TILE_HEIGHT }}>\n {/* Animated effects */}\n <WeatherEffect code={data.code} isDay={data.isDay} />\n\n {/* Compact two-row content */}\n <div className=\"relative z-10 px-3 py-2.5 flex flex-col h-full justify-between\">\n {/* Top: city + time | temp */}\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"min-w-0 flex-1\">\n <div className=\"text-base font-semibold leading-tight truncate drop-shadow-sm\">{data.city}</div>\n {prefs.showLocalTime && (\n <div className=\"text-[10px] opacity-90 leading-tight tabular-nums drop-shadow-sm\">\n {getTimeInTz(data.timezone, prefs.use24Hour)}\n </div>\n )}\n </div>\n <div className=\"text-3xl font-extralight leading-none tracking-tight tabular-nums shrink-0 drop-shadow-sm\">\n {t(data.temp)}\n </div>\n </div>\n\n {/* Bottom: condition | H/L */}\n <div className=\"flex items-end justify-between gap-2\">\n <div className=\"flex items-center gap-1.5 min-w-0\">\n <span className=\"text-lg leading-none drop-shadow-sm\">{emoji}</span>\n <span className=\"text-[11px] font-medium drop-shadow-sm truncate\">{condition}</span>\n </div>\n <span className=\"text-[10px] opacity-90 tabular-nums drop-shadow-sm shrink-0\">H:{t(data.high)} L:{t(data.low)}</span>\n </div>\n </div>\n </div>\n </div>\n\n <WidgetSettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} title=\"Weather Settings\"\n appearance={configAppearance} onAppearanceChange={setConfigAppearance} onSave={saveSettings}>\n <div className=\"space-y-3\">\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Display</h3>\n <div className=\"flex items-center gap-3 mb-2\">\n <span className=\"text-sm text-gray-600 w-24\">Temperature</span>\n <div className=\"flex gap-1\">\n {([{ key: false, label: '°C' }, { key: true, label: '°F' }] as const).map(o => (\n <button key={String(o.key)} onClick={() => setConfigPrefs(p => ({ ...p, useFahrenheit: o.key }))}\n className={`px-3 py-1 text-xs font-medium rounded-lg border transition-colors ${configPrefs.useFahrenheit === o.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'}`}>\n {o.label}\n </button>\n ))}\n </div>\n </div>\n <div className=\"flex items-center gap-3 mb-2\">\n <span className=\"text-sm text-gray-600 w-24\">Time Format</span>\n <div className=\"flex gap-1\">\n {([{ key: false, label: 'AM/PM' }, { key: true, label: '24H' }] as const).map(o => (\n <button key={String(o.key)} onClick={() => setConfigPrefs(p => ({ ...p, use24Hour: o.key }))}\n className={`px-3 py-1 text-xs font-medium rounded-lg border transition-colors ${configPrefs.use24Hour === o.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'}`}>\n {o.label}\n </button>\n ))}\n </div>\n </div>\n <label className=\"flex items-center gap-2 cursor-pointer\">\n <input type=\"checkbox\" checked={configPrefs.showLocalTime} onChange={e => setConfigPrefs(p => ({ ...p, showLocalTime: e.target.checked }))}\n className=\"rounded border-gray-300 text-blue-600 h-3.5 w-3.5\" />\n <span className=\"text-sm text-gray-600\">Show local time</span>\n </label>\n </div>\n </div>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">City</h3>\n <select value={configCity} onChange={e => setConfigCity(e.target.value)}\n className=\"w-full bg-gray-50 border border-gray-200 rounded px-2 py-1.5 text-sm focus:outline-none focus:ring-1 focus:ring-blue-500\">\n {Object.keys(AVAILABLE_CITIES).map(name => (\n <option key={name} value={name}>{name}</option>\n ))}\n </select>\n <p className=\"mt-1 text-[10px] text-gray-400\">Auto-detected from your timezone; change if needed.</p>\n </div>\n </WidgetSettingsModal>\n </>\n );\n}\n"]}
@@ -1,15 +1,15 @@
1
1
  import { AVAILABLE_CITIES, fetchCityWeather, getCondition, toFahrenheit } from './chunk-7CCHEEYC.js';
2
- import { loadAppearance, WidgetSettingsModal } from './chunk-MQPX6ERJ.js';
3
- import { useWidgetSettings } from './chunk-ZKHD4J73.js';
2
+ import { loadAppearance, WidgetSettingsModal } from './chunk-E7TB6WD2.js';
3
+ import { useWidgetSettings } from './chunk-ICTRCKUE.js';
4
4
  import './chunk-GA35NEND.js';
5
- import { useShellPrefs } from './chunk-TQURTLK2.js';
6
- import './chunk-LQTVTOSY.js';
7
- import './chunk-E3TWIN7Z.js';
8
- import './chunk-XH3ELPQZ.js';
9
- import './chunk-D276EMXS.js';
10
- import './chunk-7IN7YZAL.js';
11
- import './chunk-IRWSRJ4K.js';
5
+ import { useShellPrefs } from './chunk-HUBJAUGG.js';
6
+ import './chunk-RT6DSB5Y.js';
7
+ import './chunk-JOPU6WPY.js';
8
+ import './chunk-I2TAAJHS.js';
9
+ import './chunk-6XJEJWNJ.js';
10
+ import './chunk-YE6GUDGP.js';
12
11
  import './chunk-IPXN646P.js';
12
+ import './chunk-IRWSRJ4K.js';
13
13
  import { useState, useEffect, useCallback } from 'react';
14
14
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
15
15
 
@@ -198,5 +198,5 @@ function WorldClock() {
198
198
  }
199
199
 
200
200
  export { WorldClock as default };
201
- //# sourceMappingURL=WorldClock-HUC6D3AD.js.map
202
- //# sourceMappingURL=WorldClock-HUC6D3AD.js.map
201
+ //# sourceMappingURL=WorldClock-XPD7WOZT.js.map
202
+ //# sourceMappingURL=WorldClock-XPD7WOZT.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/apps/WorldClock.tsx"],"names":[],"mappings":"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","file":"WorldClock-HUC6D3AD.js","sourcesContent":["import { useState, useEffect, useCallback } from 'react';\nimport { useWidgetSettings } from '../shell/Modal';\nimport WidgetSettingsModal, { loadAppearance, type WidgetAppearance } from '../shell/WidgetSettingsModal';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport { AVAILABLE_CITIES, fetchCityWeather, getCondition, toFahrenheit, type CityWeather } from './_weatherData';\n\nconst SETTINGS_KEY = 'world_clock_appearance';\nconst DEFAULT_CITIES = ['London', 'Shanghai', 'New York'];\n\ninterface WeatherPrefs { useFahrenheit: boolean }\n\n/**\n * Resolve the local time for the supplied IANA timezone into a digital\n * `12:34` + `AM` / `PM` pair. Used by the World Clock rows.\n */\nfunction digitalTime(tz: string, now: Date): { time: string; ampm: string } {\n try {\n const parts = new Intl.DateTimeFormat('en-US', {\n timeZone: tz, hour: 'numeric', minute: '2-digit', hour12: true,\n }).formatToParts(now);\n const h = parts.find(p => p.type === 'hour')?.value || '12';\n const m = parts.find(p => p.type === 'minute')?.value || '00';\n const ampm = (parts.find(p => p.type === 'dayPeriod')?.value || '').toUpperCase();\n return { time: `${h}:${m}`, ampm };\n } catch { return { time: '', ampm: '' }; }\n}\n\n/**\n * World Clock widget — multi-city list. Each row pairs a tiny analogue\n * clock (minimal-style: ring, four cardinal dots, two hands) with the\n * city's current weather. The weather emoji doubles as a day/night cue\n * (☀ vs 🌙 for clear, the same icons for everything else). Reads the\n * shared Open-Meteo cache so it doesn't re-hit the API when the Weather\n * widget already has the data.\n */\nexport default function WorldClock() {\n const { prefs, save } = useShellPrefs();\n const [appearance, setAppearance] = useState(() => loadAppearance(SETTINGS_KEY));\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [configCities, setConfigCities] = useState<string[]>([]);\n const [configAppearance, setConfigAppearance] = useState<WidgetAppearance>(appearance);\n\n const wxPrefs: WeatherPrefs = {\n useFahrenheit: !!(prefs.weather_prefs as WeatherPrefs | undefined)?.useFahrenheit,\n };\n const [configWxPrefs, setConfigWxPrefs] = useState(wxPrefs);\n\n // Tick once every 30 s so the analogue minute-hands drift smoothly. We\n // don't show seconds so faster polling is wasted re-renders.\n const [now, setNow] = useState(() => new Date());\n useEffect(() => {\n const t = setInterval(() => setNow(new Date()), 30 * 1000);\n return () => clearInterval(t);\n }, []);\n\n // Resolve the saved city list and migrate the legacy IANA-timezone\n // format (`Europe/London`) over to the new city-name format\n // (`London`).\n const tzToCity: Record<string, string> = Object.fromEntries(\n Object.entries(AVAILABLE_CITIES).map(([city, info]) => [info.tz, city])\n );\n const rawClocks = prefs.world_clocks as string[] | undefined;\n const cities: string[] = (() => {\n if (!Array.isArray(rawClocks) || rawClocks.length === 0) return DEFAULT_CITIES;\n const out: string[] = [];\n for (const v of rawClocks) {\n const asCity = AVAILABLE_CITIES[v] ? v : tzToCity[v];\n if (asCity && !out.includes(asCity)) out.push(asCity);\n }\n return out.length ? out : DEFAULT_CITIES;\n })();\n\n const [data, setData] = useState<Record<string, CityWeather>>({});\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n (async () => {\n const next: Record<string, CityWeather> = {};\n await Promise.all(cities.map(async c => {\n const w = await fetchCityWeather(c);\n if (w) next[c] = w;\n }));\n if (!cancelled) { setData(next); setLoading(false); }\n })();\n return () => { cancelled = true; };\n }, [cities.join(',')]);\n\n useWidgetSettings(useCallback(() => {\n setConfigCities([...cities]);\n setConfigAppearance({ ...appearance });\n setConfigWxPrefs({ ...wxPrefs });\n setSettingsOpen(true);\n }, [cities.join(','), appearance, wxPrefs.useFahrenheit]));\n\n const saveSettings = () => {\n if (configCities.length === 0) return;\n save({\n world_clocks: configCities,\n weather_prefs: { ...(prefs.weather_prefs as object | undefined ?? {}), useFahrenheit: configWxPrefs.useFahrenheit },\n });\n setAppearance(configAppearance);\n localStorage.setItem(SETTINGS_KEY, JSON.stringify(configAppearance));\n setSettingsOpen(false);\n };\n\n const formatTemp = (c: number) => wxPrefs.useFahrenheit ? `${toFahrenheit(c)}°` : `${c}°`;\n\n return (\n <>\n {/* Theme-aware panel — same colour as the taskbar so all dashboard\n * widgets read as a coordinated set across light and dark themes.\n * Rows use `divide-y` rather than per-row border classes so the\n * last row never paints a stray separator line at the panel's\n * bottom edge. */}\n <div\n style={{\n backgroundColor: `rgb(var(--taskbar-bg-rgb, 243 244 246) / ${appearance.activeOpacity / 100})`,\n backdropFilter: appearance.activeBlur > 0 ? `blur(${appearance.activeBlur}px)` : undefined,\n }}>\n <div className=\"divide-y divide-gray-200\">\n {loading && cities.every(c => !data[c]) && (\n <div className=\"px-3 py-6 text-center text-xs text-gray-500\">Loading…</div>\n )}\n {cities.map((cityName) => {\n const w = data[cityName];\n const tz = AVAILABLE_CITIES[cityName]?.tz ?? 'UTC';\n const { time, ampm } = digitalTime(tz, now);\n if (!w) {\n return (\n <div key={cityName} className=\"px-4 py-3\">\n <div className=\"flex items-baseline justify-between gap-2\">\n <span className=\"text-[15px] font-semibold tracking-tight text-gray-900 truncate\">{cityName}</span>\n <span className=\"tabular-nums text-[13px] font-medium text-gray-500\">{time}<span className=\"text-[9px] ml-0.5 opacity-70\">{ampm}</span></span>\n </div>\n <div className=\"text-[11px] text-gray-400 mt-1\">Loading weather…</div>\n </div>\n );\n }\n const [condition, emoji] = getCondition(w.code, w.isDay);\n return (\n <div key={cityName} className=\"px-4 py-3\">\n {/* Top — city name on the left, big temperature on the right. */}\n <div className=\"flex items-baseline justify-between gap-2\">\n <span className=\"text-[15px] font-semibold tracking-tight text-gray-900 truncate\">{cityName}</span>\n <span className=\"text-[26px] font-extralight leading-none tabular-nums tracking-tight text-gray-900 shrink-0\">{formatTemp(w.temp)}</span>\n </div>\n\n {/* Bottom — emoji · digital time · condition on the left;\n H/L on the right. */}\n <div className=\"flex items-center justify-between gap-2 mt-1.5 text-[11px]\">\n <div className=\"flex items-center gap-1.5 min-w-0 text-gray-500\">\n <span className=\"text-base leading-none shrink-0\">{emoji}</span>\n <span className=\"tabular-nums font-semibold text-gray-700 shrink-0\">\n {time}<span className=\"text-[9px] font-medium ml-0.5 opacity-70\">{ampm}</span>\n </span>\n <span className=\"text-gray-300 shrink-0\">·</span>\n <span className=\"truncate\">{condition}</span>\n </div>\n <span className=\"tabular-nums text-gray-500 shrink-0\">H:{formatTemp(w.high)} L:{formatTemp(w.low)}</span>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n\n <WidgetSettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} title=\"World Clock Settings\"\n appearance={configAppearance} onAppearanceChange={setConfigAppearance} onSave={saveSettings}>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Display</h3>\n <div className=\"flex items-center gap-3 mb-2\">\n <span className=\"text-sm text-gray-600 w-24\">Temperature</span>\n <div className=\"flex gap-1\">\n {([{ key: false, label: '°C' }, { key: true, label: '°F' }] as const).map(o => (\n <button key={String(o.key)} onClick={() => setConfigWxPrefs(p => ({ ...p, useFahrenheit: o.key }))}\n className={`px-3 py-1 text-xs font-medium rounded-lg border transition-colors ${configWxPrefs.useFahrenheit === o.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'}`}>\n {o.label}\n </button>\n ))}\n </div>\n </div>\n <p className=\"text-[10px] text-gray-400 mt-1\">Shared with the Weather widget.</p>\n </div>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Cities</h3>\n <div className=\"grid grid-cols-2 gap-1 max-h-56 overflow-y-auto\">\n {Object.keys(AVAILABLE_CITIES).map(name => (\n <label key={name} className=\"flex items-center gap-2 text-sm py-1 cursor-pointer hover:bg-gray-50 rounded px-2\">\n <input type=\"checkbox\" checked={configCities.includes(name)}\n onChange={() => setConfigCities(prev => prev.includes(name) ? prev.filter(c => c !== name) : [...prev, name])}\n className=\"rounded border-gray-300 text-blue-600 focus:ring-blue-500 h-3.5 w-3.5\" />\n {name}\n </label>\n ))}\n </div>\n </div>\n </WidgetSettingsModal>\n </>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/apps/WorldClock.tsx"],"names":[],"mappings":"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","file":"WorldClock-XPD7WOZT.js","sourcesContent":["import { useState, useEffect, useCallback } from 'react';\nimport { useWidgetSettings } from '../shell/Modal';\nimport WidgetSettingsModal, { loadAppearance, type WidgetAppearance } from '../shell/WidgetSettingsModal';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport { AVAILABLE_CITIES, fetchCityWeather, getCondition, toFahrenheit, type CityWeather } from './_weatherData';\n\nconst SETTINGS_KEY = 'world_clock_appearance';\nconst DEFAULT_CITIES = ['London', 'Shanghai', 'New York'];\n\ninterface WeatherPrefs { useFahrenheit: boolean }\n\n/**\n * Resolve the local time for the supplied IANA timezone into a digital\n * `12:34` + `AM` / `PM` pair. Used by the World Clock rows.\n */\nfunction digitalTime(tz: string, now: Date): { time: string; ampm: string } {\n try {\n const parts = new Intl.DateTimeFormat('en-US', {\n timeZone: tz, hour: 'numeric', minute: '2-digit', hour12: true,\n }).formatToParts(now);\n const h = parts.find(p => p.type === 'hour')?.value || '12';\n const m = parts.find(p => p.type === 'minute')?.value || '00';\n const ampm = (parts.find(p => p.type === 'dayPeriod')?.value || '').toUpperCase();\n return { time: `${h}:${m}`, ampm };\n } catch { return { time: '', ampm: '' }; }\n}\n\n/**\n * World Clock widget — multi-city list. Each row pairs a tiny analogue\n * clock (minimal-style: ring, four cardinal dots, two hands) with the\n * city's current weather. The weather emoji doubles as a day/night cue\n * (☀ vs 🌙 for clear, the same icons for everything else). Reads the\n * shared Open-Meteo cache so it doesn't re-hit the API when the Weather\n * widget already has the data.\n */\nexport default function WorldClock() {\n const { prefs, save } = useShellPrefs();\n const [appearance, setAppearance] = useState(() => loadAppearance(SETTINGS_KEY));\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [configCities, setConfigCities] = useState<string[]>([]);\n const [configAppearance, setConfigAppearance] = useState<WidgetAppearance>(appearance);\n\n const wxPrefs: WeatherPrefs = {\n useFahrenheit: !!(prefs.weather_prefs as WeatherPrefs | undefined)?.useFahrenheit,\n };\n const [configWxPrefs, setConfigWxPrefs] = useState(wxPrefs);\n\n // Tick once every 30 s so the analogue minute-hands drift smoothly. We\n // don't show seconds so faster polling is wasted re-renders.\n const [now, setNow] = useState(() => new Date());\n useEffect(() => {\n const t = setInterval(() => setNow(new Date()), 30 * 1000);\n return () => clearInterval(t);\n }, []);\n\n // Resolve the saved city list and migrate the legacy IANA-timezone\n // format (`Europe/London`) over to the new city-name format\n // (`London`).\n const tzToCity: Record<string, string> = Object.fromEntries(\n Object.entries(AVAILABLE_CITIES).map(([city, info]) => [info.tz, city])\n );\n const rawClocks = prefs.world_clocks as string[] | undefined;\n const cities: string[] = (() => {\n if (!Array.isArray(rawClocks) || rawClocks.length === 0) return DEFAULT_CITIES;\n const out: string[] = [];\n for (const v of rawClocks) {\n const asCity = AVAILABLE_CITIES[v] ? v : tzToCity[v];\n if (asCity && !out.includes(asCity)) out.push(asCity);\n }\n return out.length ? out : DEFAULT_CITIES;\n })();\n\n const [data, setData] = useState<Record<string, CityWeather>>({});\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n (async () => {\n const next: Record<string, CityWeather> = {};\n await Promise.all(cities.map(async c => {\n const w = await fetchCityWeather(c);\n if (w) next[c] = w;\n }));\n if (!cancelled) { setData(next); setLoading(false); }\n })();\n return () => { cancelled = true; };\n }, [cities.join(',')]);\n\n useWidgetSettings(useCallback(() => {\n setConfigCities([...cities]);\n setConfigAppearance({ ...appearance });\n setConfigWxPrefs({ ...wxPrefs });\n setSettingsOpen(true);\n }, [cities.join(','), appearance, wxPrefs.useFahrenheit]));\n\n const saveSettings = () => {\n if (configCities.length === 0) return;\n save({\n world_clocks: configCities,\n weather_prefs: { ...(prefs.weather_prefs as object | undefined ?? {}), useFahrenheit: configWxPrefs.useFahrenheit },\n });\n setAppearance(configAppearance);\n localStorage.setItem(SETTINGS_KEY, JSON.stringify(configAppearance));\n setSettingsOpen(false);\n };\n\n const formatTemp = (c: number) => wxPrefs.useFahrenheit ? `${toFahrenheit(c)}°` : `${c}°`;\n\n return (\n <>\n {/* Theme-aware panel — same colour as the taskbar so all dashboard\n * widgets read as a coordinated set across light and dark themes.\n * Rows use `divide-y` rather than per-row border classes so the\n * last row never paints a stray separator line at the panel's\n * bottom edge. */}\n <div\n style={{\n backgroundColor: `rgb(var(--taskbar-bg-rgb, 243 244 246) / ${appearance.activeOpacity / 100})`,\n backdropFilter: appearance.activeBlur > 0 ? `blur(${appearance.activeBlur}px)` : undefined,\n }}>\n <div className=\"divide-y divide-gray-200\">\n {loading && cities.every(c => !data[c]) && (\n <div className=\"px-3 py-6 text-center text-xs text-gray-500\">Loading…</div>\n )}\n {cities.map((cityName) => {\n const w = data[cityName];\n const tz = AVAILABLE_CITIES[cityName]?.tz ?? 'UTC';\n const { time, ampm } = digitalTime(tz, now);\n if (!w) {\n return (\n <div key={cityName} className=\"px-4 py-3\">\n <div className=\"flex items-baseline justify-between gap-2\">\n <span className=\"text-[15px] font-semibold tracking-tight text-gray-900 truncate\">{cityName}</span>\n <span className=\"tabular-nums text-[13px] font-medium text-gray-500\">{time}<span className=\"text-[9px] ml-0.5 opacity-70\">{ampm}</span></span>\n </div>\n <div className=\"text-[11px] text-gray-400 mt-1\">Loading weather…</div>\n </div>\n );\n }\n const [condition, emoji] = getCondition(w.code, w.isDay);\n return (\n <div key={cityName} className=\"px-4 py-3\">\n {/* Top — city name on the left, big temperature on the right. */}\n <div className=\"flex items-baseline justify-between gap-2\">\n <span className=\"text-[15px] font-semibold tracking-tight text-gray-900 truncate\">{cityName}</span>\n <span className=\"text-[26px] font-extralight leading-none tabular-nums tracking-tight text-gray-900 shrink-0\">{formatTemp(w.temp)}</span>\n </div>\n\n {/* Bottom — emoji · digital time · condition on the left;\n H/L on the right. */}\n <div className=\"flex items-center justify-between gap-2 mt-1.5 text-[11px]\">\n <div className=\"flex items-center gap-1.5 min-w-0 text-gray-500\">\n <span className=\"text-base leading-none shrink-0\">{emoji}</span>\n <span className=\"tabular-nums font-semibold text-gray-700 shrink-0\">\n {time}<span className=\"text-[9px] font-medium ml-0.5 opacity-70\">{ampm}</span>\n </span>\n <span className=\"text-gray-300 shrink-0\">·</span>\n <span className=\"truncate\">{condition}</span>\n </div>\n <span className=\"tabular-nums text-gray-500 shrink-0\">H:{formatTemp(w.high)} L:{formatTemp(w.low)}</span>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n\n <WidgetSettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} title=\"World Clock Settings\"\n appearance={configAppearance} onAppearanceChange={setConfigAppearance} onSave={saveSettings}>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Display</h3>\n <div className=\"flex items-center gap-3 mb-2\">\n <span className=\"text-sm text-gray-600 w-24\">Temperature</span>\n <div className=\"flex gap-1\">\n {([{ key: false, label: '°C' }, { key: true, label: '°F' }] as const).map(o => (\n <button key={String(o.key)} onClick={() => setConfigWxPrefs(p => ({ ...p, useFahrenheit: o.key }))}\n className={`px-3 py-1 text-xs font-medium rounded-lg border transition-colors ${configWxPrefs.useFahrenheit === o.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'}`}>\n {o.label}\n </button>\n ))}\n </div>\n </div>\n <p className=\"text-[10px] text-gray-400 mt-1\">Shared with the Weather widget.</p>\n </div>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Cities</h3>\n <div className=\"grid grid-cols-2 gap-1 max-h-56 overflow-y-auto\">\n {Object.keys(AVAILABLE_CITIES).map(name => (\n <label key={name} className=\"flex items-center gap-2 text-sm py-1 cursor-pointer hover:bg-gray-50 rounded px-2\">\n <input type=\"checkbox\" checked={configCities.includes(name)}\n onChange={() => setConfigCities(prev => prev.includes(name) ? prev.filter(c => c !== name) : [...prev, name])}\n className=\"rounded border-gray-300 text-blue-600 focus:ring-blue-500 h-3.5 w-3.5\" />\n {name}\n </label>\n ))}\n </div>\n </div>\n </WidgetSettingsModal>\n </>\n );\n}\n"]}
@@ -110,7 +110,7 @@ type BuiltinAppId = keyof typeof BUILTIN_APP_INFO;
110
110
  * PDF Preview staging — the tiny consumer-facing surface of the Preview app.
111
111
  *
112
112
  * Lives apart from Preview.tsx so importing `setPdfPreview` (from
113
- * `react-os-shell/apps` or shell internals like PdfActionButton /
113
+ * `efficient-shell/apps` or shell internals like PdfActionButton /
114
114
  * openPreviewFile) never drags the viewer implementation — and its static
115
115
  * pdfjs-dist import — into a host's startup bundle. The Preview window
116
116
  * component stays behind its React.lazy dynamic import and drains the stage
@@ -157,7 +157,7 @@ declare function setPdfPreview(data: PdfPreviewData): PdfPreviewHandle;
157
157
  /**
158
158
  * Spreadsheet staging — the tiny consumer-facing surface of the Spreadsheets
159
159
  * app. Lives apart from Spreadsheet.tsx so importing `setSpreadsheetPreview`
160
- * (from `react-os-shell/apps` or shell internals like openPreviewFile) never
160
+ * (from `efficient-shell/apps` or shell internals like openPreviewFile) never
161
161
  * drags the grid implementation into a host's startup bundle. The Spreadsheet
162
162
  * window component stays behind its React.lazy dynamic import and drains the
163
163
  * stage on mount via the @internal peek/claim helpers below.
@@ -1,24 +1,24 @@
1
1
  "use client";
2
- export { openFilesInTrashMode, setFilesDemoTree } from '../chunk-I464GYJJ.js';
3
- export { setBrowserStartUrl } from '../chunk-BFBWLCO6.js';
4
- export { BUILTIN_APP_INFO } from '../chunk-CJYO4RVV.js';
2
+ export { openFilesInTrashMode, setFilesDemoTree } from '../chunk-BE7FZOFU.js';
3
+ export { setBrowserStartUrl } from '../chunk-TW7LPMVR.js';
4
+ export { BUILTIN_APP_INFO } from '../chunk-COWYSHG2.js';
5
5
  import '../chunk-YNKK7NE3.js';
6
- import { setPdfPreview } from '../chunk-3L463T5H.js';
7
- export { setPdfPreview } from '../chunk-3L463T5H.js';
8
- import { setSpreadsheetPreview } from '../chunk-CT3HVZRZ.js';
9
- export { setSpreadsheetPreview } from '../chunk-CT3HVZRZ.js';
10
- import '../chunk-ZKHD4J73.js';
6
+ import { setPdfPreview } from '../chunk-DVZWYWSD.js';
7
+ export { setPdfPreview } from '../chunk-DVZWYWSD.js';
8
+ import { setSpreadsheetPreview } from '../chunk-5O42JXQE.js';
9
+ export { setSpreadsheetPreview } from '../chunk-5O42JXQE.js';
10
+ import '../chunk-ICTRCKUE.js';
11
11
  import '../chunk-GA35NEND.js';
12
- import '../chunk-JMKYYPOF.js';
13
- import { toast_default } from '../chunk-EENVXIVU.js';
14
- import '../chunk-TQURTLK2.js';
15
- import '../chunk-LQTVTOSY.js';
16
- import '../chunk-E3TWIN7Z.js';
17
- import '../chunk-XH3ELPQZ.js';
18
- import '../chunk-D276EMXS.js';
19
- import '../chunk-7IN7YZAL.js';
20
- import '../chunk-IRWSRJ4K.js';
12
+ import '../chunk-ZS7PMGUW.js';
13
+ import { toast_default } from '../chunk-UTYKLGGT.js';
14
+ import '../chunk-HUBJAUGG.js';
15
+ import '../chunk-RT6DSB5Y.js';
16
+ import '../chunk-JOPU6WPY.js';
17
+ import '../chunk-I2TAAJHS.js';
18
+ import '../chunk-6XJEJWNJ.js';
19
+ import '../chunk-YE6GUDGP.js';
21
20
  import '../chunk-IPXN646P.js';
21
+ import '../chunk-IRWSRJ4K.js';
22
22
  import { lazy } from 'react';
23
23
 
24
24
  // src/apps/openAttachment.ts
@@ -110,19 +110,19 @@ async function openAttachment(att, openPage, opts = {}) {
110
110
  }
111
111
 
112
112
  // src/apps/index.ts
113
- var Calculator = lazy(() => import('../Calculator-ZXJPXG7F.js'));
114
- var Spreadsheet = lazy(() => import('../Spreadsheet-3WTXCHYQ.js'));
115
- var Weather = lazy(() => import('../Weather-NZO3CWLH.js'));
116
- var CurrencyConverter = lazy(() => import('../CurrencyConverter-WSJ2BBSX.js'));
117
- var PomodoroTimer = lazy(() => import('../PomodoroTimer-DG3LI5CX.js'));
118
- var Notepad = lazy(() => import('../Notepad-HM73XAM4.js'));
119
- var WorldClock = lazy(() => import('../WorldClock-HUC6D3AD.js'));
120
- var Stock = lazy(() => import('../Stock-YMPOMUAW.js'));
121
- var Preview = lazy(() => import('../Preview-TUSV4UMO.js'));
122
- var PdfViewer = lazy(() => import('../PdfViewer-M2YGZIYX.js'));
123
- var Documents = lazy(() => import('../Documents-ONGSXUJI.js'));
124
- var Files = lazy(() => import('../Files-GQZMFWXQ.js'));
125
- var Browser = lazy(() => import('../Browser-XPVJ2K7B.js'));
113
+ var Calculator = lazy(() => import('../Calculator-6FGNKOXU.js'));
114
+ var Spreadsheet = lazy(() => import('../Spreadsheet-HOCPHJOC.js'));
115
+ var Weather = lazy(() => import('../Weather-LZQGVDJL.js'));
116
+ var CurrencyConverter = lazy(() => import('../CurrencyConverter-FF7EXRYL.js'));
117
+ var PomodoroTimer = lazy(() => import('../PomodoroTimer-IR3WREED.js'));
118
+ var Notepad = lazy(() => import('../Notepad-VE7ISWRQ.js'));
119
+ var WorldClock = lazy(() => import('../WorldClock-XPD7WOZT.js'));
120
+ var Stock = lazy(() => import('../Stock-LVRQPURG.js'));
121
+ var Preview = lazy(() => import('../Preview-DAQGRNRM.js'));
122
+ var PdfViewer = lazy(() => import('../PdfViewer-SQBFYAGW.js'));
123
+ var Documents = lazy(() => import('../Documents-H3R7XSBH.js'));
124
+ var Files = lazy(() => import('../Files-ZHJIAUC2.js'));
125
+ var Browser = lazy(() => import('../Browser-ZNX4WFUH.js'));
126
126
  var utilityApps = {
127
127
  "/calculator": { component: Calculator, label: "Calculator", size: "sm", allowPinOnTop: true, utility: true, widget: true, dimensions: [280, 420] },
128
128
  "/spreadsheet": { component: Spreadsheet, label: "Spreadsheets", size: "2xl", appStyle: true, multiInstance: true },
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/apps/openAttachment.ts","../../src/apps/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Route a stored file into the app that can read it — Preview for PDFs,\n * images, drawings and 3D models, Spreadsheet for CSV/TSV — instead of handing\n * it to a browser tab (harness UI-18).\n *\n * Lifted from the admin portal, where it had routed email and CRM-note\n * attachments since 2026-09; the customer, supplier and dealer portals needed\n * the same decision table for their own attachments, and a fourth copy of a\n * classification this specific is exactly what drifts.\n *\n * Two transports, because stored-file URLs differ by deployment:\n *\n * - By default the viewer is given the URL and fetches it itself. Fine where\n * the file is same-origin with the page.\n * - Pass `fetchBlob` where it is not. A presigned/CDN URL is cross-origin to\n * the portal, so the viewer's own fetch fails (\"Failed to fetch\") even\n * though the URL opens perfectly in a tab; the caller's API client pulls\n * the bytes instead, and the window shows a placeholder until they land.\n *\n * Binary workbooks (xlsx, ods) stay downloads on purpose: previewing one means\n * parsing untrusted bytes in the host's own origin.\n */\nimport toast from '../shell/toast';\nimport { setPdfPreview } from './_previewStage';\nimport { setSpreadsheetPreview } from './_spreadsheetStage';\n\n/** Minimal attachment shape — a filename and where the bytes are. */\nexport interface OpenableAttachment {\n filename?: string | null;\n /** `null` where the serializer could not address the stored file; treated\n * exactly like a missing one, so a caller need not narrow before calling. */\n url?: string | null;\n}\n\n/** `useWindowManager().openPage`. */\nexport type OpenPage = (path: string) => void;\n\nexport interface OpenAttachmentOptions {\n /**\n * Fetch the bytes yourself — for a URL the page cannot fetch (presigned/CDN)\n * or one that needs an Authorization header. Called only for a file a viewer\n * can render; the window opens on `loadingMessage` and swaps in the result.\n * Reject with an Error whose message the reader should see.\n */\n fetchBlob?: (att: OpenableAttachment) => Promise<Blob>;\n /** Placeholder headline while `fetchBlob` runs. Default: \"LOADING FILE\". */\n loadingMessage?: string;\n}\n\n/** Lower-case file extension (no dot) from a name or URL, '' if none. */\nfunction extOf(name: string): string {\n const m = /\\.([a-z0-9]+)(?:[?#].*)?$/i.exec((name || '').trim());\n return m ? m[1].toLowerCase() : '';\n}\n\nconst DELIMITED_TEXT_EXT = new Set(['csv', 'tsv']);\nconst BINARY_WORKBOOK_EXT = new Set(['xlsx', 'xls', 'xlsm', 'ods']);\nconst IMAGE_EXT = new Set(['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'svg', 'avif']);\nconst THREED_EXT = new Set(['step', 'stp', 'stl', 'obj', 'gltf', 'glb', '3mf', 'iges', 'igs']);\n\n/** Which viewer renders this file, or `null` for one neither app can show. */\nexport function attachmentKind(nameOrUrl: string): 'pdf' | 'image' | '3d' | 'dxf' | 'csv' | null {\n const ext = extOf(nameOrUrl);\n if (ext === 'pdf') return 'pdf';\n if (ext === 'dxf') return 'dxf';\n if (DELIMITED_TEXT_EXT.has(ext)) return 'csv';\n if (IMAGE_EXT.has(ext)) return 'image';\n if (THREED_EXT.has(ext)) return '3d';\n return null;\n}\n\nfunction openInNewTab(url: string) {\n window.open(url, '_blank', 'noopener,noreferrer');\n}\n\nasync function readText(url: string, opts: OpenAttachmentOptions, att: OpenableAttachment): Promise<string> {\n if (opts.fetchBlob) return (await opts.fetchBlob(att)).text();\n const res = await fetch(url);\n if (!res.ok) throw new Error(`fetch failed: ${res.status}`);\n return res.text();\n}\n\nfunction errorText(err: unknown, fallback: string): string {\n const message = err instanceof Error ? err.message : '';\n return message || fallback;\n}\n\n/**\n * Open `att` in the shell app that can read it. `openPage` comes from\n * `useWindowManager()`.\n *\n * Resolves once the file has been handed to a window (or opened in a tab); it\n * never throws — a failure is shown to the reader, in the viewer when one is\n * already open for the file and as a toast when there is nothing to show it in.\n */\nexport async function openAttachment(\n att: OpenableAttachment,\n openPage: OpenPage,\n opts: OpenAttachmentOptions = {},\n): Promise<void> {\n const url = att?.url || '';\n const filename = att?.filename || 'attachment';\n if (!url && !opts.fetchBlob) {\n toast.error('This attachment has no download link.');\n return;\n }\n const kind = attachmentKind(filename) ?? attachmentKind(url);\n\n if (kind === 'csv') {\n try {\n setSpreadsheetPreview({ csv: await readText(url, opts, att), filename });\n openPage('/spreadsheet');\n } catch {\n toast.error('Could not open the spreadsheet — opening the file instead.');\n if (url) openInNewTab(url);\n }\n return;\n }\n\n if (BINARY_WORKBOOK_EXT.has(extOf(filename) || extOf(url))) {\n // Parsing an untrusted workbook in the host's own origin is not worth a\n // preview; the reader gets the file itself.\n toast.error('Spreadsheet preview is unavailable for this file type. Opening the file instead.');\n if (url) openInNewTab(url);\n return;\n }\n\n if (!kind) {\n // No viewer renders docx / txt / zip — say so rather than appear to fail.\n if (!url) {\n toast.error('This attachment has no download link.');\n return;\n }\n toast.info('Opening this file outside the app — no viewer can show it here.');\n openInNewTab(url);\n return;\n }\n\n if (!opts.fetchBlob) {\n setPdfPreview({ url, filename, kind });\n openPage('/preview');\n return;\n }\n\n // The viewer cannot fetch this URL itself: open it on a placeholder and swap\n // the bytes in, so a slow file is visibly loading and a failed one says why\n // in the window the reader is already looking at.\n const handle = setPdfPreview({\n filename, kind, converting: true,\n convertingMessage: opts.loadingMessage || 'LOADING FILE',\n });\n openPage('/preview');\n try {\n const blob = await opts.fetchBlob(att);\n handle.update({ url: URL.createObjectURL(blob), filename, kind });\n } catch (err) {\n handle.update({\n filename, kind, converting: false,\n convertingMessage: errorText(err, 'Failed to load this file.'),\n });\n }\n}\n","/**\n * Bundled apps — pre-built window registry entries for the 12 apps that ship\n * with `react-os-shell`. Consumers compose them into their own registry via\n * `createWindowRegistry`:\n *\n * import { createWindowRegistry } from 'react-os-shell';\n * import { bundledApps } from 'react-os-shell/apps';\n * import { erpEntities } from './shell-config';\n *\n * const windows = createWindowRegistry(bundledApps, erpEntities);\n *\n * Subsets are also exported (`utilityApps`, `documentApps`, `webApps`) so a\n * consumer can pick-and-choose without importing every component.\n *\n * NOTE: Notepad requires consumer-supplied persistence for stored content.\n * WorldClock uses `useShellPrefs()` so it lives in `bundledApps`; without a\n * consumer-supplied prefs adapter the city list won't survive a reload.\n */\nimport { lazy } from 'react';\nimport type { WindowRegistry } from '../windowRegistry/types';\n\n// ── Utility apps ──\nconst Calculator = lazy(() => import('./Calculator'));\nconst Spreadsheet = lazy(() => import('./Spreadsheet'));\nconst Weather = lazy(() => import('./Weather'));\nconst CurrencyConverter = lazy(() => import('./CurrencyConverter'));\nconst PomodoroTimer = lazy(() => import('./PomodoroTimer'));\nconst Notepad = lazy(() => import('./Notepad'));\nconst WorldClock = lazy(() => import('./WorldClock'));\nconst Stock = lazy(() => import('./Stock'));\n\n// ── Document apps ──\nconst Preview = lazy(() => import('./Preview'));\n/** The PDF reader out of the Preview window, for embedding in a pane of your\n * own (a preview beside a form, a document tab). Lazy for the same reason\n * every app here is: its static `pdfjs-dist` import must not land in a host's\n * startup bundle — so render it inside a `<Suspense>`, and give it a parent\n * with a resolved height. See `PdfViewerProps` for `fit`. */\nconst PdfViewer = lazy(() => import('./PdfViewer'));\nconst Documents = lazy(() => import('./Documents'));\nconst Files = lazy(() => import('./Files'));\n\n// ── Web ──\nconst Browser = lazy(() => import('./Browser'));\n\nexport const utilityApps: WindowRegistry = {\n '/calculator': { component: Calculator, label: 'Calculator', size: 'sm', allowPinOnTop: true, utility: true, widget: true, dimensions: [280, 420] },\n '/spreadsheet': { component: Spreadsheet, label: 'Spreadsheets', size: '2xl', appStyle: true, multiInstance: true },\n '/notepad': { component: Notepad, label: 'Notepad', size: 'lg', allowPinOnTop: true, flushBody: true },\n '/weather': { component: Weather, label: 'Weather', size: 'sm', utility: true, widget: true, autoHeight: true, dimensions: [320, 400] },\n '/currency': { component: CurrencyConverter, label: 'Currency Converter', size: 'sm', utility: true, widget: true, autoHeight: true, dimensions: [320, 480] },\n '/pomodoro': { component: PomodoroTimer, label: 'Pomodoro Timer', size: 'sm', utility: true, widget: true, dimensions: [320, 600] },\n '/world-clock': { component: WorldClock, label: 'World Clock', size: 'sm', utility: true, widget: true, autoHeight: true, dimensions: [320, 480] },\n '/stock': { component: Stock, label: 'Stocks', size: 'sm', utility: true, widget: true, autoHeight: true, dimensions: [320, 360] },\n};\n\nexport const documentApps: WindowRegistry = {\n '/preview': { component: Preview, label: 'Preview', size: '2xl', appStyle: true, multiInstance: true },\n '/documents': { component: Documents, label: 'Documents', size: 'xl', appStyle: true, multiInstance: true },\n '/files': { component: Files, label: 'Files', size: 'xl', appStyle: true },\n};\n\nexport const webApps: WindowRegistry = {\n '/browser': { component: Browser, label: 'Browser', size: '2xl', appStyle: true, multiInstance: true },\n};\n\nexport const bundledApps: WindowRegistry = {\n ...utilityApps,\n ...documentApps,\n ...webApps,\n};\n\nexport {\n Calculator,\n Spreadsheet,\n Notepad,\n Weather,\n CurrencyConverter,\n PomodoroTimer,\n WorldClock,\n Stock,\n Preview,\n PdfViewer,\n Documents,\n Files,\n Browser,\n};\n\nexport { BUILTIN_APP_INFO } from './_about';\nexport type { BuiltinAppId, BuiltinAppInfo } from './_about';\n// Setters/config live in small standalone modules (not the app-implementation\n// files) so importing them here never drags an app chunk — most notably\n// Preview's static pdfjs-dist import — into a host's startup bundle.\nexport { setPdfPreview } from './_previewStage';\nexport { setSpreadsheetPreview } from './_spreadsheetStage';\n// Routes a stored file to whichever of the two can read it (UI-18). Same\n// module family for the same reason: it imports the stages, not the apps.\nexport { openAttachment, attachmentKind } from './openAttachment';\nexport type { OpenableAttachment, OpenAttachmentOptions, OpenPage } from './openAttachment';\nexport { setBrowserStartUrl } from './_browserStage';\nexport { openFilesInTrashMode, setFilesDemoTree } from './_filesShared';\nexport type { FilesDemoNode } from './_filesShared';\nexport type { PdfPreviewData, PdfPreviewHandle } from './_previewStage';\n// Type-only, so this re-export is erased at build and never pulls the module.\nexport type { PdfViewerProps } from './PdfViewer';\nexport type { SpreadsheetPreviewData, SpreadsheetPreviewHandle } from './_spreadsheetStage';\n"]}
1
+ {"version":3,"sources":["../../src/apps/openAttachment.ts","../../src/apps/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Route a stored file into the app that can read it — Preview for PDFs,\n * images, drawings and 3D models, Spreadsheet for CSV/TSV — instead of handing\n * it to a browser tab (harness UI-18).\n *\n * Lifted from the admin portal, where it had routed email and CRM-note\n * attachments since 2026-09; the customer, supplier and dealer portals needed\n * the same decision table for their own attachments, and a fourth copy of a\n * classification this specific is exactly what drifts.\n *\n * Two transports, because stored-file URLs differ by deployment:\n *\n * - By default the viewer is given the URL and fetches it itself. Fine where\n * the file is same-origin with the page.\n * - Pass `fetchBlob` where it is not. A presigned/CDN URL is cross-origin to\n * the portal, so the viewer's own fetch fails (\"Failed to fetch\") even\n * though the URL opens perfectly in a tab; the caller's API client pulls\n * the bytes instead, and the window shows a placeholder until they land.\n *\n * Binary workbooks (xlsx, ods) stay downloads on purpose: previewing one means\n * parsing untrusted bytes in the host's own origin.\n */\nimport toast from '../shell/toast';\nimport { setPdfPreview } from './_previewStage';\nimport { setSpreadsheetPreview } from './_spreadsheetStage';\n\n/** Minimal attachment shape — a filename and where the bytes are. */\nexport interface OpenableAttachment {\n filename?: string | null;\n /** `null` where the serializer could not address the stored file; treated\n * exactly like a missing one, so a caller need not narrow before calling. */\n url?: string | null;\n}\n\n/** `useWindowManager().openPage`. */\nexport type OpenPage = (path: string) => void;\n\nexport interface OpenAttachmentOptions {\n /**\n * Fetch the bytes yourself — for a URL the page cannot fetch (presigned/CDN)\n * or one that needs an Authorization header. Called only for a file a viewer\n * can render; the window opens on `loadingMessage` and swaps in the result.\n * Reject with an Error whose message the reader should see.\n */\n fetchBlob?: (att: OpenableAttachment) => Promise<Blob>;\n /** Placeholder headline while `fetchBlob` runs. Default: \"LOADING FILE\". */\n loadingMessage?: string;\n}\n\n/** Lower-case file extension (no dot) from a name or URL, '' if none. */\nfunction extOf(name: string): string {\n const m = /\\.([a-z0-9]+)(?:[?#].*)?$/i.exec((name || '').trim());\n return m ? m[1].toLowerCase() : '';\n}\n\nconst DELIMITED_TEXT_EXT = new Set(['csv', 'tsv']);\nconst BINARY_WORKBOOK_EXT = new Set(['xlsx', 'xls', 'xlsm', 'ods']);\nconst IMAGE_EXT = new Set(['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'svg', 'avif']);\nconst THREED_EXT = new Set(['step', 'stp', 'stl', 'obj', 'gltf', 'glb', '3mf', 'iges', 'igs']);\n\n/** Which viewer renders this file, or `null` for one neither app can show. */\nexport function attachmentKind(nameOrUrl: string): 'pdf' | 'image' | '3d' | 'dxf' | 'csv' | null {\n const ext = extOf(nameOrUrl);\n if (ext === 'pdf') return 'pdf';\n if (ext === 'dxf') return 'dxf';\n if (DELIMITED_TEXT_EXT.has(ext)) return 'csv';\n if (IMAGE_EXT.has(ext)) return 'image';\n if (THREED_EXT.has(ext)) return '3d';\n return null;\n}\n\nfunction openInNewTab(url: string) {\n window.open(url, '_blank', 'noopener,noreferrer');\n}\n\nasync function readText(url: string, opts: OpenAttachmentOptions, att: OpenableAttachment): Promise<string> {\n if (opts.fetchBlob) return (await opts.fetchBlob(att)).text();\n const res = await fetch(url);\n if (!res.ok) throw new Error(`fetch failed: ${res.status}`);\n return res.text();\n}\n\nfunction errorText(err: unknown, fallback: string): string {\n const message = err instanceof Error ? err.message : '';\n return message || fallback;\n}\n\n/**\n * Open `att` in the shell app that can read it. `openPage` comes from\n * `useWindowManager()`.\n *\n * Resolves once the file has been handed to a window (or opened in a tab); it\n * never throws — a failure is shown to the reader, in the viewer when one is\n * already open for the file and as a toast when there is nothing to show it in.\n */\nexport async function openAttachment(\n att: OpenableAttachment,\n openPage: OpenPage,\n opts: OpenAttachmentOptions = {},\n): Promise<void> {\n const url = att?.url || '';\n const filename = att?.filename || 'attachment';\n if (!url && !opts.fetchBlob) {\n toast.error('This attachment has no download link.');\n return;\n }\n const kind = attachmentKind(filename) ?? attachmentKind(url);\n\n if (kind === 'csv') {\n try {\n setSpreadsheetPreview({ csv: await readText(url, opts, att), filename });\n openPage('/spreadsheet');\n } catch {\n toast.error('Could not open the spreadsheet — opening the file instead.');\n if (url) openInNewTab(url);\n }\n return;\n }\n\n if (BINARY_WORKBOOK_EXT.has(extOf(filename) || extOf(url))) {\n // Parsing an untrusted workbook in the host's own origin is not worth a\n // preview; the reader gets the file itself.\n toast.error('Spreadsheet preview is unavailable for this file type. Opening the file instead.');\n if (url) openInNewTab(url);\n return;\n }\n\n if (!kind) {\n // No viewer renders docx / txt / zip — say so rather than appear to fail.\n if (!url) {\n toast.error('This attachment has no download link.');\n return;\n }\n toast.info('Opening this file outside the app — no viewer can show it here.');\n openInNewTab(url);\n return;\n }\n\n if (!opts.fetchBlob) {\n setPdfPreview({ url, filename, kind });\n openPage('/preview');\n return;\n }\n\n // The viewer cannot fetch this URL itself: open it on a placeholder and swap\n // the bytes in, so a slow file is visibly loading and a failed one says why\n // in the window the reader is already looking at.\n const handle = setPdfPreview({\n filename, kind, converting: true,\n convertingMessage: opts.loadingMessage || 'LOADING FILE',\n });\n openPage('/preview');\n try {\n const blob = await opts.fetchBlob(att);\n handle.update({ url: URL.createObjectURL(blob), filename, kind });\n } catch (err) {\n handle.update({\n filename, kind, converting: false,\n convertingMessage: errorText(err, 'Failed to load this file.'),\n });\n }\n}\n","/**\n * Bundled apps — pre-built window registry entries for the 12 apps that ship\n * with `efficient-shell`. Consumers compose them into their own registry via\n * `createWindowRegistry`:\n *\n * import { createWindowRegistry } from 'efficient-shell';\n * import { bundledApps } from 'efficient-shell/apps';\n * import { erpEntities } from './shell-config';\n *\n * const windows = createWindowRegistry(bundledApps, erpEntities);\n *\n * Subsets are also exported (`utilityApps`, `documentApps`, `webApps`) so a\n * consumer can pick-and-choose without importing every component.\n *\n * NOTE: Notepad requires consumer-supplied persistence for stored content.\n * WorldClock uses `useShellPrefs()` so it lives in `bundledApps`; without a\n * consumer-supplied prefs adapter the city list won't survive a reload.\n */\nimport { lazy } from 'react';\nimport type { WindowRegistry } from '../windowRegistry/types';\n\n// ── Utility apps ──\nconst Calculator = lazy(() => import('./Calculator'));\nconst Spreadsheet = lazy(() => import('./Spreadsheet'));\nconst Weather = lazy(() => import('./Weather'));\nconst CurrencyConverter = lazy(() => import('./CurrencyConverter'));\nconst PomodoroTimer = lazy(() => import('./PomodoroTimer'));\nconst Notepad = lazy(() => import('./Notepad'));\nconst WorldClock = lazy(() => import('./WorldClock'));\nconst Stock = lazy(() => import('./Stock'));\n\n// ── Document apps ──\nconst Preview = lazy(() => import('./Preview'));\n/** The PDF reader out of the Preview window, for embedding in a pane of your\n * own (a preview beside a form, a document tab). Lazy for the same reason\n * every app here is: its static `pdfjs-dist` import must not land in a host's\n * startup bundle — so render it inside a `<Suspense>`, and give it a parent\n * with a resolved height. See `PdfViewerProps` for `fit`. */\nconst PdfViewer = lazy(() => import('./PdfViewer'));\nconst Documents = lazy(() => import('./Documents'));\nconst Files = lazy(() => import('./Files'));\n\n// ── Web ──\nconst Browser = lazy(() => import('./Browser'));\n\nexport const utilityApps: WindowRegistry = {\n '/calculator': { component: Calculator, label: 'Calculator', size: 'sm', allowPinOnTop: true, utility: true, widget: true, dimensions: [280, 420] },\n '/spreadsheet': { component: Spreadsheet, label: 'Spreadsheets', size: '2xl', appStyle: true, multiInstance: true },\n '/notepad': { component: Notepad, label: 'Notepad', size: 'lg', allowPinOnTop: true, flushBody: true },\n '/weather': { component: Weather, label: 'Weather', size: 'sm', utility: true, widget: true, autoHeight: true, dimensions: [320, 400] },\n '/currency': { component: CurrencyConverter, label: 'Currency Converter', size: 'sm', utility: true, widget: true, autoHeight: true, dimensions: [320, 480] },\n '/pomodoro': { component: PomodoroTimer, label: 'Pomodoro Timer', size: 'sm', utility: true, widget: true, dimensions: [320, 600] },\n '/world-clock': { component: WorldClock, label: 'World Clock', size: 'sm', utility: true, widget: true, autoHeight: true, dimensions: [320, 480] },\n '/stock': { component: Stock, label: 'Stocks', size: 'sm', utility: true, widget: true, autoHeight: true, dimensions: [320, 360] },\n};\n\nexport const documentApps: WindowRegistry = {\n '/preview': { component: Preview, label: 'Preview', size: '2xl', appStyle: true, multiInstance: true },\n '/documents': { component: Documents, label: 'Documents', size: 'xl', appStyle: true, multiInstance: true },\n '/files': { component: Files, label: 'Files', size: 'xl', appStyle: true },\n};\n\nexport const webApps: WindowRegistry = {\n '/browser': { component: Browser, label: 'Browser', size: '2xl', appStyle: true, multiInstance: true },\n};\n\nexport const bundledApps: WindowRegistry = {\n ...utilityApps,\n ...documentApps,\n ...webApps,\n};\n\nexport {\n Calculator,\n Spreadsheet,\n Notepad,\n Weather,\n CurrencyConverter,\n PomodoroTimer,\n WorldClock,\n Stock,\n Preview,\n PdfViewer,\n Documents,\n Files,\n Browser,\n};\n\nexport { BUILTIN_APP_INFO } from './_about';\nexport type { BuiltinAppId, BuiltinAppInfo } from './_about';\n// Setters/config live in small standalone modules (not the app-implementation\n// files) so importing them here never drags an app chunk — most notably\n// Preview's static pdfjs-dist import — into a host's startup bundle.\nexport { setPdfPreview } from './_previewStage';\nexport { setSpreadsheetPreview } from './_spreadsheetStage';\n// Routes a stored file to whichever of the two can read it (UI-18). Same\n// module family for the same reason: it imports the stages, not the apps.\nexport { openAttachment, attachmentKind } from './openAttachment';\nexport type { OpenableAttachment, OpenAttachmentOptions, OpenPage } from './openAttachment';\nexport { setBrowserStartUrl } from './_browserStage';\nexport { openFilesInTrashMode, setFilesDemoTree } from './_filesShared';\nexport type { FilesDemoNode } from './_filesShared';\nexport type { PdfPreviewData, PdfPreviewHandle } from './_previewStage';\n// Type-only, so this re-export is erased at build and never pulls the module.\nexport type { PdfViewerProps } from './PdfViewer';\nexport type { SpreadsheetPreviewData, SpreadsheetPreviewHandle } from './_spreadsheetStage';\n"]}