aboutsummaryrefslogtreecommitdiff
path: root/hw/clef
diff options
context:
space:
mode:
authorNathan Perry <np@nathanperry.dev>2024-09-02 19:53:43 -0400
committerNathan Perry <np@nathanperry.dev>2024-09-02 19:53:43 -0400
commit982798292719a24bcbb4f9e17cd5c65c8a46ecda (patch)
tree11800fcb5a70f21903aeebed407473420bbe0d41 /hw/clef
parent5ddfa32166cee8b2f91f37f9037eb26c182c2125 (diff)
move hw into subdirectory
Diffstat (limited to 'hw/clef')
-rw-r--r--hw/clef/.gitignore36
-rw-r--r--hw/clef/README.md199
-rw-r--r--hw/clef/flake.lock209
-rw-r--r--hw/clef/flake.nix85
-rw-r--r--hw/clef/kikit/jlc_frame.json52
-rw-r--r--hw/clef/nix/board.nix39
-rw-r--r--hw/clef/nix/bom.nix48
-rw-r--r--hw/clef/nix/default.nix61
-rw-r--r--hw/clef/nix/fabrication.nix82
-rw-r--r--hw/clef/nix/model.nix58
-rw-r--r--hw/clef/nix/panel.nix46
-rw-r--r--hw/clef/nix/pkgs/default.nix5
-rw-r--r--hw/clef/nix/pkgs/interactive_html_bom.nix69
-rw-r--r--hw/clef/nix/schematic.nix54
-rw-r--r--hw/clef/nix/svg.nix92
-rw-r--r--hw/clef/overlays.nix49
-rw-r--r--hw/clef/sheet/personal.kicad_wks139
-rw-r--r--hw/clef/sheet/personal_noborder.kicad_wks65
-rw-r--r--hw/clef/sheet/resenv.kicad_wks307
-rw-r--r--hw/clef/sheet/resenv_noborder.kicad_wks233
20 files changed, 1928 insertions, 0 deletions
diff --git a/hw/clef/.gitignore b/hw/clef/.gitignore
new file mode 100644
index 0000000..3159192
--- /dev/null
+++ b/hw/clef/.gitignore
@@ -0,0 +1,36 @@
+*-backups/
+*.lck
+fp-info-cache
+_autosave-*
+*.kicad_prl
+*.*-bak
+*.bak
+*.backups
+*.net
+*.dsn
+*.ses
+*.xml
+*.csv
+*.000
+*.tmp
+*-save.pro
+*-save.kicad_pcb
+\#auto-saved-files\#
+\#auto_saved_files\#
+sym-lib-table
+*.gbr
+*.gbrjob
+*.drl
+*/fab_out/*
+!*/fab_out/*.FlatPrj
+__pycache__/
+*.pyc
+/fab/
+/fab_out/
+*/fab/*
+
+/production/
+/panel/
+panel.*
+/bom/
+!panel.nix
diff --git a/hw/clef/README.md b/hw/clef/README.md
new file mode 100644
index 0000000..19520b9
--- /dev/null
+++ b/hw/clef/README.md
@@ -0,0 +1,199 @@
+# clef
+
+My kicad templates, libraries, and sheets.
+
+Comes with a Nix function to process a KiCad project into:
+
+- Board SVGs
+- Board 3d model (.glb, .step)
+- Schematic PDF, SVGs
+- Fabrication files (using kikit)
+ - Currently untested &mdash; I had to use Fabrication Toolkit on my last
+ project
+- Panelized board (using kikit)
+ - Also minimal testing
+
+Example output for [ocularium](https://pub.npry.dev/ocularium), which provides
+the content for [this blog post](https://blog.npry.dev/resenv/ocularium):
+
+```bash
+$ nix build .# && nix run nixpkgs#tree result
+result
+└── share
+ └── npry
+ └── ocularium
+ ├── fab
+ │   ├── bom.csv
+ │   ├── gerbers.zip
+ │   └── pos.csv
+ ├── model
+ │   ├── okm.glb
+ │   └── okm.step
+ ├── schematic
+ │   ├── schematic.pdf
+ │   └── svg
+ │   ├── IO.svg
+ │   ├── MCU.svg
+ │   ├── Power.svg
+ │   ├── root.svg
+ │   └── Sensors.svg
+ └── svg
+ ├── back.mirror.svg
+ ├── back.svg
+ ├── front.mirror.svg
+ ├── front.svg
+ ├── in1.mirror.svg
+ ├── in1.svg
+ ├── in2.mirror.svg
+ └── in2.svg
+
+8 directories, 19 files
+```
+
+## usage: subtree
+
+I currently include this repo as a [git
+_subtree_](https://manpages.debian.org/testing/git-man/git-subtree.1.en.html)
+in kicad projects that use it:
+
+```bash
+# to init:
+$ git subtree add --squash --prefix clef https://pub.npry.dev/clef master
+
+# then to update:
+$ git subtree pull --squash --prefix clef https://pub.npry.dev/clef master
+```
+
+Submodules are closer to what I want semantically, but I consider them too
+fragile to use.
+
+## nix
+
+The flake provides `pkgs.clef`, a function building a derivation that contains
+the processed content.
+
+Please be aware that complete functionality will involve rebuilding a couple
+of large derivations from source (KiCad, occt and dependents) until I get
+around to upstreaming my overlays.
+
+### example
+
+```nix
+# flake.nix
+{
+ inputs = {
+ nixpkgs.url = "github:nixos/nixpkgs/release-24.05";
+ flake-utils.url = "github:numtide/flake-utils/main";
+
+ clef = {
+ url = "git+https://pub.npry.dev/clef";
+
+ # or if using subtree/submodules:
+ # url = "path:clef";
+
+ inputs.nixpkgs.follows = "nixpkgs";
+ flake-utils.follows = "flake-utils";
+ };
+ };
+
+ outputs = { nixpkgs, clef }: (flake-utils.lib.eachDefaultSystem (system: let
+ pkgs = import nixpkgs {
+ overlays = [
+ # NB: This causes another independent nixpkgs eval -- it's just:
+ #
+ # final: prev: { inherit (clef.packages.${prev.system}) clef; }
+ #
+ # This is the easiest way to get started, and if you don't know or
+ # care why you don't want to eval nixpkgs multiple times, this is
+ # probably what you want.
+ #
+ # If you are looking for a more efficient nixpkgs config, see the
+ # flake source for notes -- currently you need to include
+ # clef.overlays.kicad and clef.overlays.nix-filter.
+ clef.default
+ ];
+ };
+
+ clefDrv = pkgs.clef {
+ name = "my_board";
+
+ # Kicad project directory. Automatically filtered by clef to
+ # kicad-relevant files.
+ src = ./.;
+
+ main_pcb = "my_pcb.kicad_pcb";
+ main_sch = "my_sch.kicad_sch";
+
+ outPath = "share/npry/example";
+
+ layers = 4;
+
+ # Parameters to `kikit panelize -p`. Only required if you want
+ # to panelize or tile your board.
+ panelizeConfigs = [
+ ":jlcTooling"
+ ./kikit/jlc_frame.json
+ ];
+ };
+
+ in {
+ packages = {
+ # The main derivation has all of the processed output in it --
+ # gerbers, 3d files, SVGs, schematic PDFs, and a panelized
+ # board (if configured). They are found in the `outPath` you
+ # configure in the argument attrs.
+ default = clefDrv;
+
+ # You can use `passthru` attributes to access individual components
+ # of the build. Outputs are all found as subdirs of
+ # `share/npry/clef`.
+ inherit (clefDrv) models;
+
+ # `panelSrc` has the panelized kicad project (new .kicad_pcb with
+ # the original .kicad_sch and .kicad_pro).
+ panelizedProject = clefDrv.panelSrc;
+
+ # `panel` is the result of calling `clef` with `src = panelSrc;`,
+ # i.e. 3d models, fabrication outputs, and so on for the
+ # panelized board.
+ inherit (clefDrv) panel;
+
+ # If for you need a recursive panelization, you can in
+ # principle do that:
+ panelPanel = (clefDrv.panel.override {
+ panelizeConfigs = [ ":jlcTooling" ./my_nested_panel_config.json ];
+ }).panel;
+ };
+ }));
+}
+```
+
+### direct `callPackage`
+
+The individual component derivations are intentionally written to be usable
+directly:
+
+```nix
+pkgs.callPackage "${clef}/nix/model.nix" {
+ src = ./.;
+ pcb_path = "my_pcb.kicad_pcb";
+}
+```
+
+Bear in mind that you will need the relevant overlays in the calling `nixpkgs`
+for this usage mode:
+
+- `models` needs `clef.overlays.kicad` (adds RapidJSON support to occt,
+ enabling glb export)
+- `fab` wants `clef.overlays.kicad` for a newer version of kikit
+- Everything needs `nix-filter`.
+
+Output for the individual derivations will be found in subdirectories of
+`share/npry/clef`, with filenames normalized.
+
+## etymology
+
+French: "key", pronounced like "clay". (Cognate with the "clef" of "treble
+clef", "bass clef" ~> "treble key", "bass key").
+
+Train of thought: KiCad's "Ki" -> "key" -> "clef".
diff --git a/hw/clef/flake.lock b/hw/clef/flake.lock
new file mode 100644
index 0000000..79b9ab4
--- /dev/null
+++ b/hw/clef/flake.lock
@@ -0,0 +1,209 @@
+{
+ "nodes": {
+ "cadquery-src": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1705326221,
+ "narHash": "sha256-f/qnq5g4FOiit9WQ7zs0axCJBITcAtqF18txMV97Gb8=",
+ "owner": "CadQuery",
+ "repo": "cadquery",
+ "rev": "c44978d60cee2d61bdadf4cb4498286b7034b4c6",
+ "type": "github"
+ },
+ "original": {
+ "owner": "CadQuery",
+ "ref": "2.4.0",
+ "repo": "cadquery",
+ "type": "github"
+ }
+ },
+ "cq": {
+ "inputs": {
+ "cadquery-src": "cadquery-src",
+ "cq-editor-src": "cq-editor-src",
+ "flake-utils": [
+ "flake-utils"
+ ],
+ "nixpkgs": [
+ "nixpkgs"
+ ],
+ "ocp-src": "ocp-src",
+ "ocp-stubs-src": "ocp-stubs-src",
+ "pybind11-stubgen-src": "pybind11-stubgen-src",
+ "pywrap-src": "pywrap-src"
+ },
+ "locked": {
+ "lastModified": 1723029696,
+ "narHash": "sha256-awv2fEsTkc749YcedWK1Y5P1xg5NfAosttlFnBsVVdg=",
+ "owner": "vinszent",
+ "repo": "cq-flake",
+ "rev": "27d9ac5b7f1fb5f271070ca0eed6a40c3fcfec17",
+ "type": "github"
+ },
+ "original": {
+ "owner": "vinszent",
+ "ref": "main",
+ "repo": "cq-flake",
+ "type": "github"
+ }
+ },
+ "cq-editor-src": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1701895648,
+ "narHash": "sha256-mHXEaA6vphps6F0WemdB6fGRY4lzpcxLU7WuYEp8c20=",
+ "owner": "CadQuery",
+ "repo": "CQ-editor",
+ "rev": "4ef178af06d24a53fee87d576f8cada14c0111a3",
+ "type": "github"
+ },
+ "original": {
+ "owner": "CadQuery",
+ "repo": "CQ-editor",
+ "rev": "4ef178af06d24a53fee87d576f8cada14c0111a3",
+ "type": "github"
+ }
+ },
+ "flake-utils": {
+ "inputs": {
+ "systems": "systems"
+ },
+ "locked": {
+ "lastModified": 1710146030,
+ "narHash": "sha256-SZ5L6eA7HJ/nmkzGG7/ISclqe6oZdOZTNoesiInkXPQ=",
+ "owner": "numtide",
+ "repo": "flake-utils",
+ "rev": "b1d9ab70662946ef0850d488da1c9019f3a9752a",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "ref": "main",
+ "repo": "flake-utils",
+ "type": "github"
+ }
+ },
+ "nix-filter": {
+ "locked": {
+ "lastModified": 1710156097,
+ "narHash": "sha256-1Wvk8UP7PXdf8bCCaEoMnOT1qe5/Duqgj+rL8sRQsSM=",
+ "owner": "numtide",
+ "repo": "nix-filter",
+ "rev": "3342559a24e85fc164b295c3444e8a139924675b",
+ "type": "github"
+ },
+ "original": {
+ "owner": "numtide",
+ "ref": "main",
+ "repo": "nix-filter",
+ "type": "github"
+ }
+ },
+ "nixpkgs": {
+ "locked": {
+ "lastModified": 1723556749,
+ "narHash": "sha256-+CHVZnTnIYRLYsARInHYoWkujzcRkLY/gXm3s5bE52o=",
+ "owner": "nixos",
+ "repo": "nixpkgs",
+ "rev": "4a92571f9207810b559c9eac203d1f4d79830073",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nixos",
+ "ref": "nixos-24.05",
+ "repo": "nixpkgs",
+ "type": "github"
+ }
+ },
+ "ocp-src": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1701196143,
+ "narHash": "sha256-PMkMYEVBHt0i7ahgqF8jLhHHp7IRS7hd+JyydovNJ4A=",
+ "owner": "cadquery",
+ "repo": "ocp",
+ "rev": "4b98a5dc79fa900f7429975708f6a8c2e41cecd1",
+ "type": "github"
+ },
+ "original": {
+ "owner": "cadquery",
+ "repo": "ocp",
+ "rev": "4b98a5dc79fa900f7429975708f6a8c2e41cecd1",
+ "type": "github"
+ }
+ },
+ "ocp-stubs-src": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1672527176,
+ "narHash": "sha256-m9Rg36GYlYfwEfF0PQJWEXf8TyM5HmjeuhJCODiurvY=",
+ "owner": "cadquery",
+ "repo": "ocp-stubs",
+ "rev": "e838ff400d5ee2f4a0579d2a713b19311855288f",
+ "type": "github"
+ },
+ "original": {
+ "owner": "cadquery",
+ "repo": "ocp-stubs",
+ "type": "github"
+ }
+ },
+ "pybind11-stubgen-src": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1700678104,
+ "narHash": "sha256-76u1GcHPPh8oYQeQZDJ4K/so0U7F6rznZ1xa6syqI9s=",
+ "owner": "CadQuery",
+ "repo": "pybind11-stubgen",
+ "rev": "6dc681d838d3ec9a8a9aa4260c8392d3fb700ff0",
+ "type": "github"
+ },
+ "original": {
+ "owner": "CadQuery",
+ "repo": "pybind11-stubgen",
+ "type": "github"
+ }
+ },
+ "pywrap-src": {
+ "flake": false,
+ "locked": {
+ "lastModified": 1676015766,
+ "narHash": "sha256-QhAvJHV5tFq9bjKOzEpcudZNnmUmNVrJ+BLCZJhO31g=",
+ "owner": "CadQuery",
+ "repo": "pywrap",
+ "rev": "f3bcde70fd66a2d884fa60a7a9d9f6aa7c3b6e16",
+ "type": "github"
+ },
+ "original": {
+ "owner": "CadQuery",
+ "repo": "pywrap",
+ "type": "github"
+ }
+ },
+ "root": {
+ "inputs": {
+ "cq": "cq",
+ "flake-utils": "flake-utils",
+ "nix-filter": "nix-filter",
+ "nixpkgs": "nixpkgs"
+ }
+ },
+ "systems": {
+ "locked": {
+ "lastModified": 1681028828,
+ "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
+ "owner": "nix-systems",
+ "repo": "default",
+ "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
+ "type": "github"
+ },
+ "original": {
+ "owner": "nix-systems",
+ "repo": "default",
+ "type": "github"
+ }
+ }
+ },
+ "root": "root",
+ "version": 7
+}
diff --git a/hw/clef/flake.nix b/hw/clef/flake.nix
new file mode 100644
index 0000000..f20b1b8
--- /dev/null
+++ b/hw/clef/flake.nix
@@ -0,0 +1,85 @@
+# vim: ft=nix :
+{
+ inputs = {
+ nixpkgs.url = "github:nixos/nixpkgs/nixos-24.05";
+ flake-utils.url = "github:numtide/flake-utils/main";
+ nix-filter.url = "github:numtide/nix-filter/main";
+
+ cq = {
+ url = "github:vinszent/cq-flake/main";
+ inputs.nixpkgs.follows = "nixpkgs";
+ inputs.flake-utils.follows = "flake-utils";
+ };
+ };
+
+ description = "clef: kicad shared data and utils";
+
+ outputs = { self, nixpkgs, flake-utils, ... } @ inputs: (flake-utils.lib.eachDefaultSystem (system: {
+ packages = let
+ packages = nixpkgs.legacyPackages.${system}.callPackages ./nix/pkgs {};
+
+ pkgs = import nixpkgs {
+ inherit system;
+
+ overlays = with self.overlays; [
+ kicad
+ nix-filter
+
+ (final: prev: packages)
+ ];
+ };
+
+ clef = pkgs.callPackage ./nix;
+ in packages // {
+ inherit clef;
+ default = clef;
+ };
+
+ devShells.default = let
+ pkgs = import nixpkgs {
+ inherit system;
+
+ overlays = with self.overlays; [
+ kicad
+ ];
+ };
+
+ in pkgs.mkShell {
+ name = "devshell";
+ version = self.rev or "dirty";
+
+ packages = with pkgs; [
+ kicad
+ kikit
+ ];
+ };
+ }
+ )) // {
+ overlays = let
+ base = (import ./overlays.nix { inherit inputs; });
+
+ in base // {
+ # clef built against its own nixpkgs import with its required overlay
+ # deps (kicad, occt).
+ #
+ # _This will cause another evaluation of nixpkgs_, which is generally
+ # undesirable. However, this provides for the most hassle-free way to
+ # use clef, as you don't need to include all of the overlay dependencies
+ # in your nixpkgs.
+ default = final: prev: {
+ inherit (self.packages.${prev.system}) clef;
+ };
+
+ # No overlay dependencies included -- clef will not work by default.
+ # You can replicate overlays.default with:
+ #
+ # import nixpkgs { overlays = with clef.overlays; [ freestanding kicad nix-filter ]; }
+ #
+ # Assuming you've pinned clef's nixpkgs to the same version as yours.
+ # This functionality is provided to give you an option
+ freestanding = final: prev: (prev.callPackage ./nix/pkgs {}) {
+ clef = prev.callPackage ./nix;
+ };
+ };
+ };
+}
diff --git a/hw/clef/kikit/jlc_frame.json b/hw/clef/kikit/jlc_frame.json
new file mode 100644
index 0000000..4be213b
--- /dev/null
+++ b/hw/clef/kikit/jlc_frame.json
@@ -0,0 +1,52 @@
+{
+ "layout": {
+ "type": "grid",
+ "rows": 1,
+ "cols": 1
+ },
+ "framing": {
+ "type": "frame",
+ "width": "5mm",
+ "space": "3mm",
+ "cuts": "both",
+ "mintotalwidth": "70mm",
+ "mintotalheight": "70mm"
+ },
+ "tabs": {
+ "type": "annotation"
+ },
+ "cuts": {
+ "type": "mousebites",
+ "drill": "0.5mm",
+ "spacing": "1mm",
+ "offset": "0.2mm",
+ "prolong": "0.5mm"
+ },
+ "fiducials": {
+ "type": "3fid",
+ "hoffset": "5mm",
+ "voffset": "5mm",
+ "coppersize": "1mm",
+ "opening": "2mm"
+ },
+ "post": {
+ "millradius": "1mm"
+ },
+ "text": {
+ "type": "simple",
+ "text": "{boardTitle} {boardRevision}",
+ "anchor": "mt",
+ "voffset": "5mm",
+ "hjustify": "center",
+ "vjustify": "center"
+ },
+ "text2": {
+ "type": "simple",
+ "text": "npry {year}",
+ "anchor": "mb",
+ "voffset": "-5mm",
+ "hjustify": "center",
+ "vjustify": "center"
+ }
+}
+
diff --git a/hw/clef/nix/board.nix b/hw/clef/nix/board.nix
new file mode 100644
index 0000000..5de46e0
--- /dev/null
+++ b/hw/clef/nix/board.nix
@@ -0,0 +1,39 @@
+{
+ runCommand,
+
+ svg,
+ model,
+ fabrication,
+ schematic,
+ panel,
+ panelSrc,
+ bom,
+
+ name,
+ outPath,
+}: let
+ pkg = runCommand name {} ''
+ set -e
+
+ mkdir -p "$out/${outPath}"
+ cd "$out/${outPath}"
+
+ echo "populating $(pwd)"
+
+ cp --reflink=auto -vr "${schematic}/share/npry/clef/schematic" ./
+ cp --reflink=auto -vr "${svg}/share/npry/clef/svg" ./
+ cp --reflink=auto -vr "${fabrication}/share/npry/clef/fab" ./
+ cp --reflink=auto -vr "${model}/share/npry/clef/model" ./
+ cp --reflink=auto -vr "${bom}/share/npry/clef/bom" ./
+
+ ${if panelSrc != null then ''
+ cp --reflink=auto -vr "${panelSrc}/share/npry/clef/panel" ./
+ '' else ""}
+ '';
+
+in pkg.overrideAttrs (prevAttrs: {
+ passthru = (prevAttrs.passthru or {}) // {
+ inherit schematic fabrication svg model panel panelSrc bom;
+ fab = fabrication;
+ };
+})
diff --git a/hw/clef/nix/bom.nix b/hw/clef/nix/bom.nix
new file mode 100644
index 0000000..fbff8ff
--- /dev/null
+++ b/hw/clef/nix/bom.nix
@@ -0,0 +1,48 @@
+{
+ runCommand,
+ interactiveHtmlBom,
+
+ nix-filter,
+ lib,
+
+ pcb_path,
+ src,
+
+ boardName ? (lib.removeSuffix ".kicad_pcb" (builtins.baseNameOf pcb_path)),
+ extraArgs ? [
+ "--dark-mode"
+ "--include-tracks"
+ "--include-nets"
+ ],
+}: let
+ sharePath = "share/npry/clef/bom";
+
+in runCommand "${boardName}.bom" {
+ nativeBuildInputs = [
+ interactiveHtmlBom
+ ];
+
+ INTERACTIVE_HTML_BOM_NO_DISPLAY = 1;
+
+ src = nix-filter {
+ root = src;
+
+ include = [
+ (nix-filter.matchExt "kicad_pcb")
+ (nix-filter.matchExt "kicad_pro")
+ (nix-filter.matchExt "kicad_wks")
+
+ (_args: path: type: type == "directory")
+ ];
+ };
+} ''
+ mkdir -p "$out/${sharePath}"
+
+ cd $src
+
+ generate_interactive_bom \
+ --dest-dir "$out/${sharePath}" \
+ --no-browser \
+ ${lib.concatMapStrings (arg: "${arg} \\\n") extraArgs} \
+ "$src/${pcb_path}"
+''
diff --git a/hw/clef/nix/default.nix b/hw/clef/nix/default.nix
new file mode 100644
index 0000000..419c8fd
--- /dev/null
+++ b/hw/clef/nix/default.nix
@@ -0,0 +1,61 @@
+{
+ pkgs,
+
+ src,
+ main_pcb,
+ main_sch,
+
+ name,
+ outPath ? "share/npry/clef",
+ layers ? 2,
+
+ # set to a list of arguments to be passed to `kikit panelize -p`
+ panelizeConfigs ? null,
+}: let
+ pcb_path = main_pcb;
+ sch_path = main_sch;
+
+ pcb_args = {
+ inherit pcb_path src;
+ };
+
+ panelSrc = if panelizeConfigs != null then pkgs.callPackage ./panel.nix (pcb_args // { inherit panelizeConfigs; }) else null;
+
+ panel = if panelizeConfigs != null then
+ pkgs.callPackage ./. {
+ src = "${panelSrc}/share/npry/clef/panel";
+ main_pcb = "panel.kicad_pcb";
+
+ name = "${name}.sub.panel";
+ outPath = "${outPath}/panel";
+
+ inherit main_sch layers;
+ }
+ else null;
+
+ svg = pkgs.callPackage ./svg.nix (pcb_args // { nLayer = layers; });
+ model = pkgs.callPackage ./model.nix pcb_args;
+
+ bom = pkgs.callPackage ./bom.nix pcb_args;
+
+ fabrication = pkgs.callPackage ./fabrication.nix (pcb_args // {
+ inherit sch_path;
+ });
+
+ schematic = pkgs.callPackage ./schematic.nix {
+ inherit sch_path src;
+ };
+
+in pkgs.callPackage ./board.nix {
+ inherit
+ svg
+ model
+ bom
+ fabrication
+ schematic
+ name
+ outPath
+ panel
+ panelSrc
+ ;
+}
diff --git a/hw/clef/nix/fabrication.nix b/hw/clef/nix/fabrication.nix
new file mode 100644
index 0000000..18bc6f6
--- /dev/null
+++ b/hw/clef/nix/fabrication.nix
@@ -0,0 +1,82 @@
+{
+ kicad,
+ kikit,
+ zip,
+
+ runCommand,
+
+ nix-filter,
+ lib,
+
+ src,
+ pcb_path,
+ sch_path,
+
+ boardName ? (lib.removeSuffix ".kicad_pcb" (builtins.baseNameOf pcb_path)),
+
+ fabHouse ? "jlcpcb",
+ withAssembly ? true,
+}: let
+ sharePath = "share/npry/clef/fab";
+
+ fabSrc = nix-filter {
+ root = src;
+
+ include = [
+ (nix-filter.matchExt "kicad_sch")
+ (nix-filter.matchExt "kicad_wks")
+ (nix-filter.matchExt "kicad_pcb")
+ (nix-filter.matchExt "kicad_pro")
+
+ (_args: path: type: type == "directory")
+ ];
+ };
+
+in runCommand "${boardName}.fab" {
+ nativeBuildInputs = [
+ kicad
+ kikit
+ zip
+ ];
+
+ src = fabSrc;
+
+ allowedRequisites = [];
+} ''
+ set -e
+
+ export HOME=$(mktemp -d)
+
+ echo "board: '${boardName}'" >&2
+
+ mkdir -p "$out/${sharePath}"
+ cd "$src"
+
+ kikit fab ${fabHouse} \
+ ${if withAssembly then "--assembly" else ""} \
+ --no-drc \
+ --schematic "${sch_path}" \
+ --field 'LCSC Part #,LCSC Part No' \
+ --missingError \
+ "${pcb_path}" \
+ "$out/${sharePath}"
+
+ cd "$out/${sharePath}"
+ rm -vf "gerbers.zip"
+
+ pushd gerber
+
+ # normalize
+ for f in ${boardName}-*; do
+ mv -nv "$f" "''${f#${boardName}-}"
+ done
+
+ for f in ${boardName}.*; do
+ mv -nv "$f" "board''${f#${boardName}}"
+ done
+
+ popd
+
+ zip -vj "gerbers.zip" gerber/*
+ rm -vrf gerber
+''
diff --git a/hw/clef/nix/model.nix b/hw/clef/nix/model.nix
new file mode 100644
index 0000000..da8be82
--- /dev/null
+++ b/hw/clef/nix/model.nix
@@ -0,0 +1,58 @@
+{
+ kicad,
+ runCommand,
+
+ nix-filter,
+ lib,
+
+ withTracks ? false,
+ withZones ? false,
+
+ src,
+ pcb_path,
+
+ boardName ? (lib.removeSuffix ".kicad_pcb" (builtins.baseNameOf pcb_path)),
+}: let
+ zonesArg = if withZones then "--include-zones" else "";
+ tracksArg = if withTracks then "--include-tracks" else "";
+ sharePath = "share/npry/clef/model";
+
+in runCommand "${boardName}.model" {
+ nativeBuildInputs = [
+ kicad
+ ];
+
+ src = nix-filter {
+ root = src;
+
+ include = [
+ (nix-filter.matchExt "kicad_pcb")
+ (nix-filter.matchExt "kicad_pro")
+
+ (nix-filter.matchExt "stp")
+ (nix-filter.matchExt "STP")
+ (nix-filter.matchExt "step")
+ (nix-filter.matchExt "STEP")
+ (nix-filter.matchExt "wrl")
+
+ (_args: path: type: type == "directory")
+ ];
+ };
+
+ allowedRequisites = [];
+
+ KICAD8_3DMODEL_DIR = "${kicad.libraries.packages3d}/share/kicad/3dmodels";
+} ''
+ set -e
+
+ export HOME=$(mktemp -d)
+
+ echo "board: '${boardName}'" >&2
+ echo "KICAD8_3DMODEL_DIR: $KICAD8_3DMODEL_DIR" >&2
+
+ mkdir -p $out/${sharePath}
+ cd "$src"
+
+ kicad-cli pcb export step --subst-models --no-dnp ${tracksArg} ${zonesArg} "${pcb_path}" -o "$out/${sharePath}/${boardName}.step"
+ kicad-cli pcb export glb --subst-models --no-dnp ${tracksArg} ${zonesArg} "${pcb_path}" -o "$out/${sharePath}/${boardName}.glb"
+''
diff --git a/hw/clef/nix/panel.nix b/hw/clef/nix/panel.nix
new file mode 100644
index 0000000..1d88d46
--- /dev/null
+++ b/hw/clef/nix/panel.nix
@@ -0,0 +1,46 @@
+{
+ kikit,
+ runCommand,
+
+ nix-filter,
+ lib,
+
+ panelizeConfigs,
+ src,
+ pcb_path,
+
+ boardName ? (lib.removeSuffix ".kicad_pcb" (builtins.baseNameOf pcb_path)),
+}: let
+ sharePath = "share/npry/clef/panel";
+
+ panelSrc = nix-filter {
+ root = src;
+
+ include = [
+ (nix-filter.matchExt "kicad_pcb")
+ ];
+ };
+
+in runCommand "${boardName}.panel" {
+ nativeBuildInputs = [
+ kikit
+ ];
+
+ allowedRequisites = [];
+} ''
+ set -e
+ export HOME=$(mktemp -d)
+
+ mkdir -p "$out/${sharePath}"
+
+ # do the panelize here rather than in $out because it creates junk we don't want
+ cd $HOME
+
+ kikit panelize \
+ ${lib.concatMapStrings (conf: "-p ${conf} \\\n") panelizeConfigs} \
+ "${panelSrc}/${pcb_path}" \
+ "panel.kicad_pcb"
+
+ cp -v panel.kicad_{pcb,pro} "$out/${sharePath}"
+ cp -v "${src}/"*.kicad_{sch,pro} "$out/${sharePath}"
+''
diff --git a/hw/clef/nix/pkgs/default.nix b/hw/clef/nix/pkgs/default.nix
new file mode 100644
index 0000000..a0a9f92
--- /dev/null
+++ b/hw/clef/nix/pkgs/default.nix
@@ -0,0 +1,5 @@
+{
+ pkgs,
+}: {
+ interactiveHtmlBom = pkgs.callPackage ./interactive_html_bom.nix {};
+}
diff --git a/hw/clef/nix/pkgs/interactive_html_bom.nix b/hw/clef/nix/pkgs/interactive_html_bom.nix
new file mode 100644
index 0000000..8adf7a7
--- /dev/null
+++ b/hw/clef/nix/pkgs/interactive_html_bom.nix
@@ -0,0 +1,69 @@
+{
+ python3Packages,
+ writeText,
+ kicad-small,
+
+ fetchFromGitHub,
+
+ version ? "v2.9.0",
+ thisSrc ? fetchFromGitHub {
+ owner = "openscopeproject";
+ repo = "interactivehtmlbom";
+ rev = version;
+ hash = "sha256-jUHEI0dWMFPQlXei3+0m1ruHzpG1hcRnxptNOXzXDqQ=";
+ },
+}:
+
+let
+ src = thisSrc;
+ dummySetupPy = writeText "setup.py" ''
+ #!/usr/bin/env python3
+ # vim: set ft=python :
+
+ from setuptools import setup, find_packages
+ import sys
+
+ packages = find_packages(include=['InteractiveHtmlBom', 'InteractiveHtmlBom.*'])
+
+ setup(
+ name="InteractiveHtmlBom",
+ version='${version}',
+ packages=packages,
+ install_requires=['wxpython>=4.0', 'jsonschema>=4.1'],
+ entry_points={
+ 'console_scripts': [
+ 'generate_interactive_bom=InteractiveHtmlBom.generate_interactive_bom:main'
+ ]
+ },
+ include_package_data=True
+ )
+ '';
+
+ dummyManifest = writeText "MANIFEST.in" ''
+ recursive-include InteractiveHtmlBom/schema *
+ recursive-include InteractiveHtmlBom/web *
+ recursive-include InteractiveHtmlBom/dialog/bitmaps *
+ '';
+
+in python3Packages.buildPythonApplication {
+ pname = "interactive_html_bom";
+
+ inherit
+ version
+ src
+ ;
+
+ preBuild = ''
+ cp -nv ${dummySetupPy} setup.py
+ cp -nv ${dummyManifest} MANIFEST.in
+ rm pyproject.toml
+ '';
+
+ dependencies = with python3Packages; [
+ wxpython
+ jsonschema
+ kicad-small.base
+ ];
+
+ doCheck = false;
+}
diff --git a/hw/clef/nix/schematic.nix b/hw/clef/nix/schematic.nix
new file mode 100644
index 0000000..e931dd4
--- /dev/null
+++ b/hw/clef/nix/schematic.nix
@@ -0,0 +1,54 @@
+{
+ kicad,
+ runCommand,
+
+ nix-filter,
+ lib,
+
+ src,
+ sch_path,
+
+ schName ? (lib.removeSuffix ".kicad_sch" (builtins.baseNameOf sch_path)),
+}: let
+ sharePath = "share/npry/clef/schematic";
+
+in runCommand "${schName}.schematic" {
+ nativeBuildInputs = [
+ kicad
+ ];
+
+ src = nix-filter {
+ root = src;
+
+ include = [
+ (nix-filter.matchExt "kicad_sch")
+ (nix-filter.matchExt "kicad_pro")
+ (nix-filter.matchExt "kicad_wks")
+
+ (_args: path: type: type == "directory")
+ ];
+ };
+} ''
+ set -e
+ export HOME=$(mktemp -d)
+
+ echo "schematic: '${schName}'" >&2
+
+ mkdir -p "$out/${sharePath}/svg"
+ cd "$src"
+
+ kicad-cli sch export pdf -o "$out/${sharePath}/schematic.pdf" $src/${sch_path}
+ kicad-cli sch export svg -n -o "$out/${sharePath}/svg" $src/${sch_path}
+
+ cd "$out/${sharePath}/svg"
+
+ # normalize
+ for f in *.svg; do
+ if [ "$f" = "${schName}.svg" ]; then
+ mv -nv "$f" "root.svg"
+ continue
+ fi
+
+ mv -nv "$f" "''${f#${schName}-}"
+ done
+''
diff --git a/hw/clef/nix/svg.nix b/hw/clef/nix/svg.nix
new file mode 100644
index 0000000..c93ba87
--- /dev/null
+++ b/hw/clef/nix/svg.nix
@@ -0,0 +1,92 @@
+{
+ runCommand,
+ kicad,
+ inkscape,
+
+ nix-filter,
+ lib,
+
+ pcb_path,
+ src,
+
+ withSilk ? true,
+ withEdgeCuts ? true,
+ withMirrors ? true,
+ nLayer ? 2,
+
+ boardName ? (lib.removeSuffix ".kicad_pcb" (builtins.baseNameOf pcb_path)),
+}: let
+ sharePath = "share/npry/clef/svg";
+
+in runCommand "${boardName}.svg" {
+ nativeBuildInputs = [
+ kicad
+ inkscape
+ ];
+
+ src = nix-filter {
+ root = src;
+
+ include = [
+ (nix-filter.matchExt "kicad_pcb")
+ ];
+ };
+
+ nInnerLayer = if nLayer < 2 then 0 else nLayer - 2;
+
+ allowedRequisites = [];
+} ''
+ set -e
+
+ export HOME=$(mktemp -d)
+
+ echo "board: '${boardName}'" >&2
+
+ mkdir -p $out/${sharePath}
+ cd "$out/${sharePath}"
+
+ mksvg() {
+ local infile=$1
+ local layers=$2
+ local outfile=$3
+
+ kicad-cli pcb export svg \
+ "$infile" \
+ -l "$layers" \
+ -o "$outfile.svg" \
+ --page-size-mode 2 \
+ --exclude-drawing-sheet
+
+ inkscape --actions 'select-all;fit-canvas-to-selection' \
+ -o "$outfile.trim.svg" \
+ "$outfile.svg"
+
+ ${if withMirrors then ''
+ kicad-cli pcb export svg \
+ "$infile" \
+ -m \
+ -l "$layers" \
+ -o "$outfile.mirror.svg" \
+ --page-size-mode 2 \
+ --exclude-drawing-sheet
+
+ inkscape --actions 'select-all;fit-canvas-to-selection' \
+ -o "$outfile.mirror.trim.svg" \
+ "$outfile.mirror.svg"
+ '' else ""}
+ }
+
+ mksvg "$src/${pcb_path}" \
+ "F.Cu,${if withSilk then "F.Silkscreen," else ""}${if withEdgeCuts then "Edge.Cuts," else ""}" \
+ front
+
+ mksvg "$src/${pcb_path}" \
+ "B.Cu,${if withSilk then "B.Silkscreen," else ""}${if withEdgeCuts then "Edge.Cuts," else ""}" \
+ back
+
+ for i in $(seq 1 $nInnerLayer); do
+ mksvg "$src/${pcb_path}" \
+ "In$i.Cu,${if withEdgeCuts then "Edge.Cuts," else ""}" \
+ "in$i"
+ done
+''
diff --git a/hw/clef/overlays.nix b/hw/clef/overlays.nix
new file mode 100644
index 0000000..7e3a00e
--- /dev/null
+++ b/hw/clef/overlays.nix
@@ -0,0 +1,49 @@
+{
+ inputs,
+}: {
+ kicad = final: prev: {
+ opencascade-occt_7_6 = prev.opencascade-occt_7_6.overrideAttrs (finalAttrs: prevAttrs: {
+ buildInputs = (prevAttrs.buildInputs or []) ++ [
+ prev.rapidjson
+ ];
+
+ cmakeFlags = (prevAttrs.cmakeFlags or []) ++ [
+ "-DUSE_RAPIDJSON=1"
+ ];
+ });
+
+ kicad = prev.kicad.override {
+ with3d = true;
+ withI18n = false;
+
+ addons = with prev.kicadAddons; [
+ kikit
+ kikit-library
+ ];
+ };
+
+ kikit = let
+ version = "1.6.0";
+
+ in prev.kikit.overridePythonAttrs {
+ inherit version;
+
+ src = final.fetchFromGitHub {
+ owner = "yaqwsx";
+ repo = "KiKit";
+ rev = "refs/tags/v${version}";
+ hash = "sha256-r8LQcy3I6hmcrU/6HfPAYJd+cEZdhad6DUldC9HvXZU=";
+ };
+
+ doCheck = false;
+ };
+ };
+
+ cq = (final: prev: {
+ inherit (inputs.cq.packages.${prev.system}) cadquery;
+ });
+
+ nix-filter = (final: prev: {
+ nix-filter = inputs.nix-filter.lib;
+ });
+}
diff --git a/hw/clef/sheet/personal.kicad_wks b/hw/clef/sheet/personal.kicad_wks
new file mode 100644
index 0000000..35150ca
--- /dev/null
+++ b/hw/clef/sheet/personal.kicad_wks
@@ -0,0 +1,139 @@
+(kicad_wks
+ (version 20231118)
+ (generator "pl_editor")
+ (generator_version "8.0")
+ (setup
+ (textsize 1.5 1.5)
+ (linewidth 0.15)
+ (textlinewidth 0.15)
+ (left_margin 10)
+ (right_margin 10)
+ (top_margin 10)
+ (bottom_margin 10)
+ )
+ (rect
+ (name "")
+ (start 80.489 15.7522)
+ (end 1.989 2.0002)
+ (comment "rect around the title block")
+ )
+ (rect
+ (name "")
+ (start 0 0 ltcorner)
+ (end 0 0)
+ (repeat 2)
+ (incrx 2)
+ (incry 2)
+ )
+ (line
+ (name "")
+ (start 50 2 ltcorner)
+ (end 50 0 ltcorner)
+ (repeat 30)
+ (incrx 50)
+ )
+ (tbtext "1"
+ (name "")
+ (pos 25 1 ltcorner)
+ (font
+ (size 1.3 1.3)
+ )
+ (repeat 100)
+ (incrx 50)
+ )
+ (line
+ (name "")
+ (start 50 2 lbcorner)
+ (end 50 0 lbcorner)
+ (repeat 30)
+ (incrx 50)
+ )
+ (tbtext "1"
+ (name "")
+ (pos 25 1 lbcorner)
+ (font
+ (size 1.3 1.3)
+ )
+ (repeat 100)
+ (incrx 50)
+ )
+ (line
+ (name "")
+ (start 0 50 ltcorner)
+ (end 2 50 ltcorner)
+ (repeat 30)
+ (incry 50)
+ )
+ (tbtext "A"
+ (name "")
+ (pos 1 25 ltcorner)
+ (font
+ (size 1.3 1.3)
+ )
+ (justify center)
+ (repeat 100)
+ (incry 50)
+ )
+ (line
+ (name "")
+ (start 0 50 rtcorner)
+ (end 2 50 rtcorner)
+ (repeat 30)
+ (incry 50)
+ )
+ (tbtext "A"
+ (name "")
+ (pos 1 25 rtcorner)
+ (font
+ (size 1.3 1.3)
+ )
+ (justify center)
+ (repeat 100)
+ (incry 50)
+ )
+ (tbtext "${ISSUE_DATE}"
+ (name "")
+ (pos 2.95 9.5002)
+ (justify right)
+ )
+ (tbtext "${REVISION}"
+ (name "")
+ (pos 2.75 4.7502)
+ (font bold)
+ (justify right)
+ )
+ (tbtext "${#}/${##}"
+ (name "")
+ (pos 2.95 13.2502)
+ (justify right)
+ (comment "Sheet id")
+ )
+ (line
+ (name "")
+ (start 80.489 7.2522)
+ (end 2 7.2502)
+ )
+ (tbtext "${TITLE}"
+ (name "")
+ (pos 78.95 4.7502)
+ (font
+ (size 2 2) bold italic)
+ )
+ (tbtext "${COMPANY}"
+ (name "")
+ (pos 79.25 9.7502)
+ (font italic)
+ (comment "Company name")
+ )
+ (tbtext "${COMMENT1}"
+ (name "")
+ (pos 79.25 13.25)
+ (font bold)
+ (comment "Comment 0")
+ )
+ (line
+ (name "")
+ (start 20.489 7.2522)
+ (end 20.489 15.7522)
+ )
+) \ No newline at end of file
diff --git a/hw/clef/sheet/personal_noborder.kicad_wks b/hw/clef/sheet/personal_noborder.kicad_wks
new file mode 100644
index 0000000..f51fdbf
--- /dev/null
+++ b/hw/clef/sheet/personal_noborder.kicad_wks
@@ -0,0 +1,65 @@
+(kicad_wks
+ (version 20231118)
+ (generator "pl_editor")
+ (generator_version "8.0")
+ (setup
+ (textsize 1.5 1.5)
+ (linewidth 0.15)
+ (textlinewidth 0.15)
+ (left_margin 10)
+ (right_margin 10)
+ (top_margin 10)
+ (bottom_margin 10)
+ )
+ (rect
+ (name "")
+ (start 80.489 15.7522)
+ (end 1.989 2.0002)
+ (comment "rect around the title block")
+ )
+ (tbtext "${ISSUE_DATE}"
+ (name "")
+ (pos 2.95 9.5002)
+ (justify right)
+ )
+ (tbtext "${REVISION}"
+ (name "")
+ (pos 2.75 4.7502)
+ (font bold)
+ (justify right)
+ )
+ (tbtext "${#}/${##}"
+ (name "")
+ (pos 2.95 13.2502)
+ (justify right)
+ (comment "Sheet id")
+ )
+ (line
+ (name "")
+ (start 80.489 7.2522)
+ (end 2 7.2502)
+ )
+ (tbtext "${TITLE}"
+ (name "")
+ (pos 78.95 4.7502)
+ (font
+ (size 2 2) bold italic)
+ )
+ (tbtext "${COMPANY}"
+ (name "")
+ (pos 79.25 9.7502)
+ (font italic)
+ (comment "Company name")
+ )
+ (tbtext "${COMMENT1}"
+ (name "")
+ (pos 79.25 13.25)
+ (font bold)
+ (comment "Comment 0")
+ )
+ (line
+ (name "")
+ (start 20.489 7.2522)
+ (end 20.489 15.7522)
+ )
+)
diff --git a/hw/clef/sheet/resenv.kicad_wks b/hw/clef/sheet/resenv.kicad_wks
new file mode 100644
index 0000000..70041a9
--- /dev/null
+++ b/hw/clef/sheet/resenv.kicad_wks
@@ -0,0 +1,307 @@
+(kicad_wks
+ (version 20231118)
+ (generator "pl_editor")
+ (generator_version "8.0")
+ (setup
+ (textsize 1.5 1.5)
+ (linewidth 0.15)
+ (textlinewidth 0.15)
+ (left_margin 10)
+ (right_margin 10)
+ (top_margin 10)
+ (bottom_margin 10)
+ )
+ (rect
+ (name "")
+ (start 80.489 15.7522)
+ (end 1.989 2.0002)
+ (comment "rect around the title block")
+ )
+ (rect
+ (name "")
+ (start 0 0 ltcorner)
+ (end 0 0)
+ (repeat 2)
+ (incrx 2)
+ (incry 2)
+ )
+ (line
+ (name "")
+ (start 50 2 ltcorner)
+ (end 50 0 ltcorner)
+ (repeat 30)
+ (incrx 50)
+ )
+ (tbtext "1"
+ (name "")
+ (pos 25 1 ltcorner)
+ (font
+ (size 1.3 1.3)
+ )
+ (repeat 100)
+ (incrx 50)
+ )
+ (line
+ (name "")
+ (start 50 2 lbcorner)
+ (end 50 0 lbcorner)
+ (repeat 30)
+ (incrx 50)
+ )
+ (tbtext "1"
+ (name "")
+ (pos 25 1 lbcorner)
+ (font
+ (size 1.3 1.3)
+ )
+ (repeat 100)
+ (incrx 50)
+ )
+ (line
+ (name "")
+ (start 0 50 ltcorner)
+ (end 2 50 ltcorner)
+ (repeat 30)
+ (incry 50)
+ )
+ (tbtext "A"
+ (name "")
+ (pos 1 25 ltcorner)
+ (font
+ (size 1.3 1.3)
+ )
+ (justify center)
+ (repeat 100)
+ (incry 50)
+ )
+ (line
+ (name "")
+ (start 0 50 rtcorner)
+ (end 2 50 rtcorner)
+ (repeat 30)
+ (incry 50)
+ )
+ (tbtext "A"
+ (name "")
+ (pos 1 25 rtcorner)
+ (font
+ (size 1.3 1.3)
+ )
+ (justify center)
+ (repeat 100)
+ (incry 50)
+ )
+ (tbtext "${ISSUE_DATE}"
+ (name "")
+ (pos 2.95 9.5002)
+ (justify right)
+ )
+ (tbtext "${REVISION}"
+ (name "")
+ (pos 2.75 4.7502)
+ (font bold)
+ (justify right)
+ )
+ (tbtext "${#}/${##}"
+ (name "")
+ (pos 2.95 13.2502)
+ (justify right)
+ (comment "Sheet id")
+ )
+ (line
+ (name "")
+ (start 80.489 7.2522)
+ (end 2 7.2502)
+ )
+ (tbtext "${TITLE}"
+ (name "")
+ (pos 78.95 4.7502)
+ (font
+ (size 2 2) bold italic)
+ )
+ (tbtext "${COMPANY}"
+ (name "")
+ (pos 79.25 9.7502)
+ (font italic)
+ (comment "Company name")
+ )
+ (tbtext "${COMMENT1}"
+ (name "")
+ (pos 79.25 13.25)
+ (font bold)
+ (comment "Comment 0")
+ )
+ (line
+ (name "")
+ (start 20.489 7.2522)
+ (end 20.489 15.7522)
+ )
+ (bitmap
+ (name "")
+ (pos 77.889 20.0022)
+ (scale 0.05)
+ (data "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"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "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"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "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"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiI16AABwX6/Hc9YbAABgAz+RDgBY6V0PAACADRzurgAAAAAQE+kAAAAA"
+ "ICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAA"
+ "ICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAA"
+ "ICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAA"
+ "ICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAA"
+ "ICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAA"
+ "ICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdMjjCyYAAAOiSURB"
+ "VAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAIPYHHMUmdJRzrsUAAAAASUVORK5CYII="
+ )
+ )
+) \ No newline at end of file
diff --git a/hw/clef/sheet/resenv_noborder.kicad_wks b/hw/clef/sheet/resenv_noborder.kicad_wks
new file mode 100644
index 0000000..646a2ac
--- /dev/null
+++ b/hw/clef/sheet/resenv_noborder.kicad_wks
@@ -0,0 +1,233 @@
+(kicad_wks
+ (version 20231118)
+ (generator "pl_editor")
+ (generator_version "8.0")
+ (setup
+ (textsize 1.5 1.5)
+ (linewidth 0.15)
+ (textlinewidth 0.15)
+ (left_margin 10)
+ (right_margin 10)
+ (top_margin 10)
+ (bottom_margin 10)
+ )
+ (rect
+ (name "")
+ (start 80.489 15.7522)
+ (end 1.989 2.0002)
+ (comment "rect around the title block")
+ )
+ (tbtext "${ISSUE_DATE}"
+ (name "")
+ (pos 2.95 9.5002)
+ (justify right)
+ )
+ (tbtext "${REVISION}"
+ (name "")
+ (pos 2.75 4.7502)
+ (font bold)
+ (justify right)
+ )
+ (tbtext "${#}/${##}"
+ (name "")
+ (pos 2.95 13.2502)
+ (justify right)
+ (comment "Sheet id")
+ )
+ (line
+ (name "")
+ (start 80.489 7.2522)
+ (end 2 7.2502)
+ )
+ (tbtext "${TITLE}"
+ (name "")
+ (pos 78.95 4.7502)
+ (font
+ (size 2 2) bold italic)
+ )
+ (tbtext "${COMPANY}"
+ (name "")
+ (pos 79.25 9.7502)
+ (font italic)
+ (comment "Company name")
+ )
+ (tbtext "${COMMENT1}"
+ (name "")
+ (pos 79.25 13.25)
+ (font bold)
+ (comment "Comment 0")
+ )
+ (line
+ (name "")
+ (start 20.489 7.2522)
+ (end 20.489 15.7522)
+ )
+ (bitmap
+ (name "")
+ (pos 77.889 20.0022)
+ (scale 0.05)
+ (data "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"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "AEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAAICbSAQAA"
+ "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"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "AAAAEBPpAAAAACAm0gEAAABATKQDAAAAgJhIBwAAAAAxkQ4AAAAAYiIdAAAAAMREOgAAAACIiXQA"
+ "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"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiIl0AAAAABAT6QAAAAAgJtIBAAAAQEykAwAAAICYSAcAAAAAMZEOAAAA"
+ "AGIiHQAAAADERDoAAAAAiI16AABwX6/Hc9YbAABgAz+RDgBY6V0PAACADRzurgAAAAAQE+kAAAAA"
+ "ICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAA"
+ "ICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAA"
+ "ICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAA"
+ "ICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAA"
+ "ICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdAAAAAAQE+kAAAAA"
+ "ICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJdMjjCyYAAAOiSURB"
+ "VAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAICbSAQAAAEBMpAMAAACAmEgHAAAAADGRDgAAAABiIh0AAAAAxEQ6AAAAAIiJ"
+ "dAAAAAAQE+kAAAAAIPYHHMUmdJRzrsUAAAAASUVORK5CYII="
+ )
+ )
+)