1<!DOCTYPE html> 2<html lang="zh-TW" prefix="og: https://ogp.me/ns#"> 3<head> 4 <meta charset="UTF-8" /> 5 <meta name="viewport" content="width=device-width, initial-scale=1" /> 6 7<!-- Rank Math çæå°å¼ææä½³å - https://rankmath.com/ --> 8<meta name="description" content="ODDCAM æ°£å ´ç¸æ©ï¼æå½©è²å ç°å³æçå¨ä½ 身ä¸ââä¸å¿ è·æå½±æ£ï¼ææ©å°±è½æåºåºçæçæ°£å ´ç §ã"/> 9<meta name="robots" content="index, follow, max-snippet:-1, max-video-preview:-1, max-image-preview:large"/> 10<link rel="canonical" href="https://0123456789.tw/oddcam-app/" /> 11<meta property="og:locale" content="zh_TW" /> 12<meta property="og:type" content="article" /> 13<meta property="og:title" content="ODDCAM é主æµç¸æ© - è¨ç®0123456789" /> 14<meta property="og:description" content="ODDCAM æ°£å ´ç¸æ©ï¼æå½©è²å ç°å³æçå¨ä½ 身ä¸ââä¸å¿ è·æå½±æ£ï¼ææ©å°±è½æåºåºçæçæ°£å ´ç §ã" /> 15<meta property="og:url" content="https://0123456789.tw/oddcam-app/" /> 16<meta property="og:site_name" content="è¨ç®0123456789" /> 17<meta property="article:section" content="APPæ¨è¦" /> 18<meta property="og:updated_time" content="2026-07-27T17:17:33+08:00" /> 19<meta property="og:image" content="https://0123456789.tw/wp-content/uploads/2026/07/iShot_2026-07-27_17.17.13.jpg" /> 20<meta property="og:image:secure_url" content="https://0123456789.tw/wp-content/uploads/2026/07/iShot_2026-07-27_17.17.13.jpg" /> 21<meta property="og:image:width" content="383" /> 22<meta property="og:image:height" content="383" /> 23<meta property="og:image:alt" content="ODDCAM é主æµç¸æ©" /> 24<meta property="og:image:type" content="image/jpeg" /> 25<meta property="article:published_time" content="2026-07-27T17:13:24+08:00" /> 26<meta property="article:modified_time" content="2026-07-27T17:17:33+08:00" /> 27<meta name="twitter:card" content="summary_large_image" /> 28<meta name="twitter:title" content="ODDCAM é主æµç¸æ© - è¨ç®0123456789" /> 29<meta name="twitter:description" content="ODDCAM æ°£å ´ç¸æ©ï¼æå½©è²å ç°å³æçå¨ä½ 身ä¸ââä¸å¿ è·æå½±æ£ï¼ææ©å°±è½æåºåºçæçæ°£å ´ç §ã" /> 30<meta name="twitter:image" content="https://0123456789.tw/wp-content/uploads/2026/07/iShot_2026-07-27_17.17.13.jpg" /> 31<meta name="twitter:label1" content="æ°å¯«è " /> 32<meta name="twitter:data1" content="admin" /> 33<meta name="twitter:label2" content="é±è®æé" /> 34<meta name="twitter:data2" content="1 åé" />
35<script type="application/ld+json" class="rank-math-schema">{"@context":"https://schema.org","@graph":[{"@type":["Person","Organization"],"@id":"https://0123456789.tw/#person","name":"\u8a08\u7b970123456789","logo":{"@type":"ImageObject","@id":"https://0123456789.tw/#logo","url":"https://0123456789.tw/wp-content/uploads/2026/05/Gemini_Generated_Image_8ce8uv8ce8uv8ce8-1.png","contentUrl":"https://0123456789.tw/wp-content/uploads/2026/05/Gemini_Generated_Image_8ce8uv8ce8uv8ce8-1.png","caption":"\u8a08\u7b970123456789","inLanguage":"zh-TW","width":"1024","height":"1024"},"image":{"@type":"ImageObject","@id":"https://0123456789.tw/#logo","url":"https://0123456789.tw/wp-content/uploads/2026/05/Gemini_Generated_Image_8ce8uv8ce8uv8ce8-1.png","contentUrl":"https://0123456789.tw/wp-content/uploads/2026/05/Gemini_Generated_Image_8ce8uv8ce8uv8ce8-1.png","caption":"\u8a08\u7b970123456789","inLanguage":"zh-TW","width":"1024","height":"1024"}},{"@type":"WebSite","@id":"https://0123456789.tw/#website","url":"https://0123456789.tw","name":"\u8a08\u7b970123456789","publisher":{"@id":"https://0123456789.tw/#person"},"inLanguage":"zh-TW"},{"@type":"ImageObject","@id":"https://0123456789.tw/wp-content/uploads/2026/07/iShot_2026-07-27_17.17.13.jpg","url":"https://0123456789.tw/wp-content/uploads/2026/07/iShot_2026-07-27_17.17.13.jpg","width":"383","height":"383","inLanguage":"zh-TW"},{"@type":"WebPage","@id":"https://0123456789.tw/oddcam-app/#webpage","url":"https://0123456789.tw/oddcam-app/","name":"ODDCAM \u975e\u4e3b\u6d41\u76f8\u6a5f - \u8a08\u7b970123456789","datePublished":"2026-07-27T17:13:24+08:00","dateModified":"2026-07-27T17:17:33+08:00","isPartOf":{"@id":"https://0123456789.tw/#website"},"primaryImageOfPage":{"@id":"https://0123456789.tw/wp-content/uploads/2026/07/iShot_2026-07-27_17.17.13.jpg"},"inLanguage":"zh-TW"},{"@type":"Person","@id":"https://0123456789.tw/author/admin/","name":"admin","url":"https://0123456789.tw/author/admin/","image":{"@type":"ImageObject","@id":"https://secure.gravatar.com/avatar/bec0ca9a7b38ab92b9c71684df17d45c2357dfee809f1e0facc57bc914a3c046?s=96&d=mm&r=g","url":"https://secure.gravatar.com/avatar/bec0ca9a7b38ab92b9c71684df17d45c2357dfee809f1e0facc57bc914a3c046?s=96&d=mm&r=g","caption":"admin","inLanguage":"zh-TW"},"sameAs":["https://0123456789.tw/blog"]},{"@type":"BlogPosting","headline":"ODDCAM \u975e\u4e3b\u6d41\u76f8\u6a5f - \u8a08\u7b970123456789","datePublished":"2026-07-27T17:13:24+08:00","dateModified":"2026-07-27T17:17:33+08:00","articleSection":"APP\u63a8\u85a6","author":{"@id":"https://0123456789.tw/author/admin/","name":"admin"},"publisher":{"@id":"https://0123456789.tw/#person"},"description":"ODDCAM \u6c23\u5834\u76f8\u6a5f\uff0c\u628a\u5f69\u8272\u5149\u74b0\u5373\u6642\u758a\u5728\u4f60\u8eab\u4e0a\u2014\u2014\u4e0
35d\u5fc5\u8dd1\u651d\u5f71\u68da\uff0c\u624b\u6a5f\u5c31\u80fd\u62cd\u51fa\u5e95\u7247\u611f\u7684\u6c23\u5834\u7167\u3002","name":"ODDCAM \u975e\u4e3b\u6d41\u76f8\u6a5f - \u8a08\u7b970123456789","@id":"https://0123456789.tw/oddcam-app/#richSnippet","isPartOf":{"@id":"https://0123456789.tw/oddcam-app/#webpage"},"image":{"@id":"https://0123456789.tw/wp-content/uploads/2026/07/iShot_2026-07-27_17.17.13.jpg"},"inLanguage":"zh-TW","mainEntityOfPage":{"@id":"https://0123456789.tw/oddcam-app/#webpage"}}]}</script>
35 36<!-- /Rank Math WordPress SEO 夿 --> 37 38<title>ODDCAM é主æµç¸æ© - è¨ç®0123456789</title> 39<link rel='dns-prefetch' href='//news.google.com' /> 40<link rel='dns-prefetch' href='//www.googletagmanager.com' /> 41<link rel='dns-prefetch' href='//pagead2.googlesyndication.com' /> 42<link rel="alternate" type="application/rss+xml" title="è¨é±ãè¨ç®0123456789ã» è³è¨æä¾" href="https://0123456789.tw/feed/" /> 43<link rel="alternate" title="oEmbed (JSON)" type="application/json+oembed" href="https://0123456789.tw/wp-json/oembed/1.0/embed?url=https%3A%2F%2F0123456789.tw%2Foddcam-app%2F" /> 44<link rel="alternate" title="oEmbed (XML)" type="text/xml+oembed" href="https://0123456789.tw/wp-json/oembed/1.0/embed?url=https%3A%2F%2F0123456789.tw%2Foddcam-app%2F&format=xml" /> 45<style id="wp-img-auto-sizes-contain-inline-css"> 46img:is([sizes=auto i],[sizes^="auto," i]){contain-intrinsic-size:3000px 1500px} 47/*# sourceURL=wp-img-auto-sizes-contain-inline-css */ 48</style> 49<style id="wp-block-site-title-inline-css"> 50.wp-block-site-title{box-sizing:border-box}.wp-block-site-title :where(a){color:inherit;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;text-decoration:inherit} 51/*# sourceURL=https://0123456789.tw/wp-includes/blocks/site-title/style.min.css */ 52</style> 53<style id="wp-block-navigation-link-inline-css"> 54.wp-block-navigation .wp-block-navigation-item__label{overflow-wrap:break-word}.wp-block-navigation .wp-block-navigation-item__description{display:none}.link-ui-tools{outline:1px solid #f0f0f0;padding:8px}.link-ui-block-inserter{padding-top:8px}.link-ui-block-inserter__back{margin-left:8px;text-transform:uppercase} 55/*# sourceURL=https://0123456789.tw/wp-includes/blocks/navigation-link/style.min.css */ 56</style> 57<link rel='stylesheet' id='wp-block-navigation-css' href='https://0123456789.tw/wp-includes/blocks/navigation/style.min.css?ver=7.1.2' media='all' /> 58<style id="wp-block-columns-inline-css"> 59.wp-block-columns{box-sizing:border-box;display:flex;flex-wrap:wrap!important}@media (min-width:782px){.wp-block-columns{flex-wrap:nowrap!important}}.wp-block-columns{align-items:normal!important}.wp-block-columns.are-vertically-aligned-top{align-items:flex-start}.wp-block-columns.are-vertically-aligned-center{align-items:center}.wp-block-columns.are-vertically-aligned-bottom{align-items:flex-end}@media (max-width:781px){.wp-block-columns:not(.is-not-stacked-on-mobile)>.wp-block-column{flex-basis:100%!important}}@media (min-width:782px){.wp-block-columns:not(.is-not-stacked-on-mobile)>.wp-block-column{flex-basis:0;flex-grow:1}.wp-block-columns:not(.is-not-stacked-on-mobile)>.wp-block-column[style*=flex-basis]{flex-grow:0}}.wp-block-columns.is-not-stacked-on-mobile{flex-wrap:nowrap!important}.wp-block-columns.is-not-stacked-on-mobile>.wp-block-column{flex-basis:0;flex-grow:1}.wp-block-columns.is-not-stacked-on-mobile>.wp-block-column[style*=flex-basis]{flex-grow:0}:where(.wp-block-columns){margin-bottom:1.75em}:where(.wp-block-columns.has-background){padding:1.25em 2.375em}.wp-block-column{flex-grow:1;min-width:0;overflow-wrap:break-word;word-break:break-word}.wp-block-column.is-vertically-aligned-top{align-self:flex-start}.wp-block-column.is-vertically-aligned-center{align-self:center}.wp-block-column.is-vertically-aligned-bottom{align-self:flex-end}.wp-block-column.is-vertically-aligned-stretch{align-self:stretch}.wp-block-column.is-vertically-aligned-bottom,.wp-block-column.is-vertically-aligned-center,.wp-block-column.is-vertically-aligned-top{width:100%} 60/*# sourceURL=https://0123456789.tw/wp-includes/blocks/columns/style.min.css */ 61</style> 62<style id="wp-block-group-inline-css"> 63.wp-block-group{box-sizing:border-box}:where(.wp-block-group.wp-block-group-is-layout-constrained){position:relative} 64/*# sourceURL=https://0123456789.tw/wp-includes/blocks/group/style.min.css */ 65</style> 66<style id="wp-block-spacer-inline-css"> 67.wp-block-spacer{clear:both} 68/*# sourceURL=https://0123456789.tw/wp-includes/blocks/spacer/style.min.css */ 69</style> 70<style id="wp-block-post-terms-inline-css"> 71.wp-block-post-terms{box-sizing:border-box}.wp-block-post-terms .wp-block-post-terms__separator{white-space:pre-wrap} 72/*# sourceURL=https://0123456789.tw/wp-includes/blocks/post-terms/style.min.css */ 73</style> 74<style id="wp-block-paragraph-inline-css"> 75.is-small-text{font-size:.875em}.is-regular-text{font-size:1em}.is-large-text{font-size:2.25em}.is-larger-text{font-size:3em}.has-drop-cap:not(:focus):first-letter{float:left;font-size:8.4em;font-style:normal;font-weight:100;line-height:.68;margin:.05em .1em 0 0;text-transform:uppercase}body.rtl .has-drop-cap:not(:focus):first-letter{float:none;margin-left:.1em}p.has-drop-cap.has-background{overflow:hidden}:root :where(p.has-background){padding:1.25em 2.375em}:where(p.has-text-color:not(.has-link-color)) a{color:inherit}p.has-text-align-left[style*="writing-mode:vertical-lr"],p.has-text-align-right[style*="writing-mode:vertical-rl"]{rotate:180deg} 76/*# sourceURL=https://0123456789.tw/wp-includes/blocks/paragraph/style.min.css */ 77</style> 78<style id="wp-block-post-author-name-inline-css"> 79.wp-block-post-author-name{box-sizing:border-box} 80/*# sourceURL=https://0123456789.tw/wp-includes/blocks/post-author-name/style.min.css */ 81</style> 82<style id="wp-block-post-date-inline-css"> 83.wp-block-post-date{box-sizing:border-box} 84/*# sourceURL=https://0123456789.tw/wp-includes/blocks/post-date/style.min.css */ 85</style> 86<style id="wp-block-post-title-inline-css"> 87.wp-block-post-title{box-sizing:border-box;word-break:break-word}.wp-block-post-title :where(a){display:inline-block;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;line-height:inherit;text-decoration:inherit} 88/*# sourceURL=https://0123456789.tw/wp-includes/blocks/post-title/style.min.css */ 89</style> 90<style id="wp-block-post-content-inline-css"> 91.wp-block-post-content{display:flow-root} 92/*# sourceURL=https://0123456789.tw/wp-includes/blocks/post-content/style.min.css */ 93</style> 94<style id="wp-block-social-links-inline-css"> 95.wp-block-social-links{background:none;box-sizing:border-box;margin-left:0;padding-left:0;padding-right:0;text-indent:0}.wp-block-social-links .wp-social-link a,.wp-block-social-links .wp-social-link a:hover{border-bottom:0;box-shadow:none;text-decoration:none}.wp-block-social-links .wp-social-link svg{height:1em;width:1em}.wp-block-social-links .wp-social-link span:not(.screen-reader-text){font-size:.65em;margin-left:.5em;margin-right:.5em}.wp-block-social-links.has-small-icon-size{font-size:16px}.wp-block-social-links,.wp-block-social-links.has-normal-icon-size{font-size:24px}.wp-block-social-links.has-large-icon-size{font-size:36px}.wp-block-social-links.has-huge-icon-size{font-size:48px}.wp-block-social-links.aligncenter{display:flex;justify-content:center}.wp-block-social-links.alignright{justify-content:flex-end}.wp-block-social-link{border-radius:9999px;display:block}@media not (prefers-reduced-motion){.wp-block-social-link{transition:transform .1s ease}}.wp-block-social-link{height:auto}.wp-block-social-link a{align-items:center;display:flex;line-height:0}.wp-block-social-link:hover{transform:scale(1.1)}.wp-block-social-links .wp-block-social-link.wp-social-link{display:inline-block;margin:0;padding:0}.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor,.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor svg,.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor:active,.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor:hover,.wp-block-social-links .wp-block-social-link.wp-social-link .wp-block-social-link-anchor:visited{fill:currentColor;color:currentColor}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link{background-color:#f0f0f0;color:#444}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-amazon{background-color:#f90;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-bandcamp{background-color:#1ea0c3;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-behance{background-color:#0757fe;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-bluesky{background-color:#0a7aff;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-codepen{background-color:#1e1f26;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-deviantart{background-color:#02e49b;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-discord{background-color:#5865f2;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-dribbble{background-color:#e94c89;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-dropbox{background-color:#4280ff;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-etsy{background-color:#f45800;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-facebook{background-color:#0866ff;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-fivehundredpx{background-color:#000;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-flickr{background-color:#0461dd;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-foursquare{background-color:#e65678;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-github{background-color:#24292d;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-goodreads{background-color:#eceadd;color:#382110}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-google{background-color:#ea4434;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-gravatar{background-color:#1d4fc4;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-instagram{background-color:#f00075;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-lastfm{background-color:#e21b24;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-linkedin{background-color:#0d66c2;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-mastodon{background-color:#3288d4;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-medium{background-color:#000;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-meetup{background-color:#f6405f;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-patreon{background-color:#000;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-pinterest{background-color:#e60122;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-pocket{background-color:#ef4155;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-reddit{background-color:#ff4500;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-skype{background-color:#0478d7;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-snapchat{stroke:#000;background-color:#fefc00;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-soundcloud{background-color:#ff5600;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-spotify{background-color:#1bd760;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-telegram{background-color:#2aabee;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-threads{background-color:#000;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-tiktok{background-color:#000;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-tumblr{background-color:#011835;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-twitch{background-color:#6440a4;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-twitter{background-color:#1da1f2;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-vimeo{background-color:#1eb7ea;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-vk{background-color:#4680c2;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-wordpress{background-color:#3499cd;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-whatsapp{background-color:#25d366;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-x{background-color:#000;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-yelp{background-color:#d32422;color:#fff}:where(.wp-block-social-links:not(.is-style-logos-only)) .wp-social-link-youtube{background-color:red;color:#fff}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link{background:none}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link svg{height:1.25em;width:1.25em}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-amazon{color:#f90}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-bandcamp{color:#1ea0c3}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-behance{color:#0757fe}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-bluesky{color:#0a7aff}
95:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-codepen{color:#1e1f26}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-deviantart{color:#02e49b}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-discord{color:#5865f2}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-dribbble{color:#e94c89}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-dropbox{color:#4280ff}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-etsy{color:#f45800}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-facebook{color:#0866ff}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-fivehundredpx{color:#000}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-flickr{color:#0461dd}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-foursquare{color:#e65678}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-github{color:#24292d}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-goodreads{color:#382110}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-google{color:#ea4434}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-gravatar{color:#1d4fc4}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-instagram{color:#f00075}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-lastfm{color:#e21b24}
95:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-linkedin{color:#0d66c2}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-mastodon{color:#3288d4}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-medium{color:#000}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-meetup{color:#f6405f}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-patreon{color:#000}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-pinterest{color:#e60122}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-pocket{color:#ef4155}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-reddit{color:#ff4500}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-skype{color:#0478d7}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-snapchat{stroke:#000;color:#fff}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-soundcloud{color:#ff5600}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-spotify{color:#1bd760}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-telegram{color:#2aabee}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-threads{color:#000}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-tiktok{color:#000}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-tumblr{color:#011835}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-twitch{color:#6440a4}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-twitter{color:#1da1f2}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-vimeo{color:#1eb7ea}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-vk{color:#4680c2}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-whatsapp{color:#25d366}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-wordpress{color:#3499cd}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-x{color:#000}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-yelp{color:#d32422}:where(.wp-block-social-links.is-style-logos-only) .wp-social-link-youtube{color:red}.wp-block-social-links.is-style-pill-shape .wp-social-link{width:auto}:root :where(.wp-block-social-links .wp-social-link a){padding:.25em}:root :where(.wp-block-social-links.is-style-logos-only .wp-social-link a){padding:0}:root :where(.wp-block-social-links.is-style-pill-shape .wp-social-link a){padding-left:.6666666667em;padding-right:.6666666667em}.wp-block-social-links:not(.has-icon-color):not(.has-icon-background-color) .wp-social-link-snapchat .wp-block-social-link-label{color:#000} 96/*# sourceURL=https://0123456789.tw/wp-includes/blocks/social-links/style.min.css */ 97</style> 98<style id="wp-emoji-styles-inline-css"> 99 100 img.wp-smiley, img.emoji { 101 display: inline !important; 102 border: none !important; 103 box-shadow: none !important; 104 height: 1em !important; 105 width: 1em !important; 106 margin: 0 0.07em !important; 107 vertical-align: -0.1em !important; 108 background: none !important; 109 padding: 0 !important; 110 } 111/*# sourceURL=wp-emoji-styles-inline-css */ 112</style> 113<style id="wp-block-library-inline-css"> 114:root{--wp-block-synced-color:#7a00df;--wp-block-synced-color--rgb:122,0,223;--wp-bound-block-color:var(--wp-block-synced-color);--wp-editor-canvas-background:#ddd;--wp-admin-theme-color:#007cba;--wp-admin-theme-color--rgb:0,124,186;--wp-admin-theme-color-darker-10:#006ba1;--wp-admin-theme-color-darker-10--rgb:0,107,160.5;--wp-admin-theme-color-darker-20:#005a87;--wp-admin-theme-color-darker-20--rgb:0,90,135;--wp-admin-border-width-focus:2px}@media (min-resolution:192dpi){:root{--wp-admin-border-width-focus:1.5px}}.wp-element-button{cursor:pointer}:root .has-very-light-gray-background-color{background-color:#eee}:root .has-very-dark-gray-background-color{background-color:#313131}:root .has-very-light-gray-color{color:#eee}:root .has-very-dark-gray-color{color:#313131}:root .has-vivid-green-cyan-to-vivid-cyan-blue-gradient-background{background:linear-gradient(135deg,#00d084,#0693e3)}:root .has-purple-crush-gradient-background{background:linear-gradient(135deg,#34e2e4,#4721fb 50%,#ab1dfe)}:root .has-hazy-dawn-gradient-background{background:linear-gradient(135deg,#faaca8,#dad0ec)}:root .has-subdued-olive-gradient-background{background:linear-gradient(135deg,#fafae1,#67a671)}:root .has-atomic-cream-gradient-background{background:linear-gradient(135deg,#fdd79a,#004a59)}:root .has-nightshade-gradient-background{background:linear-gradient(135deg,#330968,#31cdcf)}:root .has-midnight-gradient-background{background:linear-gradient(135deg,#020381,#2874fc)}:root{--wp--preset--font-size--normal:16px;
114--wp--preset--font-size--huge:42px}.has-regular-font-size{font-size:1em}.has-larger-font-size{font-size:2.625em}.has-normal-font-size{font-size:var(--wp--preset--font-size--normal)}.has-huge-font-size{font-size:var(--wp--preset--font-size--huge)}:root .has-text-align-center{text-align:center}:root .has-text-align-left{text-align:left}:root .has-text-align-right{text-align:right}.has-fit-text{white-space:nowrap!important}#end-resizable-editor-section{display:none}.aligncenter{clear:both}.items-justified-left{justify-content:flex-start}.items-justified-center{justify-content:center}.items-justified-right{justify-content:flex-end}.items-justified-space-between{justify-content:space-between}.screen-reader-text{word-wrap:normal!important;border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px;word-break:normal!important}.screen-reader-text:focus{background-color:#ddd;clip-path:none;color:#444;display:block;font-size:1em;height:auto;left:5px;line-height:normal;padding:15px 23px 14px;text-decoration:none;top:5px;width:auto;z-index:100000}html :where(.has-border-color){border-style:solid}html :where([style^=border-color],[style*=";border-color"],[style*="; border-color"]){border-style:solid}html :where([style^=border-top-color],[style*=";border-top-color"],[style*="; border-top-color"]){border-top-style:solid}html :where([style^=border-right-color],[style*=";border-right-color"],[style*="; border-right-color"]){border-right-style:solid}html :where([style^=border-bottom-color],[style*=";border-bottom-color"],[style*="; border-bottom-color"]){border-bottom-style:solid}html :where([style^=border-left-color],[style*=";border-left-color"],[style*="; border-left-color"]){border-left-style:solid}html :where([style^=border-width],[style*=";border-width"],[style*="; border-width"]){border-style:solid}html :where([style^=border-top-width],[style*=";border-top-width"],[style*="; border-top-width"]){border-top-style:solid}html :where([style^=border-right-width],[style*=";border-right-width"],[style*="; border-right-width"]){border-right-style:solid}html :where([style^=border-bottom-width],[style*=";border-bottom-width"],[style*="; border-bottom-width"]){border-bottom-style:solid}html :where([style^=border-left-width],[style*=";border-left-width"],[style*="; border-left-width"]){border-left-style:solid}html :where(img[class*=wp-image-]){height:auto;max-width:100%}:where(figure){margin:0 0 1em}html :where(.is-position-sticky){--wp-admin--admin-bar--position-offset:var(--wp-admin--admin-bar--height,0px)}@media screen and (max-width:600px){html :where(.is-position-sticky){--wp-admin--admin-bar--position-offset:0px}} 115/*# sourceURL=/wp-includes/css/dist/block-library/common.min.css */ 116</style> 117<style id="global-styles-inline-css"> 118:root{--wp--preset--aspect-ratio--square: 1;--wp--preset--aspect-ratio--4-3: 4/3;--wp--preset--aspect-ratio--3-4: 3/4;--wp--preset--aspect-ratio--3-2: 3/2;--wp--preset--aspect-ratio--2-3: 2/3;--wp--preset--aspect-ratio--16-9: 16/9;--wp--preset--aspect-ratio--9-16: 9/16;--wp--preset--color--black: #000000;--wp--preset--color--cyan-bluish-gray: #abb8c3;--wp--preset--color--white: #ffffff;--wp--preset--color--pale-pink: #f78da7;--wp--preset--color--vivid-red: #cf2e2e;--wp--preset--color--luminous-vivid-orange: #ff6900;--wp--preset--color--luminous-vivid-amber: #fcb900;--wp--preset--color--light-green-cyan: #7bdcb5;--wp--preset--color--vivid-green-cyan: #00d084;--wp--preset--color--pale-cyan-blue: #8ed1fc;--wp--preset--color--vivid-cyan-blue: #0693e3;--wp--preset--color--vivid-purple: #9b51e0;--wp--preset--color--primary: #000000;--wp--preset--color--secondary: #767676;--wp--preset--color--foreground: #000000;--wp--preset--color--background: #f8f8f8;--wp--preset--color--tertiary: #e6e6e6;--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple: linear-gradient(135deg,rgb(6,147,227) 0%,rgb(155,81,224) 100%);--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan: linear-gradient(135deg,rgb(122,220,180) 0%,rgb(0,208,130) 100%);--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange: linear-gradient(135deg,rgb(252,185,
1180) 0%,rgb(255,105,0) 100%);--wp--preset--gradient--luminous-vivid-orange-to-vivid-red: linear-gradient(135deg,rgb(255,105,0) 0%,rgb(207,46,46) 100%);--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray: linear-gradient(135deg,rgb(238,238,238) 0%,rgb(169,184,195) 100%);--wp--preset--gradient--cool-to-warm-spectrum: linear-gradient(135deg,rgb(74,234,220) 0%,rgb(151,120,209) 20%,rgb(207,42,186) 40%,rgb(238,44,130) 60%,rgb(251,105,98) 80%,rgb(254,248,76) 100%);--wp--preset--gradient--blush-light-purple: linear-gradient(135deg,rgb(255,206,236) 0%,rgb(152,150,240) 100%);--wp--preset--gradient--blush-bordeaux: linear-gradient(135deg,rgb(254,205,165) 0%,rgb(254,45,45) 50%,rgb(107,0,62) 100%);--wp--preset--gradient--luminous-dusk: linear-gradient(135deg,rgb(255,203,112) 0%,rgb(199,81,192) 50%,rgb(65,88,208) 100%);--wp--preset--gradient--pale-ocean: linear-gradient(135deg,rgb(255,245,203) 0%,rgb(182,227,212) 50%,rgb(51,167,181) 100%);--wp--preset--gradient--electric-grass: linear-gradient(135deg,rgb(202,248,128) 0%,rgb(113,206,126) 100%);--wp--preset--gradient--midnight: linear-gradient(135deg,rgb(2,3,129) 0%,rgb(40,116,252) 100%);--wp--preset--font-size--small: clamp(0.825rem, 0.825rem + ((1vw - 0.2rem) * 0.56), 1.0625rem);--wp--preset--font-size--medium: clamp(1rem, 1rem + ((1vw - 0.2rem) * 0.588), 1.25rem);--wp--preset--font-size--large: clamp(1.75rem, 1.75rem + ((1vw - 0.2rem) * 0.588), 2rem);--wp--preset--font-size--x-large: clamp(2.5rem, 2.5rem + ((1vw - 0.2rem) * 1.176), 3rem);--wp--preset--font-family--system-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif;--wp--preset--font-family--epilogue: Epilogue;--wp--preset--font-family--sora: Sora;--wp--preset--font-family--albert-sans: Albert Sans;--wp--preset--spacing--20: 0.44rem;--wp--preset--spacing--30: 0.67rem;--wp--preset--spacing--40: 1rem;--wp--preset--spacing--50: 1.5rem;--wp--preset--spacing--60: 2.25rem;--wp--preset--spacing--70: 3.38rem;--wp--preset--spacing--80: 5.06rem;--wp--preset--shadow--natural: 6px 6px 9px rgba(0, 0, 0, 0.2);--wp--preset--shadow--deep: 12px 12px 50px rgba(0, 0, 0, 0.4);--wp--preset--shadow--sharp: 6px 6px 0px rgba(0, 0, 0, 0.2);--wp--preset--shadow--outlined: 6px 6px 0px -3px rgb(255, 255, 255), 6px 6px rgb(0, 0, 0);--wp--preset--shadow--crisp: 6px 6px 0px rgb(0, 0, 0);}.wp-block-button{--wp--preset--dimension--25: 25%;--wp--preset--dimension--50: 50%;--wp--preset--dimension--75: 75%;--wp--preset--dimension--100: 100%;}:root { --wp--style--global--content-size: 620px;--wp--style--global--wide-size: 1000px; }:where(body) { margin: 0; }.wp-site-blocks { padding-top: var(--wp--style--root--padding-top); padding-bottom: var(--wp--style--root--padding-bottom); }.has-global-padding { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); }.has-global-padding > .alignfull { margin-right: calc(var(--wp--style--root--padding-right) * -1); margin-left: calc(var(--wp--style--root--padding-left) * -1); }.has-global-padding :where(:not(.alignfull.is-layout-flow) > .has-global-padding:not(.wp-block-block, .alignfull)) { padding-right: 0; padding-left: 0; }.has-global-padding :where(:not(.alignfull.is-layout-flow) > .has-global-padding:not(.wp-block-block, .alignfull)) > .alignfull { margin-left: 0; margin-right: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.wp-site-blocks) > * { margin-block-start: 1.5rem; margin-block-end: 0; }:where(.wp-site-blocks) > :first-child { margin-block-start: 0; }:where(.wp-site-blocks) > :last-child { margin-block-end: 0; }:root { --wp--style--block-gap: 1.5rem; }:root :where(.is-layout-flow) > :first-child{margin-block-start: 0;}:root :where(.is-layout-flow) > :last-child{margin-block-end: 0;}:root :where(.is-layout-flow) > *{margin-block-start: 1.5rem;margin-block-end: 0;}:root :where(.is-layout-constrained) > :first-child{margin-block-start: 0;}:root :where(.is-layout-constrained) > :last-child{margin-block-end: 0;}:root :where(.is-layout-constrained) > *{margin-block-start: 1.5rem;margin-block-end: 0;}:root :where(.is-layout-flex){gap: 1.5rem;}:root :where(.is-layout-grid){gap: 1.5rem;}.is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}.is-layout-constrained > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}.is-layout-constrained > .aligncenter{margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained >
118 :where(:not(.alignleft):not(.alignright):not(.alignfull)){max-width: var(--wp--style--global--content-size);margin-left: auto !important;margin-right: auto !important;}.is-layout-constrained > .alignwide{max-width: var(--wp--style--global--wide-size);}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}body{background-color: var(--wp--preset--color--background);color: var(--wp--preset--color--foreground);font-family: var(--wp--preset--font-family--epilogue);font-size: clamp(0.918rem, 0.918rem + ((1vw - 0.2rem) * 1.087), 1.38rem);font-style: normal;font-weight: 300;line-height: 1.6;--wp--style--root--padding-top: 0;--wp--style--root--padding-right: 0;--wp--style--root--padding-bottom: 0;--wp--style--root--padding-left: 0;}a:where(:not(.wp-element-button)){color: var(--wp--preset--color--primary);}:root :where(a:where(:not(.wp-element-button)):hover){text-decoration: none;}h1, h2, h3, h4, h5, h6{font-style: normal;font-weight: 300;letter-spacing: -0.02em;line-height: 1.3;}h1{font-size: var(--wp--preset--font-size--x-large);}h2{font-size: var(--wp--preset--font-size--large);}h3{font-size: clamp(1.188rem, 1.188rem + ((1vw - 0.2rem) * 1.628), 1.88rem);}h4{font-size: clamp(1.055rem, 1.055rem + ((1vw - 0.2rem) * 1.353), 1.63rem);}h5{font-size: clamp(0.918rem, 0.918rem + ((1vw - 0.2rem) * 1.087), 1.38rem);}h6{font-size: clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 0.882), 1.25rem);}:root :where(.wp-element-button, .wp-block-button__link){background-color: var(--wp--preset--color--primary);border-radius: 0.25rem;border-width: 0;color: var(--wp--preset--color--background);font-family: inherit;font-size: clamp(0.918rem, 0.918rem + ((1vw - 0.2rem) * 1.087), 1.38rem);font-style: inherit;font-weight: inherit;letter-spacing: inherit;line-height: inherit;padding-top: calc(0.667em + 2px);padding-right: calc(1.333em + 2px);padding-bottom: calc(0.667em + 2px);padding-left: calc(1.333em + 2px);text-decoration: none;text-transform: inherit;}:root :where(.wp-element-button:hover, .wp-block-button__link:hover){background-color: var(--wp--preset--color--secondary);color: var(--wp--preset--color--background);}:root :where(.wp-element-button:focus, .wp-block-button__link:focus){background-color: var(--wp--preset--color--primary);color: var(--wp--preset--color--background);outline-color: var(--wp--preset--color--primary);outline-offset: 2px;outline-style: dotted;outline-width: 1px;}:root :where(.wp-element-button:active, .wp-block-button__link:active){background-color: var(--wp--preset--color--primary);color: var(--wp--preset--color--background);}.has-black-color{color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-color{color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-color{color: var(--wp--preset--color--white) !important;}.has-pale-pink-color{color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-color{color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-color{color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-color{color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-color{color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-color{color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-color{color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-color{color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-color{color: var(--wp--preset--color--vivid-purple) !important;}.has-primary-color{color: var(--wp--preset--color--primary) !important;}.has-secondary-color{color: var(--wp--preset--color--secondary) !important;}.has-foreground-color{color: var(--wp--preset--color--foreground) !important;}.has-background-color{color: var(--wp--preset--color--background) !important;}.has-tertiary-color{color: var(--wp--preset--color--tertiary) !important;}.has-black-background-color{background-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-background-color{background-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}.has-pale-pink-background-color{background-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-background-color{background-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-background-color{background-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-background-color{background-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-background-color{background-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-background-color{background-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-background-color{background-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-background-color{background-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-background-color{background-color: var(--wp--preset--color--vivid-purple) !important;}.has-primary-background-color{background-color: var(--wp--preset--color--primary) !important;}.has-secondary-background-color{background-color: var(--wp--preset--color--secondary) !important;}.has-foreground-background-color{background-color: var(--wp--preset--color--foreground) !important;}.has-background-background-color{background-color: var(--wp--preset--color--background) !important;}.has-tertiary-background-color{background-color: var(--wp--preset--color--tertiary) !important;}.has-black-border-color{border-color: var(--wp--preset--color--black) !important;}.has-cyan-bluish-gray-border-color{border-color: var(--wp--preset--color--cyan-bluish-gray) !important;}.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}.has-pale-pink-border-color{border-color: var(--wp--preset--color--pale-pink) !important;}.has-vivid-red-border-color{border-color: var(--wp--preset--color--vivid-red) !important;}.has-luminous-vivid-orange-border-color{border-color: var(--wp--preset--color--luminous-vivid-orange) !important;}.has-luminous-vivid-amber-border-color{border-color: var(--wp--preset--color--luminous-vivid-amber) !important;}.has-light-green-cyan-border-color{border-color: var(--wp--preset--color--light-green-cyan) !important;}.has-vivid-green-cyan-border-color{border-color: var(--wp--preset--color--vivid-green-cyan) !important;}.has-pale-cyan-blue-border-color{border-color: var(--wp--preset--color--pale-cyan-blue) !important;}.has-vivid-cyan-blue-border-color{border-color: var(--wp--preset--color--vivid-cyan-blue) !important;}.has-vivid-purple-border-color{border-color: var(--wp--preset--color--vivid-purple) !important;}.has-primary-border-color{border-color: var(--wp--preset--color--primary) !important;}.has-secondary-border-color{border-color: var(--wp--preset--color--secondary) !important;}.has-foreground-border-color{border-color: var(--wp--preset--color--foreground) !important;}.has-background-border-color{border-color: var(--wp--preset--color--background) !important;}.has-tertiary-border-color{border-color: var(--wp--preset--color--tertiary) !important;}.has-vivid-cyan-blue-to-vivid-purple-gradient-background{background: var(--wp--preset--gradient--vivid-cyan-blue-to-vivid-purple) !important;}.has-light-green-cyan-to-vivid-green-cyan-gradient-background{background: var(--wp--preset--gradient--light-green-cyan-to-vivid-green-cyan) !important;}.has-luminous-vivid-amber-to-luminous-vivid-orange-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-amber-to-luminous-vivid-orange) !important;}.has-luminous-vivid-orange-to-vivid-red-gradient-background{background: var(--wp--preset--gradient--luminous-vivid-orange-to-vivid-red) !important;}
118.has-very-light-gray-to-cyan-bluish-gray-gradient-background{background: var(--wp--preset--gradient--very-light-gray-to-cyan-bluish-gray) !important;}.has-cool-to-warm-spectrum-gradient-background{background: var(--wp--preset--gradient--cool-to-warm-spectrum) !important;}.has-blush-light-purple-gradient-background{background: var(--wp--preset--gradient--blush-light-purple) !important;}.has-blush-bordeaux-gradient-background{background: var(--wp--preset--gradient--blush-bordeaux) !important;}.has-luminous-dusk-gradient-background{background: var(--wp--preset--gradient--luminous-dusk) !important;}.has-pale-ocean-gradient-background{background: var(--wp--preset--gradient--pale-ocean) !important;}.has-electric-grass-gradient-background{background: var(--wp--preset--gradient--electric-grass) !important;}.has-midnight-gradient-background{background: var(--wp--preset--gradient--midnight) !important;}.has-small-font-size{font-size: var(--wp--preset--font-size--small) !important;}.has-medium-font-size{font-size: var(--wp--preset--font-size--medium) !important;}.has-large-font-size{font-size: var(--wp--preset--font-size--large) !important;}.has-x-large-font-size{font-size: var(--wp--preset--font-size--x-large) !important;}.has-system-font-font-family{font-family: var(--wp--preset--font-family--system-font) !important;}.has-epilogue-font-family{font-family: var(--wp--preset--font-family--epilogue) !important;}.has-sora-font-family{font-family: var(--wp--preset--font-family--sora) !important;}.has-albert-sans-font-family{font-family: var(--wp--preset--font-family--albert-sans) !important;} 119:root :where(.wp-block-navigation){font-size: clamp(0.918rem, 0.918rem + ((1vw - 0.2rem) * 1.087), 1.38rem);font-style: normal;font-weight: 300;} 120:root :where(.wp-block-navigation a:where(:not(.wp-element-button))){text-decoration: none;} 121:root :where(.wp-block-navigation a:where(:not(.wp-element-button)):hover){text-decoration: underline;} 122:root :where(p){letter-spacing: -0.01em;} 123:root :where(.wp-block-post-author-name a:where(:not(.wp-element-button))){text-decoration: none;} 124:root :where(.wp-block-post-author-name a:where(:not(.wp-element-button)):hover){text-decoration: underline;} 125:root :where(.wp-block-post-date){color: var(--wp--preset--color--foreground);font-size: clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 0.153), 0.94rem);} 126:root :where(.wp-block-post-date a:where(:not(.wp-element-button))){text-decoration: none;} 127:root :where(.wp-block-post-date a:where(:not(.wp-element-button)):hover){text-decoration: underline;} 128:root :where(.wp-block-post-terms){font-size: clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 0.059), 0.9rem);} 129:root :where(.wp-block-post-title){font-size: var(--wp--preset--font-size--x-large);margin-bottom: 0;} 130:root :where(.wp-block-post-title a:where(:not(.wp-element-button))){text-decoration: none;} 131:root :where(.wp-block-post-title a:where(:not(.wp-element-button)):hover){text-decoration: underline;} 132:root :where(.wp-block-site-title){font-size: var(--wp--preset--font-size--medium);font-style: normal;font-weight: 300;} 133:root :where(.wp-block-site-title a:where(:not(.wp-element-button))){text-decoration: none;} 134:root :where(.wp-block-site-title a:where(:not(.wp-element-button)):hover){text-decoration: underline;} 135/*# sourceURL=global-styles-inline-css */ 136</style> 137<style id="core-block-supports-inline-css"> 138.wp-elements-1 a:where(:not(.wp-element-button)){color:var(--wp--preset--color--vivid-red);}.wp-container-core-navigation-is-layout-b4ebd6b9{gap:0;justify-content:flex-end;}.wp-container-core-columns-is-layout-920ca8ee{flex-wrap:nowrap;}.wp-container-core-group-is-layout-6030d204 > .alignfull{margin-right:calc(0px * -1);margin-left:calc(0px * -1);}.wp-elements-2 a:where(:not(.wp-element-button)){color:var(--wp--preset--color--secondary);}.wp-container-core-group-is-layout-98ce8303{flex-wrap:nowrap;gap:0.2em;}.wp-elements-3 a:where(:not(.wp-element-button)){color:var(--wp--preset--color--secondary);}.wp-container-core-group-is-layout-65c64987{gap:var(--wp--preset--spacing--20);}.wp-container-core-group-is-layout-f13622a0{gap:var(--wp--preset--spacing--40);flex-direction:column;align-items:flex-start;}.wp-container-core-columns-is-layout-c9a8b3e2{flex-wrap:nowrap;}.wp-container-core-columns-is-layout-6a1dc368{flex-wrap:nowrap;}
138.wp-elements-4 a:where(:not(.wp-element-button)){color:var(--wp--preset--color--secondary);}.wp-container-core-group-is-layout-87abe617{gap:var(--wp--preset--spacing--30);flex-direction:column;align-items:flex-start;}.wp-container-core-columns-is-layout-d7fd2005{flex-wrap:nowrap;}.wp-container-core-columns-is-layout-9bfe848c{flex-wrap:nowrap;}.wp-container-core-columns-is-layout-6ec0cbd9{flex-wrap:nowrap;}.wp-container-core-columns-is-layout-f56f613f{flex-wrap:nowrap;} 139/*# sourceURL=core-block-supports-inline-css */ 140</style> 141<style id="wp-block-template-skip-link-inline-css"> 142/*! This file is auto-generated */ 143.skip-link.screen-reader-text{border:0;clip-path:inset(50%);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute!important;width:1px;word-wrap:normal!important;word-break:normal!important}.skip-link.screen-reader-text:focus{background-color:#eee;clip-path:none;color:#444;display:block;font-size:1em;height:auto;left:5px;line-height:normal;padding:15px 23px 14px;text-decoration:none;top:5px;width:auto;z-index:100000} 144/*# sourceURL=/wp-includes/css/wp-block-template-skip-link.min.css */ 145</style> 146<link rel='stylesheet' id='fewer-style-css' href='https://0123456789.tw/wp-content/themes/fewer/style.css?ver=1.0.4' media='all' /> 147 148<!-- Google tag (gtag.js) snippet added by Site Kit --> 149<!-- Google Analytics snippet added by Site Kit -->
vendor: 80 bytes, lines 149-150
149 150<script id="google_gtagjs-js" src="https://www.googletagmanager.com/gtag/js?id=
150G-C0F95TX1P2
vendor: 18 bytes, line 150
150" async></script>
151<script id="google_gtagjs-js-after"> 152window.dataLayer = window.dataLayer || [];function gtag(){dataLayer.push(arguments);} 153gtag("set","linker",{"domains":["0123456789.tw"]}); 154gtag("js", new Date()); 155gtag("set", "developer_id.dZTNiMT", true); 156gtag("config", "G-C0F95TX1P2", {"googlesitekit_post_type":"post","googlesitekit_post_date":"20260727","googlesitekit_post_categories":"APP\u63a8\u85a6"}); 157 window._googlesitekit = window._googlesitekit || {}; window._googlesitekit.throttledEvents = []; window._googlesitekit.gtagEvent = (name, data) => { var key = JSON.stringify( { name, data } ); if ( !! window._googlesitekit.throttledEvents[ key ] ) { return; } window._googlesitekit.throttledEvents[ key ] = true; setTimeout( () => { delete window._googlesitekit.throttledEvents[ key ]; }, 5 ); gtag( "event", name, { ...data, event_source: "site-kit" } ); }; 158//# sourceURL=google_gtagjs-js-after 159</script>
159 160<link rel="https://api.w.org/" href="https://0123456789.tw/wp-json/" /><link rel="alternate" title="JSON" type="application/json" href="https://0123456789.tw/wp-json/wp/v2/posts/2166" /><link rel="EditURI" type="application/rsd+xml" title="RSD" href="https://0123456789.tw/xmlrpc.php?rsd" /> 161<meta name="generator" content="WordPress 7.1.2" /> 162<link rel='shortlink' href='https://0123456789.tw/?p=2166' /> 163<meta name="generator" content="Site Kit by Google 1.188.0" /><link rel="icon" type="image/png" href="/wp-content/uploads/fbrfg/favicon-96x96.png" sizes="96x96" /> 164<link rel="icon" type="image/svg+xml" href="/wp-content/uploads/fbrfg/favicon.svg" /> 165<link rel="shortcut icon" href="/wp-content/uploads/fbrfg/favicon.ico" /> 166<link rel="apple-touch-icon" sizes="180x180" href="/wp-content/uploads/fbrfg/apple-touch-icon.png" /> 167<link rel="manifest" href="/wp-content/uploads/fbrfg/site.webmanifest" />
167<script id="wp-importmap" type="importmap"> 168{"imports":{"@wordpress/interactivity":"https://0123456789.tw/wp-includes/js/dist/script-modules/interactivity/index.min.js?ver=efaa5193bbad9c60ffd1"}} 169</script>
169 170<link rel="modulepreload" href="https://0123456789.tw/wp-includes/js/dist/script-modules/interactivity/index.min.js?ver=efaa5193bbad9c60ffd1" id="@wordpress/interactivity-js-modulepreload" fetchpriority="low"> 171 172<!-- Google AdSense meta tags added by Site Kit --> 173<meta name="google-adsense-platform-account" content="ca-host-pub-2644536267352236"> 174<meta name="google-adsense-platform-domain" content="sitekit.withgoogle.com"> 175<!-- End Google AdSense meta tags added by Site Kit -->
176<script type="text/x-mathjax-config">MathJax.Hub.Config({ tex2jax: {inlineMath: [['[math]','[/math]']]}});</script>
176<script> (function () { var script = document.createElement("script"); script.type = "text/javascript"; script.src = "https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"; document.getElementsByTagName("head")[0].appendChild(script); })();</script>
176 177<!-- Google AdSense snippet added by Site Kit -->
178<script async crossorigin="anonymous" src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-6363297981371690&host=ca-host-pub-2644536267352236"></script>
178 179 180<!-- End Google AdSense snippet added by Site Kit --> 181<style class="wp-fonts-local"> 182@font-face{font-family:Epilogue;font-style:normal;font-weight:300;font-display:fallback;src:url('https://0123456789.tw/wp-content/themes/fewer/assets/fonts/epilogue_300.ttf') format('truetype');} 183@font-face{font-family:Epilogue;font-style:normal;font-weight:500;font-display:fallback;src:url('https://0123456789.tw/wp-content/themes/fewer/assets/fonts/epilogue_500.ttf') format('truetype');} 184@font-face{font-family:Epilogue;font-style:italic;font-weight:500;font-display:fallback;src:url('https://0123456789.tw/wp-content/themes/fewer/assets/fonts/epilogue_500italic.ttf') format('truetype');} 185@font-face{font-family:Epilogue;font-style:italic;font-weight:300;font-display:fallback;src:url('https://0123456789.tw/wp-content/themes/fewer/assets/fonts/epilogue_300italic.ttf') format('truetype');} 186@font-face{font-family:Sora;font-style:normal;font-weight:400;font-display:fallback;src:url('https://0123456789.tw/wp-content/themes/fewer/assets/fonts/sora_normal_400.ttf') format('truetype');} 187@font-face{font-family:Sora;font-style:italic;font-weight:400;font-display:fallback;src:url('https://0123456789.tw/wp-content/themes/fewer/assets/fonts/sora_italic_400.ttf') format('truetype');} 188@font-face{font-family:Sora;font-style:italic;font-weight:600;font-display:fallback;src:url('https://0123456789.tw/wp-content/themes/fewer/assets/fonts/sora_italic_600.ttf') format('truetype');} 189@font-face{font-family:Sora;font-style:normal;font-weight:600;font-display:fallback;src:url('https://0123456789.tw/wp-content/themes/fewer/assets/fonts/sora_normal_600.ttf') format('truetype');} 190@font-face{font-family:"Albert Sans";font-style:normal;font-weight:500;font-display:fallback;src:url('https://0123456789.tw/wp-content/themes/fewer/assets/fonts/albert-sans_normal_500.ttf') format('truetype');} 191@font-face{font-family:"Albert Sans";font-style:italic;font-weight:500;font-display:fallback;src:url('https://0123456789.tw/wp-content/themes/fewer/assets/fonts/albert-sans_italic_500.ttf') format('truetype');} 192@font-face{font-family:"Albert Sans";font-style:normal;font-weight:400;font-display:fallback;src:url('https://0123456789.tw/wp-content/themes/fewer/assets/fonts/albert-sans_normal_400.ttf') format('truetype');} 193@font-face{font-family:"Albert Sans";font-style:italic;font-weight:400;font-display:fallback;src:url('https://0123456789.tw/wp-content/themes/fewer/assets/fonts/albert-sans_italic_400.ttf') format('truetype');} 194@font-face{font-family:"Albert Sans";font-style:normal;font-weight:600;font-display:fallback;src:url('https://0123456789.tw/wp-content/themes/fewer/assets/fonts/albert-sans_normal_600.ttf') format('truetype');} 195@font-face{font-family:"Albert Sans";font-style:italic;font-weight:600;font-display:fallback;src:url('https://0123456789.tw/wp-content/themes/fewer/assets/fonts/albert-sans_italic_600.ttf') format('truetype');} 196</style> 197</head> 198 199<body class="wp-singular post-template-default single single-post postid-2166 single-format-standard wp-embed-responsive wp-theme-fewer"> 200 201<a class="skip-link screen-reader-text" id="wp-skip-link" href="#wp--skip-link--target">è·³è³ä¸»è¦å §å®¹</a><div class="wp-site-blocks"><header class="wp-block-template-part"> 202<div class="wp-block-group has-background-background-color has-background has-global-padding is-layout-constrained wp-container-core-group-is-layout-6030d204 wp-block-group-is-layout-constrained" style="border-top-style:none;border-top-width:0px;border-right-style:none;border-right-width:0px;border-bottom-color:var(--wp--preset--color--primary);border-bottom-width:1px;border-left-style:none;border-left-width:0px;padding-top:0;padding-right:0;padding-bottom:0;padding-left:0"> 203<div class="wp-block-columns alignfull are-vertically-aligned-center is-not-stacked-on-mobile is-layout-flex wp-container-core-columns-is-layout-920ca8ee wp-block-columns-is-layout-flex" style="padding-top:var(--wp--preset--spacing--40);padding-right:var(--wp--preset--spacing--50);padding-bottom:var(--wp--preset--spacing--40);padding-left:var(--wp--preset--spacing--50)"> 204<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:33.33%"><h1 style="font-size:clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 0.529), 1.1rem);font-style:normal;font-weight:700" class="has-text-align-center has-link-color wp-elements-1 wp-block-site-title has-text-color has-vivid-red-color"><a href="https://0123456789.tw" target="_self" rel="home">è¨ç®0123456789</a></h1></div> 205 206 207 208<div class="wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow" style="padding-right:0;padding-left:0;flex-basis:66.66%"><nav class="is-responsive items-justified-right wp-block-navigation is-horizontal is-content-justification-right is-layout-flex wp-container-core-navigation-is-layout-b4ebd6b9 wp-block-navigation-is-layout-flex" aria-label="å°è¦½é¸å®" 209 data-wp-interactive="core/navigation" data-wp-context='{"overlayOpenedBy":{"click":false,"hover":false,"focus":false},"type":"overlay","roleAttribute":"","ariaLabel":"\u9078\u55ae"}'><button aria-haspopup="dialog" aria-label="éåé¸å®" class="wp-block-navigation__responsive-container-open" 210 data-wp-on--click="actions.openMenuOnClick" 211 data-wp-on--keydown="actions.handleMenuKeydown" 212 ><svg width="24" height="24" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" focusable="false">
212<path d="M4 7.5h16v1.5H4z"></path><path d="M4 15h16v1.5H4z"></path></svg></button> 213 <div class="wp-block-navigation__responsive-container has-text-color has-primary-color has-background has-background-background-color" id="modal-1" 214 data-wp-class--has-modal-open="state.isMenuOpen" 215 data-wp-class--is-menu-open="state.isMenuOpen" 216 data-wp-watch="callbacks.initMenu" 217 data-wp-on--keydown="actions.handleMenuKeydown" 218 data-wp-on--focusout="actions.handleMenuFocusout" 219 tabindex="-1" 220 > 221 <div class="wp-block-navigation__responsive-close" tabindex="-1"> 222 <div class="wp-block-navigation__responsive-dialog" 223 data-wp-bind--aria-modal="state.ariaModal" 224 data-wp-bind--aria-label="state.ariaLabel" 225 data-wp-bind--role="state.roleAttribute" 226 > 227 <button aria-label="ééé¸å®" class="wp-block-navigation__responsive-container-close" 228 data-wp-on--click="actions.closeMenuOnClick" 229 ><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false"><path d="m13.06 12 6.47-6.47-1.06-1.06L12 10.94 5.53 4.47 4.47 5.53 10.94 12l-6.47 6.47 1.06 1.06L12 13.06l6.47 6.47 1.06-1.06L13.06 12Z"></path></svg></button> 230 <div class="wp-block-navigation__responsive-container-content" 231 data-wp-watch="callbacks.focusFirstElement" 232 id="modal-1-content"> 233 <ul class="wp-block-navigation__container is-responsive items-justified-right wp-block-navigation"><li class="wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="https://0123456789.tw/board/"><span class="wp-block-navigation-item__label">ð¥ï¸ç·ä¸ä¾¿å©è²¼</span></a></li><li class="wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="https://0123456789.tw/todo/"><span class="wp-block-navigation-item__label">â æçå°æ¸ å®</span></a></li><li class="wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="https://0123456789.tw/bm/"><span class="wp-block-navigation-item__label">ð天天æ¸ç±¤</span></a></li><li class="wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="https://0123456789.tw/note/"><span class="wp-block-navigation-item__label">â¡ï¸è¨ç®proçè¨</span></a></li><li class="wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="https://calculator.0123456789.tw/"><span class="wp-block-navigation-item__label">ð´è¨ç®æ©å表</span></a></li><li class="wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="https://apps.apple.com/tw/app/%E8%A8%88%E7%AE%970123456789/id6757208597"><span class="wp-block-navigation-item__label">ð¥APPä¸è¼</span></a></li><li class="wp-block-navigation-item wp-block-navigation-link"><a class="wp-block-navigation-item__content" href="https://line.me/S/sticker/30458834" target="_blank" ><span class="wp-block-navigation-item__label">ð¢lineè²¼åä¸è¼</span></a></li></ul> 234 235 </div> 236 </div> 237 </div> 238 </div></nav></div> 239 240 241 242<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:0%"></div> 243</div> 244</div> 245 246 247 248<div style="height:var(--wp--preset--spacing--80)" aria-hidden="true" class="wp-block-spacer"></div> 249 250 251<div id="fb-root"></div>
252<script async defer crossorigin="anonymous" src="https://connect.facebook.net/zh_TW/sdk.js#xfbml=1&version=v20.0&appId=197011163651329" nonce="SnprWgNt"></script>
252<!-- Google tag (gtag.js) -->
vendor: 64 bytes, lines 252-253
252 253<script async src="https://www.googletagmanager.com/gtag/js?id=
253G-C0F95TX1P2
vendor: 12 bytes, line 253
253"></script>
254<script> 255
vendor: 134 bytes, lines 255-259
255window.dataLayer = window.dataLayer || []; 256 function gtag(){dataLayer.push(arguments);} 257 gtag('js', new Date()); 258 259 gtag('config', '
259G-C0F95TX1P2
vendor: 4 bytes, line 259
259');
260</script>
260</header> 261 262 263<div class="wp-block-group is-layout-flow wp-block-group-is-layout-flow"> 264<div class="wp-block-group has-global-padding is-layout-constrained wp-block-group-is-layout-constrained" style="border-top-style:none;border-top-width:0px;border-right-style:none;border-right-width:0px;border-bottom-color:var(--wp--preset--color--primary);border-bottom-width:1px;border-left-style:none;border-left-width:0px"> 265<div class="wp-block-columns alignfull is-layout-flex wp-container-core-columns-is-layout-c9a8b3e2 wp-block-columns-is-layout-flex" style="padding-top:0;padding-right:var(--wp--preset--spacing--50);padding-bottom:var(--wp--preset--spacing--80);padding-left:var(--wp--preset--spacing--50)"> 266<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:35%"> 267<div class="wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-f13622a0 wp-block-group-is-layout-flex" style="padding-top:var(--wp--preset--spacing--20)"><div class="taxonomy-category wp-block-post-terms"><a href="https://0123456789.tw/category/apps/" rel="tag">APPæ¨è¦</a></div> 268 269<div class="wp-block-template-part"> 270<div class="wp-block-group has-global-padding is-layout-constrained wp-block-group-is-layout-constrained"> 271<div class="wp-block-group has-secondary-color has-text-color has-link-color wp-elements-2 is-layout-flex wp-container-core-group-is-layout-65c64987 wp-block-group-is-layout-flex"> 272<div class="wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-98ce8303 wp-block-group-is-layout-flex"> 273<p class="has-small-font-size wp-block-paragraph">By</p> 274 275 276<div class="wp-block-post-author-name has-small-font-size">admin</div></div> 277 278 279 280<p class="has-small-font-size wp-block-paragraph">·</p> 281 282 283<div class="has-link-color wp-elements-3 wp-block-post-date has-text-color has-secondary-color has-small-font-size"><time datetime="2026-07-27T17:13:24+08:00">2026-07-27</time></div></div> 284</div> 285</div></div> 286</div> 287 288 289 290<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:55%"><h2 class="has-text-align-left wp-block-post-title">ODDCAM é主æµç¸æ©</h2></div> 291 292 293 294<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:15%"></div> 295</div> 296</div> 297 298 299 300<main id="wp--skip-link--target" class="wp-block-group is-layout-flow wp-block-group-is-layout-flow" style="min-height:50vh"> 301<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-6a1dc368 wp-block-columns-is-layout-flex" style="padding-top:var(--wp--preset--spacing--50);padding-right:var(--wp--preset--spacing--50);padding-bottom:var(--wp--preset--spacing--50);padding-left:var(--wp--preset--spacing--50)"> 302<div class="wp-block-column is-vertically-aligned-top is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:80%"><div class="entry-content wp-block-post-content is-layout-flow wp-block-post-content-is-layout-flow">
303<script data-wp-block-html="js"> 304// GENERATED from dc-runtime/src/*.ts â do not edit. Rebuild with `cd dc-runtime && bun run build`. 305"use strict"; 306(() => { 307 var __defProp = Object.defineProperty; 308 var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; 309 var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); 310 311 // src/react.ts 312 function getReact() { 313 const R = window.React; 314 if (!R) throw new Error("dc-runtime: window.React is not available yet"); 315 return R; 316 } 317 function getReactDOM() { 318 const RD = window.ReactDOM; 319 if (!RD) throw new Error("dc-runtime: window.ReactDOM is not available yet"); 320 return RD; 321 } 322 var h = ((...args) => getReact().createElement( 323 ...args 324 )); 325 326 // src/parse.ts 327 function parseDcDocument(doc) { 328 const dc = doc.querySelector("x-dc"); 329 if (!dc) return null; 330 const scriptEl = doc.querySelector("script[data-dc-script]"); 331 const { props, preview } = parseDataProps( 332 scriptEl?.getAttribute("data-props") ?? null 333 ); 334 return { 335 template: dc.innerHTML, 336 js: scriptEl ? scriptEl.textContent || "" : "", 337 props, 338 preview 339 }; 340 } 341 function parseDcText(src) { 342 const openMatch = /<x-dc(?:\s[^>]*)?>/.exec(src); 343 if (!openMatch) return null; 344 const close = src.lastIndexOf("</x-dc>"); 345 if (close === -1 || close < openMatch.index) return null; 346 const template = src.slice(openMatch.index + openMatch[0].length, close); 347 const doc = new DOMParser().parseFromString(src, "text/html"); 348 const scriptEl = doc.querySelector("script[data-dc-script]"); 349 const { props, preview } = parseDataProps( 350 scriptEl?.getAttribute("data-props") ?? null 351 ); 352 return { 353 template, 354 js: scriptEl ? scriptEl.textContent || "" : "", 355 props, 356 preview 357 }; 358 } 359 function parseDataProps(raw) { 360 if (!raw) return { props: null, preview: null }; 361 let parsed; 362 try { 363 parsed = JSON.parse(raw); 364 } catch { 365 return { props: null, preview: null }; 366 } 367 if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) { 368 return { props: null, preview: null }; 369 } 370 const obj = parsed; 371 const preview = obj.$preview && typeof obj.$preview === "object" ? obj.$preview : null; 372 const rest = {}; 373 for (const k of Object.keys(obj)) { 374 if (k[0] !== "$") rest[k] = obj[k]; 375 } 376 return { props: Object.keys(rest).length ? rest : null, preview }; 377 } 378 function dcNameFromPath(pathname) { 379 let p = pathname || ""; 380 try { 381 p = decodeURIComponent(p); 382 } catch { 383 } 384 const base = p.split("/").pop() || "Root"; 385 return base.replace(/\.dc\.html$/, "").replace(/\.html?$/, "") || "Root"; 386 } 387 388 // src/boot.ts 389 var BASE_CSS = ` 390 .sc-placeholder{background:color-mix(in srgb,currentColor 8%,transparent); 391 border:1px solid color-mix(in srgb,currentColor 50%,transparent); 392 border-radius:2px;box-sizing:border-box;overflow:hidden} 393 @keyframes sc-shine{0%{background-position:100% 50%}100%{background-position:0% 50%}} 394 html.sc-dc-streaming .sc-placeholder, 395 html.sc-dc-streaming .sc-interp.sc-missing{position:relative; 396 background:color-mix(in srgb,currentColor 5%,transparent); 397 border-color:transparent} 398 html.sc-dc-streaming .sc-placeholder::before, 399 html.sc-dc-streaming .sc-interp.sc-missing::before{content:''; 400 position:absolute;inset:0;pointer-events:none; 401 background:linear-gradient(90deg,rgba(217,119,87,0) 25%,rgba(247,225,211,.95) 37%,rgba(217,119,87,0) 63%); 402 background-size:400% 100%;animation:sc-shine 1.4s ease infinite} 403 html.sc-dc-streaming .sc-placeholder:nth-child(n+9 of .sc-placeholder)::before, 404 html.sc-dc-streaming .sc-interp.sc-missing:nth-child(n+9 of .sc-interp.sc-missing)::before{animation:none; 405 background:color-mix(in srgb,currentColor 8%,transparent)} 406 .sc-placeholder-error{padding:4px 8px;font:11px/1.4 ui-monospace,monospace; 407 color:color-mix(in srgb,currentColor 70%,transparent);word-break:break-word} 408 .sc-interp.sc-missing{display:inline-block;width:2em;height:1em;overflow:hidden; 409 vertical-align:text-bottom;background:rgba(255,255,255,.3);border:1px solid rgba(0,0,0,.5); 410 border-radius:2px;box-sizing:border-box;color:transparent; 411 user-select:none} 412 .sc-interp.sc-unresolved{font-family:ui-monospace,monospace;font-size:.85em; 413 color:color-mix(in srgb,currentColor 50%,transparent); 414 background:color-mix(in srgb,currentColor 10%,transparent);border-radius:3px; 415 padding:0 3px} 416 .sc-host.sc-has-error{position:relative} 417 .sc-logic-error{position:absolute;top:8px;left:8px;z-index:2147483647;max-width:60ch; 418 padding:6px 10px;background:#b00020;color:#fff;font:12px/1.4 ui-monospace,monospace; 419 border-radius:4px;white-space:pre-wrap;pointer-events:none} 420 /* Mirrors PRINT_BASELINE_CSS in apps/web deck-stage-export.ts \u2014 keep both 421 in sync until dc-runtime regains a build step. */ 422 @media print { 423 @page { margin: 0.5cm; } 424 figure, table { break-inside: avoid; } 425 #dc-root, #dc-root > .sc-host { height: auto; } 426 *, *::before, *::after { 427 print-color-adjust: exact; -webkit-print-color-adjust: exact; 428 backdrop-filter: none !important; -webkit-backdrop-filter: none !important; 429 animation-delay: -99s !important; animation-duration: .001s !important; 430 animation-iteration-count: 1 !important; animation-fill-mode: both !important; 431 animation-play-state: running !important; transition-duration: 0s !important; 432 } 433 } 434 `; 435 var FULL_PAGE_CSS = "html,body{height:100%;margin:0}#dc-root,#dc-root>.sc-host{height:100%}"; 436 function rootNameForDocument(doc, loc) { 437 let bootPath = loc.pathname || ""; 438 if (!/\.dc\.html?$/i.test(safeDecode(bootPath))) {
439 try { 440 bootPath = new URL(doc.baseURI || "/").pathname; 441 } catch { 442 } 443 } 444 return dcNameFromPath(bootPath); 445 } 446 function safeDecode(s) { 447 try { 448 return decodeURIComponent(s); 449 } catch { 450 return s; 451 } 452 } 453 function boot(runtime, doc = document) { 454 const parsed = parseDcDocument(doc); 455 if (!parsed) return null; 456 const React = getReact(); 457 const rootName = rootNameForDocument(doc, location); 458 runtime.markFetched(rootName); 459 runtime.setRootName(rootName); 460 runtime.adoptParsed(rootName, parsed); 461 if (!window.__resources) { 462 fetch(location.href).then((res) => res.ok ? res.text() : "").then((t) => { 463 const raw = t ? parseDcText(t) : null; 464 if (raw?.template) runtime.updateHtml(rootName, raw.template); 465 }).catch(() => { 466 }); 467 } 468 const dc = doc.querySelector("x-dc"); 469 const hostEl = doc.createElement("div"); 470 hostEl.id = "dc-root"; 471 dc.replaceWith(hostEl); 472 if (!parsed.preview) { 473 const s = doc.createElement("style"); 474 s.textContent = FULL_PAGE_CSS; 475 doc.head.appendChild(s); 476 } 477 const Root = runtime.getDC(rootName); 478 const entry = runtime.registry.get(rootName); 479 function StandaloneRoot() { 480 const [, setTick] = React.useState(0); 481 React.useEffect(() => { 482 const sub = () => setTick((n) => n + 1); 483 entry.subs.add(sub); 484 return () => { 485 entry.subs.delete(sub); 486 }; 487 }, []); 488 const defaults = React.useMemo(() => { 489 const d = {}; 490 for (const k in entry.propsMeta || {}) { 491 const v = entry.propsMeta?.[k]?.default; 492 if (v !== void 0) d[k] = v; 493 } 494 return d; 495 }, [entry.propsMeta]); 496 return h(Root, { ...defaults, ...entry.propOverrides || {} }); 497 } 498 const ReactDOM = getReactDOM(); 499 if (ReactDOM.createRoot) 500 ReactDOM.createRoot(hostEl).render(h(StandaloneRoot)); 501 else ReactDOM.render(h(StandaloneRoot), hostEl); 502 return rootName; 503 } 504 505 // src/expr.ts 506 var IDENT_RE = /^[A-Za-z_$][A-Za-z0-9_$]*/; 507 var NUMBER_RE = /^-?\d+(\.\d+)?$/; 508 function resolve(vals, src) { 509 const expr = String(src).trim(); 510 if (!expr) return void 0; 511 if (expr[0] === "(" && expr[expr.length - 1] === ")" && parensWrapWhole(expr)) { 512 return resolve(vals, expr.slice(1, -1)); 513 } 514 const eq = findTopLevelEquality(expr); 515 if (eq) { 516 const lv = resolve(vals, expr.slice(0, eq.index)); 517 const rv = resolve(vals, expr.slice(eq.index + eq.op.length)); 518 switch (eq.op) { 519 case "===": 520 return lv === rv; 521 case "!==": 522 return lv !== rv; 523 case "==": 524 return lv == rv; 525 default: 526 return lv != rv; 527 } 528 } 529 if (expr[0] === "!") return !resolve(vals, expr.slice(1)); 530 if (expr === "true") return true; 531 if (expr === "false") return false; 532 if (expr === "null") return null; 533 if (expr === "undefined") return void 0; 534 if (NUMBER_RE.test(expr)) return Number(expr); 535 if (expr.length >= 2 && (expr[0] === '"' || expr[0] === "'") && expr[expr.length - 1] === expr[0]) { 536 return expr.slice(1, -1); 537 } 538 return resolvePath(vals, expr); 539 } 540 function parensWrapWhole(expr) { 541 let depth = 0; 542 for (let i = 0; i < expr.length - 1; i++) { 543 if (expr[i] === "(") depth++; 544 else if (expr[i] === ")") { 545 depth--; 546 if (depth === 0) return false; 547 } 548 } 549 return true; 550 } 551 function findTopLevelEquality(expr) { 552 let depth = 0; 553 for (let i = 0; i < expr.length; i++) { 554 const c = expr[i]; 555 if (c === "[" || c === "(") depth++; 556 else if (c === "]" || c === ")") depth--; 557 else if (depth === 0 && (c === "=" || c === "!") && expr[i + 1] === "=") { 558 if (i > 0 && (expr[i - 1] === "=" || expr[i - 1] === "!")) continue; 559 if (!expr.slice(0, i).trim()) continue; 560 const op = expr[i + 2] === "=" ? c + "==" : c + "="; 561 return { index: i, op }; 562 } 563 } 564 return null; 565 } 566 function resolvePath(vals, expr) { 567 const head = expr.match(IDENT_RE); 568 if (!head) return void 0;
569 let cur = vals == null ? void 0 : vals[head[0]]; 570 let i = head[0].length; 571 while (i < expr.length) { 572 if (expr[i] === ".") { 573 const m = expr.slice(i + 1).match(IDENT_RE) || expr.slice(i + 1).match(/^\d+/); 574 if (!m) return void 0; 575 cur = cur == null ? void 0 : cur[m[0]]; 576 i += 1 + m[0].length; 577 } else if (expr[i] === "[") { 578 let depth = 1; 579 let j = i + 1; 580 while (j < expr.length && depth > 0) { 581 if (expr[j] === "[") depth++; 582 else if (expr[j] === "]") { 583 depth--; 584 if (depth === 0) break; 585 } 586 j++; 587 } 588 if (depth !== 0) return void 0; 589 const key = resolve(vals, expr.slice(i + 1, j)); 590 cur = cur == null ? void 0 : cur[key]; 591 i = j + 1; 592 } else { 593 return void 0; 594 } 595 } 596 return cur; 597 } 598 599 // src/encode.ts 600 var CAMEL_ATTR = "sc-camel-"; 601 var INLINE_TEXT_TAGS = new Set( 602 "a abbr b bdi bdo br cite code del dfn em i ins kbd mark q s samp small span strike strong sub sup u var wbr".split( 603 " " 604 ) 605 ); 606 var RAW_WRAP = { 607 select: "sc-raw-select", 608 table: "sc-raw-table", 609 tbody: "sc-raw-tbody", 610 thead: "sc-raw-thead", 611 tfoot: "sc-raw-tfoot", 612 tr: "sc-raw-tr", 613 td: "sc-raw-td", 614 th: "sc-raw-th", 615 caption: "sc-raw-caption" 616 }; 617 var RAW_UNWRAP = Object.fromEntries( 618 Object.entries(RAW_WRAP).map(([k, v]) => [v, k]) 619 ); 620 var EVENT_MAP = { 621 onclick: "onClick", 622 onchange: "onChange", 623 oninput: "onInput", 624 onsubmit: "onSubmit", 625 onkeydown: "onKeyDown", 626 onkeyup: "onKeyUp", 627 onkeypress: "onKeyPress", 628 onmousedown: "onMouseDown", 629 onmouseup: "onMouseUp", 630 onmouseenter: "onMouseEnter", 631 onmouseleave: "onMouseLeave", 632 onfocus: "onFocus", 633 onblur: "onBlur", 634 ondoubleclick: "onDoubleClick", 635 oncontextmenu: "onContextMenu", 636 onmousemove: "onMouseMove", 637 onmouseover: "onMouseOver", 638 onmouseout: "onMouseOut", 639 onpointerdown: "onPointerDown", 640 onpointerup: "onPointerUp", 641 onpointermove: "onPointerMove", 642 onpointerenter: "onPointerEnter", 643 onpointerleave: "onPointerLeave", 644 onpointercancel: "onPointerCancel", 645 onpointerover: "onPointerOver", 646 onpointerout: "onPointerOut", 647 ongotpointercapture: "onGotPointerCapture", 648 onlostpointercapture: "onLostPointerCapture", 649 ontouchstart: "onTouchStart", 650 ontouchend: "onTouchEnd", 651 ontouchmove: "onTouchMove", 652 ontouchcancel: "onTouchCancel", 653 ondragstart: "onDragStart", 654 ondragend: "onDragEnd", 655 ondragenter: "onDragEnter", 656 ondragleave: "onDragLeave", 657 ondragover: "onDragOver", 658 onanimationstart: "onAnimationStart", 659 onanimationend: "onAnimationEnd", 660 onanimationiteration: "onAnimationIteration", 661 ontransitionend: "onTransitionEnd" 662 }; 663 var ATTRS = `(?:[^>"']|"[^"]*"|'[^']*')*`; 664 var IMPORT_SELF_CLOSE_RE = new RegExp( 665 "<(x-import|dc-import)(" + ATTRS + ")/>", 666 "gi" 667 ); 668 var CAMEL_ATTR_RE = /(\s)([a-z]+[A-Z][A-Za-z0-9]*)(\s*=)/g; 669 function encodeCamelAttrs(html) { 670 return html.replace( 671 CAMEL_ATTR_RE, 672 (_, sp, name, eq) => sp + CAMEL_ATTR + name.replace(/[A-Z]/g, (c) => "-" + c.toLowerCase()) + eq 673 ); 674 } 675 function encodeCase(html) { 676 html = html.replace( 677 IMPORT_SELF_CLOSE_RE, 678 (_, t, a) => "<" + t + a + "></" + t + ">" 679 ); 680 html = html.replace(/<helmet(\s|>)/gi, "<sc-helmet$1"); 681 html = html.replace(/<\/helmet\s*>/gi, "</sc-helmet>"); 682 html = encodeCamelAttrs(html); 683 for (const [real, alias] of Object.entries(RAW_WRAP)) { 684 html = html.replace( 685 new RegExp("(</?)" + real + "(?=[\\s>])", "gi"), 686 "$1" + alias 687 ); 688 } 689 return html; 690 } 691 function kebabToCamel(s) { 692 return s.replace(/-([a-z])/g, (_, c) => c.toUpperCase()); 693 } 694 function cssToObj(css) { 695 const o = {}; 696 for (const decl of css.split(";")) { 697 const i = decl.indexOf(":"); 698 if (i < 0) continue; 699 const prop = decl.slice(0, i).trim(); 700 o[prop.startsWith("--") ? prop : kebabToCamel(prop)] = decl.slice(i + 1).trim(); 701 } 702 return o; 703 } 704 function compileAttr(raw) { 705 const whole = raw.match(/^\s*\{\{([\s\S]+?)\}\}\s*$/); 706 if (whole) { 707 const path = whole[1]; 708 return (vals) => resolve(vals, path); 709 } 710 if (raw.includes("{{")) { 711 const parts = raw.split(/\{\{([\s\S]+?)\}\}/g); 712 return (vals) => parts.map((s, i) => i & 1 ? resolve(vals, s) ?? "" : s).join(""); 713 } 714 return () => raw; 715 } 716 717 // src/compile.ts 718 function collectProps(node, kind, host) { 719 const propGetters = []; 720 const pseudoClasses = []; 721 let hintSize = null; 722 for (const { name, value } of [...node.attributes]) { 723 if (name === "sc-name" || name === "data-dc-tpl") continue; 724 let key = name; 725 if (key.startsWith(CAMEL_ATTR)) 726 key = kebabToCamel(key.slice(CAMEL_ATTR.length)); 727 if (key === "hint-size") { 728 hintSize = value; 729 continue; 730 } 731 if (key.startsWith("style-")) { 732 pseudoClasses.push(host.pseudoClass(key.slice(6), value)); 733 continue; 734 } 735 if (kind !== "dom") { 736 if (key.includes("-") && !(kind === "x-import" && (key.startsWith("aria-") || key.startsWith("data-")))) 737 key = kebabToCamel(key); 738 } else { 739 if (key === "class") key = "className"; 740 else if (key === "for") key = "htmlFor"; 741 else if (key.startsWith("on"))
742 key = EVENT_MAP[key] || "on" + key[2].toUpperCase() + key.slice(3); 743 } 744 propGetters.push([key, compileAttr(value)]); 745 } 746 return { propGetters, pseudoClasses, hintSize }; 747 } 748 var HOST_STYLE_PROPS = /* @__PURE__ */ new Set([ 749 "position", 750 "left", 751 "right", 752 "top", 753 "bottom", 754 "inset", 755 "width", 756 "height", 757 "z-index", 758 "transform" 759 ]); 760 function hostPositionStyle(style) { 761 const all = typeof style === "string" ? cssToObj(style) : style != null && typeof style === "object" ? style : null; 762 if (!all) return void 0; 763 const out = {}; 764 for (const [k, v] of Object.entries(all)) { 765 const kebab = k.replace(/[A-Z]/g, (c) => "-" + c.toLowerCase()); 766 if (HOST_STYLE_PROPS.has(kebab)) out[k] = v; 767 } 768 return Object.keys(out).length ? out : void 0; 769 } 770 function compileTemplate(html, host) { 771 const tpl = document.createElement("template"); 772 //! nosemgrep: direct-inner-html-assignment 773 tpl.innerHTML = encodeCase(html); 774 let tplN = 0; 775 (function stamp(node) { 776 if (node.nodeType === Node.ELEMENT_NODE) { 777 node.setAttribute("data-dc-tpl", String(tplN++)); 778 } 779 for (const c of node.childNodes) stamp(c); 780 })(tpl.content); 781 const builders = walkChildren(tpl.content, host); 782 const render = ((vals, ctx) => builders.map((b, i) => b(vals || {}, ctx, i))); 783 render.__annotated = tpl.innerHTML; 784 return render; 785 } 786 function walkChildren(node, host) { 787 return [...node.childNodes].map((c) => walk(c, host)).filter((b) => b != null); 788 } 789 var SLIDE_ID_VALUE_RE = /^[0-9a-f]{8}$/; 790 var DECK_CONTROL_FLOW_RE = /^(sc-if|sc-for|sc-else|dc-import|x-import)$/; 791 var DECK_AUX_RE = /^(template|script|style|sc-helmet|helmet)$/; 792 function isDeckMountTag(el) { 793 if (el.localName === "deck-stage") return true; 794 return el.localName === "x-import" && (el.getAttribute("component-from-global-scope") || "") === "deck-stage"; 795 } 796 function walkDeckChildren(el, host) { 797 const pairs = [...el.childNodes].map((c) => ({ c, b: walk(c, host) })).filter((p) => p.b !== null); 798 const kids = pairs.map((p) => p.b); 799 const seen = /* @__PURE__ */ new Set(); 800 const wsSeen = /* @__PURE__ */ new Map(); 801 const keys = []; 802 const nextSlideId = new Array(pairs.length); 803 { 804 let upcoming = null; 805 for (let j = pairs.length - 1; j >= 0; j--) { 806 const n = pairs[j].c; 807 if (n.nodeType === Node.ELEMENT_NODE) { 808 const t = n.localName; 809 upcoming = !DECK_AUX_RE.test(t) && !DECK_CONTROL_FLOW_RE.test(t) ? n.getAttribute("data-om-slide-id") : null; 810 } 811 nextSlideId[j] = upcoming; 812 } 813 } 814 for (let j = 0; j < pairs.length; j++) { 815 const { c } = pairs[j]; 816 if (c.nodeType === Node.TEXT_NODE) { 817 if ((c.nodeValue ?? "").trim() === "") { 818 const base = nextSlideId[j] ? "omid-ws:" + nextSlideId[j] : "omid-ws:aux"; 819 const n = wsSeen.get(base) ?? 0; 820 wsSeen.set(base, n + 1); 821 keys.push(n === 0 ? base : base + ":" + n); 822 continue; 823 } 824 return { kids, keys: null }; 825 } 826 if (c.nodeType !== Node.ELEMENT_NODE) { 827 keys.push(j); 828 continue; 829 } 830 const child = c; 831 const tag = child.localName; 832 if (DECK_AUX_RE.test(tag)) { 833 keys.push(j); 834 continue; 835 } 836 if (DECK_CONTROL_FLOW_RE.test(tag)) return { kids, keys: null }; 837 const v = child.getAttribute("data-om-slide-id"); 838 if (!v || !SLIDE_ID_VALUE_RE.test(v) || seen.has(v)) { 839 return { kids, keys: null }; 840 } 841 seen.add(v); 842 keys.push("omid:" + v); 843 } 844 return { kids, keys }; 845 } 846 function renderDeckKids(kids, kidKeys, vals, ctx) { 847 return kids.map((b, j) => { 848 const k = kidKeys ? kidKeys[j] : j; 849 const out = b(vals, ctx, k); 850 return kidKeys != null && typeof out === "string" ? h(getReact().Fragment, { key: k }, out) : out; 851 }); 852 } 853 function walk(node, host) { 854 if (node.nodeType === Node.TEXT_NODE) return walkText(node); 855 if (node.nodeType !== Node.ELEMENT_NODE) return null; 856 const el = node; 857 const tag = el.tagName.toLowerCase(); 858 if (tag === "sc-for") return walkFor(el, host); 859 if (tag === "sc-if") return walkIf(el, host); 860 if (tag === "x-import") return walkXImport(el, host); 861 if (tag === "sc-helmet") return host.helmet(el); 862 if (tag === "dc-import") return walkComponent(el, host); 863 return walkElement(el, host); 864 } 865 var warnedHoles = /* @__PURE__ */ new Set(); 866 function warnUnresolved(ctx, what) {
867 const key = (ctx?.__name || "?") + "\0" + what; 868 if (warnedHoles.has(key)) return; 869 warnedHoles.add(key); 870 console.warn("[dc-runtime] " + (ctx?.__name || "template") + ": " + what); 871 } 872 function walkText(node) { 873 const txt = node.nodeValue ?? ""; 874 if (!txt.includes("{{")) { 875 if (!txt.trim() && !txt.includes(" ")) return null; 876 return () => txt; 877 } 878 const parts = txt.split(/\{\{([\s\S]+?)\}\}/g); 879 return (vals, ctx, key) => h( 880 getReact().Fragment, 881 { key }, 882 ...parts.map((p, i) => { 883 if (!(i & 1)) return p; 884 const v = resolve(vals, p); 885 if (v === void 0) { 886 if (!ctx?.__streamingNow) { 887 if (document.body?.hasAttribute("data-dc-editor-on")) { 888 return h( 889 "span", 890 { key: i, className: "sc-interp sc-unresolved" }, 891 "{{ " + p.trim() + " }}" 892 ); 893 } 894 warnUnresolved( 895 ctx, 896 "{{ " + p.trim() + " }} never resolved \u2014 rendered as empty" 897 ); 898 return null; 899 } 900 return h( 901 "span", 902 { key: i, className: "sc-interp sc-missing" }, 903 p.trim() 904 ); 905 } 906 if (getReact().isValidElement(v) || Array.isArray(v)) { 907 return h(getReact().Fragment, { key: i }, v); 908 } 909 if (v === null || typeof v === "boolean") return null; 910 return h("span", { key: i, className: "sc-interp" }, String(v)); 911 }) 912 ); 913 } 914 function walkFor(el, host) { 915 const listGet = compileAttr(el.getAttribute("list") || ""); 916 const asName = el.getAttribute("as") || "item"; 917 const hintN = parseInt(el.getAttribute("hint-placeholder-count") || "0", 10); 918 const kids = walkChildren(el, host); 919 const listSrc = el.getAttribute("list") || ""; 920 return (vals, ctx, key) => { 921 let list = listGet(vals); 922 if (!Array.isArray(list)) { 923 if (!ctx?.__streamingNow) { 924 if (list !== void 0 && list !== null) { 925 warnUnresolved( 926 ctx, 927 'sc-for list="' + listSrc + '" is not an array (' + typeof list + ")" 928 ); 929 } 930 list = []; 931 } else { 932 list = hintN > 0 ? Array(hintN).fill(void 0) : []; 933 } 934 } 935 return h( 936 getReact().Fragment, 937 { key }, 938 list.map((item, i) => { 939 const sub = { ...vals, [asName]: item, $index: i }; 940 return h( 941 getReact().Fragment, 942 { key: i }, 943 kids.map((b, j) => b(sub, ctx, j)) 944 ); 945 }) 946 ); 947 }; 948 } 949 function walkIf(el, host) { 950 const valGet = compileAttr(el.getAttribute("value") || ""); 951 const hintRaw = el.getAttribute("hint-placeholder-val"); 952 const hintGet = hintRaw != null ? compileAttr(hintRaw) : null; 953 const kids = walkChildren(el, host); 954 return (vals, ctx, key) => { 955 let v = valGet(vals); 956 if (v === void 0 && hintGet && ctx?.__streamingNow) v = hintGet(vals); 957 return v ? h( 958 getReact().Fragment, 959 { key }, 960 kids.map((b, j) => b(vals, ctx, j)) 961 ) : null; 962 }; 963 } 964 function walkComponent(el, host) { 965 const name = el.getAttribute("name") || el.getAttribute("component") || ""; 966 el.removeAttribute("name"); 967 el.removeAttribute("component"); 968 const tplId = el.getAttribute("data-dc-tpl"); 969 const styleRaw = el.getAttribute("style"); 970 el.removeAttribute("style"); 971 const styleGet = styleRaw != null ? compileAttr(styleRaw) : null; 972 const { propGetters, hintSize } = collectProps(el, "dc-import", host); 973 const kids = walkChildren(el, host); 974 return (vals, ctx, key) => { 975 const props = { 976 key, 977 __hintSize: hintSize, 978 __tplId: tplId, 979 __hostStyle: styleGet ? hostPositionStyle(styleGet(vals)) : void 0 980 }; 981 for (const [k, g] of propGetters) { 982 const v = g(vals); 983 if (k === "dcProps") { 984 if (v && typeof v === "object") Object.assign(props, v); 985 continue; 986 } 987 props[k] = v; 988 } 989 if (kids.length) props.children = kids.map((b, j) => b(vals, ctx, j)); 990 return h(host.component(name), props); 991 }; 992 } 993 function walkXImport(el, host) { 994 const globalNameGet = compileAttr( 995 el.getAttribute("component-from-global-scope") || "" 996 ); 997 const exportNameGet = compileAttr( 998 el.getAttribute("component") || el.getAttribute("name") || "" 999 ); 1000 const fromRaw = el.getAttribute("from") || (el.getAttribute("component-from-global-scope") ? "" : el.getAttribute("src") || el.getAttribute("import") || ""); 1001 const urls = fromRaw.trim() ? fromRaw.trim().split(/\s+/) : []; 1002 const url = urls.length ? urls[urls.length - 1] : "";
1003 const kindOf = (u) => /\.(jsx|tsx)(\?|#|$)/i.test(u) ? "jsx" : "js"; 1004 const tplId = el.getAttribute("data-dc-tpl"); 1005 const styleRaw = el.getAttribute("style"); 1006 el.removeAttribute("style"); 1007 const styleGet = styleRaw != null ? compileAttr(styleRaw) : null; 1008 const wrap = tplId != null || styleGet != null; 1009 const { propGetters, hintSize } = collectProps(el, "x-import", host); 1010 const hasContent = el.children.length > 0 || !!(el.textContent || "").trim(); 1011 const deckKeyed = hasContent && isDeckMountTag(el) ? walkDeckChildren(el, host) : null; 1012 const kids = deckKeyed ? deckKeyed.kids : hasContent ? walkChildren(el, host) : []; 1013 const kidKeys = deckKeyed?.keys ?? null; 1014 const urlBindable = fromRaw.includes("{{"); 1015 if (urls.length && !urlBindable) { 1016 let prev; 1017 for (const u of urls) prev = host.loadExternal(kindOf(u), u, prev); 1018 } 1019 const evalName = (g, vals) => { 1020 const v = g(vals); 1021 const s = v == null ? "" : String(v); 1022 return s.includes("{{") ? "" : s; 1023 }; 1024 return (vals, ctx, key) => { 1025 const globalName = evalName(globalNameGet, vals); 1026 const name = globalName || evalName(exportNameGet, vals); 1027 const C = !name || urlBindable ? null : globalName ? host.resolveExternalGlobal(url, globalName) : host.resolveExternal(url, name); 1028 const hostStyle = styleGet ? hostPositionStyle(styleGet(vals)) : void 0; 1029 const wrapper = wrap ? { 1030 key, 1031 className: "sc-host-x", 1032 "data-dc-tpl": tplId, 1033 style: hostStyle || { display: "contents" } 1034 } : null; 1035 if (!C) { 1036 const error = urlBindable ? "x-import `from` cannot contain {{ \u2026 }} \u2014 module URLs are resolved at parse time; use a literal URL" : host.resolveExternalError(url, name); 1037 const ph = host.placeholder({ 1038 key: wrapper ? void 0 : key, 1039 name, 1040 hintSize, 1041 error 1042 }); 1043 return wrapper ? h("div", wrapper, ph) : ph; 1044 } 1045 const props = wrapper ? {} : { key }; 1046 let unresolvedHole = false; 1047 for (const [k, g] of propGetters) { 1048 if (k === "component" || k === "componentFromGlobalScope" || k === "from") { 1049 continue; 1050 } 1051 const v = g(vals); 1052 if (v === void 0) unresolvedHole = true; 1053 if (k === "dcProps") { 1054 if (v && typeof v === "object") Object.assign(props, v); 1055 continue; 1056 } 1057 props[k] = v; 1058 } 1059 if (unresolvedHole && ctx?.__htmlStreamingNow) { 1060 const ph = host.placeholder({ 1061 key: wrapper ? void 0 : key, 1062 name, 1063 hintSize, 1064 error: null 1065 }); 1066 return wrapper ? h("div", wrapper, ph) : ph; 1067 } 1068 if (kids.length) { 1069 props.children = renderDeckKids(kids, kidKeys, vals, ctx); 1070 } 1071 return wrapper ? h("div", wrapper, h(C, props)) : h(C, props); 1072 }; 1073 } 1074 function contentKey(el) { 1075 const clone = el.cloneNode(true); 1076 for (const d of clone.querySelectorAll("*")) { 1077 while (d.attributes.length) d.removeAttribute(d.attributes[0].name); 1078 } 1079 const s = clone.innerHTML; 1080 let h2 = 5381; 1081 for (let i = 0; i < s.length; i++) h2 = (h2 << 5) + h2 + s.charCodeAt(i) | 0; 1082 return s.length + "." + (h2 >>> 0).toString(36); 1083 } 1084 var NEVER_CONTENT_KEYED = new Set( 1085 "script style textarea option title select canvas iframe video audio".split( 1086 " " 1087 ) 1088 ); 1089 var NOT_INLINE_SELECTOR = ":not(" + [...INLINE_TEXT_TAGS].join(",") + ")"; 1090 function walkElement(el, host) { 1091 const realTag = RAW_UNWRAP[el.localName] || el.localName; 1092 const tplId = el.getAttribute("data-dc-tpl"); 1093 const inlineOnly = el.childNodes.length > 0 && !NEVER_CONTENT_KEYED.has(realTag) && el.querySelector(NOT_INLINE_SELECTOR) === null; 1094 const keySuffix = inlineOnly ? "|" + contentKey(el) : ""; 1095 const { propGetters, pseudoClasses } = collectProps(el, "dom", host); 1096 const deckKeyed = isDeckMountTag(el) ? walkDeckChildren(el, host) : null; 1097 const kids = deckKeyed ? deckKeyed.kids : walkChildren(el, host); 1098 const kidKeys = deckKeyed?.keys ?? null; 1099 return (vals, ctx, key) => { 1100 const props = { 1101 key: key + keySuffix, 1102 "data-dc-tpl": tplId 1103 }; 1104 for (const [k, g] of propGetters) { 1105 let v = g(vals); 1106 if (k === "style" && typeof v === "string") v = cssToObj(v); 1107 if ((k === "value" || k === "checked") && v === void 0) { 1108 v = k === "checked" ? false : ""; 1109 } 1110 props[k] = v; 1111 } 1112 if (pseudoClasses.length) { 1113 props.className = [props.className, ...pseudoClasses].filter(
1113Boolean).join(" "); 1114 } 1115 return h(realTag, props, ...renderDeckKids(kids, kidKeys, vals, ctx)); 1116 }; 1117 } 1118 1119 // src/logic.ts 1120 var StreamableLogic = class { 1121 constructor(props) { 1122 __publicField(this, "props"); 1123 __publicField(this, "state", {}); 1124 /** Back-pointer to the wrapper component, installed after construction. */ 1125 __publicField(this, "__host"); 1126 this.props = props || {}; 1127 } 1128 setState(update, cb) { 1129 this.__host && this.__host.__setLogicState(update, cb); 1130 } 1131 forceUpdate() { 1132 this.__host && this.__host.forceUpdate(); 1133 } 1134 componentDidMount() { 1135 } 1136 componentDidUpdate(_prevProps) { 1137 } 1138 componentWillUnmount() { 1139 } 1140 /** The flat object the template renders against (merged over props). */ 1141 renderVals() { 1142 return {}; 1143 } 1144 }; 1145 function evalDcLogic(src) { 1146 //! nosemgrep: eval-and-function-constructor 1147 const fn = new Function( 1148 "DCLogic", 1149 "StreamableLogic", 1150 "React", 1151 src + '\n;return (typeof Component!=="undefined"&&Component)||undefined;' 1152 ); 1153 return fn(StreamableLogic, StreamableLogic, getReact()); 1154 } 1155 1156 // src/component.ts 1157 function shallowEqual(a, b) { 1158 if (!b) return false; 1159 const ak = Object.keys(a).filter((k) => k !== "children"); 1160 const bk = Object.keys(b).filter((k) => k !== "children"); 1161 if (ak.length !== bk.length) return false; 1162 for (const k of ak) if (a[k] !== b[k]) return false; 1163 return true; 1164 } 1165 function Placeholder({ 1166 name, 1167 hintSize, 1168 streaming, 1169 error 1170 }) { 1171 const [w, hgt] = (hintSize || "100%,60px").split(","); 1172 return h( 1173 "div", 1174 { 1175 className: "sc-placeholder" + (streaming ? " sc-streaming" : ""), 1176 style: { width: w.trim(), height: hgt && hgt.trim() }, 1177 title: name 1178 }, 1179 error ? h( 1180 "div", 1181 { className: "sc-placeholder-error" }, 1182 (name ? name + ": " : "") + error 1183 ) : null 1184 ); 1185 } 1186 function hintToMin(hint) { 1187 if (!hint) return void 0; 1188 const [w, hgt] = hint.split(","); 1189 return { minWidth: w.trim(), minHeight: hgt && hgt.trim() }; 1190 } 1191 function createComponentFactory(registry, ensureFetched) { 1192 const React = getReact(); 1193 const AncestorContext = React.createContext([]); 1194 class StreamableComponent extends React.Component { 1195 constructor(props) { 1196 super(props); 1197 __publicField(this, "__name"); 1198 __publicField(this, "__sub"); 1199 __publicField(this, "__needsDidMount", false); 1200 /** Snapshot of the registry's streaming flags taken at render time â 1201 * builders read it off the RenderCtx (this) to pick placeholder vs 1202 * render-nothing for unresolved values. */ 1203 __publicField(this, "__streamingNow", false); 1204 __publicField(this, "__htmlStreamingNow", false); 1205 /** When a construct throws, remember the (class, registry.ver, props) 1206 * triple so render-time reconcile doesn't re-attempt it on every parent 1207 * re-render. A registry bump (new class, template, external module 1208 * resolving via bumpAll) changes `ver` and breaks the memo so an 1209 * env-dependent constructor can self-heal. */ 1210 __publicField(this, "__failedLogic", null); 1211 __publicField(this, "__failedUserProps", null); 1212 __publicField(this, "__failedVer", -1); 1213 /** Per-instance constructor error â kept here (not on the registry entry) 1214 * so one instance's successful construct can't hide a sibling's failure, 1215 * and a construct can never wipe an eval error `updateJs` recorded on 1216 * `r.logicError`. */ 1217 __publicField(this, "__ctorError", null); 1218 __publicField(this, "logic"); 1219 this.__name = props.__name; 1220 this.state = { __v: 0, __err: null }; 1221 this.__sub = () => { 1222 if (this.state.__err) this.setState({ __err: null }); 1223 this.forceUpdate(); 1224 }; 1225 this.__makeLogic(registry.get(this.__name).Logic, null); 1226 ensureFetched(this.__name); 1227 } 1228 /** Error-boundary hook: a render crash anywhere in this DC's subtree 1229 * (its own template, an x-import'd component, a child DC without its 1230 * own deeper boundary) lands here instead of unmounting the page. */ 1231 static getDerivedStateFromError(e) { 1232 return { __err: e instanceof Error && e.message ? e.message :
1232String(e) }; 1233 } 1234 componentDidCatch(e, info) { 1235 console.error( 1236 "[dc-runtime] render error in <" + this.__name + ">:", 1237 e, 1238 info?.componentStack || "" 1239 ); 1240 } 1241 /** Instantiate the logic class (or the no-op base) and adopt `prevState` 1242 * over its initial state â used both at mount and on hot-swap. */ 1243 __makeLogic(Logic, prevState) { 1244 const L = Logic || StreamableLogic; 1245 try { 1246 this.logic = new L(this.__userProps()); 1247 this.__failedLogic = null; 1248 this.__failedUserProps = null; 1249 this.__ctorError = null; 1250 } catch (e) { 1251 console.error(e); 1252 this.__failedLogic = Logic; 1253 this.__failedUserProps = this.__userProps(); 1254 this.__failedVer = registry.get(this.__name).ver; 1255 this.__ctorError = this.__name + ": " + (e instanceof Error && e.message ? e.message : String(e)); 1256 this.logic = new StreamableLogic( 1257 this.__userProps() 1258 ); 1259 } 1260 this.logic.__host = this; 1261 if (prevState) 1262 this.logic.state = { ...this.logic.state || {}, ...prevState }; 1263 } 1264 /** The props the author's logic + template see â internal __-prefixed 1265 * wiring stripped. */ 1266 __userProps() { 1267 const { __name, __hintSize, __tplId, __hostStyle, ...rest } = this.props; 1268 return rest; 1269 } 1270 __setLogicState(update, cb) { 1271 const prev = this.logic.state; 1272 const patch = typeof update === "function" ? update(prev) : update; 1273 this.logic.state = { ...prev, ...patch }; 1274 this.setState((s) => ({ __v: s.__v + 1 }), cb); 1275 } 1276 /** Swap the logic instance when the registry's Logic class changed 1277 * (streaming completion, hot reload). State carries over; didMount 1278 * re-fires after the swap commits so refs exist. */ 1279 __reconcileLogic() { 1280 const r = registry.get(this.__name); 1281 const Next = r.Logic; 1282 const Cur = this.logic.constructor; 1283 if (Next === Cur || !Next && Cur === StreamableLogic || Next === this.__failedLogic && r.ver === this.__failedVer && shallowEqual(this.__userProps(), this.__failedUserProps)) { 1284 return; 1285 } 1286 if (!this.__needsDidMount) { 1287 try { 1288 this.logic.componentWillUnmount(); 1289 } catch (e) { 1290 console.error(e); 1291 } 1292 } 1293 this.__makeLogic(Next, this.logic.state); 1294 this.__needsDidMount = true; 1295 } 1296 componentDidMount() { 1297 registry.get(this.__name).subs.add(this.__sub); 1298 try { 1299 this.logic.componentDidMount(); 1300 } catch (e) { 1301 console.error(e); 1302 } 1303 } 1304 componentDidUpdate(prevProps) { 1305 this.logic.props = this.__userProps(); 1306 if (this.__needsDidMount) { 1307 if (this.state.__err || !registry.get(this.__name).tpl) return; 1308 this.__needsDidMount = false; 1309 try { 1310 this.logic.componentDidMount(); 1311 } catch (e) { 1312 console.error(e); 1313 } 1314 } else { 1315 try { 1316 this.logic.componentDidUpdate(prevProps); 1317 } catch (e) { 1318 console.error(e); 1319 } 1320 } 1321 } 1322 componentWillUnmount() { 1323 registry.get(this.__name).subs.delete(this.__sub); 1324 if (!this.__needsDidMount) { 1325 try { 1326 this.logic.componentWillUnmount(); 1327 } catch (e) { 1328 console.error(e); 1329 } 1330 } 1331 } 1332 render() { 1333 const r = registry.get(this.__name); 1334 const cls = "sc-host" + (r.htmlStreaming ? " sc-streaming-html" : "") + (r.jsStreaming ? " sc-streaming-js" : ""); 1335 const hintStyle = r.htmlStreaming ? hintToMin(this.props.__hintSize) : void 0; 1336 const hostStyle = this.props.__hostStyle || hintStyle ? { ...hintStyle || {}, ...this.props.__hostStyle || {} } : void 0; 1337 const hostBase = { 1338 className: cls, 1339 style: hostStyle, 1340 "data-sc-name": this.__name, 1341 "data-dc-tpl": this.props.__tplId 1342 }; 1343 const chain = Array.isArray(this.context) ? this.context : []; 1344 if (chain.includes(this.__name)) { 1345 const cycle = [ 1346 ...chain.slice(chain.indexOf(this.__name)), 1347 this.__name 1348 ].join(" \u2192 "); 1349 return h( 1350 "div", 1351 { ...hostBase, className: cls + " sc-has-error" }, 1352 h(Placeholder, { 1353 name: this.__name, 1354 hintSize: this.props.__hintSize, 1355 error: "circular import: " + cycle 1356 }) 1357 ); 1358 } 1359 if (this.state.__err) { 1360 return h( 1361 "div", 1362 { ...hostBase, className: cls + " sc-has-error" }, 1363 h( 1364 "div", 1365 { className: "sc-logic-error", "data-omelette-chrome": "" }, 1366 this.__name + ": " + this.state.__err 1367 ), 1368 h(Placeholder, { 1369 name: this.__name, 1370 hintSize: this.props.__hintSize, 1371 error: this.state.__err 1372 }) 1373 ); 1374 } 1375 this.__reconcileLogic(); 1376 if (!r.tpl) { 1377 return h( 1378 "div", 1379 hostBase, 1380 h(Placeholder, { name: this.__name, hintSize: this.props.__hintSize }) 1381 ); 1382 } 1383 const userProps = this.__userProps(); 1384 this.logic.props = userProps; 1385 let vals = userProps; 1386 let renderErr = r.logicError || this.__ctorError; 1387 try { 1388 vals = { ...userProps, ...this.logic.renderVals() || {} }; 1389 } catch (e) { 1390 console.error(e); 1391 renderErr = this.__name + ".renderVals(): " + (e instanceof Error && e.message ? e.message :
1391String(e)); 1392 } 1393 this.__streamingNow = !!(r.htmlStreaming || r.jsStreaming); 1394 this.__htmlStreamingNow = !!r.htmlStreaming; 1395 return h( 1396 "div", 1397 { ...hostBase, className: cls + (renderErr ? " sc-has-error" : "") }, 1398 renderErr && h( 1399 "div", 1400 { className: "sc-logic-error", "data-omelette-chrome": "" }, 1401 renderErr 1402 ), 1403 h( 1404 AncestorContext.Provider, 1405 { value: [...chain, this.__name] }, 1406 r.tpl(vals, this) 1407 ) 1408 ); 1409 } 1410 } 1411 __publicField(StreamableComponent, "contextType", AncestorContext); 1412 const named = /* @__PURE__ */ new Map(); 1413 function getDC(name) { 1414 const hit = named.get(name); 1415 if (hit) return hit; 1416 function Dispatcher(p) { 1417 const [, setTick] = React.useState(0); 1418 React.useEffect(() => { 1419 const sub = () => setTick((n) => n + 1); 1420 registry.get(name).subs.add(sub); 1421 return () => { 1422 registry.get(name).subs.delete(sub); 1423 }; 1424 }, []); 1425 ensureFetched(name); 1426 return h(StreamableComponent, { ...p, __name: name }); 1427 } 1428 Dispatcher.displayName = name; 1429 named.set(name, Dispatcher); 1430 return Dispatcher; 1431 } 1432 return { 1433 getDC, 1434 StreamableComponent 1435 }; 1436 } 1437 1438 // src/bundled.ts 1439 function bundledBlob(url) { 1440 const blobs = window.__resourceBlobs; 1441 const b = blobs ? blobs[url.split("#")[0]] : void 0; 1442 return b instanceof Blob ? b : null; 1443 } 1444 1445 // src/cdn.ts 1446 var REACT_URL = "https://unpkg.com/[email protected]/umd/react.production.min.js"; 1447 var REACT_SRI = "sha384-DGyLxAyjq0f9SPpVevD6IgztCFlnMF6oW/XQGmfe+IsZ8TqEiDrcHkMLKI6fiB/Z"; 1448 var REACT_DOM_URL = "https://unpkg.com/[email protected]/umd/react-dom.production.min.js"; 1449 var REACT_DOM_SRI = "sha384-gTGxhz21lVGYNMcdJOyq01Edg0jhn/c22nsx0kyqP0TxaV5WVdsSH1fSDUf5YJj1"; 1450 var BABEL_URL = "https://unpkg.com/@babel/[email protected]/babel.min.js"; 1451 var BABEL_SRI = "sha384-m08KidiNqLdpJqLq95G/LEi8Qvjl/xUYll3QILypMoQ65QorJ9Lvtp2RXYGBFj1y"; 1452 function cdnScriptFor(url, sri) { 1453 const res = window.__resources; 1454 const v = res ? res[url] : void 0; 1455 return typeof v === "string" && v ? { src: v } : { src: url, integrity: sri }; 1456 } 1457 1458 // src/external.ts 1459 var isCustomElementName = (n) => !n.includes(".") && n.includes("-"); 1460 function isRenderableType(g) { 1461 if (typeof g === "function") return !isElementClass(g); 1462 return typeof g === "object" && g !== null && typeof g.$$typeof === "symbol"; 1463 } 1464 function resolveDottedPath(root, name) { 1465 let cur = root; 1466 for (const seg of name.split(".")) { 1467 if (cur == null) return void 0; 1468 cur = cur[seg]; 1469 } 1470 return cur; 1471 } 1472 var GLOBAL_POLL_INTERVAL_MS = 50; 1473 var GLOBAL_POLL_TIMEOUT_MS = 3e4; 1474 function createExternalModules(onResolved) { 1475 const cache = /* @__PURE__ */ new Map(); 1476 let babelLoading = null; 1477 const reportedMissing = /* @__PURE__ */ new Map(); 1478 const polling = /* @__PURE__ */ new Set(); 1479 function ensureBabel() { 1480 if (window.Babel) return Promise.resolve(); 1481 if (babelLoading) return babelLoading; 1482 const babel = cdnScriptFor(BABEL_URL, BABEL_SRI); 1483 babelLoading = new Promise((res, rej) => { 1484 const s = document.createElement("script"); 1485 s.src = babel.src; 1486 if (babel.integrity) { 1487 s.integrity = babel.integrity; 1488 s.crossOrigin = "anonymous"; 1489 } 1490 s.onload = () => res(); 1491 s.onerror = rej; 1492 document.head.appendChild(s); 1493 }); 1494 return babelLoading; 1495 } 1496 const pending = /* @__PURE__ */ new Map(); 1497 function load(kind, url, after) { 1498 const existing = pending.get(url); 1499 if (existing) return existing; 1500 cache.set(url, null); 1501 console.info("[dc-runtime] x-import: loading", url, "(" + kind + ")"); 1502 const ready = Promise.all([
1503 kind === "jsx" ? ensureBabel() : Promise.resolve(), 1504 after ?? Promise.resolve() 1505 ]); 1506 const p = ready.then(() => { 1507 const pre = bundledBlob(url); 1508 if (pre) return pre.text(); 1509 return fetch(url).then((r) => { 1510 if (!r.ok) throw new Error("HTTP " + r.status); 1511 return r.text(); 1512 }); 1513 }).then((src) => { 1514 const code = kind === "jsx" ? window.Babel.transform(src, { 1515 filename: url, 1516 presets: ["react", "typescript"] 1517 }).code : src; 1518 const module = { exports: {} }; 1519 const before = new Set(Object.keys(window)); 1520 //! nosemgrep: eval-and-function-constructor 1521 new Function("React", "module", "exports", "require", code)( 1522 getReact(), 1523 module, 1524 module.exports, 1525 () => ({}) 1526 ); 1527 const globals = {}; 1528 for (const k of Object.keys(window)) { 1529 if (!before.has(k) && typeof window[k] === "function") { 1530 globals[k] = window[k]; 1531 } 1532 } 1533 cache.set(url, { mod: module.exports, globals }); 1534 console.info( 1535 "[dc-runtime] x-import: loaded", 1536 url, 1537 "\u2014 exports:", 1538 Object.keys(module.exports), 1539 "window globals:", 1540 Object.keys(globals) 1541 ); 1542 onResolved(); 1543 }).catch((e) => { 1544 cache.set(url, { 1545 mod: {}, 1546 globals: {}, 1547 error: "failed to load: " + (e instanceof Error && e.message ? e.message : String(e)) 1548 }); 1549 console.error( 1550 "[dc-runtime] x-import: FAILED to load", 1551 url, 1552 "(" + kind + ")", 1553 e 1554 ); 1555 onResolved(); 1556 }); 1557 pending.set(url, p); 1558 return p; 1559 } 1560 function resolve2(url, name) { 1561 const entry = cache.get(url); 1562 if (!entry) return null; 1563 const { mod, globals } = entry; 1564 const C = mod && mod[name] || globals && globals[name] || typeof window !== "undefined" && window[name] || mod && mod.default; 1565 if (typeof C === "function") return C; 1566 const key = url + "\0" + name; 1567 if (!reportedMissing.has(key)) { 1568 reportedMissing.set( 1569 key, 1570 entry.error || 'no export named "' + name + '" (has: ' + Object.keys(mod).join(", ") + ")" 1571 ); 1572 console.error( 1573 "[dc-runtime] x-import: module", 1574 url, 1575 "loaded but has no component named", 1576 JSON.stringify(name), 1577 "\u2014 available exports:", 1578 Object.keys(mod), 1579 "window globals:", 1580 Object.keys(globals), 1581 ". The module must `module.exports = {" + name + "}` or set `window." + name + "`." 1582 ); 1583 } 1584 return null; 1585 } 1586 function waitForGlobal(name) { 1587 if (polling.has(name)) return; 1588 polling.add(name); 1589 const started = Date.now(); 1590 const isCE = isCustomElementName(name); 1591 const tick = () => { 1592 const found = isCE ? customElements.get(name) : isRenderableType(resolveDottedPath(window, name)); 1593 if (found) { 1594 polling.delete(name); 1595 onResolved(); 1596 return; 1597 } 1598 if (Date.now() - started >= GLOBAL_POLL_TIMEOUT_MS) { 1599 console.warn( 1600 "[dc-runtime] x-import: global", 1601 JSON.stringify(name), 1602 "never appeared on window after " + GLOBAL_POLL_TIMEOUT_MS + "ms"
1603 ); 1604 return; 1605 } 1606 setTimeout(tick, GLOBAL_POLL_INTERVAL_MS); 1607 }; 1608 setTimeout(tick, GLOBAL_POLL_INTERVAL_MS); 1609 } 1610 function resolveGlobal(url, name) { 1611 const isCE = isCustomElementName(name); 1612 if (!url) { 1613 if (isCE) { 1614 if (customElements.get(name)) return name; 1615 waitForGlobal(name); 1616 return null; 1617 } 1618 const g2 = resolveDottedPath(window, name); 1619 if (isRenderableType(g2)) return g2; 1620 waitForGlobal(name); 1621 return null; 1622 } 1623 const entry = cache.get(url); 1624 if (!entry) return null; 1625 if (isCE && customElements.get(name)) return name; 1626 const g = entry.globals[name] ?? resolveDottedPath(window, name); 1627 if (isRenderableType(g)) return g; 1628 if (name.includes(".")) return null; 1629 const key = url + "\0global\0" + name; 1630 if (!reportedMissing.has(key)) { 1631 reportedMissing.set(key, null); 1632 if (isCE && !customElements.get(name)) { 1633 console.warn( 1634 "[dc-runtime] x-import:", 1635 url, 1636 "loaded but no custom element", 1637 JSON.stringify(name), 1638 "is registered and window." + name + " is not a function \u2014 rendering <" + name + "> as an unknown element." 1639 ); 1640 } 1641 } 1642 return name; 1643 } 1644 function getError(url, name) { 1645 const entry = cache.get(url); 1646 if (entry?.error) return entry.error; 1647 return reportedMissing.get(url + "\0" + name) || null; 1648 } 1649 return { load, resolve: resolve2, resolveGlobal, getError }; 1650 } 1651 function isElementClass(g) { 1652 try { 1653 return typeof g === "function" && typeof HTMLElement !== "undefined" && g.prototype instanceof HTMLElement; 1654 } catch { 1655 return false; 1656 } 1657 } 1658 1659 // src/atomics.ts 1660 var ATOMIC_CSS = ( 1661 // layout 1662 ".fx{display:flex}.col{display:flex;flex-direction:column}.grid{display:grid}.ac{align-items:center}.jc{justify-content:center}.jb{justify-content:space-between}.f1{flex:1}.noshrink{flex-shrink:0}.wrap{flex-wrap:wrap}.fw5{font-weight:500}.fw6{font-weight:600}.fw7{font-weight:700}.fw8{font-weight:800}.fs11{font-size:11px}.fs12{font-size:12px}.fs13{font-size:13px}.fs14{font-size:14px}.fs15{font-size:15px}.fs16{font-size:16px}.fs20{font-size:20px}.fs22{font-size:22px}.upper{text-transform:uppercase}.tc{text-align:center}.nowrap{white-space:nowrap}.gap8{gap:8px}.gap10{gap:10px}.gap12{gap:12px}.gap16{gap:16px}.gap24{gap:24px}.m0{margin:0}.mt8{margin-top:8px}.mt12{margin-top:12px}.mt16{margin-top:16px}.mb8{margin-bottom:8px}.mb12{margin-bottom:12px}.mb16{margin-bottom:16px}.posrel{position:relative}.posabs{position:absolute}.round{border-radius:50%}.ohide{overflow:hidden}.bbox{box-sizing:border-box}.pointer{cursor:pointer}.w100{width:100%}.b0{border:none}" 1663 ); 1664 1665 // src/helmet.ts 1666 var DESIGN_DOC_MODE_RE = /<meta\b[^>]*\bname\s*=\s*["']design_doc_mode["'][^>]*\b(?:content|value)\s*=\s*["'](\w+)["']/i; 1667 var CANVAS_BG_LIGHT = "#f0eee6"; 1668 var CANVAS_BG_DARK = "#2e2c26"; 1669 function createHelmetManager(doc, isStreaming) { 1670 const mounted = /* @__PURE__ */ new Set(); 1671 const live = /* @__PURE__ */ new Map(); 1672 let designDocMode = null; 1673 let canvasStyleEl = null; 1674 let appTheme = "light"; 1675 try { 1676 const ds = doc.documentElement.dataset.theme; 1677 appTheme = ds === "dark" || ds === "light" ? ds : new URLSearchParams(doc.defaultView?.location.search ?? "").get( 1678 "theme" 1679 ) === "dark" ? "dark" : "light"; 1680 } catch { 1681 } 1682 function applyCanvasBg() { 1683 if (!canvasStyleEl) return; 1684 const bg = appTheme === "dark" ? CANVAS_BG_DARK : CANVAS_BG_LIGHT; 1685 canvasStyleEl.textContent = `html,body{background:${bg}}#dc-root>.sc-host{position:relative}`; 1686 } 1687 function postDesignMode(mode) { 1688 if (window.parent === window) return; 1689 try { 1690 window.parent.postMessage({ type: "__dc_design_mode", mode }, "*"); 1691 } catch { 1692 } 1693 } 1694 function setDesignDocMode(mode) { 1695 if (mode === designDocMode) return; 1696 designDocMode = mode; 1697 postDesignMode(mode); 1698 if (mode === "canvas") { 1699 doc.documentElement.setAttribute("data-dc-canvas", ""); 1700 canvasStyleEl = doc.createElement("style"); 1701 canvasStyleEl.setAttribute("data-dc-canvas", ""); 1702 applyCanvasBg(); 1703 doc.head.appendChild(canvasStyleEl); 1704 } else { 1705 doc.documentElement.removeAttribute("data-dc-canvas"); 1706 canvasStyleEl?.remove(); 1707 canvasStyleEl = null; 1708 } 1709 } 1710 window.addEventListener("message", (e) => { 1711 const type = e.data && e.data.type; 1712 if (type === "__dc_theme") { 1713 const t = e.data.theme; 1714 if (t === "light" || t === "dark") { 1715 appTheme = t; 1716 applyCanvasBg(); 1717 } 1718 return; 1719 } 1720 if (!designDocMode || type !== "__dc_probe") return; 1721 postDesignMode(designDocMode); 1722 }); 1723 function compile(node) { 1724 const raw = [...node.children]; 1725 const helmetClosed = node.nextSibling != null || node.parentNode?.nextSibling != null; 1726 if (node.hasAttribute("data-dc-atomics") && !mounted.has("__dc-atomics")) { 1727 mounted.add("__dc-atomics"); 1728 const el = doc.createElement("style"); 1729 el.id = "__dc-atomics"; 1730 el.textContent = ATOMIC_CSS; 1731 doc.head.appendChild(el); 1732 } 1733 return (_vals, ctx) => { 1734 const name = ctx && ctx.__name || ""; 1735 const streaming = !!(name && isStreaming(name)); 1736 for (let i = 0; i < raw.length; i++) { 1737 const child = raw[i]; 1738 const tag = child.tagName; 1739 const mayBePartial = streaming && !helmetClosed && i === raw.length - 1; 1740 if (tag === "SCRIPT") { 1741 if (mayBePartial) continue;
1742 const key = "SCRIPT|" + (child.getAttribute("src") || child.textContent || ""); 1743 if (mounted.has(key)) continue; 1744 mounted.add(key); 1745 const el = doc.createElement("script"); 1746 for (const { name: an, value } of [...child.attributes]) 1747 el.setAttribute(an, value); 1748 if (child.textContent) el.textContent = child.textContent; 1749 doc.head.appendChild(el); 1750 } else if (tag === "LINK" || tag === "META") { 1751 if (mayBePartial) continue; 1752 const key = tag + "|" + (child.getAttribute("href") || child.getAttribute("src") || child.outerHTML); 1753 if (mounted.has(key)) continue; 1754 mounted.add(key); 1755 if (tag === "LINK") { 1756 const rel = (child.getAttribute("rel") || "").toLowerCase().split(/\s+/); 1757 const href = (child.getAttribute("href") || "").trim(); 1758 const res = window.__resources; 1759 const pre = res && rel.includes("stylesheet") && !rel.includes("alternate") ? res[href] : void 0; 1760 const blob = typeof pre === "string" && pre ? bundledBlob(pre) : null; 1761 if (blob) { 1762 const el = doc.createElement("style"); 1763 if (child.hasAttribute("disabled")) { 1764 el.setAttribute("media", "not all"); 1765 } else if (child.getAttribute("media")) { 1766 el.setAttribute("media", child.getAttribute("media")); 1767 } 1768 if (child.getAttribute("title")) 1769 el.setAttribute("title", child.getAttribute("title")); 1770 void blob.text().then((css) => { 1771 el.textContent = css; 1772 }); 1773 doc.head.appendChild(el); 1774 continue; 1775 } 1776 } 1777 doc.head.appendChild(child.cloneNode(true)); 1778 } else { 1779 const key = name + "|" + i; 1780 let el = live.get(key); 1781 if (!el || el.tagName !== tag) { 1782 if (el) el.remove(); 1783 el = doc.createElement(tag.toLowerCase()); 1784 live.set(key, el); 1785 doc.head.appendChild(el); 1786 } 1787 for (const { name: an, value } of [...child.attributes]) { 1788 if (el.getAttribute(an) !== value) el.setAttribute(an, value); 1789 } 1790 if (el.textContent !== child.textContent) 1791 el.textContent = child.textContent; 1792 } 1793 } 1794 return null; 1795 }; 1796 } 1797 return { compile, setDesignDocMode }; 1798 } 1799 1800 // src/pseudo.ts 1801 function scanUnquotedUrl(css, i) { 1802 if (css[i] !== "u" && css[i] !== "U" || css.slice(i, i + 4).toLowerCase() !== "url(" || /[a-z0-9_-]/i.test(css[i - 1] ?? "")) { 1803 return -1; 1804 } 1805 let j = i + 4; 1806 while (j < css.length && /\s/.test(css[j])) j++; 1807 if (css[j] === '"' || css[j] === "'") return -1; 1808 while (j < css.length && css[j] !== ")") { 1809 if (css[j] === "\\") j++; 1810 j++; 1811 } 1812 return j < css.length ? j + 1 : css.length; 1813 } 1814 function stripComments(css) { 1815 let out = ""; 1816 let quote = ""; 1817 for (let i = 0; i < css.length; i++) { 1818 const c = css[i]; 1819 if (quote) { 1820 if (c === "\\") { 1821 out += c + (css[i + 1] ?? ""); 1822 i++; 1823 continue; 1824 } 1825 if (c === quote) quote = ""; 1826 out += c; 1827 } else if (c === "'" || c === '"') { 1828 quote = c; 1829 out += c; 1830 } else if (c === "/" && css[i + 1] === "*") { 1831 const end = css.indexOf("*/", i + 2); 1832 i = end === -1 ? css.length : end + 1; 1833 out += " "; 1834 } else { 1835 const end = scanUnquotedUrl(css, i); 1836 if (end === -1) out += c; 1837 else { 1838 out += css.slice(i, end); 1839 i = end - 1; 1840 } 1841 } 1842 } 1843 return out; 1844 } 1845 function importantify(css) { 1846 css = stripComments(css); 1847 const decls = []; 1848 let start = 0; 1849 let depth = 0; 1850 let quote = ""; 1851 for (let i = 0; i < css.length; i++) { 1852 const c = css[i]; 1853 if (quote) { 1854 if (c === "\\") i++; 1855 else if (c === quote) quote = ""; 1856 } else if (c === "'" || c === '"') quote = c; 1857 else if (c === "(") depth++; 1858 else if (c === ")") depth = Math.max(0, depth - 1); 1859 else if (c === ";" && depth === 0) { 1860 decls.push(css.slice(start, i)); 1861 start = i + 1; 1862 } else { 1863 const end = scanUnquotedUrl(css, i); 1864 if (end !== -1) i = end - 1; 1865 } 1866 } 1867 decls.push(css.slice(start)); 1868 return decls.map((d) =>
1868 d.trim()).filter(Boolean).map((d) => /!\s*important$/i.test(d) ? d : d + " !important").join(";"); 1869 } 1870 function createPseudoSheet(doc) { 1871 let el = null; 1872 const cache = /* @__PURE__ */ new Map(); 1873 let n = 0; 1874 return (pseudo, css) => { 1875 const k = pseudo + "|" + css; 1876 const hit = cache.get(k); 1877 if (hit) return hit; 1878 if (!el) { 1879 el = doc.createElement("style"); 1880 doc.head.appendChild(el); 1881 } 1882 const cls = "scp" + (n++).toString(36); 1883 const isPseudoElement = pseudo === "before" || pseudo === "after"; 1884 const sel = isPseudoElement ? "." + cls + "::" + pseudo : "." + cls + ":" + pseudo; 1885 el.sheet.insertRule( 1886 sel + "{" + (isPseudoElement ? css : importantify(css)) + "}", 1887 el.sheet.cssRules.length 1888 ); 1889 cache.set(k, cls); 1890 return cls; 1891 }; 1892 } 1893 1894 // src/registry.ts 1895 function createRegistry() { 1896 const entries = /* @__PURE__ */ Object.create(null); 1897 function get(name) { 1898 return entries[name] || (entries[name] = { 1899 html: "", 1900 tpl: null, 1901 Logic: null, 1902 jsStreaming: false, 1903 htmlStreaming: false, 1904 ver: 0, 1905 subs: /* @__PURE__ */ new Set(), 1906 fetched: false 1907 }); 1908 } 1909 function bump(name) { 1910 const r = get(name); 1911 r.ver++; 1912 for (const fn of r.subs) fn(); 1913 } 1914 return { 1915 entries, 1916 get, 1917 bump, 1918 bumpAll() { 1919 for (const n in entries) bump(n); 1920 } 1921 }; 1922 } 1923 1924 // src/runtime.ts 1925 var COMPONENT_DIR = "."; 1926 function createRuntime(doc = document) { 1927 const registry = createRegistry(); 1928 const pseudoClass = createPseudoSheet(doc); 1929 const helmet = createHelmetManager( 1930 doc, 1931 (name) => registry.get(name).htmlStreaming 1932 ); 1933 const external = createExternalModules(() => registry.bumpAll()); 1934 const factory = createComponentFactory(registry, ensureFetched); 1935 const host = { 1936 component: (name) => factory.getDC(name), 1937 placeholder: (props) => h(Placeholder, props), 1938 helmet: (node) => helmet.compile(node), 1939 loadExternal: (kind, url, after) => external.load(kind, url, after), 1940 resolveExternal: (url, name) => external.resolve(url, name), 1941 resolveExternalGlobal: (url, name) => external.resolveGlobal(url, name), 1942 resolveExternalError: (url, name) => external.getError(url, name), 1943 pseudoClass 1944 }; 1945 function ensureFetched(name) { 1946 const r = registry.get(name); 1947 if (r.fetched) return; 1948 r.fetched = true; 1949 const url = COMPONENT_DIR + "/" + encodeURIComponent(name) + ".dc.html"; 1950 const res = window.__resources; 1951 const pre = res ? res[url] : void 0; 1952 const target = typeof pre === "string" && pre ? pre : url; 1953 const blob = bundledBlob(target); 1954 (blob ? blob.text() : fetch(target).then((res2) => { 1955 if (!res2.ok) { 1956 console.error( 1957 '[dc-runtime] sibling fetch for "' + name + '" failed:', 1958 url, 1959 "returned", 1960 res2.status, 1961 "\u2014 the reference renders as an empty placeholder." 1962 ); 1963 return ""; 1964 } 1965 return res2.text(); 1966 })).then((t) => { 1967 if (!t) return; 1968 const parsed = parseDcText(t); 1969 if (!parsed) { 1970 console.error( 1971 '[dc-runtime] sibling fetch for "' + name + '":', 1972 url, 1973 "has no <x-dc> block \u2014 not a Design Component." 1974 ); 1975 return; 1976 } 1977 if (parsed.props) r.propsMeta = parsed.props; 1978 if (parsed.preview) r.preview = parsed.preview; 1979 if (parsed.template && !r.html) updateHtml(name, parsed.template); 1980 if (parsed.js && !r.Logic) updateJs(name, parsed.js); 1981 }).catch( 1982 (e) => console.error( 1983 '[dc-runtime] sibling fetch for "' + name + '" threw:', 1984 url, 1985 e 1986 ) 1987 ); 1988 } 1989 let rootName = null; 1990 function updateHtml(name, html) { 1991 const r = registry.get(name); 1992 r.html = html; 1993 if (name === rootName) { 1994 const mode = DESIGN_DOC_MODE_RE.exec(html)?.[1] ?? null; 1995 if (mode || !r.htmlStreaming) helmet.setDesignDocMode(mode); 1996 }
1997 try { 1998 r.tpl = compileTemplate(html, host); 1999 } catch (e) { 2000 console.error("[dc-runtime] template compile FAILED for", name, e); 2001 } 2002 registry.bump(name); 2003 } 2004 function updateJs(name, src) { 2005 const r = registry.get(name); 2006 const seq = r.jsSeq = (r.jsSeq || 0) + 1; 2007 try { 2008 const Cls = evalDcLogic(src); 2009 if (r.jsSeq !== seq) return; 2010 if (typeof Cls !== "function") { 2011 r.logicError = name + ".dc.html:
2011<script data-dc-script> must define `class Component extends DCLogic`"; 2012 } else { 2013 r.logicError = null; 2014 r.Logic = Cls; 2015 } 2016 } catch (e) { 2017 if (r.jsSeq !== seq) return; 2018 console.error( 2019 "[dc-runtime] logic class eval FAILED for", 2020 name, 2021 "\u2014 the template renders with props only.", 2022 e 2023 ); 2024 r.logicError = name + ": " + (e instanceof Error && e.message ? e.message : String(e)); 2025 } 2026 registry.bump(name); 2027 } 2028 function setStreaming(name, kind, on) { 2029 const r = registry.get(name); 2030 if (kind === "html") r.htmlStreaming = !!on; 2031 else r.jsStreaming = !!on; 2032 let any = false; 2033 for (const n in registry.entries) { 2034 const e = registry.entries[n]; 2035 if (e && (e.htmlStreaming || e.jsStreaming)) { 2036 any = true; 2037 break; 2038 } 2039 } 2040 doc.documentElement.classList.toggle("sc-dc-streaming", any); 2041 registry.bump(name); 2042 } 2043 function dcUpdate(name, kind, content, streaming) { 2044 if (streaming) registry.get(name).fetched = true; 2045 if (kind === "html") { 2046 setStreaming(name, "html", !!streaming); 2047 updateHtml(name, content); 2048 } else if (kind === "js") { 2049 setStreaming(name, "js", !!streaming); 2050 if (!streaming) updateJs(name, content); 2051 } else if (kind === "props") { 2052 const { props, preview } = parseDataProps(content); 2053 const r = registry.get(name); 2054 r.propsMeta = props ?? void 0; 2055 r.preview = preview; 2056 registry.bump(name); 2057 } 2058 } 2059 function setProps(name, overrides) { 2060 registry.get(name).propOverrides = overrides && typeof overrides === "object" ? { ...overrides } : null; 2061 registry.bump(name); 2062 } 2063 function adoptParsed(name, parsed) { 2064 if (!parsed) return; 2065 const r = registry.get(name); 2066 if (parsed.props) r.propsMeta = parsed.props; 2067 if (parsed.preview) r.preview = parsed.preview; 2068 if (parsed.template) updateHtml(name, parsed.template); 2069 if (parsed.js) updateJs(name, parsed.js); 2070 } 2071 return { 2072 registry, 2073 getDC: factory.getDC, 2074 updateHtml, 2075 updateJs, 2076 dcUpdate, 2077 setProps, 2078 adoptParsed, 2079 setRootName: (name) => { 2080 rootName = name; 2081 }, 2082 markFetched: (name) => { 2083 registry.get(name).fetched = true; 2084 }, 2085 annotatedTemplate: (name) => { 2086 const r = registry.get(name); 2087 return r.tpl && r.tpl.__annotated || null; 2088 }, 2089 templateSource: (name) => registry.get(name).html || null, 2090 StreamableLogic 2091 }; 2092 } 2093 2094 // src/stream-state.ts 2095 function createStreamTracker(staleMs = 6e4, now = Date.now) { 2096 const since = /* @__PURE__ */ new Map(); 2097 const liveOne = (n) => { 2098 const t = since.get(n); 2099 if (t === void 0) return false; 2100 if (now() - t > staleMs) { 2101 since.delete(n); 2102 return false; 2103 } 2104 return true; 2105 }; 2106 return { 2107 push(name, streaming, viewportKey) { 2108 if (viewportKey === "dc-model") return; 2109 if (streaming) since.set(name, now()); 2110 else since.delete(name); 2111 }, 2112 live(name) { 2113 if (name !== void 0) return liveOne(name); 2114 for (const n of [...since.keys()]) if (liveOne(n)) return true; 2115 return false; 2116 } 2117 }; 2118 } 2119 2120 // src/index.ts 2121 function hideRawTemplate() { 2122 const s = document.createElement("style"); 2123 s.textContent = "x-dc{display:none!important}"; 2124 document.head.appendChild(s); 2125 } 2126 function loadScript(src, integrity) { 2127 return new Promise((resolve2, reject) => { 2128 //! nosemgrep: create-script-element 2129 const s = document.createElement("script"); 2130 s.src = src; 2131 if (integrity) { 2132 s.integrity = integrity; 2133 s.crossOrigin = "anonymous"; 2134 } 2135 s.async = false; 2136 s.onload = () => resolve2(); 2137 s.onerror = () => reject(new Error(`failed to load ${src}`)); 2138 document.head.appendChild(s); 2139 }); 2140 } 2141 function loadReactUmd() { 2142 const w = window; 2143 if (w.React && w.ReactDOM) return Promise.resolve(); 2144 const react = cdnScriptFor(REACT_URL, REACT_SRI); 2145 const reactDom = cdnScriptFor(REACT_DOM_URL, REACT_DOM_SRI); 2146 return Promise.all([ 2147 loadScript(react.src, react.integrity), 2148 loadScript(reactDom.src, reactDom.integrity) 2149 ]).then(() => void 0); 2150 }
2151 function init() { 2152 const runtime = createRuntime(document); 2153 let rootName = "Root"; 2154 const baseCss = document.createElement("style"); 2155 baseCss.textContent = BASE_CSS; 2156 document.head.prepend(baseCss); 2157 const notifyHost = () => { 2158 if (window.parent === window) return; 2159 const r = runtime.registry.entries[rootName]; 2160 try { 2161 window.parent.postMessage( 2162 { 2163 type: "__dc_booted", 2164 rootName, 2165 propsMeta: r && r.propsMeta || null, 2166 preview: r && r.preview || null 2167 }, 2168 "*" 2169 ); 2170 } catch { 2171 } 2172 }; 2173 const streams = createStreamTracker(); 2174 const api = { 2175 __dcUpdate: (name, kind, content, streaming, viewportKey) => { 2176 streams.push(name, streaming, viewportKey); 2177 runtime.dcUpdate(name, kind, content, streaming); 2178 if (name === rootName && !streaming && kind === "props") notifyHost(); 2179 }, 2180 __dcStreaming: (name) => streams.live(name), 2181 __dcSetProps: (name, overrides) => runtime.setProps(name, overrides), 2182 /** Name of the component currently mounted as the page root â DC tools 2183 * push their template-stream here when targeting "the open page". */ 2184 __dcRootName: () => rootName, 2185 /** Editor bridge â the encoded, `data-dc-tpl`-annotated template source. 2186 * The host editor parses this into its own template DOM so it can map a 2187 * rendered node (carrying the same `data-dc-tpl`) back to the source 2188 * node that emitted it. Returns the encoded form (`sc-camel-*` attrs, 2189 * `<sc-raw-*>`/`<sc-helmet>` tags); the editor decodes on serialize. */ 2190 __dcAnnotatedTemplate: (name) => runtime.annotatedTemplate(name), 2191 /** Editor bridge â the *original* (decoded) template source. */ 2192 __dcTemplateSource: (name) => runtime.templateSource(name), 2193 __dcBoot: () => { 2194 rootName = boot(runtime, document) ?? rootName; 2195 notifyHost(); 2196 }, 2197 __dcRegistry: runtime.registry.entries, 2198 getDC: (name) => runtime.getDC(name), 2199 // `DCLogic` is the documented base class name; `StreamableLogic` is the 2200 // implementation alias kept for any project that already references it. 2201 DCLogic: runtime.StreamableLogic, 2202 StreamableLogic: runtime.StreamableLogic 2203 }; 2204 Object.assign(window, api); 2205 window.__dcContentKeyed = true; 2206 if (document.readyState !== "loading") api.__dcBoot(); 2207 else document.addEventListener("DOMContentLoaded", () => api.__dcBoot()); 2208 } 2209 hideRawTemplate(); 2210 loadReactUmd().then(init).catch((err) => { 2211 console.error("[dc] failed to load React or boot:", err); 2212 throw err; 2213 }); 2214})(); 2215 2216</script>
2216 2217 2218<!DOCTYPE html> 2219<html> 2220<head> 2221<meta charset="utf-8"> 2222<meta name="viewport" content="width=device-width, initial-scale=1">
2223<script src="./support.js"></script>
2223 2224</head> 2225<body> 2226<x-dc> 2227<helmet> 2228<link rel="preconnect" href="https://fonts.googleapis.com" /> 2229<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin="" /> 2230<link href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@400;500;700;900&family=Inter:wght@400;500;600;800&display=swap" rel="stylesheet" /> 2231<style> 2232 html, body { margin: 0; padding: 0; background: #f1f1f1; } 2233 body { font-family: "Noto Sans TC", "Inter", system-ui, sans-serif; color: #2A3138; -webkit-font-smoothing: antialiased; text-wrap: pretty; } 2234 a { color: #608075; text-decoration: none; } 2235 a:hover { color: #2A3138; } 2236 * { box-sizing: border-box; } 2237 input[type=range] { -webkit-appearance: none; appearance: none; background: transparent; } 2238 input[type=range]::-webkit-slider-runnable-track { height: 4px; border-radius: 2px; background: #cfd4d8; } 2239 input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; width: 22px; height: 22px; margin-top: -9px; border-radius: 50%; background: #F7C01B; border: 3px solid #fff; box-shadow: 0 2px 6px rgba(41,41,41,.25); cursor: grab; } 2240 summary::-webkit-details-marker { display: none; } 2241 @keyframes auraDrift { 0% { transform: rotate(0deg) scale(1.08); } 50% { transform: rotate(180deg) scale(1.2); } 100% { transform: rotate(360deg) scale(1.08); } } 2242 @media (prefers-reduced-motion: reduce) { * { animation: none !important; } } 2243</style> 2244</helmet> 2245 2246<div style="background:#f1f1f1;overflow-x:hidden"> 2247 2248<header style="position:sticky;top:0;z-index:40;display:flex;align-items:center;justify-content:space-between;gap:16px;padding:14px clamp(18px,5vw,56px);background:rgba(241,241,241,.86);backdrop-filter:blur(14px);border-bottom:1px solid rgba(42,49,56,.08)"> 2249 <div style="display:flex;align-items:center;gap:10px"> 2250 <div style="width:26px;height:26px;border-radius:9px;background:conic-gradient(from 200deg,#FF2633,#FF851A,#FFE026,#26E659,#1AD9D9,#2659FF,#8C40FF,#FF40BF,#FF2633)"></div> 2251 <span style="font-family:Inter,sans-serif;font-weight:800;letter-spacing:.14em;font-size:15px">ODDCAM</span> 2252 </div> 2253 <a href="https://apps.apple.com/tw/app/oddcam/id6772143344" target="_blank" rel="noopener" style="display:inline-flex;align-items:center;padding:10px 20px;border-radius:999px;background:#F7C01B;color:#2A3138;font-weight:700;font-size:14px">å è²»ä¸è¼</a> 2254</header> 2255 2256<section style="position:relative;display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));align-items:center;gap:clamp(28px,5vw,64px);padding:clamp(48px,8vw,110px) clamp(18px,5vw,56px) clamp(56px,8vw,96px);max-width:1220px;margin:0 auto"> 2257 <div style="position:relative;z-index:2"> 2258 <div style="display:inline-flex;align-items:center;gap:8px;padding:6px 14px;border-radius:999px;background:#73A7BF;color:#fff;font-size:12px;font-weight:700;letter-spacing:.08em">NEW · æ°£å ´ç¸æ© AURA CAMERA</div> 2259 <h1 style="margin:20px 0 0;font-size:clamp(38px,6.4vw,72px);line-height:1.04;font-weight:900;letter-spacing:-.02em">ä½ çæ°£å ´ï¼<br />ä»å¤©æ¯ä»éº¼é¡è²ï¼</h1> 2260 <p style="margin:22px 0 0;max-width:30em;font-size:clamp(16px,1.4vw,19px);line-height:1.75;color:rgba(42,49,56,.78)">ODDCAM æ°£å ´ç¸æ©ï¼æå½©è²å ç°å³æçå¨ä½ 身ä¸ââä¸å¿ è·æå½±æ£ï¼ææ©å°±è½æåºåºçæçæ°£å ´ç §ã</p> 2261 <div style="display:flex;flex-wrap:wrap;align-items:center;gap:16px;margin-top:32px"> 2262 <a href="https://apps.apple.com/tw/app/oddcam/id6772143344" target="_blank" rel="noopener" style="display:inline-flex;align-items:center;gap:10px;padding:17px 32px;border-radius:999px;background:#F7C01B;color:#2A3138;font-weight:700;font-size:17px;box-shadow:0 8px 20px rgba(247,192,27,.38)" style-hover="transform:translateY(-2px);box-shadow:0 12px 26px rgba(247,192,27,.5)">å è²»ä¸è¼ ODDCAM</a> 2263 <a href="#modes" style="font-size:15px;font-weight:500;color:#608075;border-bottom:1px solid rgba(96,128,117,.4);padding-bottom:2px">ççè½æåºä»éº¼ â</a> 2264 </div> 2265 <p style="margin:22px 0 0;font-size:13px;color:rgba(42,49,56,.5);line-height:1.7">iOS 15+ · æ¯æ¬¾ç¸æ©å è²»è©¦ç¨ 3 次 · Pro 䏿¬¡è²·æ·ä¸è¨é±</p> 2266 </div> 2267 <div style="position:relative;aspect-ratio:4/5;border-radius:24px;overflow:hidden;background:#e4e4e4;box-shadow:0 18px 50px rgba(41,41,41,.16)"> 2268 <div style="position:absolute;inset:-30%;filter:blur(60px);opacity:.85;background:conic-gradient(from 30deg,#FF2633,#FF851A,#FFE026,#26E659,#1AD9D9,#2659FF,#8C40FF,#FF40BF,#FF2633);animation:auraDrift 26s linear infinite"></div> 2269 <img decoding="async" src="https://imgpoi.com/i/M4YPHB.jpg" alt="æ°£å ´ç¸æ©å¯¦æç¯ä¾ï¼å½©è²å ç°å å人å" style="position:relative;z-index:2;width:100%;height:100%;object-fit:cover;mix-blend-mode:normal" /> 2270 </div> 2271</section> 2272 2273<section style="padding:clamp(44px,7vw,88px) clamp(18px,5vw,56px);max-width:1120px;margin:0 auto"> 2274 <h2 style="margin:0 0 36px;font-size:clamp(26px,3.4vw,40px);font-weight:900;letter-spacing:-.01em">æ°£å ´ç §ï¼ä¸ç¨åæéçæå½±æ£</h2>
2275 <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:20px"> 2276 <div style="padding:28px;border-radius:18px;background:#e6e6e6;color:rgba(42,49,56,.62)"> 2277 <div style="font-size:13px;font-weight:700;letter-spacing:.1em;margin-bottom:20px">å³çµ±æ°£å ´æå½±</div> 2278 <div style="display:grid;gap:14px;font-size:15px;line-height:1.6"> 2279 <div>è¦é ç´ãè¦åºéãè¦çæ²å°</div> 2280 <div>ä¸å¼µæ¸ç¾å ï¼æå£äºä¹ç®</div> 2281 <div>é¡è²ç±æ©å¨æ±ºå®ï¼æå®æç¥é</div> 2282 <div>åªæç §ç</div> 2283 </div> 2284 </div> 2285 <div style="padding:28px;border-radius:18px;background:#fff;box-shadow:0 3px 8px rgba(41,41,41,.08);border:2px solid #F7C01B"> 2286 <div style="font-size:13px;font-weight:700;letter-spacing:.1em;margin-bottom:20px;color:#608075">ODDCAM æ°£å ´ç¸æ©</div> 2287 <div style="display:grid;gap:14px;font-size:15px;line-height:1.6;font-weight:500"> 2288 <div>æé Appï¼å³æé 覽</div> 2289 <div>æ³æå¹¾å¼µå°±æå¹¾å¼µ</div> 2290 <div>èªå·±é¸é¡è²ï¼æäº¤çµ¦é¨æ©</div> 2291 <div>ç §çãå½±çé½è½æ</div> 2292 </div> 2293 </div> 2294 </div> 2295 <p style="margin:28px 0 0;font-size:clamp(17px,2vw,22px);font-weight:700;color:#608075">忍£çå¤¢å¹»è²æï¼ä¸»å°æ¬å¨ä½ æä¸ã</p> 2296</section> 2297 2298<section style="padding:clamp(44px,7vw,88px) clamp(18px,5vw,56px);max-width:1120px;margin:0 auto"> 2299 <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:clamp(28px,4vw,56px);align-items:center"> 2300 <div style="position:relative;aspect-ratio:4/5;border-radius:18px;overflow:hidden;background:#111;box-shadow:0 3px 8px rgba(41,41,41,.12)"> 2301 <img decoding="async" src="https://imgpoi.com/i/M4YPHB.jpg" alt="æ°£å ´ç¸æ©äºå示ç¯" style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover" /> 2302 <div style="position:absolute;inset:-20%;filter:blur(34px);opacity:.92;background:{{ auraBg }};-webkit-mask-image:{{ auraMask }};mask-image:{{ auraMask }}"></div> 2303 <div style="position:absolute;left:14px;bottom:14px;z-index:3;padding:6px 12px;border-radius:999px;background:rgba(0,0,0,.45);color:#fff;font-family:Inter,sans-serif;font-size:12px;font-weight:600;backdrop-filter:blur(6px)">æ°£å ´ç¯å {{ rangeLabel }}</div> 2304 </div> 2305 <div> 2306 <div style="font-size:12px;font-weight:700;letter-spacing:.14em;color:#7093B4">äºåç¤ºç¯ Â· ææ³è©¦è©¦</div> 2307 <h3 style="margin:12px 0 0;font-size:clamp(24px,3vw,34px);font-weight:900;line-height:1.2">å «ç¨®å æè²ï¼æå¤åè²åææ··å</h3> 2308 <p style="margin:16px 0 0;font-size:16px;line-height:1.8;color:rgba(42,49,56,.78)">ç´ ãæ©ãé»ãç¶ ãéãèãç´«ãæ´ç´ ââææå¤å種é¡è²ï¼å ç°æç §ä½ é»é¸çé åºæ··è²ãä¸ç¥éæä»éº¼ï¼åå°é¨æ©æ¨¡å¼ï¼æ¯æ¬¡é²ç¸æ©èªåæ½ 2â3 è²ï¼æå°æ»¿æçºæ¢ã</p> 2309 <div style="display:flex;flex-wrap:wrap;gap:12px;margin-top:24px"> 2310 <sc-for list="{{ swatches }}" as="sw" hint-placeholder-count="8"> 2311 <button type="button" onClick="{{ sw.pick }}" aria-label="{{ sw.name }}" style="width:44px;height:44px;border-radius:50%;cursor:pointer;background:{{ sw.hex }};border:{{ sw.border }};box-shadow:0 2px 6px rgba(41,41,41,.16)" style-hover="transform:scale(1.08)"></button> 2312 </sc-for> 2313 </div> 2314 <div style="margin-top:32px;display:grid;gap:26px"> 2315 <label style="display:block"> 2316 <div style="display:flex;justify-content:space-between;font-size:14px;font-weight:700;margin-bottom:10px"><span>æ°£å ´ç¯å</span><span style="font-family:Inter,sans-serif;color:#608075">{{ rangeLabel }}</span></div> 2317 <input type="range" min="20" max="100" step="1" value="{{ range }}" onChange="{{ onRange }}" style="width:100%" /> 2318 <div style="display:flex;justify-content:space-between;font-size:12px;color:rgba(42,49,56,.45);margin-top:6px"><span>20% ä¸å¤®çç½</span><span>100% 滿ç</span></div> 2319 </label> 2320 <label style="display:block"> 2321 <div style="display:flex;justify-content:space-between;font-size:14px;font-weight:700;margin-bottom:10px"><span>é緣羽å</span><span style="font-family:Inter,sans-serif;color:#608075">{{ featherLabel }}</span></div> 2322 <input type="range" min="0" max="100" step="1" value="{{ feather }}" onChange="{{ onFeather }}" style="width:100%" /> 2323 <div style="display:flex;justify-content:space-between;font-size:12px;color:rgba(42,49,56,.45);margin-top:6px"><span>éçä¿è½</span><span>å¹¾ä¹çä¸åºäº¤ç</span></div> 2324 </label> 2325 </div> 2326 </div> 2327 </div> 2328</section> 2329 2330<section style="padding:clamp(20px,4vw,44px) clamp(18px,5vw,56px) clamp(44px,7vw,80px);max-width:1120px;margin:0 auto"> 2331 <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:clamp(28px,4vw,56px);align-items:center"> 2332 <div> 2333 <h3 style="margin:0;font-size:clamp(22px,2.6vw,30px);font-weight:900;line-height:1.25">䏿¢ææ¡¿æ±ºå®é¡è²é¢ä½ å¤è¿ï¼å¦ä¸æ¢è®äº¤çæ¶å¤±</h3> 2334 <p style="margin:16px 0 0;font-size:16px;line-height:1.8;color:rgba(42,49,56,.78)">20% æä¸å¤®çä¸å¤§çæ¸ æ°åï¼äººåæ¸ æ¥ãå ç°å¨å¤åï¼ä¸è·¯æ¨å° 100%ï¼é¡è²æ·¹æ²æ´åç«é¢ãåªå©é±ç´è¼ªå»éåºä¾ãç¾½å調ä½éçä¿è½ï¼èª¿é«ï¼è²æåå¾å¹¾ä¹çä¸åºå¾åªè£¡éå§ââå°±åé¡è²ççå¾ä½ èº«ä¸æ£åºä¾ã</p> 2335 <p style="margin:18px 0 0;font-size:14px;color:rgba(42,49,56,.5);line-height:1.7">æ°£å ´å¼·åº¦å¦æä¸æ®µå¯é¸ï¼è¼æï¼æ¨æºï¼æ¿çã</p> 2336 </div> 2337 <div style="border-radius:18px;overflow:hidden;background:#fff;box-shadow:0 3px 8px rgba(41,41,41,.08);padding:14px"> 2338 <img decoding="async" src="https://imgpoi.com/i/M4Y1VG.png" alt="æ°£å ´ç¸æ©è¨å®ç«é¢ï¼é¸è²å¨èææ¡¿" style="display:block;width:100%;border-radius:10px" /> 2339 </div> 2340 </div> 2341</section> 2342 2343<section style="padding:clamp(44px,7vw,80px) clamp(18px,5vw,56px);background:#608075"> 2344 <div style="max-width:1120px;margin:0 auto;display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:18px"> 2345 <div style="padding:24px;border-radius:18px;background:rgba(255,255,255,.1)"> 2346 <div style="font-size:15px;font-weight:700;color:#F7C01B">峿é 覽</div> 2347 <div style="margin-top:8px;font-size:14px;line-height:1.7;color:rgba(255,255,255,.85)">æä¹åå°±çå¾å°æåï¼ä¸ç¨äºå¾ä¿®</div> 2348 </div> 2349 <div style="padding:24px;border-radius:18px;background:rgba(255,255,255,.1)"> 2350 <div style="font-size:15px;font-weight:700;color:#F7C01B">éæ²æ°£å ´</div> 2351 <div style="margin-top:8px;font-size:14px;line-height:1.7;color:rgba(255,255,255,.85)">ä¸éµæä¸çµå ç°ä½å±ï¼é¨æ©æ¨¡å¼é£é¡è²ä¸èµ·éæ½</div> 2352 </div> 2353 <div style="padding:24px;border-radius:18px;background:rgba(255,255,255,.1)"> 2354 <div style="font-size:15px;font-weight:700;color:#F7C01B">ç §çèå½±ç</div> 2355 <div style="margin-top:8px;font-size:14px;line-height:1.7;color:rgba(255,255,255,.85)">ææç´æ¥çéé² 1080pï¼4K å½±ç</div> 2356 </div> 2357 <div style="padding:24px;border-radius:18px;background:rgba(255,255,255,.1)"> 2358 <div style="font-size:15px;font-weight:700;color:#F7C01B">é è¨èªæ</div> 2359 <div style="margin-top:8px;font-size:14px;line-height:1.7;color:rgba(255,255,255,.85)">çºäººåè¨è¨ï¼åå¾é¡é é½è½ç¨</div> 2360 </div> 2361 <div style="padding:24px;border-radius:18px;background:rgba(255,255,255,.1)"> 2362 <div style="font-size:15px;font-weight:700;color:#F7C01B">實é«éµæä½</div> 2363 <div style="margin-top:8px;font-size:14px;line-height:1.7;color:rgba(255,255,255,.85)">é³éä¸éµæç §ãé³éä¸éµéæ²ï¼iOS 17.2+ï¼</div> 2364 </div> 2365 <div style="padding:24px;border-radius:18px;background:rgba(255,255,255,.1)"> 2366 <div style="font-size:15px;font-weight:700;color:#F7C01B">æ¬æ©èç</div> 2367 <div style="margin-top:8px;font-size:14px;line-height:1.7;color:rgba(255,255,255,.85)">å½±åä¸é¢éä½ çææ©</div> 2368 </div> 2369 </div> 2370</section> 2371 2372<section id="modes" style="padding:clamp(48px,7vw,96px) clamp(18px,5vw,56px);max-width:1220px;margin:0 auto"> 2373 <h2 style="margin:0;font-size:clamp(26px,3.6vw,44px);font-weight:900;letter-spacing:-.01em">
2373ä¸åªæ°£å ´ï¼éæä¹ç¨®ææ³å¨çä½ </h2> 2374 <p style="margin:14px 0 40px;font-size:17px;color:rgba(42,49,56,.62)">å䏿¯ Appï¼åæå種é主æµç¸æ©ã</p> 2375 <div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:20px"> 2376 <div style="border-radius:18px;background:#fff;box-shadow:0 3px 8px rgba(41,41,41,.08);overflow:hidden;border:2px solid #F7C01B"> 2377 <div style="position:relative;aspect-ratio:4/5;background:#111;overflow:hidden"> 2378 <img decoding="async" src="https://imgpoi.com/i/M4YY8M.png" alt="æ°£å ´ç¸æ©é¦é å¡ç" style="width:100%;height:100%;object-fit:cover" /> 2379 <div style="position:absolute;top:12px;left:12px;padding:5px 11px;border-radius:999px;background:#F7C01B;font-size:11px;font-weight:800;letter-spacing:.08em">NEW</div> 2380 </div> 2381 <div style="padding:18px 20px 22px"> 2382 <div style="font-size:17px;font-weight:800">æ°£å ´ç¸æ©</div> 2383 <div style="margin-top:8px;font-size:14px;line-height:1.65;color:rgba(42,49,56,.68)">彩è²å ç°å³æå å人åï¼é è²ãç¯åãç¾½åé½è½èª¿</div> 2384 </div> 2385 </div> 2386 <div style="border-radius:18px;background:#fff;box-shadow:0 3px 8px rgba(41,41,41,.08);overflow:hidden"> 2387 <div style="aspect-ratio:4/5;background:#e9e9e9;overflow:hidden"><img decoding="async" src="https://imgpoi.com/i/M4NGDM.png" alt="æ¾å¤§é¡ç¸æ©å¯¦æ" style="width:100%;height:100%;object-fit:cover" /></div> 2388 <div style="padding:18px 20px 22px"><div style="font-size:17px;font-weight:800">æ¾å¤§é¡ç¸æ©</div><div style="margin-top:8px;font-size:14px;line-height:1.65;color:rgba(42,49,56,.68)">黿¡å §æ¾å¤§æé 宿´ååï¼ä¸å¼µåçè¦å ©ç¨®è·é¢</div></div> 2389 </div> 2390 <div style="border-radius:18px;background:#fff;box-shadow:0 3px 8px rgba(41,41,41,.08);overflow:hidden"> 2391 <div style="aspect-ratio:4/5;background:#e9e9e9;overflow:hidden"><img decoding="async" src="https://imgpoi.com/i/M4NE8D.png" alt="å¤é»æ°£æ³¡æ¾å¤§é¡ç¸æ©å¯¦æ" style="width:100%;height:100%;object-fit:cover" /></div> 2392 <div style="padding:18px 20px 22px"><div style="font-size:17px;font-weight:800">å¤é»æ°£æ³¡æ¾å¤§é¡</div><div style="margin-top:8px;font-size:14px;line-height:1.65;color:rgba(42,49,56,.68)">æå¤å ååå½¢æ¾å¤§åï¼ææ³ç§»åãæå縮æ¾</div></div> 2393 </div> 2394 <div style="border-radius:18px;background:#fff;box-shadow:0 3px 8px rgba(41,41,41,.08);overflow:hidden"> 2395 <div style="aspect-ratio:4/5;background:#e9e9e9;overflow:hidden"><img decoding="async" src="https://imgpoi.com/i/M4ND9E.png" alt="æ½è²ç¸æ©è¨å®ç«é¢" style="width:100%;height:100%;object-fit:cover" /></div> 2396 <div style="padding:18px 20px 22px"><div style="font-size:17px;font-weight:800">æ½è²ç¸æ©</div><div style="margin-top:8px;font-size:14px;line-height:1.65;color:rgba(42,49,56,.68)">åªçä¸ä½ æå®çé¡è²ï¼å ¶é¤è½çºé»ç½</div></div> 2397 </div> 2398 <div style="border-radius:18px;background:#fff;box-shadow:0 3px 8px rgba(41,41,41,.08);overflow:hidden"> 2399 <div style="aspect-ratio:4/5;background:#e9e9e9;overflow:hidden"><img decoding="async" src="https://imgpoi.com/i/M4NVLV.png" alt="é¡åç¸æ©å¯¦æ" style="width:100%;height:100%;object-fit:cover" /></div> 2400 <div style="padding:18px 20px 22px"><div style="font-size:17px;font-weight:800">é¡åç¸æ© Flip</div><div style="margin-top:8px;font-size:14px;line-height:1.65;color:rgba(42,49,56,.68)">å ©å´åå¥ä¸ç¨® LUTï¼å¯åèªæè½ 90 度ååæ</div></div> 2401 </div> 2402 <div style="border-radius:18px;background:#fff;box-shadow:0 3px 8px rgba(41,41,41,.08);overflow:hidden"> 2403 <div style="aspect-ratio:4/5;background:#e9e9e9;overflow:hidden"><img decoding="async" src="https://imgpoi.com/i/M4N0QB.png" alt="åå²ç¸æ©å¯¦æ" style="width:100%;height:100%;object-fit:cover" /></div> 2404 <div style="padding:18px 20px 22px"><div style="font-size:17px;font-weight:800">åå²ç¸æ©</div><div style="margin-top:8px;font-size:14px;line-height:1.65;color:rgba(42,49,56,.68)">ä¾åºæ 2â8 æ ¼ï¼åæä¸å¼µåå²ä½å</div></div> 2405 </div> 2406 <div style="border-radius:18px;background:#fff;box-shadow:0 3px 8px rgba(41,41,41,.08);overflow:hidden"> 2407 <div style="aspect-ratio:4/5;background:#e9e9e9;overflow:hidden"><img decoding="async" src="https://imgpoi.com/i/M4NC1G.png" alt="å°åç¸æ©å¯¦æ" style="width:100%;height:100%;object-fit:cover" /></div> 2408 <div style="padding:18px 20px 22px"><div style="font-size:17px;font-weight:800">å°åç¸æ©</div><div style="margin-top:8px;font-size:14px;line-height:1.65;color:rgba(42,49,56,.68)">ç¸æ©èå°ååæ¡ï¼è¨ä¸ç¶ç·¯åº¦ãæµ·æèè¡é</div></div> 2409 </div> 2410 <div style="border-radius:18px;background:#fff;box-shadow:0 3px 8px rgba(41,41,41,.08);overflow:hidden"> 2411 <div style="aspect-ratio:4/5;background:#e9e9e9;overflow:hidden"><img decoding="async" src="https://imgpoi.com/i/M4NBR2.png" alt="ç¹ç¸«ææç¸æ©å¯¦æ" style="width:100%;height:100%;object-fit:cover" /></div> 2412 <div style="padding:18px 20px 22px"><div style="font-size:17px;font-weight:800">ç¹ç¸«ææ</div><div style="margin-top:8px;font-size:14px;line-height:1.65;color:rgba(42,49,56,.68)">åºå®ç¹ç¸«éæ¢ææï¼æåºæç©ºæä¼¸çç §ç</div></div> 2413 </div> 2414 <div style="border-radius:18px;background:#fff;box-shadow:0 3px 8px rgba(41,41,41,.08);overflow:hidden"> 2415 <div style="aspect-ratio:4/5;background:#e9e9e9;overflow:hidden"><img decoding="async" src="https://imgpoi.com/i/M4NQH9.png" alt="ææ²ç¸æ©å¯¦æ" style="width:100%;height:100%;object-fit:cover" /></div> 2416 <div style="padding:18px 20px 22px"><div style="font-size:17px;font-weight:800">ææ²ç¸æ©</div><div style="margin-top:8px;font-size:14px;line-height:1.65;color:rgba(42,49,56,.68)">æ£å¼¦æ³¢å¹¾ä½ææ²ï¼å¼·åº¦ãå¯åº¦ãæ°´æ³¢é½å¯èª¿</div></div> 2417 </div> 2418 <div style="border-radius:18px;background:#fff;box-shadow:0 3px 8px rgba(41,41,41,.08);overflow:hidden"> 2419 <div style="aspect-ratio:4/5;background:#e9e9e9;overflow:hidden"><img decoding="async" src="https://imgpoi.com/i/M4YY8M.png" alt="æ½æ°´ç¸æ©é¦é å¡ç" style="width:100%;height:100%;object-fit:cover;object-position:bottom" /></div> 2420 <div style="padding:18px 20px 22px"><div style="font-size:17px;font-weight:800">æ½æ°´ç¸æ©</div><div style="margin-top:8px;font-size:14px;line-height:1.65;color:rgba(42,49,56,.68)">
2420便°´æ·±éåæ°´ä¸æµå¤±çç´ è²ï¼é³é鵿°´ä¸ä¹è½æä½ï¼2ï¼5ï¼10ï¼20 å ¬å°ºï¼</div></div> 2421 </div> 2422 </div> 2423</section> 2424 2425<section style="padding:clamp(44px,7vw,88px) clamp(18px,5vw,56px);max-width:1120px;margin:0 auto"> 2426 <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:clamp(28px,4vw,56px);align-items:center"> 2427 <div> 2428 <div style="font-size:12px;font-weight:700;letter-spacing:.14em;color:#7093B4">LUT å¤è§æ¿¾é¡</div> 2429 <h3 style="margin:12px 0 0;font-size:clamp(24px,3vw,34px);font-weight:900;line-height:1.2">11 種ååµ LUTï¼éè½å¯å ¥ä½ èªå·±ç</h3> 2430 <p style="margin:16px 0 0;font-size:16px;line-height:1.8;color:rgba(42,49,56,.78)">å §å»º 11 種ååµé¢¨æ ¼ LUTï¼ä¸æ¬¡å¥ç¨å°é 覽ãç §çèå½±çãæèªå·±æ £ç¨ç調è²ï¼ä¸å³ .cube æªå°±è½ç´æ¥ç¨ãæ³æåå§è²èª¿ï¼é¸ãåå§ãå³å¯ééã</p> 2431 </div> 2432 <div style="border-radius:18px;overflow:hidden;background:#fff;box-shadow:0 3px 8px rgba(41,41,41,.08);padding:14px"> 2433 <img decoding="async" src="https://imgpoi.com/i/M4YZV5.png" alt="ææ²ç¸æ©è¨å®é é¢ï¼å« LUT 鏿" style="display:block;width:100%;border-radius:10px" /> 2434 </div> 2435 </div> 2436</section> 2437 2438<section style="padding:clamp(44px,7vw,88px) clamp(18px,5vw,56px);max-width:1120px;margin:0 auto"> 2439 <h2 style="margin:0 0 12px;text-align:center;font-size:clamp(26px,3.4vw,40px);font-weight:900">䏿¬¡è²·æ·ï¼ä¸æ¯è¨é±</h2> 2440 <p style="margin:0 auto 36px;max-width:44em;text-align:center;font-size:16px;line-height:1.8;color:rgba(42,49,56,.7)">æ¯æ¬¾ç¸æ©é½å¯ä»¥å å è²»é²å ¥ 3 次ï¼åç¸æ©åéè¨ç®ï¼ï¼å䏿¬¡é²å ¥å §æ³æå¤å°å¼µé½å¯ä»¥ã試é覺å¾å°å³ï¼åç¨ ODDCAM Pro 䏿¬¡è§£éå ¨é¨æ¨¡å¼ãç¡é使ç¨ã</p> 2441 <div style="max-width:460px;margin:0 auto;padding:32px;border-radius:18px;background:#fff;border:2px solid #F7C01B;box-shadow:0 3px 8px rgba(41,41,41,.08)"> 2442 <div style="display:flex;align-items:center;justify-content:space-between;gap:12px"> 2443 <div style="font-size:22px;font-weight:900">ODDCAM Pro</div> 2444 <div style="padding:5px 12px;border-radius:999px;background:#73A7BF;color:#fff;font-size:12px;font-weight:700">䏿¬¡è²·æ· · éè¨é±</div> 2445 </div> 2446 <div style="display:grid;gap:12px;margin:24px 0 28px;font-size:15px;line-height:1.6"> 2447 <div>è§£éå ¨é¨åç¨®ç¸æ©ï¼ç¡é次é²å ¥</div> 2448 <div>ä¸ç¶æè²»ãä¸èªåçºè¨</div> 2449 <div>å¯è·¨è£ç½®æ¢å¾©è³¼è²·</div> 2450 </div> 2451 <a href="https://apps.apple.com/tw/app/oddcam/id6772143344" target="_blank" rel="noopener" style="display:block;text-align:center;padding:16px;border-radius:999px;background:#F7C01B;color:#2A3138;font-weight:700;font-size:16px" style-hover="filter:brightness(1.05)">ä¸è¼ App æ¥ç广 ¼</a> 2452 </div> 2453</section> 2454 2455<section style="padding:clamp(44px,7vw,88px) clamp(18px,5vw,56px);background:#e7eaee"> 2456 <div style="max-width:1120px;margin:0 auto"> 2457 <h2 style="margin:0;font-size:clamp(24px,3.2vw,38px);font-weight:900">ä½ çç §çï¼ä¸æé¢éä½ çææ©</h2> 2458 <p style="margin:14px 0 32px;max-width:44em;font-size:16px;line-height:1.8;color:rgba(42,49,56,.72)">ææå½±åèçé½å¨è£ç½®æ¬æ©å®æï¼ODDCAM 䏿æä½ çç §çæå½±çä¸å³å°ä»»ä½é²ç«¯ã</p> 2459 <div style="display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:16px"> 2460 <div style="padding:20px;border-radius:18px;background:#fff"><div style="font-weight:800;font-size:15px">ç¸æ©</div><div style="margin-top:6px;font-size:14px;color:rgba(42,49,56,.66)">忍¡å¼ç峿é è¦½èææ</div></div> 2461 <div style="padding:20px;border-radius:18px;background:#fff"><div style="font-weight:800;font-size:15px">麥å 風</div><div style="margin-top:6px;font-size:14px;color:rgba(42,49,56,.66)">éå½±æ¶é³</div></div> 2462 <div style="padding:20px;border-radius:18px;background:#fff"><div style="font-weight:800;font-size:15px">ç¸ç°¿</div><div style="margin-top:6px;font-size:14px;color:rgba(42,49,56,.66)">å²åç §çèå½±ç</div></div> 2463 <div style="padding:20px;border-radius:18px;background:#fff"><div style="font-weight:800;font-size:15px">å®ä½ï¼ä½¿ç¨æï¼</div><div style="margin-top:6px;font-size:14px;color:rgba(42,49,56,.66)">å°åç¸æ©é¡¯ç¤ºä½ç½®è³è¨</div></div> 2464 </div> 2465 </div> 2466</section> 2467 2468<section style="padding:clamp(44px,7vw,88px) clamp(18px,5vw,56px);max-width:820px;margin:0 auto"> 2469 <h2 style="margin:0 0 28px;font-size:clamp(24px,3.2vw,38px);font-weight:900">常è¦åé¡</h2>
2470 <div style="display:grid;gap:12px"> 2471 <details style="padding:20px 22px;border-radius:18px;background:#fff;box-shadow:0 3px 8px rgba(41,41,41,.08)"> 2472 <summary style="list-style:none;cursor:pointer;font-size:16px;font-weight:700">æ°£å ´ç¸æ©æåºä¾çé¡è²ï¼æ¯çç鿏¬æçæ°£å ´åï¼</summary> 2473 <p style="margin:14px 0 0;font-size:15px;line-height:1.8;color:rgba(42,49,56,.72)">䏿¯ãODDCAM çæ°£å ´ç¸æ©æ¯ä¸ç¨®å½±åææââç±ä½ é¸å®ï¼æé¨æ©æ½é¸ï¼çé¡è²çæå ç°ä¸¦çå¨ç«é¢ä¸ï¼ç¨ä¾æåºå¥½ççæ°£å ´é¢¨æ ¼ç §çãå®ä¸åä»»ä½ççæè½é鿏¬ã</p> 2474 </details> 2475 <details style="padding:20px 22px;border-radius:18px;background:#fff;box-shadow:0 3px 8px rgba(41,41,41,.08)"> 2476 <summary style="list-style:none;cursor:pointer;font-size:16px;font-weight:700">éè¦ç¶²è·¯é£ç·åï¼</summary> 2477 <p style="margin:14px 0 0;font-size:15px;line-height:1.8;color:rgba(42,49,56,.72)">ææèèçå®å ¨å¨æ¬æ©é²è¡ï¼ä¸éè¦é£ç·ã</p> 2478 </details> 2479 <details style="padding:20px 22px;border-radius:18px;background:#fff;box-shadow:0 3px 8px rgba(41,41,41,.08)"> 2480 <summary style="list-style:none;cursor:pointer;font-size:16px;font-weight:700">æææ¯æå®åå¥ï¼éæ¯æçæåå°±æï¼</summary> 2481 <p style="margin:14px 0 0;font-size:15px;line-height:1.8;color:rgba(42,49,56,.72)">峿é 覽就çå¾å°ï¼ä¸æææç´æ¥çéé²ç §çèå½±çã</p> 2482 </details> 2483 <details style="padding:20px 22px;border-radius:18px;background:#fff;box-shadow:0 3px 8px rgba(41,41,41,.08)"> 2484 <summary style="list-style:none;cursor:pointer;font-size:16px;font-weight:700">ä¸å®è¦ç¨åé¡é åï¼</summary> 2485 <p style="margin:14px 0 0;font-size:15px;line-height:1.8;color:rgba(42,49,56,.72)">æ°£å ´ç¸æ©é è¨ä½¿ç¨åé¡é ï¼çºèªæäººåè¨è¨ï¼ï¼ä½åå¾é¡é é½å¯ä»¥åæä½¿ç¨ã</p> 2486 </details> 2487 <details style="padding:20px 22px;border-radius:18px;background:#fff;box-shadow:0 3px 8px rgba(41,41,41,.08)"> 2488 <summary style="list-style:none;cursor:pointer;font-size:16px;font-weight:700">Pro æ¯è¨é±å¶åï¼</summary> 2489 <p style="margin:14px 0 0;font-size:15px;line-height:1.8;color:rgba(42,49,56,.72)">䏿¯ãODDCAM Pro æ¯ä¸æ¬¡è²·æ·çéæ¶èåè³¼è²·ï¼æææ©å¯ä»¥æ¢å¾©è³¼è²·ã</p> 2490 </details> 2491 <details style="padding:20px 22px;border-radius:18px;background:#fff;box-shadow:0 3px 8px rgba(41,41,41,.08)"> 2492 <summary style="list-style:none;cursor:pointer;font-size:16px;font-weight:700">æ¯æ´åªäºæ©åï¼</summary> 2493 <p style="margin:14px 0 0;font-size:15px;line-height:1.8;color:rgba(42,49,56,.72)">iOS 15 以ä¸ç iPhoneãé¨ååè½ï¼å¦é³é鵿æï¼éè¦ iOS 17.2 以ä¸ã</p> 2494 </details> 2495 </div> 2496</section> 2497 2498<footer style="position:relative;overflow:hidden;padding:clamp(60px,9vw,120px) clamp(18px,5vw,56px) clamp(90px,10vw,120px);background:#2A3138;color:#fff;text-align:center"> 2499 <div style="position:absolute;inset:-40% -10%;filter:blur(90px);opacity:.5;background:conic-gradient(from 120deg,#FF2633,#FF851A,#FFE026,#26E659,#1AD9D9,#2659FF,#8C40FF,#FF40BF,#FF2633);animation:auraDrift 30s linear infinite"></div> 2500 <div style="position:relative;z-index:2;max-width:720px;margin:0 auto"> 2501 <h2 style="margin:0;font-size:clamp(30px,5vw,58px);font-weight:900;line-height:1.1">ä»å¤©çä½ ï¼æ¯ä»éº¼é¡è²ï¼</h2> 2502 <a href="https://apps.apple.com/tw/app/oddcam/id6772143344" target="_blank" rel="noopener" style="display:inline-flex;margin-top:32px;padding:18px 38px;border-radius:999px;background:#F7C01B;color:#2A3138;font-weight:700;font-size:17px">å è²»ä¸è¼ ODDCAM</a> 2503 <p style="margin:20px 0 0;font-size:13px;color:rgba(255,255,255,.6)">iOS 15+ · æ¯æ¬¾ç¸æ©å è²»è©¦ç¨ 3 次</p> 2504 <div style="display:flex;flex-wrap:wrap;justify-content:center;gap:20px;margin-top:44px;font-size:14px"> 2505 <a href="#" style="color:rgba(255,255,255,.7)">é±ç§æ¿ç</a> 2506 <a href="#" style="color:rgba(255,255,255,.7)">使ç¨èªªæ</a> 2507 <a href="#" style="color:rgba(255,255,255,.7)">è¯çµ¡æå</a> 2508 <a href="https://apps.apple.com/tw/app/oddcam/id6772143344" target="_blank" rel="noopener" style="color:rgba(255,255,255,.7)">App Store</a> 2509 </div> 2510 </div> 2511</footer> 2512 2513</div> 2514 2515</x-dc>
2516<script type="text/x-dc" data-dc-script data-props="{}"> 2517const GLOW = [ 2518 { hex: "#FF2633", name: "ç´ " }, { hex: "#FF851A", name: "æ©" }, 2519 { hex: "#FFE026", name: "é»" }, { hex: "#26E659", name: "ç¶ " }, 2520 { hex: "#1AD9D9", name: "é" }, { hex: "#2659FF", name: "è" }, 2521 { hex: "#8C40FF", name: "ç´«" }, { hex: "#FF40BF", name: "æ´ç´ " } 2522]; 2523 2524class Component extends DCLogic { 2525 state = { range: 55, feather: 60, picked: ["#FF40BF", "#2659FF", "#FFE026"] }; 2526 2527 toggle(hex) { 2528 this.setState(s => { 2529 const has = s.picked.includes(hex); 2530 if (has) return s.picked.length > 1 ? { picked: s.picked.filter(c => c !== hex) } : null; 2531 return { picked: s.picked.length >= 4 ? [...s.picked.slice(1), hex] : [...s.picked, hex] }; 2532 }); 2533 } 2534 2535 renderVals() { 2536 const { range, feather, picked } = this.state; 2537 const ring = picked.length === 1 ? [picked[0], picked[0]] : picked; 2538 const stops = [...ring, ring[0]].join(","); 2539 const clear = 72 - (range - 20) * 0.72; 2540 const soft = Math.max(2, clear + 3 + feather * 0.42); 2541 return { 2542 range, feather, 2543 rangeLabel: range + "%", 2544 featherLabel: feather + "%", 2545 auraBg: "conic-gradient(from 40deg," + stops + ")", 2546 auraMask: "radial-gradient(circle at 50% 44%, transparent " + clear.toFixed(1) + "%, #000 " + soft.toFixed(1) + "%)", 2547 onRange: e => this.setState({ range: Number(e.target.value) }), 2548 onFeather: e => this.setState({ feather: Number(e.target.value) }), 2549 swatches: GLOW.map(g => ({ 2550 hex: g.hex, name: g.name, 2551 border: picked.includes(g.hex) ? "3px solid #2A3138" : "3px solid rgba(255,255,255,.9)", 2552 pick: () => this.toggle(g.hex) 2553 })) 2554 }; 2555 } 2556} 2557 2558</script>
2558 2559</body> 2560</html> 2561 2562</div></div> 2563</div> 2564</main> 2565 2566 2567 2568<div style="text-align: center;"> 2569
2569<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-6363297981371690" 2570 crossorigin="anonymous"></script>
2570 2571 <ins class="adsbygoogle" 2572 style="display:inline-block;width:336px;height:280px" 2573 data-ad-client="ca-pub-6363297981371690" 2574 data-ad-slot="2333566923"></ins> 2575
2575<script> 2576 (adsbygoogle = window.adsbygoogle || []).push({}); 2577 </script>
2577 2578</div><br><br> 2579 2580 2581 2582<div class="responsive-banner"> 2583 <a href="https://apps.apple.com/tw/app/%E8%A8%88%E7%AE%970123456789/id6757208597"> 2584 <img src="https://imgpoi.com/i/U25PMM.jpg" alt="è¨ç®0123456789" /> 2585 </a> 2586</div> 2587 2588<style> 2589.responsive-banner { 2590 text-align: center; 2591 width: 100%; 2592 max-width: 800px; /* ä½ å¯ä»¥æ ¹æéæ±èª¿æ´æå¤§å¯¬åº¦ */ 2593 margin: 0 auto; /* ç½®ä¸ */ 2594 padding: 10px; 2595} 2596 2597.responsive-banner img { 2598 max-width: 100%; /* ééµï¼åçæå¤§ä¸è¶ éå®¹å¨ */ 2599 height: auto; /* ééµï¼ä¿æåçæ¯ä¾ä¸è®å½¢ */ 2600 display: inline-block; 2601 border-radius: 8px; /* å¯é¸ï¼è®åçéè§åæ»ä¸é»ï¼æ´æè³ªæ */ 2602 box-shadow: 0 4px 6px rgba(0,0,0,0.1); /* å¯é¸ï¼æ·»å è¼å¾®é°å½± */ 2603} 2604</style> 2605 2606 2607 2608<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-d7fd2005 wp-block-columns-is-layout-flex" style="border-top-color:var(--wp--preset--color--primary);border-top-width:1px;border-right-style:none;border-right-width:0px;border-bottom-style:none;border-bottom-width:0px;border-left-style:none;border-left-width:0px;padding-top:var(--wp--preset--spacing--60);padding-right:var(--wp--preset--spacing--50);padding-bottom:0;padding-left:var(--wp--preset--spacing--50)"> 2609<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow" style="flex-basis:35%"> 2610<div class="wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-87abe617 wp-block-group-is-layout-flex"> 2611<p class="wp-block-paragraph"></p> 2612 2613 2614 2615<p class="has-secondary-color has-text-color has-small-font-size wp-block-paragraph" style="padding-top:var(--wp--preset--spacing--50)">Tags:</p> 2616 2617 2618</div> 2619</div> 2620</div> 2621</div> 2622 2623 2624<footer class="wp-block-template-part"> 2625<div style="height:var(--wp--preset--spacing--80)" aria-hidden="true" class="wp-block-spacer"></div> 2626 2627 2628 2629<div class="wp-block-group has-global-padding is-layout-constrained wp-block-group-is-layout-constrained" style="border-top-color:var(--wp--preset--color--primary);border-top-width:1px;border-right-style:none;border-right-width:0px;border-bottom-style:none;border-bottom-width:0px;border-left-style:none;border-left-width:0px"> 2630<div class="wp-block-columns alignfull is-layout-flex wp-container-core-columns-is-layout-9bfe848c wp-block-columns-is-layout-flex" style="padding-top:var(--wp--preset--spacing--60);padding-right:var(--wp--preset--spacing--50);padding-bottom:var(--wp--preset--spacing--60);padding-left:var(--wp--preset--spacing--50)"> 2631<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"> 2632<!DOCTYPE html> 2633<html> 2634<head> 2635<style> 2636.s4 { 2637 color: 636363; 2638 text-align: left; 2639 font-size:0.8em; 2640font-weight: bold; 2641} 2642</style> 2643</head> 2644<body> 2645 2646 <table align="center" border="0" width="100%"> 2647 <tr> 2648 <th width="50"> 2649 <div align="left"> 2650 <h2>å¥åº·èå¥èº«</H2><br> 2651 2652 <a class="s4" href="https://mc.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/fUa7znL.png">女çè¨ç®æ©</a><br> 2653 <a class="s4" href="https://mc.0123456789.tw/mchappy.php"><img decoding="async" src="https://i.imgur.com/fUa7znL.png"></i>女å©å¿æ è¨ç®æ©</a><br> 2654 <a class="s4" href="https://266.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/fUa7znL.png">æºåª½åª½è¨ç®æ©</a><br> 2655 <a class="s4" href="https://266wg.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/fUa7znL.png">åæé«éè¨ç®æ©</a><br> 2656 2657 <a class="s4" href="https://girl.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/fUa7znL.png">女ç身æè¨ç®æ©</a><br> 2658 <a class="s4" href="https://bmi.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/cZY7yrQ.png">é«éè¨ç®BMI ABW</a><br> 2659 <a class="s4" href="https://newbmi.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/cZY7yrQ.png">æ°BMIè¨ç®æ©</a><br> 2660 <a class="s4" href="https://bmibmr.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/cZY7yrQ.png">æ¸è¥è¨ç®æ©</a><br> 2661 <a class="s4" href="https://water.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/EGWgne9.png">å¤åæ°´è¨ç®æ©</a><br> 2662 <a class="s4" href="https://hip.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/tuoZVTg.png">è °èæ¯è¨ç®æ©</a><br> 2663 2664 <a class="s4" href="https://heartbeat.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/cZY7yrQ.png">éåå¿è·³çè¨ç®æ©</a><br> 2665 <a class="s4" href="https://met.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/cZY7yrQ.png">éåæ¶èå¡è·¯éè¨ç®æ©</a><br> 2666 <a class="s4" href="https://daycal.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/YyG2Dpb.png">æ¯æ¥æéç±éè¨ç®æ©</a><br> 2667 <a class="s4" href="https://run.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/P3En4TR.png">è·æ¥è·é¢è¨ç®</a><br> 2668 <a class="s4" href="https://runkcal.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/P3En4TR.png">è·æ¥æ¶è塿´éè¨ç®</a><br> 2669 <a class="s4" href="https://sleep.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/xf7wCNj.png">æä½³ç¡ç è¨ç®æ©</a><br>
2670 </div> 2671 </th> 2672 <th width="50"> 2673 <div align="left"> 2674 2675 2676 <h2>çæ´»èå®¶åº</H2> <br> 2677 <a class="s4" href="https://mc28.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/fUa7znL.png">28å¤©ç¶æä¿é¤</a><br> 2678 <a class="s4" href="https://born.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/afebv3l.png">忍å忥è¨ç®æ©</a><br> 2679 2680 <a class="s4" href="https://ymd.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/jCxaC9m.jpg">寶寶天æ¸è¨ç®æ©</a><br> 2681 <a class="s4" href="https://milk.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/jCxaC9m.jpg">泡奶溫度è¨ç®æ©</a><br> 2682 2683<a class="s4" href="https://0123456789.tw/kidsclock/"><img decoding="async" src="https://i.imgur.com/jCxaC9m.jpg">ð¢ð¡ð´å°æåè¨æå¨</a><br> <a class="s4" href="https://cm.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/2LUGVkA.png">ç·å¥³éé 身é«è¨ç®æ©</a><br> 2684 <a class="s4" href="https://age.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/o2TlWQ8.png">æ²æ¸è¨ç®</a><br> 2685 <a class="s4" href="https://iage.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/Pvo4Vun.png">ä¿éªå¹´é½¡è¨ç®æ©</a><br> 2686 <a class="s4" href="https://elec.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/9txglN9.png">é»è²»è¨ç®</a><br> 2687 <a class="s4" href="https://fish.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/yQYUN2T.png">é缸è¨ç®æ©</a><br> 2688 <a class="s4" href="https://tv.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/GdxH0J2.png">é»è¦è·é¢è¨ç®æ©</a><br> 2689 <a class="s4" href="https://btu.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/QcWNY57.png">å·æ°£å¸æ¸éæ±è¨ç®</a><br> 2690 <a class="s4" href="https://airelec.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/QcWNY57.png">å·æ°£èé»éè¨ç®æ©</a><br> 2691 <a class="s4" href="https://bloodac.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/zMRNuoQ.png">è¡æ¶²é ç²¾æ¿åº¦è¨ç®</a><br> 2692 <a class="s4" href="https://rent.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/9B37dKq.png">è²·å±æç§å±åç®?</a><br> 2693 <a class="s4" href="https://dog.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/pdiGH7R.png">ç年齡æç®</a><br> 2694 <a class="s4" href="https://dogbaby.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/pdiGH7R.png">çæ·åé ç¢è¨ç®</a><br> 2695 <a class="s4" href="https://cat.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/2qglipS.png">è²å¹´é½¡æç®</a><br> 2696 <a class="s4" href="https://catbaby.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/2qglipS.png">è²æ·åé ç¢è¨ç®</a><br> 2697 <a class="s4" href="https://smoke.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/UXv565W.png">æ½ç è¨ç®æ©</a><br> 2698 <a class="s4" href="https://wine.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/t9gqTOq.png">é é¢è¨ç®æ©</a><br> 2699 2700 2701 </div> 2702 </th> 2703 </tr> 2704 </table></body> 2705</html> 2706</div> 2707 2708 2709 2710<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"> 2711<!DOCTYPE html> 2712<html> 2713<head> 2714 2715 2716</head> 2717<body> 2718 2719 <table align="center" border="0" width="100%"> 2720 <tr> 2721 <th width="50"> 2722 <div align="left"> 2723 <h2>交éèåºè¡</h2><br> 2724 <a class="s4" href="https://taxi.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/6cwws04.png">å°ç£è¨ç¨è»è³è¨ç®</a><br> 2725 <a class="s4" href="https://taxi.0123456789.tw/hk/"><img decoding="async" src="https://i.imgur.com/6cwws04.png">馿¸¯è¨ç¨è»è³è¨ç®</a><br> 2726 <a class="s4" href="https://maps.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/TBVy9rT.png">å°åè·é¢è¨ç®æ©</a><br> 2727 <a class="s4" href="https://oil.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/RGb3Hvn.png">æ²¹èè¨ç®æ©</a><br> 2728 <a class="s4" href="https://timespeed.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/RGb3Hvn.png">æéè·é¢éçè¨ç®æ©</a><br> 2729 <a class="s4" href="https://carloan.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/RGb3Hvn.png">è»è²¸è¨ç®</a><br> 2730 <a class="s4" href="https://carturn.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/RGb3Hvn.png">
2730齿¯è½éè¨ç®</a><br> 2731 <a class="s4" href="https://tire.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/RGb3Hvn.png">輪èåç´æç®</a><br> 2732 <a class="s4" href="https://oilup.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/RGb3Hvn.png">æ²¹é¢æ¼²è·è¨ç®</a><br> 2733 <a class="s4" href="https://bicycle.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/Vubxwpc.png">éµé¦¬è¨ç®æ©</a><br> 2734 </div> 2735 </th> 2736 <th width="50"> 2737 <div align="left"> 2738 2739 2740 <h2>éèèæè³</h2><br> 2741 2742 <a class="s4" href="https://money.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/McC1R15.png">å¯çæç®</a><br> 2743 <a class="s4" href="https://loan3year.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/GCeu7v6.png">æ¿è²¸è¨ç®æ©</a><br> 2744 <a class="s4" href="https://loan.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/GCeu7v6.png">æ¿è²¸ç¸½æ¯åºè¨ç®æ©</a><br> 2745 <a class="s4" href="https://loanmonth.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/GCeu7v6.png">æç¹³éé¡å©æ¯è¨ç®</a><br> 2746 <a class="s4" href="https://loanfw.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/GCeu7v6.png">æ¿è²¸è½è²¸è©¦ç®</a><br> 2747 <a class="s4" href="https://loanback.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/GCeu7v6.png">寬éæåé試ç®</a><br> 2748 <a class="s4" href="https://rate.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/kV7arCS.png">å®å©&è¤å©è¨ç®</a><br> 2749 <a class="s4" href="https://bidmoney.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/kV7arCS.png">æ¨æå©çè¨ç®</a><br> 2750 <a class="s4" href="https://stock7.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/rExLq1I.png">è¡ç¥¨æ¼²è·åè¨ç®</a><br> 2751 <a class="s4" href="https://stocksell.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/rExLq1I.png">è¡ç¥¨è²·è³£æç試ç®</a><br> 2752 <a class="s4" href="https://stockshare.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/rExLq1I.png">è¡ç¥¨é¤æ¬æ¯è¨ç®</a><br> 2753 <a class="s4" href="https://card.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/MyTBkgS.png">å¡åµè¨ç®æ©</a><br> 2754 <a class="s4" href="https://carbuy.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/AQbX0Mt.png">è³¼è»è¨ç®</a><br> 2755 <a class="s4" href="https://save.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/McC1R15.png">åé¢è¨ç®æ©</a><br> 2756 <a class="s4" href="https://weekmoney.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/McC1R15.png">æ¯é±å10å è¨ç®æ©</a><br> 2757 2758 2759 2760 2761 </div> 2762 </th> 2763 </tr> 2764 </table></body> 2765</html> 2766</div> 2767 2768 2769 2770<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"> 2771<!DOCTYPE html> 2772<html> 2773<head> 2774<style> 2775.s4 { 2776 color: 636363; 2777 text-align: left; 2778 font-size:0.8em; 2779font-weight: bold; 2780} 2781</style> 2782</head> 2783<body> 2784 2785 <table align="center" border="0" width="100%"> 2786 <tr> 2787 <th width="50"> 2788 <div align="left"> 2789 <h2>æ¥å¸¸è¨ç®å·¥å ·</h2><br> 2790 <a class="s4" href="https://unit.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/FDBmHms.png">å®ä½æç®</a><br> 2791 <a class="s4" href="https://simple.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/kPSB1fN.png">ç°¡æè¨ç®æ©</a><br> 2792 <a class="s4" href="https://record.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/kPSB1fN.png">ç´éæ¿è¨ç®æ©</a><br> 2793 <a class="s4" href="https://science.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/kPSB1fN.png">å·¥ç¨ç§å¸è¨ç®æ©</a><br> 2794 <a class="s4" href="https://s.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/kPSB1fN.png">è¨éçå·¥ç¨è¨ç®æ©</a><br> 2795 <a class="s4" href="https://tax.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/kPSB1fN.png">å«ç¨ é¤ç¨ è¨ç®æ©</a><br> 2796 <a class="s4" href="https://dec.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/kPSB1fN.png">é²ä½æç®è¨ç®æ©</a><br> 2797 <a class="s4" href="https://profit.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/GDOFQeM.png">æ¯å©çè¨ç®æ©</a><br> 2798 <a class="s4" href="https://calendar.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/Pvo4Vun.png">è¬å¹´æ+ä¸åæè¨äº</a><br> 2799 <a class="s4" href="https://dayplus.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/Pvo4Vun.png">æ¥æå æ¸è¨ç®æ©</a><br> 2800 <a class="s4" href="https://daybetween.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/Pvo4Vun.png">æ¥æç¸éè¨ç®æ©</a><br> 2801 <a class="s4" href="https://net.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/Pvo4Vun.png">åå®åæ¥æ¥æ</a><br> <a class="s4" href="https://workday.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/Pvo4Vun.png">工使¥è¨ç®æ©</a><br> 2802 <a class="s4" href="https://clock.0123456789.tw/index.php?dur=30&dur2=10&durr=12&durs=workbell"><img decoding="async" src="https://i.imgur.com/1dGX1JL.png">循ç°è¨æå¨</a><br> 2803 <a class="s4" href="https://min.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/1dGX1JL.png">碼表è¨ç®</a><br> 2804 <a class="s4" href="https://sec.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/1dGX1JL.png">毫ç§è¨æç¢¼é¶</a><br> 2805 <a class="s4" href="https://shoes.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/To7Kpkh.png">é尺碼è¨ç®æ©</a><br> 2806 2807 <a class="s4" href="https://scale.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/QOXWr6Y.png">æ¯ä¾è¨ç®æ©</a><br> 2808 <a class="s4" href="https://count.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/Qb5c7dK.png">è¨æ¸å¨</a><br> 2809 <a class="s4" href="https://0123456789.tw/tomato/"><img decoding="async" src="https://i.imgur.com/nUyosZC.png">
2809èèéè¨æå¨</a><br> 2810 <a class="s4" href="https://youtubealarm.0123456789.tw/?musicloc=https://www.youtube.com/watch?v=zCH-jYRfbI0"><img decoding="async" src="https://i.imgur.com/nUyosZC.png">ç·ä¸<img decoding="async" src="https://live.staticflickr.com/65535/53881320812_2b9089a79f_t.jpg">鬧é</a><br> 2811 <a class="s4" href="https://youtube.0123456789.tw/">ð¬åµå ¥<img decoding="async" src="https://live.staticflickr.com/65535/53881320812_2b9089a79f_t.jpg">åæææ¾</a><br> 2812 <a class="s4" href="https://alarm.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/nUyosZC.png">ç·ä¸åæ¸é¬§é</a><br> <a class="s4" href="https://alarm.0123456789.tw/index2.php"><img decoding="async" src="https://i.imgur.com/nUyosZC.png">å¯è¦å忏鬧é</a><br> 2813 <a class="s4" href="https://clock.0123456789.tw/cuckoo/"><img decoding="async" src="https://i.imgur.com/nUyosZC.png">ååéå ±æå¨</a><br> 2814 </div> 2815 </th> 2816 <th width="50"> 2817 <div align="left"> 2818 2819 2820 <h2>ç¹å®ç¨éå·¥å ·</h2><br> <a class="s4" href="https://word.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/J0fEl4X.png">æç« 忏è¨ç®</a><br> 2821 <a class="s4" href="https://color.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/V45ktsA.jpg">æ¸é¡è²è¨ç®æ©</a><br> 2822 <a class="s4" href="https://ppi.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/crl28kz.png">è¢å¹PPIè¨ç®æ©</a><br> 2823 <a class="s4" href="https://169.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/6eF66Bl.png">é»éæ¯ä¾è¨ç®</a><br> 2824 <a class="s4" href="https://lotto.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/ktbib2J.png">æ½ç±¤è¨ç®æ©</a><br> 2825 <a class="s4" href="https://time.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/q50S5aA.png">æ¥åºæ¥è½è¨ç®æ©</a><br> 2826 2827 <a class="s4" href="https://era.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/1hjNnPJ.png">æ£çERAè¨ç®</a><br> 2828 <a class="s4" href="https://ba.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/1hjNnPJ.png">æ£çBAè¨ç®</a><br> 2829 <a class="s4" href="https://timecard.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/1dGX1JL.png">å·¥æè¨ç®æ©</a><br> 2830 <a class="s4" href="https://timediff.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/1dGX1JL.png">æéå·®è¨ç®æ©</a><br> 2831 <a class="s4" href="https://m2.0123456789.tw/"><img decoding="async" src="https://i.imgur.com/mTUSXFy.png">åªæ¸ç£ç£è¨ç®æ©</a><br> 2832 2833 2834 2835 </div> 2836 </th> 2837 </tr> 2838 </table></body> 2839</html> 2840</div> 2841</div> 2842</div> 2843 2844 2845 2846<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-6ec0cbd9 wp-block-columns-is-layout-flex" style="padding-right:var(--wp--preset--spacing--50);padding-left:var(--wp--preset--spacing--50)"> 2847<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"> 2848<p class="has-text-align-left wp-block-paragraph" style="font-size:0.8rem">0123456789.tw</p> 2849</div> 2850</div> 2851 2852 2853 2854<div class="wp-block-columns is-layout-flex wp-container-core-columns-is-layout-f56f613f wp-block-columns-is-layout-flex"> 2855<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"> 2856<iframe 2857 width="360" 2858 height="640" 2859 src="https://www.youtube.com/embed/2e0gAVCWMbM" 2860 frameborder="0" 2861 allowfullscreen> 2862</iframe> 2863 2864 2865 2866<div class="fb-page" data-href="https://www.facebook.com/0123456789tw/" data-tabs="timeline" data-width="" data-height="" data-small-header="true" data-adapt-container-width="true" data-hide-cover="true" data-show-facepile="true"><blockquote cite="https://www.facebook.com/0123456789tw/" class="fb-xfbml-parse-ignore"><a href="https://www.facebook.com/0123456789tw/">è¨ç®0123456789</a></blockquote></div>
2866<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-6363297981371690" 2867 crossorigin="anonymous"></script>
2867 2868</div> 2869 2870 2871 2872<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow"> 2873<a class="s4" href="https://0123456789.tw/%e6%9c%ac%e7%ab%99%e5%85%a7%e5%b5%8c%e8%a8%88%e7%ae%97%e6%a9%9f/%e7%8f%be%e5%9c%a8%e5%b9%be%e9%bb%9e/">âðç¾å¨å¹¾é»ðâ</a><br> 2874 2875<a class="s4" href="https://0123456789.tw/%e6%9c%ac%e7%ab%99%e5%85%a7%e5%b5%8c%e8%a8%88%e7%ae%97%e6%a9%9f/%e8%a1%9b%e7%94%9f%e7%b4%99%e5%96%ae%e6%8a%bd%e6%af%94%e5%83%b9%e8%a8%88%e7%ae%97%e6%a9%9f/">ð§»è¡çç´è¨ç®æ©ð½ 2876</a><br> 2877 2878<a class="s4" href="https://0123456789.tw/%e6%9c%ac%e7%ab%99%e5%85%a7%e5%b5%8c%e8%a8%88%e7%ae%97%e6%a9%9f/%e5%a6%82%e4%bd%95%e8%a8%88%e7%ae%97%e4%bf%83%e9%8a%b7%e6%8a%98%e6%89%a3%e7%9a%84%e7%9c%9f%e5%af%a6%e6%8a%98%e6%95%b8%ef%bc%88%e8%b2%b7%e4%ba%8c%e9%80%81%e4%b8%80%ef%bc%8c%e6%bb%bf%e7%99%be%e9%80%81/">ðçå¯¦ææ¸è¨ç®æ©ð 2879</a><br> 2880 2881 2882<a class="s4" href="https://0123456789.tw/%e6%9c%ac%e7%ab%99%e5%85%a7%e5%b5%8c%e8%a8%88%e7%ae%97%e6%a9%9f/365%e5%ad%98%e9%8c%a2%e8%a8%88%e7%95%ab%e8%a8%88%e7%ae%97%e6%a9%9f/">ð°365åé¢è¨ç«è¨ç®æ©ð 2883</a><br> 2884 2885 2886<a class="s4" href="https://0123456789.tw/%e6%9c%ac%e7%ab%99%e5%85%a7%e5%b5%8c%e8%a8%88%e7%ae%97%e6%a9%9f/%e5%a5%b3%e7%94%9f%e8%a8%88%e7%ae%97%e6%a9%9fv2-0-m-c%e8%a8%88%e7%ae%97%e6%a9%9f%e6%97%a5%e6%9b%86%e7%89%88/"> 2887ð女çè¨ç®æ©V2ðï¸ 2888</a><br> 2889 2890 2891<a class="s4" href="https://0123456789.tw/%e6%9c%ac%e7%ab%99%e5%85%a7%e5%b5%8c%e8%a8%88%e7%ae%97%e6%a9%9f/%e6%97%a9%e7%94%a2%e5%85%92%e7%9f%af%e6%ad%a3%e5%b9%b4%e9%bd%a1%e8%a8%88%e7%ae%97%e6%a9%9f/">ð¶æ©ç¢å ç¯æ£å¹´é½¡è¨ç® 2892</a><br> 2893 2894<a class="s4" href="https://0123456789.tw/%e6%9c%ac%e7%ab%99%e5%85%a7%e5%b5%8c%e8%a8%88%e7%ae%97%e6%a9%9f/%e9%a4%98%e7%94%9f%e8%a8%88%e7%ae%97%e6%a9%9f/"> 2895ðé¤çè¨ç®æ©ð 2896</a><br> 2897 2898<a class="s4" href="https://0123456789.tw/%e6%9c%ac%e7%ab%99%e5%85%a7%e5%b5%8c%e8%a8%88%e7%ae%97%e6%a9%9f/%e9%96%93%e6%ad%87%e9%81%8b%e5%8b%95%e8%a8%93%e7%b7%b4%e8%a8%88%e6%99%82%e5%99%a8hiit%e3%80%81tabata/"> 2899â°éæéå循ç°è¨æðª 2900</a><br> 2901 2902<a class="s4" href="https://0123456789.tw/%e6%9c%ac%e7%ab%99%e5%85%a7%e5%b5%8c%e8%a8%88%e7%ae%97%e6%a9%9f/ppm%e6%8f%9b%e7%ae%97%e7%99%be%e5%88%86%e6%af%94%e8%a8%88%e7%ae%97%e6%a9%9f/"> 2903ð¬PPMæç®%è¨ç®æ©ð£ 2904</a><br> 2905<a class="s4" href="https://0123456789.tw/%e6%9c%ac%e7%ab%99%e5%85%a7%e5%b5%8c%e8%a8%88%e7%ae%97%e6%a9%9f/%e9%81%ba%e7%94%a2%e7%a8%85%e8%a8%88%e7%ae%97%e6%a9%9f/">ð°éºç¢ç¨ è¨ç®æ©â°ï¸</a><br> 2906 2907<a class="s4" href="https://0123456789.tw/%e6%9c%ac%e7%ab%99%e5%85%a7%e5%b5%8c%e8%a8%88%e7%ae%97%e6%a9%9f/%e6%b2%96%e5%92%96%e5%95%a1-%e6%b3%a1%e8%8c%b6%e5%80%92%e6%95%b8%e8%a8%88%e6%99%82%e5%99%a8/">âæ²åå¡è¶è¨æå¨ðµ</a><br> 2908 2909<a class="s4" href="https://0123456789.tw/%e6%9c%ac%e7%ab%99%e5%85%a7%e5%b5%8c%e8%a8%88%e7%ae%97%e6%a9%9f/%e9%9b%bb%e5%8b%95%e6%b1%bd%e8%bb%8a%e9%9b%bb%e8%80%97%e5%85%85%e9%9b%bb%e8%a8%88%e7%ae%97%e6%a9%9f/">ðï¸é»è½è»é»èå é»è¨ç®æ©</a><br> 2910 2911<a class="s4" href="https://0123456789.tw/%e6%9c%ac%e7%ab%99%e5%85%a7%e5%b5%8c%e8%a8%88%e7%ae%97%e6%a9%9f/%e5%b0%8f%e5%ad%a9%e8%ba%ab%e9%ab%98%e9%a0%90%e6%b8%ac%e8%a8%88%e7%ae%97%e5%99%a8/">ð¨âð©âð¦å°å©èº«é«é 測è¨ç®</a><br> 2912 2913<a class="s4" href="https://0123456789.tw/%e6%9c%ac%e7%ab%99%e5%85%a7%e5%b5%8c%e8%a8%88%e7%ae%97%e6%a9%9f/%e4%bd%a0%e9%80%99%e5%80%8b%e6%9c%88%e5%81%9a%e4%ba%86%e9%80%99%e4%bb%b6%e4%ba%8b%e5%b9%be%e6%ac%a1/">ðåäºå¹¾æ¬¡è¨ç®æ©ð</a><br> 2914 2915<a class="s4" href="https://0123456789.tw/%e6%9c%ac%e7%ab%99%e5%85%a7%e5%b5%8c%e8%a8%88%e7%ae%97%e6%a9%9f/%e5%81%9c%e8%bb%8a%e8%a8%88%e6%99%82%e8%a8%88%e7%ae%97%e6%a9%9f/">ðåè»è¨æè¨ç®æ©ð</a><br> 2916 2917<a class="s4" href="https://0123456789.tw/%e6%9c%ac%e7%ab%99%e5%85%a7%e5%b5%8c%e8%a8%88%e7%ae%97%e6%a9%9f/%e7%a7%81%e6%88%bf%e9%8c%a2%e8%a8%88%e7%ae%97%e5%99%a8-%e5%a4%9a%e5%b0%91%e9%8c%a2%e8%97%8f%e5%9c%a8%e5%93%aa%e8%a3%a1/">ð²ç§æ¿é¢è¨ç®æ©ð²</a><br><a class="s4" href="https://0123456789.tw/%e6%9c%ac%e7%ab%99%e5%85%a7%e5%b5%8c%e8%a8%88%e7%ae%97%e6%a9%9f/%e6%88%91%e8%a6%ba%e5%be%97%e6%88%91%e4%bb%a5%e5%be%8c%e6%9c%83%e7%94%a8%e7%9a%84%e5%88%b0%e8%a8%88%e7%ae%97%e6%a9%9f/">ðï¸ä»¥å¾æç¨å°è¨ç®æ©ðï¸</a><br><a class="s4" href="https://0123456789.tw/%e6%9c%ac%e7%ab%99%e5%85%a7%e5%b5%8c%e8%a8%88%e7%ae%97%e6%a9%9f/%e8%b6%85%e7%b4%9a%e5%bb%9a%e6%88%bf%e8%a8%88%e6%99%82%e5%99%a8%e5%bf%ab%e9%80%9f%e9%bb%9e%e9%81%b8%e7%89%88/">â²ï¸è¶ ç´å»æ¿è¨æå¨â±ï¸</a><br> 2918</div> 2919 2920 2921 2922<div class="wp-block-column is-layout-flow wp-block-column-is-layout-flow">
2923<script src="//rss.bloople.net/?url=https%3A%2F%2F0123456789.tw%2F%3Ffeed%3Drss2&detail=-1&showicon=true&striphtml=true&type=js"></script>
2923 2924 2925 2926 2927<ul class="wp-block-social-links is-layout-flex wp-block-social-links-is-layout-flex"><li class="wp-social-link wp-social-link-facebook wp-block-social-link"><a href="https://www.facebook.com/0123456789tw/" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M12 2C6.5 2 2 6.5 2 12c0 5 3.7 9.1 8.4 9.9v-7H7.9V12h2.5V9.8c0-2.5 1.5-3.9 3.8-3.9 1.1 0 2.2.2 2.2.2v2.5h-1.3c-1.2 0-1.6.8-1.6 1.6V12h2.8l-.4 2.9h-2.3v7C18.3 21.1 22 17 22 12c0-5.5-4.5-10-10-10z"></path></svg><span class="wp-block-social-link-label screen-reader-text">Facebook</span></a></li> 2928 2929<li class="wp-social-link wp-social-link-youtube wp-block-social-link"><a href="https://www.youtube.com/@0123456789Twtw" class="wp-block-social-link-anchor"><svg width="24" height="24" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false"><path d="M21.8,8.001c0,0-0.195-1.378-0.795-1.985c-0.76-0.797-1.613-0.801-2.004-0.847c-2.799-0.202-6.997-0.202-6.997-0.202 h-0.009c0,0-4.198,0-6.997,0.202C4.608,5.216,3.756,5.22,2.995,6.016C2.395,6.623,2.2,8.001,2.2,8.001S2,9.62,2,11.238v1.517 c0,1.618,0.2,3.237,0.2,3.237s0.195,1.378,0.795,1.985c0.761,0.797,1.76,0.771,2.205,0.855c1.6,0.153,6.8,0.201,6.8,0.201 s4.203-0.006,7.001-0.209c0.391-0.047,1.243-0.051,2.004-0.847c0.6-0.607,0.795-1.985,0.795-1.985s0.2-1.618,0.2-3.237v-1.517 C22,9.62,21.8,8.001,21.8,8.001z M9.935,14.594l-0.001-5.62l5.404,2.82L9.935,14.594z"></path></svg><span class="wp-block-social-link-label screen-reader-text">YouTube</span></a></li></ul> 2930 2931 2932 2933<p><a href="https://portaly.cc/0123456789tw">é£çµ¡ç«é·</a></p> 2934 2935 2936 2937<div class="line-it-button" data-lang="zh_Hant" data-type="share-a" data-env="REAL" data-url="https://developers.line.biz/en/docs/line-social-plugins/install-guide/using-line-share-buttons/" data-color="default" data-size="small" data-count="true" data-ver="3" style="display: none;"></div>
2938<script src="https://www.line-website.com/social-plugins/js/thirdparty/loader.min.js" async="async" defer="defer"></script>
2938 2939</div> 2940</div> 2941 2942 2943<br><ul class="wp-block-social-links"></ul></footer></div>
2944<script type="speculationrules"> 2945{"prefetch":[{"source":"document","where":{"and":[{"href_matches":"/*"},{"not":{"href_matches":["/wp-*.php","/wp-admin/*","/wp-content/uploads/*","/wp-content/*","/wp-content/plugins/*","/wp-content/themes/fewer/*","/*\\?(.+)"]}},{"not":{"selector_matches":"a[rel~=\"nofollow\"]"}},{"not":{"selector_matches":".no-prefetch, .no-prefetch a"}}]},"eagerness":"conservative"}]} 2946</script>
vendor: 1 bytes, line 2946
2946
2947<script data-wp-router-options="{"loadOnClientNavigation":true}" fetchpriority="low" id="@wordpress/block-library/navigation/view-js-module" src="https://0123456789.tw/wp-includes/js/dist/script-modules/block-library/navigation/view.min.js?ver=1bf28ded04f9f188bdcb" type="module"></script>
2947 2948 2949<!-- Google Reader Revenue Manager snippet added by Site Kit -->
2950<script id="google_swgjs-js-before"> 2951(self.SWG_BASIC=self.SWG_BASIC||[]).push(basicSubscriptions=>{basicSubscriptions.init({"type":"NewsArticle","isPartOfType":["Product"],"isPartOfProductId":"CAow7pPgCw:openaccess","clientOptions":{"theme":"light","lang":"zh-TW"}});}); 2952//# sourceURL=google_swgjs-js-before 2953</script>
vendor: 1 bytes, line 2953
2953
2954<script async data-wp-strategy="async" id="google_swgjs-js" src="https://news.google.com/swg/js/v1/swg-basic.js"></script>
2954 2955 2956<!-- End Google Reader Revenue Manager snippet added by Site Kit -->
2957<script id="googlesitekit-events-provider-content-events-js-before"> 2958window._googlesitekit = window._googlesitekit || {}; 2959window._googlesitekit.contentEvents = {"postID":2166,"isSinglePost":true,"hasVimeoEmbed":false}; 2960//# sourceURL=googlesitekit-events-provider-content-events-js-before 2961</script>
vendor: 1 bytes, line 2961
2961
2962<script id="googlesitekit-events-provider-content-events-js" src="https://0123456789.tw/wp-content/plugins/google-site-kit/dist/assets/js/googlesitekit-events-provider-content-events-c7172f3fd0e4d5ad62ef.js" defer></script>
vendor: 1 bytes, line 2962
2962
2963<script id="wp-emoji-settings" type="application/json"> 2964{"baseUrl":"https://s.w.org/images/core/emoji/17.0.2/72x72/","ext":".png","svgUrl":"https://s.w.org/images/core/emoji/17.0.2/svg/","svgExt":".svg","source":{"concatemoji":"https://0123456789.tw/wp-includes/js/wp-emoji-release.min.js?ver=7.1.2"}} 2965</script>
vendor: 1 bytes, line 2965
2965
2966<script type="module"> 2967/*! This file is auto-generated */ 2968var e="script#wp-emoji-settings",t=document.querySelector(e);if(!(t instanceof HTMLScriptElement))throw new Error("Element missing: "+e);const r=JSON.parse(t.text),s=(window._wpemojiSettings=r,"wpEmojiSettingsSupports"),o=["flag","emoji"];function i(e){try{var t={supportTests:e,timestamp:(new Date).valueOf()};sessionStorage.setItem(s,JSON.stringify(t))}catch(e){}}function c(e,t,n){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);t=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(n,0,0);const r=new Uint32Array(e.getImageData(0,0,e.canvas.width,e.canvas.height).data);return t.every((e,t)=>e===r[t])}function p(e,t){e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillText(t,0,0);var n=e.getImageData(16,16,1,1);for(let e=0;e<n.data.length;e++)if(0!==n.data[e])return!1;return!0}function u(e,t,n,r){switch(t){case"flag":return n(e,"\ud83c\udff3\ufe0f\u200d\u26a7\ufe0f","\ud83c\udff3\ufe0f\u200b\u26a7\ufe0f")?!1:!n(e,"\ud83c\udde8\ud83c\uddf6","\ud83c\udde8\u200b\ud83c\uddf6")&&!n(e,"\ud83c\udff4\udb40\udc67\udb40\udc62\udb40\udc65\udb40\udc6e\udb40\udc67\udb40\udc7f","\ud83c\udff4\u200b\udb40\udc67\u200b\udb40\udc62\u200b\udb40\udc65\u200b\udb40\udc6e\u200b\udb40\udc67\u200b\udb40\udc7f");case"emoji":return!r(e,"\ud83e\u1fac8")}return!1}function f(e,t,n,r){let a;const s=(a="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?new OffscreenCanvas(300,150):document.createElement("canvas")).getContext("2d",{willReadFrequently:!0}),o=(s.textBaseline="top",s.font="600 32px Arial",{});return e.forEach(e=>{o[e]=t(s,e,n,r)}),o}function a(e){var t=document.createElement("script");t.src=e,t.defer=!0,document.head.appendChild(t)}r.supports={everything:!0,everythingExceptFlag:!0},new Promise(t=>{let n=function(){try{var e=JSON.parse(sessionStorage.getItem(s));if("object"==typeof e&&"number"==typeof e.timestamp&&(new Date).valueOf()<e.timestamp+604800&&"object"==typeof e.supportTests)return e.supportTests}catch(e){}return null}();if(!n){if("undefined"!=typeof Worker&&"undefined"!=typeof OffscreenCanvas&&"undefined"!=typeof URL&&URL.createObjectURL&&"undefined"!=typeof Blob)try{var e="postMessage("+f.toString()+"("+[JSON.stringify(o),u.toString(),c.toString(),p.toString()].join(",")+"));",r=new Blob([e],{type:"text/javascript"});const a=new Worker(URL.createObjectURL(r),{name:"wpTestEmojiSupports"});return void(a.onmessage=e=>{i(n=e.data),a.terminate(),t(n)})}catch(e){}i(n=f(o,u,c,p))}t(n)}).then(e=>{for(const n in e)r.supports[n]=e[n],r.supports.everything=r.supports.everything&&r.supports[n],"flag"!==n&&(r.supports.everythingExceptFlag=r.supports.everythingExceptFlag&&r.supports[n]);var t;r.supports.everythingExceptFlag=r.supports.everythingExceptFlag&&!r.supports.flag,r.supports.everything||((t=r.source||{}).concatemoji?a(t.concatemoji):t.wpemoji&&t.twemoji&&(a(t.twemoji),a(t.wpemoji)))}); 2969//# sourceURL=https://0123456789.tw/wp-includes/js/wp-emoji-loader.min.js 2970</script>
2970 2971</body> 2972</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.