logogram 0.1.0__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.
Files changed (179) hide show
  1. logogram-0.1.0/.gitignore +27 -0
  2. logogram-0.1.0/AGENTS.md +136 -0
  3. logogram-0.1.0/LICENSE +21 -0
  4. logogram-0.1.0/PKG-INFO +550 -0
  5. logogram-0.1.0/README.md +517 -0
  6. logogram-0.1.0/pyproject.toml +75 -0
  7. logogram-0.1.0/scripts/check_privacy.py +208 -0
  8. logogram-0.1.0/scripts/smoke_wheel.py +74 -0
  9. logogram-0.1.0/src/logogram/__init__.py +6 -0
  10. logogram-0.1.0/src/logogram/__main__.py +5 -0
  11. logogram-0.1.0/src/logogram/analysis.py +419 -0
  12. logogram-0.1.0/src/logogram/atp.py +120 -0
  13. logogram-0.1.0/src/logogram/backends/__init__.py +5 -0
  14. logogram-0.1.0/src/logogram/backends/base.py +202 -0
  15. logogram-0.1.0/src/logogram/backends/hub.py +375 -0
  16. logogram-0.1.0/src/logogram/backends/saes.py +277 -0
  17. logogram-0.1.0/src/logogram/backends/transformer_lens.py +872 -0
  18. logogram-0.1.0/src/logogram/cli.py +496 -0
  19. logogram-0.1.0/src/logogram/compare.py +177 -0
  20. logogram-0.1.0/src/logogram/datasets.py +159 -0
  21. logogram-0.1.0/src/logogram/direct.py +193 -0
  22. logogram-0.1.0/src/logogram/engine.py +550 -0
  23. logogram-0.1.0/src/logogram/examples/ioi-gpt2/.gitignore +3 -0
  24. logogram-0.1.0/src/logogram/examples/ioi-gpt2/datasets/ioi.jsonl +32 -0
  25. logogram-0.1.0/src/logogram/examples/ioi-gpt2/experiments/ioi-head-patching/spec.json +42 -0
  26. logogram-0.1.0/src/logogram/examples/ioi-gpt2/project.json +6 -0
  27. logogram-0.1.0/src/logogram/exports.py +33 -0
  28. logogram-0.1.0/src/logogram/features.py +368 -0
  29. logogram-0.1.0/src/logogram/fileio.py +63 -0
  30. logogram-0.1.0/src/logogram/ioi.py +220 -0
  31. logogram-0.1.0/src/logogram/paths.py +204 -0
  32. logogram-0.1.0/src/logogram/project.py +444 -0
  33. logogram-0.1.0/src/logogram/prompts.py +204 -0
  34. logogram-0.1.0/src/logogram/research.py +84 -0
  35. logogram-0.1.0/src/logogram/results.py +240 -0
  36. logogram-0.1.0/src/logogram/runner.py +396 -0
  37. logogram-0.1.0/src/logogram/runs.py +98 -0
  38. logogram-0.1.0/src/logogram/sae.py +161 -0
  39. logogram-0.1.0/src/logogram/schema.py +302 -0
  40. logogram-0.1.0/src/logogram/server/__init__.py +1 -0
  41. logogram-0.1.0/src/logogram/server/app.py +1083 -0
  42. logogram-0.1.0/src/logogram/server/models.py +426 -0
  43. logogram-0.1.0/src/logogram/server/security.py +212 -0
  44. logogram-0.1.0/src/logogram/server/state.py +585 -0
  45. logogram-0.1.0/src/logogram/sites.py +249 -0
  46. logogram-0.1.0/src/logogram/spec.py +518 -0
  47. logogram-0.1.0/src/logogram/stats.py +171 -0
  48. logogram-0.1.0/src/logogram/steering.py +258 -0
  49. logogram-0.1.0/src/logogram/system.py +379 -0
  50. logogram-0.1.0/src/logogram/updates.py +194 -0
  51. logogram-0.1.0/src/logogram/verify.py +39 -0
  52. logogram-0.1.0/src/logogram/web_dist/assets/index-BvCU-2uy.js +54 -0
  53. logogram-0.1.0/src/logogram/web_dist/assets/index-DTr8_ucV.css +1 -0
  54. logogram-0.1.0/src/logogram/web_dist/assets/instrument-sans-latin-ext-standard-normal-C5E2Gvlv.woff2 +0 -0
  55. logogram-0.1.0/src/logogram/web_dist/assets/instrument-sans-latin-standard-normal-BVScPF0l.woff2 +0 -0
  56. logogram-0.1.0/src/logogram/web_dist/favicon.svg +1 -0
  57. logogram-0.1.0/src/logogram/web_dist/index.html +15 -0
  58. logogram-0.1.0/tests/browser_server.py +77 -0
  59. logogram-0.1.0/tests/conftest.py +249 -0
  60. logogram-0.1.0/tests/test_architectures.py +161 -0
  61. logogram-0.1.0/tests/test_atp.py +173 -0
  62. logogram-0.1.0/tests/test_cli.py +179 -0
  63. logogram-0.1.0/tests/test_direct.py +212 -0
  64. logogram-0.1.0/tests/test_engine.py +308 -0
  65. logogram-0.1.0/tests/test_explorer.py +304 -0
  66. logogram-0.1.0/tests/test_hardening.py +402 -0
  67. logogram-0.1.0/tests/test_paths.py +169 -0
  68. logogram-0.1.0/tests/test_privacy.py +45 -0
  69. logogram-0.1.0/tests/test_release_fixes.py +368 -0
  70. logogram-0.1.0/tests/test_sae.py +408 -0
  71. logogram-0.1.0/tests/test_sanity.py +144 -0
  72. logogram-0.1.0/tests/test_server.py +229 -0
  73. logogram-0.1.0/tests/test_steering.py +158 -0
  74. logogram-0.1.0/tests/test_units.py +286 -0
  75. logogram-0.1.0/tests/test_updates.py +135 -0
  76. logogram-0.1.0/uv.lock +3254 -0
  77. logogram-0.1.0/web/index.html +14 -0
  78. logogram-0.1.0/web/package-lock.json +2380 -0
  79. logogram-0.1.0/web/package.json +36 -0
  80. logogram-0.1.0/web/playwright.config.ts +23 -0
  81. logogram-0.1.0/web/public/favicon.svg +1 -0
  82. logogram-0.1.0/web/src/App.module.css +33 -0
  83. logogram-0.1.0/web/src/App.tsx +65 -0
  84. logogram-0.1.0/web/src/api/client.ts +219 -0
  85. logogram-0.1.0/web/src/api/events.ts +70 -0
  86. logogram-0.1.0/web/src/api/types.ts +741 -0
  87. logogram-0.1.0/web/src/components/CommandPalette.module.css +97 -0
  88. logogram-0.1.0/web/src/components/CommandPalette.tsx +199 -0
  89. logogram-0.1.0/web/src/components/CopyCommand.module.css +42 -0
  90. logogram-0.1.0/web/src/components/CopyCommand.tsx +45 -0
  91. logogram-0.1.0/web/src/components/Distribution.module.css +90 -0
  92. logogram-0.1.0/web/src/components/Distribution.tsx +148 -0
  93. logogram-0.1.0/web/src/components/FolderPicker.module.css +71 -0
  94. logogram-0.1.0/web/src/components/FolderPicker.tsx +117 -0
  95. logogram-0.1.0/web/src/components/Header.module.css +110 -0
  96. logogram-0.1.0/web/src/components/Header.tsx +154 -0
  97. logogram-0.1.0/web/src/components/Heatmap/Heatmap.module.css +41 -0
  98. logogram-0.1.0/web/src/components/Heatmap/Heatmap.tsx +303 -0
  99. logogram-0.1.0/web/src/components/Heatmap/ScaleBar.tsx +34 -0
  100. logogram-0.1.0/web/src/components/History.module.css +155 -0
  101. logogram-0.1.0/web/src/components/History.tsx +146 -0
  102. logogram-0.1.0/web/src/components/Inspector.module.css +367 -0
  103. logogram-0.1.0/web/src/components/Inspector.tsx +616 -0
  104. logogram-0.1.0/web/src/components/Logogram.tsx +74 -0
  105. logogram-0.1.0/web/src/components/LogogramDial.module.css +49 -0
  106. logogram-0.1.0/web/src/components/LogogramDial.tsx +79 -0
  107. logogram-0.1.0/web/src/components/ModelDialog.module.css +162 -0
  108. logogram-0.1.0/web/src/components/ModelDialog.tsx +249 -0
  109. logogram-0.1.0/web/src/components/ModelMap/Legend.tsx +57 -0
  110. logogram-0.1.0/web/src/components/ModelMap/ModelMap.module.css +156 -0
  111. logogram-0.1.0/web/src/components/ModelMap/ModelMap.tsx +499 -0
  112. logogram-0.1.0/web/src/components/Notices.module.css +65 -0
  113. logogram-0.1.0/web/src/components/Notices.tsx +22 -0
  114. logogram-0.1.0/web/src/components/RobustnessDialog.tsx +226 -0
  115. logogram-0.1.0/web/src/components/Splitter.module.css +35 -0
  116. logogram-0.1.0/web/src/components/Splitter.tsx +66 -0
  117. logogram-0.1.0/web/src/components/StatusLine.module.css +55 -0
  118. logogram-0.1.0/web/src/components/StatusLine.tsx +85 -0
  119. logogram-0.1.0/web/src/components/TokenStrip.module.css +181 -0
  120. logogram-0.1.0/web/src/components/TokenStrip.tsx +167 -0
  121. logogram-0.1.0/web/src/components/TopBar.module.css +205 -0
  122. logogram-0.1.0/web/src/components/TopBar.tsx +112 -0
  123. logogram-0.1.0/web/src/components/UpdateNotice.module.css +120 -0
  124. logogram-0.1.0/web/src/components/UpdateNotice.tsx +118 -0
  125. logogram-0.1.0/web/src/components/ui/Icon.tsx +69 -0
  126. logogram-0.1.0/web/src/components/ui/index.tsx +401 -0
  127. logogram-0.1.0/web/src/components/ui/ui.module.css +646 -0
  128. logogram-0.1.0/web/src/lib/analysis.ts +47 -0
  129. logogram-0.1.0/web/src/lib/canvas.ts +180 -0
  130. logogram-0.1.0/web/src/lib/color.ts +140 -0
  131. logogram-0.1.0/web/src/lib/export.ts +99 -0
  132. logogram-0.1.0/web/src/lib/format.ts +96 -0
  133. logogram-0.1.0/web/src/lib/heatmapNavigation.ts +23 -0
  134. logogram-0.1.0/web/src/lib/hooks.ts +108 -0
  135. logogram-0.1.0/web/src/lib/keys.ts +104 -0
  136. logogram-0.1.0/web/src/lib/logogram.ts +249 -0
  137. logogram-0.1.0/web/src/lib/sites.ts +209 -0
  138. logogram-0.1.0/web/src/lib/spec.ts +376 -0
  139. logogram-0.1.0/web/src/main.tsx +11 -0
  140. logogram-0.1.0/web/src/screens/Projects.tsx +163 -0
  141. logogram-0.1.0/web/src/screens/Screens.module.css +382 -0
  142. logogram-0.1.0/web/src/screens/SystemCheck.tsx +157 -0
  143. logogram-0.1.0/web/src/screens/Welcome.tsx +35 -0
  144. logogram-0.1.0/web/src/screens/Workbench.module.css +194 -0
  145. logogram-0.1.0/web/src/screens/Workbench.tsx +136 -0
  146. logogram-0.1.0/web/src/store/app.ts +925 -0
  147. logogram-0.1.0/web/src/styles/global.css +184 -0
  148. logogram-0.1.0/web/src/styles/tokens.css +116 -0
  149. logogram-0.1.0/web/src/views/AttentionView.module.css +26 -0
  150. logogram-0.1.0/web/src/views/AttentionView.tsx +232 -0
  151. logogram-0.1.0/web/src/views/BaselineView.module.css +130 -0
  152. logogram-0.1.0/web/src/views/BaselineView.tsx +228 -0
  153. logogram-0.1.0/web/src/views/CompareView.module.css +107 -0
  154. logogram-0.1.0/web/src/views/CompareView.tsx +382 -0
  155. logogram-0.1.0/web/src/views/ExperimentView.module.css +87 -0
  156. logogram-0.1.0/web/src/views/ExperimentView.tsx +912 -0
  157. logogram-0.1.0/web/src/views/ExploreView.module.css +46 -0
  158. logogram-0.1.0/web/src/views/ExploreView.tsx +222 -0
  159. logogram-0.1.0/web/src/views/FeaturesView.module.css +282 -0
  160. logogram-0.1.0/web/src/views/FeaturesView.tsx +386 -0
  161. logogram-0.1.0/web/src/views/Forest.module.css +102 -0
  162. logogram-0.1.0/web/src/views/Forest.tsx +72 -0
  163. logogram-0.1.0/web/src/views/HeadComparisonView.module.css +13 -0
  164. logogram-0.1.0/web/src/views/HeadComparisonView.tsx +97 -0
  165. logogram-0.1.0/web/src/views/PredictionsView.module.css +24 -0
  166. logogram-0.1.0/web/src/views/PredictionsView.tsx +121 -0
  167. logogram-0.1.0/web/src/views/PromptsView.tsx +412 -0
  168. logogram-0.1.0/web/src/views/ResearchView.module.css +11 -0
  169. logogram-0.1.0/web/src/views/ResearchView.tsx +120 -0
  170. logogram-0.1.0/web/src/views/ResultsView.module.css +250 -0
  171. logogram-0.1.0/web/src/views/ResultsView.tsx +501 -0
  172. logogram-0.1.0/web/src/views/SpecView.module.css +63 -0
  173. logogram-0.1.0/web/src/views/SpecView.tsx +212 -0
  174. logogram-0.1.0/web/src/views/views.module.css +263 -0
  175. logogram-0.1.0/web/tests/context.unit.ts +108 -0
  176. logogram-0.1.0/web/tests/logogram.unit.ts +72 -0
  177. logogram-0.1.0/web/tests/workbench.browser.ts +146 -0
  178. logogram-0.1.0/web/tsconfig.json +18 -0
  179. logogram-0.1.0/web/vite.config.ts +25 -0
