├── .gitignore ├── CNAME ├── Gulpfile.coffee ├── LICENSE.md ├── README.md ├── bower.json ├── package.json ├── samples ├── clockblock-hub-B_Cu.gbl ├── clockblock-hub-B_Mask.gbs ├── clockblock-hub-B_SilkS.gbo ├── clockblock-hub-Edge_Cuts.gbr ├── clockblock-hub-F_Cu.gtl ├── clockblock-hub-F_Mask.gts ├── clockblock-hub-F_Paste.gtp ├── clockblock-hub-F_SilkS.gto ├── clockblock-hub-NPTH.drl └── clockblock-hub.drl ├── src ├── build-board-outline.coffee ├── build-board.coffee ├── collections │ ├── boards.coffee │ ├── layers.coffee │ └── renders.coffee ├── color-options.coffee ├── github-api-url.coffee ├── identify-layer.coffee ├── index.coffee ├── layer-options.coffee ├── models │ ├── board.coffee │ ├── layer.coffee │ └── render.coffee ├── routers │ └── router.coffee ├── views │ ├── app-view.coffee │ ├── board-view.coffee │ ├── color-picker.coffee │ ├── deprecated-view.coffee │ ├── filelist-item.coffee │ ├── layer-view.coffee │ ├── modal-view.coffee │ ├── render-view.coffee │ └── unsupported-view.coffee └── workers │ ├── board-worker.coffee │ ├── btoa-worker.coffee │ └── gerber-worker.coffee ├── styles └── index.styl └── templates ├── board-layer-template.jade ├── color-picker-template.jade ├── deprecated-template.jade ├── filelist-item-template.jade ├── index.jade ├── modal-template.jade └── unsupported-template.jade /.gitignore: -------------------------------------------------------------------------------- 1 | # ignore npm and bower doing their thing 2 | node_modules 3 | bower_components 4 | 5 | # we don't need the generated app files 6 | .publish 7 | public 8 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | svgerber.cousins.io 2 | -------------------------------------------------------------------------------- /Gulpfile.coffee: -------------------------------------------------------------------------------- 1 | # gulpfile 2 | # front end deps 3 | jeet = require 'jeet' 4 | rupture = require 'rupture' 5 | # dependencies 6 | browserify = require 'browserify' 7 | watchify = require 'watchify' 8 | source = require 'vinyl-source-stream' 9 | path = require 'path' 10 | del = require 'del' 11 | # gulp and plugins 12 | gulp = require 'gulp' 13 | gutil = require 'gulp-util' 14 | streamify = require 'gulp-streamify' 15 | stylus = require 'gulp-stylus' 16 | prefix = require 'gulp-autoprefixer' 17 | minifycss = require 'gulp-minify-css' 18 | jade = require 'gulp-jade' 19 | uglify = require 'gulp-uglify' 20 | deploy = require 'gulp-gh-pages' 21 | ignore = require 'gulp-ignore' 22 | concat = require 'gulp-concat' 23 | rename = require 'gulp-rename' 24 | webserver = require 'gulp-webserver' 25 | 26 | # deploy location 27 | DEPLOY = './public' 28 | 29 | # samples location 30 | SAMPLES = './samples' 31 | 32 | # app files 33 | SCRIPT = './src/index.coffee' 34 | TEMPLATE = './templates/index.jade' 35 | STYLE = './styles/index.styl' 36 | 37 | # vendor files 38 | VENDOR_JS = [ 39 | './node_modules/jquery/dist/jquery.min.js' 40 | './node_modules/lodash/index.js' 41 | './node_modules/backbone/backbone-min.js' 42 | ] 43 | VENDOR_CSS = [ 44 | './node_modules/octicons/octicons/octicons.css' 45 | ] 46 | VENDOR_ICON = [ 47 | './node_modules/octicons/octicons/octicons.eot' 48 | './node_modules/octicons/octicons/octicons.ttf' 49 | './node_modules/octicons/octicons/octicons.woff' 50 | './node_modules/octicons/octicons/octicons.svg' 51 | ] 52 | 53 | # files to deploy 54 | DEPLOY_FILES = [ 55 | "#{DEPLOY}/*" 56 | 'CNAME' 57 | ] 58 | 59 | # arguments (checks for production build) 60 | argv = require('minimist') process.argv.slice(2), { 61 | default: { p: false } 62 | alias: { p: 'production' } 63 | } 64 | 65 | # bundle vendor files with concat if necessary and copy them to deploy folder 66 | gulp.task 'vendorCSS', -> 67 | gulp.src VENDOR_CSS 68 | .pipe concat 'vendor.css' 69 | .pipe gulp.dest DEPLOY 70 | gulp.task 'vendorJS', -> 71 | gulp.src VENDOR_JS 72 | .pipe concat 'vendor.js' 73 | .pipe gulp.dest DEPLOY 74 | gulp.task 'vendorIcon', -> 75 | gulp.src VENDOR_ICON 76 | .pipe gulp.dest DEPLOY 77 | gulp.task 'vendor', [ 'vendorCSS', 'vendorJS', 'vendorIcon' ] 78 | 79 | # copy samples folder to the deploy folder 80 | gulp.task 'samples', -> 81 | gulp.src "#{SAMPLES}/*" 82 | .pipe gulp.dest DEPLOY 83 | 84 | # clean out the deploy folder 85 | gulp.task 'clean', (done) -> 86 | del "#{DEPLOY}/*", done 87 | 88 | # compile stylus 89 | gulp.task 'style', -> 90 | gulp.src STYLE 91 | .pipe stylus( { use: [ jeet(), rupture() ] } ).on 'error', gutil.log 92 | .pipe prefix '> 1%', 'last 3 versions', 'Firefox ESR', 'Opera 12.1' 93 | .pipe if argv.p then minifycss() else gutil.noop() 94 | .pipe rename 'app.css' 95 | .pipe gulp.dest DEPLOY 96 | 97 | # compile jade 98 | gulp.task 'template', -> 99 | gulp.src TEMPLATE 100 | .pipe jade().on 'error', gutil.log 101 | .pipe gulp.dest DEPLOY 102 | 103 | # default task build everything 104 | gulp.task 'build', [ 'vendor', 'samples', 'style', 'template', 'script' ] 105 | 106 | # set watch mode 107 | gulp.task 'watch', -> 108 | global.watching = true 109 | # watch stylus 110 | gulp.watch './styles/*.styl', [ 'style' ] 111 | # watch jade 112 | gulp.watch './templates/*.jade', [ 'template' ] 113 | 114 | # watch files with coffee files with watchify and others with gulp.watch 115 | gulp.task 'script', (done) -> 116 | bundler = browserify { 117 | entries: [ SCRIPT ] 118 | extensions: [ '.coffee' ] 119 | debug: !argv.production 120 | # watchify required options 121 | cache: {}, packageCache: {}, fullPaths: true 122 | } 123 | rebundle = -> 124 | bundler.bundle() 125 | .on 'error', (e) -> 126 | gutil.log 'browserify error', e 127 | .pipe source 'app.js' 128 | .pipe if argv.p then streamify uglify { 129 | preamble: '/* view source at github.com/mcous/svgerber */' 130 | compress: { drop_console: true } 131 | mangle: true 132 | } else gutil.noop() 133 | .pipe gulp.dest DEPLOY 134 | # log when necessary 135 | bundler.on 'log', (msg) -> gutil.log "bundle: #{msg}" 136 | # watch if watching 137 | if global.watching 138 | bundler = watchify bundler 139 | bundler.on 'update', rebundle 140 | # bundle coffee 141 | rebundle() 142 | 143 | # deploy to gh-pages 144 | gulp.task 'deploy', [ 'build' ], -> 145 | gulp.src DEPLOY_FILES 146 | .pipe deploy { 147 | branch: if argv.p then 'gh-pages' else 'test-deploy' 148 | push: argv.p 149 | } 150 | 151 | # dev server is default task 152 | gulp.task 'default', [ 'watch', 'build' ], -> 153 | gulp.src DEPLOY 154 | .pipe webserver { 155 | host: '0.0.0.0' 156 | livereload: true 157 | open: true 158 | } 159 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # svgerber license 2 | Copyright 2014 by Michael Cousins 3 | 4 | ## all code and documentation 5 | Shared under the terms of the [MIT License](http://opensource.org/licenses/MIT). 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining a copy 8 | of this software and associated documentation files (the "Software"), to deal 9 | in the Software without restriction, including without limitation the rights 10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the Software is 12 | furnished to do so, subject to the following conditions: 13 | 14 | The above copyright notice and this permission notice shall be included in 15 | all copies or substantial portions of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | THE SOFTWARE. 24 | 25 | ## everything that isn't code or documentation 26 | Shared under the terms of the [Creative Commons Attribution-ShareAlike 4.0 License](https://creativecommons.org/licenses/by-sa/4.0/). 27 | 28 | # jeet 29 | This site uses [Jeet](http://jeet.gs/). Copyright 2014 by MojoTech, and shared under the terms of the MIT License. 30 | 31 | # jquery 32 | This site uses [jQuery](http://jquery.com/). Copyright 2014 by the jQuery Foundation and other contributors, and shared under the terms of the MIT License. 33 | 34 | # fonts 35 | ## octicons 36 | This project uses [GitHub's Octicons](http://octicons.github.com/). 37 | 38 | (c) 2012-2014 GitHub 39 | 40 | Font License: SIL OFL 1.1 (http://scripts.sil.org/OFL) 41 | Applies to all font files 42 | 43 | ## Karma 44 | This project uses the Karma font, by the [Indian Type Foundry](http://www.indiantypefoundry.com/) 45 | 46 | Font License: SIL OFL 1.1 (http://scripts.sil.org/OFL) 47 | 48 | ## Lato 49 | This project uses the Lato font, by [Łukasz Dziedzic](https://plus.google.com/106163021290874968147/about) 50 | 51 | Font License: SIL OFL 1.1 (http://scripts.sil.org/OFL) 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # svgerber (deprecated!) 2 | 3 | [](https://david-dm.org/mcous/svgerber) 4 | [](https://david-dm.org/mcous/svgerber#info=devDependencies) 5 | 6 | svgerber has been deprecated and is no longer maintained. Please try [tracespace viewer](http://viewer.tracespace.io) for all your web-based Gerber viewing needs. 7 | 8 | ## what? 9 | svgerber is a browser based Gerber/drill file to SVG converter. Everything is converted locally (nothing gets sent to any server) using the [gerber-to-svg](https://github.com/mcous/gerber-to-svg) node package. 10 | 11 | Given at least a top or bottom copper layer, it will render what your board is going to look like. Regardless, it will also render each individual layer separately. 12 | 13 | Right now, it's able to convert most Gerber and drill files I can find. If you try it out with a file and get errors, let me know in [the issues](https://github.com/mcous/svgerber/issues). 14 | 15 | ## why? 16 | It's a quick and easy way to visualize your board designs. Plus, you can download the SVGs and send them to all your friends. They'll be impressed. 17 | 18 | ## how? 19 | Go to [svgerber.cousins.io](http://svgerber.cousins.io). 20 | 21 | ### local dev server 22 | This project uses [gulp](http://gulpjs.com) to build and serve the app. 23 | 24 | 1. `$ npm install # install dev and app dependencies` 25 | 2. `$ gulp # start the server / file watcher / live reload server` 26 | 3. Your browser should surf to `http://localhost:8000` automatically 27 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svgerber.cousins.io", 3 | "dependencies": { 4 | "octicons": "*" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svgerber.cousins.io", 3 | "version": "0.2.1", 4 | "description": "Client-side Gerber file to SVG converter", 5 | "repository": { 6 | "type": "git", 7 | "url": "git://github.com/mcous/svgerber.git" 8 | }, 9 | "license": "MIT", 10 | "browserify": { 11 | "transform": [ 12 | "coffeeify", 13 | "workerify" 14 | ] 15 | }, 16 | "devDependencies": { 17 | "browserify": "10.2.1", 18 | "coffee-script": "1.9.2", 19 | "coffeeify": "1.1.0", 20 | "del": "1.2.0", 21 | "gulp": "3.8.11", 22 | "gulp-autoprefixer": "2.3.0", 23 | "gulp-concat": "2.5.2", 24 | "gulp-gh-pages": "0.5.1", 25 | "gulp-ignore": "1.2.1", 26 | "gulp-jade": "1.0.1", 27 | "gulp-livereload": "3.8.0", 28 | "gulp-minify-css": "1.1.1", 29 | "gulp-rename": "1.2.2", 30 | "gulp-streamify": "0.0.5", 31 | "gulp-stylus": "2.0.2", 32 | "gulp-uglify": "1.2.0", 33 | "gulp-util": "3.0.4", 34 | "gulp-webserver": "0.9.1", 35 | "minimist": "1.1.1", 36 | "vinyl-source-stream": "1.1.0", 37 | "watchify": "3.2.1", 38 | "workerify": "0.3.0" 39 | }, 40 | "dependencies": { 41 | "Base64": "0.3.0", 42 | "backbone": "1.2.0", 43 | "gerber-to-svg": "0.4.1", 44 | "jeet": "6.1.2", 45 | "jquery": "2.1.4", 46 | "lodash": "3.9.3", 47 | "octicons": "2.2.0", 48 | "rupture": "0.6.1" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /samples/clockblock-hub-B_Mask.gbs: -------------------------------------------------------------------------------- 1 | G04 (created by PCBNEW (2013-07-07 BZR 4022)-stable) date 11/9/2013 7:35:54 PM* 2 | %MOIN*% 3 | G04 Gerber Fmt 3.4, Leading zero omitted, Abs format* 4 | %FSLAX34Y34*% 5 | G01* 6 | G70* 7 | G90* 8 | G04 APERTURE LIST* 9 | %ADD10C,0.006*% 10 | %ADD11C,0.104425*% 11 | %ADD12C,0.021*% 12 | %ADD13C,0.147732*% 13 | %ADD14R,0.0729291X0.0729291*% 14 | %ADD15C,0.0729291*% 15 | %ADD16C,0.131*% 16 | G04 APERTURE END LIST* 17 | G54D10* 18 | G54D11* 19 | X40250Y6750D03* 20 | X31750Y6750D03* 21 | X40250Y35250D03* 22 | X31750Y35250D03* 23 | G54D12* 24 | X30500Y21200D03* 25 | X30500Y20800D03* 26 | G54D13* 27 | X6250Y29750D03* 28 | X23750Y12250D03* 29 | X6250Y12250D03* 30 | X23750Y29750D03* 31 | G54D14* 32 | X9500Y17000D03* 33 | G54D15* 34 | X10500Y17000D03* 35 | X9500Y16000D03* 36 | X10500Y16000D03* 37 | X9500Y15000D03* 38 | X10500Y15000D03* 39 | G54D12* 40 | X14750Y5500D03* 41 | X15250Y5500D03* 42 | X31250Y5500D03* 43 | X31750Y5500D03* 44 | X40250Y5500D03* 45 | X40750Y5500D03* 46 | X40750Y36500D03* 47 | X40250Y36500D03* 48 | X31250Y36500D03* 49 | X31750Y36500D03* 50 | X14750Y36500D03* 51 | X15250Y36500D03* 52 | G54D16* 53 | X2500Y39500D03* 54 | X38500Y39500D03* 55 | X38500Y2500D03* 56 | X2500Y2500D03* 57 | M02* 58 | -------------------------------------------------------------------------------- /samples/clockblock-hub-B_SilkS.gbo: -------------------------------------------------------------------------------- 1 | G04 (created by PCBNEW (2013-07-07 BZR 4022)-stable) date 11/9/2013 7:35:54 PM* 2 | %MOIN*% 3 | G04 Gerber Fmt 3.4, Leading zero omitted, Abs format* 4 | %FSLAX34Y34*% 5 | G01* 6 | G70* 7 | G90* 8 | G04 APERTURE LIST* 9 | %ADD10C,0.006*% 10 | %ADD11C,0.065*% 11 | %ADD12C,0.016*% 12 | %ADD13C,0.008*% 13 | %ADD14C,0.02*% 14 | %ADD15C,0.104425*% 15 | %ADD16C,0.021*% 16 | %ADD17C,0.147732*% 17 | %ADD18R,0.0729291X0.0729291*% 18 | %ADD19C,0.0729291*% 19 | %ADD20C,0.131*% 20 | G04 APERTURE END LIST* 21 | G54D10* 22 | G54D11* 23 | X25755Y19839D02* 24 | X26065Y19684D01* 25 | X26684Y19684D01* 26 | X26994Y19839D01* 27 | X27148Y19994D01* 28 | X27303Y20303D01* 29 | X27303Y21232D01* 30 | X27148Y21541D01* 31 | X26994Y21696D01* 32 | X26684Y21851D01* 33 | X26065Y21851D01* 34 | X25755Y21696D01* 35 | X23898Y19684D02* 36 | X24208Y19839D01* 37 | X24363Y20148D01* 38 | X24363Y22934D01* 39 | X22196Y19684D02* 40 | X22505Y19839D01* 41 | X22660Y19994D01* 42 | X22815Y20303D01* 43 | X22815Y21232D01* 44 | X22660Y21541D01* 45 | X22505Y21696D01* 46 | X22196Y21851D01* 47 | X21732Y21851D01* 48 | X21422Y21696D01* 49 | X21267Y21541D01* 50 | X21113Y21232D01* 51 | X21113Y20303D01* 52 | X21267Y19994D01* 53 | X21422Y19839D01* 54 | X21732Y19684D01* 55 | X22196Y19684D01* 56 | X18327Y19839D02* 57 | X18636Y19684D01* 58 | X19255Y19684D01* 59 | X19565Y19839D01* 60 | X19720Y19994D01* 61 | X19875Y20303D01* 62 | X19875Y21232D01* 63 | X19720Y21541D01* 64 | X19565Y21696D01* 65 | X19255Y21851D01* 66 | X18636Y21851D01* 67 | X18327Y21696D01* 68 | X16934Y19684D02* 69 | X16934Y22934D01* 70 | X16625Y20922D02* 71 | X15696Y19684D01* 72 | X15696Y21851D02* 73 | X16934Y20613D01* 74 | X14303Y19684D02* 75 | X14303Y22934D01* 76 | X14303Y21696D02* 77 | X13994Y21851D01* 78 | X13375Y21851D01* 79 | X13065Y21696D01* 80 | X12910Y21541D01* 81 | X12755Y21232D01* 82 | X12755Y20303D01* 83 | X12910Y19994D01* 84 | X13065Y19839D01* 85 | X13375Y19684D01* 86 | X13994Y19684D01* 87 | X14303Y19839D01* 88 | X10898Y19684D02* 89 | X11208Y19839D01* 90 | X11363Y20148D01* 91 | X11363Y22934D01* 92 | X9196Y19684D02* 93 | X9505Y19839D01* 94 | X9660Y19994D01* 95 | X9815Y20303D01* 96 | X9815Y21232D01* 97 | X9660Y21541D01* 98 | X9505Y21696D01* 99 | X9196Y21851D01* 100 | X8732Y21851D01* 101 | X8422Y21696D01* 102 | X8267Y21541D01* 103 | X8113Y21232D01* 104 | X8113Y20303D01* 105 | X8267Y19994D01* 106 | X8422Y19839D01* 107 | X8732Y19684D01* 108 | X9196Y19684D01* 109 | X5327Y19839D02* 110 | X5636Y19684D01* 111 | X6255Y19684D01* 112 | X6565Y19839D01* 113 | X6720Y19994D01* 114 | X6874Y20303D01* 115 | X6874Y21232D01* 116 | X6720Y21541D01* 117 | X6565Y21696D01* 118 | X6255Y21851D01* 119 | X5636Y21851D01* 120 | X5327Y21696D01* 121 | X3934Y19684D02* 122 | X3934Y22934D01* 123 | X3624Y20922D02* 124 | X2696Y19684D01* 125 | X2696Y21851D02* 126 | X3934Y20613D01* 127 | G54D12* 128 | X28847Y17371D02* 129 | X28885Y17409D01* 130 | X28961Y17523D01* 131 | X28999Y17600D01* 132 | X29038Y17714D01* 133 | X29076Y17904D01* 134 | X29076Y18057D01* 135 | X29038Y18247D01* 136 | X28999Y18361D01* 137 | X28961Y18438D01* 138 | X28885Y18552D01* 139 | X28847Y18590D01* 140 | X28199Y17676D02* 141 | X28199Y18095D01* 142 | X28238Y18171D01* 143 | X28314Y18209D01* 144 | X28466Y18209D01* 145 | X28542Y18171D01* 146 | X28199Y17714D02* 147 | X28276Y17676D01* 148 | X28466Y17676D01* 149 | X28542Y17714D01* 150 | X28580Y17790D01* 151 | X28580Y17866D01* 152 | X28542Y17942D01* 153 | X28466Y17980D01* 154 | X28276Y17980D01* 155 | X28199Y18019D01* 156 | X27285Y18209D02* 157 | X27133Y17676D01* 158 | X26980Y18057D01* 159 | X26828Y17676D01* 160 | X26676Y18209D01* 161 | X26371Y17676D02* 162 | X26371Y18209D01* 163 | X26371Y18476D02* 164 | X26409Y18438D01* 165 | X26371Y18400D01* 166 | X26333Y18438D01* 167 | X26371Y18476D01* 168 | X26371Y18400D01* 169 | X25876Y17676D02* 170 | X25952Y17714D01* 171 | X25990Y17790D01* 172 | X25990Y18476D01* 173 | X25266Y17714D02* 174 | X25342Y17676D01* 175 | X25495Y17676D01* 176 | X25571Y17714D01* 177 | X25609Y17790D01* 178 | X25609Y18095D01* 179 | X25571Y18171D01* 180 | X25495Y18209D01* 181 | X25342Y18209D01* 182 | X25266Y18171D01* 183 | X25228Y18095D01* 184 | X25228Y18019D01* 185 | X25609Y17942D01* 186 | X24961Y18209D02* 187 | X24771Y17676D01* 188 | X24580Y18209D02* 189 | X24771Y17676D01* 190 | X24847Y17485D01* 191 | X24885Y17447D01* 192 | X24961Y17409D01* 193 | X23323Y17714D02* 194 | X23399Y17676D01* 195 | X23552Y17676D01* 196 | X23628Y17714D01* 197 | X23666Y17752D01* 198 | X23704Y17828D01* 199 | X23704Y18057D01* 200 | X23666Y18133D01* 201 | X23628Y18171D01* 202 | X23552Y18209D01* 203 | X23399Y18209D01* 204 | X23323Y18171D01* 205 | X22866Y17676D02* 206 | X22942Y17714D01* 207 | X22980Y17752D01* 208 | X23019Y17828D01* 209 | X23019Y18057D01* 210 | X22980Y18133D01* 211 | X22942Y18171D01* 212 | X22866Y18209D01* 213 | X22752Y18209D01* 214 | X22676Y18171D01* 215 | X22638Y18133D01* 216 | X22599Y18057D01* 217 | X22599Y17828D01* 218 | X22638Y17752D01* 219 | X22676Y17714D01* 220 | X22752Y17676D01* 221 | X22866Y17676D01* 222 | X21914Y18209D02* 223 | X21914Y17676D01* 224 | X22257Y18209D02* 225 | X22257Y17790D01* 226 | X22219Y17714D01* 227 | X22142Y17676D01* 228 | X22028Y17676D01* 229 | X21952Y17714D01* 230 | X21914Y17752D01* 231 | X21571Y17714D02* 232 | X21495Y17676D01* 233 | X21342Y17676D01* 234 | X21266Y17714D01* 235 | X21228Y17790D01* 236 | X21228Y17828D01* 237 | X21266Y17904D01* 238 | X21342Y17942D01* 239 | X21457Y17942D01* 240 | X21533Y17980D01* 241 | X21571Y18057D01* 242 | X21571Y18095D01* 243 | X21533Y18171D01* 244 | X21457Y18209D01* 245 | X21342Y18209D01* 246 | X21266Y18171D01* 247 | X20885Y17676D02* 248 | X20885Y18209D01* 249 | X20885Y18476D02* 250 | X20923Y18438D01* 251 | X20885Y18400D01* 252 | X20847Y18438D01* 253 | X20885Y18476D01* 254 | X20885Y18400D01* 255 | X20504Y18209D02* 256 | X20504Y17676D01* 257 | X20504Y18133D02* 258 | X20466Y18171D01* 259 | X20390Y18209D01* 260 | X20276Y18209D01* 261 | X20199Y18171D01* 262 | X20161Y18095D01* 263 | X20161Y17676D01* 264 | X19819Y17714D02* 265 | X19742Y17676D01* 266 | X19590Y17676D01* 267 | X19514Y17714D01* 268 | X19476Y17790D01* 269 | X19476Y17828D01* 270 | X19514Y17904D01* 271 | X19590Y17942D01* 272 | X19704Y17942D01* 273 | X19780Y17980D01* 274 | X19819Y18057D01* 275 | X19819Y18095D01* 276 | X19780Y18171D01* 277 | X19704Y18209D01* 278 | X19590Y18209D01* 279 | X19514Y18171D01* 280 | X18523Y17980D02* 281 | X17914Y17980D01* 282 | X18219Y17676D02* 283 | X18219Y18285D01* 284 | X16580Y18209D02* 285 | X16580Y17561D01* 286 | X16619Y17485D01* 287 | X16657Y17447D01* 288 | X16733Y17409D01* 289 | X16847Y17409D01* 290 | X16923Y17447D01* 291 | X16580Y17714D02* 292 | X16657Y17676D01* 293 | X16809Y17676D01* 294 | X16885Y17714D01* 295 | X16923Y17752D01* 296 | X16961Y17828D01* 297 | X16961Y18057D01* 298 | X16923Y18133D01* 299 | X16885Y18171D01* 300 | X16809Y18209D01* 301 | X16657Y18209D01* 302 | X16580Y18171D01* 303 | X16085Y17676D02* 304 | X16161Y17714D01* 305 | X16199Y17752D01* 306 | X16238Y17828D01* 307 | X16238Y18057D01* 308 | X16199Y18133D01* 309 | X16161Y18171D01* 310 | X16085Y18209D01* 311 | X15971Y18209D01* 312 | X15895Y18171D01* 313 | X15857Y18133D01* 314 | X15819Y18057D01* 315 | X15819Y17828D01* 316 | X15857Y17752D01* 317 | X15895Y17714D01* 318 | X15971Y17676D01* 319 | X16085Y17676D01* 320 | X15171Y17714D02* 321 | X15247Y17676D01* 322 | X15400Y17676D01* 323 | X15476Y17714D01* 324 | X15514Y17790D01* 325 | X15514Y18095D01* 326 | X15476Y18171D01* 327 | X15400Y18209D01* 328 | X15247Y18209D01* 329 | X15171Y18171D01* 330 | X15133Y18095D01* 331 | X15133Y18019D01* 332 | X15514Y17942D01* 333 | X14447Y17676D02* 334 | X14447Y18476D01* 335 | X14447Y17714D02* 336 | X14523Y17676D01* 337 | X14676Y17676D01* 338 | X14752Y17714D01* 339 | X14790Y17752D01* 340 | X14828Y17828D01* 341 | X14828Y18057D01* 342 | X14790Y18133D01* 343 | X14752Y18171D01* 344 | X14676Y18209D01* 345 | X14523Y18209D01* 346 | X14447Y18171D01* 347 | X13761Y17714D02* 348 | X13838Y17676D01* 349 | X13990Y17676D01* 350 | X14066Y17714D01* 351 | X14104Y17790D01* 352 | X14104Y18095D01* 353 | X14066Y18171D01* 354 | X13990Y18209D01* 355 | X13838Y18209D01* 356 | X13761Y18171D01* 357 | X13723Y18095D01* 358 | X13723Y18019D01* 359 | X14104Y17942D01* 360 | X13380Y17676D02* 361 | X13380Y18209D01* 362 | X13380Y18057D02* 363 | X13342Y18133D01* 364 | X13304Y18171D01* 365 | X13228Y18209D01* 366 | X13152Y18209D01* 367 | X13000Y18209D02* 368 | X12695Y18209D01* 369 | X12885Y18476D02* 370 | X12885Y17790D01* 371 | X12847Y17714D01* 372 | X12771Y17676D01* 373 | X12695Y17676D01* 374 | X11857Y17714D02* 375 | X11780Y17676D01* 376 | X11628Y17676D01* 377 | X11552Y17714D01* 378 | X11514Y17790D01* 379 | X11514Y17828D01* 380 | X11552Y17904D01* 381 | X11628Y17942D01* 382 | X11742Y17942D01* 383 | X11819Y17980D01* 384 | X11857Y18057D01* 385 | X11857Y18095D01* 386 | X11819Y18171D01* 387 | X11742Y18209D01* 388 | X11628Y18209D01* 389 | X11552Y18171D01* 390 | X11285Y18209D02* 391 | X10980Y18209D01* 392 | X11171Y18476D02* 393 | X11171Y17790D01* 394 | X11133Y17714D01* 395 | X11057Y17676D01* 396 | X10980Y17676D01* 397 | X10371Y18209D02* 398 | X10371Y17676D01* 399 | X10714Y18209D02* 400 | X10714Y17790D01* 401 | X10676Y17714D01* 402 | X10600Y17676D01* 403 | X10485Y17676D01* 404 | X10409Y17714D01* 405 | X10371Y17752D01* 406 | X9647Y17676D02* 407 | X9647Y18476D01* 408 | X9647Y17714D02* 409 | X9723Y17676D01* 410 | X9876Y17676D01* 411 | X9952Y17714D01* 412 | X9990Y17752D01* 413 | X10028Y17828D01* 414 | X10028Y18057D01* 415 | X9990Y18133D01* 416 | X9952Y18171D01* 417 | X9876Y18209D01* 418 | X9723Y18209D01* 419 | X9647Y18171D01* 420 | X9266Y17676D02* 421 | X9266Y18209D01* 422 | X9266Y18476D02* 423 | X9304Y18438D01* 424 | X9266Y18400D01* 425 | X9228Y18438D01* 426 | X9266Y18476D01* 427 | X9266Y18400D01* 428 | X8771Y17676D02* 429 | X8847Y17714D01* 430 | X8885Y17752D01* 431 | X8923Y17828D01* 432 | X8923Y18057D01* 433 | X8885Y18133D01* 434 | X8847Y18171D01* 435 | X8771Y18209D01* 436 | X8657Y18209D01* 437 | X8580Y18171D01* 438 | X8542Y18133D01* 439 | X8504Y18057D01* 440 | X8504Y17828D01* 441 | X8542Y17752D01* 442 | X8580Y17714D01* 443 | X8657Y17676D01* 444 | X8771Y17676D01* 445 | X8200Y17714D02* 446 | X8123Y17676D01* 447 | X7971Y17676D01* 448 | X7895Y17714D01* 449 | X7857Y17790D01* 450 | X7857Y17828D01* 451 | X7895Y17904D01* 452 | X7971Y17942D01* 453 | X8085Y17942D01* 454 | X8161Y17980D01* 455 | X8200Y18057D01* 456 | X8200Y18095D01* 457 | X8161Y18171D01* 458 | X8085Y18209D01* 459 | X7971Y18209D01* 460 | X7895Y18171D01* 461 | X6561Y17676D02* 462 | X6561Y18095D01* 463 | X6600Y18171D01* 464 | X6676Y18209D01* 465 | X6828Y18209D01* 466 | X6904Y18171D01* 467 | X6561Y17714D02* 468 | X6638Y17676D01* 469 | X6828Y17676D01* 470 | X6904Y17714D01* 471 | X6942Y17790D01* 472 | X6942Y17866D01* 473 | X6904Y17942D01* 474 | X6828Y17980D01* 475 | X6638Y17980D01* 476 | X6561Y18019D01* 477 | X5838Y17676D02* 478 | X5838Y18476D01* 479 | X5838Y17714D02* 480 | X5914Y17676D01* 481 | X6066Y17676D01* 482 | X6142Y17714D01* 483 | X6180Y17752D01* 484 | X6219Y17828D01* 485 | X6219Y18057D01* 486 | X6180Y18133D01* 487 | X6142Y18171D01* 488 | X6066Y18209D01* 489 | X5914Y18209D01* 490 | X5838Y18171D01* 491 | X5533Y18209D02* 492 | X5342Y17676D01* 493 | X5152Y18209D01* 494 | X4542Y17714D02* 495 | X4619Y17676D01* 496 | X4771Y17676D01* 497 | X4847Y17714D01* 498 | X4885Y17790D01* 499 | X4885Y18095D01* 500 | X4847Y18171D01* 501 | X4771Y18209D01* 502 | X4619Y18209D01* 503 | X4542Y18171D01* 504 | X4504Y18095D01* 505 | X4504Y18019D01* 506 | X4885Y17942D01* 507 | X4161Y18209D02* 508 | X4161Y17676D01* 509 | X4161Y18133D02* 510 | X4123Y18171D01* 511 | X4047Y18209D01* 512 | X3933Y18209D01* 513 | X3857Y18171D01* 514 | X3819Y18095D01* 515 | X3819Y17676D01* 516 | X3552Y18209D02* 517 | X3247Y18209D01* 518 | X3438Y18476D02* 519 | X3438Y17790D01* 520 | X3400Y17714D01* 521 | X3323Y17676D01* 522 | X3247Y17676D01* 523 | X2638Y18209D02* 524 | X2638Y17676D01* 525 | X2980Y18209D02* 526 | X2980Y17790D01* 527 | X2942Y17714D01* 528 | X2866Y17676D01* 529 | X2752Y17676D01* 530 | X2676Y17714D01* 531 | X2638Y17752D01* 532 | X2257Y17676D02* 533 | X2257Y18209D01* 534 | X2257Y18057D02* 535 | X2219Y18133D01* 536 | X2180Y18171D01* 537 | X2104Y18209D01* 538 | X2028Y18209D01* 539 | X1457Y17714D02* 540 | X1533Y17676D01* 541 | X1685Y17676D01* 542 | X1761Y17714D01* 543 | X1800Y17790D01* 544 | X1800Y18095D01* 545 | X1761Y18171D01* 546 | X1685Y18209D01* 547 | X1533Y18209D01* 548 | X1457Y18171D01* 549 | X1419Y18095D01* 550 | X1419Y18019D01* 551 | X1800Y17942D01* 552 | X1152Y17371D02* 553 | X1114Y17409D01* 554 | X1038Y17523D01* 555 | X1000Y17600D01* 556 | X961Y17714D01* 557 | X923Y17904D01* 558 | X923Y18057D01* 559 | X961Y18247D01* 560 | X1000Y18361D01* 561 | X1038Y18438D01* 562 | X1114Y18552D01* 563 | X1152Y18590D01* 564 | X20371Y12714D02* 565 | X20447Y12676D01* 566 | X20599Y12676D01* 567 | X20676Y12714D01* 568 | X20714Y12752D01* 569 | X20752Y12828D01* 570 | X20752Y13057D01* 571 | X20714Y13133D01* 572 | X20676Y13171D01* 573 | X20599Y13209D01* 574 | X20447Y13209D01* 575 | X20371Y13171D01* 576 | X19914Y12676D02* 577 | X19990Y12714D01* 578 | X20028Y12790D01* 579 | X20028Y13476D01* 580 | X19495Y12676D02* 581 | X19571Y12714D01* 582 | X19609Y12752D01* 583 | X19647Y12828D01* 584 | X19647Y13057D01* 585 | X19609Y13133D01* 586 | X19571Y13171D01* 587 | X19495Y13209D01* 588 | X19380Y13209D01* 589 | X19304Y13171D01* 590 | X19266Y13133D01* 591 | X19228Y13057D01* 592 | X19228Y12828D01* 593 | X19266Y12752D01* 594 | X19304Y12714D01* 595 | X19380Y12676D01* 596 | X19495Y12676D01* 597 | X18542Y12714D02* 598 | X18619Y12676D01* 599 | X18771Y12676D01* 600 | X18847Y12714D01* 601 | X18885Y12752D01* 602 | X18923Y12828D01* 603 | X18923Y13057D01* 604 | X18885Y13133D01* 605 | X18847Y13171D01* 606 | X18771Y13209D01* 607 | X18619Y13209D01* 608 | X18542Y13171D01* 609 | X18199Y12676D02* 610 | X18199Y13476D01* 611 | X18123Y12980D02* 612 | X17895Y12676D01* 613 | X17895Y13209D02* 614 | X18199Y12904D01* 615 | X17552Y12676D02* 616 | X17552Y13476D01* 617 | X17552Y13171D02* 618 | X17476Y13209D01* 619 | X17323Y13209D01* 620 | X17247Y13171D01* 621 | X17209Y13133D01* 622 | X17171Y13057D01* 623 | X17171Y12828D01* 624 | X17209Y12752D01* 625 | X17247Y12714D01* 626 | X17323Y12676D01* 627 | X17476Y12676D01* 628 | X17552Y12714D01* 629 | X16714Y12676D02* 630 | X16790Y12714D01* 631 | X16828Y12790D01* 632 | X16828Y13476D01* 633 | X16295Y12676D02* 634 | X16371Y12714D01* 635 | X16409Y12752D01* 636 | X16447Y12828D01* 637 | X16447Y13057D01* 638 | X16409Y13133D01* 639 | X16371Y13171D01* 640 | X16295Y13209D01* 641 | X16180Y13209D01* 642 | X16104Y13171D01* 643 | X16066Y13133D01* 644 | X16028Y13057D01* 645 | X16028Y12828D01* 646 | X16066Y12752D01* 647 | X16104Y12714D01* 648 | X16180Y12676D01* 649 | X16295Y12676D01* 650 | X15342Y12714D02* 651 | X15419Y12676D01* 652 | X15571Y12676D01* 653 | X15647Y12714D01* 654 | X15685Y12752D01* 655 | X15723Y12828D01* 656 | X15723Y13057D01* 657 | X15685Y13133D01* 658 | X15647Y13171D01* 659 | X15571Y13209D01* 660 | X15419Y13209D01* 661 | X15342Y13171D01* 662 | X14999Y12676D02* 663 | X14999Y13476D01* 664 | X14923Y12980D02* 665 | X14695Y12676D01* 666 | X14695Y13209D02* 667 | X14999Y12904D01* 668 | X14352Y13209D02* 669 | X14352Y12676D01* 670 | X14352Y13133D02* 671 | X14314Y13171D01* 672 | X14238Y13209D01* 673 | X14123Y13209D01* 674 | X14047Y13171D01* 675 | X14009Y13095D01* 676 | X14009Y12676D01* 677 | X13514Y12676D02* 678 | X13590Y12714D01* 679 | X13628Y12752D01* 680 | X13666Y12828D01* 681 | X13666Y13057D01* 682 | X13628Y13133D01* 683 | X13590Y13171D01* 684 | X13514Y13209D01* 685 | X13400Y13209D01* 686 | X13323Y13171D01* 687 | X13285Y13133D01* 688 | X13247Y13057D01* 689 | X13247Y12828D01* 690 | X13285Y12752D01* 691 | X13323Y12714D01* 692 | X13400Y12676D01* 693 | X13514Y12676D01* 694 | X12790Y12676D02* 695 | X12866Y12714D01* 696 | X12904Y12790D01* 697 | X12904Y13476D01* 698 | X12142Y12676D02* 699 | X12142Y13095D01* 700 | X12180Y13171D01* 701 | X12257Y13209D01* 702 | X12409Y13209D01* 703 | X12485Y13171D01* 704 | X12142Y12714D02* 705 | X12219Y12676D01* 706 | X12409Y12676D01* 707 | X12485Y12714D01* 708 | X12523Y12790D01* 709 | X12523Y12866D01* 710 | X12485Y12942D01* 711 | X12409Y12980D01* 712 | X12219Y12980D01* 713 | X12142Y13019D01* 714 | X11761Y12752D02* 715 | X11723Y12714D01* 716 | X11761Y12676D01* 717 | X11800Y12714D01* 718 | X11761Y12752D01* 719 | X11761Y12676D01* 720 | X11038Y12714D02* 721 | X11114Y12676D01* 722 | X11266Y12676D01* 723 | X11342Y12714D01* 724 | X11380Y12752D01* 725 | X11419Y12828D01* 726 | X11419Y13057D01* 727 | X11380Y13133D01* 728 | X11342Y13171D01* 729 | X11266Y13209D01* 730 | X11114Y13209D01* 731 | X11038Y13171D01* 732 | X10580Y12676D02* 733 | X10657Y12714D01* 734 | X10695Y12752D01* 735 | X10733Y12828D01* 736 | X10733Y13057D01* 737 | X10695Y13133D01* 738 | X10657Y13171D01* 739 | X10580Y13209D01* 740 | X10466Y13209D01* 741 | X10390Y13171D01* 742 | X10352Y13133D01* 743 | X10314Y13057D01* 744 | X10314Y12828D01* 745 | X10352Y12752D01* 746 | X10390Y12714D01* 747 | X10466Y12676D01* 748 | X10580Y12676D01* 749 | X9971Y12676D02* 750 | X9971Y13209D01* 751 | X9971Y13133D02* 752 | X9933Y13171D01* 753 | X9857Y13209D01* 754 | X9742Y13209D01* 755 | X9666Y13171D01* 756 | X9628Y13095D01* 757 | X9628Y12676D01* 758 | X9628Y13095D02* 759 | X9590Y13171D01* 760 | X9514Y13209D01* 761 | X9400Y13209D01* 762 | X9323Y13171D01* 763 | X9285Y13095D01* 764 | X9285Y12676D01* 765 | G54D13* 766 | X18209Y10838D02* 767 | X18247Y10857D01* 768 | X18266Y10876D01* 769 | X18285Y10914D01* 770 | X18285Y11028D01* 771 | X18266Y11066D01* 772 | X18247Y11085D01* 773 | X18209Y11104D01* 774 | X18152Y11104D01* 775 | X18114Y11085D01* 776 | X18095Y11066D01* 777 | X18076Y11028D01* 778 | X18076Y10914D01* 779 | X18095Y10876D01* 780 | X18114Y10857D01* 781 | X18152Y10838D01* 782 | X18209Y10838D01* 783 | X17904Y11104D02* 784 | X17904Y10704D01* 785 | X17904Y11085D02* 786 | X17866Y11104D01* 787 | X17790Y11104D01* 788 | X17752Y11085D01* 789 | X17733Y11066D01* 790 | X17714Y11028D01* 791 | X17714Y10914D01* 792 | X17733Y10876D01* 793 | X17752Y10857D01* 794 | X17790Y10838D01* 795 | X17866Y10838D01* 796 | X17904Y10857D01* 797 | X17390Y10857D02* 798 | X17428Y10838D01* 799 | X17504Y10838D01* 800 | X17542Y10857D01* 801 | X17561Y10895D01* 802 | X17561Y11047D01* 803 | X17542Y11085D01* 804 | X17504Y11104D01* 805 | X17428Y11104D01* 806 | X17390Y11085D01* 807 | X17371Y11047D01* 808 | X17371Y11009D01* 809 | X17561Y10971D01* 810 | X17199Y11104D02* 811 | X17199Y10838D01* 812 | X17199Y11066D02* 813 | X17180Y11085D01* 814 | X17142Y11104D01* 815 | X17085Y11104D01* 816 | X17047Y11085D01* 817 | X17028Y11047D01* 818 | X17028Y10838D01* 819 | X16552Y10857D02* 820 | X16514Y10838D01* 821 | X16438Y10838D01* 822 | X16399Y10857D01* 823 | X16380Y10895D01* 824 | X16380Y10914D01* 825 | X16399Y10952D01* 826 | X16438Y10971D01* 827 | X16495Y10971D01* 828 | X16533Y10990D01* 829 | X16552Y11028D01* 830 | X16552Y11047D01* 831 | X16533Y11085D01* 832 | X16495Y11104D01* 833 | X16438Y11104D01* 834 | X16399Y11085D01* 835 | X16152Y10838D02* 836 | X16190Y10857D01* 837 | X16209Y10876D01* 838 | X16228Y10914D01* 839 | X16228Y11028D01* 840 | X16209Y11066D01* 841 | X16190Y11085D01* 842 | X16152Y11104D01* 843 | X16095Y11104D01* 844 | X16057Y11085D01* 845 | X16038Y11066D01* 846 | X16019Y11028D01* 847 | X16019Y10914D01* 848 | X16038Y10876D01* 849 | X16057Y10857D01* 850 | X16095Y10838D01* 851 | X16152Y10838D01* 852 | X15676Y11104D02* 853 | X15676Y10838D01* 854 | X15847Y11104D02* 855 | X15847Y10895D01* 856 | X15828Y10857D01* 857 | X15790Y10838D01* 858 | X15733Y10838D01* 859 | X15695Y10857D01* 860 | X15676Y10876D01* 861 | X15485Y10838D02* 862 | X15485Y11104D01* 863 | X15485Y11028D02* 864 | X15466Y11066D01* 865 | X15447Y11085D01* 866 | X15409Y11104D01* 867 | X15371Y11104D01* 868 | X15066Y10857D02* 869 | X15104Y10838D01* 870 | X15180Y10838D01* 871 | X15219Y10857D01* 872 | X15238Y10876D01* 873 | X15257Y10914D01* 874 | X15257Y11028D01* 875 | X15238Y11066D01* 876 | X15219Y11085D01* 877 | X15180Y11104D01* 878 | X15104Y11104D01* 879 | X15066Y11085D01* 880 | X14742Y10857D02* 881 | X14780Y10838D01* 882 | X14857Y10838D01* 883 | X14895Y10857D01* 884 | X14914Y10895D01* 885 | X14914Y11047D01* 886 | X14895Y11085D01* 887 | X14857Y11104D01* 888 | X14780Y11104D01* 889 | X14742Y11085D01* 890 | X14723Y11047D01* 891 | X14723Y11009D01* 892 | X14914Y10971D01* 893 | X14247Y10838D02* 894 | X14247Y11238D01* 895 | X14076Y10838D02* 896 | X14076Y11047D01* 897 | X14095Y11085D01* 898 | X14133Y11104D01* 899 | X14190Y11104D01* 900 | X14228Y11085D01* 901 | X14247Y11066D01* 902 | X13714Y10838D02* 903 | X13714Y11047D01* 904 | X13733Y11085D01* 905 | X13771Y11104D01* 906 | X13847Y11104D01* 907 | X13885Y11085D01* 908 | X13714Y10857D02* 909 | X13752Y10838D01* 910 | X13847Y10838D01* 911 | X13885Y10857D01* 912 | X13904Y10895D01* 913 | X13904Y10933D01* 914 | X13885Y10971D01* 915 | X13847Y10990D01* 916 | X13752Y10990D01* 917 | X13714Y11009D01* 918 | X13523Y10838D02* 919 | X13523Y11104D01* 920 | X13523Y11028D02* 921 | X13504Y11066D01* 922 | X13485Y11085D01* 923 | X13447Y11104D01* 924 | X13409Y11104D01* 925 | X13104Y10838D02* 926 | X13104Y11238D01* 927 | X13104Y10857D02* 928 | X13142Y10838D01* 929 | X13219Y10838D01* 930 | X13257Y10857D01* 931 | X13276Y10876D01* 932 | X13295Y10914D01* 933 | X13295Y11028D01* 934 | X13276Y11066D01* 935 | X13257Y11085D01* 936 | X13219Y11104D01* 937 | X13142Y11104D01* 938 | X13104Y11085D01* 939 | X12952Y11104D02* 940 | X12876Y10838D01* 941 | X12800Y11028D01* 942 | X12723Y10838D01* 943 | X12647Y11104D01* 944 | X12323Y10838D02* 945 | X12323Y11047D01* 946 | X12342Y11085D01* 947 | X12380Y11104D01* 948 | X12457Y11104D01* 949 | X12495Y11085D01* 950 | X12323Y10857D02* 951 | X12361Y10838D01* 952 | X12457Y10838D01* 953 | X12495Y10857D01* 954 | X12514Y10895D01* 955 | X12514Y10933D01* 956 | X12495Y10971D01* 957 | X12457Y10990D01* 958 | X12361Y10990D01* 959 | X12323Y11009D01* 960 | X12133Y10838D02* 961 | X12133Y11104D01* 962 | X12133Y11028D02* 963 | X12114Y11066D01* 964 | X12095Y11085D01* 965 | X12057Y11104D01* 966 | X12019Y11104D01* 967 | X11733Y10857D02* 968 | X11771Y10838D01* 969 | X11847Y10838D01* 970 | X11885Y10857D01* 971 | X11904Y10895D01* 972 | X11904Y11047D01* 973 | X11885Y11085D01* 974 | X11847Y11104D01* 975 | X11771Y11104D01* 976 | X11733Y11085D01* 977 | X11714Y11047D01* 978 | X11714Y11009D01* 979 | X11904Y10971D01* 980 | X20257Y10464D02* 981 | X20257Y10140D01* 982 | X20276Y10102D01* 983 | X20295Y10083D01* 984 | X20333Y10064D01* 985 | X20390Y10064D01* 986 | X20428Y10083D01* 987 | X20257Y10217D02* 988 | X20295Y10198D01* 989 | X20371Y10198D01* 990 | X20409Y10217D01* 991 | X20428Y10236D01* 992 | X20447Y10274D01* 993 | X20447Y10388D01* 994 | X20428Y10426D01* 995 | X20409Y10445D01* 996 | X20371Y10464D01* 997 | X20295Y10464D01* 998 | X20257Y10445D01* 999 | X20066Y10198D02* 1000 | X20066Y10464D01* 1001 | X20066Y10598D02* 1002 | X20085Y10579D01* 1003 | X20066Y10560D01* 1004 | X20047Y10579D01* 1005 | X20066Y10598D01* 1006 | X20066Y10560D01* 1007 | X19933Y10464D02* 1008 | X19780Y10464D01* 1009 | X19876Y10598D02* 1010 | X19876Y10255D01* 1011 | X19857Y10217D01* 1012 | X19819Y10198D01* 1013 | X19780Y10198D01* 1014 | X19647Y10198D02* 1015 | X19647Y10598D01* 1016 | X19476Y10198D02* 1017 | X19476Y10407D01* 1018 | X19495Y10445D01* 1019 | X19533Y10464D01* 1020 | X19590Y10464D01* 1021 | X19628Y10445D01* 1022 | X19647Y10426D01* 1023 | X19114Y10464D02* 1024 | X19114Y10198D01* 1025 | X19285Y10464D02* 1026 | X19285Y10255D01* 1027 | X19266Y10217D01* 1028 | X19228Y10198D01* 1029 | X19171Y10198D01* 1030 | X19133Y10217D01* 1031 | X19114Y10236D01* 1032 | X18923Y10198D02* 1033 | X18923Y10598D01* 1034 | X18923Y10445D02* 1035 | X18885Y10464D01* 1036 | X18809Y10464D01* 1037 | X18771Y10445D01* 1038 | X18752Y10426D01* 1039 | X18733Y10388D01* 1040 | X18733Y10274D01* 1041 | X18752Y10236D01* 1042 | X18771Y10217D01* 1043 | X18809Y10198D01* 1044 | X18885Y10198D01* 1045 | X18923Y10217D01* 1046 | X18561Y10236D02* 1047 | X18542Y10217D01* 1048 | X18561Y10198D01* 1049 | X18580Y10217D01* 1050 | X18561Y10236D01* 1051 | X18561Y10198D01* 1052 | X18199Y10217D02* 1053 | X18238Y10198D01* 1054 | X18314Y10198D01* 1055 | X18352Y10217D01* 1056 | X18371Y10236D01* 1057 | X18390Y10274D01* 1058 | X18390Y10388D01* 1059 | X18371Y10426D01* 1060 | X18352Y10445D01* 1061 | X18314Y10464D01* 1062 | X18238Y10464D01* 1063 | X18199Y10445D01* 1064 | X17971Y10198D02* 1065 | X18009Y10217D01* 1066 | X18028Y10236D01* 1067 | X18047Y10274D01* 1068 | X18047Y10388D01* 1069 | X18028Y10426D01* 1070 | X18009Y10445D01* 1071 | X17971Y10464D01* 1072 | X17914Y10464D01* 1073 | X17876Y10445D01* 1074 | X17857Y10426D01* 1075 | X17838Y10388D01* 1076 | X17838Y10274D01* 1077 | X17857Y10236D01* 1078 | X17876Y10217D01* 1079 | X17914Y10198D01* 1080 | X17971Y10198D01* 1081 | X17666Y10198D02* 1082 | X17666Y10464D01* 1083 | X17666Y10426D02* 1084 | X17647Y10445D01* 1085 | X17609Y10464D01* 1086 | X17552Y10464D01* 1087 | X17514Y10445D01* 1088 | X17495Y10407D01* 1089 | X17495Y10198D01* 1090 | X17495Y10407D02* 1091 | X17476Y10445D01* 1092 | X17438Y10464D01* 1093 | X17380Y10464D01* 1094 | X17342Y10445D01* 1095 | X17323Y10407D01* 1096 | X17323Y10198D01* 1097 | X16847Y10617D02* 1098 | X17190Y10102D01* 1099 | X16752Y10464D02* 1100 | X16676Y10198D01* 1101 | X16599Y10388D01* 1102 | X16523Y10198D01* 1103 | X16447Y10464D01* 1104 | X16295Y10198D02* 1105 | X16295Y10464D01* 1106 | X16295Y10598D02* 1107 | X16314Y10579D01* 1108 | X16295Y10560D01* 1109 | X16276Y10579D01* 1110 | X16295Y10598D01* 1111 | X16295Y10560D01* 1112 | X16047Y10198D02* 1113 | X16085Y10217D01* 1114 | X16104Y10255D01* 1115 | X16104Y10598D01* 1116 | X15742Y10217D02* 1117 | X15780Y10198D01* 1118 | X15857Y10198D01* 1119 | X15895Y10217D01* 1120 | X15914Y10255D01* 1121 | X15914Y10407D01* 1122 | X15895Y10445D01* 1123 | X15857Y10464D01* 1124 | X15780Y10464D01* 1125 | X15742Y10445D01* 1126 | X15723Y10407D01* 1127 | X15723Y10369D01* 1128 | X15914Y10331D01* 1129 | X15590Y10464D02* 1130 | X15495Y10198D01* 1131 | X15399Y10464D02* 1132 | X15495Y10198D01* 1133 | X15533Y10102D01* 1134 | X15552Y10083D01* 1135 | X15590Y10064D01* 1136 | X15076Y10217D02* 1137 | X15114Y10198D01* 1138 | X15190Y10198D01* 1139 | X15228Y10217D01* 1140 | X15247Y10236D01* 1141 | X15266Y10274D01* 1142 | X15266Y10388D01* 1143 | X15247Y10426D01* 1144 | X15228Y10445D01* 1145 | X15190Y10464D01* 1146 | X15114Y10464D01* 1147 | X15076Y10445D01* 1148 | X14847Y10198D02* 1149 | X14885Y10217D01* 1150 | X14904Y10236D01* 1151 | X14923Y10274D01* 1152 | X14923Y10388D01* 1153 | X14904Y10426D01* 1154 | X14885Y10445D01* 1155 | X14847Y10464D01* 1156 | X14790Y10464D01* 1157 | X14752Y10445D01* 1158 | X14733Y10426D01* 1159 | X14714Y10388D01* 1160 | X14714Y10274D01* 1161 | X14733Y10236D01* 1162 | X14752Y10217D01* 1163 | X14790Y10198D01* 1164 | X14847Y10198D01* 1165 | X14371Y10464D02* 1166 | X14371Y10198D01* 1167 | X14542Y10464D02* 1168 | X14542Y10255D01* 1169 | X14523Y10217D01* 1170 | X14485Y10198D01* 1171 | X14428Y10198D01* 1172 | X14390Y10217D01* 1173 | X14371Y10236D01* 1174 | X14199Y10217D02* 1175 | X14161Y10198D01* 1176 | X14085Y10198D01* 1177 | X14047Y10217D01* 1178 | X14028Y10255D01* 1179 | X14028Y10274D01* 1180 | X14047Y10312D01* 1181 | X14085Y10331D01* 1182 | X14142Y10331D01* 1183 | X14180Y10350D01* 1184 | X14199Y10388D01* 1185 | X14199Y10407D01* 1186 | X14180Y10445D01* 1187 | X14142Y10464D01* 1188 | X14085Y10464D01* 1189 | X14047Y10445D01* 1190 | X13857Y10198D02* 1191 | X13857Y10464D01* 1192 | X13857Y10598D02* 1193 | X13876Y10579D01* 1194 | X13857Y10560D01* 1195 | X13838Y10579D01* 1196 | X13857Y10598D01* 1197 | X13857Y10560D01* 1198 | X13666Y10464D02* 1199 | X13666Y10198D01* 1200 | X13666Y10426D02* 1201 | X13647Y10445D01* 1202 | X13609Y10464D01* 1203 | X13552Y10464D01* 1204 | X13514Y10445D01* 1205 | X13495Y10407D01* 1206 | X13495Y10198D01* 1207 | X13323Y10217D02* 1208 | X13285Y10198D01* 1209 | X13209Y10198D01* 1210 | X13171Y10217D01* 1211 | X13152Y10255D01* 1212 | X13152Y10274D01* 1213 | X13171Y10312D01* 1214 | X13209Y10331D01* 1215 | X13266Y10331D01* 1216 | X13304Y10350D01* 1217 | X13323Y10388D01* 1218 | X13323Y10407D01* 1219 | X13304Y10445D01* 1220 | X13266Y10464D01* 1221 | X13209Y10464D01* 1222 | X13171Y10445D01* 1223 | X12695Y10617D02* 1224 | X13038Y10102D01* 1225 | X12390Y10217D02* 1226 | X12428Y10198D01* 1227 | X12504Y10198D01* 1228 | X12542Y10217D01* 1229 | X12561Y10236D01* 1230 | X12580Y10274D01* 1231 | X12580Y10388D01* 1232 | X12561Y10426D01* 1233 | X12542Y10445D01* 1234 | X12504Y10464D01* 1235 | X12428Y10464D01* 1236 | X12390Y10445D01* 1237 | X12161Y10198D02* 1238 | X12199Y10217D01* 1239 | X12219Y10255D01* 1240 | X12219Y10598D01* 1241 | X11952Y10198D02* 1242 | X11990Y10217D01* 1243 | X12009Y10236D01* 1244 | X12028Y10274D01* 1245 | X12028Y10388D01* 1246 | X12009Y10426D01* 1247 | X11990Y10445D01* 1248 | X11952Y10464D01* 1249 | X11895Y10464D01* 1250 | X11857Y10445D01* 1251 | X11838Y10426D01* 1252 | X11819Y10388D01* 1253 | X11819Y10274D01* 1254 | X11838Y10236D01* 1255 | X11857Y10217D01* 1256 | X11895Y10198D01* 1257 | X11952Y10198D01* 1258 | X11476Y10217D02* 1259 | X11514Y10198D01* 1260 | X11590Y10198D01* 1261 | X11628Y10217D01* 1262 | X11647Y10236D01* 1263 | X11666Y10274D01* 1264 | X11666Y10388D01* 1265 | X11647Y10426D01* 1266 | X11628Y10445D01* 1267 | X11590Y10464D01* 1268 | X11514Y10464D01* 1269 | X11476Y10445D01* 1270 | X11304Y10198D02* 1271 | X11304Y10598D01* 1272 | X11266Y10350D02* 1273 | X11152Y10198D01* 1274 | X11152Y10464D02* 1275 | X11304Y10312D01* 1276 | X10980Y10198D02* 1277 | X10980Y10598D01* 1278 | X10980Y10445D02* 1279 | X10942Y10464D01* 1280 | X10866Y10464D01* 1281 | X10828Y10445D01* 1282 | X10809Y10426D01* 1283 | X10790Y10388D01* 1284 | X10790Y10274D01* 1285 | X10809Y10236D01* 1286 | X10828Y10217D01* 1287 | X10866Y10198D01* 1288 | X10942Y10198D01* 1289 | X10980Y10217D01* 1290 | X10561Y10198D02* 1291 | X10600Y10217D01* 1292 | X10619Y10255D01* 1293 | X10619Y10598D01* 1294 | X10352Y10198D02* 1295 | X10390Y10217D01* 1296 | X10409Y10236D01* 1297 | X10428Y10274D01* 1298 | X10428Y10388D01* 1299 | X10409Y10426D01* 1300 | X10390Y10445D01* 1301 | X10352Y10464D01* 1302 | X10295Y10464D01* 1303 | X10257Y10445D01* 1304 | X10238Y10426D01* 1305 | X10219Y10388D01* 1306 | X10219Y10274D01* 1307 | X10238Y10236D01* 1308 | X10257Y10217D01* 1309 | X10295Y10198D01* 1310 | X10352Y10198D01* 1311 | X9876Y10217D02* 1312 | X9914Y10198D01* 1313 | X9990Y10198D01* 1314 | X10028Y10217D01* 1315 | X10047Y10236D01* 1316 | X10066Y10274D01* 1317 | X10066Y10388D01* 1318 | X10047Y10426D01* 1319 | X10028Y10445D01* 1320 | X9990Y10464D01* 1321 | X9914Y10464D01* 1322 | X9876Y10445D01* 1323 | X9704Y10198D02* 1324 | X9704Y10598D01* 1325 | X9666Y10350D02* 1326 | X9552Y10198D01* 1327 | X9552Y10464D02* 1328 | X9704Y10312D01* 1329 | G54D14* 1330 | X16309Y33261D02* 1331 | X15595Y33261D01* 1332 | X16023Y33690D02* 1333 | X16309Y32404D01* 1334 | X15690Y32833D02* 1335 | X16404Y32833D01* 1336 | X15976Y32404D02* 1337 | X15690Y33690D01* 1338 | X15309Y33261D02* 1339 | X14595Y33261D01* 1340 | X15023Y33690D02* 1341 | X15309Y32404D01* 1342 | X14690Y32833D02* 1343 | X15404Y32833D01* 1344 | X14976Y32404D02* 1345 | X14690Y33690D01* 1346 | X14309Y33261D02* 1347 | X13595Y33261D01* 1348 | X14023Y33690D02* 1349 | X14309Y32404D01* 1350 | X13690Y32833D02* 1351 | X14404Y32833D01* 1352 | X13976Y32404D02* 1353 | X13690Y33690D01* 1354 | %LPC*% 1355 | G54D15* 1356 | X40250Y6750D03* 1357 | X31750Y6750D03* 1358 | X40250Y35250D03* 1359 | X31750Y35250D03* 1360 | G54D16* 1361 | X30500Y21200D03* 1362 | X30500Y20800D03* 1363 | G54D17* 1364 | X6250Y29750D03* 1365 | X23750Y12250D03* 1366 | X6250Y12250D03* 1367 | X23750Y29750D03* 1368 | G54D18* 1369 | X9500Y17000D03* 1370 | G54D19* 1371 | X10500Y17000D03* 1372 | X9500Y16000D03* 1373 | X10500Y16000D03* 1374 | X9500Y15000D03* 1375 | X10500Y15000D03* 1376 | G54D16* 1377 | X14750Y5500D03* 1378 | X15250Y5500D03* 1379 | X31250Y5500D03* 1380 | X31750Y5500D03* 1381 | X40250Y5500D03* 1382 | X40750Y5500D03* 1383 | X40750Y36500D03* 1384 | X40250Y36500D03* 1385 | X31250Y36500D03* 1386 | X31750Y36500D03* 1387 | X14750Y36500D03* 1388 | X15250Y36500D03* 1389 | G54D20* 1390 | X2500Y39500D03* 1391 | X38500Y39500D03* 1392 | X38500Y2500D03* 1393 | X2500Y2500D03* 1394 | M02* 1395 | -------------------------------------------------------------------------------- /samples/clockblock-hub-Edge_Cuts.gbr: -------------------------------------------------------------------------------- 1 | G04 (created by PCBNEW (2013-07-07 BZR 4022)-stable) date 11/9/2013 7:35:54 PM* 2 | %MOIN*% 3 | G04 Gerber Fmt 3.4, Leading zero omitted, Abs format* 4 | %FSLAX34Y34*% 5 | G01* 6 | G70* 7 | G90* 8 | G04 APERTURE LIST* 9 | %ADD10C,0.006*% 10 | %ADD11C,0.005*% 11 | G04 APERTURE END LIST* 12 | G54D10* 13 | G54D11* 14 | X41000Y36000D02* 15 | X41000Y37000D01* 16 | X40000Y37000D02* 17 | X32000Y37000D01* 18 | X40000Y36000D02* 19 | X40000Y37000D01* 20 | X32000Y36000D02* 21 | X40000Y36000D01* 22 | X32000Y37000D02* 23 | X32000Y36000D01* 24 | X31000Y37000D02* 25 | X31000Y36000D01* 26 | X15500Y37000D02* 27 | X31000Y37000D01* 28 | X15500Y36000D02* 29 | X15500Y37000D01* 30 | X14500Y37000D02* 31 | X14500Y36000D01* 32 | X0Y37000D02* 33 | X14500Y37000D01* 34 | X0Y42000D02* 35 | X0Y37000D01* 36 | X41000Y42000D02* 37 | X0Y42000D01* 38 | X41000Y37000D02* 39 | X41000Y42000D01* 40 | X15500Y5000D02* 41 | X15500Y6000D01* 42 | X31000Y5000D02* 43 | X15500Y5000D01* 44 | X40000Y5000D02* 45 | X32000Y5000D01* 46 | X41000Y4500D02* 47 | X41000Y6000D01* 48 | X40000Y6000D02* 49 | X40000Y5000D01* 50 | X32000Y6000D02* 51 | X40000Y6000D01* 52 | X32000Y6000D02* 53 | X32000Y5000D01* 54 | X31000Y6000D02* 55 | X31000Y5000D01* 56 | X41000Y0D02* 57 | X41000Y4500D01* 58 | X0Y0D02* 59 | X41000Y0D01* 60 | X0Y5000D02* 61 | X0Y0D01* 62 | X14500Y5000D02* 63 | X14500Y6000D01* 64 | X0Y5000D02* 65 | X14500Y5000D01* 66 | X0Y21500D02* 67 | X0Y20500D01* 68 | X30000Y21500D02* 69 | G75* 70 | G03X15500Y36000I-14500J0D01* 71 | G74* 72 | G01* 73 | X15500Y6000D02* 74 | G75* 75 | G03X30000Y20500I0J14500D01* 76 | G74* 77 | G01* 78 | X14500Y36000D02* 79 | G75* 80 | G03X0Y21500I0J-14500D01* 81 | G74* 82 | G01* 83 | X0Y20500D02* 84 | G75* 85 | G03X14500Y6000I14500J0D01* 86 | G74* 87 | G01* 88 | X30000Y21500D02* 89 | X31000Y21500D01* 90 | X31000Y21500D02* 91 | X31000Y36000D01* 92 | X31000Y6000D02* 93 | X31000Y20500D01* 94 | X31000Y20500D02* 95 | X30000Y20500D01* 96 | X41000Y36000D02* 97 | X41000Y6000D01* 98 | M02* 99 | -------------------------------------------------------------------------------- /samples/clockblock-hub-F_Mask.gts: -------------------------------------------------------------------------------- 1 | G04 (created by PCBNEW (2013-07-07 BZR 4022)-stable) date 11/9/2013 7:35:54 PM* 2 | %MOIN*% 3 | G04 Gerber Fmt 3.4, Leading zero omitted, Abs format* 4 | %FSLAX34Y34*% 5 | G01* 6 | G70* 7 | G90* 8 | G04 APERTURE LIST* 9 | %ADD10C,0.006*% 10 | %ADD11C,0.104425*% 11 | %ADD12R,0.0453701X0.159543*% 12 | %ADD13C,0.021*% 13 | %ADD14C,0.147732*% 14 | %ADD15R,0.0335591X0.0335591*% 15 | %ADD16R,0.0886772X0.0571811*% 16 | %ADD17R,0.0611181X0.0709606*% 17 | %ADD18C,0.407575*% 18 | %ADD19R,0.104425X0.206787*% 19 | %ADD20R,0.0729291X0.0729291*% 20 | %ADD21C,0.0729291*% 21 | %ADD22R,0.0685039X0.0173228*% 22 | %ADD23R,0.109134X0.135906*% 23 | %ADD24R,0.023622X0.0629921*% 24 | %ADD25R,0.0984252X0.0826772*% 25 | %ADD26R,0.0787402X0.0826772*% 26 | %ADD27R,0.0268661X0.0839528*% 27 | %ADD28R,0.0334646X0.0496063*% 28 | %ADD29R,0.0611X0.0198*% 29 | %ADD30R,0.0788346X0.0493071*% 30 | %ADD31R,0.0493071X0.0788346*% 31 | %ADD32C,0.131*% 32 | %ADD33C,0.11811*% 33 | G04 APERTURE END LIST* 34 | G54D10* 35 | G54D11* 36 | X40250Y6750D03* 37 | X31750Y6750D03* 38 | X40250Y35250D03* 39 | X31750Y35250D03* 40 | G54D12* 41 | X17000Y13456D03* 42 | X17000Y10543D03* 43 | X16000Y13456D03* 44 | X16000Y10543D03* 45 | X15000Y13456D03* 46 | X15000Y10543D03* 47 | X14000Y13456D03* 48 | X14000Y10543D03* 49 | X13000Y13456D03* 50 | X13000Y10543D03* 51 | X34000Y30793D03* 52 | X34000Y33706D03* 53 | X35000Y30793D03* 54 | X35000Y33706D03* 55 | X36000Y30793D03* 56 | X36000Y33706D03* 57 | X37000Y30793D03* 58 | X37000Y33706D03* 59 | X38000Y30793D03* 60 | X38000Y33706D03* 61 | G54D13* 62 | X30500Y21200D03* 63 | X30500Y20800D03* 64 | G54D14* 65 | X6250Y29750D03* 66 | G54D15* 67 | X33500Y6974D03* 68 | X33500Y7525D03* 69 | X33500Y8224D03* 70 | X33500Y8775D03* 71 | G54D16* 72 | X34208Y13346D03* 73 | X37791Y11653D03* 74 | X34208Y11653D03* 75 | X37791Y13346D03* 76 | X34208Y20346D03* 77 | X37791Y18653D03* 78 | X34208Y18653D03* 79 | X37791Y20346D03* 80 | X34208Y27346D03* 81 | X37791Y25653D03* 82 | X34208Y25653D03* 83 | X37791Y27346D03* 84 | G54D15* 85 | X9474Y28750D03* 86 | X10025Y28750D03* 87 | G54D14* 88 | X23750Y12250D03* 89 | X6250Y12250D03* 90 | X23750Y29750D03* 91 | G54D17* 92 | X32000Y10600D03* 93 | X32000Y9399D03* 94 | G54D18* 95 | X18250Y26000D03* 96 | G54D19* 97 | X15238Y26000D03* 98 | X21261Y26000D03* 99 | G54D10* 100 | G36* 101 | X5592Y31960D02* 102 | X5883Y32127D01* 103 | X6051Y31837D01* 104 | X5760Y31669D01* 105 | X5592Y31960D01* 106 | X5592Y31960D01* 107 | G37* 108 | G36* 109 | X5868Y31482D02* 110 | X6159Y31650D01* 111 | X6327Y31359D01* 112 | X6036Y31192D01* 113 | X5868Y31482D01* 114 | X5868Y31482D01* 115 | G37* 116 | G36* 117 | X1372Y25786D02* 118 | X1539Y26077D01* 119 | X1830Y25909D01* 120 | X1662Y25618D01* 121 | X1372Y25786D01* 122 | X1372Y25786D01* 123 | G37* 124 | G36* 125 | X1849Y25510D02* 126 | X2017Y25801D01* 127 | X2307Y25633D01* 128 | X2140Y25342D01* 129 | X1849Y25510D01* 130 | X1849Y25510D01* 131 | G37* 132 | G54D15* 133 | X37474Y14250D03* 134 | X38025Y14250D03* 135 | X35025Y9000D03* 136 | X34474Y9000D03* 137 | X34500Y9974D03* 138 | X34500Y10525D03* 139 | X33750Y10525D03* 140 | X33750Y9974D03* 141 | X37525Y9000D03* 142 | X36974Y9000D03* 143 | X35724Y9000D03* 144 | X36275Y9000D03* 145 | X36000Y9974D03* 146 | X36000Y10525D03* 147 | X974Y18500D03* 148 | X1525Y18500D03* 149 | X33474Y16750D03* 150 | X34025Y16750D03* 151 | X38750Y16775D03* 152 | X38750Y16224D03* 153 | X39500Y16775D03* 154 | X39500Y16224D03* 155 | X10025Y29500D03* 156 | X9474Y29500D03* 157 | X11474Y23250D03* 158 | X12025Y23250D03* 159 | X8000Y22525D03* 160 | X8000Y21974D03* 161 | X18000Y21974D03* 162 | X18000Y22525D03* 163 | X37474Y28250D03* 164 | X38025Y28250D03* 165 | X37474Y21250D03* 166 | X38025Y21250D03* 167 | X36750Y9974D03* 168 | X36750Y10525D03* 169 | X17000Y20724D03* 170 | X17000Y21275D03* 171 | X13000Y21275D03* 172 | X13000Y20724D03* 173 | X15275Y23000D03* 174 | X14724Y23000D03* 175 | X12000Y22525D03* 176 | X12000Y21974D03* 177 | X17000Y17525D03* 178 | X17000Y16974D03* 179 | X13000Y17525D03* 180 | X13000Y16974D03* 181 | X22000Y22525D03* 182 | X22000Y21974D03* 183 | X20275Y14750D03* 184 | X19724Y14750D03* 185 | X20275Y17250D03* 186 | X19724Y17250D03* 187 | G54D10* 188 | G36* 189 | X19786Y34627D02* 190 | X20077Y34460D01* 191 | X19909Y34169D01* 192 | X19618Y34337D01* 193 | X19786Y34627D01* 194 | X19786Y34627D01* 195 | G37* 196 | G36* 197 | X19510Y34150D02* 198 | X19801Y33982D01* 199 | X19633Y33692D01* 200 | X19342Y33859D01* 201 | X19510Y34150D01* 202 | X19510Y34150D01* 203 | G37* 204 | G54D15* 205 | X29025Y23500D03* 206 | X28474Y23500D03* 207 | G54D10* 208 | G36* 209 | X25960Y30407D02* 210 | X26127Y30116D01* 211 | X25837Y29948D01* 212 | X25669Y30239D01* 213 | X25960Y30407D01* 214 | X25960Y30407D01* 215 | G37* 216 | G36* 217 | X25482Y30131D02* 218 | X25650Y29840D01* 219 | X25359Y29672D01* 220 | X25192Y29963D01* 221 | X25482Y30131D01* 222 | X25482Y30131D01* 223 | G37* 224 | G54D15* 225 | X12500Y35025D03* 226 | X12500Y34474D03* 227 | G54D10* 228 | G36* 229 | X24407Y9839D02* 230 | X24116Y9672D01* 231 | X23948Y9962D01* 232 | X24239Y10130D01* 233 | X24407Y9839D01* 234 | X24407Y9839D01* 235 | G37* 236 | G36* 237 | X24131Y10317D02* 238 | X23840Y10149D01* 239 | X23672Y10440D01* 240 | X23963Y10607D01* 241 | X24131Y10317D01* 242 | X24131Y10317D01* 243 | G37* 244 | G36* 245 | X10213Y7372D02* 246 | X9922Y7539D01* 247 | X10090Y7830D01* 248 | X10381Y7662D01* 249 | X10213Y7372D01* 250 | X10213Y7372D01* 251 | G37* 252 | G36* 253 | X10489Y7849D02* 254 | X10198Y8017D01* 255 | X10366Y8307D01* 256 | X10657Y8140D01* 257 | X10489Y7849D01* 258 | X10489Y7849D01* 259 | G37* 260 | G54D15* 261 | X17500Y6974D03* 262 | X17500Y7525D03* 263 | G54D10* 264 | G36* 265 | X4039Y11592D02* 266 | X3872Y11883D01* 267 | X4162Y12051D01* 268 | X4330Y11760D01* 269 | X4039Y11592D01* 270 | X4039Y11592D01* 271 | G37* 272 | G36* 273 | X4517Y11868D02* 274 | X4349Y12159D01* 275 | X4640Y12327D01* 276 | X4807Y12036D01* 277 | X4517Y11868D01* 278 | X4517Y11868D01* 279 | G37* 280 | G36* 281 | X28627Y16213D02* 282 | X28460Y15922D01* 283 | X28169Y16090D01* 284 | X28337Y16381D01* 285 | X28627Y16213D01* 286 | X28627Y16213D01* 287 | G37* 288 | G36* 289 | X28150Y16489D02* 290 | X27982Y16198D01* 291 | X27692Y16366D01* 292 | X27859Y16657D01* 293 | X28150Y16489D01* 294 | X28150Y16489D01* 295 | G37* 296 | G54D15* 297 | X38750Y8775D03* 298 | X38750Y8224D03* 299 | X39500Y8775D03* 300 | X39500Y8224D03* 301 | X15275Y23750D03* 302 | X14724Y23750D03* 303 | G54D20* 304 | X9500Y17000D03* 305 | G54D21* 306 | X10500Y17000D03* 307 | X9500Y16000D03* 308 | X10500Y16000D03* 309 | X9500Y15000D03* 310 | X10500Y15000D03* 311 | G54D22* 312 | X11102Y21895D03* 313 | X11102Y22151D03* 314 | X11102Y21639D03* 315 | X11102Y21383D03* 316 | X11102Y21127D03* 317 | X11102Y20872D03* 318 | X11102Y20616D03* 319 | X11102Y20360D03* 320 | X8897Y19848D03* 321 | X8897Y20104D03* 322 | X8897Y20360D03* 323 | X8897Y20616D03* 324 | X8897Y22151D03* 325 | X8897Y21895D03* 326 | X8897Y21639D03* 327 | X8897Y21383D03* 328 | X8897Y21127D03* 329 | X8897Y20872D03* 330 | G54D23* 331 | X10000Y21000D03* 332 | G54D22* 333 | X11102Y20104D03* 334 | X11102Y19848D03* 335 | X16102Y16895D03* 336 | X16102Y17151D03* 337 | X16102Y16639D03* 338 | X16102Y16383D03* 339 | X16102Y16127D03* 340 | X16102Y15872D03* 341 | X16102Y15616D03* 342 | X16102Y15360D03* 343 | X13897Y14848D03* 344 | X13897Y15104D03* 345 | X13897Y15360D03* 346 | X13897Y15616D03* 347 | X13897Y17151D03* 348 | X13897Y16895D03* 349 | X13897Y16639D03* 350 | X13897Y16383D03* 351 | X13897Y16127D03* 352 | X13897Y15872D03* 353 | G54D23* 354 | X15000Y16000D03* 355 | G54D22* 356 | X16102Y15104D03* 357 | X16102Y14848D03* 358 | X21102Y21895D03* 359 | X21102Y22151D03* 360 | X21102Y21639D03* 361 | X21102Y21383D03* 362 | X21102Y21127D03* 363 | X21102Y20872D03* 364 | X21102Y20616D03* 365 | X21102Y20360D03* 366 | X18897Y19848D03* 367 | X18897Y20104D03* 368 | X18897Y20360D03* 369 | X18897Y20616D03* 370 | X18897Y22151D03* 371 | X18897Y21895D03* 372 | X18897Y21639D03* 373 | X18897Y21383D03* 374 | X18897Y21127D03* 375 | X18897Y20872D03* 376 | G54D23* 377 | X20000Y21000D03* 378 | G54D22* 379 | X21102Y20104D03* 380 | X21102Y19848D03* 381 | G54D24* 382 | X35488Y7852D03* 383 | X35744Y7852D03* 384 | X36000Y7852D03* 385 | X36255Y7852D03* 386 | X36511Y7852D03* 387 | G54D25* 388 | X34523Y6730D03* 389 | X37476Y6730D03* 390 | G54D26* 391 | X36452Y6730D03* 392 | X35547Y6730D03* 393 | G54D27* 394 | X8750Y24155D03* 395 | X9250Y24155D03* 396 | X9750Y24155D03* 397 | X10250Y24155D03* 398 | X10750Y24155D03* 399 | X11250Y24155D03* 400 | X11750Y24155D03* 401 | X12250Y24155D03* 402 | X12750Y24155D03* 403 | X13250Y24155D03* 404 | X13250Y27844D03* 405 | X12750Y27844D03* 406 | X12250Y27844D03* 407 | X11750Y27844D03* 408 | X11250Y27844D03* 409 | X10750Y27844D03* 410 | X10250Y27844D03* 411 | X9750Y27844D03* 412 | X9250Y27844D03* 413 | X8750Y27844D03* 414 | G54D28* 415 | X19625Y15566D03* 416 | X20000Y15566D03* 417 | X20374Y15566D03* 418 | X20374Y16433D03* 419 | X19625Y16433D03* 420 | G54D29* 421 | X34868Y16896D03* 422 | X34868Y16640D03* 423 | X34868Y16384D03* 424 | X34868Y16128D03* 425 | X34868Y15872D03* 426 | X34868Y15616D03* 427 | X34868Y15360D03* 428 | X34868Y15104D03* 429 | X37132Y15104D03* 430 | X37132Y15360D03* 431 | X37132Y15616D03* 432 | X37132Y15872D03* 433 | X37132Y16128D03* 434 | X37132Y16384D03* 435 | X37132Y16640D03* 436 | X37132Y16896D03* 437 | G54D30* 438 | X748Y19500D03* 439 | X748Y20500D03* 440 | G54D10* 441 | G36* 442 | X2123Y15579D02* 443 | X2369Y15152D01* 444 | X1687Y14758D01* 445 | X1440Y15185D01* 446 | X2123Y15579D01* 447 | X2123Y15579D01* 448 | G37* 449 | G36* 450 | X2623Y14719D02* 451 | X2869Y14292D01* 452 | X2187Y13898D01* 453 | X1940Y14325D01* 454 | X2623Y14719D01* 455 | X2623Y14719D01* 456 | G37* 457 | G36* 458 | X3123Y13849D02* 459 | X3369Y13422D01* 460 | X2687Y13028D01* 461 | X2440Y13455D01* 462 | X3123Y13849D01* 463 | X3123Y13849D01* 464 | G37* 465 | G36* 466 | X3623Y12989D02* 467 | X3869Y12562D01* 468 | X3187Y12168D01* 469 | X2940Y12595D01* 470 | X3623Y12989D01* 471 | X3623Y12989D01* 472 | G37* 473 | G36* 474 | X6562Y9869D02* 475 | X6989Y9623D01* 476 | X6595Y8940D01* 477 | X6168Y9187D01* 478 | X6562Y9869D01* 479 | X6562Y9869D01* 480 | G37* 481 | G36* 482 | X7422Y9369D02* 483 | X7849Y9123D01* 484 | X7455Y8440D01* 485 | X7028Y8687D01* 486 | X7422Y9369D01* 487 | X7422Y9369D01* 488 | G37* 489 | G36* 490 | X8292Y8869D02* 491 | X8719Y8623D01* 492 | X8325Y7940D01* 493 | X7898Y8187D01* 494 | X8292Y8869D01* 495 | X8292Y8869D01* 496 | G37* 497 | G54D30* 498 | X748Y21500D03* 499 | X748Y22500D03* 500 | G54D10* 501 | G36* 502 | X2369Y26847D02* 503 | X2123Y26420D01* 504 | X1440Y26814D01* 505 | X1687Y27241D01* 506 | X2369Y26847D01* 507 | X2369Y26847D01* 508 | G37* 509 | G36* 510 | X2869Y27707D02* 511 | X2623Y27280D01* 512 | X1940Y27674D01* 513 | X2187Y28101D01* 514 | X2869Y27707D01* 515 | X2869Y27707D01* 516 | G37* 517 | G36* 518 | X3869Y29437D02* 519 | X3623Y29010D01* 520 | X2940Y29404D01* 521 | X3187Y29831D01* 522 | X3869Y29437D01* 523 | X3869Y29437D01* 524 | G37* 525 | G36* 526 | X6989Y32376D02* 527 | X6562Y32130D01* 528 | X6168Y32812D01* 529 | X6595Y33059D01* 530 | X6989Y32376D01* 531 | X6989Y32376D01* 532 | G37* 533 | G36* 534 | X7849Y32876D02* 535 | X7422Y32630D01* 536 | X7028Y33312D01* 537 | X7455Y33559D01* 538 | X7849Y32876D01* 539 | X7849Y32876D01* 540 | G37* 541 | G36* 542 | X8719Y33376D02* 543 | X8292Y33130D01* 544 | X7898Y33812D01* 545 | X8325Y34059D01* 546 | X8719Y33376D01* 547 | X8719Y33376D01* 548 | G37* 549 | G36* 550 | X9579Y33876D02* 551 | X9152Y33630D01* 552 | X8758Y34312D01* 553 | X9185Y34559D01* 554 | X9579Y33876D01* 555 | X9579Y33876D01* 556 | G37* 557 | G36* 558 | X3369Y28577D02* 559 | X3123Y28150D01* 560 | X2440Y28544D01* 561 | X2687Y28971D01* 562 | X3369Y28577D01* 563 | X3369Y28577D01* 564 | G37* 565 | G36* 566 | X22577Y32630D02* 567 | X22150Y32876D01* 568 | X22544Y33559D01* 569 | X22971Y33312D01* 570 | X22577Y32630D01* 571 | X22577Y32630D01* 572 | G37* 573 | G36* 574 | X21707Y33130D02* 575 | X21280Y33376D01* 576 | X21674Y34059D01* 577 | X22101Y33812D01* 578 | X21707Y33130D01* 579 | X21707Y33130D01* 580 | G37* 581 | G36* 582 | X20847Y33630D02* 583 | X20420Y33876D01* 584 | X20814Y34559D01* 585 | X21241Y34312D01* 586 | X20847Y33630D01* 587 | X20847Y33630D01* 588 | G37* 589 | G54D31* 590 | X16500Y35251D03* 591 | X15500Y35251D03* 592 | X14500Y35251D03* 593 | X13500Y35251D03* 594 | G54D10* 595 | G36* 596 | X23437Y32130D02* 597 | X23010Y32376D01* 598 | X23404Y33059D01* 599 | X23831Y32812D01* 600 | X23437Y32130D01* 601 | X23437Y32130D01* 602 | G37* 603 | G36* 604 | X26376Y29010D02* 605 | X26130Y29437D01* 606 | X26812Y29831D01* 607 | X27059Y29404D01* 608 | X26376Y29010D01* 609 | X26376Y29010D01* 610 | G37* 611 | G36* 612 | X26876Y28150D02* 613 | X26630Y28577D01* 614 | X27312Y28971D01* 615 | X27559Y28544D01* 616 | X26876Y28150D01* 617 | X26876Y28150D01* 618 | G37* 619 | G36* 620 | X27376Y27280D02* 621 | X27130Y27707D01* 622 | X27812Y28101D01* 623 | X28059Y27674D01* 624 | X27376Y27280D01* 625 | X27376Y27280D01* 626 | G37* 627 | G36* 628 | X27876Y26420D02* 629 | X27630Y26847D01* 630 | X28312Y27241D01* 631 | X28559Y26814D01* 632 | X27876Y26420D01* 633 | X27876Y26420D01* 634 | G37* 635 | G54D30* 636 | X29251Y22500D03* 637 | G54D10* 638 | G36* 639 | X20420Y8123D02* 640 | X20847Y8369D01* 641 | X21241Y7687D01* 642 | X20814Y7440D01* 643 | X20420Y8123D01* 644 | X20420Y8123D01* 645 | G37* 646 | G54D30* 647 | X29251Y20500D03* 648 | X29251Y19500D03* 649 | G54D10* 650 | G36* 651 | X27630Y15152D02* 652 | X27876Y15579D01* 653 | X28559Y15185D01* 654 | X28312Y14758D01* 655 | X27630Y15152D01* 656 | X27630Y15152D01* 657 | G37* 658 | G36* 659 | X27130Y14292D02* 660 | X27376Y14719D01* 661 | X28059Y14325D01* 662 | X27812Y13898D01* 663 | X27130Y14292D01* 664 | X27130Y14292D01* 665 | G37* 666 | G36* 667 | X26630Y13422D02* 668 | X26876Y13849D01* 669 | X27559Y13455D01* 670 | X27312Y13028D01* 671 | X26630Y13422D01* 672 | X26630Y13422D01* 673 | G37* 674 | G36* 675 | X26130Y12562D02* 676 | X26376Y12989D01* 677 | X27059Y12595D01* 678 | X26812Y12168D01* 679 | X26130Y12562D01* 680 | X26130Y12562D01* 681 | G37* 682 | G36* 683 | X23010Y9623D02* 684 | X23437Y9869D01* 685 | X23831Y9187D01* 686 | X23404Y8940D01* 687 | X23010Y9623D01* 688 | X23010Y9623D01* 689 | G37* 690 | G36* 691 | X22150Y9123D02* 692 | X22577Y9369D01* 693 | X22971Y8687D01* 694 | X22544Y8440D01* 695 | X22150Y9123D01* 696 | X22150Y9123D01* 697 | G37* 698 | G36* 699 | X21280Y8623D02* 700 | X21707Y8869D01* 701 | X22101Y8187D01* 702 | X21674Y7940D01* 703 | X21280Y8623D01* 704 | X21280Y8623D01* 705 | G37* 706 | G54D31* 707 | X16500Y6748D03* 708 | X15500Y6748D03* 709 | X14500Y6748D03* 710 | X13500Y6748D03* 711 | G54D10* 712 | G36* 713 | X9152Y8369D02* 714 | X9579Y8123D01* 715 | X9185Y7440D01* 716 | X8758Y7687D01* 717 | X9152Y8369D01* 718 | X9152Y8369D01* 719 | G37* 720 | G54D30* 721 | X29251Y21500D03* 722 | G54D22* 723 | X16102Y21895D03* 724 | X16102Y22151D03* 725 | X16102Y21639D03* 726 | X16102Y21383D03* 727 | X16102Y21127D03* 728 | X16102Y20872D03* 729 | X16102Y20616D03* 730 | X16102Y20360D03* 731 | X13897Y19848D03* 732 | X13897Y20104D03* 733 | X13897Y20360D03* 734 | X13897Y20616D03* 735 | X13897Y22151D03* 736 | X13897Y21895D03* 737 | X13897Y21639D03* 738 | X13897Y21383D03* 739 | X13897Y21127D03* 740 | X13897Y20872D03* 741 | X16102Y20104D03* 742 | X16102Y19848D03* 743 | G54D13* 744 | X14750Y5500D03* 745 | X15250Y5500D03* 746 | X31250Y5500D03* 747 | X31750Y5500D03* 748 | X40250Y5500D03* 749 | X40750Y5500D03* 750 | X40750Y36500D03* 751 | X40250Y36500D03* 752 | X31250Y36500D03* 753 | X31750Y36500D03* 754 | X14750Y36500D03* 755 | X15250Y36500D03* 756 | G54D32* 757 | X2500Y39500D03* 758 | X38500Y39500D03* 759 | X38500Y2500D03* 760 | X2500Y2500D03* 761 | G54D33* 762 | X8000Y14000D03* 763 | X7500Y26000D03* 764 | X27500Y25000D03* 765 | X5000Y39500D03* 766 | X5000Y2500D03* 767 | X36000Y2500D03* 768 | X40000Y26500D03* 769 | X40000Y12500D03* 770 | X33000Y19500D03* 771 | M02* 772 | -------------------------------------------------------------------------------- /samples/clockblock-hub-F_Paste.gtp: -------------------------------------------------------------------------------- 1 | G04 (created by PCBNEW (2013-07-07 BZR 4022)-stable) date 11/9/2013 7:35:54 PM* 2 | %MOIN*% 3 | G04 Gerber Fmt 3.4, Leading zero omitted, Abs format* 4 | %FSLAX34Y34*% 5 | G01* 6 | G70* 7 | G90* 8 | G04 APERTURE LIST* 9 | %ADD10C,0.006*% 10 | %ADD11R,0.0373701X0.151543*% 11 | %ADD12R,0.0255906X0.0255906*% 12 | %ADD13R,0.0806772X0.0491811*% 13 | %ADD14R,0.0531181X0.0629606*% 14 | %ADD15R,0.0610236X0.00984252*% 15 | %ADD16R,0.108976X0.135748*% 16 | %ADD17R,0.0137795X0.0531496*% 17 | %ADD18R,0.0748031X0.0590551*% 18 | %ADD19R,0.0551181X0.0590551*% 19 | %ADD20R,0.0188661X0.0759528*% 20 | %ADD21R,0.023622X0.0397638*% 21 | %ADD22R,0.0531X0.0118*% 22 | %ADD23R,0.0708346X0.0413071*% 23 | %ADD24R,0.0413071X0.0708346*% 24 | G04 APERTURE END LIST* 25 | G54D10* 26 | G54D11* 27 | X17000Y13456D03* 28 | X17000Y10543D03* 29 | X16000Y13456D03* 30 | X16000Y10543D03* 31 | X15000Y13456D03* 32 | X15000Y10543D03* 33 | X14000Y13456D03* 34 | X14000Y10543D03* 35 | X13000Y13456D03* 36 | X13000Y10543D03* 37 | X34000Y30793D03* 38 | X34000Y33706D03* 39 | X35000Y30793D03* 40 | X35000Y33706D03* 41 | X36000Y30793D03* 42 | X36000Y33706D03* 43 | X37000Y30793D03* 44 | X37000Y33706D03* 45 | X38000Y30793D03* 46 | X38000Y33706D03* 47 | G54D12* 48 | X33500Y6974D03* 49 | X33500Y7525D03* 50 | X33500Y8224D03* 51 | X33500Y8775D03* 52 | G54D13* 53 | X34208Y13346D03* 54 | X37791Y11653D03* 55 | X34208Y11653D03* 56 | X37791Y13346D03* 57 | X34208Y20346D03* 58 | X37791Y18653D03* 59 | X34208Y18653D03* 60 | X37791Y20346D03* 61 | X34208Y27346D03* 62 | X37791Y25653D03* 63 | X34208Y25653D03* 64 | X37791Y27346D03* 65 | G54D12* 66 | X9474Y28750D03* 67 | X10025Y28750D03* 68 | G54D14* 69 | X32000Y10600D03* 70 | X32000Y9399D03* 71 | G54D10* 72 | G36* 73 | X5647Y31945D02* 74 | X5869Y32073D01* 75 | X5996Y31851D01* 76 | X5775Y31723D01* 77 | X5647Y31945D01* 78 | X5647Y31945D01* 79 | G37* 80 | G36* 81 | X5923Y31468D02* 82 | X6144Y31596D01* 83 | X6272Y31374D01* 84 | X6050Y31246D01* 85 | X5923Y31468D01* 86 | X5923Y31468D01* 87 | G37* 88 | G36* 89 | X1426Y25800D02* 90 | X1554Y26022D01* 91 | X1776Y25894D01* 92 | X1648Y25673D01* 93 | X1426Y25800D01* 94 | X1426Y25800D01* 95 | G37* 96 | G36* 97 | X1903Y25525D02* 98 | X2031Y25746D01* 99 | X2253Y25619D01* 100 | X2125Y25397D01* 101 | X1903Y25525D01* 102 | X1903Y25525D01* 103 | G37* 104 | G54D12* 105 | X37474Y14250D03* 106 | X38025Y14250D03* 107 | X35025Y9000D03* 108 | X34474Y9000D03* 109 | X34500Y9974D03* 110 | X34500Y10525D03* 111 | X33750Y10525D03* 112 | X33750Y9974D03* 113 | X37525Y9000D03* 114 | X36974Y9000D03* 115 | X35724Y9000D03* 116 | X36275Y9000D03* 117 | X36000Y9974D03* 118 | X36000Y10525D03* 119 | X974Y18500D03* 120 | X1525Y18500D03* 121 | X33474Y16750D03* 122 | X34025Y16750D03* 123 | X38750Y16775D03* 124 | X38750Y16224D03* 125 | X39500Y16775D03* 126 | X39500Y16224D03* 127 | X10025Y29500D03* 128 | X9474Y29500D03* 129 | X11474Y23250D03* 130 | X12025Y23250D03* 131 | X8000Y22525D03* 132 | X8000Y21974D03* 133 | X18000Y21974D03* 134 | X18000Y22525D03* 135 | X37474Y28250D03* 136 | X38025Y28250D03* 137 | X37474Y21250D03* 138 | X38025Y21250D03* 139 | X36750Y9974D03* 140 | X36750Y10525D03* 141 | X17000Y20724D03* 142 | X17000Y21275D03* 143 | X13000Y21275D03* 144 | X13000Y20724D03* 145 | X15275Y23000D03* 146 | X14724Y23000D03* 147 | X12000Y22525D03* 148 | X12000Y21974D03* 149 | X17000Y17525D03* 150 | X17000Y16974D03* 151 | X13000Y17525D03* 152 | X13000Y16974D03* 153 | X22000Y22525D03* 154 | X22000Y21974D03* 155 | X20275Y14750D03* 156 | X19724Y14750D03* 157 | X20275Y17250D03* 158 | X19724Y17250D03* 159 | G54D10* 160 | G36* 161 | X19800Y34573D02* 162 | X20022Y34445D01* 163 | X19894Y34223D01* 164 | X19673Y34351D01* 165 | X19800Y34573D01* 166 | X19800Y34573D01* 167 | G37* 168 | G36* 169 | X19525Y34096D02* 170 | X19746Y33968D01* 171 | X19619Y33746D01* 172 | X19397Y33874D01* 173 | X19525Y34096D01* 174 | X19525Y34096D01* 175 | G37* 176 | G54D12* 177 | X29025Y23500D03* 178 | X28474Y23500D03* 179 | G54D10* 180 | G36* 181 | X25945Y30352D02* 182 | X26073Y30130D01* 183 | X25851Y30003D01* 184 | X25723Y30224D01* 185 | X25945Y30352D01* 186 | X25945Y30352D01* 187 | G37* 188 | G36* 189 | X25468Y30076D02* 190 | X25596Y29855D01* 191 | X25374Y29727D01* 192 | X25246Y29949D01* 193 | X25468Y30076D01* 194 | X25468Y30076D01* 195 | G37* 196 | G54D12* 197 | X12500Y35025D03* 198 | X12500Y34474D03* 199 | G54D10* 200 | G36* 201 | X24352Y9854D02* 202 | X24130Y9726D01* 203 | X24003Y9948D01* 204 | X24224Y10076D01* 205 | X24352Y9854D01* 206 | X24352Y9854D01* 207 | G37* 208 | G36* 209 | X24076Y10331D02* 210 | X23855Y10203D01* 211 | X23727Y10425D01* 212 | X23949Y10553D01* 213 | X24076Y10331D01* 214 | X24076Y10331D01* 215 | G37* 216 | G36* 217 | X10199Y7426D02* 218 | X9977Y7554D01* 219 | X10105Y7776D01* 220 | X10326Y7648D01* 221 | X10199Y7426D01* 222 | X10199Y7426D01* 223 | G37* 224 | G36* 225 | X10474Y7903D02* 226 | X10253Y8031D01* 227 | X10380Y8253D01* 228 | X10602Y8125D01* 229 | X10474Y7903D01* 230 | X10474Y7903D01* 231 | G37* 232 | G54D12* 233 | X17500Y6974D03* 234 | X17500Y7525D03* 235 | G54D10* 236 | G36* 237 | X4054Y11647D02* 238 | X3926Y11869D01* 239 | X4148Y11996D01* 240 | X4276Y11775D01* 241 | X4054Y11647D01* 242 | X4054Y11647D01* 243 | G37* 244 | G36* 245 | X4531Y11923D02* 246 | X4403Y12144D01* 247 | X4625Y12272D01* 248 | X4753Y12050D01* 249 | X4531Y11923D01* 250 | X4531Y11923D01* 251 | G37* 252 | G36* 253 | X28573Y16199D02* 254 | X28445Y15977D01* 255 | X28223Y16105D01* 256 | X28351Y16326D01* 257 | X28573Y16199D01* 258 | X28573Y16199D01* 259 | G37* 260 | G36* 261 | X28096Y16474D02* 262 | X27968Y16253D01* 263 | X27746Y16380D01* 264 | X27874Y16602D01* 265 | X28096Y16474D01* 266 | X28096Y16474D01* 267 | G37* 268 | G54D12* 269 | X38750Y8775D03* 270 | X38750Y8224D03* 271 | X39500Y8775D03* 272 | X39500Y8224D03* 273 | X15275Y23750D03* 274 | X14724Y23750D03* 275 | G54D15* 276 | X11102Y21895D03* 277 | X11102Y22151D03* 278 | X11102Y21639D03* 279 | X11102Y21383D03* 280 | X11102Y21127D03* 281 | X11102Y20872D03* 282 | X11102Y20616D03* 283 | X11102Y20360D03* 284 | X8897Y19848D03* 285 | X8897Y20104D03* 286 | X8897Y20360D03* 287 | X8897Y20616D03* 288 | X8897Y22151D03* 289 | X8897Y21895D03* 290 | X8897Y21639D03* 291 | X8897Y21383D03* 292 | X8897Y21127D03* 293 | X8897Y20872D03* 294 | G54D16* 295 | X10000Y21000D03* 296 | G54D15* 297 | X11102Y20104D03* 298 | X11102Y19848D03* 299 | X16102Y16895D03* 300 | X16102Y17151D03* 301 | X16102Y16639D03* 302 | X16102Y16383D03* 303 | X16102Y16127D03* 304 | X16102Y15872D03* 305 | X16102Y15616D03* 306 | X16102Y15360D03* 307 | X13897Y14848D03* 308 | X13897Y15104D03* 309 | X13897Y15360D03* 310 | X13897Y15616D03* 311 | X13897Y17151D03* 312 | X13897Y16895D03* 313 | X13897Y16639D03* 314 | X13897Y16383D03* 315 | X13897Y16127D03* 316 | X13897Y15872D03* 317 | G54D16* 318 | X15000Y16000D03* 319 | G54D15* 320 | X16102Y15104D03* 321 | X16102Y14848D03* 322 | X21102Y21895D03* 323 | X21102Y22151D03* 324 | X21102Y21639D03* 325 | X21102Y21383D03* 326 | X21102Y21127D03* 327 | X21102Y20872D03* 328 | X21102Y20616D03* 329 | X21102Y20360D03* 330 | X18897Y19848D03* 331 | X18897Y20104D03* 332 | X18897Y20360D03* 333 | X18897Y20616D03* 334 | X18897Y22151D03* 335 | X18897Y21895D03* 336 | X18897Y21639D03* 337 | X18897Y21383D03* 338 | X18897Y21127D03* 339 | X18897Y20872D03* 340 | G54D16* 341 | X20000Y21000D03* 342 | G54D15* 343 | X21102Y20104D03* 344 | X21102Y19848D03* 345 | G54D17* 346 | X35488Y7852D03* 347 | X35744Y7852D03* 348 | X36000Y7852D03* 349 | X36255Y7852D03* 350 | X36511Y7852D03* 351 | G54D18* 352 | X34523Y6730D03* 353 | X37476Y6730D03* 354 | G54D19* 355 | X36452Y6730D03* 356 | X35547Y6730D03* 357 | G54D20* 358 | X8750Y24155D03* 359 | X9250Y24155D03* 360 | X9750Y24155D03* 361 | X10250Y24155D03* 362 | X10750Y24155D03* 363 | X11250Y24155D03* 364 | X11750Y24155D03* 365 | X12250Y24155D03* 366 | X12750Y24155D03* 367 | X13250Y24155D03* 368 | X13250Y27844D03* 369 | X12750Y27844D03* 370 | X12250Y27844D03* 371 | X11750Y27844D03* 372 | X11250Y27844D03* 373 | X10750Y27844D03* 374 | X10250Y27844D03* 375 | X9750Y27844D03* 376 | X9250Y27844D03* 377 | X8750Y27844D03* 378 | G54D21* 379 | X19625Y15566D03* 380 | X20000Y15566D03* 381 | X20374Y15566D03* 382 | X20374Y16433D03* 383 | X19625Y16433D03* 384 | G54D22* 385 | X34868Y16896D03* 386 | X34868Y16640D03* 387 | X34868Y16384D03* 388 | X34868Y16128D03* 389 | X34868Y15872D03* 390 | X34868Y15616D03* 391 | X34868Y15360D03* 392 | X34868Y15104D03* 393 | X37132Y15104D03* 394 | X37132Y15360D03* 395 | X37132Y15616D03* 396 | X37132Y15872D03* 397 | X37132Y16128D03* 398 | X37132Y16384D03* 399 | X37132Y16640D03* 400 | X37132Y16896D03* 401 | G54D23* 402 | X748Y19500D03* 403 | X748Y20500D03* 404 | G54D10* 405 | G36* 406 | X2108Y15524D02* 407 | X2315Y15167D01* 408 | X1701Y14813D01* 409 | X1495Y15170D01* 410 | X2108Y15524D01* 411 | X2108Y15524D01* 412 | G37* 413 | G36* 414 | X2608Y14664D02* 415 | X2815Y14307D01* 416 | X2201Y13953D01* 417 | X1995Y14310D01* 418 | X2608Y14664D01* 419 | X2608Y14664D01* 420 | G37* 421 | G36* 422 | X3108Y13794D02* 423 | X3315Y13437D01* 424 | X2701Y13083D01* 425 | X2495Y13440D01* 426 | X3108Y13794D01* 427 | X3108Y13794D01* 428 | G37* 429 | G36* 430 | X3608Y12934D02* 431 | X3815Y12577D01* 432 | X3201Y12223D01* 433 | X2995Y12580D01* 434 | X3608Y12934D01* 435 | X3608Y12934D01* 436 | G37* 437 | G36* 438 | X6577Y9815D02* 439 | X6934Y9608D01* 440 | X6580Y8995D01* 441 | X6223Y9201D01* 442 | X6577Y9815D01* 443 | X6577Y9815D01* 444 | G37* 445 | G36* 446 | X7437Y9315D02* 447 | X7794Y9108D01* 448 | X7440Y8495D01* 449 | X7083Y8701D01* 450 | X7437Y9315D01* 451 | X7437Y9315D01* 452 | G37* 453 | G36* 454 | X8307Y8815D02* 455 | X8664Y8608D01* 456 | X8310Y7995D01* 457 | X7953Y8201D01* 458 | X8307Y8815D01* 459 | X8307Y8815D01* 460 | G37* 461 | G54D23* 462 | X748Y21500D03* 463 | X748Y22500D03* 464 | G54D10* 465 | G36* 466 | X2315Y26832D02* 467 | X2108Y26475D01* 468 | X1495Y26829D01* 469 | X1701Y27186D01* 470 | X2315Y26832D01* 471 | X2315Y26832D01* 472 | G37* 473 | G36* 474 | X2815Y27692D02* 475 | X2608Y27335D01* 476 | X1995Y27689D01* 477 | X2201Y28046D01* 478 | X2815Y27692D01* 479 | X2815Y27692D01* 480 | G37* 481 | G36* 482 | X3815Y29422D02* 483 | X3608Y29065D01* 484 | X2995Y29419D01* 485 | X3201Y29776D01* 486 | X3815Y29422D01* 487 | X3815Y29422D01* 488 | G37* 489 | G36* 490 | X6934Y32391D02* 491 | X6577Y32184D01* 492 | X6223Y32798D01* 493 | X6580Y33004D01* 494 | X6934Y32391D01* 495 | X6934Y32391D01* 496 | G37* 497 | G36* 498 | X7794Y32891D02* 499 | X7437Y32684D01* 500 | X7083Y33298D01* 501 | X7440Y33504D01* 502 | X7794Y32891D01* 503 | X7794Y32891D01* 504 | G37* 505 | G36* 506 | X8664Y33391D02* 507 | X8307Y33184D01* 508 | X7953Y33798D01* 509 | X8310Y34004D01* 510 | X8664Y33391D01* 511 | X8664Y33391D01* 512 | G37* 513 | G36* 514 | X9524Y33891D02* 515 | X9167Y33684D01* 516 | X8813Y34298D01* 517 | X9170Y34504D01* 518 | X9524Y33891D01* 519 | X9524Y33891D01* 520 | G37* 521 | G36* 522 | X3315Y28562D02* 523 | X3108Y28205D01* 524 | X2495Y28559D01* 525 | X2701Y28916D01* 526 | X3315Y28562D01* 527 | X3315Y28562D01* 528 | G37* 529 | G36* 530 | X22562Y32684D02* 531 | X22205Y32891D01* 532 | X22559Y33504D01* 533 | X22916Y33298D01* 534 | X22562Y32684D01* 535 | X22562Y32684D01* 536 | G37* 537 | G36* 538 | X21692Y33184D02* 539 | X21335Y33391D01* 540 | X21689Y34004D01* 541 | X22046Y33798D01* 542 | X21692Y33184D01* 543 | X21692Y33184D01* 544 | G37* 545 | G36* 546 | X20832Y33684D02* 547 | X20475Y33891D01* 548 | X20829Y34504D01* 549 | X21186Y34298D01* 550 | X20832Y33684D01* 551 | X20832Y33684D01* 552 | G37* 553 | G54D24* 554 | X16500Y35251D03* 555 | X15500Y35251D03* 556 | X14500Y35251D03* 557 | X13500Y35251D03* 558 | G54D10* 559 | G36* 560 | X23422Y32184D02* 561 | X23065Y32391D01* 562 | X23419Y33004D01* 563 | X23776Y32798D01* 564 | X23422Y32184D01* 565 | X23422Y32184D01* 566 | G37* 567 | G36* 568 | X26391Y29065D02* 569 | X26184Y29422D01* 570 | X26798Y29776D01* 571 | X27004Y29419D01* 572 | X26391Y29065D01* 573 | X26391Y29065D01* 574 | G37* 575 | G36* 576 | X26891Y28205D02* 577 | X26684Y28562D01* 578 | X27298Y28916D01* 579 | X27504Y28559D01* 580 | X26891Y28205D01* 581 | X26891Y28205D01* 582 | G37* 583 | G36* 584 | X27391Y27335D02* 585 | X27184Y27692D01* 586 | X27798Y28046D01* 587 | X28004Y27689D01* 588 | X27391Y27335D01* 589 | X27391Y27335D01* 590 | G37* 591 | G36* 592 | X27891Y26475D02* 593 | X27684Y26832D01* 594 | X28298Y27186D01* 595 | X28504Y26829D01* 596 | X27891Y26475D01* 597 | X27891Y26475D01* 598 | G37* 599 | G54D23* 600 | X29251Y22500D03* 601 | G54D10* 602 | G36* 603 | X20475Y8108D02* 604 | X20832Y8315D01* 605 | X21186Y7701D01* 606 | X20829Y7495D01* 607 | X20475Y8108D01* 608 | X20475Y8108D01* 609 | G37* 610 | G54D23* 611 | X29251Y20500D03* 612 | X29251Y19500D03* 613 | G54D10* 614 | G36* 615 | X27684Y15167D02* 616 | X27891Y15524D01* 617 | X28504Y15170D01* 618 | X28298Y14813D01* 619 | X27684Y15167D01* 620 | X27684Y15167D01* 621 | G37* 622 | G36* 623 | X27184Y14307D02* 624 | X27391Y14664D01* 625 | X28004Y14310D01* 626 | X27798Y13953D01* 627 | X27184Y14307D01* 628 | X27184Y14307D01* 629 | G37* 630 | G36* 631 | X26684Y13437D02* 632 | X26891Y13794D01* 633 | X27504Y13440D01* 634 | X27298Y13083D01* 635 | X26684Y13437D01* 636 | X26684Y13437D01* 637 | G37* 638 | G36* 639 | X26184Y12577D02* 640 | X26391Y12934D01* 641 | X27004Y12580D01* 642 | X26798Y12223D01* 643 | X26184Y12577D01* 644 | X26184Y12577D01* 645 | G37* 646 | G36* 647 | X23065Y9608D02* 648 | X23422Y9815D01* 649 | X23776Y9201D01* 650 | X23419Y8995D01* 651 | X23065Y9608D01* 652 | X23065Y9608D01* 653 | G37* 654 | G36* 655 | X22205Y9108D02* 656 | X22562Y9315D01* 657 | X22916Y8701D01* 658 | X22559Y8495D01* 659 | X22205Y9108D01* 660 | X22205Y9108D01* 661 | G37* 662 | G36* 663 | X21335Y8608D02* 664 | X21692Y8815D01* 665 | X22046Y8201D01* 666 | X21689Y7995D01* 667 | X21335Y8608D01* 668 | X21335Y8608D01* 669 | G37* 670 | G54D24* 671 | X16500Y6748D03* 672 | X15500Y6748D03* 673 | X14500Y6748D03* 674 | X13500Y6748D03* 675 | G54D10* 676 | G36* 677 | X9167Y8315D02* 678 | X9524Y8108D01* 679 | X9170Y7495D01* 680 | X8813Y7701D01* 681 | X9167Y8315D01* 682 | X9167Y8315D01* 683 | G37* 684 | G54D23* 685 | X29251Y21500D03* 686 | G54D15* 687 | X16102Y21895D03* 688 | X16102Y22151D03* 689 | X16102Y21639D03* 690 | X16102Y21383D03* 691 | X16102Y21127D03* 692 | X16102Y20872D03* 693 | X16102Y20616D03* 694 | X16102Y20360D03* 695 | X13897Y19848D03* 696 | X13897Y20104D03* 697 | X13897Y20360D03* 698 | X13897Y20616D03* 699 | X13897Y22151D03* 700 | X13897Y21895D03* 701 | X13897Y21639D03* 702 | X13897Y21383D03* 703 | X13897Y21127D03* 704 | X13897Y20872D03* 705 | X16102Y20104D03* 706 | X16102Y19848D03* 707 | M02* 708 | -------------------------------------------------------------------------------- /samples/clockblock-hub-NPTH.drl: -------------------------------------------------------------------------------- 1 | M48 2 | ;DRILL file {Pcbnew (2013-07-07 BZR 4022)-stable} date 11/9/2013 7:35:35 PM 3 | ;FORMAT={2:4/ absolute / inch / keep zeros} 4 | FMAT,2 5 | INCH,TZ 6 | T1C0.015 7 | T2C0.125 8 | % 9 | G90 10 | G05 11 | M72 12 | T1 13 | X014750Y036500 14 | X014750Y005500 15 | X015250Y036500 16 | X015250Y005500 17 | X030500Y021200 18 | X030500Y020800 19 | X031250Y036500 20 | X031250Y005500 21 | X031750Y036500 22 | X031750Y005500 23 | X040250Y036500 24 | X040250Y005500 25 | X040750Y036500 26 | X040750Y005500 27 | T2 28 | X002500Y039500 29 | X002500Y002500 30 | X038500Y039500 31 | X038500Y002500 32 | T0 33 | M30 34 | -------------------------------------------------------------------------------- /samples/clockblock-hub.drl: -------------------------------------------------------------------------------- 1 | M48 2 | ;DRILL file {Pcbnew (2013-07-07 BZR 4022)-stable} date 11/9/2013 7:35:35 PM 3 | ;FORMAT={2:4/ absolute / inch / keep zeros} 4 | FMAT,2 5 | INCH,TZ 6 | T1C0.015 7 | T2C0.020 8 | T3C0.035 9 | T4C0.098 10 | T5C0.142 11 | % 12 | G90 13 | G05 14 | M72 15 | T1 16 | X001600Y021800 17 | X002000Y018500 18 | X002550Y022000 19 | X003250Y020000 20 | X003700Y020000 21 | X003800Y021100 22 | X004200Y021250 23 | X004200Y020000 24 | X004600Y021500 25 | X004650Y020000 26 | X004950Y021750 27 | X005350Y019700 28 | X005700Y019950 29 | X005700Y019450 30 | X005700Y018950 31 | X006150Y020000 32 | X006550Y023000 33 | X006550Y022500 34 | X006550Y022000 35 | X006600Y020000 36 | X006900Y022250 37 | X007250Y022550 38 | X007450Y024000 39 | X007500Y022900 40 | X007550Y020000 41 | X007550Y019550 42 | X007800Y023250 43 | X008200Y023700 44 | X008700Y018400 45 | X008700Y016650 46 | X009450Y018125 47 | X009650Y023300 48 | X009750Y022000 49 | X009750Y021500 50 | X009750Y021000 51 | X009750Y020500 52 | X009750Y020000 53 | X010050Y030100 54 | X010200Y014000 55 | X010250Y022000 56 | X010250Y021500 57 | X010250Y021000 58 | X010250Y020500 59 | X010250Y020000 60 | X010550Y028650 61 | X010850Y023000 62 | X011000Y023400 63 | X011150Y022650 64 | X011200Y014100 65 | X011400Y016000 66 | X011400Y015400 67 | X011450Y014900 68 | X011500Y017150 69 | X011650Y014100 70 | X011750Y017500 71 | X012150Y014750 72 | X012350Y013750 73 | X012450Y021450 74 | X012550Y021000 75 | X012700Y023150 76 | X012775Y022700 77 | X012950Y020150 78 | X013200Y021800 79 | X013200Y008300 80 | X013250Y022700 81 | X013500Y017950 82 | X013850Y017700 83 | X013950Y023425 84 | X014400Y019300 85 | X014500Y008050 86 | X014550Y021400 87 | X014550Y011900 88 | X014600Y020450 89 | X014750Y017000 90 | X014750Y016500 91 | X014750Y016000 92 | X014750Y015500 93 | X014750Y015000 94 | X015100Y020050 95 | X015250Y017000 96 | X015250Y016500 97 | X015250Y016000 98 | X015250Y015500 99 | X015250Y015000 100 | X015425Y019750 101 | X015500Y021000 102 | X015500Y008050 103 | X015700Y022650 104 | X016000Y011650 105 | X016350Y022700 106 | X016400Y027850 107 | X016450Y012100 108 | X016550Y024300 109 | X016850Y009300 110 | X016950Y020200 111 | X017200Y023675 112 | X017450Y021050 113 | X017450Y020600 114 | X017450Y020150 115 | X017450Y019700 116 | X017500Y017500 117 | X017850Y014200 118 | X017950Y016800 119 | X018000Y017500 120 | X018150Y016100 121 | X018250Y014400 122 | X018350Y015350 123 | X018400Y009550 124 | X018400Y009050 125 | X018400Y008550 126 | X018450Y014850 127 | X018450Y013700 128 | X018500Y022900 129 | X018500Y019300 130 | X018750Y015850 131 | X018850Y022650 132 | X018900Y019500 133 | X018950Y017250 134 | X018950Y016800 135 | X019100Y008050 136 | X019626Y016850 137 | X019750Y022000 138 | X019750Y021500 139 | X019750Y021000 140 | X019750Y020500 141 | X019750Y020000 142 | X019800Y007100 143 | X020050Y027800 144 | X020250Y022000 145 | X020250Y021500 146 | X020250Y021000 147 | X020250Y020500 148 | X020250Y020000 149 | X020450Y023650 150 | X020775Y024000 151 | X021100Y023250 152 | X021200Y016550 153 | X021300Y017250 154 | X021750Y017250 155 | X022050Y023200 156 | X022500Y023200 157 | X022500Y022000 158 | X022550Y019300 159 | X022700Y020250 160 | X022800Y022800 161 | X023200Y020250 162 | X023600Y022000 163 | X023700Y020250 164 | X024000Y018400 165 | X024000Y017350 166 | X024000Y016900 167 | X024050Y022000 168 | X024450Y018400 169 | X024500Y022000 170 | X026700Y020900 171 | X027200Y020050 172 | X027900Y021000 173 | X027950Y023500 174 | X028100Y020050 175 | X034200Y017300 176 | X034950Y011600 177 | X035550Y013350 178 | X035600Y015900 179 | X035600Y015400 180 | X036000Y032550 181 | X036000Y032050 182 | X036500Y032900 183 | X036550Y016050 184 | X036600Y013350 185 | X037000Y032150 186 | X037800Y026250 187 | X037850Y015500 188 | X037900Y016450 189 | X038000Y016000 190 | X038350Y015300 191 | X038600Y021250 192 | X038650Y013400 193 | T2 194 | X001050Y017450 195 | X001200Y024900 196 | X004500Y030750 197 | X005200Y010350 198 | X011300Y007300 199 | X011450Y034900 200 | X018700Y034850 201 | X018750Y007200 202 | X020550Y011500 203 | X025200Y010800 204 | X025400Y031100 205 | X028650Y024650 206 | X028650Y017150 207 | X032900Y008800 208 | X039100Y007550 209 | T3 210 | X009500Y017000 211 | X009500Y016000 212 | X009500Y015000 213 | X010500Y017000 214 | X010500Y016000 215 | X010500Y015000 216 | T4 217 | X031750Y035250 218 | X031750Y006750 219 | X040250Y035250 220 | X040250Y006750 221 | T5 222 | X006250Y029750 223 | X006250Y012250 224 | X023750Y029750 225 | X023750Y012250 226 | T0 227 | M30 228 | -------------------------------------------------------------------------------- /src/build-board-outline.coffee: -------------------------------------------------------------------------------- 1 | # function to create a board of the exact shape as defined by the outline 2 | # takes in an svg path data array and spits out an svg path data array 3 | 4 | find = require 'lodash/collection/find' 5 | remove = require 'lodash/array/remove' 6 | 7 | # helper class: point 8 | class Point 9 | # constructor takes an x and a y and contructs a segment array 10 | # each point should have two segments 11 | constructor: (@x, @y) -> @segments = [] 12 | # add a segment to the segment array 13 | addSegment: (seg, rel) -> @segments.push { seg: seg, rel: rel } 14 | 15 | # helper class: line or arc segment 16 | class Segment 17 | # constructor adds self to the start and end point's segment array 18 | constructor: (@start, @end) -> 19 | @start.addSegment @, 'start' 20 | #@start = { x: start.x, y: start.y } 21 | @end.addSegment @, 'end' 22 | #@end = { x: end.x, y: end.y } 23 | # adds arc properties to the segment 24 | addArc: (@radius, @largeArc, @sweep) -> 25 | # spit out the command to draw to the given endpoint 26 | # this assumes that the pen is already at the other enpoint 27 | drawTo: (point) -> 28 | # check to see if we're drawing to one of our endpoints 29 | if point is @start then toStart=true else if point is @end then toEnd=true 30 | # if we're a line, we really only care if it's going somewhere we can 31 | if not @radius? and (toStart or toEnd) then [ 'L', point.x, point.y ] 32 | # else if we're an arc going to our normal end, nothing changes 33 | else if @radius? and toEnd 34 | [ 'A', @radius, @radius, 0, @largeArc, @sweep, point.x, point.y ] 35 | # else if we're an arc going to our start, we need to flip the @sweep flag 36 | else if @radius? and toStart 37 | sw = if @sweep is 1 then 0 else 1 38 | [ 'A' ,@radius, @radius, 0, @largeArc, sw, point.x, point.y ] 39 | # else this isn't going to work out, so don't draw 40 | else return [] 41 | 42 | module.exports = (outline) -> 43 | # sanity check: first command should be a move to 44 | if outline[0] isnt 'M' then console.log "didn't start with 'M'"; return [] 45 | 46 | # we're going to save points rather than segments 47 | pathStart = null 48 | points = [] 49 | # going to do a good old-fashioned while loop for this one 50 | i = 0 51 | while i < outline.length - 1 52 | # check out current character to get our starting point 53 | # M and L have a point directly after them 54 | if outline[i] is 'M' or outline[i] is 'L' 55 | x = outline[i+1] 56 | y = outline[i+2] 57 | i += 3 58 | # A (arc) has some other params we need to get by 59 | else if outline[i] is 'A' 60 | x = outline[i+6] 61 | y = outline[i+7] 62 | i += 8 63 | # Z is an end of the path, so le'ts just move along 64 | else if outline[i] is 'Z' then i++; continue 65 | 66 | # check to make sure we're not out of bounds 67 | if i >= outline.length then break 68 | else 69 | start = find points, { x: x, y: y } 70 | if not start? then newStart = true; start = new Point x, y 71 | 72 | # check our current character again to get the end of the segment 73 | if outline[i] is 'L' 74 | x = outline[i+1] 75 | y = outline[i+2] 76 | r = null 77 | else if outline[i] is 'A' 78 | x = outline[i+6] 79 | y = outline[i+7] 80 | r = outline[i+2] 81 | lrgArc = outline[i+4] 82 | sweep = outline[i+5] 83 | # M means a new path, so just continue 84 | else if outline[i] is 'M' then continue 85 | 86 | # Z is an end of the path, so draw a line directly to the start 87 | if outline[i] is 'Z' 88 | end = pathStart 89 | pathStart = null 90 | else 91 | # set the path start if ncessary 92 | if not pathStart? then pathStart = start 93 | end = find points, { x: x, y: y } 94 | if not end? then newEnd = true; end = new Point x, y 95 | 96 | # we've got a start and an end, so create the segment and push the points 97 | seg = new Segment start, end 98 | if r? then seg.addArc r, lrgArc, sweep 99 | if newStart then newStart = false; points.push start 100 | if newEnd then newEnd = false; points.push end 101 | 102 | # now that we're out of the loop, we should have all our points 103 | # let's traverse them, drawing as we go 104 | newPath = [] 105 | while points.length 106 | startPoint = points.pop() 107 | nextSegObj = startPoint.segments.pop() 108 | nextPoint = null 109 | newPath.push 'M', startPoint.x, startPoint.y 110 | while nextPoint isnt startPoint 111 | # remove nextPoint from the points array 112 | remove points, (p) -> p is nextPoint 113 | # go along the segment to get the next point 114 | nextSeg = nextSegObj.seg 115 | nextSegRel = nextSegObj.rel 116 | nextPointRel = if nextSegRel is 'start' then 'end' else 'start' 117 | nextPoint = nextSeg[nextPointRel] 118 | # draw the segment and remove it 119 | newPath.push p for p in nextSeg.drawTo nextPoint 120 | remove nextPoint.segments, (sO) -> sO.seg is nextSeg 121 | # set the next segment object by popping the other segment in the array 122 | nextSegObj = nextPoint.segments.pop() 123 | 124 | # return the new path 125 | newPath 126 | -------------------------------------------------------------------------------- /src/build-board.coffee: -------------------------------------------------------------------------------- 1 | # new board builder 2 | # hopefully less janky than the first one 3 | 4 | # board outline processor 5 | boardOutline = require './build-board-outline.coffee' 6 | 7 | # make sure we don't have overlapping ids 8 | unique = 0 9 | uniqueId = -> unique++ 10 | 11 | # board type matching 12 | reCOPPER = /cu/ 13 | reMASK = /sm/ 14 | reSILK = /ss/ 15 | rePASTE = /sp/ 16 | reEDGE = /out/ 17 | reDRILL = /drl/ 18 | 19 | # board combine function 20 | # takes the board name and board layers 21 | module.exports = (name, layers = []) -> 22 | copper = null 23 | mask = null 24 | silk = null 25 | paste = null 26 | edge = null 27 | drill = [] 28 | 29 | # resulting svg is going to have attributes, a def section, a drawing, and a 30 | # bounding box 31 | attr = {} 32 | defs = [] 33 | draw = [] 34 | bbox = [ Infinity, Infinity, -Infinity, -Infinity ] 35 | edgeBbox = null 36 | units = 'px' 37 | scale = null 38 | addVboxToBbox = (v) -> 39 | xMax = v[2] + v[0] 40 | yMax = v[3] + v[1] 41 | if v[0] < bbox[0] then bbox[0] = v[0] 42 | if v[1] < bbox[1] then bbox[1] = v[1] 43 | if xMax > bbox[2] then bbox[2] = xMax 44 | if yMax > bbox[3] then bbox[3] = yMax 45 | getVboxFromBbox = (bb) -> [ bb[0], bb[1], bb[2]-bb[0], bb[3]-bb[1] ] 46 | 47 | # gather all the layers to combine there defs, bboxes, and attributes 48 | # we're also going to push the layers themselves to the defs 49 | for layer in layers 50 | # get layer type 51 | ly = layer.type 52 | # xml object and make sure we've got something 53 | xml = layer.svgObj 54 | continue if not xml.svg? 55 | # collect the bbox 56 | addVboxToBbox xml.svg.viewBox 57 | # grab the units 58 | u = xml.svg.width.match(/(in)|(mm)/)?[0] 59 | if units is 'px' then units = u 60 | else if u isnt units then return {} 61 | # grab the units to vbox scale 62 | vbScale = parseFloat(xml.svg.width)/xml.svg.viewBox[2] 63 | if not scale? then scale = vbScale 64 | else if Math.abs(vbScale-scale) > 0.0000001 then return {} 65 | # toss the viewBox as well as the width, height and id 66 | # delete xml.svg.viewBox 67 | # delete xml.svg.width 68 | # delete xml.svg.height 69 | # delete xml.svg.id 70 | # gather the rest of the attributes 71 | for key, val of xml.svg 72 | attr[key] = val if not attr[key]? and key isnt '_' 73 | # collect the defs and group 74 | # hopefully a group and defs will be the only children of the svg node 75 | layerId = "#{name}-#{ly}_#{uniqueId()}" 76 | for node in xml.svg._ 77 | # collect the defs 78 | if node.defs? then defs.push d for d in node.defs._ 79 | # collect the group 80 | else if node.g? 81 | # delete the transform and any fill or stroke properties 82 | delete node.g.transform 83 | # add a better id 84 | node.g.id = layerId 85 | defs.push node 86 | # now, it is possible that there will be multiple drill files. deal with it 87 | if reCOPPER.test ly then copper = layerId 88 | else if reMASK.test ly then mask = layerId 89 | else if reSILK.test ly then silk = layerId 90 | else if rePASTE.test ly then paste = layerId 91 | else if reDRILL.test ly then drill.push layerId 92 | # let's get a little crazy with the edge layer if we've got one 93 | else if reEDGE.test ly 94 | edge = layerId 95 | # the last thing to get pushed to defs should be the drill g 96 | # if it only has one path, let's mess with it 97 | group = defs[defs.length-1].g._ 98 | for n in group 99 | if n.path? and n.path['stroke-width'] 100 | if not path? 101 | path = n.path 102 | else 103 | path.d = path.d.concat(n.path.d) 104 | # re-arrange the outline path so the shapes are manifold 105 | newPathData = [] 106 | try 107 | newPathData = boardOutline path.d 108 | catch e 109 | # if it works, groovy, we've got a bbox and a mask 110 | if newPathData.length 111 | oldSW = path['stroke-width'] 112 | path['stroke-width'] = 0 113 | path.fill = '#fff' 114 | path['fill-rule'] = 'evenodd' 115 | path.d = newPathData 116 | # use the edge bbox for the board 117 | vb = xml.svg.viewBox 118 | vb[0] += oldSW/2 119 | vb[1] += oldSW/2 120 | vb[2] -= oldSW 121 | vb[3] -= oldSW 122 | edgeBbox = [ vb[0], vb[1], vb[2] + vb[0], vb[3] + vb[1] ] 123 | 124 | # undefine (to save memory I guess?) 125 | xml = null 126 | # we need at least a copper layer to do this 127 | unless copper? then return {} 128 | 129 | # viewbox and covering rectangle convenience function 130 | if edgeBbox? then bbox = edgeBbox 131 | vbox = getVboxFromBbox bbox 132 | bboxRect = (cls = 'Board--cover', fill='currentColor') -> 133 | { 134 | rect: { 135 | class: cls 136 | fill: fill 137 | x: vbox[0] 138 | y: vbox[1] 139 | width: vbox[2] 140 | height: vbox[3] 141 | } 142 | } 143 | 144 | # the first layer of the board stackup is the board itself 145 | draw.push bboxRect('Board--board') 146 | 147 | # the second layer is the copper 148 | draw.push { use: { class: 'Board--cu', 'xlink:href': "##{copper}" } } 149 | 150 | # if we've got a soldermask 151 | if mask? 152 | # mask it with the copper for copper finish 153 | cuFinishId = "#{name}-sm_#{uniqueId()}" 154 | defs.push { 155 | mask: { 156 | id: cuFinishId 157 | color: '#fff' 158 | _: [ { use: { 'xlink:href': "##{copper}" } } ] 159 | } 160 | } 161 | draw.push { 162 | use: { 163 | class: 'Board--cf' 164 | mask: "url(##{cuFinishId})" 165 | 'xlink:href': "##{mask}" 166 | } 167 | } 168 | # now build group for the color and the silkscreen (if it exists) and 169 | # mask away the soldermask holes 170 | smId = "#{name}-sm_#{uniqueId()}" 171 | defs.push { mask: { id: smId, color: '#000', _: [ 172 | bboxRect null, '#fff' 173 | { use: { 'xlink:href': "##{mask}" } } 174 | ] 175 | } 176 | } 177 | smPos = { g: { mask: "url(##{smId})", _: [ bboxRect 'Board--sm' ] } } 178 | # add the silkscreen if it exists 179 | if silk? then smPos.g._.push { 180 | use: { class: 'Board--ss', 'xlink:href': "##{silk}" } 181 | } 182 | # push the soldermask to the stack 183 | draw.push smPos 184 | 185 | # if we've got solderpaste, push it to the drawing 186 | if paste? then draw.push { 187 | use: { class: 'Board--sp', 'xlink:href': "##{paste}" } 188 | } 189 | 190 | # add edge cuts if we gottem and our fanciness didn't work out 191 | if edge? and not edgeBbox? then draw.push { 192 | use: { class: 'Board--out', 'xlink:href': "##{edge}" } 193 | } 194 | 195 | # we may have some drills or a fancy board shape 196 | mechId = null 197 | if drill.length || edgeBbox? 198 | mechId = "#{name}-mech_#{uniqueId()}" 199 | mechMask = { mask: { id: mechId, color: '#000', _: [] } } 200 | mechMask.mask._.push if edgeBbox? then { use: { 'xlink:href': "##{edge}" } } else bboxRect null, '#fff' 201 | mechMask.mask._.push { use: { 'xlink:href': "##{d}" } } for d in drill 202 | # push the mask to the defs 203 | defs.push mechMask 204 | 205 | # return object 206 | # flip vertically always and horizontally as well if bottom of board 207 | if name is 'bottom' then trans = """ 208 | translate(#{bbox[2]+bbox[0]},#{bbox[3]+bbox[1]}) scale(-1,-1) 209 | """ 210 | else trans = "translate(0,#{bbox[3]+bbox[1]}) scale(1,-1)" 211 | # drawing 212 | draw = { g: { transform: trans, _: draw } } 213 | if mechId then draw.g.mask = "url(##{mechId})" 214 | # svg 215 | svg = attr 216 | svg.class = 'Board' 217 | svg.viewBox = getVboxFromBbox bbox 218 | svg.width = "#{svg.viewBox[2]*scale}#{units}" 219 | svg.height = "#{svg.viewBox[3]*scale}#{units}" 220 | svg._ = [] 221 | svg._.push { defs: { _: defs } } if defs.length 222 | svg._.push draw if draw.g._.length 223 | # return 224 | { svg: svg } 225 | -------------------------------------------------------------------------------- /src/collections/boards.coffee: -------------------------------------------------------------------------------- 1 | # collection of the top and bottom board 2 | # require Renders prototype collection, board model, and builder worker 3 | Renders = require './renders' 4 | Board = require '../models/board' 5 | builder = new Worker './../workers/board-worker.coffee' 6 | 7 | class Boards extends Renders 8 | model: Board 9 | 10 | initialize: -> 11 | # attach an event listener to the board builder 12 | @attachBuilderHandler() 13 | # when a board triggers a buildNeeded event, build it 14 | @on 'buildNeeded', @buildBoard 15 | # call the parent initialize 16 | super() 17 | 18 | buildBoard: (board) -> 19 | builder.postMessage { 20 | name: board.get 'name' 21 | layers: board.get 'boardLayers' 22 | } 23 | 24 | attachBuilderHandler: -> 25 | _self = @ 26 | handler = (e) -> _self.convert e.data.name, e.data.svgObj 27 | builder.addEventListener 'message', handler, false 28 | 29 | module.exports = Boards 30 | -------------------------------------------------------------------------------- /src/collections/layers.coffee: -------------------------------------------------------------------------------- 1 | # collection of all individual layers 2 | # require Layer model and Renders prototype collection 3 | Layer = require '../models/layer' 4 | Renders = require './renders' 5 | 6 | class Layers extends Renders 7 | model: Layer 8 | 9 | # attach an event listener on type change 10 | initialize: -> 11 | # validate whole collection when a model's layer type gets changed 12 | @on 'change:type', @validateLayers 13 | # when a model is added, convert it 14 | @on 'change:gerber', (layer) -> 15 | gerber = layer.get 'gerber' 16 | if gerber then @convert layer.get('name'), gerber 17 | # call the super 18 | super() 19 | 20 | # validate all layer selections 21 | validateLayers: -> 22 | valid = true 23 | # return true to continue even if isValid return false 24 | @forEach (layer) -> 25 | if layer.isValid() then layer.trigger 'valid' else valid = false 26 | # return true to keep validating 27 | true 28 | # return the validation 29 | valid 30 | 31 | module.exports = Layers 32 | -------------------------------------------------------------------------------- /src/collections/renders.coffee: -------------------------------------------------------------------------------- 1 | # prototype collection for individual layers as well as board stackup renders 2 | 3 | # require gerber converter and base64 workers 4 | converter = new Worker './../workers/gerber-worker.coffee' 5 | encoder = new Worker './../workers/btoa-worker.coffee' 6 | 7 | class Renders extends Backbone.Collection 8 | 9 | initialize: -> 10 | # attach handlers to the workers 11 | @attachConverterHandler() 12 | @attachEncoderHandler() 13 | # encode the svg if the svg string changes 14 | @on 'change:svg change:style', @encode 15 | 16 | encode: (render) -> 17 | render.set 'svg64', false 18 | string = render.get 'svg' 19 | style = render.get 'style' 20 | if string 21 | # insert the style into the svg string if necessary 22 | if style? 23 | index = string.match(/^.*?>/)[0].length 24 | string = string[0...index] + style + string[index..] 25 | # post the message to the encoder 26 | encoder.postMessage { 27 | name: render.get 'name' 28 | string: string 29 | } 30 | 31 | convert: (name, gerber) -> 32 | converter.postMessage { filename: name, gerber: gerber } 33 | 34 | # attach a handler for when the base64 worker finishes 35 | attachEncoderHandler: -> 36 | _self = @ 37 | handler = (e) -> 38 | if render = _self.findWhere { name: e.data.name } 39 | render.set 'svg64', e.data.string 40 | encoder.addEventListener 'message', handler, false 41 | 42 | # attach a handler for when the gerber worker finishes 43 | # this will fire in all collections, so beware of the effects that has 44 | attachConverterHandler: -> 45 | _self = @ 46 | handler = (e) -> 47 | # if render exists 48 | if render = _self.findWhere { name: e.data.filename } 49 | render.set 'svgObj', e.data.svgObj 50 | render.set 'svg', e.data.svgString 51 | render.set 'warnings', e.data.warnings 52 | render.trigger 'processEnd', render 53 | converter.addEventListener 'message', handler, false 54 | 55 | module.exports = Renders 56 | -------------------------------------------------------------------------------- /src/color-options.coffee: -------------------------------------------------------------------------------- 1 | # board colors 2 | module.exports = { 3 | # copper finish 4 | cf: { 5 | bare: { bg: '#C87533', txt: 'white' } 6 | gold: { bg: 'goldenrod', txt: 'white' } 7 | 'Ni/Au': { bg: 'whitesmoke', txt: 'black' } 8 | hasl: { bg: 'silver', txt: 'black' } 9 | } 10 | # soldermask 11 | sm: { 12 | red: { bg: 'darkred', txt: 'white' } 13 | orange: { bg: 'darkorange', txt: 'black' } 14 | yellow: { bg: '#FFFF66', txt: 'black' } 15 | green: { bg: 'darkgreen', txt: 'white' } 16 | blue: { bg: 'navy', txt: 'white' } 17 | purple: { bg: 'indigo', txt: 'white' } 18 | black: { bg: 'black', txt: 'white' } 19 | white: { bg: 'white', txt: 'black' } 20 | } 21 | # silkscreen 22 | ss: { 23 | red: { bg: 'red', txt: 'white' } 24 | yellow: { bg: 'yellow', txt: 'black' } 25 | green: { bg: 'green', txt: 'white' } 26 | blue: { bg: 'blue', txt: 'white' } 27 | black: { bg: 'black', txt: 'white' } 28 | white: { bg: 'white', txt: 'black' } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/github-api-url.coffee: -------------------------------------------------------------------------------- 1 | # parse a standard github url into an github api url 2 | module.exports = (url) -> 3 | # strip off the http and split by / 4 | url = url.match(/github\.com\S+/)?[0].split '/' 5 | if url?.length 6 | api = 'https://api.github.com/repos' 7 | owner = url[1] 8 | repo = url[2] 9 | branch = url[4] 10 | path = url[5..].join '/' 11 | url = "#{api}/#{owner}/#{repo}/contents/#{path}?ref=#{branch}" 12 | else 13 | false 14 | -------------------------------------------------------------------------------- /src/identify-layer.coffee: -------------------------------------------------------------------------------- 1 | # identify a layer by its filename 2 | 3 | # require the layer options 4 | layerOpts = require './layer-options' 5 | 6 | # some regexp constants 7 | reTOP = /top/i 8 | reBOTTOM = /bottom/i 9 | reSILK = /(silk)|(ss)/i 10 | reMASK = /(soldermask)|(sm)/i 11 | rePASTE = /(paste)|(sp)|(pm)/i 12 | 13 | module.exports = (name) -> 14 | type = '' 15 | # loop through the layer types, and if one of the regexps hits, then return 16 | for opt in layerOpts 17 | if opt.match.test name 18 | return opt.val 19 | # else, we still haven't figured it out, so we'll get a little fancier 20 | name = name.split('.')[0] 21 | # top or bottom 22 | # also grab the length of the match 23 | if len = name.match(reTOP)?[0]?.length then type = 't' 24 | else if len = name.match(reBOTTOM)?[0]?.length then type = 'b' 25 | # function 26 | if reSILK.test name then type += 'ss' 27 | else if reMASK.test name then type += 'sm' 28 | else if rePASTE.test name then type += 'sp' 29 | # assume it's copper if filename is 'top' or 'bottom' by itself 30 | else if name.length is len then type += 'cu' 31 | # make sure we don't return something invalid 32 | unless _.find layerOpts, { val: type } then type = 'drw' 33 | # return what we found 34 | type 35 | -------------------------------------------------------------------------------- /src/index.coffee: -------------------------------------------------------------------------------- 1 | # main svgerber site application 2 | # svgerber.cousins.io 3 | 4 | # requires jquery, backbone, and lodash 5 | 6 | # btoa polyfill 7 | Base64 = require 'Base64' 8 | unless typeof window.btoa is 'function' then window.btoa = Base64.btoa 9 | unless typeof window.atob is 'function' then window.atob = Base64.atob 10 | 11 | # TODO: webworker polyfill? will need to do something for IE9 support 12 | # check browser support, and attach error message to dom if necessary 13 | # check for svg support 14 | if typeof document.createElement('svg').getAttributeNS is 'undefined' or 15 | # check for web worker support 16 | typeof Worker is 'undefined' or 17 | typeof FileReader is 'undefined' 18 | unsupported = new (require './views/unsupported-view')() 19 | $('body').append unsupported.render().el 20 | 21 | # DEPRECATE 22 | deprecated = new (require './views/deprecated-view')() 23 | $('body').append deprecated.render().el 24 | 25 | # load the backbone application view to start the app 26 | AppView = require './views/app-view' 27 | appView = new AppView() 28 | # start the router 29 | Router = require './routers/router' 30 | router = new Router() 31 | Backbone.history.start() 32 | -------------------------------------------------------------------------------- /src/layer-options.coffee: -------------------------------------------------------------------------------- 1 | # all the available types of gerber layers 2 | module.exports = [ 3 | { 4 | val: 'tcu' 5 | desc: 'top copper' 6 | match: /\.(gtl)|(cmp)$/i 7 | side: 'top' 8 | mult: false 9 | } 10 | { 11 | val: 'tsm' 12 | desc: 'top soldermask' 13 | match: /\.(gts)|(stc)$/i 14 | side: 'top' 15 | mult: false 16 | } 17 | { 18 | val: 'tss' 19 | desc: 'top silkscreen' 20 | match: /\.(gto)|(plc)$/i 21 | side: 'top' 22 | mult: false 23 | } 24 | { 25 | val: 'tsp', 26 | desc: 'top solderpaste' 27 | match: /\.(gtp)|(crc)$/i 28 | side: 'top' 29 | mult: false 30 | } 31 | { 32 | val: 'bcu' 33 | desc: 'bottom copper' 34 | match: /\.(gbl)|(sol)$/i 35 | side: 'bottom' 36 | mult: false 37 | } 38 | { 39 | val: 'bsm' 40 | desc: 'bottom soldermask' 41 | match: /\.(gbs)|(sts)$/i 42 | side: 'bottom' 43 | mult: false 44 | } 45 | { 46 | val: 'bss', 47 | desc: 'bottom silkscreen' 48 | match: /\.(gbo)|(pls)$/i 49 | side: 'bottom' 50 | mult: false 51 | } 52 | { 53 | val: 'bsp' 54 | desc: 'bottom solderpaste' 55 | match: /\.(gbp)|(crs)$/i 56 | side: 'bottom' 57 | mult: false 58 | } 59 | { 60 | val: 'icu' 61 | desc: 'inner copper' 62 | match: /\.(gp\d+)|(g\d+l)$/i 63 | side: 'none' 64 | mult: true 65 | } 66 | { 67 | val: 'out' 68 | desc: 'board outline' 69 | match: /(\.(gko)|(mil)$)|edge/i 70 | side: 'both' 71 | mult: false 72 | } 73 | { 74 | val: 'drw' 75 | desc: 'gerber drawing' 76 | match: /\.gbr$/i 77 | side: 'none' 78 | mult: true 79 | } 80 | { 81 | val: 'drl' 82 | desc: 'drill hits' 83 | match: /(\.xln$)|(\.drl$)|(\.txt$)|(\.drd$)/i 84 | side: 'both' 85 | mult: true 86 | } 87 | ] 88 | -------------------------------------------------------------------------------- /src/models/board.coffee: -------------------------------------------------------------------------------- 1 | # backbone model of a board stackup 2 | 3 | # render prototype 4 | Render = require './render' 5 | 6 | # requires the layer collection and options 7 | LayerList = require '../collections/layers' 8 | layerOptions = require '../layer-options' 9 | 10 | # watches a layer collection 11 | class Board extends Render 12 | defaults: _.extend { 13 | boardLayers: {} 14 | style: ' 15 | 24 | ' 25 | }, Render.prototype.defaults 26 | 27 | initialize: -> 28 | layers = @get 'layers' 29 | # listen for changes in the layers, and trigger a new board event 30 | @listenTo layers, 'change:type change:svg change:gerber remove', 31 | _.debounce @handleLayersChange, 10 32 | 33 | getBoardLayers: -> 34 | # filter out the layers 35 | type = @get 'name' 36 | boardLayers = @get('layers').filter (layer) -> 37 | opt = _.find layerOptions, { val: layer.get 'type' } 38 | # return true if the board side of the option matches the board type 39 | opt?.side is type or opt?.side is 'both' 40 | # set layers 41 | @set 'boardLayers', _.map boardLayers, (ly) -> 42 | { type: ly.get('type'), svgObj: ly.get('svgObj') } 43 | # set mult layers 44 | # trigger a build needed event 45 | @trigger 'buildNeeded', @ 46 | 47 | handleLayersChange: -> 48 | layers = @get 'layers' 49 | # if there are layers and they passes validation 50 | if layers.validateLayers() 51 | # and the lenth of the collection matches the number of processed layers 52 | processed = (layers.filter (layer) -> layer.get('svgObj')?) ? [] 53 | if layers.length is processed.length 54 | # get the board layers and trigger a build 55 | @getBoardLayers() 56 | 57 | module.exports = Board 58 | -------------------------------------------------------------------------------- /src/models/layer.coffee: -------------------------------------------------------------------------------- 1 | # gerber layer model 2 | 3 | # render prototype 4 | Render = require './render' 5 | 6 | # available layer types and idetifier utility 7 | layerOpts = require '../layer-options' 8 | idLayer = require '../identify-layer' 9 | 10 | class Layer extends Render 11 | defaults: _.extend { 12 | gerber: '' 13 | type: 'drw' 14 | svgObj: null 15 | }, Render.prototype.defaults 16 | 17 | # on creation, get a default layer type 18 | initialize: -> 19 | # once we've got an svgObj, we don't need the gerber file anymore 20 | # if we're processed, we should also set the layer type 21 | @once 'change:svgObj', -> 22 | @unset 'gerber' 23 | @setLayerType() 24 | # once we get a warnings array, we should process it 25 | @once 'change:warnings', -> 26 | consolidated = {} 27 | for w in @get 'warnings' 28 | consolidated[w] = if consolidated[w]? then consolidated[w]+1 else 1 29 | @set 'warnings', _.map consolidated, (n, w) -> 30 | w + (if n > 1 then " - x#{n}" else '') 31 | @trigger 'warningsConsolidated' 32 | 33 | setLayerType: -> 34 | @set 'type', 35 | if Object.keys(@get 'svgObj').length then idLayer @get 'name' else 'oth' 36 | 37 | # validation 38 | # checks to make sure that if its layer type is singular, that no other models 39 | # in the collection identify as the same layer 40 | validate: (attrs, options) -> 41 | # if the type isn't other and the selected layer type must be singular 42 | if attrs.type isnt 'oth' and not _.find(layerOpts, {val: attrs.type}).mult 43 | # pull all the models from the collection with the same layer type 44 | layers = @collection.where { type: attrs.type } 45 | if layers.length isnt 1 46 | console.log "#{attrs.name} failed validation with #{attrs.type}" 47 | return "duplicate layer selection" 48 | # return nothing if valid 49 | return null 50 | 51 | module.exports = Layer 52 | -------------------------------------------------------------------------------- /src/models/render.coffee: -------------------------------------------------------------------------------- 1 | # prototype render model for individual layers as well as board stackups 2 | 3 | class Render extends Backbone.Model 4 | # common defaults 5 | defaults: { 6 | # both layers and boards will have a name 7 | # boards will have 'top' and 'bottom', layers will have filenames 8 | name: '' 9 | # both will have an svg string, obj, and encoded string 10 | svg: '' 11 | svgObj: null 12 | svg64: false 13 | # any warnings from gerber-to-svg 14 | warnings: [] 15 | } 16 | 17 | module.exports = Render 18 | -------------------------------------------------------------------------------- /src/routers/router.coffee: -------------------------------------------------------------------------------- 1 | # router 2 | # navigation sugar 3 | navHeight = $('#main-nav').height() 4 | 5 | module.exports = Backbone.Router.extend { 6 | 7 | initialize: -> 8 | @route /.*/, @scroll 9 | 10 | scroll: (route) -> 11 | frag = Backbone.history.fragment 12 | anchor = ".#{frag}-anchor" 13 | $('html, body').animate { 14 | scrollTop: if frag then $(anchor).offset().top - 1.15*navHeight else 0 15 | }, 300 16 | } 17 | -------------------------------------------------------------------------------- /src/views/app-view.coffee: -------------------------------------------------------------------------------- 1 | # svgerber backbone app 2 | 3 | # utilities 4 | githubApiUrl = require '../github-api-url' 5 | 6 | # require our other views 7 | FilelistItemView = require './filelist-item' 8 | LayerView = require './layer-view' 9 | BoardView = require './board-view' 10 | ColorPickerView = require './color-picker' 11 | ModalView = require './modal-view' 12 | 13 | # create a layers collection 14 | LayerList = require '../collections/layers' 15 | layers = new LayerList() 16 | # create collection for board renders with the top and the bottom 17 | BoardList = require '../collections/boards' 18 | boards = new BoardList() 19 | boards.add [ 20 | { name: 'top', layers: layers } 21 | { name: 'bottom', layers: layers } 22 | ] 23 | 24 | # create the modal 25 | modal = new ModalView() 26 | 27 | module.exports = Backbone.View.extend { 28 | el: '#svgerber-app' 29 | 30 | # app events 31 | events: { 32 | # file upload events 33 | # dropzone file drop 34 | 'drop #dropzone': 'handleFileSelect' 35 | # dropzone dragover - stop browser from opening file and show copy tooltip 36 | 'dragover #dropzone': (e) -> 37 | e.preventDefault() 38 | e.stopPropagation() 39 | e.originalEvent.dataTransfer.dropEffect = 'copy' 40 | # manual file select 41 | 'change #upload-select': 'handleFileSelect' 42 | # load samples when the sample button is clicked 43 | 'click #sample-btn': 'loadSamples' 44 | # url paste buttons 45 | 'click #url-paste-btn': 'showPaste' 46 | 'click #url-submit-btn': 'processUrls' 47 | 'click #url-cancel-btn': 'hidePaste' 48 | } 49 | 50 | initialize: -> 51 | # log so I don't go insane 52 | console.log 'svgerber app started' 53 | # listen to the layers collection for additions 54 | @listenTo layers, 'add', @addFilelistItem 55 | # listen to the layers collection for rendered layers 56 | @listenTo layers, 'processEnd', @addBoardLayer 57 | # create renders for the top and bottom boards 58 | @listenTo boards, 'change:svg', @addBoardRender 59 | # add or remove color picker if necessary 60 | @listenTo boards, 'change:svg', @handleColorPicker 61 | # listen to the layers collection for adds and removed 62 | # adjust nav icons accordingly 63 | @listenTo layers, 'add remove', @handleNavIcons 64 | # attach the modal view and listen for open modal events 65 | @$el.append modal.render().el 66 | @listenTo layers, 'openModal', @handleOpenModal 67 | @listenTo boards, 'openModal', @handleOpenModal 68 | 69 | 70 | 71 | 72 | # remove all models from the layers collection 73 | restart: -> layers.remove layers.models 74 | 75 | # add a filelist item to the filelist 76 | addFilelistItem: (layer) -> 77 | # add to the filelist if necessary 78 | view = new FilelistItemView { model: layer } 79 | $('#filelist').append view.render().el 80 | 81 | # add a board layer 82 | addBoardLayer: (layer) -> 83 | if layer.get('svg').length 84 | view = new LayerView { model: layer } 85 | $('#layer-output').append view.render().el 86 | 87 | # add a board render if needed 88 | addBoardRender: (board) -> 89 | existing = $('#board-output').find('.LayerHeading').text() 90 | if board.get('svg').length and not existing.match(board.get 'name')? 91 | view = new BoardView { model: board } 92 | $('#board-output').append view.render().el 93 | 94 | # handle an open modal event 95 | handleOpenModal: (render) -> modal.openModal render 96 | 97 | # add color picker to the page if it's not there 98 | handleColorPicker: (boards) -> 99 | # if there's no color picker 100 | pickerExists = $('#board-output').siblings('.ColorPicker').length 101 | boardsExist = $('#board-output').children().length 102 | if not pickerExists and boardsExist 103 | view = new ColorPickerView { collection: boards } 104 | $('#board-output').after view.render().el 105 | 106 | # handle a file select 107 | # take care of a file event 108 | handleFileSelect: (e) -> 109 | # stop bubbling 110 | e.preventDefault() 111 | e.stopPropagation() 112 | # take care of a drop or file select 113 | importFiles = e.originalEvent?.dataTransfer?.files 114 | unless importFiles? then importFiles = e.target.files 115 | # read the files to the file list 116 | for f in importFiles 117 | do (f) -> 118 | # add the layer to the collection 119 | layers.add { name: f.name }, { validate: true } 120 | # create a file reader and attach a load end listener 121 | reader = new FileReader() 122 | reader.onloadend = (event) -> 123 | event.stopPropagation() 124 | event.preventDefault() 125 | # set the gerber of the layer 126 | if event.target.readyState is FileReader.DONE 127 | (layers.findWhere { name: f.name }).set 'gerber', event.target.result 128 | # read the file as text 129 | reader.readAsText f 130 | # return false to stop propagation 131 | false 132 | 133 | # laod samples from server 134 | loadSamples: -> 135 | samples = [ 136 | 'clockblock-hub-B_Cu.gbl' 137 | 'clockblock-hub-B_Mask.gbs' 138 | 'clockblock-hub-B_SilkS.gbo' 139 | 'clockblock-hub-Edge_Cuts.gbr' 140 | 'clockblock-hub-F_Cu.gtl' 141 | 'clockblock-hub-F_Mask.gts' 142 | 'clockblock-hub-F_Paste.gtp' 143 | 'clockblock-hub-F_SilkS.gto' 144 | 'clockblock-hub-NPTH.drl' 145 | 'clockblock-hub.drl' 146 | ] 147 | # remove all models from the layers collection 148 | @restart() 149 | # get the samples from the server 150 | for s in samples 151 | do (s) -> 152 | # add the layer to the collection 153 | layers.add { name: s }, { validate: true } 154 | # get the file contents 155 | $.ajax { 156 | type: 'GET' 157 | url: "./#{s}" 158 | dataType: 'text' 159 | success: (data) -> (layers.findWhere { name: s }).set 'gerber', data 160 | } 161 | 162 | # show and hide the url paste area 163 | showPaste: -> 164 | $('#url-paste-form').removeClass 'is-hidden' 165 | hidePaste: -> 166 | $('#url-paste').val '' 167 | $('#url-paste-form').addClass 'is-hidden' 168 | 169 | # get urls 170 | processUrls: -> 171 | urls = $('#url-paste').val().split '\n' 172 | for u in urls 173 | u = githubApiUrl u 174 | if u then $.ajax { 175 | type: 'GET' 176 | url: u 177 | contentType: 'application/vnd.github.VERSION.raw' 178 | dataType: 'json' 179 | success: (data) -> 180 | layers.add { name: data.name }, { validate: true } 181 | (layers.findWhere { name: data.name }).set 'gerber', data.content 182 | } 183 | @hidePaste() 184 | 185 | # handle navigation icons 186 | handleNavIcons: -> 187 | if layers.length is 0 188 | $('#nav-filelist, #nav-output, #nav-layers').addClass 'is-disabled' 189 | @changeIcon $('.Nav--brand'), 'octicon-jump-up' 190 | $('#nav-top').off 'click', @restart 191 | else 192 | $('#nav-filelist, #nav-output, #nav-layers').removeClass 'is-disabled' 193 | @changeIcon $('.Nav--brand'), 'octicon-sync' 194 | $('#nav-top').on 'click', @restart 195 | 196 | # change icon helper 197 | changeIcon: (element, newIcon) -> 198 | element.removeClass( (i, c) -> c.match(/octicon-\S+/g)?.join ' ') 199 | .addClass newIcon 200 | 201 | } 202 | -------------------------------------------------------------------------------- /src/views/board-view.coffee: -------------------------------------------------------------------------------- 1 | # view for board stackup render 2 | # extends render view 3 | RenderView = require './render-view' 4 | 5 | class BoardView extends RenderView 6 | 7 | className: 'BoardContainer' 8 | 9 | # initialize with change listener on model 10 | initialize: -> 11 | # call super 12 | super() 13 | # listen for type changes 14 | @listenTo @model, 'change:svg change:style', @render 15 | 16 | # render function 17 | render: -> 18 | super() 19 | svg = @model.get 'svg' 20 | @$('.LayerTitle').html "board #{@model.get 'name'}" 21 | @$('svg').prepend @model.get 'style' 22 | # return this 23 | if svg.length then @ else @model.trigger 'renderRemove'; @remove() 24 | 25 | module.exports = BoardView 26 | -------------------------------------------------------------------------------- /src/views/color-picker.coffee: -------------------------------------------------------------------------------- 1 | # color picker view / controller for the boards 2 | 3 | # pull in color options 4 | colorOpts = require '../color-options' 5 | 6 | module.exports = Backbone.View.extend { 7 | tagName: 'div' 8 | className: 'ColorPicker' 9 | template: _.template $('#color-picker-template').html() 10 | 11 | events: { 12 | # color button click 13 | 'click .ColorPicker--btn': 'handleColorChange' 14 | # show color picker button 15 | 'click #show-color-picker-btn': 'toggleColorPicker' 16 | } 17 | 18 | # on initialization, it should listen to the board collection for changes 19 | initialize: -> 20 | # listen to the board collection for changes 21 | @listenTo @collection.collection, 'renderRemove', @handleBoardRemoval 22 | 23 | render: -> 24 | @$el.html @template { 25 | cfColors: colorOpts.cf 26 | smColors: colorOpts.sm 27 | ssColors: colorOpts.ss 28 | } 29 | @$el.find('.ColorPicker--box').addClass 'is-retracted' 30 | @$el.find('.ColorPicker--btn').each -> 31 | btn = $ @ 32 | layer = btn.parent().attr('id')[6..7] 33 | opt = btn.html() 34 | color = colorOpts[layer][opt] 35 | btn.css('background-color', color.bg).css 'color', color.txt 36 | # disable buttons as necessary 37 | @getCurrentColors() 38 | # return self 39 | @ 40 | 41 | getCurrentColors: -> 42 | boardStyles = @collection.collection.pluck 'style' 43 | style = boardStyles[0] 44 | for layer in [ 'cf', 'sm', 'ss' ] 45 | reStyle = new RegExp "\.Board--#{layer} { color: .*?;" 46 | match = style.match reStyle 47 | color = match[0][20...-1] 48 | opts = colorOpts[layer] 49 | opt = _.findKey opts, _.find opts, (o) -> o.bg is color 50 | @$el.find("#board-#{layer}-color-buttons").children().each -> 51 | if (btn = $ @).html() is opt then btn.prop 'disabled', true 52 | 53 | handleColorChange: (e) -> 54 | btn = $ e.currentTarget 55 | # re-enable other buttons and disable clicked button 56 | btn.prop('disabled', true).siblings().prop 'disabled', false 57 | # delay a little to let the enables and disables stick 58 | _.delay (self) -> 59 | # get the color button that was clicked 60 | layer = btn.parent().attr('id')[6..7] 61 | opt = btn.html() 62 | color = colorOpts[layer][opt].bg 63 | switch layer 64 | when 'cf' 65 | newStyle = ".Board--cf { color: #{color}; }" 66 | reStyle = /\.Board--cf {.*?}/ 67 | when 'sm' 68 | newStyle = ".Board--sm { color: #{color}; opacity: 0.75; }" 69 | reStyle = /\.Board--sm {.*?}/ 70 | when 'ss' 71 | newStyle = ".Board--ss { color: #{color}; }" 72 | reStyle = /\.Board--ss {.*?}/ 73 | # replace the appropriate part of the svg string 74 | self.collection.collection.each (board) -> 75 | board.set 'style', board.get('style').replace reStyle, newStyle 76 | # end delay function 77 | , 10, @ 78 | 79 | handleBoardRemoval: -> 80 | boardsExist = false 81 | @collection.collection.each (board) -> 82 | if board.get('svg').length then boardsExist = true 83 | if not boardsExist then @remove() 84 | 85 | toggleColorPicker: -> 86 | picker = $ '.ColorPicker--box' 87 | btnIcon = $('#show-color-picker-btn').children('.octicon') 88 | # if it's retracted, remove the retracted class and switch the button icon 89 | if picker.hasClass 'is-retracted' 90 | picker.removeClass 'is-retracted' 91 | @changeIcon btnIcon, 'octicon-chevron-up' 92 | # else, make sure that the color picker exists 93 | else if picker.length 94 | picker.addClass 'is-retracted' 95 | @changeIcon btnIcon, 'octicon-chevron-down' 96 | 97 | # change icon helper 98 | changeIcon: (element, newIcon) -> 99 | element.removeClass( (i, c) -> c.match(/octicon-\S+/g)?.join ' ') 100 | .addClass newIcon 101 | } 102 | -------------------------------------------------------------------------------- /src/views/deprecated-view.coffee: -------------------------------------------------------------------------------- 1 | # svgerber is dead 2 | # long live viewer.tracespace.io 3 | 4 | REDIRECT_URL = 'http://viewer.tracespace.io' 5 | REDIRECT_WAIT = 7 6 | 7 | remainingTime = REDIRECT_WAIT 8 | 9 | class DeprecatedView extends Backbone.View 10 | tagName: 'div' 11 | className: 'Deprecated' 12 | 13 | # cache the template 14 | template: _.template $('#deprecated-template').html() 15 | 16 | events: { 17 | 'click .Deprecated--leave-btn': 'leave', 18 | 'click .Deprecated--stay-btn': 'stay' 19 | } 20 | 21 | initialize: -> 22 | remainingTime = REDIRECT_WAIT 23 | 24 | tick = => 25 | if --remainingTime is 0 26 | @leave() 27 | else 28 | @setRemainingTime(remainingTime) 29 | 30 | @countdown = setInterval(tick, 1000) 31 | 32 | setRemainingTime: (time) -> 33 | units = if time isnt 1 then 'seconds' else 'second' 34 | 35 | @$("[data-hook='time']").html "#{time} #{units}" 36 | 37 | render: -> 38 | @$el.html @template() 39 | @setRemainingTime(REDIRECT_WAIT) 40 | this 41 | 42 | stay: -> 43 | clearInterval @countdown 44 | @$el.remove() 45 | 46 | leave: -> 47 | window.location.assign REDIRECT_URL 48 | 49 | module.exports = DeprecatedView 50 | -------------------------------------------------------------------------------- /src/views/filelist-item.coffee: -------------------------------------------------------------------------------- 1 | # backbone view for a filelist item 2 | 3 | # require the gerber layer options 4 | layerOptions = require '../layer-options' 5 | 6 | module.exports = Backbone.View.extend { 7 | # dom element is a list item with some classes 8 | tagName: 'li' 9 | className: 'UploadList--item' 10 | # cached template function 11 | template: _.template $('#filelist-item-template').html() 12 | 13 | # events 14 | events: { 15 | # delete button 16 | 'click .UploadList--itemDelete': 'removeLayer' 17 | # layer select 18 | 'change .UploadList--SelectMenu': 'changeLayerType' 19 | # don't let a click on the select menu bubble up the DOM 20 | 'click .UploadList--SelectMenu': (e) -> e.stopPropagation() 21 | # click on item 22 | 'click': 'showWarnings' 23 | } 24 | 25 | initialize: -> 26 | # delete self on model deletion 27 | @listenTo @model, 'remove', @remove 28 | # listen for type changes 29 | @listenTo @model, 'change:type', @renderType 30 | # attach event listener to model for validations 31 | @listenTo @model, 'valid invalid', @renderValidation 32 | # attach event listener to process and processend events 33 | @listenToOnce @model, 'processEnd', @renderProcessing 34 | # attach listener to warningsConsolidated event 35 | @listenToOnce @model, 'warningsConsolidated', @renderWarnings 36 | 37 | renderValidation: -> 38 | icon = @$el.find '.UploadList--selectIcon' 39 | if @model.validationError 40 | @$el.removeClass('is-valid').addClass 'is-invalid' 41 | @changeIcon icon, 'octicon-circle-slash' 42 | else 43 | @$el.removeClass('is-invalid').addClass 'is-valid' 44 | @changeIcon icon, 'octicon-chevron-right' 45 | 46 | renderProcessing: -> 47 | # default value is null, so if there's an object we're done 48 | if @model.get('svgObj')? 49 | @$el.removeClass 'is-processing' 50 | # if the svg came back, empty, though, there was a processing error 51 | if not @model.get 'svg' 52 | @$el.addClass 'is-unprocessable' 53 | @$el.find('.UploadList--text').html 'did not process' 54 | @$el.find('select.UploadList--SelectMenu').remove() 55 | else 56 | @$el.addClass 'is-processing' 57 | 58 | renderWarnings: -> 59 | warnings = @model.get 'warnings' 60 | if warnings.length 61 | @$el.addClass 'is-warned' 62 | ul = @$('.UploadList--itemWarnings') 63 | ul.html ("