@camstack/addon-pipeline-orchestrator 1.2.228 → 1.2.229
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/viewer/.viewer-current-files.json +1 -1
- package/assets/viewer/.viewer-version +1 -1
- package/assets/viewer/_expo/static/js/web/{index-e6429c8ce26c653ed9b0a993208bb603.js → index-76e9a55d32d9d4f1d0792f1a7238c9a0.js} +3 -3
- package/assets/viewer/index.html +1 -1
- package/dist/{_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-Cva58zcK.mjs → _virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-DohWXqlQ.mjs} +1 -1
- package/dist/{hostInit-BiEedqeH.mjs → hostInit-kNgf11lz.mjs} +1 -1
- package/dist/remoteEntry.js +1 -1
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
".well-known/apple-app-site-association",
|
|
3
3
|
"_expo/static/js/web/Clipboard-8401b42fa72d38659ab95a80720451ed.js",
|
|
4
4
|
"_expo/static/js/web/Haptics-2b279984ce17de8962eacaeac6e3adde.js",
|
|
5
|
-
"_expo/static/js/web/index-
|
|
5
|
+
"_expo/static/js/web/index-76e9a55d32d9d4f1d0792f1a7238c9a0.js",
|
|
6
6
|
"_expo/static/js/web/node-fs-c482ac9b67ea8a97fbc955c3e63fe988.js",
|
|
7
7
|
"_expo/static/js/web/node-path-d45df1cbd13e0a24eb24cf5831bd2774.js",
|
|
8
8
|
"assets/node_modules/expo-router/assets/arrow_down.017bc6ba3fc25503e5eb5e53826d48a8.png",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0.
|
|
1
|
+
1.0.509+fb94b53
|
|
@@ -405,7 +405,7 @@ __d(function(g,r,i,_a,m,_e,_d){'use strict';m.exports=function(e,n,o,t,a,f,s,d){
|
|
|
405
405
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t}});var t={}},324,[]);
|
|
406
406
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.installOnUIRuntime=function(t){const o=globalThis?.expo?.installOnUIRuntime;if(!o)throw Error("Native method to install Expo Modules on the worklets UI runtime wasn't found in `expo-modules-core`.");o(t)}},325,[]);
|
|
407
407
|
__d(function(g,r,i,a,m,e,d){"use strict";var t,n,o;Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"AppOwnership",{enumerable:!0,get:function(){return t}}),Object.defineProperty(e,"ExecutionEnvironment",{enumerable:!0,get:function(){return n}}),Object.defineProperty(e,"UserInterfaceIdiom",{enumerable:!0,get:function(){return o}}),(function(t){t.Expo="expo"})(t||(t={})),(function(t){t.Bare="bare",t.Standalone="standalone",t.StoreClient="storeClient"})(n||(n={})),(function(t){t.Handset="handset",t.Tablet="tablet",t.Desktop="desktop",t.TV="tv",t.Unsupported="unsupported"})(o||(o={}))},326,[]);
|
|
408
|
-
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return s}});var t=r(d[0]);const n=(Date.now()+'-'+Math.floor(1e9*Math.random())).toString();function o(){if('undefined'!=typeof navigator&&'string'==typeof navigator.userAgent){const t=navigator.userAgent.toLowerCase();if(t.includes('edge'))return'Edge';if(t.includes('edg'))return'Chromium Edge';if(t.includes('opr')&&'opr'in window&&window.opr)return'Opera';if(t.includes('chrome')&&'chrome'in window&&window.chrome)return'Chrome';if(t.includes('trident'))return'IE';if(t.includes('firefox'))return'Firefox';if(t.includes('safari'))return'Safari'}}var s={get appOwnership(){return null},get executionEnvironment(){return t.ExecutionEnvironment.Bare},get sessionId(){return n},get isHeadless(){return'undefined'==typeof navigator||/\bHeadlessChrome\//.test(navigator.userAgent)},get expoVersion(){return this.manifest.sdkVersion||null},get linkingUri(){return'undefined'!=typeof location?location.origin:''},get expoRuntimeVersion(){return this.expoVersion},get deviceName(){return o()},get systemFonts(){return[]},get statusBarHeight(){return 0},get deviceYearClass(){return null},get manifest(){return"{\"name\":\"CamStack\",\"slug\":\"camstack\",\"version\":\"1.0.
|
|
408
|
+
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return s}});var t=r(d[0]);const n=(Date.now()+'-'+Math.floor(1e9*Math.random())).toString();function o(){if('undefined'!=typeof navigator&&'string'==typeof navigator.userAgent){const t=navigator.userAgent.toLowerCase();if(t.includes('edge'))return'Edge';if(t.includes('edg'))return'Chromium Edge';if(t.includes('opr')&&'opr'in window&&window.opr)return'Opera';if(t.includes('chrome')&&'chrome'in window&&window.chrome)return'Chrome';if(t.includes('trident'))return'IE';if(t.includes('firefox'))return'Firefox';if(t.includes('safari'))return'Safari'}}var s={get appOwnership(){return null},get executionEnvironment(){return t.ExecutionEnvironment.Bare},get sessionId(){return n},get isHeadless(){return'undefined'==typeof navigator||/\bHeadlessChrome\//.test(navigator.userAgent)},get expoVersion(){return this.manifest.sdkVersion||null},get linkingUri(){return'undefined'!=typeof location?location.origin:''},get expoRuntimeVersion(){return this.expoVersion},get deviceName(){return o()},get systemFonts(){return[]},get statusBarHeight(){return 0},get deviceYearClass(){return null},get manifest(){return"{\"name\":\"CamStack\",\"slug\":\"camstack\",\"version\":\"1.0.509\",\"sdkVersion\":\"57.0.0\",\"platforms\":[\"ios\",\"android\",\"web\"],\"runtimeVersion\":\"1.0.454\",\"orientation\":\"default\",\"icon\":\"./assets/images/icon.png\",\"scheme\":\"camstack\",\"userInterfaceStyle\":\"automatic\",\"web\":{\"output\":\"single\",\"favicon\":\"./assets/images/favicon.png\",\"shortName\":\"CamStack\",\"backgroundColor\":\"#e67e22\",\"name\":\"CamStack\"},\"experiments\":{\"typedRoutes\":true,\"reactCompiler\":true,\"baseUrl\":\"/viewer/camstack\"},\"extra\":{\"router\":{\"root\":\"app\"},\"eas\":{\"projectId\":\"8fb06894-6375-41ff-959f-1a22a03dbd73\"}},\"updates\":{\"url\":\"https://u.expo.dev/8fb06894-6375-41ff-959f-1a22a03dbd73\"},\"owner\":\"zentik-notifier\"}"},get manifest2(){return null},get experienceUrl(){return'undefined'!=typeof location?location.origin:''},get debugMode(){return!1},getWebViewUserAgentAsync:async()=>'undefined'!=typeof navigator?navigator.userAgent:null}},327,[326]);
|
|
409
409
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.SITEMAP_ROUTE_NAME=e.NOT_FOUND_ROUTE_NAME=e.INTERNAL_SLOT_NAME=void 0,e.INTERNAL_SLOT_NAME='__root',e.NOT_FOUND_ROUTE_NAME='+not-found',e.SITEMAP_ROUTE_NAME='_sitemap'},328,[]);
|
|
410
410
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.useCurrentRouteInfo=function(){const n=(0,u.useStateForPath)();return(0,t.useMemo)(()=>n?(0,o.getCachedRouteInfo)(n):void 0,[n])};const t=r(d[0]),o=r(d[1]),u=r(d[2])},329,[17,330,338]);
|
|
411
411
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.routeInfoSubscribe=e.routeInfoSubscribers=void 0,e.getCachedRouteInfo=function(s){let u=o.get(s);if(!u){u=(0,t.getRouteInfoFromState)(s);const f=JSON.stringify(u),c=n.get(f);c?u=c:n.set(f,u),o.set(s,u)}return u},e.setCachedRouteInfo=function(t,s){o.set(t,s),n.set(JSON.stringify(s),s)};const t=r(d[0]),o=new WeakMap,n=new Map;e.routeInfoSubscribers=new Set;e.routeInfoSubscribe=t=>(e.routeInfoSubscribers.add(t),()=>{e.routeInfoSubscribers.delete(t)})},330,[331]);
|
|
@@ -3586,7 +3586,7 @@ __d(function(g,r,i,a,m,_e,_d){"use strict";Object.defineProperty(_e,'__esModule'
|
|
|
3586
3586
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"CRASH_SCOPE",{enumerable:!0,get:function(){return l}}),e.setRunningBundle=function(t){s=t},e.readErrorUtils=u,e.reportFatal=f,e.installCrashReporter=function(s=(0,o.getExitMarkerRecorder)()){if(b)return!1;const c=u();if(null===c)return!1;b=!0;const k=c.getGlobalHandler?.();return c.setGlobalHandler((o,c)=>{if(!1===c){const s=(0,n.describeThrown)(o);t.log.warn(l,'non-fatal error reached the global handler',{message:s.message,stack:s.stack})}else f('js-fatal',o,s);k?.(o,c)}),!0},e.reportPreviousExit=async function(c=(0,o.getExitMarkerRecorder)()){const u=await c.readPrevious(),f=(0,n.classifyPreviousExit)(u);t.log.info(l,`previous runtime exit: ${f}`,{exit:f,crash:(0,n.isCrashExit)(f),markedAt:u?.at??null,message:u?.message??null,stack:u?.stack??null,version:s?.version??null,bundle:s?.bundle??null}),await c.arm()},e.bindExitMarkerToAppState=function(t,n=(0,o.getExitMarkerRecorder)()){let l=t.currentState;const s=t.addEventListener('change',t=>{const o='background'!==l;l=t,'background'===t&&o?n.record('backgrounded'):'active'===t&&n.arm()});return()=>s.remove()};var t=r(d[0]),n=r(d[1]),o=r(d[2]);const l='crash';let s=null;function c(t){if('object'!=typeof t||null===t)return!1;return'function'==typeof Reflect.get(t,'setGlobalHandler')}function u(){const t=Reflect.get(globalThis,'ErrorUtils');return c(t)?t:null}function f(c,u,f=(0,o.getExitMarkerRecorder)()){const b=(0,n.describeThrown)(u);t.log.error(l,`runtime fatal (${c})`,{kind:c,message:b.message,stack:b.stack,version:s?.version??null,bundle:s?.bundle??null}),f.record(c,b),(0,t.flushLogsNow)()}let b=!1},2127,[1131,2128,2129]);
|
|
3587
3587
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"CRASH_STACK_MAX_CHARS",{enumerable:!0,get:function(){return n}}),e.describeThrown=function(t){if(t instanceof Error){const s='string'==typeof t.stack?t.stack:null;return{message:`${t.name}: ${t.message}`,stack:null===s?null:s.slice(0,n)}}try{return{message:String(t),stack:null}}catch{return{message:'unstringifiable thrown value',stack:null}}},e.serializeExitMarker=function(n){try{return JSON.stringify(n)}catch{return JSON.stringify({kind:n.kind,at:n.at})}},e.parseExitMarker=function(n){if(null===n||0===n.length)return null;let s;try{s=JSON.parse(n)}catch{return null}if('object'!=typeof s||null===s||Array.isArray(s))return null;const u=Object.assign({},s),l=u.kind;if(c=l,'running'!==c&&'backgrounded'!==c&&'ota-reload'!==c&&'js-fatal'!==c&&'render-error'!==c)return null;var c;const o=u.at;return{kind:l,at:'number'==typeof o&&Number.isFinite(o)?o:0,message:t(u,'message'),stack:t(u,'stack')}},e.classifyPreviousExit=function(n){return null===n?'first-launch':'running'===n.kind?'vanished':n.kind},e.isCrashExit=function(n){return'js-fatal'===n||'render-error'===n||'vanished'===n};const n=2e3;function t(n,t){const s=n[t];return'string'==typeof s&&s.length>0?s:void 0}},2128,[]);
|
|
3588
3588
|
__d(function(g,r,i,a,m,_e,d){"use strict";Object.defineProperty(_e,'__esModule',{value:!0}),Object.defineProperty(_e,"EXIT_MARKER_STORAGE_KEY",{enumerable:!0,get:function(){return s}}),_e.createExitMarkerPort=o,Object.defineProperty(_e,"ExitMarkerRecorder",{enumerable:!0,get:function(){return u}}),_e.getExitMarkerRecorder=function(){return l??=new u(o()),l};var e,t=r(d[0]),n=(e=t)&&e.__esModule?e:{default:e},c=r(d[1]);const s='camstack.runtime.exit-marker.v1';function o(){return{read:()=>n.default.getItem(s),write:e=>n.default.setItem(s,e)}}class u{constructor(e,t=Date.now){this.port=e,this.now=t}readPrevious=async()=>{try{return(0,c.parseExitMarker)(await this.port.read())}catch{return null}};arm=()=>this.record('running');record=async(e,t)=>{const n={kind:e,at:this.now(),message:t?.message,stack:t?.stack??void 0};try{await this.port.write((0,c.serializeExitMarker)(n))}catch{}}}let l},2129,[783,2128]);
|
|
3589
|
-
__d(function(g,r,i,a,m,_e,d){"use strict";Object.defineProperty(_e,'__esModule',{value:!0}),Object.defineProperty(_e,"WHATS_NEW",{enumerable:!0,get:function(){return e}}),_e.whatsNewHistory=function(t){const n=o(t);return{latest:n,past:e.filter(e=>e!==n)}},_e.whatsNewFor=o,_e.whatsNewLines=function(e,o){const t=o.toLowerCase().startsWith('it')?'it':'en',n=e.notes[t];return n.length>0?n:e.notes.en},_e.shouldShowWhatsNew=function(e,t){return!!t&&(e!==t&&null!==o(t))};const e=[{version:'1.0.507',date:'2026-09-19',notes:{en:['A camera that reports neither a battery nor a link now gets a chart glyph of its own, which opens the same card and its stream numbers. Those cameras had no badge at all, so the card could not be opened on them \u2014 the permanently-powered, wired ones, which are exactly the cameras you are most likely to be investigating.'],it:['Una telecamera che non riporta n\xe9 batteria n\xe9 collegamento adesso ha un\u2019icona a grafico tutta sua, che apre la stessa scheda e i suoi numeri dello stream. Su quelle telecamere non c\u2019era nessuna icona, quindi la scheda non si poteva aprire \u2014 e sono le telecamere fisse alimentate, cio\xe8 proprio quelle su cui \xe8 pi\xf9 probabile che tu stia indagando.']}},{version:'1.0.506',date:'2026-09-19',notes:{en:['The stream numbers moved to where you can reach them. Tap the battery or link glyph on a camera and the card now also carries the stream: the verdict first \u2014 is a frozen picture the network or the decoder? \u2014 then the evidence. Frames decoded and whether they are still advancing, freezes and how long they lasted, key-frame requests, loss, latency and the connection path; and from the hub, which profile you are actually being served, whether that stream is native or transcoded here, which node ingests it, and why the quality ladder last moved. The pill on the picture stays as it is: on a phone the panel behind it could never be opened, because the app owns the touches over the player.'],it:['I numeri dello stream si sono spostati dove puoi raggiungerli. Tocca l\u2019icona della batteria o del collegamento su una telecamera e la scheda adesso porta anche lo stream: prima il verdetto \u2014 un\u2019immagine bloccata \xe8 la rete o il decoder? \u2014 e poi le prove. Fotogrammi decodificati e se stanno ancora avanzando, blocchi e quanto sono durati, richieste di key frame, perdita, latenza e il percorso della connessione; e dall\u2019hub, quale profilo ti sta servendo davvero, se quello stream \xe8 nativo o transcodificato qui, quale nodo lo ingerisce e perch\xe9 la scala di qualit\xe0 si \xe8 mossa l\u2019ultima volta. La pastiglia sull\u2019immagine resta com\u2019\xe8: sul telefono il pannello dietro non si poteva aprire, perch\xe9 i tocchi sopra il player appartengono all\u2019app.']}},{version:'1.0.505',date:'2026-09-19',notes:{en:['The stream stats are a real debug tool now, and they stay out of your way. A small pill above the controls carries the verdict, the resolution, the frame rate and the bitrate; tap it for the full panel. The panel answers the question that mattered and could not be answered before: when a picture freezes, is it the network or the decoder? It shows frames decoded, freezes and their duration, key-frame requests, retransmissions, jitter, loss and the ICE path on the client side \u2014 and, from the hub, which rung you are actually being served, whether that stream is native or transcoded, which node is ingesting it, and why the quality ladder last moved.'],it:['Le statistiche dello stream sono diventate uno strumento di debug vero, e stanno fuori dai piedi. Una pastiglia sopra i controlli porta il verdetto, la risoluzione, i fotogrammi al secondo e il bitrate; toccala per il pannello completo. Il pannello risponde alla domanda che contava e a cui non si poteva rispondere: quando l\u2019immagine si blocca, \xe8 la rete o il decoder? Mostra i fotogrammi decodificati, i blocchi e quanto sono durati, le richieste di key frame, le ritrasmissioni, jitter, perdita e il percorso ICE lato client \u2014 e, dall\u2019hub, quale profilo ti sta servendo davvero, se quello stream \xe8 nativo o transcodificato, quale nodo lo sta ingerendo e perch\xe9 la scala di qualit\xe0 si \xe8 mossa l\u2019ultima volta.']}},{version:'1.0.504',date:'2026-09-17',notes:{en:['The Home button on a PTZ camera now tells you when it cannot do anything. It used to send the camera to whichever preset happened to sit in the first slot \u2014 on these cameras that was \u201cstanza\u201d, \u201cCredenza\u201d and \u201cPreset1\u201d, nobody\u2019s idea of home \u2014 and when that slot was empty it failed in silence. The hub now asks which preset you chose as home, refuses rather than guessing, and the app shows you the refusal instead of swallowing it. Pick one under PTZ settings.'],it:['Il pulsante Home su una telecamera PTZ ora ti dice quando non pu\xf2 fare niente. Prima mandava la telecamera al preset che si trovava nel primo posto \u2014 su queste telecamere erano \u201cstanza\u201d, \u201cCredenza\u201d e \u201cPreset1\u201d, che home non sono \u2014 e quando quel posto era vuoto falliva in silenzio. Adesso l\u2019hub chiede quale preset hai scelto come home, rifiuta invece di indovinare, e l\u2019app ti mostra il rifiuto invece di ingoiarlo. Scegline uno nelle impostazioni PTZ.']}},{version:'1.0.503',date:'2026-09-16',notes:{en:['Pages with camera tiles scroll again on a phone. A tile claimed every touch that landed on it \u2014 and on a phone a tile is most of the screen \u2014 then did nothing with it, because dragging only pans a tile you have already zoomed into. Now the gesture is yours until you zoom in; pinch and double-tap are unchanged.'],it:['Le pagine con i riquadri delle telecamere tornano a scorrere sul telefono. Un riquadro si prendeva ogni tocco che ci finiva sopra \u2014 e sul telefono un riquadro e\u2019 quasi tutto lo schermo \u2014 e poi non ne faceva niente, perche\u2019 trascinare sposta solo un riquadro in cui hai gia\u2019 zoomato. Ora il gesto resta tuo finche\u2019 non zoomi; pinch e doppio tocco invariati.']}},{version:'1.0.502',date:'2026-09-16',notes:{en:['Zones, above the places: a part of the home that holds several rooms \u2014 \u201cZona notte\u201d for the bedrooms. They come first in the filter strip, with their own icon, because it is the coarser question: asking for upstairs should not mean pressing four rooms. Create them on the hub, under Locations.','A camera still belongs to exactly one place, and a place to at most one zone. Nothing about your cameras changed to make this work.','The drawn zones in the rule editor are now called detection zones, which is what they are \u2014 so the word is free for the rooms of your home.'],it:['Le zone, sopra i luoghi: una parte della casa che tiene pi\xf9 stanze \u2014 \u201cZona notte\u201d per le camere da letto. Vengono per prime nella striscia dei filtri, con la loro icona, perch\xe9 sono la domanda pi\xf9 grossa: chiedere il piano di sopra non deve voler dire premere quattro stanze. Si creano sull\u2019hub, sotto Locations.','Una telecamera resta in un solo luogo, e un luogo in al massimo una zona. Non \xe8 cambiato nulla sulle tue telecamere perch\xe9 questo funzionasse.','Le zone disegnate nell\u2019editor delle regole ora si chiamano zone di rilevamento, che \xe8 quello che sono \u2014 cos\xec la parola resta libera per le stanze di casa.']}},{version:'1.0.501',date:'2026-09-16',notes:{en:['Choosing a place that has nothing in it no longer takes the page away. Pressing Favourites with nothing starred replaced the reel, the selector and the cameras with \u201cno cameras configured\u201d \u2014 and took away the control that would have undone it. The reel and the strip stay put; only the list below says it is empty.','The location chips are the size of chips again, and Favourites is in your language.'],it:['Scegliere un luogo vuoto non porta pi\xf9 via la pagina. Premere Preferite senza averne sostituiva reel, selettore e camere con \u201cnessuna camera configurata\u201d \u2014 e toglieva proprio il comando per tornare indietro. Reel e striscia restano al loro posto; \xe8 la lista sotto a dire che \xe8 vuota.','I chip dei luoghi sono tornati alti quanto un chip, e Preferite \xe8 nella tua lingua.']}},{version:'1.0.500',date:'2026-09-16',notes:{en:['The camera list has a location strip, between the reel and the cameras. Favourites first \u2014 with a count, because an empty shortlist is worth knowing before you press into it \u2014 then \u201cAll\u201d, then every place your cameras actually name. Pressing the place you are already in takes you back out, so a room whose cameras are all offline is never a dead end.','A heart on each camera, top left. Favourites live in your profile and travel with it: share the profile and they go too. They are yours alone otherwise.','A place can carry its own icon, chosen in the hub. A room nobody gave one to shows no icon at all rather than a default \u2014 \u201cnobody chose\u201d and \u201cthe pin was chosen\u201d are different things.'],it:['La lista camere ha una striscia dei luoghi, fra il reel e le camere. Prima le Preferite \u2014 col conteggio, perch\xe9 una lista corta vuota \xe8 meglio saperlo prima di entrarci \u2014 poi \u201cTutte\u201d, poi ogni luogo che le tue camere hanno davvero. Premere il luogo in cui sei gi\xe0 ti riporta indietro, cos\xec una stanza con tutte le camere offline non \xe8 mai un vicolo cieco.','Un cuore su ogni camera, in alto a sinistra. Le preferite stanno nel tuo profilo e viaggiano con lui: condividi il profilo e vanno con quello. Per il resto sono solo tue.','Un luogo pu\xf2 avere la sua icona, scelta sull\u2019hub. Una stanza a cui nessuno l\u2019ha data non disegna nessuna icona invece di una di default \u2014 \u201cnessuno ha scelto\u201d e \u201cha scelto il pin\u201d sono due cose diverse.']}},{version:'1.0.499',date:'2026-09-15',notes:{en:['The debug reasons are the ones you actually use. Nine of them, in your order \u2014 the old list had been inferred from a reading of eleven real notes; this one was dictated by the person who reviews with it. \u201cNo crop\u201d is gone: a crop that is WRONG and a crop that is ABSENT are two different findings, and one checkbox was blurring them.','A track\u2019s media strip can now show \u201cGate crop\u201d \u2014 the pixels the confirmation gate judged, kept when it refused to confirm a birth. It exists to be argued with: it is the only thing that can say whether the detector was right to drop a sighting.'],it:['Le reason di debug sono quelle che usi davvero. Nove, nel tuo ordine \u2014 la lista precedente era stata dedotta da una lettura di undici note reali; questa l\u2019ha dettata chi ci rivede. \xc8 sparito \u201cnessun ritaglio\u201d: un crop SBAGLIATO e un crop ASSENTE sono due reperti diversi, e una casella sola li confondeva.','La striscia media di una traccia pu\xf2 ora mostrare \u201cGate crop\u201d \u2014 i pixel su cui il confirmation gate ha deciso, tenuti quando ha rifiutato di confermare una nascita. Serve per poterlo contestare: \xe8 l\u2019unica cosa che dice se il detector avesse ragione a scartare un avvistamento.']}},{version:'1.0.498',date:'2026-09-15',notes:{en:['The \u201c?\u201d on an events card really does open the assignment now. It was made a button last time and still could not be tapped: it sits in the caption row, which is deliberately transparent to touches so the labels never swallow the card\u2019s own open \u2014 and the button inherited that.','Audio on open is no longer one answer for every camera. Alongside \u201calways on\u201d and \u201calways off\u201d there is now \u201cas you left it\u201d, which is the new default: each camera opens the way you last left it, and a camera you have never chosen on opens silent.'],it:['Il \u201c?\u201d su una card degli eventi ora apre davvero l\u2019assegnazione. L\u2019ultima volta era diventato un pulsante e restava comunque intoccabile: sta nella riga delle etichette, che \xe8 trasparente ai tocchi apposta perch\xe9 le etichette non si mangino l\u2019apertura della card \u2014 e il pulsante ereditava quella trasparenza.','L\u2019audio all\u2019apertura non \xe8 pi\xf9 una risposta sola per tutte le camere. Accanto a \u201csempre acceso\u201d e \u201csempre spento\u201d c\u2019\xe8 ora \u201ccome l\u2019hai lasciato\u201d, che \xe8 il nuovo default: ogni camera si apre com\u2019era l\u2019ultima volta, e una camera su cui non hai mai scelto si apre muta.']}},{version:'1.0.497',date:'2026-09-14',notes:{en:['You can add a linked device from the camera\u2019s own panel, not only from the cameras list. The panel showed you what was linked and gave you nowhere to add one, so the answer was to leave the camera you were looking at.','The keyboard no longer covers the device picker while you search it. And tapping outside now closes the keyboard first, so a search you were half way through is not thrown away with it.'],it:['Puoi aggiungere un dispositivo collegato dal pannello della camera stessa, non solo dalla lista camere. Il pannello ti mostrava cosa era collegato e non ti dava dove aggiungerne uno, quindi la risposta era uscire dalla camera che stavi guardando.','La tastiera non copre pi\xf9 il selettore dei dispositivi mentre lo cerchi. E il tocco fuori ora chiude prima la tastiera, cos\xec una ricerca lasciata a met\xe0 non se ne va con lei.']}},{version:'1.0.496',date:'2026-09-14',notes:{en:['The \u201c?\u201d on an events card now opens the assignment. It was a label that said a face was waiting for a name and did nothing when you tapped it \u2014 so you opened the card and looked for the assignment again, answering a question you had already asked.','A group now shows its PATH: what each of its subjects did, drawn on the picture they were in together, one colour each. Every member already had its own crop in the group; what was missing was where they went.'],it:['Il \u201c?\u201d su una card degli eventi ora apre l\u2019assegnazione. Era un\u2019etichetta che diceva che un volto aspettava un nome e non faceva niente al tocco \u2014 cos\xec aprivi la card e ricercavi l\u2019assegnazione, rispondendo a una domanda che avevi gi\xe0 fatto.','Un gruppo ora mostra il suo PERCORSO: cosa ha fatto ognuno dei suoi soggetti, disegnato sull\u2019immagine in cui erano insieme, un colore per ciascuno. Ogni membro aveva gi\xe0 il suo ritaglio nel gruppo; mancava dove sono andati.']}},{version:'1.0.495',date:'2026-09-13',notes:{en:['Groups with no camera filter now list every camera. Leaving the camera chip untouched means "all of them" here, and it meant "none of them" to the hub \u2014 so the gallery came back empty on a system full of groups.'],it:['I gruppi senza filtro camera ora elencano tutte le telecamere. Non toccare il chip delle camere qui significa \u201ctutte\u201d, e per l\u2019hub significava \u201cnessuna\u201d \u2014 cos\xec la galleria tornava vuota su un sistema pieno di gruppi.']}},{version:'1.0.494',date:'2026-09-13',notes:{en:['Administrators can link devices to a camera from the phone \u2014 a doorbell, a sensor, a light \u2014 in the same list the pencil arranges. The picker suggests the devices in that camera\u2019s own room first, and nothing is linked until you pick it.'],it:['Gli amministratori possono collegare device a una telecamera dal telefono \u2014 un campanello, un sensore, una luce \u2014 nella stessa lista che la matita riordina. Il selettore suggerisce per primi i device della stanza di quella telecamera, e niente viene collegato finch\xe9 non lo scegli tu.']}},{version:'1.0.493',date:'2026-09-13',notes:{en:['You can arrange the camera list by hand. A small pencil in the corner turns the list into edit mode, you drag the rows, and a tick saves. Nothing is draggable until you ask \u2014 no more reordering a camera by accident \u2014 and cancelling puts back exactly the order you started with, not the last one saved.','The arrangement is yours and stays on this device. A camera added on the hub appears at the end rather than somewhere unpredictable, and an order can move a camera but can never hide one.'],it:['Puoi sistemare la lista delle telecamere a mano. Una piccola matita nell\u2019angolo mette la lista in modifica, trascini le righe, e la spunta salva. Niente \xe8 trascinabile finch\xe9 non lo chiedi \u2014 niente pi\xf9 riordini per sbaglio \u2014 e annullare rimette esattamente l\u2019ordine da cui eri partito, non l\u2019ultimo salvato.','La disposizione \xe8 tua e resta su questo dispositivo. Una telecamera aggiunta sull\u2019hub compare in fondo invece che in un punto imprevedibile, e un ordine pu\xf2 spostare una telecamera ma non pu\xf2 mai nasconderla.']}},{version:'1.0.492',date:'2026-09-13',notes:{en:['Three pages can now list GROUPS instead of subjects: the camera timeline, the reel on the cameras page, and the Events gallery. A family walking in together is one entry with several pictures, not four cards. Each page has its OWN switch and each one starts on subjects \u2014 nothing changes until you ask it to, and you can always switch back from the page itself.','A group card shows what the group was made of \u2014 two people and a dog \u2014 and a Live chip while the session is still running. Opening it lists the members, each one linking to its own track.','The reel draws groups as their own strip, with several images per entry and no clustering: two sessions seconds apart are two things that happened, and the old grouping used to swallow one of them.','Filtering understands groups. Picking Dog now finds the arrivals that HAD a dog with them, including the group of four people \u2014 the filter asks about the members, and it runs on the hub rather than on your phone.'],it:['Tre pagine possono ora elencare i GRUPPI invece dei soggetti: la timeline della telecamera, il reel nella pagina telecamere e la galleria Eventi. Una famiglia che entra insieme \xe8 una voce sola con pi\xf9 immagini, non quattro schede. Ogni pagina ha il SUO interruttore e parte dai soggetti \u2014 non cambia nulla finch\xe9 non lo chiedi tu, e si torna indietro dalla pagina stessa.','La scheda di un gruppo dice di cosa era fatto \u2014 due persone e un cane \u2014 e porta la pastiglia Live finch\xe9 la sessione \xe8 in corso. Aprendola trovi i membri, ognuno con il link alla sua traccia.','Nel reel i gruppi hanno una striscia propria, con pi\xf9 immagini per voce e senza raggruppamento: due sessioni a pochi secondi di distanza sono due cose successe, e il vecchio accorpamento se ne mangiava una.','Il filtro capisce i gruppi. Scegliere Cane ora trova gli arrivi che AVEVANO un cane con loro, compreso il gruppo di quattro persone \u2014 il filtro chiede dei membri, e gira sull\u2019hub invece che sul telefono.']}},{version:'1.0.491',date:'2026-09-13',notes:{en:['The movable window now carries the stream\u2019s own controls: audio, talk-back, picture-in-picture, and a button that opens that camera full-screen. They are the same controls as the single-camera screen \u2014 the same code, so they cannot drift apart.','The resize corner wore the FULLSCREEN icon, so the grip was signing the wrong action. It now looks like every other control in the app.','The heatmap in that window only ever drew recordings. Motion and audio were never missing from the hub \u2014 the window was handing the bar an empty list. Both lanes are there now. Detections are deliberately still absent: loading them costs a few hundred kilobytes, which a floating panel over a live stream should not spend.','Exports and the hub\u2019s own files are ONE section, now called Media. An export finally has a detail view and plays in the app instead of only downloading, and the filter is the one from Events \u2014 a chip per facet that says what it is narrowing, instead of a pill that only counted.','You can delete what the hub produced. Until now a timelapse could only be waited out. A video takes its preview still with it, so one card frees both files.','The timeline can show GROUPS instead of subjects: a family arriving together is one card, not three. Off by default \u2014 turn it on in the timeline filters or in Settings. A session still in progress is listed with a Live chip rather than hidden.'],it:['La finestra mobile ora porta i comandi dello stream: audio, microfono, picture-in-picture e un pulsante che apre quella telecamera a schermo intero. Sono gli STESSI comandi della schermata singola \u2014 lo stesso codice, quindi non possono divergere.','L\u2019angolo di ridimensionamento portava l\u2019icona dello SCHERMO INTERO: la presa firmava l\u2019azione sbagliata. Ora ha l\u2019aspetto di ogni altro comando dell\u2019app.','La heatmap in quella finestra disegnava solo le registrazioni. Movimento e audio non sono mai mancati dall\u2019hub \u2014 era la finestra a passare alla barra una lista vuota. Ora ci sono entrambi. Le rilevazioni restano fuori di proposito: caricarle costa qualche centinaio di kilobyte, che un pannello sopra uno stream dal vivo non deve spendere.','Gli export e i file prodotti dall\u2019hub sono UNA sezione sola, che ora si chiama Media. Un export ha finalmente una scheda e si riproduce dentro l\u2019app invece di poter solo essere scaricato, e il filtro \xe8 quello di Eventi \u2014 una pastiglia per faceta che dice cosa sta restringendo, invece di una che contava e basta.','Puoi cancellare quello che ha prodotto l\u2019hub. Fino a ora un timelapse si poteva solo aspettare. Un video porta via anche la sua anteprima, quindi una card libera due file.','La timeline pu\xf2 mostrare i GRUPPI invece dei soggetti: una famiglia che arriva insieme \xe8 una card, non tre. Spento di default \u2014 si accende dai filtri della timeline o dalle Impostazioni. Una sessione ancora in corso viene elencata con la pastiglia Live, non nascosta.']}},{version:'1.0.490',date:'2026-09-13',notes:{en:['The movable window resizes properly now. The handle always worked \u2014 the sizes behind it did not: all three snaps came out the same box on a phone, so dragging changed nothing. The grip is finger-sized and no longer shares its corner with the playback controls.','The playback bar inside that window fits the width it is given. It was drawing a full-width bar into a small window with nothing to wrap into, which is why LIVE broke onto two lines and buttons landed on top of each other.','Event thumbnails stop failing to warm. The list was pre-fetching them with the wrong kind of id \u2014 an event\u2019s, where a track\u2019s was needed \u2014 so every pre-fetch missed and the picture had to be fetched again when the card appeared.','Picture-in-picture on app close is gone. It was granted by the system and lost 176 ms later, every time: Apple only starts picture-in-picture in response to something you do, and an app closing is not that. The button on the player still works and survives closing the app.'],it:['La finestra mobile ora si ridimensiona davvero. La maniglia ha sempre funzionato \u2014 erano le misure dietro a non funzionare: su telefono tutte e tre le taglie davano la stessa identica finestra, quindi trascinare non cambiava nulla. L\u2019angolo di presa \xe8 dimensionato per un dito e non se lo contende pi\xf9 con i comandi di riproduzione.','La barra di riproduzione dentro quella finestra si adatta alla larghezza che ha. Prima disegnava una barra intera dentro una finestra piccola senza spazio in cui andare a capo: per questo LIVE finiva su due righe e i pulsanti si sovrapponevano.','Le miniature degli eventi smettono di fallire il precaricamento. La lista le chiedeva con il tipo di id sbagliato \u2014 quello dell\u2019evento invece che quello della traccia \u2014 quindi ogni precaricamento mancava e l\u2019immagine andava richiesta da capo quando la card compariva.','Il picture-in-picture alla chiusura dell\u2019app non c\u2019\xe8 pi\xf9. Il sistema lo concedeva e lo perdeva 176 ms dopo, ogni volta: Apple avvia il picture-in-picture solo in risposta a qualcosa che fai tu, e chiudere l\u2019app non lo \xe8. Il pulsante sul player continua a funzionare e sopravvive alla chiusura.']}},{version:'1.0.489',date:'2026-09-13',notes:{en:['Review: deleting a sample from a person now actually deletes it. The request was never leaving the app \u2014 it was looked up in a way that can never find it, so nothing happened and nothing said so.','Review: you can delete parked faces you do not want to keep, and create a new person without leaving the page. Picking a person is a searchable list instead of a row of chips that grew with your gallery.','Review: the similar-groups button kept going quiet after the first pass. It was comparing faces over a wide window and then only showing groups that fell inside a much narrower one, so the matches sitting just outside vanished. One window now \u2014 and the button no longer claims a number.','The movable player lost its padlock: it came along with the shared playback bar and did nothing there but swallow your taps.','Opening a camera full-screen now closes the movable window if it was showing that same camera, instead of leaving two pictures of it.'],it:['Review: cancellare un campione da una persona ora lo cancella davvero. La richiesta non usciva nemmeno dall\u2019app \u2014 veniva cercata in un modo che non pu\xf2 trovarla, quindi non succedeva nulla e nulla lo diceva.','Review: puoi cancellare le facce parcheggiate che non vuoi tenere, e creare una nuova persona senza uscire dalla pagina. Scegliere una persona ora \xe8 una lista con ricerca invece di una fila di pastiglie che cresceva con la tua galleria.','Review: il pulsante dei gruppi simili ammutoliva dopo il primo giro. Confrontava le facce su una finestra ampia e poi mostrava solo i gruppi che cadevano dentro una molto pi\xf9 stretta, quindi le somiglianze appena fuori sparivano. Ora la finestra \xe8 una sola \u2014 e il pulsante non promette pi\xf9 un numero.','Il player mobile ha perso il lucchetto: arrivava insieme alla barra di riproduzione condivisa e l\xec non faceva altro che ingoiare i tuoi tocchi.','Aprire una telecamera a schermo intero ora chiude la finestra mobile se mostrava quella stessa telecamera, invece di lasciarne due immagini.']}},{version:'1.0.488',date:'2026-09-13',notes:{en:['The movable player works on the phone now, not only on tablets and wide windows. A button on each camera card summons it without leaving the list, and its title is the CAMERA\u2019s name \u2014 it used to say "Playback", which cannot tell two open windows apart.','The downward swipe on a camera changed hands: one finger goes back, two fingers hand the camera to the movable player and go back. Picture-in-picture is no longer a gesture at all \u2014 it now happens by itself when you close the app on a single camera, because that is the moment your hands are busy pressing Home. There is a switch for it under Stream.','Audio is on when you open a camera. It used to open muted until you found the button.','Settings were reorganised: General (theme, language, press feedback) sits right under Server, the event-vibration switches are gone, and on a tablet or a desktop window the sections lay out in two or three columns instead of one long scroll.'],it:['Il player mobile ora funziona anche sul telefono, non solo su tablet e finestre larghe. Un pulsante su ogni scheda telecamera lo apre senza uscire dalla lista, e il titolo \xe8 il nome della TELECAMERA \u2014 prima diceva "Riproduzione", che non distingue due finestre aperte.','Lo scorrimento verso il basso su una telecamera cambia mano: un dito torna indietro, due dita passano la telecamera al player mobile e tornano indietro. Il picture-in-picture non \xe8 pi\xf9 un gesto \u2014 ora parte da solo quando chiudi l\u2019app su una singola telecamera, perch\xe9 quello \xe8 il momento in cui le mani sono occupate a premere Home. C\u2019\xe8 un interruttore sotto Streaming.','L\u2019audio \xe8 attivo quando apri una telecamera. Prima si apriva muta finch\xe9 non trovavi il pulsante.','Impostazioni riorganizzate: Generale (tema, lingua, vibrazione alla pressione) sta subito sotto Server, gli interruttori di vibrazione sugli eventi sono spariti, e su tablet o finestra desktop le sezioni si dispongono su due o tre colonne invece di una lista lunga.']}},{version:'1.0.487',date:'2026-09-13',notes:{en:['Thumbnails and track media are back. A media file used to be addressed by a composite key that embedded a foreign id, and once every event table got its own numbering those keys started naming the wrong row \u2014 a night shot could answer for a different camera. The hub now addresses a media file by its own id, and asks for "the best picture of this track" as its own question. The app had been left on the old address, so every thumbnail it asked for came back missing: the track detail opened empty and the timeline drew nothing.','Playback got a player you can move. Open a recording from anywhere and it keeps playing in a window you can drag and resize, and it survives you navigating elsewhere in the app.','The camera reel lights up when something happens \u2014 motion and audio, on by default, with a settings panel to choose what counts. Tapping a camera in the reel now swaps it in place instead of reloading the page, and if you are in playback the new camera opens at the same instant you were watching, not at its own live edge.'],it:['Le miniature e i media delle tracce sono tornati. Un file media veniva indirizzato con una chiave composta che conteneva un id altrui, e da quando ogni tabella di eventi ha una sua numerazione quelle chiavi hanno cominciato a nominare la riga sbagliata \u2014 uno scatto notturno poteva rispondere per un\u2019altra telecamera. L\u2019hub ora indirizza un media con il suo id, e chiede \u201cla foto migliore di questa traccia\u201d come domanda a s\xe9. L\u2019app era rimasta all\u2019indirizzo vecchio, quindi ogni miniatura che chiedeva tornava mancante: il dettaglio della traccia si apriva vuoto e la timeline non disegnava nulla.','La riproduzione ha un player che puoi spostare. Apri una registrazione da qualsiasi punto e continua in una finestra che puoi trascinare e ridimensionare, e resta l\xec anche se navighi altrove nell\u2019app.','Il carosello delle telecamere si illumina quando succede qualcosa \u2014 movimento e audio, attivi di default, con un pannello per scegliere cosa conta. Toccare una telecamera nel carosello ora la scambia sul posto invece di ricaricare la pagina, e se sei in riproduzione la nuova telecamera si apre allo stesso istante che stavi guardando, non al suo live.']}},{version:'1.0.486',date:'2026-09-11',notes:{en:['The camera timeline now opens on the last hour instead of the last three. Three hours was the density the timeline had always drawn, not a decision about what you want to see when you open a camera \u2014 it put whatever just happened in a third of the screen and made the rest yesterday\u2019s scrolling.','Event cards now sit ON the track they describe. The timeline runs newest at the top, so a track ends above and begins below \u2014 but the card was anchored by its top edge to the track\u2019s beginning, which hung it under the event, over the minutes before anything happened. Now the card\u2019s bottom edge is where the track starts, so the card covers the subject\u2019s own passage and reading upward follows it.'],it:['La timeline della telecamera si apre sull\u2019ultima ora invece che sulle ultime tre. Tre ore erano la densit\xe0 che la timeline aveva sempre disegnato, non una scelta su cosa serve vedere aprendo una telecamera: mettevano quello appena successo in un terzo di schermo e rendevano il resto lo scroll di ieri.','Le card degli eventi ora stanno SOPRA la traccia che descrivono. La timeline ha il pi\xf9 recente in alto, quindi una traccia finisce sopra e comincia sotto \u2014 ma la card era ancorata col bordo superiore all\u2019inizio della traccia, il che la appendeva sotto l\u2019evento, sui minuti in cui non era ancora successo nulla. Ora il bordo inferiore della card \xe8 dove la traccia comincia, cos\xec la card copre il passaggio del soggetto e leggere verso l\u2019alto lo segue.']}},{version:'1.0.485',date:'2026-09-11',notes:{en:['The app now hangs up when you leave it, and calls back when you return. In the background the phone freezes the app and stops reading, but the connection stayed open \u2014 so the hub kept piling up messages for a listener that was asleep. One evening of that was 88 MB held on the hub for a phone nobody was holding. The app now closes the connection as it leaves and opens a new one as it comes back.','Coming back is a normal thing, not a fault: no error, no "offline", nothing emptied. You see a brief "connecting" and the screen you left, and the app re-asks the hub for everything that can have changed while it was away \u2014 cameras, batteries, switches, who is in frame \u2014 so what you are looking at a second later is current rather than remembered.'],it:['L\u2019app ora chiude la linea quando la lasci, e richiama quando torni. In background il telefono congela l\u2019app e smette di leggere, ma la connessione restava aperta \u2014 cos\xec l\u2019hub continuava ad accumulare messaggi per un ascoltatore che dormiva. Una sera cos\xec erano 88 MB tenuti sull\u2019hub per un telefono che nessuno aveva in mano. Ora l\u2019app chiude la connessione mentre esce e ne apre una nuova quando rientra.','Il rientro \xe8 una cosa normale, non un guasto: nessun errore, nessun \u201coffline\u201d, niente che si svuota. Vedi un breve \u201cconnessione\u201d e la schermata che avevi lasciato, e l\u2019app richiede all\u2019hub tutto quello che pu\xf2 essere cambiato mentre era via \u2014 telecamere, batterie, interruttori, chi \xe8 inquadrato \u2014 cos\xec quello che guardi un secondo dopo \xe8 attuale e non ricordato.']}},{version:'1.0.484',date:'2026-09-11',notes:{en:['Pinch-to-zoom, the pan while zoomed and the PTZ joystick work again. The crash guard added in 1.0.479 wrapped every gesture handler, and the wrapped handlers were no longer compiled for the UI thread \u2014 so each gesture was caught and dropped on every frame instead of running. Nothing was lost on the hub: every dropped gesture was logged, which is how this was found.','The camera timeline filter now lists every detection class that actually appears in the loaded window, even when the hub does not advertise it for that camera. A class you could see on the timeline but not tick in the filter was the hub describing the camera from a momentary status; the viewer no longer hides what it is showing.'],it:['Il pinch-to-zoom, lo spostamento da zoomato e il joystick PTZ funzionano di nuovo. La protezione anti-crash aggiunta nella 1.0.479 avvolgeva ogni gestore dei gesti, e i gestori avvolti non venivano pi\xf9 compilati per il thread UI \u2014 quindi ogni gesto veniva intercettato e scartato a ogni frame invece di eseguire. Sull\u2019hub non \xe8 andato perso nulla: ogni gesto scartato \xe8 stato registrato, ed \xe8 cos\xec che \xe8 stato trovato.','Il filtro della timeline della telecamera ora elenca ogni classe di rilevamento che compare davvero nella finestra caricata, anche quando l\u2019hub non la dichiara per quella telecamera. Una classe che vedevi sulla timeline ma non potevi spuntare nel filtro era l\u2019hub che descriveva la telecamera da uno stato momentaneo; il viewer non nasconde pi\xf9 ci\xf2 che sta mostrando.']}},{version:'1.0.483',date:'2026-09-10',notes:{en:['On a tablet, turning from portrait to landscape puts the timeline back beside the picture. The app was reading its window size from a notification that sometimes arrived seconds late, or not at all, so it kept laying out for portrait inside a landscape screen until you killed it. It now reads the size of the view you are actually looking at.','The camera reel under the player refreshes in turns instead of all at once. Every card used to ask the hub for a new frame in the same second, every fifteen seconds \u2014 thirty captures in a burst, and the slow cameras never made it in time. Now a quarter of the reel takes its turn on each poll, so each card refreshes about every twenty seconds and the hub is never asked for thirty frames at once.'],it:['Su tablet, ruotando da verticale a orizzontale la timeline torna accanto all\u2019immagine. L\u2019app leggeva la dimensione della finestra da una notifica che a volte arrivava con secondi di ritardo, o mai, e continuava a impaginare in verticale dentro uno schermo orizzontale finch\xe9 non la chiudevi. Ora legge la dimensione della vista che stai davvero guardando.','Il nastro delle telecamere sotto il player si aggiorna a turni invece che tutto insieme. Ogni scheda chiedeva all\u2019hub un frame nuovo nello stesso secondo, ogni quindici secondi \u2014 trenta catture in raffica, e le telecamere lente non facevano mai in tempo. Ora a ogni giro tocca a un quarto del nastro, cos\xec ogni scheda si aggiorna circa ogni venti secondi e all\u2019hub non vengono mai chiesti trenta frame in una volta.']}},{version:'1.0.482',date:'2026-09-10',notes:{en:['When assigning a face fails, it now says why. The failure was caught and thrown away in eight different places \u2014 you saw "could not assign a face" and there was nothing, anywhere, to explain it. The reason is now recorded and reaches the hub, including the case where the server answers but assigns nothing.','The app also stopped narrating itself. Four routine messages \u2014 one per camera tile, several times each \u2014 were more than half of everything it sent to the hub. They are still there in debug mode; what stays are the lines that report something going wrong.'],it:['Quando assegnare una faccia fallisce, ora dice perch\xe9. L\u2019errore veniva catturato e buttato via in otto punti diversi \u2014 tu vedevi \u201cimpossibile assegnare una faccia\u201d e non c\u2019era nulla, da nessuna parte, che lo spiegasse. Ora il motivo viene registrato e arriva all\u2019hub, compreso il caso in cui il server risponde ma non assegna niente.','L\u2019app ha anche smesso di raccontarsi. Quattro messaggi di routine \u2014 uno per riquadro di telecamera, pi\xf9 volte ciascuno \u2014 erano pi\xf9 della met\xe0 di tutto ci\xf2 che spediva all\u2019hub. Restano in modalit\xe0 debug; quel che resta sempre sono le righe che segnalano qualcosa che non va.']}},{version:'1.0.481',date:'2026-09-10',notes:{en:['Assigning faces no longer freezes the page. "Apply suggestions" writes one group per person, and each group used to wait for the whole gallery to be re-read before the next one started \u2014 six people meant dozens of round trips before you got the screen back. The gallery is now re-read once, when the last group is written. Assigning one face at a time waits only for the card you are looking at.','Scrubbing the timeline had a pulse every 80 ms \u2014 twelve a second, which is a buzz and not detents. It is now paced to feel like clicks, and dragging is lighter for it.'],it:['Assegnare le facce non blocca pi\xf9 la pagina. "Applica suggerimenti" scrive un gruppo per persona, e ogni gruppo aspettava che l\u2019intera galleria fosse riletta prima che partisse il successivo \u2014 sei persone significavano decine di andate e ritorni prima di riavere lo schermo. Ora la galleria si rilegge una volta sola, quando l\u2019ultimo gruppo \xe8 scritto. Assegnando una faccia per volta si aspetta soltanto la scheda che stai guardando.','Lo scrub della timeline aveva una vibrazione ogni 80 ms \u2014 dodici al secondo, che \xe8 un ronzio e non degli scatti. Ora \xe8 cadenzata per sembrare clic, e trascinare \xe8 pi\xf9 leggero.']}},{version:'1.0.480',date:'2026-09-10',notes:{en:['The timeline\u2019s audio bar shows the LEVEL now. It was showing how MANY audio events fell in each slot, painted on the same six-rung meter the live view uses for decibels \u2014 so fifty short clicks in a quiet hour lit every rung, whatever their volume. The hub now works out the average loudness of each slot and the bar draws that: a busy quiet hour reads quiet, one door slam reads loud. A slot with no audio at all draws nothing, because \u201cnothing was heard\u201d and \u201cnothing was measured\u201d are not the same thing.','A gesture that fails no longer takes the app down with it. The joystick and the pinch-zoom ran code that, if it threw, closed the app outright \u2014 three crash reports came from exactly that. Now the gesture is simply dropped and the reason is sent back, so the next one can be fixed instead of guessed at.'],it:['La barra audio della timeline mostra finalmente il LIVELLO. Prima mostrava QUANTI eventi audio cadevano in ogni fascia, disegnati sullo stesso misuratore a sei tacche che la vista live usa per i decibel \u2014 cos\xec cinquanta clic brevi in un\u2019ora tranquilla accendevano tutte le tacche, qualunque fosse il volume. Ora l\u2019hub calcola la rumorosit\xe0 media di ogni fascia e la barra disegna quella: un\u2019ora tranquilla ma affollata resta bassa, una porta sbattuta si vede. Una fascia senza audio non disegna nulla, perch\xe9 \u201cnon si \xe8 sentito niente\u201d e \u201cnessuno ha misurato\u201d non sono la stessa cosa.','Un gesto che va in errore non porta pi\xf9 gi\xf9 l\u2019app. Il joystick e lo zoom a pinch eseguivano codice che, se falliva, chiudeva l\u2019app di netto \u2014 tre segnalazioni di crash venivano esattamente da l\xec. Ora il gesto viene semplicemente ignorato e il motivo viene rimandato indietro, cos\xec il prossimo si corregge invece di indovinarlo.']}},{version:'1.0.479',date:'2026-09-09',notes:{en:['Pinch-zoom, second attempt. Yesterday\u2019s fix stopped the box resizing under your fingers, and that turned out to be the wrong half: with the panel set to grow, the picture kept zooming and sliding for a third of a second AFTER you let go \u2014 worst at full zoom, where all of the growth was still pending. The panel now grows under your fingers again, but the player\u2019s own frame never moves: the growth is folded into the zoom itself. Turn on debug mode and a pinch now writes one trace line you can send back.','The app also says far less to the hub: two diagnostics were 72% of everything it shipped \u2014 one of them logged every camera tile twice more just for sitting still while its snapshot aged.'],it:['Zoom a pinch, secondo tentativo. La correzione di ieri ha tolto il riquadro che si ridimensionava sotto le dita, e si \xe8 rivelata la met\xe0 sbagliata: col pannello impostato per crescere, l\u2019immagine continuava a zoomare e scivolare per un terzo di secondo DOPO che avevi lasciato \u2014 peggio al massimo, dove restava pendente tutta la crescita. Ora il pannello cresce di nuovo sotto le dita, ma il frame del player non si muove mai: la crescita \xe8 piegata dentro lo zoom stesso. Con la modalit\xe0 debug accesa, una pinch scrive una riga di traccia da rimandare indietro.','L\u2019app dice anche molto meno all\u2019hub: due diagnostiche facevano il 72% di tutto ci\xf2 che spediva \u2014 una di queste rilogga ogni tessera due volte solo per essere rimasta ferma mentre lo snapshot invecchiava.']}},{version:'1.0.478',date:'2026-09-09',notes:{en:['Pinch-zoom on the live view is smooth again. The picture box no longer resizes under your fingers frame by frame \u2014 it settles once, after you let go \u2014 the pan no longer springs back at the end of a gesture, and the double tap now runs on the UI thread instead of queueing behind the screen. The gesture feels slightly different on purpose: the panel grows after the pinch, not during it.'],it:['Lo zoom a pinch sulla vista live \xe8 di nuovo fluido. Il riquadro dell\u2019immagine non si ridimensiona pi\xf9 sotto le dita frame per frame \u2014 si assesta una volta sola, dopo che hai lasciato \u2014 la panoramica non torna pi\xf9 indietro a fine gesto, e il doppio tap gira sul thread della UI invece di accodarsi dietro allo schermo. Il gesto si sente un po\u2019 diverso di proposito: il pannello cresce dopo la pinch, non durante.']}},{version:'1.0.477',date:'2026-09-08',notes:{en:['The debug note\u2019s preset reasons now come from the notes actually written, not from guesswork: \u201ctrack started late\u201d leads, the thumbnail entry is reworded as \u201ca better frame existed (face/plate)\u201d \u2014 which is what gets typed by hand every time \u2014 and three reasons that were being typed out are now checkboxes: last frame before the first, two subjects in one track, and a two-wheeler whose rider is outside the keyframe.'],it:['Le ragioni preset della nota di debug ora vengono dalle note davvero scritte, non da supposizioni: \u201ctraccia partita in ritardo\u201d \xe8 la prima, la voce sulla miniatura diventa \u201cc\u2019era un frame migliore (volto/targa)\u201d \u2014 che \xe8 quello che viene digitato ogni volta \u2014 e tre ragioni che venivano scritte a mano sono ora caselle: ultimo frame prima del primo, due soggetti nella stessa traccia, e il conducente di un due ruote fuori dal keyframe.']}},{version:'1.0.476',date:'2026-09-08',notes:{en:['Closing the keyboard in the note dialog is the keyboard\u2019s own button now: on iOS a Done bar sits docked to it, drawn by the system above the keys, instead of a button crowding the card.'],it:['Chiudere la tastiera nel dialogo della nota ora \xe8 un pulsante della tastiera stessa: su iOS una barra Fatto le sta agganciata, disegnata dal sistema sopra i tasti, invece di un pulsante che toglie spazio alla scheda.']}},{version:'1.0.475',date:'2026-09-08',notes:{en:['The note dialog was a trap with the keyboard up: its buttons sat behind it, a multiline field has no return key, and tapping outside threw the note away. The card now lifts above the keyboard, a tap outside closes the keyboard first, and there is a Close keyboard button while it is open.'],it:['Il dialogo della nota era una trappola con la tastiera aperta: i pulsanti restavano dietro, un campo multiriga non ha tasto invio, e toccare fuori buttava via la nota. Ora la scheda si solleva sopra la tastiera, un tocco fuori chiude prima la tastiera, e c\u2019\xe8 un pulsante Chiudi tastiera finch\xe9 \xe8 aperta.']}},{version:'1.0.474',date:'2026-09-08',notes:{en:['On a Mac the player still opened the embed page in a browser: the WebView declines that load without reporting an error, so the previous fallback had nothing to react to. The player now watches for silence \u2014 if the bundled page has not spoken within six seconds, it loads the same page from the hub.'],it:['Su Mac il player apriva ancora la pagina dell\u2019embed nel browser: la WebView rifiuta quel caricamento senza segnalare alcun errore, quindi il fallback precedente non aveva nulla a cui reagire. Ora il player sorveglia il silenzio \u2014 se la pagina inclusa non ha parlato entro sei secondi, carica la stessa pagina dall\u2019hub.']}},{version:'1.0.473',date:'2026-09-08',notes:{en:['A sample whose picture is gone now says so, instead of drawing an empty square. Most of the gallery is in that state today \u2014 the crops were lost before the panel existed \u2014 and the scores beside them are unaffected: they come from the stored vector, which is intact.'],it:['Un campione la cui immagine non c\u2019\xe8 pi\xf9 ora lo dice, invece di disegnare un quadrato vuoto. Oggi gran parte della galleria \xe8 in quello stato \u2014 i ritagli erano gi\xe0 andati persi prima che il pannello esistesse \u2014 e i punteggi accanto non ne risentono: vengono dal vettore memorizzato, che \xe8 intatto.']}},{version:'1.0.472',date:'2026-09-08',notes:{en:['Library \u2192 Review can re-analyse one person\u2019s enrolled samples. Worst first, each with its crop and the reason \u2014 \u201clooks like Matthias (61%) more than like this person (12%)\u201d \u2014 and a sample is flagged only when it could actually be auto-assigned to the other person. Remove is one tap, and nothing is removed for you.'],it:['Libreria \u2192 Revisione pu\xf2 rianalizzare i campioni di una persona. Peggiori in cima, ognuno col suo ritaglio e il motivo \u2014 \u201csomiglia a Matthias (61%) pi\xf9 che a questa persona (12%)\u201d \u2014 e un campione \xe8 segnalato solo se potrebbe davvero essere auto-assegnato all\u2019altra persona. Rimuovere \xe8 un tocco, e nessuno rimuove niente al posto tuo.']}},{version:'1.0.471',date:'2026-09-08',notes:{en:['Opening the Cameras page now refreshes every camera\u2019s thumbnail, two at a time, once \u2014 so the tiles below the fold are minutes old instead of hours. It stops when it has been round the list.','What\u2019s new is a panel now, not a one-line dialog: the build that just arrived is at the top, and every earlier update is listed under it by version and date, tap to open. Settings \u2192 Info opens the same panel.'],it:['Aprendo la pagina Telecamere ora si aggiorna la miniatura di ogni camera, due alla volta, una sola volta \u2014 cos\xec i riquadri sotto la piega sono vecchi di minuti e non di ore. Finito il giro, si ferma.','Le novit\xe0 sono un pannello, non pi\xf9 un avviso a una riga: in alto la build appena arrivata, sotto l\u2019elenco di tutti gli aggiornamenti precedenti per versione e data, che si aprono al tocco. Impostazioni \u2192 Info apre lo stesso pannello.']}},{version:'1.0.470',date:'2026-09-08',notes:{en:['The debug checkboxes changed with use: an edge crop that came back mirrored, and a box that does not match the path the track drew \u2014 which usually means two subjects ended up sharing one id. "Wrong class" and "audio-only" left; neither was what anyone was actually reporting.'],it:['Le caselle di debug sono cambiate con l\u2019uso: un ritaglio sul bordo tornato specchiato, e un box che non coincide col percorso disegnato dalla traccia \u2014 che di solito significa due soggetti finiti sullo stesso id. Sono uscite "classe sbagliata" e "solo audio": non era quello che si segnalava davvero.']}},{version:'1.0.469',date:'2026-09-08',notes:{en:['Marking an event for debug now offers the questions that keep coming back as checkboxes, so a mark carries a question without typing one. Ticking one writes its phrase into the note; the field below still takes anything the boxes cannot say.'],it:['Marcando un evento per il debug ora trovi come caselle le domande che ricorrono, cos\xec una marcatura porta con s\xe9 una domanda senza doverla scrivere. Spuntarne una scrive la sua frase nella nota; il campo sotto accetta ancora tutto ci\xf2 che le caselle non dicono.']}},{version:'1.0.468',date:'2026-09-08',notes:{en:['The privacy-mask switch now says what is actually missing: no privacy zone is drawn on the camera. It used to give the same general "nothing is set up yet" sentence as every other control, which left no next step \u2014 and the next step is on the camera, not in this app.'],it:["L'interruttore della maschera privacy ora dice cosa manca davvero: sulla telecamera non \xe8 disegnata nessuna zona di privacy. Prima dava la stessa frase generica di ogni altro controllo, che non indicava alcun passo successivo \u2014 e il passo successivo \xe8 sulla telecamera, non in questa app."]}},{version:'1.0.467',date:'2026-09-08',notes:{en:['Unticking every event kind used to leave invisible leftovers behind, so the list stayed empty and the counters disagreed with the boxes. The leftovers are cleared, and no ticks now means no constraint.','Ticking only Faces or Plates therefore works on its own, across every kind, while narrowing them with a kind still works as before.','A collapsed group now shows a partial mark when something inside it is ticked, so nothing can be on where you cannot see it.'],it:["Togliendo la spunta a tutti i tipi di evento restavano dietro dei residui invisibili, cos\xec la lista restava vuota e i contatori non coincidevano con le caselle. I residui vengono ripuliti, e nessuna spunta adesso vuol dire nessun vincolo.","Spuntare solo Volti o Targhe funziona quindi da solo, su tutti i tipi, mentre restringerli a un tipo continua a funzionare come prima.","Un gruppo chiuso mostra adesso un segno parziale quando qualcosa al suo interno \xe8 spuntato, cos\xec niente pu\xf2 essere attivo dove non lo vedi."]}},{version:'1.0.466',date:'2026-09-08',notes:{en:['A filter that matched nothing on the first page used to stop the list from loading any further, so a narrow choice looked empty even when matches existed further back. The list now keeps reading until it finds them.','Plates were the clearest case: they sat four pages deep and were never reached. Faces happened to match early, which is why the same defect looked intermittent.','An empty list now says which kind of empty it is, and offers to load older events instead of ending the road.'],it:["Un filtro che non trovava nulla nella prima pagina impediva alla lista di caricare oltre, cos\xec una scelta stretta sembrava vuota anche quando i risultati c'erano pi\xf9 indietro. Adesso la lista continua a leggere finch\xe9 li trova.","Le targhe erano il caso pi\xf9 evidente: stavano quattro pagine pi\xf9 in l\xe0 e non venivano mai raggiunte. I volti capitavano presto, ed \xe8 per questo che lo stesso difetto sembrava intermittente.","Una lista vuota adesso dice di che vuoto si tratta, e propone di caricare gli eventi pi\xf9 vecchi invece di finire l\xec."]}},{version:'1.0.465',date:'2026-09-08',notes:{en:['The event kinds you already had \u2014 Audio, Sensor, Control \u2014 now actually filter. Ticking one shows those events, unticking hides them; there is no second filter to find, because the tree you were already using is the one that works.','Audio events start unticked, so the list opens on what you look at. A Default button puts the preset back without re-ticking everything by hand.','The chip counts what you kept in the terms you picked it in, so a default that hides one thing reads as one thing hidden.'],it:["I tipi di evento che avevi gi\xe0 \u2014 Audio, Sensore, Controllo \u2014 adesso filtrano davvero. Spuntandone uno vedi quegli eventi, togliendo la spunta li nascondi, e non c'\xe8 un secondo filtro da cercare: quello che usavi \xe8 quello che funziona.","Gli eventi audio partono senza spunta, cos\xec la lista si apre su quello che guardi. Un pulsante Predefinito rimette il preset senza dover rispuntare tutto a mano.","Il contatore conta quello che hai tenuto nei termini in cui l'hai scelto, cos\xec un default che nasconde una cosa si legge come una cosa nascosta."]}},{version:'1.0.464',date:'2026-09-07',notes:{en:['The events page can now filter by where an event came from, and audio-only events start hidden. The filter sits in More with the others, and the chip counts it, so a shorter list always says why it is shorter.','Picking a class used to drag every sensor and audio event along with it, and picking a sensor selected nothing at all. Provenance is now its own axis, so both do what they say.','The Recent strip on the Cameras screen has its own filter, in the same fan menu, showing detections by default and remembering what you choose.'],it:["La pagina eventi ora filtra anche per provenienza, e gli eventi di solo audio partono nascosti. Il filtro sta in Altro insieme agli altri e il contatore lo conta, cos\xec una lista pi\xf9 corta dice sempre perch\xe9 lo \xe8.","Scegliere una classe si portava dietro ogni evento di sensore e di audio, e scegliere un sensore non selezionava nulla. La provenienza adesso \xe8 un asse suo, quindi entrambi fanno quello che dicono.","La striscia Recenti nella schermata Camere ha un filtro suo, nello stesso menu a ventaglio, che di default mostra le rilevazioni e ricorda quello che scegli."]}},{version:'1.0.463',date:'2026-09-07',notes:{en:['One record button, the same pair of buttons everywhere: press it, then Keep \u2014 with the duration on it \u2014 or Discard. On the live picture it records forward from now; on the recording it anchors a period you draw with the scrub, in either direction.','Pressing it during playback no longer reports that the live view cannot be recorded, and the period you draw stops at the live edge instead of losing itself there.','While you are drawing a period the timeline no longer buzzes at every step: the notch feedback belongs to looking for an event, not to choosing a moment.'],it:["Un solo pulsante di registrazione, e la stessa coppia di pulsanti ovunque: premi, poi Salva \u2014 con la durata sopra \u2014 oppure Scarta. Sull'immagine live registra da adesso in avanti; sul registrato fissa un periodo che disegni con lo scorrimento, in entrambe le direzioni.","Premendolo durante la riproduzione non dice pi\xf9 che non pu\xf2 registrare la vista live, e il periodo che stai disegnando si ferma al bordo live invece di perdersi.","Mentre disegni un periodo la timeline non vibra pi\xf9 a ogni passo: lo scatto delle tacche serve a cercare un evento, non a scegliere un momento."]}},{version:'1.0.462',date:'2026-09-07',notes:{en:['Save a stretch of the recording from the timeline: press the record button during playback to anchor the period, scrub to the other end, then Save or Discard. The selected period is highlighted on the strip.','While you are choosing, the recording does not play \u2014 you see the frame you scrubbed to. Nothing is created on the hub until you press Save, and a period that crosses a stretch with no recording says so before it is exported.'],it:["Salva un tratto di registrato dalla timeline: durante la riproduzione premi il pulsante di registrazione per fissare il periodo, scorri fino all'altro estremo, poi Salva o Scarta. Il periodo selezionato \xe8 evidenziato sulla striscia.","Mentre scegli la registrazione non parte: vedi il fotogramma su cui ti sei fermato. Sull'hub non viene creato nulla finch\xe9 non premi Salva, e un periodo che attraversa un tratto senza registrazione lo dice prima di esportare."]}},{version:'1.0.461',date:'2026-09-07',notes:{en:['A host with nowhere to show a tile\'s linked-devices and view-options panels can now say so, and the embed stops drawing two buttons that would do nothing.'],it:["Un ospite che non ha dove mostrare i pannelli dispositivi collegati e opzioni di vista pu\xf2 dirlo, e l'embed smette di disegnare due pulsanti che non farebbero nulla."]}},{version:'1.0.460',date:'2026-09-06',notes:{en:['Battery and signal icons are now buttons: tapping one opens the figures \u2014 charge, power source, sleeping, link type, signal and Wi-Fi network \u2014 on the stream and in the cameras list.','What the camera does not report is said in words, never as a fabricated 0%.'],it:["Le icone di batteria e segnale sono diventate pulsanti: toccandone una si aprono i numeri \u2014 carica, alimentazione, sospensione, tipo di collegamento, segnale e rete Wi-Fi \u2014 sullo stream e nella lista camere.","Ci\xf2 che la camera non riporta viene detto a parole, mai come uno 0% inventato."]}},{version:'1.0.459',date:'2026-09-06',notes:{en:['Home Assistant cards: the embed no longer needs a viewing token in the page \u2014 Home Assistant carries it, and the events card URL stops carrying a credential.'],it:["Card di Home Assistant: l'embed non ha pi\xf9 bisogno del token nella pagina, lo porta Home Assistant, e l'URL della card eventi smette di trasportare una credenziale."]}},{version:'1.0.458',date:'2026-09-06',notes:{en:['Robot camera in landscape: with the timeline open the drive buttons move onto the visible picture and shrink to fit; the "\u2026" is gone there, the timeline has its own.'],it:['Camera del robot in landscape: con la timeline aperta i pulsanti di guida passano sul video visibile e si rimpiccioliscono; l\xec sparisce il "\u2026", la timeline ha gi\xe0 il suo.']}},{version:'1.0.457',date:'2026-09-06',notes:{en:['A restart for an update waits for the snapshot downloads in flight \u2014 the crash right after an update on build 16.'],it:['Il riavvio per un aggiornamento aspetta i download degli snapshot in corso: il crash subito dopo un aggiornamento sulla build 16.']}},{version:'1.0.456',date:'2026-09-06',notes:{en:['An OTA update asks before restarting the app.','A newer TestFlight / store build is announced, with a button to open it.',"What's new: these notes, once per version and in Settings \u2192 Info."],it:["Un aggiornamento OTA chiede conferma prima di riavviare l'app.",'Una build TestFlight / Store pi\xf9 recente viene segnalata, con il pulsante per aprirla.','Novit\xe0: queste note, una volta per versione e in Impostazioni \u2192 Info.']}},{version:'1.0.455',date:'2026-09-06',notes:{en:['Robot camera: a drive joystick in landscape, with Stop, light, Follow me and Return to dock.','The controls button opens for robot cameras too.','Battery and signal are glyphs in the toolbar; the day arrows fold on a narrow row.','A sleeping camera shows the moon in its name chip.'],it:['Camera del robot: joystick di guida in landscape, con Stop, luce, Seguimi e Torna alla base.','Il pulsante dei controlli si apre anche per le camere del robot.','Batteria e segnale sono glifi nella toolbar; le frecce del giorno si ripiegano su riga stretta.','Una camera dormiente mostra la luna nel chip del nome.']}}];function o(o){return o?e.find(e=>e.version===o)??null:null}},2130,[]);
|
|
3589
|
+
__d(function(g,r,i,a,m,_e,d){"use strict";Object.defineProperty(_e,'__esModule',{value:!0}),Object.defineProperty(_e,"WHATS_NEW",{enumerable:!0,get:function(){return e}}),_e.whatsNewHistory=function(t){const n=o(t);return{latest:n,past:e.filter(e=>e!==n)}},_e.whatsNewFor=o,_e.whatsNewLines=function(e,o){const t=o.toLowerCase().startsWith('it')?'it':'en',n=e.notes[t];return n.length>0?n:e.notes.en},_e.shouldShowWhatsNew=function(e,t){return!!t&&(e!==t&&null!==o(t))};const e=[{version:'1.0.509',date:'2026-09-19',notes:{en:['The timeline column on a tablet is wider, because its toolbar had stopped fitting: the row had wrapped onto a second line and the menu that opens from it was clipped by the column\u2019s edge. The second line was eating the space the timeline itself needs.'],it:['La colonna della timeline su tablet \xe8 pi\xf9 larga, perch\xe9 la sua barra non ci stava pi\xf9: la riga era andata a capo su due righe e il menu che si apre da l\xec veniva tagliato dal bordo della colonna. La seconda riga si mangiava lo spazio che serve alla timeline stessa.']}},{version:'1.0.508',date:'2026-09-19',notes:{en:['The stream numbers on the camera card now actually arrive. They were being measured once a second and thrown away on the way in: the app checks incoming messages for a stats reply, and it was matching any message that merely mentioned stats \u2014 which every sample does. So the card said "no measurement yet" on every camera, permanently, while the data was arriving the whole time.'],it:['I numeri dello stream sulla scheda della telecamera adesso arrivano davvero. Venivano misurati una volta al secondo e buttati via all\u2019ingresso: l\u2019app controlla nei messaggi in arrivo se \xe8 una risposta di statistiche, e accettava qualunque messaggio che nominasse le statistiche \u2014 cosa che ogni campione fa. Cos\xec la scheda diceva \u201cnessuna misura ancora\u201d su ogni telecamera, per sempre, mentre i dati arrivavano da subito.']}},{version:'1.0.507',date:'2026-09-19',notes:{en:['A camera that reports neither a battery nor a link now gets a chart glyph of its own, which opens the same card and its stream numbers. Those cameras had no badge at all, so the card could not be opened on them \u2014 the permanently-powered, wired ones, which are exactly the cameras you are most likely to be investigating.'],it:['Una telecamera che non riporta n\xe9 batteria n\xe9 collegamento adesso ha un\u2019icona a grafico tutta sua, che apre la stessa scheda e i suoi numeri dello stream. Su quelle telecamere non c\u2019era nessuna icona, quindi la scheda non si poteva aprire \u2014 e sono le telecamere fisse alimentate, cio\xe8 proprio quelle su cui \xe8 pi\xf9 probabile che tu stia indagando.']}},{version:'1.0.506',date:'2026-09-19',notes:{en:['The stream numbers moved to where you can reach them. Tap the battery or link glyph on a camera and the card now also carries the stream: the verdict first \u2014 is a frozen picture the network or the decoder? \u2014 then the evidence. Frames decoded and whether they are still advancing, freezes and how long they lasted, key-frame requests, loss, latency and the connection path; and from the hub, which profile you are actually being served, whether that stream is native or transcoded here, which node ingests it, and why the quality ladder last moved. The pill on the picture stays as it is: on a phone the panel behind it could never be opened, because the app owns the touches over the player.'],it:['I numeri dello stream si sono spostati dove puoi raggiungerli. Tocca l\u2019icona della batteria o del collegamento su una telecamera e la scheda adesso porta anche lo stream: prima il verdetto \u2014 un\u2019immagine bloccata \xe8 la rete o il decoder? \u2014 e poi le prove. Fotogrammi decodificati e se stanno ancora avanzando, blocchi e quanto sono durati, richieste di key frame, perdita, latenza e il percorso della connessione; e dall\u2019hub, quale profilo ti sta servendo davvero, se quello stream \xe8 nativo o transcodificato qui, quale nodo lo ingerisce e perch\xe9 la scala di qualit\xe0 si \xe8 mossa l\u2019ultima volta. La pastiglia sull\u2019immagine resta com\u2019\xe8: sul telefono il pannello dietro non si poteva aprire, perch\xe9 i tocchi sopra il player appartengono all\u2019app.']}},{version:'1.0.505',date:'2026-09-19',notes:{en:['The stream stats are a real debug tool now, and they stay out of your way. A small pill above the controls carries the verdict, the resolution, the frame rate and the bitrate; tap it for the full panel. The panel answers the question that mattered and could not be answered before: when a picture freezes, is it the network or the decoder? It shows frames decoded, freezes and their duration, key-frame requests, retransmissions, jitter, loss and the ICE path on the client side \u2014 and, from the hub, which rung you are actually being served, whether that stream is native or transcoded, which node is ingesting it, and why the quality ladder last moved.'],it:['Le statistiche dello stream sono diventate uno strumento di debug vero, e stanno fuori dai piedi. Una pastiglia sopra i controlli porta il verdetto, la risoluzione, i fotogrammi al secondo e il bitrate; toccala per il pannello completo. Il pannello risponde alla domanda che contava e a cui non si poteva rispondere: quando l\u2019immagine si blocca, \xe8 la rete o il decoder? Mostra i fotogrammi decodificati, i blocchi e quanto sono durati, le richieste di key frame, le ritrasmissioni, jitter, perdita e il percorso ICE lato client \u2014 e, dall\u2019hub, quale profilo ti sta servendo davvero, se quello stream \xe8 nativo o transcodificato, quale nodo lo sta ingerendo e perch\xe9 la scala di qualit\xe0 si \xe8 mossa l\u2019ultima volta.']}},{version:'1.0.504',date:'2026-09-17',notes:{en:['The Home button on a PTZ camera now tells you when it cannot do anything. It used to send the camera to whichever preset happened to sit in the first slot \u2014 on these cameras that was \u201cstanza\u201d, \u201cCredenza\u201d and \u201cPreset1\u201d, nobody\u2019s idea of home \u2014 and when that slot was empty it failed in silence. The hub now asks which preset you chose as home, refuses rather than guessing, and the app shows you the refusal instead of swallowing it. Pick one under PTZ settings.'],it:['Il pulsante Home su una telecamera PTZ ora ti dice quando non pu\xf2 fare niente. Prima mandava la telecamera al preset che si trovava nel primo posto \u2014 su queste telecamere erano \u201cstanza\u201d, \u201cCredenza\u201d e \u201cPreset1\u201d, che home non sono \u2014 e quando quel posto era vuoto falliva in silenzio. Adesso l\u2019hub chiede quale preset hai scelto come home, rifiuta invece di indovinare, e l\u2019app ti mostra il rifiuto invece di ingoiarlo. Scegline uno nelle impostazioni PTZ.']}},{version:'1.0.503',date:'2026-09-16',notes:{en:['Pages with camera tiles scroll again on a phone. A tile claimed every touch that landed on it \u2014 and on a phone a tile is most of the screen \u2014 then did nothing with it, because dragging only pans a tile you have already zoomed into. Now the gesture is yours until you zoom in; pinch and double-tap are unchanged.'],it:['Le pagine con i riquadri delle telecamere tornano a scorrere sul telefono. Un riquadro si prendeva ogni tocco che ci finiva sopra \u2014 e sul telefono un riquadro e\u2019 quasi tutto lo schermo \u2014 e poi non ne faceva niente, perche\u2019 trascinare sposta solo un riquadro in cui hai gia\u2019 zoomato. Ora il gesto resta tuo finche\u2019 non zoomi; pinch e doppio tocco invariati.']}},{version:'1.0.502',date:'2026-09-16',notes:{en:['Zones, above the places: a part of the home that holds several rooms \u2014 \u201cZona notte\u201d for the bedrooms. They come first in the filter strip, with their own icon, because it is the coarser question: asking for upstairs should not mean pressing four rooms. Create them on the hub, under Locations.','A camera still belongs to exactly one place, and a place to at most one zone. Nothing about your cameras changed to make this work.','The drawn zones in the rule editor are now called detection zones, which is what they are \u2014 so the word is free for the rooms of your home.'],it:['Le zone, sopra i luoghi: una parte della casa che tiene pi\xf9 stanze \u2014 \u201cZona notte\u201d per le camere da letto. Vengono per prime nella striscia dei filtri, con la loro icona, perch\xe9 sono la domanda pi\xf9 grossa: chiedere il piano di sopra non deve voler dire premere quattro stanze. Si creano sull\u2019hub, sotto Locations.','Una telecamera resta in un solo luogo, e un luogo in al massimo una zona. Non \xe8 cambiato nulla sulle tue telecamere perch\xe9 questo funzionasse.','Le zone disegnate nell\u2019editor delle regole ora si chiamano zone di rilevamento, che \xe8 quello che sono \u2014 cos\xec la parola resta libera per le stanze di casa.']}},{version:'1.0.501',date:'2026-09-16',notes:{en:['Choosing a place that has nothing in it no longer takes the page away. Pressing Favourites with nothing starred replaced the reel, the selector and the cameras with \u201cno cameras configured\u201d \u2014 and took away the control that would have undone it. The reel and the strip stay put; only the list below says it is empty.','The location chips are the size of chips again, and Favourites is in your language.'],it:['Scegliere un luogo vuoto non porta pi\xf9 via la pagina. Premere Preferite senza averne sostituiva reel, selettore e camere con \u201cnessuna camera configurata\u201d \u2014 e toglieva proprio il comando per tornare indietro. Reel e striscia restano al loro posto; \xe8 la lista sotto a dire che \xe8 vuota.','I chip dei luoghi sono tornati alti quanto un chip, e Preferite \xe8 nella tua lingua.']}},{version:'1.0.500',date:'2026-09-16',notes:{en:['The camera list has a location strip, between the reel and the cameras. Favourites first \u2014 with a count, because an empty shortlist is worth knowing before you press into it \u2014 then \u201cAll\u201d, then every place your cameras actually name. Pressing the place you are already in takes you back out, so a room whose cameras are all offline is never a dead end.','A heart on each camera, top left. Favourites live in your profile and travel with it: share the profile and they go too. They are yours alone otherwise.','A place can carry its own icon, chosen in the hub. A room nobody gave one to shows no icon at all rather than a default \u2014 \u201cnobody chose\u201d and \u201cthe pin was chosen\u201d are different things.'],it:['La lista camere ha una striscia dei luoghi, fra il reel e le camere. Prima le Preferite \u2014 col conteggio, perch\xe9 una lista corta vuota \xe8 meglio saperlo prima di entrarci \u2014 poi \u201cTutte\u201d, poi ogni luogo che le tue camere hanno davvero. Premere il luogo in cui sei gi\xe0 ti riporta indietro, cos\xec una stanza con tutte le camere offline non \xe8 mai un vicolo cieco.','Un cuore su ogni camera, in alto a sinistra. Le preferite stanno nel tuo profilo e viaggiano con lui: condividi il profilo e vanno con quello. Per il resto sono solo tue.','Un luogo pu\xf2 avere la sua icona, scelta sull\u2019hub. Una stanza a cui nessuno l\u2019ha data non disegna nessuna icona invece di una di default \u2014 \u201cnessuno ha scelto\u201d e \u201cha scelto il pin\u201d sono due cose diverse.']}},{version:'1.0.499',date:'2026-09-15',notes:{en:['The debug reasons are the ones you actually use. Nine of them, in your order \u2014 the old list had been inferred from a reading of eleven real notes; this one was dictated by the person who reviews with it. \u201cNo crop\u201d is gone: a crop that is WRONG and a crop that is ABSENT are two different findings, and one checkbox was blurring them.','A track\u2019s media strip can now show \u201cGate crop\u201d \u2014 the pixels the confirmation gate judged, kept when it refused to confirm a birth. It exists to be argued with: it is the only thing that can say whether the detector was right to drop a sighting.'],it:['Le reason di debug sono quelle che usi davvero. Nove, nel tuo ordine \u2014 la lista precedente era stata dedotta da una lettura di undici note reali; questa l\u2019ha dettata chi ci rivede. \xc8 sparito \u201cnessun ritaglio\u201d: un crop SBAGLIATO e un crop ASSENTE sono due reperti diversi, e una casella sola li confondeva.','La striscia media di una traccia pu\xf2 ora mostrare \u201cGate crop\u201d \u2014 i pixel su cui il confirmation gate ha deciso, tenuti quando ha rifiutato di confermare una nascita. Serve per poterlo contestare: \xe8 l\u2019unica cosa che dice se il detector avesse ragione a scartare un avvistamento.']}},{version:'1.0.498',date:'2026-09-15',notes:{en:['The \u201c?\u201d on an events card really does open the assignment now. It was made a button last time and still could not be tapped: it sits in the caption row, which is deliberately transparent to touches so the labels never swallow the card\u2019s own open \u2014 and the button inherited that.','Audio on open is no longer one answer for every camera. Alongside \u201calways on\u201d and \u201calways off\u201d there is now \u201cas you left it\u201d, which is the new default: each camera opens the way you last left it, and a camera you have never chosen on opens silent.'],it:['Il \u201c?\u201d su una card degli eventi ora apre davvero l\u2019assegnazione. L\u2019ultima volta era diventato un pulsante e restava comunque intoccabile: sta nella riga delle etichette, che \xe8 trasparente ai tocchi apposta perch\xe9 le etichette non si mangino l\u2019apertura della card \u2014 e il pulsante ereditava quella trasparenza.','L\u2019audio all\u2019apertura non \xe8 pi\xf9 una risposta sola per tutte le camere. Accanto a \u201csempre acceso\u201d e \u201csempre spento\u201d c\u2019\xe8 ora \u201ccome l\u2019hai lasciato\u201d, che \xe8 il nuovo default: ogni camera si apre com\u2019era l\u2019ultima volta, e una camera su cui non hai mai scelto si apre muta.']}},{version:'1.0.497',date:'2026-09-14',notes:{en:['You can add a linked device from the camera\u2019s own panel, not only from the cameras list. The panel showed you what was linked and gave you nowhere to add one, so the answer was to leave the camera you were looking at.','The keyboard no longer covers the device picker while you search it. And tapping outside now closes the keyboard first, so a search you were half way through is not thrown away with it.'],it:['Puoi aggiungere un dispositivo collegato dal pannello della camera stessa, non solo dalla lista camere. Il pannello ti mostrava cosa era collegato e non ti dava dove aggiungerne uno, quindi la risposta era uscire dalla camera che stavi guardando.','La tastiera non copre pi\xf9 il selettore dei dispositivi mentre lo cerchi. E il tocco fuori ora chiude prima la tastiera, cos\xec una ricerca lasciata a met\xe0 non se ne va con lei.']}},{version:'1.0.496',date:'2026-09-14',notes:{en:['The \u201c?\u201d on an events card now opens the assignment. It was a label that said a face was waiting for a name and did nothing when you tapped it \u2014 so you opened the card and looked for the assignment again, answering a question you had already asked.','A group now shows its PATH: what each of its subjects did, drawn on the picture they were in together, one colour each. Every member already had its own crop in the group; what was missing was where they went.'],it:['Il \u201c?\u201d su una card degli eventi ora apre l\u2019assegnazione. Era un\u2019etichetta che diceva che un volto aspettava un nome e non faceva niente al tocco \u2014 cos\xec aprivi la card e ricercavi l\u2019assegnazione, rispondendo a una domanda che avevi gi\xe0 fatto.','Un gruppo ora mostra il suo PERCORSO: cosa ha fatto ognuno dei suoi soggetti, disegnato sull\u2019immagine in cui erano insieme, un colore per ciascuno. Ogni membro aveva gi\xe0 il suo ritaglio nel gruppo; mancava dove sono andati.']}},{version:'1.0.495',date:'2026-09-13',notes:{en:['Groups with no camera filter now list every camera. Leaving the camera chip untouched means "all of them" here, and it meant "none of them" to the hub \u2014 so the gallery came back empty on a system full of groups.'],it:['I gruppi senza filtro camera ora elencano tutte le telecamere. Non toccare il chip delle camere qui significa \u201ctutte\u201d, e per l\u2019hub significava \u201cnessuna\u201d \u2014 cos\xec la galleria tornava vuota su un sistema pieno di gruppi.']}},{version:'1.0.494',date:'2026-09-13',notes:{en:['Administrators can link devices to a camera from the phone \u2014 a doorbell, a sensor, a light \u2014 in the same list the pencil arranges. The picker suggests the devices in that camera\u2019s own room first, and nothing is linked until you pick it.'],it:['Gli amministratori possono collegare device a una telecamera dal telefono \u2014 un campanello, un sensore, una luce \u2014 nella stessa lista che la matita riordina. Il selettore suggerisce per primi i device della stanza di quella telecamera, e niente viene collegato finch\xe9 non lo scegli tu.']}},{version:'1.0.493',date:'2026-09-13',notes:{en:['You can arrange the camera list by hand. A small pencil in the corner turns the list into edit mode, you drag the rows, and a tick saves. Nothing is draggable until you ask \u2014 no more reordering a camera by accident \u2014 and cancelling puts back exactly the order you started with, not the last one saved.','The arrangement is yours and stays on this device. A camera added on the hub appears at the end rather than somewhere unpredictable, and an order can move a camera but can never hide one.'],it:['Puoi sistemare la lista delle telecamere a mano. Una piccola matita nell\u2019angolo mette la lista in modifica, trascini le righe, e la spunta salva. Niente \xe8 trascinabile finch\xe9 non lo chiedi \u2014 niente pi\xf9 riordini per sbaglio \u2014 e annullare rimette esattamente l\u2019ordine da cui eri partito, non l\u2019ultimo salvato.','La disposizione \xe8 tua e resta su questo dispositivo. Una telecamera aggiunta sull\u2019hub compare in fondo invece che in un punto imprevedibile, e un ordine pu\xf2 spostare una telecamera ma non pu\xf2 mai nasconderla.']}},{version:'1.0.492',date:'2026-09-13',notes:{en:['Three pages can now list GROUPS instead of subjects: the camera timeline, the reel on the cameras page, and the Events gallery. A family walking in together is one entry with several pictures, not four cards. Each page has its OWN switch and each one starts on subjects \u2014 nothing changes until you ask it to, and you can always switch back from the page itself.','A group card shows what the group was made of \u2014 two people and a dog \u2014 and a Live chip while the session is still running. Opening it lists the members, each one linking to its own track.','The reel draws groups as their own strip, with several images per entry and no clustering: two sessions seconds apart are two things that happened, and the old grouping used to swallow one of them.','Filtering understands groups. Picking Dog now finds the arrivals that HAD a dog with them, including the group of four people \u2014 the filter asks about the members, and it runs on the hub rather than on your phone.'],it:['Tre pagine possono ora elencare i GRUPPI invece dei soggetti: la timeline della telecamera, il reel nella pagina telecamere e la galleria Eventi. Una famiglia che entra insieme \xe8 una voce sola con pi\xf9 immagini, non quattro schede. Ogni pagina ha il SUO interruttore e parte dai soggetti \u2014 non cambia nulla finch\xe9 non lo chiedi tu, e si torna indietro dalla pagina stessa.','La scheda di un gruppo dice di cosa era fatto \u2014 due persone e un cane \u2014 e porta la pastiglia Live finch\xe9 la sessione \xe8 in corso. Aprendola trovi i membri, ognuno con il link alla sua traccia.','Nel reel i gruppi hanno una striscia propria, con pi\xf9 immagini per voce e senza raggruppamento: due sessioni a pochi secondi di distanza sono due cose successe, e il vecchio accorpamento se ne mangiava una.','Il filtro capisce i gruppi. Scegliere Cane ora trova gli arrivi che AVEVANO un cane con loro, compreso il gruppo di quattro persone \u2014 il filtro chiede dei membri, e gira sull\u2019hub invece che sul telefono.']}},{version:'1.0.491',date:'2026-09-13',notes:{en:['The movable window now carries the stream\u2019s own controls: audio, talk-back, picture-in-picture, and a button that opens that camera full-screen. They are the same controls as the single-camera screen \u2014 the same code, so they cannot drift apart.','The resize corner wore the FULLSCREEN icon, so the grip was signing the wrong action. It now looks like every other control in the app.','The heatmap in that window only ever drew recordings. Motion and audio were never missing from the hub \u2014 the window was handing the bar an empty list. Both lanes are there now. Detections are deliberately still absent: loading them costs a few hundred kilobytes, which a floating panel over a live stream should not spend.','Exports and the hub\u2019s own files are ONE section, now called Media. An export finally has a detail view and plays in the app instead of only downloading, and the filter is the one from Events \u2014 a chip per facet that says what it is narrowing, instead of a pill that only counted.','You can delete what the hub produced. Until now a timelapse could only be waited out. A video takes its preview still with it, so one card frees both files.','The timeline can show GROUPS instead of subjects: a family arriving together is one card, not three. Off by default \u2014 turn it on in the timeline filters or in Settings. A session still in progress is listed with a Live chip rather than hidden.'],it:['La finestra mobile ora porta i comandi dello stream: audio, microfono, picture-in-picture e un pulsante che apre quella telecamera a schermo intero. Sono gli STESSI comandi della schermata singola \u2014 lo stesso codice, quindi non possono divergere.','L\u2019angolo di ridimensionamento portava l\u2019icona dello SCHERMO INTERO: la presa firmava l\u2019azione sbagliata. Ora ha l\u2019aspetto di ogni altro comando dell\u2019app.','La heatmap in quella finestra disegnava solo le registrazioni. Movimento e audio non sono mai mancati dall\u2019hub \u2014 era la finestra a passare alla barra una lista vuota. Ora ci sono entrambi. Le rilevazioni restano fuori di proposito: caricarle costa qualche centinaio di kilobyte, che un pannello sopra uno stream dal vivo non deve spendere.','Gli export e i file prodotti dall\u2019hub sono UNA sezione sola, che ora si chiama Media. Un export ha finalmente una scheda e si riproduce dentro l\u2019app invece di poter solo essere scaricato, e il filtro \xe8 quello di Eventi \u2014 una pastiglia per faceta che dice cosa sta restringendo, invece di una che contava e basta.','Puoi cancellare quello che ha prodotto l\u2019hub. Fino a ora un timelapse si poteva solo aspettare. Un video porta via anche la sua anteprima, quindi una card libera due file.','La timeline pu\xf2 mostrare i GRUPPI invece dei soggetti: una famiglia che arriva insieme \xe8 una card, non tre. Spento di default \u2014 si accende dai filtri della timeline o dalle Impostazioni. Una sessione ancora in corso viene elencata con la pastiglia Live, non nascosta.']}},{version:'1.0.490',date:'2026-09-13',notes:{en:['The movable window resizes properly now. The handle always worked \u2014 the sizes behind it did not: all three snaps came out the same box on a phone, so dragging changed nothing. The grip is finger-sized and no longer shares its corner with the playback controls.','The playback bar inside that window fits the width it is given. It was drawing a full-width bar into a small window with nothing to wrap into, which is why LIVE broke onto two lines and buttons landed on top of each other.','Event thumbnails stop failing to warm. The list was pre-fetching them with the wrong kind of id \u2014 an event\u2019s, where a track\u2019s was needed \u2014 so every pre-fetch missed and the picture had to be fetched again when the card appeared.','Picture-in-picture on app close is gone. It was granted by the system and lost 176 ms later, every time: Apple only starts picture-in-picture in response to something you do, and an app closing is not that. The button on the player still works and survives closing the app.'],it:['La finestra mobile ora si ridimensiona davvero. La maniglia ha sempre funzionato \u2014 erano le misure dietro a non funzionare: su telefono tutte e tre le taglie davano la stessa identica finestra, quindi trascinare non cambiava nulla. L\u2019angolo di presa \xe8 dimensionato per un dito e non se lo contende pi\xf9 con i comandi di riproduzione.','La barra di riproduzione dentro quella finestra si adatta alla larghezza che ha. Prima disegnava una barra intera dentro una finestra piccola senza spazio in cui andare a capo: per questo LIVE finiva su due righe e i pulsanti si sovrapponevano.','Le miniature degli eventi smettono di fallire il precaricamento. La lista le chiedeva con il tipo di id sbagliato \u2014 quello dell\u2019evento invece che quello della traccia \u2014 quindi ogni precaricamento mancava e l\u2019immagine andava richiesta da capo quando la card compariva.','Il picture-in-picture alla chiusura dell\u2019app non c\u2019\xe8 pi\xf9. Il sistema lo concedeva e lo perdeva 176 ms dopo, ogni volta: Apple avvia il picture-in-picture solo in risposta a qualcosa che fai tu, e chiudere l\u2019app non lo \xe8. Il pulsante sul player continua a funzionare e sopravvive alla chiusura.']}},{version:'1.0.489',date:'2026-09-13',notes:{en:['Review: deleting a sample from a person now actually deletes it. The request was never leaving the app \u2014 it was looked up in a way that can never find it, so nothing happened and nothing said so.','Review: you can delete parked faces you do not want to keep, and create a new person without leaving the page. Picking a person is a searchable list instead of a row of chips that grew with your gallery.','Review: the similar-groups button kept going quiet after the first pass. It was comparing faces over a wide window and then only showing groups that fell inside a much narrower one, so the matches sitting just outside vanished. One window now \u2014 and the button no longer claims a number.','The movable player lost its padlock: it came along with the shared playback bar and did nothing there but swallow your taps.','Opening a camera full-screen now closes the movable window if it was showing that same camera, instead of leaving two pictures of it.'],it:['Review: cancellare un campione da una persona ora lo cancella davvero. La richiesta non usciva nemmeno dall\u2019app \u2014 veniva cercata in un modo che non pu\xf2 trovarla, quindi non succedeva nulla e nulla lo diceva.','Review: puoi cancellare le facce parcheggiate che non vuoi tenere, e creare una nuova persona senza uscire dalla pagina. Scegliere una persona ora \xe8 una lista con ricerca invece di una fila di pastiglie che cresceva con la tua galleria.','Review: il pulsante dei gruppi simili ammutoliva dopo il primo giro. Confrontava le facce su una finestra ampia e poi mostrava solo i gruppi che cadevano dentro una molto pi\xf9 stretta, quindi le somiglianze appena fuori sparivano. Ora la finestra \xe8 una sola \u2014 e il pulsante non promette pi\xf9 un numero.','Il player mobile ha perso il lucchetto: arrivava insieme alla barra di riproduzione condivisa e l\xec non faceva altro che ingoiare i tuoi tocchi.','Aprire una telecamera a schermo intero ora chiude la finestra mobile se mostrava quella stessa telecamera, invece di lasciarne due immagini.']}},{version:'1.0.488',date:'2026-09-13',notes:{en:['The movable player works on the phone now, not only on tablets and wide windows. A button on each camera card summons it without leaving the list, and its title is the CAMERA\u2019s name \u2014 it used to say "Playback", which cannot tell two open windows apart.','The downward swipe on a camera changed hands: one finger goes back, two fingers hand the camera to the movable player and go back. Picture-in-picture is no longer a gesture at all \u2014 it now happens by itself when you close the app on a single camera, because that is the moment your hands are busy pressing Home. There is a switch for it under Stream.','Audio is on when you open a camera. It used to open muted until you found the button.','Settings were reorganised: General (theme, language, press feedback) sits right under Server, the event-vibration switches are gone, and on a tablet or a desktop window the sections lay out in two or three columns instead of one long scroll.'],it:['Il player mobile ora funziona anche sul telefono, non solo su tablet e finestre larghe. Un pulsante su ogni scheda telecamera lo apre senza uscire dalla lista, e il titolo \xe8 il nome della TELECAMERA \u2014 prima diceva "Riproduzione", che non distingue due finestre aperte.','Lo scorrimento verso il basso su una telecamera cambia mano: un dito torna indietro, due dita passano la telecamera al player mobile e tornano indietro. Il picture-in-picture non \xe8 pi\xf9 un gesto \u2014 ora parte da solo quando chiudi l\u2019app su una singola telecamera, perch\xe9 quello \xe8 il momento in cui le mani sono occupate a premere Home. C\u2019\xe8 un interruttore sotto Streaming.','L\u2019audio \xe8 attivo quando apri una telecamera. Prima si apriva muta finch\xe9 non trovavi il pulsante.','Impostazioni riorganizzate: Generale (tema, lingua, vibrazione alla pressione) sta subito sotto Server, gli interruttori di vibrazione sugli eventi sono spariti, e su tablet o finestra desktop le sezioni si dispongono su due o tre colonne invece di una lista lunga.']}},{version:'1.0.487',date:'2026-09-13',notes:{en:['Thumbnails and track media are back. A media file used to be addressed by a composite key that embedded a foreign id, and once every event table got its own numbering those keys started naming the wrong row \u2014 a night shot could answer for a different camera. The hub now addresses a media file by its own id, and asks for "the best picture of this track" as its own question. The app had been left on the old address, so every thumbnail it asked for came back missing: the track detail opened empty and the timeline drew nothing.','Playback got a player you can move. Open a recording from anywhere and it keeps playing in a window you can drag and resize, and it survives you navigating elsewhere in the app.','The camera reel lights up when something happens \u2014 motion and audio, on by default, with a settings panel to choose what counts. Tapping a camera in the reel now swaps it in place instead of reloading the page, and if you are in playback the new camera opens at the same instant you were watching, not at its own live edge.'],it:['Le miniature e i media delle tracce sono tornati. Un file media veniva indirizzato con una chiave composta che conteneva un id altrui, e da quando ogni tabella di eventi ha una sua numerazione quelle chiavi hanno cominciato a nominare la riga sbagliata \u2014 uno scatto notturno poteva rispondere per un\u2019altra telecamera. L\u2019hub ora indirizza un media con il suo id, e chiede \u201cla foto migliore di questa traccia\u201d come domanda a s\xe9. L\u2019app era rimasta all\u2019indirizzo vecchio, quindi ogni miniatura che chiedeva tornava mancante: il dettaglio della traccia si apriva vuoto e la timeline non disegnava nulla.','La riproduzione ha un player che puoi spostare. Apri una registrazione da qualsiasi punto e continua in una finestra che puoi trascinare e ridimensionare, e resta l\xec anche se navighi altrove nell\u2019app.','Il carosello delle telecamere si illumina quando succede qualcosa \u2014 movimento e audio, attivi di default, con un pannello per scegliere cosa conta. Toccare una telecamera nel carosello ora la scambia sul posto invece di ricaricare la pagina, e se sei in riproduzione la nuova telecamera si apre allo stesso istante che stavi guardando, non al suo live.']}},{version:'1.0.486',date:'2026-09-11',notes:{en:['The camera timeline now opens on the last hour instead of the last three. Three hours was the density the timeline had always drawn, not a decision about what you want to see when you open a camera \u2014 it put whatever just happened in a third of the screen and made the rest yesterday\u2019s scrolling.','Event cards now sit ON the track they describe. The timeline runs newest at the top, so a track ends above and begins below \u2014 but the card was anchored by its top edge to the track\u2019s beginning, which hung it under the event, over the minutes before anything happened. Now the card\u2019s bottom edge is where the track starts, so the card covers the subject\u2019s own passage and reading upward follows it.'],it:['La timeline della telecamera si apre sull\u2019ultima ora invece che sulle ultime tre. Tre ore erano la densit\xe0 che la timeline aveva sempre disegnato, non una scelta su cosa serve vedere aprendo una telecamera: mettevano quello appena successo in un terzo di schermo e rendevano il resto lo scroll di ieri.','Le card degli eventi ora stanno SOPRA la traccia che descrivono. La timeline ha il pi\xf9 recente in alto, quindi una traccia finisce sopra e comincia sotto \u2014 ma la card era ancorata col bordo superiore all\u2019inizio della traccia, il che la appendeva sotto l\u2019evento, sui minuti in cui non era ancora successo nulla. Ora il bordo inferiore della card \xe8 dove la traccia comincia, cos\xec la card copre il passaggio del soggetto e leggere verso l\u2019alto lo segue.']}},{version:'1.0.485',date:'2026-09-11',notes:{en:['The app now hangs up when you leave it, and calls back when you return. In the background the phone freezes the app and stops reading, but the connection stayed open \u2014 so the hub kept piling up messages for a listener that was asleep. One evening of that was 88 MB held on the hub for a phone nobody was holding. The app now closes the connection as it leaves and opens a new one as it comes back.','Coming back is a normal thing, not a fault: no error, no "offline", nothing emptied. You see a brief "connecting" and the screen you left, and the app re-asks the hub for everything that can have changed while it was away \u2014 cameras, batteries, switches, who is in frame \u2014 so what you are looking at a second later is current rather than remembered.'],it:['L\u2019app ora chiude la linea quando la lasci, e richiama quando torni. In background il telefono congela l\u2019app e smette di leggere, ma la connessione restava aperta \u2014 cos\xec l\u2019hub continuava ad accumulare messaggi per un ascoltatore che dormiva. Una sera cos\xec erano 88 MB tenuti sull\u2019hub per un telefono che nessuno aveva in mano. Ora l\u2019app chiude la connessione mentre esce e ne apre una nuova quando rientra.','Il rientro \xe8 una cosa normale, non un guasto: nessun errore, nessun \u201coffline\u201d, niente che si svuota. Vedi un breve \u201cconnessione\u201d e la schermata che avevi lasciato, e l\u2019app richiede all\u2019hub tutto quello che pu\xf2 essere cambiato mentre era via \u2014 telecamere, batterie, interruttori, chi \xe8 inquadrato \u2014 cos\xec quello che guardi un secondo dopo \xe8 attuale e non ricordato.']}},{version:'1.0.484',date:'2026-09-11',notes:{en:['Pinch-to-zoom, the pan while zoomed and the PTZ joystick work again. The crash guard added in 1.0.479 wrapped every gesture handler, and the wrapped handlers were no longer compiled for the UI thread \u2014 so each gesture was caught and dropped on every frame instead of running. Nothing was lost on the hub: every dropped gesture was logged, which is how this was found.','The camera timeline filter now lists every detection class that actually appears in the loaded window, even when the hub does not advertise it for that camera. A class you could see on the timeline but not tick in the filter was the hub describing the camera from a momentary status; the viewer no longer hides what it is showing.'],it:['Il pinch-to-zoom, lo spostamento da zoomato e il joystick PTZ funzionano di nuovo. La protezione anti-crash aggiunta nella 1.0.479 avvolgeva ogni gestore dei gesti, e i gestori avvolti non venivano pi\xf9 compilati per il thread UI \u2014 quindi ogni gesto veniva intercettato e scartato a ogni frame invece di eseguire. Sull\u2019hub non \xe8 andato perso nulla: ogni gesto scartato \xe8 stato registrato, ed \xe8 cos\xec che \xe8 stato trovato.','Il filtro della timeline della telecamera ora elenca ogni classe di rilevamento che compare davvero nella finestra caricata, anche quando l\u2019hub non la dichiara per quella telecamera. Una classe che vedevi sulla timeline ma non potevi spuntare nel filtro era l\u2019hub che descriveva la telecamera da uno stato momentaneo; il viewer non nasconde pi\xf9 ci\xf2 che sta mostrando.']}},{version:'1.0.483',date:'2026-09-10',notes:{en:['On a tablet, turning from portrait to landscape puts the timeline back beside the picture. The app was reading its window size from a notification that sometimes arrived seconds late, or not at all, so it kept laying out for portrait inside a landscape screen until you killed it. It now reads the size of the view you are actually looking at.','The camera reel under the player refreshes in turns instead of all at once. Every card used to ask the hub for a new frame in the same second, every fifteen seconds \u2014 thirty captures in a burst, and the slow cameras never made it in time. Now a quarter of the reel takes its turn on each poll, so each card refreshes about every twenty seconds and the hub is never asked for thirty frames at once.'],it:['Su tablet, ruotando da verticale a orizzontale la timeline torna accanto all\u2019immagine. L\u2019app leggeva la dimensione della finestra da una notifica che a volte arrivava con secondi di ritardo, o mai, e continuava a impaginare in verticale dentro uno schermo orizzontale finch\xe9 non la chiudevi. Ora legge la dimensione della vista che stai davvero guardando.','Il nastro delle telecamere sotto il player si aggiorna a turni invece che tutto insieme. Ogni scheda chiedeva all\u2019hub un frame nuovo nello stesso secondo, ogni quindici secondi \u2014 trenta catture in raffica, e le telecamere lente non facevano mai in tempo. Ora a ogni giro tocca a un quarto del nastro, cos\xec ogni scheda si aggiorna circa ogni venti secondi e all\u2019hub non vengono mai chiesti trenta frame in una volta.']}},{version:'1.0.482',date:'2026-09-10',notes:{en:['When assigning a face fails, it now says why. The failure was caught and thrown away in eight different places \u2014 you saw "could not assign a face" and there was nothing, anywhere, to explain it. The reason is now recorded and reaches the hub, including the case where the server answers but assigns nothing.','The app also stopped narrating itself. Four routine messages \u2014 one per camera tile, several times each \u2014 were more than half of everything it sent to the hub. They are still there in debug mode; what stays are the lines that report something going wrong.'],it:['Quando assegnare una faccia fallisce, ora dice perch\xe9. L\u2019errore veniva catturato e buttato via in otto punti diversi \u2014 tu vedevi \u201cimpossibile assegnare una faccia\u201d e non c\u2019era nulla, da nessuna parte, che lo spiegasse. Ora il motivo viene registrato e arriva all\u2019hub, compreso il caso in cui il server risponde ma non assegna niente.','L\u2019app ha anche smesso di raccontarsi. Quattro messaggi di routine \u2014 uno per riquadro di telecamera, pi\xf9 volte ciascuno \u2014 erano pi\xf9 della met\xe0 di tutto ci\xf2 che spediva all\u2019hub. Restano in modalit\xe0 debug; quel che resta sempre sono le righe che segnalano qualcosa che non va.']}},{version:'1.0.481',date:'2026-09-10',notes:{en:['Assigning faces no longer freezes the page. "Apply suggestions" writes one group per person, and each group used to wait for the whole gallery to be re-read before the next one started \u2014 six people meant dozens of round trips before you got the screen back. The gallery is now re-read once, when the last group is written. Assigning one face at a time waits only for the card you are looking at.','Scrubbing the timeline had a pulse every 80 ms \u2014 twelve a second, which is a buzz and not detents. It is now paced to feel like clicks, and dragging is lighter for it.'],it:['Assegnare le facce non blocca pi\xf9 la pagina. "Applica suggerimenti" scrive un gruppo per persona, e ogni gruppo aspettava che l\u2019intera galleria fosse riletta prima che partisse il successivo \u2014 sei persone significavano decine di andate e ritorni prima di riavere lo schermo. Ora la galleria si rilegge una volta sola, quando l\u2019ultimo gruppo \xe8 scritto. Assegnando una faccia per volta si aspetta soltanto la scheda che stai guardando.','Lo scrub della timeline aveva una vibrazione ogni 80 ms \u2014 dodici al secondo, che \xe8 un ronzio e non degli scatti. Ora \xe8 cadenzata per sembrare clic, e trascinare \xe8 pi\xf9 leggero.']}},{version:'1.0.480',date:'2026-09-10',notes:{en:['The timeline\u2019s audio bar shows the LEVEL now. It was showing how MANY audio events fell in each slot, painted on the same six-rung meter the live view uses for decibels \u2014 so fifty short clicks in a quiet hour lit every rung, whatever their volume. The hub now works out the average loudness of each slot and the bar draws that: a busy quiet hour reads quiet, one door slam reads loud. A slot with no audio at all draws nothing, because \u201cnothing was heard\u201d and \u201cnothing was measured\u201d are not the same thing.','A gesture that fails no longer takes the app down with it. The joystick and the pinch-zoom ran code that, if it threw, closed the app outright \u2014 three crash reports came from exactly that. Now the gesture is simply dropped and the reason is sent back, so the next one can be fixed instead of guessed at.'],it:['La barra audio della timeline mostra finalmente il LIVELLO. Prima mostrava QUANTI eventi audio cadevano in ogni fascia, disegnati sullo stesso misuratore a sei tacche che la vista live usa per i decibel \u2014 cos\xec cinquanta clic brevi in un\u2019ora tranquilla accendevano tutte le tacche, qualunque fosse il volume. Ora l\u2019hub calcola la rumorosit\xe0 media di ogni fascia e la barra disegna quella: un\u2019ora tranquilla ma affollata resta bassa, una porta sbattuta si vede. Una fascia senza audio non disegna nulla, perch\xe9 \u201cnon si \xe8 sentito niente\u201d e \u201cnessuno ha misurato\u201d non sono la stessa cosa.','Un gesto che va in errore non porta pi\xf9 gi\xf9 l\u2019app. Il joystick e lo zoom a pinch eseguivano codice che, se falliva, chiudeva l\u2019app di netto \u2014 tre segnalazioni di crash venivano esattamente da l\xec. Ora il gesto viene semplicemente ignorato e il motivo viene rimandato indietro, cos\xec il prossimo si corregge invece di indovinarlo.']}},{version:'1.0.479',date:'2026-09-09',notes:{en:['Pinch-zoom, second attempt. Yesterday\u2019s fix stopped the box resizing under your fingers, and that turned out to be the wrong half: with the panel set to grow, the picture kept zooming and sliding for a third of a second AFTER you let go \u2014 worst at full zoom, where all of the growth was still pending. The panel now grows under your fingers again, but the player\u2019s own frame never moves: the growth is folded into the zoom itself. Turn on debug mode and a pinch now writes one trace line you can send back.','The app also says far less to the hub: two diagnostics were 72% of everything it shipped \u2014 one of them logged every camera tile twice more just for sitting still while its snapshot aged.'],it:['Zoom a pinch, secondo tentativo. La correzione di ieri ha tolto il riquadro che si ridimensionava sotto le dita, e si \xe8 rivelata la met\xe0 sbagliata: col pannello impostato per crescere, l\u2019immagine continuava a zoomare e scivolare per un terzo di secondo DOPO che avevi lasciato \u2014 peggio al massimo, dove restava pendente tutta la crescita. Ora il pannello cresce di nuovo sotto le dita, ma il frame del player non si muove mai: la crescita \xe8 piegata dentro lo zoom stesso. Con la modalit\xe0 debug accesa, una pinch scrive una riga di traccia da rimandare indietro.','L\u2019app dice anche molto meno all\u2019hub: due diagnostiche facevano il 72% di tutto ci\xf2 che spediva \u2014 una di queste rilogga ogni tessera due volte solo per essere rimasta ferma mentre lo snapshot invecchiava.']}},{version:'1.0.478',date:'2026-09-09',notes:{en:['Pinch-zoom on the live view is smooth again. The picture box no longer resizes under your fingers frame by frame \u2014 it settles once, after you let go \u2014 the pan no longer springs back at the end of a gesture, and the double tap now runs on the UI thread instead of queueing behind the screen. The gesture feels slightly different on purpose: the panel grows after the pinch, not during it.'],it:['Lo zoom a pinch sulla vista live \xe8 di nuovo fluido. Il riquadro dell\u2019immagine non si ridimensiona pi\xf9 sotto le dita frame per frame \u2014 si assesta una volta sola, dopo che hai lasciato \u2014 la panoramica non torna pi\xf9 indietro a fine gesto, e il doppio tap gira sul thread della UI invece di accodarsi dietro allo schermo. Il gesto si sente un po\u2019 diverso di proposito: il pannello cresce dopo la pinch, non durante.']}},{version:'1.0.477',date:'2026-09-08',notes:{en:['The debug note\u2019s preset reasons now come from the notes actually written, not from guesswork: \u201ctrack started late\u201d leads, the thumbnail entry is reworded as \u201ca better frame existed (face/plate)\u201d \u2014 which is what gets typed by hand every time \u2014 and three reasons that were being typed out are now checkboxes: last frame before the first, two subjects in one track, and a two-wheeler whose rider is outside the keyframe.'],it:['Le ragioni preset della nota di debug ora vengono dalle note davvero scritte, non da supposizioni: \u201ctraccia partita in ritardo\u201d \xe8 la prima, la voce sulla miniatura diventa \u201cc\u2019era un frame migliore (volto/targa)\u201d \u2014 che \xe8 quello che viene digitato ogni volta \u2014 e tre ragioni che venivano scritte a mano sono ora caselle: ultimo frame prima del primo, due soggetti nella stessa traccia, e il conducente di un due ruote fuori dal keyframe.']}},{version:'1.0.476',date:'2026-09-08',notes:{en:['Closing the keyboard in the note dialog is the keyboard\u2019s own button now: on iOS a Done bar sits docked to it, drawn by the system above the keys, instead of a button crowding the card.'],it:['Chiudere la tastiera nel dialogo della nota ora \xe8 un pulsante della tastiera stessa: su iOS una barra Fatto le sta agganciata, disegnata dal sistema sopra i tasti, invece di un pulsante che toglie spazio alla scheda.']}},{version:'1.0.475',date:'2026-09-08',notes:{en:['The note dialog was a trap with the keyboard up: its buttons sat behind it, a multiline field has no return key, and tapping outside threw the note away. The card now lifts above the keyboard, a tap outside closes the keyboard first, and there is a Close keyboard button while it is open.'],it:['Il dialogo della nota era una trappola con la tastiera aperta: i pulsanti restavano dietro, un campo multiriga non ha tasto invio, e toccare fuori buttava via la nota. Ora la scheda si solleva sopra la tastiera, un tocco fuori chiude prima la tastiera, e c\u2019\xe8 un pulsante Chiudi tastiera finch\xe9 \xe8 aperta.']}},{version:'1.0.474',date:'2026-09-08',notes:{en:['On a Mac the player still opened the embed page in a browser: the WebView declines that load without reporting an error, so the previous fallback had nothing to react to. The player now watches for silence \u2014 if the bundled page has not spoken within six seconds, it loads the same page from the hub.'],it:['Su Mac il player apriva ancora la pagina dell\u2019embed nel browser: la WebView rifiuta quel caricamento senza segnalare alcun errore, quindi il fallback precedente non aveva nulla a cui reagire. Ora il player sorveglia il silenzio \u2014 se la pagina inclusa non ha parlato entro sei secondi, carica la stessa pagina dall\u2019hub.']}},{version:'1.0.473',date:'2026-09-08',notes:{en:['A sample whose picture is gone now says so, instead of drawing an empty square. Most of the gallery is in that state today \u2014 the crops were lost before the panel existed \u2014 and the scores beside them are unaffected: they come from the stored vector, which is intact.'],it:['Un campione la cui immagine non c\u2019\xe8 pi\xf9 ora lo dice, invece di disegnare un quadrato vuoto. Oggi gran parte della galleria \xe8 in quello stato \u2014 i ritagli erano gi\xe0 andati persi prima che il pannello esistesse \u2014 e i punteggi accanto non ne risentono: vengono dal vettore memorizzato, che \xe8 intatto.']}},{version:'1.0.472',date:'2026-09-08',notes:{en:['Library \u2192 Review can re-analyse one person\u2019s enrolled samples. Worst first, each with its crop and the reason \u2014 \u201clooks like Matthias (61%) more than like this person (12%)\u201d \u2014 and a sample is flagged only when it could actually be auto-assigned to the other person. Remove is one tap, and nothing is removed for you.'],it:['Libreria \u2192 Revisione pu\xf2 rianalizzare i campioni di una persona. Peggiori in cima, ognuno col suo ritaglio e il motivo \u2014 \u201csomiglia a Matthias (61%) pi\xf9 che a questa persona (12%)\u201d \u2014 e un campione \xe8 segnalato solo se potrebbe davvero essere auto-assegnato all\u2019altra persona. Rimuovere \xe8 un tocco, e nessuno rimuove niente al posto tuo.']}},{version:'1.0.471',date:'2026-09-08',notes:{en:['Opening the Cameras page now refreshes every camera\u2019s thumbnail, two at a time, once \u2014 so the tiles below the fold are minutes old instead of hours. It stops when it has been round the list.','What\u2019s new is a panel now, not a one-line dialog: the build that just arrived is at the top, and every earlier update is listed under it by version and date, tap to open. Settings \u2192 Info opens the same panel.'],it:['Aprendo la pagina Telecamere ora si aggiorna la miniatura di ogni camera, due alla volta, una sola volta \u2014 cos\xec i riquadri sotto la piega sono vecchi di minuti e non di ore. Finito il giro, si ferma.','Le novit\xe0 sono un pannello, non pi\xf9 un avviso a una riga: in alto la build appena arrivata, sotto l\u2019elenco di tutti gli aggiornamenti precedenti per versione e data, che si aprono al tocco. Impostazioni \u2192 Info apre lo stesso pannello.']}},{version:'1.0.470',date:'2026-09-08',notes:{en:['The debug checkboxes changed with use: an edge crop that came back mirrored, and a box that does not match the path the track drew \u2014 which usually means two subjects ended up sharing one id. "Wrong class" and "audio-only" left; neither was what anyone was actually reporting.'],it:['Le caselle di debug sono cambiate con l\u2019uso: un ritaglio sul bordo tornato specchiato, e un box che non coincide col percorso disegnato dalla traccia \u2014 che di solito significa due soggetti finiti sullo stesso id. Sono uscite "classe sbagliata" e "solo audio": non era quello che si segnalava davvero.']}},{version:'1.0.469',date:'2026-09-08',notes:{en:['Marking an event for debug now offers the questions that keep coming back as checkboxes, so a mark carries a question without typing one. Ticking one writes its phrase into the note; the field below still takes anything the boxes cannot say.'],it:['Marcando un evento per il debug ora trovi come caselle le domande che ricorrono, cos\xec una marcatura porta con s\xe9 una domanda senza doverla scrivere. Spuntarne una scrive la sua frase nella nota; il campo sotto accetta ancora tutto ci\xf2 che le caselle non dicono.']}},{version:'1.0.468',date:'2026-09-08',notes:{en:['The privacy-mask switch now says what is actually missing: no privacy zone is drawn on the camera. It used to give the same general "nothing is set up yet" sentence as every other control, which left no next step \u2014 and the next step is on the camera, not in this app.'],it:["L'interruttore della maschera privacy ora dice cosa manca davvero: sulla telecamera non \xe8 disegnata nessuna zona di privacy. Prima dava la stessa frase generica di ogni altro controllo, che non indicava alcun passo successivo \u2014 e il passo successivo \xe8 sulla telecamera, non in questa app."]}},{version:'1.0.467',date:'2026-09-08',notes:{en:['Unticking every event kind used to leave invisible leftovers behind, so the list stayed empty and the counters disagreed with the boxes. The leftovers are cleared, and no ticks now means no constraint.','Ticking only Faces or Plates therefore works on its own, across every kind, while narrowing them with a kind still works as before.','A collapsed group now shows a partial mark when something inside it is ticked, so nothing can be on where you cannot see it.'],it:["Togliendo la spunta a tutti i tipi di evento restavano dietro dei residui invisibili, cos\xec la lista restava vuota e i contatori non coincidevano con le caselle. I residui vengono ripuliti, e nessuna spunta adesso vuol dire nessun vincolo.","Spuntare solo Volti o Targhe funziona quindi da solo, su tutti i tipi, mentre restringerli a un tipo continua a funzionare come prima.","Un gruppo chiuso mostra adesso un segno parziale quando qualcosa al suo interno \xe8 spuntato, cos\xec niente pu\xf2 essere attivo dove non lo vedi."]}},{version:'1.0.466',date:'2026-09-08',notes:{en:['A filter that matched nothing on the first page used to stop the list from loading any further, so a narrow choice looked empty even when matches existed further back. The list now keeps reading until it finds them.','Plates were the clearest case: they sat four pages deep and were never reached. Faces happened to match early, which is why the same defect looked intermittent.','An empty list now says which kind of empty it is, and offers to load older events instead of ending the road.'],it:["Un filtro che non trovava nulla nella prima pagina impediva alla lista di caricare oltre, cos\xec una scelta stretta sembrava vuota anche quando i risultati c'erano pi\xf9 indietro. Adesso la lista continua a leggere finch\xe9 li trova.","Le targhe erano il caso pi\xf9 evidente: stavano quattro pagine pi\xf9 in l\xe0 e non venivano mai raggiunte. I volti capitavano presto, ed \xe8 per questo che lo stesso difetto sembrava intermittente.","Una lista vuota adesso dice di che vuoto si tratta, e propone di caricare gli eventi pi\xf9 vecchi invece di finire l\xec."]}},{version:'1.0.465',date:'2026-09-08',notes:{en:['The event kinds you already had \u2014 Audio, Sensor, Control \u2014 now actually filter. Ticking one shows those events, unticking hides them; there is no second filter to find, because the tree you were already using is the one that works.','Audio events start unticked, so the list opens on what you look at. A Default button puts the preset back without re-ticking everything by hand.','The chip counts what you kept in the terms you picked it in, so a default that hides one thing reads as one thing hidden.'],it:["I tipi di evento che avevi gi\xe0 \u2014 Audio, Sensore, Controllo \u2014 adesso filtrano davvero. Spuntandone uno vedi quegli eventi, togliendo la spunta li nascondi, e non c'\xe8 un secondo filtro da cercare: quello che usavi \xe8 quello che funziona.","Gli eventi audio partono senza spunta, cos\xec la lista si apre su quello che guardi. Un pulsante Predefinito rimette il preset senza dover rispuntare tutto a mano.","Il contatore conta quello che hai tenuto nei termini in cui l'hai scelto, cos\xec un default che nasconde una cosa si legge come una cosa nascosta."]}},{version:'1.0.464',date:'2026-09-07',notes:{en:['The events page can now filter by where an event came from, and audio-only events start hidden. The filter sits in More with the others, and the chip counts it, so a shorter list always says why it is shorter.','Picking a class used to drag every sensor and audio event along with it, and picking a sensor selected nothing at all. Provenance is now its own axis, so both do what they say.','The Recent strip on the Cameras screen has its own filter, in the same fan menu, showing detections by default and remembering what you choose.'],it:["La pagina eventi ora filtra anche per provenienza, e gli eventi di solo audio partono nascosti. Il filtro sta in Altro insieme agli altri e il contatore lo conta, cos\xec una lista pi\xf9 corta dice sempre perch\xe9 lo \xe8.","Scegliere una classe si portava dietro ogni evento di sensore e di audio, e scegliere un sensore non selezionava nulla. La provenienza adesso \xe8 un asse suo, quindi entrambi fanno quello che dicono.","La striscia Recenti nella schermata Camere ha un filtro suo, nello stesso menu a ventaglio, che di default mostra le rilevazioni e ricorda quello che scegli."]}},{version:'1.0.463',date:'2026-09-07',notes:{en:['One record button, the same pair of buttons everywhere: press it, then Keep \u2014 with the duration on it \u2014 or Discard. On the live picture it records forward from now; on the recording it anchors a period you draw with the scrub, in either direction.','Pressing it during playback no longer reports that the live view cannot be recorded, and the period you draw stops at the live edge instead of losing itself there.','While you are drawing a period the timeline no longer buzzes at every step: the notch feedback belongs to looking for an event, not to choosing a moment.'],it:["Un solo pulsante di registrazione, e la stessa coppia di pulsanti ovunque: premi, poi Salva \u2014 con la durata sopra \u2014 oppure Scarta. Sull'immagine live registra da adesso in avanti; sul registrato fissa un periodo che disegni con lo scorrimento, in entrambe le direzioni.","Premendolo durante la riproduzione non dice pi\xf9 che non pu\xf2 registrare la vista live, e il periodo che stai disegnando si ferma al bordo live invece di perdersi.","Mentre disegni un periodo la timeline non vibra pi\xf9 a ogni passo: lo scatto delle tacche serve a cercare un evento, non a scegliere un momento."]}},{version:'1.0.462',date:'2026-09-07',notes:{en:['Save a stretch of the recording from the timeline: press the record button during playback to anchor the period, scrub to the other end, then Save or Discard. The selected period is highlighted on the strip.','While you are choosing, the recording does not play \u2014 you see the frame you scrubbed to. Nothing is created on the hub until you press Save, and a period that crosses a stretch with no recording says so before it is exported.'],it:["Salva un tratto di registrato dalla timeline: durante la riproduzione premi il pulsante di registrazione per fissare il periodo, scorri fino all'altro estremo, poi Salva o Scarta. Il periodo selezionato \xe8 evidenziato sulla striscia.","Mentre scegli la registrazione non parte: vedi il fotogramma su cui ti sei fermato. Sull'hub non viene creato nulla finch\xe9 non premi Salva, e un periodo che attraversa un tratto senza registrazione lo dice prima di esportare."]}},{version:'1.0.461',date:'2026-09-07',notes:{en:['A host with nowhere to show a tile\'s linked-devices and view-options panels can now say so, and the embed stops drawing two buttons that would do nothing.'],it:["Un ospite che non ha dove mostrare i pannelli dispositivi collegati e opzioni di vista pu\xf2 dirlo, e l'embed smette di disegnare due pulsanti che non farebbero nulla."]}},{version:'1.0.460',date:'2026-09-06',notes:{en:['Battery and signal icons are now buttons: tapping one opens the figures \u2014 charge, power source, sleeping, link type, signal and Wi-Fi network \u2014 on the stream and in the cameras list.','What the camera does not report is said in words, never as a fabricated 0%.'],it:["Le icone di batteria e segnale sono diventate pulsanti: toccandone una si aprono i numeri \u2014 carica, alimentazione, sospensione, tipo di collegamento, segnale e rete Wi-Fi \u2014 sullo stream e nella lista camere.","Ci\xf2 che la camera non riporta viene detto a parole, mai come uno 0% inventato."]}},{version:'1.0.459',date:'2026-09-06',notes:{en:['Home Assistant cards: the embed no longer needs a viewing token in the page \u2014 Home Assistant carries it, and the events card URL stops carrying a credential.'],it:["Card di Home Assistant: l'embed non ha pi\xf9 bisogno del token nella pagina, lo porta Home Assistant, e l'URL della card eventi smette di trasportare una credenziale."]}},{version:'1.0.458',date:'2026-09-06',notes:{en:['Robot camera in landscape: with the timeline open the drive buttons move onto the visible picture and shrink to fit; the "\u2026" is gone there, the timeline has its own.'],it:['Camera del robot in landscape: con la timeline aperta i pulsanti di guida passano sul video visibile e si rimpiccioliscono; l\xec sparisce il "\u2026", la timeline ha gi\xe0 il suo.']}},{version:'1.0.457',date:'2026-09-06',notes:{en:['A restart for an update waits for the snapshot downloads in flight \u2014 the crash right after an update on build 16.'],it:['Il riavvio per un aggiornamento aspetta i download degli snapshot in corso: il crash subito dopo un aggiornamento sulla build 16.']}},{version:'1.0.456',date:'2026-09-06',notes:{en:['An OTA update asks before restarting the app.','A newer TestFlight / store build is announced, with a button to open it.',"What's new: these notes, once per version and in Settings \u2192 Info."],it:["Un aggiornamento OTA chiede conferma prima di riavviare l'app.",'Una build TestFlight / Store pi\xf9 recente viene segnalata, con il pulsante per aprirla.','Novit\xe0: queste note, una volta per versione e in Impostazioni \u2192 Info.']}},{version:'1.0.455',date:'2026-09-06',notes:{en:['Robot camera: a drive joystick in landscape, with Stop, light, Follow me and Return to dock.','The controls button opens for robot cameras too.','Battery and signal are glyphs in the toolbar; the day arrows fold on a narrow row.','A sleeping camera shows the moon in its name chip.'],it:['Camera del robot: joystick di guida in landscape, con Stop, luce, Seguimi e Torna alla base.','Il pulsante dei controlli si apre anche per le camere del robot.','Batteria e segnale sono glifi nella toolbar; le frecce del giorno si ripiegano su riga stretta.','Una camera dormiente mostra la luna nel chip del nome.']}}];function o(o){return o?e.find(e=>e.version===o)??null:null}},2130,[]);
|
|
3590
3590
|
__d(function(g,r,i,a,m,_e,d){"use strict";function e(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(_e,'__esModule',{value:!0}),_e.WhatsNewModal=function(e){const o=(0,t.c)(50),{visible:h,latest:b,past:x,onClose:S}=e,{t:I,i18n:A}=(0,p.useTranslation)(),{colors:G}=(0,y.useTheme)(),w=A.language;let M,T,R,D,z,k,H,W,_,L,V,B,E,U,F,q;o[0]!==I?(M=I("v2.common.close"),o[0]=I,o[1]=M):M=o[1];o[2]!==S||o[3]!==M?(T=(0,C.jsx)(n.default,{style:u.default.absoluteFill,accessibilityRole:"button",accessibilityLabel:M,onPress:S}),o[2]=S,o[3]=M,o[4]=T):T=o[4];o[5]!==G.backgroundElevated||o[6]!==G.border?(R=[P.card,{backgroundColor:G.backgroundElevated,borderColor:G.border}],o[5]=G.backgroundElevated,o[6]=G.border,o[7]=R):R=o[7];o[8]!==G.foreground?(D=[P.title,{color:G.foreground}],o[8]=G.foreground,o[9]=D):D=o[9];o[10]!==I?(z=I("v2.updates.whatsNewHeading"),o[10]=I,o[11]=z):z=o[11];o[12]!==D||o[13]!==z?(k=(0,C.jsx)(c.default,{style:D,children:z}),o[12]=D,o[13]=z,o[14]=k):k=o[14];o[15]!==G.foregroundMuted||o[16]!==G.primary||o[17]!==w||o[18]!==b?(H=null!==b?(0,C.jsxs)(f.default,{style:[P.latest,{borderColor:G.primary}],children:[(0,C.jsxs)(f.default,{style:P.latestHeader,children:[(0,C.jsx)(c.default,{style:[P.latestVersion,{color:G.primary}],children:b.version}),(0,C.jsx)(c.default,{style:[P.pastDate,{color:G.foregroundMuted}],children:j(b.date,w)})]}),(0,C.jsx)(N,{entry:b,language:w})]}):null,o[15]=G.foregroundMuted,o[16]=G.primary,o[17]=w,o[18]=b,o[19]=H):H=o[19];o[20]!==G.foregroundMuted||o[21]!==w||o[22]!==x||o[23]!==I?(W=x.length>0?(0,C.jsxs)(C.Fragment,{children:[(0,C.jsx)(c.default,{style:[P.pastTitle,{color:G.foregroundMuted}],children:I("v2.updates.whatsNewPrevious")}),x.map(e=>(0,C.jsx)(v,{entry:e,language:w},e.version))]}):null,o[20]=G.foregroundMuted,o[21]=w,o[22]=x,o[23]=I,o[24]=W):W=o[24];o[25]!==H||o[26]!==W?(_=(0,C.jsxs)(s.default,{style:P.scroll,contentContainerStyle:P.scrollContent,children:[H,W]}),o[25]=H,o[26]=W,o[27]=_):_=o[27];o[28]!==G.primary?(L=[P.close,{backgroundColor:G.primary}],o[28]=G.primary,o[29]=L):L=o[29];o[30]!==I?(V=I("v2.common.ok"),o[30]=I,o[31]=V):V=o[31];o[32]!==V?(B=(0,C.jsx)(c.default,{style:P.closeLabel,children:V}),o[32]=V,o[33]=B):B=o[33];o[34]!==S||o[35]!==L||o[36]!==B?(E=(0,C.jsx)(n.default,{accessibilityRole:"button",onPress:S,style:L,children:B}),o[34]=S,o[35]=L,o[36]=B,o[37]=E):E=o[37];o[38]!==E||o[39]!==R||o[40]!==k||o[41]!==_?(U=(0,C.jsxs)(f.default,{style:R,children:[k,_,E]}),o[38]=E,o[39]=R,o[40]=k,o[41]=_,o[42]=U):U=o[42];o[43]!==U||o[44]!==T?(F=(0,C.jsxs)(f.default,{style:P.backdrop,children:[T,U]}),o[43]=U,o[44]=T,o[45]=F):F=o[45];o[46]!==S||o[47]!==F||o[48]!==h?(q=(0,C.jsx)(l.default,{visible:h,transparent:!0,animationType:"fade",onRequestClose:S,children:F}),o[46]=S,o[47]=F,o[48]=h,o[49]=q):q=o[49];return q};var t=r(d[0]),o=r(d[1]),l=e(r(d[2])),n=e(r(d[3])),s=e(r(d[4])),u=e(r(d[5])),c=e(r(d[6])),f=e(r(d[7])),p=r(d[8]),h=r(d[9]),b=r(d[10]),y=r(d[11]),x=r(d[12]),S=r(d[13]),C=r(d[14]);function j(e,t){const o=new Date(e);return Number.isNaN(o.getTime())?e:o.toLocaleDateString(t,{day:'numeric',month:'short',year:'numeric'})}function N(e){const o=(0,t.c)(8),{entry:l,language:n}=e,{colors:s}=(0,y.useTheme)();let u,p;if(o[0]!==s||o[1]!==l||o[2]!==n){let e;o[4]!==s?(e=e=>(0,C.jsxs)(f.default,{style:P.note,children:[(0,C.jsx)(c.default,{style:[P.bullet,{color:s.primary}],children:"\u2022"}),(0,C.jsx)(c.default,{style:[P.noteText,{color:s.foreground}],children:e})]},e),o[4]=s,o[5]=e):e=o[5],u=(0,S.whatsNewLines)(l,n).map(e),o[0]=s,o[1]=l,o[2]=n,o[3]=u}else u=o[3];return o[6]!==u?(p=(0,C.jsx)(f.default,{style:P.notes,children:u}),o[6]=u,o[7]=p):p=o[7],p}function v(e){const l=(0,t.c)(35),{entry:s,language:u}=e,{colors:p}=(0,y.useTheme)(),[x,S]=(0,o.useState)(!1),v=x?h.ChevronDown:h.ChevronRight;let A,G;l[0]!==p.border?(A=[P.pastRow,{borderColor:p.border}],l[0]=p.border,l[1]=A):A=l[1],l[2]!==x?(G={expanded:x},l[2]=x,l[3]=G):G=l[3];const w=s.version;let M,T,R,D,z,k,H,W,_,L;return l[4]===Symbol.for("react.memo_cache_sentinel")?(M=()=>{(0,b.hapticTap)(),S(I)},l[4]=M):M=l[4],l[5]!==v||l[6]!==p.foregroundMuted?(T=(0,C.jsx)(v,{size:14,color:p.foregroundMuted}),l[5]=v,l[6]=p.foregroundMuted,l[7]=T):T=l[7],l[8]!==p.foreground?(R=[P.pastVersion,{color:p.foreground}],l[8]=p.foreground,l[9]=R):R=l[9],l[10]!==s.version||l[11]!==R?(D=(0,C.jsx)(c.default,{style:R,children:s.version}),l[10]=s.version,l[11]=R,l[12]=D):D=l[12],l[13]!==p.foregroundMuted?(z=[P.pastDate,{color:p.foregroundMuted}],l[13]=p.foregroundMuted,l[14]=z):z=l[14],l[15]!==s.date||l[16]!==u?(k=j(s.date,u),l[15]=s.date,l[16]=u,l[17]=k):k=l[17],l[18]!==z||l[19]!==k?(H=(0,C.jsx)(c.default,{style:z,children:k}),l[18]=z,l[19]=k,l[20]=H):H=l[20],l[21]!==s.version||l[22]!==H||l[23]!==G||l[24]!==T||l[25]!==D?(W=(0,C.jsxs)(n.default,{accessibilityRole:"button",accessibilityState:G,accessibilityLabel:w,onPress:M,style:P.pastHeader,children:[T,D,H]}),l[21]=s.version,l[22]=H,l[23]=G,l[24]=T,l[25]=D,l[26]=W):W=l[26],l[27]!==s||l[28]!==u||l[29]!==x?(_=x?(0,C.jsx)(N,{entry:s,language:u}):null,l[27]=s,l[28]=u,l[29]=x,l[30]=_):_=l[30],l[31]!==A||l[32]!==W||l[33]!==_?(L=(0,C.jsxs)(f.default,{style:A,children:[W,_]}),l[31]=A,l[32]=W,l[33]=_,l[34]=L):L=l[34],L}function I(e){return!e}const P=u.default.create({backdrop:{flex:1,alignItems:'center',justifyContent:'center',padding:x.SPACING.lg,backgroundColor:'rgba(0,0,0,0.5)'},card:{width:'100%',maxWidth:460,maxHeight:'80%',borderWidth:1,borderRadius:x.RADIUS.lg,padding:x.SPACING.lg},title:{fontSize:16,fontWeight:'600',marginBottom:x.SPACING.md},scroll:{flexGrow:0},scrollContent:{paddingBottom:x.SPACING.sm},latest:{borderWidth:1,borderRadius:x.RADIUS.md,padding:x.SPACING.md,marginBottom:x.SPACING.lg},latestHeader:{flexDirection:'row',alignItems:'baseline',gap:x.SPACING.sm},latestVersion:{fontSize:15,fontWeight:'700'},notes:{marginTop:x.SPACING.sm,gap:x.SPACING.xs},note:{flexDirection:'row',gap:x.SPACING.xs},bullet:{fontSize:13,lineHeight:19},noteText:{flex:1,fontSize:13,lineHeight:19},pastTitle:{fontSize:11,textTransform:'uppercase',letterSpacing:.6,marginBottom:x.SPACING.xs},pastRow:{borderTopWidth:1,paddingVertical:x.SPACING.sm},pastHeader:{flexDirection:'row',alignItems:'center',gap:x.SPACING.sm},pastVersion:{fontSize:13,fontWeight:'600'},pastDate:{fontSize:11},close:{marginTop:x.SPACING.md,alignSelf:'flex-end',paddingHorizontal:x.SPACING.lg,paddingVertical:x.SPACING.sm,borderRadius:x.RADIUS.md},closeLabel:{color:'#fff',fontSize:13,fontWeight:'600'}})},2131,[15,17,245,252,143,33,198,20,1009,796,1036,782,790,2130,10]);
|
|
3591
3591
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.useNativeRelease=function(){const c=(0,t.c)(8),{server:o}=(0,s.useServer)(),v=o?.serverUrl??null;let f;c[0]!==v?(f=["v2","native-release",v],c[0]=v,c[1]=f):f=c[1];const y=!1;let _,h;c[2]!==v?(_=async()=>{if(null===v)return null;const t=await fetch((0,l.nativeReleasePath)(v),{cache:"no-store"});if(!t.ok)return null;const n=await t.json();return(0,l.isNativeRelease)(n)?n:null},c[2]=v,c[3]=_):_=c[3];c[4]!==f||c[5]!==y||c[6]!==_?(h={queryKey:f,enabled:y,staleTime:u,queryFn:_},c[4]=f,c[5]=y,c[6]=_,c[7]=h):h=c[7];return(0,n.useQuery)(h)};var t=r(d[0]),n=r(d[1]);r(d[2]);var s=r(d[3]),l=r(d[4]);const u=36e5},2132,[15,1531,131,1592,2125]);
|
|
3592
3592
|
__d(function(g,r,i,a,m,_e,_d){"use strict";Object.defineProperty(_e,'__esModule',{value:!0}),Object.defineProperty(_e,"RELOAD_DRAIN_TIMEOUT_MS",{enumerable:!0,get:function(){return u}}),_e.reloadRuntimeForUpdate=async function(c){o.runtimeQuiesce.requestQuiesce();const s=o.runtimeQuiesce.inflight(),d=await o.runtimeQuiesce.waitForIdle(u);n.log.info('crash','restarting the runtime to apply an OTA update',{reason:c,inflight:s,drained:d}),await(0,t.getExitMarkerRecorder)().record('ota-reload'),await e.reloadAsync()};var e=(function(e){if(e&&e.__esModule)return e;var t={};return e&&Object.keys(e).forEach(function(n){var o=Object.getOwnPropertyDescriptor(e,n);Object.defineProperty(t,n,o.get?o:{enumerable:!0,get:function(){return e[n]}})}),t.default=e,t})(r(_d[0])),t=r(_d[1]),n=r(_d[2]),o=r(_d[3]);const u=4e3},2133,[2115,2129,1131,1617]);
|
|
@@ -3687,7 +3687,7 @@ __d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{v
|
|
|
3687
3687
|
__d(function(g,r,i,a,m,_e,_d){"use strict";function e(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(_e,'__esModule',{value:!0}),Object.defineProperty(_e,"TheaterTimeline",{enumerable:!0,get:function(){return ue}}),Object.defineProperty(_e,"TIMELINE_CHROME_TEST_ID",{enumerable:!0,get:function(){return me}});var n=r(_d[0]),o=e(r(_d[1])),t=e(r(_d[2])),s=r(_d[3]),l=r(_d[4]),c=r(_d[5]),d=r(_d[6]),u=r(_d[7]),p=r(_d[8]),h=r(_d[9]),v=r(_d[10]),f=r(_d[11]),k=r(_d[12]),y=r(_d[13]),M=r(_d[14]),b=r(_d[15]),S=r(_d[16]),C=r(_d[17]),I=r(_d[18]),T=r(_d[19]),E=r(_d[20]),w=r(_d[21]),x=r(_d[22]),D=r(_d[23]),L=r(_d[24]),B=r(_d[25]),P=r(_d[26]),O=r(_d[27]),F=r(_d[28]),R=r(_d[29]),A=r(_d[30]),z=r(_d[31]),_=r(_d[32]),N=r(_d[33]),H=r(_d[34]),j=r(_d[35]),W=r(_d[36]),K=r(_d[37]),q=r(_d[38]),G=r(_d[39]),Z=r(_d[40]),J=r(_d[41]),U=r(_d[42]),V=r(_d[43]),Y=r(_d[44]),Q=r(_d[45]),X=r(_d[46]),$=r(_d[47]),ee=r(_d[48]),ne=r(_d[49]),oe=r(_d[50]),te=r(_d[51]),ie=r(_d[52]),ae=r(_d[53]),se=r(_d[54]),le=r(_d[55]),re=r(_d[56]),ce=r(_d[57]);const de=864e5,ue=(0,n.memo)(function(e){const{t:t}=(0,d.useTranslation)(),{colors:ue}=(0,p.useTheme)(),ye=(0,u.useSafeAreaInsets)(),[Me,be]=(0,n.useState)(()=>Date.now());(0,n.useEffect)(()=>{const e=setInterval(()=>be(Date.now()),1e3);return()=>clearInterval(e)},[]);const Se=(0,Y.useSettings)().settings.clusters,Ce=(0,Y.useSettings)().settings.stream.toolbarDensity,[Ie,Te]=(0,n.useState)(w.DEFAULT_ZOOM_INDEX),Ee=(0,n.useCallback)(e=>Te((0,w.clampZoomIndex)(e)),[]),[we,xe]=(0,n.useState)(!1),[De,Le]=(0,n.useState)(null),Be=(0,n.useCallback)(()=>{xe(e=>!e),Le(null)},[]),Pe=(0,E.useTimelinePanels)(),{panel:Oe,body:Fe,close:Re}=Pe,Ae=Pe.toggle,ze=(0,n.useCallback)(()=>Ae('filter'),[Ae]),Ne=(0,n.useCallback)(()=>Ae('viewOptions'),[Ae]),He=(0,n.useCallback)(()=>Ae('linkedDevices'),[Ae]),je=(0,n.useCallback)(()=>Ae('ptz'),[Ae]),We=(0,n.useCallback)(()=>Ae('legend'),[Ae]),[Ke,qe]=(0,n.useState)(!1),Ge=(0,n.useCallback)(()=>qe(e=>!e),[]),Ze=(0,n.useMemo)(()=>b.QUALITY_ORDER.map(e=>({value:e,label:t((0,b.qualityLabelKey)(e))})),[t]),Je=e.singleCamera,Ue=(0,n.useCallback)(e=>{const n=b.QUALITY_ORDER.find(n=>n===e);n&&Je?.streamBinding.onSelectQuality(n),qe(!1)},[Je]),Ve=(0,n.useCallback)(()=>Ae('cameraSwitcher'),[Ae]),Ye=!(0,P.useTabletViewport)()&&void 0!==e.deviceBinding.cameraJump,Qe=Pe.open,Xe=(0,n.useCallback)(()=>Qe('storage'),[Qe]),$e=(0,n.useCallback)(()=>Qe('eventStore'),[Qe]),en=(0,n.useCallback)(()=>Qe('viewOptions'),[Qe]);(0,n.useImperativeHandle)(e.ref,()=>({openControls:()=>Qe('ptz')}),[Qe]);const nn=(0,n.useRef)(0),on=(0,n.useCallback)(e=>{nn.current=e},[]),[tn,an]=(0,n.useState)(0),[sn,ln]=(0,n.useState)(0),rn=(0,n.useCallback)(e=>{const{height:n,width:o}=e.nativeEvent.layout;n>0&&an(n),o>0&&ln(o)},[]),cn=(0,n.useMemo)(()=>(0,L.indicatorOffsetPx)(tn,L.FIXED_INDICATOR_POSITION_PCT),[tn]),dn=(0,_.scopeIdsKey)(e.scopeIds??[]),un=(0,n.useMemo)(()=>(0,z.initTimelineScope)((0,_.idsFromScopeKey)(dn),e.deviceId),[dn,e.deviceId]),mn=(0,S.useTimelineFilter)(e.deviceId),{filter:pn,classFilter:gn,filterAll:hn,classToMacro:vn}=mn,fn=Je?.zone,kn=fn?.zoneRect??null,yn=Me,Mn=(0,n.useMemo)(()=>(0,x.layoutAnchorMs)(Me,Ie),[Me,Ie]),bn='live'===e.mode&&null===e.activeEpoch,Sn=e.activeEpoch??Me,Cn=(0,n.useMemo)(()=>(0,D.localDayWindow)(Sn).fromMs,[Sn]),In=(0,n.useMemo)(()=>({from:Cn,to:Cn+de}),[Cn]),[Tn,En]=(0,n.useState)(1),wn=Cn-(Tn-1)*de,xn=(0,n.useCallback)(()=>En(e=>Math.min(30,e+1)),[]),Dn=(0,n.useRef)(Cn);(0,n.useEffect)(()=>{(0,q.isSettledDayChange)({mode:e.mode,previousSettledDayFrom:Dn.current,nextDayFrom:Cn})&&En(e=>(0,q.nextLookbackDaysAfterDayChange)({previousDayFrom:Dn.current,previousLookbackDays:e,nextDayFrom:Cn,dayMs:de,maxLookbackDays:30})),'seeking'!==e.mode&&(Dn.current=Cn)},[Cn,e.mode]);const Ln=(0,n.useMemo)(()=>{const e=new Date(Me);return e.setHours(0,0,0,0),e.getTime()},[Me]),[Bn,Pn]=(0,n.useState)(Cn),{fromMs:On,toMs:Fn}=(0,n.useMemo)(()=>(0,U.monthBoundsForMs)(Bn),[Bn]),Rn=(0,A.useDaysWithRecordings)(un,On,Fn,'date'===Oe?.kind),An=Rn.data?.days,zn=e.onSeek,_n=(0,n.useCallback)(()=>{zn((0,V.dayAtSameTime)(Sn,Cn-de,Me),'timeline')},[zn,Sn,Cn,Me]),Nn=(0,n.useCallback)(()=>{Cn>=Ln||zn((0,V.dayAtSameTime)(Sn,Cn+de,Me),'timeline')},[zn,Sn,Cn,Ln,Me]),Hn=(0,n.useCallback)(()=>{Pn(Cn),Ae('date')},[Cn,Ae]),jn=(0,n.useCallback)(e=>{Re(),zn((0,V.dayAtSameTime)(Sn,e,Me),'timeline')},[Re,zn,Sn,Me]),Wn=(0,n.useCallback)(e=>{Re(),zn(e,'timeline')},[Re,zn]),Kn=(0,n.useCallback)(e=>{Pn(n=>{const o=new Date(n);return new Date(o.getFullYear(),o.getMonth()+e,1,0,0,0,0).getTime()})},[]),qn=e.activeEpoch,Gn=!0===e.chromeHidden,Zn=(0,O.useTimelineDeferral)(e.loading)&&!Gn,{state:Jn}=(0,ee.useConnection)(),Un=(0,n.useMemo)(()=>(0,J.expandSelectionToServerClasses)(gn,vn),[gn,vn]),Vn='summaries'===Se.subjectView,Yn=(0,Q.useDeviceTracks)(un,wn,In.to,Zn&&!Vn,kn,{pollLive:'live'===e.mode,classes:Un}),Qn=(0,X.useDeviceSummaries)((0,_.scopeToIds)(un),wn,In.to,Zn&&Vn,{pollLive:'live'===e.mode}),Xn=Yn.data??pe,$n=Qn.data??pe,eo=Yn.refetch,no=Qn.refetch,oo=Vn?$n:Xn,to=(0,n.useMemo)(()=>{const e=new Set;for(const n of oo)n.className.length>0&&e.add(n.className);return[...(0,J.collapseToMacro)([...e],vn)].sort()},[oo,vn]),io=(0,n.useMemo)(()=>(0,Z.filterEventsByZone)(oo,kn),[oo,kn]),ao=(0,n.useMemo)(()=>Vn?io:(0,G.filterDetectionsByKind)(io,pn,gn,vn),[Vn,io,pn,gn,vn]),so=(0,te.useTimelineActivity)(un,wn,In.to,Zn),lo=so.activity,ro=(0,n.useMemo)(()=>sn>0?Math.round(sn*Se.cardWidthFraction):0,[sn,Se.cardWidthFraction]),co=(0,n.useMemo)(()=>ro>0?Math.round(.5625*ro):0,[ro]),{sizePx:uo,gapPx:mo}=(0,n.useMemo)(()=>{const e=Math.max(8,co);return{sizePx:e,gapPx:Se.gapPercent/100*e}},[co,Se.gapPercent]),po=(0,n.useMemo)(()=>(0,ie.clusterByZoom)(ao,{topMs:Mn,zoomIndex:Ie,sizePx:uo,gapPx:mo}),[ao,Mn,Ie,uo,mo]),go=(0,n.useMemo)(()=>we?(0,ae.deriveClipsFromClusters)({clusters:po,recording:lo.recording,deviceId:e.deviceId}):ge,[we,po,lo.recording,e.deviceId]),ho=(0,n.useMemo)(()=>(0,ae.clipStartByCardId)(go),[go]),vo=(0,n.useMemo)(()=>(0,ae.clipEndByCardId)(go),[go]),fo=(0,n.useMemo)(()=>go.map(e=>e.clip),[go]),ko=(0,n.useMemo)(()=>we?(0,se.buildClipAxis)(fo,{topMs:Mn,sizePx:uo,gapPx:mo,minGapMs:2e3}):null,[we,fo,Mn,uo,mo]),yo=(0,n.useMemo)(()=>null!==ko?(0,ae.positionDerivedClips)(ko,go):po,[ko,go,po]),Mo=(0,n.useMemo)(()=>null===ko?null:{epochToOffset:e=>(0,se.clipAxisEpochToOffset)(ko,e),offsetToEpoch:e=>(0,se.clipAxisOffsetToEpoch)(ko,yn,e),contentSpanPx:ko.contentSpanPx},[ko,yn]),bo=(0,n.useMemo)(()=>{if(null!==ko)return ko.slots.filter(e=>'gap'===e.kind&&e.durationMs>=2e3).map(e=>({topPx:e.topPx,heightPx:e.heightPx,durationMs:e.durationMs}))},[ko]),So=(0,n.useMemo)(()=>{if(null!==ko)return(0,se.clipAxisTicks)(ko,{targetSpacingPx:w.TIMELINE_ROW_HEIGHT})},[ko]),Co='live'===e.mode||null===e.activeEpoch?null:e.activeEpoch,Io=(0,n.useMemo)(()=>(0,re.buildExpansionMap)(yo,Co,Ie),[yo,Co,Ie]),To=(0,n.useRef)(Io);(0,re.expansionMapsEqual)(To.current,Io)||(To.current=Io);const Eo=To.current;(0,n.useEffect)(()=>{const n=nn.current,o=yo.filter(e=>e.topPx>=n-80-e.heightPx&&e.topPx<=n+tn+80).length,t=e=>new Date(e).toLocaleTimeString(),s=oo.map(e=>e.timestamp);K.log.info('theater:clusters','render state',{deviceId:e.deviceId,objectEvents:oo.length,objectEventRange:s.length>0?{first:t(Math.min(...s)),last:t(Math.max(...s))}:null,zone:null===kn?null:{kind:kn.kind,points:'polygon'===kn.kind?kn.points.length:4,kept:io.length,dropped:oo.length-io.length,frame:(0,Z.resolveFrameSize)(oo)},clusters:yo.length,visibleClusters:o,activity:{recording:lo.recording.length,motion:lo.motion.length,audio:lo.audio.length},geometry:{cardWidth:ro,viewportHeight:tn,listWrapWidth:sn,scrollOffsetY:n,sizePx:uo,gapPx:mo,zoomIndex:Ie},dayWindow:In})},[e.deviceId,oo,yo,kn,io,lo.recording.length,lo.motion.length,lo.audio.length,ro,tn,sn,uo,mo,Ie,In]);const wo=(0,A.useRecordingAvailability)(un,In.from,In.to,!Gn),xo=wo.data?.ranges??he,Do=(0,n.useMemo)(()=>({unknownIds:(0,N.unionUnknownIds)(wo.data?.unknownIds??ve,so.activity.unknownIds),overflowIds:(0,N.unionUnknownIds)(wo.data?.overflowIds??ve,so.activity.overflowIds)}),[wo.data?.unknownIds,wo.data?.overflowIds,so.activity.unknownIds,so.activity.overflowIds]),Lo=wo.refetch,Bo=so.refetch,{failed:Po,fetching:Oo,reason:Fo,onRetry:Ro}=e.streamFault,Ao=(0,n.useMemo)(()=>({stream:{failed:Po,fetching:Oo,reason:Fo},recordings:{failed:wo.isError||so.failed,fetching:wo.isFetching||so.fetching,reason:null},events:{failed:Vn?Qn.isError:Yn.isError,fetching:Vn?Qn.isFetching:Yn.isFetching,reason:null}}),[Po,Oo,Fo,wo.isError,wo.isFetching,so.failed,so.fetching,Vn,Qn.isError,Qn.isFetching,Yn.isError,Yn.isFetching]),[zo,_o]=(0,n.useState)([]),No=(0,n.useMemo)(()=>(0,ne.activeFaultSources)(Ao),[Ao]);(0,n.useEffect)(()=>{_o(e=>(0,ne.pruneDismissals)(e,No))},[No]);const Ho=(0,n.useMemo)(()=>(0,ne.resolveTimelineFaults)({connected:'connected'===Jn,sources:Ao,dismissed:zo}),[Jn,Ao,zo]),jo=(0,oe.resolveRecordingDaysStatus)({connected:'connected'===Jn,failed:Rn.isError,fetching:Rn.isFetching,unknownCameras:Rn.data?.unknownIds.length??0}),Wo=(0,n.useCallback)(e=>{if('stream'!==e)return'recordings'===e?(Lo(),void Bo()):void(Vn?no():eo());Ro()},[Ro,Lo,Bo,eo,Vn,no]),Ko=(0,n.useCallback)(e=>{_o(n=>n.includes(e)?n:[...n,e])},[]),qo=(0,n.useMemo)(()=>{const n=e.activeEpoch;return null===n?(0,w.heatmapCursorFraction)(Me):(0,D.epochToDayFraction)(n,In.from,In.to)},[e.activeEpoch,In,Me]),Go=e.onScrubBegin,Zo=e.onScrubCommit,Jo=e.onGoLive,Uo=(0,n.useRef)(R.DETENT_INITIAL),Vo=null!=e.exportSelection?.anchorMs,Yo=(0,n.useRef)(Vo),Qo=(0,n.useRef)(yo),Xo=(0,n.useRef)(Ie);(0,n.useEffect)(()=>{Yo.current=Vo},[Vo]),(0,n.useEffect)(()=>{Qo.current=yo},[yo]),(0,n.useEffect)(()=>{Xo.current=Ie},[Ie]);const $o=e.onScrubMove,et=(0,n.useCallback)((e,n,o)=>{const t=(0,R.resolveDetent)(Uo.current,(0,R.detentKeyWhileScrubbing)(Yo.current,()=>(0,re.nearestClusterId)(Qo.current,e,Xo.current)),Date.now());Uo.current=t.state,t.tick&&(0,F.hapticDetent)(),$o(e,n,o)},[$o]),nt=(0,n.useCallback)(e=>{(0,F.hapticTap)(),Uo.current={key:null,lastTickMs:Date.now()},Go(e)},[Go]),ot=(0,n.useCallback)((e,n)=>{(0,F.hapticTap)(),Zo(e,n)},[Zo]),tt=(0,n.useCallback)(()=>{(0,F.hapticTap)(),Jo()},[Jo]),it=(0,B.useTimelineScrub)({deviceId:e.deviceId,topMs:yn,zoomIndex:Ie,isLive:bn,selectionArmed:Vo,indicatorPx:cn,viewportHeight:tn,timelineFromMs:wn,lookbackDays:Tn,maxLookbackDays:30,onScrubBegin:nt,onScrubMove:et,onScrubCommit:ot,onGoLive:tt,onScrollOffset:on,onExtendLookback:xn,epochMap:Mo}),at=it.scrollListTo,st=e.onGoLive,lt=(0,n.useCallback)(()=>{at(0,!0),st()},[st,at]),rt=e.mode;(0,n.useEffect)(()=>{'playback'===rt&&null!==qn&&at((0,x.mappedEpochToOffset)(qn,yn,Ie,Mo),!1)},[rt,qn,yn,Ie,at,Mo]);const ct=null!==Mo,dt=(0,n.useRef)(ct);(0,n.useEffect)(()=>{dt.current!==ct&&(dt.current=ct,at((0,x.mappedEpochToOffset)(qn??yn,yn,Ie,Mo),!1))},[ct,qn,yn,Ie,Mo,at]);const ut=(0,n.useRef)(go);(0,n.useEffect)(()=>{ut.current=go},[go]);const mt=(0,n.useCallback)((e,n)=>{const o=we?(0,ae.clipForCardId)(ut.current,n.id):null;if(null!==o)return Le(o.clipId),void zn(o.startMs,'cluster');Le(null),zn(e.timestamp,'cluster')},[we,zn]),pt=Pe.openCluster,gt=(0,n.useCallback)(e=>{zn(e,'cluster'),Re()},[zn,Re]),ht=Be,vt=(0,n.useMemo)(()=>we?Object.assign({},le.EMPTY_RIBBON,{clips:(0,le.normalizeClips)(fo)}):le.EMPTY_RIBBON,[we,fo]),ft=e.onSeek;(0,n.useEffect)(()=>{if(!we)return;if(null!==e.seekAnchor)return;const n=(0,le.resolveClipAdvance)({layout:vt,currentClipId:De,playheadMs:e.activeEpoch,endGuardMs:le.DEFAULT_END_GUARD_MS});'advance'===n.kind?(Le(n.clip.clipId),ft(n.clip.startMs,'cluster')):'finished'===n.kind&&Le(null)},[we,vt,De,e.activeEpoch,e.seekAnchor,ft]);const kt=(0,n.useMemo)(()=>(0,$.resolveClipsStatus)({active:we,connected:'connected'===Jn,loading:(Vn?Qn.isLoading:Yn.isLoading)||so.loading,failed:(Vn?Qn.isError:Yn.isError)||so.failed,clipCount:fo.length}),[we,Jn,Vn,Qn.isLoading,Qn.isError,Yn.isLoading,Yn.isError,so.loading,so.failed,fo.length]),yt=(0,n.useMemo)(()=>({from:wn,to:In.to}),[wn,In.to]),Mt=e.deviceBinding.cameraJump,bt=Mt?.onSwitchCamera,St=Mt?.onOpenAdhocGrid,Ct=Mt?.cameraSelection,It=(0,n.useCallback)(e=>{Re(),bt?.(e)},[Re,bt]),Tt=(0,n.useCallback)(e=>{Re(),St?.(e)},[Re,St]),Et=(0,n.useMemo)(()=>void 0===Ct?void 0:{onSwitchCamera:It,onOpenAdhocGrid:Tt,cameraSelection:Ct},[It,Tt,Ct]),wt=(0,n.useCallback)(e=>'absent'!==(0,H.recordingKnownAt)(xo,In.from,In.to,e.representative.timestamp),[xo,In.from,In.to]),xt=e.exportSelection,Dt=(0,n.useMemo)(()=>(0,j.describeExportSelection)(xt?.anchorMs??null,e.activeEpoch,xo,In.from,In.to,Me),[xt?.anchorMs,e.activeEpoch,xo,In.from,In.to,Me]),Lt=e.liveCapture,Bt=(0,n.useMemo)(()=>(0,W.resolveRecordControl)(e.mode,Lt,xt,Dt),[e.mode,Lt,xt,Dt]),Pt=(0,n.useCallback)(e=>(0,D.dayFractionToEpoch)(e,In.from,In.to),[In.from,In.to]),Ot=e.onScrubBegin,Ft=e.onScrubMove,Rt=e.onScrubCommit,At=(0,n.useCallback)(e=>zn(Pt(e),'heatmap'),[Pt,zn]),zt=(0,n.useCallback)(()=>Ot('heatmap'),[Ot]),_t=(0,n.useCallback)(e=>Ft(Pt(e),'heatmap'),[Pt,Ft]),Nt=(0,n.useCallback)(e=>Rt(Pt(e),'heatmap'),[Pt,Rt]),Ht=hn||pn.has('motion'),jt=hn||pn.has('audio'),Wt=(0,n.useMemo)(()=>Ht?ao:[],[Ht,ao]),Kt=(0,n.useMemo)(()=>(0,G.composeHeatmapBins)({dayStartMs:Cn,detections:Wt,motion:Ht?lo.motion:[],audio:jt?lo.audio:[],classToMacro:vn}),[Wt,Cn,Ht,jt,lo.audio,lo.motion,vn]),qt=(0,n.useMemo)(()=>new Date(e.activeEpoch??Me).toLocaleTimeString(void 0,{hour:'2-digit',minute:'2-digit',second:'2-digit'}),[e.activeEpoch,Me]),Gt=e.layoutMode??'stack',Zt=e.railWidth??f.TIMELINE_RAIL_WIDTH_NARROW,{width:Jt}=(0,s.useViewportSize)(),{data:Ut=null}=(0,l.useBattery)(e.deviceId,e.deviceBinding.hasBattery),{data:Vt=null}=(0,c.useNetworkLink)(e.deviceId,e.deviceBinding.hasNetworkLink),Yt=(0,ce.jsx)(h.TimelineToolbarInline,{onBack:e.onBack,hideBack:e.hideBack,deviceId:e.deviceId,battery:Ut,networkLink:Vt,dateLabel:(0,V.dateLabel)(Cn,Me,t),onPrevDay:_n,onOpenDatePicker:Hn,onNextDay:Nn,nextDayDisabled:Cn>=Ln,menuOpen:'viewOptions'===Oe?.kind,onToggleMenu:Je?Ne:void 0,onOpenLinkedDevices:Je?He:void 0,linkedDevicesOpen:'linkedDevices'===Oe?.kind,onOpenPtz:Je&&(e.deviceBinding.hasPtz||e.deviceBinding.hasNavigation)?je:void 0,ptzOpen:'ptz'===Oe?.kind,qualityOpen:Ke,onToggleQuality:Je?Ge:void 0,qualityLabel:Je?t((0,b.qualityLabelKey)(Je.streamBinding.quality)):void 0,qualityOptions:Ze,qualityValue:Je?.streamBinding.quality,onSelectQuality:Ue,legendOpen:'legend'===Oe?.kind,onToggleLegend:We}),Qt='panel'===Fe.kind,Xt=(0,ce.jsxs)(o.default,{testID:me[Gn?'hidden':'shown'],style:[ke.bodyStack,Gn?ke.chromeHidden:null],children:[(0,ce.jsx)(o.default,{style:ke.bodyLayer,pointerEvents:Qt?'none':'auto',children:(0,ce.jsx)(I.FreezeWhileCovered,{frozen:Qt||Gn,children:(0,ce.jsx)(C.TimelineView,{onBodyLayout:rn,scrollerRef:it.scrollerRef,playback:{mode:e.mode,rate:e.playbackRate,paused:e.paused,servedTier:e.servedTier??null,loading:e.loading,faulted:Po,scrubDirection:e.scrubDirection,onTogglePause:e.onTogglePlayPause,onJogBack:e.onJogBack,onJogForward:e.onJogForward,onStepFrame:e.onStepFrame,onSelectRate:e.onSelectRate,onGoLive:lt,liveLocked:e.liveLocked,onToggleLiveLock:e.onToggleLiveLock,record:Bt},heatmap:{bins:Kt,cursorFraction:qo,coverage:xo,selection:Dt.armed&&null!==Dt.range?{startMs:Dt.range.fromMs,endMs:Dt.range.toMs}:null,unknownCameras:Do.unknownIds.length,dayStartMs:In.from,dayEndMs:In.to,onSeekFraction:At,onScrubStart:zt,onScrubFraction:_t,onScrubEnd:Nt},scroller:{topMs:Mn,zoomIndex:Ie,dayWindow:yt,clusters:yo,activity:lo,showMotionLane:Ht,showAudioLane:jt,cardWidth:ro,viewportHeight:tn,indicatorOffsetPx:cn,isLive:bn,onScroll:it.onScroll,onScrollBeginDrag:it.onScrollBeginDrag,onScrollEndDrag:it.onScrollEndDrag,onMomentumScrollBegin:it.onMomentumScrollBegin,onMomentumScrollEnd:it.onMomentumScrollEnd,onClusterPress:mt,onClusterOpenDetail:we?void 0:pt,expansion:Eo,clusterLabel:mn.clusterLabelMode,eventKinds:mn.eventKinds,epochMap:Mo,gapMarkers:bo,axisTicks:So,hideActivity:we,enableClusterActions:!we,clipStartByCardId:ho,clipEndByCardId:vo},faults:{faults:Ho,onRetry:Wo,onDismiss:Ko},history:{visible:!Vn&&Yn.hasMoreHistory,loading:Yn.isLoadingMoreHistory,onLoadMore:Yn.loadMoreHistory},scope:Do,clipsStatus:kt,indicator:{offsetPx:cn,measured:tn>0,isLive:bn,timeLabel:qt},footer:{zoomIndex:Ie,onZoomIndexChange:Ee,zoomEnabled:!we,onFilter:ze,onZoneFilter:fn?null!==kn?fn.onClearZone:fn.onRequestZoneDraw:void 0,onOpenClips:ht,onPickCamera:Ye?Ve:void 0,filterActive:mn.filterActive,zoneActive:null!==kn,clipsActive:we,bottomInset:ye.bottom}})})}),'panel'===Fe.kind?(0,ce.jsx)(o.default,{style:ke.panelLayer,children:(0,ce.jsx)(T.TimelineBodyPanel,{panel:Fe.panel,deviceId:e.deviceId,onClose:Pe.close,filterBinding:{filter:pn,onToggleKind:mn.onToggleKind,classes:to,classFilter:gn,onToggleClass:mn.onToggleClass,onSetClasses:mn.onSetClasses,onReset:mn.onReset,eventKinds:mn.eventKinds},dateBinding:{monthAnchorMs:Bn,selectedDayMs:Cn,daysSet:An??fe,daysStatus:jo,nowMs:Me,onChangeMonth:Kn,onPick:jn,onPickTime:Wn},clusterBinding:{onSeek:gt,seekAvailable:wt},deviceBinding:{cameraName:e.name,hasPtz:e.deviceBinding.hasPtz,hasBattery:e.deviceBinding.hasBattery,hasNetworkLink:e.deviceBinding.hasNetworkLink,hasNavigation:e.deviceBinding.hasNavigation,cameraJump:Et},singleCamera:Je,managementBinding:{onOpenStorage:Xe,onOpenEventStore:$e,onBackToViewOptions:en}})}):null]}),$t=!0===e.transparent||'fill'===Gt;return(0,ce.jsxs)(o.default,{testID:(0,y.detailShapeTestId)(Gt),style:[ke.container,'wide'===Gt?ke.wideRow:null,{backgroundColor:$t?'transparent':ue.background}],children:[(0,ce.jsx)(o.default,{style:Gn?ke.chromeHidden:null,children:'stack'===Gt?(0,ce.jsx)(v.TimelineScaleProvider,{availableWidth:Jt,density:Ce,children:Yt}):null}),(0,ce.jsxs)(o.default,{style:(0,M.streamSlotStyle)(Gt,Gn),children:[e.stream??null,e.belowStream??null]}),'fill'===Gt?(0,ce.jsxs)(k.LandscapeTimelineOverlay,{open:!0===e.drawerExpanded,children:[Yt,Xt]}):'wide'===Gt?(0,ce.jsx)(o.default,{style:[ke.wideRail,{width:Zt},Gn?ke.chromeHidden:null],children:(0,ce.jsxs)(v.TimelineScaleProvider,{availableWidth:Zt,density:Ce,children:[Yt,Xt]})}):Xt]})}),me={shown:'timeline-chrome',hidden:'timeline-chrome-hidden'},pe=[],ge=[],he=[],ve=[],fe=new Set,ke=t.default.create({container:{flex:1},bodyStack:{flex:1,minHeight:0,position:'relative'},bodyLayer:{flex:1,minHeight:0},panelLayer:{position:'absolute',top:0,left:0,right:0,bottom:0},wideRow:{flexDirection:'row',minHeight:0},wideRail:{minHeight:0},chromeHidden:{display:'none'}})},2228,[17,20,33,792,1622,1590,1009,466,782,2229,1927,2231,2232,2233,2234,2058,2235,2236,2255,2256,2278,1584,2238,2177,2279,2280,791,2285,1036,2286,1664,1668,1669,2252,1665,2205,2287,1131,2284,1848,1889,1678,2262,2288,1623,1906,1905,2254,1147,2289,2290,2184,2241,2291,2293,2245,2294,10]);
|
|
3688
3688
|
__d(function(g,r,i,a,m,_e,d){"use strict";function e(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(_e,'__esModule',{value:!0}),Object.defineProperty(_e,"TimelineToolbarInline",{enumerable:!0,get:function(){return L}});var t=r(d[0]),n=r(d[1]),o=e(r(d[2])),l=e(r(d[3])),s=e(r(d[4])),c=e(r(d[5])),u=r(d[6]),p=r(d[7]),b=r(d[8]),f=r(d[9]),y=r(d[10]),h=r(d[11]),x=r(d[12]),k=r(d[13]),j=r(d[14]),w=r(d[15]),S=r(d[16]),v=r(d[17]),z=r(d[18]);const L=(0,n.memo)(function(e){const n=(0,t.c)(155),{t:c}=(0,u.useTranslation)(),{colors:v}=(0,S.useTheme)(),L=(0,p.useTimelineScale)(),P=L.control.button,D=L.control.arrow,I=L.space.sm+L.space.xs,C=L.space.xs+L.space.xs,B=null!=e.battery||null!=e.networkLink;let T;n[0]!==B||n[1]!==L.width?(T=(0,j.dayArrowsVisible)(L.width,B),n[0]=B,n[1]=L.width,n[2]=T):T=n[2];const q=T,R=(0,h.useStatusDetail)();let M;n[3]!==P||n[4]!==v.primary||n[5]!==L.radius.md?(M=e=>[O.iconBtn,{minWidth:P,height:P,borderRadius:L.radius.md},{backgroundColor:e?v.primary:"transparent"}],n[3]=P,n[4]=v.primary,n[5]=L.radius.md,n[6]=M):M=n[6];const A=M;let V;n[7]!==v.foregroundMuted||n[8]!==v.primaryForeground?(V=e=>e?v.primaryForeground:v.foregroundMuted,n[7]=v.foregroundMuted,n[8]=v.primaryForeground,n[9]=V):V=n[9];const W=V;let H,G,N,_,E,F;n[10]!==v.background||n[11]!==v.border?(H=[O.container,{backgroundColor:v.background,borderBottomColor:v.border}],n[10]=v.background,n[11]=v.border,n[12]=H):H=n[12],n[13]!==I||n[14]!==L.space.md||n[15]!==L.space.xs?(G=[O.row,{paddingVertical:I,gap:L.space.xs,paddingHorizontal:L.space.md}],n[13]=I,n[14]=L.space.md,n[15]=L.space.xs,n[16]=G):G=n[16],n[17]!==P||n[18]!==v.border||n[19]!==v.foreground||n[20]!==v.surface||n[21]!==e||n[22]!==c||n[23]!==L.icon?(N=e.hideBack?null:(0,z.jsx)(s.default,{style:[O.backBtn,{width:P,height:P,borderRadius:P/2,borderColor:v.border,backgroundColor:v.surface}],onPress:()=>{(0,w.hapticTap)(),e.onBack()},hitSlop:6,accessibilityLabel:c("v2.common.back"),children:(0,z.jsx)(b.ArrowLeft,{size:L.icon.md,color:v.foreground})}),n[17]=P,n[18]=v.border,n[19]=v.foreground,n[20]=v.surface,n[21]=e,n[22]=c,n[23]=L.icon,n[24]=N):N=n[24],n[25]!==L?(_=L.px(2),n[25]=L,n[26]=_):_=n[26],n[27]!==_?(E=[O.dateGroup,{gap:_}],n[27]=_,n[28]=E):E=n[28],n[29]!==D||n[30]!==v.foregroundMuted||n[31]!==e||n[32]!==q||n[33]!==L?(F=q?(0,z.jsx)(s.default,{style:[O.dateArrow,{width:D,height:D,borderRadius:D/2}],onPress:()=>{(0,w.hapticTap)(),e.onPrevDay?.()},hitSlop:6,children:(0,z.jsx)(b.ChevronLeft,{size:L.px(16),color:v.foregroundMuted})}):null,n[29]=D,n[30]=v.foregroundMuted,n[31]=e,n[32]=q,n[33]=L,n[34]=F):F=n[34];const Q=e.onOpenDatePicker;let U,J,K,X,Y,Z,$,ee,te,ne,oe,re,ie,le,ae,se,de,ce,ue,pe,ge,be,fe,ye;return n[35]!==v.surface||n[36]!==C||n[37]!==L.radius.lg||n[38]!==L.space.md||n[39]!==L.space.sm?(U=[O.datePill,{backgroundColor:v.surface,paddingVertical:C,paddingHorizontal:L.space.md,gap:L.space.sm,borderRadius:L.radius.lg}],n[35]=v.surface,n[36]=C,n[37]=L.radius.lg,n[38]=L.space.md,n[39]=L.space.sm,n[40]=U):U=n[40],n[41]!==L?(J=L.px(12),n[41]=L,n[42]=J):J=n[42],n[43]!==v.foregroundSubtle||n[44]!==J?(K=(0,z.jsx)(b.Calendar,{size:J,color:v.foregroundSubtle}),n[43]=v.foregroundSubtle,n[44]=J,n[45]=K):K=n[45],n[46]!==v.foreground||n[47]!==L.font.sm?(X=[O.dateText,{color:v.foreground,fontSize:L.font.sm}],n[46]=v.foreground,n[47]=L.font.sm,n[48]=X):X=n[48],n[49]!==e.dateLabel||n[50]!==X?(Y=(0,z.jsx)(l.default,{style:X,children:e.dateLabel}),n[49]=e.dateLabel,n[50]=X,n[51]=Y):Y=n[51],n[52]!==L?(Z=L.px(10),n[52]=L,n[53]=Z):Z=n[53],n[54]!==v.foregroundSubtle||n[55]!==Z?($=(0,z.jsx)(b.ChevronDown,{size:Z,color:v.foregroundSubtle}),n[54]=v.foregroundSubtle,n[55]=Z,n[56]=$):$=n[56],n[57]!==U||n[58]!==K||n[59]!==Y||n[60]!==$?(ee=(0,z.jsxs)(o.default,{style:U,children:[K,Y,$]}),n[57]=U,n[58]=K,n[59]=Y,n[60]=$,n[61]=ee):ee=n[61],n[62]!==e.onOpenDatePicker||n[63]!==ee?(te=(0,z.jsx)(s.default,{onPress:Q,children:ee}),n[62]=e.onOpenDatePicker,n[63]=ee,n[64]=te):te=n[64],n[65]!==D||n[66]!==v.foregroundMuted||n[67]!==v.foregroundSubtle||n[68]!==e||n[69]!==q||n[70]!==L?(ne=q?(0,z.jsx)(s.default,{style:[O.dateArrow,{width:D,height:D,borderRadius:D/2}],onPress:()=>{(0,w.hapticTap)(),e.onNextDay?.()},disabled:e.nextDayDisabled,hitSlop:6,children:(0,z.jsx)(b.ChevronRight,{size:L.px(16),color:e.nextDayDisabled?v.foregroundSubtle:v.foregroundMuted})}):null,n[65]=D,n[66]=v.foregroundMuted,n[67]=v.foregroundSubtle,n[68]=e,n[69]=q,n[70]=L,n[71]=ne):ne=n[71],n[72]!==te||n[73]!==ne||n[74]!==E||n[75]!==F?(oe=(0,z.jsxs)(o.default,{style:E,children:[F,te,ne]}),n[72]=te,n[73]=ne,n[74]=E,n[75]=F,n[76]=oe):oe=n[76],n[77]===Symbol.for("react.memo_cache_sentinel")?(re=(0,z.jsx)(o.default,{style:O.spacer}),n[77]=re):re=n[77],n[78]!==v||n[79]!==e.battery||n[80]!==R||n[81]!==L.icon||n[82]!==L.space.xs?(ie=e.battery?(0,z.jsx)(o.default,{style:{paddingHorizontal:L.space.xs},children:(0,z.jsx)(h.StatusBadgeButton,{subject:"battery",lines:(0,x.batteryDetailLines)(e.battery),controller:R,children:(0,z.jsx)(f.BatteryBadge,{battery:e.battery,colors:v,size:L.icon.sm,compact:!0})})}):null,n[78]=v,n[79]=e.battery,n[80]=R,n[81]=L.icon,n[82]=L.space.xs,n[83]=ie):ie=n[83],n[84]!==v||n[85]!==e.networkLink||n[86]!==R||n[87]!==L.icon||n[88]!==L.space.xs?(le=(0,y.networkLinkBadgeVisible)(e.networkLink)&&e.networkLink?(0,z.jsx)(o.default,{style:{paddingHorizontal:L.space.xs},children:(0,z.jsx)(h.StatusBadgeButton,{subject:"link",lines:(0,x.networkLinkDetailLines)(e.networkLink),controller:R,children:(0,z.jsx)(y.NetworkLinkBadge,{link:e.networkLink,colors:v,size:L.icon.sm,compact:!0})})}):null,n[84]=v,n[85]=e.networkLink,n[86]=R,n[87]=L.icon,n[88]=L.space.xs,n[89]=le):le=n[89],n[90]!==v||n[91]!==e.battery||n[92]!==e.deviceId||n[93]!==e.networkLink||n[94]!==R||n[95]!==L.icon||n[96]!==L.space.xs?(ae=void 0!==e.deviceId&&(0,k.streamBadgeVisible)({batteryVisible:Boolean(e.battery),linkVisible:Boolean((0,y.networkLinkBadgeVisible)(e.networkLink)&&e.networkLink)})?(0,z.jsx)(o.default,{style:{paddingHorizontal:L.space.xs},children:(0,z.jsx)(h.StatusBadgeButton,{subject:"stream",lines:[],controller:R,children:(0,z.jsx)(k.StreamBadge,{colors:v,size:L.icon.sm})})}):null,n[90]=v,n[91]=e.battery,n[92]=e.deviceId,n[93]=e.networkLink,n[94]=R,n[95]=L.icon,n[96]=L.space.xs,n[97]=ae):ae=n[97],n[98]!==A||n[99]!==W||n[100]!==e.linkedDevicesOpen||n[101]!==e.onOpenLinkedDevices||n[102]!==L.icon?(se=e.onOpenLinkedDevices?(0,z.jsx)(s.default,{style:A(!0===e.linkedDevicesOpen),onPress:e.onOpenLinkedDevices,hitSlop:6,children:(0,z.jsx)(b.Lightbulb,{size:L.icon.sm,color:W(!0===e.linkedDevicesOpen)})}):null,n[98]=A,n[99]=W,n[100]=e.linkedDevicesOpen,n[101]=e.onOpenLinkedDevices,n[102]=L.icon,n[103]=se):se=n[103],n[104]!==A||n[105]!==W||n[106]!==e.onOpenPtz||n[107]!==e.ptzOpen||n[108]!==L.icon?(de=e.onOpenPtz?(0,z.jsx)(s.default,{style:A(!0===e.ptzOpen),onPress:e.onOpenPtz,hitSlop:6,children:(0,z.jsx)(b.Move,{size:L.icon.sm,color:W(!0===e.ptzOpen)})}):null,n[104]=A,n[105]=W,n[106]=e.onOpenPtz,n[107]=e.ptzOpen,n[108]=L.icon,n[109]=de):de=n[109],n[110]!==A||n[111]!==W||n[112]!==e.menuOpen||n[113]!==e.onToggleMenu||n[114]!==L.icon?(ce=e.onToggleMenu?(0,z.jsx)(s.default,{style:A(e.menuOpen),onPress:e.onToggleMenu,hitSlop:6,children:(0,z.jsx)(b.List,{size:L.icon.sm,color:W(e.menuOpen)})}):null,n[110]=A,n[111]=W,n[112]=e.menuOpen,n[113]=e.onToggleMenu,n[114]=L.icon,n[115]=ce):ce=n[115],n[116]!==v.backgroundElevated||n[117]!==v.border||n[118]!==v.foreground||n[119]!==v.primary||n[120]!==A||n[121]!==W||n[122]!==e||n[123]!==L?(ue=void 0===e.qualityLabel?null:(0,z.jsxs)(o.default,{style:O.qualityAnchor,children:[(0,z.jsxs)(s.default,{style:A(e.qualityOpen),onPress:e.onToggleQuality,hitSlop:6,accessibilityRole:"button",accessibilityState:{expanded:!0===e.qualityOpen},children:[(0,z.jsx)(l.default,{style:[O.qualityText,{color:W(e.qualityOpen),fontSize:L.font.xs}],children:e.qualityLabel}),(0,z.jsx)(b.ChevronDown,{size:L.px(12),color:W(e.qualityOpen)})]}),e.qualityOpen&&e.qualityOptions&&e.qualityOptions.length>0?(0,z.jsx)(o.default,{style:[O.qualityMenu,{marginTop:L.space.xs,borderRadius:L.radius.lg,backgroundColor:v.backgroundElevated,borderColor:v.border}],accessibilityRole:"menu",children:e.qualityOptions.map(t=>{const n=t.value===e.qualityValue;return(0,z.jsxs)(s.default,{onPress:()=>{(0,w.hapticTap)(),e.onSelectQuality?.(t.value)},style:O.qualityRow,accessibilityRole:"menuitem",accessibilityState:{selected:n},children:[(0,z.jsx)(l.default,{style:{fontSize:L.font.sm,color:n?v.primary:v.foreground,fontWeight:n?"700":"500"},children:t.label}),n?(0,z.jsx)(b.Check,{size:L.px(14),color:v.primary}):null]},t.value)})}):null]}),n[116]=v.backgroundElevated,n[117]=v.border,n[118]=v.foreground,n[119]=v.primary,n[120]=A,n[121]=W,n[122]=e,n[123]=L,n[124]=ue):ue=n[124],n[125]!==A||n[126]!==W||n[127]!==e||n[128]!==c||n[129]!==L.icon?(pe=e.onToggleLegend?(0,z.jsx)(s.default,{style:A(e.legendOpen),onPress:()=>{(0,w.hapticTap)(),e.onToggleLegend?.()},hitSlop:6,accessibilityRole:"button",accessibilityLabel:c("v2.theater.legend.open"),children:(0,z.jsx)(b.HelpCircle,{size:L.icon.sm,color:W(e.legendOpen)})}):null,n[125]=A,n[126]=W,n[127]=e,n[128]=c,n[129]=L.icon,n[130]=pe):pe=n[130],n[131]!==oe||n[132]!==ie||n[133]!==le||n[134]!==ae||n[135]!==se||n[136]!==de||n[137]!==ce||n[138]!==ue||n[139]!==pe||n[140]!==G||n[141]!==N?(ge=(0,z.jsxs)(o.default,{style:G,children:[N,oe,re,ie,le,ae,se,de,ce,ue,pe]}),n[131]=oe,n[132]=ie,n[133]=le,n[134]=ae,n[135]=se,n[136]=de,n[137]=ce,n[138]=ue,n[139]=pe,n[140]=G,n[141]=N,n[142]=ge):ge=n[142],n[143]!==e.deviceId?(be=void 0===e.deviceId?{}:{deviceId:e.deviceId},n[143]=e.deviceId,n[144]=be):be=n[144],n[145]!==v||n[146]!==e.battery||n[147]!==e.networkLink||n[148]!==R||n[149]!==be?(fe=(0,z.jsx)(h.StatusDetailPopover,Object.assign({controller:R,battery:e.battery,link:e.networkLink},be,{colors:v,placement:"below"})),n[145]=v,n[146]=e.battery,n[147]=e.networkLink,n[148]=R,n[149]=be,n[150]=fe):fe=n[150],n[151]!==H||n[152]!==ge||n[153]!==fe?(ye=(0,z.jsxs)(o.default,{style:H,children:[ge,fe]}),n[151]=H,n[152]=ge,n[153]=fe,n[154]=ye):ye=n[154],ye}),O=c.default.create({container:{borderBottomWidth:1,zIndex:20},row:{flexDirection:'row',alignItems:'center',flexWrap:'wrap',gap:v.SPACING.xs,paddingHorizontal:v.SPACING.md,paddingVertical:v.SPACING.sm+2},backBtn:{width:30,height:30,borderRadius:15,alignItems:'center',justifyContent:'center',borderWidth:c.default.hairlineWidth},dateGroup:{flexDirection:'row',alignItems:'center'},dateArrow:{width:28,height:28,borderRadius:14,alignItems:'center',justifyContent:'center'},datePill:{flexDirection:'row',alignItems:'center',gap:v.SPACING.sm,paddingHorizontal:v.SPACING.md,paddingVertical:v.SPACING.xs+2,borderRadius:v.RADIUS.lg},dateText:{fontSize:12,fontWeight:'600'},spacer:{flex:1},iconBtn:{minWidth:30,height:30,paddingHorizontal:v.SPACING.sm,borderRadius:v.RADIUS.lg,alignItems:'center',justifyContent:'center'},qualityAnchor:{position:'relative'},qualityMenu:{position:'absolute',top:'100%',right:0,minWidth:132,borderWidth:1,paddingVertical:4,zIndex:40,elevation:8},qualityRow:{flexDirection:'row',alignItems:'center',justifyContent:'space-between',gap:12,paddingHorizontal:12,paddingVertical:8},qualityText:{fontSize:10,fontWeight:'700'}})},2229,[15,17,20,198,252,33,1009,1927,796,1624,1625,1626,1627,1629,2230,1036,782,790,10]);
|
|
3689
3689
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"COMPACT_TOOLBAR_WIDTH",{enumerable:!0,get:function(){return t}}),e.dayArrowsVisible=function(n,u){return!(u&&n<t)};const t=520},2230,[]);
|
|
3690
|
-
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"TIMELINE_RAIL_WIDTH",{enumerable:!0,get:function(){return t}}),Object.defineProperty(e,"TIMELINE_RAIL_WIDTH_NARROW",{enumerable:!0,get:function(){return n}}),Object.defineProperty(e,"RAIL_NARROW_BELOW",{enumerable:!0,get:function(){return u}}),Object.defineProperty(e,"STREAM_MAX_HEIGHT_FRACTION",{enumerable:!0,get:function(){return o}}),e.computeWideDetailSizes=function({containerWidth:c,viewportHeight:_}){const f=c<u?n:t,I=Math.max(0,c-f),b=_*o*16/9,O=Math.min(I,b);return{railWidth:f,streamWidth:O,streamHeight:9*O/16}};const t=
|
|
3690
|
+
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"TIMELINE_RAIL_WIDTH",{enumerable:!0,get:function(){return t}}),Object.defineProperty(e,"TIMELINE_RAIL_WIDTH_NARROW",{enumerable:!0,get:function(){return n}}),Object.defineProperty(e,"RAIL_NARROW_BELOW",{enumerable:!0,get:function(){return u}}),Object.defineProperty(e,"STREAM_MAX_HEIGHT_FRACTION",{enumerable:!0,get:function(){return o}}),e.computeWideDetailSizes=function({containerWidth:c,viewportHeight:_}){const f=c<u?n:t,I=Math.max(0,c-f),b=_*o*16/9,O=Math.min(I,b);return{railWidth:f,streamWidth:O,streamHeight:9*O/16}};const t=420,n=380,u=1180,o=.62},2231,[]);
|
|
3691
3691
|
__d(function(g,r,i,a,m,_e,d){"use strict";function e(e){return e&&e.__esModule?e:{default:e}}Object.defineProperty(_e,'__esModule',{value:!0}),_e.LandscapeTimelineOverlay=function({children:e,open:W}){const _=(0,n.useSettings)().settings.stream.toolbarDensity,{width:w}=(0,u.useViewportSize)(),E=(0,c.useSafeAreaInsets)(),x=(0,f.drawerPanelBox)(w),y=x.panelWidth,V=(0,t.useRef)(new o.default.Value(0)).current;(0,t.useEffect)(()=>{h.log.debug('theater','landscape-timeline: mounted',{windowWidth:w,panelWidth:y,contentWidth:x.contentWidth})},[w,y,x.contentWidth]),(0,t.useEffect)(()=>{h.log.debug('theater','landscape-timeline: toggled',{open:W})},[W]),(0,t.useEffect)(()=>{o.default.timing(V,{toValue:W?1:0,duration:v,useNativeDriver:!0}).start()},[W,V]);const A=V.interpolate({inputRange:[0,1],outputRange:[y,0]});return(0,b.jsx)(s.default,{pointerEvents:"box-none",style:[l.default.absoluteFill,R.root],children:(0,b.jsx)(o.default.View,{pointerEvents:W?'auto':'none',style:[R.panel,{width:y,paddingTop:E.top,paddingBottom:E.bottom,transform:[{translateX:A}]}],children:(0,b.jsx)(p.TimelineScaleProvider,{availableWidth:x.contentWidth,density:_,children:e})})})};var t=r(d[0]),n=r(d[1]),o=e(r(d[2])),l=e(r(d[3])),s=e(r(d[4])),u=r(d[5]),c=r(d[6]),f=r(d[7]),p=r(d[8]),h=r(d[9]),b=r(d[10]);const v=220;const R=l.default.create({root:{zIndex:f.DRAWER_OVERLAY_Z,elevation:f.DRAWER_OVERLAY_Z},panel:{position:'absolute',top:0,bottom:0,right:0,backgroundColor:'rgba(8, 10, 14, 0.72)',borderTopLeftRadius:14,borderBottomLeftRadius:14,overflow:'hidden'}})},2232,[17,1623,129,33,20,792,466,2214,1927,1131,10]);
|
|
3692
3692
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),e.resolveDetailLayoutMode=function(n){return n.fullscreen?'fill':(0,t.shouldUseWideDetail)(n)?'wide':(0,t.isLandscapeViewport)(n)?'fill':'stack'},e.toolbarPlacementFor=function(t){return'stack'===t?'top':'inline'},e.isFillMode=function(t){return'fill'===t},e.detailShapeTestId=function(t){return`theater-shape-${t}`},e.isUnexpectedPortraitStack=function(n,l){return'stack'===l&&(0,t.isTabletViewport)(n)};var t=r(d[0])},2233,[794]);
|
|
3693
3693
|
__d(function(g,r,i,a,m,e,d){"use strict";Object.defineProperty(e,'__esModule',{value:!0}),Object.defineProperty(e,"STREAM_SLOT_Z",{enumerable:!0,get:function(){return t}}),e.streamSlotStyle=function(n,c=!1){switch(n){case'fill':return{flex:1,minHeight:0,zIndex:t};case'wide':return{flex:1,minWidth:0,alignItems:'center'};case'stack':return c?{width:'100%',flex:1,minHeight:0}:{width:'100%'}}};const t=50},2234,[]);
|
package/assets/viewer/index.html
CHANGED
|
@@ -70,6 +70,6 @@
|
|
|
70
70
|
</noscript>
|
|
71
71
|
<!-- The root element for your Expo app. -->
|
|
72
72
|
<div id="root"></div>
|
|
73
|
-
<script src="/viewer/camstack/_expo/static/js/web/index-
|
|
73
|
+
<script src="/viewer/camstack/_expo/static/js/web/index-76e9a55d32d9d4f1d0792f1a7238c9a0.js" defer></script>
|
|
74
74
|
</body>
|
|
75
75
|
</html>
|
package/dist/remoteEntry.js
CHANGED
|
@@ -30,7 +30,7 @@ async function d(e) {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
async function f() {
|
|
33
|
-
return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-
|
|
33
|
+
return l ||= d(() => import("./_virtual_mf-localSharedImportMap___mfe_internal__addon_pipeline_orchestrator_widgets-DohWXqlQ.mjs")).catch((e) => {
|
|
34
34
|
throw l = void 0, e;
|
|
35
35
|
}), l;
|
|
36
36
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camstack/addon-pipeline-orchestrator",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.229",
|
|
4
4
|
"description": "Hub-side camera-to-agent load balancer — tracks runner capacity and dispatches attachCamera calls to the optimal pipeline-runner instance",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"camstack",
|