breadkit 0.1.0

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 (49) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +16 -0
  4. data/SECURITY.md +5 -0
  5. data/data/boards/full.yml +18 -0
  6. data/data/boards/half.yml +17 -0
  7. data/data/boards/mini.yml +8 -0
  8. data/data/parts/2n3906.yml +10 -0
  9. data/data/parts/arduino_uno.yml +34 -0
  10. data/data/parts/bc547.yml +10 -0
  11. data/data/parts/bc557.yml +10 -0
  12. data/data/parts/capacitor.yml +7 -0
  13. data/data/parts/diode.yml +8 -0
  14. data/data/parts/electrolytic.yml +8 -0
  15. data/data/parts/led.yml +9 -0
  16. data/data/parts/ne555.yml +16 -0
  17. data/data/parts/pot.yml +12 -0
  18. data/data/parts/resistor.yml +7 -0
  19. data/data/parts/tact_switch_6mm.yml +19 -0
  20. data/data/parts/transistor.yml +10 -0
  21. data/docs/assets/01_led_button.svg +12 -0
  22. data/docs/dsl.md +62 -0
  23. data/exe/breadkit +5 -0
  24. data/lib/breadkit/analysis.rb +382 -0
  25. data/lib/breadkit/board.rb +163 -0
  26. data/lib/breadkit/cli.rb +61 -0
  27. data/lib/breadkit/dsl.rb +182 -0
  28. data/lib/breadkit/hole_id.rb +46 -0
  29. data/lib/breadkit/ir.rb +215 -0
  30. data/lib/breadkit/model.rb +31 -0
  31. data/lib/breadkit/part_library.rb +125 -0
  32. data/lib/breadkit/resolver.rb +449 -0
  33. data/lib/breadkit/value.rb +50 -0
  34. data/lib/breadkit/version.rb +5 -0
  35. data/lib/breadkit.rb +26 -0
  36. data/package-lock.json +1172 -0
  37. data/package.json +12 -0
  38. data/schema/ir-v1.json +128 -0
  39. data/schema/part-v1.json +48 -0
  40. data/sig/breadkit.rbs +180 -0
  41. data/site/assets/01_led_button.svg +14 -0
  42. data/site/assets/03_arduino_blink.svg +14 -0
  43. data/site/favicon.svg +7 -0
  44. data/site/guide/components/index.html +113 -0
  45. data/site/guide/dsl/index.html +132 -0
  46. data/site/guide/index.html +163 -0
  47. data/site/index.html +95 -0
  48. data/site/styles.css +14 -0
  49. metadata +94 -0
