aggregate_api 1.0.0__py3-none-any.whl

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.
Files changed (63) hide show
  1. aggregate_api/__init__.py +41 -0
  2. aggregate_api/__main__.py +154 -0
  3. aggregate_api/app.py +206 -0
  4. aggregate_api/audit.py +395 -0
  5. aggregate_api/bounds.py +331 -0
  6. aggregate_api/cache.py +319 -0
  7. aggregate_api/capability.py +823 -0
  8. aggregate_api/completion.py +219 -0
  9. aggregate_api/config.py +363 -0
  10. aggregate_api/cors.py +61 -0
  11. aggregate_api/examples.py +620 -0
  12. aggregate_api/layer_pricing.py +840 -0
  13. aggregate_api/library.py +94 -0
  14. aggregate_api/library_notes.py +96 -0
  15. aggregate_api/models.py +1407 -0
  16. aggregate_api/net.py +281 -0
  17. aggregate_api/pnl.py +101 -0
  18. aggregate_api/pricing.py +778 -0
  19. aggregate_api/resources.py +257 -0
  20. aggregate_api/routes/__init__.py +8 -0
  21. aggregate_api/routes/decl.py +327 -0
  22. aggregate_api/routes/examples.py +82 -0
  23. aggregate_api/routes/meta.py +282 -0
  24. aggregate_api/routes/objects.py +4119 -0
  25. aggregate_api/routes/status.py +466 -0
  26. aggregate_api/serializers.py +565 -0
  27. aggregate_api/sessions.py +353 -0
  28. aggregate_api/static/aggregate-api-logo-512.png +0 -0
  29. aggregate_api/static/aggregate-api-logo.png +0 -0
  30. aggregate_api/static/aggregate-api-trim.png +0 -0
  31. aggregate_api/static/android-chrome-192x192.png +0 -0
  32. aggregate_api/static/android-chrome-512x512.png +0 -0
  33. aggregate_api/static/apple-touch-icon.png +0 -0
  34. aggregate_api/static/assets/bootstrap-icons-BeopsB42.woff +0 -0
  35. aggregate_api/static/assets/bootstrap-icons-mSm7cUeB.woff2 +0 -0
  36. aggregate_api/static/assets/bootstrap-ohb1VZ53.js +5 -0
  37. aggregate_api/static/assets/codemirror-h62DHGGa.js +14 -0
  38. aggregate_api/static/assets/csv-grid.worker-DKzHGXac.js +4 -0
  39. aggregate_api/static/assets/echarts-B7o9sc00.js +40 -0
  40. aggregate_api/static/assets/echarts-gl-DG1Uf6wE.js +4282 -0
  41. aggregate_api/static/assets/lite-CUlcD8p4.css +1 -0
  42. aggregate_api/static/assets/lite-Dd2TnT4M.js +1 -0
  43. aggregate_api/static/assets/main-Bxhxa55v.css +9 -0
  44. aggregate_api/static/assets/main-CmoEiPit.js +9 -0
  45. aggregate_api/static/assets/tables-BHCF7qIF.js +8 -0
  46. aggregate_api/static/assets/tables-CxvajLr7.css +1 -0
  47. aggregate_api/static/favicon-16x16.png +0 -0
  48. aggregate_api/static/favicon-32x32.png +0 -0
  49. aggregate_api/static/favicon.ico +0 -0
  50. aggregate_api/static/index.html +912 -0
  51. aggregate_api/static/lite.html +83 -0
  52. aggregate_api/static/logo.png +0 -0
  53. aggregate_api/static/site.webmanifest +14 -0
  54. aggregate_api/static/sw.js +78 -0
  55. aggregate_api/status.py +536 -0
  56. aggregate_api/status_page.html +546 -0
  57. aggregate_api/tables.py +316 -0
  58. aggregate_api-1.0.0.dist-info/METADATA +187 -0
  59. aggregate_api-1.0.0.dist-info/RECORD +63 -0
  60. aggregate_api-1.0.0.dist-info/WHEEL +5 -0
  61. aggregate_api-1.0.0.dist-info/entry_points.txt +2 -0
  62. aggregate_api-1.0.0.dist-info/licenses/LICENSE +28 -0
  63. aggregate_api-1.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,83 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <meta name="description" content="aggregate Loss Lab (aLL), phone edition: pick an example, press Build, read the distribution.">
