asecli 0.6.2__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.
Files changed (98) hide show
  1. asecli/__init__.py +3 -0
  2. asecli/bridge/__init__.py +40 -0
  3. asecli/bridge/_editor_port_contract.py +131 -0
  4. asecli/bridge/_editor_primitives.py +205 -0
  5. asecli/bridge/_editor_spec_grammar.py +245 -0
  6. asecli/bridge/_editor_spec_io.py +26 -0
  7. asecli/bridge/_editor_spec_validation.py +218 -0
  8. asecli/bridge/_gui_handoff_store.py +78 -0
  9. asecli/bridge/_gui_project.py +35 -0
  10. asecli/bridge/_gui_resource_store.py +159 -0
  11. asecli/bridge/_gui_resource_upgrade.py +122 -0
  12. asecli/bridge/editor_create.py +173 -0
  13. asecli/bridge/editor_spec.py +250 -0
  14. asecli/bridge/graph_geometry.py +249 -0
  15. asecli/bridge/graph_geometry_parser.py +57 -0
  16. asecli/bridge/graph_inspect.py +136 -0
  17. asecli/bridge/gui_handoff.py +100 -0
  18. asecli/bridge/gui_presentation.py +70 -0
  19. asecli/bridge/gui_provider_detection.py +197 -0
  20. asecli/bridge/gui_runtime_probe.py +25 -0
  21. asecli/bridge/gui_support.py +240 -0
  22. asecli/bridge/gui_support_resource.py +58 -0
  23. asecli/bridge/mcp_client.py +231 -0
  24. asecli/bridge/recompile.py +107 -0
  25. asecli/bridge/resource_text.py +12 -0
  26. asecli/bridge/resources/asecli_material_gui.authoring.part00.cs.txt +238 -0
  27. asecli/bridge/resources/asecli_material_gui.authoring.part01.cs.txt +235 -0
  28. asecli/bridge/resources/asecli_material_gui.authoring.store.cs.txt +125 -0
  29. asecli/bridge/resources/asecli_material_gui.condition.cs.txt +99 -0
  30. asecli/bridge/resources/asecli_material_gui.hydration.cs.txt +105 -0
  31. asecli/bridge/resources/asecli_material_gui.part00.cs.txt +300 -0
  32. asecli/bridge/resources/asecli_material_gui.part01.cs.txt +290 -0
  33. asecli/bridge/resources/asecli_material_gui.reconciliation.cs.txt +174 -0
  34. asecli/bridge/resources/asecli_material_gui.transaction.cs.txt +108 -0
  35. asecli/bridge/resources/editor_create.part00.cs.txt +176 -0
  36. asecli/bridge/resources/editor_create.part01.cs.txt +145 -0
  37. asecli/bridge/resources/editor_create.part02.cs.txt +139 -0
  38. asecli/bridge/resources/editor_create.part03.cs.txt +161 -0
  39. asecli/bridge/resources/editor_create.part04.cs.txt +114 -0
  40. asecli/bridge/resources/wire_route.transaction.cs.txt +140 -0
  41. asecli/bridge/wire_route.py +127 -0
  42. asecli/checks/__init__.py +10 -0
  43. asecli/checks/checksum.py +53 -0
  44. asecli/checks/local_vars.py +135 -0
  45. asecli/checks/usage.py +141 -0
  46. asecli/checks/validate.py +129 -0
  47. asecli/cli/__init__.py +1 -0
  48. asecli/cli/commands.py +237 -0
  49. asecli/cli/commentary_command.py +158 -0
  50. asecli/cli/create_command.py +250 -0
  51. asecli/cli/custom_gui_command.py +170 -0
  52. asecli/cli/gui_provider.py +30 -0
  53. asecli/cli/gui_support_command.py +35 -0
  54. asecli/cli/io.py +214 -0
  55. asecli/cli/layout_command.py +213 -0
  56. asecli/cli/main.py +245 -0
  57. asecli/cli/recompile_metadata.py +53 -0
  58. asecli/cli/skill_command.py +121 -0
  59. asecli/cli/usage_command.py +42 -0
  60. asecli/core/__init__.py +84 -0
  61. asecli/core/comment_bounds.py +166 -0
  62. asecli/core/comment_layout.py +167 -0
  63. asecli/core/comment_metrics.py +132 -0
  64. asecli/core/comment_purpose.py +140 -0
  65. asecli/core/commentary.py +225 -0
  66. asecli/core/compiled_metadata.py +135 -0
  67. asecli/core/compiled_properties.py +190 -0
  68. asecli/core/custom_gui.py +250 -0
  69. asecli/core/custom_gui_versions.py +35 -0
  70. asecli/core/fishbone_placement.py +159 -0
  71. asecli/core/fishbone_topology.py +186 -0
  72. asecli/core/graph_ops.py +122 -0
  73. asecli/core/layout.py +174 -0
  74. asecli/core/layout_audit.py +237 -0
  75. asecli/core/layout_audit_geometry.py +247 -0
  76. asecli/core/layout_audit_repeated.py +44 -0
  77. asecli/core/layout_graph.py +113 -0
  78. asecli/core/local_vars.py +54 -0
  79. asecli/core/material_gui_condition.py +68 -0
  80. asecli/core/material_gui_protocol.py +35 -0
  81. asecli/core/material_gui_spec.py +191 -0
  82. asecli/core/meticulous_layout.py +114 -0
  83. asecli/core/model.py +237 -0
  84. asecli/core/property_presentation.py +233 -0
  85. asecli/core/wire_geometry.py +83 -0
  86. asecli/core/wire_router.py +248 -0
  87. asecli/schema/__init__.py +49 -0
  88. asecli/schema/data/observed.json +16 -0
  89. asecli/schema/data/schemas.json +14106 -0
  90. asecli/skills/asecli/SKILL.md +275 -0
  91. asecli/skills/asecli/references/layout-standard.md +99 -0
  92. asecli/skills/asecli/references/master-output-settings-standard.md +51 -0
  93. asecli/skills/asecli/references/material-property-standard.md +108 -0
  94. asecli-0.6.2.dist-info/METADATA +594 -0
  95. asecli-0.6.2.dist-info/RECORD +98 -0
  96. asecli-0.6.2.dist-info/WHEEL +4 -0
  97. asecli-0.6.2.dist-info/entry_points.txt +2 -0
  98. asecli-0.6.2.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,248 @@
