ltcai 8.0.0 → 8.1.0

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 (103) hide show
  1. package/README.md +32 -50
  2. package/docs/CHANGELOG.md +14 -0
  3. package/docs/V3_FRONTEND.md +11 -5
  4. package/lattice_brain/__init__.py +1 -1
  5. package/lattice_brain/embeddings.py +9 -1
  6. package/lattice_brain/runtime/multi_agent.py +1 -1
  7. package/latticeai/__init__.py +1 -1
  8. package/latticeai/app_factory.py +13 -134
  9. package/latticeai/core/local_embeddings.py +8 -0
  10. package/latticeai/core/marketplace.py +1 -1
  11. package/latticeai/core/mcp_registry.py +140 -1
  12. package/latticeai/core/workspace_os.py +1 -1
  13. package/latticeai/services/architecture_readiness.py +6 -5
  14. package/latticeai/services/model_runtime.py +36 -2
  15. package/latticeai/services/product_readiness.py +18 -18
  16. package/package.json +2 -2
  17. package/scripts/build_frontend_assets.mjs +11 -2
  18. package/src-tauri/Cargo.lock +1 -1
  19. package/src-tauri/Cargo.toml +1 -1
  20. package/src-tauri/tauri.conf.json +1 -1
  21. package/static/app/asset-manifest.json +11 -102
  22. package/static/app/assets/Act-BOO66G-c.js +1 -0
  23. package/static/app/assets/Brain-C6lEYiD7.js +321 -0
  24. package/static/app/assets/{Capture-B9Tlhzqr.js → Capture-TATXBRDw.js} +1 -2
  25. package/static/app/assets/Library-DK4FIp8a.js +1 -0
  26. package/static/app/assets/System-Bgs6Ql7x.js +1 -0
  27. package/static/app/assets/core-CwxXejkd.js +1 -2
  28. package/static/app/assets/index-Bvv79nre.js +16 -0
  29. package/static/app/assets/index-Dslqglia.css +2 -0
  30. package/static/app/assets/primitives-B70WOra0.js +1 -0
  31. package/static/app/assets/{textarea-BZk6ybp5.js → textarea-Czrd9gwM.js} +1 -2
  32. package/static/app/index.html +3 -10
  33. package/static/app/theme-boot.js +8 -0
  34. package/static/sw.js +1 -1
  35. package/frontend/index.html +0 -24
  36. package/frontend/openapi.json +0 -15425
  37. package/frontend/src/App.tsx +0 -243
  38. package/frontend/src/api/client.ts +0 -580
  39. package/frontend/src/api/openapi.ts +0 -17892
  40. package/frontend/src/components/AdminAccessGate.tsx +0 -70
  41. package/frontend/src/components/FeedbackState.tsx +0 -45
  42. package/frontend/src/components/LanguageSwitcher.tsx +0 -23
  43. package/frontend/src/components/LivingBrain.tsx +0 -220
  44. package/frontend/src/components/ProductFlow.tsx +0 -171
  45. package/frontend/src/components/WorkspaceProfileSwitcher.tsx +0 -176
  46. package/frontend/src/components/onboarding/AnalysisScreen.tsx +0 -135
  47. package/frontend/src/components/onboarding/DownloadConsentPanel.tsx +0 -29
  48. package/frontend/src/components/onboarding/InstallScreen.tsx +0 -263
  49. package/frontend/src/components/onboarding/LanguageChooser.tsx +0 -23
  50. package/frontend/src/components/onboarding/LoginScreen.tsx +0 -131
  51. package/frontend/src/components/onboarding/ProductFlowScreens.tsx +0 -13
  52. package/frontend/src/components/onboarding/RecommendationScreen.tsx +0 -116
  53. package/frontend/src/components/onboarding/recommendationModel.ts +0 -189
  54. package/frontend/src/components/primitives.tsx +0 -392
  55. package/frontend/src/components/ui/badge.tsx +0 -27
  56. package/frontend/src/components/ui/button.tsx +0 -37
  57. package/frontend/src/components/ui/card.tsx +0 -22
  58. package/frontend/src/components/ui/input.tsx +0 -16
  59. package/frontend/src/components/ui/textarea.tsx +0 -16
  60. package/frontend/src/features/admin/AdminConsole.tsx +0 -334
  61. package/frontend/src/features/brain/BrainCarePanel.tsx +0 -254
  62. package/frontend/src/features/brain/BrainComposer.tsx +0 -85
  63. package/frontend/src/features/brain/BrainConversation.tsx +0 -688
  64. package/frontend/src/features/brain/BrainGraphLayer.tsx +0 -365
  65. package/frontend/src/features/brain/BrainHome.tsx +0 -624
  66. package/frontend/src/features/brain/BrainMemoryLayer.tsx +0 -45
  67. package/frontend/src/features/brain/BrainOverviewPanel.tsx +0 -149
  68. package/frontend/src/features/brain/BrainRelationshipLayer.tsx +0 -43
  69. package/frontend/src/features/brain/DepthEmergence.tsx +0 -53
  70. package/frontend/src/features/brain/brainData.ts +0 -246
  71. package/frontend/src/features/brain/graphLayout.ts +0 -37
  72. package/frontend/src/features/brain/types.ts +0 -150
  73. package/frontend/src/features/review/ReviewCard.tsx +0 -100
  74. package/frontend/src/features/review/ReviewInbox.tsx +0 -127
  75. package/frontend/src/features/review/reviewHelpers.ts +0 -69
  76. package/frontend/src/i18n.ts +0 -1303
  77. package/frontend/src/lib/utils.ts +0 -33
  78. package/frontend/src/main.tsx +0 -23
  79. package/frontend/src/pages/Act.tsx +0 -458
  80. package/frontend/src/pages/Ask.tsx +0 -14
  81. package/frontend/src/pages/Brain.tsx +0 -914
  82. package/frontend/src/pages/Capture.tsx +0 -258
  83. package/frontend/src/pages/Library.tsx +0 -486
  84. package/frontend/src/pages/System.tsx +0 -621
  85. package/frontend/src/routes.ts +0 -92
  86. package/frontend/src/store/appStore.ts +0 -94
  87. package/frontend/src/styles.css +0 -6579
  88. package/static/app/assets/Act-DOvf59ru.js +0 -2
  89. package/static/app/assets/Act-DOvf59ru.js.map +0 -1
  90. package/static/app/assets/Brain-C7_0mEiI.js +0 -322
  91. package/static/app/assets/Brain-C7_0mEiI.js.map +0 -1
  92. package/static/app/assets/Capture-B9Tlhzqr.js.map +0 -1
  93. package/static/app/assets/Library-BJPEEm5O.js +0 -2
  94. package/static/app/assets/Library-BJPEEm5O.js.map +0 -1
  95. package/static/app/assets/System-D6t9jo9V.js +0 -2
  96. package/static/app/assets/System-D6t9jo9V.js.map +0 -1
  97. package/static/app/assets/core-CwxXejkd.js.map +0 -1
  98. package/static/app/assets/index-C7g26IF6.css +0 -2
  99. package/static/app/assets/index-DbcEYJQ2.js +0 -17
  100. package/static/app/assets/index-DbcEYJQ2.js.map +0 -1
  101. package/static/app/assets/primitives-CD38lt4n.js +0 -2
  102. package/static/app/assets/primitives-CD38lt4n.js.map +0 -1
  103. package/static/app/assets/textarea-BZk6ybp5.js.map +0 -1
