{"context":{"domain":"lucas-playground"},"layers":{"ApplicationLayer":{"reference":"ApplicationLayer","availableInstances":[{"reference":"ComponentsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@DataSet","reference":"SystemsDataSet","params":{"filter":{"domain":"data2"},"pagination":{"size":1},"datasource":{"component":"data2-core-types@ProcessReference","params":{"reference":"SystemsDataSource"}}}},{"reference":"ExternalComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"SystemsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"5e3b796d6228227ca637d0f4","name":"data2","domain":"data2","organization":"62292184611f480b3191c37c","visibility":"public","updatedAt":"2026-07-27T14:19:36.810Z"}]}},{"reference":"OrganizationsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"DataComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@DataSet","reference":"OneFileComponentInstancesDataSet","params":{"pagination":{"size":1},"master":{"dataset":{"component":"data2-core-types@ProcessReference","params":{"reference":"SystemsDataSet"}},"localField":"system","masterField":"_id"},"datasource":{"component":"data2-core-types@ProcessReference","params":{"reference":"FileComponentInstancesDataSource"}}}},{"reference":"ApplicationsDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"ComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"reference":"ServiceComponentInstancesDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@Data2TableDataSource","reference":"FileComponentInstancesDataSource","params":{"table":"fileComponentInstances","schema":[{"component":"data2-core-types@Field","params":{"key":"component","title":"Component","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"system","title":"System","component":"data2-core-primitives@ObjectId"}},{"component":"data2-core-types@Field","params":{"key":"displayName","title":"Display Name","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"params","title":"Params","component":"data2-core-primitives@Object"}},{"component":"data2-core-types@Field","params":{"key":"reference","title":"Reference","component":"data2-core-primitives@String"}}]}},{"component":"data2-core@MemoryDataSource","reference":"EmptyDataSource","params":{"initialData":[]}},{"reference":"ComponentsDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"UserComponentsDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"DataComponentInstancesDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"ServiceComponentInstancesDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"ComponentInstancesDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"ExternalComponentInstancesDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}},{"reference":"ApplicationsDataSet","component":"data2-core@DataSet","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"EmptyDataSource"}}}}],"processesParams":{}},"HostApplicationLayer":{"reference":"HostApplicationLayer","availableInstances":[{"_id":"5f15ff190528b92601890f71","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"SystemsTableDataSource"}},"filter":{"domain":{"component":"data2-core-types@Reference","params":{"reference":"domain"}}},"pk":"_id","fields":[{"component":"data2-core-types@FieldReference","params":{"key":"_id"}},{"component":"data2-core-types@FieldReference","params":{"key":"name"}},{"component":"data2-core-types@FieldReference","params":{"key":"domain"}},{"component":"data2-core-types@FieldReference","params":{"key":"visibility"}},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"customDomains"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"organization._id"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"organization.name"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"organization.billingStatus"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"organization.publicTrial.active"}}},"break":true},{"component":"data2-core-types@FieldReference","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"settings.defaultAccessPolicy"}}},"break":true}],"pagination":{"size":{"component":"data2-core-primitives@Number","params":{"content":1}}},"staticPagination":{"size":{"component":"data2-core-primitives@Number","params":{"content":1}}},"policies":[{"component":"data2-core-auth@Policy","params":{"allow":{"params":{"actions":[{"params":{"components":[{"params":{"query":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$params.query"}}}},"field":{"component":"data2-core-primitives@String","params":{"content":"_id"}},"fieldType":"string"},"component":"data2@7KkQq0vK4a7D2gg6IVJT7"},{"params":{"query":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$params.query"}}}},"field":{"component":"data2-core-primitives@String","params":{"content":"domain"}},"fieldType":"string"},"component":"data2@7KkQq0vK4a7D2gg6IVJT7"},{"params":{"query":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$params.query"}}}},"field":{"component":"data2-core-primitives@String","params":{"content":"customDomains"}},"fieldType":"string"},"component":"data2@7KkQq0vK4a7D2gg6IVJT7"}]},"component":"data2-core-logical-operators@Or"}]},"component":"data2-core-flow@Series"}}}]},"reference":"SystemsDataSet","updatedAt":"2026-08-07T21:51:24.037Z","createdAt":"2020-07-20T20:31:21.838Z"},{"_id":"5f1601ce0528b92601890f7c","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"pagination":{"size":1000},"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ComponentsTableDataSource"}},"sort":{"params.package":1,"params.component":1},"pk":"_id","autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"staticFilter":{"system":{"exists":{"params":{"content":false},"component":"data2-core-primitives@Boolean"}}},"filter":{"system":{"exists":{"params":{"content":false},"component":"data2-core-primitives@Boolean"}}}},"reference":"ComponentsDataSet","updatedAt":"2025-11-05T19:37:01.935Z","createdAt":"2020-07-20T20:42:54.898Z"},{"_id":"5f9041dbc8da12be8b94aea4","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"pagination":{"size":2000},"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ComponentsTableDataSource"}},"pk":"_id","autoEdit":true,"master":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"UserComponentsDataSet","updatedAt":"2025-11-06T21:06:58.095Z","createdAt":"2020-07-20T20:44:09.350Z"},{"_id":"65d8c4fabc9dbb8f94de8d53","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ExternalComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"ExternalComponentInstancesDataSet","updatedAt":"2025-11-06T21:07:23.742Z","createdAt":"2024-02-23T16:17:01.816Z"},{"reference":"SystemsTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"67850da249571825a6d31832","name":"Lucas Barduco","domain":"lucas-playground","visibility":"public","settings":{"defaultAccessPolicy":"private"},"updatedAt":"2026-08-14T19:26:29.927Z"}]}},{"reference":"ComponentsTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"5f52a278a575399a45d239b4","component":"data2-core-types@Component","params":{"package":"data2-core-primitives","component":"Router","interactions":{"component":"data2-core-types@FieldSet","params":{"fields":{"goBack":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-types@Function"}},"definition":{"component":"data2-core-functions@Function","params":{"body":{"preventEvaluation":true,"component":"data2-core-types@Getter","params":{"module":{"component":"data2-core-types@This","params":{}},"prop":"history.goBack","args":[]}}}},"icon":{"component":"data2-core-primitives@String","params":{"content":"arrow-left"}},"visibility":"public"}},"goTo":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"definition":{"component":"data2-core-functions@Function","params":{"body":{"preventEvaluation":true,"component":"data2-core-types@Getter","params":{"module":{"component":"data2-core-types@This","params":{}},"prop":"history.push","args":[{"component":"data2-core-types@Reference","params":{"reference":"url"}},{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"preserveQuery"}}}}]}},"parameters":[{"component":"data2-core-primitives@String","params":{"content":"url"}},{"component":"data2-core-primitives@String","params":{"content":"preserveQuery"}}]},"break":true},"icon":{"component":"data2-core-primitives@String","params":{"content":"share"}},"visibility":"public","arguments":[{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Path to route"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Path to redirect user"}},"visibility":"public","required":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2-core-types@ComponentParameter"},{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Boolean"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Preserve Query"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Preserve query string parameters  preserve query parameters on navigating."}},"visibility":"public","required":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2-core-types@ComponentParameter"}]}},"open":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-types@Function"}},"definition":{"component":"data2-core-functions@Function","params":{"body":{"preventEvaluation":true,"component":"data2-core-types@Getter","params":{"module":{"component":"data2-core-types@This","params":{}},"prop":"history.push","args":[{"pathname":{"component":"data2-core-types@Reference","params":{"reference":"value"}}}]}},"parameters":["value"]}},"icon":{"component":"data2-core-primitives@String","params":{"content":"share"}},"visibility":"public","arguments":[{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Link to open"}},"description":{"component":"data2-core-primitives@String","params":{"content":""}},"visibility":"public","required":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2-core-types@ComponentParameter"},{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Target"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Where to open the link"}},"visibility":"public","required":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"oneOf":[{"params":{"content":"_blank"},"component":"data2-core-primitives@String"},{"params":{"content":"_self"},"component":"data2-core-primitives@String"},{"params":{"content":"_parent"},"component":"data2-core-primitives@String"},{"params":{"content":"_top"},"component":"data2-core-primitives@String"}]},"component":"data2-core-types@ComponentParameter"}]}},"close":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-types@Function"}},"definition":{"component":"data2-core-functions@Function","params":{"body":{"preventEvaluation":true,"component":"data2-core-types@Getter","params":{"module":{"params":{},"component":"data2-core-web@Window"},"prop":"close"}},"parameters":["value"]}},"icon":{"component":"data2-core-primitives@String","params":{"content":"times"}},"visibility":"public","arguments":[{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Link to open"}},"description":{"component":"data2-core-primitives@String","params":{"content":""}},"visibility":"public","required":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2-core-types@ComponentParameter"},{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Target"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Where to open the link"}},"visibility":"public","required":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"oneOf":[{"params":{"content":"_blank"},"component":"data2-core-primitives@String"},{"params":{"content":"_self"},"component":"data2-core-primitives@String"},{"params":{"content":"_parent"},"component":"data2-core-primitives@String"},{"params":{"content":"_top"},"component":"data2-core-primitives@String"}]},"component":"data2-core-types@ComponentParameter"}],"description":{"component":"data2-core-primitives@String","params":{"content":"Closes a window that was opened via router.open."}}}}}}}}},{"_id":"620d28658271aa4129919d89","component":"data2-core-types@Component","params":{"package":"data2-interface-services","component":"DeviceController","interactions":{"params":{"fields":{"postMessage":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":"data2-core-primitives@String","title":{"component":"data2-core-primitives@String","params":{"content":"data"}}}}]},"component":"data2-core-types@ComponentParameter"},"print":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"arguments":[{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Object"}},"flat":{"component":"data2-core-primitives@Boolean","params":{"content":true}},"parameters":{"zoom":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Number"}},"title":{"component":"data2-core-primitives@String","params":{"content":"zoom"}},"visibility":"public"}}},"visibility":"public"},"component":"data2-core-types@ComponentParameter"}],"visibility":"public"},"component":"data2-core-types@ComponentParameter"},"share":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}}},"component":"data2-core-types@ComponentParameter"},"clipboard.copy":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}}}}]},"component":"data2-core-types@ComponentParameter"},"clipboard.paste":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}}}}]},"component":"data2-core-types@ComponentParameter"},"download":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"visibility":"public","arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Filename"}}}},{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Content"}}}},{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Object"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Options"}},"parameters":{"params":{"fields":{"type":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Mimetype"}}}}}},"component":"data2-core-types@FieldSet"}}}]},"component":"data2-core-types@ComponentParameter"},"downloadUrl":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"visibility":"public","arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Filename"}}}},{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Url"}}}}]},"component":"data2-core-types@ComponentParameter"},"promptFiles":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":"data2-core-primitives@Object","flat":{"component":"data2-core-primitives@Boolean","params":{"content":true}},"parameters":{"params":{"fields":{"multiple":{"component":"data2-core-types@ComponentParameter","params":{"title":{"component":"data2-core-primitives@String","params":{"content":"Multiple"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Whether or not to allow selecting multiple files"}},"component":"data2-core-primitives@Boolean"}},"acceptedFormats":{"component":"data2-core-types@ComponentParameter","params":{"title":{"component":"data2-core-primitives@String","params":{"content":"Accepted Formats"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Accepted file formats"}},"component":"data2-core-primitives@String","list":{"component":"data2-core-primitives@Boolean","params":{"content":true}}}},"timeout":{"component":"data2-core-types@ComponentParameter","params":{"title":{"component":"data2-core-primitives@String","params":{"content":"Timeout"}},"description":{"component":"data2-core-primitives@String","params":{"content":"Max milliseconds to wait for file upload"}},"component":"data2-core-primitives@Number"}}}},"component":"data2-core-types@FieldSet"}}}],"visibility":"public"},"component":"data2-core-types@ComponentParameter"},"meetingRecord":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"visibility":"public","definition":{"params":{"actions":[{"params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"meeting"}},"script":{"component":"data2-core-primitives@String","params":{"content":"(function() {\n  let mediaRecorder;\n  let audioChunks = [];\n  let combinedStream;\n  let audioContext;\n  \n  window.meetingCapture = async function() {\n    try {\n      // Solicitar acesso ao áudio da guia (e vídeo, que será ignorado depois)\n      const tabStream = await navigator.mediaDevices.getDisplayMedia({ \n        video: true, // Necessário para alguns navegadores\n        audio: true\n      });\n      \n      // Remover a trilha de vídeo\n      const tabAudioTrack = tabStream.getAudioTracks()[0];\n      \n      // Solicitar acesso ao microfone\n      const micStream = await navigator.mediaDevices.getUserMedia({ audio: true });\n      const micAudioTrack = micStream.getAudioTracks()[0];\n      \n      // Criar um novo MediaStream com ambas as trilhas de áudio\n      combinedStream = new MediaStream([tabAudioTrack, micAudioTrack]);\n      \n      // Criar um contexto de áudio para misturar os streams\n      audioContext = new AudioContext();\n      const destination = audioContext.createMediaStreamDestination();\n      \n      // Conectar a trilha de áudio da guia\n      const tabSource = audioContext.createMediaStreamSource(new MediaStream([tabAudioTrack]));\n      tabSource.connect(destination);\n      \n      // Conectar a trilha de áudio do microfone\n      const micSource = audioContext.createMediaStreamSource(new MediaStream([micAudioTrack]));\n      micSource.connect(destination);\n      \n      // Iniciar gravação com o stream misturado\n      mediaRecorder = new MediaRecorder(destination.stream);\n      audioChunks = [];\n      mediaRecorder.ondataavailable = (e) => audioChunks.push(e.data);\n      mediaRecorder.start();\n      \n      console.log('Gravação iniciada. Chame meetingCaptureStop() para finalizar.');\n    } catch (error) {\n      console.error('Erro ao iniciar a captura:', error);\n    }\n  };\n  \n  window.meetingCaptureStop = function() {\n    return new Promise((resolve, reject) => {\n      if (!mediaRecorder) {\n        reject('Nenhuma gravação em andamento.');\n        return;\n      }\n      \n      mediaRecorder.onstop = () => {\n        const audioBlob = new Blob(audioChunks, { type: 'audio/webm' });\n        combinedStream.getTracks().forEach(track => track.stop());\n        audioContext.close();\n        \n        resolve(audioBlob);\n        console.log('Gravação finalizada. O arquivo de áudio está pronto para upload.');\n      };\n      \n      mediaRecorder.stop();\n    });\n  };\n})();"}}},"component":"data2-core-web@Script"},{"component":"data2-core-types@Getter","params":{"module":{"params":{},"component":"data2-core-web@Window"},"prop":{"component":"data2-core-primitives@String","params":{"content":"meetingCapture"}}}}]},"component":"data2-core-flow@Series"}},"component":"data2-core-types@ComponentParameter"},"meetingRecordStop":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"visibility":"public","arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Filename"}}}},{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Content"}}}},{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Object"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Options"}},"parameters":{"params":{"fields":{"type":{"component":"data2-core-types@ComponentParameter","params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@String"}},"title":{"component":"data2-core-primitives@String","params":{"content":"Mimetype"}}}}}},"component":"data2-core-types@FieldSet"}}}],"definition":{"params":{"actions":[{"component":"data2-core-types@Getter","params":{"module":{"params":{},"component":"data2-core-web@Window"},"prop":{"component":"data2-core-primitives@String","params":{"content":"meetingCaptureStop"}}}}]},"component":"data2-core-flow@Series"}},"component":"data2-core-types@ComponentParameter"},"notify":{"params":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core-primitives@Function"}},"visibility":"private","arguments":[{"component":"data2-core-types@ComponentParameter","params":{"component":"data2-core-primitives@Object","parameters":{"title":{"params":{"component":"data2-core-primitives@String","index":{"component":"data2-core-primitives@Number","params":{"content":0}},"title":{"component":"data2-core-primitives@String","params":{"content":"title"}}},"component":"data2-core-types@ComponentParameter"},"sound":{"params":{"component":"data2-core-types@FileComponentUrlReference","index":{"component":"data2-core-primitives@Number","params":{"content":1}},"title":{"component":"data2-core-primitives@String","params":{"content":"sound"}}},"component":"data2-core-types@ComponentParameter"}},"flat":{"component":"data2-core-primitives@Boolean","params":{"content":true}}}}]},"component":"data2-core-types@ComponentParameter"}}},"component":"data2-core-types@FieldSet"}}},{"_id":"6a83bd00e42011de7361a9d1","component":"data2-core-types@Component","system":"67850da249571825a6d31832","params":{"extends":"data2-core-primitives@Block","component":"portalConsumo","package":"lucas-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"// portalConsumo — consumo diário de recursos × sessões (Natura AVI)\n// Fontes: rush listener em lucas-playground (server-side) -> APIs de sessões e de consumo.\n// Regras de agregação e preços verificados contra a fatura de jul/26 em 17/08/2026.\n\nconst LABELS = {\"EjkzVPO8aGOdMDm_LMcuL\":\"mensagens-zap\",\"wfUBk4a9nJKWLXvvenufg\":\"mensagens-zap\",\"BeuKCiw5NRuCGXqZMPhDc\":\"mensagens-zap\",\"bv5B0TwbvCSaeFHRcZCk5\":\"mensagens-zap\",\"Djl5PO0AA-A1VTvV09va8\":\"messages\",\"QvzYxVsqo0Rn_4NbLzUBI\":\"messages\",\"e4VJLkg9oL8PoNuN6k0Xz\":\"messages\",\"gv6tKeiwDpkLbsu9YlP0g\":\"Domínios\",\"gtuHlDZx1TQxLYcIvmI-Y\":\"Domínios\",\"FCRaa2xYnG-kfDI0Wbd2B\":\"atendimento_exemplo\",\"7eNXvpzWWA477bKIwPlq5\":\"atendimento_exemplo\",\"7-Kc_WfrOD-mQYO56Eiig\":\"regions\",\"sf62YbmAqEN36vphSMYE-\":\"regions\",\"51a_7nsaHRAtC42epq4Z0\":\"regions\",\"Xo1l3vBp_pB74VXCrT8yR\":\"useCases\",\"GAbOgAomS_h6HYNzMLy7L\":\"useCases\",\"0tM4Fz_rXCpHqi35nnSMY\":\"useCases\",\"zbvIy-5JbobFduGnTxumf\":\"useCases\",\"5M23Z1KfrPg07zEMNxSeI\":\"useCases\",\"d1pELeE8QZBtT04dCQ9wn\":\"useCases\",\"xZlxA3hlzH2tZoZJj1Hhr\":\"useCases\",\"6Mj-04KjCJmpKjoScafy5\":\"useCases\",\"49gwabxHRaQVQLFHJEo45\":\"useCases\",\"-qaMIuMz25iKUtXjPpozC\":\"useCases\",\"1M4RTkZl-N_8yOmZuNYH4\":\"usuarios\",\"DmQuM6oU6VYfeAoYC7bd0\":\"usuarios\",\"v1X-i9Ln6_tuv0R2XlSJ4\":\"usuarios\",\"0-_TObRRNMYQ2nFk-3qba\":\"Channels\",\"qN09iQTkTp7gopSyo4sjh\":\"Channels\",\"VQDwhh0gyuxY7CWMNlSC1\":\"compliance-checks\",\"X7yDiCSQyDL7rd5MexBgD\":\"compliance-checks\",\"Xg9PzioBsLbGijNqJ7QOq\":\"useCasesRegionExceptions\",\"I8uHiRQEEROX6zcV2Nryn\":\"useCasesRegionExceptions\",\"vJF6hgnBS7wyhqGy1cUAF\":\"useCasesRegionExceptions\",\"6Ocrxl6WqjioPrhNjF7XN\":\"useCasesRegionExceptions\",\"LWm0jxJUHtdFUfJ8XbtoU\":\"useCasesRegionExceptions\",\"EkLtoMcIvF-qIJ6Y-2HW-\":\"Example_useCase_info\",\"RmnRc6OpI89iAw3s09lm9\":\"Example_useCase_info\",\"TSM9kXKVs7-uDdNhAvlpt\":\"Example_useCase_info\",\"l1CdDCNCulMarka8qdd4Z\":\"test-case\",\"xoh9KYHLWrKIiB1gvZFyA\":\"test-case\",\"6Xf7hH_NqzWbKKmqeA0Cw\":\"test-case\",\"MYSWyJhYaWHrautfemsFK\":\"faqs\",\"JJdfsBfraSbfsHjLHIYOS\":\"faqs\",\"SFMbd_CNcxXDu3ko0a9z6\":\"faqs\",\"AA3uk7AskKMLKrGSfaVPM\":\"faqs\",\"TEjzNRc8J1DkpUSW2OoE1\":\"faqs\",\"BNGc_wWdSweyUPwsrv6E9\":\"faqs\",\"nODO90jdhicNzqdDLyD1f\":\"faqs\",\"upzDI34_r_FF4AJsBRAVI\":\"faqs\",\"Ol2BtLlQwjj2jFAWKwoYS\":\"faqs\",\"to58eOvqv5VD7V0BRatb9\":\"faqs\",\"9s1bq3WIsLgVx69uqISTz\":\"faqs\",\"6uTW9_Q1F_vlN6JaNKI5d\":\"faqs\",\"4yocmcfIT8NhhvhlBpfTi\":\"faqs\",\"SNvadrvyhJbPtxrv1qf8a\":\"faqs\",\"S8-O8Rhic-NB5M0IwZV-g\":\"faqs\",\"sBGA6UFP-KM4k42j7I6dt\":\"faqs\",\"goZAYeQSxwm7boqHlWFMg\":\"faqs\",\"woL64f-2KLy4Jx_2DOA6F\":\"faqs\",\"iYg4Vp5jr1DbbGrq1I269\":\"faqs\",\"USuhwwd4rIwWeAPwTB5TN\":\"faqs\",\"cLBugrXi5ts4EIuhroo5l\":\"faqs\",\"BCcvqoQlbSWc3-p_v-bdR\":\"faqs\",\"iZ6B0kDmsHLq_p-n6-jHA\":\"Conversation_cases\",\"ssdxsYMLLsXNtm5a2AYpl\":\"Conversation_cases\",\"8rPLY7MQSF2OKcMPp4rzm\":\"FAQ_Categories\",\"832myopBDXKYvuwGk_xRR\":\"FAQ_Categories\",\"2LLbal26K-tA1BRiaXY1O\":\"Variables\",\"aRieAJX30OJ-Bo-KW9Z5_\":\"Variables\",\"wbcVL8jbDJpta49Q7gLVS\":\"Casas de Cobrança - Sector\",\"YOxvBArm0GEn7FXdWRu2C\":\"Casas de Cobrança - Sector\",\"xBPbE7PXNGdyLBhYGAtqF\":\"Casas de Cobrança - Sector\",\"t7OsXgOpv_yOMuF8kOzRx\":\"Problemas-Reportado\",\"DrYMevjeCBEItuYfPUP7N\":\"Problemas-Reportado\",\"zPJ4TRpmk5YCJa-uToldx\":\"restrictions\",\"9mBfaU-zv0KhxnEUsbAC9\":\"restrictions\",\"jyicaYbxJfeHM7FKhzbKq\":\"analytics data points\",\"O3MUAVBuxfNaqwbIdKpsg\":\"analytics data points\",\"nCvWfH35myVYGRtV7fXA6\":\"analytics data points\",\"1TWn2_dt_9dxJWcmjr_Iz\":\"analytics data points\",\"O355rxCl9pTKYe67IFHe6\":\"analytics data points\",\"3tPtmxHGpA3TS5wLzFU8S\":\"analytics data points\",\"MLb8xx0gWt4Jq4vUg0wjF\":\"analytics data points\",\"dOYnXsUilNM5JPhVe1n01\":\"analytics data points\",\"j0xMxmtTCStxfFNWTd_HS\":\"analytics data points\",\"c9nrcLZKhpVegAlknQHln\":\"analytics data points\",\"eCFintPLBUhhAac1ZNSJT\":\"analytics data points\",\"v9Qn7UOkSkqz3IGkT4BWL\":\"analytics data points\",\"t-GSSwMY0sAN_YvvGpyZa\":\"analytics data points\",\"CnSk9qDeesed9nfrJBIIn\":\"analytics data points\",\"tKcVN0D5C67Y_60dRIBPn\":\"analytics data points\",\"sMZsvP486mxtZjYlUfLzW\":\"analytics data points\",\"JmWLuuCOW9deran97587K\":\"analytics data points\",\"e4vhKLp9BNShkk3iVda5Y\":\"analytics data points\",\"FwnA-K06Ls1PaEiZJbVgl\":\"analytics data points\",\"5eF7eJ55DyPrlN4q_WqPo\":\"analytics data points\",\"yX6DZYhTh6tXKI8y-iBAK\":\"analytics data points\",\"ffhu-FEyw5S3CnVfbWA5j\":\"analytics data points\",\"UeWNehWJ-C6OonoPwt3Lr\":\"analytics data points\",\"GVgI9ncCN1fvW8AYWg_7x\":\"analytics data points\",\"8PtmIpG-azGIS88kW4tjJ\":\"analytics data points\",\"zls_MMzKo4EDZTFzTrqp0\":\"analytics data points\",\"R60GQ6W1dJvomQBhg7QsW\":\"analytics data points\",\"_jpPKNL3Y6pfWUCx87Aaa\":\"analytics data points\",\"1wZGSCnnDbh9qp0Cz8sp-\":\"analytics data points\",\"Y-p_A0bvsCu1Zwq1FJI1a\":\"analytics data points\",\"o_6UFG7MSFL-kf9_dkhp3\":\"analytics data points\",\"ScfUoppyudq6A8xfFDkh8\":\"Reports\",\"veaP1I7oI7pQ6GwG-tudL\":\"Reports\",\"d1AFjBrKiLX05H5SElIMo\":\"Reports\",\"--2YzHGz3rUiwJmYhFCFY\":\"Reports\",\"CBTi4vgKQ0gi3tggd42Jz\":\"report-updates\",\"-k4xDNW5DYydh0wZnX3bE\":\"report-updates\",\"uiWT6f7J9YYSO4DvXPeHD\":\"chat_tokens\",\"dW_GWmWKmM2pT4H7A75e6\":\"chat_tokens\",\"T4i9sVBx9n3djR40FJUqT\":\"chat_tokens\",\"DH7DAlMdvHhrg_VLDqeoM\":\"chat_tokens\",\"hJ_zsvaGqPXrh7v6Drgjo\":\"chat_tokens\",\"o16mJt4sZqhrOwfRJzlgT\":\"chat_tokens\",\"thswnHxWWC6R_8yMV3cxR\":\"chat_tokens\",\"q9tSMqOajrZgWBXqKkEhb\":\"chat_tokens\",\"MoLQ3bMEa0NFZG4AyWtlJ\":\"chat_tokens\",\"BVpRak20FfLgt3pWDDlor\":\"chat_tokens\",\"wLgYrXeVHjZmUvrnzu_XR\":\"chat_sessions\",\"ewDp8c4XuPQHsmcZkYlwj\":\"chat_sessions\",\"d392opE0cxvTfYDXN7BMN\":\"chat_sessions\",\"c30byeVZ1vDPsYGqICIus\":\"chat_sessions\",\"lBOgGN_vipoAM7xUtz2Hb\":\"chat_sessions\",\"Yoa1H9P5jpJX-kSCeYCrv\":\"chat_sessions\",\"hDDILdvhm3DC1npwk_1dz\":\"chat_sessions\",\"h_dGPwfINLsizVrLJr2YM\":\"chat_sessions\",\"o8TGF4MrioTKsWDB2wkxt\":\"chat_sessions\",\"Gfo953M5TBGwrHJA1i5Io\":\"chat_sessions\",\"_Aw1gcDGuBmThkphMazhd\":\"chat_sessions\",\"QtV1SXdDZhZVgVw_C8rzs\":\"chat_sessions\",\"UEJB0ijlYPkzTp-3gUC9s\":\"chat_sessions\",\"MFmhRq5WhtXF8IlHpEP9j\":\"chat_sessions\",\"BWGFfUd4YiwwgFaUQF-sE\":\"chat_sessions\",\"A3bf21f04TogU48mbxZ3H\":\"chat_sessions\",\"QBZYUIPLFYAMn7d-Ilb-o\":\"chat_sessions\",\"t1-MFjGZYqUgrT8tw5Vak\":\"chat_sessions\",\"mLv6-FKu5m-e1kJl10KUR\":\"chat_sessions\",\"E8vWweuH4Y_l688kji_w9\":\"chat_sessions\",\"ttrR4NXNYDYWkdujKhttX\":\"chat_sessions\",\"_fBQhK3dxp-RprtzNXNza\":\"chat_sessions\",\"P3bB5iiz6COl0xy-nV_7P\":\"chat_sessions\",\"1oD92fx8HQJCuxvhkHcPk\":\"chat_sessions\",\"o8D31gej5btSGhjk2xguL\":\"chat_sessions\",\"YsbAvzNxtC3FMbW1_9kom\":\"chat_sessions\",\"nqeOZQrr-vawqUYSOkomC\":\"chat_sessions\",\"AkhiUzBAqv2l2IVIgpfsZ\":\"chat_sessions\",\"cmtVtu2mgURKIAzM0mbH_\":\"chat_sessions\",\"h2XjzeAQVWfxx2d00Q2Dm\":\"chat_sessions\",\"3RZN7xYLEjKRMYpDUYSkQ\":\"chat_sessions\",\"rUSnTg5t4vsDsDk7SDNj-\":\"chat_sessions\",\"wABLUA27FVILzKjyovGwb\":\"chat_sessions\",\"C_EQniM8bNnKa3Ywmh94j\":\"chat_sessions\",\"bSA5UPu9y1vPckiweBHRJ\":\"chat_sessions\",\"WOmftcbNfj0VcBk8qm5OC\":\"chat_sessions\",\"X1oG8NaDspvbCfke5m4lo\":\"chat_sessions\",\"a4hTdsIb0WBNjfgPcd9A4\":\"chat_sessions\",\"y5Kdo0npWIa-urYp_FUu8\":\"chat_sessions\",\"rILn30hitJfwUVd1tuXf_\":\"chat_sessions\",\"znpdiDJePvBiaVeFBxg-v\":\"chat_sessions\",\"HlkECips8XwQsodyA4ZNL\":\"chat_sessions\",\"hqRCdZur4FnEezCWXRrVb\":\"chat_sessions\",\"YRyXiJ5QuLXn-4mouRZmj\":\"chat_sessions\",\"Bg4so5NW6ao0YSLxWbaxV\":\"chat_sessions\",\"DWNAeiz3Fwajb7Hoj0GKT\":\"chat_sessions\",\"Q6Wu3QxofVWPbOtf-gVrY\":\"chat_sessions\",\"qCE8si7rHB1kgkEJv-CKT\":\"chat_sessions\",\"jGc8l0e7dTpSJlWR7sSob\":\"chat_sessions\",\"_HzpLg2qLQcMdqHKcJKWn\":\"chat_sessions\",\"LEBTQfreSXMbb_EDGsddQ\":\"chat_sessions\",\"jOv_YJO_MTiJS2M7cTQUV\":\"chat_sessions\",\"DjACE8KEgFUZj9MOSSx55\":\"chat_sessions\",\"5mOb6RjDzzYqYiYyR9E0G\":\"chat_sessions\",\"maes_J4bC6LyPNl6jZV8M\":\"agent_preset_messages\",\"i2_Ikk7v2VErkueUnGmjT\":\"agent_preset_messages\",\"t5BrNx9rlhe_ssbimNZMu\":\"agent_preset_messages\",\"LjY69zNPBf-S4iKWcJzWT\":\"agents_metadata\",\"ePgZOOB5OJJb2EwMuy0zL\":\"agents_metadata\",\"XSNQ2VDjr9Y0SrbPxS64b\":\"agents_metadata\",\"038JgaJHsqchHb4UVo8Ts\":\"agents_metadata\",\"qJrIWRriMclOIcIjPR6Oh\":\"agents_metadata\",\"ZWLqvZfiJpx86uSgJOl2A\":\"agents_metadata\",\"Fg_JJHfaCyQsBlveYWYIt\":\"agents_metadata\",\"fvKZ9V-3Rrmp2GMO4qInI\":\"agents_metadata\",\"yk8Y5tZnAbYjprdWbnvgE\":\"agents_metadata\",\"DsIkzHHECa5Lkyu5dtrbt\":\"agents_metadata\",\"-7xGKooW80Qa4IQlxovHk\":\"agents_metadata\",\"bpsgvRLn_BHAAm3xUB6j5\":\"agents_metadata\",\"d8w2Srgz-eZglmcZrmXau\":\"agents_metadata\",\"4XK1ENuItP0w0n511obF_\":\"agents_metadata\",\"1RQmj18MSuMkFbexypg2l\":\"agents_users\",\"H-MUXWjIIpHirHesYtM5n\":\"agents_users\",\"X7RLKuj6dZS1NYHPa3CP0\":\"agents_users\",\"EtoDSlJryqFOMgZKFxPE4\":\"agents_users\",\"DczyUUhzVvS_OdRZ-Aj90\":\"agents_users\",\"6CsX5RHV5820XHvgKN2id\":\"agents_users\",\"85nx1Kmy05t0lOrKC7KII\":\"agents_users\",\"T1CqwtSu90l1_nWzf-9fy\":\"agents_users\",\"qhFVZRe7NqZMIq1mCVEbg\":\"agents_users\",\"8lIMvY7b1L7I9dt8F6iPQ\":\"agents_users\",\"xE6AjwFLOj-Cjx5B133yt\":\"Agents Tools Users\",\"O86W3TFnJ7ONCsoiQ-pGt\":\"Agents Tools Users\",\"yw4kd73PqfxxryhljpJbH\":\"Agents Tools Users\",\"I1ZpZh5J1pT0JIfboAEo2\":\"Agents Tools Users\",\"-98ria-oVT1GTzK1du2G6\":\"Agents Tools Users\",\"6RPTuvUJd_KaJ1Qu3RHl3\":\"Agents Tools Users\",\"QGbcp9WEGwVUSlDNHYO22\":\"Agents Tools Users\",\"BLj74rYaHbNHW1UCawBh9\":\"Agents Tools Users\",\"9g5J8YXHvTV9w7XMsdcVd\":\"Agents Tools Users\",\"toQmjKeeWX71OPjlhYWiu\":\"Agents Tools Users\",\"dgIzqheJ2J6dHjtaGHZ6V\":\"Agents Tools Users\",\"SLmNv-LV-cJKTjap-64uJ\":\"chat_messages\",\"fDyiaJk_cX8iPAxuDOOB-\":\"chat_messages\",\"3euPAXpP7r3NHYY19q_HG\":\"chat_messages\",\"-jv87k1mdVwI2U5_NSnta\":\"chat_messages\",\"fN8oaDT5PlmKABq5MCgg5\":\"chat_messages\",\"TKTOC6PZTIKV7Ij6R4vBK\":\"chat_messages\",\"LY5ON94w1rXUTZQUvy_Ep\":\"chat_messages\",\"0c3zy9_fyhi6EiFsLxs3b\":\"chat_messages\",\"15ClnZ-EGURTogjRavNcq\":\"chat_messages\",\"jRjm7B6keoEDLWE0jFCrP\":\"chat_messages\",\"4_JX_njAPAo2_0NzA3xNZ\":\"chat_messages\",\"KXccp_XBI8iahirFM9h9E\":\"chat_messages\",\"b-PhlRThK_QDfblaAjfou\":\"chat_messages\",\"hCC8X9S7MLTEa1fez3fyP\":\"chat_messages\",\"mz3UXiIKmZSpvLYDhjAM5\":\"transfer_queues\",\"5lSTi_nVMs8MCfMqZfpOZ\":\"transfer_queues\",\"9AV3DZpifsc5h0hQRWyQi\":\"transfer_queues\",\"nv36O_QFJzRmmxX8uGjhg\":\"transfer_queues\",\"KNesKV3JcCeFSacCuLjae\":\"transfer_queues\",\"pywp7gyljUyLbmbw6iDbn\":\"transfer_queues\",\"L6VNbXSUlmh90DMLCa8q2\":\"transfer_queues\",\"Gx6pd7ZM5N0BIahawtZGw\":\"transfer_queues\",\"Mj2cfCtUmbr_IL9mLk4PZ\":\"transfer_queues\",\"bKj_NjT55d4Fix2jUnQNS\":\"transfer_queues\",\"8xZiXjMNRHdeVSgJgXywV\":\"Modulos-Documentação-Atendimento\",\"Y4yjtKxc1v-M8aemq_3H5\":\"Modulos-Documentação-Atendimento\",\"9E3rBaPzoSSA-UdShhbdg\":\"chat_surveys\",\"z1iQ24G4CTnn5UC_0ZH9w\":\"chat_surveys\",\"qV3mxP0h5cI7q7ELs0HF3\":\"chat_surveys\",\"sCA8hegfELxymLyC9zxgx\":\"chat_surveys\",\"a5cQUKa_Ix0m_t0W-dShd\":\"chat_surveys\",\"Alg2dzf8hAYzwLv4OYtn4\":\"chat_surveys\",\"Nk9qjr4zYtgmKrQ2GBPPA\":\"chat_surveys\",\"Xh6YV_K7bqwTrFwk114Et\":\"chat_surveys\",\"icJL8fNFwj68TGpOtlXaE\":\"chat_surveys\",\"0ZhXO-OloAf0ye_nvIi0Y\":\"chat_surveys\",\"ujDWrMc1jANYrCpKqbRzF\":\"chat_surveys\",\"oCR9E1mUo-MXgzObs8r1Q\":\"chat_surveys\",\"A5MXoXog2BiElCob1D0pU\":\"chat_surveys\",\"KE4umlgc2aV5_vhCRE7QX\":\"chat_surveys\",\"m6oAKN8QOnPSo_Ffc_Z05\":\"chat_surveys\",\"JXQpLx40EsOC-l9B64bc_\":\"chat_surveys\",\"W9bl1veSqEENnH4ROM66Q\":\"chat_surveys\",\"bA5kg89X4mRQhSU0D6Hj0\":\"chat_surveys\",\"68hak57KYxBW1NEvoECcr\":\"chat_surveys\",\"Tk42dVWLxk2QsbhlCvsbk\":\"chat_surveys\",\"5Q_a2YT_TxdkD9_FOqmoj\":\"chat_surveys\",\"xLzG_Kg73bJ6URDA_rDYn\":\"chat_surveys\",\"GSWFMZl8I33Ju2iPmLRT7\":\"chat_surveys\",\"vwtLsLx8BclkyNhkyPJqL\":\"chat_surveys\",\"4_4I_6QKhjnKgf2TtXEp9\":\"chat_surveys\",\"VasSfx7gPoPp5WNakzWKD\":\"chat_surveys\",\"OyxFrynz5V4gqLn2QF7_u\":\"chat_surveys\",\"4fCm30wzuBx1EkS-kkVi2\":\"chat_surveys\",\"-qIEb7sWhxUInJs8mjk2Q\":\"chat_surveys\",\"9OR3fFnhlHdaPEk2jJFXw\":\"chat_surveys\",\"Pl9Xn2aiXv3E3emhIHpFq\":\"chat_surveys\",\"6B9UinarHQKGNh4n8W3eK\":\"chat_surveys\",\"p5LgerVyNyI_qsMtWrDVB\":\"chat_surveys\",\"iLEnF7jaLpxFtnEoGzAmf\":\"chat_surveys\",\"Ucy5rj_KJsjFvyqtg6NY0\":\"Modulos-Documentação-Supervisor-Atendimento\",\"1lwZRZgvL199Dp4KCu27j\":\"Modulos-Documentação-Supervisor-Atendimento\",\"CqSALqg7f_W_s_fzWoo_H\":\"agent_statuses\",\"NqsdtqK2nFDvcc2h1VC_R\":\"agent_statuses\",\"fVRBN-ev_k6BJ8j8amQbn\":\"agent_statuses\",\"H5xtMWnip8C7MqTEKaOZs\":\"chat_tapume_surveys\",\"nMP58rFQ6TKaMIg4NHvoY\":\"chat_tapume_surveys\",\"M6g_FMuTFuc6VSfMcEDGr\":\"chat_tapume_surveys\",\"x9Ij7g0QuquqTW8ZzY0sF\":\"chat_tapume_surveys\",\"3YzsrIyrCZxsU4lUSsV40\":\"chat_transfers\",\"IMuPFgdPnuGBMMJz7gvua\":\"chat_transfers\",\"SJ0XGfl6pGjNIHo8Xxl2v\":\"chat_transfers\",\"ML824TElJ3RyuJaD_dVd9\":\"chat_transfers\",\"28oTESKi05XRJEoWOf017\":\"chat_transfers\",\"3OsPiNI8N0PqYHwI1-p5y\":\"chat_transfers\",\"gC2Vv_5YI5QyZaNkWsMmj\":\"chat_transfers\",\"4iZ9fAXLHR7C4hGZkY7aA\":\"chat_transfers\",\"lmmc6ru9ofYGCVBrWwXF4\":\"chat_transfers\",\"wJERMSPwPN8omdEr3h2DM\":\"chat_transfers\",\"rkBUbOOW2D-RpHZn8Vteh\":\"chat_transfers\",\"GTroAOI8boz8l7D4i9fq1\":\"chat_transfers\",\"bQdn_BJPY5BdCCT1Bc4Az\":\"chat_transfers\",\"ge_5sPCgj7mMqJT_fT4Wr\":\"chat_transfers\",\"UUVlZGiZBDcJreRCAVxgX\":\"chat_transfers\",\"fE5LZh-L724h-LBxktr6y\":\"chat_transfers\",\"K8CvPqcPDJdFxBlPd_XQY\":\"chat_transfers\",\"5gyDA5VyRg3tyMPMG0U9w\":\"chat_transfers\",\"wLJ1a0bSZqIUsREZjTjBO\":\"chat_transfers\",\"qUIdz-sjA7hCv00Dq5dSu\":\"chat_transfers\",\"y9757YYggYbWh_dNrqvXi\":\"chat_transfers\",\"GqPSEAdTJDCSgPOBmxpZk\":\"chat_transfers\",\"QmVUhNC2Ou-CQyekj39y-\":\"chat_transfers\",\"TFcew_mlS8RtpGyW6euyW\":\"chat_transfers\",\"QrYS6PwuV3r-XQhLj3Lry\":\"transfer_settings\",\"yxlb4DMp8ENnyr-nV1--O\":\"transfer_settings\",\"Q9egkm3CNc4ZR_nQn3kkJ\":\"transfer_settings\",\"FMZd-g28py86fWglUczOW\":\"transfer_settings\",\"zIZ3z5GmgMA-RW4kpzOVk\":\"transfer_settings\",\"ihO3aL2sivoJNc2aw9T1n\":\"transfer_settings\",\"Ie_ISguTUHnYVbBWRWxQr\":\"sinch_steps_sessions\",\"KYGAYStTDgxH479kBy3QC\":\"sinch_steps_sessions\",\"MFWTVDitkGbr7ENR-kRwB\":\"sinch_steps_sessions\",\"K6pRAQgJN6tCGhnbdXviY\":\"sinch_steps_sessions\",\"g4BgnFCIf1XoBsIM0t94m\":\"sinch_steps_sessions\",\"04elkD5HncP367-BsmoX9\":\"sinch_steps_sessions\",\"q0iatRk44sLxhNRuAhtT3\":\"sinch_steps_sessions\",\"ojZpd1mnFRZ2g_1pOcfl8\":\"agent_logs\",\"eqkAvHVk6DX2xGRk_KVxS\":\"agent_logs\",\"Ge6i1ZIQhGLEi5Qh9n982\":\"agent_logs\",\"TSKbBE3Qlj4eMUqOJkFn6\":\"agent_logs\",\"shcf7wfyAH2Y4tx78ZqS6\":\"agent_logs\",\"Qq9megeRksFRO1CuMKr3P\":\"agent_timings\",\"eVBYSEqcGrcaiP9bHlpBu\":\"agent_timings\",\"R14fadMIZbhK70MjbuWPU\":\"agent_timings\",\"oJjw__DWcGSsfsLUHtSZO\":\"agent_timings\",\"mkbAgmdYVCL9_EMxYG4Lb\":\"chat_pings\",\"TyRsjgSwJYm6_93_XH5ep\":\"chat_pings\",\"ptNXe02qYQ_LeFI4TqNtL\":\"chat_pings\",\"qq1dgIZncfRiUevPZVv3_\":\"UseCaseSteps\",\"Uci7c8cm8hbW4KDozdKul\":\"UseCaseSteps\",\"3f_YFH-bS6u0eSZYlTEe0\":\"UseCaseSteps\",\"xcVTMBwR26bWQtPCjAVt5\":\"faq_requests\",\"irU0JBxZKauF0x7TpjNvz\":\"faq_requests\",\"WhNxQ0zFHIQApBVj4LyP6\":\"faq_requests\",\"i805VL27Sl_wQKu2yvi3d\":\"faq_requests\",\"BlOsu9b3LEnR5sxfheRJd\":\"faq_requests\",\"tCkTVP0zAVd9dUbeDHrXy\":\"faq_requests\",\"zshfnVjwCZunheJQ7kiIU\":\"FAQ Users\",\"cJ6b-suQNT8TY7MgxDwPk\":\"FAQ Users\",\"gTH5wa-_swRkxfhcoU5QO\":\"FAQ Users\",\"pq1AUuqEA82kInMuwxoQT\":\"faq_request_updates\",\"4h0bK-3oQ-cM4Wlbn23NN\":\"faq_request_updates\",\"5dEAo10N-Ids1GY-xPBxM\":\"faq_request_updates\",\"XY_aXfpV3VAyNPVwzOTRb\":\"faq_request_updates\",\"6EJjSGsWi4yG8g9OarbBl\":\"faq_request_updates\",\"jUn-ddUehtN8SfxgR93ts\":\"faq_request_updates\",\"yz6pQrrR06MhwCgJ6bjFH\":\"FAQ Users Areas\",\"jGmBCtT4_wYfi6a93VYpw\":\"FAQ Users Areas\",\"FvK6UoUuVhCpGMdiLCoZT\":\"Ecuador Admin Users\",\"awmvv5yP7paRzHVrk3BWl\":\"Ecuador Admin Users\",\"dhASLUQLNJNMwVe1-3vtw\":\"Ecuador Admin Users\",\"jEQ9c3OKw6ShpC4M5a_sa\":\"Argentina - Pendencias\",\"-AsBS4q0GVfjL3kewEz6l\":\"Argentina - Pendencias\",\"cnZcJ4tFFZ5kiMk7hbR9O\":\"Copy of perguntas-home\",\"j7NM4WrnDLSTUYDKrt9h5\":\"Copy of perguntas-home\",\"vwEWwHQ7m5weZ4UGicks4\":\"Mario-Message-History\",\"x4fWl_3_IkdysEl6g7A_X\":\"Mario-Message-History\",\"8jiJA5fAvTozWenJpeeHq\":\"Luis-sessions\",\"4gj4QF6JQwlxyKWUl8t03\":\"Luis-sessions\",\"UZwfBvHvjawXCXzmwVCkQ\":\"stefcurrentsessions\",\"LEv-iCZDgzbMKr4kfcgTo\":\"stefcurrentsessions\",\"tOC1l_ZUVLHY7v7jYyK-Y\":\"Luis-Data\",\"YfLuRq9qvhtCIUDoqlb6_\":\"Luis-Data\",\"qicSv-Up3RPA2V2CrCRhK\":\"Juan - useCases\",\"EF1X4AM5EA9uRKTArjTOC\":\"Juan - useCases\",\"ckbKE1fKjiKguj6ILHHl7\":\"codeplus_package_table\",\"xTQLN3uU5v-FRplor6V7v\":\"codeplus_package_table\",\"o4aM6vX9NeoMtCuhasmb0\":\"mx-beedoo-faqs (Old)\",\"whHxn63DSYKreTie-PvnB\":\"mx-beedoo-faqs (Old)\",\"wTaI3Klg72WdtaZ3qSi0o\":\"agent-tools-monitoring\",\"NWqwS1Sv6g2bGr1ArVVh_\":\"agent-tools-monitoring\",\"PNkqnA6gVKRTpeDS_07JO\":\"agent-tools-monitoring\",\"8TBNcHi2f1K2BP6Z2AmtB\":\"agent-tools-monitoring\",\"3bjoKIXjN5jgkVgktn_HP\":\"agent-tools-monitoring\",\"OEqsoobUuPMPveDTdAf5L\":\"AnalyticsDataPoints-D2\",\"xV6OLYmtNZu72zKMajYmM\":\"AnalyticsDataPoints-D2\",\"Hb8L9GMMjC5qX8z6iIIx9\":\"AnalyticsDataPoints-D2\",\"F8SEnSImA-c9fobmv0c4i\":\"AnalyticsDataPoints-D2\",\"BMLGj0UX3xAxq69DbhbZ8\":\"AnalyticsDataPoints-D2\",\"eCn1OvV41WiVS2qrkr6xs\":\"AnalyticsDataPoints-D2\",\"zdL-a5kftjHSQGjajNYb4\":\"AnalyticsDataPoints-D2\",\"u0iIup-sX78gePlof9ZY5\":\"AnalyticsDataPoints-D2\",\"kUJhVyM7Fbv1Mp_pKWhiN\":\"AnalyticsDataPoints-D2\",\"VE51cePupS4AoOZcfzie4\":\"AnalyticsDataPoints-D2\",\"K0V6prUyKjx4soV2O_jlL\":\"AnalyticsDataPoints-D2\",\"iGh4jdk4fCnnwyglY8-YJ\":\"AnalyticsDataPoints-D2\",\"ATfwUDt7d_iwvBxOPYkkO\":\"AnalyticsDataPoints-D2\",\"dAJQK4BHqVH560alKgyeP\":\"AnalyticsDataPoints-D2\",\"T6JJZnt6N2I9f64xh5JpA\":\"AnalyticsDataPoints-D2\",\"KBUoMpU4sEAxrLPyMPHQI\":\"AnalyticsDataPoints-D2\",\"SHLdMrFy0ebCxKsWIV0io\":\"AnalyticsDataPoints-D2\",\"rzgPCYyW6OVaRcj-2WKy5\":\"AnalyticsDataPoints-D2\",\"ASef1m5pxyqsd3ps3Cz5g\":\"AnalyticsDataPoints-D2\",\"XKBCH3Swfg1ZJEAtSLtGg\":\"AnalyticsDataPoints-D2\",\"bsQpkMSg9DOcWd_vJCGeY\":\"AnalyticsDataPoints-D2\",\"UK1MoBQnqOn55VUHq27YX\":\"AnalyticsDataPoints-D2\",\"jJq1q7z0NbC7ccukqf2Wm\":\"AnalyticsDataPoints-D2\",\"DwzzkuSYCHNTJ6X2Za0om\":\"AnalyticsDataPoints-D2\",\"IH3PsPfmgfhoO9Wwl7GnX\":\"AnalyticsDataPoints-D2\",\"z-wq-FbIUGepFZmJ6ats3\":\"AnalyticsDataPoints-D2\",\"RLFelldt62C8PsIfCUKHh\":\"AnalyticsDataPoints-D2\",\"gX-gVflIIzcfQ_oHFrYyG\":\"AnalyticsDataPoints-D2\",\"jliS0oUnkl55o1mzFcYhS\":\"AnalyticsDataPoints-D2\",\"44rAS9jmrG1005FaN9oiI\":\"AnalyticsDataPoints-D2\",\"vtasKfsfDmCoKvSNVPwxb\":\"iterate-queue-recursive-job-table\",\"zbu3TmnCNQUVsxkSqlX5Q\":\"iterate-queue-recursive-job-table\",\"PC6U_1_u0euNntML18-72\":\"Autohealer Fila Table\",\"5hl6C2D0TPhAWSiksMK6W\":\"Autohealer Fila Table\",\"aC3j9dC67rqOn1cdZPbac\":\"Autohealer Fila Table\",\"jsVFQ5q7h6h4-8EMkF_af\":\"Feature Flags Table\",\"jNl90EUcAsXjTns_ffGkw\":\"Feature Flags Table\",\"-k9J0VR0Qwnhy3J6iPOGe\":\"AR - All interactions - Forms\",\"SZmMUQjCQVUF7IOinPys3\":\"AR - All interactions - Forms\",\"gEjmr7rOdDeHlA8mlQTAc\":\"AR - All interactions - Forms\",\"mpY2hYuTiQehDC8n_NgKo\":\"AR - All interactions - Forms\",\"2ogV1hMmzR3G3A9Iv6DJU\":\"AR - All interactions - Forms\",\"x_CGgVnaJcoXFRnZ7gB5O\":\"AR - All options - Forms\",\"U-N0pkipl-XoJy7DT4XVt\":\"AR - All options - Forms\",\"j3pWVQs5WebJI5iUgDlNB\":\"AR - All options - Forms\",\"NslFL5Syl9NxV16tJy3QM\":\"MAIA + AVI - pruebas - TempData\",\"-tljEFxBJxzC7e4l5C_5M\":\"MAIA + AVI - pruebas - TempData\",\"DOq7tLR-pL6eMPwKUOylm\":\"Temporal_Inside\",\"DOq7tLR-pL6eMPwKUOylmDataSet\":\"Temporal_Inside\",\"8fTwjIcFBArJTPNYB3glf\":\"AFV-LOCATION\",\"MAHPDAHBRMe0qkhTyA9l5\":\"AFV-LOCATION\",\"W_IoN5n96o2xPHV1ONGoz\":\"AFV-LOCATION\",\"6YiF65z4GoSeqJ8KWcmdc\":\"beedoo-faqs\",\"rLhjVDf3yOomashE5TICR\":\"beedoo-faqs\",\"R0Q1i3twPMu3l5O5I81kw\":\"beedoo-faqs\",\"dK3wTn30LNexGCBoZWTWD\":\"beedoo-faqs\",\"w6IcSHa7RvZwt97136IgH\":\"beedoo-faqs\",\"oFYra06X4M3715ttQ5mP8\":\"beedoo-faqs\",\"AnK6ZYeBIWUAjU7eE_rje\":\"beedoo-faqs\",\"c72bQ8o2m70MDxRtCzc1x\":\"beedoo-faqs\",\"3EZwbu4DMquuTo3hsKMXZ\":\"beedoo-faqs\",\"CKHowF2sRR_7uZg8yWR8R\":\"beedoo-faqs\",\"aBEEDuSPs25NVHCjxLh2R\":\"beedoo-faqs\",\"bvMtLki_mHkmStDu1xu7b\":\"beedoo-faqs\",\"d3B3cmU3sKXZojfDSnN8V\":\"beedoo-faqs\",\"m5ZQrM5X0OhibGbrAh-IC\":\"beedoo-faqs\",\"hlN8CZRCASELzkhv0iNMI\":\"beedoo-faqs\",\"dJqeY_HW-iUbxhnAxfLCO\":\"agent-tools-surveys\",\"cB1gq-RN26JQ6-Q9NE36a\":\"agent-tools-surveys\",\"HczDUlOgBeOk7z_Is4qHC\":\"agent-tools-surveys\",\"y6_EJiJnM8n8A2_KfRQ1m\":\"agent-tools-surveys\",\"3QPeMNf2ijUvdN4o8CReK\":\"analiticsdatapointsforms\",\"rnyYOSSl9C2umxvZyDdVB\":\"analiticsdatapointsforms\",\"Yw7PTM7IIQvsz_vuyQxdI\":\"analiticsdatapointsforms\",\"qLIbZiyvohljgX9_15d2W\":\"agent-tools-events\",\"mWgRNb5KZabt3BnnWDUqs\":\"agent-tools-events\",\"K6aM_zOwRiIxZTjVuqIiO\":\"agent-tools-events\",\"4YF64xYVf6ZmFCPp4agJk\":\"agent-tools-events\",\"xHZ9cc_FpkEzaWWKpl3Rx\":\"agent-tools-events\",\"peSZeE6tp_wBKNgDpUyys\":\"teste gui\",\"peSZeE6tp_wBKNgDpUyysDataSet\":\"teste gui\",\"VZ7KSWk5lQc8NDDgzpFSu\":\"test_loop_on_json\",\"BKNfsOb-pvwBxHzH7CZMX\":\"test_loop_on_json\",\"-lci4Nan7jQkleVaehcZ7\":\"word-tools-monitoring\",\"1Fr4SIxVVrrTkocJ6jUyL\":\"word-tools-monitoring\",\"nIb6l56ET0fyMwSqaxdb5\":\"word-tools-monitoring\",\"xFbRDScPQzCJSDbYPav0N\":\"word-count\",\"g_8_wpg__U_-ihJ4pSh3R\":\"word-count\",\"CN7S-6LL2XDqJM8qYE3OO\":\"word-count\",\"v7YYvzzAxEnfKApEJr-hx\":\"Reclamos\",\"-RAi6VPWJOVgyNPJl8VIH\":\"Reclamos\",\"cj5yhgQBORuEFnA8HayYn\":\"Reclamos\",\"83mS8jI7YitaXwUR_Y77n\":\"Reclamos\",\"CQC0gmiK4hccKBgK3Qu0w\":\"Reclamos\",\"nqsrzEe2l6i53peuYo40Y\":\"Reclamos\",\"acsdnbu0aivFUYbH9ZKKb\":\"Reclamos\",\"AljAFF8Y41ND_rgs4QegB\":\"Reclamos\",\"wwgkYoaHCQ6AVXEX3sFbk\":\"Reclamos\",\"wgLaaE-S0jWgfr9uJPpA2\":\"Reclamos\",\"lsBdlnDTClvfjyf62bAj2\":\"Reclamos\",\"K6qhJfUdv2of5SU7DfyhG\":\"Reclamos\",\"xCkcN0gl6CVWIaHjOxcV8\":\"Reclamos\",\"NxQe5hjpM3zUQ9Jc7Ys_O\":\"Reclamos\",\"-k1u-p3Qpz-OISp2DJMXS\":\"Reclamos\",\"AIoSiB4oPuGmoNl-q6DSQ\":\"Reclamos\",\"WUULFW9Z9kXDEDWVpCaM9\":\"Reclamos\",\"cg-NTdKM6Wf1VIPJC-N9v\":\"Reclamos\",\"ppz90GdPZGdzy60UycDP_\":\"Reclamos\",\"uTnBcElaE1LVzLHKNHVog\":\"Reclamos\",\"LFyN67aeh6pmT2AR62JSS\":\"Reclamos\",\"6JUoiKV-4GhJGXEDq-s0m\":\"Users-Avi-Gestion\",\"UQSI2K3srRRatRzW9bAWn\":\"Users-Avi-Gestion\",\"LFpHQWpwfUNurBZ-Dp0ut\":\"Users-Avi-Gestion\",\"u78Mk-VgU__GZ3nusHOM5\":\"multi_usecase_tester\",\"d63-saQN8kfciaC2jdwN8\":\"multi_usecase_tester\",\"xr1lUSgFPIgaKUJ52PpjC\":\"cruce-estado-pedido\",\"_PgYVj8hPBMe-gMyjT3Kl\":\"cruce-estado-pedido\",\"TgtXV2LHkIZpUdB2nL5F1\":\"cruce-estado-pedido\",\"ckfAtcX98dpvWNjbZLF3P\":\"cruce-estado-pedido\",\"FNx0gg0FUUdR99JU_hzoa\":\"beedoo-interface-ds\",\"FNx0gg0FUUdR99JU_hzoaDataSet\":\"beedoo-interface-ds\",\"YQqxFfPpow9OFqr6drPyE\":\"external-transfer-users\",\"T-cCtftfBp5ZlJh1zcQBG\":\"external-transfer-users\",\"-VLqGm0wsaQUhRQxLiDKr\":\"external-transfer-users\",\"DTarnyooO9Zts6f3aUrD_\":\"788_ds\",\"9xhO7OzWTKl8oQ-SydqLU\":\"788_ds\",\"pO6lbxUr5bOD_ec7ndhU6\":\"788_ds\",\"qNgsNLfrx0T18MS2ygum0\":\"DataSalesAssistant\",\"Iefd1Dsyc_LIliY9jPe0n\":\"DataSalesAssistant\",\"y98H13Gy-eXhvkMlGtyNA\":\"DataSalesAssistant\",\"WcxdGfxuvLwHARkcTIA4c\":\"Users Auth Table\",\"7e1XEAhJRJViyBqfRf_0S\":\"Users Auth Table\",\"JVWOmHWxizG5Bz3knSF3P\":\"Users Auth Table\",\"nh454JZc0N8jKaiSbWutH\":\"SubmonitoringForms\",\"sCb5Ac76kaRINgLQRT86J\":\"SubmonitoringForms\",\"UE4Kb961FSP1wAvcwxH0o\":\"SubmonitoringForms\",\"ig1hdgk_G-doTBPc86pVt\":\"SubmonitoringForms\",\"V4AfVyYlFiHE1z-eihUV7\":\"beedoo-ecommerce-faqs\",\"VfhEC7yoxzVgIsnaYFlb_\":\"beedoo-ecommerce-faqs\",\"ijWsRAQhrnvZZMtOxiby1\":\"beedoo-ecommerce-faqs\",\"6bq2lvwUaSG7bpsJlIUub\":\"RPA-BOT\",\"jMKfOZ66UkQpz2vt-sSqD\":\"RPA-BOT\",\"Tm9zzXRWQ987LX86XGJhz\":\"RPA-BOT\",\"r7c_R0Pq42eSls0ZHUFvH\":\"RPA-BOT\",\"DsvcmfcEdh--oULxsT1DI\":\"consultant-code-ivr\",\"nXMiwTK56Y77ITlwfV8oz\":\"consultant-code-ivr\",\"6j8EDvyRBXzkKaaxO4QrY\":\"gerencia_ar\",\"-eyjjQdR3jGzvAe8wHE6U\":\"gerencia_ar\",\"bt3tsMchwpVChqMG_yavh\":\"API_Execution_Central\",\"bnd5Bx7iA70PamX584g4M\":\"API_Execution_Central\",\"4V0yZwkJAzHvFZiuPmEfF\":\"API_Execution_Central\",\"pgNPySOMNwM2bl48w4wTr\":\"API_Execution_Central\",\"K6vtYxGq21IyQLCHOq24r\":\"API_Execution_Central\",\"znbq3rmEf75Mg0pJO8bGn\":\"API_Execution_Central\",\"zW7_Wk5eFA1U791scb7YQ\":\"API_Execution_Central\",\"haIujUPNIivJ5D8-GDbzk\":\"API_Execution_Central\",\"G9bPAOZDUJedGOBtiHJlY\":\"API_Execution_Central\",\"iIUwGkbFwg-LCJXd-UEyf\":\"API_Execution_Central\",\"NPYaf5CqgTKcctGn4860c\":\"API_Execution_Central\",\"WMc_Gg7E1YoCv7MLAUWwp\":\"API_Execution_Central\",\"T5gfPJFyvBsdxEB1VXG6m\":\"API_Execution_Central\",\"-XkMR8_PipkwSdmhW0byn\":\"Execution_API_AVI\",\"a7vOg7extkRt9FtyD1Ugn\":\"Execution_API_AVI\",\"gO579xYGZMqQq9Mmc4xMD\":\"Execution_API_AVI\",\"a96h5sWr0mBGdNNgLo9UD\":\"Execution_API_AVI\",\"UEljrYMGlBbJxQPqNAaHd\":\"Execution_API_AVI\",\"wI0yt0noWa4kdIlZBQKQH\":\"Execution_API_AVI\",\"zLYu1UYNQbDeK49rBP8DR\":\"Execution_API_AVI\",\"uQvH_EwEznUkX7JroieOE\":\"Execution_API_AVI\",\"7YJdM28quKbQyBw8KE_aA\":\"Execution_API_AVI\",\"Rayvtn-L2au_JgA90xDrh\":\"Execution_API_AVI\",\"sMzIruzDv9tnZOOj2kVfj\":\"Execution_API_AVI\",\"udbim-n7L9QUfWRVNDJ0V\":\"Execution_API_AVI\",\"sBt1PGlDTaeu3fDsx02-h\":\"Execution_API_AVI\",\"1a-5STGu5fYRrQRkEHlL9\":\"Execution_API_AVI\",\"cOJ1Gn2ke9YVn5ESqKgRY\":\"Execution_API_AVI\",\"sfE2uVR_5bLCjhFQ93Sin\":\"Execution_API_AVI\",\"RqiCq3JHfgXEYIZSHbgvn\":\"Csat_admin_filters\",\"ujNE-yVzYkXDt3OdS5hug\":\"Csat_admin_filters\",\"ZL6ces4sdKpk7umyVBvdH\":\"usuarios/hispanica\",\"JR-LDSL40aUYET6lrQIDN\":\"usuarios/hispanica\",\"EvLz5aJm0RGpgOodoEXxB\":\"usuarios/hispanica\",\"ppUKoTP-czVM8-0RqtHMw\":\"usuarios/hispanica\",\"sX6C3jOkxXe-oK-dFi4nr\":\"usuarios/hispanica\",\"eW_cp7JiLda4o1gJhnTW1\":\"usuarios/hispanica\",\"GJKPuTqxFNAwGV6WQ-ft2\":\"cache\",\"CC3J_icGpd5_-_kJ1tTjc\":\"cache\",\"0bmyNuKMqxVSYnuSar8kN\":\"Execution_API_Forms\",\"GmhsTMW1JSF8HG-85okpS\":\"Execution_API_Forms\",\"N7j7a9oot_tFtpLNlpCDw\":\"Execution_API_Forms\",\"NhYX5Bw9PTwZIstF37Pk6\":\"Execution_API_Status-Order\",\"ZZFsBwMsqSgZaYE_apWct\":\"Execution_API_Status-Order\",\"97PZOYdaXL-mQs8Em9Aeq\":\"Execution_API_Status-Order\",\"PvFYbNNqX_YoxOPNzMvOz\":\"testemail\",\"PvFYbNNqX_YoxOPNzMvOzDataSet\":\"testemail\",\"ZRIyWno2QfkMvu2Kqdlww\":\"RPADS\",\"q7Ash6nqQktqYPpBxLS59\":\"RPADS\",\"xaFiSNmZZJpho5l1H-YOg\":\"MisReclamosRPATEST\",\"cOGnLajCvf4Qv9uIZ1AKu\":\"MisReclamosRPATEST\",\"LSwdxLdoWAqZtijTZqE7u\":\"keycloak-oauth-tokens & pins\",\"7r_Var-lGoZLtONW58J1w\":\"keycloak-oauth-tokens & pins\",\"0dO4fghiHwmClvtfSVdpH\":\"Identification User Avi en Mi Negocio\",\"f1Ncdfme2aNKquwccAyc-\":\"Identification User Avi en Mi Negocio\",\"VECOrUvxj5rn01wwJRnFs\":\"test cases\",\"YJh10RQ-ROJpl1DZNQ9cA\":\"test cases\",\"gV8RtCBN3fBDJW9pguaX4\":\"test cases\",\"CIaTJECYhLJD9FWEo0sdv\":\"test cases\",\"69Fg1zleDjov8FlSpiTDb\":\"test cases\",\"OXQrpKoh_HDSx6KavU6iT\":\"test cases\",\"LrYTLairLoWR17hp6dPbp\":\"Related-CsatCountrys by Supplier\",\"XcajC4VDybdCoQ4mUNgT5\":\"Related-CsatCountrys by Supplier\",\"-qjhScbnNWM9p_HMd3fjN\":\"refactoring faq data souce\",\"6t0lsngPdvPoKM4nZsfcr\":\"refactoring faq data souce\",\"qUETLalnZPym_IePfL2I8\":\"refactoring faq data souce\",\"_Sap-4AGe2OzHyWKSQV3W\":\"refactoring faq data souce\",\"rB5c5bZtrQ2tlasgKGaVj\":\"refactoring faq data souce\",\"i2d8TDPb_muWf59qfjyi0\":\"generate-answer-data-source\",\"BSFcPGYWyu5OfpquNxB9c\":\"generate-answer-data-source\",\"I4BG2EUpCrjIjOVdTxUsp\":\"generate-answer-data-source\",\"lCEMcuqCu3PiglB0EeU57\":\"generate-answer-faq-data-source\",\"0JZVJaAAXOt_MnNCmkFov\":\"generate-answer-faq-data-source\",\"n9PBWVAnuIc99EdwSTgXU\":\"generate-answer-faq-data-source\",\"QGVCgSseGiWtvSRuE9S9z\":\"generate-answer-faq-data-source\",\"Ghsf2YdfB2WV1dQamC9yt\":\"yadi tests\",\"WR_MvoPeDHZtcVORc9MSB\":\"yadi tests\",\"jj95nSCsjVQnC6M-PuJca\":\"Activity Log\",\"_HiwkqaE6tL140snRngx3\":\"Activity Log\",\"U-FkIWlFy8Tw_16kEw13O\":\"Activity Log\",\"I94TpZZUS9i315lH04LhA\":\"debug_juan_auth\",\"QDMiPWdvHXiPqIIxcVn5t\":\"debug_juan_auth\",\"8jNWG1d8GMZv75PPzYcGo\":\"integrity_automation_tests\",\"pidHmpJgQaZadLB_ERozo\":\"integrity_automation_tests\",\"dKhFLAHX-kvfaSuZWImjL\":\"tapume_data\",\"ENkf_NOvDrQ68FlBpcyH2\":\"tapume_data\",\"XTDyEVvr6pOf-NqhvsXfY\":\"integrity_automation_logs\",\"C4njiJBvC_-jYrMcjmfRd\":\"integrity_automation_logs\",\"Y8n4_m_Ngn5aa4qiEODL5\":\"mx-filtred-chatid\",\"W6_b0DUXCachjEGXyVw0m\":\"mx-filtred-chatid\",\"1t5p4Yw3hr5EUeJJcHE7Y\":\"mx-filtred-chatid\",\"6jP7UpCEBBTUNTJ6EDyE7\":\"mx-filtred-chatid\",\"58UpR6aXm1c73TYJUgG72\":\"cl-filtred-chatid\",\"-0xGMdPCystZCmgUjQAny\":\"cl-filtred-chatid\",\"UD3bbRv8mmBtN8HesCpuL\":\"co-filtred-chatid\",\"tAAkx5lvxET4P31uftsFQ\":\"co-filtred-chatid\",\"tHHTsPYsD5gAwbnjPNVF1\":\"pe-filtred-chatid\",\"VGr5VUWI_l8tOMGT4BlgL\":\"pe-filtred-chatid\",\"9fTC1m7f6l1bzu7NtDHQi\":\"pe-filtred-chatid\",\"Urs9ESzqkZSb88s7Bl2Rc\":\"ar-filtred-chatid\",\"Bpc5b-Ib3VHG1x5ykIfQR\":\"ar-filtred-chatid\",\"mnZ97WcDCei8yLn1X7fpg\":\"ar-filtred-chatid\",\"zs5uZQRHFPh0vF6SRuYe0\":\"ar-filtred-chatid\",\"qePcX_SakQd5PA_91dEWx\":\"ec-filtred-chatid\",\"KD7F3SmdgyrQwS3937frs\":\"ec-filtred-chatid\",\"vhrlBO9xhrYaxt8m4d2RD\":\"ec-filtred-chatid\",\"0Kl6j9YeJowSLoGajBwDe\":\"ec-filtred-chatid\",\"uclq0rSYc-5Q-0VJ9XWc7\":\"sinch-ar-filtred\",\"YorwlYy7MZNc_-mGS27F2\":\"sinch-ar-filtred\",\"fC6MF07TQz8VtO6OtfQZX\":\"cari-rush-filtred\",\"qIbYT3ytrJ_4mf5co-ZCO\":\"cari-rush-filtred\",\"T840JiI8gZ4G3ynoo7Oby\":\"stefpruebas\",\"1pYPi4zec9PSZQ90hjWpJ\":\"stefpruebas\",\"_jtImXwtyDSF3MHIcaN8R\":\"stefpruebas\",\"1DmgT9yjDlv5SnVwUg_bP\":\"stefpruebas\",\"bscDqFn_AFBlzGEpWCCAa\":\"stefpruebas\",\"FddcuPiV8rUEqVKUG8r2L\":\"stefpruebas\",\"0gXfQGRocfkibq1rEZZYT\":\"paises_configuracion\",\"dczCj7IlncrUmnKX4Uldl\":\"paises_configuracion\",\"6Q2vukZ3W0hLA4Fb55opl\":\"paises_configuracion\",\"uUjYdSIdatYwBeoVlvg9S\":\"paises_configuracion\",\"E4xqDeJPxV2rY0WW0hCzf\":\"paises_configuracion\",\"twdzekRafm4m2wP4H2of4\":\"paises_configuracion\",\"sIg6CY50DnTmZCt4UeQCT\":\"RoleAauthorizedContacts\",\"hk3St1Pf-gplEjwXfGs98\":\"RoleAauthorizedContacts\",\"EziykAB_ezPsQQ4CFKtMJ\":\"RoleAauthorizedContacts\",\"h1RaseWJBiAkS9HZamA5H\":\"RoleAauthorizedContacts\",\"ab2TnlF90uyNXXzBb9GY_\":\"tapume_activity_log\",\"o-r6n41Lpw7FkOr8ooU71\":\"tapume_activity_log\",\"k1dBmU2RODmDUg99N19pa\":\"Indicadores_Digitales_Forms\",\"5OpY9kOGNuA7HawDDRx9M\":\"Indicadores_Digitales_Forms\",\"2L5GMh7PsPGenY-YEgdLO\":\"Indicadores_Digitales_Forms\",\"0nGd0jPiO-SUxdDYuTKd9\":\"CSAT_Mediciones_Formularios\",\"P973ZckOBqviQY7_b-sx6\":\"CSAT_Mediciones_Formularios\",\"-qA-rqrBcLvMOqnF6pweT\":\"CSAT_Mediciones_Formularios\",\"QaaqPVfO2eQv98OXAyo6B\":\"CSAT_Mediciones_Formularios\",\"1om1K5xbvEPWxGAxc7iCu\":\"CSAT_Mediciones_Formularios\",\"a7Ql614hAWHLZpfeQpKoG\":\"CSAT_Mediciones_Formularios\",\"jBIBb1vlAy0PnZVBFl5Kf\":\"CSAT_Mediciones_Formularios\",\"nn0vAL21Wh7qQaSFCZPuR\":\"CSAT_Mediciones_Formularios\",\"E6XbKoN9EujWxgrLDxPJ-\":\"CSAT_Mediciones_Formularios\",\"yVFrNeYuIt1s2D8QkbISf\":\"CSAT_Mediciones_Formularios\",\"uBsqnjbkDkwYBQIYfUUNw\":\"CSAT-API-Logs\",\"C2575Mf4JgkbBKy9V8A1h\":\"CSAT-API-Logs\",\"gxZnOv1qEGmr9WsZFOtqy\":\"Cancel_Order_specificLogs\",\"W42eOD1D80_Ie1HIE6mpW\":\"Cancel_Order_specificLogs\",\"AR_dXo2lHzx1GFasdl_wl\":\"Cancel_Order_specificLogs\",\"svyxg5sCG6U1MznwlrEOp\":\"Cancel_Order_specificLogs\",\"NrHZJDfpEXTc85rJ6cZjP\":\"Cancel_Order_specificLogs\",\"u8bOSEWickcx5SceC2FWB\":\"Cancel_Order_specificLogs\",\"CLc_VWhtNK4BbrVEk1b6G\":\"Cancel_Order_specificLogs\",\"i9mNdVTuL9PvtSxGubeWZ\":\"Cancel_Order_specificLogs\",\"0H8BB07cc1XpIEjpVqYmI\":\"Cancel_Order_specificLogs\",\"S1V2f4AF2kScAR_iYDQOh\":\"Cancel_Order_specificLogs\",\"bkwnFzbCWV62XUE6hYmHr\":\"Cancel_Order_specificLogs\",\"rMnK_K9qC5_qq0234dBF3\":\"Cancel_Order_specificLogs\",\"9gvjjlnY27HXOctu1Ngx2\":\"Cancel_Order_specificLogs\",\"1P5pEF4jbFnwrfgAdSCgT\":\"Numeros Admin AVI\",\"pdzvHHQ_FSFtKAzjoOpiQ\":\"Numeros Admin AVI\",\"VI-X9KdbOWlrrz0eaw90s\":\"Numeros Admin AVI\",\"QjxztAVftpJ5xzvcYBksJ\":\"Numeros Admin AVI\",\"nYVgllPZYaCiFTE9FmMlT\":\"Numeros Admin AVI\",\"1KGPCM2JTo4xfBikEI8S-\":\"ALEX TABLE\",\"KKNYY7nVMG3D8InmqzFLO\":\"ALEX TABLE\",\"TimzI1kV4Vc0Z064qHe56\":\"Control Diario de Pagos y Ajuste de Crédito\",\"-zsqUgrV3ctSzAYMKBL3u\":\"Control Diario de Pagos y Ajuste de Crédito\",\"VkQO3ChilcahxwQGAEU66\":\"faq_suggestions\",\"buMIvYIgcp4Szwb4WjEAy\":\"faq_suggestions\",\"y2Gp88N1IKIHDdHp-0zZk\":\"faq_suggestions\",\"TbYj0-jRQkH9CUkeyhI57\":\"Copy of chats_gym\",\"lHiJ5ep-HQOvaVAKIoPc1\":\"Copy of chats_gym\",\"Nweqo1wYp1U-4O2dgwvhu\":\"Copy of chats_gym\",\"QimdIhidXNEUiCTlfGef4\":\"Reset log\",\"Omqhy3vKOb0lP9KRw8yxe\":\"Reset log\",\"cjL2bSPJ9K4Tr5b01RYv6\":\"New Data2TableDataSource (361)\",\"j4xG8pflakYr5u5EIgi2d\":\"New Data2TableDataSource (361)\",\"PhE7JmUXLX4YBHmVZPzn4\":\"New Data2TableDataSource (361)\",\"JEequoS4cDPBw44u0_I6u\":\"Teste format Table\",\"UIxUessGG2isDffz1djPS\":\"Teste format Table\",\"epAdAAyfDp1vN6TVzsLp6\":\"Teste format Table\",\"ubh1S8-pjzHg9RRXqz0a8\":\"New Data2TableDataSource (363)\",\"F3CRfABXa4sGJuzPL8P4X\":\"New Data2TableDataSource (363)\",\"fNbtfErAyqz2j3hW0usC1\":\"New Data2TableDataSource (363)\",\"7Eiq8OgfxSyLcBx-Al6iq\":\"OrderOptionsUsecases_CN\",\"_6L_D-0enouanyBAPwKXA\":\"OrderOptionsUsecases_CN\",\"CVwr9Btx27wOHJg8F7QG3\":\"OrderOptionsUsecases_CN\",\"no36vR3jVbwGnT2FUCvuV\":\"OrderOptionsUsecases_LN\",\"S29PiiZJmxHQY-T_wG8fe\":\"OrderOptionsUsecases_LN\",\"c-VsG2E8KcKOUb8UOpR9W\":\"OrderOptionsUsecases_LN\",\"AL9OZS9joXG4KI72T5Ab8\":\"OrderOptionsUsecases_GN\",\"gkCxBFlKtOOBIdhocA1gn\":\"OrderOptionsUsecases_GN\",\"IVUQnEMipJyXa6eX0uTMe\":\"OrderOptionsUsecases_GN\",\"bTElqE9OlyaSnfzCLJj4A\":\"Last Messages On Whatsapp\",\"0Cr6WmIz6x2uPDlCIZhF8\":\"Last Messages On Whatsapp\",\"-PdRzI1WJmWTudfOHDB_u\":\"Last Messages On Whatsapp\",\"JlIY5MsYz6YmxC2BvJ4lW\":\"Last Messages On Whatsapp\",\"r7OJkqw80Wqh7hPrOhIGd\":\"New Data2TableDataSource (376)\",\"tW-KjwCwXAEhm26NKgY5P\":\"New Data2TableDataSource (376)\",\"_4ikPaT5L-5C5krC4F3Yw\":\"New Data2TableDataSource (376)\",\"RnSxOYWe_AIKozE8k-ncl\":\"New Data2TableDataSource (376)\",\"uZWvdDKVI_FVMnmPJf5_C\":\"New Data2TableDataSource (376)\",\"Owp5bNCaaEATN7XzGwewr\":\"No Error Tags\",\"-lAfKyJuDcGC4DqKXlBP_\":\"No Error Tags\",\"VmqGQO0MY22UAJ6N8RwFx\":\"Marcos Teste\",\"gfYAtotG4qaI26rKv_-6k\":\"Marcos Teste\",\"HEBmnFMXTdJAYGQMKukkG\":\"Marcos Teste\",\"A-LPpvcL6BhyeMsALA4a3\":\"Natura Auth Strategy\",\"NmciGBhPeF4YPa7WFcwAA\":\"✅ ai-portal-authStrategy\",\"S90XiGh93fT0KnBVr-0Lj\":\"✅ Ecuador AuthStrategy\",\"0vLbtvkp24gw72HzUGo8E\":\"✅ MX Agents Tools Auth\",\"OzjbVWfqBgPZAvmcKhHRd\":\"Agents Auth\",\"DyyTEBU6g1LXIpn1l4TBb\":\"✅ faq users auth\",\"ioKl06rqQrmsX1VUqK5-c\":\"✅ Ecuador Admin Auth\",\"Om722U4XMUcQx6O6BHkzT\":\"✅ Agents Tools Auth\",\"vob324h71FgO0vmCGOEaq\":\"✅ Gestion-authStrategy\",\"KYzYFIQHIE-oASV_Ur4uK\":\"✅ externalTransfer-authenticationStrategy\",\"APYJSnxU5Mv12fk9JOV4f\":\"auth 788\",\"ZhuDnlYl9xhSfP2jAt51O\":\"✅ Authenticate\",\"Xw4nk036Fjt_p3ddVEQll\":\"✅ authStrategy - Hispanica\",\"pASZhw5Jbv4t-JTGbPOOv\":\"Copywriting\",\"nfFaXZLQH-leaW_Qv_ORH\":\"WSDL\",\"smI-d-ImcTi9v6sUimWO_\":\"SalesForce Query Assistant\",\"7fCWMgFbt3srKOPtf2kDJ\":\"chatroom-assistant\",\"YGFSyubfcgzlLSYo86GZx\":\"ZapAssistant\",\"SBK-xNNx8RgUmgRnKRwsu\":\"Search Products\",\"VA2rNWBqOnWtyQy2uxflK\":\"imagem ou informações\",\"eSdLF7Om6x_s0OHEZVSyu\":\"Especialista Natura\",\"r_oUqNMuQkgzHezPDcAAx\":\"context-action-assistant\",\"oOX8k1N0QsfKH2wa8wNj9\":\"[hispana]chatroom-assistant\",\"f5rC6a0JvmhcVW_q9NWY7\":\"[hispana]context-action-assistant\",\"iGKHk5kadFvVeookjOzlc\":\"chile - context-action-assistant\",\"AivRcw5taDpmCGya_vvfU\":\"chile - chatroom-assistant\",\"HvWaQGZDuPf13CtnpAT1D\":\"DMA-BOT\",\"GBFF-sdWMv_RLBHst9cRA\":\"UseCase Assistant\",\"amoBPQMMezGLBuZZVAFPV\":\"FAQ Detector Assistant\",\"K0lEpGHSC2OZndmZVObSS\":\"FAQ Conversation Assistant\",\"dGlpROdO8iqokf2Pd8T2q\":\"AVI - Conversation Assistant\",\"eI30A1iEtF8iQeEFtJSVI\":\"Cria mock pedidos\",\"-YIFugqZ5yHyWG3fOu9So\":\"Cria Deudas\",\"vXnLDrq3uZdf34ZBeBWpt\":\"MessagesAudioSpeaker\",\"aB0-MQdaQH_w5_7HiNgq0\":\"AtendimentoAssistant\",\"C-itKJ9Jp5psbaBqnIwrg\":\"chatroom-assistant\",\"yITzqpUUnlXKumhgnUnZC\":\"stef-detector-casos-de-uso\",\"ilvXJEH9yj7NKun3Xje1C\":\"chatroom-assistant\",\"sXMteZakDYp6y51LmOrzM\":\"chatroom-assistant\",\"6SYTA99hNlvvtJZrBMrqC\":\"chatroom-assistant\",\"lGBqj7BTgrtHCBdmqeao3\":\"FAQ Detector Assistant+\",\"Iu3ZSXZjoieYqLHej6QYI\":\"FAQ Conversation Assistant+\",\"cv_3p8KMvU2TSeHvkrT2F\":\"Conversation Assistant+\",\"Ej5y48JDemqtob2MM9VKa\":\"UseCase Assistant+\",\"hMZ6_N1_k3oAC58cpUM1k\":\"Location_Conversation\",\"HEp-5shOWvvOEHC0eQP5a\":\"Send Package Code\",\"1ixwszvwLdmk_AEPh7VPo\":\"FAQs Counter\",\"uZJlLsWK26OLFgZl8y7FU\":\"Multi response FAQs\",\"eGZ_8YhkLGFAqN3XedDxk\":\"Nasvi (Jazz) Assistant\",\"pWLZ1z5x2lx9AqSIqp0up\":\"Specific Intention\",\"GICc_tqXSbOoaWSiQb11V\":\"check AVI content\",\"elh1ns1V-lKz4WieAO5oG\":\"Mix all information in a single answer\",\"qK_iHrmSrV8O-J4Y1iLa5\":\"step assistant - hispana\",\"iR3ThAylpuCQi6-tIYvTQ\":\"ASSISTANT - set category/context\",\"3yxzjf-l5V43iKXhhxSjS\":\"multiple_usecases_check\",\"BWdUSUGN3Xd67pWCpwigW\":\"SentenceSeparator Assistant\",\"Nt5sWx8QmyDoHSE2AFGXM\":\"Mix Answers assistant\",\"mDierjbW5J8La1MxHZ3B6\":\"B - Mix Answers assistant\",\"AW4XVDj_rBKR_frcMMTU7\":\"C - Mix Answers assistant\",\"2EYDhTi1g5tWEcZvveZuI\":\"wiki_assistant\",\"eNLMtizZAWdA8DXbBsCpq\":\"especialista-ecuador\",\"R81yu-Ghj-ZO_oJHw3-MB\":\"Skip Preload FAQ Conversation Assistant\",\"mXXLmSXihOdZJPHYySCM-\":\"Asistant_Test_Miguel\",\"zkBULFdDhtMpRawOMRAYl\":\"Assistant_Mejorada_Miguel\",\"0IPlavInQy5Zgsw20wzyZ\":\"Conversation_Assistant_Miguel_test\",\"Z9d_E6mfMCsz0TSuqKENf\":\"assist - refactoring - select usecase\",\"LLZDNXMBsm6Rdvxi8j604\":\"assist - refactoring - generate answer - usecase\",\"59DtUttJ8aR15k1Ruuxbl\":\"assist - refactoring - generate answer - FAQ\",\"Nz9lpnEoZe8gFOnTjUenw\":\"assist - refactoring - select FAQ\",\"cfKJaohLsmVRyK2e9Bv1F\":\"Conversation_assistant_antigua\",\"s3qOEa5O0wzAabmrIB2Ch\":\"assist - refactoring - compare answers FAQ\",\"TAFADwOQ79raIo3ipvVFo\":\"new - assist - refactoring - compare answers FAQ\",\"ig_mujwIc6nnvVKdXrpjJ\":\"beedooNormalizer\",\"Jvh9TNi0x_y9BwoDWqCne\":\"Copy of Copy of Asistente_chat\",\"1qS0VoejtWTERV1EpSox3\":\"sum_history\",\"z8AUipV10wPunaHcpK0Fp\":\"New Assistant (63)\",\"U9BRNWhKyh0mTogrRuMds\":\"New Assistant (63)\",\"wMvPaYzDmLfpxgFX4vDRy\":\"OtherDrive\",\"nuteSRebg7GwXm207jMOE\":\"assets\",\"BvjucKU_YVef_GEzfQMCA\":\"Temp Screenshots\",\"9DcvOcRiCx0ZeCyBQsdC_\":\"Sprint Sessions Drive\",\"Qbb37K4v-nUDpOUkvPnbB\":\"prints-endpoints 2 session\",\"oLuENtDSEhYdaB5r3j4AM\":\"FAQ Drive\",\"efKKF_frpix4xMZfAMd1T\":\"demo-atendimento-colombia-drive\",\"zRnXbqY-8m_HQq_EAoPp0\":\"MessagesAudio\",\"jeG6uJRaeVcE6MVlVudDV\":\"Natura Audios\",\"RYULth72jWwHf_sbAvwWc\":\"Print Attachments\",\"7VnQJph6VqgXjEyPfciRo\":\"live-assets\",\"hfGlZx2fGP7IjdSHuNCMC\":\"Docs Drive\",\"laPtxgWAtASsuPkg8szTo\":\"Natura Shared Assets\",\"ursSebQzAyGczDa9Bb9PZ\":\"Ecuador Documentation Drive\",\"_jLgPbv8OSmZ2IGj5v6A0\":\"atendimento-docs-assets\",\"L7oOSFzf31uZNC7rrSv8Y\":\"Natura Chat Drive\",\"xYwNCypurPRVny8bY96zL\":\"faq_request_updates_drive\",\"OVWWvaQcVOiBfolO_d6Oy\":\"Drive - Invoices CL\",\"3kHR5uvuTqd_z2nte1vkn\":\"Imagenes Varias\",\"lYOUPhtU8PjvgrllO0LQX\":\"Forms\",\"d2-rush-email-drive--i5W24aHHKkJ5EKal7HyMd\":\"[Data2] Drive for Rush EmailListener i5W24aHHKkJ5EKal7HyMd\",\"2xqXvDfqPxwhtcOjhoxhN\":\"Faq Operador Drive\",\"d2-rush-email-drive--aAuM_I24P322rGD0eZ-UG\":\"[Data2] Drive for Rush EmailListener aAuM_I24P322rGD0eZ-UG\",\"IwngrVMQ-KA88dbUEWyS4\":\"multicase_drive\",\"d2-rush-email-drive--4sJtg3IlZKvtb4rD8if4l\":\"[Data2] Drive for Rush EmailListener 4sJtg3IlZKvtb4rD8if4l\",\"jaLck-NZE5_9NUNg3kXOg\":\"Drive perro\",\"MsCz4pHpRTLPsPpyJ8RtB\":\"drive_avi_propuesta\",\"2oLDqqtLsVE2zVybJxXXy\":\"AssetRepository\",\"gASxnb9ssA7xj5ndhdI-d\":\"FAQs Drive\",\"noTNF3fE7LGuYWBq_uhVp\":\"external_transfer_drive\",\"mNL-PfXuHfR3jX37AVdDK\":\"New Drive (34)\",\"kZo5qMX3JsrHbSQsHMNaM\":\"EstadoPedidoDrive\",\"nDHBaAmxgmjmaO0yNbPoW\":\"Drive Explanation 1290\",\"Ai8ULy7sOmXXSCfKhwUiL\":\"dj_analysis_drive\",\"wnjbKgJYUdqni-dDyRyNm\":\"Copy of Copy of drive_chat\",\"yccTgOYe6M94GhdD8udsg\":\"ivr_assistant\",\"RCiLYfZ9yJeGeCnxcWrI4\":\"ChatHook\",\"mg2bxYVq7OiC4BPR_yCAH_\":\"DMA-Gateway\",\"reply-entrypoint\":\"colombia-reply-entrypoint-hml\",\"reply-entrypoint-prod\":\"colombia-reply-entrypoint-prod\",\"DKnDLQUtDA6mNdYkT8sh1\":\"audio-generator\",\"peru-reply-entrypoint-prod\":\"peru-reply-entrypoint-prod\",\"peru-reply-entrypoint\":\"peru-reply-entrypoint-hml\",\"mexico-reply-entrypoint\":\"mexico-reply-entrypoint-hml\",\"mexico-reply-entrypoint-prod\":\"mexico-reply-entrypoint-prod\",\"health-check-colombia\":\"health-check-colombia\",\"health-check-peru\":\"health-check-peru\",\"health-check-mexico\":\"health-check-mexico\",\"monitoring-colombia\":\"monitoring-colombia\",\"monitoring-peru\":\"monitoring-peru\",\"monitoring-mexico\":\"monitoring-mexico\",\"chile-reply-entrypoint\":\"chile-reply-entrypoint-hml\",\"chile-reply-entrypoint-prod\":\"chile-reply-entrypoint-prod\",\"health-check-chile\":\"health-check-chile\",\"monitoring-chile\":\"monitoring-chile\",\"ecuador-entrypoint-hml\":\"ecuador-entrypoint-hml\",\"ecuador-entrypoint-prod\":\"ecuador-entrypoint-prod\",\"health-check-ecuador\":\"health-check-ecuador\",\"monitoring-ecuador\":\"monitoring-ecuador\",\"di5-RlyrJ7LB5lv9z26xa\":\"Sync Agents Metadata Job HML\",\"ecuador-reply-entrypoint-hml\":\"whatsapp-reply-entrypoint-hml\",\"ecuador-reply-entrypoint-prod\":\"whatsapp-reply-entrypoint-prod\",\"5MryyxAbTHsb89yVx3FAe\":\"agent-send-message-entrypoint\",\"TZtOuDXGQh24VDN9CGov0\":\"PingPong KeyVault\",\"13rnkmw96E5MrquKnnI_M\":\"agent-logs-entrypoint\",\"3NwM07fRAAi2cON2KpJi_\":\"Expire Inactive Transfers Job HML\",\"ZOpJU13MlsqJNZNScpZrs\":\"Sync Agents Metadata Job PRD\",\"0ScwQIaOMBUIdDb1x5q9R\":\"transfer-operation-entrypoint\",\"JtLDId2qjiu0sNsULsD4E\":\"Expire Inactive Transfers Job PRD\",\"PqjPbzpg-bFvxXV9qSA8T\":\"chat-ping-entrypoint\",\"vC7Xapg8Lx7g4wfd0e_jR\":\"Detect Abandon Job HML\",\"GFNOx0PYwKYjS8oFd7U6l\":\"Detect Abandon Job PRD\",\"argentina-reply-entrypoint\":\"argentina-reply-entrypoint-hml\",\"argentina-reply-entrypoint-prod\":\"argentina-reply-entrypoint-prod\",\"health-check-argentina\":\"health-check-argentina\",\"monitoring-argentina\":\"monitoring-argentina\",\"authenticate-user-argentina\":\"authenticate-user-argentina\",\"VXbg6FJbalOwrIJnvZIRC\":\"Copy of Peru-Authentication\",\"kr62-VRyfj1Rd58JKRaCP\":\"Copy of semantic-faq\",\"Rdzbz0sYIWKJo-DOGAS4L\":\"colombia-reply-tests\",\"VBe5cffOny7xgAxAsNd_F\":\"semantic-faq\",\"_lFzbsy_N19dug6wI83S6\":\"DEV CAll Manual Only Iterate-Queue-recursive-JOB-DEV\",\"-_As0_UIvL1WZLhYkvnEP\":\"Iterate-Queue-Auto-Healer Scheduler <- on pause due external_transfer\",\"1knLGAxuaCD2fsuMbZBH5\":\"Iterate-Queue-recursive-JOB-PRD <- on pause due external_transfer\",\"n7l-E7afYNCPYtaJzn3o_\":\"ocular-kb-entrypoint\",\"Br8NJWvy7UDUC3dKFs-De\":\"ocular-answer-entrypoint\",\"4D2touS1KIk735CijlzJu\":\"FormsSendEmail HML\",\"oN7ZFszCha8Cx6I3WefPa\":\"MAIN RUSH Forms\",\"f9mn0XCtwjCiwA2buisUM\":\"Get Seller - Rush Invoke\",\"OXlr-pFHOSL3TyqbG_C29\":\"SubMonitoringRush\",\"SSkgjL2C2_pha_4D8YoYV\":\"Recips_infobit\",\"iZpq-fSmeaLLWLeQGh2zv\":\"Reciept-Email\",\"4G3HkuB0vUfSPAjUvThB9\":\"Webhook_InfobitData2\",\"S5Smf36KVnpAgdlXt9xU4\":\"d2-chile-entrypoint-hml\",\"vRtbsuzMqlbWrwKCvjeS6\":\"d2-mexico-entrypoint-hml\",\"xZ07GjXF6J-UE889zvhNv\":\"d2-colombia-entrypoint-hml\",\"gJnyPaWs1JQSQ8CPGfzCO\":\"d2-peru-entrypoint-hml\",\"hrfpkEcajH1t8HR61CXM2\":\"d2-no-country-entrypoint-hml\",\"pzwhsvhUFlNTNfalRoReJ\":\"[IVR] - FAQ Service - Colombia\",\"6dGeYqg30On7Vl_cYSh0G\":\"voice-entrypoint-use-cases\",\"DwKOpCazNMaMtUTpBhqC2\":\"debug-voice-entrypoint-use-cases\",\"uFHAeNtMdNZXgVqN2vxit\":\"[IVR]voice-entrypoint-use-cases\",\"LmElMY813TKSrFwDI9BFd\":\"UPLOAD WIKIS Rush\",\"X0Zduvi81uXolo0eTY6Tk\":\"cari-rush\",\"flQBZ9yWONn7dYrW-6SaO\":\"cari-data2Sec\",\"2dQ8tHgWFqO0ULXJVmfvB\":\"BUG Auth Strategy\",\"Y1O0oTlVo3601Jif1BxNB\":\"d2-Argentina-entrypoint-hml\",\"5paWQC7PQmA6TT7O8jfN1\":\"Get Csat Agent\",\"p9IwlndVIpNoYWO3V0RaX\":\"Auth Endpoint\",\"fNnAMBBznAO9wvOX5V9Jf\":\"d2-peru-entrypoint-prd\",\"W_7c3KvURCeog4RW9kzlh\":\"d2-no-country-entrypoint-prd\",\"yrzdo5Ewbnp3ZaiLXV2rz\":\"d2-chile-entrypoint-prd\",\"v4LXRPYyAgktlbttvZyTN\":\"d2-Argentina-entrypoint-prd\",\"oV37yW1tSod7tpFyqKkxy\":\"d2-colombia-entrypoint-prd\",\"AKlWpcgDjGl6n-TK_j4OY\":\"d2-mexico-entrypoint-prd\",\"NDp1EgGs3Xn4IUTan3yht\":\"debug ec get titles rush\",\"vwkNOgpr4qzNJdhY4JorT\":\"MotherTester\",\"mKozj09NcLOagalg-VqXa\":\"rush-ana-monthly-report-numbers\",\"TUdsI1xRqd9fQj-2U-Sab\":\"EmailListenerRPA\",\"m3l1c0HBBXSL5ZRt4ZWsc\":\"Scheduler Close Session\",\"pEaGKSVNxejOXqsg3EGmr\":\"RPAEmailListener\",\"HmLW40Dug8t3rvhMmfXWY\":\"keycloak-oauth-validate-pin\",\"fU6X_mrSStaevLVbZqAKX\":\"keycloak-oauth-generate-pin\",\"JVf9xTeGFXyQYrusdL4TS\":\"contesta-preguntas-ecuador\",\"uDBjs8wkDtrxMpysFrTEF\":\"refactoring - select usecase\",\"L322Lg0jWzCvY6vhp-XRd\":\"refactoring - select FAQ\",\"DU7pDuhF-5peX6NA2K0XH\":\"refactoring - generate answer - usecase\",\"pvPH-HtYlHprLUXXnUzvr\":\"refactoring - generate answer - FAQ\",\"tl059gO4UkSn6l-rMKTX3\":\"Csat Endpoint FullD2\",\"ubp46aOre3B349mcfAeZy\":\"FAQs-entrypoint-maia\",\"9EjGJRul_CfpxuxkH8uuH\":\"New HTTPListener (84)\",\"bo3vvYdwZei_1njBiiiby\":\"Do NOT DELETE! - New HTTPListener (84)\",\"sNLVZ6BazGIEpFzeJUMs0\":\"EcuadorByToken\",\"QOPIchK_LVwWCzYZFRpsF\":\"NI Sessions\",\"20Q518uE-sB06h4JJRm-q\":\"New HTTPListener (88)\",\"rbeu3OSYD9XTKdkEKhS0d\":\"New EmailListener (3)\",\"WQVnm9MIxst3JmmSsNrjq\":\"Debug not found\",\"Q86M0LYUybVvjS0DCOmK1\":\"New Scheduler (9)\",\"AZ9vggxaGj14m9wlr4jJH\":\"Scheduler Agent External Catch\",\"rM74WoHiOjwclT9OqQfSN\":\"mx-filtred-chatid-logs\",\"7hjRu6sUdMD0rREQDhF5m\":\"cl-filtred-chatid-logs\",\"Pfgl_XbCvP_MbD16we1_k\":\"co-filtred-chatid-logs\",\"ngcyRzaTIYvr455tIF1kz\":\"pe-filtred-chatid-logs\",\"fr53sxeRFZ4z97aNvd0fs\":\"ar-filtred-chatid-logs\",\"XyWU5I35B-xol8vj6E68A\":\"ec-filtred-chatid-logs\",\"JJMYzP0l4WL2syVjR3Le5\":\"sinch-ar-filtred-logs\",\"jC_thuwiDg9xvEdlEv2W4\":\"cari-rush-filtred-logs\",\"JOBH4QXjA1tsc4k_iGjyw\":\"getData-infoMaia\",\"3O7jD2oTEfg5C-guYPntf\":\"fix env null\",\"GYCxKrHJQUBAN7ELG_6cp\":\"getTime - Forms-Rush\",\"llsRwO29b2x_HqelU2ZwK\":\"Messages Controler in Queue\",\"zKLNT-goyFRBK6gnQMwFa\":\"New HTTPListener (98)\",\"M4ZqtoUWz2tvH6eepqVIx\":\"scheduler fix complete session ended data\",\"9GWeJ6GdPB6e2N1ILfQuR\":\"Close Session Manually\",\"t318vm-mHbHCN0mCySu5g\":\"Api Executions with NO NAME\",\"SInspt5Zks0QPlfoBB3Ia\":\"API_CSAT_QUALTRICS_FORMS\",\"lGLpiM1QQvJwQKrxn8NcT\":\"Comment Duplicator <31/03\",\"zqWM3dlAnLhOUVTw_vRNS\":\"Scheduler Catch data to report cancel Order\",\"RAcxhTZr3D7Hmj37bgkCc\":\"Copy of d2-colombia-entrypoint-hml\",\"QrT1-4d2hrSFAZMKGbtA3\":\"New HTTPListener (102)\",\"5iNOjWfW6z69unNZhpPxW\":\"API_AVI_KPIS\",\"pqwZ2g4lvKhd7c1-7FltP\":\"API_AVI_KPIS_INDICADORES\",\"M8Hu0reR498Ik_baDQGtB\":\"New HTTPListener (105)\",\"fWvjFunmTK_hY0lFQbjR6\":\"Delete Old Entries In - Last Messages On Whatsapp\",\"marcos.goulart@compasso.com.br\":\"marcos.goulart@compasso.com.br\",\"lucas.quiceno@konecta.com\":\"lucas.quiceno@konecta.com\",\"juannaffah120274@gmail.com\":\"juannaffah120274@gmail.com\",\"yadirahernandez.konecta@natura.net\":\"yadirahernandez.konecta@natura.net\",\"matiasdonoso@natura.net\":\"matiasdonoso@natura.net\",\"miguelbanaga.konecta@natura.net\":\"miguelbanaga.konecta@natura.net\",\"mario.hernandez.montez@konecta.com\":\"mario.hernandez.montez@konecta.com\",\"beatrizblas@natura.net\":\"beatrizblas@natura.net\",\"franzarredondo.konecta@natura.net\":\"franzarredondo.konecta@natura.net\",\"7S7Hyo83QcGUTiqlInuJ6\":\"Recover Session Cognito SSO\",\"jHH4vH-HfLIqjKwuRVnFN\":\"ByApp Get Access Token\",\"95PiFygoYiWmUMlXyUaVO\":\"Get Identification\",\"0lwqRkwQuKtdvTxUVGkLc\":\"ByApp Login Cognito\",\"nAbzjin-OAtGLyjT4HBcS\":\"auth\",\"Ab7idSsG5qnCuHnSt4Sth\":\"auth\",\"_Y8ErcnjwjFDJGoypCku-\":\"Simulated RNG\",\"n5V4pDXzViovabrABJ3Sa\":\"Login AuthStrategy\",\"xTGDjqJnZlkEr-Efnd_PA\":\"Get Commercial Plan Level\",\"gX1XZ1myNOJE8eWrqzf5E\":\"Forms - Get Order Status\",\"-sW9Cwx3Poy_sC--_eFGV\":\"ByApp Get Orders\",\"5xhtg5iciI4GAusd7mM8j\":\"Get Order\",\"EgVlonyaVuTjEinkMfwee\":\"Get Order Tracking\",\"ZKBfYYV6nJA6U8YuXUnOU\":\"ByUser Get Orders\",\"rdYXqMVMxvrmygC1ljokS\":\"Pruebas - avi-maia-summary\",\"Z0z2Ad3BWuifDoSvwg9bk\":\"Forms - Get Identification\",\"cPtXjN-uKuTjMmjz4iq4k\":\"Logout Cognito SSO\",\"QeVl2zKh7-Zw_LfDBcweV\":\"setSessionSinch\",\"PnM2XdWvKd1htfdws3fj3\":\"getAccessToken\",\"cPvq-1-UoVxmU4SSWvsQA\":\"Get Commercial Info/Cycle\",\"wiZulzXutcFa2uHNdBlAn\":\"Get Debts\",\"yF6mezl6qJSS2xBYsEpLb\":\"ByUser Get Titles\",\"I_8ajVIPH9ac2P38SZSx1\":\"openInstallments\",\"mHfIv05ajjXgUyiWKU0OF\":\"Forms - Get Commercial Info/Cycle\",\"ZDl5ybjN8IBaNMaG3a5IM\":\"Renegociated Confirm\",\"aFS_P9us1rGe-685INq0Y\":\"SendEmail\",\"53RsFIjttHcjRUlzSv6YT\":\"Get Invoice List - CL\",\"C9hY252FyX2F2bIo0tv-n\":\"Get_invoice_List\",\"nUZes_SiNTol9ElyUEGMk\":\"Send Message Generic\",\"xVjkn6C5qVKs2IKrEqtSD\":\"Get Consultant RPP\",\"9q60S-3lhT5aRGq8FI_Cl\":\"Orders PLO\",\"servicodados.ibge.gov.br\":\"servicodados.ibge.gov.br\",\"minegocio.natura.cl\":\"minegocio.natura.cl\",\"Ki_ulS3kgjJNX2hQ7pqa6\":\"Pruebas - avi-maia-response\",\"uFJ_RvYtV4K7ajLL62OFu\":\"ByApp Get Titles\",\"api.ipify.org\":\"api.ipify.org\",\"7PsCaVB318fFoI6Ayriuq\":\"ByUser Get Personal Data\",\"7QamP75O45S6Pe3_N9040\":\"API DAP Natura Argentina (Solicitar Status Reclamo)\",\"kSbRDpqY6Gjv8_a-A_Trl\":\"Forms Get Order Tracking\",\"V0TLUGWMKmvfqFiKuysYN\":\"ByApp Get Personal Data\",\"4TQRG38mpESi3kn90-MlX\":\"Installments RNG\",\"1h0QH6HlitlnZAZjSD6cG\":\"Forms - Get Debts\",\"Ydoyan7ka7qNLs9ADJ_Cw\":\"createToken\",\"GLjWiNVRi5t_4hUxPbwZ1\":\"PlansPayments\",\"UbBSYq36erHgfXz7XmqYT\":\"UbBSYq36erHgfXz7XmqYT\",\"TXHZKimIWspmFkqiJtpQd\":\"Get Order Status\",\"natura.data2.link\":\"natura.data2.link\",\"xMGTflJ1gKnNzxm9egYDt\":\"sendMsg\",\"13d0zDdtNFu0zJELsTakH\":\"getConversationStatus\",\"MqFGADgqzYcg2STmlisyV\":\"Get Credits Available\",\"YJgVwnTOFE_vAQFvJen-y\":\"ByUser Get Access Token\",\"fSv4XHNVXa19WyF3oh3TH\":\"cari-reports-transbordo conversationsAgente\",\"L-GMwJEzcjUX-uy_CQ7oC\":\"Forms - Get Commercial Plan Level\",\"71HLZyuKp3QFckaxb_337\":\"Get Seller\",\"01goN8nVKyDKItUYKfQPC\":\"cari-reports-transbordo create token\",\"jB-I4tPIUNi-bw5FEakNK\":\"Send Message Text\",\"_jyjA1UbujSVgM7SHW8fM\":\"Get Orders to Cancel\",\"ncf-apigw.prd.naturacloud.com\":\"ncf-apigw.prd.naturacloud.com\",\"TlHD_VRaJVvvdIsqYRuP6\":\"Forms - Get Item Request\",\"FvP2nDE_XMFHbhqwXrhOv\":\"createConversation\",\"cgF0jMqZZLP3Txu-PAQVP\":\"Get Invoice 2\",\"PDlvBO7dv7xycUSzhCurQ\":\"Create Case\",\"natura.data2apis.com\":\"natura.data2apis.com\",\"vxMiuzvIMupWAYtrZEG2H\":\"openDebtInstallments\",\"d2-rush-http-logs--V8QitQ-Oe6s4HIBAaMK2M\":\"[Data2] Table for Rush HTTPListener V8QitQ-Oe6s4HIBAaMK2M\",\"d2-rush-scheduler-logs--vC7Xapg8Lx7g4wfd0e_jR\":\"[Data2] Table for Rush Scheduler vC7Xapg8Lx7g4wfd0e_jR\",\"d2-rush-scheduler-logs--3NwM07fRAAi2cON2KpJi_\":\"[Data2] Table for Rush Scheduler 3NwM07fRAAi2cON2KpJi_\",\"d2-rush-scheduler-logs--ZOpJU13MlsqJNZNScpZrs\":\"[Data2] Table for Rush Scheduler ZOpJU13MlsqJNZNScpZrs\",\"d2-rush-http-logs--1KOo2Xz5PfRHlG3X0fQza\":\"[Data2] Table for Rush HTTPListener 1KOo2Xz5PfRHlG3X0fQza\",\"d2-rush-http-logs--mg2bxYVq7OiC4BPR_yCAH\":\"[Data2] Table for Rush HTTPListener mg2bxYVq7OiC4BPR_yCAH\",\"d2-rush-email-logs--TUdsI1xRqd9fQj-2U-Sab\":\"[Data2] Table for Rush EmailListener TUdsI1xRqd9fQj-2U-Sab\",\"d2-rush-scheduler-logs--t318vm-mHbHCN0mCySu5g\":\"[Data2] Table for Rush Scheduler t318vm-mHbHCN0mCySu5g\",\"d2-rush-http-logs--9dUswBQShRRYePEdnupQd\":\"[Data2] Table for Rush HTTPListener 9dUswBQShRRYePEdnupQd\",\"d2-rush-email-logs--rbeu3OSYD9XTKdkEKhS0d\":\"[Data2] Table for Rush EmailListener rbeu3OSYD9XTKdkEKhS0d\",\"d2-rush-scheduler-logs--3O7jD2oTEfg5C-guYPntf\":\"[Data2] Table for Rush Scheduler 3O7jD2oTEfg5C-guYPntf\",\"d2-rush-email-logs--pEaGKSVNxejOXqsg3EGmr\":\"[Data2] Table for Rush EmailListener pEaGKSVNxejOXqsg3EGmr\",\"d2-rush-scheduler-logs--AZ9vggxaGj14m9wlr4jJH\":\"[Data2] Table for Rush Scheduler AZ9vggxaGj14m9wlr4jJH\",\"d2-rush-http-logs--2QF7k4LV6r3lNKD2DQIY-\":\"[Data2] Table for Rush HTTPListener 2QF7k4LV6r3lNKD2DQIY-\",\"d2-rush-http-logs--mje-uNOteDESvSNXHLZLT\":\"[Data2] Table for Rush HTTPListener mje-uNOteDESvSNXHLZLT\",\"d2-rush-http-logs--az8YMS-6UsEk3gOxh7SR9\":\"[Data2] Table for Rush HTTPListener az8YMS-6UsEk3gOxh7SR9\",\"d2-rush-http-logs--e4HeHh8afr0hGzLYIOudK\":\"[Data2] Table for Rush HTTPListener e4HeHh8afr0hGzLYIOudK\",\"d2-rush-http-logs--bLxMPfXtKiY54py-DIndG\":\"[Data2] Table for Rush HTTPListener bLxMPfXtKiY54py-DIndG\",\"d2-rush-scheduler-logs--fWvjFunmTK_hY0lFQbjR6\":\"[Data2] Table for Rush Scheduler fWvjFunmTK_hY0lFQbjR6\",\"d2-rush-http-logs--urEFLyhpWyo4tai4rgsu4\":\"[Data2] Table for Rush HTTPListener reply-entrypoint-hml\",\"d2-rush-http-logs--ZOKczRUH8FwbvRdp293FH\":\"[Data2] Table for Rush HTTPListener ZOKczRUH8FwbvRdp293FH\",\"d2-rush-http-logs--HpaVieRijvQmlDd_Fq3Ik\":\"[Data2] Table for Rush HTTPListener HpaVieRijvQmlDd_Fq3Ik\",\"d2-rush-http-logs--SUrn4fG4goJSOSiy27kA-\":\"[Data2] Table for Rush HTTPListener reply-entrypoint-prod\",\"d2-rush-scheduler-logs--y4A1QBJj6PZjGjz0P5SzW\":\"[Data2] Table for Rush Scheduler y4A1QBJj6PZjGjz0P5SzW\",\"d2-rush-scheduler-logs--GFNOx0PYwKYjS8oFd7U6l\":\"[Data2] Table for Rush Scheduler GFNOx0PYwKYjS8oFd7U6l\",\"d2-rush-http-logs--J7aRLvdtz2jswiaKO6LbB\":\"[Data2] Table for Rush HTTPListener J7aRLvdtz2jswiaKO6LbB\",\"d2-rush-http-logs--4qw7g77IOEF6FhhXPBl0h\":\"[Data2] Table for Rush HTTPListener 4qw7g77IOEF6FhhXPBl0h\",\"1y2dVFvEk9dRjkXAgCJhS\":\"DEBUG -  Gabz + Lucas - websocket\",\"d2-rush-http-logs--y_Cx63lH0OkYZL9Fwh_vt\":\"[Data2] Table for Rush HTTPListener y_Cx63lH0OkYZL9Fwh_vt\",\"d2-rush-scheduler-logs--llsRwO29b2x_HqelU2ZwK\":\"[Data2] Table for Rush Scheduler llsRwO29b2x_HqelU2ZwK\",\"d2-rush-scheduler-logs--lGLpiM1QQvJwQKrxn8NcT\":\"[Data2] Table for Rush Scheduler lGLpiM1QQvJwQKrxn8NcT\",\"d2-rush-scheduler-logs--JtLDId2qjiu0sNsULsD4E\":\"[Data2] Table for Rush Scheduler JtLDId2qjiu0sNsULsD4E\",\"d2-rush-http-logs--VAuRdAFOi6fWHKsyNSDzu\":\"[Data2] Table for Rush HTTPListener VAuRdAFOi6fWHKsyNSDzu\",\"d2-rush-http-logs--cFIbi56WTtLzvP98SJGm8\":\"[Data2] Table for Rush HTTPListener cFIbi56WTtLzvP98SJGm8\",\"d2-rush-scheduler-logs---qI3WX_wNZ89B9SFb-IR6\":\"[Data2] Table for Rush Scheduler -qI3WX_wNZ89B9SFb-IR6\",\"d2-rush-http-logs--kknIKeY43H6sF45qYklwG\":\"[Data2] Table for Rush HTTPListener kknIKeY43H6sF45qYklwG\",\"d2-rush-http-logs--FMBXNnA9VIwNuFZwLR5l-\":\"[Data2] Table for Rush HTTPListener FMBXNnA9VIwNuFZwLR5l-\",\"d2-rush-scheduler-logs--M4ZqtoUWz2tvH6eepqVIx\":\"[Data2] Table for Rush Scheduler M4ZqtoUWz2tvH6eepqVIx\",\"d2-rush-scheduler-logs---_As0_UIvL1WZLhYkvnEP\":\"[Data2] Table for Rush Scheduler -_As0_UIvL1WZLhYkvnEP\",\"d2-rush-email-logs--iZpq-fSmeaLLWLeQGh2zv\":\"[Data2] Table for Rush EmailListener iZpq-fSmeaLLWLeQGh2zv\",\"d2-rush-scheduler-logs--Q86M0LYUybVvjS0DCOmK1\":\"[Data2] Table for Rush Scheduler Q86M0LYUybVvjS0DCOmK1\",\"d2-rush-scheduler-logs--m3l1c0HBBXSL5ZRt4ZWsc\":\"[Data2] Table for Rush Scheduler m3l1c0HBBXSL5ZRt4ZWsc\",\"d2-rush-http-logs--Opk-wkyI836qAOLiMO74w\":\"[Data2] Table for Rush HTTPListener Opk-wkyI836qAOLiMO74w\",\"d2-rush-http-logs--wWGIe_bke4WM_zXH1L1aX\":\"[Data2] Table for Rush HTTPListener wWGIe_bke4WM_zXH1L1aX\",\"d2-rush-http-logs--CrHuxYw5OO6UhaArGlI5k\":\"[Data2] Table for Rush HTTPListener CrHuxYw5OO6UhaArGlI5k\",\"d2-rush-scheduler-logs--zqWM3dlAnLhOUVTw_vRNS\":\"[Data2] Table for Rush Scheduler zqWM3dlAnLhOUVTw_vRNS\",\"d2-rush-http-logs--8m5oC8BGWY9_2gDfSX4Iz\":\"[Data2] Table for Rush HTTPListener 8m5oC8BGWY9_2gDfSX4Iz\",\"d2-rush-http-logs--1qcOzRJwbJOernHNczqre\":\"[Data2] Table for Rush HTTPListener 1qcOzRJwbJOernHNczqre\",\"d2-rush-http-logs--kQOalUChW01nEtOgbyvhR\":\"[Data2] Table for Rush HTTPListener kQOalUChW01nEtOgbyvhR\",\"d2-rush-http-logs--bkvgqkvfFtk47z85tdiFi\":\"[Data2] Table for Rush HTTPListener bkvgqkvfFtk47z85tdiFi\",\"d2-rush-http-logs--vw5jqNOxmOIGuMTAPu0-N\":\"[Data2] Table for Rush HTTPListener vw5jqNOxmOIGuMTAPu0-N\",\"d2-rush-scheduler-logs--di5-RlyrJ7LB5lv9z26xa\":\"[Data2] Table for Rush Scheduler di5-RlyrJ7LB5lv9z26xa\",\"d2-rush-http-logs--FZopMq_0TAjKgwluiTO2O\":\"[Data2] Table for Rush HTTPListener FZopMq_0TAjKgwluiTO2O\",\"d2-rush-scheduler-logs--QOPIchK_LVwWCzYZFRpsF\":\"[Data2] Table for Rush Scheduler QOPIchK_LVwWCzYZFRpsF\",\"d2-rush-http-logs--\":\"d2-rush-http-logs--\",\"d2-rush-http-logs--nHyPjGyfyfZBDbjEAVajv\":\"[Data2] Table for Rush HTTPListener nHyPjGyfyfZBDbjEAVajv\",\"E3oMcXu2Bz9ePMI65_C22\":\"E3oMcXu2Bz9ePMI65_C22\",\"-nMQ7qe1f0wjvb0ZvWN7A\":\"-nMQ7qe1f0wjvb0ZvWN7A\",\"7S26W0shHU9I5Ebt_WENT\":\"7S26W0shHU9I5Ebt_WENT\",\"Gtdb73GMSQ-A7BRxxfQN_\":\"Gtdb73GMSQ-A7BRxxfQN_\",\"d2-rush-http-logs--vE0mWtHWUlK5Ewz_03Tmw\":\"[Data2] Table for Rush HTTPListener vE0mWtHWUlK5Ewz_03Tmw\",\"d2-rush-http-logs--NvYvE6tTC1rTOFw_fBnql\":\"[Data2] Table for Rush HTTPListener NvYvE6tTC1rTOFw_fBnql\",\"66DHzRqOE1a1tRB0zq0ZY\":\"66DHzRqOE1a1tRB0zq0ZY\",\"UVM5gJF_mQ7tMG-YqS2nS\":\"UVM5gJF_mQ7tMG-YqS2nS\",\"d2-rush-http-logs--SH-rJXkaDoNGb7t6iobR-\":\"[Data2] Table for Rush HTTPListener SH-rJXkaDoNGb7t6iobR-\",\"d2-rush-http-logs--uBEjYWYbhiaNoFYM7dRdM\":\"[Data2] Table for Rush HTTPListener uBEjYWYbhiaNoFYM7dRdM\",\"Qpiav1VtDm8y85OYEoKaJ\":\"Qpiav1VtDm8y85OYEoKaJ\",\"d2-rush-http-logs--xTZ1L6-oE99tVZXJKSEC5\":\"d2-rush-http-logs--xTZ1L6-oE99tVZXJKSEC5\",\"WTiB4xcYb-Ice4p8GdC6z\":\"WTiB4xcYb-Ice4p8GdC6z\",\"d2-rush-http-logs--7FsZi-TUPSiSL4AmoUn7G\":\"[Data2] Table for Rush HTTPListener 7FsZi-TUPSiSL4AmoUn7G\",\"ic2M2f2TdC-Zn2TTHl59p\":\"ic2M2f2TdC-Zn2TTHl59p\",\"d2-rush-http-logs--DR7-lmFBnrdB09Sn4y5xW\":\"[Data2] Table for Rush HTTPListener DR7-lmFBnrdB09Sn4y5xW\",\"r9JxZDCF29EVaqVsssCBC\":\"r9JxZDCF29EVaqVsssCBC\",\"B1nSxZNv12IEgCn-WaYDp\":\"B1nSxZNv12IEgCn-WaYDp\",\"d2-rush-http-logs--4v3kV-PEoKcs1Wzw7zZpS\":\"[Data2] Table for Rush HTTPListener 4v3kV-PEoKcs1Wzw7zZpS\",\"d2-rush-http-logs--DKxN41CrxkSmxm3s7uB7o\":\"[Data2] Table for Rush HTTPListener DKxN41CrxkSmxm3s7uB7o\",\"d2-rush-http-logs--6j8Rw4f3JbnLu_A521iUs\":\"[Data2] Table for Rush HTTPListener 6j8Rw4f3JbnLu_A521iUs\",\"d2-rush-http-logs--uU8XSekkEUy7S8ANqlxYw\":\"[Data2] Table for Rush HTTPListener uU8XSekkEUy7S8ANqlxYw\",\"2wqCAk3cQqrAzjxc6yWDd\":\"2wqCAk3cQqrAzjxc6yWDd\",\"d2-rush-http-logs--AKIWpcgDjIGn-TK_j4OY\":\"d2-rush-http-logs--AKIWpcgDjIGn-TK_j4OY\",\"pBNp_Dx5lVVKPG26mvda7\":\"pBNp_Dx5lVVKPG26mvda7\",\"fvb1vSq-BsQ5G8WSGRNm_\":\"fvb1vSq-BsQ5G8WSGRNm_\",\"d2-rush-http-logs--hnZ2W96iFh-TqHnkCoG9K\":\"[Data2] Table for Rush HTTPListener hnZ2W96iFh-TqHnkCoG9K\",\"d2-rush-http-logs--OawAp0CkoHZ39VXUJFx14\":\"[Data2] Table for Rush HTTPListener OawAp0CkoHZ39VXUJFx14\",\"gmNR7mtDr3FudrjncHH1o\":\"gmNR7mtDr3FudrjncHH1o\",\"c1OFEYxWyhrQBxg7EQj0Q\":\"c1OFEYxWyhrQBxg7EQj0Q\",\"UvUbQsAi1RlnrX0AgGJep\":\"UvUbQsAi1RlnrX0AgGJep\",\"d2-rush-email-logs--4sJtg3IlZKvtb4rD8if4l\":\"[Data2] Table for Rush EmailListener 4sJtg3IlZKvtb4rD8if4l\",\"Q_X3yLfPYSkT1_iQnvwb5\":\"Q_X3yLfPYSkT1_iQnvwb5\",\"d2-rush-http-logs--YeUPT1GLa2TSUqjIEVHT2\":\"[Data2] Table for Rush HTTPListener YeUPT1GLa2TSUqjIEVHT2\",\"d2-rush-http-logs--DPqgghE_YHVgl5KEqwnIr\":\"[Data2] Table for Rush HTTPListener DPqgghE_YHVgl5KEqwnIr\",\"d2-rush-http-logs--jBoEeRucjC6BQ3jF4-X52\":\"[Data2] Table for Rush HTTPListener jBoEeRucjC6BQ3jF4-X52\",\"d2-rush-http-logs--k2TMMnbqr_Y_GYcoTZBHg\":\"[Data2] Table for Rush HTTPListener k2TMMnbqr_Y_GYcoTZBHg\",\"d2-rush-http-logs--1STC6oYDzP4UMk3y374qF\":\"[Data2] Table for Rush HTTPListener 1STC6oYDzP4UMk3y374qF\",\"d2-rush-http-logs--IHLWZillcz2W9ubjBx_01\":\"[Data2] Table for Rush HTTPListener IHLWZillcz2W9ubjBx_01\",\"QfISC3DFnqpEyd9TRJAzZ\":\"QfISC3DFnqpEyd9TRJAzZ\",\"d2-rush-http-logs--puL6J6fn-ylMtJ9n-o7KY\":\"d2-rush-http-logs--puL6J6fn-ylMtJ9n-o7KY\",\"d2-rush-scheduler-logs--U0oxiXTH_M-3ikGqZYXjd\":\"[Data2] Table for Rush Scheduler U0oxiXTH_M-3ikGqZYXjd\",\"Moiuq_CX03a61mFT7Klnp\":\"Moiuq_CX03a61mFT7Klnp\",\"L_C3xozqUlk-A8px5QLTb\":\"L_C3xozqUlk-A8px5QLTb\",\"HVxgx7XA2lKt_KnBjUBTB\":\"HVxgx7XA2lKt_KnBjUBTB\",\"TYxV2_I-GPn8oDPUky0fN\":\"TYxV2_I-GPn8oDPUky0fN\",\"d2-rush-http-logs--qDCzU0TUwF0l-yJ8O7gmu\":\"d2-rush-http-logs--qDCzU0TUwF0l-yJ8O7gmu\",\"d2-rush-http-logs--B3TO32lZOPuzEW-QljeZ3\":\"d2-rush-http-logs--B3TO32lZOPuzEW-QljeZ3\",\"d2-rush-http-logs--4h7IkBcYJymBD6yYUMM6W\":\"[Data2] Table for Rush HTTPListener 4h7IkBcYJymBD6yYUMM6W\",\"l2jV2RWHvaB4mr_C4ScGk\":\"l2jV2RWHvaB4mr_C4ScGk\",\"YbeJHrjYPYEphsGItCIb-\":\"YbeJHrjYPYEphsGItCIb-\",\"BMHq0NizHgDZZWeyl-0T0\":\"BMHq0NizHgDZZWeyl-0T0\",\"y1Tzq6qstzA17p_5zl-tZ\":\"y1Tzq6qstzA17p_5zl-tZ\",\"OT856KO8nvmNWfitOmOyK\":\"OT856KO8nvmNWfitOmOyK\",\"d2-rush-http-logs--arcr-7cfBBuibKldVkW5u\":\"d2-rush-http-logs--arcr-7cfBBuibKldVkW5u\",\"d2-rush-scheduler-logs--42jKFZ2UKFWGKH8fqix61\":\"d2-rush-scheduler-logs--42jKFZ2UKFWGKH8fqix61\",\"Dggo063CYnSQhYdR1Hmwu\":\"Dggo063CYnSQhYdR1Hmwu\",\"Ha0OqTqmskfV76pmwQlnT\":\"Ha0OqTqmskfV76pmwQlnT\",\"d2-rush-email-logs--aAuM_I24P322rGD0eZ-UG\":\"[Data2] Table for Rush EmailListener aAuM_I24P322rGD0eZ-UG\",\"k9Sux5mYrSspxhuCiDvTh\":\"k9Sux5mYrSspxhuCiDvTh\",\"HgbZAnQAkWOiuMaE6oZ8g\":\"HgbZAnQAkWOiuMaE6oZ8g\",\"jsX0qbjTb9gardw8U-Vie\":\"jsX0qbjTb9gardw8U-Vie\",\"d2-rush-http-logs--ZcM9eKM2Ya4g7QyZobKFr\":\"[Data2] Table for Rush HTTPListener ZcM9eKM2Ya4g7QyZobKFr\",\"2AETGaOTk7ZGHxtqmDW7v\":\"2AETGaOTk7ZGHxtqmDW7v\",\"THatiho8WzGHrJLPdMwp6\":\"THatiho8WzGHrJLPdMwp6\",\"d2-rush-http-logs--w87kUf8cR2vVtWvmlX5hT\":\"[Data2] Table for Rush HTTPListener w87kUf8cR2vVtWvmlX5hT\",\"pB5o5dIVOI3dFPYh4Z5-6\":\"pB5o5dIVOI3dFPYh4Z5-6\",\"d2-rush-scheduler-logs--AJXZof1A1pfyQzfgrFTHX\":\"[Data2] Table for Rush Scheduler AJXZof1A1pfyQzfgrFTHX\",\"d2-rush-http-logs--RXY80sBle-SCzqcktQdVA\":\"d2-rush-http-logs--RXY80sBle-SCzqcktQdVA\",\"d2-rush-http-logs--oJaRNIv2Ecb1vbhAPs9_-\":\"[Data2] Table for Rush HTTPListener oJaRNIv2Ecb1vbhAPs9_-\",\"vWu3lcHae7GkAjo23jxe4\":\"vWu3lcHae7GkAjo23jxe4\",\"d2-rush-http-logs--8lEbF3hNdqDbHJWIrBRgh\":\"d2-rush-http-logs--8lEbF3hNdqDbHJWIrBRgh\",\"Cc19NKR5j4Bo17AMwT3mL\":\"Cc19NKR5j4Bo17AMwT3mL\",\"09_HqPBV3JTqoThr3oJ7o\":\"09_HqPBV3JTqoThr3oJ7o\",\"y8sxzSs2FFwpETtX4V_AA\":\"y8sxzSs2FFwpETtX4V_AA\",\"EXGIIYT_N9-Iu78i15bQJ\":\"EXGIIYT_N9-Iu78i15bQJ\",\"d2-rush-http-logs--Ocxwf0-R7gpqn6mVrHBDu\":\"[Data2] Table for Rush HTTPListener Ocxwf0-R7gpqn6mVrHBDu\",\"8eNIKjTqm0_aqg0aZBblJ\":\"8eNIKjTqm0_aqg0aZBblJ\",\"zQRMlahLTX69P7LDPxVVS\":\"zQRMlahLTX69P7LDPxVVS\",\"rz80Il3C4_IbjUhlBB0N-\":\"rz80Il3C4_IbjUhlBB0N-\",\"d2-rush-http-logs--EHk7sTcGvfp2_VaaGHEk1\":\"[Data2] Table for Rush HTTPListener EHk7sTcGvfp2_VaaGHEk1\",\"KzZA2Ck_fPz8-mIUWrmPD\":\"KzZA2Ck_fPz8-mIUWrmPD\",\"YwJapjarCLY13f0zc6IIR\":\"YwJapjarCLY13f0zc6IIR\",\"d2-rush-http-logs--eBYfi0salfrHMOi2kgw6m\":\"[Data2] Table for Rush HTTPListener eBYfi0salfrHMOi2kgw6m\",\"d2-rush-http-logs--BN8jO-BDUEpxB9_AcM6Kg\":\"[Data2] Table for Rush HTTPListener BN8jO-BDUEpxB9_AcM6Kg\",\"IiqUenZ70kgMYe3d_kBBl\":\"IiqUenZ70kgMYe3d_kBBl\",\"d2-rush-email-logs--i5W24aHHKkJ5EKal7HyMd\":\"[Data2] Table for Rush EmailListener i5W24aHHKkJ5EKal7HyMd\",\"WUN-aj69Vl9R3yWSlkcd8\":\"WUN-aj69Vl9R3yWSlkcd8\",\"69WbiV9UOJ3xZwQeeFDs2\":\"69WbiV9UOJ3xZwQeeFDs2\",\"ZlA4-caSzV3wDlK3MlRjk\":\"ZlA4-caSzV3wDlK3MlRjk\",\"F89DTQF9zQ44GlaDFSEfL\":\"F89DTQF9zQ44GlaDFSEfL\",\"d2-rush-http-logs--lgu1CDTK7tymaAKKAgQA7\":\"[Data2] Table for Rush HTTPListener lgu1CDTK7tymaAKKAgQA7\",\"zMFaDYo-12Ow6ANJN53jE\":\"zMFaDYo-12Ow6ANJN53jE\",\"rjtnt4zvEXGBf6iilTUKx\":\"rjtnt4zvEXGBf6iilTUKx\",\"d2-rush-http-logs--hRYzykKXhz5KAbvFgGFg-\":\"d2-rush-http-logs--hRYzykKXhz5KAbvFgGFg-\",\"d2-rush-http-logs--THZG9ndzCZtpFiaFkGq8Z\":\"[Data2] Table for Rush HTTPListener THZG9ndzCZtpFiaFkGq8Z\",\"Kp3gg4R5MJ4_hUqPVvCMu\":\"Kp3gg4R5MJ4_hUqPVvCMu\",\"d2-rush-http-logs--d7DkLtfBjAMC83AedZQFe\":\"d2-rush-http-logs--d7DkLtfBjAMC83AedZQFe\",\"d2-rush-scheduler-logs--0Rpoh-mHN6e4fkJYzRu6P\":\"d2-rush-scheduler-logs--0Rpoh-mHN6e4fkJYzRu6P\",\"FapLkdYHTOx5Ucn-XSEou\":\"FapLkdYHTOx5Ucn-XSEou\",\"SbaOQyd4ieq-3j5KFzur0\":\"SbaOQyd4ieq-3j5KFzur0\",\"d2-rush-http-logs--PBVmWvvcmhTuhT3FRYbsK-prod\":\"[Data2] Table for Rush HTTPListener PBVmWvvcmhTuhT3FRYbsK-prod\",\"fU-sT2IR-BpT0CcgFpUil\":\"fU-sT2IR-BpT0CcgFpUil\",\"d2-rush-http-logs--9C7zGkNKkKdVqzd3zqNjM\":\"d2-rush-http-logs--9C7zGkNKkKdVqzd3zqNjM\",\"EbvJyddiPgCCuTUdSfw9S\":\"EbvJyddiPgCCuTUdSfw9S\",\"d2-rush-http-logs--a97y0eYSXO7J9ozN4oTz1\":\"[Data2] Table for Rush HTTPListener a97y0eYSXO7J9ozN4oTz1\",\"d2-rush-http-logs--py881QfJuzQ72gtNZPcXD\":\"[Data2] Table for Rush HTTPListener py881QfJuzQ72gtNZPcXD\",\"d2-rush-http-logs--rLSU_-d3Wm3ANqAZyAD4l\":\"[Data2] Table for Rush HTTPListener rLSU_-d3Wm3ANqAZyAD4l\",\"d2-rush-http-logs--Co8i3u9GVuwSQZLlVdC_7\":\"[Data2] Table for Rush HTTPListener Co8i3u9GVuwSQZLlVdC_7\",\"ilBDwH1WEmRRZlm6cKipM\":\"ilBDwH1WEmRRZlm6cKipM\",\"gHWkvNwOYN_Es8XlXojWf\":\"gHWkvNwOYN_Es8XlXojWf\",\"pExvlFJA9RI_MG7Vv1nna\":\"pExvlFJA9RI_MG7Vv1nna\",\"jkCAKezI3sXJzA1x4GzNY\":\"jkCAKezI3sXJzA1x4GzNY\",\"99Mz4W3ULyVDSXo6oz1Io\":\"99Mz4W3ULyVDSXo6oz1Io\",\"d2-rush-http-logs--ALEeEFrl8TvthcCSejWl9\":\"d2-rush-http-logs--ALEeEFrl8TvthcCSejWl9\",\"8OpRfxW3awFos-II88jvs\":\"8OpRfxW3awFos-II88jvs\",\"3OSaEvz9hY2EWfhC1JOAM\":\"3OSaEvz9hY2EWfhC1JOAM\",\"d2-rush-http-logs--1L2mlmHPJfV-WnkP6aScQ\":\"[Data2] Table for Rush HTTPListener 1L2mlmHPJfV-WnkP6aScQ\",\"e475439WuGwTt9OHsX0Z1\":\"e475439WuGwTt9OHsX0Z1\",\"19B_46q6_lF93v6zW139k\":\"19B_46q6_lF93v6zW139k\",\"d2-rush-http-logs--Do0_kxMBctk9pzxR2MwMj\":\"[Data2] Table for Rush HTTPListener Do0_kxMBctk9pzxR2MwMj\",\"cgGv9RZJuHKysdIsa3Cos\":\"cgGv9RZJuHKysdIsa3Cos\",\"w5KcP0bHW4jRhbLBRar7C\":\"w5KcP0bHW4jRhbLBRar7C\",\"d2-rush-http-logs--YPN1DYpUMI_ziUXiBHQqa\":\"d2-rush-http-logs--YPN1DYpUMI_ziUXiBHQqa\",\"d2-rush-http-logs--x6ZIVYSadsQLQ4DPBdmzr\":\"[Data2] Table for Rush HTTPListener x6ZIVYSadsQLQ4DPBdmzr\",\"d2-rush-http-logs--rToYJDwuN6bpnaAmN4v0h\":\"[Data2] Table for Rush HTTPListener rToYJDwuN6bpnaAmN4v0h\",\"d2-rush-http-logs--iMJWRn1GPjx1dQd46vueZ\":\"[Data2] Table for Rush HTTPListener iMJWRn1GPjx1dQd46vueZ\",\"1HmzK7srgRVGEc_TG4XMP\":\"1HmzK7srgRVGEc_TG4XMP\",\"d2-rush-http-logs--vJOJE-UAe7qHpAHqfQF1v\":\"[Data2] Table for Rush HTTPListener vJOJE-UAe7qHpAHqfQF1v\",\"AAIsd-mcUjlkQvZNKKBvl\":\"AAIsd-mcUjlkQvZNKKBvl\",\"DQ1Es4gTIzPags8NRUX6M\":\"DQ1Es4gTIzPags8NRUX6M\",\"d2-rush-http-logs--rQSpj5Fdj0KlsOHGk4mkQ\":\"[Data2] Table for Rush HTTPListener rQSpj5Fdj0KlsOHGk4mkQ\",\"d2-rush-scheduler-logs--woRd0L6WbsPVs2Gu1S6Zb\":\"[Data2] Table for Rush Scheduler woRd0L6WbsPVs2Gu1S6Zb\",\"gd9Tkk1HBicRB_pUH4xpv\":\"gd9Tkk1HBicRB_pUH4xpv\",\"d2-rush-scheduler-logs--b-5nsf8z83C9P54GttaGJ\":\"[Data2] Table for Rush Scheduler b-5nsf8z83C9P54GttaGJ\",\"d2-rush-http-logs--WIUoOAOAW0Q_yVVjz5xK_\":\"[Data2] Table for Rush HTTPListener WIUoOAOAW0Q_yVVjz5xK_\",\"d2-rush-http-logs--R2d3AKF6hJrr7XFB8zXVG\":\"[Data2] Table for Rush HTTPListener R2d3AKF6hJrr7XFB8zXVG\",\"d2-rush-http-logs--VVaPfPD880sI8jg-I7uE3\":\"[Data2] Table for Rush HTTPListener VVaPfPD880sI8jg-I7uE3\",\"d2-rush-http-logs--lQGCU0VVQfx9EgU1ERS1t\":\"[Data2] Table for Rush HTTPListener lQGCU0VVQfx9EgU1ERS1t\",\"aXKRU2mu8lP4ylgWJ8IzH\":\"aXKRU2mu8lP4ylgWJ8IzH\",\"d2-rush-http-logs--AtoOjhTYyjsFt7H10IS-d\":\"[Data2] Table for Rush HTTPListener AtoOjhTYyjsFt7H10IS-d\",\"J3WGi_61Hi1Ho258nhXno\":\"J3WGi_61Hi1Ho258nhXno\",\"d2-rush-http-logs--r6p6XcD4pyYrl0ZQ1svcN\":\"[Data2] Table for Rush HTTPListener r6p6XcD4pyYrl0ZQ1svcN\",\"d2-rush-http-logs--WR38gPHj6UDqYgwMG54vG\":\"d2-rush-http-logs--WR38gPHj6UDqYgwMG54vG\",\"d2-rush-http-logs--f7NKCp31JgkniBUFh76Qt\":\"d2-rush-http-logs--f7NKCp31JgkniBUFh76Qt\",\"d2-rush-http-logs--DS6I60MyNlCW9qVQEtdUw\":\"[Data2] Table for Rush HTTPListener DS6I60MyNlCW9qVQEtdUw\",\"d2-rush-http-logs---yK2Se0PzErtXYQwVvbpN\":\"d2-rush-http-logs---yK2Se0PzErtXYQwVvbpN\",\"d2-rush-http-logs--W4KLoZStjqg1g_fFeBoWz\":\"[Data2] Table for Rush HTTPListener W4KLoZStjqg1g_fFeBoWz\",\"lylWySeuwO3drhvaYZs6H\":\"lylWySeuwO3drhvaYZs6H\",\"2b6T0x4ySG0AXYFSLZmOJ\":\"2b6T0x4ySG0AXYFSLZmOJ\",\"d2-rush-http-logs--Ccz2M5lWNLMhp4f3ii05A\":\"[Data2] Table for Rush HTTPListener Ccz2M5lWNLMhp4f3ii05A\",\"d2-rush-http-logs--HlECseNcp8wUWsOh_lucr\":\"[Data2] Table for Rush HTTPListener HlECseNcp8wUWsOh_lucr\",\"iFEU_mSrXE43PQ2ADfi0F\":\"iFEU_mSrXE43PQ2ADfi0F\",\"d2-rush-http-logs--PepDJspgKp7pVswDg1CNJ\":\"[Data2] Table for Rush HTTPListener PepDJspgKp7pVswDg1CNJ\",\"KYA09k5GT8j6NTOG8fsFj\":\"KYA09k5GT8j6NTOG8fsFj\",\"d2-rush-http-logs--BSXPYZFmF9GAk_wqnDNq4\":\"[Data2] Table for Rush HTTPListener BSXPYZFmF9GAk_wqnDNq4\",\"d2-rush-http-logs--PBVmWvvcmhTuhT3FRYbsK\":\"[Data2] Table for Rush HTTPListener PBVmWvvcmhTuhT3FRYbsK\",\"66Dq5yLMEe7WQzqtzoc-4\":\"66Dq5yLMEe7WQzqtzoc-4\",\"d2-rush-scheduler-logs--BCSNMxS5gMDw4XY10fgLI\":\"d2-rush-scheduler-logs--BCSNMxS5gMDw4XY10fgLI\",\"eWUNQliaRsYHtJ99734b0\":\"eWUNQliaRsYHtJ99734b0\",\"d2-rush-scheduler-logs--o46JnsW3-7zXSdF_w8iz7\":\"[Data2] Table for Rush Scheduler o46JnsW3-7zXSdF_w8iz7\",\"NokKcBgImfpRXCPMUSTbk\":\"NokKcBgImfpRXCPMUSTbk\",\"mEXV29FcrK02IYkEgCZ9H\":\"mEXV29FcrK02IYkEgCZ9H\",\"d2-rush-http-logs--t1XgMbwbnyg-UQkXHUzqH\":\"[Data2] Table for Rush HTTPListener t1XgMbwbnyg-UQkXHUzqH\",\"d2-rush-http-logs--YbIPAstsvgrtaf87Mxa4H\":\"d2-rush-http-logs--YbIPAstsvgrtaf87Mxa4H\",\"d2-rush-http-logs--70J44PXYXQSK6F-G0nG8r\":\"[Data2] Table for Rush HTTPListener 70J44PXYXQSK6F-G0nG8r\",\"sFsZOK_SLDVu2OwQfXNte\":\"sFsZOK_SLDVu2OwQfXNte\",\"d2-rush-http-logs--7RRHaFm33n5OWAPx_DNkg\":\"[Data2] Table for Rush HTTPListener 7RRHaFm33n5OWAPx_DNkg\",\"rUb_9gg90TVTZs5Ddc-Oc\":\"rUb_9gg90TVTZs5Ddc-Oc\",\"_fBWjM5U5nYmKXqN1DJDM\":\"_fBWjM5U5nYmKXqN1DJDM\",\"d2-rush-http-logs--1woS_1lYRZbkht2UVXh-v\":\"[Data2] Table for Rush HTTPListener 1woS_1lYRZbkht2UVXh-v\",\"d2-rush-http-logs--V3Z8Jja5renlPZNRXwYie\":\"[Data2] Table for Rush HTTPListener V3Z8Jja5renlPZNRXwYie\",\"5wbmLets06QNQBfpkt8A2\":\"5wbmLets06QNQBfpkt8A2\",\"WqYUG3VpN5SOLzjd5yFnY\":\"WqYUG3VpN5SOLzjd5yFnY\",\"mUeNCdtFlWIYAYDxG_tqi\":\"mUeNCdtFlWIYAYDxG_tqi\",\"d2-rush-http-logs--cB6tEhvTiN0hcZBBwFMZv\":\"[Data2] Table for Rush HTTPListener cB6tEhvTiN0hcZBBwFMZv\",\"d2-rush-scheduler-logs--rXtMaRcc427yv0jRnOOTe\":\"[Data2] Table for Rush Scheduler rXtMaRcc427yv0jRnOOTe\",\"d2-rush-http-logs--jyCdZdlXHNB7vLOxeJjd6\":\"[Data2] Table for Rush HTTPListener jyCdZdlXHNB7vLOxeJjd6\",\"uSxYU_rPqTeBVYxU-dkMw\":\"uSxYU_rPqTeBVYxU-dkMw\",\"gsojmb-KWvMDTOIsi7n-p\":\"gsojmb-KWvMDTOIsi7n-p\",\"d2-rush-scheduler-logs--dx6SmK5gwf-W2kfTyPF4X\":\"[Data2] Table for Rush Scheduler dx6SmK5gwf-W2kfTyPF4X\",\"d2-rush-http-logs--naeyel1lCtn2Yzk4rpcRz\":\"[Data2] Table for Rush HTTPListener naeyel1lCtn2Yzk4rpcRz\",\"pIkuHqBZUvRSWtOvS6Z8I\":\"pIkuHqBZUvRSWtOvS6Z8I\",\"d2-rush-http-logs--50ZNZk9nkuyDu85-nI5ug\":\"[Data2] Table for Rush HTTPListener 50ZNZk9nkuyDu85-nI5ug\",\"fxNu5KIm858hftHzuoZp6\":\"fxNu5KIm858hftHzuoZp6\",\"tpuhR-FpIRiJbeE7IjQX4\":\"tpuhR-FpIRiJbeE7IjQX4\",\"QX_tWcOdZLbVi73z0EAJH\":\"QX_tWcOdZLbVi73z0EAJH\",\"oscvxjwysYDhQ04GAylOk\":\"oscvxjwysYDhQ04GAylOk\",\"d2-rush-scheduler-logs--jhUhf-0hRjw63ljH5qCB6\":\"[Data2] Table for Rush Scheduler jhUhf-0hRjw63ljH5qCB6\",\"rlB3BHambYG3CPR4ZOPwc\":\"rlB3BHambYG3CPR4ZOPwc\",\"d2-rush-http-logs--7DG2U7MM-pf1OS-Gnn67L\":\"[Data2] Table for Rush HTTPListener 7DG2U7MM-pf1OS-Gnn67L\",\"d2-rush-http-logs--VMM-xjy5uXiFcpBfh98Za\":\"[Data2] Table for Rush HTTPListener VMM-xjy5uXiFcpBfh98Za\",\"d2-rush-http-logs--33aqtYKKd7G5AW3yRezeA\":\"[Data2] Table for Rush HTTPListener 33aqtYKKd7G5AW3yRezeA\",\"3zuZiGtaM2sIN4ZUyt4-l\":\"3zuZiGtaM2sIN4ZUyt4-l\",\"T6QI-cT9lDbBdMxcCICkj\":\"T6QI-cT9lDbBdMxcCICkj\",\"d2-rush-http-logs--mQ7fJAIywQCq2R4ONiMVM\":\"d2-rush-http-logs--mQ7fJAIywQCq2R4ONiMVM\",\"E0-sVRq13htpYHEE5qdbX\":\"E0-sVRq13htpYHEE5qdbX\",\"d2-rush-http-logs--_RaNU58Pp4WjIXUdFxRbt\":\"d2-rush-http-logs--_RaNU58Pp4WjIXUdFxRbt\",\"d2-rush-http-logs--8dqrP8Gsd030mo5Wp35CD\":\"[Data2] Table for Rush HTTPListener 8dqrP8Gsd030mo5Wp35CD\",\"d2-rush-http-logs--EDWOEeXuK6tWJ643YZeaJ\":\"[Data2] Table for Rush HTTPListener EDWOEeXuK6tWJ643YZeaJ\",\"3XgUIwamOv6IhtGpgQfCY\":\"3XgUIwamOv6IhtGpgQfCY\",\"d2-rush-http-logs--FzZMY2uB8JrPlFu88tZp-\":\"[Data2] Table for Rush HTTPListener FzZMY2uB8JrPlFu88tZp-\",\"d2-rush-http-logs--wdCFXJClIy2iCSmGScriE\":\"[Data2] Table for Rush HTTPListener wdCFXJClIy2iCSmGScriE\",\"d2-rush-http-logs--8P22dDeq8AAEGroxRuqBg\":\"[Data2] Table for Rush HTTPListener 8P22dDeq8AAEGroxRuqBg\",\"mPW92Cz-BIokQbWnVDSGL\":\"mPW92Cz-BIokQbWnVDSGL\",\"d2-rush-http-logs--ChAi8o2yG594CfBKKCnrq\":\"[Data2] Table for Rush HTTPListener ChAi8o2yG594CfBKKCnrq\",\"d2-rush-http-logs--LCUDoFxRkXkGyiUqzUPy2\":\"[Data2] Table for Rush HTTPListener LCUDoFxRkXkGyiUqzUPy2\",\"d2-rush-http-logs--8BbxBrlug4ffVBhEEneOr\":\"[Data2] Table for Rush HTTPListener 8BbxBrlug4ffVBhEEneOr\",\"jdRJv_yqldmMKJNHp-wLa\":\"jdRJv_yqldmMKJNHp-wLa\",\"d2-rush-scheduler-logs--iLqFlsIZybFSzlTVtKNnB\":\"[Data2] Table for Rush Scheduler iLqFlsIZybFSzlTVtKNnB\",\"d2-rush-http-logs--pNhQmYeAfxRVX_Pv6jdPw\":\"[Data2] Table for Rush HTTPListener pNhQmYeAfxRVX_Pv6jdPw\",\"p7Df4gBAqIj5pqKmIpwco\":\"p7Df4gBAqIj5pqKmIpwco\",\"d2-rush-http-logs---MPi8E2jq90tIWkio4czK\":\"[Data2] Table for Rush HTTPListener -MPi8E2jq90tIWkio4czK\",\"mh4jf3eB8kSSvrA1Hrvlr\":\"mh4jf3eB8kSSvrA1Hrvlr\",\"d2-rush-http-logs--ReKM8guLSeGSgJTrovOvg\":\"[Data2] Table for Rush HTTPListener ReKM8guLSeGSgJTrovOvg\",\"tv6Z2Cgp5ONzJZw4TiLUs\":\"tv6Z2Cgp5ONzJZw4TiLUs\",\"d2-rush-http-logs--cMghiRbGAsO4-UKPNS66d\":\"d2-rush-http-logs--cMghiRbGAsO4-UKPNS66d\",\"d2-rush-http-logs--yi3c-GepkmvjFUYggnl9j\":\"[Data2] Table for Rush HTTPListener yi3c-GepkmvjFUYggnl9j\",\"d2-rush-http-logs--qx8Aw2NW2pySfInBXA51X\":\"d2-rush-http-logs--qx8Aw2NW2pySfInBXA51X\",\"d2-rush-scheduler-logs--hZltBTTitA5c9vqeHOpAm\":\"[Data2] Table for Rush Scheduler hZltBTTitA5c9vqeHOpAm\",\"d2-rush-http-logs--aXXHhwbpE141SbgXQYtp_\":\"[Data2] Table for Rush HTTPListener aXXHhwbpE141SbgXQYtp_\",\"d2-rush-http-logs--v_4RAktPKDcC6q7IRAQ5s\":\"[Data2] Table for Rush HTTPListener v_4RAktPKDcC6q7IRAQ5s\",\"d2-rush-http-logs--TYMe9YwS84ML8i5hZAdSw\":\"d2-rush-http-logs--TYMe9YwS84ML8i5hZAdSw\",\"d2-rush-http-logs--0GyUzp4cAnSnLh8Q0v6aC\":\"d2-rush-http-logs--0GyUzp4cAnSnLh8Q0v6aC\",\"d2-rush-http-logs--rYMDbMntkEtmoXgpWKAZB\":\"[Data2] Table for Rush HTTPListener rYMDbMntkEtmoXgpWKAZB\",\"d2-rush-http-logs--kSpcay0CWMjK2PKxgzHNo\":\"d2-rush-http-logs--kSpcay0CWMjK2PKxgzHNo\",\"T5JNebX6FYRCFv01uksnX\":\"T5JNebX6FYRCFv01uksnX\",\"d2-rush-scheduler-logs--X38EYIWasHbPIuB_2BIoD\":\"[Data2] Table for Rush Scheduler X38EYIWasHbPIuB_2BIoD\",\"OqhTp_--6AeqyYqyY-sSe\":\"OqhTp_--6AeqyYqyY-sSe\",\"d2-rush-http-logs--iLeIqxpZdOgIvwp1KT03y\":\"[Data2] Table for Rush HTTPListener iLeIqxpZdOgIvwp1KT03y\",\"d2-rush-http-logs--h0xNpWu_qksX7ULLXGJ5U\":\"[Data2] Table for Rush HTTPListener h0xNpWu_qksX7ULLXGJ5U\",\"aenRe-3InW5rnaLcqa6VG\":\"aenRe-3InW5rnaLcqa6VG\",\"d2-rush-http-logs--7-iMNFazSWBgePYHOHMe8\":\"[Data2] Table for Rush HTTPListener 7-iMNFazSWBgePYHOHMe8\",\"d2-rush-http-logs--EgPM4kddN0U-urWFTY3ux\":\"[Data2] Table for Rush HTTPListener EgPM4kddN0U-urWFTY3ux\",\"Jjt3fjc77UA_xoLob6BvN\":\"Jjt3fjc77UA_xoLob6BvN\",\"d2-rush-http-logs--kE00jmOKFLyK21NYsyMDt\":\"[Data2] Table for Rush HTTPListener kE00jmOKFLyK21NYsyMDt\",\"JVixTj_DaxK49U_iUKX6h\":\"JVixTj_DaxK49U_iUKX6h\",\"d2-rush-http-logs--kNC2M25EuyYpLJZJ5kYs7\":\"d2-rush-http-logs--kNC2M25EuyYpLJZJ5kYs7\",\"blFP_7Q7TR05zTcfYa5Xn\":\"blFP_7Q7TR05zTcfYa5Xn\",\"S_nydCRoy0Pi7Eq6fsQ1c\":\"S_nydCRoy0Pi7Eq6fsQ1c\",\"HqDZ6vn8eD4Clqrp4jbLN\":\"HqDZ6vn8eD4Clqrp4jbLN\",\"wXNT3DsHyGKu1gDpVv2Qe\":\"wXNT3DsHyGKu1gDpVv2Qe\",\"VnaKoTAw17mGUg4NUaFZ7\":\"VnaKoTAw17mGUg4NUaFZ7\",\"fELj4e-PGguRt7uv0NNmQ\":\"fELj4e-PGguRt7uv0NNmQ\",\"assets\":\"assets\",\"-108q7RFWJya1KlO2lG_p\":\"New HTTPListener (106)\",\"Iuei0_9jOCSaC8p5wqE5I\":\"API_AVI_KPIS_INDICADORES_V2\",\"WmEWgHBof4tZ20sVpm9wK\":\"New HTTPListener (106)\",\"y4A1QBJj6PZjGjz0P5SzW\":\"Scheduler Agent External Catch in chat survey\",\"-qI3WX_wNZ89B9SFb-IR6\":\"Scheduler Fixer Agent Null\",\"kwd1xJwIeeVUKs83AkLZx\":\"EC CognitoIdentityProviderGetPayload\",\"LgIQ9eyXolMb_TATBdRF7\":\"cognitoSetupAccessTokens\",\"RlpaJ8M3tCp2Q4yueyDFR\":\"MiNegocioInitializeSession\",\"uii8bQSNQbfTHXyZHmmbB\":\"MiNegocioGetIdentification\",\"KEETg5uE6acsP2uYArc7C\":\"SaveReclaimRUSH\",\"9dhucdyA3IRnRa9naVQ0q\":\"Marcos Teste\",\"TSwY-BGDyOGOLaXa5t6fW\":\"KACE Identity Provider\",\"KEZqqKYwFxE2lzg1t_6lo\":\"Rework Errors in No Errors\",\"5hKTExBiwtBc3EodqGBBY\":\"Sending CSAT data to Qualtrics\",\"X3G1YtIaNDGJ1EJi_VRgv\":\"cost-report-kpi-data\",\"Data2BuilderAuthentication\":\"Autenticação do Builder (data2)\",\"645b823726c1280637133f0e\":\"Natura Hispana AVI\",\"Eu-4BuvCT5Pv589p75jeM\":\"Rush_APP\",\"RCiLYfZ9yJeGeCnxcWrI4LogReadDataSet\":\"Logs · ChatHook\",\"DKnDLQUtDA6mNdYkT8sh1LogReadDataSet\":\"Logs · audio-generator\",\"di5-RlyrJ7LB5lv9z26xaLogReadDataSet\":\"Logs · Sync Agents Metadata Job HML\",\"5MryyxAbTHsb89yVx3FAeLogReadDataSet\":\"Logs · agent-send-message-entrypoint\",\"TZtOuDXGQh24VDN9CGov0LogReadDataSet\":\"Logs · PingPong KeyVault\",\"13rnkmw96E5MrquKnnI_MLogReadDataSet\":\"Logs · agent-logs-entrypoint\",\"3NwM07fRAAi2cON2KpJi_LogReadDataSet\":\"Logs · Expire Inactive Transfers Job HML\",\"ZOpJU13MlsqJNZNScpZrsLogReadDataSet\":\"Logs · Sync Agents Metadata Job PRD\",\"0ScwQIaOMBUIdDb1x5q9RLogReadDataSet\":\"Logs · transfer-operation-entrypoint\",\"JtLDId2qjiu0sNsULsD4ELogReadDataSet\":\"Logs · Expire Inactive Transfers Job PRD\",\"PqjPbzpg-bFvxXV9qSA8TLogReadDataSet\":\"Logs · chat-ping-entrypoint\",\"PqjPbzpg-bFvxXV9qSA8TLogInsertDataSet\":\"Logs · chat-ping-entrypoint\",\"vC7Xapg8Lx7g4wfd0e_jRLogReadDataSet\":\"Logs · Detect Abandon Job HML\",\"GFNOx0PYwKYjS8oFd7U6lLogReadDataSet\":\"Logs · Detect Abandon Job PRD\",\"VXbg6FJbalOwrIJnvZIRCLogReadDataSet\":\"Logs · Copy of Peru-Authentication\",\"kr62-VRyfj1Rd58JKRaCPLogReadDataSet\":\"Logs · Copy of semantic-faq\",\"Rdzbz0sYIWKJo-DOGAS4LLogReadDataSet\":\"Logs · colombia-reply-tests\",\"VBe5cffOny7xgAxAsNd_FLogReadDataSet\":\"Logs · semantic-faq\",\"_lFzbsy_N19dug6wI83S6LogReadDataSet\":\"Logs · DEV CAll Manual Only Iterate-Queue-recursive-JOB-DEV\",\"-_As0_UIvL1WZLhYkvnEPLogReadDataSet\":\"Logs · Iterate-Queue-Auto-Healer Scheduler <- on pause due external_transfer\",\"1knLGAxuaCD2fsuMbZBH5LogReadDataSet\":\"Logs · Iterate-Queue-recursive-JOB-PRD <- on pause due external_transfer\",\"n7l-E7afYNCPYtaJzn3o_LogReadDataSet\":\"Logs · ocular-kb-entrypoint\",\"Br8NJWvy7UDUC3dKFs-DeLogReadDataSet\":\"Logs · ocular-answer-entrypoint\",\"4D2touS1KIk735CijlzJuLogReadDataSet\":\"Logs · FormsSendEmail HML\",\"4D2touS1KIk735CijlzJuLogInsertDataSet\":\"Logs · FormsSendEmail HML\",\"oN7ZFszCha8Cx6I3WefPaLogReadDataSet\":\"Logs · MAIN RUSH Forms\",\"oN7ZFszCha8Cx6I3WefPaLogInsertDataSet\":\"Logs · MAIN RUSH Forms\",\"f9mn0XCtwjCiwA2buisUMLogReadDataSet\":\"Logs · Get Seller - Rush Invoke\",\"f9mn0XCtwjCiwA2buisUMLogInsertDataSet\":\"Logs · Get Seller - Rush Invoke\",\"OXlr-pFHOSL3TyqbG_C29LogReadDataSet\":\"Logs · SubMonitoringRush\",\"SSkgjL2C2_pha_4D8YoYVLogReadDataSet\":\"Logs · Recips_infobit\",\"iZpq-fSmeaLLWLeQGh2zvLogReadDataSet\":\"Logs · Reciept-Email\",\"4G3HkuB0vUfSPAjUvThB9LogReadDataSet\":\"Logs · Webhook_InfobitData2\",\"S5Smf36KVnpAgdlXt9xU4LogReadDataSet\":\"Logs · d2-chile-entrypoint-hml\",\"S5Smf36KVnpAgdlXt9xU4LogInsertDataSet\":\"Logs · d2-chile-entrypoint-hml\",\"vRtbsuzMqlbWrwKCvjeS6LogReadDataSet\":\"Logs · d2-mexico-entrypoint-hml\",\"vRtbsuzMqlbWrwKCvjeS6LogInsertDataSet\":\"Logs · d2-mexico-entrypoint-hml\",\"xZ07GjXF6J-UE889zvhNvLogReadDataSet\":\"Logs · d2-colombia-entrypoint-hml\",\"xZ07GjXF6J-UE889zvhNvLogInsertDataSet\":\"Logs · d2-colombia-entrypoint-hml\",\"gJnyPaWs1JQSQ8CPGfzCOLogReadDataSet\":\"Logs · d2-peru-entrypoint-hml\",\"gJnyPaWs1JQSQ8CPGfzCOLogInsertDataSet\":\"Logs · d2-peru-entrypoint-hml\",\"hrfpkEcajH1t8HR61CXM2LogReadDataSet\":\"Logs · d2-no-country-entrypoint-hml\",\"hrfpkEcajH1t8HR61CXM2LogInsertDataSet\":\"Logs · d2-no-country-entrypoint-hml\",\"pzwhsvhUFlNTNfalRoReJLogReadDataSet\":\"Logs · [IVR] - FAQ Service - Colombia\",\"LmElMY813TKSrFwDI9BFdLogReadDataSet\":\"Logs · UPLOAD WIKIS Rush\",\"LmElMY813TKSrFwDI9BFdLogInsertDataSet\":\"Logs · UPLOAD WIKIS Rush\",\"X0Zduvi81uXolo0eTY6TkLogReadDataSet\":\"Logs · cari-rush\",\"X0Zduvi81uXolo0eTY6TkLogInsertDataSet\":\"Logs · cari-rush\",\"flQBZ9yWONn7dYrW-6SaOLogReadDataSet\":\"Logs · cari-data2Sec\",\"flQBZ9yWONn7dYrW-6SaOLogInsertDataSet\":\"Logs · cari-data2Sec\",\"2dQ8tHgWFqO0ULXJVmfvBLogReadDataSet\":\"Logs · BUG Auth Strategy\",\"Y1O0oTlVo3601Jif1BxNBLogReadDataSet\":\"Logs · d2-Argentina-entrypoint-hml\",\"Y1O0oTlVo3601Jif1BxNBLogInsertDataSet\":\"Logs · d2-Argentina-entrypoint-hml\",\"5paWQC7PQmA6TT7O8jfN1LogReadDataSet\":\"Logs · Get Csat Agent\",\"p9IwlndVIpNoYWO3V0RaXLogReadDataSet\":\"Logs · Auth Endpoint\",\"fNnAMBBznAO9wvOX5V9JfLogReadDataSet\":\"Logs · d2-peru-entrypoint-prd\",\"fNnAMBBznAO9wvOX5V9JfLogInsertDataSet\":\"Logs · d2-peru-entrypoint-prd\",\"W_7c3KvURCeog4RW9kzlhLogReadDataSet\":\"Logs · d2-no-country-entrypoint-prd\",\"W_7c3KvURCeog4RW9kzlhLogInsertDataSet\":\"Logs · d2-no-country-entrypoint-prd\",\"yrzdo5Ewbnp3ZaiLXV2rzLogReadDataSet\":\"Logs · d2-chile-entrypoint-prd\",\"yrzdo5Ewbnp3ZaiLXV2rzLogInsertDataSet\":\"Logs · d2-chile-entrypoint-prd\",\"v4LXRPYyAgktlbttvZyTNLogReadDataSet\":\"Logs · d2-Argentina-entrypoint-prd\",\"v4LXRPYyAgktlbttvZyTNLogInsertDataSet\":\"Logs · d2-Argentina-entrypoint-prd\",\"oV37yW1tSod7tpFyqKkxyLogReadDataSet\":\"Logs · d2-colombia-entrypoint-prd\",\"oV37yW1tSod7tpFyqKkxyLogInsertDataSet\":\"Logs · d2-colombia-entrypoint-prd\",\"AKlWpcgDjGl6n-TK_j4OYLogReadDataSet\":\"Logs · d2-mexico-entrypoint-prd\",\"AKlWpcgDjGl6n-TK_j4OYLogInsertDataSet\":\"Logs · d2-mexico-entrypoint-prd\",\"NDp1EgGs3Xn4IUTan3yhtLogReadDataSet\":\"Logs · debug ec get titles rush\",\"vwkNOgpr4qzNJdhY4JorTLogReadDataSet\":\"Logs · MotherTester\",\"mKozj09NcLOagalg-VqXaLogReadDataSet\":\"Logs · rush-ana-monthly-report-numbers\",\"TUdsI1xRqd9fQj-2U-SabLogReadDataSet\":\"Logs · EmailListenerRPA\",\"m3l1c0HBBXSL5ZRt4ZWscLogReadDataSet\":\"Logs · Scheduler Close Session\",\"m3l1c0HBBXSL5ZRt4ZWscLogInsertDataSet\":\"Logs · Scheduler Close Session\",\"pEaGKSVNxejOXqsg3EGmrLogReadDataSet\":\"Logs · RPAEmailListener\",\"pEaGKSVNxejOXqsg3EGmrLogInsertDataSet\":\"Logs · RPAEmailListener\",\"HmLW40Dug8t3rvhMmfXWYLogReadDataSet\":\"Logs · keycloak-oauth-validate-pin\",\"fU6X_mrSStaevLVbZqAKXLogReadDataSet\":\"Logs · keycloak-oauth-generate-pin\",\"JVf9xTeGFXyQYrusdL4TSLogReadDataSet\":\"Logs · contesta-preguntas-ecuador\",\"JVf9xTeGFXyQYrusdL4TSLogInsertDataSet\":\"Logs · contesta-preguntas-ecuador\",\"uDBjs8wkDtrxMpysFrTEFLogReadDataSet\":\"Logs · refactoring - select usecase\",\"uDBjs8wkDtrxMpysFrTEFLogInsertDataSet\":\"Logs · refactoring - select usecase\",\"L322Lg0jWzCvY6vhp-XRdLogReadDataSet\":\"Logs · refactoring - select FAQ\",\"DU7pDuhF-5peX6NA2K0XHLogReadDataSet\":\"Logs · refactoring - generate answer - usecase\",\"pvPH-HtYlHprLUXXnUzvrLogReadDataSet\":\"Logs · refactoring - generate answer - FAQ\",\"tl059gO4UkSn6l-rMKTX3LogReadDataSet\":\"Logs · Csat Endpoint FullD2\",\"tl059gO4UkSn6l-rMKTX3LogInsertDataSet\":\"Logs · Csat Endpoint FullD2\",\"ubp46aOre3B349mcfAeZyLogReadDataSet\":\"Logs · FAQs-entrypoint-maia\",\"ubp46aOre3B349mcfAeZyLogInsertDataSet\":\"Logs · FAQs-entrypoint-maia\",\"9EjGJRul_CfpxuxkH8uuHLogReadDataSet\":\"Logs · New HTTPListener (84)\",\"bo3vvYdwZei_1njBiiibyLogReadDataSet\":\"Logs · Do NOT DELETE! - New HTTPListener (84)\",\"sNLVZ6BazGIEpFzeJUMs0LogReadDataSet\":\"Logs · EcuadorByToken\",\"sNLVZ6BazGIEpFzeJUMs0LogInsertDataSet\":\"Logs · EcuadorByToken\",\"QOPIchK_LVwWCzYZFRpsFLogReadDataSet\":\"Logs · NI Sessions\",\"QOPIchK_LVwWCzYZFRpsFLogInsertDataSet\":\"Logs · NI Sessions\",\"20Q518uE-sB06h4JJRm-qLogReadDataSet\":\"Logs · New HTTPListener (88)\",\"rbeu3OSYD9XTKdkEKhS0dLogReadDataSet\":\"Logs · New EmailListener (3)\",\"WQVnm9MIxst3JmmSsNrjqLogReadDataSet\":\"Logs · Debug not found\",\"Q86M0LYUybVvjS0DCOmK1LogReadDataSet\":\"Logs · New Scheduler (9)\",\"AZ9vggxaGj14m9wlr4jJHLogReadDataSet\":\"Logs · Scheduler Agent External Catch\",\"AZ9vggxaGj14m9wlr4jJHLogInsertDataSet\":\"Logs · Scheduler Agent External Catch\",\"rM74WoHiOjwclT9OqQfSNLogReadDataSet\":\"Logs · mx-filtred-chatid-logs\",\"7hjRu6sUdMD0rREQDhF5mLogReadDataSet\":\"Logs · cl-filtred-chatid-logs\",\"Pfgl_XbCvP_MbD16we1_kLogReadDataSet\":\"Logs · co-filtred-chatid-logs\",\"ngcyRzaTIYvr455tIF1kzLogReadDataSet\":\"Logs · pe-filtred-chatid-logs\",\"fr53sxeRFZ4z97aNvd0fsLogReadDataSet\":\"Logs · ar-filtred-chatid-logs\",\"XyWU5I35B-xol8vj6E68ALogReadDataSet\":\"Logs · ec-filtred-chatid-logs\",\"JJMYzP0l4WL2syVjR3Le5LogReadDataSet\":\"Logs · sinch-ar-filtred-logs\",\"jC_thuwiDg9xvEdlEv2W4LogReadDataSet\":\"Logs · cari-rush-filtred-logs\",\"jC_thuwiDg9xvEdlEv2W4LogInsertDataSet\":\"Logs · cari-rush-filtred-logs\",\"JOBH4QXjA1tsc4k_iGjywLogReadDataSet\":\"Logs · getData-infoMaia\",\"3O7jD2oTEfg5C-guYPntfLogReadDataSet\":\"Logs · fix env null\",\"GYCxKrHJQUBAN7ELG_6cpLogReadDataSet\":\"Logs · getTime - Forms-Rush\",\"GYCxKrHJQUBAN7ELG_6cpLogInsertDataSet\":\"Logs · getTime - Forms-Rush\",\"llsRwO29b2x_HqelU2ZwKLogReadDataSet\":\"Logs · Messages Controler in Queue\",\"llsRwO29b2x_HqelU2ZwKLogInsertDataSet\":\"Logs · Messages Controler in Queue\",\"zKLNT-goyFRBK6gnQMwFaLogReadDataSet\":\"Logs · New HTTPListener (98)\",\"M4ZqtoUWz2tvH6eepqVIxLogReadDataSet\":\"Logs · scheduler fix complete session ended data\",\"M4ZqtoUWz2tvH6eepqVIxLogInsertDataSet\":\"Logs · scheduler fix complete session ended data\",\"9GWeJ6GdPB6e2N1ILfQuRLogReadDataSet\":\"Logs · Close Session Manually\",\"9GWeJ6GdPB6e2N1ILfQuRLogInsertDataSet\":\"Logs · Close Session Manually\",\"t318vm-mHbHCN0mCySu5gLogReadDataSet\":\"Logs · Api Executions with NO NAME\",\"t318vm-mHbHCN0mCySu5gLogInsertDataSet\":\"Logs · Api Executions with NO NAME\",\"SInspt5Zks0QPlfoBB3IaLogReadDataSet\":\"Logs · API_CSAT_QUALTRICS_FORMS\",\"SInspt5Zks0QPlfoBB3IaLogInsertDataSet\":\"Logs · API_CSAT_QUALTRICS_FORMS\",\"lGLpiM1QQvJwQKrxn8NcTLogReadDataSet\":\"Logs · Comment Duplicator <31/03\",\"zqWM3dlAnLhOUVTw_vRNSLogReadDataSet\":\"Logs · Scheduler Catch data to report cancel Order\",\"zqWM3dlAnLhOUVTw_vRNSLogInsertDataSet\":\"Logs · Scheduler Catch data to report cancel Order\",\"RAcxhTZr3D7Hmj37bgkCcLogReadDataSet\":\"Logs · Copy of d2-colombia-entrypoint-hml\",\"RAcxhTZr3D7Hmj37bgkCcLogInsertDataSet\":\"Logs · Copy of d2-colombia-entrypoint-hml\",\"QrT1-4d2hrSFAZMKGbtA3LogReadDataSet\":\"Logs · New HTTPListener (102)\",\"5iNOjWfW6z69unNZhpPxWLogReadDataSet\":\"Logs · API_AVI_KPIS\",\"5iNOjWfW6z69unNZhpPxWLogInsertDataSet\":\"Logs · API_AVI_KPIS\",\"pqwZ2g4lvKhd7c1-7FltPLogReadDataSet\":\"Logs · API_AVI_KPIS_INDICADORES\",\"pqwZ2g4lvKhd7c1-7FltPLogInsertDataSet\":\"Logs · API_AVI_KPIS_INDICADORES\",\"M8Hu0reR498Ik_baDQGtBLogReadDataSet\":\"Logs · New HTTPListener (105)\",\"fWvjFunmTK_hY0lFQbjR6LogReadDataSet\":\"Logs · Delete Old Entries In - Last Messages On Whatsapp\",\"fWvjFunmTK_hY0lFQbjR6LogInsertDataSet\":\"Logs · Delete Old Entries In - Last Messages On Whatsapp\",\"-qI3WX_wNZ89B9SFb-IR6LogReadDataSet\":\"Logs · Scheduler Fixer Agent Null\",\"kwd1xJwIeeVUKs83AkLZxLogReadDataSet\":\"Logs · EC CognitoIdentityProviderGetPayload\",\"kwd1xJwIeeVUKs83AkLZxLogInsertDataSet\":\"Logs · EC CognitoIdentityProviderGetPayload\",\"LgIQ9eyXolMb_TATBdRF7LogReadDataSet\":\"Logs · cognitoSetupAccessTokens\",\"LgIQ9eyXolMb_TATBdRF7LogInsertDataSet\":\"Logs · cognitoSetupAccessTokens\",\"RlpaJ8M3tCp2Q4yueyDFRLogReadDataSet\":\"Logs · MiNegocioInitializeSession\",\"RlpaJ8M3tCp2Q4yueyDFRLogInsertDataSet\":\"Logs · MiNegocioInitializeSession\",\"uii8bQSNQbfTHXyZHmmbBLogReadDataSet\":\"Logs · MiNegocioGetIdentification\",\"uii8bQSNQbfTHXyZHmmbBLogInsertDataSet\":\"Logs · MiNegocioGetIdentification\",\"KEETg5uE6acsP2uYArc7CLogReadDataSet\":\"Logs · SaveReclaimRUSH\",\"KEETg5uE6acsP2uYArc7CLogInsertDataSet\":\"Logs · SaveReclaimRUSH\",\"9dhucdyA3IRnRa9naVQ0qLogReadDataSet\":\"Logs · Marcos Teste\",\"9dhucdyA3IRnRa9naVQ0qLogInsertDataSet\":\"Logs · Marcos Teste\",\"TSwY-BGDyOGOLaXa5t6fWLogReadDataSet\":\"Logs · KACE Identity Provider\",\"TSwY-BGDyOGOLaXa5t6fWLogInsertDataSet\":\"Logs · KACE Identity Provider\",\"KEZqqKYwFxE2lzg1t_6loLogReadDataSet\":\"Logs · Rework Errors in No Errors\",\"KEZqqKYwFxE2lzg1t_6loLogInsertDataSet\":\"Logs · Rework Errors in No Errors\",\"5hKTExBiwtBc3EodqGBBYLogReadDataSet\":\"Logs · Sending CSAT data to Qualtrics\",\"5hKTExBiwtBc3EodqGBBYLogInsertDataSet\":\"Logs · Sending CSAT data to Qualtrics\",\"X3G1YtIaNDGJ1EJi_VRgvLogReadDataSet\":\"Logs · cost-report-kpi-data\",\"X3G1YtIaNDGJ1EJi_VRgvLogInsertDataSet\":\"Logs · cost-report-kpi-data\",\"Eu-4BuvCT5Pv589p75jeMLogReadDataSet\":\"Logs · Rush_APP\",\"roE_vjIAYEoYdX9ymhaUJ\":\"AgentSocketClient\",\"lTQRb152dXh5ddifgEM_J\":\"UserSocketClient\"};\n\nconst PRICES = {\"BUILDER|sessions\":{\"p\":null,\"u\":\"sessões\",\"k\":\"flow\",\"agg1\":\"sum\",\"n\":\"não faturado por dia — a fatura cobra BUILDER/logged_users (US$ 10/usuário/mês)\",\"dim\":\"authentication_strategy.reference\"},\"BUILDER|login\":{\"p\":null,\"u\":\"logins\",\"k\":\"flow\",\"agg1\":\"avg\",\"n\":\"nível 1 é MÉDIA por estratégia — só o detalhe soma\",\"dim\":\"authentication_strategy.reference\"},\"ID|sessions\":{\"p\":null,\"u\":\"sessões\",\"k\":\"flow\",\"agg1\":\"sum\",\"n\":\"não faturado por dia — a fatura cobra ID/logged_users (US$ 0,10/usuário/mês)\",\"dim\":\"system.id\"},\"ID|login\":{\"p\":null,\"u\":\"logins\",\"k\":\"flow\",\"agg1\":\"avg\",\"n\":\"nível 1 é MÉDIA por estratégia — só o detalhe soma\",\"dim\":\"authentication_strategy.reference\"},\"TABLE|read\":{\"p\":1e-05,\"u\":\"leituras\",\"k\":\"flow\",\"agg1\":\"sum\",\"dim\":\"dataset.reference\"},\"TABLE|write\":{\"p\":0.0005,\"u\":\"escritas\",\"k\":\"flow\",\"agg1\":\"sum\",\"dim\":\"dataset.reference\"},\"TABLE|semantic_search_read_tokens\":{\"p\":6.5e-07,\"u\":\"tokens\",\"k\":\"flow\",\"agg1\":\"sum\",\"dim\":\"dataset.reference\"},\"TABLE|semantic_search_write_tokens\":{\"p\":6.5e-07,\"u\":\"tokens\",\"k\":\"flow\",\"agg1\":\"sum\",\"dim\":\"dataset.reference\"},\"TABLE|storage\":{\"p\":null,\"u\":\"B\",\"d\":1073741824,\"k\":\"stock\",\"agg1\":\"avg\",\"n\":\"MÉDIA por DataSource nos dois níveis — o total real não sai desta API (fatura jul: 533 GiB em 516 recursos, média 1,03 GiB). Preço seria US$ 25/GiB-mês.\",\"dim\":\"system.id\"},\"DRIVE|storage\":{\"p\":1,\"u\":\"B\",\"d\":1073741824,\"k\":\"stock\",\"agg1\":\"avg\",\"mo\":true,\"n\":\"nível 1 é MÉDIA por drive — o total é a soma do detalhe (bate com a fatura)\",\"dim\":\"drive.reference\"},\"DRIVE|read_size\":{\"p\":1,\"u\":\"B\",\"d\":1073741824,\"k\":\"flow\",\"agg1\":\"sum\",\"n\":\"detalhe por arquivo: >500 linhas, precisa paginar; arquivos não têm nome\",\"dim\":\"file.reference\"},\"DRIVE|screenshot\":{\"p\":null,\"u\":\"prints\",\"k\":\"flow\",\"agg1\":\"sum\"},\"DRIVE|screenshot_size\":{\"p\":null,\"u\":\"B\",\"d\":1073741824,\"k\":\"flow\",\"agg1\":\"sum\"},\"DRIVE|screenshot_time\":{\"p\":null,\"u\":\"ms\",\"k\":\"flow\",\"agg1\":\"sum\"},\"DOMAIN|ai_tokens\":{\"p\":0.000008,\"u\":\"tokens\",\"k\":\"flow\",\"agg1\":\"sum\",\"dim\":\"assistant.reference\",\"neg\":true,\"n\":\"Preço acordado (private deal): US$ 0,000008 por token. As faturas de mai, jun e jul/26 registram US$ 0,0001, que é o preço de tabela — exatamente 12,5x maior. Por isso o total desta tela é o custo real e NÃO reconcilia com o valor faturado.\"},\"DOMAIN|ai_speech_to_text_seconds\":{\"p\":0.0003,\"u\":\"seg\",\"k\":\"flow\",\"agg1\":\"sum\",\"dim\":\"assistant.reference\"},\"DOMAIN|ai_speech_to_text_minutes\":{\"p\":null,\"u\":\"min\",\"k\":\"flow\",\"agg1\":\"sum\",\"n\":\"não faturado — a fatura cobra os SEGUNDOS; contar os dois seria dupla contagem\",\"dim\":\"assistant.reference\"},\"DOMAIN|ai_text_to_speech_characters\":{\"p\":4.8e-05,\"u\":\"chars\",\"k\":\"flow\",\"agg1\":\"sum\",\"dim\":\"assistant.reference\"},\"DOMAIN|ai_ocr_pages\":{\"p\":null,\"u\":\"páginas\",\"k\":\"flow\",\"agg1\":\"sum\",\"n\":\"sem preço na fatura de jul/26\"},\"DOMAIN|ai_images\":{\"p\":null,\"u\":\"imagens\",\"k\":\"flow\",\"agg1\":\"sum\",\"n\":\"sem preço na fatura de jul/26\"},\"RUSH|http_listener\":{\"p\":0.0001,\"u\":\"execuções\",\"k\":\"flow\",\"agg1\":\"sum\",\"dim\":\"listener.reference\"},\"RUSH|http_listener_duration\":{\"p\":6.68e-08,\"u\":\"ms\",\"k\":\"flow\",\"agg1\":\"sum\",\"dim\":\"listener.reference\"},\"RUSH|scheduler\":{\"p\":0.0001,\"u\":\"execuções\",\"k\":\"flow\",\"agg1\":\"sum\",\"dim\":\"scheduler.reference\"},\"RUSH|scheduler_duration\":{\"p\":6.68e-08,\"u\":\"ms\",\"k\":\"flow\",\"agg1\":\"sum\",\"dim\":\"scheduler.reference\"},\"RUSH|email_listener\":{\"p\":0.00013,\"u\":\"execuções\",\"k\":\"flow\",\"agg1\":\"sum\",\"dim\":\"listener.reference\"},\"RUSH|email_listener_chunks\":{\"p\":0.000468,\"u\":\"chunks\",\"k\":\"flow\",\"agg1\":\"sum\",\"dim\":\"listener.reference\"},\"RUSH|email_listener_duration\":{\"p\":8.684e-08,\"u\":\"ms\",\"k\":\"flow\",\"agg1\":\"sum\",\"dim\":\"listener.reference\"},\"CONNECT|request\":{\"p\":0.0001,\"u\":\"requisições\",\"k\":\"flow\",\"agg1\":\"sum\",\"dim\":\"request.path\"},\"CONNECT|request_time\":{\"p\":6.68e-08,\"u\":\"ms\",\"k\":\"flow\",\"agg1\":\"sum\",\"dim\":\"request.path\"},\"CONNECT|socket_connection\":{\"p\":0,\"u\":\"conexões\",\"k\":\"flow\",\"agg1\":\"sum\",\"n\":\"preço 0 na fatura\",\"dim\":\"power_cord_socket.reference\"},\"CONNECT|socket_duration\":{\"p\":0,\"u\":\"ms\",\"k\":\"flow\",\"agg1\":\"sum\",\"n\":\"preço 0 na fatura\",\"dim\":\"power_cord_socket.reference\"},\"CONNECT|invite_send\":{\"p\":null,\"u\":\"convites\",\"k\":\"flow\",\"agg1\":\"sum\",\"n\":\"sem preço na fatura de jul/26\"},\"CONNECT|mail_send\":{\"p\":null,\"u\":\"e-mails\",\"k\":\"flow\",\"agg1\":\"sum\",\"n\":\"sem preço na fatura de jul/26\"},\"CONNECT|aws_s3_put\":{\"p\":null,\"u\":\"puts\",\"k\":\"flow\",\"agg1\":\"sum\",\"n\":\"sem preço na fatura de jul/26\"},\"CONNECT|aws_athena_query\":{\"p\":null,\"u\":\"queries\",\"k\":\"flow\",\"agg1\":\"sum\",\"n\":\"sem preço na fatura de jul/26\"},\"CONNECT|whatsapp_messenger_instance\":{\"p\":null,\"u\":\"instâncias\",\"k\":\"flow\",\"agg1\":\"sum\",\"n\":\"sem preço na fatura de jul/26\"},\"TABLE|key_used\":{\"p\":null,\"u\":\"usos\",\"k\":\"flow\",\"agg1\":\"sum\"},\"ID|key_used\":{\"p\":null,\"u\":\"usos\",\"k\":\"flow\",\"agg1\":\"sum\"}};\n\n/*C0*/\nconst PROD_COLOR = {\n  DOMAIN: '#e619c8', TABLE: '#e11d48', ID: '#12c9b8', RUSH: '#8b5cf6',\n  CONNECT: '#14b3e8', DRIVE: '#eab308', BUILDER: '#64748b',\n  PESSOAS: '#22c55e'   // custo de alocação; sem esta cor o empilhado emitiria fill=\"undefined\"\n};\n// PESSOAS por último = faixa no TOPO da pilha. Sem a entrada aqui, chartStacked descarta o valor\n// EM SILÊNCIO (ele monta as faixas com PROD_ORDER.filter), e o gráfico deixaria de bater com o KPI.\nconst PROD_ORDER = ['DOMAIN', 'TABLE', 'RUSH', 'CONNECT', 'DRIVE', 'ID', 'BUILDER', 'PESSOAS'];\nconst BASE_KEYS = new Set(['date', 'product', 'measure_name', 'measure_value_type', 'sum_measure_value']);\n\nconst MAX_DAYS = 7;      // dias avulsos na visão diária\nconst MIN_DAYS = 2;      // mesmo piso do semanal: com UM período o único período é a base, e elasticidade,\n                         // impacto e tendência ficam indefinidos — o relatório sai sem comparação nenhuma\n// A visão semanal aceita 2 ou 3 janelas. O piso é 2 porque com UMA semana o período-base seria o\n// único período: não sobra nada contra o que comparar, e elasticidade/impacto ficariam indefinidos.\n// O teto é 4: com 4 janelas a leitura vira de PROGRESSÃO (a reta sobre os 4 pontos), que é o que\n// separa \"subiu e voltou\" de \"alta consistente\". A quinta só somaria carga sem mudar essa leitura.\nconst WEEKS_MIN = 2;\nconst WEEKS_MAX = 4;\nconst WEEK_LEN = 7;\nconst PAGE = 500;\nconst MAX_PAGES = 3;     // teto de páginas por (período, evento) — truncagem é SINALIZADA\nconst MAX_PAGES_W = 8;   // medido: uma semana de TABLE/read são 1.748 linhas = 4 páginas; com teto 2 o\n                         // drill-down via 2 dias de 7 (34,6% do volume) e subestimava o por-sessão em ~2,9×.\n                         // O laço sai sozinho na exaustão, então teto alto só custa chamada onde há dado:\n                         // de todos os pares (período, evento) carregados, só TABLE/read passa de 2 páginas.\nconst POOL = 6;\n// Só o par de MAIOR CUSTO vem pronto; o resto é sob demanda pelo botão de cada linha. A fase 2 é um\n// produto cartesiano `pares × períodos` a ~17 s por chamada, então cada par a mais custa N chamadas:\n// com 8/4 dava 33 chamadas em 3 dias e 18 em 3 semanas, e passaria de 90 em 7 dias, sem teto.\n// ⚠ Isto NÃO tira custo nenhum da tela: o custo de alto nível dos 25 pares vem da fase 1 (nível 1).\n// A fase 2 só alimenta o destrinchamento por recurso — e o `storage`, cujo nível 1 é média (ver\n// pickEager). pickEager ainda soma storage e o irmão de contagem, então o conjunto real fica em ~2.\nconst TOP_N = 1;\nconst TOP_N_W = 1;\n// Mensal: meses de CALENDÁRIO, que é o recorte da fatura. Medido hoje: 1 mês = 1 chamada de sessões\n// (3 s) + 1 de nível 1 (40 s), então 4 meses custam 16 chamadas contra as 44 de 4 semanas.\n// TOP_N_M = 0 porque no mensal só o storage vem pronto: TABLE/read num mês são ~16 páginas.\nconst MONTHS_MIN = 2;\nconst MONTHS_MAX = 4;\nconst MAX_PAGES_M = 4;   // storage num mês = 2 páginas (medido); o resto do detalhe é bloqueado no mensal\nconst TOP_N_M = 0;\n\n// ---------- alocações: custo de PESSOAS, digitado — não vem de API ----------\n// Um desenvolvedor contratado custa R$ 26.000/mês. O portal inteiro é em US$, então a conversão passa\n// por uma taxa editável na tela E impressa no PDF: sem a taxa à vista, ninguém refaz a conta.\n// ⚠️ Entra no TOTAL do mês, nunca no custo por sessão — ver o comentário em periodTotals.\nconst ALLOC_BRL = 26000;\nconst ALLOC_CUT = '2026-09-01';   // até aqui o histórico é 1 alocação; deste mês em diante, 2\nconst FX_DEFAULT = 5.40;\nconst ALLOC_MAX = 99;\nconst allocDefault = (d0) => (d0 >= ALLOC_CUT ? 2 : 1);\nconst allocOf = (st, per) => ((st.mAlloc && st.mAlloc[per.k] !== undefined)\n  ? st.mAlloc[per.k] : allocDefault(per.d0));\nconst PARETO = 0.8;      // fração do custo que define os \"TOP CUSTO\"\nconst SESS_EPS = 0.02;   // abaixo disso as sessões não se moveram o bastante p/ dividir\n\n// ---------- utilitários ----------\nconst num = (v) => { const n = Number(v); return Number.isFinite(n) ? n : 0; };\nconst key = (p, e) => p + '|' + e;\nconst meta = (p, e) => PRICES[key(p, e)] || { p: null, u: '', k: 'flow', agg1: 'sum' };\nconst isStock = (p, e) => meta(p, e).k === 'stock';\n\nfunction addDays(iso, n) {\n  const d = new Date(iso + 'T12:00:00Z');\n  d.setUTCDate(d.getUTCDate() + n);\n  return d.toISOString().slice(0, 10);\n}\nconst yesterday = () => addDays(new Date(Date.now()).toISOString().slice(0, 10), -1);\nfunction daysInMonth(iso) { const [y, m] = iso.split('-').map(Number); return new Date(y, m, 0).getDate(); }\nfunction dowPt(iso) {\n  return ['dom', 'seg', 'ter', 'qua', 'qui', 'sex', 'sáb'][new Date(iso + 'T12:00:00Z').getUTCDay()];\n}\nconst shortDay = (iso) => iso.slice(8, 10) + '/' + iso.slice(5, 7);\n\n// custo estimado em US$ a partir do volume bruto (unidade da API)\nfunction costOf(p, e, raw, refIso, dias) {\n  const m = meta(p, e);\n  if (m.p === null || m.p === undefined || raw === null) return null;\n  const q = raw / (m.d || 1);\n  // ⚠️ Preço mensal (mo:true, hoje só DRIVE/storage) é cobrado POR MÊS. Dividir por daysInMonth dá a\n  // cota de UM dia — certo quando o período É um dia, mas num período de 7 dias subestimava 7× e num\n  // mês ~31×, justo na visão que deve bater com a fatura. O nº de dias vem do próprio período.\n  return m.mo ? (q * m.p) * ((dias || 1) / daysInMonth(refIso)) : q * m.p;\n}\nfunction labelOf(ref, dim) {\n  if (ref === null || ref === undefined || ref === '') return '(sem dimensão)';\n  const s = String(ref);\n  if (dim === 'request.path') return s;\n  return LABELS[s] || null;\n}\n\n// ---------- formatação ----------\nfunction fmtNum(n) {\n  if (n === null || n === undefined || !Number.isFinite(n)) return '—';\n  const a = Math.abs(n);\n  if (a >= 1e9) return (n / 1e9).toFixed(2) + ' bi';\n  if (a >= 1e6) return (n / 1e6).toFixed(2) + ' mi';\n  if (a >= 1e3) return (n / 1e3).toFixed(1) + ' mil';\n  if (a >= 1) return n.toFixed(0);\n  if (a === 0) return '0';\n  return n.toFixed(2);\n}\n// Bytes em unidade BINÁRIA: a fatura cobra GiB (1024³). E 'B' de bilhão colidiria com 'B' de byte.\nfunction fmtBytes(n) {\n  if (n === null || n === undefined || !Number.isFinite(n)) return '—';\n  const a = Math.abs(n);\n  const u = [[1073741824, 'GiB'], [1048576, 'MiB'], [1024, 'KiB']];\n  for (const [d, s] of u) if (a >= d) return (n / d).toFixed(2) + ' ' + s;\n  return n.toFixed(0) + ' B';\n}\nconst fmtVal = (n, unit) => (unit === 'B' ? fmtBytes(n) : fmtNum(n));\n// O consumo por sessão virou o número grande da tabela, e quase sempre é um valor pequeno — fmtNum foi\n// feito para volume e destrói a leitura nessa faixa: 1.13 e 1.60 viram '1' e '2' (parece +100%, são\n// +42%) e 0.0062 vira '0.01', empatando com 0.0137. Aí a pontilhada mostra o movimento certo enquanto\n// o número diz outra coisa. Aqui o que importa é dígito significativo, não escala.\nfunction fmtPerS(n, unit) {\n  if (n === null || n === undefined || !Number.isFinite(n)) return '—';\n  if (unit === 'B') return fmtBytes(n);\n  const a = Math.abs(n);\n  if (a === 0) return '0';\n  if (a >= 1000) return fmtNum(n);\n  if (a >= 100) return n.toFixed(0);\n  if (a >= 10) return n.toFixed(1);\n  if (a >= 1) return n.toFixed(2);\n  return n.toPrecision(2).replace(/(\\.\\d*?)0+$/, '$1').replace(/\\.$/, '');\n}\nfunction fmtUsd(n) {\n  if (n === null || n === undefined || !Number.isFinite(n)) return '—';\n  const a = Math.abs(n);\n  if (a >= 1000) return 'US$ ' + n.toLocaleString('pt-BR', { maximumFractionDigits: 0 });\n  if (a >= 1) return 'US$ ' + n.toFixed(2);\n  if (a === 0) return 'US$ 0';\n  return 'US$ ' + n.toFixed(4);\n}\nfunction fmtPct(x) {\n  if (x === null || x === undefined || !Number.isFinite(x)) return '—';\n  return (x >= 0 ? '+' : '') + (x * 100).toFixed(1) + '%';\n}\nfunction esc(s) {\n  return String(s == null ? '' : s).replace(/[&<>\"']/g, (c) =>\n    ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' }[c]));\n}\n\n// ---------- elasticidade ----------\n// E = Δ%recurso ÷ Δ%sessões, sempre contra o PRIMEIRO período selecionado.\n// Os guarda-corpos são o que impede a tabela de mentir quando o divisor é minúsculo.\n// ⚠️ A DIREÇÃO NUNCA VEM DE E. E = Δ%recurso ÷ Δ%sessões é uma divisão, e quando as sessões CAEM o\n// divisor é negativo — aí a faixa de E inverte de sentido. Um recurso que caiu 36% com o tráfego\n// caindo 12,5% dá E = 2,88 e era rotulado \"cresceu o dobro\", quando na verdade ficou 27% MAIS\n// eficiente por sessão. Por isso: |E| dá a MAGNITUDE, e o sinal de Δ(consumo/sessão) dá a DIREÇÃO.\nconst BANDS = [\n  { cls: 'critico',      lab: '↑ forte',    txt: 'consumo por sessão SUBIU e o recurso se moveu ≥ 2× o tráfego' },\n  { cls: 'atencao',      lab: '↑ moderada', txt: 'consumo por sessão SUBIU, em ordem próxima à do tráfego' },\n  { cls: 'esperado',     lab: '≈ estável',   txt: 'consumo por sessão praticamente não mudou (±5%)' },\n  { cls: 'subutilizado', lab: '↓ caiu',     txt: 'consumo por sessão CAIU — o recurso ficou mais eficiente' },\n  { cls: 'divergente',   lab: 'DIVERGENTE', txt: 'recurso e sessões foram em direções opostas' }\n];\n\n// Tendência de uma série ao longo dos períodos, ignorando buracos (null = período sem dado).\n//   rel           = variação total IMPLÍCITA PELA RETA ajustada, relativa ao primeiro ponto\n//   mesmos/passos = degraus que seguem a direção dominante (consistência da progressão)\n// ⚠️ Com 2 pontos a reta passa EXATAMENTE por ambos, então usa-se o valor cru: o resultado fica\n// bit-idêntico ao cálculo antigo (base vs último) e a visão de 2 janelas NÃO regride. Verificado\n// offline em 50.000 pares aleatórios: diferença absoluta 0,0 (sem esse caso o erro era ~1e-11).\nfunction trend(serie) {\n  const pts = [];\n  (serie || []).forEach((v, i) => {\n    if (v !== null && v !== undefined && Number.isFinite(v)) pts.push([i, v]);\n  });\n  if (pts.length < 2) return null;\n  const n = pts.length;\n  const mx = pts.reduce((a, p) => a + p[0], 0) / n;\n  const my = pts.reduce((a, p) => a + p[1], 0) / n;\n  let num = 0, den = 0, sst = 0;\n  for (const pt of pts) {\n    num += (pt[0] - mx) * (pt[1] - my); den += (pt[0] - mx) * (pt[0] - mx); sst += (pt[1] - my) * (pt[1] - my);\n  }\n  const slope = den ? num / den : 0;\n  let y0, y1;\n  if (n === 2) { y0 = pts[0][1]; y1 = pts[1][1]; }\n  else { y0 = my + slope * (pts[0][0] - mx); y1 = my + slope * (pts[n - 1][0] - mx); }\n  const rel = y0 ? (y1 - y0) / Math.abs(y0) : null;   // base zero -> null: cai no ramo NOVO/SUMIU\n  let ss = 0;\n  for (const pt of pts) { const f = my + slope * (pt[0] - mx); ss += (pt[1] - f) * (pt[1] - f); }\n  let passos = 0, mesmos = 0;\n  for (let i = 1; i < n; i++) {\n    const d = pts[i][1] - pts[i - 1][1];\n    if (d === 0) continue;\n    passos++;\n    if (slope !== 0 && (d > 0) === (slope > 0)) mesmos++;\n  }\n  return { rel: rel, r2: sst ? 1 - ss / sst : 1, passos: passos, mesmos: mesmos };\n}\n\n// Sufixo de consistência no rótulo. Só aparece com 3+ períodos — com 2 janelas passos <= 1, então\n// a visão de 2 semanas continua visualmente idêntica à validada.\nconst sufProg = (o) => (o.prog && o.prog.passos > 1) ? ' ' + o.prog.mesmos + '/' + o.prog.passos : '';\n\nfunction classify(vBase, vCur, sBase, sCur, serie) {\n  const out = { e: null, dRes: null, dSess: null, dPer: null, cls: 'estavel', tag: '', why: '' };\n  // ⚠️ Período sem dado NÃO é zero. Tratar como zero fazia toda linha virar NOVO/SUMIU e o impacto\n  // virar o custo integral com sinal negativo — pintado de verde, como se fosse economia.\n  if (vBase === null || vBase === undefined || vCur === null || vCur === undefined) {\n    out.cls = 'zero'; out.tag = 'sem dado';\n    out.why = 'um dos períodos não tem dado carregado — não dá para comparar';\n    return out;\n  }\n  if (sBase > 0) out.dSess = (sCur - sBase) / sBase;\n  if (vBase > 0) out.dRes = (vCur - vBase) / vBase;\n  const perB = sBase > 0 ? vBase / sBase : null;\n  const perC = sCur > 0 ? vCur / sCur : null;\n  if (perB) out.dPer = (perC - perB) / perB;\n\n  // PROGRESSÃO (semanal): a leitura passa a vir da reta ajustada sobre TODOS os períodos, não de\n  // base-vs-último. Duas séries que terminam no mesmo lugar podem ter caminhos opostos —\n  // [10,18,14,12] e [10,11,12,12] dão ambas +20% no fim, mas +4,5% e +20,6% na reta ajustada.\n  // ⚠️ A árvore de decisão abaixo NÃO muda: só a ORIGEM de dRes/dSess/dPer.\n  if (serie) {\n    const tr = trend(serie.res), ts = trend(serie.sess), tp = trend(serie.per);\n    if (tr && ts && tr.rel !== null && ts.rel !== null) {\n      out.dRes = tr.rel; out.dSess = ts.rel;\n      if (tp && tp.rel !== null) out.dPer = tp.rel;\n      out.prog = tp || tr;\n    }\n  }\n\n  if (vBase === 0 && vCur > 0) { out.cls = 'novo'; out.tag = 'NOVO'; out.why = 'não existia no período-base'; return out; }\n  if (vCur === 0 && vBase > 0) { out.cls = 'sumiu'; out.tag = 'SUMIU'; out.why = 'zerou em relação ao período-base'; return out; }\n  if (vBase === 0 && vCur === 0) { out.cls = 'zero'; out.tag = '—'; return out; }\n\n  if (out.dSess === null || Math.abs(out.dSess) < SESS_EPS) {\n    out.why = 'sessões praticamente paradas (' + fmtPct(out.dSess) + ') — a divisão explodiria, então a classificação vem do consumo por sessão';\n    if (out.dPer === null) { out.cls = 'estavel'; out.tag = '—'; return out; }\n    // ⚠️ MESMA armadilha do ramo de E: usar Math.abs aqui classificava uma QUEDA de 53% no consumo\n    // por sessão — que é ganho de eficiência — como crítico, em vermelho. A magnitude vem do módulo,\n    // a direção vem do SINAL.\n    const ap = Math.abs(out.dPer);\n    if (ap < 0.10) { out.cls = 'estavel'; out.tag = 'esperado'; return out; }\n    out.cls = out.dPer > 0 ? (ap >= 0.30 ? 'critico' : 'atencao') : 'subutilizado';\n    out.tag = fmtPct(out.dPer) + ' /sessão' + sufProg(out);\n    return out;\n  }\n  out.e = out.dRes / out.dSess;\n  if (out.e === 0) out.e = 0;   // normaliza -0, que toFixed imprimiria como \"-0.00\"\n  if (out.dRes * out.dSess < 0) {\n    out.cls = 'divergente'; out.tag = 'DIVERGENTE';\n    out.why = 'recurso ' + fmtPct(out.dRes) + ' vs sessões ' + fmtPct(out.dSess) + ' — direções opostas';\n    return out;\n  }\n  // magnitude por |E|, DIREÇÃO por Δ(consumo/sessão) — ver o comentário em BANDS\n  const a = Math.abs(out.e);\n  const p = (out.dPer === null || !Number.isFinite(out.dPer)) ? 0 : out.dPer;\n  if (Math.abs(p) < 0.05) out.cls = 'esperado';\n  else if (p > 0) out.cls = a >= 2 ? 'critico' : 'atencao';\n  else out.cls = 'subutilizado';\n  out.tag = 'E ' + out.e.toFixed(2) + (Math.abs(p) < 0.05 ? '' : (p > 0 ? ' ↑' : ' ↓')) + sufProg(out);\n  out.why = 'recurso ' + fmtPct(out.dRes) + ' ÷ sessões ' + fmtPct(out.dSess)\n    + ' — consumo por sessão ' + fmtPct(out.dPer)\n    + (out.dSess < 0 ? ' (sessões caindo: E alto aqui significa que o recurso caiu MAIS que o tráfego)' : '');\n  return out;\n}\n\n// ---------- períodos ----------\n// Um \"período\" é a unidade de comparação: 1 dia na visão diária, 7 dias na semanal.\n// Tudo abaixo (agregação, elasticidade, tabela, gráficos) opera sobre períodos, não sobre dias —\n// é o que faz as duas visões compartilharem o mesmo código.\nfunction dayPeriods(days) {\n  return days.map((d) => ({ k: d, lab: shortDay(d), sub: dowPt(d), d0: d, d1: d, days: [d] }));\n}\nfunction weekPeriods(endIso, n) {\n  const qtd = Math.max(WEEKS_MIN, Math.min(WEEKS_MAX, n || WEEKS_MAX));\n  const out = [];\n  for (let i = qtd - 1; i >= 0; i--) {\n    const d1 = addDays(endIso, -i * WEEK_LEN);\n    const d0 = addDays(d1, -(WEEK_LEN - 1));\n    const days = [];\n    for (let j = 0; j < WEEK_LEN; j++) days.push(addDays(d0, j));\n    out.push({ k: 'S' + d0, lab: shortDay(d0) + '–' + shortDay(d1), sub: '7 dias', d0, d1, days });\n  }\n  return out;\n}\n// Meses de CALENDÁRIO (01→fim): é o recorte em que a fatura cobra, e o preço do storage já é mensal.\n// O mês corrente entra PARCIAL (d1 = ontem) e marcado: o custo por sessão segue comparável, porque\n// numerador e denominador encolhem juntos, mas o custo TOTAL do mês fica menor só por faltar dia.\nconst MES_PT = ['jan', 'fev', 'mar', 'abr', 'mai', 'jun', 'jul', 'ago', 'set', 'out', 'nov', 'dez'];\nfunction monthStart(iso) { return iso.slice(0, 8) + '01'; }\nfunction addMonths(iso, n) {\n  const [y, m] = iso.split('-').map(Number);\n  const d = new Date(y, m - 1 + n, 1);\n  return d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-01';\n}\nfunction monthLab(iso) { const [y, m] = iso.split('-').map(Number); return MES_PT[m - 1] + '/' + String(y).slice(2); }\nfunction monthPeriods(endIso, n) {\n  const qtd = Math.max(MONTHS_MIN, Math.min(MONTHS_MAX, n || MONTHS_MAX));\n  const ont = yesterday();\n  const base = monthStart(endIso || ont);\n  const out = [];\n  for (let i = qtd - 1; i >= 0; i--) {\n    const d0 = addMonths(base, -i);\n    const nd = daysInMonth(d0);\n    const fim = d0.slice(0, 8) + String(nd).padStart(2, '0');\n    const parcial = fim > ont;\n    const d1 = parcial ? ont : fim;\n    const days = [];\n    for (let d = d0; d <= d1; d = addDays(d, 1)) days.push(d);\n    out.push({ k: 'M' + d0, lab: monthLab(d0) + (parcial ? '*' : ''),\n      sub: parcial ? days.length + ' de ' + nd + ' dias' : nd + ' dias',\n      d0, d1, days, parcial });\n  }\n  return out;\n}\n\n// ---------- camada de dados ----------\nfunction makeApi(d2) {\n  const ref = d2.param('listenerRef', 'sLSYzN3EtX3kpGdQzYwov');\n  // NÃO usar d2.rush().invoke(): ele anexa a sessão do visitante à chamada, e o listener de sessões\n  // do Natura recusa sessão sem permissão (401 → 424). fetch puro no MESMO endpoint funciona.\n  // ⚠️ `from`/`until` NÃO são legíveis em $body no handler (colidem com o contexto de\n  // requestParameters do HttpRequest) — por isso a janela viaja como d0/d1.\n  const url = d2.rush(ref).url();\n  // Segredo compartilhado exigido pela policy do listener: ela compara headers.authorization BYTE A\n  // BYTE com main_key do KeyVault yKBvZckVp5c-Lasp2D0gr — por isso vai o token PURO, sem \"Bearer\".\n  // ⚠ Isto é código de CLIENTE: o token viaja no bundle publicado e é legível por quem abrir a página.\n  // Ele fecha o endpoint para quem não passou pelo app; não para quem inspecionar o bundle.\n  const TOKEN = 'r0IJs-aabNKEL32RnJoG1LSEUE2Ofez2AZocyfQVMtvEwltwTl4KZqkBiRHhTkJ';\n  const call = async (payload, signal) => {\n    const r = await fetch(url, {\n      method: 'POST', credentials: 'omit',\n      headers: { 'Content-Type': 'application/json', Authorization: TOKEN },\n      body: JSON.stringify(payload), signal: signal\n    });\n    const txt = await r.text();\n    // A policy do PORTAL recusando é um caso distinto do 401 do listener de sessões do Natura, e a\n    // mensagem crua não diz qual dos dois falhou — nem distingue token errado de policy em edição.\n    if (r.status === 401 || r.status === 403 || /no permissions/i.test(txt)) {\n      throw new Error('o listener do portal recusou a chamada (HTTP ' + r.status + '). A policy dele compara '\n        + 'headers.authorization byte a byte com main_key do KeyVault yKBvZckVp5c-Lasp2D0gr. A MESMA resposta '\n        + 'aparece para token errado, header ausente E policy sendo alterada naquele instante — re-teste depois '\n        + 'de ~1 min antes de concluir que o segredo dessincronizou.');\n    }\n    let json;\n    try { json = JSON.parse(txt); }\n    catch (e) { throw new Error('resposta não-JSON (HTTP ' + r.status + '): ' + txt.slice(0, 140)); }\n    const out = json && json.data ? json.data : json;   // listener responde envelopado\n    if (!r.ok || !out || out.error) {\n      const cru = (out && out.error) || ('HTTP ' + r.status);\n      const txt2 = typeof cru === 'string' ? cru : JSON.stringify(cru);\n      // ⚠️ O listener de sessões do Natura NÃO valida sessão: a policy dele compara o header\n      // `authorization` BYTE A BYTE com `auth_key` do KeyVault 4kYx6aU00vaMSQnGP5mOp. Por isso a\n      // mensagem genérica \"Selected session has no permissions\" aparece igual para token ausente,\n      // errado ou dessincronizado — e a causa real é sempre segredo compartilhado fora de sincronia.\n      if (payload.op === 'sessions' && /401|424|no permissions/i.test(txt2)) {\n        throw new Error('Sessões recusadas (401). Quando a policy do listener do Natura está ativa, ela compara '\n          + 'o header Authorization byte a byte com auth_key do KeyVault 4kYx6aU00vaMSQnGP5mOp; o nosso valor sai '\n          + 'de natura-api-vault/sessions_token. A MESMA mensagem aparece para segredo diferente, policy sendo '\n          + 'alterada naquele instante, ou header ausente — ela não distingue as causas. Re-teste depois de alguns '\n          + 'minutos ANTES de concluir que o segredo dessincronizou. O consumo não é afetado: aquela API é pública.');\n      }\n      throw new Error(txt2);\n    }\n    return out;\n  };\n  return {\n    sessions: (d0, d1, sig) => call({ op: 'sessions', d0, d1 }, sig),\n    overview: (d0, d1, sig) => call({ op: 'overview', d0, d1 }, sig),\n    detailPage: (d0, d1, product, event, skip, sig) =>\n      call({ op: 'detail', d0, d1, product, event, page_size: PAGE, skip }, sig)\n  };\n}\n\n// `stop` é o que faz o cancelar realmente cancelar: sem ele os workers drenavam a fila inteira e as\n// chamadas restantes eram cobradas normalmente — cancelar não economizava um centavo.\nasync function pool(tasks, size, onTick, stop) {\n  const out = new Array(tasks.length);\n  let i = 0, done = 0;\n  await Promise.all(new Array(Math.min(size, tasks.length)).fill(0).map(async () => {\n    for (;;) {\n      if (stop && stop()) return;\n      const k = i++;\n      if (k >= tasks.length) return;\n      try { out[k] = await tasks[k](); }\n      catch (err) { out[k] = { __err: (err && err.message) || String(err) }; }\n      done++;\n      if (onTick) onTick(done, tasks.length);\n    }\n  }));\n  return out;\n}\n\n// nível 3 de um par num período, paginando até acabar OU até o teto — a truncagem é devolvida,\n// nunca escondida, porque é ela que decide se o total pode vir do detalhe.\nasync function fetchDetail(api, per, product, event, maxPages, sig) {\n  const rows = [];\n  let dim = null, truncated = false, pages = 0;\n  for (;;) {\n    const out = await api.detailPage(per.d0, per.d1, product, event, pages * PAGE, sig);\n    const list = out.rows || [];\n    if (list.length && !dim) dim = Object.keys(list[0]).find((k) => !BASE_KEYS.has(k)) || null;\n    for (const r of list) rows.push({ r: dim ? r[dim] : null, v: num(r.sum_measure_value), date: r.date });\n    pages++;\n    if (list.length < PAGE) break;\n    if (pages >= (maxPages || MAX_PAGES)) { truncated = true; break; }\n  }\n  // ⚠️ A API pagina ao longo do EIXO DATA, ordenada por data: UMA página de 500 linhas de TABLE/read\n  // cobre ~2,2 dias de uma semana (medido: 238 de 10/08 + 224 de 11/08 + 38 de 12/08). Somar isso e\n  // exibir como \"a semana\" mostra ~60% do valor como se fosse o total. Quando truncou, o último dia\n  // veio pela metade: descarta-se esse dia e declara-se quais dias a lista realmente cobre.\n  let cover = null;\n  if (truncated) {\n    const ds = [];\n    for (const x of rows) if (x.date && ds.indexOf(x.date) < 0) ds.push(x.date);\n    ds.sort();\n    // o último dia veio pela metade -> fora. Em período de 1 dia isso zera a cobertura, e é a verdade:\n    // não há nenhum dia íntegro na lista.\n    cover = ds.slice(0, -1);\n  }\n  return { dim: dim || meta(product, event).dim || null, rows, truncated, pages, cover };\n}\n\n// ---------- agregação ----------\n// ⚠️ Regra que separa certo de errado: FLUXO soma entre os dias do período; ESTOQUE (`storage`)\n// tira a MÉDIA — somar estoque de 7 dias daria 7× o valor real.\nfunction aggLevel1(rows) {\n  const acc = {};\n  for (const r of rows || []) {\n    const k = key(r.product, r.measure_name);\n    if (!acc[k]) acc[k] = { sum: 0, n: 0 };\n    acc[k].sum += num(r.sum_measure_value); acc[k].n++;\n  }\n  const out = {};\n  for (const k in acc) {\n    const i = k.indexOf('|');\n    out[k] = isStock(k.slice(0, i), k.slice(i + 1)) ? acc[k].sum / acc[k].n : acc[k].sum;\n  }\n  return out;\n}\n\nfunction aggDetail(det, p, e) {\n  if (!det || det.__err || det.__loading) return null;\n  const cov = det.cover ? new Set(det.cover) : null;   // só os dias integralmente cobertos\n  const acc = new Map();\n  for (const x of det.rows) {\n    if (cov && x.date && !cov.has(x.date)) continue;\n    const k = (x.r === null || x.r === undefined) ? '' : String(x.r);\n    if (!acc.has(k)) acc.set(k, { sum: 0, n: 0 });\n    const a = acc.get(k); a.sum += x.v; a.n++;\n  }\n  const stock = isStock(p, e);\n  const out = new Map();\n  for (const [k, a] of acc) out.set(k, stock ? a.sum / a.n : a.sum);\n  return out;\n}\n\n// O nível 1 é a fonte padrão. O detalhe só substitui quando está COMPLETO — um detalhe truncado\n// vira um total menor que o real, e o erro é invisível. Foi o bug da fase 1.\nfunction valueOf(store, per, p, e) {\n  const a = store.agg[per.k] || {};\n  const lvl1 = (a[key(p, e)] === undefined) ? null : a[key(p, e)];\n  const m = meta(p, e);\n  const det = store.det[per.k + '|' + p + '|' + e];\n  if (det && !det.__err && !det.__loading) {\n    if (det.truncated) {\n      return { v: lvl1, src: 'nivel1', lvl1, mean: m.agg1 === 'avg', truncated: true,\n               diverges: false, noClose: m.agg1 === 'avg' };\n    }\n    const map = aggDetail(det, p, e);\n    let s = 0; map.forEach((x) => { s += x; });\n    return { v: s, src: 'detalhe', lvl1, mean: false, truncated: false, noClose: false,\n             diverges: lvl1 !== null && Math.abs(s - lvl1) > Math.max(1, Math.abs(lvl1) * 1e-6) };\n  }\n  return { v: lvl1, src: 'nivel1', lvl1, mean: m.agg1 === 'avg', truncated: false, diverges: false, noClose: false };\n}\n\nfunction buildRows(store, periods, prog) {\n  const pairs = new Map();\n  for (const per of periods) for (const k in (store.agg[per.k] || {})) {\n    const i = k.indexOf('|');\n    pairs.set(k, { p: k.slice(0, i), e: k.slice(i + 1) });\n  }\n  const base = periods[0];\n  const sBase = store.sess[base.k] || 0;\n  const out = [];\n  pairs.forEach(({ p, e }) => {\n    const m = meta(p, e);\n    const cells = periods.map((per) => {\n      const vo = valueOf(store, per, p, e);\n      const s = store.sess[per.k];\n      const c = vo.v === null ? null : costOf(p, e, vo.v, per.d1, per.days.length);\n      return Object.assign({}, vo, {\n        per, c,\n        perS: (vo.v !== null && s) ? vo.v / s : null,\n        cps: (c !== null && s) ? c / s : null\n      });\n    });\n    // ⚠️ Para métricas cujo nível 1 é MÉDIA por recurso (storage/login), o detalhe completo é a SOMA —\n    // grandezas que diferem por um fator igual ao nº de recursos. Se QUALQUER período ficou sem detalhe,\n    // a linha inteira volta ao nível 1; misturar as duas bases célula a célula produz uma linha em que\n    // 3,3 GiB e 107 GiB convivem como se fossem comparáveis.\n    if (m.agg1 === 'avg' && cells.some((c) => c.src !== 'detalhe')) {\n      cells.forEach((c) => {\n        if (c.src === 'detalhe') {\n          c.v = c.lvl1; c.src = 'nivel1'; c.mean = true; c.diverges = false;\n          c.c = c.v === null ? null : costOf(p, e, c.v, c.per.d1, c.per.days.length);\n          const s = store.sess[c.per.k];\n          c.perS = (c.v !== null && s) ? c.v / s : null;\n          c.cps = (c.c !== null && s) ? c.c / s : null;\n        }\n      });\n    }\n    const b = cells[0];\n    const cls = cells.map((c, i) => (i === 0 ? null : classify(b.v, c.v, sBase, store.sess[c.per.k] || 0)));\n    let worst = null;\n    for (const c of cls) {\n      if (!c) continue;\n      if (!worst) { worst = c; continue; }\n      const rk = (x) => ({ critico: 4, divergente: 4, novo: 3, sumiu: 3, atencao: 2, subutilizado: 1, esperado: 0, estavel: 0, zero: -1 }[x.cls] || 0);\n      if (rk(c) > rk(worst) || (rk(c) === rk(worst) && Math.abs(c.e || 0) > Math.abs(worst.e || 0))) worst = c;\n    }\n    // No semanal a verdade da linha é a PROGRESSÃO inteira, não o pior período isolado: com 4\n    // janelas o \"pior\" pode ser um pico que já voltou ao lugar. Com 2 janelas isto devolve\n    // exatamente o mesmo que o laço acima — a reta por 2 pontos É a reta base->último.\n    if (prog && cells.length > 1) {\n      const last = cells[cells.length - 1];\n      const pr = classify(b.v, last.v, sBase, store.sess[last.per.k] || 0, {\n        res: cells.map((c) => c.v),\n        sess: cells.map((c) => (store.sess[c.per.k] === undefined ? null : store.sess[c.per.k])),\n        per: cells.map((c) => c.perS)\n      });\n      if (pr.cls !== 'zero') worst = pr;\n    }\n    let impact = 0;\n    for (let i = 1; i < cells.length; i++) {\n      if (cells[i].c === null || b.c === null) continue;   // sem dado != queda a zero\n      const d = cells[i].c - b.c;\n      if (Math.abs(d) > Math.abs(impact)) impact = d;\n    }\n    const maxCost = cells.reduce((a, c) => Math.max(a, c.c || 0), 0);\n    // ⚠️ A tendência plota EXATAMENTE os valores impressos nas células — mesma grandeza, mesma\n    // granularidade, mesma regra de agregação. Plotar valor÷sessões (ou a série diária sob células\n    // semanais) faz o desenho responder a outra pergunta que não a dos números ao lado.\n    out.push({ p, e, m, cells, cls, worst, impact, baseCost: b.c || 0, maxCost,\n               spark: cells.map((c) => c.v),\n               // o volume que o TRÁFEGO sozinho explicaria, ancorado no período-base\n               refSpark: cells.map((c) => {\n                 const s = store.sess[c.per.k];\n                 return (cells[0].v !== null && sBase && s) ? cells[0].v * (s / sBase) : null;\n               }) });\n  });\n  // Pareto: quem forma os primeiros 80% do custo fica marcado TOP CUSTO em QUALQUER ordenação.\n  const tot = out.reduce((a, r) => a + r.maxCost, 0);\n  let cum = 0;\n  out.slice().sort((a, b) => b.maxCost - a.maxCost).forEach((r) => {\n    r.share = tot ? r.maxCost / tot : 0;\n    r.top = cum < PARETO * tot && r.maxCost > 0;\n    cum += r.maxCost;\n  });\n  return out;\n}\n\nfunction sortRows(rows, mode, minCost) {\n  const r = rows.slice();\n  if (mode === 'elasticidade') {\n    const rk = (x) => ({ critico: 4, divergente: 4, novo: 3, sumiu: 3, atencao: 2, subutilizado: 1, esperado: 0, estavel: 0, zero: -1 }[x] || 0);\n    return r.filter((x) => Math.max(Math.abs(x.impact), x.maxCost) >= minCost)\n      .sort((a, b) => {\n        const ra = rk(a.worst && a.worst.cls), rb = rk(b.worst && b.worst.cls);\n        if (ra !== rb) return rb - ra;\n        return Math.abs((b.worst && b.worst.e) || 0) - Math.abs((a.worst && a.worst.e) || 0);\n      });\n  }\n  return r.sort((a, b) => (b.maxCost + Math.abs(b.impact)) - (a.maxCost + Math.abs(a.impact)));\n}\n\nfunction periodTotals(store, periods) {\n  return periods.map((per) => {\n    const a = store.agg[per.k];\n    // ⚠️ PESSOAS entra em `total`, NUNCA em `cost`: `cps` deriva de `cost`, e o custo por sessão tem\n    // de continuar sendo só de infraestrutura — é a métrica-âncora já validada. Somar aqui a\n    // contaminaria de um custo fixo que não tem relação nenhuma com o volume de sessões.\n    const nAloc = store.alloc ? store.alloc(per) : 0;\n    const aloc = nAloc * (store.allocUsd || 0);\n    if (!a || !Object.keys(a).length) {\n      const s0 = store.sess[per.k];\n      return { per, cost: null, sessions: (s0 === undefined ? null : s0), cps: null, semDados: true,\n        nAloc, aloc, total: aloc };\n    }\n    let cost = 0, unpriced = 0;\n    for (const k in (store.agg[per.k] || {})) {\n      const i = k.indexOf('|'); const p = k.slice(0, i), e = k.slice(i + 1);\n      const vo = valueOf(store, per, p, e);\n      if (vo.v === null) continue;\n      const c = costOf(p, e, vo.v, per.d1, per.days.length);\n      if (c === null) { unpriced++; continue; }\n      cost += c;\n    }\n    const s = store.sess[per.k];\n    return { per, cost, sessions: (s === undefined ? null : s), cps: s ? cost / s : null, unpriced,\n      nAloc, aloc, total: cost + aloc };\n  });\n}\n\nfunction costByProduct(store, per) {\n  const acc = {};\n  for (const k in (store.agg[per.k] || {})) {\n    const i = k.indexOf('|'); const p = k.slice(0, i), e = k.slice(i + 1);\n    const vo = valueOf(store, per, p, e);\n    if (vo.v === null) continue;\n    const c = costOf(p, e, vo.v, per.d1, per.days.length);\n    if (c === null) continue;\n    acc[p] = (acc[p] || 0) + c;\n  }\n  // O laço acima é dirigido pelas chaves de store.agg, então um custo que NÃO vem da API só pode\n  // entrar aqui, depois. Sem isto o empilhado deixaria de somar o mesmo que o KPI ao lado.\n  const aloc = (store.alloc ? store.alloc(per) : 0) * (store.allocUsd || 0);\n  if (aloc > 0) acc.PESSOAS = aloc;\n  return acc;\n}\n\n// eager: os pares que mais pesam no custo do período-base, + o evento-irmão de contagem quando um\n// *_duration entra, + DRIVE/storage (cujo nível 1 é média — sem detalhe o total do período erra).\nfunction pickEager(store, base, topN) {\n  const a = store.agg[base.k] || {};\n  const scored = Object.keys(a).map((k) => {\n    const i = k.indexOf('|'); const p = k.slice(0, i), e = k.slice(i + 1);\n    return { p, e, c: costOf(p, e, a[k], base.d1, base.days.length) || 0 };\n  }).sort((x, y) => y.c - x.c);\n  const seen = new Set(), chosen = [];\n  const add = (p, e) => { const k = key(p, e); if (!seen.has(k) && a[k] !== undefined) { seen.add(k); chosen.push({ p, e }); } };\n  for (const s of scored.slice(0, (topN === undefined || topN === null) ? TOP_N : topN)) {\n    add(s.p, s.e);\n    if (s.e.endsWith('_duration')) add(s.p, s.e.replace(/_duration$/, ''));\n  }\n  add('DRIVE', 'storage');\n  return chosen;\n}\n\nconst CSS = `\n:host { display:block; width:100%; height:100%; }\n*, *::before, *::after { box-sizing:border-box; }\n.wrap {\n  --bg:#0b1020; --panel:#121a30; --panel2:#0f1729; --line:#233150; --txt:#e6ecff; --dim:#93a3c8;\n  --accent:#5b9bff; --ok:#22c55e; --warn:#f59e0b; --bad:#ef4444; --mut:#64748b;\n  background:var(--bg); color:var(--txt); height:100%; width:100%; overflow-y:auto; overflow-x:hidden;\n  font-family:'Inter',system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;\n  font-size:13px; line-height:1.45; padding:20px 22px 80px;\n}\n.wrap.light { --bg:#f6f8fc; --panel:#ffffff; --panel2:#eef2f9; --line:#dbe3f0; --txt:#0f172a;\n  --dim:#5b6b8c; --accent:#2563eb; --mut:#94a3b8; }\nh1,h2,h3 { margin:0; font-weight:650; letter-spacing:-.01em; }\nh1 { font-size:19px; } h2 { font-size:14px; margin-bottom:10px; } h3 { font-size:12px; }\n.sub { color:var(--dim); font-size:12px; }\n.row { display:flex; gap:10px; align-items:center; flex-wrap:wrap; }\n.between { display:flex; justify-content:space-between; align-items:flex-start; gap:16px; flex-wrap:wrap; }\n.card { background:var(--panel); border:1px solid var(--line); border-radius:12px; padding:14px 16px; }\n.mt { margin-top:16px; } .mt8 { margin-top:8px; }\n.secthead { display:flex; align-items:baseline; gap:10px; margin:30px 0 12px; }\n.secthead .n { width:24px; height:24px; border-radius:7px; background:var(--accent); color:#fff;\n  display:grid; place-items:center; font-size:12px; font-weight:700; flex:none; }\nbutton { font:inherit; color:inherit; cursor:pointer; border-radius:8px; border:1px solid var(--line);\n  background:var(--panel2); padding:6px 11px; transition:.12s; }\nbutton:hover { border-color:var(--accent); }\nbutton.pri { background:var(--accent); border-color:var(--accent); color:#fff; font-weight:600; }\nbutton.pri:disabled { opacity:.45; cursor:not-allowed; }\nbutton.on { background:var(--accent); border-color:var(--accent); color:#fff; }\nbutton.ghost { background:transparent; }\ninput[type=date], input[type=number] { font:inherit; color:inherit; background:var(--panel2);\n  border:1px solid var(--line); border-radius:8px; padding:5px 8px; }\n.chip { display:inline-flex; align-items:center; gap:7px; background:var(--panel2);\n  border:1px solid var(--line); border-radius:999px; padding:4px 6px 4px 11px; }\n.chip.base { border-color:var(--accent); }\n.chip .x { border:0; background:transparent; color:var(--dim); padding:0 5px; line-height:1; font-size:15px; }\n.tag { display:inline-block; font-size:10.5px; font-weight:700; letter-spacing:.03em;\n  padding:2px 6px; border-radius:5px; white-space:nowrap; }\n.t-critico,.t-divergente { background:rgba(239,68,68,.16); color:#fca5a5; }\n.t-atencao { background:rgba(245,158,11,.16); color:#fcd34d; }\n.t-esperado,.t-estavel { background:rgba(100,116,139,.16); color:var(--dim); }\n.t-subutilizado { background:rgba(56,189,248,.14); color:#7dd3fc; }\n.t-novo { background:rgba(34,197,94,.16); color:#86efac; }\n.t-sumiu { background:rgba(148,163,184,.18); color:#cbd5e1; }\n.t-zero { background:transparent; color:var(--mut); }\n.t-top { background:rgba(91,155,255,.16); color:#93c5fd; }\n.light .t-critico,.light .t-divergente { color:#b91c1c; } .light .t-atencao { color:#a16207; }\n.light .t-novo { color:#15803d; } .light .t-subutilizado { color:#0369a1; } .light .t-top { color:#1d4ed8; }\n.hero { display:grid; grid-template-columns:minmax(340px,1.6fr) minmax(240px,1fr); gap:14px; }\n.heroK { display:flex; flex-direction:column; gap:10px; }\n.kpi { background:var(--panel); border:1px solid var(--line); border-radius:12px; padding:11px 14px; }\n.kpi.isbase { border-color:var(--accent); }\n.kpi .lab { color:var(--dim); font-size:10.5px; text-transform:uppercase; letter-spacing:.05em; }\n.kpi .big { font-size:21px; font-weight:680; margin-top:2px; letter-spacing:-.02em; }\n.kpi .foot { font-size:11.5px; color:var(--dim); margin-top:2px; }\n.scroll { overflow-x:auto; }\ntable { border-collapse:collapse; width:100%; font-variant-numeric:tabular-nums; }\nth, td { text-align:right; padding:6px 9px; border-bottom:1px solid var(--line); white-space:nowrap; }\nth { color:var(--dim); font-size:10.5px; font-weight:600; text-transform:uppercase; letter-spacing:.04em;\n  position:sticky; top:0; background:var(--panel); z-index:2; }\nth.l, td.l { text-align:left; }\ntbody tr:hover { background:var(--panel2); }\ntr.grp { cursor:pointer; }\ntr.grp.istop td { background:linear-gradient(90deg, rgba(91,155,255,.07), transparent 40%); }\ntr.det td { background:var(--panel2); font-size:11.5px; color:var(--dim); }\ntr.det td.l { padding-left:26px; }\n.nm { display:flex; align-items:center; gap:8px; min-width:250px; }\n.nm .bar { width:52px; height:22px; background:var(--panel2); border-radius:4px; overflow:hidden; flex:none; position:relative; }\n.nm .bar i { position:absolute; left:0; top:0; bottom:0; opacity:.85; }\n.nm .bar b { position:absolute; inset:0; display:grid; place-items:center; font-size:9.5px; font-weight:600; color:var(--txt); }\n.ev { font-weight:600; }\n.stack { display:flex; flex-direction:column; align-items:flex-end; line-height:1.25; }\n.stack .v { font-weight:600; }\n.stack .s { font-size:10.5px; color:var(--dim); }\n.stack .un { font-size:9px; color:var(--dim); font-weight:400; margin-left:1px; }\n.mono { font-family:ui-monospace,'SF Mono',Menlo,monospace; font-size:11px; color:var(--mut); }\n.warnI { color:var(--warn); cursor:help; }\n.bad { color:var(--bad); } .good { color:var(--ok); }\n.note { background:rgba(245,158,11,.09); border:1px solid rgba(245,158,11,.3); color:var(--warn);\n  border-radius:8px; padding:9px 12px; font-size:11.5px; }\n.err { background:rgba(239,68,68,.1); border:1px solid rgba(239,68,68,.35); color:#fca5a5;\n  border-radius:8px; padding:9px 12px; font-size:12px; }\n.bar2 { height:6px; border-radius:3px; background:var(--panel2); overflow:hidden; }\n.bar2 i { display:block; height:100%; background:var(--accent); transition:width .2s; }\n.charts { display:grid; grid-template-columns:repeat(auto-fit,minmax(330px,1fr)); gap:14px; }\nsvg { display:block; width:100%; height:auto; overflow:visible; }\n.lg { display:flex; gap:12px; flex-wrap:wrap; font-size:11px; color:var(--dim); margin-top:8px; }\n.lg span { display:inline-flex; align-items:center; gap:5px; }\n.pdot { display:inline-block; width:8px; height:8px; border-radius:2px; flex:none; }\n.empty { color:var(--dim); padding:26px 0; text-align:center; font-size:12.5px; }\n.foot { color:var(--mut); font-size:11px; margin-top:8px; line-height:1.6; }\n.spin { display:inline-block; width:11px; height:11px; border:2px solid var(--line);\n  border-top-color:var(--accent); border-radius:50%; animation:sp .7s linear infinite; }\n@keyframes sp { to { transform:rotate(360deg); } }\n.explain { display:grid; grid-template-columns:minmax(230px,1fr) minmax(260px,1.3fr) minmax(200px,1fr); gap:18px; }\n.explain code { background:var(--panel2); padding:1px 5px; border-radius:4px; font-size:11px; }\n.explain ul { margin:6px 0 0; padding-left:16px; }\n.explain li { margin:3px 0; font-size:11.5px; color:var(--dim); }\n.bandrow { display:flex; align-items:center; gap:8px; margin:4px 0; font-size:11.5px; color:var(--dim); }\n.bandrow .tag { min-width:96px; text-align:center; }\n.formula { font-size:15px; font-weight:600; text-align:center; padding:12px 0 6px; letter-spacing:-.01em; }\n.formula em { font-style:normal; color:var(--accent); }\n.printhead { display:none; }\n.onlyprint { display:none; }\n.alocrow { margin-top:10px; flex-wrap:wrap; align-items:flex-end; }\n.alocbox { display:inline-flex; flex-direction:column; align-items:center; gap:3px; padding:5px 9px;\n  background:var(--panel2); border:1px solid var(--line); border-radius:10px; }\n.alocmes { font-size:10px; text-transform:uppercase; letter-spacing:.04em; color:var(--dim); }\n.alocctl { display:flex; align-items:center; gap:5px; }\n.alocctl button { width:24px; height:24px; padding:0; font-size:15px; line-height:1; }\n.alocnum { width:54px; text-align:center; font-size:23px; font-weight:700; padding:1px 3px;\n  background:transparent; border:0; color:var(--txt); -moz-appearance:textfield; }\n.alocnum::-webkit-outer-spin-button, .alocnum::-webkit-inner-spin-button { -webkit-appearance:none; margin:0; }\n.alocusd { font-size:10px; color:var(--dim); }\n\n/* ---------- impressão / PDF ----------\n   window.print() com folha própria em vez de rasterizar com html2canvas: o texto sai selecionável,\n   os SVG saem vetoriais e não entra dependência de CDN. Três coisas precisam ser desfeitas aqui:\n   a altura fixa com scroll interno (senão só a primeira tela imprime), o tema escuro (queima tinta)\n   e os controles interativos (inúteis no papel — o cabeçalho de impressão diz o escopo em texto). */\n@media print {\n  .onlyprint { display:inline !important; color:#64748b; }\n  .wrap, .wrap.light {\n    height:auto !important; overflow:visible !important; padding:0 !important; font-size:9.5px;\n    --bg:#fff; --panel:#fff; --panel2:#f4f6fa; --line:#c9d3e4;\n    --txt:#0f172a; --dim:#475569; --mut:#7c8aa5; --accent:#1d4ed8;\n  }\n  .noprint, .noprint * { display:none !important; }\n  .printhead { display:block !important; margin-bottom:12px; }\n  .printhead h1 { font-size:15px; }\n  .printhead .l { font-size:10px; color:var(--dim); margin-top:3px; }\n  .card { break-inside:avoid; page-break-inside:avoid; box-shadow:none; }\n  /* a tabela é mais alta que uma folha: exigir que ela não quebre faria o Chrome empurrá-la inteira\n     para a página seguinte e deixar meia folha em branco. Ela DEVE fluir entre páginas — o cabeçalho\n     se repete (table-header-group) e as linhas seguem indivisíveis. */\n  .cardTabela { break-inside:auto; page-break-inside:auto; }\n  .hero, .charts { break-inside:avoid; }\n  tr, .kpi, .bandrow { break-inside:avoid; page-break-inside:avoid; }\n  thead { display:table-header-group; }\n  .scroll { overflow:visible !important; }\n  table { font-size:8.5px; }\n  th, td { padding:3px 5px; }\n  .secthead { break-after:avoid; }\n  /* as cores dos chips foram escolhidas para fundo escuro; no papel virariam pastel ilegível */\n  .t-critico, .t-divergente { color:#b91c1c; }\n  .t-atencao { color:#a16207; }\n  .t-novo { color:#15803d; }\n  .t-subutilizado { color:#0369a1; }\n  .t-top { color:#1d4ed8; }\n  .t-esperado, .t-estavel, .t-sumiu { color:#475569; }\n  .good { color:#15803d; }\n  .bad { color:#b91c1c; }\n  .warnI { color:#a16207; }\n  /* ⚠️ LARGURA — no A4 paisagem a área útil é ~1062px e a tabela pede 1466px na tela. Como a\n     impressão não rola, o excedente sairia CORTADO: some a coluna de impacto US$. Estas regras\n     comprimem nome, id, sparkline e a mini-barra de elasticidade; os NÚMEROS ficam intactos e\n     seguem sem quebrar linha. */\n  td.l, th.l { white-space:normal; }\n  .nm { min-width:0; gap:5px; }\n  .nm .bar { width:32px; height:15px; }\n  .nm .bar b { font-size:7px; }\n  td:nth-child(3) svg { max-width:76px; }\n  .stack svg { max-width:60px; }\n  .mono { font-size:7px; }\n  td.l .tag { font-size:6.5px; padding:1px 3px; }\n  .stack .s { font-size:7px; }\n}\n`;\n\n// ---------- gráficos (SVG à mão) ----------\n// HERO: a leitura principal da tela. Barras = sessões (volume de tráfego), linha = US$ por sessão\n// (eficiência). Quando a linha sobe enquanto a barra desce, o custo descolou do tráfego.\nfunction chartHero(tot) {\n  const W = 560, H = 230, PL = 56, PR = 60, PT = 26, PB = 34;\n  const withS = tot.filter((t) => t.sessions !== null);\n  if (!withS.length) return '<div class=\"empty\">carregue os períodos</div>';\n  const maxS = Math.max(1, ...tot.map((t) => t.sessions || 0));\n  const cpsV = tot.map((t) => t.cps).filter((x) => x !== null && Number.isFinite(x));\n  const maxC = Math.max(1e-9, ...cpsV), minC = Math.min(...cpsV, 0);\n  const padC = Math.max((maxC - minC) * 0.25, maxC * 0.15);\n  const cHi = maxC + padC, cLo = Math.max(0, minC - padC);\n  const step = (W - PL - PR) / Math.max(1, tot.length);\n  const cx = (i) => PL + step * i + step / 2;\n  const yS = (v) => H - PB - (v / maxS) * (H - PT - PB);\n  const yC = (v) => H - PB - ((v - cLo) / (cHi - cLo || 1)) * (H - PT - PB);\n  const bw = Math.min(74, step * 0.52);\n\n  const grid = [0, .5, 1].map((f) => {\n    const y = H - PB - f * (H - PT - PB);\n    return `<line x1=\"${PL}\" x2=\"${W - PR}\" y1=\"${y.toFixed(1)}\" y2=\"${y.toFixed(1)}\" stroke=\"currentColor\" stroke-opacity=\".1\"/>` +\n      `<text x=\"${PL - 7}\" y=\"${(y + 3.5).toFixed(1)}\" text-anchor=\"end\" font-size=\"9.5\" fill=\"#38bdf8\" opacity=\".8\">${fmtNum(maxS * f)}</text>` +\n      `<text x=\"${W - PR + 7}\" y=\"${(y + 3.5).toFixed(1)}\" font-size=\"9.5\" fill=\"#f472b6\" opacity=\".85\">${(cLo + (cHi - cLo) * f).toFixed(2)}</text>`;\n  }).join('');\n\n  const bars = tot.map((t, i) => {\n    if (t.sessions === null) return '';\n    const y = yS(t.sessions);\n    return `<rect x=\"${(cx(i) - bw / 2).toFixed(1)}\" y=\"${y.toFixed(1)}\" width=\"${bw.toFixed(1)}\" height=\"${(H - PB - y).toFixed(1)}\" rx=\"3\" fill=\"#38bdf8\" opacity=\".28\"/>` +\n      `<text x=\"${cx(i).toFixed(1)}\" y=\"${(y - 6).toFixed(1)}\" text-anchor=\"middle\" font-size=\"10.5\" fill=\"#38bdf8\" font-weight=\"600\">${t.sessions.toLocaleString('pt-BR')}</text>`;\n  }).join('');\n\n  const pts = tot.map((t, i) => (t.cps === null ? null : [cx(i), yC(t.cps)])).filter(Boolean);\n  const line = pts.length > 1\n    ? `<path d=\"${pts.map((p, i) => (i ? 'L' : 'M') + p[0].toFixed(1) + ' ' + p[1].toFixed(1)).join(' ')}\" fill=\"none\" stroke=\"#f472b6\" stroke-width=\"2.5\" stroke-linejoin=\"round\"/>` : '';\n  const dots = tot.map((t, i) => t.cps === null ? '' :\n    `<circle cx=\"${cx(i).toFixed(1)}\" cy=\"${yC(t.cps).toFixed(1)}\" r=\"4\" fill=\"#f472b6\" stroke=\"var(--panel)\" stroke-width=\"2\"/>` +\n    `<text x=\"${cx(i).toFixed(1)}\" y=\"${(yC(t.cps) - 11).toFixed(1)}\" text-anchor=\"middle\" font-size=\"10.5\" fill=\"#f472b6\" font-weight=\"700\">US$ ${t.cps.toFixed(4)}</text>`).join('');\n  const labs = tot.map((t, i) =>\n    `<text x=\"${cx(i).toFixed(1)}\" y=\"${H - 16}\" text-anchor=\"middle\" font-size=\"10.5\" fill=\"currentColor\" opacity=\".8\">${esc(t.per.lab)}</text>` +\n    `<text x=\"${cx(i).toFixed(1)}\" y=\"${H - 4}\" text-anchor=\"middle\" font-size=\"9\" fill=\"currentColor\" opacity=\".45\">${esc(t.per.sub)}</text>`).join('');\n\n  return `<svg viewBox=\"0 0 ${W} ${H}\" role=\"img\" aria-label=\"sessões e custo por sessão\">${grid}${bars}${line}${dots}${labs}</svg>\n    <div class=\"lg\"><span><i class=\"pdot\" style=\"background:#38bdf8\"></i>sessões (eixo esq.)</span>\n    <span><i class=\"pdot\" style=\"background:#f472b6\"></i>US$ por sessão (eixo dir.)</span></div>`;\n}\n\n// Sparkline da coluna \"tendência\". Duas regras inegociáveis, porque foi a violação delas que fez o\n// desenho contradizer os números:\n//  1. plota EXATAMENTE o array impresso nas células da mesma linha — mesma grandeza, mesma agregação;\n//  2. eixo de 0 ao máximo da série, então a altura É o valor e a amplitude desenhada É a variação real.\n//     (Normalizar pelo min–max fazia uma oscilação de 4% ocupar a caixa inteira, igual a um +900%.)\nfunction sparkline(vals, color, opts) {\n  const o = opts || {};\n  const W = o.w || 108, H = 22, P = 2;\n  const ok = vals.map((v) => (v === null || v === undefined || !Number.isFinite(v) ? null : v));\n  const real = ok.filter((v) => v !== null);\n  if (real.length < 2) return `<svg viewBox=\"0 0 ${W} ${H}\"></svg>`;\n  // série de referência: o volume que o TRÁFEGO sozinho explicaria (sessões reescaladas para partir do\n  // mesmo ponto). A distância entre a linha cheia e a pontilhada É o consumo por sessão: acima do\n  // pontilhado subiu por sessão, abaixo caiu. Antes era uma reta no valor inicial, que não dizia nada.\n  const refS = (o.ref || []).map((v) => (v === null || v === undefined || !Number.isFinite(v) ? null : v));\n  const refReal = refS.filter((v) => v !== null);\n  const hi = Math.max.apply(null, real.concat(refReal));\n  if (!(hi > 0)) return `<svg viewBox=\"0 0 ${W} ${H}\"></svg>`;   // série toda zero: nada a desenhar\n  const n = ok.length;\n  const x = (i) => P + (n === 1 ? 0 : i * (W - 2 * P) / (n - 1));\n  const y = (v) => H - P - (v / hi) * (H - 2 * P);\n\n  // segmentos: um buraco NÃO vira reta atravessando o vão (isso inventava uma tendência que não existe)\n  const segs = []; let cur = [];\n  ok.forEach((v, i) => {\n    if (v === null) { if (cur.length) segs.push(cur); cur = []; return; }\n    cur.push([x(i), y(v)]);\n  });\n  if (cur.length) segs.push(cur);\n  const dOf = (s) => s.map((p, i) => (i ? 'L' : 'M') + p[0].toFixed(1) + ' ' + p[1].toFixed(1)).join(' ');\n  const linhas = segs.filter((s) => s.length > 1);\n  const area = linhas.map((s) => `<path d=\"${dOf(s)}L ${s[s.length - 1][0].toFixed(1)} ${H - P} L ${s[0][0].toFixed(1)} ${H - P} Z\" fill=\"${color}\" opacity=\".14\"/>`).join('');\n  const traco = linhas.map((s) => `<path d=\"${dOf(s)}\" fill=\"none\" stroke=\"${color}\" stroke-width=\"1.6\"/>`).join('');\n  const soltos = segs.filter((s) => s.length === 1).map((s) => `<circle cx=\"${s[0][0].toFixed(1)}\" cy=\"${s[0][1].toFixed(1)}\" r=\"1.6\" fill=\"${color}\" opacity=\".7\"/>`).join('');\n  let ref;\n  if (refReal.length >= 2) {\n    const pts = [];\n    refS.forEach((v, i) => { if (v !== null) pts.push([x(i), y(v)]); });\n    ref = `<path d=\"${dOf(pts)}\" fill=\"none\" stroke=\"currentColor\" stroke-opacity=\".45\" stroke-width=\"1.2\" stroke-dasharray=\"2.5 2\"/>`;\n  } else {\n    // sem sessões carregadas não dá para traçar o tráfego: cai para a marca do valor inicial\n    ref = `<line x1=\"${P}\" x2=\"${W - P}\" y1=\"${y(real[0]).toFixed(1)}\" y2=\"${y(real[0]).toFixed(1)}\" stroke=\"currentColor\" stroke-opacity=\".28\" stroke-dasharray=\"2 2\"/>`;\n  }\n  const ult = segs.length ? segs[segs.length - 1][segs[segs.length - 1].length - 1] : null;\n  const dot = ult ? `<circle cx=\"${ult[0].toFixed(1)}\" cy=\"${ult[1].toFixed(1)}\" r=\"2.2\" fill=\"${color}\"/>` : '';\n  const tip = o.tip ? `<title>${esc(o.tip)}</title>` : '';\n  return `<svg viewBox=\"0 0 ${W} ${H}\" aria-hidden=\"true\">${tip}${area}${ref}${traco}${soltos}${dot}</svg>`;\n}\n\n// barra divergente de elasticidade DENTRO da célula — é daqui que a leitura de elasticidade nasce\nfunction miniElast(cl) {\n  const W = 88, H = 18, mid = W / 2, half = W / 2 - 2;\n  if (!cl) return '';\n  const col = (cl.cls === 'critico' || cl.cls === 'divergente') ? '#ef4444'\n    : cl.cls === 'atencao' ? '#f59e0b' : cl.cls === 'subutilizado' ? '#38bdf8'\n    : cl.cls === 'novo' ? '#22c55e' : '#64748b';\n  if (cl.e === null || !Number.isFinite(cl.e)) {\n    return `<svg viewBox=\"0 0 ${W} ${H}\" aria-hidden=\"true\"><line x1=\"${mid}\" x2=\"${mid}\" y1=\"1\" y2=\"${H - 1}\" stroke=\"currentColor\" stroke-opacity=\".3\"/></svg>`;\n  }\n  const e = Math.max(-4, Math.min(4, cl.e));\n  const w = Math.max(1.5, Math.abs(e) / 4 * half);\n  const x0 = e >= 0 ? mid : mid - w;\n  return `<svg viewBox=\"0 0 ${W} ${H}\" aria-hidden=\"true\">\n    <line x1=\"${mid}\" x2=\"${mid}\" y1=\"1\" y2=\"${H - 1}\" stroke=\"currentColor\" stroke-opacity=\".3\"/>\n    <rect x=\"${x0.toFixed(1)}\" y=\"4\" width=\"${w.toFixed(1)}\" height=\"${H - 8}\" rx=\"2\" fill=\"${col}\" opacity=\".9\"/></svg>`;\n}\n\nfunction chartStacked(store, tot) {\n  const W = 520, H = 210, PL = 54, PR = 12, PT = 14, PB = 32;\n  const per = tot.map((t) => ({ per: t.per, acc: costByProduct(store, t.per) }));\n  const max = Math.max(1, ...tot.map((t) => t.total || t.cost || 0));   // a escala precisa caber PESSOAS\n  const step = (W - PL - PR) / Math.max(1, per.length);\n  const bw = Math.min(70, step * 0.6);\n  const bars = per.map((d, i) => {\n    let yc = H - PB; const cx = PL + step * i + step / 2;\n    const segs = PROD_ORDER.filter((p) => d.acc[p]).map((p) => {\n      const h = (d.acc[p] / max) * (H - PT - PB); yc -= h;\n      return `<rect x=\"${(cx - bw / 2).toFixed(1)}\" y=\"${yc.toFixed(1)}\" width=\"${bw.toFixed(1)}\" height=\"${Math.max(0.6, h).toFixed(1)}\" fill=\"${PROD_COLOR[p]}\" opacity=\".92\"><title>${p}: ${fmtUsd(d.acc[p])}</title></rect>`;\n    }).join('');\n    return segs + `<text x=\"${cx.toFixed(1)}\" y=\"${H - 10}\" text-anchor=\"middle\" font-size=\"10\" fill=\"currentColor\" opacity=\".7\">${esc(d.per.lab)}</text>`;\n  }).join('');\n  const ax = [0, .5, 1].map((f) => {\n    const y = H - PB - f * (H - PT - PB);\n    return `<line x1=\"${PL}\" x2=\"${W - PR}\" y1=\"${y.toFixed(1)}\" y2=\"${y.toFixed(1)}\" stroke=\"currentColor\" stroke-opacity=\".1\"/>` +\n      `<text x=\"${PL - 6}\" y=\"${(y + 3.5).toFixed(1)}\" text-anchor=\"end\" font-size=\"9.5\" fill=\"currentColor\" opacity=\".5\">${fmtUsd(max * f).replace('US$ ', '')}</text>`;\n  }).join('');\n  const used = PROD_ORDER.filter((p) => per.some((d) => d.acc[p]));\n  return `<svg viewBox=\"0 0 ${W} ${H}\" role=\"img\" aria-label=\"custo por produto\">${ax}${bars}</svg>\n    <div class=\"lg\">${used.map((p) => `<span><i class=\"pdot\" style=\"background:${PROD_COLOR[p]}\"></i>${p}</span>`).join('')}</div>`;\n}\n\n// Projeção da TABELA: mesma ordenação, mesmo filtro. Deixa de ser um ranking próprio.\nfunction chartElasticity(rows) {\n  const list = rows.filter((r) => r.worst && r.worst.e !== null && Number.isFinite(r.worst.e)).slice(0, 14);\n  if (!list.length) return '<div class=\"empty\">nenhuma linha com elasticidade calculável — sessões estáveis ou só um período</div>';\n  const rowH = 21, W = 520, PL = 178, PR = 50, H = list.length * rowH + 26;\n  const mid = PL + (W - PL - PR) / 2, half = (W - PL - PR) / 2;\n  const maxW = Math.max(1, ...list.map((r) => r.maxCost));\n  const bars = list.map((r, i) => {\n    const yc = 16 + i * rowH;\n    const el = Math.max(-4, Math.min(4, r.worst.e));\n    const w = Math.max(1.5, Math.abs(el) / 4 * half);\n    const th = Math.max(5, 15 * Math.sqrt(r.maxCost / maxW));\n    const col = (r.worst.cls === 'critico' || r.worst.cls === 'divergente') ? '#ef4444'\n      : r.worst.cls === 'atencao' ? '#f59e0b' : r.worst.cls === 'subutilizado' ? '#38bdf8' : '#64748b';\n    return `<text x=\"${PL - 8}\" y=\"${yc + 4}\" text-anchor=\"end\" font-size=\"10\" fill=\"currentColor\" opacity=\"${r.top ? '.95' : '.6'}\" font-weight=\"${r.top ? '600' : '400'}\">${esc((r.p.toLowerCase() + '/' + r.e).slice(0, 30))}</text>` +\n      `<rect x=\"${(el >= 0 ? mid : mid - w).toFixed(1)}\" y=\"${(yc - th / 2).toFixed(1)}\" width=\"${w.toFixed(1)}\" height=\"${th.toFixed(1)}\" rx=\"2\" fill=\"${col}\" opacity=\".85\"><title>E=${r.worst.e.toFixed(2)} · custo ${fmtUsd(r.maxCost)} · impacto ${fmtUsd(r.impact)}</title></rect>` +\n      `<text x=\"${W - PR + 5}\" y=\"${yc + 4}\" font-size=\"10\" fill=\"currentColor\" opacity=\".7\">${r.worst.e.toFixed(1)}</text>`;\n  }).join('');\n  const ticks = [-4, -2, 0, 2, 4].map((t) => {\n    const xx = mid + t / 4 * half;\n    return `<line x1=\"${xx.toFixed(1)}\" x2=\"${xx.toFixed(1)}\" y1=\"6\" y2=\"${H - 14}\" stroke=\"currentColor\" stroke-opacity=\"${t === 0 ? '.35' : '.1'}\"/>` +\n      `<text x=\"${xx.toFixed(1)}\" y=\"${H - 3}\" text-anchor=\"middle\" font-size=\"9\" fill=\"currentColor\" opacity=\".5\">${t}</text>`;\n  }).join('');\n  return `<svg viewBox=\"0 0 ${W} ${H}\" role=\"img\" aria-label=\"elasticidade por evento\">${ticks}${bars}</svg>\n    <div class=\"foot\">Comprimento = elasticidade (limitada a ±4). <b>Espessura = peso no custo.</b> Segue a ordenação da tabela.</div>`;\n}\n\n// faixa de sessões por dia — só na visão semanal, onde os 21 dias existem\nfunction dailyStrip(days, daySess) {\n  const vals = days.map((d) => (daySess[d] === undefined ? null : daySess[d]));\n  const real = vals.filter((v) => v !== null);\n  if (real.length < 2) return '';\n  const W = 560, H = 62, PB = 14, max = Math.max(1, ...real);\n  const bw = (W / days.length) * 0.7, step = W / days.length;\n  const bars = days.map((d, i) => {\n    if (vals[i] === null) return '';\n    const h = (vals[i] / max) * (H - PB - 4);\n    const wk = Math.floor(i / WEEK_LEN);\n    return `<rect x=\"${(step * i + (step - bw) / 2).toFixed(1)}\" y=\"${(H - PB - h).toFixed(1)}\" width=\"${bw.toFixed(1)}\" height=\"${Math.max(1, h).toFixed(1)}\" rx=\"1.5\" fill=\"#38bdf8\" opacity=\"${0.35 + wk * 0.25}\"><title>${d} (${dowPt(d)}): ${vals[i].toLocaleString('pt-BR')}</title></rect>`;\n  }).join('');\n  const labs = days.map((d, i) => (i % WEEK_LEN === 0\n    ? `<text x=\"${(step * i).toFixed(1)}\" y=\"${H - 2}\" font-size=\"9\" fill=\"currentColor\" opacity=\".55\">${shortDay(d)}</text>` : '')).join('');\n  return `<svg viewBox=\"0 0 ${W} ${H}\" role=\"img\" aria-label=\"sessões por dia\">${bars}${labs}</svg>\n    <div class=\"foot\">Sessões dia a dia nas 3 semanas — a mais recente é a mais opaca. Revela a sazonalidade que a média semanal esconde.</div>`;\n}\n\n// ---------- render: painel explicativo ----------\nfunction renderExplain() {\n  const bands = BANDS.map((b) => `<div class=\"bandrow\"><span class=\"tag t-${b.cls}\">${esc(b.lab)}</span><span>${esc(b.txt)}</span></div>`).join('');\n  return `<div class=\"card mt\">\n    <h2>Como ler a elasticidade</h2>\n    <div class=\"explain\">\n      <div>\n        <div class=\"formula\"><em>E</em> = Δ% do recurso ÷ Δ% das sessões</div>\n        <div class=\"sub\">Sempre contra o <b>primeiro período</b> da lista. A pergunta que ela responde:\n          <i>o consumo se moveu na mesma proporção do tráfego, ou descolou?</i>\n          <b>|E| = 1</b> é acompanhar o tráfego; <b>|E| = 3</b>, mover-se três vezes mais rápido que ele.<br>\n          <b>|E| dá só a magnitude.</b> A direção vem da seta, que é o sinal da variação do\n          <b>consumo por sessão</b>: ↑ subiu (ficou mais caro por sessão), ↓ caiu (ficou mais eficiente).\n          Isso importa porque E é uma divisão: quando as <b>sessões caem</b>, o divisor é negativo e um\n          E alto passa a significar que o recurso caiu <i>mais</i> que o tráfego — ou seja, melhorou.</div>\n      </div>\n      <div>${bands}\n        <div class=\"foot\" style=\"margin-top:9px\">A cor da barra na coluna <b>elasticidade</b> segue estas faixas,\n          e a <b>espessura</b> dela no gráfico é o peso no custo — barra vermelha e grossa é o que dói.</div>\n      </div>\n      <div>\n        <h3>Quando E não vale</h3>\n        <ul>\n          <li><b>Sessões paradas</b> (variação abaixo de 2%): o divisor é quase zero e E explodiria — a linha\n            passa a ser classificada pela variação do <b>consumo por sessão</b>, e o rótulo mostra isso.</li>\n          <li><b>Base zero</b>: não há divisão possível — vira <span class=\"tag t-novo\">NOVO</span> ou\n            <span class=\"tag t-sumiu\">SUMIU</span>.</li>\n          <li><b>Direções opostas</b>: <span class=\"tag t-divergente\">DIVERGENTE</span> — consumo subiu com tráfego\n            caindo (ou o contrário). É o sinal mais forte de que algo mudou no comportamento, não na demanda.</li>\n        </ul>\n        <h3 style=\"margin-top:9px\">A coluna tendência</h3>\n        <ul>\n          <li>A <b>linha cheia</b> é o volume do recurso. A <b>pontilhada</b> é o volume que o\n            <b>tráfego sozinho explicaria</b> — as sessões reescaladas para partir do mesmo ponto.</li>\n          <li>A distância entre as duas <b>é</b> o consumo por sessão: linha cheia <b>acima</b> da pontilhada\n            significa que subiu por sessão; <b>abaixo</b>, que caiu. Coladas = acompanhou o tráfego.</li>\n        </ul>\n        <h3 style=\"margin-top:9px\">Símbolos</h3>\n        <ul>\n          <li><span class=\"warnI\">≈</span> o nível 1 dessa métrica é <b>média por recurso</b>, não total\n            (vale para <code>storage</code> e <code>login</code>) — só o detalhe fecha.</li>\n          <li><span class=\"warnI\">Δ</span> o detalhe diverge do nível 1; o detalhe é a verdade.</li>\n          <li><span class=\"warnI\">⋯</span> lista de recursos truncada no teto de páginas — o total exibido\n            <b>continua sendo o do nível 1</b>, que é completo.</li>\n          <li><span class=\"warnI\">⚠</span> nem o nível 1 nem o detalhe fecham esse valor.</li>\n        </ul>\n      </div>\n    </div>\n  </div>`;\n}\n\n// ---------- render: tabela produto/evento ----------\nfunction flagsOf(c) {\n  return (c.mean ? '<span class=\"warnI\" title=\"nível 1 é MÉDIA por recurso, não total — abra o detalhe\">≈</span>' : '')\n    + (c.truncated ? '<span class=\"warnI\" title=\"lista de recursos truncada; o total segue vindo do nível 1\">⋯</span>' : '')\n    + (c.diverges ? '<span class=\"warnI\" title=\"detalhe diverge do nível 1 — o detalhe é a verdade\">Δ</span>' : '')\n    + (c.noClose ? '<span class=\"warnI\" title=\"nível 1 é média e o detalhe truncou: este valor não fecha\">⚠</span>' : '');\n}\n\n// A tendência desenha os MESMOS números das colunas; o tooltip declara isso para não sobrar dúvida.\nfunction sparkOpts(periods, vals, unidade) {\n  return { tip: periods.map((p, i) => p.lab + ': ' + fmtVal(vals[i], unidade)).join('  →  ') };\n}\n\nfunction renderTable(st, scope, periods, store, rows) {\n  const open = st[K(scope, 'Open')] || {};\n  const head = `<tr>\n      <th class=\"l\">produto / evento</th><th class=\"l\">id</th><th>tendência<br><span style=\"font-weight:400;text-transform:none\">volume × tráfego</span></th>\n      ${periods.map((p, i) => `<th>${esc(p.lab)}${i === 0 ? ' · base' : ''}<br><span style=\"font-weight:400;text-transform:none\">${esc(p.sub)}</span></th>`).join('')}\n      <th>elasticidade</th><th>impacto US$</th></tr>`;\n  const body = rows.map((r) => {\n    const k = key(r.p, r.e);\n    const isOpen = !!open[k];\n    const col = PROD_COLOR[r.p] || '#64748b';\n    const shPct = (r.share * 100);\n    // O consumo POR SESSÃO é a leitura principal desta tabela — volume sozinho só acompanha o tráfego.\n    // Por isso ele vem grande; volume e US$ ficam de apoio na linha de baixo.\n    const cells = r.cells.map((c) => `<td><div class=\"stack\">\n        <span class=\"v\">${c.perS === null ? '—' : fmtPerS(c.perS, r.m.u)}<span class=\"un\">/sess</span>${flagsOf(c)}</span>\n        <span class=\"s\">${c.v === null ? '—' : fmtVal(c.v, r.m.u)}${c.c === null ? '' : ' · ' + fmtUsd(c.c)}</span>\n      </div></td>`).join('');\n    const w = r.worst;\n    const tag = w ? `<span class=\"tag t-${w.cls}\" title=\"${esc(w.why || '')}\">${esc(w.tag)}</span>` : '<span class=\"tag t-zero\">—</span>';\n    const main = `<tr class=\"grp ${r.top ? 'istop' : ''}\" data-act=\"toggle\" data-scope=\"${scope}\" data-k=\"${esc(k)}\">\n      <td class=\"l\"><div class=\"nm\">\n        <span class=\"bar\" title=\"${shPct.toFixed(1)}% do custo estimado do período\"><i style=\"width:${Math.min(100, shPct).toFixed(1)}%;background:${col}\"></i><b>${shPct >= 0.5 ? shPct.toFixed(0) + '%' : ''}</b></span>\n        <span><span class=\"mono\">${isOpen ? '▾' : '▸'}</span> <span class=\"ev\">${esc(r.e)}</span>\n          <span class=\"sub\">${esc(r.p.toLowerCase())} · ${esc(r.m.u || '')}</span>\n          ${r.top ? '<span class=\"tag t-top\" title=\"está entre os que formam 80% do custo estimado\">TOP CUSTO</span>' : ''}\n          ${(r.m.p === null || r.m.p === undefined) ? `<span class=\"tag t-zero\" title=\"${esc(r.m.n || 'sem preço na fatura de jul/26')}\">fora deste total</span>` : ''}\n          ${r.m.neg ? `<span class=\"tag t-top\" title=\"${esc(r.m.n || '')}\">preço acordado</span>` : ''}\n        </span></div></td>\n      <td class=\"l\"><span class=\"mono\" title=\"tipo de identificador dos recursos deste evento — é o que aparece na coluna id ao expandir\">${esc(r.m.dim || '—')}</span></td>\n      <td>${sparkline(r.spark, col, Object.assign(sparkOpts(periods, r.spark, r.m.u), { ref: r.refSpark }))}</td>\n      ${cells}\n      <td><div class=\"stack\">${miniElast(w)}<span class=\"s\">${tag}</span></div></td>\n      <td>${r.impact ? `<span class=\"${r.impact > 0 ? 'bad' : 'good'}\">${fmtUsd(r.impact)}</span>` : '—'}</td></tr>`;\n    return isOpen ? main + renderDetail(st, scope, periods, store, r) : main;\n  }).join('');\n  return `<div class=\"card mt cardTabela\"><div class=\"scroll\"><table><thead>${head}</thead><tbody>${body}</tbody></table></div>\n    ${rows.length ? '' : '<div class=\"empty\">nada para mostrar com o filtro atual</div>'}</div>`;\n}\n\nfunction renderDetail(st, scope, periods, store, r) {\n  const cols = periods.length + 5;   // nome | id | tendência | ...períodos... | elasticidade | impacto\n  const dets = periods.map((per) => store.det[per.k + '|' + r.p + '|' + r.e]);\n  // ⚠️ `|| x.__loading` é o que impede o crash: drill() escreve {__loading:true} em TODOS os períodos\n  // antes de buscar, então a guarda por ausência sozinha deixava passar, aggDetail devolvia null e o\n  // forEach abaixo estourava — derrubando a tela inteira (e o estado do par aberto persistia, então\n  // recarregar reproduzia). Com isso o ramo `busy` finalmente é alcançável.\n  if (dets.some((x) => !x || x.__loading)) {\n    const busy = dets.some((x) => x && x.__loading);\n    return `<tr class=\"det\"><td class=\"l\" colspan=\"${cols}\">\n      ${busy ? '<span class=\"spin\"></span> buscando o detalhe por recurso…'\n             : !SCOPES[scope].drill\n             // No mensal o detalhe por recurso não é oferecido: UM evento pode passar de 16 páginas\n             // por mês (~40 s cada). A seção Semanal responde a mesma pergunta por uma fração disso.\n             ? '<span class=\"warnI\">detalhe por recurso não é carregado no mensal — um único evento passa de '\n               + '16 páginas por mês. Para destrinchar por recurso, use a seção <b>Semanal</b>.</span>'\n             : `<button class=\"noprint\" data-act=\"drill\" data-scope=\"${scope}\" data-p=\"${esc(r.p)}\" data-e=\"${esc(r.e)}\">carregar detalhe por recurso (${periods.length} chamada${periods.length > 1 ? 's' : ''} · ~16 s cada)</button>` +\n             // Agora que só o par mais caro vem pronto, a maioria das linhas expandidas mostra este botão.\n             // Botão no papel não significa nada: no PDF vira uma frase dizendo que o detalhe não foi buscado.\n             '<span class=\"onlyprint\">detalhe por recurso não carregado</span>'}\n    </td></tr>`;\n  }\n  const errs = dets.filter((x) => x.__err);\n  if (errs.length) return `<tr class=\"det\"><td class=\"l\" colspan=\"${cols}\"><span class=\"bad\">falhou: ${esc(errs[0].__err)}</span></td></tr>`;\n  const dim = dets[0].dim || meta(r.p, r.e).dim || '?';\n  const maps = dets.map((d) => aggDetail(d, r.p, r.e));\n  // Cobertura real: quando a paginação trunca, a lista cobre só os primeiros dias do período —\n  // os valores do drill-down são de janela PARCIAL e não podem ser lidos como o período inteiro.\n  const covers = dets.map((d) => (d.cover ? d.cover.length : periods[0].days.length));\n  const coberturaDesigual = new Set(covers).size > 1;\n  // truncou antes de fechar UM dia sequer: não há valor honesto a mostrar aqui\n  if (covers.some((n) => n === 0)) {\n    return `<tr class=\"det\"><td class=\"l\" colspan=\"${cols}\"><span class=\"warnI\">⚠ a lista de recursos truncou\n      antes de completar um único dia do período — qualquer soma aqui seria de janela parcial. O total da\n      linha-pai continua vindo do nível 1, que é completo.</span></td></tr>`;\n  }\n  const refs = new Set(); maps.forEach((m) => m.forEach((_, kk) => refs.add(kk)));\n  // ⚠ O denominador tem de vir do MESMO recorte que o numerador. Quando a lista trunca, os valores\n  // aqui somam só os dias cobertos; dividir isso pelas sessões do período inteiro subestima o consumo\n  // por sessão na proporção dos dias que faltam — medido em TABLE/read semanal: 2 dias de 7 fazia\n  // 38.079/sess aparecer como 13.199/sess. daySess (só existe no semanal) é indexado por data, igual\n  // ao cover; sem ele, cai para as sessões do período inteiro.\n  const sessOf = (i) => {\n    const d = dets[i], full = store.sess[periods[i].k] || 0;\n    if (!d || !d.cover || !store.daySess) return full;\n    let s = 0;\n    for (const dia of d.cover) {\n      const v = store.daySess[dia];\n      if (v === undefined || v === null) return full;\n      s += v;\n    }\n    return s > 0 ? s : full;\n  };\n  const sBase = sessOf(0);\n  const sLast = sessOf(periods.length - 1);\n  const list = [...refs].map((ref) => {\n    const vals = maps.map((m) => (m.get(ref) === undefined ? 0 : m.get(ref)));\n    const cl = classify(vals[0], vals[vals.length - 1], sBase, sLast, SCOPES[scope].prog ? {\n      res: vals,\n      sess: periods.map((_, i) => sessOf(i)),\n      per: vals.map((v, i) => { const s = sessOf(i); return s ? v / s : null; })\n    } : undefined);\n    const cb = costOf(r.p, r.e, vals[0], periods[0].d1, periods[0].days.length) || 0;\n    const cl2 = costOf(r.p, r.e, vals[vals.length - 1], periods[periods.length - 1].d1,\n      periods[periods.length - 1].days.length) || 0;\n    // mesma referência de tráfego da linha-mãe, ancorada no período-base deste recurso\n    const refTraf = vals.map((_, i) => {\n      const s = sessOf(i);\n      return (sBase && s) ? vals[0] * (s / sBase) : null;\n    });\n    return { ref, vals, cl, imp: cl2 - cb, cb, spark: vals, refSerie: refTraf };\n  }).sort((a, b) => (st.sort === 'elasticidade'\n      ? Math.abs(b.cl.e || 0) - Math.abs(a.cl.e || 0)\n      : (Math.abs(b.imp) + b.cb) - (Math.abs(a.imp) + a.cb))).slice(0, 25);\n  const trunc = dets.some((x) => x.truncated);\n  const head = `<tr class=\"det\"><td class=\"l\" colspan=\"${cols}\">\n    <b>${refs.size}</b> recursos em <span class=\"mono\">${esc(dim)}</span> · mostrando 25 por ${st.sort === 'elasticidade' ? 'discrepância' : 'impacto'}\n    ${trunc ? `<span class=\"warnI\"> · ⋯ lista truncada em ${Math.max.apply(null, dets.map((x) => x.pages || 0)) * PAGE} linhas por período — o total da linha continua vindo do nível 1, que é completo, e o por-sessão abaixo já divide só pelas sessões dos dias cobertos</span>` : ''}\n    ${dim === 'file.reference' ? '<span class=\"sub\"> · arquivos individuais não têm nome no dicionário</span>' : ''}\n  </td></tr>`;\n  const body = list.map((x) => {\n    const nm = labelOf(x.ref, dim);\n    // o id do recurso ganha coluna própria: é ele que serve para procurar o recurso no builder.\n    // Em CONNECT/request a dimensão JÁ é o path, então nome e id seriam a mesma string — não duplica.\n    const idTxt = (dim === 'request.path' && nm === x.ref) ? '—' : (x.ref || '(nulo)');\n    return `<tr class=\"det\"><td class=\"l\">${nm ? esc(nm) : '<span class=\"tag t-zero\">sem nome</span>'}</td>\n      <td class=\"l\"><span class=\"mono\" title=\"${esc(dim)}\">${esc(idTxt)}</span></td>\n      <td>${sparkline(x.spark, PROD_COLOR[r.p] || '#64748b', Object.assign(sparkOpts(periods, x.spark, r.m.u), { ref: x.refSerie }))}</td>\n      ${x.vals.map((v, i) => { const s = sessOf(i);\n        return `<td><div class=\"stack\"><span class=\"v\">${s ? fmtPerS(v / s, r.m.u) : '—'}<span class=\"un\">/sess</span></span>\n          <span class=\"s\">${fmtVal(v, r.m.u)}</span></div></td>`; }).join('')}\n      <td><span class=\"tag t-${x.cl.cls}\" title=\"${esc(x.cl.why || '')}${coberturaDesigual ? ' · ⋯ os períodos cobrem quantidades diferentes de dias (truncagem da paginação): leia com ressalva' : ''}\">${esc(x.cl.tag)}${coberturaDesigual ? ' ⋯' : ''}</span></td>\n      <td>${x.imp ? `<span class=\"${x.imp > 0 ? 'bad' : 'good'}\">${fmtUsd(x.imp)}</span>` : '—'}</td></tr>`;\n  }).join('');\n  return head + body;\n}\n\nfunction renderKpis(tot) {\n  const base = tot[0];\n  // O US$/sessão é o número mais visível da página e o mais fácil de confundir com \"custo de um\n  // atendimento\". Ele inclui parcelas que não variam com volume (BUILDER/sessions, storage rateado),\n  // então cai quando o tráfego sobe sem que nada tenha ficado mais barato.\n  const nota = `<div class=\"foot\" style=\"grid-column:1/-1\">US$/sessão = custo modelado do período ÷ sessões\n    da plataforma no período. <b>Não é o custo de um atendimento nem custo marginal</b>: inclui parcelas\n    que existiriam com zero atendimento, então dobrar o volume não dobra o custo. Valores em US$ são\n    <b>modelados a preço acordado</b> e não reconciliam com a fatura — ver a nota ao pé da página.</div>`;\n  return nota + tot.map((t, i) => {\n    const dS = i && base.sessions ? (t.sessions - base.sessions) / base.sessions : null;\n    const dC = i && base.cps ? (t.cps - base.cps) / base.cps : null;\n    const cl = (x) => (x === null ? '' : x > 0.02 ? 'bad' : x < -0.02 ? 'good' : '');\n    return `<div class=\"kpi ${i === 0 ? 'isbase' : ''}\">\n      <div class=\"lab\">${esc(t.per.lab)} · ${esc(t.per.sub)}${i === 0 ? ' · BASE' : ''}</div>\n      <div class=\"big\">${t.cps === null ? '—' : 'US$ ' + t.cps.toFixed(4)}<span class=\"sub\" style=\"font-size:11px\"> ${t.semDados ? 'sem dado carregado' : 'por sessão'}</span></div>\n      <div class=\"foot\">${i ? `<span class=\"${cl(dC)}\">${fmtPct(dC)}</span> vs base · ` : 'referência · '}${fmtUsd(t.cost)} de custo modelado</div>\n      ${t.aloc ? `<div class=\"foot\">+ ${fmtUsd(t.aloc)} de pessoas (${t.nAloc} aloc.) ·\n        <b>${fmtUsd(t.total)} total</b></div>` : ''}\n      <div class=\"foot\">${t.sessions === null ? '—' : t.sessions.toLocaleString('pt-BR')} sessões ${i ? `<span class=\"${cl(dS)}\">${fmtPct(dS)}</span>` : ''}</div>\n    </div>`;\n  }).join('');\n}\n\n// ---------- estado ----------\nfunction defaultDays(d2) {\n  const n = Math.max(1, Math.min(MAX_DAYS, Number(d2.param('defaultDays', 3)) || 3));\n  const end = yesterday(), out = [];\n  for (let i = n - 1; i >= 0; i--) out.push(addDays(end, -i));\n  return out;\n}\nconst EMPTY_PROG = { done: 0, total: 0, label: '' };\n// render() nunca depende de setState ter rodado: lê o estado com defaults aplicados.\nfunction viewState(d2) {\n  const s = d2.state || {};\n  return {\n    theme: s.theme || 'dark', sort: s.sort || 'impacto',\n    minCost: (s.minCost === undefined || s.minCost === null) ? 1 : s.minCost,\n    days: (s.days && s.days.length) ? s.days : defaultDays(d2),\n    dAgg: s.dAgg || {}, dSess: s.dSess || {}, dDet: s.dDet || {}, dOpen: s.dOpen || {},\n    dLoading: !!s.dLoading, dProg: s.dProg || EMPTY_PROG, dErr: s.dErr || null, dRun: s.dRun || 0,\n    wEnd: s.wEnd || yesterday(),\n    wAgg: s.wAgg || {}, wSess: s.wSess || {}, wDaySess: s.wDaySess || {}, wDet: s.wDet || {},\n    wOpen: s.wOpen || {}, wLoading: !!s.wLoading, wProg: s.wProg || EMPTY_PROG,\n    wErr: s.wErr || null, wRun: s.wRun || 0, wWarn: s.wWarn || '',\n    wCount: Math.max(WEEKS_MIN, Math.min(WEEKS_MAX, s.wCount || WEEKS_MAX)),\n    mEnd: s.mEnd || yesterday(),\n    mAgg: s.mAgg || {}, mSess: s.mSess || {}, mDet: s.mDet || {}, mOpen: s.mOpen || {},\n    mLoading: !!s.mLoading, mProg: s.mProg || EMPTY_PROG, mErr: s.mErr || null, mRun: s.mRun || 0,\n    mWarn: s.mWarn || '',\n    mCount: Math.max(MONTHS_MIN, Math.min(MONTHS_MAX, s.mCount || MONTHS_MAX)),\n    mAlloc: s.mAlloc || {},\n    fx: (s.fx === undefined || s.fx === null) ? FX_DEFAULT : s.fx,\n    printedAt: s.printedAt || '', pdfWarn: s.pdfWarn || ''\n  };\n}\n// ---------- escopo ----------\n// O escopo era BINÁRIO em 24 pontos (`sc === 'w' ? … : …`), e 16 escritas de estado fixavam o\n// prefixo `d`/`w` no nome da chave. Com três seções cada um viraria ternário de três vias. As chaves\n// já seguem o padrão <letra><Nome> (dAgg/wAgg/mAgg), então basta montar o nome — mesmo truque que\n// `alive` já usava com `d2.state[runKey]`. Adicionar um 4º escopo passa a ser uma linha em SCOPES.\nconst K = (sc, nome) => sc + nome;\nconst setScope = (sc, o) => { const out = {}; for (const n in o) out[K(sc, n)] = o[n]; return out; };\nconst SCOPES = {\n  d: { ord: 1, periods: (st) => dayPeriods(st.days),\n       maxPages: MAX_PAGES,   topN: TOP_N,   prog: false, strip: false, drill: true },\n  w: { ord: 2, periods: (st) => weekPeriods(st.wEnd, st.wCount),\n       maxPages: MAX_PAGES_W, topN: TOP_N_W, prog: true,  strip: true,  drill: true },\n  // `strip:false` — o mensal não busca sessões por dia: o endpoint devolve a soma do intervalo, então\n  // um mês custa 1 chamada em vez de 30. `drill:false` — detalhe por recurso num mês são ~16 páginas.\n  m: { ord: 3, periods: (st) => monthPeriods(st.mEnd, st.mCount),\n       maxPages: MAX_PAGES_M, topN: TOP_N_M, prog: true,  strip: false, drill: false, alloc: true }\n};\n// `periodTotals` e `costByProduct` recebem só `store`, nunca `st` — então a alocação viaja por aqui,\n// o que evita mexer na assinatura das duas e nos seus chamadores.\nconst storeOf = (st, sc) => ({ agg: st[K(sc, 'Agg')] || {}, sess: st[K(sc, 'Sess')] || {},\n  det: st[K(sc, 'Det')] || {}, daySess: st[K(sc, 'DaySess')] || {},\n  alloc: SCOPES[sc].alloc ? (per) => allocOf(st, per) : null,\n  allocUsd: Number(st.fx) > 0 ? ALLOC_BRL / Number(st.fx) : 0 });\nconst periodsOf = (st, sc) => SCOPES[sc].periods(st);\n\n// ---------- render: controles ----------\nfunction progBar(prog) {\n  if (!prog.total) return '';\n  return `<div class=\"mt8\"><div class=\"bar2\"><i style=\"width:${(prog.done / prog.total * 100).toFixed(1)}%\"></i></div>\n    <div class=\"sub\" style=\"margin-top:5px\">${prog.done}/${prog.total} chamadas · ${esc(prog.label || '')}</div></div>`;\n}\n\nfunction ctrlDaily(st) {\n  const chips = st.days.map((d, i) => `\n    <span class=\"chip ${i === 0 ? 'base' : ''}\" title=\"${i === 0 ? 'período-base: todos comparam com ele' : ''}\">\n      ${i === 0 ? '<b>BASE</b>' : ''}\n      <input type=\"date\" data-act=\"setday\" data-i=\"${i}\" value=\"${d}\" max=\"${yesterday()}\">\n      <span class=\"mono\">${dowPt(d)}</span>\n      ${st.days.length > MIN_DAYS ? `<button class=\"x\" data-act=\"rmday\" data-i=\"${i}\" title=\"remover\">×</button>` : ''}\n    </span>`).join('');\n  return `<div class=\"card\"><div class=\"row\">\n      ${chips}\n      ${st.days.length < MAX_DAYS ? '<button data-act=\"addday\" class=\"ghost\">+ dia</button>' : '<span class=\"sub\">teto de 7 dias</span>'}\n      ${st.days.length <= MIN_DAYS ? `<span class=\"sub\">mínimo de ${MIN_DAYS} dias — o primeiro é a base de comparação</span>` : ''}\n      <button class=\"pri\" data-act=\"loadD\" ${st.dLoading ? 'disabled' : ''}>${st.dLoading ? '<span class=\"spin\"></span> carregando…' : 'Carregar diário'}</button>\n      ${st.dLoading ? '<button data-act=\"cancelD\" class=\"ghost\">cancelar</button>' : ''}\n    </div>${progBar(st.dProg)}</div>`;\n}\n\nfunction ctrlWeekly(st) {\n  const pers = weekPeriods(st.wEnd, st.wCount);\n  return `<div class=\"card\"><div class=\"row\">\n      <span class=\"chip\"><b>ATÉ</b><input type=\"date\" data-act=\"setwend\" value=\"${st.wEnd}\" max=\"${yesterday()}\"><span class=\"mono\">${dowPt(st.wEnd)}</span></span>\n      <span class=\"sub\">${pers.map((p, i) => (i === 0 ? '<b>' + esc(p.lab) + '</b> (base)' : esc(p.lab))).join(' · ')}</span>\n      <button data-act=\"rmweek\" class=\"ghost\" title=\"mínimo ${WEEKS_MIN} semanas\">− semana</button>\n      <span class=\"mono\">${st.wCount} sem.</span>\n      <button data-act=\"addweek\" class=\"ghost\" title=\"máximo ${WEEKS_MAX} semanas\">+ semana</button>\n      <button class=\"pri\" data-act=\"loadW\" ${st.wLoading ? 'disabled' : ''}>${st.wLoading ? '<span class=\"spin\"></span> carregando…' : 'Carregar semanal'}</button>\n      ${st.wLoading ? '<button data-act=\"cancelW\" class=\"ghost\">cancelar</button>' : ''}\n    </div>\n    ${st.wWarn === 'max' ? `<div class=\"note mt8\"><b>Máximo de ${WEEKS_MAX} semanas.</b>\n      Com 4 janelas a leitura já é de progressão — a reta sobre os 4 pontos, que é o que separa\n      \"subiu e voltou\" de \"alta consistente\". A quinta só somaria carga (9 chamadas por janela) sem\n      mudar essa leitura. Para olhar mais longe, mova a data final.</div>` : ''}\n    ${st.wWarn === 'min' ? `<div class=\"note mt8\"><b>Mínimo de ${WEEKS_MIN} semanas.</b>\n      Com uma semana só, o período-base seria o único período — não sobraria nada contra o que comparar,\n      e elasticidade e impacto ficariam indefinidos. Para ver uma semana isolada, use a seção diária.</div>` : ''}\n    ${progBar(st.wProg)}</div>`;\n}\n\nfunction ctrlMonthly(st) {\n  const pers = monthPeriods(st.mEnd, st.mCount);\n  const parc = pers.filter((p) => p.parcial);\n  const usdPorAloc = Number(st.fx) > 0 ? ALLOC_BRL / Number(st.fx) : 0;\n  return `<div class=\"card\"><div class=\"row\">\n      <span class=\"chip\"><b>ATÉ O MÊS DE</b><input type=\"date\" data-act=\"setmend\" value=\"${st.mEnd}\" max=\"${yesterday()}\"><span class=\"mono\">${monthLab(st.mEnd)}</span></span>\n      <span class=\"sub\">${pers.map((p, i) => (i === 0 ? '<b>' + esc(p.lab) + '</b> (base)' : esc(p.lab))).join(' · ')}</span>\n      <button data-act=\"rmmonth\" class=\"ghost\" title=\"mínimo ${MONTHS_MIN} meses\">− mês</button>\n      <span class=\"mono\">${st.mCount} meses</span>\n      <button data-act=\"addmonth\" class=\"ghost\" title=\"máximo ${MONTHS_MAX} meses\">+ mês</button>\n      <button class=\"pri\" data-act=\"loadM\" ${st.mLoading ? 'disabled' : ''}>${st.mLoading ? '<span class=\"spin\"></span> carregando…' : 'Carregar mensal'}</button>\n      ${st.mLoading ? '<button data-act=\"cancelM\" class=\"ghost\">cancelar</button>' : ''}\n    </div>\n    <div class=\"row alocrow\">\n      <span class=\"chip\"><b>ALLOCATIONS</b><span class=\"sub\">devs contratados · R$ ${ALLOC_BRL.toLocaleString('pt-BR')} cada</span></span>\n      ${pers.map((p) => { const n = allocOf(st, p); return `<span class=\"alocbox\">\n        <span class=\"alocmes\">${esc(p.lab)}</span>\n        <span class=\"alocctl\">\n          <button data-act=\"allocdec\" data-k=\"${esc(p.k)}\" ${n <= 0 ? 'disabled' : ''}>−</button>\n          <input type=\"number\" class=\"alocnum\" data-act=\"allocset\" data-k=\"${esc(p.k)}\" value=\"${n}\" min=\"0\" max=\"${ALLOC_MAX}\" step=\"1\">\n          <button data-act=\"allocinc\" data-k=\"${esc(p.k)}\" ${n >= ALLOC_MAX ? 'disabled' : ''}>+</button>\n        </span>\n        <span class=\"alocusd\">${fmtUsd(n * usdPorAloc)}</span>\n      </span>`; }).join('')}\n      <span class=\"chip\"><b>CÂMBIO</b><input type=\"number\" data-act=\"setfx\" value=\"${st.fx}\" min=\"0.01\" step=\"0.01\" style=\"width:76px\"><span class=\"mono\">R$/US$</span></span>\n    </div>\n    ${parc.length ? `<div class=\"note mt8\"><b>${esc(parc[0].lab)} é um mês PARCIAL</b> (${esc(parc[0].sub)}).\n      O custo <b>por sessão</b> continua comparável, porque numerador e denominador encolhem juntos — mas o\n      custo <b>total</b> desse mês aparece menor só porque ainda faltam dias. Não leia essa queda como economia.\n      <br>A <b>alocação entra cheia</b> nesse mês — salário não se rateia por dia decorrido —, então o total\n      mistura pessoas de mês inteiro com infra de mês parcial.</div>` : ''}\n    ${st.mWarn === 'max' ? `<div class=\"note mt8\"><b>Máximo de ${MONTHS_MAX} meses.</b>\n      Com 4 pontos a leitura já é de progressão — a reta sobre os 4 meses. Para olhar mais para trás,\n      mova o mês final.</div>` : ''}\n    ${st.mWarn === 'min' ? `<div class=\"note mt8\"><b>Mínimo de ${MONTHS_MIN} meses.</b>\n      Com um mês só, o período-base seria o único período — não sobraria nada contra o que comparar.</div>` : ''}\n    ${progBar(st.mProg)}</div>`;\n}\n\n// ---------- render: uma seção completa (serve diário e semanal) ----------\nfunction renderSection(st, sc) {\n  const periods = periodsOf(st, sc);\n  const store = storeOf(st, sc);\n  const has = periods.some((p) => store.agg[p.k]);\n  if (!has) return '';\n  const tot = periodTotals(store, periods);\n  const rows = sortRows(buildRows(store, periods, SCOPES[sc].prog), st.sort, Number(st.minCost) || 0);\n  const strip = SCOPES[sc].strip ? dailyStrip(periods.reduce((a, p) => a.concat(p.days), []), store.daySess) : '';\n  // consumo carregou e sessões não: a tela continua útil, mas metade das perguntas fica sem resposta\n  const semSess = periods.every((p) => store.sess[p.k] === undefined || store.sess[p.k] === null);\n  const aviso = semSess ? `<div class=\"note mt\">Consumo carregado, <b>sessões não</b>. Sem elas não há\n    custo por sessão nem elasticidade — volume e custo absoluto seguem válidos. A causa quase sempre é o\n    segredo compartilhado do KeyVault fora de sincronia; a faixa vermelha acima traz o diagnóstico.</div>` : '';\n  // Períodos selecionados mas ainda não buscados — acontece ao mover a data final ou ao passar de 2 para\n  // 3 semanas, que acrescenta uma janela mais antiga E a torna a nova base. Sem este aviso a tela\n  // mostraria “—” em toda a coluna e pareceria defeito, quando só falta carregar.\n  const faltam = periods.filter((p) => !store.agg[p.k]);\n  const avisoFalta = faltam.length ? `<div class=\"note mt\"><b>${faltam.length} de ${periods.length} períodos\n    ainda sem dado</b> (${esc(faltam.map((p) => p.lab).join(', '))}) — as colunas saem como “—”.\n    ${!store.agg[periods[0].k] ? '<b>O período-base está entre eles</b>, então nenhuma comparação vale. ' : ''}\n    Clique em <b>Carregar</b> para buscá-los.</div>` : '';\n  return aviso + avisoFalta + `<div class=\"hero mt\">\n      <div class=\"card\"><h2>Sessões × custo por sessão</h2>${chartHero(tot)}${strip ? '<div class=\"mt8\">' + strip + '</div>' : ''}</div>\n      <div class=\"heroK\">${renderKpis(tot)}</div>\n    </div>\n    <div class=\"charts mt\">\n      <div class=\"card\"><h2>Custo estimado por produto</h2>${chartStacked(store, tot)}</div>\n      <div class=\"card\"><h2>Elasticidade por evento</h2>${chartElasticity(rows)}</div>\n    </div>\n    ${renderTable(st, sc, periods, store, rows)}`;\n}\n\nexport default {\n  css: CSS,\n\n  render(d2) {\n    const st = viewState(d2);\n    // Cabeçalho que SÓ existe no papel: os controles somem na impressão, então o escopo do relatório\n    // precisa estar escrito em texto, senão o PDF sai sem dizer de que dias ele fala.\n    // ⚠️ weekPeriods sem o wCount usava o teto e podia LISTAR mais semanas do que a seção mostra.\n    const cD = dayPeriods(st.days).filter((p) => st.dAgg[p.k]).map((p) => p.lab);\n    const cW = weekPeriods(st.wEnd, st.wCount).filter((p) => st.wAgg[p.k]).map((p) => p.lab);\n    const mPer = monthPeriods(st.mEnd, st.mCount).filter((p) => st.mAgg[p.k]);\n    const cM = mPer.map((p) => p.lab);\n    const temAloc = mPer.some((p) => allocOf(st, p) > 0);\n    const escopo = [cD.length ? 'Diário: ' + cD.join(', ') : '', cW.length ? 'Semanal: ' + cW.join(', ') : '',\n      cM.length ? 'Mensal: ' + cM.join(', ') : ''].filter(Boolean).join('   ·   ') || 'nenhum período carregado';\n    // As duas seções podem cobrir os MESMOS dias (um dia solto costuma cair dentro de uma das semanas).\n    // Somar as duas contaria o mesmo custo duas vezes — e no papel nada impediria esse erro.\n    // Com três seções a sobreposição virou a regra (dia ⊂ semana ⊂ mês), então o aviso precisa dizer\n    // QUAIS pares se cruzam. O teste também passa a ser de interseção de intervalos: o antigo só\n    // comparava o INÍCIO de um contra o outro e perdia um período que começa antes e invade.\n    const carr = [['Diário', dayPeriods(st.days).filter((p) => st.dAgg[p.k])],\n      ['Semanal', weekPeriods(st.wEnd, st.wCount).filter((p) => st.wAgg[p.k])],\n      ['Mensal', monthPeriods(st.mEnd, st.mCount).filter((p) => st.mAgg[p.k])]];\n    const pares = [];\n    for (let i = 0; i < carr.length; i++) for (let j = i + 1; j < carr.length; j++) {\n      if (carr[i][1].some((a) => carr[j][1].some((b) => a.d0 <= b.d1 && b.d0 <= a.d1))) {\n        pares.push(carr[i][0] + ' × ' + carr[j][0]);\n      }\n    }\n    const alerta = pares.length\n      ? 'Seções que cobrem os MESMOS dias: ' + pares.join(', ') + '. Não some uma com a outra — '\n        + 'seria o mesmo custo contado duas vezes.'\n      : '';\n    return `<div class=\"wrap ${st.theme === 'light' ? 'light' : ''}\">\n      <div class=\"printhead\">\n        <h1>Consumo × sessões — Natura AVI</h1>\n        <div class=\"l\">${esc(escopo)}</div>\n        ${alerta ? `<div class=\"l\"><b>${esc(alerta)}</b></div>` : ''}\n        ${temAloc ? `<div class=\"l\">Alocações a R$ ${ALLOC_BRL.toLocaleString('pt-BR')}/mês por desenvolvedor,\n          convertidas a R$ ${Number(st.fx).toFixed(2).replace('.', ',')}/US$. Elas somam ao total do mês e NÃO entram no\n          custo por sessão, que segue sendo só de infraestrutura.</div>` : ''}\n        <div class=\"l\">Gerado em ${esc(st.printedAt)} · preços da fatura de jul/26, exceto DOMAIN/ai_tokens\n          ao preço acordado de US$ 0,000008/token — por isso o total NÃO reconcilia com o valor faturado.</div>\n      </div>\n      <div class=\"between\">\n        <div>\n          <h1>Consumo × sessões — Natura AVI</h1>\n          <div class=\"sub\">A métrica-âncora é <b>produto/evento</b>: quanto cada recurso custa por sessão e\n            se ele cresceu na proporção do tráfego. O escopo vai de dias avulsos a janelas de 7 dias e meses de calendário.</div>\n        </div>\n        <div class=\"row noprint\">\n          <button data-act=\"pdf\" title=\"abre o diálogo de impressão do navegador; escolha 'Salvar como PDF'\">⬇ PDF</button>\n          <button data-act=\"sort\" data-v=\"impacto\" class=\"${st.sort === 'impacto' ? 'on' : ''}\">Impacto US$</button>\n          <button data-act=\"sort\" data-v=\"elasticidade\" class=\"${st.sort === 'elasticidade' ? 'on' : ''}\">Discrepância</button>\n          ${st.sort === 'elasticidade' ? `<span class=\"sub\">piso <input type=\"number\" data-act=\"mincost\" value=\"${st.minCost}\" min=\"0\" step=\"1\" style=\"width:70px\"> US$</span>` : ''}\n          <button data-act=\"theme\" class=\"ghost\">${st.theme === 'dark' ? '☀' : '☾'}</button>\n        </div>\n      </div>\n      ${st.pdfWarn ? `<div class=\"note mt8 noprint\"><b>Há busca em andamento.</b>\n        Imprimir agora levaria ao papel a frase “buscando o detalhe por recurso…” no lugar dos\n        números, porque o estado de carregamento fica dentro da tabela. Espere a carga terminar —\n        ou clique em <b>cancelar</b> — e gere o PDF de novo.</div>` : ''}\n\n      ${renderExplain()}\n\n      <div class=\"secthead\"><span class=\"n\">1</span><h2 style=\"margin:0\">Diário — dias avulsos, até ${MAX_DAYS}</h2>\n        <span class=\"sub\">o primeiro dia é a base de comparação</span></div>\n      <div class=\"noprint\">${ctrlDaily(st)}</div>\n      ${st.dErr ? `<div class=\"err mt\">${esc(st.dErr)}</div>` : ''}\n      ${renderSection(st, 'd') || '<div class=\"card mt noprint\"><div class=\"empty\">escolha os dias e clique em <b>Carregar diário</b>.</div></div>'}\n\n      <div class=\"secthead\"><span class=\"n\">2</span><h2 style=\"margin:0\">Semanal — ${st.wCount} janelas de ${WEEK_LEN} dias</h2>\n        <span class=\"sub\">de ${WEEKS_MIN} a ${WEEKS_MAX} janelas; a mais antiga é a base · com 3+ a\n          elasticidade lê a <b>progressão inteira</b>, e o <b>n/n</b> diz quantos degraus seguiram a direção</span></div>\n      <div class=\"noprint\">${ctrlWeekly(st)}</div>\n      ${st.wErr ? `<div class=\"err mt\">${esc(st.wErr)}</div>` : ''}\n      ${renderSection(st, 'w') || '<div class=\"card mt noprint\"><div class=\"empty\">escolha a data final e clique em <b>Carregar semanal</b>.<br><span class=\"sub\">1 chamada por semana cobre os 7 dias — o custo da API é por chamada, não por dia.</span></div></div>'}\n\n      <div class=\"secthead\"><span class=\"n\">3</span><h2 style=\"margin:0\">Mensal — ${st.mCount} meses de calendário</h2>\n        <span class=\"sub\">de ${MONTHS_MIN} a ${MONTHS_MAX} meses; o mais antigo é a base · recorte da <b>fatura</b> ·\n          o detalhe por recurso fica na seção Semanal</span></div>\n      <div class=\"noprint\">${ctrlMonthly(st)}</div>\n      ${st.mErr ? `<div class=\"err mt\">${esc(st.mErr)}</div>` : ''}\n      ${renderSection(st, 'm') || '<div class=\"card mt noprint\"><div class=\"empty\">escolha o mês final e clique em <b>Carregar mensal</b>.<br><span class=\"sub\">um mês custa 2 chamadas (sessões + nível 1) — 4 meses saem mais baratos que 4 semanas.</span></div></div>'}\n\n      <div class=\"foot\">\n        <b>Preços</b> da fatura de jul/26, <b>exceto <code>DOMAIN/ai_tokens</code>, que usa o preço acordado de US$ 0,000008 por token</b>\n        — as faturas registram US$ 0,0001, o preço de tabela, 12,5× maior. O custo mostrado aqui é o real; ele\n        <b>não</b> reconcilia com o valor faturado, e a diferença é quase toda essa linha.\n        Os demais preços continuam vindo da fatura e podem ter o mesmo tipo de desconto sem que eu saiba.\n        <code>ID/sessions</code> e <code>BUILDER/sessions</code> não são faturados\n        por dia (a fatura cobra <code>logged_users</code> por mês). <code>TABLE/storage</code> vem como média por\n        DataSource nos dois níveis e não reconcilia com a fatura — fica só como volume.\n        Métricas de <b>estoque</b> (<code>storage</code>) são a média dos dias do período, nunca a soma.\n      </div>\n    </div>`;\n  },\n\n  mounted(d2) {\n    const api = makeApi(d2);\n    const aborts = {};   // um AbortController por seção, para o cancelar interromper de fato\n\n    // Regras de impressão que precisam viver no DOCUMENTO, não no shadow root: a altura fixa e o\n    // scroll que cortariam o relatório na primeira página estão nos ANCESTRAIS do componente.\n    // guarda de ambiente: o dry_render roda num DOM simulado onde document.head não existe\n    if (typeof document !== 'undefined' && document.head && document.getElementById\n        && !document.getElementById('pc-print-css')) {\n      const s = document.createElement('style');\n      s.id = 'pc-print-css';\n      s.textContent = '@page{size:A4 landscape;margin:8mm}'\n        + '@media print{html,body{height:auto!important;overflow:visible!important;background:#fff!important}'\n        + '.data2-artboard,.data2-player-block{height:auto!important;max-height:none!important;'\n        + 'overflow:visible!important;position:static!important}}';\n      document.head.appendChild(s);\n      d2.onUnmount(() => { const el = document.getElementById('pc-print-css'); if (el) el.remove(); });\n    }\n\n    async function loadScope(sc) {\n      const st = viewState(d2);\n      if (st[K(sc, 'Loading')]) return;\n      const runKey = K(sc, 'Run');\n      const run = (st[runKey] || 0) + 1;\n      const P = (o) => d2.setState(setScope(sc, {\n        Loading: o.loading, Prog: o.prog || EMPTY_PROG,\n        Err: o.err === undefined ? d2.state[K(sc, 'Err')] : o.err\n      }));\n      const periods = periodsOf(st, sc);\n      const alive = () => d2.state[runKey] === run;\n      if (aborts[sc]) aborts[sc].abort();\n      const ac = (typeof AbortController !== 'undefined') ? new AbortController() : null;\n      aborts[sc] = ac;\n      const sig = ac ? ac.signal : undefined;\n\n      d2.setState(setScope(sc, { Run: run, Loading: true, Err: null,\n        Agg: {}, Sess: {}, DaySess: {}, Det: {}, Prog: { done: 0, total: 0, label: 'fase 1' } }));\n\n      try {\n        // ---- fase 1: sessões + nível 1 por período (+ sessões por dia no semanal) ----\n        const jobs = [];\n        periods.forEach((per) => {\n          jobs.push({ kind: 's', per });\n          jobs.push({ kind: 'o', per });\n        });\n        const allDays = SCOPES[sc].strip ? periods.reduce((a, p) => a.concat(p.days), []) : [];\n        allDays.forEach((day) => jobs.push({ kind: 'ds', day }));\n        P({ loading: true, prog: { done: 0, total: jobs.length, label: 'fase 1: sessões e visão geral' } });\n\n        const res = await pool(jobs.map((j) => () => (\n          j.kind === 's' ? api.sessions(j.per.d0, j.per.d1, sig)\n            : j.kind === 'o' ? api.overview(j.per.d0, j.per.d1, sig)\n              : api.sessions(j.day, j.day, sig)\n        )), POOL, (done) => { if (alive()) P({ loading: true, prog: { done, total: jobs.length, label: 'fase 1: sessões e visão geral' } }); }, () => !alive());\n        if (!alive()) return;\n\n        const sess = {}, agg = {}, daySess = {}, errs = [];\n        jobs.forEach((j, i) => {\n          const r = res[i];\n          if (!r) return;\n          if (r.__err) { errs.push({ lab: (j.per ? j.per.lab : j.day), msg: String(r.__err) }); return; }\n          if (j.kind === 's') sess[j.per.k] = num(r.sessions);\n          else if (j.kind === 'o') agg[j.per.k] = aggLevel1(r.rows || []);\n          else daySess[j.day] = num(r.sessions);\n        });\n        // 27 chamadas falhando pelo mesmo motivo são UM problema, não 27 — agrupa por mensagem para\n        // a faixa de erro dizer a causa uma vez e listar quais períodos ela atingiu.\n        const porMsg = {};\n        errs.forEach((e) => { (porMsg[e.msg] = porMsg[e.msg] || []).push(e.lab); });\n        const resumoErr = Object.keys(porMsg).map((m) => {\n          const ls = porMsg[m];\n          const quem = ls.length > 4 ? ls.slice(0, 4).join(', ') + ' e mais ' + (ls.length - 4) : ls.join(', ');\n          return (ls.length > 1 ? ls.length + '× (' + quem + ') — ' : quem + ' — ') + m;\n        }).join('  |  ');\n        const errFinal = errs.length ? resumoErr : null;\n        d2.setState(setScope(sc, { Sess: sess, Agg: agg, DaySess: daySess, Err: errFinal }));\n\n        // ---- fase 2: detalhe antecipado dos pares que mais pesam ----\n        const eager = pickEager({ agg, sess, det: {} }, periods[0], SCOPES[sc].topN);\n        if (!eager.length) { P({ loading: false, prog: EMPTY_PROG }); return; }\n        const t2 = [];\n        eager.forEach(({ p, e }) => periods.forEach((per) => t2.push({ per, p, e })));\n        let done = 0;\n        const lab2 = 'fase 2: detalhe de ' + eager.length + ' par' + (eager.length > 1 ? 'es' : '')\n          + ' — os demais são sob demanda';\n        P({ loading: true, prog: { done: 0, total: t2.length, label: lab2 } });\n        await pool(t2.map((j) => async () => {\n          const dk = j.per.k + '|' + j.p + '|' + j.e;\n          let out;\n          try { out = await fetchDetail(api, j.per, j.p, j.e, SCOPES[sc].maxPages, sig); }\n          catch (err) { out = { __err: (err && err.message) || String(err) }; }\n          if (!alive()) return;\n          const cur = d2.state[K(sc, 'Det')] || {};\n          d2.setState(setScope(sc, { Det: Object.assign({}, cur, { [dk]: out }) }));\n        }), POOL, () => { done++; if (alive()) P({ loading: true, prog: { done, total: t2.length, label: lab2 } }); }, () => !alive());\n        if (!alive()) return;\n        P({ loading: false, prog: EMPTY_PROG });\n      } catch (err) {\n        if (alive()) P({ loading: false, prog: EMPTY_PROG, err: (err && err.message) || String(err) });\n      }\n    }\n\n    async function drill(sc, p, e) {\n      const st = viewState(d2);\n      const periods = periodsOf(st, sc);\n      const mark = {};\n      periods.forEach((per) => { mark[per.k + '|' + p + '|' + e] = { __loading: true }; });\n      const base = d2.state[K(sc, 'Det')] || {};\n      d2.setState(setScope(sc, { Det: Object.assign({}, base, mark) }));\n      await pool(periods.map((per) => async () => {\n        let out;\n        try { out = await fetchDetail(api, per, p, e, SCOPES[sc].maxPages, aborts[sc] ? aborts[sc].signal : undefined); }\n        catch (err) { out = { __err: (err && err.message) || String(err) }; }\n        const cur = d2.state[K(sc, 'Det')] || {};\n        d2.setState(setScope(sc, { Det: Object.assign({}, cur, { [per.k + '|' + p + '|' + e]: out }) }));\n      }), POOL);\n    }\n\n    d2.on('[data-act]', 'click', (ev, el) => {\n      const t = el || (ev.target && ev.target.closest && ev.target.closest('[data-act]'));\n      if (!t) return;\n      const act = t.dataset.act, st = viewState(d2);\n      if (act === 'loadD') return void loadScope('d');\n      if (act === 'loadW') return void loadScope('w');\n      if (act === 'loadM') return void loadScope('m');\n      if (act === 'cancelD') { if (aborts.d) aborts.d.abort(); return void d2.setState({ dRun: st.dRun + 1, dLoading: false, dProg: EMPTY_PROG }); }\n      if (act === 'cancelW') { if (aborts.w) aborts.w.abort(); return void d2.setState({ wRun: st.wRun + 1, wLoading: false, wProg: EMPTY_PROG }); }\n      if (act === 'cancelM') { if (aborts.m) aborts.m.abort(); return void d2.setState({ mRun: st.mRun + 1, mLoading: false, mProg: EMPTY_PROG }); }\n      if (act === 'pdf') {\n        // Nunca imprimir com busca em voo: o estado de carregamento de um drill é renderizado DENTRO\n        // da tabela (fora do .noprint), então o PDF sairia com 'buscando o detalhe por recurso…'\n        // impresso no lugar dos números — e este relatório vai para fora.\n        const emVoo = st.dLoading || st.wLoading || st.mLoading\n          || ['dDet', 'wDet', 'mDet'].some((dk) => Object.keys(st[dk] || {})\n            .some((k) => st[dk][k] && st[dk][k].__loading));\n        if (emVoo) return void d2.setState({ pdfWarn: 1 });\n        // carimba a hora, deixa o render sair, e só então abre o diálogo — senão o cabeçalho de\n        // impressão iria ao papel sem a data, porque setState re-renderiza em lote.\n        d2.setState({ printedAt: new Date().toLocaleString('pt-BR'), pdfWarn: '' });\n        setTimeout(() => { try { window.print(); } catch (err) { d2.log('print falhou', err); } }, 150);\n        return;\n      }\n      if (act === 'theme') return void d2.setState({ theme: st.theme === 'dark' ? 'light' : 'dark' });\n      if (act === 'sort') return void d2.setState({ sort: t.dataset.v });\n      if (act === 'addweek') {\n        return void (st.wCount >= WEEKS_MAX\n          ? d2.setState({ wWarn: 'max' })\n          : d2.setState({ wCount: st.wCount + 1, wWarn: '' }));\n      }\n      if (act === 'rmweek') {\n        return void (st.wCount <= WEEKS_MIN\n          ? d2.setState({ wWarn: 'min' })\n          : d2.setState({ wCount: st.wCount - 1, wWarn: '' }));\n      }\n      if (act === 'addmonth') {\n        return void (st.mCount >= MONTHS_MAX\n          ? d2.setState({ mWarn: 'max' })\n          : d2.setState({ mCount: st.mCount + 1, mWarn: '' }));\n      }\n      if (act === 'rmmonth') {\n        return void (st.mCount <= MONTHS_MIN\n          ? d2.setState({ mWarn: 'min' })\n          : d2.setState({ mCount: st.mCount - 1, mWarn: '' }));\n      }\n      if (act === 'allocinc' || act === 'allocdec') {\n        const kk = t.dataset.k;\n        // a chave do período mensal é 'M' + d0, então slice(1) devolve a data do início do mês\n        const atual = st.mAlloc[kk] === undefined ? allocDefault(kk.slice(1)) : st.mAlloc[kk];\n        const novo = Math.max(0, Math.min(ALLOC_MAX, atual + (act === 'allocinc' ? 1 : -1)));\n        return void d2.setState({ mAlloc: Object.assign({}, st.mAlloc, { [kk]: novo }) });\n      }\n      if (act === 'addday') {\n        if (st.days.length >= MAX_DAYS) return;\n        const nd = addDays(st.days[st.days.length - 1], 1);\n        return void d2.setState({ days: st.days.concat([st.days.includes(nd) || nd > yesterday() ? yesterday() : nd]) });\n      }\n      if (act === 'rmday') return void d2.setState({ days: st.days.filter((_, k) => k !== Number(t.dataset.i)) });\n      if (act === 'toggle') {\n        const sc = t.dataset.scope, k = t.dataset.k;\n        const cur = st[K(sc, 'Open')] || {};\n        const next = Object.assign({}, cur); next[k] = !cur[k];\n        return void d2.setState(setScope(sc, { Open: next }));\n      }\n      if (act === 'drill') return void drill(t.dataset.scope, t.dataset.p, t.dataset.e);\n    });\n\n    d2.on('[data-act]', 'change', (ev, el) => {\n      const t = el || (ev.target && ev.target.closest && ev.target.closest('[data-act]'));\n      if (!t) return;\n      const st = viewState(d2);\n      if (t.dataset.act === 'setday') {\n        const days = st.days.slice(); days[Number(t.dataset.i)] = t.value;\n        d2.setState({ days });\n      }\n      if (t.dataset.act === 'setwend') d2.setState({ wEnd: t.value, wWarn: '' });\n      if (t.dataset.act === 'setmend') d2.setState({ mEnd: t.value, mWarn: '' });\n      if (t.dataset.act === 'allocset') {\n        const n = Math.max(0, Math.min(ALLOC_MAX, Math.round(Number(t.value) || 0)));\n        d2.setState({ mAlloc: Object.assign({}, st.mAlloc, { [t.dataset.k]: n }) });\n      }\n      if (t.dataset.act === 'setfx') { const v = Number(t.value); d2.setState({ fx: v > 0 ? v : FX_DEFAULT }); }\n      if (t.dataset.act === 'mincost') d2.setState({ minCost: Number(t.value) || 0 });\n    });\n  }\n};\n/*C1*/\n\n\n\n\n\n"}},"listenerRef":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"listenerRef"}}}},"defaultDays":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"defaultDays"}}}}}}}}}},{"_id":"6a8c5b7905e12b46422da308","component":"data2-core-types@Component","system":"67850da249571825a6d31832","params":{"extends":"data2-core-primitives@Block","component":"ZZProbe","package":"lucas-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"export default {\n  css: `.wrap{display:flex;flex-direction:column;gap:12px;align-items:flex-start;justify-content:center;height:100%;padding:32px;font:16px/1.5 system-ui,sans-serif;background:#0f172a;color:#e2e8f0}\n        .t{font-size:28px;font-weight:700;color:#38bdf8}\n        .b{padding:8px 16px;border:0;border-radius:8px;background:#38bdf8;color:#0f172a;font-weight:600;cursor:pointer}`,\n  render(d2){\n    const n = d2.state.n || 0\n    return `<div class=\"wrap\" data-loaded>\n      <div class=\"t\">probe ok</div>\n      <div>etiqueta: ${String(d2.param('etiqueta','(sem valor)'))}</div>\n      <div>contador: <b class=\"n\">${n}</b></div>\n      <button class=\"b\">somar</button>\n    </div>`\n  },\n  mounted(d2){\n    d2.on('.b','click',()=>{ d2.state.n = (d2.state.n||0)+1 })\n  },\n}\n"}},"etiqueta":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"etiqueta"}}}}}}}}}},{"_id":"6a8c5c542fc601cd4a2c374c","component":"data2-core-types@Component","system":"67850da249571825a6d31832","params":{"extends":"data2-core-primitives@Block","component":"FaqOperadorV2","package":"lucas-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"// FaqOperadorV2 — NASVI operator FAQ copilot, single code component.\n// demo:true  -> embedded mock data (playground validation, no backend, no AI cost)\n// demo:false -> real path: d2.data('faqs').filter+refresh, then d2.assistant().ask({context})\n\nconst MOCK_USER = { name: 'Ana Gomez', email: 'ana.gomez@natura.net', countries: ['AR', 'MX'], user_type: ['Standard'], role: 'agent' }\nconst MOCK_REGIONS = ['AR', 'MX', 'CO', 'PE', 'CL', 'EC']\nconst MOCK_FAQS = [\n  { _id: 'm1', title: 'Puntos de la consultora no actualizados', article: '10231', d2_search_score: 0.87, category: 'MODELO_COMERCIAL', content: 'Si la consultora tiene apenas 1 punto, debe actualizar su registro. Esto ocurre por alguna inconsistencia en su dirección; después de actualizar sus datos sus puntos deberían restablecerse en hasta 24 horas.' },\n  { _id: 'm2', title: 'Pedido retenido por límite de crédito', article: '10884', d2_search_score: 0.74, category: 'PEDIDOS', content: 'Si el pedido queda retenido por exceder el límite de crédito, la consultora deberá ajustar el puntaje del pedido según el crédito disponible o pagar pedidos pendientes para liberar crédito.' },\n  { _id: 'm3', title: 'Unificación ELO Natura y Avon', article: '11002', d2_search_score: 0.66, category: 'MODELO_COMERCIAL', content: 'Con el ELO México, Natura y Avon se unificaron. Los ciclos, el catálogo y la tabla de puntos pasan a ser únicos. Ante conflicto de información, siempre prevalece el contenido que habla específicamente del ELO.' },\n  { _id: 'm4', title: 'Dejar de vender / baja de consultora', article: '10077', d2_search_score: 0.52, category: 'MODELO_COMERCIAL', content: 'Para darse de baja como Consultora de Belleza Natura debe enviar un correo a atencion_consultor@natura.net adjuntando identificación oficial vigente por ambos lados y una carta con el motivo.' },\n  { _id: 'm5', title: 'Plazos de entrega por región', article: '10455', d2_search_score: 0.41, category: 'PEDIDOS', content: 'Los plazos de entrega varían por región. Capital y GBA: 3 a 5 días hábiles. Interior: 5 a 8 días hábiles contados desde la facturación del pedido.' }\n]\nconst MOCK_HISTORY = [\n  { _id: 'h1', pergunta: '¿Cómo actualizo la dirección de una consultora?', resposta: 'Querido Asesor, para actualizar la dirección ingresá en el panel de registro, sección *Datos personales*, y editá el campo Domicilio. El cambio impacta el próximo ciclo.', createdAt: Date.now() - 1000 * 60 * 18 },\n  { _id: 'h2', pergunta: '¿Cuántos días demora un reembolso?', resposta: 'Estimado asesor, el reembolso se procesa en hasta **10 días hábiles** después de aprobada la solicitud.', createdAt: Date.now() - 1000 * 60 * 95 },\n  { _id: 'h3', pergunta: '¿Qué pasa si el pedido llega incompleto?', resposta: 'Querido Asesor, se debe abrir un reclamo de falta de producto adjuntando el número de pedido y la foto del remito.', createdAt: Date.now() - 1000 * 60 * 60 * 26 }\n]\nconst MOCK_ANSWER = 'Querido Asesor,\\n\\nSi la consultora visualiza **apenas 1 punto**, casi siempre se debe a una **inconsistencia en su dirección**.\\n\\nPasos a seguir:\\n\\n1. Pedíle que ingrese a *Mi registro* y revise el domicilio completo.\\n2. Que corrija calle, número y código postal.\\n3. Guardar los cambios.\\n\\nDespués de actualizar los datos, **sus puntos deberían restablecerse** automáticamente.\\n\\n> Si pasadas 24 horas el puntaje sigue igual, abrí un ticket para el área comercial.'\n\nconst HELP_MD = 'Soy **NASVI**\\n\\nTu nuevo **copiloto virtual**, listo para acompañarte en cada contacto con nuestras consultoras.\\n\\nEstoy aquí para hacer tu trabajo **más ágil, más seguro y más claro**.\\n\\n¿Cómo lo hago? Muy fácil:\\n\\n- Estoy entrenado con los procesos, protocolos y wikis actualizados de Natura y Avon.\\n- Cuando tengas una duda, yo te doy la respuesta en segundos, sin detener tu atención.\\n- Además, te llevo directo a la fuente oficial en Beedoo, para que siempre tengas información validada.\\n\\nMi misión es que puedas resolver más consultas en el primer contacto, sin errores, y con total confianza.'\n\nconst VOTE = {\n  1: ['No encontré nada útil', 'Sin respuesta o sin relevancia para la consulta'],\n  2: ['Encontré muy poca información', 'Respuesta incompleta o poco relevante'],\n  3: ['Encontré parte de la información', 'Resolvió parcialmente, se requiere buscar más'],\n  4: ['Encontré casi todo lo que buscaba', 'Útil en gran parte, pero con pequeños vacíos'],\n  5: ['Encontré exactamente lo que necesitaba', 'Respuesta clara, completa y satisfactoria']\n}\nconst ORIGENES = [['chat', 'Chat'], ['voz', 'Voz'], ['video', 'Video']]\nconst BEEDOO = { MX: 'https://naturamexico.beedoo.io/wiki/' }\nconst BEEDOO_DEFAULT = 'https://naturalatam.beedoo.io/wiki/'\n\nfunction esc(s) { return String(s == null ? '' : s).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;') }\nfunction attr(s) { return esc(s).replace(/\"/g, '&quot;') }\nfunction isDemo(d2) { return d2.param('demo') === true }\n\nfunction user(d2) {\n  if (isDemo(d2)) return MOCK_USER\n  const ds = d2.data('usuarios')\n  return (ds && ds.selected()) || {}\n}\nfunction isEcom(u) { return [].concat(u.user_type || []).indexOf('E-commerce') >= 0 }\nfunction solo(u) { return (u.countries || []).length === 1 }\nfunction regionCodes(d2) {\n  if (isDemo(d2)) return MOCK_REGIONS\n  const ds = d2.data('regiones')\n  return ds ? ds.records().map(function (r) { return r.country_code }).filter(Boolean) : []\n}\nfunction marketOptions(d2, u) { return isEcom(u) ? regionCodes(d2) : (u.countries || []) }\nfunction showSelector(d2, u) { return isEcom(u) || !solo(u) }\nfunction market(d2, u) {\n  if (!isEcom(u) && solo(u)) return u.countries[0]\n  return d2.state.region || marketOptions(d2, u)[0] || ''\n}\nfunction hits(d2) {\n  if (isDemo(d2)) return d2.state.hits || []\n  const ds = d2.data('faqs')\n  return ds ? ds.records() : []\n}\nfunction answerText(d2) {\n  if (isDemo(d2)) return d2.state.answer || ''\n  const a = d2.assistant(d2.params.assistant)\n  return (a && a.answer) || ''\n}\nfunction busy(d2) {\n  if (isDemo(d2)) return !!d2.state.busy\n  const a = d2.assistant(d2.params.assistant)\n  return !!(a && a.busy)\n}\nfunction history(d2) {\n  if (isDemo(d2)) return MOCK_HISTORY\n  const ds = d2.data('historial')\n  return ds ? ds.records() : []\n}\nfunction beedooUrl(mk, article) { return (BEEDOO[mk] || BEEDOO_DEFAULT) + String(article || '') + '/lll' }\n\nfunction card(d2, r, i) {\n  const score = typeof r.d2_search_score === 'number' ? (r.d2_search_score * 10).toFixed(1) : ''\n  const mk = market(d2, user(d2))\n  return '<article class=\"src\" data-key=\"' + attr(r._id || i) + '\">'\n    + '<header class=\"src-h\"><h3 class=\"src-t\">' + esc(r.title) + '</h3>'\n    + (score ? '<span class=\"src-s\">' + esc(score) + '</span>' : '') + '</header>'\n    + (r.category ? '<span class=\"src-c\">' + esc(r.category) + '</span>' : '')\n    + '<p class=\"src-b\">' + esc(r.content) + '</p>'\n    + (r.article ? '<a class=\"src-l\" href=\"' + attr(beedooUrl(mk, r.article)) + '\" target=\"_blank\" rel=\"noopener\" data-article=\"' + attr(r.article) + '\">contenido en Beedoo</a>' : '')\n    + '</article>'\n}\n\nexport default {\n  css: '*,*::before,*::after{box-sizing:border-box}'\n    + ':host{all:initial}'\n    + '.app{--cream:rgb(254,251,244);--ink:#162b37;--ink2:rgba(22,43,55,.62);--line:#e3ddd2;--olive:rgb(230,238,189);--ok:rgb(125,230,28);--off:rgb(200,46,0);--accent:var(--acc,#FF6C0E);display:grid;grid-template-rows:auto 1fr auto;height:100%;width:100%;background:var(--cream);color:var(--ink);font:14px/1.55 \"Open Sans\",system-ui,-apple-system,\"Segoe UI\",Roboto,sans-serif;position:relative;overflow:hidden}'\n    + '.hd{display:flex;align-items:center;gap:18px;padding:14px 22px;border-bottom:1px solid var(--line);background:#fff}'\n    + '.brand{display:flex;flex-direction:column;line-height:1.15;margin-right:6px}'\n    + '.brand b{font-size:22px;font-weight:700;letter-spacing:.5px}'\n    + '.brand span{font-size:12px;color:var(--ink2)}'\n    + '.chips{display:flex;gap:6px}'\n    + '.chip{flex:none;border:0;border-radius:16px;padding:6px 14px;font:600 12px/1 inherit;color:#fff;background:var(--off);cursor:pointer;opacity:.55;transition:opacity .15s}'\n    + '.chip[aria-pressed=\"true\"]{background:var(--ok);color:var(--ink);opacity:1}'\n    + '.spacer{flex:1}'\n    + '.mk{display:flex;align-items:center;gap:7px;font-size:12px;color:var(--ink2)}'\n    + '.mk select{font:inherit;padding:5px 8px;border:1px solid var(--line);border-radius:7px;background:#fff;color:var(--ink)}'\n    + '.lock{flex:none;border:1px solid var(--line);border-radius:7px;padding:5px 10px;font-weight:700;background:#faf6ef}'\n    + '.who{font-size:12px;color:var(--ink2);text-align:right;line-height:1.3}'\n    + '.who b{display:block;color:var(--ink);font-size:13px}'\n    + '.ico{flex:none;width:34px;height:34px;border-radius:50%;border:1px solid var(--line);background:#fff;color:var(--ink);cursor:pointer;font:700 15px/1 inherit;display:grid;place-items:center}'\n    + '.ico:hover{border-color:var(--accent);color:var(--accent)}'\n    + '.main{display:grid;grid-template-columns:1fr 372px;min-height:0}'\n    + '.left{display:flex;flex-direction:column;min-height:0;padding:20px 22px;gap:14px}'\n    + '.ask label{display:block;font-weight:600;margin-bottom:6px}'\n    + '.q{width:100%;height:96px;resize:none;padding:12px 14px;border:1px solid var(--line);border-radius:10px;background:#fff;color:var(--ink);font:inherit}'\n    + '.q:focus{outline:2px solid var(--accent);outline-offset:-1px}'\n    + '.ask-r{display:flex;align-items:center;gap:12px;margin-top:8px}'\n    + '.hint{font-size:12px;color:var(--ink2)}'\n    + '.send{flex:none;margin-left:auto;border:0;border-radius:8px;padding:10px 22px;background:var(--ink);color:#fff;font:600 14px/1 inherit;cursor:pointer}'\n    + '.send:disabled{opacity:.4;cursor:default}'\n    + '.log{flex:1;min-height:0;overflow:auto;display:flex;flex-direction:column;gap:12px;padding-right:4px}'\n    + '.you{align-self:flex-end;max-width:82%;background:#fff;border:1px solid var(--line);border-radius:12px 12px 2px 12px;padding:10px 14px}'\n    + '.bot{display:flex;gap:10px;max-width:94%}'\n    + '.av{width:34px;height:34px;flex:none;border-radius:50%;background:var(--ink);color:#fff;display:grid;place-items:center;font:700 13px/1 inherit}'\n    + '.bub{background:var(--olive);border-radius:2px 16px 16px 16px;padding:12px 16px;min-width:0}'\n    + '.bub p{margin:0 0 8px}.bub p:last-child{margin:0}.bub ul,.bub ol{margin:6px 0;padding-left:20px}'\n    + '.bub h1,.bub h2,.bub h3{font-size:15px;margin:8px 0 4px}.bub code{background:rgba(0,0,0,.07);padding:1px 5px;border-radius:4px}'\n    + '.bub blockquote{margin:8px 0;padding-left:10px;border-left:3px solid rgba(22,43,55,.25);color:var(--ink2)}'\n    + '.cur{display:inline-block;width:7px;height:15px;background:var(--ink);vertical-align:-2px;animation:bl .9s steps(2) infinite}'\n    + '@keyframes bl{50%{opacity:0}}'\n    + '.acts{display:flex;gap:8px;margin-top:10px}'\n    + '.act{border:1px solid rgba(22,43,55,.22);background:rgba(255,255,255,.6);border-radius:7px;padding:5px 11px;font:600 12px/1.4 inherit;color:var(--ink);cursor:pointer}'\n    + '.act:hover{border-color:var(--ink)}'\n    + '.empty{margin:auto;text-align:center;color:var(--ink2);max-width:300px;font-size:13px}'\n    + '.empty b{display:block;margin-bottom:8px;opacity:.3}.empty svg{width:34px;height:34px;stroke:currentColor;fill:none;stroke-width:1.6}'\n    + '.err{background:#fff0ef;border:1px solid rgba(255,60,51,.45);color:#b3261e;border-radius:9px;padding:9px 12px;font-size:13px}'\n    + '.right{border-left:1px solid var(--line);background:#fffdf9;display:flex;flex-direction:column;min-height:0}'\n    + '.right h2{margin:0;padding:16px 18px 10px;font-size:11px;letter-spacing:1.3px;text-transform:uppercase;color:var(--ink2)}'\n    + '.srcs{flex:1;min-height:0;overflow:auto;padding:0 16px 16px;display:flex;flex-direction:column;gap:10px}'\n    + '.src{background:#fff;border:1px solid var(--line);border-radius:14px;padding:12px 14px}'\n    + '.src-h{display:flex;gap:10px;align-items:flex-start}'\n    + '.src-t{flex:1;margin:0;font-size:13.5px;font-weight:700;line-height:1.35}'\n    + '.src-s{font-size:19px;font-weight:700;color:var(--accent);line-height:1}'\n    + '.src-c{display:inline-block;margin-top:6px;font-size:10px;letter-spacing:.6px;background:#f2ede4;border-radius:5px;padding:2px 7px;color:var(--ink2)}'\n    + '.src-b{margin:8px 0 0;font-size:12.5px;color:var(--ink2);max-height:76px;overflow:hidden}'\n    + '.src-l{display:inline-block;margin-top:9px;font-size:12px;font-weight:600;color:var(--accent);text-decoration:underline}'\n    + '.ft{display:flex;align-items:center;gap:16px;padding:10px 22px;border-top:1px solid var(--line);background:#fff;font-size:12px;color:var(--ink2)}'\n    + '.hist{flex:none;margin-left:auto;border:1px solid var(--line);background:#fff;border-radius:8px;padding:7px 14px;font:600 12px/1 inherit;color:var(--ink);cursor:pointer}'\n    + '.hist:hover{border-color:var(--accent);color:var(--accent)}'\n    + '.scrim{position:absolute;inset:0;background:rgba(0,0,0,.44);backdrop-filter:blur(2px);display:grid;place-items:center;z-index:9}'\n    + '.dlg{background:var(--cream);border-radius:20px;box-shadow:0 18px 50px rgba(0,0,0,.28);position:relative;max-width:92%;max-height:88%;display:flex;flex-direction:column}'\n    + '.dlg-h{display:flex;align-items:center;padding:22px 24px 12px}'\n    + '.dlg-h h2{margin:0;font-size:21px;font-weight:700}'\n    + '.x{margin-left:auto;border:0;background:transparent;font:700 20px/1 inherit;color:var(--ink);cursor:pointer;padding:2px 4px}'\n    + '.dlg-b{padding:0 24px 24px;overflow:auto;min-height:0}'\n    + '.help{width:660px}'\n    + '.hist-w{width:1000px;height:78%;display:grid;grid-template-columns:290px 1fr;gap:18px;overflow:hidden}'\n    + '.hlist{overflow:auto;background:#fff;border:1px solid var(--line);border-radius:12px}'\n    + '.hitem{display:block;width:100%;text-align:left;border:0;border-bottom:1px solid var(--line);background:transparent;padding:11px 13px;cursor:pointer;font:inherit;color:var(--ink)}'\n    + '.hitem:hover{background:#faf6ef}'\n    + '.hitem[aria-selected=\"true\"]{background:var(--olive)}'\n    + '.hitem b{display:block;font-size:12.5px;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}'\n    + '.hitem span{font-size:11px;color:var(--ink2)}'\n    + '.hdet{overflow:auto;padding-right:6px;display:flex;flex-direction:column;gap:12px}'\n    + '.vote{width:700px}'\n    + '.scale{display:flex;gap:11px;margin:4px 0 12px}'\n    + '.dot{flex:none;width:42px;height:42px;border-radius:50%;border:1px solid rgba(22,43,55,.35);background:#fff;color:var(--ink);font:700 17px/1 inherit;cursor:pointer}'\n    + '.dot[aria-pressed=\"true\"]{background:var(--ink);color:#fff}'\n    + '.vdesc{min-height:38px;font-size:13px;color:var(--ink2);white-space:pre-line}'\n    + '.vin{width:100%;padding:10px 12px;border:1px solid var(--line);border-radius:9px;font:inherit;background:#fff;color:var(--ink)}'\n    + '.vrow{display:flex;align-items:center;gap:12px;margin-top:14px}'\n    + '.vrow .send{margin-left:auto}'\n    + '.tag{font-size:11px;border:1px dashed rgba(22,43,55,.35);border-radius:6px;padding:2px 7px;color:var(--ink2)}',\n\n  render(d2) {\n    const u = user(d2)\n    const mk = market(d2, u)\n    const opts = marketOptions(d2, u)\n    const hs = hits(d2)\n    const ans = answerText(d2)\n    const bz = busy(d2)\n    const marked = d2.lib('marked@12.0.0')\n    const md = function (t) {\n      if (!t) return ''\n      if (!marked) return '<p>' + esc(t).replace(/\\n/g, '<br>') + '</p>'\n      try { return marked.parse(t) } catch (e) { return '<p>' + esc(t) + '</p>' }\n    }\n    const acc = d2.param('accent', '#FF6C0E')\n\n    const selector = showSelector(d2, u)\n      ? '<select class=\"sel\">' + opts.map(function (c) { return '<option value=\"' + attr(c) + '\"' + (c === mk ? ' selected' : '') + '>' + esc(c) + '</option>' }).join('') + '</select>'\n      : '<span class=\"lock\" title=\"Tu usuario está asignado a un solo mercado\">' + esc(mk || '--') + '</span>'\n\n    const conversa = (!d2.state.pregunta && !ans)\n      ? '<div class=\"empty\"><b><svg viewBox=\"0 0 24 24\"><path d=\"M21 12a8 8 0 0 1-8 8H7l-4 3v-5a8 8 0 0 1 8-11h2a8 8 0 0 1 8 5z\" stroke-linejoin=\"round\"/></svg></b>Escribí la duda del cliente y NASVI busca en las wikis por vos.</div>'\n      : (d2.state.pregunta ? '<div class=\"you\">' + esc(d2.state.pregunta) + '</div>' : '')\n        + ((ans || bz)\n          ? '<div class=\"bot\"><div class=\"av\">N</div><div><div class=\"bub\">' + md(ans) + (bz ? '<span class=\"cur\"></span>' : '') + '</div>'\n            + (!bz && ans ? '<div class=\"acts\"><button class=\"act copy\">Copiar</button><button class=\"act vote\">Votar</button></div>' : '')\n            + '</div></div>'\n          : '')\n\n    const fuentes = hs.length\n      ? hs.map(function (r, i) { return card(d2, r, i) }).join('')\n      : '<div class=\"empty\"><b><svg viewBox=\"0 0 24 24\"><path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z\" stroke-linejoin=\"round\"/><path d=\"M14 3v5h5M9 13h6M9 17h4\" stroke-linecap=\"round\"/></svg></b>Realiza tu consulta para ver las wikis relacionadas aquí.</div>'\n\n    let overlay = ''\n    if (d2.state.panel === 'help') {\n      overlay = '<div class=\"scrim\" data-close><div class=\"dlg help\"><div class=\"dlg-h\"><h2>NASVI: El Agente del Agente</h2><button class=\"x\">&#215;</button></div><div class=\"dlg-b bub\" style=\"background:transparent;padding:0 24px 24px\">' + md(HELP_MD) + '</div></div></div>'\n    } else if (d2.state.panel === 'hist') {\n      const rows = history(d2)\n      const sel = d2.state.hsel || (rows[0] && (rows[0]._id || 0))\n      const cur = rows.filter(function (r, i) { return (r._id || i) === sel })[0] || rows[0]\n      overlay = '<div class=\"scrim\" data-close><div class=\"dlg hist-w\"><div class=\"dlg-h\" style=\"grid-column:1/-1\"><h2>Historial</h2><button class=\"x\">&#215;</button></div>'\n        + '<div class=\"hlist\">' + (rows.length ? rows.map(function (r, i) {\n          const id = r._id || i\n          return '<button class=\"hitem\" data-key=\"' + attr(id) + '\" data-h=\"' + attr(id) + '\" aria-selected=\"' + (id === sel ? 'true' : 'false') + '\"><b>' + esc(r.pergunta) + '</b><span>' + esc(r.createdAt ? d2.fmt.relative(r.createdAt) : '') + '</span></button>'\n        }).join('') : '<div class=\"empty\" style=\"padding:20px\">Sin consultas todavía.</div>') + '</div>'\n        + '<div class=\"hdet\">' + (cur ? '<div class=\"you\" style=\"align-self:flex-start;max-width:100%\">' + esc(cur.pergunta) + '</div><div class=\"bot\"><div class=\"av\">N</div><div class=\"bub\">' + md(cur.resposta) + '</div></div>' : '') + '</div>'\n        + '</div></div>'\n    } else if (d2.state.panel === 'vote') {\n      const g = d2.state.grade || 0\n      const lab = VOTE[g]\n      overlay = '<div class=\"scrim\" data-close><div class=\"dlg vote\"><div class=\"dlg-h\"><h2>¿Qué tan útil fue la respuesta?</h2><button class=\"x\">&#215;</button></div><div class=\"dlg-b\">'\n        + '<div class=\"scale\">' + [1, 2, 3, 4, 5].map(function (n) { return '<button class=\"dot\" data-key=\"' + n + '\" data-g=\"' + n + '\" aria-pressed=\"' + (n === g ? 'true' : 'false') + '\">' + n + '</button>' }).join('') + '</div>'\n        + '<div class=\"vdesc\">' + (lab ? esc(lab[0]) + '\\n' + esc(lab[1]) : '') + '</div>'\n        + '<input class=\"vin\" placeholder=\"Comentarios (opcional)\" value=\"' + attr(d2.state.vcomment || '') + '\"/>'\n        + '<div class=\"vrow\">' + (d2.param('telemetry') ? '' : '<span class=\"tag\">telemetría desactivada — no se guarda</span>') + '<button class=\"send vsend\"' + (g ? '' : ' disabled') + '>Enviar</button></div>'\n        + '</div></div></div>'\n    }\n\n    return '<div class=\"app\" data-ready style=\"--acc:' + attr(acc) + '\">'\n      + '<header class=\"hd\">'\n      + '<div class=\"brand\"><b>NASVI</b><span>Copiloto activo</span></div>'\n      + '<div class=\"chips\">' + ORIGENES.map(function (o) { return '<button class=\"chip\" data-o=\"' + o[0] + '\" aria-pressed=\"' + ((d2.state.origen || 'chat') === o[0] ? 'true' : 'false') + '\">' + o[1] + '</button>' }).join('') + '</div>'\n      + '<div class=\"spacer\"></div>'\n      + '<div class=\"mk\"><span>Mercado</span>' + selector + '</div>'\n      + '<div class=\"who\"><b>' + esc(u.name || 'Asesor') + '</b>' + esc(u.email || '') + '</div>'\n      + '<button class=\"ico help\" title=\"Ayuda\">?</button>'\n      + '</header>'\n      + '<div class=\"main\">'\n      + '<section class=\"left\">'\n      + '<div class=\"ask\"><label for=\"q\">¿Cuál es la pregunta del cliente?</label>'\n      + '<textarea class=\"q\" id=\"q\" placeholder=\"Escribí la duda tal como te la hizo la consultora…\"' + (bz ? ' disabled' : '') + '></textarea>'\n      + '<div class=\"ask-r\"><span class=\"hint\">Enter envía &middot; Shift+Enter salta línea</span>'\n      + '<button class=\"send go\"' + (bz ? ' disabled' : '') + '>' + (bz ? 'Buscando…' : 'Enviar pregunta') + '</button></div></div>'\n      + (d2.state.err ? '<div class=\"err\">' + esc(d2.state.err) + '</div>' : '')\n      + '<div class=\"log\">' + conversa + '</div>'\n      + '</section>'\n      + '<aside class=\"right\"><h2>Fuentes</h2><div class=\"srcs\">' + fuentes + '</div></aside>'\n      + '</div>'\n      + '<footer class=\"ft\">'\n      + '<span>' + (d2.state.duracion ? (d2.state.duracion / 1000).toFixed(1) + ' s' : '--') + '</span>'\n      + '<span>' + hs.length + ' fuentes</span>'\n      + '<span>Mercado ' + esc(mk || '--') + '</span>'\n      + (isDemo(d2) ? '<span class=\"tag\">demo</span>' : '')\n      + (d2.param('telemetry') ? '' : '<span class=\"tag\">telemetría off</span>')\n      + '<button class=\"hist\">Historial</button>'\n      + '</footer>'\n      + overlay\n      + '</div>'\n  },\n\n  mounted(d2) {\n    const ask = async function () {\n      const el = d2.$('.q')\n      if (!el) return\n      const q = (el.value || '').trim()\n      if (!q) return\n      const t0 = Date.now()\n      el.value = ''\n      d2.setState({ pregunta: q, err: '', duracion: 0, grade: 0, vcomment: '' })\n      if (isDemo(d2)) { await demo(d2, q, t0); return }\n      try {\n        const u = user(d2)\n        const ds = d2.data('faqs')\n        if (!ds) throw new Error('Parámetro \"faqs\" no está conectado a un dataset.')\n        ds.filter({ ecommerce: isEcom(u) ? true : { nin: [true] }, busca: q, country: market(d2, u) })\n        await ds.refresh()\n        const rows = ds.records()\n        d2.setState({ hits: rows })\n        await d2.assistant(d2.params.assistant).ask('Operador Pergunta :  \\n\\n\"' + q + '\"\\n\\nContesta en espanol', { context: JSON.stringify(rows) })\n        d2.state.duracion = Date.now() - t0\n        if (d2.param('telemetry')) await persist(d2, q)\n      } catch (e) {\n        d2.state.err = 'No se pudo completar la búsqueda: ' + String((e && e.message) || e)\n      }\n    }\n\n    const demo = async function (d2, q, t0) {\n      d2.setState({ busy: true, answer: '', hits: [] })\n      await new Promise(function (r) { setTimeout(r, 450) })\n      d2.setState({ hits: MOCK_FAQS })\n      let i = 0\n      await new Promise(function (done) {\n        const id = setInterval(function () {\n          i += 4\n          d2.state.answer = MOCK_ANSWER.slice(0, i)\n          if (i >= MOCK_ANSWER.length) { clearInterval(id); done() }\n        }, 16)\n        d2.onUnmount(function () { clearInterval(id) })\n      })\n      d2.setState({ busy: false, duracion: Date.now() - t0 })\n    }\n\n    const persist = async function (d2, q) {\n      const u = user(d2)\n      const mon = d2.data('historial')\n      if (mon) await mon.create({\n        email: u.email, name: u.name, pergunta: q, resposta: answerText(d2),\n        country: market(d2, u), origen: d2.state.origen || 'chat',\n        duracion: d2.state.duracion, user_type: isEcom(u) ? 'ecommerce' : undefined\n      })\n      const ev = d2.data('eventos')\n      if (ev) await ev.create({ event: 'assistant_ask', email: u.email, nome: u.name, country: market(d2, u), payload: { article: (hits(d2)[0] || {}).article } })\n    }\n\n    d2.on('.go', 'click', ask)\n    d2.on('.q', 'keydown', function (e) {\n      if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); ask() }\n    })\n    d2.on('.chip', 'click', function (e, el) { d2.state.origen = el.dataset.o })\n    d2.on('.sel', 'change', function (e, el) { d2.state.region = el.value })\n    d2.on('.help', 'click', function () { d2.state.panel = 'help' })\n    d2.on('.hist', 'click', function () { d2.state.panel = 'hist' })\n    d2.on('.vote', 'click', function () { d2.setState({ panel: 'vote', grade: 0, vcomment: '' }) })\n    d2.on('.x', 'click', function () { d2.state.panel = null })\n    d2.on('.scrim', 'click', function (e, el) { if (e.target === el) d2.state.panel = null })\n    d2.on('.hitem', 'click', function (e, el) { d2.state.hsel = el.dataset.h })\n    d2.on('.dot', 'click', function (e, el) { d2.state.grade = Number(el.dataset.g) })\n    d2.on('.vin', 'input', function (e, el) { d2.state.vcomment = el.value })\n    d2.on('.src-l', 'click', function (e, el) {\n      if (!d2.param('telemetry')) return\n      const ev = d2.data('eventos')\n      const u = user(d2)\n      if (ev) ev.create({ event: 'wiki_view', email: u.email, nome: u.name, country: market(d2, u), payload: { article: el.dataset.article } })\n    })\n    d2.on('.vsend', 'click', async function () {\n      const g = d2.state.grade\n      if (!g) return\n      if (d2.param('telemetry')) {\n        const u = user(d2)\n        const ev = d2.data('eventos')\n        const payload = { message: d2.state.pregunta, answer: answerText(d2), grade: g, comment: d2.state.vcomment || '' }\n        if (ev) {\n          await ev.create({ event: 'voting', email: u.email, nome: u.name, country: market(d2, u), payload: payload })\n          if (g === 1) await ev.create({ event: 'answer_not_found', email: u.email, nome: u.name, country: market(d2, u), payload: payload })\n        }\n        const enc = d2.data('encuestas')\n        if (enc) await enc.create({ country: market(d2, u), email: u.email, reaction: g >= 4 ? 'like' : 'dislike', comments: d2.state.vcomment || '' })\n      }\n      d2.setState({ panel: null, voted: g })\n    })\n    d2.on('.copy', 'click', function (e, el) {\n      const t = answerText(d2)\n      if (!t) return\n      try { navigator.clipboard.writeText(t) } catch (err) { }\n      el.textContent = 'Copiado'\n      setTimeout(function () { try { el.textContent = 'Copiar' } catch (e2) { } }, 1400)\n    })\n    d2.on(document, 'keydown', function (e) { if (e.key === 'Escape' && d2.state.panel) d2.state.panel = null })\n  },\n\n  updated(d2) {\n    const log = d2.$('.log')\n    if (log) log.scrollTop = log.scrollHeight\n  }\n}\n"}},"demo":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"demo"}}}},"telemetry":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"telemetry"}}}},"assistant":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"assistant"}}}},"faqs":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"faqs"}}}},"usuarios":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"usuarios"}}}},"regiones":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"regiones"}}}},"historial":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"historial"}}}},"eventos":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"eventos"}}}},"encuestas":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"encuestas"}}}},"estado":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"estado"}}}},"accent":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"accent"}}}}}}}}}},{"_id":"6ab029c576d35d65732ff420","component":"data2-core-types@Component","system":"67850da249571825a6d31832","params":{"extends":"data2-core-primitives@Block","component":"bellaSim","package":"lucas-playground","definition":{"preventEvaluation":true,"component":"data2-core-types@Definition","params":{"def":{"component":"data2-code-components@CodeHost","params":{"code":{"component":"data2-core-primitives@String","params":{"content":"/* Bella Sim — réplica de WhatsApp Web (80%) + móvil espejo (20%) */\n\nconst T = {\n  searchPh: 'Buscar un chat',\n  tabs: ['Todos', 'No leídos', 'Favoritos', 'Grupos'],\n  online: 'en línea',\n  typing: 'escribiendo…',\n  composerPh: 'Escribe un mensaje',\n  encrypted: 'Los mensajes están cifrados de extremo a extremo. Nadie fuera de este chat puede leerlos, ni siquiera nosotros.',\n  today: 'HOY',\n  emptyT: 'Aún no hay mensajes',\n  reply: 'Responder',\n  you: 'Tú',\n  recHint: 'Grabando…',\n  attPhotos: 'Fotos y vídeos',\n  attDoc: 'Documento',\n  dbgEmpty: 'Todavía no hay turnos. Envía un mensaje para ver la petición y la respuesta.',\n  noReply: 'No se pudo contactar a Bella.'\n}\nconst KL = { image: 'Foto', video: 'Vídeo', audio: 'Mensaje de voz', document: 'Documento', sticker: 'Sticker' }\n\nconst EMO = ['😀','😃','😄','😁','😆','😅','😂','🤣','😊','😇','🙂','🙃','😉','😌','😍','🥰','😘','😋','😎','🤓','🥳','🤔','😐','😴','😒','😞','😔','😟','🙁','😢','😭','😤','😠','🥺','😳','🤗','🤝','👍','👎','👏','🙏','💪','👋','❤️','🧡','💛','💚','💙','💜','🔥','✨','🎉','✅','❌','💯','🚀','👀','💬','📦','🛍️','💄','🌸','☀️','🌙']\nconst QUICK = ['👍','❤️','😂','😮','😢','🙏']\n\nconst sv = (p, w) => '<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"' + (w || 1.9) + '\" stroke-linecap=\"round\" stroke-linejoin=\"round\">' + p + '</svg>'\nconst IC = {\n  search: sv('<circle cx=\"11\" cy=\"11\" r=\"7\"/><path d=\"m20.5 20.5-3.7-3.7\"/>'),\n  menu: '<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><circle cx=\"12\" cy=\"5\" r=\"1.8\"/><circle cx=\"12\" cy=\"12\" r=\"1.8\"/><circle cx=\"12\" cy=\"19\" r=\"1.8\"/></svg>',\n  newchat: sv('<path d=\"M21 11.5a8.4 8.4 0 0 1-9 8.4 8.6 8.6 0 0 1-3.8-.9L3 20.5l1.6-4.9A8.4 8.4 0 1 1 21 11.5Z\"/><path d=\"M12 8.5v5M9.5 11h5\"/>'),\n  emoji: sv('<circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M8.5 14.5a4.5 4.5 0 0 0 7 0\"/><path d=\"M9 9.5h.01M15 9.5h.01\" stroke-width=\"2.6\"/>'),\n  clip: sv('<path d=\"M20 11.5 12.2 19.3a4.6 4.6 0 0 1-6.5-6.5l7.8-7.8a3.1 3.1 0 0 1 4.4 4.4l-7.8 7.8a1.5 1.5 0 0 1-2.2-2.2l7.2-7.2\"/>'),\n  mic: sv('<rect x=\"9\" y=\"2.5\" width=\"6\" height=\"11\" rx=\"3\"/><path d=\"M5.5 11a6.5 6.5 0 0 0 13 0\"/><path d=\"M12 17.5V21\"/>'),\n  send: '<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M2.2 21 23 12 2.2 3l.01 7L17 12 2.21 14z\"/></svg>',\n  x: sv('<path d=\"M18 6 6 18M6 6l12 12\"/>'),\n  down: sv('<path d=\"M12 4v12m0 0 4.5-4.5M12 16l-4.5-4.5\"/><path d=\"M4.5 19.5h15\"/>'),\n  play: '<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M7 4.5 19.5 12 7 19.5z\"/></svg>',\n  pause: '<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><rect x=\"6.5\" y=\"4.5\" width=\"4\" height=\"15\" rx=\"1\"/><rect x=\"13.5\" y=\"4.5\" width=\"4\" height=\"15\" rx=\"1\"/></svg>',\n  chev: sv('<path d=\"m6 9.5 6 6 6-6\"/>', 2.2),\n  trash: sv('<path d=\"M4 7h16M10 7V4.8h4V7M6.5 7l.9 12.2h9.2L17.5 7\"/>'),\n  back: sv('<path d=\"M19 12H5m0 0 6.5-6.5M5 12l6.5 6.5\"/>'),\n  phone: sv('<path d=\"M6.5 3.5h3l1.5 4-2 1.5a12 12 0 0 0 6 6L16.5 13l4 1.5v3a2 2 0 0 1-2.2 2A16.8 16.8 0 0 1 4.5 5.7a2 2 0 0 1 2-2.2Z\"/>'),\n  video: sv('<rect x=\"2.5\" y=\"6\" width=\"13\" height=\"12\" rx=\"2.5\"/><path d=\"m15.5 11 6-3.2v8.4l-6-3.2z\"/>'),\n  lock: sv('<rect x=\"4.5\" y=\"10.5\" width=\"15\" height=\"10\" rx=\"2.5\"/><path d=\"M8 10.5V7.8a4 4 0 0 1 8 0v2.7\"/>'),\n  image: sv('<rect x=\"3\" y=\"4.5\" width=\"18\" height=\"15\" rx=\"2.5\"/><circle cx=\"8.5\" cy=\"10\" r=\"1.7\"/><path d=\"m4 17 5-4.5 4.5 4L17 13l3 3\"/>'),\n  doc: sv('<path d=\"M14 3H7a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V8z\"/><path d=\"M14 3v5h5M9 13h6M9 17h4\"/>'),\n  reply: sv('<path d=\"M9.5 6.5 4 12l5.5 5.5\"/><path d=\"M4 12h9a7 7 0 0 1 7 7v1\"/>'),\n  smile: sv('<circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"M8.5 14.5a4.5 4.5 0 0 0 7 0\"/><path d=\"M9 9.5h.01M15 9.5h.01\" stroke-width=\"2.6\"/>'),\n  bug: sv('<rect x=\"7\" y=\"7\" width=\"10\" height=\"13\" rx=\"5\"/><path d=\"M9 6.5a3 3 0 0 1 6 0M3.5 11h3.5M17 11h3.5M3.5 17H7M17 17h3.5M12 7V4.5\"/>')\n}\nconst TICK = {\n  pending: '<svg viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.3\"><circle cx=\"8\" cy=\"8\" r=\"6\"/><path d=\"M8 4.8V8l2.2 1.4\"/></svg>',\n  sent: '<svg viewBox=\"0 0 16 15\" fill=\"currentColor\"><path d=\"M10.9 3.3 5.6 10 3 7.6l-.9 1 3.6 3.3 6.1-7.7z\"/></svg>',\n  two: '<svg viewBox=\"0 0 18 15\" fill=\"currentColor\"><path d=\"M12.9 3.3 7.6 10 5.9 8.4l-.9 1L7.6 12l6.2-7.7zM8.3 3.3 3 10 1.2 8.3l-.9 1L3 12l6.2-7.7z\"/></svg>'\n}\n\nconst esc = (s) => String(s == null ? '' : s).replace(/[&<>\"']/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '\"': '&quot;', \"'\": '&#39;' }[c]))\nconst hhmm = (ts) => { const d = new Date(ts); return String(d.getHours()).padStart(2, '0') + ':' + String(d.getMinutes()).padStart(2, '0') }\nconst mmss = (s) => Math.floor(s / 60) + ':' + String(Math.floor(s % 60)).padStart(2, '0')\nconst wait = (ms) => new Promise((r) => setTimeout(r, ms))\nconst uid = (p) => p + Date.now().toString(36) + Math.random().toString(36).slice(2, 6)\n\nfunction bars(id, n) {\n  let h = 0\n  for (let i = 0; i < id.length; i++) h = (h * 31 + id.charCodeAt(i)) >>> 0\n  const out = []\n  for (let i = 0; i < n; i++) { h = (h * 1103515245 + 12345) >>> 0; out.push(22 + (h % 78)) }\n  return out\n}\n\n/* ---- estado no reactivo (propiedad del DOM / del navegador) ---- */\nlet draft = ''\nlet stick = true\nlet audioEl = null\nlet rec = null\nlet recChunks = []\nlet recTimer = null\nlet recStart = 0\nlet SID = uid('s-')\nlet blobs = []\n\n/* ---------------- burbujas: UNA sola función, usada por los dos paneles ---------------- */\nfunction quoteHTML(q) {\n  if (!q) return ''\n  const label = q.mine ? T.you : esc(q.author || '')\n  const prev = q.kind === 'text' ? q.preview : (KL[q.kind] || '') + (q.preview ? ' · ' + q.preview : '')\n  return '<div class=\"quote ' + (q.mine ? 'qme' : 'qthem') + '\"><span class=\"qa\">' + label + '</span><span class=\"qt\">' + esc(prev) + '</span></div>'\n}\n\nfunction metaHTML(m) {\n  let t = ''\n  if (m.mine) {\n    if (m.status === 'pending') t = '<span class=\"tk\">' + TICK.pending + '</span>'\n    else if (m.status === 'sent') t = '<span class=\"tk\">' + TICK.sent + '</span>'\n    else if (m.status === 'delivered') t = '<span class=\"tk\">' + TICK.two + '</span>'\n    else if (m.status === 'read') t = '<span class=\"tk blue\">' + TICK.two + '</span>'\n  }\n  return '<span class=\"meta\"><span class=\"mt\">' + hhmm(m.ts) + '</span>' + t + '</span>'\n}\n\nfunction reactHTML(m) {\n  const ks = Object.keys(m.reactions || {})\n  if (!ks.length) return ''\n  return '<span class=\"reacts\">' + ks.map((k) => '<span>' + k + '</span>').join('') + '</span>'\n}\n\nfunction bodyHTML(m) {\n  const cap = m.body || m.caption || ''\n  const capH = cap ? '<div class=\"txt\">' + esc(cap) + '</div>' : ''\n  if (m.kind === 'image') return '<div class=\"media img\" data-open=\"' + esc(m.media) + '\" style=\"background-image:url(' + esc(m.media) + ')\"></div>' + capH\n  if (m.kind === 'sticker') return '<div class=\"media stk\" style=\"background-image:url(' + esc(m.media) + ')\"></div>'\n  if (m.kind === 'video') return '<div class=\"media vid\"><video src=\"' + esc(m.media) + '\" controls preload=\"metadata\"></video></div>' + capH\n  if (m.kind === 'document') return '<div class=\"docrow\"><span class=\"dic\">' + IC.doc + '</span><span class=\"dmeta\"><b>' + esc(m.fname || 'documento') + '</b><i>' + esc(m.fsize || '') + '</i></span><a class=\"ddl\" href=\"' + esc(m.media) + '\" download=\"' + esc(m.fname || 'archivo') + '\" title=\"Descargar\">' + IC.down + '</a></div>' + capH\n  if (m.kind === 'audio') {\n    const bb = bars(m.id, 34).map((h) => '<i style=\"height:' + Math.round(h * 0.26) + 'px\"></i>').join('')\n    return '<div class=\"aud\"><button class=\"apl\" data-play=\"' + esc(m.id) + '\" data-src=\"' + esc(m.media) + '\">' + IC.play + '</button><span class=\"awrap\"><span class=\"abars\" data-seek=\"' + esc(m.id) + '\">' + bb + '<span class=\"afill\" data-fill=\"' + esc(m.id) + '\"></span></span><span class=\"atime\" data-time=\"' + esc(m.id) + '\">' + mmss(m.durSec || 0) + '</span></span></div>'\n  }\n  if (m.kind === 'system') return '<div class=\"txt sys\">' + esc(cap) + '</div>'\n  return '<div class=\"txt\">' + esc(cap) + '</div>'\n}\n\nfunction bubbleHTML(m, st, name) {\n  if (m.kind === 'system') return '<div class=\"row sysrow\" data-key=\"' + esc(m.id) + '\"><div class=\"syschip\">' + esc(m.body) + '</div></div>'\n  const cls = ['bub', m.mine ? 'me' : 'them']\n  if (m.kind === 'sticker') cls.push('plain')\n  if (m.kind === 'image' || m.kind === 'video') cls.push('hasmedia')\n  const hasR = Object.keys(m.reactions || {}).length ? ' hasreact' : ''\n  const open = st && st.menuFor === m.id\n  const menu = open ? '<div class=\"bmenu\"><div class=\"qrow\">' + QUICK.map((e) => '<button class=\"qr\" data-react=\"' + esc(m.id) + '\" data-emo=\"' + e + '\">' + e + '</button>').join('') + '</div><button class=\"mitem\" data-replyto=\"' + esc(m.id) + '\">' + IC.reply + '<span>' + T.reply + '</span></button></div>' : ''\n  return '<div class=\"row ' + (m.mine ? 'rme' : 'rthem') + hasR + '\" data-key=\"' + esc(m.id) + '\" data-id=\"' + esc(m.id) + '\">' +\n    '<div class=\"bwrap\">' +\n      '<div class=\"' + cls.join(' ') + '\">' + quoteHTML(m.replyTo) + bodyHTML(m) + metaHTML(m) + reactHTML(m) + '</div>' +\n      '<button class=\"bmb\" data-menu=\"' + esc(m.id) + '\">' + IC.chev + '</button>' + menu +\n    '</div></div>'\n}\n\nfunction threadHTML(msgs, st, name) {\n  let out = '<div class=\"enc\">' + IC.lock + '<span>' + T.encrypted + '</span></div>'\n  if (!msgs.length) {\n    out += '<div class=\"empty\"><div class=\"eico\">' + IC.smile + '</div><b>' + T.emptyT + '</b><span>Escribe abajo para empezar a hablar con ' + esc(name) + '.</span></div>'\n    return out\n  }\n  out += '<div class=\"day\"><span>' + T.today + '</span></div>'\n  for (const m of msgs) out += bubbleHTML(m, st, name)\n  if (st.bellaTyping) out += '<div class=\"row rthem\" data-key=\"__typing\"><div class=\"bwrap\"><div class=\"bub them typing\"><i></i><i></i><i></i></div></div></div>'\n  return out\n}\n\n/* ---------------------------------- componente ---------------------------------- */\nexport default {\n  css: `\n:host{display:block;height:100%}\n*{box-sizing:border-box;margin:0;padding:0}\n.root{--wp:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='150' height='150'%3E%3Cg fill='none' stroke='%23ffffff' stroke-opacity='0.033' stroke-width='1.4'%3E%3Ccircle cx='24' cy='28' r='7'/%3E%3Cpath d='M62 20l10 10-10 10-10-10z'/%3E%3Cpath d='M104 24h18M104 32h11'/%3E%3Cpath d='M20 78c6-8 15-8 21 0'/%3E%3Ccircle cx='79' cy='84' r='9'/%3E%3Cpath d='M118 74l9 15h-18z'/%3E%3Cpath d='M32 118h19v13H32z'/%3E%3Cpath d='M75 124h15M75 131h9'/%3E%3Ccircle cx='124' cy='124' r='6'/%3E%3C/g%3E%3C/svg%3E\");display:flex;height:100%;min-height:520px;background:#0b141a;color:#e9edef;font-family:'Segoe UI',Helvetica,system-ui,-apple-system,sans-serif;font-size:14.2px;position:relative;overflow:hidden}\nbutton{font:inherit;color:inherit;background:none;border:0;cursor:pointer}\nsvg{width:100%;height:100%;display:block}\n.ib{width:38px;height:38px;border-radius:50%;display:grid;place-items:center;color:#aebac1;flex:0 0 auto}\n.ib>svg{width:21px;height:21px}\n.ib:hover{background:rgba(134,150,160,.12)}\n\n/* ---------- panel web (80%) ---------- */\n.web{flex:1 1 80%;display:flex;min-width:0;border-right:1px solid #0a1014}\n.side{flex:0 0 400px;max-width:44%;display:flex;flex-direction:column;background:#111b21;border-right:1px solid #222d34;min-width:0}\n.shead{height:59px;background:#202c33;display:flex;align-items:center;gap:6px;padding:0 16px;flex:0 0 auto}\n.av{border-radius:50%;background:#3b4a54 center/cover no-repeat;flex:0 0 auto}\n.shead .av{width:40px;height:40px}\n.meav{background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 40 40'%3E%3Crect width='40' height='40' fill='%236a7c85'/%3E%3Ccircle cx='20' cy='15' r='7' fill='%23cfd8dc'/%3E%3Cpath d='M6 40c0-8 6.5-12 14-12s14 4 14 12z' fill='%23cfd8dc'/%3E%3C/svg%3E\")}\n.sp{flex:1}\n.srow{padding:7px 12px;background:#111b21;flex:0 0 auto}\n.sbox{display:flex;align-items:center;gap:10px;height:35px;background:#202c33;border-radius:8px;padding:0 12px;color:#8696a0}\n.sbox>svg{width:17px;height:17px;flex:0 0 auto}\n.sbox span{font-size:14px}\n.tabs{display:flex;gap:8px;padding:2px 12px 10px;flex:0 0 auto}\n.tab{font-size:13.2px;color:#8696a0;background:#202c33;border-radius:999px;padding:5px 13px;white-space:nowrap}\n.tab.on{background:rgba(0,168,132,.2);color:#00a884}\n.convs{flex:1;overflow-y:auto;border-top:1px solid #222d34}\n.conv{display:flex;gap:14px;padding:10px 14px;cursor:pointer;background:#2a3942}\n.conv .av{width:49px;height:49px}\n.cmid{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center;gap:3px}\n.cn{display:flex;justify-content:space-between;gap:8px;align-items:baseline}\n.cn b{font-weight:400;font-size:16.5px;color:#e9edef;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.cn i{font-style:normal;font-size:12px;color:#8696a0;flex:0 0 auto}\n.cp{font-size:13.6px;color:#8696a0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n\n.chat{flex:1;display:flex;flex-direction:column;min-width:0;position:relative}\n.chead{height:59px;background:#202c33;display:flex;align-items:center;gap:14px;padding:0 16px;flex:0 0 auto;z-index:3}\n.chead .av{width:40px;height:40px}\n.ci{flex:1;min-width:0;line-height:1.25}\n.ci b{display:block;font-weight:400;font-size:16px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.ci span{display:block;font-size:12.6px;color:#8696a0}\n.ci span.act{color:#00a884}\n.thread{flex:1;overflow-y:auto;padding:14px 6.5% 10px;background-color:#0b141a;background-image:var(--wp)}\n.enc{max-width:560px;margin:2px auto 14px;background:#182229;color:#ffd279;border-radius:8px;padding:7px 12px;font-size:12.4px;line-height:1.45;display:flex;gap:7px;align-items:flex-start;text-align:center}\n.enc>svg{width:13px;height:13px;flex:0 0 auto;margin-top:2px}\n.day{display:flex;justify-content:center;margin:8px 0 12px}\n.day span{background:#182229;color:#8696a0;font-size:12.2px;border-radius:7px;padding:5px 12px;text-transform:uppercase;letter-spacing:.3px}\n.empty{display:flex;flex-direction:column;align-items:center;gap:8px;color:#8696a0;padding:52px 20px;text-align:center}\n.eico{width:46px;height:46px;color:#2a3942}\n.empty b{color:#e9edef;font-weight:400;font-size:17px}\n.empty span{font-size:13.4px;max-width:330px}\n\n.row{display:flex;margin-bottom:3px}\n.rme{justify-content:flex-end}\n.rthem{justify-content:flex-start}\n.sysrow{justify-content:center;margin:10px 0}\n.syschip{background:#3b2b2b;color:#f0a6a6;border-radius:8px;padding:6px 12px;font-size:12.6px;max-width:70%}\n.bwrap{position:relative;max-width:66%;display:flex}\n.bub{position:relative;border-radius:8px;padding:6px 9px 8px;min-width:78px;box-shadow:0 1px .5px rgba(11,20,26,.13);word-wrap:break-word;overflow-wrap:anywhere}\n.bub.them{background:#202c33;border-top-left-radius:0}\n.bub.me{background:#005c4b;border-top-right-radius:0}\n.bub.plain{background:none!important;box-shadow:none;padding:0;min-width:0}\n.txt{font-size:14.2px;line-height:1.36;white-space:pre-wrap;padding-right:58px}\n.txt.sys{color:#f0a6a6}\n.bub.hasmedia .txt{padding-top:5px}\n.meta{position:absolute;right:9px;bottom:5px;display:flex;align-items:center;gap:3px;font-size:11px;color:rgba(233,237,239,.6);pointer-events:none}\n.bub.plain .meta{right:2px;bottom:2px;background:rgba(11,20,26,.5);border-radius:6px;padding:1px 5px}\n.tk{width:16px;height:11px;color:rgba(233,237,239,.6);display:block}\n.tk.blue{color:#53bdeb}\n.tk svg{width:100%;height:100%}\n.reacts{position:absolute;bottom:-11px;right:8px;background:#202c33;border:1px solid #0b141a;border-radius:999px;padding:1px 5px;font-size:12px;line-height:1.5;display:flex;gap:1px}\n.rme .reacts{background:#005c4b}\n.row.hasreact{margin-bottom:16px}\n.reacts,.qr,.ec{font-family:'Noto Color Emoji','Apple Color Emoji','Segoe UI Emoji','Twemoji Mozilla',sans-serif}\n.pthread .row.hasreact{margin-bottom:13px}\n.quote{display:flex;flex-direction:column;gap:2px;border-left:4px solid #53bdeb;border-radius:5px;padding:4px 8px;margin-bottom:4px;background:rgba(11,20,26,.28);max-width:100%;overflow:hidden}\n.quote.qme{border-left-color:#25d366}\n.qa{font-size:12.8px;color:#53bdeb}\n.qme .qa{color:#25d366}\n.qt{font-size:13px;color:rgba(233,237,239,.65);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.media{border-radius:6px;overflow:hidden}\n.img{width:296px;max-width:100%;height:198px;background:#0b141a center/cover no-repeat;cursor:pointer}\n.stk{width:168px;height:168px;background:center/contain no-repeat}\n.vid video{width:296px;max-width:100%;height:198px;border-radius:6px;background:#000;display:block}\n.docrow{display:flex;align-items:center;gap:10px;background:rgba(11,20,26,.22);border-radius:6px;padding:10px;min-width:262px}\n.dic{width:28px;height:28px;color:#8696a0;flex:0 0 auto}\n.dmeta{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}\n.dmeta b{font-weight:400;font-size:13.6px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.dmeta i{font-style:normal;font-size:11.6px;color:#8696a0}\n.ddl{width:30px;height:30px;color:#8696a0;flex:0 0 auto;display:grid;place-items:center;border-radius:50%}\n.ddl svg{width:18px;height:18px}\n.ddl:hover{background:rgba(134,150,160,.16)}\n.aud{display:flex;align-items:center;gap:9px;min-width:252px;padding:2px 0}\n.apl{width:32px;height:32px;color:#8696a0;flex:0 0 auto;display:grid;place-items:center}\n.apl svg{width:20px;height:20px}\n.awrap{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}\n.abars{position:relative;display:flex;align-items:center;gap:2px;height:26px;cursor:pointer}\n.abars i{flex:1;background:#5b6b73;border-radius:2px;min-width:1.6px}\n.afill{position:absolute;left:0;top:0;bottom:0;width:0;background:rgba(0,168,132,.32);border-radius:3px;pointer-events:none}\n.atime{font-size:11.4px;color:rgba(233,237,239,.6);padding-right:56px}\n.typing{display:flex;gap:4px;align-items:center;min-width:0;padding:11px 13px}\n.typing i{width:7px;height:7px;border-radius:50%;background:#8696a0;animation:bl 1.3s infinite}\n.typing i:nth-child(2){animation-delay:.18s}\n.typing i:nth-child(3){animation-delay:.36s}\n@keyframes bl{0%,60%,100%{opacity:.35}30%{opacity:1}}\n.bmb{position:absolute;top:2px;right:2px;width:26px;height:26px;color:#8696a0;opacity:0;border-radius:4px;display:grid;place-items:center}\n.bmb svg{width:17px;height:17px}\n.row:hover .bmb{opacity:1;background:linear-gradient(90deg,transparent,rgba(32,44,51,.95) 45%)}\n.rme .row:hover .bmb,.rme .bmb{background:linear-gradient(90deg,transparent,rgba(0,92,75,.95) 45%)}\n.bmenu{position:absolute;top:26px;right:0;z-index:20;background:#233138;border-radius:10px;box-shadow:0 6px 22px rgba(0,0,0,.5);padding:6px;min-width:190px}\n.qrow{display:flex;gap:2px;padding:2px 2px 6px;border-bottom:1px solid #2f3b43;margin-bottom:4px}\n.qr{width:29px;height:29px;border-radius:50%;font-size:17px;line-height:1}\n.qr:hover{background:rgba(134,150,160,.16)}\n.mitem{display:flex;align-items:center;gap:10px;width:100%;padding:8px 10px;border-radius:6px;font-size:14px;color:#d1d7db}\n.mitem svg{width:17px;height:17px}\n.mitem:hover{background:rgba(134,150,160,.14)}\n\n.replybar{background:#1d282f;padding:8px 14px;display:flex;align-items:center;gap:10px;flex:0 0 auto}\n.replybar .quote{flex:1;margin:0;background:rgba(11,20,26,.35)}\n.composer{background:#202c33;padding:8px 14px;display:flex;align-items:flex-end;gap:8px;flex:0 0 auto;position:relative}\n.cinwrap{flex:1;background:#2a3942;border-radius:8px;display:flex;align-items:center;padding:0 12px;min-height:42px}\n.cin{flex:1;background:none;border:0;outline:0;color:#e9edef;font:inherit;font-size:15px;resize:none;padding:11px 0;max-height:96px;line-height:1.35}\n.cin::placeholder{color:#8696a0}\n.recbar{flex:1;display:flex;align-items:center;gap:12px;background:#2a3942;border-radius:8px;min-height:42px;padding:0 14px}\n.recdot{width:9px;height:9px;border-radius:50%;background:#f15c6d;animation:pulse 1.1s infinite}\n@keyframes pulse{0%,100%{opacity:1}50%{opacity:.25}}\n.rectime{font-variant-numeric:tabular-nums;font-size:14px;color:#e9edef;min-width:44px}\n.rechint{flex:1;font-size:13px;color:#8696a0}\n.sendbtn{color:#8696a0}\n.sendbtn.on{color:#00a884}\n\n.pop{position:absolute;z-index:40;background:#233138;border-radius:12px;box-shadow:0 10px 34px rgba(0,0,0,.55);overflow:hidden}\n.emojip{left:12px;bottom:66px;width:352px;padding:10px}\n.egrid{display:grid;grid-template-columns:repeat(9,1fr);gap:2px;max-height:238px;overflow-y:auto}\n.ec{height:35px;border-radius:6px;font-size:21px;line-height:1}\n.ec:hover{background:rgba(134,150,160,.16)}\n.attp{left:56px;bottom:66px;width:214px;padding:8px}\n.scrim{position:absolute;inset:0;z-index:35}\n.lightbox{position:absolute;inset:0;z-index:60;background:rgba(11,20,26,.95);display:flex;align-items:center;justify-content:center}\n.lightbox img{max-width:86%;max-height:86%;border-radius:4px}\n.lbx{position:absolute;top:18px;right:22px;width:40px;height:40px;color:#e9edef}\n\n.dbgbtn{position:absolute;right:0;top:50%;transform:translateY(-50%);z-index:30;width:30px;height:74px;background:#202c33;border-radius:8px 0 0 8px;color:#8696a0;display:grid;place-items:center;border:1px solid #2f3b43;border-right:0}\n.dbgbtn svg{width:17px;height:17px}\n.dbg{position:absolute;top:0;right:0;bottom:0;width:430px;max-width:80%;z-index:70;background:#111b21;border-left:1px solid #2f3b43;display:flex;flex-direction:column;box-shadow:-12px 0 34px rgba(0,0,0,.45)}\n.dhead{height:52px;display:flex;align-items:center;gap:10px;padding:0 10px 0 16px;background:#202c33;flex:0 0 auto}\n.dhead b{flex:1;font-weight:400;font-size:15.5px}\n.dbody{flex:1;overflow-y:auto;padding:12px;display:flex;flex-direction:column;gap:12px}\n.dturn{background:#182229;border:1px solid #2f3b43;border-radius:8px;overflow:hidden}\n.dtop{display:flex;align-items:center;gap:8px;padding:7px 10px;background:#1d282f;font-size:12.4px;color:#8696a0}\n.dtop .ok{color:#00a884}\n.dtop .bad{color:#f15c6d}\n.dtop .ms{margin-left:auto;font-variant-numeric:tabular-nums}\n.dlab{font-size:11px;color:#8696a0;text-transform:uppercase;letter-spacing:.5px;padding:8px 10px 3px}\n.dpre{font-family:ui-monospace,Menlo,Consolas,monospace;font-size:11.4px;line-height:1.45;color:#c7d1d6;white-space:pre-wrap;word-break:break-word;padding:0 10px 10px;max-height:190px;overflow:auto}\n.dpre.err{color:#f0a6a6}\n.dempty{color:#8696a0;font-size:13.4px;text-align:center;padding:30px 16px}\n\n/* ---------- móvil espejo (20%) ---------- */\n.phone{flex:0 0 clamp(272px,20%,376px);display:flex;align-items:center;justify-content:center;padding:16px 14px;background:#0a1014;pointer-events:none;user-select:none}\n.frame{width:100%;max-width:330px;height:100%;max-height:712px;background:#0b141a;border:9px solid #1c262c;border-radius:34px;box-shadow:0 18px 44px rgba(0,0,0,.55),inset 0 0 0 1px #2b373e;display:flex;flex-direction:column;overflow:hidden}\n.pstat{height:26px;flex:0 0 auto;background:#1f2c33;display:flex;align-items:center;justify-content:space-between;padding:0 14px;font-size:11px;color:#e9edef;font-variant-numeric:tabular-nums}\n.pbat{display:flex;align-items:center;gap:4px}\n.pbat i{display:block;width:17px;height:9px;border:1px solid #e9edef;border-radius:2px;position:relative}\n.pbat i::after{content:'';position:absolute;inset:1.5px;right:5px;background:#e9edef;border-radius:1px}\n.phead{height:50px;flex:0 0 auto;background:#1f2c33;display:flex;align-items:center;gap:8px;padding:0 10px}\n.phead .bk{width:20px;height:20px;color:#e9edef;flex:0 0 auto}\n.phead .av{width:32px;height:32px}\n.pi{flex:1;min-width:0;line-height:1.2}\n.pi b{display:block;font-size:14px;font-weight:400;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n.pi span{display:block;font-size:11px;color:#8696a0}\n.pi span.act{color:#00a884}\n.pact{display:flex;gap:14px;color:#aebac1;flex:0 0 auto}\n.pact svg{width:19px;height:19px}\n.pthread{flex:1;overflow-y:auto;padding:8px 9px;background-color:#0b141a;background-image:var(--wp);background-size:104px}\n.pcomp{flex:0 0 auto;background:#1f2c33;padding:7px 8px;display:flex;align-items:center;gap:7px}\n.pin{flex:1;background:#2a3942;border-radius:18px;min-height:33px;display:flex;align-items:center;padding:0 11px;gap:7px;color:#8696a0;overflow:hidden}\n.pin svg{width:16px;height:16px;flex:0 0 auto}\n.ptx{flex:1;font-size:12.4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}\n.ptx.has{color:#e9edef}\n.pmic{width:33px;height:33px;border-radius:50%;background:#00a884;color:#0b141a;display:grid;place-items:center;flex:0 0 auto}\n.pmic svg{width:17px;height:17px}\n\n/* la misma burbuja, a escala móvil */\n.pthread .bwrap{max-width:82%}\n.pthread .txt{font-size:12.4px;padding-right:50px}\n.pthread .meta{font-size:9.6px;right:7px;bottom:4px}\n.pthread .tk{width:14px;height:10px}\n.pthread .img{width:186px;height:126px}\n.pthread .stk{width:104px;height:104px}\n.pthread .vid video{width:186px;height:126px}\n.pthread .docrow{min-width:0;padding:8px;gap:7px}\n.pthread .dic{width:22px;height:22px}\n.pthread .dmeta b{font-size:11.6px}\n.pthread .dmeta i{font-size:10px}\n.pthread .ddl{width:22px;height:22px}\n.pthread .aud{min-width:0;gap:6px}\n.pthread .apl{width:24px;height:24px}\n.pthread .abars{height:19px;gap:1.4px}\n.pthread .atime{font-size:9.6px;padding-right:46px}\n.pthread .enc{font-size:9.8px;padding:6px 9px;margin-bottom:9px}\n.pthread .day span{font-size:10px;padding:4px 9px}\n.pthread .empty{padding:30px 10px;gap:5px}\n.pthread .eico{width:34px;height:34px}\n.pthread .empty b{font-size:13.5px}\n.pthread .empty span{font-size:11.2px}\n.pthread .bmb,.pthread .bmenu{display:none}\n.pthread .quote{padding:3px 6px}\n.pthread .qa{font-size:10.6px}\n.pthread .qt{font-size:11px}\n.pthread .reacts{font-size:10px;bottom:-9px}\n.pthread .typing{padding:9px 11px}\n.pthread .typing i{width:5.5px;height:5.5px}\n.pthread .syschip{font-size:10.6px;padding:5px 9px}\n`,\n\n  render(d2) {\n    const st = d2.state\n    const msgs = st.msgs || []\n    const name = d2.param('bellaName') || 'Bella'\n    const avatar = d2.param('bellaAvatar') || ''\n    const phone = d2.param('bellaPhone') || ''\n    const avCss = avatar ? 'background-image:url(' + esc(avatar) + ')' : ''\n    const status = st.bellaTyping ? T.typing : (st.presence === 'online' ? T.online : (st.lastSeen || T.online))\n    const actCls = st.bellaTyping || st.presence === 'online' ? ' act' : ''\n    const last = msgs.length ? msgs[msgs.length - 1] : null\n    const preview = last ? (last.mine ? T.you + ': ' : '') + (last.kind === 'text' || last.kind === 'system' ? (last.body || '') : (KL[last.kind] || '') + (last.caption ? ' · ' + last.caption : '')) : 'Toca para empezar a chatear'\n    const thread = threadHTML(msgs, st, name)\n    const overlay = st.emojiOpen || st.attachOpen || st.menuFor\n    const clock = hhmm(Date.now())\n\n    return '<div class=\"root\">' +\n\n      '<div class=\"web\">' +\n        '<aside class=\"side\">' +\n          '<div class=\"shead\"><div class=\"av meav\"></div><div class=\"sp\"></div>' +\n            '<button class=\"ib\">' + IC.newchat + '</button><button class=\"ib\">' + IC.menu + '</button></div>' +\n          '<div class=\"srow\"><div class=\"sbox\">' + IC.search + '<span>' + T.searchPh + '</span></div></div>' +\n          '<div class=\"tabs\">' + T.tabs.map((t, i) => '<span class=\"tab' + (i === 0 ? ' on' : '') + '\">' + t + '</span>').join('') + '</div>' +\n          '<div class=\"convs\"><div class=\"conv\"><div class=\"av\" style=\"' + avCss + '\"></div>' +\n            '<div class=\"cmid\"><div class=\"cn\"><b>' + esc(name) + '</b><i>' + (last ? hhmm(last.ts) : clock) + '</i></div>' +\n            '<div class=\"cp\">' + esc(preview) + '</div></div></div></div>' +\n        '</aside>' +\n\n        '<section class=\"chat\">' +\n          '<div class=\"chead\"><div class=\"av\" style=\"' + avCss + '\"></div>' +\n            '<div class=\"ci\"><b>' + esc(name) + '</b><span class=\"' + actCls.trim() + '\">' + esc(status) + '</span></div>' +\n            '<button class=\"ib\">' + IC.search + '</button><button class=\"ib\">' + IC.menu + '</button></div>' +\n\n          '<div class=\"thread\" id=\"thread\">' + thread + '</div>' +\n\n          (st.replyTo ? '<div class=\"replybar\">' + quoteHTML(st.replyTo) + '<button class=\"ib\" id=\"reply-x\">' + IC.x + '</button></div>' : '') +\n\n          '<div class=\"composer\">' +\n            (st.recording\n              ? '<button class=\"ib\" id=\"rec-cancel\" title=\"Cancelar\">' + IC.trash + '</button>' +\n                '<div class=\"recbar\"><span class=\"recdot\"></span><span class=\"rectime\" id=\"rectime\">0:00</span><span class=\"rechint\">' + T.recHint + '</span></div>' +\n                '<button class=\"ib sendbtn on\" id=\"rec-send\">' + IC.send + '</button>'\n              : '<button class=\"ib\" id=\"btn-emoji\">' + IC.emoji + '</button>' +\n                '<button class=\"ib\" id=\"btn-attach\">' + IC.clip + '</button>' +\n                '<div class=\"cinwrap\"><textarea class=\"cin\" id=\"cin\" rows=\"1\" placeholder=\"' + T.composerPh + '\"></textarea></div>' +\n                '<button class=\"ib sendbtn\" id=\"btn-send\" style=\"display:none\">' + IC.send + '</button>' +\n                '<button class=\"ib\" id=\"btn-mic\">' + IC.mic + '</button>') +\n\n            (st.emojiOpen ? '<div class=\"pop emojip\"><div class=\"egrid\">' + EMO.map((e) => '<button class=\"ec\" data-emo=\"' + e + '\">' + e + '</button>').join('') + '</div></div>' : '') +\n            (st.attachOpen ? '<div class=\"pop attp\"><button class=\"mitem\" data-att=\"media\">' + IC.image + '<span>' + T.attPhotos + '</span></button><button class=\"mitem\" data-att=\"doc\">' + IC.doc + '<span>' + T.attDoc + '</span></button></div>' : '') +\n          '</div>' +\n\n          (overlay ? '<div class=\"scrim\" id=\"scrim\"></div>' : '') +\n          (d2.param('debugEnabled') !== false && !st.debugOpen ? '<button class=\"dbgbtn\" id=\"dbg-open\" title=\"Inspector\">' + IC.bug + '</button>' : '') +\n        '</section>' +\n      '</div>' +\n\n      '<div class=\"phone\"><div class=\"frame\">' +\n        '<div class=\"pstat\"><span>' + clock + '</span><span class=\"pbat\">5G<i></i></span></div>' +\n        '<div class=\"phead\"><span class=\"bk\">' + IC.back + '</span><div class=\"av\" style=\"' + avCss + '\"></div>' +\n          '<div class=\"pi\"><b>' + esc(name) + '</b><span class=\"' + actCls.trim() + '\">' + esc(status) + '</span></div>' +\n          '<div class=\"pact\">' + IC.video + IC.phone + '</div></div>' +\n        '<div class=\"pthread\" id=\"pthread\">' + thread + '</div>' +\n        '<div class=\"pcomp\"><div class=\"pin\">' + IC.emoji + '<span class=\"ptx\" id=\"ptx\">' + T.composerPh + '</span>' + IC.clip + '</div>' +\n          '<span class=\"pmic\">' + IC.mic + '</span></div>' +\n      '</div></div>' +\n\n      (st.debugOpen ? debugHTML(st) : '') +\n      (st.lightbox ? '<div class=\"lightbox\" id=\"lightbox\"><img src=\"' + esc(st.lightbox) + '\"><button class=\"ib lbx\">' + IC.x + '</button></div>' : '') +\n      '<input type=\"file\" id=\"fin\" style=\"display:none\">' +\n    '</div>'\n  },\n\n  mounted(d2, root) {\n    if (!d2.state.msgs) d2.setState({ msgs: [], log: [], presence: 'idle', lastSeen: 'últ. vez hoy a las ' + hhmm(Date.now()) })\n    ensureAudio(d2)\n\n    d2.on('#cin', 'input', (e, el) => { draft = el.value; syncDraft(d2) })\n    d2.on('#cin', 'keydown', (e, el) => {\n      if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); draft = el.value; sendText(d2) }\n    })\n    d2.on('#btn-send', 'click', () => sendText(d2))\n    d2.on('#btn-emoji', 'click', () => { d2.state.attachOpen = false; d2.state.emojiOpen = !d2.state.emojiOpen })\n    d2.on('#btn-attach', 'click', () => { d2.state.emojiOpen = false; d2.state.attachOpen = !d2.state.attachOpen })\n    d2.on('.ec', 'click', (e, el) => {\n      const ta = d2.$('#cin')\n      draft = (ta ? ta.value : draft) + el.dataset.emo\n      if (ta) { ta.value = draft; ta.focus() }\n      syncDraft(d2)\n    })\n    d2.on('#scrim', 'click', () => d2.setState({ emojiOpen: false, attachOpen: false, menuFor: '' }))\n\n    d2.on('.mitem[data-att]', 'click', (e, el) => {\n      const fin = d2.$('#fin')\n      if (!fin) return\n      fin.accept = el.dataset.att === 'media' ? 'image/*,video/*' : ''\n      d2.state.attachOpen = false\n      fin.click()\n    })\n    d2.on('#fin', 'change', (e, el) => { const f = el.files && el.files[0]; el.value = ''; if (f) sendFile(d2, f) })\n\n    d2.on('#btn-mic', 'click', () => startRec(d2))\n    d2.on('#rec-send', 'click', () => stopRec(d2, true))\n    d2.on('#rec-cancel', 'click', () => stopRec(d2, false))\n\n    d2.on('.bmb', 'click', (e, el) => { e.stopPropagation(); d2.setState({ emojiOpen: false, attachOpen: false, menuFor: d2.state.menuFor === el.dataset.menu ? '' : el.dataset.menu }) })\n    d2.on('.qr', 'click', (e, el) => {\n      const id = el.dataset.react, emo = el.dataset.emo\n      d2.state.msgs = (d2.state.msgs || []).map((m) => {\n        if (m.id !== id) return m\n        const r = Object.assign({}, m.reactions || {})\n        if (r[emo]) delete r[emo]; else r[emo] = 1\n        return Object.assign({}, m, { reactions: r })\n      })\n      d2.state.menuFor = ''\n    })\n    d2.on('.mitem[data-replyto]', 'click', (e, el) => {\n      const m = (d2.state.msgs || []).find((x) => x.id === el.dataset.replyto)\n      if (!m) return\n      d2.setState({\n        menuFor: '',\n        replyTo: { id: m.id, mine: m.mine, author: d2.param('bellaName') || 'Bella', kind: m.kind, preview: (m.body || m.caption || m.fname || '').slice(0, 90) }\n      })\n      const ta = d2.$('#cin'); if (ta) ta.focus()\n    })\n    d2.on('#reply-x', 'click', () => { d2.state.replyTo = null })\n\n    d2.on('.img', 'click', (e, el) => { if (el.dataset.open) d2.state.lightbox = el.dataset.open })\n    d2.on('#lightbox', 'click', () => { d2.state.lightbox = '' })\n\n    d2.on('.apl', 'click', (e, el) => {\n      const id = el.dataset.play, src = el.dataset.src\n      if (!ensureAudio(d2)) return\n      if (d2.state.playingId === id) { audioEl.pause(); d2.state.playingId = ''; return }\n      if (audioEl.src !== src) { audioEl.src = src; audioEl.currentTime = 0 }\n      audioEl.play().catch(() => {})\n      d2.state.playingId = id\n    })\n    d2.on('.abars', 'click', (e, el) => {\n      if (!audioEl || d2.state.playingId !== el.dataset.seek || !audioEl.duration) return\n      const r = el.getBoundingClientRect()\n      audioEl.currentTime = Math.max(0, Math.min(1, (e.clientX - r.left) / r.width)) * audioEl.duration\n      paintAudio(d2)\n    })\n\n    d2.on('#dbg-open', 'click', () => { d2.state.debugOpen = true })\n    d2.on('#dbg-close', 'click', () => { d2.state.debugOpen = false })\n\n    d2.on('#thread', 'scroll', (e, el) => {\n      stick = el.scrollHeight - el.scrollTop - el.clientHeight < 60\n      mirrorScroll(d2)\n    })\n\n    d2.onUnmount(() => {\n      try { if (audioEl) audioEl.pause() } catch (x) {}\n      if (recTimer) clearInterval(recTimer)\n      try { if (rec && rec.state === 'recording') rec.stream.getTracks().forEach((t) => t.stop()) } catch (x) {}\n      blobs.forEach((u) => { try { URL.revokeObjectURL(u) } catch (x) {} })\n      blobs = []\n    })\n  },\n\n  updated(d2) {\n    const ta = d2.$('#cin')\n    if (ta && draft && !ta.value) ta.value = draft\n    syncDraft(d2)\n    paintAudio(d2)\n    const th = d2.$('#thread'), pt = d2.$('#pthread')\n    if (stick) {\n      if (th) th.scrollTop = th.scrollHeight\n      if (pt) pt.scrollTop = pt.scrollHeight\n    } else {\n      mirrorScroll(d2)\n    }\n  }\n}\n\n/* ---------------------------------- inspector ---------------------------------- */\nfunction debugHTML(st) {\n  const log = st.log || []\n  const body = !log.length\n    ? '<div class=\"dempty\">' + T.dbgEmpty + '</div>'\n    : log.slice().reverse().map((e) =>\n        '<div class=\"dturn\"><div class=\"dtop\"><span class=\"' + (e.error ? 'bad' : 'ok') + '\">' + (e.error ? 'ERROR' : 'OK') + '</span><span>' + hhmm(e.t) + '</span><span class=\"ms\">' + e.ms + ' ms</span></div>' +\n        '<div class=\"dlab\">Petición</div><div class=\"dpre\">' + esc(JSON.stringify(e.request, null, 2)) + '</div>' +\n        (e.error\n          ? '<div class=\"dlab\">Error</div><div class=\"dpre err\">' + esc(e.error) + '</div>'\n          : '<div class=\"dlab\">Respuesta</div><div class=\"dpre\">' + esc(JSON.stringify(e.response, null, 2)) + '</div>') +\n        '</div>').join('')\n  return '<div class=\"dbg\"><div class=\"dhead\">' + IC.bug + '<b>Inspector</b><button class=\"ib\" id=\"dbg-close\">' + IC.x + '</button></div><div class=\"dbody\">' + body + '</div></div>'\n}\n\n/* ---------------------------------- helpers de DOM ---------------------------------- */\nfunction ensureAudio(d2) {\n  if (audioEl) return audioEl\n  if (typeof Audio === 'undefined') return null\n  audioEl = new Audio()\n  audioEl.addEventListener('timeupdate', () => paintAudio(d2))\n  audioEl.addEventListener('ended', () => { d2.state.playingId = ''; paintAudio(d2) })\n  return audioEl\n}\n\nfunction syncDraft(d2) {\n  const has = !!draft.trim()\n  const px = d2.$('#ptx')\n  if (px) { px.textContent = has ? draft : T.composerPh; px.className = 'ptx' + (has ? ' has' : '') }\n  const sb = d2.$('#btn-send'), mb = d2.$('#btn-mic')\n  if (sb) sb.style.display = has ? '' : 'none'\n  if (mb) mb.style.display = has ? 'none' : ''\n}\n\nfunction mirrorScroll(d2) {\n  const th = d2.$('#thread'), pt = d2.$('#pthread')\n  if (!th || !pt) return\n  const den = th.scrollHeight - th.clientHeight\n  const r = den > 0 ? th.scrollTop / den : 1\n  pt.scrollTop = r * Math.max(0, pt.scrollHeight - pt.clientHeight)\n}\n\nfunction paintAudio(d2) {\n  const id = d2.state.playingId\n  d2.$$('.afill').forEach((el) => { if (el.dataset.fill !== id) el.style.width = '0' })\n  d2.$$('.apl').forEach((el) => { el.innerHTML = el.dataset.play === id ? IC.pause : IC.play })\n  if (!id || !audioEl) return\n  const dur = audioEl.duration && isFinite(audioEl.duration) ? audioEl.duration : 0\n  const pct = dur ? (audioEl.currentTime / dur) * 100 : 0\n  d2.$$('.afill').forEach((el) => { if (el.dataset.fill === id) el.style.width = pct + '%' })\n  d2.$$('.atime').forEach((el) => { if (el.dataset.time === id) el.textContent = mmss(audioEl.currentTime || 0) })\n}\n\n/* ---------------------------------- envío ---------------------------------- */\nfunction pushMsg(d2, m) { d2.state.msgs = (d2.state.msgs || []).concat([m]); stick = true }\nfunction setStatus(d2, id, s) {\n  d2.state.msgs = (d2.state.msgs || []).map((m) => (m.id === id && m.status !== 'read' ? Object.assign({}, m, { status: s }) : m))\n}\n\nfunction sendText(d2) {\n  const ta = d2.$('#cin')\n  const txt = ((ta ? ta.value : draft) || '').trim()\n  if (!txt || d2.state.sending) return\n  if (ta) ta.value = ''\n  draft = ''\n  syncDraft(d2)\n  dispatch(d2, { kind: 'text', body: txt })\n}\n\nfunction sendFile(d2, f) {\n  const url = URL.createObjectURL(f)\n  blobs.push(url)\n  const mime = f.type || ''\n  const kind = mime.indexOf('image/') === 0 ? 'image' : (mime.indexOf('video/') === 0 ? 'video' : (mime.indexOf('audio/') === 0 ? 'audio' : 'document'))\n  const kb = f.size < 1048576 ? Math.max(1, Math.round(f.size / 1024)) + ' kB' : (f.size / 1048576).toFixed(1) + ' MB'\n  const ta = d2.$('#cin')\n  const cap = ((ta ? ta.value : draft) || '').trim()\n  if (ta) ta.value = ''\n  draft = ''\n  syncDraft(d2)\n  dispatch(d2, { kind: kind, caption: cap, media: url, fname: f.name, fsize: kb + ' · ' + (f.name.split('.').pop() || '').toUpperCase(), durSec: 0 })\n}\n\nfunction dispatch(d2, part) {\n  const prev = d2.state.msgs || []\n  const history = prev.filter((m) => m.kind !== 'system').slice(-20).map((m) => ({\n    from: m.mine ? 'user' : 'bella', kind: m.kind, text: m.body || m.caption || m.fname || ''\n  }))\n  const m = Object.assign({\n    id: uid('u'), mine: true, kind: 'text', body: '', caption: '', media: '', fname: '', fsize: '', durSec: 0,\n    ts: Date.now(), status: 'pending', replyTo: d2.state.replyTo || null, reactions: {}\n  }, part)\n  pushMsg(d2, m)\n  d2.setState({ replyTo: null, sending: true, presence: 'online' })\n  setTimeout(() => setStatus(d2, m.id, 'sent'), 320)\n  setTimeout(() => setStatus(d2, m.id, 'delivered'), 820)\n  askBella(d2, m, history)\n}\n\nasync function askBella(d2, m, history) {\n  const request = {\n    sessionId: SID,\n    message: { kind: m.kind, text: m.body || m.caption || '', fileName: m.fname || '', durSec: m.durSec || 0 },\n    history: history\n  }\n  const t0 = Date.now()\n  let res = null, err = null\n  d2.state.bellaTyping = true\n  try {\n    res = await d2.rush(d2.param('api')).invoke(request, { headers: { Authorization: d2.param('apiKey') || '' } })\n  } catch (e) {\n    err = String((e && e.message) || e)\n  }\n  const ms = Date.now() - t0\n  d2.state.log = (d2.state.log || []).concat([{ t: Date.now(), ms: ms, request: request, response: res, error: err }]).slice(-25)\n  setStatus(d2, m.id, 'read')\n\n  const replies = (res && (res.replies || (res.data && res.data.replies))) || null\n  if (!replies || !replies.length) {\n    d2.state.bellaTyping = false\n    pushMsg(d2, { id: uid('e'), mine: false, kind: 'system', body: T.noReply + (err ? ' (' + err + ')' : ''), ts: Date.now(), reactions: {} })\n    d2.setState({ sending: false, presence: 'idle', lastSeen: 'últ. vez hoy a las ' + hhmm(Date.now()) })\n    return\n  }\n  for (let i = 0; i < replies.length; i++) {\n    const r = replies[i]\n    d2.state.bellaTyping = true\n    await wait(Math.max(400, Math.min(3000, r.delayMs || 1100)))\n    d2.state.bellaTyping = false\n    const kind = r.kind || 'text'\n    pushMsg(d2, {\n      id: uid('b'), mine: false, kind: kind,\n      body: kind === 'text' ? (r.text || '') : '',\n      caption: kind === 'text' ? '' : (r.text || ''),\n      media: r.media || '', fname: r.fileName || '', fsize: r.fileSize || '',\n      durSec: r.durSec || 0, ts: Date.now(), status: '', replyTo: null, reactions: {}\n    })\n  }\n  d2.setState({ sending: false, presence: 'idle', lastSeen: 'últ. vez hoy a las ' + hhmm(Date.now()) })\n}\n\n/* ---------------------------------- grabación de voz ---------------------------------- */\nasync function startRec(d2) {\n  if (d2.state.recording) return\n  try {\n    const stream = await navigator.mediaDevices.getUserMedia({ audio: true })\n    recChunks = []\n    rec = new MediaRecorder(stream)\n    rec.ondataavailable = (e) => { if (e.data && e.data.size) recChunks.push(e.data) }\n    rec.start()\n    recStart = Date.now()\n    d2.state.recording = true\n    recTimer = setInterval(() => {\n      const el = d2.$('#rectime')\n      if (el) el.textContent = mmss((Date.now() - recStart) / 1000)\n    }, 250)\n  } catch (e) {\n    pushMsg(d2, { id: uid('e'), mine: false, kind: 'system', body: 'No se pudo acceder al micrófono: ' + String((e && e.message) || e), ts: Date.now(), reactions: {} })\n  }\n}\n\nfunction stopRec(d2, keep) {\n  if (!rec || rec.state !== 'recording') { d2.state.recording = false; rec = null; return }\n  const secs = Math.max(1, Math.round((Date.now() - recStart) / 1000))\n  if (recTimer) { clearInterval(recTimer); recTimer = null }\n  rec.onstop = () => {\n    try { rec.stream.getTracks().forEach((t) => t.stop()) } catch (x) {}\n    if (keep && recChunks.length) {\n      const blob = new Blob(recChunks, { type: rec.mimeType || 'audio/webm' })\n      const url = URL.createObjectURL(blob)\n      blobs.push(url)\n      dispatch(d2, { kind: 'audio', media: url, durSec: secs, fname: 'nota-de-voz.webm' })\n    }\n    rec = null\n    recChunks = []\n  }\n  d2.state.recording = false\n  try { rec.stop() } catch (x) { rec = null }\n}"}},"api":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"api"}}}},"apiKey":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"apiKey"}}}},"bellaName":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"bellaName"}}}},"bellaAvatar":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"bellaAvatar"}}}},"bellaPhone":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"bellaPhone"}}}},"debugEnabled":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"debugEnabled"}}}}}}}}}},{"_id":"5ed9bed7b9e0891ce913e884","component":"data2-core-types@Component","params":{"package":"data2-core","component":"DataSource","renderable":{"dimensions":{"disabled":false,"component":"data2-core-types@Dimensions","params":{"width":1366,"exactWidth":false,"exactHeight":false,"height":768}}}}},{"_id":"5f472ae463c680de4ff296e9","component":"data2-core-types@Component","params":{"package":"data2-core","component":"Data2TableDataSource","extends":"data2-core@DataSource","renderable":{"dimensions":{"disabled":false,"component":"data2-core-types@Dimensions","params":{"width":1366,"exactWidth":false,"exactHeight":false,"height":768}}}}}]}},{"reference":"ExternalComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"_id":"5f060d9b1ca96def42f3c40a","displayName":"Builder AuthStrategy","component":"data2-core@AuthenticationStrategy","system":"5e3b796d6228227ca637d0f4","params":{"credentials":[{"component":"data2-core-types@DataSetColumnReference","params":{"column":"email"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"password"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"status"}}],"verifier":{"component":"data2-core-types@DataSetReference","params":{"reference":"UsersDataSet"}},"sessionShared":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"password":{"disabled":false,"component":"data2-core-types@DataSetColumnReference","params":{"column":"password"}},"email":{"disabled":false,"component":"data2-core-types@DataSetColumnReference","params":{"column":"email"}},"resetPassword":{"resetEmail":{"artboard":{"params":{"preventEvaluation":true,"reference":"nR6Q9d7qdaPtZhJ28Q8Dy"},"component":"data2-core-types@ArtboardReference"}},"resetSuccessEmail":{"artboard":{"params":{"preventEvaluation":true,"reference":"yPCJBTKo8q1Mw0B_3Kpwl"},"component":"data2-core-types@ArtboardReference"}}},"session":[{"component":"data2-core-types@DataSetColumnReference","params":{"column":"name"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"email"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"password"}},{"component":"data2-core-types@DataSetColumnReference","params":{"column":"status"}}],"sessionMetadata":{"params":{"actions":[{"params":{"compare":{"params":{"subject":{"params":{"components":[{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user._id"}}}},{"params":{"comparisonSubject":{"component":"data2-core-primitives@String","params":{"content":"active"}},"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user.status"}}}}},"component":"data2-core-comparison-operators@Equal","displayName":"is active user"}]},"component":"data2-core-logical-operators@And","displayName":"is active and has _id"}},"component":"data2-core-logical-operators@Not"},"then":{"params":{"message":{"component":"data2-core-primitives@String","params":{"content":"Invalid Credentials"}},"code":{"component":"data2-core-primitives@String","params":{"content":"401"}}},"component":"data2-core-types@Error"}},"component":"data2-core-flow@If","displayName":"check $user"},{"params":{"action":{"params":{"pattern":{"component":"data2-core-primitives@String","params":{"content":"@data2.app"}},"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user.email"}}}}},"component":"data2-core-functions@Includes","displayName":"isData2User"},"resultName":{"component":"data2-core-primitives@String","params":{"content":"is_data2_user"}}},"component":"data2-core-flow@Step"},{"params":{"action":{"params":{"pattern":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.d2_app"}}}},"subject":[{"component":"data2-core-primitives@String","params":{"content":"management"}}]},"component":"data2-core-functions@Includes","displayName":"isData2App Exception"},"resultName":{"component":"data2-core-primitives@String","params":{"content":"is_data2_app_exception"}}},"component":"data2-core-flow@Step"},{"params":{"resultName":{"component":"data2-core-primitives@String","params":{"content":"has_access"}},"action":{"params":{"compare":{"params":{"components":[{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"is_data2_user"}}}},{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"is_data2_app_exception"}}}}]},"component":"data2-core-logical-operators@Or"},"else":{"params":{"actions":[{"params":{"actions":[{"params":{"compare":{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}},"component":"data2-core-logical-operators@Not"},"then":{"params":{"message":{"component":"data2-core-primitives@String","params":{"content":"Invalid Credentials"}},"code":{"component":"data2-core-primitives@String","params":{"content":"401"}}},"component":"data2-core-types@Error"}},"component":"data2-core-flow@If","displayName":"check $metadata.system"},{"params":{"module":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"WuUa-VKHhW9uYU0E3-mJ8"}},"prop":"filter","args":[{"_id":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}}]},"component":"data2-core-types@Interaction"},{"params":{"compare":{"params":{"subject":{"component":"data2-core-types@Getter","params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"WuUa-VKHhW9uYU0E3-mJ8"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records.length"}}}}},"component":"data2-core-logical-operators@Not","displayName":"systems not found"},"then":{"params":{"message":{"component":"data2-core-primitives@String","params":{"content":"Invalid Credentials"}},"code":{"component":"data2-core-primitives@String","params":{"content":"401"}}},"component":"data2-core-types@Error"}},"component":"data2-core-flow@If","displayName":"check system found"},{"params":{"actions":[{"params":{"module":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":"filter","args":[{"user":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user._id"}}}},"organization":{"component":"data2-core-types@Getter","params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"WuUa-VKHhW9uYU0E3-mJ8"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"cursor.current.organization._id"}}}}}]},"component":"data2-core-types@Interaction"},{"params":{"module":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"NqKAY34n2ffFL64zamp7t"}},"prop":"filter","args":[{"user":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$user._id"}}}},"system":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}}]},"component":"data2-core-types@Interaction"}]},"component":"data2-core-flow@Parallel"}]},"component":"data2-core-flow@Series","displayName":"common setup"},{"params":{"then":{"params":{"content":true},"component":"data2-core-primitives@Boolean"},"else":{"params":{"content":false},"component":"data2-core-primitives@Boolean"},"compare":{"params":{"components":{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"WuUa-VKHhW9uYU0E3-mJ8"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"mapper":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"system"}}],"body":{"params":{"expression":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.visibility"}}}},"defaultCase":{"params":{"content":false},"component":"data2-core-primitives@Boolean"},"cases":[{"component":"data2-core-flow@Case","params":{"expression":{"component":"data2-core-primitives@String","params":{"content":"public"}},"value":{"params":{"components":[{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"member"}}],"body":{"params":{"components":[{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.organization._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.organization._id"}}}}},"component":"data2-core-comparison-operators@Equal","displayName":"is org member"},{"params":{"pattern":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.role"}}}},"subject":[{"component":"data2-core-primitives@String","params":{"content":"owner"}},{"component":"data2-core-primitives@String","params":{"content":"billing-owner"}},{"component":"data2-core-primitives@String","params":{"content":"admin"}},{"component":"data2-core-primitives@String","params":{"content":"member"}}]},"component":"data2-core-functions@Includes","displayName":"has role with access"}]},"component":"data2-core-logical-operators@And","displayName":"has org member role with access"}}}},"component":"data2-core-functions@ArrayFind","displayName":"is org member"},{"params":{"components":[{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"member"}}],"body":{"params":{"components":[{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.organization._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.organization._id"}}}}},"component":"data2-core-comparison-operators@Equal","displayName":"is org member"},{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.role"}}}},"comparisonSubject":{"component":"data2-core-primitives@String","params":{"content":"collaborator"}}},"component":"data2-core-comparison-operators@Equal","displayName":"is collaborator"}]},"component":"data2-core-logical-operators@And","displayName":"is org member and collaborator"}}}},"component":"data2-core-functions@ArrayFind","displayName":"is collaborator"},{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"NqKAY34n2ffFL64zamp7t"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"access"}}],"body":{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"access.system._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system._id"}}}}},"component":"data2-core-comparison-operators@Equal"}}}},"component":"data2-core-functions@ArrayFind","displayName":"has system access"}]},"component":"data2-core-logical-operators@And","displayName":"is collaborator and has system access"}]},"component":"data2-core-logical-operators@Or"}}},{"component":"data2-core-flow@Case","params":{"expression":{"component":"data2-core-primitives@String","params":{"content":"private"}},"value":{"params":{"components":[{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"member"}}],"body":{"params":{"components":[{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.organization._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.organization._id"}}}}},"component":"data2-core-comparison-operators@Equal","displayName":"is org member"},{"params":{"pattern":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.role"}}}},"subject":[{"component":"data2-core-primitives@String","params":{"content":"owner"}},{"component":"data2-core-primitives@String","params":{"content":"admin"}}]},"component":"data2-core-functions@Includes","displayName":"is owner/admin"}]},"component":"data2-core-logical-operators@And","displayName":"has org member role with access"}}}},"component":"data2-core-functions@ArrayFind","displayName":"is owner/admin"},{"params":{"components":[{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"Ok6Tsu5XkS7r8PyW_7TyW"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"member"}}],"body":{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"member.organization._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system.organization._id"}}}}},"component":"data2-core-comparison-operators@Equal"}}}},"component":"data2-core-functions@ArrayFind","displayName":"is org member"},{"params":{"array":{"params":{"module":{"disabled":false,"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"NqKAY34n2ffFL64zamp7t"}},"prop":{"component":"data2-core-primitives@String","params":{"content":"data.records"}}},"component":"data2-core-types@Getter"},"filter":{"disabled":false,"component":"data2-core-functions@Function","params":{"parameters":[{"component":"data2-core-primitives@String","params":{"content":"access"}}],"body":{"params":{"subject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"access.system._id"}}}},"comparisonSubject":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"system._id"}}}}},"component":"data2-core-comparison-operators@Equal"}}}},"component":"data2-core-functions@ArrayFind","displayName":"has system access"}]},"component":"data2-core-logical-operators@And","displayName":"is member and has system access"}]},"component":"data2-core-logical-operators@Or","displayName":"is owner/admin or has system access"}}}]},"component":"data2-core-flow@Switch"}}}},"component":"data2-core-functions@ArrayMap"}},"component":"data2-core-logical-operators@And","displayName":"has org member for all systems in request"}},"component":"data2-core-flow@If"}]},"component":"data2-core-flow@Series"},"then":{"params":{"content":true},"component":"data2-core-primitives@Boolean"}},"component":"data2-core-flow@If"}},"component":"data2-core-flow@Step"},{"params":{"then":{"system":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"$metadata.system"}}}}},"else":{"params":{"message":{"component":"data2-core-primitives@String","params":{"content":"Invalid Credentials"}},"code":{"component":"data2-core-primitives@String","params":{"content":"401"}}},"component":"data2-core-types@Error"},"compare":{"component":"data2-core-types@Reference","params":{"reference":{"component":"data2-core-primitives@String","params":{"content":"has_access"}}}}},"component":"data2-core-flow@If"}]},"component":"data2-core-flow@Series"},"sessionExpiresIn":{"component":"data2-core-primitives@Number","params":{"content":604800}},"sessionRenewal":{"component":"data2-core-primitives@Boolean","params":{"content":true}},"identityProviders":[{"provider":{"component":"data2-core-primitives@String","params":{"content":"GOOGLE"}},"clientId":{"component":"data2-core-primitives@String","params":{"content":"55470861603-22pvfc1t49lp8cjnbfk71s5ct9hp1q1v.apps.googleusercontent.com"}}}]},"reference":"Data2BuilderAuthentication","updatedAt":"2026-08-06T19:31:23.557Z"},{"_id":"5f060ee51ca96def42f3fbd1","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"UsersTableDataSource"}},"pagination":{"size":{"component":"data2-core-primitives@Number","params":{"content":1}}}},"reference":"UsersDataSet","updatedAt":"2026-03-04T21:16:40.291Z"},{"_id":"68f938cf5fb002e33752a43d","displayName":"InternalApplicationsAuthenticationStrategy","component":"data2-core@AuthenticationStrategy","system":"5e3b796d6228227ca637d0f4","params":{"resetPassword":{"resetEmail":{"artboard":{"params":{"preventEvaluation":true},"component":"data2-core-types@ArtboardReference"}},"resetSuccessEmail":{"artboard":{"params":{"preventEvaluation":true},"component":"data2-core-types@ArtboardReference"}}},"verifier":{"disabled":false,"component":"data2-core-types@DataSetReference","params":{"reference":"InternalApplicationsVerifierDataSet"}},"password":{"disabled":false,"component":"data2-core-types@DataSetColumnReference","params":{"column":"secret"}},"credentials":[{"component":"data2-core-types@FieldReference","params":{"key":"application"}},{"component":"data2-core-types@FieldReference","params":{"key":"secret"}},{"component":"data2-core-types@FieldReference","params":{"key":"status"}}],"session":[{"component":"data2-core-types@FieldReference","params":{"key":"application"}},{"component":"data2-core-types@FieldReference","params":{"key":"secret"}},{"component":"data2-core-types@FieldReference","params":{"key":"status"}}]},"reference":"InternalApplicationsAuthenticationStrategy","updatedAt":"2025-10-22T20:08:54.442Z","createdAt":"2025-10-22T20:04:31.198Z"},{"component":"data2-core@DataSet","reference":"SessionsDataSet","params":{"requiresConfirmation":false,"pk":"key","datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"data2sessionsdatasource"}}}},{"reference":"UsersTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}},{"component":"data2-core@ServerSessionsDataSource","reference":"data2sessionsdatasource","params":{}},{"_id":"5f1600b70528b92601890f75","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ServiceComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"ServiceComponentInstancesDataSet","updatedAt":"2025-11-06T21:07:20.208Z","createdAt":"2020-07-20T20:38:15.436Z"},{"_id":"5f1602190528b92601890f7d","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"pagination":{"size":40000},"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ComponentInstancesTableDataSource"}},"sort":{"_id":1},"pk":"_id","autoEdit":true,"master":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"ComponentInstancesDataSet","updatedAt":"2025-11-06T21:07:07.089Z","createdAt":"2020-07-20T20:44:09.350Z"},{"_id":"5f16017f0528b92601890f7a","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"FileComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"filter":{"domain":{"component":"data2-core-types@Reference","params":{"reference":"clientApplicationDomain"}}},"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}}},"reference":"FileComponentInstancesDataSet","updatedAt":"2023-08-03T16:08:18.193Z","createdAt":"2020-07-20T20:41:35.797Z"},{"_id":"5f1601990528b92601890f7b","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"ApplicationsTableDataSource"}},"pk":"_id","autoEdit":{"component":"data2-core-primitives@Boolean","params":{"content":true}},"master":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"params":{"column":"_id"},"component":"data2-core-types@DataSetColumnReference"}},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}}},"reference":"ApplicationsDataSet","updatedAt":"2022-12-13T21:51:13.995Z","createdAt":"2020-07-20T20:42:01.657Z"},{"_id":"5f16172a0528b92601890f85","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"pagination":{"size":{"component":"data2-core-primitives@Number","params":{"content":10000}}},"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"DataComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}},"policies":{"params":{"allowGet":{"component":"data2-core-primitives@Boolean","params":{"content":true}}},"component":"data2@hkXy-UhMjhyfptdE6_fpW"}},"reference":"DataComponentInstancesDataSet","updatedAt":"2025-11-06T21:07:12.831Z","createdAt":"2020-07-20T22:14:02.097Z"},{"_id":"60ddc1bbda3861ca65407c5a","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"FileComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"filter":{"domain":{"component":"data2-core-types@Reference","params":{"reference":"clientApplicationDomain"}}},"pagination":{"size":1},"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"}},"reference":"OneFileComponentInstancesDataSet","updatedAt":"2022-02-09T19:44:38.036Z","createdAt":"2020-07-20T20:41:35.797Z"},{"_id":"63ee3d38b8c9838c62fb05fb","displayName":"DriveFileComponentInstancesDataSet","component":"data2-core@DataSet","system":"5e3b796d6228227ca637d0f4","params":{"datasource":{"component":"data2-core-types@DataSourceReference","params":{"reference":"FileComponentInstancesTableDataSource"}},"pk":"_id","autoEdit":true,"filter":{"component":{"component":"data2-core-primitives@String","params":{"content":"data2-core@Drive"}}},"master":{"params":{"dataset":{"component":"data2-core-types@DataSetReference","params":{"reference":"SystemsDataSet"}},"localField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"system"}},"masterField":{"component":"data2-core-types@DataSetColumnReference","params":{"column":"_id"}}},"component":"data2-core-types@DataSetMaster"},"autoSelect":{"component":"data2-core-primitives@Boolean","params":{"content":false}}},"reference":"DriveFileComponentInstancesDataSet","updatedAt":"2025-12-04T21:58:32.367Z","createdAt":"2023-02-16T14:27:07.797Z"},{"reference":"ServiceComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6a8381f975a221e62113625c","component":"data2-rush@HTTPListener","reference":"sLSYzN3EtX3kpGdQzYwov","system":"67850da249571825a6d31832","params":{},"versioning":"enabled","bundleId":null},{"_id":"6ab027a6d6b02ee161da9034","component":"data2-rush@HTTPListener","reference":"bella-inbound","system":"67850da249571825a6d31832","params":{}}]}},{"reference":"ComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6ab029e86cba07ade638869c","component":"data2-core-primitives@Artboard","system":"67850da249571825a6d31832","displayName":"bella-sim-main","params":{"title":{"component":"data2-core-primitives@String","params":{"content":"bella-sim-main"}},"dimensions":{"component":"data2-core-types@Dimensions","params":{"width":1440,"height":900}},"position":{"component":"data2-core-types@Position","params":{"x":-2567,"y":-3315,"exactX":-2567.43,"exactY":-3315.3}}},"reference":"uhqBz2T2mVJAA6xvE4FV8"},{"_id":"14c1503038c09cb79f1a97c6","parent":"6ab029e86cba07ade638869c","component":"lucas-playground@bellaSim","system":"67850da249571825a6d31832","displayName":"Bella Sim","params":{"api":{"component":"data2-core-types@InteractiveModuleReference","params":{"reference":"bella-inbound"}},"apiKey":"bella-sim-2026-7c4f91ae3d02","bellaName":"Bella","bellaAvatar":"https://lucas-playground.data2.media/file/oq1LkHb7UrDWB7w4Rv_BE","bellaPhone":"+34 600 123 456","debugEnabled":true,"super":{"position":{"component":"data2-core-types@Position","params":{"x":0,"y":0,"freeTransform":true,"left":true,"right":true,"top":true,"bottom":true}},"dimensions":{"component":"data2-core-types@Dimensions","params":{"width":1440,"height":900}}}},"reference":"fOWBIWpbEABcTDwlBCw0h"}]}},{"_id":"5fc4faeec8da12be8bf3d08a","component":"data2-core@Data2TableDataSource","system":"5e3b796d6228227ca637d0f4","params":{"paginate":{"default":1000},"super":{},"table":"fileComponentInstances","schema":[{"component":"data2-core-types@Field","params":{"key":"component","title":"Component","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"system","title":"System","component":"data2-core-primitives@ObjectId"}},{"component":"data2-core-types@Field","params":{"key":"displayName","title":"Display Name","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"params","title":"Params","component":"data2-core-primitives@Object"}},{"component":"data2-core-types@Field","params":{"key":"reference","title":"Reference","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":{"component":"data2-core-primitives@String","params":{"content":"fileId"}},"title":"File ID","component":"data2-core-primitives@ObjectId"},"break":true}],"hooks":{"before":{"all":[{"hook":"softDelete"}],"find":[{"hook":"useCache","options":{"additionalGroupKeys":["$and.0.system","$and.1.system"],"skipCache":true}}],"create":[{"hook":"timestamp","options":{"fields":["createdAt","updatedAt"]}}],"update":[{"hook":"timestamp","options":{"fields":["updatedAt"]}}],"patch":[{"hook":"timestamp","options":{"fields":["updatedAt"]}}]},"after":{"all":[{"hook":"fileUrl","options":{"downloadField":"params.fileUrl","uploadField":"params.uploadFileUrl","enhanceSchema":false}}],"find":[{"hook":"useCache","options":{"additionalGroupKeys":["$and.0.system","$and.1.system"],"skipCache":true}}],"create":[{"hook":"invalidateCache","options":{"additionalGroupKeys":["system"],"secondaryUniqueKeys":["reference"]}},{"hook":"invalidateEnvCache"}],"update":[{"hook":"invalidateCache","options":{"additionalGroupKeys":["system"],"secondaryUniqueKeys":["reference"]}},{"hook":"invalidateEnvCache"}],"patch":[{"hook":"invalidateCache","options":{"additionalGroupKeys":["system"],"secondaryUniqueKeys":["reference"]}},{"hook":"invalidateEnvCache"}],"remove":[{"hook":"invalidateCache","options":{"additionalGroupKeys":["system"],"secondaryUniqueKeys":["reference"]}},{"hook":"invalidateEnvCache"}]}},"multi":["create"],"useEstimatedDocumentCount":true},"reference":"FileComponentInstancesTableDataSource","updatedAt":"2022-12-19T20:42:51.837Z","createdAt":"2020-11-30T13:59:52.294Z"},{"reference":"ApplicationsTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6ab19727c25c8a8144653927","displayName":"bella-sim","reference":"bUOdfXpLSSisiiToC4Jjr","params":{"domain":{"component":"data2-core-primitives@String","params":{"content":"bella-sim"}},"entryPoint":{"params":{"component":"data2-core-primitives@Artboard","reference":"uhqBz2T2mVJAA6xvE4FV8"},"component":"data2-core-types@ComponentInstanceReference"}},"system":"67850da249571825a6d31832","component":"data2-core-primitives@Application"}]}},{"reference":"DataComponentInstancesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[{"_id":"6ab3c7a42086c2e43413fb97","component":"data2-core@Data2TableDataSource","system":"67850da249571825a6d31832","params":{"table":"faqs","schema":[{"component":"data2-core-types@Field","params":{"key":"faq_id","title":"faq_id","component":"data2-core-primitives@String","required":true}},{"component":"data2-core-types@Field","params":{"key":"standard_question","title":"standard_question","component":"data2-core-primitives@String","required":true}},{"component":"data2-core-types@Field","params":{"key":"intent_variations","title":"intent_variations","component":"data2-core-primitives@Array"}},{"component":"data2-core-types@Field","params":{"key":"approved_answer_es_uy","title":"approved_answer_es_uy","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"country","title":"country","component":"data2-core-primitives@String"}},{"component":"data2-core-types@Field","params":{"key":"active","title":"active","component":"data2-core-primitives@Boolean"}},{"component":"data2-core-types@Field","params":{"key":"created_at","title":"created_at","component":"data2-core-primitives@Date"}},{"component":"data2-core-types@Field","params":{"key":"updated_at","title":"updated_at","component":"data2-core-primitives@Date"}}]},"reference":"faqs"}]}},{"reference":"BundlesTableDataSource","component":"data2-core@MemoryDataSource","params":{"initialData":[]}}],"processesParams":{}}}}