1
+ """Explicit, topology-preserving routing plans for ASE WireNode anchors."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from dataclasses import dataclass
6
+ from math import hypot
7
+ from typing import Mapping, Protocol
8
+
9
+ from .model import AseGraph, WireLine
10
+ from .wire_geometry import path_hits_rect, paths_cross
11
+
12
+ WIRE_NODE_TYPE = "AmplifyShaderEditor.WireNode"
13
+ ROUTE_CLEARANCE = 48.0
14
+
15
+
16
+ class Geometry(Protocol):
17
+ width: float
18
+ height: float
19
+ input_ports: dict[str, tuple[float, float]]
20
+ output_ports: dict[str, tuple[float, float]]
21
+
22
+
23
+ @dataclass(frozen=True)
24
+ class LogicalWire:
25
+ wire: WireLine
26
+ wire_nodes: tuple[str, ...]
27
+
28
+
29
+ def logical_wires(graph: AseGraph) -> list[LogicalWire]:
30
+ """Collapse each WireNode chain into its original logical connection."""
31
+ types = {node.node_id: node.type_name for node in graph.nodes}
32
+ wire_ids = {node_id for node_id, type_name in types.items() if type_name == WIRE_NODE_TYPE}
33
+ outgoing: dict[str, list[WireLine]] = {}
34
+ for wire in graph.wires:
35
+ outgoing.setdefault(wire.out_node, []).append(wire)
36
+
37
+ result: list[LogicalWire] = []
38
+
39
+ def follow(first: WireLine, current: WireLine, anchors: tuple[str, ...], visiting: set[str]) -> None:
40
+ if current.in_node not in wire_ids:
41
+ result.append(LogicalWire(
42
+ WireLine(first.out_node, first.out_port, current.in_node, current.in_port),
43
+ anchors,
44
+ ))
45
+ return
46
+ anchor = current.in_node
47
+ if anchor in visiting:
48
+ raise ValueError(f"WireNode routing cycle at node {anchor}")
49
+ next_wires = outgoing.get(anchor, [])
50
+ if len(next_wires) != 1:
51
+ raise ValueError(f"WireNode {anchor} must have exactly one outgoing connection")
52
+ follow(first, next_wires[0], anchors + (anchor,), visiting | {anchor})
53
+
54
+ for wire in graph.wires:
55
+ if wire.out_node not in wire_ids:
56
+ follow(wire, wire, (), set())
57
+ return sorted(result, key=lambda item: _wire_key(item.wire))
58
+
59
+
60
+ def plan_wire_routes(
61
+ graph: AseGraph,
62
+ geometry: Mapping[str, Geometry],
63
+ positions: dict[str, tuple[float, float]],
64
+ ) -> tuple[dict, ...]:
65
+ """Move existing anchors first, then propose at most two for a direct wire."""
66
+ routes = logical_wires(graph)
67
+ rects = {
68
+ node_id: (x, y, x + geometry[node_id].width, y + geometry[node_id].height)
69
+ for node_id, (x, y) in positions.items()
70
+ if node_id in geometry and graph.node_by_id(node_id).type_name != WIRE_NODE_TYPE
71
+ }
72
+ route_points = {
73
+ _wire_key(route.wire): [_wire_node_anchor(node_id, geometry, positions) for node_id in route.wire_nodes]
74
+ for route in routes
75
+ }
76
+ changes: list[dict] = []
77
+ for route in routes:
78
+ key = _wire_key(route.wire)
79
+ baseline = route_points[key]
80
+ baseline_score = _route_score(route, baseline, routes, route_points, geometry, positions, rects)
81
+ if baseline_score[:2] == (0, 0):
82
+ continue
83
+ anchor_count = len(route.wire_nodes) or 2
84
+ candidates = _candidate_points(route.wire, anchor_count, geometry, positions, rects)
85
+ best_points, best_score = baseline, baseline_score
86
+ for candidate in candidates:
87
+ score = _route_score(route, candidate, routes, route_points, geometry, positions, rects)
88
+ if score < best_score:
89
+ best_points, best_score = candidate, score
90
+ # Routing may not trade a new collision/crossing for a shorter path.
91
+ if (
92
+ best_points == baseline
93
+ or best_score[0] > baseline_score[0]
94
+ or best_score[1] > baseline_score[1]
95
+ or best_score[:2] == baseline_score[:2]
96
+ ):
97
+ continue
98
+ route_points[key] = best_points
99
+ logical = {
100
+ "from_node": route.wire.out_node, "from_port": route.wire.out_port,
101
+ "to_node": route.wire.in_node, "to_port": route.wire.in_port,
102
+ }
103
+ if route.wire_nodes:
104
+ moved = []
105
+ for node_id, point in zip(route.wire_nodes, best_points):
106
+ old = positions[node_id]
107
+ new = _wire_node_position(node_id, point, geometry, positions)
108
+ if new != old:
109
+ positions[node_id] = new
110
+ moved.append({"wire_node_id": node_id, "from": list(old), "to": list(new)})
111
+ if moved:
112
+ changes.append({"action": "move", "logical_wire": logical, "anchors": moved})
113
+ else:
114
+ changes.append({
115
+ "action": "add", "logical_wire": logical,
116
+ "anchors": [[round(x, 1), round(y, 1)] for x, y in best_points],
117
+ })
118
+ return tuple(changes)
119
+
120
+
121
+ def routed_wire_paths(
122
+ graph: AseGraph,
123
+ geometry: Mapping[str, Geometry],
124
+ positions: Mapping[str, tuple[float, float]],
125
+ route_changes: tuple[dict, ...] = (),
126
+ ) -> list[tuple[WireLine, list[tuple[float, float]]]]:
127
+ additions = {
128
+ _dict_wire_key(change["logical_wire"]): [tuple(point) for point in change["anchors"]]
129
+ for change in route_changes if change["action"] == "add"
130
+ }
131
+ result = []
132
+ for route in logical_wires(graph):
133
+ wire = route.wire
134
+ points = additions.get(
135
+ _wire_key(wire),
136
+ [_wire_node_anchor(node_id, geometry, positions) for node_id in route.wire_nodes],
137
+ )
138
+ result.append((wire, _sample_route(wire, points, geometry, positions)))
139
+ return result
140
+
141
+
142
+ def logical_wire_manifest(graph: AseGraph) -> list[tuple[str, str, str, str]]:
143
+ return sorted(
144
+ (item.wire.out_node, item.wire.out_port, item.wire.in_node, item.wire.in_port)
145
+ for item in logical_wires(graph)
146
+ )
147
+
148
+
149
+ def _route_score(route, points, routes, route_points, geometry, positions, rects):
150
+ path = _sample_route(route.wire, points, geometry, positions)
151
+ hits = sum(
152
+ path_hits_rect(path, rect)
153
+ for node_id, rect in rects.items()
154
+ if node_id not in {route.wire.out_node, route.wire.in_node}
155
+ )
156
+ crossings = 0
157
+ endpoints = {route.wire.out_node, route.wire.in_node}
158
+ for other in routes:
159
+ if other is route or endpoints & {other.wire.out_node, other.wire.in_node}:
160
+ continue
161
+ other_path = _sample_route(
162
+ other.wire, route_points[_wire_key(other.wire)], geometry, positions,
163
+ )
164
+ crossings += paths_cross(path, other_path)
165
+ length = sum(hypot(b[0] - a[0], b[1] - a[1]) for a, b in zip(path, path[1:]))
166
+ return hits, crossings, round(length, 3)
167
+
168
+
169
+ def _candidate_points(wire, count, geometry, positions, rects):
170
+ source = _port_anchor(wire.out_node, wire.out_port, True, geometry, positions)
171
+ target = _port_anchor(wire.in_node, wire.in_port, False, geometry, positions)
172
+ between = [
173
+ rect for node_id, rect in rects.items()
174
+ if node_id not in {wire.out_node, wire.in_node}
175
+ and not (rect[2] < min(source[0], target[0]) or rect[0] > max(source[0], target[0]))
176
+ ]
177
+ tops = [min(source[1], target[1]) - ROUTE_CLEARANCE]
178
+ bottoms = [max(source[1], target[1]) + ROUTE_CLEARANCE]
179
+ if between:
180
+ tops.append(min(rect[1] for rect in between) - ROUTE_CLEARANCE)
181
+ bottoms.append(max(rect[3] for rect in between) + ROUTE_CLEARANCE)
182
+ channels = sorted(set(tops + bottoms + [(source[1] + target[1]) * 0.5]))
183
+ values = []
184
+ for channel_y in channels:
185
+ if count == 1:
186
+ values.append([(round((source[0] + target[0]) * 0.5, 1), round(channel_y, 1))])
187
+ else:
188
+ left_x = source[0] + (target[0] - source[0]) / 3.0
189
+ right_x = source[0] + 2.0 * (target[0] - source[0]) / 3.0
190
+ points = []
191
+ for index in range(count):
192
+ fraction = index / max(1, count - 1)
193
+ points.append((round(left_x + (right_x - left_x) * fraction, 1), round(channel_y, 1)))
194
+ values.append(points)
195
+ return values
196
+
197
+
198
+ def _sample_route(wire, anchors, geometry, positions, samples=12):
199
+ points = [
200
+ _port_anchor(wire.out_node, wire.out_port, True, geometry, positions),
201
+ *anchors,
202
+ _port_anchor(wire.in_node, wire.in_port, False, geometry, positions),
203
+ ]
204
+ result = []
205
+ for index, (start, end) in enumerate(zip(points, points[1:])):
206
+ span = max(24.0, abs(end[0] - start[0]) * 0.5)
207
+ control_a, control_b = (start[0] + span, start[1]), (end[0] - span, end[1])
208
+ segment = [_bezier(start, control_a, control_b, end, step / samples) for step in range(samples + 1)]
209
+ result.extend(segment if index == 0 else segment[1:])
210
+ return result
211
+
212
+
213
+ def _port_anchor(node_id, port_id, output, geometry, positions):
214
+ offsets = geometry[node_id].output_ports if output else geometry[node_id].input_ports
215
+ x, y = positions[node_id]
216
+ dx, dy = offsets[port_id]
217
+ return x + dx, y + dy
218
+
219
+
220
+ def _wire_node_anchor(node_id, geometry, positions):
221
+ x, y = positions[node_id]
222
+ measured = geometry.get(node_id)
223
+ if measured is None:
224
+ return x, y
225
+ return x + measured.width * 0.5, y + measured.height * 0.5
226
+
227
+
228
+ def _wire_node_position(node_id, point, geometry, positions):
229
+ measured = geometry.get(node_id)
230
+ if measured is None:
231
+ return round(point[0], 1), round(point[1], 1)
232
+ return round(point[0] - measured.width * 0.5, 1), round(point[1] - measured.height * 0.5, 1)
233
+
234
+
235
+ def _bezier(p0, p1, p2, p3, t):
236
+ one = 1.0 - t
237
+ return (
238
+ one ** 3 * p0[0] + 3 * one * one * t * p1[0] + 3 * one * t * t * p2[0] + t ** 3 * p3[0],
239
+ one ** 3 * p0[1] + 3 * one * one * t * p1[1] + 3 * one * t * t * p2[1] + t ** 3 * p3[1],
240
+ )
241
+
242
+
243
+ def _wire_key(wire):
244
+ return f"{wire.out_node}:{wire.out_port}->{wire.in_node}:{wire.in_port}"
245
+
246
+
247
+ def _dict_wire_key(value):
248
+ return f"{value['from_node']}:{value['from_port']}->{value['to_node']}:{value['to_port']}"
@@ -0,0 +1,49 @@
1
+ """Node schema library (TASK-0005)."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ from functools import lru_cache
7
+ from pathlib import Path
8
+
9
+ DATA = Path(__file__).parent / "data" / "schemas.json"
10
+
11
+
12
+ @lru_cache(maxsize=1)
13
+ def load() -> dict:
14
+ return json.loads(DATA.read_text(encoding="utf-8"))
15
+
16
+
17
+ def schema_for(node_type: str) -> dict | None:
18
+ """Return the schema for a node type, or None when unknown (caller passthrough)."""
19
+ return load()["types"].get(node_type)
20
+
21
+
22
+ def is_known(node_type: str) -> bool:
23
+ s = schema_for(node_type)
24
+ return s is not None and s.get("source") in ("runtime", "observed")
25
+
26
+
27
+ def allows_mutation(node_type: str) -> bool:
28
+ """Runtime types: full structured mutation. Observed types: full-line replace only."""
29
+ s = schema_for(node_type)
30
+ return (
31
+ s is not None
32
+ and s.get("source") == "runtime"
33
+ and s.get("layout_ok") is True
34
+ )
35
+
36
+
37
+ def schema_version(node_type: str) -> str | None:
38
+ """Return the normalized ASE version for a runtime schema."""
39
+ schema = schema_for(node_type)
40
+ value = schema.get("ase_version") if schema else None
41
+ if not isinstance(value, str) or not value:
42
+ return None
43
+ return value.removeprefix("Version=")
44
+
45
+
46
+ def is_version_compatible(node_type: str, graph_version: str) -> bool:
47
+ """Only exact runtime schema versions are proven safe for structured writes."""
48
+ version = schema_version(node_type)
49
+ return version is not None and version == graph_version.removeprefix("Version=")
@@ -0,0 +1,16 @@
1
+ {
2
+ "AmplifyShaderEditor.TemplateMultiPassMasterNode": {
3
+ "samples": [
4
+ "Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;0;0,0;Float;False;False;-1;2;UnityEditor.ShaderGraphLitGUI;0;1;New Amplify Shader;94348b07e5e8bab40bd6c8a1e3df54cd;True;ExtraPrePass;0;0;ExtraPrePass;5;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;True;0;False;;False;False;False;False;False;False;False;False;False;True;False;0;False;;255;False;;255;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;False;True;1;False;;True;3;False;;True;True;0;False;;0;False;;True;4;RenderPipeline=UniversalPipeline;RenderType=Opaque=RenderType;Queue=Geometry=Queue=0;UniversalMaterialType=Lit;True;5;True;12;all;0;False;True;1;1;False;;0;False;;0;1;False;;0;False;;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;True;True;True;True;True;0;False;;False;False;False;False;False;False;False;True;False;0;False;;255;False;;255;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;False;True;1;False;;True;3;False;;True;True;0;False;;0;False;;True;0;False;False;0;;0;0;Standard;0;False;0",
5
+ "Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;1;0,0;Float;False;True;-1;2;UnityEditor.ShaderGraphLitGUI;0;1;HLIT;94348b07e5e8bab40bd6c8a1e3df54cd;True;Forward;0;1;Forward;20;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;True;0;False;;False;False;False;False;False;False;False;False;False;True;False;0;False;;255;False;;255;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;False;True;1;False;;True;3;False;;True;True;0;False;;0;False;;True;4;RenderPipeline=UniversalPipeline;RenderType=Opaque=RenderType;Queue=Geometry=Queue=0;UniversalMaterialType=Lit;True;5;True;12;all;0;False;True;1;1;False;;0;False;;0;1;False;;0;False;;False;False;False;False;False;False;False;False;False;False;False;False;False;False;True;True;True;True;True;0;False;;False;False;False;False;False;False;False;True;False;0;False;;255;False;;255;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;False;True;1;False;;True;3;False;;True;True;0;False;;0;False;;True;1;LightMode=UniversalForward;False;False;0;;0;0;Standard;41;Workflow;1;0;Surface;0;0; Refraction Model;0;0; Blend;0;0;Two Sided;1;0;Fragment Normal Space,InvertActionOnDeselection;0;0;Forward Only;0;0;Transmission;0;0; Transmission Shadow;0.5,False,;0;Translucency;0;0; Translucency Strength;1,False,;0; Normal Distortion;0.5,False,;0; Scattering;2,False,;0; Direct;0.9,False,;0; Ambient;0.1,False,;0; Shadow;0.5,False,;0;Cast Shadows;1;0; Use Shadow Threshold;0;0;Receive Shadows;1;0;GPU Instancing;1;0;LOD CrossFade;1;0;Built-in Fog;1;0;_FinalColorxAlpha;0;0;Meta Pass;1;0;Override Baked GI;0;0;Extra Pre Pass;0;0;DOTS Instancing;0;0;Tessellation;0;0; Phong;0;0; Strength;0.5,False,;0; Type;0;0; Tess;16,False,;0; Min;10,False,;0; Max;25,False,;0; Edge Length;16,False,;0; Max Displacement;25,False,;0;Write Depth;0;0; Early Z;0;0;Vertex Position,InvertActionOnDeselection;1;0;Debug Display;0;0;Clear Coat;0;0;0;10;True;True;True;True;True;True;True;True;True;True;False;;False;0",
6
+ "Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;2;0,0;Float;False;False;-1;2;UnityEditor.ShaderGraphLitGUI;0;1;New Amplify Shader;94348b07e5e8bab40bd6c8a1e3df54cd;True;ShadowCaster;0;2;ShadowCaster;0;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;True;0;False;;False;False;False;False;False;False;False;False;False;True;False;0;False;;255;False;;255;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;False;True;1;False;;True;3;False;;True;True;0;False;;0;False;;True;4;RenderPipeline=UniversalPipeline;RenderType=Opaque=RenderType;Queue=Geometry=Queue=0;UniversalMaterialType=Lit;True;5;True;12;all;0;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;False;False;True;False;False;False;False;0;False;;False;False;False;False;False;False;False;False;False;True;1;False;;True;3;False;;False;True;1;LightMode=ShadowCaster;False;False;0;;0;0;Standard;0;False;0",
7
+ "Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;3;0,0;Float;False;False;-1;2;UnityEditor.ShaderGraphLitGUI;0;1;New Amplify Shader;94348b07e5e8bab40bd6c8a1e3df54cd;True;DepthOnly;0;3;DepthOnly;0;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;True;0;False;;False;False;False;False;False;False;False;False;False;True;False;0;False;;255;False;;255;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;False;True;1;False;;True;3;False;;True;True;0;False;;0;False;;True;4;RenderPipeline=UniversalPipeline;RenderType=Opaque=RenderType;Queue=Geometry=Queue=0;UniversalMaterialType=Lit;True;5;True;12;all;0;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;False;False;True;True;False;False;False;0;False;;False;False;False;False;False;False;False;False;False;True;1;False;;False;False;True;1;LightMode=DepthOnly;False;False;0;;0;0;Standard;0;False;0",
8
+ "Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;4;0,0;Float;False;False;-1;2;UnityEditor.ShaderGraphLitGUI;0;1;New Amplify Shader;94348b07e5e8bab40bd6c8a1e3df54cd;True;Meta;0;4;Meta;0;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;True;0;False;;False;False;False;False;False;False;False;False;False;True;False;0;False;;255;False;;255;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;False;True;1;False;;True;3;False;;True;True;0;False;;0;False;;True;4;RenderPipeline=UniversalPipeline;RenderType=Opaque=RenderType;Queue=Geometry=Queue=0;UniversalMaterialType=Lit;True;5;True;12;all;0;False;False;False;False;False;False;False;False;False;False;False;False;False;False;True;2;False;;False;False;False;False;False;False;False;False;False;False;False;False;False;False;True;1;LightMode=Meta;False;False;0;;0;0;Standard;0;False;0",
9
+ "Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;5;0,0;Float;False;False;-1;2;UnityEditor.ShaderGraphLitGUI;0;1;New Amplify Shader;94348b07e5e8bab40bd6c8a1e3df54cd;True;Universal2D;0;5;Universal2D;0;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;True;0;False;;False;False;False;False;False;False;False;False;False;True;False;0;False;;255;False;;255;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;False;True;1;False;;True;3;False;;True;True;0;False;;0;False;;True;4;RenderPipeline=UniversalPipeline;RenderType=Opaque=RenderType;Queue=Geometry=Queue=0;UniversalMaterialType=Lit;True;5;True;12;all;0;False;True;1;1;False;;0;False;;0;1;False;;0;False;;False;False;False;False;False;False;False;False;False;False;False;False;False;False;True;True;True;True;True;0;False;;False;False;False;False;False;False;False;False;False;True;1;False;;True;3;False;;True;True;0;False;;0;False;;True;1;LightMode=Universal2D;False;False;0;;0;0;Standard;0;False;0",
10
+ "Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;6;0,0;Float;False;False;-1;2;UnityEditor.ShaderGraphLitGUI;0;1;New Amplify Shader;94348b07e5e8bab40bd6c8a1e3df54cd;True;DepthNormals;0;6;DepthNormals;0;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;True;0;False;;False;False;False;False;False;False;False;False;False;True;False;0;False;;255;False;;255;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;False;True;1;False;;True;3;False;;True;True;0;False;;0;False;;True;4;RenderPipeline=UniversalPipeline;RenderType=Opaque=RenderType;Queue=Geometry=Queue=0;UniversalMaterialType=Lit;True;5;True;12;all;0;False;True;1;1;False;;0;False;;0;1;False;;0;False;;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;True;1;False;;True;3;False;;False;True;1;LightMode=DepthNormals;False;False;0;;0;0;Standard;0;False;0",
11
+ "Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;7;0,0;Float;False;False;-1;2;UnityEditor.ShaderGraphLitGUI;0;1;New Amplify Shader;94348b07e5e8bab40bd6c8a1e3df54cd;True;GBuffer;0;7;GBuffer;0;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;True;0;False;;False;False;False;False;False;False;False;False;False;True;False;0;False;;255;False;;255;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;False;True;1;False;;True;3;False;;True;True;0;False;;0;False;;True;4;RenderPipeline=UniversalPipeline;RenderType=Opaque=RenderType;Queue=Geometry=Queue=0;UniversalMaterialType=Lit;True;5;True;12;all;0;False;True;1;1;False;;0;False;;0;1;False;;0;False;;False;False;False;False;False;False;False;False;False;False;False;False;False;False;True;True;True;True;True;0;False;;False;False;False;False;False;False;False;True;False;0;False;;255;False;;255;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;False;True;1;False;;True;3;False;;True;True;0;False;;0;False;;True;1;LightMode=UniversalGBuffer;False;False;0;;0;0;Standard;0;False;0",
12
+ "Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;8;0,0;Float;False;False;-1;2;UnityEditor.ShaderGraphLitGUI;0;1;New Amplify Shader;94348b07e5e8bab40bd6c8a1e3df54cd;True;SceneSelectionPass;0;8;SceneSelectionPass;0;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;True;0;False;;False;False;False;False;False;False;False;False;False;True;False;0;False;;255;False;;255;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;False;True;1;False;;True;3;False;;True;True;0;False;;0;False;;True;4;RenderPipeline=UniversalPipeline;RenderType=Opaque=RenderType;Queue=Geometry=Queue=0;UniversalMaterialType=Lit;True;5;True;12;all;0;False;False;False;False;False;False;False;False;False;False;False;False;False;False;True;2;False;;False;False;False;False;False;False;False;False;False;False;False;False;False;False;True;1;LightMode=SceneSelectionPass;False;False;0;;0;0;Standard;0;False;0",
13
+ "Node;AmplifyShaderEditor.TemplateMultiPassMasterNode;9;0,0;Float;False;False;-1;2;UnityEditor.ShaderGraphLitGUI;0;1;New Amplify Shader;94348b07e5e8bab40bd6c8a1e3df54cd;True;ScenePickingPass;0;9;ScenePickingPass;0;False;False;False;False;False;False;False;False;False;False;False;False;True;0;False;;False;True;0;False;;False;False;False;False;False;False;False;False;False;True;False;0;False;;255;False;;255;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;0;False;;False;True;1;False;;True;3;False;;True;True;0;False;;0;False;;True;4;RenderPipeline=UniversalPipeline;RenderType=Opaque=RenderType;Queue=Geometry=Queue=0;UniversalMaterialType=Lit;True;5;True;12;all;0;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;True;1;LightMode=Picking;False;False;0;;0;0;Standard;0;False;0"
14
+ ]
15
+ }
16
+ }