data/package.json ADDED
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "breadkit-site",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "scripts": {
6
+ "build": "mkdir -p _site && cp -R site/. _site/ && tailwindcss -i site/styles.css -o _site/assets/site.css --minify"
7
+ },
8
+ "devDependencies": {
9
+ "@tailwindcss/cli": "4.3.3",
10
+ "tailwindcss": "4.3.3"
11
+ }
12
+ }
data/schema/ir-v1.json ADDED
@@ -0,0 +1,128 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "Breadkit IR v1",
4
+ "type": "object",
5
+ "required": ["schema_version", "title", "board", "components", "wires", "supplies", "labels", "expectations"],
6
+ "properties": {
7
+ "schema_version": { "const": 1 },
8
+ "title": { "type": ["string", "null"] },
9
+ "part_definitions": {
10
+ "type": "array",
11
+ "items": {
12
+ "type": "object",
13
+ "required": ["id", "pins"],
14
+ "properties": { "id": { "type": "string" }, "pins": { "type": "array", "items": { "type": "object" } } },
15
+ "additionalProperties": true
16
+ }
17
+ },
18
+ "board_definition": { "type": "object" },
19
+ "lint_disables": { "type": "array", "items": { "type": "object" } },
20
+ "board": {
21
+ "type": "object",
22
+ "required": ["type", "options"],
23
+ "properties": {
24
+ "type": { "type": "string" },
25
+ "options": { "type": "object", "properties": { "split_rails": { "type": "boolean" } } }
26
+ }
27
+ },
28
+ "components": { "type": "array", "items": { "$ref": "#/$defs/component" } },
29
+ "wires": { "type": "array", "items": { "$ref": "#/$defs/wire" } },
30
+ "supplies": { "type": "array", "items": { "$ref": "#/$defs/supply" } },
31
+ "labels": { "type": "array", "items": { "$ref": "#/$defs/label" } },
32
+ "expectations": { "type": "array", "items": { "$ref": "#/$defs/expectation" } },
33
+ "analysis": {
34
+ "type": "object",
35
+ "required": ["nets"],
36
+ "properties": { "nets": { "type": "array", "items": { "$ref": "#/$defs/net" } } }
37
+ }
38
+ },
39
+ "additionalProperties": true,
40
+ "$defs": {
41
+ "source": {
42
+ "type": "object",
43
+ "required": ["path", "line"],
44
+ "properties": { "path": { "type": "string" }, "line": { "type": "integer", "minimum": 1 } }
45
+ },
46
+ "nullableSource": { "anyOf": [{ "type": "null" }, { "$ref": "#/$defs/source" }] },
47
+ "location": {
48
+ "type": "object",
49
+ "required": ["path", "line"],
50
+ "properties": { "path": { "type": "string" }, "line": { "type": "integer", "minimum": 1 } }
51
+ },
52
+ "component": {
53
+ "type": "object",
54
+ "required": ["ref", "part", "value", "attrs", "pins", "unused", "source"],
55
+ "properties": {
56
+ "ref": { "type": "string" },
57
+ "part": { "type": "string" },
58
+ "value": { "type": ["string", "number", "null"] },
59
+ "attrs": { "type": "object" },
60
+ "pins": { "type": "object", "additionalProperties": { "type": ["string", "null"] } },
61
+ "unused": { "type": "array", "items": { "type": "string" } },
62
+ "source": { "$ref": "#/$defs/nullableSource" }
63
+ }
64
+ },
65
+ "wire": {
66
+ "type": "object",
67
+ "required": ["id", "from", "to", "color", "route", "source"],
68
+ "properties": {
69
+ "id": { "type": "string" },
70
+ "from": { "type": "string" },
71
+ "to": { "type": "string" },
72
+ "color": { "type": ["string", "null"] },
73
+ "route": { "type": "string" },
74
+ "source": { "$ref": "#/$defs/nullableSource" }
75
+ }
76
+ },
77
+ "supply": {
78
+ "type": "object",
79
+ "required": ["name", "voltage", "plus", "minus", "source"],
80
+ "properties": {
81
+ "name": { "type": "string" },
82
+ "voltage": { "type": "number" },
83
+ "plus": { "type": "string" },
84
+ "minus": { "type": "string" },
85
+ "source": { "$ref": "#/$defs/nullableSource" }
86
+ }
87
+ },
88
+ "label": {
89
+ "type": "object",
90
+ "required": ["net", "at", "source"],
91
+ "properties": {
92
+ "net": { "type": "string" },
93
+ "at": { "type": "string" },
94
+ "source": { "$ref": "#/$defs/nullableSource" }
95
+ }
96
+ },
97
+ "expectation": {
98
+ "type": "object",
99
+ "required": ["strict", "entries", "location"],
100
+ "properties": {
101
+ "strict": { "type": "boolean" },
102
+ "entries": {
103
+ "type": "array",
104
+ "items": {
105
+ "type": "object",
106
+ "required": ["kind", "refs", "location"],
107
+ "properties": {
108
+ "kind": { "enum": ["connected", "isolated", "net"] },
109
+ "refs": { "type": "array", "items": { "type": "string" } },
110
+ "location": { "$ref": "#/$defs/location" }
111
+ }
112
+ }
113
+ },
114
+ "location": { "$ref": "#/$defs/location" }
115
+ }
116
+ },
117
+ "net": {
118
+ "type": "object",
119
+ "required": ["name", "members", "holes", "potential"],
120
+ "properties": {
121
+ "name": { "type": "string" },
122
+ "members": { "type": "array", "items": { "type": "string" } },
123
+ "holes": { "type": "array", "items": { "type": "string" } },
124
+ "potential": { "type": ["number", "null"] }
125
+ }
126
+ }
127
+ }
128
+ }
@@ -0,0 +1,48 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "title": "Breadkit part definition v1",
4
+ "type": "object",
5
+ "required": ["id", "pins"],
6
+ "properties": {
7
+ "id": { "type": "string", "minLength": 1 },
8
+ "aliases": { "type": "array", "items": { "type": "string", "minLength": 1 } },
9
+ "category": { "type": "string" },
10
+ "placement": { "enum": ["leads", "dip", "footprint", "offboard"] },
11
+ "pins": {
12
+ "type": "array",
13
+ "items": {
14
+ "type": "object",
15
+ "required": ["num"],
16
+ "properties": {
17
+ "num": { "type": ["integer", "string"] },
18
+ "name": { "type": "string" },
19
+ "aliases": { "type": "array", "items": { "type": "string" } },
20
+ "type": { "type": "string" },
21
+ "role": { "type": "string" }
22
+ },
23
+ "additionalProperties": true
24
+ }
25
+ },
26
+ "polarity": { "type": "object", "additionalProperties": { "type": ["string", "integer"] } },
27
+ "footprint": {
28
+ "type": "object",
29
+ "additionalProperties": {
30
+ "type": "array", "prefixItems": [{ "type": "integer" }, { "type": "integer" }],
31
+ "minItems": 2, "maxItems": 2
32
+ }
33
+ },
34
+ "internal": { "$ref": "#/$defs/pairs" },
35
+ "switch": { "$ref": "#/$defs/pairs" },
36
+ "same_strip_ok": { "$ref": "#/$defs/pairs" }
37
+ },
38
+ "additionalProperties": true,
39
+ "$defs": {
40
+ "pairs": {
41
+ "type": "array",
42
+ "items": {
43
+ "type": "array", "prefixItems": [{ "type": ["string", "integer"] }, { "type": ["string", "integer"] }],
44
+ "minItems": 2, "maxItems": 2
45
+ }
46
+ }
47
+ }
48
+ }
data/sig/breadkit.rbs ADDED
@@ -0,0 +1,180 @@
1
+ module Breadkit
2
+ VERSION: String
3
+
4
+ class Error < StandardError
5
+ end
6
+
7
+ class DSLError < Error
8
+ end
9
+
10
+ def self.load: (String path) -> Circuit
11
+
12
+ class SourceLocation
13
+ attr_reader path: String
14
+ attr_reader line: Integer?
15
+ end
16
+
17
+ class Diagnostic
18
+ attr_reader code: String
19
+ attr_reader severity: String
20
+ attr_reader message: String
21
+ attr_reader location: SourceLocation?
22
+ attr_reader targets: Array[String]
23
+ end
24
+
25
+ class Pin
26
+ attr_reader name: String
27
+ attr_reader hole_id: String?
28
+ attr_reader node_id: String?
29
+ end
30
+
31
+ class Component
32
+ attr_reader ref: String
33
+ attr_reader part: PartDef
34
+ attr_reader pins: Hash[String, Pin]
35
+ def pin: (String | Symbol | Integer reference) -> Pin?
36
+ end
37
+
38
+ class Wire
39
+ attr_reader id: String
40
+ attr_reader from: String
41
+ attr_reader to: String
42
+ attr_reader electrical: bool
43
+ end
44
+
45
+ class Supply
46
+ attr_reader name: String
47
+ attr_reader voltage: Float
48
+ attr_reader plus: String
49
+ attr_reader minus: String
50
+ attr_reader location: SourceLocation?
51
+ end
52
+
53
+ class Label
54
+ attr_reader name: String
55
+ attr_reader at: String
56
+ attr_reader location: SourceLocation?
57
+ end
58
+
59
+ class Net
60
+ attr_reader name: String
61
+ attr_reader members: Array[String]
62
+ attr_reader holes: Array[String]
63
+ attr_reader potential: Float?
64
+ end
65
+
66
+ class State
67
+ attr_reader name: String?
68
+ attr_reader closed_switches: Array[untyped]
69
+ end
70
+
71
+ class PotentialResult
72
+ attr_reader values: Hash[String, Float]
73
+ attr_reader conflicts: Array[untyped]
74
+ end
75
+
76
+ class Circuit
77
+ attr_reader title: String?
78
+ attr_reader board: Board
79
+ attr_reader components: Hash[String, Component]
80
+ attr_reader wires: Array[Wire]
81
+ attr_reader supplies: Array[Supply]
82
+ attr_reader labels: Array[Label]
83
+ attr_reader expectations: Array[Hash[Symbol, untyped]]
84
+ attr_reader lint_disables: Array[Hash[Symbol, untyped]]
85
+ attr_reader diagnostics: Array[Diagnostic]
86
+ def states: (?String mode) -> Array[State]
87
+ def nets: (?State? state) -> Array[Net]
88
+ def potentials: (?State? state) -> PotentialResult
89
+ def net_of: (String reference, ?State? state) -> Net?
90
+ def shortest_path: (String a, String b, ?State? state) -> Array[untyped]
91
+ def to_ir: () -> Hash[String, untyped]
92
+ end
93
+
94
+ class BoardDef
95
+ attr_reader data: Hash[String, untyped]
96
+ def initialize: (Hash[String, untyped] data) -> void
97
+ def id: () -> String
98
+ def self.load: (String | Symbol id, ?extra_paths: Array[String], ?extra_definitions: Array[Hash[String, untyped]]) -> BoardDef
99
+ end
100
+
101
+ class Board
102
+ attr_reader definition: BoardDef
103
+ attr_reader holes: Hash[String, untyped]
104
+ attr_reader strips: Hash[String, Array[String]]
105
+ def initialize: (BoardDef definition, ?split_rails: bool) -> void
106
+ def hole: (String id) -> untyped
107
+ def strip: (String id) -> Array[String]?
108
+ def width: () -> Integer
109
+ def height: () -> Integer
110
+ def row_count: () -> Integer
111
+ def terminal_rows: () -> Array[String]
112
+ def ravine_between: () -> Array[String]
113
+ def rail_ids: () -> Array[String]
114
+ def rail_polarity: (String id) -> String?
115
+ end
116
+
117
+ class HoleId
118
+ attr_reader kind: Symbol
119
+ attr_reader row: String?
120
+ attr_reader col: Integer?
121
+ attr_reader rail: String?
122
+ def self.parse: (String value, ?board: Board?) -> HoleId
123
+ def to_s: () -> String
124
+ end
125
+
126
+ class PartDef
127
+ attr_reader data: Hash[String, untyped]
128
+ def initialize: (Hash[String, untyped] data) -> void
129
+ def id: () -> String
130
+ def pins: () -> Array[Hash[String, untyped]]
131
+ def placement: () -> String
132
+ def pin: (String | Symbol | Integer value) -> Hash[String, untyped]?
133
+ end
134
+
135
+ class PartLibrary
136
+ def initialize: (?extra_paths: Array[String], ?extra_definitions: Array[Hash[String, untyped]]) -> void
137
+ def find: (String | Symbol name, ?pin_count: Integer?) -> PartDef?
138
+ def all: () -> Array[PartDef]
139
+ end
140
+
141
+ class Value
142
+ attr_reader value: Float
143
+ attr_reader unit: String
144
+ def initialize: (String | Numeric value) -> void
145
+ def self.parse: (String | Numeric input) -> Float
146
+ def to_s: () -> String
147
+ end
148
+
149
+ class Resolver
150
+ def call: (Document document) -> Circuit
151
+ end
152
+
153
+ class CLI
154
+ def run: (Array[String] argv) -> Integer
155
+ end
156
+
157
+ class Document
158
+ attr_accessor title: String?
159
+ attr_accessor board: Hash[Symbol, untyped]
160
+ attr_accessor board_paths: Array[String]
161
+ attr_accessor board_definitions: Array[Hash[String, untyped]]
162
+ attr_accessor part_paths: Array[String]
163
+ attr_accessor part_definitions: Array[Hash[String, untyped]]
164
+ end
165
+
166
+ module DSL
167
+ def self.load_file: (String path) -> Document
168
+ end
169
+
170
+ module IR
171
+ class Writer
172
+ def write: (Circuit circuit) -> Hash[String, untyped]
173
+ end
174
+
175
+ class Reader
176
+ def read_file: (String path) -> Circuit
177
+ def read: (Hash[String, untyped] data) -> Circuit
178
+ end
179
+ end
180
+ end
@@ -0,0 +1,14 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg xmlns="http://www.w3.org/2000/svg" width="205.00" height="330.00" viewBox="0 0 205.00 330.00" font-family="Helvetica, Arial, 'Noto Sans JP', sans-serif" fill="#e8efeb" role="img">
3
+ <title>Button-controlled LED</title>
4
+ <desc>Breadboard wiring diagram generated by Breadkit.</desc>
5
+ <g transform="matrix(0 1 -1 0 175.00 15.00)">
6
+ <g id="board"><rect x="-15.00" y="-45.00" width="320.00" height="200.00" rx="8" fill="#202a27" stroke="#52625b" stroke-width="1"/><rect x="-10.00" y="45.00" width="310.00" height="20.00" rx="2" fill="#141c19"/><rect x="7.00" y="-23.00" width="286.00" height="6.00" rx="3" fill="#ed7168" opacity="0.14" data-rail="T+"/><rect x="7.00" y="-33.00" width="286.00" height="6.00" rx="3" fill="#99aaa4" opacity="0.14" data-rail="T-"/><rect x="7.00" y="137.00" width="286.00" height="6.00" rx="3" fill="#ed7168" opacity="0.14" data-rail="B+"/><rect x="7.00" y="127.00" width="286.00" height="6.00" rx="3" fill="#99aaa4" opacity="0.14" data-rail="B-"/></g>
7
+ <g id="holes"><circle cx="0.00" cy="110.00" r="1.30" fill="#718178" data-hole="a1" opacity="0.75"/><circle cx="0.00" cy="100.00" r="1.30" fill="#718178" data-hole="b1" opacity="0.75"/><circle cx="0.00" cy="90.00" r="1.30" fill="#718178" data-hole="c1" opacity="0.75"/><circle cx="0.00" cy="80.00" r="1.30" fill="#718178" data-hole="d1" opacity="0.75"/><circle cx="0.00" cy="70.00" r="1.30" fill="#718178" data-hole="e1" opacity="0.75"/><circle cx="0.00" cy="40.00" r="1.30" fill="#718178" data-hole="f1" opacity="0.75"/><circle cx="0.00" cy="30.00" r="1.30" fill="#718178" data-hole="g1" opacity="0.75"/><circle cx="0.00" cy="20.00" r="1.30" fill="#718178" data-hole="h1" opacity="0.75"/><circle cx="0.00" cy="10.00" r="1.30" fill="#718178" data-hole="i1" opacity="0.75"/><circle cx="0.00" cy="0.00" r="1.30" fill="#718178" data-hole="j1" opacity="0.75"/><circle cx="10.00" cy="110.00" r="1.30" fill="#718178" data-hole="a2" opacity="0.75"/><circle cx="10.00" cy="100.00" r="1.30" fill="#718178" data-hole="b2" opacity="0.75"/><circle cx="10.00" cy="90.00" r="1.30" fill="#718178" data-hole="c2" opacity="0.75"/><circle cx="10.00" cy="80.00" r="1.30" fill="#718178" data-hole="d2" opacity="0.75"/><circle cx="10.00" cy="70.00" r="1.30" fill="#718178" data-hole="e2" opacity="0.75"/><circle cx="10.00" cy="40.00" r="1.30" fill="#718178" data-hole="f2" opacity="0.75"/><circle cx="10.00" cy="30.00" r="1.30" fill="#718178" data-hole="g2" opacity="0.75"/><circle cx="10.00" cy="20.00" r="1.30" fill="#718178" data-hole="h2" opacity="0.75"/><circle cx="10.00" cy="10.00" r="1.30" fill="#718178" data-hole="i2" opacity="0.75"/><circle cx="10.00" cy="0.00" r="1.30" fill="#718178" data-hole="j2" opacity="0.75"/><circle cx="20.00" cy="110.00" r="1.30" fill="#718178" data-hole="a3" opacity="0.75"/><circle cx="20.00" cy="100.00" r="1.30" fill="#718178" data-hole="b3" opacity="0.75"/><circle cx="20.00" cy="90.00" r="1.30" fill="#718178" data-hole="c3" opacity="0.75"/><circle cx="20.00" cy="80.00" r="1.30" fill="#718178" data-hole="d3" opacity="0.75"/><circle cx="20.00" cy="70.00" r="1.30" fill="#718178" data-hole="e3" opacity="0.75"/><circle cx="20.00" cy="40.00" r="1.30" fill="#718178" data-hole="f3" opacity="0.75"/><circle cx="20.00" cy="30.00" r="1.30" fill="#718178" data-hole="g3" opacity="0.75"/><circle cx="20.00" cy="20.00" r="1.30" fill="#718178" data-hole="h3" opacity="0.75"/><circle cx="20.00" cy="10.00" r="1.30" fill="#718178" data-hole="i3" opacity="0.75"/><circle cx="20.00" cy="0.00" r="1.30" fill="#718178" data-hole="j3" opacity="0.75"/><circle cx="30.00" cy="110.00" r="1.30" fill="#718178" data-hole="a4" opacity="0.75"/><circle cx="30.00" cy="100.00" r="1.30" fill="#718178" data-hole="b4" opacity="0.75"/><circle cx="30.00" cy="90.00" r="1.30" fill="#718178" data-hole="c4" opacity="0.75"/><circle cx="30.00" cy="80.00" r="1.30" fill="#718178" data-hole="d4" opacity="0.75"/><circle cx="30.00" cy="70.00" r="1.30" fill="#718178" data-hole="e4" opacity="0.75"/><circle cx="30.00" cy="40.00" r="1.30" fill="#718178" data-hole="f4" opacity="0.75"/><circle cx="30.00" cy="30.00" r="1.30" fill="#718178" data-hole="g4" opacity="0.75"/><circle cx="30.00" cy="20.00" r="1.30" fill="#718178" data-hole="h4" opacity="0.75"/><circle cx="30.00" cy="10.00" r="1.30" fill="#718178" data-hole="i4" opacity="0.75"/><circle cx="30.00" cy="0.00" r="1.30" fill="#718178" data-hole="j4" opacity="0.75"/><circle cx="40.00" cy="110.00" r="1.30" fill="#718178" data-hole="a5" opacity="0.75"/><circle cx="40.00" cy="100.00" r="1.30" fill="#718178" data-hole="b5" opacity="0.75"/><circle cx="40.00" cy="90.00" r="1.30" fill="#718178" data-hole="c5" opacity="0.75"/><circle cx="40.00" cy="80.00" r="1.30" fill="#718178" data-hole="d5" opacity="0.75"/><circle cx="40.00" cy="70.00" r="1.30" fill="#718178" data-hole="e5" opacity="0.75"/><circle cx="40.00" cy="40.00" r="1.30" fill="#718178" data-hole="f5" opacity="0.75"/><circle cx="40.00" cy="30.00" r="1.30" fill="#718178" data-hole="g5" opacity="0.75"/><circle cx="40.00" cy="20.00" r="1.30" fill="#718178" data-hole="h5" opacity="0.75"/><circle cx="40.00" cy="10.00" r="1.30" fill="#718178" data-hole="i5" opacity="0.75"/><circle cx="40.00" cy="0.00" r="1.30" fill="#718178" data-hole="j5" opacity="0.75"/><circle cx="50.00" cy="110.00" r="1.30" fill="#718178" data-hole="a6" opacity="0.75"/><circle cx="50.00" cy="100.00" r="1.30" fill="#718178" data-hole="b6" opacity="0.75"/><circle cx="50.00" cy="90.00" r="1.30" fill="#718178" data-hole="c6" opacity="0.75"/><circle cx="50.00" cy="80.00" r="1.30" fill="#718178" data-hole="d6" opacity="0.75"/><circle cx="50.00" cy="70.00" r="1.30" fill="#718178" data-hole="e6" opacity="0.75"/><circle cx="50.00" cy="40.00" r="1.30" fill="#718178" data-hole="f6" opacity="0.75"/><circle cx="50.00" cy="30.00" r="1.30" fill="#718178" data-hole="g6" opacity="0.75"/><circle cx="50.00" cy="20.00" r="1.30" fill="#718178" data-hole="h6" opacity="0.75"/><circle cx="50.00" cy="10.00" r="1.30" fill="#718178" data-hole="i6" opacity="0.75"/><circle cx="50.00" cy="0.00" r="1.30" fill="#718178" data-hole="j6" opacity="0.75"/><circle cx="60.00" cy="110.00" r="1.30" fill="#718178" data-hole="a7" opacity="0.75"/><circle cx="60.00" cy="100.00" r="1.30" fill="#718178" data-hole="b7" opacity="0.75"/><circle cx="60.00" cy="90.00" r="1.30" fill="#718178" data-hole="c7" opacity="0.75"/><circle cx="60.00" cy="80.00" r="1.30" fill="#718178" data-hole="d7" opacity="0.75"/><circle cx="60.00" cy="70.00" r="1.30" fill="#718178" data-hole="e7" opacity="0.75"/><circle cx="60.00" cy="40.00" r="1.30" fill="#718178" data-hole="f7" opacity="0.75"/><circle cx="60.00" cy="30.00" r="1.30" fill="#718178" data-hole="g7" opacity="0.75"/><circle cx="60.00" cy="20.00" r="1.30" fill="#718178" data-hole="h7" opacity="0.75"/><circle cx="60.00" cy="10.00" r="1.30" fill="#718178" data-hole="i7" opacity="0.75"/><circle cx="60.00" cy="0.00" r="1.30" fill="#718178" data-hole="j7" opacity="0.75"/><circle cx="70.00" cy="110.00" r="1.30" fill="#718178" data-hole="a8" opacity="0.75"/><circle cx="70.00" cy="100.00" r="1.30" fill="#718178" data-hole="b8" opacity="0.75"/><circle cx="70.00" cy="90.00" r="1.30" fill="#718178" data-hole="c8" opacity="0.75"/><circle cx="70.00" cy="80.00" r="1.30" fill="#718178" data-hole="d8" opacity="0.75"/><circle cx="70.00" cy="70.00" r="1.30" fill="#718178" data-hole="e8" opacity="0.75"/><circle cx="70.00" cy="40.00" r="1.30" fill="#718178" data-hole="f8" opacity="0.75"/><circle cx="70.00" cy="30.00" r="1.30" fill="#718178" data-hole="g8" opacity="0.75"/><circle cx="70.00" cy="20.00" r="1.30" fill="#718178" data-hole="h8" opacity="0.75"/><circle cx="70.00" cy="10.00" r="1.30" fill="#718178" data-hole="i8" opacity="0.75"/><circle cx="70.00" cy="0.00" r="1.30" fill="#718178" data-hole="j8" opacity="0.75"/><circle cx="80.00" cy="110.00" r="1.30" fill="#718178" data-hole="a9" opacity="0.75"/><circle cx="80.00" cy="100.00" r="1.30" fill="#718178" data-hole="b9" opacity="0.75"/><circle cx="80.00" cy="90.00" r="1.30" fill="#718178" data-hole="c9" opacity="0.75"/><circle cx="80.00" cy="80.00" r="1.30" fill="#718178" data-hole="d9" opacity="0.75"/><circle cx="80.00" cy="70.00" r="1.30" fill="#718178" data-hole="e9" opacity="0.75"/><circle cx="80.00" cy="40.00" r="1.30" fill="#718178" data-hole="f9" opacity="0.75"/><circle cx="80.00" cy="30.00" r="1.30" fill="#718178" data-hole="g9" opacity="0.75"/><circle cx="80.00" cy="20.00" r="1.30" fill="#718178" data-hole="h9" opacity="0.75"/><circle cx="80.00" cy="10.00" r="1.30" fill="#718178" data-hole="i9" opacity="0.75"/><circle cx="80.00" cy="0.00" r="1.30" fill="#718178" data-hole="j9" opacity="0.75"/><circle cx="90.00" cy="110.00" r="1.80" fill="#d4e2d9" data-hole="a10" opacity="1"/><circle cx="90.00" cy="100.00" r="1.80" fill="#d4e2d9" data-hole="b10" opacity="1"/><circle cx="90.00" cy="90.00" r="1.80" fill="#d4e2d9" data-hole="c10" opacity="1"/><circle cx="90.00" cy="80.00" r="1.80" fill="#d4e2d9" data-hole="d10" opacity="1"/><circle cx="90.00" cy="70.00" r="1.80" fill="#d4e2d9" data-hole="e10" opacity="1"/><circle cx="90.00" cy="40.00" r="1.80" fill="#d4e2d9" data-hole="f10" opacity="1"/><circle cx="90.00" cy="30.00" r="1.80" fill="#d4e2d9" data-hole="g10" opacity="1"/><circle cx="90.00" cy="20.00" r="1.80" fill="#d4e2d9" data-hole="h10" opacity="1"/><circle cx="90.00" cy="10.00" r="1.80" fill="#d4e2d9" data-hole="i10" opacity="1"/><circle cx="90.00" cy="0.00" r="1.80" fill="#d4e2d9" data-hole="j10" opacity="1"/><circle cx="100.00" cy="110.00" r="1.30" fill="#718178" data-hole="a11" opacity="0.75"/><circle cx="100.00" cy="100.00" r="1.30" fill="#718178" data-hole="b11" opacity="0.75"/><circle cx="100.00" cy="90.00" r="1.30" fill="#718178" data-hole="c11" opacity="0.75"/><circle cx="100.00" cy="80.00" r="1.30" fill="#718178" data-hole="d11" opacity="0.75"/><circle cx="100.00" cy="70.00" r="1.30" fill="#718178" data-hole="e11" opacity="0.75"/><circle cx="100.00" cy="40.00" r="1.30" fill="#718178" data-hole="f11" opacity="0.75"/><circle cx="100.00" cy="30.00" r="1.30" fill="#718178" data-hole="g11" opacity="0.75"/><circle cx="100.00" cy="20.00" r="1.30" fill="#718178" data-hole="h11" opacity="0.75"/><circle cx="100.00" cy="10.00" r="1.30" fill="#718178" data-hole="i11" opacity="0.75"/><circle cx="100.00" cy="0.00" r="1.30" fill="#718178" data-hole="j11" opacity="0.75"/><circle cx="110.00" cy="110.00" r="1.80" fill="#d4e2d9" data-hole="a12" opacity="1"/><circle cx="110.00" cy="100.00" r="1.80" fill="#d4e2d9" data-hole="b12" opacity="1"/><circle cx="110.00" cy="90.00" r="1.80" fill="#d4e2d9" data-hole="c12" opacity="1"/><circle cx="110.00" cy="80.00" r="1.80" fill="#d4e2d9" data-hole="d12" opacity="1"/><circle cx="110.00" cy="70.00" r="1.80" fill="#d4e2d9" data-hole="e12" opacity="1"/><circle cx="110.00" cy="40.00" r="1.80" fill="#d4e2d9" data-hole="f12" opacity="1"/><circle cx="110.00" cy="30.00" r="1.80" fill="#d4e2d9" data-hole="g12" opacity="1"/><circle cx="110.00" cy="20.00" r="1.80" fill="#d4e2d9" data-hole="h12" opacity="1"/><circle cx="110.00" cy="10.00" r="1.80" fill="#d4e2d9" data-hole="i12" opacity="1"/><circle cx="110.00" cy="0.00" r="1.80" fill="#d4e2d9" data-hole="j12" opacity="1"/><circle cx="120.00" cy="110.00" r="1.30" fill="#718178" data-hole="a13" opacity="0.75"/><circle cx="120.00" cy="100.00" r="1.30" fill="#718178" data-hole="b13" opacity="0.75"/><circle cx="120.00" cy="90.00" r="1.30" fill="#718178" data-hole="c13" opacity="0.75"/><circle cx="120.00" cy="80.00" r="1.30" fill="#718178" data-hole="d13" opacity="0.75"/><circle cx="120.00" cy="70.00" r="1.30" fill="#718178" data-hole="e13" opacity="0.75"/><circle cx="120.00" cy="40.00" r="1.30" fill="#718178" data-hole="f13" opacity="0.75"/><circle cx="120.00" cy="30.00" r="1.30" fill="#718178" data-hole="g13" opacity="0.75"/><circle cx="120.00" cy="20.00" r="1.30" fill="#718178" data-hole="h13" opacity="0.75"/><circle cx="120.00" cy="10.00" r="1.30" fill="#718178" data-hole="i13" opacity="0.75"/><circle cx="120.00" cy="0.00" r="1.30" fill="#718178" data-hole="j13" opacity="0.75"/><circle cx="130.00" cy="110.00" r="1.30" fill="#718178" data-hole="a14" opacity="0.75"/><circle cx="130.00" cy="100.00" r="1.30" fill="#718178" data-hole="b14" opacity="0.75"/><circle cx="130.00" cy="90.00" r="1.30" fill="#718178" data-hole="c14" opacity="0.75"/><circle cx="130.00" cy="80.00" r="1.30" fill="#718178" data-hole="d14" opacity="0.75"/><circle cx="130.00" cy="70.00" r="1.30" fill="#718178" data-hole="e14" opacity="0.75"/><circle cx="130.00" cy="40.00" r="1.30" fill="#718178" data-hole="f14" opacity="0.75"/><circle cx="130.00" cy="30.00" r="1.30" fill="#718178" data-hole="g14" opacity="0.75"/><circle cx="130.00" cy="20.00" r="1.30" fill="#718178" data-hole="h14" opacity="0.75"/><circle cx="130.00" cy="10.00" r="1.30" fill="#718178" data-hole="i14" opacity="0.75"/><circle cx="130.00" cy="0.00" r="1.30" fill="#718178" data-hole="j14" opacity="0.75"/><circle cx="140.00" cy="110.00" r="1.30" fill="#718178" data-hole="a15" opacity="0.75"/><circle cx="140.00" cy="100.00" r="1.30" fill="#718178" data-hole="b15" opacity="0.75"/><circle cx="140.00" cy="90.00" r="1.30" fill="#718178" data-hole="c15" opacity="0.75"/><circle cx="140.00" cy="80.00" r="1.30" fill="#718178" data-hole="d15" opacity="0.75"/><circle cx="140.00" cy="70.00" r="1.30" fill="#718178" data-hole="e15" opacity="0.75"/><circle cx="140.00" cy="40.00" r="1.30" fill="#718178" data-hole="f15" opacity="0.75"/><circle cx="140.00" cy="30.00" r="1.30" fill="#718178" data-hole="g15" opacity="0.75"/><circle cx="140.00" cy="20.00" r="1.30" fill="#718178" data-hole="h15" opacity="0.75"/><circle cx="140.00" cy="10.00" r="1.30" fill="#718178" data-hole="i15" opacity="0.75"/><circle cx="140.00" cy="0.00" r="1.30" fill="#718178" data-hole="j15" opacity="0.75"/><circle cx="150.00" cy="110.00" r="1.80" fill="#d4e2d9" data-hole="a16" opacity="1"/><circle cx="150.00" cy="100.00" r="1.80" fill="#d4e2d9" data-hole="b16" opacity="1"/><circle cx="150.00" cy="90.00" r="1.80" fill="#d4e2d9" data-hole="c16" opacity="1"/><circle cx="150.00" cy="80.00" r="1.80" fill="#d4e2d9" data-hole="d16" opacity="1"/><circle cx="150.00" cy="70.00" r="1.80" fill="#d4e2d9" data-hole="e16" opacity="1"/><circle cx="150.00" cy="40.00" r="1.30" fill="#718178" data-hole="f16" opacity="0.75"/><circle cx="150.00" cy="30.00" r="1.30" fill="#718178" data-hole="g16" opacity="0.75"/><circle cx="150.00" cy="20.00" r="1.30" fill="#718178" data-hole="h16" opacity="0.75"/><circle cx="150.00" cy="10.00" r="1.30" fill="#718178" data-hole="i16" opacity="0.75"/><circle cx="150.00" cy="0.00" r="1.30" fill="#718178" data-hole="j16" opacity="0.75"/><circle cx="160.00" cy="110.00" r="1.80" fill="#d4e2d9" data-hole="a17" opacity="1"/><circle cx="160.00" cy="100.00" r="1.80" fill="#d4e2d9" data-hole="b17" opacity="1"/><circle cx="160.00" cy="90.00" r="1.80" fill="#d4e2d9" data-hole="c17" opacity="1"/><circle cx="160.00" cy="80.00" r="1.80" fill="#d4e2d9" data-hole="d17" opacity="1"/><circle cx="160.00" cy="70.00" r="1.80" fill="#d4e2d9" data-hole="e17" opacity="1"/><circle cx="160.00" cy="40.00" r="1.30" fill="#718178" data-hole="f17" opacity="0.75"/><circle cx="160.00" cy="30.00" r="1.30" fill="#718178" data-hole="g17" opacity="0.75"/><circle cx="160.00" cy="20.00" r="1.30" fill="#718178" data-hole="h17" opacity="0.75"/><circle cx="160.00" cy="10.00" r="1.30" fill="#718178" data-hole="i17" opacity="0.75"/><circle cx="160.00" cy="0.00" r="1.30" fill="#718178" data-hole="j17" opacity="0.75"/><circle cx="170.00" cy="110.00" r="1.30" fill="#718178" data-hole="a18" opacity="0.75"/><circle cx="170.00" cy="100.00" r="1.30" fill="#718178" data-hole="b18" opacity="0.75"/><circle cx="170.00" cy="90.00" r="1.30" fill="#718178" data-hole="c18" opacity="0.75"/><circle cx="170.00" cy="80.00" r="1.30" fill="#718178" data-hole="d18" opacity="0.75"/><circle cx="170.00" cy="70.00" r="1.30" fill="#718178" data-hole="e18" opacity="0.75"/><circle cx="170.00" cy="40.00" r="1.30" fill="#718178" data-hole="f18" opacity="0.75"/><circle cx="170.00" cy="30.00" r="1.30" fill="#718178" data-hole="g18" opacity="0.75"/><circle cx="170.00" cy="20.00" r="1.30" fill="#718178" data-hole="h18" opacity="0.75"/><circle cx="170.00" cy="10.00" r="1.30" fill="#718178" data-hole="i18" opacity="0.75"/><circle cx="170.00" cy="0.00" r="1.30" fill="#718178" data-hole="j18" opacity="0.75"/><circle cx="180.00" cy="110.00" r="1.30" fill="#718178" data-hole="a19" opacity="0.75"/><circle cx="180.00" cy="100.00" r="1.30" fill="#718178" data-hole="b19" opacity="0.75"/><circle cx="180.00" cy="90.00" r="1.30" fill="#718178" data-hole="c19" opacity="0.75"/><circle cx="180.00" cy="80.00" r="1.30" fill="#718178" data-hole="d19" opacity="0.75"/><circle cx="180.00" cy="70.00" r="1.30" fill="#718178" data-hole="e19" opacity="0.75"/><circle cx="180.00" cy="40.00" r="1.30" fill="#718178" data-hole="f19" opacity="0.75"/><circle cx="180.00" cy="30.00" r="1.30" fill="#718178" data-hole="g19" opacity="0.75"/><circle cx="180.00" cy="20.00" r="1.30" fill="#718178" data-hole="h19" opacity="0.75"/><circle cx="180.00" cy="10.00" r="1.30" fill="#718178" data-hole="i19" opacity="0.75"/><circle cx="180.00" cy="0.00" r="1.30" fill="#718178" data-hole="j19" opacity="0.75"/><circle cx="190.00" cy="110.00" r="1.30" fill="#718178" data-hole="a20" opacity="0.75"/><circle cx="190.00" cy="100.00" r="1.30" fill="#718178" data-hole="b20" opacity="0.75"/><circle cx="190.00" cy="90.00" r="1.30" fill="#718178" data-hole="c20" opacity="0.75"/><circle cx="190.00" cy="80.00" r="1.30" fill="#718178" data-hole="d20" opacity="0.75"/><circle cx="190.00" cy="70.00" r="1.30" fill="#718178" data-hole="e20" opacity="0.75"/><circle cx="190.00" cy="40.00" r="1.30" fill="#718178" data-hole="f20" opacity="0.75"/><circle cx="190.00" cy="30.00" r="1.30" fill="#718178" data-hole="g20" opacity="0.75"/><circle cx="190.00" cy="20.00" r="1.30" fill="#718178" data-hole="h20" opacity="0.75"/><circle cx="190.00" cy="10.00" r="1.30" fill="#718178" data-hole="i20" opacity="0.75"/><circle cx="190.00" cy="0.00" r="1.30" fill="#718178" data-hole="j20" opacity="0.75"/><circle cx="200.00" cy="110.00" r="1.30" fill="#718178" data-hole="a21" opacity="0.75"/><circle cx="200.00" cy="100.00" r="1.30" fill="#718178" data-hole="b21" opacity="0.75"/><circle cx="200.00" cy="90.00" r="1.30" fill="#718178" data-hole="c21" opacity="0.75"/><circle cx="200.00" cy="80.00" r="1.30" fill="#718178" data-hole="d21" opacity="0.75"/><circle cx="200.00" cy="70.00" r="1.30" fill="#718178" data-hole="e21" opacity="0.75"/><circle cx="200.00" cy="40.00" r="1.30" fill="#718178" data-hole="f21" opacity="0.75"/><circle cx="200.00" cy="30.00" r="1.30" fill="#718178" data-hole="g21" opacity="0.75"/><circle cx="200.00" cy="20.00" r="1.30" fill="#718178" data-hole="h21" opacity="0.75"/><circle cx="200.00" cy="10.00" r="1.30" fill="#718178" data-hole="i21" opacity="0.75"/><circle cx="200.00" cy="0.00" r="1.30" fill="#718178" data-hole="j21" opacity="0.75"/><circle cx="210.00" cy="110.00" r="1.30" fill="#718178" data-hole="a22" opacity="0.75"/><circle cx="210.00" cy="100.00" r="1.30" fill="#718178" data-hole="b22" opacity="0.75"/><circle cx="210.00" cy="90.00" r="1.30" fill="#718178" data-hole="c22" opacity="0.75"/><circle cx="210.00" cy="80.00" r="1.30" fill="#718178" data-hole="d22" opacity="0.75"/><circle cx="210.00" cy="70.00" r="1.30" fill="#718178" data-hole="e22" opacity="0.75"/><circle cx="210.00" cy="40.00" r="1.30" fill="#718178" data-hole="f22" opacity="0.75"/><circle cx="210.00" cy="30.00" r="1.30" fill="#718178" data-hole="g22" opacity="0.75"/><circle cx="210.00" cy="20.00" r="1.30" fill="#718178" data-hole="h22" opacity="0.75"/><circle cx="210.00" cy="10.00" r="1.30" fill="#718178" data-hole="i22" opacity="0.75"/><circle cx="210.00" cy="0.00" r="1.30" fill="#718178" data-hole="j22" opacity="0.75"/><circle cx="220.00" cy="110.00" r="1.30" fill="#718178" data-hole="a23" opacity="0.75"/><circle cx="220.00" cy="100.00" r="1.30" fill="#718178" data-hole="b23" opacity="0.75"/><circle cx="220.00" cy="90.00" r="1.30" fill="#718178" data-hole="c23" opacity="0.75"/><circle cx="220.00" cy="80.00" r="1.30" fill="#718178" data-hole="d23" opacity="0.75"/><circle cx="220.00" cy="70.00" r="1.30" fill="#718178" data-hole="e23" opacity="0.75"/><circle cx="220.00" cy="40.00" r="1.30" fill="#718178" data-hole="f23" opacity="0.75"/><circle cx="220.00" cy="30.00" r="1.30" fill="#718178" data-hole="g23" opacity="0.75"/><circle cx="220.00" cy="20.00" r="1.30" fill="#718178" data-hole="h23" opacity="0.75"/><circle cx="220.00" cy="10.00" r="1.30" fill="#718178" data-hole="i23" opacity="0.75"/><circle cx="220.00" cy="0.00" r="1.30" fill="#718178" data-hole="j23" opacity="0.75"/><circle cx="230.00" cy="110.00" r="1.30" fill="#718178" data-hole="a24" opacity="0.75"/><circle cx="230.00" cy="100.00" r="1.30" fill="#718178" data-hole="b24" opacity="0.75"/><circle cx="230.00" cy="90.00" r="1.30" fill="#718178" data-hole="c24" opacity="0.75"/><circle cx="230.00" cy="80.00" r="1.30" fill="#718178" data-hole="d24" opacity="0.75"/><circle cx="230.00" cy="70.00" r="1.30" fill="#718178" data-hole="e24" opacity="0.75"/><circle cx="230.00" cy="40.00" r="1.30" fill="#718178" data-hole="f24" opacity="0.75"/><circle cx="230.00" cy="30.00" r="1.30" fill="#718178" data-hole="g24" opacity="0.75"/><circle cx="230.00" cy="20.00" r="1.30" fill="#718178" data-hole="h24" opacity="0.75"/><circle cx="230.00" cy="10.00" r="1.30" fill="#718178" data-hole="i24" opacity="0.75"/><circle cx="230.00" cy="0.00" r="1.30" fill="#718178" data-hole="j24" opacity="0.75"/><circle cx="240.00" cy="110.00" r="1.30" fill="#718178" data-hole="a25" opacity="0.75"/><circle cx="240.00" cy="100.00" r="1.30" fill="#718178" data-hole="b25" opacity="0.75"/><circle cx="240.00" cy="90.00" r="1.30" fill="#718178" data-hole="c25" opacity="0.75"/><circle cx="240.00" cy="80.00" r="1.30" fill="#718178" data-hole="d25" opacity="0.75"/><circle cx="240.00" cy="70.00" r="1.30" fill="#718178" data-hole="e25" opacity="0.75"/><circle cx="240.00" cy="40.00" r="1.30" fill="#718178" data-hole="f25" opacity="0.75"/><circle cx="240.00" cy="30.00" r="1.30" fill="#718178" data-hole="g25" opacity="0.75"/><circle cx="240.00" cy="20.00" r="1.30" fill="#718178" data-hole="h25" opacity="0.75"/><circle cx="240.00" cy="10.00" r="1.30" fill="#718178" data-hole="i25" opacity="0.75"/><circle cx="240.00" cy="0.00" r="1.30" fill="#718178" data-hole="j25" opacity="0.75"/><circle cx="250.00" cy="110.00" r="1.30" fill="#718178" data-hole="a26" opacity="0.75"/><circle cx="250.00" cy="100.00" r="1.30" fill="#718178" data-hole="b26" opacity="0.75"/><circle cx="250.00" cy="90.00" r="1.30" fill="#718178" data-hole="c26" opacity="0.75"/><circle cx="250.00" cy="80.00" r="1.30" fill="#718178" data-hole="d26" opacity="0.75"/><circle cx="250.00" cy="70.00" r="1.30" fill="#718178" data-hole="e26" opacity="0.75"/><circle cx="250.00" cy="40.00" r="1.30" fill="#718178" data-hole="f26" opacity="0.75"/><circle cx="250.00" cy="30.00" r="1.30" fill="#718178" data-hole="g26" opacity="0.75"/><circle cx="250.00" cy="20.00" r="1.30" fill="#718178" data-hole="h26" opacity="0.75"/><circle cx="250.00" cy="10.00" r="1.30" fill="#718178" data-hole="i26" opacity="0.75"/><circle cx="250.00" cy="0.00" r="1.30" fill="#718178" data-hole="j26" opacity="0.75"/><circle cx="260.00" cy="110.00" r="1.30" fill="#718178" data-hole="a27" opacity="0.75"/><circle cx="260.00" cy="100.00" r="1.30" fill="#718178" data-hole="b27" opacity="0.75"/><circle cx="260.00" cy="90.00" r="1.30" fill="#718178" data-hole="c27" opacity="0.75"/><circle cx="260.00" cy="80.00" r="1.30" fill="#718178" data-hole="d27" opacity="0.75"/><circle cx="260.00" cy="70.00" r="1.30" fill="#718178" data-hole="e27" opacity="0.75"/><circle cx="260.00" cy="40.00" r="1.30" fill="#718178" data-hole="f27" opacity="0.75"/><circle cx="260.00" cy="30.00" r="1.30" fill="#718178" data-hole="g27" opacity="0.75"/><circle cx="260.00" cy="20.00" r="1.30" fill="#718178" data-hole="h27" opacity="0.75"/><circle cx="260.00" cy="10.00" r="1.30" fill="#718178" data-hole="i27" opacity="0.75"/><circle cx="260.00" cy="0.00" r="1.30" fill="#718178" data-hole="j27" opacity="0.75"/><circle cx="270.00" cy="110.00" r="1.30" fill="#718178" data-hole="a28" opacity="0.75"/><circle cx="270.00" cy="100.00" r="1.30" fill="#718178" data-hole="b28" opacity="0.75"/><circle cx="270.00" cy="90.00" r="1.30" fill="#718178" data-hole="c28" opacity="0.75"/><circle cx="270.00" cy="80.00" r="1.30" fill="#718178" data-hole="d28" opacity="0.75"/><circle cx="270.00" cy="70.00" r="1.30" fill="#718178" data-hole="e28" opacity="0.75"/><circle cx="270.00" cy="40.00" r="1.30" fill="#718178" data-hole="f28" opacity="0.75"/><circle cx="270.00" cy="30.00" r="1.30" fill="#718178" data-hole="g28" opacity="0.75"/><circle cx="270.00" cy="20.00" r="1.30" fill="#718178" data-hole="h28" opacity="0.75"/><circle cx="270.00" cy="10.00" r="1.30" fill="#718178" data-hole="i28" opacity="0.75"/><circle cx="270.00" cy="0.00" r="1.30" fill="#718178" data-hole="j28" opacity="0.75"/><circle cx="280.00" cy="110.00" r="1.30" fill="#718178" data-hole="a29" opacity="0.75"/><circle cx="280.00" cy="100.00" r="1.30" fill="#718178" data-hole="b29" opacity="0.75"/><circle cx="280.00" cy="90.00" r="1.30" fill="#718178" data-hole="c29" opacity="0.75"/><circle cx="280.00" cy="80.00" r="1.30" fill="#718178" data-hole="d29" opacity="0.75"/><circle cx="280.00" cy="70.00" r="1.30" fill="#718178" data-hole="e29" opacity="0.75"/><circle cx="280.00" cy="40.00" r="1.30" fill="#718178" data-hole="f29" opacity="0.75"/><circle cx="280.00" cy="30.00" r="1.30" fill="#718178" data-hole="g29" opacity="0.75"/><circle cx="280.00" cy="20.00" r="1.30" fill="#718178" data-hole="h29" opacity="0.75"/><circle cx="280.00" cy="10.00" r="1.30" fill="#718178" data-hole="i29" opacity="0.75"/><circle cx="280.00" cy="0.00" r="1.30" fill="#718178" data-hole="j29" opacity="0.75"/><circle cx="290.00" cy="110.00" r="1.30" fill="#718178" data-hole="a30" opacity="0.75"/><circle cx="290.00" cy="100.00" r="1.30" fill="#718178" data-hole="b30" opacity="0.75"/><circle cx="290.00" cy="90.00" r="1.30" fill="#718178" data-hole="c30" opacity="0.75"/><circle cx="290.00" cy="80.00" r="1.30" fill="#718178" data-hole="d30" opacity="0.75"/><circle cx="290.00" cy="70.00" r="1.30" fill="#718178" data-hole="e30" opacity="0.75"/><circle cx="290.00" cy="40.00" r="1.30" fill="#718178" data-hole="f30" opacity="0.75"/><circle cx="290.00" cy="30.00" r="1.30" fill="#718178" data-hole="g30" opacity="0.75"/><circle cx="290.00" cy="20.00" r="1.30" fill="#718178" data-hole="h30" opacity="0.75"/><circle cx="290.00" cy="10.00" r="1.30" fill="#718178" data-hole="i30" opacity="0.75"/><circle cx="290.00" cy="0.00" r="1.30" fill="#718178" data-hole="j30" opacity="0.75"/><circle cx="10.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+1" opacity="0.75"/><circle cx="20.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+2" opacity="0.75"/><circle cx="30.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+3" opacity="0.75"/><circle cx="40.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+4" opacity="0.75"/><circle cx="50.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+5" opacity="0.75"/><circle cx="70.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+6" opacity="0.75"/><circle cx="80.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+7" opacity="0.75"/><circle cx="90.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+8" opacity="0.75"/><circle cx="100.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+9" opacity="0.75"/><circle cx="110.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+10" opacity="0.75"/><circle cx="130.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+11" opacity="0.75"/><circle cx="140.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+12" opacity="0.75"/><circle cx="150.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+13" opacity="0.75"/><circle cx="160.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+14" opacity="0.75"/><circle cx="170.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+15" opacity="0.75"/><circle cx="190.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+16" opacity="0.75"/><circle cx="200.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+17" opacity="0.75"/><circle cx="210.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+18" opacity="0.75"/><circle cx="220.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+19" opacity="0.75"/><circle cx="230.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+20" opacity="0.75"/><circle cx="250.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+21" opacity="0.75"/><circle cx="260.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+22" opacity="0.75"/><circle cx="270.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+23" opacity="0.75"/><circle cx="280.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+24" opacity="0.75"/><circle cx="290.00" cy="-20.00" r="1.30" fill="#718178" data-hole="T+25" opacity="0.75"/><circle cx="10.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-1" opacity="0.75"/><circle cx="20.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-2" opacity="0.75"/><circle cx="30.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-3" opacity="0.75"/><circle cx="40.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-4" opacity="0.75"/><circle cx="50.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-5" opacity="0.75"/><circle cx="70.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-6" opacity="0.75"/><circle cx="80.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-7" opacity="0.75"/><circle cx="90.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-8" opacity="0.75"/><circle cx="100.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-9" opacity="0.75"/><circle cx="110.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-10" opacity="0.75"/><circle cx="130.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-11" opacity="0.75"/><circle cx="140.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-12" opacity="0.75"/><circle cx="150.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-13" opacity="0.75"/><circle cx="160.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-14" opacity="0.75"/><circle cx="170.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-15" opacity="0.75"/><circle cx="190.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-16" opacity="0.75"/><circle cx="200.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-17" opacity="0.75"/><circle cx="210.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-18" opacity="0.75"/><circle cx="220.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-19" opacity="0.75"/><circle cx="230.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-20" opacity="0.75"/><circle cx="250.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-21" opacity="0.75"/><circle cx="260.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-22" opacity="0.75"/><circle cx="270.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-23" opacity="0.75"/><circle cx="280.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-24" opacity="0.75"/><circle cx="290.00" cy="-30.00" r="1.30" fill="#718178" data-hole="T-25" opacity="0.75"/><circle cx="10.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+1" opacity="1"/><circle cx="20.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+2" opacity="1"/><circle cx="30.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+3" opacity="1"/><circle cx="40.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+4" opacity="1"/><circle cx="50.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+5" opacity="1"/><circle cx="70.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+6" opacity="1"/><circle cx="80.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+7" opacity="1"/><circle cx="90.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+8" opacity="1"/><circle cx="100.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+9" opacity="1"/><circle cx="110.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+10" opacity="1"/><circle cx="130.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+11" opacity="1"/><circle cx="140.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+12" opacity="1"/><circle cx="150.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+13" opacity="1"/><circle cx="160.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+14" opacity="1"/><circle cx="170.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+15" opacity="1"/><circle cx="190.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+16" opacity="1"/><circle cx="200.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+17" opacity="1"/><circle cx="210.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+18" opacity="1"/><circle cx="220.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+19" opacity="1"/><circle cx="230.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+20" opacity="1"/><circle cx="250.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+21" opacity="1"/><circle cx="260.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+22" opacity="1"/><circle cx="270.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+23" opacity="1"/><circle cx="280.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+24" opacity="1"/><circle cx="290.00" cy="140.00" r="1.80" fill="#d4e2d9" data-hole="B+25" opacity="1"/><circle cx="10.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-1" opacity="1"/><circle cx="20.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-2" opacity="1"/><circle cx="30.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-3" opacity="1"/><circle cx="40.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-4" opacity="1"/><circle cx="50.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-5" opacity="1"/><circle cx="70.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-6" opacity="1"/><circle cx="80.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-7" opacity="1"/><circle cx="90.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-8" opacity="1"/><circle cx="100.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-9" opacity="1"/><circle cx="110.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-10" opacity="1"/><circle cx="130.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-11" opacity="1"/><circle cx="140.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-12" opacity="1"/><circle cx="150.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-13" opacity="1"/><circle cx="160.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-14" opacity="1"/><circle cx="170.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-15" opacity="1"/><circle cx="190.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-16" opacity="1"/><circle cx="200.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-17" opacity="1"/><circle cx="210.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-18" opacity="1"/><circle cx="220.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-19" opacity="1"/><circle cx="230.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-20" opacity="1"/><circle cx="250.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-21" opacity="1"/><circle cx="260.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-22" opacity="1"/><circle cx="270.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-23" opacity="1"/><circle cx="280.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-24" opacity="1"/><circle cx="290.00" cy="130.00" r="1.80" fill="#d4e2d9" data-hole="B-25" opacity="1"/></g>
8
+ <g id="components"><g data-ref="SW1"><line x1="90.00" y1="70.00" x2="100.00" y2="55.00" stroke="#91a199" stroke-width="0.90"/><line x1="90.00" y1="40.00" x2="100.00" y2="55.00" stroke="#91a199" stroke-width="0.90"/><line x1="110.00" y1="70.00" x2="100.00" y2="55.00" stroke="#91a199" stroke-width="0.90"/><line x1="110.00" y1="40.00" x2="100.00" y2="55.00" stroke="#91a199" stroke-width="0.90"/><rect x="88.00" y="45.00" width="24.00" height="20.00" rx="2" fill="#ece7dd" stroke="#504c45" data-ref="SW1"/><circle cx="100.00" cy="55.00" r="5.00" fill="#c7c0b5" stroke="#6c655b"/><text x="100.00" y="42.00" transform="rotate(-90 100.00 42.00)" font-size="5" font-weight="500" text-anchor="middle">SW1</text></g><g data-ref="R1"><line x1="110.00" y1="110.00" x2="130.00" y2="110.00" stroke="#91a199" stroke-width="0.90"/><line x1="150.00" y1="110.00" x2="130.00" y2="110.00" stroke="#91a199" stroke-width="0.90"/><rect x="118.00" y="106.00" width="24.00" height="8.00" rx="3" fill="#f0d79c" stroke="#654f36" data-ref="R1"/><rect x="123.00" y="106.00" width="1.70" height="8.00" fill="#ff8c00"/><rect x="127.00" y="106.00" width="1.70" height="8.00" fill="#ff8c00"/><rect x="131.00" y="106.00" width="1.70" height="8.00" fill="#8b4513"/><rect x="135.00" y="106.00" width="1.70" height="8.00" fill="#d4af37"/><text x="130.00" y="103.00" transform="rotate(-90 130.00 103.00)" font-size="5" font-weight="500" text-anchor="middle">R1 330</text></g><g data-ref="D1"><line x1="150.00" y1="100.00" x2="155.00" y2="100.00" stroke="#91a199" stroke-width="0.90"/><line x1="160.00" y1="100.00" x2="155.00" y2="100.00" stroke="#91a199" stroke-width="0.90"/><circle cx="155.00" cy="100.00" r="5.50" fill="#df5550" stroke="#733b39" data-ref="D1"/><line x1="157.50" y1="95.00" x2="157.50" y2="105.00" stroke="#733b39" stroke-width="1.20"/><text x="155.00" y="92.00" transform="rotate(-90 155.00 92.00)" font-size="5" font-weight="500" text-anchor="middle">D1</text></g></g>
9
+ <g id="offboard"></g>
10
+ <g id="wires"><path d="M 90.00 110.00 L 90.00 140.00" fill="none" stroke="#202a27" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/><path d="M 160.00 110.00 L 160.00 130.00" fill="none" stroke="#202a27" stroke-width="3.6" stroke-linecap="round" stroke-linejoin="round"/><path d="M 90.00 110.00 L 90.00 140.00" fill="none" stroke="red" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" data-ref="W1"/><path d="M 160.00 110.00 L 160.00 130.00" fill="none" stroke="black" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" data-ref="W2"/><circle cx="90.00" cy="110.00" r="2.80" fill="red" stroke="#202a27" stroke-width="1.2" data-wire="W1"/><circle cx="90.00" cy="140.00" r="2.80" fill="red" stroke="#202a27" stroke-width="1.2" data-wire="W1"/><circle cx="160.00" cy="110.00" r="2.80" fill="black" stroke="#202a27" stroke-width="1.2" data-wire="W2"/><circle cx="160.00" cy="130.00" r="2.80" fill="black" stroke="#202a27" stroke-width="1.2" data-wire="W2"/></g>
11
+ <g id="labels"><text x="-7.00" y="110.00" transform="rotate(-90 -7.00 110.00)" font-size="8" font-weight="500" fill="#c0cdc5" text-anchor="middle">a</text><text x="-7.00" y="100.00" transform="rotate(-90 -7.00 100.00)" font-size="8" font-weight="500" fill="#c0cdc5" text-anchor="middle">b</text><text x="-7.00" y="90.00" transform="rotate(-90 -7.00 90.00)" font-size="8" font-weight="500" fill="#c0cdc5" text-anchor="middle">c</text><text x="-7.00" y="80.00" transform="rotate(-90 -7.00 80.00)" font-size="8" font-weight="500" fill="#c0cdc5" text-anchor="middle">d</text><text x="-7.00" y="70.00" transform="rotate(-90 -7.00 70.00)" font-size="8" font-weight="500" fill="#c0cdc5" text-anchor="middle">e</text><text x="-7.00" y="40.00" transform="rotate(-90 -7.00 40.00)" font-size="8" font-weight="500" fill="#c0cdc5" text-anchor="middle">f</text><text x="-7.00" y="30.00" transform="rotate(-90 -7.00 30.00)" font-size="8" font-weight="500" fill="#c0cdc5" text-anchor="middle">g</text><text x="-7.00" y="20.00" transform="rotate(-90 -7.00 20.00)" font-size="8" font-weight="500" fill="#c0cdc5" text-anchor="middle">h</text><text x="-7.00" y="10.00" transform="rotate(-90 -7.00 10.00)" font-size="8" font-weight="500" fill="#c0cdc5" text-anchor="middle">i</text><text x="-7.00" y="0.00" transform="rotate(-90 -7.00 0.00)" font-size="8" font-weight="500" fill="#c0cdc5" text-anchor="middle">j</text><rect x="2.00" y="115.00" width="6.00" height="10.00" rx="2" fill="#202a27" stroke="#52625b" stroke-width="0.6"/><text x="8.00" y="120.00" transform="rotate(-90 8.00 120.00)" font-size="6" font-weight="500" fill="#e8efeb" text-anchor="middle">1</text><rect x="42.00" y="115.00" width="6.00" height="10.00" rx="2" fill="#202a27" stroke="#52625b" stroke-width="0.6"/><text x="48.00" y="120.00" transform="rotate(-90 48.00 120.00)" font-size="6" font-weight="500" fill="#e8efeb" text-anchor="middle">5</text><rect x="92.00" y="115.00" width="6.00" height="10.00" rx="2" fill="#202a27" stroke="#52625b" stroke-width="0.6"/><text x="98.00" y="120.00" transform="rotate(-90 98.00 120.00)" font-size="6" font-weight="500" fill="#e8efeb" text-anchor="middle">10</text><rect x="142.00" y="115.00" width="6.00" height="10.00" rx="2" fill="#202a27" stroke="#52625b" stroke-width="0.6"/><text x="148.00" y="120.00" transform="rotate(-90 148.00 120.00)" font-size="6" font-weight="500" fill="#e8efeb" text-anchor="middle">15</text><rect x="192.00" y="115.00" width="6.00" height="10.00" rx="2" fill="#202a27" stroke="#52625b" stroke-width="0.6"/><text x="198.00" y="120.00" transform="rotate(-90 198.00 120.00)" font-size="6" font-weight="500" fill="#e8efeb" text-anchor="middle">20</text><rect x="242.00" y="115.00" width="6.00" height="10.00" rx="2" fill="#202a27" stroke="#52625b" stroke-width="0.6"/><text x="248.00" y="120.00" transform="rotate(-90 248.00 120.00)" font-size="6" font-weight="500" fill="#e8efeb" text-anchor="middle">25</text><rect x="292.00" y="115.00" width="6.00" height="10.00" rx="2" fill="#202a27" stroke="#52625b" stroke-width="0.6"/><text x="298.00" y="120.00" transform="rotate(-90 298.00 120.00)" font-size="6" font-weight="500" fill="#e8efeb" text-anchor="middle">30</text></g>
12
+ <g id="nets"></g><g id="annotations"></g>
13
+ </g>
14
+ <g id="legend"></g></svg>