@@ -0,0 +1,27 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ .venv/
5
+ .pytest_cache/
6
+ .ruff_cache/
7
+ .mypy_cache/
8
+ dist/
9
+ build/
10
+ *.egg-info/
11
+
12
+ # Web app sources build into src/logogram/web_dist, which is committed so that
13
+ # `uv tool install .` works without Node. Only dependencies and caches are ignored.
14
+ web/node_modules/
15
+ web/.vite/
16
+ web/test-results/
17
+ web/playwright-report/
18
+
19
+ # Editors, assistants and operating systems
20
+ .DS_Store
21
+ Thumbs.db
22
+ .idea/
23
+ .vscode/
24
+ .claude/
25
+
26
+ # Logogram caches inside projects
27
+ .logogram/
@@ -0,0 +1,136 @@
1
+ # AGENTS.md
2
+
3
+ Guidance for anyone, human or AI, changing this repository. Read it before editing.
4
+
5
+ Logogram is a local-first workbench for causal experiments in language models (activation
6
+ patching, ablation, robustness checks). It is a research instrument: correctness and
7
+ traceability come before features.
8
+
9
+ ## Privacy rules (this repository is public)
10
+
11
+ * No tracked file may identify the person or machine it was made on: no absolute paths, home
12
+ directories, usernames, hostnames, email addresses, hardware names, tokens or keys. This
13
+ applies to code, comments, tests, examples, configs, fixtures, docs and screenshots.
14
+ * Use `platformdirs` for runtime locations (settings, recent projects) and project-relative paths
15
+ in anything written into a project (specs, manifests, summaries).
16
+ * Don't commit run outputs from your machine: manifests record the device and GPU model. The
17
+ bundled example ships a spec and a dataset only.
18
+ * No telemetry, analytics, crash reporting, CDNs or remote fonts. Bundle assets locally. Network
19
+ access is limited to Hugging Face downloads the user starts (with their own login) and the
20
+ version check in `src/logogram/updates.py`: one GET of pypi.org's JSON for `logogram`, carrying
21
+ only the version in its User-Agent, run when the user asks or once a day if they opted in
22
+ (`update_check` in settings, off until they say yes). Keep it opt-in and keep it that small.
23
+ * The server binds 127.0.0.1, requires the session token on every HTTP and WebSocket request,
24
+ checks Host, Origin and Fetch Metadata, and sends no CORS headers. Keep it that way. The token
25
+ never goes on a command line (the browser gets a single-use launch code).
26
+ * Project folders come from other people. Write into them only through `Project.writable` /
27
+ `prepare_run_dir` / `dataset_file` and the `fileio` helpers (which never follow a symlink at the
28
+ file), and read files only after checking they are regular files inside the project.
29
+ * Never unpickle untrusted files. Load weights, SAEs included, from safetensors only.
30
+ * Run `python3 scripts/check_privacy.py` before committing. CI runs it on every push.
31
+
32
+ ## Science rules
33
+
34
+ * The experiment spec (`src/logogram/spec.py`) is the single source of truth. The app and
35
+ `logogram run` execute the same spec through `logogram.runner.run_spec`; never add a code path
36
+ that only one of them uses.
37
+ * Every choice that can change a number lives in the spec and is shown in the UI: direction,
38
+ baseline, site, position, metric, normalization, seeds, batch size, dtype, model revision.
39
+ Nothing methodological is silently defaulted. Ablation has no default baseline.
40
+ * Specs use abstract sites (`resid_pre`, `resid_mid`, `resid_post`, `attn_out`, `mlp_out`,
41
+ `head`). Library hook names appear only inside a backend (`src/logogram/backends/`).
42
+ * Keep per-prompt values. Statistics come from them: n, mean, SD, a seeded percentile bootstrap
43
+ CI, sign flips and opposite-sign counts.
44
+ * Determinism: the same spec on the same machine must give bit-identical results. Seed
45
+ everything, keep batch composition fixed, and don't introduce nondeterministic kernels.
46
+ * The sanity tests in `tests/test_sanity.py` must keep passing: patching all clean activations
47
+ at a layer gives effect 1; patching corrupt into corrupt gives 0; the same spec twice gives
48
+ identical results. `tests/test_architectures.py` runs them on tiny models of other families.
49
+ Tests use tiny local models and must never touch the network.
50
+ * Don't trust a model to be what its architecture name says. `check_model` in the backend
51
+ measures, when a model loads, that TransformerLens reproduces its predictions, how its layers
52
+ add into the residual stream, and whether the logit lens reproduces its output; features that
53
+ rely on a property must check that it was measured.
54
+
55
+ ## Design rules
56
+
57
+ * White and black, with color that means something. The page is pure white (or pure black); regions
58
+ are separated by space and hairlines, never grey washes or drop shadows (only menus, dialogs and
59
+ tooltips float). Navigation runs across the top; there is no sidebar.
60
+ * Color has jobs (tokens in `web/src/styles/tokens.css`):
61
+ * each workspace has one: green Explore (`--explore`), orange Experiment (`--experiment`), pink
62
+ Evidence (`--evidence`). The open workspace's pill, its tab underline, its progress and its
63
+ radio marks use it (`--ws` holds the current one);
64
+ * green (`--live`) means a loaded model;
65
+ * effects use the diverging cobalt–neutral–amber scale, symmetric around zero, always with a
66
+ legend, and nothing else uses those hues. Attention uses the single-hue ink ramp.
67
+ * Primary buttons are solid ink (white in the dark theme), not colored.
68
+ * Selection is circled in ink (`inkRing` in `web/src/lib/canvas.ts`), not a new color.
69
+ * Logograms (`web/src/lib/logogram.ts`) are data, not decoration. A run's glyph is written by its
70
+ results: layers clockwise from the top, the ink swelling outward where a layer's strongest
71
+ effect is positive and inward where it is negative, bleeding in the effect colors. Glyphs from
72
+ a seed alone mark identity only: the brand (`BRAND_SEED`), projects, empty states. The welcome
73
+ screens' color bloom behind the brand glyph is the one decorative use of color.
74
+ * One typeface, Instrument Sans (weight and width axes): condensed widths for titles and big
75
+ figures (`--display-stretch`, `.figure`), tabular figures for numbers. Its word space is
76
+ narrow, so body text widens it (`--word-space`). Monospace appears only in the spec view.
77
+ Sentence case everywhere; no all-caps labels.
78
+ * Motion only explains state changes, such as cells filling as results stream in, a glyph
79
+ appearing, or panels opening. Respect reduced motion.
80
+ * Copy uses plain verbs that say exactly what happens. Errors say what went wrong and how to fix
81
+ it. Titles say what a view found or is for; they don't repeat the tab's name.
82
+ * Avoid the generic AI-app look and the enterprise look: no sidebars of icons, grey dashboards,
83
+ decorative gradients, glassmorphism, glow, sparkle icons, emoji, chat panels, grids of
84
+ identical rounded cards, purple-blue palettes, or 3D brains and node galaxies.
85
+ * Draw the model map and heatmaps on canvas. Use Radix primitives for menus, dialogs, tooltips
86
+ and popovers, Zustand for state, d3-scale and d3-color for scales, CSS variables and CSS
87
+ modules for styling. No component kits or chart libraries.
88
+ * Every view must work with the keyboard and in both the white and black themes, and down to an
89
+ 800-pixel window.
90
+
91
+ ## Layout of the code
92
+
93
+ ```text
94
+ src/logogram/
95
+ spec.py experiment spec (pydantic)
96
+ datasets.py, ioi.py JSONL datasets and the IOI generator
97
+ prompts.py tokenization, alignment checks, length groups
98
+ sites.py scope expansion and result layouts
99
+ engine.py the sweep: captures, patches, streams per layer, cancels; routes methods
100
+ direct.py direct logit attribution
101
+ atp.py attribution patching (first-order estimates of patching)
102
+ verify.py the spec that verifies an estimate by patching its strongest sites
103
+ steering.py steering with held-out prompts and a random control
104
+ paths.py path patching
105
+ features.py SAE features: patching and attribution patching
106
+ sae.py SAE encode, decode and fit
107
+ stats.py bootstrap and summary statistics
108
+ results.py summary.json and results.parquet
109
+ schema.py schemas for run files, history listings and live events
110
+ fileio.py atomic writes that never follow symlinks
111
+ runner.py run a spec end to end (used by the app and the CLI)
112
+ compare.py robustness checks and run comparisons
113
+ analysis.py token strip, baseline check, attention patterns
114
+ backends/ ModelBackend interface, TransformerLens backend, Hugging Face access,
115
+ published SAE formats
116
+ server/ FastAPI app, security, response models, job and event handling
117
+ system.py hardware report, doctor, memory estimates
118
+ updates.py opt-in version check against PyPI, update commands
119
+ cli.py typer command line
120
+ web_dist/ built web app (generated by `npm run build` in web/, committed)
121
+ examples/ioi-gpt2/ the bundled example project
122
+ web/ React + TypeScript + Vite sources
123
+ scripts/check_privacy.py
124
+ tests/
125
+ ```
126
+
127
+ ## Commands
128
+
129
+ ```bash
130
+ uv sync
131
+ uv run pytest
132
+ uv run ruff check src tests scripts && uv run ruff format src tests scripts
133
+ python3 scripts/check_privacy.py
134
+ cd web && npm install && npm run build # rebuild src/logogram/web_dist after web changes
135
+ uv run logogram serve --dev # API for `npm run dev` in web/
136
+ ```
logogram-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 The Logogram contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.