├── 13.jpg ├── 13.png ├── 328-dip.jpg ├── 328-mlf28.jpg ├── 328.jpg ├── 328.png ├── LICENSE ├── README.md ├── core.js ├── gogo.js ├── index.html ├── more.js ├── templates.js ├── tiny4,9.jpg ├── tiny4,9.png ├── tiny5,10.jpg ├── tiny5,10.png ├── tiny828.jpg ├── x4-alt.jpg ├── x4-alt.png ├── x4.jpg ├── x4.png ├── x5.jpg └── x5.png /13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleemanj/ArduinoOrientedChipPinoutCreator/fcbb550b228ac05cd2431d088f6923cf2730f129/13.jpg -------------------------------------------------------------------------------- /13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleemanj/ArduinoOrientedChipPinoutCreator/fcbb550b228ac05cd2431d088f6923cf2730f129/13.png -------------------------------------------------------------------------------- /328-dip.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleemanj/ArduinoOrientedChipPinoutCreator/fcbb550b228ac05cd2431d088f6923cf2730f129/328-dip.jpg -------------------------------------------------------------------------------- /328-mlf28.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleemanj/ArduinoOrientedChipPinoutCreator/fcbb550b228ac05cd2431d088f6923cf2730f129/328-mlf28.jpg -------------------------------------------------------------------------------- /328.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleemanj/ArduinoOrientedChipPinoutCreator/fcbb550b228ac05cd2431d088f6923cf2730f129/328.jpg -------------------------------------------------------------------------------- /328.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sleemanj/ArduinoOrientedChipPinoutCreator/fcbb550b228ac05cd2431d088f6923cf2730f129/328.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 James Sleeman 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # James' Dodgy Arduino-Oriented Pinout Maker For Microcontrollers 2 | 3 | A quick-and-dirty tool to create a simple Arduino-oriented pinout diagrams of a Microcontroller (2 sided or 4 sided) IC from a JSON based description of the IC. 4 | 5 | Download/Clone and open the index.html in your browser (no server required). 6 | 7 | Tested in Chrome only. 8 | 9 | A few templates have been built in you can select from, and hit the Draw It button. 10 | 11 | If you want to create a new template, open the templates.js file and you will find it well commented and easy to understand. 12 | 13 | Examples 14 | --- 15 | 16 | ### ATTiny13 17 |  18 | 19 | ### ATMega328 QFP/MLF32 20 |  21 | -------------------------------------------------------------------------------- /core.js: -------------------------------------------------------------------------------- 1 | /* 2 | --- 3 | MooTools: the javascript framework 4 | 5 | web build: 6 | - http://mootools.net/core/7c56cfef9dddcf170a5d68e3fb61cfd7 7 | 8 | packager build: 9 | - packager build Core/Core Core/Array Core/String Core/Number Core/Function Core/Object Core/Event Core/Browser Core/Class Core/Class.Extras Core/Slick.Parser Core/Slick.Finder Core/Element Core/Element.Style Core/Element.Event Core/Element.Dimensions Core/Fx Core/Fx.CSS Core/Fx.Tween Core/Fx.Morph Core/Fx.Transitions Core/Request Core/Request.HTML Core/Request.JSON Core/Cookie Core/JSON Core/DOMReady Core/Swiff 10 | 11 | /* 12 | --- 13 | 14 | name: Core 15 | 16 | description: The heart of MooTools. 17 | 18 | license: MIT-style license. 19 | 20 | copyright: Copyright (c) 2006-2010 [Valerio Proietti](http://mad4milk.net/). 21 | 22 | authors: The MooTools production team (http://mootools.net/developers/) 23 | 24 | inspiration: 25 | - Class implementation inspired by [Base.js](http://dean.edwards.name/weblog/2006/03/base/) Copyright (c) 2006 Dean Edwards, [GNU Lesser General Public License](http://opensource.org/licenses/lgpl-license.php) 26 | - Some functionality inspired by [Prototype.js](http://prototypejs.org) Copyright (c) 2005-2007 Sam Stephenson, [MIT License](http://opensource.org/licenses/mit-license.php) 27 | 28 | provides: [Core, MooTools, Type, typeOf, instanceOf, Native] 29 | 30 | ... 31 | */ 32 | 33 | (function(){ 34 | 35 | this.MooTools = { 36 | version: '1.3.1', 37 | build: 'af48c8d589f43f32212f9bb8ff68a127e6a3ba6c' 38 | }; 39 | 40 | // typeOf, instanceOf 41 | 42 | var typeOf = this.typeOf = function(item){ 43 | if (item == null) return 'null'; 44 | if (item.$family) return item.$family(); 45 | 46 | if (item.nodeName){ 47 | if (item.nodeType == 1) return 'element'; 48 | if (item.nodeType == 3) return (/\S/).test(item.nodeValue) ? 'textnode' : 'whitespace'; 49 | } else if (typeof item.length == 'number'){ 50 | if (item.callee) return 'arguments'; 51 | if ('item' in item) return 'collection'; 52 | } 53 | 54 | return typeof item; 55 | }; 56 | 57 | var instanceOf = this.instanceOf = function(item, object){ 58 | if (item == null) return false; 59 | var constructor = item.$constructor || item.constructor; 60 | while (constructor){ 61 | if (constructor === object) return true; 62 | constructor = constructor.parent; 63 | } 64 | return item instanceof object; 65 | }; 66 | 67 | // Function overloading 68 | 69 | var Function = this.Function; 70 | 71 | var enumerables = true; 72 | for (var i in {toString: 1}) enumerables = null; 73 | if (enumerables) enumerables = ['hasOwnProperty', 'valueOf', 'isPrototypeOf', 'propertyIsEnumerable', 'toLocaleString', 'toString', 'constructor']; 74 | 75 | Function.prototype.overloadSetter = function(usePlural){ 76 | var self = this; 77 | return function(a, b){ 78 | if (a == null) return this; 79 | if (usePlural || typeof a != 'string'){ 80 | for (var k in a) self.call(this, k, a[k]); 81 | if (enumerables) for (var i = enumerables.length; i--;){ 82 | k = enumerables[i]; 83 | if (a.hasOwnProperty(k)) self.call(this, k, a[k]); 84 | } 85 | } else { 86 | self.call(this, a, b); 87 | } 88 | return this; 89 | }; 90 | }; 91 | 92 | Function.prototype.overloadGetter = function(usePlural){ 93 | var self = this; 94 | return function(a){ 95 | var args, result; 96 | if (usePlural || typeof a != 'string') args = a; 97 | else if (arguments.length > 1) args = arguments; 98 | if (args){ 99 | result = {}; 100 | for (var i = 0; i < args.length; i++) result[args[i]] = self.call(this, args[i]); 101 | } else { 102 | result = self.call(this, a); 103 | } 104 | return result; 105 | }; 106 | }; 107 | 108 | Function.prototype.extend = function(key, value){ 109 | this[key] = value; 110 | }.overloadSetter(); 111 | 112 | Function.prototype.implement = function(key, value){ 113 | this.prototype[key] = value; 114 | }.overloadSetter(); 115 | 116 | // From 117 | 118 | var slice = Array.prototype.slice; 119 | 120 | Function.from = function(item){ 121 | return (typeOf(item) == 'function') ? item : function(){ 122 | return item; 123 | }; 124 | }; 125 | 126 | Array.from = function(item){ 127 | if (item == null) return []; 128 | return (Type.isEnumerable(item) && typeof item != 'string') ? (typeOf(item) == 'array') ? item : slice.call(item) : [item]; 129 | }; 130 | 131 | Number.from = function(item){ 132 | var number = parseFloat(item); 133 | return isFinite(number) ? number : null; 134 | }; 135 | 136 | String.from = function(item){ 137 | return item + ''; 138 | }; 139 | 140 | // hide, protect 141 | 142 | Function.implement({ 143 | 144 | hide: function(){ 145 | this.$hidden = true; 146 | return this; 147 | }, 148 | 149 | protect: function(){ 150 | this.$protected = true; 151 | return this; 152 | } 153 | 154 | }); 155 | 156 | // Type 157 | 158 | var Type = this.Type = function(name, object){ 159 | if (name){ 160 | var lower = name.toLowerCase(); 161 | var typeCheck = function(item){ 162 | return (typeOf(item) == lower); 163 | }; 164 | 165 | Type['is' + name] = typeCheck; 166 | if (object != null){ 167 | object.prototype.$family = (function(){ 168 | return lower; 169 | }).hide(); 170 | //<1.2compat> 171 | object.type = typeCheck; 172 | //1.2compat> 173 | } 174 | } 175 | 176 | if (object == null) return null; 177 | 178 | object.extend(this); 179 | object.$constructor = Type; 180 | object.prototype.$constructor = object; 181 | 182 | return object; 183 | }; 184 | 185 | var toString = Object.prototype.toString; 186 | 187 | Type.isEnumerable = function(item){ 188 | return (item != null && typeof item.length == 'number' && toString.call(item) != '[object Function]' ); 189 | }; 190 | 191 | var hooks = {}; 192 | 193 | var hooksOf = function(object){ 194 | var type = typeOf(object.prototype); 195 | return hooks[type] || (hooks[type] = []); 196 | }; 197 | 198 | var implement = function(name, method){ 199 | if (method && method.$hidden) return; 200 | 201 | var hooks = hooksOf(this); 202 | 203 | for (var i = 0; i < hooks.length; i++){ 204 | var hook = hooks[i]; 205 | if (typeOf(hook) == 'type') implement.call(hook, name, method); 206 | else hook.call(this, name, method); 207 | } 208 | 209 | var previous = this.prototype[name]; 210 | if (previous == null || !previous.$protected) this.prototype[name] = method; 211 | 212 | if (this[name] == null && typeOf(method) == 'function') extend.call(this, name, function(item){ 213 | return method.apply(item, slice.call(arguments, 1)); 214 | }); 215 | }; 216 | 217 | var extend = function(name, method){ 218 | if (method && method.$hidden) return; 219 | var previous = this[name]; 220 | if (previous == null || !previous.$protected) this[name] = method; 221 | }; 222 | 223 | Type.implement({ 224 | 225 | implement: implement.overloadSetter(), 226 | 227 | extend: extend.overloadSetter(), 228 | 229 | alias: function(name, existing){ 230 | implement.call(this, name, this.prototype[existing]); 231 | }.overloadSetter(), 232 | 233 | mirror: function(hook){ 234 | hooksOf(this).push(hook); 235 | return this; 236 | } 237 | 238 | }); 239 | 240 | new Type('Type', Type); 241 | 242 | // Default Types 243 | 244 | var force = function(name, object, methods){ 245 | var isType = (object != Object), 246 | prototype = object.prototype; 247 | 248 | if (isType) object = new Type(name, object); 249 | 250 | for (var i = 0, l = methods.length; i < l; i++){ 251 | var key = methods[i], 252 | generic = object[key], 253 | proto = prototype[key]; 254 | 255 | if (generic) generic.protect(); 256 | 257 | if (isType && proto){ 258 | delete prototype[key]; 259 | prototype[key] = proto.protect(); 260 | } 261 | } 262 | 263 | if (isType) object.implement(prototype); 264 | 265 | return force; 266 | }; 267 | 268 | force('String', String, [ 269 | 'charAt', 'charCodeAt', 'concat', 'indexOf', 'lastIndexOf', 'match', 'quote', 'replace', 'search', 270 | 'slice', 'split', 'substr', 'substring', 'toLowerCase', 'toUpperCase' 271 | ])('Array', Array, [ 272 | 'pop', 'push', 'reverse', 'shift', 'sort', 'splice', 'unshift', 'concat', 'join', 'slice', 273 | 'indexOf', 'lastIndexOf', 'filter', 'forEach', 'every', 'map', 'some', 'reduce', 'reduceRight' 274 | ])('Number', Number, [ 275 | 'toExponential', 'toFixed', 'toLocaleString', 'toPrecision' 276 | ])('Function', Function, [ 277 | 'apply', 'call', 'bind' 278 | ])('RegExp', RegExp, [ 279 | 'exec', 'test' 280 | ])('Object', Object, [ 281 | 'create', 'defineProperty', 'defineProperties', 'keys', 282 | 'getPrototypeOf', 'getOwnPropertyDescriptor', 'getOwnPropertyNames', 283 | 'preventExtensions', 'isExtensible', 'seal', 'isSealed', 'freeze', 'isFrozen' 284 | ])('Date', Date, ['now']); 285 | 286 | Object.extend = extend.overloadSetter(); 287 | 288 | Date.extend('now', function(){ 289 | return +(new Date); 290 | }); 291 | 292 | new Type('Boolean', Boolean); 293 | 294 | // fixes NaN returning as Number 295 | 296 | Number.prototype.$family = function(){ 297 | return isFinite(this) ? 'number' : 'null'; 298 | }.hide(); 299 | 300 | // Number.random 301 | 302 | Number.extend('random', function(min, max){ 303 | return Math.floor(Math.random() * (max - min + 1) + min); 304 | }); 305 | 306 | // forEach, each 307 | 308 | var hasOwnProperty = Object.prototype.hasOwnProperty; 309 | Object.extend('forEach', function(object, fn, bind){ 310 | for (var key in object){ 311 | if (hasOwnProperty.call(object, key)) fn.call(bind, object[key], key, object); 312 | } 313 | }); 314 | 315 | Object.each = Object.forEach; 316 | 317 | Array.implement({ 318 | 319 | forEach: function(fn, bind){ 320 | for (var i = 0, l = this.length; i < l; i++){ 321 | if (i in this) fn.call(bind, this[i], i, this); 322 | } 323 | }, 324 | 325 | each: function(fn, bind){ 326 | Array.forEach(this, fn, bind); 327 | return this; 328 | } 329 | 330 | }); 331 | 332 | // Array & Object cloning, Object merging and appending 333 | 334 | var cloneOf = function(item){ 335 | switch (typeOf(item)){ 336 | case 'array': return item.clone(); 337 | case 'object': return Object.clone(item); 338 | default: return item; 339 | } 340 | }; 341 | 342 | Array.implement('clone', function(){ 343 | var i = this.length, clone = new Array(i); 344 | while (i--) clone[i] = cloneOf(this[i]); 345 | return clone; 346 | }); 347 | 348 | var mergeOne = function(source, key, current){ 349 | switch (typeOf(current)){ 350 | case 'object': 351 | if (typeOf(source[key]) == 'object') Object.merge(source[key], current); 352 | else source[key] = Object.clone(current); 353 | break; 354 | case 'array': source[key] = current.clone(); break; 355 | default: source[key] = current; 356 | } 357 | return source; 358 | }; 359 | 360 | Object.extend({ 361 | 362 | merge: function(source, k, v){ 363 | if (typeOf(k) == 'string') return mergeOne(source, k, v); 364 | for (var i = 1, l = arguments.length; i < l; i++){ 365 | var object = arguments[i]; 366 | for (var key in object) mergeOne(source, key, object[key]); 367 | } 368 | return source; 369 | }, 370 | 371 | clone: function(object){ 372 | var clone = {}; 373 | for (var key in object) clone[key] = cloneOf(object[key]); 374 | return clone; 375 | }, 376 | 377 | append: function(original){ 378 | for (var i = 1, l = arguments.length; i < l; i++){ 379 | var extended = arguments[i] || {}; 380 | for (var key in extended) original[key] = extended[key]; 381 | } 382 | return original; 383 | } 384 | 385 | }); 386 | 387 | // Object-less types 388 | 389 | ['Object', 'WhiteSpace', 'TextNode', 'Collection', 'Arguments'].each(function(name){ 390 | new Type(name); 391 | }); 392 | 393 | // Unique ID 394 | 395 | var UID = Date.now(); 396 | 397 | String.extend('uniqueID', function(){ 398 | return (UID++).toString(36); 399 | }); 400 | 401 | //<1.2compat> 402 | 403 | var Hash = this.Hash = new Type('Hash', function(object){ 404 | if (typeOf(object) == 'hash') object = Object.clone(object.getClean()); 405 | for (var key in object) this[key] = object[key]; 406 | return this; 407 | }); 408 | 409 | Hash.implement({ 410 | 411 | forEach: function(fn, bind){ 412 | Object.forEach(this, fn, bind); 413 | }, 414 | 415 | getClean: function(){ 416 | var clean = {}; 417 | for (var key in this){ 418 | if (this.hasOwnProperty(key)) clean[key] = this[key]; 419 | } 420 | return clean; 421 | }, 422 | 423 | getLength: function(){ 424 | var length = 0; 425 | for (var key in this){ 426 | if (this.hasOwnProperty(key)) length++; 427 | } 428 | return length; 429 | } 430 | 431 | }); 432 | 433 | Hash.alias('each', 'forEach'); 434 | 435 | Object.type = Type.isObject; 436 | 437 | var Native = this.Native = function(properties){ 438 | return new Type(properties.name, properties.initialize); 439 | }; 440 | 441 | Native.type = Type.type; 442 | 443 | Native.implement = function(objects, methods){ 444 | for (var i = 0; i < objects.length; i++) objects[i].implement(methods); 445 | return Native; 446 | }; 447 | 448 | var arrayType = Array.type; 449 | Array.type = function(item){ 450 | return instanceOf(item, Array) || arrayType(item); 451 | }; 452 | 453 | this.$A = function(item){ 454 | return Array.from(item).slice(); 455 | }; 456 | 457 | this.$arguments = function(i){ 458 | return function(){ 459 | return arguments[i]; 460 | }; 461 | }; 462 | 463 | this.$chk = function(obj){ 464 | return !!(obj || obj === 0); 465 | }; 466 | 467 | this.$clear = function(timer){ 468 | clearTimeout(timer); 469 | clearInterval(timer); 470 | return null; 471 | }; 472 | 473 | this.$defined = function(obj){ 474 | return (obj != null); 475 | }; 476 | 477 | this.$each = function(iterable, fn, bind){ 478 | var type = typeOf(iterable); 479 | ((type == 'arguments' || type == 'collection' || type == 'array' || type == 'elements') ? Array : Object).each(iterable, fn, bind); 480 | }; 481 | 482 | this.$empty = function(){}; 483 | 484 | this.$extend = function(original, extended){ 485 | return Object.append(original, extended); 486 | }; 487 | 488 | this.$H = function(object){ 489 | return new Hash(object); 490 | }; 491 | 492 | this.$merge = function(){ 493 | var args = Array.slice(arguments); 494 | args.unshift({}); 495 | return Object.merge.apply(null, args); 496 | }; 497 | 498 | this.$lambda = Function.from; 499 | this.$mixin = Object.merge; 500 | this.$random = Number.random; 501 | this.$splat = Array.from; 502 | this.$time = Date.now; 503 | 504 | this.$type = function(object){ 505 | var type = typeOf(object); 506 | if (type == 'elements') return 'array'; 507 | return (type == 'null') ? false : type; 508 | }; 509 | 510 | this.$unlink = function(object){ 511 | switch (typeOf(object)){ 512 | case 'object': return Object.clone(object); 513 | case 'array': return Array.clone(object); 514 | case 'hash': return new Hash(object); 515 | default: return object; 516 | } 517 | }; 518 | 519 | //1.2compat> 520 | 521 | }).call(this); 522 | 523 | 524 | /* 525 | --- 526 | 527 | name: Array 528 | 529 | description: Contains Array Prototypes like each, contains, and erase. 530 | 531 | license: MIT-style license. 532 | 533 | requires: Type 534 | 535 | provides: Array 536 | 537 | ... 538 | */ 539 | 540 | Array.implement({ 541 | 542 | invoke: function(methodName){ 543 | var args = Array.slice(arguments, 1); 544 | return this.map(function(item){ 545 | return item[methodName].apply(item, args); 546 | }); 547 | }, 548 | 549 | every: function(fn, bind){ 550 | for (var i = 0, l = this.length; i < l; i++){ 551 | if ((i in this) && !fn.call(bind, this[i], i, this)) return false; 552 | } 553 | return true; 554 | }, 555 | 556 | filter: function(fn, bind){ 557 | var results = []; 558 | for (var i = 0, l = this.length; i < l; i++){ 559 | if ((i in this) && fn.call(bind, this[i], i, this)) results.push(this[i]); 560 | } 561 | return results; 562 | }, 563 | 564 | clean: function(){ 565 | return this.filter(function(item){ 566 | return item != null; 567 | }); 568 | }, 569 | 570 | indexOf: function(item, from){ 571 | var len = this.length; 572 | for (var i = (from < 0) ? Math.max(0, len + from) : from || 0; i < len; i++){ 573 | if (this[i] === item) return i; 574 | } 575 | return -1; 576 | }, 577 | 578 | map: function(fn, bind){ 579 | var results = []; 580 | for (var i = 0, l = this.length; i < l; i++){ 581 | if (i in this) results[i] = fn.call(bind, this[i], i, this); 582 | } 583 | return results; 584 | }, 585 | 586 | some: function(fn, bind){ 587 | for (var i = 0, l = this.length; i < l; i++){ 588 | if ((i in this) && fn.call(bind, this[i], i, this)) return true; 589 | } 590 | return false; 591 | }, 592 | 593 | associate: function(keys){ 594 | var obj = {}, length = Math.min(this.length, keys.length); 595 | for (var i = 0; i < length; i++) obj[keys[i]] = this[i]; 596 | return obj; 597 | }, 598 | 599 | link: function(object){ 600 | var result = {}; 601 | for (var i = 0, l = this.length; i < l; i++){ 602 | for (var key in object){ 603 | if (object[key](this[i])){ 604 | result[key] = this[i]; 605 | delete object[key]; 606 | break; 607 | } 608 | } 609 | } 610 | return result; 611 | }, 612 | 613 | contains: function(item, from){ 614 | return this.indexOf(item, from) != -1; 615 | }, 616 | 617 | append: function(array){ 618 | this.push.apply(this, array); 619 | return this; 620 | }, 621 | 622 | getLast: function(){ 623 | return (this.length) ? this[this.length - 1] : null; 624 | }, 625 | 626 | getRandom: function(){ 627 | return (this.length) ? this[Number.random(0, this.length - 1)] : null; 628 | }, 629 | 630 | include: function(item){ 631 | if (!this.contains(item)) this.push(item); 632 | return this; 633 | }, 634 | 635 | combine: function(array){ 636 | for (var i = 0, l = array.length; i < l; i++) this.include(array[i]); 637 | return this; 638 | }, 639 | 640 | erase: function(item){ 641 | for (var i = this.length; i--;){ 642 | if (this[i] === item) this.splice(i, 1); 643 | } 644 | return this; 645 | }, 646 | 647 | empty: function(){ 648 | this.length = 0; 649 | return this; 650 | }, 651 | 652 | flatten: function(){ 653 | var array = []; 654 | for (var i = 0, l = this.length; i < l; i++){ 655 | var type = typeOf(this[i]); 656 | if (type == 'null') continue; 657 | array = array.concat((type == 'array' || type == 'collection' || type == 'arguments' || instanceOf(this[i], Array)) ? Array.flatten(this[i]) : this[i]); 658 | } 659 | return array; 660 | }, 661 | 662 | pick: function(){ 663 | for (var i = 0, l = this.length; i < l; i++){ 664 | if (this[i] != null) return this[i]; 665 | } 666 | return null; 667 | }, 668 | 669 | hexToRgb: function(array){ 670 | if (this.length != 3) return null; 671 | var rgb = this.map(function(value){ 672 | if (value.length == 1) value += value; 673 | return value.toInt(16); 674 | }); 675 | return (array) ? rgb : 'rgb(' + rgb + ')'; 676 | }, 677 | 678 | rgbToHex: function(array){ 679 | if (this.length < 3) return null; 680 | if (this.length == 4 && this[3] == 0 && !array) return 'transparent'; 681 | var hex = []; 682 | for (var i = 0; i < 3; i++){ 683 | var bit = (this[i] - 0).toString(16); 684 | hex.push((bit.length == 1) ? '0' + bit : bit); 685 | } 686 | return (array) ? hex : '#' + hex.join(''); 687 | } 688 | 689 | }); 690 | 691 | //<1.2compat> 692 | 693 | Array.alias('extend', 'append'); 694 | 695 | var $pick = function(){ 696 | return Array.from(arguments).pick(); 697 | }; 698 | 699 | //1.2compat> 700 | 701 | 702 | /* 703 | --- 704 | 705 | name: String 706 | 707 | description: Contains String Prototypes like camelCase, capitalize, test, and toInt. 708 | 709 | license: MIT-style license. 710 | 711 | requires: Type 712 | 713 | provides: String 714 | 715 | ... 716 | */ 717 | 718 | String.implement({ 719 | 720 | test: function(regex, params){ 721 | return ((typeOf(regex) == 'regexp') ? regex : new RegExp('' + regex, params)).test(this); 722 | }, 723 | 724 | contains: function(string, separator){ 725 | return (separator) ? (separator + this + separator).indexOf(separator + string + separator) > -1 : this.indexOf(string) > -1; 726 | }, 727 | 728 | trim: function(){ 729 | return this.replace(/^\s+|\s+$/g, ''); 730 | }, 731 | 732 | clean: function(){ 733 | return this.replace(/\s+/g, ' ').trim(); 734 | }, 735 | 736 | camelCase: function(){ 737 | return this.replace(/-\D/g, function(match){ 738 | return match.charAt(1).toUpperCase(); 739 | }); 740 | }, 741 | 742 | hyphenate: function(){ 743 | return this.replace(/[A-Z]/g, function(match){ 744 | return ('-' + match.charAt(0).toLowerCase()); 745 | }); 746 | }, 747 | 748 | capitalize: function(){ 749 | return this.replace(/\b[a-z]/g, function(match){ 750 | return match.toUpperCase(); 751 | }); 752 | }, 753 | 754 | escapeRegExp: function(){ 755 | return this.replace(/([-.*+?^${}()|[\]\/\\])/g, '\\$1'); 756 | }, 757 | 758 | toInt: function(base){ 759 | return parseInt(this, base || 10); 760 | }, 761 | 762 | toFloat: function(){ 763 | return parseFloat(this); 764 | }, 765 | 766 | hexToRgb: function(array){ 767 | var hex = this.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/); 768 | return (hex) ? hex.slice(1).hexToRgb(array) : null; 769 | }, 770 | 771 | rgbToHex: function(array){ 772 | var rgb = this.match(/\d{1,3}/g); 773 | return (rgb) ? rgb.rgbToHex(array) : null; 774 | }, 775 | 776 | substitute: function(object, regexp){ 777 | return this.replace(regexp || (/\\?\{([^{}]+)\}/g), function(match, name){ 778 | if (match.charAt(0) == '\\') return match.slice(1); 779 | return (object[name] != null) ? object[name] : ''; 780 | }); 781 | } 782 | 783 | }); 784 | 785 | 786 | /* 787 | --- 788 | 789 | name: Number 790 | 791 | description: Contains Number Prototypes like limit, round, times, and ceil. 792 | 793 | license: MIT-style license. 794 | 795 | requires: Type 796 | 797 | provides: Number 798 | 799 | ... 800 | */ 801 | 802 | Number.implement({ 803 | 804 | limit: function(min, max){ 805 | return Math.min(max, Math.max(min, this)); 806 | }, 807 | 808 | round: function(precision){ 809 | precision = Math.pow(10, precision || 0).toFixed(precision < 0 ? -precision : 0); 810 | return Math.round(this * precision) / precision; 811 | }, 812 | 813 | times: function(fn, bind){ 814 | for (var i = 0; i < this; i++) fn.call(bind, i, this); 815 | }, 816 | 817 | toFloat: function(){ 818 | return parseFloat(this); 819 | }, 820 | 821 | toInt: function(base){ 822 | return parseInt(this, base || 10); 823 | } 824 | 825 | }); 826 | 827 | Number.alias('each', 'times'); 828 | 829 | (function(math){ 830 | var methods = {}; 831 | math.each(function(name){ 832 | if (!Number[name]) methods[name] = function(){ 833 | return Math[name].apply(null, [this].concat(Array.from(arguments))); 834 | }; 835 | }); 836 | Number.implement(methods); 837 | })(['abs', 'acos', 'asin', 'atan', 'atan2', 'ceil', 'cos', 'exp', 'floor', 'log', 'max', 'min', 'pow', 'sin', 'sqrt', 'tan']); 838 | 839 | 840 | /* 841 | --- 842 | 843 | name: Function 844 | 845 | description: Contains Function Prototypes like create, bind, pass, and delay. 846 | 847 | license: MIT-style license. 848 | 849 | requires: Type 850 | 851 | provides: Function 852 | 853 | ... 854 | */ 855 | 856 | Function.extend({ 857 | 858 | attempt: function(){ 859 | for (var i = 0, l = arguments.length; i < l; i++){ 860 | try { 861 | return arguments[i](); 862 | } catch (e){} 863 | } 864 | return null; 865 | } 866 | 867 | }); 868 | 869 | Function.implement({ 870 | 871 | attempt: function(args, bind){ 872 | try { 873 | return this.apply(bind, Array.from(args)); 874 | } catch (e){} 875 | 876 | return null; 877 | }, 878 | 879 | bind: function(bind){ 880 | var self = this, 881 | args = (arguments.length > 1) ? Array.slice(arguments, 1) : null; 882 | 883 | return function(){ 884 | if (!args && !arguments.length) return self.call(bind); 885 | if (args && arguments.length) return self.apply(bind, args.concat(Array.from(arguments))); 886 | return self.apply(bind, args || arguments); 887 | }; 888 | }, 889 | 890 | pass: function(args, bind){ 891 | var self = this; 892 | if (args != null) args = Array.from(args); 893 | return function(){ 894 | return self.apply(bind, args || arguments); 895 | }; 896 | }, 897 | 898 | delay: function(delay, bind, args){ 899 | return setTimeout(this.pass((args == null ? [] : args), bind), delay); 900 | }, 901 | 902 | periodical: function(periodical, bind, args){ 903 | return setInterval(this.pass((args == null ? [] : args), bind), periodical); 904 | } 905 | 906 | }); 907 | 908 | //<1.2compat> 909 | 910 | delete Function.prototype.bind; 911 | 912 | Function.implement({ 913 | 914 | create: function(options){ 915 | var self = this; 916 | options = options || {}; 917 | return function(event){ 918 | var args = options.arguments; 919 | args = (args != null) ? Array.from(args) : Array.slice(arguments, (options.event) ? 1 : 0); 920 | if (options.event) args = [event || window.event].extend(args); 921 | var returns = function(){ 922 | return self.apply(options.bind || null, args); 923 | }; 924 | if (options.delay) return setTimeout(returns, options.delay); 925 | if (options.periodical) return setInterval(returns, options.periodical); 926 | if (options.attempt) return Function.attempt(returns); 927 | return returns(); 928 | }; 929 | }, 930 | 931 | bind: function(bind, args){ 932 | var self = this; 933 | if (args != null) args = Array.from(args); 934 | return function(){ 935 | return self.apply(bind, args || arguments); 936 | }; 937 | }, 938 | 939 | bindWithEvent: function(bind, args){ 940 | var self = this; 941 | if (args != null) args = Array.from(args); 942 | return function(event){ 943 | return self.apply(bind, (args == null) ? arguments : [event].concat(args)); 944 | }; 945 | }, 946 | 947 | run: function(args, bind){ 948 | return this.apply(bind, Array.from(args)); 949 | } 950 | 951 | }); 952 | 953 | var $try = Function.attempt; 954 | 955 | //1.2compat> 956 | 957 | 958 | /* 959 | --- 960 | 961 | name: Object 962 | 963 | description: Object generic methods 964 | 965 | license: MIT-style license. 966 | 967 | requires: Type 968 | 969 | provides: [Object, Hash] 970 | 971 | ... 972 | */ 973 | 974 | (function(){ 975 | 976 | var hasOwnProperty = Object.prototype.hasOwnProperty; 977 | 978 | Object.extend({ 979 | 980 | subset: function(object, keys){ 981 | var results = {}; 982 | for (var i = 0, l = keys.length; i < l; i++){ 983 | var k = keys[i]; 984 | results[k] = object[k]; 985 | } 986 | return results; 987 | }, 988 | 989 | map: function(object, fn, bind){ 990 | var results = {}; 991 | for (var key in object){ 992 | if (hasOwnProperty.call(object, key)) results[key] = fn.call(bind, object[key], key, object); 993 | } 994 | return results; 995 | }, 996 | 997 | filter: function(object, fn, bind){ 998 | var results = {}; 999 | Object.each(object, function(value, key){ 1000 | if (fn.call(bind, value, key, object)) results[key] = value; 1001 | }); 1002 | return results; 1003 | }, 1004 | 1005 | every: function(object, fn, bind){ 1006 | for (var key in object){ 1007 | if (hasOwnProperty.call(object, key) && !fn.call(bind, object[key], key)) return false; 1008 | } 1009 | return true; 1010 | }, 1011 | 1012 | some: function(object, fn, bind){ 1013 | for (var key in object){ 1014 | if (hasOwnProperty.call(object, key) && fn.call(bind, object[key], key)) return true; 1015 | } 1016 | return false; 1017 | }, 1018 | 1019 | keys: function(object){ 1020 | var keys = []; 1021 | for (var key in object){ 1022 | if (hasOwnProperty.call(object, key)) keys.push(key); 1023 | } 1024 | return keys; 1025 | }, 1026 | 1027 | values: function(object){ 1028 | var values = []; 1029 | for (var key in object){ 1030 | if (hasOwnProperty.call(object, key)) values.push(object[key]); 1031 | } 1032 | return values; 1033 | }, 1034 | 1035 | getLength: function(object){ 1036 | return Object.keys(object).length; 1037 | }, 1038 | 1039 | keyOf: function(object, value){ 1040 | for (var key in object){ 1041 | if (hasOwnProperty.call(object, key) && object[key] === value) return key; 1042 | } 1043 | return null; 1044 | }, 1045 | 1046 | contains: function(object, value){ 1047 | return Object.keyOf(object, value) != null; 1048 | }, 1049 | 1050 | toQueryString: function(object, base){ 1051 | var queryString = []; 1052 | 1053 | Object.each(object, function(value, key){ 1054 | if (base) key = base + '[' + key + ']'; 1055 | var result; 1056 | switch (typeOf(value)){ 1057 | case 'object': result = Object.toQueryString(value, key); break; 1058 | case 'array': 1059 | var qs = {}; 1060 | value.each(function(val, i){ 1061 | qs[i] = val; 1062 | }); 1063 | result = Object.toQueryString(qs, key); 1064 | break; 1065 | default: result = key + '=' + encodeURIComponent(value); 1066 | } 1067 | if (value != null) queryString.push(result); 1068 | }); 1069 | 1070 | return queryString.join('&'); 1071 | } 1072 | 1073 | }); 1074 | 1075 | })(); 1076 | 1077 | //<1.2compat> 1078 | 1079 | Hash.implement({ 1080 | 1081 | has: Object.prototype.hasOwnProperty, 1082 | 1083 | keyOf: function(value){ 1084 | return Object.keyOf(this, value); 1085 | }, 1086 | 1087 | hasValue: function(value){ 1088 | return Object.contains(this, value); 1089 | }, 1090 | 1091 | extend: function(properties){ 1092 | Hash.each(properties || {}, function(value, key){ 1093 | Hash.set(this, key, value); 1094 | }, this); 1095 | return this; 1096 | }, 1097 | 1098 | combine: function(properties){ 1099 | Hash.each(properties || {}, function(value, key){ 1100 | Hash.include(this, key, value); 1101 | }, this); 1102 | return this; 1103 | }, 1104 | 1105 | erase: function(key){ 1106 | if (this.hasOwnProperty(key)) delete this[key]; 1107 | return this; 1108 | }, 1109 | 1110 | get: function(key){ 1111 | return (this.hasOwnProperty(key)) ? this[key] : null; 1112 | }, 1113 | 1114 | set: function(key, value){ 1115 | if (!this[key] || this.hasOwnProperty(key)) this[key] = value; 1116 | return this; 1117 | }, 1118 | 1119 | empty: function(){ 1120 | Hash.each(this, function(value, key){ 1121 | delete this[key]; 1122 | }, this); 1123 | return this; 1124 | }, 1125 | 1126 | include: function(key, value){ 1127 | if (this[key] == null) this[key] = value; 1128 | return this; 1129 | }, 1130 | 1131 | map: function(fn, bind){ 1132 | return new Hash(Object.map(this, fn, bind)); 1133 | }, 1134 | 1135 | filter: function(fn, bind){ 1136 | return new Hash(Object.filter(this, fn, bind)); 1137 | }, 1138 | 1139 | every: function(fn, bind){ 1140 | return Object.every(this, fn, bind); 1141 | }, 1142 | 1143 | some: function(fn, bind){ 1144 | return Object.some(this, fn, bind); 1145 | }, 1146 | 1147 | getKeys: function(){ 1148 | return Object.keys(this); 1149 | }, 1150 | 1151 | getValues: function(){ 1152 | return Object.values(this); 1153 | }, 1154 | 1155 | toQueryString: function(base){ 1156 | return Object.toQueryString(this, base); 1157 | } 1158 | 1159 | }); 1160 | 1161 | Hash.extend = Object.append; 1162 | 1163 | Hash.alias({indexOf: 'keyOf', contains: 'hasValue'}); 1164 | 1165 | //1.2compat> 1166 | 1167 | 1168 | /* 1169 | --- 1170 | 1171 | name: Browser 1172 | 1173 | description: The Browser Object. Contains Browser initialization, Window and Document, and the Browser Hash. 1174 | 1175 | license: MIT-style license. 1176 | 1177 | requires: [Array, Function, Number, String] 1178 | 1179 | provides: [Browser, Window, Document] 1180 | 1181 | ... 1182 | */ 1183 | 1184 | (function(){ 1185 | 1186 | var document = this.document; 1187 | var window = document.window = this; 1188 | 1189 | var UID = 1; 1190 | 1191 | this.$uid = (window.ActiveXObject) ? function(item){ 1192 | return (item.uid || (item.uid = [UID++]))[0]; 1193 | } : function(item){ 1194 | return item.uid || (item.uid = UID++); 1195 | }; 1196 | 1197 | $uid(window); 1198 | $uid(document); 1199 | 1200 | var ua = navigator.userAgent.toLowerCase(), 1201 | platform = navigator.platform.toLowerCase(), 1202 | UA = ua.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/) || [null, 'unknown', 0], 1203 | mode = UA[1] == 'ie' && document.documentMode; 1204 | 1205 | var Browser = this.Browser = { 1206 | 1207 | extend: Function.prototype.extend, 1208 | 1209 | name: (UA[1] == 'version') ? UA[3] : UA[1], 1210 | 1211 | version: mode || parseFloat((UA[1] == 'opera' && UA[4]) ? UA[4] : UA[2]), 1212 | 1213 | Platform: { 1214 | name: ua.match(/ip(?:ad|od|hone)/) ? 'ios' : (ua.match(/(?:webos|android)/) || platform.match(/mac|win|linux/) || ['other'])[0] 1215 | }, 1216 | 1217 | Features: { 1218 | xpath: !!(document.evaluate), 1219 | air: !!(window.runtime), 1220 | query: !!(document.querySelector), 1221 | json: !!(window.JSON) 1222 | }, 1223 | 1224 | Plugins: {} 1225 | 1226 | }; 1227 | 1228 | Browser[Browser.name] = true; 1229 | Browser[Browser.name + parseInt(Browser.version, 10)] = true; 1230 | Browser.Platform[Browser.Platform.name] = true; 1231 | 1232 | // Request 1233 | 1234 | Browser.Request = (function(){ 1235 | 1236 | var XMLHTTP = function(){ 1237 | return new XMLHttpRequest(); 1238 | }; 1239 | 1240 | var MSXML2 = function(){ 1241 | return new ActiveXObject('MSXML2.XMLHTTP'); 1242 | }; 1243 | 1244 | var MSXML = function(){ 1245 | return new ActiveXObject('Microsoft.XMLHTTP'); 1246 | }; 1247 | 1248 | return Function.attempt(function(){ 1249 | XMLHTTP(); 1250 | return XMLHTTP; 1251 | }, function(){ 1252 | MSXML2(); 1253 | return MSXML2; 1254 | }, function(){ 1255 | MSXML(); 1256 | return MSXML; 1257 | }); 1258 | 1259 | })(); 1260 | 1261 | Browser.Features.xhr = !!(Browser.Request); 1262 | 1263 | // Flash detection 1264 | 1265 | var version = (Function.attempt(function(){ 1266 | return navigator.plugins['Shockwave Flash'].description; 1267 | }, function(){ 1268 | return new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version'); 1269 | }) || '0 r0').match(/\d+/g); 1270 | 1271 | Browser.Plugins.Flash = { 1272 | version: Number(version[0] || '0.' + version[1]) || 0, 1273 | build: Number(version[2]) || 0 1274 | }; 1275 | 1276 | // String scripts 1277 | 1278 | Browser.exec = function(text){ 1279 | if (!text) return text; 1280 | if (window.execScript){ 1281 | window.execScript(text); 1282 | } else { 1283 | var script = document.createElement('script'); 1284 | script.setAttribute('type', 'text/javascript'); 1285 | script.text = text; 1286 | document.head.appendChild(script); 1287 | document.head.removeChild(script); 1288 | } 1289 | return text; 1290 | }; 1291 | 1292 | String.implement('stripScripts', function(exec){ 1293 | var scripts = ''; 1294 | var text = this.replace(/ 5 | 6 | 7 | 8 | 9 | 544 | 545 | 661 | 662 | 663 |
664 |667 | Step 1. Select template from drop down. Edit as required. Click the button. 668 |
669 | 670 |671 | Step 2. Adjust the position of the vertical pins and margins so they are correct. 672 |
673 |674 | Step 3. Screenshot or print-to-pdf or whatever and adjust further in your favourite graphics package. 675 |
676 | 677 |
678 |
681 |
682 |
683 |
Vertical Pins Offset: | 688 |top: , left: | 689 |
---|---|
Vertical Pins Margins: | 692 |top: , bottom: | 693 |
0..n, ~ | digitalWrite(), digitalRead(), pinMode(), ~analogWrite() | 705 |
A0..An | analogRead() | 708 |
711 | Programmer
712 | Serial
713 | SPI
714 | I2C
715 | Interrupt
716 | |
717 |