{\rtf1\ansi\ansicpg950\cocoartf2870 \cocoatextscaling0\cocoaplatform0{\fonttbl\f0\fswiss\fcharset0 Helvetica;} {\colortbl;\red255\green255\blue255;} {\*\expandedcolortbl;;} \paperw11900\paperh16840\margl1440\margr1440\vieww11520\viewh8400\viewkind0 \pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\pardirnatural\partightenfactor0 \f0\fs24 \cf0 /**\ * \uc0\u20179 \u24211 \u24179 \u38754 \u22270 - Cloudflare Worker\u65288 \u21333 \u25991 \u20214 \u65289 \ *\ * - GET / \uc0\u36820 \u22238 \u24179 \u38754 \u22270 \u39029 \u38754 \ * - GET /api/data \uc0\u35835 \u21462 \u24050 \u20445 \u23384 \u30340 \u36135 \u26550 \u25968 \u25454 \u65288 \u38656 \u35201 \u32465 \u23450 KV\u65306 WAREHOUSE_KV\u65289 \ * - PUT /api/data \uc0\u20445 \u23384 \u36135 \u26550 \u25968 \u25454 \ *\ * \uc0\u27809 \u26377 \u32465 \u23450 KV \u26102 \u39029 \u38754 \u29031 \u24120 \u20351 \u29992 \u65292 \u25968 \u25454 \u21482 \u20445 \u23384 \u22312 \u24403 \u21069 \u27983 \u35272 \u22120 \u65288 localStorage\u65289 \u12290 \ */\ \ const SLOT_COUNT = 11 * 5;\ \ export default \{\ async fetch(request, env) \{\ const url = new URL(request.url);\ \ if (url.pathname === "/api/data") \{\ return handleData(request, env);\ \}\ \ if (url.pathname === "/" || url.pathname === "/index.html") \{\ return new Response(HTML, \{\ headers: \{\ "content-type": "text/html; charset=utf-8",\ "cache-control": "no-cache",\ \},\ \});\ \}\ \ return new Response("Not found", \{ status: 404 \});\ \},\ \};\ \ async function handleData(request, env) \{\ const headers = \{\ "content-type": "application/json; charset=utf-8",\ "cache-control": "no-store",\ \};\ \ if (!env.WAREHOUSE_KV) \{\ return new Response(JSON.stringify(\{ error: "KV not bound" \}), \{ status: 501, headers \});\ \}\ \ if (request.method === "GET") \{\ const saved = await env.WAREHOUSE_KV.get("layout");\ return new Response(saved || "null", \{ headers \});\ \}\ \ if (request.method === "PUT") \{\ const text = await request.text();\ if (text.length > 200000) \{\ return new Response(JSON.stringify(\{ error: "Payload too large" \}), \{ status: 413, headers \});\ \}\ let parsed;\ try \{\ parsed = JSON.parse(text);\ \} catch (e) \{\ return new Response(JSON.stringify(\{ error: "Invalid JSON" \}), \{ status: 400, headers \});\ \}\ if (!parsed || !Array.isArray(parsed.slots) || parsed.slots.length !== SLOT_COUNT) \{\ return new Response(JSON.stringify(\{ error: "Invalid layout" \}), \{ status: 400, headers \});\ \}\ await env.WAREHOUSE_KV.put("layout", text);\ return new Response(JSON.stringify(\{ ok: true \}), \{ headers \});\ \}\ \ return new Response(JSON.stringify(\{ error: "Method not allowed" \}), \{ status: 405, headers \});\ \}\ \ const HTML = String.raw`\ \ \ \ \ \uc0\u20179 \u24211 \u24179 \u38754 \u22270 \ \ \ \ \
\

\uc0\u20179 \u24211 \u24179 \u38754 \u22270

\ \ \
\ \ 100%\ \ \ \
\ \uc0\u21152 \u36733 \u20013 \'85\
\ \
\
\
\uc0\u25302 \u21160 \u31354 \u30333 \u22788 \u31227 \u21160 \u30011 \u38754 \u12290 \u25353 \u20303 \u36135 \u26550 \u39030 \u37096 \u30340 \u34013 \u33394 \u26631 \u39064 \u26639 \u65292 \u25302 \u21040 \u21478 \u19968 \u20010 \u36135 \u26550 \u19978 \u21363 \u21487 \u20114 \u25442 \u12290 Ctrl + \u28378 \u36718 \u32553 \u25918 \u12290
\
\ \ \ \ `;}