7
+ <meta name="theme-color" content="#ffffff">
8
+ <title>aggregate Loss Lab</title>
9
+
10
+ <link rel="icon" type="image/x-icon" href="./favicon.ico">
11
+ <link rel="icon" type="image/png" sizes="32x32" href="./favicon-32x32.png">
12
+ <link rel="icon" type="image/png" sizes="16x16" href="./favicon-16x16.png">
13
+ <link rel="apple-touch-icon" href="./apple-touch-icon.png">
14
+ <link rel="manifest" href="./site.webmanifest">
15
+ <script type="module" crossorigin src="./assets/lite-Dd2TnT4M.js"></script>
16
+ <link rel="modulepreload" crossorigin href="./assets/echarts-B7o9sc00.js">
17
+ <link rel="modulepreload" crossorigin href="./assets/tables-BHCF7qIF.js">
18
+ <link rel="stylesheet" crossorigin href="./assets/tables-CxvajLr7.css">
19
+ <link rel="stylesheet" crossorigin href="./assets/lite-CUlcD8p4.css">
20
+ </head>
21
+ <body>
22
+
23
+ <!-- The lite shell: dev/prototypes/phone.html frame 1 is the drawing this
24
+ markup realizes. A phone user never types DecL, so the chip row is the
25
+ primary control, the program is read-only, and Build is the one verb.
26
+ The full app is one explicit link away (?full=1). -->
27
+
28
+ <header class="p-hdr">
29
+ <div>
30
+ <span class="p-brand">aggregate Loss Lab</span>
31
+ <span class="p-kicker">description to distribution</span>
32
+ </div>
33
+ <!-- Filled from /v1/meta; blank until it answers, and blank if it does
34
+ not, since a wrong version is worse than none. -->
35
+ <span class="p-vers" id="lite-versions"></span>
36
+ </header>
37
+
38
+ <div class="p-sect">Pick an example</div>
39
+ <div class="p-chips" id="lite-chips"></div>
40
+
41
+ <!-- The program, displayed rather than edited, collapsed to its opening
42
+ lines. A tap toggles the rest; it stays read-only either way. -->
43
+ <div class="p-prog" id="lite-prog" hidden>
44
+ <pre id="lite-prog-text"></pre>
45
+ <div class="hint" id="lite-prog-hint">DecL program from the library · tap to expand</div>
46
+ </div>
47
+
48
+ <button class="p-build" id="lite-build" disabled>Build</button>
49
+
50
+ <!-- The built state: prototype frame 2. Hidden until the first build. -->
51
+ <section id="lite-built" hidden>
52
+ <div class="p-strip" id="lite-strip"></div>
53
+ <div class="p-tiles" id="lite-tiles"></div>
54
+ <!-- The object's own picture: the same chart document and adapter the
55
+ full app's Overview Plot leaf uses. The control apparatus below
56
+ the canvas is hidden by lite.css (ruled 2026-09-28): the chart
57
+ ships the emitter's default scales. -->
58
+ <div class="p-chart" id="lite-chart" hidden>
59
+ <div id="lite-chart-host"></div>
60
+ </div>
61
+ <!-- One static table: the return-period ladder, rendered by the
62
+ walker. The interactive grid never boards the phone. -->
63
+ <div class="p-table" id="lite-table" hidden></div>
64
+ </section>
65
+
66
+ <footer class="p-full">aLL is built for a wide screen. On a laptop?
67
+ <a href="./?full=1">Open the full site</a></footer>
68
+
69
+ <!-- The example sheet: prototype frame 3, the whole menu of the lite app.
70
+ Plain DOM, no Bootstrap offcanvas. -->
71
+ <div class="p-dim" id="lite-dim" hidden></div>
72
+ <div class="p-sheet" id="lite-sheet" hidden>
73
+ <div class="p-sheet-grab"></div>
74
+ <div class="p-sheet-head">
75
+ <div class="p-sheet-title">Examples</div>
76
+ <input class="p-search" id="lite-search" type="search"
77
+ placeholder="search name, tag, note" autocomplete="off">
78
+ </div>
79
+ <div class="p-sheet-list" id="lite-sheet-list"></div>
80
+ </div>
81
+
82
+ </body>
83
+ </html>
Binary file
@@ -0,0 +1,14 @@
1
+ {
2
+ "name": "aggregate Loss Lab",
3
+ "short_name": "aLL",
4
+ "description": "Build and explore compound (aggregate) loss distributions from a simple DecL program.",
5
+ "start_url": "/",
6
+ "scope": "/",
7
+ "display": "standalone",
8
+ "theme_color": "#ffffff",
9
+ "background_color": "#ffffff",
10
+ "icons": [
11
+ { "src": "/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" },
12
+ { "src": "/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" }
13
+ ]
14
+ }
@@ -0,0 +1,78 @@
1
+ /* Service worker for the aggregate Loss Lab PWA.
2
+ *
3
+ * Deliberately minimal. A build *requires* the backend (you cannot compute an
4
+ * Aggregate offline), so this is NOT an offline-first app. The worker exists to
5
+ * (a) make the SPA installable, since Chrome only offers "Install" when a
6
+ * service worker with a fetch handler is registered, and (b) speed repeat loads
7
+ * by caching the static shell. It must never cache /v1/* (the dynamic API plus
8
+ * the CSV / density frames) or it would serve stale builds and stale data.
9
+ *
10
+ * Strategy:
11
+ * - non-GET / cross-origin / /v1/* -> pass through, never cached
12
+ * - navigations (HTML) -> network-first, fall back to the cached
13
+ * shell when offline so an installed app
14
+ * still opens
15
+ * - other same-origin GETs -> cache-first (Vite content-hashes the
16
+ * (js / css / icons / fonts) js/css asset filenames, so a new build
17
+ * produces new URLs, safe to keep)
18
+ * - activate -> delete caches from older CACHE_VERSIONs
19
+ *
20
+ * Bump CACHE_VERSION on any change to the caching behavior to evict old caches,
21
+ * and also when a file served at a stable URL is replaced in place. The icons
22
+ * are the case that arises: they are not content hashed, so a returning visitor
23
+ * keeps serving the previous artwork out of the cache until the version moves.
24
+ */
25
+
26
+ const CACHE_VERSION = 'agg-pwa-v2';
27
+
28
+ self.addEventListener('install', () => {
29
+ // Take over as soon as installed; we don't precache, so nothing to wait on.
30
+ self.skipWaiting();
31
+ });
32
+
33
+ self.addEventListener('activate', (event) => {
34
+ event.waitUntil((async () => {
35
+ const keys = await caches.keys();
36
+ await Promise.all(
37
+ keys.filter((k) => k !== CACHE_VERSION).map((k) => caches.delete(k)),
38
+ );
39
+ await self.clients.claim();
40
+ })());
41
+ });
42
+
43
+ self.addEventListener('fetch', (event) => {
44
+ const { request } = event;
45
+ if (request.method !== 'GET') return; // never touch POST builds
46
+
47
+ const url = new URL(request.url);
48
+ if (url.origin !== self.location.origin) return; // leave cross-origin alone
49
+ if (url.pathname.startsWith('/v1/')) return; // dynamic API: network-only
50
+
51
+ // HTML navigations: network-first so a redeploy is picked up immediately;
52
+ // fall back to the cached page (or app root) when offline.
53
+ if (request.mode === 'navigate') {
54
+ event.respondWith((async () => {
55
+ try {
56
+ const fresh = await fetch(request);
57
+ const cache = await caches.open(CACHE_VERSION);
58
+ cache.put(request, fresh.clone());
59
+ return fresh;
60
+ } catch {
61
+ return (await caches.match(request)) || (await caches.match('/'));
62
+ }
63
+ })());
64
+ return;
65
+ }
66
+
67
+ // Static assets: cache-first (content-hashed, so safe to keep).
68
+ event.respondWith((async () => {
69
+ const cached = await caches.match(request);
70
+ if (cached) return cached;
71
+ const fresh = await fetch(request);
72
+ if (fresh.ok) {
73
+ const cache = await caches.open(CACHE_VERSION);
74
+ cache.put(request, fresh.clone());
75
+ }
76
+ return fresh;
77
+ })());
78
+ });