rafa-engineering 0.0.1b1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- rafa_engineering-0.0.1b1/.gitignore +25 -0
- rafa_engineering-0.0.1b1/LICENSE +121 -0
- rafa_engineering-0.0.1b1/PKG-INFO +175 -0
- rafa_engineering-0.0.1b1/README.md +130 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/ActionButton-Bf4Edlki.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/ActionButton.vue_vue_type_script_setup_true_lang-D4XFensL.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/ActionButtonInput-Fh_nzqPc.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/ActionJobButton.vue_vue_type_script_setup_true_lang-DoDkgjyF.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/AutocompleteInput-BZX1zQNq.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/BooleanInput-Bwk7TmkZ.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/BufferGeometryUtils-DCeCGp_k.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/ChatPanel-CRGfj0rM.js +5 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/ChatPanel-DV8X386K.css +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/ChildrenView-BoHMn59N.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/ColorInput-BPm4Z_Jb.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/Column-BeMEmV70.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/DateInput-BCCGUhNt.css +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/DateInput-DoB9qbsx.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/DynamicArrayInput-DMMS0Z-7.css +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/DynamicArrayInput-_ZexTyhi.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/EntityInput-DtkTtCvs.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/FieldShell.vue_vue_type_script_setup_true_lang-D1Iio9Vx.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/FileUpload-D0temXG6.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/FlowList-BFQbYe4d.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/FlowList-BJJKReYx.css +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/GeoInput-B8mK3_to.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/GeometrySelectInput-C-dllULO.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/InlineMarkdown-273vK7EL.css +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/InlineMarkdown-DZ6hRlXd.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/ItemFields.vue_vue_type_script_setup_true_lang-oM-9Jbkr.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/LineBreak-aRafznt0.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/MapSelectInput-DSHaB30s.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/MediaEmbed-BJ439byk.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/Metric-CZNGA3xN.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/MetricCard.vue_vue_type_script_setup_true_lang-C9JQb8Wv.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/MultiFileInput-ZXboXAai.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/NodeList.vue_vue_type_script_setup_true_lang-QazaRbQq.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/NumberInput-C2W5shMF.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/NumberInput-ClGTeHqr.css +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/OutputText-BCN_LkxG.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/Page-CaGMez-_.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/Region.vue_vue_type_script_setup_true_lang-C5zmYcwf.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/Row-Svp3fhrJ.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/Section-Bxqg4axO.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/SelectInput-3bMoZmLo.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/Tab-DmT7FFbM.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/TableInput-B6pu8pc-.css +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/TableInput-DRy1zZlo.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/Tabs-D_ly_8Cg.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/TextBlock-DCx1b51J.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/TextInput-ChR21tIl.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/View-5zkwqki7.js +7 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/View-B5J19S_i.css +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/Workspace-BHmWCHUw.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/Workspace-kQMd1Tiw.css +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/_commonjsHelpers-CqkleIqs.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/buildModel-FvbW_vi8.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/fileRecords-J4dDztnY.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/geometryPick-D2JWx8eh.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/geometryScene-DBVxLCLP.js +4012 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/index-BDd7wfsC.css +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/index-BR16ovZa.js +81 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-cyrillic-400-normal-obahsSVq.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-cyrillic-500-normal-BasfLYem.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-cyrillic-600-normal-CWCymEST.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-cyrillic-700-normal-CjBOestx.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-cyrillic-ext-400-normal-BQZuk6qB.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-cyrillic-ext-500-normal-B0yAr1jD.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-cyrillic-ext-600-normal-Dfes3d0z.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-cyrillic-ext-700-normal-BjwYoWNd.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-greek-400-normal-B4URO6DV.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-greek-500-normal-BIZE56-Y.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-greek-600-normal-plRanbMR.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-greek-700-normal-C3JjAnD8.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-greek-ext-400-normal-DGGRlc-M.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-greek-ext-500-normal-C4iEst2y.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-greek-ext-600-normal-DRtmH8MT.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-greek-ext-700-normal-qfdV9bQt.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-latin-400-normal-C38fXH4l.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-latin-500-normal-Cerq10X2.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-latin-600-normal-LgqL8muc.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-latin-700-normal-Yt3aPRUw.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-latin-ext-400-normal-C1nco2VV.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-latin-ext-500-normal-CV4jyFjo.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-latin-ext-600-normal-D2bJ5OIk.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-latin-ext-700-normal-Ca8adRJv.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-vietnamese-400-normal-DMkecbls.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-vietnamese-500-normal-DOriooB6.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-vietnamese-600-normal-Cc8MFFhd.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/inter-vietnamese-700-normal-DlLaEgI2.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/jetbrains-mono-cyrillic-500-normal-DmUKJPL_.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/jetbrains-mono-greek-500-normal-JpySY46c.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/jetbrains-mono-latin-ext-500-normal-Cut-4mMH.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/katex-BYjW4tYw.css +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/katex-DhXJpUyf.js +261 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/leafletChunk-wTN8pUxY.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/leafletChunk-ySJ7tiBZ.css +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/leafletMap-sOqlnmE2.js +2 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/listbox-CB4ZAfo3.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/loadGltf-3B6-WLUM.js +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/loadIfc-XWq_7Qp9.js +6 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/mapSelect-3T3UH25p.js +3 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/material-symbols-outlined-latin-400-normal-C-3S2fI8.woff2 +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/plotly.min-CSPuXaX0.js +3789 -0
- rafa_engineering-0.0.1b1/frontend/dist/assets/web-ifc-BDaIXFUT.wasm +0 -0
- rafa_engineering-0.0.1b1/frontend/dist/favicon.svg +1 -0
- rafa_engineering-0.0.1b1/frontend/dist/index.html +20 -0
- rafa_engineering-0.0.1b1/frontend/dist/theme-init.js +33 -0
- rafa_engineering-0.0.1b1/frontend/dist/web-view-frame.html +154 -0
- rafa_engineering-0.0.1b1/hatch_build.py +89 -0
- rafa_engineering-0.0.1b1/pyproject.toml +126 -0
- rafa_engineering-0.0.1b1/src/rafa/__init__.py +463 -0
- rafa_engineering-0.0.1b1/src/rafa/actions/__init__.py +42 -0
- rafa_engineering-0.0.1b1/src/rafa/actions/decorators.py +204 -0
- rafa_engineering-0.0.1b1/src/rafa/actions/results.py +533 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/__init__.py +40 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/install.py +428 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/scaffold.py +163 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/skill/SKILL.md +156 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/skill/references/access-and-permissions.md +126 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/skill/references/actions.md +157 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/skill/references/common-mistakes.md +274 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/skill/references/entities-and-hierarchy.md +190 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/skill/references/fields-and-layout.md +218 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/skill/references/jobs-and-progress.md +105 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/skill/references/maps-3d-documents-chats.md +175 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/skill/references/testing-and-checking.md +187 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/skill/references/validation-and-conditions.md +176 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/skill/references/views-and-results.md +206 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/templates/README.md.tmpl +34 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/templates/gitignore.tmpl +5 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/templates/package/__init__.py.tmpl +1 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/templates/package/controller.py.tmpl +59 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/templates/package/parametrization.py.tmpl +32 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/templates/pyproject.toml.tmpl +20 -0
- rafa_engineering-0.0.1b1/src/rafa/agent/templates/tests/test_app.py.tmpl +44 -0
- rafa_engineering-0.0.1b1/src/rafa/auth.py +72 -0
- rafa_engineering-0.0.1b1/src/rafa/chat/__init__.py +26 -0
- rafa_engineering-0.0.1b1/src/rafa/chat/execution.py +221 -0
- rafa_engineering-0.0.1b1/src/rafa/chat/model.py +194 -0
- rafa_engineering-0.0.1b1/src/rafa/chat/service.py +353 -0
- rafa_engineering-0.0.1b1/src/rafa/chat/store.py +196 -0
- rafa_engineering-0.0.1b1/src/rafa/cli.py +541 -0
- rafa_engineering-0.0.1b1/src/rafa/cli_access.py +402 -0
- rafa_engineering-0.0.1b1/src/rafa/cli_agent.py +193 -0
- rafa_engineering-0.0.1b1/src/rafa/cli_dev.py +223 -0
- rafa_engineering-0.0.1b1/src/rafa/core/__init__.py +6 -0
- rafa_engineering-0.0.1b1/src/rafa/core/access.py +2915 -0
- rafa_engineering-0.0.1b1/src/rafa/core/app_roles.py +276 -0
- rafa_engineering-0.0.1b1/src/rafa/core/application.py +2717 -0
- rafa_engineering-0.0.1b1/src/rafa/core/calculations.py +253 -0
- rafa_engineering-0.0.1b1/src/rafa/core/controller.py +614 -0
- rafa_engineering-0.0.1b1/src/rafa/core/entity.py +419 -0
- rafa_engineering-0.0.1b1/src/rafa/core/field_permissions.py +146 -0
- rafa_engineering-0.0.1b1/src/rafa/core/jobs/__init__.py +0 -0
- rafa_engineering-0.0.1b1/src/rafa/core/jobs/execution.py +238 -0
- rafa_engineering-0.0.1b1/src/rafa/core/jobs/messages.py +218 -0
- rafa_engineering-0.0.1b1/src/rafa/core/jobs/model.py +242 -0
- rafa_engineering-0.0.1b1/src/rafa/core/jobs/progress.py +248 -0
- rafa_engineering-0.0.1b1/src/rafa/core/jobs/service.py +988 -0
- rafa_engineering-0.0.1b1/src/rafa/core/jobs/store.py +412 -0
- rafa_engineering-0.0.1b1/src/rafa/core/jobs/wire.py +73 -0
- rafa_engineering-0.0.1b1/src/rafa/core/parametrization.py +712 -0
- rafa_engineering-0.0.1b1/src/rafa/core/params.py +481 -0
- rafa_engineering-0.0.1b1/src/rafa/core/registry.py +215 -0
- rafa_engineering-0.0.1b1/src/rafa/core/services/__init__.py +42 -0
- rafa_engineering-0.0.1b1/src/rafa/core/services/_common.py +53 -0
- rafa_engineering-0.0.1b1/src/rafa/core/services/calculations.py +436 -0
- rafa_engineering-0.0.1b1/src/rafa/core/services/edit_locks.py +78 -0
- rafa_engineering-0.0.1b1/src/rafa/core/services/entities.py +754 -0
- rafa_engineering-0.0.1b1/src/rafa/core/services/revisions.py +200 -0
- rafa_engineering-0.0.1b1/src/rafa/core/services/summaries.py +113 -0
- rafa_engineering-0.0.1b1/src/rafa/core/steps.py +141 -0
- rafa_engineering-0.0.1b1/src/rafa/core/storage.py +370 -0
- rafa_engineering-0.0.1b1/src/rafa/core/summary.py +344 -0
- rafa_engineering-0.0.1b1/src/rafa/demo.py +88 -0
- rafa_engineering-0.0.1b1/src/rafa/documents/__init__.py +65 -0
- rafa_engineering-0.0.1b1/src/rafa/documents/_common.py +123 -0
- rafa_engineering-0.0.1b1/src/rafa/documents/_sandbox.py +607 -0
- rafa_engineering-0.0.1b1/src/rafa/documents/excel.py +264 -0
- rafa_engineering-0.0.1b1/src/rafa/documents/images.py +246 -0
- rafa_engineering-0.0.1b1/src/rafa/documents/pdf.py +83 -0
- rafa_engineering-0.0.1b1/src/rafa/documents/word.py +235 -0
- rafa_engineering-0.0.1b1/src/rafa/exceptions.py +257 -0
- rafa_engineering-0.0.1b1/src/rafa/fields/__init__.py +98 -0
- rafa_engineering-0.0.1b1/src/rafa/fields/autocomplete.py +128 -0
- rafa_engineering-0.0.1b1/src/rafa/fields/base.py +412 -0
- rafa_engineering-0.0.1b1/src/rafa/fields/buttons.py +181 -0
- rafa_engineering-0.0.1b1/src/rafa/fields/chat.py +160 -0
- rafa_engineering-0.0.1b1/src/rafa/fields/color.py +109 -0
- rafa_engineering-0.0.1b1/src/rafa/fields/containers.py +809 -0
- rafa_engineering-0.0.1b1/src/rafa/fields/date.py +249 -0
- rafa_engineering-0.0.1b1/src/rafa/fields/file.py +430 -0
- rafa_engineering-0.0.1b1/src/rafa/fields/geo.py +535 -0
- rafa_engineering-0.0.1b1/src/rafa/fields/geometry_select.py +275 -0
- rafa_engineering-0.0.1b1/src/rafa/fields/hidden.py +61 -0
- rafa_engineering-0.0.1b1/src/rafa/fields/layout.py +331 -0
- rafa_engineering-0.0.1b1/src/rafa/fields/multiselect.py +159 -0
- rafa_engineering-0.0.1b1/src/rafa/fields/numeric.py +524 -0
- rafa_engineering-0.0.1b1/src/rafa/fields/options.py +390 -0
- rafa_engineering-0.0.1b1/src/rafa/fields/output.py +149 -0
- rafa_engineering-0.0.1b1/src/rafa/fields/relationships.py +385 -0
- rafa_engineering-0.0.1b1/src/rafa/fields/text.py +221 -0
- rafa_engineering-0.0.1b1/src/rafa/geo.py +313 -0
- rafa_engineering-0.0.1b1/src/rafa/geometry/__init__.py +107 -0
- rafa_engineering-0.0.1b1/src/rafa/geometry/material.py +215 -0
- rafa_engineering-0.0.1b1/src/rafa/geometry/models.py +221 -0
- rafa_engineering-0.0.1b1/src/rafa/geometry/objects.py +1126 -0
- rafa_engineering-0.0.1b1/src/rafa/geometry/transform.py +177 -0
- rafa_engineering-0.0.1b1/src/rafa/geometry/vector.py +195 -0
- rafa_engineering-0.0.1b1/src/rafa/geometry/wire.py +278 -0
- rafa_engineering-0.0.1b1/src/rafa/layout/__init__.py +71 -0
- rafa_engineering-0.0.1b1/src/rafa/layout/base.py +46 -0
- rafa_engineering-0.0.1b1/src/rafa/layout/chat.py +43 -0
- rafa_engineering-0.0.1b1/src/rafa/layout/children.py +27 -0
- rafa_engineering-0.0.1b1/src/rafa/layout/containers.py +141 -0
- rafa_engineering-0.0.1b1/src/rafa/layout/elements.py +105 -0
- rafa_engineering-0.0.1b1/src/rafa/layout/geo.py +33 -0
- rafa_engineering-0.0.1b1/src/rafa/layout/inputs.py +173 -0
- rafa_engineering-0.0.1b1/src/rafa/map_tiles.py +268 -0
- rafa_engineering-0.0.1b1/src/rafa/messages.py +211 -0
- rafa_engineering-0.0.1b1/src/rafa/persistence/__init__.py +6 -0
- rafa_engineering-0.0.1b1/src/rafa/persistence/access_models.py +224 -0
- rafa_engineering-0.0.1b1/src/rafa/persistence/chat_models.py +93 -0
- rafa_engineering-0.0.1b1/src/rafa/persistence/deletion.py +198 -0
- rafa_engineering-0.0.1b1/src/rafa/persistence/dialects.py +96 -0
- rafa_engineering-0.0.1b1/src/rafa/persistence/edit_locks.py +322 -0
- rafa_engineering-0.0.1b1/src/rafa/persistence/files.py +486 -0
- rafa_engineering-0.0.1b1/src/rafa/persistence/job_models.py +207 -0
- rafa_engineering-0.0.1b1/src/rafa/persistence/models.py +361 -0
- rafa_engineering-0.0.1b1/src/rafa/persistence/params_json.py +154 -0
- rafa_engineering-0.0.1b1/src/rafa/persistence/repository.py +930 -0
- rafa_engineering-0.0.1b1/src/rafa/persistence/retention.py +507 -0
- rafa_engineering-0.0.1b1/src/rafa/persistence/session.py +302 -0
- rafa_engineering-0.0.1b1/src/rafa/persistence/storage_models.py +76 -0
- rafa_engineering-0.0.1b1/src/rafa/persistence/transfer.py +238 -0
- rafa_engineering-0.0.1b1/src/rafa/persistence/types.py +56 -0
- rafa_engineering-0.0.1b1/src/rafa/project.py +158 -0
- rafa_engineering-0.0.1b1/src/rafa/project_dependencies.py +233 -0
- rafa_engineering-0.0.1b1/src/rafa/server/__init__.py +0 -0
- rafa_engineering-0.0.1b1/src/rafa/server/api.py +45 -0
- rafa_engineering-0.0.1b1/src/rafa/server/auth.py +393 -0
- rafa_engineering-0.0.1b1/src/rafa/server/controllers.py +87 -0
- rafa_engineering-0.0.1b1/src/rafa/server/dependencies.py +112 -0
- rafa_engineering-0.0.1b1/src/rafa/server/dev.py +80 -0
- rafa_engineering-0.0.1b1/src/rafa/server/logs.py +80 -0
- rafa_engineering-0.0.1b1/src/rafa/server/main.py +511 -0
- rafa_engineering-0.0.1b1/src/rafa/server/middleware.py +229 -0
- rafa_engineering-0.0.1b1/src/rafa/server/oidc.py +525 -0
- rafa_engineering-0.0.1b1/src/rafa/server/params.py +101 -0
- rafa_engineering-0.0.1b1/src/rafa/server/purge.py +87 -0
- rafa_engineering-0.0.1b1/src/rafa/server/routes/__init__.py +1 -0
- rafa_engineering-0.0.1b1/src/rafa/server/routes/_common.py +80 -0
- rafa_engineering-0.0.1b1/src/rafa/server/routes/access.py +328 -0
- rafa_engineering-0.0.1b1/src/rafa/server/routes/admin.py +318 -0
- rafa_engineering-0.0.1b1/src/rafa/server/routes/calculations.py +268 -0
- rafa_engineering-0.0.1b1/src/rafa/server/routes/chats.py +188 -0
- rafa_engineering-0.0.1b1/src/rafa/server/routes/edit_locks.py +125 -0
- rafa_engineering-0.0.1b1/src/rafa/server/routes/entities.py +289 -0
- rafa_engineering-0.0.1b1/src/rafa/server/routes/jobs.py +389 -0
- rafa_engineering-0.0.1b1/src/rafa/server/routes/navigation.py +86 -0
- rafa_engineering-0.0.1b1/src/rafa/server/routes/revisions.py +86 -0
- rafa_engineering-0.0.1b1/src/rafa/server/routes/types.py +84 -0
- rafa_engineering-0.0.1b1/src/rafa/server/schemas.py +1151 -0
- rafa_engineering-0.0.1b1/src/rafa/server/security.py +454 -0
- rafa_engineering-0.0.1b1/src/rafa/server/themes.py +326 -0
- rafa_engineering-0.0.1b1/src/rafa/server/worker_process.py +320 -0
- rafa_engineering-0.0.1b1/src/rafa/server/workers.py +473 -0
- rafa_engineering-0.0.1b1/src/rafa/settings.py +586 -0
- rafa_engineering-0.0.1b1/src/rafa/testing/__init__.py +397 -0
- rafa_engineering-0.0.1b1/src/rafa/testing/checks.py +803 -0
- rafa_engineering-0.0.1b1/src/rafa/testing/pytest_plugin.py +50 -0
- rafa_engineering-0.0.1b1/src/rafa/testing/screenshot.py +508 -0
- rafa_engineering-0.0.1b1/src/rafa/themes/__init__.py +11 -0
- rafa_engineering-0.0.1b1/src/rafa/themes/colors.py +181 -0
- rafa_engineering-0.0.1b1/src/rafa/themes/css.py +109 -0
- rafa_engineering-0.0.1b1/src/rafa/themes/files.py +143 -0
- rafa_engineering-0.0.1b1/src/rafa/themes/model.py +423 -0
- rafa_engineering-0.0.1b1/src/rafa/themes/tokens.py +124 -0
- rafa_engineering-0.0.1b1/src/rafa/ui/__init__.py +75 -0
- rafa_engineering-0.0.1b1/src/rafa/ui/adapters/__init__.py +31 -0
- rafa_engineering-0.0.1b1/src/rafa/ui/adapters/cli.py +652 -0
- rafa_engineering-0.0.1b1/src/rafa/ui/application.py +667 -0
- rafa_engineering-0.0.1b1/src/rafa/ui/context.py +153 -0
- rafa_engineering-0.0.1b1/src/rafa/ui/protocols.py +681 -0
- rafa_engineering-0.0.1b1/src/rafa/utils/__init__.py +29 -0
- rafa_engineering-0.0.1b1/src/rafa/utils/dicts.py +37 -0
- rafa_engineering-0.0.1b1/src/rafa/utils/memoization.py +312 -0
- rafa_engineering-0.0.1b1/src/rafa/utils/migrations.py +316 -0
- rafa_engineering-0.0.1b1/src/rafa/validation/__init__.py +22 -0
- rafa_engineering-0.0.1b1/src/rafa/validation/callbacks.py +187 -0
- rafa_engineering-0.0.1b1/src/rafa/validation/lookup.py +807 -0
- rafa_engineering-0.0.1b1/src/rafa/views/__init__.py +91 -0
- rafa_engineering-0.0.1b1/src/rafa/views/decorators.py +290 -0
- rafa_engineering-0.0.1b1/src/rafa/views/maps.py +990 -0
- rafa_engineering-0.0.1b1/src/rafa/views/results.py +1428 -0
- rafa_engineering-0.0.1b1/src/rafa/views/safe_html.py +100 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Python-generated files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[oc]
|
|
4
|
+
build/
|
|
5
|
+
dist/
|
|
6
|
+
wheels/
|
|
7
|
+
*.egg-info
|
|
8
|
+
.python-version
|
|
9
|
+
*.db
|
|
10
|
+
misc.xml
|
|
11
|
+
.idea
|
|
12
|
+
|
|
13
|
+
# Virtual environments
|
|
14
|
+
.venv
|
|
15
|
+
venv
|
|
16
|
+
|
|
17
|
+
.claude
|
|
18
|
+
.gemini-clipboard
|
|
19
|
+
|
|
20
|
+
# MkDocs build output
|
|
21
|
+
site/
|
|
22
|
+
|
|
23
|
+
node_modules
|
|
24
|
+
.coverage
|
|
25
|
+
coverage.json
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
Business Source License 1.1
|
|
2
|
+
|
|
3
|
+
Parameters
|
|
4
|
+
|
|
5
|
+
Licensor: Enrique García
|
|
6
|
+
|
|
7
|
+
Licensed Work: Rafa (the Python package rafa-engineering and its web app),
|
|
8
|
+
version 0.1.0 and later. The Licensed Work is
|
|
9
|
+
(c) 2026 Enrique García.
|
|
10
|
+
|
|
11
|
+
Additional Use Grant: You may make production use of the Licensed Work if at
|
|
12
|
+
least one of the following applies to you:
|
|
13
|
+
|
|
14
|
+
(a) you are a natural person;
|
|
15
|
+
|
|
16
|
+
(b) you are an organization that qualifies as a small
|
|
17
|
+
enterprise as defined in Commission Recommendation
|
|
18
|
+
2003/361/EC: fewer than 50 staff and an annual
|
|
19
|
+
turnover or annual balance sheet total not exceeding
|
|
20
|
+
EUR 10 million, counted together with your partner
|
|
21
|
+
and linked enterprises as that Recommendation
|
|
22
|
+
prescribes;
|
|
23
|
+
|
|
24
|
+
(c) you are an accredited educational institution or a
|
|
25
|
+
non-profit research organization, and you use the
|
|
26
|
+
Licensed Work for teaching, study or research.
|
|
27
|
+
|
|
28
|
+
This grant does not cover production use (i) on behalf
|
|
29
|
+
of, for, or as a service to an organization that does
|
|
30
|
+
not itself qualify under (b) or (c), or (ii) in which
|
|
31
|
+
people acting on behalf of such an organization use the
|
|
32
|
+
Licensed Work or an application built with it. Such use
|
|
33
|
+
requires a commercial license from the Licensor.
|
|
34
|
+
|
|
35
|
+
Change Date: Four years from the date the Licensed Work is published.
|
|
36
|
+
Each version has its own Change Date.
|
|
37
|
+
|
|
38
|
+
Change License: Apache License, Version 2.0
|
|
39
|
+
|
|
40
|
+
For a commercial license, or any other licensing question, contact
|
|
41
|
+
Enrique García at enriquegarcia@live.nl.
|
|
42
|
+
|
|
43
|
+
Notice
|
|
44
|
+
|
|
45
|
+
The Business Source License (this document, or the "License") is not an Open
|
|
46
|
+
Source license. However, the Licensed Work will eventually be made available
|
|
47
|
+
under an Open Source License, as stated in this License.
|
|
48
|
+
|
|
49
|
+
License text copyright (c) 2017 MariaDB Corporation Ab, All Rights Reserved.
|
|
50
|
+
"Business Source License" is a trademark of MariaDB Corporation Ab.
|
|
51
|
+
|
|
52
|
+
-----------------------------------------------------------------------------
|
|
53
|
+
|
|
54
|
+
Business Source License 1.1
|
|
55
|
+
|
|
56
|
+
Terms
|
|
57
|
+
|
|
58
|
+
The Licensor hereby grants you the right to copy, modify, create derivative
|
|
59
|
+
works, redistribute, and make non-production use of the Licensed Work. The
|
|
60
|
+
Licensor may make an Additional Use Grant, above, permitting limited
|
|
61
|
+
production use.
|
|
62
|
+
|
|
63
|
+
Effective on the Change Date, or the fourth anniversary of the first publicly
|
|
64
|
+
available distribution of a specific version of the Licensed Work under this
|
|
65
|
+
License, whichever comes first, the Licensor hereby grants you rights under
|
|
66
|
+
the terms of the Change License, and the rights granted in the paragraph
|
|
67
|
+
above terminate.
|
|
68
|
+
|
|
69
|
+
If your use of the Licensed Work does not comply with the requirements
|
|
70
|
+
currently in effect as described in this License, you must purchase a
|
|
71
|
+
commercial license from the Licensor, its affiliated entities, or authorized
|
|
72
|
+
resellers, or you must refrain from using the Licensed Work.
|
|
73
|
+
|
|
74
|
+
All copies of the original and modified Licensed Work, and derivative works
|
|
75
|
+
of the Licensed Work, are subject to this License. This License applies
|
|
76
|
+
separately for each version of the Licensed Work and the Change Date may vary
|
|
77
|
+
for each version of the Licensed Work released by Licensor.
|
|
78
|
+
|
|
79
|
+
You must conspicuously display this License on each original or modified copy
|
|
80
|
+
of the Licensed Work. If you receive the Licensed Work in original or
|
|
81
|
+
modified form from a third party, the terms and conditions set forth in this
|
|
82
|
+
License apply to your use of that work.
|
|
83
|
+
|
|
84
|
+
Any use of the Licensed Work in violation of this License will automatically
|
|
85
|
+
terminate your rights under this License for the current and all other
|
|
86
|
+
versions of the Licensed Work.
|
|
87
|
+
|
|
88
|
+
This License does not grant you any right in any trademark or logo of
|
|
89
|
+
Licensor or its affiliates (provided that you may use a trademark or logo of
|
|
90
|
+
Licensor as expressly required by this License).
|
|
91
|
+
|
|
92
|
+
TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
|
|
93
|
+
AN “AS IS” BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
|
|
94
|
+
EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
|
|
95
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
|
|
96
|
+
TITLE.
|
|
97
|
+
|
|
98
|
+
MariaDB hereby grants you permission to use this License’s text to license
|
|
99
|
+
your works, and to refer to it using the trademark “Business Source License”,
|
|
100
|
+
as long as you comply with the Covenants of Licensor below.
|
|
101
|
+
|
|
102
|
+
Covenants of Licensor
|
|
103
|
+
|
|
104
|
+
In consideration of the right to use this License’s text and the “Business
|
|
105
|
+
Source License” name and trademark, Licensor covenants to MariaDB, and to all
|
|
106
|
+
other recipients of the licensed work to be provided by Licensor:
|
|
107
|
+
|
|
108
|
+
1. To specify as the Change License the GPL Version 2.0 or any later version,
|
|
109
|
+
or a license that is compatible with GPL Version 2.0 or a later version,
|
|
110
|
+
where “compatible” means that software provided under the Change License can
|
|
111
|
+
be included in a program with software provided under GPL Version 2.0 or a
|
|
112
|
+
later version. Licensor may specify additional Change Licenses without
|
|
113
|
+
limitation.
|
|
114
|
+
|
|
115
|
+
2. To either: (a) specify an additional grant of rights to use that does not
|
|
116
|
+
impose any additional restriction on the right granted in this License, as
|
|
117
|
+
the Additional Use Grant; or (b) insert the text “None”.
|
|
118
|
+
|
|
119
|
+
3. To specify a Change Date.
|
|
120
|
+
|
|
121
|
+
4. Not to modify this License in any other way.
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: rafa-engineering
|
|
3
|
+
Version: 0.0.1b1
|
|
4
|
+
Summary: A self-hosted application framework for engineering web applications
|
|
5
|
+
Project-URL: Homepage, https://github.com/egarciamendez/rafa
|
|
6
|
+
Project-URL: Documentation, https://github.com/egarciamendez/rafa/tree/main/docs
|
|
7
|
+
Project-URL: Changelog, https://github.com/egarciamendez/rafa/blob/main/docs/changelog.md
|
|
8
|
+
Author: Enrique García
|
|
9
|
+
License: BUSL-1.1
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: Other/Proprietary License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Requires-Python: >=3.12
|
|
18
|
+
Requires-Dist: fastapi>=0.100.0
|
|
19
|
+
Requires-Dist: packaging>=23.0
|
|
20
|
+
Requires-Dist: pydantic-settings>=2.7
|
|
21
|
+
Requires-Dist: pydantic>=2.0
|
|
22
|
+
Requires-Dist: python-multipart>=0.0.6
|
|
23
|
+
Requires-Dist: sqlmodel>=0.0.22
|
|
24
|
+
Requires-Dist: uvicorn>=0.20.0
|
|
25
|
+
Requires-Dist: watchfiles>=0.21
|
|
26
|
+
Provides-Extra: documents
|
|
27
|
+
Requires-Dist: docxtpl>=0.19; extra == 'documents'
|
|
28
|
+
Requires-Dist: openpyxl>=3.1; extra == 'documents'
|
|
29
|
+
Requires-Dist: pypdf>=5.0; extra == 'documents'
|
|
30
|
+
Provides-Extra: maps
|
|
31
|
+
Requires-Dist: mapyta>=1.1; extra == 'maps'
|
|
32
|
+
Provides-Extra: oidc
|
|
33
|
+
Requires-Dist: httpx>=0.27; extra == 'oidc'
|
|
34
|
+
Requires-Dist: pyjwt[crypto]>=2.8; extra == 'oidc'
|
|
35
|
+
Provides-Extra: plotly-export
|
|
36
|
+
Requires-Dist: kaleido>=1.0; extra == 'plotly-export'
|
|
37
|
+
Requires-Dist: plotly>=6.1; extra == 'plotly-export'
|
|
38
|
+
Provides-Extra: plots
|
|
39
|
+
Requires-Dist: matplotlib>=3.8; extra == 'plots'
|
|
40
|
+
Provides-Extra: postgres
|
|
41
|
+
Requires-Dist: psycopg[binary]>=3.2; extra == 'postgres'
|
|
42
|
+
Provides-Extra: screenshot
|
|
43
|
+
Requires-Dist: playwright>=1.49; extra == 'screenshot'
|
|
44
|
+
Description-Content-Type: text/markdown
|
|
45
|
+
|
|
46
|
+
# Rafa
|
|
47
|
+
|
|
48
|
+
**Build engineering web apps in plain Python.** Declare the inputs, write the calculation, get a
|
|
49
|
+
browser workspace with forms, live views, revisions and a database. A library you run on your
|
|
50
|
+
own infrastructure.
|
|
51
|
+
|
|
52
|
+
<picture>
|
|
53
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/egarciamendez/rafa/main/docs/assets/screenshots/workspace-light.png">
|
|
54
|
+
<img alt="The workspace: loads of a foundation pad on the left, its soil pressure chart on the canvas, metrics in the results panel on the right" src="https://raw.githubusercontent.com/egarciamendez/rafa/main/docs/assets/screenshots/workspace-dark.png">
|
|
55
|
+
</picture>
|
|
56
|
+
|
|
57
|
+
- **Python SDK** (`rafa`): parametrizations, controllers, views, actions, entities,
|
|
58
|
+
revisions, migrations. Stored in SQLite or PostgreSQL through SQLModel.
|
|
59
|
+
- **Server**: a FastAPI app that serves the HTTP API and the web UI from one process.
|
|
60
|
+
- **Web app**: a Vue 3 workspace rendered from layout JSON the server generates from your
|
|
61
|
+
Python classes: entity browser, autosave with undo and revision history, RUN for slow
|
|
62
|
+
calculations, keyboard shortcuts and a command palette, dark and light theme.
|
|
63
|
+
|
|
64
|
+
## Quickstart
|
|
65
|
+
|
|
66
|
+
Requires Python 3.12+. The package contains the web app, so no Node.js is needed. Rafa is in
|
|
67
|
+
beta:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pip install rafa-engineering # or: uv add rafa-engineering
|
|
71
|
+
rafa serve --demo # http://127.0.0.1:7232
|
|
72
|
+
rafa new bridge-checks && cd bridge-checks # a new app of your own
|
|
73
|
+
rafa dev # it, restarted and checked on every change
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The [Quickstart](https://github.com/egarciamendez/rafa/blob/main/docs/quickstart.md) walks from the install to your own app in the browser,
|
|
77
|
+
and shows how to run the [example apps](https://github.com/egarciamendez/rafa/blob/main/docs/examples/index.md) from a checkout.
|
|
78
|
+
|
|
79
|
+
## Features
|
|
80
|
+
|
|
81
|
+
- **Declarative inputs**: 25 field types (numbers, options, dates, tables, dynamic arrays,
|
|
82
|
+
files, entity references) in tabs and sections, with `Lookup` constraints and conditional
|
|
83
|
+
visibility.
|
|
84
|
+
- **Views**: `@view` returns HTML, data, a table, an image, a PDF, a Plotly chart or 3D
|
|
85
|
+
geometry; `@metric` shows a number in the results panel. Fast views refresh on every change,
|
|
86
|
+
slow views run on **RUN**.
|
|
87
|
+
- **Actions**: `@action` methods become buttons that return a message, a file download, new
|
|
88
|
+
input values or candidate designs to choose from.
|
|
89
|
+
- **Entities**: typed, hierarchical records with navigation, cascade rules, soft delete and
|
|
90
|
+
recovery.
|
|
91
|
+
- **Revisions**: every save is a revision; list, read and restore.
|
|
92
|
+
- **Schema migrations**: evolve a parametrization without losing stored data.
|
|
93
|
+
- **Server**: one `rafa serve` command, sign-in (API key, proxy, OpenID Connect or your
|
|
94
|
+
own hook), SQLite or PostgreSQL, backups, retention, calculation limits, a Docker image.
|
|
95
|
+
- **Design system**: one token file drives the web app's dark and light theme.
|
|
96
|
+
|
|
97
|
+
Overview: [docs/features.md](https://github.com/egarciamendez/rafa/blob/main/docs/features.md).
|
|
98
|
+
|
|
99
|
+
## Documentation
|
|
100
|
+
|
|
101
|
+
| You want to | Read |
|
|
102
|
+
|---|---|
|
|
103
|
+
| Try it in 5 minutes | [Quickstart](https://github.com/egarciamendez/rafa/blob/main/docs/quickstart.md) |
|
|
104
|
+
| Learn the SDK step by step | [Tutorial](https://github.com/egarciamendez/rafa/blob/main/docs/tutorial/index.md) |
|
|
105
|
+
| Look up a term | [Concepts](https://github.com/egarciamendez/rafa/blob/main/docs/concepts.md) |
|
|
106
|
+
| Learn from working apps | [Example apps](https://github.com/egarciamendez/rafa/blob/main/docs/examples/index.md) |
|
|
107
|
+
| Solve a specific task | [How-to guides](https://github.com/egarciamendez/rafa/blob/main/docs/how-to/index.md) |
|
|
108
|
+
| Use the web app | [User guide](https://github.com/egarciamendez/rafa/blob/main/docs/user-guide/index.md) |
|
|
109
|
+
| Run or deploy the server | [Run the server](https://github.com/egarciamendez/rafa/blob/main/docs/server/index.md), [Deploy](https://github.com/egarciamendez/rafa/blob/main/docs/server/deploy.md), [Settings](https://github.com/egarciamendez/rafa/blob/main/docs/server/settings.md) |
|
|
110
|
+
| Call the HTTP API | [HTTP API](https://github.com/egarciamendez/rafa/blob/main/docs/reference/http-api.md) |
|
|
111
|
+
| Look up a class | [Reference](https://github.com/egarciamendez/rafa/blob/main/docs/reference/index.md) |
|
|
112
|
+
| Know why it works this way | [Decisions](https://github.com/egarciamendez/rafa/blob/main/docs/decisions.md), [Architecture](https://github.com/egarciamendez/rafa/blob/main/docs/about/architecture.md) |
|
|
113
|
+
|
|
114
|
+
Build the documentation site locally:
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
uv sync --group docs
|
|
118
|
+
uv run properdocs serve -f properdocs.yml # http://127.0.0.1:8000
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Project layout
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
src/rafa/ Python SDK (package `rafa`)
|
|
125
|
+
core/ Application, Controller, Parametrization, Entity, Params, services
|
|
126
|
+
fields/ input fields and layout (Tab, Section, ...)
|
|
127
|
+
views/ actions/ @view, @metric, @action and their result types
|
|
128
|
+
layout/ layout tree sent to the web app as JSON
|
|
129
|
+
persistence/ SQLModel models and repositories
|
|
130
|
+
server/ FastAPI app, settings, middleware
|
|
131
|
+
frontend/ Vue 3 + Vite + Tailwind web app
|
|
132
|
+
design_system/ design tokens (colors_and_type.css) and UI kit
|
|
133
|
+
examples/ example apps: engineering_app (Beam, Project, Showcase), foundation_app,
|
|
134
|
+
beam_formulas_app
|
|
135
|
+
docs/ documentation site (properdocs)
|
|
136
|
+
tests/ pytest suite
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Development
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
uv sync --all-groups # Python dependencies (dev + docs)
|
|
143
|
+
uv run pytest # tests
|
|
144
|
+
uv run ruff check . && uv run ruff format --check .
|
|
145
|
+
uv run ty check . # type check
|
|
146
|
+
|
|
147
|
+
# Frontend development: the API with reload (answering the dev server's origin), and Vite
|
|
148
|
+
RAFA_CORS_ORIGINS=http://localhost:5173 \
|
|
149
|
+
uv run uvicorn rafa.server.main:app --reload --port 8000 --no-proxy-headers
|
|
150
|
+
cd frontend
|
|
151
|
+
npm ci
|
|
152
|
+
npm run dev # http://localhost:5173, uses the API on :8000
|
|
153
|
+
npm run build # type check + production build to dist/
|
|
154
|
+
npm test # Storybook story tests (needs Playwright Chromium)
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
CI runs all of the above plus a strict docs build, and builds the wheel, installs it outside
|
|
158
|
+
the checkout and serves an app from it. See [Contributing](https://github.com/egarciamendez/rafa/blob/main/docs/contributing.md).
|
|
159
|
+
|
|
160
|
+
## License
|
|
161
|
+
|
|
162
|
+
Rafa is licensed under the [Business Source License 1.1](https://github.com/egarciamendez/rafa/blob/main/LICENSE). Production use is free for:
|
|
163
|
+
|
|
164
|
+
- individuals;
|
|
165
|
+
- small enterprises: fewer than 50 staff and at most EUR 10 million turnover or balance sheet
|
|
166
|
+
total (the EU definition, Recommendation 2003/361/EC, group companies included);
|
|
167
|
+
- teaching, study and research at educational institutions and non-profit research
|
|
168
|
+
organizations.
|
|
169
|
+
|
|
170
|
+
Development, testing and evaluation are free for everyone. Production use on behalf of, for, or
|
|
171
|
+
by people of a larger organization needs a commercial license: contact Enrique García at
|
|
172
|
+
enriquegarcia@live.nl. Four years after its release, each version becomes available under the
|
|
173
|
+
Apache License 2.0.
|
|
174
|
+
|
|
175
|
+
© 2026 Enrique García
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Rafa
|
|
2
|
+
|
|
3
|
+
**Build engineering web apps in plain Python.** Declare the inputs, write the calculation, get a
|
|
4
|
+
browser workspace with forms, live views, revisions and a database. A library you run on your
|
|
5
|
+
own infrastructure.
|
|
6
|
+
|
|
7
|
+
<picture>
|
|
8
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/egarciamendez/rafa/main/docs/assets/screenshots/workspace-light.png">
|
|
9
|
+
<img alt="The workspace: loads of a foundation pad on the left, its soil pressure chart on the canvas, metrics in the results panel on the right" src="https://raw.githubusercontent.com/egarciamendez/rafa/main/docs/assets/screenshots/workspace-dark.png">
|
|
10
|
+
</picture>
|
|
11
|
+
|
|
12
|
+
- **Python SDK** (`rafa`): parametrizations, controllers, views, actions, entities,
|
|
13
|
+
revisions, migrations. Stored in SQLite or PostgreSQL through SQLModel.
|
|
14
|
+
- **Server**: a FastAPI app that serves the HTTP API and the web UI from one process.
|
|
15
|
+
- **Web app**: a Vue 3 workspace rendered from layout JSON the server generates from your
|
|
16
|
+
Python classes: entity browser, autosave with undo and revision history, RUN for slow
|
|
17
|
+
calculations, keyboard shortcuts and a command palette, dark and light theme.
|
|
18
|
+
|
|
19
|
+
## Quickstart
|
|
20
|
+
|
|
21
|
+
Requires Python 3.12+. The package contains the web app, so no Node.js is needed. Rafa is in
|
|
22
|
+
beta:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install rafa-engineering # or: uv add rafa-engineering
|
|
26
|
+
rafa serve --demo # http://127.0.0.1:7232
|
|
27
|
+
rafa new bridge-checks && cd bridge-checks # a new app of your own
|
|
28
|
+
rafa dev # it, restarted and checked on every change
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The [Quickstart](https://github.com/egarciamendez/rafa/blob/main/docs/quickstart.md) walks from the install to your own app in the browser,
|
|
32
|
+
and shows how to run the [example apps](https://github.com/egarciamendez/rafa/blob/main/docs/examples/index.md) from a checkout.
|
|
33
|
+
|
|
34
|
+
## Features
|
|
35
|
+
|
|
36
|
+
- **Declarative inputs**: 25 field types (numbers, options, dates, tables, dynamic arrays,
|
|
37
|
+
files, entity references) in tabs and sections, with `Lookup` constraints and conditional
|
|
38
|
+
visibility.
|
|
39
|
+
- **Views**: `@view` returns HTML, data, a table, an image, a PDF, a Plotly chart or 3D
|
|
40
|
+
geometry; `@metric` shows a number in the results panel. Fast views refresh on every change,
|
|
41
|
+
slow views run on **RUN**.
|
|
42
|
+
- **Actions**: `@action` methods become buttons that return a message, a file download, new
|
|
43
|
+
input values or candidate designs to choose from.
|
|
44
|
+
- **Entities**: typed, hierarchical records with navigation, cascade rules, soft delete and
|
|
45
|
+
recovery.
|
|
46
|
+
- **Revisions**: every save is a revision; list, read and restore.
|
|
47
|
+
- **Schema migrations**: evolve a parametrization without losing stored data.
|
|
48
|
+
- **Server**: one `rafa serve` command, sign-in (API key, proxy, OpenID Connect or your
|
|
49
|
+
own hook), SQLite or PostgreSQL, backups, retention, calculation limits, a Docker image.
|
|
50
|
+
- **Design system**: one token file drives the web app's dark and light theme.
|
|
51
|
+
|
|
52
|
+
Overview: [docs/features.md](https://github.com/egarciamendez/rafa/blob/main/docs/features.md).
|
|
53
|
+
|
|
54
|
+
## Documentation
|
|
55
|
+
|
|
56
|
+
| You want to | Read |
|
|
57
|
+
|---|---|
|
|
58
|
+
| Try it in 5 minutes | [Quickstart](https://github.com/egarciamendez/rafa/blob/main/docs/quickstart.md) |
|
|
59
|
+
| Learn the SDK step by step | [Tutorial](https://github.com/egarciamendez/rafa/blob/main/docs/tutorial/index.md) |
|
|
60
|
+
| Look up a term | [Concepts](https://github.com/egarciamendez/rafa/blob/main/docs/concepts.md) |
|
|
61
|
+
| Learn from working apps | [Example apps](https://github.com/egarciamendez/rafa/blob/main/docs/examples/index.md) |
|
|
62
|
+
| Solve a specific task | [How-to guides](https://github.com/egarciamendez/rafa/blob/main/docs/how-to/index.md) |
|
|
63
|
+
| Use the web app | [User guide](https://github.com/egarciamendez/rafa/blob/main/docs/user-guide/index.md) |
|
|
64
|
+
| Run or deploy the server | [Run the server](https://github.com/egarciamendez/rafa/blob/main/docs/server/index.md), [Deploy](https://github.com/egarciamendez/rafa/blob/main/docs/server/deploy.md), [Settings](https://github.com/egarciamendez/rafa/blob/main/docs/server/settings.md) |
|
|
65
|
+
| Call the HTTP API | [HTTP API](https://github.com/egarciamendez/rafa/blob/main/docs/reference/http-api.md) |
|
|
66
|
+
| Look up a class | [Reference](https://github.com/egarciamendez/rafa/blob/main/docs/reference/index.md) |
|
|
67
|
+
| Know why it works this way | [Decisions](https://github.com/egarciamendez/rafa/blob/main/docs/decisions.md), [Architecture](https://github.com/egarciamendez/rafa/blob/main/docs/about/architecture.md) |
|
|
68
|
+
|
|
69
|
+
Build the documentation site locally:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
uv sync --group docs
|
|
73
|
+
uv run properdocs serve -f properdocs.yml # http://127.0.0.1:8000
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Project layout
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
src/rafa/ Python SDK (package `rafa`)
|
|
80
|
+
core/ Application, Controller, Parametrization, Entity, Params, services
|
|
81
|
+
fields/ input fields and layout (Tab, Section, ...)
|
|
82
|
+
views/ actions/ @view, @metric, @action and their result types
|
|
83
|
+
layout/ layout tree sent to the web app as JSON
|
|
84
|
+
persistence/ SQLModel models and repositories
|
|
85
|
+
server/ FastAPI app, settings, middleware
|
|
86
|
+
frontend/ Vue 3 + Vite + Tailwind web app
|
|
87
|
+
design_system/ design tokens (colors_and_type.css) and UI kit
|
|
88
|
+
examples/ example apps: engineering_app (Beam, Project, Showcase), foundation_app,
|
|
89
|
+
beam_formulas_app
|
|
90
|
+
docs/ documentation site (properdocs)
|
|
91
|
+
tests/ pytest suite
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Development
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
uv sync --all-groups # Python dependencies (dev + docs)
|
|
98
|
+
uv run pytest # tests
|
|
99
|
+
uv run ruff check . && uv run ruff format --check .
|
|
100
|
+
uv run ty check . # type check
|
|
101
|
+
|
|
102
|
+
# Frontend development: the API with reload (answering the dev server's origin), and Vite
|
|
103
|
+
RAFA_CORS_ORIGINS=http://localhost:5173 \
|
|
104
|
+
uv run uvicorn rafa.server.main:app --reload --port 8000 --no-proxy-headers
|
|
105
|
+
cd frontend
|
|
106
|
+
npm ci
|
|
107
|
+
npm run dev # http://localhost:5173, uses the API on :8000
|
|
108
|
+
npm run build # type check + production build to dist/
|
|
109
|
+
npm test # Storybook story tests (needs Playwright Chromium)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
CI runs all of the above plus a strict docs build, and builds the wheel, installs it outside
|
|
113
|
+
the checkout and serves an app from it. See [Contributing](https://github.com/egarciamendez/rafa/blob/main/docs/contributing.md).
|
|
114
|
+
|
|
115
|
+
## License
|
|
116
|
+
|
|
117
|
+
Rafa is licensed under the [Business Source License 1.1](https://github.com/egarciamendez/rafa/blob/main/LICENSE). Production use is free for:
|
|
118
|
+
|
|
119
|
+
- individuals;
|
|
120
|
+
- small enterprises: fewer than 50 staff and at most EUR 10 million turnover or balance sheet
|
|
121
|
+
total (the EU definition, Recommendation 2003/361/EC, group companies included);
|
|
122
|
+
- teaching, study and research at educational institutions and non-profit research
|
|
123
|
+
organizations.
|
|
124
|
+
|
|
125
|
+
Development, testing and evaluation are free for everyone. Production use on behalf of, for, or
|
|
126
|
+
by people of a larger organization needs a commercial license: contact Enrique García at
|
|
127
|
+
enriquegarcia@live.nl. Four years after its release, each version becomes available under the
|
|
128
|
+
Apache License 2.0.
|
|
129
|
+
|
|
130
|
+
© 2026 Enrique García
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as o}from"./ActionButton.vue_vue_type_script_setup_true_lang-D4XFensL.js";import"./ActionJobButton.vue_vue_type_script_setup_true_lang-DoDkgjyF.js";import"./index-BR16ovZa.js";export{o as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as p}from"./ActionJobButton.vue_vue_type_script_setup_true_lang-DoDkgjyF.js";import{d as x,l as t,T as A,A as z,a7 as B,m as h,S as K,o as v,p as d,w as j,h as w,t as C,x as J,f as o,i as S}from"./index-BR16ovZa.js";const V=x({__name:"ActionButton",props:{label:{},action_slug:{},variant:{},icon:{},confirmation_message:{},description:{},disabled:{type:Boolean},block:{type:Boolean},size:{}},setup(a){const e=a,r=t(A,null),b=t(z,null),l=o(()=>b?.(e.action_slug)??null),g=t(B,"canvas"),c=o(()=>g==="inspector"),s=S(!1),n=o(()=>e.label||e.action_slug),f=t(h,null),m=t(K,null),i=o(()=>f?.(e.action_slug)??null),y=()=>{i.value&&m?.(i.value.id)},u=o(()=>e.variant==="text"?"ghost":c.value&&e.variant!=="danger"?"secondary":e.variant??"primary"),k=async()=>{if(!r){console.warn("ActionButton: no trigger-action provided");return}s.value=!0;try{await r(e.action_slug,e.confirmation_message,n.value,u.value)}finally{s.value=!1}};return(_,$)=>i.value?(v(),d(p,{key:0,job:i.value,text:n.value,variant:u.value,size:a.size,icon:a.icon,block:a.block||c.value,onStop:y},null,8,["job","text","variant","size","icon","block"])):(v(),d(J,{key:1,variant:u.value,size:a.size??"md",icon:a.icon,loading:s.value,disabled:a.disabled||!!l.value,block:a.block||c.value,title:l.value?`${n.value}: ${l.value}`:a.description||n.value,onClick:k},{default:j(()=>[w(C(n.value),1)]),_:1},8,["variant","size","icon","loading","disabled","block","title"]))}});export{V as _};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as x,l as o,T as A,A as $,m as B,S as w,o as t,c as i,t as c,e as m,p as v,w as j,h as C,x as J,f as s,i as K}from"./index-BR16ovZa.js";import{_ as S}from"./ActionJobButton.vue_vue_type_script_setup_true_lang-DoDkgjyF.js";const T={class:"flex flex-col gap-2 w-full"},V={key:0,class:"label"},I=["id"],N=["id"],z=x({__name:"ActionButtonInput",props:{name:{},label:{},value:{},method:{},variant:{},icon:{},button_label:{},confirmation_message:{},description:{},disabled:{type:Boolean},error:{}},setup(e){const a=e,u=o(A,null),f=o($,null),r=s(()=>f?.(a.method)??null),y=o(B,null),g=o(w,null),l=s(()=>y?.(a.method)??null),h=()=>{l.value&&g?.(l.value.id)},d=K(!1),n=s(()=>a.button_label||a.label),b=s(()=>a.variant==="danger"?"danger":"secondary"),k=async()=>{if(!u){console.warn("ActionButtonInput: no trigger-action provided");return}d.value=!0;try{await u(a.method,a.confirmation_message,n.value,a.variant??"primary")}finally{d.value=!1}};return(D,E)=>(t(),i("div",T,[e.button_label&&e.label&&e.label!==e.button_label?(t(),i("span",V,c(e.label),1)):m("",!0),l.value?(t(),v(S,{key:1,job:l.value,text:n.value,variant:b.value,icon:e.icon,block:"",onStop:h},null,8,["job","text","variant","icon"])):(t(),v(J,{key:2,id:e.name,variant:b.value,icon:e.icon,loading:d.value,disabled:e.disabled||!!r.value,title:r.value?`${n.value}: ${r.value}`:n.value,"aria-describedby":e.error||e.description?`${e.name}-help`:void 0,block:"",onClick:k},{default:j(()=>[C(c(n.value),1)]),_:1},8,["id","variant","icon","loading","disabled","title","aria-describedby"])),e.error?(t(),i("p",{key:3,id:`${e.name}-help`,role:"alert",class:"field-error -mt-1"},c(e.error),9,I)):e.description?(t(),i("p",{key:4,id:`${e.name}-help`,class:"field-help -mt-1"},c(e.description),9,N)):m("",!0)]))}});export{z as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as g,o as t,c as i,n as u,b as d,a as p,w as j,h as k,t as m,e as l,x as b,p as y,Q as z,f as r,bF as $,q as h}from"./index-BR16ovZa.js";const w={class:"flex items-stretch gap-2 min-w-0"},B={key:0,class:"ml-1 font-mono normal-case tracking-normal"},N=g({__name:"ActionJobButton",props:{job:{},text:{},variant:{},size:{},icon:{},block:{type:Boolean}},emits:["stop"],setup(e,{emit:f}){const a=e,v=f,s=r(()=>$(a.job.progress)),n=r(()=>a.job.stop_reason?"Stopping…":a.job.status==="queued"?"Queued":h(a.job.progress)),x=r(()=>{const o=a.job;return`${a.text} is running${o.message?`: ${o.message}`:""}`});return(o,c)=>(t(),i("div",{class:u(["flex flex-col gap-1 min-w-0",{"w-full":e.block}]),"data-action-job":""},[d("div",w,[p(b,{class:"flex-1",variant:e.variant,size:e.size??"md",icon:e.icon,loading:"",title:x.value,"aria-label":`${e.text}: ${n.value??"running"}`},{default:j(()=>[k(m(e.text),1),n.value?(t(),i("span",B,m(n.value),1)):l("",!0)]),_:1},8,["variant","size","icon","title","aria-label"]),e.job.can_stop?(t(),y(b,{key:0,variant:"secondary",size:e.size==="sm"?"sm":"md",icon:"stop",disabled:!!e.job.stop_reason,"aria-label":`Stop ${e.text}`,title:"Stop",onClick:c[0]||(c[0]=C=>v("stop"))},null,8,["size","disabled","aria-label"])):l("",!0)]),d("div",{class:u(["rafa-bar !h-0.5",{"rafa-bar-indeterminate":s.value===null}]),"aria-hidden":"true"},[s.value!==null?(t(),i("div",{key:0,class:"rafa-bar-fill",style:z({width:`${s.value}%`})},null,4)):l("",!0)],2)],2))}});export{N as _};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as j,N as U,o as r,p as $,w as q,b as m,u as o,c as d,a as D,L as M,e as v,O as z,aE as G,bC as H,F as J,g as Q,t as N,i as y,f as x}from"./index-BR16ovZa.js";import{_ as R}from"./FieldShell.vue_vue_type_script_setup_true_lang-D1Iio9Vx.js";import{_ as W,n as X,u as Y}from"./listbox-CB4ZAfo3.js";import"./InlineMarkdown-DZ6hRlXd.js";const Z=["data-open","data-invalid","data-disabled","data-readonly"],_={key:0,class:"rafa-unit rafa-prefix"},ee=["id","aria-expanded","aria-controls","aria-activedescendant","aria-invalid","aria-describedby","disabled","readonly","placeholder"],ae={key:2,class:"rafa-unit"},te=["id","aria-selected","data-active","onMouseenter","onClick"],le={class:"flex-1 truncate"},ne={key:0,"aria-hidden":"true",class:"material-symbols-outlined text-[16px] text-accent"},oe={key:0,class:"rafa-popover-note"},de=j({__name:"AutocompleteInput",props:{name:{},label:{},value:{},options:{},min_chars:{},prefix:{},suffix:{},description:{},disabled:{type:Boolean},read_only:{type:Boolean},required:{type:Boolean},error:{}},emits:["update:value"],setup(t,{emit:T}){const s=t,C=T,n=y(""),i=y(!1),f=x(()=>s.min_chars??1),h=e=>{const a=(s.options??[]).find(c=>c.value===e);return a?a.label:e!=null?String(e):""};U(()=>s.value,e=>{n.value=h(e),i.value=!1},{immediate:!0});const b=x(()=>{const e=s.options??[];if(!i.value)return e;if(n.value.length<f.value)return[];const a=n.value.toLowerCase();return e.filter(c=>c.label.toLowerCase().includes(a)||String(c.value).toLowerCase().includes(a))}),k=X("autocomplete"),w=y(null),I=y(null),g=x(()=>s.disabled||s.read_only),l=Y({items:b,labelOf:e=>e.label,onSelect:e=>{n.value=e.label,i.value=!1,C("update:value",e.value)},initialIndex:()=>b.value.findIndex(e=>e.value===s.value),idPrefix:k}),V=x(()=>i.value&&n.value.length<f.value),L=()=>{i.value=!0,n.value.length>=f.value?l.openList(0):l.closeList()},E=e=>{const a=e;!i.value&&a.inputType==="insertText"&&a.data&&(n.value=a.data),L()},F=e=>{if(g.value||i.value)return;const a=e.clipboardData?.getData("text/plain");a&&(e.preventDefault(),n.value=a.replace(/\s+/g," ").trim(),L())},A=e=>{if(!g.value){if(e.key==="Escape"&&!l.open.value&&i.value){n.value=h(s.value),i.value=!1;return}l.onKeydown(e,{textInput:!0})}},K=()=>{l.closeList(),i.value&&(n.value=h(s.value),i.value=!1)},O=()=>{n.value="",i.value=!1,l.closeList(),C("update:value",null),I.value?.focus()},B=x(()=>f.value>1?`Type ${f.value}+ characters…`:"Search…");return(e,a)=>(r(),$(R,{name:t.name,label:t.label,description:t.description,error:t.error,required:t.required},{default:q(({describedBy:c,invalid:S})=>[m("div",{ref_key:"control",ref:w,class:"rafa-control","data-open":o(l).open.value||void 0,"data-invalid":S||void 0,"data-disabled":t.disabled||void 0,"data-readonly":t.read_only&&!t.disabled||void 0},[t.prefix?(r(),d("span",_,[D(M,{text:t.prefix},null,8,["text"])])):v("",!0),a[4]||(a[4]=m("span",{"aria-hidden":"true",class:"material-symbols-outlined text-[16px] text-fg-subtle self-center ml-2.5"},"search",-1)),z(m("input",{id:t.name,ref_key:"input",ref:I,"onUpdate:modelValue":a[0]||(a[0]=u=>n.value=u),type:"text",role:"combobox","aria-autocomplete":"list","aria-expanded":o(l).open.value,"aria-controls":o(k),"aria-activedescendant":o(l).open.value&&o(l).activeIndex.value>=0?o(l).optionId(o(l).activeIndex.value):void 0,"aria-invalid":S||void 0,"aria-describedby":c,disabled:t.disabled,readonly:t.read_only,placeholder:B.value,autocomplete:"off",spellcheck:"false",class:"rafa-control-input pl-2",onInput:E,onPaste:F,onKeydown:A,onBlur:K},null,40,ee),[[G,n.value]]),n.value&&!g.value?(r(),d("button",{key:1,type:"button",tabindex:"-1","aria-label":"Clear",class:"flex items-center justify-center w-7 shrink-0 text-fg-subtle hover:text-fg transition-colors duration-150",onMousedown:a[1]||(a[1]=H(()=>{},["prevent"])),onClick:O},[...a[3]||(a[3]=[m("span",{"aria-hidden":"true",class:"material-symbols-outlined text-[16px]"},"close",-1)])],32)):v("",!0),t.suffix?(r(),d("span",ae,[D(M,{text:t.suffix},null,8,["text"])])):v("",!0)],8,Z),o(l).open.value?(r(),$(W,{key:0,id:o(k),role:"listbox",anchor:w.value,"aria-label":t.label??t.name,onClose:a[2]||(a[2]=u=>o(l).closeList())},{default:q(()=>[(r(!0),d(J,null,Q(b.value,(u,p)=>(r(),d("div",{id:o(l).optionId(p),key:String(u.value),role:"option",class:"rafa-option","aria-selected":u.value===t.value,"data-active":o(l).activeIndex.value===p||void 0,onMouseenter:P=>o(l).setActive(p),onClick:P=>o(l).select(p)},[m("span",le,N(u.label),1),u.value===t.value?(r(),d("span",ne,"check")):v("",!0)],40,te))),128)),b.value.length?v("",!0):(r(),d("div",oe,N(V.value?B.value:"No results"),1))]),_:1},8,["id","anchor","aria-label"])):v("",!0)]),_:1},8,["name","label","description","error","required"]))}});export{de as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as v,l as y,b9 as x,i as g,N as k,o as r,c as n,b as o,u as d,n as i,e as u,a as f,L as w,t as p,f as B}from"./index-BR16ovZa.js";import{I as C}from"./InlineMarkdown-DZ6hRlXd.js";const $={class:"flex flex-col gap-1 w-full"},N=["id","role","checked","disabled","aria-readonly","aria-invalid","aria-describedby"],I={key:0,class:"material-symbols-outlined text-[14px]"},V=["id"],j=["id"],F=v({__name:"BooleanInput",props:{name:{},label:{},value:{type:[Boolean,null]},description:{},variant:{},disabled:{type:Boolean},read_only:{type:Boolean},error:{}},emits:["update:value"],setup(e,{emit:b}){const s=y(x,!1),t=e,h=b,l=g(!!t.value);k(()=>t.value,a=>{l.value=!!a});const c=B(()=>{let a="bg-sunken border-line-strong";return l.value?a="bg-accent-fill border-accent-fill text-on-fill":t.error?a="bg-sunken border-danger":t.disabled||(a+=" group-hover:border-fg-disabled"),t.disabled?a+" opacity-40":a}),m=a=>{if(t.read_only){a.target.checked=l.value;return}l.value=a.target.checked,h("update:value",l.value)};return(a,z)=>(r(),n("div",$,[o("label",{class:i(["group inline-flex items-center gap-2 min-h-5 w-fit",e.disabled?"cursor-not-allowed":"cursor-pointer"])},[o("input",{id:e.name,type:"checkbox",role:e.variant==="switch"?"switch":void 0,class:"peer sr-only",checked:l.value,disabled:e.disabled,"aria-readonly":e.read_only||void 0,"aria-invalid":e.error?!0:void 0,"aria-describedby":e.error?`${e.name}-error`:e.description&&!d(s)?`${e.name}-help`:void 0,onChange:m},null,40,N),e.variant==="switch"?(r(),n("span",{key:0,"aria-hidden":"true",class:i(["relative w-8 h-4 shrink-0 rounded-full border transition-colors duration-150 peer-focus-visible:shadow-focus-ring",c.value])},[o("span",{class:i(["absolute top-px left-px w-3 h-3 rounded-full transition-transform duration-150",l.value?"translate-x-4 bg-on-fill":"bg-fg-subtle"])},null,2)],2)):(r(),n("span",{key:1,"aria-hidden":"true",class:i(["flex items-center justify-center w-4 h-4 shrink-0 rounded-sm border transition-colors duration-150 peer-focus-visible:shadow-focus-ring",[c.value,{"border-dashed":e.read_only}]])},[l.value?(r(),n("span",I,"check")):u("",!0)],2)),o("span",{class:i(["text-xs select-none",[e.disabled?"text-fg-disabled":"text-fg-muted",{"sr-only":d(s)}]])},[f(w,{text:e.label},null,8,["text"])],2)],2),e.error?(r(),n("p",{key:0,id:`${e.name}-error`,role:"alert",class:i(["field-error pl-6",{"sr-only":d(s)}])},p(e.error),11,V)):e.description&&!d(s)?(r(),n("p",{key:1,id:`${e.name}-help`,class:"field-help pl-6"},[f(C,{text:e.description},null,8,["text"])],8,j)):u("",!0)]))}});export{F as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{B as y,J as T,an as E,am as p,al as G}from"./geometryScene-DBVxLCLP.js";function x(i,a=!1){const r=i[0].index!==null,m=new Set(Object.keys(i[0].attributes)),s=new Set(Object.keys(i[0].morphAttributes)),f={},t={},d=i[0].morphTargetsRelative,u=new y;let g=0;for(let e=0;e<i.length;++e){const n=i[e];let l=0;if(r!==(n.index!==null))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+e+". All geometries must have compatible attributes; make sure index attribute exists among all geometries, or in none of them."),null;for(const o in n.attributes){if(!m.has(o))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+e+'. All geometries must have compatible attributes; make sure "'+o+'" attribute exists among all geometries, or in none of them.'),null;f[o]===void 0&&(f[o]=[]),f[o].push(n.attributes[o]),l++}if(l!==m.size)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+e+". Make sure all geometries have the same number of attributes."),null;if(d!==n.morphTargetsRelative)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+e+". .morphTargetsRelative must be consistent throughout all geometries."),null;for(const o in n.morphAttributes){if(!s.has(o))return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+e+". .morphAttributes must be consistent throughout all geometries."),null;t[o]===void 0&&(t[o]=[]),t[o].push(n.morphAttributes[o])}if(a){let o;if(r)o=n.index.count;else if(n.attributes.position!==void 0)o=n.attributes.position.count;else return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed with geometry at index "+e+". The geometry must have either an index or a position attribute"),null;u.addGroup(g,o,e),g+=o}}if(r){let e=0;const n=[];for(let l=0;l<i.length;++l){const o=i[l].index;for(let c=0;c<o.count;++c)n.push(o.getX(c)+e);e+=i[l].attributes.position.count}u.setIndex(n)}for(const e in f){const n=b(f[e]);if(!n)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the "+e+" attribute."),null;u.setAttribute(e,n)}for(const e in t){const n=t[e][0].length;if(n===0)break;u.morphAttributes=u.morphAttributes||{},u.morphAttributes[e]=[];for(let l=0;l<n;++l){const o=[];for(let h=0;h<t[e].length;++h)o.push(t[e][h][l]);const c=b(o);if(!c)return console.error("THREE.BufferGeometryUtils: .mergeGeometries() failed while trying to merge the "+e+" morphAttribute."),null;u.morphAttributes[e].push(c)}}return u}function b(i){let a,r,m,s=-1,f=0;for(let g=0;g<i.length;++g){const e=i[g];if(a===void 0&&(a=e.array.constructor),a!==e.array.constructor)return console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.array must be of consistent array types across matching attributes."),null;if(r===void 0&&(r=e.itemSize),r!==e.itemSize)return console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.itemSize must be consistent across matching attributes."),null;if(m===void 0&&(m=e.normalized),m!==e.normalized)return console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.normalized must be consistent across matching attributes."),null;if(s===-1&&(s=e.gpuType),s!==e.gpuType)return console.error("THREE.BufferGeometryUtils: .mergeAttributes() failed. BufferAttribute.gpuType must be consistent across matching attributes."),null;f+=e.count*r}const t=new a(f),d=new T(t,r,m);let u=0;for(let g=0;g<i.length;++g){const e=i[g];if(e.isInterleavedBufferAttribute){const n=u/r;for(let l=0,o=e.count;l<o;l++)for(let c=0;c<r;c++){const h=e.getComponent(l,c);d.setComponent(l+n,c,h)}}else t.set(e.array,u);u+=e.count*r}return s!==void 0&&(d.gpuType=s),d}function B(i,a){if(a===E)return console.warn("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles."),i;if(a===p||a===G){let r=i.getIndex();if(r===null){const t=[],d=i.getAttribute("position");if(d!==void 0){for(let u=0;u<d.count;u++)t.push(u);i.setIndex(t),r=i.getIndex()}else return console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible."),i}const m=r.count-2,s=[];if(a===p)for(let t=1;t<=m;t++)s.push(r.getX(0)),s.push(r.getX(t)),s.push(r.getX(t+1));else for(let t=0;t<m;t++)t%2===0?(s.push(r.getX(t)),s.push(r.getX(t+1)),s.push(r.getX(t+2))):(s.push(r.getX(t+2)),s.push(r.getX(t+1)),s.push(r.getX(t)));s.length/3!==m&&console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.");const f=i.clone();return f.setIndex(s),f.clearGroups(),f}else return console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:",a),i}export{x as m,B as t};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{ba as Me,d as Q,N as H,o as i,c as d,i as T,bb as De,bc as Be,b0 as Ne,_ as Re,bd as ve,W as ge,n as U,b as y,t as h,e as g,p as C,x as K,w as O,h as $,f as c,be as He,bf as Z,af as pe,ae as I,bg as ee,bh as q,ab as Ue,bi as he,bj as ye,bk as Ke,bl as be,bm as we,bn as Oe,bo as qe,bp as ze,l as V,a8 as Fe,R as Pe,I as Ve,E as Ye,s as ie,a1 as Je,u as ue,a as We,F as E,g as Xe,O as Ge,aE as Qe,bq as Ze,br as Ie}from"./index-BR16ovZa.js";const et={"&":"&","<":"<",">":">",'"':""","'":"'"},j=e=>e.replace(/[&<>"']/g,t=>et[t]),tt=/^(https?:\/\/|mailto:)/i;function ce(e){const t=(e??"").trim();return tt.test(t)?t:null}const de=(e,t)=>`<a href="${j(e)}" target="_blank" rel="noopener noreferrer nofollow">${t}</a>`,nt=new Me({gfm:!0,breaks:!0,async:!1,renderer:{html({text:e}){return j(e)},link(e){const t=this.parser.parseInline(e.tokens),n=ce(e.href);return n?de(n,t):t},image({href:e,text:t}){const n=ce(e),a=j(t||e||"");return n?de(n,a||j(n)):a}}}),at=/(```[\s\S]*?(?:```|$)|`[^`\n]*`)|\$\$([\s\S]+?)\$\$|\\\[([\s\S]+?)\\\]|\\\(([\s\S]+?)\\\)|\$(?=[^\s`])([^$\n`]*?[^\s`])\$(?!\d)/g;function st(e){const t=[],n=e.replace(at,(o,l,r,s,u,v)=>{if(l!==void 0)return o;const p=r!==void 0||s!==void 0;t.push({source:(r??s??u??v??"").trim(),display:p});const b=`CHATMATH${t.length-1}X`;return p?`
|
|
2
|
+
|
|
3
|
+
${b}
|
|
4
|
+
|
|
5
|
+
`:b});let a;try{a=nt.parse(n)}catch{a=`<p>${j(n)}</p>`}return{html:a,math:t}}const ot=/CHATMATH(\d+)X/g,lt=["innerHTML"],rt=Q({__name:"ChatMarkdown",props:{content:{}},setup(e){const t=e,n=T("");let a=0;function o(r,s){if(!r)return s.display?`<pre>${j(s.source)}</pre>`:`<code>${j(s.source)}</code>`;try{const u=r.renderToString(s.source,{displayMode:s.display,throwOnError:!1,maxSize:10,maxExpand:200});return s.display?`<div class="katex-display-wrapper">${u}</div>`:u}catch{return`<code>${j(s.source)}</code>`}}async function l(){const r=++a,s=st(t.content);let u=null;if(s.math.length){try{u=await De()}catch{u=null}if(r!==a)return}n.value=Be(Ne(s.html),ot,s.math.map(v=>o(u,v)))}return H(()=>t.content,l,{immediate:!0}),(r,s)=>(i(),d("div",{class:"rafa-prose rafa-prose-compact rafa-chat-text rafa-text-box",innerHTML:n.value},null,8,lt))}}),ke=Re(rt,[["__scopeId","data-v-18e5088f"]]),S=e=>typeof e=="string"&&e?e:null,fe=(e,t)=>typeof e=="number"&&Number.isFinite(e)&&e>0?Math.floor(e):t,it=["user","assistant"],ut=["done","pending","stopped","failed"];function ct(e){if(!e||typeof e!="object")return null;const t=S(e.label),n=e.params;return!t||!n||typeof n!="object"||Array.isArray(n)||!Object.keys(n).length?null:{label:t,params:n}}function G(e){return!e||typeof e!="object"||!it.includes(e.role)?null:{id:S(e.id),role:e.role,content:typeof e.content=="string"?e.content:"",at:S(e.at),status:ut.includes(e.status)?e.status:"done",note:S(e.note),suggestion:ct(e.suggestion),author:S(e.author)}}function dt(e){if(!e||typeof e!="object"||!S(e.entity_id)||!S(e.chat))return null;const t=Array.isArray(e.messages)?e.messages.map(G).filter(n=>n!==null):[];return{entity_id:e.entity_id,chat:e.chat,label:S(e.label)??e.chat,messages:t,answering:e.answering===!0,job_id:S(e.job_id),can_send:e.can_send===!0,trimmed:e.trimmed===!0,max_messages:fe(e.max_messages,100),max_message_length:fe(e.max_message_length,4e3)}}function xe(e,t=0){const n=G(e?.question),a=G(e?.answer),o=ve(e?.job,t);return n&&a&&o?{question:n,answer:a,job:o}:null}function me(e){if(!e||e.type!=="ChatReply")return null;const t=e.data?.text;return typeof t=="string"?t:null}function ft(e){const t=[],n=(a,o)=>{for(const[l,r]of Object.entries(a)){const s=o?`${o}.${l}`:l;r&&typeof r=="object"&&!Array.isArray(r)&&Object.keys(r).length?n(r,s):t.push([s,r])}};return n(e.params,""),t}function mt(e){return`Older messages were removed: this chat keeps the last ${e.toLocaleString("en-US")}.`}function vt(e,t){return e<t*.9?null:`${e.toLocaleString("en-US")} / ${t.toLocaleString("en-US")}`}function gt(e){return e.key==="Enter"&&!e.shiftKey&&!e.isComposing&&!e.altKey&&!e.ctrlKey&&!e.metaKey}function pt(e){switch(e.status){case"stopped":return e.note??"Stopped.";case"failed":return e.note??"No answer.";default:return e.note}}function ht(e,t){return e.role==="assistant"?"Assistant":t&&e.author?e.author:"You"}function yt(e,t=new Date){if(!e)return null;const n=new Date(e);if(Number.isNaN(n.getTime()))return null;const a=n.toLocaleTimeString("en-US",{hour:"2-digit",minute:"2-digit",hour12:!1});return n.toDateString()===t.toDateString()?a:`${n.toLocaleDateString("en-US",{month:"short",day:"numeric"})}, ${a}`}function bt(e){return e.blocked?"This chat is read-only now.":e.canSend?e.editLockedBy:e.permission==="edit"?"You can read this conversation. Editors can send messages.":e.permission==="manage"?"You can read this conversation. Project admins can send messages.":`You can read this conversation. Sending needs the ${e.permission} permission.`}const wt=["aria-busy","data-role","data-status"],kt={class:"flex items-center gap-2 min-w-0"},xt=["datetime"],$t=["aria-label","title"],St={class:"material-symbols-outlined text-[16px]","aria-hidden":"true"},_t={key:1,class:"m-0 text-xs leading-normal text-fg whitespace-pre-wrap [overflow-wrap:anywhere]"},Tt={key:2,class:"m-0 label !text-link",role:"status"},jt={key:4,class:"flex flex-wrap items-center gap-2 pt-1"},Ct=Q({__name:"ChatMessage",props:{message:{},streaming:{default:null},showAuthors:{type:Boolean,default:!1},canRetry:{type:Boolean,default:!1},applyDenial:{default:null}},emits:["retry","apply"],setup(e,{emit:t}){const n=e,a=t,o=c(()=>n.message.status==="pending"),l=c(()=>o.value?n.streaming??"":n.message.content),r=c(()=>ht(n.message,n.showAuthors)),s=c(()=>yt(n.message.at)),u=c(()=>pt(n.message)),v=c(()=>n.message.role==="assistant"),p=T(null);let b=null;async function W(){try{await navigator.clipboard.writeText(l.value),p.value="ok"}catch{p.value="failed"}b&&clearTimeout(b),b=setTimeout(()=>p.value=null,2e3)}ge(()=>{b&&clearTimeout(b)});const A=c(()=>p.value==="ok"?"Copied":p.value==="failed"?"Cannot copy to the clipboard":"Copy message");return(B,_)=>(i(),d("article",{class:U(["flex flex-col gap-1 min-w-0 rounded px-3 py-2",v.value?"bg-transparent":"bg-elevated border border-line-subtle"]),"aria-busy":o.value||void 0,"data-role":e.message.role,"data-status":e.message.status},[y("header",kt,[y("span",{class:U(["label min-w-0 truncate",{"!text-link":v.value}])},h(r.value),3),s.value&&e.message.at?(i(),d("time",{key:0,class:"font-mono text-[11px] text-fg-subtle shrink-0",datetime:e.message.at},h(s.value),9,xt)):g("",!0),l.value?(i(),d("button",{key:1,type:"button",class:"ml-auto shrink-0 w-6 h-6 flex items-center justify-center rounded text-fg-subtle hover:text-fg hover:bg-elevated","aria-label":`${A.value}: ${r.value}${s.value?`, ${s.value}`:""}`,title:A.value,onClick:W},[y("span",St,h(p.value==="ok"?"check":"content_copy"),1)],8,$t)):g("",!0)]),v.value&&l.value?(i(),C(ke,{key:0,content:l.value},null,8,["content"])):l.value?(i(),d("p",_t,h(l.value),1)):g("",!0),o.value?(i(),d("p",Tt,"Writing…")):u.value?(i(),d("p",{key:3,class:U(["m-0 text-[11px] leading-4",e.message.status==="failed"?"text-danger":"text-fg-muted"])},h(u.value),3)):g("",!0),e.message.suggestion&&e.message.status==="done"||e.canRetry&&!o.value?(i(),d("div",jt,[e.message.suggestion&&e.message.status==="done"?(i(),C(K,{key:0,class:"!normal-case !tracking-normal",variant:"secondary",size:"sm",icon:"edit_note",disabled:!!e.applyDenial,title:e.applyDenial??`Set the inputs: ${e.message.suggestion.label}`,onClick:_[0]||(_[0]=x=>a("apply"))},{default:O(()=>[$(h(e.message.suggestion.label),1)]),_:1},8,["disabled","title"])):g("",!0),e.canRetry&&!o.value?(i(),C(K,{key:1,variant:"ghost",size:"sm",icon:"refresh",onClick:_[1]||(_[1]=x=>a("retry"))},{default:O(()=>[..._[2]||(_[2]=[$("Ask again",-1)])]),_:1})):g("",!0)])):g("",!0)],10,wt))}}),Y=Ke(new Map),$e=(e,t)=>`${e}|${t}`,J=(e,t)=>`/entities/${encodeURIComponent(e)}/chats/${encodeURIComponent(t)}`,te=()=>typeof performance>"u"?Date.now():performance.now();function At(e,t){return Y.get($e(e,t))??null}function D(e,t){const n=$e(e,t);return Y.has(n)||Y.set(n,{conversation:null,loading:!1,error:null,sending:!1}),Y.get(n)}async function M(e,t){const n=D(e,t);n.loading=!n.conversation;try{const a=dt((await q.get(J(e,t))).data);if(!a)throw new Error("Not a conversation");return n.conversation=a,n.error=null,a.job_id&&!I.has(a.job_id)&&Lt(e,t,a.job_id),a}catch(a){return n.error=ye(a),null}finally{n.loading=!1}}async function Lt(e,t,n){try{const a=ve((await q.get(`/jobs/${n}`)).data,te());a&&be(a,{notify:!1})}catch{}await we(n),await M(e,t)}function Et(e){const t=e?.job_id;if(!t)return null;const n=I.get(t);return n?me(n.partial)??me(n.result)??"":null}function Mt(e){const t=e?.job_id;return!!t&&pe(I.get(t)??{status:"queued"})}function ne(e,t,n,a){const o=ye(n),l=Oe(n),r=l===409?qe(n):null;return r&&ze(e,r),l===409&&M(e,t),Z(l===400?"warning":"error",`${a}: ${o}`),l!==400&&he.notify(l===409||l===429?"warning":"error",a,o),{ok:!1,error:o}}async function Se(e,t,n,a){const o=xe(n,te()),l=D(e,t);if(!o){await M(e,t);return}const r=l.conversation;if(r){const s=r.messages.filter(u=>u.id!==o.answer.id&&u.id!==o.question.id);!a&&s[s.length-1]?.role==="assistant"&&s.pop(),l.conversation={...r,messages:a?[...s,o.question,o.answer]:[...s,o.answer],answering:pe(o.job),job_id:o.job.id}}be(o.job,{notify:!1}),await we(o.job.id),await M(e,t)}async function Dt(e,t,n){const a=n.trim();if(!a)return{ok:!1,error:"Type a message first."};const o=D(e,t);if(!await ee(e))return{ok:!1,error:"Someone else is editing this entity."};o.sending=!0;try{const l=await q.post(`${J(e,t)}/messages`,{content:a});return Se(e,t,l.data,xe(l.data)?.question??null),{ok:!0}}catch(l){return ne(e,t,l,"Message not sent")}finally{o.sending=!1}}async function Bt(e,t){if(!await ee(e))return{ok:!1,error:"Someone else is editing this entity."};const n=D(e,t);n.sending=!0;try{const a=await q.post(`${J(e,t)}/retry`);return Se(e,t,a.data,null),{ok:!0}}catch(a){return ne(e,t,a,"Not asked again")}finally{n.sending=!1}}async function Nt(e,t){const n=D(e,t).conversation?.job_id;n&&await Ue(n)}async function Rt(e,t){const n=D(e,t).conversation?.label??"chat";if(!await he.confirm({title:"Clear the conversation?",body:`Every message of ${n} is removed, for everyone who can open this entity. This cannot be undone.`,confirmLabel:"Clear",danger:!0})||!await ee(e))return!1;try{return await q.delete(`${J(e,t)}/messages`),Z("info",`Cleared ${n}`),await M(e,t),!0}catch(o){return ne(e,t,o,"Not cleared"),!1}}function Ht(e){const t=ft(e);He(t,{undoKey:`chat-suggestion-${te()}`}),Z("info",`Applied: ${e.label}`)}const Ut=["aria-labelledby"],Kt={class:"flex items-center gap-2 min-w-0"},Ot=["id"],qt={key:0,class:"field-help -mt-1 m-0"},zt=["aria-labelledby"],Ft={key:0,class:"m-0 field-help text-center"},Pt={key:1,class:"px-3 py-2 min-w-0","data-first-message":""},Vt={key:2,class:"m-0 label text-center py-2",role:"status"},Yt={key:3,class:"m-0 field-error text-center py-2",role:"alert"},Jt={key:4,class:"m-0 field-help text-center py-2"},Wt=["data-invalid"],Xt=["id","placeholder","aria-label","aria-describedby","aria-invalid"],Gt={class:"flex items-center gap-2 min-w-0"},Qt=["id","role"],Zt={key:2,class:"m-0 field-help"},tn=Q({__name:"ChatPanel",props:{name:{},label:{},description:{default:null},first_message:{default:null},placeholder:{default:null},permission:{default:"edit"},max_message_length:{default:4e3},disabled:{type:Boolean},read_only:{type:Boolean}},setup(e){const t=e,n=V(Fe,T(null)),a=V(Pe,null),o=V(Ve,null),l=V(Ye,null),r=c(()=>n.value?At(n.value,t.name):null),s=c(()=>r.value?.conversation??null),u=c(()=>s.value?.messages??[]),v=c(()=>!!s.value?.answering),p=c(()=>Mt(s.value)),b=c(()=>Et(s.value)),W=c(()=>Ze(Ie.value)),A=c(()=>bt({canSend:s.value?.can_send??!1,permission:t.permission,editLockedBy:l?.value?.kind==="other"?l.value.text:null,blocked:t.disabled||t.read_only})),B=c(()=>!!s.value&&!A.value),_=c(()=>a?.value??(l?.value?.kind==="other"?l.value.text:null)??o?.value?.text??null),x=T(""),w=T(null),ae=c(()=>vt(x.value.trim().length,t.max_message_length)),N=c(()=>x.value.trim().length>t.max_message_length),z=T(null),R=T(null),_e=c(()=>`${t.name}-chat-input`),X=c(()=>`${t.name}-chat-label`),se=c(()=>`${t.name}-chat-help`);async function oe(){if(!n.value||!B.value||v.value||r.value?.sending)return;if(N.value){w.value=`The message has ${x.value.trim().length.toLocaleString("en-US")} characters; at most ${t.max_message_length.toLocaleString("en-US")} are allowed. Shorten it.`;return}const f=await Dt(n.value,t.name,x.value);f.ok?(x.value="",w.value=null,F.value=!0):w.value=f.error}function Te(f){gt(f)&&(f.preventDefault(),oe())}async function je(){n.value&&(await Nt(n.value,t.name),z.value?.focus())}async function Ce(){if(!n.value)return;const f=await Bt(n.value,t.name);w.value=f.ok?null:f.error,F.value=!0}async function Ae(){n.value&&await Rt(n.value,t.name)&&(w.value=null,await ie(),z.value?.focus())}const Le=c(()=>{const f=u.value[u.value.length-1];return f&&f.role==="assistant"?f.id:null}),F=T(!0);function Ee(){const f=R.value;f&&(F.value=f.scrollHeight-f.scrollTop-f.clientHeight<24)}H([()=>u.value.length,b],async()=>{F.value&&(await ie(),R.value&&(R.value.scrollTop=R.value.scrollHeight))});let L=null;async function P(){n.value&&await M(n.value,t.name)}function le(){L&&clearTimeout(L),L=null,v.value&&!s.value?.job_id&&(L=setTimeout(async()=>{await P(),le()},3e3))}H([v,()=>s.value?.job_id],le),H(n,P);const re=()=>{P()};return Je(()=>{P(),window.addEventListener("focus",re)}),ge(()=>{window.removeEventListener("focus",re),L&&clearTimeout(L)}),H(p,(f,m)=>{m&&!f&&document.activeElement===document.body&&z.value?.focus()}),(f,m)=>(i(),d("section",{class:"flex flex-col gap-2 w-full min-w-0","aria-labelledby":X.value,"data-chat":""},[y("div",Kt,[y("span",{id:X.value,class:"label min-w-0 truncate"},h(e.label),9,Ot),B.value&&u.value.length?(i(),C(K,{key:0,class:"ml-auto -my-1",variant:"ghost",size:"sm",icon:"delete_sweep",disabled:v.value,title:v.value?"Stop the answer first":void 0,"aria-label":`Clear ${e.label}`,onClick:Ae},{default:O(()=>[...m[2]||(m[2]=[$("Clear",-1)])]),_:1},8,["disabled","title","aria-label"])):g("",!0)]),e.description?(i(),d("p",qt,h(e.description),1)):g("",!0),y("div",{ref_key:"log",ref:R,role:"log","aria-live":"polite","aria-labelledby":X.value,tabindex:"0",class:"flex flex-col gap-2 max-h-[420px] min-h-24 overflow-y-auto rounded-md border border-line bg-sunken p-2 focus-visible:outline-none focus-visible:shadow-[var(--shadow-focus)]",onScroll:Ee},[s.value?.trimmed?(i(),d("p",Ft,h(ue(mt)(s.value.max_messages)),1)):g("",!0),e.first_message?(i(),d("div",Pt,[m[3]||(m[3]=y("span",{class:"label !text-link"},"Assistant",-1)),We(ke,{content:e.first_message},null,8,["content"])])):g("",!0),(i(!0),d(E,null,Xe(u.value,k=>(i(),C(Ct,{key:k.id??k.at??"",message:k,streaming:k.status==="pending"&&k.id===u.value[u.value.length-1]?.id?b.value:null,"show-authors":W.value,"can-retry":B.value&&!v.value&&k.id===Le.value,"apply-denial":_.value,onRetry:Ce,onApply:It=>k.suggestion&&ue(Ht)(k.suggestion)},null,8,["message","streaming","show-authors","can-retry","apply-denial","onApply"]))),128)),r.value?.loading?(i(),d("p",Vt,"Loading…")):r.value?.error&&!s.value?(i(),d("p",Yt,h(r.value.error),1)):s.value&&!u.value.length&&!e.first_message?(i(),d("p",Jt,"No messages yet.")):g("",!0)],40,zt),B.value?(i(),d(E,{key:1},[y("div",{class:"rafa-control rafa-control-multiline","data-invalid":N.value||!!w.value||void 0},[Ge(y("textarea",{id:_e.value,ref_key:"box",ref:z,"onUpdate:modelValue":m[0]||(m[0]=k=>x.value=k),rows:"2",placeholder:e.placeholder??"Ask a question","aria-label":`Message to ${e.label}`,"aria-describedby":se.value,"aria-invalid":N.value||void 0,class:"rafa-control-input py-2 leading-normal resize-y min-h-14 max-h-60",onKeydown:Te,onInput:m[1]||(m[1]=k=>w.value=null)},null,40,Xt),[[Qe,x.value]])],8,Wt),y("div",Gt,[y("p",{id:se.value,class:U(["m-0 min-w-0 flex-1",w.value?"field-error":"field-help"]),role:w.value?"alert":void 0},[w.value?(i(),d(E,{key:0},[$(h(w.value),1)],64)):v.value&&!p.value?(i(),d(E,{key:1},[$("Someone else's question is being answered.")],64)):(i(),d(E,{key:2},[m[5]||(m[5]=$("Enter to send, Shift+Enter for a new line",-1)),ae.value?(i(),d(E,{key:0},[m[4]||(m[4]=$(" · ",-1)),y("span",{class:U(["font-mono",{"text-danger":N.value}])},h(ae.value),3)],64)):g("",!0)],64))],10,Qt),p.value?(i(),C(K,{key:0,variant:"secondary",size:"sm",icon:"stop","aria-label":`Stop the answer of ${e.label}`,onClick:je},{default:O(()=>[...m[6]||(m[6]=[$("Stop",-1)])]),_:1},8,["aria-label"])):(i(),C(K,{key:1,variant:"primary",size:"sm",icon:"send",loading:r.value?.sending,disabled:!x.value.trim()||v.value||N.value,"aria-label":`Send the message to ${e.label}`,onClick:oe},{default:O(()=>[...m[7]||(m[7]=[$("Send",-1)])]),_:1},8,["loading","disabled","aria-label"]))])],64)):s.value&&A.value?(i(),d("p",Zt,h(A.value),1)):g("",!0)],8,Ut))}});export{tn as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.rafa-chat-text[data-v-18e5088f] .katex{font-size:1.05em}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as C,a1 as O,W as $,N as x,bs as I,o as B,c as D,a as N,u as o,bt as k,bu as L,U as V,bv as j,bw as A,f as s,a4 as R,a5 as c,bx as S,by as U,V as _,bz as z,i as p,bA as M,bB as T}from"./index-BR16ovZa.js";const h=C({__name:"ChildrenView",props:{label:{default:"Children"},display:{default:"cards"},child_types:{default:()=>[]}},setup(b){const n=b,l=s(()=>R.value),i=s(()=>l.value?c.value.filter(e=>e.parent_id===l.value.id):[]),y=s(()=>Object.values(S.value).map(e=>({name:e.name,label:e.label,summary:e.summary??[]}))),m=s(()=>U(l.value,"edit")?n.child_types.map(e=>({name:e,label:_(e)})):[]),f=s(()=>Object.fromEntries(i.value.map(e=>[e.id,z(e.id)]))),r=p(null),u=p(typeof IntersectionObserver>"u");let d=null;O(()=>{u.value||!r.value||(d=new IntersectionObserver(e=>{e.some(a=>a.isIntersecting)&&(u.value=!0)}),d.observe(r.value))}),$(()=>d?.disconnect()),x([i,u],([e,a])=>{a&&I(e)},{immediate:!0});const v=p(null),w=e=>{const a=c.value.find(t=>t.id===e.id);return!!a&&M(a)},E=e=>{l.value&&T(e,l.value.id)};return(e,a)=>(B(),D("div",{ref_key:"root",ref:r,class:"h-full overflow-auto","data-children-view":""},[N(A,{entities:i.value,types:y.value,display:n.display==="table"?"table":"cards",values:f.value,"create-types":m.value,"can-duplicate":w,"rename-save":(t,g)=>o(j)(t,g),"renaming-id":v.value,label:l.value?`${n.label} of ${l.value.name}`:n.label,"empty-text":m.value.length?`No ${n.label.toLowerCase()} yet. Add one to begin.`:`No ${n.label.toLowerCase()} yet.`,onOpen:a[0]||(a[0]=t=>o(V)(t)),onCreate:E,onDuplicate:a[1]||(a[1]=t=>o(L)(t)),onDelete:a[2]||(a[2]=t=>o(k)(t)),onStartRename:a[3]||(a[3]=t=>v.value=t),onRenameDone:a[4]||(a[4]=t=>v.value=null)},null,8,["entities","types","display","values","create-types","rename-save","renaming-id","label","empty-text"])],512))}});export{h as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as k}from"./FieldShell.vue_vue_type_script_setup_true_lang-D1Iio9Vx.js";import{d as B,i as f,N as I,o as q,p as A,w as E,b as u,n as L,Q as z,f as b}from"./index-BR16ovZa.js";import"./InlineMarkdown-DZ6hRlXd.js";const F=["data-invalid","data-disabled","data-readonly"],H=["title"],N=["id","value","disabled"],T=["id","value","disabled","readonly","aria-invalid","aria-describedby"],p="#000000",R=B({__name:"ColorInput",props:{name:{},label:{},value:{},description:{},disabled:{type:Boolean},read_only:{type:Boolean},required:{type:Boolean},error:{}},emits:["update:value"],setup(e,{emit:y}){const c=/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/;function r(l){const a=l.trim().toLowerCase();if(/^#[0-9a-f]{3}$/.test(a)){const[,n,d,h]=a;return`#${n}${n}${d}${d}${h}${h}`}return a}const t=e,m=y,s=f(t.value?r(t.value):p),o=f(t.value?r(t.value):""),i=f(!1);I(()=>t.value,l=>{s.value=l?r(l):p,o.value=l?r(l):"",i.value=!1});const w=b(()=>c.test(o.value)?r(o.value):s.value),x=b(()=>t.error||(i.value?"Enter a valid hex colour (#ff0000 or #f00).":null)),v=b(()=>t.disabled||t.read_only),$=l=>{const a=l.target.value.toLowerCase();s.value=a,o.value=a,i.value=!1,m("update:value",a)},g=l=>{const a=l.target.value;if(o.value=a,c.test(a)){const n=r(a);s.value=n,i.value=!1,m("update:value",n)}},C=()=>{i.value=o.value.length>0&&!c.test(o.value)};return(l,a)=>(q(),A(k,{name:e.name,label:e.label,description:e.description,error:x.value,required:e.required,"for-id":`${e.name}-text`},{default:E(({describedBy:n,invalid:d})=>[u("div",{class:"rafa-control","data-invalid":d||void 0,"data-disabled":e.disabled||void 0,"data-readonly":e.read_only&&!e.disabled||void 0},[u("label",{class:L(["relative self-center ml-1.5 w-5 h-5 shrink-0 rounded-sm border border-line-strong overflow-hidden",v.value?"cursor-not-allowed opacity-60":"cursor-pointer"]),title:v.value?void 0:"Choose colour"},[u("span",{class:"absolute inset-0",style:z({background:w.value})},null,4),u("input",{id:`${e.name}-picker`,type:"color",value:s.value,disabled:v.value,"aria-label":"Choose colour",class:"absolute inset-0 w-full h-full opacity-0 cursor-pointer disabled:cursor-not-allowed",onInput:$},null,40,N)],10,H),u("input",{id:`${e.name}-text`,type:"text",value:o.value,disabled:e.disabled,readonly:e.read_only,placeholder:"#rrggbb",maxlength:"7",spellcheck:"false",autocomplete:"off","aria-invalid":d||void 0,"aria-describedby":n,class:"rafa-control-input font-mono pl-2",onInput:g,onChange:C},null,40,T)],8,F)]),_:1},8,["name","label","description","error","required","for-id"]))}});export{R as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{d as o,o as a,c as n,r as c,Q as r,f as p}from"./index-BR16ovZa.js";const i=o({__name:"Column",props:{width:{},gap:{},children:{}},setup(l){const t=l,s=p(()=>{const e={gap:`${(t.gap??4)*4}px`};return t.width?e.flex=`0 0 calc(${t.width/12*100}% - 16px)`:e.flex="1",e});return(e,d)=>(a(),n("div",{class:"flex flex-col min-w-0",style:r(s.value)},[c(e.$slots,"default")],4))}});export{i as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
input[type=date][data-v-732b2199]::-webkit-calendar-picker-indicator{opacity:.55;cursor:pointer}input[type=date][data-v-732b2199]::-webkit-calendar-picker-indicator:hover{opacity:.9}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as c}from"./FieldShell.vue_vue_type_script_setup_true_lang-D1Iio9Vx.js";import{d as m,i as v,N as b,o as y,p as f,w as x,b as t,_ as h}from"./index-BR16ovZa.js";import"./InlineMarkdown-DZ6hRlXd.js";const B=["data-invalid","data-disabled","data-readonly"],p=["id","value","min","max","disabled","readonly","aria-invalid","aria-describedby"],g=m({__name:"DateInput",props:{name:{},label:{},value:{},description:{},min:{},max:{},disabled:{type:Boolean},read_only:{type:Boolean},required:{type:Boolean},error:{}},emits:["update:value"],setup(a,{emit:o}){const i=a,r=o,e=v(i.value??"");b(()=>i.value,d=>{e.value=d??""});const s=d=>{e.value=d.target.value,r("update:value",e.value||null)};return(d,l)=>(y(),f(c,{name:a.name,label:a.label,description:a.description,error:a.error,required:a.required},{default:x(({describedBy:u,invalid:n})=>[t("div",{class:"rafa-control","data-invalid":n||void 0,"data-disabled":a.disabled||void 0,"data-readonly":a.read_only&&!a.disabled||void 0},[l[0]||(l[0]=t("span",{"aria-hidden":"true",class:"material-symbols-outlined text-[16px] text-fg-subtle self-center ml-2.5"}," calendar_today ",-1)),t("input",{id:a.name,type:"date",value:e.value,min:a.min??void 0,max:a.max??void 0,disabled:a.disabled,readonly:a.read_only,"aria-invalid":n||void 0,"aria-describedby":u,class:"rafa-control-input font-mono pl-2",onChange:s},null,40,p)],8,B)]),_:1},8,["name","label","description","error","required"]))}}),I=h(g,[["__scopeId","data-v-732b2199"]]);export{I as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
select.rafa-control-input option[data-v-dfb2c9e9]{background:var(--color-bg-elevated);color:var(--color-text-primary)}
|