@@ -1,9 +1,10 @@
1
1
  """Machine-checkable architecture readiness gates for release work.
2
2
 
3
- 8.0.0 turns the major architecture priorities into an explicit release
4
- contract. AgentRuntime, ToolRegistry, central Config, decomposed server runtime,
5
- and Knowledge Graph stabilization must be discoverable, ordered, and backed by
6
- tests before the release can be called complete.
3
+ 8.1.0 keeps the major architecture priorities under an explicit release
4
+ contract while the product surface is refreshed. AgentRuntime, ToolRegistry,
5
+ central Config, decomposed server runtime, and Knowledge Graph stabilization
6
+ must remain discoverable, ordered, and backed by tests before the release can be
7
+ called complete.
7
8
  """
8
9
 
9
10
  from __future__ import annotations
@@ -14,7 +15,7 @@ from pathlib import Path
14
15
  from typing import Any, Dict, List
15
16
 
16
17
 
17
- ARCHITECTURE_VERSION_TARGET = "8.0.0"
18
+ ARCHITECTURE_VERSION_TARGET = "8.1.0"
18
19
 
19
20
  PREFERRED_REFACTORING_ORDER = [
20
21
  "agent-runtime",
@@ -127,8 +127,42 @@ get_user_api_key = _missing_user_api_key
127
127
 
128
128
 
129
129
  def configure_model_runtime(**deps) -> None:
130
- """Wire app-owned runtime dependencies without importing server_app."""
131
- globals().update({key: value for key, value in deps.items() if key in globals()})
130
+ """Wire app-owned runtime dependencies without importing server_app.
131
+
132
+ Explicit per-key assignment (no blanket globals().update) so wiring is
133
+ auditable and side effects are visible. Preserves exact public module
134
+ globals and prior behavior for all callers and shims.
135
+ """
136
+ global router, APP_MODE, DEFAULT_HOST, DEFAULT_PORT, DATA_DIR, BASE_DIR
137
+ global ENABLE_TELEGRAM, ENABLE_GRAPH, AUTOLOAD_MODELS, MODEL_IDLE_UNLOAD_SECONDS
138
+ global ALLOW_LOCAL_MODELS, REQUIRE_AUTH, INVITE_GATE_ENABLED, ALLOW_PLAINTEXT_API_KEYS
139
+ global CORS_ALLOW_NETWORK, PUBLIC_MODEL, LOCAL_MODEL, IS_PUBLIC_MODE
140
+ global keyring, get_current_user, get_user_api_key
141
+
142
+ router = deps.get("router", router)
143
+ APP_MODE = deps.get("APP_MODE", APP_MODE)
144
+ DEFAULT_HOST = deps.get("DEFAULT_HOST", DEFAULT_HOST)
145
+ DEFAULT_PORT = deps.get("DEFAULT_PORT", DEFAULT_PORT)
146
+ DATA_DIR = deps.get("DATA_DIR", DATA_DIR)
147
+ BASE_DIR = deps.get("BASE_DIR", BASE_DIR)
148
+ ENABLE_TELEGRAM = deps.get("ENABLE_TELEGRAM", ENABLE_TELEGRAM)
149
+ ENABLE_GRAPH = deps.get("ENABLE_GRAPH", ENABLE_GRAPH)
150
+ AUTOLOAD_MODELS = deps.get("AUTOLOAD_MODELS", AUTOLOAD_MODELS)
151
+ MODEL_IDLE_UNLOAD_SECONDS = deps.get("MODEL_IDLE_UNLOAD_SECONDS", MODEL_IDLE_UNLOAD_SECONDS)
152
+ ALLOW_LOCAL_MODELS = deps.get("ALLOW_LOCAL_MODELS", ALLOW_LOCAL_MODELS)
153
+ REQUIRE_AUTH = deps.get("REQUIRE_AUTH", REQUIRE_AUTH)
154
+ INVITE_GATE_ENABLED = deps.get("INVITE_GATE_ENABLED", INVITE_GATE_ENABLED)
155
+ ALLOW_PLAINTEXT_API_KEYS = deps.get("ALLOW_PLAINTEXT_API_KEYS", ALLOW_PLAINTEXT_API_KEYS)
156
+ CORS_ALLOW_NETWORK = deps.get("CORS_ALLOW_NETWORK", CORS_ALLOW_NETWORK)
157
+ PUBLIC_MODEL = deps.get("PUBLIC_MODEL", PUBLIC_MODEL)
158
+ LOCAL_MODEL = deps.get("LOCAL_MODEL", LOCAL_MODEL)
159
+ IS_PUBLIC_MODE = deps.get("IS_PUBLIC_MODE", IS_PUBLIC_MODE)
160
+ if "keyring" in deps:
161
+ keyring = deps["keyring"]
162
+ if "get_current_user" in deps:
163
+ get_current_user = deps["get_current_user"]
164
+ if "get_user_api_key" in deps:
165
+ get_user_api_key = deps["get_user_api_key"]
132
166
 
133
167
 
134
168
  # Catalog data + version-dedup helpers live in ``model_catalog``; re-exported
@@ -1,13 +1,13 @@
1
- """Machine-checkable *product* readiness gates for the 8.0 line.
1
+ """Machine-checkable *product* readiness gates for the 8.1 line.
2
2
 
3
3
  Where ``architecture_readiness`` proves the internal structure is sound, this
4
- module answers the product question the 8.0 release exists to settle: *are the
5
- runtime boundaries still clear and release-ready after hardening?* It does so
6
- honestly — every gate is backed by evidence that is probed on disk, so a gate
7
- only reports ``complete`` when its evidence actually resolves. The same report
8
- can be printed by ``scripts/product_readiness.py`` and re-run after every
9
- change, which is the point: completeness is something we keep measuring, not a
10
- one-time claim.
4
+ module answers the product question the 8.1 release exists to settle: *is the
5
+ Brain experience still release-ready after the default surface becomes more
6
+ intuitive?* It does so honestly — every gate is backed by evidence that is
7
+ probed on disk, so a gate only reports ``complete`` when its evidence actually
8
+ resolves. The same report can be printed by ``scripts/product_readiness.py`` and
9
+ re-run after every change, which is the point: completeness is something we keep
10
+ measuring, not a one-time claim.
11
11
  """
12
12
 
13
13
  from __future__ import annotations
@@ -18,7 +18,7 @@ from typing import Any, Dict, List
18
18
 
19
19
  from latticeai.services.architecture_readiness import architecture_readiness
20
20
 
21
- PRODUCT_VERSION_TARGET = "8.0.0"
21
+ PRODUCT_VERSION_TARGET = "8.1.0"
22
22
 
23
23
 
24
24
  @dataclass(frozen=True)
@@ -65,10 +65,10 @@ PRODUCT_GATES: List[ProductGate] = [
65
65
  evidence=[
66
66
  "package.json::release:artifacts",
67
67
  "package.json::release:validate",
68
- "README.md::dist/ltcai-8.0.0-py3-none-any.whl",
69
- "README.md::dist/ltcai-8.0.0.tar.gz",
70
- "README.md::dist/ltcai-8.0.0.vsix",
71
- "README.md::ltcai-8.0.0.tgz",
68
+ "README.md::dist/ltcai-8.1.0-py3-none-any.whl",
69
+ "README.md::dist/ltcai-8.1.0.tar.gz",
70
+ "README.md::dist/ltcai-8.1.0.vsix",
71
+ "README.md::ltcai-8.1.0.tgz",
72
72
  "scripts/validate_release_artifacts.py",
73
73
  "scripts/release_smoke.py",
74
74
  "Dockerfile",
@@ -84,12 +84,12 @@ PRODUCT_GATES: List[ProductGate] = [
84
84
  title="Release story is documented and honest",
85
85
  evidence=[
86
86
  "README.md",
87
- "README.md::The current release is **8.0.0",
88
- "SECURITY.md::8.0.x (latest)",
89
- "vscode-extension/README.md::**8.0.0",
90
- "docs/CHANGELOG.md::## [8.0.0]",
87
+ "README.md::The current release is **8.1.0",
88
+ "SECURITY.md::8.1.x (latest)",
89
+ "vscode-extension/README.md::**8.1.0",
90
+ "docs/CHANGELOG.md::## [8.1.0]",
91
91
  "FEATURE_STATUS.md",
92
- "RELEASE_NOTES_v8.0.0.md",
92
+ "RELEASE_NOTES_v8.1.0.md",
93
93
  "latticeai/core/agent.py::SingleAgentRuntime",
94
94
  "latticeai/core/agent.py::AgentRuntime = SingleAgentRuntime",
95
95
  "lattice_brain/runtime/contracts.py::runtime-boundary/v1",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ltcai",
3
- "version": "8.0.0",
3
+ "version": "8.1.0",
4
4
  "description": "Lattice AI — local-first Digital Brain that keeps your knowledge durable across any AI model.",
5
5
  "homepage": "https://github.com/TaeSooPark-PTS/LatticeAI#readme",
6
6
  "repository": {
@@ -85,7 +85,6 @@
85
85
  "static/manifest.json",
86
86
  "static/sw.js",
87
87
  "static/css/",
88
- "frontend/",
89
88
  "static/app/",
90
89
  "static/icons/",
91
90
  "plugins/",
@@ -94,6 +93,7 @@
94
93
  "!docs/images/tmp_frames/",
95
94
  "!**/__pycache__/",
96
95
  "!**/*.pyc",
96
+ "!**/*.map",
97
97
  "README.md",
98
98
  "setup_wizard.py",
99
99
  "knowledge_graph_api.py",
@@ -6,6 +6,7 @@ const repo = join(import.meta.dirname, "..");
6
6
  const appDir = join(repo, "static", "app");
7
7
  const nestedViteManifest = join(appDir, ".vite", "asset-manifest.json");
8
8
  const publicManifest = join(appDir, "asset-manifest.json");
9
+ const serviceWorker = join(repo, "static", "sw.js");
9
10
  const pkg = JSON.parse(readFileSync(join(repo, "package.json"), "utf8"));
10
11
 
11
12
  const assetsDir = join(appDir, "assets");
@@ -39,11 +40,19 @@ const manifest = {
39
40
  version: pkg.version,
40
41
  generated_at: "vite",
41
42
  entrypoints: {
42
- app: assets["frontend/index.html"] || "/static/app/index.html",
43
+ app: assets["index.html"] || "/static/app/index.html",
43
44
  },
44
45
  assets,
45
- vite: raw,
46
46
  };
47
47
 
48
48
  writeFileSync(publicManifest, JSON.stringify(manifest, null, 2) + "\n", "utf8");
49
+ if (existsSync(serviceWorker)) {
50
+ const cacheVersion = pkg.version.replace(/\D/g, "");
51
+ const source = readFileSync(serviceWorker, "utf8");
52
+ const normalized = source.replace(
53
+ /const CACHE = "lattice-v[^"]+";/,
54
+ `const CACHE = "lattice-v${cacheVersion}";`,
55
+ );
56
+ if (normalized !== source) writeFileSync(serviceWorker, normalized, "utf8");
57
+ }
49
58
  console.log(`wrote static/app/asset-manifest.json with ${Object.keys(assets).length} assets`);
@@ -1584,7 +1584,7 @@ dependencies = [
1584
1584
 
1585
1585
  [[package]]
1586
1586
  name = "lattice-ai-desktop"
1587
- version = "8.0.0"
1587
+ version = "8.1.0"
1588
1588
  dependencies = [
1589
1589
  "plist",
1590
1590
  "serde",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "lattice-ai-desktop"
3
- version = "8.0.0"
3
+ version = "8.1.0"
4
4
  description = "Lattice AI Digital Brain desktop shell"
5
5
  authors = ["TaeSoo Park"]
6
6
  edition = "2021"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://schema.tauri.app/config/2",
3
3
  "productName": "Lattice AI",
4
- "version": "8.0.0",
4
+ "version": "8.1.0",
5
5
  "identifier": "ai.lattice.desktop",
6
6
  "build": {
7
7
  "beforeDevCommand": "npm run frontend:dev",
@@ -1,110 +1,19 @@
1
1
  {
2
- "version": "8.0.0",
2
+ "version": "8.1.0",
3
3
  "generated_at": "vite",
4
4
  "entrypoints": {
5
- "app": "/static/app/index.html"
5
+ "app": "/static/app/assets/index-Bvv79nre.js"
6
6
  },
7
7
  "assets": {
8
8
  "../node_modules/@tauri-apps/api/core.js": "/static/app/assets/core-CwxXejkd.js",
9
- "_primitives-CD38lt4n.js": "/static/app/assets/primitives-CD38lt4n.js",
10
- "_textarea-BZk6ybp5.js": "/static/app/assets/textarea-BZk6ybp5.js",
11
- "index.html": "/static/app/assets/index-DbcEYJQ2.js",
12
- "assets/index-C7g26IF6.css": "/static/app/assets/index-C7g26IF6.css",
13
- "src/pages/Act.tsx": "/static/app/assets/Act-DOvf59ru.js",
14
- "src/pages/Brain.tsx": "/static/app/assets/Brain-C7_0mEiI.js",
15
- "src/pages/Capture.tsx": "/static/app/assets/Capture-B9Tlhzqr.js",
16
- "src/pages/Library.tsx": "/static/app/assets/Library-BJPEEm5O.js",
17
- "src/pages/System.tsx": "/static/app/assets/System-D6t9jo9V.js"
18
- },
19
- "vite": {
20
- "../node_modules/@tauri-apps/api/core.js": {
21
- "file": "assets/core-CwxXejkd.js",
22
- "name": "core",
23
- "src": "../node_modules/@tauri-apps/api/core.js",
24
- "isDynamicEntry": true
25
- },
26
- "_primitives-CD38lt4n.js": {
27
- "file": "assets/primitives-CD38lt4n.js",
28
- "name": "primitives",
29
- "imports": [
30
- "index.html"
31
- ]
32
- },
33
- "_textarea-BZk6ybp5.js": {
34
- "file": "assets/textarea-BZk6ybp5.js",
35
- "name": "textarea",
36
- "imports": [
37
- "index.html"
38
- ]
39
- },
40
- "index.html": {
41
- "file": "assets/index-DbcEYJQ2.js",
42
- "name": "index",
43
- "src": "index.html",
44
- "isEntry": true,
45
- "dynamicImports": [
46
- "../node_modules/@tauri-apps/api/core.js",
47
- "src/pages/Act.tsx",
48
- "src/pages/Brain.tsx",
49
- "src/pages/Capture.tsx",
50
- "src/pages/Library.tsx",
51
- "src/pages/System.tsx"
52
- ],
53
- "css": [
54
- "assets/index-C7g26IF6.css"
55
- ]
56
- },
57
- "src/pages/Act.tsx": {
58
- "file": "assets/Act-DOvf59ru.js",
59
- "name": "Act",
60
- "src": "src/pages/Act.tsx",
61
- "isDynamicEntry": true,
62
- "imports": [
63
- "index.html",
64
- "_primitives-CD38lt4n.js",
65
- "_textarea-BZk6ybp5.js"
66
- ]
67
- },
68
- "src/pages/Brain.tsx": {
69
- "file": "assets/Brain-C7_0mEiI.js",
70
- "name": "Brain",
71
- "src": "src/pages/Brain.tsx",
72
- "isDynamicEntry": true,
73
- "imports": [
74
- "index.html",
75
- "_primitives-CD38lt4n.js",
76
- "_textarea-BZk6ybp5.js"
77
- ]
78
- },
79
- "src/pages/Capture.tsx": {
80
- "file": "assets/Capture-B9Tlhzqr.js",
81
- "name": "Capture",
82
- "src": "src/pages/Capture.tsx",
83
- "isDynamicEntry": true,
84
- "imports": [
85
- "index.html",
86
- "_primitives-CD38lt4n.js"
87
- ]
88
- },
89
- "src/pages/Library.tsx": {
90
- "file": "assets/Library-BJPEEm5O.js",
91
- "name": "Library",
92
- "src": "src/pages/Library.tsx",
93
- "isDynamicEntry": true,
94
- "imports": [
95
- "index.html",
96
- "_primitives-CD38lt4n.js"
97
- ]
98
- },
99
- "src/pages/System.tsx": {
100
- "file": "assets/System-D6t9jo9V.js",
101
- "name": "System",
102
- "src": "src/pages/System.tsx",
103
- "isDynamicEntry": true,
104
- "imports": [
105
- "index.html",
106
- "_primitives-CD38lt4n.js"
107
- ]
108
- }
9
+ "_primitives-B70WOra0.js": "/static/app/assets/primitives-B70WOra0.js",
10
+ "_textarea-Czrd9gwM.js": "/static/app/assets/textarea-Czrd9gwM.js",
11
+ "index.html": "/static/app/assets/index-Bvv79nre.js",
12
+ "assets/index-Dslqglia.css": "/static/app/assets/index-Dslqglia.css",
13
+ "src/pages/Act.tsx": "/static/app/assets/Act-BOO66G-c.js",
14
+ "src/pages/Brain.tsx": "/static/app/assets/Brain-C6lEYiD7.js",
15
+ "src/pages/Capture.tsx": "/static/app/assets/Capture-TATXBRDw.js",
16
+ "src/pages/Library.tsx": "/static/app/assets/Library-DK4FIp8a.js",
17
+ "src/pages/System.tsx": "/static/app/assets/System-Bgs6Ql7x.js"
109
18
  }
110
19
  }