PageSourceSearch

https://echeng.com/

html echeng.com collected 2026-10-03 20:17:55 UTC 22,345 bytes, 281 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en">
3<head>
4<meta charset="utf-8">
5<meta name="viewport" content="width=device-width, initial-scale=1">
6<meta name="theme-color" content="#0a0a0a">
7<meta name="color-scheme" content="dark">
8<meta name="apple-mobile-web-app-capable" content="yes">
9<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
10<title>Eric Cheng</title>
11<link rel="manifest" href="/manifest.json">
12<link rel="icon" type="image/svg+xml" href="/api/icon.svg">
13<link rel="apple-touch-icon" href="/api/icon.svg">
14<link rel="alternate" type="application/rss+xml" title="Eric Cheng" href="/feed.xml">
15<link rel="preload" href="/static/montserrat-600.woff2" as="font" type="font/woff2" crossorigin>
16<link rel="preload" href="/static/montserrat-700.woff2" as="font" type="font/woff2" crossorigin>
17<link rel="preload" href="/api/site/config" as="fetch" crossorigin>
18<!-- Leaflet CSS loaded on demand when map view opens -->
19
20<style>@font-face{font-family:Montserrat;font-style:normal;font-weight:600;font-display:swap;src:url(/static/montserrat-600.woff2) format("woff2")}@font-face{font-family:Montserrat;font-style:normal;font-weight:700;font-display:swap;src:url(/static/montserrat-700.woff2) format("woff2")}*,*:before,*:after{box-sizing:border-box;margin:0;padding:0}:root{color-scheme:dark;--bg: #0a0a0a;--surface: #141414;--surface2: #1e1e1e;--text: #e0e0e0;--text-dim: rgba(224,224,224,.5);--text-dimmer: rgba(224,224,224,.3);--accent: #d4a853;--accent-rgb: 212,168,83;--accent-dim: rgba(var(--accent-rgb),.3);--radius: 4px;--nav-height: 56px;--font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif}html{background:var(--bg);color:var(--text);font-family:var(--font);scroll-behavior:smooth;-webkit-text-size-adjust:100%;text-size-adjust:100%}body{min-height:100vh;overflow-x:hidden}.nav{position:fixed;top:0;left:0;right:0;z-index:100;height:var(--nav-height);display:flex;align-items:center;padding:0 24px;gap:24px;transition:background .3s,transform .3s}.nav.scrolled{background:#0a0a0aeb;backdrop-filter:blur(12px)}.nav.hidden{transform:translateY(-100%)}.nav-title{font-family:"Montserrat",var(--font);font-size:22px;font-weight:700;letter-spacing:.075em;text-transform:uppercase;color:var(--text);text-decoration:none;white-space:nowrap;cursor:pointer}.nav-links{display:flex;gap:4px;margin-left:auto}.nav-link{padding:6px 14px;font-size:13px;font-weight:500;color:var(--text-dim);text-decoration:none;border-radius:20px;transition:color .2s,background .2s;cursor:pointer}.nav-link:hover,.nav-link.active{color:var(--text);background:var(--surface2)}.nav-dropdown{position:relative}.nav-dropdown-menu{display:none;position:absolute;top:100%;right:0;margin-top:4px;background:var(--bg);border:1px solid var(--surface2);border-radius:12px;padding:6px 0;min-width:160px;z-index:60;box-shadow:0 8px 24px #00000080}.nav-dropdown.open .nav-dropdown-menu{display:block}.nav-dropdown-item{display:flex;align-items:center;gap:8px;padding:8px 16px;font-size:13px;font-weight:500;color:var(--text-dim);text-decoration:none;cursor:pointer;transition:color .15s,background .15s}.nav-dropdown-item:hover,.nav-dropdown-item.active{color:var(--text);background:var(--surface2)}.nav-dropdown-item kbd{margin-left:auto;font-size:11px;opacity:.4;font-family:inherit}.nav-search-btn{background:none;border:none;color:var(--text-dim);cursor:pointer;padding:6px;font-size:18px;transition:color .2s;flex-shrink:0}.nav-search-btn:hover{color:var(--text)}.nav-hamburger{display:none;background:none;border:none;color:var(--text-dim);cursor:pointer;padding:6px;font-size:22px;line-height:1}.nav-hamburger:hover{color:var(--text)}.search-bar{position:relative;display:flex;align-items:center;background:var(--surface2);border-radius:24px;padding:0 16px;height:36px;flex:1;max-width:240px;min-width:0}.search-bar form{flex:1;min-width:0;display:flex}.search-bar input{flex:1;min-width:0;background:none;border:none;color:var(--text);font-size:14px;outline:none;font-family:var(--font)}.search-bar input::placeholder{color:var(--text-dimmer)}.search-suggestions{position:absolute;top:100%;left:0;right:0;margin-top:4px;background:var(--surface2);border-radius:12px;max-height:280px;overflow-y:auto;display:none;box-shadow:0 8px 32px #00000080;z-index:200}.search-suggestions.open{display:block}.search-suggestion{padding:8px 16px;cursor:pointer;font-size:13px;display:flex;justify-content:space-between;align-items:center;transition:background .15s}.search-suggestion:first-child{border-radius:12px 12px 0 0}.search-suggestion:last-child{border-radius:0 0 12px 12px}.search-suggestion:hover,.search-suggestion.active{background:#ffffff14}.search-suggestion .sug-label{color:var(--text)}.search-suggestion .sug-type{font-size:10px;color:var(--text-dimmer);text-transform:uppercase;letter-spacing:.5px}.filter-chip{padding:5px 14px;font-size:12px;border-radius:16px;background:var(--surface2);color:var(--text-dim);border:1px solid rgba(255,255,255,.06);
20cursor:pointer;transition:all .2s;white-space:nowrap;user-select:none}.filter-chip:hover{color:var(--text);border-color:#ffffff1f}.filter-chip.active{color:var(--accent);border-color:var(--accent-dim);background:rgba(var(--accent-rgb),.08)}.filter-chip .remove{margin-left:6px;opacity:.5}.filter-chip .remove:hover{opacity:1}.filter-select{background:var(--surface2);color:var(--text-dim);border:1px solid rgba(255,255,255,.06);padding:5px 10px;font-size:12px;border-radius:16px;cursor:pointer;font-family:var(--font);outline:none}.filter-select option{background:var(--surface);color:var(--text)}.main{padding-top:var(--nav-height)}.grid{padding:4px 8px;position:relative;overflow:hidden}.grid-row{display:flex;gap:4px;margin-bottom:4px}@keyframes shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}.skeleton-row{display:flex;gap:4px;margin-bottom:4px}.skeleton-item{background:linear-gradient(90deg,var(--surface) 25%,var(--surface2) 50%,var(--surface) 75%);background-size:200% 100%;animation:shimmer 1.5s infinite;border-radius:2px}.grid-item{position:relative;overflow:hidden;cursor:pointer;border-radius:2px;background:var(--surface);-webkit-touch-callout:none;user-select:none;-webkit-tap-highlight-color:transparent}.grid-item img{display:block;width:100%;height:100%;object-fit:cover;transition:opacity .4s;-webkit-touch-callout:none;pointer-events:none}.grid-item img.loading{opacity:0}
21</style>
22<link rel="stylesheet" href="/static/styles.9fc54bd91794.css" media="print" onload="this.media='all'">
23<noscript><link rel="stylesheet" href="/static/styles.9fc54bd91794.css"></noscript>
24<meta name="description" content="Photography portfolio: ERIC CHENG">
25<link rel="canonical" href="https://echeng.com">
26<meta property="og:title" content="ERIC CHENG">
27<meta property="og:description" content="Photography portfolio: ERIC CHENG">
28<meta property="og:url" content="https://echeng.com">
29<meta property="og:type" content="website">
30<meta property="og:locale" content="en_US">
31<meta property="og:site_name" content="ERIC CHENG">
32<meta name="twitter:card" content="summary_large_image">
33<meta name="twitter:title" content="ERIC CHENG">
34<meta name="twitter:description" content="Photography portfolio: ERIC CHENG">
35<meta property="og:image" content="https://echeng.com/img/76adb1762fcd9548d8b697d46e4ec90be4f88946df1da3f0235509768f5038b1/view.webp">
36<meta property="og:image:type" content="image/webp">
37<meta name="twitter:image" content="https://echeng.com/img/76adb1762fcd9548d8b697d46e4ec90be4f88946df1da3f0235509768f5038b1/view.webp">
38<script type="application/ld+json">{"@context":"https://schema.org","@type":"WebSite","name":"ERIC CHENG","url":"https://echeng.com","description":"Photography portfolio: ERIC CHENG","publisher":{"@type":"Person","name":"ERIC CHENG","url":"https://echeng.com","sameAs":[],"knowsAbout":["Photography","Underwater Photography","Wildlife Photography"],"jobTitle":"Photographer"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://echeng.com/?q={search_term_string}"},"query-input":"required name=search_term_string"}}</script>
vendor: 1 bytes, line 38
38
39<script type="application/ld+json">{"@context":"https://schema.org","@type":"Person","name":"ERIC CHENG","url":"https://echeng.com","sameAs":[],"knowsAbout":["Photography","Underwater Photography","Wildlife Photography"],"jobTitle":"Photographer"}</script>
vendor: 64 bytes, lines 39-40
39
40<script async src="https://www.googletagmanager.com/gtag/js?id=
40G-2YBMB0CJQC
vendor: 12 bytes, line 40
40"></script>
41<script>
vendor: 118 bytes, line 41
41window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag('js',new Date());gtag('config','
41G-2YBMB0CJQC
vendor: 3 bytes, line 41
41');
41</script>
41
42</head>
43<body>
44<noscript><h1>ERIC CHENG</h1><h2>Collections</h2><ul><li><a href="/c/all">All Media</a> (4042 photos)</li><li><a href="/c/portfolio">portfolio</a> (94 photos)</li><li><a href="/c/greenland">greenland</a> (81 photos)</li><li><a href="/c/360">360</a> (13 photos)</li><li><a href="/c/gigapixel">gigapixel</a> (1 photos)</li><li><a href="/c/3d">3d</a> (7 photos)</li><li><a href="/c/nature-snow-monkeys">nature-snow-monkeys</a> (38 photos)</li><li><a href="/c/biography">biography</a> (36 photos)</li><li><a href="/c/astrophotography">astrophotography</a> (27 photos)</li><li><a href="/c/event-burning-man">event-burning-man</a> (86 photos)</li><li><a href="/c/event-stankey-kubrick">event-stankey-kubrick</a> (28 photos)</li><li><a href="/c/event-star-wars-exhibit">event-star-wars-exhibit</a> (73 photos)</li><li><a href="/c/topic-drone-days">topic-drone-days</a> (74 photos)</li><li><a href="/c/music">music</a> (69 photos)</li><li><a href="/c/people">people</a> (80 photos)</li><li><a href="/c/in-print">in-print</a> (10 photos)</li></ul></noscript>
45<a href="#main" class="skip-link">Skip to content</a>
46<div class="scroll-progress" id="scrollProgress" role="progressbar" aria-label="Scroll progress"></div>
47
48<!-- Nav -->
49<nav class="nav" id="nav" role="navigation" aria-label="Main navigation">
50  <a class="nav-title" id="siteTitle">ERIC CHENG</a>
51  <button class="nav-hamburger" id="hamburger">&#9776;</button>
52  <div class="nav-links" id="navLinks"></div>
53  <div class="search-bar" id="searchBar">
54    <form id="searchForm" onsubmit="return false"><input type="search" id="searchInput" placeholder="/ search, ? keys" autocomplete="off" maxlength="200" enterkeyhint="search"></form>
55    <div class="search-suggestions" id="searchSuggestions"></div>
56  </div>
57  <button class="nav-search-btn" id="adminBtn" style="display:none">&#x1F512;</button>
58</nav>
59
60<!-- Main content -->
61<main class="main" id="main">
62  <div id="heroContainer"></div>
63  <div class="potd-banner" id="potdBanner" style="display:none"></div>
64  <div id="searchPage" class="search-page" style="display:none"></div>
65  <div id="browsePage" class="search-page" style="display:none"></div>
66  <div class="grid-sort-bar" id="gridSortBar" style="display:none"></div>
67  <div class="grid" id="grid"></div>
68  <div class="empty-state" id="emptyState" style="display:none">
69    <h2>No photos found</h2>
70    <p>Try adjusting your filters or search terms.</p>
71  </div>
72  <div class="content-page about-page" id="aboutPage" style="display:none"></div>
73  <div class="content-page terms-page" id="termsPage" style="display:none"></div>
74  <div class="contact-page" id="contactPage" style="display:none"></div>
75  <div class="stats-page" id="statsPage" style="display:none"></div>
76  <div class="collections-page" id="collectionsPage" style="display:none"></div>
77  <div class="story-page" id="storyPage" style="display:none"></div>
78  <div class="discover-page" id="discoverPage" style="display:none"></div>
79  <div class="tags-page" id="tagsPage" style="display:none"></div>
80  <div class="tags-page" id="camerasPage" style="display:none"></div>
81  <div class="tags-page" id="placesPage" style="display:none"></div>
82  <div class="year-review-page" id="yearReviewPage" style="display:none"></div>
83  <div class="seasons-page" id="seasonsPage" style="display:none"></div>
84  <div class="calendar-page" id="calendarPage" style="display:none"></div>
85</main>
86
87<!-- Persistent Terms link -->
88<div class="terms-link-overlay" id="termsLinkOverlay"><a href="/terms" onclick="event.preventDefault();navigate('/terms')">Terms</a></div>
89
90<!-- Loading -->
91<div class="loading-spinner" id="spinner" style="display:none"></div>
92
93<!-- Gallery Walk -->
94<div class="walk-page" id="walkPage">
95  <button class="walk-close" onclick="closeWalk()" aria-label="Close gallery walk">&times;</button>
96  <div class="walk-strip" id="walkStrip"></div>
97  <div class="walk-counter" id="walkCounter"></div>
98  <div class="walk-hint" id="walkHint">Scroll to browse &middot; Click to view &middot; Esc to close</div>
99</div>
100
101<!-- Detail/Lightbox -->
102<div class="detail-overlay" id="detail" role="dialog" aria-label="Photo detail view" aria-modal="true">
103  <button class="detail-back" id="detailBack" title="Back to grid">&#x2190;</button>
104  <div class="detail-toolbar" id="detailToolbar">
105    <div class="detail-toolbar-center">
106      <button onclick="toggleSlideshow()" id="slideshowBtn" title="Slideshow (S)">&#x25B6; Slideshow</button>
107      <button onclick="toggleDetailFullscreen()" id="detailFullscreenBtn" title="Full Screen (F)">&#x26F6; Full Screen</button>
108      <button onclick="browseRelated()" title="Browse related">&#x2728; Related</button>
109      <button onclick="shareCurrentItem()" title="Share link">&#x1F517; Share</button>
110      <button id="detailDownloadBtn" onclick="toggleDownloadMenu()" title="Download">&#x2B07; Download</button>
111      <button onclick="toggleInfoPanel()" title="Info (I)">&#x2139; Info</button>
112    </div>
113    <div class="detail-toolbar-right">
114      <button class="dz-info-btn" id="dzInfoBtn" onclick="toggleInfoPanel()" title="Info">info</button>
115      <button class="like-btn detail-like" id="detailLikeBtn" title="Like">
116        <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="1" y="12" width="4" height="10" rx="1"/><path d="M7 22h12a2 2 0 002-1.7l1.4-9A2 2 0 0020.4 9H14V5a3 3 0 00-3-3L7 11v11z" stroke-linejoin="round"/><path d="M14.5 15.5h3M14.5 18h2.5" stroke-linecap="round" opacity="0.4"/></svg>
117        <span class="like-count" id="detailLikeCount">0</span>
118      </button>
119      <span class="detail-counter" id="detailCounter"></span>
120      <button id="detailClose" title="Close">&times;</button>
121    </div>
122  </div>
123  <button class="detail-nav prev" id="detailPrev">&#x2039;</button>
124  <button class="detail-nav next" id="detailNext">&#x203A;</button>
125  <div id="detailContent"></div>
126  <div class="detail-swipe-hint"></div>
127  <a class="detail-terms-link" href="/terms" onclick="event.preventDefault();closeDetail();navigate('/terms')">Terms</a>
128</div>
129
130<!-- Admin unlock modal -->
131<div class="admin-modal" id="adminModal">
132  <div class="admin-modal-content">
133    <h3>&#x1F512; Admin Unlock</h3>
134    <p>Enter admin password to unlock full-resolution images.</p>
135    <input type="password" id="adminPassword" placeholder="Password">
136    <div class="error" id="adminError" style="display:none"></div>
137    <div class="btn-row">
138      <button class="btn-cancel" onclick="closeAdminModal()">Cancel</button>
139      <button class="btn-primary" onclick="submitAdminPassword()">Unlock</button>
140    </div>
141  </div>
142</div>
143
144<!-- Unlisted album password gate -->
145<div class="admin-modal" id="albumGateModal">
146  <div class="admin-modal-content">
147    <h3>&#x1F512; <span id="albumGateName">Private album</span></h3>
148    <p>Private album. Password required.</p>
149    <input type="password" id="albumGatePassword" placeholder="Password" onkeydown="if(event.key==='Enter')submitAlbumGate()">
150    <div class="error" id="albumGateError" style="display:none"></div>
151    <div class="btn-row">
152      <button class="btn-cancel" onclick="closeAlbumGate()">Cancel</button>
153      <button class="btn-primary" onclick="submitAlbumGate()">View album</button>
154    </div>
155  </div>
156</div>
157
158<!-- Prefetch links (injected dynamically) -->
159<div id="prefetchContainer" style="display:none"></div>
160<div class="loupe" id="loupe"></div>
161
162<!-- Back to top -->
163<button class="back-to-top" id="backToTop" title="Back to top" onclick="window.scrollTo({top:0,behavior:'smooth'})">&#x2191;</button>
164
165<!-- Info panel -->
166<div class="info-panel" id="infoPanel">
167  <h3>Details</h3>
168  <div id="infoPanelContent"></div>
169</div>
170
171<!-- Slideshow -->
172<div class="slideshow-overlay" id="slideshow">
173  <img class="slideshow-img" id="slideshowImg1">
174  <img class="slideshow-img fade-out" id="slideshowImg2">
175  <div class="slideshow-metadata" id="slideshowMetadata">
176    <div class="slideshow-metadata-caption" id="ssMetaCaption"></div>
177    <div class="slideshow-metadata-meta" id="ssMetaMeta"></div>
178    <div class="slideshow-metadata-exif" id="ssMetaExif"></div>
179  </div>
180  <div class="slideshow-controls-bar" id="ssControls">
181    <button onclick="slideshowPrev()" title="Previous">&#x2039;</button>
182    <button onclick="toggleSlideshowPause()" id="slideshowPlayBtn" title="Play/Pause (Space)">&#x23F8;</button>
183    <button onclick="slideshowNext()" title="Next">&#x203A;</button>
184    <span class="ss-divider"></span>
185    <button onclick="slideshowSlower()" title="Slower (-)">&#x2212;</button>
186    <span class="ss-speed" id="slideshowSpeedLabel">5s</span>
187    <button onclick="slideshowFaster()" title="Faster (+)">+</button>
188    <span class="ss-divider"></span>
189    <label title="Ken Burns animation (A)"><input type="checkbox" id="ssAnimatedToggle" onchange="toggleSlideshowAnimated()" checked> Animated</label>
190    <label title="Show captions (C)"><input type="checkbox" id="ssMetadataToggle" onchange="toggleSlideshowMetadata()"> Captions</label>
191    <span class="ss-divider"></span>
192    <button onclick="toggleSlideshowFullscreen()" id="ssFullscreenBtn" title="Fullscreen (F)">&#x26F6;</button>
193    <span class="ss-counter" id="slideshowCounter"></span>
194    <button onclick="stopSlideshow()" title="Exit (Esc)">&#x2715;</button>
195  </div>
196</div>
197
198<!-- Map view -->
199<div class="map-view" id="mapView">
200  <div id="mapContainer" style="width:100%;height:100%"></div>
201  <div class="map-preview hidden" id="mapPreview">
202    <div class="map-preview-header">
203      <span id="mapPreviewCounter"></span>
204      <button class="map-preview-close" onclick="closeMapPreview()" aria-label="Close">&times;</button>
205    </div>
206    <div class="map-preview-grid" id="mapPreviewGrid"></div>
207    <div class="map-preview-more" id="mapPreviewMore" style="display:none"></div>
208  </div>
209</div>
210
211<!-- Offline banner -->
212<div class="offline-banner" id="offlineBanner">You are offline. Some features may not work.</div>
213
214<!-- Toast container -->
215<div class="toast-container" id="toastContainer"></div>
216
217<!-- Keyboard help -->
218<div class="kb-help" id="kbHelp">
219  <div class="kb-help-content">
220    <h3>Keyboard Shortcuts</h3>
221    <div class="kb-help-section">
222      <h4>Navigation</h4>
223      <div class="kb-row"><span>Home</span><kbd>H</kbd></div>
224      <div class="kb-row"><span>Browse</span><kbd>B</kbd></div>
225      <div class="kb-row"><span>Search</span><kbd>/</kbd></div>
226      <div class="kb-row"><span>Map</span><kbd>M</kbd></div>
227      <div class="kb-row"><span>Surprise</span><kbd>S</kbd></div>
228      <div class="kb-row"><span>About</span><kbd>A</kbd></div>
229      <div class="kb-row"><span>Story</span><kbd>J</kbd></div>
230      <div class="kb-row"><span>Close / Back</span><kbd>Esc</kbd></div>
231      <div class="kb-row"><span>Show this help</span><kbd>?</kbd></div>
232    </div>
233    <div class="kb-help-section">
234      <h4>Grid</h4>
235      <div class="kb-row"><span>Move focus</span><kbd>&larr;</kbd> <kbd>&rarr;</kbd> <kbd>&uarr;</kbd> <kbd>&darr;</kbd></div>
236      <div class="kb-row"><span>Open focused item</span><kbd>Enter</kbd></div>
237      <div class="kb-row"><span>Grid size</span><kbd>[</kbd> <kbd>]</kbd></div>
238      <div class="kb-row"><span>First / Last item</span><kbd>Home</kbd> <kbd>End</kbd></div>
239    </div>
240    <div class="kb-help-section">
241      <h4>Detail View</h4>
242      <div class="kb-row"><span>Previous / Next</span><kbd>&larr;</kbd> <kbd>&rarr;</kbd></div>
243      <div class="kb-row"><span>Info panel</span><kbd>I</kbd></div>
244      <div class="kb-row"><span>Fullscreen</span><kbd>F</kbd></div>
245      <div class="kb-row"><span>Start slideshow</span><kbd>P</kbd></div>
246      <div class="kb-row"><span>Like / unlike</span><kbd>L</kbd></div>
247      <div class="kb-row"><span>Loupe magnifier</span><kbd>Z</kbd></div>
248      <div class="kb-row"><span>Zoom in/out</span><span>Scroll wheel</span></div>
249      <div class="kb-row"><span>Toggle zoom</span><span>Double-click</span></div>
250      <div class="kb-row"><span>Pan (zoomed)</span><span>Click + drag</span></div>
251    </div>
252    <div class="kb-help-section">
253      <h4>Slideshow</h4>
254      <div class="kb-row"><span>Play / Pause</span><kbd>Space</kbd></div>
255      <div class="kb-row"><span>Previous / Next</span><kbd>&larr;</kbd> <kbd>&rarr;</kbd></div>
256      <div class="kb-row"><span>Faster / Slower</span><kbd>+</kbd> <kbd>-</kbd></div>
257      <div class="kb-row"><span>Toggle captions</span><kbd>C</kbd></div>
258      <div class="kb-row"><span>Fullscreen</span><kbd>F</kbd></div>
259      <div class="kb-row"><span>Exit</span><kbd>Esc</kbd></div>
260    </div>
261    <div class="kb-help-section">
262      <h4>Mobile</h4>
263      <div class="kb-row"><span>Next / Previous</span><span>Swipe up / down</span></div>
264      <div class="kb-row"><span>Back to grid</span><span>Swipe right</span></div>
265      <div class="kb-row"><span>Zoom</span><span>Pinch</span></div>
266    </div>
267  </div>
268</div>
269
270<!-- Status bar -->
271<div class="status-bar" id="statusBar"></div>
272
273<!-- Leaflet JS loaded on demand when map view opens -->
274
275<script src="/static/app.4b5e98517ba2.js"></script>
275
276<!-- Cloudflare Web Analytics (privacy-respecting, no cookies) -->
277<!-- Replace beacon token with your real one from Cloudflare dashboard -->
278<!-- 
278<script defer src='https://static.cloudflareinsights.com/beacon.min.js' data-cf-beacon='{"token": "YOUR_TOKEN"}'></script>
278 -->
279<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"c2b34d3bb61d433ca77347e187f7046e","r":1,"spa":2}' crossorigin="anonymous"></script>
279
280</body>
281</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.