hinge 0.1.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.
- hinge/__init__.py +3 -0
- hinge/config/__init__.py +0 -0
- hinge/config/logging_setup.py +63 -0
- hinge/config/settings.py +23 -0
- hinge/config/types.yaml +42 -0
- hinge/dbt/.user.yml +1 -0
- hinge/dbt/dbt_project.yml +18 -0
- hinge/dbt/macros/apply_time_window.sql +11 -0
- hinge/dbt/macros/assert_recipe_supported.sql +59 -0
- hinge/dbt/macros/build_incidence.sql +46 -0
- hinge/dbt/macros/collapse_path.sql +26 -0
- hinge/dbt/macros/filter_bots.sql +23 -0
- hinge/dbt/macros/network_edges.sql +39 -0
- hinge/dbt/macros/project_bipartite.sql +33 -0
- hinge/dbt/macros/slice_edges.sql +41 -0
- hinge/dbt/models/hin/hin_accounts.sql +14 -0
- hinge/dbt/models/hin/hin_artifacts.sql +23 -0
- hinge/dbt/models/hin/hin_capabilities.sql +42 -0
- hinge/dbt/models/hin/hin_edges.sql +57 -0
- hinge/dbt/models/hin/hin_nodes.sql +44 -0
- hinge/dbt/models/hin/hin_repositories.sql +15 -0
- hinge/dbt/models/intermediate/int_developer_repo_affiliation.sql +27 -0
- hinge/dbt/models/intermediate/int_user_artifact_incidence.sql +21 -0
- hinge/dbt/models/networks/artifact_reference.sql +27 -0
- hinge/dbt/models/networks/co_commit_user_user.sql +48 -0
- hinge/dbt/models/networks/co_edit_file_user_user.sql +48 -0
- hinge/dbt/models/networks/co_edit_line_user_user.sql +48 -0
- hinge/dbt/models/networks/dev_interaction.sql +98 -0
- hinge/dbt/models/networks/developer_repo_affiliation.sql +20 -0
- hinge/dbt/models/networks/follow_user_user.sql +27 -0
- hinge/dbt/models/networks/fork_repo_repo.sql +27 -0
- hinge/dbt/models/networks/issue_co_participation.sql +50 -0
- hinge/dbt/models/networks/issue_participation.sql +40 -0
- hinge/dbt/models/networks/pr_author_reviewer.sql +66 -0
- hinge/dbt/models/networks/pr_participation.sql +40 -0
- hinge/dbt/models/networks/pr_reviewer_coreview.sql +48 -0
- hinge/dbt/models/networks/repo_shared_contributors.sql +41 -0
- hinge/dbt/models/networks/star_user_repo.sql +27 -0
- hinge/dbt/models/networks/user_mention_user.sql +60 -0
- hinge/dbt/models/networks/watch_user_repo.sql +27 -0
- hinge/dbt/models/sources/sources.yml +63 -0
- hinge/dbt/models/staging/stg_accounts.sql +4 -0
- hinge/dbt/models/staging/stg_adapter_manifest.sql +4 -0
- hinge/dbt/models/staging/stg_artifacts.sql +4 -0
- hinge/dbt/models/staging/stg_relations.sql +4 -0
- hinge/dbt/models/staging/stg_repositories.sql +4 -0
- hinge/dbt/profiles.yml +9 -0
- hinge/dbt/seeds/ref_recipe_requirements.csv +35 -0
- hinge/frontends/__init__.py +0 -0
- hinge/frontends/cli/__init__.py +3 -0
- hinge/frontends/cli/app.py +189 -0
- hinge/frontends/lib.py +148 -0
- hinge/frontends/tui/__init__.py +7 -0
- hinge/frontends/web/__init__.py +6 -0
- hinge/kernel/__init__.py +0 -0
- hinge/kernel/projection/__init__.py +9 -0
- hinge/kernel/projection/projected_graph.py +32 -0
- hinge/kernel/projection/projection_spec.py +35 -0
- hinge/kernel/protocols/__init__.py +24 -0
- hinge/kernel/protocols/dataset_view.py +30 -0
- hinge/kernel/protocols/exporter_stage.py +24 -0
- hinge/kernel/protocols/projection_stage.py +36 -0
- hinge/kernel/protocols/reader_stage.py +52 -0
- hinge/kernel/protocols/store_stage.py +71 -0
- hinge/kernel/registry.py +71 -0
- hinge/kernel/runner.py +236 -0
- hinge/kernel/schema/__init__.py +12 -0
- hinge/kernel/schema/hin_schema.py +38 -0
- hinge/kernel/schema/schema_violation.py +21 -0
- hinge/kernel/schema/typed_edge.py +20 -0
- hinge/kernel/schema/typed_node.py +17 -0
- hinge/stages/__init__.py +0 -0
- hinge/stages/exporters/__init__.py +0 -0
- hinge/stages/exporters/csv_exporter.py +77 -0
- hinge/stages/exporters/dot_exporter.py +13 -0
- hinge/stages/exporters/gexf_exporter.py +13 -0
- hinge/stages/exporters/gml_exporter.py +79 -0
- hinge/stages/exporters/graphml_exporter.py +13 -0
- hinge/stages/exporters/jsonld_exporter.py +13 -0
- hinge/stages/exporters/networkx_exporter.py +57 -0
- hinge/stages/exporters/parquet_exporter.py +13 -0
- hinge/stages/projection/__init__.py +0 -0
- hinge/stages/projection/dbt_projection.py +342 -0
- hinge/stages/projection/specs/__init__.py +0 -0
- hinge/stages/projection/specs/artifact_reference.py +14 -0
- hinge/stages/projection/specs/co_commit_user_user.py +14 -0
- hinge/stages/projection/specs/co_edit_file_user_user.py +14 -0
- hinge/stages/projection/specs/co_edit_line_user_user.py +14 -0
- hinge/stages/projection/specs/dev_interaction.py +26 -0
- hinge/stages/projection/specs/developer_repo_affiliation.py +15 -0
- hinge/stages/projection/specs/follow_user_user.py +14 -0
- hinge/stages/projection/specs/fork_repo_repo.py +14 -0
- hinge/stages/projection/specs/issue_co_participation.py +14 -0
- hinge/stages/projection/specs/issue_participation.py +14 -0
- hinge/stages/projection/specs/pr_author_reviewer.py +14 -0
- hinge/stages/projection/specs/pr_participation.py +14 -0
- hinge/stages/projection/specs/pr_reviewer_coreview.py +14 -0
- hinge/stages/projection/specs/repo_shared_contributors.py +14 -0
- hinge/stages/projection/specs/star_user_repo.py +15 -0
- hinge/stages/projection/specs/user_mention_user.py +14 -0
- hinge/stages/projection/specs/watch_user_repo.py +14 -0
- hinge/stages/readers/__init__.py +0 -0
- hinge/stages/readers/_numfocus_contract_adapter.py +314 -0
- hinge/stages/readers/numfocus_reader.py +69 -0
- hinge/stages/store/__init__.py +0 -0
- hinge/stages/store/duckdb_store.py +466 -0
- hinge-0.1.0.dist-info/METADATA +309 -0
- hinge-0.1.0.dist-info/RECORD +111 -0
- hinge-0.1.0.dist-info/WHEEL +4 -0
- hinge-0.1.0.dist-info/entry_points.txt +35 -0
- hinge-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: hinge
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Heterogeneous Information Network tool for GitHub research datasets
|
|
5
|
+
Project-URL: Homepage, https://github.com/marcotonnarelli/hinge
|
|
6
|
+
Project-URL: Repository, https://github.com/marcotonnarelli/hinge
|
|
7
|
+
Project-URL: Issues, https://github.com/marcotonnarelli/hinge/issues
|
|
8
|
+
Author-email: Filippo Scaramuzza <f.scaramuzza@tue.nl>, Marco Tonnarelli <m.tonnarelli@tue.nl>, Gergő Bocsárdi <a.g.bocsardi@tue.nl>
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: dbt,duckdb,github,graph,heterogeneous-information-network,mining
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Intended Audience :: Science/Research
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
19
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
20
|
+
Requires-Python: >=3.12
|
|
21
|
+
Requires-Dist: dbt-core>=1.8
|
|
22
|
+
Requires-Dist: dbt-duckdb>=1.8
|
|
23
|
+
Requires-Dist: duckdb>=1.0
|
|
24
|
+
Requires-Dist: networkx>=3.3
|
|
25
|
+
Requires-Dist: orjson>=3.10
|
|
26
|
+
Requires-Dist: pyarrow>=16.0
|
|
27
|
+
Requires-Dist: pydantic>=2.7
|
|
28
|
+
Requires-Dist: pyyaml>=6.0
|
|
29
|
+
Requires-Dist: rich>=13.7
|
|
30
|
+
Requires-Dist: typer>=0.12
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: import-linter>=2.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
34
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest>=8.2; extra == 'dev'
|
|
36
|
+
Requires-Dist: ruff>=0.5; extra == 'dev'
|
|
37
|
+
Requires-Dist: types-pyyaml; extra == 'dev'
|
|
38
|
+
Provides-Extra: tui
|
|
39
|
+
Requires-Dist: textual>=0.70; extra == 'tui'
|
|
40
|
+
Provides-Extra: web
|
|
41
|
+
Requires-Dist: fastapi>=0.111; extra == 'web'
|
|
42
|
+
Requires-Dist: uvicorn>=0.30; extra == 'web'
|
|
43
|
+
Description-Content-Type: text/markdown
|
|
44
|
+
|
|
45
|
+
# HINGE — Heterogeneous Information Network for Generalized Extraction
|
|
46
|
+
|
|
47
|
+
`hinge` ingests GitHub activity datasets (JSONL today; CSV/Parquet planned), persists
|
|
48
|
+
them as a typed multi-relational graph in DuckDB, and exposes **projections** —
|
|
49
|
+
dbt SQL models that derive task-specific sub-graphs and export them to formats
|
|
50
|
+
consumed by Gephi, NetworkX, igraph, etc.
|
|
51
|
+
|
|
52
|
+
This is a research artefact accompanying an ICSME 2026 Tools and Data Showcase submission.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Quick start
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# 1. Install (uv is the only supported package manager)
|
|
60
|
+
uv sync --all-extras
|
|
61
|
+
|
|
62
|
+
# 2. Ingest a dataset
|
|
63
|
+
uv run hinge ingest path/to/events.jsonl --reader numfocus
|
|
64
|
+
# → ingested 48 elements → 29 nodes, 19 edges (0 violations)
|
|
65
|
+
# → Dataset ID: 78fc87c370944dc2b4a4e2d4bdd97ce1
|
|
66
|
+
|
|
67
|
+
# 3. Use the printed Dataset ID to run a projection and export
|
|
68
|
+
uv run hinge export \
|
|
69
|
+
--dataset 78fc87c370944dc2b4a4e2d4bdd97ce1 \
|
|
70
|
+
--projection user-user-repo-collaboration \
|
|
71
|
+
--format gml \
|
|
72
|
+
-o out/graph.gml
|
|
73
|
+
|
|
74
|
+
# 4. Inspect all ingested datasets
|
|
75
|
+
uv run hinge list datasets
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Or via Docker:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
docker compose build
|
|
82
|
+
cp path/to/events.jsonl ./data/
|
|
83
|
+
docker compose run --rm hinge hinge ingest /data/events.jsonl --reader numfocus
|
|
84
|
+
docker compose run --rm hinge hinge export \
|
|
85
|
+
--dataset <id> --projection user-user-repo-collaboration --format gml -o /output/graph.gml
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The DuckDB store lives at `$HINGE_STORE_PATH` (default `./network.duckdb`
|
|
89
|
+
locally, `/store/network.duckdb` inside the container). Multiple datasets
|
|
90
|
+
can coexist in the same file — each ingest run gets a unique Dataset ID.
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## HIN contract + adapters
|
|
95
|
+
|
|
96
|
+
The source-agnostic core starts at the adapter contract tables:
|
|
97
|
+
|
|
98
|
+
```text
|
|
99
|
+
source-specific adapter
|
|
100
|
+
-> contract_accounts / contract_repositories / contract_artifacts / contract_relations
|
|
101
|
+
-> hin_nodes / hin_edges
|
|
102
|
+
-> dbt projections
|
|
103
|
+
-> exporters
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The `numfocus` reader uses a DuckDB adapter for this repo's NumFocus Actions
|
|
107
|
+
JSONL scrape. It is intentionally source-specific: it knows paths like
|
|
108
|
+
`$.actor.login` and `$.details.pull_request.id`. Other data sources should
|
|
109
|
+
implement their own adapter that writes the same `contract_*` tables; then the
|
|
110
|
+
HIN views and dbt recipes can run unchanged.
|
|
111
|
+
|
|
112
|
+
The generic Python `ReaderStage` path is still available for simple custom
|
|
113
|
+
readers, but large JSONL ingests should use a DuckDB/SQL contract adapter where
|
|
114
|
+
possible.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Adding a new projection
|
|
119
|
+
|
|
120
|
+
A projection is a dbt SQL model that derives a task-specific sub-graph from
|
|
121
|
+
the typed HIN stored in DuckDB. Adding one requires exactly four files/edits
|
|
122
|
+
and no changes to the kernel.
|
|
123
|
+
|
|
124
|
+
### Step 1 — Write the SQL model
|
|
125
|
+
|
|
126
|
+
Create `hinge/dbt/models/networks/<name>.sql`. The model should read from
|
|
127
|
+
the canonical HIN dbt models and produce a fixed set of columns:
|
|
128
|
+
|
|
129
|
+
```sql
|
|
130
|
+
-- Inputs (prefer these canonical HIN models, never the raw tables)
|
|
131
|
+
{{ ref('hin_nodes') }}
|
|
132
|
+
{{ ref('hin_edges') }}
|
|
133
|
+
|
|
134
|
+
-- Output (prefer the network_edges macro; it emits this standard schema)
|
|
135
|
+
network_edges(
|
|
136
|
+
recipe_name, recipe_version,
|
|
137
|
+
source_node_id, source_node_type,
|
|
138
|
+
target_node_id, target_node_type,
|
|
139
|
+
directed, edge_type,
|
|
140
|
+
weight, weight_kind,
|
|
141
|
+
n_contexts, n_events,
|
|
142
|
+
first_seen_at, last_seen_at,
|
|
143
|
+
time_bin, bot_policy,
|
|
144
|
+
properties
|
|
145
|
+
)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
`DbtProjection` converts this richer schema into `TypedEdge` objects for existing
|
|
149
|
+
exporters, merging standard fields and `properties` into edge attrs.
|
|
150
|
+
|
|
151
|
+
The upstream HIN models are built from `active_*` views created by the store
|
|
152
|
+
immediately before dbt runs — they are already filtered to the requested
|
|
153
|
+
`dataset_id`, so network SQL never needs to reference `dataset_id` at all.
|
|
154
|
+
|
|
155
|
+
**Nodes-only projections:** the pipeline derives output nodes from the union
|
|
156
|
+
of `source_node_id` and `target_node_id` in the result table. A projection that
|
|
157
|
+
emits no edges will therefore produce no nodes either. The workaround is to use
|
|
158
|
+
**self-loop edges** (`source_node_id = target_node_id`): they make the nodes
|
|
159
|
+
visible to the exporter, carry metadata in `properties`, and can be filtered out
|
|
160
|
+
in downstream tools with `G.remove_edges_from(nx.selfloop_edges(G))`.
|
|
161
|
+
|
|
162
|
+
See [dev_interaction.sql](hinge/dbt/models/networks/dev_interaction.sql)
|
|
163
|
+
for a full working example with a documented input/output contract.
|
|
164
|
+
|
|
165
|
+
### Step 2 — Create the spec module
|
|
166
|
+
|
|
167
|
+
Create `hinge/stages/projection/specs/<name>.py` and expose a `SPEC` constant:
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
from hinge.kernel.projection.projection_spec import ProjectionSpec
|
|
171
|
+
|
|
172
|
+
SPEC = ProjectionSpec(
|
|
173
|
+
name="my-projection", # CLI key: --projection my-projection
|
|
174
|
+
description="...",
|
|
175
|
+
model_name="my_projection", # must match the .sql file stem
|
|
176
|
+
output_node_types=["user"],
|
|
177
|
+
output_edge_types=["my_edge_label"],
|
|
178
|
+
)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
This is a plain value object — no class, no inheritance. The registry loads
|
|
182
|
+
the module and returns the `SPEC` attribute directly.
|
|
183
|
+
|
|
184
|
+
### Step 3 — Register the entry-point
|
|
185
|
+
|
|
186
|
+
Add one line to `pyproject.toml`:
|
|
187
|
+
|
|
188
|
+
```toml
|
|
189
|
+
[project.entry-points."hinge.projection_specs"]
|
|
190
|
+
my-projection = "hinge.stages.projection.specs.my_projection:SPEC"
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Third-party packages can register projections the same way — no fork required.
|
|
194
|
+
|
|
195
|
+
### Step 4 — Re-install so the entry-point is picked up
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
uv sync --all-extras
|
|
199
|
+
uv run hinge list projections # → my-projection should appear
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Entry-points are baked into `.dist-info/entry_points.txt` at install time.
|
|
203
|
+
Without this step the registry will not find the new spec.
|
|
204
|
+
|
|
205
|
+
### Run it
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
uv run hinge export \
|
|
209
|
+
--dataset <id> \
|
|
210
|
+
--projection my-projection \
|
|
211
|
+
--format gml \
|
|
212
|
+
-o output/result.gml
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
### Local SQL custom projection
|
|
216
|
+
|
|
217
|
+
For research-specific variants, write a local dbt model and run it without
|
|
218
|
+
packaging or entry-points:
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
uv run hinge export-sql custom_star_user_repo.sql \
|
|
222
|
+
--dataset <id> \
|
|
223
|
+
--format gml \
|
|
224
|
+
-o output/custom.gml
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
The SQL file is temporarily added to the built-in dbt project, so it can use
|
|
228
|
+
`ref('hin_edges')`, `ref('int_user_artifact_incidence')`, and all macros under
|
|
229
|
+
`hinge/dbt/macros/`. It must still emit the standard `network_edges` schema.
|
|
230
|
+
Use `--name valid_model_name` if the filename is not a valid dbt identifier.
|
|
231
|
+
|
|
232
|
+
See [docs/custom-projections.md](docs/custom-projections.md).
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
## Logging
|
|
237
|
+
|
|
238
|
+
Logs go to **stderr** by default. Use env vars to control verbosity and persistence:
|
|
239
|
+
|
|
240
|
+
| Variable | Purpose | Default |
|
|
241
|
+
|---|---|---|
|
|
242
|
+
| `HINGE_LOG_LEVEL` | `DEBUG` / `INFO` / `WARNING` / `ERROR` | `INFO` |
|
|
243
|
+
| `HINGE_LOG_FILE` | Also write logs to this file at full `DEBUG` detail | _(none)_ |
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
# See all pipeline milestones (default)
|
|
247
|
+
uv run hinge ingest events.jsonl --reader numfocus
|
|
248
|
+
|
|
249
|
+
# See every batch, dbt SQL, store open/close
|
|
250
|
+
HINGE_LOG_LEVEL=DEBUG uv run hinge ingest events.jsonl --reader numfocus
|
|
251
|
+
|
|
252
|
+
# Persist a full debug log to disk (useful for long ingest runs)
|
|
253
|
+
HINGE_LOG_FILE=hinge.log uv run hinge ingest events.jsonl --reader numfocus
|
|
254
|
+
tail -f hinge.log
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
## Common commands
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
# Ingest NumFocus Actions JSONL via the DuckDB -> HIN contract adapter
|
|
263
|
+
uv run hinge ingest events.jsonl --reader numfocus
|
|
264
|
+
|
|
265
|
+
# Inspect stored datasets
|
|
266
|
+
uv run hinge list datasets
|
|
267
|
+
uv run hinge list projections
|
|
268
|
+
uv run hinge list readers
|
|
269
|
+
uv run hinge list exporters
|
|
270
|
+
|
|
271
|
+
# Export
|
|
272
|
+
uv run hinge export --dataset <id> --projection user-user-repo-collaboration --format gml -o out.gml
|
|
273
|
+
|
|
274
|
+
# Dev / CI
|
|
275
|
+
uv run pytest # tests
|
|
276
|
+
uv run ruff check . # lint
|
|
277
|
+
uv run ruff format . # format
|
|
278
|
+
uv run mypy hinge/kernel hinge/frontends # strict type-check
|
|
279
|
+
uv run lint-imports # enforce kernel/stages/frontends boundary
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## Makefile (development)
|
|
285
|
+
|
|
286
|
+
A `Makefile` is provided for quick local iteration. It uses hardcoded defaults
|
|
287
|
+
(fixture file, `numfocus` reader, `user-user-repo-collaboration` projection, GML format) so
|
|
288
|
+
you don't have to remember arguments during development — **not intended for
|
|
289
|
+
production use**.
|
|
290
|
+
|
|
291
|
+
```bash
|
|
292
|
+
make install # uv sync --all-extras
|
|
293
|
+
make run # ingest fixture + export graph in one shot
|
|
294
|
+
make ingest # ingest tests/fixtures/events_10.jsonl --reader numfocus
|
|
295
|
+
make export # export the latest dataset (auto-detects ID from the store)
|
|
296
|
+
make test # pytest
|
|
297
|
+
make lint # ruff check
|
|
298
|
+
make fmt # ruff format
|
|
299
|
+
make typecheck # mypy on kernel + frontends
|
|
300
|
+
make clean # delete output/, dbt artefacts, caches
|
|
301
|
+
make reset # clean + delete network.duckdb (full fresh start)
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Any default can be overridden on the command line:
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
make run READER=numfocus LOG_LEVEL=DEBUG
|
|
308
|
+
make export FORMAT=graphml OUTPUT=output/graph.graphml
|
|
309
|
+
```
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
hinge/__init__.py,sha256=yVsheukxlHtBh1mKOtlZ441hdyycWVEPKlPNer_J_EM,175
|
|
2
|
+
hinge/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
hinge/config/logging_setup.py,sha256=LJeJuoyraOQgIfxpm71OWQuPwZ2XWi_8Fy7wNR2OXNA,2038
|
|
4
|
+
hinge/config/settings.py,sha256=fWAuyKPxBIcKEStfX1WYGWs3uPBL_SQ_sFeP_DiHCRk,589
|
|
5
|
+
hinge/config/types.yaml,sha256=ZmVJQu22HJ9YDRLc19iaxu92IxFS0uUjsr3m1Nk-auM,1110
|
|
6
|
+
hinge/dbt/.user.yml,sha256=mJg0YPvdYshUURVJfSSgmJPBXTd9uvgTwN-RWj06DvQ,41
|
|
7
|
+
hinge/dbt/dbt_project.yml,sha256=BDvNgBk8tAEXx_pDYL2TcNQWluY8TJ09HOfFbesuEJM,290
|
|
8
|
+
hinge/dbt/profiles.yml,sha256=oMvY5y8Nzpx5RSVRk9L1QMB51BjKv8tgooJPAt5nxF8,253
|
|
9
|
+
hinge/dbt/macros/apply_time_window.sql,sha256=_DQBWR9eUbKaDVUYNWtGKTyjA0OhGR0b13x9OB_8s0s,364
|
|
10
|
+
hinge/dbt/macros/assert_recipe_supported.sql,sha256=B4LcXQ7gPxsD9Rp8tw3syj_XnBH8SD-CxcLX0juHQuA,3288
|
|
11
|
+
hinge/dbt/macros/build_incidence.sql,sha256=BWh5OLstIp1FY1ebapieC5KS0Dfr9G3wOn0BNkpgCt8,1284
|
|
12
|
+
hinge/dbt/macros/collapse_path.sql,sha256=2LMT_cRGMGGSQjJPBpT-aqg6VfQPD94t9UCGARsCoQ4,984
|
|
13
|
+
hinge/dbt/macros/filter_bots.sql,sha256=fRcYdqE3JE5AAX-MNxkyV6eN_uk3OmGe6-U2vO62Z1Y,983
|
|
14
|
+
hinge/dbt/macros/network_edges.sql,sha256=k0myGty2oDeKz2ePjnhvTCpDtJITTVbuqDcuduOCMvw,1177
|
|
15
|
+
hinge/dbt/macros/project_bipartite.sql,sha256=kKZwWc5yInls089Z-SiFWkEBdvsY1DozqPJt6B2TUo8,1238
|
|
16
|
+
hinge/dbt/macros/slice_edges.sql,sha256=hnp4Qwa2g6G5xAltAqtjj5GWIxQlXwH_8M_3bCYlh1I,1342
|
|
17
|
+
hinge/dbt/models/hin/hin_accounts.sql,sha256=JvHdFsq2GTvyOaolOuHR4VyJZF4iu-aycLhvXv1wf6c,398
|
|
18
|
+
hinge/dbt/models/hin/hin_artifacts.sql,sha256=t6MuGYkXp-dmkPqeOCCDftEG7fN6riD0bP8WKOErURE,468
|
|
19
|
+
hinge/dbt/models/hin/hin_capabilities.sql,sha256=hkDJYDybIf3JkLsVqZqsT2bU5_7TnHk0C0Lq5HwnQkI,2684
|
|
20
|
+
hinge/dbt/models/hin/hin_edges.sql,sha256=oTF0JrdcloxAj2HSCnpg9x8hXta-pRFR7FaRHBjGq3Q,1662
|
|
21
|
+
hinge/dbt/models/hin/hin_nodes.sql,sha256=m3IMoUwYvUTYCxsDjyFGki1qhv0WtA744TLYluqWrrQ,925
|
|
22
|
+
hinge/dbt/models/hin/hin_repositories.sql,sha256=lGRLQTHsXeDEBMxfbxx6C7e95p-6PheBRIpNwAy_KsQ,453
|
|
23
|
+
hinge/dbt/models/intermediate/int_developer_repo_affiliation.sql,sha256=ynP_X1DN6dBFWC_gT0rqJz6eK1Lgz9_ZWj3tsik0zmg,846
|
|
24
|
+
hinge/dbt/models/intermediate/int_user_artifact_incidence.sql,sha256=FPqqsZP5i9sjmF9jLHioR_MHJ2A9fgZoNRhqAr9EfC0,412
|
|
25
|
+
hinge/dbt/models/networks/artifact_reference.sql,sha256=z_IR0t-V5Hlimuz88fbzG6kiIL7DUK7OiGmah3YSufY,806
|
|
26
|
+
hinge/dbt/models/networks/co_commit_user_user.sql,sha256=7-u2EzZcU7yhC1p5Wxas7SUDzQWN1lkVAFrFKn9uiEw,1315
|
|
27
|
+
hinge/dbt/models/networks/co_edit_file_user_user.sql,sha256=Vs6Gp6qtCkFEc7Ei4oDGIDopDw4KhvXy06NDPIa2-DA,1282
|
|
28
|
+
hinge/dbt/models/networks/co_edit_line_user_user.sql,sha256=M3JMuqVYO2qT8ZQW2GChqvqGbBCLrtEg99kWtOAhpoc,1292
|
|
29
|
+
hinge/dbt/models/networks/dev_interaction.sql,sha256=RCA9MIt-wmh3koIntS_3ohsqilboIGTZFrH9i8nxHkY,4822
|
|
30
|
+
hinge/dbt/models/networks/developer_repo_affiliation.sql,sha256=NmIikSKba95ysDeSsDijTPhIvqpK79APoxtnWy1ZO18,596
|
|
31
|
+
hinge/dbt/models/networks/follow_user_user.sql,sha256=m7h24h8Hq7HDlOmtIeqzIsjqFJ4NxvdhUnqsxHnu9CQ,701
|
|
32
|
+
hinge/dbt/models/networks/fork_repo_repo.sql,sha256=METms8QZm9OST6Y8eh8DbqHm8THg7sU18fUkFLu-onA,693
|
|
33
|
+
hinge/dbt/models/networks/issue_co_participation.sql,sha256=8Z_dqSRn0-FIVqapOo6lre3B8XsSn0Qj5WBrE5k_pFE,1446
|
|
34
|
+
hinge/dbt/models/networks/issue_participation.sql,sha256=ja1D7JRzIJ6rQh3eNG_saYMjbErV_FrpDAZaEapE9nE,1150
|
|
35
|
+
hinge/dbt/models/networks/pr_author_reviewer.sql,sha256=TI9qovx-wxVyeCC82iL5l0pvdPAv-fyJpKeS8J1znuM,1987
|
|
36
|
+
hinge/dbt/models/networks/pr_participation.sql,sha256=oP6TkntxNnCvfLs42Z3yRL8T6vjiGjdUDHOdco9EoIY,1171
|
|
37
|
+
hinge/dbt/models/networks/pr_reviewer_coreview.sql,sha256=S9G-Bk0slp-qWFHDw19wXZWPuPdfJqt5ClPVsWueghs,1307
|
|
38
|
+
hinge/dbt/models/networks/repo_shared_contributors.sql,sha256=UxMALaxzolxR3g5FP5cHAsKn-YiWAQoj00fERMS1vEE,1155
|
|
39
|
+
hinge/dbt/models/networks/star_user_repo.sql,sha256=cROUkE5ecFll1dFlLIEViFP457H-Ol1J0B5-RIbzKoc,699
|
|
40
|
+
hinge/dbt/models/networks/user_mention_user.sql,sha256=eZ8WMxySPA_UoyTl4KYAfCy9eM3tiyYHM1X8SP1I8eE,1938
|
|
41
|
+
hinge/dbt/models/networks/watch_user_repo.sql,sha256=yp2gl3SzpiAp2e7dvcl8Ki3P9Wl5vLNmUgAD41olmGY,697
|
|
42
|
+
hinge/dbt/models/sources/sources.yml,sha256=9g_nw6bndhlrMWH3mjcVC1vp8RUMj_vxmEwVg-WjcW4,2358
|
|
43
|
+
hinge/dbt/models/staging/stg_accounts.sql,sha256=kf2D__UMe5RQbMd_3qxW33ljg6UOgrnpxnoNWOtc6Nw,97
|
|
44
|
+
hinge/dbt/models/staging/stg_adapter_manifest.sql,sha256=dHAnBRQYPy6crCChP_lZAqCW6HdhBUAp1tljVmcqaDM,105
|
|
45
|
+
hinge/dbt/models/staging/stg_artifacts.sql,sha256=T-oUZTSHZYI7X3NH-65KZCRi3qRvEGAqIAsmdHfQKzI,98
|
|
46
|
+
hinge/dbt/models/staging/stg_relations.sql,sha256=hSIMOiuI5-tQ8YrqUct9yR5NsYPfiSf46lYyBnTtP5E,98
|
|
47
|
+
hinge/dbt/models/staging/stg_repositories.sql,sha256=QPbEdFeQYZg8VAaE7kLlZl4xXubFQGFjdvaVDbZct1c,101
|
|
48
|
+
hinge/dbt/seeds/ref_recipe_requirements.csv,sha256=Wd5PcN4MSSHyq4CppT8sulHtb3oEdH2GzjAsSSQBYPs,1210
|
|
49
|
+
hinge/frontends/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
50
|
+
hinge/frontends/lib.py,sha256=rZztKwXP3yljJzHnJqLjrUY2-RT54jKAML2kemN_OTQ,4627
|
|
51
|
+
hinge/frontends/cli/__init__.py,sha256=8lzSTHavtyxQaXcuqkD5EBY6MPHn-icoIw7Am6MCSTQ,59
|
|
52
|
+
hinge/frontends/cli/app.py,sha256=C-mSzUtqBHenYbPui1H7Z4cqtaSYEbjcBKxLcKoQgoU,6638
|
|
53
|
+
hinge/frontends/tui/__init__.py,sha256=JHkc1MUsZYwDl-iNVBq939qznQo3ol0X7S32XYQv8eU,284
|
|
54
|
+
hinge/frontends/web/__init__.py,sha256=XcrUOdp_DJNe8Pi2CiOnZXRqZfWB-zKBdE-ovmyVeLE,205
|
|
55
|
+
hinge/kernel/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
56
|
+
hinge/kernel/registry.py,sha256=ryAzebg4JwcplxVs8QWzmBY7FNoVtuCH8BMe-6al3pQ,2381
|
|
57
|
+
hinge/kernel/runner.py,sha256=HDbz-Bv7NefsRMgRksRLOLK9tSc6N095Iv01T4_1R2w,8137
|
|
58
|
+
hinge/kernel/projection/__init__.py,sha256=4iZA_OXzqOCq5lACPfcbTp4EMxDx7AkcirvlN3SrpMw,285
|
|
59
|
+
hinge/kernel/projection/projected_graph.py,sha256=U1koWmW5GCzL2fIocTjpFnPqhm4J3IvJiC8r2Wch0lw,931
|
|
60
|
+
hinge/kernel/projection/projection_spec.py,sha256=gbKtj9oUPzPoysGQSjqOncspnMM_G0rcSC5iRjKddVI,1084
|
|
61
|
+
hinge/kernel/protocols/__init__.py,sha256=i0MUWeLlxQXCktqaqSrXzifgKmSwtkq5o-THoEt7Q9g,674
|
|
62
|
+
hinge/kernel/protocols/dataset_view.py,sha256=Z8Nv0QvVTRTWX67y8fZ1dkecblKwuEAq0V1PQ8Rm-0Y,988
|
|
63
|
+
hinge/kernel/protocols/exporter_stage.py,sha256=e2Gb8QbJU9qZp9U3PSVKoCq69ipHmCn7NAO5efhioS8,635
|
|
64
|
+
hinge/kernel/protocols/projection_stage.py,sha256=bxFvvXfMRfvs0Z6CiXILtQlZOn07UVkrqcy0wPfC9zM,1051
|
|
65
|
+
hinge/kernel/protocols/reader_stage.py,sha256=svnloypqoxqYcB6GIpnH8FVk3VkxRTh2JC4zjakcuyI,1823
|
|
66
|
+
hinge/kernel/protocols/store_stage.py,sha256=zUQfloR1aaK4YrRbo_OY_Ih3Lpoio77lbhnutr5V3-g,2272
|
|
67
|
+
hinge/kernel/schema/__init__.py,sha256=MhSCAbx5jJX7PiqxGoHmF3106C80H3yctMJYAgfDLvs,363
|
|
68
|
+
hinge/kernel/schema/hin_schema.py,sha256=u2RazJ2nSVGrza8XNs4zZMqsm5y-eP1YoB4D6Nf3B1k,1277
|
|
69
|
+
hinge/kernel/schema/schema_violation.py,sha256=ahZHb1XlWIixp2xMYsfSvaXuCsZyQb5M2rnrfjSprAY,525
|
|
70
|
+
hinge/kernel/schema/typed_edge.py,sha256=dhdFYbeExR1Nvuj4kM7b_kiAe6KIJYx4B5uG0jM_G1k,592
|
|
71
|
+
hinge/kernel/schema/typed_node.py,sha256=enZ2JlKQzuKMsNAAWjxloxgKV34QRJUwsqVCVfBj3bQ,444
|
|
72
|
+
hinge/stages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
73
|
+
hinge/stages/exporters/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
74
|
+
hinge/stages/exporters/csv_exporter.py,sha256=5uJsIvLufFoSSNRbaQ3A1w8utoP9fTeooL12niyAbpk,2369
|
|
75
|
+
hinge/stages/exporters/dot_exporter.py,sha256=JCY8PMs2BdnaFyMHzfgDauFTIl_BSvTCGtiZiDsUBu4,434
|
|
76
|
+
hinge/stages/exporters/gexf_exporter.py,sha256=iU3gUT3NyK6wimi_Hy_AxbKdjU1K6A7QTUNxg3p-t28,436
|
|
77
|
+
hinge/stages/exporters/gml_exporter.py,sha256=2M1ZsJ3l55W_P3th8Nhy668dndLAGaSk6xWj8CyIRbY,2524
|
|
78
|
+
hinge/stages/exporters/graphml_exporter.py,sha256=U028uKovQf4QRK2Hf-P1Q9qga_4Ez_W0mt0DIT5Z43c,442
|
|
79
|
+
hinge/stages/exporters/jsonld_exporter.py,sha256=ja6O0-aH7JTT8s36J7LjU4x2ILbZaHO4Fqyfqag2tHc,440
|
|
80
|
+
hinge/stages/exporters/networkx_exporter.py,sha256=hm4JAYkIQqujvbe_K6723QVOEnnUTfWuB8hLXb7Xnbs,1790
|
|
81
|
+
hinge/stages/exporters/parquet_exporter.py,sha256=oA6a7qnSc20yIorPDpSwz_PnCoaDHTAuXqZbF8gsoSk,442
|
|
82
|
+
hinge/stages/projection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
83
|
+
hinge/stages/projection/dbt_projection.py,sha256=IBRf3dAd-VU8jvwTrntAnSD90D8W0MCpObM9XZCTzSQ,13867
|
|
84
|
+
hinge/stages/projection/specs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
85
|
+
hinge/stages/projection/specs/artifact_reference.py,sha256=MnlDLdsH28GgYrJnd-i6KVrU-VjOu33sEMjBChwYCWA,513
|
|
86
|
+
hinge/stages/projection/specs/co_commit_user_user.py,sha256=VBh_BznSk_MocXdthVULhcyOar_ujui67D9KZHjyAao,456
|
|
87
|
+
hinge/stages/projection/specs/co_edit_file_user_user.py,sha256=Uo6dn2eKwfac2elaH2eyhX7My_hGmTl-vSqD9W0JMVY,438
|
|
88
|
+
hinge/stages/projection/specs/co_edit_line_user_user.py,sha256=Z2c-QzkXkakub02ys5La8lCXEVEPwNJTY47bN3TWjwc,447
|
|
89
|
+
hinge/stages/projection/specs/dev_interaction.py,sha256=VyD08reBNg_ONliDEqeUb7iMnGGvY99TJN-aigi8Zng,1010
|
|
90
|
+
hinge/stages/projection/specs/developer_repo_affiliation.py,sha256=s7kRN7bZvHpTDDn_JQdoN6TjBdOx5HTAPY7dUV24fSI,545
|
|
91
|
+
hinge/stages/projection/specs/follow_user_user.py,sha256=7NuanWqd375m4pKObLgRlU3Y5cXyT_zAhV2OKdlT4z8,434
|
|
92
|
+
hinge/stages/projection/specs/fork_repo_repo.py,sha256=o2qH9mc93yjI5LKEDNTTD2-XUvqORAruTCTF6uMSCs0,427
|
|
93
|
+
hinge/stages/projection/specs/issue_co_participation.py,sha256=bhLDyii34qeNpgOMSFHJkeK2ZzX_rYKq7f4YSbS9TZ0,457
|
|
94
|
+
hinge/stages/projection/specs/issue_participation.py,sha256=QNEzGOcL0PIrzAzqCOkc-LTCUXf9S5BEbi4j8UzXnew,466
|
|
95
|
+
hinge/stages/projection/specs/pr_author_reviewer.py,sha256=h2b3uBHpQowuJXVud3QtUp5WyAazCAUZ9nu3yBzLRkA,438
|
|
96
|
+
hinge/stages/projection/specs/pr_participation.py,sha256=eD8uN3gJTPABIWmn4S7Fq0TkTlaJ5Y8WyyK4pYWfKx8,471
|
|
97
|
+
hinge/stages/projection/specs/pr_reviewer_coreview.py,sha256=ibxg38M6rtE900WYbyMyplf2HiNYfIysFaEFAtCJkOU,442
|
|
98
|
+
hinge/stages/projection/specs/repo_shared_contributors.py,sha256=KzZkKv1_sKN4x8T2kLdbvIooZZGAs9BgH1IGnvzNvuY,472
|
|
99
|
+
hinge/stages/projection/specs/star_user_repo.py,sha256=5ib-u7KSavgbtVd_BdSKzeZiFc2eSrZ51BVrhpVl7_w,476
|
|
100
|
+
hinge/stages/projection/specs/user_mention_user.py,sha256=WFYAn915_ZOUl4FCirHJln3cTdKrAp3loRxJqYMhJC8,443
|
|
101
|
+
hinge/stages/projection/specs/watch_user_repo.py,sha256=ZJylv-XXe-4urBrdWpgiuOLctsAounPEh47ffq8r-Ic,455
|
|
102
|
+
hinge/stages/readers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
103
|
+
hinge/stages/readers/_numfocus_contract_adapter.py,sha256=5owQzuMgaaFqFLdWUvUQVeC9qCGuinnoR8QhmJ2RU1A,21924
|
|
104
|
+
hinge/stages/readers/numfocus_reader.py,sha256=dXFCjUGIy69CscNo2dctRFn01qE35EsXNYz9cnq282E,2653
|
|
105
|
+
hinge/stages/store/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
106
|
+
hinge/stages/store/duckdb_store.py,sha256=eZ9NLbodc_vtZ90hzR7rdo8WLfGD7Hyh8gLEML1xuoc,20155
|
|
107
|
+
hinge-0.1.0.dist-info/METADATA,sha256=dZSn08Ct9oeGFoPyx4pFXaQc_ATMCDPam3WewpkBINw,10404
|
|
108
|
+
hinge-0.1.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
|
|
109
|
+
hinge-0.1.0.dist-info/entry_points.txt,sha256=R0nw4ZNq1CBh87Y0NU6wXCIIgZNwEeMEhqvmSNcRGVY,1856
|
|
110
|
+
hinge-0.1.0.dist-info/licenses/LICENSE,sha256=Yc8_1CXgv6_b-qpi-CU0Sq0fqJr570EtDQEgc-rs5CA,1075
|
|
111
|
+
hinge-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
[console_scripts]
|
|
2
|
+
hinge = hinge.frontends.cli.app:app
|
|
3
|
+
|
|
4
|
+
[hinge.exporters]
|
|
5
|
+
csv = hinge.stages.exporters.csv_exporter:CsvExporter
|
|
6
|
+
gml = hinge.stages.exporters.gml_exporter:GmlExporter
|
|
7
|
+
networkx = hinge.stages.exporters.networkx_exporter:NetworkXExporter
|
|
8
|
+
|
|
9
|
+
[hinge.projection_specs]
|
|
10
|
+
artifact-artifact-reference = hinge.stages.projection.specs.artifact_reference:SPEC
|
|
11
|
+
repo-repo-fork = hinge.stages.projection.specs.fork_repo_repo:SPEC
|
|
12
|
+
repo-repo-shared-contributors = hinge.stages.projection.specs.repo_shared_contributors:SPEC
|
|
13
|
+
user-issue-participation = hinge.stages.projection.specs.issue_participation:SPEC
|
|
14
|
+
user-pr-participation = hinge.stages.projection.specs.pr_participation:SPEC
|
|
15
|
+
user-repo-affiliation = hinge.stages.projection.specs.developer_repo_affiliation:SPEC
|
|
16
|
+
user-repo-star = hinge.stages.projection.specs.star_user_repo:SPEC
|
|
17
|
+
user-repo-watch = hinge.stages.projection.specs.watch_user_repo:SPEC
|
|
18
|
+
user-user-co-commit = hinge.stages.projection.specs.co_commit_user_user:SPEC
|
|
19
|
+
user-user-co-edit-file = hinge.stages.projection.specs.co_edit_file_user_user:SPEC
|
|
20
|
+
user-user-co-edit-line = hinge.stages.projection.specs.co_edit_line_user_user:SPEC
|
|
21
|
+
user-user-follow = hinge.stages.projection.specs.follow_user_user:SPEC
|
|
22
|
+
user-user-issue-co-participation = hinge.stages.projection.specs.issue_co_participation:SPEC
|
|
23
|
+
user-user-mention = hinge.stages.projection.specs.user_mention_user:SPEC
|
|
24
|
+
user-user-pr-author-reviewer = hinge.stages.projection.specs.pr_author_reviewer:SPEC
|
|
25
|
+
user-user-pr-co-review = hinge.stages.projection.specs.pr_reviewer_coreview:SPEC
|
|
26
|
+
user-user-repo-collaboration = hinge.stages.projection.specs.dev_interaction:SPEC
|
|
27
|
+
|
|
28
|
+
[hinge.projections]
|
|
29
|
+
dbt = hinge.stages.projection.dbt_projection:DbtProjection
|
|
30
|
+
|
|
31
|
+
[hinge.readers]
|
|
32
|
+
numfocus = hinge.stages.readers.numfocus_reader:NumFocusReader
|
|
33
|
+
|
|
34
|
+
[hinge.stores]
|
|
35
|
+
duckdb = hinge.stages.store.duckdb_store:DuckDBStore
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Filippo Scaramuzza
|
|
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.
|