code-node-graph 0.1.0__py3-none-any.whl → 0.2.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.
- code_node/__init__.py +1 -1
- code_node/report/graph.py +153 -4
- code_node/report/style.py +34 -6
- {code_node_graph-0.1.0.dist-info → code_node_graph-0.2.0.dist-info}/METADATA +1 -1
- {code_node_graph-0.1.0.dist-info → code_node_graph-0.2.0.dist-info}/RECORD +8 -8
- {code_node_graph-0.1.0.dist-info → code_node_graph-0.2.0.dist-info}/WHEEL +0 -0
- {code_node_graph-0.1.0.dist-info → code_node_graph-0.2.0.dist-info}/entry_points.txt +0 -0
- {code_node_graph-0.1.0.dist-info → code_node_graph-0.2.0.dist-info}/licenses/LICENSE +0 -0
code_node/__init__.py
CHANGED
|
@@ -13,7 +13,7 @@ from .libraries import Library, register_library
|
|
|
13
13
|
from .platforms import Platform, get_platform, register_platform
|
|
14
14
|
from .project import EntryPoint, Project, entry_points, read_project
|
|
15
15
|
|
|
16
|
-
__version__ = "0.
|
|
16
|
+
__version__ = "0.2.0"
|
|
17
17
|
|
|
18
18
|
__all__ = [
|
|
19
19
|
"CodeGraph",
|
code_node/report/graph.py
CHANGED
|
@@ -13,8 +13,8 @@ from typing import Any, Callable
|
|
|
13
13
|
|
|
14
14
|
from ..kit.blocks import _Report, _draws
|
|
15
15
|
from ..kit.fmt import _plural
|
|
16
|
-
from ..kit.highlight import _python_lines
|
|
17
|
-
from ..kit.render import _prose
|
|
16
|
+
from ..kit.highlight import _python_html, _python_lines
|
|
17
|
+
from ..kit.render import _CALL_RE, _prose
|
|
18
18
|
from ..kit.text import _esc
|
|
19
19
|
|
|
20
20
|
from ..analysis.graph import CodeGraph, GraphEdge, GraphNode
|
|
@@ -1081,7 +1081,7 @@ def _node_svg(
|
|
|
1081
1081
|
)
|
|
1082
1082
|
classes = " ".join(["cn", f"k-{n.kind}", f"n-{n.id}", *(f"a-{m}" for m in neighbours)]) + (" warn" if warn else "")
|
|
1083
1083
|
return (
|
|
1084
|
-
f'<g class="{_esc(classes)}" transform="translate({x:.1f},{y:.1f})"
|
|
1084
|
+
f'<g class="{_esc(classes)}" transform="translate({x:.1f},{y:.1f})">'
|
|
1085
1085
|
f'<rect class="bg" width="{w:.0f}" height="{h:.0f}" rx="11"/>'
|
|
1086
1086
|
f'<rect class="fg" x=".5" y=".5" width="{w - 1:.0f}" height="{h - 1:.0f}" rx="10.5"/>{"".join(parts)}</g>'
|
|
1087
1087
|
)
|
|
@@ -1175,6 +1175,153 @@ def _g_panel(n: GraphNode, lines_of: Callable[[str], list[str]], editor: str = "
|
|
|
1175
1175
|
)
|
|
1176
1176
|
|
|
1177
1177
|
|
|
1178
|
+
_G_TIP_W = 420 # a box's hover card, wide
|
|
1179
|
+
|
|
1180
|
+
_G_TIP_SIGNATURE = 6 # lines of a def its hover card shows, at most
|
|
1181
|
+
|
|
1182
|
+
_G_TIP_WARNING = "A warning is about it: "
|
|
1183
|
+
|
|
1184
|
+
# a name in the card's sentences worth setting as code: a dotted or keyed path (Records[].s3.bucket.name,
|
|
1185
|
+
# book:{book_id}, s3:GetObject, orders/handler.py) or a variable in capitals (DB_HOST)
|
|
1186
|
+
_G_CODE_RE = re.compile(
|
|
1187
|
+
r"(?<![\w.\-/])([A-Za-z_][\w\-]*(?:[.:/]+[\w{}\-]+|\[\]|\{\w*\})+|[A-Z][A-Z0-9]*_[A-Z0-9_]*[A-Z0-9])(?![\w{])"
|
|
1188
|
+
)
|
|
1189
|
+
|
|
1190
|
+
|
|
1191
|
+
def _g_tip_text(text: str) -> str:
|
|
1192
|
+
"""
|
|
1193
|
+
One of the card's sentences as HTML, its calls coloured as Python and its names set as code, every piece escaped.
|
|
1194
|
+
"""
|
|
1195
|
+
out = []
|
|
1196
|
+
for i, piece in enumerate(_CALL_RE.split(text)):
|
|
1197
|
+
if i % 2:
|
|
1198
|
+
out.append(f'<code class="ctk">{_python_html(piece)}</code>')
|
|
1199
|
+
continue
|
|
1200
|
+
for k, part in enumerate(_G_CODE_RE.split(piece)):
|
|
1201
|
+
out.append(f'<code class="ctk ctn">{_esc(part)}</code>' if k % 2 else _esc(part))
|
|
1202
|
+
return "".join(out)
|
|
1203
|
+
|
|
1204
|
+
|
|
1205
|
+
def _g_tip_item(item: str) -> str:
|
|
1206
|
+
"""
|
|
1207
|
+
One thing a service box lists, for its card: 'PutItem (dynamodb:PutItem)' as the operation in code and what it
|
|
1208
|
+
needs beside it.
|
|
1209
|
+
"""
|
|
1210
|
+
m = re.fullmatch(r"(.+?) \((.+)\)", item)
|
|
1211
|
+
if not m:
|
|
1212
|
+
return f'<li><code class="ctk ctn">{_esc(item)}</code></li>'
|
|
1213
|
+
return (
|
|
1214
|
+
f'<li><code class="ctk ctn">{_esc(m.group(1))}</code> <span class="ctm">{_g_tip_text(m.group(2))}</span></li>'
|
|
1215
|
+
)
|
|
1216
|
+
|
|
1217
|
+
|
|
1218
|
+
def _g_tip_signature(n: GraphNode, lines_of: Callable[[str], list[str]]) -> list[str]:
|
|
1219
|
+
"""
|
|
1220
|
+
A function's def as it's written, in colour: its decorators and the lines up to the colon that opens its body.
|
|
1221
|
+
[] when its file wasn't read.
|
|
1222
|
+
"""
|
|
1223
|
+
if not n.code:
|
|
1224
|
+
return []
|
|
1225
|
+
span = n.code[0]
|
|
1226
|
+
lines = lines_of(span.file)
|
|
1227
|
+
if not lines or span.start > len(lines):
|
|
1228
|
+
return []
|
|
1229
|
+
start = span.start
|
|
1230
|
+
while start > 1 and lines[start - 2].lstrip().startswith("@"):
|
|
1231
|
+
start -= 1
|
|
1232
|
+
shown = []
|
|
1233
|
+
for k in range(start, min(len(lines), span.end, start + _G_TIP_SIGNATURE - 1) + 1):
|
|
1234
|
+
shown.append(lines[k - 1])
|
|
1235
|
+
if k >= span.start and re.sub(r"<[^>]*>", "", lines[k - 1]).rstrip().endswith(":"):
|
|
1236
|
+
break
|
|
1237
|
+
indent = min((len(line) - len(line.lstrip(" ")) for line in shown if line.strip()), default=0)
|
|
1238
|
+
return [line[indent:] for line in shown]
|
|
1239
|
+
|
|
1240
|
+
|
|
1241
|
+
def _g_tip(n: GraphNode, lines_of: Callable[[str], list[str]], opens: bool) -> tuple[str, float]:
|
|
1242
|
+
"""
|
|
1243
|
+
What a box says on hover, as a card: what kind of box it is and its name, a function's def in colour and its
|
|
1244
|
+
docstring, then the rest of its words with the code in them set as code, its warnings apart, and when it has a
|
|
1245
|
+
panel (opens), that a click shows its code. With how tall it is likely to be, to pick whether it goes under the
|
|
1246
|
+
box or over it.
|
|
1247
|
+
"""
|
|
1248
|
+
said = [line for line in (n.tip or n.label).split("\n") if line]
|
|
1249
|
+
warnings = [w for line in said if line.startswith(_G_TIP_WARNING) for w in line[len(_G_TIP_WARNING) :].split("; ")]
|
|
1250
|
+
said = [line for line in said if not line.startswith(_G_TIP_WARNING)]
|
|
1251
|
+
mono = n.kind in ("handler", "function")
|
|
1252
|
+
body, tall, sub = [], 80.0 + (20 if n.sub else 0), n.sub
|
|
1253
|
+
if mono and said and _CALL_RE.match(said[0]) and " in " in said[0]: # 'name(args) in file, 3 lines: its doc'
|
|
1254
|
+
head = said.pop(0)
|
|
1255
|
+
signature = _g_tip_signature(n, lines_of) or [_python_html(head.split(" in ", 1)[0])]
|
|
1256
|
+
body.append(f'<pre class="ctc">{chr(10).join(signature)}</pre>')
|
|
1257
|
+
tall += 21 * len(signature) + 34
|
|
1258
|
+
lines = re.search(r", (\d+ lines?)", head)
|
|
1259
|
+
sub = f"{n.sub} · {lines.group(1)}" if lines and n.sub else sub
|
|
1260
|
+
if n.lines and n.lines[0]:
|
|
1261
|
+
body.append(f'<p class="ctd">{_g_tip_text(n.lines[0])}</p>')
|
|
1262
|
+
tall += 23 * math.ceil(len(n.lines[0]) / 42) + 10
|
|
1263
|
+
for line in said:
|
|
1264
|
+
lead, _, rest = line.partition(": ")
|
|
1265
|
+
if rest and lead == n.label: # 'S3: GetObject (s3:GetObject), PutObject (s3:PutObject)': a list
|
|
1266
|
+
items = rest.split(", ")
|
|
1267
|
+
body.append(f'<ul class="ctl">{"".join(_g_tip_item(item) for item in items)}</ul>')
|
|
1268
|
+
tall += 30 * len(items) + 8
|
|
1269
|
+
else:
|
|
1270
|
+
body.append(f'<p class="ctp">{_g_tip_text(line)}</p>')
|
|
1271
|
+
tall += 23 * math.ceil(len(line) / 42) + 10
|
|
1272
|
+
if warnings:
|
|
1273
|
+
body.append(
|
|
1274
|
+
'<div class="ctw"><b>Warning</b><ul>'
|
|
1275
|
+
+ "".join(f"<li>{_g_tip_text(w)}</li>" for w in warnings)
|
|
1276
|
+
+ "</ul></div>"
|
|
1277
|
+
)
|
|
1278
|
+
tall += 50 + sum(23 * math.ceil(len(w) / 36) + 4 for w in warnings)
|
|
1279
|
+
kind = _G_PANEL_KINDS.get(n.kind, n.kind)
|
|
1280
|
+
name = _python_html(n.label) if mono else _esc(n.label)
|
|
1281
|
+
card = (
|
|
1282
|
+
f'<div class="ctt k-{_esc(n.kind)}{" warn" if warnings else ""}"><div class="cth">'
|
|
1283
|
+
f'<span class="ctkd">{_esc(kind)}</span><b class="ctn{" mono" if mono else ""}">{name}</b>'
|
|
1284
|
+
+ (f'<span class="cts{" mono" if mono else ""}">{_esc(sub)}</span>' if sub else "")
|
|
1285
|
+
+ f"</div>{''.join(body)}"
|
|
1286
|
+
+ ('<div class="cto">Click it to read its code</div>' if opens else "")
|
|
1287
|
+
+ "</div>"
|
|
1288
|
+
)
|
|
1289
|
+
return card, tall + (40 if opens else 0)
|
|
1290
|
+
|
|
1291
|
+
|
|
1292
|
+
def _g_tip_svg(
|
|
1293
|
+
n: GraphNode,
|
|
1294
|
+
box: tuple[float, float, float, float],
|
|
1295
|
+
width: float,
|
|
1296
|
+
tall: float,
|
|
1297
|
+
lines_of: Callable[[str], list[str]],
|
|
1298
|
+
opens: bool,
|
|
1299
|
+
) -> str:
|
|
1300
|
+
"""
|
|
1301
|
+
A box's hover card, in the graph so it zooms with it: under the box when it fits there, else over it, else beside
|
|
1302
|
+
it, and inside the graph from left to right. Hidden until the box is pointed at.
|
|
1303
|
+
"""
|
|
1304
|
+
card, high = _g_tip(n, lines_of, opens)
|
|
1305
|
+
x, y, w, h = box
|
|
1306
|
+
card_w = min(_G_TIP_W, max(width - 16, 220))
|
|
1307
|
+
left = max(8.0, min(x, width - card_w - 8))
|
|
1308
|
+
below, above = tall - (y + h + 10) - 8, y - 10 - 8
|
|
1309
|
+
if high <= below:
|
|
1310
|
+
top, room, side = y + h + 10, below, "dn"
|
|
1311
|
+
elif high <= above:
|
|
1312
|
+
top, room, side = 8.0, above, "up"
|
|
1313
|
+
else: # beside the box, as high up as keeps all of it in the graph; over the box only when there's no room beside
|
|
1314
|
+
if width - (x + w + 12) - 8 >= card_w:
|
|
1315
|
+
left = x + w + 12
|
|
1316
|
+
elif x - 12 - 8 >= card_w:
|
|
1317
|
+
left = x - 12 - card_w
|
|
1318
|
+
top, room, side = max(8.0, min(y, tall - high - 8)), high, "dn"
|
|
1319
|
+
return (
|
|
1320
|
+
f'<foreignObject class="ctip tp-{_esc(n.id)} {side}" x="{left:.0f}" y="{top:.0f}" width="{card_w:.0f}" '
|
|
1321
|
+
f'height="{room:.0f}" aria-hidden="true"><div class="ctx">{card}</div></foreignObject>'
|
|
1322
|
+
)
|
|
1323
|
+
|
|
1324
|
+
|
|
1178
1325
|
def _g_captions(graph: CodeGraph, xs: dict[int, float], widths: dict[int, float], column_of: dict[str, int]) -> str:
|
|
1179
1326
|
"""
|
|
1180
1327
|
The words over the columns: COMES IN, HANDLER, CALLS, REACHES, each over the columns it covers.
|
|
@@ -1256,6 +1403,7 @@ def _graph_html(block: _Graph, report: _Report) -> str:
|
|
|
1256
1403
|
for n in graph.nodes: # pointing at a box leaves only it, its arrows and the boxes they join in sight
|
|
1257
1404
|
report.rules.add(f".{root} .cg:has(.n-{n.id}:hover) .ce:not(.s-{n.id}):not(.t-{n.id}){{opacity:.06}}")
|
|
1258
1405
|
report.rules.add(f".{root} .cg:has(.n-{n.id}:hover) .cn:not(.n-{n.id}):not(.a-{n.id}){{opacity:.28}}")
|
|
1406
|
+
report.rules.add(f".{root} .cg:has(.n-{n.id}:hover) .tp-{n.id}{{display:inline}}")
|
|
1259
1407
|
report.rules.add(
|
|
1260
1408
|
f".{root} .cg:has(.n-{n.id}:hover) :is(.s-{n.id},.t-{n.id}) .ln{{stroke-width:2.4;stroke-opacity:1}}"
|
|
1261
1409
|
)
|
|
@@ -1307,6 +1455,7 @@ def _graph_html(block: _Graph, report: _Report) -> str:
|
|
|
1307
1455
|
for n in graph.nodes
|
|
1308
1456
|
for box in [_node_svg(cards[n.id], boxes[n.id], list(dict.fromkeys(near[n.id])), access[n.id])]
|
|
1309
1457
|
)
|
|
1458
|
+
tips = "".join(_g_tip_svg(n, boxes[n.id], width, tall, lines_of, bool(panels.get(n.id))) for n in graph.nodes)
|
|
1310
1459
|
kinds = {e.kind for e in graph.edges}
|
|
1311
1460
|
pills = [f'<span class="kp">{_g_swatch(k)}{_esc(word)}</span>' for k, word in _G_LEGEND if k in kinds]
|
|
1312
1461
|
if any(e.guessed for e in graph.edges):
|
|
@@ -1362,7 +1511,7 @@ def _graph_html(block: _Graph, report: _Report) -> str:
|
|
|
1362
1511
|
f'{title}<div class="cgw">{switches}<div class="cgb">{bar}<div class="cg">'
|
|
1363
1512
|
f'<svg viewBox="0 0 {width:.0f} {tall:.0f}" width="{width:.0f}" height="{tall:.0f}" '
|
|
1364
1513
|
f'style="--w:{width:.0f}px" role="img" aria-label="{_esc(block.title or "How the code fits together")}">'
|
|
1365
|
-
f"{_g_captions(graph, xs, widths, column_of)}{edges}{nodes}{ports}</svg></div>"
|
|
1514
|
+
f"{_g_captions(graph, xs, widths, column_of)}{edges}{nodes}{ports}{tips}</svg></div>"
|
|
1366
1515
|
f'<div class="cgk">{"".join(pills)}{hidden}{hint}</div></div>{"".join(panels.values())}</div>'
|
|
1367
1516
|
)
|
|
1368
1517
|
|
code_node/report/style.py
CHANGED
|
@@ -95,12 +95,12 @@ _EXTRA_CSS = """\
|
|
|
95
95
|
.cnd .flow .oq{font-style:italic}
|
|
96
96
|
.cnd .flow .os{display:inline-flex;flex-wrap:wrap;gap:3px 5px}
|
|
97
97
|
.cnd .flow .ob{margin-left:22px}
|
|
98
|
-
.cnd :is(.flow,.cside,.walk) .pk{color:var(--jp-mirror-editor-keyword-color,light-dark(#7c3aed,#c792ea))}
|
|
99
|
-
.cnd :is(.flow,.cside,.walk) .pf{color:var(--jp-mirror-editor-def-color,light-dark(#2563eb,#82aaff))}
|
|
100
|
-
.cnd :is(.flow,.cside,.walk) :is(.js,.jk){color:var(--jp-mirror-editor-string-color,light-dark(#047857,#a5d6a7))}
|
|
101
|
-
.cnd :is(.flow,.cside,.walk) :is(.jn,.jl){color:var(--jp-mirror-editor-number-color,light-dark(#c2410c,#f78c6c))}
|
|
102
|
-
.cnd :is(.flow,.cside,.walk) .pa{font-style:italic}
|
|
103
|
-
.cnd :is(.flow,.cside,.walk) .pc{opacity:.6;font-style:italic}
|
|
98
|
+
.cnd :is(.flow,.cside,.walk,.ctip) .pk{color:var(--jp-mirror-editor-keyword-color,light-dark(#7c3aed,#c792ea))}
|
|
99
|
+
.cnd :is(.flow,.cside,.walk,.ctip) .pf{color:var(--jp-mirror-editor-def-color,light-dark(#2563eb,#82aaff))}
|
|
100
|
+
.cnd :is(.flow,.cside,.walk,.ctip) :is(.js,.jk){color:var(--jp-mirror-editor-string-color,light-dark(#047857,#a5d6a7))}
|
|
101
|
+
.cnd :is(.flow,.cside,.walk,.ctip) :is(.jn,.jl){color:var(--jp-mirror-editor-number-color,light-dark(#c2410c,#f78c6c))}
|
|
102
|
+
.cnd :is(.flow,.cside,.walk,.ctip) .pa{font-style:italic}
|
|
103
|
+
.cnd :is(.flow,.cside,.walk,.ctip) .pc{opacity:.6;font-style:italic}
|
|
104
104
|
.cnd .cgb{width:fit-content;max-width:min(100%,1180px)}
|
|
105
105
|
.cnd .cg{border:1px solid rgba(127,127,127,.2);border-radius:14px;margin:6px 0 8px;overflow:auto;background-color:rgba(127,127,127,.035);background-attachment:local;background-size:18px 18px;
|
|
106
106
|
background-image:radial-gradient(circle at 1px 1px,rgba(127,127,127,.3) 1px,transparent 0);background-position:9px 9px}
|
|
@@ -221,6 +221,34 @@ _EXTRA_CSS = """\
|
|
|
221
221
|
.cnd .cgk .kl path{fill:none;stroke:currentColor;stroke-opacity:.8;stroke-width:2.1;stroke-linecap:round;stroke-linejoin:round}
|
|
222
222
|
.cnd .cg a.cl{cursor:pointer;outline:none}
|
|
223
223
|
.cnd .cg a.cl:focus-visible .fg{stroke:light-dark(#2563eb,#60a5fa);stroke-opacity:1;stroke-width:2}
|
|
224
|
+
.cnd .cg .ctip{display:none;overflow:visible;pointer-events:none}
|
|
225
|
+
.cnd .cg .ctip .ctx{display:flex;flex-direction:column;height:100%}
|
|
226
|
+
.cnd .cg .ctip.up .ctx{justify-content:flex-end}
|
|
227
|
+
.cnd .cg .ctt{position:relative;box-sizing:border-box;padding:16px 18px;border:1px solid rgba(127,127,127,.3);border-radius:12px;background:var(--jp-layout-color0,var(--vscode-editor-background,Canvas));color:CanvasText;box-shadow:0 2px 6px rgba(15,23,42,.08),0 14px 34px rgba(15,23,42,.18);font-size:14px;line-height:1.6;text-align:left;animation:cnTip .14s ease-out .18s both}
|
|
228
|
+
@keyframes cnTip{from{opacity:0;transform:translateY(3px)}to{opacity:1;transform:none}}
|
|
229
|
+
@media (prefers-reduced-motion:reduce){.cnd .cg .ctt{animation:none}}
|
|
230
|
+
.cnd .cg .ctt.k-function,.cnd .cg .ctt.k-handler{--c:light-dark(#2563eb,#82aaff)}
|
|
231
|
+
.cnd .cg .cth{display:flex;flex-direction:column;gap:3px;margin:0 0 14px}
|
|
232
|
+
.cnd .cg .ctkd{font-size:10.5px;font-weight:650;letter-spacing:.08em;text-transform:uppercase;color:var(--c,currentColor);opacity:.9}
|
|
233
|
+
.cnd .cg .ctt b.ctn{font-size:16px;font-weight:650;overflow-wrap:anywhere}
|
|
234
|
+
.cnd .cg .ctt b.ctn.mono{font:650 15px var(--mono)}
|
|
235
|
+
.cnd .cg .cts{font-size:12.5px;opacity:.65;overflow-wrap:anywhere}
|
|
236
|
+
.cnd .cg .cts.mono{font-family:var(--mono)}
|
|
237
|
+
.cnd .cg .ctt pre.ctc{margin:0 0 12px;padding:10px 12px;border:1px solid rgba(127,127,127,.2);border-radius:8px;background:rgba(127,127,127,.06);font:13px/1.55 var(--mono);white-space:pre-wrap;overflow-wrap:anywhere}
|
|
238
|
+
.cnd .cg .cto{margin:16px -18px -16px;padding:9px 18px;border-top:1px solid rgba(127,127,127,.16);border-radius:0 0 12px 12px;background:rgba(127,127,127,.05);font-size:12px;opacity:.7}
|
|
239
|
+
.cnd .cg .ctt p{margin:0 0 10px;overflow-wrap:anywhere}
|
|
240
|
+
.cnd .cg .ctt p:last-child{margin-bottom:0}
|
|
241
|
+
.cnd .cg .ctt p.ctd{font-style:italic;opacity:.85}
|
|
242
|
+
.cnd .cg .ctt p.ctp{opacity:.88}
|
|
243
|
+
.cnd .cg .ctt code.ctk{font:12.5px var(--mono);padding:1px 5px;border-radius:4px;background:rgba(127,127,127,.12);overflow-wrap:anywhere}
|
|
244
|
+
.cnd .cg .ctt code.ctn{color:light-dark(#0f766e,#7dd3c0)}
|
|
245
|
+
.cnd .cg .ctt ul{margin:0;padding:0;list-style:none}
|
|
246
|
+
.cnd .cg .ctt ul.ctl li{display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 10px;padding:6px 0;border-top:1px solid rgba(127,127,127,.14)}
|
|
247
|
+
.cnd .cg .ctt ul.ctl li:first-child{border-top:none}
|
|
248
|
+
.cnd .cg .ctt .ctm{font-size:12px;opacity:.7}
|
|
249
|
+
.cnd .cg .ctt .ctw{margin:12px 0 0;padding:10px 14px;border-radius:8px;background:rgba(245,158,11,.12);border-left:3px solid #f59e0b}
|
|
250
|
+
.cnd .cg .ctt .ctw b{display:block;margin:0 0 4px;font-size:10.5px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:light-dark(#b45309,#fbbf24)}
|
|
251
|
+
.cnd .cg .ctt .ctw li{margin:4px 0 0;overflow-wrap:anywhere}
|
|
224
252
|
.cnd .cside{position:fixed;top:0;right:0;bottom:0;z-index:30;box-sizing:border-box;width:min(660px,94vw);overflow:auto;padding:0 20px 28px;background:var(--jp-layout-color0,var(--vscode-editor-background,Canvas));color:CanvasText;border-left:1px solid rgba(127,127,127,.3);box-shadow:-14px 0 36px rgba(15,23,42,.14);transform:translateX(104%);visibility:hidden;transition:transform .22s ease,visibility 0s linear .22s}
|
|
225
253
|
.cnd .cside:target{transform:none;visibility:visible;transition:transform .22s ease}
|
|
226
254
|
.cnd .cside .csh{display:flex;align-items:flex-start;gap:12px;position:sticky;top:0;z-index:1;margin:0 -20px 12px;padding:16px 20px 12px;background:var(--jp-layout-color0,var(--vscode-editor-background,Canvas));border-bottom:1px solid rgba(127,127,127,.2)}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: code-node-graph
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: See how Python code works without running it: a graph of who calls whom from an entry point, and what each path reaches.
|
|
5
5
|
Project-URL: Homepage, https://github.com/utkarsh5026/code-node
|
|
6
6
|
Project-URL: Documentation, https://utkarsh5026.github.io/code-node/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
code_node/__init__.py,sha256=
|
|
1
|
+
code_node/__init__.py,sha256=sfJ6RjFtxsJMr0-zronmOKVpmXZECgEUsWBV3BKfHrA,1106
|
|
2
2
|
code_node/__main__.py,sha256=0W2bmerF1S96rjlTNJZKVzO4FvVhN6ENzAl451A08sQ,101
|
|
3
3
|
code_node/cli.py,sha256=GI0vZY1t4Pf7qtZI2coTpWZi-ulQEWNREDJPkTtmxG0,12302
|
|
4
4
|
code_node/pages.py,sha256=2UOrHUz3G_vAjPO89phJxhF4652FysVLgrLtJ-Iw6p4,3234
|
|
@@ -34,9 +34,9 @@ code_node/report/__init__.py,sha256=l3dfZFbLEo-7Fl7O_Rk2lvyAElQnyugSZPI_PzHrG_Q,
|
|
|
34
34
|
code_node/report/brands.py,sha256=n32BfFz2d02ZVUHvy8L4wPHBtiD_1FCTKzdR4NyvU88,8372
|
|
35
35
|
code_node/report/build.py,sha256=F0wdC0ibu3WSAenUsovUWuKwLC0vVxnNYKJVXtU5jRk,4644
|
|
36
36
|
code_node/report/editor.py,sha256=TRUX6BTB-oe-m5Vf3xM9PppnC99sCLL4PObXkYAGKoU,1466
|
|
37
|
-
code_node/report/graph.py,sha256=
|
|
37
|
+
code_node/report/graph.py,sha256=YbrVWbymYUL8-KOdsDSRhD2RxCMWbGVEhHD0-MSjX1I,66832
|
|
38
38
|
code_node/report/outline.py,sha256=3RRxU4FMUZKBVjFDsscKZkvDlj_W4ZeW4DwUztg4wd0,8539
|
|
39
|
-
code_node/report/style.py,sha256=
|
|
39
|
+
code_node/report/style.py,sha256=zTOZ552sasyRASnm8-P8XNzashtxHe38RkvOZTMDm24,33743
|
|
40
40
|
code_node/report/tabs.py,sha256=K2XR16owfgEL1kfux61PI9nBcRsgjQurTx1ptMM5Mac,3016
|
|
41
41
|
code_node/report/walk.py,sha256=jumSV-x1X0D614V7K0zECCSWk69OkHNR7IuDt8K4ggg,27516
|
|
42
42
|
code_node/report/logos/README.md,sha256=8Evw8eApl_56QJrwY7LAtGgJMZE0mp0-HIpRz9bu1ME,613
|
|
@@ -171,8 +171,8 @@ code_node/report/logos/small/aws-systems-manager.svg,sha256=9VzzFdTjaRZO9ulR8Ulp
|
|
|
171
171
|
code_node/report/logos/small/aws-timestream.svg,sha256=yKdKIj7pbooFqDKClEQxW9h7dYV5mnDn0RCHnLUDf8Q,639
|
|
172
172
|
code_node/report/logos/small/aws-waf.svg,sha256=l9ZzBZAl2g8bK1-m6A50ga37l5g1t-9Mj70bxWDykWE,591
|
|
173
173
|
code_node/report/logos/small/aws-xray.svg,sha256=VKg_QtKGZKDCbZvKBRDn7eReuNVbJpduBUVV8MQrZZU,591
|
|
174
|
-
code_node_graph-0.
|
|
175
|
-
code_node_graph-0.
|
|
176
|
-
code_node_graph-0.
|
|
177
|
-
code_node_graph-0.
|
|
178
|
-
code_node_graph-0.
|
|
174
|
+
code_node_graph-0.2.0.dist-info/METADATA,sha256=BkbfZl6ViABwgsSH4QAJoGIkbbTNyfAp6FuPyo9JJuA,7619
|
|
175
|
+
code_node_graph-0.2.0.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
176
|
+
code_node_graph-0.2.0.dist-info/entry_points.txt,sha256=eEArp-uk7ZzODIWr6l62rI0-mIA0-mLDaqJEyKikPJw,49
|
|
177
|
+
code_node_graph-0.2.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
178
|
+
code_node_graph-0.2.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|