{"id":2361,"date":"2026-11-01T02:06:32","date_gmt":"2026-11-01T01:06:32","guid":{"rendered":"https:\/\/chicachica.com\/?page_id=2361"},"modified":"2026-11-01T11:48:07","modified_gmt":"2026-11-01T10:48:07","slug":"el-pueblo-de-chicachica","status":"publish","type":"page","link":"https:\/\/chicachica.com\/index.php\/el-pueblo-de-chicachica\/","title":{"rendered":"Juegos"},"content":{"rendered":"\n\n<iframe id=\"chicachica-juego\" title=\"El Pueblo de ChicaChica\" style=\"width:100%;height:760px;border:0;display:block;border-radius:12px;background:#2a1533\" allow=\"autoplay; fullscreen; clipboard-write\" allowfullscreen srcdoc=\"&lt;!DOCTYPE html&gt;&#10;&lt;!-- El Pueblo de ChicaChica v1.0 \u00b7 chicachica.com \u00b7 gratis y sin publicidad --&gt;&#10;&lt;html lang=&quot;es&quot;&gt;&#10;&lt;head&gt;&#10;&lt;meta charset=&quot;UTF-8&quot;&gt;&#10;&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1, maximum-scale=1, viewport-fit=cover&quot;&gt;&#10;&lt;link rel=&quot;icon&quot; href=&quot;data:image\/svg+xml,&lt;svg xmlns=%22http:\/\/www.w3.org\/2000\/svg%22 viewBox=%220 0 100 100%22&gt;&lt;text y=%22.9em%22 font-size=%2290%22&gt;\ud83d\udc97&lt;\/text&gt;&lt;\/svg&gt;&quot;&gt;&#10;&lt;title&gt;El Pueblo de ChicaChica \u00b7 v1.0&lt;\/title&gt;&#10;&lt;meta name=&quot;description&quot; content=&quot;Un pueblo solarpunk donde las chicas viven su d\u00eda: huerta, mercado, biblioteca digital, playa, puerto y fiestas vascas. Juego sin anuncios ni cookies.&quot;&gt;&#10;&lt;meta name=&quot;theme-color&quot; content=&quot;#2a1533&quot;&gt;&#10;&lt;meta name=&quot;mobile-web-app-capable&quot; content=&quot;yes&quot;&gt;&#10;&lt;meta name=&quot;apple-mobile-web-app-title&quot; content=&quot;ChicaChica&quot;&gt;&#10;&lt;meta property=&quot;og:type&quot; content=&quot;website&quot;&gt;&lt;meta property=&quot;og:locale&quot; content=&quot;es_ES&quot;&gt;&lt;meta property=&quot;og:site_name&quot; content=&quot;ChicaChica&quot;&gt;&#10;&lt;meta property=&quot;og:title&quot; content=&quot;El Pueblo de ChicaChica \ud83d\udc9c\ud83c\udf38&quot;&gt;&lt;meta property=&quot;og:description&quot; content=&quot;Un pueblo solarpunk donde las chicas viven su d\u00eda. Sin anuncios ni cookies.&quot;&gt;&#10;&lt;meta name=&quot;twitter:card&quot; content=&quot;summary&quot;&gt;&#10;&lt;!-- Tipograf\u00eda: Plus Jakarta Sans se carga desde Google Fonts (\u00fanica petici\u00f3n externa). Si prefieres cero terceros, borra la l\u00ednea &lt;link ... fonts.googleapis.com&gt; y el juego usar\u00e1 Comic Sans \/ sans-serif del sistema. --&gt;&#10;&lt;style&gt;&#10;    :root{&#10;        --rosa: #ff69b4;&#10;        --morado: #6a3e8c;&#10;        --crema: #fff5fa;&#10;        box-sizing: border-box;&#10;        padding-top: env(safe-area-inset-top, 0px);&#10;        padding-bottom: env(safe-area-inset-bottom, 0px);&#10;    }&#10;    html { height: 100%; scroll-padding-top: env(safe-area-inset-top, 0px); }&#10;    html, body { margin: 0; }&#10;    body {&#10;        height: 100%;&#10;        background: radial-gradient(circle at 20% 15%, #3a1d47, transparent 55%),&#10;                    radial-gradient(circle at 85% 85%, #7a1f3f, transparent 55%),&#10;                    #2a1533;&#10;        font-family: 'Comic Sans MS', 'Trebuchet MS', sans-serif;&#10;        display: flex; flex-direction: column; align-items: center;&#10;        overflow: hidden;&#10;        padding: 8px max(8px, env(safe-area-inset-right, 0px)) 8px max(8px, env(safe-area-inset-left, 0px));&#10;        box-sizing: border-box;&#10;    }&#10;    \/* Barra de navegaci\u00f3n superior fija: siempre visible, com\u00fan a todas las vistas *\/&#10;    #nav {&#10;        position: sticky; top: 0; z-index: 10; flex: 0 0 auto;&#10;        display: flex; gap: 6px; align-items: center; justify-content: center; flex-wrap: wrap;&#10;        width: 100%; max-width: 960px; margin: 0 0 6px; padding: 4px 6px;&#10;        background: rgba(42,21,51,0.85); border: 2px solid var(--rosa); border-radius: 22px;&#10;        font-family: 'Plus Jakarta Sans', 'Comic Sans MS', sans-serif; box-sizing: border-box;&#10;    }&#10;    #nav button {&#10;        border: 2px solid rgba(255,255,255,0.85); border-radius: 18px; padding: 6px 12px; cursor: pointer;&#10;        font: 700 13px 'Plus Jakarta Sans', 'Comic Sans MS', sans-serif; color: #fff; white-space: nowrap;&#10;        background: linear-gradient(90deg, var(--rosa), var(--morado)); opacity: 0.8;&#10;    }&#10;    #nav button.activo { opacity: 1; background: #2a9d78; border-color: #7cffd9; box-shadow: 0 0 10px rgba(124,255,217,0.6); }&#10;    #nav .chipfiesta { cursor: pointer; color: #fff5e0; font: 700 12px 'Plus Jakarta Sans', sans-serif; padding: 5px 10px; border: 2px dashed rgba(255,245,224,0.6); border-radius: 16px; white-space: nowrap; }&#10;    #nav .chipfiesta.previa { border-style: solid; background: rgba(124,255,217,0.2); }&#10;    #avisoKutxa { position: fixed; top: auto; bottom: max(14px, env(safe-area-inset-bottom, 0px)); left: 50%; transform: translateX(-50%); z-index: 15; max-width: 90vw; padding: 8px 16px; border-radius: 18px; background: rgba(42,21,51,0.95); border: 2px solid #7cffd9; color: #fff; font: 700 13px 'Plus Jakarta Sans', 'Comic Sans MS', sans-serif; opacity: 0; pointer-events: none; transition: opacity 0.4s; }&#10;    #avisoKutxa.ver { opacity: 1; }&#10;    #radioMenu { position: absolute; top: calc(100% + 6px); right: 6px; min-width: 270px; background: rgba(42,21,51,0.97); border: 2px solid var(--rosa); border-radius: 14px; padding: 6px; display: flex; flex-direction: column; gap: 4px; z-index: 20; }&#10;    #radioMenu[hidden] { display: none; }&#10;    #radioMenu .op { color: #fff; font: 700 12px 'Plus Jakarta Sans', sans-serif; padding: 6px 10px; border-radius: 10px; cursor: pointer; display: flex; justify-content: space-between; gap: 12px; }&#10;    #radioMenu .op:hover { background: rgba(255,255,255,0.12); } #radioMenu .op.sel { background: #2a9d78; } #radioMenu .op.off { opacity: 0.55; }&#10;    #radioMenu .pie { color: #fff5e0; font: 500 11px 'Plus Jakarta Sans', sans-serif; padding: 2px 10px; }&#10;    #nav .saldo { margin-left: auto; color: #fff5e0; font: 700 13px 'Plus Jakarta Sans', sans-serif; padding: 0 6px; white-space: nowrap; }&#10;    h1 {&#10;        color: var(--crema);&#10;        text-shadow: 0 2px 6px rgba(0,0,0,0.4);&#10;        margin: 0 0 4px;&#10;        font-size: clamp(15px, 3.6vw, 26px);&#10;        text-align: center;&#10;        flex: 0 0 auto;&#10;    }&#10;    p.pista {&#10;        color: var(--crema);&#10;        opacity: 0.85;&#10;        font-size: 12px;&#10;        margin: 0 0 6px;&#10;        text-align: center;&#10;        flex: 0 0 auto;&#10;        max-width: 640px;&#10;    }&#10;    @media (max-height: 620px) {&#10;        h1 { font-size: 14px; margin-bottom: 2px; }&#10;        p.pista { display: none; }&#10;    }&#10;    \/* Contenedor que ocupa todo el espacio restante y centra el lienzo dentro de \u00e9l *\/&#10;    .pantalla-juego {&#10;        flex: 1 1 auto;&#10;        width: 100%;&#10;        min-height: 0;&#10;        display: flex; align-items: center; justify-content: center;&#10;        overflow: hidden;&#10;    }&#10;    \/* Ocupa el 100% del espacio disponible (con altura expl\u00edcita, para que el&#10;       max-height del canvas se calcule de verdad) y centra el lienzo dentro. Como&#10;       el bot\u00f3n &quot;volver&quot; y el selector de clima ahora se dibujan DENTRO del propio&#10;       canvas (no como botones HTML superpuestos), quedan siempre pegados a las&#10;       esquinas reales del mapa y escalan junto con \u00e9l, sin solaparse nunca. *\/&#10;    .lienzo-wrap {&#10;        position: relative;&#10;        width: 100%; height: 100%;&#10;        display: flex; align-items: center; justify-content: center;&#10;    }&#10;    canvas {&#10;        display: block;&#10;        background: #bfe4ff;&#10;        border: 6px solid var(--rosa);&#10;        border-radius: 20px;&#10;        box-shadow: 0 10px 40px rgba(0,0,0,0.4);&#10;        width: auto; height: auto; box-sizing: border-box;&#10;        max-width: 100%; max-height: 100%;&#10;        cursor: pointer;&#10;    }&#10;&#10;\/* ===== MODO SMART TV: el pueblo como cuadro vivo ===== *\/&#10;#btnTV { position: fixed; top: max(4px, env(safe-area-inset-top, 0px)); right: max(8px, env(safe-area-inset-right, 0px)); z-index: 60; font: 700 13px 'Plus Jakarta Sans', sans-serif; color: #fff5e0; background: rgba(42,21,51,0.88); border: 2px solid var(--rosa); border-radius: 18px; padding: 3px 11px; cursor: pointer; line-height: 1.4; transition: opacity .6s; opacity: .92; }&#10;@media (min-height: 520px) { body:not(.tv) { padding-top: 30px; } }&#10;body.tv { padding: 0 !important; background: #000 !important; }&#10;body.tv #nav, body.tv h1, body.tv p.pista, body.tv #giroAviso, body.tv #panZoom { display: none !important; }&#10;body.tv .pantalla-juego, body.tv .pantalla-juego.zoom { width: 100vw; height: 100vh; height: 100dvh; overflow: hidden; display: flex; align-items: center; justify-content: center; }&#10;body.tv .lienzo-wrap, body.tv .lienzo-wrap.zoom { width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; margin: 0; }&#10;body.tv canvas { border: 0 !important; border-radius: 0 !important; box-shadow: none !important; max-width: none !important; max-height: none !important; width: min(100vw, 177.78vh) !important; height: min(56.25vw, 100vh) !important; }&#10;body.tv #btnTV { opacity: 0; pointer-events: none; }&#10;body.tv #btnTV.ver { opacity: .9; pointer-events: auto; }&#10;&#10;\/* ===== MANDO A DISTANCIA (Smart TV): la mano ===== *\/&#10;#manoTV { position: fixed; z-index: 5000; left: 50%; top: 50%; font-size: 46px; line-height: 1; pointer-events: none; display: none; transform: translate(-50%, -8%); filter: drop-shadow(0 0 8px #7cffd9) drop-shadow(0 2px 3px rgba(0,0,0,0.6)); }&#10;#manoTV.ver { display: block; }&#10;#ayudaMando { position: fixed; left: 50%; bottom: 14px; transform: translateX(-50%); z-index: 4900; background: rgba(42,21,51,0.92); color: #fff5e0; font: 700 15px 'Plus Jakarta Sans', sans-serif; padding: 8px 18px; border-radius: 16px; border: 2px solid var(--rosa); opacity: 0; transition: opacity .5s; pointer-events: none; white-space: nowrap; }&#10;#ayudaMando.ver { opacity: .96; }&#10;&#10;\/* ===== FICHAS DE LAS CHICAS (privadas) ===== *\/&#10;#fichas { position: fixed; inset: 0; z-index: 4800; background: rgba(10,6,20,0.72); display: flex; align-items: center; justify-content: center; }&#10;#fichas[hidden] { display: none; }&#10;#fichas .fi-caja { width: min(660px, 94vw); max-height: 90vh; overflow: auto; background: #2a1533; color: #fff5e0; border: 3px solid var(--rosa); border-radius: 20px; padding: 14px 16px; font: 600 14px 'Plus Jakarta Sans', sans-serif; }&#10;#fichas .fi-tit { display: flex; justify-content: space-between; align-items: center; font-weight: 800; font-size: 17px; margin-bottom: 4px; }&#10;#fichas .fi-tit button { background: transparent; color: #fff5e0; border: 2px solid var(--rosa); border-radius: 50%; width: 30px; height: 30px; font-size: 15px; cursor: pointer; }&#10;#fichas .fi-sub { font-size: 12px; opacity: .8; margin-bottom: 10px; }&#10;#fichas .fi-fila { display: flex; align-items: center; gap: 10px; padding: 7px 0; border-top: 1px solid rgba(255,255,255,0.12); }&#10;#fichas .fi-ic { width: 38px; height: 38px; border-radius: 50%; border: 3px solid; display: flex; align-items: center; justify-content: center; font-size: 20px; flex: none; background: rgba(255,255,255,0.08); }&#10;#fichas .fi-tx { flex: 1; min-width: 0; }&#10;#fichas .fi-tx small { display: block; opacity: .75; font-size: 11px; font-weight: 600; }&#10;#fichas input { width: 150px; font: 700 14px 'Plus Jakarta Sans', sans-serif; padding: 6px 10px; border-radius: 10px; border: 2px solid var(--rosa); background: #fff5e0; color: #2a1533; }&#10;&#10;\/* ===== SELECTOR DE IDIOMA ===== *\/&#10;#btnIdioma { position: fixed; top: max(4px, env(safe-area-inset-top, 0px)); left: max(8px, env(safe-area-inset-left, 0px)); z-index: 60; font: 700 13px 'Plus Jakarta Sans', sans-serif; color: #fff5e0; background: rgba(42,21,51,0.88); border: 2px solid var(--rosa); border-radius: 18px; padding: 3px 11px; cursor: pointer; line-height: 1.4; transition: opacity .6s; opacity: .85; }&#10;#menuIdioma { position: fixed; top: 36px; left: 8px; z-index: 4700; display: grid; grid-template-columns: repeat(4, auto); gap: 4px; background: rgba(42,21,51,0.97); border: 2px solid var(--rosa); border-radius: 14px; padding: 8px; }&#10;#menuIdioma[hidden] { display: none; }&#10;#menuIdioma button { font: 700 13px 'Plus Jakarta Sans', sans-serif; color: #fff5e0; background: rgba(255,255,255,0.08); border: 1px solid rgba(255,255,255,0.25); border-radius: 10px; padding: 5px 9px; cursor: pointer; }&#10;body.tv #btnIdioma { opacity: 0; pointer-events: none; }&#10;body.tv #btnIdioma.ver { opacity: .9; pointer-events: auto; }&#10;&#10;\/* ===== PORTADA, POSTAL Y AJUSTES PARA LA WEB ===== *\/&#10;body { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; -webkit-tap-highlight-color: transparent; }&#10;#portada { position: fixed; inset: 0; z-index: 1000; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px;&#10;  padding: max(24px, env(safe-area-inset-top, 0px)) max(24px, env(safe-area-inset-right, 0px)) max(24px, env(safe-area-inset-bottom, 0px)) max(24px, env(safe-area-inset-left, 0px));&#10;  text-align: center; color: #fff5fa; font-family: 'Plus Jakarta Sans', 'Comic Sans MS', sans-serif; overflow: hidden; transition: opacity 0.55s ease;&#10;  background: radial-gradient(circle at 20% 15%, #5a2a6b, transparent 55%), radial-gradient(circle at 85% 85%, #b02a5a, transparent 55%), #2a1533; }&#10;#portada.saliendo { opacity: 0; pointer-events: none; }&#10;#portada h2 { margin: 0; font-size: clamp(30px, 7.5vw, 58px); line-height: 1.05; text-shadow: 0 0 22px rgba(255,105,180,0.65), 0 3px 8px rgba(0,0,0,0.45); }&#10;#portada .lema { margin: 0; max-width: 520px; font-size: clamp(13px, 2.6vw, 17px); opacity: 0.92; line-height: 1.45; }&#10;#portada .fila { font-size: clamp(24px, 5vw, 34px); letter-spacing: 6px; filter: drop-shadow(0 2px 4px rgba(0,0,0,0.35)); }&#10;#portada .botones { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-top: 6px; }&#10;.btn-portada { border: 3px solid #fff; border-radius: 999px; padding: 13px 26px; cursor: pointer; color: #fff; font: 800 clamp(15px, 3.4vw, 19px) 'Plus Jakarta Sans', 'Comic Sans MS', sans-serif;&#10;  background: linear-gradient(90deg, #ff69b4, #6a3e8c); box-shadow: 0 6px 22px rgba(0,0,0,0.4); transition: transform 0.15s, opacity 0.3s; }&#10;.btn-portada.sec { background: rgba(255,255,255,0.12); }&#10;.btn-portada.pref { box-shadow: 0 0 0 4px rgba(124,255,217,0.55), 0 6px 22px rgba(0,0,0,0.4); }&#10;.btn-portada:hover:not(:disabled) { transform: scale(1.05); } .btn-portada:disabled { opacity: 0.45; cursor: default; }&#10;#portada .barra { width: min(260px, 60vw); height: 8px; border-radius: 8px; background: rgba(255,255,255,0.2); overflow: hidden; }&#10;#portada .barra i { display: block; height: 100%; width: 40%; border-radius: 8px; background: #7cffd9; animation: carga 1.1s ease-in-out infinite; }&#10;#portada.listo .barra { display: none; }&#10;@keyframes carga { 0% { transform: translateX(-100%); } 100% { transform: translateX(260%); } }&#10;#portadaEstado { font-size: 13px; opacity: 0.9; min-height: 18px; margin: 0; }&#10;#portada .pie { margin: 0; font-size: 11.5px; opacity: 0.75; max-width: 560px; line-height: 1.5; }&#10;#portada .giro { display: none; font-size: 13px; background: rgba(255,255,255,0.14); border-radius: 12px; padding: 6px 12px; }&#10;@media (orientation: portrait) and (max-width: 700px) { #portada .giro { display: block; } }&#10;.petalo { position: absolute; bottom: -50px; opacity: 0.85; pointer-events: none; animation: subir linear infinite; }&#10;@keyframes subir { 0% { transform: translateY(0) rotate(0deg); opacity: 0; } 10% { opacity: 0.85; } 100% { transform: translateY(-115vh) rotate(380deg); opacity: 0; } }&#10;@media (prefers-reduced-motion: reduce) { .petalo { display: none; } #portada .barra i { animation: none; width: 100%; } #portada { transition: none; } }&#10;#postalModal { position: fixed; inset: 0; z-index: 900; display: flex; align-items: center; justify-content: center; padding: 16px; background: rgba(20,8,28,0.82); }&#10;#postalModal[hidden] { display: none; }&#10;#postalModal .caja { max-width: min(96vw, 980px); max-height: 94vh; display: flex; flex-direction: column; align-items: center; gap: 10px; }&#10;#postalModal img { max-width: 100%; max-height: 72vh; border-radius: 16px; box-shadow: 0 10px 40px rgba(0,0,0,0.6); -webkit-user-select: auto; user-select: auto; -webkit-touch-callout: default; }&#10;#postalModal .fila-botones { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }&#10;#postalModal button { border: 2px solid rgba(255,255,255,0.9); border-radius: 18px; padding: 9px 16px; cursor: pointer; color: #fff; font: 700 14px 'Plus Jakarta Sans', 'Comic Sans MS', sans-serif; background: linear-gradient(90deg, #ff69b4, #6a3e8c); }&#10;#postalModal button[hidden] { display: none; }&#10;#postalAviso { margin: 0; color: #fff5e0; font: 500 12px 'Plus Jakarta Sans', sans-serif; text-align: center; max-width: 520px; }&#10;\/* ===== AYUDA Y PANTALLAS PEQUE\u00d1AS: men\u00fa compacto, zoom, gu\u00eda de bienvenida y texto grande ===== *\/&#10;#navExtra { display: contents; }&#10;#navMas, #navZoom { }&#10;#navMas { display: none; }&#10;#nav .chipfiesta.sel { border-style: solid; background: rgba(124,255,217,0.25); }&#10;#nav .chipfiesta.ico { padding: 3px 8px; font-size: 14px; }&#10;#nav .chipfiesta { box-sizing: border-box; }&#10;#giroAviso { display: none; margin: 0 0 3px; padding: 3px 10px; border-radius: 12px; background: rgba(255,245,224,0.14); color: #fff5e0; font: 700 11.5px 'Plus Jakarta Sans', 'Comic Sans MS', sans-serif; text-align: center; flex: 0 0 auto; }&#10;@media (orientation: portrait) and (max-width: 500px) { #giroAviso { display: block; } body.zoomOn #giroAviso { display: none; } }&#10;\/* Pantallas peque\u00f1as o bajitas (m\u00f3vil, la vista dentro de Claude, ventanas peque\u00f1as): una sola fila de iconos y el resto en \u00ab\u2699\ufe0f\u00bb \u2192 el pueblo ocupa casi todo *\/&#10;@media (max-width: 760px), (max-height: 600px) {&#10;    body { padding: 3px max(6px, env(safe-area-inset-right, 0px)) 3px max(6px, env(safe-area-inset-left, 0px)); }&#10;    h1, p.pista { display: none; }&#10;    #nav { gap: 4px; padding: 2px 5px; margin: 0 0 3px; border-width: 1.5px; align-items: center; }&#10;    #nav button { padding: 2px 10px; font-size: 14px; flex: 0 0 auto; line-height: 1.5; border-width: 1.5px; }&#10;    #nav .et { display: none; }&#10;    #nav .chipfiesta { flex: 0 0 auto; }&#10;    #navMas { display: inline-block; }&#10;    #nav .saldo { font-size: 12px; margin-left: auto; flex: 0 0 auto; }&#10;    #navExtra { display: none; position: absolute; top: calc(100% + 4px); left: 0; right: 0; z-index: 12; flex-wrap: wrap; justify-content: center; gap: 6px; padding: 8px; background: rgba(42,21,51,0.97); border: 2px solid var(--rosa); border-radius: 16px; }&#10;    body.masAbierto #navExtra { display: flex; }&#10;    #nav .chipfiesta { min-height: 30px; display: inline-flex; align-items: center; }&#10;    #nav .chipfiesta.ico { min-height: 28px; padding: 1px 9px; border-width: 1.5px; }&#10;    #radioMenu { position: fixed; top: 54px; left: 8px; right: 8px; max-width: 430px; margin: 0 auto; min-width: 0; z-index: 14; }&#10;    #avisoKutxa { top: auto; bottom: max(10px, env(safe-area-inset-bottom, 0px)); font-size: 13px; padding: 6px 12px; max-width: 94vw; }&#10;}&#10;@media (max-width: 350px) {&#10;    #nav { gap: 1px; padding: 2px 2px; } #nav button { padding: 2px 3px; font-size: 12px; } #nav .chipfiesta.ico { padding: 1px 3px; font-size: 12px; } #nav .saldo { font-size: 9.5px; padding: 0 1px; }&#10;}&#10;@media (max-width: 430px) {&#10;    #nav { gap: 3px; padding: 2px 4px; }&#10;    #nav button { padding: 2px 5px; }&#10;    #nav .chipfiesta.ico { padding: 1px 5px; font-size: 13px; }&#10;    #nav .saldo { font-size: 10.5px; padding: 0 2px; }&#10;}&#10;@media (min-width: 761px) and (min-height: 601px) {&#10;    body.grande #nav button { font-size: 15px; padding: 9px 14px; min-height: 44px; }&#10;    body.grande #nav .chipfiesta { font-size: 14px; padding: 8px 12px; min-height: 40px; }&#10;    body.grande #nav .saldo { font-size: 15px; }&#10;    body.grande h1 { font-size: clamp(18px, 4.4vw, 30px); } body.grande p.pista { font-size: 15px; }&#10;}&#10;body.grande #avisoKutxa { font-size: 16px; max-width: 94vw; }&#10;body.grande #radioMenu .op { font-size: 15px; padding: 10px 12px; } body.grande #radioMenu .pie { font-size: 13px; }&#10;\/* Zoom: el lienzo se agranda dentro de su marco y se mueve con las flechas *\/&#10;.pantalla-juego.zoom { overflow: auto; align-items: flex-start; justify-content: flex-start; -webkit-overflow-scrolling: touch; }&#10;.lienzo-wrap.zoom { width: max-content; height: max-content; display: block; margin: auto; }&#10;#panZoom { position: fixed; right: max(10px, env(safe-area-inset-right, 0px)); bottom: calc(max(10px, env(safe-area-inset-bottom, 0px)) + 42px); z-index: 13; display: grid; grid-template-columns: repeat(3, 34px); grid-template-rows: repeat(3, 34px); gap: 2px; opacity: 0.72; transition: opacity 0.4s; }&#10;#panZoom.tenue { opacity: 0.28; }&#10;#panZoom[hidden], body.padOculto #panZoom { display: none; }&#10;#panZoom button { width: 34px; height: 34px; border-radius: 50%; border: 1.5px solid rgba(255,255,255,0.7); background: rgba(42,21,51,0.55); color: #fff; font: 700 14px 'Plus Jakarta Sans', sans-serif; cursor: pointer; padding: 0; }&#10;#panAsa { position: fixed; right: max(10px, env(safe-area-inset-right, 0px)); bottom: max(10px, env(safe-area-inset-bottom, 0px)); z-index: 13; width: 34px; height: 34px; border-radius: 50%; border: 1.5px solid rgba(255,255,255,0.7); background: rgba(42,21,51,0.6); color: #fff; font: 700 15px 'Plus Jakarta Sans', sans-serif; cursor: pointer; padding: 0; opacity: 0.72; }&#10;#panAsa[hidden] { display: none; }&#10;@media (max-height: 420px) { #panZoom { grid-template-columns: repeat(3, 30px); grid-template-rows: repeat(3, 30px); bottom: calc(max(8px, env(safe-area-inset-bottom, 0px)) + 38px); } #panZoom button, #panAsa { width: 30px; height: 30px; font-size: 12px; } }&#10;#panZoom [data-d=&quot;up&quot;] { grid-area: 1 \/ 2; } #panZoom [data-d=&quot;left&quot;] { grid-area: 2 \/ 1; } #panZoom [data-d=&quot;right&quot;] { grid-area: 2 \/ 3; } #panZoom [data-d=&quot;down&quot;] { grid-area: 3 \/ 2; } #panZoom [data-d=&quot;reset&quot;] { grid-area: 2 \/ 2; background: rgba(42,157,120,0.8); font-size: 12px; }&#10;#guardar { position: fixed; inset: 0; z-index: 1500; display: flex; align-items: center; justify-content: center; padding: 12px; background: rgba(20,8,28,0.82); }&#10;#guardar[hidden] { display: none; }&#10;#guardar .caja { width: min(94vw, 520px); max-height: 94vh; overflow: auto; display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 16px 18px; border-radius: 24px; text-align: center; background: radial-gradient(circle at 20% 10%, #4a2360, transparent 60%), #2a1533; border: 3px solid var(--rosa); box-shadow: 0 12px 50px rgba(0,0,0,0.6); font-family: 'Plus Jakarta Sans', 'Comic Sans MS', sans-serif; color: #fff5fa; }&#10;#guardar h2 { margin: 0; font-size: clamp(19px, 5vw, 26px); } #guardar p { margin: 0; font-size: clamp(13px, 3.4vw, 16px); line-height: 1.4; }&#10;#guardar textarea { width: 100%; box-sizing: border-box; border-radius: 12px; border: 2px solid rgba(255,255,255,0.5); background: rgba(0,0,0,0.35); color: #fff; font: 12px\/1.3 monospace; padding: 8px; resize: none; }&#10;#guardar .fila-botones { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }&#10;#guardar button { min-height: 42px; border: 2px solid rgba(255,255,255,0.9); border-radius: 20px; padding: 6px 16px; cursor: pointer; color: #fff; font: 700 clamp(13px, 3.4vw, 15px) 'Plus Jakarta Sans', 'Comic Sans MS', sans-serif; background: linear-gradient(90deg, var(--rosa), var(--morado)); }&#10;#guardar button.sec { background: rgba(255,255,255,0.12); } #guardar button.armado { background: #c0392b; border-color: #ffd0c8; }&#10;#guardarEstado { min-height: 1.2em; color: #7cffd9; font-weight: 700; }&#10;@media (max-height: 420px) { #guardar .caja { padding: 8px 14px; gap: 5px; } #guardar p:first-of-type { display: none; } #guardar textarea { rows: 2; height: 40px; } #guardar button { min-height: 34px; padding: 3px 12px; } }&#10;#guia { position: fixed; inset: 0; z-index: 1500; display: flex; align-items: center; justify-content: center; padding: 14px; background: rgba(20,8,28,0.82); }&#10;#guia[hidden] { display: none; }&#10;#libro { position: fixed; inset: 0; z-index: 3000; display: flex; align-items: center; justify-content: center; padding: 14px; background: rgba(20,8,28,0.88); }&#10;#libro[hidden] { display: none; }&#10;#libro .caja { width: min(96vw, 680px); max-height: 94vh; display: flex; flex-direction: column; gap: 10px; padding: 16px 18px; border-radius: 24px; background: linear-gradient(160deg, #3a1d52, #1d0f2e); border: 3px solid #ff69b4; color: #fff; }&#10;#libro h2 { margin: 0; text-align: center; font-size: clamp(20px, 5vw, 26px); }&#10;#libro textarea { width: 100%; flex: 1; min-height: 38vh; resize: none; border-radius: 14px; border: 2px solid rgba(255,255,255,0.4); background: rgba(0,0,0,0.35); color: #fff; padding: 12px; font: 500 15px\/1.5 'Plus Jakarta Sans', sans-serif; box-sizing: border-box; }&#10;#libro #libroEstado { min-height: 20px; text-align: center; font-size: 14px; color: #7cffd9; }&#10;#libro .fila-botones { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }&#10;#libro button { min-height: 46px; border: 2px solid rgba(255,255,255,0.9); border-radius: 22px; padding: 8px 18px; cursor: pointer; color: #fff; font: 700 16px 'Plus Jakarta Sans', 'Comic Sans MS', sans-serif; background: linear-gradient(90deg, var(--rosa), var(--morado)); }&#10;#libro button.sec { background: rgba(255,255,255,0.12); }&#10;#libroAbrir { background: none; border: 0; color: rgba(255,255,255,0.85); text-decoration: underline; cursor: pointer; font: 600 15px 'Plus Jakarta Sans', sans-serif; margin-top: 6px; }&#10;#diario { position: fixed; inset: 0; z-index: 1500; display: flex; align-items: center; justify-content: center; padding: 14px; background: rgba(20,8,28,0.82); }&#10;#diario[hidden] { display: none; }&#10;#diario .caja { width: min(94vw, 620px); max-height: 92vh; overflow: auto; display: flex; flex-direction: column; gap: 10px; padding: 18px 20px; border-radius: 26px; background: linear-gradient(160deg, #3a1d52, #1d0f2e); border: 3px solid #ff69b4; color: #fff; }&#10;#diario h2 { margin: 0; text-align: center; font-size: clamp(22px, 5vw, 28px); }&#10;#diario .sub { margin: 0; text-align: center; opacity: .8; font-size: 15px; }&#10;#diario h3 { margin: 8px 0 4px; font-size: 17px; color: #7cffd9; }&#10;#diario .fila { display: flex; flex-wrap: wrap; gap: 6px; }&#10;#diario .it { padding: 6px 12px; border-radius: 16px; background: rgba(255,255,255,0.14); font-size: 15px; font-weight: 600; }&#10;#diario .it.no { opacity: .35; background: rgba(255,255,255,0.06); }&#10;#diario .vacio { opacity: .55; font-size: 14px; font-style: italic; }&#10;#diario .fila-botones { display: flex; justify-content: center; margin-top: 6px; }&#10;#diario button { min-height: 48px; border: 2px solid rgba(255,255,255,0.9); border-radius: 22px; padding: 10px 26px; cursor: pointer; color: #fff; font: 700 17px 'Plus Jakarta Sans', 'Comic Sans MS', sans-serif; background: linear-gradient(90deg, var(--rosa), var(--morado)); }&#10;#guia .caja { width: min(94vw, 560px); max-height: 92vh; overflow: auto; display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 20px 22px; border-radius: 26px; text-align: center;&#10;    background: radial-gradient(circle at 20% 10%, #4a2360, transparent 60%), #2a1533; border: 3px solid var(--rosa); box-shadow: 0 12px 50px rgba(0,0,0,0.6); font-family: 'Plus Jakarta Sans', 'Comic Sans MS', sans-serif; color: #fff5fa; }&#10;#guia .icono { font-size: clamp(40px, 11vw, 64px); line-height: 1; }&#10;#guia h2 { margin: 0; font-size: clamp(22px, 5.4vw, 30px); line-height: 1.2; }&#10;#guia p { margin: 0; font-size: clamp(17px, 4.2vw, 21px); line-height: 1.5; font-weight: 500; }&#10;#guia .puntos { display: flex; gap: 8px; } #guia .puntos i { width: 10px; height: 10px; border-radius: 50%; background: rgba(255,255,255,0.3); } #guia .puntos i.on { background: #7cffd9; }&#10;#guia .fila-botones { display: flex; flex-wrap: wrap; gap: 10px; justify-content: center; margin-top: 4px; }&#10;#guia button { min-height: 48px; border: 2px solid rgba(255,255,255,0.9); border-radius: 22px; padding: 10px 22px; cursor: pointer; color: #fff; font: 700 clamp(16px, 4vw, 18px) 'Plus Jakarta Sans', 'Comic Sans MS', sans-serif; background: linear-gradient(90deg, var(--rosa), var(--morado)); }&#10;#guia button.sec { background: rgba(255,255,255,0.12); } #guia button.on { background: #2a9d78; border-color: #7cffd9; }&#10;@media (max-height: 300px) { #guia .icono { display: none; } #guia .caja { padding: 10px 16px; gap: 5px; } #guia h2 { font-size: 18px; } #guia p { font-size: 14px; } #guia button { min-height: 38px; padding: 4px 14px; font-size: 14px; } }&#10;@media (max-height: 520px) { #guia .caja { padding: 12px 18px; gap: 6px; } #guia .icono { font-size: 34px; } #guia h2 { font-size: 20px; } #guia p { font-size: 15px; line-height: 1.35; } #guia button { min-height: 42px; padding: 6px 18px; } }&#10;\/* ===== PORTADA EN PANTALLAS BAJITAS (m\u00f3vil en horizontal, vista dentro de Claude): todo cabe y, si no cabe, se desplaza ===== *\/&#10;@media (max-height: 560px) {&#10;    #portada { overflow-y: auto; justify-content: flex-start; } #portada &gt; .fila { margin-top: auto; } #portada &gt; .pie { margin-bottom: auto; } #portada .petalo { display: none; }&#10;    #portada { gap: 6px; padding: max(8px, env(safe-area-inset-top, 0px)) max(16px, env(safe-area-inset-right, 0px)) max(8px, env(safe-area-inset-bottom, 0px)) max(16px, env(safe-area-inset-left, 0px)); }&#10;    #portada .fila { font-size: 18px; letter-spacing: 3px; }&#10;    #portada h2 { font-size: clamp(20px, 6.5vh, 34px); }&#10;    #portada .lema { font-size: 12px; line-height: 1.3; max-width: 92vw; }&#10;    #portada .botones { gap: 8px; margin-top: 0; }&#10;    .btn-portada { padding: 7px 18px; border-width: 2px; font-size: 14px; }&#10;    #portada .pie { font-size: 10px; line-height: 1.3; }&#10;    #portadaEstado { min-height: 0; font-size: 12px; }&#10;    #portada .giro { padding: 3px 10px; font-size: 11.5px; }&#10;}&#10;@media (max-height: 300px) { #portada .fila, #portada .lema { display: none; } #portada h2 { font-size: 22px; } }&#10;&lt;\/style&gt;&#10;&lt;link rel=&quot;stylesheet&quot; href=&quot;https:\/\/fonts.googleapis.com\/css2?family=Plus+Jakarta+Sans:wght@500;700&amp;display=swap&quot;&gt;&#10;&lt;\/head&gt;&#10;&lt;body&gt;&#10;&lt;div id=&quot;portada&quot; role=&quot;dialog&quot; aria-modal=&quot;true&quot; aria-labelledby=&quot;portadaTitulo&quot;&gt;&#10;  &lt;span class=&quot;petalo&quot; style=&quot;left:6%;font-size:22px;animation-duration:13s;animation-delay:0s&quot; aria-hidden=&quot;true&quot;&gt;\ud83c\udf38&lt;\/span&gt;&#10;  &lt;span class=&quot;petalo&quot; style=&quot;left:16%;font-size:16px;animation-duration:10s;animation-delay:2s&quot; aria-hidden=&quot;true&quot;&gt;\u2728&lt;\/span&gt;&#10;  &lt;span class=&quot;petalo&quot; style=&quot;left:27%;font-size:26px;animation-duration:15s;animation-delay:5s&quot; aria-hidden=&quot;true&quot;&gt;\ud83d\udc9c&lt;\/span&gt;&#10;  &lt;span class=&quot;petalo&quot; style=&quot;left:38%;font-size:18px;animation-duration:11s;animation-delay:1s&quot; aria-hidden=&quot;true&quot;&gt;\ud83c\udf3c&lt;\/span&gt;&#10;  &lt;span class=&quot;petalo&quot; style=&quot;left:49%;font-size:24px;animation-duration:14s;animation-delay:7s&quot; aria-hidden=&quot;true&quot;&gt;\ud83c\udf38&lt;\/span&gt;&#10;  &lt;span class=&quot;petalo&quot; style=&quot;left:60%;font-size:15px;animation-duration:9.5s;animation-delay:3s&quot; aria-hidden=&quot;true&quot;&gt;\u2728&lt;\/span&gt;&#10;  &lt;span class=&quot;petalo&quot; style=&quot;left:70%;font-size:22px;animation-duration:12.5s;animation-delay:6s&quot; aria-hidden=&quot;true&quot;&gt;\ud83c\udf3a&lt;\/span&gt;&#10;  &lt;span class=&quot;petalo&quot; style=&quot;left:81%;font-size:18px;animation-duration:10.5s;animation-delay:4s&quot; aria-hidden=&quot;true&quot;&gt;\ud83d\udc9c&lt;\/span&gt;&#10;  &lt;span class=&quot;petalo&quot; style=&quot;left:91%;font-size:24px;animation-duration:14.5s;animation-delay:8s&quot; aria-hidden=&quot;true&quot;&gt;\ud83c\udf38&lt;\/span&gt;&#10;  &lt;div class=&quot;fila&quot; aria-hidden=&quot;true&quot;&gt;\ud83c\udfd8\ufe0f\ud83c\udfd6\ufe0f\ud83c\udf31\ud83c\udfea\ud83c\udfed\ud83d\udcda\u26f5&lt;\/div&gt;&#10;  &lt;h2 id=&quot;portadaTitulo&quot;&gt;El Pueblo de ChicaChica \ud83d\udc9c\ud83c\udf38&lt;\/h2&gt;&#10;  &lt;p class=&quot;lema&quot;&gt;Un pueblo solarpunk donde las chicas viven su d\u00eda: huerta, mercado, biblioteca digital, playa y puerto, y las fiestas vascas del calendario.&lt;\/p&gt;&#10;  &lt;div class=&quot;barra&quot; aria-hidden=&quot;true&quot;&gt;&lt;i&gt;&lt;\/i&gt;&lt;\/div&gt;&#10;  &lt;p id=&quot;portadaEstado&quot; role=&quot;status&quot;&gt;Cargando el pueblo\u2026&lt;\/p&gt;&#10;  &lt;div class=&quot;botones&quot;&gt;&#10;    &lt;button class=&quot;btn-portada&quot; id=&quot;btnConSonido&quot; data-sonido=&quot;si&quot; disabled&gt;\ud83d\udd0a Entrar con m\u00fasica&lt;\/button&gt;&#10;    &lt;button class=&quot;btn-portada sec&quot; id=&quot;btnSinSonido&quot; data-sonido=&quot;no&quot; disabled&gt;\ud83d\udd07 Entrar sin sonido&lt;\/button&gt;&#10;    &lt;button class=&quot;btn-portada sec&quot; id=&quot;btnRecargar&quot; hidden onclick=&quot;location.reload()&quot;&gt;\u21bb Recargar&lt;\/button&gt;&#10;    &lt;button id=&quot;libroAbrir&quot; type=&quot;button&quot;&gt;\ud83d\udcc4 Libro blanco&lt;\/button&gt;&#10;  &lt;\/div&gt;&#10;  &lt;p class=&quot;giro&quot;&gt;\ud83d\udcf1\u2194 En el m\u00f3vil se ve mejor en horizontal&lt;\/p&gt;&#10;  &lt;p class=&quot;pie&quot; id=&quot;portadaPie&quot;&gt;v1.0 \u00b7 Sin cookies ni anuncios \u00b7 tu progreso se guarda solo en este dispositivo \u00b7 m\u00fasica original&lt;\/p&gt;&#10;&lt;\/div&gt;&#10;&lt;noscript&gt;&lt;p style=&quot;position:fixed;inset:0;z-index:2000;margin:0;padding:40px;background:#2a1533;color:#fff5fa;font:600 18px sans-serif;text-align:center&quot;&gt;El Pueblo de ChicaChica necesita JavaScript para funcionar \ud83d\udc9c&lt;\/p&gt;&lt;\/noscript&gt;&#10;&#10;&lt;nav id=&quot;nav&quot; aria-label=&quot;Navegaci\u00f3n entre pantallas&quot;&gt;&#10;    &lt;button data-p=&quot;pueblo&quot;&gt;\ud83c\udfd8\ufe0f&lt;span class=&quot;et&quot;&gt; Pueblo&lt;\/span&gt;&lt;\/button&gt;&#10;    &lt;button data-p=&quot;playa&quot;&gt;\ud83c\udfd6\ufe0f&lt;span class=&quot;et&quot;&gt; Playa&lt;\/span&gt;&lt;\/button&gt;&#10;    &lt;button data-p=&quot;huerta&quot;&gt;\ud83c\udf31&lt;span class=&quot;et&quot;&gt; La Huerta&lt;\/span&gt;&lt;\/button&gt;&#10;    &lt;button data-p=&quot;mercado&quot;&gt;\ud83c\udfea&lt;span class=&quot;et&quot;&gt; Mercado&lt;\/span&gt;&lt;\/button&gt;&#10;    &lt;button data-p=&quot;industria&quot;&gt;\ud83c\udfed&lt;span class=&quot;et&quot;&gt; Industrial&lt;\/span&gt;&lt;\/button&gt;&#10;    &lt;button data-p=&quot;arena&quot;&gt;\ud83c\udfdf\ufe0f&lt;span class=&quot;et&quot;&gt; Arena&lt;\/span&gt;&lt;\/button&gt;&#10;    &lt;button data-p=&quot;hospital&quot;&gt;\ud83c\udfe5&lt;span class=&quot;et&quot;&gt; Hospital&lt;\/span&gt;&lt;\/button&gt;&#10;    &lt;span class=&quot;chipfiesta ico&quot; id=&quot;navZoom&quot; role=&quot;button&quot; tabindex=&quot;0&quot; title=&quot;Acercar el pueblo&quot; aria-label=&quot;Acercar el pueblo&quot;&gt;\ud83d\udd0d&lt;\/span&gt;&#10;    &lt;span class=&quot;chipfiesta ico&quot; id=&quot;navMas&quot; role=&quot;button&quot; tabindex=&quot;0&quot; title=&quot;M\u00e1s opciones&quot; aria-label=&quot;M\u00e1s opciones&quot; aria-expanded=&quot;false&quot;&gt;\u2699\ufe0f&lt;\/span&gt;&#10;    &lt;span class=&quot;chipfiesta ico&quot; id=&quot;navGuardar&quot; role=&quot;button&quot; tabindex=&quot;0&quot; title=&quot;Guardar o cargar mi pueblo&quot; aria-label=&quot;Guardar o cargar mi pueblo&quot;&gt;\ud83d\udcbe&lt;\/span&gt;&#10;    &lt;div id=&quot;navExtra&quot;&gt;&#10;        &lt;span class=&quot;chipfiesta&quot; id=&quot;navRadio&quot; role=&quot;button&quot; title=&quot;Emisora de radio&quot;&gt;\ud83d\udcfb \u2026&lt;\/span&gt;&#10;        &lt;span class=&quot;chipfiesta&quot; id=&quot;navFiesta&quot; role=&quot;button&quot; title=&quot;Toca para previsualizar las fiestas&quot;&gt;\ud83d\udcc5 \u2026&lt;\/span&gt;&#10;        &lt;span class=&quot;chipfiesta&quot; id=&quot;navPostal&quot; role=&quot;button&quot; tabindex=&quot;0&quot; title=&quot;Saca una postal del pueblo&quot;&gt;\ud83d\udcf8 Postal&lt;\/span&gt;&#10;        &lt;span class=&quot;chipfiesta&quot; id=&quot;navDiario&quot; role=&quot;button&quot; tabindex=&quot;0&quot; title=&quot;El diario del pueblo&quot; aria-label=&quot;El diario del pueblo&quot;&gt;\ud83d\udcd6 Diario&lt;\/span&gt;&#10;        &lt;span class=&quot;chipfiesta&quot; id=&quot;navTexto&quot; role=&quot;button&quot; tabindex=&quot;0&quot; title=&quot;Texto grande&quot; aria-label=&quot;Texto grande&quot;&gt;Aa+ Texto grande&lt;\/span&gt;&#10;        &lt;span class=&quot;chipfiesta&quot; id=&quot;navAyuda&quot; role=&quot;button&quot; tabindex=&quot;0&quot; title=&quot;C\u00f3mo se juega&quot; aria-label=&quot;C\u00f3mo se juega&quot;&gt;\u2753 Ayuda&lt;\/span&gt;&#10;    &lt;\/div&gt;&#10;    &lt;span class=&quot;saldo&quot; id=&quot;navSaldo&quot;&gt;\ud83e\ude99 0 MIIG26D&lt;\/span&gt;&#10;    &lt;div id=&quot;radioMenu&quot; hidden&gt;&lt;\/div&gt;&#10;&lt;\/nav&gt;&#10;&lt;div id=&quot;avisoKutxa&quot; role=&quot;status&quot;&gt;&lt;\/div&gt;&#10;&lt;p id=&quot;giroAviso&quot;&gt;\ud83d\udcf1\u2194 Gira el m\u00f3vil, o toca la lupa \ud83d\udd0d para acercar&lt;\/p&gt;&#10;&#10;&lt;button id=&quot;btnTV&quot; type=&quot;button&quot; aria-label=&quot;Modo Smart TV: pantalla completa y sin botones&quot;&gt;\ud83d\udcfa Smart TV&lt;\/button&gt;&#10;&lt;h1&gt;El Pueblo de ChicaChica \ud83d\udc9c\ud83c\udf38&lt;\/h1&gt;&#10;&lt;p class=&quot;pista&quot; data-i18n=&quot;pista&quot;&gt;Arrastra a una chica a un banco, a un patinete, al tranv\u00eda o t\u00f3calo (\u00a1se va a la playa a surfear!), a una casa, a la mesa de la biblioteca, o toca el cubo del gimnasio&lt;\/p&gt;&#10;&lt;div class=&quot;pantalla-juego&quot; id=&quot;pantallaJuego&quot;&gt;&#10;    &lt;div class=&quot;lienzo-wrap&quot; id=&quot;lienzoWrap&quot;&gt;&#10;        &lt;canvas id=&quot;pueblo&quot; width=&quot;960&quot; height=&quot;540&quot; role=&quot;img&quot; aria-label=&quot;El Pueblo de ChicaChica: un pueblo solarpunk con casas, plaza, tranv\u00eda, huerta, mercado, playa y puerto, donde las chicas viven su d\u00eda&quot;&gt;&lt;\/canvas&gt;&#10;    &lt;\/div&gt;&#10;&lt;\/div&gt;&#10;&#10;&lt;div id=&quot;panZoom&quot; hidden aria-label=&quot;Mover la vista&quot;&gt;&#10;  &lt;button data-d=&quot;up&quot; aria-label=&quot;Subir la vista&quot;&gt;\u25b2&lt;\/button&gt;&lt;button data-d=&quot;left&quot; aria-label=&quot;Vista a la izquierda&quot;&gt;\u25c0&lt;\/button&gt;&lt;button data-d=&quot;reset&quot; aria-label=&quot;Quitar el zoom&quot;&gt;1\u00d7&lt;\/button&gt;&lt;button data-d=&quot;right&quot; aria-label=&quot;Vista a la derecha&quot;&gt;\u25b6&lt;\/button&gt;&lt;button data-d=&quot;down&quot; aria-label=&quot;Bajar la vista&quot;&gt;\u25bc&lt;\/button&gt;&#10;&lt;\/div&gt;&#10;&lt;button id=&quot;panAsa&quot; hidden aria-label=&quot;Mostrar u ocultar las flechas de la vista&quot; title=&quot;Mostrar u ocultar las flechas&quot;&gt;\u2725&lt;\/button&gt;&#10;&lt;div id=&quot;postalModal&quot; hidden role=&quot;dialog&quot; aria-modal=&quot;true&quot; aria-label=&quot;Postal del pueblo&quot;&gt;&#10;  &lt;div class=&quot;caja&quot;&gt;&#10;    &lt;img id=&quot;postalImg&quot; alt=&quot;Postal del Pueblo ChicaChica&quot;&gt;&#10;    &lt;div class=&quot;fila-botones&quot;&gt;&#10;      &lt;button id=&quot;postalCompartir&quot; hidden&gt;\ud83d\udce4 Compartir&lt;\/button&gt;&#10;      &lt;button id=&quot;postalDescargar&quot;&gt;\u2b07\ufe0f Descargar&lt;\/button&gt;&#10;      &lt;button id=&quot;postalCerrar&quot;&gt;\u2715 Cerrar&lt;\/button&gt;&#10;    &lt;\/div&gt;&#10;    &lt;p id=&quot;postalAviso&quot;&gt;Si no se descarga, mant\u00e9n pulsada la imagen y elige \u00abGuardar\u00bb.&lt;\/p&gt;&#10;  &lt;\/div&gt;&#10;&lt;\/div&gt;&#10;&lt;div id=&quot;guardar&quot; hidden role=&quot;dialog&quot; aria-modal=&quot;true&quot; aria-labelledby=&quot;guardarTitulo&quot;&gt;&#10;  &lt;div class=&quot;caja&quot;&gt;&#10;    &lt;h2 id=&quot;guardarTitulo&quot;&gt;\ud83d\udcbe Guardar mi pueblo&lt;\/h2&gt;&#10;    &lt;p&gt;Tu pueblo se guarda solo en este dispositivo. Para llevarlo a otro, o tener una copia, descarga el archivo o copia el c\u00f3digo. Para cargarlo, pega el c\u00f3digo aqu\u00ed o elige el archivo.&lt;\/p&gt;&#10;    &lt;div class=&quot;fila-botones&quot;&gt;&lt;button id=&quot;guardarDescargar&quot;&gt;\u2b07\ufe0f Descargar o compartir&lt;\/button&gt;&lt;button id=&quot;guardarCopiar&quot; class=&quot;sec&quot;&gt;\ud83d\udccb Copiar c\u00f3digo&lt;\/button&gt;&lt;\/div&gt;&#10;    &lt;textarea id=&quot;guardarTexto&quot; rows=&quot;3&quot; aria-label=&quot;C\u00f3digo de mi pueblo&quot; spellcheck=&quot;false&quot; placeholder=&quot;Aqu\u00ed aparece el c\u00f3digo de tu pueblo. Para cargar uno, p\u00e9galo aqu\u00ed.&quot;&gt;&lt;\/textarea&gt;&#10;    &lt;div class=&quot;fila-botones&quot;&gt;&lt;button id=&quot;guardarCargar&quot; class=&quot;sec&quot;&gt;\u2b06\ufe0f Cargar este c\u00f3digo&lt;\/button&gt;&lt;button id=&quot;guardarElegir&quot; class=&quot;sec&quot;&gt;\ud83d\udcc1 Elegir archivo&lt;\/button&gt;&lt;input type=&quot;file&quot; id=&quot;guardarArchivo&quot; accept=&quot;.json,application\/json&quot; hidden&gt;&lt;\/div&gt;&#10;    &lt;h3 style=&quot;margin:10px 0 4px&quot;&gt;\ud83c\udf26\ufe0f El tiempo de tu ciudad&lt;\/h3&gt;&#10;    &lt;div class=&quot;fila-botones&quot;&gt;&lt;input id=&quot;ciudadTxt&quot; type=&quot;text&quot; maxlength=&quot;60&quot; autocomplete=&quot;off&quot; spellcheck=&quot;false&quot; aria-label=&quot;Ciudad&quot; placeholder=&quot;Bilbao&quot; style=&quot;flex:1;min-width:140px;padding:8px;border-radius:10px;border:2px solid #ff69b4;font-size:15px&quot;&gt;&lt;button id=&quot;ciudadBuscar&quot; class=&quot;sec&quot;&gt;Buscar ciudad&lt;\/button&gt;&lt;\/div&gt;&#10;    &lt;p style=&quot;font-size:12px;opacity:.8;margin:4px 0&quot;&gt;Escribe tu ciudad para ver su tiempo en el pueblo. D\u00e9jalo vac\u00edo para volver a Bilbao. Solo se guarda en este dispositivo.&lt;\/p&gt;&#10;    &lt;p id=&quot;ciudadEstado&quot; role=&quot;status&quot; style=&quot;min-height:1.2em;font-weight:700&quot;&gt;&lt;\/p&gt;&#10;    &lt;p id=&quot;guardarEstado&quot; role=&quot;status&quot;&gt;&lt;\/p&gt;&#10;    &lt;div class=&quot;fila-botones&quot;&gt;&lt;button id=&quot;guardarCerrar&quot;&gt;Cerrar&lt;\/button&gt;&lt;\/div&gt;&#10;  &lt;\/div&gt;&#10;&lt;\/div&gt;&#10;&lt;div id=&quot;diario&quot; hidden role=&quot;dialog&quot; aria-modal=&quot;true&quot; aria-labelledby=&quot;diarioTitulo&quot;&gt;&#10;  &lt;div class=&quot;caja&quot;&gt;&#10;    &lt;h2 id=&quot;diarioTitulo&quot;&gt;\ud83d\udcd6 Diario del pueblo&lt;\/h2&gt;&#10;    &lt;p class=&quot;sub&quot; id=&quot;diarioSub&quot;&gt;Se va llenando solo con lo que ves. Sin prisas y sin puntos.&lt;\/p&gt;&#10;    &lt;div id=&quot;diarioCuerpo&quot;&gt;&lt;\/div&gt;&#10;    &lt;div class=&quot;fila-botones&quot;&gt;&lt;button id=&quot;diarioCerrar&quot;&gt;Cerrar&lt;\/button&gt;&lt;\/div&gt;&#10;  &lt;\/div&gt;&#10;&lt;\/div&gt;&#10;&lt;div id=&quot;libro&quot; hidden role=&quot;dialog&quot; aria-modal=&quot;true&quot; aria-labelledby=&quot;libroTitulo&quot;&gt;&#10;  &lt;div class=&quot;caja&quot;&gt;&#10;    &lt;h2 id=&quot;libroTitulo&quot;&gt;\ud83d\udcc4 Libro blanco&lt;\/h2&gt;&#10;    &lt;textarea id=&quot;libroTexto&quot; readonly rows=&quot;14&quot; spellcheck=&quot;false&quot;&gt;&lt;\/textarea&gt;&#10;    &lt;div id=&quot;libroEstado&quot; role=&quot;status&quot;&gt;&lt;\/div&gt;&#10;    &lt;div class=&quot;fila-botones&quot;&gt;&#10;      &lt;button id=&quot;libroIdioma&quot; class=&quot;sec&quot; type=&quot;button&quot;&gt;ES \u00b7 EN&lt;\/button&gt;&#10;      &lt;button id=&quot;libroCopiar&quot; type=&quot;button&quot;&gt;Copiar texto&lt;\/button&gt;&#10;      &lt;button id=&quot;libroDescargar&quot; type=&quot;button&quot;&gt;Descargar&lt;\/button&gt;&#10;      &lt;button id=&quot;libroCerrar&quot; class=&quot;sec&quot; type=&quot;button&quot;&gt;Cerrar&lt;\/button&gt;&#10;    &lt;\/div&gt;&#10;  &lt;\/div&gt;&#10;&lt;\/div&gt;&#10;&lt;div id=&quot;guia&quot; hidden role=&quot;dialog&quot; aria-modal=&quot;true&quot; aria-labelledby=&quot;guiaTitulo&quot;&gt;&#10;  &lt;div class=&quot;caja&quot;&gt;&#10;    &lt;div class=&quot;icono&quot; id=&quot;guiaIcono&quot; aria-hidden=&quot;true&quot;&gt;\ud83d\udc9c&lt;\/div&gt;&#10;    &lt;h2 id=&quot;guiaTitulo&quot;&gt;Bienvenida&lt;\/h2&gt;&#10;    &lt;p id=&quot;guiaCuerpo&quot;&gt;&lt;\/p&gt;&#10;    &lt;div class=&quot;puntos&quot; id=&quot;guiaPuntos&quot; aria-hidden=&quot;true&quot;&gt;&lt;\/div&gt;&#10;    &lt;div class=&quot;fila-botones&quot;&gt;&#10;      &lt;button id=&quot;guiaTexto&quot; class=&quot;sec&quot;&gt;Aa+ Texto grande&lt;\/button&gt;&#10;      &lt;button id=&quot;guiaSaltar&quot; class=&quot;sec&quot;&gt;Saltar&lt;\/button&gt;&#10;      &lt;button id=&quot;guiaSiguiente&quot;&gt;Siguiente \u25b6&lt;\/button&gt;&#10;    &lt;\/div&gt;&#10;  &lt;\/div&gt;&#10;&lt;\/div&gt;&#10;&lt;script&gt;setTimeout(function () { if (!window.__chicachicaListo) { var e = document.getElementById('portadaEstado'), b = document.getElementById('btnRecargar'); if (e) e.textContent = 'Algo no ha cargado bien. Recarga la p\u00e1gina \ud83d\udc9c'; if (b) b.hidden = false; } }, 12000);&lt;\/script&gt;&#10;&lt;script&gt;const canvas = document.getElementById('pueblo');&#10;let ctx = canvas.getContext('2d');&#10;let TXT_ESCALA = 1;                                                                                           \/\/ \u00abAa+\u00bb: agranda los textos que se dibujan en vivo en el lienzo (los ya horneados en sprites no cambian)&#10;try { const df = Object.getOwnPropertyDescriptor(CanvasRenderingContext2D.prototype, 'font');&#10;    if (df &amp;&amp; df.set) Object.defineProperty(ctx, 'font', { configurable: true, get() { return df.get.call(this); }, set(v) { if (TXT_ESCALA !== 1 &amp;&amp; typeof v === 'string') v = v.replace(\/(\\d+(?:\\.\\d+)?)px\/, (m, k) =&gt; (+k &gt;= 9 &amp;&amp; +k &lt; 20 ? Math.round(+k * TXT_ESCALA * 10) \/ 10 : k) + 'px'); df.set.call(this, v); } }); } catch (e) {}&#10;const _spritesTxt = new Map();&#10;let _PICT = null; try { _PICT = new RegExp('(\\\\p{Extended_Pictographic}\\\\uFE0F?)', 'u'); } catch (e) { _PICT = null; }&#10;let _EMOJI = null; try { _EMOJI = new RegExp('\\\\p{Emoji_Presentation}|\\\\uFE0F', 'u'); } catch (e) { _EMOJI = null; }&#10;if (typeof CanvasRenderingContext2D !== 'undefined' &amp;&amp; _EMOJI) {&#10;    const _fillText = CanvasRenderingContext2D.prototype.fillText;&#10;    CanvasRenderingContext2D.prototype.fillText = function (txt, x, y, maxW) {&#10;        if (maxW === undefined &amp;&amp; typeof txt === 'string' &amp;&amp; txt.length &lt;= 8 &amp;&amp; _EMOJI.test(txt)) {                       \/\/ solo emojis (a color: no dependen del fillStyle)&#10;            const font = this.font, base = this.textBaseline, key = font + '|' + base + '|' + txt;&#10;            let sp = _spritesTxt.get(key);&#10;            if (sp === undefined) {&#10;                const px = parseFloat((font.match(\/(\\d+(?:\\.\\d+)?)px\/) || [])[1]);&#10;                if (!px || _spritesTxt.size &gt; 300) sp = null;&#10;                else {&#10;                    const c = document.createElement('canvas'), g = c.getContext('2d'); g.font = font; const w = Math.ceil(g.measureText(txt).width), pad = Math.ceil(px * 0.35) + 2, H = Math.ceil(px * 2.2) + 2 * pad;&#10;                    c.width = w + 2 * pad; c.height = H; g.font = font; g.fillStyle = '#000'; g.textAlign = 'left'; g.textBaseline = base;&#10;                    const by = base === 'middle' ? H \/ 2 : (base === 'top' || base === 'hanging') ? pad : (base === 'bottom' || base === 'ideographic') ? H - pad : H * 0.65;&#10;                    _fillText.call(g, txt, pad, by); sp = { c, w, pad, by };&#10;                }&#10;                _spritesTxt.set(key, sp);&#10;            }&#10;            if (sp) { const al = this.textAlign, dx = al === 'center' ? -sp.w \/ 2 : (al === 'right' || al === 'end') ? -sp.w : 0; this.drawImage(sp.c, x + dx - sp.pad, y - sp.by); return; }&#10;        }&#10;        if (maxW === undefined &amp;&amp; _PICT &amp;&amp; typeof txt === 'string' &amp;&amp; txt.length &gt; 2 &amp;&amp; txt.indexOf('\\uFE0F') &gt;= 0 &amp;&amp; (this.textAlign === 'center' || this.textAlign === 'right' || this.textAlign === 'end')) {   \/\/ Safari descentra el texto con emojis VS16: lo alineamos a mano&#10;            const partes = txt.split(_PICT).filter(Boolean), al = this.textAlign, an = partes.map(q =&gt; this.measureText(q).width), tot = an.reduce((a, b) =&gt; a + b, 0); let cx = al === 'center' ? x - tot \/ 2 : x - tot;&#10;            this.textAlign = 'left'; partes.forEach((q, i) =&gt; { this.fillText(q, cx, y); cx += an[i]; }); this.textAlign = al; return;&#10;        }&#10;        return maxW === undefined ? _fillText.call(this, txt, x, y) : _fillText.call(this, txt, x, y, maxW);&#10;    };&#10;}&#10;const _spritesBrillo = {};&#10;function resplandor(x, y, r, rgb, a = 1) {                                   \/\/ halo suave: sustituye a shadowBlur, muy caro en Safari&#10;    let c = _spritesBrillo[rgb];&#10;    if (!c) { c = document.createElement('canvas'); c.width = c.height = 64; const g = c.getContext('2d'), gr = g.createRadialGradient(32, 32, 0, 32, 32, 32);&#10;        gr.addColorStop(0, `rgba(${rgb},1)`); gr.addColorStop(0.35, `rgba(${rgb},0.45)`); gr.addColorStop(1, `rgba(${rgb},0)`); g.fillStyle = gr; g.fillRect(0, 0, 64, 64); _spritesBrillo[rgb] = c; }&#10;    const ga = ctx.globalAlpha; ctx.globalAlpha = ga * a; ctx.drawImage(c, x - r, y - r, r * 2, r * 2); ctx.globalAlpha = ga;&#10;}&#10;const PIEZAS = [];&#10;function conLienzo(w, h, fn) {   \/\/ pre-dibuja una pieza est\u00e1tica en su propio lienzo (se intercambia ctx un instante); se recuerda para repintarla si cambia el idioma&#10;    const c = document.createElement('canvas'); c.width = w; c.height = h; pintarPieza(c, fn);&#10;    PIEZAS.push({ c, fn }); if (PIEZAS.length &gt; 500) PIEZAS.shift(); return c;&#10;}&#10;function pintarPieza(c, fn) { const previo = ctx; try { ctx = c.getContext('2d'); fn(); } catch (e) {} finally { ctx = previo; } }&#10;function repintarPiezas() { PIEZAS.forEach(q =&gt; { q.c.width = q.c.width; pintarPieza(q.c, q.fn); }); }&#10;let _sprSombra = null;&#10;function spriteSombra() {&#10;    if (!_sprSombra) { const c = document.createElement('canvas'); c.width = c.height = 256; const g = c.getContext('2d'), gr = g.createRadialGradient(128, 128, 128 * 0.15, 128, 128, 128); gr.addColorStop(0, 'rgba(0,0,0,1)'); gr.addColorStop(1, 'rgba(0,0,0,0)'); g.fillStyle = gr; g.fillRect(0, 0, 256, 256); _sprSombra = c; }&#10;    return _sprSombra;&#10;}&#10;const _spritesFlor = {};&#10;function spriteFlor(color) {&#10;    let c = _spritesFlor[color];&#10;    if (!c) { c = document.createElement('canvas'); c.width = c.height = 24; const g = c.getContext('2d'); g.translate(12, 12); g.fillStyle = color;&#10;        for (let i = 0; i &lt; 5; i++) { const ang = (i \/ 5) * Math.PI * 2; g.beginPath(); g.ellipse(Math.cos(ang) * 5, Math.sin(ang) * 5, 3.5, 2.2, ang, 0, Math.PI * 2); g.fill(); }&#10;        g.fillStyle = &quot;#f7d94c&quot;; g.beginPath(); g.arc(0, 0, 2.5, 0, Math.PI * 2); g.fill(); _spritesFlor[color] = c; }&#10;    return c;&#10;}&#10;let climaPlaya = 'parcial';&#10;let climaSinSol = false;   \/\/ el tiempo real tapa el sol dibujado cuando llueve, nieva o est\u00e1 muy nublado&#10;let audioCtx = null, masterGain = null, percusionGain = null;&#10;let audioIniciado = false, silenciado = false;&#10;let bufferRuidoTxalaparta = null;&#10;let zonaAltavoz = { x: 0, y: 24, radio: 17 };&#10;const PATRONES_TTAKUN_DIA = [&#10;    [&#10;        { agudo: true,  vol: 0.40 }, null,                        { agudo: false, vol: 0.22 }, { agudo: true, vol: 0.26 },&#10;        null,                        { agudo: true,  vol: 0.38 }, { agudo: false, vol: 0.20 }, null,&#10;        { agudo: true,  vol: 0.34 }, { agudo: false, vol: 0.36 }, null,                        { agudo: true, vol: 0.22 },&#10;        { agudo: false, vol: 0.30 }, null,                        { agudo: true,  vol: 0.38 }, null&#10;    ],&#10;    [&#10;        { agudo: false, vol: 0.36 }, { agudo: true, vol: 0.20 },  null,                        { agudo: false, vol: 0.24 },&#10;        { agudo: true,  vol: 0.34 }, null,                        { agudo: false, vol: 0.20 },  { agudo: true, vol: 0.30 },&#10;        null,                        { agudo: false, vol: 0.38 }, { agudo: true, vol: 0.20 },   null,&#10;        { agudo: false, vol: 0.22 }, { agudo: true,  vol: 0.34 }, null,                         { agudo: true, vol: 0.18 }&#10;    ]&#10;];&#10;const PATRONES_HERRENA_DIA = [&#10;    [&#10;        { agudo: true,  vol: 0.42 }, { agudo: false, vol: 0.24 }, { agudo: true, vol: 0.22 },  null,&#10;        { agudo: true,  vol: 0.38 }, null,                        null,                        { agudo: false, vol: 0.30 },&#10;        { agudo: true,  vol: 0.34 }, { agudo: false, vol: 0.20 }, null,                        { agudo: true, vol: 0.28 },&#10;        null,                        { agudo: false, vol: 0.38 }, { agudo: true, vol: 0.22 },  null&#10;    ],&#10;    [&#10;        { agudo: false, vol: 0.32 }, null,                        { agudo: true, vol: 0.40 },  { agudo: false, vol: 0.20 },&#10;        null,                        { agudo: true, vol: 0.26 },  null,                        { agudo: true, vol: 0.34 },&#10;        { agudo: false, vol: 0.22 }, null,                        null,                        { agudo: true, vol: 0.38 },&#10;        { agudo: false, vol: 0.28 }, { agudo: false, vol: 0.18 }, null,                        { agudo: true, vol: 0.26 }&#10;    ]&#10;];&#10;const PATRONES_TTAKUN_NOCHE = [&#10;    [&#10;        { agudo: false, vol: 0.18 }, null, null, { agudo: true, vol: 0.14 },&#10;        null, null,                  { agudo: false, vol: 0.17 }, null,&#10;        null, { agudo: true, vol: 0.13 }, null, null,&#10;        { agudo: false, vol: 0.17 }, null, null, null&#10;    ]&#10;];&#10;const PATRONES_HERRENA_NOCHE = [&#10;    [&#10;        { agudo: true, vol: 0.17 }, { agudo: false, vol: 0.11 }, null, null,&#10;        null, { agudo: true, vol: 0.16 }, null, null,&#10;        { agudo: false, vol: 0.14 }, null, null, { agudo: false, vol: 0.10 },&#10;        null, null, { agudo: true, vol: 0.13 }, null&#10;    ]&#10;];&#10;let modoTxalaparta = 'ttakun';&#10;let patronActual = PATRONES_TTAKUN_DIA[0];&#10;let pasoFraseActual = 0;&#10;let duracionFraseActual = 64;&#10;function elegirNuevaFrase() {&#10;    const dia = esDeDia();&#10;    modoTxalaparta = Math.random() &lt; 0.55 ? 'ttakun' : 'herrena';&#10;    const conjunto = dia&#10;        ? (modoTxalaparta === 'ttakun' ? PATRONES_TTAKUN_DIA : PATRONES_HERRENA_DIA)&#10;        : (modoTxalaparta === 'ttakun' ? PATRONES_TTAKUN_NOCHE : PATRONES_HERRENA_NOCHE);&#10;    patronActual = conjunto[Math.floor(Math.random() * conjunto.length)];&#10;    duracionFraseActual = (dia ? 36 : 26) + Math.floor(Math.random() * (dia ? 32 : 24));&#10;    pasoFraseActual = 0;&#10;}&#10;function multiplicadorTempoFrase() {&#10;    const progreso = pasoFraseActual \/ duracionFraseActual;&#10;    const ola = Math.sin(Math.pow(progreso, 0.72) * Math.PI); \/\/ 0 \u2192 1 \u2192 0, subida r\u00e1pida&#10;    const amplitud = modoTxalaparta === 'herrena' ? 0.60 : 0.42;&#10;    return 1 + ola * amplitud;&#10;}&#10;function crearBufferRuido(duracion) {&#10;    const tamano = Math.floor(audioCtx.sampleRate * duracion);&#10;    const buffer = audioCtx.createBuffer(1, tamano, audioCtx.sampleRate);&#10;    const datos = buffer.getChannelData(0);&#10;    for (let i = 0; i &lt; tamano; i++) datos[i] = Math.random() * 2 - 1;&#10;    return buffer;&#10;}&#10;function golpeTxalaparta(cuando, agudo, volumen) {&#10;    const fResonancia = agudo ? 780 : 420;&#10;    const osc = audioCtx.createOscillator();&#10;    osc.type = 'triangle';&#10;    osc.frequency.setValueAtTime(fResonancia, cuando);&#10;    osc.frequency.exponentialRampToValueAtTime(fResonancia * 0.94, cuando + 0.045);&#10;    const filtroMadera = audioCtx.createBiquadFilter();&#10;    filtroMadera.type = 'bandpass';&#10;    filtroMadera.frequency.value = fResonancia;&#10;    filtroMadera.Q.value = 7; \/\/ estrecho y resonante: timbre de madera, no de sirena&#10;    const g = audioCtx.createGain();&#10;    g.gain.setValueAtTime(0.0001, cuando);&#10;    g.gain.exponentialRampToValueAtTime(Math.max(volumen, 0.001), cuando + 0.0015); \/\/ ataque casi instant\u00e1neo&#10;    g.gain.exponentialRampToValueAtTime(0.0001, cuando + 0.05); \/\/ ca\u00edda corta y seca, sin cola sostenida&#10;    osc.connect(filtroMadera);&#10;    filtroMadera.connect(g);&#10;    g.connect(percusionGain);&#10;    osc.start(cuando);&#10;    osc.stop(cuando + 0.07);&#10;    const ruido = audioCtx.createBufferSource();&#10;    ruido.buffer = bufferRuidoTxalaparta;&#10;    const filtroClic = audioCtx.createBiquadFilter();&#10;    filtroClic.type = 'highpass';&#10;    filtroClic.frequency.value = 2800;&#10;    const gClic = audioCtx.createGain();&#10;    gClic.gain.setValueAtTime(volumen * 0.6, cuando);&#10;    gClic.gain.exponentialRampToValueAtTime(0.0001, cuando + 0.01);&#10;    ruido.connect(filtroClic);&#10;    filtroClic.connect(gClic);&#10;    gClic.connect(percusionGain);&#10;    ruido.start(cuando);&#10;    ruido.stop(cuando + 0.018);&#10;}&#10;let indicePatronTxalaparta = 0, siguienteGolpeTiempo = 0, temporizadorSecuenciador = null;&#10;const AVISO_PREVIO = 0.12, INTERVALO_COMPROBACION = 25;&#10;function avanzarPaso() {&#10;    const bpmBase = esDeDia() ? 188 : 82; \/\/ de d\u00eda, vivo y r\u00e1pido; de noche, pausado&#10;    const bpm = bpmBase * multiplicadorTempoFrase();&#10;    const duracionPaso = 60 \/ bpm \/ 2; \/\/ dieciseisavos&#10;    siguienteGolpeTiempo += duracionPaso;&#10;    indicePatronTxalaparta = (indicePatronTxalaparta + 1) % 16;&#10;    pasoFraseActual++;&#10;    if (pasoFraseActual &gt;= duracionFraseActual) elegirNuevaFrase();&#10;}&#10;function programarGolpes() {&#10;    while (siguienteGolpeTiempo &lt; audioCtx.currentTime + AVISO_PREVIO) {&#10;        const paso = patronActual[indicePatronTxalaparta];&#10;        if (paso) {&#10;            const jitter = 0.92 + Math.random() * 0.16;&#10;            golpeTxalaparta(siguienteGolpeTiempo, paso.agudo, paso.vol * jitter);&#10;        }&#10;        avanzarPaso();&#10;    }&#10;}&#10;function iniciarAudio() {&#10;    if (audioIniciado) return;&#10;    audioIniciado = true;&#10;    audioCtx = new (window.AudioContext || window.webkitAudioContext)();&#10;    if (audioCtx.state === 'suspended') audioCtx.resume().catch(() =&gt; {});&#10;    masterGain = audioCtx.createGain();&#10;    masterGain.gain.value = silenciado ? 0 : 0.5;&#10;    masterGain.connect(audioCtx.destination);&#10;    percusionGain = audioCtx.createGain();&#10;    percusionGain.gain.value = 0;                       \/\/ la txalaparta es una emisora m\u00e1s: la radio la enciende (y apaga) cuando toca&#10;    percusionGain.connect(masterGain);&#10;    bufferRuidoTxalaparta = crearBufferRuido(0.05);&#10;    if (typeof Radio !== 'undefined') Radio.ahora();    \/\/ sintoniza ya la emisora que corresponde (sin esperar al siguiente segundo)&#10;}&#10;function alternarSilencio() {&#10;    silenciado = !silenciado;&#10;    if (!audioCtx || !masterGain) return;&#10;    const ahora = audioCtx.currentTime;&#10;    masterGain.gain.cancelScheduledValues(ahora);&#10;    masterGain.gain.setValueAtTime(masterGain.gain.value, ahora);&#10;    if (silenciado) {&#10;        masterGain.gain.linearRampToValueAtTime(0, ahora + 0.2);&#10;        setTimeout(() =&gt; { if (silenciado &amp;&amp; audioCtx) audioCtx.suspend().catch(() =&gt; {}); }, 260);          \/\/ silencio total: se para todo el audio&#10;    } else {&#10;        audioCtx.resume().catch(() =&gt; {});                                                                      \/\/ dentro del gesto del usuario (iOS)&#10;        masterGain.gain.linearRampToValueAtTime(0.5, ahora + 0.4);&#10;    }&#10;}&#10;function alternarSonido() {&#10;    if (!audioIniciado) {                                \/\/ si se entr\u00f3 \u00absin sonido\u00bb, el altavoz es quien lo activa&#10;        silenciado = false;&#10;        iniciarAudio();&#10;        return;&#10;    }&#10;    alternarSilencio();&#10;}&#10;document.addEventListener('pointerdown', () =&gt; {&#10;    if (silenciado) return;&#10;    if (!audioIniciado) iniciarAudio();&#10;    else if (audioCtx.state === 'suspended') audioCtx.resume();&#10;}, { once: true });&#10;const CIELO_ALTO = 150;&#10;const SUELO_Y = CIELO_ALTO;&#10;const PARQUE_MIN = 410, PARQUE_MAX = 600;&#10;const FUENTE_POS = { x: 592, y: SUELO_Y + 140 };&#10;const GIMNASIO_EDIFICIO = { x: 615, ancho: 85, alto: 95 };&#10;const BIBLIOTECA = { x: 450, ancho: 90, alto: 85 };&#10;const BIBLIOTECA_MESA = { x: BIBLIOTECA.x + BIBLIOTECA.ancho \/ 2, y: SUELO_Y + 85 };&#10;const BIBLIOTECA_ASIENTOS = [&#10;    { x: BIBLIOTECA_MESA.x - 16, y: BIBLIOTECA_MESA.y - 4 },&#10;    { x: BIBLIOTECA_MESA.x + 16, y: BIBLIOTECA_MESA.y - 4 }&#10;];&#10;let enHuerta = false;&#10;const CAMINO_HUERTA = {&#10;    xNear: BIBLIOTECA.x + BIBLIOTECA.ancho \/ 2, yNear: BIBLIOTECA_MESA.y + 17, anchoNear: 60,&#10;    xFar: BIBLIOTECA.x + BIBLIOTECA.ancho \/ 2,  yFar: 430,                    anchoFar: 22&#10;};&#10;const ZONA_ENTRADA_HUERTA = { x: CAMINO_HUERTA.xFar - 5, y: CAMINO_HUERTA.yFar - 26, radio: 18 };&#10;function dibujarCaminoHuerta() {&#10;    const c = CAMINO_HUERTA;&#10;    ctx.save();&#10;    ctx.fillStyle = &quot;#c9a06a&quot;;&#10;    ctx.beginPath();&#10;    ctx.moveTo(c.xNear - c.anchoNear \/ 2, c.yNear);&#10;    ctx.lineTo(c.xNear + c.anchoNear \/ 2, c.yNear);&#10;    ctx.lineTo(c.xFar + c.anchoFar \/ 2, c.yFar);&#10;    ctx.lineTo(c.xFar - c.anchoFar \/ 2, c.yFar);&#10;    ctx.closePath();&#10;    ctx.fill();&#10;    ctx.strokeStyle = &quot;#8a6a3e&quot;; ctx.lineWidth = 2;&#10;    ctx.beginPath(); ctx.moveTo(c.xNear - c.anchoNear \/ 2, c.yNear); ctx.lineTo(c.xFar - c.anchoFar \/ 2, c.yFar); ctx.stroke();&#10;    ctx.beginPath(); ctx.moveTo(c.xNear + c.anchoNear \/ 2, c.yNear); ctx.lineTo(c.xFar + c.anchoFar \/ 2, c.yFar); ctx.stroke();&#10;    ctx.strokeStyle = &quot;rgba(120,85,45,0.4)&quot;; ctx.lineWidth = 1.5;&#10;    for (let f = 0.25; f &lt; 1; f += 0.25) {&#10;        const ay = c.yNear + (c.yFar - c.yNear) * f;&#10;        const aw = (c.anchoNear + (c.anchoFar - c.anchoNear) * f) \/ 2;&#10;        ctx.beginPath(); ctx.moveTo(c.xFar - aw, ay); ctx.lineTo(c.xFar + aw, ay); ctx.stroke();&#10;    }&#10;    const z = ZONA_ENTRADA_HUERTA;&#10;    ctx.fillStyle = &quot;rgba(255,255,255,0.88)&quot;;&#10;    ctx.strokeStyle = &quot;#3a7d44&quot;; ctx.lineWidth = 2.5;&#10;    ctx.beginPath();&#10;    ctx.arc(z.x, z.y, z.radio, 0, Math.PI * 2);&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.font = &quot;20px Arial&quot;;&#10;    ctx.textAlign = &quot;center&quot;; ctx.textBaseline = &quot;middle&quot;;&#10;    ctx.fillText(&quot;\ud83c\udf31&quot;, z.x, z.y + 1);&#10;    ctx.textBaseline = &quot;alphabetic&quot;;&#10;    ctx.restore();&#10;}&#10;function yDeCalle(x) {&#10;    return (x &gt; PARQUE_MIN &amp;&amp; x &lt; PARQUE_MAX) ? SUELO_Y + 165 : SUELO_Y + 100;&#10;}&#10;let rostro = null;      \/\/ \u00e1nimo de la chica que se est\u00e1 dibujando: dormida, enamorada, curiosa, leyendo, feliz (null = sereno)&#10;function dibujarCara(modo, colorPelo, esDerecha) {&#10;    let semilla = 0; for (let i = 0; i &lt; colorPelo.length; i++) semilla += colorPelo.charCodeAt(i);&#10;    const parpadea = ((t + semilla * 37) % 230) &lt; 7;&#10;    const mira = (esDerecha ? -1 : 1) * 0.7, baja = modo === 'leyendo' ? 1.2 : 0;&#10;    ctx.save(); ctx.lineCap = 'round'; ctx.lineJoin = 'round';&#10;    ctx.fillStyle = `rgba(255,120,150,${modo === 'enamorada' ? 0.6 : 0.32})`;&#10;    [-9.5, 9.5].forEach(x =&gt; { ctx.beginPath(); ctx.ellipse(x, 2, 3.4, 2.1, 0, 0, Math.PI * 2); ctx.fill(); });&#10;    ctx.strokeStyle = &quot;#2a1a18&quot;; ctx.lineWidth = 1.3;&#10;    const ce = modo === 'curiosa' ? -2.4 : modo === 'enamorada' ? -0.8 : 0;&#10;    [-1, 1].forEach(d =&gt; { ctx.beginPath(); ctx.moveTo(d * 8.2, -10 + ce + (modo === 'curiosa' ? 0 : 0.6)); ctx.quadraticCurveTo(d * 5.4, -11.8 + ce, d * 2.8, -10.2 + ce + (modo === 'curiosa' ? 0.8 : 0)); ctx.stroke(); });&#10;    if (modo === 'dormida' || parpadea) {&#10;        ctx.lineWidth = 1.6;&#10;        [-5, 5].forEach(x =&gt; { ctx.beginPath(); ctx.arc(x, modo === 'dormida' ? -5.6 : -5, 2.7, 0.15 * Math.PI, 0.85 * Math.PI); ctx.stroke(); });&#10;        [-1, 1].forEach(d =&gt; { ctx.beginPath(); ctx.moveTo(d * 7.6, -4.4); ctx.lineTo(d * 9.2, -3.2); ctx.stroke(); });&#10;    } else if (modo === 'enamorada') {&#10;        ctx.fillStyle = &quot;#ff3b6b&quot;;&#10;        [-5, 5].forEach(x =&gt; { const l = 1 + 0.12 * Math.sin(t \/ 5); ctx.save(); ctx.translate(x, -5); ctx.scale(l, l); ctx.beginPath(); ctx.moveTo(0, 2.6); ctx.bezierCurveTo(-4.6, -0.6, -2.4, -4, 0, -1.6); ctx.bezierCurveTo(2.4, -4, 4.6, -0.6, 0, 2.6); ctx.fill(); ctx.restore(); });&#10;    } else {&#10;        const rx = modo === 'curiosa' ? 3.3 : 2.9, ry = modo === 'curiosa' ? 4 : 3.4;&#10;        [-5, 5].forEach(x =&gt; {&#10;            ctx.fillStyle = &quot;#fff&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 1;&#10;            ctx.beginPath(); ctx.ellipse(x, -5, rx, ry, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;            const ig = ctx.createRadialGradient(x + mira - 0.6, -5 + baja - 0.8, 0.2, x + mira, -5 + baja, 2.4);&#10;            ig.addColorStop(0, &quot;#6b4a35&quot;); ig.addColorStop(1, &quot;#1a0f0a&quot;);&#10;            ctx.fillStyle = ig; ctx.beginPath(); ctx.arc(x + mira, -5 + baja, 2.1, 0, Math.PI * 2); ctx.fill();&#10;            ctx.fillStyle = &quot;#fff&quot;; ctx.beginPath(); ctx.arc(x + mira + 0.8, -6 + baja, 0.8, 0, Math.PI * 2); ctx.fill();&#10;        });&#10;        ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 1.3;                              \/\/ pesta\u00f1as&#10;        [-1, 1].forEach(d =&gt; { ctx.beginPath(); ctx.moveTo(d * 7.6, -6.4); ctx.lineTo(d * 9.4, -7.8); ctx.stroke(); ctx.beginPath(); ctx.moveTo(d * 7.9, -4.8); ctx.lineTo(d * 9.8, -5.2); ctx.stroke(); });&#10;    }&#10;    ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 1.5; ctx.fillStyle = &quot;#c2273f&quot;;&#10;    if (modo === 'feliz' || modo === 'enamorada') {&#10;        ctx.beginPath(); ctx.moveTo(-4.4, 4.4); ctx.quadraticCurveTo(0, 10.8, 4.4, 4.4); ctx.closePath(); ctx.fill(); ctx.stroke();&#10;        ctx.fillStyle = &quot;#ff8fa3&quot;; ctx.beginPath(); ctx.ellipse(0, 7, 1.8, 1, 0, 0, Math.PI * 2); ctx.fill();&#10;    } else if (modo === 'curiosa') {&#10;        ctx.beginPath(); ctx.ellipse(0, 6, 1.7, 2.2, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    } else if (modo === 'dormida') {&#10;        ctx.beginPath(); ctx.ellipse(0, 6, 1.5, 1.1, 0, 0, Math.PI * 2); ctx.stroke();&#10;    } else if (modo === 'leyendo') {&#10;        ctx.beginPath(); ctx.moveTo(-2.6, 5.6); ctx.quadraticCurveTo(0, 6.6, 2.6, 5.6); ctx.stroke();&#10;    } else {&#10;        ctx.beginPath(); ctx.moveTo(-4, 4.6); ctx.quadraticCurveTo(0, 8.4, 4, 4.6); ctx.stroke();&#10;    }&#10;    ctx.restore();&#10;}&#10;function dibujarMu\u00f1eca(p, colorPelo, estaCerca, esDerecha, esEnemiga = false, estiloPelo = 'largo') {&#10;    ctx.save();&#10;    ctx.translate(p.x, p.y);&#10;    ctx.rotate(p.angulo || 0);&#10;    ctx.lineWidth = 3; ctx.strokeStyle = esEnemiga ? &quot;#4B0082&quot; : &quot;#000&quot;;&#10;    ctx.beginPath();&#10;    if (estaCerca &amp;&amp; !esEnemiga) {&#10;        ctx.moveTo((esDerecha ? -10 : 10), 5);&#10;        ctx.lineTo((esDerecha ? -35 : 35), 0);&#10;    } else {&#10;        ctx.moveTo(-12, 5); ctx.lineTo(-15, 25);&#10;        ctx.moveTo(12, 5); ctx.lineTo(15, 25);&#10;    }&#10;    ctx.stroke();&#10;    ctx.fillStyle = esEnemiga ? &quot;#E6E6FA&quot; : &quot;#fff&quot;;&#10;    ctx.beginPath(); ctx.ellipse(0, 0, 15, 25, 0, 0, Math.PI*2); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = colorPelo;&#10;    if (estiloPelo === 'pincho') {&#10;        ctx.beginPath();&#10;        ctx.moveTo(-18, -8);&#10;        ctx.quadraticCurveTo(0, -18, 18, -8);&#10;        ctx.lineTo(20, 6);&#10;        ctx.quadraticCurveTo(0, -4, -20, 6);&#10;        ctx.closePath();&#10;        ctx.fill(); ctx.stroke();&#10;        for (let i = -3; i &lt;= 3; i++) {&#10;            const sx = i * 6;&#10;            const largo = 14 - Math.abs(sx) * 0.5;&#10;            ctx.beginPath();&#10;            ctx.moveTo(sx - 4, -10);&#10;            ctx.lineTo(sx, -10 - largo);&#10;            ctx.lineTo(sx + 4, -10);&#10;            ctx.closePath();&#10;            ctx.fill(); ctx.stroke();&#10;        }&#10;    } else if (estiloPelo === 'mohawk') {&#10;        ctx.beginPath();&#10;        ctx.moveTo(-16, -6);&#10;        ctx.quadraticCurveTo(-18, -2, -15, 6);&#10;        ctx.lineTo(-9, -6);&#10;        ctx.closePath();&#10;        ctx.fill(); ctx.stroke();&#10;        ctx.beginPath();&#10;        ctx.moveTo(16, -6);&#10;        ctx.quadraticCurveTo(18, -2, 15, 6);&#10;        ctx.lineTo(9, -6);&#10;        ctx.closePath();&#10;        ctx.fill(); ctx.stroke();&#10;        [-5, 0, 5].forEach((sx, i) =&gt; {&#10;            const alto = i === 1 ? 30 : 22;&#10;            ctx.beginPath();&#10;            ctx.moveTo(sx - 3, -8);&#10;            ctx.lineTo(sx, -8 - alto);&#10;            ctx.lineTo(sx + 3, -8);&#10;            ctx.closePath();&#10;            ctx.fill(); ctx.stroke();&#10;        });&#10;    } else if (estiloPelo === 'coletas') {   \/\/ dos coletas altas con gomas&#10;        ctx.beginPath(); ctx.moveTo(-17, -4); ctx.bezierCurveTo(-16, -30, 16, -30, 17, -4); ctx.quadraticCurveTo(0, -12, -17, -4); ctx.fill(); ctx.stroke();&#10;        [-1, 1].forEach(q =&gt; { ctx.beginPath(); ctx.moveTo(q * 15, -16); ctx.bezierCurveTo(q * 34, -20, q * 36, 4, q * 26, 18); ctx.bezierCurveTo(q * 24, 4, q * 22, -6, q * 15, -10); ctx.closePath(); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#fff'; ctx.beginPath(); ctx.arc(q * 16, -14, 2.6, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.fillStyle = colorPelo; });&#10;    } else if (estiloPelo === 'rizos') {   \/\/ mo\u00f1o de rizos&#10;        ctx.beginPath(); ctx.moveTo(-17, -4); ctx.bezierCurveTo(-18, -28, 18, -28, 17, -4); ctx.quadraticCurveTo(0, -11, -17, -4); ctx.fill(); ctx.stroke();&#10;        [[-8, -30, 8], [0, -36, 9], [8, -30, 8], [-13, -22, 6], [13, -22, 6]].forEach(r =&gt; { ctx.beginPath(); ctx.arc(r[0], r[1], r[2], 0, Math.PI * 2); ctx.fill(); ctx.stroke(); });&#10;    } else {&#10;        ctx.beginPath(); ctx.moveTo(-20, -10);&#10;        ctx.bezierCurveTo(-30, -45, 30, -45, 20, -10);&#10;        ctx.lineTo(25, 10); ctx.bezierCurveTo(30, -20, -30, -20, -25, 10);&#10;        ctx.fill(); ctx.stroke();&#10;    }&#10;    dibujarCara(esEnemiga ? null : (p.rostro || rostro), colorPelo, esDerecha);&#10;    ctx.restore();&#10;}&#10;function dibujarEdificioGimnasio(g) {&#10;    const x = g.x, y = SUELO_Y + 55, ancho = g.ancho, alto = g.alto;&#10;    const grad = ctx.createLinearGradient(x, y - alto, x + ancho, y);&#10;    grad.addColorStop(0, &quot;#c3c8ce&quot;);&#10;    grad.addColorStop(1, &quot;#8d939b&quot;);&#10;    ctx.fillStyle = grad;&#10;    ctx.strokeStyle = &quot;#3f4550&quot;; ctx.lineWidth = 3;&#10;    ctx.fillRect(x, y - alto, ancho, alto);&#10;    ctx.strokeRect(x, y - alto, ancho, alto);&#10;    ctx.fillStyle = &quot;#4a4f57&quot;;&#10;    ctx.fillRect(x + ancho * 0.36, y - alto * 0.42, ancho * 0.28, alto * 0.42);&#10;    ctx.strokeRect(x + ancho * 0.36, y - alto * 0.42, ancho * 0.28, alto * 0.42);&#10;    const letreroY = y - alto - 26;&#10;    ctx.fillStyle = &quot;#d9dce0&quot;; ctx.strokeStyle = &quot;#3f4550&quot;; ctx.lineWidth = 2.5;&#10;    ctx.fillRect(x - 6, letreroY, ancho + 12, 26);&#10;    ctx.strokeRect(x - 6, letreroY, ancho + 12, 26);&#10;    ctx.fillStyle = &quot;#3f4550&quot;;&#10;    ctx.font = &quot;bold 12px 'Comic Sans MS', sans-serif&quot;;&#10;    ctx.textAlign = &quot;center&quot;;&#10;    ctx.fillText(&quot;GIMNASIO&quot;, x + ancho \/ 2, letreroY + 17);&#10;}&#10;function dibujarEdificioBiblioteca(b) {&#10;    const x = b.x, y = SUELO_Y + 55, ancho = b.ancho, alto = b.alto;&#10;    const grad = ctx.createLinearGradient(x, y - alto, x + ancho, y);&#10;    grad.addColorStop(0, &quot;#f0dfc0&quot;);&#10;    grad.addColorStop(1, &quot;#d8bf95&quot;);&#10;    ctx.fillStyle = grad;&#10;    ctx.strokeStyle = &quot;#7a5a34&quot;; ctx.lineWidth = 3;&#10;    ctx.fillRect(x, y - alto, ancho, alto);&#10;    ctx.strokeRect(x, y - alto, ancho, alto);&#10;    ctx.fillStyle = &quot;#c9a86a&quot;;&#10;    ctx.beginPath();&#10;    ctx.moveTo(x - 8, y - alto);&#10;    ctx.lineTo(x + ancho \/ 2, y - alto - ancho * 0.3);&#10;    ctx.lineTo(x + ancho + 8, y - alto);&#10;    ctx.closePath();&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#fff8ea&quot;; ctx.strokeStyle = &quot;#7a5a34&quot;; ctx.lineWidth = 2;&#10;    [0.18, 0.5, 0.82].forEach(f =&gt; {&#10;        ctx.fillRect(x + ancho * f - 5, y - alto * 0.85, 10, alto * 0.85);&#10;        ctx.strokeRect(x + ancho * f - 5, y - alto * 0.85, 10, alto * 0.85);&#10;    });&#10;    ctx.fillStyle = &quot;#5a3d1e&quot;;&#10;    ctx.beginPath();&#10;    ctx.moveTo(x + ancho \/ 2 - 13, y);&#10;    ctx.lineTo(x + ancho \/ 2 - 13, y - alto * 0.42);&#10;    ctx.quadraticCurveTo(x + ancho \/ 2, y - alto * 0.6, x + ancho \/ 2 + 13, y - alto * 0.42);&#10;    ctx.lineTo(x + ancho \/ 2 + 13, y);&#10;    ctx.closePath();&#10;    ctx.fill(); ctx.stroke();&#10;    const letreroY = y - alto - ancho * 0.3 - 24;&#10;    ctx.fillStyle = &quot;#fff5fa&quot;; ctx.strokeStyle = &quot;#6a3e8c&quot;; ctx.lineWidth = 2.5;&#10;    ctx.fillRect(x - 6, letreroY, ancho + 12, 24);&#10;    ctx.strokeRect(x - 6, letreroY, ancho + 12, 24);&#10;    ctx.font = &quot;14px Arial&quot;;&#10;    ctx.textAlign = &quot;center&quot;;&#10;    ctx.fillText(&quot;\ud83d\udcd6&quot;, x + 16, letreroY + 17);&#10;    ctx.fillStyle = &quot;#6a3e8c&quot;;&#10;    ctx.font = &quot;bold 11px 'Comic Sans MS', sans-serif&quot;;&#10;    ctx.fillText(&quot;BIBLIOTECA&quot;, x + ancho \/ 2 + 8, letreroY + 16);&#10;}&#10;function dibujarMesaLectura(x, y) {&#10;    ctx.fillStyle = &quot;#8a5a2b&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    ctx.beginPath(); ctx.ellipse(x, y, 20, 8, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.fillRect(x - 3, y, 6, 10);&#10;    ctx.save();&#10;    ctx.translate(x, y - 4);&#10;    ctx.rotate(-0.15);&#10;    ctx.fillStyle = &quot;#e85fb0&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 1.5;&#10;    ctx.fillRect(-9, -6, 18, 12);&#10;    ctx.strokeRect(-9, -6, 18, 12);&#10;    ctx.strokeStyle = &quot;#fff&quot;; ctx.lineWidth = 1;&#10;    ctx.beginPath(); ctx.moveTo(0, -6); ctx.lineTo(0, 6); ctx.stroke();&#10;    ctx.restore();&#10;}&#10;function dibujarCasa(x, y, ancho, alto, colorPared, colorTejado, iluminada, nevando) {&#10;    ctx.fillStyle = colorPared;&#10;    ctx.strokeStyle = &quot;#000&quot;;&#10;    ctx.lineWidth = 2.5;&#10;    ctx.fillRect(x, y - alto, ancho, alto);&#10;    ctx.strokeRect(x, y - alto, ancho, alto);&#10;    ctx.fillStyle = colorTejado;&#10;    ctx.beginPath();&#10;    ctx.moveTo(x - 10, y - alto);&#10;    ctx.lineTo(x + ancho \/ 2, y - alto - ancho * 0.45);&#10;    ctx.lineTo(x + ancho + 10, y - alto);&#10;    ctx.closePath();&#10;    ctx.fill(); ctx.stroke();&#10;    if (nevando) {&#10;        ctx.fillStyle = &quot;#ffffff&quot;; ctx.strokeStyle = &quot;#dfe8ee&quot;; ctx.lineWidth = 1;&#10;        ctx.beginPath();&#10;        ctx.moveTo(x - 10, y - alto);&#10;        ctx.lineTo(x + ancho \/ 2, y - alto - ancho * 0.45);&#10;        ctx.lineTo(x + ancho + 10, y - alto);&#10;        ctx.lineTo(x + ancho * 0.75, y - alto - ancho * 0.06);&#10;        ctx.lineTo(x + ancho \/ 2, y - alto - ancho * 0.32);&#10;        ctx.lineTo(x + ancho * 0.25, y - alto - ancho * 0.06);&#10;        ctx.closePath();&#10;        ctx.fill();&#10;    }&#10;    ctx.save();&#10;    const cresta = { x: x + ancho \/ 2, y: y - alto - ancho * 0.45 };&#10;    const faldon = { x: x + ancho + 10, y: y - alto };&#10;    const anguloTejado = Math.atan2(faldon.y - cresta.y, faldon.x - cresta.x);&#10;    const placaX = cresta.x + (faldon.x - cresta.x) * 0.28;&#10;    const placaY = cresta.y + (faldon.y - cresta.y) * 0.28;&#10;    ctx.translate(placaX, placaY);&#10;    ctx.rotate(anguloTejado);&#10;    const placaAncho = ancho * 0.34, placaAlto = ancho * 0.16;&#10;    ctx.fillStyle = &quot;#2a3a55&quot;; ctx.strokeStyle = &quot;#0a1420&quot;; ctx.lineWidth = 1.5;&#10;    ctx.fillRect(-placaAncho \/ 2, 0, placaAncho, placaAlto);&#10;    ctx.strokeRect(-placaAncho \/ 2, 0, placaAncho, placaAlto);&#10;    ctx.strokeStyle = &quot;#4a6a95&quot;; ctx.lineWidth = 1;&#10;    for (let i = 1; i &lt; 4; i++) {&#10;        ctx.beginPath();&#10;        ctx.moveTo(-placaAncho \/ 2 + (placaAncho \/ 4) * i, 0);&#10;        ctx.lineTo(-placaAncho \/ 2 + (placaAncho \/ 4) * i, placaAlto);&#10;        ctx.stroke();&#10;    }&#10;    ctx.beginPath();&#10;    ctx.moveTo(-placaAncho \/ 2, placaAlto \/ 2);&#10;    ctx.lineTo(placaAncho \/ 2, placaAlto \/ 2);&#10;    ctx.stroke();&#10;    ctx.restore();&#10;    const puertaAncho = ancho * 0.22;&#10;    const puertaAlto = alto * 0.5;&#10;    ctx.fillStyle = &quot;#7a4a2b&quot;;&#10;    ctx.fillRect(x + ancho\/2 - puertaAncho\/2, y - puertaAlto, puertaAncho, puertaAlto);&#10;    ctx.strokeRect(x + ancho\/2 - puertaAncho\/2, y - puertaAlto, puertaAncho, puertaAlto);&#10;    const ventanaLado = Math.min(ancho, alto) * 0.18;&#10;    ctx.fillStyle = iluminada ? &quot;#ffe08a&quot; : &quot;#cdeeff&quot;;&#10;    const ventanas = [&#10;        [x + ancho * 0.18, y - alto * 0.72],&#10;        [x + ancho * 0.82 - ventanaLado, y - alto * 0.72]&#10;    ];&#10;    ventanas.forEach(([vx, vy]) =&gt; {&#10;        ctx.fillRect(vx, vy, ventanaLado, ventanaLado);&#10;        ctx.strokeRect(vx, vy, ventanaLado, ventanaLado);&#10;        ctx.beginPath();&#10;        ctx.moveTo(vx + ventanaLado\/2, vy);&#10;        ctx.lineTo(vx + ventanaLado\/2, vy + ventanaLado);&#10;        ctx.moveTo(vx, vy + ventanaLado\/2);&#10;        ctx.lineTo(vx + ventanaLado, vy + ventanaLado\/2);&#10;        ctx.stroke();&#10;    });&#10;}&#10;function dibujarMolino(x, y, escala, t) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.scale(escala, escala);&#10;    ctx.fillStyle = &quot;#ffffff&quot;; ctx.strokeStyle = &quot;#333&quot;; ctx.lineWidth = 3;&#10;    ctx.beginPath();&#10;    ctx.moveTo(-9, 0); ctx.lineTo(9, 0); ctx.lineTo(3.5, -130); ctx.lineTo(-3.5, -130);&#10;    ctx.closePath();&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#e0e0e0&quot;; ctx.strokeStyle = &quot;#333&quot;; ctx.lineWidth = 2.5;&#10;    ctx.fillRect(-4, -138, 22, 11);&#10;    ctx.strokeRect(-4, -138, 22, 11);&#10;    ctx.save();&#10;    ctx.translate(12, -133);&#10;    ctx.rotate(t \/ 22);&#10;    ctx.fillStyle = &quot;#ffffff&quot;; ctx.strokeStyle = &quot;#333&quot;; ctx.lineWidth = 2.5;&#10;    for (let i = 0; i &lt; 3; i++) {&#10;        ctx.save();&#10;        ctx.rotate((i * Math.PI * 2) \/ 3);&#10;        ctx.beginPath();&#10;        ctx.moveTo(0, 0);&#10;        ctx.quadraticCurveTo(10, -32, 5, -72);&#10;        ctx.quadraticCurveTo(-3, -32, 0, 0);&#10;        ctx.closePath();&#10;        ctx.fill(); ctx.stroke();&#10;        ctx.restore();&#10;    }&#10;    ctx.beginPath(); ctx.arc(0, 0, 5, 0, Math.PI * 2); ctx.fillStyle = &quot;#555&quot;; ctx.fill();&#10;    ctx.restore();&#10;    ctx.restore();&#10;}&#10;function dibujarPatinete(x, y, angulo) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.rotate(angulo || 0);&#10;    ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2.5;&#10;    ctx.fillStyle = &quot;#333&quot;;&#10;    ctx.beginPath(); ctx.arc(-16, 8, 5, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.beginPath(); ctx.arc(16, 8, 5, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.strokeStyle = &quot;#000&quot;; ctx.fillStyle = &quot;#e85fb0&quot;;&#10;    ctx.beginPath();&#10;    ctx.moveTo(-18, 4); ctx.lineTo(18, 4); ctx.lineTo(16, -1); ctx.lineTo(-16, -1);&#10;    ctx.closePath(); ctx.fill(); ctx.stroke();&#10;    ctx.beginPath(); ctx.moveTo(14, -1); ctx.lineTo(14, -26); ctx.stroke();&#10;    ctx.beginPath(); ctx.moveTo(6, -26); ctx.lineTo(22, -26); ctx.stroke();&#10;    ctx.restore();&#10;}&#10;function copaFrutal(escala, colorFruta, estacion) {&#10;    if (estacion === 'invierno') {&#10;        ctx.strokeStyle = &quot;#6b4a2b&quot;; ctx.lineWidth = 2 * escala;&#10;        [[-10, -10], [10, -12], [0, -18], [-6, -4], [7, -3]].forEach(([bx, by]) =&gt; {&#10;            ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(bx * escala, by * escala); ctx.stroke();&#10;        });&#10;        ctx.fillStyle = &quot;#ffffff&quot;;&#10;        [[0, -12], [-10, -9], [10, -11], [-6, -3], [7, -2]].forEach(([nx, ny]) =&gt; {&#10;            ctx.beginPath(); ctx.arc(nx * escala, ny * escala, 4 * escala, 0, Math.PI * 2); ctx.fill();&#10;        });&#10;    } else {&#10;        ctx.fillStyle = estacion === 'oto\u00f1o' ? &quot;#c9822f&quot; : &quot;#5fae5f&quot;;&#10;        const copas = [[0, -12, 17], [-13, 0, 13], [13, 0, 13]];&#10;        copas.forEach(([dx, dy, r]) =&gt; {&#10;            ctx.beginPath();&#10;            ctx.arc(dx * escala, dy * escala, r * escala, 0, Math.PI * 2);&#10;            ctx.fill();&#10;        });&#10;        ctx.fillStyle = colorFruta;&#10;        const frutas = [[-8, -14], [8, -10], [-4, 2], [10, 4], [0, -20], [-14, 4]];&#10;        frutas.forEach(([fx, fy]) =&gt; {&#10;            ctx.beginPath();&#10;            ctx.arc(fx * escala, fy * escala, 3 * escala, 0, Math.PI * 2);&#10;            ctx.fill();&#10;        });&#10;    }&#10;}&#10;const _sprCopas = {};&#10;function spriteCopaFrutal(escala, colorFruta, estacion) {&#10;    const k = escala + '|' + colorFruta + '|' + estacion; let sp = _sprCopas[k];&#10;    if (!sp) { const ox = Math.ceil(30 * escala) + 4, oy = Math.ceil(32 * escala) + 4, c = conLienzo(2 * ox, oy + Math.ceil(17 * escala) + 4, () =&gt; { ctx.translate(ox, oy); copaFrutal(escala, colorFruta, estacion); }); sp = _sprCopas[k] = { c, ox, oy }; }&#10;    return sp;&#10;}&#10;function dibujarArbolFrutal(x, y, escala, t, fase, colorFruta, estacion) {&#10;    ctx.fillStyle = &quot;#8a5a2b&quot;;&#10;    ctx.fillRect(x - 4 * escala, y - 22 * escala, 8 * escala, 22 * escala);&#10;    const balanceo = Math.sin(t \/ 45 + fase) * 0.06;&#10;    ctx.save();&#10;    ctx.translate(x, y - 22 * escala);&#10;    ctx.rotate(balanceo);&#10;    const sp = spriteCopaFrutal(escala, colorFruta, estacion); ctx.drawImage(sp.c, -sp.ox, -sp.oy);          \/\/ copa y frutas: sprite (solo se mece)&#10;    ctx.restore();&#10;}&#10;function dibujarArbol(x, y, escala, t, fase, estacion) {&#10;    ctx.fillStyle = &quot;#8a5a2b&quot;;&#10;    ctx.fillRect(x - 4 * escala, y - 22 * escala, 8 * escala, 22 * escala);&#10;    const balanceo = Math.sin(t \/ 45 + fase) * 0.06;&#10;    ctx.save();&#10;    ctx.translate(x, y - 22 * escala);&#10;    ctx.rotate(balanceo);&#10;    if (estacion === 'invierno') {&#10;        ctx.strokeStyle = &quot;#6b4a2b&quot;; ctx.lineWidth = 2.5 * escala;&#10;        [[-14, -8], [14, -8], [0, -20], [-8, -3], [8, -3]].forEach(([bx, by]) =&gt; {&#10;            ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(bx * escala, by * escala); ctx.stroke();&#10;        });&#10;        ctx.fillStyle = &quot;#ffffff&quot;;&#10;        [[0, -14], [-14, -8], [14, -8], [-8, -2], [8, -2]].forEach(([nx, ny]) =&gt; {&#10;            ctx.beginPath(); ctx.arc(nx * escala, ny * escala, 5 * escala, 0, Math.PI * 2); ctx.fill();&#10;        });&#10;    } else if (estacion === 'oto\u00f1o') {&#10;        const coposOtono = [[0, -12, 18, &quot;#d97b29&quot;], [-14, 0, 14, &quot;#c94f2c&quot;], [14, 0, 14, &quot;#e0a63a&quot;]];&#10;        coposOtono.forEach(([dx, dy, r, color]) =&gt; {&#10;            ctx.fillStyle = color;&#10;            ctx.beginPath();&#10;            ctx.arc(dx * escala, dy * escala, r * escala, 0, Math.PI * 2);&#10;            ctx.fill();&#10;        });&#10;    } else {&#10;        ctx.fillStyle = estacion === 'primavera' ? &quot;#6fce6a&quot; : &quot;#5fae5f&quot;;&#10;        [[0, -12, 18], [-14, 0, 14], [14, 0, 14]].forEach(([dx, dy, r]) =&gt; {&#10;            ctx.beginPath();&#10;            ctx.arc(dx * escala, dy * escala, r * escala, 0, Math.PI * 2);&#10;            ctx.fill();&#10;        });&#10;        if (estacion === 'primavera') {&#10;            ctx.fillStyle = &quot;#ff9ec7&quot;;&#10;            [[-6, -16], [8, -8], [-10, 2], [6, 6]].forEach(([fx, fy]) =&gt; {&#10;                ctx.beginPath(); ctx.arc(fx * escala, fy * escala, 2.2 * escala, 0, Math.PI * 2); ctx.fill();&#10;            });&#10;        }&#10;    }&#10;    ctx.restore();&#10;}&#10;const hojasOtono = [];&#10;for (let i = 0; i &lt; 22; i++) {&#10;    hojasOtono.push({&#10;        x: Math.random() * 960,&#10;        fase: Math.random() * 300,&#10;        vel: 0.35 + Math.random() * 0.4,&#10;        deriva: 8 + Math.random() * 14,&#10;        color: [&quot;#d97b29&quot;, &quot;#c94f2c&quot;, &quot;#e0a63a&quot;][Math.floor(Math.random() * 3)]&#10;    });&#10;}&#10;function dibujarHojasOtono(t) {&#10;    hojasOtono.forEach(h =&gt; {&#10;        const ciclo = 300 \/ h.vel;&#10;        const progreso = ((t * h.vel + h.fase) % ciclo) \/ ciclo;&#10;        const y = CIELO_ALTO - 10 + progreso * (540 - CIELO_ALTO + 10);&#10;        const x = h.x + Math.sin(progreso * Math.PI * 4) * h.deriva;&#10;        ctx.save();&#10;        ctx.translate(x, y);&#10;        ctx.rotate(t \/ 20 + h.fase);&#10;        ctx.fillStyle = h.color;&#10;        ctx.beginPath();&#10;        ctx.ellipse(0, 0, 4, 2.4, 0, 0, Math.PI * 2);&#10;        ctx.fill();&#10;        ctx.restore();&#10;    });&#10;}&#10;function dibujarFlor(x, y, colorPetalo, t) {&#10;    const balanceo = Math.sin(t \/ 20 + x) * 6;&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.strokeStyle = &quot;#3f7d3f&quot;;&#10;    ctx.lineWidth = 2;&#10;    ctx.beginPath(); ctx.moveTo(0, 0); ctx.quadraticCurveTo(balanceo * 0.3, 5, balanceo, 10); ctx.stroke();&#10;    ctx.translate(balanceo, 10);&#10;    ctx.rotate(balanceo \/ 40);&#10;    ctx.drawImage(spriteFlor(colorPetalo), -12, -12);                    \/\/ p\u00e9talos y centro, como sprite&#10;    ctx.restore();&#10;}&#10;function dibujarBanco(x, y) {&#10;    ctx.fillStyle = &quot;#8a5a2b&quot;;&#10;    ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    ctx.fillRect(x, y - 18, 46, 6);&#10;    ctx.strokeRect(x, y - 18, 46, 6);&#10;    ctx.fillRect(x, y - 8, 46, 5);&#10;    ctx.strokeRect(x, y - 8, 46, 5);&#10;    ctx.fillRect(x + 3, y - 3, 4, 8);&#10;    ctx.fillRect(x + 39, y - 3, 4, 8);&#10;}&#10;const gotasFuente = [];&#10;for (let i = 0; i &lt; 18; i++) {&#10;    gotasFuente.push({ fase: Math.random() * 40, lado: (Math.random() - 0.5) * 2 });&#10;}&#10;const ondasFuente = [];&#10;function dibujarFuente(x, y, t) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    if (t % 25 === 0) ondasFuente.push({ r: 6, alpha: 0.5 });&#10;    for (let i = ondasFuente.length - 1; i &gt;= 0; i--) {&#10;        const o = ondasFuente[i];&#10;        ctx.save();&#10;        ctx.globalAlpha = o.alpha;&#10;        ctx.strokeStyle = &quot;#ffffff&quot;;&#10;        ctx.lineWidth = 1.5;&#10;        ctx.beginPath();&#10;        ctx.ellipse(0, -2, o.r, o.r * 0.32, 0, 0, Math.PI * 2);&#10;        ctx.stroke();&#10;        ctx.restore();&#10;        o.r += 0.6; o.alpha -= 0.012;&#10;        if (o.alpha &lt;= 0) ondasFuente.splice(i, 1);&#10;    }&#10;    ctx.fillStyle = &quot;#c9c9c9&quot;;&#10;    ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2.5;&#10;    ctx.beginPath();&#10;    ctx.ellipse(0, 0, 42, 16, 0, 0, Math.PI * 2);&#10;    ctx.fill(); ctx.stroke();&#10;    const brillo = ctx.createRadialGradient(0, -4, 4, 0, -2, 34);&#10;    brillo.addColorStop(0, &quot;#e6f7ff&quot;);&#10;    brillo.addColorStop(1, &quot;#8fcdf2&quot;);&#10;    ctx.fillStyle = brillo;&#10;    ctx.beginPath();&#10;    ctx.ellipse(0, -2, 34, 11, 0, 0, Math.PI * 2);&#10;    ctx.fill();&#10;    ctx.fillStyle = &quot;#c9c9c9&quot;;&#10;    ctx.fillRect(-6, -46, 12, 46);&#10;    ctx.strokeRect(-6, -46, 12, 46);&#10;    ctx.beginPath();&#10;    ctx.ellipse(0, -46, 14, 6, 0, 0, Math.PI * 2);&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.strokeStyle = &quot;rgba(190,230,255,0.95)&quot;;&#10;    ctx.lineWidth = 4;&#10;    ctx.beginPath();&#10;    ctx.moveTo(0, -46);&#10;    for (let i = 1; i &lt;= 10; i++) {&#10;        const py = -46 - i * 3.4;&#10;        const px = Math.sin(t \/ 6 + i) * 2;&#10;        ctx.lineTo(px, py);&#10;    }&#10;    ctx.stroke();&#10;    gotasFuente.forEach(g =&gt; {&#10;        const fase = (t \/ 3 + g.fase) % 40;&#10;        const progreso = fase \/ 40;&#10;        const alturaMax = 34;&#10;        const py = -46 + (progreso * progreso) * alturaMax * 1.4 - alturaMax;&#10;        const px = g.lado * progreso * 26;&#10;        const alpha = 1 - progreso;&#10;        if (py &lt; -4) {&#10;            ctx.save();&#10;            ctx.globalAlpha = Math.max(0, alpha);&#10;            ctx.fillStyle = &quot;#cdeeff&quot;;&#10;            ctx.beginPath();&#10;            ctx.arc(px, py, 2, 0, Math.PI * 2);&#10;            ctx.fill();&#10;            ctx.restore();&#10;        }&#10;    });&#10;    ctx.restore();&#10;}&#10;function dibujarCorazon(x, y, opacidad) {&#10;    ctx.save();&#10;    ctx.globalAlpha = opacidad;&#10;    ctx.fillStyle = &quot;#ff69b4&quot;;&#10;    ctx.font = &quot;18px Arial&quot;;&#10;    ctx.textAlign = &quot;center&quot;;&#10;    ctx.fillText(&quot;\u2665&quot;, x, y);&#10;    ctx.restore();&#10;}&#10;function dibujarGato(x, y, t, fase, tumbado = false) {&#10;    const cola = Math.sin(t \/ 15 + fase) * 12;&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    if (tumbado) ctx.scale(1, 0.6);&#10;    ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    ctx.beginPath();&#10;    ctx.moveTo(-10, 0);&#10;    ctx.quadraticCurveTo(-20, cola - 5, -14, cola - 14);&#10;    ctx.stroke();&#10;    ctx.fillStyle = &quot;#e8965a&quot;;&#10;    ctx.beginPath(); ctx.ellipse(0, 0, 12, 8, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.beginPath(); ctx.arc(11, -6, 7, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.beginPath();&#10;    ctx.moveTo(7, -11); ctx.lineTo(9, -18); ctx.lineTo(12, -12); ctx.closePath();&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.beginPath();&#10;    ctx.moveTo(13, -12); ctx.lineTo(17, -17); ctx.lineTo(16, -10); ctx.closePath();&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#000&quot;;&#10;    ctx.beginPath(); ctx.arc(9, -6, 1, 0, Math.PI * 2); ctx.fill();&#10;    ctx.beginPath(); ctx.arc(14, -6, 1, 0, Math.PI * 2); ctx.fill();&#10;    ctx.restore();&#10;}&#10;function dibujarPerro(x, y, t, fase, tumbado = false) {&#10;    const cola = Math.sin(t \/ 8 + fase) * 20;&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    if (tumbado) ctx.scale(1, 0.6);&#10;    ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    ctx.beginPath();&#10;    ctx.moveTo(-12, -2);&#10;    ctx.lineTo(-12 - 8, -2 + cola * 0.3);&#10;    ctx.stroke();&#10;    ctx.fillStyle = &quot;#c8935a&quot;;&#10;    ctx.beginPath(); ctx.ellipse(0, 0, 14, 9, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.beginPath(); ctx.ellipse(15, -5, 8, 7, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.beginPath(); ctx.ellipse(10, -2, 3, 6, 0.4, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.beginPath(); ctx.ellipse(19, -2, 3, 6, -0.4, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#000&quot;;&#10;    ctx.beginPath(); ctx.arc(18, -6, 1, 0, Math.PI * 2); ctx.fill();&#10;    ctx.strokeStyle = &quot;#000&quot;;&#10;    [-8, -1, 6, 12].forEach(px =&gt; {&#10;        ctx.beginPath(); ctx.moveTo(px, 8); ctx.lineTo(px, 12); ctx.stroke();&#10;    });&#10;    ctx.restore();&#10;}&#10;function dibujarCocheVolador(x, y, t, escala = 1) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.scale(escala, escala);&#10;    const pulso = 0.55 + 0.35 * Math.sin(t \/ 7);&#10;    const rg = ctx.createRadialGradient(0, 18, 2, 0, 18, 46);&#10;    rg.addColorStop(0, `rgba(120,230,255,${0.45 * pulso})`); rg.addColorStop(1, &quot;rgba(120,230,255,0)&quot;);&#10;    ctx.fillStyle = rg; ctx.beginPath(); ctx.ellipse(0, 20, 46, 16, 0, 0, Math.PI * 2); ctx.fill();&#10;    [-16, 0, 16].forEach(ux =&gt; {&#10;        ctx.fillStyle = `rgba(190,245,255,${0.35 + 0.4 * pulso})`;&#10;        ctx.beginPath(); ctx.ellipse(ux, 13, 5, 2, 0, 0, Math.PI * 2); ctx.fill();&#10;    });&#10;    [-31, 31].forEach(wx =&gt; {&#10;        const wg = ctx.createRadialGradient(wx - 1.5, 1, 1, wx, 3, 10);&#10;        wg.addColorStop(0, &quot;#4a4a4a&quot;); wg.addColorStop(1, &quot;#141414&quot;);&#10;        ctx.fillStyle = wg; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 1.2;&#10;        ctx.beginPath(); ctx.ellipse(wx, 3, 6.5, 9.5, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;        ctx.fillStyle = &quot;#ff8a2a&quot;;&#10;        ctx.beginPath(); ctx.ellipse(wx, 3, 3, 5, 0, 0, Math.PI * 2); ctx.fill();&#10;        ctx.fillStyle = &quot;rgba(255,255,255,0.55)&quot;;&#10;        ctx.beginPath(); ctx.ellipse(wx - 1, 1, 1, 2.2, 0, 0, Math.PI * 2); ctx.fill();&#10;    });&#10;    const g = ctx.createLinearGradient(0, -16, 0, 16);&#10;    g.addColorStop(0, &quot;#fbfdff&quot;); g.addColorStop(0.45, &quot;#dfe5eb&quot;); g.addColorStop(0.8, &quot;#aab3bc&quot;); g.addColorStop(1, &quot;#7e8791&quot;);&#10;    ctx.fillStyle = g; ctx.strokeStyle = &quot;#5f6770&quot;; ctx.lineWidth = 1.8;&#10;    ctx.beginPath(); ctx.ellipse(0, 0, 35, 15.5, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.strokeStyle = &quot;rgba(90,100,110,0.55)&quot;; ctx.lineWidth = 0.8;&#10;    ctx.beginPath(); ctx.ellipse(0, 0.5, 29, 11, 0, 0.15, Math.PI - 0.15); ctx.stroke();&#10;    ctx.fillStyle = &quot;#8a939c&quot;;&#10;    [-24, -12, 12, 24].forEach(rx =&gt; { ctx.beginPath(); ctx.arc(rx, 4, 0.9, 0, Math.PI * 2); ctx.fill(); });&#10;    const og = ctx.createLinearGradient(0, -1, 0, 4);&#10;    og.addColorStop(0, &quot;#ffb064&quot;); og.addColorStop(0.5, &quot;#ff7a1a&quot;); og.addColorStop(1, &quot;#c4540a&quot;);&#10;    ctx.fillStyle = og; ctx.beginPath(); ctx.moveTo(-33, -1); ctx.lineTo(33, -1); ctx.lineTo(32, 3.5); ctx.lineTo(-32, 3.5); ctx.closePath(); ctx.fill();&#10;    [-1, 1].forEach(d =&gt; {&#10;        const hg = ctx.createRadialGradient(d * 33, 0, 0, d * 33, 0, 9);&#10;        hg.addColorStop(0, &quot;rgba(255,250,200,0.95)&quot;); hg.addColorStop(1, &quot;rgba(255,250,200,0)&quot;);&#10;        ctx.fillStyle = hg; ctx.beginPath(); ctx.arc(d * 33, 0, 9, 0, Math.PI * 2); ctx.fill();&#10;        ctx.fillStyle = &quot;#fffbe0&quot;; ctx.beginPath(); ctx.ellipse(d * 32, 0.5, 2.6, 1.6, 0, 0, Math.PI * 2); ctx.fill();&#10;    });&#10;    const cg = ctx.createLinearGradient(-18, -19, 14, 2);&#10;    cg.addColorStop(0, &quot;rgba(215,240,255,0.85)&quot;); cg.addColorStop(0.55, &quot;rgba(120,180,225,0.55)&quot;); cg.addColorStop(1, &quot;rgba(60,110,160,0.6)&quot;);&#10;    ctx.save();&#10;    ctx.beginPath(); ctx.ellipse(0, -7, 18.5, 12, 0, Math.PI, 0); ctx.closePath(); ctx.clip();&#10;    ctx.fillStyle = cg; ctx.fillRect(-20, -22, 40, 18);&#10;    ctx.fillStyle = &quot;rgba(40,55,80,0.55)&quot;;                                 \/\/ respaldo y cabecero&#10;    ctx.beginPath(); ctx.ellipse(2, -4, 6, 6.5, 0, 0, Math.PI * 2); ctx.fill();&#10;    ctx.fillRect(-1, -4, 6, 6);&#10;    ctx.fillStyle = &quot;rgba(255,255,255,0.5)&quot;;                               \/\/ reflejo largo&#10;    ctx.beginPath(); ctx.moveTo(-14, -9); ctx.lineTo(-7, -17); ctx.lineTo(-3, -17); ctx.lineTo(-10, -9); ctx.closePath(); ctx.fill();&#10;    ctx.restore();&#10;    ctx.strokeStyle = &quot;#6b737b&quot;; ctx.lineWidth = 1.4;&#10;    ctx.beginPath(); ctx.ellipse(0, -7, 18.5, 12, 0, Math.PI, 0); ctx.stroke();&#10;    ctx.fillStyle = &quot;#fff&quot;; ctx.strokeStyle = &quot;#333&quot;; ctx.lineWidth = 1;&#10;    ctx.fillRect(-17, 5, 34, 9); ctx.strokeRect(-17, 5, 34, 9);&#10;    ctx.fillStyle = &quot;#222&quot;; ctx.font = &quot;bold 6.5px monospace&quot;; ctx.textAlign = &quot;center&quot;; ctx.textBaseline = &quot;middle&quot;;&#10;    ctx.fillText(&quot;MIIG26C1&quot;, 0, 9.5); ctx.textBaseline = &quot;alphabetic&quot;;&#10;    ctx.strokeStyle = &quot;#7c3aed&quot;; ctx.lineWidth = 2;&#10;    ctx.beginPath(); ctx.moveTo(0, -18); ctx.lineTo(0, -29); ctx.stroke();&#10;    const gg = ctx.createRadialGradient(-1.2, -32.2, 0.5, 0, -31, 4);&#10;    gg.addColorStop(0, &quot;#f1e9ff&quot;); gg.addColorStop(0.5, &quot;#a78bfa&quot;); gg.addColorStop(1, &quot;#5b21b6&quot;);&#10;    ctx.fillStyle = gg; ctx.strokeStyle = &quot;#4c1d95&quot;; ctx.lineWidth = 1;&#10;    ctx.beginPath(); ctx.arc(0, -31, 3.6, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.restore();&#10;}&#10;function dibujarPajaro(x, y, t) {&#10;    const aleteo = Math.sin(t \/ 4) * 6;&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.strokeStyle = &quot;#3a1d47&quot;;&#10;    ctx.lineWidth = 2.5;&#10;    ctx.beginPath();&#10;    ctx.moveTo(-8, 0); ctx.quadraticCurveTo(-3, -aleteo, 0, 0);&#10;    ctx.quadraticCurveTo(3, -aleteo, 8, 0);&#10;    ctx.stroke();&#10;    ctx.restore();&#10;}&#10;function dibujarEscritorioTeletrabajo(x, y) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.strokeStyle = &quot;#222&quot;; ctx.lineWidth = 2;&#10;    [-7, -2, 4, 9].forEach(dx =&gt; {&#10;        ctx.beginPath(); ctx.moveTo(3, 8); ctx.lineTo(3 + dx, 13); ctx.stroke();&#10;        ctx.fillStyle = &quot;#333&quot;;&#10;        ctx.beginPath(); ctx.arc(3 + dx, 14, 1.4, 0, Math.PI * 2); ctx.fill();&#10;    });&#10;    ctx.beginPath(); ctx.moveTo(3, 8); ctx.lineTo(3, -1); ctx.stroke();&#10;    ctx.fillStyle = &quot;#3a3a44&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 1.5;&#10;    ctx.beginPath(); ctx.ellipse(3, -3, 9, 4, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.beginPath();&#10;    ctx.moveTo(-5, -5);&#10;    ctx.quadraticCurveTo(-9, -21, 2, -25);&#10;    ctx.quadraticCurveTo(11, -21, 6, -5);&#10;    ctx.closePath();&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.strokeStyle = &quot;#5c5c68&quot;; ctx.lineWidth = 1;&#10;    ctx.beginPath();&#10;    ctx.moveTo(-1, -9); ctx.lineTo(0, -21);&#10;    ctx.moveTo(3, -9); ctx.lineTo(3, -22);&#10;    ctx.stroke();&#10;    const mesaX = 24;&#10;    ctx.fillStyle = &quot;#c9915a&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2.5;&#10;    ctx.fillRect(mesaX, -30, 40, 7);&#10;    ctx.strokeRect(mesaX, -30, 40, 7);&#10;    ctx.fillStyle = &quot;#8a5a2b&quot;;&#10;    ctx.fillRect(mesaX + 2, -23, 4, 23);&#10;    ctx.fillRect(mesaX + 34, -23, 4, 23);&#10;    ctx.fillStyle = &quot;#555&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 1.5;&#10;    ctx.fillRect(mesaX + 8, -33, 20, 3);&#10;    ctx.strokeRect(mesaX + 8, -33, 20, 3);&#10;    ctx.save();&#10;    ctx.translate(mesaX + 8, -33);&#10;    ctx.rotate(-0.2);&#10;    ctx.fillStyle = &quot;#2a2a2a&quot;;&#10;    ctx.fillRect(0, -16, 20, 16);&#10;    ctx.strokeRect(0, -16, 20, 16);&#10;    ctx.shadowColor = &quot;rgba(150,215,255,0.9)&quot;;&#10;    ctx.shadowBlur = 6;&#10;    ctx.fillStyle = &quot;#bfe9ff&quot;;&#10;    ctx.fillRect(2, -14, 16, 12);&#10;    ctx.shadowBlur = 0;&#10;    ctx.strokeStyle = &quot;rgba(255,255,255,0.5)&quot;; ctx.lineWidth = 0.8;&#10;    ctx.beginPath(); ctx.moveTo(2, -9); ctx.lineTo(18, -9); ctx.stroke();&#10;    ctx.restore();&#10;    ctx.restore();&#10;}&#10;function dibujarCocina(x, y, ancho, alto) {&#10;    ctx.fillStyle = &quot;#d9a066&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    ctx.fillRect(x, y + alto * 0.55, ancho, alto * 0.2);&#10;    ctx.strokeRect(x, y + alto * 0.55, ancho, alto * 0.2);&#10;    ctx.fillStyle = &quot;#f2e6d8&quot;;&#10;    ctx.fillRect(x, y + alto * 0.75, ancho, alto * 0.25);&#10;    ctx.strokeRect(x, y + alto * 0.75, ancho, alto * 0.25);&#10;    ctx.fillStyle = &quot;#333&quot;;&#10;    [0.2, 0.38].forEach(f =&gt; {&#10;        ctx.beginPath();&#10;        ctx.arc(x + ancho * f, y + alto * 0.55, ancho * 0.07, 0, Math.PI * 2);&#10;        ctx.fill();&#10;    });&#10;    ctx.fillStyle = &quot;#cfd8dc&quot;;&#10;    ctx.fillRect(x + ancho * 0.58, y + alto * 0.5, ancho * 0.28, alto * 0.08);&#10;    ctx.strokeRect(x + ancho * 0.58, y + alto * 0.5, ancho * 0.28, alto * 0.08);&#10;    ctx.strokeStyle = &quot;#8a8a8a&quot;; ctx.lineWidth = 3;&#10;    ctx.beginPath();&#10;    ctx.moveTo(x + ancho * 0.72, y + alto * 0.5);&#10;    ctx.lineTo(x + ancho * 0.72, y + alto * 0.4);&#10;    ctx.stroke();&#10;    ctx.fillStyle = &quot;#8a5a2b&quot;;&#10;    ctx.fillRect(x, y + alto * 0.32, ancho, 5);&#10;    [&quot;#ff6f91&quot;, &quot;#ffd166&quot;, &quot;#8fd66a&quot;].forEach((col, i) =&gt; {&#10;        ctx.fillStyle = col;&#10;        ctx.beginPath();&#10;        ctx.arc(x + 14 + i * 16, y + alto * 0.32 - 8, 6, 0, Math.PI * 2);&#10;        ctx.fill();&#10;    });&#10;}&#10;function dibujarChorroFregadero(x, y, t) {&#10;    ctx.save();&#10;    ctx.strokeStyle = &quot;rgba(150,210,240,0.9)&quot;;&#10;    ctx.lineWidth = 2.5;&#10;    ctx.beginPath();&#10;    ctx.moveTo(x, y - 24);&#10;    ctx.lineTo(x, y - 6);&#10;    ctx.stroke();&#10;    ctx.fillStyle = &quot;rgba(150,210,240,0.8)&quot;;&#10;    for (let i = 0; i &lt; 4; i++) {&#10;        const fase = (t \/ 3 + i * 5) % 20;&#10;        ctx.beginPath();&#10;        ctx.arc(x, y - 6 + fase, 2, 0, Math.PI * 2);&#10;        ctx.fill();&#10;    }&#10;    ctx.restore();&#10;}&#10;function dibujarChapoteo(x, y, t) {&#10;    ctx.save();&#10;    for (let i = 0; i &lt; 2; i++) {&#10;        const fase = (t \/ 6 + i * 15) % 30;&#10;        ctx.strokeStyle = `rgba(150,210,240,${Math.max(0, 0.6 - fase \/ 30)})`;&#10;        ctx.lineWidth = 2;&#10;        ctx.beginPath();&#10;        ctx.ellipse(x, y, 14 + fase, (14 + fase) * 0.35, 0, 0, Math.PI * 2);&#10;        ctx.stroke();&#10;    }&#10;    ctx.fillStyle = &quot;rgba(150,210,240,0.9)&quot;;&#10;    for (let i = 0; i &lt; 4; i++) {&#10;        const ang = (i \/ 4) * Math.PI * 2 + t \/ 15;&#10;        const salto = Math.abs(Math.sin(t \/ 6 + i));&#10;        const px = x + Math.cos(ang) * (18 + salto * 6);&#10;        const py = y - salto * 12 + Math.sin(ang) * 4;&#10;        ctx.beginPath();&#10;        ctx.arc(px, py, 2, 0, Math.PI * 2);&#10;        ctx.fill();&#10;    }&#10;    ctx.restore();&#10;}&#10;function dibujarSarten(x, y, t) {&#10;    ctx.save();&#10;    ctx.translate(x, y - 18);&#10;    const salto = Math.abs(Math.sin(t \/ 8)) * 4;&#10;    ctx.translate(0, -salto);&#10;    ctx.strokeStyle = &quot;#333&quot;; ctx.lineWidth = 5;&#10;    ctx.beginPath(); ctx.moveTo(14, 0); ctx.lineTo(34, -4); ctx.stroke();&#10;    ctx.fillStyle = &quot;#555&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    ctx.beginPath(); ctx.ellipse(0, 0, 16, 8, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#f2a65a&quot;;&#10;    const salpicon = Math.sin(t \/ 8) * 3;&#10;    ctx.beginPath(); ctx.arc(salpicon, -salto * 0.6, 4, 0, Math.PI * 2); ctx.fill();&#10;    ctx.strokeStyle = &quot;rgba(255,255,255,0.6)&quot;; ctx.lineWidth = 2;&#10;    ctx.beginPath();&#10;    ctx.moveTo(-6, -8); ctx.quadraticCurveTo(-10, -16 - Math.sin(t\/6)*3, -6, -24);&#10;    ctx.stroke();&#10;    ctx.restore();&#10;}&#10;function dibujarNevera(x, y, ancho, alto, abierta) {&#10;    ctx.fillStyle = &quot;#fdfdfd&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2.5;&#10;    ctx.fillRect(x, y + alto * 0.15, ancho, alto * 0.85);&#10;    ctx.strokeRect(x, y + alto * 0.15, ancho, alto * 0.85);&#10;    if (!abierta) {&#10;        ctx.beginPath();&#10;        ctx.moveTo(x, y + alto * 0.42);&#10;        ctx.lineTo(x + ancho, y + alto * 0.42);&#10;        ctx.stroke();&#10;        return;&#10;    }&#10;    ctx.fillStyle = &quot;#eaf7ff&quot;;&#10;    ctx.fillRect(x + ancho * 0.1, y + alto * 0.2, ancho * 0.8, alto * 0.75);&#10;    ctx.strokeStyle = &quot;#bcdff0&quot;; ctx.lineWidth = 1.5;&#10;    [0.4, 0.6, 0.8].forEach(f =&gt; {&#10;        ctx.beginPath();&#10;        ctx.moveTo(x + ancho * 0.1, y + alto * f);&#10;        ctx.lineTo(x + ancho * 0.9, y + alto * f);&#10;        ctx.stroke();&#10;    });&#10;    const comida = [&quot;#ff6f91&quot;, &quot;#ffd166&quot;, &quot;#8fd66a&quot;, &quot;#f4a6ff&quot;];&#10;    comida.forEach((col, i) =&gt; {&#10;        ctx.fillStyle = col;&#10;        ctx.beginPath();&#10;        ctx.arc(x + ancho * (0.25 + (i % 2) * 0.4), y + alto * (0.32 + Math.floor(i \/ 2) * 0.2), ancho * 0.09, 0, Math.PI * 2);&#10;        ctx.fill();&#10;    });&#10;    ctx.save();&#10;    ctx.translate(x, y + alto * 0.15);&#10;    ctx.rotate(-1.1);&#10;    ctx.fillStyle = &quot;#e6e6e6&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    ctx.fillRect(0, 0, ancho * 0.9, alto * 0.85);&#10;    ctx.strokeRect(0, 0, ancho * 0.9, alto * 0.85);&#10;    ctx.restore();&#10;}&#10;function dibujarBa\u00f1o(x, y, ancho, alto) {&#10;    ctx.fillStyle = &quot;#dff3f8&quot;;&#10;    ctx.fillRect(x, y, ancho, alto * 0.6);&#10;    ctx.fillStyle = &quot;#ffffff&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2.5;&#10;    ctx.beginPath();&#10;    ctx.ellipse(x + ancho * 0.28, y + alto * 0.72, ancho * 0.24, alto * 0.14, 0, 0, Math.PI * 2);&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.strokeStyle = &quot;#7ecbe0&quot;; ctx.lineWidth = 2;&#10;    ctx.beginPath();&#10;    ctx.ellipse(x + ancho * 0.28, y + alto * 0.70, ancho * 0.18, alto * 0.08, 0, 0, Math.PI * 2);&#10;    ctx.stroke();&#10;    ctx.fillStyle = &quot;#ffffff&quot;; ctx.strokeStyle = &quot;#000&quot;;&#10;    ctx.fillRect(x + ancho * 0.62, y + alto * 0.5, ancho * 0.14, alto * 0.1);&#10;    ctx.strokeRect(x + ancho * 0.62, y + alto * 0.5, ancho * 0.14, alto * 0.1);&#10;    ctx.beginPath();&#10;    ctx.ellipse(x + ancho * 0.69, y + alto * 0.78, ancho * 0.12, alto * 0.1, 0, 0, Math.PI * 2);&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#ffffff&quot;;&#10;    ctx.beginPath();&#10;    ctx.ellipse(x + ancho * 0.88, y + alto * 0.6, ancho * 0.09, alto * 0.06, 0, 0, Math.PI * 2);&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#8a5a2b&quot;;&#10;    ctx.fillRect(x + ancho * 0.86, y + alto * 0.55, ancho * 0.04, alto * 0.15);&#10;    ctx.fillStyle = &quot;#cdeeff&quot;; ctx.strokeStyle = &quot;#7ecbe0&quot;;&#10;    ctx.fillRect(x + ancho * 0.80, y + alto * 0.28, ancho * 0.16, alto * 0.2);&#10;    ctx.strokeRect(x + ancho * 0.80, y + alto * 0.28, ancho * 0.16, alto * 0.2);&#10;}&#10;function dibujarGoteoLavabo(x, y, t) {&#10;    ctx.save();&#10;    ctx.fillStyle = &quot;rgba(150,210,240,0.85)&quot;;&#10;    const fase = (t \/ 5) % 30;&#10;    if (fase &lt; 22) {&#10;        ctx.beginPath();&#10;        ctx.arc(x, y + fase * 0.7, 2, 0, Math.PI * 2);&#10;        ctx.fill();&#10;    }&#10;    ctx.restore();&#10;}&#10;function dibujarPuerta(xBisagra, yBisagra, alto, abierta, ladoIzq) {&#10;    ctx.save();&#10;    ctx.translate(xBisagra, yBisagra);&#10;    const angulo = abierta ? (ladoIzq ? -1.1 : 1.1) : 0;&#10;    ctx.rotate(angulo);&#10;    ctx.fillStyle = &quot;rgba(122,74,43,0.85)&quot;;&#10;    ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    const ancho = ladoIzq ? -34 : 34;&#10;    ctx.fillRect(0, 0, ancho, alto);&#10;    ctx.strokeRect(0, 0, ancho, alto);&#10;    ctx.fillStyle = &quot;#e8c168&quot;;&#10;    ctx.beginPath(); ctx.arc(ancho * 0.82, alto * 0.5, 2.5, 0, Math.PI * 2); ctx.fill();&#10;    ctx.restore();&#10;}&#10;function dibujarBici(x, y, pedaleando, t) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.strokeStyle = &quot;#333&quot;; ctx.lineWidth = 3;&#10;    ctx.fillStyle = &quot;#ddd&quot;;&#10;    ctx.beginPath(); ctx.arc(-28, 20, 22, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.save();&#10;    ctx.translate(-28, 20);&#10;    ctx.rotate(pedaleando ? t \/ 8 : 0);&#10;    ctx.strokeStyle = &quot;#e63946&quot;; ctx.lineWidth = 2.5;&#10;    for (let i = 0; i &lt; 5; i++) {&#10;        const ang = (i \/ 5) * Math.PI * 2;&#10;        ctx.beginPath();&#10;        ctx.moveTo(0, 0);&#10;        ctx.lineTo(Math.cos(ang) * 20, Math.sin(ang) * 20);&#10;        ctx.stroke();&#10;    }&#10;    ctx.restore();&#10;    ctx.strokeStyle = &quot;#333&quot;; ctx.lineWidth = 3;&#10;    ctx.beginPath();&#10;    ctx.moveTo(-28, 20); ctx.lineTo(0, -10); ctx.lineTo(20, 20);&#10;    ctx.moveTo(0, -10); ctx.lineTo(-6, 20);&#10;    ctx.moveTo(0, -10); ctx.lineTo(6, -34);&#10;    ctx.stroke();&#10;    ctx.fillStyle = &quot;#333&quot;;&#10;    ctx.fillRect(-8, -16, 16, 5);&#10;    ctx.beginPath(); ctx.moveTo(6, -34); ctx.lineTo(22, -34); ctx.stroke();&#10;    ctx.save();&#10;    ctx.translate(-6, 20);&#10;    ctx.rotate(pedaleando ? t \/ 8 : 0);&#10;    ctx.strokeStyle = &quot;#555&quot;; ctx.lineWidth = 4;&#10;    ctx.beginPath(); ctx.moveTo(-13, 0); ctx.lineTo(13, 0); ctx.stroke();&#10;    ctx.fillStyle = &quot;#222&quot;;&#10;    ctx.beginPath(); ctx.arc(-13, 0, 4, 0, Math.PI * 2); ctx.fill();&#10;    ctx.beginPath(); ctx.arc(13, 0, 4, 0, Math.PI * 2); ctx.fill();&#10;    ctx.restore();&#10;    ctx.fillStyle = &quot;#ddd&quot;; ctx.strokeStyle = &quot;#333&quot;; ctx.lineWidth = 3;&#10;    ctx.beginPath(); ctx.arc(20, 20, 14, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.save();&#10;    ctx.translate(20, 20);&#10;    ctx.rotate(pedaleando ? t \/ 8 : 0);&#10;    ctx.strokeStyle = &quot;#e63946&quot;; ctx.lineWidth = 2;&#10;    for (let i = 0; i &lt; 4; i++) {&#10;        const ang = (i \/ 4) * Math.PI * 2;&#10;        ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(Math.cos(ang) * 12, Math.sin(ang) * 12); ctx.stroke();&#10;    }&#10;    ctx.restore();&#10;    if (pedaleando) {&#10;        ctx.font = &quot;16px Arial&quot;; ctx.textAlign = &quot;center&quot;;&#10;        ctx.fillText(&quot;\ud83d\udca8&quot;, 0, -50);&#10;    }&#10;    ctx.restore();&#10;}&#10;function dibujarPesas(x, y) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.fillStyle = &quot;#666&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    ctx.fillRect(-30, 20, 60, 8);&#10;    ctx.strokeRect(-30, 20, 60, 8);&#10;    [-14, 14].forEach(dx =&gt; {&#10;        ctx.strokeStyle = &quot;#333&quot;; ctx.lineWidth = 5;&#10;        ctx.beginPath(); ctx.moveTo(dx - 10, 12); ctx.lineTo(dx + 10, 12); ctx.stroke();&#10;        ctx.fillStyle = &quot;#333&quot;;&#10;        ctx.beginPath(); ctx.arc(dx - 10, 12, 6, 0, Math.PI * 2); ctx.fill();&#10;        ctx.beginPath(); ctx.arc(dx + 10, 12, 6, 0, Math.PI * 2); ctx.fill();&#10;    });&#10;    ctx.restore();&#10;}&#10;function dibujarMancuernaEnUso(x, y, t) {&#10;    const sube = Math.abs(Math.sin(t \/ 10)) * 14;&#10;    ctx.save();&#10;    ctx.translate(x, y - 20 - sube);&#10;    ctx.strokeStyle = &quot;#333&quot;; ctx.lineWidth = 5;&#10;    ctx.beginPath(); ctx.moveTo(-10, 0); ctx.lineTo(10, 0); ctx.stroke();&#10;    ctx.fillStyle = &quot;#333&quot;;&#10;    ctx.beginPath(); ctx.arc(-10, 0, 6, 0, Math.PI * 2); ctx.fill();&#10;    ctx.beginPath(); ctx.arc(10, 0, 6, 0, Math.PI * 2); ctx.fill();&#10;    ctx.restore();&#10;}&#10;function dibujarPiscina(x, y, ancho, alto, t) {&#10;    ctx.save();&#10;    ctx.fillStyle = &quot;#7ecbe8&quot;; ctx.strokeStyle = &quot;#3a8fb0&quot;; ctx.lineWidth = 4;&#10;    ctx.beginPath();&#10;    ctx.roundRect ? ctx.roundRect(x, y, ancho, alto, 14) : ctx.rect(x, y, ancho, alto);&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.strokeStyle = &quot;rgba(255,255,255,0.6)&quot;; ctx.lineWidth = 2;&#10;    for (let i = 0; i &lt; 3; i++) {&#10;        ctx.beginPath();&#10;        for (let px = x + 10; px &lt; x + ancho - 10; px += 14) {&#10;            const py = y + 20 + i * 22 + Math.sin(px \/ 20 + t \/ 12 + i) * 3;&#10;            if (px === x + 10) ctx.moveTo(px, py); else ctx.lineTo(px, py);&#10;        }&#10;        ctx.stroke();&#10;    }&#10;    ctx.restore();&#10;}&#10;const TERRAZA = { baseX: 670, baseY: SUELO_Y + 195, ancho: 250, alto: 90 };&#10;const MESAS_TERRAZA = [&#10;    { x: TERRAZA.baseX + 40,  y: TERRAZA.baseY + 30, color: &quot;#f7d34c&quot; },&#10;    { x: TERRAZA.baseX + 125, y: TERRAZA.baseY + 50, color: &quot;#4caf50&quot; },&#10;    { x: TERRAZA.baseX + 210, y: TERRAZA.baseY + 30, color: &quot;#f7d34c&quot; }&#10;];&#10;const ASIENTOS_TERRAZA_OFFSETS = [[-22, 10], [22, 10], [0, 26]];&#10;const ZONAS_TERRAZA_ASIENTOS = [];&#10;MESAS_TERRAZA.forEach(m =&gt; {&#10;    ASIENTOS_TERRAZA_OFFSETS.forEach(([dx, dy]) =&gt; {&#10;        ZONAS_TERRAZA_ASIENTOS.push({ x: m.x + dx, y: m.y + dy - 4 });&#10;    });&#10;});&#10;function dibujarMesaTerraza(x, y, colorSombrilla) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2; ctx.fillStyle = &quot;#8a5a2b&quot;;&#10;    ASIENTOS_TERRAZA_OFFSETS.forEach(([cx, cy]) =&gt; {&#10;        ctx.fillRect(cx - 6, cy - 10, 12, 12);&#10;        ctx.strokeRect(cx - 6, cy - 10, 12, 12);&#10;        ctx.fillRect(cx - 6, cy - 22, 12, 4);&#10;        ctx.strokeRect(cx - 6, cy - 22, 12, 4);&#10;    });&#10;    ctx.fillStyle = &quot;#fff&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2.5;&#10;    ctx.beginPath(); ctx.ellipse(0, 4, 20, 9, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#333&quot;;&#10;    ctx.fillRect(-3, 4, 6, 18);&#10;    ctx.strokeStyle = &quot;#333&quot;; ctx.lineWidth = 3;&#10;    ctx.beginPath(); ctx.moveTo(0, 4); ctx.lineTo(0, -46); ctx.stroke();&#10;    ctx.fillStyle = colorSombrilla; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    ctx.beginPath();&#10;    ctx.moveTo(-34, -46);&#10;    ctx.quadraticCurveTo(0, -70, 34, -46);&#10;    ctx.quadraticCurveTo(0, -58, -34, -46);&#10;    ctx.closePath();&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.strokeStyle = &quot;rgba(0,0,0,0.25)&quot;; ctx.lineWidth = 1;&#10;    for (let g = -2; g &lt;= 2; g++) {&#10;        ctx.beginPath(); ctx.moveTo(0, -58); ctx.lineTo(g * 14, -46); ctx.stroke();&#10;    }&#10;    ctx.restore();&#10;}&#10;function dibujarGuirnalda(mesas, y, t, dia) {&#10;    ctx.save();&#10;    ctx.strokeStyle = &quot;#333&quot;; ctx.lineWidth = 1.5;&#10;    for (let i = 0; i &lt; mesas.length - 1; i++) {&#10;        const a = mesas[i], b = mesas[i + 1];&#10;        const midX = (a.x + b.x) \/ 2, midY = y + 16;&#10;        ctx.beginPath();&#10;        ctx.moveTo(a.x, y);&#10;        ctx.quadraticCurveTo(midX, midY, b.x, y);&#10;        ctx.stroke();&#10;        for (let f = 0.15; f &lt; 1; f += 0.17) {&#10;            const bx = (1 - f) * (1 - f) * a.x + 2 * (1 - f) * f * midX + f * f * b.x;&#10;            const by = (1 - f) * (1 - f) * y + 2 * (1 - f) * f * midY + f * f * y;&#10;            if (!dia) {&#10;                const brillo = 0.6 + Math.sin(t \/ 12 + bx) * 0.4;&#10;                resplandor(bx, by, 9, '255,220,120', 0.75 * brillo);&#10;                ctx.fillStyle = `rgba(255,220,120,${brillo})`;&#10;            } else {&#10;                ctx.shadowBlur = 0;&#10;                ctx.fillStyle = &quot;#c9c9c9&quot;;&#10;            }&#10;            ctx.beginPath(); ctx.arc(bx, by, 2.6, 0, Math.PI * 2); ctx.fill();&#10;        }&#10;    }&#10;    ctx.shadowBlur = 0;&#10;    ctx.restore();&#10;}&#10;function dibujarTerraza(t, dia) {&#10;    const { baseX, baseY, ancho, alto } = TERRAZA;&#10;    ctx.fillStyle = &quot;#c9a06a&quot;;&#10;    ctx.fillRect(baseX, baseY, ancho, alto);&#10;    ctx.strokeStyle = &quot;rgba(0,0,0,0.15)&quot;; ctx.lineWidth = 1.5;&#10;    for (let i = 1; i &lt; 8; i++) {&#10;        ctx.beginPath();&#10;        ctx.moveTo(baseX + i * (ancho \/ 8), baseY);&#10;        ctx.lineTo(baseX + i * (ancho \/ 8), baseY + alto);&#10;        ctx.stroke();&#10;    }&#10;    ctx.strokeStyle = &quot;#8a5a2b&quot;; ctx.lineWidth = 3;&#10;    ctx.strokeRect(baseX, baseY, ancho, alto);&#10;    ctx.fillStyle = &quot;#ff9f43&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    ctx.fillRect(baseX + ancho \/ 2 - 55, baseY - 28, 110, 26);&#10;    ctx.strokeRect(baseX + ancho \/ 2 - 55, baseY - 28, 110, 26);&#10;    ctx.fillStyle = &quot;#fff&quot;;&#10;    ctx.font = &quot;bold 13px 'Comic Sans MS', sans-serif&quot;;&#10;    ctx.textAlign = &quot;center&quot;;&#10;    ctx.fillText(&quot;\u2615 TERRAZA&quot;, baseX + ancho \/ 2, baseY - 10);&#10;    MESAS_TERRAZA.forEach(m =&gt; dibujarMesaTerraza(m.x, m.y, m.color));&#10;    dibujarGuirnalda(MESAS_TERRAZA, baseY - 55, t, dia);&#10;}&#10;const MERCADILLO = { baseX: 40, baseY: SUELO_Y + 276, ancho: 240, alto: 80 };           \/\/ escalera en diagonal: el Mercadillo, abajo del todo (primer plano)&#10;function dibujarPuestoMercadillo(x, y, color) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.strokeStyle = &quot;#5a3d1e&quot;; ctx.lineWidth = 4;&#10;    ctx.beginPath(); ctx.moveTo(-24, 10); ctx.lineTo(-24, -30); ctx.stroke();&#10;    ctx.beginPath(); ctx.moveTo(24, 10); ctx.lineTo(24, -30); ctx.stroke();&#10;    ctx.fillStyle = color; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    ctx.beginPath();&#10;    ctx.moveTo(-30, -30); ctx.lineTo(30, -30); ctx.lineTo(24, -42); ctx.lineTo(-24, -42);&#10;    ctx.closePath();&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.strokeStyle = &quot;rgba(255,255,255,0.5)&quot;; ctx.lineWidth = 3;&#10;    for (let i = -20; i &lt;= 20; i += 12) {&#10;        ctx.beginPath(); ctx.moveTo(i, -30); ctx.lineTo(i * 0.8, -42); ctx.stroke();&#10;    }&#10;    ctx.fillStyle = &quot;#8a5a2b&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    ctx.fillRect(-28, 4, 56, 10);&#10;    ctx.strokeRect(-28, 4, 56, 10);&#10;    const cols = [&quot;#ff6f91&quot;, &quot;#ffd166&quot;, &quot;#8fd66a&quot;, &quot;#f4a6ff&quot;];&#10;    cols.forEach((c, i) =&gt; {&#10;        ctx.fillStyle = c;&#10;        ctx.beginPath(); ctx.arc(-20 + i * 13, 0, 4, 0, Math.PI * 2); ctx.fill();&#10;    });&#10;    ctx.restore();&#10;}&#10;function dibujarFarolillo(x, y, color, t, fase, dia) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.strokeStyle = &quot;rgba(0,0,0,0.3)&quot;; ctx.lineWidth = 1;&#10;    ctx.beginPath(); ctx.moveTo(0, -14); ctx.lineTo(0, 0); ctx.stroke();&#10;    const balanceo = Math.sin(t \/ 30 + fase) * 4;&#10;    ctx.translate(balanceo * 0.25, 0);&#10;    if (!dia) {&#10;        resplandor(0, 10, 18, '255,200,120', 0.8);&#10;        ctx.fillStyle = color;&#10;    } else {&#10;        ctx.shadowBlur = 0;&#10;        ctx.fillStyle = &quot;#cfcfcf&quot;; \/\/ apagado durante el d\u00eda&#10;    }&#10;    ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 1.5;&#10;    ctx.beginPath(); ctx.ellipse(0, 10, 8, 10, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.shadowBlur = 0;&#10;    ctx.fillStyle = &quot;#8a5a2b&quot;;&#10;    ctx.fillRect(-2, -1, 4, 3);&#10;    ctx.fillRect(-2, 19, 4, 3);&#10;    ctx.restore();&#10;}&#10;function dibujarMercadillo(t, dia) {&#10;    const { baseX, baseY, ancho, alto } = MERCADILLO;&#10;    ctx.fillStyle = &quot;#8a6a45&quot;;&#10;    ctx.fillRect(baseX, baseY, ancho, alto);&#10;    ctx.strokeStyle = &quot;#5a4326&quot;; ctx.lineWidth = 2;&#10;    ctx.strokeRect(baseX, baseY, ancho, alto);&#10;    ctx.fillStyle = &quot;#6a3e8c&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    ctx.fillRect(baseX + ancho \/ 2 - 70, baseY - 28, 140, 26);&#10;    ctx.strokeRect(baseX + ancho \/ 2 - 70, baseY - 28, 140, 26);&#10;    ctx.fillStyle = &quot;#fff&quot;;&#10;    ctx.font = &quot;bold 13px 'Comic Sans MS', sans-serif&quot;;&#10;    ctx.textAlign = &quot;center&quot;;&#10;    ctx.fillText(&quot;\ud83c\udfee MERCADILLO&quot;, baseX + ancho \/ 2, baseY - 10);&#10;    const puestos = [&#10;        { x: baseX + 45,  y: baseY + 55, color: &quot;#e85fb0&quot; },&#10;        { x: baseX + 120, y: baseY + 55, color: &quot;#4caf50&quot; },&#10;        { x: baseX + 195, y: baseY + 55, color: &quot;#ffb84d&quot; }&#10;    ];&#10;    puestos.forEach(p =&gt; dibujarPuestoMercadillo(p.x, p.y, p.color));&#10;    const y0 = baseY - 42;&#10;    const x0 = baseX + 15, xAncho = ancho - 30;&#10;    const colores = [&quot;#ff6f91&quot;, &quot;#ffd166&quot;, &quot;#8fd66a&quot;, &quot;#f4a6ff&quot;, &quot;#7ecbe8&quot;];&#10;    ctx.strokeStyle = &quot;rgba(0,0,0,0.35)&quot;; ctx.lineWidth = 1.5;&#10;    ctx.beginPath();&#10;    for (let px = 0; px &lt;= xAncho; px += 6) {&#10;        const py = y0 + Math.sin((px \/ xAncho) * Math.PI) * 12;&#10;        if (px === 0) ctx.moveTo(x0 + px, py); else ctx.lineTo(x0 + px, py);&#10;    }&#10;    ctx.stroke();&#10;    for (let i = 0; i &lt; 7; i++) {&#10;        const frac = i \/ 6;&#10;        const fx = x0 + frac * xAncho;&#10;        const fy = y0 + Math.sin(frac * Math.PI) * 12;&#10;        dibujarFarolillo(fx, fy, colores[i % colores.length], t, i, dia);&#10;    }&#10;}&#10;function dibujarPuestoFrutas(x, y, escala = 1) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.scale(escala, escala);&#10;    ctx.strokeStyle = &quot;#5a3d1e&quot;; ctx.lineWidth = 3;&#10;    ctx.beginPath(); ctx.moveTo(-16, -4); ctx.lineTo(-16, -26); ctx.stroke();&#10;    ctx.beginPath(); ctx.moveTo(16, -4); ctx.lineTo(16, -26); ctx.stroke();&#10;    ctx.fillStyle = &quot;#ff9f43&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    ctx.beginPath();&#10;    ctx.moveTo(-20, -26); ctx.lineTo(20, -26); ctx.lineTo(16, -36); ctx.lineTo(-16, -36);&#10;    ctx.closePath();&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#8a5a2b&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    ctx.fillRect(-18, -4, 36, 8);&#10;    ctx.strokeRect(-18, -4, 36, 8);&#10;    [&quot;#d6335a&quot;, &quot;#f2a65a&quot;, &quot;#ffd166&quot;].forEach((c, i) =&gt; {&#10;        ctx.fillStyle = c;&#10;        ctx.beginPath(); ctx.arc(-12 + i * 10, -8, 3.5, 0, Math.PI * 2); ctx.fill();&#10;    });&#10;    [&quot;#ff6f91&quot;, &quot;#f4a6ff&quot;].forEach((c, i) =&gt; {&#10;        ctx.strokeStyle = &quot;#3f7d3f&quot;; ctx.lineWidth = 1.5;&#10;        ctx.beginPath(); ctx.moveTo(10 + i * 5, -4); ctx.lineTo(10 + i * 5, -15); ctx.stroke();&#10;        ctx.fillStyle = c;&#10;        ctx.beginPath(); ctx.arc(10 + i * 5, -17, 3, 0, Math.PI * 2); ctx.fill();&#10;    });&#10;    ctx.restore();&#10;}&#10;function dibujarRefugio(x, y) {&#10;    const ancho = REFUGIO.ancho, alto = REFUGIO.alto;&#10;    ctx.save();&#10;    ctx.fillStyle = &quot;#c98a52&quot;; ctx.strokeStyle = &quot;#5a3a1e&quot;; ctx.lineWidth = 2.5;&#10;    ctx.fillRect(x - ancho \/ 2, y - alto, ancho, alto);&#10;    ctx.strokeRect(x - ancho \/ 2, y - alto, ancho, alto);&#10;    ctx.fillStyle = &quot;#8a5a2b&quot;;&#10;    ctx.beginPath();&#10;    ctx.moveTo(x - ancho \/ 2 - 8, y - alto);&#10;    ctx.lineTo(x, y - alto - ancho * 0.4);&#10;    ctx.lineTo(x + ancho \/ 2 + 8, y - alto);&#10;    ctx.closePath();&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#4a2f18&quot;;&#10;    ctx.beginPath();&#10;    ctx.moveTo(x - 14, y);&#10;    ctx.lineTo(x - 14, y - alto * 0.55);&#10;    ctx.quadraticCurveTo(x, y - alto * 0.85, x + 14, y - alto * 0.55);&#10;    ctx.lineTo(x + 14, y);&#10;    ctx.closePath();&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#fff5fa&quot;; ctx.strokeStyle = &quot;#ff69b4&quot;; ctx.lineWidth = 2;&#10;    ctx.fillRect(x - 34, y - alto - ancho * 0.4 - 20, 68, 18);&#10;    ctx.strokeRect(x - 34, y - alto - ancho * 0.4 - 20, 68, 18);&#10;    ctx.fillStyle = &quot;#6a3e8c&quot;;&#10;    ctx.font = &quot;bold 10px 'Comic Sans MS', sans-serif&quot;;&#10;    ctx.textAlign = &quot;center&quot;;&#10;    ctx.fillText(&quot;\ud83d\udc3e Refugio&quot;, x, y - alto - ancho * 0.4 - 7);&#10;    ctx.restore();&#10;}&#10;function dibujarTranvia(x, y, t) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.fillStyle = &quot;#e85fb0&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2.5;&#10;    ctx.beginPath();&#10;    ctx.roundRect ? ctx.roundRect(-40, -34, 80, 34, 8) : ctx.rect(-40, -34, 80, 34);&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#cdeeff&quot;;&#10;    [-28, -4, 20].forEach(vx =&gt; { ctx.fillRect(vx, -28, 16, 12); ctx.strokeRect(vx, -28, 16, 12); });&#10;    ctx.fillStyle = &quot;#fff&quot;; ctx.font = &quot;bold 9px 'Comic Sans MS', sans-serif&quot;; ctx.textAlign = &quot;center&quot;;&#10;    ctx.fillText(&quot;PLAYA \u279c&quot;, 0, -3);&#10;    ctx.fillStyle = &quot;#333&quot;;&#10;    const giro = (t \/ 10) % (Math.PI * 2);&#10;    [-24, 24].forEach(rx =&gt; {&#10;        ctx.save(); ctx.translate(rx, 4); ctx.rotate(giro);&#10;        ctx.beginPath(); ctx.arc(0, 0, 6, 0, Math.PI * 2); ctx.fill();&#10;        ctx.strokeStyle = &quot;#aaa&quot;; ctx.lineWidth = 1;&#10;        ctx.beginPath(); ctx.moveTo(-6, 0); ctx.lineTo(6, 0); ctx.moveTo(0, -6); ctx.lineTo(0, 6); ctx.stroke();&#10;        ctx.restore();&#10;    });&#10;    ctx.restore();&#10;}&#10;function dibujarOlas(t, colorMar) {&#10;    ctx.fillStyle = colorMar;&#10;    ctx.fillRect(0, 90, 960, 260);&#10;    ctx.strokeStyle = &quot;rgba(255,255,255,0.65)&quot;; ctx.lineWidth = 3;&#10;    for (let fila = 0; fila &lt; 4; fila++) {&#10;        ctx.beginPath();&#10;        for (let px = 0; px &lt;= 960; px += 16) {&#10;            const py = 130 + fila * 55 + Math.sin(px \/ 40 + t \/ 15 + fila) * 8;&#10;            if (px === 0) ctx.moveTo(px, py); else ctx.lineTo(px, py);&#10;        }&#10;        ctx.stroke();&#10;    }&#10;}&#10;function dibujarTablaSurf(x, y, usando, t) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    const balanceo = usando ? Math.sin(t \/ 10) * 8 : 0;&#10;    ctx.rotate(usando ? Math.sin(t \/ 10) * 0.08 : 0);&#10;    ctx.fillStyle = &quot;#ffd166&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2.5;&#10;    ctx.beginPath();&#10;    ctx.ellipse(0, balanceo * 0.2, 34, 10, 0, 0, Math.PI * 2);&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.strokeStyle = &quot;#d6335a&quot;; ctx.lineWidth = 2;&#10;    ctx.beginPath(); ctx.moveTo(-30, balanceo * 0.2); ctx.lineTo(30, balanceo * 0.2); ctx.stroke();&#10;    ctx.restore();&#10;}&#10;function dibujarVelaWindsurf(x, y, usando, t) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.fillStyle = &quot;#8fd66a&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2.5;&#10;    ctx.beginPath();&#10;    ctx.ellipse(0, 8, 30, 9, 0, 0, Math.PI * 2);&#10;    ctx.fill(); ctx.stroke();&#10;    const inclinacion = usando ? Math.sin(t \/ 14) * 0.18 : 0.08;&#10;    ctx.save();&#10;    ctx.translate(0, 6);&#10;    ctx.rotate(inclinacion);&#10;    ctx.strokeStyle = &quot;#333&quot;; ctx.lineWidth = 3;&#10;    ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(0, -60); ctx.stroke();&#10;    ctx.fillStyle = &quot;#ff9ec7&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    ctx.beginPath();&#10;    ctx.moveTo(0, -58); ctx.quadraticCurveTo(28, -40, 18, -8); ctx.lineTo(0, -8);&#10;    ctx.closePath(); ctx.fill(); ctx.stroke();&#10;    ctx.restore();&#10;    ctx.restore();&#10;}&#10;function dibujarRocaConCana(x, y, escala = 1) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.scale(escala, escala);&#10;    ctx.fillStyle = &quot;#8d8d8d&quot;; ctx.strokeStyle = &quot;#4a4a4a&quot;; ctx.lineWidth = 2;&#10;    ctx.beginPath();&#10;    ctx.moveTo(-26, 10);&#10;    ctx.quadraticCurveTo(-30, -14, -8, -20);&#10;    ctx.quadraticCurveTo(16, -26, 26, -6);&#10;    ctx.quadraticCurveTo(30, 10, 10, 12);&#10;    ctx.quadraticCurveTo(-10, 16, -26, 10);&#10;    ctx.closePath();&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.strokeStyle = &quot;#6b6b6b&quot;; ctx.lineWidth = 1.5;&#10;    ctx.beginPath(); ctx.moveTo(-6, -14); ctx.lineTo(2, 4); ctx.stroke();&#10;    ctx.strokeStyle = &quot;#7a4a20&quot;; ctx.lineWidth = 3;&#10;    ctx.beginPath(); ctx.moveTo(14, 6); ctx.lineTo(46, -58); ctx.stroke();&#10;    ctx.strokeStyle = &quot;rgba(255,255,255,0.7)&quot;; ctx.lineWidth = 1;&#10;    ctx.beginPath(); ctx.moveTo(46, -58); ctx.lineTo(60, -10); ctx.stroke();&#10;    ctx.fillStyle = &quot;#e63946&quot;;&#10;    ctx.beginPath(); ctx.arc(60, -10, 3.5, 0, Math.PI * 2); ctx.fill();&#10;    ctx.restore();&#10;}&#10;function dibujarSombrillaPlaya(x, y, colorA, colorB) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.fillStyle = &quot;#fff&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 1.5;&#10;    ctx.fillRect(-22, 18, 44, 16);&#10;    ctx.strokeRect(-22, 18, 44, 16);&#10;    ctx.strokeStyle = &quot;#ff6b81&quot;; ctx.lineWidth = 2;&#10;    for (let i = -16; i &lt;= 16; i += 8) { ctx.beginPath(); ctx.moveTo(i, 18); ctx.lineTo(i, 34); ctx.stroke(); }&#10;    ctx.strokeStyle = &quot;#5a3d1e&quot;; ctx.lineWidth = 4;&#10;    ctx.beginPath(); ctx.moveTo(0, 20); ctx.lineTo(0, -46); ctx.stroke();&#10;    const radio = 34;&#10;    ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    for (let i = 0; i &lt; 8; i++) {&#10;        const a0 = Math.PI + (i \/ 8) * Math.PI, a1 = Math.PI + ((i + 1) \/ 8) * Math.PI;&#10;        ctx.fillStyle = i % 2 === 0 ? colorA : colorB;&#10;        ctx.beginPath();&#10;        ctx.moveTo(0, -46);&#10;        ctx.arc(0, -46, radio, a0, a1);&#10;        ctx.closePath();&#10;        ctx.fill(); ctx.stroke();&#10;    }&#10;    ctx.fillStyle = colorA;&#10;    ctx.beginPath(); ctx.arc(0, -46 - radio, 4, 0, Math.PI * 2); ctx.fill();&#10;    ctx.restore();&#10;}&#10;let _sprEscuela = null;&#10;function spriteEscuela() {&#10;    return _sprEscuela || (_sprEscuela = conLienzo(190, 134, () =&gt; {&#10;        const cx = 95, b = 130; ctx.lineWidth = 2; ctx.strokeStyle = '#000'; ctx.lineJoin = 'round';&#10;        sombra(cx, b + 2, 62, 6, 0.22);&#10;        [['#ff6fa8', -52, 0.18], ['#2fd6c0', -45, 0.1], ['#ffd54a', -38, 0.03]].forEach(([c, dx, rot]) =&gt; { ctx.save(); ctx.translate(cx + dx, b - 1); ctx.rotate(rot); ctx.fillStyle = c; ctx.beginPath(); ctx.ellipse(0, -29, 6, 30, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.strokeStyle = 'rgba(255,255,255,0.85)'; ctx.lineWidth = 1.4; ctx.beginPath(); ctx.moveTo(0, -56); ctx.lineTo(0, -4); ctx.stroke(); ctx.restore(); ctx.strokeStyle = '#000'; ctx.lineWidth = 2; });   \/\/ tablas de surf&#10;        ctx.save(); ctx.translate(cx - 57, b - 1); ctx.rotate(-0.12); ctx.fillStyle = '#7c5cff'; ctx.beginPath(); ctx.ellipse(0, -26, 5, 27, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#fff'; ctx.beginPath(); ctx.moveTo(0, -50); ctx.lineTo(13, -34); ctx.lineTo(0, -22); ctx.closePath(); ctx.fill(); ctx.stroke(); ctx.restore();                \/\/ tabla de windsurf con vela&#10;        ctx.fillStyle = '#a5703a'; ctx.fillRect(cx - 35, b - 78, 70, 78); ctx.strokeRect(cx - 35, b - 78, 70, 78);                                                                                 \/\/ paredes de tablones&#10;        ctx.strokeStyle = 'rgba(70,40,15,0.5)'; ctx.lineWidth = 1; ctx.beginPath(); for (let y = b - 70; y &lt; b; y += 8) { ctx.moveTo(cx - 35, y); ctx.lineTo(cx + 35, y); } ctx.stroke();&#10;        ctx.fillStyle = '#6b4a2b'; ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(cx - 44, b - 76); ctx.lineTo(cx + 44, b - 76); ctx.lineTo(cx + 38, b - 100); ctx.lineTo(cx - 38, b - 100); ctx.closePath(); ctx.fill(); ctx.stroke();      \/\/ tejado&#10;        ctx.fillStyle = '#1d3f7a'; ctx.beginPath(); ctx.moveTo(cx - 39, b - 79); ctx.lineTo(cx + 39, b - 79); ctx.lineTo(cx + 34, b - 97); ctx.lineTo(cx - 34, b - 97); ctx.closePath(); ctx.fill(); ctx.stroke();&#10;        ctx.strokeStyle = 'rgba(140,190,255,0.75)'; ctx.lineWidth = 0.8; ctx.beginPath(); for (let i = 1; i &lt; 8; i++) { const k = i \/ 8; ctx.moveTo(cx - 39 + 78 * k, b - 79); ctx.lineTo(cx - 34 + 68 * k, b - 97); } ctx.moveTo(cx - 37, b - 88); ctx.lineTo(cx + 37, b - 88); ctx.stroke();       \/\/ paneles solares&#10;        [[70, 225, 255, cx - 44, b - 76, cx + 44, b - 76], [255, 47, 209, cx - 12, b - 36, cx + 12, b - 36]].forEach(([r, g, bl, x1, y1, x2, y2], i) =&gt; {                                                 \/\/ ne\u00f3n&#10;            ctx.lineCap = 'round'; ctx.strokeStyle = `rgba(${r},${g},${bl},0.28)`; ctx.lineWidth = 6; ctx.beginPath(); if (!i) { ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); } else { ctx.moveTo(cx - 12, b); ctx.lineTo(cx - 12, b - 36); ctx.lineTo(cx + 12, b - 36); ctx.lineTo(cx + 12, b); } ctx.stroke();&#10;            ctx.strokeStyle = `rgba(${r},${g},${bl},0.95)`; ctx.lineWidth = 2.2; ctx.stroke(); });&#10;        ctx.fillStyle = '#10243f'; ctx.fillRect(cx - 10, b - 34, 20, 34); ctx.fillStyle = 'rgba(120,220,255,0.35)'; ctx.fillRect(cx - 8, b - 32, 6, 30);                                                  \/\/ puerta de cristal&#10;        [-24, 24].forEach(dx =&gt; { ctx.fillStyle = '#2b4a6b'; ctx.strokeStyle = 'rgba(70,225,255,0.95)'; ctx.lineWidth = 2; ctx.beginPath(); ctx.arc(cx + dx, b - 52, 6, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); });       \/\/ ojos de buey con ne\u00f3n&#10;        ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.fillStyle = '#1f7a68'; ctx.fillRect(cx - 44, b - 124, 88, 18); ctx.strokeRect(cx - 44, b - 124, 88, 18); ctx.beginPath(); ctx.moveTo(cx - 30, b - 106); ctx.lineTo(cx - 30, b - 100); ctx.moveTo(cx + 30, b - 106); ctx.lineTo(cx + 30, b - 100); ctx.stroke();&#10;        mTxtAjustado('ESCUELA DE SURF', cx + 8, b - 115, 8, '#fff', 66); mTxt('\ud83c\udfc4', cx - 34, b - 115, 10, '#000', 'center');&#10;        ctx.strokeStyle = '#4a4f55'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(cx + 40, b - 64); ctx.lineTo(cx + 40, b); ctx.moveTo(cx + 66, b - 64); ctx.lineTo(cx + 66, b); ctx.moveTo(cx + 38, b - 62); ctx.lineTo(cx + 68, b - 62); ctx.stroke();            \/\/ perchero&#10;        [['#2fd6c0', 46], ['#ff6fa8', 53.5], ['#ffd54a', 61]].forEach(([c, dx]) =&gt; {                                                                                                                \/\/ ropa l\u00edquida: trajes brillantes&#10;            ctx.fillStyle = c; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.2; ctx.fillRect(cx + dx - 4, b - 60, 8, 14); ctx.strokeRect(cx + dx - 4, b - 60, 8, 14); ctx.fillRect(cx + dx - 4, b - 46, 3.4, 16); ctx.strokeRect(cx + dx - 4, b - 46, 3.4, 16); ctx.fillRect(cx + dx + 0.6, b - 46, 3.4, 16); ctx.strokeRect(cx + dx + 0.6, b - 46, 3.4, 16);&#10;            ctx.strokeStyle = 'rgba(255,255,255,0.8)'; ctx.lineWidth = 1.4; ctx.beginPath(); ctx.moveTo(cx + dx - 2, b - 58); ctx.lineTo(cx + dx - 2, b - 48); ctx.stroke(); });&#10;    }));&#10;}&#10;function lerpE(a, b, k) { return a + (b - a) * k; }&#10;function dibujarCasetaPlaya(x, y) {                                                                      \/\/ ESCUELA DE SURF (sprite con ne\u00f3n y paneles solares)&#10;    ctx.drawImage(spriteEscuela(), x - 95, y - 130);&#10;}&#10;const gotasLluviaPlaya = [];&#10;for (let i = 0; i &lt; 60; i++) {&#10;    gotasLluviaPlaya.push({ x: Math.random() * 960, y: Math.random() * 540, vel: 6 + Math.random() * 4 });&#10;}&#10;const ZONA_VOLVER = { x: 20, y: 14, ancho: 190, alto: 34 };&#10;const ZONA_CLIMA = { x: 700, y: 14, ancho: 240, alto: 34 };&#10;const BOTONES_CLIMA = ['soleado', 'parcial', 'lluvia', 'viento'];&#10;const ICONOS_CLIMA = { soleado: '\u2600\ufe0f', parcial: '\u26c5', lluvia: '\ud83c\udf27\ufe0f', viento: '\ud83d\udca8' };&#10;function dibujarBotonVolver() {&#10;    return;   \/\/ sustituido por la barra de navegaci\u00f3n superior&#10;    const z = ZONA_VOLVER;&#10;    ctx.save();&#10;    const grad = ctx.createLinearGradient(z.x, 0, z.x + z.ancho, 0);&#10;    grad.addColorStop(0, '#ff69b4'); grad.addColorStop(1, '#6a3e8c');&#10;    ctx.fillStyle = grad;&#10;    ctx.strokeStyle = 'rgba(255,255,255,0.9)'; ctx.lineWidth = 2;&#10;    ctx.beginPath();&#10;    ctx.roundRect ? ctx.roundRect(z.x, z.y, z.ancho, z.alto, 17) : ctx.rect(z.x, z.y, z.ancho, z.alto);&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = '#fff';&#10;    ctx.font = &quot;bold 15px 'Comic Sans MS', sans-serif&quot;;&#10;    ctx.textAlign = 'center'; ctx.textBaseline = 'middle';&#10;    ctx.fillText('\u2190 Volver al pueblo', z.x + z.ancho \/ 2, z.y + z.alto \/ 2 + 1);&#10;    ctx.restore();&#10;}&#10;function dibujarSelectorClima() {&#10;    const z = ZONA_CLIMA;&#10;    ctx.save();&#10;    ctx.fillStyle = 'rgba(255,255,255,0.55)';&#10;    ctx.strokeStyle = '#fff'; ctx.lineWidth = 2;&#10;    ctx.beginPath();&#10;    ctx.roundRect ? ctx.roundRect(z.x, z.y, z.ancho, z.alto, 17) : ctx.rect(z.x, z.y, z.ancho, z.alto);&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.font = '20px Arial';&#10;    ctx.textAlign = 'center'; ctx.textBaseline = 'middle';&#10;    BOTONES_CLIMA.forEach((clima, i) =&gt; {&#10;        const cx = z.x + (i + 0.5) * (z.ancho \/ 4);&#10;        const cy = z.y + z.alto \/ 2;&#10;        if (clima === climaPlaya) {&#10;            ctx.fillStyle = 'rgba(255,255,255,0.95)';&#10;            ctx.strokeStyle = '#ff69b4';&#10;            ctx.lineWidth = 2;&#10;            ctx.beginPath(); ctx.arc(cx, cy, 15, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;        }&#10;        ctx.fillStyle = '#000';&#10;        ctx.fillText(ICONOS_CLIMA[clima], cx, cy + 1);&#10;    });&#10;    ctx.restore();&#10;}&#10;function tocoZonaVolver(x, y) {&#10;    return false;   \/\/ sin bot\u00f3n suelto: se navega con la barra superior&#10;    const z = ZONA_VOLVER;&#10;    return x &gt;= z.x &amp;&amp; x &lt;= z.x + z.ancho &amp;&amp; y &gt;= z.y &amp;&amp; y &lt;= z.y + z.alto;&#10;}&#10;function tocoZonaClima(x, y) {&#10;    const z = ZONA_CLIMA;&#10;    if (x &lt; z.x || x &gt; z.x + z.ancho || y &lt; z.y || y &gt; z.y + z.alto) return null;&#10;    const idx = Math.max(0, Math.min(3, Math.floor((x - z.x) \/ (z.ancho \/ 4))));&#10;    return BOTONES_CLIMA[idx];&#10;}&#10;function salirDeEscena() {&#10;    KutxaPanel.cerrar();&#10;    casaAbierta = null;&#10;    enGimnasio = false; enArena = false; enHospital = false;&#10;    if (enPlaya || enPuerto || enSubmarino) {&#10;        [...habitantesEnPlaya].forEach(h =&gt; volverDeLaPlaya(h));&#10;    }&#10;    enPlaya = false; enPuerto = false; enSubmarino = false;&#10;    enHuerta = false;&#10;    enMercado = false; mercadoPanel = null; enIndustria = false; enBiblioteca = false;&#10;    bancoAbierto = false;&#10;    dialogoCosecha = null;&#10;}&#10;function dibujarPlaya(t) {&#10;    const climas = {&#10;        soleado: { cieloA: &quot;#bfe4ff&quot;, cieloB: &quot;#e8f7ff&quot;, mar: &quot;#3aa0d6&quot;, sol: true, nubes: 0, lluvia: false, viento: 0 },&#10;        parcial: { cieloA: &quot;#a9c9dd&quot;, cieloB: &quot;#d7e7ee&quot;, mar: &quot;#4a92b0&quot;, sol: true, nubes: 3, lluvia: false, viento: 0.4 },&#10;        lluvia:  { cieloA: &quot;#6f7d8a&quot;, cieloB: &quot;#9aa7b0&quot;, mar: &quot;#4f6570&quot;, sol: false, nubes: 5, lluvia: true, viento: 0.6 },&#10;        viento:  { cieloA: &quot;#9fc7de&quot;, cieloB: &quot;#d3e6ee&quot;, mar: &quot;#3a8fae&quot;, sol: true, nubes: 4, lluvia: false, viento: 1.4 }&#10;    };&#10;    const c = climas[climaPlaya] || climas.parcial;&#10;    const cielo = ctx.createLinearGradient(0, 0, 0, 90);&#10;    cielo.addColorStop(0, c.cieloA);&#10;    cielo.addColorStop(1, c.cieloB);&#10;    ctx.fillStyle = cielo;&#10;    ctx.fillRect(0, 0, 960, 90);&#10;    if (c.sol &amp;&amp; !nochePlaya) dibujarSol(870, 40, t);&#10;    if (c.nubes &gt; 0) {&#10;        ctx.fillStyle = &quot;rgba(255,255,255,0.8)&quot;;&#10;        for (let i = 0; i &lt; c.nubes; i++) {&#10;            const nx = ((i * 210 + t * c.viento) % 1100) - 70;&#10;            const ny = 25 + (i % 3) * 20;&#10;            const r = 24 + (i % 2) * 8;&#10;            ctx.beginPath();&#10;            ctx.ellipse(nx, ny, r, r * 0.55, 0, 0, Math.PI * 2);&#10;            ctx.fill();&#10;        }&#10;    }&#10;    dibujarOlas(t + (c.viento &gt; 0.5 ? t * c.viento * 0.5 : 0), c.mar);&#10;    Puerto.dibujarTrafico();                                                              \/\/ yate y barco solar aut\u00f3nomos&#10;    ctx.fillStyle = &quot;#f2d9a1&quot;;&#10;    ctx.fillRect(0, 350, 960, 190);&#10;    Puerto.dibujarPasarela();                                                             \/\/ pasarela de madera con farolas LED y muelle del puerto&#10;    dibujarRocaConCana(50, 355, 1.8);&#10;    dibujarSombrillaPlaya(350, 400, &quot;#ff6b6b&quot;, &quot;#fff8ea&quot;);&#10;    dibujarSombrillaPlaya(610, 400, &quot;#4a90d9&quot;, &quot;#fff8ea&quot;);&#10;    dibujarCasetaPlaya(730, 400);&#10;    if (c.lluvia) {&#10;        ctx.strokeStyle = &quot;rgba(210,225,235,0.6)&quot;;&#10;        ctx.lineWidth = 1.5;&#10;        gotasLluviaPlaya.forEach(g =&gt; {&#10;            const y = (g.y + t * g.vel) % 540;&#10;            ctx.beginPath();&#10;            ctx.moveTo(g.x, y);&#10;            ctx.lineTo(g.x - 4, y + 14);&#10;            ctx.stroke();&#10;        });&#10;    }&#10;    ctx.fillStyle = &quot;#ff9f43&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2.5;&#10;    ctx.fillRect(960 \/ 2 - 90, 14, 180, 34);&#10;    ctx.strokeRect(960 \/ 2 - 90, 14, 180, 34);&#10;    ctx.fillStyle = &quot;#fff&quot;;&#10;    ctx.font = &quot;bold 17px 'Comic Sans MS', sans-serif&quot;;&#10;    ctx.textAlign = &quot;center&quot;;&#10;    ctx.fillText(&quot;\ud83c\udfd6\ufe0f LA PLAYA \ud83c\udfd6\ufe0f&quot;, 960 \/ 2, 36);&#10;    const enSurf = habitantesEnPlaya.some(h =&gt; h.playaEstado === 'surfeando');&#10;    const enWindsurf = habitantesEnPlaya.some(h =&gt; h.playaEstado === 'windsurf');&#10;    dibujarTablaSurf(ZONA_SURF.x, ZONA_SURF.y, enSurf, t);&#10;    dibujarVelaWindsurf(ZONA_WINDSURF.x, ZONA_WINDSURF.y, enWindsurf, t);&#10;    dibujarEscenarioPlayaNuevo(t);&#10;    Costa.dibujarPlaya(t);                                                               \/\/ Genoides costeras, brazos rob\u00f3ticos, residuos y algas                                                         \/\/ barquito, resort, chiringuito y helader\u00eda voladora&#10;    habitantesEnPlaya.forEach((h, i) =&gt; {&#10;        if (!h.posPlaya) h.posPlaya = { x: 470, y: 420 };&#10;        if (h.playaEstado === 'surfeando') {&#10;            h.posPlaya.x = ZONA_SURF.x;&#10;            h.posPlaya.y = ZONA_SURF.y + Math.sin(t \/ 10) * 8 - 18;&#10;        } else if (h.playaEstado === 'windsurf') {&#10;            h.posPlaya.x = ZONA_WINDSURF.x;&#10;            h.posPlaya.y = ZONA_WINDSURF.y - 18;&#10;        } else if (h.zonaPlaya) {&#10;            h.posPlaya.x = h.zonaPlaya.x;&#10;            h.posPlaya.y = h.zonaPlaya.y;&#10;        }&#10;        if (h.zonaPlaya &amp;&amp; (h.zonaPlaya.accion === 'moto' || h.zonaPlaya.accion === 'bucear')) return;     \/\/ a bordo de la moto de agua o buceando&#10;        const bamboleo = Math.sin(t \/ 25 + i) * 0.05;&#10;        ctx.save();&#10;        ctx.translate(h.posPlaya.x, h.posPlaya.y);&#10;        if (h.zonaPlaya &amp;&amp; h.zonaPlaya.rot) ctx.rotate(h.zonaPlaya.rot);                  \/\/ tumbada en la tumbona&#10;        ctx.scale(1.1, 1.1);&#10;        dibujarMu\u00f1eca({ x: 0, y: 0, angulo: bamboleo }, h.colorPelo, false, !!h.miraPlayaDerecha, false, h.estilo); accesorioFiesta(0, 0, h.miraPlayaDerecha ? -1 : 1);&#10;        ctx.restore();&#10;        if (h.equipoSurf &amp;&amp; !h.zonaPlaya) Costa.dibujarEquipo(h);                                          \/\/ lleva su tabla bajo el brazo&#10;        if (h.zonaPlaya &amp;&amp; h.zonaPlaya.pose === 'agua') aguaBano(h.posPlaya.x, h.posPlaya.y, t);&#10;        if (h.zonaPlaya) {&#10;            ctx.font = &quot;22px Arial&quot;;&#10;            ctx.textAlign = &quot;center&quot;;&#10;            ctx.fillText(h.zonaPlaya.icono, h.posPlaya.x, h.posPlaya.y - 45);&#10;        }&#10;    });&#10;    Costa.dibujarPlayaFrente(t);                                                          \/\/ puesto de algas y decoraci\u00f3n de fiestas, por delante de las chicas&#10;    dibujarFrentePlayaNuevo(t);&#10;    dibujarSelectorClima();&#10;    dibujarBotonVolver();&#10;}&#10;function dibujarGimnasio(t) {&#10;    ctx.fillStyle = &quot;#ffe3d1&quot;;&#10;    ctx.fillRect(0, 0, canvas.width, canvas.height * 0.55);&#10;    ctx.fillStyle = &quot;#e0a978&quot;;&#10;    ctx.fillRect(0, canvas.height * 0.55, canvas.width, canvas.height * 0.45);&#10;    ctx.strokeStyle = &quot;rgba(0,0,0,0.1)&quot;; ctx.lineWidth = 2;&#10;    for (let i = 0; i &lt; 12; i++) {&#10;        ctx.beginPath();&#10;        ctx.moveTo(i * (canvas.width \/ 12), canvas.height * 0.55);&#10;        ctx.lineTo(i * (canvas.width \/ 12), canvas.height);&#10;        ctx.stroke();&#10;    }&#10;    ctx.fillStyle = &quot;#ff9f43&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2.5;&#10;    ctx.fillRect(canvas.width \/ 2 - 110, 14, 220, 40);&#10;    ctx.strokeRect(canvas.width \/ 2 - 110, 14, 220, 40);&#10;    ctx.fillStyle = &quot;#fff&quot;;&#10;    ctx.font = &quot;bold 20px 'Comic Sans MS', sans-serif&quot;;&#10;    ctx.textAlign = &quot;center&quot;;&#10;    ctx.fillText(&quot;\ud83d\udcaa GIMNASIO \ud83d\udcaa&quot;, canvas.width \/ 2, 40);&#10;    dibujarBici(ZONA_BICI1.x, ZONA_BICI1.y, gimnasioChicas.some(c =&gt; c.zonaActiva === ZONA_BICI1), t);&#10;    dibujarBici(ZONA_BICI2.x, ZONA_BICI2.y, gimnasioChicas.some(c =&gt; c.zonaActiva === ZONA_BICI2), t);&#10;    dibujarPesas(ZONA_PESAS.x, ZONA_PESAS.y);&#10;    dibujarPiscina(ZONA_PISCINA.x - 90, ZONA_PISCINA.y - 40, 180, 110, t);&#10;    dibujarGimnasioExtra(t);                                                              \/\/ interior de la piscina, m\u00e1quinas, esterillas, vending y banco&#10;    gimnasioChicas.forEach(c =&gt; {&#10;        if (c.estado === 'nadando') dibujarChapoteo(c.x, c.y, t);&#10;    });&#10;    gimnasioChicas.forEach(c =&gt; {&#10;        const bamboleo = Math.sin(t \/ 25 + c.x) * 0.05;&#10;        ctx.save();&#10;        ctx.translate(c.x, c.y);&#10;        poseGimnasio(c, t);&#10;        ctx.scale(1.1, 1.1);&#10;        dibujarMu\u00f1eca({ x: 0, y: 0, angulo: bamboleo }, c.colorPelo, false, false, false, c.estilo); accesorioFiesta(0, 0, 1);&#10;        ctx.restore();&#10;        if (c.estado === 'levantando') {&#10;            dibujarMancuernaEnUso(c.x - 14, c.y, t);&#10;            dibujarMancuernaEnUso(c.x + 14, c.y, t + 6);&#10;        }&#10;        dibujarExtrasGimnasio(c, t);&#10;        if (c.estado !== 'de_pie') {&#10;            const zona = ZONAS_GIMNASIO.find(z =&gt; z.accion === c.estado);&#10;            if (zona) {&#10;                ctx.font = &quot;20px Arial&quot;;&#10;                ctx.textAlign = &quot;center&quot;;&#10;                ctx.fillText((c.zonaActiva || zona).icono, c.x, c.y - 50);&#10;            }&#10;        }&#10;    });&#10;    dibujarFiestaGimnasio(t);&#10;    dibujarBotonVolver();&#10;}&#10;const CHEQUEO_MS = 45000;&#10;let chequeoInicio = 0, chequeoFin = 0;&#10;const ZONA_CAMILLA = { x: 338, y: 392, accion: 'chequeo', icono: '\ud83e\ude7a' };&#10;const ZONA_MOCHILA = { x: 209, y: 252, accion: 'sos',     icono: '\ud83c\udf92' };&#10;function dibujarCamillaTelemedicina(t) {&#10;    const x = 290, y = 412, act = interiorEstado === 'chequeo';&#10;    ctx.save(); ctx.strokeStyle = '#000'; ctx.lineWidth = 2.5;&#10;    ctx.fillStyle = '#9aa4ad'; [x + 8, x + 82].forEach(lx =&gt; { ctx.fillRect(lx, y + 12, 6, 26); });   \/\/ patas&#10;    ctx.fillStyle = '#4a4f57'; [x + 11, x + 85].forEach(lx =&gt; { ctx.beginPath(); ctx.arc(lx, y + 41, 4, 0, Math.PI * 2); ctx.fill(); });&#10;    ctx.fillStyle = '#e8f4f8'; ctx.fillRect(x, y, 96, 14); ctx.strokeRect(x, y, 96, 14);            \/\/ colch\u00f3n&#10;    ctx.fillStyle = '#ffffff'; ctx.fillRect(x + 4, y - 6, 24, 8); ctx.strokeRect(x + 4, y - 6, 24, 8);  \/\/ almohada&#10;    ctx.fillStyle = act ? '#7cffd9' : '#38bdf8'; ctx.fillRect(x + 40, y + 3, 16, 3); ctx.fillRect(x + 46, y - 1, 4, 11);   \/\/ cruz m\u00e9dica&#10;    ctx.strokeStyle = '#5a6066'; ctx.lineWidth = 3;                                                  \/\/ poste del monitor&#10;    ctx.beginPath(); ctx.moveTo(x + 110, y + 40); ctx.lineTo(x + 110, y - 24); ctx.stroke();&#10;    ctx.fillStyle = '#20262e'; ctx.strokeStyle = '#000'; ctx.lineWidth = 2;&#10;    ctx.fillRect(x + 96, y - 46, 28, 22); ctx.strokeRect(x + 96, y - 46, 28, 22);                   \/\/ pantalla&#10;    ctx.strokeStyle = act ? '#7cffd9' : '#2a7a63'; ctx.lineWidth = 1.5; ctx.beginPath();&#10;    for (let i = 0; i &lt;= 24; i++) { const yy = y - 35 - (act &amp;&amp; i % 8 === 4 ? 7 : 0) + (act ? Math.sin((i + t \/ 3) * 0.9) * 1.2 : 0); i ? ctx.lineTo(x + 98 + i, yy) : ctx.moveTo(x + 98, yy); }&#10;    ctx.stroke(); ctx.restore();&#10;}&#10;function dibujarMochilaSOS(t) {&#10;    const x = 196, y = 214, pulso = 0.5 + 0.5 * Math.sin(t \/ 15);        \/\/ colgada de la pared de la habitaci\u00f3n&#10;    ctx.save(); ctx.lineWidth = 2.5; ctx.strokeStyle = '#000';&#10;    ctx.fillStyle = '#8a5a2b'; ctx.fillRect(x - 8, y - 20, 42, 7); ctx.strokeRect(x - 8, y - 20, 42, 7);   \/\/ tabla de la percha&#10;    ctx.fillStyle = '#c7cdd3'; ctx.beginPath(); ctx.arc(x + 13, y - 12, 3.5, 0, Math.PI * 2); ctx.fill(); ctx.stroke();   \/\/ gancho&#10;    ctx.fillStyle = 'rgba(0,0,0,0.16)'; ctx.fillRect(x + 4, y + 4, 26, 36);                                 \/\/ sombra en la pared&#10;    ctx.lineWidth = 2; ctx.beginPath(); ctx.arc(x + 13, y - 3, 8, Math.PI, 0); ctx.stroke();                 \/\/ asa colgando del gancho&#10;    ctx.lineWidth = 2.5; ctx.fillStyle = '#b3243f'; ctx.beginPath(); ctx.roundRect ? ctx.roundRect(x, y, 26, 36, 8) : ctx.rect(x, y, 26, 36); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = '#d6335a'; ctx.fillRect(x + 4, y + 20, 18, 12); ctx.strokeRect(x + 4, y + 20, 18, 12);   \/\/ bolsillo&#10;    ctx.fillStyle = '#fff'; ctx.fillRect(x + 11, y + 6, 4, 11); ctx.fillRect(x + 7.5, y + 9.5, 11, 4);       \/\/ cruz&#10;    ctx.font = &quot;bold 9px 'Comic Sans MS', sans-serif&quot;; ctx.textAlign = 'center'; ctx.fillText('SOS', x + 13, y + 29);&#10;    ctx.fillStyle = `rgba(124,255,217,${0.4 + 0.5 * pulso})`; ctx.beginPath(); ctx.arc(x + 22, y + 4, 2.5, 0, Math.PI * 2); ctx.fill();   \/\/ LED&#10;    ctx.restore();&#10;}&#10;function dibujarOverlaysInterior(casa, t) {&#10;    if (interiorEstado === 'chequeo' &amp;&amp; Date.now() - chequeoInicio &gt;= CHEQUEO_MS) {&#10;        interiorEstado = 'de_pie'; temporizadorInterior = 0; chequeoFin = Date.now(); nuevoResultadoChequeo();&#10;    }&#10;    const activo = interiorEstado === 'chequeo';&#10;    const rojo = !activo &amp;&amp; chequeoRes &amp;&amp; chequeoRes.pendiente &amp;&amp; chequeoRes.casa === casaAbierta;                       \/\/ requiere medicinas&#10;    const verde = !activo &amp;&amp; chequeoRes &amp;&amp; !chequeoRes.necesita &amp;&amp; chequeoRes.casa === casaAbierta &amp;&amp; chequeoFin &amp;&amp; Date.now() - chequeoFin &lt; 6000;   \/\/ todo en orden&#10;    if (activo || rojo || verde) {&#10;        const { x: hx, y: hy, w, h } = HOLO, seg = activo ? Math.min(45, (Date.now() - chequeoInicio) \/ 1000) : 45;&#10;        const col = rojo ? '#ff0000' : verde ? '#00ff00' : '#8cf5ff';                                    \/\/ colores puros; cian mientras mide&#10;        const rel = rojo ? 'rgba(255,0,0,0.22)' : verde ? 'rgba(0,255,0,0.20)' : 'rgba(40,190,235,0.22)';&#10;        ctx.save();&#10;        const haz = ctx.createLinearGradient(0, hy + h, 0, ZONA_CAMILLA.y);&#10;        haz.addColorStop(0, rojo ? 'rgba(255,0,0,0.28)' : verde ? 'rgba(0,255,0,0.26)' : 'rgba(90,230,255,0.28)'); haz.addColorStop(1, 'rgba(255,255,255,0)');&#10;        ctx.fillStyle = haz; ctx.beginPath(); ctx.moveTo(hx + 30, hy + h); ctx.lineTo(hx + w - 30, hy + h); ctx.lineTo(ZONA_CAMILLA.x + 14, ZONA_CAMILLA.y + 20); ctx.lineTo(ZONA_CAMILLA.x - 14, ZONA_CAMILLA.y + 20); ctx.fill();&#10;        ctx.fillStyle = rel; ctx.strokeStyle = col; ctx.lineWidth = 2;&#10;        ctx.beginPath(); ctx.roundRect ? ctx.roundRect(hx, hy, w, h, 10) : ctx.rect(hx, hy, w, h); ctx.fill(); ctx.stroke();&#10;        ctx.save(); ctx.translate(hx + 44, hy + 62); ctx.globalAlpha = 0.6 + 0.15 * Math.sin(t \/ 8);                     \/\/ holograma de la chica&#10;        dibujarMu\u00f1eca({ x: 0, y: 0, angulo: 0 }, casa.colorPelo, false, false, false, casa.estilo); ctx.restore();&#10;        if (activo) { ctx.fillStyle = 'rgba(190,255,255,0.55)'; ctx.fillRect(hx + 6, hy + 14 + ((t * 1.2) % 90) * 0.9, 80, 2); }   \/\/ barrido de escaneo&#10;        const bx = hx + 124, by = hy + 50;                                                                                \/\/ indicador: sin texto&#10;        if (activo) {                                                                                                     \/\/ anillo de progreso&#10;            ctx.strokeStyle = 'rgba(255,255,255,0.25)'; ctx.lineWidth = 5; ctx.beginPath(); ctx.arc(bx, by, 22, 0, Math.PI * 2); ctx.stroke();&#10;            ctx.strokeStyle = col; ctx.beginPath(); ctx.arc(bx, by, 22, -Math.PI \/ 2, -Math.PI \/ 2 + Math.PI * 2 * seg \/ 45); ctx.stroke();&#10;        } else {                                                                                                          \/\/ disco de color puro&#10;            const r = 22 + 2 * Math.sin(t \/ 10), g = ctx.createRadialGradient(bx, by, 4, bx, by, r + 14);&#10;            g.addColorStop(0, col); g.addColorStop(0.6, col); g.addColorStop(1, 'rgba(255,255,255,0)');&#10;            ctx.fillStyle = g; ctx.beginPath(); ctx.arc(bx, by, r + 14, 0, Math.PI * 2); ctx.fill();&#10;            ctx.fillStyle = col; ctx.beginPath(); ctx.arc(bx, by, r, 0, Math.PI * 2); ctx.fill();&#10;            if (rojo) {                                                                                                   \/\/ cajita = &quot;toca para enviar&quot;&#10;                ctx.strokeStyle = '#fff'; ctx.lineWidth = 2; ctx.globalAlpha = 0.6 + 0.4 * Math.sin(t \/ 8);&#10;                ctx.strokeRect(bx - 10, by + 44, 20, 15); ctx.beginPath(); ctx.moveTo(bx - 10, by + 51); ctx.lineTo(bx + 10, by + 51); ctx.moveTo(bx, by + 44); ctx.lineTo(bx, by + 59); ctx.stroke(); ctx.globalAlpha = 1;&#10;            }&#10;        }&#10;        ctx.strokeStyle = col; ctx.lineWidth = 1.3; ctx.beginPath();                                                      \/\/ electrocardiograma&#10;        for (let i = 0; i &lt;= 156; i += 2) { const yy = hy + h - 30 - (i % 52 === 26 ? 12 : 0) - (i % 52 === 30 ? -5 : 0) + Math.sin((i + t) * 0.3) * 0.8; i ? ctx.lineTo(hx + 8 + i, yy) : ctx.moveTo(hx + 8, yy); }&#10;        ctx.stroke();&#10;        if (activo) { ctx.fillStyle = 'rgba(255,255,255,0.25)'; ctx.fillRect(hx + 8, hy + h - 16, 156, 6); ctx.fillStyle = col; ctx.fillRect(hx + 8, hy + h - 16, 156 * seg \/ 45, 6); }&#10;        ctx.restore();&#10;    }&#10;    if (interiorEstado === 'sos') {&#10;        const x = 24, y = 36, w = 322, h = 128;&#10;        ctx.save(); ctx.fillStyle = 'rgba(255,248,234,0.96)'; ctx.strokeStyle = '#b3243f'; ctx.lineWidth = 3;&#10;        ctx.beginPath(); ctx.roundRect ? ctx.roundRect(x, y, w, h, 14) : ctx.rect(x, y, w, h); ctx.fill(); ctx.stroke();&#10;        ctx.textAlign = 'left'; ctx.fillStyle = '#b3243f'; ctx.font = &quot;bold 16px 'Comic Sans MS', sans-serif&quot;;&#10;        ctx.fillText('\ud83c\udf92 Mochila SOS \u00b7 Resiliencia comunitaria', x + 14, y + 28);&#10;        ctx.fillStyle = '#4a3a2a'; ctx.font = &quot;13px 'Comic Sans MS', sans-serif&quot;;&#10;        ['Agua, botiqu\u00edn, linterna solar y radio,', 'listos junto a la puerta para quien los necesite.', 'Nadie afronta una emergencia sola:', 'el pueblo se cuida entre todas. \ud83d\udc9c'].forEach((l, i) =&gt; ctx.fillText(l, x + 14, y + 54 + i * 21));&#10;        ctx.restore();&#10;    }&#10;}&#10;const SUMINISTROS = [['\ud83d\udc8a', 'analg\u00e9sico'], ['\ud83e\ude79', 'ap\u00f3sitos'], ['\ud83e\uddf4', 'suero oral'], ['\ud83c\udf3f', 'infusi\u00f3n']];&#10;const HOLO = { x: 252, y: 170, w: 172, h: 122 };                  \/\/ holograma, sobre la camilla&#10;const HYP_CASA = { tuboX: 540, terminalY: 246 };                   \/\/ tubo vertical en la pared, a la derecha de la ventana&#10;const T_VIAJE = 5000, T_ENTREGA = 11000, T_FIN = 17000;&#10;let chequeoRes = null;                                             \/\/ { casa, pendiente, items }&#10;let pedidoHyp = null;                                              \/\/ { casa, items, t0, entregado }&#10;const botiquinCasas = {};                                          \/\/ suministros recibidos por casa&#10;function nuevoResultadoChequeo() {                                 \/\/ se llama al terminar los 45 s&#10;    const necesita = Math.random() &lt; 0.6;&#10;    const pool = [...SUMINISTROS].sort(() =&gt; Math.random() - 0.5).slice(0, 2);&#10;    chequeoRes = { casa: casaAbierta, necesita, pendiente: necesita, items: pool };   \/\/ pendiente = rojo hasta enviar el pedido&#10;}&#10;function manejarToqueHologramaPedido(x, y) {                       \/\/ toque en el holograma ROJO = pedir por Hyperloop&#10;    if (!chequeoRes || !chequeoRes.pendiente || chequeoRes.casa !== casaAbierta || interiorEstado === 'chequeo') return false;&#10;    if (!dentroRect(x, y, HOLO)) return false;&#10;    pedidoHyp = { casa: casaAbierta, items: chequeoRes.items, t0: Date.now(), entregado: false };&#10;    chequeoRes.pendiente = false;&#10;    try { ventasHoy.unshift({ puesto: 'Botiqu\u00edn comunitario', txt: chequeoRes.items.map(i =&gt; i[0]).join(' ') + ' \u2192 Casa', tok: 0 }); } catch (e) {}&#10;    return true;&#10;}&#10;function dibujarTerminalHyperloopCasa(t) {                         \/\/ accesorio fijo de la casa (tubo + terminal)&#10;    const x = HYP_CASA.tuboX, ty = HYP_CASA.terminalY, p = pedidoHyp &amp;&amp; pedidoHyp.casa === casaAbierta ? pedidoHyp : null;&#10;    const el = p ? Date.now() - p.t0 : -1, entrega = p &amp;&amp; el &gt;= T_VIAJE &amp;&amp; el &lt; T_ENTREGA;&#10;    ctx.save();&#10;    ctx.fillStyle = 'rgba(190,240,255,0.35)'; ctx.strokeStyle = '#9fd6e8'; ctx.lineWidth = 2;        \/\/ tubo acristalado&#10;    ctx.beginPath(); ctx.roundRect ? ctx.roundRect(x + 4, 0, 20, ty, 6) : ctx.rect(x + 4, 0, 20, ty); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = '#aab2ba'; ctx.strokeStyle = '#4a4f57'; ctx.lineWidth = 2;                       \/\/ terminal&#10;    ctx.fillRect(x - 4, ty, 36, 44); ctx.strokeRect(x - 4, ty, 36, 44);&#10;    ctx.fillStyle = '#20262e'; ctx.font = &quot;bold 6px 'Comic Sans MS', sans-serif&quot;; ctx.textAlign = 'center'; ctx.fillText('HYPERLOOP', x + 14, ty + 38);&#10;    ctx.fillStyle = entrega ? (Math.sin(t \/ 4) &gt; 0 ? '#7cffd9' : '#2a7a63') : '#3a3f45';&#10;    ctx.beginPath(); ctx.arc(x + 14, ty + 30, 3, 0, Math.PI * 2); ctx.fill();&#10;    ctx.save(); ctx.translate(x - 2, ty); ctx.rotate(entrega ? -0.9 : 0);                              \/\/ escotilla&#10;    ctx.fillStyle = '#c7cdd3'; ctx.fillRect(0, -3, 32, 6); ctx.strokeRect(0, -3, 32, 6); ctx.restore();&#10;    if (p &amp;&amp; el &lt; T_VIAJE) {                                                                            \/\/ c\u00e1psula bajando&#10;        const f = el \/ T_VIAJE, e = f * f * (3 - 2 * f), cy = -34 + (ty - 30 + 34) * e;&#10;        const g = ctx.createLinearGradient(x + 6, 0, x + 22, 0); g.addColorStop(0, '#f4f6f8'); g.addColorStop(1, '#8f979f');&#10;        ctx.fillStyle = g; ctx.beginPath(); ctx.roundRect ? ctx.roundRect(x + 7, cy, 14, 30, 6) : ctx.rect(x + 7, cy, 14, 30); ctx.fill(); ctx.stroke();&#10;        ctx.fillStyle = '#7cffd9'; [6, 14, 22].forEach(d =&gt; { ctx.beginPath(); ctx.arc(x + 14, cy + d, 1.6, 0, Math.PI * 2); ctx.fill(); });&#10;    } else if (entrega) {&#10;        p.items.forEach((it, k) =&gt; { ctx.font = '20px Arial'; ctx.fillText(it[0], x + 4 + k * 22, ty - 12 - Math.min(14, (el - T_VIAJE) \/ 60) - Math.sin(t \/ 10 + k) * 2); });&#10;    }&#10;    ctx.restore();&#10;}&#10;function dibujarPedidoHyperloop(casa, t) {                          \/\/ botones bajo el holograma + estado del pedido&#10;    const p = pedidoHyp; if (!p || p.casa !== casaAbierta) return;&#10;    const el = Date.now() - p.t0;&#10;    if (el &gt;= T_ENTREGA &amp;&amp; !p.entregado) {                          \/\/ entregado: pasa al botiqu\u00edn de la casa&#10;        p.entregado = true; const b = botiquinCasas[p.casa] = botiquinCasas[p.casa] || {};&#10;        p.items.forEach(i =&gt; { b[i[0]] = (b[i[0]] || 0) + 1; });&#10;    }&#10;    if (el &gt;= T_FIN) { pedidoHyp = null; return; }&#10;    const msg = el &lt; T_VIAJE ? `\ud83d\udce6 Pedido enviado por Hyperloop \u00b7 llega en ${Math.ceil((T_VIAJE - el) \/ 1000)} s` : el &lt; T_ENTREGA ? '\ud83d\udfe2 C\u00e1psula en la terminal\u2026' : '\u2714 Recibido: ' + p.items.map(i =&gt; i[0] + ' ' + i[1]).join(', ');&#10;    ctx.save(); ctx.font = &quot;bold 13px 'Comic Sans MS', sans-serif&quot;; const w = ctx.measureText(msg).width + 28;&#10;    ctx.fillStyle = 'rgba(30,58,50,0.92)'; ctx.strokeStyle = '#7cffd9'; ctx.lineWidth = 1.5;&#10;    ctx.beginPath(); ctx.roundRect ? ctx.roundRect(338 - w \/ 2, 312, w, 28, 14) : ctx.rect(338 - w \/ 2, 312, w, 28); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = '#fff'; ctx.textAlign = 'center'; ctx.fillText(msg, 338, 331); ctx.restore();&#10;}&#10;function dibujarInterior(casa, t) {&#10;    ctx.clearRect(0, 0, canvas.width, canvas.height);&#10;    const anchoPrincipal = ANCHO_PRINCIPAL;&#10;    if (!posInterior) posInterior = { x: anchoPrincipal * 0.5, y: canvas.height * 0.86 };&#10;    let dormidosAqui = habitantes.filter(h =&gt; h.durmiendo &amp;&amp; h.casaAsignada === casaAbierta);&#10;    const duo = dormidosAqui.find(h =&gt; h.pareja &amp;&amp; dormidosAqui.includes(h.pareja));&#10;    if (duo) dormidosAqui = [duo, duo.pareja, ...dormidosAqui.filter(o =&gt; o !== duo &amp;&amp; o !== duo.pareja)];&#10;    const escenaNocturna = dormidosAqui.length &gt; 0;                      \/\/ cualquiera que duerma aqu\u00ed se tumba: en la cama, en el sof\u00e1 o en una colchoneta&#10;    const esNoche = !esDeDia(); \/\/ controla la ventana de TODAS las casas, haya o no alguien durmiendo&#10;    ctx.fillStyle = casa.pared;&#10;    ctx.fillRect(0, 0, anchoPrincipal, canvas.height * 0.62);&#10;    ctx.fillStyle = &quot;#d8b382&quot;;&#10;    ctx.fillRect(0, canvas.height * 0.62, anchoPrincipal, canvas.height * 0.38);&#10;    ctx.strokeStyle = &quot;rgba(0,0,0,0.15)&quot;; ctx.lineWidth = 2;&#10;    for (let i = 0; i &lt; 7; i++) {&#10;        ctx.beginPath();&#10;        ctx.moveTo(i * (anchoPrincipal \/ 7), canvas.height * 0.62);&#10;        ctx.lineTo(i * (anchoPrincipal \/ 7) - 20, canvas.height);&#10;        ctx.stroke();&#10;    }&#10;    const vx = anchoPrincipal * 0.62, vy = 40, vw = anchoPrincipal * 0.28, vh = 100;&#10;    const cieloV = ctx.createLinearGradient(0, vy, 0, vy + vh);&#10;    if (esNoche) {&#10;        cieloV.addColorStop(0, &quot;#0d1130&quot;);&#10;        cieloV.addColorStop(1, &quot;#2a1d47&quot;);&#10;    } else {&#10;        cieloV.addColorStop(0, &quot;#bfe4ff&quot;);&#10;        cieloV.addColorStop(1, &quot;#e8f7ff&quot;);&#10;    }&#10;    ctx.fillStyle = cieloV;&#10;    ctx.fillRect(vx, vy, vw, vh);&#10;    if (esNoche) {&#10;        ctx.fillStyle = &quot;#f2f2e8&quot;;&#10;        ctx.beginPath(); ctx.arc(vx + vw * 0.7, vy + vh * 0.35, 10, 0, Math.PI * 2); ctx.fill();&#10;        ctx.fillStyle = &quot;rgba(255,255,255,0.8)&quot;;&#10;        for (let i = 0; i &lt; 6; i++) {&#10;            ctx.beginPath();&#10;            ctx.arc(vx + (vw * (i + 0.5)) \/ 6, vy + vh * (0.15 + 0.5 * ((i * 37) % 5) \/ 5), 1.2, 0, Math.PI * 2);&#10;            ctx.fill();&#10;        }&#10;    }&#10;    ctx.strokeStyle = &quot;#7a4a2b&quot;; ctx.lineWidth = 7;&#10;    ctx.strokeRect(vx, vy, vw, vh);&#10;    ctx.lineWidth = 3;&#10;    ctx.beginPath();&#10;    ctx.moveTo(vx + vw\/2, vy); ctx.lineTo(vx + vw\/2, vy + vh);&#10;    ctx.moveTo(vx, vy + vh\/2); ctx.lineTo(vx + vw, vy + vh\/2);&#10;    ctx.stroke();&#10;    if (escenaNocturna) {&#10;        ctx.save();&#10;        ctx.translate(vx, vy);&#10;        ctx.rotate(-0.9);&#10;        ctx.fillStyle = &quot;rgba(220,235,245,0.5)&quot;;&#10;        ctx.strokeStyle = &quot;#7a4a2b&quot;; ctx.lineWidth = 4;&#10;        ctx.fillRect(0, 0, vw * 0.48, vh);&#10;        ctx.strokeRect(0, 0, vw * 0.48, vh);&#10;        ctx.restore();&#10;        ctx.fillStyle = &quot;rgba(0,0,0,0.5)&quot;;&#10;        ctx.font = &quot;12px 'Comic Sans MS', sans-serif&quot;;&#10;        ctx.textAlign = &quot;center&quot;;&#10;        ctx.fillText(&quot;~ brisa nocturna ~&quot;, vx + vw \/ 2, vy + vh + 16);&#10;    }&#10;    const alfX = anchoPrincipal * 0.12, alfY = canvas.height * 0.72, alfAncho = anchoPrincipal * 0.55, alfAlto = canvas.height * 0.2;&#10;    ctx.fillStyle = casa.tejado;&#10;    ctx.globalAlpha = 0.55;&#10;    ctx.beginPath();&#10;    ctx.roundRect ? ctx.roundRect(alfX, alfY, alfAncho, alfAlto, 16) : ctx.rect(alfX, alfY, alfAncho, alfAlto);&#10;    ctx.fill();&#10;    ctx.globalAlpha = 1;&#10;    ctx.strokeStyle = &quot;#fff&quot;; ctx.lineWidth = 2;&#10;    ctx.beginPath();&#10;    ctx.roundRect ? ctx.roundRect(alfX + 8, alfY + 8, alfAncho - 16, alfAlto - 16, 10) : ctx.rect(alfX + 8, alfY + 8, alfAncho - 16, alfAlto - 16);&#10;    ctx.stroke();&#10;    ctx.fillStyle = &quot;rgba(255,255,255,0.7)&quot;;&#10;    for (let i = 0; i &lt; 5; i++) {&#10;        ctx.beginPath();&#10;        ctx.arc(alfX + alfAncho * (0.15 + i * 0.18), alfY + alfAlto * 0.5, 3, 0, Math.PI * 2);&#10;        ctx.fill();&#10;    }&#10;    const muebleX = anchoPrincipal * 0.15, muebleY = canvas.height * 0.78;&#10;    if (casa.mueble === 'cama') {&#10;        ctx.fillStyle = &quot;#fff&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2.5;&#10;        ctx.fillRect(muebleX, muebleY - 55, 140, 55);&#10;        ctx.strokeRect(muebleX, muebleY - 55, 140, 55);&#10;        ctx.fillStyle = casa.tejado;&#10;        ctx.fillRect(muebleX, muebleY - 55, 140, 16);&#10;        ctx.strokeRect(muebleX, muebleY - 55, 140, 16);&#10;        ctx.fillStyle = &quot;#8a5a2b&quot;;&#10;        ctx.fillRect(muebleX - 8, muebleY - 64, 12, 64);&#10;        const mesillaX = muebleX + 150, mesillaY = muebleY - 34;&#10;        ctx.fillStyle = &quot;#8a5a2b&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;        ctx.fillRect(mesillaX, mesillaY, 34, 34);&#10;        ctx.strokeRect(mesillaX, mesillaY, 34, 34);&#10;        ctx.strokeRect(mesillaX + 4, mesillaY + 14, 26, 2);&#10;        ctx.fillStyle = &quot;#e8c168&quot;;&#10;        ctx.beginPath();&#10;        ctx.moveTo(mesillaX + 9, mesillaY - 14);&#10;        ctx.lineTo(mesillaX + 25, mesillaY - 14);&#10;        ctx.lineTo(mesillaX + 29, mesillaY);&#10;        ctx.lineTo(mesillaX + 5, mesillaY);&#10;        ctx.closePath();&#10;        ctx.fill(); ctx.stroke();&#10;        ctx.strokeStyle = &quot;#8a5a2b&quot;;&#10;        ctx.beginPath(); ctx.moveTo(mesillaX + 17, mesillaY); ctx.lineTo(mesillaX + 17, mesillaY - 20); ctx.stroke();&#10;    } else if (casa.mueble === 'sofa') {&#10;        ctx.fillStyle = casa.tejado; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2.5;&#10;        ctx.fillRect(muebleX, muebleY - 46, 150, 46);&#10;        ctx.strokeRect(muebleX, muebleY - 46, 150, 46);&#10;        ctx.fillRect(muebleX - 10, muebleY - 60, 18, 60);&#10;        ctx.fillRect(muebleX + 142, muebleY - 60, 18, 60);&#10;        ctx.fillStyle = &quot;#8a5a2b&quot;;&#10;        ctx.fillRect(muebleX + 55, muebleY + 14, 55, 26);&#10;        ctx.strokeRect(muebleX + 55, muebleY + 14, 55, 26);&#10;    } else {&#10;        ctx.fillStyle = &quot;#8a5a2b&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2.5;&#10;        ctx.fillRect(muebleX + 30, muebleY - 10, 90, 12);&#10;        ctx.strokeRect(muebleX + 30, muebleY - 10, 90, 12);&#10;        ctx.fillRect(muebleX + 35, muebleY + 2, 8, 36);&#10;        ctx.fillRect(muebleX + 107, muebleY + 2, 8, 36);&#10;        ctx.fillStyle = casa.tejado;&#10;        ctx.beginPath(); ctx.arc(muebleX + 75, muebleY - 30, 9, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    }&#10;    dibujarEscritorioTeletrabajo(18, canvas.height - 8);&#10;    dibujarTeletrabajoCasa(t);&#10;    dibujarCamillaTelemedicina(t);&#10;    dibujarMochilaSOS(t);&#10;    dibujarTerminalHyperloopCasa(t);&#10;    dibujarFiestaInterior(t);&#10;    if (motasSuciedad.length === 0) generarSuciedad();&#10;    ctx.fillStyle = &quot;#8a6a45&quot;;&#10;    motasSuciedad.forEach(m =&gt; {&#10;        if (!m.limpia) {&#10;            ctx.beginPath();&#10;            ctx.ellipse(m.x, m.y, m.r * 1.4, m.r, 0, 0, Math.PI * 2);&#10;            ctx.fill();&#10;        }&#10;    });&#10;    const sueloLimpio = motasSuciedad.length &gt; 0 &amp;&amp; motasSuciedad.every(m =&gt; m.limpia);&#10;    if (sosteniendoEscoba &amp;&amp; ((sueloLimpio &amp;&amp; !arrastrandoInterior) || posInterior.x &gt; anchoPrincipal)) {&#10;        sosteniendoEscoba = false;&#10;    }&#10;    if (!sosteniendoEscoba) {&#10;        dibujarEscoba(ZONA_ESCOBA.x, ZONA_ESCOBA.y, t, false);&#10;    }&#10;    ctx.fillStyle = &quot;#7a4a2b&quot;;&#10;    ctx.fillRect(anchoPrincipal, 0, 6, canvas.height);&#10;    const derechaX = anchoPrincipal + 6;&#10;    const derechaAncho = canvas.width - derechaX - 20;&#10;    dibujarCocina(derechaX + 10, 20, derechaAncho - 20, canvas.height * 0.42);&#10;    dibujarNevera(derechaX + derechaAncho - derechaAncho * 0.24, 20, derechaAncho * 0.22, canvas.height * 0.42, interiorEstado === 'nevera');&#10;    dibujarFiestaCocina(t);&#10;    dibujarCocineraVecina(t);                                                              \/\/ la vecina que cocina, en los fogones&#10;    if (interiorEstado === 'fregando') {&#10;        dibujarChorroFregadero(ZONA_FREGADERO.x, ZONA_FREGADERO.y - 6, t);&#10;    }&#10;    if (interiorEstado === 'cocinando') {&#10;        dibujarSarten(ZONA_FOGONES.x, ZONA_FOGONES.y, t);&#10;    }&#10;    ctx.fillStyle = &quot;#7a4a2b&quot;;&#10;    ctx.fillRect(derechaX, canvas.height * 0.5, canvas.width - derechaX, 6);&#10;    const bathX = derechaX + 10, bathY = canvas.height * 0.5 + 10, bathAncho = derechaAncho - 20, bathAlto = canvas.height * 0.42;&#10;    dibujarBa\u00f1o(bathX, bathY, bathAncho, bathAlto);&#10;    dibujarGoteoLavabo(bathX + bathAncho * 0.88, bathY + bathAlto * 0.55, t);&#10;    dibujarFiestaBa\u00f1o(t);&#10;    if (interiorEstado === 'ba\u00f1\u00e1ndose') {&#10;        dibujarChapoteo(ZONA_BA\u00d1ERA.x, ZONA_BA\u00d1ERA.y, t);&#10;    }&#10;    ctx.fillStyle = &quot;rgba(0,0,0,0.55)&quot;;&#10;    ctx.font = &quot;13px 'Comic Sans MS', sans-serif&quot;;&#10;    ctx.textAlign = &quot;left&quot;;&#10;    ctx.fillText(&quot;Cocina&quot;, derechaX + 12, 34);&#10;    ctx.fillText(&quot;Ba\u00f1o&quot;, derechaX + 12, canvas.height * 0.5 + 26);&#10;    const enCocina = posInterior.x &gt; anchoPrincipal &amp;&amp; posInterior.y &lt; canvas.height * 0.5;&#10;    const enBa\u00f1o = posInterior.x &gt; anchoPrincipal &amp;&amp; posInterior.y &gt;= canvas.height * 0.5;&#10;    dibujarPuerta(anchoPrincipal + 6, canvas.height * 0.22, canvas.height * 0.16, enCocina, false);&#10;    dibujarPuerta(anchoPrincipal + 6, canvas.height * 0.7, canvas.height * 0.16, enBa\u00f1o, false);&#10;    if (escenaNocturna) {&#10;        const camaCentroX = muebleX + 70, camaCentroY = muebleY - 27;&#10;        if (casa.mueble !== 'cama') {                                                       \/\/ sin cama: colchoneta con almohada sobre el sof\u00e1 o el suelo&#10;            ctx.fillStyle = casa.tejado; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2.5;&#10;            ctx.beginPath(); ctx.roundRect ? ctx.roundRect(muebleX - 4, muebleY - 46, 148, 40, 12) : ctx.rect(muebleX - 4, muebleY - 46, 148, 40); ctx.fill(); ctx.stroke();&#10;            ctx.fillStyle = &quot;#fff&quot;; ctx.beginPath(); ctx.roundRect ? ctx.roundRect(muebleX + 4, muebleY - 42, 34, 30, 10) : ctx.rect(muebleX + 4, muebleY - 42, 34, 30); ctx.fill(); ctx.stroke();&#10;        }&#10;        const respirar = Math.sin(t \/ 40) * 1.5;&#10;        const enPareja = dormidosAqui.length &gt;= 2 &amp;&amp; dormidosAqui[0].pareja === dormidosAqui[1];      \/\/ abrazadas solo si son pareja&#10;        if (enPareja) {&#10;            ctx.save();&#10;            ctx.translate(camaCentroX - 18, camaCentroY + respirar);&#10;            ctx.rotate(Math.PI \/ 2);&#10;            ctx.scale(0.85, 0.85);&#10;            dibujarMu\u00f1eca({ x: 0, y: 0, angulo: 0, rostro: 'dormida' }, dormidosAqui[0].colorPelo, false, false, false, dormidosAqui[0].estilo);&#10;            ctx.restore();&#10;            ctx.save();&#10;            ctx.translate(camaCentroX + 18, camaCentroY - respirar);&#10;            ctx.rotate(Math.PI \/ 2);&#10;            ctx.scale(0.85, 0.85);&#10;            dibujarMu\u00f1eca({ x: 0, y: 0, angulo: 0, rostro: 'dormida' }, dormidosAqui[1].colorPelo, false, false, false, dormidosAqui[1].estilo);&#10;            ctx.restore();&#10;        } else {&#10;            ctx.save();&#10;            ctx.translate(camaCentroX, camaCentroY + respirar);&#10;            ctx.rotate(Math.PI \/ 2);&#10;            ctx.scale(0.85, 0.85);&#10;            dibujarMu\u00f1eca({ x: 0, y: 0, angulo: 0, rostro: 'dormida' }, dormidosAqui[0].colorPelo, false, false, false, dormidosAqui[0].estilo);&#10;            ctx.restore();&#10;            dormidosAqui.slice(1, 3).forEach((o, k) =&gt; {                                      \/\/ si comparten casa sin ser pareja, la otra duerme en una colchoneta aparte&#10;                const mx = camaCentroX + 20 + k * 70, my = muebleY + 34;&#10;                ctx.fillStyle = casa.tejado; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;                ctx.beginPath(); ctx.roundRect ? ctx.roundRect(mx - 40, my - 14, 80, 28, 10) : ctx.rect(mx - 40, my - 14, 80, 28); ctx.fill(); ctx.stroke();&#10;                ctx.fillStyle = &quot;#fff&quot;; ctx.beginPath(); ctx.roundRect ? ctx.roundRect(mx - 36, my - 10, 22, 20, 8) : ctx.rect(mx - 36, my - 10, 22, 20); ctx.fill(); ctx.stroke();&#10;                ctx.save(); ctx.translate(mx, my + respirar); ctx.rotate(Math.PI \/ 2); ctx.scale(0.62, 0.62);&#10;                dibujarMu\u00f1eca({ x: 0, y: 0, angulo: 0, rostro: 'dormida' }, o.colorPelo, false, false, false, o.estilo); ctx.restore();&#10;            });&#10;        }&#10;        ctx.fillStyle = &quot;rgba(255,255,255,0.35)&quot;;&#10;        ctx.beginPath();&#10;        ctx.roundRect ? ctx.roundRect(muebleX + 6, muebleY - 40, 128, 26, 10) : ctx.rect(muebleX + 6, muebleY - 40, 128, 26);&#10;        ctx.fill();&#10;        ctx.fillStyle = &quot;rgba(0,0,0,0.45)&quot;;&#10;        ctx.font = &quot;16px Arial&quot;;&#10;        ctx.textAlign = &quot;left&quot;;&#10;        ctx.fillText(&quot;\ud83d\udca4&quot;, camaCentroX + 45, camaCentroY - 20 + Math.sin(t \/ 25) * 3);&#10;    } else {&#10;        const bamboleo = Math.sin(t \/ 30) * 0.03;&#10;        ctx.save();&#10;        ctx.translate(posInterior.x, posInterior.y);&#10;        ctx.scale(1.15, 1.15);&#10;        dibujarMu\u00f1eca({ x: 0, y: 0, angulo: bamboleo }, casa.colorPelo, false, false, false, casa.estilo); accesorioFiesta(0, 0, 1);&#10;        ctx.restore();&#10;    }&#10;    if (sosteniendoEscoba) {&#10;        dibujarEscoba(posInterior.x + 16, posInterior.y + 14, t, arrastrandoInterior);&#10;        if (motasSuciedad.length &amp;&amp; motasSuciedad.every(m =&gt; m.limpia)) {&#10;            ctx.fillStyle = &quot;rgba(0,0,0,0.55)&quot;;&#10;            ctx.font = &quot;16px 'Comic Sans MS', sans-serif&quot;;&#10;            ctx.textAlign = &quot;center&quot;;&#10;            ctx.fillText(&quot;\u00a1Suelo reluciente! \u2728&quot;, posInterior.x, posInterior.y - 60);&#10;        }&#10;    }&#10;    if (interiorEstado !== 'de_pie') {&#10;        const zona = ZONAS_INTERIOR.find(z =&gt; z.accion === interiorEstado);&#10;        if (zona) {&#10;            ctx.font = &quot;22px Arial&quot;;&#10;            ctx.textAlign = &quot;center&quot;;&#10;            ctx.fillText(zona.icono, posInterior.x, posInterior.y - 55);&#10;        }&#10;    }&#10;    dibujarOverlaysInterior(casa, t);&#10;    dibujarPedidoHyperloop(casa, t);&#10;    dibujarBotonVolver();&#10;}&#10;const casas = [&#10;    { x: 20,  ancho: 110, alto: 100, pared: &quot;#f7c68b&quot;, tejado: &quot;#c0522d&quot;, mueble: 'cama',  colorPelo: &quot;#f2c14e&quot;, estilo: 'largo' },&#10;    { x: 155, ancho: 80,  alto: 75,  pared: &quot;#f3a6c6&quot;, tejado: &quot;#6a3e8c&quot;, mueble: 'mesa',  colorPelo: &quot;#6b3f26&quot;, estilo: 'pincho' },&#10;    { x: 260, ancho: 130, alto: 120, pared: &quot;#fff4e0&quot;, tejado: &quot;#d6335a&quot;, mueble: 'sofa',  colorPelo: &quot;#c0522d&quot;, estilo: 'largo' },&#10;    { x: 700, ancho: 95,  alto: 90,  pared: &quot;#c8e6c9&quot;, tejado: &quot;#8a5a2b&quot;, mueble: 'cama',  colorPelo: &quot;#c9c9c9&quot;, estilo: 'pincho' },&#10;    { x: 810, ancho: 130, alto: 110, pared: &quot;#f7c68b&quot;, tejado: &quot;#6a3e8c&quot;, mueble: 'mesa',  colorPelo: &quot;#c0522d&quot;, estilo: 'largo' }&#10;];&#10;function nuevoObjetivo(h) {&#10;    if (vidaLista) { VidaDiaria.nuevoDestino(h); return; }                                 \/\/ vida diaria org\u00e1nica (m\u00f3dulo VidaDiaria)&#10;    h.objetivoX = 40 + Math.random() * (935 - 40);&#10;    h.direccion = h.objetivoX &gt; h.x ? 1 : -1;&#10;}&#10;const habitantes = [&#10;    { x: 75,  colorPelo: &quot;#f2c14e&quot;, estilo: 'largo' },&#10;    { x: 195, colorPelo: &quot;#6b3f26&quot;, estilo: 'pincho' },&#10;    { x: 325, colorPelo: &quot;#c0522d&quot;, estilo: 'largo' },&#10;    { x: 480, colorPelo: &quot;#2b2b2b&quot;, estilo: 'mohawk' },&#10;    { x: 545, colorPelo: &quot;#4fb3d9&quot;, estilo: 'coletas' },&#10;    { x: 745, colorPelo: &quot;#c9c9c9&quot;, estilo: 'pincho' },&#10;    { x: 875, colorPelo: &quot;#b36bd9&quot;, estilo: 'rizos' },&#10;    { x: 610, colorPelo: &quot;#e85fb0&quot;, estilo: 'mohawk' }&#10;];&#10;habitantes.forEach(h =&gt; {&#10;    h.y = yDeCalle(h.x);&#10;    h.offsetY = (Math.random() - 0.5) * 18;&#10;    h.estado = 'caminando';&#10;    h.velocidad = 0.4 + Math.random() * 0.35;&#10;    h.temporizador = Math.random() * 120;&#10;    h.inmuneSocial = 0;&#10;    h.arrastrando = false;&#10;    h.pareja = null;&#10;    h.durmiendo = false;&#10;    h.casaAsignada = null;&#10;    h.enamorada = 0;&#10;    h.enPlaya = false;&#10;    h.posPlaya = null;&#10;    h.playaEstado = 'de_pie';&#10;    h.zonaPlaya = null;&#10;    h.horaEntradaAgua = 0;&#10;    h.objetivoPlaya = null;&#10;    h.esperaPlaya = 0;&#10;    h.miraPlayaDerecha = false;&#10;    nuevoObjetivo(h);&#10;});&#10;const coloresFlores = [&quot;#ff6f91&quot;, &quot;#ffd166&quot;, &quot;#f4a6ff&quot;, &quot;#ff9770&quot;, &quot;#c9f2c7&quot;];&#10;const flores = [];&#10;for (let i = 0; i &lt; 60; i++) {&#10;    flores.push({&#10;        x: 420 + Math.random() * 220,&#10;        y: SUELO_Y + 60 + Math.random() * 120,&#10;        color: coloresFlores[Math.floor(Math.random() * coloresFlores.length)]&#10;    });&#10;}&#10;const floresPrimavera = [];&#10;for (let i = 0; i &lt; 45; i++) {&#10;    const enParque = Math.random() &lt; 0.3;&#10;    floresPrimavera.push({&#10;        x: enParque ? 420 + Math.random() * 220 : Math.random() * 960,&#10;        y: enParque ? SUELO_Y + 60 + Math.random() * 120 : SUELO_Y + 15 + Math.random() * 30,&#10;        color: coloresFlores[Math.floor(Math.random() * coloresFlores.length)]&#10;    });&#10;}&#10;const bancos = [&#10;    { x: 90,  y: SUELO_Y + 95 },   \/\/ m\u00e1s arriba para dejar libre la parada del hospital&#10;    { x: 790, y: SUELO_Y + 120 }&#10;];&#10;const patinetes = [&#10;    { x: 250, y: SUELO_Y + 90, montadaPor: null },&#10;    { x: 600, y: SUELO_Y + 195, montadaPor: null },&#10;    { x: 830, y: SUELO_Y + 90, montadaPor: null }&#10;];&#10;const REFUGIO = { x: 575, y: 426, ancho: 74, alto: 54, radio: 58 * escalaProf(426) };   \/\/ zona de adopci\u00f3n escalada con la perspectiva&#10;const mascotas = [&#10;    { tipo: 'gato',  x: REFUGIO.x - 16, y: REFUGIO.y - 6,  fase: 0, estado: 'en_refugio', siguiendoA: null },&#10;    { tipo: 'perro', x: REFUGIO.x + 14, y: REFUGIO.y - 4,  fase: 1, estado: 'en_refugio', siguiendoA: null },&#10;    { tipo: 'gato',  x: REFUGIO.x + 2,  y: REFUGIO.y - 12, fase: 2, estado: 'en_refugio', siguiendoA: null }&#10;];&#10;function actualizarMascotas() {&#10;    mascotas.forEach(m =&gt; {&#10;        if (m.estado === 'en_refugio') {&#10;            let mejor = null, distMin = REFUGIO.radio;&#10;            habitantes.forEach(h =&gt; {&#10;                if (h.arrastrando || h.durmiendo || h.enPlaya || h.oculta) return;&#10;                const yaTieneMascota = mascotas.some(otra =&gt; otra.siguiendoA === h);&#10;                if (yaTieneMascota) return;&#10;                const d = Math.hypot(h.x - REFUGIO.x, h.y - REFUGIO.y);&#10;                if (d &lt; distMin) { mejor = h; distMin = d; }&#10;            });&#10;            if (mejor) { m.siguiendoA = mejor; m.estado = 'siguiendo'; }&#10;            return; \/\/ sin due\u00f1a: se queda echada, tranquila, junto al refugio&#10;        }&#10;        const h = m.siguiendoA;&#10;        if (!h) { m.estado = 'en_refugio'; return; }&#10;        let objX, objY, quieta;&#10;        if (h.oculta) {                                                                    \/\/ su due\u00f1a est\u00e1 en la biblioteca o en casa: espera junto a la puerta&#10;            const p = h.lugar === 'casa' ? { x: casas[h.casaAsignada].x + casas[h.casaAsignada].ancho \/ 2, y: SUELO_Y + 62 } : h.lugar === 'tranvia' ? { x: TRANVIA.x, y: TRANVIA.y } : h.lugar === 'gimnasio' ? GimnasioPueblo.puerta() : Biblioteca.puertaBib();&#10;            objX = p.x + (m.tipo === 'gato' ? -20 : 20); objY = p.y + 12; quieta = true;&#10;        } else if (h.enPlaya) {&#10;            objX = TRANVIA.x + (m.tipo === 'gato' ? -22 : 22);&#10;            objY = TRANVIA.y + 20;&#10;            quieta = true;&#10;        } else if (h.durmiendo) {&#10;            const casaHogar = casas[h.casaAsignada];&#10;            objX = casaHogar.x + casaHogar.ancho \/ 2 + (m.tipo === 'gato' ? -14 : 14);&#10;            objY = SUELO_Y + 58;&#10;            quieta = true;&#10;        } else if (h.estado === 'leyendo') {&#10;            objX = BIBLIOTECA.x + BIBLIOTECA.ancho \/ 2 + (m.tipo === 'gato' ? -18 : 18);&#10;            objY = SUELO_Y + 58;&#10;            quieta = true;&#10;        } else {&#10;            objX = h.x + (h.direccion &gt;= 0 ? -24 : 24) + (m.tipo === 'gato' ? 8 : -8);&#10;            objY = h.y + 15;&#10;            quieta = h.estado !== 'caminando';&#10;        }&#10;        const dist = Math.hypot(m.x - objX, m.y - objY);&#10;        if (quieta &amp;&amp; dist &lt; 16) {&#10;            m.estado = 'reposo';&#10;        } else {&#10;            m.estado = 'siguiendo';&#10;            const vel = m.tipo === 'perro' ? 0.09 : 0.07;&#10;            m.x += (objX - m.x) * vel;&#10;            m.y += (objY - m.y) * vel;&#10;        }&#10;    });&#10;}&#10;const CASAS_CON_CAMA = [0, 3]; \/\/ \u00edndices de casas que tienen cama, para poder dormir en ellas&#10;let diaAnterior = null;&#10;const CASAS_PAREJA = [0, 4];   \/\/ tejado rojo y tejado morado: la casa de cada pareja (m\u00e1ximo 2 parejas)&#10;function asignarCasaPareja(a, b) {&#10;    const ocupada = i =&gt; habitantes.some(o =&gt; o !== a &amp;&amp; o !== b &amp;&amp; o.pareja &amp;&amp; o.casaAsignada === i);&#10;    const libre = CASAS_PAREJA.find(i =&gt; !ocupada(i));&#10;    const casaIdx = libre !== undefined ? libre : CASAS_PAREJA[0];&#10;    a.casaAsignada = casaIdx; b.casaAsignada = casaIdx;&#10;}&#10;function ordenarCamasNocturnas() {&#10;    habitantes.forEach(h =&gt; {&#10;        const p = h.pareja; if (!p) return;&#10;        const junta = h.casaAsignada !== null &amp;&amp; h.casaAsignada !== undefined &amp;&amp; h.casaAsignada === p.casaAsignada;&#10;        const sola = junta &amp;&amp; !habitantes.some(o =&gt; o !== h &amp;&amp; o !== p &amp;&amp; o.casaAsignada === h.casaAsignada);&#10;        if (!sola) asignarCasaPareja(h, p);&#10;    });&#10;    habitantes.forEach(h =&gt; {&#10;        if (h.pareja || h.casaAsignada === null || h.casaAsignada === undefined) return;&#10;        if (habitantes.some(o =&gt; o.pareja &amp;&amp; o.casaAsignada === h.casaAsignada)) h.casaAsignada = casaPropia(h);&#10;    });&#10;}&#10;function formarPareja(a, b) {&#10;    a.pareja = b; b.pareja = a;&#10;    asignarCasaPareja(a, b);&#10;    diarioNota('momentos', 'pareja', 'Dos chicas se han enamorado', '\ud83d\udc9e');&#10;    a.enamorada = 200; b.enamorada = 200; \/\/ para mostrar un coraz\u00f3n doble un rato&#10;}&#10;function actualizarHabitantes() {&#10;    habitantes.forEach(h =&gt; {&#10;        if (h.arrastrando || h.durmiendo || h.enPlaya || h.oculta) return;&#10;        if (h.inmuneSocial &gt; 0) h.inmuneSocial--;&#10;        if (h.enamorada &gt; 0) h.enamorada--;&#10;        if (h.estado === 'caminando') {&#10;            if (h.objetivoY != null) {                                                       \/\/ destino en 2D (todo el mapa)&#10;                if (VidaDiaria.mover(h, h.velocidad * (h.patinete ? 1.7 : 1))) { h.objetivoY = null; if (!VidaDiaria.llegada(h)) { h.estado = 'parada'; h.temporizador = 2700; } }&#10;                return;&#10;            }&#10;            h.x += h.velocidad * (h.patinete ? 1.7 : 1) * h.direccion;&#10;            const objetivoY = yDeCalle(h.x) + h.offsetY;&#10;            h.y += (objetivoY - h.y) * 0.08;&#10;            if (Math.abs(h.x - h.objetivoX) &lt; 3) {&#10;                h.estado = 'parada';&#10;                h.temporizador = 2700;&#10;            }&#10;        } else if (h.estado === 'parada' || h.estado === 'sentada' || h.estado === 'leyendo') {&#10;            h.temporizador -= 1;&#10;            if (h.temporizador &lt;= 0) {&#10;                nuevoObjetivo(h);&#10;                h.estado = 'caminando';&#10;            }&#10;        } else if (h.estado === 'social') {&#10;            h.temporizador -= (h.ritmo || 1);&#10;            if (h.temporizador &lt;= 0) {&#10;                const otra = h.parejaCandidata;&#10;                if (otra &amp;&amp; !h.pareja &amp;&amp; !otra.pareja &amp;&amp; habitantes.filter(o =&gt; o.pareja).length &lt; 4) {   \/\/ como mucho 2 parejas; el resto, solteras&#10;                    const idOtra = habitantes.indexOf(otra);&#10;                    const veces = (h.vecesConEsta &amp;&amp; h.vecesConEsta[idOtra]) || 1;&#10;                    if (veces &gt;= 2 || Math.random() &lt; 0.6) {&#10;                        formarPareja(h, otra);&#10;                    }&#10;                }&#10;                h.inmuneSocial = 70;&#10;                nuevoObjetivo(h);&#10;                h.estado = 'caminando';&#10;            }&#10;        } else if (h.estado === 'mercadillo_esperando') {&#10;        } else if (h.estado === 'mercadillo') {&#10;            if (Date.now() - h.inicioMercadillo &gt;= 30000) {&#10;                if (esperandoMercadillo === h) esperandoMercadillo = null;&#10;                nuevoObjetivo(h);&#10;                h.estado = 'caminando';&#10;            }&#10;        } else if (h.estado === 'frutas_esperando') {&#10;        } else if (h.estado === 'frutas') {&#10;            if (Date.now() - h.inicioFrutas &gt;= 30000) {&#10;                if (esperandoFrutas === h) esperandoFrutas = null;&#10;                nuevoObjetivo(h);&#10;                h.estado = 'caminando';&#10;            }&#10;        }&#10;    });&#10;    for (let i = 0; i &lt; habitantes.length; i++) {&#10;        for (let j = i + 1; j &lt; habitantes.length; j++) {&#10;            const a = habitantes[i], b = habitantes[j];&#10;            if (a.arrastrando || b.arrastrando) continue;&#10;            if (a.estado === 'caminando' &amp;&amp; b.estado === 'caminando' &amp;&amp;&#10;                a.inmuneSocial &lt;= 0 &amp;&amp; b.inmuneSocial &lt;= 0 &amp;&amp;&#10;                Math.abs(a.y - b.y) &lt; 10 &amp;&amp; Math.abs(a.x - b.x) &lt; 48 * Math.max(a.alc || 1, b.alc || 1)) {&#10;                a.estado = 'social'; b.estado = 'social';&#10;                a.temporizador = 60 + Math.random() * 30;&#10;                b.temporizador = a.temporizador;&#10;                a.parejaCandidata = b; b.parejaCandidata = a;&#10;                a.vecesConEsta = a.vecesConEsta || {};&#10;                b.vecesConEsta = b.vecesConEsta || {};&#10;                const idB = habitantes.indexOf(b), idA = habitantes.indexOf(a);&#10;                a.vecesConEsta[idB] = (a.vecesConEsta[idB] || 0) + 1;&#10;                b.vecesConEsta[idA] = (b.vecesConEsta[idA] || 0) + 1;&#10;            }&#10;        }&#10;    }&#10;}&#10;let t = 0;&#10;let casaAbierta = null;&#10;const ANCHO_PRINCIPAL = canvas.width * 0.6;&#10;let posInterior = null;&#10;let enGimnasio = false;&#10;let fadeAlpha = 0;&#10;let fadeSubiendo = false;&#10;let fadeAccion = null;&#10;function iniciarTransicion(accion) {&#10;    fadeAccion = accion;&#10;    fadeSubiendo = true;&#10;}&#10;let esperandoMercadillo = null;&#10;let esperandoFrutas = null;&#10;const ZONA_PUESTOFRUTA = { x: 400, y: 446, yBase: 466, radio: 60 * escalaProf(466), escala: 1.5 };   \/\/ puesto de frutas y flores: un escal\u00f3n m\u00e1s arriba (plano medio), zona escalada con la perspectiva&#10;let enPlaya = false;&#10;let habitantesEnPlaya = [];&#10;const DURACION_PLAYA_MS = 35000;&#10;const SLOTS_PLAYA = [&#10;    { x: 260, y: 450 }, { x: 340, y: 470 }, { x: 560, y: 470 }, { x: 640, y: 450 }&#10;];&#10;const TRANVIA = { x: 350, y: SUELO_Y + 100 };&#10;const ZONA_SURF = { x: 250, y: 300, accion: 'surfeando', icono: '\ud83c\udfc4' };&#10;const ZONA_WINDSURF = { x: 620, y: 300, accion: 'windsurf', icono: '\u26f5' };&#10;const ZONA_ROCA = { x: 70, y: 405, accion: 'pescando', icono: '\ud83c\udfa3' };&#10;const ZONA_SOMBRILLA_A = { x: 350, y: 435, accion: 'descansando', icono: '\ud83d\ude0c' };&#10;const ZONA_SOMBRILLA_B = { x: 610, y: 435, accion: 'descansando', icono: '\ud83d\ude0c' };&#10;const ZONA_CASETA = { x: 730, y: 402, accion: 'caseta', icono: '\ud83d\udeaa' };&#10;const ZONAS_PLAYA = [ZONA_SURF, ZONA_WINDSURF, ZONA_ROCA, ZONA_SOMBRILLA_A, ZONA_SOMBRILLA_B, ZONA_CASETA];&#10;function enviarAPlaya(h) {&#10;    h.enPlaya = true;&#10;    const hueco = SLOTS_PLAYA[habitantesEnPlaya.length % SLOTS_PLAYA.length];&#10;    h.posPlaya = { x: hueco.x, y: hueco.y };&#10;    h.playaEstado = 'de_pie';&#10;    h.zonaPlaya = null;&#10;    h.horaEntradaAgua = 0;&#10;    h.objetivoPlaya = null;&#10;    h.esperaPlaya = 30 + Math.random() * 60;&#10;    habitantesEnPlaya.push(h);&#10;}&#10;function volverDeLaPlaya(h) {&#10;    if (h.buceoFin &amp;&amp; !h.buceoAplicado) Puerto.finBuceo(h);                                  \/\/ si se va a media inmersi\u00f3n, se aplican igualmente los efectos&#10;    h.enPlaya = false;&#10;    h.posPlaya = null;&#10;    h.playaEstado = 'de_pie';&#10;    h.zonaPlaya = null;&#10;    h.horaEntradaAgua = 0;&#10;    h.objetivoPlaya = null;&#10;    h.x = TRANVIA.x;&#10;    h.y = TRANVIA.y;&#10;    nuevoObjetivo(h);&#10;    h.estado = 'caminando';&#10;    habitantesEnPlaya = habitantesEnPlaya.filter(o =&gt; o !== h);&#10;}&#10;function actualizarPlaya() {&#10;    habitantesEnPlaya.forEach(h =&gt; {&#10;        if (!h.posPlaya) return;&#10;        if (h.pausaEquipo &gt; 0) { h.pausaEquipo--; return; }                                              \/\/ coge su tabla de la exhibici\u00f3n de la escuela&#10;        if (h.zonaPlaya &amp;&amp; h.zonaPlaya.dur) {                                              \/\/ actividades nuevas: 45 s y vuelve a su rutina&#10;            if (h !== arrastrandoPlaya &amp;&amp; Date.now() - h.horaEntradaAgua &gt;= h.zonaPlaya.dur) liberarZonaPlaya(h);&#10;            return;&#10;        }&#10;        if (h.playaEstado === 'surfeando' || h.playaEstado === 'windsurf') {&#10;            if (Date.now() - h.horaEntradaAgua &gt;= DURACION_PLAYA_MS) {&#10;                const zona = h.zonaPlaya;&#10;                h.playaEstado = 'de_pie'; h.equipoSurf = null;&#10;                h.zonaPlaya = null;&#10;                h.horaEntradaAgua = 0;&#10;                if (zona) { h.posPlaya.x = zona.x; h.posPlaya.y = 460; }&#10;            }&#10;            return;&#10;        }&#10;        if (h.playaEstado !== 'de_pie' || h === arrastrandoPlaya) return;&#10;        if (h.objetivoPlaya &amp;&amp; h.objetivoPlaya.equipo &amp;&amp; Math.hypot(h.posPlaya.x - h.objetivoPlaya.x, h.posPlaya.y - h.objetivoPlaya.y) &lt; 6) { Costa.recogeEquipo(h); return; }&#10;        if (h.objetivoPlaya &amp;&amp; h.objetivoPlaya.zona &amp;&amp; Math.hypot(h.posPlaya.x - h.objetivoPlaya.x, h.posPlaya.y - h.objetivoPlaya.y) &lt; 6) { llegarAZonaPlaya(h); return; }&#10;        if (!h.objetivoPlaya || Math.hypot(h.posPlaya.x - h.objetivoPlaya.x, h.posPlaya.y - h.objetivoPlaya.y) &lt; 6) {&#10;            if (h.esperaPlaya &gt; 0) { h.esperaPlaya--; return; }&#10;            h.objetivoPlaya = objetivoLibrePlaya(h);&#10;            h.esperaPlaya = 60 + Math.random() * 150;&#10;            return;&#10;        }&#10;        const dx = h.objetivoPlaya.x - h.posPlaya.x, dy = h.objetivoPlaya.y - h.posPlaya.y;&#10;        const dist = Math.hypot(dx, dy);&#10;        h.posPlaya.x += (dx \/ dist) * 0.7;&#10;        h.posPlaya.y += (dy \/ dist) * 0.7;&#10;        if (Math.abs(dx) &gt; 1) h.miraPlayaDerecha = dx &gt; 0;&#10;    });&#10;}&#10;let gimnasioChicas = [];&#10;let chicaGimnasioArrastrada = null;&#10;const ZONA_BICI1  = { x: 160, y: 330, accion: 'pedaleando', icono: '\ud83d\udeb4' };&#10;const ZONA_BICI2  = { x: 330, y: 330, accion: 'pedaleando', icono: '\ud83d\udeb4' };&#10;const ZONA_PESAS  = { x: 520, y: 330, accion: 'levantando', icono: '\ud83d\udcaa' };&#10;const ZONA_PISCINA= { x: 800, y: 340, accion: 'nadando',    icono: '\ud83d\udca6' };&#10;const ZONAS_GIMNASIO = [ZONA_BICI1, ZONA_BICI2, ZONA_PESAS, ZONA_PISCINA];&#10;function entrarAlGimnasio() {                                                              \/\/ las del gimnasio son las vecinas del pueblo (m\u00f3dulo GimnasioPueblo)&#10;    GimnasioPueblo.reclutar(3);&#10;}&#10;const HUERTA_SUELO_Y = 130;   \/\/ l\u00ednea donde empieza la tierra de cultivo (bajo el cielo)&#10;const HUERTA_CORTE_Y = 330;   \/\/ l\u00ednea donde empieza el corte subterr\u00e1neo&#10;let belarUnidades = [];&#10;function entrarALaHuerta() {&#10;    belarUnidades = [&#10;        { x: 300, y: 246, fase: 0, objetivo: null, espera: 0, miraDerecha: true },&#10;        { x: 620, y: 250, fase: 3, objetivo: null, espera: 0, miraDerecha: false }&#10;    ];&#10;}&#10;function actualizarHuerta() {&#10;    actualizarSiembra();&#10;    actualizarDronHabia();&#10;    belarUnidades.forEach(b =&gt; {&#10;        if (!b.objetivo || Math.hypot(b.x - b.objetivo.x, b.y - b.objetivo.y) &lt; 6) {&#10;            if (b.espera &gt; 0) { b.espera--; return; }&#10;            b.objetivo = { x: 130 + Math.random() * 680, y: 236 + Math.random() * 32 };&#10;            b.espera = 90 + Math.random() * 180;&#10;            return;&#10;        }&#10;        const dx = b.objetivo.x - b.x, dy = b.objetivo.y - b.y;&#10;        const dist = Math.hypot(dx, dy);&#10;        b.x += (dx \/ dist) * 0.35;&#10;        b.y += (dy \/ dist) * 0.35;&#10;        if (Math.abs(dx) &gt; 1) b.miraDerecha = dx &gt; 0;&#10;    });&#10;}&#10;function dibujarLauburu(x, y, r, color) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.fillStyle = color; ctx.strokeStyle = &quot;rgba(0,0,0,0.5)&quot;; ctx.lineWidth = 0.6;&#10;    for (let i = 0; i &lt; 4; i++) {&#10;        ctx.save(); ctx.rotate(i * Math.PI \/ 2);&#10;        ctx.beginPath();&#10;        ctx.moveTo(0, 0);&#10;        ctx.quadraticCurveTo(r * 0.95, -r * 0.18, r, 0);&#10;        ctx.quadraticCurveTo(r * 0.55, r * 0.5, 0, 0);&#10;        ctx.closePath(); ctx.fill(); ctx.stroke();&#10;        ctx.restore();&#10;    }&#10;    ctx.restore();&#10;}&#10;function dibujarBelar(x, y, t, fase, miraDerecha) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.scale(miraDerecha ? 1 : -1, 1);&#10;    ctx.fillStyle = &quot;#26292e&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 1.5;&#10;    [-8, 8].forEach(lx =&gt; { ctx.beginPath(); ctx.ellipse(lx, 21, 6.5, 6.5, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); });&#10;    ctx.fillStyle = &quot;#22d3ee&quot;;&#10;    [-8, 8].forEach(lx =&gt; { ctx.beginPath(); ctx.arc(lx, 21, 2, 0, Math.PI * 2); ctx.fill(); });&#10;    const gradT = ctx.createLinearGradient(0, -8, 0, 18);&#10;    gradT.addColorStop(0, &quot;#eef1f4&quot;); gradT.addColorStop(1, &quot;#a7aeb6&quot;);&#10;    ctx.fillStyle = gradT; ctx.strokeStyle = &quot;#5a6066&quot;; ctx.lineWidth = 2;&#10;    ctx.beginPath(); ctx.ellipse(0, 6, 12.5, 16, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    const alcance = 0.5 + 0.5 * Math.sin(t \/ 20 + fase);&#10;    const codoX = 12, codoY = -2 + alcance * 14;&#10;    const pinzaX = 16, pinzaY = 6 + alcance * 20;&#10;    ctx.strokeStyle = &quot;#c7cdd3&quot;; ctx.lineWidth = 5; ctx.lineCap = 'round';&#10;    ctx.beginPath(); ctx.moveTo(9, -2); ctx.lineTo(codoX, codoY); ctx.stroke();&#10;    ctx.lineWidth = 4;&#10;    ctx.beginPath(); ctx.moveTo(codoX, codoY); ctx.lineTo(pinzaX, pinzaY); ctx.stroke();&#10;    ctx.lineCap = 'butt';&#10;    ctx.fillStyle = &quot;#c7cdd3&quot;; ctx.strokeStyle = &quot;#7a828a&quot;; ctx.lineWidth = 1;&#10;    ctx.beginPath(); ctx.arc(codoX, codoY, 3, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    const apertura = 3 + (1 - alcance) * 4.5;&#10;    ctx.strokeStyle = &quot;#e7ebee&quot;; ctx.lineWidth = 2.5; ctx.lineCap = 'round';&#10;    ctx.beginPath(); ctx.moveTo(pinzaX, pinzaY); ctx.lineTo(pinzaX + 5, pinzaY - apertura); ctx.stroke();&#10;    ctx.beginPath(); ctx.moveTo(pinzaX, pinzaY); ctx.lineTo(pinzaX + 5, pinzaY + apertura); ctx.stroke();&#10;    ctx.lineCap = 'butt';&#10;    ctx.fillStyle = &quot;#3b4450&quot;; ctx.strokeStyle = &quot;#20262e&quot;; ctx.lineWidth = 2;&#10;    ctx.beginPath(); ctx.ellipse(0, -18, 12.5, 13.5, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;rgba(120,190,255,0.3)&quot;;&#10;    ctx.beginPath(); ctx.ellipse(2, -17, 8.5, 6.5, 0, 0, Math.PI * 2); ctx.fill();&#10;    dibujarLauburu(-1, -20, 5.5, &quot;#ff6fb0&quot;);&#10;    const destello = 0.55 + 0.45 * Math.sin(t \/ 6 + fase * 2);&#10;    ctx.fillStyle = `rgba(230,20,30,${destello})`;&#10;    ctx.beginPath(); ctx.arc(-3, -13, 1.8, 0, Math.PI * 2); ctx.fill();&#10;    ctx.beginPath(); ctx.arc(4, -13, 1.8, 0, Math.PI * 2); ctx.fill();&#10;    ctx.restore();&#10;}&#10;const dronHabia = { x: 640, y: 98, lado: 1, ang: 0, objetivo: null };&#10;const DRON_DIST_TRACTOR = 118;   \/\/ separaci\u00f3n lateral m\u00ednima respecto al tractor&#10;function actualizarDronHabia() {&#10;    if (!belarUnidades.length) return;&#10;    const d = dronHabia, tx = huertaTractorX();&#10;    const b = belarUnidades[Math.floor(t \/ 420) % belarUnidades.length];&#10;    const limite = l =&gt; tx + l * DRON_DIST_TRACTOR;&#10;    const valido = l =&gt; limite(l) &gt;= 165 &amp;&amp; limite(l) &lt;= 790;&#10;    if (!valido(d.lado) || ((b.x - tx) * d.lado &lt; -170 &amp;&amp; valido(-d.lado))) d.lado = -d.lado;&#10;    const objX = Math.max(165, Math.min(790, limite(d.lado) + d.lado * 18 * Math.sin(t \/ 90)));&#10;    const cruzando = Math.abs(d.x - tx) &lt; 100;          \/\/ al pasar por encima del tractor sube&#10;    const vx = (objX - d.x) * 0.025;&#10;    d.x += vx;&#10;    d.y += ((cruzando ? 32 : 98) - d.y) * 0.05;&#10;    d.ang += (vx * 0.12 - d.ang) * 0.1;&#10;    d.objetivo = b;&#10;}&#10;function dibujarDronHabia(t) {&#10;    const d = dronHabia, b = d.objetivo;&#10;    if (!b) return;&#10;    const x = d.x, y = d.y + Math.sin(t \/ 26) * 3, tx = huertaTractorX();&#10;    const lenteY = y + 10;&#10;    ctx.save();&#10;    ctx.fillStyle = &quot;rgba(0,0,0,0.16)&quot;;&#10;    ctx.beginPath(); ctx.ellipse(x, HUERTA_SUELO_Y + 10, 17, 3.2, 0, 0, Math.PI * 2); ctx.fill();&#10;    const puntaY = b.y + 18, mitad = 26;&#10;    const gradHaz = ctx.createLinearGradient(0, lenteY, 0, puntaY);&#10;    gradHaz.addColorStop(0, &quot;rgba(124,255,217,0.55)&quot;);&#10;    gradHaz.addColorStop(1, &quot;rgba(124,255,217,0.10)&quot;);&#10;    ctx.fillStyle = gradHaz;&#10;    ctx.beginPath(); ctx.moveTo(x - 3, lenteY); ctx.lineTo(b.x + mitad, puntaY); ctx.lineTo(b.x - mitad, puntaY); ctx.closePath(); ctx.fill();&#10;    ctx.fillStyle = &quot;rgba(124,255,217,0.22)&quot;; ctx.strokeStyle = &quot;rgba(190,255,235,0.7)&quot;; ctx.lineWidth = 1;&#10;    ctx.beginPath(); ctx.ellipse(b.x, puntaY, mitad, 5, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    const f = 0.5 + 0.5 * Math.sin(t \/ 18);                 \/\/ l\u00ednea de escaneo que barre el haz&#10;    const yy = lenteY + (puntaY - lenteY) * f, cx = x + (b.x - x) * f, hw = 3 + (mitad - 3) * f;&#10;    ctx.strokeStyle = &quot;rgba(220,255,245,0.9)&quot;; ctx.lineWidth = 1.5;&#10;    ctx.beginPath(); ctx.moveTo(cx - hw, yy); ctx.lineTo(cx + hw, yy); ctx.stroke();&#10;    const enlaces = [[tx + d.lado * 58, 118, &quot;#22d3ee&quot;]];&#10;    belarUnidades.forEach(u =&gt; enlaces.push([u.x, u.y - 36, &quot;#ff6fb0&quot;]));&#10;    ctx.lineWidth = 1.5; ctx.setLineDash([5, 5]); ctx.lineDashOffset = -t * 0.6; ctx.globalAlpha = 0.6;&#10;    enlaces.forEach(([ex, ey, col]) =&gt; {&#10;        ctx.strokeStyle = col;&#10;        ctx.beginPath(); ctx.moveTo(x, y + 4); ctx.lineTo(ex, ey); ctx.stroke();&#10;    });&#10;    ctx.setLineDash([]); ctx.globalAlpha = 1;&#10;    enlaces.forEach(([ex, ey, col], i) =&gt; {&#10;        const p = (t \/ 60 + i * 0.33) % 1;&#10;        ctx.fillStyle = col;&#10;        ctx.beginPath(); ctx.arc(x + (ex - x) * p, y + 4 + (ey - y - 4) * p, 2.2, 0, Math.PI * 2); ctx.fill();&#10;    });&#10;    ctx.fillStyle = &quot;#fff&quot;; ctx.strokeStyle = &quot;#333&quot;; ctx.lineWidth = 1.2;&#10;    ctx.fillRect(x - 17, y - 36, 34, 11); ctx.strokeRect(x - 17, y - 36, 34, 11);&#10;    ctx.fillStyle = &quot;#5b21b6&quot;; ctx.font = &quot;bold 8px monospace&quot;; ctx.textAlign = &quot;center&quot;; ctx.textBaseline = &quot;middle&quot;;&#10;    ctx.fillText(&quot;MIIGD1&quot;, x, y - 30);&#10;    ctx.translate(x, y); ctx.rotate(d.ang);&#10;    [[-26, -6, 11, 0], [26, -6, 11, 1.7], [-14, -11, 8, 3.1], [14, -11, 8, 4.4]].forEach(([rx, ry, r, ph], i) =&gt; {&#10;        ctx.strokeStyle = &quot;#5a6066&quot;; ctx.lineWidth = 2.5;&#10;        ctx.beginPath(); ctx.moveTo(rx &gt; 0 ? 10 : -10, -2); ctx.lineTo(rx, ry); ctx.stroke();&#10;        ctx.fillStyle = &quot;rgba(180,200,220,0.25)&quot;;&#10;        ctx.beginPath(); ctx.ellipse(rx, ry - 2, r, 2.6, 0, 0, Math.PI * 2); ctx.fill();&#10;        const L = 2 + (r - 2) * Math.abs(Math.cos(t * 0.9 + ph));&#10;        ctx.strokeStyle = &quot;#20262e&quot;; ctx.lineWidth = 1.6;&#10;        ctx.beginPath(); ctx.moveTo(rx - L, ry - 2); ctx.lineTo(rx + L, ry - 2); ctx.stroke();&#10;        ctx.fillStyle = &quot;#3b4450&quot;; ctx.beginPath(); ctx.arc(rx, ry, 2.4, 0, Math.PI * 2); ctx.fill();&#10;    });&#10;    ctx.strokeStyle = &quot;#5a6066&quot;; ctx.lineWidth = 1.6;             \/\/ patines de aterrizaje&#10;    ctx.beginPath(); ctx.moveTo(-14, 7); ctx.lineTo(-17, 13); ctx.moveTo(14, 7); ctx.lineTo(17, 13); ctx.stroke();&#10;    const gradC = ctx.createLinearGradient(0, -7, 0, 7);&#10;    gradC.addColorStop(0, &quot;#f4f6f8&quot;); gradC.addColorStop(1, &quot;#8f979f&quot;);&#10;    ctx.fillStyle = gradC; ctx.strokeStyle = &quot;#4a4f55&quot;; ctx.lineWidth = 2;&#10;    rectRedondo(-19, -7, 38, 14, 7); ctx.fill(); ctx.stroke();      \/\/ chasis met\u00e1lico&#10;    ctx.fillStyle = &quot;#2c333c&quot;; ctx.strokeStyle = &quot;#20262e&quot;; ctx.lineWidth = 1.5;&#10;    ctx.beginPath(); ctx.ellipse(0, -7, 13, 6, 0, Math.PI, 0); ctx.fill(); ctx.stroke();   \/\/ c\u00fapula&#10;    dibujarLauburu(0, -8, 5, &quot;#ff6fb0&quot;);                                                  \/\/ Lauburu rosa&#10;    ctx.fillStyle = `rgba(34,211,238,${0.5 + 0.4 * Math.sin(t \/ 10)})`;                   \/\/ tira LED inferior&#10;    ctx.fillRect(-9, 4, 18, 2);&#10;    const ledOn = Math.sin(t \/ 8) &gt; 0;&#10;    [[-15, 0, &quot;#22c55e&quot;, true], [15, 0, &quot;#f59e0b&quot;, ledOn]].forEach(([lx, ly, col, on]) =&gt; {   \/\/ LED de estado&#10;        ctx.fillStyle = on ? col : &quot;#3a3f45&quot;;&#10;        ctx.beginPath(); ctx.arc(lx, ly, 2.2, 0, Math.PI * 2); ctx.fill();&#10;        if (on) { ctx.fillStyle = &quot;rgba(255,255,255,0.35)&quot;; ctx.beginPath(); ctx.arc(lx - 0.6, ly - 0.6, 0.9, 0, Math.PI * 2); ctx.fill(); }&#10;    });&#10;    ctx.fillStyle = &quot;#111&quot;; ctx.strokeStyle = &quot;#e7ebee&quot;; ctx.lineWidth = 1.2;             \/\/ lente esc\u00e1ner&#10;    ctx.beginPath(); ctx.arc(0, 9, 4, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#7cffd9&quot;; ctx.beginPath(); ctx.arc(0, 9, 1.8, 0, Math.PI * 2); ctx.fill();&#10;    ctx.restore();&#10;}&#10;const LUR_TINAJAS = [150, 290, 680, 820];&#10;const LUR_POROS = [[-14, 20], [10, 14], [-5, 30], [16, 34], [-16, 42], [3, 48], [-9, 58], [9, 62], [0, 72], [-13, 30], [14, 50], [-4, 40]];&#10;function ollaLUR(x) {&#10;    const gradA = ctx.createLinearGradient(x - 25, 0, x + 25, 0);&#10;    gradA.addColorStop(0, &quot;#d38a55&quot;); gradA.addColorStop(0.5, &quot;#b5622f&quot;); gradA.addColorStop(1, &quot;#8f4a22&quot;);&#10;    ctx.fillStyle = gradA; ctx.strokeStyle = &quot;#5a2f14&quot;; ctx.lineWidth = 2;&#10;    ctx.beginPath();&#10;    ctx.moveTo(x - 6, 306); ctx.lineTo(x - 6, 344); ctx.quadraticCurveTo(x - 24, 346, x - 25, 366);&#10;    ctx.lineTo(x - 7, 430); ctx.quadraticCurveTo(x, 440, x + 7, 430); ctx.lineTo(x + 25, 366);&#10;    ctx.quadraticCurveTo(x + 24, 346, x + 6, 344); ctx.lineTo(x + 6, 306); ctx.closePath(); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;rgba(60,30,10,0.35)&quot;;                                              \/\/ microporos&#10;    LUR_POROS.forEach(([dx, dy]) =&gt; { ctx.beginPath(); ctx.arc(x + dx * (1 - dy \/ 140), 350 + dy, 1.3, 0, Math.PI * 2); ctx.fill(); });&#10;    ctx.strokeStyle = &quot;#0047AB&quot;; ctx.fillStyle = &quot;#0047AB&quot;; ctx.lineWidth = 2.2; ctx.lineCap = 'round';&#10;    ctx.beginPath(); ctx.arc(x, 386, 13, Math.PI, 2 * Math.PI); ctx.stroke();           \/\/ arco&#10;    ctx.beginPath(); ctx.arc(x, 388, 2.6, 0, Math.PI * 2); ctx.fill();                  \/\/ cabeza&#10;    ctx.beginPath();&#10;    ctx.moveTo(x - 13, 386); ctx.lineTo(x, 393); ctx.lineTo(x + 13, 386);               \/\/ brazos&#10;    ctx.moveTo(x, 391); ctx.lineTo(x, 405);                                             \/\/ tronco&#10;    ctx.moveTo(x - 6, 415); ctx.lineTo(x, 405); ctx.lineTo(x + 6, 415);                 \/\/ piernas&#10;    ctx.stroke(); ctx.lineCap = 'butt';&#10;}&#10;let _sprOlla = null, _sprHalo = null;&#10;function spriteOllaLUR() { return _sprOlla || (_sprOlla = conLienzo(80, 150, () =&gt; { ctx.translate(0, -300); ollaLUR(40); })); }&#10;function spriteHaloLUR() {&#10;    return _sprHalo || (_sprHalo = conLienzo(128, 128, () =&gt; { const g = ctx.createRadialGradient(64, 64, 11, 64, 64, 64); g.addColorStop(0, 'rgba(56,170,255,0.38)'); g.addColorStop(1, 'rgba(56,170,255,0)'); ctx.fillStyle = g; ctx.fillRect(0, 0, 128, 128); }));&#10;}&#10;function dibujarTinajaLUR(x, t, i) {&#10;    const cy = 396, r = 58 + Math.sin(t \/ 40 + i) * 2.5;&#10;    ctx.drawImage(spriteHaloLUR(), x - r, cy - r, r * 2, r * 2);                    \/\/ halo de humedad: sprite escalado&#10;    ctx.strokeStyle = &quot;rgba(140,210,255,0.6)&quot;; ctx.lineWidth = 1.5; ctx.setLineDash([4, 5]); ctx.lineDashOffset = -t * 0.3;&#10;    ctx.beginPath(); ctx.arc(x, cy, r, 0, Math.PI * 2); ctx.stroke(); ctx.setLineDash([]);&#10;    ctx.fillStyle = &quot;rgba(56,170,255,0.18)&quot;;&#10;    ctx.beginPath(); ctx.ellipse(x, 318, 40, 15, 0, 0, Math.PI * 2); ctx.fill();&#10;    ctx.strokeStyle = &quot;#e3d2a6&quot;; ctx.lineWidth = 1.2; ctx.lineCap = 'round';           \/\/ ra\u00edces hacia la humedad&#10;    [-26, -9, 9, 26].forEach((k, j) =&gt; {&#10;        ctx.beginPath(); ctx.moveTo(x + k, HUERTA_CORTE_Y);&#10;        ctx.quadraticCurveTo(x + k * 1.2, HUERTA_CORTE_Y + 14, x + k * 1.5, HUERTA_CORTE_Y + 26 + (j % 2) * 6); ctx.stroke();&#10;    });&#10;    ctx.lineCap = 'butt';&#10;    for (let k = 0; k &lt; 6; k++) {                                                       \/\/ agua que rezuma por los poros&#10;        const p = (t \/ 55 + k \/ 6 + i * 0.13) % 1, a = Math.PI * (1.1 + k * 0.16);&#10;        ctx.fillStyle = &quot;rgba(126,200,255,&quot; + (0.8 * (1 - p)).toFixed(2) + &quot;)&quot;;&#10;        ctx.beginPath(); ctx.arc(x + Math.cos(a) * (24 + p * (r - 24)), cy + Math.sin(a) * (24 + p * (r - 24)), 2, 0, Math.PI * 2); ctx.fill();&#10;    }&#10;    ctx.drawImage(spriteOllaLUR(), x - 40, 300);                                          \/\/ olla de arcilla, poros e \u00cdndalo: sprite&#10;    ctx.fillStyle = &quot;#aab2ba&quot;; ctx.strokeStyle = &quot;#5a6066&quot;; ctx.lineWidth = 1.5;&#10;    ctx.fillRect(x - 9, 310, 18, 11); ctx.strokeRect(x - 9, 310, 18, 11);&#10;    ctx.fillStyle = `rgba(34,211,238,${0.55 + 0.35 * Math.sin(t \/ 12 + i)})`; ctx.fillRect(x - 7, 314, 14, 2.5);&#10;    ctx.fillStyle = &quot;#2c333c&quot;; ctx.strokeStyle = &quot;#20262e&quot;;&#10;    ctx.fillRect(x - 8, 301, 16, 9); ctx.strokeRect(x - 8, 301, 16, 9);&#10;    [-12, 12].forEach(sx =&gt; {&#10;        ctx.fillStyle = &quot;#2c333c&quot;; ctx.beginPath(); ctx.arc(x + sx, 316, 3, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;        ctx.fillStyle = &quot;#38bdf8&quot;; ctx.beginPath(); ctx.arc(x + sx, 316, 1.4, 0, Math.PI * 2); ctx.fill();&#10;    });&#10;    ctx.strokeStyle = &quot;#5a6066&quot;; ctx.lineWidth = 1.5;&#10;    ctx.beginPath(); ctx.moveTo(x, 301); ctx.lineTo(x, 292); ctx.stroke();&#10;    ctx.fillStyle = Math.sin(t \/ 14 + i * 2) &gt; -0.2 ? &quot;#4ade80&quot; : &quot;#3a3f45&quot;;&#10;    ctx.beginPath(); ctx.arc(x, 291, 2.3, 0, Math.PI * 2); ctx.fill();&#10;}&#10;function dibujarRiegoLUR(t) {&#10;    ctx.save();&#10;    LUR_TINAJAS.forEach((x, i) =&gt; dibujarTinajaLUR(x, t, i));&#10;    ctx.fillStyle = &quot;#e3d2a6&quot;; ctx.font = &quot;11px 'Comic Sans MS', sans-serif&quot;; ctx.textAlign = &quot;left&quot;;&#10;    ctx.fillText(&quot;\ud83d\udca7 Riego subterr\u00e1neo LUR \u00b7 tinajas de arcilla microporosa&quot;, 16, 528);&#10;    ctx.restore();&#10;}&#10;function dibujarTractorAutonomo(x, y, t, escala = 1, apero = 'arado', orientacion = 1) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.scale(escala, escala);&#10;    const anchoChasis = 92, altoChasis = 40, diametroRueda = 30, R = diametroRueda \/ 2;&#10;    const yChasis = -R - altoChasis;&#10;    const sg = ctx.createRadialGradient(0, R + 1, 4, 0, R + 1, 62);&#10;    sg.addColorStop(0, &quot;rgba(0,0,0,0.38)&quot;); sg.addColorStop(1, &quot;rgba(0,0,0,0)&quot;);&#10;    ctx.fillStyle = sg; ctx.beginPath(); ctx.ellipse(0, R + 1, 62, 7, 0, 0, Math.PI * 2); ctx.fill();&#10;    const gradChasis = ctx.createLinearGradient(0, yChasis, 0, yChasis + altoChasis);&#10;    gradChasis.addColorStop(0, &quot;#f1f3f5&quot;); gradChasis.addColorStop(0.18, &quot;#d5d9dd&quot;); gradChasis.addColorStop(0.7, &quot;#9a9fa5&quot;); gradChasis.addColorStop(1, &quot;#6c7176&quot;);&#10;    ctx.fillStyle = gradChasis; ctx.strokeStyle = &quot;#3f4246&quot;; ctx.lineWidth = 2.5;&#10;    rectRedondo(-anchoChasis \/ 2, yChasis, anchoChasis, altoChasis, 5); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;rgba(255,255,255,0.55)&quot;;&#10;    rectRedondo(-anchoChasis \/ 2 + 5, yChasis + 3, anchoChasis - 10, 4, 2); ctx.fill();&#10;    ctx.strokeStyle = &quot;rgba(60,64,68,0.6)&quot;; ctx.lineWidth = 1;&#10;    [-30, 30].forEach(px =&gt; { ctx.beginPath(); ctx.moveTo(px, yChasis + 8); ctx.lineTo(px, yChasis + altoChasis - 9); ctx.stroke(); });&#10;    [-1, 1].forEach(d =&gt; { for (let i = 0; i &lt; 4; i++) { ctx.beginPath(); ctx.moveTo(d * 36 - 6, yChasis + 11 + i * 4); ctx.lineTo(d * 36 + 6, yChasis + 11 + i * 4); ctx.stroke(); } });&#10;    ctx.fillStyle = &quot;#5c6166&quot;;&#10;    [[-42, yChasis + 5], [42, yChasis + 5], [-42, yChasis + altoChasis - 11], [42, yChasis + altoChasis - 11]].forEach(([px, py]) =&gt; { ctx.beginPath(); ctx.arc(px, py, 1.3, 0, Math.PI * 2); ctx.fill(); });&#10;    const brilloLed = 0.6 + Math.sin(t \/ 12) * 0.35;&#10;    const lg = ctx.createRadialGradient(0, yChasis + altoChasis - 4, 2, 0, yChasis + altoChasis - 4, 60);&#10;    lg.addColorStop(0, `rgba(34,211,238,${0.35 * brilloLed})`); lg.addColorStop(1, &quot;rgba(34,211,238,0)&quot;);&#10;    ctx.fillStyle = lg; ctx.fillRect(-60, yChasis + altoChasis - 20, 120, 28);&#10;    ctx.fillStyle = `rgba(34,211,238,${brilloLed})`;&#10;    rectRedondo(-anchoChasis \/ 2 + 4, yChasis + altoChasis - 6, anchoChasis - 8, 4, 2); ctx.fill();&#10;    [-1, 1].forEach(d =&gt; {&#10;        const fg = ctx.createRadialGradient(d * 44, yChasis + 14, 0, d * 44, yChasis + 14, 11);&#10;        fg.addColorStop(0, &quot;rgba(255,252,215,0.9)&quot;); fg.addColorStop(1, &quot;rgba(255,252,215,0)&quot;);&#10;        ctx.fillStyle = fg; ctx.beginPath(); ctx.arc(d * 44, yChasis + 14, 11, 0, Math.PI * 2); ctx.fill();&#10;        ctx.fillStyle = &quot;#fffbe0&quot;; ctx.strokeStyle = &quot;#555&quot;; ctx.lineWidth = 1;&#10;        rectRedondo(d * 44 - 3, yChasis + 11, 6, 6, 2); ctx.fill(); ctx.stroke();&#10;    });&#10;    const giro = t \/ 9 * orientacion;&#10;    [-anchoChasis \/ 2 + 16, anchoChasis \/ 2 - 16].forEach(rx =&gt; {&#10;        const tg = ctx.createRadialGradient(rx - 3, -3, 3, rx, 0, R);&#10;        tg.addColorStop(0, &quot;#3b3b3b&quot;); tg.addColorStop(1, &quot;#0d0d0d&quot;);&#10;        ctx.fillStyle = tg; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;        ctx.beginPath(); ctx.arc(rx, 0, R, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;        ctx.save(); ctx.translate(rx, 0); ctx.rotate(giro);&#10;        ctx.strokeStyle = &quot;#2c2c2c&quot;; ctx.lineWidth = 3;                           \/\/ tacos del dibujo del neum\u00e1tico&#10;        for (let i = 0; i &lt; 14; i++) { const a = i * Math.PI * 2 \/ 14; ctx.beginPath(); ctx.moveTo(Math.cos(a) * (R - 3.5), Math.sin(a) * (R - 3.5)); ctx.lineTo(Math.cos(a) * (R - 0.5), Math.sin(a) * (R - 0.5)); ctx.stroke(); }&#10;        const cg = ctx.createRadialGradient(-1.5, -1.5, 1, 0, 0, 8);&#10;        cg.addColorStop(0, &quot;#a5f3fc&quot;); cg.addColorStop(0.6, &quot;#22d3ee&quot;); cg.addColorStop(1, &quot;#0e7490&quot;);&#10;        ctx.fillStyle = cg; ctx.beginPath(); ctx.arc(0, 0, 8, 0, Math.PI * 2); ctx.fill();&#10;        ctx.strokeStyle = &quot;#0b5d70&quot;; ctx.lineWidth = 1.2;&#10;        for (let i = 0; i &lt; 5; i++) { const a = i * Math.PI * 2 \/ 5; ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(Math.cos(a) * 7.5, Math.sin(a) * 7.5); ctx.stroke(); }&#10;        ctx.fillStyle = &quot;#083a47&quot;; ctx.beginPath(); ctx.arc(0, 0, 2, 0, Math.PI * 2); ctx.fill();&#10;        ctx.restore();&#10;        ctx.strokeStyle = &quot;rgba(255,255,255,0.18)&quot;; ctx.lineWidth = 2;               \/\/ brillo del caucho&#10;        ctx.beginPath(); ctx.arc(rx, 0, R - 2, Math.PI * 1.1, Math.PI * 1.45); ctx.stroke();&#10;        ctx.strokeStyle = &quot;#50555a&quot;; ctx.lineWidth = 3;                               \/\/ guardabarros&#10;        ctx.beginPath(); ctx.arc(rx, 0, R + 3, Math.PI * 1.08, Math.PI * 1.92); ctx.stroke();&#10;    });&#10;    ctx.fillStyle = &quot;#fff&quot;; ctx.strokeStyle = &quot;#333&quot;; ctx.lineWidth = 1.5;&#10;    ctx.fillRect(-25, yChasis + altoChasis \/ 2 - 7, 50, 14);&#10;    ctx.strokeRect(-25, yChasis + altoChasis \/ 2 - 7, 50, 14);&#10;    ctx.fillStyle = &quot;#222&quot;; ctx.font = &quot;bold 8px monospace&quot;; ctx.textAlign = &quot;center&quot;; ctx.textBaseline = &quot;middle&quot;;&#10;    ctx.fillText(&quot;MIIGT1&quot;, 0, yChasis + altoChasis \/ 2 + 1); ctx.textBaseline = &quot;alphabetic&quot;;&#10;    [-0.72, -0.24, 0.24, 0.72].forEach((f, i) =&gt; {&#10;        const lx = f * anchoChasis \/ 2;&#10;        ctx.fillStyle = &quot;#4a4d51&quot;; ctx.fillRect(lx - 6, yChasis - 2, 12, 3);&#10;        const dg = ctx.createRadialGradient(lx - 1.5, yChasis - 3, 0.5, lx, yChasis - 1, 5.5);&#10;        dg.addColorStop(0, &quot;#ff8a93&quot;); dg.addColorStop(0.5, &quot;#e11d2e&quot;); dg.addColorStop(1, &quot;#6b0d16&quot;);&#10;        ctx.fillStyle = dg; ctx.strokeStyle = &quot;#5a0b13&quot;; ctx.lineWidth = 1;&#10;        ctx.beginPath(); ctx.arc(lx, yChasis - 1, 5, Math.PI, 0); ctx.fill(); ctx.stroke();&#10;        const ba = 0.35 + 0.35 * Math.sin(t \/ 5 + i * 1.6);&#10;        ctx.fillStyle = `rgba(255,170,175,${ba})`; ctx.beginPath(); ctx.arc(lx + 1.5, yChasis - 3.5, 1.2, 0, Math.PI * 2); ctx.fill();&#10;    });&#10;    ctx.strokeStyle = &quot;#6d28d9&quot;; ctx.lineWidth = 3;&#10;    ctx.beginPath(); ctx.moveTo(0, yChasis); ctx.lineTo(0, yChasis - 22); ctx.stroke();&#10;    ctx.strokeStyle = &quot;rgba(255,255,255,0.35)&quot;; ctx.lineWidth = 1;&#10;    ctx.beginPath(); ctx.moveTo(-0.8, yChasis); ctx.lineTo(-0.8, yChasis - 22); ctx.stroke();&#10;    const gg = ctx.createRadialGradient(-1.8, yChasis - 26, 0.8, 0, yChasis - 24, 6);&#10;    gg.addColorStop(0, &quot;#f3ecff&quot;); gg.addColorStop(0.5, &quot;#a78bfa&quot;); gg.addColorStop(1, &quot;#4c1d95&quot;);&#10;    ctx.fillStyle = gg; ctx.strokeStyle = &quot;#4c1d95&quot;; ctx.lineWidth = 1.5;&#10;    ctx.beginPath(); ctx.arc(0, yChasis - 24, 5, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.strokeStyle = &quot;rgba(196,181,253,0.7)&quot;; ctx.lineWidth = 1;&#10;    ctx.beginPath(); ctx.ellipse(0, yChasis - 24, 7.5, 2, 0, 0, Math.PI * 2); ctx.stroke();&#10;    ctx.save();&#10;    ctx.scale(orientacion, 1);   \/\/ el apero se orienta hacia el lado del \u00e1rbol\/zona m\u00e1s cercana&#10;    if (apero === 'arado') {&#10;        ctx.strokeStyle = &quot;#5a5d61&quot;; ctx.lineWidth = 4;&#10;        ctx.beginPath(); ctx.moveTo(-anchoChasis \/ 2, yChasis + altoChasis - 8); ctx.lineTo(-anchoChasis \/ 2 - 22, yChasis + altoChasis + 6); ctx.stroke();&#10;        const ax = -anchoChasis \/ 2 - 34, ay = yChasis + altoChasis + 4;&#10;        ctx.fillStyle = &quot;#9aa0a6&quot;; ctx.strokeStyle = &quot;#4a4d51&quot;; ctx.lineWidth = 2;&#10;        ctx.beginPath();&#10;        ctx.moveTo(ax, ay - 4); ctx.lineTo(ax - 6, ay + 16); ctx.lineTo(ax + 10, ay + 16); ctx.lineTo(ax + 8, ay - 4);&#10;        ctx.closePath(); ctx.fill(); ctx.stroke();&#10;        ctx.fillStyle = &quot;#e11d2e&quot;; ctx.strokeStyle = &quot;#7a0f18&quot;; ctx.lineWidth = 1.5;&#10;        ctx.beginPath();&#10;        ctx.moveTo(ax + 2, ay - 11); ctx.lineTo(ax + 9, ay - 11); ctx.lineTo(ax + 6, ay - 2); ctx.lineTo(ax + 4, ay - 2);&#10;        ctx.closePath(); ctx.fill(); ctx.stroke();&#10;        ctx.fillStyle = &quot;#3a3a3a&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 1.5;&#10;        [ax - 5, ax + 11].forEach(rx =&gt; {&#10;            ctx.beginPath(); ctx.ellipse(rx, ay + 20, 6, 6, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;        });&#10;    } else {&#10;        const bx = anchoChasis \/ 2 - 6, by = yChasis + 6;&#10;        ctx.lineCap = 'round';&#10;        ctx.strokeStyle = &quot;#eef0f2&quot;; ctx.lineWidth = 8;&#10;        ctx.beginPath(); ctx.moveTo(bx, by); ctx.lineTo(bx + 18, by - 24); ctx.stroke();&#10;        ctx.strokeStyle = &quot;#eef0f2&quot;; ctx.lineWidth = 7;&#10;        ctx.beginPath(); ctx.moveTo(bx + 18, by - 24); ctx.lineTo(bx + 30, by - 42); ctx.stroke();&#10;        ctx.strokeStyle = &quot;#ff7a1a&quot;; ctx.lineWidth = 3;               \/\/ franja naranja central&#10;        ctx.beginPath(); ctx.moveTo(bx + 5, by - 6); ctx.lineTo(bx + 14, by - 19); ctx.stroke();&#10;        ctx.strokeStyle = &quot;#eef0f2&quot;; ctx.lineWidth = 3;                \/\/ pinza&#10;        ctx.beginPath(); ctx.moveTo(bx + 30, by - 42); ctx.lineTo(bx + 37, by - 48); ctx.stroke();&#10;        ctx.beginPath(); ctx.moveTo(bx + 30, by - 42); ctx.lineTo(bx + 38, by - 39); ctx.stroke();&#10;        ctx.lineCap = 'butt';&#10;        ctx.fillStyle = &quot;#c7c7c7&quot;; ctx.strokeStyle = &quot;#7a7a7a&quot;; ctx.lineWidth = 1;&#10;        [[bx, by], [bx + 18, by - 24], [bx + 30, by - 42]].forEach(([jx, jy]) =&gt; {&#10;            ctx.beginPath(); ctx.arc(jx, jy, 4, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;        });&#10;    }&#10;    ctx.restore();&#10;    ctx.restore();&#10;}&#10;const HUERTA_BANCO = { x: 380, y: HUERTA_CORTE_Y + 26, w: 200, h: 164 };&#10;const VARIEDADES = [&#10;    { id: 'tomate_rosa',      nombre: 'Tomate Rosa',            emoji: '\ud83c\udf45', color: '#e8749a', forma: 'redondo',  madura: 14, desc: 'Piel fina, muy dulce y carnoso.' },&#10;    { id: 'tomate_crimea',    nombre: 'Tomate Negro de Crimea', emoji: '\ud83c\udf45', color: '#5b2a3a', forma: 'redondo',  madura: 16, desc: 'Antiguo y ruso: sabor ahumado y complejo.' },&#10;    { id: 'trigo_espelta',    nombre: 'Trigo Espelta',          emoji: '\ud83c\udf3e', color: '#d8b24a', forma: 'espiga',   madura: 12, desc: 'Cereal ancestral, r\u00fastico y arom\u00e1tico.' },&#10;    { id: 'zanahoria_morada', nombre: 'Zanahoria Morada',       emoji: '\ud83e\udd55', color: '#7a3fa0', forma: 'raiz',     madura: 11, desc: 'Variedad milenaria, rica en antocianinas.' },&#10;    { id: 'pimiento_padron',  nombre: 'Pimiento de Padr\u00f3n',     emoji: '\ud83c\udf36\ufe0f', color: '#4a9a3a', forma: 'alargado', madura: 13, desc: 'Unos pican y otros no: pura tradici\u00f3n.' },&#10;    { id: 'patata_kennebec',  nombre: 'Patata Kennebec',        emoji: '\ud83e\udd54', color: '#c9a46a', forma: 'raiz',     madura: 15, desc: 'Su almid\u00f3n, con las algas, da el biopl\u00e1stico.' }&#10;];&#10;const BANCO_STOCK = {};&#10;VARIEDADES.forEach(v =&gt; { BANCO_STOCK[v.id] = 40; });&#10;const LOTE_SEMILLAS = 10;                       \/\/ semillas que el tractor carga de una vez&#10;const tractorCarga = { id: null, n: 0 };        \/\/ semilla activa del tractor&#10;const huertaSiembra = [];                       \/\/ plantas sembradas: { slot, x, id, plantadoEn }&#10;const HUERTA_SLOTS = [];&#10;for (let sx = 150; sx &lt;= 810; sx += 30) HUERTA_SLOTS.push(sx);&#10;const SIEMBRA_Y = 178;                          \/\/ l\u00ednea de suelo del carril del tractor&#10;let bancoAbierto = false;&#10;let dialogoCosecha = null;&#10;let cestaCosecha = 0;&#10;let huertaToast = null;&#10;let huertaFlashBanco = 0;&#10;const BANCO_MODAL = { x: 150, y: 56, w: 660, h: 430 };&#10;const BANCO_CERRAR = { x: BANCO_MODAL.x + BANCO_MODAL.w - 42, y: BANCO_MODAL.y + 10, w: 30, h: 30 };&#10;const DIALOGO = { x: 290, y: 130, w: 380, h: 210 };&#10;const DIALOGO_BTN1 = { x: DIALOGO.x + 20, y: DIALOGO.y + 104, w: DIALOGO.w - 40, h: 38 };&#10;const DIALOGO_BTN2 = { x: DIALOGO.x + 20, y: DIALOGO.y + 152, w: DIALOGO.w - 40, h: 38 };&#10;function filaBanco(i) {&#10;    const y = BANCO_MODAL.y + 82 + i * 54;&#10;    return { y, h: 50, btn: { x: BANCO_MODAL.x + BANCO_MODAL.w - 112, y: y + 8, w: 88, h: 34 } };&#10;}&#10;function varPorId(id) { return VARIEDADES.find(v =&gt; v.id === id); }&#10;function dentroRect(x, y, r) { return x &gt;= r.x &amp;&amp; x &lt;= r.x + r.w &amp;&amp; y &gt;= r.y &amp;&amp; y &lt;= r.y + r.h; }&#10;function rectRedondo(x, y, w, h, r) {&#10;    ctx.beginPath();&#10;    ctx.moveTo(x + r, y);&#10;    ctx.arcTo(x + w, y, x + w, y + h, r);&#10;    ctx.arcTo(x + w, y + h, x, y + h, r);&#10;    ctx.arcTo(x, y + h, x, y, r);&#10;    ctx.arcTo(x, y, x + w, y, r);&#10;    ctx.closePath();&#10;}&#10;function mostrarToast(texto) { huertaToast = { texto, hasta: Date.now() + 2800 }; }&#10;function huertaTractorX() { return 140 + (820 - 140) * (0.5 + 0.5 * Math.sin(t \/ 220)); }&#10;const HUERTA_ZONA_ARBOL_IZQ_X = 150, HUERTA_ZONA_ARBOL_DER_X = 810;&#10;let aperoManual = null;&#10;function aperoActivo(tx) {&#10;    if (aperoManual) return aperoManual;&#10;    return (tx &lt;= HUERTA_ZONA_ARBOL_IZQ_X || tx &gt;= HUERTA_ZONA_ARBOL_DER_X) ? 'brazo' : 'arado';&#10;}&#10;const APERO_BOTON = { x: 830, y: 12, w: 122, h: 26 };&#10;function progresoSiembra(p) {&#10;    return Math.min(1, (Date.now() - p.plantadoEn) \/ 1000 \/ varPorId(p.id).madura * (p.abonada ? 1.3 : 1) * ({ primavera: 1.1, verano: 1.15, oto\u00f1o: .9, invierno: .6 }[obtenerEstacion()] || 1));      \/\/ con compost crece un 30 % m\u00e1s r\u00e1pido&#10;}&#10;function cargarTractor(id) {&#10;    if (tractorCarga.id &amp;&amp; tractorCarga.n &gt; 0) BANCO_STOCK[tractorCarga.id] += tractorCarga.n;&#10;    const n = Math.min(LOTE_SEMILLAS, BANCO_STOCK[id]);&#10;    tractorCarga.id = n &gt; 0 ? id : null;&#10;    tractorCarga.n = n;&#10;    BANCO_STOCK[id] -= n;&#10;    mostrarToast(n &gt; 0 ? `\ud83d\ude9c MIIGT1 cargado: ${varPorId(id).nombre} \u00d7${n}` : 'Ya no quedan semillas de esa variedad');&#10;}&#10;function actualizarSiembra() {&#10;    if (!tractorCarga.id || tractorCarga.n &lt;= 0) return;&#10;    const tx = huertaTractorX();&#10;    HUERTA_SLOTS.forEach((sx, i) =&gt; {&#10;        if (tractorCarga.n &lt;= 0 || Math.abs(sx - tx) &gt; 8) return;&#10;        if (huertaSiembra.some(p =&gt; p.slot === i)) return;&#10;        huertaSiembra.push({ slot: i, x: sx, id: tractorCarga.id, plantadoEn: Date.now(), abonada: SiloCompost.usarCompost() });&#10;        tractorCarga.n--; { const vv = varPorId(tractorCarga.id || huertaSiembra[huertaSiembra.length - 1].id); if (vv) diarioNota('herbario', vv.id, vv.nombre, vv.emoji); }&#10;    });&#10;    if (tractorCarga.n &lt;= 0) { tractorCarga.n = 0; tractorCarga.id = null; }&#10;}&#10;function cosechar(enviarAlBanco) {&#10;    const p = dialogoCosecha;&#10;    if (!p) return;&#10;    const v = varPorId(p.id);&#10;    const i = huertaSiembra.indexOf(p);&#10;    if (i &gt;= 0) huertaSiembra.splice(i, 1);&#10;    const bono = Math.min(2, p.polinizada || 0);                      \/\/ +1 por cada visita de abeja (m\u00e1x. +2)&#10;    cestaCosecha += 3 + bono; Kutxa.aportar(0.5); SiloCompost.cosecha(bono);                  \/\/ excedente al silo y restos a la compostera&#10;    if (enviarAlBanco) {&#10;        BANCO_STOCK[p.id] += 4;&#10;        huertaFlashBanco = Date.now() + 1800;&#10;        mostrarToast(`\u2744\ufe0f +4 semillas de ${v.nombre} conservadas a -18 \u00b0C` + (bono ? ` \u00b7 \ud83d\udc1d +${bono} en la cesta` : ''));&#10;    } else {&#10;        mostrarToast(`\ud83e\uddfa Cosechado: ${v.nombre} \u00d7${3 + bono}` + (bono ? ` \u00b7 \ud83d\udc1d +${bono} por polinizaci\u00f3n` : ''));&#10;    }&#10;    dialogoCosecha = null;&#10;}&#10;function manejarToqueHuerta(x, y) {&#10;    if (dentroRect(x, y, APERO_BOTON)) {&#10;        aperoManual = aperoManual === null ? 'arado' : (aperoManual === 'arado' ? 'brazo' : null);&#10;        mostrarToast(aperoManual ? `\ud83d\udd27 Apero fijado: ${aperoManual === 'arado' ? '\ud83d\udd29 Arado subsolador' : '\ud83e\uddbe Brazo rob\u00f3tico'}` : '\ud83d\udd04 Apero en modo autom\u00e1tico');&#10;        return;&#10;    }&#10;    if (dialogoCosecha) {&#10;        if (dentroRect(x, y, DIALOGO_BTN1)) cosechar(false);&#10;        else if (dentroRect(x, y, DIALOGO_BTN2)) cosechar(true);&#10;        else if (!dentroRect(x, y, DIALOGO)) dialogoCosecha = null;&#10;        return;&#10;    }&#10;    if (bancoAbierto) {&#10;        if (dentroRect(x, y, BANCO_CERRAR) || !dentroRect(x, y, BANCO_MODAL)) { bancoAbierto = false; return; }&#10;        VARIEDADES.forEach((v, i) =&gt; {&#10;            if (dentroRect(x, y, filaBanco(i).btn) &amp;&amp; BANCO_STOCK[v.id] &gt; 0) cargarTractor(v.id);&#10;        });&#10;        return;&#10;    }&#10;    if (dentroRect(x, y, HUERTA_BANCO)) { bancoAbierto = true; return; }&#10;    for (const p of huertaSiembra) {&#10;        if (progresoSiembra(p) &gt;= 1 &amp;&amp; Math.hypot(x - p.x, y - (SIEMBRA_Y - 10)) &lt; 22) { dialogoCosecha = p; return; }&#10;    }&#10;}&#10;function dibujarSiembra() {&#10;    huertaSiembra.forEach(p =&gt; {&#10;        const v = varPorId(p.id), prog = progresoSiembra(p), x = p.x, y = SIEMBRA_Y;&#10;        const h = 5 + 15 * prog;&#10;        ctx.strokeStyle = &quot;#3f8a34&quot;; ctx.lineWidth = 2;&#10;        ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(x, y - h); ctx.stroke();&#10;        ctx.fillStyle = &quot;#57a944&quot;;&#10;        ctx.beginPath(); ctx.ellipse(x - 4, y - h * 0.55, 4, 2, -0.5, 0, Math.PI * 2); ctx.fill();&#10;        ctx.beginPath(); ctx.ellipse(x + 4, y - h * 0.75, 4, 2, 0.5, 0, Math.PI * 2); ctx.fill();&#10;        if (prog &lt; 1) return;&#10;        ctx.fillStyle = v.color; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 1;&#10;        if (v.forma === 'redondo') {&#10;            ctx.beginPath(); ctx.arc(x, y - h - 2, 4.5, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;            ctx.beginPath(); ctx.arc(x + 5, y - h + 4, 3.5, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;        } else if (v.forma === 'espiga') {&#10;            ctx.beginPath(); ctx.ellipse(x, y - h - 3, 2.8, 6.5, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;        } else if (v.forma === 'raiz') {&#10;            ctx.beginPath(); ctx.moveTo(x - 5, y); ctx.lineTo(x + 5, y); ctx.lineTo(x, y + 8); ctx.closePath(); ctx.fill(); ctx.stroke();&#10;        } else {&#10;            ctx.beginPath(); ctx.ellipse(x + 3, y - h + 3, 2.8, 6.5, 0.3, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;        }&#10;        ctx.strokeStyle = `rgba(255,255,255,${0.55 + 0.4 * Math.sin(t \/ 8)})`; ctx.lineWidth = 2;&#10;        ctx.beginPath(); ctx.arc(x, y - h \/ 2 - 2, 16, 0, Math.PI * 2); ctx.stroke();   \/\/ &quot;lista para cosechar&quot;&#10;    });&#10;}&#10;function dibujarIndicadorSemilla(tx) {&#10;    const v = tractorCarga.id ? varPorId(tractorCarga.id) : null;&#10;    const txt = v ? `${v.emoji} ${v.nombre} \u00d7${tractorCarga.n}` : '\ud83c\udf30 Sin semilla';&#10;    ctx.save();&#10;    ctx.font = &quot;bold 12px 'Comic Sans MS', sans-serif&quot;;&#10;    const w = ctx.measureText(txt).width + 20;&#10;    const px = Math.max(8, Math.min(canvas.width - w - 8, tx - w \/ 2)), py = 184;&#10;    ctx.fillStyle = &quot;rgba(255,255,255,0.94)&quot;; ctx.strokeStyle = v ? v.color : &quot;#999&quot;; ctx.lineWidth = 3;&#10;    rectRedondo(px, py, w, 22, 11); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#333&quot;; ctx.textAlign = &quot;center&quot;; ctx.textBaseline = &quot;middle&quot;;&#10;    ctx.fillText(txt, px + w \/ 2, py + 12);&#10;    ctx.restore();&#10;}&#10;function dibujarSelectorApero(apero) {&#10;    const b = APERO_BOTON;&#10;    ctx.save();&#10;    ctx.fillStyle = aperoManual ? &quot;#3d95b8&quot; : &quot;rgba(255,255,255,0.9)&quot;;&#10;    ctx.strokeStyle = &quot;#333&quot;; ctx.lineWidth = 2;&#10;    rectRedondo(b.x, b.y, b.w, b.h, 13); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = aperoManual ? &quot;#fff&quot; : &quot;#333&quot;;&#10;    ctx.font = &quot;bold 12px 'Comic Sans MS', sans-serif&quot;;&#10;    ctx.textAlign = &quot;center&quot;; ctx.textBaseline = &quot;middle&quot;;&#10;    const etiqueta = apero === 'arado' ? &quot;\ud83d\udd29 Arado&quot; : &quot;\ud83e\uddbe Brazo&quot;;&#10;    ctx.fillText(aperoManual ? etiqueta : `\ud83d\udd04 ${etiqueta}`, b.x + b.w \/ 2, b.y + b.h \/ 2 + 1);&#10;    ctx.textBaseline = &quot;alphabetic&quot;;&#10;    ctx.restore();&#10;}&#10;function dibujarBancoInterfaz() {&#10;    ctx.save();&#10;    ctx.textBaseline = &quot;alphabetic&quot;;&#10;    if (bancoAbierto) {&#10;        const m = BANCO_MODAL;&#10;        ctx.fillStyle = &quot;rgba(10,20,30,0.55)&quot;; ctx.fillRect(0, 0, canvas.width, canvas.height);&#10;        ctx.fillStyle = &quot;#eaf6fc&quot;; ctx.strokeStyle = &quot;#5aa9c9&quot;; ctx.lineWidth = 3;&#10;        rectRedondo(m.x, m.y, m.w, m.h, 16); ctx.fill(); ctx.stroke();&#10;        ctx.textAlign = &quot;left&quot;; ctx.fillStyle = &quot;#1d5d7a&quot;;&#10;        ctx.font = &quot;bold 20px 'Comic Sans MS', sans-serif&quot;;&#10;        ctx.fillText(&quot;\u2744\ufe0f Banco de Semillas \u00b7 -18 \u00b0C&quot;, m.x + 24, m.y + 36);&#10;        ctx.font = &quot;12px 'Comic Sans MS', sans-serif&quot;; ctx.fillStyle = &quot;#4a7f96&quot;;&#10;        ctx.fillText(&quot;Variedades antiguas y tradicionales. Elige una para cargarla en el tractor MIIGT1.&quot;, m.x + 24, m.y + 56);&#10;        ctx.fillStyle = &quot;#7a9aa8&quot;; ctx.font = &quot;italic 11px 'Comic Sans MS', sans-serif&quot;;&#10;        ctx.fillText(&quot;\ud83e\udde0 Gestionado por LUR, el sistema inteligente del suelo&quot;, m.x + 24, m.y + 72);&#10;        ctx.fillStyle = &quot;#c95a5a&quot;; rectRedondo(BANCO_CERRAR.x, BANCO_CERRAR.y, 30, 30, 8); ctx.fill();&#10;        ctx.fillStyle = &quot;#fff&quot;; ctx.textAlign = &quot;center&quot;; ctx.font = &quot;bold 16px Arial&quot;;&#10;        ctx.fillText(&quot;\u2715&quot;, BANCO_CERRAR.x + 15, BANCO_CERRAR.y + 21);&#10;        VARIEDADES.forEach((v, i) =&gt; {&#10;            const f = filaBanco(i), activo = tractorCarga.id === v.id, agotado = BANCO_STOCK[v.id] &lt;= 0;&#10;            ctx.fillStyle = activo ? &quot;#e9f8e8&quot; : &quot;#fff&quot;; ctx.strokeStyle = activo ? &quot;#4aa63c&quot; : &quot;#b9d8e6&quot;; ctx.lineWidth = activo ? 3 : 2;&#10;            rectRedondo(m.x + 16, f.y, m.w - 32, f.h, 10); ctx.fill(); ctx.stroke();&#10;            ctx.font = &quot;26px Arial&quot;; ctx.textAlign = &quot;center&quot;; ctx.fillStyle = &quot;#000&quot;;&#10;            ctx.fillText(v.emoji, m.x + 44, f.y + 37);&#10;            ctx.fillStyle = v.color; ctx.beginPath(); ctx.arc(m.x + 74, f.y + 20, 5, 0, Math.PI * 2); ctx.fill();&#10;            ctx.textAlign = &quot;left&quot;; ctx.fillStyle = &quot;#222&quot;; ctx.font = &quot;bold 15px 'Comic Sans MS', sans-serif&quot;;&#10;            ctx.fillText(v.nombre, m.x + 86, f.y + 24);&#10;            ctx.fillStyle = &quot;#666&quot;; ctx.font = &quot;12px 'Comic Sans MS', sans-serif&quot;;&#10;            ctx.fillText(v.desc, m.x + 74, f.y + 44);&#10;            ctx.textAlign = &quot;center&quot;; ctx.fillStyle = &quot;#1d5d7a&quot;; ctx.font = &quot;bold 15px 'Comic Sans MS', sans-serif&quot;;&#10;            ctx.fillText(`\u2744\ufe0f ${BANCO_STOCK[v.id]}`, m.x + m.w - 170, f.y + 26);&#10;            ctx.fillStyle = &quot;#7a9aa8&quot;; ctx.font = &quot;10px 'Comic Sans MS', sans-serif&quot;;&#10;            ctx.fillText(activo ? `en el tractor \u00d7${tractorCarga.n}` : &quot;semillas&quot;, m.x + m.w - 170, f.y + 43);&#10;            ctx.fillStyle = agotado ? &quot;#aaa&quot; : &quot;#4aa63c&quot;;&#10;            rectRedondo(f.btn.x, f.btn.y, f.btn.w, f.btn.h, 9); ctx.fill();&#10;            ctx.fillStyle = &quot;#fff&quot;; ctx.font = &quot;bold 14px 'Comic Sans MS', sans-serif&quot;;&#10;            ctx.fillText(agotado ? &quot;Agotado&quot; : (activo ? &quot;Recargar&quot; : &quot;Cargar&quot;), f.btn.x + f.btn.w \/ 2, f.btn.y + 22);&#10;        });&#10;        const cv = tractorCarga.id ? varPorId(tractorCarga.id) : null;&#10;        ctx.textAlign = &quot;left&quot;; ctx.fillStyle = &quot;#1d5d7a&quot;; ctx.font = &quot;bold 14px 'Comic Sans MS', sans-serif&quot;;&#10;        ctx.fillText(cv ? `\ud83d\ude9c MIIGT1 lleva: ${cv.emoji} ${cv.nombre} \u00d7${tractorCarga.n}` : &quot;\ud83d\ude9c MIIGT1: sin semilla cargada&quot;, m.x + 24, m.y + m.h - 18);&#10;        ctx.textAlign = &quot;right&quot;;&#10;        ctx.fillText(`\ud83e\uddfa Cesta: ${cestaCosecha}`, m.x + m.w - 24, m.y + m.h - 18);&#10;    }&#10;    if (dialogoCosecha) {&#10;        const d = DIALOGO, v = varPorId(dialogoCosecha.id);&#10;        ctx.fillStyle = &quot;rgba(10,20,30,0.45)&quot;; ctx.fillRect(0, 0, canvas.width, canvas.height);&#10;        ctx.fillStyle = &quot;#fffaf0&quot;; ctx.strokeStyle = &quot;#8a5a34&quot;; ctx.lineWidth = 3;&#10;        rectRedondo(d.x, d.y, d.w, d.h, 14); ctx.fill(); ctx.stroke();&#10;        ctx.textAlign = &quot;center&quot;; ctx.fillStyle = &quot;#5a3d1e&quot;; ctx.font = &quot;bold 18px 'Comic Sans MS', sans-serif&quot;;&#10;        ctx.fillText(`${v.emoji} ${v.nombre}: \u00a1lista!`, d.x + d.w \/ 2, d.y + 34);&#10;        ctx.font = &quot;12px 'Comic Sans MS', sans-serif&quot;; ctx.fillStyle = &quot;#7a6248&quot;;&#10;        const bonoD = Math.min(2, dialogoCosecha.polinizada || 0);&#10;        ctx.fillText(`Rinde ${3 + bonoD} frutos${bonoD ? ` (\ud83d\udc1d +${bonoD} por polinizaci\u00f3n)` : ''}. \u00bfGuardas semillas para el futuro?`, d.x + d.w \/ 2, d.y + 58);&#10;        ctx.fillText(&quot;(toca fuera para cancelar)&quot;, d.x + d.w \/ 2, d.y + 78);&#10;        [[DIALOGO_BTN1, &quot;#c98a3c&quot;, `\ud83e\uddfa Cosechar (+${3 + Math.min(2, dialogoCosecha.polinizada || 0)})`], [DIALOGO_BTN2, &quot;#3d95b8&quot;, &quot;\u2744\ufe0f Cosechar y enviar semillas al Banco (+4)&quot;]].forEach(([b, col, txt]) =&gt; {&#10;            ctx.fillStyle = col; rectRedondo(b.x, b.y, b.w, b.h, 10); ctx.fill();&#10;            ctx.fillStyle = &quot;#fff&quot;; ctx.font = &quot;bold 14px 'Comic Sans MS', sans-serif&quot;;&#10;            ctx.fillText(txt, b.x + b.w \/ 2, b.y + 24);&#10;        });&#10;    }&#10;    if (huertaToast) {&#10;        const resto = huertaToast.hasta - Date.now();&#10;        if (resto &lt;= 0) huertaToast = null;&#10;        else {&#10;            ctx.globalAlpha = Math.min(1, resto \/ 500);&#10;            ctx.font = &quot;bold 14px 'Comic Sans MS', sans-serif&quot;;&#10;            const w = ctx.measureText(huertaToast.texto).width + 30;&#10;            ctx.fillStyle = &quot;rgba(30,60,80,0.92)&quot;;&#10;            rectRedondo(canvas.width \/ 2 - w \/ 2, 68, w, 30, 15); ctx.fill();&#10;            ctx.fillStyle = &quot;#fff&quot;; ctx.textAlign = &quot;center&quot;;&#10;            ctx.fillText(huertaToast.texto, canvas.width \/ 2, 88);&#10;        }&#10;    }&#10;    ctx.restore();&#10;}&#10;const HUERTA_FILAS = [239, 265];        \/\/ l\u00ednea base de las dos filas de cultivo&#10;const HUERTA_TIPOS = ['lechuga', 'pimiento', 'berenjena'];&#10;let huertaCapaCache = null;&#10;function dibujarTomatera(x, y) {&#10;    ctx.strokeStyle = &quot;#8a6a3e&quot;; ctx.lineWidth = 2.5;            \/\/ tutor de madera&#10;    ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(x, y - 30); ctx.stroke();&#10;    ctx.strokeStyle = &quot;#a3835a&quot;; ctx.lineWidth = 1.5;            \/\/ atadura&#10;    ctx.beginPath(); ctx.moveTo(x - 4, y - 14); ctx.lineTo(x + 4, y - 14); ctx.stroke();&#10;    ctx.fillStyle = &quot;#4a7d3c&quot;;                                   \/\/ follaje&#10;    ctx.beginPath(); ctx.ellipse(x, y - 18, 10, 13, 0, 0, Math.PI * 2); ctx.fill();&#10;    ctx.fillStyle = &quot;#d6335a&quot;;                                   \/\/ tomates&#10;    [[-5, -22], [5, -15], [-3, -9]].forEach(([dx, dy]) =&gt; {&#10;        ctx.beginPath(); ctx.arc(x + dx, y + dy, 3.4, 0, Math.PI * 2); ctx.fill();&#10;    });&#10;}&#10;function dibujarHortaliza(x, y, tipo) {&#10;    if (tipo === 'lechuga') {&#10;        ctx.fillStyle = &quot;#7cb342&quot;;&#10;        for (let i = 0; i &lt; 6; i++) {&#10;            const a = (i \/ 6) * Math.PI * 2;&#10;            ctx.beginPath(); ctx.ellipse(x + Math.cos(a) * 6, y - 6 + Math.sin(a) * 3.5, 6, 4, a, 0, Math.PI * 2); ctx.fill();&#10;        }&#10;        ctx.fillStyle = &quot;#a5d66b&quot;;&#10;        ctx.beginPath(); ctx.arc(x, y - 6, 4, 0, Math.PI * 2); ctx.fill();&#10;    } else {&#10;        ctx.fillStyle = &quot;#3a7d30&quot;;                               \/\/ mata verde&#10;        ctx.beginPath(); ctx.ellipse(x, y - 12, 8, 10, 0, 0, Math.PI * 2); ctx.fill();&#10;        if (tipo === 'pimiento') {&#10;            ctx.fillStyle = &quot;#e8632c&quot;;&#10;            ctx.beginPath(); ctx.ellipse(x - 3, y - 8, 3.2, 5, 0.2, 0, Math.PI * 2); ctx.fill();&#10;            ctx.fillStyle = &quot;#f2c14e&quot;;&#10;            ctx.beginPath(); ctx.ellipse(x + 4, y - 12, 3, 4.5, -0.2, 0, Math.PI * 2); ctx.fill();&#10;        } else {&#10;            ctx.fillStyle = &quot;#5b3a8a&quot;;&#10;            ctx.beginPath(); ctx.ellipse(x - 2, y - 6, 3.6, 7, 0.15, 0, Math.PI * 2); ctx.fill();&#10;            ctx.beginPath(); ctx.ellipse(x + 5, y - 10, 3.2, 6, -0.2, 0, Math.PI * 2); ctx.fill();&#10;        }&#10;    }&#10;}&#10;function dibujarMataTrigo(x, y) {&#10;    for (let i = -2; i &lt;= 2; i++) {&#10;        ctx.strokeStyle = &quot;#c9a227&quot;; ctx.lineWidth = 1.5;&#10;        ctx.beginPath(); ctx.moveTo(x + i * 3, y); ctx.lineTo(x + i * 3 + i, y - 22); ctx.stroke();&#10;        ctx.fillStyle = &quot;#e6be3c&quot;;&#10;        ctx.beginPath(); ctx.ellipse(x + i * 3 + i, y - 23, 2.4, 5, 0, 0, Math.PI * 2); ctx.fill();&#10;    }&#10;}&#10;function dibujarTuboRiego(x1, x2, y, paso) {&#10;    ctx.strokeStyle = &quot;#141414&quot;; ctx.lineWidth = 2;&#10;    ctx.beginPath(); ctx.moveTo(x1, y); ctx.lineTo(x2, y); ctx.stroke();&#10;    ctx.fillStyle = &quot;#141414&quot;;&#10;    for (let x = x1 + paso \/ 2; x &lt; x2; x += paso) {&#10;        ctx.beginPath(); ctx.arc(x, y, 2.2, 0, Math.PI * 2); ctx.fill();&#10;    }&#10;}&#10;function dibujarVaca(x, y, escala = 1) {&#10;    ctx.save(); ctx.translate(x, y); ctx.scale(escala, escala);&#10;    ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    ctx.fillStyle = &quot;#2b2b2b&quot;;                                    \/\/ patas&#10;    [-17, -9, 10, 18].forEach(lx =&gt; { ctx.fillRect(lx - 2.5, -14, 5, 14); });&#10;    ctx.strokeStyle = &quot;#3a2a2a&quot;; ctx.lineWidth = 3;               \/\/ cola&#10;    ctx.beginPath(); ctx.moveTo(-25, -30); ctx.quadraticCurveTo(-33, -22, -30, -12); ctx.stroke();&#10;    ctx.fillStyle = &quot;#2b2b2b&quot;; ctx.beginPath(); ctx.ellipse(-30, -11, 3, 5, 0, 0, Math.PI * 2); ctx.fill();&#10;    ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    ctx.fillStyle = &quot;#f2a0b4&quot;;                                    \/\/ ubre&#10;    ctx.beginPath(); ctx.ellipse(-4, -12, 7, 4.5, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#fff&quot;;                                       \/\/ cuerpo&#10;    ctx.beginPath(); ctx.ellipse(0, -25, 27, 14, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#2b2b2b&quot;;                                    \/\/ manchas&#10;    [[-11, -29, 7, 5], [8, -20, 6, 5], [14, -31, 4.5, 3.5]].forEach(([mx, my, rx, ry]) =&gt; {&#10;        ctx.beginPath(); ctx.ellipse(mx, my, rx, ry, 0.2, 0, Math.PI * 2); ctx.fill();&#10;    });&#10;    ctx.fillStyle = &quot;#fff&quot;;                                       \/\/ cabeza&#10;    ctx.beginPath(); ctx.ellipse(31, -30, 11, 9.5, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#f2a0b4&quot;;                                    \/\/ hocico&#10;    ctx.beginPath(); ctx.ellipse(38, -27, 6, 5, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#e9d8a6&quot;; ctx.lineWidth = 1.5;               \/\/ cuernos&#10;    ctx.beginPath(); ctx.moveTo(26, -38); ctx.lineTo(23, -46); ctx.lineTo(30, -39); ctx.closePath(); ctx.fill(); ctx.stroke();&#10;    ctx.beginPath(); ctx.moveTo(35, -38); ctx.lineTo(38, -46); ctx.lineTo(31, -39); ctx.closePath(); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#2b2b2b&quot;;                                    \/\/ oreja, ojo, ollares&#10;    ctx.beginPath(); ctx.ellipse(21, -33, 4, 2.5, -0.5, 0, Math.PI * 2); ctx.fill();&#10;    ctx.beginPath(); ctx.arc(33, -33, 1.6, 0, Math.PI * 2); ctx.fill();&#10;    ctx.beginPath(); ctx.arc(37, -27, 0.9, 0, Math.PI * 2); ctx.fill();&#10;    ctx.beginPath(); ctx.arc(40, -27, 0.9, 0, Math.PI * 2); ctx.fill();&#10;    ctx.restore();&#10;}&#10;function dibujarOveja(x, y, escala = 1) {&#10;    ctx.save(); ctx.translate(x, y); ctx.scale(escala, escala);&#10;    ctx.fillStyle = &quot;#2b2b2b&quot;;                                    \/\/ patas&#10;    [-9, -3, 7, 13].forEach(lx =&gt; { ctx.fillRect(lx - 2, -12, 4, 12); });&#10;    const lana = [[-8, -22, 11], [3, -27, 11], [13, -22, 10], [-1, -17, 11], [8, -16, 9]];&#10;    ctx.fillStyle = &quot;#f6f2e7&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;&#10;    lana.forEach(([lx, ly, r]) =&gt; { ctx.beginPath(); ctx.arc(lx, ly, r, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); });&#10;    lana.forEach(([lx, ly, r]) =&gt; { ctx.beginPath(); ctx.arc(lx, ly, r - 1, 0, Math.PI * 2); ctx.fill(); });&#10;    ctx.fillStyle = &quot;#3a3a3a&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2;   \/\/ cabeza&#10;    ctx.beginPath(); ctx.ellipse(-21, -22, 7.5, 9, 0.1, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.beginPath(); ctx.ellipse(-27, -27, 4, 2.5, 0.6, 0, Math.PI * 2); ctx.fill();   \/\/ oreja&#10;    ctx.fillStyle = &quot;#f6f2e7&quot;;                                                          \/\/ flequillo&#10;    ctx.beginPath(); ctx.arc(-19, -30, 5, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#fff&quot;;                                                             \/\/ ojo&#10;    ctx.beginPath(); ctx.arc(-24, -24, 1.8, 0, Math.PI * 2); ctx.fill();&#10;    ctx.fillStyle = &quot;#000&quot;; ctx.beginPath(); ctx.arc(-24.5, -24, 0.9, 0, Math.PI * 2); ctx.fill();&#10;    ctx.restore();&#10;}&#10;function dibujarVegetacionHuerta() {&#10;    for (let x = 130; x &lt;= 830; x += 9) dibujarMataTrigo(x + (x * 7) % 5, 205);&#10;    [[38, &quot;#e8632c&quot;], [922, &quot;#d6335a&quot;]].forEach(([tx, fruta]) =&gt; {&#10;        dibujarArbolFrutal(tx, 228, 1.1, 0, 0, fruta, 'verano');   \/\/ t=0: sin balanceo (est\u00e1tico)&#10;    });&#10;    dibujarVaca(96, 228, 1.05);      \/\/ lado izquierdo: sustituye a un \u00e1rbol&#10;    dibujarOveja(872, 228, 1.15);    \/\/ lado derecho: sustituye a un \u00e1rbol&#10;    HUERTA_FILAS.forEach(y =&gt; {&#10;        dibujarTuboRiego(115, 395, y + 3, 40);&#10;        dibujarTuboRiego(405, 805, y + 3, 40);&#10;        for (let i = 0; i &lt; 7; i++) dibujarTomatera(135 + i * 40, y);&#10;        for (let i = 0; i &lt; 10; i++) dibujarHortaliza(425 + i * 40, y, HUERTA_TIPOS[i % 3]);&#10;    });&#10;}&#10;function construirCapaHuerta() { return conLienzo(canvas.width, canvas.height, () =&gt; dibujarVegetacionHuerta()); }&#10;let enMercado = false, mercadoPanel = null, mercadoSel = 0, mercadoToast = null;&#10;let saldoMIIG26D = 0, kutxaAuZ = 0;            \/\/ monedero global del pueblo y fondo com\u00fan&#10;const ventasHoy = [];                          \/\/ registro del cuaderno contable&#10;const FUENTE_MERCADO = &quot;'Plus Jakarta Sans', 'Comic Sans MS', sans-serif&quot;;&#10;const MERCADO_BOTON = { x: -999, y: -999, w: 0, h: 0 };            \/\/ acceso desde La Huerta&#10;const M_VOLVER = { x: -999, y: -999, w: 0, h: 0 }, M_PUEBLO = { x: -999, y: -999, w: 0, h: 0 };   \/\/ botones sueltos eliminados&#10;const M_PANEL = { x: 130, y: 100, w: 700, h: 360 };&#10;const M_LIBRO = { x: 410, y: 290, w: 140, h: 86 };                 \/\/ mesa central&#10;const M_ESCOTILLA = { x: 0, y: 440, w: 275, h: 72 };               \/\/ terminal Hyperloop (lateral)&#10;const M_CX = [150, 330, 630, 810];                                 \/\/ centros de los 4 puestos&#10;const P = (n, e, v, s, d) =&gt; ({ n, e, v, s, d, q: 0 });            \/\/ producto: nombre, emoji, valor, stock, detalle&#10;const PUESTOS = [&#10;    { nombre: 'Frutas y Hortalizas', emoji: '\ud83c\udf45', color: '#e8632c', prods: [&#10;        P('Tomates', '\ud83c\udf45', 3, 8, 'Tomatera con tutor, cosechada en La Huerta esta ma\u00f1ana.'),&#10;        P('Lechugas', '\ud83e\udd6c', 2, 10, 'Hoja tierna del bancal, riego LUR subterr\u00e1neo.'),&#10;        P('Pimientos', '\ud83e\uded1', 3, 6, 'Rojos y amarillos, madurados en mata.'),&#10;        P('Berenjenas', '\ud83c\udf46', 3, 6, 'Variedad antigua morada, sin tratamientos.'),&#10;        P('Nopales', '\ud83c\udf35', 3, 8, 'Cact\u00e1cea de secano, tierna y cargada de agua.'),&#10;        P('Moringa y kale', '\ud83e\udd6c', 3, 8, 'Hojas verdes muy resistentes, ricas en hierro.')] },&#10;    { nombre: 'Semillas y Harinas', emoji: '\ud83c\udf3e', color: '#c9a227', prods: [&#10;        P('Harina de trigo', '\ud83c\udf3e', 4, 12, 'Molida en piedra y conservada en fr\u00edo activo.'),&#10;        P('Harina integral', '\ud83e\udd56', 4, 9, 'Grano entero de trigo local, sin refinar.'),&#10;        P('Semillas de tomate', '\ud83c\udf30', 2, 20, 'Variedad tradicional del Banco de Semillas (\u221218 \u00b0C).'),&#10;        P('Semillas de lechuga', '\ud83c\udf31', 2, 20, 'Para resembrar: intercambio libre entre vecinas.'),&#10;        P('Harina de insectos', '\ud83e\udd97', 5, 8, 'Prote\u00edna de bajo consumo de agua, molida fina.'),&#10;        P('Harina de sorgo', '\ud83c\udf3e', 4, 10, 'Sin gluten, de un cereal que casi no necesita riego.')] },&#10;    { nombre: 'L\u00e1cteos y Quesos', emoji: '\ud83e\uddc0', color: '#e6b422', prods: [&#10;        P('Queso curado', '\ud83e\uddc0', 6, 7, 'Artesanal comunitario, 4 meses de cueva.'),&#10;        P('Leche fresca', '\ud83e\udd5b', 2, 14, 'Orde\u00f1ada por la ma\u00f1ana, envase retornable.'),&#10;        P('Yogur', '\ud83e\udd63', 2, 12, 'Fermento natural, sin az\u00facares a\u00f1adidos.'),&#10;        P('Cuajada', '\ud83c\udf6e', 3, 8, 'Al estilo del pueblo, con leche de oveja.'),&#10;        P('K\u00e9fir', '\ud83e\udd5b', 3, 10, 'Fermentado vivo que cuida la microbiota.'),&#10;        P('Queso de micelio', '\ud83e\uddc0', 6, 6, 'Fermentaci\u00f3n de hongos con sabor de queso curado.')] },&#10;    { nombre: 'Legumbres Resilientes', emoji: '\ud83e\uded8', color: '#8a5a34', prods: [&#10;        P('Alubia pinta', '\ud83e\uded8', 4, 12, 'Variedad local adaptada a poca agua.'),&#10;        P('Garbanzo', '\ud83d\udfe1', 4, 10, 'R\u00fastico, resiste el secano.'),&#10;        P('Lenteja pardina', '\ud83d\udfe4', 3, 14, 'Peque\u00f1a y sabrosa, cultivo de rotaci\u00f3n.'),&#10;        P('Carne vegetal', '\ud83e\udd69', 5, 0, 'Prote\u00edna de legumbres impresa en la Zona Industrial.'),&#10;        P('Frijol de Bambara', '\ud83e\uded8', 4, 10, 'Legumbre del secano africano, crece donde otras no.'),&#10;        P('Frijol Marama', '\ud83e\uded8', 4, 10, 'Frijol del desierto, rico en prote\u00edna y aceites.')] }&#10;];&#10;function mCaja(x, y, w, h, r, fill, stroke, lw = 2) {&#10;    ctx.beginPath(); ctx.roundRect ? ctx.roundRect(x, y, w, h, r) : ctx.rect(x, y, w, h);&#10;    if (fill) { ctx.fillStyle = fill; ctx.fill(); }&#10;    if (stroke) { ctx.strokeStyle = stroke; ctx.lineWidth = lw; ctx.stroke(); }&#10;}&#10;function mTxt(s, x, y, tam, col, al = 'left', neg = false) {&#10;    ctx.font = `${neg ? 'bold ' : ''}${tam}px ${FUENTE_MERCADO}`;&#10;    ctx.fillStyle = col; ctx.textAlign = al; ctx.textBaseline = 'middle'; ctx.fillText(s, x, y);&#10;}&#10;function mTxtAjustado(s, x, y, tam, col, ancho) { ctx.font = `bold ${tam}px ${FUENTE_MERCADO}`; const w = ctx.measureText(s).width; mTxt(s, x, y, w &gt; ancho ? Math.max(7, tam * ancho \/ w) : tam, col, 'center', true); }&#10;const mFila = n =&gt; n &gt; 4 ? { h: 38, f: 34, b: 28, o: 3, t: 17 } : { h: 50, f: 46, b: 32, o: 7, t: 23 };   \/\/ medidas de cada fila del panel&#10;function mostrarToastMercado(s) { mercadoToast = { s, hasta: Date.now() + 2800 }; }&#10;const capsula = { fase: 'reposo', x: -90, f: 0, carga: 0 };&#10;function enviarCapsula(carga, api = null) {&#10;    if (capsula.fase !== 'reposo') return false;&#10;    Object.assign(capsula, { fase: 'llega', x: -90, f: 0, carga, api });&#10;    return true;&#10;}&#10;function repartirCarga(n, api) {               \/\/ la mercanc\u00eda de La Huerta (cosecha y apicultura) llega a sus puestos&#10;    if (n &gt; 0) { const ps = PUESTOS[0].prods; for (let i = 0; i &lt; n; i++) ps[i % ps.length].s++; }&#10;    if (api) Apicultura.entregar(api);&#10;    const partes = []; if (n &gt; 0) partes.push(`+${n} piezas frescas`); if (api) partes.push('\ud83c\udf6f producci\u00f3n ap\u00edcola');&#10;    if (partes.length) mostrarToastMercado('\ud83d\udce6 C\u00e1psula de La Huerta: ' + partes.join(' \u00b7 '));&#10;}&#10;function entrarAlMercado() {&#10;    enHuerta = false; enMercado = true; mercadoPanel = null;&#10;    const n = cestaCosecha; cestaCosecha = 0; recursos.resina = Math.min(100, recursos.resina + n);   \/\/ restos de cosecha \u2192 bio-resina&#10;    capsula.fase = 'reposo'; const api = Apicultura.hay() ? Apicultura.cargar() : null; enviarCapsula(n &gt; 0 ? n : (api ? 0 : 6), api);   \/\/ sin cesta: lote matinal de 6&#10;}&#10;function actualizarMercado() {&#10;    const c = capsula; c.f++;&#10;    actualizarChicas();&#10;    if (c.fase === 'llega') {                  \/\/ frenada suave desde alta velocidad&#10;        const p = Math.min(1, c.f \/ 70); c.x = -90 + 250 * (1 - Math.pow(1 - p, 3));&#10;        if (p &gt;= 1) { c.fase = 'entrega'; c.f = 0; repartirCarga(c.carga, c.api); }&#10;    } else if (c.fase === 'entrega' &amp;&amp; c.f &gt; 110) { c.fase = 'sale'; c.f = 0; }&#10;    else if (c.fase === 'sale') { c.x -= 4 + c.f * 0.6; if (c.x &lt; -100) c.fase = 'reposo'; }&#10;}&#10;function registrarVenta() {&#10;    const ps = PUESTOS[mercadoPanel].prods; let tok = 0; const txt = [];&#10;    if (mercadoPanel === 3) recursos.proteina = Math.min(100, recursos.proteina + 2 * ps.reduce((a, p) =&gt; a + p.q, 0));   \/\/ legumbres \u2192 prote\u00edna&#10;    ps.forEach(p =&gt; { if (p.q &gt; 0) { p.s -= p.q; tok += p.q * p.v; txt.push(`${p.e}\u00d7${p.q}`); p.q = 0; } });&#10;    if (!tok) { mostrarToastMercado('Elige cantidades con + y \u2212, sin prisa'); return; }&#10;    ventasHoy.unshift({ puesto: PUESTOS[mercadoPanel].nombre, txt: txt.join(' '), tok });&#10;    saldoMIIG26D += tok; Kutxa.aportar(tok * 0.08);   \/\/ la tasa justa del mercado: 8 % al fondo com\u00fan;      \/\/ balance autom\u00e1tico: nunca hay deuda&#10;    mostrarToastMercado(`\ud83e\ude99 +${tok} MIIG26D \u00b7 8 % a la Kutxa AuZ`);&#10;}&#10;function manejarToqueMercado(x, y) {&#10;    if (dentroRect(x, y, M_VOLVER)) { iniciarTransicion(() =&gt; { enMercado = false; mercadoPanel = null; enHuerta = true; entrarALaHuerta(); }); return; }&#10;    if (dentroRect(x, y, M_PUEBLO)) { iniciarTransicion(() =&gt; salirDeEscena()); return; }&#10;    const B = M_PANEL;&#10;    if (mercadoPanel !== null) {&#10;        if (!dentroRect(x, y, B) || dentroRect(x, y, { x: B.x + B.w - 42, y: B.y + 8, w: 34, h: 34 })) { mercadoPanel = null; return; }&#10;        if (mercadoPanel === 'libro') return;&#10;        const ps = PUESTOS[mercadoPanel].prods, F = mFila(ps.length);&#10;        if (dentroRect(x, y, { x: B.x + B.w - 240, y: B.y + B.h - 54, w: 220, h: 40 })) { registrarVenta(); return; }&#10;        ps.forEach((p, i) =&gt; {&#10;            const ry = B.y + 68 + i * F.h; if (y &lt; ry || y &gt; ry + F.f) return;&#10;            mercadoSel = i;&#10;            if (dentroRect(x, y, { x: B.x + B.w - 190, y: ry + F.o, w: F.b, h: F.b })) p.q = Math.max(0, p.q - 1);&#10;            if (dentroRect(x, y, { x: B.x + B.w - 70, y: ry + F.o, w: F.b, h: F.b })) p.q = Math.min(p.s, p.q + 1);&#10;        });&#10;        return;&#10;    }&#10;    if (dentroRect(x, y, M_LIBRO)) { mercadoPanel = 'libro'; return; }&#10;    if (dentroRect(x, y, M_ESCOTILLA)) {&#10;        const api = (capsula.fase === 'reposo' &amp;&amp; Apicultura.hay()) ? Apicultura.cargar() : null;      \/\/ cosecha y apicultura viajan en la misma c\u00e1psula&#10;        if (cestaCosecha &gt; 0 || api) { if (enviarCapsula(cestaCosecha, api)) cestaCosecha = 0; }&#10;        else mostrarToastMercado('\ud83e\uddfa Nada que enviar: cosecha o espera a la producci\u00f3n de las colmenas');&#10;        return;&#10;    }&#10;    M_CX.forEach((cx, i) =&gt; { if (dentroRect(x, y, { x: cx - 75, y: 236 + (PUESTOS[i].oy || 0), w: 150, h: 136 })) { mercadoPanel = i; mercadoSel = 0; } });&#10;}&#10;function dibujarPuestoMercado(i, t) {&#10;    const cx = M_CX[i], q = PUESTOS[i];&#10;    mCaja(cx - 70, 300, 140, 74, 6, '#b9854f', '#5a3a1c');                  \/\/ mostrador de madera local&#10;    mCaja(cx - 70, 300, 140, 12, 4, '#d6a56a', '#5a3a1c', 1.5);&#10;    const exp = q.contadores ? q.prods : q.prods.slice(0, 4), sp = exp.length &gt; 4 ? 24 : 32;   \/\/ g\u00e9nero expuesto (5 en la apicultura, 4 en el resto)&#10;    exp.forEach((p, k) =&gt; mTxt(p.e, cx - (exp.length - 1) * sp \/ 2 + k * sp, 288, exp.length &gt; 4 ? 20 : 24, '#000', 'center'));&#10;    if (q.contadores) {                                                                      \/\/ contadores independientes sobre el mostrador&#10;        exp.forEach((p, k) =&gt; { const px = cx - (exp.length - 1) * sp \/ 2 + k * sp; mCaja(px - 11, 300, 22, 11, 5, 'rgba(255,248,234,0.96)', q.color, 1); mTxt('\u00d7' + Math.min(99, p.s), px, 306, 9, '#5a3a1c', 'center', true); });&#10;        [-52, 52].forEach(dx =&gt; { ctx.strokeStyle = q.color; ctx.lineWidth = 1.5; ctx.beginPath(); for (let a = 0; a &lt; 6; a++) { const an = Math.PI \/ 3 * a + Math.PI \/ 6; a ? ctx.lineTo(cx + dx + Math.cos(an) * 6, 335 + Math.sin(an) * 6) : ctx.moveTo(cx + dx + Math.cos(an) * 6, 335 + Math.sin(an) * 6); } ctx.closePath(); ctx.stroke(); });   \/\/ panal&#10;        mTxt('\ud83d\udc1d', cx + 66 + Math.sin(t \/ 20) * 6, 258 + Math.cos(t \/ 17) * 4, 12, '#000', 'center');   \/\/ abejita revoloteando&#10;    }&#10;    for (let k = 0; k &lt; 7; k++) {                                            \/\/ toldo a rayas&#10;        ctx.fillStyle = k % 2 ? '#fff5e0' : q.color;&#10;        ctx.beginPath(); ctx.moveTo(cx - 75 + k * 21.4, 236); ctx.lineTo(cx - 75 + (k + 1) * 21.4, 236);&#10;        ctx.lineTo(cx - 75 + (k + 1) * 21.4, 268); ctx.arc(cx - 75 + (k + 0.5) * 21.4, 268, 10.7, 0, Math.PI); ctx.fill();&#10;    }&#10;    mCaja(cx - 62, 320, 124, 30, 8, 'rgba(255,255,255,0.92)', q.color);&#10;    mTxtAjustado(q.emoji + ' ' + q.nombre, cx, 335, 11, '#333', 112);&#10;    mTxt('\ud83d\udc46 Toca', cx, 366, 10, '#fff', 'center', true);&#10;}&#10;function dibujarHyperloop(t) {&#10;    const c = capsula;&#10;    mCaja(0, 468, 205, 34, 14, 'rgba(190,240,255,0.35)', '#9fd6e8', 2.5);      \/\/ tubo de vac\u00edo acristalado&#10;    ctx.strokeStyle = 'rgba(255,255,255,0.5)'; ctx.lineWidth = 1;&#10;    for (let x = 20; x &lt; 205; x += 30) { ctx.beginPath(); ctx.moveTo(x, 470); ctx.lineTo(x, 500); ctx.stroke(); }&#10;    mCaja(205, 452, 70, 62, 8, '#aab2ba', '#4a4f55');                          \/\/ terminal met\u00e1lica&#10;    mTxt('HYPERLOOP', 240, 470, 9, '#20262e', 'center', true); mTxt('\u2190 LA HUERTA', 240, 484, 8, '#20262e', 'center');&#10;    const ok = c.fase === 'entrega', led = ok ? (Math.sin(t \/ 4) &gt; 0 ? '#7cffd9' : '#2a7a63') : '#3a3f45';&#10;    ctx.fillStyle = led; ctx.beginPath(); ctx.arc(240, 501, 4, 0, Math.PI * 2); ctx.fill();&#10;    const tapa = ok ? Math.min(1, c.f \/ 15) : 0;                               \/\/ escotilla superior&#10;    ctx.save(); ctx.translate(125, 464); ctx.rotate(-tapa * 1.1);&#10;    mCaja(0, -6, 62, 8, 3, '#c7cdd3', '#4a4f55', 1.5); ctx.restore();&#10;    if (ok) ['\ud83c\udf45', '\ud83e\udd6c', '\ud83e\uddfa'].forEach((e, k) =&gt; mTxt(e, 132 + k * 22, 446 - Math.min(24, c.f * 0.5) - Math.sin(t \/ 10 + k) * 2, 20, '#000', 'center'));&#10;    if (c.fase !== 'reposo') {                                                 \/\/ c\u00e1psula magn\u00e9tica&#10;        if (c.fase !== 'entrega') { ctx.strokeStyle = 'rgba(124,255,217,0.5)'; ctx.lineWidth = 2;&#10;            for (let k = 0; k &lt; 3; k++) { ctx.beginPath(); ctx.moveTo(c.x - 10 - k * 14, 480 + k * 5 - 5); ctx.lineTo(c.x - 40 - k * 14, 480 + k * 5 - 5); ctx.stroke(); } }&#10;        const g = ctx.createLinearGradient(0, 471, 0, 497); g.addColorStop(0, '#f4f6f8'); g.addColorStop(1, '#8f979f');&#10;        mCaja(c.x - 40, 471, 80, 26, 13, g, '#4a4f55', 1.5);&#10;        ctx.fillStyle = ok ? `rgba(124,255,217,${0.6 + 0.4 * Math.sin(t \/ 4)})` : 'rgba(124,255,217,0.9)';&#10;        [-26, -10, 6, 22].forEach(dx =&gt; { ctx.beginPath(); ctx.arc(c.x + dx, 484, 2.6, 0, Math.PI * 2); ctx.fill(); });&#10;    }&#10;}&#10;function dibujarPanelMercado() {&#10;    const B = M_PANEL, lib = mercadoPanel === 'libro', q = lib ? null : PUESTOS[mercadoPanel];&#10;    ctx.fillStyle = 'rgba(30,20,10,0.45)'; ctx.fillRect(0, 0, canvas.width, canvas.height);&#10;    mCaja(B.x, B.y, B.w, B.h, 18, '#fff8ea', lib ? '#6a3e8c' : q.color, 4);&#10;    mCaja(B.x + B.w - 42, B.y + 8, 34, 34, 17, '#eee', '#999', 1.5); mTxt('\u2715', B.x + B.w - 25, B.y + 26, 16, '#555', 'center', true);&#10;    if (lib) {&#10;        mTxt('\ud83d\udcd2 Cuaderno de Contabilidad \u00b7 MIIG26D', B.x + 24, B.y + 30, 20, '#4a2a6a', 'left', true);&#10;        mTxt('Balance autom\u00e1tico del d\u00eda \u00b7 cero deudas \u00b7 cero presi\u00f3n', B.x + 24, B.y + 58, 13, '#7a6a5a');&#10;        if (!ventasHoy.length) mTxt('A\u00fan no hay ventas hoy. Todo a su ritmo \ud83c\udf3f', B.x + 24, B.y + 110, 15, '#7a6a5a');&#10;        ventasHoy.slice(0, 6).forEach((v, i) =&gt; {&#10;            mTxt(`${v.puesto}  ${v.txt}`, B.x + 24, B.y + 92 + i * 30, 14, '#333');&#10;            mTxt(`+${v.tok} \ud83e\ude99`, B.x + B.w - 40, B.y + 92 + i * 30, 14, '#2a7a63', 'right', true);&#10;        });&#10;        mCaja(B.x + 20, B.y + B.h - 96, B.w - 40, 78, 12, 'rgba(124,255,217,0.25)', '#2a7a63', 1.5);&#10;        mTxt(`Monedero global del pueblo: ${saldoMIIG26D} MIIG26D`, B.x + 36, B.y + B.h - 72, 16, '#1d5a48', 'left', true);&#10;        mTxt(`Kutxa AuZ alimentada: ${Kutxa.visible()} MIIG26D  \u2714 sincronizado`, B.x + 36, B.y + B.h - 42, 15, '#1d5a48');&#10;        return;&#10;    }&#10;    mTxt(q.emoji + ' ' + q.nombre, B.x + 24, B.y + 30, 20, q.color, 'left', true);&#10;    let total = 0; const F = mFila(q.prods.length);          \/\/ con m\u00e1s de 4 productos las filas se hacen algo m\u00e1s bajas&#10;    q.prods.forEach((p, i) =&gt; {&#10;        const ry = B.y + 68 + i * F.h; total += p.q * p.v;&#10;        mCaja(B.x + 16, ry, B.w - 32, F.f, 10, i === mercadoSel ? 'rgba(124,255,217,0.3)' : 'rgba(0,0,0,0.04)', i === mercadoSel ? '#2a7a63' : null, 1.5);&#10;        mTxt(p.e + ' ' + p.n, B.x + 28, ry + F.t, 16, '#333', 'left', true);&#10;        mTxt(`${p.v} \ud83e\ude99 c\/u`, B.x + 300, ry + F.t, 13, '#7a5a1a'); mTxt(`stock ${p.s}`, B.x + 400, ry + F.t, 13, '#555');&#10;        mCaja(B.x + B.w - 190, ry + F.o, F.b, F.b, F.b \/ 2, '#fff', '#999', 1.5); mTxt('\u2212', B.x + B.w - 190 + F.b \/ 2, ry + F.t, 20, '#555', 'center', true);&#10;        mTxt(String(p.q), B.x + B.w - 114, ry + F.t, 18, '#222', 'center', true);&#10;        mCaja(B.x + B.w - 70, ry + F.o, F.b, F.b, F.b \/ 2, '#fff', '#999', 1.5); mTxt('+', B.x + B.w - 70 + F.b \/ 2, ry + F.t, 20, '#555', 'center', true);&#10;    });&#10;    mTxt('\u2139\ufe0f ' + q.prods[mercadoSel].d, B.x + 24, B.y + B.h - 34, 12, '#5a4a3a');&#10;    mCaja(B.x + B.w - 240, B.y + B.h - 54, 220, 40, 20, total ? '#2a9d78' : '#b8b8b8', '#1d5a48', 2);&#10;    mTxt(`\u2714 Registrar venta (+${total} \ud83e\ude99)`, B.x + B.w - 130, B.y + B.h - 34, 14, '#fff', 'center', true);&#10;}&#10;function dibujarLetreroMercado(t) {&#10;    const cx = canvas.width \/ 2, w = 320, h = 38, y = 122;&#10;    ctx.strokeStyle = '#5a3a1c'; ctx.lineWidth = 3;                                  \/\/ cadenas sim\u00e9tricas&#10;    [-1, 1].forEach(s =&gt; { ctx.beginPath(); ctx.moveTo(cx + s * 120, 106); ctx.lineTo(cx + s * 120, y); ctx.stroke(); });&#10;    const g = ctx.createLinearGradient(0, y, 0, y + h); g.addColorStop(0, '#8bc34a'); g.addColorStop(1, '#5f9a2c');&#10;    mCaja(cx - w \/ 2, y, w, h, 12, g, '#20262e', 2.5);&#10;    mCaja(cx - w \/ 2 + 5, y + 5, w - 10, h - 10, 8, null, 'rgba(255,255,255,0.45)', 1.2);&#10;    [-1, 1].forEach(s =&gt; {                                                            \/\/ LEDs solares en las esquinas&#10;        ctx.fillStyle = Math.sin(t \/ 20 + s) &gt; -0.3 ? '#7cffd9' : '#2a7a63';&#10;        ctx.beginPath(); ctx.arc(cx + s * (w \/ 2 - 12), y + h \/ 2, 3, 0, Math.PI * 2); ctx.fill();&#10;    });&#10;    mTxt('MERCADO DE ABASTOS', cx, y + h \/ 2 + 1, 18, '#fff', 'center', true);&#10;    const tw = ctx.measureText('MERCADO DE ABASTOS').width;&#10;    [-1, 1].forEach(s =&gt; mTxt('\ud83c\udf31', cx + s * (tw \/ 2 + 22), y + h \/ 2 + 1, 16, '#000', 'center'));&#10;}&#10;const CHICAS = [&#10;    { x: 90,  y: 410, vestido: '#ff69b4', colorPelo: '#f2c14e', estilo: 'largo', v: 0.55 },&#10;    { x: 380, y: 425, vestido: '#2a9d78', colorPelo: '#6b3f26', estilo: 'pincho', v: 0.7 },&#10;    { x: 620, y: 405, vestido: '#f4b400', colorPelo: '#c0522d', estilo: 'largo', v: 0.6 },&#10;    { x: 860, y: 430, vestido: '#6a3e8c', colorPelo: '#2b2b2b', estilo: 'mohawk', v: 0.5 }&#10;].map(c =&gt; ({ ...c, tx: c.x, ty: c.y, dir: 1, fase: Math.random() * 6, espera: 30, icono: null }));&#10;function destinoChica() {&#10;    const k = Math.floor(Math.random() * 6), y = 396 + Math.random() * 48;&#10;    if (k &lt; 4) return { x: M_CX[k] + (Math.random() - 0.5) * 70, y, ic: PUESTOS[k].prods[Math.floor(Math.random() * 4)].e };&#10;    return k === 4 ? { x: 480 + (Math.random() - 0.5) * 60, y, ic: '\ud83d\udcd2' } : { x: 320, y: 440, ic: '\ud83d\udce6' };&#10;}&#10;function actualizarChicas() {&#10;    CHICAS.forEach((c, i) =&gt; {&#10;        if (c.espera &gt; 0) {                                     \/\/ curioseando: se queda mirando&#10;            c.espera--; if (c.espera === 0) { const d = destinoChica(); c.tx = d.x; c.ty = d.y; c.icono = d.ic; c.mira = false; }&#10;            return;&#10;        }&#10;        const dx = c.tx - c.x, dy = c.ty - c.y, d = Math.hypot(dx, dy);&#10;        if (d &lt; 3) { c.espera = 140 + Math.random() * 160; c.mira = true; return; }&#10;        let vx = dx \/ d * c.v, vy = dy \/ d * c.v * 0.6;&#10;        CHICAS.forEach((o, j) =&gt; { if (j !== i &amp;&amp; Math.abs(o.x - c.x) &lt; 34 &amp;&amp; Math.abs(o.y - c.y) &lt; 16) vy += (c.y &lt; o.y ? -0.25 : 0.25); });   \/\/ no se pisan&#10;        c.x = Math.max(30, Math.min(930, c.x + vx)); c.y = Math.max(392, Math.min(452, c.y + vy));&#10;        c.dir = vx &gt;= 0 ? 1 : -1; c.fase += 0.14;&#10;    });&#10;}&#10;function dibujarChica(c, t) {&#10;    const caminando = c.espera &lt;= 0;&#10;    const bamboleo = caminando ? Math.sin(t \/ 6) * 0.06 * c.dir : Math.sin(t \/ 30 + c.fase) * 0.02;&#10;    ctx.save(); ctx.translate(c.x, c.y - 28); ctx.scale(1.1, 1.1);&#10;    dibujarMu\u00f1eca({ x: 0, y: 0, angulo: bamboleo }, c.colorPelo, false, c.dir &lt; 0, false, c.estilo); accesorioFiesta(0, 0, c.dir &lt; 0 ? -1 : 1);   \/\/ gorro, m\u00e1scara, corona o diadema&#10;    ctx.restore();&#10;    if (c.espera &gt; 0 &amp;&amp; c.icono) {                                                   \/\/ burbuja con lo que mira&#10;        const by = c.y - 92 - Math.sin(t \/ 20 + c.fase) * 1.5;&#10;        mCaja(c.x - 14, by - 13, 28, 24, 10, 'rgba(255,255,255,0.95)', '#20262e', 1.2); mTxt(c.icono, c.x, by, 15, '#000', 'center');&#10;    }&#10;}&#10;function dibujarChicas(t) { [...CHICAS].sort((a, b) =&gt; a.y - b.y).forEach(c =&gt; dibujarChica(c, t)); }&#10;function dibujarMercado(t) {&#10;    const gp = ctx.createLinearGradient(0, 0, 0, 400); gp.addColorStop(0, '#ffe9bd'); gp.addColorStop(1, '#f4cf95');&#10;    ctx.fillStyle = gp; ctx.fillRect(0, 0, canvas.width, 400);&#10;    ctx.fillStyle = '#d9b98a'; ctx.fillRect(0, 400, canvas.width, 140);&#10;    ctx.strokeStyle = 'rgba(90,58,28,0.18)'; ctx.lineWidth = 1;&#10;    for (let y = 400; y &lt; 540; y += 28) { ctx.beginPath(); ctx.moveTo(0, y); ctx.lineTo(960, y); ctx.stroke(); }&#10;    ctx.fillStyle = '#1e3a5f'; ctx.fillRect(0, 0, 960, 92);&#10;    for (let y = 0; y &lt; 92; y += 18) for (let x = (y \/ 18 % 2) * 20; x &lt; 960; x += 40) mCaja(x + 2, y + 2, 36, 14, 3, '#26508a', '#6fa8dc', 1);&#10;    ctx.fillStyle = 'rgba(255,255,255,0.12)'; ctx.fillRect(((t * 2) % 1200) - 200, 0, 60, 92);   \/\/ destello solar&#10;    ctx.fillStyle = '#8a5a34'; ctx.fillRect(0, 92, 960, 14);&#10;    [40, 480, 920].forEach(x =&gt; { ctx.fillStyle = '#8a5a34'; ctx.fillRect(x - 9, 106, 18, 294); ctx.fillStyle = 'rgba(0,0,0,0.15)'; ctx.fillRect(x + 2, 106, 7, 294); });&#10;    for (let i = 0; i &lt; 5; i++) {&#10;        const h = 26 + 18 * (0.5 + 0.5 * Math.sin(t \/ 90 + i));&#10;        ctx.fillStyle = 'rgba(255,238,190,0.6)'; ctx.fillRect(60 + i * 175, 106, 140, h);&#10;        ctx.fillStyle = 'rgba(255,220,140,' + (0.10 + 0.05 * Math.sin(t \/ 60 + i)) + ')';   \/\/ luz c\u00e1lida filtrada&#10;        ctx.beginPath(); ctx.moveTo(60 + i * 175, 106 + h); ctx.lineTo(200 + i * 175, 106 + h); ctx.lineTo(230 + i * 175, 400); ctx.lineTo(30 + i * 175, 400); ctx.fill();&#10;    }&#10;    dibujarLetreroMercado(t);&#10;    PUESTOS.forEach((q, i) =&gt; { ctx.save(); ctx.translate(0, q.oy || 0); dibujarPuestoMercado(i, t); ctx.restore(); });&#10;    const L = M_LIBRO;&#10;    mCaja(L.x, L.y + 30, L.w, 56, 8, '#a5703a', '#5a3a1c'); mCaja(L.x - 6, L.y + 24, L.w + 12, 12, 5, '#d6a56a', '#5a3a1c', 1.5);&#10;    mCaja(L.x + 30, L.y - 2, 80, 30, 4, '#3b2a6a', '#20262e', 2);&#10;    mCaja(L.x + 34, L.y + 1, 72, 24, 3, '#f6f1ff', null); mTxt('\ud83d\udcd2 ' + saldoMIIG26D + ' \ud83e\ude99', L.x + 70, L.y + 13, 11, '#4a2a6a', 'center', true);&#10;    mTxt('Cuaderno \u00b7 Toca', L.x + 70, L.y + 60, 11, '#fff', 'center', true);&#10;    dibujarChicas(t);&#10;    dibujarHyperloop(t);&#10;    [].forEach(([z, s]) =&gt; {&#10;        const g = ctx.createLinearGradient(z.x, 0, z.x + z.w, 0); g.addColorStop(0, '#ff69b4'); g.addColorStop(1, '#6a3e8c');&#10;        mCaja(z.x, z.y, z.w, z.h, 17, g, 'rgba(255,255,255,0.9)'); mTxt(s, z.x + z.w \/ 2, z.y + z.h \/ 2 + 1, 14, '#fff', 'center', true);&#10;    });&#10;    mCaja(730, 14, 210, 34, 17, 'rgba(255,255,255,0.9)', '#2a9d78'); mTxt(`\ud83e\ude99 MIIG26D: ${saldoMIIG26D}`, 835, 32, 14, '#1d5a48', 'center', true);&#10;    dibujarFiestaEscena('mercado', t);&#10;    if (mercadoPanel !== null) dibujarPanelMercado();&#10;    if (mercadoToast) {&#10;        if (Date.now() &gt; mercadoToast.hasta) mercadoToast = null;&#10;        else { ctx.font = `bold 14px ${FUENTE_MERCADO}`; const w = ctx.measureText(mercadoToast.s).width + 30;&#10;            mCaja(480 - w \/ 2, 66, w, 32, 16, 'rgba(30,58,50,0.92)', '#7cffd9', 1.5); mTxt(mercadoToast.s, 480, 83, 14, '#fff', 'center', true); }&#10;    }&#10;}&#10;function dibujarBotonMercado() {&#10;    return;   \/\/ sustituido por la barra de navegaci\u00f3n superior&#10;    const b = MERCADO_BOTON; ctx.save();&#10;    mCaja(b.x, b.y, b.w, b.h, 13, '#fff5e0', '#333'); mTxt('\ud83c\udfea Mercado \u2192', b.x + b.w \/ 2, b.y + b.h \/ 2 + 1, 12, '#333', 'center', true);&#10;    ctx.restore(); ctx.textBaseline = 'alphabetic';&#10;}&#10;const HUERTA_COLMENAS = [{ x: 410, y: 322, c: '#e0b46b' }, { x: 480, y: 322, c: '#9ec7a5' }, { x: 550, y: 322, c: '#e8b4b8' }];   \/\/ zona despejada, lejos de las tinajas LUR&#10;const HUERTA_FLORES = [[120, 316, '#ffffff'], [166, 310, '#ff5ca8'], [214, 318, '#ffd23f'], [250, 308, '#b388ff'], [332, 318, '#ff7043'], [366, 310, '#ffd23f'], [612, 318, '#ff5ca8'], [646, 308, '#ffffff'], [722, 316, '#b388ff'], [758, 310, '#ff7043'], [862, 318, '#ffd23f'], [900, 310, '#ff5ca8']];&#10;const abejas = Array.from({ length: 9 }, (_, i) =&gt; ({ casa: i % 3, estado: 'dentro', espera: 40 + i * 35, x: 0, y: 0, tx: 0, ty: 0, flores: 0, fase: i * 1.7, dir: 1, polen: 0, obj: null }));&#10;const entradaColmena = c =&gt; ({ x: HUERTA_COLMENAS[c].x, y: HUERTA_COLMENAS[c].y - 10.5 });&#10;function elegirFlor(b) {&#10;    const cand = b.polen &gt;= 0.2 ? huertaSiembra.filter(p =&gt; { const g = progresoSiembra(p); return g &gt;= 0.25; }) : [];   \/\/ solo si ya llevan polen de alguna flor&#10;    if (cand.length &amp;&amp; Math.random() &lt; 0.45) { const p = cand[Math.floor(Math.random() * cand.length)]; b.obj = p; b.tx = p.x + (Math.random() - 0.5) * 6; b.ty = SIEMBRA_Y - 34; return; }&#10;    b.obj = null; const f = HUERTA_FLORES[Math.floor(Math.random() * HUERTA_FLORES.length)]; b.tx = f[0] + (Math.random() - 0.5) * 8; b.ty = f[1] - 15 + (Math.random() - 0.5) * 4;&#10;}&#10;function polinizar(b) {                                                              \/\/ al terminar la visita: el cultivo queda polinizado (hasta 3 visitas)&#10;    const p = b.obj; b.obj = null; if (!p || !huertaSiembra.includes(p)) return;&#10;    p.polinizada = Math.min(3, (p.polinizada || 0) + 1); emitirPolen(b.x, b.y + 4, 10); b.polen = Math.max(0, b.polen - 0.4); Apicultura.polinizacion(); Kutxa.aportar(0.3);&#10;}&#10;function dibujarPolinizacionCultivos(t) {                                            \/\/ indicador sutil: halo dorado, motitas y una abejita en los cultivos polinizados&#10;    huertaSiembra.forEach(p =&gt; {&#10;        const n = p.polinizada || 0; if (!n) return;&#10;        const cx = p.x, cy = SIEMBRA_Y - 12, r = 15 + n * 2;&#10;        ctx.save();&#10;        const g = ctx.createRadialGradient(cx, cy, 2, cx, cy, r); g.addColorStop(0, `rgba(255,214,90,${0.16 + 0.05 * n + 0.04 * Math.sin(t \/ 15 + p.x)})`); g.addColorStop(1, 'rgba(255,214,90,0)');&#10;        ctx.fillStyle = g; ctx.beginPath(); ctx.arc(cx, cy, r, 0, Math.PI * 2); ctx.fill();&#10;        for (let k = 0; k &lt; 2 + n; k++) { const a = t \/ 40 + k * 2.1 + p.x; ctx.fillStyle = `rgba(255,224,110,${0.45 + 0.45 * Math.sin(t \/ 9 + k + p.x)})`; ctx.beginPath(); ctx.arc(cx + Math.cos(a) * (8 + k * 2), cy + Math.sin(a) * (8 + k * 2) * 0.7, 1.1, 0, Math.PI * 2); ctx.fill(); }&#10;        if (progresoSiembra(p) &gt;= 1) mTxt('\ud83d\udc1d', cx + 11, SIEMBRA_Y - 34, 9, '#000', 'center');   \/\/ lista y polinizada: se ve de un vistazo&#10;        ctx.restore();&#10;    });&#10;}&#10;const polen = [];                                                                    \/\/ part\u00edculas { x, y, vx, vy, v, vida, tam }&#10;function emitirPolen(x, y, n) {&#10;    for (let i = 0; i &lt; n &amp;&amp; polen.length &lt; 140; i++)&#10;        polen.push({ x: x + (Math.random() - 0.5) * 6, y, vx: (Math.random() - 0.5) * 0.5, vy: -0.15 - Math.random() * 0.4, v: 0, vida: 28 + Math.random() * 22, tam: 0.9 + Math.random() * 0.9, c: colorPolen() });&#10;}&#10;function actualizarPolen() {&#10;    for (let i = polen.length - 1; i &gt;= 0; i--) { const p = polen[i]; p.x += p.vx + Math.sin(p.v \/ 5 + p.vida) * 0.12; p.y += p.vy; p.vy += 0.004; if (++p.v &gt;= p.vida) polen.splice(i, 1); }&#10;}&#10;function dibujarPolen() {&#10;    ctx.save();&#10;    polen.forEach(p =&gt; {&#10;        const a = Math.pow(1 - p.v \/ p.vida, 0.8), r = p.tam * (0.75 + 0.25 * Math.sin(p.v * 0.7 + p.x));                 \/\/ titilan al desvanecerse&#10;        ctx.fillStyle = `rgba(${p.c},${a * 0.28})`; ctx.beginPath(); ctx.arc(p.x, p.y, r * 2.6, 0, Math.PI * 2); ctx.fill();      \/\/ halo&#10;        ctx.fillStyle = `rgba(${p.c},${a})`; ctx.beginPath(); ctx.arc(p.x, p.y, r, 0, Math.PI * 2); ctx.fill();                      \/\/ punto dorado&#10;    });&#10;    ctx.restore();&#10;}&#10;function actualizarAbejas(t) {&#10;    const inv = invernada();                                                       \/\/ invierno: las abejas hibernan dentro de las colmenas&#10;    abejas.forEach(b =&gt; {&#10;        if (inv &amp;&amp; b.estado !== 'dentro' &amp;&amp; b.estado !== 'vuelve') { const e = entradaColmena(b.casa); b.tx = e.x; b.ty = e.y; b.estado = 'vuelve'; b.obj = null; }   \/\/ las que est\u00e1n fuera vuelven a casa&#10;        if (b.estado === 'dentro') {                                                   \/\/ descansa en la colmena y sale de nuevo&#10;            if (inv) { b.espera = 20 + (b.fase * 25) % 120; return; }               \/\/ hibernando; en primavera salen escalonadas&#10;            if (--b.espera &lt;= 0) { const e = entradaColmena(b.casa); b.x = e.x; b.y = e.y; b.flores = 2 + Math.floor(Math.random() * 3); elegirFlor(b); b.estado = 'sale'; }&#10;            return;&#10;        }&#10;        if (b.estado === 'flor') {                                                     \/\/ revolotea sobre la flor y decide&#10;            if (--b.espera &gt; 0) {&#10;                b.x += Math.sin(t \/ 6 + b.fase) * 0.2; b.y += Math.cos(t \/ 5 + b.fase) * 0.15;&#10;                b.polen = Math.min(1, b.polen + 0.012);                                  \/\/ va cargando polen&#10;                if (Math.floor(t + b.fase * 10) % 4 === 0) emitirPolen(b.x, b.y + 4, 1);   \/\/ destellos mientras revolotea&#10;                return;&#10;            }&#10;            polinizar(b);&#10;            if (--b.flores &gt; 0) { elegirFlor(b); b.estado = 'vuela'; } else { const e = entradaColmena(b.casa); b.tx = e.x; b.ty = e.y; b.estado = 'vuelve'; }&#10;        }&#10;        const dx = b.tx - b.x, dy = b.ty - b.y, d = Math.hypot(dx, dy);&#10;        if (d &lt; 3) { if (b.estado === 'vuelve') { b.estado = 'dentro'; b.espera = 60 + Math.random() * 180; Apicultura.recolecta(b.polen); b.polen = 0; emitirPolen(b.x, b.y, 8); } else { b.estado = 'flor'; b.espera = 60 + Math.random() * 70; } return; }&#10;        b.x += dx \/ d * 1.5 + Math.sin(t \/ 5 + b.fase) * 0.5; b.y += dy \/ d * 1.5 + Math.cos(t \/ 6 + b.fase) * 0.5; b.dir = dx &gt;= 0 ? 1 : -1;&#10;        if (b.polen &gt; 0.1 &amp;&amp; Math.floor(t + b.fase * 10) % 7 === 0) emitirPolen(b.x - b.dir * 4, b.y + 2, 1);   \/\/ estela brillante de la abeja cargada&#10;    });&#10;}&#10;const invernada = () =&gt; obtenerEstacion() === 'invierno' || fiestaPrevia === 'navidad' || fiestaPrevia === 'santotomas' || fiestaPrevia === 'olentzero' || fiestaPrevia === 'carnaval';&#10;const POLEN_RGB = { navidad: [[229, 57, 53], [255, 193, 7]], carnaval: [[233, 30, 99], [255, 235, 59], [0, 188, 212], [142, 68, 173]], sanjuan: [[255, 120, 0], [255, 220, 80]], feria: [[229, 57, 53], [253, 216, 53]], santjordi: [[211, 47, 47], [253, 216, 53]],&#10;                    halloween: [[255, 117, 24], [142, 68, 173]], '28j': [[228, 3, 3], [255, 140, 0], [255, 237, 0], [0, 128, 38], [0, 77, 255], [117, 7, 135]] };&#10;function colorPolen() { const F = fiestaActual(), l = F &amp;&amp; POLEN_RGB[F.id]; return l ? l[Math.floor(Math.random() * l.length)] : [255, 208, 64]; }&#10;function accesorioAbeja(t) {                                                         \/\/ en coordenadas de la abeja (cabeza en x\u22484)&#10;    const F = fiestaActual(); if (!F) return; const id = F.id;&#10;    if (id === 'navidad') {                                                          \/\/ gorrito de Pap\u00e1 Noel&#10;        ctx.fillStyle = '#e53935'; ctx.beginPath(); ctx.moveTo(2.4, -1.6); ctx.lineTo(6.2, -1.6); ctx.lineTo(5.6, -5.4); ctx.closePath(); ctx.fill();&#10;        ctx.fillStyle = '#fff'; ctx.fillRect(2.2, -2.2, 4.2, 1); ctx.beginPath(); ctx.arc(5.8, -5.8, 0.9, 0, Math.PI * 2); ctx.fill();&#10;    } else if (id === 'carnaval') {                                                  \/\/ antifaz con plumita&#10;        ctx.fillStyle = '#8e44ad'; ctx.fillRect(3, -1.2, 3.4, 1.8); ctx.strokeStyle = '#ffeb3b'; ctx.lineWidth = 0.7; ctx.beginPath(); ctx.moveTo(6, -1.4); ctx.quadraticCurveTo(8, -3.5, 7, -5); ctx.stroke();&#10;    } else if (id === 'sanjuan') {                                                   \/\/ coronita de flores + chispas de hoguera&#10;        ['#ff5ca8', '#ffd23f', '#ffffff'].forEach((c, k) =&gt; { ctx.fillStyle = c; ctx.beginPath(); ctx.arc(2.8 + k * 1.6, -2.9, 0.9, 0, Math.PI * 2); ctx.fill(); });&#10;        for (let k = 0; k &lt; 2; k++) { const a = t \/ 8 + k * Math.PI; ctx.fillStyle = k ? 'rgba(255,200,0,0.9)' : 'rgba(255,120,0,0.9)'; ctx.beginPath(); ctx.arc(Math.cos(a) * 7, Math.sin(a) * 5, 0.8, 0, Math.PI * 2); ctx.fill(); }&#10;    } else if (id === '28j') {                                                       \/\/ diadema arco\u00edris&#10;        ctx.lineWidth = 0.7; PAL['28j'].forEach((c, i) =&gt; { ctx.strokeStyle = c; ctx.beginPath(); ctx.arc(1, 0, 5.5 + i * 0.6, Math.PI * 1.1, Math.PI * 1.9); ctx.stroke(); });&#10;    } else if (id === 'halloween') {                                                 \/\/ sombrero de bruja&#10;        ctx.fillStyle = '#1a1a1a'; ctx.beginPath(); ctx.moveTo(2.4, -1.8); ctx.lineTo(6.6, -1.8); ctx.lineTo(6.8, -6.2); ctx.closePath(); ctx.fill(); ctx.fillRect(1.8, -2, 5.6, 0.8);&#10;        ctx.fillStyle = '#ff7518'; ctx.fillRect(3, -3, 3.4, 0.9);&#10;    }&#10;}&#10;function decorarColmenas(t) {                                                        \/\/ nieve y abejas dormidas en invierno + adornos de fiesta&#10;    const F = fiestaActual(), id = F &amp;&amp; F.id, inv = invernada(), H = HUERTA_COLMENAS, y = H[0].y;&#10;    ctx.save();&#10;    if (inv) {&#10;        H.forEach(({ x }, i) =&gt; {&#10;            ctx.fillStyle = '#fff'; ctx.beginPath(); ctx.moveTo(x - 17, y - 48); ctx.quadraticCurveTo(x - 12, y - 56, x, y - 55); ctx.quadraticCurveTo(x + 12, y - 56, x + 17, y - 48);&#10;            ctx.quadraticCurveTo(x + 8, y - 46, x, y - 47); ctx.quadraticCurveTo(x - 8, y - 46, x - 17, y - 48); ctx.fill();                                                     \/\/ nieve en el tejado&#10;            ctx.fillStyle = 'rgba(190,230,255,0.9)'; [-14, -8, 9, 15].forEach(dx =&gt; { ctx.beginPath(); ctx.moveTo(x + dx - 1.5, y - 41); ctx.lineTo(x + dx + 1.5, y - 41); ctx.lineTo(x + dx, y - 36); ctx.fill(); });   \/\/ car\u00e1mbanos&#10;            ctx.fillStyle = '#c28a4b'; ctx.fillRect(x - 5, y - 13, 10, 3);                                                                                                    \/\/ tap\u00f3n de cera en la piquera&#10;            ctx.save(); ctx.translate(x - 3, y - 11.5); ctx.scale(0.8, 0.8); ctx.fillStyle = '#ffc928'; ctx.strokeStyle = '#1a1a1a'; ctx.lineWidth = 1;                         \/\/ abeja dormida asomada&#10;            ctx.beginPath(); ctx.ellipse(0, 0, 4.2, 2.8, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#1a1a1a'; ctx.fillRect(-1.6, -2.4, 1.3, 4.8); ctx.beginPath(); ctx.arc(4.2, 0, 1.6, 0, Math.PI * 2); ctx.fill();&#10;            if (i === 1) accesorioAbeja(t); ctx.restore();                                                                                                                      \/\/ la del medio, con el accesorio de la fiesta&#10;        });&#10;        const z = (t * 0.15) % 14; ctx.globalAlpha = 1 - z \/ 14; mTxt('\ud83d\udca4', H[1].x + 18, y - 56 - z, 11, '#000', 'center'); ctx.globalAlpha = 1;&#10;    }&#10;    if (id) {&#10;        const pal = PAL[id], ban = id === 'carnaval' || id === '28j';&#10;        if (id === 'sanjuan') H.forEach(({ x }, i) =&gt; {                                                                                                                         \/\/ farolillos con resplandor y chispas&#10;            const g = ctx.createRadialGradient(x + 22, y - 40, 1, x + 22, y - 40, 12); g.addColorStop(0, 'rgba(255,170,40,0.55)'); g.addColorStop(1, 'rgba(255,170,40,0)');&#10;            ctx.fillStyle = g; ctx.beginPath(); ctx.arc(x + 22, y - 40, 12, 0, Math.PI * 2); ctx.fill(); mTxt('\ud83c\udfee', x + 22, y - 40, 11, '#000', 'center');&#10;            if (!inv &amp;&amp; Math.floor(t + i * 9) % 30 === 0) emitirPolen(x + 22, y - 44, 1);&#10;        });&#10;        else H.forEach(({ x }) =&gt; guirnalda(x - 18, x + 18, y - 24, pal, t, ban));                                                                                              \/\/ luces o banderines en cada colmena&#10;        if (id === '28j') { const fx = H[2].x + 34; ctx.strokeStyle = '#5a3a1c'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(fx, y); ctx.lineTo(fx, y - 38); ctx.stroke();                 \/\/ bandera arco\u00edris&#10;            pal.forEach((c, i) =&gt; { ctx.fillStyle = c; ctx.fillRect(fx, y - 38 + i * 2.4 + Math.sin(t \/ 12 + i) * 0.6, 22, 2.4); }); }&#10;        if (id === 'halloween') { mTxt('\ud83c\udf83', H[1].x, y - 56, 14, '#000', 'center'); mTxt('\ud83d\udd78\ufe0f', H[0].x - 16, y - 44, 11, '#000', 'center'); }&#10;    }&#10;    ctx.restore();&#10;}&#10;function cuerpoColmena(x, y, c) {&#10;        ctx.fillStyle = '#5fa84a'; ctx.beginPath(); ctx.ellipse(x, y + 1, 32, 5, 0, 0, Math.PI * 2); ctx.fill();               \/\/ pradillo bajo la colmena (contraste con la tierra)&#10;        sombra(x, y + 1, 24, 4, 0.25); ctx.lineWidth = 1.8; ctx.strokeStyle = '#3b2412';&#10;        ctx.fillStyle = '#6b4a2b'; ctx.fillRect(x - 15, y - 6, 4, 6); ctx.fillRect(x + 11, y - 6, 4, 6);                      \/\/ patas&#10;        ctx.fillStyle = '#c28a4b'; ctx.fillRect(x - 18, y - 9, 36, 3); ctx.strokeRect(x - 18, y - 9, 36, 3);                   \/\/ base con tablilla de aterrizaje&#10;        [[y - 25, '#e0b46b'], [y - 41, c]].forEach(([by, col]) =&gt; {                                                           \/\/ alzas de madera&#10;            ctx.fillStyle = col; ctx.fillRect(x - 16, by, 32, 16); ctx.strokeRect(x - 16, by, 32, 16);&#10;            ctx.strokeStyle = 'rgba(59,36,18,0.35)'; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(x - 16, by + 8); ctx.lineTo(x + 16, by + 8); ctx.stroke(); ctx.strokeStyle = '#3b2412'; ctx.lineWidth = 1.8; });&#10;        ctx.fillStyle = '#8a5a2b'; ctx.beginPath(); ctx.moveTo(x - 20, y - 41); ctx.lineTo(x + 20, y - 41); ctx.lineTo(x + 15, y - 49); ctx.lineTo(x - 15, y - 49); ctx.closePath(); ctx.fill(); ctx.stroke();   \/\/ tejado&#10;        ctx.fillStyle = '#2b1a0d'; ctx.fillRect(x - 8, y - 13, 16, 3);                                                         \/\/ piquera (entrada)&#10;}&#10;const _sprColmena = {};&#10;function spriteColmena(c) { return _sprColmena[c] || (_sprColmena[c] = conLienzo(80, 70, () =&gt; { ctx.translate(40, 60); cuerpoColmena(0, 0, c); })); }&#10;function dibujarColmenasHuerta(t, parte) {                                           \/\/ parte: 'flores' (fondo) o 'colmenas' (capa superior)                                                   \/\/ flores + colmenas (por detr\u00e1s de las chicas)&#10;    ctx.save();&#10;    (parte === 'colmenas' ? [] : HUERTA_FLORES).forEach(([x, y, c]) =&gt; {&#10;        const s = Math.sin(t \/ 40 + x) * 1.5;&#10;        if (invernada()) { ctx.strokeStyle = '#7a6a4a'; ctx.lineWidth = 1.4; ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(x + s * 0.4, y - 8); ctx.stroke(); ctx.fillStyle = '#fff'; ctx.beginPath(); ctx.arc(x + s * 0.4, y - 9, 1.6, 0, Math.PI * 2); ctx.fill(); return; }   \/\/ flores secas con nieve&#10;        ctx.strokeStyle = '#3f8f3a'; ctx.lineWidth = 1.6; ctx.beginPath(); ctx.moveTo(x, y); ctx.quadraticCurveTo(x + s * 0.5, y - 7, x + s, y - 13); ctx.stroke();&#10;        ctx.fillStyle = '#4caf50'; ctx.beginPath(); ctx.ellipse(x + 3, y - 4, 3, 1.5, -0.5, 0, Math.PI * 2); ctx.fill();&#10;        ctx.fillStyle = c; for (let k = 0; k &lt; 5; k++) { const a = k \/ 5 * Math.PI * 2; ctx.beginPath(); ctx.arc(x + s + Math.cos(a) * 3.2, y - 14 + Math.sin(a) * 3.2, 2.2, 0, Math.PI * 2); ctx.fill(); }&#10;        ctx.fillStyle = '#f2a900'; ctx.beginPath(); ctx.arc(x + s, y - 14, 1.8, 0, Math.PI * 2); ctx.fill();&#10;    });&#10;    (parte === 'flores' ? [] : HUERTA_COLMENAS).forEach(({ x, y, c }) =&gt; ctx.drawImage(spriteColmena(c), x - 40, y - 60));       \/\/ cuerpo de la colmena: sprite&#10;    if (parte !== 'flores') decorarColmenas(t);                                          \/\/ nieve, abejas dormidas y adornos de fiesta&#10;    ctx.restore();&#10;}&#10;function dibujarAbejasHuerta(t) {                                                      \/\/ abejas por encima de todo&#10;    actualizarAbejas(t); actualizarPolen();&#10;    abejas.forEach(b =&gt; {&#10;        if (b.estado === 'dentro') return;&#10;        const e = entradaColmena(b.casa), a = (b.estado === 'sale' || b.estado === 'vuelve') ? Math.min(1, Math.hypot(b.x - e.x, b.y - e.y) \/ 12) : 1;   \/\/ aparece\/desaparece en la piquera&#10;        const ale = 0.4 + 0.6 * (Math.sin(t * 1.8 + b.fase) * 0.5 + 0.5);&#10;        ctx.save(); ctx.globalAlpha = a; ctx.translate(b.x, b.y); ctx.scale(b.dir, 1);&#10;        if (b.polen &gt; 0.1) { const g = ctx.createRadialGradient(0, 0, 1, 0, 0, 11); g.addColorStop(0, `rgba(255,222,100,${b.polen * 0.5})`); g.addColorStop(1, 'rgba(255,222,100,0)'); ctx.fillStyle = g; ctx.beginPath(); ctx.arc(0, 0, 11, 0, Math.PI * 2); ctx.fill(); }   \/\/ aura dorada&#10;        ctx.fillStyle = 'rgba(220,240,255,0.8)'; ctx.beginPath(); ctx.ellipse(-1, -4, 2.2, 3.4 * ale, -0.4, 0, Math.PI * 2); ctx.fill(); ctx.beginPath(); ctx.ellipse(2, -4.5, 2, 3.2 * ale, 0.4, 0, Math.PI * 2); ctx.fill();   \/\/ alas&#10;        ctx.fillStyle = '#ffc928'; ctx.strokeStyle = '#1a1a1a'; ctx.lineWidth = 1; ctx.beginPath(); ctx.ellipse(0, 0, 4.2, 2.8, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();           \/\/ cuerpo&#10;        ctx.fillStyle = '#1a1a1a'; ctx.fillRect(-1.6, -2.4, 1.3, 4.8); ctx.fillRect(1, -2.2, 1.3, 4.4); ctx.beginPath(); ctx.arc(4.2, 0, 1.6, 0, Math.PI * 2); ctx.fill();&#10;        if (b.polen &gt; 0.1) { ctx.fillStyle = `rgba(255,208,64,${0.4 + b.polen * 0.6})`; [-1.5, 1].forEach(dx =&gt; { ctx.beginPath(); ctx.arc(dx, 3.2, 1.2 + b.polen * 0.7, 0, Math.PI * 2); ctx.fill(); }); }   \/\/ cestitas de polen en las patas            \/\/ rayas y cabeza&#10;        accesorioAbeja(t);                                                                                      \/\/ gorro, antifaz, corona o diadema seg\u00fan la fiesta&#10;        ctx.restore();&#10;    });&#10;    dibujarPolen();&#10;}&#10;function dibujarHuerta(t) {&#10;    const gradCielo = ctx.createLinearGradient(0, 0, 0, HUERTA_SUELO_Y);&#10;    gradCielo.addColorStop(0, &quot;#bfe4ff&quot;);&#10;    gradCielo.addColorStop(1, &quot;#e8f7ff&quot;);&#10;    ctx.fillStyle = gradCielo;&#10;    ctx.fillRect(0, 0, canvas.width, HUERTA_SUELO_Y);&#10;    ctx.fillStyle = &quot;#8a5a34&quot;;&#10;    ctx.fillRect(0, HUERTA_SUELO_Y, canvas.width, HUERTA_CORTE_Y - HUERTA_SUELO_Y);&#10;    ctx.strokeStyle = &quot;rgba(0,0,0,0.12)&quot;; ctx.lineWidth = 3;&#10;    for (let sy = HUERTA_SUELO_Y + 18; sy &lt; HUERTA_CORTE_Y; sy += 16) {&#10;        ctx.beginPath();&#10;        for (let sx = 0; sx &lt;= canvas.width; sx += 20) {&#10;            ctx.lineTo(sx, sy + Math.sin(sx \/ 40) * 3);&#10;        }&#10;        ctx.stroke();&#10;    }&#10;    if (!huertaCapaCache) huertaCapaCache = construirCapaHuerta();&#10;    ctx.drawImage(huertaCapaCache, 0, 0);&#10;    SiloCompost.dibujar(t);                                                               \/\/ silo de ladrillo y compostera, al fondo&#10;    SiloCompost.dibujarMantillo();&#10;    dibujarSiembra();&#10;    dibujarPolinizacionCultivos(t);&#10;    dibujarColmenasHuerta(t, 'flores');&#10;    belarUnidades.forEach(b =&gt; dibujarBelar(b.x, b.y, t, b.fase, b.miraDerecha));&#10;    const tractorX = huertaTractorX();&#10;    const apero = aperoActivo(tractorX);&#10;    const orientacionApero = tractorX &lt;= HUERTA_ZONA_ARBOL_IZQ_X ? -1 : 1;&#10;    dibujarTractorAutonomo(tractorX, 160, t, 1.28, apero, orientacionApero);&#10;    dibujarIndicadorSemilla(tractorX);&#10;    dibujarSelectorApero(apero);&#10;    dibujarDronHabia(t);&#10;    ctx.fillStyle = &quot;#4a3620&quot;;&#10;    ctx.fillRect(0, HUERTA_CORTE_Y, canvas.width, canvas.height - HUERTA_CORTE_Y);&#10;    ctx.strokeStyle = &quot;rgba(255,255,255,0.08)&quot;; ctx.lineWidth = 2;&#10;    for (let i = 0; i &lt; 6; i++) {&#10;        ctx.beginPath();&#10;        ctx.moveTo(0, HUERTA_CORTE_Y + 14 + i * 22);&#10;        ctx.lineTo(canvas.width, HUERTA_CORTE_Y + 8 + i * 22);&#10;        ctx.stroke();&#10;    }&#10;    dibujarRiegoLUR(t);&#10;    dibujarColmenasHuerta(t, 'colmenas');&#10;    dibujarAbejasHuerta(t);&#10;    const B = HUERTA_BANCO, destello = Date.now() &lt; huertaFlashBanco;&#10;    ctx.fillStyle = destello ? &quot;rgba(190,235,255,0.45)&quot; : &quot;rgba(140,200,230,0.18)&quot;;&#10;    ctx.strokeStyle = destello ? &quot;#ffffff&quot; : &quot;#8cd0e6&quot;; ctx.lineWidth = 2.5;&#10;    ctx.setLineDash([7, 6]);&#10;    ctx.fillRect(B.x, B.y, B.w, B.h);&#10;    ctx.strokeRect(B.x, B.y, B.w, B.h);&#10;    ctx.setLineDash([]);&#10;    ctx.fillStyle = &quot;#cdeaf6&quot;; ctx.textAlign = &quot;center&quot;;&#10;    ctx.font = &quot;bold 20px 'Comic Sans MS', sans-serif&quot;;&#10;    ctx.fillText(&quot;\u2744\ufe0f -18\u00b0C&quot;, B.x + B.w \/ 2, B.y + B.h \/ 2 - 16);&#10;    ctx.font = &quot;13px 'Comic Sans MS', sans-serif&quot;;&#10;    ctx.fillText(&quot;Banco de semillas&quot;, B.x + B.w \/ 2, B.y + B.h \/ 2 + 6);&#10;    ctx.fillText(`${VARIEDADES.reduce((a, v) =&gt; a + BANCO_STOCK[v.id], 0)} semillas conservadas`, B.x + B.w \/ 2, B.y + B.h \/ 2 + 24);&#10;    ctx.fillStyle = &quot;#ffffff&quot;; ctx.font = &quot;bold 12px 'Comic Sans MS', sans-serif&quot;;&#10;    ctx.fillText(&quot;\ud83d\udc46 Toca para abrir&quot;, B.x + B.w \/ 2, B.y + B.h \/ 2 + 50);&#10;    ctx.strokeStyle = &quot;#3a2a18&quot;; ctx.lineWidth = 4;&#10;    ctx.beginPath(); ctx.moveTo(0, HUERTA_CORTE_Y); ctx.lineTo(canvas.width, HUERTA_CORTE_Y); ctx.stroke();&#10;    ctx.fillStyle = &quot;#7cb342&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2.5;&#10;    ctx.fillRect(canvas.width \/ 2 - 110, 14, 220, 40);&#10;    ctx.strokeRect(canvas.width \/ 2 - 110, 14, 220, 40);&#10;    ctx.fillStyle = &quot;#fff&quot;;&#10;    ctx.font = &quot;bold 20px 'Comic Sans MS', sans-serif&quot;;&#10;    ctx.textAlign = &quot;center&quot;;&#10;    ctx.fillText(&quot;\ud83c\udf31 LA HUERTA \ud83c\udf31&quot;, canvas.width \/ 2, 40);&#10;    if (belarUnidades.length === 0) entrarALaHuerta();&#10;    dibujarFiestaEscena('huerta', t);&#10;    dibujarBancoInterfaz();&#10;    dibujarBotonVolver();&#10;    dibujarBotonMercado();&#10;}&#10;let interiorEstado = 'de_pie';&#10;let temporizadorInterior = 0;&#10;let sosteniendoEscoba = false;&#10;let motasSuciedad = [];&#10;function generarSuciedad() {&#10;    motasSuciedad = [];&#10;    for (let i = 0; i &lt; 22; i++) {&#10;        motasSuciedad.push({&#10;            x: 20 + Math.random() * (ANCHO_PRINCIPAL - 40),&#10;            y: canvas.height * 0.65 + Math.random() * (canvas.height * 0.33),&#10;            r: 3 + Math.random() * 3,&#10;            limpia: false&#10;        });&#10;    }&#10;}&#10;const DERECHA_X = ANCHO_PRINCIPAL + 6;&#10;const DERECHA_ANCHO = canvas.width - DERECHA_X - 20;&#10;const ZONA_BA\u00d1ERA    = { x: DERECHA_X + 10 + (DERECHA_ANCHO - 20) * 0.28, y: canvas.height * 0.5 + 10 + canvas.height * 0.42 * 0.72, accion: 'ba\u00f1\u00e1ndose', icono: '\ud83d\udca6' };&#10;const ZONA_FOGONES   = { x: DERECHA_X + 10 + (DERECHA_ANCHO - 20) * 0.32, y: 20 + canvas.height * 0.42 * 0.55,                       accion: 'cocinando',  icono: '\ud83c\udf73' };&#10;const ZONA_FREGADERO = { x: DERECHA_X + 10 + (DERECHA_ANCHO - 20) * 0.75, y: 20 + canvas.height * 0.42 * 0.54,                       accion: 'fregando',   icono: '\u2728' };&#10;const ZONA_ESCOBA    = { x: ANCHO_PRINCIPAL * 0.85, y: canvas.height * 0.9,                                                          accion: 'barriendo',  icono: '\ud83e\uddf9' };&#10;const ZONA_NEVERA    = { x: DERECHA_X + DERECHA_ANCHO - DERECHA_ANCHO * 0.24 + (DERECHA_ANCHO * 0.22) \/ 2, y: 20 + canvas.height * 0.42 \/ 2, accion: 'nevera', icono: '\ud83e\uddca' };&#10;const ZONAS_INTERIOR = [ZONA_BA\u00d1ERA, ZONA_FOGONES, ZONA_FREGADERO, ZONA_ESCOBA, ZONA_NEVERA, ZONA_CAMILLA, ZONA_MOCHILA];&#10;function dibujarEscoba(x, y, t, moviendo) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    const balanceo = moviendo ? Math.sin(t \/ 5) * 0.4 : 0;&#10;    ctx.rotate(-0.2 + balanceo);&#10;    ctx.strokeStyle = &quot;#8a5a2b&quot;; ctx.lineWidth = 4;&#10;    ctx.beginPath(); ctx.moveTo(0, 10); ctx.lineTo(0, -30); ctx.stroke();&#10;    ctx.fillStyle = &quot;#e8c168&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 1.5;&#10;    ctx.beginPath();&#10;    ctx.moveTo(-9, 10); ctx.lineTo(9, 10); ctx.lineTo(5, 24); ctx.lineTo(-5, 24);&#10;    ctx.closePath(); ctx.fill(); ctx.stroke();&#10;    ctx.restore();&#10;    if (moviendo) {&#10;        ctx.fillStyle = &quot;rgba(180,150,100,0.7)&quot;;&#10;        for (let i = 0; i &lt; 3; i++) {&#10;            const fase = (t \/ 4 + i * 6) % 18;&#10;            ctx.beginPath();&#10;            ctx.arc(x + Math.sin(t \/ 5 + i) * 20, y + 22 - fase, 2, 0, Math.PI * 2);&#10;            ctx.fill();&#10;        }&#10;    }&#10;}&#10;function esDeDia() {&#10;    const hora = new Date().getHours();&#10;    return hora &gt;= 6 &amp;&amp; hora &lt; 18;&#10;}&#10;function esHoraDeDormir() {&#10;    const hora = new Date().getHours();&#10;    return hora &gt;= 23 || hora &lt; 6;&#10;}&#10;function casaPropia(h) {&#10;    const propia = casas.findIndex(c =&gt; c.colorPelo === h.colorPelo &amp;&amp; c.estilo === h.estilo);&#10;    if (propia &gt;= 0 &amp;&amp; !habitantes.some(o =&gt; o !== h &amp;&amp; o.casaAsignada === propia)) return propia;      \/\/ su casa, si no la ocupa ya otra&#10;    let mejor = 0, mejorPuntos = Infinity;&#10;    casas.forEach((c, i) =&gt; {&#10;        const ocupantes = habitantes.filter(o =&gt; o !== h &amp;&amp; o.casaAsignada === i).length;&#10;        const puntos = ocupantes * 1000 + Math.abs((c.x + c.ancho \/ 2) - h.x);&#10;        if (puntos &lt; mejorPuntos) { mejorPuntos = puntos; mejor = i; }&#10;    });&#10;    return mejor;&#10;}&#10;function dormirHabitante(h) {&#10;    h.durmiendo = true; diarioNota('momentos', 'noche', 'Primera noche: el pueblo duerme', '\ud83c\udf19');&#10;    if (h.lugar === 'gimnasio') { GimnasioPueblo.limpiar(h); h.estado = 'caminando'; }&#10;    h.enPlaya = false; h.oculta = false; h.lugar = null; h.bib = null; h.comida = null; h.comiendo = null; h.cocinando = false;&#10;    if (h.patinete) { h.patinete.montadaPor = null; h.patinete = null; }&#10;    if (h.casaAsignada === null || h.casaAsignada === undefined) {&#10;        h.casaAsignada = casaPropia(h);                                  \/\/ duerme sola, en su casa&#10;    }&#10;    if (esperandoMercadillo === h) esperandoMercadillo = null;&#10;    if (esperandoFrutas === h) esperandoFrutas = null;&#10;}&#10;function despertarHabitante(h) {&#10;    h.durmiendo = false;&#10;    h.enPlaya = false; h.oculta = false; h.lugar = null; h.bib = null;&#10;    const casaHogar = casas[h.casaAsignada];&#10;    h.x = casaHogar.x + casaHogar.ancho \/ 2 + (Math.random() * 30 - 15);&#10;    h.y = yDeCalle(h.x);&#10;    nuevoObjetivo(h);&#10;    h.estado = 'caminando';&#10;}&#10;function gestionarSue\u00f1oNocturno() {&#10;    const horaDormir = esHoraDeDormir();&#10;    if (horaDormir &amp;&amp; habitantes.some(h =&gt; !h.durmiendo &amp;&amp; !h.arrastrando)) ordenarCamasNocturnas();&#10;    habitantes.forEach(h =&gt; {&#10;        if (h.arrastrando) return; \/\/ no forzar mientras el jugador la est\u00e1 moviendo&#10;        if (horaDormir &amp;&amp; !h.durmiendo) {&#10;            dormirHabitante(h);&#10;        } else if (!horaDormir &amp;&amp; h.durmiendo) {&#10;            despertarHabitante(h);&#10;        }&#10;    });&#10;    if (horaDormir &amp;&amp; habitantesEnPlaya.length &gt; 0) {&#10;        habitantesEnPlaya = []; \/\/ la playa queda vac\u00eda; ya se han ido a dormir arriba&#10;    }&#10;}&#10;function obtenerEstacion() {&#10;    const mes = new Date().getMonth(); \/\/ 0 = enero&#10;    if (mes === 11 || mes === 0 || mes === 1) return 'invierno';&#10;    if (mes &gt;= 2 &amp;&amp; mes &lt;= 4) return 'primavera';&#10;    if (mes &gt;= 5 &amp;&amp; mes &lt;= 7) return 'verano';&#10;    return 'oto\u00f1o'; \/\/ 8, 9, 10 \u2192 septiembre, octubre, noviembre&#10;}&#10;function horaTexto() {&#10;    const d = new Date();&#10;    return String(d.getHours()).padStart(2, '0') + ':' + String(d.getMinutes()).padStart(2, '0');&#10;}&#10;function dibujarReloj(dia) {&#10;    ctx.save();&#10;    const texto = (dia ? &quot;\u2600\ufe0f &quot; : &quot;\ud83c\udf19 &quot;) + horaTexto();&#10;    ctx.font = &quot;bold 16px 'Comic Sans MS', sans-serif&quot;;&#10;    const anchoTexto = ctx.measureText(texto).width;&#10;    ctx.fillStyle = &quot;rgba(255,255,255,0.88)&quot;;&#10;    ctx.strokeStyle = &quot;rgba(0,0,0,0.25)&quot;; ctx.lineWidth = 1.5;&#10;    const pw = anchoTexto + 20, ph = 28;&#10;    const px = canvas.width \/ 2 - pw \/ 2, py = 10;&#10;    ctx.beginPath();&#10;    ctx.roundRect ? ctx.roundRect(px, py, pw, ph, 14) : ctx.rect(px, py, pw, ph);&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#2a1533&quot;;&#10;    ctx.textAlign = &quot;left&quot;;&#10;    ctx.textBaseline = &quot;middle&quot;;&#10;    ctx.fillText(texto, px + 10, py + ph \/ 2 + 1);&#10;    const sx = px + pw + 24, sy = py + ph \/ 2;&#10;    zonaAltavoz.x = sx; zonaAltavoz.y = sy; zonaAltavoz.radio = 17;&#10;    ctx.fillStyle = &quot;rgba(255,255,255,0.88)&quot;;&#10;    ctx.strokeStyle = &quot;rgba(0,0,0,0.25)&quot;; ctx.lineWidth = 1.5;&#10;    ctx.beginPath();&#10;    ctx.arc(sx, sy, zonaAltavoz.radio, 0, Math.PI * 2);&#10;    ctx.fill(); ctx.stroke();&#10;    ctx.font = &quot;17px Arial&quot;;&#10;    ctx.textAlign = &quot;center&quot;;&#10;    ctx.fillText(silenciado ? &quot;\ud83d\udd07&quot; : &quot;\ud83d\udd0a&quot;, sx, sy + 1);&#10;    ctx.restore();&#10;}&#10;function dibujarSol(x, y, t) {&#10;    if (climaSinSol) return;&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.fillStyle = &quot;#ffd166&quot;;&#10;    ctx.strokeStyle = &quot;#f2a65a&quot;; ctx.lineWidth = 2;&#10;    ctx.rotate(t \/ 200);&#10;    for (let i = 0; i &lt; 8; i++) {&#10;        ctx.save();&#10;        ctx.rotate((i * Math.PI) \/ 4);&#10;        ctx.beginPath();&#10;        ctx.moveTo(0, -26); ctx.lineTo(4, -34); ctx.lineTo(-4, -34);&#10;        ctx.closePath(); ctx.fill();&#10;        ctx.restore();&#10;    }&#10;    ctx.beginPath(); ctx.arc(0, 0, 22, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.restore();&#10;}&#10;function dibujarLuna(x, y) {&#10;    ctx.save();&#10;    ctx.translate(x, y);&#10;    ctx.fillStyle = &quot;#f2f2e8&quot;;&#10;    ctx.beginPath(); ctx.arc(0, 0, 20, 0, Math.PI * 2); ctx.fill();&#10;    ctx.fillStyle = &quot;#dcdccc&quot;;&#10;    [[-6, -5, 4], [5, 3, 3], [-2, 8, 2.5]].forEach(([cx, cy, r]) =&gt; {&#10;        ctx.beginPath(); ctx.arc(cx, cy, r, 0, Math.PI * 2); ctx.fill();&#10;    });&#10;    ctx.restore();&#10;}&#10;const estrellas = [];&#10;for (let i = 0; i &lt; 40; i++) {&#10;    estrellas.push({ x: Math.random() * 960, y: Math.random() * (CIELO_ALTO - 10), fase: Math.random() * 100 });&#10;}&#10;const TREN = { x: TRANVIA.x, estado: 'parado', espera: 600, v: 0, n: 2, parada: 0, pasajeras: [] };   \/\/ n = vagones enganchados      \/\/ x = posici\u00f3n de la cabina&#10;function dibujarRailTranvia() {&#10;    const y = TRANVIA.y + 11, w = canvas.width;&#10;    ctx.save();&#10;    for (let x = 2; x &lt; w; x += 14) { ctx.fillStyle = (x \/ 14) % 2 ? '#6b4a2b' : '#5a3a1c'; ctx.fillRect(x, y + 1, 9, 6); }   \/\/ traviesas&#10;    ctx.fillStyle = 'rgba(120,110,100,0.35)'; ctx.fillRect(0, y + 6, w, 3);                                             \/\/ balasto&#10;    ctx.strokeStyle = '#4a4f57'; ctx.lineWidth = 3; ctx.beginPath(); ctx.moveTo(0, y); ctx.lineTo(w, y); ctx.stroke();   \/\/ ra\u00edl continuo&#10;    ctx.strokeStyle = 'rgba(255,255,255,0.55)'; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(0, y - 1.5); ctx.lineTo(w, y - 1.5); ctx.stroke();&#10;    ctx.restore();&#10;}&#10;function dibujarVagon(x, y, t) {                                          \/\/ mismo rosa y ruedas que la cabina&#10;    ctx.save(); ctx.translate(x, y);&#10;    ctx.fillStyle = &quot;#e85fb0&quot;; ctx.strokeStyle = &quot;#000&quot;; ctx.lineWidth = 2.5;&#10;    ctx.beginPath(); ctx.roundRect ? ctx.roundRect(-38, -34, 76, 34, 8) : ctx.rect(-38, -34, 76, 34); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = &quot;#cdeeff&quot;; [-30, -10, 10].forEach(vx =&gt; { ctx.fillRect(vx, -28, 16, 12); ctx.strokeRect(vx, -28, 16, 12); });&#10;    ctx.fillStyle = &quot;#fff&quot;; ctx.fillRect(-36, -10, 72, 3);&#10;    const giro = (t \/ 10) % (Math.PI * 2);&#10;    [-22, 22].forEach(rx =&gt; {&#10;        ctx.save(); ctx.translate(rx, 4); ctx.rotate(giro); ctx.fillStyle = &quot;#333&quot;;&#10;        ctx.beginPath(); ctx.arc(0, 0, 6, 0, Math.PI * 2); ctx.fill();&#10;        ctx.strokeStyle = &quot;#aaa&quot;; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(-6, 0); ctx.lineTo(6, 0); ctx.moveTo(0, -6); ctx.lineTo(0, 6); ctx.stroke(); ctx.restore();&#10;    });&#10;    ctx.restore();&#10;}&#10;function dibujarTren(t) {                                                 \/\/ un \u00fanico convoy: su longitud crece con los vagones fabricados&#10;    const T = TREN, offVagon = k =&gt; 84 + (k - 1) * 82, colaDe = n =&gt; offVagon(n) + 38;   \/\/ k=1 es el vag\u00f3n pegado a la cabina&#10;    if (T.estado === 'parado') {&#10;        T.x = TRANVIA.x;&#10;        if (T.n &lt; Math.min(4, 2 + flota.vagones) &amp;&amp; t % 50 === 0) T.n++;           \/\/ engancha un vag\u00f3n nuevo de la Zona Industrial (m\u00e1x. 4 para caber en la parada)&#10;        else if (--T.espera &lt;= 0) { T.estado = 'viaje'; T.parada = 1; T.v = 0.2; Desgaste.sube('reptranvia', 0.03); }&#10;    }&#10;    else if (T.estado === 'viaje') {                                                                                \/\/ de parada en parada, frenando suave&#10;        const meta = PARADAS[T.parada].x; T.v = Math.min(2.4 * (1 - 0.15 * Desgaste.nivel('reptranvia')), Math.max(0.7, (meta - T.x) * 0.04), T.v + 0.05); T.x += T.v;&#10;        if (meta - T.x &lt;= 0.8) { T.x = meta; T.estado = 'estacion'; T.espera = 420; }&#10;    }&#10;    else if (T.estado === 'estacion') { if (--T.espera &lt;= 0) { T.parada++; if (T.parada &gt;= PARADAS.length) { T.estado = 'sale'; T.v = 0.8; } else { T.estado = 'viaje'; T.v = 0.2; } } }&#10;    else if (T.estado === 'sale') { T.v = Math.min(4.2 * (1 - 0.15 * Desgaste.nivel('reptranvia')), T.v + 0.05); T.x += T.v; if (T.x - colaDe(T.n) &gt; canvas.width) { T.x = -60; T.estado = 'entra'; Tranvia.llegaPlaya(T); } }&#10;    else { T.v = Math.max(0.6, (TRANVIA.x - T.x) * 0.03); T.x += T.v; if (T.x &gt;= TRANVIA.x - 0.5) { T.x = TRANVIA.x; T.estado = 'parado'; T.parada = 0; T.espera = 1200; } }&#10;    dibujarRailTranvia(); Tranvia.dibujarParadas(); Tranvia.gestionar(T, t);&#10;    sombra(T.x, TRANVIA.y + 14, 46, 6, 0.3);&#10;    for (let k = 1; k &lt;= T.n; k++) sombra(T.x - offVagon(k), TRANVIA.y + 14, 46, 6, 0.3);   \/\/ sombra bajo cabina y vagones&#10;    ctx.fillStyle = '#20262e'; for (let k = 1; k &lt;= T.n; k++) ctx.fillRect(T.x - (offVagon(k) - 38) - 6, TRANVIA.y - 10, 12, 4);   \/\/ enganches&#10;    for (let k = T.n; k &gt;= 1; k--) dibujarVagon(T.x - offVagon(k), TRANVIA.y, t);&#10;    dibujarTranvia(T.x, TRANVIA.y, t);&#10;    Tranvia.dibujarPasajeras(T, t, offVagon);&#10;    desgasteTren(T, t, offVagon);&#10;}&#10;function escalaProf(yBase) { return 0.93 + 0.15 * Math.max(0, Math.min(1, (yBase - SUELO_Y) \/ (canvas.height - SUELO_Y))); }&#10;function conProf(x, yBase, fn) {                                          \/\/ dibuja fn() escalado alrededor de su punto de apoyo&#10;    const f = escalaProf(yBase);&#10;    ctx.save(); ctx.translate(x, yBase); ctx.scale(f, f); ctx.translate(-x, -yBase); fn(); ctx.restore();&#10;}&#10;function sombra(x, y, rx, ry = rx * 0.22, a = 0.16) {                     \/\/ elipse suave con degradado radial (sprite \u00fanico escalado)&#10;    const ga = ctx.globalAlpha; ctx.globalAlpha = ga * a; ctx.drawImage(spriteSombra(), x - rx, y - ry, rx * 2, ry * 2); ctx.globalAlpha = ga;&#10;}&#10;function dibujarSombrasPueblo() {                                         \/\/ sombras de fondo: edificios, \u00e1rboles, bancos y fuente&#10;    const by = SUELO_Y + 57;&#10;    casas.forEach(c =&gt; sombra(c.x + c.ancho \/ 2, by, c.ancho * 0.66, 8));&#10;    sombra(GIMNASIO_EDIFICIO.x + GIMNASIO_EDIFICIO.ancho \/ 2, by, GIMNASIO_EDIFICIO.ancho * 0.66, 8);&#10;    sombra(BIBLIOTECA.x + BIBLIOTECA.ancho \/ 2, by, BIBLIOTECA.ancho * 0.66, 8);&#10;    bancos.forEach(b =&gt; sombra(b.x + 23, b.y + 1, 32, 5));&#10;    sombra(FUENTE_POS.x, FUENTE_POS.y + 14, 58, 9, 0.14);&#10;    sombra(KUTXA_POS.x, KUTXA_POS.y + 2, 32, 5, 0.22);&#10;    sombra(TERRAZA.baseX + TERRAZA.ancho \/ 2, TERRAZA.baseY + TERRAZA.alto + 4, TERRAZA.ancho * 0.6, 10);&#10;    sombra(MERCADILLO.baseX + MERCADILLO.ancho \/ 2, MERCADILLO.baseY + MERCADILLO.alto + 4, MERCADILLO.ancho * 0.6, 10);&#10;    sombra(REFUGIO.x, REFUGIO.y + 4, 54, 8); sombra(ZONA_PUESTOFRUTA.x, ZONA_PUESTOFRUTA.yBase + 4, 66, 9);   \/\/ refugio y puesto de frutas&#10;    [[412, SUELO_Y + 90, 1], [634, SUELO_Y + 105, 1], [460, canvas.height - 30, 0.9]].forEach(([x, y, e]) =&gt; sombra(x, y + 2, 34 * e, 7 * e));&#10;}&#10;function dibujarPueblo() {&#10;    const dia = esDeDia();&#10;    const estacion = obtenerEstacion();&#10;    const cielo = ctx.createLinearGradient(0, 0, 0, CIELO_ALTO);&#10;    if (dia) {&#10;        cielo.addColorStop(0, &quot;#bfe4ff&quot;);&#10;        cielo.addColorStop(1, &quot;#e8f7ff&quot;);&#10;    } else {&#10;        cielo.addColorStop(0, &quot;#0d1130&quot;);&#10;        cielo.addColorStop(1, &quot;#2a1d47&quot;);&#10;    }&#10;    ctx.fillStyle = cielo;&#10;    ctx.fillRect(0, 0, canvas.width, CIELO_ALTO);&#10;    if (dia) {&#10;        dibujarSol(870, 30, t);&#10;        ctx.fillStyle = &quot;rgba(255,255,255,0.85)&quot;;&#10;        [[100, 40, 30], [260, 60, 22], [700, 35, 28], [860, 100, 20]].forEach(([nx, ny, r]) =&gt; {&#10;            ctx.beginPath();&#10;            ctx.ellipse(nx, ny, r, r * 0.5, 0, 0, Math.PI * 2);&#10;            ctx.fill();&#10;        });&#10;    } else {&#10;        dibujarLuna(870, 55);&#10;        estrellas.forEach(e =&gt; {&#10;            const parpadeo = 0.5 + Math.sin(t \/ 20 + e.fase) * 0.5;&#10;            ctx.fillStyle = `rgba(255,255,255,${0.3 + parpadeo * 0.6})`;&#10;            ctx.beginPath();&#10;            ctx.arc(e.x, e.y, 1.4, 0, Math.PI * 2);&#10;            ctx.fill();&#10;        });&#10;        ctx.fillStyle = &quot;rgba(255,255,255,0.12)&quot;;&#10;        [[130, 45, 26], [700, 40, 24], [300, 30, 18]].forEach(([nx, ny, r]) =&gt; {&#10;            ctx.beginPath();&#10;            ctx.ellipse(nx, ny, r, r * 0.5, 0, 0, Math.PI * 2);&#10;            ctx.fill();&#10;        });&#10;    }&#10;    const px = (t * 1.5) % (canvas.width + 100) - 50;&#10;    dibujarMolino(55, SUELO_Y + 5, 0.85, t);&#10;    if (dia) {&#10;        dibujarPajaro(px, 45, t);&#10;        dibujarPajaro((px + 400) % (canvas.width + 100) - 50, 75, t + 10);&#10;    }&#10;    const cocheX = (t * 0.7) % (canvas.width + 160) - 80;&#10;    const cocheY = 55 + Math.sin(t \/ 45) * 6;&#10;    dibujarCieloFiesta(t);&#10;    dibujarCocheVolador(cocheX, cocheY, t, 0.9); humoCoche(cocheX, cocheY, t);&#10;    dibujarEfectosKutxa(t);                                                             \/\/ vuelo triunfal del coche financiado por la Kutxa&#10;    if (flota.coches &gt; 0 &amp;&amp; !KutxaPanel.volandoCoche()) { const x2 = ((t * 0.5) + 420) % (canvas.width + 160) - 80, y2 = 98 + Math.sin(t \/ 38 + 1) * 6; dibujarCocheVolador(x2, y2, t, 0.8); humoCoche(x2, y2, t); }   \/\/ 2.\u00ba coche fabricado; nunca m\u00e1s de 2 a la vez&#10;    const colorCesped = estacion === 'invierno' ? &quot;#dfeee0&quot; : estacion === 'primavera' ? &quot;#8fe07a&quot; : estacion === 'oto\u00f1o' ? &quot;#c2b25a&quot; : &quot;#8fd66a&quot;;&#10;    const colorCespedParque = estacion === 'invierno' ? &quot;#cfe3d2&quot; : estacion === 'primavera' ? &quot;#7fd66a&quot; : estacion === 'oto\u00f1o' ? &quot;#b3a24e&quot; : &quot;#79c85b&quot;;&#10;    ctx.fillStyle = colorCesped;&#10;    ctx.fillRect(0, SUELO_Y, canvas.width, canvas.height - SUELO_Y);&#10;    ctx.fillStyle = &quot;#e8d3a9&quot;;&#10;    ctx.fillRect(0, SUELO_Y + 55, canvas.width, 30);&#10;    ctx.fillStyle = colorCespedParque;&#10;    ctx.fillRect(410, SUELO_Y + 50, 230, canvas.height - SUELO_Y - 50);&#10;    dibujarSombrasPueblo();&#10;    dibujarCaminoHuerta();&#10;    dibujarTren(t);&#10;    conProf(412, SUELO_Y + 90, () =&gt; dibujarArbol(412, SUELO_Y + 90, 1, t, 0, estacion));&#10;    conProf(634, SUELO_Y + 105, () =&gt; dibujarArbol(634, SUELO_Y + 105, 1, t, 1.5, estacion));&#10;    conProf(460, canvas.height - 30, () =&gt; dibujarArbol(460, canvas.height - 30, 0.9, t, 3, estacion));&#10;    conProf(FUENTE_POS.x, FUENTE_POS.y + 14, () =&gt; dibujarFuente(FUENTE_POS.x, FUENTE_POS.y, t));&#10;    conProf(KUTXA_POS.x, KUTXA_POS.y, () =&gt; dibujarKutxa(t));                         \/\/ Kutxa AuZ junto a la fuente&#10;    conProf(Noticias.TABLON.x, Noticias.TABLON.y, () =&gt; Noticias.dibujarTablon(t));  \/\/ tabl\u00f3n de noticias y sucesos&#10;    ctx.fillStyle = &quot;#e8d3a9&quot;;&#10;    ctx.fillRect(0, canvas.height - 34, canvas.width, 34);&#10;    const coloresFruta = [&quot;#d6335a&quot;, &quot;#f2a65a&quot;];&#10;    for (let i = 0; i &lt; 9; i++) {&#10;        conProf(35 + i * 115, canvas.height - 34, () =&gt; dibujarArbolFrutal(35 + i * 115, canvas.height - 34, 0.85, t, i * 1.3, coloresFruta[i % 2], estacion));&#10;    }&#10;    conProf(REFUGIO.x, REFUGIO.y, () =&gt; dibujarRefugio(REFUGIO.x, REFUGIO.y));                                                               \/\/ al fondo&#10;    conProf(ZONA_PUESTOFRUTA.x, ZONA_PUESTOFRUTA.yBase, () =&gt; dibujarPuestoFrutas(ZONA_PUESTOFRUTA.x, ZONA_PUESTOFRUTA.yBase, ZONA_PUESTOFRUTA.escala));   \/\/ plano medio&#10;    bancos.forEach(b =&gt; conProf(b.x + 23, b.y, () =&gt; dibujarBanco(b.x, b.y)));&#10;    patinetes.forEach(p =&gt; { if (!p.montadaPor) conProf(p.x, p.y, () =&gt; dibujarPatinete(p.x, p.y, 0)); });&#10;    flores.forEach(f =&gt; dibujarFlor(f.x, f.y, f.color, t));&#10;    if (estacion === 'primavera') {&#10;        floresPrimavera.forEach(f =&gt; dibujarFlor(f.x, f.y, f.color, t));&#10;    }&#10;    casas.forEach((c, i) =&gt; {&#10;        const ocupadaDeNoche = !dia &amp;&amp; habitantes.some(h =&gt; h.durmiendo &amp;&amp; h.casaAsignada === i);&#10;        dibujarCasa(c.x, SUELO_Y + 55, c.ancho, c.alto, c.pared, c.tejado, ocupadaDeNoche, estacion === 'invierno');&#10;    });&#10;    dibujarEdificioGimnasio(GIMNASIO_EDIFICIO);&#10;    dibujarEdificioBiblioteca(BIBLIOTECA);&#10;    dibujarEdificioIndustria(t);&#10;    dibujarParadaArena(t);&#10;    dibujarParadaHospital(t);&#10;    dibujarMesaLectura(BIBLIOTECA_MESA.x, BIBLIOTECA_MESA.y);&#10;    dibujarFiestaBiblioteca(t);&#10;    conProf(TERRAZA.baseX + TERRAZA.ancho \/ 2, TERRAZA.baseY + TERRAZA.alto, () =&gt; dibujarTerraza(t, dia));&#10;    conProf(MERCADILLO.baseX + MERCADILLO.ancho \/ 2, MERCADILLO.baseY + MERCADILLO.alto, () =&gt; dibujarMercadillo(t, dia));&#10;    Conmemoraciones.dibujarPueblo(t);                                                  \/\/ 8M \/ 25N: pancartas, y velas en el minuto de silencio&#10;    Fiestas2.dibujarPueblo(t);                                                            \/\/ Gargant\u00faa, puesto de talos, Olentzero y regalos: por delante del mercadillo y su guirnalda&#10;    dibujarDesgasteCasas(t); dibujarFiestaPueblo(t); dibujarGauBeltzaPueblo(t);&#10;    actualizarHabitantes();&#10;    VidaDiaria.actualizar();&#10;    Biblioteca.actualizar();&#10;    Asamblea.actualizar();&#10;    actualizarMascotas();&#10;    mascotas.forEach(m =&gt; {&#10;        const tumbado = m.estado === 'reposo' || m.estado === 'en_refugio';&#10;        conProf(m.x, m.y, () =&gt; { sombra(m.x, m.y + 2, 15, 3.5, 0.2);&#10;            if (m.tipo === 'gato') dibujarGato(m.x, m.y, t, m.fase, tumbado);&#10;            else dibujarPerro(m.x, m.y, t, m.fase, tumbado); });&#10;    });&#10;    Ayuda.latidos(t);&#10;    habitantes.forEach((h) =&gt; {&#10;        if (h.durmiendo || h.enPlaya || h.oculta) return;&#10;        ctx.save(); const fh = escalaProf(h.y + 27); ctx.translate(h.x, h.y + 27); ctx.scale(fh, fh); ctx.translate(-h.x, -(h.y + 27));   \/\/ perspectiva&#10;        sombra(h.x, h.y + 28, 16, 4, 0.2);&#10;        const caminando = h.estado === 'caminando' || h.moviendoAsamblea;&#10;        const bamboleo = caminando ? Math.sin(t \/ 6) * 0.06 * h.direccion : Math.sin(t \/ 30) * 0.02;&#10;        if (h.patinete) {&#10;            h.patinete.x = h.x;&#10;            h.patinete.y = h.y + 20;&#10;            dibujarPatinete(h.patinete.x, h.patinete.y, h.direccion &lt; 0 ? 0.08 : -0.08);&#10;        }&#10;        rostro = (h.enamorada &gt; 0 || h.estado === 'social') ? 'enamorada' : h.felizHasta &gt; t ? 'feliz' : (h.estado === 'mercadillo' || h.estado === 'mercadillo_esperando') ? 'curiosa' : h.estado === 'leyendo' ? 'leyendo' : (h.estado === 'frutas' || h.estado === 'frutas_esperando' || h.comiendo) ? 'feliz' : null;&#10;        dibujarMu\u00f1eca(&#10;            { x: h.x, y: h.y, angulo: bamboleo },&#10;            h.colorPelo, false, h.direccion &lt; 0, false, h.estilo&#10;        );&#10;        rostro = null;&#10;        accesorioFiesta(h.x, h.y, h.direccion &lt; 0 ? -1 : 1);&#10;        if (h.felizHasta &gt; t) { const k = (h.felizHasta - t) \/ 260; dibujarCorazon(h.x + 14, h.y - 48 - (1 - k) * 22, Math.min(1, k * 2)); }&#10;        if (h.comiendo) Comidas.dibujarPlato(h, t); else if (h.comida) Comidas.dibujarBolsa(h); else if (h.taloT &gt; 0) Fiestas2.dibujarComiendoTalo(h, t);        \/\/ plato en la terraza \/ bolsa de la compra&#10;        if (h.estado === 'social') {&#10;            dibujarCorazon(h.x, h.y - 45, Math.min(1, h.temporizador \/ 20));&#10;        }&#10;        if (h.estado === 'mercadillo' || h.estado === 'mercadillo_esperando') {&#10;            ctx.font = &quot;18px Arial&quot;;&#10;            ctx.textAlign = &quot;center&quot;;&#10;            ctx.fillText(&quot;\ud83d\udc40&quot;, h.x, h.y - 45);&#10;        }&#10;        if (h.estado === 'frutas' || h.estado === 'frutas_esperando') {&#10;            ctx.font = &quot;18px Arial&quot;;&#10;            ctx.textAlign = &quot;center&quot;;&#10;            ctx.fillText(&quot;\ud83c\udf38&quot;, h.x, h.y - 45);&#10;        }&#10;        if (h.estado === 'leyendo') {&#10;            ctx.font = &quot;18px Arial&quot;;&#10;            ctx.textAlign = &quot;center&quot;;&#10;            ctx.fillText(&quot;\ud83d\udcd6&quot;, h.x, h.y - 45);&#10;        }&#10;        if (h.enamorada &gt; 0) {&#10;            ctx.font = &quot;20px Arial&quot;;&#10;            ctx.textAlign = &quot;center&quot;;&#10;            ctx.globalAlpha = Math.min(1, h.enamorada \/ 30);&#10;            ctx.fillText(&quot;\ud83d\udc95&quot;, h.x, h.y - 48);&#10;            ctx.globalAlpha = 1;&#10;        }&#10;        ctx.restore();&#10;    });&#10;    if (estacion === 'oto\u00f1o') {&#10;        dibujarHojasOtono(t);&#10;    }&#10;    if (!dia) {&#10;        ctx.fillStyle = &quot;rgba(20,20,60,0.32)&quot;;&#10;        ctx.fillRect(0, 0, canvas.width, canvas.height);&#10;    } else if (estacion === 'verano') {&#10;        ctx.fillStyle = &quot;rgba(255,200,80,0.1)&quot;;&#10;        ctx.fillRect(0, 0, canvas.width, canvas.height);&#10;    } else if (estacion === 'invierno') {&#10;        ctx.fillStyle = &quot;rgba(200,220,255,0.12)&quot;;&#10;        ctx.fillRect(0, 0, canvas.width, canvas.height);&#10;    } else if (estacion === 'oto\u00f1o') {&#10;        ctx.fillStyle = &quot;rgba(200,130,50,0.1)&quot;;&#10;        ctx.fillRect(0, 0, canvas.width, canvas.height);&#10;    }&#10;    dibujarConfeti(t);&#10;    dibujarFraseGauBeltza(t);&#10;    Asamblea.dibujar(t);&#10;    dibujarPanelKutxa();&#10;    Noticias.dibujarPanel();&#10;    dibujarReloj(dia);&#10;}&#10;let enIndustria = false;&#10;const flota = { vagones: 0, coches: 0 };                                   \/\/ veh\u00edculos fabricados en la Zona Industrial&#10;const recursos = { arcilla: 80, resina: 80, proteina: 80, energia: 80 };   \/\/ flujo de recursos compartido&#10;const bienestar = { alim: 35, agua: 35, viv: 35, mov: 35 };                \/\/ bienestar comunitario&#10;const INDUSTRIA_EDIFICIO = { x: 550, ancho: 58, alto: 108 };               \/\/ hueco libre entre biblioteca y gimnasio&#10;function dibujarEdificioIndustria(t) {                                     \/\/ edificio de cristal futurista con engranaje&#10;    const b = INDUSTRIA_EDIFICIO, x = b.x, y = SUELO_Y + 55, w = b.ancho, h = b.alto, cx = x + w \/ 2;&#10;    ctx.save();&#10;    ctx.fillStyle = 'rgba(0,0,0,0.15)'; ctx.beginPath(); ctx.ellipse(cx, y + 2, w * 0.62, 5, 0, 0, Math.PI * 2); ctx.fill();&#10;    const g = ctx.createLinearGradient(x, y - h, x + w, y); g.addColorStop(0, 'rgba(200,240,250,0.95)'); g.addColorStop(1, 'rgba(110,190,215,0.9)');&#10;    ctx.fillStyle = g; ctx.strokeStyle = '#3f4550'; ctx.lineWidth = 3; ctx.fillRect(x, y - h, w, h); ctx.strokeRect(x, y - h, w, h);&#10;    ctx.lineWidth = 1; ctx.strokeStyle = 'rgba(63,69,80,0.55)';&#10;    for (let k = 1; k &lt; 6; k++) { ctx.beginPath(); ctx.moveTo(x, y - h + k * h \/ 6); ctx.lineTo(x + w, y - h + k * h \/ 6); ctx.stroke(); }&#10;    [1, 2].forEach(k =&gt; { ctx.beginPath(); ctx.moveTo(x + k * w \/ 3, y - h); ctx.lineTo(x + k * w \/ 3, y); ctx.stroke(); });&#10;    ctx.fillStyle = 'rgba(255,255,255,0.3)'; const r = ((t * 0.6) % (w + 40)) - 20;              \/\/ destello en el cristal&#10;    ctx.beginPath(); ctx.moveTo(x + r, y - h); ctx.lineTo(x + r + 10, y - h); ctx.lineTo(x + r - 14, y); ctx.lineTo(x + r - 24, y); ctx.fill();&#10;    ctx.fillStyle = '#26508a'; ctx.strokeStyle = '#3f4550'; ctx.lineWidth = 3;                     \/\/ cubierta fotovoltaica&#10;    ctx.beginPath(); ctx.moveTo(x - 5, y - h); ctx.lineTo(x + w + 5, y - h); ctx.lineTo(x + w - 4, y - h - 9); ctx.lineTo(x + 4, y - h - 9); ctx.closePath(); ctx.fill(); ctx.stroke();&#10;    ctx.beginPath(); ctx.moveTo(cx, y - h - 9); ctx.lineTo(cx, y - h - 20); ctx.stroke();&#10;    ctx.fillStyle = Math.sin(t \/ 15) &gt; 0 ? '#7cffd9' : '#2a7a63'; ctx.beginPath(); ctx.arc(cx, y - h - 21, 2.5, 0, Math.PI * 2); ctx.fill();&#10;    const gy = y - h * 0.56; ctx.fillStyle = `rgba(124,255,217,${0.18 + 0.1 * Math.sin(t \/ 20)})`;   \/\/ halo + engranaje \u2699\ufe0f giratorio&#10;    ctx.beginPath(); ctx.arc(cx, gy, 19, 0, Math.PI * 2); ctx.fill();&#10;    ctx.translate(cx, gy); ctx.rotate(Desgaste.giro(t)); ctx.font = '26px Arial'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.fillStyle = '#000'; ctx.fillText('\u2699\ufe0f', 0, 0); ctx.rotate(-Desgaste.giro(t)); ctx.translate(-cx, -gy);&#10;    ctx.fillStyle = `rgba(124,255,217,${0.5 + 0.3 * Math.sin(t \/ 12)})`; ctx.strokeStyle = '#2a7a63'; ctx.lineWidth = 2;   \/\/ portal de entrada&#10;    ctx.beginPath(); ctx.moveTo(cx - 9, y); ctx.lineTo(cx - 9, y - 14); ctx.arc(cx, y - 14, 9, Math.PI, 0); ctx.lineTo(cx + 9, y); ctx.closePath(); ctx.fill(); ctx.stroke();&#10;    ctx.restore();&#10;}&#10;let enArena = false;&#10;const PERSONAS = [&#10;    { rol: 'La Surfista', temp: { n: 'aventurera', vel: 1.25, ritmo: 1.3, alc: 1.0 }, ic: '\ud83c\udfc4', rasgo: 'vive para las olas', afin: { tranvia: 3.5, patinete: 1.6 }, arena: { grada: 1.5 } },&#10;    { rol: 'La Intelectual', temp: { n: 't\u00edmida', vel: 0.85, ritmo: 0.9, alc: 0.55 }, ic: '\ud83d\udcda', rasgo: 'devora libros y partidas', afin: { biblioteca: 4, teletrabajo: 2, banco: 1.5 }, arena: { ajedrez: 3 } },&#10;    { rol: 'La Bot\u00e1nica', temp: { n: 'so\u00f1adora', vel: 0.8, ritmo: 0.6, alc: 0.8 }, ic: '\ud83c\udf31', rasgo: 'cuida cada planta del pueblo', afin: { paseo: 1.6, banco: 1.4, mercadillo: 1.5 }, arena: { pasear: 2 } },&#10;    { rol: 'La Deportista', temp: { n: 'combativa', vel: 1.2, ritmo: 1.2, alc: 1.1 }, ic: '\ud83c\udfcb\ufe0f', rasgo: 'no para de entrenar', afin: { gimnasio: 4.5, patinete: 1.5 }, arena: { grada: 2.5 } },&#10;    { rol: 'La Artista', temp: { n: 'extrovertida', vel: 1.05, ritmo: 1.0, alc: 1.6 }, ic: '\ud83c\udfa8', rasgo: 've belleza en todo', afin: { terraza: 2, banco: 1.8, paseo: 1.3 }, arena: { teatro: 3, sastre: 2 } },&#10;    { rol: 'La Chef', temp: { n: 'met\u00f3dica', vel: 1.0, ritmo: 1.1, alc: 0.9 }, ic: '\ud83c\udf73', rasgo: 'siempre con algo al fuego', afin: { mercadillo: 3.5, terraza: 1.6 }, arena: { sastre: 1.5, teatro: 1.5 } },&#10;    { rol: 'La Gamer', temp: { n: 'vaga', vel: 0.7, ritmo: 0.55, alc: 0.8 }, ic: '\ud83c\udfae', rasgo: 'vive entre pantallas y partidas', afin: { teletrabajo: 2.5, banco: 1.3 }, arena: { ajedrez: 2.5, grada: 1.5 } },&#10;    { rol: 'La Exploradora', temp: { n: 'curiosa', vel: 1.1, ritmo: 1.0, alc: 1.3 }, ic: '\ud83e\udded', rasgo: 'siempre quiere ver qu\u00e9 hay m\u00e1s all\u00e1', afin: { paseo: 2.5, patinete: 2.5, tranvia: 1.8 }, arena: { pasear: 3 } }&#10;];&#10;const Personas = { ok: false, aplicar() { habitantes.forEach((h, i) =&gt; { const t = PERSONAS[i].temp; h.velocidad *= t.vel * .7; h.ritmo = t.ritmo; h.alc = t.alc; }); this.ok = true; },   \/\/ el temperamento cambia su velocidad, sus pausas y su alcance social&#10;    peso(h, k) { const p = PERSONAS[habitantes.indexOf(h)]; return (p &amp;&amp; p.afin[k]) || 1; } };   \/\/ la personalidad inclina sus decisiones en el pueblo&#10;const Memoria = (() =&gt; {&#10;    const K = 'chicachica:memoria:v1', KN = 'chicachica:nombres';&#10;    const leer = k =&gt; { try { return localStorage.getItem(k); } catch (e) { return null; } }, guardar = (k, v) =&gt; { try { localStorage.setItem(k, v); } catch (e) {} };&#10;    let datos = Array.from({ length: 8 }, () =&gt; ({})), nombres = Array(8).fill(''), ult = 0, acum = 0, sucio = false, ultG = 0;&#10;    try { const d = JSON.parse(leer(K) || 'null'); if (Array.isArray(d) &amp;&amp; d.length === 8) datos = d.map(o =&gt; o &amp;&amp; typeof o === 'object' ? o : {}); const n = JSON.parse(leer(KN) || 'null'); if (Array.isArray(n) &amp;&amp; n.length === 8) nombres = n.map(x =&gt; String(x || '').slice(0, 16)); } catch (e) {}&#10;    const LAB = { huerta: 'huerta', surf: 'surf', playa: 'playa', lectura: 'lectura', pantallas: 'pantallas', gym: 'gimnasio', mercado: 'mercado', cocina: 'cocina', paseo: 'paseos', sentada: 'sentada', descanso: 'descanso', tranvia: 'tranv\u00eda', deporte: 'carreras', estadio: 'estadio', ajedrez: 'ajedrez', teatro: 'teatro', moda: 'moda' };&#10;    const DX = [   \/\/ punto d\u00e9bil \u2190 categor\u00edas de actividad real que lo provocan (t: terapia 0 c\u00e9lulas madre \u00b7 1 ADN \u00b7 2 vacuna \u00b7 3 neuromodulaci\u00f3n)&#10;        { n: 'los hombros', t: 0, c: { surf: 1 }, why: 'hombros cargados por el surf' },&#10;        { n: 'la vista', t: 3, c: { lectura: 1, pantallas: 1, teatro: 1 }, why: 'fatiga visual por leer y mirar pantallas' },&#10;        { n: 'las rodillas', t: 0, c: { gym: 1, deporte: 1, mercado: .6 }, why: 'rodillas cargadas por entrenar y estar de pie' },&#10;        { n: 'la espalda', t: 0, c: { sentada: 1, pantallas: .7, ajedrez: .8, estadio: .5, huerta: .8 }, why: 'espalda cargada por tantas horas sentada' },&#10;        { n: 'la piel', t: 1, c: { playa: 1, huerta: .4 }, why: 'piel castigada por el sol de la playa' },&#10;        { n: 'las defensas', t: 2, c: { tranvia: 1, mercado: .4, estadio: .4 }, why: 'defensas bajas por tanto trato con la gente' },&#10;        { n: 'la mente', t: 3, c: { ajedrez: 1, moda: .3, cocina: .2 }, why: 'mente saturada de tanta concentraci\u00f3n' }&#10;    ];&#10;    function sumar(i, cat, s) { if (i == null || !cat || !datos[i]) return; datos[i][cat] = (datos[i][cat] || 0) + s; sucio = true; }&#10;    function categoria(h) {   \/\/ qu\u00e9 est\u00e1 haciendo de verdad ahora mismo, seg\u00fan su estado en el pueblo&#10;        if (h.enPlaya) return h.playaEstado === 'surfeando' || h.playaEstado === 'windsurf' ? 'surf' : 'playa';&#10;        if (h.oculta) return h.lugar === 'biblioteca' ? 'lectura' : h.lugar === 'gimnasio' ? 'gym' : h.lugar === 'huerta' ? 'huerta' : h.lugar === 'tranvia' ? 'tranvia' : h.lugar === 'casa' ? (h.durmiendo ? 'descanso' : h.cocinando ? 'cocina' : 'pantallas') : null;&#10;        if (h.durmiendo) return 'descanso';&#10;        const e = h.estado;&#10;        return e === 'leyendo' ? 'lectura' : e === 'sentada' ? 'sentada' : (e === 'mercadillo' || e === 'mercadillo_esperando' || e === 'frutas' || e === 'frutas_esperando') ? 'mercado' : e === 'esperando_tranvia' ? 'tranvia' : (e === 'caminando' || e === 'parada' || e === 'social' || e === 'asamblea') ? 'paseo' : null;&#10;    }&#10;    function tick(now) {&#10;        if (!Personas.ok) Personas.aplicar();&#10;        if (!ult) ult = now; acum += Math.min(2, (now - ult) \/ 1000); ult = now;&#10;        if (acum &gt;= 1) { habitantes.forEach((h, i) =&gt; sumar(i, categoria(h), acum)); acum = 0; }&#10;        if (sucio &amp;&amp; now - ultG &gt; 15000) { ultG = now; sucio = false; guardar(K, JSON.stringify(datos.map(o =&gt; Object.fromEntries(Object.entries(o).map(([k, v]) =&gt; [k, Math.round(v)]))))); }&#10;    }&#10;    function diagnostico(i) {   \/\/ estrictamente a partir de su historial real&#10;        const d = datos[i] || {}, tot = Object.values(d).reduce((a, b) =&gt; a + b, 0), g = k =&gt; d[k] || 0;&#10;        if (tot &lt; 60) return { n: 'chequeo general', why: 'todav\u00eda sin historial suficiente', t: 2, cats: [] };&#10;        const cand = DX.map(x =&gt; ({ x, s: Object.entries(x.c).reduce((a, [k, w]) =&gt; a + g(k) * w, 0) }));&#10;        if (tot &gt; 300 &amp;&amp; g('descanso') \/ tot &lt; .04) cand.push({ x: { n: 'el sue\u00f1o', t: 3, c: { descanso: 1 }, why: 'casi sin descanso \u00faltimamente' }, s: tot * .45 });&#10;        if ((g('sentada') + g('pantallas') + g('lectura') + g('ajedrez')) \/ tot &gt; .45 &amp;&amp; (g('gym') + g('deporte') + g('surf')) \/ tot &lt; .08) cand.push({ x: { n: 'el metabolismo', t: 1, c: { sentada: 1, pantallas: 1, lectura: 1, ajedrez: 1 }, why: 'mucho sedentarismo y poco ejercicio' }, s: tot * .4 });&#10;        cand.sort((a, b) =&gt; b.s - a.s); const m = cand[0];&#10;        return m &amp;&amp; m.s &gt; 0 ? { n: m.x.n, why: m.x.why, t: m.x.t, cats: Object.keys(m.x.c) } : { n: 'chequeo general', why: 'solo una revisi\u00f3n', t: 2, cats: [] };&#10;    }&#10;    const sanar = (i, cats) =&gt; { const d = datos[i]; if (!d) return; cats.forEach(k =&gt; { if (d[k]) d[k] *= .3; }); sucio = true; };   \/\/ tras el tratamiento, ese desgaste baja&#10;    const resumen = i =&gt; { const e = Object.entries(datos[i] || {}).filter(([, v]) =&gt; v &gt;= 30).sort((a, b) =&gt; b[1] - a[1]).slice(0, 3); return e.length ? e.map(([k, v]) =&gt; (LAB[k] || k) + ' ' + Math.max(1, Math.round(v \/ 60)) + ' min').join(' \u00b7 ') : 'a\u00fan sin historial'; };&#10;    const nombre = i =&gt; nombres[i] || PERSONAS[i].rol, propio = i =&gt; nombres[i], ponerNombre = (i, s) =&gt; { nombres[i] = String(s || '').trim().slice(0, 16); guardar(KN, JSON.stringify(nombres)); };&#10;    return { tick, sumar, diagnostico, sanar, resumen, nombre, propio, ponerNombre, cat: categoria };&#10;})();&#10;const Fichas = (() =&gt; {   \/\/ fichas privadas: el nombre se guarda solo en este dispositivo y solo se usa en el hospital&#10;    const el = document.createElement('div'); el.id = 'fichas'; el.hidden = true;&#10;    el.innerHTML = '&lt;div class=&quot;fi-caja&quot;&gt;&lt;div class=&quot;fi-tit&quot;&gt;&lt;span&gt;\ud83d\udccb Fichas de las 8 chicas&lt;\/span&gt;&lt;button type=&quot;button&quot; id=&quot;fiCerrar&quot; aria-label=&quot;Cerrar&quot;&gt;\u2715&lt;\/button&gt;&lt;\/div&gt;&lt;div class=&quot;fi-sub&quot;&gt;Bautiza o apadrina a cada una con el nombre que quieras. Se guarda solo en este dispositivo y solo se usa en los diagn\u00f3sticos del hospital.&lt;\/div&gt;&lt;div id=&quot;fiLista&quot;&gt;&lt;\/div&gt;&lt;\/div&gt;';&#10;    document.body.appendChild(el);&#10;    const lista = el.querySelector('#fiLista');&#10;    function pintar() {&#10;        lista.innerHTML = '';&#10;        PERSONAS.forEach((p, i) =&gt; {&#10;            const f = document.createElement('div'); f.className = 'fi-fila';&#10;            f.innerHTML = `&lt;span class=&quot;fi-ic&quot; style=&quot;border-color:${habitantes[i].colorPelo}&quot;&gt;${p.ic}&lt;\/span&gt;&lt;div class=&quot;fi-tx&quot;&gt;&lt;b&gt;${p.rol}&lt;\/b&gt;&lt;small&gt;car\u00e1cter: ${p.temp.n} \u00b7 ${Memoria.resumen(i)}&lt;\/small&gt;&lt;\/div&gt;&lt;input type=&quot;text&quot; maxlength=&quot;16&quot; placeholder=&quot;Ponle un nombre&quot; autocomplete=&quot;off&quot;&gt;`;&#10;            const inp = f.querySelector('input'); inp.value = Memoria.propio(i) || ''; inp.placeholder = Idioma.tr('Ponle un nombre'); inp.addEventListener('input', () =&gt; Memoria.ponerNombre(i, inp.value)); lista.appendChild(f);&#10;        });&#10;    }&#10;    el.querySelector('#fiCerrar').addEventListener('click', () =&gt; { el.hidden = true; });&#10;    return { abrir() { pintar(); Idioma.aplicar(); el.hidden = false; }, cerrar() { el.hidden = true; } };&#10;})();&#10;const HuertaBot = {   \/\/ la Bot\u00e1nica visita la huerta: los robots siguen llev\u00e1ndola, ella cuida y supervisa&#10;    entrar(h) { h.oculta = true; h.lugar = 'huerta'; h.bib = { fin: Date.now() + 45000 }; return true; },&#10;    dibujar(t) {&#10;        const h = habitantes.find(o =&gt; o.oculta &amp;&amp; o.lugar === 'huerta'); if (!h) return;&#10;        const x = 480 + Math.sin(t \/ 260) * 340, y = 318, dir = Math.cos(t \/ 260) &gt; 0 ? 1 : -1, pausa = Math.abs(Math.sin(t \/ 130)) &lt; .25;&#10;        ctx.save(); ctx.translate(x, y - 28); ctx.scale(1.1, 1.1); dibujarMu\u00f1eca({ x: 0, y: 0, angulo: pausa ? 0 : Math.sin(t \/ 6) * .06 * dir }, h.colorPelo, false, dir &lt; 0, false, h.estilo); ctx.restore();&#10;        if (pausa) mTxt(['\ud83d\udca7', '\u2702\ufe0f', '\ud83c\udf31'][Math.floor(t \/ 130) % 3], x, y - 88, 24, '#000', 'center');&#10;    }&#10;};&#10;const Mar = (() =&gt; {   \/\/ el agua se calcula a partir de lo que ocurre de verdad en el pueblo: luz real del d\u00eda, estaci\u00f3n, surf, basura, huerta e industria&#10;    const E = { o2: 6.6, sal: 34, yodo: 60, ch4: .3, sis: .1, org: .15, sol: 0, calor: 0, surf: 0, riego: 0, prod: 0 }; let ult = 0;&#10;    const lim = (v, a, b) =&gt; Math.max(a, Math.min(b, v)), mez = (a, b, k) =&gt; a + (b - a) * k;&#10;    function tick(now) {&#10;        if (now - ult &lt; 1000) return; const dt = Math.min(5, (now - ult) \/ 1000); ult = now;&#10;        const d = new Date(), hh = d.getHours() + d.getMinutes() \/ 60, mes = d.getMonth() + d.getDate() \/ 31;&#10;        const sol = Math.max(0, Math.sin(Math.PI * (hh - 6.5) \/ 11.5)), est = .75 + .25 * Math.cos(2 * Math.PI * (mes - 6.5) \/ 12), calor = lim((14 + 14 * sol * est - 18) \/ 12, 0, 1), evap = sol * est * (.4 + .6 * calor);&#10;        const FO = Puerto.FONDO, algas = FO.s \/ 100, suc = FO.b \/ 8, surf = habitantes.filter(x =&gt; x.enPlaya &amp;&amp; (x.playaEstado === 'surfeando' || x.playaEstado === 'windsurf')).length;&#10;        const riego = lim(huertaSiembra.filter(p =&gt; progresoSiembra(p) &lt; 1).length \/ 8, 0, 1), prod = Industria.actividad(), k = Math.min(1, dt * .15);&#10;        E.org = lim(E.org + dt * (.0012 * FO.b * (1 + calor) + .0002 - .0003), 0, 1.2);   \/\/ restos org\u00e1nicos en las rocas: crecen con la basura y el calor&#10;        E.o2 = mez(E.o2, lim(6.2 + 2 * algas * sol - .9 * (1 - sol) * algas + .35 * Math.min(3, surf) - 1.8 * calor - 1.1 * suc, 3, 9.5), k);   \/\/ fotos\u00edntesis de d\u00eda, agitaci\u00f3n al surfear; baja con calor y suciedad&#10;        E.sal = mez(E.sal, 33.6 + 2.8 * evap - 1.8 * riego, k);   \/\/ sube con la evaporaci\u00f3n solar y baja con el riego de La Huerta&#10;        E.yodo = mez(E.yodo, 35 + 50 * algas * (.7 + .3 * (1 - suc)), k);   \/\/ ligado a la densidad de algas y fauna viva&#10;        E.ch4 = mez(E.ch4, .3 + 2.6 * Math.max(0, E.org - .2) * (1 + .5 * calor), k * 2);   \/\/ sube con los restos org\u00e1nicos hasta que los robots los absorben&#10;        E.sis = mez(E.sis, .08 + 1.6 * Math.pow(prod, 1.5), k * 2);   \/\/ micro-vibraciones de la Zona Industrial&#10;        Object.assign(E, { sol, calor, surf, riego, prod });&#10;    }&#10;    return { tick, get: () =&gt; E, absorber: a =&gt; { E.org = lim(E.org - a, 0, 1.2); }, gas: () =&gt; lim((E.ch4 - 1) \/ 1.6, 0, 1), sis: () =&gt; lim((E.sis - .9) \/ 1, 0, 1) };&#10;})();&#10;const Idioma = (() =&gt; {   \/\/ selector de idioma: diccionario de textos clave, recordado en este dispositivo (Smart TV incluida)&#10;    const LANGS = [['es', 'ES', 'Espa\u00f1ol'], ['eu', 'EU', 'Euskara'], ['ca', 'CA', 'Catal\u00e0'], ['gl', 'GL', 'Galego'], ['en', 'EN', 'English'], ['fr', 'FR', 'Fran\u00e7ais'], ['de', 'DE', 'Deutsch'], ['it', 'IT', 'Italiano'], ['ru', 'RU', '\u0420\u0443\u0441\u0441\u043a\u0438\u0439'], ['zh', 'ZH', '\u4e2d\u6587'], ['af', 'AF', 'Afrikaans'], ['ar', 'AR', '\u0627\u0644\u0639\u0631\u0628\u064a\u0629'], ['calo', 'CAL\u00d3', 'Castellano con toque cal\u00f3']];&#10;    const FILAS = `El Pueblo de ChicaChica|ChicaChicako Herria|El Poble de ChicaChica|O Pobo de ChicaChica|The Town of ChicaChica|Le Village de ChicaChica|Das Dorf ChicaChica|Il Paese di ChicaChica|\u0414\u0435\u0440\u0435\u0432\u043d\u044f \u0427\u0438\u043a\u0430\u0427\u0438\u043a\u0430|\u5947\u5361\u5947\u5361\u5c0f\u9547|Die Dorp ChicaChica|\u0642\u0631\u064a\u0629 \u062a\u0634\u064a\u0643\u0627\u062a\u0634\u064a\u0643\u0627|El Gao de ChicaChica&#10;Pueblo|Herria|Poble|Pobo|Town|Village|Dorf|Paese|\u0414\u0435\u0440\u0435\u0432\u043d\u044f|\u5c0f\u9547|Dorp|\u0627\u0644\u0642\u0631\u064a\u0629|Gao&#10;Playa|Hondartza|Platja|Praia|Beach|Plage|Strand|Spiaggia|\u041f\u043b\u044f\u0436|\u6d77\u6ee9|Strand|\u0627\u0644\u0634\u0627\u0637\u0626|&#10;La Huerta|Baratza|L'Horta|A Horta|The Garden|Le Potager|Der Gem\u00fcsegarten|L'Orto|\u041e\u0433\u043e\u0440\u043e\u0434|\u83dc\u56ed|Die Tuin|\u0627\u0644\u0628\u0633\u062a\u0627\u0646|&#10;Mercado|Azoka|Mercat|Mercado|Market|March\u00e9|Markt|Mercato|\u0420\u044b\u043d\u043e\u043a|\u5e02\u573a|Mark|\u0627\u0644\u0633\u0648\u0642|&#10;Industrial|Industria|Industrial|Industrial|Industrial|Industriel|Industrie|Industriale|\u0417\u0430\u0432\u043e\u0434|\u5de5\u4e1a\u533a|Nywerheid|\u0627\u0644\u0635\u0646\u0627\u0639\u0629|&#10;Arena|Arena|Arena|Arena|Arena|Ar\u00e8ne|Arena|Arena|\u0410\u0440\u0435\u043d\u0430|\u7ade\u6280\u573a|Arena|\u0627\u0644\u0633\u0627\u062d\u0629|&#10;Hospital|Ospitalea|Hospital|Hospital|Hospital|H\u00f4pital|Krankenhaus|Ospedale|\u0411\u043e\u043b\u044c\u043d\u0438\u0446\u0430|\u533b\u9662|Hospitaal|\u0627\u0644\u0645\u0633\u062a\u0634\u0641\u0649|&#10;Postal|Postala|Postal|Postal|Postcard|Carte postale|Postkarte|Cartolina|\u041e\u0442\u043a\u0440\u044b\u0442\u043a\u0430|\u660e\u4fe1\u7247|Poskaart|\u0628\u0637\u0627\u0642\u0629 \u0628\u0631\u064a\u062f\u064a\u0629|&#10;Texto grande|Testu handia|Text gran|Texto grande|Large text|Grand texte|Gro\u00dfer Text|Testo grande|\u041a\u0440\u0443\u043f\u043d\u044b\u0439 \u0442\u0435\u043a\u0441\u0442|\u5927\u5b57|Groot teks|\u0646\u0635 \u0643\u0628\u064a\u0631|&#10;Ayuda|Laguntza|Ajuda|Axuda|Help|Aide|Hilfe|Aiuto|\u041f\u043e\u043c\u043e\u0449\u044c|\u5e2e\u52a9|Hulp|\u0645\u0633\u0627\u0639\u062f\u0629|&#10;sin fiesta hoy|gaur ez dago jairik|avui sense festa|hoxe sen festa|no party today|pas de f\u00eate aujourd'hui|heute kein Fest|oggi nessuna festa|\u0441\u0435\u0433\u043e\u0434\u043d\u044f \u043d\u0435\u0442 \u043f\u0440\u0430\u0437\u0434\u043d\u0438\u043a\u0430|\u4eca\u5929\u6ca1\u6709\u8282\u65e5|vandag geen fees|\u0644\u0627 \u0627\u062d\u062a\u0641\u0627\u0644 \u0627\u0644\u064a\u0648\u0645|&#10;Entrar con m\u00fasica|Sartu musikarekin|Entrar amb m\u00fasica|Entrar con m\u00fasica|Enter with music|Entrer avec musique|Mit Musik starten|Entra con musica|\u0412\u043e\u0439\u0442\u0438 \u0441 \u043c\u0443\u0437\u044b\u043a\u043e\u0439|\u5e26\u97f3\u4e50\u8fdb\u5165|Gaan in met musiek|\u0627\u0644\u062f\u062e\u0648\u0644 \u0645\u0639 \u0627\u0644\u0645\u0648\u0633\u064a\u0642\u0649|&#10;Entrar sin sonido|Sartu soinurik gabe|Entrar sense so|Entrar sen son|Enter without sound|Entrer sans son|Ohne Ton starten|Entra senza suono|\u0412\u043e\u0439\u0442\u0438 \u0431\u0435\u0437 \u0437\u0432\u0443\u043a\u0430|\u9759\u97f3\u8fdb\u5165|Gaan in sonder klank|\u0627\u0644\u062f\u062e\u0648\u0644 \u0628\u062f\u0648\u0646 \u0635\u0648\u062a|&#10;\u00a1Todo listo!|Dena prest!|Tot a punt!|Todo listo!|All ready!|Tout est pr\u00eat !|Alles bereit!|Tutto pronto!|\u0412\u0441\u0451 \u0433\u043e\u0442\u043e\u0432\u043e!|\u4e00\u5207\u5c31\u7eea\uff01|Alles gereed!|\u0643\u0644 \u0634\u064a\u0621 \u062c\u0627\u0647\u0632!|&#10;Salir de Smart TV|Atera Smart TV modutik|Sortir de Smart TV|Sa\u00edr de Smart TV|Exit Smart TV|Quitter Smart TV|Smart-TV beenden|Esci da Smart TV|\u0412\u044b\u0439\u0442\u0438 \u0438\u0437 Smart TV|\u9000\u51fa\u667a\u80fd\u7535\u89c6\u6a21\u5f0f|Verlaat Smart TV|\u0627\u0644\u062e\u0631\u0648\u062c \u0645\u0646 \u0648\u0636\u0639 \u0627\u0644\u062a\u0644\u0641\u0627\u0632|&#10;Flechas: mueven la mano|Geziak: eskua mugitzen dute|Fletxes: mouen la m\u00e0|Frechas: moven a man|Arrows: move the hand|Fl\u00e8ches : d\u00e9placent la main|Pfeile: bewegen die Hand|Frecce: muovono la mano|\u0421\u0442\u0440\u0435\u043b\u043a\u0438: \u0434\u0432\u0438\u0433\u0430\u044e\u0442 \u0440\u0443\u043a\u0443|\u65b9\u5411\u952e\uff1a\u79fb\u52a8\u5c0f\u624b|Pyltjies: beweeg die hand|\u0627\u0644\u0623\u0633\u0647\u0645: \u062a\u062d\u0631\u0643 \u0627\u0644\u064a\u062f|&#10;OK: toca, o agarra y suelta|OK: ukitu, edo heldu eta askatu|OK: toca, o agafa i deixa anar|OK: toca, ou agarra e solta|OK: tap, or grab and drop|OK : touche, ou saisis et l\u00e2che|OK: antippen oder greifen und loslassen|OK: tocca, oppure afferra e rilascia|OK: \u043d\u0430\u0436\u0430\u0442\u044c \u0438\u043b\u0438 \u0432\u0437\u044f\u0442\u044c \u0438 \u043e\u0442\u043f\u0443\u0441\u0442\u0438\u0442\u044c|\u786e\u5b9a\uff1a\u70b9\u51fb\uff0c\u6216\u6293\u53d6\u5e76\u653e\u4e0b|OK: raak, of gryp en los|\u0645\u0648\u0627\u0641\u0642: \u0644\u0645\u0633\u060c \u0623\u0648 \u0625\u0645\u0633\u0627\u0643 \u0648\u0625\u0641\u0644\u0627\u062a|&#10;CH+ \/ CH\u2212: cambian de escena|CH+ \/ CH\u2212: eszena aldatzen dute|CH+ \/ CH\u2212: canvien d'escena|CH+ \/ CH\u2212: cambian de escena|CH+ \/ CH\u2212: change scene|CH+ \/ CH\u2212 : changent de sc\u00e8ne|CH+ \/ CH\u2212: Szene wechseln|CH+ \/ CH\u2212: cambiano scena|CH+ \/ CH\u2212: \u0441\u043c\u0435\u043d\u0430 \u0441\u0446\u0435\u043d\u044b|CH+ \/ CH\u2212\uff1a\u5207\u6362\u573a\u666f|CH+ \/ CH\u2212: wissel toneel|CH+ \/ CH\u2212: \u062a\u063a\u064a\u064a\u0631 \u0627\u0644\u0645\u0634\u0647\u062f|&#10;\u2192 Distrito Cultural|\u2192 Kultur Auzoa|\u2192 Districte Cultural|\u2192 Distrito Cultural|\u2192 Cultural District|\u2192 Quartier culturel|\u2192 Kulturviertel|\u2192 Distretto Culturale|\u2192 \u041a\u0443\u043b\u044c\u0442\u0443\u0440\u043d\u044b\u0439 \u0440\u0430\u0439\u043e\u043d|\u2192 \u6587\u5316\u533a|\u2192 Kultuurdistrik|\u2192 \u0627\u0644\u062d\u064a \u0627\u0644\u062b\u0642\u0627\u0641\u064a|&#10;\u2192 Hospital|\u2192 Ospitalea|\u2192 Hospital|\u2192 Hospital|\u2192 Hospital|\u2192 H\u00f4pital|\u2192 Krankenhaus|\u2192 Ospedale|\u2192 \u0411\u043e\u043b\u044c\u043d\u0438\u0446\u0430|\u2192 \u533b\u9662|\u2192 Hospitaal|\u2192 \u0627\u0644\u0645\u0633\u062a\u0634\u0641\u0649|&#10;cient\u00edfico|zientifikoa|cient\u00edfic|cient\u00edfico|scientific|scientifique|wissenschaftlich|scientifico|\u043d\u0430\u0443\u0447\u043d\u0430\u044f|\u79d1\u5b66|wetenskaplik|\u0627\u0644\u0639\u0644\u0645\u064a|&#10;HOSPITAL OSASU \u00b7 MEDICINA DEL FUTURO|OSASU OSPITALEA \u00b7 BIHARKO MEDIKUNTZA|HOSPITAL OSASU \u00b7 MEDICINA DEL FUTUR|HOSPITAL OSASU \u00b7 MEDICINA DO FUTURO|OSASU HOSPITAL \u00b7 MEDICINE OF THE FUTURE|H\u00d4PITAL OSASU \u00b7 M\u00c9DECINE DU FUTUR|OSASU KRANKENHAUS \u00b7 MEDIZIN DER ZUKUNFT|OSPEDALE OSASU \u00b7 MEDICINA DEL FUTURO|\u0411\u041e\u041b\u042c\u041d\u0418\u0426\u0410 \u041e\u0421\u0410\u0421\u0423 \u00b7 \u041c\u0415\u0414\u0418\u0426\u0418\u041d\u0410 \u0411\u0423\u0414\u0423\u0429\u0415\u0413\u041e|OSASU\u533b\u9662 \u00b7 \u672a\u6765\u533b\u5b66|OSASU HOSPITAAL \u00b7 GENEESKUNDE VAN DIE TOEKOMS|\u0645\u0633\u062a\u0634\u0641\u0649 \u0623\u0648\u0633\u0627\u0633\u0648 \u00b7 \u0637\u0628 \u0627\u0644\u0645\u0633\u062a\u0642\u0628\u0644|&#10;Recepci\u00f3n y diagn\u00f3stico|Harrera eta diagnostikoa|Recepci\u00f3 i diagn\u00f2stic|Recepci\u00f3n e diagn\u00f3stico|Reception and diagnosis|Accueil et diagnostic|Empfang und Diagnose|Accoglienza e diagnosi|\u041f\u0440\u0438\u0451\u043c \u0438 \u0434\u0438\u0430\u0433\u043d\u043e\u0441\u0442\u0438\u043a\u0430|\u63a5\u5f85\u4e0e\u8bca\u65ad|Ontvangs en diagnose|\u0627\u0644\u0627\u0633\u062a\u0642\u0628\u0627\u0644 \u0648\u0627\u0644\u062a\u0634\u062e\u064a\u0635|&#10;C\u00e1psula de terapias|Terapia kapsula|C\u00e0psula de ter\u00e0pies|C\u00e1psula de terapias|Therapy capsule|Capsule de th\u00e9rapies|Therapiekapsel|Capsula delle terapie|\u041a\u0430\u043f\u0441\u0443\u043b\u0430 \u0442\u0435\u0440\u0430\u043f\u0438\u0439|\u6cbb\u7597\u8231|Terapiekapsule|\u0643\u0628\u0633\u0648\u0644\u0629 \u0627\u0644\u0639\u0644\u0627\u062c\u0627\u062a|&#10;Laboratorio de terapias|Terapia laborategia|Laboratori de ter\u00e0pies|Laboratorio de terapias|Therapy laboratory|Laboratoire de th\u00e9rapies|Therapielabor|Laboratorio delle terapie|\u041b\u0430\u0431\u043e\u0440\u0430\u0442\u043e\u0440\u0438\u044f \u0442\u0435\u0440\u0430\u043f\u0438\u0439|\u6cbb\u7597\u5b9e\u9a8c\u5ba4|Terapielaboratorium|\u0645\u062e\u062a\u0628\u0631 \u0627\u0644\u0639\u0644\u0627\u062c\u0627\u062a|&#10;Sala de recuperaci\u00f3n|Errekuperazio gela|Sala de recuperaci\u00f3|Sala de recuperaci\u00f3n|Recovery room|Salle de r\u00e9cup\u00e9ration|Erholungsraum|Sala di recupero|\u041f\u0430\u043b\u0430\u0442\u0430 \u0432\u043e\u0441\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f|\u5eb7\u590d\u5ba4|Herstelkamer|\u063a\u0631\u0641\u0629 \u0627\u0644\u062a\u0639\u0627\u0641\u064a|&#10;C\u00e1psula libre|Kapsula libre|C\u00e0psula lliure|C\u00e1psula libre|Capsule free|Capsule libre|Kapsel frei|Capsula libera|\u041a\u0430\u043f\u0441\u0443\u043b\u0430 \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u0430|\u6cbb\u7597\u8231\u7a7a\u95f2|Kapsule vry|\u0627\u0644\u0643\u0628\u0633\u0648\u0644\u0629 \u0641\u0627\u0631\u063a\u0629|&#10;Lista para recibir|Hartzeko prest|Llesta per rebre|Lista para recibir|Ready to receive|Pr\u00eate \u00e0 accueillir|Bereit zum Empfang|Pronta ad accogliere|\u0413\u043e\u0442\u043e\u0432\u043e \u043a \u043f\u0440\u0438\u0451\u043c\u0443|\u51c6\u5907\u63a5\u5f85|Gereed om te ontvang|\u062c\u0627\u0647\u0632\u0629 \u0644\u0644\u0627\u0633\u062a\u0642\u0628\u0627\u0644|&#10;Diagn\u00f3stico para|Diagnostikoa:|Diagn\u00f2stic per a|Diagn\u00f3stico para|Diagnosis for|Diagnostic pour|Diagnose f\u00fcr|Diagnosi per|\u0414\u0438\u0430\u0433\u043d\u043e\u0437 \u0434\u043b\u044f|\u8bca\u65ad\u5bf9\u8c61\uff1a|Diagnose vir|\u062a\u0634\u062e\u064a\u0635 \u0644\u0640|&#10;Sincronizando wearables|Wearableak sinkronizatzen|Sincronitzant wearables|Sincronizando wearables|Syncing wearables|Synchronisation des wearables|Wearables werden synchronisiert|Sincronizzazione dei wearable|\u0421\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u043e\u0441\u0438\u043c\u044b\u0445 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432|\u540c\u6b65\u53ef\u7a7f\u6234\u8bbe\u5907|Sinchroniseer draagbare toestelle|\u0645\u0632\u0627\u0645\u0646\u0629 \u0627\u0644\u0623\u062c\u0647\u0632\u0629 \u0627\u0644\u0642\u0627\u0628\u0644\u0629 \u0644\u0644\u0627\u0631\u062a\u062f\u0627\u0621|&#10;Colocando diadema neuronal y pulsera inteligente|Diadema neuronala eta eskumuturreko adimenduna jartzen|Col\u00b7locant diadema neuronal i polsera intel\u00b7ligent|Colocando diadema neuronal e pulseira intelixente|Fitting neural headband and smart bracelet|Pose du bandeau neuronal et du bracelet intelligent|Neuro-Stirnband und Smart-Armband werden angelegt|Applicazione di fascia neurale e braccialetto smart|\u041d\u0430\u0434\u0435\u0432\u0430\u0435\u043c \u043d\u0435\u0439\u0440\u043e\u043f\u043e\u0432\u044f\u0437\u043a\u0443 \u0438 \u0443\u043c\u043d\u044b\u0439 \u0431\u0440\u0430\u0441\u043b\u0435\u0442|\u6b63\u5728\u4f69\u6234\u795e\u7ecf\u5934\u5e26\u548c\u667a\u80fd\u624b\u73af|Neurale hoofband en slim armband word aangesit|\u0648\u0636\u0639 \u0639\u0635\u0627\u0628\u0629 \u0627\u0644\u0631\u0623\u0633 \u0627\u0644\u0639\u0635\u0628\u064a\u0629 \u0648\u0627\u0644\u0633\u0648\u0627\u0631 \u0627\u0644\u0630\u0643\u064a|&#10;Diadema neuronal y pulsera inteligente, sin prisas|Diadema neuronala eta eskumuturreko adimenduna, presarik gabe|Diadema neuronal i polsera intel\u00b7ligent, sense pressa|Diadema neuronal e pulseira intelixente, sen pr\u00e9sa|Neural headband and smart bracelet, no rush|Bandeau neuronal et bracelet intelligent, sans se presser|Neuro-Stirnband und Smart-Armband, ganz ohne Eile|Fascia neurale e braccialetto smart, senza fretta|\u041d\u0435\u0439\u0440\u043e\u043f\u043e\u0432\u044f\u0437\u043a\u0430 \u0438 \u0443\u043c\u043d\u044b\u0439 \u0431\u0440\u0430\u0441\u043b\u0435\u0442, \u0431\u0435\u0437 \u0441\u043f\u0435\u0448\u043a\u0438|\u795e\u7ecf\u5934\u5e26\u4e0e\u667a\u80fd\u624b\u73af\uff0c\u4e0d\u7528\u7740\u6025|Neurale hoofband en slim armband, sonder haas|\u0639\u0635\u0627\u0628\u0629 \u0631\u0623\u0633 \u0639\u0635\u0628\u064a\u0629 \u0648\u0633\u0648\u0627\u0631 \u0630\u0643\u064a\u060c \u062f\u0648\u0646 \u0639\u062c\u0644\u0629|&#10;Preparando|Prestatzen|Preparant|Preparando|Preparing|Pr\u00e9paration|Vorbereitung|Preparazione|\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430|\u51c6\u5907\u4e2d|Berei voor|\u062a\u062d\u0636\u064a\u0631|&#10;descansando|atseden hartzen|descansant|descansando|resting|se reposent|ruhen sich aus|riposano|\u043e\u0442\u0434\u044b\u0445\u0430\u044e\u0442|\u6b63\u5728\u4f11\u606f|rus|\u064a\u0631\u062a\u062d\u0646|&#10;ya como nuevas|jada berri-berri|ja com a noves|xa como novas|already like new|comme neuves|schon wie neu|gi\u00e0 come nuove|\u043a\u0430\u043a \u043d\u043e\u0432\u0435\u043d\u044c\u043a\u0438\u0435|\u7115\u7136\u4e00\u65b0|reeds soos nuut|\u0643\u0623\u0646\u0647\u0646 \u062c\u062f\u064a\u062f\u0627\u062a|&#10;Un sitio tranquilo para descansar|Atseden hartzeko toki lasaia|Un lloc tranquil per descansar|Un sitio tranquilo para descansar|A quiet place to rest|Un endroit calme pour se reposer|Ein ruhiger Ort zum Ausruhen|Un posto tranquillo per riposare|\u0422\u0438\u0445\u043e\u0435 \u043c\u0435\u0441\u0442\u043e \u0434\u043b\u044f \u043e\u0442\u0434\u044b\u0445\u0430|\u5b89\u9759\u7684\u4f11\u606f\u4e4b\u5904|'n Rustige plek om te rus|\u0645\u0643\u0627\u0646 \u0647\u0627\u062f\u0626 \u0644\u0644\u0631\u0627\u062d\u0629|&#10;cuerpo \u00b7 mente \u00b7 constantes|gorputza \u00b7 burua \u00b7 konstanteak|cos \u00b7 ment \u00b7 constants|corpo \u00b7 mente \u00b7 constantes|body \u00b7 mind \u00b7 vitals|corps \u00b7 esprit \u00b7 constantes|K\u00f6rper \u00b7 Geist \u00b7 Vitalwerte|corpo \u00b7 mente \u00b7 parametri|\u0442\u0435\u043b\u043e \u00b7 \u0440\u0430\u0437\u0443\u043c \u00b7 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u0438|\u8eab\u4f53 \u00b7 \u5fc3\u7075 \u00b7 \u4f53\u5f81|liggaam \u00b7 gees \u00b7 lewenstekens|\u0627\u0644\u062c\u0633\u062f \u00b7 \u0627\u0644\u0639\u0642\u0644 \u00b7 \u0627\u0644\u0645\u0624\u0634\u0631\u0627\u062a|&#10;Pulso|Pultsua|Pols|Pulso|Pulse|Pouls|Puls|Polso|\u041f\u0443\u043b\u044c\u0441|\u8109\u640f|Polsslag|\u0627\u0644\u0646\u0628\u0636|&#10;Calma|Lasaitasuna|Calma|Calma|Calm|Calme|Ruhe|Calma|\u041f\u043e\u043a\u043e\u0439|\u5e73\u9759|Kalmte|\u0627\u0644\u0647\u062f\u0648\u0621|&#10;Respira|Arnasa|Respira|Respira|Breath|Souffle|Atmung|Respiro|\u0414\u044b\u0445\u0430\u043d\u0438\u0435|\u547c\u5438|Asem|\u0627\u0644\u062a\u0646\u0641\u0633|&#10;Temp.|Tenp.|Temp.|Temp.|Temp.|Temp.|Temp.|Temp.|\u0422\u0435\u043c\u043f.|\u4f53\u6e29|Temp.|\u0627\u0644\u062d\u0631\u0627\u0631\u0629|&#10;Aplicando vacuna antiviral|Txerto antibiralak aplikatzen|Aplicant vacuna antiviral|Aplicando vacina antiviral|Applying antiviral vaccine|Application du vaccin antiviral|Antivirale Impfung wird verabreicht|Somministrazione del vaccino antivirale|\u0412\u0432\u043e\u0434\u0438\u043c \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u0432\u0438\u0440\u0443\u0441\u043d\u0443\u044e \u0432\u0430\u043a\u0446\u0438\u043d\u0443|\u6b63\u5728\u63a5\u79cd\u6297\u75c5\u6bd2\u75ab\u82d7|Antivirale entstof word toegedien|\u062a\u0637\u0628\u064a\u0642 \u0627\u0644\u0644\u0642\u0627\u062d \u0627\u0644\u0645\u0636\u0627\u062f \u0644\u0644\u0641\u064a\u0631\u0648\u0633\u0627\u062a|&#10;Reequilibrando el ADN|ADNa birdoitzen|Reequilibrant l'ADN|Reequilibrando o ADN|Rebalancing the DNA|R\u00e9\u00e9quilibrage de l'ADN|DNA wird neu ausbalanciert|Riequilibrio del DNA|\u0411\u0430\u043b\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u043a\u0430 \u0414\u041d\u041a|\u91cd\u65b0\u5e73\u8861DNA|Herbalanseer die DNS|\u0625\u0639\u0627\u062f\u0629 \u062a\u0648\u0627\u0632\u0646 \u0627\u0644\u062d\u0645\u0636 \u0627\u0644\u0646\u0648\u0648\u064a|&#10;Neuromodulaci\u00f3n|Neuromodulazioa|Neuromodulaci\u00f3|Neuromodulaci\u00f3n|Neuromodulation|Neuromodulation|Neuromodulation|Neuromodulazione|\u041d\u0435\u0439\u0440\u043e\u043c\u043e\u0434\u0443\u043b\u044f\u0446\u0438\u044f|\u795e\u7ecf\u8c03\u63a7|Neuromodulasie|\u0627\u0644\u062a\u0639\u062f\u064a\u0644 \u0627\u0644\u0639\u0635\u0628\u064a|&#10;Regenerando|Birsortzen|Regenerant|Rexenerando|Regenerating|R\u00e9g\u00e9n\u00e9ration|Regeneration|Rigenerazione|\u0420\u0435\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f|\u6b63\u5728\u518d\u751f|Regenereer|\u062a\u062c\u062f\u064a\u062f|&#10;con c\u00e9lulas madre|zelula amarekin|amb c\u00e8l\u00b7lules mare|con c\u00e9lulas nai|with stem cells|avec des cellules souches|mit Stammzellen|con cellule staminali|\u0441\u0442\u0432\u043e\u043b\u043e\u0432\u044b\u043c\u0438 \u043a\u043b\u0435\u0442\u043a\u0430\u043c\u0438|\u4f7f\u7528\u5e72\u7ec6\u80de|met stamselle|\u0628\u0627\u0644\u062e\u0644\u0627\u064a\u0627 \u0627\u0644\u062c\u0630\u0639\u064a\u0629|&#10;c\u00e9lulas madre regenerativas|zelula ama birsortzaileak|c\u00e8l\u00b7lules mare regeneratives|c\u00e9lulas nai rexenerativas|regenerative stem cells|cellules souches r\u00e9g\u00e9n\u00e9ratives|regenerative Stammzellen|cellule staminali rigenerative|\u0440\u0435\u0433\u0435\u043d\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u0441\u0442\u0432\u043e\u043b\u043e\u0432\u044b\u0435 \u043a\u043b\u0435\u0442\u043a\u0438|\u518d\u751f\u5e72\u7ec6\u80de|regeneratiewe stamselle|\u0627\u0644\u062e\u0644\u0627\u064a\u0627 \u0627\u0644\u062c\u0630\u0639\u064a\u0629 \u0627\u0644\u062a\u062c\u062f\u064a\u062f\u064a\u0629|&#10;terapia gen\u00f3mica de ADN|ADN terapia genomikoa|ter\u00e0pia gen\u00f2mica d'ADN|terapia xen\u00f3mica de ADN|genomic DNA therapy|th\u00e9rapie g\u00e9nomique de l'ADN|genomische DNA-Therapie|terapia genomica del DNA|\u0433\u0435\u043d\u043e\u043c\u043d\u0430\u044f \u0442\u0435\u0440\u0430\u043f\u0438\u044f \u0414\u041d\u041a|\u57fa\u56e0\u7ec4DNA\u7597\u6cd5|genomiese DNS-terapie|\u0627\u0644\u0639\u0644\u0627\u062c \u0627\u0644\u062c\u064a\u0646\u064a \u0644\u0644\u062d\u0645\u0636 \u0627\u0644\u0646\u0648\u0648\u064a|&#10;vacuna antiviral (micro-dosis)|txerto antibirala (mikrodosia)|vacuna antiviral (microdosi)|vacina antiviral (microdose)|antiviral vaccine (micro-dose)|vaccin antiviral (micro-dose)|antivirale Impfung (Mikrodosis)|vaccino antivirale (microdose)|\u043f\u0440\u043e\u0442\u0438\u0432\u043e\u0432\u0438\u0440\u0443\u0441\u043d\u0430\u044f \u0432\u0430\u043a\u0446\u0438\u043d\u0430 (\u043c\u0438\u043a\u0440\u043e\u0434\u043e\u0437\u0430)|\u6297\u75c5\u6bd2\u75ab\u82d7\uff08\u5fae\u5242\u91cf\uff09|antivirale entstof (mikrodosis)|\u0644\u0642\u0627\u062d \u0645\u0636\u0627\u062f \u0644\u0644\u0641\u064a\u0631\u0648\u0633\u0627\u062a (\u062c\u0631\u0639\u0629 \u062f\u0642\u064a\u0642\u0629)|&#10;neuromodulaci\u00f3n|neuromodulazioa|neuromodulaci\u00f3|neuromodulaci\u00f3n|neuromodulation|neuromodulation|Neuromodulation|neuromodulazione|\u043d\u0435\u0439\u0440\u043e\u043c\u043e\u0434\u0443\u043b\u044f\u0446\u0438\u044f|\u795e\u7ecf\u8c03\u63a7|neuromodulasie|\u0627\u0644\u062a\u0639\u062f\u064a\u0644 \u0627\u0644\u0639\u0635\u0628\u064a|&#10;chequeo general|azterketa orokorra|revisi\u00f3 general|revisi\u00f3n xeral|general check-up|bilan g\u00e9n\u00e9ral|allgemeiner Check-up|controllo generale|\u043e\u0431\u0449\u0438\u0439 \u043e\u0441\u043c\u043e\u0442\u0440|\u5168\u9762\u68c0\u67e5|algemene ondersoek|\u0641\u062d\u0635 \u0639\u0627\u0645|&#10;todav\u00eda sin historial suficiente|oraindik historial nahikorik gabe|encara sense prou historial|a\u00ednda sen historial suficiente|not enough history yet|pas encore assez d'historique|noch nicht genug Verlauf|ancora poca cronologia|\u0438\u0441\u0442\u043e\u0440\u0438\u0438 \u043f\u043e\u043a\u0430 \u043d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e|\u8bb0\u5f55\u5c1a\u4e0d\u8db3|nog nie genoeg geskiedenis|\u0644\u0627 \u064a\u0648\u062c\u062f \u0633\u062c\u0644 \u0643\u0627\u0641\u064d \u0628\u0639\u062f|&#10;solo una revisi\u00f3n|errebisio bat besterik ez|nom\u00e9s una revisi\u00f3|s\u00f3 unha revisi\u00f3n|just a check-up|un simple contr\u00f4le|nur eine Kontrolle|solo un controllo|\u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0441\u043c\u043e\u0442\u0440|\u53ea\u662f\u4f8b\u884c\u68c0\u67e5|net 'n kontrole|\u0645\u062c\u0631\u062f \u0641\u062d\u0635|&#10;los hombros|sorbaldak|les espatlles|os ombreiros|the shoulders|les \u00e9paules|die Schultern|le spalle|\u043f\u043b\u0435\u0447\u0438|\u80a9\u8180|die skouers|\u0627\u0644\u0643\u062a\u0641\u064a\u0646|&#10;la vista|ikusmena|la vista|a vista|eyesight|la vue|das Sehverm\u00f6gen|la vista|\u0437\u0440\u0435\u043d\u0438\u0435|\u89c6\u529b|die sig|\u0627\u0644\u0628\u0635\u0631|&#10;las rodillas|belaunak|els genolls|os xeonllos|the knees|les genoux|die Knie|le ginocchia|\u043a\u043e\u043b\u0435\u043d\u0438|\u819d\u76d6|die knie\u00eb|\u0627\u0644\u0631\u0643\u0628\u062a\u064a\u0646|&#10;la espalda|bizkarra|l'esquena|a espalda|the back|le dos|der R\u00fccken|la schiena|\u0441\u043f\u0438\u043d\u0443|\u80cc\u90e8|die rug|\u0627\u0644\u0638\u0647\u0631|&#10;la piel|azala|la pell|a pel|the skin|la peau|die Haut|la pelle|\u043a\u043e\u0436\u0443|\u76ae\u80a4|die vel|\u0627\u0644\u062c\u0644\u062f|&#10;las defensas|defentsak|les defenses|as defensas|the defenses|les d\u00e9fenses|die Abwehrkr\u00e4fte|le difese|\u0438\u043c\u043c\u0443\u043d\u0438\u0442\u0435\u0442|\u514d\u75ab\u529b|die weerstand|\u0627\u0644\u062f\u0641\u0627\u0639\u0627\u062a|&#10;la mente|burua|la ment|a mente|the mind|l'esprit|der Geist|la mente|\u0440\u0430\u0437\u0443\u043c|\u5fc3\u667a|die gees|\u0627\u0644\u0639\u0642\u0644|&#10;el sue\u00f1o|loa|el son|o sono|sleep|le sommeil|der Schlaf|il sonno|\u0441\u043e\u043d|\u7761\u7720|die slaap|\u0627\u0644\u0646\u0648\u0645|&#10;el metabolismo|metabolismoa|el metabolisme|o metabolismo|the metabolism|le m\u00e9tabolisme|der Stoffwechsel|il metabolismo|\u043e\u0431\u043c\u0435\u043d \u0432\u0435\u0449\u0435\u0441\u0442\u0432|\u65b0\u9648\u4ee3\u8c22|die metabolisme|\u0627\u0644\u0623\u064a\u0636|&#10;los pulmones|birikak|els pulmons|os pulm\u00f3ns|the lungs|les poumons|die Lunge|i polmoni|\u043b\u0451\u0433\u043a\u0438\u0435|\u80ba\u90e8|die longe|\u0627\u0644\u0631\u0626\u062a\u064a\u0646|&#10;hombros cargados por el surf|surfak zamatutako sorbaldak|espatlles carregades pel surf|ombreiros cargados polo surf|shoulders strained by surfing|\u00e9paules charg\u00e9es par le surf|vom Surfen belastete Schultern|spalle affaticate dal surf|\u043f\u043b\u0435\u0447\u0438 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0436\u0435\u043d\u044b \u0441\u0451\u0440\u0444\u0438\u043d\u0433\u043e\u043c|\u51b2\u6d6a\u9020\u6210\u80a9\u8180\u52b3\u635f|skouers belas deur branderplankry|\u0623\u0643\u062a\u0627\u0641 \u0645\u062c\u0647\u062f\u0629 \u0645\u0646 \u0631\u0643\u0648\u0628 \u0627\u0644\u0623\u0645\u0648\u0627\u062c|&#10;fatiga visual por leer y mirar pantallas|irakurtzeak eta pantailak begiratzeak eragindako nekea|fatiga visual per llegir i mirar pantalles|fatiga visual por ler e mirar pantallas|eye strain from reading and screens|fatigue visuelle due \u00e0 la lecture et aux \u00e9crans|Augenerm\u00fcdung durch Lesen und Bildschirme|affaticamento visivo da lettura e schermi|\u0443\u0441\u0442\u0430\u043b\u043e\u0441\u0442\u044c \u0433\u043b\u0430\u0437 \u043e\u0442 \u0447\u0442\u0435\u043d\u0438\u044f \u0438 \u044d\u043a\u0440\u0430\u043d\u043e\u0432|\u9605\u8bfb\u548c\u770b\u5c4f\u5e55\u5bfc\u81f4\u89c6\u75b2\u52b3|oogvermoeidheid van lees en skerms|\u0625\u062c\u0647\u0627\u062f \u0628\u0635\u0631\u064a \u0645\u0646 \u0627\u0644\u0642\u0631\u0627\u0621\u0629 \u0648\u0627\u0644\u0634\u0627\u0634\u0627\u062a|&#10;rodillas cargadas por entrenar y estar de pie|entrenatzeak eta zutik egoteak zamatutako belaunak|genolls carregats per entrenar i estar dempeus|xeonllos cargados por adestrar e estar de p\u00e9|knees strained by training and standing|genoux fatigu\u00e9s par l'entra\u00eenement et la station debout|Knie belastet durch Training und langes Stehen|ginocchia affaticate da allenamento e stare in piedi|\u043a\u043e\u043b\u0435\u043d\u0438 \u043d\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u044b \u0442\u0440\u0435\u043d\u0438\u0440\u043e\u0432\u043a\u0430\u043c\u0438 \u0438 \u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c|\u8bad\u7ec3\u548c\u4e45\u7ad9\u4f7f\u819d\u76d6\u8d1f\u62c5\u8fc7\u91cd|knie\u00eb belas deur oefen en staan|\u0631\u0643\u0628\u062a\u0627\u0646 \u0645\u062c\u0647\u062f\u062a\u0627\u0646 \u0645\u0646 \u0627\u0644\u062a\u062f\u0631\u064a\u0628 \u0648\u0627\u0644\u0648\u0642\u0648\u0641|&#10;espalda cargada por tantas horas sentada|ordu askotan eserita egoteak zamatutako bizkarra|esquena carregada per tantes hores asseguda|espalda cargada por tantas horas sentada|back strained by so many hours sitting|dos fatigu\u00e9 par tant d'heures assise|R\u00fccken belastet durch stundenlanges Sitzen|schiena affaticata da tante ore seduta|\u0441\u043f\u0438\u043d\u0430 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0436\u0435\u043d\u0430 \u0434\u043e\u043b\u0433\u0438\u043c \u0441\u0438\u0434\u0435\u043d\u0438\u0435\u043c|\u4e45\u5750\u8ba9\u80cc\u90e8\u8d1f\u62c5\u8fc7\u91cd|rug belas deur soveel ure sit|\u0638\u0647\u0631 \u0645\u062c\u0647\u062f \u0645\u0646 \u0633\u0627\u0639\u0627\u062a \u0627\u0644\u062c\u0644\u0648\u0633 \u0627\u0644\u0637\u0648\u064a\u0644\u0629|&#10;piel castigada por el sol de la playa|hondartzako eguzkiak zigortutako azala|pell castigada pel sol de la platja|pel castigada polo sol da praia|skin punished by the beach sun|peau malmen\u00e9e par le soleil de la plage|von der Strandsonne strapazierte Haut|pelle provata dal sole della spiaggia|\u043a\u043e\u0436\u0430 \u043e\u0431\u043e\u0436\u0436\u0435\u043d\u0430 \u043f\u043b\u044f\u0436\u043d\u044b\u043c \u0441\u043e\u043b\u043d\u0446\u0435\u043c|\u6d77\u6ee9\u9633\u5149\u6652\u4f24\u76ae\u80a4|vel gestraf deur die strandson|\u062c\u0644\u062f \u0623\u0631\u0647\u0642\u062a\u0647 \u0634\u0645\u0633 \u0627\u0644\u0634\u0627\u0637\u0626|&#10;defensas bajas por tanto trato con la gente|jende askorekin trato egiteak ahuldutako defentsak|defenses baixes per tant tracte amb la gent|defensas baixas por tanto trato coa xente|low defenses from so much contact with people|d\u00e9fenses basses \u00e0 force de c\u00f4toyer du monde|geschw\u00e4chte Abwehr durch viel Kontakt|difese basse per tanto contatto con la gente|\u0438\u043c\u043c\u0443\u043d\u0438\u0442\u0435\u0442 \u0441\u043d\u0438\u0436\u0435\u043d \u0438\u0437-\u0437\u0430 \u0447\u0430\u0441\u0442\u044b\u0445 \u043a\u043e\u043d\u0442\u0430\u043a\u0442\u043e\u0432|\u4e0e\u4eba\u63a5\u89e6\u592a\u591a\u5bfc\u81f4\u514d\u75ab\u529b\u4e0b\u964d|lae weerstand weens soveel kontak met mense|\u062f\u0641\u0627\u0639\u0627\u062a \u0645\u0646\u062e\u0641\u0636\u0629 \u0645\u0646 \u0643\u062b\u0631\u0629 \u0627\u0644\u0627\u062d\u062a\u0643\u0627\u0643 \u0628\u0627\u0644\u0646\u0627\u0633|&#10;mente saturada de tanta concentraci\u00f3n|kontzentrazio handiak saturatutako burua|ment saturada de tanta concentraci\u00f3|mente saturada de tanta concentraci\u00f3n|mind overloaded by so much focus|esprit satur\u00e9 par tant de concentration|Geist \u00fcberlastet von so viel Konzentration|mente satura di tanta concentrazione|\u0440\u0430\u0437\u0443\u043c \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0436\u0435\u043d \u043a\u043e\u043d\u0446\u0435\u043d\u0442\u0440\u0430\u0446\u0438\u0435\u0439|\u957f\u65f6\u95f4\u4e13\u6ce8\u8ba9\u5927\u8111\u9971\u548c|gees oorlaai deur soveel konsentrasie|\u0639\u0642\u0644 \u0645\u0631\u0647\u0642 \u0645\u0646 \u0643\u062b\u0631\u0629 \u0627\u0644\u062a\u0631\u0643\u064a\u0632|&#10;casi sin descanso \u00faltimamente|azkenaldian ia atsedenik gabe|gaireb\u00e9 sense descans \u00faltimament|case sen descanso ultimamente|almost no rest lately|presque sans repos ces derniers temps|in letzter Zeit kaum Ruhe|quasi senza riposo ultimamente|\u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0447\u0442\u0438 \u0431\u0435\u0437 \u043e\u0442\u0434\u044b\u0445\u0430|\u6700\u8fd1\u51e0\u4e4e\u6ca1\u6709\u4f11\u606f|onlangs amper geen rus|\u0628\u0627\u0644\u0643\u0627\u062f \u062a\u0631\u062a\u0627\u062d \u0645\u0624\u062e\u0631\u064b\u0627|&#10;mucho sedentarismo y poco ejercicio|sedentarismo handia eta ariketa gutxi|molt sedentarisme i poc exercici|moito sedentarismo e pouco exercicio|a lot of sitting and little exercise|beaucoup de s\u00e9dentarit\u00e9 et peu d'exercice|viel Sitzen und wenig Bewegung|molta sedentariet\u00e0 e poco esercizio|\u043c\u043d\u043e\u0433\u043e \u0441\u0438\u0434\u044f\u0447\u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0437\u0430 \u0436\u0438\u0437\u043d\u0438 \u0438 \u043c\u0430\u043b\u043e \u0434\u0432\u0438\u0436\u0435\u043d\u0438\u044f|\u4e45\u5750\u4e0d\u52a8\uff0c\u8fd0\u52a8\u592a\u5c11|baie sit en min oefening|\u062e\u0645\u0648\u0644 \u0643\u062b\u064a\u0631 \u0648\u0631\u064a\u0627\u0636\u0629 \u0642\u0644\u064a\u0644\u0629|&#10;Fichas de las 8 chicas|8 neskatoen fitxak|Fitxes de les 8 noies|Fichas das 8 rapazas|Profiles of the 8 girls|Fiches des 8 filles|Steckbriefe der 8 M\u00e4dchen|Schede delle 8 ragazze|\u041a\u0430\u0440\u0442\u043e\u0447\u043a\u0438 8 \u0434\u0435\u0432\u043e\u0447\u0435\u043a|8\u4f4d\u5973\u5b69\u7684\u6863\u6848|Profiele van die 8 meisies|\u0645\u0644\u0641\u0627\u062a \u0627\u0644\u0641\u062a\u064a\u0627\u062a \u0627\u0644\u062b\u0645\u0627\u0646\u064a|&#10;Bautiza o apadrina a cada una con el nombre que quieras. Se guarda solo en este dispositivo y solo se usa en los diagn\u00f3sticos del hospital.|Ipini izena bakoitzari nahi duzuna. Gailu honetan soilik gordetzen da eta ospitaleko diagnostikoetan bakarrik erabiltzen da.|Bateja o apadrina cada una amb el nom que vulguis. Es guarda nom\u00e9s en aquest dispositiu i nom\u00e9s s'usa als diagn\u00f2stics de l'hospital.|Bautiza ou apadri\u00f1a cada unha co nome que queiras. G\u00e1rdase s\u00f3 neste dispositivo e s\u00f3 se usa nos diagn\u00f3sticos do hospital.|Name or sponsor each girl however you like. It is saved only on this device and used only in hospital diagnoses.|Baptise ou parraine chacune avec le nom de ton choix. Il reste uniquement sur cet appareil et sert seulement aux diagnostics de l'h\u00f4pital.|Gib jedem M\u00e4dchen einen Namen oder werde ihre Patin. Er wird nur auf diesem Ger\u00e4t gespeichert und nur in den Diagnosen des Krankenhauses verwendet.|Dai a ciascuna il nome che vuoi. Viene salvato solo su questo dispositivo e usato solo nelle diagnosi dell'ospedale.|\u0414\u0430\u0439\u0442\u0435 \u043a\u0430\u0436\u0434\u043e\u0439 \u0438\u043c\u044f \u043f\u043e \u0441\u0432\u043e\u0435\u043c\u0443 \u0436\u0435\u043b\u0430\u043d\u0438\u044e. \u041e\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u044d\u0442\u043e\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0434\u0438\u0430\u0433\u043d\u043e\u0437\u0430\u0445 \u0431\u043e\u043b\u044c\u043d\u0438\u0446\u044b.|\u7ed9\u6bcf\u4f4d\u5973\u5b69\u8d77\u4e2a\u4f60\u559c\u6b22\u7684\u540d\u5b57\u3002\u540d\u5b57\u53ea\u4fdd\u5b58\u5728\u6b64\u8bbe\u5907\u4e0a\uff0c\u53ea\u7528\u4e8e\u533b\u9662\u8bca\u65ad\u3002|Gee elke een die naam wat jy wil. Dit word net op hierdie toestel gestoor en net in die hospitaal se diagnoses gebruik.|\u0633\u0645\u0650\u0651 \u0643\u0644 \u0648\u0627\u062d\u062f\u0629 \u0628\u0645\u0627 \u062a\u0634\u0627\u0621. \u064a\u064f\u062d\u0641\u0638 \u0639\u0644\u0649 \u0647\u0630\u0627 \u0627\u0644\u062c\u0647\u0627\u0632 \u0641\u0642\u0637 \u0648\u064a\u064f\u0633\u062a\u062e\u062f\u0645 \u0641\u064a \u062a\u0634\u062e\u064a\u0635\u0627\u062a \u0627\u0644\u0645\u0633\u062a\u0634\u0641\u0649 \u0641\u0642\u0637.|&#10;Ponle un nombre|Jarri izena|Posa-li un nom|Ponlle un nome|Give her a name|Donne-lui un nom|Gib ihr einen Namen|Dalle un nome|\u0414\u0430\u0439\u0442\u0435 \u0438\u043c\u044f|\u8d77\u4e2a\u540d\u5b57|Gee 'n naam|\u0627\u0645\u0646\u062d\u0647\u0627 \u0627\u0633\u0645\u064b\u0627|&#10;a\u00fan sin historial|oraindik historialik gabe|encara sense historial|a\u00ednda sen historial|no history yet|pas encore d'historique|noch kein Verlauf|ancora senza cronologia|\u0438\u0441\u0442\u043e\u0440\u0438\u0438 \u043f\u043e\u043a\u0430 \u043d\u0435\u0442|\u6682\u65e0\u8bb0\u5f55|nog geen geskiedenis|\u0644\u0627 \u0633\u062c\u0644 \u0628\u0639\u062f|&#10;La Surfista|Surflaria|La Surfista|A Surfista|The Surfer|La Surfeuse|Die Surferin|La Surfista|\u0421\u0435\u0440\u0444\u0438\u043d\u0433\u0438\u0441\u0442\u043a\u0430|\u51b2\u6d6a\u8005|Die Branderplankryer|\u0631\u0627\u0643\u0628\u0629 \u0627\u0644\u0623\u0645\u0648\u0627\u062c|&#10;La Intelectual|Intelektuala|La Intel\u00b7lectual|A Intelectual|The Scholar|L'Intellectuelle|Die Intellektuelle|L'Intellettuale|\u0418\u043d\u0442\u0435\u043b\u043b\u0435\u043a\u0442\u0443\u0430\u043b\u043a\u0430|\u77e5\u8bc6\u5206\u5b50|Die Intellektueel|\u0627\u0644\u0645\u062b\u0642\u0641\u0629|&#10;La Bot\u00e1nica|Botanikaria|La Bot\u00e0nica|A Bot\u00e1nica|The Botanist|La Botaniste|Die Botanikerin|La Botanica|\u0411\u043e\u0442\u0430\u043d\u0438\u043a|\u690d\u7269\u5b66\u5bb6|Die Plantkundige|\u0639\u0627\u0644\u0645\u0629 \u0627\u0644\u0646\u0628\u0627\u062a|&#10;La Deportista|Kirolaria|La Esportista|A Deportista|The Athlete|La Sportive|Die Sportlerin|La Sportiva|\u0421\u043f\u043e\u0440\u0442\u0441\u043c\u0435\u043d\u043a\u0430|\u8fd0\u52a8\u5458|Die Atleet|\u0627\u0644\u0631\u064a\u0627\u0636\u064a\u0629|&#10;La Artista|Artista|L'Artista|A Artista|The Artist|L'Artiste|Die K\u00fcnstlerin|L'Artista|\u0425\u0443\u0434\u043e\u0436\u043d\u0438\u0446\u0430|\u827a\u672f\u5bb6|Die Kunstenaar|\u0627\u0644\u0641\u0646\u0627\u0646\u0629|&#10;La Chef|Sukaldaria|La Xef|A Chef|The Chef|La Cheffe|Die K\u00f6chin|La Chef|\u0428\u0435\u0444-\u043f\u043e\u0432\u0430\u0440|\u53a8\u5e08|Die Sjef|\u0627\u0644\u0637\u0627\u0647\u064a\u0629|&#10;La Gamer|Jokalaria|La Gamer|A Gamer|The Gamer|La Gameuse|Die Gamerin|La Gamer|\u0413\u0435\u0439\u043c\u0435\u0440\u0448\u0430|\u6e38\u620f\u73a9\u5bb6|Die Gamer|\u0627\u0644\u0644\u0627\u0639\u0628\u0629|&#10;La Exploradora|Esploratzailea|L'Exploradora|A Exploradora|The Explorer|L'Exploratrice|Die Entdeckerin|L'Esploratrice|\u0418\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u0438\u0446\u0430|\u63a2\u9669\u5bb6|Die Ontdekkingsreisiger|\u0627\u0644\u0645\u0633\u062a\u0643\u0634\u0641\u0629|&#10;car\u00e1cter: aventurera|izaera: abenturazalea|car\u00e0cter: aventurera|car\u00e1cter: aventureira|character: adventurous|caract\u00e8re : aventuri\u00e8re|Charakter: abenteuerlustig|carattere: avventurosa|\u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440: \u0430\u0432\u0430\u043d\u0442\u044e\u0440\u043d\u044b\u0439|\u6027\u683c\uff1a\u7231\u5192\u9669|karakter: avontuurlustig|\u0627\u0644\u0637\u0628\u0639: \u0645\u063a\u0627\u0645\u0631\u0629|&#10;car\u00e1cter: t\u00edmida|izaera: lotsatia|car\u00e0cter: t\u00edmida|car\u00e1cter: t\u00edmida|character: shy|caract\u00e8re : timide|Charakter: sch\u00fcchtern|carattere: timida|\u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440: \u0437\u0430\u0441\u0442\u0435\u043d\u0447\u0438\u0432\u044b\u0439|\u6027\u683c\uff1a\u5bb3\u7f9e|karakter: skaam|\u0627\u0644\u0637\u0628\u0639: \u062e\u062c\u0648\u0644\u0629|&#10;car\u00e1cter: so\u00f1adora|izaera: amesgilea|car\u00e0cter: somiadora|car\u00e1cter: so\u00f1adora|character: dreamy|caract\u00e8re : r\u00eaveuse|Charakter: vertr\u00e4umt|carattere: sognatrice|\u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440: \u043c\u0435\u0447\u0442\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u0439|\u6027\u683c\uff1a\u7231\u5e7b\u60f3|karakter: dromerig|\u0627\u0644\u0637\u0628\u0639: \u062d\u0627\u0644\u0645\u0629|&#10;car\u00e1cter: combativa|izaera: borrokalaria|car\u00e0cter: combativa|car\u00e1cter: combativa|character: fighter|caract\u00e8re : combative|Charakter: k\u00e4mpferisch|carattere: combattiva|\u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440: \u0431\u043e\u0435\u0432\u043e\u0439|\u6027\u683c\uff1a\u597d\u6597|karakter: strydlustig|\u0627\u0644\u0637\u0628\u0639: \u0645\u0642\u0627\u062a\u0644\u0629|&#10;car\u00e1cter: extrovertida|izaera: estrobertitua|car\u00e0cter: extravertida|car\u00e1cter: extrovertida|character: outgoing|caract\u00e8re : extravertie|Charakter: extrovertiert|carattere: estroversa|\u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440: \u043e\u0431\u0449\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439|\u6027\u683c\uff1a\u5916\u5411|karakter: ekstroverte|\u0627\u0644\u0637\u0628\u0639: \u0645\u0646\u0641\u062a\u062d\u0629|&#10;car\u00e1cter: met\u00f3dica|izaera: metodikoa|car\u00e0cter: met\u00f2dica|car\u00e1cter: met\u00f3dica|character: methodical|caract\u00e8re : m\u00e9thodique|Charakter: methodisch|carattere: metodica|\u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440: \u043c\u0435\u0442\u043e\u0434\u0438\u0447\u043d\u044b\u0439|\u6027\u683c\uff1a\u6709\u6761\u7406|karakter: metodies|\u0627\u0644\u0637\u0628\u0639: \u0645\u0646\u0647\u062c\u064a\u0629|&#10;car\u00e1cter: vaga|izaera: alferra|car\u00e0cter: gandula|car\u00e1cter: preguiceira|character: lazy|caract\u00e8re : paresseuse|Charakter: faul|carattere: pigra|\u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440: \u043b\u0435\u043d\u0438\u0432\u044b\u0439|\u6027\u683c\uff1a\u61d2\u6563|karakter: lui|\u0627\u0644\u0637\u0628\u0639: \u0643\u0633\u0648\u0644\u0629|&#10;car\u00e1cter: curiosa|izaera: jakintsua|car\u00e0cter: curiosa|car\u00e1cter: curiosa|character: curious|caract\u00e8re : curieuse|Charakter: neugierig|carattere: curiosa|\u0445\u0430\u0440\u0430\u043a\u0442\u0435\u0440: \u043b\u044e\u0431\u043e\u043f\u044b\u0442\u043d\u044b\u0439|\u6027\u683c\uff1a\u597d\u5947|karakter: nuuskierig|\u0627\u0644\u0637\u0628\u0639: \u0641\u0636\u0648\u0644\u064a\u0629|&#10;Teatro Hologr\u00e1fico|Teatro Holografikoa|Teatre Hologr\u00e0fic|Teatro Hologr\u00e1fico|Holographic Theater|Th\u00e9\u00e2tre holographique|Holografisches Theater|Teatro Olografico|\u0413\u043e\u043b\u043e\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0442\u0435\u0430\u0442\u0440|\u5168\u606f\u5267\u573a|Holografiese Teater|\u0627\u0644\u0645\u0633\u0631\u062d \u0627\u0644\u0647\u0648\u0644\u0648\u063a\u0631\u0627\u0641\u064a|&#10;Mesa de Ajedrez|Xake mahaia|Taula d'escacs|Mesa de xadrez|Chess Table|Table d'\u00e9checs|Schachtisch|Tavolo da scacchi|\u0428\u0430\u0445\u043c\u0430\u0442\u043d\u044b\u0439 \u0441\u0442\u043e\u043b|\u56fd\u9645\u8c61\u68cb\u684c|Skaaktafel|\u0637\u0627\u0648\u0644\u0629 \u0627\u0644\u0634\u0637\u0631\u0646\u062c|&#10;Boutique de Moda MIIG26|MIIG26 Moda Denda|Boutique de Moda MIIG26|Boutique de Moda MIIG26|MIIG26 Fashion Boutique|Boutique de mode MIIG26|MIIG26 Mode-Boutique|Boutique di moda MIIG26|\u041c\u043e\u0434\u043d\u044b\u0439 \u0431\u0443\u0442\u0438\u043a MIIG26|MIIG26\u65f6\u88c5\u5e97|MIIG26 Modeboetiek|\u0628\u0648\u062a\u064a\u0643 \u0623\u0632\u064a\u0627\u0621 MIIG26|&#10;Esperando rival\u2026|Aurkaria zain\u2026|Esperant rival\u2026|Esperando rival\u2026|Waiting for an opponent\u2026|En attente d'un adversaire\u2026|Warten auf Gegner\u2026|In attesa di un avversario\u2026|\u0416\u0434\u0451\u043c \u0441\u043e\u043f\u0435\u0440\u043d\u0438\u043a\u0430\u2026|\u7b49\u5f85\u5bf9\u624b\u2026|Wag vir teenstander\u2026|\u0628\u0627\u0646\u062a\u0638\u0627\u0631 \u0645\u0646\u0627\u0641\u0633\u2026|&#10;Cambiando el suelo retr\u00e1ctil\u2026|Zoru atzerakorra aldatzen\u2026|Canviant el s\u00f2l retr\u00e0ctil\u2026|Cambiando o chan retr\u00e1ctil\u2026|Changing the retractable floor\u2026|Changement du sol r\u00e9tractable\u2026|Einziehbarer Boden wird gewechselt\u2026|Cambio del pavimento retrattile\u2026|\u041c\u0435\u043d\u044f\u0435\u043c \u0440\u0430\u0437\u0434\u0432\u0438\u0436\u043d\u043e\u0439 \u043f\u043e\u043b\u2026|\u6b63\u5728\u5207\u6362\u4f38\u7f29\u5730\u9762\u2026|Verander die intrekbare vloer\u2026|\u062a\u063a\u064a\u064a\u0631 \u0627\u0644\u0623\u0631\u0636\u064a\u0629 \u0627\u0644\u0642\u0627\u0628\u0644\u0629 \u0644\u0644\u0633\u062d\u0628\u2026|&#10;Modo F\u00fatbol|Futbol modua|Mode Futbol|Modo F\u00fatbol|Football mode|Mode football|Fu\u00dfballmodus|Modalit\u00e0 calcio|\u0420\u0435\u0436\u0438\u043c \u0444\u0443\u0442\u0431\u043e\u043b\u0430|\u8db3\u7403\u6a21\u5f0f|Sokkermodus|\u0648\u0636\u0639 \u0643\u0631\u0629 \u0627\u0644\u0642\u062f\u0645|&#10;Modo eSports|eSports modua|Mode eSports|Modo eSports|eSports mode|Mode eSports|eSports-Modus|Modalit\u00e0 eSports|\u0420\u0435\u0436\u0438\u043c \u043a\u0438\u0431\u0435\u0440\u0441\u043f\u043e\u0440\u0442\u0430|\u7535\u7ade\u6a21\u5f0f|eSports-modus|\u0648\u0636\u0639 \u0627\u0644\u0631\u064a\u0627\u0636\u0627\u062a \u0627\u0644\u0625\u0644\u0643\u062a\u0631\u0648\u0646\u064a\u0629|&#10;Atletismo piezoel\u00e9ctrico|Atletismo piezoelektrikoa|Atletisme piezoel\u00e8ctric|Atletismo piezoel\u00e9ctrico|Piezoelectric athletics|Athl\u00e9tisme pi\u00e9zo\u00e9lectrique|Piezoelektrische Leichtathletik|Atletica piezoelettrica|\u041f\u044c\u0435\u0437\u043e\u044d\u043b\u0435\u043a\u0442\u0440\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0430\u0442\u043b\u0435\u0442\u0438\u043a\u0430|\u538b\u7535\u7530\u5f84|Pi\u00ebso\u00eblektriese atletiek|\u0623\u0644\u0639\u0627\u0628 \u0627\u0644\u0642\u0648\u0649 \u0628\u0627\u0644\u0643\u0647\u0631\u0636\u063a\u0637\u064a\u0629|&#10;Dise\u00f1ando|Diseinatzen|Dissenyant|Dese\u00f1ando|Designing|Cr\u00e9ation|Entwerfen|Progettazione|\u0421\u043e\u0437\u0434\u0430\u0451\u043c|\u8bbe\u8ba1\u4e2d|Ontwerp|\u062a\u0635\u0645\u064a\u0645|&#10;Desfilando|Desfilatzen|Desfilant|Desfilando|On the runway|D\u00e9fil\u00e9|Auf dem Laufsteg|In passerella|\u041d\u0430 \u043f\u043e\u0434\u0438\u0443\u043c\u0435|T\u53f0\u8d70\u79c0|Op die loopplank|\u0639\u0631\u0636 \u0627\u0644\u0623\u0632\u064a\u0627\u0621|&#10;toca la pantalla|ukitu pantaila|toca la pantalla|toca a pantalla|tap the screen|touche l'\u00e9cran|tippe auf den Bildschirm|tocca lo schermo|\u043d\u0430\u0436\u043c\u0438\u0442\u0435 \u043d\u0430 \u044d\u043a\u0440\u0430\u043d|\u70b9\u51fb\u5c4f\u5e55|raak die skerm|\u0627\u0644\u0645\u0633 \u0627\u0644\u0634\u0627\u0634\u0629|&#10;toca la pasarela|ukitu pasarela|toca la passarel\u00b7la|toca a pasarela|tap the runway|touche le podium|tippe auf den Laufsteg|tocca la passerella|\u043d\u0430\u0436\u043c\u0438\u0442\u0435 \u043d\u0430 \u043f\u043e\u0434\u0438\u0443\u043c|\u70b9\u51fbT\u53f0|raak die loopplank|\u0627\u0644\u0645\u0633 \u0645\u0646\u0635\u0629 \u0627\u0644\u0639\u0631\u0636|&#10;Red de robots-huevo|Arrautza-robot sarea|Xarxa de robots-ou|Rede de robots-ovo|Egg-robot network|R\u00e9seau de robots-\u0153ufs|Ei-Roboter-Netzwerk|Rete di robot-uovo|\u0421\u0435\u0442\u044c \u0440\u043e\u0431\u043e\u0442\u043e\u0432-\u044f\u0438\u0446|\u86cb\u5f62\u673a\u5668\u4eba\u7f51\u7edc|Eier-robotnetwerk|\u0634\u0628\u0643\u0629 \u0627\u0644\u0631\u0648\u0628\u0648\u062a\u0627\u062a \u0627\u0644\u0628\u064a\u0636\u064a\u0629|&#10;Salinidad|Gazitasuna|Salinitat|Salinidade|Salinity|Salinit\u00e9|Salzgehalt|Salinit\u00e0|\u0421\u043e\u043b\u0451\u043d\u043e\u0441\u0442\u044c|\u76d0\u5ea6|Soutgehalte|\u0627\u0644\u0645\u0644\u0648\u062d\u0629|&#10;Yodo|Iodoa|Iode|Iodo|Iodine|Iode|Jod|Iodio|\u0419\u043e\u0434|\u7898|Jodium|\u0627\u0644\u064a\u0648\u062f|&#10;Ox\u00edgeno|Oxigenoa|Oxigen|Os\u00edxeno|Oxygen|Oxyg\u00e8ne|Sauerstoff|Ossigeno|\u041a\u0438\u0441\u043b\u043e\u0440\u043e\u0434|\u6c27\u6c14|Suurstof|\u0627\u0644\u0623\u0643\u0633\u062c\u064a\u0646|&#10;Metano|Metanoa|Met\u00e0|Metano|Methane|M\u00e9thane|Methan|Metano|\u041c\u0435\u0442\u0430\u043d|\u7532\u70f7|Metaan|\u0627\u0644\u0645\u064a\u062b\u0627\u0646|&#10;S\u00edsmica|Sismika|S\u00edsmica|S\u00edsmica|Seismic|Sismique|Seismik|Sismica|\u0421\u0435\u0439\u0441\u043c\u0438\u043a\u0430|\u5730\u9707|Seismies|\u0627\u0644\u0632\u0644\u0632\u0627\u0644\u064a\u0629|&#10;Fauna y flora|Fauna eta flora|Fauna i flora|Fauna e flora|Fauna and flora|Faune et flore|Fauna und Flora|Fauna e flora|\u0424\u0430\u0443\u043d\u0430 \u0438 \u0444\u043b\u043e\u0440\u0430|\u52a8\u690d\u7269|Fauna en flora|\u0627\u0644\u062d\u064a\u0648\u0627\u0646\u0627\u062a \u0648\u0627\u0644\u0646\u0628\u0627\u062a\u0627\u062a|&#10;sana|osasuntsu|sana|sana|healthy|saine|gesund|sana|\u0437\u0434\u043e\u0440\u043e\u0432\u0430|\u5065\u5eb7|gesond|\u0633\u0644\u064a\u0645\u0629|&#10;vigilada|zainduta|vigilada|vixiada|monitored|surveill\u00e9e|\u00fcberwacht|monitorata|\u043f\u043e\u0434 \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u0435\u043c|\u53d7\u76d1\u6d4b|gemonitor|\u0645\u0631\u0627\u0642\u064e\u0628\u0629|&#10;Todo en orden en el fondo marino|Dena ongi itsas hondoan|Tot en ordre al fons mar\u00ed|Todo en orde no fondo mari\u00f1o|All in order on the seabed|Tout est en ordre au fond de la mer|Alles in Ordnung am Meeresgrund|Tutto in ordine sul fondale|\u041d\u0430 \u0434\u043d\u0435 \u0432\u0441\u0451 \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435|\u6d77\u5e95\u4e00\u5207\u6b63\u5e38|Alles in orde op die seebodem|\u0643\u0644 \u0634\u064a\u0621 \u0639\u0644\u0649 \u0645\u0627 \u064a\u0631\u0627\u0645 \u0641\u064a \u0642\u0627\u0639 \u0627\u0644\u0628\u062d\u0631|&#10;Fuga de metano: robot ge\u00f3logo act\u00faa|Metano ihesa: robot geologoa jardunean|Fuita de met\u00e0: el robot ge\u00f2leg actua|Fuga de metano: o robot xe\u00f3logo act\u00faa|Methane leak: geologist robot acting|Fuite de m\u00e9thane : le robot g\u00e9ologue intervient|Methanleck: Geologen-Roboter greift ein|Perdita di metano: il robot geologo interviene|\u0423\u0442\u0435\u0447\u043a\u0430 \u043c\u0435\u0442\u0430\u043d\u0430: \u0440\u043e\u0431\u043e\u0442-\u0433\u0435\u043e\u043b\u043e\u0433 \u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u0442|\u7532\u70f7\u6cc4\u6f0f\uff1a\u5730\u8d28\u673a\u5668\u4eba\u5904\u7406\u4e2d|Metaanlek: geoloog-robot tree op|\u062a\u0633\u0631\u0628 \u0645\u064a\u062b\u0627\u0646: \u0627\u0644\u0631\u0648\u0628\u0648\u062a \u0627\u0644\u062c\u064a\u0648\u0644\u0648\u062c\u064a \u064a\u062a\u062f\u062e\u0644|&#10;Micro-vibraciones industriales|Mikro-bibrazio industrialak|Microvibracions industrials|Microvibraci\u00f3ns industriais|Industrial micro-vibrations|Micro-vibrations industrielles|Industrielle Mikrovibrationen|Microvibrazioni industriali|\u041f\u0440\u043e\u043c\u044b\u0448\u043b\u0435\u043d\u043d\u044b\u0435 \u043c\u0438\u043a\u0440\u043e\u0432\u0438\u0431\u0440\u0430\u0446\u0438\u0438|\u5de5\u4e1a\u5fae\u632f\u52a8|Industri\u00eble mikrovibrasies|\u0627\u0647\u062a\u0632\u0627\u0632\u0627\u062a \u0635\u0646\u0627\u0639\u064a\u0629 \u062f\u0642\u064a\u0642\u0629|&#10;Ox\u00edgeno bajo: calor y suciedad|Oxigeno gutxi: beroa eta zikinkeria|Oxigen baix: calor i brut\u00edcia|Os\u00edxeno baixo: calor e sucidade|Low oxygen: heat and dirt|Oxyg\u00e8ne bas : chaleur et salet\u00e9|Wenig Sauerstoff: Hitze und Schmutz|Ossigeno basso: caldo e sporcizia|\u041c\u0430\u043b\u043e \u043a\u0438\u0441\u043b\u043e\u0440\u043e\u0434\u0430: \u0436\u0430\u0440\u0430 \u0438 \u0433\u0440\u044f\u0437\u044c|\u6c27\u6c14\u504f\u4f4e\uff1a\u9ad8\u6e29\u548c\u6c61\u67d3|Lae suurstof: hitte en vuilheid|\u0623\u0643\u0633\u062c\u064a\u0646 \u0645\u0646\u062e\u0641\u0636: \u062d\u0631\u0627\u0631\u0629 \u0648\u0623\u0648\u0633\u0627\u062e|&#10;Robot limpiador|Garbitzaile robota|Robot netejador|Robot limpador|Cleaner robot|Robot nettoyeur|Reinigungsroboter|Robot pulitore|\u0420\u043e\u0431\u043e\u0442-\u0443\u0431\u043e\u0440\u0449\u0438\u043a|\u6e05\u6d01\u673a\u5668\u4eba|Skoonmaakrobot|\u0631\u0648\u0628\u0648\u062a \u0627\u0644\u062a\u0646\u0638\u064a\u0641|&#10;Robot de aguas|Uren robota|Robot d'aig\u00fces|Robot de augas|Water robot|Robot des eaux|Wasser-Roboter|Robot delle acque|\u0412\u043e\u0434\u043d\u044b\u0439 \u0440\u043e\u0431\u043e\u0442|\u6c34\u8d28\u673a\u5668\u4eba|Waterrobot|\u0631\u0648\u0628\u0648\u062a \u0627\u0644\u0645\u064a\u0627\u0647|&#10;Robot ge\u00f3logo|Robot geologoa|Robot ge\u00f2leg|Robot xe\u00f3logo|Geologist robot|Robot g\u00e9ologue|Geologen-Roboter|Robot geologo|\u0420\u043e\u0431\u043e\u0442-\u0433\u0435\u043e\u043b\u043e\u0433|\u5730\u8d28\u673a\u5668\u4eba|Geoloog-robot|\u0627\u0644\u0631\u0648\u0628\u0648\u062a \u0627\u0644\u062c\u064a\u0648\u0644\u0648\u062c\u064a|&#10;Robot de vida|Bizitza robota|Robot de vida|Robot de vida|Life robot|Robot du vivant|Lebens-Roboter|Robot della vita|\u0420\u043e\u0431\u043e\u0442 \u0436\u0438\u0437\u043d\u0438|\u751f\u547d\u673a\u5668\u4eba|Lewe-robot|\u0631\u0648\u0628\u0648\u062a \u0627\u0644\u062d\u064a\u0627\u0629|&#10;recogiendo basura|zaborra jasotzen|recollint brossa|recollendo lixo|collecting trash|ramasse les d\u00e9chets|sammelt M\u00fcll|raccoglie rifiuti|\u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u043c\u0443\u0441\u043e\u0440|\u6b63\u5728\u6e05\u7406\u5783\u573e|versamel rommel|\u064a\u062c\u0645\u0639 \u0627\u0644\u0642\u0645\u0627\u0645\u0629|&#10;fondo limpio|hondo garbia|fons net|fondo limpo|clean seabed|fond propre|sauberer Grund|fondale pulito|\u0434\u043d\u043e \u0447\u0438\u0441\u0442\u043e\u0435|\u6d77\u5e95\u5e72\u51c0|skoon seebodem|\u0627\u0644\u0642\u0627\u0639 \u0646\u0638\u064a\u0641|&#10;yendo a la basura|zabalera doa|anant cap a la brossa|indo ao lixo|heading to the trash|va vers les d\u00e9chets|geht zum M\u00fcll|va verso i rifiuti|\u043f\u043b\u044b\u0432\u0451\u0442 \u043a \u043c\u0443\u0441\u043e\u0440\u0443|\u524d\u5f80\u5783\u573e\u5904|op pad na die rommel|\u064a\u062a\u062c\u0647 \u0625\u0644\u0649 \u0627\u0644\u0642\u0645\u0627\u0645\u0629|&#10;midiendo el agua|ura neurtzen|mesurant l'aigua|medindo a auga|measuring the water|mesure l'eau|misst das Wasser|misura l'acqua|\u0438\u0437\u043c\u0435\u0440\u044f\u0435\u0442 \u0432\u043e\u0434\u0443|\u6b63\u5728\u6d4b\u91cf\u6c34\u8d28|meet die water|\u064a\u0642\u064a\u0633 \u0627\u0644\u0645\u0627\u0621|&#10;sellando la fuga|ihesa zigilatzen|segellant la fuita|selando a fuga|sealing the leak|colmate la fuite|dichtet das Leck ab|sigilla la perdita|\u0437\u0430\u0434\u0435\u043b\u044b\u0432\u0430\u0435\u0442 \u0443\u0442\u0435\u0447\u043a\u0443|\u6b63\u5728\u5c01\u5835\u6cc4\u6f0f|se\u00ebl die lek|\u064a\u0633\u062f \u0627\u0644\u062a\u0633\u0631\u0628|&#10;vigilando metano|metanoa zaintzen|vigilant el met\u00e0|vixiando metano|watching methane|surveille le m\u00e9thane|\u00fcberwacht Methan|sorveglia il metano|\u0441\u043b\u0435\u0434\u0438\u0442 \u0437\u0430 \u043c\u0435\u0442\u0430\u043d\u043e\u043c|\u76d1\u6d4b\u7532\u70f7|monitor metaan|\u064a\u0631\u0627\u0642\u0628 \u0627\u0644\u0645\u064a\u062b\u0627\u0646|&#10;revisando|aztertzen|revisant|revisando|checking|v\u00e9rifie|pr\u00fcft|controlla|\u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442|\u6b63\u5728\u68c0\u67e5|kyk na|\u064a\u0641\u062d\u0635|&#10;estrellas|izarrak|estrelles|estrelas|starfish|\u00e9toiles de mer|Seesterne|stelle marine|\u043c\u043e\u0440\u0441\u043a\u0438\u0435 \u0437\u0432\u0451\u0437\u0434\u044b|\u6d77\u661f|seesterre|\u0646\u062c\u0648\u0645 \u0627\u0644\u0628\u062d\u0631|&#10;erizos|trikuak|garotes|ourizos|urchins|oursins|Seeigel|ricci|\u0435\u0436\u0438|\u6d77\u80c6|see-egels|\u0642\u0646\u0627\u0641\u0630 \u0627\u0644\u0628\u062d\u0631|&#10;an\u00e9mona|anemona|an\u00e8mona|an\u00e9mona|anemone|an\u00e9mone|Anemone|anemone|\u0430\u043d\u0435\u043c\u043e\u043d|\u6d77\u8475|anemoon|\u0634\u0642\u0627\u0626\u0642 \u0627\u0644\u0646\u0639\u0645\u0627\u0646|&#10;posidonia|posidonia|posid\u00f2nia|posidonia|posidonia|posidonie|Neptungras|posidonia|\u043f\u043e\u0441\u0438\u0434\u043e\u043d\u0438\u044f|\u6ce2\u897f\u591a\u5c3c\u4e9a\u6d77\u8349|posidonia|\u0628\u0648\u0633\u064a\u062f\u0648\u0646\u064a\u0627|&#10;algas|algak|algues|algas|algae|algues|Algen|alghe|\u0432\u043e\u0434\u043e\u0440\u043e\u0441\u043b\u0438|\u6d77\u85fb|alge|\u0627\u0644\u0637\u062d\u0627\u0644\u0628|&#10;sardinas|sardinak|sardines|sardi\u00f1as|sardines|sardines|Sardinen|sardine|\u0441\u0430\u0440\u0434\u0438\u043d\u044b|\u6c99\u4e01\u9c7c|sardyne|\u0627\u0644\u0633\u0631\u062f\u064a\u0646|&#10;Arrastra a una chica a un banco, a un patinete, al tranv\u00eda o t\u00f3calo (\u00a1se va a la playa a surfear!), a una casa, a la mesa de la biblioteca, o toca el cubo del gimnasio|Eraman neska bat banku batera, patinete batera, tranbiara edo ukitu tranbia (hondartzara doa surfera!), etxe batera, liburutegiko mahaira, edo ukitu gimnasioko kuboa|Arrossega una noia a un banc, a un patinet, al tramvia o toca'l (se'n va a la platja a surfejar!), a una casa, a la taula de la biblioteca, o toca el cub del gimn\u00e0s|Arrastra unha rapaza a un banco, a un patinete, ao tranv\u00eda ou t\u00f3cao (vai \u00e1 praia surfear!), a unha casa, \u00e1 mesa da biblioteca, ou toca o cubo do ximnasio|Drag a girl to a bench, a scooter, the tram or tap it (she goes surfing at the beach!), a house, the library table, or tap the gym cube|Fais glisser une fille vers un banc, une trottinette, le tram ou touche-le (elle part surfer \u00e0 la plage !), une maison, la table de la biblioth\u00e8que, ou touche le cube du gymnase|Zieh ein M\u00e4dchen zu einer Bank, einem Roller, zur Stra\u00dfenbahn oder tippe sie an (sie geht am Strand surfen!), zu einem Haus, zum Tisch der Bibliothek oder tippe auf den Fitnessw\u00fcrfel|Trascina una ragazza su una panchina, su un monopattino, sul tram o toccalo (va a fare surf in spiaggia!), in una casa, al tavolo della biblioteca, o tocca il cubo della palestra|\u041f\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u0435 \u0434\u0435\u0432\u043e\u0447\u043a\u0443 \u043d\u0430 \u0441\u043a\u0430\u043c\u0435\u0439\u043a\u0443, \u0441\u0430\u043c\u043e\u043a\u0430\u0442, \u0442\u0440\u0430\u043c\u0432\u0430\u0439 \u0438\u043b\u0438 \u043d\u0430\u0436\u043c\u0438\u0442\u0435 \u043d\u0430 \u043d\u0435\u0433\u043e (\u043e\u043d\u0430 \u043f\u043e\u0435\u0434\u0435\u0442 \u0441\u0451\u0440\u0444\u0438\u0442\u044c \u043d\u0430 \u043f\u043b\u044f\u0436!), \u0432 \u0434\u043e\u043c, \u043a \u0441\u0442\u043e\u043b\u0443 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0438\u043b\u0438 \u043d\u0430\u0436\u043c\u0438\u0442\u0435 \u043d\u0430 \u043a\u0443\u0431 \u0441\u043f\u043e\u0440\u0442\u0437\u0430\u043b\u0430|\u628a\u5973\u5b69\u62d6\u5230\u957f\u6905\u3001\u6ed1\u677f\u8f66\u3001\u7535\u8f66\uff08\u70b9\u7535\u8f66\u5979\u4f1a\u53bb\u6d77\u6ee9\u51b2\u6d6a\uff01\uff09\u3001\u623f\u5b50\u3001\u56fe\u4e66\u9986\u7684\u684c\u5b50\uff0c\u6216\u70b9\u51fb\u5065\u8eab\u623f\u65b9\u5757|Sleep 'n meisie na 'n bankie, 'n stootfiets, die trem of raak dit aan (sy gaan branderplank ry by die strand!), 'n huis, die biblioteektafel, of raak die gimnasiumkubus aan|\u0627\u0633\u062d\u0628 \u0641\u062a\u0627\u0629 \u0625\u0644\u0649 \u0645\u0642\u0639\u062f \u0623\u0648 \u0633\u0643\u0648\u062a\u0631 \u0623\u0648 \u0627\u0644\u062a\u0631\u0627\u0645 \u0623\u0648 \u0627\u0644\u0645\u0633\u0647 (\u0633\u062a\u0630\u0647\u0628 \u0644\u0631\u0643\u0648\u0628 \u0627\u0644\u0623\u0645\u0648\u0627\u062c \u0639\u0644\u0649 \u0627\u0644\u0634\u0627\u0637\u0626!) \u0623\u0648 \u0625\u0644\u0649 \u0645\u0646\u0632\u0644 \u0623\u0648 \u0625\u0644\u0649 \u0637\u0627\u0648\u0644\u0629 \u0627\u0644\u0645\u0643\u062a\u0628\u0629\u060c \u0623\u0648 \u0627\u0644\u0645\u0633 \u0645\u0643\u0639\u0628 \u0627\u0644\u0635\u0627\u0644\u0629 \u0627\u0644\u0631\u064a\u0627\u0636\u064a\u0629|&#10;En ChicaChica las chicas viven su d\u00eda solas: cultivan la huerta, compran en el mercado, estudian, entrenan y surfean. Aqu\u00ed no hay prisas, ni enemigos, ni forma de perder.|ChicaChican neskek beren kabuz bizi dute eguna: baratza lantzen dute, azokan erosten dute, ikasten dute, entrenatzen dute eta surfa egiten dute. Hemen ez dago presarik, etsairik, ezta galtzeko modurik ere.|A ChicaChica les noies viuen el seu dia soles: conreen l'horta, compren al mercat, estudien, entrenen i surfegen. Aqu\u00ed no hi ha pressa, ni enemics, ni manera de perdre.|En ChicaChica as rapazas viven o seu d\u00eda soas: cultivan a horta, compran no mercado, estudan, adestran e surfean. Aqu\u00ed non hai pr\u00e9sas, nin inimigos, nin xeito de perder.|In ChicaChica the girls live their day on their own: they grow the garden, shop at the market, study, train and surf. Here there is no rush, no enemies, and no way to lose.|\u00c0 ChicaChica, les filles vivent leur journ\u00e9e seules : elles cultivent le potager, font leurs courses au march\u00e9, \u00e9tudient, s'entra\u00eenent et surfent. Ici, pas de presse, pas d'ennemis, aucun moyen de perdre.|In ChicaChica verbringen die M\u00e4dchen ihren Tag allein: Sie bewirtschaften den Garten, kaufen auf dem Markt ein, lernen, trainieren und surfen. Hier gibt es keine Eile, keine Feinde und keine M\u00f6glichkeit zu verlieren.|A ChicaChica le ragazze vivono la loro giornata da sole: coltivano l'orto, fanno la spesa al mercato, studiano, si allenano e fanno surf. Qui non c'\u00e8 fretta, n\u00e9 nemici, n\u00e9 modo di perdere.|\u0412 \u0427\u0438\u043a\u0430\u0427\u0438\u043a\u0435 \u0434\u0435\u0432\u043e\u0447\u043a\u0438 \u0441\u0430\u043c\u0438 \u043f\u0440\u043e\u0436\u0438\u0432\u0430\u044e\u0442 \u0441\u0432\u043e\u0439 \u0434\u0435\u043d\u044c: \u0432\u044b\u0440\u0430\u0449\u0438\u0432\u0430\u044e\u0442 \u043e\u0433\u043e\u0440\u043e\u0434, \u0445\u043e\u0434\u044f\u0442 \u043d\u0430 \u0440\u044b\u043d\u043e\u043a, \u0443\u0447\u0430\u0442\u0441\u044f, \u0442\u0440\u0435\u043d\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0438 \u0441\u0451\u0440\u0444\u044f\u0442. \u0417\u0434\u0435\u0441\u044c \u043d\u0435\u0442 \u0441\u043f\u0435\u0448\u043a\u0438, \u043d\u0435\u0442 \u0432\u0440\u0430\u0433\u043e\u0432 \u0438 \u043d\u0435\u043b\u044c\u0437\u044f \u043f\u0440\u043e\u0438\u0433\u0440\u0430\u0442\u044c.|\u5728\u5947\u5361\u5947\u5361\uff0c\u5973\u5b69\u4eec\u81ea\u5df1\u8fc7\u65e5\u5b50\uff1a\u79cd\u83dc\u56ed\u3001\u901b\u5e02\u573a\u3001\u5b66\u4e60\u3001\u953b\u70bc\u3001\u51b2\u6d6a\u3002\u8fd9\u91cc\u6ca1\u6709\u5306\u5fd9\uff0c\u6ca1\u6709\u654c\u4eba\uff0c\u4e5f\u4e0d\u4f1a\u5931\u8d25\u3002|In ChicaChica leef die meisies hul dag alleen: hulle bewerk die tuin, koop by die mark, studeer, oefen en gaan branderplank ry. Hier is daar geen haas, geen vyande en geen manier om te verloor nie.|\u0641\u064a \u062a\u0634\u064a\u0643\u0627\u062a\u0634\u064a\u0643\u0627 \u062a\u0639\u064a\u0634 \u0627\u0644\u0641\u062a\u064a\u0627\u062a \u064a\u0648\u0645\u0647\u0646 \u0628\u0645\u0641\u0631\u062f\u0647\u0646: \u064a\u0632\u0631\u0639\u0646 \u0627\u0644\u0628\u0633\u062a\u0627\u0646 \u0648\u064a\u062a\u0633\u0648\u0642\u0646 \u0645\u0646 \u0627\u0644\u0633\u0648\u0642 \u0648\u064a\u062f\u0631\u0633\u0646 \u0648\u064a\u062a\u062f\u0631\u0628\u0646 \u0648\u064a\u0631\u0643\u0628\u0646 \u0627\u0644\u0623\u0645\u0648\u0627\u062c. \u0647\u0646\u0627 \u0644\u0627 \u0639\u062c\u0644\u0629 \u0648\u0644\u0627 \u0623\u0639\u062f\u0627\u0621 \u0648\u0644\u0627 \u0637\u0631\u064a\u0642\u0629 \u0644\u0644\u062e\u0633\u0627\u0631\u0629.|&#10;Tu pueblo se guarda solo en este dispositivo. Para llevarlo a otro, o tener una copia, descarga el archivo o copia el c\u00f3digo. Para cargarlo, pega el c\u00f3digo aqu\u00ed o elige el archivo.|Zure herria gailu honetan bakarrik gordetzen da. Beste batera eramateko edo kopia bat izateko, deskargatu fitxategia edo kopiatu kodea. Kargatzeko, itsatsi kodea hemen edo aukeratu fitxategia.|El teu poble es guarda nom\u00e9s en aquest dispositiu. Per portar-lo a un altre, o tenir-ne una c\u00f2pia, descarrega l'arxiu o copia el codi. Per carregar-lo, enganxa el codi aqu\u00ed o tria l'arxiu.|O teu pobo g\u00e1rdase s\u00f3 neste dispositivo. Para levalo a outro, ou ter unha copia, descarga o arquivo ou copia o c\u00f3digo. Para cargalo, pega o c\u00f3digo aqu\u00ed ou elixe o arquivo.|Your town is saved only on this device. To take it to another one, or to keep a copy, download the file or copy the code. To load it, paste the code here or choose the file.|Ton village est enregistr\u00e9 uniquement sur cet appareil. Pour l'emporter ailleurs, ou en garder une copie, t\u00e9l\u00e9charge le fichier ou copie le code. Pour le charger, colle le code ici ou choisis le fichier.|Dein Dorf wird nur auf diesem Ger\u00e4t gespeichert. Um es auf ein anderes zu \u00fcbertragen oder eine Kopie zu haben, lade die Datei herunter oder kopiere den Code. Zum Laden f\u00fcge den Code hier ein oder w\u00e4hle die Datei.|Il tuo paese viene salvato solo su questo dispositivo. Per portarlo su un altro, o averne una copia, scarica il file o copia il codice. Per caricarlo, incolla il codice qui o scegli il file.|\u0412\u0430\u0448\u0430 \u0434\u0435\u0440\u0435\u0432\u043d\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u044d\u0442\u043e\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435. \u0427\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0435\u0451 \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0435 \u0438\u043b\u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043a\u043e\u043f\u0438\u044e, \u0441\u043a\u0430\u0447\u0430\u0439\u0442\u0435 \u0444\u0430\u0439\u043b \u0438\u043b\u0438 \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0439\u0442\u0435 \u043a\u043e\u0434. \u0427\u0442\u043e\u0431\u044b \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c, \u0432\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u043a\u043e\u0434 \u0441\u044e\u0434\u0430 \u0438\u043b\u0438 \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0444\u0430\u0439\u043b.|\u4f60\u7684\u5c0f\u9547\u53ea\u4fdd\u5b58\u5728\u6b64\u8bbe\u5907\u4e0a\u3002\u60f3\u5e26\u5230\u522b\u7684\u8bbe\u5907\u6216\u7559\u4e00\u4efd\u5907\u4efd\uff0c\u8bf7\u4e0b\u8f7d\u6587\u4ef6\u6216\u590d\u5236\u4ee3\u7801\u3002\u8981\u8bfb\u53d6\u65f6\uff0c\u628a\u4ee3\u7801\u7c98\u8d34\u5230\u8fd9\u91cc\u6216\u9009\u62e9\u6587\u4ef6\u3002|Jou dorp word net op hierdie toestel gestoor. Om dit na 'n ander toestel te neem of 'n kopie te h\u00ea, laai die l\u00eaer af of kopieer die kode. Om dit te laai, plak die kode hier of kies die l\u00eaer.|\u062a\u064f\u062d\u0641\u0638 \u0642\u0631\u064a\u062a\u0643 \u0639\u0644\u0649 \u0647\u0630\u0627 \u0627\u0644\u062c\u0647\u0627\u0632 \u0641\u0642\u0637. \u0644\u0646\u0642\u0644\u0647\u0627 \u0625\u0644\u0649 \u062c\u0647\u0627\u0632 \u0622\u062e\u0631 \u0623\u0648 \u0627\u0644\u0627\u062d\u062a\u0641\u0627\u0638 \u0628\u0646\u0633\u062e\u0629\u060c \u0646\u0632\u0651\u0644 \u0627\u0644\u0645\u0644\u0641 \u0623\u0648 \u0627\u0646\u0633\u062e \u0627\u0644\u0631\u0645\u0632. \u0648\u0644\u062a\u062d\u0645\u064a\u0644\u0647\u0627\u060c \u0627\u0644\u0635\u0642 \u0627\u0644\u0631\u0645\u0632 \u0647\u0646\u0627 \u0623\u0648 \u0627\u062e\u062a\u0631 \u0627\u0644\u0645\u0644\u0641.|&#10;Las vecinas entrenan aqu\u00ed cuando les apetece. Si quieres, toca las m\u00e1quinas.|Bizilagunak hemen entrenatzen dira gogoa dutenean. Nahi baduzu, ukitu makinak.|Les ve\u00efnes entrenen aqu\u00ed quan els ve de gust. Si vols, toca les m\u00e0quines.|As veci\u00f1as adestran aqu\u00ed cando lles apetece. Se queres, toca as m\u00e1quinas.|The neighbours train here whenever they feel like it. If you want, tap the machines.|Les voisines s'entra\u00eenent ici quand elles en ont envie. Si tu veux, touche les machines.|Die Nachbarinnen trainieren hier, wann immer sie Lust haben. Wenn du magst, tippe auf die Ger\u00e4te.|Le vicine si allenano qui quando ne hanno voglia. Se vuoi, tocca le macchine.|\u0421\u043e\u0441\u0435\u0434\u043a\u0438 \u0442\u0440\u0435\u043d\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0437\u0434\u0435\u0441\u044c, \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u0445\u043e\u0442\u044f\u0442. \u0415\u0441\u043b\u0438 \u0445\u043e\u0442\u0438\u0442\u0435, \u043d\u0430\u0436\u043c\u0438\u0442\u0435 \u043d\u0430 \u0442\u0440\u0435\u043d\u0430\u0436\u0451\u0440\u044b.|\u90bb\u5c45\u4eec\u60f3\u7ec3\u7684\u65f6\u5019\u5c31\u6765\u8fd9\u91cc\u3002\u60f3\u7684\u8bdd\uff0c\u70b9\u4e00\u70b9\u5668\u68b0\u5427\u3002|Die bure oefen hier wanneer hulle lus is. As jy wil, raak die masjiene aan.|\u062a\u062a\u062f\u0631\u0628 \u0627\u0644\u062c\u0627\u0631\u0627\u062a \u0647\u0646\u0627 \u0645\u062a\u0649 \u0623\u0631\u062f\u0646. \u0625\u0646 \u0623\u062d\u0628\u0628\u062a\u060c \u0627\u0644\u0645\u0633 \u0627\u0644\u0622\u0644\u0627\u062a.|&#10;Gira el m\u00f3vil, o toca la lupa|Biratu mugikorra, edo ukitu lupa|Gira el m\u00f2bil, o toca la lupa|Xira o m\u00f3bil, ou toca a lupa|Rotate your phone, or tap the magnifier|Tourne ton t\u00e9l\u00e9phone, ou touche la loupe|Dreh das Handy oder tippe auf die Lupe|Ruota il telefono, o tocca la lente|\u041f\u043e\u0432\u0435\u0440\u043d\u0438\u0442\u0435 \u0442\u0435\u043b\u0435\u0444\u043e\u043d \u0438\u043b\u0438 \u043d\u0430\u0436\u043c\u0438\u0442\u0435 \u043d\u0430 \u043b\u0443\u043f\u0443|\u65cb\u8f6c\u624b\u673a\uff0c\u6216\u70b9\u51fb\u653e\u5927\u955c|Draai jou foon, of raak die vergrootglas aan|\u0623\u062f\u0631 \u0647\u0627\u062a\u0641\u0643 \u0623\u0648 \u0627\u0644\u0645\u0633 \u0627\u0644\u0639\u062f\u0633\u0629|&#10;para acercar|zooma egiteko|per apropar|para achegar|to zoom in|pour zoomer|zum Vergr\u00f6\u00dfern|per ingrandire|\u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u044c|\u4ee5\u653e\u5927|om in te zoom|\u0644\u0644\u062a\u0642\u0631\u064a\u0628|&#10;Si no se descarga, mant\u00e9n pulsada la imagen y elige \u00abGuardar\u00bb.|Deskargatzen ez bada, eduki sakatuta irudia eta aukeratu \u00abGorde\u00bb.|Si no es descarrega, mant\u00e9n premuda la imatge i tria \u00abDesa\u00bb.|Se non se descarga, mant\u00e9n premida a imaxe e elixe \u00abGardar\u00bb.|If it doesn't download, press and hold the image and choose \u201cSave\u201d.|Si elle ne se t\u00e9l\u00e9charge pas, appuie longuement sur l'image et choisis \u00ab Enregistrer \u00bb.|Falls der Download nicht startet, halte das Bild gedr\u00fcckt und w\u00e4hle \u201eSpeichern\u201c.|Se non si scarica, tieni premuta l'immagine e scegli \u00abSalva\u00bb.|\u0415\u0441\u043b\u0438 \u043d\u0435 \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u043d\u0430\u0436\u043c\u0438\u0442\u0435 \u0438 \u0443\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0439\u0442\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438 \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u00ab\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c\u00bb.|\u5982\u679c\u6ca1\u6709\u4e0b\u8f7d\uff0c\u8bf7\u957f\u6309\u56fe\u7247\u5e76\u9009\u62e9\u201c\u4fdd\u5b58\u201d\u3002|As dit nie aflaai nie, hou die beeld ingedruk en kies \u201cStoor\u201d.|\u0625\u0646 \u0644\u0645 \u064a\u062a\u0645 \u0627\u0644\u062a\u0646\u0632\u064a\u0644\u060c \u0627\u0636\u063a\u0637 \u0645\u0637\u0648\u0644\u064b\u0627 \u0639\u0644\u0649 \u0627\u0644\u0635\u0648\u0631\u0629 \u0648\u0627\u062e\u062a\u0631 \u00ab\u062d\u0641\u0638\u00bb.|&#10;Guardar mi pueblo|Gorde nire herria|Desa el meu poble|Gardar o meu pobo|Save my town|Enregistrer mon village|Mein Dorf speichern|Salva il mio paese|\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043c\u043e\u044e \u0434\u0435\u0440\u0435\u0432\u043d\u044e|\u4fdd\u5b58\u6211\u7684\u5c0f\u9547|Stoor my dorp|\u0627\u062d\u0641\u0638 \u0642\u0631\u064a\u062a\u064a|&#10;Descargar o compartir|Deskargatu edo partekatu|Descarrega o comparteix|Descargar ou compartir|Download or share|T\u00e9l\u00e9charger ou partager|Herunterladen oder teilen|Scarica o condividi|\u0421\u043a\u0430\u0447\u0430\u0442\u044c \u0438\u043b\u0438 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f|\u4e0b\u8f7d\u6216\u5206\u4eab|Laai af of deel|\u062a\u0646\u0632\u064a\u0644 \u0623\u0648 \u0645\u0634\u0627\u0631\u0643\u0629|&#10;Copiar c\u00f3digo|Kopiatu kodea|Copia el codi|Copiar c\u00f3digo|Copy code|Copier le code|Code kopieren|Copia il codice|\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434|\u590d\u5236\u4ee3\u7801|Kopieer kode|\u0646\u0633\u062e \u0627\u0644\u0631\u0645\u0632|&#10;Cargar este c\u00f3digo|Kargatu kode hau|Carrega aquest codi|Cargar este c\u00f3digo|Load this code|Charger ce code|Diesen Code laden|Carica questo codice|\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u043a\u043e\u0434|\u52a0\u8f7d\u6b64\u4ee3\u7801|Laai hierdie kode|\u062a\u062d\u0645\u064a\u0644 \u0647\u0630\u0627 \u0627\u0644\u0631\u0645\u0632|&#10;Elegir archivo|Aukeratu fitxategia|Tria un arxiu|Elixir arquivo|Choose file|Choisir un fichier|Datei w\u00e4hlen|Scegli il file|\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0444\u0430\u0439\u043b|\u9009\u62e9\u6587\u4ef6|Kies l\u00eaer|\u0627\u062e\u062a\u0631 \u0645\u0644\u0641\u064b\u0627|&#10;Cerrar|Itxi|Tanca|Pechar|Close|Fermer|Schlie\u00dfen|Chiudi|\u0417\u0430\u043a\u0440\u044b\u0442\u044c|\u5173\u95ed|Maak toe|\u0625\u063a\u0644\u0627\u0642|&#10;Compartir|Partekatu|Comparteix|Compartir|Share|Partager|Teilen|Condividi|\u041f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f|\u5206\u4eab|Deel|\u0645\u0634\u0627\u0631\u0643\u0629|&#10;Descargar|Deskargatu|Descarrega|Descargar|Download|T\u00e9l\u00e9charger|Herunterladen|Scarica|\u0421\u043a\u0430\u0447\u0430\u0442\u044c|\u4e0b\u8f7d|Laai af|\u062a\u0646\u0632\u064a\u0644|&#10;Bienvenida al pueblo|Ongi etorri herrira|Benvinguda al poble|Benvida ao pobo|Welcome to the town|Bienvenue au village|Willkommen im Dorf|Benvenuta al paese|\u0414\u043e\u0431\u0440\u043e \u043f\u043e\u0436\u0430\u043b\u043e\u0432\u0430\u0442\u044c \u0432 \u0434\u0435\u0440\u0435\u0432\u043d\u044e|\u6b22\u8fce\u6765\u5230\u5c0f\u9547|Welkom by die dorp|\u0645\u0631\u062d\u0628\u064b\u0627 \u0628\u0643 \u0641\u064a \u0627\u0644\u0642\u0631\u064a\u0629|&#10;Saltar|Saltatu|Omet|Saltar|Skip|Passer|\u00dcberspringen|Salta|\u041f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c|\u8df3\u8fc7|Slaan oor|\u062a\u062e\u0637\u064a|&#10;Siguiente|Hurrengoa|Seg\u00fcent|Seguinte|Next|Suivant|Weiter|Avanti|\u0414\u0430\u043b\u0435\u0435|\u4e0b\u4e00\u6b65|Volgende|\u0627\u0644\u062a\u0627\u0644\u064a|&#10;Auto|Automatikoa|Autom\u00e0tic|Autom\u00e1tico|Auto|Auto|Auto|Auto|\u0410\u0432\u0442\u043e|\u81ea\u52a8|Outo|\u062a\u0644\u0642\u0627\u0626\u064a|&#10;Algo no ha cargado bien. Recarga la p\u00e1gina|Zerbait ez da ondo kargatu. Birkargatu orria|Alguna cosa no ha carregat b\u00e9. Recarrega la p\u00e0gina|Algo non cargou ben. Recarga a p\u00e1xina|Something didn't load properly. Reload the page|Un \u00e9l\u00e9ment ne s'est pas bien charg\u00e9. Recharge la page|Etwas wurde nicht richtig geladen. Lade die Seite neu|Qualcosa non si \u00e8 caricato bene. Ricarica la pagina|\u0427\u0442\u043e-\u0442\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043b\u043e\u0441\u044c \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e. \u041f\u0435\u0440\u0435\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443|\u6709\u5185\u5bb9\u6ca1\u6709\u52a0\u8f7d\u597d\u3002\u8bf7\u5237\u65b0\u9875\u9762|Iets het nie reg gelaai nie. Herlaai die bladsy|\u0644\u0645 \u064a\u062a\u0645 \u062a\u062d\u0645\u064a\u0644 \u0634\u064a\u0621 \u0645\u0627 \u0628\u0634\u0643\u0644 \u0635\u062d\u064a\u062d. \u0623\u0639\u062f \u062a\u062d\u0645\u064a\u0644 \u0627\u0644\u0635\u0641\u062d\u0629|&#10;Selecci\u00f3nalo y c\u00f3pialo a mano|Hautatu eta kopiatu eskuz|Selecciona'l i copia'l a m\u00e0|Selecci\u00f3nao e c\u00f3piao a man|Select it and copy it by hand|S\u00e9lectionne-le et copie-le \u00e0 la main|Markiere es und kopiere es von Hand|Selezionalo e copialo a mano|\u0412\u044b\u0434\u0435\u043b\u0438\u0442\u0435 \u0438 \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0439\u0442\u0435 \u0432\u0440\u0443\u0447\u043d\u0443\u044e|\u8bf7\u624b\u52a8\u9009\u4e2d\u5e76\u590d\u5236|Kies dit en kopieer dit met die hand|\u062d\u062f\u0651\u062f\u0647 \u0648\u0627\u0646\u0633\u062e\u0647 \u064a\u062f\u0648\u064a\u064b\u0627|&#10;Ese archivo es demasiado grande para ser un pueblo.|Fitxategi hori handiegia da herri bat izateko.|Aquest arxiu \u00e9s massa gran per ser un poble.|Ese arquivo \u00e9 demasiado grande para ser un pobo.|That file is too big to be a town.|Ce fichier est trop volumineux pour \u00eatre un village.|Diese Datei ist zu gro\u00df f\u00fcr ein Dorf.|Quel file \u00e8 troppo grande per essere un paese.|\u042d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0432\u0435\u043b\u0438\u043a \u0434\u043b\u044f \u0434\u0435\u0440\u0435\u0432\u043d\u0438.|\u8be5\u6587\u4ef6\u592a\u5927\uff0c\u4e0d\u53ef\u80fd\u662f\u4e00\u4e2a\u5c0f\u9547\u3002|Daardie l\u00eaer is te groot om 'n dorp te wees.|\u0647\u0630\u0627 \u0627\u0644\u0645\u0644\u0641 \u0623\u0643\u0628\u0631 \u0645\u0646 \u0623\u0646 \u064a\u0643\u0648\u0646 \u0642\u0631\u064a\u0629.|&#10;No se ha podido sacar la postal en este navegador.|Ezin izan da postala atera nabigatzaile honetan.|No s'ha pogut fer la postal en aquest navegador.|Non se puido sacar a postal neste navegador.|The postcard couldn't be created in this browser.|Impossible de cr\u00e9er la carte postale dans ce navigateur.|Die Postkarte konnte in diesem Browser nicht erstellt werden.|Non \u00e8 stato possibile creare la cartolina in questo browser.|\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0442\u043a\u0440\u044b\u0442\u043a\u0443 \u0432 \u044d\u0442\u043e\u043c \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0435.|\u6b64\u6d4f\u89c8\u5668\u65e0\u6cd5\u751f\u6210\u660e\u4fe1\u7247\u3002|Die poskaart kon nie in hierdie blaaier geskep word nie.|\u062a\u0639\u0630\u0651\u0631 \u0625\u0646\u0634\u0627\u0621 \u0627\u0644\u0628\u0637\u0627\u0642\u0629 \u0627\u0644\u0628\u0631\u064a\u062f\u064a\u0629 \u0641\u064a \u0647\u0630\u0627 \u0627\u0644\u0645\u062a\u0635\u0641\u062d.|&#10;AVISOS|OHARRAK|AVISOS|AVISOS|NOTICES|AVIS|HINWEISE|AVVISI|\u041e\u0411\u042a\u042f\u0412\u041b\u0415\u041d\u0418\u042f|\u516c\u544a|KENNISGEWINGS|\u0625\u0639\u0644\u0627\u0646\u0627\u062a|&#10;Refugio|Aterpea|Refugi|Refuxio|Shelter|Refuge|Tierheim|Rifugio|\u041f\u0440\u0438\u044e\u0442|\u6536\u5bb9\u6240|Skuiling|\u0645\u0644\u062c\u0623|&#10;GIMNASIO|GIMNASIOA|GIMN\u00c0S|XIMNASIO|GYM|GYMNASE|FITNESSSTUDIO|PALESTRA|\u0421\u041f\u041e\u0420\u0422\u0417\u0410\u041b|\u5065\u8eab\u623f|GIMNASIUM|\u0627\u0644\u0635\u0627\u0644\u0629 \u0627\u0644\u0631\u064a\u0627\u0636\u064a\u0629|&#10;BIBLIOTECA|LIBURUTEGIA|BIBLIOTECA|BIBLIOTECA|LIBRARY|BIBLIOTH\u00c8QUE|BIBLIOTHEK|BIBLIOTECA|\u0411\u0418\u0411\u041b\u0418\u041e\u0422\u0415\u041a\u0410|\u56fe\u4e66\u9986|BIBLIOTEEK|\u0627\u0644\u0645\u0643\u062a\u0628\u0629|&#10;TERRAZA|TERRAZA|TERRASSA|TERRAZA|TERRACE|TERRASSE|TERRASSE|TERRAZZA|\u0422\u0415\u0420\u0420\u0410\u0421\u0410|\u9732\u53f0|TERRAS|\u0627\u0644\u0634\u0631\u0641\u0629|&#10;MERCADILLO|AZOKATXOA|MERCAT|MERCADILLO|FLEA MARKET|PETIT MARCH\u00c9|FLOHMARKT|MERCATINO|\u0411\u0410\u0417\u0410\u0420\u0427\u0418\u041a|\u5c0f\u96c6\u5e02|MARKTEFEES|\u0627\u0644\u0633\u0648\u0642 \u0627\u0644\u0635\u063a\u064a\u0631|&#10;LA PLAYA|HONDARTZA|LA PLATJA|A PRAIA|THE BEACH|LA PLAGE|DER STRAND|LA SPIAGGIA|\u041f\u041b\u042f\u0416|\u6d77\u6ee9|DIE STRAND|\u0627\u0644\u0634\u0627\u0637\u0626|&#10;PLAYA|HONDARTZA|PLATJA|PRAIA|BEACH|PLAGE|STRAND|SPIAGGIA|\u041f\u041b\u042f\u0416|\u6d77\u6ee9|STRAND|\u0627\u0644\u0634\u0627\u0637\u0626|&#10;EL PUERTO|PORTUA|EL PORT|O PORTO|THE PORT|LE PORT|DER HAFEN|IL PORTO|\u041f\u041e\u0420\u0422|\u6e2f\u53e3|DIE HAWE|\u0627\u0644\u0645\u064a\u0646\u0627\u0621|&#10;AL PUERTO|PORTURA|AL PORT|AO PORTO|TO THE PORT|AU PORT|ZUM HAFEN|AL PORTO|\u0412 \u041f\u041e\u0420\u0422|\u56de\u6e2f\u53e3|NA DIE HAWE|\u0625\u0644\u0649 \u0627\u0644\u0645\u064a\u0646\u0627\u0621|&#10;PUERTO|PORTUA|PORT|PORTO|PORT|PORT|HAFEN|PORTO|\u041f\u041e\u0420\u0422|\u6e2f\u53e3|HAWE|\u0627\u0644\u0645\u064a\u0646\u0627\u0621|&#10;ESCUELA DE SURF|SURF ESKOLA|ESCOLA DE SURF|ESCOLA DE SURF|SURF SCHOOL|\u00c9COLE DE SURF|SURFSCHULE|SCUOLA DI SURF|\u0428\u041a\u041e\u041b\u0410 \u0421\u0401\u0420\u0424\u0418\u041d\u0413\u0410|\u51b2\u6d6a\u5b66\u6821|BRANDERPLANKSKOOL|\u0645\u062f\u0631\u0633\u0629 \u0631\u0643\u0648\u0628 \u0627\u0644\u0623\u0645\u0648\u0627\u062c|&#10;CHIRINGUITO|CHIRINGITOA|XIRINGUITO|CHIRINGUITO|BEACH BAR|BUVETTE DE PLAGE|STRANDBAR|CHIRINGUITO|\u041f\u041b\u042f\u0416\u041d\u042b\u0419 \u0411\u0410\u0420|\u6d77\u6ee9\u9152\u5427|STRANDKROEG|\u0645\u0642\u0647\u0649 \u0627\u0644\u0634\u0627\u0637\u0626|&#10;ALGAS \u00b7 T\u00c9S \u00b7 SNACKS|ALGAK \u00b7 TEAK \u00b7 TXIRRINDOLAK|ALGUES \u00b7 TES \u00b7 SNACKS|ALGAS \u00b7 T\u00c9S \u00b7 SNACKS|ALGAE \u00b7 TEAS \u00b7 SNACKS|ALGUES \u00b7 TH\u00c9S \u00b7 SNACKS|ALGEN \u00b7 TEES \u00b7 SNACKS|ALGHE \u00b7 T\u00c8 \u00b7 SNACK|\u0412\u041e\u0414\u041e\u0420\u041e\u0421\u041b\u0418 \u00b7 \u0427\u0410\u0419 \u00b7 \u0421\u041d\u0415\u041a\u0418|\u6d77\u85fb \u00b7 \u8336 \u00b7 \u5c0f\u5403|ALGE \u00b7 TEE \u00b7 IMBISSE|\u0637\u062d\u0627\u0644\u0628 \u00b7 \u0634\u0627\u064a \u00b7 \u0648\u062c\u0628\u0627\u062a \u062e\u0641\u064a\u0641\u0629|&#10;BUCEO ECOL\u00d3GICO|URPEKO IBILBIDE EKOLOGIKOA|BUSSEIG ECOL\u00d2GIC|MERGULLO ECOL\u00d3XICO|ECO DIVING|PLONG\u00c9E \u00c9COLOGIQUE|\u00d6KO-TAUCHEN|IMMERSIONI ECOLOGICHE|\u042d\u041a\u041e\u0414\u0410\u0419\u0412\u0418\u041d\u0413|\u751f\u6001\u6f5c\u6c34|EKO-DUIK|\u063a\u0648\u0635 \u0628\u064a\u0626\u064a|&#10;H\u2082 VERDE|H\u2082 BERDEA|H\u2082 VERD|H\u2082 VERDE|GREEN H\u2082|H\u2082 VERT|GR\u00dcNER H\u2082|H\u2082 VERDE|\u0417\u0415\u041b\u0401\u041d\u042b\u0419 H\u2082|\u7eff\u8272\u6c22\u80fd|GROEN H\u2082|\u0647\u064a\u062f\u0631\u0648\u062c\u064a\u0646 \u0623\u062e\u0636\u0631|&#10;LA HUERTA|BARATZA|L'HORTA|A HORTA|THE GARDEN|LE POTAGER|DER GEM\u00dcSEGARTEN|L'ORTO|\u041e\u0413\u041e\u0420\u041e\u0414|\u83dc\u56ed|DIE TUIN|\u0627\u0644\u0628\u0633\u062a\u0627\u0646|&#10;Sin semilla|Hazirik gabe|Sense llavor|Sen semente|No seed|Sans graine|Kein Samen|Senza semi|\u041d\u0435\u0442 \u0441\u0435\u043c\u044f\u043d|\u6ca1\u6709\u79cd\u5b50|Geen saad|\u0628\u062f\u0648\u0646 \u0628\u0630\u0648\u0631|&#10;Arado|Goldea|Arada|Arado|Plow|Charrue|Pflug|Aratro|\u041f\u043b\u0443\u0433|\u7281|Ploeg|\u0627\u0644\u0645\u062d\u0631\u0627\u062b|&#10;Brazo|Besoa|Bra\u00e7|Brazo|Arm|Bras|Arm|Braccio|\u041c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0442\u043e\u0440|\u673a\u68b0\u81c2|Arm|\u0627\u0644\u0630\u0631\u0627\u0639|&#10;Riego subterr\u00e1neo LUR \u00b7 tinajas de arcilla microporosa|LUR lurpeko ureztatzea \u00b7 buztin mikroporotsuzko untziak|Reg subterrani LUR \u00b7 gerres d'argila microporosa|Rego subterr\u00e1neo LUR \u00b7 talegas de arxila microporosa|LUR underground irrigation \u00b7 microporous clay jars|Irrigation souterraine LUR \u00b7 jarres d'argile microporeuse|LUR-Untergrundbew\u00e4sserung \u00b7 mikropor\u00f6se Tont\u00f6pfe|Irrigazione sotterranea LUR \u00b7 giare di argilla microporosa|\u041f\u043e\u0434\u0437\u0435\u043c\u043d\u044b\u0439 \u043f\u043e\u043b\u0438\u0432 LUR \u00b7 \u0433\u043b\u0438\u043d\u044f\u043d\u044b\u0435 \u043a\u0443\u0432\u0448\u0438\u043d\u044b|LUR\u5730\u4e0b\u704c\u6e89 \u00b7 \u5fae\u5b54\u9676\u7f50|LUR-ondergrondse besproeiing \u00b7 mikroporeuse kleipotte|\u0631\u064a \u062c\u0648\u0641\u064a LUR \u00b7 \u062c\u0631\u0627\u0631 \u0645\u0646 \u0627\u0644\u0637\u064a\u0646 \u0627\u0644\u0645\u0633\u0627\u0645\u064a|&#10;Banco de Semillas|Hazi Bankua|Banc de Llavors|Banco de Sementes|Seed Bank|Banque de graines|Saatgutbank|Banca dei semi|\u0411\u0430\u043d\u043a \u0441\u0435\u043c\u044f\u043d|\u79cd\u5b50\u5e93|Saadbank|\u0628\u0646\u0643 \u0627\u0644\u0628\u0630\u0648\u0631|&#10;Banco de semillas|Hazi bankua|Banc de llavors|Banco de sementes|Seed bank|Banque de graines|Saatgutbank|Banca dei semi|\u0411\u0430\u043d\u043a \u0441\u0435\u043c\u044f\u043d|\u79cd\u5b50\u5e93|Saadbank|\u0628\u0646\u0643 \u0627\u0644\u0628\u0630\u0648\u0631|&#10;semillas conservadas|hazi gordeak|llavors conservades|sementes conservadas|seeds stored|graines conserv\u00e9es|Samen gelagert|semi conservati|\u0441\u0435\u043c\u044f\u043d \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f|\u9897\u79cd\u5b50\u5df2\u4fdd\u5b58|sade bewaar|\u0628\u0630\u0648\u0631 \u0645\u062d\u0641\u0648\u0638\u0629|&#10;Toca para abrir|Ukitu irekitzeko|Toca per obrir|Toca para abrir|Tap to open|Touche pour ouvrir|Zum \u00d6ffnen tippen|Tocca per aprire|\u041d\u0430\u0436\u043c\u0438\u0442\u0435, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043a\u0440\u044b\u0442\u044c|\u70b9\u51fb\u6253\u5f00|Raak om oop te maak|\u0627\u0644\u0645\u0633 \u0644\u0644\u0641\u062a\u062d|&#10;Variedades antiguas y tradicionales. Elige una para cargarla en el tractor|Barietate zahar eta tradizionalak. Aukeratu bat traktorean kargatzeko|Varietats antigues i tradicionals. Tria'n una per carregar-la al tractor|Variedades antigas e tradicionais. Elixe unha para cargala no tractor|Old and traditional varieties. Pick one to load it on the tractor|Vari\u00e9t\u00e9s anciennes et traditionnelles. Choisis-en une pour la charger dans le tracteur|Alte und traditionelle Sorten. W\u00e4hle eine, um sie in den Traktor zu laden|Variet\u00e0 antiche e tradizionali. Scegline una per caricarla sul trattore|\u0421\u0442\u0430\u0440\u0438\u043d\u043d\u044b\u0435 \u0438 \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0441\u043e\u0440\u0442\u0430. \u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043e\u0434\u0438\u043d, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432 \u0442\u0440\u0430\u043a\u0442\u043e\u0440|\u53e4\u8001\u7684\u4f20\u7edf\u54c1\u79cd\u3002\u9009\u4e00\u4e2a\u88c5\u8fdb\u62d6\u62c9\u673a|Ou en tradisionele vari\u00ebteite. Kies een om dit op die trekker te laai|\u0623\u0635\u0646\u0627\u0641 \u0642\u062f\u064a\u0645\u0629 \u0648\u062a\u0642\u0644\u064a\u062f\u064a\u0629. \u0627\u062e\u062a\u0631 \u0648\u0627\u062d\u062f\u064b\u0627 \u0644\u062a\u062d\u0645\u064a\u0644\u0647 \u0639\u0644\u0649 \u0627\u0644\u062c\u0631\u0627\u0631|&#10;sin semilla cargada|hazirik kargatu gabe|sense llavor carregada|sen semente cargada|no seed loaded|aucune graine charg\u00e9e|kein Samen geladen|nessun seme caricato|\u0441\u0435\u043c\u0435\u043d\u0430 \u043d\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u044b|\u672a\u88c5\u8f7d\u79cd\u5b50|geen saad gelaai nie|\u0644\u0627 \u062a\u0648\u062c\u062f \u0628\u0630\u0648\u0631 \u0645\u062d\u0645\u0651\u0644\u0629|&#10;Gestionado por LUR, el sistema inteligente del suelo|LURrek kudeatua, lurzoruaren sistema adimenduna|Gestionat per LUR, el sistema intel\u00b7ligent del s\u00f2l|Xestionado por LUR, o sistema intelixente do solo|Managed by LUR, the smart soil system|G\u00e9r\u00e9 par LUR, le syst\u00e8me intelligent du sol|Verwaltet von LUR, dem intelligenten Bodensystem|Gestito da LUR, il sistema intelligente del suolo|\u0423\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f LUR \u2014 \u0443\u043c\u043d\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439 \u043f\u043e\u0447\u0432\u044b|\u7531LUR\uff08\u667a\u80fd\u571f\u58e4\u7cfb\u7edf\uff09\u7ba1\u7406|Bestuur deur LUR, die slim grondstelsel|\u062a\u062f\u064a\u0631\u0647 LUR\u060c \u0646\u0638\u0627\u0645 \u0627\u0644\u062a\u0631\u0628\u0629 \u0627\u0644\u0630\u0643\u064a|&#10;semillas|haziak|llavors|sementes|seeds|graines|Samen|semi|\u0441\u0435\u043c\u044f\u043d|\u9897\u79cd\u5b50|sade|\u0628\u0630\u0648\u0631|&#10;Cargar|Kargatu|Carrega|Cargar|Load|Charger|Laden|Carica|\u0417\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c|\u88c5\u8f7d|Laai|\u062a\u062d\u0645\u064a\u0644|&#10;Cesta|Saskia|Cistella|Cesta|Basket|Panier|Korb|Cesto|\u041a\u043e\u0440\u0437\u0438\u043d\u0430|\u7bee\u5b50|Mandjie|\u0627\u0644\u0633\u0644\u0629|&#10;Tomate Rosa|Tomate Arrosa|Tom\u00e0quet Rosa|Tomate Rosa|Pink Tomato|Tomate Rose|Rosa Tomate|Pomodoro Rosa|\u0420\u043e\u0437\u043e\u0432\u044b\u0439 \u0442\u043e\u043c\u0430\u0442|\u7c89\u7ea2\u756a\u8304|Pienk Tamatie|\u0637\u0645\u0627\u0637\u0645 \u0648\u0631\u062f\u064a\u0629|&#10;Tomate Negro de Crimea|Krimeako Tomate Beltza|Tom\u00e0quet Negre de Crimea|Tomate Negro de Crimea|Black Crimea Tomato|Tomate Noire de Crim\u00e9e|Schwarze Krim-Tomate|Pomodoro Nero di Crimea|\u0427\u0451\u0440\u043d\u044b\u0439 \u043a\u0440\u044b\u043c\u0441\u043a\u0438\u0439 \u0442\u043e\u043c\u0430\u0442|\u514b\u91cc\u7c73\u4e9a\u9ed1\u756a\u8304|Swart Krim-tamatie|\u0637\u0645\u0627\u0637\u0645 \u0627\u0644\u0642\u0631\u0645 \u0627\u0644\u0633\u0648\u062f\u0627\u0621|&#10;Trigo Espelta|Espelta Garia|Blat Espelta|Trigo Espelta|Spelt Wheat|\u00c9peautre|Dinkelweizen|Farro Spelta|\u0421\u043f\u0435\u043b\u044c\u0442\u0430|\u65af\u4f69\u5c14\u7279\u5c0f\u9ea6|Spelt-koring|\u0642\u0645\u062d \u0627\u0644\u0625\u0633\u0628\u0644\u062a|&#10;Zanahoria Morada|Azenario More|Pastanaga Morada|Cenoria Morada|Purple Carrot|Carotte Violette|Lila Karotte|Carota Viola|\u0424\u0438\u043e\u043b\u0435\u0442\u043e\u0432\u0430\u044f \u043c\u043e\u0440\u043a\u043e\u0432\u044c|\u7d2b\u80e1\u841d\u535c|Pers Wortel|\u062c\u0632\u0631 \u0628\u0646\u0641\u0633\u062c\u064a|&#10;Pimiento de Padr\u00f3n|Padroiko Piperra|Pebrot de Padr\u00f3n|Pemento de Padr\u00f3n|Padr\u00f3n Pepper|Piment de Padr\u00f3n|Padr\u00f3n-Paprika|Peperone di Padr\u00f3n|\u041f\u0435\u0440\u0435\u0446 \u043f\u0430\u0434\u0440\u043e\u043d|\u5e15\u5fb7\u9f99\u8fa3\u6912|Padr\u00f3n-peper|\u0641\u0644\u0641\u0644 \u0628\u0627\u062f\u0631\u0648\u0646|&#10;Patata Kennebec|Kennebec Patata|Patata Kennebec|Pataca Kennebec|Kennebec Potato|Pomme de terre Kennebec|Kennebec-Kartoffel|Patata Kennebec|\u041a\u0430\u0440\u0442\u043e\u0444\u0435\u043b\u044c \u041a\u0435\u043d\u043d\u0435\u0431\u0435\u043a|\u80af\u7eb3\u8d1d\u514b\u571f\u8c46|Kennebec-aartappel|\u0628\u0637\u0627\u0637\u0633 \u0643\u064a\u0646\u064a\u0628\u064a\u0643|&#10;Piel fina, muy dulce y carnoso.|Azal fina, oso gozoa eta mamitsua.|Pell fina, molt dol\u00e7 i carn\u00f3s.|Pel fina, moi doce e carnoso.|Thin skin, very sweet and meaty.|Peau fine, tr\u00e8s sucr\u00e9 et charnu.|D\u00fcnne Haut, sehr s\u00fc\u00df und fleischig.|Buccia sottile, molto dolce e carnoso.|\u0422\u043e\u043d\u043a\u0430\u044f \u043a\u043e\u0436\u0438\u0446\u0430, \u043e\u0447\u0435\u043d\u044c \u0441\u043b\u0430\u0434\u043a\u0438\u0439 \u0438 \u043c\u044f\u0441\u0438\u0441\u0442\u044b\u0439.|\u76ae\u8584\u3001\u5f88\u751c\u3001\u679c\u8089\u539a\u5b9e\u3002|Dun skil, baie soet en vlesig.|\u0642\u0634\u0631\u0629 \u0631\u0642\u064a\u0642\u0629\u060c \u062d\u0644\u0648 \u062c\u062f\u064b\u0627 \u0648\u0644\u062d\u0645\u064a.|&#10;Antiguo y ruso: sabor ahumado y complejo.|Zaharra eta errusiarra: zapore ketua eta konplexua.|Antic i rus: sabor fumat i complex.|Antigo e ruso: sabor afumado e complexo.|Ancient and Russian: smoky, complex flavour.|Ancien et russe : saveur fum\u00e9e et complexe.|Alt und russisch: rauchiger, komplexer Geschmack.|Antico e russo: sapore affumicato e complesso.|\u0421\u0442\u0430\u0440\u0438\u043d\u043d\u044b\u0439 \u0440\u0443\u0441\u0441\u043a\u0438\u0439 \u0441\u043e\u0440\u0442: \u0434\u044b\u043c\u043d\u044b\u0439, \u0441\u043b\u043e\u0436\u043d\u044b\u0439 \u0432\u043a\u0443\u0441.|\u53e4\u8001\u7684\u4fc4\u7f57\u65af\u54c1\u79cd\uff1a\u70df\u718f\u590d\u6742\u7684\u98ce\u5473\u3002|Oud en Russies: rokerige, komplekse smaak.|\u0642\u062f\u064a\u0645 \u0648\u0631\u0648\u0633\u064a: \u0646\u0643\u0647\u0629 \u0645\u062f\u062e\u0646\u0629 \u0648\u0645\u0639\u0642\u062f\u0629.|&#10;Cereal ancestral, r\u00fastico y arom\u00e1tico.|Aintzinako zerealea, zakarra eta aromatikoa.|Cereal ancestral, r\u00fastic i arom\u00e0tic.|Cereal ancestral, r\u00fastico e arom\u00e1tico.|Ancestral grain, rustic and aromatic.|C\u00e9r\u00e9ale ancestrale, rustique et aromatique.|Urgetreide, rustikal und aromatisch.|Cereale ancestrale, rustico e aromatico.|\u0414\u0440\u0435\u0432\u043d\u0438\u0439 \u0437\u043b\u0430\u043a, \u043d\u0435\u043f\u0440\u0438\u0445\u043e\u0442\u043b\u0438\u0432\u044b\u0439 \u0438 \u0430\u0440\u043e\u043c\u0430\u0442\u043d\u044b\u0439.|\u53e4\u8001\u8c37\u7269\uff0c\u6734\u5b9e\u800c\u82b3\u9999\u3002|Voorvaderlike graan, rustiek en aromaties.|\u062d\u0628\u0648\u0628 \u0623\u062c\u062f\u0627\u062f\u060c \u0631\u064a\u0641\u064a\u0629 \u0648\u0639\u0637\u0631\u064a\u0629.|&#10;Variedad milenaria, rica en antocianinas.|Barietate milenarioa, antozianinetan aberatsa.|Varietat mil\u00b7len\u00e0ria, rica en antocians.|Variedade milenaria, rica en antocianinas.|Ancient variety, rich in anthocyanins.|Vari\u00e9t\u00e9 mill\u00e9naire, riche en anthocyanes.|Jahrtausendealte Sorte, reich an Anthocyanen.|Variet\u00e0 millenaria, ricca di antociani.|\u0422\u044b\u0441\u044f\u0447\u0435\u043b\u0435\u0442\u043d\u0438\u0439 \u0441\u043e\u0440\u0442, \u0431\u043e\u0433\u0430\u0442 \u0430\u043d\u0442\u043e\u0446\u0438\u0430\u043d\u0430\u043c\u0438.|\u5343\u5e74\u54c1\u79cd\uff0c\u5bcc\u542b\u82b1\u9752\u7d20\u3002|Eeue-oue vari\u00ebteit, ryk aan antosianiene.|\u0635\u0646\u0641 \u0639\u0631\u064a\u0642 \u063a\u0646\u064a \u0628\u0627\u0644\u0623\u0646\u062b\u0648\u0633\u064a\u0627\u0646\u064a\u0646.|&#10;Unos pican y otros no: pura tradici\u00f3n.|Batzuek pikatzen dute eta besteek ez: tradizio hutsa.|Uns piquen i altres no: pura tradici\u00f3.|Uns pican e outros non: pura tradici\u00f3n.|Some are hot and some aren't: pure tradition.|Certains piquent, d'autres non : pure tradition.|Manche sind scharf, andere nicht: pure Tradition.|Alcuni piccano e altri no: pura tradizione.|\u041e\u0434\u043d\u0438 \u043e\u0441\u0442\u0440\u044b\u0435, \u0434\u0440\u0443\u0433\u0438\u0435 \u043d\u0435\u0442: \u0447\u0438\u0441\u0442\u0430\u044f \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u044f.|\u6709\u7684\u8fa3\u6709\u7684\u4e0d\u8fa3\uff1a\u7eaf\u7cb9\u7684\u4f20\u7edf\u3002|Sommige is skerp en ander nie: suiwer tradisie.|\u0628\u0639\u0636\u0647\u0627 \u062d\u0627\u0631 \u0648\u0628\u0639\u0636\u0647\u0627 \u0644\u0627: \u062a\u0642\u0644\u064a\u062f \u0623\u0635\u064a\u0644.|&#10;Su almid\u00f3n, con las algas, da el biopl\u00e1stico.|Bere almidoiak, algekin batera, bioplastikoa ematen du.|El seu mid\u00f3, amb les algues, dona el biopl\u00e0stic.|O seu amid\u00f3n, coas algas, d\u00e1 o biopl\u00e1stico.|Its starch, with algae, makes bioplastic.|Son amidon, avec les algues, donne le bioplastique.|Seine St\u00e4rke ergibt mit Algen Bioplastik.|Il suo amido, con le alghe, d\u00e0 la bioplastica.|\u0415\u0433\u043e \u043a\u0440\u0430\u0445\u043c\u0430\u043b \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0432\u043e\u0434\u043e\u0440\u043e\u0441\u043b\u044f\u043c\u0438 \u0434\u0430\u0451\u0442 \u0431\u0438\u043e\u043f\u043b\u0430\u0441\u0442\u0438\u043a.|\u5b83\u7684\u6dc0\u7c89\u4e0e\u6d77\u85fb\u4e00\u8d77\u53ef\u5236\u6210\u751f\u7269\u5851\u6599\u3002|Sy stysel gee saam met alge bioplastiek.|\u0646\u0634\u0627\u0624\u0647\u0627 \u0645\u0639 \u0627\u0644\u0637\u062d\u0627\u0644\u0628 \u064a\u0639\u0637\u064a \u0627\u0644\u0628\u0644\u0627\u0633\u062a\u064a\u0643 \u0627\u0644\u062d\u064a\u0648\u064a.|&#10;MERCADO DE ABASTOS|ELIKAGAI AZOKA|MERCAT D'ABASTS|MERCADO DE ABASTOS|FOOD MARKET|MARCH\u00c9 D'APPROVISIONNEMENT|LEBENSMITTELMARKT|MERCATO ALIMENTARE|\u041f\u0420\u041e\u0414\u041e\u0412\u041e\u041b\u042c\u0421\u0422\u0412\u0415\u041d\u041d\u042b\u0419 \u0420\u042b\u041d\u041e\u041a|\u98df\u54c1\u5e02\u573a|VOEDSELMARK|\u0633\u0648\u0642 \u0627\u0644\u062a\u0645\u0648\u064a\u0646|&#10;Frutas y Hortalizas|Fruta eta Barazkiak|Fruites i Hortalisses|Froitas e Hortalizas|Fruit and Vegetables|Fruits et L\u00e9gumes|Obst und Gem\u00fcse|Frutta e Verdura|\u0424\u0440\u0443\u043a\u0442\u044b \u0438 \u043e\u0432\u043e\u0449\u0438|\u6c34\u679c\u548c\u852c\u83dc|Vrugte en Groente|\u0627\u0644\u0641\u0648\u0627\u0643\u0647 \u0648\u0627\u0644\u062e\u0636\u0631\u0648\u0627\u062a|&#10;Semillas y Harinas|Haziak eta Irinak|Llavors i Farines|Sementes e Fari\u00f1as|Seeds and Flours|Graines et Farines|Samen und Mehle|Semi e Farine|\u0421\u0435\u043c\u0435\u043d\u0430 \u0438 \u043c\u0443\u043a\u0430|\u79cd\u5b50\u548c\u9762\u7c89|Sade en Meel|\u0627\u0644\u0628\u0630\u0648\u0631 \u0648\u0627\u0644\u062f\u0642\u064a\u0642|&#10;L\u00e1cteos y Quesos|Esnekiak eta Gaztak|L\u00e0ctics i Formatges|L\u00e1cteos e Queixos|Dairy and Cheeses|Produits laitiers et Fromages|Milchprodukte und K\u00e4se|Latticini e Formaggi|\u041c\u043e\u043b\u043e\u0447\u043d\u044b\u0435 \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u044b \u0438 \u0441\u044b\u0440\u044b|\u4e73\u5236\u54c1\u548c\u5976\u916a|Suiwel en Kase|\u0627\u0644\u0623\u0644\u0628\u0627\u0646 \u0648\u0627\u0644\u0623\u062c\u0628\u0627\u0646|&#10;Legumbres Resilientes|Lekale Erresilienteak|Llegums Resilients|Legumes Resilientes|Resilient Legumes|L\u00e9gumineuses R\u00e9silientes|Robuste H\u00fclsenfr\u00fcchte|Legumi Resilienti|\u0423\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0435 \u0431\u043e\u0431\u043e\u0432\u044b\u0435|\u8010\u65f1\u8c46\u7c7b|Veerkragtige Peulgewasse|\u0628\u0642\u0648\u0644\u064a\u0627\u062a \u0635\u0627\u0645\u062f\u0629|&#10;Apicultura|Erlezaintza|Apicultura|Apicultura|Beekeeping|Apiculture|Imkerei|Apicoltura|\u041f\u0447\u0435\u043b\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u043e|\u517b\u8702|Byeboerdery|\u062a\u0631\u0628\u064a\u0629 \u0627\u0644\u0646\u062d\u0644|&#10;Cuaderno|Koadernoa|Quadern|Caderno|Notebook|Cahier|Heft|Quaderno|\u0422\u0435\u0442\u0440\u0430\u0434\u044c|\u7b14\u8bb0\u672c|Notaboek|\u062f\u0641\u062a\u0631|&#10;Toca|Ukitu|Toca|Toca|Tap|Touche|Tippen|Tocca|\u041d\u0430\u0436\u043c\u0438\u0442\u0435|\u70b9\u51fb|Raak|\u0627\u0644\u0645\u0633|&#10;toca|ukitu|toca|toca|tap|touche|tippen|tocca|\u043d\u0430\u0436\u043c\u0438\u0442\u0435|\u70b9\u51fb|raak|\u0627\u0644\u0645\u0633|&#10;C\u00e1psula de La Huerta|Baratzako Kapsula|C\u00e0psula de l'Horta|C\u00e1psula da Horta|Garden Capsule|Capsule du Potager|Kapsel aus dem Gem\u00fcsegarten|Capsula dell'Orto|\u041a\u0430\u043f\u0441\u0443\u043b\u0430 \u0438\u0437 \u043e\u0433\u043e\u0440\u043e\u0434\u0430|\u83dc\u56ed\u80f6\u56ca|Tuinkapsule|\u0643\u0628\u0633\u0648\u0644\u0629 \u0645\u0646 \u0627\u0644\u0628\u0633\u062a\u0627\u0646|&#10;piezas frescas|pieza freskoak|peces fresques|pezas frescas|fresh pieces|pi\u00e8ces fra\u00eeches|frische St\u00fccke|pezzi freschi|\u0441\u0432\u0435\u0436\u0438\u0445 \u0448\u0442\u0443\u043a|\u4ef6\u65b0\u9c9c\u54c1|vars stukke|\u0642\u0637\u0639 \u0637\u0627\u0632\u062c\u0629|&#10;ZONA INDUSTRIAL|INDUSTRIA EREMUA|ZONA INDUSTRIAL|ZONA INDUSTRIAL|INDUSTRIAL ZONE|ZONE INDUSTRIELLE|INDUSTRIEGEBIET|ZONA INDUSTRIALE|\u041f\u0420\u041e\u041c\u0417\u041e\u041d\u0410|\u5de5\u4e1a\u533a|NYWERHEIDSONE|\u0627\u0644\u0645\u0646\u0637\u0642\u0629 \u0627\u0644\u0635\u0646\u0627\u0639\u064a\u0629|&#10;IMPRESORA|INPRIMAGAILUA|IMPRESSORA|IMPRESORA|PRINTER|IMPRIMANTE|DRUCKER|STAMPANTE|\u041f\u0420\u0418\u041d\u0422\u0415\u0420|\u6253\u5370\u673a|DRUKKER|\u0627\u0644\u0637\u0627\u0628\u0639\u0629|&#10;Cuadro de mandos|Agintaulak|Quadre de comandament|Cadro de mandos|Control panel|Tableau de bord|Schalttafel|Quadro di comando|\u041f\u0430\u043d\u0435\u043b\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f|\u63a7\u5236\u9762\u677f|Beheerpaneel|\u0644\u0648\u062d\u0629 \u0627\u0644\u062a\u062d\u0643\u0645|&#10;Bienestar comunitario|Komunitatearen ongizatea|Benestar comunitari|Benestar comunitario|Community well-being|Bien-\u00eatre communautaire|Gemeinschaftliches Wohlbefinden|Benessere comunitario|\u0411\u043b\u0430\u0433\u043e\u043f\u043e\u043b\u0443\u0447\u0438\u0435 \u043e\u0431\u0449\u0438\u043d\u044b|\u793e\u533a\u798f\u7949|Gemeenskapswelsyn|\u0631\u0641\u0627\u0647\u064a\u0629 \u0627\u0644\u0645\u062c\u062a\u0645\u0639|&#10;BIENESTAR|ONGIZATEA|BENESTAR|BENESTAR|WELL-BEING|BIEN-\u00caTRE|WOHLBEFINDEN|BENESSERE|\u0411\u041b\u0410\u0413\u041e\u041f\u041e\u041b\u0423\u0427\u0418\u0415|\u798f\u7949|WELSYN|\u0627\u0644\u0631\u0641\u0627\u0647\u064a\u0629|&#10;MAPA DEL PUEBLO|HERRIAREN MAPA|MAPA DEL POBLE|MAPA DO POBO|TOWN MAP|CARTE DU VILLAGE|DORFKARTE|MAPPA DEL PAESE|\u041a\u0410\u0420\u0422\u0410 \u0414\u0415\u0420\u0415\u0412\u041d\u0418|\u5c0f\u9547\u5730\u56fe|DORPSKAART|\u062e\u0631\u064a\u0637\u0629 \u0627\u0644\u0642\u0631\u064a\u0629|&#10;RECURSOS|BALIABIDEAK|RECURSOS|RECURSOS|RESOURCES|RESSOURCES|RESSOURCEN|RISORSE|\u0420\u0415\u0421\u0423\u0420\u0421\u042b|\u8d44\u6e90|HULPBRONNE|\u0627\u0644\u0645\u0648\u0627\u0631\u062f|&#10;cosecha|uzta|collita|colleita|harvest|r\u00e9colte|Ernte|raccolto|\u0443\u0440\u043e\u0436\u0430\u0439|\u6536\u6210|oes|\u062d\u0635\u0627\u062f|&#10;legumbres|lekaleak|llegums|legumes|legumes|l\u00e9gumineuses|H\u00fclsenfr\u00fcchte|legumi|\u0431\u043e\u0431\u043e\u0432\u044b\u0435|\u8c46\u7c7b|peulgewasse|\u0628\u0642\u0648\u0644\u064a\u0627\u062a|&#10;Tomates|Tomateak|Tom\u00e0quets|Tomates|Tomatoes|Tomates|Tomaten|Pomodori|\u041f\u043e\u043c\u0438\u0434\u043e\u0440\u044b|\u756a\u8304|Tamaties|\u0637\u0645\u0627\u0637\u0645|&#10;Lechugas|Letxugak|Enciams|Leitugas|Lettuces|Laitues|Salatk\u00f6pfe|Lattughe|\u0421\u0430\u043b\u0430\u0442|\u751f\u83dc|Blaarslaai|\u062e\u0633|&#10;Pimientos|Piperrak|Pebrots|Pementos|Peppers|Poivrons|Paprika|Peperoni|\u041f\u0435\u0440\u0446\u044b|\u751c\u6912|Soetrissies|\u0641\u0644\u0641\u0644|&#10;Berenjenas|Berenjenak|Alberg\u00ednies|Berenxenas|Aubergines|Aubergines|Auberginen|Melanzane|\u0411\u0430\u043a\u043b\u0430\u0436\u0430\u043d\u044b|\u8304\u5b50|Eiervrugte|\u0628\u0627\u0630\u0646\u062c\u0627\u0646|&#10;Harina de trigo|Gari-irina|Farina de blat|Fari\u00f1a de trigo|Wheat flour|Farine de bl\u00e9|Weizenmehl|Farina di grano|\u041f\u0448\u0435\u043d\u0438\u0447\u043d\u0430\u044f \u043c\u0443\u043a\u0430|\u5c0f\u9ea6\u7c89|Koringmeel|\u062f\u0642\u064a\u0642 \u0627\u0644\u0642\u0645\u062d|&#10;Harina integral|Irina osoa|Farina integral|Fari\u00f1a integral|Wholemeal flour|Farine compl\u00e8te|Vollkornmehl|Farina integrale|\u0426\u0435\u043b\u044c\u043d\u043e\u0437\u0435\u0440\u043d\u043e\u0432\u0430\u044f \u043c\u0443\u043a\u0430|\u5168\u9ea6\u7c89|Volkoringmeel|\u062f\u0642\u064a\u0642 \u0643\u0627\u0645\u0644|&#10;Semillas de tomate|Tomate haziak|Llavors de tom\u00e0quet|Sementes de tomate|Tomato seeds|Graines de tomate|Tomatensamen|Semi di pomodoro|\u0421\u0435\u043c\u0435\u043d\u0430 \u043f\u043e\u043c\u0438\u0434\u043e\u0440\u043e\u0432|\u756a\u8304\u79cd\u5b50|Tamatiesaad|\u0628\u0630\u0648\u0631 \u0627\u0644\u0637\u0645\u0627\u0637\u0645|&#10;Semillas de lechuga|Letxuga haziak|Llavors d'enciam|Sementes de leituga|Lettuce seeds|Graines de laitue|Salatsamen|Semi di lattuga|\u0421\u0435\u043c\u0435\u043d\u0430 \u0441\u0430\u043b\u0430\u0442\u0430|\u751f\u83dc\u79cd\u5b50|Blaarslaaisaad|\u0628\u0630\u0648\u0631 \u0627\u0644\u062e\u0633|&#10;Queso curado|Gazta zaharra|Formatge curat|Queixo curado|Cured cheese|Fromage affin\u00e9|Gereifter K\u00e4se|Formaggio stagionato|\u0412\u044b\u0434\u0435\u0440\u0436\u0430\u043d\u043d\u044b\u0439 \u0441\u044b\u0440|\u719f\u6210\u5976\u916a|Gerypte kaas|\u062c\u0628\u0646 \u0645\u0639\u062a\u0651\u0642|&#10;Leche fresca|Esne freskoa|Llet fresca|Leite fresco|Fresh milk|Lait frais|Frische Milch|Latte fresco|\u0421\u0432\u0435\u0436\u0435\u0435 \u043c\u043e\u043b\u043e\u043a\u043e|\u9c9c\u725b\u5976|Vars melk|\u062d\u0644\u064a\u0628 \u0637\u0627\u0632\u062c|&#10;Yogur|Jogurta|Iogurt|Iogur|Yogurt|Yaourt|Joghurt|Yogurt|\u0419\u043e\u0433\u0443\u0440\u0442|\u9178\u5976|Jogurt|\u0632\u0628\u0627\u062f\u064a|&#10;Cuajada|Mamia|Mat\u00f3|Cuallada|Curd|Caill\u00e9|Quark|Cagliata|\u0422\u0432\u043e\u0440\u043e\u0433|\u51dd\u4e73|Wrongel|\u0644\u0628\u0646 \u0631\u0627\u0626\u0628|&#10;Alubia pinta|Babarrun pintoa|Mongeta pinta|Fabas pintas|Pinto beans|Haricots pinto|Pintobohnen|Fagioli pinto|\u0424\u0430\u0441\u043e\u043b\u044c \u043f\u0438\u043d\u0442\u043e|\u6591\u8c46|Pintobone|\u0641\u0627\u0635\u0648\u0644\u064a\u0627\u0621 \u0645\u0628\u0642\u0639\u0629|&#10;Garbanzo|Txitxirioa|Cigr\u00f3|Garavanzo|Chickpea|Pois chiche|Kichererbse|Cece|\u041d\u0443\u0442|\u9e70\u5634\u8c46|Kekerertjie|\u062d\u0645\u0635|&#10;Lenteja pardina|Dilista pardina|Llentia pardina|Lentella pardina|Brown lentil|Lentille brune|Braune Linse|Lenticchia bruna|\u0411\u0443\u0440\u0430\u044f \u0447\u0435\u0447\u0435\u0432\u0438\u0446\u0430|\u8910\u6241\u8c46|Bruin lensie|\u0639\u062f\u0633 \u0628\u0646\u064a|&#10;Carne vegetal|Landare-haragia|Carn vegetal|Carne vexetal|Plant-based meat|Viande v\u00e9g\u00e9tale|Pflanzliches Fleisch|Carne vegetale|\u0420\u0430\u0441\u0442\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0435 \u043c\u044f\u0441\u043e|\u690d\u7269\u8089|Plantaardige vleis|\u0644\u062d\u0645 \u0646\u0628\u0627\u062a\u064a|&#10;Criobanco|Kriobankua|Criobanc|Criobanco|Cryobank|Cryobanque|Kryobank|Criobanca|\u041a\u0440\u0438\u043e\u0431\u0430\u043d\u043a|\u51b7\u51bb\u5e93|Krio-bank|\u0628\u0646\u0643 \u0627\u0644\u062a\u0628\u0631\u064a\u062f|&#10;\u00d3vulos y cord\u00f3n umbilical|Obuluak eta zilbor-hestea|\u00d2vuls i cord\u00f3 umbilical|\u00d3vulos e cord\u00f3n umbilical|Eggs and umbilical cord|Ovocytes et cordon ombilical|Eizellen und Nabelschnur|Ovuli e cordone ombelicale|\u042f\u0439\u0446\u0435\u043a\u043b\u0435\u0442\u043a\u0438 \u0438 \u043f\u0443\u043f\u043e\u0432\u0438\u043d\u0430|\u5375\u5b50\u548c\u8110\u5e26\u8840|Eiers en naelstring|\u0627\u0644\u0628\u0648\u064a\u0636\u0627\u062a \u0648\u0627\u0644\u062d\u0628\u0644 \u0627\u0644\u0633\u0631\u064a|&#10;Estadio|Estadioa|Estadi|Estadio|Stadium|Stade|Stadion|Stadio|\u0421\u0442\u0430\u0434\u0438\u043e\u043d|\u4f53\u80b2\u573a|Stadion|\u0627\u0644\u0645\u0644\u0639\u0628|&#10;Cine hologr\u00e1fico|Zine holografikoa|Cinema hologr\u00e0fic|Cine hologr\u00e1fico|Holographic cinema|Cin\u00e9ma holographique|Holografisches Kino|Cinema olografico|\u0413\u043e\u043b\u043e\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043a\u0438\u043d\u043e|\u5168\u606f\u7535\u5f71|Holografiese fliek|\u0633\u064a\u0646\u0645\u0627 \u0647\u0648\u0644\u0648\u063a\u0631\u0627\u0641\u064a\u0629|&#10;Teatro inmersivo|Antzoki murgilgarria|Teatre immersiu|Teatro inmersivo|Immersive theater|Th\u00e9\u00e2tre immersif|Immersives Theater|Teatro immersivo|\u0418\u043c\u043c\u0435\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u0442\u0435\u0430\u0442\u0440|\u6c89\u6d78\u5f0f\u620f\u5267|Meesleurende teater|\u0645\u0633\u0631\u062d \u063a\u0627\u0645\u0631|&#10;Concierto hologr\u00e1fico|Kontzertu holografikoa|Concert hologr\u00e0fic|Concerto hologr\u00e1fico|Holographic concert|Concert holographique|Holografisches Konzert|Concerto olografico|\u0413\u043e\u043b\u043e\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043a\u043e\u043d\u0446\u0435\u0440\u0442|\u5168\u606f\u6f14\u5531\u4f1a|Holografiese konsert|\u062d\u0641\u0644 \u0647\u0648\u0644\u0648\u063a\u0631\u0627\u0641\u064a|&#10;Partida de la \u00d3pera|Operaren partida|Partida de l'\u00d2pera|Partida da \u00d3pera|The Opera Game|La Partie de l'Op\u00e9ra|Die Opernpartie|La Partita dell'Opera|\u041f\u0430\u0440\u0442\u0438\u044f \u0432 \u043e\u043f\u0435\u0440\u0435|\u6b4c\u5267\u9662\u5bf9\u5c40|Die Opera-wedstryd|\u0645\u0628\u0627\u0631\u0627\u0629 \u0627\u0644\u0623\u0648\u0628\u0631\u0627|&#10;jugada|jokaldia|jugada|xogada|move|coup|Zug|mossa|\u0445\u043e\u0434|\u6b65|skuif|\u0646\u0642\u0644\u0629|&#10;Jaque mate|Xake mate|Escac i mat|Xaque mate|Checkmate|\u00c9chec et mat|Schachmatt|Scacco matto|\u041c\u0430\u0442|\u5c06\u6b7b|Skaakmat|\u0643\u0634 \u0645\u0627\u062a|&#10;Atelier molecular|Atelier molekularra|Atelier molecular|Atelier molecular|Molecular atelier|Atelier mol\u00e9culaire|Molekulares Atelier|Atelier molecolare|\u041c\u043e\u043b\u0435\u043a\u0443\u043b\u044f\u0440\u043d\u043e\u0435 \u0430\u0442\u0435\u043b\u044c\u0435|\u5206\u5b50\u5de5\u574a|Molekul\u00eare atelier|\u0645\u0634\u063a\u0644 \u062c\u0632\u064a\u0626\u064a|&#10;Colecci\u00f3n lista|Bilduma prest|Col\u00b7lecci\u00f3 llesta|Colecci\u00f3n lista|Collection ready|Collection pr\u00eate|Kollektion fertig|Collezione pronta|\u041a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f \u0433\u043e\u0442\u043e\u0432\u0430|\u7cfb\u5217\u5df2\u5b8c\u6210|Versameling gereed|\u0627\u0644\u0645\u062c\u0645\u0648\u0639\u0629 \u062c\u0627\u0647\u0632\u0629|&#10;urbana|hirikoa|urbana|urbana|urban|urbaine|urban|urbana|\u0433\u043e\u0440\u043e\u0434\u0441\u043a\u0430\u044f|\u90fd\u5e02\u98ce|stedelike|\u062d\u0636\u0631\u064a\u0629|&#10;deportiva|kirol-estilokoa|esportiva|deportiva|sporty|sportive|sportlich|sportiva|\u0441\u043f\u043e\u0440\u0442\u0438\u0432\u043d\u0430\u044f|\u8fd0\u52a8\u98ce|sportiewe|\u0631\u064a\u0627\u0636\u064a\u0629|&#10;Urbana|Hirikoa|Urbana|Urbana|Urban|Urbaine|Urban|Urbana|\u0413\u043e\u0440\u043e\u0434\u0441\u043a\u0430\u044f|\u90fd\u5e02\u98ce|Stedelik|\u062d\u0636\u0631\u064a\u0629|&#10;Deportiva|Kirol-estilokoa|Esportiva|Deportiva|Sporty|Sportive|Sportlich|Sportiva|\u0421\u043f\u043e\u0440\u0442\u0438\u0432\u043d\u0430\u044f|\u8fd0\u52a8\u98ce|Sportief|\u0631\u064a\u0627\u0636\u064a\u0629|&#10;Accesorios|Osagarriak|Accessoris|Accesorios|Accessories|Accessoires|Accessoires|Accessori|\u0410\u043a\u0441\u0435\u0441\u0441\u0443\u0430\u0440\u044b|\u914d\u9970|Bykomstighede|\u0625\u0643\u0633\u0633\u0648\u0627\u0631\u0627\u062a|&#10;Pasarela|Pasarela|Passarel\u00b7la|Pasarela|Runway|Podium|Laufsteg|Passerella|\u041f\u043e\u0434\u0438\u0443\u043c|T\u53f0|Loopplank|\u0645\u0646\u0635\u0629 \u0627\u0644\u0639\u0631\u0636|`, D = {};&#10;    FILAS.split('\\n').forEach(l =&gt; { const c = l.split('|'); if (c.length &gt; 1) D[c[0]] = c; });&#10;    `Toca la lupa para acercar el pueblo y mu\u00e9vete con las flechas. Arrastra a una chica a un banco o a una casa.|Ukitu lupa herria hurbiltzeko eta mugitu geziekin. Arrastatu neska bat banku batera edo etxe batera.|Toca la lupa per acostar el poble i mou-te amb les fletxes. Arrossega una xica a un banc o a una casa.|Toca a lupa para achegar o pobo e m\u00f3vete coas frechas. Arrastra unha rapaza a un banco ou a unha casa.|Tap the magnifier to zoom into the town and move with the arrows. Drag a girl to a bench or a house.|Touche la loupe pour zoomer sur le village et d\u00e9place-toi avec les fl\u00e8ches. Glisse une fille vers un banc ou une maison.|Tippe auf die Lupe, um das Dorf heranzuzoomen, und bewege dich mit den Pfeilen. Zieh ein M\u00e4dchen zu einer Bank oder einem Haus.|Tocca la lente per ingrandire il paese e muoviti con le frecce. Trascina una ragazza su una panchina o in una casa.|\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u043d\u0430 \u043b\u0443\u043f\u0443, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u0431\u043b\u0438\u0437\u0438\u0442\u044c \u0434\u0435\u0440\u0435\u0432\u043d\u044e, \u0438 \u0434\u0432\u0438\u0433\u0430\u0439\u0442\u0435\u0441\u044c \u0441\u0442\u0440\u0435\u043b\u043a\u0430\u043c\u0438. \u041f\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u0435 \u0434\u0435\u0432\u043e\u0447\u043a\u0443 \u043d\u0430 \u0441\u043a\u0430\u043c\u0435\u0439\u043a\u0443 \u0438\u043b\u0438 \u0432 \u0434\u043e\u043c.|\u70b9\u6309\u653e\u5927\u955c\u53ef\u653e\u5927\u5c0f\u9547\uff0c\u7528\u65b9\u5411\u952e\u79fb\u52a8\u3002\u628a\u5973\u5b69\u62d6\u5230\u957f\u6905\u6216\u623f\u5b50\u4e0a\u3002|Tik die vergrootglas om die dorp nader te bring en beweeg met die pyle. Sleep 'n meisie na 'n bankie of 'n huis.|\u0627\u0636\u063a\u0637 \u0639\u0644\u0649 \u0627\u0644\u0639\u062f\u0633\u0629 \u0644\u062a\u0642\u0631\u064a\u0628 \u0627\u0644\u0642\u0631\u064a\u0629 \u0648\u062a\u062d\u0631\u0651\u0643 \u0628\u0627\u0644\u0623\u0633\u0647\u0645. \u0627\u0633\u062d\u0628 \u0641\u062a\u0627\u0629 \u0625\u0644\u0649 \u0645\u0642\u0639\u062f \u0623\u0648 \u0625\u0644\u0649 \u0645\u0646\u0632\u0644.|&#10;Arrastra a una chica a un banco, al tranv\u00eda o a una casa. Toca el tabl\u00f3n \ud83d\udccc y el cofre com\u00fan del pueblo (la Kutxa).|Arrastatu neska bat banku batera, tranbiara edo etxe batera. Ukitu \ud83d\udccc iragarki-taula eta herriko kutxa komuna (Kutxa).|Arrossega una xica a un banc, al tramvia o a una casa. Toca el tauler \ud83d\udccc i el cofre com\u00fa del poble (la Kutxa).|Arrastra unha rapaza a un banco, ao tranv\u00eda ou a unha casa. Toca o taboleiro \ud83d\udccc e o cofre com\u00fan do pobo (a Kutxa).|Drag a girl to a bench, the tram or a house. Tap the notice board \ud83d\udccc and the town's shared chest (the Kutxa).|Glisse une fille vers un banc, le tram ou une maison. Touche le panneau \ud83d\udccc et le coffre commun du village (la Kutxa).|Zieh ein M\u00e4dchen zu einer Bank, zur Stra\u00dfenbahn oder zu einem Haus. Tippe auf das Brett \ud83d\udccc und die Gemeinschaftstruhe des Dorfes (die Kutxa).|Trascina una ragazza su una panchina, sul tram o in una casa. Tocca la bacheca \ud83d\udccc e il forziere comune del paese (la Kutxa).|\u041f\u0435\u0440\u0435\u0442\u0430\u0449\u0438\u0442\u0435 \u0434\u0435\u0432\u043e\u0447\u043a\u0443 \u043d\u0430 \u0441\u043a\u0430\u043c\u0435\u0439\u043a\u0443, \u043a \u0442\u0440\u0430\u043c\u0432\u0430\u044e \u0438\u043b\u0438 \u0432 \u0434\u043e\u043c. \u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u043d\u0430 \u0434\u043e\u0441\u043a\u0443 \ud83d\udccc \u0438 \u043e\u0431\u0449\u0438\u0439 \u0441\u0443\u043d\u0434\u0443\u043a \u0434\u0435\u0440\u0435\u0432\u043d\u0438 (\u041a\u0443\u0442xa).|\u628a\u5973\u5b69\u62d6\u5230\u957f\u6905\u3001\u7535\u8f66\u6216\u623f\u5b50\u4e0a\u3002\u70b9\u6309\u516c\u544a\u677f \ud83d\udccc \u548c\u5c0f\u9547\u7684\u516c\u5171\u5b9d\u7bb1\uff08Kutxa\uff09\u3002|Sleep 'n meisie na 'n bankie, die trem of 'n huis. Tik die kennisgewingbord \ud83d\udccc en die dorp se gemeenskaplike kis (die Kutxa).|\u0627\u0633\u062d\u0628 \u0641\u062a\u0627\u0629 \u0625\u0644\u0649 \u0645\u0642\u0639\u062f \u0623\u0648 \u0625\u0644\u0649 \u0627\u0644\u062a\u0631\u0627\u0645 \u0623\u0648 \u0625\u0644\u0649 \u0645\u0646\u0632\u0644. \u0627\u0636\u063a\u0637 \u0639\u0644\u0649 \u0644\u0648\u062d\u0629 \u0627\u0644\u0625\u0639\u0644\u0627\u0646\u0627\u062a \ud83d\udccc \u0648\u0635\u0646\u062f\u0648\u0642 \u0627\u0644\u0642\u0631\u064a\u0629 \u0627\u0644\u0645\u0634\u062a\u0631\u0643 (\u0627\u0644\u0643\u0648\u062a\u0634\u0627).|&#10;Aqu\u00ed las chicas surfean y recogen algas. Toca el cartel \u00abEL PUERTO\u00bb para ir al muelle.|Hemen neskek surfa egiten dute eta algak biltzen dituzte. Ukitu \u00abPORTUA\u00bb kartela kaira joateko.|Aqu\u00ed les xiques fan surf i recullen algues. Toca el cartell \u00abEL PORT\u00bb per anar al moll.|Aqu\u00ed as rapazas fan surf e recollen algas. Toca o cartel \u00abO PORTO\u00bb para ir ao peirao.|Here the girls surf and gather seaweed. Tap the \u00abTHE PORT\u00bb sign to go to the pier.|Ici les filles font du surf et ramassent des algues. Touche le panneau \u00abLE PORT\u00bb pour aller \u00e0 la jet\u00e9e.|Hier surfen die M\u00e4dchen und sammeln Algen. Tippe auf das Schild \u00abDER HAFEN\u00bb, um zum Steg zu gehen.|Qui le ragazze fanno surf e raccolgono alghe. Tocca il cartello \u00abIL PORTO\u00bb per andare al molo.|\u0417\u0434\u0435\u0441\u044c \u0434\u0435\u0432\u043e\u0447\u043a\u0438 \u0441\u0451\u0440\u0444\u044f\u0442 \u0438 \u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0442 \u0432\u043e\u0434\u043e\u0440\u043e\u0441\u043b\u0438. \u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u043d\u0430 \u0442\u0430\u0431\u043b\u0438\u0447\u043a\u0443 \u00ab\u041f\u041e\u0420\u0422\u00bb, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0439\u0442\u0438 \u043d\u0430 \u043f\u0440\u0438\u0447\u0430\u043b.|\u5973\u5b69\u4eec\u5728\u8fd9\u91cc\u51b2\u6d6a\u3001\u91c7\u6d77\u85fb\u3002\u70b9\u6309\u201c\u6e2f\u53e3\u201d\u724c\u5b50\u524d\u5f80\u7801\u5934\u3002|Hier surf die meisies en versamel seewier. Tik die \u00abDIE HAWE\u00bb bord om na die pier te gaan.|\u0647\u0646\u0627 \u062a\u062a\u0632\u0644\u062c \u0627\u0644\u0641\u062a\u064a\u0627\u062a \u0639\u0644\u0649 \u0627\u0644\u0623\u0645\u0648\u0627\u062c \u0648\u062a\u062c\u0645\u0639 \u0627\u0644\u0637\u062d\u0627\u0644\u0628. \u0627\u0636\u063a\u0637 \u0639\u0644\u0649 \u0644\u0627\u0641\u062a\u0629 \u00ab\u0627\u0644\u0645\u064a\u0646\u0627\u0621\u00bb \u0644\u0644\u0630\u0647\u0627\u0628 \u0625\u0644\u0649 \u0627\u0644\u0631\u0635\u064a\u0641.|&#10;Toca la estaci\u00f3n de buceo \ud83e\udd3f para bajar al fondo marino.|Ukitu \ud83e\udd3f urpekaritza-estazioa itsas hondora jaisteko.|Toca l'estaci\u00f3 de busseig \ud83e\udd3f per baixar al fons mar\u00ed.|Toca a estaci\u00f3n de mergullo \ud83e\udd3f para baixar ao fondo mari\u00f1o.|Tap the diving station \ud83e\udd3f to go down to the seabed.|Touche la station de plong\u00e9e \ud83e\udd3f pour descendre au fond marin.|Tippe auf die Tauchstation \ud83e\udd3f, um zum Meeresgrund hinabzutauchen.|Tocca la stazione di immersione \ud83e\udd3f per scendere sul fondale marino.|\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u043d\u0430 \u0441\u0442\u0430\u043d\u0446\u0438\u044e \u0434\u0430\u0439\u0432\u0438\u043d\u0433\u0430 \ud83e\udd3f, \u0447\u0442\u043e\u0431\u044b \u0441\u043f\u0443\u0441\u0442\u0438\u0442\u044c\u0441\u044f \u043d\u0430 \u043c\u043e\u0440\u0441\u043a\u043e\u0435 \u0434\u043d\u043e.|\u70b9\u6309\u6f5c\u6c34\u7ad9 \ud83e\udd3f \u4e0b\u6f5c\u5230\u6d77\u5e95\u3002|Tik die duikstasie \ud83e\udd3f om na die seebodem af te gaan.|\u0627\u0636\u063a\u0637 \u0639\u0644\u0649 \u0645\u062d\u0637\u0629 \u0627\u0644\u063a\u0648\u0635 \ud83e\udd3f \u0644\u0644\u0646\u0632\u0648\u0644 \u0625\u0644\u0649 \u0642\u0627\u0639 \u0627\u0644\u0628\u062d\u0631.|&#10;Toca los animales y las plantas para saber c\u00f3mo se llaman.|Ukitu animaliak eta landareak zer izen duten jakiteko.|Toca els animals i les plantes per saber com es diuen.|Toca os animais e as plantas para saber como se chaman.|Tap the animals and plants to learn their names.|Touche les animaux et les plantes pour conna\u00eetre leur nom.|Tippe auf die Tiere und Pflanzen, um ihre Namen zu erfahren.|Tocca gli animali e le piante per scoprire come si chiamano.|\u041d\u0430\u0436\u0438\u043c\u0430\u0439\u0442\u0435 \u043d\u0430 \u0436\u0438\u0432\u043e\u0442\u043d\u044b\u0445 \u0438 \u0440\u0430\u0441\u0442\u0435\u043d\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u0443\u0437\u043d\u0430\u0442\u044c \u0438\u0445 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f.|\u70b9\u6309\u52a8\u7269\u548c\u690d\u7269\uff0c\u4e86\u89e3\u5b83\u4eec\u7684\u540d\u5b57\u3002|Tik die diere en plante om hul name te leer ken.|\u0627\u0636\u063a\u0637 \u0639\u0644\u0649 \u0627\u0644\u062d\u064a\u0648\u0627\u0646\u0627\u062a \u0648\u0627\u0644\u0646\u0628\u0627\u062a\u0627\u062a \u0644\u062a\u0639\u0631\u0641 \u0623\u0633\u0645\u0627\u0621\u0647\u0627.|&#10;El tractor siembra y las genoides cosechadoras (las BELAR, con casco y visor) recogen la cosecha. Toca el banco de semillas para elegir qu\u00e9 plantar.|Traktoreak ereiten du eta genoide uzta-biltzaileek (BELAR, kaskoa eta bisorea dituztenak) uzta jasotzen dute. Ukitu hazi-banku bat zer landatu aukeratzeko.|El tractor sembra i les genoides collidores (les BELAR, amb casc i visera) recullen la collita. Toca el banc de llavors per triar qu\u00e8 plantar.|O tractor sementa e as xenoides colleitadoras (as BELAR, con casco e viseira) recollen a colleita. Toca o banco de sementes para elixir que plantar.|The tractor sows and the harvester genoids (the BELAR, with helmet and visor) gather the crop. Tap the seed bank to choose what to plant.|Le tracteur s\u00e8me et les g\u00e9no\u00efdes moissonneuses (les BELAR, avec casque et visi\u00e8re) r\u00e9coltent. Touche la banque de graines pour choisir quoi planter.|Der Traktor s\u00e4t und die Erntegenoiden (die BELAR, mit Helm und Visier) bringen die Ernte ein. Tippe auf die Saatgutbank, um zu w\u00e4hlen, was gepflanzt wird.|Il trattore semina e le genoidi raccoglitrici (le BELAR, con casco e visiera) raccolgono il raccolto. Tocca la banca dei semi per scegliere cosa piantare.|\u0422\u0440\u0430\u043a\u0442\u043e\u0440 \u0441\u0435\u0435\u0442, \u0430 \u0433\u0435\u043d\u043e\u0438\u0434\u044b-\u0441\u0431\u043e\u0440\u0449\u0438\u0446\u044b (BELAR, \u0432 \u0448\u043b\u0435\u043c\u0435 \u0441 \u0432\u0438\u0437\u043e\u0440\u043e\u043c) \u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0442 \u0443\u0440\u043e\u0436\u0430\u0439. \u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u043d\u0430 \u0431\u0430\u043d\u043a \u0441\u0435\u043c\u044f\u043d, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0431\u0440\u0430\u0442\u044c, \u0447\u0442\u043e \u0441\u0430\u0436\u0430\u0442\u044c.|\u62d6\u62c9\u673a\u8d1f\u8d23\u64ad\u79cd\uff0c\u6536\u5272\u57fa\u56e0\u4f53\uff08BELAR\uff0c\u6234\u5934\u76d4\u548c\u9762\u7f69\uff09\u8d1f\u8d23\u6536\u83b7\u3002\u70b9\u6309\u79cd\u5b50\u5e93\u9009\u62e9\u8981\u79cd\u690d\u7684\u4f5c\u7269\u3002|Die trekker saai en die oesgeno\u00efede (die BELAR, met helm en visier) pluk die oes. Tik die saadbank om te kies wat om te plant.|\u064a\u0632\u0631\u0639 \u0627\u0644\u062c\u0631\u0627\u0631 \u0648\u062a\u062d\u0635\u062f \u0627\u0644\u062c\u064a\u0646\u0648\u064a\u062f\u0627\u062a (\u0628\u064a\u0644\u0627\u0631\u060c \u0628\u062e\u0648\u0630\u0629 \u0648\u0642\u0646\u0627\u0639) \u0627\u0644\u0645\u062d\u0635\u0648\u0644. \u0627\u0636\u063a\u0637 \u0639\u0644\u0649 \u0628\u0646\u0643 \u0627\u0644\u0628\u0630\u0648\u0631 \u0644\u0627\u062e\u062a\u064a\u0627\u0631 \u0645\u0627 \u0633\u064a\u064f\u0632\u0631\u0639.|&#10;Las chicas compran seg\u00fan su hambre. Toca el cuaderno de la mesa para ver las cuentas.|Neskek gosearen arabera erosten dute. Ukitu mahaiko koadernoa kontuak ikusteko.|Les xiques compren segons la seua gana. Toca el quadern de la taula per veure els comptes.|As rapazas compran segundo a s\u00faa fame. Toca o caderno da mesa para ver as contas.|The girls shop according to their hunger. Tap the notebook on the table to see the accounts.|Les filles font leurs courses selon leur faim. Touche le carnet sur la table pour voir les comptes.|Die M\u00e4dchen kaufen je nach Hunger ein. Tippe auf das Heft auf dem Tisch, um die Abrechnung zu sehen.|Le ragazze fanno la spesa in base alla fame. Tocca il quaderno sul tavolo per vedere i conti.|\u0414\u0435\u0432\u043e\u0447\u043a\u0438 \u043f\u043e\u043a\u0443\u043f\u0430\u044e\u0442 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0433\u043e\u043b\u043e\u0434\u0430. \u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u043d\u0430 \u0442\u0435\u0442\u0440\u0430\u0434\u044c \u043d\u0430 \u0441\u0442\u043e\u043b\u0435, \u0447\u0442\u043e\u0431\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0441\u0447\u0435\u0442\u0430.|\u5973\u5b69\u4eec\u6839\u636e\u9965\u997f\u7a0b\u5ea6\u8d2d\u7269\u3002\u70b9\u6309\u684c\u4e0a\u7684\u7b14\u8bb0\u672c\u67e5\u770b\u8d26\u76ee\u3002|Die meisies koop na gelang van hul honger. Tik die notaboek op die tafel om die rekeninge te sien.|\u062a\u062a\u0633\u0648\u0642 \u0627\u0644\u0641\u062a\u064a\u0627\u062a \u062d\u0633\u0628 \u062c\u0648\u0639\u0647\u0646. \u0627\u0636\u063a\u0637 \u0639\u0644\u0649 \u0627\u0644\u062f\u0641\u062a\u0631 \u0627\u0644\u0645\u0648\u062c\u0648\u062f \u0639\u0644\u0649 \u0627\u0644\u0637\u0627\u0648\u0644\u0629 \u0644\u0631\u0624\u064a\u0629 \u0627\u0644\u062d\u0633\u0627\u0628\u0627\u062a.|&#10;La impresora 3D fabrica cosas para el pueblo. Toca su panel para elegir qu\u00e9 hacer.|3D inprimagailuak gauzak egiten ditu herriarentzat. Ukitu bere panela zer egin aukeratzeko.|La impressora 3D fabrica coses per al poble. Toca el seu panell per triar qu\u00e8 fer.|A impresora 3D fabrica cousas para o pobo. Toca o seu panel para elixir que facer.|The 3D printer makes things for the town. Tap its panel to choose what to make.|L'imprimante 3D fabrique des choses pour le village. Touche son panneau pour choisir quoi faire.|Der 3D-Drucker stellt Dinge f\u00fcr das Dorf her. Tippe auf sein Bedienfeld, um zu w\u00e4hlen, was er tun soll.|La stampante 3D produce cose per il paese. Tocca il suo pannello per scegliere cosa fare.|3D-\u043f\u0440\u0438\u043d\u0442\u0435\u0440 \u0438\u0437\u0433\u043e\u0442\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442 \u0432\u0435\u0449\u0438 \u0434\u043b\u044f \u0434\u0435\u0440\u0435\u0432\u043d\u0438. \u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u043d\u0430 \u0435\u0433\u043e \u043f\u0430\u043d\u0435\u043b\u044c, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0431\u0440\u0430\u0442\u044c, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c.|3D \u6253\u5370\u673a\u4e3a\u5c0f\u9547\u5236\u9020\u7269\u54c1\u3002\u70b9\u6309\u5b83\u7684\u9762\u677f\u9009\u62e9\u8981\u505a\u4ec0\u4e48\u3002|Die 3D-drukker maak goed vir die dorp. Tik sy paneel om te kies wat om te doen.|\u062a\u0635\u0646\u0639 \u0627\u0644\u0637\u0627\u0628\u0639\u0629 \u062b\u0644\u0627\u062b\u064a\u0629 \u0627\u0644\u0623\u0628\u0639\u0627\u062f \u0623\u0634\u064a\u0627\u0621 \u0644\u0644\u0642\u0631\u064a\u0629. \u0627\u0636\u063a\u0637 \u0639\u0644\u0649 \u0644\u0648\u062d\u062a\u0647\u0627 \u0644\u0627\u062e\u062a\u064a\u0627\u0631 \u0645\u0627 \u062a\u0635\u0646\u0639\u0647.|&#10;Las vecinas entrenan aqu\u00ed cuando les apetece. Si quieres, toca las m\u00e1quinas.|Auzokideek hemen entrenatzen dute nahi dutenean. Nahi baduzu, ukitu makinak.|Les ve\u00efnes entrenen ac\u00ed quan els ve de gust. Si vols, toca les m\u00e0quines.|As veci\u00f1as adestran aqu\u00ed cando lles apetece. Se queres, toca as m\u00e1quinas.|The neighbours train here whenever they feel like it. If you want, tap the machines.|Les voisines s'entra\u00eenent ici quand elles en ont envie. Si tu veux, touche les machines.|Die Nachbarinnen trainieren hier, wann immer sie Lust haben. Wenn du magst, tippe auf die Ger\u00e4te.|Le vicine si allenano qui quando ne hanno voglia. Se vuoi, tocca le macchine.|\u0421\u043e\u0441\u0435\u0434\u043a\u0438 \u0437\u0430\u043d\u0438\u043c\u0430\u044e\u0442\u0441\u044f \u0437\u0434\u0435\u0441\u044c, \u043a\u043e\u0433\u0434\u0430 \u0437\u0430\u0445\u043e\u0442\u044f\u0442. \u0415\u0441\u043b\u0438 \u0445\u043e\u0442\u0438\u0442\u0435, \u043d\u0430\u0436\u043c\u0438\u0442\u0435 \u043d\u0430 \u0442\u0440\u0435\u043d\u0430\u0436\u0451\u0440\u044b.|\u90bb\u5c45\u4eec\u60f3\u7ec3\u7684\u65f6\u5019\u5c31\u6765\u8fd9\u91cc\u3002\u4f60\u4e5f\u53ef\u4ee5\u70b9\u6309\u5668\u68b0\u3002|Die bure oefen hier wanneer hulle lus is. As jy wil, tik die toestelle.|\u062a\u062a\u062f\u0631\u0651\u0628 \u0627\u0644\u062c\u0627\u0631\u0627\u062a \u0647\u0646\u0627 \u0645\u062a\u0649 \u0634\u0626\u0646. \u0625\u0646 \u0623\u0631\u062f\u062a\u060c \u0627\u0636\u063a\u0637 \u0639\u0644\u0649 \u0627\u0644\u0623\u062c\u0647\u0632\u0629.|&#10;Toca un panel de la pared para cambiar los datos del pueblo que se muestran.|Ukitu hormako panel bat erakusten diren herriko datuak aldatzeko.|Toca un panell de la paret per canviar les dades del poble que es mostren.|Toca un panel da parede para cambiar os datos do pobo que se amosan.|Tap a wall panel to change which town data is shown.|Touche un panneau du mur pour changer les donn\u00e9es du village affich\u00e9es.|Tippe auf eine Wandtafel, um die angezeigten Dorfdaten zu wechseln.|Tocca un pannello alla parete per cambiare i dati del paese mostrati.|\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u044c \u043d\u0430 \u0441\u0442\u0435\u043d\u0435, \u0447\u0442\u043e\u0431\u044b \u0441\u043c\u0435\u043d\u0438\u0442\u044c \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u0435\u0440\u0435\u0432\u043d\u0438.|\u70b9\u6309\u5899\u4e0a\u7684\u9762\u677f\uff0c\u5207\u6362\u663e\u793a\u7684\u5c0f\u9547\u6570\u636e\u3002|Tik 'n muurpaneel om te verander watter dorpdata gewys word.|\u0627\u0636\u063a\u0637 \u0639\u0644\u0649 \u0644\u0648\u062d\u0629 \u0627\u0644\u062d\u0627\u0626\u0637 \u0644\u062a\u063a\u064a\u064a\u0631 \u0628\u064a\u0627\u0646\u0627\u062a \u0627\u0644\u0642\u0631\u064a\u0629 \u0627\u0644\u0645\u0639\u0631\u0648\u0636\u0629.|&#10;pantalla central MIIG26 ARENA|MIIG26 ARENA pantaila nagusia|pantalla central MIIG26 ARENA|pantalla central MIIG26 ARENA|central screen MIIG26 ARENA|\u00e9cran central MIIG26 ARENA|Zentralbildschirm MIIG26 ARENA|schermo centrale MIIG26 ARENA|\u0446\u0435\u043d\u0442\u0440\u0430\u043b\u044c\u043d\u044b\u0439 \u044d\u043a\u0440\u0430\u043d MIIG26 ARENA|\u4e2d\u592e\u5c4f\u5e55 MIIG26 ARENA|sentrale skerm MIIG26 ARENA|\u0627\u0644\u0634\u0627\u0634\u0629 \u0627\u0644\u0645\u0631\u0643\u0632\u064a\u0629 MIIG26 ARENA|&#10;Dise\u00f1ando urbana|Hiri-jantzia diseinatzen|Dissenyant urbana|Dese\u00f1ando urbana|Designing urban wear|Cr\u00e9ation urbaine|Urbane Mode im Entwurf|Progettando urbana|\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0433\u043e\u0440\u043e\u0434\u0441\u043a\u043e\u0439 \u0441\u0442\u0438\u043b\u044c|\u8bbe\u8ba1\u90fd\u5e02\u98ce|Ontwerp stedelike mode|\u062a\u0635\u0645\u064a\u0645 \u0623\u0632\u064a\u0627\u0621 \u062d\u0636\u0631\u064a\u0629|&#10;Dise\u00f1ando deportiva|Kirol-jantzia diseinatzen|Dissenyant esportiva|Dese\u00f1ando deportiva|Designing sportswear|Cr\u00e9ation sportive|Sportmode im Entwurf|Progettando sportiva|\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u043f\u043e\u0440\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0442\u0438\u043b\u044c|\u8bbe\u8ba1\u8fd0\u52a8\u98ce|Ontwerp sportklere|\u062a\u0635\u0645\u064a\u0645 \u0623\u0632\u064a\u0627\u0621 \u0631\u064a\u0627\u0636\u064a\u0629|&#10;producci\u00f3n ap\u00edcola|erlezaintza-ekoizpena|producci\u00f3 ap\u00edcola|produci\u00f3n ap\u00edcola|beekeeping output|production apicole|Imkerei-Ertrag|produzione apicola|\u043f\u0440\u043e\u0434\u0443\u043a\u0446\u0438\u044f \u043f\u0447\u0435\u043b\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430|\u517b\u8702\u4ea7\u51fa|byeprodukte|\u0625\u0646\u062a\u0627\u062c \u0627\u0644\u0646\u062d\u0644|&#10;se ha ido a surfear.|joan da surfa egitera.|ha anat a fer surf.|foi surfear.|has gone surfing.|est partie surfer.|ist surfen gegangen.|\u00e8 andata a fare surf.|\u0443\u0448\u043b\u0430 \u0441\u0451\u0440\u0444\u0438\u0442\u044c.|\u53bb\u51b2\u6d6a\u4e86\u3002|het gaan branderplank ry.|\u0630\u0647\u0628\u062a \u0644\u062a\u062a\u0632\u0644\u062c \u0639\u0644\u0649 \u0627\u0644\u0623\u0645\u0648\u0627\u062c.|&#10;se ha sumergido en la biblioteca.|liburutegian murgildu da.|s'ha submergit a la biblioteca.|mergullouse na biblioteca.|has dived into the library.|s'est plong\u00e9e dans la biblioth\u00e8que.|ist in die Bibliothek eingetaucht.|si \u00e8 immersa nella biblioteca.|\u043f\u043e\u0433\u0440\u0443\u0437\u0438\u043b\u0430\u0441\u044c \u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443.|\u6c89\u6d78\u5728\u56fe\u4e66\u9986\u91cc\u3002|het in die biblioteek ingeduik.|\u0627\u0646\u063a\u0645\u0633\u062a \u0641\u064a \u0627\u0644\u0645\u0643\u062a\u0628\u0629.|&#10;entrena en el gimnasio.|gimnasioan entrenatzen ari da.|entrena al gimn\u00e0s.|adestra no ximnasio.|is training at the gym.|s'entra\u00eene \u00e0 la salle de sport.|trainiert im Fitnessstudio.|si allena in palestra.|\u0442\u0440\u0435\u043d\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 \u0441\u043f\u043e\u0440\u0442\u0437\u0430\u043b\u0435.|\u5728\u5065\u8eab\u623f\u953b\u70bc\u3002|oefen by die gimnasium.|\u062a\u062a\u062f\u0631\u0651\u0628 \u0641\u064a \u0627\u0644\u0646\u0627\u062f\u064a \u0627\u0644\u0631\u064a\u0627\u0636\u064a.|&#10;cuida la huerta.|baratza zaintzen du.|cuida l'hort.|coida a horta.|tends the garden.|s'occupe du potager.|pflegt den Gem\u00fcsegarten.|cura l'orto.|\u0443\u0445\u0430\u0436\u0438\u0432\u0430\u0435\u0442 \u0437\u0430 \u043e\u0433\u043e\u0440\u043e\u0434\u043e\u043c.|\u7167\u6599\u83dc\u56ed\u3002|versorg die tuin.|\u062a\u0639\u062a\u0646\u064a \u0628\u0627\u0644\u0628\u0633\u062a\u0627\u0646.|&#10;cocina en casa.|etxean sukaldatzen ari da.|cuina a casa.|coci\u00f1a na casa.|is cooking at home.|cuisine \u00e0 la maison.|kocht zu Hause.|cucina a casa.|\u0433\u043e\u0442\u043e\u0432\u0438\u0442 \u0434\u043e\u043c\u0430.|\u5728\u5bb6\u505a\u996d\u3002|kook by die huis.|\u062a\u0637\u0628\u062e \u0641\u064a \u0627\u0644\u0645\u0646\u0632\u0644.|&#10;hace la compra.|erosketak egiten ditu.|fa la compra.|fai a compra.|is doing the shopping.|fait ses courses.|geht einkaufen.|fa la spesa.|\u0434\u0435\u043b\u0430\u0435\u0442 \u043f\u043e\u043a\u0443\u043f\u043a\u0438.|\u5728\u4e70\u4e1c\u897f\u3002|doen inkopies.|\u062a\u062a\u0633\u0648\u0642.|&#10;da un paseo.|paseo bat ematen du.|fa un passeig.|d\u00e1 un paseo.|takes a stroll.|fait une promenade.|macht einen Spaziergang.|fa una passeggiata.|\u0433\u0443\u043b\u044f\u0435\u0442.|\u5728\u6563\u6b65\u3002|gaan stap.|\u062a\u062a\u0645\u0634\u0649.|&#10;se ha ido a descansar.|atseden hartzera joan da.|ha anat a descansar.|foi descansar.|has gone to rest.|est partie se reposer.|hat sich ausruhen gelegt.|\u00e8 andata a riposare.|\u0443\u0448\u043b\u0430 \u043e\u0442\u0434\u044b\u0445\u0430\u0442\u044c.|\u53bb\u4f11\u606f\u4e86\u3002|het gaan rus.|\u0630\u0647\u0628\u062a \u0644\u062a\u0631\u062a\u0627\u062d.|&#10;coge el tranv\u00eda.|tranbia hartzen du.|agafa el tramvia.|colle o tranv\u00eda.|catches the tram.|prend le tram.|nimmt die Stra\u00dfenbahn.|prende il tram.|\u0441\u0430\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u0442\u0440\u0430\u043c\u0432\u0430\u0439.|\u642d\u4e58\u7535\u8f66\u3002|neem die trem.|\u062a\u0633\u062a\u0642\u0644 \u0627\u0644\u062a\u0631\u0627\u0645.|&#10;toma el sol en la playa.|hondartzan eguzkia hartzen du.|pren el sol a la platja.|toma o sol na praia.|sunbathes on the beach.|prend le soleil sur la plage.|sonnt sich am Strand.|prende il sole in spiaggia.|\u0437\u0430\u0433\u043e\u0440\u0430\u0435\u0442 \u043d\u0430 \u043f\u043b\u044f\u0436\u0435.|\u5728\u6d77\u6ee9\u6652\u592a\u9633\u3002|son op die strand.|\u062a\u0633\u062a\u062d\u0645 \u0628\u0627\u0644\u0634\u0645\u0633 \u0639\u0644\u0649 \u0627\u0644\u0634\u0627\u0637\u0626.|&#10;Amanece en el pueblo.|Egunsentia herrian.|Es fa de dia al poble.|Amencer no pobo.|Dawn breaks over the town.|L'aube se l\u00e8ve sur le village.|Der Tag bricht im Dorf an.|Albeggia nel paese.|\u0412 \u0434\u0435\u0440\u0435\u0432\u043d\u0435 \u0440\u0430\u0441\u0441\u0432\u0435\u0442.|\u5c0f\u9547\u8fce\u6765\u9ece\u660e\u3002|Dit daag oor die dorp.|\u064a\u0628\u0632\u063a \u0627\u0644\u0641\u062c\u0631 \u0639\u0644\u0649 \u0627\u0644\u0642\u0631\u064a\u0629.|&#10;Cae la noche sobre el pueblo.|Gaua dator herrira.|Cau la nit sobre el poble.|Cae a noite sobre o pobo.|Night falls over the town.|La nuit tombe sur le village.|Die Nacht senkt sich \u00fcber das Dorf.|Cala la notte sul paese.|\u041d\u0430 \u0434\u0435\u0440\u0435\u0432\u043d\u044e \u043e\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u0447\u044c.|\u591c\u5e55\u964d\u4e34\u5c0f\u9547\u3002|Die nag val oor die dorp.|\u064a\u062d\u0644\u0651 \u0627\u0644\u0644\u064a\u0644 \u0639\u0644\u0649 \u0627\u0644\u0642\u0631\u064a\u0629.|&#10;Empieza la primavera: el pueblo florece.|Udaberria hasi da: herria loratzen da.|Comen\u00e7a la primavera: el poble floreix.|Comeza a primavera: o pobo florece.|Spring begins: the town blooms.|Le printemps commence : le village fleurit.|Der Fr\u00fchling beginnt: das Dorf bl\u00fcht auf.|Inizia la primavera: il paese fiorisce.|\u041d\u0430\u0447\u0430\u043b\u0430\u0441\u044c \u0432\u0435\u0441\u043d\u0430: \u0434\u0435\u0440\u0435\u0432\u043d\u044f \u0440\u0430\u0441\u0446\u0432\u0435\u0442\u0430\u0435\u0442.|\u6625\u5929\u5f00\u59cb\u4e86\uff1a\u5c0f\u9547\u7e41\u82b1\u76db\u5f00\u3002|Die lente begin: die dorp bloei.|\u064a\u0628\u062f\u0623 \u0627\u0644\u0631\u0628\u064a\u0639: \u0627\u0644\u0642\u0631\u064a\u0629 \u062a\u0632\u0647\u0631.|&#10;Empieza el verano: d\u00edas largos y mucho sol.|Uda hasi da: egun luzeak eta eguzki asko.|Comen\u00e7a l'estiu: dies llargs i molt de sol.|Comeza o ver\u00e1n: d\u00edas longos e moito sol.|Summer begins: long days and lots of sun.|L'\u00e9t\u00e9 commence : longues journ\u00e9es et beaucoup de soleil.|Der Sommer beginnt: lange Tage und viel Sonne.|Inizia l'estate: giorni lunghi e tanto sole.|\u041d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u043b\u0435\u0442\u043e: \u0434\u043b\u0438\u043d\u043d\u044b\u0435 \u0434\u043d\u0438 \u0438 \u043c\u043d\u043e\u0433\u043e \u0441\u043e\u043b\u043d\u0446\u0430.|\u590f\u5929\u5f00\u59cb\u4e86\uff1a\u767d\u663c\u6f2b\u957f\uff0c\u9633\u5149\u5145\u8db3\u3002|Die somer begin: lang dae en baie son.|\u064a\u0628\u062f\u0623 \u0627\u0644\u0635\u064a\u0641: \u0623\u064a\u0627\u0645 \u0637\u0648\u064a\u0644\u0629 \u0648\u0634\u0645\u0633 \u0648\u0641\u064a\u0631\u0629.|&#10;Empieza el oto\u00f1o: el pueblo se viste de hojas.|Udazkena hasi da: herria hostoz jantzi da.|Comen\u00e7a la tardor: el poble es vesteix de fulles.|Comeza o outono: o pobo v\u00edstese de follas.|Autumn begins: the town dresses in leaves.|L'automne commence : le village se couvre de feuilles.|Der Herbst beginnt: das Dorf kleidet sich in Laub.|Inizia l'autunno: il paese si veste di foglie.|\u041d\u0430\u0447\u0430\u043b\u0430\u0441\u044c \u043e\u0441\u0435\u043d\u044c: \u0434\u0435\u0440\u0435\u0432\u043d\u044f \u043e\u0434\u0435\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043b\u0438\u0441\u0442\u044c\u044f.|\u79cb\u5929\u5f00\u59cb\u4e86\uff1a\u5c0f\u9547\u62ab\u4e0a\u843d\u53f6\u3002|Die herfs begin: die dorp trek blare aan.|\u064a\u0628\u062f\u0623 \u0627\u0644\u062e\u0631\u064a\u0641: \u062a\u0643\u062a\u0633\u064a \u0627\u0644\u0642\u0631\u064a\u0629 \u0628\u0627\u0644\u0623\u0648\u0631\u0627\u0642.|&#10;Empieza el invierno: las abejas se recogen.|Negua hasi da: erleak bildu egiten dira.|Comen\u00e7a l'hivern: les abelles es recullen.|Comeza o inverno: as abellas rec\u00f3llense.|Winter begins: the bees huddle inside.|L'hiver commence : les abeilles se retirent.|Der Winter beginnt: die Bienen ziehen sich zur\u00fcck.|Inizia l'inverno: le api si ritirano.|\u041d\u0430\u0447\u0430\u043b\u0430\u0441\u044c \u0437\u0438\u043c\u0430: \u043f\u0447\u0451\u043b\u044b \u043f\u0440\u044f\u0447\u0443\u0442\u0441\u044f \u0432 \u0443\u043b\u044c\u0438.|\u51ac\u5929\u5f00\u59cb\u4e86\uff1a\u871c\u8702\u56de\u5de2\u8fc7\u51ac\u3002|Die winter begin: die bye trek terug.|\u064a\u0628\u062f\u0623 \u0627\u0644\u0634\u062a\u0627\u0621: \u062a\u0623\u0648\u064a \u0627\u0644\u0646\u062d\u0644 \u0625\u0644\u0649 \u062e\u0644\u0627\u064a\u0627\u0647\u0627.|&#10;Sube el metano del fondo marino: el mar pide calma.|Itsas hondoko metanoa igotzen da: itsasoak lasaitasuna eskatzen du.|Puja el met\u00e0 del fons mar\u00ed: el mar demana calma.|Sobe o metano do fondo mari\u00f1o: o mar pide calma.|Methane rises on the seabed: the sea asks for calm.|Le m\u00e9thane monte au fond de la mer : la mer demande du calme.|Das Methan am Meeresgrund steigt: das Meer braucht Ruhe.|Sale il metano sul fondale: il mare chiede calma.|\u0420\u0430\u0441\u0442\u0451\u0442 \u043c\u0435\u0442\u0430\u043d \u043d\u0430 \u043c\u043e\u0440\u0441\u043a\u043e\u043c \u0434\u043d\u0435: \u043c\u043e\u0440\u0435 \u043f\u0440\u043e\u0441\u0438\u0442 \u043f\u043e\u043a\u043e\u044f.|\u6d77\u5e95\u7532\u70f7\u4e0a\u5347\uff1a\u5927\u6d77\u9700\u8981\u5e73\u9759\u3002|Metaan styg op die seebodem: die see vra rus.|\u064a\u0631\u062a\u0641\u0639 \u0627\u0644\u0645\u064a\u062b\u0627\u0646 \u0641\u064a \u0642\u0627\u0639 \u0627\u0644\u0628\u062d\u0631: \u0627\u0644\u0628\u062d\u0631 \u064a\u0637\u0644\u0628 \u0627\u0644\u0647\u062f\u0648\u0621.|&#10;Crece la actividad s\u00edsmica bajo el mar.|Itsaspeko jarduera sismikoa areagotzen da.|Creix l'activitat s\u00edsmica sota el mar.|Medra a actividade s\u00edsmica baixo o mar.|Seismic activity grows beneath the sea.|L'activit\u00e9 sismique augmente sous la mer.|Die seismische Aktivit\u00e4t unter dem Meer nimmt zu.|Cresce l'attivit\u00e0 sismica sotto il mare.|\u041f\u043e\u0434 \u043c\u043e\u0440\u0435\u043c \u0440\u0430\u0441\u0442\u0451\u0442 \u0441\u0435\u0439\u0441\u043c\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0441\u0442\u044c.|\u6d77\u5e95\u5730\u9707\u6d3b\u52a8\u589e\u5f3a\u3002|Seismiese aktiwiteit neem onder die see toe.|\u064a\u0632\u062f\u0627\u062f \u0627\u0644\u0646\u0634\u0627\u0637 \u0627\u0644\u0632\u0644\u0632\u0627\u0644\u064a \u062a\u062d\u062a \u0627\u0644\u0628\u062d\u0631.|&#10;aventurera|abenturazalea|aventurera|aventureira|adventurous|aventuri\u00e8re|abenteuerlustig|avventurosa|\u0430\u0432\u0430\u043d\u0442\u044e\u0440\u043d\u0430\u044f|\u7231\u5192\u9669|avontuurlustig|\u0645\u063a\u0627\u0645\u0631\u0629|&#10;t\u00edmida|lotsatia|t\u00edmida|t\u00edmida|shy|timide|sch\u00fcchtern|timida|\u0437\u0430\u0441\u0442\u0435\u043d\u0447\u0438\u0432\u0430\u044f|\u5bb3\u7f9e|skaam|\u062e\u062c\u0648\u0644\u0629|&#10;so\u00f1adora|ametsezkoa|somiadora|so\u00f1adora|dreamy|r\u00eaveuse|vertr\u00e4umt|sognatrice|\u043c\u0435\u0447\u0442\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f|\u7231\u5e7b\u60f3|dromerig|\u062d\u0627\u0644\u0645\u0629|&#10;combativa|borrokalaria|combativa|combativa|combative|combative|k\u00e4mpferisch|combattiva|\u0431\u043e\u0435\u0432\u0430\u044f|\u597d\u6597|veglustig|\u0645\u0642\u0627\u062a\u0644\u0629|&#10;extrovertida|estrobertitua|extravertida|extrovertida|outgoing|extravertie|extrovertiert|estroversa|\u043e\u0431\u0449\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f|\u5916\u5411|ekstroverties|\u0645\u0646\u0641\u062a\u062d\u0629|&#10;met\u00f3dica|metodikoa|met\u00f2dica|met\u00f3dica|methodical|m\u00e9thodique|methodisch|metodica|\u043c\u0435\u0442\u043e\u0434\u0438\u0447\u043d\u0430\u044f|\u6709\u6761\u7406|metodies|\u0645\u0646\u0647\u062c\u064a\u0629|&#10;vaga|alferra|mandrosa|preguiceira|lazy|paresseuse|faul|pigra|\u043b\u0435\u043d\u0438\u0432\u0430\u044f|\u61d2\u6563|lui|\u0643\u0633\u0648\u0644\u0629|&#10;curiosa|jakintsua|curiosa|curiosa|curious|curieuse|neugierig|curiosa|\u043b\u044e\u0431\u043e\u043f\u044b\u0442\u043d\u0430\u044f|\u597d\u5947|nuuskierig|\u0641\u0636\u0648\u0644\u064a\u0629|&#10;hace un momento|orain dela gutxi|fa un moment|hai un momento|a moment ago|il y a un instant|gerade eben|poco fa|\u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u043e|\u521a\u521a|netnou|\u0645\u0646\u0630 \u0644\u062d\u0638\u0629|&#10;hace|duela|fa|hai|ago|il y a|vor|fa|\u043d\u0430\u0437\u0430\u0434|\u524d|gelede|\u0645\u0646\u0630|&#10;Tabl\u00f3n de ChicaChica|ChicaChicako iragarki-taula|Tauler de ChicaChica|Taboleiro de ChicaChica|ChicaChica Notice Board|Tableau d'affichage de ChicaChica|ChicaChica-Anschlagbrett|Bacheca di ChicaChica|\u0414\u043e\u0441\u043a\u0430 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0439 \u0427\u0438\u043a\u0430\u0427\u0438\u043a\u0430|\u5947\u5361\u5947\u5361\u516c\u544a\u677f|ChicaChica Kennisgewingbord|\u0644\u0648\u062d\u0629 \u0625\u0639\u0644\u0627\u0646\u0627\u062a \u062a\u0634\u064a\u0643\u0627\u062a\u0634\u064a\u0643\u0627|&#10;Sonido del mar|Itsasoaren soinua|So del mar|Son do mar|Sound of the sea|Son de la mer|Meeresrauschen|Suono del mare|\u0417\u0432\u0443\u043a \u043c\u043e\u0440\u044f|\u6d77\u6d6a\u58f0|Klank van die see|\u0635\u0648\u062a \u0627\u0644\u0628\u062d\u0631|&#10;Haz doble toque sobre una chica para seguirla; otro doble toque la suelta.|Sakatu birritan neska bati jarraitzeko; beste bi sakatuk utziko du.|Fes doble toc sobre una xica per seguir-la; un altre doble toc l'amolla.|Fai dobre toque sobre unha rapaza para seguila; outro dobre toque solta.|Double-tap a girl to follow her; double-tap again to let her go.|Touche deux fois une fille pour la suivre ; deux fois encore pour la l\u00e2cher.|Tippe zweimal auf ein M\u00e4dchen, um ihr zu folgen; nochmal zweimal, um sie loszulassen.|Tocca due volte una ragazza per seguirla; altri due tocchi per lasciarla.|\u0414\u0432\u0430\u0436\u0434\u044b \u043a\u043e\u0441\u043d\u0438\u0441\u044c \u0434\u0435\u0432\u0443\u0448\u043a\u0438, \u0447\u0442\u043e\u0431\u044b \u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u0437\u0430 \u043d\u0435\u0439; \u0435\u0449\u0451 \u0434\u0432\u0430 \u043a\u0430\u0441\u0430\u043d\u0438\u044f \u2014 \u043e\u0442\u043f\u0443\u0441\u0442\u0438\u0442\u044c.|\u53cc\u51fb\u4e00\u4f4d\u5973\u5b69\u5373\u53ef\u8ddf\u968f\u5979\uff1b\u518d\u53cc\u51fb\u5373\u53ef\u653e\u5f00\u3002|Tik twee keer op 'n meisie om haar te volg; weer twee keer om haar te laat gaan.|\u0627\u0646\u0642\u0631 \u0645\u0631\u062a\u064a\u0646 \u0639\u0644\u0649 \u0641\u062a\u0627\u0629 \u0644\u0645\u062a\u0627\u0628\u0639\u062a\u0647\u0627\u061b \u0648\u0627\u0646\u0642\u0631 \u0645\u0631\u062a\u064a\u0646 \u0645\u062c\u062f\u062f\u064b\u0627 \u0644\u062a\u0631\u0643\u0647\u0627.|&#10;El tabl\u00f3n \ud83d\udccc cuenta lo que pasa en el pueblo.|Iragarki-taulak herrian gertatzen dena kontatzen du \ud83d\udccc.|El tauler \ud83d\udccc explica el que passa al poble.|O taboleiro \ud83d\udccc conta o que pasa no pobo.|The notice board \ud83d\udccc tells what happens in the village.|Le tableau \ud83d\udccc raconte ce qui se passe au village.|Das Anschlagbrett \ud83d\udccc erz\u00e4hlt, was im Dorf passiert.|La bacheca \ud83d\udccc racconta cosa succede nel paese.|\u0414\u043e\u0441\u043a\u0430 \ud83d\udccc \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u0434\u0435\u0440\u0435\u0432\u043d\u0435.|\u516c\u544a\u677f\ud83d\udccc\u8bb2\u8ff0\u5c0f\u9547\u91cc\u53d1\u751f\u7684\u4e8b\u3002|Die kennisgewingbord \ud83d\udccc vertel wat in die dorp gebeur.|\u0644\u0648\u062d\u0629 \u0627\u0644\u0625\u0639\u0644\u0627\u0646\u0627\u062a \ud83d\udccc \u062a\u0631\u0648\u064a \u0645\u0627 \u064a\u062d\u062f\u062b \u0641\u064a \u0627\u0644\u0642\u0631\u064a\u0629.|&#10;Nopales|Nopalak|Nopals|Nopais|Prickly pear pads|Nopals|Nopales (Kaktusfeigenbl\u00e4tter)|Nopali|\u041d\u043e\u043f\u0430\u043b\u0435\u0441|\u4ed9\u4eba\u638c\u7247|Turksvy-blare|\u0646\u0648\u0628\u0627\u0644|&#10;Moringa y kale|Moringa eta kalea|Moringa i kale|Moringa e kale|Moringa and kale|Moringa et chou kale|Moringa und Gr\u00fcnkohl|Moringa e cavolo riccio|\u041c\u043e\u0440\u0438\u043d\u0433\u0430 \u0438 \u043a\u0430\u043f\u0443\u0441\u0442\u0430 \u043a\u0435\u0439\u043b|\u8fa3\u6728\u53f6\u548c\u7fbd\u8863\u7518\u84dd|Moringa en boerenkool|\u0627\u0644\u0645\u0648\u0631\u064a\u0646\u063a\u0627 \u0648\u0627\u0644\u0643\u0631\u0646\u0628 \u0627\u0644\u0623\u062c\u0639\u062f|&#10;Harina de insectos|Intsektu-irina|Farina d'insectes|Fari\u00f1a de insectos|Insect flour|Farine d'insectes|Insektenmehl|Farina di insetti|\u041c\u0443\u043a\u0430 \u0438\u0437 \u043d\u0430\u0441\u0435\u043a\u043e\u043c\u044b\u0445|\u6606\u866b\u7c89|Insekmeel|\u062f\u0642\u064a\u0642 \u0627\u0644\u062d\u0634\u0631\u0627\u062a|&#10;Harina de sorgo|Artamo-irina|Farina de sorgo|Fari\u00f1a de sorgo|Sorghum flour|Farine de sorgho|Sorghummehl|Farina di sorgo|\u0421\u043e\u0440\u0433\u043e\u0432\u0430\u044f \u043c\u0443\u043a\u0430|\u9ad8\u7cb1\u7c89|Sorghummeel|\u062f\u0642\u064a\u0642 \u0627\u0644\u0630\u0631\u0629 \u0627\u0644\u0631\u0641\u064a\u0639\u0629|&#10;K\u00e9fir|Kefira|Quefir|Kefir|Kefir|K\u00e9fir|Kefir|Kefir|\u041a\u0435\u0444\u0438\u0440|\u5f00\u83f2\u5c14|Kefir|\u0627\u0644\u0643\u0641\u064a\u0631|&#10;Queso de micelio|Mizelio-gazta|Formatge de miceli|Queixo de micelio|Mycelium cheese|Fromage de myc\u00e9lium|Myzelk\u00e4se|Formaggio di micelio|\u0421\u044b\u0440 \u0438\u0437 \u043c\u0438\u0446\u0435\u043b\u0438\u044f|\u83cc\u4e1d\u5976\u916a|Miselium-kaas|\u062c\u0628\u0646 \u0627\u0644\u0645\u064a\u0633\u064a\u0644\u064a\u0648\u0645|&#10;Queso de cultivo celular|Zelula-laboreko gazta|Formatge de cultiu cel\u00b7lular|Queixo de cultivo celular|Cell-cultured cheese|Fromage de culture cellulaire|K\u00e4se aus Zellkultur|Formaggio da coltura cellulare|\u0421\u044b\u0440 \u043a\u043b\u0435\u0442\u043e\u0447\u043d\u043e\u0433\u043e \u043a\u0443\u043b\u044c\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f|\u7ec6\u80de\u57f9\u517b\u5976\u916a|Selkultuurkaas|\u062c\u0628\u0646 \u0645\u0632\u0631\u0648\u0639 \u0645\u0646 \u0627\u0644\u062e\u0644\u0627\u064a\u0627|&#10;Frijol de Bambara|Bambara babarruna|Mongeta de Bambara|Feix\u00f3n de Bambara|Bambara bean|Pois de Bambara|Bambara-Erdnuss|Fagiolo di Bambara|\u0411\u0430\u043c\u0431\u0430\u0440\u0441\u043a\u0438\u0439 \u0430\u0440\u0430\u0445\u0438\u0441|\u73ed\u5df4\u62c9\u8c46|Bambara-boontjie|\u0641\u0648\u0644 \u0628\u0627\u0645\u0628\u0627\u0631\u0627|&#10;Frijol Marama|Marama babarruna|Mongeta Marama|Feix\u00f3n Marama|Marama bean|Haricot marama|Marama-Bohne|Fagiolo Marama|\u0424\u0430\u0441\u043e\u043b\u044c \u043c\u0430\u0440\u0430\u043c\u0430|\u9a6c\u62c9\u9a6c\u8c46|Marama-boontjie|\u0641\u0648\u0644 \u0645\u0627\u0631\u0627\u0645\u0627|&#10;Alga wakame|Wakame algak|Alga wakame|Alga wakame|Wakame seaweed|Algue wakame|Wakame-Alge|Alga wakame|\u0412\u043e\u0434\u043e\u0440\u043e\u0441\u043b\u0438 \u0432\u0430\u043a\u0430\u043c\u0435|\u88d9\u5e26\u83dc|Wakame-seewier|\u0637\u062d\u0644\u0628 \u0648\u0627\u0643\u0627\u0645\u064a|&#10;Alga laver|Laver algak|Alga laver|Alga laver|Laver seaweed|Algue laver|Laver-Alge|Alga laver|\u0412\u043e\u0434\u043e\u0440\u043e\u0441\u043b\u0438 \u043b\u0430\u0432\u0435\u0440|\u7d2b\u83dc|Laver-seewier|\u0637\u062d\u0644\u0628 \u0644\u0627\u0641\u0631|&#10;Hongo enoki|Enoki perretxikoa|Bolet enoki|Cogomelo enoki|Enoki mushroom|Champignon enoki|Enoki-Pilz|Fungo enoki|\u0413\u0440\u0438\u0431\u044b \u044d\u043d\u043e\u043a\u0438|\u91d1\u9488\u83c7|Enoki-sampioen|\u0641\u0637\u0631 \u0625\u064a\u0646\u0648\u0643\u064a|&#10;Hongo maitake|Maitake perretxikoa|Bolet maitake|Cogomelo maitake|Maitake mushroom|Champignon maitake|Maitake-Pilz|Fungo maitake|\u0413\u0440\u0438\u0431\u044b \u043c\u0430\u0439\u0442\u0430\u043a\u0435|\u821e\u8338|Maitake-sampioen|\u0641\u0637\u0631 \u0645\u0627\u064a\u062a\u0627\u0643\u064a|&#10;Bloque de micoprote\u00edna|Mikroproteina-blokea|Bloc de micoprote\u00efna|Bloque de micoprote\u00edna|Mycoprotein block|Bloc de mycoprot\u00e9ine|Mykoprotein-Block|Blocco di micoproteina|\u0411\u043b\u043e\u043a \u043c\u0438\u043a\u043e\u043f\u0440\u043e\u0442\u0435\u0438\u043d\u0430|\u771f\u83cc\u86cb\u767d\u5757|Mikoprote\u00efenblok|\u0642\u0627\u0644\u0628 \u0628\u0631\u0648\u062a\u064a\u0646 \u0641\u0637\u0631\u064a|&#10;Fonio|Fonioa|Fonio|Fonio|Fonio|Fonio|Fonio|Fonio|\u0424\u043e\u043d\u0438\u043e|\u798f\u5c3c\u5965\u7c73|Fonio|\u0641\u0648\u0646\u064a\u0648|&#10;Teff|Teffa|Teff|Teff|Teff|Teff|Teff|Teff|\u0422\u0435\u0444\u0444|\u82d4\u9eb8|Teff|\u062a\u064a\u0641|&#10;Quinoa|Kinoa|Quinoa|Quinoa|Quinoa|Quinoa|Quinoa|Quinoa|\u041a\u0438\u043d\u043e\u0430|\u85dc\u9ea6|Quinoa|\u0627\u0644\u0643\u064a\u0646\u0648\u0627|&#10;Amaranto|Amarantoa|Amarant|Amaranto|Amaranth|Amarante|Amaranth|Amaranto|\u0410\u043c\u0430\u0440\u0430\u043d\u0442|\u82cb\u7c7d|Amarant|\u0627\u0644\u0623\u0645\u0627\u0631\u0627\u0646\u062b|&#10;Camote amarillo|Patata gozo horia|Moniato groc|Pataca doce amarela|Yellow sweet potato|Patate douce jaune|Gelbe S\u00fc\u00dfkartoffel|Patata dolce gialla|\u0416\u0451\u043b\u0442\u044b\u0439 \u0431\u0430\u0442\u0430\u0442|\u9ec4\u5fc3\u7ea2\u85af|Geel patat|\u0628\u0637\u0627\u0637\u0627 \u062d\u0644\u0648\u0629 \u0635\u0641\u0631\u0627\u0621|&#10;J\u00edcama|Jicama|J\u00edcama|X\u00edcama|Jicama|Jicama|Jicama|Jicama|\u0414\u0436\u0438\u043a\u0430\u043c\u0430|\u8c46\u85af|Jicama|\u062c\u064a\u0643\u0627\u0645\u0627|&#10;Algas y Hongos|Algak eta Perretxikoak|Algues i Bolets|Algas e Cogomelos|Seaweed &amp; Mushrooms|Algues et Champignons|Algen &amp; Pilze|Alghe e Funghi|\u0412\u043e\u0434\u043e\u0440\u043e\u0441\u043b\u0438 \u0438 \u0433\u0440\u0438\u0431\u044b|\u6d77\u85fb\u4e0e\u8611\u83c7|Seewier en Sampioene|\u0627\u0644\u0637\u062d\u0627\u0644\u0628 \u0648\u0627\u0644\u0641\u0637\u0631|&#10;Granos Antiguos y Ra\u00edces|Aintzinako Aleak eta Sustraiak|Grans Antics i Arrels|Grans Antigos e Ra\u00edces|Ancient Grains &amp; Roots|Grains Anciens et Racines|Urgetreide &amp; Wurzeln|Cereali Antichi e Radici|\u0414\u0440\u0435\u0432\u043d\u0438\u0435 \u0437\u043b\u0430\u043a\u0438 \u0438 \u043a\u043e\u0440\u043d\u0435\u043f\u043b\u043e\u0434\u044b|\u53e4\u8001\u8c37\u7269\u4e0e\u6839\u830e|Antieke Graan en Wortels|\u0627\u0644\u062d\u0628\u0648\u0628 \u0627\u0644\u0642\u062f\u064a\u0645\u0629 \u0648\u0627\u0644\u062c\u0630\u0648\u0631|&#10;Cact\u00e1cea de secano, tierna y cargada de agua.|Lehorreko kaktusa, samurra eta urez betea.|Cact\u00e0cia de sec\u00e0, tendra i plena d'aigua.|Cact\u00e1cea de seca\u00f1o, tenra e chea de auga.|A dryland cactus, tender and full of water.|Cactus de culture s\u00e8che, tendre et gorg\u00e9 d'eau.|Ein Trockenland-Kaktus, zart und voller Wasser.|Cactus da terreno asciutto, tenero e ricco d'acqua.|\u0417\u0430\u0441\u0443\u0445\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u044b\u0439 \u043a\u0430\u043a\u0442\u0443\u0441, \u043d\u0435\u0436\u043d\u044b\u0439 \u0438 \u043f\u043e\u043b\u043d\u044b\u0439 \u0432\u043e\u0434\u044b.|\u8010\u65f1\u7684\u4ed9\u4eba\u638c\uff0c\u9c9c\u5ae9\u591a\u6c41\u3002|Dro\u00ebland-kaktus, sag en vol water.|\u0635\u0628\u0627\u0631 \u064a\u062a\u062d\u0645\u0644 \u0627\u0644\u062c\u0641\u0627\u0641\u060c \u0637\u0631\u064a \u0648\u0645\u0644\u064a\u0621 \u0628\u0627\u0644\u0645\u0627\u0621.|&#10;Hojas verdes muy resistentes, ricas en hierro.|Hosto berde oso erresistenteak, burdinez aberatsak.|Fulles verdes molt resistents, riques en ferro.|Follas verdes moi resistentes, ricas en ferro.|Very hardy green leaves, rich in iron.|Feuilles vertes tr\u00e8s r\u00e9sistantes, riches en fer.|Sehr robuste gr\u00fcne Bl\u00e4tter, reich an Eisen.|Foglie verdi molto resistenti, ricche di ferro.|\u041e\u0447\u0435\u043d\u044c \u0432\u044b\u043d\u043e\u0441\u043b\u0438\u0432\u0430\u044f \u0437\u0435\u043b\u0435\u043d\u044c, \u0431\u043e\u0433\u0430\u0442\u0430\u044f \u0436\u0435\u043b\u0435\u0437\u043e\u043c.|\u5341\u5206\u8010\u5bd2\u8010\u65f1\u7684\u7eff\u53f6\u83dc\uff0c\u5bcc\u542b\u94c1\u3002|Baie sterk groen blare, ryk aan yster.|\u0623\u0648\u0631\u0627\u0642 \u062e\u0636\u0631\u0627\u0621 \u0634\u062f\u064a\u062f\u0629 \u0627\u0644\u062a\u062d\u0645\u0644 \u0648\u063a\u0646\u064a\u0629 \u0628\u0627\u0644\u062d\u062f\u064a\u062f.|&#10;Grano diminuto de crecimiento rapid\u00edsimo, aguanta la sequ\u00eda.|Ale txiki-txikia, oso azkar hazten da eta lehorteari eusten dio.|Gra diminut de creixement r\u00e0pid, aguanta la sequera.|Gran diminuto de crecemento rapid\u00edsimo, aguanta a seca.|A tiny grain that grows very fast and withstands drought.|Minuscule grain \u00e0 croissance tr\u00e8s rapide, r\u00e9siste \u00e0 la s\u00e9cheresse.|Winziges, sehr schnell wachsendes Korn, das D\u00fcrre \u00fcbersteht.|Chicco minuscolo a crescita rapidissima, resiste alla siccit\u00e0.|\u041a\u0440\u043e\u0448\u0435\u0447\u043d\u043e\u0435 \u0437\u0435\u0440\u043d\u043e, \u0431\u044b\u0441\u0442\u0440\u043e \u0440\u0430\u0441\u0442\u0451\u0442 \u0438 \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442 \u0437\u0430\u0441\u0443\u0445\u0443.|\u6781\u5c0f\u7684\u8c37\u7c92\uff0c\u751f\u957f\u5f88\u5feb\uff0c\u8010\u5e72\u65f1\u3002|Piepklein graan wat vinnig groei en droogte verduur.|\u062d\u0628\u0629 \u0635\u063a\u064a\u0631\u0629 \u062c\u062f\u064b\u0627 \u062a\u0646\u0645\u0648 \u0628\u0633\u0631\u0639\u0629 \u0641\u0627\u0626\u0642\u0629 \u0648\u062a\u062a\u062d\u0645\u0644 \u0627\u0644\u062c\u0641\u0627\u0641.|&#10;Cereal peque\u00f1o y resistente, base de panes fermentados.|Zereal txiki eta erresistentea, ogi hartzituen oinarria.|Cereal petit i resistent, base de pans fermentats.|Cereal pequeno e resistente, base de pans fermentados.|A small, hardy cereal, the base of fermented breads.|Petite c\u00e9r\u00e9ale r\u00e9sistante, base des pains ferment\u00e9s.|Kleines, robustes Getreide, Grundlage fermentierter Brote.|Piccolo cereale resistente, base dei pani fermentati.|\u041c\u0435\u043b\u043a\u0430\u044f \u0432\u044b\u043d\u043e\u0441\u043b\u0438\u0432\u0430\u044f \u0437\u043b\u0430\u043a\u043e\u0432\u0430\u044f \u043a\u0443\u043b\u044c\u0442\u0443\u0440\u0430 \u0434\u043b\u044f \u043a\u0432\u0430\u0441\u043d\u043e\u0433\u043e \u0445\u043b\u0435\u0431\u0430.|\u7ec6\u5c0f\u8010\u6d3b\u7684\u8c37\u7269\uff0c\u662f\u53d1\u9175\u9762\u5305\u7684\u57fa\u7840\u3002|Klein, sterk graan, die basis van gefermenteerde brood.|\u062d\u0628\u0648\u0628 \u0635\u063a\u064a\u0631\u0629 \u0645\u062a\u062d\u0645\u0644\u0629\u060c \u0623\u0633\u0627\u0633 \u0627\u0644\u062e\u0628\u0632 \u0627\u0644\u0645\u062e\u0645\u0651\u0631.|&#10;Prote\u00edna de bajo consumo de agua, molida fina.|Ur gutxi behar duen proteina, fin ehotua.|Prote\u00efna de baix consum d'aigua, m\u00f2lta fina.|Prote\u00edna de baixo consumo de auga, mo\u00edda fina.|Low-water protein, finely ground.|Prot\u00e9ine \u00e0 faible empreinte hydrique, finement moulue.|Wassersparendes Protein, fein gemahlen.|Proteina a basso consumo d'acqua, macinata fine.|\u0411\u0435\u043b\u043e\u043a \u0441 \u043d\u0438\u0437\u043a\u0438\u043c \u0440\u0430\u0441\u0445\u043e\u0434\u043e\u043c \u0432\u043e\u0434\u044b, \u0442\u043e\u043d\u043a\u043e\u0433\u043e \u043f\u043e\u043c\u043e\u043b\u0430.|\u8017\u6c34\u91cf\u4f4e\u7684\u86cb\u767d\u8d28\uff0c\u7814\u78e8\u5f97\u5f88\u7ec6\u3002|Prote\u00efen wat min water gebruik, fyn gemaal.|\u0628\u0631\u0648\u062a\u064a\u0646 \u0642\u0644\u064a\u0644 \u0627\u0633\u062a\u0647\u0644\u0627\u0643 \u0627\u0644\u0645\u064a\u0627\u0647\u060c \u0645\u0637\u062d\u0648\u0646 \u0646\u0627\u0639\u0645\u064b\u0627.|&#10;Sin gluten, de un cereal que casi no necesita riego.|Glutenik gabea, ia ureztatu beharrik ez duen zerealetik.|Sense gluten, d'un cereal que gaireb\u00e9 no necessita reg.|Sen glute, dun cereal que case non precisa rega.|Gluten-free, from a cereal that hardly needs irrigation.|Sans gluten, issue d'une c\u00e9r\u00e9ale qui demande \u00e0 peine d'irrigation.|Glutenfrei, aus einem Getreide, das kaum Bew\u00e4sserung braucht.|Senza glutine, da un cereale che quasi non richiede irrigazione.|\u0411\u0435\u0437 \u0433\u043b\u044e\u0442\u0435\u043d\u0430, \u0438\u0437 \u0437\u043b\u0430\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u043e\u0447\u0442\u0438 \u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u043f\u043e\u043b\u0438\u0432.|\u65e0\u9eb8\u8d28\uff0c\u6765\u81ea\u51e0\u4e4e\u4e0d\u9700\u8981\u704c\u6e89\u7684\u8c37\u7269\u3002|Glutenvry, van 'n graan wat byna geen besproeiing nodig het.|\u062e\u0627\u0644\u064d \u0645\u0646 \u0627\u0644\u063a\u0644\u0648\u062a\u064a\u0646\u060c \u0645\u0646 \u062d\u0628\u0648\u0628 \u0644\u0627 \u062a\u062d\u062a\u0627\u062c \u0625\u0644\u0649 \u0631\u064a\u0651 \u064a\u064f\u0630\u0643\u0631.|&#10;Fermentado vivo que cuida la microbiota.|Hartzigarri bizia, mikrobiota zaintzen duena.|Fermentat viu que cuida la microbiota.|Fermentado vivo que coida a microbiota.|A living ferment that looks after the gut microbiota.|Ferment vivant qui prend soin du microbiote.|Lebendiges Ferment, das die Darmflora pflegt.|Fermentato vivo che si prende cura del microbiota.|\u0416\u0438\u0432\u043e\u0439 \u0444\u0435\u0440\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043f\u0440\u043e\u0434\u0443\u043a\u0442, \u0437\u0430\u0431\u043e\u0442\u0438\u0442\u0441\u044f \u043e \u043c\u0438\u043a\u0440\u043e\u0431\u0438\u043e\u0442\u0435.|\u6d3b\u6027\u53d1\u9175\u98df\u54c1\uff0c\u5475\u62a4\u80a0\u9053\u83cc\u7fa4\u3002|Lewende fermentasie wat die mikrobiota versorg.|\u0645\u062e\u0645\u0651\u0631 \u062d\u064a\u0651 \u064a\u0639\u062a\u0646\u064a \u0628\u0627\u0644\u0645\u064a\u0643\u0631\u0648\u0628\u064a\u0648\u0645.|&#10;Fermentaci\u00f3n de hongos con sabor de queso curado.|Onddoen hartzidura, gazta zaharraren zaporekoa.|Fermentaci\u00f3 de fongs amb gust de formatge curat.|Fermentaci\u00f3n de fungos con sabor de queixo curado.|Fungal fermentation with the taste of aged cheese.|Fermentation de champignons au go\u00fbt de fromage affin\u00e9.|Pilzfermentation mit dem Geschmack von gereiftem K\u00e4se.|Fermentazione di funghi con sapore di formaggio stagionato.|\u0413\u0440\u0438\u0431\u043d\u0430\u044f \u0444\u0435\u0440\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u0441\u043e \u0432\u043a\u0443\u0441\u043e\u043c \u0432\u044b\u0434\u0435\u0440\u0436\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u044b\u0440\u0430.|\u771f\u83cc\u53d1\u9175\uff0c\u5e26\u6709\u9648\u5e74\u5976\u916a\u7684\u98ce\u5473\u3002|Swamfermentasie met die smaak van ryp kaas.|\u062a\u062e\u0645\u064a\u0631 \u0641\u0637\u0631\u064a \u0628\u0646\u0643\u0647\u0629 \u0627\u0644\u062c\u0628\u0646 \u0627\u0644\u0645\u0639\u062a\u0651\u0642.|&#10;Prote\u00ednas l\u00e1cteas hechas por fermentaci\u00f3n, sin ganado.|Esnekiaren proteinak hartziduraz egindakoak, abererik gabe.|Prote\u00efnes l\u00e0cties fetes per fermentaci\u00f3, sense bestiar.|Prote\u00ednas l\u00e1cteas feitas por fermentaci\u00f3n, sen gando.|Dairy proteins made by fermentation, with no livestock.|Prot\u00e9ines laiti\u00e8res obtenues par fermentation, sans \u00e9levage.|Milchproteine aus Fermentation, ganz ohne Vieh.|Proteine del latte ottenute per fermentazione, senza bestiame.|\u041c\u043e\u043b\u043e\u0447\u043d\u044b\u0435 \u0431\u0435\u043b\u043a\u0438, \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0444\u0435\u0440\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439, \u0431\u0435\u0437 \u0441\u043a\u043e\u0442\u0430.|\u901a\u8fc7\u53d1\u9175\u5236\u6210\u7684\u4e73\u86cb\u767d\uff0c\u65e0\u9700\u7272\u755c\u3002|Suiwelprote\u00efene deur fermentasie, sonder vee.|\u0628\u0631\u0648\u062a\u064a\u0646\u0627\u062a \u0623\u0644\u0628\u0627\u0646 \u062a\u064f\u0646\u062a\u062c \u0628\u0627\u0644\u062a\u062e\u0645\u064a\u0631 \u062f\u0648\u0646 \u0645\u0627\u0634\u064a\u0629.|&#10;Legumbre del secano africano, crece donde otras no.|Afrikako lehorreko lekalea, besteek ez dutenean hazten da.|Llegum del sec\u00e0 afric\u00e0, creix on d'altres no.|Legume do seca\u00f1o africano, medra onde outros non.|A dryland African legume that grows where others cannot.|L\u00e9gumineuse africaine de culture s\u00e8che, pousse l\u00e0 o\u00f9 d'autres \u00e9chouent.|Afrikanische H\u00fclsenfrucht, die dort w\u00e4chst, wo andere es nicht k\u00f6nnen.|Legume africano da terreno asciutto, cresce dove altri non crescono.|\u0410\u0444\u0440\u0438\u043a\u0430\u043d\u0441\u043a\u0430\u044f \u0437\u0430\u0441\u0443\u0445\u043e\u0443\u0441\u0442\u043e\u0439\u0447\u0438\u0432\u0430\u044f \u0431\u043e\u0431\u043e\u0432\u0430\u044f, \u0440\u0430\u0441\u0442\u0451\u0442 \u0442\u0430\u043c, \u0433\u0434\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u043d\u0435 \u043c\u043e\u0433\u0443\u0442.|\u975e\u6d32\u65f1\u5730\u8c46\u7c7b\uff0c\u522b\u7684\u4f5c\u7269\u4e0d\u957f\u7684\u5730\u65b9\u5b83\u4e5f\u80fd\u751f\u957f\u3002|Afrika-dro\u00eblandpeulgewas wat groei waar ander nie kan nie.|\u0628\u0642\u0648\u0644\u064a\u0627\u062a \u0623\u0641\u0631\u064a\u0642\u064a\u0629 \u062a\u0646\u0645\u0648 \u062d\u064a\u062b \u0644\u0627 \u062a\u0646\u0645\u0648 \u063a\u064a\u0631\u0647\u0627.|&#10;Frijol del desierto, rico en prote\u00edna y aceites.|Basamortuko babarruna, proteina eta olio aberatsa.|Mongeta del desert, rica en prote\u00efna i olis.|Feix\u00f3n do deserto, rico en prote\u00edna e aceites.|A desert bean, rich in protein and oils.|Haricot du d\u00e9sert, riche en prot\u00e9ines et en huiles.|W\u00fcstenbohne, reich an Protein und \u00d6len.|Fagiolo del deserto, ricco di proteine e oli.|\u041f\u0443\u0441\u0442\u044b\u043d\u043d\u0430\u044f \u0444\u0430\u0441\u043e\u043b\u044c, \u0431\u043e\u0433\u0430\u0442\u0430\u044f \u0431\u0435\u043b\u043a\u043e\u043c \u0438 \u043c\u0430\u0441\u043b\u0430\u043c\u0438.|\u6c99\u6f20\u8c46\u7c7b\uff0c\u5bcc\u542b\u86cb\u767d\u8d28\u548c\u6cb9\u8102\u3002|Woestynboontjie, ryk aan prote\u00efen en olies.|\u0641\u0648\u0644 \u0635\u062d\u0631\u0627\u0648\u064a \u063a\u0646\u064a \u0628\u0627\u0644\u0628\u0631\u0648\u062a\u064a\u0646 \u0648\u0627\u0644\u0632\u064a\u0648\u062a.|&#10;Alga tierna recogida en la costa del pueblo.|Alga samurra, herriko kostan bilduta.|Alga tendra recollida a la costa del poble.|Alga tenra recollida na costa do pobo.|Tender seaweed gathered on the village coast.|Algue tendre r\u00e9colt\u00e9e sur la c\u00f4te du village.|Zarte Alge, an der K\u00fcste des Dorfes gesammelt.|Alga tenera raccolta sulla costa del paese.|\u041d\u0435\u0436\u043d\u044b\u0435 \u0432\u043e\u0434\u043e\u0440\u043e\u0441\u043b\u0438, \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043d\u0430 \u043f\u043e\u0431\u0435\u0440\u0435\u0436\u044c\u0435 \u0434\u0435\u0440\u0435\u0432\u043d\u0438.|\u5728\u5c0f\u9547\u6d77\u5cb8\u91c7\u96c6\u7684\u5ae9\u6d77\u85fb\u3002|Sagte seewier wat aan die dorp se kus ingesamel is.|\u0637\u062d\u0644\u0628 \u0637\u0631\u064a \u064a\u064f\u062c\u0645\u0639 \u0645\u0646 \u0633\u0627\u062d\u0644 \u0627\u0644\u0642\u0631\u064a\u0629.|&#10;Alga fina para tostar o desmenuzar en las comidas.|Alga mehea, txigortzeko edo janarietan birrintzeko.|Alga fina per torrar o esmicolar als \u00e0pats.|Alga fina para torrar ou esmiuzar nas comidas.|Fine seaweed to toast or crumble into meals.|Algue fine \u00e0 griller ou \u00e0 \u00e9mietter dans les plats.|Feine Alge zum R\u00f6sten oder Zerbr\u00f6seln \u00fcber Gerichte.|Alga sottile da tostare o sbriciolare nei piatti.|\u0422\u043e\u043d\u043a\u0438\u0435 \u0432\u043e\u0434\u043e\u0440\u043e\u0441\u043b\u0438: \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0441\u0443\u0448\u0438\u0442\u044c \u0438\u043b\u0438 \u0440\u0430\u0441\u043a\u0440\u043e\u0448\u0438\u0442\u044c \u0432 \u0431\u043b\u044e\u0434\u0430.|\u7ec6\u5ae9\u7684\u6d77\u85fb\uff0c\u53ef\u70e4\u5236\u6216\u78be\u788e\u52a0\u5165\u996d\u83dc\u3002|Fyn seewier om te rooster of in maaltye te krummel.|\u0637\u062d\u0644\u0628 \u0631\u0642\u064a\u0642 \u064a\u064f\u062d\u0645\u064e\u0651\u0635 \u0623\u0648 \u064a\u064f\u0641\u062a\u064e\u0651\u062a \u0641\u064a \u0627\u0644\u0648\u062c\u0628\u0627\u062a.|&#10;Hongo largo y delicado, cultivado en residuos agr\u00edcolas.|Perretxiko luze eta delikatua, nekazaritza-hondakinetan hazia.|Bolet llarg i delicat, cultivat en residus agr\u00edcoles.|Cogomelo longo e delicado, cultivado en residuos agr\u00edcolas.|A long, delicate mushroom grown on farm waste.|Champignon long et d\u00e9licat, cultiv\u00e9 sur des d\u00e9chets agricoles.|Langer, zarter Pilz, auf landwirtschaftlichen Reststoffen gez\u00fcchtet.|Fungo lungo e delicato, coltivato su scarti agricoli.|\u0414\u043b\u0438\u043d\u043d\u044b\u0439 \u043d\u0435\u0436\u043d\u044b\u0439 \u0433\u0440\u0438\u0431, \u0432\u044b\u0440\u0430\u0449\u0435\u043d\u043d\u044b\u0439 \u043d\u0430 \u0441\u0435\u043b\u044c\u0445\u043e\u0437\u043e\u0442\u0445\u043e\u0434\u0430\u0445.|\u7ec6\u957f\u67d4\u5ae9\u7684\u8611\u83c7\uff0c\u7528\u519c\u4e1a\u5e9f\u6599\u683d\u57f9\u3002|Lang, delikate sampioen wat op plaasafval gekweek word.|\u0641\u0637\u0631 \u0637\u0648\u064a\u0644 \u0631\u0642\u064a\u0642 \u064a\u064f\u0632\u0631\u0639 \u0639\u0644\u0649 \u0645\u062e\u0644\u0641\u0627\u062a \u0632\u0631\u0627\u0639\u064a\u0629.|&#10;Hongo de textura carnosa, cultivado en residuos agr\u00edcolas.|Ehundura haragitsuko perretxikoa, nekazaritza-hondakinetan hazia.|Bolet de textura carnosa, cultivat en residus agr\u00edcoles.|Cogomelo de textura carnosa, cultivado en residuos agr\u00edcolas.|A meaty-textured mushroom grown on farm waste.|Champignon \u00e0 la texture charnue, cultiv\u00e9 sur des d\u00e9chets agricoles.|Fleischig strukturierter Pilz, auf landwirtschaftlichen Reststoffen gez\u00fcchtet.|Fungo dalla consistenza carnosa, coltivato su scarti agricoli.|\u0413\u0440\u0438\u0431 \u0441 \u043c\u044f\u0441\u0438\u0441\u0442\u043e\u0439 \u0442\u0435\u043a\u0441\u0442\u0443\u0440\u043e\u0439, \u0432\u044b\u0440\u0430\u0449\u0435\u043d\u043d\u044b\u0439 \u043d\u0430 \u0441\u0435\u043b\u044c\u0445\u043e\u0437\u043e\u0442\u0445\u043e\u0434\u0430\u0445.|\u53e3\u611f\u8089\u8d28\u7684\u8611\u83c7\uff0c\u7528\u519c\u4e1a\u5e9f\u6599\u683d\u57f9\u3002|Vleesagtige sampioen wat op plaasafval gekweek word.|\u0641\u0637\u0631 \u0628\u0642\u0648\u0627\u0645 \u0644\u062d\u0645\u064a \u064a\u064f\u0632\u0631\u0639 \u0639\u0644\u0649 \u0645\u062e\u0644\u0641\u0627\u062a \u0632\u0631\u0627\u0639\u064a\u0629.|&#10;Bloque de prote\u00edna f\u00fangica, huella h\u00eddrica casi nula.|Onddo-proteinazko blokea, ur-aztarna ia hutsa.|Bloc de prote\u00efna f\u00fangica, petjada h\u00eddrica gaireb\u00e9 nul\u00b7la.|Bloque de prote\u00edna f\u00fanxica, pegada h\u00eddrica case nula.|A block of fungal protein with almost no water footprint.|Bloc de prot\u00e9ine fongique, empreinte hydrique quasi nulle.|Block aus Pilzprotein, fast ohne Wasserfu\u00dfabdruck.|Blocco di proteina fungina, impronta idrica quasi nulla.|\u0411\u043b\u043e\u043a \u0433\u0440\u0438\u0431\u043d\u043e\u0433\u043e \u0431\u0435\u043b\u043a\u0430, \u0432\u043e\u0434\u043d\u044b\u0439 \u0441\u043b\u0435\u0434 \u043f\u043e\u0447\u0442\u0438 \u043d\u0443\u043b\u0435\u0432\u043e\u0439.|\u771f\u83cc\u86cb\u767d\u5757\uff0c\u6c34\u8db3\u8ff9\u51e0\u4e4e\u4e3a\u96f6\u3002|Blok swamprote\u00efen met byna geen waterspoor.|\u0642\u0627\u0644\u0628 \u0645\u0646 \u0627\u0644\u0628\u0631\u0648\u062a\u064a\u0646 \u0627\u0644\u0641\u0637\u0631\u064a \u0628\u0628\u0635\u0645\u0629 \u0645\u0627\u0626\u064a\u0629 \u0634\u0628\u0647 \u0645\u0639\u062f\u0648\u0645\u0629.|&#10;Pseudocereal completo, aguanta clima extremo.|Pseudozereal osoa, muturreko klimari eusten dio.|Pseudocereal complet, aguanta el clima extrem.|Pseudocereal completo, aguanta o clima extremo.|A complete pseudocereal that withstands extreme climates.|Pseudo-c\u00e9r\u00e9ale complet, r\u00e9siste aux climats extr\u00eames.|Vollwertiges Pseudogetreide, \u00fcbersteht extremes Klima.|Pseudocereale completo, resiste ai climi estremi.|\u041f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u0430\u044f \u043f\u0441\u0435\u0432\u0434\u043e\u0437\u043b\u0430\u043a\u043e\u0432\u0430\u044f \u043a\u0443\u043b\u044c\u0442\u0443\u0440\u0430, \u0432\u044b\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u044d\u043a\u0441\u0442\u0440\u0435\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043b\u0438\u043c\u0430\u0442.|\u8425\u517b\u5b8c\u6574\u7684\u5047\u8c37\u7269\uff0c\u8010\u6781\u7aef\u6c14\u5019\u3002|Volledige pseudograan wat uiterste klimaat verduur.|\u062d\u0628\u0648\u0628 \u0643\u0627\u0630\u0628\u0629 \u0645\u062a\u0643\u0627\u0645\u0644\u0629 \u062a\u062a\u062d\u0645\u0644 \u0627\u0644\u0645\u0646\u0627\u062e \u0627\u0644\u0642\u0627\u0633\u064a.|&#10;Semilla antigua de gran valor nutritivo.|Hazi zaharra, balio nutritibo handikoa.|Llavor antiga de gran valor nutritiu.|Semente antiga de gran valor nutritivo.|An ancient seed of great nutritional value.|Graine ancienne de grande valeur nutritive.|Uraltes Saatgut von hohem N\u00e4hrwert.|Seme antico di grande valore nutritivo.|\u0414\u0440\u0435\u0432\u043d\u0435\u0435 \u0441\u0435\u043c\u044f \u0441 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u043f\u0438\u0442\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0439 \u0446\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e.|\u8425\u517b\u4ef7\u503c\u5f88\u9ad8\u7684\u53e4\u8001\u79cd\u5b50\u3002|Eeue-oue saad van groot voedingswaarde.|\u0628\u0630\u0631\u0629 \u0642\u062f\u064a\u0645\u0629 \u0630\u0627\u062a \u0642\u064a\u0645\u0629 \u063a\u0630\u0627\u0626\u064a\u0629 \u0639\u0627\u0644\u064a\u0629.|&#10;Batata amarilla dulce, de cultivo resistente.|Patata gozo horia, laborantza erresistentekoa.|Moniato groc dol\u00e7, de cultiu resistent.|Pataca doce amarela, de cultivo resistente.|A sweet yellow sweet potato from a hardy crop.|Patate douce jaune, d'une culture r\u00e9sistante.|S\u00fc\u00dfe gelbe S\u00fc\u00dfkartoffel aus robustem Anbau.|Patata dolce gialla, di coltura resistente.|\u0421\u043b\u0430\u0434\u043a\u0438\u0439 \u0436\u0451\u043b\u0442\u044b\u0439 \u0431\u0430\u0442\u0430\u0442 \u043d\u0435\u043f\u0440\u0438\u0445\u043e\u0442\u043b\u0438\u0432\u043e\u0439 \u043a\u0443\u043b\u044c\u0442\u0443\u0440\u044b.|\u9999\u751c\u7684\u9ec4\u5fc3\u7ea2\u85af\uff0c\u4f5c\u7269\u8010\u6027\u5f3a\u3002|Soet geel patat van 'n sterk gewas.|\u0628\u0637\u0627\u0637\u0627 \u062d\u0644\u0648\u0629 \u0635\u0641\u0631\u0627\u0621 \u0645\u0646 \u0645\u062d\u0635\u0648\u0644 \u0645\u062a\u064a\u0646.|&#10;Ra\u00edz crujiente y refrescante, se come cruda o cocida.|Sustrai kurruskaria eta freskagarria, gordina edo egosia jaten da.|Arrel cruixent i refrescant, es menja crua o cuita.|Ra\u00edz crocante e refrescante, c\u00f3mese cr\u00faa ou cocida.|A crunchy, refreshing root, eaten raw or cooked.|Racine croquante et rafra\u00eechissante, se mange crue ou cuite.|Knackige, erfrischende Wurzel, roh oder gekocht.|Radice croccante e rinfrescante, si mangia cruda o cotta.|\u0425\u0440\u0443\u0441\u0442\u044f\u0449\u0438\u0439 \u043e\u0441\u0432\u0435\u0436\u0430\u044e\u0449\u0438\u0439 \u043a\u043e\u0440\u043d\u0435\u043f\u043b\u043e\u0434, \u0435\u0434\u044f\u0442 \u0441\u044b\u0440\u044b\u043c \u0438\u043b\u0438 \u0432\u0430\u0440\u0451\u043d\u044b\u043c.|\u6e05\u8106\u723d\u53e3\u7684\u6839\u830e\uff0c\u53ef\u751f\u5403\u6216\u716e\u98df\u3002|Bros, verfrissende wortel, rou of gekook ge\u00ebet.|\u062c\u0630\u0631 \u0645\u0642\u0631\u0645\u0634 \u0648\u0645\u0646\u0639\u0634 \u064a\u064f\u0624\u0643\u0644 \u0646\u064a\u0626\u064b\u0627 \u0623\u0648 \u0645\u0637\u0628\u0648\u062e\u064b\u0627.|&#10;Registrar venta|Salmenta erregistratu|Registrar venda|Rexistrar venda|Record sale|Enregistrer la vente|Verkauf buchen|Registra vendita|\u0417\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0434\u0430\u0436\u0443|\u8bb0\u5f55\u9500\u552e|Teken verkoop aan|\u062a\u0633\u062c\u064a\u0644 \u0627\u0644\u0628\u064a\u0639|&#10;c\/u|bana|cada u.|cada un.|each|l'unit\u00e9|je St\u00fcck|cad.|\u0437\u0430 \u0448\u0442.|\u6bcf\u4ef6|elk|\u0644\u0644\u0648\u0627\u062d\u062f\u0629|&#10;Jalea real|Errege-jelea|Gelea reial|Xelea real|Royal jelly|Gel\u00e9e royale|Gel\u00e9e Royale|Pappa reale|\u041c\u0430\u0442\u043e\u0447\u043d\u043e\u0435 \u043c\u043e\u043b\u043e\u0447\u043a\u043e|\u8702\u738b\u6d46|Koninginjellie|\u063a\u0630\u0627\u0621 \u0645\u0644\u0643\u0627\u062a \u0627\u0644\u0646\u062d\u0644|&#10;Alimento de la reina de la colmena, escaso y muy valioso.|Erlauntzako erreginaren elikagaia, urria eta oso baliotsua.|Aliment de la reina del rusc, esc\u00e0s i molt valu\u00f3s.|Alimento da ra\u00ed\u00f1a da colmea, escaso e moi valioso.|Food of the hive's queen, scarce and very precious.|Nourriture de la reine de la ruche, rare et tr\u00e8s pr\u00e9cieuse.|Nahrung der Bienenk\u00f6nigin, selten und sehr wertvoll.|Cibo della regina dell'alveare, raro e preziosissimo.|\u041f\u0438\u0449\u0430 \u043c\u0430\u0442\u043a\u0438 \u0443\u043b\u044c\u044f, \u0440\u0435\u0434\u043a\u0430\u044f \u0438 \u043e\u0447\u0435\u043d\u044c \u0446\u0435\u043d\u043d\u0430\u044f.|\u8702\u5de2\u5973\u738b\u7684\u98df\u7269\uff0c\u7a00\u5c11\u800c\u73cd\u8d35\u3002|Voedsel van die byekoningin, skaars en baie kosbaar.|\u063a\u0630\u0627\u0621 \u0645\u0644\u0643\u0629 \u0627\u0644\u062e\u0644\u064a\u0629\u060c \u0646\u0627\u062f\u0631 \u0648\u062b\u0645\u064a\u0646 \u062c\u062f\u064b\u0627.|&#10;Miel|Eztia|Mel|Mel|Honey|Miel|Honig|Miele|\u041c\u0451\u0434|\u8702\u871c|Heuning|\u0639\u0633\u0644|&#10;Cera real|Argizari erreala|Cera real|Cera real|Pure beeswax|Cire pure|Reines Bienenwachs|Cera pura|\u0427\u0438\u0441\u0442\u044b\u0439 \u0432\u043e\u0441\u043a|\u7eaf\u8702\u8721|Suiwer byewas|\u0634\u0645\u0639 \u0646\u062d\u0644 \u0646\u0642\u064a|&#10;Prop\u00f3leo|Propolisa|Pr\u00f2polis|Pr\u00f3pole|Propolis|Propolis|Propolis|Propoli|\u041f\u0440\u043e\u043f\u043e\u043b\u0438\u0441|\u8702\u80f6|Propolis|\u0627\u0644\u0628\u0631\u0648\u0628\u0648\u0644\u064a\u0633|&#10;Hidromiel|Hidromela|Hidromel|Hidromel|Mead|Hydromel|Met|Idromele|\u041c\u0435\u0434\u043e\u0432\u0443\u0445\u0430|\u8702\u871c\u9152|Mede|\u0634\u0631\u0627\u0628 \u0627\u0644\u0639\u0633\u0644 \u0627\u0644\u0645\u062e\u0645\u0651\u0631|&#10;Miel de las flores de La Huerta, recogida de las colmenas.|Baratzako loreen eztia, erlauntzetatik bildua.|Mel de les flors de L'Hort, recollida dels ruscs.|Mel das flores da Horta, recollida das colmeas.|Honey from the flowers of the Garden, collected from the hives.|Miel des fleurs du Potager, r\u00e9colt\u00e9e dans les ruches.|Honig von den Blumen des Gartens, aus den Bienenst\u00f6cken geerntet.|Miele dei fiori dell'Orto, raccolto dalle arnie.|\u041c\u0451\u0434 \u0441 \u0446\u0432\u0435\u0442\u043e\u0432 \u041e\u0433\u043e\u0440\u043e\u0434\u0430, \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u0438\u0437 \u0443\u043b\u044c\u0435\u0432.|\u91c7\u81ea\u83dc\u56ed\u82b1\u6735\u7684\u8702\u871c\uff0c\u53d6\u81ea\u8702\u7bb1\u3002|Heuning van die blomme van die Tuin, uit die korwe ingesamel.|\u0639\u0633\u0644 \u0645\u0646 \u0623\u0632\u0647\u0627\u0631 \u0627\u0644\u062d\u062f\u064a\u0642\u0629 \u064a\u064f\u062c\u0645\u0639 \u0645\u0646 \u0627\u0644\u062e\u0644\u0627\u064a\u0627.|&#10;Cera pura de abeja para velas y b\u00e1lsamos.|Erle-argizari hutsa, kandelak eta ukendurako.|Cera pura d'abella per a espelmes i b\u00e0lsams.|Cera pura de abella para velas e b\u00e1lsamos.|Pure beeswax for candles and balms.|Cire d'abeille pure pour bougies et baumes.|Reines Bienenwachs f\u00fcr Kerzen und Balsame.|Cera d'api pura per candele e balsami.|\u0427\u0438\u0441\u0442\u044b\u0439 \u043f\u0447\u0435\u043b\u0438\u043d\u044b\u0439 \u0432\u043e\u0441\u043a \u0434\u043b\u044f \u0441\u0432\u0435\u0447\u0435\u0439 \u0438 \u0431\u0430\u043b\u044c\u0437\u0430\u043c\u043e\u0432.|\u7528\u4e8e\u5236\u4f5c\u8721\u70db\u548c\u9999\u818f\u7684\u7eaf\u8702\u8721\u3002|Suiwer byewas vir kerse en balsems.|\u0634\u0645\u0639 \u0646\u062d\u0644 \u0646\u0642\u064a \u0644\u0644\u0634\u0645\u0648\u0639 \u0648\u0627\u0644\u0628\u0644\u0633\u0645.|&#10;Resina de las yemas que las abejas usan para proteger la colmena.|Erleek erlauntza babesteko erabiltzen duten kimuen erretxina.|Resina dels borrons que les abelles fan servir per protegir el rusc.|Resina das xemas que as abellas usan para protexer a colmea.|Resin from the buds that bees use to protect the hive.|R\u00e9sine des bourgeons que les abeilles utilisent pour prot\u00e9ger la ruche.|Harz der Knospen, mit dem die Bienen den Stock sch\u00fctzen.|Resina delle gemme che le api usano per proteggere l'alveare.|\u0421\u043c\u043e\u043b\u0430 \u043f\u043e\u0447\u0435\u043a, \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043f\u0447\u0451\u043b\u044b \u0437\u0430\u0449\u0438\u0449\u0430\u044e\u0442 \u0443\u043b\u0435\u0439.|\u871c\u8702\u7528\u6765\u4fdd\u62a4\u8702\u5de2\u7684\u82bd\u82de\u6811\u8102\u3002|Hars van die knoppe wat bye gebruik om die korf te beskerm.|\u0631\u0627\u062a\u0646\u062c \u0627\u0644\u0628\u0631\u0627\u0639\u0645 \u0627\u0644\u0630\u064a \u062a\u0633\u062a\u062e\u062f\u0645\u0647 \u0627\u0644\u0646\u062d\u0644 \u0644\u062d\u0645\u0627\u064a\u0629 \u0627\u0644\u062e\u0644\u064a\u0629.|&#10;Miel fermentada 30 segundos: dulce, suave y muy nuestra.|30 segundoz hartzitako eztia: gozoa, leuna eta oso gurea.|Mel fermentada 30 segons: dol\u00e7a, suau i molt nostra.|Mel fermentado 30 segundos: doce, suave e moi noso.|Honey fermented for 30 seconds: sweet, smooth and very much ours.|Miel ferment\u00e9 30 secondes : doux, tendre et bien \u00e0 nous.|In 30 Sekunden vergorener Honig: s\u00fc\u00df, mild und ganz unser.|Miele fermentato per 30 secondi: dolce, morbido e molto nostro.|\u041c\u0451\u0434, \u0444\u0435\u0440\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 30 \u0441\u0435\u043a\u0443\u043d\u0434: \u0441\u043b\u0430\u0434\u043a\u0438\u0439, \u043c\u044f\u0433\u043a\u0438\u0439 \u0438 \u043e\u0447\u0435\u043d\u044c \u043d\u0430\u0448.|\u53d1\u917530\u79d2\u7684\u8702\u871c\uff1a\u9999\u751c\u67d4\u548c\uff0c\u5f88\u6709\u6211\u4eec\u7684\u7279\u8272\u3002|Heuning 30 sekondes gefermenteer: soet, sag en baie ons eie.|\u0639\u0633\u0644 \u0645\u062e\u0645\u0651\u0631 \u0644\u0645\u062f\u0629 30 \u062b\u0627\u0646\u064a\u0629: \u062d\u0644\u0648 \u0648\u0646\u0627\u0639\u0645 \u0648\u0628\u0635\u0645\u062a\u0646\u0627 \u0627\u0644\u062e\u0627\u0635\u0629.|&#10;Un pueblo solarpunk donde las chicas viven su d\u00eda: huerta, mercado, biblioteca digital, playa y puerto, y las fiestas vascas del calendario.|Herri solarpunk bat, neskek euren eguna bizi dutena: baratza, merkatua, liburutegi digitala, hondartza eta portua, eta egutegiko euskal jaiak.|Un poble solarpunk on les xiques viuen el seu dia: hort, mercat, biblioteca digital, platja i port, i les festes basques del calendari.|Un pobo solarpunk onde as rapazas viven o seu d\u00eda: horta, mercado, biblioteca dixital, praia e porto, e as festas vascas do calendario.|A solarpunk village where the girls live their day: garden, market, digital library, beach and port, and the Basque festivals of the calendar.|Un village solarpunk o\u00f9 les filles vivent leur journ\u00e9e : potager, march\u00e9, biblioth\u00e8que num\u00e9rique, plage et port, et les f\u00eates basques du calendrier.|Ein Solarpunk-Dorf, in dem die M\u00e4dchen ihren Tag leben: Garten, Markt, digitale Bibliothek, Strand und Hafen und die baskischen Feste des Kalenders.|Un paese solarpunk dove le ragazze vivono la loro giornata: orto, mercato, biblioteca digitale, spiaggia e porto, e le feste basche del calendario.|\u0414\u0435\u0440\u0435\u0432\u043d\u044f \u0432 \u0441\u0442\u0438\u043b\u0435 \u0441\u043e\u043b\u043d\u0435\u0447\u043d\u043e\u0433\u043e \u043f\u0430\u043d\u043a\u0430, \u0433\u0434\u0435 \u0434\u0435\u0432\u043e\u0447\u043a\u0438 \u043f\u0440\u043e\u0436\u0438\u0432\u0430\u044e\u0442 \u0441\u0432\u043e\u0439 \u0434\u0435\u043d\u044c: \u043e\u0433\u043e\u0440\u043e\u0434, \u0440\u044b\u043d\u043e\u043a, \u0446\u0438\u0444\u0440\u043e\u0432\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430, \u043f\u043b\u044f\u0436 \u0438 \u043f\u043e\u0440\u0442, \u0438 \u0431\u0430\u0441\u043a\u0441\u043a\u0438\u0435 \u043f\u0440\u0430\u0437\u0434\u043d\u0438\u043a\u0438 \u043f\u043e \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u044e.|\u4e00\u4e2a\u592a\u9633\u670b\u514b\u5c0f\u9547\uff0c\u5973\u5b69\u4eec\u5728\u8fd9\u91cc\u5ea6\u8fc7\u6bcf\u4e00\u5929\uff1a\u83dc\u56ed\u3001\u5e02\u573a\u3001\u6570\u5b57\u56fe\u4e66\u9986\u3001\u6d77\u6ee9\u4e0e\u6e2f\u53e3\uff0c\u8fd8\u6709\u65e5\u5386\u4e0a\u7684\u5df4\u65af\u514b\u8282\u65e5\u3002|'n Solarpunk-dorp waar die meisies hul dag deurbring: tuin, mark, digitale biblioteek, strand en hawe, en die Baskiese feeste van die kalender.|\u0642\u0631\u064a\u0629 \u0633\u0648\u0644\u0627\u0631\u0628\u0627\u0646\u0643 \u062a\u0639\u064a\u0634 \u0641\u064a\u0647\u0627 \u0627\u0644\u0641\u062a\u064a\u0627\u062a \u064a\u0648\u0645\u0647\u0646: \u0627\u0644\u062d\u062f\u064a\u0642\u0629 \u0648\u0627\u0644\u0633\u0648\u0642 \u0648\u0627\u0644\u0645\u0643\u062a\u0628\u0629 \u0627\u0644\u0631\u0642\u0645\u064a\u0629 \u0648\u0627\u0644\u0634\u0627\u0637\u0626 \u0648\u0627\u0644\u0645\u064a\u0646\u0627\u0621\u060c \u0648\u0627\u0644\u0623\u0639\u064a\u0627\u062f \u0627\u0644\u0628\u0627\u0633\u0643\u064a\u0629 \u0641\u064a \u0627\u0644\u062a\u0642\u0648\u064a\u0645.|&#10;Sin cookies ni anuncios \u00b7 tu progreso se guarda solo en este dispositivo \u00b7 m\u00fasica original y melod\u00edas tradicionales vascas (Haurtxo polita, Hator hator)|Cookierik eta iragarkirik gabe \u00b7 zure aurrerapena gailu honetan bakarrik gordetzen da \u00b7 jatorrizko musika eta euskal doinu tradizionalak (Haurtxo polita, Hator hator)|Sense galetes ni anuncis \u00b7 el teu progr\u00e9s es guarda nom\u00e9s en aquest dispositiu \u00b7 m\u00fasica original i melodies tradicionals basques (Haurtxo polita, Hator hator)|Sen cookies nin anuncios \u00b7 o teu progreso g\u00e1rdase s\u00f3 neste dispositivo \u00b7 m\u00fasica orixinal e melod\u00edas tradicionais vascas (Haurtxo polita, Hator hator)|No cookies or ads \u00b7 your progress is saved only on this device \u00b7 original music and traditional Basque melodies (Haurtxo polita, Hator hator)|Sans cookies ni publicit\u00e9s \u00b7 votre progression est enregistr\u00e9e uniquement sur cet appareil \u00b7 musique originale et m\u00e9lodies traditionnelles basques (Haurtxo polita, Hator hator)|Keine Cookies, keine Werbung \u00b7 dein Fortschritt wird nur auf diesem Ger\u00e4t gespeichert \u00b7 Originalmusik und traditionelle baskische Melodien (Haurtxo polita, Hator hator)|Niente cookie n\u00e9 pubblicit\u00e0 \u00b7 i tuoi progressi restano solo su questo dispositivo \u00b7 musica originale e melodie tradizionali basche (Haurtxo polita, Hator hator)|\u0411\u0435\u0437 cookie \u0438 \u0440\u0435\u043a\u043b\u0430\u043c\u044b \u00b7 \u0432\u0430\u0448 \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u044d\u0442\u043e\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u00b7 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u0443\u0437\u044b\u043a\u0430 \u0438 \u0442\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0431\u0430\u0441\u043a\u0441\u043a\u0438\u0435 \u043c\u0435\u043b\u043e\u0434\u0438\u0438 (Haurtxo polita, Hator hator)|\u65e0 Cookie\u3001\u65e0\u5e7f\u544a \u00b7 \u8fdb\u5ea6\u4ec5\u4fdd\u5b58\u5728\u6b64\u8bbe\u5907\u4e0a \u00b7 \u539f\u521b\u97f3\u4e50\u4e0e\u5df4\u65af\u514b\u4f20\u7edf\u65cb\u5f8b\uff08Haurtxo polita\u3001Hator hator\uff09|Geen koekies of advertensies \u00b7 jou vordering word net op hierdie toestel gestoor \u00b7 oorspronklike musiek en tradisionele Baskiese melodie\u00eb (Haurtxo polita, Hator hator)|\u0628\u0644\u0627 \u0645\u0644\u0641\u0627\u062a \u062a\u0639\u0631\u064a\u0641 \u0627\u0631\u062a\u0628\u0627\u0637 \u0623\u0648 \u0625\u0639\u0644\u0627\u0646\u0627\u062a \u00b7 \u064a\u064f\u062d\u0641\u0638 \u062a\u0642\u062f\u0645\u0643 \u0639\u0644\u0649 \u0647\u0630\u0627 \u0627\u0644\u062c\u0647\u0627\u0632 \u0641\u0642\u0637 \u00b7 \u0645\u0648\u0633\u064a\u0642\u0649 \u0623\u0635\u0644\u064a\u0629 \u0648\u0623\u0644\u062d\u0627\u0646 \u0628\u0627\u0633\u0643\u064a\u0629 \u062a\u0642\u0644\u064a\u062f\u064a\u0629 (Haurtxo polita, Hator hator)|&#10;Sin cookies ni anuncios \u00b7 tu progreso se guarda solo en este dispositivo \u00b7 m\u00fasica original|Cookierik eta iragarkirik gabe \u00b7 zure aurrerapena gailu honetan bakarrik gordetzen da \u00b7 jatorrizko musika|Sense galetes ni anuncis \u00b7 el teu progr\u00e9s es guarda nom\u00e9s en aquest dispositiu \u00b7 m\u00fasica original|Sen cookies nin anuncios \u00b7 o teu progreso g\u00e1rdase s\u00f3 neste dispositivo \u00b7 m\u00fasica orixinal|No cookies or ads \u00b7 your progress is saved only on this device \u00b7 original music|Sans cookies ni publicit\u00e9s \u00b7 votre progression est enregistr\u00e9e uniquement sur cet appareil \u00b7 musique originale|Keine Cookies, keine Werbung \u00b7 dein Fortschritt wird nur auf diesem Ger\u00e4t gespeichert \u00b7 Originalmusik|Niente cookie n\u00e9 pubblicit\u00e0 \u00b7 i tuoi progressi restano solo su questo dispositivo \u00b7 musica originale|\u0411\u0435\u0437 cookie \u0438 \u0440\u0435\u043a\u043b\u0430\u043c\u044b \u00b7 \u0432\u0430\u0448 \u043f\u0440\u043e\u0433\u0440\u0435\u0441\u0441 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u044d\u0442\u043e\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435 \u00b7 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u0430\u044f \u043c\u0443\u0437\u044b\u043a\u0430|\u65e0 Cookie\u3001\u65e0\u5e7f\u544a \u00b7 \u8fdb\u5ea6\u4ec5\u4fdd\u5b58\u5728\u6b64\u8bbe\u5907\u4e0a \u00b7 \u539f\u521b\u97f3\u4e50|Geen koekies of advertensies \u00b7 jou vordering word net op hierdie toestel gestoor \u00b7 oorspronklike musiek|\u0628\u0644\u0627 \u0645\u0644\u0641\u0627\u062a \u062a\u0639\u0631\u064a\u0641 \u0627\u0631\u062a\u0628\u0627\u0637 \u0623\u0648 \u0625\u0639\u0644\u0627\u0646\u0627\u062a \u00b7 \u064a\u064f\u062d\u0641\u0638 \u062a\u0642\u062f\u0645\u0643 \u0639\u0644\u0649 \u0647\u0630\u0627 \u0627\u0644\u062c\u0647\u0627\u0632 \u0641\u0642\u0637 \u00b7 \u0645\u0648\u0633\u064a\u0642\u0649 \u0623\u0635\u0644\u064a\u0629|&#10;Tomatera con tutor, cosechada en La Huerta esta ma\u00f1ana.|Tutoreko tomate-landarea, gaur goizean Baratzan bilduta.|Tomaquera amb tutor, collida a L'Hort aquest mat\u00ed.|Tomateira con tutor, colleita da Horta esta ma\u00f1\u00e1.|Staked tomato plant, picked in the Garden this morning.|Tomate sur tuteur, cueillie au Potager ce matin.|Tomate am St\u00fctzstab, heute Morgen im Garten geerntet.|Pomodoro con tutore, raccolto stamattina nell'Orto.|\u041f\u043e\u0434\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0442\u043e\u043c\u0430\u0442\u044b, \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0441\u0435\u0433\u043e\u0434\u043d\u044f \u0443\u0442\u0440\u043e\u043c \u0432 \u041e\u0433\u043e\u0440\u043e\u0434\u0435.|\u7528\u652f\u67b6\u79cd\u690d\u7684\u756a\u8304\uff0c\u4eca\u65e9\u5728\u83dc\u56ed\u91c7\u6458\u3002|Tamatie aan 'n stut, vanoggend in die Tuin gepluk.|\u0637\u0645\u0627\u0637\u0645 \u0645\u062f\u0639\u0648\u0645\u0629 \u0628\u0639\u0635\u0627\u060c \u0642\u064f\u0637\u0641\u062a \u0635\u0628\u0627\u062d \u0627\u0644\u064a\u0648\u0645 \u0645\u0646 \u0627\u0644\u062d\u062f\u064a\u0642\u0629.|&#10;Hoja tierna del bancal, riego LUR subterr\u00e1neo.|Ohereko hosto samurra, LUR lurpeko ureztatzearekin.|Fulla tendra del bancal, reg LUR subterrani.|Folla tenra do bancal, rega LUR subterr\u00e1nea.|Tender leaf from the plot, with underground LUR irrigation.|Feuille tendre de la planche, irrigation LUR souterraine.|Zartes Blatt vom Beet, mit unterirdischer LUR-Bew\u00e4sserung.|Foglia tenera dell'aiuola, irrigazione LUR sotterranea.|\u041d\u0435\u0436\u043d\u044b\u0439 \u043b\u0438\u0441\u0442 \u0441 \u0433\u0440\u044f\u0434\u043a\u0438, \u043f\u043e\u0434\u0437\u0435\u043c\u043d\u044b\u0439 \u043f\u043e\u043b\u0438\u0432 LUR.|\u83dc\u7566\u91cc\u7684\u5ae9\u53f6\uff0c\u91c7\u7528\u5730\u4e0bLUR\u704c\u6e89\u3002|Sagte blaar uit die bed, ondergrondse LUR-besproeiing.|\u0648\u0631\u0642\u0629 \u0637\u0631\u064a\u0629 \u0645\u0646 \u0627\u0644\u062d\u0648\u0636\u060c \u0628\u0631\u064a\u0651 LUR \u062c\u0648\u0641\u064a.|&#10;Rojos y amarillos, madurados en mata.|Gorriak eta horiak, landarean helduak.|Vermells i grocs, madurats a la mata.|Vermellos e amarelos, madurados na mata.|Red and yellow, ripened on the plant.|Rouges et jaunes, m\u00fbris sur le pied.|Rot und gelb, am Strauch gereift.|Rossi e gialli, maturati sulla pianta.|\u041a\u0440\u0430\u0441\u043d\u044b\u0435 \u0438 \u0436\u0451\u043b\u0442\u044b\u0435, \u0441\u043e\u0437\u0440\u0435\u0432\u0448\u0438\u0435 \u043d\u0430 \u043a\u0443\u0441\u0442\u0435.|\u7ea2\u8272\u548c\u9ec4\u8272\uff0c\u5728\u690d\u682a\u4e0a\u81ea\u7136\u6210\u719f\u3002|Rooi en geel, aan die plant ryp geword.|\u0623\u062d\u0645\u0631 \u0648\u0623\u0635\u0641\u0631\u060c \u0646\u0636\u062c\u0627 \u0639\u0644\u0649 \u0627\u0644\u0646\u0628\u062a\u0629.|&#10;Variedad antigua morada, sin tratamientos.|Barietate zahar more, tratamendurik gabe.|Varietat antiga morada, sense tractaments.|Variedade antiga morada, sen tratamentos.|Old purple variety, untreated.|Ancienne vari\u00e9t\u00e9 violette, sans traitements.|Alte violette Sorte, unbehandelt.|Antica variet\u00e0 viola, senza trattamenti.|\u0421\u0442\u0430\u0440\u0438\u043d\u043d\u044b\u0439 \u0444\u0438\u043e\u043b\u0435\u0442\u043e\u0432\u044b\u0439 \u0441\u043e\u0440\u0442, \u0431\u0435\u0437 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438.|\u53e4\u8001\u7684\u7d2b\u8272\u54c1\u79cd\uff0c\u672a\u7ecf\u4efb\u4f55\u5904\u7406\u3002|Ou pers vari\u00ebteit, onbehandeld.|\u0635\u0646\u0641 \u0642\u062f\u064a\u0645 \u0628\u0646\u0641\u0633\u062c\u064a\u060c \u062f\u0648\u0646 \u0645\u0639\u0627\u0644\u062c\u0629.|&#10;Molida en piedra y conservada en fr\u00edo activo.|Harrian ehoa eta hotz aktiboan kontserbatua.|Molta amb pedra i conservada en fred actiu.|Mo\u00edda en pedra e conservada en fr\u00edo activo.|Stone-ground and kept in active cold storage.|Moulue sur pierre et conserv\u00e9e au froid actif.|Steingemahlen und in aktiver K\u00fchlung gelagert.|Macinata a pietra e conservata al freddo attivo.|\u041f\u043e\u043c\u043e\u043b \u043d\u0430 \u043a\u0430\u043c\u043d\u0435, \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c \u0445\u043e\u043b\u043e\u0434\u0435.|\u77f3\u78e8\u7814\u78e8\uff0c\u4e3b\u52a8\u51b7\u85cf\u4fdd\u5b58\u3002|Klipgemaal en in aktiewe koue bewaar.|\u0645\u0637\u062d\u0648\u0646\u0629 \u0628\u0627\u0644\u062d\u062c\u0631 \u0648\u0645\u062d\u0641\u0648\u0638\u0629 \u0628\u062a\u0628\u0631\u064a\u062f \u0646\u0634\u0637.|&#10;Grano entero de trigo local, sin refinar.|Bertako gari ale osoa, fintzeke.|Gra sencer de blat local, sense refinar.|Gran enteiro de trigo local, sen refinar.|Whole grain of local wheat, unrefined.|Grain entier de bl\u00e9 local, non raffin\u00e9.|Ganzes Korn von heimischem Weizen, unraffiniert.|Chicco intero di grano locale, non raffinato.|\u0426\u0435\u043b\u044c\u043d\u043e\u0435 \u0437\u0435\u0440\u043d\u043e \u043c\u0435\u0441\u0442\u043d\u043e\u0439 \u043f\u0448\u0435\u043d\u0438\u0446\u044b, \u043d\u0435\u0440\u0430\u0444\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435.|\u672c\u5730\u5c0f\u9ea6\u5168\u7c92\uff0c\u672a\u7ecf\u7cbe\u5236\u3002|Volgraan van plaaslike koring, onverfyn.|\u062d\u0628\u0648\u0628 \u0643\u0627\u0645\u0644\u0629 \u0645\u0646 \u0627\u0644\u0642\u0645\u062d \u0627\u0644\u0645\u062d\u0644\u064a\u060c \u063a\u064a\u0631 \u0645\u0643\u0631\u0651\u0631\u0629.|&#10;Variedad tradicional del Banco de Semillas (\u221218 \u00b0C).|Hazi-bankuko barietate tradizionala (\u221218 \u00b0C).|Varietat tradicional del Banc de Llavors (\u221218 \u00b0C).|Variedade tradicional do Banco de Sementes (\u221218 \u00b0C).|Traditional variety from the Seed Bank (\u221218 \u00b0C).|Vari\u00e9t\u00e9 traditionnelle de la Banque de Graines (\u221218 \u00b0C).|Traditionelle Sorte aus der Saatgutbank (\u221218 \u00b0C).|Variet\u00e0 tradizionale della Banca dei Semi (\u221218 \u00b0C).|\u0422\u0440\u0430\u0434\u0438\u0446\u0438\u043e\u043d\u043d\u044b\u0439 \u0441\u043e\u0440\u0442 \u0438\u0437 \u0411\u0430\u043d\u043a\u0430 \u0441\u0435\u043c\u044f\u043d (\u221218 \u00b0C).|\u79cd\u5b50\u5e93\u4e2d\u7684\u4f20\u7edf\u54c1\u79cd\uff08\u221218 \u00b0C\uff09\u3002|Tradisionele vari\u00ebteit uit die Saadbank (\u221218 \u00b0C).|\u0635\u0646\u0641 \u062a\u0642\u0644\u064a\u062f\u064a \u0645\u0646 \u0628\u0646\u0643 \u0627\u0644\u0628\u0630\u0648\u0631 (\u221218 \u00b0\u0645).|&#10;Para resembrar: intercambio libre entre vecinas.|Berriz ereiteko: auzokideen arteko trukaketa librea.|Per tornar a sembrar: intercanvi lliure entre ve\u00efnes.|Para resementar: intercambio libre entre veci\u00f1as.|For replanting: free exchange between neighbours.|Pour ressemer : \u00e9change libre entre voisines.|Zum Neuauss\u00e4en: freier Tausch unter Nachbarinnen.|Per riseminare: scambio libero tra vicine.|\u0414\u043b\u044f \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u0433\u043e \u043f\u043e\u0441\u0435\u0432\u0430: \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u0439 \u043e\u0431\u043c\u0435\u043d \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0441\u0435\u0434\u043a\u0430\u043c\u0438.|\u7528\u4e8e\u518d\u6b21\u64ad\u79cd\uff1a\u90bb\u91cc\u95f4\u81ea\u7531\u4ea4\u6362\u3002|Om weer te saai: vrye ruil tussen bure.|\u0644\u0625\u0639\u0627\u062f\u0629 \u0627\u0644\u0632\u0631\u0627\u0639\u0629: \u062a\u0628\u0627\u062f\u0644 \u062d\u0631 \u0628\u064a\u0646 \u0627\u0644\u062c\u0627\u0631\u0627\u062a.|&#10;Artesanal comunitario, 4 meses de cueva.|Komunitateko artisau-gazta, 4 hilabete kobazuloan.|Artesanal comunitari, 4 mesos de cova.|Artesanal comunitario, 4 meses de cova.|Community-made, aged 4 months in the cave.|Artisanal et communautaire, 4 mois de cave.|Gemeinschaftlich handwerklich, 4 Monate in der H\u00f6hle gereift.|Artigianale comunitario, 4 mesi di grotta.|\u041e\u0431\u0449\u0438\u043d\u043d\u043e\u0435 \u0440\u0435\u043c\u0435\u0441\u043b\u0435\u043d\u043d\u043e\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0441\u0442\u0432\u043e, 4 \u043c\u0435\u0441\u044f\u0446\u0430 \u0432 \u043f\u0435\u0449\u0435\u0440\u0435.|\u793e\u533a\u624b\u5de5\u5236\u4f5c\uff0c\u5728\u6d1e\u7a9f\u4e2d\u719f\u62104\u4e2a\u6708\u3002|Gemeenskap-ambagtelik, 4 maande in die grot.|\u062d\u0650\u0631\u0641\u064a \u0645\u062c\u062a\u0645\u0639\u064a\u060c \u0623\u0631\u0628\u0639\u0629 \u0623\u0634\u0647\u0631 \u0641\u064a \u0627\u0644\u0643\u0647\u0641.|&#10;Orde\u00f1ada por la ma\u00f1ana, envase retornable.|Goizean jetzia, ontzi berrerabilgarrian.|Munyida al mat\u00ed, env\u00e0s retornable.|Muxida pola ma\u00f1\u00e1, envase retornable.|Milked in the morning, returnable bottle.|Traite le matin, bouteille consign\u00e9e.|Morgens gemolken, Mehrwegflasche.|Munta al mattino, bottiglia restituibile.|\u0423\u0442\u0440\u0435\u043d\u043d\u0435\u0433\u043e \u0443\u0434\u043e\u044f, \u0432\u043e\u0437\u0432\u0440\u0430\u0442\u043d\u0430\u044f \u0442\u0430\u0440\u0430.|\u6e05\u6668\u6324\u5976\uff0c\u4f7f\u7528\u53ef\u56de\u6536\u5bb9\u5668\u3002|In die oggend gemelk, terugbesorgbare bottel.|\u062d\u0644\u064a\u0628 \u0627\u0644\u0635\u0628\u0627\u062d\u060c \u0641\u064a \u0639\u0628\u0648\u0629 \u0642\u0627\u0628\u0644\u0629 \u0644\u0644\u0625\u0631\u062c\u0627\u0639.|&#10;Fermento natural, sin az\u00facares a\u00f1adidos.|Hartzigarri naturala, azukre gehigarririk gabe.|Ferment natural, sense sucres afegits.|Fermento natural, sen azucres engadidos.|Natural ferment, no added sugars.|Ferment naturel, sans sucres ajout\u00e9s.|Nat\u00fcrliches Ferment, ohne Zuckerzusatz.|Fermento naturale, senza zuccheri aggiunti.|\u041d\u0430\u0442\u0443\u0440\u0430\u043b\u044c\u043d\u0430\u044f \u0437\u0430\u043a\u0432\u0430\u0441\u043a\u0430, \u0431\u0435\u0437 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0441\u0430\u0445\u0430\u0440\u0430.|\u5929\u7136\u53d1\u9175\uff0c\u4e0d\u6dfb\u52a0\u7cd6\u3002|Natuurlike fermentasie, geen bygevoegde suiker.|\u062a\u062e\u0645\u064a\u0631 \u0637\u0628\u064a\u0639\u064a \u0628\u0644\u0627 \u0633\u0643\u0631 \u0645\u0636\u0627\u0641.|&#10;Al estilo del pueblo, con leche de oveja.|Herriko erara, ardi-esnearekin.|A l'estil del poble, amb llet d'ovella.|Ao estilo do pobo, con leite de ovella.|Village style, made with sheep's milk.|\u00c0 la fa\u00e7on du village, au lait de brebis.|Nach Art des Dorfes, mit Schafsmilch.|Alla maniera del paese, con latte di pecora.|\u041f\u043e-\u0434\u0435\u0440\u0435\u0432\u0435\u043d\u0441\u043a\u0438, \u0438\u0437 \u043e\u0432\u0435\u0447\u044c\u0435\u0433\u043e \u043c\u043e\u043b\u043e\u043a\u0430.|\u5c0f\u9547\u98ce\u5473\uff0c\u7528\u7f8a\u5976\u5236\u6210\u3002|Dorpstyl, met skaapmelk.|\u0639\u0644\u0649 \u0637\u0631\u064a\u0642\u0629 \u0627\u0644\u0642\u0631\u064a\u0629\u060c \u0628\u062d\u0644\u064a\u0628 \u0627\u0644\u0623\u063a\u0646\u0627\u0645.|&#10;Variedad local adaptada a poca agua.|Bertako barietatea, ur gutxira egokitua.|Varietat local adaptada a poca aigua.|Variedade local adaptada a pouca auga.|Local variety adapted to little water.|Vari\u00e9t\u00e9 locale adapt\u00e9e \u00e0 peu d'eau.|Lokale Sorte, an wenig Wasser angepasst.|Variet\u00e0 locale adattata a poca acqua.|\u041c\u0435\u0441\u0442\u043d\u044b\u0439 \u0441\u043e\u0440\u0442, \u043f\u0440\u0438\u0441\u043f\u043e\u0441\u043e\u0431\u043b\u0435\u043d\u043d\u044b\u0439 \u043a \u043c\u0430\u043b\u043e\u043c\u0443 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0443 \u0432\u043e\u0434\u044b.|\u9002\u5e94\u5c11\u6c34\u73af\u5883\u7684\u672c\u5730\u54c1\u79cd\u3002|Plaaslike vari\u00ebteit wat by min water aangepas is.|\u0635\u0646\u0641 \u0645\u062d\u0644\u064a \u0645\u062a\u0643\u064a\u0641 \u0645\u0639 \u0642\u0644\u0629 \u0627\u0644\u0645\u064a\u0627\u0647.|&#10;R\u00fastico, resiste el secano.|Zakarra, lehorteari eusten dio.|R\u00fastic, resisteix el sec\u00e0.|R\u00fastico, resiste o seca\u00f1o.|Hardy, withstands dry farming.|Rustique, r\u00e9siste \u00e0 la culture s\u00e8che.|Robust, \u00fcbersteht Trockenanbau.|Rustico, resiste all'asciutto.|\u041d\u0435\u043f\u0440\u0438\u0445\u043e\u0442\u043b\u0438\u0432\u044b\u0439, \u043f\u0435\u0440\u0435\u043d\u043e\u0441\u0438\u0442 \u0437\u0430\u0441\u0443\u0445\u0443.|\u76ae\u5b9e\u8010\u65f1\uff0c\u9002\u5408\u65f1\u5730\u79cd\u690d\u3002|Sterk, verduur dro\u00eblandbou.|\u0645\u062a\u064a\u0646\u060c \u064a\u062a\u062d\u0645\u0644 \u0627\u0644\u0632\u0631\u0627\u0639\u0629 \u0627\u0644\u062c\u0627\u0641\u0629.|&#10;Peque\u00f1a y sabrosa, cultivo de rotaci\u00f3n.|Txikia eta goxoa, txandakako laborantza.|Petita i saborosa, cultiu de rotaci\u00f3.|Pequena e saborosa, cultivo de rotaci\u00f3n.|Small and tasty, a rotation crop.|Petite et savoureuse, culture de rotation.|Klein und schmackhaft, Fruchtwechselkultur.|Piccola e saporita, coltura di rotazione.|\u041c\u0435\u043b\u043a\u0430\u044f \u0438 \u0432\u043a\u0443\u0441\u043d\u0430\u044f, \u043a\u0443\u043b\u044c\u0442\u0443\u0440\u0430 \u0441\u0435\u0432\u043e\u043e\u0431\u043e\u0440\u043e\u0442\u0430.|\u4e2a\u5c0f\u5473\u7f8e\uff0c\u9002\u5408\u8f6e\u4f5c\u3002|Klein en smaaklik, wisselbougewas.|\u0635\u063a\u064a\u0631\u0629 \u0648\u0644\u0630\u064a\u0630\u0629\u060c \u0645\u062d\u0635\u0648\u0644 \u062a\u0646\u0627\u0648\u0628.|&#10;Prote\u00edna de legumbres impresa en la Zona Industrial.|Lekaleen proteina, Industria Eremuan inprimatua.|Prote\u00efna de llegums impresa a la Zona Industrial.|Prote\u00edna de legumes impresa na Zona Industrial.|Legume protein printed in the Industrial Zone.|Prot\u00e9ine de l\u00e9gumineuses imprim\u00e9e dans la Zone Industrielle.|H\u00fclsenfrucht-Protein, gedruckt in der Industriezone.|Proteina di legumi stampata nella Zona Industriale.|\u0411\u0435\u043b\u043e\u043a \u0431\u043e\u0431\u043e\u0432\u044b\u0445, \u043d\u0430\u043f\u0435\u0447\u0430\u0442\u0430\u043d\u043d\u044b\u0439 \u0432 \u041f\u0440\u043e\u043c\u0437\u043e\u043d\u0435.|\u5728\u5de5\u4e1a\u533a\u6253\u5370\u7684\u8c46\u7c7b\u86cb\u767d\u3002|Peulgewasprote\u00efen wat in die Industri\u00eble Sone gedruk is.|\u0628\u0631\u0648\u062a\u064a\u0646 \u0627\u0644\u0628\u0642\u0648\u0644\u064a\u0627\u062a \u0645\u0637\u0628\u0648\u0639 \u0641\u064a \u0627\u0644\u0645\u0646\u0637\u0642\u0629 \u0627\u0644\u0635\u0646\u0627\u0639\u064a\u0629.|&#10;stock|stock|estoc|existencias|stock|stock|Bestand|scorte|\u043e\u0441\u0442\u0430\u0442\u043e\u043a|\u5e93\u5b58|voorraad|\u0627\u0644\u0645\u062e\u0632\u0648\u0646|&#10;Granos y Ra\u00edces|Aleak eta Sustraiak|Grans i Arrels|Grans e Ra\u00edces|Grains &amp; Roots|Grains et Racines|Getreide &amp; Wurzeln|Cereali e Radici|\u0417\u043b\u0430\u043a\u0438 \u0438 \u043a\u043e\u0440\u043d\u0435\u043f\u043b\u043e\u0434\u044b|\u8c37\u7269\u4e0e\u6839\u830e|Graan en Wortels|\u0627\u0644\u062d\u0628\u0648\u0628 \u0648\u0627\u0644\u062c\u0630\u0648\u0631|&#10;Diario del pueblo|Herriko egunkaria|Diari del poble|Diario do pobo|Village journal|Journal du village|Dorftagebuch|Diario del paese|\u0414\u043d\u0435\u0432\u043d\u0438\u043a \u0434\u0435\u0440\u0435\u0432\u043d\u0438|\u6751\u5e84\u65e5\u8bb0|Dorpsjoernaal|\u064a\u0648\u0645\u064a\u0627\u062a \u0627\u0644\u0642\u0631\u064a\u0629|Diario del pueblo|&#10;Se va llenando solo con lo que ves. Sin prisas y sin puntos.|Ikusten duzunarekin bere kasa betetzen da. Presarik gabe eta punturik gabe.|S'omple sol amb el que veus. Sense pressa i sense punts.|\u00c9nchese soo co que ves. Sen pr\u00e9sas e sen puntos.|It fills itself with what you see. No rush and no points.|Il se remplit tout seul avec ce que tu vois. Sans h\u00e2te et sans points.|Es f\u00fcllt sich von selbst mit dem, was du siehst. Ohne Eile und ohne Punkte.|Si riempie da solo con ci\u00f2 che vedi. Senza fretta e senza punti.|\u041e\u043d \u0437\u0430\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0441\u0430\u043c \u0442\u0435\u043c, \u0447\u0442\u043e \u0442\u044b \u0432\u0438\u0434\u0438\u0448\u044c. \u0411\u0435\u0437 \u0441\u043f\u0435\u0448\u043a\u0438 \u0438 \u0431\u0435\u0437 \u043e\u0447\u043a\u043e\u0432.|\u5b83\u4f1a\u968f\u7740\u4f60\u7684\u6240\u89c1\u81ea\u52a8\u8bb0\u5f55\u3002\u4e0d\u8d76\u65f6\u95f4,\u4e5f\u6ca1\u6709\u79ef\u5206\u3002|Dit vul vanself met wat jy sien. Sonder haas en sonder punte.|\u064a\u0645\u062a\u0644\u0626 \u0648\u062d\u062f\u0647 \u0628\u0645\u0627 \u062a\u0631\u0627\u0647. \u0628\u0644\u0627 \u0627\u0633\u062a\u0639\u062c\u0627\u0644 \u0648\u0628\u0644\u0627 \u0646\u0642\u0627\u0637.|Se va llenando solo con lo que ves. Sin prisas y sin puntos.|&#10;Herbario|Belardegia|Herbari|Herbario|Herbarium|Herbier|Herbarium|Erbario|\u0413\u0435\u0440\u0431\u0430\u0440\u0438\u0439|\u690d\u7269\u6807\u672c|Herbarium|\u0645\u062c\u0645\u0648\u0639\u0629 \u0627\u0644\u0646\u0628\u0627\u062a\u0627\u062a|Herbario|&#10;Fauna marina|Itsas fauna|Fauna marina|Fauna mari\u00f1a|Marine life|Faune marine|Meerestiere|Fauna marina|\u041c\u043e\u0440\u0441\u043a\u0430\u044f \u0444\u0430\u0443\u043d\u0430|\u6d77\u6d0b\u751f\u7269|Seelewe|\u0627\u0644\u062d\u064a\u0627\u0629 \u0627\u0644\u0628\u062d\u0631\u064a\u0629|Fauna marina|&#10;Estaciones y fiestas|Urtaroak eta jaiak|Estacions i festes|Estaci\u00f3ns e festas|Seasons and festivals|Saisons et f\u00eates|Jahreszeiten und Feste|Stagioni e feste|\u0412\u0440\u0435\u043c\u0435\u043d\u0430 \u0433\u043e\u0434\u0430 \u0438 \u043f\u0440\u0430\u0437\u0434\u043d\u0438\u043a\u0438|\u5b63\u8282\u4e0e\u8282\u65e5|Seisoene en feeste|\u0627\u0644\u0641\u0635\u0648\u0644 \u0648\u0627\u0644\u0623\u0639\u064a\u0627\u062f|Estaciones y fiestas|&#10;Momentos de las chicas|Neskei buruzko uneak|Moments de les xiques|Momentos das rapazas|The girls' moments|Les moments des filles|Momente der M\u00e4dels|I momenti delle ragazze|\u041c\u043e\u043c\u0435\u043d\u0442\u044b \u0434\u0435\u0432\u0443\u0448\u0435\u043a|\u5973\u5b69\u4eec\u7684\u65f6\u523b|Die meisies se oomblikke|\u0644\u062d\u0638\u0627\u062a \u0627\u0644\u0641\u062a\u064a\u0627\u062a|Momentos de las chicas|&#10;A\u00fan por descubrir\u2026|Oraindik aurkitzeko\u2026|Encara per descobrir\u2026|A\u00ednda por descubrir\u2026|Still to discover\u2026|Encore \u00e0 d\u00e9couvrir\u2026|Noch zu entdecken\u2026|Ancora da scoprire\u2026|\u0415\u0449\u0451 \u043f\u0440\u0435\u0434\u0441\u0442\u043e\u0438\u0442 \u043e\u0442\u043a\u0440\u044b\u0442\u044c\u2026|\u7b49\u5f85\u53d1\u73b0\u2026\u2026|Nog om te ontdek\u2026|\u0644\u0645 \u064a\u064f\u0643\u062a\u0634\u0641 \u0628\u0639\u062f\u2026|A\u00fan por descubrir\u2026|&#10;Nuevo en el diario:|Berria egunkarian:|Nou al diari:|Novo no diario:|New in the journal:|Nouveau dans le journal :|Neu im Tagebuch:|Novit\u00e0 nel diario:|\u041d\u043e\u0432\u043e\u0435 \u0432 \u0434\u043d\u0435\u0432\u043d\u0438\u043a\u0435:|\u65e5\u8bb0\u65b0\u589e:|Nuut in die joernaal:|\u062c\u062f\u064a\u062f \u0641\u064a \u0627\u0644\u064a\u0648\u0645\u064a\u0627\u062a:|Nuevo en el diario:|&#10;Dos chicas se han enamorado|Bi neska maitemindu dira|Dues xiques s'han enamorat|D\u00faas rapazas namor\u00e1ronse|Two girls have fallen in love|Deux filles sont tomb\u00e9es amoureuses|Zwei M\u00e4dels haben sich verliebt|Due ragazze si sono innamorate|\u0414\u0432\u0435 \u0434\u0435\u0432\u0443\u0448\u043a\u0438 \u0432\u043b\u044e\u0431\u0438\u043b\u0438\u0441\u044c|\u4e24\u4e2a\u5973\u5b69\u5760\u5165\u4e86\u7231\u6cb3|Twee meisies het verlief geraak|\u0641\u062a\u0627\u062a\u0627\u0646 \u0648\u0642\u0639\u062a\u0627 \u0641\u064a \u0627\u0644\u062d\u0628|Dos chicas se han enamorado|&#10;Primera noche: el pueblo duerme|Lehen gaua: herria lo dago|Primera nit: el poble dorm|Primeira noite: o pobo dorme|First night: the village sleeps|Premi\u00e8re nuit : le village dort|Erste Nacht: das Dorf schl\u00e4ft|Prima notte: il paese dorme|\u041f\u0435\u0440\u0432\u0430\u044f \u043d\u043e\u0447\u044c: \u0434\u0435\u0440\u0435\u0432\u043d\u044f \u0441\u043f\u0438\u0442|\u7b2c\u4e00\u591c:\u6751\u5e84\u5165\u7761\u4e86|Eerste nag: die dorp slaap|\u0627\u0644\u0644\u064a\u0644\u0629 \u0627\u0644\u0623\u0648\u0644\u0649: \u0627\u0644\u0642\u0631\u064a\u0629 \u0646\u0627\u0626\u0645\u0629|Primera noche: el pueblo duerme|&#10;Oto\u00f1o|Udazkena|Tardor|Outono|Autumn|Automne|Herbst|Autunno|\u041e\u0441\u0435\u043d\u044c|\u79cb\u5929|Herfs|\u0627\u0644\u062e\u0631\u064a\u0641|Oto\u00f1o|&#10;Primavera|Udaberria|Primavera|Primavera|Spring|Printemps|Fr\u00fchling|Primavera|\u0412\u0435\u0441\u043d\u0430|\u6625\u5929|Lente|\u0627\u0644\u0631\u0628\u064a\u0639|Primavera|&#10;Verano|Uda|Estiu|Ver\u00e1n|Summer|\u00c9t\u00e9|Sommer|Estate|\u041b\u0435\u0442\u043e|\u590f\u5929|Somer|\u0627\u0644\u0635\u064a\u0641|Verano|&#10;Invierno|Negua|Hivern|Inverno|Winter|Hiver|Winter|Inverno|\u0417\u0438\u043c\u0430|\u51ac\u5929|Winter|\u0627\u0644\u0634\u062a\u0627\u0621|Invierno|&#10;Diario|Egunkaria|Diari|Diario|Journal|Journal|Tagebuch|Diario|\u0414\u043d\u0435\u0432\u043d\u0438\u043a|\u65e5\u8bb0|Joernaal|\u0627\u0644\u064a\u0648\u0645\u064a\u0627\u062a|Diario|&#10;Estrella de mar|Itsas izarra|Estrella de mar|Estrela de mar|Starfish|\u00c9toile de mer|Seestern|Stella marina|\u041c\u043e\u0440\u0441\u043a\u0430\u044f \u0437\u0432\u0435\u0437\u0434\u0430|\u6d77\u661f|Seester|\u0646\u062c\u0645 \u0627\u0644\u0628\u062d\u0631|Estrella de mar|&#10;An\u00e9mona|Anemonak|An\u00e8mone|An\u00e9mona|Anemone|An\u00e9mone|Anemone|Anemone|\u0410\u043d\u0435\u043c\u043e\u043d|\u6d77\u8475|Anemoon|\u0634\u0642\u0627\u0626\u0642 \u0627\u0644\u0628\u062d\u0631|An\u00e9mona|&#10;Banco de sardinas|Sardina-taldea|Banc de sardines|Banco de sardi\u00f1as|School of sardines|Banc de sardines|Sardinenschwarm|Banco di sardine|\u041a\u043e\u0441\u044f\u043a \u0441\u0430\u0440\u0434\u0438\u043d|\u6c99\u4e01\u9c7c\u7fa4|Skool sardyne|\u0633\u0631\u0628 \u0633\u0631\u062f\u064a\u0646|Banco de sardinas|&#10;Pradera de posidonia|Posidonia-belardia|Praderia de posid\u00f2nia|Pradar\u00eda de posidonia|Posidonia meadow|Herbier de posidonie|Posidonia-Wiese|Prateria di posidonia|\u041b\u0443\u0433 \u043f\u043e\u0441\u0438\u0434\u043e\u043d\u0438\u0438|\u6d77\u8349\u8349\u7538|Posidonia-weiveld|\u0645\u0631\u062c \u0627\u0644\u0628\u0648\u0633\u064a\u062f\u0648\u0646\u064a\u0627|Pradera de posidonia|&#10;Bosque de algas pardas|Alga marroien basoa|Bosc d'algues brunes|Bosque de algas pardas|Brown kelp forest|For\u00eat d'algues brunes|Wald aus Braunalgen|Foresta di alghe brune|\u041b\u0435\u0441 \u0431\u0443\u0440\u044b\u0445 \u0432\u043e\u0434\u043e\u0440\u043e\u0441\u043b\u0435\u0439|\u8910\u85fb\u68ee\u6797|Bruin kelpwoud|\u063a\u0627\u0628\u0629 \u0627\u0644\u0637\u062d\u0627\u0644\u0628 \u0627\u0644\u0628\u0646\u064a\u0629|Bosque de algas pardas|&#10;Postales|Postalak|Postals|Postais|Postcards|Cartes postales|Postkarten|Cartoline|\u041e\u0442\u043a\u0440\u044b\u0442\u043a\u0438|\u660e\u4fe1\u7247|Poskaarte|\u0628\u0637\u0627\u0642\u0627\u062a \u0628\u0631\u064a\u062f\u064a\u0629|Postales|&#10;Toca un puesto para hacer tu compra. Las chicas compran seg\u00fan su hambre; el cuaderno de la mesa muestra las cuentas.|Ukitu postu bat zure erosketa egiteko. Neskek gosearen arabera erosten dute; mahaiko koadernoak kontuak erakusten ditu.|Toca una parada per fer la teva compra. Les xiques compren segons la fam; el quadern de la taula mostra els comptes.|Toca un posto para facer a t\u00faa compra. As rapazas compran segundo a s\u00faa fame; o caderno da mesa amosa as contas.|Tap a stall to do your shopping. The girls buy according to their hunger; the notebook on the table shows the accounts.|Touche un \u00e9tal pour faire tes courses. Les filles ach\u00e8tent selon leur faim ; le cahier de la table montre les comptes.|Tippe auf einen Stand, um einzukaufen. Die M\u00e4dels kaufen nach Hunger; das Heft auf dem Tisch zeigt die Abrechnung.|Tocca una bancarella per fare la tua spesa. Le ragazze comprano secondo la fame; il quaderno sul tavolo mostra i conti.|\u041d\u0430\u0436\u043c\u0438 \u043d\u0430 \u043f\u0440\u0438\u043b\u0430\u0432\u043e\u043a, \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e\u043a\u0443\u043f\u043a\u0438. \u0414\u0435\u0432\u0443\u0448\u043a\u0438 \u043f\u043e\u043a\u0443\u043f\u0430\u044e\u0442 \u043f\u043e \u0433\u043e\u043b\u043e\u0434\u0443; \u0442\u0435\u0442\u0440\u0430\u0434\u044c \u043d\u0430 \u0441\u0442\u043e\u043b\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442 \u0440\u0430\u0441\u0447\u0451\u0442\u044b.|\u70b9\u6309\u644a\u4f4d\u5373\u53ef\u8d2d\u7269\u3002\u5973\u5b69\u4eec\u6309\u9965\u997f\u7a0b\u5ea6\u8d2d\u4e70;\u684c\u4e0a\u7684\u672c\u5b50\u663e\u793a\u8d26\u76ee\u3002|Tik op \u2019n stalletjie om te koop. Die meisies koop volgens hul honger; die boek op die tafel wys die rekeninge.|\u0627\u0644\u0645\u0633 \u0643\u0634\u0643\u064b\u0627 \u0644\u062a\u062a\u0633\u0648\u0651\u0642. \u062a\u0634\u062a\u0631\u064a \u0627\u0644\u0641\u062a\u064a\u0627\u062a \u062d\u0633\u0628 \u062c\u0648\u0639\u0647\u0646\u061b \u0648\u062f\u0641\u062a\u0631 \u0627\u0644\u0637\u0627\u0648\u0644\u0629 \u064a\u0639\u0631\u0636 \u0627\u0644\u062d\u0633\u0627\u0628\u0627\u062a.|Toca un puesto para hacer tu compra. Las chicas compran seg\u00fan su hambre; el cuaderno de la mesa muestra las cuentas.|&#10;Una chica sonri\u00f3 porque la acompa\u00f1aste|Neska batek irribarre egin zuen lagundu zenuelako|Una xica va somriure perqu\u00e8 l'has acompanyada|Unha rapaza sorriu porque a acompa\u00f1aches|A girl smiled because you walked her over|Une fille a souri parce que tu l'as accompagn\u00e9e|Ein M\u00e4del hat gel\u00e4chelt, weil du sie begleitet hast|Una ragazza ha sorriso perch\u00e9 l'hai accompagnata|\u0414\u0435\u0432\u0443\u0448\u043a\u0430 \u0443\u043b\u044b\u0431\u043d\u0443\u043b\u0430\u0441\u044c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u044b \u0435\u0451 \u043f\u0440\u043e\u0432\u043e\u0434\u0438\u043b(\u0430)|\u4e00\u4e2a\u5973\u5b69\u7b11\u4e86,\u56e0\u4e3a\u4f60\u966a\u5979\u8d70\u4e86\u4e00\u7a0b|\u2019n Meisie het geglimlag omdat jy haar vergesel het|\u0627\u0628\u062a\u0633\u0645\u062a \u0641\u062a\u0627\u0629 \u0644\u0623\u0646\u0643 \u0631\u0627\u0641\u0642\u062a\u0647\u0627|Una chica sonri\u00f3 porque la acompa\u00f1aste|&#10;Bienvenida de vuelta: el pueblo te ha echado de menos.|Ongi etorri berriro: herriak faltan bota zaitu.|Benvinguda de nou: el poble t'ha enyorat.|Benvida de volta: o pobo botouche de menos.|Welcome back: the village missed you.|Bon retour : le village t'a manqu\u00e9.|Willkommen zur\u00fcck: das Dorf hat dich vermisst.|Bentornata: il paese ti ha aspettata.|\u0421 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435\u043c: \u0434\u0435\u0440\u0435\u0432\u043d\u044f \u0441\u043a\u0443\u0447\u0430\u043b\u0430 \u043f\u043e \u0442\u0435\u0431\u0435.|\u6b22\u8fce\u56de\u6765:\u6751\u5e84\u5f88\u60f3\u5ff5\u4f60\u3002|Welkom terug: die dorp het jou gemis.|\u0623\u0647\u0644\u064b\u0627 \u0628\u0639\u0648\u062f\u062a\u0643: \u0627\u0634\u062a\u0627\u0642\u062a \u0625\u0644\u064a\u0643 \u0627\u0644\u0642\u0631\u064a\u0629.|Bienvenida de vuelta: el pueblo te ha echado de menos.|&#10;Hoy:|Gaur:|Avui:|Hoxe:|Today:|Aujourd'hui :|Heute:|Oggi:|\u0421\u0435\u0433\u043e\u0434\u043d\u044f:|\u4eca\u5929:|Vandag:|\u0627\u0644\u064a\u0648\u0645:|Hoy:|&#10;Sonido del campo|Landaren soinua|So del camp|Son do campo|Sound of the fields|Sons des champs|Klang der Felder|Suono dei campi|\u0417\u0432\u0443\u043a\u0438 \u043f\u043e\u043b\u0435\u0439|\u7530\u91ce\u4e4b\u58f0|Klank van die land|\u0635\u0648\u062a \u0627\u0644\u062d\u0642\u0648\u0644|Sonido del campo|&#10;Sonido del hospital|Ospitaleko soinua|So de l'hospital|Son do hospital|Sound of the hospital|Sons de l'h\u00f4pital|Klang des Krankenhauses|Suono dell'ospedale|\u0417\u0432\u0443\u043a\u0438 \u0431\u043e\u043b\u044c\u043d\u0438\u0446\u044b|\u533b\u9662\u4e4b\u58f0|Klank van die hospitaal|\u0635\u0648\u062a \u0627\u0644\u0645\u0633\u062a\u0634\u0641\u0649|Sonido del hospital|&#10;Ambiente suave|Giro lasaia|Ambient suau|Ambiente suave|Soft ambience|Ambiance douce|Sanfte Stimmung|Atmosfera soffusa|\u041c\u044f\u0433\u043a\u0430\u044f \u0430\u0442\u043c\u043e\u0441\u0444\u0435\u0440\u0430|\u8f7b\u67d4\u6c1b\u56f4|Sagte atmosfeer|\u0623\u062c\u0648\u0627\u0621 \u0647\u0627\u062f\u0626\u0629|Ambiente suave|&#10;Libro blanco|Liburu zuria|Llibre blanc|Libro branco|White paper|Livre blanc|Wei\u00dfbuch|Libro bianco|\u0411\u0435\u043b\u0430\u044f \u043a\u043d\u0438\u0433\u0430|\u767d\u76ae\u4e66|Witskrif|\u0627\u0644\u0643\u062a\u0627\u0628 \u0627\u0644\u0623\u0628\u064a\u0636|Libro blanco|&#10;Copiar texto|Kopiatu testua|Copia el text|Copiar texto|Copy text|Copier le texte|Text kopieren|Copia il testo|\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0435\u043a\u0441\u0442|\u590d\u5236\u6587\u672c|Kopieer teks|\u0646\u0633\u062e \u0627\u0644\u0646\u0635|Copiar texto|&#10;Texto copiado \u2714|Testua kopiatu da \u2714|Text copiat \u2714|Texto copiado \u2714|Text copied \u2714|Texte copi\u00e9 \u2714|Text kopiert \u2714|Testo copiato \u2714|\u0422\u0435\u043a\u0441\u0442 \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d \u2714|\u6587\u672c\u5df2\u590d\u5236 \u2714|Teks gekopieer \u2714|\u062a\u0645 \u0646\u0633\u062e \u0627\u0644\u0646\u0635 \u2714|Texto copiado \u2714|&#10;Descargado \u2714 (si no ves nada, copia el texto)|Deskargatu da \u2714 (ezer ikusten ez baduzu, kopiatu testua)|Descarregat \u2714 (si no veus res, copia el text)|Descargado \u2714 (se non ves nada, copia o texto)|Downloaded \u2714 (if you see nothing, copy the text)|T\u00e9l\u00e9charg\u00e9 \u2714 (si tu ne vois rien, copie le texte)|Heruntergeladen \u2714 (falls nichts passiert, kopiere den Text)|Scaricato \u2714 (se non vedi nulla, copia il testo)|\u0421\u043a\u0430\u0447\u0430\u043d\u043e \u2714 (\u0435\u0441\u043b\u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0432\u0438\u0434\u043d\u043e, \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0439 \u0442\u0435\u043a\u0441\u0442)|\u5df2\u4e0b\u8f7d \u2714(\u5982\u679c\u6ca1\u6709\u770b\u5230,\u8bf7\u590d\u5236\u6587\u672c)|Afgelaai \u2714 (as jy niks sien nie, kopieer die teks)|\u062a\u0645 \u0627\u0644\u062a\u0646\u0632\u064a\u0644 \u2714 (\u0625\u0646 \u0644\u0645 \u062a\u0631\u064e \u0634\u064a\u0626\u064b\u0627 \u0641\u0627\u0646\u0633\u062e \u0627\u0644\u0646\u0635)|Descargado \u2714 (si no ves nada, copia el texto)|&#10;Selecci\u00f3nalo y c\u00f3pialo a mano|Hautatu eta kopiatu eskuz|Selecciona'l i copia'l a m\u00e0|Selecci\u00f3nao e c\u00f3piao a man|Select it and copy it by hand|S\u00e9lectionne-le et copie-le \u00e0 la main|Markiere und kopiere ihn von Hand|Selezionalo e copialo a mano|\u0412\u044b\u0434\u0435\u043b\u0438 \u0438 \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0439 \u0432\u0440\u0443\u0447\u043d\u0443\u044e|\u8bf7\u624b\u52a8\u9009\u4e2d\u5e76\u590d\u5236|Kies dit en kopieer dit self|\u062d\u062f\u0651\u062f\u0647 \u0648\u0627\u0646\u0633\u062e\u0647 \u064a\u062f\u0648\u064a\u064b\u0627|Selecci\u00f3nalo y c\u00f3pialo a mano|&#10;No se pudo descargar aqu\u00ed: copia el texto.|Hemen ezin izan da deskargatu: kopiatu testua.|No s'ha pogut descarregar aqu\u00ed: copia el text.|Non se puido descargar aqu\u00ed: copia o texto.|Could not download here: copy the text.|T\u00e9l\u00e9chargement impossible ici : copie le texte.|Hier ging der Download nicht: kopiere den Text.|Impossibile scaricare qui: copia il testo.|\u0417\u0434\u0435\u0441\u044c \u0441\u043a\u0430\u0447\u0430\u0442\u044c \u043d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c: \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0439 \u0442\u0435\u043a\u0441\u0442.|\u6b64\u5904\u65e0\u6cd5\u4e0b\u8f7d:\u8bf7\u590d\u5236\u6587\u672c\u3002|Kon nie hier aflaai nie: kopieer die teks.|\u062a\u0639\u0630\u0651\u0631 \u0627\u0644\u062a\u0646\u0632\u064a\u0644 \u0647\u0646\u0627: \u0627\u0646\u0633\u062e \u0627\u0644\u0646\u0635.|No se pudo descargar aqu\u00ed: copia el texto.|&#10;Postal guardada \u2714|Postala gorde da \u2714|Postal desada \u2714|Postal gardada \u2714|Postcard saved \u2714|Carte postale enregistr\u00e9e \u2714|Postkarte gespeichert \u2714|Cartolina salvata \u2714|\u041e\u0442\u043a\u0440\u044b\u0442\u043a\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0430 \u2714|\u660e\u4fe1\u7247\u5df2\u4fdd\u5b58 \u2714|Poskaart gestoor \u2714|\u062a\u0645 \u062d\u0641\u0638 \u0627\u0644\u0628\u0637\u0627\u0642\u0629 \u2714|Postal guardada \u2714|&#10;Descargado \u2714|Deskargatu da \u2714|Descarregat \u2714|Descargado \u2714|Downloaded \u2714|T\u00e9l\u00e9charg\u00e9 \u2714|Heruntergeladen \u2714|Scaricato \u2714|\u0421\u043a\u0430\u0447\u0430\u043d\u043e \u2714|\u5df2\u4e0b\u8f7d \u2714|Afgelaai \u2714|\u062a\u0645 \u0627\u0644\u062a\u0646\u0632\u064a\u0644 \u2714|Descargado \u2714|&#10;T\u00fa decides|Zuk erabakitzen duzu|Tu decideixes|Ti decides|You decide|C'est toi qui d\u00e9cides|Du entscheidest|Decidi tu|\u0420\u0435\u0448\u0430\u0435\u0448\u044c \u0442\u044b|\u7531\u4f60\u51b3\u5b9a|Jy besluit|\u0627\u0644\u0642\u0631\u0627\u0631 \u0644\u0643|T\u00fa decides|&#10;Arrastra a una chica a una casa para que cocine, barra o se ba\u00f1e, al gimnasio para que entrene, a la playa para que surfee o a un banco para que descanse. En la huerta eliges qu\u00e9 sembrar y en el mercado qu\u00e9 comprar. Las genoides trabajan solas, d\u00eda y noche.|Arrastatu neska bat etxe batera sukaldatu, erratzatu edo bainatu dadin, gimnasiora entrenatu dezan, hondartzara surfeatu dezan edo banku batera atseden hartu dezan. Baratzean zer ereingo den aukeratzen duzu eta merkatuan zer erosi. Genoideek bakarrik lan egiten dute, gau eta egun.|Arrossega una xica a una casa perqu\u00e8 cuini, escombri o es banyi, al gimn\u00e0s perqu\u00e8 entreni, a la platja perqu\u00e8 surfegi o a un banc perqu\u00e8 descansi. A l'hort tries qu\u00e8 sembrar i al mercat qu\u00e8 comprar. Les genoides treballen soles, de dia i de nit.|Arrastra unha rapaza a unha casa para que coci\u00f1e, varra ou se ba\u00f1e, ao ximnasio para que adestre, \u00e1 praia para que surfee ou a un banco para que descanse. Na horta escolles que sementar e no mercado que mercar. As xenoides traballan soas, de d\u00eda e de noite.|Drag a girl to a house to cook, sweep or take a bath, to the gym to train, to the beach to surf or to a bench to rest. In the garden you choose what to sow and in the market what to buy. The genoids work on their own, day and night.|Fais glisser une fille vers une maison pour qu'elle cuisine, balaie ou prenne un bain, vers la salle de sport pour qu'elle s'entra\u00eene, vers la plage pour qu'elle surfe ou vers un banc pour qu'elle se repose. Au potager tu choisis quoi semer et au march\u00e9 quoi acheter. Les g\u00e9no\u00efdes travaillent seules, jour et nuit.|Zieh ein M\u00e4del in ein Haus, damit sie kocht, fegt oder badet, ins Fitnessstudio zum Training, an den Strand zum Surfen oder auf eine Bank zum Ausruhen. Im Garten w\u00e4hlst du, was ges\u00e4t wird, und auf dem Markt, was gekauft wird. Die Genoiden arbeiten allein, Tag und Nacht.|Trascina una ragazza in una casa perch\u00e9 cucini, scopi o faccia il bagno, in palestra perch\u00e9 si alleni, in spiaggia perch\u00e9 faccia surf o su una panchina perch\u00e9 riposi. Nell'orto scegli cosa seminare e al mercato cosa comprare. Le genoidi lavorano da sole, giorno e notte.|\u041f\u0435\u0440\u0435\u0442\u0430\u0449\u0438 \u0434\u0435\u0432\u0443\u0448\u043a\u0443 \u0432 \u0434\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u0433\u043e\u0442\u043e\u0432\u0438\u043b\u0430, \u043f\u043e\u0434\u043c\u0435\u0442\u0430\u043b\u0430 \u0438\u043b\u0438 \u043f\u0440\u0438\u043d\u044f\u043b\u0430 \u0432\u0430\u043d\u043d\u0443, \u0432 \u0441\u043f\u043e\u0440\u0442\u0437\u0430\u043b \u043d\u0430 \u0442\u0440\u0435\u043d\u0438\u0440\u043e\u0432\u043a\u0443, \u043d\u0430 \u043f\u043b\u044f\u0436 \u0441\u0451\u0440\u0444\u0438\u0442\u044c \u0438\u043b\u0438 \u043d\u0430 \u0441\u043a\u0430\u043c\u0435\u0439\u043a\u0443 \u043e\u0442\u0434\u043e\u0445\u043d\u0443\u0442\u044c. \u0412 \u043e\u0433\u043e\u0440\u043e\u0434\u0435 \u0442\u044b \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0448\u044c, \u0447\u0442\u043e \u0441\u0435\u044f\u0442\u044c, \u0430 \u043d\u0430 \u0440\u044b\u043d\u043a\u0435 \u2014 \u0447\u0442\u043e \u043a\u0443\u043f\u0438\u0442\u044c. \u0413\u0435\u043d\u043e\u0438\u0434\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0441\u0430\u043c\u0438, \u0434\u043d\u0451\u043c \u0438 \u043d\u043e\u0447\u044c\u044e.|\u628a\u5973\u5b69\u62d6\u5230\u623f\u5b50\u91cc,\u5979\u4f1a\u505a\u996d\u3001\u626b\u5730\u6216\u6d17\u6fa1;\u62d6\u5230\u5065\u8eab\u623f\u8bad\u7ec3;\u62d6\u5230\u6d77\u6ee9\u51b2\u6d6a;\u6216\u62d6\u5230\u957f\u6905\u4e0a\u4f11\u606f\u3002\u4f60\u51b3\u5b9a\u5728\u83dc\u56ed\u91cc\u79cd\u4ec0\u4e48,\u5728\u5e02\u573a\u4e0a\u4e70\u4ec0\u4e48\u3002\u57fa\u56e0\u4f53\u81ea\u5df1\u5de5\u4f5c,\u65e5\u591c\u4e0d\u505c\u3002|Sleep \u2019n meisie na \u2019n huis om te kook, te vee of te bad, na die gimnasium om te oefen, na die strand om te branderplank, of na \u2019n bank om te rus. In die tuin kies jy wat om te saai en by die mark wat om te koop. Die geno\u00efede werk self, dag en nag.|\u0627\u0633\u062d\u0628 \u0641\u062a\u0627\u0629 \u0625\u0644\u0649 \u0628\u064a\u062a \u0644\u062a\u0637\u0628\u062e \u0623\u0648 \u062a\u0643\u0646\u0633 \u0623\u0648 \u062a\u0633\u062a\u062d\u0645\u060c \u0623\u0648 \u0625\u0644\u0649 \u0627\u0644\u0646\u0627\u062f\u064a \u0644\u062a\u062a\u062f\u0631\u0651\u0628\u060c \u0623\u0648 \u0625\u0644\u0649 \u0627\u0644\u0634\u0627\u0637\u0626 \u0644\u062a\u062a\u0632\u0644\u0651\u062c \u0639\u0644\u0649 \u0627\u0644\u0623\u0645\u0648\u0627\u062c\u060c \u0623\u0648 \u0625\u0644\u0649 \u0645\u0642\u0639\u062f \u0644\u062a\u0631\u062a\u0627\u062d. \u0641\u064a \u0627\u0644\u0628\u0633\u062a\u0627\u0646 \u062a\u062e\u062a\u0627\u0631 \u0645\u0627 \u062a\u0632\u0631\u0639\u0647\u060c \u0648\u0641\u064a \u0627\u0644\u0633\u0648\u0642 \u0645\u0627 \u062a\u0634\u062a\u0631\u064a\u0647. \u0648\u0627\u0644\u062c\u064a\u0646\u0648\u064a\u062f\u0627\u062a \u062a\u0639\u0645\u0644 \u0648\u062d\u062f\u0647\u0627 \u0644\u064a\u0644\u064b\u0627 \u0648\u0646\u0647\u0627\u0631\u064b\u0627.|Arrastra a una chica a una casa para que cocine, barra o se ba\u00f1e, al gimnasio para que entrene, a la playa para que surfee o a un banco para que descanse. En la huerta eliges qu\u00e9 sembrar y en el mercado qu\u00e9 comprar. Las genoides trabajan solas, d\u00eda y noche.|&#10;Arrastra a una chica al barco, a la tabla de surf o a una roca|Eraman neska bat untzira, surf-taulara edo harri batera|Arrossega una noia al vaixell, a la taula de surf o a una roca|Arrastra a unha rapaza ao barco, \u00e1 t\u00e1boa de surf ou a unha rocha|Drag a girl to the boat, the surfboard or a rock|Fais glisser une fille vers le bateau, la planche de surf ou un rocher|Zieh ein M\u00e4dchen zum Boot, zum Surfbrett oder zu einem Felsen|Trascina una ragazza alla barca, alla tavola da surf o a uno scoglio|\u041f\u0435\u0440\u0435\u0442\u0430\u0449\u0438 \u0434\u0435\u0432\u043e\u0447\u043a\u0443 \u043a \u043b\u043e\u0434\u043a\u0435, \u0434\u043e\u0441\u043a\u0435 \u0434\u043b\u044f \u0441\u0451\u0440\u0444\u0438\u043d\u0433\u0430 \u0438\u043b\u0438 \u043a\u0430\u043c\u043d\u044e|\u628a\u5973\u5b69\u62d6\u5230\u5c0f\u8239\u3001\u51b2\u6d6a\u677f\u6216\u5ca9\u77f3\u4e0a|Sleep 'n meisie na die boot, die branderplank of 'n rots|\u0627\u0633\u062d\u0628 \u0641\u062a\u0627\u0629 \u0625\u0644\u0649 \u0627\u0644\u0642\u0627\u0631\u0628 \u0623\u0648 \u0644\u0648\u062d \u0627\u0644\u062a\u0632\u0644\u062c \u0623\u0648 \u0635\u062e\u0631\u0629|Arrastra a una chica al barco, a la tabla de surf o a una roca|&#10;Arrastra a una chica a un patinete, a un banco, a una casa o al tranv\u00eda; y toca el gimnasio|Eraman neska bat patinetera, banku batera, etxe batera edo tranbiara; eta ukitu gimnasioa|Arrossega una noia a un patinet, a un banc, a una casa o al tramvia; i toca el gimn\u00e0s|Arrastra a unha rapaza a un patinete, a un banco, a unha casa ou ao tranv\u00eda; e toca o ximnasio|Drag a girl to a scooter, a bench, a house or the tram; and tap the gym|Fais glisser une fille vers une trottinette, un banc, une maison ou le tram ; et touche la salle de sport|Zieh ein M\u00e4dchen zu einem Roller, einer Bank, einem Haus oder der Stra\u00dfenbahn; tippe auf das Fitnessstudio|Trascina una ragazza a un monopattino, una panchina, una casa o al tram; e tocca la palestra|\u041f\u0435\u0440\u0435\u0442\u0430\u0449\u0438 \u0434\u0435\u0432\u043e\u0447\u043a\u0443 \u043a \u0441\u0430\u043c\u043e\u043a\u0430\u0442\u0443, \u0441\u043a\u0430\u043c\u0435\u0439\u043a\u0435, \u0434\u043e\u043c\u0443 \u0438\u043b\u0438 \u0442\u0440\u0430\u043c\u0432\u0430\u044e; \u0438 \u043a\u043e\u0441\u043d\u0438\u0441\u044c \u0441\u043f\u043e\u0440\u0442\u0437\u0430\u043b\u0430|\u628a\u5973\u5b69\u62d6\u5230\u6ed1\u677f\u8f66\u3001\u957f\u51f3\u3001\u623f\u5b50\u6216\u7535\u8f66\u4e0a\uff1b\u70b9\u4e00\u4e0b\u5065\u8eab\u623f|Sleep 'n meisie na 'n step, 'n bank, 'n huis of die tram; en raak die gimnasium aan|\u0627\u0633\u062d\u0628 \u0641\u062a\u0627\u0629 \u0625\u0644\u0649 \u0633\u0643\u0648\u062a\u0631 \u0623\u0648 \u0645\u0642\u0639\u062f \u0623\u0648 \u0628\u064a\u062a \u0623\u0648 \u0627\u0644\u062a\u0631\u0627\u0645\u061b \u0648\u0627\u0636\u063a\u0637 \u0639\u0644\u0649 \u0627\u0644\u0646\u0627\u062f\u064a|Arrastra a una chica a un patinete, a un banco, a una casa o al tranv\u00eda; y toca el gimnasio|&#10;Arrastra a una chica a cocinar, a barrer o a ba\u00f1arse: t\u00fa decides qu\u00e9 hace|Eraman neska bat sukaldatzera, erratzera edo bainatzera: zuk erabakitzen duzu zer egin|Arrossega una noia a cuinar, a escombrar o a banyar-se: tu decideixes qu\u00e8 fa|Arrastra a unha rapaza a coci\u00f1ar, a varrer ou a ba\u00f1arse: ti decides que fai|Drag a girl to cook, sweep or bathe: you decide what she does|Fais glisser une fille pour cuisiner, balayer ou se baigner : c'est toi qui d\u00e9cides|Zieh ein M\u00e4dchen zum Kochen, Fegen oder Baden: du entscheidest, was sie tut|Trascina una ragazza a cucinare, spazzare o farsi il bagno: decidi tu cosa fa|\u041f\u0435\u0440\u0435\u0442\u0430\u0449\u0438 \u0434\u0435\u0432\u043e\u0447\u043a\u0443 \u0433\u043e\u0442\u043e\u0432\u0438\u0442\u044c, \u043f\u043e\u0434\u043c\u0435\u0442\u0430\u0442\u044c \u0438\u043b\u0438 \u043a\u0443\u043f\u0430\u0442\u044c\u0441\u044f: \u0440\u0435\u0448\u0430\u0435\u0448\u044c \u0442\u044b|\u628a\u5973\u5b69\u62d6\u53bb\u505a\u996d\u3001\u626b\u5730\u6216\u6d17\u6fa1\uff1a\u7531\u4f60\u51b3\u5b9a\u5979\u505a\u4ec0\u4e48|Sleep 'n meisie om te kook, te vee of te bad: jy besluit wat sy doen|\u0627\u0633\u062d\u0628 \u0641\u062a\u0627\u0629 \u0644\u062a\u0637\u0628\u062e \u0623\u0648 \u062a\u0643\u0646\u0633 \u0623\u0648 \u062a\u0633\u062a\u062d\u0645: \u0627\u0644\u0642\u0631\u0627\u0631 \u0644\u0643|Arrastra a una chica a cocinar, a barrer o a ba\u00f1arse: t\u00fa decides qu\u00e9 hace|&#10;Toca las m\u00e1quinas o arrastra a una chica para que entrene|Ukitu makinak edo eraman neska bat entrenatzera|Toca les m\u00e0quines o arrossega una noia perqu\u00e8 entreni|Toca as m\u00e1quinas ou arrastra a unha rapaza para que adestre|Tap the machines or drag a girl to work out|Touche les machines ou fais glisser une fille pour qu'elle s'entra\u00eene|Tippe auf die Ger\u00e4te oder zieh ein M\u00e4dchen zum Training|Tocca le macchine o trascina una ragazza ad allenarsi|\u041a\u043e\u0441\u043d\u0438\u0441\u044c \u0442\u0440\u0435\u043d\u0430\u0436\u0451\u0440\u043e\u0432 \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0449\u0438 \u0434\u0435\u0432\u043e\u0447\u043a\u0443 \u0442\u0440\u0435\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f|\u70b9\u4e00\u4e0b\u5668\u68b0\uff0c\u6216\u628a\u5973\u5b69\u62d6\u6765\u953b\u70bc|Raak die toestelle aan of sleep 'n meisie om te oefen|\u0627\u0636\u063a\u0637 \u0639\u0644\u0649 \u0627\u0644\u0623\u062c\u0647\u0632\u0629 \u0623\u0648 \u0627\u0633\u062d\u0628 \u0641\u062a\u0627\u0629 \u0644\u062a\u062a\u062f\u0631\u0628|Toca las m\u00e1quinas o arrastra a una chica para que entrene|&#10;Arrastra a una chica a la mesa de la biblioteca para que lea y estudie|Eraman neska bat liburutegiko mahaira irakur eta ikas dezan|Arrossega una noia a la taula de la biblioteca perqu\u00e8 llegeixi i estudi\u00ef|Arrastra a unha rapaza \u00e1 mesa da biblioteca para que lea e estude|Drag a girl to the library table to read and study|Fais glisser une fille vers la table de la biblioth\u00e8que pour lire et \u00e9tudier|Zieh ein M\u00e4dchen an den Bibliothekstisch zum Lesen und Lernen|Trascina una ragazza al tavolo della biblioteca per leggere e studiare|\u041f\u0435\u0440\u0435\u0442\u0430\u0449\u0438 \u0434\u0435\u0432\u043e\u0447\u043a\u0443 \u043a \u0441\u0442\u043e\u043b\u0443 \u0432 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0435 \u0447\u0438\u0442\u0430\u0442\u044c \u0438 \u0443\u0447\u0438\u0442\u044c\u0441\u044f|\u628a\u5973\u5b69\u62d6\u5230\u56fe\u4e66\u9986\u7684\u684c\u5b50\u65c1\u8bfb\u4e66\u5b66\u4e60|Sleep 'n meisie na die biblioteektafel om te lees en te leer|\u0627\u0633\u062d\u0628 \u0641\u062a\u0627\u0629 \u0625\u0644\u0649 \u0637\u0627\u0648\u0644\u0629 \u0627\u0644\u0645\u0643\u062a\u0628\u0629 \u0644\u062a\u0642\u0631\u0623 \u0648\u062a\u062f\u0631\u0633|Arrastra a una chica a la mesa de la biblioteca para que lea y estudie|&#10;Toca la tierra para elegir qu\u00e9 sembrar; las genoides cuidan la huerta d\u00eda y noche|Ukitu lurra zer ereinen duzun aukeratzeko; genoideek baratza zaintzen dute egunez eta gauez|Toca la terra per triar qu\u00e8 sembrar; les genoides cuiden l'hort dia i nit|Toca a terra para elixir que sementar; as xenoides coidan a horta d\u00eda e noite|Tap the soil to choose what to sow; the genoids tend the garden day and night|Touche la terre pour choisir quoi semer ; les g\u00e9no\u00efdes soignent le potager jour et nuit|Tippe auf die Erde, um zu w\u00e4hlen, was ges\u00e4t wird; die Genoiden pflegen den Garten Tag und Nacht|Tocca la terra per scegliere cosa seminare; i genoidi curano l'orto giorno e notte|\u041a\u043e\u0441\u043d\u0438\u0441\u044c \u0437\u0435\u043c\u043b\u0438, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0431\u0440\u0430\u0442\u044c, \u0447\u0442\u043e \u0441\u0435\u044f\u0442\u044c; \u0433\u0435\u043d\u043e\u0438\u0434\u044b \u0443\u0445\u0430\u0436\u0438\u0432\u0430\u044e\u0442 \u0437\u0430 \u043e\u0433\u043e\u0440\u043e\u0434\u043e\u043c \u0434\u043d\u0451\u043c \u0438 \u043d\u043e\u0447\u044c\u044e|\u70b9\u4e00\u4e0b\u571f\u5730\u9009\u62e9\u79cd\u4ec0\u4e48\uff1b\u57fa\u8bfa\u4f9d\u5fb7\u65e5\u591c\u7167\u6599\u83dc\u56ed|Raak die grond aan om te kies wat om te saai; die geno\u00efede versorg die tuin dag en nag|\u0627\u0636\u063a\u0637 \u0639\u0644\u0649 \u0627\u0644\u062a\u0631\u0628\u0629 \u0644\u062a\u062e\u062a\u0627\u0631 \u0645\u0627 \u062a\u0632\u0631\u0639\u061b \u0627\u0644\u062c\u064a\u0646\u0648\u064a\u062f\u0627\u062a \u062a\u0639\u062a\u0646\u064a \u0628\u0627\u0644\u0628\u0633\u062a\u0627\u0646 \u0644\u064a\u0644\u0627\u064b \u0648\u0646\u0647\u0627\u0631\u0627\u064b|Toca la tierra para elegir qu\u00e9 sembrar; las genoides cuidan la huerta d\u00eda y noche|&#10;Toca un puesto para hacer tu compra; las chicas vienen cuando tienen hambre|Ukitu postu bat zure erosketa egiteko; neskak gosea dutenean etortzen dira|Toca una parada per fer la teva compra; les noies v\u00e9nen quan tenen gana|Toca un posto para facer a t\u00faa compra; as rapazas ve\u00f1en cando te\u00f1en fame|Tap a stall to do your shopping; the girls come when they are hungry|Touche un \u00e9tal pour faire tes courses ; les filles viennent quand elles ont faim|Tippe auf einen Stand, um einzukaufen; die M\u00e4dchen kommen, wenn sie Hunger haben|Tocca una bancarella per fare la spesa; le ragazze vengono quando hanno fame|\u041a\u043e\u0441\u043d\u0438\u0441\u044c \u043f\u0440\u0438\u043b\u0430\u0432\u043a\u0430, \u0447\u0442\u043e\u0431\u044b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e\u043a\u0443\u043f\u043a\u0438; \u0434\u0435\u0432\u043e\u0447\u043a\u0438 \u043f\u0440\u0438\u0445\u043e\u0434\u044f\u0442, \u043a\u043e\u0433\u0434\u0430 \u0433\u043e\u043b\u043e\u0434\u043d\u044b|\u70b9\u4e00\u4e0b\u644a\u4f4d\u8d2d\u7269\uff1b\u5973\u5b69\u4eec\u997f\u4e86\u5c31\u4f1a\u6765|Raak 'n stalletjie aan om inkopies te doen; die meisies kom as hulle honger is|\u0627\u0636\u063a\u0637 \u0639\u0644\u0649 \u0643\u0634\u0643 \u0644\u062a\u062a\u0633\u0648\u0642\u061b \u0627\u0644\u0641\u062a\u064a\u0627\u062a \u064a\u0623\u062a\u064a\u0646 \u0639\u0646\u062f\u0645\u0627 \u064a\u062c\u0639\u0646|Toca un puesto para hacer tu compra; las chicas vienen cuando tienen hambre|&#10;Aqu\u00ed trabajan las genoides d\u00eda y noche; toca las m\u00e1quinas para ver qu\u00e9 fabrican|Hemen genoideek lan egiten dute egunez eta gauez; ukitu makinak zer egiten duten ikusteko|Aqu\u00ed treballen les genoides dia i nit; toca les m\u00e0quines per veure qu\u00e8 fabriquen|Aqu\u00ed traballan as xenoides d\u00eda e noite; toca as m\u00e1quinas para ver que fabrican|The genoids work here day and night; tap the machines to see what they make|Ici les g\u00e9no\u00efdes travaillent jour et nuit ; touche les machines pour voir ce qu'elles fabriquent|Hier arbeiten die Genoiden Tag und Nacht; tippe auf die Maschinen, um zu sehen, was sie herstellen|Qui i genoidi lavorano giorno e notte; tocca le macchine per vedere cosa producono|\u0417\u0434\u0435\u0441\u044c \u0433\u0435\u043d\u043e\u0438\u0434\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0434\u043d\u0451\u043c \u0438 \u043d\u043e\u0447\u044c\u044e; \u043a\u043e\u0441\u043d\u0438\u0441\u044c \u043c\u0430\u0448\u0438\u043d, \u0447\u0442\u043e\u0431\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e \u043e\u043d\u0438 \u0434\u0435\u043b\u0430\u044e\u0442|\u57fa\u8bfa\u4f9d\u5fb7\u5728\u8fd9\u91cc\u65e5\u591c\u5de5\u4f5c\uff1b\u70b9\u4e00\u4e0b\u673a\u5668\u770b\u770b\u5b83\u4eec\u9020\u4ec0\u4e48|Hier werk die geno\u00efede dag en nag; raak die masjiene aan om te sien wat hulle maak|\u0647\u0646\u0627 \u062a\u0639\u0645\u0644 \u0627\u0644\u062c\u064a\u0646\u0648\u064a\u062f\u0627\u062a \u0644\u064a\u0644\u0627\u064b \u0648\u0646\u0647\u0627\u0631\u0627\u064b\u061b \u0627\u0636\u063a\u0637 \u0639\u0644\u0649 \u0627\u0644\u0622\u0644\u0627\u062a \u0644\u062a\u0631\u0649 \u0645\u0627 \u062a\u0635\u0646\u0639\u0647|Aqu\u00ed trabajan las genoides d\u00eda y noche; toca las m\u00e1quinas para ver qu\u00e9 fabrican|&#10;Arrastra a una chica a la grada, al teatro, al ajedrez o al sastre|Eraman neska bat harmailara, antzokira, xakera edo jostunarengana|Arrossega una noia a la graderia, al teatre, als escacs o al sastre|Arrastra a unha rapaza \u00e1 bancada, ao teatro, ao xadrez ou ao xastre|Drag a girl to the stands, the theatre, chess or the tailor|Fais glisser une fille vers les gradins, le th\u00e9\u00e2tre, les \u00e9checs ou le tailleur|Zieh ein M\u00e4dchen zur Trib\u00fcne, zum Theater, zum Schach oder zum Schneider|Trascina una ragazza alla gradinata, al teatro, agli scacchi o al sarto|\u041f\u0435\u0440\u0435\u0442\u0430\u0449\u0438 \u0434\u0435\u0432\u043e\u0447\u043a\u0443 \u043d\u0430 \u0442\u0440\u0438\u0431\u0443\u043d\u0443, \u0432 \u0442\u0435\u0430\u0442\u0440, \u043a \u0448\u0430\u0445\u043c\u0430\u0442\u0430\u043c \u0438\u043b\u0438 \u043a \u043f\u043e\u0440\u0442\u043d\u043e\u043c\u0443|\u628a\u5973\u5b69\u62d6\u5230\u770b\u53f0\u3001\u5267\u9662\u3001\u56fd\u9645\u8c61\u68cb\u6216\u88c1\u7f1d\u5904|Sleep 'n meisie na die gradestoel, die teater, skaak of die snyer|\u0627\u0633\u062d\u0628 \u0641\u062a\u0627\u0629 \u0625\u0644\u0649 \u0627\u0644\u0645\u062f\u0631\u062c\u0627\u062a \u0623\u0648 \u0627\u0644\u0645\u0633\u0631\u062d \u0623\u0648 \u0627\u0644\u0634\u0637\u0631\u0646\u062c \u0623\u0648 \u0627\u0644\u062e\u064a\u0627\u0637|Arrastra a una chica a la grada, al teatro, al ajedrez o al sastre|&#10;Toca una cama o una m\u00e1quina; aqu\u00ed se cuidan con calma|Ukitu ohe bat edo makina bat; hemen patxadaz zaintzen dira|Toca un llit o una m\u00e0quina; aqu\u00ed es cuiden amb calma|Toca unha cama ou unha m\u00e1quina; aqu\u00ed c\u00f3idanse con calma|Tap a bed or a machine; here they take care of each other calmly|Touche un lit ou une machine ; ici on se soigne en douceur|Tippe auf ein Bett oder ein Ger\u00e4t; hier k\u00fcmmert man sich in Ruhe umeinander|Tocca un letto o una macchina; qui ci si prende cura con calma|\u041a\u043e\u0441\u043d\u0438\u0441\u044c \u043a\u0440\u043e\u0432\u0430\u0442\u0438 \u0438\u043b\u0438 \u0430\u043f\u043f\u0430\u0440\u0430\u0442\u0430; \u0437\u0434\u0435\u0441\u044c \u0437\u0430\u0431\u043e\u0442\u044f\u0442\u0441\u044f \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e|\u70b9\u4e00\u4e0b\u75c5\u5e8a\u6216\u673a\u5668\uff1b\u8fd9\u91cc\u4e00\u5207\u90fd\u4ece\u5bb9\u7167\u6599|Raak 'n bed of masjien aan; hier word rustig na mekaar omgesien|\u0627\u0636\u063a\u0637 \u0639\u0644\u0649 \u0633\u0631\u064a\u0631 \u0623\u0648 \u062c\u0647\u0627\u0632\u061b \u0647\u0646\u0627 \u064a\u0639\u062a\u0646\u0648\u0646 \u0628\u0628\u0639\u0636\u0647\u0645 \u0628\u0647\u062f\u0648\u0621|Toca una cama o una m\u00e1quina; aqu\u00ed se cuidan con calma|&#10;Arrastra a una chica a un barco o al submarino|Eraman neska bat untzira edo itsaspekora|Arrossega una noia a un vaixell o al submar\u00ed|Arrastra a unha rapaza a un barco ou ao submarino|Drag a girl to a boat or the submarine|Fais glisser une fille vers un bateau ou le sous-marin|Zieh ein M\u00e4dchen zu einem Boot oder zum U-Boot|Trascina una ragazza a una barca o al sommergibile|\u041f\u0435\u0440\u0435\u0442\u0430\u0449\u0438 \u0434\u0435\u0432\u043e\u0447\u043a\u0443 \u043a \u043b\u043e\u0434\u043a\u0435 \u0438\u043b\u0438 \u043f\u043e\u0434\u0432\u043e\u0434\u043d\u043e\u0439 \u043b\u043e\u0434\u043a\u0435|\u628a\u5973\u5b69\u62d6\u5230\u5c0f\u8239\u6216\u6f5c\u6c34\u8247\u4e0a|Sleep 'n meisie na 'n boot of die duikboot|\u0627\u0633\u062d\u0628 \u0641\u062a\u0627\u0629 \u0625\u0644\u0649 \u0642\u0627\u0631\u0628 \u0623\u0648 \u063a\u0648\u0627\u0635\u0629|Arrastra a una chica a un barco o al submarino|&#10;Mira el fondo marino: peces, corales y medusas viven a su aire|Begiratu itsas hondoari: arrainak, koralak eta medusak beren aldetik bizi dira|Mira el fons mar\u00ed: peixos, corals i meduses viuen al seu aire|Mira o fondo mari\u00f1o: peixes, corais e medusas viven ao seu aire|Look at the sea floor: fish, corals and jellyfish live freely|Regarde le fond marin : poissons, coraux et m\u00e9duses vivent \u00e0 leur guise|Schau auf den Meeresgrund: Fische, Korallen und Quallen leben, wie sie wollen|Guarda il fondale: pesci, coralli e meduse vivono a modo loro|\u0421\u043c\u043e\u0442\u0440\u0438 \u043d\u0430 \u043c\u043e\u0440\u0441\u043a\u043e\u0435 \u0434\u043d\u043e: \u0440\u044b\u0431\u044b, \u043a\u043e\u0440\u0430\u043b\u043b\u044b \u0438 \u043c\u0435\u0434\u0443\u0437\u044b \u0436\u0438\u0432\u0443\u0442 \u0441\u0430\u043c\u0438 \u043f\u043e \u0441\u0435\u0431\u0435|\u770b\u770b\u6d77\u5e95\uff1a\u9c7c\u3001\u73ca\u745a\u548c\u6c34\u6bcd\u81ea\u7531\u81ea\u5728\u5730\u751f\u6d3b|Kyk na die seebodem: visse, korale en jellievisse leef vrylik|\u0627\u0646\u0638\u0631 \u0625\u0644\u0649 \u0642\u0627\u0639 \u0627\u0644\u0628\u062d\u0631: \u0627\u0644\u0623\u0633\u0645\u0627\u0643 \u0648\u0627\u0644\u0645\u0631\u062c\u0627\u0646 \u0648\u0642\u0646\u0627\u062f\u064a\u0644 \u0627\u0644\u0628\u062d\u0631 \u062a\u0639\u064a\u0634 \u0628\u062d\u0631\u064a\u0629|Mira el fondo marino: peces, corales y medusas viven a su aire|&#10;Han brotado flores nuevas en la huerta|Lore berriak loratu dira baratzean|Han brotat flors noves a l'hort|Brotaron flores novas na horta|New flowers have bloomed in the garden|De nouvelles fleurs ont \u00e9clos au potager|Im Garten sind neue Blumen aufgebl\u00fcht|Nel orto sono sbocciati fiori nuovi|\u0412 \u043e\u0433\u043e\u0440\u043e\u0434\u0435 \u0440\u0430\u0441\u043f\u0443\u0441\u0442\u0438\u043b\u0438\u0441\u044c \u043d\u043e\u0432\u044b\u0435 \u0446\u0432\u0435\u0442\u044b|\u83dc\u56ed\u91cc\u5f00\u51fa\u4e86\u65b0\u82b1|Nuwe blomme het in die tuin geblom|\u0623\u0632\u0647\u0631\u062a \u0623\u0632\u0647\u0627\u0631 \u062c\u062f\u064a\u062f\u0629 \u0641\u064a \u0627\u0644\u0628\u0633\u062a\u0627\u0646|Han brotado flores nuevas en la huerta|&#10;Las abejas vuelven a zumbar por el pueblo|erleak berriro zurrumurrutan ari dira herrian|Les abelles tornen a brunzir pel poble|As abellas volven zumbar polo pobo|The bees are buzzing around town again|Les abeilles bourdonnent de nouveau dans le village|Die Bienen summen wieder durchs Dorf|Le api tornano a ronzare per il paese|\u041f\u0447\u0451\u043b\u044b \u0441\u043d\u043e\u0432\u0430 \u0436\u0443\u0436\u0436\u0430\u0442 \u043d\u0430\u0434 \u0434\u0435\u0440\u0435\u0432\u043d\u0435\u0439|\u871c\u8702\u53c8\u5728\u5c0f\u9547\u4e0a\u55e1\u55e1\u98de\u821e|Die bye zoem weer deur die dorp|\u0639\u0627\u062f\u062a \u0627\u0644\u0646\u062d\u0644\u0627\u062a \u062a\u0637\u0646\u0651 \u0641\u064a \u0623\u0631\u062c\u0627\u0621 \u0627\u0644\u0628\u0644\u062f\u0629|Las abejas vuelven a zumbar por el pueblo|&#10;Hoy las chicas pasean m\u00e1s despacio, con el olor a primavera|Gaur neskak astiroago ibiltzen dira, udaberriaren usainarekin|Avui les noies passegen m\u00e9s a poc a poc, amb l'olor de primavera|Hoxe as rapazas pasean m\u00e1is amodo, co cheiro de primavera|Today the girls stroll more slowly in the scent of spring|Aujourd'hui les filles se prom\u00e8nent plus lentement, dans l'odeur du printemps|Heute schlendern die M\u00e4dchen langsamer, im Duft des Fr\u00fchlings|Oggi le ragazze passeggiano pi\u00f9 lente, nel profumo di primavera|\u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0434\u0435\u0432\u043e\u0447\u043a\u0438 \u0433\u0443\u043b\u044f\u044e\u0442 \u043c\u0435\u0434\u043b\u0435\u043d\u043d\u0435\u0435, \u0432 \u0430\u0440\u043e\u043c\u0430\u0442\u0435 \u0432\u0435\u0441\u043d\u044b|\u4eca\u5929\u5973\u5b69\u4eec\u5728\u6625\u5929\u7684\u6c14\u606f\u91cc\u8d70\u5f97\u66f4\u6162\u4e86|Vandag stap die meisies stadiger in die geur van lente|\u0627\u0644\u064a\u0648\u0645 \u062a\u062a\u0645\u0634\u0649 \u0627\u0644\u0641\u062a\u064a\u0627\u062a \u0628\u0628\u0637\u0621 \u0623\u0643\u062b\u0631 \u0641\u064a \u0639\u0628\u064a\u0631 \u0627\u0644\u0631\u0628\u064a\u0639|Hoy las chicas pasean m\u00e1s despacio, con el olor a primavera|&#10;La playa huele a sal y a verano|Hondartzak gatza eta uda usaintzen ditu|La platja fa olor de sal i d'estiu|A praia cheira a sal e a ver\u00e1n|The beach smells of salt and summer|La plage sent le sel et l'\u00e9t\u00e9|Der Strand riecht nach Salz und Sommer|La spiaggia sa di sale e di estate|\u041f\u043b\u044f\u0436 \u043f\u0430\u0445\u043d\u0435\u0442 \u0441\u043e\u043b\u044c\u044e \u0438 \u043b\u0435\u0442\u043e\u043c|\u6d77\u6ee9\u4e0a\u6709\u76d0\u548c\u590f\u5929\u7684\u5473\u9053|Die strand ruik na sout en somer|\u0627\u0644\u0634\u0627\u0637\u0626 \u062a\u0641\u0648\u062d \u0645\u0646\u0647 \u0631\u0627\u0626\u062d\u0629 \u0627\u0644\u0645\u0644\u062d \u0648\u0627\u0644\u0635\u064a\u0641|La playa huele a sal y a verano|&#10;Las tardes largas invitan a charlar en el banco|Arratsalde luzeek bankuan hizketan aritzera gonbidatzen dute|Les tardes llargues conviden a xerrar al banc|As tardes longas invitan a falar no banco|Long afternoons invite a chat on the bench|Les longues soir\u00e9es invitent \u00e0 bavarder sur le banc|Die langen Abende laden zum Plaudern auf der Bank ein|I lunghi pomeriggi invitano a chiacchierare sulla panchina|\u0414\u043e\u043b\u0433\u0438\u0435 \u0432\u0435\u0447\u0435\u0440\u0430 \u0437\u043e\u0432\u0443\u0442 \u043f\u043e\u0431\u043e\u043b\u0442\u0430\u0442\u044c \u043d\u0430 \u0441\u043a\u0430\u043c\u0435\u0439\u043a\u0435|\u6f2b\u957f\u7684\u5348\u540e\u8ba9\u4eba\u60f3\u5750\u5728\u957f\u51f3\u4e0a\u804a\u5929|Die lang middae nooi uit tot 'n gesels op die bank|\u0627\u0644\u0623\u0635\u0627\u0626\u0644 \u0627\u0644\u0637\u0648\u064a\u0644\u0629 \u062a\u062f\u0639\u0648 \u0625\u0644\u0649 \u0627\u0644\u062f\u0631\u062f\u0634\u0629 \u0639\u0644\u0649 \u0627\u0644\u0645\u0642\u0639\u062f|Las tardes largas invitan a charlar en el banco|&#10;El mercado huele a fruta madura|Merkatuak fruta heldua usaintzen du|El mercat fa olor de fruita madura|O mercado cheira a froita madura|The market smells of ripe fruit|Le march\u00e9 sent le fruit m\u00fbr|Der Markt duftet nach reifem Obst|Il mercato profuma di frutta matura|\u041d\u0430 \u0440\u044b\u043d\u043a\u0435 \u043f\u0430\u0445\u043d\u0435\u0442 \u0441\u043f\u0435\u043b\u044b\u043c\u0438 \u0444\u0440\u0443\u043a\u0442\u0430\u043c\u0438|\u5e02\u573a\u91cc\u6ee1\u662f\u719f\u900f\u6c34\u679c\u7684\u9999\u5473|Die mark ruik na ryp vrugte|\u0627\u0644\u0633\u0648\u0642 \u062a\u0641\u0648\u062d \u0645\u0646\u0647 \u0631\u0627\u0626\u062d\u0629 \u0627\u0644\u0641\u0627\u0643\u0647\u0629 \u0627\u0644\u0646\u0627\u0636\u062c\u0629|El mercado huele a fruta madura|&#10;Caen las hojas y el pueblo huele a tierra mojada|Hostoak erortzen dira eta herriak lur bustia usaintzen du|Cauen les fulles i el poble fa olor de terra mullada|Caen as follas e o pobo cheira a terra mollada|Leaves are falling and the town smells of wet earth|Les feuilles tombent et le village sent la terre mouill\u00e9e|Die Bl\u00e4tter fallen und das Dorf riecht nach nasser Erde|Cadono le foglie e il paese sa di terra bagnata|\u041f\u0430\u0434\u0430\u044e\u0442 \u043b\u0438\u0441\u0442\u044c\u044f, \u0438 \u0434\u0435\u0440\u0435\u0432\u043d\u044f \u043f\u0430\u0445\u043d\u0435\u0442 \u043c\u043e\u043a\u0440\u043e\u0439 \u0437\u0435\u043c\u043b\u0451\u0439|\u843d\u53f6\u7eb7\u98de\uff0c\u5c0f\u9547\u6709\u6e7f\u6ce5\u571f\u7684\u5473\u9053|Die blare val en die dorp ruik na nat aarde|\u062a\u062a\u0633\u0627\u0642\u0637 \u0627\u0644\u0623\u0648\u0631\u0627\u0642 \u0648\u0627\u0644\u0628\u0644\u062f\u0629 \u062a\u0641\u0648\u062d \u0628\u0631\u0627\u0626\u062d\u0629 \u0627\u0644\u062a\u0631\u0627\u0628 \u0627\u0644\u0645\u0628\u0644\u0644|Caen las hojas y el pueblo huele a tierra mojada|&#10;Las vecinas hablan de recoger la \u00faltima cosecha|Bizilagunak azken uzta biltzeaz hitz egiten ari dira|Les ve\u00efnes parlen de recollir l'\u00faltima collita|As veci\u00f1as falan de recoller a \u00faltima colleita|The neighbours talk about gathering the last harvest|Les voisines parlent de r\u00e9colter les derni\u00e8res r\u00e9coltes|Die Nachbarinnen reden von der letzten Ernte|Le vicine parlano di raccogliere l'ultimo raccolto|\u0421\u043e\u0441\u0435\u0434\u043a\u0438 \u0433\u043e\u0432\u043e\u0440\u044f\u0442 \u043e \u0441\u0431\u043e\u0440\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0443\u0440\u043e\u0436\u0430\u044f|\u90bb\u5c45\u4eec\u5728\u8c08\u8bba\u6536\u5b8c\u6700\u540e\u4e00\u832c\u5e84\u7a3c|Die bure praat oor die laaste oes insamel|\u0627\u0644\u062c\u0627\u0631\u0627\u062a \u064a\u062a\u062d\u062f\u062b\u0646 \u0639\u0646 \u062c\u0645\u0639 \u0622\u062e\u0631 \u0645\u062d\u0635\u0648\u0644|Las vecinas hablan de recoger la \u00faltima cosecha|&#10;Anochece antes y las luces del pueblo se ven m\u00e1s bonitas|Lehenago ilunduko du eta herriko argiak politagoak dira|Es fa de nit abans i els llums del poble es veuen m\u00e9s bonics|Anoitece antes e as luces do pobo ven m\u00e1is bonitas|Dusk comes earlier and the town lights look prettier|La nuit tombe plus t\u00f4t et les lumi\u00e8res du village sont plus belles|Es wird fr\u00fcher dunkel und die Lichter des Dorfes wirken sch\u00f6ner|Fa buio prima e le luci del paese sembrano pi\u00f9 belle|\u0422\u0435\u043c\u043d\u0435\u0435\u0442 \u0440\u0430\u043d\u044c\u0448\u0435, \u0438 \u043e\u0433\u043d\u0438 \u0434\u0435\u0440\u0435\u0432\u043d\u0438 \u043a\u0430\u0436\u0443\u0442\u0441\u044f \u043a\u0440\u0430\u0441\u0438\u0432\u0435\u0435|\u5929\u9ed1\u5f97\u66f4\u65e9\uff0c\u5c0f\u9547\u7684\u706f\u5149\u66f4\u7f8e\u4e86|Dit word vroe\u00ebr donker en die dorp se ligte lyk mooier|\u064a\u062d\u0644\u0651 \u0627\u0644\u0644\u064a\u0644 \u0645\u0628\u0643\u0631\u0627\u064b \u0648\u062a\u0628\u062f\u0648 \u0623\u0636\u0648\u0627\u0621 \u0627\u0644\u0628\u0644\u062f\u0629 \u0623\u062c\u0645\u0644|Anochece antes y las luces del pueblo se ven m\u00e1s bonitas|&#10;Hace fr\u00edo fuera, pero en las casas huele a sopa caliente|Kanpoan hotz egiten du, baina etxeetan zopa beroa usaintzen da|Fa fred fora, per\u00f2 a les cases fa olor de sopa calenta|Fai fr\u00edo f\u00f3ra, pero nas casas cheira a sopa quente|It is cold outside, but the houses smell of hot soup|Il fait froid dehors, mais les maisons sentent la soupe chaude|Drau\u00dfen ist es kalt, aber in den H\u00e4usern duftet es nach hei\u00dfer Suppe|Fuori fa freddo, ma nelle case profuma di zuppa calda|\u041d\u0430 \u0443\u043b\u0438\u0446\u0435 \u0445\u043e\u043b\u043e\u0434\u043d\u043e, \u0430 \u0432 \u0434\u043e\u043c\u0430\u0445 \u043f\u0430\u0445\u043d\u0435\u0442 \u0433\u043e\u0440\u044f\u0447\u0438\u043c \u0441\u0443\u043f\u043e\u043c|\u5916\u9762\u5f88\u51b7\uff0c\u53ef\u5c4b\u91cc\u98d8\u7740\u70ed\u6c64\u7684\u9999\u5473|Buite is dit koud, maar die huise ruik na warm sop|\u0627\u0644\u062c\u0648 \u0628\u0627\u0631\u062f \u0641\u064a \u0627\u0644\u062e\u0627\u0631\u062c\u060c \u0644\u0643\u0646 \u0627\u0644\u0628\u064a\u0648\u062a \u062a\u0641\u0648\u062d \u0628\u0631\u0627\u0626\u062d\u0629 \u0627\u0644\u062d\u0633\u0627\u0621 \u0627\u0644\u0633\u0627\u062e\u0646|Hace fr\u00edo fuera, pero en las casas huele a sopa caliente|&#10;Las chicas se abrigan y se saludan con las manos en los bolsillos|Neskak jantzi beroa janzten dute eta poltsikoetan eskuak dituztela agurtzen dira|Les noies s'abriguen i se saluden amb les mans a les butxaques|As rapazas abr\u00edgase e sa\u00fadanse coas mans nos petos|The girls wrap up and greet each other with hands in their pockets|Les filles s'emmitouflent et se saluent les mains dans les poches|Die M\u00e4dchen ziehen sich warm an und gr\u00fc\u00dfen sich mit den H\u00e4nden in den Taschen|Le ragazze si coprono e si salutano con le mani in tasca|\u0414\u0435\u0432\u043e\u0447\u043a\u0438 \u043a\u0443\u0442\u0430\u044e\u0442\u0441\u044f \u0438 \u0437\u0434\u043e\u0440\u043e\u0432\u0430\u044e\u0442\u0441\u044f, \u0434\u0435\u0440\u0436\u0430 \u0440\u0443\u043a\u0438 \u0432 \u043a\u0430\u0440\u043c\u0430\u043d\u0430\u0445|\u5973\u5b69\u4eec\u88f9\u5f97\u4e25\u4e25\u5b9e\u5b9e\uff0c\u63d2\u7740\u53e3\u888b\u4e92\u76f8\u95ee\u597d|Die meisies trek warm aan en groet met hande in die sakke|\u062a\u062a\u062f\u062b\u0631 \u0627\u0644\u0641\u062a\u064a\u0627\u062a \u0648\u062a\u062d\u064a\u0651\u064a \u0628\u0639\u0636\u0647\u0646 \u0648\u064a\u062f\u0627\u0647\u0646 \u0641\u064a \u0627\u0644\u062c\u064a\u0648\u0628|Las chicas se abrigan y se saludan con las manos en los bolsillos|&#10;Las noches largas dejan ver m\u00e1s estrellas|Gau luzeek izar gehiago ikusten uzten dute|Les nits llargues deixen veure m\u00e9s estrelles|As noites longas deixan ver m\u00e1is estrelas|Long nights let you see more stars|Les longues nuits laissent voir plus d'\u00e9toiles|Die langen N\u00e4chte zeigen mehr Sterne|Le lunghe notti lasciano vedere pi\u00f9 stelle|\u0414\u043e\u043b\u0433\u0438\u0435 \u043d\u043e\u0447\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u0437\u0432\u0451\u0437\u0434|\u6f2b\u957f\u7684\u591c\u665a\u80fd\u770b\u5230\u66f4\u591a\u661f\u661f|Die lang nagte laat jou meer sterre sien|\u0627\u0644\u0644\u064a\u0627\u0644\u064a \u0627\u0644\u0637\u0648\u064a\u0644\u0629 \u062a\u062a\u064a\u062d \u0631\u0624\u064a\u0629 \u0646\u062c\u0648\u0645 \u0623\u0643\u062b\u0631|Las noches largas dejan ver m\u00e1s estrellas|&#10;\ud83d\udc8c Lo que cuentan las vecinas|\ud83d\udc8c Auzokoek kontatzen dutena|\ud83d\udc8c El que expliquen les ve\u00efnes|\ud83d\udc8c O que contan as veci\u00f1as|\ud83d\udc8c What the neighbours say|\ud83d\udc8c Ce que racontent les voisines|\ud83d\udc8c Was die Nachbarinnen erz\u00e4hlen|\ud83d\udc8c Quello che raccontano le vicine|\ud83d\udc8c \u0427\u0442\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u0441\u043e\u0441\u0435\u0434\u043a\u0438|\ud83d\udc8c \u90bb\u5c45\u4eec\u8bf4\u7684\u8bdd|\ud83d\udc8c Wat die bure vertel|\ud83d\udc8c \u0645\u0627 \u062a\u062d\u0643\u064a\u0647 \u0627\u0644\u062c\u0627\u0631\u0627\u062a|\ud83d\udc8c Lo que cuentan las vecinas|&#10;\ud83c\udf26\ufe0f El tiempo de tu ciudad|\ud83c\udf26\ufe0f Zure hiriko eguraldia|\ud83c\udf26\ufe0f El temps de la teva ciutat|\ud83c\udf26\ufe0f O tempo da t\u00faa cidade|\ud83c\udf26\ufe0f The weather in your city|\ud83c\udf26\ufe0f Le temps de ta ville|\ud83c\udf26\ufe0f Das Wetter in deiner Stadt|\ud83c\udf26\ufe0f Il meteo della tua citt\u00e0|\ud83c\udf26\ufe0f \u041f\u043e\u0433\u043e\u0434\u0430 \u0432 \u0442\u0432\u043e\u0451\u043c \u0433\u043e\u0440\u043e\u0434\u0435|\ud83c\udf26\ufe0f \u4f60\u6240\u5728\u57ce\u5e02\u7684\u5929\u6c14|\ud83c\udf26\ufe0f Die weer in jou stad|\ud83c\udf26\ufe0f \u0637\u0642\u0633 \u0645\u062f\u064a\u0646\u062a\u0643|\ud83c\udf26\ufe0f El tiempo de tu ciudad|&#10;Buscar ciudad|Hiria bilatu|Cercar ciutat|Buscar cidade|Find city|Chercher la ville|Stadt suchen|Cerca la citt\u00e0|\u041d\u0430\u0439\u0442\u0438 \u0433\u043e\u0440\u043e\u0434|\u67e5\u627e\u57ce\u5e02|Soek stad|\u0627\u0628\u062d\u062b \u0639\u0646 \u0627\u0644\u0645\u062f\u064a\u0646\u0629|Buscar ciudad|&#10;Escribe tu ciudad para ver su tiempo en el pueblo. D\u00e9jalo vac\u00edo para volver a Bilbao. Solo se guarda en este dispositivo.|Idatzi zure hiria herrian bertako eguraldia ikusteko. Utzi hutsik Bilbora itzultzeko. Gailu honetan soilik gordetzen da.|Escriu la teva ciutat per veure'n el temps al poble. Deixa-ho buit per tornar a Bilbao. Nom\u00e9s es guarda en aquest dispositiu.|Escribe a t\u00faa cidade para ver o seu tempo no pobo. D\u00e9ixao baleiro para volver a Bilbao. S\u00f3 se garda neste dispositivo.|Type your city to see its weather in the town. Leave it empty to go back to Bilbao. It is only saved on this device.|\u00c9cris ta ville pour voir son temps dans le village. Laisse vide pour revenir \u00e0 Bilbao. Cela reste seulement sur cet appareil.|Gib deine Stadt ein, um ihr Wetter im Dorf zu sehen. Leer lassen, um zu Bilbao zur\u00fcckzukehren. Wird nur auf diesem Ger\u00e4t gespeichert.|Scrivi la tua citt\u00e0 per vedere il suo meteo nel paese. Lascia vuoto per tornare a Bilbao. Resta salvato solo su questo dispositivo.|\u0412\u0432\u0435\u0434\u0438 \u0441\u0432\u043e\u0439 \u0433\u043e\u0440\u043e\u0434, \u0447\u0442\u043e\u0431\u044b \u0432\u0438\u0434\u0435\u0442\u044c \u0435\u0433\u043e \u043f\u043e\u0433\u043e\u0434\u0443 \u0432 \u0434\u0435\u0440\u0435\u0432\u043d\u0435. \u041e\u0441\u0442\u0430\u0432\u044c \u043f\u0443\u0441\u0442\u044b\u043c, \u0447\u0442\u043e\u0431\u044b \u0432\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u043a \u0411\u0438\u043b\u044c\u0431\u0430\u043e. \u0425\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u044d\u0442\u043e\u043c \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0435.|\u8f93\u5165\u4f60\u7684\u57ce\u5e02\uff0c\u5c31\u80fd\u5728\u5c0f\u9547\u770b\u5230\u90a3\u91cc\u7684\u5929\u6c14\u3002\u7559\u7a7a\u5219\u56de\u5230\u6bd5\u5c14\u5df4\u9102\u3002\u4ec5\u4fdd\u5b58\u5728\u6b64\u8bbe\u5907\u4e0a\u3002|Tik jou stad in om sy weer in die dorp te sien. Los leeg om na Bilbao terug te keer. Word net op hierdie toestel gestoor.|\u0627\u0643\u062a\u0628 \u0645\u062f\u064a\u0646\u062a\u0643 \u0644\u062a\u0631\u0649 \u0637\u0642\u0633\u0647\u0627 \u0641\u064a \u0627\u0644\u0628\u0644\u062f\u0629. \u0627\u062a\u0631\u0643\u0647\u0627 \u0641\u0627\u0631\u063a\u0629 \u0644\u0644\u0639\u0648\u062f\u0629 \u0625\u0644\u0649 \u0628\u0644\u0628\u0627\u0648. \u062a\u064f\u062d\u0641\u0638 \u0639\u0644\u0649 \u0647\u0630\u0627 \u0627\u0644\u062c\u0647\u0627\u0632 \u0641\u0642\u0637.|Escribe tu ciudad para ver su tiempo en el pueblo. D\u00e9jalo vac\u00edo para volver a Bilbao. Solo se guarda en este dispositivo.|&#10;Ciudad elegida:|Aukeratutako hiria:|Ciutat triada:|Cidade elixida:|City chosen:|Ville choisie :|Gew\u00e4hlte Stadt:|Citt\u00e0 scelta:|\u0412\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0439 \u0433\u043e\u0440\u043e\u0434:|\u5df2\u9009\u57ce\u5e02\uff1a|Gekose stad:|\u0627\u0644\u0645\u062f\u064a\u0646\u0629 \u0627\u0644\u0645\u062e\u062a\u0627\u0631\u0629:|Ciudad elegida:|&#10;No he encontrado esa ciudad|Ez dut hiri hori aurkitu|No he trobat aquesta ciutat|Non atopei esa cidade|I could not find that city|Je n'ai pas trouv\u00e9 cette ville|Diese Stadt habe ich nicht gefunden|Non ho trovato quella citt\u00e0|\u042f \u043d\u0435 \u043d\u0430\u0448\u043b\u0430 \u044d\u0442\u043e\u0442 \u0433\u043e\u0440\u043e\u0434|\u6ca1\u6709\u627e\u5230\u8fd9\u4e2a\u57ce\u5e02|Ek kon daardie stad nie vind nie|\u0644\u0645 \u0623\u062c\u062f \u0647\u0630\u0647 \u0627\u0644\u0645\u062f\u064a\u0646\u0629|No he encontrado esa ciudad|&#10;Vuelves al tiempo de Bilbao|Bilboko eguraldira itzultzen zara|Tornes al temps de Bilbao|Volves ao tempo de Bilbao|Back to Bilbao's weather|Retour au temps de Bilbao|Zur\u00fcck zum Wetter von Bilbao|Torni al meteo di Bilbao|\u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a \u043f\u043e\u0433\u043e\u0434\u0435 \u0411\u0438\u043b\u044c\u0431\u0430\u043e|\u56de\u5230\u6bd5\u5c14\u5df4\u9102\u7684\u5929\u6c14|Terug na Bilbao se weer|\u0639\u062f\u062a\u064e \u0625\u0644\u0649 \u0637\u0642\u0633 \u0628\u0644\u0628\u0627\u0648|Vuelves al tiempo de Bilbao|&#10;Sin conexi\u00f3n: int\u00e9ntalo luego|Konexiorik ez: saiatu geroago|Sense connexi\u00f3: torna-ho a provar despr\u00e9s|Sen conexi\u00f3n: t\u00e9ntao despois|No connection: try again later|Pas de connexion : r\u00e9essaie plus tard|Keine Verbindung: versuche es sp\u00e4ter|Nessuna connessione: riprova pi\u00f9 tardi|\u041d\u0435\u0442 \u0441\u0432\u044f\u0437\u0438: \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0439 \u043f\u043e\u0437\u0436\u0435|\u6ca1\u6709\u7f51\u7edc\uff1a\u8bf7\u7a0d\u540e\u518d\u8bd5|Geen verbinding nie: probeer later weer|\u0644\u0627 \u064a\u0648\u062c\u062f \u0627\u062a\u0635\u0627\u0644: \u062d\u0627\u0648\u0644 \u0644\u0627\u062d\u0642\u0627\u064b|Sin conexi\u00f3n: int\u00e9ntalo luego|&#10;Feria de Abril|Apirileko Feria|Fira d'Abril|Feira de Abril|April Fair|Feria d'Avril|Feria de Abril (Sevilla)|Feria di Aprile|\u0410\u043f\u0440\u0435\u043b\u044c\u0441\u043a\u0430\u044f \u044f\u0440\u043c\u0430\u0440\u043a\u0430|\u585e\u7ef4\u5229\u4e9a\u56db\u6708\u96c6\u4f1a|April-fees|\u0645\u0639\u0631\u0636 \u0623\u0628\u0631\u064a\u0644|Feria de Abril|&#10;Sant Jordi|San Jorge (Sant Jordi)|Sant Jordi|San Xurxo (Sant Jordi)|St George's Day (Sant Jordi)|Saint-Georges (Sant Jordi)|Sant Jordi|Sant Jordi|\u0421\u0430\u043d\u0442-\u0416\u043e\u0440\u0434\u0438|\u5723\u82e5\u5c14\u8fea\u8282|Sant Jordi|\u0633\u0627\u0646\u062a \u062c\u0648\u0631\u062f\u064a|Sant Jordi|&#10;San Esteban|Done Eztebe|Sant Esteve|San Estevo|St Stephen's Day|Saint-\u00c9tienne|Stephanstag|Santo Stefano|\u0414\u0435\u043d\u044c \u0441\u0432\u044f\u0442\u043e\u0433\u043e \u0421\u0442\u0435\u0444\u0430\u043d\u0430|\u5723\u65af\u8482\u82ac\u8282|Sint Stefanus-dag|\u0639\u064a\u062f \u0627\u0644\u0642\u062f\u064a\u0633 \u0625\u0633\u0637\u0641\u0627\u0646\u0648\u0633|San Esteban|&#10;CHICACHICA 2100 \/\/ MIIG26 STADIUM ARENA &amp; DISTRITO CULTURAL|CHICACHICA 2100 \/\/ MIIG26 STADIUM ARENA ETA KULTUR AUZOA|CHICACHICA 2100 \/\/ MIIG26 STADIUM ARENA I DISTRICTE CULTURAL|CHICACHICA 2100 \/\/ MIIG26 STADIUM ARENA E DISTRITO CULTURAL|CHICACHICA 2100 \/\/ MIIG26 STADIUM ARENA &amp; CULTURAL DISTRICT|CHICACHICA 2100 \/\/ MIIG26 STADIUM ARENA &amp; QUARTIER CULTUREL|CHICACHICA 2100 \/\/ MIIG26 STADIUM ARENA &amp; KULTURVIERTEL|CHICACHICA 2100 \/\/ MIIG26 STADIUM ARENA E DISTRETTO CULTURALE|\u0427\u0418\u041a\u0410\u0427\u0418\u041a\u0410 2100 \/\/ MIIG26 STADIUM ARENA \u0418 \u041a\u0423\u041b\u042c\u0422\u0423\u0420\u041d\u042b\u0419 \u041a\u0412\u0410\u0420\u0422\u0410\u041b|\u5947\u5361\u5947\u5361 2100 \/\/ MIIG26 \u4f53\u80b2\u573a\u7ade\u6280\u9986\u4e0e\u6587\u5316\u533a|CHICACHICA 2100 \/\/ MIIG26 STADIUM ARENA &amp; KULTUURDISTRIK|\u062a\u0634\u064a\u0643\u0627\u062a\u0634\u064a\u0643\u0627 2100 \u2014 \u0627\u0644\u062d\u064a \u0627\u0644\u062b\u0642\u0627\u0641\u064a \u0648\u0645\u0644\u0639\u0628 \u0623\u0631\u064a\u0646\u0627 MIIG26|`.split('\\n').forEach(l =&gt; { const c = l.split('|'); if (c.length &gt; 1) D[c[0]] = c; });&#10;    const rx = new RegExp(Object.keys(D).sort((a, b) =&gt; b.length - a.length).map(k =&gt; k.replace(\/[.*+?^${}()|[\\]\\\\]\/g, '\\\\$&amp;')).join('|'), 'g'), letra = c =&gt; !!c &amp;&amp; \/[A-Za-z\u00c0-\u024f]\/.test(c);&#10;    let idx = 0; const memo = new Map();&#10;    function tr(s) {&#10;        if (idx === 0 || !s) return s; const k = idx + '|' + s; let r = memo.get(k);&#10;        if (r === undefined) { r = s.replace(rx, (m, o, str) =&gt; (letra(str[o - 1]) || letra(str[o + m.length])) ? m : (D[m][idx] || m)); if (memo.size &gt; 800) memo.clear(); memo.set(k, r); }&#10;        return r;&#10;    }&#10;    function aplicarDOM() {&#10;        const w = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, { acceptNode: n =&gt; (n.parentNode &amp;&amp; \/^(SCRIPT|STYLE|CANVAS|TEXTAREA)$\/.test(n.parentNode.tagName)) ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_ACCEPT }); let n;&#10;        while ((n = w.nextNode())) { if (n.__t !== n.nodeValue) n.__es = n.nodeValue; const t = tr(n.__es); if (n.nodeValue !== t) n.nodeValue = t; n.__t = n.nodeValue; if (idx &gt; 0 &amp;&amp; t !== n.__es &amp;&amp; n.parentNode &amp;&amp; n.parentNode.setAttribute) n.parentNode.setAttribute('data-i18n', '1'); }&#10;    }&#10;    const btn = document.createElement('button'), menu = document.createElement('div'); btn.id = 'btnIdioma'; btn.type = 'button'; menu.id = 'menuIdioma'; menu.hidden = true;&#10;    LANGS.forEach((l, i) =&gt; { const b = document.createElement('button'); b.type = 'button'; b.textContent = l[1]; b.title = l[2]; b.addEventListener('click', () =&gt; { poner(i); menu.hidden = true; }); menu.appendChild(b); });&#10;    btn.addEventListener('click', () =&gt; { menu.hidden = !menu.hidden; }); document.body.appendChild(btn); document.body.appendChild(menu);&#10;    function poner(i) {&#10;        idx = i; btn.textContent = '\ud83c\udf10 ' + LANGS[i][1]; try { localStorage.setItem('chicachica:idioma', LANGS[i][0]); } catch (e) {}&#10;        document.documentElement.lang = LANGS[i][0] === 'calo' ? 'es' : LANGS[i][0]; if (typeof repintarPiezas === 'function') repintarPiezas(); ['fichas', 'menuIdioma'].forEach(id =&gt; { const e = document.getElementById(id); if (e) e.dir = LANGS[i][0] === 'ar' ? 'rtl' : 'ltr'; }); aplicarDOM();&#10;    }&#10;    let ini = 0; try { const g = localStorage.getItem('chicachica:idioma'), j = LANGS.findIndex(l =&gt; l[0] === g); if (j &gt;= 0) ini = j; else { const n = (navigator.language || 'es').slice(0, 2).toLowerCase(), j2 = LANGS.findIndex(l =&gt; l[0] === n); if (j2 &gt;= 0) ini = j2; } } catch (e) {}&#10;    poner(ini); setInterval(aplicarDOM, 2000);&#10;    const P = CanvasRenderingContext2D.prototype, _ft = P.fillText, _st = P.strokeText, _mt = P.measureText;   \/\/ todo el texto de cualquier lienzo (tambi\u00e9n las piezas pre-dibujadas) pasa por el diccionario&#10;    P.fillText = function (t, x, y, w) { return _ft.call(this, tr(String(t)), x, y, w); }; P.strokeText = function (t, x, y, w) { return _st.call(this, tr(String(t)), x, y, w); }; P.measureText = function (t) { return _mt.call(this, tr(String(t))); };&#10;    window.changeLanguage = c =&gt; { const i = LANGS.findIndex(l =&gt; l[0] === String(c).toLowerCase()); if (i &gt;= 0) poner(i); };&#10;    return { tr, aplicar: aplicarDOM, poner };&#10;})();&#10;const Dia = {   \/\/ hora real: amanecer 5:30-6:30, anochecer 17:30-18:30; la noche se nota en el 100 % de las zonas&#10;    k() { const d = new Date(), h = d.getHours() + d.getMinutes() \/ 60; return (h &gt;= 18.5 || h &lt; 5.5) ? 1 : h &gt;= 17.5 ? h - 17.5 : h &lt; 6.5 ? 6.5 - h : 0; },&#10;    aplicar() {&#10;        const k = this.k(); if (k &lt;= .01) return;&#10;        const f = enHuerta ? .55 : enMercado ? .26 : enIndustria ? .3 : enBiblioteca ? .18 : enGimnasio ? .18 : enArena ? .14 : enHospital ? .12 : casaAbierta !== null ? .14 : 0; if (!f) return;&#10;        ctx.save(); ctx.fillStyle = 'rgba(10,16,52,' + (f * k).toFixed(3) + ')'; ctx.fillRect(0, 0, canvas.width, canvas.height);&#10;        if (enHuerta &amp;&amp; k &gt; .3) { ctx.globalAlpha = k; ctx.fillStyle = '#fff'; for (let i = 0; i &lt; 30; i++) ctx.fillRect((i * 137) % 940 + 10, (i * 53) % 120 + 8, 2, 2); ctx.fillStyle = '#f5f0d0'; ctx.beginPath(); ctx.arc(860, 58, 15, 0, Math.PI * 2); ctx.fill(); }&#10;        ctx.restore();&#10;    }&#10;};&#10;const ARENA_PARADA = { x: 880, y: TRANVIA.y + 39 };&#10;const HOSPITAL_PARADA = { x: 82, y: TRANVIA.y + 39 };   \/\/ parada del Hospital cient\u00edfico (extremo izquierdo)   \/\/ centro de la marquesina (cambia x\/y para moverla)&#10;function dibujarParadaTranvia(P, t, l1, l2, glow) {&#10;    const px = P.x, py = P.y, g = .55 + .25 * Math.sin(t \/ 25), W = 72;&#10;    ctx.save(); ctx.lineWidth = 1.5; ctx.strokeStyle = '#000';&#10;    ctx.fillStyle = 'rgba(0,0,0,0.18)'; ctx.beginPath(); ctx.ellipse(px, py + 25, W + 6, 5, 0, 0, Math.PI * 2); ctx.fill();                  \/\/ sombra&#10;    ctx.fillStyle = '#c9ced3'; ctx.fillRect(px - W - 4, py + 20, 2 * W + 8, 4); ctx.strokeRect(px - W - 4, py + 20, 2 * W + 8, 4);          \/\/ and\u00e9n&#10;    ctx.fillStyle = 'rgba(150,220,235,0.35)'; ctx.fillRect(px - W, py - 22, 2 * W, 42); ctx.strokeRect(px - W, py - 22, 2 * W, 42);        \/\/ cristal trasero&#10;    ctx.fillStyle = '#5a6066'; [px - W - 2, px + W - 2].forEach(x =&gt; { ctx.fillRect(x, py - 24, 4, 44); ctx.strokeRect(x, py - 24, 4, 44); });   \/\/ postes&#10;    ctx.fillStyle = '#2f6fd0'; ctx.beginPath(); ctx.moveTo(px - W - 6, py - 22); ctx.lineTo(px + W + 6, py - 22); ctx.lineTo(px + W, py - 31); ctx.lineTo(px - W, py - 31); ctx.closePath(); ctx.fill(); ctx.stroke();   \/\/ techo solar&#10;    ctx.strokeStyle = 'rgba(255,255,255,0.5)'; for (let i = -W + 12; i &lt; W; i += 24) { ctx.beginPath(); ctx.moveTo(px + i, py - 31); ctx.lineTo(px + i, py - 22); ctx.stroke(); }&#10;    ctx.fillStyle = '#0d1226'; ctx.strokeStyle = '#000'; ctx.beginPath(); ctx.roundRect(px - W + 6, py - 18, 2 * W - 12, 34, 6); ctx.fill();   \/\/ cartel luminoso&#10;    ctx.save(); ctx.shadowColor = glow; ctx.shadowBlur = 9 * g; ctx.strokeStyle = glow; ctx.lineWidth = 2.5; ctx.stroke(); ctx.restore();&#10;    mTxt(l1, px, py - 7, 11.5, '#fff', 'center'); mTxt(l2, px, py + 8, 11.5, glow, 'center');&#10;    ctx.restore();&#10;}&#10;function dibujarParadaArena(t) { dibujarParadaTranvia(ARENA_PARADA, t, '\u2192 Distrito Cultural', '&amp; Arena \ud83c\udfdf\ufe0f', '#7cffd9'); }&#10;function dibujarParadaHospital(t) { dibujarParadaTranvia(HOSPITAL_PARADA, t, '\u2192 Hospital', 'cient\u00edfico \ud83c\udfe5', '#8affc1'); }&#10;const Arena = (() =&gt; {&#10;    const W = canvas.width, H = canvas.height;&#10;    const Z = { pista: { x: 8, y: 24, w: 468, h: 250 }, teatro: { x: 484, y: 24, w: 468, h: 250 }, ajedrez: { x: 8, y: 282, w: 468, h: 250 }, sastre: { x: 484, y: 282, w: 468, h: 250 } };&#10;    const ZT = { teatro: { k: 1.37, ox: 485, oy: 20, x0: 14, y0: 272 }, ajedrez: { k: 1.55, ox: 59, oy: 274, x0: 362, y0: 272 }, sastre: { k: 1.37, ox: 485, oy: 278, x0: 606, y0: 272 } };&#10;    const M = (z, x, y) =&gt; [ZT[z].ox + (x - ZT[z].x0) * ZT[z].k, ZT[z].oy + (y - ZT[z].y0) * ZT[z].k];&#10;    const slm = (z, a) =&gt; a.map(([x, y, d]) =&gt; [...M(z, x, y), d]);&#10;    const rm = (z, r) =&gt; { const p = M(z, r.x, r.y); return { x: p[0], y: p[1], w: r.w * ZT[z].k, h: r.h * ZT[z].k }; };&#10;    const SLO = { teatro: [[245, 412, -1], [300, 412, -1], [272, 384, -1]], ajedrez: [[410, 414, 1], [550, 414, -1]] };&#10;    function elegirActividad(f) {   \/\/ las chicas deciden solas: pasear, grada, teatro, ajedrez o boutique (si alguien espera rival en el ajedrez, se sientan con ella)&#10;        const ocup = k =&gt; F.filter(o =&gt; !o.gen &amp;&amp; o !== f &amp;&amp; o.act === k).length;&#10;        const ks = ['grada', 'teatro', 'ajedrez', 'sastre', 'pasear'].filter(k =&gt; k !== f.act &amp;&amp; (k === 'pasear' || ocup(k) &lt; SL[k].length));&#10;        const W = ks.map(z =&gt; PERSONAS[f.id].arena[z] || 1); let r = Math.random() * W.reduce((a, b) =&gt; a + b, 0), q = 0; while (q &lt; ks.length - 1 &amp;&amp; (r -= W[q]) &gt; 0) q++;   \/\/ su personalidad inclina la elecci\u00f3n&#10;        const k = ks.find(z =&gt; z === 'ajedrez' &amp;&amp; ocup(z) === 1) || ks[q];&#10;        if (k === 'pasear') { const z = Z[['pista', 'teatro', 'ajedrez', 'sastre'][Math.floor(Math.random() * 4)]]; f.act = 'pasear'; f.slot = 0; f.llego = false; f.pt = [z.x + 40 + Math.random() * (z.w - 80), z.y + 170 + Math.random() * 60, Math.random() &lt; .5 ? 1 : -1]; f.dur = 2700; }&#10;        else if (k &amp;&amp; asignar(f, k, false)) f.dur = 2700;&#10;    }&#10;    const SCR = { x: 28, y: 322, w: 170, h: 84 }, MAN = { x: 776, y: 400 };&#10;    const SL = { grada: [[44, 160, 1], [54, 206, 1], [122, 238, 1], [362, 238, -1], [430, 206, -1], [440, 160, -1], [192, 254, 1], [292, 254, -1], [70, 120, 1], [414, 120, -1]], corre: [[0, 0, 1], [0, 0, 1], [0, 0, 1]], teatro: slm('teatro', SLO.teatro), ajedrez: slm('ajedrez', SLO.ajedrez), sastre: slm('sastre', [[628, 426, 1], [748, 428, -1]]) };&#10;    const SLG = { sastre: slm('sastre', [[700, 402, 1], [786, 424, 1]]) };   \/\/ 0 = modelo en la tarima, 1 = operadora de la impresora (puestos fijos 24\/7\/365)&#10;    const RUT = ['pista', 'teatro', 'ajedrez', 'ajedrez', 'sastre', 'sastre', 'sastre'];      \/\/ rutina fija en Modo Sandbox: las chicas disfrutan, las genoides trabajan&#10;    const TRAB = { pista: '\ud83e\uddf9', teatro: '\ud83c\udf9e\ufe0f', ajedrez: '\ud83e\uddfd', sastre: '\ud83e\uddf5' };&#10;    const COL = ['#4a7bd8', '#d32f2f', '#4caf78', '#a14bd6', '#f4b400'], EST = ['\ud83d\udc55 Urbana', '\ud83c\udfc3 Deportiva', '\ud83e\udde2 Accesorios'];&#10;    const SHOW = ['\ud83c\udfac Cine hologr\u00e1fico', '\ud83c\udfad Teatro inmersivo', '\ud83c\udfa4 Concierto hologr\u00e1fico'], ICO = ['\ud83c\udfac', '\ud83c\udfad', '\ud83c\udfa4'], REAC = ['\ud83c\udf7f', '\ud83d\udc4f', '\ud83d\ude4c'];&#10;    const gen = (x, y, fase, estilo) =&gt; ({ gen: true, x, y, fase, estilo, dir: 1, tarea: 'busca', t: 0, trab: false, ic: '', espera: 1, arm: 'A', llevando: null, obj: null, act: null, slot: null, llego: false });&#10;    const chi = (id, fase) =&gt; ({ x: 0, y: 0, id, pelo: habitantes[id].colorPelo, estilo: habitantes[id].estilo, fase, dir: 1, espera: 1, act: null, slot: null, llego: false });&#10;    const F = [chi(0, 0), chi(1, 1), chi(2, 2), chi(3, 3), chi(4, 6), gen(0, 0, 4, 'pincho'), gen(0, 0, 5, 'largo'), chi(5, 7), chi(6, 8), chi(7, 9)];&#10;    const CATARENA = { grada: 'estadio', corre: 'deporte', ajedrez: 'ajedrez', teatro: 'teatro', sastre: 'moda' };&#10;    let modo = 'sandbox', energia = 0, ondas = [], man = { c: 0, e: 0 }, grab = null, off = { x: 0, y: 0 }, show = 0, showT = 0;&#10;    const PART = 'e2e4 e7e5 g1f3 d7d6 d2d4 c8g4 d4e5 g4f3 d1f3 d6e5 f1c4 g8f6 f3b3 d8e7 b1c3 c7c6 c1g5 b7b5 c3b5 c6b5 c4b5 b8d7 e1c1 a8d8 d1d7 d8d7 h1d1 e7e6 b5d7 f6d7 b3b8 d7b8 d1d8'.split(' ');&#10;    const GL = { k: '\u265a', q: '\u265b', r: '\u265c', b: '\u265d', n: '\u265e', p: '\u265f' }, BX = 440, BY = 318, C = 10;&#10;    const tablero = () =&gt; { const b = {}; 'rnbqkbnr'.split('').forEach((p, i) =&gt; { const c = 'abcdefgh'[i]; b[c + 8] = p; b[c + 1] = p.toUpperCase(); b[c + 7] = 'p'; b[c + 2] = 'P'; }); return b; };&#10;    let ajd = { b: tablero(), n: 0, t: 0 };&#10;    function jugar(m) {&#10;        const a = m.slice(0, 2), b = m.slice(2), p = ajd.b[a];&#10;        if ('kK'.includes(p) &amp;&amp; Math.abs(a.charCodeAt(0) - b.charCodeAt(0)) === 2) { const k = b &gt; a, r = a[1]; ajd.b[(k ? 'f' : 'd') + r] = ajd.b[(k ? 'h' : 'a') + r]; delete ajd.b[(k ? 'h' : 'a') + r]; }   \/\/ enroque&#10;        ajd.b[b] = p; delete ajd.b[a];&#10;    }&#10;    const zonaDe = (x, y) =&gt; Object.keys(Z).find(k =&gt; dentroRect(x, y, Z[k])) || null;&#10;    function asignar(f, act, snap) {&#10;        const L = f.gen ? SLG : SL, libre = i =&gt; !F.some(o =&gt; o !== f &amp;&amp; o.gen === f.gen &amp;&amp; o.act === act &amp;&amp; o.slot === i);&#10;        const oc = F.filter(o =&gt; o !== f &amp;&amp; !o.gen &amp;&amp; o.act === 'grada').map(o =&gt; SL.grada[o.slot]), dm = k =&gt; oc.length ? Math.min(...oc.map(q =&gt; Math.hypot(q[0] - SL.grada[k][0], q[1] - SL.grada[k][1]))) : 0;   \/\/ en la grada se sientan lo m\u00e1s separadas posible&#10;        const i = act === 'grada' &amp;&amp; !f.gen ? L.grada.map((s, k) =&gt; k).filter(libre).reduce((a, b) =&gt; a &lt; 0 || dm(b) &gt; dm(a) ? b : a, -1) : L[act].findIndex((s, k) =&gt; libre(k));&#10;        if (i &lt; 0) return false;&#10;        f.act = act; f.slot = i; f.llego = false;&#10;        if (snap) { f.x = L[act][i][0]; f.y = L[act][i][1]; f.dir = L[act][i][2]; f.llego = true; }&#10;        return true;&#10;    }&#10;    function paso(f, t) {&#10;        if (f === grab) return;&#10;        f.espera = 1;&#10;        if (!f.gen) { if (f.dur &gt; 0) f.dur--; else if (f.llego || !f.act) elegirActividad(f); }&#10;        if (f.act === 'corre') {   \/\/ atletismo: 3 chicas corren juntas por sus calles y generan energ\u00eda limpia&#10;            const l = [[172, 60], [152, 50], [132, 40]][f.slot], a = t * 0.022 + f.slot * 0.35, tx = EC.x + l[0] * Math.cos(a), ty = EC.y + l[1] * Math.sin(a), d = Math.hypot(tx - f.x, ty - f.y);&#10;            if (d &gt; 20) { f.x += (tx - f.x) \/ d * 2.4; f.y += (ty - f.y) \/ d * 2.4; f.dir = tx &gt; f.x ? 1 : -1; } else { f.x = tx; f.y = ty; f.dir = Math.sin(a) &lt; 0 ? 1 : -1; energia += 0.003; if (t % 18 === Math.floor(f.fase * 3) % 18) ondas.push({ x: f.x, y: f.y, r: 4 }); }&#10;            f.espera = 0; f.llego = true; return;&#10;        }&#10;        const s = f.act === 'pasear' ? f.pt : f.act &amp;&amp; (f.gen ? SLG : SL)[f.act][f.slot];&#10;        if (s &amp;&amp; f.gen &amp;&amp; f.act === 'sastre' &amp;&amp; f.slot === 0 &amp;&amp; Math.hypot(f.x - SLG.sastre[0][0], f.y - SLG.sastre[0][1]) &lt; 70) { f.x = SLG.sastre[0][0] + Math.sin(t \/ 70) * 44; f.y = SLG.sastre[0][1]; f.dir = Math.cos(t \/ 70) &gt; 0 ? 1 : -1; f.espera = 0; f.llego = true; f.trab = true; return; }   \/\/ desfila por la pasarela&#10;        if (!s) { f.llego = false; return; }&#10;        const dx = s[0] - f.x, dy = s[1] - f.y, d = Math.hypot(dx, dy);&#10;        if (d &gt; 1.6) { f.x += dx \/ d * 1.1; f.y += dy \/ d * 1.1; f.dir = dx &gt; 0 ? 1 : -1; f.espera = 0; f.llego = false; }&#10;        else { f.x = s[0]; f.y = s[1]; f.dir = s[2]; f.llego = true; }&#10;        f.trab = !!f.gen &amp;&amp; f.llego;&#10;        if (!f.llego) return;&#10;        if (f.act === 'pista' &amp;&amp; !f.gen &amp;&amp; t % 40 === Math.floor(f.fase * 7) % 40) { ondas.push({ x: f.x, y: f.y, r: 4 }); energia += 0.02; }   \/\/ pasos piezoel\u00e9ctricos&#10;    }&#10;    function silla(x, y, d, c) {   \/\/ asiento futurista con borde de ne\u00f3n&#10;        ctx.save(); ctx.shadowColor = c; ctx.shadowBlur = 8; ctx.fillStyle = '#0d1226'; ctx.strokeStyle = c; ctx.lineWidth = 1.5;&#10;        ctx.beginPath(); ctx.roundRect(x - d * 18 - 4, y - 42, 8, 34, 4); ctx.fill(); ctx.stroke();&#10;        ctx.beginPath(); ctx.roundRect(x - 16, y - 16, 32, 9, 4); ctx.fill(); ctx.stroke();&#10;        ctx.beginPath(); ctx.moveTo(x, y - 7); ctx.lineTo(x, y - 2); ctx.stroke(); ctx.beginPath(); ctx.ellipse(x, y - 1, 11, 3, 0, 0, Math.PI * 2); ctx.stroke();&#10;        ctx.restore();&#10;    }&#10;    let ropa = { e: 0, ph: 0, t: 0 };                                   \/\/ taller: 0 imprimiendo \u00b7 1 vistiendo \u00b7 2 desfile&#10;    const TAR = { x: 628, y: 330, w: 140, h: 90 }, COLR = ['#4a7bd8', '#d32f2f'];&#10;    function elegir() { F.forEach(f =&gt; { if (!f.gen &amp;&amp; f.act === 'sastre' &amp;&amp; f.llego) f.vest = ropa.ph &gt;= 1 ? ropa.e : 1 - ropa.e; }); }   \/\/ las chicas eligen el conjunto que luce la genoide&#10;    function ciclo() { if (++ropa.t &gt; [360, 50, 480][ropa.ph]) { ropa.t = 0; if (ropa.ph === 2) elegir(); ropa.ph = (ropa.ph + 1) % 3; if (ropa.ph === 0) ropa.e = 1 - ropa.e; } }&#10;    function prenda(f, e) {&#10;        const c = COLR[e]; ctx.save(); ctx.translate(f.x, f.y - 28); ctx.scale(1.1, 1.1);&#10;        ctx.beginPath(); ctx.ellipse(0, 0, 15, 25, 0, 0, Math.PI * 2); ctx.clip();&#10;        ctx.fillStyle = c; ctx.fillRect(-16, 8, 32, 20); ctx.fillStyle = '#fff';&#10;        if (e) { ctx.fillRect(-3, 8, 2.5, 20); ctx.fillRect(1, 8, 2.5, 20); } else ctx.fillRect(-4, 8, 8, 4);&#10;        ctx.restore();&#10;        ctx.save(); ctx.translate(f.x, f.y - 28); ctx.scale(1.1, 1.1); ctx.fillStyle = c; ctx.fillRect(-12, e ? -16 : -28, 24, e ? 3 : 6); ctx.restore();   \/\/ gorra (urbana) o cinta (deportiva)&#10;    }&#10;    function sastreria(t) {   \/\/ boutique de moda: pasarela con la modelo y atelier molecular de cristal&#10;        const e = ropa.e, c = COLR[e], p = ropa.ph === 0 ? Math.min(1, ropa.t \/ 360) : 1, ORO = '#d4af37', pm = F.find(f =&gt; f.gen &amp;&amp; f.act === 'sastre' &amp;&amp; f.slot === 0), bx = 866, gy = 372;&#10;        ctx.fillStyle = '#2a1230'; ctx.fillRect(612, 322, 328, 84);                                                  \/\/ pared de terciopelo&#10;        ctx.fillStyle = '#e9dfd0'; ctx.fillRect(612, 404, 328, 26); ctx.fillStyle = ORO; ctx.fillRect(612, 404, 328, 2);   \/\/ suelo de m\u00e1rmol&#10;        ctx.fillStyle = '#7b2d5b'; ctx.fillRect(630, 322, 22, 82); ctx.fillRect(748, 322, 22, 82); ctx.fillStyle = 'rgba(255,255,255,0.12)';&#10;        for (let i = 0; i &lt; 3; i++) { ctx.fillRect(634 + i * 6, 322, 1.5, 82); ctx.fillRect(752 + i * 6, 322, 1.5, 82); }   \/\/ cortinas&#10;        mTxt('\u2726 MIIG26 MODA \u2726', 700, 332, 10, ORO, 'center');&#10;        ctx.fillStyle = 'rgba(255,240,170,0.14)'; ctx.beginPath(); ctx.moveTo(684, 340); ctx.lineTo(716, 340); ctx.lineTo(756, 404); ctx.lineTo(644, 404); ctx.closePath(); ctx.fill();   \/\/ foco&#10;        ctx.fillStyle = '#f5ecd9'; ctx.strokeStyle = ORO; ctx.lineWidth = 2; ctx.fillRect(640, 402, 120, 12); ctx.strokeRect(640, 402, 120, 12);&#10;        ctx.fillStyle = COLR[ropa.ph &gt;= 1 ? e : 1 - e]; ctx.fillRect(642, 411, 116, 2);                                \/\/ pasarela con luz LED del conjunto&#10;        if (ropa.ph === 1 &amp;&amp; pm) for (let i = 0; i &lt; 12; i++) { ctx.fillStyle = i % 2 ? '#fff' : ORO; ctx.fillRect(((pm.x - ZT.sastre.ox) \/ ZT.sastre.k + ZT.sastre.x0) + Math.cos(i * 2.4 + t \/ 5) * 20, 372 + Math.sin(i * 1.7 + t \/ 4) * 28, 3, 3); }&#10;        ctx.save(); ctx.fillStyle = 'rgba(255,255,255,0.08)'; ctx.strokeStyle = 'rgba(255,255,255,0.55)'; ctx.lineWidth = 2;   \/\/ atelier molecular de cristal&#10;        ctx.beginPath(); ctx.moveTo(bx - 38, 408); ctx.lineTo(bx - 38, 340); ctx.ellipse(bx, 340, 38, 8, 0, Math.PI, Math.PI * 2); ctx.lineTo(bx + 38, 408); ctx.closePath(); ctx.fill(); ctx.stroke();&#10;        ctx.save(); ctx.beginPath(); ctx.rect(bx - 30, gy + 14 - 36 * p, 60, 36 * p); ctx.clip();                    \/\/ la prenda se materializa de abajo arriba&#10;        ctx.shadowColor = c; ctx.shadowBlur = 10; ctx.fillStyle = c; ctx.beginPath(); ctx.moveTo(bx - 12, gy - 20); ctx.lineTo(bx + 12, gy - 20); ctx.lineTo(bx + 26, gy - 8); ctx.lineTo(bx + 19, gy - 2); ctx.lineTo(bx + 12, gy - 8); ctx.lineTo(bx + 12, gy + 14); ctx.lineTo(bx - 12, gy + 14); ctx.lineTo(bx - 12, gy - 8); ctx.lineTo(bx - 19, gy - 2); ctx.lineTo(bx - 26, gy - 8); ctx.closePath(); ctx.fill();&#10;        ctx.shadowBlur = 0; ctx.fillStyle = '#fff'; if (e) { ctx.fillRect(bx - 4, gy - 20, 2.5, 34); ctx.fillRect(bx + 2, gy - 20, 2.5, 34); } else ctx.fillRect(bx - 8, gy + 2, 16, 8);&#10;        ctx.restore();&#10;        if (ropa.ph === 0) { ctx.strokeStyle = '#ffd6f2'; ctx.lineWidth = 2; ctx.beginPath(); ctx.ellipse(bx, gy + 14 - 36 * p, 34, 7, 0, 0, Math.PI * 2); ctx.stroke(); }   \/\/ anillo de escaneo&#10;        for (let i = 0; i &lt; 10; i++) { ctx.fillStyle = i % 2 ? '#ffd6f2' : '#fff'; ctx.fillRect(bx + Math.sin(i * 5 + t \/ 15) * 28, 406 - ((t * .8 + i * 13) % 66), 2, 2); }&#10;        ctx.fillStyle = ORO; ctx.beginPath(); ctx.ellipse(bx, 408, 42, 8, 0, 0, Math.PI * 2); ctx.fill(); ctx.fillStyle = '#4a2c52'; ctx.beginPath(); ctx.ellipse(bx, 406, 34, 5, 0, 0, Math.PI * 2); ctx.fill();&#10;        ctx.strokeStyle = ORO; ctx.beginPath(); ctx.ellipse(bx, 340, 38, 8, 0, 0, Math.PI * 2); ctx.stroke();&#10;        ctx.restore();&#10;        mTxt('Atelier molecular', bx, 328, 10, ORO, 'center');&#10;        mTxt(ropa.ph === 0 ? '\u2728 Dise\u00f1ando ' + (e ? 'deportiva ' : 'urbana ') + Math.round(p * 100) + '%' : '\u2714 Colecci\u00f3n lista', bx, 421, 10, '#3a2a44', 'center');&#10;    }&#10;    let ms = { i: 0, t: 0, tr: 0 }, boost = 0, da = 0, rot = 0, foco = 0;&#10;    const DUR = [3000, 2700, 2700], MOD = ['\u26bd Modo F\u00fatbol \u00b7 pantalla central MIIG26 ARENA', '\ud83d\udef8 Modo eSports \u00b7 campeonato de drones \u00b7 toca el circuito', '\ud83c\udfc3 Atletismo piezoel\u00e9ctrico'], EC = { x: 242, y: 172 };&#10;    function cambiarModo(n) {&#10;        ms.i = n; if (n === 0) fut = null;&#10;        F.forEach(f =&gt; { if (f.act === 'corre') { f.act = null; f.slot = null; if (!asignar(f, 'grada', false)) elegirActividad(f); f.dur = 400; } });   \/\/ al acabar, las corredoras pasan a la grada&#10;        if (n === 2) { rot = (rot + 1) % 5; const ch = F.filter(f =&gt; !f.gen &amp;&amp; f.act !== 'ajedrez' &amp;&amp; f.act !== 'sastre'), c = ch.slice(rot % Math.max(1, ch.length)).concat(ch.slice(0, rot % Math.max(1, ch.length)));&#10;            c.slice(0, 3).forEach(f =&gt; { if (asignar(f, 'corre', false)) f.dur = 1e9; }); }                  \/\/ 3 chicas corren juntas durante 45 s&#10;    }&#10;    function cicloEstadio() {&#10;        if (ms.tr &gt; 0) { ms.tr--; if (ms.tr === 50) cambiarModo((ms.i + 1) % 3); }&#10;        else if (++ms.t &gt; DUR[ms.i]) { ms.t = 0; ms.tr = 100; }&#10;    }&#10;    let fut = null;   \/\/ partido de f\u00fatbol 3 contra 3: portera + dos jugadoras de campo que persiguen el bal\u00f3n; saques alternos&#10;    function saque(g) { const cx = EC.x, cy = EC.y, H = [[-100, 0], [-50, -30], [-162, 0]]; g.kc = 0; g.hold = 45; g.b = { x: cx, y: cy, vx: 0, vy: 0 }; g.p = [];&#10;        H.forEach(h =&gt; g.p.push({ hx: h[0], hy: h[1], x: cx + h[0], y: cy + h[1], dir: 1, kt: 0 })); H.forEach(h =&gt; g.p.push({ hx: -h[0], hy: h[1], x: cx - h[0], y: cy + h[1], dir: -1, kt: 0 })); }&#10;    function futbol(t) {&#10;        const cx = EC.x, cy = EC.y; if (!fut) { fut = { sa: 0, sb: 0, n: 0 }; saque(fut); }&#10;        const b = fut.b; if (fut.kc &gt; 0) fut.kc--; if (fut.hold &gt; 0) fut.hold--; b.x += b.vx; b.y += b.vy; b.vx *= .985; b.vy *= .985;&#10;        if (b.x &gt; cx + 172 &amp;&amp; Math.abs(b.y - cy) &lt; 24) { fut.sa++; fut.n++; saque(fut); return; }&#10;        if (b.x &lt; cx - 172 &amp;&amp; Math.abs(b.y - cy) &lt; 24) { fut.sb++; fut.n++; saque(fut); return; }&#10;        const ex = (b.x - cx) \/ 182, ey = (b.y - cy) \/ 64, d = ex * ex + ey * ey;&#10;        if (d &gt; 1 &amp;&amp; !(Math.abs(b.y - cy) &lt; 24 &amp;&amp; Math.abs(b.x - cx) &gt; 150)) { const k = 1 \/ Math.sqrt(d); b.x = cx + (b.x - cx) * k * .98; b.y = cy + (b.y - cy) * k * .98; b.vx *= -.6; b.vy *= -.6; }&#10;        (t % 2 ? [0, 3] : [3, 0]).forEach(o =&gt; {   \/\/ (el orden alterna para que ning\u00fan equipo tenga ventaja) en cada equipo: la jugadora de campo m\u00e1s cercana persigue el bal\u00f3n, la otra apoya y la portera guarda su porter\u00eda&#10;            const c = Math.hypot(fut.p[o].x - b.x, fut.p[o].y - b.y) &lt; Math.hypot(fut.p[o + 1].x - b.x, fut.p[o + 1].y - b.y) ? o : o + 1;&#10;            for (let i = o; i &lt; o + 3; i++) {&#10;                const q = fut.p[i], port = i === o + 2, tx = port ? cx + (o === 0 ? -162 : 162) : i === c ? b.x : cx + q.hx + (b.x - cx) * .35, ty = port ? cy + Math.max(-14, Math.min(14, b.y - cy)) : i === c ? b.y : cy + q.hy + (b.y - cy) * .35;&#10;                const dx = tx - q.x, dy = ty - q.y, dd = Math.hypot(dx, dy) || 1, v = port ? .6 : i === c ? 1.7 : 1;&#10;                if (dd &gt; 2) { q.x += dx \/ dd * v; q.y += dy \/ dd * v; q.dir = dx &gt; 0 ? 1 : -1; }&#10;                q.x = Math.max(cx - 176, Math.min(cx + 176, q.x)); q.y = Math.max(cy - 56, Math.min(cy + 56, q.y));&#10;                if (q.kt &gt; 0) q.kt--;&#10;                else if (fut.kc &lt;= 0 &amp;&amp; (fut.hold &lt;= 0 || fut.n % 2 === (o ? 1 : 0)) &amp;&amp; Math.hypot(q.x - b.x, q.y - b.y) &lt; 11) {   \/\/ chuta hacia la porter\u00eda rival, con algo de error&#10;                    const gx = cx + (o === 0 ? 178 : -178) - b.x, gy = cy + Math.sin(t * .07 + i) * 12 - b.y, a = Math.atan2(gy, gx) + Math.sin(t * .13 + i * 7) * .5 * Math.min(1, Math.abs(gx) \/ 220);&#10;                    b.vx = Math.cos(a) * 3.9; b.vy = Math.sin(a) * 3.9; q.kt = 25; fut.kc = 12;&#10;                }&#10;            }&#10;        });&#10;    }&#10;    function estadio(t) {&#10;        const cx = EC.x, cy = EC.y, c = ms.tr &gt; 0 ? 1 - Math.abs(ms.tr - 50) \/ 50 : 0, L = cx - 190, top = cy - 72;&#10;        ctx.save(); ctx.lineWidth = 5; ctx.strokeStyle = '#000'; ctx.fillStyle = '#1a1030'; ctx.beginPath(); ctx.ellipse(242, 168, 222, 92, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();   \/\/ grader\u00edo&#10;        for (let i = 0; i &lt; 40; i++) { const a = i \/ 40 * Math.PI * 2; ctx.fillStyle = i % 2 ? '#7cffd9' : '#a14bd6'; ctx.beginPath(); ctx.roundRect(242 + Math.cos(a) * 205 - 5, 168 + Math.sin(a) * 82 - 3, 10, 6, 2); ctx.fill(); }&#10;        ctx.save(); ctx.beginPath(); ctx.ellipse(cx, cy, 188, 70, 0, 0, Math.PI * 2); ctx.clip();&#10;        if (ms.i === 0) {   \/\/ F\u00daTBOL: porter\u00edas de luz y pantalla central&#10;            futbol(t);&#10;            ctx.fillStyle = '#0b3d2e'; ctx.fillRect(L, top, 380, 144); ctx.strokeStyle = 'rgba(255,255,255,0.8)'; ctx.lineWidth = 2;&#10;            ctx.beginPath(); ctx.moveTo(cx, top); ctx.lineTo(cx, top + 144); ctx.stroke(); ctx.beginPath(); ctx.arc(cx, cy, 26, 0, Math.PI * 2); ctx.stroke();&#10;            ctx.save(); ctx.shadowColor = '#7cffd9'; ctx.shadowBlur = 10; ctx.strokeStyle = '#7cffd9'; ctx.lineWidth = 3; ctx.strokeRect(cx - 186, cy - 22, 14, 44); ctx.strokeRect(cx + 172, cy - 22, 14, 44); ctx.restore();&#10;            ctx.fillStyle = '#000'; ctx.strokeStyle = '#fff'; ctx.lineWidth = 2; ctx.beginPath(); ctx.roundRect(cx - 44, cy - 16, 88, 32, 6); ctx.fill(); ctx.stroke(); mTxtAjustado('MIIG26', cx, cy - 5, 11, '#fff', 76); mTxtAjustado('ARENA', cx, cy + 8, 11, '#fff', 76);&#10;            mTxt(fut.sa + ' - ' + fut.sb, cx, cy + 30, 13, '#fff', 'center');&#10;            fut.p.forEach((q, i) =&gt; {   \/\/ chicas de equipo en miniatura&#10;                const eq = i &lt; 3; ctx.save(); ctx.translate(q.x, q.y + 12); ctx.scale(.42, .42); dibujarMu\u00f1eca({ x: 0, y: 0, angulo: Math.sin(t \/ 5 + i) * .1 }, eq ? '#f2c14e' : '#6b3f26', false, q.dir &lt; 0, false, 'largo');&#10;                ctx.beginPath(); ctx.ellipse(0, 0, 15, 25, 0, 0, Math.PI * 2); ctx.clip(); ctx.fillStyle = i % 3 === 2 ? '#4caf78' : eq ? '#4a7bd8' : '#d32f2f'; ctx.fillRect(-16, 6, 32, 22); ctx.restore();&#10;            });&#10;            ctx.save(); ctx.shadowColor = '#fff'; ctx.shadowBlur = 8; ctx.fillStyle = '#fff'; ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.beginPath(); ctx.arc(fut.b.x, fut.b.y, 6, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.restore();   \/\/ el bal\u00f3n va siempre por encima de la pantalla y de las jugadoras&#10;        } else if (ms.i === 1) {   \/\/ eSPORTS \/ DRONES: escenario digital y circuito interactivo&#10;            ctx.fillStyle = '#060818'; ctx.fillRect(L, top, 380, 144); ctx.strokeStyle = 'rgba(124,255,217,0.25)'; ctx.lineWidth = 1;&#10;            for (let x = L; x &lt; L + 380; x += 20) { ctx.beginPath(); ctx.moveTo(x, top); ctx.lineTo(x, top + 144); ctx.stroke(); } for (let y = top; y &lt; top + 144; y += 20) { ctx.beginPath(); ctx.moveTo(L, y); ctx.lineTo(L + 380, y); ctx.stroke(); }&#10;            ctx.strokeStyle = '#a14bd6'; ctx.lineWidth = 4; ctx.beginPath(); ctx.ellipse(cx, cy, 130, 42, 0, 0, Math.PI * 2); ctx.stroke();&#10;            if (boost &gt; 0) boost--; da += .03 + (boost &gt; 0 ? .05 : 0);&#10;            for (let i = 0; i &lt; 3; i++) { const a = da * (1 + i * .12) + i * 2.1, x = cx + 130 * Math.cos(a), y = cy + 42 * Math.sin(a); ctx.save(); ctx.shadowColor = ['#7cffd9', '#ff4081', '#f4b400'][i]; ctx.shadowBlur = 12; ctx.fillStyle = ctx.shadowColor; ctx.beginPath(); ctx.arc(x, y, 5, 0, Math.PI * 2); ctx.fill(); ctx.strokeStyle = '#fff'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(x - 9 * Math.cos(t \/ 2), y - 4); ctx.lineTo(x + 9 * Math.cos(t \/ 2), y - 4); ctx.stroke(); ctx.restore(); }&#10;            mTxt('eSPORTS \u00b7 DRONES', cx, cy - 56, 11, '#7cffd9', 'center');&#10;        } else {   \/\/ ATLETISMO PIEZOEL\u00c9CTRICO: pista de calles&#10;            ctx.fillStyle = '#7a2e1c'; ctx.fillRect(L, top, 380, 144); ctx.strokeStyle = '#fff'; ctx.lineWidth = 2;&#10;            [[172, 60], [152, 50], [132, 40]].forEach(l =&gt; { ctx.beginPath(); ctx.ellipse(cx, cy, l[0], l[1], 0, 0, Math.PI * 2); ctx.stroke(); });&#10;            ctx.fillStyle = '#0b3d2e'; ctx.beginPath(); ctx.ellipse(cx, cy, 112, 30, 0, 0, Math.PI * 2); ctx.fill();&#10;            mTxt(ms.tr &gt; 0 ? '' : Math.ceil((DUR[2] - ms.t) \/ 60) + ' s', cx, cy - 4, 18, '#fff', 'center'); mTxt('PIEZOEL\u00c9CTRICO', cx, cy + 12, 10, '#7cffd9', 'center');&#10;        }&#10;        ondas = ondas.filter(o =&gt; o.r &lt; 40); ondas.forEach(o =&gt; { o.r += 1; ctx.strokeStyle = `rgba(124,255,217,${1 - o.r \/ 40})`; ctx.lineWidth = 2; ctx.beginPath(); ctx.ellipse(o.x, o.y, o.r, o.r * .35, 0, 0, Math.PI * 2); ctx.stroke(); });&#10;        if (c &gt; 0) {   \/\/ suelo retr\u00e1ctil: paneles met\u00e1licos que se cierran y se abren&#10;            const w = 190 * c; ctx.fillStyle = '#37474f'; ctx.fillRect(L, top, w, 144); ctx.fillRect(cx + 190 - w, top, w, 144); ctx.strokeStyle = '#7cffd9'; ctx.lineWidth = 2;&#10;            for (let i = 1; i &lt; 6; i++) { ctx.beginPath(); ctx.moveTo(L, top + i * 24); ctx.lineTo(L + w, top + i * 24); ctx.moveTo(cx + 190 - w, top + i * 24); ctx.lineTo(cx + 190, top + i * 24); ctx.stroke(); }&#10;            ctx.fillStyle = '#7cffd9'; ctx.fillRect(L + w - 3, top, 3, 144); ctx.fillRect(cx + 190 - w, top, 3, 144);&#10;        }&#10;        ctx.restore();&#10;        ctx.strokeStyle = '#7cffd9'; ctx.lineWidth = 3; ctx.beginPath(); ctx.ellipse(cx, cy, 188, 70, 0, 0, Math.PI * 2); ctx.stroke();&#10;        SL.grada.forEach(s =&gt; { ctx.save(); ctx.translate(s[0], s[1]); ctx.scale(1.3, 1.3); silla(0, 0, s[2], '#7cffd9'); ctx.restore(); });   \/\/ asientos de la grada&#10;        ctx.restore();&#10;    }&#10;    function figura(f, t, now) {&#10;        const z = f.llego &amp;&amp; !f.gen ? f.act : null, sent = z === 'teatro' || z === 'ajedrez' || z === 'grada', baile = z === 'pista';&#10;        const salto = baile ? Math.abs(Math.sin(t \/ 8 + f.fase)) * 5 : 0;&#10;        ctx.save(); ctx.translate(f.x, f.y - salto - (f === grab ? 12 : 0) + (sent ? 5 : 0)); ctx.scale(1, 1); ctx.translate(-f.x, -f.y);&#10;        if (f.gen) Industria.genoide(f, now);&#10;        else { const bam = f.espera === 0 ? Math.sin(t \/ 6) * .06 * f.dir : Math.sin(t \/ 30 + f.fase) * .02 + (baile ? Math.sin(t \/ 5 + f.fase) * .08 : 0) + (z === 'teatro' ? .05 * f.dir : 0);&#10;            ctx.translate(f.x, f.y - 28); ctx.scale(1.1, 1.1); dibujarMu\u00f1eca({ x: 0, y: 0, angulo: bam }, f.pelo, false, f.dir &lt; 0, false, f.estilo); }&#10;        if (!f.gen) { ctx.scale(1 \/ 1.1, 1 \/ 1.1); ctx.translate(-f.x, -(f.y - 28)); }   \/\/ vuelve al sistema de coordenadas base&#10;        { const e = f.gen &amp;&amp; f.act === 'sastre' &amp;&amp; f.slot === 0 &amp;&amp; f.llego ? (ropa.ph &gt;= 1 ? ropa.e : 1 - ropa.e) : f.vest; if (e !== undefined) prenda(f, e); }&#10;        ctx.restore();&#10;        let ic = z === 'teatro' ? REAC[show] : z === 'sastre' ? '\u2728' : z === 'grada' ? ['\u26bd', '\ud83d\udef8', '\ud83c\udfc3'][ms.i] : z === 'corre' ? '\ud83d\udca8' : '';&#10;        if (z === 'ajedrez') ic = (ajd.n % 2 === f.slot &amp;&amp; ajd.t &lt; 100) ? '\ud83e\udd14' : '\u265f\ufe0f';&#10;        if (f.gen &amp;&amp; f.llego) ic = f.act === 'sastre' &amp;&amp; f.slot === 0 ? '' : TRAB[f.act];&#10;        if (ic) mTxt(ic, f.x, f.y - 86, 24, '#000', 'center');&#10;    }&#10;    function pantalla(t) {&#10;        const S = SCR; ctx.save(); ctx.beginPath(); ctx.rect(S.x, S.y, S.w, S.h); ctx.clip();&#10;        ctx.fillStyle = '#04121f'; ctx.fillRect(S.x, S.y, S.w, S.h);&#10;        if (show === 0) { for (let i = 0; i &lt; 5; i++) { const x = S.x + ((i * 40 - t * 1.5) % 200 + 200) % 200 - 30; ctx.fillStyle = i % 2 ? '#2b6cb0' : '#7cffd9'; ctx.fillRect(x, S.y + 14, 28, S.h - 28); } }&#10;        else if (show === 1) { ctx.fillStyle = '#8b1a1a'; ctx.fillRect(S.x, S.y, 24, S.h); ctx.fillRect(S.x + S.w - 24, S.y, 24, S.h); ctx.fillStyle = 'rgba(255,240,150,0.4)'; ctx.beginPath(); ctx.ellipse(S.x + S.w \/ 2, S.y + S.h - 10, 50, 14, 0, 0, Math.PI * 2); ctx.fill(); }&#10;        else { for (let i = 0; i &lt; 12; i++) { const h = 8 + Math.abs(Math.sin(t \/ 9 + i)) * (S.h - 36); ctx.fillStyle = `hsl(${180 + i * 12},90%,60%)`; ctx.fillRect(S.x + 10 + i * 13, S.y + S.h - 6 - h, 9, h); } }&#10;        ctx.fillStyle = 'rgba(124,255,217,0.08)'; for (let y = S.y; y &lt; S.y + S.h; y += 4) ctx.fillRect(S.x, y, S.w, 1);&#10;        ctx.restore();&#10;        ctx.save(); ctx.shadowColor = '#7cffd9'; ctx.shadowBlur = 10; ctx.strokeStyle = '#7cffd9'; ctx.lineWidth = 2; ctx.strokeRect(S.x, S.y, S.w, S.h); ctx.restore();&#10;        ctx.fillStyle = 'rgba(124,255,217,0.25)'; ctx.beginPath(); ctx.moveTo(S.x + 50, S.y + S.h + 14); ctx.lineTo(S.x + S.w - 50, S.y + S.h + 14); ctx.lineTo(S.x + S.w - 10, S.y + S.h); ctx.lineTo(S.x + 10, S.y + S.h); ctx.closePath(); ctx.fill();   \/\/ proyector&#10;        ctx.fillStyle = '#37474f'; ctx.fillRect(S.x + 50, S.y + S.h + 14, S.w - 100, 6);&#10;        mTxt(ICO[show], S.x + S.w \/ 2, S.y + S.h \/ 2 + Math.sin(t \/ 12) * 3, 30, '#000', 'center');&#10;    }&#10;    function tableroDibujo() {&#10;        ctx.fillStyle = '#6d4c41'; ctx.beginPath(); ctx.roundRect(BX - 8, BY - 8, 8 * C + 16, 8 * C + 16, 6); ctx.fill();&#10;        for (let i = 0; i &lt; 8; i++) for (let j = 0; j &lt; 8; j++) { ctx.fillStyle = (i + j) % 2 ? '#8d6e63' : '#f0d9b5'; ctx.fillRect(BX + i * C, BY + j * C, C, C); }&#10;        ctx.font = 'bold 10px Arial'; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; ctx.lineWidth = 1.2;&#10;        Object.keys(ajd.b).forEach(s =&gt; { const p = ajd.b[s], w = p === p.toUpperCase(), x = BX + (s.charCodeAt(0) - 97) * C + C \/ 2, y = BY + (8 - +s[1]) * C + C \/ 2 + 1;&#10;            ctx.strokeStyle = w ? '#000' : '#fff'; ctx.fillStyle = w ? '#fff' : '#111'; ctx.strokeText(GL[p.toLowerCase()], x, y); ctx.fillText(GL[p.toLowerCase()], x, y); });&#10;    }&#10;    function dibujar(t) {&#10;        const now = performance.now();&#10;        if (++showT &gt; 600) { show = (show + 1) % 3; showT = 0; }&#10;        ctx.fillStyle = '#05060f'; ctx.fillRect(0, 0, W, H);&#10;        mTxt('CHICACHICA 2100 \/\/ MIIG26 STADIUM ARENA &amp; DISTRITO CULTURAL', W \/ 2, 11, 14, '#ff6b5b', 'center');&#10;        const A = F.find(f =&gt; !f.gen &amp;&amp; f.act === 'ajedrez' &amp;&amp; f.slot === 0 &amp;&amp; f.llego), B = F.find(f =&gt; !f.gen &amp;&amp; f.act === 'ajedrez' &amp;&amp; f.slot === 1 &amp;&amp; f.llego);&#10;        if (A &amp;&amp; B) { ajd.t++; if (ajd.n &gt;= PART.length) { if (ajd.t &gt; 360) { ajd = { b: tablero(), n: 0, t: 0 }; } } else if (ajd.t &gt; 110) { jugar(PART[ajd.n++]); ajd.t = 0; } }&#10;        const hov = grab ? zonaDe(grab.x, grab.y) : foco &gt; 0 &amp;&amp; foco-- % 40 &lt; 28 ? 'pista' : null;   \/\/ al llegar, el estadio parpadea un momento&#10;        [['pista', 'rgba(211,47,47,0.10)', '#d32f2f'], ['teatro', 'rgba(74,123,216,0.12)', '#4a7bd8'], ['ajedrez', 'rgba(161,75,214,0.12)', '#a14bd6'], ['sastre', 'rgba(76,175,120,0.12)', '#4caf78']].forEach(([k, fl, st]) =&gt; mCaja(Z[k].x, Z[k].y, Z[k].w, Z[k].h, 14, fl, hov === k ? '#fff' : st, hov === k ? 5 : 3));&#10;        cicloEstadio(); estadio(t);&#10;        const T = (k, a, b, c) =&gt; { mTxt(a, Z[k].x + 234, Z[k].y + 18, 20, c, 'center'); mTxt(b, Z[k].x + 234, Z[k].y + 40, 14, '#4caf78', 'center'); };&#10;        const en = (k, fn) =&gt; { const z = ZT[k]; ctx.save(); ctx.translate(z.ox, z.oy); ctx.scale(z.k, z.k); ctx.translate(-z.x0, -z.y0); fn(); ctx.restore(); };&#10;        en('teatro', () =&gt; { pantalla(t); SLO.teatro.forEach(s =&gt; silla(s[0], s[1], s[2], '#4a7bd8')); });&#10;        en('ajedrez', () =&gt; { SLO.ajedrez.forEach(s =&gt; silla(s[0], s[1], s[2], '#a14bd6')); tableroDibujo(); });&#10;        ciclo(); en('sastre', () =&gt; sastreria(t));&#10;        F.forEach(f =&gt; { paso(f, t); if (!f.gen &amp;&amp; f.llego &amp;&amp; f !== grab) Memoria.sumar(f.id, CATARENA[f.act], 1 \/ 60); }); [...F].sort((a, b) =&gt; a.y - b.y).forEach(f =&gt; figura(f, t, now));&#10;        T('pista', 'Estadio MIIG26 ARENA', ms.tr &gt; 0 ? '\ud83d\udd04 Cambiando el suelo retr\u00e1ctil\u2026' : ms.i === 2 ? MOD[2] + ' \u00b7 ' + Math.ceil((DUR[2] - ms.t) \/ 60) + ' s \u00b7 \u26a1 ' + energia.toFixed(2) + ' kWh' : MOD[ms.i], '#ff6b5b');&#10;        T('teatro', 'Teatro Hologr\u00e1fico', SHOW[show] + ' \u00b7 toca la pantalla', '#4a7bd8');&#10;        T('ajedrez', 'Mesa de Ajedrez', A &amp;&amp; B ? (ajd.n &gt;= PART.length ? '\u265a Jaque mate \u00b7 Morphy 1858' : 'Partida de la \u00d3pera \u00b7 jugada ' + ajd.n + '\/' + PART.length) : 'Esperando rival\u2026', '#a14bd6');&#10;        T('sastre', 'Boutique de Moda MIIG26', (ropa.ph === 0 ? '\u2728 Dise\u00f1ando ' : '\ud83d\udc83 Desfilando ') + EST[ropa.e] + ' \u00b7 toca la pasarela', '#d4af37');&#10;    }&#10;    return {&#10;        entrar() { grab = null; foco = 160; ms = { i: 0, t: 0, tr: 0 }; F.forEach(f =&gt; { f.act = null; f.slot = null; }); ['grada', 'teatro', 'ajedrez', 'ajedrez', 'sastre'].forEach((k, i) =&gt; { asignar(F[i], k, true); F[i].dur = 500 + i * 260; }); asignar(F[5], 'sastre', true); asignar(F[6], 'sastre', true); ['grada', 'grada', 'teatro'].forEach((k, i) =&gt; { asignar(F[7 + i], k, true); F[7 + i].dur = 700 + i * 300; }); ajd = { b: tablero(), n: 0, t: 0 }; },&#10;        dibujar,&#10;        toque(x, y, e) {   \/\/ la jugadora arrastra a cualquier chica con el dedo; las genoides no se mueven de su puesto&#10;            let m = null, md = (e &amp;&amp; e.pointerType === 'touch') ? 78 : 58; F.forEach(f =&gt; { if (f.gen) return; const d = Math.hypot(f.x - x, f.y - 40 - y); if (d &lt; md) { m = f; md = d; } });&#10;            if (m) { grab = m; off = { x: m.x - x, y: m.y - y }; m.act = null; m.slot = null; m.llego = false; canvas.setPointerCapture(e.pointerId); return; }&#10;            if (ms.i === 1 &amp;&amp; dentroRect(x, y, { x: 54, y: 112, w: 376, h: 120 })) { boost = 150; return; }   \/\/ eSports: el circuito responde al toque&#10;            if (dentroRect(x, y, rm('teatro', SCR))) { show = (show + 1) % 3; showT = 0; return; }&#10;            if (dentroRect(x, y, rm('sastre', TAR))) elegir();&#10;        },&#10;        mover(x, y) { if (grab) { grab.x = Math.max(24, Math.min(936, x + off.x)); grab.y = Math.max(70, Math.min(520, y + off.y)); } },&#10;        soltar() {   \/\/ al soltarla, la chica se queda en la actividad de la zona m\u00e1s cercana&#10;            if (!grab) return; const g = grab; grab = null; const d = k =&gt; Math.hypot(g.x - Z[k].x - Z[k].w \/ 2, g.y - Z[k].y - Z[k].h \/ 2);&#10;            Object.keys(Z).sort((a, b) =&gt; d(a) - d(b)).some(k =&gt; k === 'pista' ? (ms.i === 2 &amp;&amp; ms.tr === 0 &amp;&amp; asignar(g, 'corre', false)) || asignar(g, 'grada', false) : asignar(g, k, false)); g.dur = g.act === 'corre' ? 1e9 : 2400;&#10;        }&#10;    };&#10;})();&#10;canvas.addEventListener('pointermove', e =&gt; { if (enArena) { const p = coordenadasClic(e); Arena.mover(p.x, p.y); } });&#10;['pointerup', 'pointercancel'].forEach(n =&gt; canvas.addEventListener(n, () =&gt; { if (enArena) Arena.soltar(); }));&#10;let enHospital = false;&#10;const Hospital = (() =&gt; {&#10;    const W = canvas.width, H = canvas.height;&#10;    const Zs = { diag: { x: 8, y: 24, w: 468, h: 250 }, capsula: { x: 484, y: 24, w: 468, h: 250 }, lab: { x: 8, y: 282, w: 468, h: 250 }, recu: { x: 484, y: 282, w: 468, h: 250 } };&#10;    const ZK = ['diag', 'capsula', 'lab', 'recu'];&#10;    const sl = (k, x, y, d) =&gt; [Zs[k].x + x, Zs[k].y + y, d];&#10;    const SL = { diag: [sl('diag', 140, 226, 1)], capsula: [sl('capsula', 95, 226, 1)], recu: [sl('recu', 120, 226, 1), sl('recu', 340, 226, -1)] };&#10;    const SLG = { diag: [sl('diag', 410, 226, -1)], lab: [sl('lab', 132, 226, 1)] };            \/\/ las genoides son personal fijo 24\/7&#10;    const DUR = { diag: 480, capsula: 1100, recu: 700 };&#10;    const DEB = [{ n: 'la espalda', why: 'mucho tiempo sentada', t: 0 }, { n: 'los hombros', why: 'surfear sin parar', t: 0 }, { n: 'las rodillas', why: 'muchas horas de pie', t: 0 }, { n: 'la piel', why: 'demasiado sol', t: 1 }, { n: 'el metabolismo', why: 'comidas a deshoras', t: 1 }, { n: 'las defensas', why: '\u00e9poca de virus', t: 2 }, { n: 'los pulmones', why: 'poco aire limpio', t: 2 }, { n: 'la mente', why: 'mucho estr\u00e9s', t: 3 }, { n: 'el sue\u00f1o', why: 'noches muy cortas', t: 3 }];&#10;    const ch = (id, fase) =&gt; ({ x: 0, y: 0, id, pelo: habitantes[id].colorPelo, estilo: habitantes[id].estilo, fase, dir: 1, espera: 1, act: null, slot: null, llego: false, dur: 0, sana: false, prog: 0, debil: null });&#10;    const ge = (estilo, fase) =&gt; ({ gen: true, x: 0, y: 0, fase, estilo, dir: 1, tarea: 'busca', t: 0, trab: false, ic: '', espera: 1, arm: 'A', llevando: null, obj: null, act: null, slot: null, llego: false });&#10;    const F = [ch(0, 0), ch(1, 1), ch(2, 2), ch(3, 3), ch(4, 6), ch(5, 7), ch(6, 8), ch(7, 9), ge('pincho', 4), ge('largo', 5)];&#10;    let grab = null, off = { x: 0, y: 0 };&#10;    const dc = (g, k) =&gt; Math.hypot(g.x - Zs[k].x - Zs[k].w \/ 2, g.y - Zs[k].y - Zs[k].h \/ 2);&#10;    function asignar(f, act) {&#10;        const a = (f.gen ? SLG : SL)[act]; if (!a) return false;&#10;        const i = a.findIndex((s, k) =&gt; !F.some(o =&gt; o !== f &amp;&amp; o.gen === f.gen &amp;&amp; o.act === act &amp;&amp; o.slot === k)); if (i &lt; 0) return false;&#10;        f.act = act; f.slot = i; f.llego = false; f.dur = DUR[act] || 0;&#10;        if (!f.gen &amp;&amp; (act === 'diag' || (act === 'capsula' &amp;&amp; !f.debil))) { f.debil = Memoria.diagnostico(f.id); f.sana = false; }&#10;        return true;&#10;    }&#10;    function pasear(f, x, y) { const z = Zs[ZK[Math.floor(Math.random() * 4)]]; f.act = 'pasear'; f.slot = 0; f.llego = false; f.pt = [x === undefined ? z.x + 40 + Math.random() * (z.w - 80) : x, y === undefined ? z.y + 170 + Math.random() * 60 : y, Math.random() &lt; .5 ? 1 : -1]; f.dur = 2700; }&#10;    function siguiente(f) {   \/\/ circuito amable: diagn\u00f3stico \u2192 c\u00e1psula \u2192 recuperaci\u00f3n \u2192 paseo libre&#10;        if (f.act === 'diag') { if (!asignar(f, 'capsula')) pasear(f); }&#10;        else if (f.act === 'capsula') { f.sana = true; if (f.debil) Memoria.sanar(f.id, f.debil.cats); if (!asignar(f, 'recu')) pasear(f); }&#10;        else if (f.act === 'recu') pasear(f);&#10;        else if (!(Math.random() &lt; .6 &amp;&amp; asignar(f, 'diag'))) pasear(f);&#10;    }&#10;    function paso(f) {&#10;        if (f === grab) return; f.espera = 1;&#10;        if (!f.gen) { if (f.llego &amp;&amp; f.dur &gt; 0) f.dur--; if (f.dur &lt;= 0 &amp;&amp; (f.llego || !f.act)) siguiente(f); }&#10;        const s = f.act === 'pasear' ? f.pt : f.act &amp;&amp; (f.gen ? SLG : SL)[f.act][f.slot];&#10;        if (!s) { f.llego = false; return; }&#10;        const dx = s[0] - f.x, dy = s[1] - f.y, d = Math.hypot(dx, dy);&#10;        if (d &gt; 1.6) { f.x += dx \/ d * 1.1; f.y += dy \/ d * 1.1; f.dir = dx &gt; 0 ? 1 : -1; f.espera = 0; f.llego = false; } else { f.x = s[0]; f.y = s[1]; f.dir = s[2]; f.llego = true; }&#10;        f.trab = !!f.gen &amp;&amp; f.llego;&#10;        if (f.act === 'capsula' &amp;&amp; f.llego) f.prog = 1 - f.dur \/ DUR.capsula;&#10;    }&#10;    const cuerpo = (cx, cy, d, sana, t) =&gt; {   \/\/ silueta con el punto d\u00e9bil (naranja) o ya sanado (verde)&#10;        ctx.save(); ctx.strokeStyle = '#2fb5a0'; ctx.lineWidth = 3; ctx.lineCap = 'round'; ctx.fillStyle = 'rgba(47,181,160,0.12)';&#10;        ctx.beginPath(); ctx.arc(cx, cy - 34, 9, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.beginPath(); ctx.roundRect(cx - 13, cy - 23, 26, 32, 8); ctx.fill(); ctx.stroke();&#10;        [[-13, -18, -26, 4], [13, -18, 26, 4], [-6, 9, -8, 42], [6, 9, 8, 42]].forEach(l =&gt; { ctx.beginPath(); ctx.moveTo(cx + l[0], cy + l[1]); ctx.lineTo(cx + l[2], cy + l[3]); ctx.stroke(); });&#10;        const P = { 'la espalda': [[0, -8]], 'los hombros': [[-15, -20], [15, -20]], 'las rodillas': [[-7, 27], [7, 27]], 'los pulmones': [[-6, -12], [6, -12]], 'el coraz\u00f3n': [[3, -12]], 'el metabolismo': [[0, 0]], 'las defensas': [[0, -24], [-8, -8], [8, -8], [0, 4]], 'la mente': [[0, -34], [-5, -37], [5, -37]], 'el sue\u00f1o': [[0, -34], [0, -29]], 'la vista': [[-4, -36], [4, -36]], 'chequeo general': [[0, -12], [0, 0]], 'la piel': [[-13, -14], [13, -14], [-13, 2], [13, 2], [0, -36], [-8, 30], [8, 30]] }[d.n] || [];&#10;        P.forEach(([x, y]) =&gt; { ctx.fillStyle = sana ? '#66bb6a' : '#ff7043'; ctx.globalAlpha = .55 + .35 * Math.sin(t \/ 8); ctx.beginPath(); ctx.arc(cx + x, cy + y, 5 + (sana ? 0 : Math.sin(t \/ 8) * 1.5), 0, Math.PI * 2); ctx.fill(); });&#10;        ctx.restore();&#10;    };&#10;    function microCelulas(cx, cy, R, p, t, act) {   \/\/ vista al microscopio: las c\u00e9lulas madre viajan por el vaso y reparan el tejido da\u00f1ado&#10;        ctx.save(); ctx.beginPath(); ctx.arc(cx, cy, R, 0, Math.PI * 2); ctx.clip(); ctx.fillStyle = '#ffe3e0'; ctx.fillRect(cx - R, cy - R, 2 * R, 2 * R);&#10;        const px = cx + 28, py = cy + 34, s = act ? p : 1;&#10;        ctx.fillStyle = `rgb(${Math.round(150 + 105 * s)},${Math.round(130 + 95 * s)},${Math.round(130 + 100 * s)})`; ctx.beginPath(); ctx.ellipse(px, py, 38, 28, .4, 0, Math.PI * 2); ctx.fill();&#10;        ctx.strokeStyle = `rgba(110,60,50,${1 - s})`; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(px - 22, py - 8); ctx.lineTo(px - 6, py + 2); ctx.lineTo(px + 4, py - 6); ctx.lineTo(px + 20, py + 6); ctx.moveTo(px - 10, py + 14); ctx.lineTo(px + 2, py + 4); ctx.lineTo(px + 14, py + 16); ctx.stroke();&#10;        ctx.lineCap = 'round'; ctx.strokeStyle = '#ef9a9a'; ctx.lineWidth = 26; ctx.beginPath(); ctx.moveTo(cx - R, cy + R * .55); ctx.lineTo(cx + R, cy - R * .55); ctx.stroke(); ctx.strokeStyle = '#ffcdd2'; ctx.lineWidth = 20; ctx.stroke();&#10;        for (let i = 0; i &lt; 10; i++) { const k = (t * .003 + i \/ 10) % 1; ctx.fillStyle = '#c62828'; ctx.beginPath(); ctx.ellipse(cx - R + 2 * R * k, cy + R * .55 - R * 1.1 * k + Math.sin(i * 3 + t \/ 20) * 5, 5, 3.2, -.5, 0, Math.PI * 2); ctx.fill(); }&#10;        const n = act ? 6 + Math.round(8 * p) : 6;&#10;        for (let i = 0; i &lt; n; i++) {&#10;            const k = (t * .0045 + i \/ n) % 1, vx = cx - R + 2 * R * k, vy = cy + R * .55 - R * 1.1 * k, a = i * 2.4 + t \/ 30, g = act ? Math.max(0, Math.min(1, p * 3 + .1 - i \/ n)) : 0, e = g * g * (3 - 2 * g);&#10;            const x = vx + (px + Math.cos(a) * 20 - vx) * e, y = vy + (py + Math.sin(a) * 14 - vy) * e;&#10;            ctx.fillStyle = '#4dd0e1'; ctx.strokeStyle = '#00838f'; ctx.lineWidth = 1.5; ctx.beginPath(); ctx.arc(x, y, 6.5, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#ffd54f'; ctx.beginPath(); ctx.arc(x, y, 2.6, 0, Math.PI * 2); ctx.fill();&#10;        }&#10;        for (let i = 0; i &lt; (act ? 4 : 3); i++) {   \/\/ minichips intravenosos: viajan por el vaso, se acoplan al tejido blando y lo regeneran con hebras nuevas&#10;            const k = (t * .0035 + i \/ 4) % 1, vx = cx - R + 2 * R * k, vy = cy + R * .55 - R * 1.1 * k, a2 = i * 2.1 + t \/ 40, g = act ? Math.max(0, Math.min(1, p * 2.2 + .15 - i \/ 4)) : 0, e = g * g * (3 - 2 * g), x = vx + (px - 8 + Math.cos(a2) * 24 - vx) * e, y = vy + (py + Math.sin(a2) * 17 - vy) * e;&#10;            ctx.save(); ctx.translate(x, y); ctx.rotate(Math.sin(t \/ 25 + i) * .4); ctx.fillStyle = '#263238'; ctx.strokeStyle = '#ffd54f'; ctx.lineWidth = 1.2; ctx.beginPath(); ctx.roundRect(-7, -4.5, 14, 9, 2); ctx.fill(); ctx.stroke();&#10;            ctx.fillStyle = Math.sin(t \/ 6 + i) &gt; 0 ? '#7cffd9' : '#ff4081'; ctx.fillRect(-2, -1.5, 4, 3); ctx.strokeStyle = '#ffd54f'; for (let q = -1; q &lt;= 1; q++) { ctx.beginPath(); ctx.moveTo(q * 4, -4.5); ctx.lineTo(q * 4, -7); ctx.moveTo(q * 4, 4.5); ctx.lineTo(q * 4, 7); ctx.stroke(); } ctx.restore();&#10;            if (e &gt; .6) { ctx.strokeStyle = 'rgba(244,143,177,' + (.5 + .4 * Math.sin(t \/ 8 + i)).toFixed(2) + ')'; ctx.lineWidth = 1.6; ctx.beginPath(); ctx.moveTo(x, y); ctx.quadraticCurveTo(px + Math.cos(a2 + 1) * 14, py + Math.sin(a2 + 1) * 10, px + Math.cos(a2 + 2.4) * 22, py + Math.sin(a2 + 2.4) * 15); ctx.stroke(); }&#10;        }&#10;        ctx.fillStyle = '#f8bbd0'; for (let j = 0; j &lt; 14 * (act ? p : 1); j++) { ctx.beginPath(); ctx.arc(px + Math.cos(j * 2.4) * 24 * ((j % 3 + 1) \/ 3), py + Math.sin(j * 2.4) * 16 * ((j % 3 + 1) \/ 3), 3, 0, Math.PI * 2); ctx.fill(); }&#10;        ctx.restore(); ctx.strokeStyle = '#2fb5a0'; ctx.lineWidth = 5; ctx.beginPath(); ctx.arc(cx, cy, R, 0, Math.PI * 2); ctx.stroke();&#10;    }&#10;    const TER = [{ n: 'c\u00e9lulas madre regenerativas', ic: '\ud83e\uddec', fill: 'rgba(190,240,255,0.55)', stroke: '#4dd0e1' }, { n: 'terapia gen\u00f3mica de ADN', ic: '\ud83e\uddea', fill: 'rgba(200,240,225,0.55)', stroke: '#26a69a' }, { n: 'vacuna antiviral (micro-dosis)', ic: '\ud83d\udc89', fill: 'rgba(255,215,225,0.55)', stroke: '#ec407a' }, { n: 'neuromodulaci\u00f3n', ic: '\ud83e\udde0', fill: 'rgba(215,200,245,0.55)', stroke: '#9575cd' }];&#10;    const capSub = f =&gt; f.prog &lt; .12 ? 'Sincronizando wearables \u00b7 ' + Math.round(f.prog \/ .12 * 100) + '%' : [`Regenerando ${f.debil.n} con c\u00e9lulas madre`, 'Reequilibrando el ADN', 'Aplicando vacuna antiviral', 'Neuromodulaci\u00f3n'][f.debil.t] + ' \u00b7 ' + Math.round(f.prog * 100) + '%';&#10;    function marco(cx, cy, R, fondo, fn) { ctx.save(); ctx.beginPath(); ctx.arc(cx, cy, R, 0, Math.PI * 2); ctx.clip(); ctx.fillStyle = fondo; ctx.fillRect(cx - R, cy - R, 2 * R, 2 * R); fn(); ctx.restore(); ctx.strokeStyle = '#2fb5a0'; ctx.lineWidth = 5; ctx.beginPath(); ctx.arc(cx, cy, R, 0, Math.PI * 2); ctx.stroke(); }&#10;    function microADN(cx, cy, R, p, t, act) {   \/\/ doble h\u00e9lice: los pares desajustados (naranja) se reequilibran (verde)&#10;        const s = act ? p : .4;&#10;        marco(cx, cy, R, '#e8f4ff', () =&gt; {&#10;            const n = 36;&#10;            for (let i = 0; i &lt; n; i++) {&#10;                const y = cy - R * .85 + i \/ (n - 1) * R * 1.7, a = y \/ 11 + t \/ 22, x1 = cx + 34 * Math.sin(a), x2 = cx - 34 * Math.sin(a);&#10;                ctx.globalAlpha = .35 + .65 * Math.abs(Math.cos(a)); ctx.strokeStyle = i \/ n &lt; s * 1.05 ? '#66bb6a' : '#ff7043'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(x1, y); ctx.lineTo(x2, y); ctx.stroke();&#10;                ctx.fillStyle = '#26c6da'; ctx.beginPath(); ctx.arc(x1, y, 3.2, 0, Math.PI * 2); ctx.fill(); ctx.fillStyle = '#f06292'; ctx.beginPath(); ctx.arc(x2, y, 3.2, 0, Math.PI * 2); ctx.fill(); ctx.globalAlpha = 1;&#10;            }&#10;            if (act) { const y = cy - R * .85 + s * R * 1.7, x = cx + 52 + Math.sin(t \/ 8) * 4; ctx.fillStyle = '#4dd0e1'; ctx.strokeStyle = '#00838f'; ctx.lineWidth = 1.5; ctx.beginPath(); ctx.arc(x, y, 7, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.strokeStyle = '#ffd54f'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(x - 7, y); ctx.lineTo(x - 30, y); ctx.stroke(); }&#10;        });&#10;    }&#10;    function microVacuna(cx, cy, R, p, t, act) {   \/\/ una micro-dosis refuerza las defensas: los anticuerpos neutralizan los virus&#10;        const s = act ? p : .3, rr = 16 + 16 * s;&#10;        marco(cx, cy, R, '#fff0f0', () =&gt; {&#10;            ctx.fillStyle = 'rgba(66,165,245,0.25)'; ctx.beginPath(); ctx.arc(cx, cy, rr + 12, 0, Math.PI * 2); ctx.fill(); ctx.fillStyle = '#42a5f5'; ctx.strokeStyle = '#1565c0'; ctx.lineWidth = 2; ctx.beginPath(); ctx.arc(cx, cy, rr, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); mTxt('\ud83d\udee1\ufe0f', cx, cy, 14 + 12 * s, '#000', 'center');&#10;            const nv = Math.max(0, Math.round(9 * (1 - s)));&#10;            for (let i = 0; i &lt; nv; i++) { const a = i * 2.4 + t \/ 60, d = rr + 22 + (1 - s) * 40 + 8 * Math.sin(t \/ 15 + i), x = cx + Math.cos(a) * d, y = cy + Math.sin(a) * d * .85; ctx.strokeStyle = '#6a1b9a'; ctx.lineWidth = 1.5; for (let k = 0; k &lt; 8; k++) { const b = k * Math.PI \/ 4 + t \/ 40; ctx.beginPath(); ctx.moveTo(x + Math.cos(b) * 6, y + Math.sin(b) * 6); ctx.lineTo(x + Math.cos(b) * 10, y + Math.sin(b) * 10); ctx.stroke(); } ctx.fillStyle = '#8e24aa'; ctx.beginPath(); ctx.arc(x, y, 6, 0, Math.PI * 2); ctx.fill(); }&#10;            ctx.strokeStyle = '#e3f2fd'; ctx.lineWidth = 2.4;&#10;            for (let i = 0; i &lt; 8; i++) { const a = i * Math.PI \/ 4 + t \/ 90, x = cx + Math.cos(a) * (rr + 9), y = cy + Math.sin(a) * (rr + 9), x2 = x + Math.cos(a) * 7, y2 = y + Math.sin(a) * 7; ctx.beginPath(); ctx.moveTo(x, y); ctx.lineTo(x2, y2); ctx.lineTo(x2 + Math.cos(a + .6) * 6, y2 + Math.sin(a + .6) * 6); ctx.moveTo(x2, y2); ctx.lineTo(x2 + Math.cos(a - .6) * 6, y2 + Math.sin(a - .6) * 6); ctx.stroke(); }&#10;            ctx.fillStyle = 'rgba(244,67,54,0.6)'; ctx.beginPath(); ctx.arc(cx - R * .55, cy - R * .55 + (t * .6) % 50, 4, 0, Math.PI * 2); ctx.fill(); mTxt('\ud83d\udc89', cx - R * .55, cy - R * .72, 16, '#000', 'center');&#10;        });&#10;    }&#10;    function microNeuro(cx, cy, R, p, t, act) {   \/\/ neuromodulaci\u00f3n no invasiva: la red neuronal se sincroniza y la onda se calma&#10;        const s = act ? p : .3, mix = (a, b) =&gt; Math.round(a + (b - a) * s);&#10;        marco(cx, cy, R, '#10182f', () =&gt; {&#10;            const N = [[-.5, -.4], [0, -.55], [.5, -.35], [-.6, .05], [.05, 0], [.6, .1], [-.4, .5], [.15, .55], [.55, .48]].map(q =&gt; [cx + q[0] * R * .85, cy + q[1] * R * .85]), Lk = [[0, 1], [1, 2], [0, 3], [1, 4], [2, 5], [3, 4], [4, 5], [3, 6], [4, 7], [5, 8], [6, 7], [7, 8]];&#10;            ctx.strokeStyle = 'rgba(120,180,255,0.35)'; ctx.lineWidth = 2; Lk.forEach(l =&gt; { ctx.beginPath(); ctx.moveTo(N[l[0]][0], N[l[0]][1]); ctx.lineTo(N[l[1]][0], N[l[1]][1]); ctx.stroke(); });&#10;            Lk.forEach((l, k) =&gt; { const u = (t * .02 + k * .13 + (1 - s) * Math.sin(k * 9 + t \/ 6) * .5) % 1, uu = u &lt; 0 ? u + 1 : u; ctx.fillStyle = `rgb(${mix(255, 120)},${mix(110, 255)},${mix(110, 200)})`; ctx.beginPath(); ctx.arc(N[l[0]][0] + (N[l[1]][0] - N[l[0]][0]) * uu, N[l[0]][1] + (N[l[1]][1] - N[l[0]][1]) * uu, 3, 0, Math.PI * 2); ctx.fill(); });&#10;            N.forEach(q =&gt; { ctx.fillStyle = `rgb(${mix(239, 102)},${mix(83, 187)},${mix(80, 106)})`; ctx.beginPath(); ctx.arc(q[0], q[1], 6 + 2 * s * Math.sin(t \/ 10), 0, Math.PI * 2); ctx.fill(); });&#10;            ctx.strokeStyle = `rgb(${mix(255, 124)},${mix(120, 255)},${mix(100, 217)})`; ctx.lineWidth = 2; ctx.beginPath();&#10;            for (let x = -R * .8; x &lt;= R * .8; x += 3) { const y = cy + R * .78 + Math.sin(x \/ 6 + t \/ 6) * 6 * s + Math.sin(x * 1.7 + t \/ 2) * 8 * (1 - s); x === -R * .8 ? ctx.moveTo(cx + x, y) : ctx.lineTo(cx + x, y); } ctx.stroke();&#10;        });&#10;    }&#10;    function micro(cx, cy, R, p, t, act, ter) { [microCelulas, microADN, microVacuna, microNeuro][ter || 0](cx, cy, R, p, t, act); }&#10;    function sillon(x, y, d, ocupado) { ctx.save(); ctx.strokeStyle = '#6a4c80'; ctx.lineWidth = 2; ctx.fillStyle = '#ba68c8'; ctx.beginPath(); ctx.roundRect(x - d * 30 - 7, y - 66, 14, 50, 8); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#ce93d8'; ctx.beginPath(); ctx.roundRect(x - 28, y - 28, 56, 18, 9); ctx.fill(); ctx.stroke(); if (ocupado) { ctx.fillStyle = '#ffccbc'; ctx.beginPath(); ctx.roundRect(x - 22, y - 16, 44, 12, 6); ctx.fill(); ctx.stroke(); } ctx.restore(); }&#10;    function figura(f, t, now) {&#10;        const z = f.llego &amp;&amp; !f.gen ? f.act : null, sent = z === 'recu', dentro = z === 'capsula';&#10;        ctx.save(); ctx.translate(0, sent ? 5 : 0);&#10;        if (f.gen) Industria.genoide(f, now);&#10;        else { const bam = f.espera === 0 ? Math.sin(t \/ 6) * .06 * f.dir : Math.sin(t \/ 30 + f.fase) * .02; ctx.translate(f.x, f.y - 28); ctx.scale(1.1, 1.1); dibujarMu\u00f1eca({ x: 0, y: 0, angulo: bam }, f.pelo, false, f.dir &lt; 0, false, f.estilo);&#10;            if (f.llego &amp;&amp; (z === 'capsula' || z === 'recu' || (z === 'diag' &amp;&amp; f.dur &lt; DUR.diag * .9))) {   \/\/ diadema biom\u00e9trica neuronal y anillo\/pulsera inteligente&#10;                ctx.save(); ctx.strokeStyle = '#4dd0e1'; ctx.lineWidth = 2.6; ctx.shadowColor = '#4dd0e1'; ctx.shadowBlur = 6; ctx.beginPath(); ctx.moveTo(-14, -12); ctx.quadraticCurveTo(0, -19, 14, -12); ctx.stroke();&#10;                ctx.fillStyle = '#fff'; [[-9, -14.5], [0, -16.5], [9, -14.5]].forEach(q =&gt; { ctx.beginPath(); ctx.arc(q[0], q[1], 1.8, 0, Math.PI * 2); ctx.fill(); }); ctx.strokeStyle = '#ffd54f'; ctx.shadowColor = '#ffd54f'; ctx.beginPath(); ctx.arc(-17, 10, 3.4, 0, Math.PI * 2); ctx.stroke(); ctx.restore();&#10;            } }&#10;        ctx.restore();&#10;        let ic = z === 'diag' ? '\ud83e\ude7a' : dentro ? TER[f.debil ? f.debil.t : 0].ic : sent ? '\ud83d\ude34' : f.gen &amp;&amp; f.llego ? (f.act === 'lab' ? '\ud83d\udd2c' : '\ud83e\ude7a') : '';&#10;        if (!f.gen &amp;&amp; f.sana &amp;&amp; !ic) ic = '\u2728';&#10;        if (ic) mTxt(ic, f.x, f.y - 86, 24, '#000', 'center');&#10;    }&#10;    function dibujar(t) {&#10;        const now = performance.now(), pd = F.find(f =&gt; !f.gen &amp;&amp; f.act === 'diag' &amp;&amp; f.llego), pc = F.find(f =&gt; !f.gen &amp;&amp; f.act === 'capsula' &amp;&amp; f.llego), nr = F.filter(f =&gt; !f.gen &amp;&amp; f.act === 'recu' &amp;&amp; f.llego).length;&#10;        ctx.fillStyle = '#eaf7f3'; ctx.fillRect(0, 0, W, H);&#10;        const terCap = pc ? pc.debil.t : Math.floor(t \/ 300) % 4, labTer = pc ? pc.debil.t : pd ? pd.debil.t : Math.floor(t \/ 420) % 4, dp = pd ? 1 - pd.dur \/ DUR.diag : 0;&#10;        mTxt('HOSPITAL OSASU \u00b7 MEDICINA DEL FUTURO', W \/ 2, 11, 14, '#2f8f80', 'center', true);&#10;        [['diag', '#2fb5a0'], ['capsula', '#4dd0e1'], ['lab', '#f9a825'], ['recu', '#ba68c8']].forEach(([k, c]) =&gt; mCaja(Zs[k].x, Zs[k].y, Zs[k].w, Zs[k].h, 14, 'rgba(255,255,255,0.78)', grab &amp;&amp; ZK.reduce((a, b) =&gt; dc(grab, a) &lt; dc(grab, b) ? a : b) === k ? '#27474e' : c, 3));&#10;        const en = (k, fn) =&gt; { ctx.save(); ctx.translate(Zs[k].x, Zs[k].y); ctx.fillStyle = 'rgba(180,225,210,0.45)'; ctx.fillRect(0, 205, 468, 45); fn(); ctx.restore(); };&#10;        en('diag', () =&gt; {   \/\/ recepci\u00f3n y diagn\u00f3stico: diadema biom\u00e9trica neuronal y pulsera inteligente, sin prisas&#10;            ctx.fillStyle = '#fff'; ctx.strokeStyle = '#2fb5a0'; ctx.lineWidth = 3; [86, 178].forEach(x =&gt; { ctx.beginPath(); ctx.roundRect(x, 70, 16, 140, 6); ctx.fill(); ctx.stroke(); });&#10;            ctx.lineWidth = 6; ctx.beginPath(); ctx.ellipse(140, 80, 54, 18, 0, Math.PI, Math.PI * 2); ctx.stroke();&#10;            if (pd) { const y = 82 + (t * 1.2) % 120; ctx.fillStyle = 'rgba(77,208,225,0.45)'; ctx.fillRect(104, y, 72, 7); }&#10;            ctx.fillStyle = '#cfd8dc'; ctx.strokeStyle = '#78909c'; ctx.lineWidth = 2; ctx.beginPath(); ctx.roundRect(8, 196, 70, 10, 4); ctx.fill(); ctx.stroke();   \/\/ mesita con los wearables&#10;            ctx.lineWidth = 3; ctx.strokeStyle = '#4dd0e1'; ctx.beginPath(); ctx.arc(26, 196, 11, Math.PI * 1.1, Math.PI * 1.9); ctx.stroke(); ctx.strokeStyle = '#ffd54f'; ctx.beginPath(); ctx.arc(52, 190, 5, 0, Math.PI * 2); ctx.stroke(); ctx.strokeStyle = '#e1bee7'; ctx.beginPath(); ctx.arc(66, 191, 4, 0, Math.PI * 2); ctx.stroke();&#10;            mTxt('wearables', 43, 220, 10.5, '#4a6f68', 'center');&#10;            ctx.fillStyle = '#fdfefe'; ctx.strokeStyle = '#2fb5a0'; ctx.lineWidth = 3; ctx.beginPath(); ctx.roundRect(236, 62, 190, 140, 10); ctx.fill(); ctx.stroke();&#10;            mTxt('cuerpo \u00b7 mente \u00b7 constantes', 331, 73, 9.5, '#6b8f87', 'center');&#10;            if (pd) {&#10;                ctx.save(); ctx.translate(276, 128); ctx.scale(1.1, 1.1); cuerpo(0, 0, pd.debil, pd.sana, t); ctx.restore(); mTxt(pd.debil.n, 276, 192, 12, '#27474e', 'center', true);&#10;                [['\u2764\ufe0f Pulso', (70 + 6 * Math.sin(t \/ 30)).toFixed(0) + ' lpm'], ['\ud83e\udde0 Calma', (78 + 8 * Math.sin(t \/ 55)).toFixed(0) + ' %'], ['\ud83e\udec1 Respira', (14 + 2 * Math.sin(t \/ 40)).toFixed(0) + ' rpm'], ['\ud83c\udf21\ufe0f Temp.', (36.5 + .2 * Math.sin(t \/ 70)).toFixed(1) + ' \u00b0C']].forEach((r, i) =&gt; { mTxt(r[0], 336, 88 + i * 29, 10, '#6b8f87', 'left'); mTxt(r[1], 336, 102 + i * 29, 12.5, '#27474e', 'left', true); });&#10;            } else mTxt('Lista para recibir', 331, 135, 14, '#6b8f87', 'center');&#10;        });&#10;        en('capsula', () =&gt; {   \/\/ c\u00e1psula y viaje al interior: la terapia cambia seg\u00fan la paciente&#10;            const tr = TER[terCap];&#10;            ctx.fillStyle = tr.fill; ctx.strokeStyle = tr.stroke; ctx.lineWidth = 4; ctx.beginPath(); ctx.roundRect(52, 64, 86, 170, 28); ctx.fill(); ctx.stroke();&#10;            ctx.fillStyle = '#b0bec5'; ctx.beginPath(); ctx.ellipse(95, 236, 54, 9, 0, 0, Math.PI * 2); ctx.fill();&#10;            ctx.strokeStyle = tr.stroke; ctx.lineWidth = 3; ctx.setLineDash([8, 8]); ctx.beginPath(); ctx.moveTo(142, 140); ctx.lineTo(238, 140); ctx.stroke(); ctx.setLineDash([]);&#10;            micro(334, 138, 84, pc ? pc.prog : 0, t, !!pc, terCap);&#10;            TER.forEach((x, i) =&gt; { const on = i === terCap; mTxt(x.ic, 268 + i * 44, 238, on ? 20 : 13, '#000', 'center'); if (on) { ctx.strokeStyle = x.stroke; ctx.lineWidth = 2.5; ctx.beginPath(); ctx.arc(268 + i * 44, 238, 14, 0, Math.PI * 2); ctx.stroke(); } });&#10;        });&#10;        en('lab', () =&gt; {   \/\/ laboratorio: prepara la terapia de la paciente en curso&#10;            ctx.fillStyle = '#cfd8dc'; ctx.strokeStyle = '#78909c'; ctx.lineWidth = 2; ctx.beginPath(); ctx.roundRect(110, 190, 340, 18, 5); ctx.fill(); ctx.stroke();&#10;            [165, 250, 335].forEach((x, i) =&gt; {&#10;                ctx.fillStyle = 'rgba(180,235,255,0.5)'; ctx.strokeStyle = TER[labTer].stroke; ctx.lineWidth = 3; ctx.beginPath(); ctx.roundRect(x - 27, 72, 54, 118, 14); ctx.fill(); ctx.stroke();&#10;                ctx.fillStyle = ['rgba(255,224,130,0.5)', 'rgba(128,222,234,0.45)', 'rgba(248,187,208,0.55)', 'rgba(149,117,205,0.45)'][labTer]; ctx.fillRect(x - 24, 100, 48, 88);&#10;                if (labTer === 0) { for (let j = 0; j &lt; 7; j++) { ctx.fillStyle = '#ffd54f'; ctx.strokeStyle = '#f9a825'; ctx.lineWidth = 1.5; ctx.beginPath(); ctx.arc(x + Math.sin(j * 2.3 + t \/ 40) * 13, 186 - (t * .5 + j * 17 + i * 30) % 84, 4, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); } }&#10;                else if (labTer === 1) { for (let y = 104; y &lt; 186; y += 6) { const a = y \/ 9 + t \/ 25 + i; ctx.strokeStyle = y % 12 &lt; 6 ? '#00897b' : '#f06292'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(x + Math.sin(a) * 16, y); ctx.lineTo(x - Math.sin(a) * 16, y); ctx.stroke(); } }&#10;                else if (labTer === 2) { for (let j = 0; j &lt; 8; j++) { ctx.fillStyle = j % 2 ? '#e53935' : '#fff'; ctx.beginPath(); ctx.arc(x + Math.sin(j * 2.1 + t \/ 30) * 14, 186 - (t * .6 + j * 11 + i * 20) % 82, 3.2, 0, Math.PI * 2); ctx.fill(); } }&#10;                else { ctx.strokeStyle = '#d1c4e9'; ctx.lineWidth = 2; ctx.beginPath(); for (let k = -22; k &lt;= 22; k += 2) { const yy = 144 + Math.sin(k \/ 5 + t \/ 8 + i) * 18 * (.5 + .5 * Math.sin(t \/ 30 + i)); k === -22 ? ctx.moveTo(x + k, yy) : ctx.lineTo(x + k, yy); } ctx.stroke(); }&#10;                ctx.fillStyle = '#90a4ae'; ctx.fillRect(x - 30, 66, 60, 8);&#10;            });&#10;            ctx.fillStyle = '#eceff1'; ctx.strokeStyle = '#78909c'; ctx.lineWidth = 2; ctx.beginPath(); ctx.roundRect(398, 150, 30, 40, 5); ctx.fill(); ctx.stroke(); ctx.fillRect(404, 134, 8, 20); mTxt(TER[labTer].ic, 413, 168, 22, '#000', 'center');&#10;            ctx.fillStyle = '#cfd8dc'; ctx.strokeStyle = '#607d8b'; ctx.lineWidth = 3; ctx.beginPath(); ctx.roundRect(14, 74, 82, 118, 12); ctx.fill(); ctx.stroke();   \/\/ criobanco: \u00f3vulos y cord\u00f3n umbilical&#10;            ctx.fillStyle = '#90a4ae'; ctx.beginPath(); ctx.ellipse(55, 74, 41, 9, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;            ctx.fillStyle = 'rgba(210,240,255,0.92)'; ctx.strokeStyle = '#4dd0e1'; ctx.lineWidth = 2; ctx.beginPath(); ctx.roundRect(24, 96, 62, 70, 8); ctx.fill(); ctx.stroke();&#10;            for (let i = 0; i &lt; 12; i++) { ctx.fillStyle = '#f8bbd0'; ctx.strokeStyle = '#ec407a'; ctx.lineWidth = 1; ctx.beginPath(); ctx.arc(32 + (i % 4) * 14, 106 + Math.floor(i \/ 4) * 10, 3.6, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); }&#10;            for (let i = 0; i &lt; 3; i++) { ctx.fillStyle = '#e57373'; ctx.strokeStyle = '#b71c1c'; ctx.beginPath(); ctx.roundRect(30 + i * 20, 138, 13, 22, 4); ctx.fill(); ctx.stroke(); ctx.beginPath(); ctx.moveTo(36 + i * 20, 138); ctx.lineTo(36 + i * 20, 131); ctx.stroke(); }&#10;            for (let i = 0; i &lt; 4; i++) { const k = ((t * .6 + i * 22) % 70) \/ 70; ctx.fillStyle = 'rgba(220,245,255,' + (.5 * (1 - k)).toFixed(2) + ')'; ctx.beginPath(); ctx.arc(30 + i * 16 + Math.sin(t \/ 20 + i) * 4, 68 - k * 34, 6 + k * 6, 0, Math.PI * 2); ctx.fill(); }&#10;            mTxt('-196 \u00b0C', 55, 180, 10, '#006064', 'center', true); mTxt('Criobanco', 55, 55, 11, '#006064', 'center', true); mTxt('\u00d3vulos y cord\u00f3n umbilical', 55, 200, 8.5, '#455a64', 'center');&#10;        });&#10;        en('recu', () =&gt; {   \/\/ sala de recuperaci\u00f3n&#10;            ctx.fillStyle = Dia.k() &gt; .5 ? '#1d2a5a' : '#bde3ff'; ctx.strokeStyle = '#90caf9'; ctx.lineWidth = 3; ctx.beginPath(); ctx.roundRect(172, 48, 130, 76, 10); ctx.fill(); ctx.stroke(); ctx.fillStyle = Dia.k() &gt; .5 ? '#f5f0d0' : '#ffe082'; ctx.beginPath(); ctx.arc(268, 76, 14 + Math.sin(t \/ 40) * 1.5, 0, Math.PI * 2); ctx.fill();&#10;            ctx.strokeStyle = '#90caf9'; ctx.beginPath(); ctx.moveTo(237, 48); ctx.lineTo(237, 124); ctx.moveTo(172, 86); ctx.lineTo(302, 86); ctx.stroke();&#10;            ctx.fillStyle = '#a1887f'; ctx.beginPath(); ctx.roundRect(396, 170, 34, 34, 6); ctx.fill(); ctx.fillStyle = '#66bb6a'; [[-14, -10, -.6], [0, -22, 0], [14, -10, .6]].forEach(([x, y, r]) =&gt; { ctx.beginPath(); ctx.ellipse(413 + x, 164 + y, 8, 18, r, 0, Math.PI * 2); ctx.fill(); });&#10;            SL.recu.forEach((s, i) =&gt; sillon(s[0] - Zs.recu.x, s[1] - Zs.recu.y, s[2], F.some(f =&gt; !f.gen &amp;&amp; f.act === 'recu' &amp;&amp; f.slot === i &amp;&amp; f.llego)));&#10;        });&#10;        const T = (k, a, b, c) =&gt; { mTxt(a, Zs[k].x + 234, Zs[k].y + 18, 20, c, 'center', true); mTxt(b, Zs[k].x + 234, Zs[k].y + 40, 14, '#4a6f68', 'center'); };&#10;        F.forEach(f =&gt; { paso(f); if (!f.gen &amp;&amp; f.llego &amp;&amp; f.act === 'recu' &amp;&amp; f !== grab) Memoria.sumar(f.id, 'descanso', 1 \/ 60); }); [...F].sort((a, b) =&gt; a.y - b.y).forEach(f =&gt; figura(f, t, now));&#10;        mCaja(Zs.diag.x + 424, Zs.diag.y + 6, 36, 28, 9, 'rgba(255,255,255,0.92)', '#2fb5a0', 2); mTxt('\ud83d\udccb', Zs.diag.x + 442, Zs.diag.y + 21, 16, '#000', 'center');   \/\/ fichas privadas de las chicas&#10;        T('diag', 'Recepci\u00f3n y diagn\u00f3stico', pd ? (dp &lt; .1 ? '\ud83e\udde0 Colocando diadema neuronal y pulsera inteligente' : dp &lt; .9 ? 'Sincronizando wearables \u00b7 ' + Math.round((dp - .1) \/ .8 * 100) + '%' : 'Diagn\u00f3stico para ' + Memoria.nombre(pd.id) + ' \u00b7 ' + pd.debil.why) : 'Diadema neuronal y pulsera inteligente, sin prisas', '#2f8f80');&#10;        T('capsula', 'C\u00e1psula de terapias', pc ? capSub(pc) : 'C\u00e1psula libre', '#1e9db0');&#10;        T('lab', 'Laboratorio de terapias', 'Preparando ' + TER[labTer].n, '#c77c00');&#10;        T('recu', 'Sala de recuperaci\u00f3n', nr ? nr + (nr &gt; 1 ? ' descansando' : ' descansando') + ' \u00b7 ya como nuevas \u2728' : 'Un sitio tranquilo para descansar', '#8e4fa8');&#10;    }&#10;    return {&#10;        entrar() { grab = null; F.forEach(f =&gt; { f.act = null; f.slot = null; f.llego = false; });&#10;            [['diag', 0], ['capsula', 1], ['recu', 2]].forEach(([k, i]) =&gt; { const f = F[i]; asignar(f, k); const s = SL[k][f.slot]; f.x = s[0]; f.y = s[1]; f.dir = s[2]; f.llego = true; if (k === 'capsula') f.dur = DUR.capsula * .45; if (k === 'recu') f.sana = true; });&#10;            [3, 4, 5, 6, 7].forEach(i =&gt; { pasear(F[i]); F[i].x = F[i].pt[0]; F[i].y = F[i].pt[1]; });&#10;            [8, 9].forEach((i, n) =&gt; { asignar(F[i], n ? 'lab' : 'diag'); const s = SLG[F[i].act][0]; F[i].x = s[0]; F[i].y = s[1]; F[i].dir = s[2]; F[i].llego = true; }); },&#10;        dibujar,&#10;        toque(x, y, e) {   \/\/ la jugadora arrastra a cualquier chica; las genoides siguen en su puesto&#10;            if (x &gt;= Zs.diag.x + 424 &amp;&amp; x &lt;= Zs.diag.x + 460 &amp;&amp; y &gt;= Zs.diag.y + 6 &amp;&amp; y &lt;= Zs.diag.y + 34) { Fichas.abrir(); return; }&#10;            let m = null, md = (e &amp;&amp; e.pointerType === 'touch') ? 78 : 58; F.forEach(f =&gt; { if (f.gen) return; const d = Math.hypot(f.x - x, f.y - 40 - y); if (d &lt; md) { m = f; md = d; } });&#10;            if (m) { grab = m; off = { x: m.x - x, y: m.y - y }; m.act = null; m.slot = null; m.llego = false; canvas.setPointerCapture(e.pointerId); }&#10;        },&#10;        mover(x, y) { if (grab) { grab.x = Math.max(24, Math.min(936, x + off.x)); grab.y = Math.max(70, Math.min(520, y + off.y)); } },&#10;        soltar() { if (!grab) return; const g = grab; grab = null; const k = ZK.reduce((a, b) =&gt; dc(g, a) &lt; dc(g, b) ? a : b); if (k === 'lab' || !asignar(g, k)) pasear(g, g.x, g.y); }&#10;    };&#10;})();&#10;canvas.addEventListener('pointermove', e =&gt; { if (enHospital) { const p = coordenadasClic(e); Hospital.mover(p.x, p.y); } });&#10;['pointerup', 'pointercancel'].forEach(n =&gt; canvas.addEventListener(n, () =&gt; { if (enHospital) Hospital.soltar(); }));&#10;const Industria = (() =&gt; {&#10;    const W = canvas.width, H = canvas.height, ease = p =&gt; p * p * (3 - 2 * p);&#10;    const RES = { arcilla: { e: '\ud83e\uddf1', c: '#c1763f', n: 'Arcilla' }, resina: { e: '\ud83c\udf3f', c: '#7cb342', n: 'Bio-resina' }, proteina: { e: '\ud83e\uded8', c: '#e6b422', n: 'Prote\u00edna' }, energia: { e: '\u2600\ufe0f', c: '#38bdf8', n: 'Energ\u00eda' } };&#10;    const AREAS = { alim: '\ud83c\udf7d\ufe0f', agua: '\ud83d\udca7', viv: '\ud83c\udfe0', mov: '\ud83d\ude83' };&#10;    const DEST = { mercado: { x: 700, e: '\ud83c\udfea', n: 'Mercado de Abastos' }, huerta: { x: 750, e: '\ud83c\udf31', n: 'La Huerta' }, casas: { x: 800, e: '\ud83c\udfe0', n: 'Casas' }, tranvia: { x: 850, e: '\ud83d\ude83', n: 'Tranv\u00eda' }, movilidad: { x: 900, e: '\ud83d\ude81', n: 'Movilidad' } };&#10;    const I = (e, n, dest, area, cost, seg, val, col, d) =&gt; ({ e, n, dest, area, cost, seg, val, col, d });&#10;    const ITEMS = [&#10;        I('\ud83e\udd69', 'Carne vegetal', 'mercado', 'alim', { proteina: 20, energia: 8 }, 6, 5, '#c0522d', 'Prote\u00edna de legumbres locales para el Mercado de Abastos.'),&#10;        I('\ud83c\udffa', 'Tinajas LUR', 'huerta', 'agua', { arcilla: 22, energia: 8 }, 7, 4, '#b5622f', 'Ollas c\u00f3nicas de arcilla microporosa para el riego subterr\u00e1neo.'),&#10;        I('\ud83c\udfe0', 'Componentes de vivienda', 'casas', 'viv', { resina: 24, arcilla: 10, energia: 12 }, 9, 6, '#8a5a34', 'Paneles y m\u00f3dulos para ampliar o reparar las casas.'),&#10;        I('\ud83d\udd27', 'Herramientas comunitarias', 'casas', 'viv', { resina: 14, energia: 6 }, 6, 3, '#6b7280', 'Herramientas compartidas: se prestan, nunca se compran.'),&#10;        I('\ud83d\ude83', 'Vag\u00f3n nuevo', 'tranvia', 'mov', { resina: 30, arcilla: 12, energia: 20 }, 10, 8, '#ff69b4', 'Vag\u00f3n modular para el tranv\u00eda del pueblo.'),&#10;        I('\ud83d\udede', 'Ruedas y tramos de ra\u00edl', 'tranvia', 'mov', { resina: 18, energia: 10 }, 7, 4, '#4a4f57', 'Ruedas de repuesto y tramos de ra\u00edl para ampliar la l\u00ednea.'),&#10;        I('\ud83d\ude81', 'Coche aut\u00f3nomo volador (renting)', 'movilidad', 'mov', { resina: 30, arcilla: 10, energia: 28 }, 12, 10, '#6a3e8c', 'Movilidad compartida: renting comunitario, sin propietaria.'),&#10;        I('\ud83e\udd6c', 'Envases biodegradables', 'mercado', 'alim', { resina: 16, energia: 6 }, 6, 4, '#3a7d44', 'Biopl\u00e1stico de algas de la costa: envases 100 % compostables para el Mercado.'),&#10;        I('\ud83e\udd54', 'Biopl\u00e1stico de algas y patata', 'casas', 'viv', { resina: 20, proteina: 8, energia: 10 }, 8, 6, '#b08a4a', 'L\u00e1minas de algas y almid\u00f3n de patata para reparar y ampliar las casas.')&#10;    ];&#10;    const entregados = { mercado: 0, huerta: 0, casas: 0, tranvia: 0, movilidad: 0 };&#10;    let job = null, cap = null, sel = 0, panel = false, toast = null, last = performance.now();&#10;    const msg = s =&gt; { toast = { s, hasta: performance.now() + 3200 }; };&#10;    const PN = { x: 130, y: 60, w: 700, h: 420 }, BTN = { x: PN.x + PN.w - 290, y: PN.y + PN.h - 56, w: 270, h: 40 }, CLOSE = { x: PN.x + PN.w - 42, y: PN.y + 8, w: 34, h: 34 };&#10;    const tile = i =&gt; ({ x: PN.x + 20 + (i % 4) * 164, y: PN.y + 52 + Math.floor(i \/ 4) * 70, w: 152, h: 62 });&#10;    function fabricar() {&#10;        const it = ITEMS[sel];&#10;        if (job || cap) { msg('\u23f3 La impresora est\u00e1 ocupada, sin prisa'); return; }&#10;        for (const k in it.cost) if (recursos[k] &lt; it.cost[k]) { msg(`Falta ${RES[k].n.toLowerCase()}: se recupera sola`); return; }&#10;        for (const k in it.cost) recursos[k] -= it.cost[k];&#10;        job = { it, t0: performance.now(), dur: it.seg * 1000 * (1 + 0.3 * Desgaste.nivel('engranajes')) };   \/\/ la impresora desgastada tarda hasta un 30 % m\u00e1s panel = false; msg(`\ud83d\udda8\ufe0f Fabricando ${it.n}\u2026`);&#10;    }&#10;    function actualizar(now) {                                   \/\/ corre siempre: la producci\u00f3n sigue aunque est\u00e9s en otra pantalla&#10;        const dt = Math.min(0.1, (now - last) \/ 1000); last = now;&#10;        for (const k in recursos) recursos[k] = Math.min(100, recursos[k] + dt * (k === 'energia' ? 1.2 : 0.6));   \/\/ econom\u00eda circular&#10;        if (job &amp;&amp; now - job.t0 &gt;= job.dur) { Desgaste.sube('engranajes', 0.06); cap = { it: job.it, t0: now, ok: false }; job = null; msg('\ud83d\udce6 Prototipo listo \u00b7 enviando por Holiloop'); }&#10;        if (cap) {&#10;            const e = now - cap.t0, it = cap.it;&#10;            if (e &gt; 1800 &amp;&amp; !cap.ok) {                           \/\/ llegada: bienestar + fichas MIIG26D + stock compartido&#10;                cap.ok = true; entregados[it.dest]++; if (it.n === 'Vag\u00f3n nuevo') flota.vagones++; else if (it.dest === 'movilidad') flota.coches++; bienestar[it.area] = Math.min(100, bienestar[it.area] + 7);&#10;                saldoMIIG26D += it.val; Kutxa.aportar(it.val * 0.2);&#10;                ventasHoy.unshift({ puesto: 'Zona Industrial', txt: `${it.e} \u2192 ${DEST[it.dest].e}`, tok: it.val });&#10;                if (it.dest === 'mercado') PUESTOS[3].prods[3].s += 4;   \/\/ carne vegetal al puesto de Legumbres&#10;                msg(`\u2714 Entregado en ${DEST[it.dest].n} \u00b7 +${it.val} MIIG26D`);&#10;            }&#10;            if (e &gt; 4000) cap = null;&#10;        }&#10;        if (toast &amp;&amp; now &gt; toast.hasta) toast = null;&#10;    }&#10;    function escena(now) {&#10;        const g = ctx.createLinearGradient(0, 0, 0, 380); g.addColorStop(0, '#eef4ee'); g.addColorStop(1, '#d8e4dc');&#10;        ctx.fillStyle = g; ctx.fillRect(0, 0, W, 380); ctx.fillStyle = '#c9d3cb'; ctx.fillRect(0, 380, W, 160);&#10;        ctx.strokeStyle = 'rgba(60,80,70,0.15)'; ctx.lineWidth = 1;&#10;        for (let y = 380; y &lt; H; y += 27) { ctx.beginPath(); ctx.moveTo(0, y); ctx.lineTo(W, y); ctx.stroke(); }&#10;        for (let x = 0; x &lt; W; x += 60) { ctx.beginPath(); ctx.moveTo(x, 70); ctx.lineTo(x, 380); ctx.stroke(); }&#10;        ctx.fillStyle = '#1e3a5f'; ctx.fillRect(0, 0, W, 64);&#10;        for (let y = 0; y &lt; 64; y += 16) for (let x = (y \/ 16 % 2) * 20; x &lt; W; x += 40) mCaja(x + 2, y + 2, 36, 12, 3, '#26508a', '#6fa8dc', 1);&#10;        ctx.fillStyle = 'rgba(255,255,255,0.12)'; ctx.fillRect(((now \/ 8) % 1200) - 200, 0, 60, 64);&#10;        ctx.fillStyle = '#8a5a34'; ctx.fillRect(0, 64, W, 10); [40, 480, 920].forEach(x =&gt; ctx.fillRect(x - 8, 74, 16, 306));&#10;        ctx.strokeStyle = '#5a3a1c'; ctx.lineWidth = 3; [-1, 1].forEach(s =&gt; { ctx.beginPath(); ctx.moveTo(480 + s * 110, 74); ctx.lineTo(480 + s * 110, 90); ctx.stroke(); });&#10;        mCaja(330, 90, 300, 34, 12, '#7cb342', '#20262e', 2.5); mTxt('\ud83c\udfed ZONA INDUSTRIAL', 480, 108, 17, '#fff', 'center', true);&#10;    }&#10;    function silos(now) {&#10;        ['arcilla', 'resina', 'proteina'].forEach((k, i) =&gt; {&#10;            const x = 60 + i * 72, r = RES[k], h = 200 * recursos[k] \/ 100;&#10;            mCaja(x - 26, 150, 52, 222, 10, '#eef2ef', '#20262e', 2.5);&#10;            ctx.save(); ctx.beginPath(); ctx.roundRect(x - 22, 160, 44, 202, 6); ctx.clip(); ctx.fillStyle = r.c; ctx.fillRect(x - 22, 362 - h, 44, h); ctx.restore();&#10;            mTxt(r.e, x, 138, 20, '#000', 'center'); mTxt(Math.round(recursos[k]) + '%', x, 384, 11, '#333', 'center', true);&#10;            ctx.strokeStyle = r.c; ctx.lineWidth = 3; ctx.setLineDash([8, 6]); ctx.lineDashOffset = job ? -now \/ 40 : 0;&#10;            ctx.beginPath(); ctx.moveTo(x, 372); ctx.lineTo(x, 396 + i * 9); ctx.lineTo(345, 396 + i * 9); ctx.stroke(); ctx.setLineDash([]);&#10;        });&#10;    }&#10;    function impresora(now) {&#10;        const p = job ? Math.min(1, (now - job.t0) \/ job.dur) : 0, oh = p * 84, ow = 46 + (job ? job.it.seg : 6) * 3;&#10;        ctx.fillStyle = '#eef2ef'; ctx.strokeStyle = '#20262e'; ctx.lineWidth = 3;&#10;        [345, 599].forEach(x =&gt; { ctx.fillRect(x, 200, 16, 184); ctx.strokeRect(x, 200, 16, 184); });&#10;        mCaja(345, 190, 270, 22, 8, '#aab2ba', '#20262e'); mCaja(400, 372, 160, 14, 5, '#4a4f57', '#20262e');&#10;        if (job) { ctx.fillStyle = job.it.col; ctx.fillRect(480 - ow \/ 2, 372 - oh, ow, oh); ctx.fillStyle = 'rgba(255,255,255,0.35)'; for (let y = 372; y &gt; 372 - oh; y -= 5) ctx.fillRect(480 - ow \/ 2, y, ow, 1); }&#10;        const nx = 480 + (job ? Math.sin(now \/ 160) * (ow \/ 2 - 4) : 0), ny = 372 - oh - 16;&#10;        ctx.strokeStyle = '#5a6066'; ctx.lineWidth = 4; ctx.beginPath(); ctx.moveTo(360, ny); ctx.lineTo(600, ny); ctx.stroke();&#10;        mCaja(nx - 12, ny - 8, 24, 16, 4, '#f4f6f8', '#20262e'); ctx.fillStyle = '#20262e'; ctx.beginPath(); ctx.moveTo(nx - 4, ny + 8); ctx.lineTo(nx + 4, ny + 8); ctx.lineTo(nx, ny + 16); ctx.fill();&#10;        if (job) mTxt(job.it.e + ' ' + Math.round(p * 100) + '%', 480, 236, 14, '#20262e', 'center', true);&#10;        ctx.fillStyle = job ? (Math.sin(now \/ 120) &gt; 0 ? '#f59e0b' : '#a16207') : '#22c55e'; ctx.beginPath(); ctx.arc(600, 201, 4, 0, 7); ctx.fill();&#10;        mCaja(395, 394, 170, 22, 11, '#fff5e0', '#20262e'); mTxtAjustado(job ? '\ud83d\udda8\ufe0f Fabricando\u2026' : '\ud83d\udda8\ufe0f IMPRESORA 3D \u00b7 toca', 480, 405, 12, '#333', 154);&#10;    }&#10;    function holiloop(now) {&#10;        mCaja(640, 333, 40, 38, 8, '#aab2ba', '#4a4f57'); mTxt('HOLILOOP', 660, 361, 7, '#20262e', 'center', true);&#10;        mCaja(680, 340, 262, 24, 12, 'rgba(190,240,255,0.35)', '#9fd6e8', 2.5);&#10;        Object.values(DEST).forEach(d =&gt; {&#10;            const on = cap &amp;&amp; cap.ok &amp;&amp; DEST[cap.it.dest] === d;&#10;            mCaja(d.x - 18, 368, 36, 34, 8, on ? 'rgba(124,255,217,0.6)' : 'rgba(255,255,255,0.7)', on ? '#2a7a63' : '#9aa4ad', 1.5); mTxt(d.e, d.x, 385, 18, '#000', 'center');&#10;        });&#10;        if (!cap) return;&#10;        const e = now - cap.t0, dx = DEST[cap.it.dest].x, x = e &lt; 1800 ? 660 + (dx - 660) * ease(e \/ 1800) : e &lt; 3000 ? dx : dx - (dx - 660) * ease(Math.min(1, (e - 3000) \/ 1000));&#10;        mCaja(x - 16, 344, 32, 16, 8, '#f4f6f8', '#4a4f57', 1.5); ctx.fillStyle = Math.sin(now \/ 90) &gt; 0 ? '#7cffd9' : '#2a7a63';&#10;        [-8, 0, 8].forEach(o =&gt; { ctx.beginPath(); ctx.arc(x + o, 352, 2, 0, 7); ctx.fill(); });&#10;        if (cap.ok &amp;&amp; e &lt; 3000) mTxt(cap.it.e, x, 326 - (e - 1800) \/ 40, 20, '#000', 'center');&#10;    }&#10;    function mandos(now) {                                        \/\/ flujo de recursos + bienestar comunitario&#10;        const X = 640, Y = 132, w = 290, h = 190, avg = (bienestar.alim + bienestar.agua + bienestar.viv + bienestar.mov) \/ 4, rx = X + 208, ry = Y + 84;&#10;        mCaja(X, Y, w, h, 14, '#fff8ea', '#2a9d78', 3); mTxt('\ud83d\udcca Cuadro de mandos', X + 14, Y + 16, 13, '#1d5a48', 'left', true); mTxt('\ud83e\ude99 ' + saldoMIIG26D + ' MIIG26D', X + w - 12, Y + 16, 12, '#7a5a1a', 'right', true);&#10;        Object.keys(RES).forEach((k, i) =&gt; { const y = Y + 40 + i * 24; mTxt(RES[k].e, X + 14, y, 14, '#000'); mCaja(X + 34, y - 5, 96, 10, 5, 'rgba(0,0,0,0.1)'); mCaja(X + 34, y - 5, Math.max(6, 96 * recursos[k] \/ 100), 10, 5, RES[k].c); });&#10;        ctx.lineWidth = 12; ctx.strokeStyle = 'rgba(0,0,0,0.1)'; ctx.beginPath(); ctx.arc(rx, ry, 38, 0, 7); ctx.stroke();&#10;        ctx.strokeStyle = avg &gt; 66 ? '#22c55e' : avg &gt; 40 ? '#f59e0b' : '#ef4444'; ctx.lineCap = 'round'; ctx.beginPath(); ctx.arc(rx, ry, 38, -Math.PI \/ 2, -Math.PI \/ 2 + Math.PI * 2 * avg \/ 100); ctx.stroke(); ctx.lineCap = 'butt';&#10;        mTxt(Math.round(avg) + '%', rx, ry - 3, 20, '#20262e', 'center', true); mTxt('\ud83d\udc9c', rx, ry + 16, 12, '#000', 'center'); mTxt('Bienestar comunitario', rx, Y + 136, 10, '#1d5a48', 'center', true);&#10;        if (job || cap) { ctx.fillStyle = '#2a9d78'; for (let k = 0; k &lt; 4; k++) { const f = ((now \/ 700) + k \/ 4) % 1; ctx.beginPath(); ctx.arc(X + 136 + (rx - 44 - X - 136) * f, ry + Math.sin(f * 6) * 3, 2.2, 0, 7); ctx.fill(); } }&#10;        Object.keys(AREAS).forEach((k, i) =&gt; { const x = X + 14 + i * 68; mTxt(AREAS[k], x + 6, Y + 162, 14, '#000', 'center'); mCaja(x + 16, Y + 157, 40, 10, 5, 'rgba(0,0,0,0.1)'); mCaja(x + 16, Y + 157, Math.max(5, 40 * bienestar[k] \/ 100), 10, 5, '#22c55e'); });&#10;        mTxt('\ud83c\udf31 cosecha \u2192 \ud83c\udf3f   \u00b7   \ud83c\udfea legumbres \u2192 \ud83e\uded8   \u00b7   \ud83e\udd69 \u2192 \ud83c\udfea', X + w \/ 2, Y + 180, 9, '#7a6a5a', 'center');&#10;        ctx.strokeStyle = '#2a9d78'; ctx.lineWidth = 2; ctx.setLineDash([5, 5]); ctx.lineDashOffset = -now \/ 60; ctx.beginPath(); ctx.moveTo(X + w \/ 2, Y + h); ctx.lineTo(X + w \/ 2, 333); ctx.stroke(); ctx.setLineDash([]);&#10;    }&#10;    function panelImpresora() {                                   \/\/ mismo estilo que el Mercado de Abastos&#10;        ctx.fillStyle = 'rgba(30,20,10,0.45)'; ctx.fillRect(0, 0, W, H); mCaja(PN.x, PN.y, PN.w, PN.h, 18, '#fff8ea', '#2a9d78', 4);&#10;        mCaja(CLOSE.x, CLOSE.y, 34, 34, 17, '#eee', '#999', 1.5); mTxt('\u2715', CLOSE.x + 17, CLOSE.y + 18, 16, '#555', 'center', true);&#10;        mTxt('\ud83d\udda8\ufe0f Impresora 3D \u00b7 \u00bfQu\u00e9 fabricamos?', PN.x + 24, PN.y + 30, 20, '#1d5a48', 'left', true);&#10;        ITEMS.forEach((it, i) =&gt; { const r = tile(i), on = i === sel;&#10;            mCaja(r.x, r.y, r.w, r.h, 12, on ? 'rgba(124,255,217,0.3)' : 'rgba(0,0,0,0.04)', on ? '#2a7a63' : '#d8c9a8', on ? 2.5 : 1.5);&#10;            mTxt(it.e, r.x + r.w \/ 2, r.y + 24, 26, '#000', 'center'); mTxt(it.n, r.x + r.w \/ 2, r.y + 50, 10.5, '#333', 'center', true); });&#10;        const it = ITEMS[sel], dy = PN.y + 262; let cx = PN.x + 74;&#10;        mTxt(it.e + ' ' + it.n, PN.x + 24, dy, 16, '#333', 'left', true); mTxt('\u2139\ufe0f ' + it.d, PN.x + 24, dy + 24, 12, '#5a4a3a'); mTxt('Coste:', PN.x + 24, dy + 52, 12, '#7a5a1a', 'left', true);&#10;        Object.keys(it.cost).forEach(k =&gt; { const ok = recursos[k] &gt;= it.cost[k]; mCaja(cx, dy + 40, 74, 24, 12, ok ? 'rgba(42,157,120,0.15)' : 'rgba(239,68,68,0.18)', ok ? '#2a9d78' : '#ef4444', 1.5); mTxt(`${RES[k].e} ${it.cost[k]}`, cx + 37, dy + 53, 12, '#333', 'center', true); cx += 82; });&#10;        mTxt(`\u23f1\ufe0f ${it.seg} s  \u00b7  ${DEST[it.dest].e} ${DEST[it.dest].n}  \u00b7  ${AREAS[it.area]} bienestar +7  \u00b7  \ud83e\ude99 +${it.val}`, PN.x + 24, dy + 82, 12, '#1d5a48', 'left', true);&#10;        mCaja(BTN.x, BTN.y, BTN.w, BTN.h, 20, job || cap ? '#b8b8b8' : '#2a9d78', '#1d5a48'); mTxt('\ud83d\udda8\ufe0f Fabricar y enviar por Holiloop', BTN.x + BTN.w \/ 2, BTN.y + 21, 13, '#fff', 'center', true);&#10;        mTxt('Sin deudas \u00b7 sin prisa \ud83c\udf3f', PN.x + 24, PN.y + PN.h - 34, 12, '#7a6a5a');&#10;    }&#10;    const MALLA = (() =&gt; {                                        \/\/ textura de malla met\u00e1lica que sustituye al pelo&#10;        const c = document.createElement('canvas'); c.width = c.height = 6; const g = c.getContext('2d');&#10;        g.fillStyle = '#8f99a3'; g.fillRect(0, 0, 6, 6); g.strokeStyle = '#3f4550'; g.lineWidth = 1;&#10;        g.beginPath(); g.moveTo(0, 0); g.lineTo(6, 6); g.moveTo(0, 6); g.lineTo(6, 0); g.stroke();&#10;        g.fillStyle = '#dfe6ec'; g.fillRect(2, 2, 2, 2); return ctx.createPattern(c, 'repeat');&#10;    })();&#10;    const PUESTOS_G = [{ x: 60, y: 462, ic: '\ud83d\udce5' }, { x: 132, y: 462, ic: '\ud83d\udce5' }, { x: 204, y: 462, ic: '\ud83d\udce5' },    \/\/ silos&#10;                       { x: 430, y: 458, ic: '\ud83d\udd27' }, { x: 530, y: 458, ic: '\ud83d\udd27' }, { x: 640, y: 440, ic: '\ud83d\udce6' }];   \/\/ impresora y Holiloop&#10;    const GEN = [{ x: 120, y: 480, estilo: 'largo' }, { x: 320, y: 490, estilo: 'pincho' }, { x: 560, y: 495, estilo: 'mohawk' }, { x: 780, y: 480, estilo: 'largo' }]&#10;        .map((g, i) =&gt; ({ ...g, tx: g.x, ty: g.y, dir: 1, espera: 30 + i * 50, ic: null, fase: i * 2, v: 0.55 + 0.07 * i, trab: false }));&#10;    function actualizarGen() {&#10;        GEN.forEach((g, i) =&gt; {&#10;            if (g.espera &gt; 0) {&#10;                if (--g.espera === 0) { if (g.trab) { Kutxa.aportar(0.6); Desgaste.sube('ordenadores', 0.01); } const p = PUESTOS_G[Math.floor(Math.random() * PUESTOS_G.length)]; g.tx = p.x + (Math.random() - 0.5) * 24; g.ty = p.y + (Math.random() - 0.5) * 14; g.ic = p.ic; g.trab = false; }&#10;                return;&#10;            }&#10;            const dx = g.tx - g.x, dy = g.ty - g.y, d = Math.hypot(dx, dy);&#10;            if (d &lt; 3) { g.espera = 160 + Math.random() * 140; g.trab = true; return; }          \/\/ llega y trabaja&#10;            let vy = dy \/ d * g.v * 0.6;&#10;            GEN.forEach((o, j) =&gt; { if (j !== i &amp;&amp; Math.abs(o.x - g.x) &lt; 34 &amp;&amp; Math.abs(o.y - g.y) &lt; 16) vy += g.y &lt; o.y ? -0.25 : 0.25; });   \/\/ no se pisan&#10;            g.x += dx \/ d * g.v; g.y = Math.max(440, Math.min(520, g.y + vy)); g.dir = dx &gt;= 0 ? 1 : -1; g.fase += 0.14;&#10;        });&#10;    }&#10;    function dibujarGen(g, now) {&#10;        const anda = g.espera &lt;= 0, bam = anda ? Math.sin(now \/ 100) * 0.06 * g.dir : Math.sin(now \/ 200 + g.fase) * 0.02 + (g.trab ? Math.sin(now \/ 60) * 0.03 : 0);&#10;        ctx.save(); ctx.translate(g.x, g.y - 28); ctx.scale(1.1, 1.1);&#10;        dibujarMu\u00f1eca({ x: 0, y: 0, angulo: bam }, MALLA, false, g.dir &lt; 0, false, g.estilo); accesorioFiesta(0, 0, g.dir &lt; 0 ? -1 : 1);   \/\/ las Genoides tambi\u00e9n celebran; los sensores rojos brillan por encima&#10;        const luzRoja = ((g.trab ? 0.8 : 0.6) + 0.4 * Math.sin(now \/ (g.trab ? 60 : 130) + g.fase)) * (Desgaste.parpadeo(now, g.fase) ? 0.12 : 1);&#10;        [-5, 5].forEach(ex =&gt; resplandor(ex, -5, 6, '255,0,0', luzRoja * 0.55));&#10;        ctx.fillStyle = `rgba(255,30,30,${luzRoja})`;   \/\/ sensores de luz roja&#10;        [-5, 5].forEach(ex =&gt; { ctx.beginPath(); ctx.arc(ex, -5, 2.4, 0, Math.PI * 2); ctx.fill(); });&#10;        ctx.restore();&#10;        if (g.trab &amp;&amp; g.ic) { const by = g.y - 92 - Math.sin(now \/ 150 + g.fase) * 1.5; mCaja(g.x - 14, by - 13, 28, 24, 10, 'rgba(255,255,255,0.95)', '#20262e', 1.2); mTxt(g.ic, g.x, by, 15, '#000', 'center'); }&#10;    }&#10;    function dibujar() {&#10;        const now = performance.now();&#10;        escena(now); silos(now); impresora(now); Costa.brazoIndustria(now \/ 16, !!job, job ? job.it.col : null); holiloop(now); mandos(now); dibujarDesgasteIndustria(now);&#10;        actualizarGen(); [...GEN].sort((a, b) =&gt; a.y - b.y).forEach(g =&gt; dibujarGen(g, now));&#10;        mCaja(730, 14, 210, 34, 17, 'rgba(255,255,255,0.9)', '#2a9d78'); mTxt(`\ud83e\ude99 MIIG26D: ${saldoMIIG26D}`, 835, 32, 14, '#1d5a48', 'center', true);&#10;        dibujarFiestaEscena('industria', now \/ 16);&#10;        if (panel) panelImpresora();&#10;        if (toast) { ctx.font = `bold 14px ${FUENTE_MERCADO}`; const w = ctx.measureText(toast.s).width + 30; mCaja(W \/ 2 - w \/ 2, 136, w, 32, 16, 'rgba(30,58,50,0.92)', '#7cffd9', 1.5); mTxt(toast.s, W \/ 2, 152, 14, '#fff', 'center', true); }&#10;        dibujarBotonVolver();&#10;    }&#10;    function toque(x, y) {&#10;        if (panel) {&#10;            if (!dentroRect(x, y, PN) || dentroRect(x, y, CLOSE)) { panel = false; return; }&#10;            ITEMS.forEach((_, i) =&gt; { if (dentroRect(x, y, tile(i))) sel = i; });&#10;            if (dentroRect(x, y, BTN)) fabricar(); return;&#10;        }&#10;        if (tocoZonaVolver(x, y)) { iniciarTransicion(() =&gt; salirDeEscena()); return; }&#10;        if (dentroRect(x, y, { x: 340, y: 186, w: 280, h: 240 })) panel = true;&#10;    }&#10;    return { actualizar, dibujar, toque, genoide: dibujarGen, actividad: () =&gt; GEN.filter(g =&gt; g.trab).length \/ GEN.length, entrar() { enIndustria = true; panel = false; } };&#10;})();&#10;function entrarAIndustria() { salirDeEscena(); Industria.entrar(); }&#10;const navBotones = [...document.querySelectorAll('#nav button')], navSaldo = document.getElementById('navSaldo');&#10;let navUltima = '', navUltimoSaldo = -1;&#10;function pantallaActual() { return enHospital ? 'hospital' : enArena ? 'arena' : enIndustria ? 'industria' : enMercado ? 'mercado' : enHuerta ? 'huerta' : (enPlaya || enPuerto || enSubmarino) ? 'playa' : 'pueblo'; }&#10;function irAPantalla(id) {&#10;    if (enPuerto &amp;&amp; id === 'playa') { iniciarTransicion(() =&gt; { enPuerto = false; enPlaya = true; }); return; }        \/\/ del puerto a la playa&#10;    if (enSubmarino &amp;&amp; id === 'playa') { iniciarTransicion(() =&gt; { enSubmarino = false; enPlaya = true; }); return; }  \/\/ del fondo marino a la playa&#10;    if (pantallaActual() === id &amp;&amp; casaAbierta === null &amp;&amp; !enGimnasio &amp;&amp; !enBiblioteca &amp;&amp; !enArena &amp;&amp; !enHospital) return;        \/\/ ya est\u00e1s aqu\u00ed&#10;    iniciarTransicion(() =&gt; {&#10;        salirDeEscena();                                                                  \/\/ limpia interiores, playa, huerta, mercado e industria&#10;        if (id === 'playa') {&#10;            if (!habitantesEnPlaya.length) habitantes.filter(o =&gt; !o.enPlaya &amp;&amp; !o.oculta &amp;&amp; !o.durmiendo &amp;&amp; !o.arrastrando).slice(0, 4).forEach(o =&gt; enviarAPlaya(o));&#10;            enPlaya = true;&#10;        } else if (id === 'huerta') { enHuerta = true; entrarALaHuerta(); }&#10;        else if (id === 'mercado') entrarAlMercado();&#10;        else if (id === 'industria') Industria.entrar();&#10;        else if (id === 'hospital') { enHospital = true; Hospital.entrar(); try { canvas.scrollIntoView({ behavior: 'smooth', block: 'center' }); } catch (e) {} }&#10;        else if (id === 'arena') { enArena = true; Arena.entrar(); try { canvas.scrollIntoView({ behavior: 'smooth', block: 'center' }); } catch (e) {} }   \/\/ desplazamiento suave hasta el estadio&#10;    });&#10;}&#10;navBotones.forEach(b =&gt; b.addEventListener('click', () =&gt; irAPantalla(b.dataset.p)));&#10;function actualizarNav() {                                                               \/\/ resalta la vista actual y el saldo MIIG26D compartido&#10;    const p = pantallaActual();&#10;    if (p !== navUltima) { navUltima = p; navBotones.forEach(b =&gt; b.classList.toggle('activo', b.dataset.p === p)); }&#10;    if (saldoMIIG26D !== navUltimoSaldo) { navUltimoSaldo = saldoMIIG26D; navSaldo.textContent = '\ud83e\ude99 ' + saldoMIIG26D + ' MIIG26D'; }&#10;}&#10;let fiestaPrevia = null, _fiestaCache = { t: 0, v: null };&#10;const PREVIAS = [null, 'navidad', 'santotomas', 'olentzero', 'carnaval', 'm8', 'sanjuan', '28j', 'astenagusia', 'n25', 'halloween', 'feria', 'santjordi', 'sanesteban'];&#10;const PREV_INFO = { m8: { id: 'm8', txt: '\ud83d\udc9c 8M \u00b7 D\u00eda de la Mujer' }, n25: { id: 'n25', txt: '\ud83c\udf97\ufe0f 25N \u00b7 Contra la violencia hacia las mujeres' }, astenagusia: { id: 'astenagusia', txt: '\ud83c\udf86 Aste Nagusia' }, santotomas: { id: 'navidad', sub: 'santotomas', txt: '\ud83e\udd56 Santo Tom\u00e1s' }, olentzero: { id: 'navidad', sub: 'olentzero', txt: '\ud83c\udf85 Olentzero' }, navidad: { id: 'navidad', txt: '\ud83c\udf84 Navidad' }, carnaval: { id: 'carnaval', txt: '\ud83c\udfad Carnaval' }, sanjuan: { id: 'sanjuan', txt: '\ud83d\udd25 San Juan' }, '28j': { id: '28j', txt: '\ud83c\udff3\ufe0f\u200d\ud83c\udf08 28J' }, halloween: { id: 'halloween', txt: '\ud83c\udf83 Gau Beltza' }, feria: { id: 'feria', txt: '\ud83d\udc83 Feria de Abril' }, santjordi: { id: 'santjordi', txt: '\ud83c\udf39 Sant Jordi' }, sanesteban: { id: 'navidad', sub: 'sanesteban', txt: '\ud83c\udf5d San Esteban \u00b7 Sant Esteve (canelones)' } };&#10;const PAL = { navidad: ['#e53935', '#43a047', '#fdd835', '#ffffff'], carnaval: ['#e91e63', '#ffeb3b', '#00bcd4', '#8e44ad', '#ff9800'],&#10;              sanjuan: ['#ff9800', '#ffcc33', '#ff5722', '#fff3c4'], '28j': ['#e40303', '#ff8c00', '#ffed00', '#008026', '#004dff', '#750787'], halloween: ['#ff7518', '#7e22ce', '#1a1a1a', '#76ff03'], feria: ['#e53935', '#ffffff', '#2e7d32', '#fdd835'], santjordi: ['#d32f2f', '#fdd835', '#ffffff', '#2e7d32'], astenagusia: ['#d52b1e', '#ffffff', '#009b48', '#fdd835'], m8: ['#6a1b9a', '#9c4dcc', '#ffffff', '#d1b3ff'], n25: ['#6a1b9a', '#9c4dcc', '#ffffff', '#d1b3ff'] };&#10;function pascua(y) {                                                      \/\/ algoritmo de Meeus\/Jones\/Butcher&#10;    const a = y % 19, b = Math.floor(y \/ 100), c = y % 100, d = Math.floor(b \/ 4), e = b % 4, f = Math.floor((b + 8) \/ 25), g = Math.floor((b - f + 1) \/ 3);&#10;    const h = (19 * a + b - d - g + 15) % 30, i = Math.floor(c \/ 4), k = c % 4, l = (32 + 2 * e + 2 * i - h - k) % 7, m = Math.floor((a + 11 * h + 22 * l) \/ 451);&#10;    return new Date(y, Math.floor((h + l - 7 * m + 114) \/ 31) - 1, ((h + l - 7 * m + 114) % 31) + 1);&#10;}&#10;function infoFiesta(ahora) {&#10;    const y = ahora.getFullYear(), d0 = new Date(y, ahora.getMonth(), ahora.getDate()), m = d0.getMonth() + 1, d = d0.getDate();&#10;    if (m === 3 &amp;&amp; d === 8) return PREV_INFO.m8;                                  \/\/ 8M: D\u00eda Internacional de la Mujer&#10;    if (m === 11 &amp;&amp; d === 25) return PREV_INFO.n25;                               \/\/ 25N: D\u00eda Internacional de la Eliminaci\u00f3n de la Violencia contra la Mujer&#10;    const P = pascua(y), ceniza = new Date(P.getFullYear(), P.getMonth(), P.getDate() - 46);&#10;    const jueves = new Date(ceniza.getFullYear(), ceniza.getMonth(), ceniza.getDate() - 6), martes = new Date(ceniza.getFullYear(), ceniza.getMonth(), ceniza.getDate() - 1);&#10;    if (d0 &gt;= jueves &amp;&amp; d0 &lt;= martes) return PREV_INFO.carnaval;&#10;    if (m === 6 &amp;&amp; d === 28) return PREV_INFO['28j'];&#10;    if (m === 6 &amp;&amp; (d === 23 || d === 24)) return PREV_INFO.sanjuan;&#10;    if (m === 4 &amp;&amp; d === 23) return PREV_INFO.santjordi;                          \/\/ Sant Jordi: rosas y libros&#10;    const f0 = new Date(P.getFullYear(), P.getMonth(), P.getDate() + 15), f1 = new Date(P.getFullYear(), P.getMonth(), P.getDate() + 21);   \/\/ Feria de Abril de Sevilla: del lunes (alumbrado) al domingo, dos semanas despu\u00e9s de Semana Santa&#10;    if (d0 &gt;= f0 &amp;&amp; d0 &lt;= f1) return PREV_INFO.feria;&#10;    if (m === 12 &amp;&amp; d === 26) return PREV_INFO.sanesteban;                        \/\/ San Esteban (Sant Esteve)&#10;    if (m === 10 &amp;&amp; d === 31) return PREV_INFO.halloween;                         \/\/ Gau Beltza \/ Halloween&#10;    const a15 = new Date(y, 7, 15), ds = (6 - a15.getDay() + 7) % 7 || 7, ini = new Date(y, 7, 15 + ds), fin = new Date(y, 7, 15 + ds + 8);       \/\/ Aste Nagusia: 9 d\u00edas desde el primer s\u00e1bado posterior al 15 de agosto&#10;    if (d0 &gt;= ini &amp;&amp; d0 &lt;= fin) return PREV_INFO.astenagusia;&#10;    if (m === 12 &amp;&amp; d === 21) return PREV_INFO.santotomas;                        \/\/ Santo Tom\u00e1s: talos con txistorra&#10;    if (m === 12 &amp;&amp; d === 24) return PREV_INFO.olentzero;                         \/\/ Olentzero&#10;    const nav = new Date(y, 11, 25), adv = new Date(y, 11, 25 - (nav.getDay() || 7) - 21);           \/\/ 1.er domingo de Adviento&#10;    if (d0 &gt;= adv &amp;&amp; d0 &lt; nav) { const n = Math.min(4, Math.floor((d0 - adv) \/ 6048e5) + 1); return { id: 'navidad', txt: '\ud83d\udd6f\ufe0f'.repeat(n) + ' Adviento' }; }&#10;    if (d0 &gt;= nav || d0 &lt;= new Date(y, 1, 2)) return (m === 2 &amp;&amp; d === 2) ? { id: 'navidad', txt: '\ud83d\udd6f\ufe0f Candelaria' } : PREV_INFO.navidad;&#10;    return null;&#10;}&#10;function fiestaActual() {&#10;    if (fiestaPrevia) return PREV_INFO[fiestaPrevia];&#10;    if (Date.now() - _fiestaCache.t &gt; 60000) _fiestaCache = { t: Date.now(), v: infoFiesta(new Date()) };&#10;    return _fiestaCache.v;&#10;}&#10;function guirnalda(x1, x2, y, pal, t, banderines) {                      \/\/ cuerda con ca\u00edda, bombillas o banderines&#10;    const n = Math.max(3, Math.round((x2 - x1) \/ 16)), pt = f =&gt; [x1 + (x2 - x1) * f, y + Math.sin(f * Math.PI) * 7];&#10;    ctx.save(); ctx.strokeStyle = 'rgba(40,40,40,0.8)'; ctx.lineWidth = 1.5; ctx.beginPath();&#10;    for (let i = 0; i &lt;= n; i++) { const [x, yy] = pt(i \/ n); i ? ctx.lineTo(x, yy) : ctx.moveTo(x, yy); } ctx.stroke();&#10;    for (let i = 0; i &lt;= n; i++) {&#10;        const [x, yy] = pt(i \/ n); ctx.fillStyle = pal[i % pal.length];&#10;        if (banderines) { ctx.beginPath(); ctx.moveTo(x - 4, yy); ctx.lineTo(x + 4, yy); ctx.lineTo(x, yy + 9); ctx.fill(); }&#10;        else { ctx.globalAlpha = Math.sin(t \/ 12 + i) &gt; -0.4 ? 1 : 0.45; ctx.beginPath(); ctx.arc(x, yy + 3, 2.6, 0, Math.PI * 2); ctx.fill(); ctx.globalAlpha = 1; }&#10;    }&#10;    ctx.restore();&#10;}&#10;function dibujarCieloFiesta(t) {                                          \/\/ arco\u00edris del 28J, detr\u00e1s de todo&#10;    const F = fiestaActual();&#10;    if (F &amp;&amp; F.id === 'astenagusia') { Fiestas2.fuegos(t, 8, 150); return; }       \/\/ fuegos artificiales de Aste Nagusia&#10;    if (F &amp;&amp; F.id === 'halloween') {                                                  \/\/ luna llena y murci\u00e9lagos&#10;        const mx = 720, my = 58, g = ctx.createRadialGradient(mx, my, 10, mx, my, 60); g.addColorStop(0, 'rgba(255,200,90,0.55)'); g.addColorStop(1, 'rgba(255,200,90,0)');&#10;        ctx.fillStyle = g; ctx.beginPath(); ctx.arc(mx, my, 60, 0, Math.PI * 2); ctx.fill(); ctx.fillStyle = '#ffd86b'; ctx.beginPath(); ctx.arc(mx, my, 24, 0, Math.PI * 2); ctx.fill();&#10;        ctx.fillStyle = '#f0b94a'; [[-8, -6, 4], [7, 4, 5], [-4, 9, 3]].forEach(([dx, dy, r]) =&gt; { ctx.beginPath(); ctx.arc(mx + dx, my + dy, r, 0, Math.PI * 2); ctx.fill(); });&#10;        for (let i = 0; i &lt; 3; i++) dibujarMurcielago(((t * 0.9 + i * 330) % 1100) - 70, 40 + i * 24 + Math.sin(t \/ 25 + i) * 10, t, 1);&#10;        return;&#10;    }&#10;    if (!F || F.id !== '28j') return;&#10;    ctx.save(); ctx.lineWidth = 9; ctx.globalAlpha = 0.55;&#10;    PAL['28j'].forEach((c, i) =&gt; { ctx.strokeStyle = c; ctx.beginPath(); ctx.arc(480, 175, 168 - i * 9, Math.PI, Math.PI * 2); ctx.stroke(); });&#10;    ctx.restore();&#10;}&#10;const FRASE_GAU_BELTZA = 'Xanduli, manduli, kikirriki\u2026 eman goxokiak guri! \ud83c\udf6c';&#10;const HOJAS_OTONO = ['#ff7518', '#c2571a', '#8d5524', '#d4a017'];&#10;function dibujarMurcielago(x, y, t, e = 1) {&#10;    const w = Math.sin(t \/ 3 + x) * 5 * e; ctx.save(); ctx.fillStyle = '#1a1a1a';&#10;    ctx.beginPath(); ctx.ellipse(x, y, 3.5 * e, 4.5 * e, 0, 0, Math.PI * 2); ctx.fill();&#10;    [-1, 1].forEach(s =&gt; { ctx.beginPath(); ctx.moveTo(x, y - 1); ctx.quadraticCurveTo(x + s * 9 * e, y - 8 * e - w, x + s * 16 * e, y - e + w); ctx.quadraticCurveTo(x + s * 11 * e, y + 1, x + s * 8 * e, y + 3 * e); ctx.quadraticCurveTo(x + s * 4 * e, y + 1, x, y + 3); ctx.fill(); });&#10;    ctx.restore();&#10;}&#10;function dibujarArgizaiola(x, y, t, i) {&#10;    conProf(x, y, () =&gt; {&#10;        const w = 16, h = 30, top = y - 6 - h, noche = !esDeDia();&#10;        sombra(x, y + 1, 12, 3, 0.2);&#10;        ctx.fillStyle = '#6b4a2b'; ctx.fillRect(x - 1.5, y - 6, 3, 8);                                     \/\/ estaca clavada en la tierra&#10;        ctx.fillStyle = '#9a6b3a'; ctx.strokeStyle = '#3b2412'; ctx.lineWidth = 1.5;                       \/\/ tablilla de madera con remate redondeado&#10;        ctx.beginPath(); ctx.roundRect ? ctx.roundRect(x - w \/ 2, top, w, h, [8, 8, 2, 2]) : ctx.rect(x - w \/ 2, top, w, h); ctx.fill(); ctx.stroke();&#10;        ctx.strokeStyle = 'rgba(59,36,18,0.35)'; ctx.lineWidth = 1; ctx.beginPath(); [-3, 3].forEach(dx =&gt; { ctx.moveTo(x + dx, top + 4); ctx.lineTo(x + dx, y - 8); }); ctx.stroke();   \/\/ veta&#10;        ctx.strokeStyle = '#5a3a1c'; ctx.beginPath(); ctx.arc(x, top + 9, 3, 0, Math.PI * 2); ctx.moveTo(x - 3, top + 9); ctx.lineTo(x + 3, top + 9); ctx.moveTo(x, top + 6); ctx.lineTo(x, top + 12); ctx.stroke();   \/\/ roseta grabada&#10;        const y0 = y - 9, y1 = top + 17, n = 7;                                                             \/\/ cera enrollada en zigzag&#10;        const cera = () =&gt; { ctx.beginPath(); for (let k = 0; k &lt;= n; k++) { const yy = y0 + (y1 - y0) * k \/ n, xx = x + (k % 2 ? 6 : -6); k ? ctx.lineTo(xx, yy) : ctx.moveTo(xx, yy); } ctx.lineTo(x, top - 1); };&#10;        ctx.lineCap = 'round'; ctx.lineJoin = 'round'; ctx.strokeStyle = 'rgba(160,110,30,0.7)'; ctx.lineWidth = 4.2; cera(); ctx.stroke();&#10;        ctx.strokeStyle = '#f2d27a'; ctx.lineWidth = 3; cera(); ctx.stroke();&#10;        ctx.strokeStyle = '#3b2412'; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(x, top - 1); ctx.lineTo(x, top - 4); ctx.stroke();   \/\/ mecha&#10;        const fl = 1 + 0.18 * Math.sin(t \/ 3 + i * 2), fx = x + Math.sin(t \/ 7 + i) * 0.8, fy = top - 4;      \/\/ llama que titila + resplandor&#10;        const g = ctx.createRadialGradient(fx, fy - 4, 1, fx, fy - 4, 30); g.addColorStop(0, `rgba(255,190,70,${noche ? 0.6 : 0.3})`); g.addColorStop(1, 'rgba(255,150,40,0)');&#10;        ctx.fillStyle = g; ctx.beginPath(); ctx.arc(fx, fy - 4, 30, 0, Math.PI * 2); ctx.fill();&#10;        ctx.fillStyle = '#ff8a1f'; ctx.beginPath(); ctx.moveTo(fx, fy - 11 * fl); ctx.quadraticCurveTo(fx + 5, fy - 3, fx, fy + 1); ctx.quadraticCurveTo(fx - 5, fy - 3, fx, fy - 11 * fl); ctx.fill();&#10;        ctx.fillStyle = '#ffe27a'; ctx.beginPath(); ctx.moveTo(fx, fy - 6 * fl); ctx.quadraticCurveTo(fx + 2.4, fy - 2, fx, fy); ctx.quadraticCurveTo(fx - 2.4, fy - 2, fx, fy - 6 * fl); ctx.fill();&#10;    });&#10;}&#10;function dibujarGauBeltzaPueblo(t) {                                      \/\/ calabazas en las puertas de las casas&#10;    const F = fiestaActual(); if (!F || F.id !== 'halloween') return;&#10;    casas.forEach((c, i) =&gt; { mTxt('\ud83c\udf83', c.x + 12, SUELO_Y + 62, 16 + (i % 2) * 2, '#000', 'center'); dibujarArgizaiola(c.x + c.ancho - 14, SUELO_Y + 74, t, i); });   \/\/ una Argizaiola en el jard\u00edn de cada casa&#10;}&#10;function dibujarFraseGauBeltza(t) {                                       \/\/ una ni\u00f1a canta la frase cada ~15 s durante ~5 s&#10;    const F = fiestaActual(); if (!F || F.id !== 'halloween') return;&#10;    const ciclo = Math.floor(t \/ 900), fase = t % 900; if (fase &gt; 300) return;&#10;    const cand = habitantes.filter(h =&gt; !h.durmiendo &amp;&amp; !h.enPlaya &amp;&amp; !h.oculta &amp;&amp; !h.arrastrando); if (!cand.length) return;&#10;    const h = cand[ciclo % cand.length], a = Math.min(1, fase \/ 20, (300 - fase) \/ 20);&#10;    ctx.save(); ctx.globalAlpha = a; ctx.font = `bold 12px ${FUENTE_MERCADO}`;&#10;    const w = ctx.measureText(FRASE_GAU_BELTZA).width + 24, x = Math.max(w \/ 2 + 6, Math.min(canvas.width - w \/ 2 - 6, h.x)), y = h.y - 70;&#10;    mCaja(x - w \/ 2, y - 14, w, 28, 12, '#fff8ea', '#ff7518', 2.5);&#10;    ctx.fillStyle = '#fff8ea'; ctx.beginPath(); ctx.moveTo(h.x - 6, y + 14); ctx.lineTo(h.x + 6, y + 14); ctx.lineTo(h.x, y + 24); ctx.fill();&#10;    mTxt(FRASE_GAU_BELTZA, x, y, 12, '#4a1d6a', 'center', true); ctx.restore();&#10;}&#10;function dibujarFiestaPueblo(t) {                                         \/\/ guirnaldas en los edificios y luces en los \u00e1rboles&#10;    const F = fiestaActual(); if (!F) return;&#10;    const pal = PAL[F.id], ban = F.id === 'carnaval' || F.id === '28j', by = SUELO_Y + 55;&#10;    casas.forEach(c =&gt; guirnalda(c.x, c.x + c.ancho, by - c.alto + 2, pal, t, ban));&#10;    guirnalda(GIMNASIO_EDIFICIO.x, GIMNASIO_EDIFICIO.x + GIMNASIO_EDIFICIO.ancho, by - GIMNASIO_EDIFICIO.alto + 2, pal, t, ban);&#10;    guirnalda(BIBLIOTECA.x, BIBLIOTECA.x + BIBLIOTECA.ancho, by - BIBLIOTECA.alto + 2, pal, t, ban);&#10;    if (F.id === 'navidad') [[412, SUELO_Y + 90], [634, SUELO_Y + 105]].forEach(([tx, ty]) =&gt; {&#10;        for (let k = 0; k &lt; 14; k++) { const a = k \/ 14 * Math.PI * 2; ctx.fillStyle = pal[k % 4]; ctx.globalAlpha = Math.sin(t \/ 10 + k) &gt; -0.3 ? 1 : 0.4;&#10;            ctx.beginPath(); ctx.arc(tx + Math.cos(a) * 28, ty - 58 + Math.sin(a) * 24, 2.4, 0, Math.PI * 2); ctx.fill(); }&#10;        ctx.globalAlpha = 1; });&#10;}&#10;function dibujarConfeti(t) {                                              \/\/ Carnaval y 28J: confeti por toda la pantalla&#10;    const F = fiestaActual(); if (!F || (F.id !== 'carnaval' &amp;&amp; F.id !== '28j' &amp;&amp; F.id !== 'halloween' &amp;&amp; F.id !== 'feria' &amp;&amp; F.id !== 'santjordi')) return;&#10;    const hoja = F.id === 'halloween' || F.id === 'santjordi', pal = F.id === 'halloween' ? HOJAS_OTONO : PAL[F.id]; ctx.save();&#10;    for (let i = 0; i &lt; 60; i++) {&#10;        const x = (i * 97 + Math.sin(t \/ 40 + i) * 14 + 960) % 960, y = (i * 53 + t * (0.7 + (i % 4) * 0.25)) % 540;&#10;        ctx.save(); ctx.translate(x, y); ctx.rotate(t \/ 15 + i); ctx.fillStyle = pal[i % pal.length]; if (hoja) { ctx.beginPath(); ctx.ellipse(0, 0, 4, 2, 0, 0, Math.PI * 2); ctx.fill(); } else ctx.fillRect(-3, -1.5, 6, 3); ctx.restore();&#10;    }&#10;    ctx.restore();&#10;}&#10;function accesorioFiesta(x, y, dir) {                                     \/\/ gorro, m\u00e1scara, corona de flores o diadema arco\u00edris&#10;    const F = fiestaActual(); if (!F) return; ctx.save(); ctx.lineWidth = 1.5; ctx.strokeStyle = '#000';&#10;    if (F.id === 'navidad') {&#10;        ctx.fillStyle = '#e53935'; ctx.beginPath(); ctx.moveTo(x - 12, y - 19); ctx.lineTo(x + 12, y - 19); ctx.lineTo(x + dir * 10, y - 42); ctx.closePath(); ctx.fill(); ctx.stroke();&#10;        ctx.fillStyle = '#fff'; ctx.fillRect(x - 13, y - 22, 26, 5); ctx.beginPath(); ctx.arc(x + dir * 10, y - 43, 3.5, 0, Math.PI * 2); ctx.fill();&#10;    } else if (F.id === 'carnaval') {&#10;        ctx.fillStyle = '#8e44ad'; ctx.beginPath(); ctx.roundRect ? ctx.roundRect(x - 13, y - 10, 26, 10, 5) : ctx.rect(x - 13, y - 10, 26, 10); ctx.fill(); ctx.stroke();&#10;        [-5, 5].forEach(ox =&gt; { ctx.fillStyle = '#fff'; ctx.beginPath(); ctx.arc(x + ox, y - 5, 2.8, 0, Math.PI * 2); ctx.fill(); ctx.fillStyle = '#000'; ctx.beginPath(); ctx.arc(x + ox, y - 5, 1.3, 0, Math.PI * 2); ctx.fill(); });&#10;        ctx.strokeStyle = '#ffeb3b'; ctx.lineWidth = 2.5; ctx.beginPath(); ctx.moveTo(x + 11, y - 9); ctx.quadraticCurveTo(x + 20, y - 18, x + 17, y - 27); ctx.stroke();&#10;    } else if (F.id === 'sanjuan') {&#10;        for (let k = 0; k &lt; 7; k++) { const a = Math.PI * (1.08 + k * 0.14); ctx.fillStyle = PAL.navidad &amp;&amp; ['#ff5ca8', '#ffd23f', '#ffffff', '#ff8a3d'][k % 4]; ctx.beginPath(); ctx.arc(x + Math.cos(a) * 14, y - 3 + Math.sin(a) * 21, 3.2, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); }&#10;    } else if (F.id === 'halloween') {&#10;        ctx.fillStyle = '#1a1a1a'; ctx.beginPath(); ctx.ellipse(x, y - 21, 16, 4, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;        ctx.beginPath(); ctx.moveTo(x - 9, y - 22); ctx.lineTo(x + 9, y - 22); ctx.quadraticCurveTo(x + dir * 2, y - 36, x + dir * 10, y - 48); ctx.quadraticCurveTo(x - dir * 3, y - 38, x - 9, y - 22); ctx.fill(); ctx.stroke();&#10;        ctx.fillStyle = '#ff7518'; ctx.fillRect(x - 9, y - 27, 18, 4); ctx.fillStyle = '#ffd54a'; ctx.fillRect(x - 2, y - 27, 4, 4);&#10;    } else if (F.id === 'm8' || F.id === 'n25') {&#10;        ctx.fillStyle = '#7b2cbf'; ctx.lineWidth = 1.6;&#10;        if (F.id === 'm8') { ctx.beginPath(); ctx.moveTo(x - 12, y + 14); ctx.lineTo(x + 12, y + 14); ctx.lineTo(x, y + 28); ctx.closePath(); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#fff'; [-5, 4].forEach(dx =&gt; { ctx.beginPath(); ctx.arc(x + dx, y + 18, 1.3, 0, Math.PI * 2); ctx.fill(); }); }          \/\/ pa\u00f1uelo violeta (8M)&#10;        else { ctx.beginPath(); ctx.moveTo(x, y + 20); ctx.bezierCurveTo(x - 9, y + 10, x - 10, y + 22, x, y + 21); ctx.moveTo(x, y + 20); ctx.bezierCurveTo(x + 9, y + 10, x + 10, y + 22, x, y + 21); ctx.fill(); ctx.stroke(); ctx.beginPath(); ctx.moveTo(x, y + 21); ctx.lineTo(x - 5, y + 30); ctx.moveTo(x, y + 21); ctx.lineTo(x + 5, y + 30); ctx.stroke(); }   \/\/ lazo violeta (25N)&#10;    } else if (F.id === 'feria') {&#10;        const fx = x - dir * 12, fy = y - 18;                                           \/\/ clavel flamenco: flor roja grande de borde rizado&#10;        ctx.fillStyle = '#e53935'; for (let k = 0; k &lt; 10; k++) { const a = k * 0.6283; ctx.beginPath(); ctx.arc(fx + Math.cos(a) * 5.2, fy + Math.sin(a) * 5.2, 2.7, 0, Math.PI * 2); ctx.fill(); }&#10;        ctx.fillStyle = '#ff5252'; ctx.beginPath(); ctx.arc(fx, fy, 4.6, 0, Math.PI * 2); ctx.fill();&#10;        ctx.strokeStyle = '#a31515'; ctx.lineWidth = 0.9; for (let k = 0; k &lt; 5; k++) { const a = k * 1.2566 + 0.3; ctx.beginPath(); ctx.moveTo(fx, fy); ctx.lineTo(fx + Math.cos(a) * 4.8, fy + Math.sin(a) * 4.8); ctx.stroke(); }&#10;    } else if (F.id === 'santjordi') {&#10;        const fx = x - dir * 12, fy = y - 20;                                           \/\/ rosa: capullo en espiral con tallo y hojas verdes&#10;        ctx.strokeStyle = '#2e7d32'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(fx, fy + 4); ctx.lineTo(fx - dir * 3, fy + 16); ctx.stroke();&#10;        ctx.fillStyle = '#43a047'; ctx.lineWidth = 1; ctx.strokeStyle = '#1b5e20'; [[-1, 9], [1, 12]].forEach(([sd, oy]) =&gt; { ctx.beginPath(); ctx.ellipse(fx - dir * 2 + sd * 4, fy + oy, 4, 2, sd * 0.5, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); });&#10;        ctx.fillStyle = '#c62828'; ctx.strokeStyle = '#7f0000'; ctx.lineWidth = 1.2; ctx.beginPath(); ctx.arc(fx, fy, 5.2, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;        ctx.beginPath(); ctx.arc(fx, fy, 3.2, 0.4, Math.PI * 1.6); ctx.stroke(); ctx.beginPath(); ctx.arc(fx + 0.5, fy, 1.4, 0.2, Math.PI * 1.5); ctx.stroke();&#10;    } else if (F.id === 'astenagusia') {&#10;        ctx.fillStyle = '#d52b1e'; ctx.beginPath(); ctx.moveTo(x - 12, y + 14); ctx.lineTo(x + 12, y + 14); ctx.lineTo(x, y + 28); ctx.closePath(); ctx.fill(); ctx.stroke();        \/\/ pa\u00f1uelo rojo de las fiestas&#10;        ctx.fillStyle = '#fff'; [-5, 4].forEach(dx =&gt; { ctx.beginPath(); ctx.arc(x + dx, y + 18, 1.3, 0, Math.PI * 2); ctx.fill(); });&#10;    } else if (F.id === '28j') {&#10;        ctx.lineWidth = 2; PAL['28j'].forEach((c, i) =&gt; { ctx.strokeStyle = c; ctx.beginPath(); ctx.arc(x, y - 6, 20 - i * 2, Math.PI * 1.05, Math.PI * 1.95); ctx.stroke(); });&#10;    }&#10;    ctx.restore();&#10;}&#10;function dibujarFiestaPlaya(t) {                                          \/\/ San Juan: hoguera en la arena&#10;    const F = fiestaActual(); if (F &amp;&amp; F.id === 'astenagusia') { Fiestas2.fuegos(t, 4, 90); return; }&#10;    if (!F || F.id !== 'sanjuan') return;&#10;    const x = 480, y = 478; ctx.save();&#10;    const g = ctx.createRadialGradient(x, y - 20, 4, x, y - 20, 110); g.addColorStop(0, 'rgba(255,170,40,0.45)'); g.addColorStop(1, 'rgba(255,120,0,0)');&#10;    ctx.fillStyle = g; ctx.beginPath(); ctx.arc(x, y - 20, 110, 0, Math.PI * 2); ctx.fill();&#10;    ctx.strokeStyle = '#5a3a1c'; ctx.lineWidth = 7; ctx.lineCap = 'round'; ctx.beginPath(); ctx.moveTo(x - 30, y + 4); ctx.lineTo(x + 26, y - 8); ctx.moveTo(x + 30, y + 4); ctx.lineTo(x - 26, y - 8); ctx.stroke();&#10;    [['#ff5722', 34, 0], ['#ff9800', 26, 1.3], ['#ffeb3b', 16, 2.4]].forEach(([c, h, ph]) =&gt; {&#10;        const fl = h + Math.sin(t \/ 5 + ph) * 6; ctx.fillStyle = c; ctx.beginPath(); ctx.moveTo(x - 16 + ph * 4, y - 4); ctx.quadraticCurveTo(x - 10 + ph * 4, y - fl, x + ph * 3, y - fl - 10);&#10;        ctx.quadraticCurveTo(x + 10 + ph * 3, y - fl, x + 16 - ph * 2, y - 4); ctx.closePath(); ctx.fill(); });&#10;    ctx.fillStyle = '#ffd27a'; for (let k = 0; k &lt; 8; k++) { const f = ((t \/ 60) + k \/ 8) % 1; ctx.globalAlpha = 1 - f; ctx.beginPath(); ctx.arc(x + Math.sin(k * 3 + t \/ 20) * 14, y - 20 - f * 90, 1.6, 0, Math.PI * 2); ctx.fill(); }&#10;    ctx.restore();&#10;}&#10;const navFiesta = document.getElementById('navFiesta');&#10;navFiesta.addEventListener('click', () =&gt; { fiestaPrevia = PREVIAS[(PREVIAS.indexOf(fiestaPrevia) + 1) % PREVIAS.length]; });   \/\/ ciclo de vista previa&#10;let navFiestaTxt = '';&#10;function actualizarChipFiesta() {&#10;    const F = fiestaActual(), s = (fiestaPrevia ? '\ud83d\udc41\ufe0f vista previa \u00b7 ' : '\ud83d\udcc5 ') + (F ? F.txt : 'sin fiesta hoy');&#10;    if (s !== navFiestaTxt) { navFiestaTxt = s; navFiesta.textContent = s; navFiesta.classList.toggle('previa', !!fiestaPrevia); }&#10;}&#10;function propFiesta(x, y, id, t, pal) {                                   \/\/ objeto de suelo propio de cada fiesta&#10;    if (id === 'navidad') {&#10;        ctx.fillStyle = '#6b4a2b'; ctx.fillRect(x - 5, y - 12, 10, 14); ctx.strokeStyle = '#000'; ctx.lineWidth = 1.5;&#10;        ['#2e7d32', '#388e3c', '#43a047'].forEach((c, i) =&gt; { ctx.fillStyle = c; ctx.beginPath(); ctx.moveTo(x - 30 + i * 6, y - 12 - i * 22); ctx.lineTo(x + 30 - i * 6, y - 12 - i * 22); ctx.lineTo(x, y - 40 - i * 22); ctx.closePath(); ctx.fill(); ctx.stroke(); });&#10;        for (let k = 0; k &lt; 9; k++) { ctx.globalAlpha = Math.sin(t \/ 10 + k) &gt; -0.3 ? 1 : 0.4; ctx.fillStyle = pal[k % 4]; ctx.beginPath(); ctx.arc(x + (k % 3 - 1) * (16 - Math.floor(k \/ 3) * 4), y - 24 - Math.floor(k \/ 3) * 20, 2.6, 0, Math.PI * 2); ctx.fill(); }&#10;        ctx.globalAlpha = 1; ctx.fillStyle = '#ffd54a'; ctx.beginPath(); ctx.arc(x, y - 88, 5, 0, Math.PI * 2); ctx.fill();&#10;        ctx.fillStyle = '#e53935'; ctx.fillRect(x - 32, y - 8, 16, 12); ctx.fillStyle = '#fdd835'; ctx.fillRect(x + 16, y - 8, 16, 12);   \/\/ regalos&#10;    } else mTxt({ carnaval: '\ud83c\udfad', sanjuan: '\ud83c\udf3c', '28j': '\ud83c\udff3\ufe0f\u200d\ud83c\udf08', halloween: '\ud83c\udf83', astenagusia: '\ud83c\udf86', m8: '\ud83d\udc9c', n25: '\ud83c\udf97\ufe0f', feria: '\ud83d\udc83', santjordi: '\ud83c\udf39' }[id], x, y - 18, 34, '#000', 'center');&#10;}&#10;function dibujarNieve(t, hasta) {&#10;    ctx.fillStyle = 'rgba(255,255,255,0.85)';&#10;    for (let i = 0; i &lt; 40; i++) { ctx.beginPath(); ctx.arc((i * 83 + Math.sin(t \/ 50 + i) * 10 + 960) % 960, (i * 47 + t * (0.5 + (i % 3) * 0.2)) % hasta, 1.5 + (i % 3) * 0.5, 0, Math.PI * 2); ctx.fill(); }&#10;}&#10;function dibujarFiestaEscena(esc, t) {&#10;    const F = fiestaActual(); if (!F) return;&#10;    const id = F.id, pal = PAL[id], ban = id === 'carnaval' || id === '28j';&#10;    ctx.save();&#10;    if (esc === 'mercado') {&#10;        guirnalda(40, 480, 110, pal, t, ban); guirnalda(480, 920, 110, pal, t, ban);&#10;        propFiesta(880, 505, id, t, pal);&#10;        if (id === 'halloween') { M_CX.forEach((cx, i) =&gt; mTxt('\ud83c\udf83', cx + 52, 292 + (PUESTOS[i].oy || 0), 22, '#000', 'center')); [300, 660].forEach((x, i) =&gt; { const y = 130 + Math.sin(t \/ 30 + i) * 8; ctx.strokeStyle = '#555'; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(x, 106); ctx.lineTo(x, y); ctx.stroke(); mTxt('\ud83d\udd77\ufe0f', x, y + 6, 16, '#000', 'center'); }); }&#10;        if (id === 'sanjuan') M_CX.forEach((cx, i) =&gt; { const g = ctx.createRadialGradient(cx, 130, 1, cx, 130, 18); g.addColorStop(0, 'rgba(255,170,40,0.7)'); g.addColorStop(1, 'rgba(255,170,40,0)');&#10;            ctx.strokeStyle = '#333'; ctx.lineWidth = 1.5; ctx.beginPath(); ctx.moveTo(cx, 106); ctx.lineTo(cx, 124); ctx.stroke(); ctx.fillStyle = g; ctx.beginPath(); ctx.arc(cx, 130, 18, 0, Math.PI * 2); ctx.fill(); ctx.fillStyle = '#ff9800'; ctx.beginPath(); ctx.ellipse(cx, 130, 6, 8, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); });&#10;        if (id === 'carnaval') { const px = 700 + Math.sin(t \/ 30) * 6; ctx.strokeStyle = '#333'; ctx.lineWidth = 1.5; ctx.beginPath(); ctx.moveTo(700, 106); ctx.lineTo(px, 150); ctx.stroke(); mTxt('\ud83c\udf89', px, 160, 26, '#000', 'center'); }&#10;        if (id === '28j') { pal.forEach((c, i) =&gt; { ctx.fillStyle = c; ctx.fillRect(660, 112 + i * 7 + Math.sin(t \/ 15 + i) * 0.8, 200, 7); }); ctx.strokeStyle = '#5a3a1c'; ctx.lineWidth = 3; ctx.beginPath(); ctx.moveTo(660, 108); ctx.lineTo(660, 168); ctx.stroke(); }&#10;        mCaja(430, 160, 100, 18, 9, 'rgba(255,255,255,0.92)', '#2a9d78', 1.5); mTxt(F.txt, 480, 169, 11, '#1d5a48', 'center', true);&#10;        if (ban) dibujarConfeti(t);&#10;    } else if (esc === 'huerta') {&#10;        guirnalda(0, 960, 22, pal, t, ban);&#10;        if (id === 'halloween') { for (let i = 0; i &lt; 5; i++) mTxt('\ud83c\udf83', 120 + i * 180, HUERTA_SUELO_Y + 8, 20, '#000', 'center'); for (let i = 0; i &lt; 3; i++) dibujarMurcielago(((t * 0.7 + i * 330) % 1100) - 70, 50 + i * 18 + Math.sin(t \/ 20 + i) * 8, t, 0.9); }&#10;        if (id === 'navidad') dibujarNieve(t, HUERTA_SUELO_Y + 40);&#10;        if (id === 'astenagusia') Fiestas2.fuegos(t, 6, HUERTA_SUELO_Y - 8);&#10;        if (id === 'sanjuan') for (let i = 0; i &lt; 22; i++) { ctx.fillStyle = `rgba(255,240,120,${0.35 + 0.6 * Math.max(0, Math.sin(t \/ 20 + i * 1.7))})`; ctx.beginPath(); ctx.arc(60 + (i * 41 + Math.sin(t \/ 60 + i) * 30 + 900) % 840, HUERTA_SUELO_Y - 50 + Math.sin(t \/ 45 + i * 2) * 28, 2.2, 0, Math.PI * 2); ctx.fill(); }&#10;        if (id === '28j') { ctx.save(); ctx.beginPath(); ctx.rect(0, 0, 960, HUERTA_SUELO_Y); ctx.clip(); ctx.lineWidth = 8; ctx.globalAlpha = 0.4; const R = Math.min(170, HUERTA_SUELO_Y - 8);&#10;            pal.forEach((c, i) =&gt; { ctx.strokeStyle = c; ctx.beginPath(); ctx.arc(480, HUERTA_SUELO_Y, R - i * 8, Math.PI, Math.PI * 2); ctx.stroke(); }); ctx.restore(); }&#10;        if (ban) dibujarConfeti(t);&#10;        mTxt({ navidad: '\ud83c\udf84', carnaval: '\ud83c\udfad', sanjuan: '\ud83d\udd25', '28j': '\ud83c\udf08', halloween: '\ud83e\udd87', astenagusia: '\ud83c\udf86', m8: '\ud83d\udc9c', n25: '\ud83c\udf97\ufe0f', feria: '\ud83d\udc83', santjordi: '\ud83c\udf39' }[id], dronHabia.x + 24, dronHabia.y - 22, 18, '#000', 'center');   \/\/ dron festivo&#10;    } else if (esc === 'industria') {&#10;        guirnalda(40, 480, 84, pal, t, ban); guirnalda(480, 920, 84, pal, t, ban); guirnalda(345, 615, 188, pal, t, ban); guirnalda(34, 236, 146, pal, t, ban);&#10;        for (let i = 0; i &lt; 20; i++) { ctx.globalAlpha = 0.5 + 0.5 * Math.sin(t \/ 6 - i * 0.7); ctx.fillStyle = pal[(i + Math.floor(t \/ 8)) % pal.length]; ctx.beginPath(); ctx.arc(690 + i * 12.5, 352, 2.6, 0, Math.PI * 2); ctx.fill(); }   \/\/ luces corredoras en el tubo Holiloop&#10;        ctx.globalAlpha = 1; propFiesta(925, 515, id, t, pal);&#10;        mCaja(430, 128, 100, 18, 9, 'rgba(255,255,255,0.92)', '#2a9d78', 1.5); mTxt('Edici\u00f3n ' + F.txt, 480, 137, 10, '#1d5a48', 'center', true);&#10;        if (ban) dibujarConfeti(t);&#10;    }&#10;    ctx.restore();&#10;}&#10;function dibujarFiestaInterior(t) {&#10;    const F = fiestaActual(); if (!F) return;&#10;    const id = F.id, pal = PAL[id], ban = id === 'carnaval' || id === '28j';&#10;    const vx = ANCHO_PRINCIPAL * 0.62, vy = 40, vw = ANCHO_PRINCIPAL * 0.28, vh = 100;&#10;    ctx.save();&#10;    guirnalda(0, ANCHO_PRINCIPAL, 16, pal, t, ban);&#10;    ctx.save(); ctx.beginPath(); ctx.rect(vx, vy, vw, vh); ctx.clip();                     \/\/ lo que se ve por la ventana&#10;    if (id === 'navidad') { ctx.fillStyle = 'rgba(255,255,255,0.9)'; for (let i = 0; i &lt; 18; i++) { ctx.beginPath(); ctx.arc(vx + (i * 37 + Math.sin(t \/ 40 + i) * 6 + 161) % vw, vy + (i * 23 + t * 0.5) % vh, 1.8, 0, Math.PI * 2); ctx.fill(); } }&#10;    else if (id === 'sanjuan') { const g = ctx.createRadialGradient(vx + vw \/ 2, vy + vh, 4, vx + vw \/ 2, vy + vh, 80); g.addColorStop(0, 'rgba(255,150,40,0.6)'); g.addColorStop(1, 'rgba(255,100,0,0)'); ctx.fillStyle = g; ctx.fillRect(vx, vy, vw, vh);&#10;        ctx.fillStyle = '#ffd27a'; for (let k = 0; k &lt; 6; k++) { const f = ((t \/ 70) + k \/ 6) % 1; ctx.globalAlpha = 1 - f; ctx.beginPath(); ctx.arc(vx + vw \/ 2 + Math.sin(k * 3 + t \/ 25) * 14, vy + vh - f * 80, 1.5, 0, Math.PI * 2); ctx.fill(); } ctx.globalAlpha = 1; }&#10;    else if (id === 'halloween') { ctx.fillStyle = '#ffd86b'; ctx.beginPath(); ctx.arc(vx + vw * 0.7, vy + 30, 16, 0, Math.PI * 2); ctx.fill(); dibujarMurcielago(vx + ((t * 0.5) % (vw + 40)) - 20, vy + 40 + Math.sin(t \/ 15) * 8, t, 0.8); }&#10;    else if (id === '28j') { ctx.lineWidth = 6; ctx.globalAlpha = 0.65; pal.forEach((c, i) =&gt; { ctx.strokeStyle = c; ctx.beginPath(); ctx.arc(vx + vw \/ 2, vy + vh + 10, 78 - i * 6, Math.PI, Math.PI * 2); ctx.stroke(); }); ctx.globalAlpha = 1; }&#10;    else { for (let i = 0; i &lt; 14; i++) { ctx.fillStyle = pal[i % pal.length]; ctx.fillRect(vx + (i * 41 + 161) % vw, vy + (i * 29 + t * 0.9) % vh, 4, 2); } }&#10;    ctx.restore();&#10;    propFiesta(540, 525, id, t, pal);&#10;    if (ban) dibujarConfeti(t);&#10;    ctx.restore();&#10;}&#10;function dibujarFiestaGimnasio(t) {&#10;    const F = fiestaActual(); if (!F) return;&#10;    const id = F.id, pal = PAL[id], ban = id === 'carnaval' || id === '28j';&#10;    ctx.save(); guirnalda(0, canvas.width, 66, pal, t, ban);&#10;    if (id === '28j') { pal.forEach((c, i) =&gt; { ctx.fillStyle = c; ctx.fillRect(40, 96 + i * 7 + Math.sin(t \/ 15 + i) * 0.8, 180, 7); }); ctx.strokeStyle = '#5a3a1c'; ctx.lineWidth = 3; ctx.beginPath(); ctx.moveTo(40, 92); ctx.lineTo(40, 150); ctx.stroke(); }&#10;    propFiesta(905, 520, id, t, pal);&#10;    if (ban) dibujarConfeti(t);&#10;    ctx.restore();&#10;}&#10;function dibujarFiestaBiblioteca(t) {&#10;    const F = fiestaActual(); if (!F) return;&#10;    const id = F.id, pal = PAL[id], b = BIBLIOTECA, cx = b.x + b.ancho \/ 2, base = SUELO_Y + 55;&#10;    const sy = base - b.alto - b.ancho * 0.3 - 24, py = base - b.alto * 0.3;                 \/\/ y del cartel y de la puerta&#10;    ctx.save();&#10;    if (id === '28j') {                                                                         \/\/ bandera arco\u00edris sobre el cartel&#10;        ctx.strokeStyle = '#5a3a1c'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(cx - 20, sy); ctx.lineTo(cx - 20, sy - 30); ctx.stroke();&#10;        pal.forEach((c, i) =&gt; { ctx.fillStyle = c; ctx.fillRect(cx - 20, sy - 30 + i * 4 + Math.sin(t \/ 12 + i) * 0.8, 36, 4); });&#10;    } else mTxt({ navidad: '\u2b50', carnaval: '\ud83c\udf8a', sanjuan: '\ud83c\udfee', halloween: '\ud83e\udd87', astenagusia: '\ud83c\udf86', m8: '\ud83d\udc9c', n25: '\ud83c\udf97\ufe0f', feria: '\ud83c\udfee', santjordi: '\ud83c\udf39' }[id], cx, sy - 10, 20, '#000', 'center');&#10;    if (id === 'navidad') {                                                                     \/\/ corona de Adviento en la puerta&#10;        ctx.strokeStyle = '#2e7d32'; ctx.lineWidth = 5; ctx.beginPath(); ctx.arc(cx, py, 8, 0, Math.PI * 2); ctx.stroke();&#10;        ctx.fillStyle = '#e53935'; [0, 1.6, 3.2, 4.8].forEach(a =&gt; { ctx.beginPath(); ctx.arc(cx + Math.cos(a) * 8, py + Math.sin(a) * 8, 2, 0, Math.PI * 2); ctx.fill(); });&#10;        ctx.fillRect(cx - 3, py + 7, 6, 4);&#10;    } else mTxt({ carnaval: '\ud83c\udfad', sanjuan: '\ud83c\udf3c', '28j': '\ud83c\udff3\ufe0f\u200d\ud83c\udf08', halloween: '\ud83d\udd78\ufe0f', astenagusia: '\ud83c\udf86', m8: '\ud83d\udc9c', n25: '\ud83c\udf97\ufe0f', feria: '\ud83c\udf3a', santjordi: '\ud83c\udf39' }[id], cx, py, 14, '#000', 'center');&#10;    if (id === 'carnaval') for (let k = 0; k &lt; 7; k++) {                                        \/\/ cintas colgando del cartel&#10;        const x = b.x - 4 + k * 16, l = 14 + (k % 3) * 6; ctx.strokeStyle = pal[k % pal.length]; ctx.lineWidth = 2.5;&#10;        ctx.beginPath(); ctx.moveTo(x, sy + 24); ctx.quadraticCurveTo(x + Math.sin(t \/ 15 + k) * 4, sy + 24 + l \/ 2, x + Math.sin(t \/ 12 + k) * 3, sy + 24 + l); ctx.stroke();&#10;    }&#10;    mTxt({ navidad: '\ud83c\udf84', carnaval: '\ud83c\udfad', sanjuan: '\ud83c\udfee', '28j': '\ud83c\udff3\ufe0f\u200d\ud83c\udf08', halloween: '\ud83c\udf83', astenagusia: '\ud83c\udf86', m8: '\ud83d\udc9c', n25: '\ud83c\udf97\ufe0f', feria: '\ud83d\udc83', santjordi: '\ud83d\udcd6' }[id], BIBLIOTECA_MESA.x + 16, BIBLIOTECA_MESA.y - 12, 12, '#000', 'center');   \/\/ mesa de lectura&#10;    ctx.restore();&#10;}&#10;function dibujarFiestaCocina(t) {&#10;    const F = fiestaActual(); if (!F) return;&#10;    const id = F.id, pal = PAL[id], x0 = DERECHA_X + 10, an = DERECHA_ANCHO - 20, al = canvas.height * 0.42;&#10;    const encY = 20 + al * 0.55;                                                  \/\/ superficie de la encimera&#10;    ctx.save(); ctx.strokeStyle = '#000'; ctx.lineWidth = 1.5;&#10;    if (id === 'navidad') {&#10;        const rx = x0 + an * 0.5, ry = encY - 5;                                 \/\/ rosc\u00f3n de Reyes&#10;        ctx.fillStyle = '#e0a050'; ctx.beginPath(); ctx.ellipse(rx, ry, 17, 8, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;        ctx.fillStyle = '#d9a066'; ctx.beginPath(); ctx.ellipse(rx, ry, 6, 3, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;        for (let k = 0; k &lt; 8; k++) { const a = k \/ 8 * Math.PI * 2; ctx.fillStyle = ['#e53935', '#43a047', '#fdd835', '#ff9800'][k % 4]; ctx.beginPath(); ctx.arc(rx + Math.cos(a) * 11.5, ry + Math.sin(a) * 5.2, 1.9, 0, Math.PI * 2); ctx.fill(); }&#10;        ctx.fillStyle = 'rgba(255,255,255,0.85)'; for (let k = 0; k &lt; 10; k++) { ctx.beginPath(); ctx.arc(rx + Math.cos(k * 2.1) * 14, ry + Math.sin(k * 2.1) * 6.5, 0.9, 0, Math.PI * 2); ctx.fill(); }   \/\/ az\u00facar&#10;        const sx = x0 + 26, sy = 20 + al;                                       \/\/ silla con el gorrito colgado&#10;        ctx.fillStyle = '#a5703a'; ctx.lineWidth = 2;&#10;        [[1, -52, 4, 36], [21, -52, 4, 36], [1, -17, 4, 17], [21, -17, 4, 17], [0, -22, 26, 5], [1, -52, 24, 5]].forEach(([dx, dy, w, h]) =&gt; { ctx.fillRect(sx + dx, sy + dy, w, h); ctx.strokeRect(sx + dx, sy + dy, w, h); });&#10;        ctx.fillStyle = '#e53935'; ctx.beginPath(); ctx.moveTo(sx + 4, sy - 47); ctx.lineTo(sx + 22, sy - 47); ctx.lineTo(sx + 16 + Math.sin(t \/ 40) * 1.5, sy - 24); ctx.closePath(); ctx.fill(); ctx.stroke();&#10;        ctx.fillStyle = '#fff'; ctx.fillRect(sx + 3, sy - 50, 20, 5); ctx.strokeRect(sx + 3, sy - 50, 20, 5);&#10;        ctx.beginPath(); ctx.arc(sx + 16 + Math.sin(t \/ 40) * 1.5, sy - 23, 3.5, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    } else if (id === 'carnaval') {&#10;        const wx = x0 + an * 0.32, wy = 30, ww = 70, wh = 48;                    \/\/ ventana + banderines mini&#10;        ctx.fillStyle = esDeDia() ? '#bfe6ff' : '#1d2a4a'; ctx.fillRect(wx, wy, ww, wh);&#10;        ctx.strokeStyle = '#8a5a2b'; ctx.lineWidth = 3; ctx.strokeRect(wx, wy, ww, wh);&#10;        ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(wx + ww \/ 2, wy); ctx.lineTo(wx + ww \/ 2, wy + wh); ctx.moveTo(wx, wy + wh \/ 2); ctx.lineTo(wx + ww, wy + wh \/ 2); ctx.stroke();&#10;        guirnalda(wx + 2, wx + ww - 2, wy + 5, pal, t, true);&#10;    } else if (id === 'sanjuan') {&#10;        const cx = x0 + 22, cy = encY - 8;                                       \/\/ coca de San Juan&#10;        ctx.fillStyle = '#e6b86a'; ctx.beginPath(); ctx.roundRect ? ctx.roundRect(cx - 19, cy - 6, 38, 13, 4) : ctx.rect(cx - 19, cy - 6, 38, 13); ctx.fill(); ctx.stroke();&#10;        ctx.fillStyle = 'rgba(255,255,255,0.9)'; ctx.fillRect(cx - 17, cy - 4, 34, 2);                                           \/\/ az\u00facar&#10;        [[-12, '#e53935'], [-4, '#43a047'], [4, '#e53935'], [12, '#43a047']].forEach(([dx, c]) =&gt; { ctx.fillStyle = c; ctx.beginPath(); ctx.arc(cx + dx, cy, 2.2, 0, Math.PI * 2); ctx.fill(); });   \/\/ fruta escarchada&#10;        ctx.fillStyle = '#fff1c8'; [-8, 0, 8].forEach(dx =&gt; { ctx.beginPath(); ctx.ellipse(cx + dx, cy + 3.5, 1.6, 1, 0, 0, Math.PI * 2); ctx.fill(); });    \/\/ pi\u00f1ones&#10;    } else if (id === 'halloween') {                                                \/\/ calabaza tallada sobre la encimera&#10;        const cx = x0 + an * 0.5, cy = encY - 14; ctx.fillStyle = '#ff7518'; ctx.beginPath(); ctx.ellipse(cx, cy, 14, 11, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;        ctx.fillStyle = '#4a1d6a'; ctx.fillRect(cx - 2, cy - 15, 4, 5); ctx.fillStyle = '#ffd54a'; [-5, 5].forEach(ox =&gt; { ctx.beginPath(); ctx.moveTo(cx + ox - 3, cy - 2); ctx.lineTo(cx + ox + 3, cy - 2); ctx.lineTo(cx + ox, cy - 7); ctx.fill(); });&#10;        ctx.beginPath(); ctx.arc(cx, cy + 3, 6, 0.1 * Math.PI, 0.9 * Math.PI); ctx.lineWidth = 2; ctx.strokeStyle = '#ffd54a'; ctx.stroke();&#10;    } else if (id === '28j') {&#10;        const px = x0 + an * 0.42, py = 20 + al * 0.75 + 2, sw = Math.sin(t \/ 40) * 1.2;   \/\/ pa\u00f1o arco\u00edris colgado de la puerta del mueble&#10;        ctx.fillStyle = '#8a8a8a'; ctx.fillRect(px - 4, py, 30, 3);&#10;        pal.forEach((c, i) =&gt; { ctx.fillStyle = c; ctx.fillRect(px + sw * (i \/ 6), py + 3 + i * 6, 22, 6); });&#10;        ctx.strokeStyle = '#000'; ctx.strokeRect(px + sw \/ 2, py + 3, 22, 36);&#10;    }&#10;    ctx.restore();&#10;}&#10;function dibujarFiestaBa\u00f1o(t) {&#10;    const F = fiestaActual(); if (!F) return;&#10;    const id = F.id, pal = PAL[id], bx = DERECHA_X + 10, by = canvas.height * 0.5 + 10, bw = DERECHA_ANCHO - 20, bh = canvas.height * 0.42;&#10;    ctx.save();&#10;    if (id === 'navidad' || id === '28j') {                                                  \/\/ alfombrilla delante de la ba\u00f1era&#10;        const mx = bx + bw * 0.31, my = by + bh * 0.88, w = 76, h = 15;&#10;        ctx.lineWidth = 2; ctx.strokeStyle = '#000';&#10;        if (id === 'navidad') {&#10;            ctx.fillStyle = '#c62828'; ctx.beginPath(); ctx.roundRect ? ctx.roundRect(mx - w \/ 2, my, w, h, 5) : ctx.rect(mx - w \/ 2, my, w, h); ctx.fill(); ctx.stroke();&#10;            ctx.fillStyle = '#fff'; ctx.fillRect(mx - w \/ 2 + 6, my + 6, w - 12, 3); ctx.strokeStyle = '#ffc107'; ctx.lineWidth = 1.5; ctx.strokeRect(mx - w \/ 2 + 3, my + 3, w - 6, h - 6);&#10;            ctx.fillStyle = '#ffc107'; [-1, 1].forEach(s =&gt; { ctx.beginPath(); ctx.arc(mx + s * 22, my + h \/ 2, 2.2, 0, Math.PI * 2); ctx.fill(); });&#10;        } else {&#10;            pal.forEach((c, i) =&gt; { ctx.fillStyle = c; ctx.fillRect(mx - w \/ 2, my + i * (h \/ 6), w, h \/ 6 + 0.5); }); ctx.strokeRect(mx - w \/ 2, my, w, h);&#10;        }&#10;        ctx.strokeStyle = 'rgba(0,0,0,0.5)'; ctx.lineWidth = 1; ctx.beginPath(); for (let k = 0; k &lt;= 12; k++) { const x = mx - w \/ 2 + k * w \/ 12; ctx.moveTo(x, my + h); ctx.lineTo(x, my + h + 3); } ctx.stroke();   \/\/ flecos&#10;    }&#10;    ctx.beginPath(); ctx.rect(bx, by, bw, bh); ctx.clip();                                   \/\/ las pompas no salen del ba\u00f1o&#10;    for (let i = 0; i &lt; 14; i++) {&#10;        const r = 4 + (i % 4) * 2.2, y = by + bh - 8 - ((t * 0.3 * (0.6 + (i % 3) * 0.25) + i * 47) % (bh - 40)), x = bx + 14 + (i * 61) % (bw - 28) + Math.sin(t \/ 35 + i * 1.7) * 9;&#10;        let fill, stroke, glow = null;&#10;        if (id === 'navidad') { const rojo = i % 2 === 0; fill = rojo ? 'rgba(229,57,53,0.2)' : 'rgba(255,193,7,0.22)'; stroke = rojo ? 'rgba(229,57,53,0.9)' : 'rgba(255,193,7,0.95)'; }&#10;        else if (id === 'sanjuan') { fill = 'rgba(255,210,80,0.3)'; stroke = 'rgba(255,225,120,0.95)'; glow = '#ffb300'; }&#10;        else { const h = id === '28j' ? (i * 40 + t * 2) % 360 : id === 'halloween' ? [28, 275, 100, 28][i % 4] : [330, 55, 185, 280, 35][i % 5]; fill = `hsla(${h},90%,60%,0.2)`; stroke = `hsla(${h},90%,60%,0.9)`; }&#10;        ctx.save(); if (glow) { ctx.shadowColor = glow; ctx.shadowBlur = 12; }&#10;        ctx.fillStyle = fill; ctx.strokeStyle = stroke; ctx.lineWidth = 1.5; ctx.beginPath(); ctx.arc(x, y, r, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.restore();&#10;        ctx.fillStyle = 'rgba(255,255,255,0.8)'; ctx.beginPath(); ctx.arc(x - r * 0.35, y - r * 0.35, r * 0.22, 0, Math.PI * 2); ctx.fill();            \/\/ brillo&#10;        if (id === 'carnaval') for (let k = 0; k &lt; 2; k++) {                                   \/\/ purpurina&#10;            if (Math.sin(t \/ 6 + i * 3 + k * 2) &gt; 0) { const gx = x + (k ? 0.4 : -0.3) * r, gy = y + (k ? -0.3 : 0.4) * r; ctx.strokeStyle = k ? '#fff' : '#ffeb3b'; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(gx - 2.5, gy); ctx.lineTo(gx + 2.5, gy); ctx.moveTo(gx, gy - 2.5); ctx.lineTo(gx, gy + 2.5); ctx.stroke(); }&#10;        }&#10;        if (id === 'sanjuan') for (let k = 0; k &lt; 3; k++) {                                    \/\/ chispas de fuego alrededor&#10;            const a = t \/ 10 + k * 2.1 + i, d = r + 4 + Math.sin(t \/ 7 + k + i) * 2.5;&#10;            ctx.fillStyle = `rgba(${k % 2 ? '255,235,59' : '255,120,0'},${0.4 + 0.6 * Math.abs(Math.sin(t \/ 5 + k + i))})`; ctx.beginPath(); ctx.arc(x + Math.cos(a) * d, y + Math.sin(a) * d, 1.3, 0, Math.PI * 2); ctx.fill();&#10;        }&#10;    }&#10;    ctx.restore();&#10;}&#10;const INCLUIR_HAURTXO = true;&#10;const INCLUIR_MARIJAIA = true;&#10;const Fiestas = (() =&gt; {&#10;    let gain = null, timer = null, tema = null, drones = [], proximo = 0, paso = 0, p = 0, cancion = 0, proxIrr = 0, buf = null, inicio = 0;&#10;    const hz = m =&gt; 440 * Math.pow(2, (m - 69) \/ 12), AVISO = 0.15, ahora = () =&gt; audioCtx.currentTime;&#10;    const salida = () =&gt; { if (!gain) { gain = audioCtx.createGain(); gain.gain.value = 0; gain.connect(masterGain); } return gain; };&#10;    const tono = (f, t, d, tipo, v) =&gt; { const o = audioCtx.createOscillator(), g = audioCtx.createGain(); o.type = tipo; o.frequency.setValueAtTime(f, t);&#10;        g.gain.setValueAtTime(0.0001, t); g.gain.exponentialRampToValueAtTime(v, t + 0.012); g.gain.exponentialRampToValueAtTime(0.0001, t + d);&#10;        o.connect(g); g.connect(salida()); o.start(t); o.stop(t + d + 0.05); };&#10;    const ruido = (t, d, hp, v) =&gt; { buf = buf || crearBufferRuido(0.6); const s = audioCtx.createBufferSource(), f = audioCtx.createBiquadFilter(), g = audioCtx.createGain();&#10;        s.buffer = buf; f.type = 'highpass'; f.frequency.value = hp; g.gain.setValueAtTime(v, t); g.gain.exponentialRampToValueAtTime(0.0001, t + d);&#10;        s.connect(f); f.connect(g); g.connect(salida()); s.start(t, Math.random() * 0.4, d); };&#10;    const bombo = (t, v, f0, f1, d) =&gt; { const o = audioCtx.createOscillator(), g = audioCtx.createGain(); o.frequency.setValueAtTime(f0, t); o.frequency.exponentialRampToValueAtTime(f1, t + 0.12);&#10;        g.gain.setValueAtTime(v, t); g.gain.exponentialRampToValueAtTime(0.0001, t + d); o.connect(g); g.connect(salida()); o.start(t); o.stop(t + d + 0.02); };&#10;    const sonar = fn =&gt; { while (proximo &lt; ahora() + AVISO) { fn(proximo); } };&#10;    const NOCHE_DE_PAZ = [[67,3],[69,1],[67,2],[64,6],[67,3],[69,1],[67,2],[64,6],[74,6],[74,2],[71,4],[72,6],[72,2],[67,4],[69,3],[69,1],[72,2],[71,3],[69,3],[67,3],[69,1],[67,2],[64,6],&#10;        [69,3],[69,1],[72,2],[71,3],[69,3],[67,3],[69,1],[67,2],[64,6],[74,3],[74,1],[77,2],[74,3],[71,3],[72,6],[76,6],[72,4],[67,4],[64,4],[67,4],[65,4],[62,4],[60,12]];&#10;    const F_ = { b: 41, p: [53, 57, 60] }, BB = { b: 46, p: [58, 62, 65] }, C7 = { b: 48, p: [52, 55, 58] };                \/\/ fa, si\u266d y do7&#10;    const AUR_SEGMENTOS = [{ at: 0, len: 10, ac: F_ }, { at: 10, len: 12, ac: BB }, { at: 22, len: 10, ac: F_ }, { at: 32, len: 8, ac: C7 }, { at: 40, len: 8, ac: F_ },     \/\/ frase 1: F-Bb \u00b7 frase 2: F-C7-F&#10;        { at: 48, len: 26, ac: C7 }, { at: 74, len: 24, ac: C7 },                                                                                                      \/\/ frases 3 y 4: C7&#10;        { at: 98, len: 6, ac: F_ }, { at: 104, len: 6, ac: BB }, { at: 110, len: 6, ac: C7 }, { at: 116, len: 6, ac: F_ }];                                              \/\/ frase 5: F-Bb-C7-F&#10;    const MIDI = n =&gt; { const m = \/^([A-G])(#|b)?(\\d)$\/.exec(n); return 12 * (+m[3] + 1) + { C: 0, D: 2, E: 4, F: 5, G: 7, A: 9, B: 11 }[m[1]] + (m[2] === '#' ? 1 : m[2] === 'b' ? -1 : 0); };   \/\/ 'Bb4' \u2192 70&#10;    const HAURTXO_POLITA = [                                                                         \/\/ duration en dieciseisavos: corchea=2, negra=4, blanca=8, blanca con puntillo=12&#10;        { note: 'F4', duration: 2 }, { note: 'G4', duration: 2 }, { note: 'A4', duration: 4 }, { note: 'A4', duration: 2 },&#10;        { note: 'Bb4', duration: 2 }, { note: 'A4', duration: 2 }, { note: 'G4', duration: 4 }, { note: 'F4', duration: 4 },&#10;        { note: 'F4', duration: 2 }, { note: 'A4', duration: 2 }, { note: 'C5', duration: 4 }, { note: 'A4', duration: 2 },&#10;        { note: 'G4', duration: 2 }, { note: 'F4', duration: 2 }, { note: 'G4', duration: 12 },&#10;        { note: 'C5', duration: 4 }, { note: 'Bb4', duration: 2 }, { note: 'A4', duration: 4 }, { note: 'G4', duration: 2 },&#10;        { note: 'A4', duration: 4 }, { note: 'Bb4', duration: 2 }, { note: 'C5', duration: 8 },&#10;        { note: 'C5', duration: 2 }, { note: 'C5', duration: 2 }, { note: 'D5', duration: 2 }, { note: 'C5', duration: 2 }, { note: 'Bb4', duration: 2 }, { note: 'A4', duration: 2 },&#10;        { note: 'G4', duration: 4 }, { note: 'F4', duration: 2 }, { note: 'G4', duration: 4 }, { note: 'A4', duration: 2 },&#10;        { note: 'F4', duration: 2 }, { note: 'G4', duration: 2 }, { note: 'A4', duration: 2 }, { note: 'Bb4', duration: 2 }, { note: 'A4', duration: 2 }, { note: 'G4', duration: 2 },&#10;        { note: 'F4', duration: 12 }&#10;    ].map(({ note, duration }) =&gt; [MIDI(note), duration]);                                          \/\/ \u2192 [midi, duraci\u00f3n] para el secuenciador&#10;    const G_ = { b: 43, p: [55, 59, 62] }, D7 = { b: 50, p: [54, 57, 60] }, C_ = { b: 48, p: [52, 55, 60] };                \/\/ sol, re7 y do&#10;    const HAT_SEGMENTOS = [{ at: 0, len: 16, ac: G_ }, { at: 16, len: 8, ac: D7 }, { at: 24, len: 8, ac: G_ },                                              \/\/ frase 1&#10;        { at: 32, len: 12, ac: G_ }, { at: 44, len: 4, ac: D7 }, { at: 48, len: 8, ac: C_ }, { at: 56, len: 8, ac: G_ },                                           \/\/ frase 2&#10;        { at: 64, len: 12, ac: G_ }, { at: 76, len: 4, ac: C_ }, { at: 80, len: 16, ac: D7 }, { at: 96, len: 12, ac: G_ }];                                       \/\/ frase 3 \/ cierre&#10;    const HATOR_HATOR = [[67,4],[71,4],[74,4],[74,4], [72,2],[71,2],[69,4],[67,8],                  \/\/ frase 1 (negra=4, corchea=2, blanca=8, blanca con puntillo=12 dieciseisavos)&#10;        [71,4],[74,4],[79,4],[78,4], [76,2],[74,2],[72,4],[71,8],                                  \/\/ frase 2&#10;        [67,4],[71,4],[74,4],[76,4], [74,2],[72,2],[71,4],[69,8], [67,12]];                        \/\/ frase 3 \/ cierre&#10;    const vals = (b0, ac, len = 12) =&gt; [{ at: b0, tipo: 'b', m: ac.b }, ...[3, 6, 9].filter(o =&gt; o &lt; len).map((o, i) =&gt; ({ at: b0 + o, tipo: 'a', m: ac.p[i % 3] }))];                              \/\/ \u00abun-dos-tres\u00bb en 6\/8&#10;    const marchaSeg = (at, len, ac) =&gt; [{ at, tipo: 'b', m: ac.b }, ...[4, 8, 12].filter(o =&gt; o &lt; len).flatMap(o =&gt; (at + o) % 8 === 0 ? [{ at: at + o, tipo: 'b', m: ac.b }] : ac.p.map(m =&gt; ({ at: at + o, tipo: 'a', m })))];   \/\/ bajo en los tiempos 1 y 3, acordes en 2 y 4&#10;    function compilar(c) {                                                                                                  \/\/ melod\u00eda + acompa\u00f1amiento \u2192 l\u00ednea de tiempo&#10;        const ev = []; let at = 0; c.n.forEach(([m, d]) =&gt; { if (m) ev.push({ at, tipo: 'm', m: m + c.tr, d }); at += d; });&#10;        if (c.segmentos) c.segmentos.forEach(sg =&gt; ev.push(...(c.patronSeg || vals)(sg.at, sg.ac, sg.len)));                                   \/\/ acordes por frases&#10;        if (c.acordes) c.acordes.forEach((ac, i) =&gt; ev.push(...c.patron(i * c.barLen, ac)));&#10;        ev.sort((a, b) =&gt; a.at - b.at); return { ...c, ev, len: at };&#10;    }&#10;    const MEDLEY = [{ n: NOCHE_DE_PAZ, s: 0.19, tr: 2, barLen: 12 }, { n: HAURTXO_POLITA, s: 0.22, tr: 0, segmentos: AUR_SEGMENTOS },&#10;                    { n: HATOR_HATOR, s: 0.15, tr: 0, segmentos: HAT_SEGMENTOS, patronSeg: marchaSeg }].filter(c =&gt; INCLUIR_HAURTXO || c.n !== HAURTXO_POLITA).map(compilar);&#10;    function progNavidad() {&#10;        sonar(t =&gt; { const c = MEDLEY[cancion], e = c.ev[p];&#10;            if (e.tipo === 'm') { const f = hz(e.m); tono(f, t, Math.min(1.6, e.d * c.s + 0.5), 'triangle', 0.17); tono(f * 2, t, 0.5, 'sine', 0.05); }   \/\/ caja de m\u00fasica&#10;            else if (e.tipo === 'b') { tono(hz(e.m), t, 0.9, 'triangle', 0.12); ruido(t, 0.04, 8000, 0.03); }                                           \/\/ bajo + cascabel suave&#10;            else tono(hz(e.m), t, 0.7, 'sine', 0.06);                                                                                                  \/\/ acompa\u00f1amiento&#10;            if (++p &gt;= c.ev.length) { inicio += c.len * c.s + 1.2; cancion = (cancion + 1) % MEDLEY.length; p = 0; proximo = inicio + MEDLEY[cancion].ev[0].at * MEDLEY[cancion].s; }&#10;            else proximo = inicio + c.ev[p].at * c.s; });&#10;    }&#10;    const TAM = [1,0,0,1,0,0,1,0,1,0,1,0,0,1,0,0], AGO = { 0: 900, 3: 680, 6: 900, 8: 680, 11: 900, 14: 680 }, BAJO = { 0: 98, 6: 98, 10: 98, 12: 147 };&#10;    const RIFF_A = { 0: 67, 3: 69, 6: 71, 8: 74, 11: 71, 14: 69 }, RIFF_B = { 0: 74, 3: 72, 6: 71, 8: 69, 11: 71, 14: 67 };&#10;    function progSamba() {&#10;        sonar(t =&gt; { const s = paso % 16, riff = (Math.floor(paso \/ 16) % 2) ? RIFF_B : RIFF_A;&#10;            if (s === 4 || s === 12) bombo(t, 0.55, 110, 42, 0.3); else if (s === 0 || s === 8) bombo(t, 0.22, 90, 50, 0.15);               \/\/ surdo&#10;            if (TAM[s]) { ruido(t, 0.05, 2500, 0.15); tono(1800, t, 0.03, 'sine', 0.05); }                                                  \/\/ tamborim sincopado&#10;            ruido(t, 0.035, 7000, s % 4 === 0 ? 0.09 : 0.045);                                                                              \/\/ ganz\u00e1&#10;            if (AGO[s]) tono(AGO[s], t, 0.12, 'square', 0.045);                                                                             \/\/ agog\u00f4&#10;            if (BAJO[s]) tono(BAJO[s], t, 0.18, 'triangle', 0.2);&#10;            if (riff[s]) tono(hz(riff[s]), t, 0.13, 'square', 0.07);&#10;            proximo += 60 \/ 104 \/ 4; paso++; });&#10;    }&#10;    function irrintzi(t, v) {&#10;        const o = audioCtx.createOscillator(), g = audioCtx.createGain(), l = audioCtx.createOscillator(), lg = audioCtx.createGain();&#10;        o.frequency.setValueAtTime(650, t); o.frequency.linearRampToValueAtTime(1450, t + 0.3); o.frequency.linearRampToValueAtTime(1750, t + 0.8); o.frequency.linearRampToValueAtTime(900, t + 1.3);&#10;        l.frequency.value = 12; lg.gain.value = 55; l.connect(lg); lg.connect(o.frequency);&#10;        g.gain.setValueAtTime(0.0001, t); g.gain.linearRampToValueAtTime(v, t + 0.1); g.gain.setValueAtTime(v, t + 1.0); g.gain.linearRampToValueAtTime(0.0001, t + 1.35);&#10;        o.connect(g); g.connect(salida()); o.start(t); l.start(t); o.stop(t + 1.4); l.stop(t + 1.4);&#10;    }&#10;    function bordon() {&#10;        const f = audioCtx.createBiquadFilter(), g = audioCtx.createGain(), l = audioCtx.createOscillator(), lg = audioCtx.createGain();&#10;        f.type = 'lowpass'; f.frequency.value = 340; g.gain.value = 0.06; l.frequency.value = 0.15; lg.gain.value = 120; l.connect(lg); lg.connect(f.frequency); f.connect(g); g.connect(salida()); l.start(); drones.push(l);&#10;        [73.4, 110.2, 146.9].forEach((fr, i) =&gt; { const o = audioCtx.createOscillator(); o.type = 'sawtooth'; o.frequency.value = fr * (1 + i * 0.002); o.connect(f); o.start(); drones.push(o); });&#10;    }&#10;    function progAkelarre() {&#10;        sonar(t =&gt; { const s = paso % 16, d = 60 \/ 92 \/ 4;&#10;            if (s % 4 === 0) bombo(t, s === 0 ? 0.5 : 0.34, 130, 60, 0.18);                                                                 \/\/ pandero grave, constante&#10;            if (s % 4 === 2) ruido(t, 0.09, 4500, 0.11); else if (s % 2) ruido(t, 0.03, 7000, 0.035);                                       \/\/ sonajas&#10;            if (Math.random() &lt; 0.18) ruido(t + Math.random() * d, 0.02, 3500, 0.05);                                                       \/\/ chasquidos de la hoguera&#10;            if (s === 0 &amp;&amp; (paso \/ 16) % 2 === 0 &amp;&amp; Math.random() &lt; 0.7) [62, 64, 65, 69, 67, 65, 64].slice(0, 4 + Math.floor(Math.random() * 3)).forEach((m, k) =&gt; tono(hz(m + 12), t + k * d * 2, 0.5, 'sine', 0.07));   \/\/ flauta modal&#10;            if (t &gt;= proxIrr) { irrintzi(t, 0.12); irrintzi(t + 2.4, 0.06); proxIrr = t + 9 + Math.random() * 8; }                            \/\/ llamada y eco&#10;            proximo += d; paso++; });&#10;    }&#10;    const RAIZ = [48, 43, 45, 41], TERC = [4, 4, 3, 4];&#10;    function prog28j() {&#10;        sonar(t =&gt; { const s = paso % 16, b = Math.floor(paso \/ 16) % 4, r = RAIZ[b], q = TERC[b];&#10;            if (s % 2 === 0) { const m = r + 12 + [0, q, 7, 12, 12 + q, 19, 24, 24 + q][s \/ 2]; tono(hz(m), t, 0.9, 'sine', 0.13); tono(hz(m) * 2, t, 0.5, 'triangle', 0.04); }   \/\/ arpegio campanilla&#10;            if (s === 0) { tono(hz(r), t, 60 \/ 126 * 4, 'triangle', 0.07); tono(hz(r + 7), t, 60 \/ 126 * 4, 'triangle', 0.04); }              \/\/ colch\u00f3n&#10;            if (s % 4 === 2) ruido(t, 0.03, 6500, 0.04);                                                                                     \/\/ pandereta&#10;            if (s === 0 &amp;&amp; b % 2 === 1) [0, 3, 7].forEach((k, i) =&gt; tono(hz(96 + k), t + i * 0.07, 0.4, 'sine', 0.05));                       \/\/ destellos&#10;            proximo += 60 \/ 126 \/ 4; paso++; });&#10;    }&#10;    const GAU_MEL = [[69,4],[74,4],[77,4],[76,6],[74,3],[73,3],[74,4],[70,4],[69,4],[67,8],[0,4],&#10;        [69,4],[74,4],[77,4],[81,6],[79,3],[77,3],[76,4],[73,4],[76,4],[74,12],&#10;        [77,4],[81,4],[84,4],[83,6],[81,3],[79,3],[77,4],[76,4],[74,4],[73,8],[0,4]];          \/\/ 12 compases de 12 dieciseisavos&#10;    const GAU_RAIZ = [38,38,34,45,38,38,43,38,41,41,43,45], GAU_INICIO = {};                    \/\/ ra\u00edz de cada comp\u00e1s&#10;    (() =&gt; { let c = 0; GAU_MEL.forEach(([m, d]) =&gt; { if (m) GAU_INICIO[c] = [m, d]; c += d; }); })();&#10;    function progGauBeltza() {&#10;        sonar(t =&gt; { const s = paso % 144, bar = Math.floor(s \/ 12), st = s % 12, d = 0.18, r = GAU_RAIZ[bar];&#10;            if (GAU_INICIO[s]) { const [m, n] = GAU_INICIO[s], f = hz(m); tono(f, t, n * d + 0.8, 'sine', 0.13); tono(f * 2, t, 0.9, 'triangle', 0.04); tono(f * 3, t, 0.4, 'sine', 0.012); }   \/\/ celesta&#10;            if (st === 0) tono(hz(r), t, 0.9, 'triangle', 0.2);                                                         \/\/ 1.er tiempo: ra\u00edz grave&#10;            if (st === 4 || st === 8) { tono(hz(r + 19), t, 0.5, 'sine', 0.05); tono(hz(r + 24), t, 0.5, 'triangle', 0.035); }   \/\/ quintas huecas (vals)&#10;            if (st === 0 &amp;&amp; bar % 2 === 0) tono(hz(r + 12), t, 4.3, 'triangle', 0.05);                                  \/\/ colch\u00f3n lento&#10;            if (st === 0 &amp;&amp; bar % 4 === 3) [88, 91, 93, 96].slice(0, 3).forEach((m, i) =&gt; tono(hz(m + Math.floor(Math.random() * 3)), t + i * 0.07, 0.35, 'sine', 0.035));   \/\/ destellos m\u00e1gicos&#10;            if (st === 0 &amp;&amp; bar % 3 === 0) ruido(t, 2.2, 500, 0.018);                                                   \/\/ r\u00e1faga de viento oto\u00f1al&#10;            proximo += d; paso++; });&#10;    }&#10;    const ACORDES_AN = [{ r: 43, p: [55, 59, 62] }, { r: 48, p: [55, 60, 64] }, { r: 50, p: [54, 57, 62] }, { r: 43, p: [55, 59, 62] }];&#10;    const MEL_AN = [[79,0,0,0,83,0,81,0,79,0,0,0,76,0,74,0], [72,0,76,0,79,0,76,0,74,0,76,0,72,0,0,0], [74,0,0,0,78,0,81,0,79,0,78,0,74,0,0,0], [79,0,83,0,86,0,83,0,79,0,0,0,79,0,0,0]];&#10;    function progAste() {&#10;        sonar(t =&gt; { const s = paso % 16, bar = Math.floor(paso \/ 16), ac = ACORDES_AN[bar % 4], mel = MEL_AN[bar % 4];&#10;            if (s === 0 || s === 8) bombo(t, 0.5, 105, 40, 0.28);&#10;            if (s === 4 || s === 12) ruido(t, 0.09, 1800, 0.13); if (bar % 4 === 3 &amp;&amp; s &gt;= 13) ruido(t, 0.05, 2200, 0.09);&#10;            if (s === 0 || s === 8) tono(hz(ac.r - 12), t, 0.26, 'triangle', 0.2);&#10;            if (s === 4 || s === 12) ac.p.forEach(m =&gt; tono(hz(m), t, 0.14, 'sawtooth', 0.03));&#10;            if (mel[s]) tono(hz(mel[s]), t, 0.2, 'square', 0.05);&#10;            ruido(t, 0.03, 7000, 0.03);&#10;            if (s === 0 &amp;&amp; bar % 8 === 7) irrintzi(t + 0.1, 0.045);&#10;            proximo += 60 \/ 118 \/ 4; paso++; });&#10;    }&#10;    const ACORDES_8M = [{ r: 38, p: [50, 54, 57] }, { r: 43, p: [55, 59, 62] }, { r: 45, p: [57, 61, 64] }, { r: 38, p: [50, 54, 57] }];&#10;    const MEL_8M = [[74,0,0,0,78,0,81,0,0,0,81,0,79,0,78,0], [79,0,0,0,83,0,86,0,0,0,86,0,83,0,79,0], [81,0,0,0,85,0,88,0,0,0,88,0,85,0,81,0], [86,0,0,0,85,0,81,0,78,0,0,0,74,0,0,0]];&#10;    function prog8M() {&#10;        sonar(t =&gt; { const s = paso % 16, bar = Math.floor(paso \/ 16), ac = ACORDES_8M[bar % 4], mel = MEL_8M[bar % 4];&#10;            if (s === 0 || s === 8) bombo(t, 0.5, 100, 38, 0.22); if (s === 4 || s === 12) ruido(t, 0.08, 1700, 0.1);&#10;            if (s === 0 || s === 8) tono(hz(ac.r), t, 0.3, 'triangle', 0.16); if (s % 4 === 2) ac.p.forEach(m =&gt; tono(hz(m), t, 0.12, 'sawtooth', 0.02));&#10;            if (mel[s]) tono(hz(mel[s]), t, 0.28, 'triangle', 0.06);&#10;            proximo += 60 \/ 104 \/ 4; paso++; });&#10;    }&#10;    const ACORDES_25 = [{ r: 45, p: [57, 60, 64, 67] }, { r: 41, p: [53, 57, 60, 64] }, { r: 48, p: [52, 55, 59, 64] }, { r: 43, p: [55, 59, 62, 64] }];&#10;    function prog25N() {&#10;        sonar(t =&gt; { const s = paso % 32, ac = ACORDES_25[Math.floor(paso \/ 32) % 4]; proximo += 0.25; paso++;&#10;            if (Conmemoraciones.silencioReal()) return;&#10;            if (s === 0) { ac.p.forEach(m =&gt; tono(hz(m), t, 8, 'sine', 0.03)); tono(hz(ac.r), t, 7, 'triangle', 0.09); }&#10;            if (s % 8 === 4 &amp;&amp; Math.random() &lt; 0.7) tono(hz(ac.p[Math.floor(Math.random() * ac.p.length)] + 12), t, 2.4, 'sine', 0.035); });&#10;    }&#10;    const CF = [[57, 60, 64], [55, 59, 62], [53, 57, 60], [52, 56, 59]];&#10;    function progFeria() {&#10;        sonar(t =&gt; { const s = paso % 12, b = Math.floor(paso \/ 12) % 4, c = CF[b], d = 60 \/ 124 \/ 4;&#10;            if (s === 0) { c.forEach((m, k) =&gt; tono(hz(m + 12), t + k * 0.02, 0.5, 'triangle', 0.055)); tono(hz(c[0] - 12), t, 0.55, 'triangle', 0.09); }&#10;            if (s === 6) c.forEach((m, k) =&gt; tono(hz(m + 12), t + k * 0.015, 0.3, 'triangle', 0.04));&#10;            if (s === 3 || s === 9) tono(hz(c[2] + 12), t, 0.25, 'triangle', 0.04);&#10;            if (s % 3 === 0) ruido(t, 0.035, 3200, s === 0 ? 0.09 : 0.06);                                                              \/\/ palmas&#10;            proximo += d; paso++; });&#10;    }&#10;    const CJ = [[60, 64, 67], [55, 59, 62], [57, 60, 64], [53, 57, 60]];&#10;    function progJordi() {&#10;        sonar(t =&gt; { const s = paso % 12, b = Math.floor(paso \/ 12) % 4, c = CJ[b], d = 60 \/ 104 \/ 4;&#10;            if (s === 0) { tono(hz(c[0] - 12), t, 0.9, 'sine', 0.09); tono(hz(c[2] + 12), t, 0.7, 'sine', 0.05); }&#10;            if (s === 4) tono(hz(c[1] + 12), t, 0.7, 'sine', 0.045); if (s === 8) tono(hz(c[2] + 12), t, 0.7, 'sine', 0.045);&#10;            if (s === 6 &amp;&amp; Math.random() &lt; 0.5) tono(hz(c[1] + 24), t, 0.5, 'sine', 0.035);&#10;            proximo += d; paso++; });&#10;    }&#10;    const temas = { feria: progFeria, santjordi: progJordi, navidad: progNavidad, carnaval: progSamba, sanjuan: progAkelarre, '28j': prog28j, halloween: progGauBeltza, astenagusia: progAste, m8: prog8M, n25: prog25N };&#10;    function parar() { clearInterval(timer); timer = null; tema = null; drones.forEach(o =&gt; { try { o.stop(); } catch (e) {} }); drones = []; }&#10;    function iniciar(id) {&#10;        parar(); if (!temas[id]) return;&#10;        tema = id; paso = 0; p = 0; cancion = 0; proximo = ahora() + 0.1; inicio = proximo; proxIrr = proximo + 4;&#10;        if (id === 'sanjuan') bordon();&#10;        timer = setInterval(temas[id], 25);&#10;    }&#10;    return { iniciar, parar, salida, tema: () =&gt; tema, estallido() { if (tema !== 'astenagusia') return; const t = ahora() + 0.02; bombo(t, 0.5, 90, 28, 0.55); ruido(t, 0.5, 900, 0.1); ruido(t + 0.12, 0.35, 3500, 0.05); } };&#10;})();&#10;const Ambiente = (() =&gt; {&#10;    let gain = null, rev = null, timer = null, osc = [], nodos = [], acorde = 0, proxAcorde = 0, proxCampana = 0, proxGrillo = 0, proxBuho = 0;&#10;    const hz = m =&gt; 440 * Math.pow(2, (m - 69) \/ 12), ahora = () =&gt; audioCtx.currentTime, rnd = (a, b) =&gt; a + Math.random() * (b - a);&#10;    const ACORDES = [{ b: 45, p: [57, 60, 64, 71] }, { b: 41, p: [53, 57, 60, 64] }, { b: 48, p: [55, 59, 60, 64] }, { b: 43, p: [55, 59, 62, 64] }];&#10;    const PENTA = [69, 72, 74, 76, 79, 81, 84];                                       \/\/ la menor pentat\u00f3nica: encaja sobre los cuatro acordes&#10;    const salida = () =&gt; { if (!gain) { gain = audioCtx.createGain(); gain.gain.value = 0; gain.connect(masterGain); } return gain; };&#10;    function reverb() {                                                                 \/\/ reverberaci\u00f3n sint\u00e9tica (impulso de ruido que decae)&#10;        if (rev) return rev;&#10;        const sr = audioCtx.sampleRate, n = Math.floor(sr * 2.6), b = audioCtx.createBuffer(2, n, sr);&#10;        for (let c = 0; c &lt; 2; c++) { const d = b.getChannelData(c); for (let i = 0; i &lt; n; i++) d[i] = (Math.random() * 2 - 1) * Math.pow(1 - i \/ n, 2.5); }&#10;        const cv = audioCtx.createConvolver(), g = audioCtx.createGain(); cv.buffer = b; g.gain.value = 0.45; cv.connect(g); g.connect(salida()); return (rev = cv);&#10;    }&#10;    function enviar(nodo, wet) { nodo.connect(salida()); const s = audioCtx.createGain(); s.gain.value = wet; nodo.connect(s); s.connect(reverb()); }   \/\/ directo + env\u00edo a reverb&#10;    function suave(f, t, d, tipo, v, wet) {&#10;        const o = audioCtx.createOscillator(), g = audioCtx.createGain(); o.type = tipo; o.frequency.setValueAtTime(f, t);&#10;        g.gain.setValueAtTime(0.0001, t); g.gain.linearRampToValueAtTime(v, t + 0.03); g.gain.exponentialRampToValueAtTime(0.0001, t + d);&#10;        o.connect(g); enviar(g, wet); o.start(t); o.stop(t + d + 0.1);&#10;    }&#10;    const campana = t =&gt; { const m = PENTA[Math.floor(Math.random() * PENTA.length)]; suave(hz(m), t, 3.2, 'sine', 0.06, 0.8); suave(hz(m) * 2, t, 1.4, 'triangle', 0.015, 0.8);&#10;        if (Math.random() &lt; 0.25) suave(hz(m + 5), t + 0.35, 2.4, 'sine', 0.04, 0.8); };                                                \/\/ a veces, una segunda nota m\u00e1s aguda&#10;    function grillo(t) { const f = rnd(4300, 4900), n = 3 + Math.floor(Math.random() * 2);&#10;        for (let i = 0; i &lt; n; i++) { const o = audioCtx.createOscillator(), g = audioCtx.createGain(), s = t + i * 0.07; o.frequency.value = f;&#10;            g.gain.setValueAtTime(0.0001, s); g.gain.linearRampToValueAtTime(0.012, s + 0.008); g.gain.linearRampToValueAtTime(0.0001, s + 0.04); o.connect(g); g.connect(salida()); o.start(s); o.stop(s + 0.05); } }&#10;    function buho(t) { [[410, 360, 0], [380, 320, 0.55]].forEach(([a, b, dt]) =&gt; { const o = audioCtx.createOscillator(), g = audioCtx.createGain(), f = audioCtx.createBiquadFilter(), s = t + dt;&#10;        f.type = 'lowpass'; f.frequency.value = 900; o.frequency.setValueAtTime(a, s); o.frequency.linearRampToValueAtTime(b, s + 0.35);&#10;        g.gain.setValueAtTime(0.0001, s); g.gain.linearRampToValueAtTime(0.05, s + 0.08); g.gain.linearRampToValueAtTime(0.0001, s + 0.4); o.connect(f); f.connect(g); enviar(g, 0.8); o.start(s); o.stop(s + 0.45); }); }&#10;    function cambiarAcorde(t) { const A = ACORDES[acorde]; osc.forEach((o, i) =&gt; o.frequency.setTargetAtTime(hz(i === 0 ? A.b : A.p[i - 1]), t, 1.4)); }&#10;    function tick() {&#10;        const n = ahora();&#10;        if (n &gt;= proxAcorde) { acorde = (acorde + 1) % ACORDES.length; cambiarAcorde(n); proxAcorde = n + 8; }&#10;        while (proxCampana &lt; n + 0.4) { campana(Math.max(proxCampana, n)); proxCampana += rnd(1.4, 3.6); }&#10;        while (proxGrillo &lt; n + 0.4) { grillo(Math.max(proxGrillo, n)); proxGrillo += rnd(0.7, 1.8); }&#10;        if (n &gt;= proxBuho) { buho(n + 0.05); proxBuho = n + rnd(28, 55); }&#10;    }&#10;    function parar() { clearInterval(timer); timer = null; [...osc, ...nodos].forEach(o =&gt; { try { o.stop(); } catch (e) {} }); osc = []; nodos = []; }&#10;    function iniciar() {&#10;        parar(); const t = ahora(); acorde = 0;&#10;        const filtro = audioCtx.createBiquadFilter(), gp = audioCtx.createGain(); filtro.type = 'lowpass'; filtro.frequency.value = 900;     \/\/ colch\u00f3n de acordes&#10;        gp.gain.setValueAtTime(0.0001, t); gp.gain.linearRampToValueAtTime(1, t + 3); filtro.connect(gp); enviar(gp, 0.6);&#10;        [ACORDES[0].b, ...ACORDES[0].p].forEach((m, i) =&gt; { const o = audioCtx.createOscillator(), g = audioCtx.createGain(); o.type = i === 0 ? 'sine' : 'triangle'; o.frequency.value = hz(m);&#10;            g.gain.value = i === 0 ? 0.09 : 0.045; o.connect(g); g.connect(filtro); o.start(); osc.push(o); });&#10;        const sr = audioCtx.sampleRate, b = audioCtx.createBuffer(1, sr * 2, sr), d = b.getChannelData(0);                                  \/\/ viento lejano&#10;        for (let i = 0; i &lt; sr * 2; i++) d[i] = Math.random() * 2 - 1;&#10;        const v = audioCtx.createBufferSource(), vf = audioCtx.createBiquadFilter(), vg = audioCtx.createGain(), l = audioCtx.createOscillator(), lg = audioCtx.createGain();&#10;        v.buffer = b; v.loop = true; vf.type = 'lowpass'; vf.frequency.value = 450; vg.gain.value = 0.03; l.frequency.value = 0.07; lg.gain.value = 0.015;&#10;        l.connect(lg); lg.connect(vg.gain); v.connect(vf); vf.connect(vg); vg.connect(salida()); v.start(); l.start(); nodos.push(v, l);&#10;        proxAcorde = t + 8; proxCampana = t + 1.5; proxGrillo = t + 0.5; proxBuho = t + rnd(10, 20);&#10;        timer = setInterval(tick, 200);&#10;    }&#10;    return { iniciar, parar, salida };&#10;})();&#10;const Chiptune = (() =&gt; {&#10;    let gain = null, timer = null, proximo = 0, paso = 0, buf = null, ondas = null;&#10;    const hz = m =&gt; 440 * Math.pow(2, (m - 69) \/ 12), ahora = () =&gt; audioCtx.currentTime, AVISO = 0.15, D = 60 \/ 132 \/ 4;     \/\/ D = un dieciseisavo&#10;    const dens = o =&gt; Array.from({ length: 16 }, (_, i) =&gt; o[i] || 0);&#10;    const RAICES = [45, 41, 48, 43], BAJO = [0, 0, 12, 0, 0, 0, 12, 7];&#10;    const ACORDES = [[57, 60, 64, 69], [53, 57, 60, 65], [60, 64, 67, 72], [55, 59, 62, 67]], ARP = [0, 1, 2, 3, 2, 1, 2, 3];&#10;    const MEL_A = [{ 0: 81, 2: 84, 4: 88, 6: 84, 8: 81, 10: 76, 12: 81 }, { 0: 77, 2: 81, 4: 84, 6: 81, 8: 77, 10: 72, 12: 77, 14: 76 },&#10;                   { 0: 79, 2: 76, 4: 79, 6: 84, 8: 88, 10: 84, 12: 79 }, { 0: 86, 2: 83, 4: 79, 6: 83, 8: 86, 10: 88, 12: 86, 14: 83 }].map(dens);&#10;    const POS_B = [0, 3, 6, 8, 11, 14];                                                                                           \/\/ secci\u00f3n B: las mismas notas, sincopadas&#10;    const MEL_B = MEL_A.map(b =&gt; { const ns = b.filter(Boolean), c = Array(16).fill(0); POS_B.forEach((p, i) =&gt; { c[p] = ns[i % ns.length]; }); return c; });&#10;    const salida = () =&gt; { if (!gain) { gain = audioCtx.createGain(); gain.gain.value = 0; gain.connect(masterGain); } return gain; };&#10;    function pulso(d) {                                                                                                            \/\/ onda de pulso con ciclo de trabajo d (serie de Fourier)&#10;        const n = 24, re = new Float32Array(n + 1), im = new Float32Array(n + 1);&#10;        for (let k = 1; k &lt;= n; k++) { const c = 2 \/ (k * Math.PI) * Math.sin(k * Math.PI * d); re[k] = c * Math.cos(k * Math.PI * d); im[k] = c * Math.sin(k * Math.PI * d); }&#10;        return audioCtx.createPeriodicWave(re, im);&#10;    }&#10;    const onda = () =&gt; ondas || (ondas = { p25: pulso(0.25), p125: pulso(0.125) });&#10;    function nota(f, t, d, w, v, tipo, f2) {                                                                                       \/\/ envolvente plana y corte seco, como un chip&#10;        const o = audioCtx.createOscillator(), g = audioCtx.createGain(); if (w) o.setPeriodicWave(w); else o.type = tipo || 'square';&#10;        o.frequency.setValueAtTime(f, t); if (f2) o.frequency.exponentialRampToValueAtTime(f2, t + d);&#10;        g.gain.setValueAtTime(v, t); g.gain.setValueAtTime(v, t + d * 0.6); g.gain.linearRampToValueAtTime(0.0001, t + d); o.connect(g); g.connect(salida()); o.start(t); o.stop(t + d + 0.02);&#10;    }&#10;    function ruido(t, d, tipo, fr, v) {&#10;        buf = buf || crearBufferRuido(0.6); const s = audioCtx.createBufferSource(), f = audioCtx.createBiquadFilter(), g = audioCtx.createGain();&#10;        s.buffer = buf; f.type = tipo; f.frequency.value = fr; g.gain.setValueAtTime(v, t); g.gain.exponentialRampToValueAtTime(0.0001, t + d); s.connect(f); f.connect(g); g.connect(salida()); s.start(t, Math.random() * 0.4, d);&#10;    }&#10;    const bombo = t =&gt; { const o = audioCtx.createOscillator(), g = audioCtx.createGain(); o.frequency.setValueAtTime(150, t); o.frequency.exponentialRampToValueAtTime(45, t + 0.1); g.gain.setValueAtTime(0.45, t); g.gain.exponentialRampToValueAtTime(0.0001, t + 0.14); o.connect(g); g.connect(salida()); o.start(t); o.stop(t + 0.16); };&#10;    const caja = t =&gt; { ruido(t, 0.12, 'bandpass', 1800, 0.16); nota(180, t, 0.05, null, 0.06, 'triangle'); };&#10;    const hat = (t, abierto) =&gt; ruido(t, abierto ? 0.12 : 0.03, 'highpass', 7000, 0.04);&#10;    const clank = t =&gt; { ruido(t, 0.1, 'bandpass', 3200, 0.1); nota(233, t, 0.07, null, 0.05, 'square'); };                        \/\/ golpe met\u00e1lico de la f\u00e1brica&#10;    const blip = t =&gt; nota(1500, t, 0.09, null, 0.04, 'square', 2600);                                                                \/\/ pitido de robot&#10;    function prog() {&#10;        while (proximo &lt; ahora() + AVISO) {&#10;            const t = proximo, s = paso % 16, bar = Math.floor(paso \/ 16) % 8, ac = bar % 4, sec = bar &lt; 4 ? 0 : 1;&#10;            if (s === 0 || s === 8 || (sec &amp;&amp; s === 10)) bombo(t);&#10;            if (s === 4 || s === 12 || (ac === 3 &amp;&amp; s &gt;= 13)) caja(t);                                                                \/\/ redoble al final de cada ciclo&#10;            if (s % 2 === 0) hat(t, s === 14);&#10;            if (s % 2 === 0) nota(hz(RAICES[ac] + BAJO[(s \/ 2) % 8]), t, D * 1.8, null, 0.16, 'triangle');&#10;            nota(hz(ACORDES[ac][ARP[s % 8]]), t, D * 0.9, onda().p125, 0.035);&#10;            const m = (sec ? MEL_B : MEL_A)[ac][s]; if (m) nota(hz(m), t, D * 1.6, onda().p25, 0.075);&#10;            if (ac === 3 &amp;&amp; s === 6) clank(t);&#10;            if (sec &amp;&amp; s === 15 &amp;&amp; ac % 2 === 1) blip(t);&#10;            proximo += D; paso++;&#10;        }&#10;    }&#10;    function parar() { clearInterval(timer); timer = null; }&#10;    function iniciar() { parar(); paso = 0; proximo = ahora() + 0.1; timer = setInterval(prog, 25); }&#10;    return { iniciar, parar, salida, partitura: { MEL_A, MEL_B } };&#10;})();&#10;const CiberAmbiente = (() =&gt; {&#10;    let gain = null, timer = null, proximo = 0, paso = 0, buf = null, eco = null;&#10;    const hz = m =&gt; 440 * Math.pow(2, (m - 69) \/ 12), ahora = () =&gt; audioCtx.currentTime, AVISO = 0.15, D = 60 \/ 96 \/ 4;&#10;    const ACORDES = [{ b: 38, p: [50, 53, 57, 64] }, { b: 34, p: [46, 50, 53, 57] }, { b: 31, p: [46, 50, 53, 57] }, { b: 33, p: [48, 52, 55, 60] }];     \/\/ Dm9 \u00b7 Sib maj7 \u00b7 Sol m9 \u00b7 La m7&#10;    const salida = () =&gt; { if (!gain) { gain = audioCtx.createGain(); gain.gain.value = 0; gain.connect(masterGain); } return gain; };&#10;    const retardo = () =&gt; { if (!eco) { const d = audioCtx.createDelay(1), fb = audioCtx.createGain(), wet = audioCtx.createGain(); d.delayTime.value = 0.375; fb.gain.value = 0.38; wet.gain.value = 0.45; d.connect(fb); fb.connect(d); d.connect(wet); wet.connect(salida()); eco = d; } return eco; };&#10;    function tono(f, t, d, tipo, v, conEco) {&#10;        const o = audioCtx.createOscillator(), g = audioCtx.createGain(); o.type = tipo; o.frequency.setValueAtTime(f, t);&#10;        g.gain.setValueAtTime(0.0001, t); g.gain.exponentialRampToValueAtTime(v, t + 0.02); g.gain.exponentialRampToValueAtTime(0.0001, t + d); o.connect(g); g.connect(salida()); if (conEco) g.connect(retardo()); o.start(t); o.stop(t + d + 0.05);&#10;    }&#10;    function clic(t, v) { buf = buf || crearBufferRuido(0.4); const s = audioCtx.createBufferSource(), f = audioCtx.createBiquadFilter(), g = audioCtx.createGain(); s.buffer = buf; f.type = 'highpass'; f.frequency.value = 6500; g.gain.setValueAtTime(v, t); g.gain.exponentialRampToValueAtTime(0.0001, t + 0.02); s.connect(f); f.connect(g); g.connect(salida()); s.start(t, Math.random() * 0.3, 0.02); }&#10;    function prog() {&#10;        while (proximo &lt; ahora() + AVISO) {&#10;            const t = proximo, s = paso % 32, ac = ACORDES[Math.floor(paso \/ 32) % 4];&#10;            if (s === 0) { ac.p.slice(0, 3).forEach(m =&gt; tono(hz(m), t, 5.2, 'triangle', 0.035)); tono(hz(ac.b), t, 2.4, 'sine', 0.16); }&#10;            if (s === 16) tono(hz(ac.b), t, 1.6, 'sine', 0.1);&#10;            if (s % 2 === 0 &amp;&amp; Math.random() &lt; 0.8) tono(hz(ac.p[Math.floor(Math.random() * ac.p.length)] + (Math.random() &lt; 0.3 ? 24 : 12)), t, 0.42, 'sine', 0.045, true);&#10;            if (Math.random() &lt; 0.1) clic(t + Math.random() * D, 0.03);&#10;            if (Math.random() &lt; 0.03) tono(1800 + Math.random() * 900, t, 0.08, 'square', 0.02, true);&#10;            proximo += D; paso++;&#10;        }&#10;    }&#10;    return { salida, parar() { clearInterval(timer); timer = null; }, iniciar() { this.parar(); paso = 0; proximo = ahora() + 0.1; timer = setInterval(prog, 25); } };&#10;})();&#10;const Radio = (() =&gt; {&#10;    const E = [&#10;        { id: 'txalaparta', emoji: '\ud83e\udd41', nombre: 'Txalaparta', frec: '88.8', disponible: true, sugerir: () =&gt; 1,&#10;          iniciar() { if (temporizadorSecuenciador) return; siguienteGolpeTiempo = audioCtx.currentTime + 0.1; indicePatronTxalaparta = 0; elegirNuevaFrase(); programarGolpes(); temporizadorSecuenciador = setInterval(programarGolpes, INTERVALO_COMPROBACION); },&#10;          parar() { clearInterval(temporizadorSecuenciador); temporizadorSecuenciador = null; },&#10;          salida: () =&gt; percusionGain },&#10;        { id: 'chiptune', emoji: '\ud83c\udfae', nombre: 'Chiptune 8 bits', frec: '92.4', disponible: true, sugerir: c =&gt; c.pantalla === 'industria' ? 1.8 : 0,      \/\/ en AUTO suena en la Zona Industrial&#10;          iniciar() { Chiptune.iniciar(); }, parar() { Chiptune.parar(); }, salida: () =&gt; Chiptune.salida() },&#10;        { id: 'ciber', emoji: '\ud83e\udde0', nombre: 'Ciber-ambient', frec: '98.7', disponible: true, sugerir: c =&gt; c.pantalla === 'biblioteca' ? 1.9 : 0,      \/\/ suena sola en la biblioteca&#10;          iniciar() { CiberAmbiente.iniciar(); }, parar() { CiberAmbiente.parar(); }, salida: () =&gt; CiberAmbiente.salida() },&#10;        { id: 'olas', emoji: '\ud83c\udf0a', nombre: 'Sonido del mar', frec: '90.1', disponible: true, sugerir: c =&gt; c.pantalla === 'playa' ? 1.8 : 0,      \/\/ en AUTO suena en la playa: su propio sonido, sin m\u00fasica&#10;          iniciar() {}, parar() {}, salida: () =&gt; null },&#10;        { id: 'campo', emoji: '\ud83c\udf3e', nombre: 'Sonido del campo', frec: '90.7', disponible: true, sugerir: c =&gt; c.pantalla === 'huerta' ? 1.8 : 0,      \/\/ en AUTO suena en la huerta: viento, agua de riego, p\u00e1jaros y abejas, sin m\u00fasica&#10;          iniciar() {}, parar() {}, salida: () =&gt; null },&#10;        { id: 'ambiente', emoji: '\ud83c\udf19', nombre: 'Ambiente suave', frec: '96.1', disponible: true, sugerir: c =&gt; c.pantalla === 'hospital' ? 1.9 : c.dia ? 0 : 1.5,      \/\/ solo de noche; la fiesta (2) tiene prioridad&#10;          iniciar() { Ambiente.iniciar(); }, parar() { Ambiente.parar(); }, salida: () =&gt; Ambiente.salida() },&#10;        { id: 'fiestas', get emoji() { return Conmemoraciones.id() ? '\ud83d\udc9c' : '\ud83c\udf89'; }, get nombre() { return Conmemoraciones.id() ? 'Conmemoraci\u00f3n' : 'Fiestas del pueblo'; }, frec: '101.5', disponible: true, sugerir: c =&gt; c.fiesta ? 2 : 0,&#10;          iniciar() { Fiestas.iniciar((fiestaActual() || {}).id); }, parar() { Fiestas.parar(); }, salida: () =&gt; Fiestas.salida() }&#10;    ];&#10;    const menu = document.getElementById('radioMenu'), chip = document.getElementById('navRadio');&#10;    let modo = 'auto', actual = null, ultimo = 0, pie = '', txtChip = ''; const sonando = new Set();&#10;    const contexto = () =&gt; ({ pantalla: enBiblioteca ? 'biblioteca' : pantallaActual(), dia: esDeDia(), fiesta: (fiestaActual() || {}).id || null });&#10;    const elegir = () =&gt; {                                                      \/\/ AUTO: gana la emisora con mayor prioridad (fiesta &gt; txalaparta)&#10;        if (modo === 'auto') { const c = contexto(); return E.filter(e =&gt; e.disponible).map(e =&gt; [e.sugerir(c), e]).sort((a, b) =&gt; b[0] - a[0])[0][1]; }&#10;        const e = E.find(x =&gt; x.id === modo); return ((e.id === 'fiestas' &amp;&amp; !fiestaActual()) || (e.id === 'ambiente' &amp;&amp; contexto().dia &amp;&amp; contexto().pantalla !== 'hospital')) ? E[0] : e;&#10;    };&#10;    function fundir(e, v) { const g = e.salida &amp;&amp; e.salida(); if (!g) return; const a = audioCtx.currentTime; g.gain.cancelScheduledValues(a); g.gain.setValueAtTime(g.gain.value, a); g.gain.linearRampToValueAtTime(v, a + 0.4); }&#10;    function aplicar() {                                                       \/\/ sintoniza la elegida y apaga la anterior con fundido&#10;        if (!audioIniciado) return;&#10;        const n = elegir();&#10;        if (n === actual &amp;&amp; n.id === 'fiestas') { const f = fiestaActual(); if (f &amp;&amp; Fiestas.tema() !== f.id) Fiestas.iniciar(f.id); }   \/\/ cambia el tema si cambia la fiesta&#10;        if (n === actual) return;&#10;        actual = n;&#10;        E.forEach(e =&gt; { if (e !== n &amp;&amp; sonando.has(e)) { fundir(e, 0); setTimeout(() =&gt; { if (actual !== e) { e.parar &amp;&amp; e.parar(); sonando.delete(e); } }, 450); } });      \/\/ las dem\u00e1s, fuera: una sola emisora a la vez&#10;        if (n.iniciar) { n.iniciar(); sonando.add(n); fundir(n, 1); }&#10;    }&#10;    function pintar(conMenu = true) {                                          \/\/ el men\u00fa solo se reconstruye al abrirlo o al elegir&#10;        const n = actual || elegir(), t = `\ud83d\udcfb ${modo === 'auto' ? 'Auto \u00b7 ' : ''}${n.emoji} ${n.nombre}`;&#10;        if (t !== txtChip) { txtChip = t; chip.textContent = t; }&#10;        if (!conMenu) return;&#10;        menu.innerHTML = '';&#10;        const op = (id, html, off) =&gt; { const d = document.createElement('div'); d.className = 'op' + (modo === id ? ' sel' : '') + (off ? ' off' : ''); d.innerHTML = html; d.addEventListener('click', ev =&gt; { ev.stopPropagation(); sintonizar(id); }); menu.appendChild(d); };&#10;        op('auto', '&lt;span&gt;\ud83d\udd00 Auto&lt;\/span&gt;&lt;span&gt;pantalla \u00b7 hora \u00b7 fiesta&lt;\/span&gt;', false);&#10;        E.forEach(e =&gt; op(e.id, `&lt;span&gt;${e.emoji} ${e.frec} FM \u00b7 ${e.nombre}&lt;\/span&gt;&lt;span&gt;${e.disponible ? '' : 'pronto'}&lt;\/span&gt;`, !e.disponible));&#10;        if (pie) { const f = document.createElement('div'); f.className = 'pie'; f.textContent = pie; menu.appendChild(f); }&#10;    }&#10;    function sintonizar(id) {&#10;        const e = E.find(x =&gt; x.id === id);&#10;        if (id === 'fiestas' &amp;&amp; !fiestaActual()) { pie = '\ud83c\udf89 Hoy no hay fiesta: toca el chip \ud83d\udcc5 para previsualizar'; pintar(); setTimeout(() =&gt; { pie = ''; pintar(); }, 2800); return; }&#10;        if (id === 'ambiente' &amp;&amp; contexto().dia &amp;&amp; contexto().pantalla !== 'hospital') { pie = '\ud83c\udf19 Ambiente suave suena solo de noche'; pintar(); setTimeout(() =&gt; { pie = ''; pintar(); }, 2800); return; }&#10;        if (e &amp;&amp; !e.disponible) { pie = `${e.emoji} ${e.nombre}: pr\u00f3ximamente, ${e.nota}`; pintar(); setTimeout(() =&gt; { pie = ''; pintar(); }, 2800); return; }&#10;        modo = id; if (!audioIniciado &amp;&amp; !silenciado) iniciarAudio(); aplicar(); pintar();&#10;        if (silenciado) { pie = '\ud83d\udd07 Est\u00e1s en silencio: toca el altavoz \ud83d\udd0a del juego para escuchar'; pintar(); setTimeout(() =&gt; { pie = ''; pintar(); }, 3200); }&#10;    }&#10;    chip.addEventListener('click', ev =&gt; { ev.stopPropagation(); menu.hidden = !menu.hidden; if (!menu.hidden) pintar(); });&#10;    document.addEventListener('click', () =&gt; { menu.hidden = true; });&#10;    return { suena: () =&gt; !!actual &amp;&amp; !['olas', 'campo'].includes(actual.id), ahora() { aplicar(); pintar(false); }, tick() { const now = performance.now(); if (now - ultimo &lt; 1000) return; ultimo = now; aplicar(); pintar(false); } };   \/\/ reeval\u00faa el modo AUTO cada segundo&#10;})();&#10;PUESTOS.push({ id: 'apicultura', nombre: 'Apicultura', emoji: '\ud83c\udf6f', color: '#f2a900', oy: 150, contadores: true, prods: [&#10;    P('Miel', '\ud83c\udf6f', 4, 0, 'Miel de las flores de La Huerta, recogida de las colmenas.'),&#10;    P('Cera real', '\ud83d\udd6f\ufe0f', 5, 0, 'Cera pura de abeja para velas y b\u00e1lsamos.'),&#10;    P('Prop\u00f3leo', '\ud83d\udfe4', 6, 0, 'Resina de las yemas que las abejas usan para proteger la colmena.'),&#10;    P('Hidromiel', '\ud83c\udf76', 8, 0, 'Miel fermentada 30 segundos: dulce, suave y muy nuestra.'),&#10;    P('Jalea real', '\ud83d\udc51', 10, 0, 'Alimento de la reina de la colmena, escaso y muy valioso.')] });&#10;M_CX.push(770);                                                                      \/\/ el puesto de apicultura, en la fila delantera&#10;PUESTOS.push({ id: 'algas', nombre: 'Algas y Hongos', emoji: '\ud83c\udf44', color: '#5f8f4a', oy: 150, prods: [      \/\/ fila trasera: mundo sin escasez, productos resilientes y nuevas prote\u00ednas&#10;    P('Alga wakame', '\ud83c\udf3f', 3, 10, 'Alga tierna recogida en la costa del pueblo.'),&#10;    P('Alga laver', '\ud83d\udfe2', 3, 10, 'Alga fina para tostar o desmenuzar en las comidas.'),&#10;    P('Hongo enoki', '\ud83c\udf44', 4, 8, 'Hongo largo y delicado, cultivado en residuos agr\u00edcolas.'),&#10;    P('Hongo maitake', '\ud83c\udf44', 5, 8, 'Hongo de textura carnosa, cultivado en residuos agr\u00edcolas.'),&#10;    P('Bloque de micoprote\u00edna', '\ud83d\udfeb', 5, 8, 'Bloque de prote\u00edna f\u00fangica, huella h\u00eddrica casi nula.'),&#10;    P('Queso de cultivo celular', '\ud83e\uddea', 7, 5, 'Prote\u00ednas l\u00e1cteas hechas por fermentaci\u00f3n, sin ganado.')] });&#10;M_CX.push(400);&#10;PUESTOS.push({ id: 'granos', nombre: 'Granos y Ra\u00edces', emoji: '\ud83c\udf60', color: '#b5651d', oy: 150, prods: [&#10;    P('Fonio', '\ud83c\udf3e', 3, 12, 'Grano diminuto de crecimiento rapid\u00edsimo, aguanta la sequ\u00eda.'),&#10;    P('Teff', '\ud83c\udf3e', 4, 12, 'Cereal peque\u00f1o y resistente, base de panes fermentados.'),&#10;    P('Quinoa', '\ud83c\udf5a', 4, 12, 'Pseudocereal completo, aguanta clima extremo.'),&#10;    P('Amaranto', '\ud83c\udf3a', 4, 10, 'Semilla antigua de gran valor nutritivo.'),&#10;    P('Camote amarillo', '\ud83c\udf60', 3, 10, 'Batata amarilla dulce, de cultivo resistente.'),&#10;    P('J\u00edcama', '\ud83e\udd54', 3, 10, 'Ra\u00edz crujiente y refrescante, se come cruda o cocida.')] });&#10;M_CX.push(580);&#10;const Apicultura = (() =&gt; {&#10;    const e = { nectar: 0, resina: 0, sinCera: 0, sinJalea: 0, miel: 0, cera: 0, propoleo: 0, hidromiel: 0, jalea: 0, fermentaFin: 0 };   \/\/ producci\u00f3n lista para enviar&#10;    let ultimo = performance.now(), envio = null, proxEnvio = 0;&#10;    const PRODUCTOS = ['miel', 'cera', 'propoleo', 'hidromiel', 'jalea'], puesto = () =&gt; PUESTOS.find(q =&gt; q.id === 'apicultura'), total = () =&gt; PRODUCTOS.reduce((a, k) =&gt; a + e[k], 0);&#10;    function cargar() { const c = {}; PRODUCTOS.forEach(k =&gt; { c[k] = e[k]; e[k] = 0; }); return c; }            \/\/ vac\u00eda lo listo y lo mete en la c\u00e1psula&#10;    function entregar(c) { const ps = puesto().prods; PRODUCTOS.forEach((k, i) =&gt; { ps[i].s += c[k]; }); }      \/\/ contadores independientes del mostrador&#10;    function tick(now) {&#10;        const dt = Math.min(0.2, (now - ultimo) \/ 1000); ultimo = now;&#10;        if (!invernada()) e.nectar += dt * 0.12;   \/\/                                                                              \/\/ producci\u00f3n pasiva de las colmenas&#10;        while (e.nectar &gt;= 6) { e.nectar -= 6; e.miel++; if (++e.sinCera &gt;= 5) { e.sinCera = 0; e.cera++; } if (++e.sinJalea &gt;= 8) { e.sinJalea = 0; e.jalea++; } }   \/\/ la jalea real es rara: 1 por cada 8 mieles&#10;        while (e.resina &gt;= 2) { e.resina -= 2; e.propoleo++; }&#10;        if (!e.fermentaFin &amp;&amp; e.miel &gt;= 5) { e.miel -= 4; e.fermentaFin = now + 30000; }                    \/\/ barril de hidromiel&#10;        if (e.fermentaFin &amp;&amp; now &gt;= e.fermentaFin) { e.fermentaFin = 0; e.hidromiel++; }&#10;        PRODUCTOS.forEach(k =&gt; { if (e[k] &gt; 99) e[k] = 99; });&#10;        if (!envio &amp;&amp; total() &gt;= 8 &amp;&amp; now &gt;= proxEnvio) {                                                    \/\/ despacho autom\u00e1tico por el Hyperloop&#10;            envio = { llegada: now + 7000, carga: cargar() }; proxEnvio = now + 20000;&#10;            if (enHuerta) mostrarToast('\ud83c\udf6f Producci\u00f3n ap\u00edcola en camino por el Hyperloop');&#10;        }&#10;        if (envio &amp;&amp; now &gt;= envio.llegada) {&#10;            const c = envio.carga; envio = null;&#10;            if (enMercado &amp;&amp; capsula.fase === 'reposo') enviarCapsula(0, c);                                  \/\/ se ve llegar la c\u00e1psula&#10;            else { entregar(c); if (enMercado) mostrarToastMercado('\ud83d\udce6 Hyperloop: producci\u00f3n ap\u00edcola entregada'); }&#10;        }&#10;    }&#10;    return { e, tick, cargar, entregar, hay: () =&gt; total() &gt; 0,&#10;             recolecta(polen) { e.nectar += 0.5 + polen * 0.8; },                                           \/\/ abeja que vuelve cargada de polen&#10;             polinizacion() { e.nectar += 1.5; e.resina += 1; } };                                           \/\/ cultivo polinizado&#10;})();&#10;const KUTXA_POS = { x: 690, y: SUELO_Y + 152 };&#10;const Kutxa = (() =&gt; {&#10;    let fondo = 0, pend = 0, ultimoFlot = 0, brilloT = -1e9, ultimo = performance.now();&#10;    const flot = [];                                                                   \/\/ avisos flotantes &quot;+n&quot; agrupados&#10;    return {&#10;        flot,&#10;        aportar(n) { if (n &gt; 0) { fondo += n; pend += n; } },                           \/\/ ingreso al fondo com\u00fan (MIIG26D)&#10;        gastar(n) { if (fondo &gt;= n) { fondo -= n; return true; } return false; },       \/\/ lo usar\u00e1 el panel de proyectos&#10;        visible: () =&gt; Math.floor(fondo),&#10;        valor: () =&gt; fondo,&#10;        exportar: () =&gt; ({ fondo }),&#10;        importar(o) { if (o &amp;&amp; Number.isFinite(+o.fondo)) fondo = Math.min(1e7, Math.max(0, +o.fondo)); },&#10;        brillo: now =&gt; Math.max(0, 1 - (now - brilloT) \/ 900),&#10;        tick(now) {&#10;            const dt = Math.min(0.2, (now - ultimo) \/ 1000); ultimo = now;&#10;            this.aportar(dt * 0.05);                                                    \/\/ turnos constantes de las Genoides&#10;            if (pend &gt;= 0.3 &amp;&amp; now - ultimoFlot &gt; 1500) {                               \/\/ agrupa los ingresos peque\u00f1os en un solo &quot;+n&quot;&#10;                flot.push({ txt: '+' + (pend &lt; 10 ? pend.toFixed(1) : Math.round(pend)), t0: now }); if (flot.length &gt; 4) flot.shift();&#10;                pend = 0; ultimoFlot = now; brilloT = now;&#10;            }&#10;        }&#10;    };&#10;})();&#10;function decorarKutxa(t, x, y) {&#10;    const F = fiestaActual(); if (!F) return;&#10;    const id = F.id, pal = PAL[id], lid = u =&gt; y - 22 - 48 * u * (1 - u);                                \/\/ altura de la tapa curva en u\u2208[0,1]&#10;    ctx.save(); ctx.lineWidth = 1.5; ctx.strokeStyle = '#000';&#10;    if (id === 'navidad') {                                                                                \/\/ luces + gorrito de Pap\u00e1 Noel sobre la tapa&#10;        guirnalda(x - 24, x + 24, y - 19, pal, t, false);&#10;        ctx.fillStyle = '#e53935'; ctx.beginPath(); ctx.moveTo(x + 3, y - 37); ctx.lineTo(x + 17, y - 34); ctx.lineTo(x + 13, y - 49); ctx.closePath(); ctx.fill(); ctx.stroke();&#10;        ctx.strokeStyle = '#fff'; ctx.lineWidth = 3; ctx.beginPath(); ctx.moveTo(x + 2, y - 37); ctx.lineTo(x + 18, y - 34); ctx.stroke();&#10;        ctx.fillStyle = '#fff'; ctx.beginPath(); ctx.arc(x + 13, y - 50, 2.2, 0, Math.PI * 2); ctx.fill();&#10;    } else if (id === 'carnaval') {                                                                        \/\/ banderines, antifaz con plumita y confeti&#10;        guirnalda(x - 24, x + 24, y - 19, pal, t, true);&#10;        ctx.fillStyle = '#8e44ad'; ctx.beginPath(); ctx.ellipse(x - 14, y - 38, 7, 3.2, -0.2, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;        ctx.fillStyle = '#fff'; [-3, 3].forEach(dx =&gt; { ctx.beginPath(); ctx.arc(x - 14 + dx, y - 38, 1.4, 0, Math.PI * 2); ctx.fill(); });&#10;        ctx.strokeStyle = '#ffeb3b'; ctx.lineWidth = 1.6; ctx.beginPath(); ctx.moveTo(x - 20, y - 40); ctx.quadraticCurveTo(x - 26, y - 48, x - 21, y - 53); ctx.stroke();&#10;        for (let k = 0; k &lt; 6; k++) { const a = t \/ 30 + k * 1.05; ctx.fillStyle = pal[k % pal.length]; ctx.fillRect(x + Math.cos(a) * 32 - 1.5, y - 22 + Math.sin(a) * 14 - 1, 3, 2); }&#10;    } else if (id === 'sanjuan') {                                                                         \/\/ corona de flores en la tapa + farolillo con chispas&#10;        [0.08, 0.22, 0.36, 0.5, 0.64, 0.78, 0.92].forEach((u, k) =&gt; { ctx.fillStyle = ['#ff5ca8', '#ffd23f', '#ffffff', '#ff8a3d'][k % 4]; ctx.beginPath(); ctx.arc(x - 25 + 50 * u, lid(u) - 2, 2.6, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); });&#10;        const lx = x + 36, ly = y - 12, g = ctx.createRadialGradient(lx, ly, 1, lx, ly, 14); g.addColorStop(0, 'rgba(255,170,40,0.6)'); g.addColorStop(1, 'rgba(255,170,40,0)');&#10;        ctx.fillStyle = g; ctx.beginPath(); ctx.arc(lx, ly, 14, 0, Math.PI * 2); ctx.fill(); mTxt('\ud83c\udfee', lx, ly, 13, '#000', 'center');&#10;        for (let k = 0; k &lt; 3; k++) { const f = ((t \/ 40) + k \/ 3) % 1; ctx.globalAlpha = 1 - f; ctx.fillStyle = '#ffb347'; ctx.beginPath(); ctx.arc(lx + Math.sin(k * 4 + t \/ 15) * 4, ly - 8 - f * 14, 1.1, 0, Math.PI * 2); ctx.fill(); } ctx.globalAlpha = 1;&#10;    } else if (id === '28j') {                                                                             \/\/ cinta arco\u00edris sobre la tapa + banderita&#10;        ctx.lineWidth = 1.5; pal.forEach((c, i) =&gt; { ctx.strokeStyle = c; ctx.beginPath(); ctx.moveTo(x - 25, y - 22 + i * 1.5); ctx.quadraticCurveTo(x, y - 46 + i * 1.5, x + 25, y - 22 + i * 1.5); ctx.stroke(); });&#10;        const fx = x + 34; ctx.strokeStyle = '#5a3a1c'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(fx, y - 1); ctx.lineTo(fx, y - 32); ctx.stroke();&#10;        pal.forEach((c, i) =&gt; { ctx.fillStyle = c; ctx.fillRect(fx, y - 32 + i * 1.8 + Math.sin(t \/ 12 + i) * 0.5, 16, 1.8); });&#10;    } else if (id === 'halloween') {                                                                       \/\/ calabaza en la tapa, telara\u00f1a y una Argizaiola al lado&#10;        mTxt('\ud83c\udf83', x - 14, y - 40, 14, '#000', 'center'); mTxt('\ud83d\udd78\ufe0f', x - 27, y - 36, 11, '#000', 'center');&#10;        dibujarArgizaiola(x + 40, y, t, 4);&#10;    }&#10;    ctx.restore();&#10;}&#10;function dibujarKutxa(t) {                                                             \/\/ cofre vasco: madera noble, tallas y herrajes de forja&#10;    const { x, y } = KUTXA_POS, now = performance.now();&#10;    ctx.save(); ctx.lineJoin = 'round';&#10;    ctx.fillStyle = '#4a2a14'; ctx.fillRect(x - 21, y - 3, 7, 4); ctx.fillRect(x + 14, y - 3, 7, 4);                  \/\/ patas&#10;    ctx.fillStyle = '#8a5428'; ctx.strokeStyle = '#2e1a0c'; ctx.lineWidth = 2; ctx.fillRect(x - 24, y - 22, 48, 20); ctx.strokeRect(x - 24, y - 22, 48, 20);   \/\/ cuerpo&#10;    ctx.strokeStyle = 'rgba(46,26,12,0.45)'; ctx.lineWidth = 1; ctx.beginPath(); [-15, -9].forEach(dy =&gt; { ctx.moveTo(x - 24, y + dy); ctx.lineTo(x + 24, y + dy); }); ctx.stroke();    \/\/ tablones&#10;    ctx.strokeStyle = 'rgba(217,164,90,0.6)'; ctx.strokeRect(x - 21, y - 19, 42, 14);                                                                              \/\/ marco tallado&#10;    ctx.fillStyle = '#9a6030'; ctx.strokeStyle = '#2e1a0c'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(x - 25, y - 22); ctx.quadraticCurveTo(x, y - 46, x + 25, y - 22); ctx.closePath(); ctx.fill(); ctx.stroke();   \/\/ tapa curva&#10;    ctx.strokeStyle = 'rgba(46,26,12,0.4)'; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(x - 20, y - 26); ctx.quadraticCurveTo(x, y - 40, x + 20, y - 26); ctx.stroke();    \/\/ veta de la tapa&#10;    dibujarLauburu(x, y - 30, 5, '#d9a45a');                                                                                                                         \/\/ lauburu tallado&#10;    ctx.fillStyle = '#3a3f45'; ctx.strokeStyle = '#1b1e22'; ctx.lineWidth = 1.5;                                                                                       \/\/ herrajes de forja&#10;    [-15, 15].forEach(dx =&gt; { ctx.fillRect(x + dx - 3, y - 22, 6, 20); ctx.strokeRect(x + dx - 3, y - 22, 6, 20); ctx.fillRect(x + dx - 3, y - 30, 6, 8); ctx.strokeRect(x + dx - 3, y - 30, 6, 8); });&#10;    ctx.fillStyle = '#9aa4ad'; [-15, 15].forEach(dx =&gt; [-17, -8].forEach(dy =&gt; { ctx.beginPath(); ctx.arc(x + dx, y + dy, 1.2, 0, Math.PI * 2); ctx.fill(); }));       \/\/ remaches&#10;    ctx.fillStyle = '#3a3f45'; ctx.fillRect(x - 5, y - 19, 10, 11); ctx.strokeRect(x - 5, y - 19, 10, 11);                                                           \/\/ cerradura&#10;    ctx.fillStyle = '#d9a45a'; ctx.beginPath(); ctx.arc(x, y - 15, 1.6, 0, Math.PI * 2); ctx.fill(); ctx.fillRect(x - 0.6, y - 15, 1.2, 4);&#10;    const b = Kutxa.brillo(now);                                                                                                                                       \/\/ destello al entrar dinero&#10;    if (b &gt; 0) { const g = ctx.createRadialGradient(x, y - 22, 2, x, y - 22, 34); g.addColorStop(0, `rgba(255,214,90,${b * 0.55})`); g.addColorStop(1, 'rgba(255,214,90,0)'); ctx.fillStyle = g; ctx.beginPath(); ctx.arc(x, y - 22, 34, 0, Math.PI * 2); ctx.fill(); }&#10;    decorarKutxa(t, x, y);                                                                                                                                              \/\/ detalle de la fiesta del calendario&#10;    const fl = Math.sin(t \/ 30) * 2, txt = 'Kutxa AuZ \u00b7 \ud83e\ude99 ' + Kutxa.visible();                                                                                          \/\/ contador flotante&#10;    ctx.font = `bold 10px ${FUENTE_MERCADO}`; const w = ctx.measureText(txt).width + 18;&#10;    mCaja(x - w \/ 2, y - 68 + fl, w, 16, 8, 'rgba(255,248,234,0.92)', '#8a5428', 1.5); mTxt(txt, x, y - 60 + fl, 10, '#5a3a1c', 'center', true);&#10;    Kutxa.flot.forEach((f, i) =&gt; { const e = now - f.t0; if (e &gt; 1400) return; ctx.globalAlpha = 1 - e \/ 1400; mTxt(f.txt, x + (i % 2 ? 14 : -14), y - 76 - e * 0.02, 10, '#b8860b', 'center', true); ctx.globalAlpha = 1; });   \/\/ &quot;+n&quot; que sube&#10;    ctx.restore();&#10;}&#10;const Desgaste = (() =&gt; {&#10;    const est = { casas: 0, engranajes: 0, ordenadores: 0, repcoche: 0, reptranvia: 0 }, brillo = {};&#10;    const TASA = { casas: 1 \/ 1800, engranajes: 1 \/ 1500, ordenadores: 1 \/ 1700, repcoche: 1 \/ 2000, reptranvia: 1 \/ 1800 }, TOPE = 0.85;   \/\/ por segundo: ~30 min hasta el desgaste m\u00e1ximo&#10;    let ultimo = performance.now();&#10;    return {&#10;        nivel: k =&gt; est[k],&#10;        exportar: () =&gt; ({ ...est }),&#10;        importar(o) { if (o) for (const k in est) if (Number.isFinite(+o[k])) est[k] = Math.min(TOPE, Math.max(0, +o[k])); },&#10;        sube(k, n) { est[k] = Math.min(TOPE, est[k] + n); },                                    \/\/ desgaste por uso (prototipos, salidas del tren, turnos)&#10;        reparar(k) { est[k] = 0; brillo[k] = performance.now(); },&#10;        destello: k =&gt; k in brillo ? Math.max(0, 1 - (performance.now() - brillo[k]) \/ 3500) : 0,   \/\/ brillo de 3,5 s tras reparar&#10;        giro: t =&gt; t * 0.012 * (1 - 0.7 * est.engranajes) + Math.sin(t \/ 7) * 0.05 * est.engranajes,   \/\/ engranaje del portal: m\u00e1s lento y con tirones&#10;        parpadeo: (now, fase) =&gt; { const n = est.ordenadores; return n &gt; 0.15 &amp;&amp; Math.sin(now \/ 41 + fase * 5) * Math.sin(now \/ 173 + fase) &gt; 1 - n * 0.8; },&#10;        tick(now) { const dt = Math.min(0.2, (now - ultimo) \/ 1000); ultimo = now; for (const k in est) est[k] = Math.min(TOPE, est[k] + dt * TASA[k]); }&#10;    };&#10;})();&#10;function brillos(x, y, w, h, b, t) {                                                               \/\/ destellos de \u00abreci\u00e9n reparado\u00bb&#10;    ctx.save(); ctx.strokeStyle = '#fff3a0'; ctx.lineWidth = 1.2;&#10;    for (let k = 0; k &lt; 8; k++) { const px = x + (k * 53 + Math.floor(t \/ 14) * 31) % w, py = y + (k * 37 + Math.floor(t \/ 14) * 17) % h, s = 2 + 2 * Math.abs(Math.sin(t \/ 5 + k));&#10;        ctx.globalAlpha = b * (0.4 + 0.6 * Math.abs(Math.sin(t \/ 6 + k))); ctx.beginPath(); ctx.moveTo(px - s, py); ctx.lineTo(px + s, py); ctx.moveTo(px, py - s); ctx.lineTo(px, py + s); ctx.stroke(); }&#10;    ctx.restore();&#10;}&#10;function dibujarDesgasteCasas(t) {&#10;    const n = Desgaste.nivel('casas'), b = Desgaste.destello('casas'); if (n &lt; 0.08 &amp;&amp; b &lt;= 0) return;&#10;    const by = SUELO_Y + 55; ctx.save();&#10;    casas.forEach((c, i) =&gt; {&#10;        const top = by - c.alto;&#10;        if (n &gt;= 0.08) {&#10;            ctx.fillStyle = `rgba(110,90,70,${n * 0.16})`; ctx.fillRect(c.x, top, c.ancho, c.alto);                                          \/\/ fachada deslucida&#10;            ctx.strokeStyle = `rgba(60,40,30,${0.35 + n * 0.3})`; ctx.lineWidth = 1.2;&#10;            for (let k = 0; k &lt; Math.ceil(n * 4); k++) { const sx = c.x + 8 + ((i * 37 + k * 53) % Math.max(10, c.ancho - 16)), sy = top + 10 + (k * 23 + i * 11) % Math.max(10, c.alto - 40);&#10;                ctx.beginPath(); ctx.moveTo(sx, sy); ctx.lineTo(sx + 4, sy + 7); ctx.lineTo(sx - 2, sy + 13); ctx.lineTo(sx + 3, sy + 19); ctx.stroke(); }          \/\/ grietas&#10;            ctx.fillStyle = 'rgba(40,30,25,0.75)'; for (let k = 0; k &lt; Math.floor(n * 6); k++) ctx.fillRect(c.x + 6 + ((i * 29 + k * 41) % Math.max(10, c.ancho - 14)), top - 4 - (k % 2) * 3, 6, 4);   \/\/ tejas que faltan&#10;        }&#10;        if (b &gt; 0) brillos(c.x, top - 20, c.ancho, c.alto + 20, b, t + i * 7);&#10;    });&#10;    ctx.restore();&#10;}&#10;function humoCoche(x, y, t) {                                                                       \/\/ coche volador desgastado: humito y chispas&#10;    const n = Desgaste.nivel('repcoche'), b = Desgaste.destello('repcoche');&#10;    if (n &gt;= 0.25) { ctx.save(); for (let k = 0; k &lt; Math.ceil(n * 5); k++) { ctx.fillStyle = `rgba(110,110,110,${0.28 * (1 - k \/ 6)})`; ctx.beginPath(); ctx.arc(x - 22 - k * 11, y + 4 + Math.sin(t \/ 9 + k * 2) * 3 - k * 0.6, 2.5 + k * 0.9, 0, Math.PI * 2); ctx.fill(); }&#10;        if (n &gt; 0.5 &amp;&amp; Math.sin(t \/ 5 + x) &gt; 0.8) { ctx.fillStyle = '#ffb347'; ctx.beginPath(); ctx.arc(x - 18, y + 8, 1.4, 0, Math.PI * 2); ctx.fill(); } ctx.restore(); }&#10;    if (b &gt; 0) brillos(x - 24, y - 16, 50, 32, b, t);&#10;}&#10;function desgasteTren(T, t, off) {                                                                  \/\/ tranv\u00eda: \u00f3xido, humo y chirridos&#10;    const n = Desgaste.nivel('reptranvia'), b = Desgaste.destello('reptranvia'), y = TRANVIA.y, coches = [T.x]; for (let k = 1; k &lt;= T.n; k++) coches.push(T.x - off(k));&#10;    if (n &gt;= 0.08) {&#10;        ctx.save();&#10;        coches.forEach((cx, i) =&gt; {&#10;            ctx.fillStyle = `rgba(90,90,100,${n * 0.14})`; ctx.fillRect(cx - 38, y - 34, 76, 34);&#10;            ctx.fillStyle = `rgba(150,80,40,${0.2 + n * 0.45})`; for (let k = 0; k &lt; Math.ceil(n * 4); k++) { ctx.beginPath(); ctx.ellipse(cx - 30 + ((i * 17 + k * 29) % 60), y - 8 - (k * 7 + i * 5) % 18, 3 + k % 2, 2, 0, 0, Math.PI * 2); ctx.fill(); }&#10;        });&#10;        if (T.v &gt; 1 &amp;&amp; n &gt; 0.3) { for (let k = 0; k &lt; 3; k++) { ctx.fillStyle = `rgba(120,120,120,${0.3 * (1 - k \/ 3)})`; ctx.beginPath(); ctx.arc(T.x + 10 - k * 9, y - 40 - k * 5 - Math.sin(t \/ 6 + k) * 2, 3 + k, 0, Math.PI * 2); ctx.fill(); } }&#10;        if (T.v &gt; 1.5 &amp;&amp; n &gt; 0.4 &amp;&amp; Math.sin(t \/ 3) &gt; 0.5) { ctx.fillStyle = '#ffb347'; [-22, 22].forEach(dx =&gt; { ctx.beginPath(); ctx.arc(T.x + dx - 6 + Math.random() * 4, y + 9, 1.2, 0, Math.PI * 2); ctx.fill(); }); }   \/\/ chirrido de ruedas&#10;        ctx.restore();&#10;    }&#10;    if (b &gt; 0) brillos(T.x - off(T.n) - 40, y - 36, off(T.n) + 80, 40, b, t);&#10;}&#10;function dibujarDesgasteIndustria(now) {                                                            \/\/ \u00f3xido de la impresora y fallos del panel&#10;    const ne = Desgaste.nivel('engranajes'), no = Desgaste.nivel('ordenadores'), be = Desgaste.destello('engranajes');&#10;    ctx.save();&#10;    for (let k = 0; k &lt; Math.ceil(ne * 8); k++) { ctx.fillStyle = 'rgba(160,85,35,0.7)'; if (k % 3 === 2) ctx.fillRect(350 + (k * 61) % 260, 195, 6, 4); else ctx.fillRect(k % 2 ? 599 : 345, 205 + (k * 29) % 170, 5, 7); }&#10;    if (ne &gt; 0.4 &amp;&amp; Math.sin(now \/ 90) &gt; 0.6) { ctx.fillStyle = '#ffb347'; ctx.beginPath(); ctx.arc(470 + Math.random() * 20, 372, 1.3, 0, Math.PI * 2); ctx.fill(); }   \/\/ chispas&#10;    if (be &gt; 0) brillos(340, 186, 280, 200, be, now \/ 16);&#10;    if (no &gt; 0.15 &amp;&amp; Desgaste.parpadeo(now, 1.7)) { ctx.fillStyle = 'rgba(255,255,255,0.3)'; ctx.fillRect(640, 132 + (now \/ 7) % 180, 290, 3); ctx.fillStyle = 'rgba(255,60,60,0.18)'; ctx.fillRect(640, 132, 290, 190); }   \/\/ panel que parpadea&#10;    ctx.restore();&#10;}&#10;const KutxaPanel = (() =&gt; {&#10;    const PROYECTOS = [&#10;        { id: 'coche', cat: 'exp', e: '\ud83d\ude81', n: 'Coche volador', coste: 120, d: 'Otro coche aut\u00f3nomo sobrevuela el pueblo (m\u00e1x. 2).' },&#10;        { id: 'vagon', cat: 'exp', e: '\ud83d\ude83', n: 'Vag\u00f3n nuevo', coste: 60, d: 'Un vag\u00f3n m\u00e1s para el tranv\u00eda (m\u00e1x. 4).' },&#10;        { id: 'colmena', cat: 'exp', e: '\ud83c\udf6f', n: 'Colmena nueva', coste: 40, d: 'Otra colmena en La Huerta, con sus abejas.' },&#10;        { id: 'tinaja', cat: 'exp', e: '\ud83c\udffa', n: 'Tinaja LUR', coste: 30, d: 'Otra olla de arcilla para el riego subterr\u00e1neo.' },&#10;        { id: 'casas', cat: 'man', e: '\ud83c\udfe0', n: 'Arreglo de casas', coste: 35, d: 'Tejados, ventanas, puertas y fachadas.' },&#10;        { id: 'engranajes', cat: 'man', e: '\u2699\ufe0f', n: 'Engranajes de la impresora', coste: 40, d: 'Piezas de repuesto para la impresora 3D.' },&#10;        { id: 'ordenadores', cat: 'man', e: '\ud83d\udcbb', n: 'Ordenadores de las Genoides', coste: 45, d: 'Actualizaci\u00f3n y puesta a punto.' },&#10;        { id: 'repcoche', cat: 'man', e: '\ud83d\udee0\ufe0f', n: 'Reparar el coche volador', coste: 50, d: 'Revisi\u00f3n mec\u00e1nica del coche de alquiler.' },&#10;        { id: 'reptranvia', cat: 'man', e: '\ud83d\udd29', n: 'Reparar el tranv\u00eda', coste: 50, d: 'Puesta a punto de la cabina y los vagones.' }];&#10;    const PN = { x: 110, y: 50, w: 740, h: 440 }, CLOSE = { x: PN.x + PN.w - 42, y: PN.y + 8, w: 34, h: 34 }, RESET = { x: PN.x + PN.w - 190, y: PN.y + PN.h - 40, w: 170, h: 26 }, CONV = { x: PN.x + PN.w - 220, y: PN.y + 92, w: 200, h: 28 };&#10;    const TAB = i =&gt; ({ x: PN.x + 20 + i * 214, y: PN.y + 92, w: 204, h: 28 });&#10;    const card = i =&gt; ({ x: PN.x + 20 + (i % 2) * 350, y: PN.y + 128 + Math.floor(i \/ 2) * 84, w: 340, h: 76 });&#10;    const ZONA_COFRE = { x: KUTXA_POS.x - 30, y: KUTXA_POS.y - 74, w: 60, h: 80 };&#10;    const eventos = [], aviso = typeof document !== 'undefined' ? document.getElementById('avisoKutxa') : null;&#10;    let abierto = false, tab = 'exp', activo = null, avisoHasta = 0, confirma = 0;&#10;    const lista = () =&gt; PROYECTOS.filter(p =&gt; p.cat === tab), mant = p =&gt; p.cat === 'man';&#10;    const tope = p =&gt; mant(p) ? Desgaste.nivel(p.id) &lt; 0.1 : p.id === 'coche' ? flota.coches &gt;= 1 : p.id === 'vagon' ? flota.vagones &gt;= 2 : p.id === 'colmena' ? HUERTA_COLMENAS.length &gt;= 5 : p.id === 'tinaja' ? LUR_TINAJAS.length &gt;= 6 : false;&#10;    const peor = () =&gt; { const w = PROYECTOS.filter(mant).sort((a, b) =&gt; Desgaste.nivel(b.id) - Desgaste.nivel(a.id))[0]; return Desgaste.nivel(w.id) &gt;= 0.5 ? [w.id, `est\u00e1 al ${Math.round((1 - Desgaste.nivel(w.id)) * 100)} % de su estado`] : null; };&#10;    const sugerida = () =&gt; peor() ? peor() : flota.coches === 0 ? ['coche', 'a\u00fan no hay ning\u00fan coche volador'] : flota.vagones &lt; 2 ? ['vagon', 'el tranv\u00eda todav\u00eda puede crecer'] : ['colmena', 'm\u00e1s colmenas, m\u00e1s miel y m\u00e1s polinizaci\u00f3n'];&#10;    function avisar(txt) { if (\/^(\ud83c\udf89|\ud83d\ude81|\ud83d\uddf3\ufe0f \u00a1?Las vecinas)\/.test(txt)) Noticias.publicar(txt); if (!aviso) return; aviso.textContent = (typeof Idioma !== 'undefined' &amp;&amp; Idioma.tr) ? Idioma.tr(txt) : txt; aviso.classList.add('ver'); avisoHasta = performance.now() + 4500; setTimeout(() =&gt; { if (performance.now() &gt;= avisoHasta) aviso.classList.remove('ver'); }, 4600); }&#10;    const EFECTOS = {&#10;        coche: () =&gt; { flota.coches++; eventos.push({ tipo: 'coche', t0: null }); },                                  \/\/ vuelo triunfal y luego se une al cielo&#10;        vagon: () =&gt; { flota.vagones++; },                                                                           \/\/ el tren lo engancha al parar&#10;        colmena: () =&gt; { const n = HUERTA_COLMENAS.length, x = [790, 70][n - 3];&#10;            HUERTA_COLMENAS.push({ x, y: 322, c: n === 3 ? '#b8d8f0' : '#f2d27a' });&#10;            for (let k = 0; k &lt; 3; k++) abejas.push({ casa: n, estado: 'dentro', espera: 30 + k * 40, x: 0, y: 0, tx: 0, ty: 0, flores: 0, fase: 20 + n * 5 + k * 1.9, dir: 1, polen: 0, obj: null });&#10;            emitirPolen(x, 290, 24); },&#10;        tinaja: () =&gt; { LUR_TINAJAS.push([330, 620][LUR_TINAJAS.length - 4]); }&#10;    };&#10;    ['casas', 'engranajes', 'ordenadores', 'repcoche', 'reptranvia'].forEach(id =&gt; { EFECTOS[id] = () =&gt; Desgaste.reparar(id); });                \/\/ mantenimiento: lo deja como nuevo&#10;    function efectos(t) {                                                                                            \/\/ vuelo triunfal del coche nuevo sobre el pueblo&#10;        const ev = eventos[0]; if (!ev) return;&#10;        const now = performance.now(); if (ev.t0 === null) { ev.t0 = now; avisar('\ud83d\ude81 \u00a1Un nuevo coche volador sobrevuela ChicaChica!'); }&#10;        const e = (now - ev.t0) \/ 1000; if (e &gt; 6) { eventos.shift(); return; }&#10;        const x = -80 + (e \/ 6) * (canvas.width + 160), y = 74 + Math.sin(e * 2) * 8;&#10;        ctx.save();&#10;        for (let k = 0; k &lt; 16; k++) { const a = 1 - k \/ 16; ctx.fillStyle = `rgba(255,214,90,${a * 0.7})`; ctx.beginPath(); ctx.arc(x - 30 - k * 12, y + 6 + Math.sin(e * 6 + k) * 5, 3 * a + 0.5, 0, Math.PI * 2); ctx.fill(); }   \/\/ estela dorada&#10;        ctx.restore(); dibujarCocheVolador(x, y, t, 1.2);&#10;    }&#10;    function dibujar() {&#10;        if (!abierto) return;&#10;        const fondo = Kutxa.valor(), sug = sugerida(), act = PROYECTOS.find(p =&gt; p.id === activo);&#10;        ctx.fillStyle = 'rgba(30,20,10,0.45)'; ctx.fillRect(0, 0, canvas.width, canvas.height);&#10;        mCaja(PN.x, PN.y, PN.w, PN.h, 18, '#fff8ea', '#8a5428', 4);&#10;        mCaja(CLOSE.x, CLOSE.y, 34, 34, 17, '#eee', '#999', 1.5); mTxt('\u2715', CLOSE.x + 17, CLOSE.y + 18, 16, '#555', 'center', true);&#10;        mTxt('\ud83e\udeb5 Kutxa AuZ \u00b7 Fondo com\u00fan', PN.x + 24, PN.y + 30, 20, '#5a3a1c', 'left', true);&#10;        mCaja(PN.x + PN.w - 170, PN.y + 14, 120, 28, 14, 'rgba(255,214,90,0.3)', '#b8860b', 1.5); mTxt('\ud83e\ude99 ' + Math.floor(fondo), PN.x + PN.w - 110, PN.y + 29, 15, '#5a3a1c', 'center', true);&#10;        const s = PROYECTOS.find(p =&gt; p.id === sug[0]); mTxt(`\ud83d\udc6d Las vecinas proponen: ${s.e} ${s.n} (${sug[1]})`, PN.x + 24, PN.y + 58, 12, '#4a6a5a', 'left', true);&#10;        mTxt(act ? `Proyecto activo: ${act.e} ${act.n}` : 'Elige un proyecto: solo uno activo a la vez', PN.x + 24, PN.y + 76, 12, '#5a3a1c', 'left', true);&#10;        if (act) { const f = Math.min(1, fondo \/ act.coste); mCaja(PN.x + 300, PN.y + 70, 300, 10, 5, 'rgba(0,0,0,0.12)'); mCaja(PN.x + 300, PN.y + 70, Math.max(6, 300 * f), 10, 5, f &gt;= 1 ? '#2a9d78' : '#f2a900'); mTxt(Math.floor(f * 100) + ' %', PN.x + 610, PN.y + 75, 11, '#5a3a1c', 'left', true); }&#10;        [['exp', '\ud83c\udfd7\ufe0f Expansi\u00f3n'], ['man', '\ud83d\udd27 Mantenimiento']].forEach(([id, txt], i) =&gt; { const t = TAB(i), on = tab === id; mCaja(t.x, t.y, t.w, t.h, 14, on ? '#8a5428' : 'rgba(0,0,0,0.06)', '#8a5428', 1.5); mTxt(txt, t.x + t.w \/ 2, t.y + 15, 13, on ? '#fff' : '#5a3a1c', 'center', true); });&#10;        const as = Asamblea.estado(); mCaja(CONV.x, CONV.y, CONV.w, CONV.h, 14, as.libre ? '#2a9d78' : '#b8b8b8', '#1d5a48', 1.5); mTxt(as.libre ? '\ud83d\uddf3\ufe0f Convocar asamblea' : as.etiqueta, CONV.x + CONV.w \/ 2, CONV.y + 15, 12, '#fff', 'center', true);&#10;        lista().forEach((p, i) =&gt; {&#10;            const c = card(i), on = p.id === activo, f = Math.min(1, fondo \/ p.coste), off = tope(p);&#10;            mCaja(c.x, c.y, c.w, c.h, 12, on ? 'rgba(124,255,217,0.25)' : off ? 'rgba(0,0,0,0.08)' : 'rgba(0,0,0,0.04)', on ? '#2a7a63' : '#d8c9a8', on ? 2.5 : 1.5);&#10;            mTxt(p.e, c.x + 26, c.y + 36, 28, '#000', 'center'); mTxt(p.n, c.x + 52, c.y + 18, 13, off ? '#888' : '#333', 'left', true); mTxt(p.d, c.x + 52, c.y + 36, 10, '#7a6a5a');&#10;            mTxt('\ud83e\ude99 ' + p.coste, c.x + c.w - 12, c.y + 18, 12, '#7a5a1a', 'right', true);&#10;            if (off) { mTxt(mant(p) ? '\u2714 En perfecto estado' : '\u2714 M\u00e1ximo alcanzado', c.x + 52, c.y + 58, 10, '#7a6a5a', 'left', true); return; }&#10;            if (p.id === sug[0]) mTxt('\ud83d\udc6d propuesto', c.x + c.w - 12, c.y + 36, 10, '#4a6a5a', 'right', true);&#10;            if (mant(p)) { const w = Desgaste.nivel(p.id); mTxt('Estado ' + Math.round((1 - w) * 100) + ' %', c.x + 52, c.y + 46, 9, w &gt; 0.5 ? '#c0392b' : w &gt; 0.25 ? '#b8860b' : '#2a7a63', 'left', true); }&#10;            mCaja(c.x + 52, c.y + 54, 220, 8, 4, 'rgba(0,0,0,0.12)'); mCaja(c.x + 52, c.y + 54, Math.max(4, 220 * f), 8, 4, f &gt;= 1 ? '#2a9d78' : '#f2a900');&#10;            mTxt(Math.floor(f * 100) + ' %', c.x + 282, c.y + 58, 10, '#5a3a1c', 'left', true); if (on) mTxt('\u25b6 ACTIVO', c.x + c.w - 12, c.y + 58, 10, '#2a7a63', 'right', true);&#10;        });&#10;        mTxt('Las vecinas votan \u00b7 un solo proyecto activo \u00b7 se cierra al llegar al coste \u00b7 cero deudas \ud83c\udf3f', PN.x + 24, PN.y + PN.h - 22, 11, '#7a6a5a');&#10;        mTxt(Persistencia.estado(), PN.x + 24, PN.y + PN.h - 40, 10, '#7a6a5a');&#10;        const conf = performance.now() &lt; confirma; mCaja(RESET.x, RESET.y, RESET.w, RESET.h, 13, conf ? '#c0392b' : 'rgba(0,0,0,0.06)', '#8a5428', 1.2); mTxt(conf ? '\u00bfSeguro? Toca otra vez' : '\u21ba Reiniciar partida', RESET.x + RESET.w \/ 2, RESET.y + 14, 11, conf ? '#fff' : '#7a6a5a', 'center', true);&#10;    }&#10;    function toque(x, y) {&#10;        if (!dentroRect(x, y, PN) || dentroRect(x, y, CLOSE)) { abierto = false; return; }&#10;        if (dentroRect(x, y, CONV)) { if (Asamblea.estado().libre) { if (Asamblea.convocar()) abierto = false; } else avisar('\ud83d\uddf3\ufe0f Las vecinas est\u00e1n ocupadas: prueba en un rato'); return; }&#10;        if (dentroRect(x, y, RESET)) { if (performance.now() &lt; confirma) Persistencia.reiniciar(); else { confirma = performance.now() + 4000; avisar('Toca otra vez para borrar todo el progreso'); } return; }&#10;        [['exp'], ['man']].forEach(([id], i) =&gt; { if (dentroRect(x, y, TAB(i))) tab = id; });&#10;        lista().forEach((p, i) =&gt; { if (!dentroRect(x, y, card(i))) return; if (tope(p)) { avisar(mant(p) ? '\u2714 Ya est\u00e1 en perfecto estado' : '\u2714 Ya se ha alcanzado el m\u00e1ximo de este proyecto'); return; } activo = activo === p.id ? null : p.id; });&#10;    }&#10;    function tick() {                                                                                                \/\/ cierre autom\u00e1tico al llegar al coste&#10;        const p = PROYECTOS.find(q =&gt; q.id === activo); if (!p) return;&#10;        if (tope(p)) { activo = null; return; }&#10;        if (Kutxa.valor() &gt;= p.coste &amp;&amp; Kutxa.gastar(p.coste)) { EFECTOS[p.id](); activo = null; avisar(`\ud83c\udf89 Kutxa AuZ: \u00a1${p.n} completado!`); }&#10;    }&#10;    return { dibujar, toque, tick, efectos, cerrar() { abierto = false; }, abierto: () =&gt; abierto, abrir() { abierto = true; }, zonaCofre: ZONA_COFRE, activo: () =&gt; activo, proyectos: PROYECTOS, volandoCoche: () =&gt; eventos.some(e =&gt; e.tipo === 'coche'),&#10;             efecto: id =&gt; EFECTOS[id](), fijarActivo(id) { if (PROYECTOS.some(p =&gt; p.id === id)) activo = id; },&#10;             avisar, sugerida, votables: () =&gt; PROYECTOS.filter(p =&gt; !tope(p)) };&#10;})();&#10;const Persistencia = (() =&gt; {&#10;    const CLAVE = 'chicachica:v1';&#10;    let ok = false, ultimo = '', reiniciando = false, guardado = false;&#10;    const num = (v, d, lo, hi) =&gt; Number.isFinite(+v) ? Math.min(hi, Math.max(lo, +v)) : d;&#10;    const almacen = () =&gt; { try { localStorage.setItem('__prueba', '1'); localStorage.removeItem('__prueba'); return true; } catch (e) { return false; } };&#10;    function capturar() {&#10;        const a = Apicultura.e;&#10;        return { v: 1, saldo: saldoMIIG26D, kutxa: Kutxa.exportar(), activo: KutxaPanel.activo(), flota: { vagones: flota.vagones, coches: flota.coches },&#10;            colmenas: HUERTA_COLMENAS.length, tinajas: LUR_TINAJAS.length, desgaste: Desgaste.exportar(),&#10;            apicultura: { nectar: a.nectar, resina: a.resina, sinCera: a.sinCera, miel: a.miel + (a.fermentaFin ? 4 : 0), cera: a.cera, propoleo: a.propoleo, hidromiel: a.hidromiel, jalea: a.jalea },   \/\/ si fermentaba, la miel se devuelve&#10;            stock: PUESTOS.map(q =&gt; q.prods.map(p =&gt; p.s)), recursos: { ...recursos }, bienestar: { ...bienestar }, cesta: cestaCosecha, banco: { ...BANCO_STOCK }, ventas: ventasHoy.slice(0, 20), silo: { ...SiloCompost.e }, h2: Math.round(Puerto.H2.nivel), aire: Math.round(Puerto.AIRE.n), fondo: { s: Math.round(Puerto.FONDO.s), b: Puerto.FONDO.b }, algas: Costa.cesta.algas, puestoAlgas: Costa.puesto.stock, noticias: Noticias.exportar(), diario: Diario.exportar(), parejas: habitantes.map(h =&gt; habitantes.indexOf(h.pareja)), casas: habitantes.map(h =&gt; h.casaAsignada) };&#10;    }&#10;    function aplicar(d) {&#10;        if (!d || d.v !== 1) return;                                                                          \/\/ versi\u00f3n desconocida: se ignora&#10;        saldoMIIG26D = num(d.saldo, 0, 0, 1e9);&#10;        Kutxa.importar(d.kutxa);&#10;        const f = d.flota || {}; flota.vagones = num(f.vagones, 0, 0, 2) | 0; flota.coches = num(f.coches, 0, 0, 9) | 0;&#10;        for (let i = HUERTA_COLMENAS.length; i &lt; num(d.colmenas, 3, 3, 5); i++) KutxaPanel.efecto('colmena');   \/\/ recrea colmenas y tinajas compradas&#10;        for (let i = LUR_TINAJAS.length; i &lt; num(d.tinajas, 4, 4, 6); i++) KutxaPanel.efecto('tinaja');&#10;        Desgaste.importar(d.desgaste);&#10;        const a = d.apicultura || {}; ['nectar', 'resina', 'sinCera', 'sinJalea', 'miel', 'cera', 'propoleo', 'hidromiel', 'jalea'].forEach(k =&gt; { Apicultura.e[k] = num(a[k], 0, 0, 999); }); Apicultura.e.fermentaFin = 0;&#10;        if (Array.isArray(d.stock)) PUESTOS.forEach((q, i) =&gt; q.prods.forEach((p, j) =&gt; { if (Array.isArray(d.stock[i]) &amp;&amp; d.stock[i][j] !== undefined) p.s = num(d.stock[i][j], p.s, 0, 999) | 0; }));&#10;        if (d.recursos) ['arcilla', 'resina', 'proteina', 'energia'].forEach(k =&gt; { recursos[k] = num(d.recursos[k], recursos[k], 0, 100); });&#10;        if (d.bienestar) ['alim', 'agua', 'viv', 'mov'].forEach(k =&gt; { bienestar[k] = num(d.bienestar[k], bienestar[k], 0, 100); });&#10;        cestaCosecha = num(d.cesta, 0, 0, 999) | 0;&#10;        if (d.banco &amp;&amp; typeof d.banco === 'object') Object.keys(d.banco).forEach(k =&gt; { if (\/^[\\w-]{1,24}$\/.test(k)) BANCO_STOCK[k] = num(d.banco[k], 0, 0, 999) | 0; });&#10;        if (Array.isArray(d.ventas)) { ventasHoy.length = 0; d.ventas.slice(0, 20).forEach(v =&gt; { if (v &amp;&amp; typeof v.puesto === 'string') ventasHoy.push({ puesto: v.puesto.slice(0, 40), txt: String(v.txt || '').slice(0, 60), tok: num(v.tok, 0, 0, 9999) }); }); }&#10;        if (d.h2 !== undefined) Puerto.H2.nivel = num(d.h2, 40, 0, 100);&#10;        if (d.aire !== undefined) Puerto.AIRE.n = num(d.aire, 60, 0, 100);&#10;        if (d.fondo &amp;&amp; typeof d.fondo === 'object') { Puerto.FONDO.s = num(d.fondo.s, 40, 0, 100); Puerto.FONDO.b = num(d.fondo.b, 3, 0, 8) | 0; }&#10;        if (d.algas !== undefined) Costa.cesta.algas = num(d.algas, 0, 0, 12) | 0;&#10;        if (d.puestoAlgas !== undefined) Costa.puesto.stock = num(d.puestoAlgas, 0, 0, 8) | 0;&#10;        Noticias.importar(d.noticias);&#10;        if (Array.isArray(d.parejas)) habitantes.forEach((h, i) =&gt; { const j = d.parejas[i] | 0; if (d.parejas[i] &gt;= 0 &amp;&amp; j !== i &amp;&amp; habitantes[j] &amp;&amp; d.parejas[j] === i) h.pareja = habitantes[j]; });   \/\/ las parejas se recuerdan&#10;        if (Array.isArray(d.casas)) habitantes.forEach((h, i) =&gt; { const c = d.casas[i]; if (Number.isInteger(c) &amp;&amp; c &gt;= 0 &amp;&amp; c &lt; casas.length) h.casaAsignada = c; });&#10;        Diario.importar(d.diario);&#10;        if (d.silo) ['silo', 'compost', 'residuos'].forEach(k =&gt; { SiloCompost.e[k] = num(d.silo[k], 0, 0, 60) | 0; });&#10;        if (typeof d.activo === 'string') KutxaPanel.fijarActivo(d.activo);&#10;        TREN.n = Math.min(4, 2 + flota.vagones); polen.length = 0;                                             \/\/ el tren ya viene con sus vagones; sin r\u00e1fagas de polen al cargar&#10;    }&#10;    function guardar() {&#10;        if (!ok || reiniciando) return;&#10;        try { const s = JSON.stringify(capturar()); if (s !== ultimo) { localStorage.setItem(CLAVE, s); ultimo = s; guardado = true; } } catch (e) { ok = false; }&#10;    }&#10;    function iniciar() {&#10;        ok = almacen(); if (!ok) return;&#10;        try { const raw = localStorage.getItem(CLAVE); if (raw) aplicar(JSON.parse(raw)); } catch (e) {}&#10;        try { ultimo = JSON.stringify(capturar()); } catch (e) { ok = false; return; }&#10;        setInterval(guardar, 5000);&#10;        document.addEventListener('visibilitychange', () =&gt; { if (document.hidden) guardar(); });&#10;        window.addEventListener('pagehide', guardar);&#10;    }&#10;    function reiniciar() {&#10;        reiniciando = true; try { localStorage.removeItem(CLAVE); } catch (e) {}&#10;        try { location.reload(); } catch (e) {}&#10;        setTimeout(() =&gt; { reiniciando = false; }, 1500);                                                       \/\/ si la recarga est\u00e1 bloqueada, sigue como antes&#10;    }&#10;    function exportarTexto() { try { guardar(); return JSON.stringify({ juego: 'chicachica', v: 1, fecha: new Date().toISOString().slice(0, 10), datos: capturar() }); } catch (e) { return ''; } }&#10;    function importarTexto(txt) {                                                                              \/\/ acepta el archivo completo o solo los datos; valida antes de tocar nada&#10;        let o; try { o = JSON.parse(String(txt || '').trim()); } catch (e) { return { ok: false, msg: 'No se puede leer: no parece un c\u00f3digo de ChicaChica.' }; }&#10;        const d = o &amp;&amp; o.juego === 'chicachica' ? o.datos : (o &amp;&amp; o.v === 1 ? o : null);&#10;        if (!d || d.v !== 1) return { ok: false, msg: 'Eso no es una partida de ChicaChica (o es de otra versi\u00f3n).' };&#10;        try { aplicar(d); } catch (e) { return { ok: false, msg: 'No se pudo cargar la partida.' }; }&#10;        ultimo = ''; guardar(); return { ok: true, msg: 'Partida cargada \u2714' };&#10;    }&#10;    return { iniciar, guardar, reiniciar, exportarTexto, importarTexto, estado: () =&gt; ok ? '\ud83d\udcbe Guardado autom\u00e1tico' + (guardado ? ' \u2714' : '') : '\ud83d\udcbe Este navegador no permite guardar el progreso' };&#10;})();&#10;const Asamblea = (() =&gt; {&#10;    let fase = 'reposo', f = 0, grupo = [], votos = [], ganador = null, enfriamiento = 3600, quien = 0;   \/\/ enfriamiento en fotogramas (\u22481 min hasta la primera autom\u00e1tica)&#10;    const KX = KUTXA_POS.x, KY = KUTXA_POS.y, libre = h =&gt; !h.durmiendo &amp;&amp; !h.enPlaya &amp;&amp; !h.oculta &amp;&amp; !h.arrastrando &amp;&amp; (h.estado === 'caminando' || h.estado === 'parada');&#10;    const hueco = (i, n) =&gt; { const a = Math.PI * (0.14 + 0.72 * (n &gt; 1 ? i \/ (n - 1) : 0.5)); return { x: KX + Math.cos(a) * 58, y: KY + 6 + Math.sin(a) * 26 }; };   \/\/ semic\u00edrculo ante el cofre&#10;    function soltar(h) { h.moviendoAsamblea = false; if (h.estado === 'asamblea') { h.estado = 'caminando'; nuevoObjetivo(h); } }&#10;    function elegirVoto(cands, sug) {                                                                              \/\/ cada vecina vota seg\u00fan lo que m\u00e1s hace falta, con su toque personal&#10;        const w = cands.map(p =&gt; (1 + (p.id === sug ? 3 : 0) + (p.cat === 'man' ? 4 * Desgaste.nivel(p.id) : 0) + (p.id === 'coche' &amp;&amp; flota.coches === 0 ? 1 : 0)) * (0.7 + Math.random() * 0.6));&#10;        let r = Math.random() * w.reduce((a, b) =&gt; a + b, 0); for (let i = 0; i &lt; cands.length; i++) { if ((r -= w[i]) &lt;= 0) return cands[i]; } return cands[cands.length - 1];&#10;    }&#10;    function convocar() {&#10;        if (fase !== 'reposo') return false;&#10;        const cands = KutxaPanel.votables(); if (!cands.length) { KutxaPanel.avisar('\u2714 No hay nada que votar: todo est\u00e1 en su m\u00e1ximo o en perfecto estado'); return false; }&#10;        const libres = habitantes.filter(libre).sort((a, b) =&gt; Math.hypot(a.x - KX, a.y - KY) - Math.hypot(b.x - KX, b.y - KY)).slice(0, 5);&#10;        if (libres.length &lt; 3) { KutxaPanel.avisar('\ud83d\uddf3\ufe0f Hacen falta al menos 3 vecinas libres para la asamblea'); return false; }&#10;        grupo = libres; votos = []; ganador = null; fase = 'reunion'; f = 0;&#10;        grupo.forEach((h, i) =&gt; { h.estado = 'asamblea'; h.asambleaSlot = hueco(i, grupo.length); });&#10;        KutxaPanel.avisar('\ud83d\uddf3\ufe0f \u00a1Las vecinas se re\u00fanen en la plaza para votar!'); return true;&#10;    }&#10;    function actualizar() {                                                                                        \/\/ se llama una vez por fotograma en el pueblo&#10;        if (enfriamiento &gt; 0) enfriamiento--;&#10;        if (fase === 'reposo') {                                                                                    \/\/ asamblea autom\u00e1tica&#10;            const v = KutxaPanel.votables();&#10;            if (enfriamiento &lt;= 0 &amp;&amp; !KutxaPanel.activo() &amp;&amp; v.length &amp;&amp; Kutxa.valor() &gt;= Math.min(...v.map(p =&gt; p.coste))) convocar();&#10;            return;&#10;        }&#10;        grupo = grupo.filter(h =&gt; { if (h.arrastrando || h.estado !== 'asamblea') { soltar(h); return false; } return true; });             \/\/ quien se lleve la jugadora, se va&#10;        if (grupo.length &lt; 3) { grupo.forEach(soltar); fase = 'reposo'; enfriamiento = 1800; return; }          \/\/ con menos de 3 no hay asamblea&#10;        f++;&#10;        let llegadas = 0;&#10;        grupo.forEach(h =&gt; {                                                                                        \/\/ caminan al hueco y miran al cofre&#10;            const s = h.asambleaSlot, dx = s.x - h.x, dy = s.y - h.y, d = Math.hypot(dx, dy);&#10;            if (d &gt; 2) { h.x += dx \/ d * 1.4; h.y += dy \/ d * 1.4; if (Math.abs(dx) &gt; 2) h.direccion = dx &gt;= 0 ? 1 : -1; h.moviendoAsamblea = true; }&#10;            else { h.moviendoAsamblea = false; h.direccion = KX &gt;= h.x ? 1 : -1; llegadas++; }&#10;        });&#10;        if (fase === 'reunion' &amp;&amp; (llegadas === grupo.length || f &gt; 600)) {                                         \/\/ todas listas \u2192 votaci\u00f3n&#10;            const cands = KutxaPanel.votables(), sug = KutxaPanel.sugerida()[0];&#10;            votos = grupo.map(() =&gt; elegirVoto(cands, sug)); fase = 'votacion'; f = 0; quien = 0;&#10;        } else if (fase === 'votacion') {&#10;            quien = Math.min(grupo.length, Math.floor(f \/ 55));                                                      \/\/ una voz cada ~1 s&#10;            if (f &gt; grupo.length * 55 + 90) {                                                                       \/\/ recuento&#10;                const cuenta = {}; votos.forEach(p =&gt; { cuenta[p.id] = (cuenta[p.id] || 0) + 1; });&#10;                const max = Math.max(...Object.values(cuenta)), empate = votos.filter(p =&gt; cuenta[p.id] === max);&#10;                ganador = empate[Math.floor(Math.random() * empate.length)];&#10;                KutxaPanel.fijarActivo(ganador.id); KutxaPanel.avisar(`\ud83d\uddf3\ufe0f Las vecinas han votado: ${ganador.e} ${ganador.n} (${max} de ${grupo.length})`);&#10;                fase = 'resultado'; f = 0;&#10;            }&#10;        } else if (fase === 'resultado' &amp;&amp; f &gt; 150) { grupo.forEach(soltar); grupo = []; fase = 'reposo'; enfriamiento = 9000; }   \/\/ vuelven a pasear; la siguiente, en ~2,5 min&#10;    }&#10;    function dibujar(t) {                                                                                           \/\/ burbujas de voto, \u270b y recuento sobre el cofre&#10;        if (fase === 'reposo' || fase === 'reunion') return;&#10;        ctx.save();&#10;        const cuenta = {}; for (let i = 0; i &lt; quien; i++) cuenta[votos[i].id] = (cuenta[votos[i].id] || 0) + 1;&#10;        grupo.forEach((h, i) =&gt; {&#10;            if (fase === 'votacion' &amp;&amp; i &gt;= quien) return;&#10;            const p = votos[i], ganadora = fase === 'resultado' &amp;&amp; p.id === ganador.id, dy = ganadora ? -Math.abs(Math.sin(t \/ 6 + i)) * 5 : 0;&#10;            mCaja(h.x - 13, h.y - 70 + dy, 26, 22, 10, ganadora ? 'rgba(255,245,200,0.97)' : 'rgba(255,255,255,0.95)', ganadora ? '#b8860b' : '#20262e', 1.5); mTxt(p.e, h.x, h.y - 59 + dy, 14, '#000', 'center');&#10;            if (fase === 'votacion' &amp;&amp; i === quien - 1 &amp;&amp; f % 55 &lt; 40) mTxt('\u270b', h.x + 15, h.y - 36 + Math.sin(t \/ 4) * 2, 13, '#000', 'center');      \/\/ levanta la mano al votar&#10;            if (ganadora) mTxt('\ud83c\udf89', h.x + 12, h.y - 76 + dy, 11, '#000', 'center');&#10;        });&#10;        const items = Object.entries(cuenta); if (items.length) {                                                                                           \/\/ recuento&#10;            const txt = items.map(([id, n]) =&gt; KutxaPanel.proyectos.find(p =&gt; p.id === id).e + '\u00d7' + n).join('  '), w = txt.length * 9 + 22;&#10;            mCaja(KX - w \/ 2, KY - 100, w, 18, 9, 'rgba(255,248,234,0.95)', '#8a5428', 1.5); mTxt('\ud83d\uddf3\ufe0f ' + txt, KX, KY - 91, 11, '#5a3a1c', 'center', true);&#10;        }&#10;        ctx.restore();&#10;    }&#10;    return { convocar, actualizar, dibujar, estado: () =&gt; fase === 'reposo' ? { libre: enfriamiento &lt;= 0, etiqueta: enfriamiento &gt; 0 ? '\ud83d\uddf3\ufe0f Vecinas descansando\u2026' : '' } : { libre: false, etiqueta: '\ud83d\uddf3\ufe0f Asamblea en curso\u2026' } };&#10;})();&#10;function dibujarPanelKutxa() { KutxaPanel.dibujar(); }&#10;function dibujarEfectosKutxa(t) { KutxaPanel.efectos(t); }&#10;let nochePlaya = false;&#10;const NOCHE_BOTON = { x: 654, y: 14, w: 38, h: 34 }, D45 = 45000;&#10;const BARCO = { x: 480, y: 178, desp: 0, ang: 0 }, barcoBob = () =&gt; Math.sin(performance.now() \/ 600) * 3;&#10;const HELADERIA = { x: 480, y: 356 };   \/\/ centrada en la playa; las plazas de helado (\u00b130) y las Genoides siguen a este valor&#10;const ZONA_BARCO_A = { get x() { return BARCO.x + BARCO.desp - 16; }, get y() { return BARCO.y - 12 + barcoBob(); }, accion: 'barco', icono: '\u2693', dur: D45, salida: { x: 450, y: 384 } };&#10;const ZONA_BARCO_B = { get x() { return BARCO.x + BARCO.desp + 16; }, get y() { return BARCO.y - 12 + barcoBob(); }, accion: 'barco', icono: '\u2693', dur: D45, salida: { x: 510, y: 384 } };&#10;const ZONAS_TUMBONA = [{ x: 418, y: 470, rot: -Math.PI \/ 2 }, { x: 522, y: 470, rot: Math.PI \/ 2 }, { x: 418, y: 508, rot: -Math.PI \/ 2 }, { x: 522, y: 508, rot: Math.PI \/ 2 }].map(z =&gt; ({ ...z, accion: 'tumbada', icono: '\ud83d\ude0e', dur: D45, auto: true }));&#10;const ZONAS_BAR = [{ x: 852, y: 466 }, { x: 906, y: 466 }].map(z =&gt; ({ ...z, accion: 'refrigerio', icono: '\ud83c\udf79', dur: D45, auto: true }));&#10;const ZONAS_HELADO = [{ x: HELADERIA.x - 30, y: 436 }, { x: HELADERIA.x + 30, y: 436 }].map(z =&gt; ({ ...z, accion: 'helado', icono: '\ud83c\udf66', dur: D45, auto: true }));&#10;const ZONAS_BANO = [{ x: 150, y: 352 }, { x: 335, y: 356 }, { x: 560, y: 358 }].map(z =&gt; ({ ...z, accion: 'bano', icono: '\ud83c\udfca', dur: D45, auto: true, pose: 'agua' }));&#10;ZONA_SURF.auto = true; ZONA_WINDSURF.auto = true;                                                  \/\/ las chicas tambi\u00e9n van solas a surfear&#10;ZONAS_PLAYA.push({ x: 868, y: 326, accion: 'bucear', icono: '\ud83e\udd3f', dur: 70000, auto: true }, { x: 846, y: 334, accion: 'bucear', icono: '\ud83e\udd3f', dur: 70000, auto: true });      \/\/ estaci\u00f3n de buceo: las chicas bajan al fondo marino&#10;ZONAS_PLAYA.push({ x: 892, y: 268, accion: 'moto', icono: '\ud83c\udf0a', dur: 60000, auto: true, idx: 0 }, { x: 876, y: 300, accion: 'moto', icono: '\ud83c\udf0a', dur: 60000, auto: true, idx: 1 });      \/\/ embarcadero: las chicas pilotan las motos de agua&#10;ZONAS_PLAYA.push(ZONA_BARCO_A, ZONA_BARCO_B, ...ZONAS_TUMBONA, ...ZONAS_BAR, ...ZONAS_HELADO, ...ZONAS_BANO);&#10;const ocupadaPlaya = z =&gt; habitantesEnPlaya.some(h =&gt; h.zonaPlaya === z);&#10;const GEN_BAR = [{ x: 852, y: 444, estilo: 'largo', fase: 0.4 }, { x: 906, y: 444, estilo: 'pincho', fase: 2.1 }].map(g =&gt; ({ ...g, dir: 1, espera: 1, trab: false, ic: '\ud83c\udf79' }));&#10;const GEN_HELADO = [{ x: HELADERIA.x - 42, estilo: 'mohawk', fase: 1.2 }, { x: HELADERIA.x + 10, estilo: 'largo', fase: 3.3 }].map(g =&gt; ({ ...g, y: 0, dir: 1, espera: 1, trab: false, ic: null }));&#10;function liberarZonaPlaya(h) {&#10;    const z = h.zonaPlaya, s = z.salida || { x: z.x, y: Math.max(420, Math.min(500, z.y + 24)) };&#10;    h.playaEstado = 'de_pie'; h.equipoSurf = null; h.zonaPlaya = null; h.horaEntradaAgua = 0; h.posPlaya.x = s.x; h.posPlaya.y = s.y; h.objetivoPlaya = null; h.esperaPlaya = 40;&#10;}&#10;function objetivoLibrePlaya(h) {&#10;    if (h.equipoSurf) {                                                                              \/\/ ya lleva su tabla: va directa a la orilla&#10;        const zs = ZONAS_PLAYA.filter(z =&gt; z.accion === (h.equipoSurf === 'windsurf' ? 'windsurf' : 'surfeando') &amp;&amp; !ocupadaPlaya(z) &amp;&amp; !habitantesEnPlaya.some(o =&gt; o !== h &amp;&amp; o.objetivoPlaya &amp;&amp; o.objetivoPlaya.zona === z));&#10;        if (zs.length) return { x: zs[0].x, y: zs[0].y, zona: zs[0] }; h.equipoSurf = null;&#10;    }                                                                   \/\/ 40 %: se va por su cuenta a ba\u00f1arse, tumbarse, tomar algo o comprar un helado&#10;    if (Math.random() &lt; 0.4) {&#10;        const libres = ZONAS_PLAYA.filter(z =&gt; z.auto &amp;&amp; !ocupadaPlaya(z) &amp;&amp; !habitantesEnPlaya.some(o =&gt; o !== h &amp;&amp; o.objetivoPlaya &amp;&amp; o.objetivoPlaya.zona === z) &amp;&amp; (z.accion !== 'moto' || Puerto.motoDisponible(z.idx)) &amp;&amp; (z.accion !== 'bucear' || Puerto.buceoDisponible()));&#10;        if (libres.length) { const surf = libres.filter(z =&gt; z.accion === 'surfeando' || z.accion === 'windsurf'), motos = libres.filter(z =&gt; z.accion === 'moto'), buzos = libres.filter(z =&gt; z.accion === 'bucear'), lista = (motos.length &amp;&amp; Math.random() &lt; 0.3) ? motos : (buzos.length &amp;&amp; Math.random() &lt; 0.3) ? buzos : (surf.length &amp;&amp; Math.random() &lt; 0.5) ? surf : libres, z = lista[Math.floor(Math.random() * lista.length)]; return (z.accion === 'surfeando' || z.accion === 'windsurf') &amp;&amp; !h.equipoSurf ? { x: 680, y: 398, zona: null, equipo: { x: z.x, y: z.y, zona: z }, tipo: z.accion === 'windsurf' ? 'windsurf' : 'surf' } : { x: z.x, y: z.y, zona: z }; }&#10;    }&#10;    return { x: 90 + Math.random() * 780, y: 400 + Math.random() * 110 };&#10;}&#10;function llegarAZonaPlaya(h) {&#10;    const z = h.objetivoPlaya.zona; h.objetivoPlaya = null;&#10;    if (ocupadaPlaya(z)) { h.esperaPlaya = 30; return; }&#10;    if (z.accion === 'moto' &amp;&amp; !Puerto.arrancarMoto(z.idx)) { h.esperaPlaya = 30; return; }&#10;    if (z.accion === 'bucear' &amp;&amp; !Puerto.empezarBuceo(h)) { h.esperaPlaya = 30; return; }                     \/\/ sin aire en las botellas, no baja                 \/\/ si la moto ya no est\u00e1 lista, espera y elige otra cosa&#10;    h.zonaPlaya = z; h.playaEstado = z.accion; h.horaEntradaAgua = Date.now();&#10;    if (z.accion === 'comprando') Costa.vender();                                                     \/\/ compra algas, t\u00e9 o snacks en el puesto&#10;}&#10;function aguaBano(x, y, t) {                                                                       \/\/ agua por el pecho + ondas y salpicaduras&#10;    ctx.save(); ctx.fillStyle = 'rgba(74,146,176,0.62)'; ctx.beginPath(); ctx.ellipse(x, y + 16, 27, 9, 0, 0, Math.PI * 2); ctx.fill();&#10;    ctx.strokeStyle = 'rgba(255,255,255,0.7)'; ctx.lineWidth = 1.2; for (let k = 0; k &lt; 2; k++) { const r = 8 + ((t \/ 3 + k * 14) % 28); ctx.globalAlpha = 1 - r \/ 36; ctx.beginPath(); ctx.ellipse(x, y + 16, r, r * 0.34, 0, 0, Math.PI * 2); ctx.stroke(); }&#10;    ctx.globalAlpha = 0.9; ctx.fillStyle = '#fff'; for (let k = 0; k &lt; 3; k++) { const f = ((t \/ 18) + k \/ 3) % 1; ctx.beginPath(); ctx.arc(x + Math.sin(k * 4 + t \/ 9) * 18, y + 10 - f * 14, 1.6, 0, Math.PI * 2); ctx.fill(); } ctx.restore();&#10;}&#10;function dibujarBarcoAtras(t) {&#10;    const ocupado = habitantesEnPlaya.some(h =&gt; h.zonaPlaya === ZONA_BARCO_A || h.zonaPlaya === ZONA_BARCO_B);&#10;    if (ocupado) { BARCO.ang += 0.004; BARCO.desp = Math.sin(BARCO.ang) * 70; }                         \/\/ con chicas a bordo, navega suave&#10;    const x = BARCO.x + BARCO.desp, y = BARCO.y + barcoBob();&#10;    ctx.save(); ctx.lineWidth = 2; ctx.strokeStyle = '#000';&#10;    ctx.fillStyle = 'rgba(255,255,255,0.25)'; ctx.beginPath(); ctx.ellipse(x, y + 24, 56, 5, 0, 0, Math.PI * 2); ctx.fill();    \/\/ estela&#10;    ctx.fillStyle = '#6b4a2b'; ctx.beginPath(); ctx.moveTo(x - 46, y - 4); ctx.quadraticCurveTo(x - 40, y + 20, x - 18, y + 22); ctx.lineTo(x + 18, y + 22); ctx.quadraticCurveTo(x + 40, y + 20, x + 46, y - 4); ctx.closePath(); ctx.fill(); ctx.stroke();   \/\/ interior del casco&#10;    ctx.strokeStyle = '#5a3a1c'; ctx.lineWidth = 3; ctx.beginPath(); ctx.moveTo(x + 2, y - 4); ctx.lineTo(x + 2, y - 64); ctx.stroke();&#10;    ctx.fillStyle = '#1d3f7a'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.5; ctx.beginPath(); ctx.moveTo(x - 38, y - 4); ctx.lineTo(x - 8, y - 4); ctx.lineTo(x - 12, y - 14); ctx.lineTo(x - 34, y - 14); ctx.closePath(); ctx.fill(); ctx.stroke(); ctx.strokeStyle = 'rgba(140,190,255,0.8)'; ctx.lineWidth = 0.8; ctx.beginPath(); for (let k = 1; k &lt; 4; k++) { ctx.moveTo(x - 34 + k * 6.5, y - 14); ctx.lineTo(x - 38 + k * 7.5, y - 4); } ctx.moveTo(x - 36, y - 9); ctx.lineTo(x - 10, y - 9); ctx.stroke();       \/\/ paneles solares del barquito                                                                                             \/\/ m\u00e1stil&#10;    ctx.fillStyle = '#ffe3f1'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.5; ctx.beginPath(); ctx.moveTo(x + 4, y - 62); ctx.quadraticCurveTo(x + 40, y - 36, x + 38, y - 12); ctx.lineTo(x + 4, y - 12); ctx.closePath(); ctx.fill(); ctx.stroke();    \/\/ vela&#10;    ctx.fillStyle = '#ff69b4'; ctx.fillRect(x + 6, y - 40, 30, 6); ctx.fillStyle = '#e53935'; ctx.beginPath(); ctx.moveTo(x + 2, y - 64); ctx.lineTo(x - 12, y - 59 + Math.sin(t \/ 8) * 2); ctx.lineTo(x + 2, y - 54); ctx.fill();                      \/\/ franja y bandera&#10;    ctx.restore();&#10;}&#10;function dibujarBarcoFrente(t) {                                                                    \/\/ la borda tapa a las chicas por la cintura&#10;    const x = BARCO.x + BARCO.desp, y = BARCO.y + barcoBob();&#10;    ctx.save(); ctx.lineWidth = 2; ctx.strokeStyle = '#000'; ctx.fillStyle = '#a5703a';&#10;    ctx.beginPath(); ctx.moveTo(x - 46, y - 2); ctx.lineTo(x + 46, y - 2); ctx.quadraticCurveTo(x + 40, y + 20, x + 18, y + 22); ctx.lineTo(x - 18, y + 22); ctx.quadraticCurveTo(x - 40, y + 20, x - 46, y - 2); ctx.closePath(); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = '#fff'; ctx.fillRect(x - 41, y + 6, 82, 4); ctx.fillStyle = '#ffd54a'; ctx.beginPath(); ctx.arc(x - 28, y + 14, 2, 0, Math.PI * 2); ctx.arc(x + 28, y + 14, 2, 0, Math.PI * 2); ctx.fill();&#10;    ctx.restore();&#10;}&#10;function dibujarResort(t) {&#10;    ctx.save(); ctx.lineWidth = 2; ctx.strokeStyle = '#000';&#10;    sombra(470, 520, 120, 10, 0.12);&#10;    ctx.fillStyle = '#d9c9a0'; ctx.fillRect(364, 484 + 4, 212, 6); ctx.strokeRect(364, 488, 212, 6);                                   \/\/ pasarela de madera clara&#10;    ZONAS_TUMBONA.forEach(z =&gt; {                                                                                                          \/\/ tumbonas&#10;        const cx = z.x, cy = z.y + 8, cab = z.rot &lt; 0 ? -1 : 1;&#10;        ctx.fillStyle = '#a5703a'; ctx.fillRect(cx - 44, cy - 2, 88, 6); ctx.strokeRect(cx - 44, cy - 2, 88, 6);&#10;        ctx.fillStyle = z.y &lt; 490 ? '#ff9ccf' : '#7cdcc8'; ctx.fillRect(cx - 40, cy - 8, 80, 8); ctx.strokeRect(cx - 40, cy - 8, 80, 8);&#10;        ctx.fillStyle = '#fff'; ctx.fillRect(cx + cab * 30 - 6, cy - 12, 12, 5); ctx.strokeRect(cx + cab * 30 - 6, cy - 12, 12, 5);     \/\/ almohada&#10;    });&#10;    ctx.fillStyle = '#6b4a2b'; ctx.fillRect(468, 440, 5, 62);                                                                             \/\/ palapa: poste, sombrilla de paja y flecos&#10;    ctx.fillStyle = '#e0b84a'; ctx.beginPath(); ctx.ellipse(470, 440, 50, 13, 0, Math.PI, 0); ctx.fill(); ctx.stroke(); ctx.fillRect(420, 440, 100, 4);&#10;    for (let k = 0; k &lt; 11; k++) { ctx.beginPath(); ctx.moveTo(422 + k * 9.6, 444); ctx.lineTo(422 + k * 9.6 + Math.sin(t \/ 20 + k) * 1.5, 452); ctx.stroke(); }&#10;    mTxt('\ud83c\udf79', 470, 497, 13, '#000', 'center'); mTxt('\ud83c\udfd0', 575, 520, 15, '#000', 'center'); mTxt('\ud83e\uddf4', 366, 521, 12, '#000', 'center');&#10;    ctx.restore();&#10;}&#10;function dibujarChiringuito(t, now) {&#10;    ctx.save(); ctx.lineWidth = 2; ctx.strokeStyle = '#000'; sombra(880, 462, 84, 8, 0.2);&#10;    ctx.fillStyle = '#8a5a2b'; [816, 944].forEach(px =&gt; { ctx.fillRect(px - 5, 394, 10, 61); ctx.strokeRect(px - 5, 394, 10, 61); });          \/\/ postes de madera&#10;    ctx.fillStyle = '#e0b84a'; ctx.beginPath(); ctx.moveTo(796, 396); ctx.lineTo(880, 346); ctx.lineTo(962, 396); ctx.closePath(); ctx.fill(); ctx.stroke();   \/\/ techo de paja&#10;    ctx.lineWidth = 1; ctx.strokeStyle = 'rgba(120,80,20,0.7)'; for (let k = 0; k &lt; 16; k++) { const px = 800 + k * 10.4; ctx.beginPath(); ctx.moveTo(px, 396); ctx.lineTo(px + 1, 404 + (k % 3)); ctx.stroke(); }                    \/\/ flecos de paja&#10;    ctx.lineWidth = 1.5; ctx.strokeStyle = '#3b2412'; ctx.fillStyle = '#c28a4b'; ctx.fillRect(832, 398, 96, 16); ctx.strokeRect(832, 398, 96, 16); mTxt('CHIRINGUITO', 880, 406, 9, '#3b2412', 'center', true);   \/\/ cartel&#10;    GEN_BAR.forEach((g, i) =&gt; { g.trab = ocupadaPlaya(ZONAS_BAR[i]); Industria.genoide(g, now); });                                       \/\/ Genoides tras la barra&#10;    ctx.lineWidth = 2; ctx.strokeStyle = '#000'; ctx.fillStyle = '#b9854f'; ctx.fillRect(826, 430, 108, 26); ctx.strokeRect(826, 430, 108, 26);        \/\/ barra&#10;    ctx.fillStyle = '#d6a56a'; ctx.fillRect(820, 426, 120, 6); ctx.strokeRect(820, 426, 120, 6);&#10;    ctx.strokeStyle = 'rgba(60,36,18,0.4)'; ctx.lineWidth = 1; [438, 446].forEach(y =&gt; { ctx.beginPath(); ctx.moveTo(826, y); ctx.lineTo(934, y); ctx.stroke(); });&#10;    mTxt('\ud83c\udf79', 842, 424, 13, '#000', 'center'); mTxt('\ud83e\udd65', 880, 424, 13, '#000', 'center'); mTxt('\ud83c\udf7a', 920, 424, 13, '#000', 'center');&#10;    ZONAS_BAR.forEach(z =&gt; { ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.fillStyle = '#c0392b'; ctx.fillRect(z.x - 2, z.y + 22, 4, 12); ctx.beginPath(); ctx.ellipse(z.x, z.y + 22, 10, 4, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); });   \/\/ taburetes&#10;    ctx.restore();&#10;}&#10;function dibujarHeladeria(t, now) {&#10;    const x = HELADERIA.x, bob = Math.sin(t \/ 45) * 4, y = HELADERIA.y + bob;&#10;    ctx.save(); ctx.lineWidth = 2; ctx.strokeStyle = '#000'; sombra(x, 414, 62 - bob, 8, 0.24);                                               \/\/ sombra sobre la arena&#10;    [-56, -20, 20, 56].forEach(dx =&gt; { ctx.fillStyle = `rgba(120,230,255,${0.4 + 0.25 * Math.sin(t \/ 4 + dx)})`; ctx.beginPath(); ctx.ellipse(x + dx, y + 46, 10, 4, 0, 0, Math.PI * 2); ctx.fill(); });   \/\/ propulsores&#10;    ctx.fillStyle = '#5a6066'; [-56, -20, 20, 56].forEach(dx =&gt; ctx.fillRect(x + dx - 6, y + 38, 12, 6));&#10;    ctx.fillStyle = '#9fe3d0'; ctx.beginPath(); ctx.roundRect ? ctx.roundRect(x - 72, y - 44, 144, 84, 14) : ctx.rect(x - 72, y - 44, 144, 84); ctx.fill(); ctx.stroke();   \/\/ carrocer\u00eda&#10;    ctx.fillStyle = '#7ccfba'; ctx.beginPath(); ctx.roundRect ? ctx.roundRect(x + 38, y - 24, 34, 64, 12) : ctx.rect(x + 38, y - 24, 34, 64); ctx.fill(); ctx.stroke();   \/\/ cabina&#10;    ctx.fillStyle = '#d8f0ff'; ctx.beginPath(); ctx.roundRect ? ctx.roundRect(x + 46, y - 18, 22, 20, 5) : ctx.rect(x + 46, y - 18, 22, 20); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = '#ffeb9a'; ctx.beginPath(); ctx.arc(x + 68, y + 24, 3, 0, Math.PI * 2); ctx.fill(); ctx.stroke();                          \/\/ faro&#10;    [[x - 66, 0], [x - 14, 1]].forEach(([wx, i]) =&gt; {                                                                                         \/\/ ventanillas con su Genoide&#10;        ctx.fillStyle = '#2c3340'; ctx.fillRect(wx, y - 34, 48, 54);&#10;        const g = GEN_HELADO[i]; g.x = wx + 24; g.y = y - 7 + 28; g.trab = ocupadaPlaya(ZONAS_HELADO[i]);&#10;        ctx.save(); ctx.beginPath(); ctx.rect(wx, y - 34, 48, 54); ctx.clip(); Industria.genoide(g, now); ctx.restore(); ctx.strokeRect(wx, y - 34, 48, 54);&#10;    });&#10;    for (let k = 0; k &lt; 8; k++) { ctx.fillStyle = k % 2 ? '#fff' : '#ff8fb8'; ctx.fillRect(x - 70 + k * 12.4, y - 44, 12.4, 10); }               \/\/ toldo a rayas&#10;    ctx.fillStyle = '#fff'; ctx.fillRect(x - 68, y + 20, 104, 7); ctx.strokeRect(x - 68, y + 20, 104, 7);                                       \/\/ mostrador&#10;    ctx.fillStyle = '#e2a65a'; ctx.beginPath(); ctx.moveTo(x - 28, y - 50); ctx.lineTo(x - 12, y - 50); ctx.lineTo(x - 20, y - 36); ctx.closePath(); ctx.fill(); ctx.stroke();   \/\/ cartel: cucurucho y bolas&#10;    ctx.fillStyle = '#ff9ccf'; ctx.beginPath(); ctx.arc(x - 20, y - 56, 8, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#fff'; ctx.beginPath(); ctx.arc(x - 20, y - 66, 7, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;    ctx.fillStyle = 'rgba(200,220,255,0.55)'; [x - 72, x + 72].forEach((px, i) =&gt; { ctx.beginPath(); ctx.ellipse(px, y - 48, 16, 3 + Math.abs(Math.sin(t \/ 2 + i)) * 2, 0, 0, Math.PI * 2); ctx.fill(); });   \/\/ h\u00e9lices&#10;    ctx.restore();&#10;}&#10;function dibujarBotonNoche() {&#10;    const b = NOCHE_BOTON; ctx.save(); mCaja(b.x, b.y, b.w, b.h, 17, nochePlaya ? '#1b2a5e' : 'rgba(255,255,255,0.92)', nochePlaya ? '#ffd86b' : '#ff69b4', 2);&#10;    mTxt(nochePlaya ? '\u2600\ufe0f' : '\ud83c\udf19', b.x + b.w \/ 2, b.y + b.h \/ 2 + 1, 18, '#000', 'center'); ctx.restore();&#10;}&#10;function luzPlaya(x, y, r, col, a) { const g = ctx.createRadialGradient(x, y, 1, x, y, r); g.addColorStop(0, `rgba(${col},${a})`); g.addColorStop(1, `rgba(${col},0)`); ctx.fillStyle = g; ctx.beginPath(); ctx.arc(x, y, r, 0, Math.PI * 2); ctx.fill(); }&#10;function dibujarNochePlaya(t) {&#10;    if (!nochePlaya) return;&#10;    ctx.save(); ctx.fillStyle = 'rgba(10,16,52,0.52)'; ctx.fillRect(0, 0, canvas.width, canvas.height);                                      \/\/ atardecer \u2192 noche&#10;    ctx.fillStyle = '#fff'; for (let i = 0; i &lt; 40; i++) { ctx.globalAlpha = 0.4 + 0.6 * Math.abs(Math.sin(t \/ 30 + i)); ctx.fillRect((i * 97) % 940 + 10, (i * 53) % 84 + 4, 2, 2); } ctx.globalAlpha = 1;   \/\/ estrellas&#10;    ctx.fillStyle = '#fff6cf'; ctx.beginPath(); ctx.arc(870, 46, 17, 0, Math.PI * 2); ctx.fill(); ctx.fillStyle = 'rgba(10,16,52,0.35)'; ctx.beginPath(); ctx.arc(878, 42, 14, 0, Math.PI * 2); ctx.fill();   \/\/ luna&#10;    ctx.globalCompositeOperation = 'lighter';&#10;    luzPlaya(870, 46, 60, '255,246,207', 0.4); for (let k = 0; k &lt; 9; k++) luzPlaya(870 + Math.sin(t \/ 20 + k) * (4 + k), 100 + k * 22, 10 + k, '255,246,207', 0.12);    \/\/ reflejo en el mar&#10;    for (let k = 0; k &lt; 11; k++) luzPlaya(806 + k * 15.4, 398 + Math.sin(k) * 2, 12, '255,200,110', 0.5 + 0.2 * Math.sin(t \/ 10 + k));               \/\/ bombillas del chiringuito&#10;    luzPlaya(880, 438, 50, '255,190,100', 0.3);&#10;    luzPlaya(BARCO.x + BARCO.desp, BARCO.y - 62 + barcoBob(), 26, '255,210,120', 0.55);                                                              \/\/ farol del barco&#10;    const hy = HELADERIA.y + Math.sin(t \/ 45) * 4; luzPlaya(HELADERIA.x, 410, 60, '120,230,255', 0.32); luzPlaya(HELADERIA.x - 18, hy - 7, 44, '255,200,140', 0.3); luzPlaya(HELADERIA.x + 76, hy + 24, 30, '255,240,160', 0.5);   \/\/ ne\u00f3n, ventanillas y faro&#10;    luzPlaya(470, 438, 46, '255,200,120', 0.4); [372, 570].forEach(lx =&gt; luzPlaya(lx, 478, 22, '255,210,140', 0.35));                                  \/\/ palapa y farolillos del resort&#10;    luzPlaya(ZONA_CASETA.x, ZONA_CASETA.y - 34, 30, '255,200,110', 0.4); Puerto.lucesNochePlaya(t);                                                                             \/\/ farol de la caseta&#10;    ctx.restore();&#10;    ctx.save(); ctx.fillStyle = '#ffd98a'; for (let k = 0; k &lt; 11; k++) { ctx.beginPath(); ctx.arc(806 + k * 15.4, 398 + Math.sin(k) * 2, 2.4, 0, Math.PI * 2); ctx.fill(); } ctx.restore();               \/\/ bombillas encendidas&#10;}&#10;function dibujarEscenarioPlayaNuevo(t) { const now = performance.now(); dibujarBarcoAtras(t); dibujarResort(t); dibujarChiringuito(t, now); dibujarHeladeria(t, now); }&#10;function dibujarFrentePlayaNuevo(t) { dibujarBarcoFrente(t); dibujarNochePlaya(t); dibujarBotonNoche(); }&#10;const ZONA_POLEA1 = { x: 70,  y: 330, accion: 'poleas', icono: '\ud83c\udfcb\ufe0f', unica: true };&#10;const ZONA_POLEA2 = { x: 610, y: 330, accion: 'poleas', icono: '\ud83c\udfcb\ufe0f', unica: true };&#10;const ZONA_RACK   = { x: 430, y: 336, accion: 'levantando', icono: '\ud83d\udcaa', unica: true };                  \/\/ rack de kettlebells: mismas pesas en otro puesto&#10;const ZONAS_ESTERILLA = [{ x: 310, y: 455, accion: 'yoga', icono: '\ud83e\uddd8' }, { x: 410, y: 455, accion: 'pilates', icono: '\ud83e\udd38' }, { x: 510, y: 455, accion: 'yoga', icono: '\ud83e\uddd8' }].map(z =&gt; ({ ...z, unica: true, relax: true }));&#10;const ZONAS_BANCO = [{ x: 592, y: 461 }, { x: 632, y: 461 }, { x: 672, y: 461 }].map(z =&gt; ({ ...z, accion: 'charlando', icono: '\ud83d\udcac', unica: true, relax: true }));&#10;const ZONAS_VENDING = [{ x: 728, y: 462, k: 'bebida', col: '62,240,208' }, { x: 798, y: 462, k: 'snack', col: '155,229,100' }, { x: 868, y: 462, k: 'batido', col: '199,125,255' }].map(z =&gt; ({ ...z, accion: 'tomando', icono: z.k === 'snack' ? '\ud83e\udd57' : '\ud83e\udd64', unica: true }));&#10;ZONAS_GIMNASIO.push(ZONA_POLEA1, ZONA_POLEA2, ZONA_RACK, ...ZONAS_ESTERILLA, ...ZONAS_BANCO, ...ZONAS_VENDING);&#10;const POOL = { x: 710, y: 300, w: 180, h: 110 }, NADO = { x0: 746, x1: 858, carriles: [332, 378] };&#10;function dibujarInteriorPiscina(t) {&#10;    const { x: x0, y: y0, w, h } = POOL; ctx.save();&#10;    ctx.beginPath(); ctx.rect(x0 + 6, y0 + 6, w - 12, h - 12); ctx.clip();&#10;    ctx.strokeStyle = 'rgba(255,255,255,0.22)'; ctx.lineWidth = 1; ctx.beginPath();                                                         \/\/ azulejos del fondo&#10;    for (let x = x0 + 6; x &lt; x0 + w; x += 18) { ctx.moveTo(x, y0); ctx.lineTo(x, y0 + h); } for (let y = y0 + 6; y &lt; y0 + h; y += 18) { ctx.moveTo(x0, y); ctx.lineTo(x0 + w, y); } ctx.stroke();&#10;    ctx.fillStyle = 'rgba(255,255,255,0.14)'; for (let k = 0; k &lt; 8; k++) { const cx = x0 + 20 + ((k * 47 + t * 0.35) % (w - 30)), cy = y0 + 18 + (k * 29) % (h - 36) + Math.sin(t \/ 25 + k) * 4;&#10;        ctx.beginPath(); ctx.ellipse(cx, cy, 10 + (k % 3) * 3, 3, Math.sin(t \/ 40 + k) * 0.5, 0, Math.PI * 2); ctx.fill(); }                    \/\/ ca\u00fasticas: reflejos que ondulan&#10;    const ly = y0 + h \/ 2; ctx.strokeStyle = 'rgba(255,255,255,0.8)'; ctx.lineWidth = 1.2; ctx.beginPath(); ctx.moveTo(x0 + 6, ly); ctx.lineTo(x0 + w - 6, ly); ctx.stroke();   \/\/ corchera&#10;    for (let b = 0; b &lt; 12; b++) { ctx.fillStyle = b % 2 ? '#fff' : '#e53935'; ctx.beginPath(); ctx.arc(x0 + 14 + b * 14, ly + Math.sin(t \/ 18 + b) * 1.2, 3, 0, Math.PI * 2); ctx.fill(); }&#10;    ctx.restore(); ctx.save(); ctx.strokeStyle = '#c9d2d8'; ctx.lineWidth = 2.4; ctx.beginPath();                                              \/\/ escalerilla cromada&#10;    ctx.moveTo(x0 + 2, y0 + h - 34); ctx.lineTo(x0 + 2, y0 + h + 6); ctx.moveTo(x0 + 12, y0 + h - 34); ctx.lineTo(x0 + 12, y0 + h - 4); ctx.stroke();&#10;    ctx.lineWidth = 1.6; [-24, -14, -4].forEach(dy =&gt; { ctx.beginPath(); ctx.moveTo(x0 + 2, y0 + h + dy); ctx.lineTo(x0 + 12, y0 + h + dy); ctx.stroke(); }); ctx.restore();&#10;}&#10;function dibujarPolea(z, t) {&#10;    const x = z.x, y = z.y, act = gimnasioChicas.some(c =&gt; c.zonaActiva === z), sube = act ? (Math.sin(t \/ 14) + 1) * 8 : 0;&#10;    ctx.save(); ctx.lineWidth = 2; ctx.strokeStyle = '#000'; sombra(x, y + 16, 34, 5, 0.2);&#10;    ctx.fillStyle = '#4a5560'; ctx.fillRect(x - 30, y + 8, 60, 8); ctx.strokeRect(x - 30, y + 8, 60, 8);                                    \/\/ base&#10;    ctx.fillStyle = '#7a8793'; [-26, 26].forEach(dx =&gt; { ctx.fillRect(x + dx - 3, y - 92, 6, 102); ctx.strokeRect(x + dx - 3, y - 92, 6, 102); });  \/\/ montantes&#10;    ctx.fillRect(x - 29, y - 96, 58, 8); ctx.strokeRect(x - 29, y - 96, 58, 8);&#10;    for (let i = 0; i &lt; 8; i++) { ctx.fillStyle = i === 3 ? '#ffd54a' : '#2a2f36'; ctx.fillRect(x - 21, y - 80 + i * 8 - sube, 12, 6); }                \/\/ pila de pesas (sube con el uso)&#10;    ctx.fillStyle = '#cfd6dc'; [-16, 16].forEach(dx =&gt; { ctx.beginPath(); ctx.arc(x + dx, y - 92, 4, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); });      \/\/ poleas&#10;    ctx.restore();&#10;}&#10;function dibujarRack(z) {&#10;    const x = z.x, y = z.y; ctx.save(); ctx.lineWidth = 2; ctx.strokeStyle = '#000'; sombra(x, y + 18, 34, 5, 0.2);&#10;    ctx.fillStyle = '#8a5a2b'; ctx.fillRect(x - 32, y + 2, 64, 6); ctx.strokeRect(x - 32, y + 2, 64, 6); ctx.fillRect(x - 32, y - 20, 64, 6); ctx.strokeRect(x - 32, y - 20, 64, 6);&#10;    [-30, 30].forEach(dx =&gt; { ctx.fillRect(x + dx - 2, y - 22, 4, 40); ctx.strokeRect(x + dx - 2, y - 22, 4, 40); });&#10;    [-20, 0, 20].forEach((dx, i) =&gt; { ctx.fillStyle = i === 1 ? '#c0392b' : '#2a2f36'; ctx.beginPath(); ctx.arc(x + dx, y - 6, 8, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.beginPath(); ctx.arc(x + dx, y - 17, 5, Math.PI, 0); ctx.stroke(); });   \/\/ kettlebells&#10;    ctx.restore();&#10;}&#10;function dibujarEsterilla(z, t) {&#10;    const act = gimnasioChicas.some(c =&gt; c.zonaActiva === z), cx = z.x, cy = z.y + 27; ctx.save(); ctx.lineWidth = 2; ctx.strokeStyle = '#000';&#10;    if (act) { const g = ctx.createRadialGradient(cx, cy, 6, cx, cy, 64); g.addColorStop(0, `rgba(255,214,90,${0.28 + 0.1 * Math.sin(t \/ 20)})`); g.addColorStop(1, 'rgba(255,214,90,0)'); ctx.fillStyle = g; ctx.beginPath(); ctx.arc(cx, cy, 64, 0, Math.PI * 2); ctx.fill(); }   \/\/ aura de calma&#10;    ctx.fillStyle = z.accion === 'pilates' ? '#b388ff' : (z.x &lt; 400 ? '#7cdcc8' : '#ff9ccf'); ctx.beginPath(); ctx.roundRect ? ctx.roundRect(cx - 50, cy - 17, 100, 34, 8) : ctx.rect(cx - 50, cy - 17, 100, 34); ctx.fill(); ctx.stroke();&#10;    ctx.strokeStyle = 'rgba(255,255,255,0.55)'; ctx.lineWidth = 1.4; ctx.beginPath(); ctx.moveTo(cx - 40, cy); ctx.lineTo(cx + 40, cy); ctx.stroke(); ctx.restore();&#10;}&#10;function dibujarVending(z, t) {&#10;    const x = z.x, b = z.y + 28, act = gimnasioChicas.some(c =&gt; c.zonaActiva === z), pulso = 0.5 + 0.5 * Math.sin(t \/ 18 + x), c = z.col;&#10;    ctx.save(); ctx.lineWidth = 2; ctx.strokeStyle = '#000'; sombra(x, b + 4, 36, 5, 0.22);&#10;    ctx.fillStyle = '#1f2b3a'; ctx.beginPath(); ctx.roundRect ? ctx.roundRect(x - 28, b - 78, 56, 78, 7) : ctx.rect(x - 28, b - 78, 56, 78); ctx.fill(); ctx.stroke();       \/\/ cuerpo&#10;    ctx.fillStyle = `rgba(${c},${0.18 + 0.12 * pulso + (act ? 0.3 : 0)})`; ctx.fillRect(x - 23, b - 70, 46, 46);                                                                  \/\/ vitrina iluminada&#10;    if (z.k === 'snack') [0, 1, 2].forEach(r =&gt; [0, 1, 2].forEach(q =&gt; { ctx.fillStyle = ['#9be564', '#ffb347', '#ffd54a', '#ff7aa8'][(r + q) % 4]; ctx.fillRect(x - 20 + q * 15, b - 66 + r * 14, 11, 9); }));   \/\/ snacks saludables&#10;    else [0, 1, 2].forEach(q =&gt; { const hq = 18 + (q % 2) * 6, yo = Math.sin(t \/ 14 + q * 2) * 1.5; ctx.fillStyle = `rgba(${c},${0.65 + 0.3 * pulso})`; ctx.fillRect(x - 19 + q * 14, b - 44 - hq + yo, 9, hq); ctx.strokeRect(x - 19 + q * 14, b - 44 - hq + yo, 9, hq); });   \/\/ tubos bio-luminiscentes&#10;    ctx.fillStyle = `rgba(${c},0.95)`; ctx.fillRect(x - 24, b - 76, 48, 3); ctx.fillRect(x - 24, b - 22, 48, 2);                                                                 \/\/ tiras LED&#10;    ctx.fillStyle = '#0b0f14'; ctx.fillRect(x - 14, b - 16, 28, 11); ctx.strokeRect(x - 14, b - 16, 28, 11);                                                                       \/\/ bandeja de recogida&#10;    mTxt('\ud83c\udf3f', x, b - 84, 12, '#000', 'center');&#10;    if (act) { ctx.fillStyle = `rgba(${c},0.4)`; ctx.beginPath(); ctx.arc(x, b - 40, 36, 0, Math.PI * 2); ctx.fill(); }&#10;    ctx.restore();&#10;}&#10;function dibujarBancoGlass(t) {&#10;    const x = 572, y = 496; ctx.save(); ctx.lineWidth = 2; ctx.strokeStyle = '#000'; sombra(632, y + 14, 66, 6, 0.18);&#10;    ctx.fillStyle = 'rgba(150,230,255,0.22)'; ctx.fillRect(x, y - 44, 120, 34); ctx.strokeStyle = 'rgba(190,245,255,0.85)'; ctx.strokeRect(x, y - 44, 120, 34);                       \/\/ respaldo de smart-glass&#10;    ctx.fillStyle = 'rgba(150,230,255,0.4)'; ctx.fillRect(x, y, 120, 10); ctx.strokeRect(x, y, 120, 10);                                                                              \/\/ asiento&#10;    ctx.fillStyle = '#7a8793'; [10, 100].forEach(dx =&gt; ctx.fillRect(x + dx, y + 10, 5, 12));&#10;    const g = 0.45 + 0.3 * Math.sin(t \/ 25); ctx.fillStyle = `rgba(120,240,255,${g})`; ctx.fillRect(x + 2, y + 9, 116, 2);                                                          \/\/ ne\u00f3n bajo el asiento&#10;    ctx.restore();&#10;}&#10;function dibujarGimnasioExtra(t) {                                                                         \/\/ se dibuja antes que las chicas&#10;    dibujarInteriorPiscina(t); dibujarPolea(ZONA_POLEA1, t); dibujarPolea(ZONA_POLEA2, t); dibujarRack(ZONA_RACK);&#10;    ZONAS_ESTERILLA.forEach(z =&gt; dibujarEsterilla(z, t)); dibujarBancoGlass(t); ZONAS_VENDING.forEach(z =&gt; dibujarVending(z, t));&#10;}&#10;function poseGimnasio(c, t) {                                                                              \/\/ postura de cada actividad (tras el translate al personaje)&#10;    if (c.estado === 'pilates') ctx.rotate(-Math.PI \/ 2 + Math.sin(t \/ 30) * 0.04);&#10;    else if (c.estado === 'yoga') ctx.translate(0, Math.sin(t \/ 40) * 1.6);&#10;    else if (c.estado === 'nadando') ctx.rotate((c.nado ? c.nado.dir : 0) * 0.14 + Math.sin(t \/ 8) * 0.04);&#10;    else if (c.estado === 'charlando') ctx.rotate(Math.sin(t \/ 50 + c.x) * 0.05);&#10;    else if (c.estado === 'poleas') ctx.translate(0, Math.abs(Math.sin(t \/ 14)) * 3);&#10;}&#10;function dibujarExtrasGimnasio(c, t) {                                                                     \/\/ solo detalles de escena: agua, cables y chapuz\u00f3n (sin indicadores de cansancio)&#10;    if (c.estado === 'nadando') aguaBano(c.x, c.y, t);&#10;    if (c.estado === 'poleas') {                                                                           \/\/ cables desde las poleas hasta las manos&#10;        const z = c.zonaActiva, p = Math.abs(Math.sin(t \/ 14)) * 12; ctx.save(); ctx.strokeStyle = '#2a2f36'; ctx.lineWidth = 1.6; ctx.beginPath();&#10;        [-16, 16].forEach(dx =&gt; { ctx.moveTo(z.x + dx, z.y - 92); ctx.lineTo(c.x + dx * 1.4, c.y - 8 + p); }); ctx.stroke(); ctx.fillStyle = '#c0392b'; [-16, 16].forEach(dx =&gt; ctx.fillRect(c.x + dx * 1.4 - 3, c.y - 10 + p, 6, 4)); ctx.restore();&#10;    }&#10;    if (c.chapuzon &gt; 0) { const k = 1 - c.chapuzon \/ 40; ctx.save(); ctx.fillStyle = 'rgba(255,255,255,0.85)'; for (let i = 0; i &lt; 8; i++) { ctx.beginPath(); ctx.arc(c.x + Math.cos(i * 0.8) * 24 * k, c.y + 8 - Math.sin(k * Math.PI) * 26 * (0.6 + (i % 3) * 0.2), 2, 0, Math.PI * 2); ctx.fill(); } ctx.restore(); }&#10;}&#10;const GimnasioVida = (() =&gt; {&#10;    const ESFUERZO = { pedaleando: 0.0005, levantando: 0.0007, poleas: 0.0008, nadando: 0.00022 }, RECUPERA = { yoga: 0.0012, pilates: 0.001, charlando: 0.0007 };&#10;    const VIA = { x: 700, y: 408 };                                                                        \/\/ borde de la piscina, junto a la escalerilla&#10;    const DUR = { pedaleando: [1500, 2700], levantando: [1500, 2700], poleas: [1500, 2400], nadando: [2400, 3600], yoga: [1500, 2400], pilates: [1500, 2400], charlando: [1500, 2400], tomando: [300, 300] };&#10;    const ocupada = (z, c) =&gt; gimnasioChicas.some(o =&gt; o !== c &amp;&amp; (o.zonaActiva === z || (o.meta &amp;&amp; o.meta.zona === z)));&#10;    const destino = z =&gt; ({ x: z.x, y: z.y + (z.accion === 'nadando' ? 0 : 25) });&#10;    function elegirZona(c) {&#10;        const cansada = (c.fatiga || 0) &gt;= 0.55, nadando = gimnasioChicas.filter(o =&gt; o.estado === 'nadando' || (o.meta &amp;&amp; o.meta.zona &amp;&amp; o.meta.zona.accion === 'nadando')).length;&#10;        const peso = z =&gt; (z.unica || z.accion === 'pedaleando') &amp;&amp; ocupada(z, c) ? 0 : z.accion === 'nadando' &amp;&amp; nadando &gt;= 2 ? 0 :&#10;            cansada ? (z.relax ? 4 : z.accion === 'tomando' ? 2 : 0) : (z.relax ? (z.accion === 'charlando' ? 0.6 : 0.3) : z.accion === 'tomando' ? 0.6 : z.accion === 'nadando' ? 2 : 1.5);&#10;        const lista = ZONAS_GIMNASIO.map(z =&gt; [z, peso(z)]).filter(p =&gt; p[1] &gt; 0); if (!lista.length) return null;&#10;        let r = Math.random() * lista.reduce((a, p) =&gt; a + p[1], 0); for (const [z, w] of lista) { if ((r -= w) &lt;= 0) return z; } return lista[lista.length - 1][0];&#10;    }&#10;    function empezar(c, z) {                                                                               \/\/ llega y comienza la actividad (si nadie le ha quitado el sitio)&#10;        c.meta = null; if ((z.unica || z.accion === 'pedaleando') &amp;&amp; ocupada(z, c)) { c.espera = 30; return; }&#10;        const d = destino(z), [a, b] = DUR[z.accion] || [1200, 1800];&#10;        c.x = d.x; c.y = d.y; c.estado = z.accion; c.zonaActiva = z; c.ultimaZona = z; c.temporizador = a + Math.random() * (b - a); c.tomandoT = 0; c.limite = 0.6 + Math.random() * 0.3;   \/\/ cada una tiene su propio aguante&#10;        if (z.accion === 'nadando') c.chapuzon = 40;&#10;    }&#10;    function nadar(c) {                                                                                    \/\/ brazadas de lado a lado por su carril&#10;        if (!c.nado) { const usados = gimnasioChicas.filter(o =&gt; o !== c &amp;&amp; o.nado).map(o =&gt; o.nado.carril), pref = Math.abs(c.y - NADO.carriles[0]) &lt; Math.abs(c.y - NADO.carriles[1]) ? 0 : 1; c.nado = { dir: Math.random() &lt; 0.5 ? 1 : -1, carril: usados.includes(pref) ? 1 - pref : pref }; }&#10;        const n = c.nado; c.x += n.dir * 0.55; if (c.x &gt; NADO.x1) { c.x = NADO.x1; n.dir = -1; } if (c.x &lt; NADO.x0) { c.x = NADO.x0; n.dir = 1; }&#10;        c.y += (NADO.carriles[n.carril] - c.y) * 0.08;&#10;    }&#10;    function terminar(c) { c.estado = 'de_pie'; c.zonaActiva = null; c.temporizador = 0; }&#10;    function alSalir(c) {                                                                                  \/\/ al acabar una actividad&#10;        if (c.ultimaZona.accion === 'nadando') { c.x = 706; c.y = 412; c.nado = null; }                   \/\/ sale por la escalerilla&#10;        c.ultimaZona = null; c.espera = c.fatiga &gt;= 0.55 ? 30 + Math.random() * 60 : 90 + Math.random() * 150;   \/\/ cansada: se va enseguida a descansar&#10;    }&#10;    function decidir(c) {&#10;        const z = (c.fatiga &gt;= 0.55 || Math.random() &lt; 0.8) ? elegirZona(c) : null;      \/\/ cansada: siempre a descansar o a beber&#10;        if (z) { const d = destino(z); c.meta = { x: d.x, y: d.y, zona: z, via: z.accion === 'nadando' ? VIA : null, viaOk: false }; }&#10;        else c.meta = { x: 60 + Math.random() * 880, y: 420 + Math.random() * 90, zona: null };&#10;    }&#10;    function caminar(c) {                                                                                  \/\/ devuelve true al llegar&#10;        const m = c.meta, v = (m.via &amp;&amp; !m.viaOk) ? m.via : m, dx = v.x - c.x, dy = v.y - c.y, d = Math.hypot(dx, dy);&#10;        if (d &gt; 2) { c.x += dx \/ d * 1.25; c.y += dy \/ d * 1.25; return false; } if (m.via &amp;&amp; !m.viaOk) { m.viaOk = true; return false; } return true;&#10;    }&#10;    function actualizar() {&#10;        gimnasioChicas.forEach(c =&gt; {&#10;            if (c === chicaGimnasioArrastrada) { c.meta = null; c.nado = null; return; }                    \/\/ si la arrastras, se cancela lo que hac\u00eda&#10;            if (c.fatiga === undefined) { c.fatiga = 0; c.espera = 90 + Math.random() * 200; c.chapuzon = 0; c.tomandoT = 0; c.meta = null; c.ultimaZona = null; }&#10;            const e = ESFUERZO[c.estado], r = RECUPERA[c.estado];&#10;            if (e) c.fatiga = Math.min(1, c.fatiga + e); else if (r) c.fatiga = Math.max(0, c.fatiga - r); else if (c.estado === 'de_pie' &amp;&amp; !c.meta) c.fatiga = Math.max(0, c.fatiga - 0.00008);&#10;            if (c.chapuzon &gt; 0) c.chapuzon--;&#10;            if (c.estado === 'nadando') nadar(c);&#10;            if (c.estado === 'tomando' &amp;&amp; ++c.tomandoT &gt; 270) { const k = c.zonaActiva.k; c.fatiga = Math.max(0, c.fatiga - (k === 'snack' ? 0.15 : 0.25)); c.tomandoT = 0; terminar(c); }   \/\/ se recupera con lo que toma&#10;            if (['pedaleando', 'levantando', 'poleas'].includes(c.estado) &amp;&amp; c.fatiga &gt;= (c.limite || 0.85)) terminar(c);                                                                                               \/\/ agotada: deja el esfuerzo&#10;            if (c.estado === 'nadando' &amp;&amp; c.fatiga &gt;= (c.limite || 0.85) + 0.1) terminar(c);&#10;            if (c.estado !== 'de_pie') return;&#10;            if (c.ultimaZona) alSalir(c);&#10;            if (c.meta) { if (caminar(c)) { const z = c.meta.zona; if (z) empezar(c, z); else { c.meta = null; c.espera = 90 + Math.random() * 150; } } }&#10;            else if (--c.espera &lt;= 0) decidir(c);                                                          \/\/ cansada \u2192 esterillas, banco o vending; descansada \u2192 m\u00e1quinas, piscina\u2026&#10;        });&#10;    }&#10;    return { actualizar };&#10;})();&#10;var vidaLista = false;&#10;const VidaDiaria = (() =&gt; {&#10;    const OBST = [{ x: FUENTE_POS.x, y: FUENTE_POS.y - 4, rx: 52, ry: 20 }, { x: KUTXA_POS.x, y: KUTXA_POS.y - 18, rx: 40, ry: 22 }];   \/\/ fuente y cofre de la Kutxa (elipses): se rodean, pero la calle del parque, por delante, sigue libre&#10;    const bloqueado = (x, y) =&gt; OBST.some(o =&gt; ((x - o.x) \/ o.rx) ** 2 + ((y - o.y) \/ o.ry) ** 2 &lt; 1);&#10;    function puntoPaseo() {&#10;        for (let i = 0; i &lt; 12; i++) {&#10;            const r = Math.random(); let x, y;&#10;            if (r &lt; 0.4) { x = 40 + Math.random() * 895; y = yDeCalle(x) + (Math.random() - 0.5) * 24; }                  \/\/ la calle de siempre&#10;            else if (r &lt; 0.75) { x = 40 + Math.random() * 895; y = SUELO_Y + 130 + Math.random() * 110; }                 \/\/ plaza, parque y fuente&#10;            else { x = 60 + Math.random() * 850; y = SUELO_Y + 245 + Math.random() * 120; }                               \/\/ sur: mercadillo, puesto y refugio&#10;            if (!bloqueado(x, y)) return { x, y };&#10;        } return { x: 120, y: yDeCalle(120) };&#10;    }&#10;    const reservado = (h, clave) =&gt; habitantes.some(o =&gt; o !== h &amp;&amp; o.plan &amp;&amp; o.plan.clave === clave);&#10;    const sentada = (h, x, y, est) =&gt; habitantes.some(o =&gt; o !== h &amp;&amp; o.estado === est &amp;&amp; Math.abs(o.x - x) &lt; 8 &amp;&amp; Math.abs(o.y - y) &lt; 8);&#10;    const posMercadillo = () =&gt; { const py = MERCADILLO.baseY + MERCADILLO.alto, f = escalaProf(py); return { x: MERCADILLO.baseX + MERCADILLO.ancho \/ 2, y: py + (MERCADILLO.baseY + 18 - py) * f }; };&#10;    function elegirPlan(h) {&#10;        if (h.comida) { const pc = Comidas.plan(h); if (pc) return pc; }                                                \/\/ si le toca comer, eso va primero&#10;        const T = [];                                                                                                   \/\/ [tipo, peso, destinos posibles]&#10;        const bs = []; bancos.forEach((b, i) =&gt; [b.x + 11, b.x + 35].forEach((x, k) =&gt; { const clave = 'b' + i + k; if (!sentada(h, x, b.y - 6, 'sentada') &amp;&amp; !reservado(h, clave)) bs.push({ x, y: b.y - 6, clave }); }));&#10;        if (bs.length) T.push(['banco', 1, bs]);&#10;        const ts = ZONAS_TERRAZA_ASIENTOS.map((s, i) =&gt; ({ x: s.x, y: s.y, clave: 't' + i })).filter(s =&gt; !sentada(h, s.x, s.y, 'sentada') &amp;&amp; !reservado(h, s.clave));&#10;        if (ts.length) T.push(['terraza', 1, ts]);&#10;        const ls = BIBLIOTECA_ASIENTOS.map((s, i) =&gt; ({ x: s.x, y: s.y, clave: 'l' + i })).filter(s =&gt; !sentada(h, s.x, s.y, 'leyendo') &amp;&amp; !reservado(h, s.clave));&#10;        if (ls.length) T.push(['biblioteca', 0.5, ls]);&#10;        if (habitantes.indexOf(h) === 2 &amp;&amp; !habitantes.some(o =&gt; o.oculta &amp;&amp; o.lugar === 'huerta')) T.push(['huerta', 1.2, [{ x: ZONA_ENTRADA_HUERTA.x, y: ZONA_ENTRADA_HUERTA.y + 10 }]]);   \/\/ la Bot\u00e1nica visita la huerta&#10;        const hr = Biblioteca.horario();                                                                              \/\/ rutina suave por reloj real&#10;        if (hr.bib &gt; 0 &amp;&amp; Biblioteca.dentro().length + habitantes.filter(o =&gt; o !== h &amp;&amp; o.plan &amp;&amp; o.plan.acc === 'estudio').length &lt; Biblioteca.capacidad) T.push(['estudio', hr.bib, [Biblioteca.puertaBib()]]);&#10;        if (hr.tele &amp;&amp; Biblioteca.teletrab().length + habitantes.filter(o =&gt; o !== h &amp;&amp; o.plan &amp;&amp; o.plan.acc === 'teletrabajo').length &lt; 3) { const c = Biblioteca.casaDe(h); T.push(['teletrabajo', 3.5, [{ x: c.x + c.ancho \/ 2, y: SUELO_Y + 62 }]]); }&#10;        if (GimnasioPueblo.dentro().length + habitantes.filter(o =&gt; o !== h &amp;&amp; o.plan &amp;&amp; o.plan.acc === 'gimnasio').length &lt; GimnasioPueblo.capacidad) T.push(['gimnasio', hr.tele ? 0.2 : 1.1, [GimnasioPueblo.puerta()]]);&#10;        if (!h.patinete) { const ps = patinetes.filter(p =&gt; !p.montadaPor &amp;&amp; !reservado(h, p)).map(p =&gt; ({ x: p.x, y: p.y, clave: p, p })); if (ps.length) T.push(['patinete', 0.8, ps]); }&#10;        if (habitantesEnPlaya.length &lt; 4) T.push(['tranvia', 0.45, [0, 0, 1, 2].map(i =&gt; ({ x: PARADAS[i].x, y: Tranvia.PLAT, parada: i }))]);&#10;        if (!mascotas.some(m =&gt; m.siguiendoA === h) &amp;&amp; mascotas.some(m =&gt; m.estado === 'en_refugio')) T.push(['mascota', 0.6, [{ x: REFUGIO.x, y: REFUGIO.y - 14 }]]);&#10;        T.push(['mercadillo', esperandoMercadillo &amp;&amp; esperandoMercadillo !== h ? 2 : 0.8, [posMercadillo()]]);&#10;        T.push(['frutas', esperandoFrutas &amp;&amp; esperandoFrutas !== h ? 2 : 0.8, [{ x: ZONA_PUESTOFRUTA.x, y: ZONA_PUESTOFRUTA.y + 14 }]]);&#10;        const FF = fiestaActual(); if (FF) {                                                                                                          \/\/ planes propios de las fiestas vascas&#10;            if (FF.id === 'm8' || FF.id === 'n25') { T.push(['pancarta', 1.8, Conmemoraciones.puntosPancarta(h)]); if (Conmemoraciones.silencio()) T.push(['silencio', 100, [Conmemoraciones.puestoSilencio(h)]]); }&#10;            if (FF.id === 'astenagusia') { T.push(['gargantua', 3, [Fiestas2.entrada()]]); if (Fiestas2.enTarima()) T.push(['marijaia', 1.5, [{ x: Fiestas2.TARIMA.x + (Math.random() - 0.5) * 110, y: Fiestas2.TARIMA.y + 16 + Math.random() * 14 }]]); }&#10;            if (FF.sub === 'santotomas') T.push(['talo', 2.5, [Fiestas2.puestoTalo()]]);&#10;            if (FF.sub === 'olentzero') { const po = Fiestas2.posOlentzero(); T.push(['olentzero', po.x &gt; 20 &amp;&amp; po.x &lt; 940 ? 2.5 : 0, [{ x: po.x - 40, y: po.y + 8 }]]); }&#10;        }&#10;        T.push(['paseo', h.patinete ? 3.5 : 2.2, null]);&#10;        const w = T.map(([k, p]) =&gt; p * (h.ultimaAcc === k ? 0.3 : 1) * Personas.peso(h, k)); let r = Math.random() * w.reduce((a, b) =&gt; a + b, 0), i = 0; while (i &lt; T.length - 1 &amp;&amp; (r -= w[i]) &gt; 0) i++;&#10;        const [acc, , dest] = T[i], d = dest ? dest[Math.floor(Math.random() * dest.length)] : puntoPaseo();&#10;        return { acc, x: d.x, y: d.y, clave: d.clave, p: d.p, parada: d.parada };&#10;    }&#10;    function nuevoDestino(h) {                                                                                         \/\/ sustituye al antiguo &quot;sitio al azar de la calle&quot;&#10;        const p = elegirPlan(h); h.plan = p; h.ultimaAcc = p.acc; h.objetivoX = p.x; h.objetivoY = p.y; h.direccion = p.x &gt; h.x ? 1 : -1; h.atasco = 0;&#10;        if (p.acc === 'patinete') p.p.reservaPor = h;&#10;    }&#10;    function bajarPatinete(h) { if (h.patinete) { h.patinete.montadaPor = null; h.patinete = null; } h.bajaEn = undefined; }&#10;    function sentarse(h, p, est) { bajarPatinete(h); h.x = p.x; h.y = p.y; h.estado = est; h.temporizador = 2700; return true; }&#10;    function llegada(h) {                                                                                               \/\/ se llama al llegar a su destino; true si empieza una actividad&#10;        const p = h.plan; h.plan = null; if (!p) return false;&#10;        switch (p.acc) {&#10;            case 'banco': return sentada(h, p.x, p.y, 'sentada') ? false : sentarse(h, p, 'sentada');&#10;            case 'terraza': return sentada(h, p.x, p.y, 'sentada') ? false : sentarse(h, p, 'sentada');&#10;            case 'biblioteca': return sentada(h, p.x, p.y, 'leyendo') ? false : sentarse(h, p, 'leyendo');&#10;            case 'patinete': if (!p.p.montadaPor &amp;&amp; !h.patinete) { p.p.montadaPor = h; h.patinete = p.p; h.bajaEn = 700 + Math.random() * 700; } nuevoObjetivo(h); return true;         \/\/ monta y sigue su camino&#10;            case 'tranvia': bajarPatinete(h); return Tranvia.esperar(h, p.parada);                                       \/\/ espera en la parada hasta que llegue el tren                                                   \/\/ se va a la playa (a surfear, ba\u00f1arse\u2026)&#10;            case 'huerta': bajarPatinete(h); return HuertaBot.entrar(h);&#10;            case 'gimnasio': bajarPatinete(h); return GimnasioPueblo.entrar(h);                                        \/\/ entra a entrenar&#10;            case 'pancarta': bajarPatinete(h); h.estado = 'parada'; h.temporizador = 360; return true;                                                    \/\/ se une a la pancarta&#10;            case 'silencio': bajarPatinete(h); h.estado = 'parada'; h.temporizador = Conmemoraciones.restoSilencio(); return true;                       \/\/ minuto de silencio en la plaza&#10;            case 'marijaia': bajarPatinete(h); h.estado = 'parada'; h.temporizador = 360; h.direccion = p.x &lt; Fiestas2.TARIMA.x ? 1 : -1; return true;                                  \/\/ baila delante de Marijaia&#10;            case 'gargantua': bajarPatinete(h); Fiestas2.entrarGargantua(h); return true;                                                                 \/\/ se mete por la boca de Gargant\u00faa y baja por el tobog\u00e1n&#10;            case 'talo': bajarPatinete(h); Fiestas2.comprarTalo(h); h.estado = 'parada'; h.temporizador = 340; return true;                             \/\/ compra y se come un talo con txistorra&#10;            case 'olentzero': h.estado = 'parada'; h.temporizador = 380; h.direccion = p.x &lt; h.x ? -1 : 1; return true;                                    \/\/ escucha a Olentzero&#10;            case 'compra': bajarPatinete(h); Comidas.compra(h); h.estado = 'parada'; h.temporizador = 180; return true;                                  \/\/ hace la compra&#10;            case 'cocinar': bajarPatinete(h); Comidas.cocina(h); return true;                                                                              \/\/ entra a cocinar a su casa&#10;            case 'comer': if (sentada(h, p.x, p.y, 'sentada')) { Comidas.terminar(h, 0.6); return false; } sentarse(h, p, 'sentada'); h.temporizador = 460 + Math.random() * 160; Comidas.empieza(h); return true;   \/\/ come en la terraza&#10;            case 'estudio': bajarPatinete(h); return Biblioteca.entrar(h);                                              \/\/ entra a la biblioteca digital&#10;            case 'teletrabajo': bajarPatinete(h); Biblioteca.teletrabajar(h); return true;                           \/\/ teletrabaja en casa&#10;            case 'mascota': h.estado = 'parada'; h.temporizador = 150 + Math.random() * 100; return true;                                                                               \/\/ se queda un rato: el refugio hace el resto&#10;            case 'mercadillo': case 'frutas': {&#10;                bajarPatinete(h); const m = p.acc === 'mercadillo', cx = m ? posMercadillo().x : ZONA_PUESTOFRUTA.x, fy = m ? posMercadillo().y : ZONA_PUESTOFRUTA.y + 14, otra = m ? esperandoMercadillo : esperandoFrutas;&#10;                if (otra &amp;&amp; otra !== h) { h.x = cx + 13; h.y = fy; otra.x = cx - 13; otra.y = fy; h.estado = otra.estado = p.acc; otra.esperaDesde = 0; if (m) { h.inicioMercadillo = otra.inicioMercadillo = Date.now(); esperandoMercadillo = null; } else { h.inicioFrutas = otra.inicioFrutas = Date.now(); esperandoFrutas = null; } }&#10;                else { h.x = cx; h.y = fy; h.estado = p.acc + '_esperando'; h.esperaDesde = Date.now(); if (m) esperandoMercadillo = h; else esperandoFrutas = h; }&#10;                return true;&#10;            }&#10;        } return false;&#10;    }&#10;    function actualizar() {&#10;        const ahora = Date.now();&#10;        habitantes.forEach(h =&gt; {&#10;            if (h.arrastrando || h.estado === 'asamblea') { h.plan = null; h.objetivoY = null; return; }                 \/\/ la jugadora manda&#10;            if (h.patinete &amp;&amp; h.bajaEn === undefined) h.bajaEn = 900 + Math.random() * 900;&#10;            if (h.patinete &amp;&amp; h.estado === 'caminando' &amp;&amp; --h.bajaEn &lt;= 0) bajarPatinete(h);                              \/\/ deja el patinete donde est\u00e1&#10;            if ((h.estado === 'mercadillo_esperando' || h.estado === 'frutas_esperando') &amp;&amp; h.esperaDesde &amp;&amp; ahora - h.esperaDesde &gt; 20000) {   \/\/ nadie lleg\u00f3: se cansa de esperar&#10;                if (esperandoMercadillo === h) esperandoMercadillo = null; if (esperandoFrutas === h) esperandoFrutas = null; h.esperaDesde = 0; nuevoObjetivo(h); h.estado = 'caminando';&#10;            }&#10;            if (h.estado === 'esperando_tranvia' &amp;&amp; h.esperaDesde &amp;&amp; ahora - h.esperaDesde &gt; 50000) { h.esperaDesde = 0; h.estado = 'caminando'; nuevoObjetivo(h); }   \/\/ se cansa de esperar&#10;            if (h.enPlaya &amp;&amp; h.finPlayaVida &amp;&amp; ahora &gt; h.finPlayaVida &amp;&amp; !enPlaya) { h.finPlayaVida = 0; volverDeLaPlaya(h); }   \/\/ vuelve en el tranv\u00eda&#10;        });&#10;    }&#10;    function mover(h, v) {                                                                                              \/\/ 2D hacia su destino, rodeando la fuente y el cofre&#10;        const dx = h.objetivoX - h.x, dy = h.objetivoY - h.y, d = Math.hypot(dx, dy); if (d &lt;= 3) return true;&#10;        const ux = dx \/ d * v, uy = dy \/ d * v, dentro = bloqueado(h.x, h.y); let moved = false;                   \/\/ si ya est\u00e1 dentro de un obst\u00e1culo, puede salir&#10;        for (const a of [0, 0.9, -0.9, 1.6, -1.6]) { const c = Math.cos(a), s = Math.sin(a), nx = h.x + ux * c - uy * s, ny = h.y + ux * s + uy * c; if (dentro || !bloqueado(nx, ny)) { h.x = nx; h.y = ny; moved = true; break; } }&#10;        if (Math.abs(dx) &gt; 2) h.direccion = dx &gt;= 0 ? 1 : -1; if (!moved &amp;&amp; ++h.atasco &gt; 240) { h.plan = null; h.objetivoY = null; nuevoObjetivo(h); } return false;&#10;    }&#10;    function irA(h, acc) { const d = acc === 'gimnasio' ? GimnasioPueblo.puerta() : Biblioteca.puertaBib(); h.plan = { acc, x: d.x, y: d.y }; h.ultimaAcc = acc; h.objetivoX = d.x; h.objetivoY = d.y; h.direccion = d.x &gt; h.x ? 1 : -1; h.atasco = 0; }   \/\/ destino directo al bajar del tranv\u00eda&#10;    return { nuevoDestino, llegada, actualizar, mover, irA };&#10;})();&#10;let enBiblioteca = false;&#10;const Biblioteca = (() =&gt; {&#10;    const W = 960, H = 540, NEON_A = '47,140,255', NEON_B = '255,47,209';&#10;    const PUESTOS = [{ x: 150, y: 352 }, { x: 330, y: 352 }, { x: 630, y: 352 }, { x: 810, y: 352 }, { x: 240, y: 452 }, { x: 480, y: 452 }, { x: 720, y: 452 }];&#10;    const TOTEMS = [270, 480, 690], COLUMNAS = [40, 920];&#10;    const PANELES = [{ x: 90, y: 92, w: 150, h: 100 }, { x: 300, y: 92, w: 150, h: 100 }, { x: 510, y: 92, w: 150, h: 100 }, { x: 720, y: 92, w: 150, h: 100 }];&#10;    const TIPOS = ['mapa', 'bienestar', 'recursos', 'kutxa', 'apicultura', 'desgaste'], contenido = [0, 1, 3, 2];&#10;    let fondo = null, frente = null, tiras = null, hist = [], ultHist = 0;&#10;    const lienzo = () =&gt; { const c = document.createElement('canvas'); c.width = W; c.height = H; return c; };&#10;    const neon = (g, trazo, rgb, a) =&gt; { [[a * 6, 0.08], [a * 3, 0.18], [a, 0.95]].forEach(([k, al]) =&gt; { g.lineWidth = k; g.strokeStyle = `rgba(${rgb},${al})`; trazo(); g.stroke(); }); };&#10;    const linea = (g, x1, y1, x2, y2) =&gt; () =&gt; { g.beginPath(); g.moveTo(x1, y1); g.lineTo(x2, y2); };&#10;    function crearTira(rgb) {                                                                                      \/\/ tira de glifos pre-renderizada (se desplaza: cero coste de texto por fotograma)&#10;        const c = document.createElement('canvas'); c.width = 36; c.height = 512; const g = c.getContext('2d'), L = '01ABCDEF&lt;&gt;\/{}[]#$%&amp;=+*'; g.font = '11px monospace';&#10;        for (let y = 10; y &lt; 512; y += 13) for (let x = 2; x &lt; 36; x += 11) { if (Math.random() &lt; 0.2) continue; g.fillStyle = `rgba(${rgb},${0.25 + Math.random() * 0.75})`; g.fillText(L[Math.floor(Math.random() * L.length)], x, y); }&#10;        return c;&#10;    }&#10;    function construir() {                                                                                         \/\/ capas est\u00e1ticas: se dibujan una sola vez&#10;        tiras = [crearTira('90,200,255'), crearTira('255,120,230')];&#10;        fondo = lienzo(); let g = fondo.getContext('2d'), gr = g.createLinearGradient(0, 0, 0, H);&#10;        gr.addColorStop(0, '#05071a'); gr.addColorStop(0.55, '#0b0e2c'); gr.addColorStop(1, '#13124a'); g.fillStyle = gr; g.fillRect(0, 0, W, H);&#10;        g.strokeStyle = 'rgba(80,120,255,0.07)'; g.lineWidth = 1; g.beginPath(); for (let x = 30; x &lt; W; x += 60) { g.moveTo(x, 60); g.lineTo(x, 300); } g.stroke();&#10;        const cl = g.createLinearGradient(0, 0, 0, 330); cl.addColorStop(0, 'rgba(255,220,160,0.24)'); cl.addColorStop(1, 'rgba(255,220,160,0)');       \/\/ claraboya: luz natural y c\u00e1lida&#10;        g.fillStyle = cl; g.beginPath(); g.moveTo(400, 0); g.lineTo(560, 0); g.lineTo(650, 330); g.lineTo(310, 330); g.closePath(); g.fill();&#10;        g.fillStyle = '#04061a'; g.fillRect(0, 0, W, 58); g.fillStyle = 'rgba(255,236,200,0.92)'; g.fillRect(400, 5, 160, 9);&#10;        neon(g, linea(g, 0, 22, W, 22), NEON_A, 2); neon(g, linea(g, 0, 52, W, 52), NEON_B, 2);&#10;        const fl = g.createLinearGradient(0, 300, 0, H); fl.addColorStop(0, '#0a0c2a'); fl.addColorStop(1, '#17164f'); g.fillStyle = fl; g.fillRect(0, 300, W, H - 300);&#10;        g.strokeStyle = 'rgba(70,140,255,0.2)'; g.lineWidth = 1; g.beginPath();                                    \/\/ suelo reflectante con rejilla en perspectiva&#10;        for (let k = -8; k &lt;= 8; k++) { g.moveTo(480 + k * 40, 300); g.lineTo(480 + k * 120, H); } for (let j = 1; j &lt;= 8; j++) { const y = 300 + 240 * Math.pow(j \/ 8, 1.7); g.moveTo(0, y); g.lineTo(W, y); } g.stroke();&#10;        neon(g, linea(g, 0, 300, W, 300), NEON_B, 2);&#10;        COLUMNAS.forEach(x =&gt; { const c = g.createLinearGradient(x - 11, 0, x + 11, 0); c.addColorStop(0, '#0d1236'); c.addColorStop(0.5, '#1c2766'); c.addColorStop(1, '#0d1236'); g.fillStyle = c; g.fillRect(x - 11, 58, 22, 262); neon(g, linea(g, x - 11, 58, x - 11, 320), NEON_A, 1.4); neon(g, linea(g, x + 11, 58, x + 11, 320), NEON_B, 1.4); });&#10;        TOTEMS.forEach(x =&gt; {                                                                                      \/\/ t\u00f3tems: cilindro transl\u00facido, haz hasta el techo y anillos de ne\u00f3n&#10;            const hz = g.createLinearGradient(0, 0, 0, 118); hz.addColorStop(0, 'rgba(120,180,255,0)'); hz.addColorStop(1, 'rgba(120,180,255,0.32)'); g.fillStyle = hz; g.fillRect(x - 14, 0, 28, 118);&#10;            g.fillStyle = 'rgba(25,45,140,0.42)'; g.fillRect(x - 19, 118, 38, 200); neon(g, linea(g, x - 19, 118, x - 19, 318), NEON_A, 1.2); neon(g, linea(g, x + 19, 118, x + 19, 318), NEON_B, 1.2);&#10;            [118, 318].forEach(y =&gt; neon(g, () =&gt; { g.beginPath(); g.ellipse(x, y, 22, 6, 0, 0, Math.PI * 2); }, y === 118 ? NEON_A : NEON_B, 1.4));&#10;        });&#10;        [60, 900].forEach(x =&gt; {                                                                                   \/\/ plantas bio-luminiscentes: el toque acogedor&#10;            g.fillStyle = 'rgba(56,240,192,0.16)'; g.beginPath(); g.ellipse(x, 505, 46, 12, 0, 0, Math.PI * 2); g.fill(); g.fillStyle = '#1a1f4f'; g.fillRect(x - 14, 490, 28, 22);&#10;            for (let k = -3; k &lt;= 3; k++) { g.strokeStyle = k % 2 ? 'rgba(56,240,192,0.9)' : 'rgba(255,120,230,0.85)'; g.lineWidth = 2.4; g.beginPath(); g.moveTo(x, 492); g.quadraticCurveTo(x + k * 12, 462, x + k * 20, 448 + Math.abs(k) * 6); g.stroke(); }&#10;        });&#10;        frente = lienzo(); g = frente.getContext('2d');&#10;        PUESTOS.forEach(s =&gt; {                                                                                     \/\/ mesas de dise\u00f1o: madera clara arriba, base oscura con ne\u00f3n&#10;            g.fillStyle = '#e0c48f'; g.fillRect(s.x - 52, s.y, 104, 6); g.fillStyle = '#171a44'; g.fillRect(s.x - 50, s.y + 6, 100, 22); neon(g, linea(g, s.x - 50, s.y + 28, s.x + 50, s.y + 28), NEON_A, 1.2);&#10;            g.fillStyle = '#1b2a6a'; g.fillRect(s.x - 22, s.y - 7, 44, 7); g.fillStyle = 'rgba(120,220,255,0.9)'; g.fillRect(s.x - 22, s.y - 8, 44, 1.5);        \/\/ terminal t\u00e1ctil&#10;        });&#10;        neon(g, () =&gt; { g.beginPath(); g.arc(480, 540, 46, Math.PI, 0); }, NEON_A, 2); neon(g, () =&gt; { g.beginPath(); g.arc(480, 540, 34, Math.PI, 0); }, NEON_B, 1.4);     \/\/ puerta&#10;    }&#10;    function lluvia(x, y, h, vel, t, k) {                                                                           \/\/ columna de c\u00f3digo en cascada&#10;        const off = Math.floor((t * vel) % 512), s1 = Math.min(h, 512 - off);&#10;        ctx.drawImage(tiras[k], 0, off, 36, s1, x - 18, y, 36, s1); if (s1 &lt; h) ctx.drawImage(tiras[k], 0, 0, 36, h - s1, x - 18, y + s1, 36, h - s1);&#10;    }&#10;    const barra = (x, y, w, f, col) =&gt; { ctx.fillStyle = 'rgba(255,255,255,0.12)'; ctx.fillRect(x, y, w, 6); ctx.fillStyle = col; ctx.fillRect(x, y, Math.max(2, w * Math.max(0, Math.min(1, f))), 6); };&#10;    function datos(tipo, x, y, w, h, t) {&#10;        const T = (s, tx, ty, z = 8, al = 'left') =&gt; mTxt(s, tx, ty, z, 'rgba(190,225,255,0.95)', al, true);&#10;        if (tipo === 'mapa') {&#10;            T('MAPA DEL PUEBLO', x + 6, y + 9, 8); const mx = x + 6, my = y + 16, mw = w - 12, mh = h - 22, px = v =&gt; mx + v \/ 960 * mw, py = v =&gt; my + (v - 60) \/ 480 * mh;&#10;            ctx.fillStyle = 'rgba(70,150,255,0.18)'; ctx.fillRect(mx, my, mw, mh); ctx.fillStyle = 'rgba(160,200,255,0.5)'; casas.forEach(c =&gt; ctx.fillRect(px(c.x), py(SUELO_Y + 55 - c.alto), c.ancho \/ 960 * mw, c.alto \/ 480 * mh));&#10;            ctx.fillStyle = 'rgba(255,47,209,0.7)'; ctx.beginPath(); ctx.arc(px(FUENTE_POS.x), py(FUENTE_POS.y), 3, 0, 7); ctx.fill(); ctx.fillStyle = 'rgba(255,214,90,0.9)'; ctx.fillRect(px(KUTXA_POS.x) - 1.5, py(KUTXA_POS.y) - 1.5, 3, 3);&#10;            ctx.fillStyle = '#7cffd9'; habitantes.forEach(v =&gt; { if (!v.oculta &amp;&amp; !v.enPlaya &amp;&amp; !v.durmiendo) { ctx.beginPath(); ctx.arc(px(v.x), py(v.y), 1.8, 0, 7); ctx.fill(); } });&#10;        } else if (tipo === 'bienestar') { T('BIENESTAR', x + 6, y + 9, 8); [['\ud83c\udf7d\ufe0f', bienestar.alim], ['\ud83d\udca7', bienestar.agua], ['\ud83c\udfe0', bienestar.viv], ['\ud83d\ude83', bienestar.mov]].forEach(([e, v], i) =&gt; { mTxt(e, x + 12, y + 28 + i * 17, 9, '#fff', 'center'); barra(x + 24, y + 25 + i * 17, w - 32, v \/ 100, `rgba(${i % 2 ? NEON_B : NEON_A},0.95)`); }); }&#10;        else if (tipo === 'recursos') { T('RECURSOS', x + 6, y + 9, 8); [['\ud83e\uddf1', recursos.arcilla, '#c1763f'], ['\ud83c\udf3f', recursos.resina, '#7cb342'], ['\ud83e\uded8', recursos.proteina, '#e6b422'], ['\u2600\ufe0f', recursos.energia, '#38bdf8']].forEach(([e, v, c], i) =&gt; { mTxt(e, x + 12, y + 28 + i * 17, 9, '#fff', 'center'); barra(x + 24, y + 25 + i * 17, w - 32, v \/ 100, c); }); }&#10;        else if (tipo === 'kutxa') {&#10;            T('KUTXA AuZ', x + 6, y + 9, 8); mTxt('\ud83e\ude99 ' + Kutxa.visible(), x + w \/ 2, y + 30, 14, '#ffd54a', 'center', true);&#10;            ctx.strokeStyle = `rgba(${NEON_B},0.95)`; ctx.lineWidth = 1.4; ctx.beginPath(); const mxv = Math.max(1, ...hist);&#10;            hist.forEach((v, i) =&gt; { const px = x + 8 + i \/ 59 * (w - 16), py = y + h - 8 - v \/ mxv * (h - 52); i ? ctx.lineTo(px, py) : ctx.moveTo(px, py); }); ctx.stroke();&#10;        } else if (tipo === 'apicultura') { T('APICULTURA', x + 6, y + 9, 8); const a = Apicultura.e; [['\ud83c\udf6f', a.miel], ['\ud83d\udd6f\ufe0f', a.cera], ['\ud83d\udfe4', a.propoleo], ['\ud83c\udf76', a.hidromiel]].forEach(([e, v], i) =&gt; { const bh = Math.min(50, v * 5); ctx.fillStyle = `rgba(${i % 2 ? NEON_B : NEON_A},0.85)`; ctx.fillRect(x + 14 + i * 34, y + h - 18 - bh, 14, bh); mTxt(e, x + 21 + i * 34, y + h - 9, 9, '#fff', 'center'); }); }&#10;        else { T('MANTENIMIENTO', x + 6, y + 9, 8); [['\ud83c\udfe0', 'casas'], ['\u2699\ufe0f', 'engranajes'], ['\ud83d\udcbb', 'ordenadores'], ['\ud83d\ude81', 'repcoche'], ['\ud83d\ude83', 'reptranvia']].forEach(([e, k], i) =&gt; { mTxt(e, x + 12, y + 24 + i * 14, 8, '#fff', 'center'); barra(x + 24, y + 21 + i * 14, w - 32, 1 - Desgaste.nivel(k), `rgba(${NEON_A},0.95)`); }); }&#10;    }&#10;    function panel(x, y, w, h, tipo, t, vivo) {&#10;        ctx.save(); ctx.fillStyle = `rgba(40,110,255,${vivo ? 0.16 : 0.07})`; ctx.fillRect(x, y, w, h); ctx.strokeStyle = `rgba(${NEON_A},${vivo ? 0.95 : 0.4})`; ctx.lineWidth = 1.3; ctx.strokeRect(x, y, w, h);&#10;        ctx.fillStyle = `rgba(${NEON_B},0.9)`; ctx.fillRect(x, y, 12, 2); ctx.fillRect(x + w - 12, y + h - 2, 12, 2); ctx.beginPath(); ctx.rect(x + 1, y + 1, w - 2, h - 2); ctx.clip();&#10;        if (vivo) { if (tipo) datos(tipo, x, y, w, h, t); else mini(x, y, w, h, t); ctx.fillStyle = 'rgba(170,220,255,0.2)'; ctx.fillRect(x, y + ((t * 0.8) % h), w, 2); }&#10;        ctx.restore();&#10;    }&#10;    function mini(x, y, w, h, t) {                                                                                  \/\/ gr\u00e1fico anal\u00edtico animado de los puestos&#10;        for (let i = 0; i &lt; 6; i++) { const bh = 8 + (Math.sin(t \/ 20 + i * 1.3 + x) * 0.5 + 0.5) * (h - 20); ctx.fillStyle = `rgba(${i % 2 ? NEON_B : NEON_A},0.8)`; ctx.fillRect(x + 6 + i * 10, y + h - 5 - bh, 7, bh); }&#10;        ctx.strokeStyle = 'rgba(124,255,217,0.9)'; ctx.lineWidth = 1; ctx.beginPath(); for (let i = 0; i &lt; 8; i++) { const px = x + 4 + i * 8, py = y + 12 + Math.sin(t \/ 15 + i + x) * 6; i ? ctx.lineTo(px, py) : ctx.moveTo(px, py); } ctx.stroke();&#10;    }&#10;    function visor(t, f) {                                                                                          \/\/ gafas AR ne\u00f3n sobre los ojos&#10;        ctx.save(); ctx.fillStyle = 'rgba(40,200,255,0.5)'; ctx.fillRect(-13, -9.5, 26, 7.5); ctx.strokeStyle = 'rgba(255,47,209,0.95)'; ctx.lineWidth = 1.3; ctx.strokeRect(-13, -9.5, 26, 7.5);&#10;        ctx.beginPath(); ctx.moveTo(-13, -6); ctx.lineTo(-17, -3); ctx.moveTo(13, -6); ctx.lineTo(17, -3); ctx.stroke(); ctx.fillStyle = 'rgba(255,255,255,0.55)'; ctx.fillRect(-13 + (((t * 0.6 + f * 20) % 60) - 10) * 0.5, -9.5, 3, 7.5); ctx.restore();&#10;    }&#10;    function gestos(s, x, y, t) {                                                                                   \/\/ manos que arrastran el panel, pellizco y comandos de voz&#10;        const pr = { x: s.x - 34, y: s.y - 152, w: 68, h: 46 }, ph = s.x * 0.013; ctx.save();&#10;        [-1, 1].forEach((d, k) =&gt; { const mx = pr.x + pr.w \/ 2 + d * 22 + Math.sin(t \/ 17 + ph + k) * 10, my = pr.y + pr.h - 6 + Math.cos(t \/ 13 + ph + k) * 8;&#10;            ctx.strokeStyle = 'rgba(47,140,255,0.45)'; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(mx, my); ctx.lineTo(pr.x + pr.w \/ 2 + d * 10, pr.y + pr.h \/ 2); ctx.stroke();&#10;            ctx.fillStyle = 'rgba(255,255,255,0.22)'; ctx.beginPath(); ctx.arc(mx, my, 6, 0, 7); ctx.fill(); ctx.fillStyle = 'rgba(255,47,209,0.95)'; ctx.beginPath(); ctx.arc(mx, my, 2.6, 0, 7); ctx.fill(); });&#10;        const c = (t + ph * 300) % 180; if (c &lt; 24) { ctx.strokeStyle = `rgba(124,255,217,${1 - c \/ 24})`; ctx.lineWidth = 1.5; ctx.beginPath(); ctx.arc(pr.x + pr.w \/ 2, pr.y + pr.h \/ 2, 4 + c * 0.7, 0, 7); ctx.stroke(); }&#10;        const v = (t + ph * 500) % 380; if (v &lt; 60) { ctx.strokeStyle = `rgba(255,47,209,${0.7 - v \/ 90})`; ctx.lineWidth = 1.4; for (let r = 0; r &lt; 3; r++) { ctx.beginPath(); ctx.arc(x + 20, y - 8, 8 + r * 7 + v * 0.2, -0.7, 0.7); ctx.stroke(); } }&#10;        ctx.restore();&#10;    }&#10;    function horario() {&#10;        const d = new Date(), dia = d.getDay(), hora = d.getHours() + d.getMinutes() \/ 60, lj = dia &gt;= 1 &amp;&amp; dia &lt;= 4, tele = lj &amp;&amp; hora &gt;= 9 &amp;&amp; hora &lt; 13;&#10;        return { tele, bib: tele ? 0 : (lj &amp;&amp; hora &gt;= 13 &amp;&amp; hora &lt; 20) ? 3 : (hora &gt;= 6 &amp;&amp; hora &lt; 23) ? 0.7 : 0 };&#10;    }&#10;    const dentro = () =&gt; habitantes.filter(h =&gt; h.oculta &amp;&amp; h.lugar === 'biblioteca'), teletrab = () =&gt; habitantes.filter(h =&gt; h.oculta &amp;&amp; h.lugar === 'casa' &amp;&amp; !h.cocinando);&#10;    function casaDe(h) {&#10;        if (h.casaAsignada === null || h.casaAsignada === undefined) h.casaAsignada = casaPropia(h);&#10;        return casas[h.casaAsignada];&#10;    }&#10;    const puertaBib = () =&gt; ({ x: BIBLIOTECA.x + BIBLIOTECA.ancho \/ 2, y: SUELO_Y + 62 });&#10;    function entrar(h) {&#10;        const usados = dentro().map(o =&gt; o.bib.puesto), libres = PUESTOS.map((_, i) =&gt; i).filter(i =&gt; !usados.includes(i)); if (!libres.length) return false;&#10;        const ahora = Date.now(); h.oculta = true; h.lugar = 'biblioteca'; h.bib = { puesto: libres[Math.floor(Math.random() * libres.length)], desde: ahora, fin: ahora + 45000 }; return true;&#10;    }&#10;    function teletrabajar(h) { casaDe(h); h.oculta = true; h.lugar = 'casa'; h.bib = { fin: Date.now() + 45000 }; }&#10;    function gestionar() {                                                                                          \/\/ llegadas y salidas seg\u00fan el reloj (tambi\u00e9n con la escena cerrada)&#10;        const ahora = Date.now();&#10;        habitantes.forEach(h =&gt; { if (h.oculta &amp;&amp; h.bib &amp;&amp; ahora &gt; h.bib.fin &amp;&amp; h !== chicaGimnasioArrastrada) { const p = h.lugar === 'casa' ? { x: casaDe(h).x + casaDe(h).ancho \/ 2, y: SUELO_Y + 62 } : h.lugar === 'gimnasio' ? GimnasioPueblo.puerta() : h.lugar === 'gargantua' ? Fiestas2.salida() : h.lugar === 'huerta' ? { x: ZONA_ENTRADA_HUERTA.x, y: ZONA_ENTRADA_HUERTA.y + 10 } : puertaBib(); if (h.lugar === 'gimnasio') GimnasioPueblo.limpiar(h); h.oculta = false; h.cocinando = false; h.lugar = null; h.bib = null; h.x = p.x; h.y = p.y; h.estado = 'caminando'; nuevoObjetivo(h); } });&#10;        if (ahora - ultHist &gt; 3000) { ultHist = ahora; hist.push(Kutxa.valor()); if (hist.length &gt; 60) hist.shift(); }&#10;    }&#10;    let cont = 0;&#10;    function actualizar() {&#10;        gestionar();&#10;        if (enBiblioteca &amp;&amp; ++cont % 480 === 0 &amp;&amp; horario().bib &gt; 0 &amp;&amp; dentro().length &lt; 3) {                         \/\/ mirando la sala, van llegando vecinas&#10;            const libres = habitantes.filter(h =&gt; !h.oculta &amp;&amp; !h.durmiendo &amp;&amp; !h.enPlaya &amp;&amp; !h.arrastrando &amp;&amp; ['caminando', 'parada', 'sentada', 'leyendo'].includes(h.estado));&#10;            if (libres.length) { const h = libres[Math.floor(Math.random() * libres.length)]; h.plan = null; h.objetivoY = null; entrar(h); }&#10;        }&#10;    }&#10;    function dibujar(t) {&#10;        if (!fondo) construir(); const now = Date.now();&#10;        ctx.drawImage(fondo, 0, 0);&#10;        COLUMNAS.forEach((x, i) =&gt; lluvia(x, 60, 258, 0.7 + i * 0.2, t, i)); TOTEMS.forEach((x, i) =&gt; { lluvia(x, 120, 196, 0.9 + i * 0.25, t, i % 2); for (let k = 0; k &lt; 5; k++) { const f = ((t * 0.012) + k \/ 5 + i * 0.2) % 1; ctx.fillStyle = `rgba(190,230,255,${0.8 * (1 - f)})`; ctx.fillRect(x - 1 + Math.sin(k * 3 + t \/ 20) * 8, 116 - f * 112, 2, 3); } });&#10;        PANELES.forEach((p, i) =&gt; panel(p.x, p.y, p.w, p.h, TIPOS[contenido[i]], t, true));&#10;        const ocup = dentro(); PUESTOS.forEach((s, i) =&gt; panel(s.x - 34, s.y - 152, 68, 46, null, t, ocup.some(o =&gt; o.bib.puesto === i)));&#10;        ocup.map(h =&gt; { const b = h.bib, s = PUESTOS[b.puesto], pin = Math.min(1, (now - b.desde) \/ 2500), pout = Math.max(0, 1 - (b.fin - now) \/ 2500), p = pin &lt; 1 ? pin : pout &gt; 0 ? 1 - pout : 1, q = p * p * (3 - 2 * p);&#10;            return { h, s, p, x: 480 + (s.x - 480) * q, y: 512 + (s.y - 24 - 512) * q }; }).sort((a, b) =&gt; a.y - b.y).forEach(o =&gt; {&#10;            ctx.save(); ctx.translate(o.x, o.y); ctx.scale(1.1, 1.1); dibujarMu\u00f1eca({ x: 0, y: 0, angulo: o.p &lt; 1 ? Math.sin(t \/ 6) * 0.06 : Math.sin(t \/ 40 + o.s.x) * 0.015 }, o.h.colorPelo, false, false, false, o.h.estilo);&#10;            accesorioFiesta(0, 0, 1); visor(t, o.s.x); ctx.restore();&#10;        });&#10;        ctx.drawImage(frente, 0, 0);&#10;        ocup.forEach(h =&gt; { const b = h.bib, s = PUESTOS[b.puesto]; if (now - b.desde &gt; 2500 &amp;&amp; b.fin - now &gt; 2500) gestos(s, s.x, s.y - 24, t); });&#10;        decorarBiblioteca(t);&#10;    }&#10;    function toque(x, y) {&#10;        if (y &gt; 495 &amp;&amp; x &gt; 430 &amp;&amp; x &lt; 530) { iniciarTransicion(() =&gt; salirDeEscena()); return; }                  \/\/ la puerta, abajo&#10;        PANELES.forEach((p, i) =&gt; { if (dentroRect(x, y, p)) contenido[i] = (contenido[i] + 1) % TIPOS.length; });  \/\/ cambia los datos del panel&#10;    }&#10;    return { actualizar, dibujar, toque, horario, entrar, teletrabajar, casaDe, puertaBib, dentro, teletrab, capacidad: PUESTOS.length };&#10;})();&#10;const GimnasioPueblo = (() =&gt; {&#10;    const puerta = () =&gt; ({ x: GIMNASIO_EDIFICIO.x + GIMNASIO_EDIFICIO.ancho \/ 2, y: SUELO_Y + 62 });&#10;    const dentro = () =&gt; habitantes.filter(h =&gt; h.oculta &amp;&amp; h.lugar === 'gimnasio');&#10;    function limpiar(h) { h.zonaActiva = null; h.meta = null; h.nado = null; h.ultimaZona = null; h.temporizador = 0; h.tomandoT = 0; h.chapuzon = 0; }&#10;    function entrar(h, yaDentro) {&#10;        if (h.patinete) { h.patinete.montadaPor = null; h.patinete = null; }&#10;        limpiar(h); h.oculta = true; h.lugar = 'gimnasio'; h.bib = { fin: Date.now() + 45000 };&#10;        if (yaDentro) { h.x = 60 + Math.random() * 880; h.y = 470 + Math.random() * 40; } else { h.x = 450 + Math.random() * 60; h.y = 522; }          \/\/ llega por la puerta de abajo&#10;        h.estado = 'de_pie'; h.espera = 40 + Math.random() * 100; if (h.fatiga === undefined) h.fatiga = 0; h.refrescada = 0; return true;&#10;    }&#10;    let cont = 0; const listar = () =&gt; { gimnasioChicas = dentro(); };&#10;    function reclutar(n, yaDentro = true) {                                                                       \/\/ al abrirlo, hay al menos n entrenando&#10;        const libres = habitantes.filter(h =&gt; !h.oculta &amp;&amp; !h.durmiendo &amp;&amp; !h.enPlaya &amp;&amp; !h.arrastrando &amp;&amp; ['caminando', 'parada', 'sentada', 'leyendo'].includes(h.estado)).sort(() =&gt; Math.random() - 0.5);&#10;        while (dentro().length &lt; n &amp;&amp; libres.length) { const h = libres.pop(); h.plan = null; h.objetivoY = null; entrar(h, yaDentro); }&#10;        listar();&#10;    }&#10;    function sincronizar() { listar(); if (++cont % 420 === 0 &amp;&amp; gimnasioChicas.length &lt; 3) reclutar(gimnasioChicas.length + 1, false); }   \/\/ mirando el gimnasio, van llegando vecinas&#10;    return { dentro, entrar, limpiar, sincronizar, reclutar, puerta, capacidad: 5 };&#10;})();&#10;function dibujarTeletrabajoCasa(t) {&#10;    const h = habitantes.find(o =&gt; o.oculta &amp;&amp; o.lugar === 'casa' &amp;&amp; !o.cocinando &amp;&amp; o.casaAsignada === casaAbierta); if (!h) return;&#10;    const x = 22, y = canvas.height - 40;&#10;    ctx.save(); ctx.translate(x, y + Math.sin(t \/ 45) * 0.8); dibujarMu\u00f1eca({ x: 0, y: 0, angulo: Math.sin(t \/ 35) * 0.02 }, h.colorPelo, false, false, false, h.estilo); accesorioFiesta(0, 0, 1); ctx.restore();   \/\/ sentada en la silla&#10;    ctx.save(); const g = 0.3 + 0.12 * Math.sin(t \/ 12); ctx.fillStyle = `rgba(130,210,255,${g})`; ctx.beginPath(); ctx.ellipse(54, canvas.height - 42, 22, 12, 0, 0, Math.PI * 2); ctx.fill();    \/\/ luz de la pantalla&#10;    ctx.fillStyle = 'rgba(255,255,255,0.85)'; [-1, 1].forEach((d, k) =&gt; { ctx.beginPath(); ctx.arc(34 + d * 5 + Math.sin(t \/ 5 + k * 2) * 2, canvas.height - 33 + Math.cos(t \/ 6 + k) * 1.5, 1.8, 0, Math.PI * 2); ctx.fill(); }); ctx.restore();   \/\/ manos tecleando&#10;}&#10;function decorarBiblioteca(t) {&#10;    const F = fiestaActual(); if (!F) return; const id = F.id, pal = PAL[id], ban = id === 'carnaval' || id === '28j';&#10;    ctx.save(); guirnalda(40, 920, 66, pal, t, ban);&#10;    if (id === 'navidad') {                                                                                          \/\/ pino hologr\u00e1fico y nieve por la claraboya&#10;        const x = 860, y = 392; ctx.lineWidth = 1.6; ctx.strokeStyle = 'rgba(56,240,192,0.95)';&#10;        [[322, 346, 16], [338, 368, 24], [354, 392, 32]].forEach(([a, b, w]) =&gt; { ctx.beginPath(); ctx.moveTo(x, a); ctx.lineTo(x + w, b); ctx.lineTo(x - w, b); ctx.closePath(); ctx.stroke(); });&#10;        for (let k = 0; k &lt; 7; k++) { ctx.fillStyle = PAL.navidad[k % 4]; ctx.globalAlpha = Math.sin(t \/ 9 + k) &gt; -0.2 ? 1 : 0.35; ctx.beginPath(); ctx.arc(x + (k % 3 - 1) * 12, 346 + k * 6, 2.2, 0, Math.PI * 2); ctx.fill(); }&#10;        ctx.globalAlpha = 1; ctx.fillStyle = '#ffd54a'; ctx.beginPath(); ctx.arc(x, 320, 3.4, 0, Math.PI * 2); ctx.fill();&#10;        ctx.fillStyle = 'rgba(255,255,255,0.8)'; for (let i = 0; i &lt; 26; i++) { ctx.beginPath(); ctx.arc(400 + ((i * 53) % 160) + Math.sin(t \/ 40 + i) * 6, (i * 37 + t * 0.6) % 330, 1.6, 0, Math.PI * 2); ctx.fill(); }&#10;    } else if (id === 'carnaval' || id === '28j') {                                                                  \/\/ confeti y, el 28J, el arco\u00edris sobre el ne\u00f3n del techo&#10;        if (id === '28j') { ctx.globalAlpha = 0.75; pal.forEach((c, i) =&gt; { ctx.fillStyle = c; ctx.fillRect(0, 31 + i * 2.6, 960, 2.4); }); ctx.globalAlpha = 1; }&#10;        dibujarConfeti(t);&#10;    } else if (id === 'sanjuan') {                                                                                   \/\/ farolillos hologr\u00e1ficos con chispas&#10;        [[200, 232], [480, 214], [760, 232]].forEach(([x, y], i) =&gt; { const yy = y + Math.sin(t \/ 40 + i) * 5, g = ctx.createRadialGradient(x, yy, 1, x, yy, 30); g.addColorStop(0, 'rgba(255,170,40,0.55)'); g.addColorStop(1, 'rgba(255,170,40,0)'); ctx.fillStyle = g; ctx.beginPath(); ctx.arc(x, yy, 30, 0, Math.PI * 2); ctx.fill(); mTxt('\ud83c\udfee', x, yy, 16, '#000', 'center');&#10;            ctx.fillStyle = '#ffb347'; for (let k = 0; k &lt; 3; k++) { const f = ((t \/ 50) + k \/ 3) % 1; ctx.globalAlpha = 1 - f; ctx.beginPath(); ctx.arc(x + Math.sin(k * 4 + t \/ 18) * 6, yy + 10 - f * 24, 1.2, 0, Math.PI * 2); ctx.fill(); } ctx.globalAlpha = 1; });&#10;    } else if (id === 'halloween') {                                                                                 \/\/ calabazas flotantes, murci\u00e9lagos y telara\u00f1as&#10;        [[130, 250], [380, 268], [590, 268], [830, 250]].forEach(([x, y], i) =&gt; mTxt('\ud83c\udf83', x, y + Math.sin(t \/ 35 + i) * 5, 20, '#000', 'center'));&#10;        for (let i = 0; i &lt; 3; i++) dibujarMurcielago(((t * 0.9 + i * 330) % 1100) - 70, 90 + i * 22 + Math.sin(t \/ 25 + i) * 10, t, 1);&#10;        mTxt('\ud83d\udd78\ufe0f', 26, 72, 16, '#000', 'center'); mTxt('\ud83d\udd78\ufe0f', 934, 72, 16, '#000', 'center');&#10;    }&#10;    ctx.restore();&#10;}&#10;const SiloCompost = (() =&gt; {&#10;    const e = { silo: 0, compost: 0, residuos: 0, madura: 0 }, CAP_SILO = 60, CAP_COMP = 6, SILO = { x: 800, y: 160 }, COMP = { x: 700, y: 158 };&#10;    let ultimo = performance.now(), flash = 0, ultRev = 0;&#10;    function tick(now) {&#10;        const dt = Math.min(0.2, (now - ultimo) \/ 1000); ultimo = now;&#10;        if (e.residuos &gt;= 2 &amp;&amp; e.compost &lt; CAP_COMP) { e.madura += dt; if (e.madura &gt;= 40) { e.madura = 0; e.residuos -= 2; e.compost++; recursos.resina = Math.min(100, recursos.resina + 3); } }&#10;        if (now - ultRev &gt; 1000) {                                                                                  \/\/ el silo repone los puestos que se quedan vac\u00edos&#10;            ultRev = now;&#10;            [0, 1, 3].forEach(i =&gt; PUESTOS[i].prods.forEach(p =&gt; { if (p.s &lt;= 0 &amp;&amp; e.silo &gt;= 2) { e.silo -= 2; p.s += 4; flash = now + 2000; if (enMercado) mostrarToastMercado(`\ud83c\udfda\ufe0f El silo repone ${p.e} ${p.n}`); } }));&#10;        }&#10;    }&#10;    function dibujar(t) {&#10;        const now = performance.now(), x = SILO.x, Y = SILO.y, top = Y - 106, nivel = e.silo \/ CAP_SILO;&#10;        ctx.save(); ctx.lineWidth = 2; ctx.strokeStyle = '#000'; sombra(x, Y + 3, 46, 6, 0.28);&#10;        ctx.fillStyle = '#8d8f94'; ctx.fillRect(x - 31, Y - 18, 62, 18); ctx.strokeRect(x - 31, Y - 18, 62, 18);                    \/\/ base de piedra con sillares&#10;        ctx.strokeStyle = 'rgba(40,40,45,0.55)'; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(x - 31, Y - 9); ctx.lineTo(x + 31, Y - 9);&#10;        for (let r = 0; r &lt; 2; r++) for (let k = 0; k &lt; 5; k++) { const bx = x - 31 + (r ? 6 : 0) + k * 13; ctx.moveTo(bx, Y - 18 + r * 9); ctx.lineTo(bx, Y - 9 + r * 9); } ctx.stroke();&#10;        ctx.lineWidth = 2; ctx.strokeStyle = '#000'; ctx.fillStyle = '#a8412a'; ctx.fillRect(x - 26, top, 52, 88); ctx.strokeRect(x - 26, top, 52, 88);                  \/\/ cuerpo de ladrillo rojo&#10;        ctx.strokeStyle = 'rgba(70,22,12,0.4)'; ctx.lineWidth = 1; ctx.beginPath();&#10;        for (let r = 0; r &lt; 14; r++) { const y = top + 6 + r * 6; ctx.moveTo(x - 26, y); ctx.lineTo(x + 26, y); for (let k = 0; k &lt; 6; k++) { const bx = x - 26 + (r % 2 ? 4 : 12) + k * 8.7; if (bx &lt; x + 26) { ctx.moveTo(bx, y - 6); ctx.lineTo(bx, y); } } } ctx.stroke();&#10;        ctx.fillStyle = 'rgba(255,205,170,0.2)'; ctx.fillRect(x - 25, top + 1, 9, 86); ctx.fillStyle = 'rgba(0,0,0,0.26)'; ctx.fillRect(x + 14, top + 1, 11, 86);   \/\/ luz y sombra del cilindro&#10;        ctx.fillStyle = '#3a3f45'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.5; [0.2, 0.52, 0.84].forEach(f =&gt; { ctx.fillRect(x - 27, top + 88 * f, 54, 4); ctx.strokeRect(x - 27, top + 88 * f, 54, 4); });   \/\/ aros de hierro&#10;        ctx.fillStyle = '#6b6f75'; ctx.beginPath(); ctx.moveTo(x - 32, top + 2); ctx.lineTo(x, top - 28); ctx.lineTo(x + 32, top + 2); ctx.closePath(); ctx.fill(); ctx.stroke();              \/\/ tejado c\u00f3nico de zinc&#10;        ctx.fillStyle = '#3a3f45'; ctx.beginPath(); ctx.arc(x, top - 30, 3, 0, Math.PI * 2); ctx.fill();&#10;        ctx.fillStyle = '#7a4a24'; ctx.beginPath(); ctx.moveTo(x - 8, Y - 18); ctx.lineTo(x - 8, Y - 36); ctx.quadraticCurveTo(x, Y - 46, x + 8, Y - 36); ctx.lineTo(x + 8, Y - 18); ctx.closePath(); ctx.fill(); ctx.stroke();   \/\/ puerta de madera&#10;        ctx.strokeStyle = 'rgba(0,0,0,0.5)'; ctx.beginPath(); ctx.moveTo(x, Y - 42); ctx.lineTo(x, Y - 18); ctx.stroke();&#10;        ctx.fillStyle = '#1d242c'; ctx.strokeStyle = '#000'; ctx.fillRect(x + 11, top + 14, 8, 58); ctx.strokeRect(x + 11, top + 14, 8, 58);                                                    \/\/ ventanilla del nivel de grano&#10;        const h = 56 * nivel; ctx.fillStyle = '#e6b422'; ctx.fillRect(x + 12, top + 15 + 56 - h, 6, h);&#10;        ctx.fillStyle = 'rgba(255,255,255,0.35)'; ctx.fillRect(x + 12, top + 15, 2, 56);&#10;        if (now &lt; flash) { ctx.fillStyle = `rgba(124,255,217,${0.5 + 0.4 * Math.sin(t \/ 3)})`; ctx.beginPath(); ctx.arc(x - 14, top + 14, 3, 0, Math.PI * 2); ctx.fill(); }               \/\/ piloto: acaba de repartir&#10;        if (e.silo &gt; 0) { ctx.fillStyle = '#e6b422'; ctx.beginPath(); ctx.ellipse(x + 14, Y + 2, 9, 3, 0, 0, Math.PI * 2); ctx.fill(); }                                                          \/\/ grano junto a la puerta&#10;        ctx.restore(); this.decorarFiesta(x, Y, top, t); this.dibujarCompostera(t);&#10;    }&#10;    function dibujarCompostera(t) {&#10;        const x = COMP.x, Y = COMP.y, pila = Math.min(1, (e.residuos + e.compost * 2) \/ 8), lleno = e.residuos &gt;= 2 &amp;&amp; e.compost &lt; CAP_COMP;&#10;        ctx.save(); ctx.lineWidth = 2; ctx.strokeStyle = '#000'; sombra(x, Y + 3, 40, 5, 0.25);&#10;        ctx.fillStyle = '#4a3220'; ctx.beginPath(); ctx.ellipse(x, Y - 12 - pila * 8, 26, 9 + pila * 9, 0, Math.PI, 0); ctx.fill();                                                            \/\/ mont\u00f3n de compost&#10;        ctx.fillStyle = '#8bc34a'; for (let k = 0; k &lt; 4; k++) { ctx.beginPath(); ctx.arc(x - 14 + k * 9, Y - 14 - pila * 6 - (k % 2) * 3, 2.2, 0, Math.PI * 2); ctx.fill(); }          \/\/ restos verdes&#10;        if (lleno) { ctx.strokeStyle = '#ec8fb0'; ctx.lineWidth = 1.4; [-8, 10].forEach((dx, k) =&gt; { ctx.beginPath(); ctx.moveTo(x + dx, Y - 14 - pila * 5); ctx.quadraticCurveTo(x + dx + 3, Y - 16 - pila * 5 + Math.sin(t \/ 6 + k) * 2, x + dx + 6, Y - 14 - pila * 5); ctx.stroke(); }); }   \/\/ lombrices&#10;        ctx.fillStyle = '#8a5a2b'; ctx.strokeStyle = '#000'; ctx.lineWidth = 2;&#10;        [0, 1, 2].forEach(i =&gt; { ctx.fillRect(x - 30, Y - 8 - i * 9, 60, 8); ctx.strokeRect(x - 30, Y - 8 - i * 9, 60, 8); });                                                              \/\/ tablones del caj\u00f3n&#10;        [-30, 30].forEach(px =&gt; { ctx.fillRect(px + x - 3, Y - 30, 6, 30); ctx.strokeRect(px + x - 3, Y - 30, 6, 30); });&#10;        if (lleno) { ctx.fillStyle = 'rgba(235,240,245,0.5)'; for (let k = 0; k &lt; 3; k++) { const f = ((t \/ 55) + k \/ 3) % 1; ctx.globalAlpha = 0.6 * (1 - f); ctx.beginPath(); ctx.arc(x - 10 + k * 10 + Math.sin(t \/ 15 + k) * 3, Y - 30 - pila * 6 - f * 26, 4 + f * 4, 0, Math.PI * 2); ctx.fill(); } ctx.globalAlpha = 1; }   \/\/ vapor de la fermentaci\u00f3n&#10;        for (let k = 0; k &lt; e.compost; k++) { ctx.fillStyle = '#c9a46a'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.5; const sx = x + 42 + (k % 3) * 13, sy = Y - 7 - Math.floor(k \/ 3) * 11; ctx.fillRect(sx - 6, sy - 9, 12, 11); ctx.strokeRect(sx - 6, sy - 9, 12, 11); ctx.fillStyle = '#6b4a2b'; ctx.fillRect(sx - 3, sy - 10, 6, 2); }   \/\/ sacos de compost listos&#10;        ctx.restore();&#10;    }&#10;    function dibujarMantillo() { huertaSiembra.forEach(p =&gt; { if (p.abonada) { ctx.fillStyle = 'rgba(60,38,22,0.55)'; ctx.beginPath(); ctx.ellipse(p.x, SIEMBRA_Y + 3, 13, 4, 0, 0, Math.PI * 2); ctx.fill(); } }); }&#10;    function decorarFiesta(x, Y, top, t) {                                                                                                                                                       \/\/ detalle de la fiesta del calendario&#10;        const F = fiestaActual(); if (!F) return; const id = F.id, pal = PAL[id];&#10;        ctx.save(); guirnalda(x - 34, x + 34, Y - 62, pal, t, id === 'carnaval' || id === '28j');&#10;        if (id === 'navidad') mTxt('\u2b50', x, top - 38, 14, '#000', 'center'); else if (id === 'halloween') mTxt('\ud83c\udf83', x - 40, Y - 6, 16, '#000', 'center'); else if (id === 'sanjuan' || id === 'feria') mTxt('\ud83c\udfee', x + 40, Y - 58, 14, '#000', 'center'); else if (id === 'santjordi') mTxt('\ud83c\udf39', x + 40, Y - 58, 14, '#000', 'center');&#10;        ctx.restore();&#10;    }&#10;    return { e, tick, dibujar, dibujarCompostera, dibujarMantillo, decorarFiesta,&#10;        cosecha(bono) { e.silo = Math.min(CAP_SILO, e.silo + 2 + bono); e.residuos = Math.min(12, e.residuos + 1); },&#10;        usarCompost() { if (e.compost &gt; 0) { e.compost--; return true; } return false; } };&#10;})();&#10;const PARADAS = [{ x: TRANVIA.x, nombre: 'centro', e: '\ud83d\ude83' }, { x: 495, nombre: 'biblioteca', e: '\ud83d\udcda' }, { x: 640, nombre: 'gimnasio', e: '\ud83c\udfcb\ufe0f' }];&#10;const Tranvia = (() =&gt; {&#10;    const PLAT = TRANVIA.y + 6, CAP = 6;&#10;    function dibujarParadas() {                                                                                      \/\/ poste y cartel de cada parada&#10;        PARADAS.forEach(p =&gt; { ctx.save(); ctx.lineWidth = 1.5; ctx.strokeStyle = '#000'; ctx.fillStyle = '#5a6066'; ctx.fillRect(p.x + 18, PLAT + 16, 3, 22); ctx.strokeRect(p.x + 18, PLAT + 16, 3, 22);&#10;            ctx.fillStyle = '#2f6fd0'; ctx.fillRect(p.x + 10, PLAT + 6, 19, 13); ctx.strokeRect(p.x + 10, PLAT + 6, 19, 13); mTxt(p.e, p.x + 19.5, PLAT + 13, 9, '#fff', 'center'); ctx.restore(); });&#10;    }&#10;    function esperar(h, i) { h.estado = 'esperando_tranvia'; h.paradaTram = i; h.esperaDesde = Date.now(); h.direccion = 1; return true; }&#10;    function destinoPara(i) {                                                                                         \/\/ a d\u00f3nde va: la playa (final de l\u00ednea) o una parada intermedia posterior&#10;        const hr = Biblioteca.horario(), op = [['playa', 0.5]];&#10;        PARADAS.forEach((p, j) =&gt; { if (j &gt; i &amp;&amp; (p.nombre === 'gimnasio' || (p.nombre === 'biblioteca' &amp;&amp; hr.bib &gt; 0))) op.push([p.nombre, 0.3]); });&#10;        let r = Math.random() * op.reduce((a, o) =&gt; a + o[1], 0); for (const [d, w] of op) { if ((r -= w) &lt;= 0) return d; } return 'playa';&#10;    }&#10;    function gestionar(T, t) {&#10;        T.pasajeras = T.pasajeras.filter(q =&gt; q.h.oculta &amp;&amp; q.h.lugar === 'tranvia');                                   \/\/ las que ya no est\u00e1n (p. ej. se fueron a dormir) se descartan&#10;        const i = T.estado === 'parado' ? 0 : T.estado === 'estacion' ? T.parada : -1; if (i &lt; 0 || t % 24) return; const p = PARADAS[i];&#10;        const k = T.pasajeras.findIndex(q =&gt; q.dest === p.nombre);&#10;        if (k &gt;= 0) { const h = T.pasajeras.splice(k, 1)[0].h; h.oculta = false; h.lugar = null; h.x = p.x; h.y = PLAT; h.estado = 'caminando'; h.objetivoY = null; VidaDiaria.irA(h, p.nombre === 'gimnasio' ? 'gimnasio' : 'estudio'); return; }   \/\/ baja y va a su destino&#10;        if (T.pasajeras.length &lt; CAP) { const h = habitantes.find(o =&gt; o.estado === 'esperando_tranvia' &amp;&amp; o.paradaTram === i &amp;&amp; !o.oculta); if (h) { h.oculta = true; h.lugar = 'tranvia'; h.esperaDesde = 0; T.pasajeras.push({ h, dest: destinoPara(i) }); } }   \/\/ sube la primera de la cola&#10;    }&#10;    function llegaPlaya(T) {                                                                                           \/\/ el tren sale por la derecha: las que segu\u00edan a bordo llegan a la playa&#10;        T.pasajeras = T.pasajeras.filter(q =&gt; { if (q.dest !== 'playa') return true; const h = q.h; h.oculta = false; h.lugar = null; enviarAPlaya(h); h.finPlayaVida = Date.now() + 80000 + Math.random() * 80000; return false; });&#10;    }&#10;    function dibujarPasajeras(T, t, off) {                                                                              \/\/ sus caritas, peque\u00f1as, asomadas a las ventanillas&#10;        T.pasajeras.forEach((q, i) =&gt; { const k = 1 + Math.floor(i \/ 3) % T.n, wx = T.x - off(k) + [-22, -2, 18][i % 3], wy = TRANVIA.y - 22;&#10;            ctx.save(); ctx.beginPath(); ctx.rect(wx - 8, wy - 6, 16, 12); ctx.clip(); ctx.translate(wx, wy + 1); ctx.scale(0.3, 0.3); dibujarMu\u00f1eca({ x: 0, y: 0, angulo: 0 }, q.h.colorPelo, false, false, false, q.h.estilo); ctx.restore(); });&#10;    }&#10;    return { PLAT, dibujarParadas, esperar, gestionar, llegaPlaya, dibujarPasajeras };&#10;})();&#10;let enPuerto = false;&#10;const Puerto = (() =&gt; {&#10;    const W = 960, H = 540, MUELLE = { x: 846, y: 214, w: 110, h: 138 }, PIER_X = 892, QUAY = 318, SALIDA = { x: 14, y: 462, w: 128, h: 52 };&#10;    const FLOTA = [{ id: 'yate', P: 210000, off: 0.1, lane: 122, esc: 0.55, berth: 470 }, { id: 'solar', P: 150000, off: 0.55, lane: 246, esc: 0.8, berth: 200 }];&#10;    const ease = k =&gt; k * k * (3 - 2 * k), lerp = (a, b, k) =&gt; a + (b - a) * k;&#10;    const H2 = { nivel: 40 }, SLIPS = [690, 800], PUMPS = [{ x: 540 }, { x: 640 }, { x: 850 }];&#10;    const MOTOS = [{ id: 'moto0', P: 100000, off: 0, lane: 270, slip: 690, col: '#ff6fa8', rid: '#2b3a67', gasto: 3, ok: true, ciclo: -1 }, { id: 'moto1', P: 100000, off: 0.5, lane: 322, slip: 800, col: '#2fd6c0', rid: '#8a2b6b', gasto: 3, ok: true, ciclo: -1 }];&#10;    const YATE_GAS = { gasto: 2, ciclo: -1 };&#10;    const TUB_AGUA = [[762, 492], [722, 492], [722, 322], [722, 306]], TUB_H2 = [[910, 440], [910, 408], [540, 408]];&#10;    const AIRE = { n: 60 }, BUC = { x: 330, y: 470 }, FONDO = { s: 40, b: 3 }, DUR_BUCEO = 70000, AIRE_BUCEO = 12; let llenando = false, ultBasura = 0, ultRobot = 0;&#10;    const buceoDisponible = () =&gt; AIRE.n &gt;= AIRE_BUCEO &amp;&amp; performance.now() &gt;= temporalHasta;&#10;    function empezarBuceo(h) {&#10;        if (!buceoDisponible()) return false; AIRE.n -= AIRE_BUCEO; const a = Date.now();&#10;        h.buceoIni = a; h.buceoFin = a + DUR_BUCEO; h.buceoAplicado = false; h.buceoItems = Math.min(3, FONDO.b); h.buceoSitio = Math.floor(Math.random() * 6); return true;&#10;    }&#10;    function finBuceo(h) {                                                                                     \/\/ efectos suaves: mejora la salud del fondo y baja la basura (idempotente)&#10;        if (!h.buceoFin || h.buceoAplicado) return; h.buceoAplicado = true; const it = h.buceoItems || 0;&#10;        FONDO.b = Math.max(0, FONDO.b - it); FONDO.s = Math.min(100, FONDO.s + 3 + it * 1.2);&#10;        Noticias.publicar('\ud83e\udd3f Una vecina ha plantado posidonia' + (it ? ' y recogido ' + it + (it &gt; 1 ? ' restos' : ' resto') + ' del fondo' : ''), 'buceo', 240000);&#10;    }&#10;    const buzos = () =&gt; habitantesEnPlaya.filter(h =&gt; h.zonaPlaya &amp;&amp; h.zonaPlaya.accion === 'bucear' &amp;&amp; h.buceoIni);&#10;    let capa = null, capaPlanta = null, sprites = {}, produciendo = false, ultTick = performance.now(), temporalHasta = 0;&#10;    function temporal(ms) { temporalHasta = performance.now() + ms; }&#10;    function fase(b, now) {&#10;        if (now &lt; temporalHasta) return { tipo: 'amarrado', u: 0.5 };                                              \/\/ temporal: todos amarrados&#10;        const u = ((now \/ b.P) + b.off) % 1;&#10;        if (u &lt; 0.22 || u &gt;= 0.94) return { tipo: 'amarrado', u };&#10;        if (u &lt; 0.5) return { tipo: 'sale', k: (u - 0.22) \/ 0.28 };&#10;        if (u &lt; 0.66) return { tipo: 'lejos' };&#10;        return { tipo: 'vuelve', k: (u - 0.66) \/ 0.28 };&#10;    }&#10;    function faseMoto(m, now) {&#10;        const u = ((now \/ m.P) + m.off) % 1;&#10;        if (!m.ok || now &lt; temporalHasta) return { tipo: 'amarrado', u: 0.5 };&#10;        if (u &lt; 0.25 || u &gt;= 0.85) return { tipo: 'amarrado', u };&#10;        if (u &lt; 0.30) return { tipo: 'sale', k: (u - 0.25) \/ 0.05 };&#10;        if (u &lt; 0.80) return { tipo: 'costa', k: (u - 0.30) \/ 0.5 };&#10;        return { tipo: 'vuelve', k: (u - 0.80) \/ 0.05 };&#10;    }&#10;    function tick(now) {                                                                                           \/\/ producci\u00f3n de hidr\u00f3geno y repostaje (por reloj; no depende de la escena visible)&#10;        const dt = Math.min(0.2, (now - ultTick) \/ 1000); ultTick = now;&#10;        produciendo = H2.nivel &lt; 100 &amp;&amp; recursos.energia &gt;= 30;&#10;        if (produciendo) { H2.nivel = Math.min(100, H2.nivel + dt * 0.15); recursos.energia -= dt * 0.05; }&#10;        if (!ultBasura) ultBasura = now;&#10;        FONDO.s = Math.max(0, FONDO.s - dt * 0.012);                                                                          \/\/ si nadie lo cuida, el fondo se resiente poco a poco&#10;        if (now - ultBasura &gt; 40000 * (0.5 + 0.5 * FONDO.s \/ 100)) { ultBasura = now; if (FONDO.b &lt; 8) FONDO.b++; }       \/\/ y le llega basura (m\u00e1s cuanto peor est\u00e1)&#10;        if (now - ultRobot &gt; 90000) { ultRobot = now; if (FONDO.b &gt; 0) FONDO.b--; FONDO.s = Math.min(100, FONDO.s + 1); }          \/\/ los robots-huevo mantienen el fondo aunque nadie bucee&#10;        habitantesEnPlaya.forEach(h =&gt; { if (h.buceoFin &amp;&amp; !h.buceoAplicado &amp;&amp; Date.now() &gt;= h.buceoFin) finBuceo(h); });&#10;        if (FONDO.s &gt;= 70) Noticias.publicar('\ud83c\udf3f El fondo marino est\u00e1 en plena forma: m\u00e1s algas y menos basura en la orilla', 'fondo70', 1800000);&#10;        if (FONDO.s &lt;= 20) Noticias.publicar('\u26a0\ufe0f El fondo marino necesita cuidados: pocas vecinas est\u00e1n buceando', 'fondo20', 1800000);&#10;        llenando = AIRE.n &lt; 100 &amp;&amp; recursos.energia &gt;= 25; if (llenando) { AIRE.n = Math.min(100, AIRE.n + dt * 0.4); recursos.energia -= dt * 0.03; }                       \/\/ el compresor de la estaci\u00f3n de buceo, con energ\u00eda solar&#10;        if (H2.nivel &lt; 3) Noticias.publicar('\ud83d\udee2\ufe0f El dep\u00f3sito de hidr\u00f3geno est\u00e1 casi vac\u00edo: las motos esperan', 'h2', 300000);&#10;        MOTOS.forEach(m =&gt; { const c = Math.floor(now \/ m.P + m.off); if (m.ciclo === -1) { m.ciclo = c; m.ok = H2.nivel &gt;= m.gasto; } else if (c !== m.ciclo) { m.ciclo = c; if (H2.nivel &gt;= m.gasto) { H2.nivel -= m.gasto; m.ok = true; } else m.ok = false; } });   \/\/ al arrancar no gasta: la moto ya estaba en su ciclo&#10;        const cy = Math.floor(now \/ FLOTA[0].P + FLOTA[0].off); if (YATE_GAS.ciclo === -1) YATE_GAS.ciclo = cy; else if (cy !== YATE_GAS.ciclo) { YATE_GAS.ciclo = cy; H2.nivel = Math.max(0, H2.nivel - YATE_GAS.gasto); }&#10;    }&#10;    function rejilla(x, y, w, h, nx, ny) { ctx.strokeStyle = 'rgba(140,190,255,0.75)'; ctx.lineWidth = 0.8; ctx.beginPath(); for (let i = 1; i &lt; nx; i++) { ctx.moveTo(x + w * i \/ nx, y); ctx.lineTo(x + w * i \/ nx, y + h); } for (let j = 1; j &lt; ny; j++) { ctx.moveTo(x, y + h * j \/ ny); ctx.lineTo(x + w, y + h * j \/ ny); } ctx.stroke(); }&#10;    function spriteYate() {&#10;        return sprites.yate || (sprites.yate = { ox: 100, oy: 84, c: conLienzo(200, 110, () =&gt; {&#10;            ctx.translate(100, 84); ctx.lineWidth = 2; ctx.strokeStyle = '#000';&#10;            ctx.fillStyle = '#f4f1e8'; ctx.beginPath(); ctx.moveTo(-82, -12); ctx.lineTo(80, -14); ctx.quadraticCurveTo(72, 10, 42, 12); ctx.lineTo(-54, 12); ctx.quadraticCurveTo(-78, 6, -82, -12); ctx.closePath(); ctx.fill(); ctx.stroke();       \/\/ casco&#10;            ctx.fillStyle = '#1f4e79'; ctx.fillRect(-77, -9, 150, 5);                                                                                                                                                  \/\/ franja marina&#10;            ctx.fillStyle = '#fff'; ctx.fillRect(-54, -34, 98, 22); ctx.strokeRect(-54, -34, 98, 22);                                                                                                                  \/\/ cabina&#10;            ctx.fillStyle = '#2b4a6b'; for (let k = 0; k &lt; 6; k++) ctx.fillRect(-48 + k * 15.5, -29, 11, 8);                                                                                                           \/\/ ventanas&#10;            ctx.fillStyle = '#f4f1e8'; ctx.fillRect(-32, -48, 62, 14); ctx.strokeRect(-32, -48, 62, 14);                                                                                                               \/\/ puente&#10;            ctx.fillStyle = '#1d3f7a'; ctx.beginPath(); ctx.moveTo(-46, -53); ctx.lineTo(40, -53); ctx.lineTo(46, -48); ctx.lineTo(-40, -48); ctx.closePath(); ctx.fill(); ctx.stroke(); rejilla(-44, -53, 88, 5, 9, 1);   \/\/ paneles solares&#10;            ctx.strokeStyle = '#444'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(6, -53); ctx.lineTo(6, -74); ctx.stroke();                                                                                       \/\/ m\u00e1stil&#10;            ctx.fillStyle = '#43b36a'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.2; ctx.beginPath(); ctx.moveTo(7, -74); ctx.lineTo(24, -69); ctx.lineTo(7, -64); ctx.closePath(); ctx.fill(); ctx.stroke();                    \/\/ bandera verde&#10;            ctx.fillStyle = '#9bd3ff'; [-62, 52].forEach(px =&gt; { ctx.beginPath(); ctx.arc(px, -2, 3.2, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); });&#10;        }) });&#10;    }&#10;    function spriteSolar() {&#10;        return sprites.solar || (sprites.solar = { ox: 60, oy: 54, c: conLienzo(120, 70, () =&gt; {&#10;            ctx.translate(60, 54); ctx.lineWidth = 2; ctx.strokeStyle = '#000';&#10;            ctx.fillStyle = '#e8f6ff'; ctx.beginPath(); ctx.moveTo(-48, -6); ctx.lineTo(50, -6); ctx.quadraticCurveTo(42, 9, 22, 9); ctx.lineTo(-36, 9); ctx.quadraticCurveTo(-48, 5, -48, -6); ctx.closePath(); ctx.fill(); ctx.stroke();&#10;            ctx.fillStyle = '#38c9a8'; ctx.fillRect(-44, -3, 90, 4);&#10;            ctx.fillStyle = '#fff'; ctx.fillRect(-18, -22, 34, 16); ctx.strokeRect(-18, -22, 34, 16); ctx.fillStyle = '#2b4a6b'; ctx.fillRect(-13, -18, 11, 8); ctx.fillRect(2, -18, 11, 8);&#10;            ctx.strokeStyle = '#555'; ctx.lineWidth = 1.6; ctx.beginPath(); ctx.moveTo(-30, -6); ctx.lineTo(-30, -30); ctx.moveTo(30, -6); ctx.lineTo(30, -30); ctx.stroke();&#10;            ctx.fillStyle = '#1d3f7a'; ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(-40, -34); ctx.lineTo(38, -34); ctx.lineTo(44, -28); ctx.lineTo(-46, -28); ctx.closePath(); ctx.fill(); ctx.stroke(); rejilla(-42, -34, 82, 6, 8, 1);   \/\/ toldo solar&#10;            ctx.fillStyle = '#43b36a'; ctx.lineWidth = 1.2; ctx.beginPath(); ctx.moveTo(-1, -34); ctx.lineTo(-1, -46); ctx.lineTo(12, -41); ctx.lineTo(-1, -38); ctx.closePath(); ctx.fill(); ctx.stroke();&#10;        }) });&#10;    }&#10;    function spriteMoto(m, piloto = true) {&#10;        const kk = m.id + (piloto ? '' : 'x'); return sprites[kk] || (sprites[kk] = { ox: 30, oy: 32, c: conLienzo(64, 44, () =&gt; {&#10;            ctx.translate(30, 32); ctx.lineWidth = 1.6; ctx.strokeStyle = '#000';&#10;            ctx.fillStyle = m.col; ctx.beginPath(); ctx.moveTo(-26, 2); ctx.lineTo(-22, -8); ctx.quadraticCurveTo(-8, -14, 10, -11); ctx.quadraticCurveTo(24, -8, 30, 1); ctx.quadraticCurveTo(10, 8, -14, 6); ctx.closePath(); ctx.fill(); ctx.stroke();&#10;            ctx.strokeStyle = '#fff'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(-18, -3); ctx.quadraticCurveTo(0, -8, 22, -3); ctx.stroke();&#10;            ctx.fillStyle = '#3fb37f'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.2; ctx.fillRect(-29, -9, 9, 5); ctx.strokeRect(-29, -9, 9, 5);                  \/\/ dep\u00f3sito de H\u2082&#10;            ctx.fillStyle = '#20262e'; ctx.fillRect(-14, -16, 16, 5); ctx.strokeStyle = '#444'; ctx.lineWidth = 1.8; ctx.beginPath(); ctx.moveTo(8, -12); ctx.lineTo(11, -21); ctx.lineTo(17, -21); ctx.stroke();&#10;            if (piloto) {&#10;            ctx.fillStyle = m.rid; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.2; ctx.fillRect(-9, -31, 11, 17); ctx.strokeRect(-9, -31, 11, 17);                      \/\/ piloto&#10;            ctx.fillStyle = '#f2c9a0'; ctx.beginPath(); ctx.arc(-3, -35, 4.6, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#fff'; ctx.beginPath(); ctx.arc(-3, -36, 5, Math.PI, 0); ctx.fill(); ctx.stroke();&#10;            ctx.strokeStyle = '#20262e'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(0, -27); ctx.lineTo(14, -21); ctx.stroke();&#10;            }&#10;        }) });&#10;    }&#10;    const pilotoDe = m =&gt; { const i = MOTOS.indexOf(m); return habitantesEnPlaya.find(h =&gt; h.zonaPlaya &amp;&amp; h.zonaPlaya.accion === 'moto' &amp;&amp; h.zonaPlaya.idx === i) || null; };&#10;    const motoDisponible = i =&gt; { const m = MOTOS[i], now = performance.now(); return !!m &amp;&amp; m.ok &amp;&amp; now &gt;= temporalHasta &amp;&amp; H2.nivel &gt;= m.gasto &amp;&amp; faseMoto(m, now).tipo === 'amarrado'; };&#10;    function arrancarMoto(i) {                                                                                   \/\/ una chica sube: la moto sale ya (se adelanta su ciclo) y gasta su hidr\u00f3geno&#10;        const m = MOTOS[i]; if (!motoDisponible(i)) return false; const now = performance.now();&#10;        m.off = (((0.25 - now \/ m.P) % 1) + 1) % 1; m.ciclo = Math.floor(now \/ m.P + m.off); H2.nivel -= m.gasto;&#10;        Noticias.publicar('\ud83c\udf0a Una vecina sale a pilotar una moto de agua de hidr\u00f3geno', 'moto', 600000); return true;&#10;    }&#10;    function dibujarMoto(m, x, y, dir, esc, estela) {&#10;        if (estela) { ctx.fillStyle = 'rgba(255,255,255,0.45)'; ctx.beginPath(); ctx.ellipse(x - dir * 34 * esc, y + 3, 30 * esc, 4 * esc, 0, 0, Math.PI * 2); ctx.fill(); for (let k = 0; k &lt; 3; k++) { ctx.beginPath(); ctx.arc(x - dir * (30 + k * 14) * esc, y - 4 - k * 2, 2.6 - k * 0.5, 0, Math.PI * 2); ctx.fill(); } }   \/\/ estela y espuma&#10;        const rider = pilotoDe(m), sp = spriteMoto(m, !rider); ctx.save(); ctx.translate(x, y); ctx.scale(dir * esc, esc); ctx.drawImage(sp.c, -sp.ox, -sp.oy); ctx.restore();&#10;        if (rider) {                                                                                             \/\/ la chica a los mandos, con casco&#10;            ctx.save(); ctx.translate(x - dir * 3 * esc, y - 38 * esc); ctx.scale(0.5 * esc, 0.5 * esc); dibujarMu\u00f1eca({ x: 0, y: 0, angulo: Math.sin(performance.now() \/ 110) * 0.05 }, rider.colorPelo, false, dir &lt; 0, false, rider.estilo);&#10;            ctx.fillStyle = '#fff'; ctx.strokeStyle = '#000'; ctx.lineWidth = 3; ctx.beginPath(); ctx.arc(0, -4, 25, Math.PI, 0); ctx.closePath(); ctx.fill(); ctx.stroke(); ctx.fillStyle = m.col; ctx.fillRect(-25, -8, 50, 5); ctx.restore();&#10;        }&#10;    }&#10;    function posCosta(m, now) {                                                                                     \/\/ zig-zag por la zona de ba\u00f1o: 3 idas y vueltas&#10;        const f = faseMoto(m, now); if (f.tipo !== 'costa') return null;&#10;        const k = f.k, x = PIER_X - (PIER_X - 120) * 0.5 * (1 - Math.cos(k * 6 * Math.PI));&#10;        return { x, y: m.lane + 20 * Math.sin(k * 40) + Math.sin(now \/ 300 + m.off * 7) * 1.2, dir: Math.sin(k * 6 * Math.PI) &gt; 0 ? -1 : 1 };&#10;    }&#10;    function dibujarBarco(b, x, y, esc, dir, movido) {&#10;        const sp = b.id === 'yate' ? spriteYate() : spriteSolar();&#10;        if (movido) { ctx.fillStyle = 'rgba(255,255,255,0.3)'; ctx.beginPath(); ctx.ellipse(x - dir * 52 * esc, y + 2, 40 * esc, 4 * esc, 0, 0, Math.PI * 2); ctx.fill(); }   \/\/ estela&#10;        ctx.save(); ctx.translate(x, y); ctx.scale(dir * esc, esc); ctx.drawImage(sp.c, -sp.ox, -sp.oy); ctx.restore();&#10;    }&#10;    function dibujarTrafico() {                                                                                    \/\/ por detr\u00e1s de todo, sobre el mar&#10;        const now = performance.now();&#10;        FLOTA.forEach(b =&gt; { const f = fase(b, now); if (f.tipo !== 'sale' &amp;&amp; f.tipo !== 'vuelve') return; const sale = f.tipo === 'sale', x = sale ? lerp(PIER_X, -150, ease(f.k)) : lerp(-150, PIER_X, ease(f.k));&#10;            dibujarBarco(b, x, b.lane + Math.sin(now \/ 500 + b.off * 9) * 1.8, b.esc, sale ? -1 : 1, true); });&#10;        MOTOS.forEach(m =&gt; { const p = posCosta(m, now); if (p) dibujarMoto(m, p.x, p.y, p.dir, 0.95, true); });                       \/\/ motos de agua de hidr\u00f3geno&#10;    }&#10;    function spritePasarela() {&#10;        return sprites.pasarela || (sprites.pasarela = conLienzo(W, 46, () =&gt; {&#10;            ctx.lineWidth = 1.6; ctx.strokeStyle = '#000'; ctx.fillStyle = 'rgba(0,0,0,0.12)'; ctx.fillRect(0, 26, 856, 4);&#10;            ctx.fillStyle = '#5a3a1c'; for (let x = 20; x &lt; 856; x += 60) ctx.fillRect(x, 18, 5, 12);                                          \/\/ pilotes&#10;            ctx.fillStyle = '#b88a54'; ctx.fillRect(0, 12, 856, 14); ctx.strokeRect(0, 12, 856, 14);                                             \/\/ tablones&#10;            ctx.strokeStyle = 'rgba(70,40,15,0.55)'; ctx.lineWidth = 1; ctx.beginPath(); for (let x = 0; x &lt; 856; x += 14) { ctx.moveTo(x, 12); ctx.lineTo(x, 26); } ctx.moveTo(0, 19); ctx.lineTo(856, 19); ctx.stroke();&#10;            ctx.strokeStyle = '#000'; ctx.lineWidth = 1.4; for (let x = 40; x &lt; 856; x += 96) { ctx.fillStyle = '#4a4f55'; ctx.fillRect(x - 1.5, 0, 3, 13); ctx.fillStyle = '#ffe9a8'; ctx.beginPath(); ctx.arc(x, -1 + 2, 3.4, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); }   \/\/ farolas LED&#10;        }));&#10;    }&#10;    function spriteMuelle() {&#10;        return sprites.muelle || (sprites.muelle = conLienzo(MUELLE.w + 10, MUELLE.h, () =&gt; {&#10;            ctx.lineWidth = 2; ctx.strokeStyle = '#000';&#10;            ctx.fillStyle = '#8d8f94'; ctx.beginPath(); ctx.moveTo(8, 138); ctx.lineTo(16, 106); ctx.lineTo(96, 106); ctx.lineTo(104, 138); ctx.closePath(); ctx.fill(); ctx.stroke();                          \/\/ escollera de piedra&#10;            ctx.strokeStyle = 'rgba(40,40,45,0.5)'; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(12, 122); ctx.lineTo(100, 122); for (let x = 22; x &lt; 96; x += 16) { ctx.moveTo(x, 106); ctx.lineTo(x, 122); ctx.moveTo(x + 8, 122); ctx.lineTo(x + 8, 136); } ctx.stroke();&#10;            ctx.lineWidth = 2; ctx.strokeStyle = '#000'; ctx.fillStyle = '#b88a54'; ctx.beginPath(); ctx.moveTo(30, 106); ctx.lineTo(82, 106); ctx.lineTo(70, 22); ctx.lineTo(42, 22); ctx.closePath(); ctx.fill(); ctx.stroke();          \/\/ cubierta de madera en perspectiva&#10;            ctx.strokeStyle = 'rgba(70,40,15,0.55)'; ctx.lineWidth = 1; ctx.beginPath(); for (let y = 30; y &lt; 106; y += 10) { const k = (y - 22) \/ 84; ctx.moveTo(lerp(42, 30, k), y); ctx.lineTo(lerp(70, 82, k), y); } ctx.stroke();&#10;            ctx.strokeStyle = '#4a4f55'; ctx.lineWidth = 2; [[34, 100, 44, 28], [78, 100, 68, 28]].forEach(([x1, y1, x2, y2]) =&gt; { ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke(); });                                    \/\/ barandillas&#10;            ctx.fillStyle = '#ffe9a8'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.4; [[44, 24], [68, 24], [36, 96], [76, 96]].forEach(([x, y]) =&gt; { ctx.beginPath(); ctx.arc(x, y, 3.6, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); });       \/\/ luces LED&#10;            ctx.fillStyle = '#1f7a68'; ctx.fillRect(22, 0, 68, 18); ctx.strokeRect(22, 0, 68, 18); mTxt('\u2693 PUERTO', 56, 9.5, 10, '#fff', 'center', true);                                                                        \/\/ cartel&#10;        }));&#10;    }&#10;    function dibujarPasarela() { ctx.drawImage(spritePasarela(), 0, 340); ctx.drawImage(spriteMuelle(), MUELLE.x - 4, MUELLE.y); }&#10;    function lucesNochePlaya(t) {                                                                                  \/\/ dentro del pase 'lighter' del modo noche de la playa&#10;        for (let x = 40; x &lt; 856; x += 96) resplandor(x, 341, 16, '255,220,140', 0.5 + 0.15 * Math.sin(t \/ 14 + x));&#10;        [[MUELLE.x + 40, MUELLE.y + 24], [MUELLE.x + 64, MUELLE.y + 24], [MUELLE.x + 32, MUELLE.y + 96], [MUELLE.x + 72, MUELLE.y + 96]].forEach(([x, y]) =&gt; resplandor(x, y, 14, '255,220,140', 0.55));&#10;        Costa.lucesNoche(t, false); const now0 = performance.now(); MOTOS.forEach(m =&gt; { const p = posCosta(m, now0); if (p) resplandor(p.x, p.y - 14, 16, '120,255,200', 0.4); });&#10;        const now = performance.now(); FLOTA.forEach(b =&gt; { const f = fase(b, now); if (f.tipo !== 'sale' &amp;&amp; f.tipo !== 'vuelve') return; const x = f.tipo === 'sale' ? lerp(PIER_X, -150, ease(f.k)) : lerp(-150, PIER_X, ease(f.k)); resplandor(x, b.lane - 20 * b.esc, 22 * b.esc + 8, '255,220,140', 0.5); });&#10;    }&#10;    function tocoMuelle(x, y) { return dentroRect(x, y, MUELLE); }&#10;    function construir() {&#10;        capa = conLienzo(W, H, () =&gt; {&#10;            let g = ctx.createLinearGradient(0, 0, 0, 100); g.addColorStop(0, '#bfe4ff'); g.addColorStop(1, '#e8f7ff'); ctx.fillStyle = g; ctx.fillRect(0, 0, W, 100);&#10;            ctx.fillStyle = '#3aa0d6'; ctx.fillRect(0, 100, W, QUAY - 100);&#10;            ctx.fillStyle = '#ff9f43'; ctx.strokeStyle = '#000'; ctx.lineWidth = 2.5; ctx.fillRect(W \/ 2 - 90, 14, 180, 34); ctx.strokeRect(W \/ 2 - 90, 14, 180, 34); mTxt('\u2693 EL PUERTO \u2693', W \/ 2, 32, 17, '#fff', 'center', true);&#10;            ctx.lineWidth = 2; ctx.strokeStyle = '#000';                                                                                                  \/\/ pontones de atraque&#10;            [335, 605].forEach(x =&gt; { ctx.fillStyle = '#a5703a'; ctx.fillRect(x - 9, 286, 18, 36); ctx.strokeRect(x - 9, 286, 18, 36); ctx.fillStyle = '#2a2f36'; ctx.beginPath(); ctx.arc(x, 292, 3.4, 0, Math.PI * 2); ctx.fill(); });&#10;            ctx.fillStyle = '#b88a54'; ctx.fillRect(0, QUAY, W, 54); ctx.strokeRect(0, QUAY, W, 54);                                                      \/\/ cubierta del muelle (madera)&#10;            ctx.strokeStyle = 'rgba(70,40,15,0.55)'; ctx.lineWidth = 1; ctx.beginPath(); for (let x = 0; x &lt; W; x += 26) { ctx.moveTo(x, QUAY); ctx.lineTo(x, QUAY + 54); } ctx.stroke();&#10;            ctx.fillStyle = '#8d8f94'; ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.fillRect(0, QUAY + 54, W, 34); ctx.strokeRect(0, QUAY + 54, W, 34);   \/\/ muro de piedra&#10;            ctx.strokeStyle = 'rgba(40,40,45,0.5)'; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(0, QUAY + 71); ctx.lineTo(W, QUAY + 71); for (let r = 0; r &lt; 2; r++) for (let x = r ? 18 : 0; x &lt; W; x += 36) { ctx.moveTo(x, QUAY + 54 + r * 17); ctx.lineTo(x, QUAY + 71 + r * 17); } ctx.stroke();&#10;            ctx.fillStyle = '#d9d2c3'; ctx.fillRect(0, QUAY + 88, W, H - QUAY - 88);                                                                     \/\/ explanada de piedra clara&#10;            ctx.strokeStyle = 'rgba(120,110,95,0.4)'; ctx.lineWidth = 1; ctx.beginPath(); for (let y = QUAY + 88; y &lt; H; y += 34) { ctx.moveTo(0, y); ctx.lineTo(W, y); } for (let r = 0; r &lt; 6; r++) for (let x = (r % 2) * 40; x &lt; W; x += 80) { ctx.moveTo(x, QUAY + 88 + r * 34); ctx.lineTo(x, QUAY + 88 + (r + 1) * 34); } ctx.stroke();&#10;            ctx.fillStyle = '#4ea3d9'; ctx.fillRect(0, QUAY + 52, W, 3);                                                                                  \/\/ borde del muelle&#10;            ctx.fillStyle = 'rgba(70,225,255,0.9)'; ctx.fillRect(0, QUAY + 52, W, 2);                                                                     \/\/ tira LED azul&#10;            [80, 300, 540, 780, 910].forEach(x =&gt; { ctx.strokeStyle = '#000'; ctx.lineWidth = 1.6; ctx.fillStyle = '#4a4f55'; ctx.fillRect(x - 2, QUAY - 54, 4, 56); ctx.strokeRect(x - 2, QUAY - 54, 4, 56); ctx.fillStyle = '#ffe9a8'; ctx.beginPath(); ctx.arc(x, QUAY - 58, 6, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); });   \/\/ farolas&#10;            [140, 400, 680].forEach(x =&gt; { ctx.fillStyle = '#2a2f36'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.5; ctx.fillRect(x - 5, QUAY - 6, 10, 10); ctx.strokeRect(x - 5, QUAY - 6, 10, 10); });         \/\/ norays de amarre&#10;            ctx.fillStyle = '#a5703a'; ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.fillRect(SALIDA.x, SALIDA.y, SALIDA.w, SALIDA.h); ctx.strokeRect(SALIDA.x, SALIDA.y, SALIDA.w, SALIDA.h);   \/\/ cartel de vuelta a la playa&#10;            ctx.fillStyle = '#fff'; ctx.fillRect(SALIDA.x + 8, SALIDA.y + 8, SALIDA.w - 16, SALIDA.h - 16); mTxt('\u2190 \ud83c\udfd6\ufe0f PLAYA', SALIDA.x + SALIDA.w \/ 2, SALIDA.y + SALIDA.h \/ 2 + 1, 13, '#20262e', 'center', true);&#10;        });&#10;    }&#10;    function tubo(pts, col, ancho = 6) {                                                                          \/\/ tuber\u00eda con contorno y brillo&#10;        [['#000', ancho + 3], [col, ancho], ['rgba(255,255,255,0.35)', 1.6]].forEach(([c, w], i) =&gt; { ctx.strokeStyle = c; ctx.lineWidth = w; ctx.lineJoin = 'round'; ctx.beginPath(); pts.forEach(([x, y], j) =&gt; j ? ctx.lineTo(x, y - (i === 2 ? 1.5 : 0)) : ctx.moveTo(x, y - (i === 2 ? 1.5 : 0))); ctx.stroke(); });&#10;    }&#10;    function construirPlanta() {&#10;        capaPlanta = conLienzo(W, H, () =&gt; {&#10;            ctx.lineJoin = 'round'; tubo(TUB_AGUA, '#4a90b8'); tubo(TUB_H2, '#9fb7a8'); PUMPS.forEach(p =&gt; tubo([[p.x, 408], [p.x, 366]], '#9fb7a8'));            \/\/ toma de agua de mar y distribuci\u00f3n de H\u2082&#10;            ctx.fillStyle = '#6aa7c9'; ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.fillRect(715, 298, 14, 12); ctx.strokeRect(715, 298, 14, 12); ctx.strokeStyle = 'rgba(0,0,0,0.5)'; ctx.lineWidth = 1; ctx.beginPath(); for (let k = 1; k &lt; 4; k++) { ctx.moveTo(715, 298 + k * 3); ctx.lineTo(729, 298 + k * 3); } ctx.stroke();   \/\/ filtro de la toma&#10;            ctx.lineWidth = 2; ctx.strokeStyle = '#000';&#10;            [762, 806, 850].forEach(x =&gt; { ctx.fillStyle = '#4a4f55'; ctx.fillRect(x + 18, 424, 4, 14); ctx.fillStyle = '#1d3f7a'; ctx.beginPath(); ctx.moveTo(x, 424); ctx.lineTo(x + 40, 424); ctx.lineTo(x + 36, 412); ctx.lineTo(x - 4, 412); ctx.closePath(); ctx.fill(); ctx.stroke(); rejilla(x - 4, 412, 44, 12, 5, 2); });   \/\/ paneles solares&#10;            ctx.fillStyle = '#e9edf0'; ctx.fillRect(762, 442, 100, 70); ctx.strokeRect(762, 442, 100, 70); ctx.fillStyle = '#2fa36b'; ctx.fillRect(762, 442, 100, 10); ctx.strokeRect(762, 442, 100, 10);   \/\/ m\u00f3dulo de electr\u00f3lisis&#10;            mTxt('H\u2082 VERDE', 812, 447.5, 8, '#fff', 'center', true); mTxt('\ud83c\udf3f', 850, 447, 9, '#000', 'center');&#10;            ctx.fillStyle = '#10243f'; ctx.fillRect(772, 460, 40, 42); ctx.strokeRect(772, 460, 40, 42); ctx.fillStyle = 'rgba(80,170,230,0.55)'; ctx.fillRect(773, 470, 38, 31); ctx.fillStyle = 'rgba(255,255,255,0.18)'; ctx.fillRect(775, 461, 5, 40);          \/\/ ventana de las celdas&#10;            ctx.fillStyle = '#c9d2d8'; [778, 794].forEach(x =&gt; { ctx.fillRect(x, 478, 4, 22); ctx.strokeRect(x, 478, 4, 22); });                                                                             \/\/ pilas de electr\u00f3lisis&#10;            ctx.fillStyle = '#d9dee2'; ctx.fillRect(820, 458, 36, 48); ctx.strokeRect(820, 458, 36, 48); ctx.beginPath(); ctx.arc(838, 482, 10, 0, Math.PI * 2); ctx.fillStyle = '#9aa4ab'; ctx.fill(); ctx.stroke();    \/\/ compresor&#10;            [[872, 442], [872, 478]].forEach(([x, y]) =&gt; { ctx.fillStyle = '#f2f5f6'; ctx.beginPath(); ctx.roundRect ? ctx.roundRect(x, y, 76, 28, 13) : ctx.rect(x, y, 76, 28); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#2fa36b'; ctx.fillRect(x + 28, y + 1, 20, 26); ctx.strokeRect(x + 28, y + 1, 20, 26); mTxt('H\u2082', x + 38, y + 14.5, 9, '#fff', 'center', true); ctx.fillStyle = '#10243f'; ctx.fillRect(x + 8, y + 6, 10, 16); ctx.strokeRect(x + 8, y + 6, 10, 16); });   \/\/ dep\u00f3sitos&#10;            tubo([[862, 470], [872, 470]], '#9fb7a8', 4); tubo([[862, 492], [872, 492]], '#9fb7a8', 4);&#10;            PUMPS.forEach(p =&gt; {                                                                                                                                                                              \/\/ surtidores limpios&#10;                ctx.fillStyle = '#4a4f55'; ctx.fillRect(p.x - 15, 362, 30, 6); ctx.strokeRect(p.x - 15, 362, 30, 6);&#10;                ctx.fillStyle = '#eef2f4'; ctx.fillRect(p.x - 11, 326, 22, 38); ctx.strokeRect(p.x - 11, 326, 22, 38); ctx.fillStyle = '#2fa36b'; ctx.fillRect(p.x - 11, 326, 22, 8); ctx.strokeRect(p.x - 11, 326, 22, 8);&#10;                ctx.fillStyle = '#10243f'; ctx.fillRect(p.x - 8, 338, 16, 11); ctx.strokeRect(p.x - 8, 338, 16, 11); mTxt('H\u2082', p.x, 331, 7, '#fff', 'center', true);&#10;                ctx.fillStyle = '#20262e'; ctx.fillRect(p.x + 11, 340, 5, 12); ctx.strokeRect(p.x + 11, 340, 5, 12);                                                                                       \/\/ soporte de la manguera&#10;            });&#10;        });&#10;    }&#10;    function manguera(x1, y1, x2, y2, t) {&#10;        ctx.save(); ctx.lineCap = 'round'; ctx.strokeStyle = '#000'; ctx.lineWidth = 4.2; ctx.beginPath(); ctx.moveTo(x1, y1); ctx.quadraticCurveTo((x1 + x2) \/ 2, Math.max(y1, y2) + 16, x2, y2); ctx.stroke();&#10;        ctx.strokeStyle = '#3fb37f'; ctx.lineWidth = 2; ctx.setLineDash([5, 7]); ctx.lineDashOffset = -t * 0.8; ctx.stroke(); ctx.restore();&#10;    }&#10;    function flujo(pts, col, t) { ctx.save(); ctx.strokeStyle = col; ctx.lineWidth = 2; ctx.lineCap = 'round'; ctx.setLineDash([3, 10]); ctx.lineDashOffset = -t * 0.9; ctx.beginPath(); pts.forEach(([x, y], j) =&gt; j ? ctx.lineTo(x, y) : ctx.moveTo(x, y)); ctx.stroke(); ctx.restore(); }&#10;    function dibujarPlanta(t, now, noche) {                                                                         \/\/ capa fija + partes que se mueven&#10;        if (!capaPlanta) construirPlanta(); ctx.drawImage(capaPlanta, 0, 0);&#10;        const lleno = H2.nivel \/ 100;&#10;        if (produciendo) { flujo(TUB_AGUA, 'rgba(210,240,255,0.95)', t); flujo([[862, 470], [872, 470]], 'rgba(220,255,235,0.9)', t); }&#10;        if (H2.nivel &gt; 8) flujo(TUB_H2, 'rgba(230,255,240,0.9)', t);&#10;        ctx.fillStyle = 'rgba(235,250,255,0.85)'; if (produciendo) for (let i = 0; i &lt; 6; i++) { const f = ((t \/ 38) + i \/ 6) % 1; ctx.beginPath(); ctx.arc(780 + (i % 3) * 14 + Math.sin(t \/ 9 + i * 2) * 2, 500 - f * 30, 1.8 + (i % 2), 0, Math.PI * 2); ctx.fill(); }   \/\/ burbujas de la electr\u00f3lisis&#10;        ctx.save(); ctx.translate(838, 482); ctx.rotate(produciendo ? t \/ 6 : 0); ctx.strokeStyle = '#4a4f55'; ctx.lineWidth = 2; ctx.beginPath(); for (let k = 0; k &lt; 3; k++) { ctx.moveTo(0, 0); ctx.lineTo(Math.cos(k * 2.094) * 8, Math.sin(k * 2.094) * 8); } ctx.stroke(); ctx.restore();   \/\/ compresor girando&#10;        [[872, 442], [872, 478]].forEach(([x, y]) =&gt; { ctx.fillStyle = '#6cd6a0'; ctx.fillRect(x + 9, y + 21 - 14 * lleno, 8, 14 * lleno); });                                                                       \/\/ nivel de H\u2082 en los dep\u00f3sitos&#10;        ctx.fillStyle = produciendo ? '#3ddc84' : '#e0b84a'; ctx.beginPath(); ctx.arc(826, 465, 2.4, 0, Math.PI * 2); ctx.fill();                                                                         \/\/ piloto de la planta&#10;        PUMPS.forEach(p =&gt; { ctx.fillStyle = H2.nivel &gt;= 3 ? '#3ddc84' : '#ef4444'; ctx.beginPath(); ctx.arc(p.x, 343.5, 2.6, 0, Math.PI * 2); ctx.fill(); });                                                     \/\/ pilotos de los surtidores&#10;        const f0 = faseMoto(MOTOS[0], now), f1 = faseMoto(MOTOS[1], now), fy = fase(FLOTA[0], now), reposta = (f, u0, u1) =&gt; f.tipo === 'amarrado' &amp;&amp; f.u &gt;= u0 &amp;&amp; f.u &lt; u1;&#10;        const conn = [reposta(fy, 0.12, 0.2), reposta(f0, 0.1, 0.22), reposta(f1, 0.1, 0.22)], dest = [[546, 292], [684, 294], [808, 294]];&#10;        PUMPS.forEach((p, i) =&gt; conn[i] ? manguera(p.x + 14, 346, dest[i][0], dest[i][1], t) : manguera(p.x + 14, 346, p.x + 18, 354, t * 0));&#10;    }&#10;    function spriteBuceo() {&#10;        return sprites.buceo || (sprites.buceo = conLienzo(176, 128, () =&gt; {&#10;            const cx = 88, b = 120; ctx.lineWidth = 2; ctx.strokeStyle = '#000'; ctx.lineJoin = 'round'; sombra(cx, b + 2, 80, 8, 0.25);&#10;            ctx.fillStyle = '#4a4f55'; [-76, -56].forEach(dx =&gt; { ctx.fillRect(cx + dx - 2, b - 62, 4, 62); ctx.strokeRect(cx + dx - 2, b - 62, 4, 62); }); ctx.fillRect(cx - 80, b - 58, 28, 4);                                    \/\/ perchero de ropa l\u00edquida&#10;            [['#2fd6c0', -74], ['#ff6fa8', -66], ['#ffd54a', -58]].forEach(([c, dx]) =&gt; { ctx.fillStyle = c; ctx.lineWidth = 1.3; ctx.fillRect(cx + dx - 3.5, b - 55, 7, 14); ctx.strokeRect(cx + dx - 3.5, b - 55, 7, 14); ctx.fillRect(cx + dx - 3.5, b - 41, 3, 17); ctx.strokeRect(cx + dx - 3.5, b - 41, 3, 17); ctx.fillRect(cx + dx + 0.5, b - 41, 3, 17); ctx.strokeRect(cx + dx + 0.5, b - 41, 3, 17); ctx.strokeStyle = 'rgba(255,255,255,0.85)'; ctx.beginPath(); ctx.moveTo(cx + dx - 1.5, b - 53); ctx.lineTo(cx + dx - 1.5, b - 44); ctx.stroke(); ctx.strokeStyle = '#000'; });&#10;            ctx.lineWidth = 2; ctx.fillStyle = '#2a9d8f'; ctx.fillRect(cx - 50, b - 70, 100, 70); ctx.strokeRect(cx - 50, b - 70, 100, 70); ctx.strokeStyle = 'rgba(0,60,55,0.5)'; ctx.lineWidth = 1; ctx.beginPath(); for (let y = b - 64; y &lt; b; y += 7) { ctx.moveTo(cx - 50, y); ctx.lineTo(cx + 50, y); } ctx.stroke();       \/\/ cabina de contenedor&#10;            ctx.fillStyle = '#10243f'; ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.fillRect(cx - 36, b - 54, 50, 26); ctx.strokeRect(cx - 36, b - 54, 50, 26); ctx.fillStyle = 'rgba(120,220,255,0.28)'; ctx.fillRect(cx - 34, b - 52, 14, 22);                          \/\/ ventanilla de servicio&#10;            ctx.fillStyle = '#b88a54'; ctx.fillRect(cx - 38, b - 28, 54, 5); ctx.strokeRect(cx - 38, b - 28, 54, 5);&#10;            ctx.fillStyle = '#1d3f7a'; ctx.beginPath(); ctx.moveTo(cx - 56, b - 72); ctx.lineTo(cx + 56, b - 72); ctx.lineTo(cx + 46, b - 90); ctx.lineTo(cx - 46, b - 90); ctx.closePath(); ctx.fill(); ctx.stroke(); rejilla(cx - 50, b - 90, 100, 18, 9, 2);              \/\/ tejado con paneles solares&#10;            ctx.strokeStyle = 'rgba(70,225,255,0.95)'; ctx.lineWidth = 2.2; ctx.beginPath(); ctx.moveTo(cx - 56, b - 72); ctx.lineTo(cx + 56, b - 72); ctx.stroke();                                                                                                         \/\/ ne\u00f3n&#10;            ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.fillStyle = '#16456b'; ctx.fillRect(cx - 52, b - 114, 104, 20); ctx.strokeRect(cx - 52, b - 114, 104, 20); mTxt('BUCEO ECOL\u00d3GICO', cx + 9, b - 104, 7.4, '#fff', 'center', true); mTxt('\ud83e\udd3f', cx - 44, b - 104, 11, '#000', 'center');&#10;            ctx.beginPath(); ctx.moveTo(cx - 36, b - 94); ctx.lineTo(cx - 36, b - 90); ctx.moveTo(cx + 36, b - 94); ctx.lineTo(cx + 36, b - 90); ctx.stroke();&#10;            ctx.fillStyle = '#cfd6dc'; ctx.fillRect(cx + 56, b - 52, 8, 52); [0, 1, 2].forEach(i =&gt; { ctx.fillStyle = '#e9edf0'; ctx.beginPath(); ctx.roundRect ? ctx.roundRect(cx + 56 + i * 9, b - 52, 8, 52, 4) : ctx.rect(cx + 56 + i * 9, b - 52, 8, 52); ctx.fill(); ctx.stroke(); ctx.fillStyle = ['#2fd6c0', '#ff6fa8', '#ffd54a'][i]; ctx.fillRect(cx + 56 + i * 9, b - 52, 8, 7); ctx.strokeRect(cx + 56 + i * 9, b - 52, 8, 7); });   \/\/ botellas&#10;            ctx.fillStyle = '#d9dee2'; ctx.fillRect(cx + 20, b - 22, 34, 22); ctx.strokeRect(cx + 20, b - 22, 34, 22); ctx.fillStyle = '#10243f'; ctx.fillRect(cx + 23, b - 19, 8, 6); ctx.strokeRect(cx + 23, b - 19, 8, 6);                                                       \/\/ compresor&#10;            ctx.strokeStyle = '#2a2f36'; ctx.lineWidth = 2.4; ctx.beginPath(); ctx.moveTo(cx + 54, b - 12); ctx.quadraticCurveTo(cx + 60, b - 4, cx + 66, b - 2); ctx.stroke();&#10;        }));&#10;    }&#10;    function dibujarBuceo(t, now, noche) {&#10;        const x = BUC.x - 88, y = BUC.y - 120; ctx.drawImage(spriteBuceo(), x, y);&#10;        const f = AIRE.n \/ 100; [0, 1, 2].forEach(i =&gt; { ctx.fillStyle = '#10243f'; ctx.fillRect(x + 88 + 62 + i * 9 - 1.5, y + 120 - 38, 3, 20); ctx.fillStyle = '#6cd6a0'; ctx.fillRect(x + 88 + 62 + i * 9 - 1.5, y + 120 - 18 - 20 * f, 3, 20 * f); });                 \/\/ nivel de aire de las botellas&#10;        const vx = x + 88 + 20 + 17, vy = y + 120 - 14 + (llenando ? Math.sin(t \/ 2) * 0.6 : 0); ctx.save(); ctx.translate(vx, vy); ctx.rotate(llenando ? t \/ 5 : 0); ctx.strokeStyle = '#4a4f55'; ctx.lineWidth = 2; ctx.beginPath(); for (let k = 0; k &lt; 3; k++) { ctx.moveTo(0, 0); ctx.lineTo(Math.cos(k * 2.094) * 7, Math.sin(k * 2.094) * 7); } ctx.stroke(); ctx.restore();   \/\/ ventilador del compresor&#10;        ctx.fillStyle = llenando ? '#3ddc84' : '#e0b84a'; ctx.beginPath(); ctx.arc(x + 88 + 27, y + 120 - 16, 2, 0, Math.PI * 2); ctx.fill();                                                                                                                      \/\/ piloto&#10;        const g = ((t * 0.7) % 120) \/ 120; if (g &lt; 0.35) { ctx.fillStyle = `rgba(255,255,255,${0.5 * Math.sin(g \/ 0.35 * Math.PI)})`; ctx.fillRect(x + 88 - 50 + g \/ 0.35 * 100, y + 120 - 90, 6, 18); }                                                                   \/\/ destello en los paneles solares&#10;        ctx.save(); ctx.strokeStyle = '#000'; ctx.lineWidth = 3.4; ctx.beginPath(); ctx.moveTo(323, 286); ctx.lineTo(323, 314); ctx.moveTo(329, 286); ctx.lineTo(329, 314); ctx.stroke(); ctx.strokeStyle = '#cfd6dc'; ctx.lineWidth = 1.8; ctx.stroke();&#10;        ctx.lineWidth = 1.6; [292, 298, 304, 310].forEach(yy =&gt; { ctx.strokeStyle = '#000'; ctx.beginPath(); ctx.moveTo(322, yy); ctx.lineTo(330, yy); ctx.stroke(); });&#10;        ctx.fillStyle = '#ff6fa8'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.3; ctx.beginPath(); ctx.ellipse(338, 290, 5, 2.4, -0.3, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.beginPath(); ctx.ellipse(345, 292, 5, 2.4, 0.2, 0, Math.PI * 2); ctx.fill(); ctx.stroke();        \/\/ aletas&#10;        const bob = Math.sin(now \/ 520) * 1.6, bx = 380, by = 304 + bob; ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(bx, by); ctx.lineTo(bx, by - 24); ctx.stroke(); ctx.fillStyle = '#e53935'; ctx.beginPath(); ctx.moveTo(bx, by - 24); ctx.lineTo(bx + 16, by - 20 + Math.sin(t \/ 12) * 1.4); ctx.lineTo(bx, by - 13); ctx.closePath(); ctx.fill(); ctx.stroke();&#10;        ctx.strokeStyle = '#fff'; ctx.lineWidth = 2.2; ctx.beginPath(); ctx.moveTo(bx + 1, by - 22.5); ctx.lineTo(bx + 14, by - 18.8 + Math.sin(t \/ 12) * 1.2); ctx.stroke(); ctx.fillStyle = '#ff9f43'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.8; ctx.beginPath(); ctx.arc(bx, by + 2, 5, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.restore();&#10;        if (noche) { resplandor(BUC.x, BUC.y - 100, 34, '70,225,255', 0.4); resplandor(BUC.x - 20, BUC.y - 50, 26, '120,220,255', 0.22); }&#10;    }&#10;    function dibujar(t) {&#10;        if (!capa) construir(); const now = performance.now(), noche = nochePlaya || !esDeDia();&#10;        ctx.drawImage(capa, 0, 0);&#10;        if (!noche) dibujarSol(860, 56, t);&#10;        ctx.strokeStyle = 'rgba(255,255,255,0.6)'; ctx.lineWidth = 2.4;                                                                                \/\/ olas&#10;        for (let f = 0; f &lt; 4; f++) { ctx.beginPath(); for (let px = 0; px &lt;= W; px += 24) { const py = 130 + f * 46 + Math.sin(px \/ 40 + t \/ 15 + f) * 6; px ? ctx.lineTo(px, py) : ctx.moveTo(px, py); } ctx.stroke(); }&#10;        FLOTA.forEach(b =&gt; {                                                                                                                             \/\/ embarcaciones en su atraque (o entrando y saliendo)&#10;            const f = fase(b, now); let x = null, dir = 1;&#10;            if (f.tipo === 'amarrado') x = b.berth;&#10;            else if (f.tipo === 'sale' &amp;&amp; f.k &lt; 0.1) x = lerp(b.berth, 1120, ease(f.k \/ 0.1));&#10;            else if (f.tipo === 'vuelve' &amp;&amp; f.k &gt; 0.9) { x = lerp(1120, b.berth, ease((f.k - 0.9) \/ 0.1)); dir = f.k &gt; 0.97 ? 1 : -1; }&#10;            if (x !== null) dibujarBarco(b, x, 301 + Math.sin(now \/ 600 + b.off * 9) * 1.6, b.id === 'yate' ? 1 : 1.15, dir, x !== b.berth);&#10;        });&#10;        MOTOS.forEach(m =&gt; {                                                                                                                            \/\/ motos en su atraque (o entrando y saliendo)&#10;            const f = faseMoto(m, now); let x = null, dir = 1;&#10;            if (f.tipo === 'amarrado') x = m.slip; else if (f.tipo === 'sale') x = lerp(m.slip, 1120, ease(f.k)); else if (f.tipo === 'vuelve') { x = lerp(1120, m.slip, ease(f.k)); dir = f.k &gt; 0.9 ? 1 : -1; }&#10;            if (x !== null) dibujarMoto(m, x, 302 + Math.sin(now \/ 420 + m.off * 9) * 1.4, dir, 1, f.tipo !== 'amarrado');&#10;        });&#10;        dibujarPlanta(t, now, noche);&#10;        dibujarBuceo(t, now, noche);&#10;        Costa.dibujarPuerto(t);                                                                                                                     \/\/ Genoide de mantenimiento y brazo que limpia los paneles&#10;        Costa.decorarCosta(t, 'puerto');                                                                                                           \/\/ fiestas del calendario&#10;        ctx.strokeStyle = 'rgba(255,255,255,0.9)'; ctx.lineWidth = 1.6;                                                                                  \/\/ gaviotas&#10;        for (let i = 0; i &lt; 3; i++) { const gx = ((t * (0.5 + i * 0.15) + i * 330) % 1100) - 70, gy = 62 + i * 14 + Math.sin(t \/ 30 + i) * 6, fl = Math.sin(t \/ 8 + i) * 3; ctx.beginPath(); ctx.moveTo(gx - 7, gy); ctx.quadraticCurveTo(gx - 3, gy - 4 + fl, gx, gy); ctx.quadraticCurveTo(gx + 3, gy - 4 + fl, gx + 7, gy); ctx.stroke(); }&#10;        if (now &lt; temporalHasta) {                                                                                                                     \/\/ temporal: cielo gris y lluvia&#10;            ctx.save(); ctx.fillStyle = 'rgba(40,52,76,0.28)'; ctx.fillRect(0, 0, W, H); ctx.strokeStyle = 'rgba(190,210,235,0.55)'; ctx.lineWidth = 1.2; ctx.beginPath(); for (let i = 0; i &lt; 70; i++) { const x = (i * 97 + t * 3) % W, y = (i * 61 + t * 9) % H; ctx.moveTo(x, y); ctx.lineTo(x - 4, y + 12); } ctx.stroke(); ctx.restore();&#10;        }&#10;        if (noche) {&#10;            ctx.save(); ctx.fillStyle = 'rgba(10,16,52,0.55)'; ctx.fillRect(0, 0, W, H); ctx.fillStyle = '#fff'; for (let i = 0; i &lt; 36; i++) { ctx.globalAlpha = 0.4 + 0.6 * Math.abs(Math.sin(t \/ 30 + i)); ctx.fillRect((i * 97) % 940 + 10, (i * 53) % 84 + 4, 2, 2); } ctx.globalAlpha = 1;&#10;            ctx.fillStyle = '#fff6cf'; ctx.beginPath(); ctx.arc(860, 56, 16, 0, Math.PI * 2); ctx.fill(); ctx.fillStyle = 'rgba(10,16,52,0.35)'; ctx.beginPath(); ctx.arc(867, 52, 13, 0, Math.PI * 2); ctx.fill();&#10;            ctx.globalCompositeOperation = 'lighter'; [80, 300, 540, 780, 910].forEach(x =&gt; resplandor(x, QUAY - 58, 40, '255,220,140', 0.55));&#10;            for (let x = 30; x &lt; W; x += 60) resplandor(x, QUAY + 53, 18, '70,225,255', 0.45 + 0.2 * Math.sin(t \/ 16 + x));&#10;            FLOTA.forEach(b =&gt; { const f = fase(b, now); if (f.tipo === 'amarrado') resplandor(b.berth, 301 - (b.id === 'yate' ? 38 : 26), 34, '255,220,140', 0.45); });&#10;            resplandor(792, 482, 44, '120,210,255', produciendo ? 0.55 : 0.25); PUMPS.forEach(p =&gt; resplandor(p.x, 343, 22, H2.nivel &gt;= 3 ? '90,255,160' : '255,90,90', 0.5)); [[910, 456], [910, 492]].forEach(([x, y]) =&gt; resplandor(x, y, 22, '90,255,160', 0.2 + 0.3 * H2.nivel \/ 100));&#10;            MOTOS.forEach(m =&gt; { const f = faseMoto(m, now); if (f.tipo === 'amarrado') resplandor(m.slip, 288, 20, '120,255,200', 0.35); });&#10;            Costa.lucesNoche(t, true);&#10;            ctx.restore();&#10;        }&#10;        { const FF = fiestaActual(); if (FF &amp;&amp; FF.id === 'astenagusia') { Fiestas2.fuegos(t, 8, 100); Fiestas2.dibujarRitualPuerto(t); } }          \/\/ fuegos artificiales sobre el puerto y la despedida de Marijaia&#10;    }&#10;    function toque(x, y) {&#10;        if (dentroRect(x, y, SALIDA)) { iniciarTransicion(() =&gt; { enPuerto = false; enPlaya = true; }); return; }&#10;        if (dentroRect(x, y, { x: BUC.x - 90, y: BUC.y - 122, w: 180, h: 124 })) iniciarTransicion(() =&gt; { enPuerto = false; enSubmarino = true; });          \/\/ \ud83e\udd3f al fondo marino&#10;    }&#10;    return { dibujar, actualizar() {}, tick, temporal, H2, AIRE, FONDO, buceoDisponible, empezarBuceo, finBuceo, buzos, motoDisponible, arrancarMoto, toque, tocoMuelle, dibujarTrafico, dibujarPasarela, lucesNochePlaya };&#10;})();&#10;const Costa = (() =&gt; {&#10;    const CAP = 12, QUAY_Y = 318, MUELLE_X = 884, cesta = { algas: 0 }, litter = [], clumps = [], reciclado = { n: 0 };&#10;    const ease = k =&gt; k * k * (3 - 2 * k), lerp = (a, b, k) =&gt; a + (b - a) * k;&#10;    const BR = {&#10;        A: { id: 'A', x: 150, y: 446, dest: { x: 192, y: 448 }, mano: { x: 124, y: 462 }, estado: 'reposo', f: 0, item: null, tipo: 'basura' },&#10;        B: { id: 'B', x: 250, y: 398, dest: { x: 286, y: 402 }, mano: { x: 224, y: 412 }, estado: 'reposo', f: 0, item: null, tipo: 'alga' },&#10;        C: { x: 738, y: 442, estado: 'limpia', f: 0 }&#10;    };&#10;    const G = [{ id: 'g1', x: 120, y: 470, tarea: 'busca', t: 0, dir: 1, estilo: 'pincho', fase: 0.4, trab: false, ic: '', espera: 1, arm: 'A', llevando: null, obj: null },&#10;               { id: 'g2', x: 300, y: 380, tarea: 'busca', t: 0, dir: 1, estilo: 'mohawk', fase: 1.7, trab: false, ic: '', espera: 1, arm: 'B', llevando: null, obj: null }];&#10;    const GP = { x: 600, y: 440, tarea: 'va', t: 0, dir: 1, estilo: 'pincho', fase: 2.6, trab: false, ic: '', espera: 1, i: 0 };&#10;    const RUTA_PUERTO = [{ x: 540, y: 428, mira: [540, 346] }, { x: 640, y: 428, mira: [640, 346] }, { x: 850, y: 428, mira: [850, 346] }, { x: 812, y: 526, mira: [812, 490] }, { x: 912, y: 524, mira: [910, 470] }, { x: 700, y: 466, mira: [722, 400] }, { x: 300, y: 508, mira: [330, 470] }];&#10;    const PUNTOS_FAROLA = []; for (let x = 40; x &lt; 856; x += 96) PUNTOS_FAROLA.push(x);&#10;    const puesto = { stock: 0, ventas: 0, flash: 0 }, STOCK_MAX = 8, envios = [], PX = 690, PB = 500, CESTA = { x: 286, y: 392 };&#10;    let ultL = 0, ultA = 0, ultOff = 0, ultEnvio = 0, ultVenta = 0, rutaN = 0, sprites = {}, mareaHasta = 0;&#10;    const NOMBRES_BRAZO = { A: 'la playa (residuos)', B: 'la playa (algas)', C: 'el puerto (paneles solares)' };&#10;    function marea(ms) { mareaHasta = performance.now() + ms; }&#10;    function averiar(ms) { const id = ['A', 'B', 'C'][Math.floor(Math.random() * 3)]; BR[id].rota = performance.now() + ms; return { id, donde: NOMBRES_BRAZO[id] }; }&#10;    const rota = a =&gt; !!a.rota &amp;&amp; performance.now() &lt; a.rota;&#10;    function humoBrazo(a, t) { if (!rota(a)) return; ctx.save(); for (let k = 0; k &lt; 3; k++) { const f = ((t \/ 60) + k \/ 3) % 1; ctx.globalAlpha = 0.5 * (1 - f); ctx.fillStyle = '#7a7f86'; ctx.beginPath(); ctx.arc(a.x + 8 + Math.sin(t \/ 10 + k) * 4, a.y - 60 - f * 26, 4 + f * 5, 0, Math.PI * 2); ctx.fill(); } ctx.globalAlpha = 0.5 + 0.5 * Math.sin(t \/ 4); ctx.fillStyle = '#ffd54a'; ctx.beginPath(); ctx.arc(a.x + 6, a.y - 52, 2, 0, Math.PI * 2); ctx.fill(); ctx.restore(); }&#10;    ZONAS_PLAYA.push(...[{ x: PX - 78, y: 492 }, { x: PX + 78, y: 492 }].map(z =&gt; ({ ...z, accion: 'comprando', icono: '\ud83c\udf75', dur: 9000, auto: true })));      \/\/ las chicas compran t\u00e9 y algas en el puesto&#10;    function libreArena(x, y) {&#10;        const en = (r) =&gt; x &gt; r[0] &amp;&amp; x &lt; r[0] + r[2] &amp;&amp; y &gt; r[1] &amp;&amp; y &lt; r[1] + r[3];&#10;        return !(en([364, 462, 214, 70]) || en([790, 340, 170, 125]) || en([690, 350, 90, 100]) || en([100, 410, 150, 80]) || en([580, 424, 200, 100]) || en([230, 380, 80, 50]) || Math.hypot(x - 350, y - 400) &lt; 44 || Math.hypot(x - 610, y - 400) &lt; 44);&#10;    }&#10;    function vender() { if (puesto.stock &lt;= 0) return false; puesto.stock--; puesto.ventas++; saldoMIIG26D += 2; Kutxa.aportar(0.16); puesto.flash = performance.now(); return true; }&#10;    function tick(now) {&#10;        if (!ultL) { ultL = ultA = ultOff = ultEnvio = ultVenta = now; }&#10;        if (cesta.algas &gt;= CAP) Noticias.publicar('\ud83e\uddfa La cesta de algas est\u00e1 llena: los drones reparten lo que pueden', 'cesta', 300000);&#10;        if (litter.length &lt; 5 &amp;&amp; now - ultL &gt; 14000 * (0.65 + 0.7 * Puerto.FONDO.s \/ 100)) { ultL = now; for (let i = 0; i &lt; 14; i++) { const x = 60 + Math.random() * 840, y = 396 + Math.random() * 120; if (libreArena(x, y)) { litter.push({ x, y, k: Math.floor(Math.random() * 3), res: null }); break; } } }&#10;        if (clumps.length &lt; (now &lt; mareaHasta ? 9 : 5) &amp;&amp; now - ultA &gt; (now &lt; mareaHasta ? 3000 : 10000 * (1.35 - 0.7 * Puerto.FONDO.s \/ 100))) { ultA = now; clumps.push({ x: 110 + Math.random() * 640, y: 338 + Math.random() * 10, ph: Math.random() * 6, res: null }); }&#10;        if (now - ultEnvio &gt; 8000 &amp;&amp; cesta.algas &gt; 0 &amp;&amp; envios.length &lt; 3) {                                          \/\/ reparto: 3 de cada 5 algas van a la Zona Industrial; el resto, al puesto&#10;            ultEnvio = now; cesta.algas--; let ruta = ['industria', 'industria', 'puesto', 'industria', 'puesto'][rutaN++ % 5]; if (ruta === 'puesto' &amp;&amp; puesto.stock &gt;= STOCK_MAX) ruta = 'industria'; envios.push({ ruta, t0: now, dur: 4200 });&#10;        }&#10;        for (let i = envios.length - 1; i &gt;= 0; i--) { const e = envios[i]; if (now - e.t0 &gt;= e.dur) { envios.splice(i, 1); if (e.ruta === 'industria') recursos.resina = Math.min(100, recursos.resina + 6); else puesto.stock = Math.min(STOCK_MAX, puesto.stock + 1); } }&#10;        if (now - ultVenta &gt; 45000) { ultVenta = now; if (puesto.stock &gt; 2) vender(); }                              \/\/ la gente del pueblo tambi\u00e9n compra&#10;        if (!enPlaya &amp;&amp; now - ultOff &gt; 22000) {                                                                      \/\/ con la playa cerrada, el trabajo sigue por reloj&#10;            ultOff = now; if (clumps.length &amp;&amp; cesta.algas &lt; CAP) { clumps.shift(); cesta.algas++; } else if (litter.length) { litter.shift(); reciclado.n++; }&#10;        }&#10;    }&#10;    function brazo(a, tx, ty, abierta, t) {&#10;        const L1 = 36, L2 = 32, sx = a.x, sy = a.y - 18; let dx = tx - sx, dy = ty - sy, d = Math.hypot(dx, dy); d = Math.max(Math.abs(L1 - L2) + 2, Math.min(L1 + L2 - 1, d));&#10;        const ang = Math.atan2(dy, dx), da = Math.acos(Math.max(-1, Math.min(1, (L1 * L1 + d * d - L2 * L2) \/ (2 * L1 * d)))), e1 = { x: sx + L1 * Math.cos(ang - da), y: sy + L1 * Math.sin(ang - da) }, e2 = { x: sx + L1 * Math.cos(ang + da), y: sy + L1 * Math.sin(ang + da) };&#10;        const e = e1.y &lt; e2.y ? e1 : e2, hx = sx + d * Math.cos(ang), hy = sy + d * Math.sin(ang), aa = Math.atan2(hy - e.y, hx - e.x);&#10;        ctx.save(); ctx.lineCap = 'round';&#10;        ctx.fillStyle = '#e9edf0'; ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.fillRect(a.x - 9, a.y - 16, 18, 16); ctx.strokeRect(a.x - 9, a.y - 16, 18, 16); ctx.fillStyle = '#ff9f43'; ctx.fillRect(a.x - 9, a.y - 10, 18, 3);     \/\/ pedestal&#10;        [[sx, sy, e.x, e.y], [e.x, e.y, hx, hy]].forEach(([x1, y1, x2, y2], i) =&gt; { ctx.strokeStyle = '#000'; ctx.lineWidth = 9; ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke(); ctx.strokeStyle = '#f4f6f7'; ctx.lineWidth = 6; ctx.stroke(); ctx.strokeStyle = '#ff9f43'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(lerp(x1, x2, 0.3), lerp(y1, y2, 0.3)); ctx.lineTo(lerp(x1, x2, 0.7), lerp(y1, y2, 0.7)); ctx.stroke(); });&#10;        ctx.fillStyle = '#4a4f55'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.6; [[sx, sy], [e.x, e.y]].forEach(([x, y]) =&gt; { ctx.beginPath(); ctx.arc(x, y, 4.6, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); });&#10;        const ab = abierta ? 0.7 : 0.15; ctx.strokeStyle = '#20262e'; ctx.lineWidth = 2.4; [-1, 1].forEach(s =&gt; { ctx.beginPath(); ctx.moveTo(hx, hy); ctx.lineTo(hx + 8 * Math.cos(aa + s * ab), hy + 8 * Math.sin(aa + s * ab)); ctx.stroke(); });      \/\/ pinza&#10;        ctx.fillStyle = `rgba(255,70,70,${0.6 + 0.4 * Math.sin(t \/ 8 + a.x)})`; ctx.beginPath(); ctx.arc(e.x, e.y - 6, 1.8, 0, Math.PI * 2); ctx.fill(); ctx.restore();&#10;        return { x: hx, y: hy };&#10;    }&#10;    const manoDe = g =&gt; ({ x: g.x + g.dir * 12, y: g.y - 52 });&#10;    function actualizarBrazoMano(a, gs) {                                                                          \/\/ recibe lo que le entrega una Genoide y lo lleva a su destino&#10;        if (rota(a)) return; const rest = { x: a.x + 10, y: a.y - 56 }, tope = { x: a.dest.x, y: a.dest.y - 22 }; a.f++;&#10;        const g = gs.find(o =&gt; o.arm === a.id &amp;&amp; o.tarea === 'entrega');&#10;        if (a.estado === 'reposo') { a.pos = rest; if (g &amp;&amp; g.llevando &amp;&amp; Math.hypot(g.x - a.mano.x, g.y - a.mano.y) &lt; 6) { a.estado = 'alcanza'; a.f = 0; } }&#10;        else if (a.estado === 'alcanza') { const m = g ? manoDe(g) : rest; a.pos = { x: lerp(rest.x, m.x, ease(Math.min(1, a.f \/ 30))), y: lerp(rest.y, m.y, ease(Math.min(1, a.f \/ 30))) }; if (a.f &gt;= 30) { a.estado = 'agarra'; a.f = 0; } }&#10;        else if (a.estado === 'agarra') { const m = g ? manoDe(g) : rest; a.pos = m; if (a.f &gt;= 14) { a.item = g ? g.llevando : a.tipo; if (g) g.llevando = null; a.estado = 'lleva'; a.f = 0; } }&#10;        else if (a.estado === 'lleva') { const m = g ? manoDe(g) : a.pos; a.desde = a.desde || a.pos; const k = ease(Math.min(1, a.f \/ 50)); a.pos = { x: lerp(a.desde.x, tope.x, k), y: lerp(a.desde.y, tope.y, k) }; if (a.f &gt;= 50) { a.estado = 'suelta'; a.f = 0; a.desde = null; } }&#10;        else if (a.estado === 'suelta') { a.pos = tope; if (a.f === 1) { if (a.tipo === 'alga') cesta.algas = Math.min(CAP, cesta.algas + 1); else reciclado.n++; a.item = null; } if (a.f &gt;= 18) { a.estado = 'vuelve'; a.f = 0; } }&#10;        else if (a.estado === 'vuelve') { const k = ease(Math.min(1, a.f \/ 30)); a.pos = { x: lerp(tope.x, rest.x, k), y: lerp(tope.y, rest.y, k) }; if (a.f &gt;= 30) { a.estado = 'reposo'; a.f = 0; } }&#10;    }&#10;    function mover(g, tx, ty, v) { const dx = tx - g.x, dy = ty - g.y, d = Math.hypot(dx, dy); if (d &lt; 2) { g.espera = 1; return true; } g.x += dx \/ d * v; g.y += dy \/ d * v; if (Math.abs(dx) &gt; 1) g.dir = dx &gt; 0 ? 1 : -1; g.espera = 0; return false; }&#10;    function actualizarGenPlaya(g) {&#10;        const a = BR[g.arm], lista = g.arm === 'A' ? litter : clumps; g.t++;&#10;        if (g.tarea === 'busca') {&#10;            const libres = lista.filter(i =&gt; !i.res &amp;&amp; (g.arm === 'A' || cesta.algas &lt; CAP)); libres.sort((p, q) =&gt; Math.hypot(p.x - g.x, p.y - g.y) - Math.hypot(q.x - g.x, q.y - g.y));&#10;            if (libres.length) { g.obj = libres[0]; g.obj.res = g; g.tarea = 'va'; } else { g.tarea = 'ronda'; g.pt = { x: 60 + Math.random() * 790, y: g.arm === 'B' ? 378 : 472 + Math.random() * 40 }; if (g.arm === 'B') g.pt.y = 378; }&#10;        } else if (g.tarea === 'ronda') {&#10;            if (mover(g, g.pt.x, g.pt.y, 0.55)) { g.tarea = 'revisa'; g.t = 0; g.trab = true; g.ic = '\ud83d\udd27'; g.farola = PUNTOS_FAROLA.reduce((m, x) =&gt; Math.abs(x - g.x) &lt; Math.abs(m - g.x) ? x : m, 40); }&#10;        } else if (g.tarea === 'revisa') { if (g.t &gt; 100) { g.trab = false; g.ic = ''; g.tarea = 'busca'; g.t = 0; } }&#10;        else if (g.tarea === 'va') { if (!g.obj || !lista.includes(g.obj)) { g.tarea = 'busca'; return; } if (mover(g, g.obj.x, g.arm === 'B' ? 376 : g.obj.y + 6, 0.85)) { g.tarea = 'recoge'; g.t = 0; g.trab = true; g.ic = g.arm === 'A' ? '\ud83e\uddf9' : '\ud83c\udf3f'; } }&#10;        else if (g.tarea === 'recoge') { if (g.t &gt; 55) { const i = lista.indexOf(g.obj); if (i &gt;= 0) lista.splice(i, 1); g.llevando = g.arm === 'A' ? 'basura' : 'alga'; g.obj = null; g.tarea = 'lleva'; g.ic = '\u267b\ufe0f'; } }&#10;        else if (g.tarea === 'lleva') { if (mover(g, a.mano.x, a.mano.y, 0.85)) { g.tarea = 'entrega'; g.dir = a.x &gt; g.x ? 1 : -1; } }&#10;        else if (g.tarea === 'entrega') { if (!g.llevando) { g.tarea = 'busca'; g.trab = false; g.ic = ''; } }&#10;    }&#10;    function actualizarPlaya() { G.forEach(actualizarGenPlaya); actualizarBrazoMano(BR.A, G); actualizarBrazoMano(BR.B, G); }&#10;    function actualizarPuerto() {&#10;        GP.t++; const p = RUTA_PUERTO[GP.i];&#10;        if (GP.tarea === 'va') { if (mover(GP, p.x, p.y, 0.7)) { GP.tarea = 'revisa'; GP.t = 0; GP.trab = true; GP.ic = '\ud83d\udd27'; GP.dir = p.mira[0] &gt;= GP.x ? 1 : -1; } }&#10;        else if (GP.t &gt; 170) { GP.trab = false; GP.ic = ''; GP.i = (GP.i + 1) % RUTA_PUERTO.length; GP.tarea = 'va'; }&#10;        if (!rota(BR.C)) BR.C.f++;&#10;    }&#10;    function dibujarItem(i, t) {&#10;        ctx.save(); ctx.lineWidth = 1.2; ctx.strokeStyle = '#000';&#10;        if (i.k === 0) { ctx.fillStyle = 'rgba(126,200,227,0.9)'; ctx.fillRect(i.x - 2, i.y - 9, 4, 10); ctx.strokeRect(i.x - 2, i.y - 9, 4, 10); ctx.fillStyle = '#e53935'; ctx.fillRect(i.x - 1.5, i.y - 11, 3, 2); }&#10;        else if (i.k === 1) { ctx.fillStyle = '#c0c4cc'; ctx.fillRect(i.x - 3, i.y - 8, 6, 8); ctx.strokeRect(i.x - 3, i.y - 8, 6, 8); ctx.fillStyle = '#e53935'; ctx.fillRect(i.x - 3, i.y - 5, 6, 2); }&#10;        else { ctx.fillStyle = '#ffb347'; ctx.beginPath(); ctx.moveTo(i.x - 5, i.y); ctx.lineTo(i.x - 3, i.y - 6); ctx.lineTo(i.x + 2, i.y - 4); ctx.lineTo(i.x + 5, i.y - 1); ctx.closePath(); ctx.fill(); ctx.stroke(); }&#10;        ctx.restore();&#10;    }&#10;    function dibujarAlga(c, t, sobre) {&#10;        const x = c.x, y = c.y + Math.sin(t \/ 22 + c.ph) * 1.6; ctx.save(); ctx.lineWidth = 1.2; ctx.strokeStyle = '#143a1c';&#10;        [['#2f6d3a', -5, 0, 8, 4], ['#4f9d54', 3, -1, 9, 4.4], ['#3a7d44', -1, -3, 7, 3.6]].forEach(([col, dx, dy, rx, ry]) =&gt; { ctx.fillStyle = col; ctx.beginPath(); ctx.ellipse(x + dx, y + dy, rx, ry, 0.3 * dx, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); });&#10;        ctx.strokeStyle = 'rgba(190,255,200,0.6)'; ctx.beginPath(); ctx.moveTo(x - 7, y - 2); ctx.quadraticCurveTo(x, y - 6, x + 8, y - 3); ctx.stroke(); ctx.restore();&#10;    }&#10;    function spriteContenedor() {&#10;        return sprites.cont || (sprites.cont = conLienzo(44, 44, () =&gt; {&#10;            ctx.lineWidth = 2; ctx.strokeStyle = '#000'; ctx.fillStyle = '#2fa36b'; ctx.fillRect(6, 14, 32, 28); ctx.strokeRect(6, 14, 32, 28); ctx.fillStyle = '#1f7a52'; ctx.fillRect(3, 8, 38, 8); ctx.strokeRect(3, 8, 38, 8); mTxt('\u267b\ufe0f', 22, 29, 14, '#fff', 'center');&#10;        }));&#10;    }&#10;    function dibujarCesta(t) {&#10;        const b = BR.B.dest; ctx.save(); ctx.lineWidth = 2; ctx.strokeStyle = '#000';&#10;        const h = 12 * cesta.algas \/ CAP; ctx.fillStyle = '#3a7d44'; ctx.beginPath(); ctx.ellipse(b.x, b.y - 10 - h * 0.4, 14, 5 + h * 0.5, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();     \/\/ pila de algas&#10;        ctx.fillStyle = '#c9a46a'; ctx.beginPath(); ctx.moveTo(b.x - 15, b.y - 10); ctx.lineTo(b.x + 15, b.y - 10); ctx.lineTo(b.x + 11, b.y + 6); ctx.lineTo(b.x - 11, b.y + 6); ctx.closePath(); ctx.fill(); ctx.stroke();            \/\/ cesta&#10;        ctx.strokeStyle = 'rgba(90,60,25,0.7)'; ctx.lineWidth = 1; ctx.beginPath(); for (let k = -10; k &lt;= 10; k += 5) { ctx.moveTo(b.x + k, b.y - 9); ctx.lineTo(b.x + k * 0.75, b.y + 5); } ctx.moveTo(b.x - 13, b.y - 3); ctx.lineTo(b.x + 13, b.y - 3); ctx.stroke(); ctx.restore();&#10;    }&#10;    function dibujarGen(g, t) { Industria.genoide(g, performance.now()); }&#10;    function spritePuesto() {&#10;        return sprites.puesto || (sprites.puesto = conLienzo(150, 104, () =&gt; {&#10;            const cx = 75, b = 96; ctx.lineWidth = 2; ctx.strokeStyle = '#000';&#10;            ctx.fillStyle = '#8a5a2b'; [-58, 52].forEach(dx =&gt; { ctx.fillRect(cx + dx, b - 70, 6, 70); ctx.strokeRect(cx + dx, b - 70, 6, 70); });                                                   \/\/ postes&#10;            ctx.fillStyle = '#b88a54'; ctx.fillRect(cx - 56, b - 42, 112, 5); ctx.strokeRect(cx - 56, b - 42, 112, 5);                                                                             \/\/ balda&#10;            [['#d9a441', -46], ['#7cb342', -34], ['#8a5a2b', -22], ['#d9a441', 18], ['#7cb342', 30], ['#8a5a2b', 42]].forEach(([c, dx]) =&gt; { ctx.fillStyle = 'rgba(235,245,250,0.85)'; ctx.fillRect(cx + dx, b - 56, 9, 14); ctx.strokeRect(cx + dx, b - 56, 9, 14); ctx.fillStyle = c; ctx.fillRect(cx + dx + 1, b - 52, 7, 9); });    \/\/ tarros de t\u00e9&#10;            [['#9be564', -8], ['#ffb347', 2]].forEach(([c, dx]) =&gt; { ctx.fillStyle = c; ctx.fillRect(cx + dx, b - 55, 8, 12); ctx.strokeRect(cx + dx, b - 55, 8, 12); });                                 \/\/ bolsas de snacks&#10;            ctx.fillStyle = '#aab4bc'; ctx.beginPath(); ctx.moveTo(cx - 68, b - 64); ctx.lineTo(cx + 68, b - 64); ctx.lineTo(cx + 58, b - 80); ctx.lineTo(cx - 58, b - 80); ctx.closePath(); ctx.fill(); ctx.stroke();   \/\/ tejadillo de zinc&#10;            ctx.strokeStyle = 'rgba(70,80,90,0.55)'; ctx.lineWidth = 1; ctx.beginPath(); for (let x = -60; x &lt;= 60; x += 8) { ctx.moveTo(cx + x * 0.9, b - 80); ctx.lineTo(cx + x, b - 64); } ctx.stroke();&#10;            ctx.fillStyle = '#8f99a3'; ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.fillRect(cx - 68, b - 64, 136, 5); ctx.strokeRect(cx - 68, b - 64, 136, 5);&#10;            ctx.fillStyle = '#b88a54'; ctx.fillRect(cx - 62, b - 26, 124, 26); ctx.strokeRect(cx - 62, b - 26, 124, 26); ctx.strokeStyle = 'rgba(70,40,15,0.5)'; ctx.lineWidth = 1; ctx.beginPath(); for (let x = -50; x &lt; 62; x += 20) { ctx.moveTo(cx + x, b - 26); ctx.lineTo(cx + x, b); } ctx.stroke();   \/\/ mostrador de madera&#10;            ctx.fillStyle = '#cfd6dc'; ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.fillRect(cx - 64, b - 30, 128, 6); ctx.strokeRect(cx - 64, b - 30, 128, 6);                                       \/\/ encimera de zinc&#10;            [-30, 20].forEach(dx =&gt; { ctx.fillStyle = '#c9a46a'; ctx.beginPath(); ctx.moveTo(cx + dx - 16, b - 30); ctx.lineTo(cx + dx + 16, b - 30); ctx.lineTo(cx + dx + 12, b - 20); ctx.lineTo(cx + dx - 12, b - 20); ctx.closePath(); ctx.fill(); ctx.stroke(); });   \/\/ cestas&#10;            ctx.fillStyle = '#1f7a68'; ctx.fillRect(cx - 40, b - 96, 80, 14); ctx.strokeRect(cx - 40, b - 96, 80, 14); mTxt('ALGAS \u00b7 T\u00c9S \u00b7 SNACKS', cx + 4, b - 89, 7, '#fff', 'center', true); mTxt('\ud83c\udf3f', cx - 34, b - 89, 9, '#000', 'center');   \/\/ cartel&#10;        }));&#10;    }&#10;    function dibujarPuesto(t, now) {&#10;        ctx.drawImage(spritePuesto(), PX - 75, PB - 96);&#10;        const h = 12 * puesto.stock \/ STOCK_MAX; [-30, 20].forEach((dx, i) =&gt; { ctx.fillStyle = i ? '#4f9d54' : '#3a7d44'; ctx.strokeStyle = '#143a1c'; ctx.lineWidth = 1.2; ctx.beginPath(); ctx.ellipse(PX + dx, PB - 32 - h * 0.35, 13, 3 + h * 0.5, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); });   \/\/ algas frescas seg\u00fan el g\u00e9nero&#10;        for (let i = 0; i &lt; 3; i++) { ctx.fillStyle = `rgba(255,225,150,${0.8 + 0.2 * Math.sin(t \/ 10 + i)})`; ctx.beginPath(); ctx.arc(PX - 30 + i * 30, PB - 60, 2.6, 0, Math.PI * 2); ctx.fill(); }                    \/\/ bombillas c\u00e1lidas&#10;        if (now - puesto.flash &lt; 1300) { const k = (now - puesto.flash) \/ 1300; ctx.globalAlpha = 1 - k; mTxt('\ud83e\ude99', PX + 4, PB - 44 - k * 26, 14, '#000', 'center'); ctx.globalAlpha = 1; }                       \/\/ moneda al vender&#10;    }&#10;    function dron(x, y, t, caja) {&#10;        ctx.save(); ctx.translate(x, y); ctx.lineWidth = 1.6; ctx.strokeStyle = '#000';&#10;        ctx.fillStyle = 'rgba(0,0,0,0.12)'; ctx.beginPath(); ctx.ellipse(0, 20, 12, 3, 0, 0, Math.PI * 2); ctx.fill();&#10;        ctx.fillStyle = '#e9edf0'; ctx.beginPath(); ctx.ellipse(0, 0, 11, 5, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#1d3f7a'; ctx.fillRect(-8, -9, 16, 4); ctx.strokeRect(-8, -9, 16, 4);&#10;        ctx.strokeStyle = 'rgba(60,70,80,0.9)'; ctx.lineWidth = 2; [-1, 1].forEach(s =&gt; { ctx.beginPath(); ctx.moveTo(s * 11, -2); ctx.lineTo(s * 17, -5); ctx.stroke(); const w = Math.sin(t * 1.3 + s) * 9; ctx.beginPath(); ctx.moveTo(s * 17 - w, -6); ctx.lineTo(s * 17 + w, -6); ctx.stroke(); });&#10;        ctx.strokeStyle = '#000'; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(0, 5); ctx.lineTo(0, 9); ctx.stroke(); ctx.fillStyle = '#c9a46a'; ctx.fillRect(-6, 9, 12, 9); ctx.strokeRect(-6, 9, 12, 9); ctx.fillStyle = '#3a7d44'; ctx.fillRect(-5, 9, 10, 4);        \/\/ caja con algas&#10;        ctx.restore();&#10;    }&#10;    function dibujarEnvios(t, now) {&#10;        envios.forEach(e =&gt; { const k = Math.min(1, (now - e.t0) \/ e.dur), p = ease(k);&#10;            if (e.ruta === 'puesto') dron(lerp(CESTA.x, PX, p), lerp(CESTA.y - 20, PB - 60, p) - Math.sin(p * Math.PI) * 60, t);&#10;            else dron(lerp(CESTA.x, 960, p), lerp(CESTA.y - 20, -30, p) - Math.sin(p * Math.PI) * 24, t); });&#10;    }&#10;    const COLORES_TABLA = ['#ff6fa8', '#2fd6c0', '#ffd54a', '#7c5cff'];&#10;    function recogeEquipo(h) { h.equipoSurf = h.objetivoPlaya.tipo; h.colorTabla = COLORES_TABLA[Math.floor(Math.random() * COLORES_TABLA.length)]; h.objetivoPlaya = h.objetivoPlaya.equipo; h.pausaEquipo = 70; }&#10;    function dibujarEquipo(h) {                                                                                    \/\/ la chica lleva su tabla (y la vela, si es de windsurf) bajo el brazo&#10;        const dir = h.miraPlayaDerecha ? 1 : -1, x = h.posPlaya.x + dir * 15, y = h.posPlaya.y - 4;&#10;        ctx.save(); ctx.translate(x, y); ctx.rotate(dir * 0.12); ctx.lineWidth = 1.6; ctx.strokeStyle = '#000'; ctx.fillStyle = h.colorTabla || '#ff6fa8';&#10;        ctx.beginPath(); ctx.ellipse(0, 0, 5, 24, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.strokeStyle = 'rgba(255,255,255,0.85)'; ctx.lineWidth = 1.2; ctx.beginPath(); ctx.moveTo(0, -20); ctx.lineTo(0, 20); ctx.stroke();&#10;        if (h.equipoSurf === 'windsurf') { ctx.fillStyle = '#ffe3f1'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.4; ctx.beginPath(); ctx.moveTo(0, -22); ctx.lineTo(dir * 14, -8); ctx.lineTo(0, 0); ctx.closePath(); ctx.fill(); ctx.stroke(); }&#10;        ctx.restore();&#10;    }&#10;    function decorarCosta(t, escena) {                                                                             \/\/ fiestas del calendario en la playa y el puerto&#10;        const F = fiestaActual(); if (!F) return; const id = F.id, pal = PAL[id], ban = id === 'carnaval' || id === '28j'; ctx.save();&#10;        if (escena === 'playa') {&#10;            guirnalda(40, 840, 346, pal, t, ban); guirnalda(PX - 62, PX + 62, PB - 86, pal, t, ban); guirnalda(694, 768, 322, pal, t, ban);&#10;            if (id === 'navidad') { mTxt('\ud83c\udf84', 790, 410, 22, '#000', 'center'); mTxt('\u2b50', 892, 218, 14, '#000', 'center'); }&#10;            else if (id === 'halloween') { mTxt('\ud83c\udf83', PX + 78, PB - 6, 18, '#000', 'center'); mTxt('\ud83c\udf83', 668, 410, 16, '#000', 'center'); }&#10;            else if (id === 'sanjuan') { [[PX - 60, PB - 70], [PX + 60, PB - 70], [776, 340]].forEach(([x, y], i) =&gt; mTxt('\ud83c\udfee', x, y + Math.sin(t \/ 30 + i) * 3, 14, '#000', 'center')); }&#10;            else if (id === '28j') mTxt('\ud83c\udff3\ufe0f\u200d\ud83c\udf08', 892, 214, 16, '#000', 'center'); else if (id === 'carnaval') mTxt('\ud83c\udfad', 730, 276, 16, '#000', 'center');&#10;            else if (id === 'm8' || id === 'n25') Conmemoraciones.dibujarPancartas(t, 0.85, [{ x: 120, y: 392 }, { x: 560, y: 380 }]);&#10;            else if (id === 'astenagusia') { Fiestas2.ikurrina(MUELLE_X, 196, 24, 15, t); Fiestas2.ikurrina(PX + 56, PB - 118, 22, 14, t + 10); Fiestas2.ikurrina(746, 288, 22, 14, t + 25); }&#10;        } else {&#10;            guirnalda(80, 910, QUAY_Y - 52, pal, t, ban);&#10;            if (id === 'navidad') { ctx.fillStyle = 'rgba(255,255,255,0.85)'; for (let i = 0; i &lt; 30; i++) { ctx.beginPath(); ctx.arc((i * 83 + Math.sin(t \/ 40 + i) * 8) % 960, (i * 41 + t * 0.6) % 330, 1.6, 0, Math.PI * 2); ctx.fill(); } mTxt('\ud83c\udf84', 300, QUAY_Y - 60, 20, '#000', 'center'); }&#10;            else if (id === 'carnaval' || id === '28j') dibujarConfeti(t);&#10;            else if (id === 'sanjuan') [[300, QUAY_Y - 30], [540, QUAY_Y - 30], [780, QUAY_Y - 30]].forEach(([x, y], i) =&gt; mTxt('\ud83c\udfee', x, y + Math.sin(t \/ 30 + i) * 3, 15, '#000', 'center'));&#10;            else if (id === 'astenagusia') [80, 300, 540, 780, 910].forEach(x =&gt; Fiestas2.ikurrina(x - 8, QUAY_Y - 96, 20, 13, t));&#10;            else if (id === 'm8' || id === 'n25') Conmemoraciones.dibujarPancartas(t, 0.8, [{ x: 150, y: QUAY_Y + 40 }, { x: 600, y: QUAY_Y + 40 }]);&#10;            else if (id === 'halloween') { [[140, QUAY_Y - 8], [400, QUAY_Y - 8], [680, QUAY_Y - 8]].forEach(([x, y]) =&gt; mTxt('\ud83c\udf83', x, y, 16, '#000', 'center')); for (let i = 0; i &lt; 3; i++) dibujarMurcielago(((t * 0.9 + i * 330) % 1100) - 70, 80 + i * 22 + Math.sin(t \/ 25 + i) * 10, t, 1); }&#10;        }&#10;        ctx.restore();&#10;    }&#10;    function dibujarPlayaFrente(t) { dibujarPuesto(t, performance.now()); decorarCosta(t, 'playa'); }&#10;    const TRAY = { x: 316, y: 438 };&#10;    function brazoIndustria(t, activo, col) {                                                                      \/\/ el brazo asiste a la impresora: lleva cartuchos de la bandeja a la m\u00e1quina&#10;        const a = { x: 332, y: 462 }, k = activo ? 0.5 + 0.5 * Math.sin(t \/ 22) : 0, from = { x: TRAY.x + 14, y: 422 }, to = { x: 376, y: 410 }, tgt = activo ? { x: lerp(from.x, to.x, ease(k)), y: lerp(from.y, to.y, ease(k)) - Math.sin(k * Math.PI) * 14 } : { x: a.x + 10, y: a.y - 56 };&#10;        ctx.save(); ctx.fillStyle = '#c9a46a'; ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.fillRect(TRAY.x - 14, TRAY.y - 6, 30, 8); ctx.strokeRect(TRAY.x - 14, TRAY.y - 6, 30, 8); ctx.restore();&#10;        brazo(a, tgt.x, tgt.y, k &gt; 0.9 || k &lt; 0.1, t);&#10;        if (activo &amp;&amp; col) { ctx.fillStyle = col; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.2; ctx.fillRect(tgt.x - 4, tgt.y + 6, 8, 10); ctx.strokeRect(tgt.x - 4, tgt.y + 6, 8, 10); }&#10;    }&#10;    function escaner(g, tx, ty, t) { const m = manoDe(g); ctx.save(); ctx.strokeStyle = `rgba(80,230,255,${0.45 + 0.35 * Math.sin(t \/ 5)})`; ctx.lineWidth = 1.6; ctx.setLineDash([4, 4]); ctx.lineDashOffset = -t; ctx.beginPath(); ctx.moveTo(m.x, m.y); ctx.lineTo(tx, ty); ctx.stroke(); ctx.setLineDash([]); ctx.fillStyle = 'rgba(80,230,255,0.7)'; ctx.beginPath(); ctx.arc(tx, ty, 3 + Math.sin(t \/ 5), 0, Math.PI * 2); ctx.fill(); ctx.restore(); }&#10;    function dibujarPlaya(t) {&#10;        actualizarPlaya();&#10;        litter.forEach(i =&gt; dibujarItem(i, t)); clumps.forEach(c =&gt; { if (!c.res || c.res.tarea !== 'recoge') dibujarAlga(c, t); });&#10;        ctx.drawImage(spriteContenedor(), BR.A.dest.x - 22, BR.A.dest.y - 34); dibujarCesta(t);&#10;        const aA = BR.A, aB = BR.B; [aA, aB].forEach(a =&gt; { const pos = a.pos || { x: a.x + 10, y: a.y - 56 }; brazo(a, pos.x, pos.y, a.estado === 'alcanza' || a.estado === 'suelta', t); humoBrazo(a, t); if (a.item &amp;&amp; ['lleva', 'agarra'].includes(a.estado)) { a.item === 'alga' ? dibujarAlga({ x: pos.x, y: pos.y + 6, ph: 0 }, t) : dibujarItem({ x: pos.x, y: pos.y + 8, k: 0 }, t); } });&#10;        G.slice().sort((p, q) =&gt; p.y - q.y).forEach(g =&gt; {&#10;            dibujarGen(g, t);&#10;            if (g.tarea === 'recoge' &amp;&amp; g.obj) { const o = g.obj; ctx.save(); ctx.strokeStyle = '#d0d6da'; ctx.lineWidth = 2.4; ctx.beginPath(); const m = manoDe(g), k = Math.min(1, g.t \/ 20); ctx.moveTo(m.x, m.y); ctx.lineTo(lerp(m.x, o.x, k), lerp(m.y, o.y - 4, k)); ctx.stroke(); ctx.restore(); }&#10;            if (g.tarea === 'revisa') escaner(g, g.farola, 342, t);&#10;            if ((g.tarea === 'lleva' || g.tarea === 'entrega') &amp;&amp; g.llevando) { const m = manoDe(g); g.llevando === 'alga' ? dibujarAlga({ x: m.x, y: m.y - 4, ph: 0 }, t) : dibujarItem({ x: m.x, y: m.y, k: 0 }, t); }&#10;        });&#10;        dibujarEnvios(t, performance.now());                                                                         \/\/ drones de carga solares: algas al puesto o a la Zona Industrial&#10;    }&#10;    function dibujarPuerto(t) {&#10;        actualizarPuerto();&#10;        const C = BR.C, i = Math.floor(C.f \/ 150) % 3, px = 762 + i * 44, k = (C.f % 150) \/ 150, sweep = Math.sin(k * Math.PI * 6) * 15;      \/\/ el brazo limpia los paneles de uno en uno&#10;        const tgt = { x: px + 18 + sweep, y: 412 + (k &lt; 0.08 || k &gt; 0.92 ? -14 : 4) };&#10;        brazo(C, tgt.x, tgt.y, false, t); humoBrazo(C, t);&#10;        if (k &gt; 0.92 || k &lt; 0.2) { const br = 0.5 + 0.5 * Math.sin(t \/ 3); ctx.fillStyle = `rgba(255,255,255,${0.9 * (k &lt; 0.2 ? 1 - k \/ 0.2 : (k - 0.92) \/ 0.08) * br})`; ctx.beginPath(); ctx.arc(px + 30, 418, 3, 0, Math.PI * 2); ctx.fill(); }                                    \/\/ destello: panel limpio&#10;        dibujarGen(GP, t); const p = RUTA_PUERTO[GP.i]; if (GP.tarea === 'revisa') escaner(GP, p.mira[0], p.mira[1], t);&#10;    }&#10;    function lucesNoche(t, enPuertoEscena) {&#10;        if (!enPuertoEscena) { resplandor(730, 402 - 4, 22, '70,225,255', 0.5); resplandor(730, 402 - 70, 34, '70,225,255', 0.28); resplandor(730 - 52, 402 - 30, 16, '255,47,209', 0.18); [PX - 30, PX, PX + 30].forEach(x =&gt; resplandor(x, PB - 60, 20, '255,210,130', 0.55)); resplandor(PX, PB - 36, 46, '255,210,130', 0.25); }&#10;        (enPuertoEscena ? [GP] : G).forEach(g =&gt; resplandor(g.x + g.dir * 10, g.y - 54, 18, '255,240,200', 0.5));&#10;    }&#10;    return { marea, averiar, tick, dibujarPlaya, dibujarPlayaFrente, dibujarPuerto, decorarCosta, lucesNoche, brazoIndustria, recogeEquipo, dibujarEquipo, vender, cesta, puesto, reciclado, CAP, STOCK_MAX };&#10;})();&#10;const Comidas = (() =&gt; {&#10;    const COL = ['#e8632c', '#c9a227', '#e6b422', '#8a5a2b', '#d9a441'];&#10;    let ult = performance.now();&#10;    const hora = () =&gt; { const d = new Date(); return d.getHours() + d.getMinutes() \/ 60; };&#10;    const esHoraComer = () =&gt; { const t = hora(); return (t &gt;= 7 &amp;&amp; t &lt; 10) || (t &gt;= 13 &amp;&amp; t &lt; 15.5) || (t &gt;= 20 &amp;&amp; t &lt; 22.5); };&#10;    function posTienda(tienda) {&#10;        if (tienda === 'frutas') return { x: ZONA_PUESTOFRUTA.x, y: ZONA_PUESTOFRUTA.y + 14 };&#10;        const py = MERCADILLO.baseY + MERCADILLO.alto, f = escalaProf(py); return { x: MERCADILLO.baseX + MERCADILLO.ancho \/ 2, y: py + (MERCADILLO.baseY + 18 - py) * f };&#10;    }&#10;    function terminar(h, k) {                                                                                        \/\/ beneficios de la comida&#10;        if (h.comida || h.comiendo) { bienestar.alim = Math.min(100, bienestar.alim + 0.8 * k); SiloCompost.e.residuos = Math.min(12, SiloCompost.e.residuos + 1); }&#10;        h.hambre = 0; h.comida = null; h.comiendo = null;&#10;    }&#10;    function plan(h) {                                                                                               \/\/ lo que le toca hacer ahora (lo usa la vida diaria)&#10;        const c = h.comida; if (!c) return null;&#10;        if (c.fase === 'compra') { c.tienda = c.tienda || (Math.random() &lt; 0.5 ? 'frutas' : 'mercadillo'); const p = posTienda(c.tienda); return { acc: 'compra', x: p.x, y: p.y }; }&#10;        if (c.fase === 'cocina') { const k = Biblioteca.casaDe(h); return { acc: 'cocinar', x: k.x + k.ancho \/ 2, y: SUELO_Y + 62 }; }&#10;        const libres = ZONAS_TERRAZA_ASIENTOS.map((s, i) =&gt; ({ x: s.x, y: s.y, clave: 'm' + i })).filter(s =&gt; !habitantes.some(o =&gt; o !== h &amp;&amp; ((o.estado === 'sentada' &amp;&amp; Math.abs(o.x - s.x) &lt; 8 &amp;&amp; Math.abs(o.y - s.y) &lt; 8) || (o.plan &amp;&amp; o.plan.clave === s.clave))));&#10;        if (!libres.length) { terminar(h, 0.6); return null; }                                                       \/\/ terraza llena: come de pie, algo m\u00e1s corto&#10;        const s = libres[Math.floor(Math.random() * libres.length)]; return { acc: 'comer', x: s.x, y: s.y, clave: s.clave };&#10;    }&#10;    function compra(h) {                                                                                             \/\/ compra en el Mercado (o tira del silo)&#10;        const cand = []; PUESTOS.forEach((st, i) =&gt; st.prods.forEach(p =&gt; { if (p.s &gt; 0 &amp;&amp; !\/^Semillas\/.test(p.n)) cand.push({ i, p }); }));&#10;        if (cand.length) { const c = cand[Math.floor(Math.random() * cand.length)]; c.p.s--; if (c.p.s &lt;= 0) Noticias.publicar('\ud83d\udce6 Se han agotado ' + c.p.n.toLowerCase() + ' en el Mercado', 'stock' + c.p.n, 120000); saldoMIIG26D += c.p.v; Kutxa.aportar(c.p.v * 0.08); h.comida.plato = { e: c.p.e, col: COL[c.i] }; }&#10;        else if (SiloCompost.e.silo &gt;= 1) { SiloCompost.e.silo--; h.comida.plato = { e: '\ud83c\udf72', col: '#c9a227' }; }&#10;        else h.comida.plato = { e: '\ud83c\udf5e', col: '#d9a441' };&#10;        h.comida.fase = 'cocina';&#10;    }&#10;    function cocina(h) { h.oculta = true; h.lugar = 'casa'; h.cocinando = true; h.bib = { fin: Date.now() + 45000 }; Biblioteca.casaDe(h); h.comida.fase = 'mesa'; }&#10;    function empieza(h) { h.comiendo = h.comida.plato; h.comida = null; }&#10;    function tick(now) {&#10;        const dt = Math.min(0.2, (now - ult) \/ 1000); ult = now; const comer = esHoraComer();&#10;        bienestar.alim = Math.max(15, bienestar.alim - dt * 0.02);&#10;        habitantes.forEach(h =&gt; {&#10;            if (h.hambre === undefined) h.hambre = 10 + Math.random() * 50;&#10;            if (h.durmiendo) { h.comida = null; h.comiendo = null; h.cocinando = false; h.hambre = Math.min(h.hambre, 30); return; }&#10;            h.hambre = Math.min(100, h.hambre + dt * 0.45);&#10;            if (h.comida &amp;&amp; now - h.comida.t0 &gt; 240000) { h.comida = null; h.hambre = 50; }&#10;            if (h.comiendo &amp;&amp; h.estado !== 'sentada') terminar(h, 1);&#10;            if (!h.comida &amp;&amp; !h.comiendo &amp;&amp; !h.oculta &amp;&amp; !h.enPlaya &amp;&amp; !h.arrastrando &amp;&amp; h.estado === 'caminando' &amp;&amp; h.hambre &gt;= (comer ? 45 : 80)) { h.comida = { fase: 'compra', t0: now }; h.plan = null; h.objetivoY = null; nuevoObjetivo(h); }&#10;        });&#10;    }&#10;    function dibujarPlato(h, t) {                                                                                    \/\/ plato sobre la terraza (y un poco de vapor al principio)&#10;        const x = h.x, y = h.y + 21, c = h.comiendo; ctx.save(); ctx.lineWidth = 1.4; ctx.strokeStyle = '#000'; ctx.fillStyle = '#fff'; ctx.beginPath(); ctx.ellipse(x, y, 11, 4, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;        ctx.fillStyle = c.col; ctx.beginPath(); ctx.ellipse(x, y - 1, 7, 2.6, 0, 0, Math.PI * 2); ctx.fill();&#10;        if ((h.temporizador || 0) &gt; 330) { ctx.strokeStyle = 'rgba(255,255,255,0.7)'; ctx.lineWidth = 1.4; [-3, 3].forEach((dx, i) =&gt; { ctx.beginPath(); ctx.moveTo(x + dx, y - 4); ctx.quadraticCurveTo(x + dx + 3, y - 10 + Math.sin(t \/ 8 + i) * 2, x + dx, y - 16); ctx.stroke(); }); }&#10;        ctx.restore();&#10;    }&#10;    function dibujarBolsa(h) {                                                                                       \/\/ lleva la compra a casa&#10;        const c = h.comida &amp;&amp; h.comida.plato; if (!c || h.comida.fase === 'compra') return; const x = h.x + (h.direccion &lt; 0 ? -15 : 15), y = h.y + 10;&#10;        ctx.save(); ctx.fillStyle = '#c9a46a'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.4; ctx.fillRect(x - 6, y - 4, 12, 11); ctx.strokeRect(x - 6, y - 4, 12, 11); ctx.fillStyle = c.col; ctx.beginPath(); ctx.arc(x, y - 5, 4, Math.PI, 0); ctx.fill(); ctx.restore();&#10;    }&#10;    return { tick, plan, compra, cocina, empieza, terminar, dibujarPlato, dibujarBolsa };&#10;})();&#10;function dibujarCocineraVecina(t) {                                                                              \/\/ al abrir una casa: la vecina que cocina est\u00e1 en los fogones&#10;    const h = habitantes.find(o =&gt; o.oculta &amp;&amp; o.lugar === 'casa' &amp;&amp; o.cocinando &amp;&amp; o.casaAsignada === casaAbierta); if (!h) return;&#10;    const fx = ZONA_FOGONES.x, fy = ZONA_FOGONES.y; dibujarSarten(fx, fy, t);&#10;    ctx.save(); ctx.translate(fx + 42, fy + 44 + Math.sin(t \/ 25) * 0.8); ctx.scale(1.1, 1.1); dibujarMu\u00f1eca({ x: 0, y: 0, angulo: Math.sin(t \/ 18) * 0.04 }, h.colorPelo, false, true, false, h.estilo); accesorioFiesta(0, 0, -1); ctx.restore();&#10;    ctx.save(); ctx.strokeStyle = 'rgba(255,255,255,0.7)'; ctx.lineWidth = 2; [-8, 0, 8].forEach((dx, i) =&gt; { const f = ((t \/ 45) + i \/ 3) % 1; ctx.globalAlpha = 0.8 * (1 - f); ctx.beginPath(); ctx.moveTo(fx + dx, fy - 8 - f * 6); ctx.quadraticCurveTo(fx + dx + 4, fy - 20 - f * 14, fx + dx, fy - 32 - f * 20); ctx.stroke(); }); ctx.restore();   \/\/ vapor del guiso&#10;}&#10;const Noticias = (() =&gt; {&#10;    const TABLON = { x: 332, y: 350 }, PN = { x: 150, y: 64, w: 660, h: 412 }, CERRAR = { x: PN.x + PN.w - 44, y: PN.y + 10, w: 32, h: 32 };&#10;    const NOTAS = [{ x: 10, y: 18, w: 26, h: 20, rot: -0.08 }, { x: 42, y: 16, w: 28, h: 22, rot: 0.06 }, { x: 22, y: 40, w: 34, h: 20, rot: -0.03 }], PAPEL = ['#fff3a6', '#ffd1e0', '#c9f2d0', '#cfe6ff'];&#10;    const lista = [], claves = {}; let abierto = false, noLeidas = 0, prox = performance.now() + 180000, activo = null, ultTipo = '', ultFiesta = null, ultCheck = 0, spr = null;&#10;    function publicar(txt, clave, enfria = 0) {&#10;        const ahora = Date.now(); if (clave) { if (claves[clave] &amp;&amp; ahora - claves[clave] &lt; enfria) return; claves[clave] = ahora; }&#10;        const m = String(txt).match(\/^(\\S+)\\s+([\\s\\S]*)$\/), e = m ? m[1] : '\ud83d\udccc', t = (m ? m[2] : String(txt)).slice(0, 90); lista.unshift({ e, t, ts: ahora }); if (lista.length &gt; 20) lista.pop(); noLeidas++;&#10;    }&#10;    const EVENTOS = [&#10;        { id: 'marea', peso: 1.2, dur: 180000, inicio() { Costa.marea(180000); publicar('\ud83c\udf0a Marea de algas: la orilla amanece cargada de algas', 'ev'); }, fin() { publicar('\ud83c\udf0a La marea de algas se calma', 'ev'); } },&#10;        { id: 'temporal', peso: 1, dur: 150000, inicio() { Puerto.temporal(150000); publicar('\u26c8\ufe0f Temporal en la costa: barcos y motos esperan amarrados', 'ev'); }, fin() { publicar('\u2600\ufe0f Pas\u00f3 el temporal: vuelven a salir los barcos', 'ev'); } },&#10;        { id: 'averia', peso: 1, dur: 120000, inicio() { const k = Costa.averiar(120000); publicar('\ud83d\udd27 Se ha averiado el brazo rob\u00f3tico de ' + k.donde, 'ev'); this.k = k; }, fin() { publicar('\u2705 El brazo rob\u00f3tico de ' + this.k.donde + ' vuelve a funcionar', 'ev'); } },&#10;        { id: 'concierto', peso: 0.8, inicio() { publicar('\ud83c\udfb6 Concierto improvisado de txalaparta junto a la fuente', 'ev'); } },&#10;        { id: 'flores', peso: 0.6, inicio() { publicar('\ud83c\udf38 Las vecinas han plantado flores nuevas en el parque', 'ev'); } },&#10;        { id: 'pan', peso: 0.6, inicio() { publicar('\ud83e\udd56 Hoy huele a pan reci\u00e9n hecho en el mercadillo', 'ev'); } },&#10;        { id: 'gaviotas', peso: 0.6, inicio() { publicar('\ud83d\udc26 Una bandada de gaviotas visita el puerto', 'ev'); } },&#10;        { id: 'abejas', peso: 0.7, inicio() { Apicultura.e.miel += 2; publicar('\ud83d\udc1d Las abejas han trabajado de m\u00e1s: +2 de miel para el Mercado', 'ev'); } },&#10;        { id: 'donativo', peso: 0.5, inicio() { Kutxa.aportar(1); publicar('\ud83c\udf81 Un donativo an\u00f3nimo llega a la Kutxa AuZ', 'ev'); } }&#10;    ];&#10;    function lanzar() {&#10;        const cand = EVENTOS.filter(e =&gt; e.id !== ultTipo), tot = cand.reduce((a, e) =&gt; a + e.peso, 0); let r = Math.random() * tot, ev = cand[0]; for (const e of cand) { if ((r -= e.peso) &lt;= 0) { ev = e; break; } }&#10;        ultTipo = ev.id; ev.inicio(); activo = ev.dur ? { ev, fin: performance.now() + ev.dur } : null;&#10;    }&#10;    function tick(now) {&#10;        if (activo &amp;&amp; now &gt;= activo.fin) { if (activo.ev.fin) activo.ev.fin(); activo = null; }&#10;        if (now &gt;= prox &amp;&amp; !activo &amp;&amp; !esHoraDeDormir()) { lanzar(); prox = now + 300000 + Math.random() * 240000; }&#10;        if (now - ultCheck &gt; 30000) {&#10;            ultCheck = now; const F = fiestaActual(), id = F ? F.id : null; if (id !== ultFiesta) { if (id &amp;&amp; (ultFiesta !== null || id === 'm8' || id === 'n25')) publicar(id === 'm8' ? '\ud83d\udc9c 8M \u00b7 Hoy el pueblo se viste de violeta por la igualdad' : id === 'n25' ? '\ud83c\udf97\ufe0f 25N \u00b7 Violencia machista: 016, gratuito, confidencial y sin rastro en la factura' : '\ud83c\udf89 Hoy es fiesta en el pueblo: ' + (F.txt || id), 'fiesta' + id, 20 * 3600000); ultFiesta = id; }&#10;            if (Biblioteca.dentro().length &gt;= 5) publicar('\ud83d\udcda La biblioteca digital est\u00e1 llena de vecinas aprendiendo', 'bib', 900000);&#10;        }&#10;    }&#10;    function spriteTablon() {&#10;        return spr || (spr = conLienzo(84, 100, () =&gt; {&#10;            ctx.lineWidth = 2; ctx.strokeStyle = '#000'; ctx.fillStyle = '#8a5a2b'; [14, 64].forEach(x =&gt; { ctx.fillRect(x, 62, 6, 36); ctx.strokeRect(x, 62, 6, 36); });&#10;            sombra(42, 98, 34, 4, 0.22); ctx.fillStyle = '#8a5a2b'; ctx.fillRect(6, 10, 72, 56); ctx.strokeRect(6, 10, 72, 56); ctx.fillStyle = '#d9b98a'; ctx.fillRect(10, 14, 64, 48); ctx.strokeStyle = 'rgba(120,80,40,0.35)'; ctx.lineWidth = 1; ctx.strokeRect(10, 14, 64, 48);&#10;            ctx.fillStyle = '#b5472e'; ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(0, 12); ctx.lineTo(42, 0); ctx.lineTo(84, 12); ctx.closePath(); ctx.fill(); ctx.stroke(); mTxt('AVISOS', 42, 8, 6, '#fff', 'center', true);&#10;            ctx.fillStyle = 'rgba(255,255,255,0.55)'; ctx.fillRect(54, 44, 16, 12); ctx.fillStyle = 'rgba(200,170,120,0.8)'; ctx.fillRect(12, 50, 14, 10);&#10;        }));&#10;    }&#10;    function dibujarTablon(t) {&#10;        const x = TABLON.x - 42, y = TABLON.y - 96; ctx.drawImage(spriteTablon(), x, y);&#10;        lista.slice(0, 3).forEach((n, i) =&gt; { const p = NOTAS[i]; ctx.save(); ctx.translate(x + p.x + p.w \/ 2, y + p.y + p.h \/ 2); ctx.rotate(p.rot); ctx.fillStyle = PAPEL[(n.ts + i) % 4]; ctx.strokeStyle = '#000'; ctx.lineWidth = 1; ctx.fillRect(-p.w \/ 2, -p.h \/ 2, p.w, p.h); ctx.strokeRect(-p.w \/ 2, -p.h \/ 2, p.w, p.h); mTxt(n.e, 0, 1, 10, '#000', 'center'); ctx.fillStyle = '#d23'; ctx.beginPath(); ctx.arc(0, -p.h \/ 2 + 1.5, 1.6, 0, Math.PI * 2); ctx.fill(); ctx.restore(); });&#10;        if (noLeidas &gt; 0) { const a = 0.55 + 0.45 * Math.sin(t \/ 8); resplandor(x + 74, y + 8, 12, '255,60,60', a); ctx.fillStyle = '#e53935'; ctx.strokeStyle = '#fff'; ctx.lineWidth = 1.4; ctx.beginPath(); ctx.arc(x + 74, y + 8, 4.2, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); }&#10;    }&#10;    const hace = ts =&gt; { const s = Math.max(0, (Date.now() - ts) \/ 1000); const H = Idioma.tr('hace'); return s &lt; 60 ? 'hace un momento' : s &lt; 3600 ? `${H} ${Math.floor(s \/ 60)} min` : s &lt; 86400 ? `${H} ${Math.floor(s \/ 3600)} h` : `${H} ${Math.floor(s \/ 86400)} d`; };&#10;    function envolver(texto, ancho, px) { ctx.font = `${px}px ${FUENTE_MERCADO}`; const ps = texto.split(' '), ls = []; let l = ''; ps.forEach(w =&gt; { const c = l ? l + ' ' + w : w; if (ctx.measureText(c).width &gt; ancho &amp;&amp; l) { ls.push(l); l = w; } else l = c; }); if (l) ls.push(l); return ls; }&#10;    function dibujarPanel() {&#10;        if (!abierto) return; ctx.fillStyle = 'rgba(30,20,10,0.45)'; ctx.fillRect(0, 0, canvas.width, canvas.height); mCaja(PN.x, PN.y, PN.w, PN.h, 18, '#fff8ea', '#b5472e', 4);&#10;        mCaja(CERRAR.x, CERRAR.y, CERRAR.w, CERRAR.h, 16, '#eee', '#999', 1.5); mTxt('\u2715', CERRAR.x + 16, CERRAR.y + 17, 15, '#555', 'center', true);&#10;        mTxt('\ud83d\udccc Tabl\u00f3n de ChicaChica', PN.x + 24, PN.y + 30, 20, '#7a2d1c', 'left', true);&#10;        let y0 = PN.y + 56; const msg = Conmemoraciones.mensaje();                                                                       \/\/ mensaje del d\u00eda (8M \/ 25N), fijo arriba&#10;        if (msg) { const ls = envolver(msg.texto, PN.w - 84, 12), h = 40 + ls.length * 16; mCaja(PN.x + 20, y0, PN.w - 40, h, 12, 'rgba(123,44,191,0.12)', '#7b2cbf', 2); mTxt(msg.titulo, PN.x + 34, y0 + 19, 13, '#5a189a', 'left', true); ls.forEach((l, i) =&gt; mTxt(l, PN.x + 34, y0 + 41 + i * 16, 12, '#3a2a4a', 'left')); y0 += h + 10; }&#10;        if (!lista.length) { mTxt('Todo tranquilo por el pueblo \ud83c\udf3f', PN.x + PN.w \/ 2, (y0 + PN.y + PN.h) \/ 2, 16, '#7a6a5a', 'center'); return; }&#10;        lista.slice(0, Math.max(2, Math.floor((PN.y + PN.h - 14 - y0) \/ 43))).forEach((n, i) =&gt; { const y = y0 + i * 43; mCaja(PN.x + 20, y, PN.w - 40, 38, 10, i % 2 ? 'rgba(0,0,0,0.03)' : 'rgba(181,71,46,0.07)', '#e5d3b3', 1); mTxt(n.e, PN.x + 44, y + 20, 20, '#000', 'center'); mTxt(n.t, PN.x + 68, y + 20, 13, '#3a2a1a', 'left'); mTxt(hace(n.ts), PN.x + PN.w - 34, y + 20, 11, '#8a7a6a', 'right'); });&#10;    }&#10;    function toque(x, y) { if (!dentroRect(x, y, PN) || dentroRect(x, y, CERRAR)) abierto = false; }&#10;    const tocoTablon = (x, y) =&gt; dentroRect(x, y, { x: TABLON.x - 40, y: TABLON.y - 96, w: 80, h: 100 });&#10;    return { TABLON, publicar, tick, dibujarTablon, dibujarPanel, toque, tocoTablon, abierto: () =&gt; abierto, abrir() { abierto = true; noLeidas = 0; },&#10;        exportar: () =&gt; lista.slice(0, 20).map(n =&gt; ({ e: n.e, t: n.t, ts: n.ts })),&#10;        importar(a) { if (!Array.isArray(a)) return; lista.length = 0; a.slice(0, 20).forEach(n =&gt; { if (n &amp;&amp; typeof n.e === 'string' &amp;&amp; typeof n.t === 'string' &amp;&amp; Number.isFinite(n.ts)) lista.push({ e: n.e.slice(0, 8), t: n.t.slice(0, 90), ts: n.ts }); }); } };&#10;})();&#10;const Fiestas2 = (() =&gt; {&#10;    const GARG = { x: 200, y: 340 }, TALO = { x: 428, y: 352 }, COLS_FUEGO = ['255,214,90', '255,80,80', '90,255,160', '90,200,255', '255,120,230', '255,255,255'];&#10;    const lerp = (a, b, k) =&gt; a + (b - a) * k, ease = k =&gt; k * k * (3 - 2 * k);&#10;    let sprGarg = null, sprTalo = null, sprOlen = null, bang = [-1, -1, -1, -1], ultOlen = 0;&#10;    const subFiesta = () =&gt; { const F = fiestaActual(); return F ? F.sub || null : null; };&#10;    const hora = () =&gt; { const d = new Date(); return d.getHours() + d.getMinutes() \/ 60; };&#10;    const esNoche = () =&gt; fiestaPrevia === 'astenagusia' || !esDeDia();&#10;    function fuegos(t, y0, y1) {&#10;        if (!esNoche()) return; ctx.save(); ctx.globalCompositeOperation = 'lighter';&#10;        for (let i = 0; i &lt; 4; i++) {&#10;            const ciclo = 120 + i * 19, a = (t + i * 47) % ciclo, k = Math.floor((t + i * 47) \/ ciclo), seed = ((k * 7919 + i * 104729) % 1000) \/ 1000;&#10;            const bx = 90 + ((seed * 7.3 + i * 0.31) % 1) * 780, by = y0 + 18 + ((seed * 13.7) % 1) * Math.max(10, y1 - y0 - 30), col = COLS_FUEGO[(k + i) % COLS_FUEGO.length];&#10;            if (a &gt; 92) continue;&#10;            if (a &lt; 14) { ctx.fillStyle = 'rgba(255,233,168,0.9)'; ctx.beginPath(); ctx.arc(bx, lerp(y1 + 40, by, a \/ 14), 2, 0, Math.PI * 2); ctx.fill(); continue; }&#10;            if (bang[i] !== k) { bang[i] = k; if (typeof Fiestas !== 'undefined' &amp;&amp; Fiestas.tema() === 'astenagusia') Fiestas.estallido(); }&#10;            const e = a - 14, R = 60 * (1 - Math.exp(-e \/ 16)), al = Math.max(0, 1 - e \/ 78);&#10;            for (let p = 0; p &lt; 22; p++) { const ang = p \/ 22 * Math.PI * 2 + seed * 6, r = R * (0.75 + 0.25 * (((p * 37) % 5) \/ 4)); ctx.fillStyle = `rgba(${col},${al})`; ctx.beginPath(); ctx.arc(bx + Math.cos(ang) * r, by + Math.sin(ang) * r + 0.0045 * e * e, 1.9 * al + 0.4, 0, Math.PI * 2); ctx.fill(); }&#10;            if (e &lt; 8) resplandor(bx, by, 44 - e * 3, col, (1 - e \/ 8) * 0.8);&#10;        }&#10;        ctx.restore();&#10;    }&#10;    function ikurrina(x, y, w, h, t) {&#10;        ctx.save(); ctx.translate(x, y); ctx.rotate(Math.sin(t \/ 30 + x) * 0.04); ctx.beginPath(); ctx.rect(0, 0, w, h); ctx.clip();&#10;        ctx.fillStyle = '#d52b1e'; ctx.fillRect(0, 0, w, h); ctx.strokeStyle = '#009b48'; ctx.lineWidth = h * 0.17; ctx.beginPath(); ctx.moveTo(0, 0); ctx.lineTo(w, h); ctx.moveTo(w, 0); ctx.lineTo(0, h); ctx.stroke();&#10;        ctx.strokeStyle = '#fff'; ctx.lineWidth = h * 0.1; ctx.beginPath(); ctx.moveTo(w \/ 2, 0); ctx.lineTo(w \/ 2, h); ctx.moveTo(0, h \/ 2); ctx.lineTo(w, h \/ 2); ctx.stroke(); ctx.restore();&#10;        ctx.save(); ctx.strokeStyle = '#000'; ctx.lineWidth = 1; ctx.strokeRect(x, y, w, h); ctx.restore();&#10;    }&#10;    function spriteGarg() {&#10;        return sprGarg || (sprGarg = conLienzo(260, 196, () =&gt; {&#10;            const cx = 110, b = 176; ctx.lineWidth = 2.4; ctx.strokeStyle = '#000'; ctx.lineJoin = 'round'; sombra(cx + 10, b + 2, 84, 11, 0.28);&#10;            ctx.strokeStyle = '#000'; ctx.lineWidth = 15; ctx.lineCap = 'round'; ctx.beginPath(); ctx.moveTo(cx + 26, b - 58); ctx.quadraticCurveTo(cx + 84, b - 56, cx + 100, b + 8); ctx.stroke();     \/\/ tobog\u00e1n interior: sale por detr\u00e1s&#10;            ctx.strokeStyle = '#ffd54a'; ctx.lineWidth = 11; ctx.stroke(); ctx.strokeStyle = '#d52b1e'; ctx.lineWidth = 11; ctx.setLineDash([9, 9]); ctx.stroke(); ctx.setLineDash([]);&#10;            ctx.fillStyle = '#d52b1e'; ctx.strokeStyle = '#000'; ctx.lineWidth = 2.4; ctx.beginPath(); ctx.moveTo(cx - 48, b); ctx.quadraticCurveTo(cx - 54, b - 40, cx - 24, b - 76); ctx.lineTo(cx + 24, b - 76); ctx.quadraticCurveTo(cx + 54, b - 40, cx + 48, b); ctx.closePath(); ctx.fill(); ctx.stroke();   \/\/ falda&#10;            ctx.fillStyle = '#fff'; ctx.beginPath(); ctx.moveTo(cx - 24, b); ctx.quadraticCurveTo(cx - 26, b - 40, cx - 10, b - 70); ctx.lineTo(cx + 10, b - 70); ctx.quadraticCurveTo(cx + 26, b - 40, cx + 24, b); ctx.closePath(); ctx.fill(); ctx.stroke();                          \/\/ delantal&#10;            ctx.fillStyle = '#009b48'; ctx.fillRect(cx - 49, b - 9, 98, 9); ctx.strokeRect(cx - 49, b - 9, 98, 9);&#10;            ctx.save(); ctx.translate(cx, b - 104); ctx.scale(1.95, 1.95); dibujarMu\u00f1eca({ x: 0, y: 0, angulo: 0 }, '#c0522d', false, false, false, 'largo');                                    \/\/ cabeza enorme&#10;            ctx.fillStyle = '#2b0a0a'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.4; ctx.beginPath(); ctx.ellipse(0, 9, 8.5, 10.5, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#e8657a'; ctx.beginPath(); ctx.ellipse(0, 14, 5.4, 3.4, 0, 0, Math.PI * 2); ctx.fill();     \/\/ boca abierta&#10;            ctx.fillStyle = '#d52b1e'; ctx.beginPath(); ctx.ellipse(0, -24, 23, 7, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.beginPath(); ctx.arc(0, -31, 2.4, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.restore();       \/\/ txapela roja&#10;            ctx.fillStyle = '#c9a46a'; ctx.strokeStyle = '#000'; ctx.lineWidth = 2; [[cx - 76, b], [cx - 58, b - 10], [cx - 40, b - 20]].forEach(([x, y]) =&gt; { ctx.fillRect(x, y, 20, 10); ctx.strokeRect(x, y, 20, 10); });   \/\/ escalones de entrada&#10;            ctx.fillStyle = '#1f7a68'; ctx.fillRect(cx - 78, b + 12, 76, 14); ctx.strokeRect(cx - 78, b + 12, 76, 14); mTxt('GARGANT\u00daA', cx - 40, b + 19.5, 8, '#fff', 'center', true);&#10;        }));&#10;    }&#10;    const entrada = () =&gt; ({ x: GARG.x - 66, y: GARG.y + 2 }), salida = () =&gt; ({ x: GARG.x + 94, y: GARG.y + 20 }), boca = () =&gt; ({ x: GARG.x + 6, y: GARG.y - 98 });&#10;    function entrarGargantua(h) { h.oculta = true; h.lugar = 'gargantua'; const a = Date.now(); h.bib = { desde: a, fin: a + 3400 }; }&#10;    function dibujarGargantua(t) {&#10;        ctx.drawImage(spriteGarg(), GARG.x - 110, GARG.y - 176);&#10;        const sw = Math.sin(t \/ 14) * 7;                                                                                                \/\/ brazos que saludan&#10;        ctx.save(); ctx.lineCap = 'round'; [-1, 1].forEach(s =&gt; { const x0 = GARG.x + s * 24, y0 = GARG.y - 66, x1 = GARG.x + s * 56, y1 = GARG.y - 98 + (s &gt; 0 ? sw : -sw); ctx.strokeStyle = '#000'; ctx.lineWidth = 11; ctx.beginPath(); ctx.moveTo(x0, y0); ctx.lineTo(x1, y1); ctx.stroke(); ctx.strokeStyle = '#d52b1e'; ctx.lineWidth = 7; ctx.stroke(); ctx.fillStyle = '#f2c9a0'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.6; ctx.beginPath(); ctx.arc(x1, y1, 5.5, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); }); ctx.restore();&#10;        ikurrina(GARG.x - 104, GARG.y - 150, 32, 20, t); ikurrina(GARG.x + 76, GARG.y - 150, 32, 20, t + 20);&#10;        const ahora = Date.now(); habitantes.forEach(h =&gt; {                                                                             \/\/ las que bajan por el tobog\u00e1n&#10;            if (!h.oculta || h.lugar !== 'gargantua' || !h.bib) return; const p = (ahora - h.bib.desde) \/ (h.bib.fin - h.bib.desde); if (p &lt; 0.28 || p &gt; 1) return;&#10;            const s = ease((p - 0.28) \/ 0.72), x0 = GARG.x + 26, y0 = GARG.y - 58, cx = GARG.x + 84, cy = GARG.y - 56, x1 = GARG.x + 100, y1 = GARG.y + 8, u = 1 - s;&#10;            const x = u * u * x0 + 2 * u * s * cx + s * s * x1, y = u * u * y0 + 2 * u * s * cy + s * s * y1, rot = (s - 0.5) * 1.6;&#10;            ctx.save(); ctx.translate(x, y - 14); ctx.rotate(rot); ctx.scale(0.8, 0.8); dibujarMu\u00f1eca({ x: 0, y: 0, angulo: 0 }, h.colorPelo, false, false, false, h.estilo); ctx.restore();&#10;        });&#10;    }&#10;    const TARIMA = { x: 470, y: 344 };&#10;    function ultimoDia(d) { const y = d.getFullYear(), a15 = new Date(y, 7, 15), ds = (6 - a15.getDay() + 7) % 7 || 7, fin = new Date(y, 7, 15 + ds + 8); return d.getMonth() === fin.getMonth() &amp;&amp; d.getDate() === fin.getDate(); }&#10;    function ritual() {                                                                                           \/\/ fase de la despedida (solo el \u00faltimo d\u00eda de verdad)&#10;        if (!INCLUIR_MARIJAIA || fiestaPrevia) return null; const F = fiestaActual(); if (!F || F.id !== 'astenagusia') return null; const d = new Date(); if (!ultimoDia(d)) return null;&#10;        const m = d.getHours() * 60 + d.getMinutes() + d.getSeconds() \/ 60; if (m &lt; 22 * 60 || m &gt;= 22 * 60 + 20) return null;&#10;        return m &lt; 22 * 60 + 12 ? { fase: 'viaje', k: (m - 22 * 60) \/ 12 } : { fase: 'quema', k: (m - (22 * 60 + 12)) \/ 8 };&#10;    }&#10;    function enTarima() { if (!INCLUIR_MARIJAIA) return false; const F = fiestaActual(); if (!F || F.id !== 'astenagusia') return false; if (fiestaPrevia) return true; const d = new Date(); return !(ultimoDia(d) &amp;&amp; d.getHours() &gt;= 22); }&#10;    function figuraMarijaia(x, y, esc, t, llama) {&#10;        ctx.save(); ctx.translate(x, y); ctx.scale(esc, esc); ctx.lineJoin = 'round'; ctx.lineWidth = 2.4; ctx.strokeStyle = '#000';&#10;        const sw = Math.sin(t \/ 14) * 7; ctx.lineCap = 'round';&#10;        [-1, 1].forEach(s =&gt; { const hx = s * (40 + sw * s * 0.4), hy = -140 + sw * s; ctx.strokeStyle = '#000'; ctx.lineWidth = 12; ctx.beginPath(); ctx.moveTo(s * 18, -80); ctx.lineTo(hx, hy); ctx.stroke(); ctx.strokeStyle = '#ff9800'; ctx.lineWidth = 8; ctx.stroke(); ctx.fillStyle = '#f2c9a0'; ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.beginPath(); ctx.arc(hx, hy, 6.5, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); });   \/\/ brazos en alto&#10;        ctx.save(); ctx.beginPath(); ctx.moveTo(-31, 0); ctx.quadraticCurveTo(-36, -42, -15, -86); ctx.lineTo(15, -86); ctx.quadraticCurveTo(36, -42, 31, 0); ctx.closePath(); ctx.clip();&#10;        ['#e53935', '#fdd835', '#43a047', '#1e88e5', '#ff9800', '#8e24aa', '#e53935'].forEach((c, i) =&gt; { ctx.fillStyle = c; ctx.fillRect(-36 + i * 10.4, -90, 10.6, 92); });                                    \/\/ vestido de colores&#10;        ctx.fillStyle = 'rgba(255,255,255,0.8)'; for (let i = 0; i &lt; 9; i++) { ctx.beginPath(); ctx.arc(-24 + (i % 5) * 12, -18 - Math.floor(i \/ 5) * 24, 2.4, 0, Math.PI * 2); ctx.fill(); } ctx.restore();&#10;        ctx.beginPath(); ctx.moveTo(-31, 0); ctx.quadraticCurveTo(-36, -42, -15, -86); ctx.lineTo(15, -86); ctx.quadraticCurveTo(36, -42, 31, 0); ctx.stroke();&#10;        ctx.fillStyle = '#fff'; ctx.beginPath(); ctx.ellipse(0, -86, 15, 5, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;        ctx.save(); ctx.translate(0, -112); ctx.scale(1.55, 1.55); dibujarMu\u00f1eca({ x: 0, y: 0, angulo: Math.sin(t \/ 22) * 0.04 }, '#5b3a1e', false, false, false, 'largo');&#10;        ctx.fillStyle = '#d52b1e'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.6; ctx.beginPath(); ctx.arc(0, -5, 26, Math.PI, 0); ctx.closePath(); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#fff'; [-14, -5, 5, 14].forEach((dx, i) =&gt; { ctx.beginPath(); ctx.arc(dx, -16 - (i % 2) * 4, 1.8, 0, Math.PI * 2); ctx.fill(); });   \/\/ pa\u00f1uelo en la cabeza&#10;        ctx.fillStyle = '#8b1a2b'; ctx.beginPath(); ctx.ellipse(0, 10, 11, 7, 0, 0, Math.PI); ctx.fill(); ctx.fillStyle = '#fff'; ctx.fillRect(-8, 9, 16, 2.6); ctx.fillStyle = 'rgba(255,120,150,0.55)'; [-15, 15].forEach(dx =&gt; { ctx.beginPath(); ctx.arc(dx, 8, 4, 0, Math.PI * 2); ctx.fill(); }); ctx.restore();   \/\/ sonrisa eterna y mofletes&#10;        if (llama &gt; 0) {                                                                                           \/\/ la quema: llamas que suben por el vestido&#10;            ctx.fillStyle = `rgba(40,20,10,${0.55 * llama})`; ctx.beginPath(); ctx.moveTo(-31, 0); ctx.quadraticCurveTo(-36, -42, -15, -86); ctx.lineTo(15, -86); ctx.quadraticCurveTo(36, -42, 31, 0); ctx.closePath(); ctx.fill();&#10;            for (let i = 0; i &lt; 11; i++) { const fx = -30 + i * 6, fh = 18 + 70 * llama * (0.55 + 0.45 * Math.sin(t \/ 3.4 + i * 1.7)), fy = -6 - (i % 3) * 12; ctx.fillStyle = 'rgba(255,110,20,0.92)'; ctx.beginPath(); ctx.moveTo(fx - 6, fy); ctx.quadraticCurveTo(fx - 2, fy - fh * 0.6, fx + 1, fy - fh); ctx.quadraticCurveTo(fx + 3, fy - fh * 0.5, fx + 6, fy); ctx.closePath(); ctx.fill(); ctx.fillStyle = 'rgba(255,220,80,0.95)'; ctx.beginPath(); ctx.moveTo(fx - 3, fy); ctx.quadraticCurveTo(fx, fy - fh * 0.45, fx + 1, fy - fh * 0.7); ctx.quadraticCurveTo(fx + 2, fy - fh * 0.3, fx + 3, fy); ctx.closePath(); ctx.fill(); }&#10;        }&#10;        ctx.restore();&#10;    }&#10;    function dibujarTarima(t) {&#10;        if (!enTarima()) return; const x = TARIMA.x, y = TARIMA.y; sombra(x, y + 2, 66, 8, 0.25); figuraMarijaia(x, y - 14, 0.8, t, 0);&#10;        ctx.save(); ctx.lineWidth = 2; ctx.strokeStyle = '#000'; ctx.fillStyle = '#a5703a'; ctx.fillRect(x - 52, y - 14, 104, 14); ctx.strokeRect(x - 52, y - 14, 104, 14);&#10;        ctx.fillStyle = '#8a5a2b'; for (let i = 0; i &lt; 10; i++) { ctx.fillRect(x - 48 + i * 10.6, y - 34, 3.4, 20); } ctx.strokeRect(x - 50, y - 36, 100, 4); ctx.fillStyle = '#b88a54'; ctx.fillRect(x - 50, y - 38, 100, 5); ctx.strokeRect(x - 50, y - 38, 100, 5);        \/\/ barandilla del balc\u00f3n&#10;        ctx.fillStyle = '#fff'; ctx.fillRect(x - 34, y - 12, 68, 11); ctx.strokeRect(x - 34, y - 12, 68, 11); mTxt('GORA MARIJAIA', x, y - 6.5, 7.2, '#d52b1e', 'center', true); ctx.restore();&#10;        if (!esDeDia() || fiestaPrevia) resplandor(x, y - 70, 54, '255,200,120', 0.25);&#10;    }&#10;    function trainera(x, y, t, k, llama) {&#10;        ctx.save(); ctx.translate(x, y); ctx.lineWidth = 2; ctx.strokeStyle = '#000'; ctx.fillStyle = '#8a5a2b'; ctx.beginPath(); ctx.moveTo(-74, -4); ctx.lineTo(74, -8); ctx.quadraticCurveTo(70, 8, 52, 9); ctx.lineTo(-52, 9); ctx.quadraticCurveTo(-72, 6, -74, -4); ctx.closePath(); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#fff'; ctx.fillRect(-68, -2, 136, 4);&#10;        ctx.strokeStyle = '#4a2f1a'; ctx.lineWidth = 2; ctx.beginPath(); for (let i = 0; i &lt; 6; i++) { const ox = -50 + i * 20, rem = Math.sin(t \/ 12 + i * 0.4) * 5; ctx.moveTo(ox, -3); ctx.lineTo(ox - 8, 14 + rem); } ctx.stroke();&#10;        ctx.fillStyle = '#fff'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.4; for (let i = 0; i &lt; 6; i++) { ctx.beginPath(); ctx.arc(-50 + i * 20, -8, 4.4, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#d52b1e'; ctx.fillRect(-52 + i * 20, -5, 5, 2.4); ctx.fillStyle = '#fff'; }          \/\/ remeros de blanco con el pa\u00f1uelo de fiestas&#10;        figuraMarijaia(0, -8, 0.5, t, llama); ctx.restore();&#10;    }&#10;    function dibujarRitualPuerto(t) {&#10;        const r = ritual(); if (!r) return; const llama = r.fase === 'quema' ? Math.min(1, r.k * 1.4) * (r.k &gt; 0.85 ? (1 - r.k) \/ 0.15 : 1) : 0, x = r.fase === 'viaje' ? lerp(-100, 520, r.k) : 520, y = 266 + Math.sin(t \/ 30) * 1.5;&#10;        if (r.fase === 'quema') { ctx.save(); ctx.fillStyle = `rgba(0,0,10,${0.32 * Math.min(1, r.k * 6)})`; ctx.fillRect(0, 0, 960, 540); ctx.restore(); }                                    \/\/ se apagan las luces (como las txosnas)&#10;        trainera(x, y, t, r.k, llama); if (llama &gt; 0) { resplandor(x, y - 50, 80 + 40 * llama, '255,150,50', 0.8 * llama); for (let i = 0; i &lt; 12; i++) { const f = ((t \/ 40) + i \/ 12) % 1; ctx.fillStyle = `rgba(255,${160 + i * 6},60,${0.9 * (1 - f)})`; ctx.fillRect(x + Math.sin(i * 3 + t \/ 10) * 22, y - 40 - f * 90, 2, 2); } }&#10;    }&#10;    const puestoTalo = () =&gt; ({ x: TALO.x, y: TALO.y + 24 });&#10;    function spriteTalo() {&#10;        return sprTalo || (sprTalo = conLienzo(110, 100, () =&gt; {&#10;            const cx = 55, b = 92; ctx.lineWidth = 2; ctx.strokeStyle = '#000'; sombra(cx, b + 2, 44, 6, 0.25);&#10;            ctx.fillStyle = '#8a5a2b'; [-42, 36].forEach(dx =&gt; { ctx.fillRect(cx + dx, b - 62, 6, 62); ctx.strokeRect(cx + dx, b - 62, 6, 62); });&#10;            ctx.fillStyle = '#b88a54'; ctx.fillRect(cx - 44, b - 28, 88, 28); ctx.strokeRect(cx - 44, b - 28, 88, 28); ctx.fillStyle = '#3a3a3f'; ctx.fillRect(cx - 40, b - 36, 46, 9); ctx.strokeRect(cx - 40, b - 36, 46, 9);                \/\/ mostrador y plancha&#10;            for (let k = 0; k &lt; 6; k++) { ctx.fillStyle = k % 2 ? '#d52b1e' : '#fff'; ctx.beginPath(); ctx.moveTo(cx - 52 + k * 17.3, b - 62); ctx.lineTo(cx - 35 + k * 17.3, b - 62); ctx.lineTo(cx - 35 + k * 17.3 + (k &lt; 3 ? 3 : -3), b - 50); ctx.lineTo(cx - 52 + k * 17.3 + (k &lt; 3 ? 3 : -3), b - 50); ctx.closePath(); ctx.fill(); ctx.stroke(); }   \/\/ toldo rojiblanco&#10;            ctx.fillStyle = '#e3b778'; [0, 1, 2].forEach(i =&gt; { ctx.beginPath(); ctx.ellipse(cx + 24, b - 34 - i * 4, 14, 4.5, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); });                                                 \/\/ pila de talos&#10;            ctx.fillStyle = '#9c3b2a'; [0, 1, 2, 3].forEach(i =&gt; { ctx.beginPath(); ctx.ellipse(cx - 34 + i * 10, b - 38, 8, 2.6, -0.2, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); });                                           \/\/ txistorra en la plancha&#10;            ctx.fillStyle = '#1f7a68'; ctx.fillRect(cx - 40, b - 82, 80, 14); ctx.strokeRect(cx - 40, b - 82, 80, 14); mTxt('TALO CON TXISTORRA', cx, b - 75, 7, '#fff', 'center', true);&#10;            ctx.fillStyle = '#d23'; [[-30, -26], [-24, -26], [-16, -26]].forEach(([dx, dy], i) =&gt; { ctx.beginPath(); ctx.arc(cx + dx + i * 3, b + dy, 3, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); });                                       \/\/ pimientos del caser\u00edo&#10;        }));&#10;    }&#10;    function dibujarTalo(t) {&#10;        ctx.drawImage(spriteTalo(), TALO.x - 55, TALO.y - 68);&#10;        ctx.save(); for (let k = 0; k &lt; 4; k++) { const f = ((t \/ 55) + k \/ 4) % 1; ctx.globalAlpha = 0.55 * (1 - f); ctx.fillStyle = '#e8e8e8'; ctx.beginPath(); ctx.arc(TALO.x - 33 + Math.sin(t \/ 12 + k) * 4, TALO.y - 40 - f * 30, 3 + f * 5, 0, Math.PI * 2); ctx.fill(); } ctx.restore();   \/\/ humo de la plancha&#10;    }&#10;    function comprarTalo(h) { saldoMIIG26D += 3; Kutxa.aportar(0.24); bienestar.alim = Math.min(100, bienestar.alim + 0.8); h.hambre = 0; h.taloT = 340; }&#10;    function dibujarComiendoTalo(h, t) { ctx.save(); ctx.fillStyle = '#e3b778'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.2; const x = h.x + (h.direccion &lt; 0 ? -14 : 14), y = h.y + 6; ctx.beginPath(); ctx.ellipse(x, y, 8, 3.4, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#9c3b2a'; ctx.beginPath(); ctx.ellipse(x, y - 1, 6, 1.6, 0, 0, Math.PI * 2); ctx.fill(); ctx.restore(); }&#10;    const visibleOlentzero = () =&gt; subFiesta() === 'olentzero' &amp;&amp; (fiestaPrevia === 'olentzero' || (hora() &gt;= 17 &amp;&amp; hora() &lt; 23));&#10;    function posOlentzero() { const x = -60 + ((performance.now() \/ 1000) % 40) * 27.5; return { x, y: yDeCalle(Math.max(0, Math.min(960, x))) + 14 }; }&#10;    function spriteOlentzero() {&#10;        return sprOlen || (sprOlen = conLienzo(70, 80, () =&gt; {&#10;            ctx.translate(35, 72); ctx.lineWidth = 1.8; ctx.strokeStyle = '#000'; ctx.lineJoin = 'round';&#10;            ctx.fillStyle = '#a5703a'; ctx.beginPath(); ctx.ellipse(-18, -34, 11, 15, -0.3, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#4a4f55'; ctx.beginPath(); ctx.arc(-17, -48, 3, 0, Math.PI * 2); ctx.fill(); ctx.stroke();      \/\/ saco de regalos&#10;            ctx.fillStyle = '#1f1f23'; ctx.fillRect(-8, -2, 6, 9); ctx.strokeRect(-8, -2, 6, 9); ctx.fillRect(2, -2, 6, 9); ctx.strokeRect(2, -2, 6, 9); ctx.beginPath(); ctx.ellipse(0, -20, 17, 21, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke();                 \/\/ botas y blus\u00f3n negro&#10;            ctx.fillStyle = '#f2c9a0'; ctx.beginPath(); ctx.arc(0, -46, 11, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#ef8c9a'; [-6, 6].forEach(dx =&gt; { ctx.beginPath(); ctx.arc(dx, -42, 3, 0, Math.PI * 2); ctx.fill(); });&#10;            ctx.fillStyle = '#000'; [-4, 4].forEach(dx =&gt; { ctx.beginPath(); ctx.arc(dx, -48, 1.3, 0, Math.PI * 2); ctx.fill(); }); ctx.strokeStyle = '#000'; ctx.lineWidth = 1.3; ctx.beginPath(); ctx.arc(0, -43, 4, 0.2, Math.PI - 0.2); ctx.stroke();&#10;            ctx.fillStyle = '#d52b1e'; ctx.lineWidth = 1.6; ctx.beginPath(); ctx.moveTo(-8, -35); ctx.lineTo(8, -35); ctx.lineTo(0, -26); ctx.closePath(); ctx.fill(); ctx.stroke();                                          \/\/ pa\u00f1uelo rojo&#10;            ctx.fillStyle = '#111'; ctx.beginPath(); ctx.ellipse(0, -56, 15, 5.5, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.beginPath(); ctx.arc(0, -61, 2, 0, Math.PI * 2); ctx.fill();                                      \/\/ txapela&#10;            ctx.strokeStyle = '#4a2f1a'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(5, -43); ctx.lineTo(15, -41); ctx.stroke(); ctx.fillStyle = '#4a2f1a'; ctx.fillRect(14, -47, 5, 7);                                    \/\/ pipa&#10;            ctx.strokeStyle = '#1f1f23'; ctx.lineWidth = 5; ctx.lineCap = 'round'; ctx.beginPath(); ctx.moveTo(14, -26); ctx.lineTo(24, -14); ctx.stroke(); ctx.fillStyle = '#f2c9a0'; ctx.beginPath(); ctx.arc(24, -13, 3, 0, Math.PI * 2); ctx.fill();&#10;        }));&#10;    }&#10;    let sprMari = null;&#10;    function spriteMari() {&#10;        return sprMari || (sprMari = conLienzo(70, 84, () =&gt; {&#10;            ctx.translate(35, 76); ctx.lineWidth = 1.8; ctx.strokeStyle = '#000'; ctx.lineJoin = 'round'; ctx.lineCap = 'round';&#10;            ctx.strokeStyle = '#6b4a2b'; ctx.lineWidth = 2.6; ctx.beginPath(); ctx.moveTo(20, 0); ctx.lineTo(20, -50); ctx.arc(15, -50, 5, 0, Math.PI, true); ctx.stroke();                                                  \/\/ cayado de pastora&#10;            ctx.strokeStyle = '#000'; ctx.lineWidth = 1.8; ctx.fillStyle = '#2f6b4a'; ctx.beginPath(); ctx.moveTo(-16, 0); ctx.quadraticCurveTo(-17, -14, -9, -24); ctx.lineTo(9, -24); ctx.quadraticCurveTo(17, -14, 16, 0); ctx.closePath(); ctx.fill(); ctx.stroke();    \/\/ falda&#10;            ctx.fillStyle = '#f4efe6'; ctx.beginPath(); ctx.ellipse(0, -31, 11, 10, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#e7dfc9'; ctx.fillRect(-6, -22, 12, 16); ctx.strokeRect(-6, -22, 12, 16);               \/\/ blusa y delantal&#10;            ctx.strokeStyle = '#f4efe6'; ctx.lineWidth = 5; ctx.beginPath(); ctx.moveTo(10, -33); ctx.lineTo(19, -26); ctx.stroke(); ctx.strokeStyle = '#000'; ctx.lineWidth = 1.2; ctx.beginPath(); ctx.moveTo(10, -33); ctx.lineTo(19, -26); ctx.stroke();&#10;            ctx.fillStyle = '#f2c9a0'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.8; ctx.beginPath(); ctx.arc(0, -49, 11, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#ef8c9a'; [-6, 6].forEach(dx =&gt; { ctx.beginPath(); ctx.arc(dx, -45, 3, 0, Math.PI * 2); ctx.fill(); });&#10;            ctx.fillStyle = '#000'; [-4, 4].forEach(dx =&gt; { ctx.beginPath(); ctx.arc(dx, -51, 1.3, 0, Math.PI * 2); ctx.fill(); }); ctx.lineWidth = 1.3; ctx.beginPath(); ctx.arc(0, -46, 4, 0.2, Math.PI - 0.2); ctx.stroke();&#10;            ctx.strokeStyle = '#4a2f1a'; ctx.lineWidth = 3; ctx.beginPath(); ctx.moveTo(-10, -50); ctx.quadraticCurveTo(-14, -44, -12, -36); ctx.moveTo(10, -50); ctx.quadraticCurveTo(14, -44, 12, -36); ctx.stroke();                                \/\/ trenzas&#10;            ctx.fillStyle = '#c0392b'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.6; ctx.beginPath(); ctx.arc(0, -53, 12, Math.PI, 0); ctx.closePath(); ctx.fill(); ctx.stroke(); ctx.beginPath(); ctx.moveTo(10, -53); ctx.lineTo(18, -49); ctx.lineTo(10, -47); ctx.closePath(); ctx.fill(); ctx.stroke();     \/\/ pa\u00f1uelo en la cabeza&#10;            ctx.fillStyle = '#fff'; [-6, 0, 6].forEach((dx, i) =&gt; { ctx.beginPath(); ctx.arc(dx, -60 + (i % 2) * 2, 1.5, 0, Math.PI * 2); ctx.fill(); });&#10;        }));&#10;    }&#10;    function dibujarMariDomingi(t) {                                                                              \/\/ amiga y vecina de Olentzero: pastora, cantora e irrintzilari&#10;        const p = posOlentzero(), x = p.x - 46, y = p.y + 4 + Math.abs(Math.sin(t \/ 7 + 1.4)) * -2; ctx.save(); ctx.translate(x, y); ctx.scale(1.2, 1.2); sombra(0, 2, 20, 4, 0.25); ctx.drawImage(spriteMari(), -35, -76); ctx.restore();&#10;        const c = (t + 90) % 720; if (c &lt; 70) { ctx.save(); ctx.strokeStyle = `rgba(255,80,170,${0.85 - c \/ 90})`; ctx.lineWidth = 2; for (let r = 0; r &lt; 3; r++) { ctx.beginPath(); ctx.arc(x + 12, y - 60, 10 + r * 8 + c * 0.25, -0.9, 0.9); ctx.stroke(); } ctx.restore(); }          \/\/ irrintzi&#10;    }&#10;    function dibujarOlentzero(t) {&#10;        const p = posOlentzero(); ctx.save(); ctx.translate(p.x, p.y + Math.abs(Math.sin(t \/ 7)) * -2); ctx.scale(1.25, 1.25); sombra(0, 2, 22, 4, 0.25); ctx.drawImage(spriteOlentzero(), -35, -72);&#10;        resplandor(24, -12, 14, '255,200,120', 0.55 + 0.2 * Math.sin(t \/ 9));                                                       \/\/ el farol&#10;        ctx.fillStyle = 'rgba(235,235,235,0.7)'; for (let k = 0; k &lt; 3; k++) { const f = ((t \/ 40) + k \/ 3) % 1; ctx.globalAlpha = 0.6 * (1 - f); ctx.beginPath(); ctx.arc(17 + Math.sin(t \/ 10 + k) * 2, -50 - f * 16, 2 + f * 3, 0, Math.PI * 2); ctx.fill(); } ctx.restore();                                           \/\/ humo de la pipa&#10;    }&#10;    function regalosVisibles() { if (subFiesta() !== 'olentzero') return false; if (fiestaPrevia === 'olentzero') return true; const d = new Date(), h = d.getHours(); return d.getDate() === 24 ? h &gt;= 21 : h &lt; 12; }&#10;    function dibujarRegalos(t) {                                                                                                        \/\/ junto a la puerta de cada casa&#10;        const cols = ['#e53935', '#43a047', '#fdd835', '#1e88e5']; casas.forEach((c, i) =&gt; { const x = c.x + c.ancho \/ 2 + 20, y = SUELO_Y + 66; ctx.save(); ctx.lineWidth = 1.4; ctx.strokeStyle = '#000';&#10;            [[0, 0, 11, 9, cols[i % 4]], [11, 2, 8, 7, cols[(i + 2) % 4]]].forEach(([dx, dy, w, h, col]) =&gt; { ctx.fillStyle = col; ctx.fillRect(x + dx, y - h + dy, w, h); ctx.strokeRect(x + dx, y - h + dy, w, h); ctx.fillStyle = '#fff'; ctx.fillRect(x + dx + w \/ 2 - 1, y - h + dy, 2, h); });&#10;            ctx.fillStyle = '#fff'; ctx.beginPath(); ctx.arc(x + 5.5, y - 10, 2.2, 0, Math.PI * 2); ctx.fill(); ctx.restore(); });&#10;    }&#10;    function dibujarPueblo(t) {&#10;        const sub = subFiesta(), F = fiestaActual();&#10;        if (F &amp;&amp; F.id === 'astenagusia') dibujarGargantua(t);&#10;        if (sub === 'santotomas') dibujarTalo(t);&#10;        if (regalosVisibles()) dibujarRegalos(t);&#10;        if (visibleOlentzero()) { dibujarMariDomingi(t); dibujarOlentzero(t); }&#10;        dibujarTarima(t);&#10;    }&#10;    function tick() {&#10;        habitantes.forEach(h =&gt; { if (h.taloT &gt; 0) h.taloT--; });&#10;        const ahora = Date.now(); if (visibleOlentzero() &amp;&amp; ahora - ultOlen &gt; 20 * 3600000) { ultOlen = ahora; Noticias.publicar('\ud83c\udf85 Olentzero ha bajado de la monta\u00f1a con su amiga Mari Domingi y su saco de regalos', 'olentzero', 20 * 3600000); }&#10;        { const d = new Date(), m = d.getHours() * 60 + d.getMinutes(); if (INCLUIR_MARIJAIA &amp;&amp; !fiestaPrevia &amp;&amp; fiestaActual() &amp;&amp; fiestaActual().id === 'astenagusia' &amp;&amp; ultimoDia(d) &amp;&amp; m &gt;= 21 * 60 + 45 &amp;&amp; m &lt; 22 * 60 + 20) Noticias.publicar('\ud83d\udd25 Agur Marijaia: a las 22:00 se despide en el puerto, en trainera', 'marijaia', 20 * 3600000); }&#10;    }&#10;    return { fuegos, ikurrina, dibujarRitualPuerto, dibujarPueblo, tick, enTarima, ritual, TARIMA, entrarGargantua, entrada, salida, boca, puestoTalo, posOlentzero, comprarTalo, dibujarComiendoTalo, subFiesta, esNoche };&#10;})();&#10;const Conmemoraciones = (() =&gt; {&#10;    const PANCARTAS = [{ x: 170, y: 338 }, { x: 480, y: 386 }, { x: 800, y: 336 }], FUENTE = { x: 592, y: 338 };&#10;    const TEXTOS = { m8: [['JUNTAS,', 'M\u00c1S FUERTES', ''], ['BERDINTASUNA', 'ORAIN', ''], ['', '', 'venus']], n25: [['NI UNA', 'M\u00c1S', ''], ['INDARKERIARIK', 'EZ', ''], ['', '', 'lazo']] };&#10;    const MSG = {&#10;        m8: { titulo: '\ud83d\udc9c 8M \u00b7 D\u00eda Internacional de la Mujer', texto: 'Hoy el pueblo se viste de violeta: igualdad, cuidados y derechos para todas. Juntas somos m\u00e1s fuertes. Berdintasuna orain.' },&#10;        n25: { titulo: '\ud83c\udf97\ufe0f 25N \u00b7 D\u00eda Internacional de la Eliminaci\u00f3n de la Violencia contra la Mujer', texto: 'Si vives o conoces una situaci\u00f3n de violencia machista, llama al 016: es gratuito, confidencial, atiende las 24 horas y no deja rastro en la factura (borra la llamada del registro del m\u00f3vil). WhatsApp: 600 000 016. Emergencias: 112.' }&#10;    };&#10;    let sprites = {};&#10;    const id = () =&gt; { const F = fiestaActual(); return F &amp;&amp; (F.id === 'm8' || F.id === 'n25') ? F.id : null; };&#10;    const mensaje = () =&gt; { const k = id(); return k ? MSG[k] : null; };&#10;    const hoy = () =&gt; { const d = new Date(); return { h: d.getHours(), m: d.getMinutes(), s: d.getSeconds() }; };&#10;    const silencioReal = () =&gt; { const F = fiestaActual(); if (!F || F.id !== 'n25' || fiestaPrevia) return false; const t = hoy(); return t.h === 12 &amp;&amp; t.m === 0; };      \/\/ el 25N de verdad, de 12:00 a 12:01&#10;    const silencio = () =&gt; silencioReal() || fiestaPrevia === 'n25';                                                                                                  \/\/ en la vista previa tambi\u00e9n se re\u00fanen (sin callar la radio)&#10;    const restoSilencio = () =&gt; { if (fiestaPrevia === 'n25') return 600; const t = hoy(); return Math.max(60, (60 - t.s) * 60); };&#10;    const noche = () =&gt; !esDeDia() || fiestaPrevia !== null;&#10;    function spritePancarta(l1, l2, simbolo) {&#10;        const k = l1 + '|' + l2 + '|' + simbolo;&#10;        return sprites[k] || (sprites[k] = conLienzo(104, 102, () =&gt; {&#10;            ctx.lineJoin = 'round'; ctx.lineCap = 'round'; sombra(52, 98, 42, 5, 0.25); ctx.lineWidth = 2; ctx.strokeStyle = '#000'; ctx.fillStyle = '#8a5a2b';&#10;            [8, 92].forEach(x =&gt; { ctx.fillRect(x - 2.5, 6, 5, 92); ctx.strokeRect(x - 2.5, 6, 5, 92); });&#10;            ctx.fillStyle = '#fff'; ctx.strokeStyle = '#7b2cbf'; ctx.lineWidth = 3; ctx.beginPath(); ctx.moveTo(8, 10); ctx.lineTo(92, 10); ctx.lineTo(92, 62); ctx.quadraticCurveTo(50, 68, 8, 62); ctx.closePath(); ctx.fill(); ctx.stroke();&#10;            ctx.fillStyle = '#7b2cbf'; ctx.fillRect(12, 14, 76, 4);&#10;            if (simbolo === 'venus') { ctx.strokeStyle = '#7b2cbf'; ctx.lineWidth = 3.2; ctx.beginPath(); ctx.arc(50, 29, 8.5, 0, Math.PI * 2); ctx.moveTo(50, 37.5); ctx.lineTo(50, 53); ctx.moveTo(43, 46); ctx.lineTo(57, 46); ctx.stroke(); }&#10;            else if (simbolo === 'lazo') { ctx.strokeStyle = '#7b2cbf'; ctx.lineWidth = 3.2; ctx.beginPath(); ctx.moveTo(50, 36); ctx.bezierCurveTo(34, 14, 32, 40, 50, 36); ctx.moveTo(50, 36); ctx.bezierCurveTo(66, 14, 68, 40, 50, 36); ctx.moveTo(50, 36); ctx.lineTo(41, 55); ctx.moveTo(50, 36); ctx.lineTo(59, 55); ctx.stroke(); mTxt('016', 78, 52, 9, '#5a189a', 'center', true); }&#10;            else { [[l1, 31], [l2, 49]].forEach(([l, y]) =&gt; mTxt(l, 50, y, Math.min(10.5, 74 \/ (Math.max(1, l.length) * 0.6)), '#5a189a', 'center', true)); }&#10;            if (simbolo === 'venus') mTxt('8M', 76, 52, 9, '#5a189a', 'center', true);&#10;        }));&#10;    }&#10;    function dibujarPancartas(t, escala = 1, lista = PANCARTAS, claves = null) {&#10;        const k = id(); if (!k) return;&#10;        lista.forEach((p, i) =&gt; { const [l1, l2, sim] = TEXTOS[k][i % 3]; ctx.save(); ctx.translate(p.x, p.y); ctx.transform(1, 0, Math.sin(t \/ 40 + i * 2) * 0.025, 1, 0, 0); ctx.scale(escala, escala); ctx.drawImage(spritePancarta(l1, l2, sim), -52, -98); ctx.restore();&#10;            if (noche()) resplandor(p.x, p.y - 62 * escala, 44 * escala, '170,90,230', 0.3); });&#10;    }&#10;    function velas(t) {                                                                                           \/\/ el 25N: velas violetas en la plaza durante el minuto de silencio&#10;        for (let i = 0; i &lt; 9; i++) { const a = (i + 0.5) \/ 9 * Math.PI, x = FUENTE.x + Math.cos(a) * 92, y = FUENTE.y + 8 + Math.sin(a) * 26;&#10;            ctx.save(); ctx.lineWidth = 1.2; ctx.strokeStyle = '#000'; ctx.fillStyle = '#e9d5ff'; ctx.fillRect(x - 2.5, y - 8, 5, 9); ctx.strokeRect(x - 2.5, y - 8, 5, 9);&#10;            const f = Math.sin(t \/ 5 + i * 1.7) * 0.8; ctx.fillStyle = '#ffd37a'; ctx.beginPath(); ctx.ellipse(x + f * 0.3, y - 12, 2.2, 3.4 + f * 0.4, 0, 0, Math.PI * 2); ctx.fill(); ctx.restore();&#10;            resplandor(x, y - 12, 14, '200,140,255', 0.55); }&#10;    }&#10;    function dibujarPueblo(t) { if (!id()) return; dibujarPancartas(t); if (silencio()) velas(t); }&#10;    const puntosPancarta = h =&gt; PANCARTAS.map((p, i) =&gt; ({ x: p.x + (i % 2 ? 30 : -30), y: p.y + 14 }));&#10;    const puestoSilencio = h =&gt; { const n = Math.max(1, habitantes.length), i = Math.max(0, habitantes.indexOf(h)), a = (i + 0.5) \/ n * Math.PI; return { x: FUENTE.x + Math.cos(a) * 128, y: FUENTE.y + 14 + Math.sin(a) * 38 }; };&#10;    let hubo = false;&#10;    function tick() {                                                                                             \/\/ al empezar el minuto de silencio, las vecinas que andan por el pueblo van a la plaza&#10;        const ya = id() === 'n25' &amp;&amp; silencio(); if (ya &amp;&amp; !hubo) habitantes.forEach(h =&gt; {&#10;            if (h.oculta || h.durmiendo || h.enPlaya || h.arrastrando || !['caminando', 'parada', 'sentada', 'leyendo'].includes(h.estado)) return;&#10;            if (h.patinete) { h.patinete.montadaPor = null; h.patinete = null; } h.estado = 'caminando'; h.plan = null; h.objetivoY = null; nuevoObjetivo(h); });&#10;        hubo = ya;&#10;    }&#10;    return { id, mensaje, silencio, silencioReal, restoSilencio, tick, dibujarPueblo, dibujarPancartas, puntosPancarta, puestoSilencio, PANCARTAS };&#10;})();&#10;let enSubmarino = false;&#10;const Submarino = (() =&gt; {&#10;    const W = 960, H = 540, SUELO = 458, SALIDA = { x: 14, y: 474, w: 138, h: 48 };&#10;    const KELP = [{ x: 48, h: 300, f: 0 }, { x: 96, h: 240, f: 1.3 }, { x: 150, h: 330, f: 2.1 }, { x: 210, h: 260, f: 0.7 }, { x: 262, h: 300, f: 3 }, { x: 704, h: 290, f: 1.7 }, { x: 760, h: 340, f: 2.6 }, { x: 816, h: 250, f: 0.4 }, { x: 872, h: 310, f: 3.5 }, { x: 924, h: 270, f: 1.1 }];&#10;    const NOMBRES = [{ x: 340, y: 487, n: 'Estrella de mar', r: 24 }, { x: 598, y: 495, n: 'Erizos de mar', r: 24 }, { x: 884, y: 470, n: 'An\u00e9mona', r: 26 }];&#10;    let capa = null, etiqueta = null, dispersa = 0; const vivos = [];&#10;    const lerp = (a, b, k) =&gt; a + (b - a) * k;&#10;    function construir() {&#10;        capa = conLienzo(W, H, () =&gt; {&#10;            const g = ctx.createLinearGradient(0, 0, 0, H); [[0, '#46cbe0'], [0.28, '#1b8fb8'], [0.56, '#0f5a8f'], [0.88, '#0a3560'], [1, '#081f42']].forEach(([o, c]) =&gt; g.addColorStop(o, c)); ctx.fillStyle = g; ctx.fillRect(0, 0, W, H);&#10;            ctx.fillStyle = 'rgba(8,70,110,0.42)'; ctx.beginPath(); ctx.moveTo(0, 470); [[60, 380], [140, 410], [220, 360], [300, 420], [380, 440], [470, 470]].forEach(([x, y]) =&gt; ctx.lineTo(x, y)); ctx.lineTo(470, 470); ctx.fill();                          \/\/ siluetas lejanas&#10;            ctx.beginPath(); ctx.moveTo(500, 470); [[580, 430], [660, 400], [740, 350], [820, 410], [900, 380], [960, 410]].forEach(([x, y]) =&gt; ctx.lineTo(x, y)); ctx.lineTo(960, 470); ctx.fill();&#10;            ctx.fillStyle = '#d3b97c'; ctx.beginPath(); ctx.moveTo(0, SUELO + 6); for (let x = 0; x &lt;= W; x += 40) ctx.lineTo(x, SUELO + Math.sin(x \/ 55) * 7); ctx.lineTo(W, H); ctx.lineTo(0, H); ctx.closePath(); ctx.fill();                                                  \/\/ arena&#10;            const sg = ctx.createLinearGradient(0, SUELO, 0, H); sg.addColorStop(0, 'rgba(255,240,200,0.18)'); sg.addColorStop(1, 'rgba(10,30,60,0.55)'); ctx.fillStyle = sg; ctx.fillRect(0, SUELO - 10, W, H - SUELO + 10);&#10;            ctx.strokeStyle = 'rgba(120,95,50,0.35)'; ctx.lineWidth = 1.4; ctx.beginPath(); for (let r = 0; r &lt; 4; r++) for (let x = (r * 37) % 70; x &lt; W; x += 70) { ctx.moveTo(x, SUELO + 22 + r * 16); ctx.quadraticCurveTo(x + 18, SUELO + 17 + r * 16, x + 38, SUELO + 22 + r * 16); } ctx.stroke();               \/\/ ondulaciones de la arena&#10;            [[[0, 472], [10, 422], [50, 392], [100, 386], [150, 404], [190, 440], [214, 472]], [[120, 472], [150, 442], [190, 434], [232, 454], [244, 472]], [[960, 472], [950, 420], [905, 390], [850, 386], [800, 406], [766, 444], [748, 472]], [[840, 472], [870, 446], [910, 440], [948, 458], [960, 472]]].forEach((pts, k) =&gt; {&#10;                ctx.fillStyle = k % 2 ? '#566b7e' : '#4c5f70'; ctx.strokeStyle = '#1d2a36'; ctx.lineWidth = 2.4; ctx.lineJoin = 'round'; ctx.beginPath(); pts.forEach(([x, y], i) =&gt; i ? ctx.lineTo(x, y) : ctx.moveTo(x, y)); ctx.closePath(); ctx.fill(); ctx.stroke();&#10;                ctx.strokeStyle = 'rgba(180,205,225,0.35)'; ctx.lineWidth = 3; ctx.beginPath(); pts.slice(1, 4).forEach(([x, y], i) =&gt; i ? ctx.lineTo(x, y + 4) : ctx.moveTo(x, y + 4)); ctx.stroke(); });                                                          \/\/ luz en las rocas&#10;            ctx.fillStyle = '#0b1624'; ctx.beginPath(); ctx.ellipse(90, 434, 24, 15, 0, 0, Math.PI * 2); ctx.fill();                                                                                                                                    \/\/ cueva del pulpo&#10;            ctx.fillStyle = 'rgba(180,60,70,0.85)'; [[220, 470], [236, 474], [716, 470], [732, 474], [840, 478]].forEach(([x, y]) =&gt; { ctx.beginPath(); ctx.ellipse(x, y, 9, 5, 0, 0, Math.PI * 2); ctx.fill(); });                                                      \/\/ algas rojas&#10;            ctx.fillStyle = '#e58a2b'; ctx.strokeStyle = '#8a4a12'; ctx.lineWidth = 1.4; ctx.beginPath(); for (let i = 0; i &lt; 10; i++) { const a = -Math.PI \/ 2 + i * Math.PI \/ 5, r = i % 2 ? 6 : 17; ctx.lineTo(340 + Math.cos(a) * r, 487 + Math.sin(a) * r); } ctx.closePath(); ctx.fill(); ctx.stroke();    \/\/ estrella de mar&#10;            ctx.fillStyle = '#3a2447'; ctx.strokeStyle = '#1b0f24'; [[596, 494, 7], [610, 499, 6]].forEach(([x, y, r]) =&gt; { ctx.beginPath(); ctx.arc(x, y, r, 0, Math.PI * 2); ctx.fill(); for (let i = 0; i &lt; 12; i++) { const a = i * Math.PI \/ 6; ctx.beginPath(); ctx.moveTo(x + Math.cos(a) * r, y + Math.sin(a) * r); ctx.lineTo(x + Math.cos(a) * (r + 5), y + Math.sin(a) * (r + 5)); ctx.stroke(); } });    \/\/ erizos&#10;            ctx.fillStyle = '#ff8fb3'; for (let i = 0; i &lt; 9; i++) { ctx.beginPath(); ctx.ellipse(884 + (i - 4) * 4.4, 464 - Math.abs(i - 4) * 1.5, 2.6, 13, (i - 4) * 0.14, 0, Math.PI * 2); ctx.fill(); } ctx.fillStyle = '#c24a74'; ctx.beginPath(); ctx.ellipse(884, 472, 15, 6, 0, 0, Math.PI * 2); ctx.fill();   \/\/ an\u00e9mona&#10;            ctx.fillStyle = '#a5703a'; ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.fillRect(SALIDA.x, SALIDA.y, SALIDA.w, SALIDA.h); ctx.strokeRect(SALIDA.x, SALIDA.y, SALIDA.w, SALIDA.h); ctx.fillStyle = '#fff'; ctx.fillRect(SALIDA.x + 7, SALIDA.y + 7, SALIDA.w - 14, SALIDA.h - 14); mTxt('\u2191 AL PUERTO', SALIDA.x + SALIDA.w \/ 2, SALIDA.y + SALIDA.h \/ 2 + 1, 13, '#20262e', 'center', true);&#10;        });&#10;    }&#10;    const SLOTS = [{ x: 250, y: 494, k: 0 }, { x: 430, y: 502, k: 1 }, { x: 640, y: 490, k: 2 }, { x: 780, y: 498, k: 0 }, { x: 180, y: 502, k: 1 }, { x: 540, y: 508, k: 2 }, { x: 710, y: 506, k: 0 }, { x: 350, y: 474, k: 2 }];&#10;    const SITIOS = [{ x: 305, y: 468 }, { x: 365, y: 472 }, { x: 430, y: 474 }, { x: 500, y: 472 }, { x: 570, y: 474 }, { x: 650, y: 470 }];&#10;    function basuraItem(p, t) {&#10;        ctx.save(); ctx.lineWidth = 1.2; ctx.strokeStyle = '#000';&#10;        if (p.k === 0) { ctx.fillStyle = 'rgba(126,200,227,0.9)'; ctx.fillRect(p.x - 2.5, p.y - 11, 5, 11); ctx.strokeRect(p.x - 2.5, p.y - 11, 5, 11); ctx.fillStyle = '#e53935'; ctx.fillRect(p.x - 2, p.y - 13, 4, 2); }&#10;        else if (p.k === 1) { ctx.fillStyle = '#c0c4cc'; ctx.fillRect(p.x - 3.5, p.y - 9, 7, 9); ctx.strokeRect(p.x - 3.5, p.y - 9, 7, 9); ctx.fillStyle = '#e53935'; ctx.fillRect(p.x - 3.5, p.y - 6, 7, 2.4); }&#10;        else { ctx.fillStyle = 'rgba(255,255,255,0.78)'; ctx.beginPath(); ctx.ellipse(p.x, p.y - 4 + Math.sin(t \/ 20 + p.x) * 1, 9, 5, 0.3, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); }&#10;        ctx.restore();&#10;    }&#10;    function posBuzo(h, e) {                                                                                   \/\/ ruta de la inmersi\u00f3n (70 s): bajar \u00b7 plantar \u00b7 recoger basura \u00b7 cuidar las algas \u00b7 subir&#10;        const st = SITIOS[h.buceoSitio % 6], ke = KELP[h.buceoSitio % KELP.length], it = h.buceoItems || 0, b0 = Math.max(0, Puerto.FONDO.b - 1), slot = j =&gt; SLOTS[((b0 - j) % 8 + 8) % 8], buoy = { x: 380, y: 36 };&#10;        const mix = (a, b, k) =&gt; ({ x: lerp(a.x, b.x, k), y: lerp(a.y, b.y, k) }), ease = k =&gt; k * k * (3 - 2 * k);&#10;        if (e &lt; 0.12) return { ...mix(buoy, { x: st.x, y: st.y - 30 }, ease(e \/ 0.12)), f: 'baja' };&#10;        if (e &lt; 0.45) return { x: st.x + Math.sin(e * 60) * 6, y: st.y - 22 + Math.sin(e * 90) * 2, f: 'planta' };&#10;        let pos = { x: st.x, y: st.y - 22 };&#10;        for (let j = 0; j &lt; it; j++) { const a = 0.45 + j * 0.09, b = a + 0.09, dest = { x: slot(j).x, y: slot(j).y - 16 }; if (e &lt; b) return { ...mix(pos, dest, ease(Math.max(0, (e - a) \/ 0.09))), f: 'basura' }; pos = dest; }&#10;        const kb = { x: ke.x + 12, y: 436 }; if (e &lt; 0.76) return { ...mix(pos, kb, ease(Math.max(0, (e - Math.max(0.45 + it * 0.09, 0.72 - 0.0)) \/ (0.76 - Math.max(0.45 + it * 0.09, 0.72))) || 0)), f: 'algas' };&#10;        if (e &lt; 0.90) { const k = (e - 0.76) \/ 0.14; return { x: kb.x + Math.sin(k * 14) * 6, y: 436 - Math.sin(k * Math.PI) * ke.h * 0.5, f: 'algas' }; }&#10;        return { ...mix(kb, buoy, ease((e - 0.9) \/ 0.1)), f: 'sube' };&#10;    }&#10;    function dibujarBuzo(h, pos, t) {&#10;        ctx.save(); ctx.translate(pos.x, pos.y); ctx.rotate(Math.max(-0.4, Math.min(0.4, (pos.vx || 0) * 0.1))); ctx.scale(0.52, 0.52); ctx.lineWidth = 3; ctx.strokeStyle = '#000';&#10;        ctx.fillStyle = '#e9edf0'; ctx.fillRect(-27, 0, 10, 30); ctx.strokeRect(-27, 0, 10, 30); ctx.fillStyle = '#2fd6c0'; ctx.fillRect(-27, 0, 10, 8); ctx.strokeRect(-27, 0, 10, 8);                       \/\/ botella a la espalda&#10;        ctx.fillStyle = '#ff6fa8'; [-1, 1].forEach(s =&gt; { ctx.save(); ctx.translate(s * 9, 40); ctx.rotate(s * 0.3 + Math.sin(t \/ 6 + s) * 0.3); ctx.beginPath(); ctx.ellipse(0, 6, 5, 12, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.restore(); });   \/\/ aletas&#10;        dibujarMu\u00f1eca({ x: 0, y: 0, angulo: Math.sin(t \/ 14) * 0.05 }, h.colorPelo, false, false, false, h.estilo);&#10;        ctx.fillStyle = 'rgba(130,210,255,0.6)'; ctx.strokeStyle = '#10243f'; ctx.lineWidth = 3; ctx.beginPath(); if (ctx.roundRect) ctx.roundRect(-15, -10, 30, 11, 5); else ctx.rect(-15, -10, 30, 11); ctx.fill(); ctx.stroke();            \/\/ m\u00e1scara&#10;        ctx.restore();&#10;        ctx.fillStyle = 'rgba(255,255,255,0.7)'; ctx.beginPath(); for (let k = 0; k &lt; 3; k++) { const f = ((t \/ 25) + k \/ 3) % 1; ctx.moveTo(pos.x + 4 + Math.sin(t \/ 7 + k) * 3 + 2, pos.y - 12 - f * 30); ctx.arc(pos.x + 4 + Math.sin(t \/ 7 + k) * 3, pos.y - 12 - f * 30, 1.6 + f, 0, Math.PI * 2); } ctx.fill();   \/\/ burbujas del regulador&#10;    }&#10;    function basuraYBuzos(t, now, FO) {&#10;        const bz = Puerto.buzos().map(h =&gt; ({ h, e: (Date.now() - h.buceoIni) \/ 70000 })).filter(o =&gt; o.e &gt;= 0 &amp;&amp; o.e &lt; 1); let recogidas = 0;&#10;        bz.forEach(({ h, e }) =&gt; { const it = h.buceoItems || 0; recogidas += [0.54, 0.63, 0.72].filter((th, j) =&gt; j &lt; it &amp;&amp; e &gt;= th).length; });&#10;        const n = Math.max(0, FO.b - recogidas); for (let i = 0; i &lt; n; i++) basuraItem(SLOTS[i], t);&#10;        bz.forEach(({ h, e }) =&gt; { const p = posBuzo(h, e), q = posBuzo(h, Math.min(0.999, e + 0.004)); p.vx = (q.x - p.x) * 40; dibujarBuzo(h, p, t);&#10;            if (p.f === 'planta') { const g = Math.min(1, (e - 0.12) \/ 0.3); ctx.strokeStyle = '#3f9a52'; ctx.lineWidth = 2.4; ctx.beginPath(); [-8, -2, 5, 11].forEach((dx, i) =&gt; { const bx = SITIOS[h.buceoSitio % 6].x + dx; ctx.moveTo(bx, SITIOS[h.buceoSitio % 6].y + 8); ctx.lineTo(bx + Math.sin(t \/ 30 + i) * 2, SITIOS[h.buceoSitio % 6].y + 8 - 16 * g); }); ctx.stroke(); }          \/\/ brotes de posidonia que planta&#10;            vivos.push({ x: p.x, y: p.y, n: 'Vecina buceando', r: 26 }); });&#10;    }&#10;    const RB = [{ n: 'Robot limpiador', col: '#2fd6c0', x: 380, y: 470, f: 0, dir: 1, tm: 0, ult: 0, acc: 'va' }, { n: 'Robot de aguas', col: '#4a7bd8', x: 480, y: 200, f: 1.7, dir: 1 }, { n: 'Robot ge\u00f3logo', col: '#ff9f43', x: 120, y: 452, f: 3.1, dir: 1 }, { n: 'Robot de vida', col: '#7cdc5b', x: 700, y: 436, f: 4.4, dir: 1, i: 0, tm: 0 }];&#10;    const VIDA = [{ x: 340, y: 470, n: 'estrellas' }, { x: 598, y: 476, n: 'erizos' }, { x: 884, y: 452, n: 'an\u00e9mona' }, { x: 500, y: 430, n: 'posidonia' }, { x: 150, y: 330, n: 'algas' }, { x: 470, y: 225, n: 'sardinas' }];&#10;    function mover(r, tx, ty, v) { const dx = tx - r.x, dy = ty - r.y, d = Math.hypot(dx, dy); if (d &gt; v) { r.x += dx \/ d * v; r.y += dy \/ d * v; if (Math.abs(dx) &gt; 1) r.dir = dx &gt; 0 ? 1 : -1; return false; } r.x = tx; r.y = ty; return true; }&#10;    function sucesos() { return { gas: Mar.gas(), sis: Mar.sis() }; }   \/\/ causal: depende del estado real del agua, ya no hay sucesos programados&#10;    function huevo(r, t) {   \/\/ Itxas: robots-huevo amarillos, dibujados con detalle (casco con brillo, remaches, visor, aletas con h\u00e9lice y herramienta de su oficio)&#10;        const d = r.dir || 1, ph = t + r.f * 57; ctx.save(); ctx.translate(r.x, r.y + Math.sin(t \/ 18 + r.f) * 2.2); ctx.scale(1.35, 1.35); ctx.rotate(.08 * d); ctx.lineJoin = 'round'; ctx.lineCap = 'round'; ctx.strokeStyle = '#1a1200'; ctx.lineWidth = 1.3;&#10;        let g = ctx.createRadialGradient(0, 0, 6, 0, 0, 30); g.addColorStop(0, 'rgba(255,225,90,0.22)'); g.addColorStop(1, 'rgba(255,225,90,0)'); ctx.fillStyle = g; ctx.beginPath(); ctx.arc(0, 0, 30, 0, Math.PI * 2); ctx.fill();            \/\/ halo&#10;        for (let k = 0; k &lt; 3; k++) { const u = ((t * 0.9 + k * 13 + r.f * 9) % 38) \/ 38; ctx.fillStyle = 'rgba(225,246,255,' + (0.55 * (1 - u)).toFixed(2) + ')'; ctx.beginPath(); ctx.arc((k - 1) * 9 + Math.sin(t \/ 9 + k) * 2, 20 - u * 34, 1.2 + (k % 2), 0, Math.PI * 2); ctx.fill(); }   \/\/ burbujas del propulsor&#10;        ctx.beginPath(); ctx.moveTo(0, -20); ctx.lineTo(0, -28); ctx.stroke();                                                                                                                       \/\/ antena&#10;        const on = Math.sin(ph \/ 8) &gt; 0; ctx.fillStyle = on ? '#ff5252' : '#7a1f1f'; ctx.beginPath(); ctx.arc(0, -29.5, 2.8, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); if (on) { ctx.strokeStyle = 'rgba(255,90,90,0.45)'; ctx.beginPath(); ctx.arc(0, -29.5, 5.5, 0, Math.PI * 2); ctx.stroke(); ctx.strokeStyle = '#1a1200'; }&#10;        [-1, 1].forEach(sd =&gt; { ctx.save(); ctx.translate(sd * 15.5, 7); ctx.fillStyle = '#c98a00'; ctx.beginPath(); ctx.ellipse(0, 0, 4.2, 7.5, sd * .4, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.strokeStyle = 'rgba(60,40,0,0.7)'; ctx.lineWidth = 1; const a = Math.sin(t \/ 2.5 + sd) * 0.9; ctx.beginPath(); ctx.moveTo(-3 * Math.cos(a), -3 * Math.sin(a) + 7); ctx.lineTo(3 * Math.cos(a), 3 * Math.sin(a) + 7); ctx.stroke(); ctx.restore(); ctx.strokeStyle = '#1a1200'; ctx.lineWidth = 1.3; });   \/\/ aletas con h\u00e9lice&#10;        if (r.n === 'Robot limpiador') { ctx.strokeStyle = '#5b6770'; ctx.lineWidth = 3; ctx.beginPath(); ctx.moveTo(d * 14, 10); ctx.quadraticCurveTo(d * 24, 12, d * 25, 21); ctx.stroke(); ctx.fillStyle = '#2fd6c0'; ctx.strokeStyle = '#1a1200'; ctx.lineWidth = 1.2; ctx.beginPath(); ctx.roundRect(d * 25 - 5, 20, 10, 6, 2); ctx.fill(); ctx.stroke(); }&#10;        else if (r.n === 'Robot de aguas') { ctx.strokeStyle = '#5b6770'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(d * 15, 2); ctx.lineTo(d * 24, -8); ctx.stroke(); ctx.strokeStyle = '#1a1200'; ctx.fillStyle = '#4a7bd8'; ctx.lineWidth = 1.2; ctx.beginPath(); ctx.arc(d * 24, -9, 5, Math.PI * (d &gt; 0 ? 1.2 : -0.2), Math.PI * (d &gt; 0 ? 2.2 : 0.8)); ctx.lineTo(d * 24, -9); ctx.closePath(); ctx.fill(); ctx.stroke(); }&#10;        else if (r.n === 'Robot ge\u00f3logo') { ctx.strokeStyle = '#5b6770'; ctx.lineWidth = 3; ctx.beginPath(); ctx.moveTo(-d * 14, 9); ctx.lineTo(-d * 22, 17); ctx.stroke(); ctx.fillStyle = '#ff9f43'; ctx.strokeStyle = '#1a1200'; ctx.lineWidth = 1.2; ctx.beginPath(); ctx.moveTo(-d * 22, 12); ctx.lineTo(-d * 22, 23); ctx.lineTo(-d * 30, 17.5); ctx.closePath(); ctx.fill(); ctx.stroke(); }&#10;        else { ctx.strokeStyle = '#5b6770'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(d * 15, 4); ctx.lineTo(d * 22, -2); ctx.stroke(); ctx.strokeStyle = '#1a1200'; ctx.fillStyle = 'rgba(190,240,255,0.55)'; ctx.lineWidth = 1.2; ctx.beginPath(); ctx.arc(d * 25, -5, 5, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#7cdc5b'; ctx.beginPath(); ctx.ellipse(d * 25, -5, 2.4, 1.2, -0.6, 0, Math.PI * 2); ctx.fill(); }&#10;        ctx.strokeStyle = '#1a1200'; ctx.lineWidth = 1.3;&#10;        g = ctx.createRadialGradient(-6, -11, 2, 0, -2, 24); g.addColorStop(0, '#fff6b0'); g.addColorStop(0.45, '#ffd23f'); g.addColorStop(1, '#d99a00'); ctx.fillStyle = g;&#10;        ctx.beginPath(); ctx.moveTo(0, -21); ctx.bezierCurveTo(14, -21, 17, 2, 14, 11); ctx.bezierCurveTo(11, 20, -11, 20, -14, 11); ctx.bezierCurveTo(-17, 2, -14, -21, 0, -21); ctx.fill(); ctx.stroke();                                \/\/ cuerpo de huevo&#10;        ctx.strokeStyle = 'rgba(120,80,0,0.55)'; ctx.lineWidth = 0.9; ctx.beginPath(); ctx.moveTo(-13.5, 10); ctx.quadraticCurveTo(0, 15, 13.5, 10); ctx.moveTo(-8, -17); ctx.quadraticCurveTo(0, -20, 8, -17); ctx.stroke();           \/\/ juntas de las placas&#10;        ctx.fillStyle = '#8a5d00'; [[-9, 13], [9, 13], [0, 15.6], [-12, -3], [12, -3]].forEach(([x, y]) =&gt; { ctx.beginPath(); ctx.arc(x, y, 0.9, 0, Math.PI * 2); ctx.fill(); });     \/\/ remaches&#10;        ctx.fillStyle = 'rgba(255,255,255,0.65)'; ctx.beginPath(); ctx.ellipse(-8, -13, 2.6, 6, -.35, 0, Math.PI * 2); ctx.fill();                                                                                       \/\/ brillo&#10;        ctx.strokeStyle = '#1a1200'; ctx.lineWidth = 1.3; g = ctx.createLinearGradient(0, -9, 0, 3); g.addColorStop(0, '#16355c'); g.addColorStop(1, '#091a30'); ctx.fillStyle = g; ctx.beginPath(); ctx.roundRect(-10.5, -9, 21, 11, 5.5); ctx.fill(); ctx.stroke();   \/\/ visor&#10;        const he = (ph % 230) &lt; 7 ? 0.8 : 4.2; ctx.fillStyle = '#7cffd9'; ctx.shadowColor = '#7cffd9'; ctx.shadowBlur = 5; ctx.beginPath(); ctx.ellipse(-4, -3.5, 1.9, he \/ 2, 0, 0, Math.PI * 2); ctx.ellipse(4, -3.5, 1.9, he \/ 2, 0, 0, Math.PI * 2); ctx.fill(); ctx.shadowBlur = 0;   \/\/ ojos que parpadean&#10;        ctx.fillStyle = 'rgba(255,255,255,0.25)'; ctx.beginPath(); ctx.ellipse(-3, -7, 5, 1.2, -0.1, 0, Math.PI * 2); ctx.fill();&#10;        ctx.fillStyle = r.col; ctx.strokeStyle = '#1a1200'; ctx.lineWidth = 1; ctx.fillRect(-12.5, 6, 25, 3.2); ctx.strokeRect(-12.5, 6, 25, 3.2);                                                                         \/\/ cintur\u00f3n del oficio&#10;        ctx.fillStyle = Math.sin(ph \/ 12) &gt; -0.3 ? '#fff' : r.col; ctx.beginPath(); ctx.arc(8, 7.6, 1.1, 0, Math.PI * 2); ctx.fill();&#10;        ctx.restore();&#10;    }&#10;    function robotsHuevo(t, now, FO) {&#10;        const { gas, sis } = sucesos(now), vent = { x: 560, y: 478 };&#10;        if (gas &gt; .02) { ctx.fillStyle = `rgba(255,190,60,${.25 + .5 * gas})`; for (let i = 0; i &lt; 14; i++) { const k = ((t * 1.3 + i * 17) % 190) \/ 190; ctx.beginPath(); ctx.arc(vent.x + Math.sin(i * 2.1 + t \/ 15) * 10 * k, vent.y - k * 170, 2 + (i % 3), 0, Math.PI * 2); ctx.fill(); } }   \/\/ burbujas de metano&#10;        if (sis &gt; .02) for (let i = 0; i &lt; 3; i++) { const k = ((t * 2 + i * 40) % 120) \/ 120; ctx.strokeStyle = `rgba(255,120,80,${sis * (1 - k)})`; ctx.lineWidth = 3; ctx.beginPath(); ctx.ellipse(320, 486, 20 + k * 220, 4 + k * 22, 0, 0, Math.PI * 2); ctx.stroke(); }   \/\/ ondas s\u00edsmicas&#10;        const [L, A, G, V] = RB;&#10;        if (FO.b &gt; 0) {   \/\/ limpiador: va a la basura del fondo y la aspira&#10;            const sl = SLOTS[FO.b - 1];&#10;            if (mover(L, sl.x, sl.y - 24, 1.5)) { L.tm++; L.acc = 'aspira'; Mar.absorber(.0001); ctx.fillStyle = 'rgba(124,255,217,0.28)'; ctx.beginPath(); ctx.moveTo(L.x - 4, L.y + 14); ctx.lineTo(L.x + 4, L.y + 14); ctx.lineTo(sl.x + 10, sl.y); ctx.lineTo(sl.x - 10, sl.y); ctx.closePath(); ctx.fill();&#10;                if (L.tm &gt; 140 &amp;&amp; now - L.ult &gt; 10000) { L.tm = 0; L.ult = now; FO.b = Math.max(0, FO.b - 1); FO.s = Math.min(100, FO.s + 1.5); } } else { L.tm = 0; L.acc = 'va'; }&#10;        } else { L.acc = 'limpio'; mover(L, 480 + Math.sin(t \/ 260) * 340, 474, 1.2); }&#10;        mover(A, 480 + Math.sin(t \/ 400) * 380, 250 + Math.sin(t \/ 230) * 55, 1.1);                    \/\/ aguas: patrulla midiendo&#10;        for (let i = 0; i &lt; 2; i++) { const k = ((t + i * 45) % 90) \/ 90; ctx.strokeStyle = `rgba(160,220,255,${.5 * (1 - k)})`; ctx.lineWidth = 1.6; ctx.beginPath(); ctx.arc(A.x, A.y, 14 + k * 34, 0, Math.PI * 2); ctx.stroke(); }&#10;        const gx = gas &gt; .01 ? vent.x : 180 + (Math.sin(t \/ 500) + 1) * 300, gy = gas &gt; .01 ? vent.y - 28 : 456;   \/\/ ge\u00f3logo: vigila y sella fugas&#10;        if (mover(G, gx, gy, 1.4)) { ctx.strokeStyle = gas &gt; .01 ? '#7cffd9' : 'rgba(255,255,255,0.5)'; ctx.lineWidth = 2; ctx.beginPath(); ctx.moveTo(G.x, G.y + 18); ctx.lineTo(G.x, 482); ctx.stroke(); if (gas &gt; .01) { ctx.strokeStyle = `rgba(124,255,217,${.4 + .3 * Math.sin(t \/ 5)})`; ctx.beginPath(); ctx.arc(G.x, 480, 8 + (t % 20), 0, Math.PI * 2); ctx.stroke(); Mar.absorber(.0004); } }&#10;        const pv = VIDA[V.i];                                                                            \/\/ vida: revisa la salud de fauna y flora&#10;        if (mover(V, pv.x, pv.y - 26, 1.3)) { V.tm++; ctx.fillStyle = 'rgba(120,255,140,0.22)'; ctx.beginPath(); ctx.moveTo(V.x - 3, V.y + 12); ctx.lineTo(V.x + 3, V.y + 12); ctx.lineTo(pv.x + 22, pv.y + 6); ctx.lineTo(pv.x - 22, pv.y + 6); ctx.closePath(); ctx.fill(); if (V.tm &gt; 170) { V.tm = 0; V.i = (V.i + 1) % VIDA.length; } } else V.tm = 0;&#10;        const est = [L.acc === 'aspira' ? 'recogiendo basura' : L.acc === 'limpio' ? 'fondo limpio' : 'yendo a la basura', 'midiendo el agua', gas &gt; .01 ? 'sellando la fuga' : 'vigilando metano', 'revisando ' + pv.n + (V.tm &gt; 20 ? ' \ud83d\udc9a' : '')];&#10;        [L, A, G, V].forEach((r, i) =&gt; { huevo(r, t); mTxt(['\ud83e\uddf9', '\ud83e\uddea', gas &gt; .05 || sis &gt; .05 ? '\u26a0\ufe0f' : '\ud83d\udce1', '\ud83d\udc9a'][i], r.x, r.y - 56, 16, '#000', 'center'); vivos.push({ x: r.x, y: r.y, ly: r.y - 30, n: r.n, n2: est[i], r: 28 }); });&#10;    }&#10;    function panelRobots(t, now, FO) {   \/\/ panel de datos ambientales y alertas&#10;        const { gas, sis } = sucesos(now), M = Mar.get(), x = 700, y = 38, w = 252, h = 124, alerta = gas &gt; .05 || sis &gt; .05 || M.o2 &lt; 4.5;&#10;        mCaja(x, y, w, h, 10, 'rgba(6,20,45,0.74)', alerta ? '#ff9f43' : '#ffd23f', 1.6);&#10;        mTxt('\ud83e\udd5a Red de robots-huevo', x + w \/ 2, y + 13, 12, '#ffd23f', 'center');&#10;        const rows = [['Salinidad', M.sal.toFixed(1) + ' \u2030', M.sal &gt; 36.5 ? .6 : 0], ['Yodo', M.yodo.toFixed(0) + ' \u00b5g\/L', 0], ['Ox\u00edgeno', M.o2.toFixed(1) + ' mg\/L', M.o2 &lt; 4.5 ? .6 : M.o2 &lt; 5.5 ? .1 : 0], ['Metano', M.ch4.toFixed(1) + ' ppm', gas], ['S\u00edsmica', M.sis.toFixed(1) + ' mag', sis], ['Fauna y flora', FO.s &gt;= 40 ? 'sana' : 'vigilada', FO.s &gt;= 40 ? 0 : .1]];&#10;        rows.forEach(([a, b, v], i) =&gt; { const cx = x + 12 + (i % 2) * 122, cy = y + 34 + Math.floor(i \/ 2) * 25; mTxt(a, cx, cy, 10, '#9bc3e6', 'left'); mTxt(b, cx, cy + 12, 11.5, '#fff', 'left'); ctx.fillStyle = v &gt; .5 ? '#ff5252' : v &gt; .05 ? '#ffb300' : '#7cffd9'; ctx.beginPath(); ctx.arc(cx + 104, cy + 6, 4, 0, Math.PI * 2); ctx.fill(); });&#10;        mTxt(alerta ? '\u26a0 ' + (gas &gt; .05 ? 'Fuga de metano: robot ge\u00f3logo act\u00faa' : sis &gt; .05 ? 'Micro-vibraciones industriales' : 'Ox\u00edgeno bajo: calor y suciedad') : '\u2714 Todo en orden en el fondo marino', x + w \/ 2, y + h - 9, 10, alerta ? '#ff9f43' : '#7cffd9', 'center');&#10;    }&#10;    function pez(x, y, dir, s, col, raya) { ctx.fillStyle = col; ctx.beginPath(); ctx.ellipse(x, y, 7 * s, 3.4 * s, 0, 0, Math.PI * 2); ctx.moveTo(x - dir * 6 * s, y); ctx.lineTo(x - dir * 12 * s, y - 4 * s); ctx.lineTo(x - dir * 12 * s, y + 4 * s); ctx.closePath(); ctx.fill(); if (raya) { ctx.fillStyle = raya; ctx.fillRect(x - 3 * s, y - 2.4 * s, 1.6 * s, 4.8 * s); } ctx.fillStyle = '#10243f'; ctx.fillRect(x + dir * 4 * s - 0.6, y - 1.4 * s, 1.2 * s, 1.2 * s); }&#10;    function dibujar(t) {&#10;        if (!capa) construir(); const now = performance.now(), noche = !esDeDia(), FO = Puerto.FONDO, sal = FO.s, hf = 0.6 + 0.4 * sal \/ 100; vivos.length = 0; ctx.drawImage(capa, 0, 0);&#10;        if (sal &lt; 35) { ctx.fillStyle = `rgba(95,90,45,${0.2 * (1 - sal \/ 35)})`; ctx.fillRect(0, 0, W, SUELO); }                                            \/\/ agua turbia si el fondo est\u00e1 mal&#10;        if (!noche) { ctx.fillStyle = `rgba(255,255,230,${0.035 + 0.04 * sal \/ 100})`; for (let k = 0; k &lt; 6; k++) { const x = 70 + k * 150 + Math.sin(t \/ 200 + k) * 22; ctx.beginPath(); ctx.moveTo(x, 0); ctx.lineTo(x + 46, 0); ctx.lineTo(x + 46 - 140, SUELO); ctx.lineTo(x - 140, SUELO); ctx.closePath(); ctx.fill(); } }                                    \/\/ rayos de luz&#10;        ctx.fillStyle = 'rgba(255,255,255,0.32)'; ctx.fillRect(0, 0, W, 16); ctx.strokeStyle = 'rgba(255,255,255,0.85)'; ctx.lineWidth = 2.4; ctx.beginPath(); for (let x = 0; x &lt;= W; x += 30) { const y = 17 + Math.sin(x \/ 38 + t \/ 18) * 3; x ? ctx.lineTo(x, y) : ctx.moveTo(x, y); } ctx.stroke();                          \/\/ superficie vista desde abajo&#10;        ctx.fillStyle = 'rgba(10,50,90,0.6)'; ctx.fillRect(326, 14, 18, 20); ctx.beginPath(); ctx.ellipse(470, 20, 84, 9, 0, 0, Math.PI); ctx.fill(); ctx.beginPath(); ctx.ellipse(200, 20, 56, 8, 0, 0, Math.PI); ctx.fill();   \/\/ pont\u00f3n y cascos de los barcos&#10;        const bob = Math.sin(now \/ 520) * 1.6, bx = 380 + Math.sin(t \/ 60) * 2; ctx.fillStyle = '#ff9f43'; ctx.strokeStyle = '#000'; ctx.lineWidth = 1.6; ctx.beginPath(); ctx.arc(bx, 22 + bob, 5, 0, Math.PI * 2); ctx.fill(); ctx.stroke();&#10;        ctx.strokeStyle = 'rgba(230,230,210,0.85)'; ctx.lineWidth = 1.6; ctx.beginPath(); ctx.moveTo(bx, 27 + bob); ctx.quadraticCurveTo(bx + 16 * Math.sin(t \/ 90), 240, 380, SUELO - 2); ctx.stroke(); ctx.fillStyle = '#4a4f55'; ctx.fillRect(374, SUELO - 4, 12, 6);                                  \/\/ boya de buceo y su cuerda&#10;        KELP.forEach(k =&gt; { const y0 = k.x &lt; 300 ? 446 : 450; ctx.strokeStyle = '#6b4f1c'; ctx.lineWidth = 4; ctx.lineCap = 'round'; ctx.beginPath(); const n = 11, pts = [];&#10;            for (let i = 0; i &lt;= n; i++) { const f = i \/ n, sw = Math.sin(t \/ 55 + k.f + f * 2.2) * 16 * f * f; pts.push([k.x + sw, y0 - k.h * f]); i ? ctx.lineTo(pts[i][0], pts[i][1]) : ctx.moveTo(pts[i][0], pts[i][1]); } ctx.stroke();&#10;            ctx.fillStyle = '#a07a24'; ctx.beginPath(); for (let i = 2; i &lt;= n; i += 2) { const [px, py] = pts[i], s = i % 4 ? 1 : -1; ctx.moveTo(px + s * 22, py); ctx.ellipse(px + s * 11, py, 11, 4.4, s * 0.35 + Math.sin(t \/ 30 + i) * 0.1, 0, Math.PI * 2); } ctx.fill();&#10;            ctx.fillStyle = 'rgba(120,175,60,0.5)'; ctx.beginPath(); for (let i = 3; i &lt;= n; i += 4) { const [px, py] = pts[i]; ctx.moveTo(px - 3, py); ctx.ellipse(px - 9, py - 2, 7, 3, -0.3, 0, Math.PI * 2); } ctx.fill(); });&#10;        ctx.lineWidth = 3; [['#2f7d44', 0], ['#3f9a52', 1]].forEach(([col, cap]) =&gt; { ctx.strokeStyle = col; ctx.beginPath(); for (let x = 300 + cap * 14; x &lt;= 690; x += 28) { if ((x - 300) \/ 390 &gt; 0.3 + 0.7 * sal \/ 100) continue; for (let b = -2; b &lt;= 2; b++) { const h = (44 + ((x * 7 + b * 13) % 26)) * hf, bx = x + b * 3.2, sw = Math.sin(t \/ 40 + x \/ 50 + b) * 9; ctx.moveTo(bx, SUELO + 6 + cap * 10); ctx.quadraticCurveTo(bx + sw * 0.4, SUELO - h * 0.5, bx + sw, SUELO - h + cap * 10); } } ctx.stroke(); });&#10;        const dsp = Math.max(0, 1 - (now - dispersa) \/ 2200), cx = 480 + Math.sin(t \/ 420) * 360, cy = 215 + Math.sin(t \/ 310) * 55, dir = Math.cos(t \/ 420) &gt;= 0 ? 1 : -1;&#10;        for (let i = 0; i &lt; 8 + Math.floor(6 * sal \/ 100); i++) pez(cx + Math.cos(i * 1.7) * (30 + 90 * dsp) + (i % 3) * 5 * dsp * 6, cy + Math.sin(i * 2.3) * (16 + 70 * dsp) - dsp * 40, dir, 0.85, '#d6e8f2', null); vivos.push({ x: cx, y: cy, n: 'Banco de sardinas', r: 60 });&#10;        for (let i = 0; i &lt; 3; i++) { const dx = 230 + Math.sin(t \/ 300 + i * 2) * 120 + i * 140, dy = 380 + Math.sin(t \/ 170 + i) * 22, d = Math.cos(t \/ 300 + i * 2) &gt;= 0 ? 1 : -1; pez(dx, dy, d, 1.25, '#d9b44a', '#8a6a1c'); vivos.push({ x: dx, y: dy, n: 'Dorada', r: 22 }); }&#10;        const tp = ((t \/ 60) % 70) \/ 70, tx = lerp(-90, 1050, tp), ty = 290 + Math.sin(tp * 12) * 24, fl = Math.sin(t \/ 14) * 0.5;&#10;        ctx.save(); ctx.translate(tx, ty); ctx.fillStyle = '#7a8a3c'; ctx.strokeStyle = '#2d3516'; ctx.lineWidth = 1.8; [-1, 1].forEach(s =&gt; { ctx.save(); ctx.rotate(s * (0.6 + fl)); ctx.beginPath(); ctx.ellipse(6, s * 14, 14, 5, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.restore(); });&#10;        ctx.beginPath(); ctx.ellipse(0, 0, 24, 15, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.strokeStyle = 'rgba(40,50,20,0.7)'; ctx.beginPath(); ctx.moveTo(-14, 0); ctx.lineTo(14, 0); ctx.moveTo(0, -12); ctx.lineTo(0, 12); ctx.stroke(); ctx.fillStyle = '#9aa84e'; ctx.strokeStyle = '#2d3516'; ctx.beginPath(); ctx.ellipse(27, 0, 8, 6, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#10243f'; ctx.beginPath(); ctx.arc(30, -2, 1.4, 0, Math.PI * 2); ctx.fill(); ctx.restore(); vivos.push({ x: tx, y: ty, n: 'Tortuga boba', r: 34 });&#10;        [[300, 175, 0], [650, 140, 2.2]].forEach(([jx, jy, ph]) =&gt; { const p = Math.sin(t \/ 22 + ph), x = jx + Math.sin(t \/ 130 + ph) * 26, y = jy + Math.sin(t \/ 90 + ph) * 22; ctx.fillStyle = 'rgba(255,190,235,0.55)'; ctx.strokeStyle = 'rgba(255,255,255,0.75)'; ctx.lineWidth = 1.4; ctx.beginPath(); ctx.ellipse(x, y, 13, 9 + p * 2.4, 0, Math.PI, 0); ctx.closePath(); ctx.fill(); ctx.stroke();&#10;            ctx.strokeStyle = 'rgba(255,200,240,0.7)'; ctx.beginPath(); for (let k = -2; k &lt;= 2; k++) { ctx.moveTo(x + k * 5, y); ctx.quadraticCurveTo(x + k * 5 + Math.sin(t \/ 15 + k) * 4, y + 12, x + k * 6, y + 22 + p * 3); } ctx.stroke(); resplandor(x, y, 24, '255,160,230', noche ? 0.55 : 0.18); vivos.push({ x, y, n: 'Medusa luminosa', r: 22 }); });&#10;        const bl = (t % 240) &gt; 8 ? 1 : 0.1; ctx.fillStyle = '#c0523a'; ctx.strokeStyle = '#5a1d12'; ctx.lineWidth = 1.6; ctx.beginPath(); ctx.ellipse(90, 436, 13, 11, 0, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.fillStyle = '#fff'; [-5, 5].forEach(dx =&gt; { ctx.beginPath(); ctx.ellipse(90 + dx, 434, 3.6, 3.6 * bl, 0, 0, Math.PI * 2); ctx.fill(); }); ctx.fillStyle = '#10243f'; [-5, 5].forEach(dx =&gt; { ctx.beginPath(); ctx.arc(90 + dx + 0.8, 434, 1.4, 0, Math.PI * 2); ctx.fill(); });&#10;        ctx.strokeStyle = '#c0523a'; ctx.lineWidth = 4; ctx.lineCap = 'round'; ctx.beginPath(); ctx.moveTo(100, 442); ctx.quadraticCurveTo(122, 448 + Math.sin(t \/ 25) * 6, 132, 460); ctx.stroke(); vivos.push({ x: 90, y: 436, n: 'Pulpo', r: 26 });&#10;        const kx = 520 + Math.sin(t \/ 700) * 70, ky = 484; ctx.fillStyle = '#d98c5f'; ctx.strokeStyle = '#6b3a1c'; ctx.lineWidth = 1.4; ctx.beginPath(); ctx.arc(kx, ky - 6, 7, 0, Math.PI * 2); ctx.fill(); ctx.stroke(); ctx.strokeStyle = '#c0523a'; ctx.lineWidth = 1.8; ctx.beginPath(); for (let i = -2; i &lt;= 2; i++) { ctx.moveTo(kx + i * 3, ky); ctx.lineTo(kx + i * 4, ky + 5 + Math.sin(t \/ 8 + i) * 1.4); } ctx.stroke(); vivos.push({ x: kx, y: ky - 4, n: 'Cangrejo ermita\u00f1o', r: 18 });&#10;        basuraYBuzos(t, now, FO); robotsHuevo(t, now, FO);                                                                                                       \/\/ basura del fondo y vecinas buceando&#10;        ctx.fillStyle = 'rgba(255,255,255,0.55)'; ctx.strokeStyle = 'rgba(255,255,255,0.8)'; ctx.lineWidth = 1; ctx.beginPath(); for (let i = 0; i &lt; 26; i++) { const sp = 0.5 + (i % 5) * 0.12, y = H - ((t * sp * 1.6 + i * 53) % (H + 30)), x = ((i * 37) % 900) + 30 + Math.sin(t \/ 30 + i) * 6, r = 1.5 + (i % 3); ctx.moveTo(x + r, y); ctx.arc(x, y, r, 0, Math.PI * 2); } ctx.fill(); ctx.stroke();       \/\/ burbujas&#10;        ctx.fillStyle = 'rgba(255,255,255,0.4)'; ctx.beginPath(); for (let i = 0; i &lt; 24; i++) ctx.rect(((i * 97 + t * 0.15) % W), ((i * 61 + t * 0.08) % SUELO), 1.6, 1.6); ctx.fill();                                                                                       \/\/ nieve marina&#10;        if (noche) { ctx.fillStyle = 'rgba(4,10,40,0.5)'; ctx.fillRect(0, 0, W, H); for (let i = 0; i &lt; 16; i++) resplandor(((i * 211 + t * 0.4) % W), 120 + ((i * 97) % 300), 9, '120,255,220', 0.35 + 0.25 * Math.sin(t \/ 15 + i)); }                                         \/\/ de noche: plancton luminoso&#10;        panelRobots(t, now, FO);                                                                                  \/\/ datos ambientales y alertas de los robots-huevo&#10;        if (etiqueta) {&#10;            const a = 1 - (now - etiqueta.t0) \/ 2600;&#10;            if (a &lt;= 0) etiqueta = null;&#10;            else {   \/\/ caja de ancho din\u00e1mico: nunca recorta el texto y siempre queda dentro de la pantalla&#10;                ctx.save(); ctx.globalAlpha = Math.min(1, a * 1.6);&#10;                ctx.font = `bold 12px ${FUENTE_MERCADO}`; const w1 = ctx.measureText(etiqueta.n).width; ctx.font = `11px ${FUENTE_MERCADO}`; const w2 = etiqueta.n2 ? ctx.measureText(etiqueta.n2).width : 0;&#10;                const bw = Math.max(w1, w2) + 26, bh = etiqueta.n2 ? 42 : 26, bx = Math.max(6, Math.min(954 - bw, etiqueta.x - bw \/ 2)), by = etiqueta.y - 26 - bh;&#10;                mCaja(bx, by, bw, bh, 12, 'rgba(255,255,255,0.95)', '#1b8fb8', 2);&#10;                mTxt(etiqueta.n, bx + bw \/ 2, by + (etiqueta.n2 ? 14 : 13), 12, '#16456b', 'center', true); if (etiqueta.n2) mTxt(etiqueta.n2, bx + bw \/ 2, by + 30, 11, '#2f6f8f', 'center');&#10;                ctx.restore();&#10;            }&#10;        }&#10;    }&#10;    function toque(x, y) {&#10;        if (dentroRect(x, y, SALIDA)) { iniciarTransicion(() =&gt; { enSubmarino = false; enPuerto = true; }); return; }&#10;        let mejor = null, md = 1e9; vivos.concat(NOMBRES).forEach(v =&gt; { const d = Math.hypot(v.x - x, v.y - y); if (d &lt; v.r + 12 &amp;&amp; d &lt; md) { md = d; mejor = v; } });&#10;        if (!mejor) { const sl = SLOTS.slice(0, Puerto.FONDO.b).find(q =&gt; Math.hypot(q.x - x, q.y - 6 - y) &lt; 20); if (sl) mejor = { x: sl.x, y: sl.y - 14, n: 'Basura del fondo' }; }&#10;        if (!mejor) { if (x &gt; 300 &amp;&amp; x &lt; 700 &amp;&amp; y &gt; 400 &amp;&amp; y &lt; SUELO + 10) mejor = { x: 500, y: 440, n: 'Pradera de posidonia' }; else if (KELP.some(k =&gt; Math.abs(k.x - x) &lt; 26 &amp;&amp; y &gt; 450 - k.h &amp;&amp; y &lt; 456)) mejor = { x, y, n: 'Bosque de algas pardas' }; }&#10;        if (mejor &amp;&amp; mejor.n !== 'Basura del fondo') diarioNota('fauna', mejor.n, mejor.n, '\ud83d\udc1a');&#10;        if (mejor) { etiqueta = { x: Math.max(30, Math.min(930, mejor.x)), y: Math.max(70, mejor.ly || mejor.y), n: mejor.n, n2: mejor.n2, t0: performance.now() }; if (mejor.n === 'Banco de sardinas') dispersa = performance.now(); }&#10;    }&#10;    return { dibujar, actualizar() {}, toque };&#10;})();&#10;vidaLista = true; habitantes.forEach(h =&gt; { if (h.estado === 'caminando') nuevoObjetivo(h); });           \/\/ a partir de ahora (con la biblioteca ya definida), todas planean su d\u00eda&#10;function bucleInterno() {&#10;    t++;&#10;    gestionarSue\u00f1oNocturno();&#10;    actualizarNav(); actualizarChipFiesta(); Radio.tick(); Memoria.tick(performance.now()); Mar.tick(performance.now()); Cronica.tick(performance.now()); SonidoZona.tick(performance.now()); Seguir.tick();&#10;    Industria.actualizar(performance.now()); Apicultura.tick(performance.now()); Kutxa.tick(performance.now()); KutxaPanel.tick(); Desgaste.tick(performance.now()); SiloCompost.tick(performance.now()); Puerto.tick(performance.now()); Costa.tick(performance.now()); Comidas.tick(performance.now()); Noticias.tick(performance.now()); Fiestas2.tick(); Conmemoraciones.tick(); Ayuda.tick(); Diario.tick();     \/\/ la producci\u00f3n contin\u00faa aunque est\u00e9s en otra pantalla&#10;    ctx.clearRect(0, 0, canvas.width, canvas.height);&#10;    if (fadeSubiendo) {&#10;        fadeAlpha = Math.min(1, fadeAlpha + 0.09);&#10;        if (fadeAlpha &gt;= 1) {&#10;            if (fadeAccion) { fadeAccion(); fadeAccion = null; }&#10;            fadeSubiendo = false;&#10;        }&#10;    } else if (fadeAlpha &gt; 0) {&#10;        fadeAlpha = Math.max(0, fadeAlpha - 0.09);&#10;    }&#10;    if (casaAbierta !== null) {&#10;        if (temporizadorInterior &gt; 0) {&#10;            temporizadorInterior--;&#10;            if (temporizadorInterior &lt;= 0) interiorEstado = 'de_pie';&#10;        }&#10;        dibujarInterior(casas[casaAbierta], t);&#10;    } else if (enSubmarino) {&#10;        Submarino.dibujar(t);&#10;    } else if (enPuerto) {&#10;        Puerto.actualizar();&#10;        Puerto.dibujar(t);&#10;    } else if (enBiblioteca) {&#10;        Biblioteca.actualizar();&#10;        Biblioteca.dibujar(t);&#10;    } else if (enHospital) {&#10;        Hospital.dibujar(t);&#10;    } else if (enArena) {&#10;        Arena.dibujar(t);&#10;    } else if (enGimnasio) {&#10;        GimnasioPueblo.sincronizar(); Biblioteca.actualizar();&#10;        gimnasioChicas.forEach(c =&gt; {&#10;            if (c.temporizador &gt; 0) {&#10;                c.temporizador--;&#10;                if (c.temporizador &lt;= 0) { c.estado = 'de_pie'; c.zonaActiva = null; }&#10;            }&#10;        });&#10;        GimnasioVida.actualizar();&#10;        dibujarGimnasio(t);&#10;    } else if (enPlaya) {&#10;        nochePlaya = !esDeDia();   \/\/ la playa sigue la hora real&#10;        actualizarPlaya();&#10;        dibujarPlaya(t);&#10;        dibujarFiestaPlaya(t);&#10;    } else if (enIndustria) {&#10;        Industria.dibujar();&#10;    } else if (enMercado) {&#10;        actualizarMercado();&#10;        dibujarMercado(t);&#10;    } else if (enHuerta) {&#10;        actualizarHuerta();&#10;        dibujarHuerta(t);&#10;        HuertaBot.dibujar(t);&#10;    } else {&#10;        dibujarPueblo();&#10;    }&#10;    Dia.aplicar();&#10;    if (Tiempo) Tiempo.dibujar();&#10;    Seguir.dibujar();&#10;    if (fadeAlpha &gt; 0) {&#10;        ctx.fillStyle = `rgba(0,0,0,${fadeAlpha})`;&#10;        ctx.fillRect(0, 0, canvas.width, canvas.height);&#10;    }&#10;}&#10;function coordenadasClic(e) {&#10;    const rect = canvas.getBoundingClientRect(), bx = canvas.clientLeft || 0, by = canvas.clientTop || 0;&#10;    const escalaX = canvas.width \/ Math.max(1, rect.width - 2 * bx);&#10;    const escalaY = canvas.height \/ Math.max(1, rect.height - 2 * by);&#10;    return { x: (e.clientX - rect.left - bx) * escalaX, y: (e.clientY - rect.top - by) * escalaY };&#10;}&#10;let habitanteArrastrada = null;&#10;let arrastrandoInterior = false;&#10;canvas.style.touchAction = 'none';&#10;canvas.addEventListener('pointerdown', (e) =&gt; {&#10;    const { x, y } = coordenadasClic(e);&#10;    if (casaAbierta !== null) {&#10;        if (tocoZonaVolver(x, y)) { salirDeEscena(); return; }&#10;        if (manejarToqueHologramaPedido(x, y)) return;&#10;        if (!posInterior) posInterior = { x: ANCHO_PRINCIPAL * 0.5, y: canvas.height * 0.86 };&#10;        posInterior.x = Math.max(55, Math.min(canvas.width - 55, x));&#10;        posInterior.y = Math.max(75, Math.min(canvas.height - 55, y - 10));&#10;        arrastrandoInterior = true;&#10;        interiorEstado = 'de_pie';&#10;        temporizadorInterior = 0;&#10;        canvas.setPointerCapture(e.pointerId);&#10;        return;&#10;    }&#10;    if (enHospital) { Hospital.toque(x, y, e); return; }&#10;    if (enArena) { Arena.toque(x, y, e); return; }&#10;    if (enSubmarino) { Submarino.toque(x, y); return; }&#10;    if (enPuerto) { Puerto.toque(x, y); return; }&#10;    if (enBiblioteca) { Biblioteca.toque(x, y); return; }&#10;    if (enGimnasio) {&#10;        if (tocoZonaVolver(x, y)) { salirDeEscena(); return; }&#10;        let mejorChica = null, mejorDistChica = 40;&#10;        gimnasioChicas.forEach(c =&gt; {&#10;            const d = Math.hypot(c.x - x, c.y - (y + 10));&#10;            if (d &lt; mejorDistChica) { mejorChica = c; mejorDistChica = d; }&#10;        });&#10;        if (!mejorChica &amp;&amp; !gimnasioChicas.length) return;&#10;        chicaGimnasioArrastrada = mejorChica || gimnasioChicas[0];&#10;        chicaGimnasioArrastrada.x = Math.max(50, Math.min(canvas.width - 50, x));&#10;        chicaGimnasioArrastrada.y = Math.max(80, Math.min(canvas.height - 30, y - 10));&#10;        chicaGimnasioArrastrada.estado = 'de_pie';&#10;        chicaGimnasioArrastrada.zonaActiva = null;&#10;        chicaGimnasioArrastrada.temporizador = 0;&#10;        arrastrandoGimnasio = true;&#10;        canvas.setPointerCapture(e.pointerId);&#10;        return;&#10;    }&#10;    if (enPlaya) {&#10;        if (tocoZonaVolver(x, y)) { salirDeEscena(); return; }&#10;        if (Puerto.tocoMuelle(x, y)) { iniciarTransicion(() =&gt; { enPlaya = false; enPuerto = true; }); return; }          \/\/ \u2693 entra al puerto&#10;        if (dentroRect(x, y, NOCHE_BOTON)) { \/* la noche sigue la hora real *\/ return; }          \/\/ \ud83c\udf19 modo noche&#10;        const climaTocado = tocoZonaClima(x, y);&#10;        if (climaTocado) { climaPlaya = climaTocado; return; }&#10;        let chica = null, distMin = 46;&#10;        habitantesEnPlaya.forEach(h =&gt; {&#10;            if (!h.posPlaya) return;&#10;            const d = Math.hypot(h.posPlaya.x - x, h.posPlaya.y - y);&#10;            if (d &lt; distMin) { distMin = d; chica = h; }&#10;        });&#10;        if (chica) {&#10;            chica.posPlaya.x = Math.max(40, Math.min(canvas.width - 40, x));&#10;            chica.posPlaya.y = Math.max(100, Math.min(canvas.height - 20, y - 10));&#10;            chica.playaEstado = 'de_pie';&#10;            chica.zonaPlaya = null;&#10;            chica.horaEntradaAgua = 0;&#10;            arrastrandoPlaya = chica;&#10;            canvas.setPointerCapture(e.pointerId);&#10;        }&#10;        return;&#10;    }&#10;    if (Noticias.abierto()) { Noticias.toque(x, y); return; }                        \/\/ el tabl\u00f3n tambi\u00e9n es modal&#10;    if (KutxaPanel.abierto()) { KutxaPanel.toque(x, y); return; }                    \/\/ el panel de la Kutxa es modal&#10;    if (enIndustria) { Industria.toque(x, y); return; }&#10;    if (enMercado) { manejarToqueMercado(x, y); return; }&#10;    if (enHuerta) {&#10;        if (tocoZonaVolver(x, y)) { iniciarTransicion(() =&gt; salirDeEscena()); return; }&#10;        if (dentroRect(x, y, MERCADO_BOTON)) { iniciarTransicion(entrarAlMercado); return; }&#10;        manejarToqueHuerta(x, y);&#10;        return;&#10;    }&#10;    if (Math.hypot(x - zonaAltavoz.x, y - zonaAltavoz.y) &lt; zonaAltavoz.radio + 6) {&#10;        alternarSonido();&#10;        return;&#10;    }&#10;    let mejor = null, mejorDist = (typeof e !== 'undefined' &amp;&amp; e &amp;&amp; (e.pointerType === 'touch' || e.pointerType === 'pen')) ? 68 : 48;   \/\/ zona de toque ampliada para dedos&#10;    habitantes.forEach(h =&gt; {&#10;        if (h.oculta) return;&#10;        const d = Math.hypot(h.x - x, h.y - (y + 10));&#10;        if (d &lt; mejorDist) { mejor = h; mejorDist = d; }&#10;    });&#10;    if (mejor &amp;&amp; Seguir.toque(mejor)) { return; }                                   \/\/ doble toque: seguir a esa chica (o soltarla)&#10;    if (mejor) {&#10;        habitanteArrastrada = mejor;&#10;        mejor.arrastrando = true;&#10;        mejor.estado = 'caminando';&#10;        if (esperandoMercadillo === mejor) esperandoMercadillo = null;&#10;        if (esperandoFrutas === mejor) esperandoFrutas = null;&#10;        canvas.setPointerCapture(e.pointerId);&#10;        return;&#10;    }&#10;    if (dentroRect(x, y, KutxaPanel.zonaCofre)) { KutxaPanel.abrir(); return; }&#10;    if (Noticias.tocoTablon(x, y)) { Noticias.abrir(); return; }                       \/\/ lee el tabl\u00f3n de noticias&#10;    { const b = BIBLIOTECA, by = SUELO_Y + 55;&#10;      if (x &gt;= b.x - 6 &amp;&amp; x &lt;= b.x + b.ancho + 6 &amp;&amp; y &gt;= by - b.alto - b.ancho * 0.3 - 30 &amp;&amp; y &lt;= by) { iniciarTransicion(() =&gt; { enBiblioteca = true; }); return; } }&#10;    if (x &gt;= TREN.x - (typeof offVagon === 'function' ? offVagon(TREN.n) : 170) - 50 &amp;&amp; x &lt;= TREN.x + 50 &amp;&amp; y &gt;= TRANVIA.y - 48 &amp;&amp; y &lt;= TRANVIA.y + 14) { irAPantalla('playa'); return; }&#10;    if (x &gt;= HOSPITAL_PARADA.x - 76 &amp;&amp; x &lt;= HOSPITAL_PARADA.x + 76 &amp;&amp; y &gt;= HOSPITAL_PARADA.y - 34 &amp;&amp; y &lt;= HOSPITAL_PARADA.y + 26) { irAPantalla('hospital'); return; }&#10;    if (x &gt;= ARENA_PARADA.x - 76 &amp;&amp; x &lt;= ARENA_PARADA.x + 76 &amp;&amp; y &gt;= ARENA_PARADA.y - 34 &amp;&amp; y &lt;= ARENA_PARADA.y + 26) { irAPantalla('arena'); return; }&#10;    { const b = INDUSTRIA_EDIFICIO, by = SUELO_Y + 55;&#10;      if (x &gt;= b.x - 6 &amp;&amp; x &lt;= b.x + b.ancho + 6 &amp;&amp; y &gt;= by - b.alto - 25 &amp;&amp; y &lt;= by) { iniciarTransicion(entrarAIndustria); return; } }&#10;    const gBaseY = SUELO_Y + 55;&#10;    const g = GIMNASIO_EDIFICIO;&#10;    if (x &gt;= g.x - 10 &amp;&amp; x &lt;= g.x + g.ancho + 10 &amp;&amp; y &gt;= gBaseY - g.alto - 30 &amp;&amp; y &lt;= gBaseY) {&#10;        enGimnasio = true;&#10;        entrarAlGimnasio();&#10;        return;&#10;    }&#10;    if (Math.hypot(x - ZONA_ENTRADA_HUERTA.x, y - ZONA_ENTRADA_HUERTA.y) &lt; ZONA_ENTRADA_HUERTA.radio) {&#10;        iniciarTransicion(() =&gt; { enHuerta = true; entrarALaHuerta(); });&#10;        return;&#10;    }&#10;    const baseY = SUELO_Y + 55;&#10;    for (let i = 0; i &lt; casas.length; i++) {&#10;        const c = casas[i];&#10;        if (x &gt;= c.x - 10 &amp;&amp; x &lt;= c.x + c.ancho + 10 &amp;&amp; y &gt;= baseY - c.alto - c.ancho * 0.45 &amp;&amp; y &lt;= baseY) {&#10;            casaAbierta = i;&#10;            posInterior = null;&#10;            interiorEstado = 'de_pie';&#10;            temporizadorInterior = 0;&#10;            sosteniendoEscoba = false;&#10;            motasSuciedad = [];&#10;            return;&#10;        }&#10;    }&#10;});&#10;canvas.addEventListener('pointermove', (e) =&gt; {&#10;    const { x, y } = coordenadasClic(e);&#10;    if (arrastrandoInterior &amp;&amp; posInterior) {&#10;        posInterior.x = Math.max(55, Math.min(canvas.width - 55, x));&#10;        posInterior.y = Math.max(75, Math.min(canvas.height - 55, y - 10));&#10;        if (sosteniendoEscoba) {&#10;            motasSuciedad.forEach(m =&gt; {&#10;                if (!m.limpia &amp;&amp; Math.hypot(posInterior.x - m.x, posInterior.y - m.y) &lt; 34) {&#10;                    m.limpia = true;&#10;                }&#10;            });&#10;        }&#10;        return;&#10;    }&#10;    if (arrastrandoGimnasio &amp;&amp; chicaGimnasioArrastrada) {&#10;        chicaGimnasioArrastrada.x = Math.max(50, Math.min(canvas.width - 50, x));&#10;        chicaGimnasioArrastrada.y = Math.max(80, Math.min(canvas.height - 30, y - 10));&#10;        return;&#10;    }&#10;    if (arrastrandoPlaya &amp;&amp; arrastrandoPlaya.posPlaya) {&#10;        arrastrandoPlaya.posPlaya.x = Math.max(40, Math.min(canvas.width - 40, x));&#10;        arrastrandoPlaya.posPlaya.y = Math.max(100, Math.min(canvas.height - 20, y - 10));&#10;        return;&#10;    }&#10;    if (!habitanteArrastrada) return;&#10;    habitanteArrastrada.x = Math.max(30, Math.min(930, x));&#10;    habitanteArrastrada.y = Math.max(SUELO_Y + 60, Math.min(canvas.height - 10, y - 10));&#10;});&#10;let arrastrandoGimnasio = false;&#10;let arrastrandoPlaya = false;&#10;function soltarMu\u00f1eca() {&#10;    if (arrastrandoPlaya &amp;&amp; arrastrandoPlaya.posPlaya) {&#10;        const chica = arrastrandoPlaya;&#10;        let zonaCercana = null, distMin = 60;&#10;        ZONAS_PLAYA.forEach(z =&gt; {&#10;            if (habitantesEnPlaya.some(o =&gt; o !== chica &amp;&amp; o.zonaPlaya === z)) return;&#10;            const d = Math.hypot(chica.posPlaya.x - z.x, chica.posPlaya.y - z.y);&#10;            if (d &lt; distMin) { zonaCercana = z; distMin = d; }&#10;        });&#10;        chica.playaEstado = zonaCercana ? zonaCercana.accion : 'de_pie';&#10;        chica.zonaPlaya = zonaCercana;&#10;        const esAgua = zonaCercana &amp;&amp; (zonaCercana.accion === 'surfeando' || zonaCercana.accion === 'windsurf');&#10;        chica.horaEntradaAgua = (esAgua || (zonaCercana &amp;&amp; zonaCercana.dur)) ? Date.now() : 0;&#10;        if (!zonaCercana) { chica.objetivoPlaya = null; chica.esperaPlaya = 30; }&#10;        arrastrandoPlaya = false;&#10;        return;&#10;    }&#10;    if (arrastrandoGimnasio &amp;&amp; chicaGimnasioArrastrada) {&#10;        const c = chicaGimnasioArrastrada;&#10;        let zonaCercana = null, distMin = 60;&#10;        ZONAS_GIMNASIO.forEach(z =&gt; {&#10;            if ((z.accion === 'pedaleando' || z.unica) &amp;&amp; gimnasioChicas.some(o =&gt; o !== c &amp;&amp; o.zonaActiva === z)) return;&#10;            const d = Math.hypot(c.x - z.x, c.y - z.y);&#10;            if (d &lt; distMin) { zonaCercana = z; distMin = d; }&#10;        });&#10;        if (zonaCercana) {&#10;            c.x = zonaCercana.x;&#10;            c.y = zonaCercana.y + (zonaCercana.accion === 'nadando' ? 0 : 25);&#10;            c.estado = zonaCercana.accion;&#10;            c.zonaActiva = zonaCercana;&#10;            c.temporizador = Infinity;&#10;        } else {&#10;            c.estado = 'de_pie';&#10;            c.zonaActiva = null;&#10;            c.temporizador = 0;&#10;        }&#10;        arrastrandoGimnasio = false;&#10;        chicaGimnasioArrastrada = null;&#10;        return;&#10;    }&#10;    if (arrastrandoInterior &amp;&amp; posInterior) {&#10;        let zonaCercana = null, distMin = 65;&#10;        ZONAS_INTERIOR.forEach(z =&gt; {&#10;            const d = Math.hypot(posInterior.x - z.x, posInterior.y - z.y);&#10;            if (d &lt; distMin) { zonaCercana = z; distMin = d; }&#10;        });&#10;        if (zonaCercana === ZONA_ESCOBA) {&#10;            sosteniendoEscoba = true;&#10;            interiorEstado = 'de_pie';&#10;            temporizadorInterior = 0;&#10;        } else if (zonaCercana) {&#10;            posInterior.x = zonaCercana.x;&#10;            posInterior.y = zonaCercana.y + 10;&#10;            interiorEstado = zonaCercana.accion;&#10;            temporizadorInterior = 220 + Math.random() * 120;&#10;            if (zonaCercana === ZONA_CAMILLA) { temporizadorInterior = 1e9; chequeoInicio = Date.now(); chequeoFin = 0; chequeoRes = null; }   \/\/ 45 s en tiempo real&#10;            if (zonaCercana === ZONA_MOCHILA) temporizadorInterior = 600;                                                  \/\/ mensaje ~10 s&#10;        } else {&#10;            interiorEstado = 'de_pie';&#10;            temporizadorInterior = 0;&#10;        }&#10;    }&#10;    arrastrandoInterior = false;&#10;    if (!habitanteArrastrada) return;&#10;    const h = habitanteArrastrada;&#10;    h.arrastrando = false; h.felizHasta = t + 260; diarioNota('momentos', 'cuidado', 'Una chica sonri\u00f3 porque la acompa\u00f1aste', '\ud83d\udc9c');      \/\/ se nota que cuidas: sonr\u00ede y suelta un coraz\u00f3n&#10;    const pxM = MERCADILLO.baseX + MERCADILLO.ancho \/ 2, pyM = MERCADILLO.baseY + MERCADILLO.alto, fM = escalaProf(pyM);&#10;    const escM = (v, p) =&gt; p + (v - p) * fM;&#10;    const enZonaMercadillo = h.x &gt;= escM(MERCADILLO.baseX - 10, pxM) &amp;&amp; h.x &lt;= escM(MERCADILLO.baseX + MERCADILLO.ancho + 10, pxM) &amp;&amp;&#10;                              h.y &gt;= escM(MERCADILLO.baseY - 30, pyM) &amp;&amp; h.y &lt;= escM(MERCADILLO.baseY + MERCADILLO.alto + 10, pyM);&#10;    if (enZonaMercadillo) {&#10;        if (h.patinete) { h.patinete.montadaPor = null; h.patinete = null; }&#10;        const centroX = MERCADILLO.baseX + MERCADILLO.ancho \/ 2;&#10;        const filaY = escM(MERCADILLO.baseY + 18, pyM);&#10;        if (esperandoMercadillo &amp;&amp; esperandoMercadillo !== h) {&#10;            const otra = esperandoMercadillo;&#10;            h.x = centroX + 15; h.y = filaY;&#10;            otra.x = centroX - 15; otra.y = filaY;&#10;            h.estado = 'mercadillo'; otra.estado = 'mercadillo';&#10;            h.inicioMercadillo = otra.inicioMercadillo = Date.now();&#10;            esperandoMercadillo = null;&#10;        } else {&#10;            h.x = centroX; h.y = filaY;&#10;            h.estado = 'mercadillo_esperando';&#10;            esperandoMercadillo = h;&#10;        }&#10;        habitanteArrastrada = null;&#10;        return;&#10;    }&#10;    if (Math.hypot(h.x - ZONA_PUESTOFRUTA.x, h.y - ZONA_PUESTOFRUTA.y) &lt; ZONA_PUESTOFRUTA.radio) {&#10;        if (h.patinete) { h.patinete.montadaPor = null; h.patinete = null; }&#10;        const filaY = ZONA_PUESTOFRUTA.y + 14;&#10;        if (esperandoFrutas &amp;&amp; esperandoFrutas !== h) {&#10;            const otra = esperandoFrutas;&#10;            h.x = ZONA_PUESTOFRUTA.x + 13; h.y = filaY;&#10;            otra.x = ZONA_PUESTOFRUTA.x - 13; otra.y = filaY;&#10;            h.estado = 'frutas'; otra.estado = 'frutas';&#10;            h.inicioFrutas = otra.inicioFrutas = Date.now();&#10;            esperandoFrutas = null;&#10;        } else {&#10;            h.x = ZONA_PUESTOFRUTA.x; h.y = filaY;&#10;            h.estado = 'frutas_esperando';&#10;            esperandoFrutas = h;&#10;        }&#10;        habitanteArrastrada = null;&#10;        return;&#10;    }&#10;    let sillaTerraza = null, distSilla = 34;&#10;    ZONAS_TERRAZA_ASIENTOS.forEach(s =&gt; {&#10;        const ocupada = habitantes.some(o =&gt; o !== h &amp;&amp; o.estado === 'sentada' &amp;&amp; Math.abs(o.x - s.x) &lt; 8 &amp;&amp; Math.abs(o.y - s.y) &lt; 8);&#10;        if (ocupada) return;&#10;        const d = Math.hypot(h.x - s.x, h.y - s.y);&#10;        if (d &lt; distSilla) { sillaTerraza = s; distSilla = d; }&#10;    });&#10;    if (sillaTerraza) {&#10;        if (h.patinete) { h.patinete.montadaPor = null; h.patinete = null; }&#10;        h.x = sillaTerraza.x;&#10;        h.y = sillaTerraza.y;&#10;        h.estado = 'sentada';&#10;        h.temporizador = 2700;&#10;        habitanteArrastrada = null;&#10;        return;&#10;    }&#10;    let asientoBiblioteca = null, distBiblio = 34;&#10;    BIBLIOTECA_ASIENTOS.forEach(s =&gt; {&#10;        const ocupada = habitantes.some(o =&gt; o !== h &amp;&amp; o.estado === 'leyendo' &amp;&amp; Math.abs(o.x - s.x) &lt; 8 &amp;&amp; Math.abs(o.y - s.y) &lt; 8);&#10;        if (ocupada) return;&#10;        const d = Math.hypot(h.x - s.x, h.y - s.y);&#10;        if (d &lt; distBiblio) { asientoBiblioteca = s; distBiblio = d; }&#10;    });&#10;    if (asientoBiblioteca) {&#10;        if (h.patinete) { h.patinete.montadaPor = null; h.patinete = null; }&#10;        h.x = asientoBiblioteca.x;&#10;        h.y = asientoBiblioteca.y;&#10;        h.estado = 'leyendo';&#10;        h.temporizador = 2700;&#10;        habitanteArrastrada = null;&#10;        return;&#10;    }&#10;    let bancoCercano = null, distMin = 40, asientoElegido = null;&#10;    bancos.forEach(b =&gt; {&#10;        const centroX = b.x + 23, centroY = b.y - 10;&#10;        const d = Math.hypot(h.x - centroX, h.y - centroY);&#10;        if (d &lt; distMin) {&#10;            bancoCercano = b;&#10;            distMin = d;&#10;            const izqOcupada = habitantes.some(o =&gt; o !== h &amp;&amp; o.estado === 'sentada' &amp;&amp; Math.abs(o.x - (b.x + 11)) &lt; 6);&#10;            asientoElegido = izqOcupada ? b.x + 35 : b.x + 11;&#10;        }&#10;    });&#10;    if (bancoCercano) {&#10;        if (h.patinete) { h.patinete.montadaPor = null; h.patinete = null; }&#10;        h.x = asientoElegido;&#10;        h.y = bancoCercano.y - 6;&#10;        h.estado = 'sentada';&#10;        h.temporizador = 2700;&#10;        habitanteArrastrada = null;&#10;        return;&#10;    }&#10;    if (Math.hypot(h.x - HOSPITAL_PARADA.x, h.y - HOSPITAL_PARADA.y) &lt; 76) {&#10;        if (h.patinete) { h.patinete.montadaPor = null; h.patinete = null; }&#10;        h.estado = 'caminando'; nuevoObjetivo(h); habitanteArrastrada = null;&#10;        irAPantalla('hospital');&#10;        return;&#10;    }&#10;    if (Math.hypot(h.x - ARENA_PARADA.x, h.y - ARENA_PARADA.y) &lt; 76) {&#10;        if (h.patinete) { h.patinete.montadaPor = null; h.patinete = null; }&#10;        h.estado = 'caminando'; nuevoObjetivo(h); habitanteArrastrada = null;&#10;        irAPantalla('arena');&#10;        return;&#10;    }&#10;    if (Math.hypot(h.x - TRANVIA.x, h.y - TRANVIA.y) &lt; 45) {&#10;        if (h.patinete) { h.patinete.montadaPor = null; h.patinete = null; }&#10;        const primeraVez = !enPlaya;&#10;        enviarAPlaya(h);&#10;        if (primeraVez) {&#10;            habitantes&#10;                .filter(o =&gt; o !== h &amp;&amp; !o.enPlaya &amp;&amp; !o.oculta &amp;&amp; !o.durmiendo &amp;&amp; !o.arrastrando)&#10;                .slice(0, 4 - habitantesEnPlaya.length)&#10;                .forEach(o =&gt; enviarAPlaya(o));&#10;        }&#10;        enPlaya = true;&#10;        habitanteArrastrada = null;&#10;        return;&#10;    }&#10;    if (!h.patinete) {&#10;        let patineteCercano = null, distPat = 45;&#10;        patinetes.forEach(p =&gt; {&#10;            if (p.montadaPor) return;&#10;            const d = Math.hypot(h.x - p.x, h.y - p.y);&#10;            if (d &lt; distPat) { patineteCercano = p; distPat = d; }&#10;        });&#10;        if (patineteCercano) {&#10;            patineteCercano.montadaPor = h;&#10;            h.patinete = patineteCercano;&#10;        }&#10;    }&#10;    h.inmuneSocial = 40;&#10;    nuevoObjetivo(h);&#10;    h.estado = 'caminando';&#10;    habitanteArrastrada = null;&#10;}&#10;canvas.addEventListener('pointerup', soltarMu\u00f1eca);&#10;canvas.addEventListener('pointercancel', soltarMu\u00f1eca);&#10;const Portada = (() =&gt; {&#10;    const el = document.getElementById('portada'), est = document.getElementById('portadaEstado'), bSi = document.getElementById('btnConSonido'), bNo = document.getElementById('btnSinSonido'), pie = document.getElementById('portadaPie');&#10;    const leer = () =&gt; { try { return localStorage.getItem('chicachica:sonido'); } catch (e) { return null; } };&#10;    const guardar = v =&gt; { try { localStorage.setItem('chicachica:sonido', v); } catch (e) {} };&#10;    let entrada = false;&#10;    function entrar(conSonido) {&#10;        if (entrada) return; entrada = true; guardar(conSonido ? 'si' : 'no');&#10;        if (conSonido) { silenciado = false; if (!audioIniciado) iniciarAudio(); else { audioCtx.resume().catch(() =&gt; {}); if (masterGain) masterGain.gain.value = 0.5; } }&#10;        else silenciado = true;&#10;        if (el) { el.classList.add('saliendo'); setTimeout(() =&gt; { if (el.remove) el.remove(); }, 650); }&#10;        try { canvas.focus &amp;&amp; canvas.focus(); } catch (e) {}&#10;        try { Zoom.auto(); } catch (e) {}                                                         \/\/ zoom autom\u00e1tico en ventanas estrechas y altas&#10;        setTimeout(() =&gt; Ayuda.abrirSiPrimera(), 700); setTimeout(() =&gt; Vuelta.saludar(), 3500);                                           \/\/ gu\u00eda de bienvenida la primera vez&#10;    }&#10;    function listo() {&#10;        window.__chicachicaListo = true;&#10;        if (est) est.textContent = '\u00a1Todo listo!'; if (el) el.classList.add('listo'); if (bSi) bSi.disabled = false; if (bNo) bNo.disabled = false;&#10;        const p = leer(); if (p === 'no' &amp;&amp; bNo) bNo.classList.add('pref'); else if (bSi) bSi.classList.add('pref');&#10;        if (pie) pie.textContent = 'Sin cookies ni anuncios \u00b7 tu progreso se guarda solo en este dispositivo \u00b7 m\u00fasica original' + (INCLUIR_HAURTXO ? ' y melod\u00edas tradicionales vascas (Haurtxo polita, Hator hator)' : '');&#10;        if (bSi) bSi.focus &amp;&amp; bSi.focus();&#10;    }&#10;    if (el) {&#10;        el.addEventListener('pointerdown', e =&gt; { const b = e.target &amp;&amp; e.target.closest ? e.target.closest('[data-sonido]') : null; if (b &amp;&amp; b.dataset.sonido === 'no') silenciado = true; if (!(b &amp;&amp; b.dataset.sonido === 'si')) e.stopPropagation(); });   \/\/ solo \u00abcon m\u00fasica\u00bb deja pasar el gesto al arranque del audio&#10;        if (bSi) bSi.addEventListener('click', () =&gt; entrar(true)); if (bNo) bNo.addEventListener('click', () =&gt; entrar(false));&#10;    }&#10;    return { listo };&#10;})();&#10;const Ayuda = (() =&gt; {&#10;    const $ = id =&gt; document.getElementById(id), KG = 'chicachica:guia', KT = 'chicachica:textogrande', KP = 'chicachica:pistas';&#10;    const leer = k =&gt; { try { return localStorage.getItem(k); } catch (e) { return null; } }, guardar = (k, v) =&gt; { try { localStorage.setItem(k, v); } catch (e) {} };&#10;    const PASOS = [&#10;        { i: '\ud83d\udc9c', t: 'Bienvenida al pueblo', p: 'En ChicaChica las chicas viven su d\u00eda solas: cultivan la huerta, compran en el mercado, estudian, entrenan y surfean. Aqu\u00ed no hay prisas, ni enemigos, ni forma de perder.' },&#10;        { i: '\ud83c\udfae', t: 'T\u00fa decides', p: 'Arrastra a una chica a una casa para que cocine, barra o se ba\u00f1e, al gimnasio para que entrene, a la playa para que surfee o a un banco para que descanse. En la huerta eliges qu\u00e9 sembrar y en el mercado qu\u00e9 comprar. Las genoides trabajan solas, d\u00eda y noche.' },&#10;        { i: '\ud83d\udc46', t: 'Qu\u00e9 puedes hacer', p: 'Arrastra a una chica a un banco, a una casa o al tranv\u00eda. Toca las cosas para descubrirlas: el tabl\u00f3n \ud83d\udccc con las noticias, el cofre com\u00fan del pueblo (la Kutxa), el cubo del gimnasio\u2026 Cambia de lugar con los botones de arriba. Con la lupa \ud83d\udd0d acercas el pueblo y lo mueves con las flechas. Haz doble toque sobre una chica para seguirla; otro doble toque la suelta. El tabl\u00f3n \ud83d\udccc cuenta lo que pasa en el pueblo.' },&#10;        { i: '\ud83c\udf31', t: 'Todo est\u00e1 conectado', p: 'La huerta da comida, el mercado la reparte, el mar y el puerto tienen su ciclo, y el pueblo celebra las fiestas del calendario vasco. Mira, juega y haz una \ud83d\udcf8 postal cuando quieras. Tu pueblo se guarda solo en este dispositivo.' }&#10;    ];&#10;    const vistos = new Set((leer(KP) || '').split(',').filter(Boolean)); let n = 0, habilitado = false, ultima = '', mostradas = 0, grande = leer(KT) === 'si';&#10;    const escenaId = () =&gt; enSubmarino ? 'submarino' : enPuerto ? 'puerto' : enPlaya ? 'playa' : enHuerta ? 'huerta' : enMercado ? 'mercado' : enIndustria ? 'industria' : enGimnasio ? 'gimnasio' : enBiblioteca ? 'biblioteca' : casaAbierta !== null ? 'casa' : 'pueblo';&#10;    const PISTAS = {&#10;        get pueblo() { const peq = typeof matchMedia === 'function' &amp;&amp; matchMedia('(max-width: 760px), (max-height: 600px)').matches; return peq ? '\ud83d\udd0d Toca la lupa para acercar el pueblo y mu\u00e9vete con las flechas. Arrastra a una chica a un banco o a una casa.' : '\ud83d\udc46 Arrastra a una chica a un banco, al tranv\u00eda o a una casa. Toca el tabl\u00f3n \ud83d\udccc y el cofre com\u00fan del pueblo (la Kutxa).'; },&#10;        playa: '\ud83c\udfd6\ufe0f Aqu\u00ed las chicas surfean y recogen algas. Toca el cartel \u00abEL PUERTO\u00bb para ir al muelle.',&#10;        puerto: '\u2693 Toca la estaci\u00f3n de buceo \ud83e\udd3f para bajar al fondo marino.',&#10;        submarino: '\ud83e\udd3f Toca los animales y las plantas para saber c\u00f3mo se llaman.',&#10;        huerta: '\ud83c\udf31 El tractor siembra y las genoides cosechadoras (las BELAR, con casco y visor) recogen la cosecha. Toca el banco de semillas para elegir qu\u00e9 plantar.',&#10;        mercado: '\ud83c\udfea Toca un puesto para hacer tu compra. Las chicas compran seg\u00fan su hambre; el cuaderno de la mesa muestra las cuentas.',&#10;        industria: '\ud83c\udfed La impresora 3D fabrica cosas para el pueblo. Toca su panel para elegir qu\u00e9 hacer.',&#10;        gimnasio: '\ud83c\udfcb\ufe0f Las vecinas entrenan aqu\u00ed cuando les apetece. Si quieres, toca las m\u00e1quinas.',&#10;        biblioteca: '\ud83d\udcda Toca un panel de la pared para cambiar los datos del pueblo que se muestran.'&#10;    };&#10;    function aplicarTexto() { TXT_ESCALA = grande ? 1.2 : 1; document.body.classList.toggle('grande', grande); const c = $('navTexto'); if (c) c.classList.toggle('sel', grande); const b = $('guiaTexto'); if (b) b.classList.toggle('on', grande); }&#10;    function alternarTexto() { grande = !grande; guardar(KT, grande ? 'si' : 'no'); aplicarTexto(); }&#10;    function pintar() {&#10;        const p = PASOS[n], ult = n === PASOS.length - 1; $('guiaIcono').textContent = p.i; $('guiaTitulo').textContent = p.t; $('guiaCuerpo').textContent = p.p;&#10;        $('guiaSiguiente').textContent = ult ? '\u00a1A jugar! \ud83d\udc9c' : 'Siguiente \u25b6'; $('guiaSaltar').hidden = ult; $('guiaTexto').hidden = n !== 0;&#10;        const pts = $('guiaPuntos'); if (pts) { pts.textContent = ''; PASOS.forEach((_, i) =&gt; { const d = document.createElement('i'); if (i === n) d.className = 'on'; pts.appendChild(d); }); }&#10;    }&#10;    function abrir() { n = 0; pintar(); const g = $('guia'); if (g) g.hidden = false; const b = $('guiaSiguiente'); if (b &amp;&amp; b.focus) b.focus(); }&#10;    let latido = false, latidoHasta = 0;                                                                         \/\/ primera visita: tres anillos suaves invitan a tocar (tabl\u00f3n, cofre y una vecina) hasta el primer toque&#10;    function cerrar() { const g = $('guia'); if (g) g.hidden = true; if (leer(KG) !== 'si') { latido = true; latidoHasta = performance.now() + 25000; } guardar(KG, 'si'); habilitado = true; ultima = ''; try { canvas.focus &amp;&amp; canvas.focus(); } catch (e) {} }&#10;    function siguiente() { if (n &gt;= PASOS.length - 1) cerrar(); else { n++; pintar(); } }&#10;    function tick() {                                                                                           \/\/ pista breve la primera vez que entras en cada lugar&#10;        if (!habilitado) return; const e = escenaId(); if (e === ultima) return; ultima = e;&#10;        if (PISTAS[e] &amp;&amp; !vistos.has(e)) { vistos.add(e); guardar(KP, [...vistos].join(',')); mostradas++; KutxaPanel.avisar(PISTAS[e]); }&#10;    }&#10;    function habilitar() { habilitado = true; ultima = escenaId(); const p = escenaId(); if (PISTAS[p] &amp;&amp; !vistos.has(p)) { ultima = ''; } }&#10;    function abrirSiPrimera() { if (leer(KG) !== 'si') abrir(); else habilitar(); }&#10;    const g = $('guia');&#10;    if (g) {&#10;        g.addEventListener('pointerdown', e =&gt; e.stopPropagation());&#10;        const s = $('guiaSiguiente'), k = $('guiaSaltar'), t = $('guiaTexto'); if (s) s.addEventListener('click', siguiente); if (k) k.addEventListener('click', cerrar); if (t) t.addEventListener('click', alternarTexto);&#10;    }&#10;    const ca = $('navAyuda'), ct = $('navTexto'); const act = (el, f) =&gt; { if (!el) return; el.addEventListener('click', f); el.addEventListener('keydown', e =&gt; { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); f(); } }); }; act(ca, abrir); act(ct, alternarTexto);&#10;    document.addEventListener('keydown', e =&gt; { const gg = $('guia'); if (e.key === 'Escape' &amp;&amp; gg &amp;&amp; !gg.hidden) cerrar(); });&#10;    aplicarTexto();&#10;    function latidos(tt) {&#10;        if (!latido) return; if (performance.now() &gt; latidoHasta || enPlaya || enPuerto || enSubmarino || enHuerta || enMercado || enIndustria || enBiblioteca || enGimnasio || enHospital || enArena || casaAbierta !== null) { return; }&#10;        const v = habitantes.find(h =&gt; !h.durmiendo &amp;&amp; !h.enPlaya &amp;&amp; !h.oculta), P = [[332, 312], [KUTXA_POS.x, KUTXA_POS.y - 28]]; if (v) P.push([v.x, v.y - 8]);&#10;        ctx.save(); ctx.lineWidth = 3; P.forEach(([x, y], i) =&gt; { const k = ((tt \/ 40) + i * 0.33) % 1; ctx.strokeStyle = `rgba(124,255,217,${0.85 * (1 - k)})`; ctx.beginPath(); ctx.arc(x, y, 18 + k * 26, 0, Math.PI * 2); ctx.stroke(); }); ctx.restore();&#10;    }&#10;    function quitarLatido() { latido = false; }&#10;    if (typeof canvas !== 'undefined' &amp;&amp; canvas) canvas.addEventListener('pointerdown', quitarLatido);&#10;    return { latidos, abrir, abrirSiPrimera, habilitar, tick, alternarTexto, vistos: () =&gt; [...vistos], mostradas: () =&gt; mostradas, grande: () =&gt; grande };&#10;})();&#10;const Ligero = (() =&gt; {&#10;    const d = Object.getOwnPropertyDescriptor(CanvasRenderingContext2D.prototype, 'shadowBlur'); let on = false;&#10;    function activar() { if (on || !d) return; on = true; try { Object.defineProperty(ctx, 'shadowBlur', { set() { d.set.call(this, 0); }, get() { return d.get.call(this); }, configurable: true }); } catch (e) {} }&#10;    let n = 0, ult = performance.now(), lentos = 0;&#10;    (function medir(now) { const dt = now - ult; ult = now; if (dt &gt; 28) lentos++; if (++n &lt; 240) requestAnimationFrame(medir); else if (lentos \/ n &gt; .35) activar(); })(ult);   \/\/ si en los primeros 4 s va por debajo de ~36 fps, se activa solo&#10;    return { activar, activo: () =&gt; on };&#10;})();&#10;const ModoTV = (() =&gt; {&#10;    const btn = document.getElementById('btnTV'); if (!btn) return {};&#10;    let on = false, tOcultar = 0;&#10;    const mostrar = () =&gt; { const bi = document.getElementById('btnIdioma'); btn.classList.add('ver'); if (bi) bi.classList.add('ver'); clearTimeout(tOcultar); tOcultar = setTimeout(() =&gt; { btn.classList.remove('ver'); if (bi) bi.classList.remove('ver'); }, 3000); };&#10;    function aplicar(v) {&#10;        on = v; document.body.classList.toggle('tv', v); btn.textContent = v ? '\u2715 Salir de Smart TV' : '\ud83d\udcfa Smart TV';&#10;        if (v) { document.body.classList.remove('zoomOn'); const c = document.getElementById('pantallaJuego'), w = document.getElementById('lienzoWrap'); if (c) c.classList.remove('zoom'); if (w) w.classList.remove('zoom'); mostrar(); } else { clearTimeout(tOcultar); btn.classList.remove('ver'); }&#10;    }&#10;    async function entrar() { aplicar(true); try { const el = document.documentElement, f = el.requestFullscreen || el.webkitRequestFullscreen; if (f) await f.call(el); } catch (e) {} }   \/\/ si el sistema no permite pantalla completa, el modo sigue funcionando a pantalla del navegador&#10;    function salir() { aplicar(false); try { if (document.fullscreenElement || document.webkitFullscreenElement) (document.exitFullscreen || document.webkitExitFullscreen).call(document); } catch (e) {} }&#10;    btn.addEventListener('click', () =&gt; on ? salir() : entrar());&#10;    const cambio = () =&gt; { if (on &amp;&amp; !document.fullscreenElement &amp;&amp; !document.webkitFullscreenElement &amp;&amp; salioDeFS) aplicar(false); };   \/\/ Esc o el gesto del sistema tambi\u00e9n salen del modo&#10;    let salioDeFS = false; document.addEventListener('fullscreenchange', () =&gt; { salioDeFS = !!document.fullscreenElement || salioDeFS; cambio(); });&#10;    ['pointermove', 'pointerdown'].forEach(n =&gt; document.addEventListener(n, () =&gt; { if (on) mostrar(); }, { passive: true }));&#10;    document.addEventListener('keydown', e =&gt; { if (e.key === 'Escape' &amp;&amp; on) salir(); });&#10;    return { entrar, salir };&#10;})();&#10;const Mando = (() =&gt; {&#10;    const esTV = \/SMART-?TV|Tizen|Web0S|webOS|HbbTV|NetCast|BRAVIA|VIDAA|Hisense|AFT[A-Z]|Roku|CrKey|GoogleTV|Android ?TV|Viera\/i.test(navigator.userAgent);&#10;    const mano = document.createElement('div'), ayuda = document.createElement('div');&#10;    mano.id = 'manoTV'; mano.textContent = '\ud83d\udc46'; ayuda.id = 'ayudaMando'; ayuda.textContent = '\ud83c\udfae Flechas: mueven la mano \u00b7 OK: toca, o agarra y suelta \u00b7 CH+ \/ CH\u2212: cambian de escena';&#10;    document.body.appendChild(mano); document.body.appendChild(ayuda);&#10;    let x = innerWidth \/ 2, y = innerHeight \/ 2, activo = false, agarrando = false, tAyuda = 0, tTap = 0, rep = 0;&#10;    const _spc = canvas.setPointerCapture.bind(canvas); canvas.setPointerCapture = id =&gt; { try { _spc(id); } catch (e) {} };   \/\/ los eventos del mando no son punteros reales&#10;    const ESC = ['pueblo', 'playa', 'huerta', 'mercado', 'industria', 'arena', 'hospital'];&#10;    function ev(tipo, el) { const o = { bubbles: true, cancelable: true, clientX: x, clientY: y, pointerId: 77, pointerType: 'mouse', isPrimary: true, button: tipo === 'pointermove' ? -1 : 0, buttons: tipo === 'pointerup' ? 0 : 1 }; (el || document.elementFromPoint(x, y) || document.body).dispatchEvent(new PointerEvent(tipo, o)); }&#10;    function pintar() { mano.style.left = x + 'px'; mano.style.top = y + 'px'; mano.textContent = agarrando ? '\u270a' : '\ud83d\udc46'; mano.classList.toggle('ver', activo); }&#10;    function mostrarAyuda() { ayuda.classList.add('ver'); clearTimeout(tAyuda); tAyuda = setTimeout(() =&gt; ayuda.classList.remove('ver'), 8000); }&#10;    function activar() {&#10;        if (activo) return; activo = true; document.body.classList.add('tv'); mostrarAyuda();&#10;        const p = document.getElementById('portada'), b = document.getElementById('btnConSonido');&#10;        if (p &amp;&amp; b &amp;&amp; p.offsetWidth &gt; 0 &amp;&amp; getComputedStyle(p).display !== 'none') { const r = b.getBoundingClientRect(); x = r.left + r.width \/ 2; y = r.top + r.height \/ 2; }   \/\/ en la portada, la mano empieza sobre \u00abEntrar con m\u00fasica\u00bb&#10;        pintar();&#10;    }&#10;    function soltar() { agarrando = false; clearTimeout(tTap); ev('pointerup', canvas); pintar(); }&#10;    function escena(d) { const i = ESC.indexOf(pantallaActual()); irAPantalla(ESC[(i + d + ESC.length) % ESC.length]); }&#10;    document.addEventListener('keydown', e =&gt; {&#10;        if (document.activeElement &amp;&amp; \/^(INPUT|TEXTAREA)$\/.test(document.activeElement.tagName)) return;   \/\/ mientras escribes un nombre, las teclas son del teclado&#10;        const k = e.keyCode, d = { 37: [-1, 0], 38: [0, -1], 39: [1, 0], 40: [0, 1] }[k], ok = k === 13, cambio = [33, 34, 427, 428, 403, 404, 412, 417].includes(k);&#10;        if (!activo) { if (!(k === 77 || (esTV &amp;&amp; (d || ok)))) return; activar(); e.preventDefault(); if (k === 77 || !ok) return; }   \/\/ la tecla M la activa tambi\u00e9n en un ordenador&#10;        if (k === 77 &amp;&amp; !esTV) { activo = false; mano.classList.remove('ver'); e.preventDefault(); return; }&#10;        if (d) { e.preventDefault(); const paso = Math.max(10, innerWidth * .01) * (1 + Math.min(4, (e.repeat ? ++rep : (rep = 0)) \/ 6)); x = Math.max(0, Math.min(innerWidth - 1, x + d[0] * paso)); y = Math.max(0, Math.min(innerHeight - 1, y + d[1] * paso)); pintar(); if (agarrando) { clearTimeout(tTap); ev('pointermove', canvas); } }&#10;        else if (ok) { e.preventDefault(); const el = document.elementFromPoint(x, y);&#10;            if (agarrando) soltar();&#10;            else if (el === canvas) { agarrando = true; ev('pointerdown', canvas); tTap = setTimeout(soltar, 650); pintar(); }   \/\/ un toque corto = tocar; si te mueves enseguida, agarras&#10;            else if (el &amp;&amp; el !== document.body) { if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') el.focus(); else el.click(); } }&#10;        else if (cambio) { e.preventDefault(); escena([34, 428, 404, 417].includes(k) ? 1 : -1); }&#10;        else if ((k === 27 || k === 461 || k === 10009 || k === 8) &amp;&amp; agarrando) { e.preventDefault(); soltar(); }&#10;    });&#10;    if (esTV) { document.body.classList.add('tv'); mostrarAyuda(); Ligero.activar(); }&#10;    return { irA(px, py) { x = px; y = py; if (!activo) activar(); pintar(); if (agarrando) ev('pointermove', canvas); } };&#10;})();&#10;const Zoom = (() =&gt; {&#10;    const $ = id =&gt; document.getElementById(id), NIV = [1, 1.8, 2.6]; let i = 0, manual = false, tt = null;&#10;    function tenue() { const pan = $('panZoom'); if (!pan) return; pan.classList.remove('tenue'); if (tt) clearTimeout(tt); tt = setTimeout(() =&gt; pan.classList.add('tenue'), 3500); }&#10;    function soltar() {                                                                                         \/\/ quita el zoom (clases y medidas del lienzo) para poder medir el ajuste normal&#10;        const cont = $('pantallaJuego'), wrap = $('lienzoWrap'); if (cont) cont.classList.remove('zoom'); if (wrap) wrap.classList.remove('zoom');&#10;        canvas.style.maxWidth = ''; canvas.style.maxHeight = ''; canvas.style.width = ''; canvas.style.height = '';&#10;    }&#10;    function auto() {                                                                                           \/\/ ventana estrecha y alta (m\u00f3vil en vertical, iPad en ventana): arranca con zoom para no dejar huecos arriba y abajo&#10;        if (manual) return; const cont = $('pantallaJuego'); if (!cont) return;&#10;        soltar(); const w = canvas.getBoundingClientRect().width, ch = cont.clientHeight, cw = cont.clientWidth;&#10;        if (!isFinite(w) || !isFinite(ch) || !isFinite(cw) || w &lt;= 0) return; const gap = ch \/ (w * 540 \/ 960);&#10;        if (cw &lt;= 760 &amp;&amp; gap &gt; 1.35) { NIV[1] = Math.round(Math.min(1.8, Math.max(1.3, gap * 0.9)) * 10) \/ 10; i = 1; } else { NIV[1] = 1.8; i = 0; }&#10;        aplicar();&#10;    }&#10;    function aplicar() {&#10;        const cont = $('pantallaJuego'), wrap = $('lienzoWrap'), z = NIV[i], chip = $('navZoom'), pan = $('panZoom'); if (!cont || !wrap) return;&#10;        soltar();&#10;        if (z &gt; 1) {&#10;            const w = canvas.getBoundingClientRect().width; cont.classList.add('zoom'); wrap.classList.add('zoom');&#10;            canvas.style.maxWidth = 'none'; canvas.style.maxHeight = 'none'; canvas.style.width = Math.round(w * z) + 'px'; canvas.style.height = 'auto';&#10;            cont.scrollLeft = Math.max(0, (cont.scrollWidth - cont.clientWidth) \/ 2); cont.scrollTop = Math.max(0, (cont.scrollHeight - cont.clientHeight) \/ 2);&#10;        }&#10;        document.body.classList.toggle('zoomOn', z &gt; 1);&#10;        if (chip) { chip.textContent = z &gt; 1 ? (window.innerWidth &lt;= 380 ? '\u00d7' : '\ud83d\udd0d\u00d7') + z : '\ud83d\udd0d'; chip.classList.toggle('sel', z &gt; 1); } if (pan) pan.hidden = z &lt;= 1; const asa = $('panAsa'); if (asa) asa.hidden = z &lt;= 1; if (z &gt; 1) tenue();&#10;    }&#10;    function siguiente() { manual = true; i = (i + 1) % NIV.length; aplicar(); }&#10;    function mover(d) { const c = $('pantallaJuego'); if (!c) return; tenue(); if (d === 'reset') { manual = true; i = 0; aplicar(); return; } const dx = d === 'left' ? -1 : d === 'right' ? 1 : 0, dy = d === 'up' ? -1 : d === 'down' ? 1 : 0; try { c.scrollBy({ left: dx * c.clientWidth * 0.4, top: dy * c.clientHeight * 0.4, behavior: 'smooth' }); } catch (e) { c.scrollLeft += dx * c.clientWidth * 0.4; c.scrollTop += dy * c.clientHeight * 0.4; } }&#10;    const act = (el, f) =&gt; { if (!el) return; el.addEventListener('click', f); el.addEventListener('keydown', e =&gt; { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); f(); } }); };&#10;    act($('navZoom'), siguiente);&#10;    const asa = $('panAsa'); if (asa) { asa.addEventListener('pointerdown', e =&gt; e.stopPropagation()); asa.addEventListener('click', () =&gt; { document.body.classList.toggle('padOculto'); tenue(); }); }&#10;    const pan = $('panZoom'); if (pan) { pan.addEventListener('pointerdown', e =&gt; { e.stopPropagation(); tenue(); }); ['up', 'down', 'left', 'right', 'reset'].forEach(d =&gt; { const b = pan.querySelector ? pan.querySelector('[data-d=&quot;' + d + '&quot;]') : null; if (b) b.addEventListener('click', () =&gt; mover(d)); }); }&#10;    const mas = $('navMas'); act(mas, () =&gt; { const a = document.body.classList.toggle('masAbierto'); mas.setAttribute &amp;&amp; mas.setAttribute('aria-expanded', a ? 'true' : 'false'); });&#10;    document.addEventListener('pointerdown', e =&gt; { const t = e.target; if (document.body.classList.contains('masAbierto') &amp;&amp; t &amp;&amp; t.closest &amp;&amp; !t.closest('#nav')) document.body.classList.remove('masAbierto'); });&#10;    let rt = null, ultOri = window.innerWidth &gt;= window.innerHeight;&#10;    const reajustar = (ms = 120) =&gt; { if (rt) clearTimeout(rt); rt = setTimeout(() =&gt; { const ori = window.innerWidth &gt;= window.innerHeight; if (ori !== ultOri) { ultOri = ori; manual = false; }        \/\/ al girar el m\u00f3vil se vuelve a elegir el zoom que mejor va a esa orientaci\u00f3n&#10;        if (manual) { if (i &gt; 0) aplicar(); } else auto(); }, ms); };&#10;    window.addEventListener('resize', () =&gt; reajustar(120)); window.addEventListener('orientationchange', () =&gt; reajustar(300)); window.addEventListener('load', () =&gt; reajustar(200));&#10;    function fijar(z) { manual = true; const j = NIV.findIndex(v =&gt; v &gt;= z - .001); i = j &lt; 0 ? NIV.length - 1 : j; aplicar(); }&#10;    function centrar(x, y, k) { const c = $('pantallaJuego'); if (!c || NIV[i] &lt;= 1) return; const r = canvas.getBoundingClientRect(), cr = c.getBoundingClientRect(), s = r.width \/ canvas.width; c.scrollLeft += ((r.left + x * s) - (cr.left + c.clientWidth \/ 2)) * k; c.scrollTop += ((r.top + y * s) - (cr.top + c.clientHeight \/ 2)) * k; }&#10;    return { siguiente, mover, nivel: () =&gt; NIV[i], aplicar, auto, fijar, centrar };&#10;})();&#10;async function ofrecerDescarga(nombre, datos) {&#10;    try {&#10;        if (!(window.claude &amp;&amp; window.claude.use)) return false;&#10;        const d = await window.claude.use('downloads'); if (!d) return false;&#10;        await d.save({ filename: nombre, data: datos }); return true;&#10;    } catch (e) { return e &amp;&amp; e.code === 'declined' ? 'no' : false; }&#10;}&#10;const Copia = (() =&gt; {&#10;    const $ = id =&gt; document.getElementById(id); let armado = null;&#10;    const estado = (t, ok = true) =&gt; { const e = $('guardarEstado'); if (e) { e.textContent = t; e.style.color = ok ? '#7cffd9' : '#ffb3a8'; } };&#10;    function abrir() { const g = $('guardar'); if (!g) return; $('guardarTexto').value = Persistencia.exportarTexto(); estado(''); g.hidden = false; try { $('guardarCerrar').focus(); } catch (e) {} }&#10;    function cerrar() { const g = $('guardar'); if (g) g.hidden = true; armado = null; try { canvas.focus &amp;&amp; canvas.focus(); } catch (e) {} }&#10;    async function descargar() {&#10;        const txt = $('guardarTexto').value &amp;&amp; $('guardarTexto').value.trim().startsWith('{&quot;juego&quot;') ? $('guardarTexto').value : Persistencia.exportarTexto(), nombre = 'chicachica-pueblo-' + new Date().toISOString().slice(0, 10) + '.json';&#10;        { const r = await ofrecerDescarga(nombre, txt); if (r === true) { estado('Archivo descargado \u2714'); return; } if (r === 'no') return; }&#10;        try { const f = new File([txt], nombre, { type: 'application\/json' }); if (navigator.canShare &amp;&amp; navigator.canShare({ files: [f] })) { await navigator.share({ files: [f], title: 'Mi pueblo de ChicaChica' }); estado('Listo \u2714 (elige d\u00f3nde guardarlo)'); return; } } catch (e) { if (e &amp;&amp; e.name === 'AbortError') return; }&#10;        try { const url = URL.createObjectURL(new Blob([txt], { type: 'application\/json' })), a = document.createElement('a'); a.href = url; a.download = nombre; document.body.appendChild(a); a.click(); a.remove(); setTimeout(() =&gt; URL.revokeObjectURL(url), 4000); estado('Archivo descargado \u2714 (si no ves nada, copia el c\u00f3digo)'); }&#10;        catch (e) { estado('No se pudo descargar aqu\u00ed: copia el c\u00f3digo.', false); }&#10;    }&#10;    async function copiar() {&#10;        const t = $('guardarTexto'); try { await navigator.clipboard.writeText(t.value); estado('C\u00f3digo copiado \u2714'); return; } catch (e) {}&#10;        try { t.focus(); t.select(); t.setSelectionRange(0, t.value.length); estado(document.execCommand &amp;&amp; document.execCommand('copy') ? 'C\u00f3digo copiado \u2714' : 'Selecci\u00f3nalo y c\u00f3pialo a mano', true); } catch (e) { estado('Selecci\u00f3nalo y c\u00f3pialo a mano', false); }&#10;    }&#10;    function cargar() {&#10;        const b = $('guardarCargar'); if (!armado) { armado = setTimeout(() =&gt; { armado = null; b.classList.remove('armado'); b.textContent = '\u2b06\ufe0f Cargar este c\u00f3digo'; }, 4000); b.classList.add('armado'); b.textContent = '\u00bfSeguro? Pulsa otra vez'; estado('Se cambiar\u00e1 lo que tienes ahora por ese pueblo.', false); return; }&#10;        clearTimeout(armado); armado = null; b.classList.remove('armado'); b.textContent = '\u2b06\ufe0f Cargar este c\u00f3digo';&#10;        const r = Persistencia.importarTexto($('guardarTexto').value); estado(r.msg, r.ok);&#10;    }&#10;    function leerArchivo() { const f = $('guardarArchivo').files &amp;&amp; $('guardarArchivo').files[0]; if (!f) return; if (f.size &gt; 600000) { estado('Ese archivo es demasiado grande para ser un pueblo.', false); return; } const lector = new FileReader(); lector.onload = () =&gt; { $('guardarTexto').value = String(lector.result || ''); estado('Archivo le\u00eddo. Pulsa \u00abCargar este c\u00f3digo\u00bb.'); }; lector.onerror = () =&gt; estado('No se pudo leer el archivo.', false); lector.readAsText(f); }&#10;    const act = (el, f) =&gt; { if (!el) return; el.addEventListener('click', f); el.addEventListener('keydown', e =&gt; { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); f(); } }); };&#10;    act($('navGuardar'), abrir); const g = $('guardar');&#10;    if (g) { g.addEventListener('pointerdown', e =&gt; e.stopPropagation()); $('guardarDescargar').addEventListener('click', descargar); $('guardarCopiar').addEventListener('click', copiar); $('guardarCargar').addEventListener('click', cargar); $('guardarCerrar').addEventListener('click', cerrar); $('guardarElegir').addEventListener('click', () =&gt; $('guardarArchivo').click()); $('guardarArchivo').addEventListener('change', leerArchivo); }&#10;    document.addEventListener('keydown', e =&gt; { const gg = $('guardar'); if (e.key === 'Escape' &amp;&amp; gg &amp;&amp; !gg.hidden) cerrar(); });&#10;    return { abrir, cerrar };&#10;})();&#10;function diarioNota(c, i, t, e) { try { Diario.nota(c, i, t, e); } catch (x) {} }&#10;const Vuelta = (() =&gt; {                                                                                         \/\/ si hace horas que no vienes, el pueblo te saluda con lo que hay hoy&#10;    const K = 'chicachica:ultima'; const leer = () =&gt; { try { return +localStorage.getItem(K) || 0; } catch (e) { return 0; } }, poner = () =&gt; { try { localStorage.setItem(K, String(Date.now())); } catch (e) {} };&#10;    const antes = leer(); poner(); setInterval(poner, 30000); window.addEventListener('pagehide', poner);&#10;    function saludar() {&#10;        if (!antes || Date.now() - antes &lt; 3 * 3600 * 1000) return;&#10;        const F = typeof fiestaActual === 'function' ? fiestaActual() : null;&#10;        try { KutxaPanel.avisar('\ud83d\udc9c Bienvenida de vuelta: el pueblo te ha echado de menos.' + (F ? ' Hoy: ' + F.txt : '')); } catch (e) {}&#10;    }&#10;    return { saludar };&#10;})();&#10;const Diario = (() =&gt; {&#10;    const K = 'chicachica:diario', $ = id =&gt; document.getElementById(id);&#10;    let d = {}; try { d = JSON.parse(localStorage.getItem(K) || '{}') || {}; } catch (e) { d = {}; }&#10;    const SECC = [['herbario', '\ud83c\udf3f Herbario'], ['fauna', '\ud83d\udc20 Fauna marina'], ['estaciones', '\ud83c\udf42 Estaciones y fiestas'], ['cartas', '\ud83d\udc8c Lo que cuentan las vecinas'], ['momentos', '\ud83d\udc9e Momentos de las chicas'], ['postales', '\ud83d\udcf8 Postales']];&#10;    const guardar = () =&gt; { try { localStorage.setItem(K, JSON.stringify(d)); } catch (e) {} };&#10;    function nota(c, i, t, e) {&#10;        if (!c || !i || typeof t !== 'string') return; i = String(i).slice(0, 60);&#10;        d[c] = d[c] || {}; if (d[c][i]) return; d[c][i] = { t: t.slice(0, 70), e: String(e || '').slice(0, 8) }; guardar();&#10;        try { KutxaPanel.avisar('\ud83d\udcd6 Nuevo en el diario: ' + (e ? e + ' ' : '') + t); } catch (x) {}&#10;    }&#10;    function pintar() {&#10;        const cu = $('diarioCuerpo'); if (!cu) return; cu.textContent = '';&#10;        SECC.forEach(([c, nombre]) =&gt; {&#10;            const h = document.createElement('h3'); h.textContent = nombre; cu.appendChild(h);&#10;            const fila = document.createElement('div'); fila.className = 'fila';&#10;            const got = Object.values(d[c] || {});&#10;            got.forEach(o =&gt; { const s = document.createElement('span'); s.className = 'it'; s.textContent = (o.e ? o.e + ' ' : '') + o.t; fila.appendChild(s); });&#10;            if (c === 'herbario') { const hechos = new Set(Object.keys(d[c] || {})); VARIEDADES.forEach(v =&gt; { if (!hechos.has(v.id)) { const s = document.createElement('span'); s.className = 'it no'; s.textContent = '\u2754'; fila.appendChild(s); } }); }&#10;            if (!got.length &amp;&amp; c !== 'herbario') { const s = document.createElement('span'); s.className = 'vacio'; s.textContent = 'A\u00fan por descubrir\u2026'; fila.appendChild(s); }&#10;            cu.appendChild(fila);&#10;        });&#10;    }&#10;    const CARTAS = {&quot;primavera&quot;: [[&quot;\ud83c\udf3c&quot;, &quot;Han brotado flores nuevas en la huerta&quot;], [&quot;\ud83d\udc1d&quot;, &quot;Las abejas vuelven a zumbar por el pueblo&quot;], [&quot;\ud83d\udeb6&quot;, &quot;Hoy las chicas pasean m\u00e1s despacio, con el olor a primavera&quot;]], &quot;verano&quot;: [[&quot;\ud83c\udfd6\ufe0f&quot;, &quot;La playa huele a sal y a verano&quot;], [&quot;\ud83c\udf07&quot;, &quot;Las tardes largas invitan a charlar en el banco&quot;], [&quot;\ud83c\udf51&quot;, &quot;El mercado huele a fruta madura&quot;]], &quot;otono&quot;: [[&quot;\ud83c\udf42&quot;, &quot;Caen las hojas y el pueblo huele a tierra mojada&quot;], [&quot;\ud83c\udf3e&quot;, &quot;Las vecinas hablan de recoger la \u00faltima cosecha&quot;], [&quot;\ud83c\udf06&quot;, &quot;Anochece antes y las luces del pueblo se ven m\u00e1s bonitas&quot;]], &quot;invierno&quot;: [[&quot;\ud83c\udf72&quot;, &quot;Hace fr\u00edo fuera, pero en las casas huele a sopa caliente&quot;], [&quot;\ud83e\udde3&quot;, &quot;Las chicas se abrigan y se saludan con las manos en los bolsillos&quot;], [&quot;\u2b50&quot;, &quot;Las noches largas dejan ver m\u00e1s estrellas&quot;]]};&#10;    const estacion = () =&gt; { const m = new Date().getMonth() + 1; return m &gt;= 3 &amp;&amp; m &lt;= 5 ? ['primavera', '\ud83c\udf38 Primavera'] : m &gt;= 6 &amp;&amp; m &lt;= 8 ? ['verano', '\u2600\ufe0f Verano'] : m &gt;= 9 &amp;&amp; m &lt;= 11 ? ['otono', '\ud83c\udf42 Oto\u00f1o'] : ['invierno', '\u2744\ufe0f Invierno']; };&#10;    let ult = 0;&#10;    function tick() {&#10;        const n = performance.now(); if (n - ult &lt; 5000) return; ult = n;&#10;        const [id, txt] = estacion(); nota('estaciones', id, txt.slice(3), txt.slice(0, 2));&#10;        { const dd = new Date(), m = dd.getMonth() + 1, k = (((m - 3) % 3) + 3) % 3, c = CARTAS[id]; if (c &amp;&amp; c[k]) nota('cartas', dd.getFullYear() + id + k, c[k][1], c[k][0]); }   \/\/ una carta nueva de las vecinas cada mes, seg\u00fan la estaci\u00f3n&#10;        const F = typeof fiestaActual === 'function' ? fiestaActual() : null; if (F &amp;&amp; F.id) nota('estaciones', 'f_' + (F.sub || F.id), F.txt.replace(\/^\\S+\\s\/, ''), F.txt.split(' ')[0]);&#10;    }&#10;    function abrir() { pintar(); const g = $('diario'); if (g) g.hidden = false; try { Idioma.aplicar(); } catch (e) {} const b = $('diarioCerrar'); if (b &amp;&amp; b.focus) b.focus(); }&#10;    function cerrar() { const g = $('diario'); if (g) g.hidden = true; try { canvas.focus &amp;&amp; canvas.focus(); } catch (e) {} }&#10;    const g = $('diario'); if (g) { g.addEventListener('pointerdown', e =&gt; e.stopPropagation()); const b = $('diarioCerrar'); if (b) b.addEventListener('click', cerrar); }&#10;    const chip = $('navDiario'); if (chip) { chip.addEventListener('click', abrir); chip.addEventListener('keydown', e =&gt; { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); abrir(); } }); }&#10;    document.addEventListener('keydown', e =&gt; { const gg = $('diario'); if (e.key === 'Escape' &amp;&amp; gg &amp;&amp; !gg.hidden) cerrar(); });&#10;    return { nota, tick, abrir, exportar: () =&gt; d, importar(o) { if (!o || typeof o !== 'object') return; SECC.forEach(([c]) =&gt; { const src = o[c]; if (!src || typeof src !== 'object') return; d[c] = d[c] || {}; Object.keys(src).slice(0, 80).forEach(i =&gt; { const v = src[i]; if (v &amp;&amp; typeof v.t === 'string' &amp;&amp; !d[c][i]) d[c][i] = { t: v.t.slice(0, 70), e: String(v.e || '').slice(0, 8) }; }); }); guardar(); } };&#10;})();&#10;const LibroBlanco = (() =&gt; {&#10;    const T = { es: &quot;EL PUEBLO DE CHICACHICA \u00b7 LIBRO BLANCO\\nchicachica.com\\n\\nQU\u00c9 ES\\nEl Pueblo de ChicaChica es una simulaci\u00f3n de mundo inmersivo: un pueblo solarpunk donde ocho chicas viven su d\u00eda por su cuenta mientras la jugadora observa, acompa\u00f1a y cuida. No tiene puntuaci\u00f3n, ni enemigos, ni forma de perder.\\nSe juega gratis desde el navegador, sin cookies ni anuncios. Es un \u00fanico archivo web que funciona en iPad, iPhone, ordenador y Smart TV, con 13 opciones de idioma.\\nEst\u00e1 pensado para toda la humanidad: para quien juega por primera vez y para quien nunca ha jugado, de cualquier edad, en cualquier idioma y en cualquier pantalla. No hace falta saber nada para empezar.\\n\\nPRINCIPIOS\\nChicaChica no es un juego de acaparar: nada se gana, se pierde ni se acumula para vencer a nadie.\\n- Sin derrota ni enemigos. El mundo sigue vivo pase lo que pase.\\n- Las chicas son las usuarias libres que disfrutan. Eligen c\u00f3mo pasar el d\u00eda: surfear, leer, entrenar, cocinar, pasear.\\n- Las genoides solo trabajan, las 24 horas, los 365 d\u00edas. No se sientan en las gradas ni juegan al ajedrez.\\n- La moneda MIIG26D es interna. No tiene valor real y no se canjea por nada.\\n- Gratis, sin cookies y sin publicidad.\\n\\nEL MUNDO\\nEl pueblo se recorre por zonas, que se cambian con la barra superior o tocando el tranv\u00eda, los carteles y las paradas.\\n- Pueblo: casas, plaza, tranv\u00eda, biblioteca digital, gimnasio, terraza, tabl\u00f3n de noticias y cofre com\u00fan (la Kutxa).\\n- Playa y puerto: surf, recogida de algas, hidr\u00f3geno verde y la estaci\u00f3n de buceo.\\n- Fondo marino: robots con forma de huevo que miden salinidad, yodo, ox\u00edgeno, metano y s\u00edsmica.\\n- La Huerta: tractor, genoides cosechadoras, colmenas, banco de semillas y cuidado de plantas.\\n- Mercado: puestos de fruta, harinas, l\u00e1cteos, legumbres, algas y hongos, granos y ra\u00edces, y apicultura; las chicas compran seg\u00fan su hambre.\\n- Zona industrial: impresora 3D y panel de producci\u00f3n del pueblo.\\n- Arena: estadio multideportivo, teatro hologr\u00e1fico, mesa de ajedrez y boutique de moda.\\n- Hospital OSASU: recepci\u00f3n con wearables, c\u00e1psula de terapia, laboratorio con criobanco y sala de recuperaci\u00f3n.\\n\\nQUI\u00c9N VIVE ALL\u00cd\\nOcho chicas, cada una con su aspecto y su temperamento: la surfista aventurera, la intelectual t\u00edmida, la bot\u00e1nica so\u00f1adora, la deportista combativa, la artista extrovertida, la chef met\u00f3dica, la gamer vaga y la exploradora curiosa. Su car\u00e1cter inclina lo que hacen, lo r\u00e1pido que caminan y con qui\u00e9n se juntan.\\nRecuerdan sus h\u00e1bitos, y el hospital las atiende seg\u00fan lo que viven: demasiadas horas sentadas piden cuidar la espalda; demasiado sol en la playa, la piel.\\nLas genoides son el personal del pueblo: cosechan, cuidan, atienden el hospital y fabrican, siempre trabajando.\\nLos nombres que cada jugadora da a las chicas son privados: se guardan solo en su dispositivo y solo se ven en el hospital.\\n\\nUN MUNDO CAUSAL\\nEl pueblo sigue el tiempo real del dispositivo y no se puede adelantar.\\n- D\u00eda y noche: la luz cambia con la hora real en todas las zonas.\\n- Estaciones: una cada tres meses naturales (invierno de diciembre a febrero, primavera de marzo a mayo, verano de junio a agosto, oto\u00f1o de septiembre a noviembre).\\n- El mar responde al pueblo: ox\u00edgeno, salinidad, yodo, metano y s\u00edsmica se calculan a partir del calor, la evaporaci\u00f3n, el riego, la basura y la producci\u00f3n industrial, no al azar.\\n\\nUN PUEBLO VIVO\\nNo hay objetivos ni niveles: el pueblo simplemente est\u00e1 vivo, y se puede mirar de cerca.\\n- Seguir a una chica. Un doble toque sobre ella y la c\u00e1mara la acompa\u00f1a; otro doble toque la suelta. Se la identifica por su oficio y temperamento, nunca por su nombre privado.\\n- Cr\u00f3nica del pueblo. El tabl\u00f3n recoge lo que ocurre y se traduce al idioma elegido.\\n- Sonido por zona. La playa suena a mar y gaviotas, la huerta a arroyo y p\u00e1jaros, el mercado a murmullo, la zona industrial a zumbido grave y el hospital a m\u00fasica relajante. Las zonas con m\u00fasica propia no se mezclan con otras emisoras. Respeta el bot\u00f3n de silencio.\\n- Estaciones en tiempo real. Influyen en lo que las chicas prefieren hacer, en la huerta y en las abejas.\\n- Mercado de abastos ampliado. Con alimentos del mundo posterior a la escasez, entre ellos insectos y cultivos celulares, y jalea real en la apicultura.\\n- Caras con expresi\u00f3n. Las chicas parpadean, miran y cambian de gesto: ojos de coraz\u00f3n al enamorarse, asombro en el mercadillo, calma al leer y sonrisa al comer o al ser acompa\u00f1adas.\\n- La noche. Todas duermen tumbadas: las parejas, abrazadas en su cama; las que viven solas, en su cama o en una colchoneta.\\n- Diario del pueblo. Un cuaderno que se rellena solo con lo que se ve: plantas, fauna marina, estaciones y fiestas, momentos de las chicas y postales. Sin puntos ni porcentajes.\\n- La asamblea. Para decidir qu\u00e9 arreglar o qu\u00e9 hacer en el pueblo hacen falta al menos 3 chicas libres; votan hasta 5, las m\u00e1s cercanas al cofre com\u00fan. Se re\u00fanen en la plaza junto a la Kutxa y votan entre las opciones que el cofre puede pagar. Las genoides no votan: trabajan.\\n\\nPRIVACIDAD, ACCESIBILIDAD E IDIOMAS\\n- Privacidad: sin cookies ni anuncios. El progreso se guarda solo en el dispositivo; el tiempo real se pide a Open-Meteo, que recibe solo las coordenadas de tu ciudad (o de Bilbao), el nombre si la buscas, y tu IP; la tipograf\u00eda se carga desde Google Fonts, que tambi\u00e9n ve tu IP; para llevarlo a otro se copia un c\u00f3digo o se descarga un archivo desde \u00abGuardar mi pueblo\u00bb.\\n- Idiomas: castellano, euskera, catal\u00e1n, gallego, ingl\u00e9s, franc\u00e9s, alem\u00e1n, italiano, ruso, chino, afrik\u00e1ans, \u00e1rabe (de derecha a izquierda) y castellano con un toque de cal\u00f3.\\n- Dispositivos: iPad, iPhone, ordenador y Smart TV, con modo pantalla completa y manejo con mando a distancia.\\n- Accesibilidad: bot\u00f3n de texto grande y zonas t\u00e1ctiles ampliadas.\\n- Ligero: un solo archivo que reduce efectos por s\u00ed solo si el equipo va justo.\\n&quot;, en: &quot;THE TOWN OF CHICACHICA \u00b7 WHITE PAPER\\nchicachica.com\\n\\nWHAT IT IS\\nThe Town of ChicaChica is an immersive world simulation: a solarpunk village where eight girls live their day on their own while the player watches, accompanies and cares for them. There is no score, no enemies and no way to lose.\\nIt is free to play in the browser, with no cookies and no ads. It is a single web file that runs on iPad, iPhone, desktop and Smart TV, with 13 language options.\\nIt is meant for all of humanity: for people playing for the first time and for people who have never played, of any age, in any language and on any screen. You need to know nothing to begin.\\n\\nPRINCIPLES\\nChicaChica is not a hoarding game: nothing is won, lost or piled up to beat anyone.\\n- No defeat, no enemies. The world keeps living whatever happens.\\n- The girls are free users who enjoy themselves. They choose how to spend the day: surfing, reading, training, cooking, strolling.\\n- The genoids only work, around the clock, 365 days a year. They never sit in the stands or play chess.\\n- The MIIG26D currency is internal. It has no real value and cannot be exchanged for anything.\\n- Free, with no cookies and no advertising.\\n\\nTHE WORLD\\nThe village is explored by zone, switched with the top bar or by tapping the tram, the signs and the stops.\\n- Town: houses, square, tram, digital library, gym, terrace, notice board and shared chest (the Kutxa).\\n- Beach and port: surfing, seaweed gathering, green hydrogen and the diving station.\\n- Seabed: egg-shaped robots measuring salinity, iodine, oxygen, methane and seismic activity.\\n- The Garden: tractor, harvester genoids, beehives, seed bank and plant care.\\n- Market: stalls for fruit, flour, dairy, pulses, algae and mushrooms, grains and roots, and beekeeping; the girls shop according to their hunger.\\n- Industrial zone: 3D printer and the town's production panel.\\n- Arena: multi-sport stadium, holographic theatre, chess table and fashion boutique.\\n- OSASU Hospital: reception with wearables, therapy capsule, laboratory with cryobank and recovery room.\\n\\nWHO LIVES THERE\\nEight girls, each with her own look and temperament: the adventurous surfer, the shy intellectual, the dreamy botanist, the combative athlete, the outgoing artist, the methodical chef, the lazy gamer and the curious explorer. Their character shapes what they do, how fast they walk and who they spend time with.\\nThey remember their habits, and the hospital treats them according to what they live: too many hours sitting call for back care; too much beach sun, for the skin.\\nThe genoids are the town's staff: they harvest, tend, run the hospital and manufacture, always working.\\nThe names each player gives the girls are private: they are stored only on the player's device and appear only in the hospital.\\n\\nA CAUSAL WORLD\\nThe village follows the device's real time and cannot be fast-forwarded.\\n- Day and night: the light follows the real clock in every zone.\\n- Seasons: one every three calendar months (winter from December to February, spring from March to May, summer from June to August, autumn from September to November).\\n- The sea responds to the town: oxygen, salinity, iodine, methane and seismic activity are computed from heat, evaporation, irrigation, waste and industrial output, not at random.\\n\\nA LIVING VILLAGE\\nThere are no goals or levels: the village is simply alive, and you can watch it up close.\\n- Follow a girl. Double-tap her and the camera accompanies her; double-tap again to let go. She is identified by her trade and temperament, never by her private name.\\n- Village chronicle. The notice board records what happens and is translated into the chosen language.\\n- Zone sound. The beach sounds of sea and gulls, the garden of stream and birds, the market of murmur, the industrial zone of a low hum and the hospital of relaxing music. Zones with their own music never mix with other stations. It respects the mute button.\\n- Real-time seasons. They shape what the girls prefer to do, the garden and the bees.\\n- A larger food market. With foods from the post-scarcity world, including insects and cell-cultured foods, and royal jelly in the apiculture stall.\\n- Expressive faces. The girls blink, look around and change expression: heart eyes when they fall in love, wonder at the market, calm while reading and a smile when eating or being accompanied.\\n- The night. Everyone sleeps lying down: couples hugging in their bed; those who live alone in their bed or on a mattress.\\n- Village journal. A notebook that fills itself with what the player sees: plants, marine life, seasons and festivals, the girls' moments and postcards. No points or percentages.\\n- The assembly. To decide what to fix or what to do in the village, at least 3 free girls are needed; up to 5 vote, the ones closest to the shared chest. They gather in the square by the Kutxa and vote among the options the chest can afford. The genoids do not vote: they work.\\n\\nPRIVACY, ACCESSIBILITY AND LANGUAGES\\n- Privacy: no cookies and no ads. Progress is stored only on the device; the live weather is requested from Open-Meteo, which receives only your city's coordinates (or Bilbao's), the name if you search for it, and your IP; the typeface is loaded from Google Fonts, which also sees your IP; to move it to another, copy a code or download a file from \\&quot;Save my town\\&quot;.\\n- Languages: Spanish, Basque, Catalan, Galician, English, French, German, Italian, Russian, Chinese, Afrikaans, Arabic (right-to-left) and Spanish with a touch of Cal\u00f3.\\n- Devices: iPad, iPhone, desktop and Smart TV, with full-screen mode and remote-control navigation.\\n- Accessibility: a large-text button and enlarged touch targets.\\n- Lightweight: a single file that reduces effects by itself if the device is struggling.\\n&quot; };&#10;    const $ = id =&gt; document.getElementById(id); let k = 'es';&#10;    const estado = (t, ok = true) =&gt; { const e = $('libroEstado'); if (e) { e.textContent = t; e.style.color = ok ? '#7cffd9' : '#ffb3a8'; } };&#10;    const pintar = () =&gt; { $('libroTexto').value = T[k]; $('libroIdioma').textContent = k === 'es' ? 'ES \u2192 EN' : 'EN \u2192 ES'; $('libroTexto').dir = 'ltr'; $('libroTexto').scrollTop = 0; };&#10;    function abrir() { let l = 'es'; try { l = (localStorage.getItem('chicachica:idioma') || navigator.language || 'es').slice(0, 2).toLowerCase(); } catch (e) {} k = ['es', 'eu', 'ca', 'gl', 'calo'].includes(l) ? 'es' : 'en'; pintar(); estado(''); $('libro').hidden = false; try { $('libroCerrar').focus(); } catch (e) {} }&#10;    function cerrar() { $('libro').hidden = true; }&#10;    async function copiar() { const t = $('libroTexto'); try { await navigator.clipboard.writeText(t.value); estado('Texto copiado \u2714'); return; } catch (e) {} try { t.focus(); t.select(); t.setSelectionRange(0, t.value.length); estado(document.execCommand &amp;&amp; document.execCommand('copy') ? 'Texto copiado \u2714' : 'Selecci\u00f3nalo y c\u00f3pialo a mano', true); } catch (e) { estado('Selecci\u00f3nalo y c\u00f3pialo a mano', false); } }&#10;    async function descargar() {&#10;        const txt = T[k], nombre = 'chicachica-libro-blanco-' + k + '.txt';&#10;        { const r = await ofrecerDescarga(nombre, txt); if (r === true) { estado('Descargado \u2714'); return; } if (r === 'no') return; }&#10;        try { const f = new File([txt], nombre, { type: 'text\/plain' }); if (navigator.canShare &amp;&amp; navigator.canShare({ files: [f] })) { await navigator.share({ files: [f], title: 'El Pueblo de ChicaChica' }); estado('Listo \u2714'); return; } } catch (e) { if (e &amp;&amp; e.name === 'AbortError') return; }&#10;        try { const url = URL.createObjectURL(new Blob([txt], { type: 'text\/plain' })), a = document.createElement('a'); a.href = url; a.download = nombre; document.body.appendChild(a); a.click(); a.remove(); setTimeout(() =&gt; URL.revokeObjectURL(url), 4000); estado('Descargado \u2714 (si no ves nada, copia el texto)'); }&#10;        catch (e) { estado('No se pudo descargar aqu\u00ed: copia el texto.', false); }&#10;    }&#10;    const L = $('libro'); if (L) L.addEventListener('pointerdown', e =&gt; e.stopPropagation());&#10;    const b = $('libroAbrir'); if (b) { b.addEventListener('pointerdown', e =&gt; e.stopPropagation()); b.addEventListener('click', abrir); }&#10;    [['libroCerrar', cerrar], ['libroCopiar', copiar], ['libroDescargar', descargar], ['libroIdioma', () =&gt; { k = k === 'es' ? 'en' : 'es'; pintar(); estado(''); }]].forEach(([id, f]) =&gt; { const e = $(id); if (e) e.addEventListener('click', f); });&#10;    document.addEventListener('keydown', e =&gt; { if (e.key === 'Escape' &amp;&amp; L &amp;&amp; !L.hidden) cerrar(); });&#10;    return { abrir };&#10;})();&#10;const Postal = (() =&gt; {&#10;    const chip = document.getElementById('navPostal'), modal = document.getElementById('postalModal'), img = document.getElementById('postalImg'), aviso = document.getElementById('postalAviso');&#10;    const bComp = document.getElementById('postalCompartir'), bDesc = document.getElementById('postalDescargar'), bCerr = document.getElementById('postalCerrar');&#10;    let url = null, blob = null;&#10;    const escena = () =&gt; enBiblioteca ? 'La biblioteca' : enPuerto ? 'El puerto' : enGimnasio ? 'El gimnasio' : casaAbierta !== null ? 'Una casa' : enIndustria ? 'La Zona Industrial' : enMercado ? 'El Mercado' : enHuerta ? 'La Huerta' : enPlaya ? 'La playa' : 'El pueblo';&#10;    function rr(g, x, y, w, h, r) { g.beginPath(); if (g.roundRect) g.roundRect(x, y, w, h, r); else g.rect(x, y, w, h); }&#10;    function componer() {&#10;        const W = canvas.width, H = canvas.height, M = 16, P = 54, c = document.createElement('canvas'); c.width = W + 2 * M; c.height = H + M + P; const g = c.getContext('2d');&#10;        const bg = g.createLinearGradient(0, 0, c.width, c.height); bg.addColorStop(0, '#ff69b4'); bg.addColorStop(1, '#6a3e8c'); g.fillStyle = bg; g.fillRect(0, 0, c.width, c.height);&#10;        g.save(); rr(g, M, M, W, H, 16); g.clip(); g.drawImage(canvas, M, M); g.restore(); g.strokeStyle = 'rgba(255,255,255,0.92)'; g.lineWidth = 3; rr(g, M, M, W, H, 16); g.stroke();&#10;        const F = typeof fiestaActual === 'function' ? fiestaActual() : null, fecha = new Date().toLocaleDateString('es-ES', { day: 'numeric', month: 'long', year: 'numeric' }), yb = H + M + P \/ 2;&#10;        g.textBaseline = 'middle'; g.fillStyle = '#fff5fa'; g.textAlign = 'left'; g.font = &quot;800 24px 'Plus Jakarta Sans','Comic Sans MS',sans-serif&quot;; g.fillText('El Pueblo de ChicaChica \ud83d\udc9c\ud83c\udf38', M + 8, yb + 2);&#10;        g.textAlign = 'right'; g.font = &quot;700 15px 'Plus Jakarta Sans','Comic Sans MS',sans-serif&quot;; g.fillText(escena() + (F ? ' \u00b7 ' + F.txt : '') + ' \u00b7 ' + fecha, W + M - 8, yb - 9);&#10;        g.font = &quot;600 12px 'Plus Jakarta Sans','Comic Sans MS',sans-serif&quot;; g.fillStyle = 'rgba(255,245,250,0.85)'; g.fillText('chicachica.com', W + M - 8, yb + 11);&#10;        return c;&#10;    }&#10;    function cerrar() { if (modal) modal.hidden = true; if (url) { URL.revokeObjectURL(url); url = null; } blob = null; }&#10;    function mostrar(b, dataUrl) { blob = b; if (url) URL.revokeObjectURL(url); url = b ? URL.createObjectURL(b) : null; if (img) img.src = url || dataUrl; if (modal) modal.hidden = false; if (aviso) aviso.textContent = 'Si no se descarga, mant\u00e9n pulsada la imagen y elige \u00abGuardar\u00bb.'; }&#10;    function tomar() {&#10;        diarioNota('postales', escena(), escena(), '\ud83d\udcf8');&#10;        try { const c = componer(); if (c.toBlob) c.toBlob(b =&gt; { if (b) mostrar(b); else mostrar(null, c.toDataURL('image\/png')); }, 'image\/png'); else mostrar(null, c.toDataURL('image\/png')); }&#10;        catch (e) { const a = document.getElementById('avisoKutxa'); if (a) { a.textContent = '\ud83d\udcf8 No se ha podido sacar la postal en este navegador.'; a.classList.add('ver'); setTimeout(() =&gt; a.classList.remove('ver'), 3500); } }&#10;    }&#10;    async function descargar() { try { const b = blob || (img &amp;&amp; img.src ? await (await fetch(img.src)).blob() : null); if (b) { const r = await ofrecerDescarga('postal-chicachica.png', b); if (r === true) { if (aviso) aviso.textContent = 'Postal guardada \u2714'; return; } if (r === 'no') return; } } catch (e) {}&#10;        const href = url || (img &amp;&amp; img.src); if (!href) return; const a = document.createElement('a'); a.href = href; a.download = 'postal-chicachica.png'; (document.body || document).appendChild(a); a.click(); if (a.remove) a.remove(); }&#10;    async function compartir() {&#10;        try { const f = new File([blob], 'postal-chicachica.png', { type: 'image\/png' }); await navigator.share({ files: [f], title: 'El Pueblo de ChicaChica', text: 'Mi pueblo en ChicaChica \ud83d\udc9c\ud83c\udf38' }); }&#10;        catch (e) { if (e &amp;&amp; e.name !== 'AbortError' &amp;&amp; aviso) aviso.textContent = 'No se ha podido compartir desde aqu\u00ed: usa \u00abDescargar\u00bb o mant\u00e9n pulsada la imagen.'; }&#10;    }&#10;    if (chip) { chip.addEventListener('click', tomar); chip.addEventListener('keydown', e =&gt; { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); tomar(); } }); }&#10;    if (bCerr) bCerr.addEventListener('click', cerrar); if (bDesc) bDesc.addEventListener('click', descargar); if (bComp) bComp.addEventListener('click', compartir);&#10;    if (modal) modal.addEventListener('pointerdown', e =&gt; { e.stopPropagation(); if (e.target === modal) cerrar(); });&#10;    document.addEventListener('keydown', e =&gt; { if (e.key === 'Escape') cerrar(); });&#10;    try { if (bComp &amp;&amp; typeof navigator !== 'undefined' &amp;&amp; navigator.canShare &amp;&amp; navigator.canShare({ files: [new File([new Blob(['x'])], 'a.png', { type: 'image\/png' })] })) bComp.hidden = false; } catch (e) {}&#10;    return { tomar, cerrar };&#10;})();&#10;const Cronica = (() =&gt; {   \/\/ lo que hacen las chicas queda en el tabl\u00f3n de avisos, sin textos flotantes&#10;    const FR = { surf: ['\ud83c\udfc4', 'se ha ido a surfear.'], lectura: ['\ud83d\udcda', 'se ha sumergido en la biblioteca.'], gym: ['\ud83c\udfcb\ufe0f', 'entrena en el gimnasio.'], huerta: ['\ud83c\udf31', 'cuida la huerta.'], cocina: ['\ud83c\udf73', 'cocina en casa.'], mercado: ['\ud83d\uded2', 'hace la compra.'], paseo: ['\ud83d\udeb6', 'da un paseo.'], descanso: ['\ud83d\ude34', 'se ha ido a descansar.'], tranvia: ['\ud83d\ude8b', 'coge el tranv\u00eda.'], playa: ['\u26f1\ufe0f', 'toma el sol en la playa.'] };&#10;    const EST = { primavera: '\ud83c\udf38 Empieza la primavera: el pueblo florece.', verano: '\u2600\ufe0f Empieza el verano: d\u00edas largos y mucho sol.', oto\u00f1o: '\ud83c\udf42 Empieza el oto\u00f1o: el pueblo se viste de hojas.', invierno: '\u2744\ufe0f Empieza el invierno: las abejas se recogen.' };&#10;    const prev = [], ult = []; let ultH = -1, ultC = 0;&#10;    const leer = k =&gt; { try { return localStorage.getItem(k); } catch (e) { return null; } }, guardar = (k, v) =&gt; { try { localStorage.setItem(k, v); } catch (e) {} };&#10;    function tick(now) {&#10;        if (now - ultC &lt; 4000) return; ultC = now;&#10;        habitantes.forEach((h, i) =&gt; {&#10;            let k; try { k = Memoria.cat(h); } catch (e) { return; }&#10;            if (prev[i] === undefined) { prev[i] = k; return; }&#10;            if (k !== prev[i]) { prev[i] = k; const f = FR[k]; if (f &amp;&amp; now - (ult[i] || 0) &gt; 600000) { ult[i] = now; Noticias.publicar(f[0] + ' ' + PERSONAS[i].rol + ' ' + f[1]); } }&#10;        });&#10;        const hh = new Date().getHours();&#10;        if (ultH !== -1 &amp;&amp; hh !== ultH) { if (hh === 7) Noticias.publicar('\ud83c\udf05 Amanece en el pueblo.', 'alba', 3600000); if (hh === 20) Noticias.publicar('\ud83c\udf19 Cae la noche sobre el pueblo.', 'noche', 3600000); }&#10;        ultH = hh;&#10;        const e = obtenerEstacion(), g = leer('chicachica:estacion'); if (g !== e) { guardar('chicachica:estacion', e); if (g) Noticias.publicar(EST[e], 'est', 86400000); }&#10;        if (Mar.gas() &gt; .6) Noticias.publicar('\ud83e\udee7 Sube el metano del fondo marino: el mar pide calma.', 'gas', 1800000);&#10;        if (Mar.sis() &gt; .6) Noticias.publicar('\ud83d\udcc8 Crece la actividad s\u00edsmica bajo el mar.', 'sis', 1800000);&#10;    }&#10;    return { tick, EST };&#10;})();&#10;const Seguir = (() =&gt; {   \/\/ doble toque sobre una chica: la c\u00e1mara la acompa\u00f1a; otro doble toque (o el zoom) la suelta&#10;    let h = null, nivelPrev = 1, uh = null, ut = 0;&#10;    const enPueblo = () =&gt; pantallaActual() === 'pueblo' &amp;&amp; !enBiblioteca &amp;&amp; !enGimnasio &amp;&amp; !casaAbierta &amp;&amp; !enPlaya &amp;&amp; !enPuerto &amp;&amp; !enSubmarino;&#10;    function parar() { if (!h) return; h = null; if (nivelPrev &lt;= 1) { try { Zoom.mover('reset'); } catch (e) {} } }&#10;    function activar(x) { h = x; nivelPrev = Zoom.nivel(); if (nivelPrev &lt;= 1) Zoom.fijar(1.8); }&#10;    function toque(x) { const now = performance.now(), doble = uh === x &amp;&amp; now - ut &lt; 420; uh = x; ut = now; if (!doble) return false; uh = null; if (h === x) parar(); else activar(x); return true; }&#10;    function tick() { if (!h) return; if (h.oculta || !enPueblo() || Zoom.nivel() &lt;= 1) { const z = Zoom.nivel() &gt; 1 &amp;&amp; nivelPrev &lt;= 1; h = null; if (z) { try { Zoom.mover('reset'); } catch (e) {} } return; } Zoom.centrar(h.x, h.y - 30, .12); }&#10;    function dibujar() {&#10;        if (!h || !enPueblo()) return; const i = habitantes.indexOf(h); if (i &lt; 0) return; const p = PERSONAS[i];&#10;        ctx.save(); ctx.strokeStyle = 'rgba(255,255,255,.85)'; ctx.lineWidth = 2; ctx.setLineDash([5, 4]); ctx.beginPath(); ctx.ellipse(h.x, h.y + 24, 28, 8, 0, 0, Math.PI * 2); ctx.stroke(); ctx.setLineDash([]);&#10;        const s = '\ud83d\udc41 ' + p.ic + ' ' + p.rol + ' \u00b7 ' + p.temp.n; ctx.font = 'bold 12px sans-serif'; const w = ctx.measureText(s).width + 20, x = Math.max(6, Math.min(canvas.width - w - 6, h.x - w \/ 2)), y = Math.max(6, h.y - 92);&#10;        ctx.fillStyle = 'rgba(30,14,40,.72)'; ctx.beginPath(); ctx.roundRect(x, y, w, 22, 11); ctx.fill(); ctx.fillStyle = '#fff'; ctx.textAlign = 'left'; ctx.textBaseline = 'middle'; ctx.fillText(s, x + 10, y + 11); ctx.restore();&#10;    }&#10;    return { toque, tick, dibujar, parar, activo: () =&gt; !!h };&#10;})();&#10;const SonidoZona = (() =&gt; {   \/\/ sonido de cada zona hecho con WebAudio (sin archivos): olas, murmullo, zumbido, viento y p\u00e1jaros de d\u00eda (de noche suena la emisora Ambiente suave)&#10;    let A = null, ult = 0, ultAve = 0, ultBip = 0, ultAbeja = 0, ultGav = 0;&#10;    function construir() {&#10;        const c = audioCtx, m = c.createGain(); m.gain.value = .55; m.connect(masterGain);&#10;        const buf = c.createBuffer(1, c.sampleRate * 2, c.sampleRate), d = buf.getChannelData(0); for (let i = 0; i &lt; d.length; i++) d[i] = Math.random() * 2 - 1;&#10;        const capa = (tipo, f, q) =&gt; { const s = c.createBufferSource(); s.buffer = buf; s.loop = true; const fl = c.createBiquadFilter(); fl.type = tipo; fl.frequency.value = f; fl.Q.value = q || .7; const g = c.createGain(); g.gain.value = 0; s.connect(fl); fl.connect(g); g.connect(m); s.start(); return { g, fl }; };&#10;        const olas = capa('lowpass', 650, .5), lfo = c.createOscillator(), lg = c.createGain(); lfo.frequency.value = .11; lg.gain.value = .5; lfo.connect(lg); lg.connect(olas.fl.frequency); lfo.start(); olas.fl.frequency.value = 650;&#10;        const gente = capa('bandpass', 700, .9), agua = capa('lowpass', 240, .5), viento = capa('bandpass', 2600, .6);&#10;        const arroyo = capa('bandpass', 1500, .8);                                                            \/\/ agua de riego: ruido suave y grave, sin osciladores&#10;        const hum = c.createOscillator(), hg = c.createGain(); hum.type = 'sine'; hum.frequency.value = 58; hg.gain.value = 0; hum.connect(hg); hg.connect(m); hum.start();&#10;        A = { c, m, olas, gente, agua, viento, arroyo, grillos: { g: { gain: { setTargetAtTime() {} } } }, hum: { g: hg } };&#10;    }&#10;    function zona() { return enSubmarino ? 'submarino' : enPuerto ? 'puerto' : enPlaya ? 'playa' : enHospital ? 'hospital' : enArena ? 'arena' : enIndustria ? 'industria' : enMercado ? 'mercado' : enHuerta ? 'huerta' : enBiblioteca ? 'biblioteca' : enGimnasio ? 'gimnasio' : 'pueblo'; }&#10;    const MAPA = { pueblo: { v: .35, a: 1 }, playa: { o: .5, gv: 1 }, puerto: { o: .4, h: .08, v: .2 }, submarino: { w: .55 }, huerta: { r: .09, a: 1 }, mercado: { g: .22 }, industria: { h: .14 }, hospital: {}, arena: { g: .24 }, biblioteca: { v: .05 }, gimnasio: { h: .06, g: .1 } };&#10;    function nota(f0, f1, dur, vol, t0) { const c = A.c, o = c.createOscillator(), g = c.createGain(); o.type = 'sine'; o.frequency.setValueAtTime(f0, t0); o.frequency.exponentialRampToValueAtTime(f1, t0 + dur); g.gain.setValueAtTime(0, t0); g.gain.linearRampToValueAtTime(vol, t0 + dur * .2); g.gain.linearRampToValueAtTime(0, t0 + dur); o.connect(g); g.connect(A.m); o.start(t0); o.stop(t0 + dur + .02); }&#10;    function tick(now) {&#10;        if (!audioIniciado || !audioCtx || silenciado || audioCtx.state !== 'running' || now - ult &lt; 500) return; ult = now;&#10;        if (!A) { try { construir(); } catch (e) { A = null; return; } }&#10;        const z = zona(), M = Radio.suena() ? {} : (MAPA[z] || {}), t = A.c.currentTime, noche = Dia.k() &gt; .5;   \/\/ si suena una emisora, el sonido de zona se aparta: nunca se mezclan&#10;        const set = (n, v) =&gt; n.g.gain.setTargetAtTime(v || 0, t, .9);&#10;        set(A.olas, M.o); set(A.gente, M.g); set(A.agua, M.w); set(A.viento, M.v); set(A.hum, M.h); set(A.arroyo, M.r); set(A.grillos, M.c);&#10;        const aves = M.a &amp;&amp; !noche &amp;&amp; now - ultAve &gt; 2500 + Math.random() * 5000;&#10;        if (M.gv &amp;&amp; !noche &amp;&amp; now - ultGav &gt; 4000 + Math.random() * 8000) { ultGav = now; const f = 1800 + Math.random() * 300; nota(f, f * .62, .4, .03, t); nota(f * 1.04, f * .6, .32, .02, t + .45); }            \/\/ gaviotas: grito largo y descendente, nada que ver con los pajarillos del campo&#10;        if (M.p &amp;&amp; now - ultBip &gt; 1700) { ultBip = now; nota(880, 880, .09, .02, t); nota(880, 880, .09, .012, t + .75); }                         \/\/ monitor lejano, muy suave&#10;        if (M.z &amp;&amp; !noche &amp;&amp; now - ultAbeja &gt; 3500 + Math.random() * 6000) { ultAbeja = now; const f = 190 + Math.random() * 50; nota(f, f * 1.12, .7, .014, t); nota(f * 1.01, f * 1.1, .6, .01, t + .08); }   \/\/ una abeja que pasa&#10;        if (aves) { ultAve = now; const f = 2600 + Math.random() * 1400, n = 2 + (Math.random() * 3 | 0); for (let i = 0; i &lt; n; i++) nota(f * (1 + i * .06), f * (1.25 + Math.random() * .2), .09, .028 * M.a, t + i * .13); }&#10;    }&#10;    return { tick, zona };&#10;})();&#10;const SEMANAL = { invierno: { tranvia: .5, terraza: .4, banco: .7, biblioteca: 1.5, teletrabajo: 1.3, gimnasio: 1.2, mercadillo: 1.1 }, verano: { tranvia: 1.5, terraza: 1.6, paseo: 1.2, biblioteca: .8 }, primavera: { paseo: 1.4, mercadillo: 1.2, terraza: 1.2 }, oto\u00f1o: { biblioteca: 1.2, mercadillo: 1.2, paseo: .9, teletrabajo: 1.1 } };&#10;(() =&gt; { const p0 = Personas.peso; Personas.peso = (h, k) =&gt; p0(h, k) * ((SEMANAL[obtenerEstacion()] || {})[k] || 1); })();   \/\/ la estaci\u00f3n real inclina lo que apetece hacer&#10;let ultAvisoError = 0;&#10;function avisarError() {&#10;    const ahora = Date.now(); if (ahora - ultAvisoError &lt; 30000) return; ultAvisoError = ahora; const a = document.getElementById('avisoKutxa');&#10;    if (a) { a.textContent = '\u26a0\ufe0f Algo no ha ido bien. Si el pueblo se ve raro, recarga la p\u00e1gina.'; a.classList.add('ver'); setTimeout(() =&gt; a.classList.remove('ver'), 5000); }&#10;}&#10;function bucle() {&#10;    try { ctx.setTransform(1, 0, 0, 1, 0, 0); ctx.globalAlpha = 1; ctx.globalCompositeOperation = 'source-over'; bucleInterno(); }&#10;    catch (e) { console.error(e); avisarError(); }&#10;    requestAnimationFrame(bucle);&#10;}&#10;window.addEventListener('error', avisarError); window.addEventListener('unhandledrejection', avisarError);&#10;document.addEventListener('visibilitychange', () =&gt; { if (!audioCtx) return; if (document.hidden) audioCtx.suspend().catch(() =&gt; {}); else if (!silenciado) audioCtx.resume().catch(() =&gt; {}); });&#10;Persistencia.iniciar();                                                          \/\/ carga el progreso guardado y activa el guardado autom\u00e1tico&#10;bucle();&#10;Portada.listo();                                                                      \/\/ activa los botones de la portada&#10;const PistaEscena = (() =&gt; {   \/\/ el texto de ayuda bajo el t\u00edtulo cambia seg\u00fan el lugar&#10;    const P = {&quot;playa&quot;: &quot;Arrastra a una chica al barco, a la tabla de surf o a una roca&quot;, &quot;pueblo&quot;: &quot;Arrastra a una chica a un patinete, a un banco, a una casa o al tranv\u00eda; y toca el gimnasio&quot;, &quot;casa&quot;: &quot;Arrastra a una chica a cocinar, a barrer o a ba\u00f1arse: t\u00fa decides qu\u00e9 hace&quot;, &quot;gimnasio&quot;: &quot;Toca las m\u00e1quinas o arrastra a una chica para que entrene&quot;, &quot;biblioteca&quot;: &quot;Arrastra a una chica a la mesa de la biblioteca para que lea y estudie&quot;, &quot;huerta&quot;: &quot;Toca la tierra para elegir qu\u00e9 sembrar; las genoides cuidan la huerta d\u00eda y noche&quot;, &quot;mercado&quot;: &quot;Toca un puesto para hacer tu compra; las chicas vienen cuando tienen hambre&quot;, &quot;industria&quot;: &quot;Aqu\u00ed trabajan las genoides d\u00eda y noche; toca las m\u00e1quinas para ver qu\u00e9 fabrican&quot;, &quot;arena&quot;: &quot;Arrastra a una chica a la grada, al teatro, al ajedrez o al sastre&quot;, &quot;hospital&quot;: &quot;Toca una cama o una m\u00e1quina; aqu\u00ed se cuidan con calma&quot;, &quot;puerto&quot;: &quot;Arrastra a una chica a un barco o al submarino&quot;, &quot;submarino&quot;: &quot;Mira el fondo marino: peces, corales y medusas viven a su aire&quot;}, el = document.querySelector('p.pista'); let ult = '';&#10;    const id = () =&gt; enHospital ? 'hospital' : enArena ? 'arena' : enSubmarino ? 'submarino' : enPuerto ? 'puerto' : enPlaya ? 'playa' : enHuerta ? 'huerta' : enMercado ? 'mercado' : enIndustria ? 'industria' : enGimnasio ? 'gimnasio' : enBiblioteca ? 'biblioteca' : casaAbierta !== null ? 'casa' : 'pueblo';&#10;    function poner() { if (!el) return; const e = id(); if (e === ult) return; ult = e; el.textContent = P[e]; if (typeof Idioma !== 'undefined') Idioma.aplicar(); }&#10;    setInterval(poner, 400); poner();&#10;})();&#10;const TIEMPO_LUGAR = { lat: 43.26, lon: -2.93 };&#10;const CLAVE_CIUDAD = 'chicachica:ciudad';&#10;function lugarTiempo() { try { const c = JSON.parse(localStorage.getItem(CLAVE_CIUDAD) || 'null'); if (c &amp;&amp; typeof c.lat === 'number' &amp;&amp; typeof c.lon === 'number') return c; } catch (e) {} return TIEMPO_LUGAR; }   \/\/ lugar fijo del pueblo (cambia estas dos cifras por tu ciudad); no se pide la ubicaci\u00f3n a nadie&#10;var Tiempo = (() =&gt; {   \/\/ tiempo real del lugar del pueblo (Open-Meteo, gratis y sin clave); si no hay red, el pueblo sigue como siempre&#10;    let est = null, ult = 0;&#10;    function leer(c) {&#10;        const w = c.weather_code, v = c.wind_speed_10m || 0, nub = c.cloud_cover || 0;&#10;        const tipo = (w &gt;= 71 &amp;&amp; w &lt;= 77) || w === 85 || w === 86 ? 'nieve' : ((w &gt;= 51 &amp;&amp; w &lt;= 67) || (w &gt;= 80 &amp;&amp; w &lt;= 82) || w &gt;= 95) ? 'lluvia' : v &gt;= 32 ? 'viento' : (w === 0 || w === 1) &amp;&amp; nub &lt; 35 ? 'soleado' : 'parcial';&#10;        est = { tipo, nub }; climaSinSol = tipo === 'lluvia' || tipo === 'nieve' || nub &gt;= 85; climaPlaya = tipo === 'nieve' ? 'parcial' : tipo;&#10;    }&#10;    async function pedir() {&#10;        ult = performance.now();&#10;        try {&#10;            const r = await fetch('https:\/\/api.open-meteo.com\/v1\/forecast?latitude=' + lugarTiempo().lat + '&amp;longitude=' + lugarTiempo().lon + '&amp;current=weather_code,wind_speed_10m,cloud_cover', { cache: 'no-store' });&#10;            if (!r.ok) return; const j = await r.json(); if (j &amp;&amp; j.current) leer(j.current);&#10;        } catch (e) {}&#10;    }&#10;    const exterior = () =&gt; !(enSubmarino || enPlaya || enMercado || enIndustria || enBiblioteca || enGimnasio || enHospital || enArena || casaAbierta !== null);&#10;    function dibujar() {&#10;        if (performance.now() - ult &gt; 1800000) pedir();&#10;        if (!est || !exterior()) return;&#10;        const W = canvas.width, H = canvas.height; ctx.save();&#10;        if (est.tipo === 'lluvia' || est.tipo === 'nieve') { ctx.fillStyle = est.tipo === 'lluvia' ? 'rgba(55,68,92,0.26)' : 'rgba(205,222,240,0.16)'; ctx.fillRect(0, 0, W, H); }&#10;        else if (est.nub &gt; 70) { ctx.fillStyle = 'rgba(120,130,145,0.09)'; ctx.fillRect(0, 0, W, H); }&#10;        if (est.tipo === 'lluvia') {&#10;            ctx.strokeStyle = 'rgba(190,215,240,0.55)'; ctx.lineWidth = 1.2; ctx.beginPath();&#10;            for (let i = 0; i &lt; 110; i++) { const x = (i * 97 + t * 1.5) % (W + 40) - 20, y = (i * 53 + t * 9) % H; ctx.moveTo(x, y); ctx.lineTo(x - 3, y + 11); }&#10;            ctx.stroke();&#10;        } else if (est.tipo === 'nieve') {&#10;            ctx.fillStyle = 'rgba(255,255,255,0.85)';&#10;            for (let i = 0; i &lt; 80; i++) { const x = (i * 83 + Math.sin(t \/ 40 + i) * 14) % W, y = (i * 47 + t * (1 + (i % 4) * .4)) % H; ctx.beginPath(); ctx.arc(x &lt; 0 ? x + W : x, y, 1.6 + (i % 3) * .6, 0, Math.PI * 2); ctx.fill(); }&#10;        }&#10;        ctx.restore();&#10;    }&#10;    pedir();&#10;    return { dibujar, estado: () =&gt; est, repetir: () =&gt; { est = null; pedir(); } };&#10;})();&#10;const CiudadTiempo = (() =&gt; {   \/\/ cada jugadora escribe su ciudad; solo se guarda en su dispositivo&#10;    const $ = id =&gt; document.getElementById(id), inp = $('ciudadTxt'), btn = $('ciudadBuscar'), est = $('ciudadEstado'); if (!inp || !btn) return {};&#10;    const msg = (t, ok = true) =&gt; { est.textContent = t; est.style.color = ok ? '#7cffd9' : '#ffb3a8'; };&#10;    try { const c = JSON.parse(localStorage.getItem(CLAVE_CIUDAD) || 'null'); if (c &amp;&amp; c.n) inp.value = c.n; } catch (e) {}&#10;    async function buscar() {&#10;        const q = inp.value.trim();&#10;        if (!q) { try { localStorage.removeItem(CLAVE_CIUDAD); } catch (e) {} msg('Vuelves al tiempo de Bilbao'); Tiempo.repetir(); return; }&#10;        btn.disabled = true;&#10;        try {&#10;            const r = await fetch('https:\/\/geocoding-api.open-meteo.com\/v1\/search?count=1&amp;language=es&amp;name=' + encodeURIComponent(q)); const j = await r.json();&#10;            const c = j &amp;&amp; j.results &amp;&amp; j.results[0];&#10;            if (!c) { msg('No he encontrado esa ciudad', false); return; }&#10;            const nombre = c.name + (c.country ? ', ' + c.country : '');&#10;            try { localStorage.setItem(CLAVE_CIUDAD, JSON.stringify({ n: c.name, lat: Math.round(c.latitude * 100) \/ 100, lon: Math.round(c.longitude * 100) \/ 100 })); } catch (e) {}&#10;            inp.value = c.name; msg('Ciudad elegida: ' + nombre); Tiempo.repetir();&#10;        } catch (e) { msg('Sin conexi\u00f3n: int\u00e9ntalo luego', false); } finally { btn.disabled = false; }&#10;    }&#10;    btn.addEventListener('click', buscar); inp.addEventListener('keydown', e =&gt; { e.stopPropagation(); if (e.key === 'Enter') { e.preventDefault(); buscar(); } }); inp.addEventListener('keyup', e =&gt; e.stopPropagation());&#10;    return { buscar };&#10;})();&lt;\/script&gt;&#10;&#10;&lt;\/body&gt;&#10;&lt;\/html&gt;&#10;\"><\/iframe><script>(function(){var f=document.getElementById('chicachica-juego');if(!f)return;var k='';function aj(){try{var d=f.contentDocument,w=d&&d.defaultView;if(!d||!d.body||!w)return;var box=d.getElementById('pantallaJuego'),c=d.querySelector('canvas');if(!box||!c)return;var tv=d.body.classList.contains('tv'),z=box.classList.contains('zoom'),W=f.clientWidth,top=Math.round(box.getBoundingClientRect().top),cw=box.clientWidth;if(tv)return;var key=[W,top,cw,z].join('|');if(key===k)return;var ch=z?(d.getElementById('lienzoWrap')||c).getBoundingClientRect().height:(Math.min(972,cw)-12)*0.5625+12;var mn=Math.max(560,Math.min(760,Math.round(window.innerHeight*0.9)));var H=Math.max(mn,Math.ceil(top+ch+24));H=Math.min(H,1400);k=key;f.style.height=H+'px';}catch(e){}}f.addEventListener('load',function(){k='';aj();});setInterval(aj,500);window.addEventListener('resize',function(){k='';aj();});})();<\/script>\n\n","protected":false},"excerpt":{"rendered":"<p>Un pueblo solarpunk donde ocho chicas viven su d\u00eda: huerta, mercado, playa, fiestas y el tiempo real de tu ciudad. Sin anuncios ni cookies, en 13 idiomas.<\/p>\n","protected":false},"author":2,"featured_media":2366,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-2361","page","type-page","status-publish","has-post-thumbnail","hentry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Juegos - ChicaChica<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/chicachica.com\/index.php\/el-pueblo-de-chicachica\/\" \/>\n<meta property=\"og:locale\" content=\"es_ES\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Juegos - ChicaChica\" \/>\n<meta property=\"og:description\" content=\"Un pueblo solarpunk donde ocho chicas viven su d\u00eda: huerta, mercado, playa, fiestas y el tiempo real de tu ciudad. Sin anuncios ni cookies, en 13 idiomas.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/chicachica.com\/index.php\/el-pueblo-de-chicachica\/\" \/>\n<meta property=\"og:site_name\" content=\"ChicaChica\" \/>\n<meta property=\"article:modified_time\" content=\"2026-11-01T10:48:07+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/chicachica.com\/wp-content\/uploads\/2026\/11\/IMG_7349.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Tiempo de lectura\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minuto\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/chicachica.com\\\/index.php\\\/el-pueblo-de-chicachica\\\/\",\"url\":\"https:\\\/\\\/chicachica.com\\\/index.php\\\/el-pueblo-de-chicachica\\\/\",\"name\":\"Juegos - ChicaChica\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/chicachica.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/chicachica.com\\\/index.php\\\/el-pueblo-de-chicachica\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/chicachica.com\\\/index.php\\\/el-pueblo-de-chicachica\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/chicachica.com\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/IMG_7349.png\",\"datePublished\":\"2026-11-01T01:06:32+00:00\",\"dateModified\":\"2026-11-01T10:48:07+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/chicachica.com\\\/index.php\\\/el-pueblo-de-chicachica\\\/#breadcrumb\"},\"inLanguage\":\"es\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/chicachica.com\\\/index.php\\\/el-pueblo-de-chicachica\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"es\",\"@id\":\"https:\\\/\\\/chicachica.com\\\/index.php\\\/el-pueblo-de-chicachica\\\/#primaryimage\",\"url\":\"https:\\\/\\\/chicachica.com\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/IMG_7349.png\",\"contentUrl\":\"https:\\\/\\\/chicachica.com\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/IMG_7349.png\",\"width\":1200,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/chicachica.com\\\/index.php\\\/el-pueblo-de-chicachica\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Portada\",\"item\":\"https:\\\/\\\/chicachica.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Juegos\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/chicachica.com\\\/#website\",\"url\":\"https:\\\/\\\/chicachica.com\\\/\",\"name\":\"ChicaChica\",\"description\":\"Tu otra comunidad en la que puedes ser t\u00fa misma\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/chicachica.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"es\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Juegos - ChicaChica","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/chicachica.com\/index.php\/el-pueblo-de-chicachica\/","og_locale":"es_ES","og_type":"article","og_title":"Juegos - ChicaChica","og_description":"Un pueblo solarpunk donde ocho chicas viven su d\u00eda: huerta, mercado, playa, fiestas y el tiempo real de tu ciudad. Sin anuncios ni cookies, en 13 idiomas.","og_url":"https:\/\/chicachica.com\/index.php\/el-pueblo-de-chicachica\/","og_site_name":"ChicaChica","article_modified_time":"2026-11-01T10:48:07+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/chicachica.com\/wp-content\/uploads\/2026\/11\/IMG_7349.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_misc":{"Tiempo de lectura":"1 minuto"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/chicachica.com\/index.php\/el-pueblo-de-chicachica\/","url":"https:\/\/chicachica.com\/index.php\/el-pueblo-de-chicachica\/","name":"Juegos - ChicaChica","isPartOf":{"@id":"https:\/\/chicachica.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/chicachica.com\/index.php\/el-pueblo-de-chicachica\/#primaryimage"},"image":{"@id":"https:\/\/chicachica.com\/index.php\/el-pueblo-de-chicachica\/#primaryimage"},"thumbnailUrl":"https:\/\/chicachica.com\/wp-content\/uploads\/2026\/11\/IMG_7349.png","datePublished":"2026-11-01T01:06:32+00:00","dateModified":"2026-11-01T10:48:07+00:00","breadcrumb":{"@id":"https:\/\/chicachica.com\/index.php\/el-pueblo-de-chicachica\/#breadcrumb"},"inLanguage":"es","potentialAction":[{"@type":"ReadAction","target":["https:\/\/chicachica.com\/index.php\/el-pueblo-de-chicachica\/"]}]},{"@type":"ImageObject","inLanguage":"es","@id":"https:\/\/chicachica.com\/index.php\/el-pueblo-de-chicachica\/#primaryimage","url":"https:\/\/chicachica.com\/wp-content\/uploads\/2026\/11\/IMG_7349.png","contentUrl":"https:\/\/chicachica.com\/wp-content\/uploads\/2026\/11\/IMG_7349.png","width":1200,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/chicachica.com\/index.php\/el-pueblo-de-chicachica\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Portada","item":"https:\/\/chicachica.com\/"},{"@type":"ListItem","position":2,"name":"Juegos"}]},{"@type":"WebSite","@id":"https:\/\/chicachica.com\/#website","url":"https:\/\/chicachica.com\/","name":"ChicaChica","description":"Tu otra comunidad en la que puedes ser t\u00fa misma","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/chicachica.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"es"}]}},"_links":{"self":[{"href":"https:\/\/chicachica.com\/index.php\/wp-json\/wp\/v2\/pages\/2361","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/chicachica.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/chicachica.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/chicachica.com\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/chicachica.com\/index.php\/wp-json\/wp\/v2\/comments?post=2361"}],"version-history":[{"count":3,"href":"https:\/\/chicachica.com\/index.php\/wp-json\/wp\/v2\/pages\/2361\/revisions"}],"predecessor-version":[{"id":2367,"href":"https:\/\/chicachica.com\/index.php\/wp-json\/wp\/v2\/pages\/2361\/revisions\/2367"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/chicachica.com\/index.php\/wp-json\/wp\/v2\/media\/2366"}],"wp:attachment":[{"href":"https:\/\/chicachica.com\/index.php\/wp-json\/wp\/v2\/media?parent=2361"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}