rgrid-python 4.5.3__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.
@@ -0,0 +1,489 @@
1
+ Metadata-Version: 2.4
2
+ Name: rgrid-python
3
+ Version: 4.5.3
4
+ Summary: Python port of the R grid package (tracks R grid 4.5.3)
5
+ Project-URL: Homepage, https://github.com/Bio-Babel/grid_py
6
+ Project-URL: Repository, https://github.com/Bio-Babel/grid_py
7
+ Project-URL: Issues, https://github.com/Bio-Babel/grid_py/issues
8
+ Project-URL: Documentation, https://github.com/Bio-Babel/grid_py#readme
9
+ Author-email: Jeffery Liu <jeffliu.lucky@gmail.com>
10
+ License-Expression: Artistic-2.0
11
+ License-File: LICENSE
12
+ Keywords: R-port,ggplot2,graphics,grid,scientific-visualization,visualization
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Science/Research
16
+ Classifier: License :: OSI Approved :: Artistic License
17
+ Classifier: Operating System :: MacOS
18
+ Classifier: Operating System :: POSIX :: Linux
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Topic :: Multimedia :: Graphics
24
+ Classifier: Topic :: Scientific/Engineering :: Visualization
25
+ Classifier: Typing :: Typed
26
+ Requires-Python: >=3.10
27
+ Requires-Dist: numpy>=1.24
28
+ Requires-Dist: pycairo>=1.20
29
+ Provides-Extra: dev
30
+ Requires-Dist: build; extra == 'dev'
31
+ Requires-Dist: pytest; extra == 'dev'
32
+ Requires-Dist: pytest-cov; extra == 'dev'
33
+ Requires-Dist: ruff; extra == 'dev'
34
+ Requires-Dist: twine; extra == 'dev'
35
+ Provides-Extra: docs
36
+ Requires-Dist: mkdocs; extra == 'docs'
37
+ Requires-Dist: mkdocs-jupyter; extra == 'docs'
38
+ Requires-Dist: mkdocs-material; extra == 'docs'
39
+ Requires-Dist: mkdocstrings[python]; extra == 'docs'
40
+ Description-Content-Type: text/markdown
41
+
42
+ # grid_py
43
+
44
+ Python port of the R **grid** package.
45
+
46
+ ## Installation
47
+
48
+ ```bash
49
+ pip install rgrid-python
50
+ ```
51
+
52
+ The importable package name is `grid_py`:
53
+
54
+ ```python
55
+ import grid_py
56
+ ```
57
+
58
+ ### System requirements
59
+
60
+ `grid_py` depends on [`pycairo`](https://pypi.org/project/pycairo/), which
61
+ builds against the system **cairo** library. Install the system package
62
+ *before* `pip install rgrid-python`:
63
+
64
+ | Platform | Command |
65
+ |---|---|
66
+ | Ubuntu / Debian | `sudo apt install libcairo2-dev pkg-config python3-dev` |
67
+ | Fedora / RHEL | `sudo dnf install cairo-devel pkgconf-pkg-config python3-devel` |
68
+ | macOS (Homebrew) | `brew install cairo pkg-config` |
69
+ | Windows | `conda install -c conda-forge pycairo` *(recommended; the MSVC build is fiddly)* |
70
+
71
+ `conda install -c conda-forge pycairo` is also the easiest route on Linux /
72
+ macOS if you prefer not to touch system packages.
73
+
74
+ ### Development install
75
+
76
+ ```bash
77
+ git clone https://github.com/Bio-Babel/grid_py
78
+ cd grid_py
79
+ pip install -e ".[dev]"
80
+ pytest # 2600+ tests
81
+ ```
82
+
83
+ ## Quick Start
84
+
85
+ ```python
86
+ from grid_py import (
87
+ CairoRenderer, Gpar, Unit, Viewport, GridLayout,
88
+ get_state, grid_draw, grid_newpage,
89
+ push_viewport, pop_viewport,
90
+ rect_grob, text_grob, points_grob, circle_grob,
91
+ unit_c, string_width,
92
+ )
93
+ ```
94
+
95
+ ## The Unit System — Why Layout "Just Works"
96
+
97
+ The central idea of grid is that **sizes are expressions, not numbers**.
98
+ A `Unit` carries both a value and a *strategy* for resolving that value.
99
+ Resolution is deferred until a viewport is pushed — at that point the parent
100
+ dimensions, font metrics, and device DPI are all known, so every unit can
101
+ evaluate itself in context.
102
+
103
+ This means the same layout specification produces correct results on a 72 dpi
104
+ screen, a 300 dpi PDF, a 7-inch plot or a 14-inch poster — with no manual
105
+ tweaking.
106
+
107
+ ### Unit types at a glance
108
+
109
+ | Category | Units | Resolved from |
110
+ |----------|-------|---------------|
111
+ | **Absolute** | `"cm"`, `"inches"`, `"mm"`, `"points"` | Fixed physical conversion |
112
+ | **Relative** | `"npc"` (0-1 fraction of parent) | Parent viewport dimensions |
113
+ | **Font-relative** | `"lines"` (line height), `"char"` (char width) | Current `fontsize` × `lineheight` |
114
+ | **Content-measuring** | `"strwidth"`, `"strheight"` | Cairo text measurement |
115
+ | **Grob-measuring** | `"grobwidth"`, `"grobheight"` | Grob bounding box query |
116
+ | **Flex** | `"null"` | Remaining space (layout only) |
117
+ | **Data** | `"native"` | Viewport `xscale` / `yscale` mapping |
118
+
119
+ ### Mixing units with arithmetic
120
+
121
+ Units of different types can be freely combined. The result is a **compound
122
+ unit** that is evaluated recursively at resolve time:
123
+
124
+ ```python
125
+ # "fill the parent, but leave 2 line-heights of margin on each side"
126
+ width = Unit(1, "npc") - Unit(4, "lines")
127
+
128
+ # "start 1 cm from the right edge"
129
+ x = Unit(1, "npc") - Unit(1, "cm")
130
+
131
+ # also supports min / max across types
132
+ from grid_py import unit_pmin
133
+ safe_width = unit_pmin(Unit(10, "cm"), Unit(1, "npc")) # whichever is smaller
134
+ ```
135
+
136
+ Internally `Unit(1,"npc") - Unit(4,"lines")` is stored as a tree:
137
+
138
+ ```
139
+ sum ──┬── 1.0 npc
140
+ └── -4.0 lines
141
+ ```
142
+
143
+ When the viewport is pushed, each leaf is resolved to inches and summed.
144
+ Changing the font or the device size automatically changes the result.
145
+
146
+ ## Layout Patterns
147
+
148
+ ### Pattern 1 — Adaptive margins with `"lines"`
149
+
150
+ The most common pattern: margins that scale with the font.
151
+
152
+ ```python
153
+ r = CairoRenderer(width=7, height=5, dpi=150)
154
+ get_state().init_device(r)
155
+ grid_newpage()
156
+
157
+ # Title: 2 line-heights tall, pinned to the top
158
+ title_vp = Viewport(
159
+ name="title",
160
+ x=Unit(0.5, "npc"),
161
+ y=Unit(1, "npc") - Unit(1, "lines"),
162
+ width=Unit(1, "npc"),
163
+ height=Unit(2, "lines"),
164
+ )
165
+
166
+ # Plot area: fills the rest, with room for axis labels
167
+ plot_vp = Viewport(
168
+ name="plot",
169
+ x=Unit(0.5, "npc") + Unit(1, "lines"),
170
+ y=Unit(0.5, "npc") - Unit(0.5, "lines"),
171
+ width=Unit(1, "npc") - Unit(4, "lines"),
172
+ height=Unit(1, "npc") - Unit(5, "lines"),
173
+ )
174
+ ```
175
+
176
+ If you later change `Gpar(fontsize=14)` to `fontsize=20`, the margins grow
177
+ proportionally — no constants to update.
178
+
179
+ ### Pattern 2 — Content-driven margins with `string_width`
180
+
181
+ Let the label measure itself:
182
+
183
+ ```python
184
+ label = "Sepal Length (cm)"
185
+ margin = string_width(label) # Unit whose value = rendered width of that string
186
+
187
+ plot_vp = Viewport(
188
+ x=margin + Unit(0.5, "cm"), # left edge = label width + gap
189
+ width=Unit(1, "npc") - margin - Unit(1, "cm"),
190
+ y=Unit(0.5, "npc"),
191
+ height=Unit(1, "npc") - Unit(3, "lines"),
192
+ )
193
+ ```
194
+
195
+ Change the label text → the margin updates automatically.
196
+
197
+ ### Pattern 3 — Flexible grid with `"null"` units
198
+
199
+ `"null"` units divide **remaining space** proportionally, after all absolute
200
+ and relative units have been allocated. This is how `GridLayout` works:
201
+
202
+ ```python
203
+ # Column 1: fixed 3 cm (e.g. y-axis labels)
204
+ # Columns 2-3: split remaining space 2:1
205
+ layout = GridLayout(
206
+ nrow=1, ncol=3,
207
+ widths=unit_c(Unit(3, "cm"), Unit(2, "null"), Unit(1, "null")),
208
+ heights=Unit([1], "null"),
209
+ )
210
+
211
+ main_vp = Viewport(name="main", layout=layout,
212
+ x=Unit(0.5, "npc"), y=Unit(0.5, "npc"),
213
+ width=Unit(1, "npc"), height=Unit(1, "npc"))
214
+ push_viewport(main_vp)
215
+
216
+ # Place children into cells
217
+ for col in [1, 2, 3]:
218
+ cell_vp = Viewport(name=f"cell_{col}",
219
+ layout_pos_row=1, layout_pos_col=col)
220
+ push_viewport(cell_vp)
221
+ grid_draw(rect_grob(x=0.5, y=0.5, width=1, height=1,
222
+ gp=Gpar(fill="grey90", col="grey50")))
223
+ pop_viewport(1)
224
+ ```
225
+
226
+ Resize the device → column 1 stays 3 cm, the rest reflows.
227
+
228
+ ### Pattern 4 — Nested viewports for complex figures
229
+
230
+ Viewports nest. Each child resolves its units against its parent, so you
231
+ can build deeply structured layouts compositionally:
232
+
233
+ ```python
234
+ # Outer: 2-row layout (title + body)
235
+ outer = GridLayout(nrow=2, ncol=1,
236
+ heights=unit_c(Unit(2, "lines"), Unit(1, "null")))
237
+
238
+ # Body: 1×3 panel grid
239
+ inner = GridLayout(nrow=1, ncol=3,
240
+ widths=Unit([1, 1, 1], "null"))
241
+
242
+ push_viewport(Viewport(name="page", layout=outer, ...))
243
+
244
+ # Row 1 — title
245
+ push_viewport(Viewport(layout_pos_row=1, layout_pos_col=1))
246
+ grid_draw(text_grob("My Title", x=0.5, y=0.5, gp=Gpar(fontsize=16, fontface="bold")))
247
+ pop_viewport(1)
248
+
249
+ # Row 2 — panels
250
+ push_viewport(Viewport(layout_pos_row=2, layout_pos_col=1, layout=inner))
251
+ for col in [1, 2, 3]:
252
+ push_viewport(Viewport(layout_pos_row=1, layout_pos_col=col))
253
+ # ... draw panel content using npc coordinates (0-1 within this cell)
254
+ pop_viewport(1)
255
+ pop_viewport(1)
256
+
257
+ pop_viewport(1)
258
+ ```
259
+
260
+ ### The three-layer coordinate pipeline
261
+
262
+ Every coordinate in grid passes through three distinct transformations before
263
+ reaching the device. Understanding these layers is the key to reasoning about
264
+ why layouts are portable and how viewports compose.
265
+
266
+ ```
267
+ ┌─────────────────────────────────────────────────────────────┐
268
+ │ Layer 1: Unit → Viewport-local inches │
269
+ │ │
270
+ │ _transform_to_inches() (_vp_calc.py) │
271
+ │ │
272
+ │ Each unit type has its own rule: │
273
+ │ "npc" → value × parent_width_inches │
274
+ │ "cm" → value / 2.54 │
275
+ │ "lines" → value × fontsize × cex × lineheight / 72 │
276
+ │ "native" → map [scalemin, scalemax] → [0, parent] │
277
+ │ "strwidth" → Cairo text_extents(string).width │
278
+ │ "grobwidth" → grob.width_details() recursive query │
279
+ │ "sum" → Σ recursive resolve of child units │
280
+ │ "null" → 0 (only meaningful inside GridLayout) │
281
+ │ │
282
+ │ Result: a position or dimension in inches, local to the │
283
+ │ current viewport's own coordinate system. │
284
+ ├─────────────────────────────────────────────────────────────┤
285
+ │ Layer 2: Viewport-local inches → Absolute inches │
286
+ │ │
287
+ │ transform_loc_to_device() (_renderer_base.py) │
288
+ │ │
289
+ │ Applies the viewport's accumulated 3×3 affine transform: │
290
+ │ T = Justification × Rotation × Translation × Parent_T │
291
+ │ │
292
+ │ Built at push_viewport() time by calc_viewport_transform() │
293
+ │ Each push multiplies into the parent's matrix, so nested │
294
+ │ viewports compose naturally: │
295
+ │ │
296
+ │ abs_loc = [x_inches, y_inches, 1] @ vp_transform_3x3 │
297
+ │ │
298
+ │ Result: inches from device origin (bottom-left). │
299
+ ├─────────────────────────────────────────────────────────────┤
300
+ │ Layer 3: Absolute inches → Device pixels │
301
+ │ │
302
+ │ inches_to_dev_x/y() (_renderer_base.py) │
303
+ │ │
304
+ │ dev_x = abs_inches_x × DPI │
305
+ │ dev_y = device_height - abs_inches_y × DPI (Y-flip) │
306
+ │ │
307
+ │ Grid uses bottom-left origin; devices use top-left. │
308
+ │ This layer bridges the two. │
309
+ └─────────────────────────────────────────────────────────────┘
310
+ ```
311
+
312
+ A concrete example — drawing a point at `x = Unit(1,"npc") - Unit(2,"lines")`
313
+ inside a child viewport:
314
+
315
+ ```
316
+ User writes: Unit(1, "npc") - Unit(2, "lines") + Unit(0.5, "cm")
317
+
318
+ ▼ arithmetic builds a compound tree
319
+ Stored as: sum ──┬── 1.0 npc
320
+ ├── -2.0 lines
321
+ └── 0.5 cm
322
+
323
+ ── Layer 1 ─────────────────────────────────────────
324
+
325
+ ▼ _transform_to_inches(parent_context)
326
+ Resolve: npc → 1.0 × parent_width_inches = 5.000"
327
+ lines → -2 × fontsize × lineheight / 72 = -0.333"
328
+ cm → 0.5 / 2.54 = 0.197"
329
+ sum → 5.000 - 0.333 + 0.197 = 4.864" (viewport-local)
330
+
331
+ ── Layer 2 ─────────────────────────────────────────
332
+
333
+ ▼ [4.864, y, 1] @ viewport_transform_3x3
334
+ Absolute: account for viewport position, rotation = 5.214" (from device origin)
335
+
336
+ ── Layer 3 ─────────────────────────────────────────
337
+
338
+ ▼ × DPI, Y-flip
339
+ Device: 5.214 × 150 = 782 px
340
+ ```
341
+
342
+ **Why this matters for users:**
343
+
344
+ - **Layer 1** is where your Unit expressions are evaluated. Because each unit
345
+ type knows how to measure itself (text metrics, parent size, font size),
346
+ your layout adapts to context automatically.
347
+ - **Layer 2** is where viewport nesting works. You never compute global
348
+ positions — you work in local coordinates and the transform stack composes
349
+ them.
350
+ - **Layer 3** is invisible to you. It just makes sure the same inches
351
+ produce correct pixels on any device.
352
+
353
+ The net effect: you describe layout in meaningful terms (`"lines"`, `"cm"`,
354
+ `"npc"`, `"strwidth"`), nest viewports freely, and the three-layer pipeline
355
+ ensures the result is correct on every device and at every DPI.
356
+
357
+ ## Backend Architecture
358
+
359
+ grid\_py ships with a pluggable rendering backend system built on a single
360
+ abstract base class (`GridRenderer`). User code is identical across backends —
361
+ swap the renderer instance to switch output formats.
362
+
363
+ ```
364
+ GridRenderer (ABC)
365
+ ┌──────────────────────────┐
366
+ │ viewport transform stack │
367
+ │ unit resolution │
368
+ │ coordinate system mgmt │
369
+ │ 29 abstract methods │
370
+ └────────────┬─────────────┘
371
+ ┌─────┴──────┐
372
+ │ │
373
+ CairoRenderer WebRenderer
374
+ (immediate) (scene graph)
375
+ ┌──────────┐ ┌──────────────┐
376
+ │ PNG/PDF/ │ │ JSON Scene → │
377
+ │ SVG/PS │ │ HTML + D3.js │
378
+ └──────────┘ └──────────────┘
379
+ ```
380
+
381
+ ### Renderers
382
+
383
+ | Backend | Module | Output Formats | Rendering Mode |
384
+ |---------|--------|----------------|----------------|
385
+ | **CairoRenderer** | `renderer.py` | PNG, PDF, SVG, PS | Immediate — draws directly to a pycairo surface |
386
+ | **WebRenderer** | `renderer_web.py` | Standalone HTML (SVG + Canvas + D3.js) | Deferred — builds a JSON scene graph, rendered browser-side |
387
+
388
+ ### Supporting Components
389
+
390
+ | Component | Module | Role |
391
+ |-----------|--------|------|
392
+ | GridRenderer (ABC) | `_renderer_base.py` | Abstract base class defining the renderer interface (29 abstract methods) |
393
+ | Scene Graph | `_scene_graph.py` | `SceneNode` / `ViewportNode` / `GrobNode` tree used by WebRenderer |
394
+ | Font Metrics | `_font_metrics.py` | Pluggable text measurement (Cairo, fonttools, or heuristic backends) |
395
+ | GridState | `_state.py` | Global singleton that binds the active renderer to the drawing API |
396
+
397
+ ### Backend Selection
398
+
399
+ There is no registry or factory — instantiate the renderer you need and bind it:
400
+
401
+ ```python
402
+ from grid_py import WebRenderer, get_state, grid_draw
403
+
404
+ r = WebRenderer(width=7, height=5, dpi=100)
405
+ state = get_state()
406
+ state.init_device(r)
407
+
408
+ grid_draw(my_grob) # draws into the scene graph
409
+ html = r.to_html() # export interactive HTML
410
+ ```
411
+
412
+ `grid_newpage()` creates a `CairoRenderer` by default when no renderer is bound.
413
+
414
+ ## Interactive Web Visualization
415
+
416
+ `WebRenderer` turns any grid plot into an interactive HTML document. The same
417
+ layout code that produces a static PNG via `CairoRenderer` can produce a
418
+ zoomable, pannable, tooltip-enabled web page — with zero API changes.
419
+
420
+ ### How it works
421
+
422
+ ```
423
+ Python (grid_py) Browser (gridpy.js)
424
+ ┌──────────────┐ ┌──────────────────────┐
425
+ │ grid_draw() │──→ Scene Graph JSON ──→ │ SVG layer (text, │
426
+ │ viewports, │ {root, defs, dpi} │ shapes, clip/mask) │
427
+ │ grobs, gpar │ │ Canvas layer (>2000 │
428
+ │ │ │ points batch) │
429
+ │ .metadata │──→ node.data[] ───────→ │ Quadtree spatial │
430
+ │ (per-point) │ │ index → tooltips │
431
+ └──────────────┘ └──────────────────────┘
432
+ ```
433
+
434
+ 1. Python builds a JSON scene graph during `grid_draw()` calls
435
+ 2. `gridpy.js` renders SVG for shapes/text, Canvas for large point clouds
436
+ 3. All data-carrying points register in a spatial index (quadtree)
437
+ 4. Hover triggers a proximity query — no DOM hit-testing needed
438
+
439
+ ### Tooltip data
440
+
441
+ Attach a `metadata` dict to any grob before drawing. Keys become tooltip
442
+ labels; list values are indexed per point:
443
+
444
+ ```python
445
+ grob = points_grob(x=x_data, y=y_data, pch=19,
446
+ gp=Gpar(col=colors, fill=colors))
447
+ grob.metadata = {
448
+ "species": species_list, # per-point label
449
+ "value": [f"{v:.1f}" for v in values],
450
+ }
451
+ grid_draw(grob) # metadata flows into the scene graph
452
+ ```
453
+
454
+ ### Output modes
455
+
456
+ ```python
457
+ r = WebRenderer(width=7, height=5, dpi=100)
458
+ get_state().init_device(r)
459
+ # ... draw with grid_draw() ...
460
+
461
+ # Jupyter notebook — inline display with D3 inlined (no CDN dependency)
462
+ display(r) # uses _repr_html_() → <iframe srcdoc>
463
+
464
+ # Standalone HTML — lightweight, loads D3 from CDN
465
+ r.save("plot.html") # open in any browser
466
+
467
+ # Raw scene graph — for custom frontends (Vue, React, etc.)
468
+ json_str = r.to_scene_json() # framework calls gridpy.render(el, json)
469
+ ```
470
+
471
+ ### Rendering layers
472
+
473
+ The browser runtime uses a layered architecture for performance:
474
+
475
+ | Layer | z-index | Content | When used |
476
+ |-------|---------|---------|-----------|
477
+ | Canvas | 1 | Batch-drawn points | Point count > 2000 |
478
+ | SVG | 2 | Text, shapes, small point sets | Default for most grobs |
479
+ | Overlay | 3 | D3 zoom/brush handlers | When `interactive: true` |
480
+
481
+ Routing is automatic (`render_hint="auto"`), or you can force a layer per grob
482
+ with `render_hint="svg"` or `render_hint="canvas"`.
483
+
484
+ ## Documentation
485
+
486
+ ```bash
487
+ pip install -e ".[docs]"
488
+ mkdocs serve
489
+ ```
@@ -0,0 +1,42 @@
1
+ grid_py/__init__.py,sha256=UU2vFwHFQBb4ZOGwhRwSBmjoRMs6fkMn6XP4NNCoUto,10378
2
+ grid_py/_arrow.py,sha256=pgn4OCgF6TZY2yXl7ML-kt08DbwqlvT1ulApDcmRz4k,10867
3
+ grid_py/_clippath.py,sha256=p6fUAkcEc5Bg8chv-lIZwaOjEUbLK57duwjtIpDjAkw,4015
4
+ grid_py/_colour.py,sha256=WqaxGop-SM1LYZG4uMPmMX3Zjh6Y_ip0HcanP5wEij8,22872
5
+ grid_py/_coords.py,sha256=9cDD3MWHmw9TnT1I8QKHQA96SCG06OxRXNqYGFZsfwg,47210
6
+ grid_py/_curve.py,sha256=MV7hl1MR-4FZfKBKEm4MCSvHgJLYP9UaWLp8eHXPhv0,54041
7
+ grid_py/_display_list.py,sha256=uMFAupSJaCgUCbLMv2-RDBQ-YLxCkAldypRqc7CnF3w,13622
8
+ grid_py/_draw.py,sha256=JE1WmmzrezReB9xlU8jy6Ydda186b984TkAnQtyAI1I,48233
9
+ grid_py/_edit.py,sha256=vQDZGBTTYy6DmlW33l94s1KJLrzPNym21NR4Od4qIFw,22263
10
+ grid_py/_font_metrics.py,sha256=XC_dgIN3eB72VPXIRFU-tynnS3wJl3bPugGHrwVzyeo,11086
11
+ grid_py/_gpar.py,sha256=PT8gn6laJaYuonlE32Hfuhfd6sYNofElkF-kEtfChRc,18508
12
+ grid_py/_grab.py,sha256=XAPdYG2gyl9Px29xM_rByIPA2NwuvkbFaLcHGrqpaUQ,15423
13
+ grid_py/_grob.py,sha256=kHSxkPHWqHHyMVum7ueKS-ddDqFF2E-8tUQOM-azEXU,39992
14
+ grid_py/_group.py,sha256=jmPQPcy_lrVjurF8w5ovhCXvwKLBeGVkOwAvX0X0gA0,22828
15
+ grid_py/_highlevel.py,sha256=KVcFc0aUm6WBGyNKlYJfZ16qC4bRolng8ZKb86lSLpc,61803
16
+ grid_py/_just.py,sha256=lh9ar8lw6JRqZE5qHP4Wx7GHPIW0y7Wp0EgJ7vhFjek,10590
17
+ grid_py/_layout.py,sha256=fYomioHrI--nHi8tC1X_fsv91QCRZ4E-g0F9hl6XW4c,19307
18
+ grid_py/_ls.py,sha256=RhUGZJCZkcTUjUK97fft_G4D9KxuyBr3OMFhzC5IShc,25547
19
+ grid_py/_mask.py,sha256=d2Wm2z-RJnfEKHdAHcjteL7VubimcaK1_f9Us9MfrUk,4902
20
+ grid_py/_path.py,sha256=Tr5bNNcGwPpOsxWKqEp65MRri-KV8IqplUh2Z90sxnk,11421
21
+ grid_py/_patterns.py,sha256=PBwV2b3oJkbueTLCku6cxeZ1PThREjiPcA6lmrwH3pE,32691
22
+ grid_py/_primitives.py,sha256=dpX5_q5CS8p1vhuVzTa77MVbtaxigGBA5mmUzfFfHks,58861
23
+ grid_py/_renderer_base.py,sha256=kY_mdcldRR94OBBcgEFg9cmIM3fUlbnUPdGiy-ulaSM,48701
24
+ grid_py/_scene_graph.py,sha256=mKhNEMkUolbWt4_CFgGhrGUudrYenxFNXaBp6GLN9_Y,7412
25
+ grid_py/_size.py,sha256=NuzLD567ywRYyhSPWna9CA2ScxtCWgV1BWpt_ot0Txs,41962
26
+ grid_py/_state.py,sha256=GiOMFQozol_SInRoxUZ5TXsFLOBwuNs7EWWi19WFiWM,20598
27
+ grid_py/_transforms.py,sha256=mQvs_Qm6icti66peLXTsjgmSmvIUCCphf_-D-tiE1O4,11675
28
+ grid_py/_typeset.py,sha256=J_PJ5YcOAOnnFkBfo8IW86utJdkdsrnGZi3MvnHc8io,11516
29
+ grid_py/_units.py,sha256=DFwIptXRKq9JpegD0HsOt4kEjgcb-d0jB_ffPbH9zq0,57584
30
+ grid_py/_utils.py,sha256=QaWNkCF3BbPHyrqPPRxN7Ji2vB5ethNwVT3SJ1ad9Lc,8335
31
+ grid_py/_viewport.py,sha256=AOrYmv05Y4QJbsTksn86RLStfHdbOHERc2YDHdZAekE,48477
32
+ grid_py/_vp_calc.py,sha256=v0MJc-YmWohO5t7LHFopk5ogH-Sink_A_zNFV_1769w,32935
33
+ grid_py/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
+ grid_py/renderer.py,sha256=oicSqKjTC1fz3mQ3RdcCEttwFExDHJN03OQGw08UPNc,61473
35
+ grid_py/renderer_web.py,sha256=pbOijES1eUUqkeAadXVyZPCBRIUIgzs3HIOgAElTYmo,27958
36
+ grid_py/resources/d3.v7.min.js,sha256=8glLv2FBs1lyLE_kVOtsSw8OQswQzHr5IfwVj864ZTk,279706
37
+ grid_py/resources/gridpy.css,sha256=tR5LF2rLvi_bGRWuH9CnmLQk-aG2f-jlZjQZqS7_4uY,1351
38
+ grid_py/resources/gridpy.js,sha256=l8KGgK-qZbJPVvrMAmLUu57RhpSAo_LMibs6rx3RnvA,28340
39
+ rgrid_python-4.5.3.dist-info/METADATA,sha256=_O3F6MOjlwqZzW1Rh0vMCxu4aZ6XYD-cPRBW6zM2R-c,19809
40
+ rgrid_python-4.5.3.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
41
+ rgrid_python-4.5.3.dist-info/licenses/LICENSE,sha256=8zNQKZlkc4JOaW7br_a8aALg4baZwZkLKLTQx3kuHkc,48
42
+ rgrid_python-4.5.3.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,3 @@
1
+ # Artistic-2.0
2
+
3
+ See DESCRIPTION from R package.