1/** 2 * JTab - Javascript/CSS Guitar Chord and Tab Notation for the Web. 3 * Version 1.3.1 4 * Written by Paul Gallagher (http://tardate.com), 2009. (original version and maintainer) 5 * Contributions: 6 * Jason Ong (https://github.com/jasonong) 7 * Bruno Bornsztein (https://github.com/bborn) 8 * Binary Bit LAN (https://github.com/binarybitlan) 9 * See: 10 * http://jtab.tardate.com : more information on availability, configuration and use. 11 * http://github.com/tardate/jtab/tree/master : source code repository, wiki, documentation 12 * 13 * This library also depends on the following two libraries that must be loaded for it to work: 14 * jQuery - http://www.jquery.com/ 15 * Raphael - http://raphaeljs.com/ 16 * 17 * 18 * This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General 19 * Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) 20 * any later version. 21 * 22 * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied 23 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 24 * details. 25 * 26 * You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to 27 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 28 */ 29 30// 31// define the jtab class 32// 33 34var jtab = { 35 Version : '1.3.1', 36 element_count:0, //TODO: 37 Strings : { 38 AboutDialog : '<html><head><title>About jTab</title></head><body style=""><p style="">jTab version: {V}</p><p><a href="http://jtab.tardate.com" target="_blank">http://jtab.tardate.com</a></p><p><input type="button" class="close" value="OK" onClick="window.close()"/></p></body></html>' 39 }, 40 Chords : { 41 // chord data - currently explicit representation for 6 string guitar, standard tuning only, and 42 // each chord is an array of alternate positions 43 // 0 : 1st (open) position 44 // 1 : 1st barre position, generally at 12/13/14th fret 45 // - minimum, only required for CAGED chords where open strings are used in the 1st (open) position 46 // since the main purpose of this is to provide barre fingering positions for CAGED-based chords 47 // 2.. : alternative positions/fingerings 48 // each position is an array comprising: 1. base fret (0==nut); 2. 6x note definitions (strings 6,5,4,3,2,1) 49 // each note is an array: (fret position), (left hand fingering if applicable 1,2,3,4,T) 50 // fret position: -1 = muted/not played; 0 = open; 1,2,3... = fret position 51 C : [ [ 0, [-1 ], [3,3], [2,2], [0 ], [1,1], [0 ] ], [ 12, [-1,-1], [15,4], [14,3], [12,1], [13,2], [12,1 ] ] ], 52 Cm : [ [ 0, [-1 ], [3,4], [1,2], [0 ], [1,1], [-1 ] ], [ 12, [-1,-1], [15,4], [13,3], [12,1], [13,2], [-1,-1] ] ], 53 C6 : [ [ 0, [-1 ], [0 ], [2,2], [2,3], [1,1], [3,4] ], [ 12, [-1,-1], [12,1], [14,3], [14,3], [13,2], [15,4] ] ], 54 Cm6 : [ [ 0, [-1 ], [-1 ], [1,1], [2,3], [1,2], [3,4] ], [ ] ], 55 C69 : [ [ 0, [-1 ], [3,2], [2,1], [2,1], [3,3], [3,4] ], [ ] ], 56 C7 : [ [ 0, [-1 ], [3,3], [2,2], [3,4], [1,1], [0 ] ], [ 12, [-1,-1], [15,3], [14,2], [15,4], [13,1], [12, ] ] ], 57 Cm7 : [ [ 0, [-1 ], [-1 ], [1,1], [3,3], [1,1], [3,4] ], [ ] ], 58 Cmaj7 : [ [ 0, [-1 ], [3,3], [2,2], [0 ], [0 ], [0 ] ], [ 12, [-1,-1], [15,4], [14,3], [12,1], [12,1], [12,1] ] ], 59 C7b5 : [ [ 2, [-1 ], [3,1], [4,3], [3,2], [5,4], [-1 ] ], [ ] ], 60 "C7#5" : [ [ 0, [-1 ], [-1 ], [2,2], [3,3], [1,1], [4,4] ], [ ] ], 61 "Cm7b5" : [ [ 0, [-1 ], [3,1], [4,3], [3,2], [4,4], [-1 ] ], [ ] ], 62 C7b9 : [ [ 0, [-1 ], [3,3], [2,1], [3,4], [2,2], [0 ] ], [ ] ], 63 C9 : [ [ 0, [-1 ], [3,2], [2,1], [3,3], [3,4], [-1 ] ], [ ] ], 64 Cm9 : [ [ 0, [-1 ], [3,2], [1,1], [3,3], [3,3], [3,3] ], [ ] ], 65 Cmaj9 : [ [ 0, [-1 ], [3,3], [0 ], [0 ], [0 ], [0 ] ], [ 12, [-1 ], [15,3], [12,1], [12,1], [12,1], [12,1] ] ], 66 Cadd9 : [ [ 0, [-1 ], [3,2], [2,1], [0 ], [3,3], [0 ] ], [ 12, [-1 ], [15,3], [14,2], [12,1], [15,4], [12,1] ] ], 67 C13 : [ [ 2, [-1 ], [3,1], [5,2], [3,1], [5,3], [5,4] ], [ ] ], 68 Csus2 : [ [ 2, [ -1], [3,1], [5,3], [5,4], [3,1], [3,1] ], [ ] ], 69 Csus4 : [ [ 2, [ -1], [3,1], [5,2], [5,3], [6,4], [3,1] ], [ ] ], 70 Cdim : [ [ 0, [-1 ], [3,3], [4,4], [2,2], [1,1], [-1 ] ], [ ] ], 71 Cdim7 : [ [ 0, [-1 ], [-1 ], [1,1], [2,3], [1,2], [2,4] ], [ ] ], 72 Caug : [ [ 0, [-1 ], [-1 ], [2,2], [1,1], [1,1], [4,4] ], [ ] ], 73 74 "C#" : [ [ 0, [-1 ], [4,4], [3,4], [1,1], [2,2], [1,1] ], [ ] ], 75 "C#m" : [ [ 0, [-1 ], [-1 ], [2,2], [1,1], [2,3], [0 ] ], [ ] ], 76 "C#6" : [ [ 0, [-1 ], [-1 ], [3,2], [3,3], [2,1], [4,4] ], [ ] ], 77 "C#m6" : [ [ 0, [-1 ], [4,3], [2,1], [3,2], [2,1], [4,4] ], [ ] ], 78 "C#69" : [ [ 2, [-1 ], [4,2], [3,1], [3,1], [4,3], [4,4] ], [ ] ], 79 "C#7" : [ [ 0, [-1 ], [-1 ], [3,2], [4,3], [2,1], [4,4] ], [ ] ], 80 "C#m7" : [ [ 0, [-1 ], [-1 ], [2,1], [4,3], [2,1], [4,4] ], [ ] ], 81 "C#maj7": [ [ 0, [-1 ], [4,4], [3,3], [1,1], [1,1], [1,1] ], [ ] ], 82 "C#7b5" : [ [ 0, [3,2], [0 ], [3,3], [4,4], [2,1], [-1 ] ], [ ] ], 83 "C#7#5" : [ [ 0, [-1 ], [4,3], [3,2], [2,1], [0 ], [-1 ] ], [ ] ], 84 "C#m7b5": [ [ 0, [-1 ], [2,1], [2,2], [0 ], [2,3], [0 ] ], [ ] ], 85 "C#7b9" : [ [ 0, [-1 ], [4,2], [3,1], [4,3], [3,1], [4,4] ], [ ] ], 86 "C#9" : [ [ 3, [-1 ], [4,1], [6,2], [6,3], [4,1], [4,1] ], [ ] ], 87 "C#m9" : [ [ 0, [0 ], [2,2], [1,1], [1,1], [2,3], [0 ] ], [ ] ], 88 "C#maj9": [ [ 0, [-1 ], [4,4], [1,1], [1,1], [1,1], [1,1] ], [ ] ], 89 "C#add9": [ [ 0, [1,1], [-1 ], [1,1], [1,1], [2,2], [1,1] ], [ ] ], 90 "C#13" : [ [ 3, [-1 ], [4,1], [6,2], [4,1], [6,3], [6,4] ], [ ] ], 91 "C#sus2": [ [ 0, [-1 ], [-1 ], [3,3], [3,4], [1,1], [1,1] ], [ ] ], 92 "C#sus4": [ [ 0, [-1 ], [-1 ], [3,2], [3,3], [4,4], [1,1] ], [ ] ], 93 "C#dim" : [ [ 0, [-1 ], [-1 ], [2,1], [3,3], [2,2], [3,4] ], [ ] ], 94 "C#dim7": [ [ 0, [-1 ], [-1 ], [2,1], [3,3], [2,2], [3,4] ], [ ] ], 95 "C#aug" : [ [ 0, [-1 ], [4,4], [3,3], [2,1], [2,2], [-1 ] ], [ ] ], 96 97 98 D : [ [ 0, [-1 ], [0 ], [0 ], [2,1], [3,3], [2,2] ], [ 12, [-1,-1], [12,1], [12,1], [14,3], [15,4], [14,2] ] ], 99 Dm : [ [ 0, [-1 ], [0 ], [0 ], [2,2], [3,3], [1,1] ], [ 12, [-1,-1], [12,1], [12,1], [14,3], [15,4], [13,2] ] ], 100 D6 : [ [ 0, [-1 ], [0 ], [0 ], [2,2], [0 ], [2,3] ], [ 12, [-1,-1], [12,1], [12,1], [14,3], [12,1], [14,4] ] ], 101 Dm6 : [ [ 0, [-1 ], [2,2], [0 ], [2,3], [0 ], [1,1] ], [ 12, [-1,-1], [14,3], [12,1], [14,4], [12,1], [1,2] ] ], 102 D69 : [ [ 3, [-1 ], [5,2], [4,1], [4,1], [5,3], [5,4] ], [ ] ], 103 D7 : [ [ 0, [-1 ], [0 ], [0 ], [2,2], [1,1], [2,3] ], [ 12, [-1,-1], [12,1], [12,1], [14,3], [13,2], [14,4] ] ], 104 Dm7 : [ [ 0, [-1 ], [-1 ], [0 ], [2,2], [1,1], [1,1] ], [ 12, [-1,-1], [-1,-1], [12,1], [14,4], [13,2], [13,3] ] ], 105 Dmaj7 : [ [ 0, [-1 ], [5,4], [4,3], [2,1], [2,1], [2,1] ], [ ] ], 106 D7b5 : [ [ 4, [-1 ], [5,1], [6,3], [5,2], [7,4], [-1 ] ], [ ] ], 107 "D7#5" : [ [ 0, [-1 ], [-1 ], [0 ], [4,3], [1,1], [2,2] ], [ 12, [-1,-1], [-1,-1], [12,1], [16,4], [13,2], [14,3] ] ], 108 Dm7b5 : [ [ 0, [-1 ], [-1 ], [0 ], [1,1], [1,1], [1,1] ], [ 12, [-1,-1], [-1,-1], [12,1], [12,2], [12,3], [12,4] ] ], 109 D7b9 : [ [ 3, [-1 ], [5,2], [4,1], [5,3], [4,1], [5,4] ], [ ] ], 110 D9 : [ [ 0, [2,2], [-1 ], [0 ], [2,3], [1,1], [0 ] ], [ 12, [14,4 ], [-1,-1], [12,1], [14,3], [13,2], [12,1] ] ], 111 Dm9 : [ [ 0, [-1 ], [-1 ], [3,3], [2,2], [1,1], [0 ] ], [ 12, [-1,-1], [-1,-1], [15,4], [14,3], [13,2], [12,1] ] ], 112 Dmaj9 : [ [ 0, [-1 ], [5,4], [2,1], [2,1], [2,1], [2,1] ], [ ] ], 113 Dadd9 : [ [ 0, [-1 ], [-1 ], [0 ], [2,1], [3,2], [0 ] ], [ 12, [-1,-1], [-1,-1], [12,1], [14,3], [15,4], [12,1] ] ], 114 D13 : [ [ 4, [-1 ], [5,1], [7,2], [5,1], [7,3], [7,4] ], [ ] ], 115 Dsus2 : [ [ 0, [-1 ], [-1 ], [0 ], [2,1], [3,3], [0 ] ], [ 12, [-1,-1], [-1,-1], [12,1], [14,3], [15,4], [12,1] ] ], 116 Dsus4 : [ [ 0, [-1 ], [-1 ], [0 ], [2,1], [3,3], [3,4] ], [ 12, [-1,-1], [-1,-1], [12,1], [14,2], [15,3], [15,4] ] ], 117 Ddim : [ [ 0, [-1 ], [-1 ], [0 ], [1,1], [0 ], [1,2] ], [ 12, [-1,-1], [-1,-1], [12,1], [13,2], [12,1], [13,3] ] ], 118 Ddim7 : [ [ 0, [-1 ], [2,3], [0 ], [1,1], [0 ], [1,2] ], [ 12, [-1,-1], [14,4], [12,1], [13,2], [12,1], [13,3] ] ], 119 Daug : [ [ 0, [-1 ], [-1 ], [0 ], [3,2], [3,3], [2,1] ], [ 12, [-1,-1], [-1,-1], [12,1], [15,3], [15,4], [14,2] ] ], 120 121 "Eb" : [ [ 0, [-1 ], [-1 ], [5,4], [3,1], [4,3], [3,2] ], [ ] ], 122 "Ebm" : [ [ 0, [-1 ], [-1 ], [4,3], [3,2], [4,4], [2,1] ], [ ] ], 123 "Eb6" : [ [ 0, [-1 ], [3,1], [5,3], [3,1], [4,2], [3,1] ], [ ] ], 124 "Ebm6" : [ [ 0, [-1 ], [-1 ], [1,1], [3,3], [1,1], [2,2] ], [ ] ], 125 "Eb69" : [ [ 0, [-1 ], [-1 ], [1,1], [0 ], [1,2], [1,3] ], [ ] ], 126 "Eb7" : [ [ 0, [-1 ], [-1 ], [1,1], [3,3], [2,2], [3,4] ], [ ] ], 127 "Ebm7" : [ [ 0, [-1 ], [-1 ], [1,1], [3,4], [2,2], [2,3] ], [ ] ], 128 "Ebmaj7": [ [ 0, [-1 ], [-1 ], [1,1], [3,2], [3,3], [3,4] ], [ ] ], 129 "Eb7b5" : [ [ 0, [-1 ], [-1 ], [1,1], [2,2], [2,3], [4,4] ], [ ] ], 130 "Eb7#5" : [ [ 0, [-1 ], [-1 ], [1,1], [4,4], [2,2], [3,3] ], [ ] ], 131 "Ebm7b5": [ [ 0, [-1 ], [-1 ], [1,1], [2,2], [2,3], [2,4] ], [ ] ], 132 "Eb7b9" : [ [ 0, [-1 ], [-1 ], [1,1], [0 ], [2,3], [0 ] ], [ ] ], 133 "Eb9" : [ [ 0, [3,4], [1,1], [1,1], [0 ], [2,1], [1,1] ], [ ] ], 134 "Ebm9" : [ [ 0, [2,2], [1,1], [1,1], [3,4], [2,3], [1,1] ], [ ] ], 135 "Ebmaj9": [ [ 0, [-1 ], [-1 ], [1,1], [0 ], [3,4], [1,2] ], [ ] ], 136 "Ebadd9": [ [ 0, [3,4], [2,2], [2,2], [0 ], [-1 ], [1,1] ], [ ] ], 137 "Eb13" : [ [ 4, [-1 ], [6,2], [5,1], [6,3], [8,4], [8,4] ], [ ] ], 138 "Ebsus2": [ [ 0, [1,1], [1,1], [1,1], [3,3], [-1 ], [1,1] ], [ ] ], 139 "Ebsus4": [ [ 0, [-1 ], [-1 ], [1,1], [3,3], [4,4], [4,4] ], [ ] ], 140 "Ebdim" : [ [ 0, [-1 ], [-1 ], [1,1], [2,3], [1,2], [2,4] ], [ ] ], 141 "Ebdim7": [ [ 0, [-1 ], [-1 ], [1,1], [2,3], [1,2], [2,4] ], [ ] ], 142 "Ebaug" : [ [ 0, [3,3], [2,2], [1,1], [0 ], [0 ], [3,4] ], [ ] ], 143 144 E : [ [ 0, [ 0 ], [2,2], [2,3], [1,1], [0 ], [0 ] ], [ 12, [ 12,1], [14,3], [14,4], [13,2], [12,1], [12,1] ] ], 145 Em : [ [ 0, [ 0 ], [2,2], [2,3], [0 ], [0 ], [0 ] ], [ 12, [ 12,1], [14,3], [14,4], [12,1], [12,1], [12,1] ] ], 146 E6 : [ [ 0, [ 0 ], [2,2], [2,3], [1,1], [2,4], [0 ] ], [ 12, [ 12,1], [14,3], [14,3], [13,2], [14,4], [12,1] ] ], 147 Em6 : [ [ 0, [ 0 ], [2,1], [2,2], [0 ], [2,3], [0 ] ], [ 12, [ 12,1], [14,2], [14,3], [12,1], [14,4], [12,1] ] ], 148 E69 : [ [ 0, [-1 ], [2,2], [2,2], [1,1], [2,3], [2,3] ], [ ] ], 149 E7 : [ [ 0, [ 0 ], [2,2], [0 ], [1,1], [0 ], [0 ] ], [ 12, [ 12,1], [14,3], [12,1], [13,2], [12,1], [12,1] ] ], 150 Em7 : [ [ 0, [ 0 ], [2,2], [2,3], [0 ], [3,4], [0 ] ], [ 12, [ 12,1], [14,2], [14,3], [12,1], [15,4], [12,1] ] ], 151 Emaj7 : [ [ 0, [ 0 ], [2,3], [1,1], [1,2], [0 ], [0 ] ], [ 12, [ 12,1], [14,4], [13,2], [13,3], [12,1], [12,1] ] ], 152 E7b5 : [ [ 0, [-1 ], [1,1], [0 ], [1,2], [3,4], [0 ] ], [ 12, [-1,-1], [13,2], [12,1], [13,3], [15,4], [12,1] ] ], 153 "E7#5" : [ [ 0, [0 ], [3,4], [0 ], [1,1], [1,2], [-1 ] ], [ 12, [ 12,1], [15,4], [12,1], [13,3], [13,2], [-1 ] ] ], 154 Em7b5 : [ [ 0, [-1 ], [-1 ], [2,1], [3,2], [3,3], [3,4] ], [ ] ], 155 E7b9 : [ [ 0, [0 ], [2,3], [0 ], [1,1], [0 ], [1,2] ], [ 12, [ 12,1], [14,4], [12,1], [13,3], [12,1], [13,2] ] ], 156 E9 : [ [ 0, [0 ], [2,2], [0 ], [1,1], [0 ], [2,3] ], [ 12, [ 12,1], [14,3], [12,1], [13,2], [12,1], [14,4] ] ], 157 Em9 : [ [ 0, [0 ], [2,1], [0 ], [0 ], [0 ], [2,2] ], [ 12, [ 12,1], [14,2], [12,1], [12,1], [12,1], [14,4] ] ], 158 Emaj9 : [ [ 0, [0 ], [2,2], [1,1], [1,1], [0 ], [2,4] ], [ 12, [ 12,1], [14,3], [13,2], [13,2], [12,1], [14,4] ] ], 159 Eadd9 : [ [ 0, [2,2], [2,3], [2,4], [1,1], [0 ], [0 ] ], [ 12, [ 14,3], [14,3], [14,4], [13,2], [12,1], [12,1] ] ], 160 E13 : [ [ 0, [0 ], [2,2], [0 ], [1,1], [2,3], [0 ] ], [ 12, [ 12,1], [14,3], [12,1], [13,2], [14,4], [12,1] ] ], 161 Esus2 : [ [ 0, [ -1], [2,1], [4,3], [4,4], [-1 ], [0 ] ], [ 12, [ -1,-1], [14,2], [16,3], [16,4], [-1 ], [12,1] ] ], 162 Esus4 : [ [ 0, [ 0 ], [2,2], [2,3], [2,4], [0 ], [0 ] ], [ 12, [ 12,1], [14,2], [14,3], [14,4], [12,1], [12,1] ] ], 163 Edim : [ [ 0, [-1 ], [1,1], [2,2], [3,4], [2,3], [-1 ] ], [ ] ], 164 Edim7 : [ [ 0, [-1 ], [-1 ], [2,1], [3,3], [2,2], [3,4] ], [ ] ], 165 Eaug : [ [ 0, [ 0 ], [3,4], [2,3], [1,1], [1,2], [0 ] ], [ 12, [ 12,1], [15,4], [14,3], [13,2], [13,2], [12,1] ] ], 166 167 F : [ [ 0, [1,1], [3,3], [3,4], [2,2], [1,1], [1,1] ], [ ] ], 168 Fm : [ [ 0, [1,1], [3,3], [3,4], [1,1], [1,1], [1,1] ], [ ] ], 169 F6 : [ [ 0, [-1 ], [3,2], [3,3], [2,1], [3,4], [-1 ] ], [ ] ], 170 Fm6 : [ [ 0, [-1 ], [-1 ], [0 ], [1,1], [1,1], [1,1] ], [ ] ], 171 F69 : [ [ 0, [1,1], [0 ], [0 ], [0 ], [1,2], [1,3] ], [ ] ], 172 F7 : [ [ 0, [1,1], [3,3], [1,1], [2,2], [1,1], [1,1] ], [ ] ], 173 Fm7 : [ [ 0, [1,1], [3,3], [3,4], [1,1], [4,4], [1,1] ], [ ] ], 174 Fmaj7 : [ [ 0, [1,1], [-1 ], [2,3], [2,4], [1,2], [-1 ] ], [ ] ], 175 F7b5 : [ [ 0, [1,1], [-1 ], [1,2], [2,3], [0 ], [-1 ] ], [ ] ], 176 "F7#5" : [ [ 0, [1,1], [-1 ], [1,2], [2,3], [2,4], [-1 ] ], [ ] ], 177 Fm7b5 : [ [ 2, [-1 ], [-1 ], [3,1], [4,2], [4,3], [4,4] ], [ ] ], 178 F7b9 : [ [ 0, [-1 ], [-1 ], [3,2], [2,1], [4,4], [2,1] ], [ ] ], 179 F9 : [ [ 0, [3,3], [0 ], [3,4], [2,2], [1,1], [1,1] ], [ ] ], 180 Fm9 : [ [ 0, [-1 ], [-1 ], [1,1], [1,1], [1,1], [3,4] ], [ ] ], 181 Fmaj9 : [ [ 0, [0 ], [0 ], [3,3], [0 ], [1,1], [3,4] ], [ ] ], 182 Fadd9 : [ [ 0, [-1 ], [-1 ], [3,3], [2,2], [1,1], [3,4] ], [ ] ], 183 F13 : [ [ 0, [1,1], [0 ], [1,2], [3,4], [3,4], [3,4] ], [ ] ], 184 Fsus2 : [ [ 0, [-1 ], [3,3], [3,4], [0 ], [1,1], [1,1] ], [ ] ], 185 Fsus4 : [ [ 0, [1,1], [3,2], [3,3], [3,4], [1,1], [1,1] ], [ ] ], 186 Fdim : [ [ 0, [-1 ], [-1 ], [0 ], [1,1], [0 ], [1,2] ], [ ] ], 187 Fdim7 : [ [ 0, [-1 ], [2,3], [0 ], [1,1], [0 ], [1,2] ], [ ] ], 188 Faug : [ [ 0, [1,1], [-1 ], [3,4], [2,2], [2,3], [1,1] ], [ ] ], 189 190 "F#" : [ [ 0, [2,1], [4,3], [4,4], [3,2], [2,1], [2,1] ], [ ] ], 191 "F#m" : [ [ 0, [2,1], [4,3], [4,4], [2,1], [2,1], [2,1] ], [ ] ], 192 "F#6" : [ [ 0, [2,1], [4,3], [-1 ], [3,2], [4,4], [-1 ] ], [ ] ], 193 "F#m6" : [ [ 0, [-1 ], [-1 ], [1,1], [2,2], [2,3], [2,4] ], [ ] ], 194 "F#69" : [ [ 0, [2,2], [1,1], [1,1], [1,1], [2,3], [2,4] ], [ ] ], 195 "F#7" : [ [ 0, [2,1], [4,3], [2,1], [3,2], [2,1], [2,1] ], [ ] ], 196 "F#m7" : [ [ 0, [2,1], [4,3], [4,4], [2,1], [5,4], [2,1] ], [ ] ], 197 "F#maj7": [ [ 0, [2,1], [-1 ], [3,3], [3,4], [2,2], [-1 ] ], [ ] ], 198 "F#7b5" : [ [ 0, [2,2], [-1 ], [2,3], [3,4], [1,1], [-1 ] ], [ ] ], 199 "F#7#5" : [ [ 0, [2,2], [-1 ], [2,3], [3,4], [3,4], [-1 ] ], [ ] ], 200 "F#m7b5": [ [ 0, [-1 ], [-1 ], [2,2], [2,3], [1,1], [2,4] ], [ ] ], 201 "F#7b9" : [ [ 0, [2,2], [1,1], [2,3], [0 ], [2,4], [0 ] ], [ ] ], 202 "F#9" : [ [ 0, [2,1], [4,3], [2,1], [3,2], [2,1], [4,4] ], [ ] ], 203 "F#m9" : [ [ 0, [3,3], [0 ], [3,4], [1,1], [2,3], [2,3] ], [ ] ], 204 "F#maj9": [ [ 0, [2,1], [-1 ], [3,2], [3,3], [-1 ], [4,4] ], [ ] ], 205 "F#add9": [ [ 0, [2,2], [1,1], [-1 ], [1,1], [2,3], [2,4] ], [ ] ], 206 "F#13" : [ [ 0, [2,1], [4,3], [2,1], [3,2], [4,4], [2,1] ], [ ] ], 207 "F#sus2": [ [ 0, [2,2], [-1 ], [-1 ], [1,1], [2,3], [2,4] ], [ ] ], 208 "F#sus4": [ [ 0, [2,1], [4,2], [4,3], [4,4], [2,1], [2,1] ], [ ] ], 209 "F#dim" : [ [ 0, [-1 ], [-1 ], [1,1], [2,3], [1,2], [2,4] ], [ ] ], 210 "F#dim7": [ [ 0, [-1 ], [-1 ], [1,1], [2,3], [1,2], [2,4] ], [ ] ], 211 "F#aug" : [ [ 0, [2,1], [-1 ], [4,4], [3,2], [3,3], [2,1] ], [ ] ], 212 213 G : [ [ 0, [3,3], [2,2], [0 ], [0 ], [0 ], [3,4] ], [ 12, [15,3], [14,2], [12,1], [12,1], [12,1], [15,4] ] ], 214 Gm : [ [ 0, [3,2], [1,1], [0 ], [0 ], [3,3], [3,4] ], [ 12, [15,3], [13,2], [12,1], [12,1], [15,4], [15,4] ] ], 215 G6 : [ [ 0, [3,3], [2,2], [0 ], [0 ], [0 ], [0 ] ], [ 12, [15,4], [14,3], [12,1], [12,1], [12,1], [12,1] ] ], 216 Gm6 : [ [ 0, [-1 ], [-1 ], [2,1], [3,3], [3,3], [3,3] ], [ ] ], 217 G69 : [ [ 0, [3,3], [2,1], [0 ], [2,2], [0 ], [0 ] ], [ 12, [15,4], [14,3], [12,1], [14,2], [12,1], [12,1] ] ], 218 G7 : [ [ 0, [3,3], [2,2], [0 ], [0 ], [0 ], [1,1] ], [ 12, [15,4], [14,3], [12,1], [12,1], [12,1], [13,2] ] ], 219 Gm7 : [ [ 0, [-1 ], [1,1], [3,3], [0 ], [3,4], [-1 ] ], [ 12, [-1 ], [13,2], [15,3], [12,1], [15,4], [-1 ] ] ], 220 Gmaj7 : [ [ 0, [3,3], [2,2], [0 ], [0 ], [0 ], [2,1] ], [ 12, [15,3], [14,2], [12,1], [12,1], [12,1], [14,4] ] ], 221 "G7b5" : [ [ 0, [3,2], [-1 ], [3,3], [4,4], [2,1], [-1 ] ], [ ], [ 4, [-1 ], [-1 ], [5,1], [6,2], [6,3], [7,4] ] ], 222 "G7#5" : [ [ 0, [3,1], [-1 ], [3,2], [4,3], [4,4], [-1 ] ], [ ] ], 223 Gm7b5 : [ [ 2, [3,1], [4,2], [3,1], [3,1], [6,4], [3,1] ], [ ] ], 224 G7b9 : [ [ 0, [3,4], [2,3], [0 ], [1,1], [0 ], [1,2] ], [ 12, [15,4], [14,3], [12,1], [13,2], [12,1], [13,] ] ], 225 G9 : [ [ 0, [3,3], [-1 ], [0 ], [2,2], [0 ], [1,1] ], [ 12, [15,4], [-1 ], [12,1], [14,3], [12,1], [13,2] ] ], 226 Gm9 : [ [ 2, [3,1], [5,3], [3,1], [3,1], [3,1], [5,4] ], [ ] ], 227 Gmaj9 : [ [ 0, [3,3], [-1 ], [0 ], [2,1], [0 ], [2,2] ], [ 12, [15,4], [-1 ], [12,1], [14,3], [12,1], [14,2] ] ], 228 Gadd9 : [ [ 0, [3,2], [0 ], [0 ], [0 ], [0 ], [3,3] ], [ 12, [15,3], [12,1], [12,1], [12,1], [12,1], [15,4] ] ], 229 G13 : [ [ 0, [3,2], [2,1], [3,3], [0 ], [0 ], [0 ] ], [ 12, [15,3], [14,2], [15,3], [12,1], [12,1], [12,1] ] ], 230 Gsus2 : [ [ 0, [3,1], [0 ], [0 ], [0 ], [3,3], [3,4] ], [ 12, [15,2], [12,1], [12,1], [12,1], [15,3], [15,4] ] ], 231 Gsus4 : [ [ 2, [3,1], [5,2], [5,3], [5,4], [3,1], [3,1] ], [ ] ], 232 Gdim : [ [ 2, [-1 ], [-1 ], [5,2], [6,4], [5,3], [3,1] ], [ ] ], 233 Gdim7 : [ [ 0, [-1 ], [-1 ], [2,1], [3,3], [2,2], [3,4] ], [ ] ], 234 Gaug : [ [ 0, [3,1], [-1 ], [5,4], [4,2], [4,3], [3,1] ], [ ] ], 235 236 "G#" : [ [ 0, [4,4], [3,3], [1,1], [1,1], [1,1], [-1 ] ], [ ] ], 237 "G#m" : [ [ 0, [-1 ], [2,2], [1,1], [1,1], [4,4], [4,4] ], [ ] ], 238 "G#6" : [ [ 0, [-1 ], [-1 ], [1,1], [1,1], [1,1], [1,1] ], [ ] ], 239 "G#m6" : [ [ 0, [-1 ], [-1 ], [1,1], [1,2], [0 ], [1,3] ], [ ] ], 240 "G#69" : [ [ 0, [4,2], [3,1], [3,1], [3,1], [4,3], [4,4] ], [ ] ], 241 "G#7" : [ [ 0, [-1 ], [-1 ], [1,1], [1,1], [1,1], [2,2] ], [ ] ], 242 "G#m7" : [ [ 3, [4,1], [6,3], [4,1], [4,1], [7,4], [4,1] ], [ ] ], 243 "G#maj7": [ [ 0, [-1 ], [-1 ], [1,1], [1,1], [1,1], [3,3] ], [ ] ], 244 "G#7b5" : [ [ 2, [4,2], [-1 ], [4,3], [5,4], [3,2], [-1 ] ], [ ] ], 245 "G#7#5" : [ [ 3, [4,1], [-1 ], [4,2], [5,3], [5,4], [-1 ] ], [ ] ], 246 "G#m7b5": [ [ 0, [4,1], [5,2], [4,1], [4,1], [7,4], [4,1] ], [ ] ], 247 "G#7b9" : [ [ 0, [4,3], [3,2], [4,4], [2,1], [-1 ], [-1 ] ], [ ] ], 248 "G#9" : [ [ 0, [2,2], [1,1], [1,1], [1,1], [1,1], [2,4] ], [ ] ], 249 "G#m9" : [ [ 0, [2,2], [1,1], [1,1], [1,1], [0 ], [2,4] ], [ ] ], 250 "G#maj9": [ [ 2, [4,2], [3,1], [5,4], [3,1], [4,3], [-1 ] ], [ ] ], 251 "G#add9": [ [ 0, [-1 ], [1,1], [1,1], [1,1], [1,1], [-1 ] ], [ ] ], 252 "G#13" : [ [ 0, [4,3], [3,2], [4,4], [1,1], [1,1], [1,1] ], [ ] ], 253 "G#sus2": [ [ 0, [-1 ], [1,1], [1,2], [1,3], [-1 ], [-1 ] ], [ ] ], 254 "G#sus4": [ [ 0, [-1 ], [-1 ], [1,1], [1,1], [2,2], [4,4] ], [ ] ], 255 "G#dim" : [ [ 0, [-1 ], [-1 ], [0 ], [1,1], [0 ], [1,2] ], [ ] ], 256 "G#dim7": [ [ 0, [-1 ], [-1 ], [0 ], [1,1], [0 ], [1,2] ], [ ] ], 257 "G#aug" : [ [ 0, [0,-1], [3,4], [2,3], [1,1], [1,2], [0,-1] ], [ ] ], 258 259 A : [ [ 0, [-1], [0 ], [2,2], [2,1], [2,3], [0 ] ], [ 12, [-1,-1], [12,1], [14,2], [14,3], [14,4], [12,1] ] ], 260 Am : [ [ 0, [-1], [0 ], [2,2], [2,3], [1,1], [0 ] ], [ 12, [-1,-1], [12,1], [14,3], [14,4], [13,2], [12,1] ] ], 261 A6 : [ [ 0, [-1], [0 ], [2,1], [2,1], [2,1], [2,1] ], [ 12, [-1,-1], [12,1], [14,3], [14,3], [14,3], [14,3] ] ], 262 Am6 : [ [ 0, [-1], [0 ], [2,2], [2,3], [1,1], [2,4] ], [ 12, [-1,-1], [12,1], [14,3], [14,3], [13,2], [14,4] ] ], 263 A69 : [ [ 3, [5,2], [4,1], [4,1], [4,1], [5,3], [5,4] ], [ ] ], 264 A7 : [ [ 0, [-1], [0 ], [2,2], [0 ], [2,3], [0 ] ], [ 12, [-1,-1], [12,1], [14,2], [12,1], [14,3], [12,1] ] ], 265 Am7 : [ [ 0, [-1], [0 ], [2,2], [0 ], [1,1], [0 ] ], [ 12, [-1,-1], [12,1], [14,3], [12,1], [13,2], [12,1] ] ], 266 Amaj7 : [ [ 0, [-1], [0 ], [2,2], [1,1], [2,3], [0 ] ], [ 12, [-1,-1], [12,1], [14,3], [13,2], [14,4], [12,1] ] ], 267 A7b5 : [ [ 3, [5,2], [-1 ], [5,3], [6,4], [4,1], [-1 ] ], [ ] ], 268 "A7#5" : [ [ 4, [5,1], [-1 ], [5,2], [6,3], [6,4], [-1 ] ], [ ] ], 269 Am7b5 : [ [ 0, [-1], [-1 ], [1,1], [2,3], [1,2], [3,4] ], [ ] ], 270 A7b9 : [ [ 0, [-1], [0 ], [2,1], [3,3], [2,2], [3,4] ], [ 12, [-1,-1], [12,''], [14,1], [15,3], [14,2], [15,4] ] ], 271 A9 : [ [ 0, [-1], [0 ], [2,1], [4,4], [2,2], [3,3] ], [ 12, [-1], [12,], [14,1], [16,4], [14,2], [15,3] ] ], 272 Am9 : [ [ 0, [-1], [0 ], [1,1], [1,1], [1,1], [3,4] ], [ 12, [-1], [12,1], [13,2], [13,2], [13,2], [15,4] ] ], 273 Amaj9 : [ [ 0, [-1], [0 ], [2,1], [4,3], [2,1], [4,4] ], [ 12, [-1], [12, ], [14,1], [16,3], [14,1], [16,4] ] ], 274 Aadd9 : [ [ 0, [-1], [0 ], [2,2], [2,3], [0 ], [0 ] ], [ 12, [-1], [12,1], [14,3], [14,4], [12,1], [12,1] ] ], 275 A13 : [ [ 0, [-1], [0 ], [2,1], [0 ], [2,2], [3,3] ], [ 12, [-1], [12,1], [14,2], [12,1], [14,3], [15,4] ] ], 276 Asus2 : [ [ 0, [-1], [0 ], [2,1], [2,2], [0 ], [0 ] ], [ 12, [-1], [12,1], [14,3], [14,4], [12,1], [12,1] ] ], 277 Asus4 : [ [ 0, [-1], [0 ], [2,1], [2,2], [3,3], [0 ] ], [ 12, [-1], [12,1], [14,2], [14,3], [15,4], [12,1] ] ], 278 Adim : [ [ 0, [-1], [0 ], [1,1], [2,3], [1,2], [-1 ] ], [ 12, [-1], [12,1], [13,2], [14,4], [13,3], [-1 ] ] ], 279 Adim7 : [ [ 0, [-1], [-1 ], [1,1], [2,3], [1,2], [2,4] ], [ ] ], 280 Aaug : [ [ 0, [-1], [0 ], [3,4], [2,2], [2,3], [1,1] ], [ 12, [-1], [12,], [15,4], [14,2], [14,3], [13,1] ] ], 281 282 "Bb" : [ [ 0, [-1], [1,1], [3,3], [3,3], [3,3], [1,1] ], [ ] ], 283 "Bbm" : [ [ 0, [-1], [1,1], [3,3], [3,4], [2,2], [1,1] ], [ ] ], 284 "Bb6" : [ [ 0, [-1], [1,1], [3,3], [3,3], [3,3], [3,3] ], [ ] ], 285 "Bbm6" : [ [ 0, [-1], [1,1], [3,3], [0 ], [2,2], [-1 ] ], [ ] ], 286 "Bb69" : [ [ 0, [-1], [1,1], [0 ], [0 ], [1,2], [1,3] ], [ ] ], 287 "Bb7" : [ [ 0, [-1], [1,1], [3,3], [1,1], [4,4], [1,1] ], [ ] ], 288 "Bbm7" : [ [ 0, [-1], [1,1], [3,3], [1,1], [2,2], [1,1] ], [ ] ], 289 "Bbmaj7": [ [ 0, [-1], [1,1], [3,3], [2,2], [3,4], [1,1] ], [ ] ], 290 "Bb7b5" : [ [ 4, [6,2], [-1 ], [6,3], [7,4], [5,1], [-1 ] ], [ ] ], 291 "Bb7#5" : [ [ 5, [6,1], [-1 ], [6,2], [7,3], [7,4], [-1 ] ], [ ] ], 292 "Bbm7b5": [ [ 0, [-1], [1,1], [-1 ], [1,2], [2,3], [-1 ] ], [ ] ], 293 "Bb7b9" : [ [ 6, [-1], [-1 ], [8,2], [7,1], [9,4], [7,1] ], [ ] ], 294 "Bb9" : [ [ 0, [1,1], [1,2], [0 ], [1,3], [1,3], [1,3] ], [ ] ], 295 "Bbm9" : [ [ 5, [-1], [-1 ], [-1 ], [6,1], [6,1], [8,4] ], [ ] ], 296 "Bbmaj9": [ [ 0, [-1], [1,1], [0 ], [2,4], [1,2], [1,3] ], [ ] ], 297 "Bbadd9": [ [ 0, [1,1], [1,1], [0 ], [3,4], [1,1], [1,1] ], [ ] ], 298 "Bb13" : [ [ 0, [-1 ], [1,1], [0 ], [1,2], [3,4], [3,4] ], [ ] ], 299 "Bbsus2": [ [ 0, [-1], [1,1], [3,3], [3,4], [1,1], [1,1] ], [ ] ], 300 "Bbsus4": [ [ 0, [-1], [1,1], [3,2], [3,3], [4,4], [1,1] ], [ ] ], 301 "Bbdim" : [ [ 0, [-1], [1,1], [2,2], [3,4], [2,3], [-1 ] ], [ ] ], 302 "Bbdim7": [ [ 0, [-1], [-1 ], [2,1], [3,3], [2,2], [3,4] ], [ ] ], 303 "Bbaug" : [ [ 0, [-1], [1,1], [4,4], [3,2], [3,3], [2,1] ], [ ] ], 304 305 B : [ [ 0, [ -1], [2,1], [4,3], [4,3], [4,3], [2,1] ], [ ] ], 306 Bm : [ [ 0, [ -1], [2,1], [4,3], [4,4], [3,2], [2,1] ], [ ] ], 307 B6 : [ [ 0, [ -1], [2,1], [4,3], [4,3], [4,3], [4,3] ], [ ] ], 308 Bm6 : [ [ 0, [ -1], [-1 ], [4,2], [4,3], [3,1], [4,4] ], [ ] ], 309 B69 : [ [ 0, [ -1], [2,2], [1,1], [1,1], [2,3], [2,4] ], [ ] ], 310 B7 : [ [ 0, [ -1], [2,2], [1,1], [2,3], [0 ], [2,4] ], [ ] ], 311 Bm7 : [ [ 0, [ -1], [2,2], [0 ], [2,3], [0 ], [2,4] ], [ ] ], 312 Bmaj7 : [ [ 0, [ -1], [2,1], [4,3], [3,2], [4,4], [2,1] ], [ ] ], 313 B7b5 : [ [ 5, [7,2], [-1 ], [7,3], [8,4], [6,1], [-1 ] ], [ ] ], 314 "B7#5" : [ [ 0, [ -1], [2,2], [1,1], [2,3], [0 ], [3,4] ], [ ] ], 315 "Bm7b5" : [ [ 0, [-1 ], [2,2], [0 ], [2,3], [0 ], [1,1] ], [ ] ], 316 B7b9 : [ [ 0, [ -1], [2,2], [1,1], [2,3], [1,1], [2,4] ], [ ] ], 317 B9 : [ [ 6, [7,1], [9,3], [7,1], [8,2], [7,1], [9,4] ], [ ] ], 318 Bm9 : [ [ 0, [ -1], [2,1], [0 ], [2,2], [2,3], [2,4] ], [ ] ], 319 Bmaj9 : [ [ 0, [ -1], [2,2], [1,1], [3,4], [2,3], [2,3] ], [ ] ], 320 Badd9 : [ [ 0, [ -1], [2,1], [4,3], [4,4], [2,1], [2,1] ], [ ] ], 321 B13 : [ [ 0, [-1 ], [2,2], [1,1], [2,3], [0 ], [4,4] ], [ ] ], 322 Bsus2 : [ [ 0, [ -1], [2,1], [4,3], [4,4], [2,1], [2,1] ], [ ] ], 323 Bsus4 : [ [ 0, [ -1], [2,1], [4,2], [4,3], [5,4], [2,1] ], [ ] ], 324 Bdim : [ [ 0, [-1], [2,1], [3,2], [4,4], [3,3], [-1 ] ], [ ] ], 325 Bdim7 : [ [ 0, [-1], [-1 ], [0 ], [1,1], [0 ], [1,2] ], [ ] ], 326 Baug : [ [ 0, [-1], [2,1], [5,4], [4,2], [4,3], [3,1] ], [ ] ] 327 }, 328 WesternScale: { 329 BaseNotes: { // for each: array[ translated western scale note, caged base, base fret ] 330 'C' : [ 'C' , 'C', 0 ], 331 'C#': [ 'C#', 'C', 1 ], 332 'Db': [ 'C#', 'C', 1 ], 333 'D' : [ 'D' , 'D', 0 ], 334 'D#': [ 'Eb', 'D', 1 ], 335 'Eb': [ 'Eb', 'D', 1 ], 336 'E' : [ 'E' , 'E', 0 ], 337 'F' : [ 'F' , 'E', 1 ], 338 'F#': [ 'F#', 'E', 2 ], 339 'Gb': [ 'F#', 'E', 2 ], 340 'G' : [ 'G' , 'G', 0 ], 341 'G#': [ 'G#', 'G', 1 ], 342 'Ab': [ 'G#', 'G', 1 ], 343 'A' : [ 'A' , 'A', 0 ], 344 'A#': [ 'Bb', 'A', 1 ], 345 'Bb': [ 'Bb', 'A', 1 ], 346 'B' : [ 'B' , 'A', 2 ] 347 }, 348 BaseIntervals: ['C', 'C#', 'D', 'Eb', 'E', 'F', 'F#', 'G', 'G#', 'A', 'Bb', 'B'] 349 }, 350 ChordList : function() { 351 var list = []; 352 for (var key in jtab.Chords) { 353 list.push( key ); 354 } 355 return list; 356 }, 357 /* 358 * Usage: jtab.AddChord("ChordName", Chord-Array) 359 * Example of Add: jtab.AddChord("Dsus4l", [ [ 0, [-1 ], [-1 ], [3,2], [2,1], [3,3], [3,4] ], [ 12, [-1,-1], [-1,-1], [12,1], [14,2], [15,3], [15,4] ] ]); 360 * Example of Update: jtab.AddChord("A", [ [ 0, [-1], [0 ], [2,3], [2,2], [2,1], [0 ] ], [ 12, [-1,-1], [12,1], [14,2], [14,3], [14,4], [12,1] ] ]); 361 */ 362 AddChord : function(chordName, chord) { 363 this.Chords[chordName] = chord; 364 } 365 }; 366 367 // 368 // define Array utility functions 369 // 370 371 Array.prototype.max_chars = function() { 372 var max = this[0].length; 373 var len = this.length; 374 for (var i = 1; i < len; i++) if (this[i].length > max) max = this[i].length; 375 return max; 376 } 377 378 379 // 380 // define jtabChord class 381 // public members: 382 // isValid = whether valid chord defined 383 // isCaged = whether chord is CAGED type 384 // isCustom = whether chord is a custom fingering 385 // fullChordName = full chord name, including position e.g. D#m7:3 386 // chordName = chord name, without position e.g. D#m7 387 // baseName = translated chord name (B <-> #), without position e.g. Ebm7 388 // rootNote = root note e.g. D# 389 // rootExt = root note extension e.g. m7 390 // cagedBaseShape = caged base shape e.g. D 391 // cagedBaseFret = caged base fret e.g. 0 392 // cagedPos = caged position e.g. 3 393 // 394 395 function jtabChord (token) { 396 397 this.scale = jtab.WesternScale; 398 this.baseNotes = this.scale.BaseNotes; 399 this.baseChords = jtab.Chords; 400 this.chordArray = null; 401 this.isValid = false; 402 403 this.fullChordName = token; 404 this.isCustom = ( this.fullChordName.match( /\%/ ) != null ) 405 this.isCaged = ( this.fullChordName.match( /\:/ ) != null ) 406 407 if (this.isCaged) { 408 var parts = this.fullChordName.split(':'); 409 this.chordName = parts[0]; 410 this.cagedPos = parts[1]; 411 } else if (this.isCustom){ 412 var parts = this.fullChordName.match( /\[(.+?)\]/ ); 413 if(parts){ 414 this.chordName = parts[1]; 415 } else { 416 this.chordName = ''; 417 } 418 } else { 419 this.chordName = this.fullChordName; 420 this.cagedPos = 1; 421 } 422 this.rootExt = this.chordName.replace(/^[A-G#b]{1,2}/,''); 423 this.rootNote = this.chordName.substr(0, this.chordName.length - this.rootExt.length); 424 var baseNoteInfo = this.baseNotes[this.rootNote]; 425 if (baseNoteInfo) { 426 this.baseName = baseNoteInfo[0] + this.rootExt; 427 this.cagedBaseShape = baseNoteInfo[1]; 428 this.cagedBaseFret = baseNoteInfo[2]; 429 } else { 430 this.cagedBaseShape = ''; 431 this.cagedBaseFret = 0; 432 } 433 434 if ( ( this.isCaged ) && ( this.cagedPos > 1 ) ) { 435 this.setCagedChordArray(); 436 } else if (this.isCustom){ 437 this.setCustomChordArray(); 438 } else { 439 this.setChordArray(this.baseName); 440 } 441 } 442 443 jtabChord.prototype.setCustomChordArray = function(){ 444 this.chordArray = new Array(); 445 this.chordArray = this.parseCustomChordArrayFromToken(); 446 }; 447 448 jtabChord.prototype.parseCustomChordArrayFromToken = function() { 449 notes = this.fullChordName.replace(/(\%|\[.+\])/g, ''); 450 pairs = notes.split('.'); 451 if (pairs.length < 6){ 452 this.isValid = false; 453 return; 454 } 455 this.isValid = true; 456 457 array = []; 458 for (var i = 0; i < pairs.length; i++){ 459 pair = pairs[i].split('/') 460 if (pair[0].match(/X/)){ 461 pair = [-1] 462 } 463 array.push(pair) 464 } 465 466 fingeredFrets = jQuery.grep(array, function(pair){ 467 return (pair.length != 1); 468 }).map(function(pair){ 469 return parseInt(pair[0]); 470 }).map(function(i){ 471 if ((i != 0) || (i != -1)){ 472 return i; 473 } else { 474 return null; 475 } 476 }) 477 478 fingeredFrets = jQuery.grep(fingeredFrets,function(n){ 479 return(n); 480 }); 481 482 min = Math.min.apply( Math, fingeredFrets ); 483 484 array.unshift(min-1); 485 return array; 486 }; 487 488 jtabChord.prototype.setChordArray = function(chordName) { // clones chord array (position 0) from chord ref data into this object 489 this.chordArray = new Array(); 490 if (this.baseChords[chordName] === undefined ) { 491 this.isValid = false; 492 return; 493 } 494 this.isValid = true; 495 var modelRef = this.baseChords[chordName][0]; 496 this.chordArray[0] = modelRef[0] 497 for (var i = 1; i < modelRef.length ; i++) { 498 this.chordArray[i] = modelRef[i]; // TODO: this.chordArray[i] = modelRef[i].clone(); 499 } 500 }; 501 502 jtabChord.prototype.setCagedChordArray = function() { 503 if ( ! this.cagedBaseShape.match( /[CAGED]/ ) ) return; 504 var caged_index = "CAGED".indexOf(this.cagedBaseShape) + 1; 505 var fret_widths = [3,2,3,2,2]; 506 var starting_fret = this.cagedBaseFret; 507 508 for (var i = 1; i < this.cagedPos ; i++) { 509 var index = (caged_index - 1) % 5; 510 caged_index = ( caged_index >= 5) ? 1 : caged_index + 1; 511 starting_fret += fret_widths[index]; 512 } 513 514 var modelChord = "CAGED".charAt( caged_index - 1 ) + this.rootExt; 515 this.setChordArray(modelChord); 516 this.shiftChordArray(starting_fret,modelChord); 517 }; 518 519 jtabChord.prototype.shiftChordArray = function(atFret,modelChord) { 520 var initFret = this.chordArray[0]; 521 if (atFret != initFret) { 522 var use_caged_fingering = ( (this.isCaged) && (this.cagedPos > 0) && ( ! ( this.baseChords[modelChord][1][0] === undefined ) ) ); 523 524 this.chordArray[0] = atFret - 1; 525 for (var i = 1; i < this.chordArray.length ; i++) { 526 var fret = (this.chordArray[i][0] >= 0 ) ? this.chordArray[i][0] + atFret - initFret : this.chordArray[i][0]; 527 var finger = (use_caged_fingering) ? this.baseChords[modelChord][1][i][1] : this.chordArray[i][1]; 528 this.chordArray[i] = [ fret , finger ]; 529 } 530 } 531 }; 532 533 Raphael.fn.tabtype = 0; // 0 = none, 1 = tab & chord, 2 = chord, 3 = tab 534 Raphael.fn.has_chord = false; 535 Raphael.fn.has_tab = false; 536 537 Raphael.fn.debug = false; 538 Raphael.fn.scale = 1; 539 Raphael.fn.margin_top = 36; 540 Raphael.fn.margin_bottom = 10; 541 Raphael.fn.margin_left = 16; 542 Raphael.fn.margin_right = 10; 543 544 Raphael.fn.current_offset = Raphael.fn.margin_left; 545 546 Raphael.fn.string_spacing = 16; 547 Raphael.fn.strings_drawn = 6; 548 Raphael.fn.fret_spacing = 16; 549 Raphael.fn.frets_drawn = 4; 550 Raphael.fn.note_radius = 7; 551 552 Raphael.fn.fret_width = Raphael.fn.string_spacing * ( Raphael.fn.strings_drawn - 1 ); 553 Raphael.fn.fret_height = Raphael.fn.fret_spacing * (Raphael.fn.frets_drawn + 0.5); 554 Raphael.fn.chord_width = Raphael.fn.margin_left + Raphael.fn.fret_width + Raphael.fn.string_spacing + Raphael.fn.margin_right; 555 Raphael.fn.chord_height = Raphael.fn.margin_top + Raphael.fn.fret_height + Raphael.fn.margin_bottom; 556 557 Raphael.fn.tab_current_string = 0; // 1,2,3,4,5,6 or 0 = not set 558 Raphael.fn.tab_margin_top = 10; 559 Raphael.fn.tab_top = Raphael.fn.chord_height + Raphael.fn.tab_margin_top; 560 Raphael.fn.tab_spacing = Raphael.fn.fret_spacing; 561 Raphael.fn.tab_height = Raphael.fn.tab_spacing * 5; 562 Raphael.fn.tab_char_width = 8; 563 564 Raphael.fn.total_height = Raphael.fn.tab_top + Raphael.fn.tab_height + Raphael.fn.margin_bottom; 565 566 Raphael.fn.color = "#000"; 567 Raphael.fn.fingering_text_color = "#fff"; 568 Raphael.fn.tab_text_color = "#000"; 569 570 571 // debug helper - puts grid marks on the rendered image 572 Raphael.fn.debug_grid = function (width) { 573 // h ticks 574 this.path(this.svg_params(this.current_offset, 0,0,4)).attr({stroke: this.color, "stroke-width":0.2 }) 575 this.path(this.svg_params( this.current_offset + this.margin_left, 0,0,2)).attr({stroke: this.color, "stroke-width":0.2 }) 576 this.path(this.svg_params( this.current_offset + width - this.margin_right, 0,0,2)).attr({stroke: this.color, "stroke-width":0.2 }) 577 // v ticks 578 if (this.tabtype == 3) { 579 this.path(this.svg_params(this.current_offset, this.tab_margin_top,2,0)).attr({stroke: this.color, "stroke-width":0.2 }) 580 } else { 581 this.path(this.svg_params(this.current_offset, this.margin_top,2, 0)).attr({stroke: this.color, "stroke-width":0.2 }) 582 } 583 } 584 585 586 // step the current position for drawing 587 Raphael.fn.increment_offset = function (width) { 588 w = ( width === undefined ) ? this.chord_width : width; 589 if (this.debug) this.debug_grid(w); 590 this.current_offset += w; 591 this.setSize( this.current_offset, this.total_height ); 592 } 593 594 Raphael.fn.svg_params = function(x,y,l1,l2) { 595 // http://www.w3.org/TR/SVG/paths.html#PathData --helpful reading 596 var move_line_to = "m"+x+" "+y+"l"+l1+" "+l2 597 if(arguments.length == 4) return move_line_to 598 } 599 600 // draw the fretboard 601 Raphael.fn.chord_fretboard = function ( position, chord_name ) { 602 var fret_left = this.current_offset + this.margin_left; 603 // conventional fret labels 604 var fret_labels = [ '', '', '', 'III', '', 'V', '', 'VII', '', 'IX', '', '', 'XII', '', '', 'XV', '', 'XVII', '', 'XIX', '', 'XXI', '' ]; 605 // alternative friendly fret labels. Currently disabled, maybe bring these back as a configurable option? 606 // var fret_labels = [ '', '1fr', '2fr', '3fr', '4fr', '5fr', '6fr', '7fr', '8fr', '9fr', '10fr', '11fr', '12fr', '13fr', '14fr', '15fr', '16fr', '17fr', '18fr', '19fr', '20fr', '21fr', '' ]; 607 608 this.text( // chord name 609 fret_left + 2.5 * this.string_spacing, 610 this.margin_top - 20, 611 chord_name).attr({fill: this.tab_text_color, "font-size":"20px"}); 612 613 var stroke_width = position == 0 ? 3 : 0 // nut 614 var chord_fretboard_path = this.path(this.svg_params(fret_left,this.margin_top,this.string_spacing * (this.strings_drawn - 1),0)) 615 chord_fretboard_path.attr({stroke: this.color, "stroke-width":stroke_width }) 616 617 for (var i = 0; i <= this.frets_drawn; i++ ) { // frets 618 619 this.path(this.svg_params(fret_left,this.margin_top + (i * this.fret_spacing),this.string_spacing * (this.strings_drawn - 1), 0)) 620 621 pos = ( fret_labels[ position + i ] === undefined ) ? '' : fret_labels[ position + i ]; 622 623 if ( pos.length > 0 ) { // draw fret position 624 this.text( 625 fret_left + this.fret_width + this.string_spacing * 1.0, 626 this.margin_top + ( ( i - 0.5 ) * this.fret_spacing), 627 pos).attr({stroke: this.tab_text_color, "font-size":"12px"}); 628 } 629 } 630 for (var i = 0; i < this.strings_drawn; i++ ) { 631 this.path(this.svg_params(fret_left + (i * this.string_spacing),this.margin_top,0, this.fret_spacing * (this.frets_drawn + 0.5))) // strings 632 } 633 this.tab_extend(this.chord_width); // extend the tab if present 634 } 635 636 637 // draw a stroke (/) 638 Raphael.fn.stroke = function () { 639 640 if (this.has_tab) { 641 var width = this.tab_char_width * 3; 642 // extend tab 643 this.tab_extend(width); 644 // stroke 645 var stroke_path = this.path(this.svg_params(this.current_offset + this.tab_char_width, this.tab_top + (3.5 * this.tab_spacing),this.tab_char_width, - 2 * this.tab_spacing)) 646 stroke_path.attr({stroke: this.tab_text_color, "stroke-width":4 }) 647 648 this.increment_offset(width); 649 } else if (this.has_chord) { 650 var dx = this.string_spacing; 651 var dy = 2 * this.fret_spacing; 652 this.path(this.svg_params(this.current_offset + this.margin_left, 653 this.margin_top + this.fret_spacing + dy,dx,-dy)).attr({stroke: this.tab_text_color, "stroke-width":4 }) 654 655 this.increment_offset( this.margin_left + dx + this.margin_right ); 656 } 657 } 658 659 660 // draw a bar 661 Raphael.fn.bar = function () { 662 663 if (this.has_tab) { 664 var width = this.tab_char_width * 2; 665 // extend tab 666 this.tab_extend(width); 667 var bar_stroke=this.path(this.svg_params(this.current_offset + this.tab_char_width, this.tab_top,0, this.tab_height)) 668 this.increment_offset(width); 669 670 } else if (this.has_chord) { 671 var fret_left = this.current_offset + this.margin_left; 672 var bar_stroke=this.path(this.svg_params(this.current_offset + this.margin_left, this.margin_top,0, 0, this.fret_height)) 673 this.increment_offset( this.margin_left + this.margin_right ); 674 } 675 bar_stroke.attr({stroke: this.color, "stroke-width":1 }) 676 677 } 678 679 680 // draw double bar 681 Raphael.fn.doublebar = function () { 682 if (this.has_tab) { 683 var width = this.tab_char_width + 8; 684 // extend tab 685 this.tab_extend(width); 686 // bar 687 var path_1 = this.path(this.svg_params(this.current_offset + this.tab_char_width, this.tab_top,0, this.tab_height)) 688 var path_2 = this.path(this.svg_params(this.current_offset + this.tab_char_width + 6, this.tab_top,0, this.tab_height )) 689 this.increment_offset(width); 690 691 } else if (this.has_chord) { 692 var left = this.current_offset + this.margin_left; 693 694 var path_1 = this.path(this.svg_params(left, this.margin_top,0, this.fret_height)) 695 var path_2 = this.path(this.svg_params(left + 6, this.margin_top,0, this.fret_height)) 696 697 this.increment_offset( this.margin_left + 6 + this.margin_right ); 698 } 699 path_1.attr({stroke: this.color, "stroke-width":1 }) 700 path_2.attr({stroke: this.color, "stroke-width":4 }) 701 } 702 703 704 // draw a note in a chord 705 Raphael.fn.chord_note = function (position, string_number, note) { 706 // NB: internal string_number in chords counts from low to high 707 var fret_number = note[0]; 708 var fret_left = this.current_offset + this.margin_left; 709 710 if (fret_number < 0 ) { 711 // muted/not played 712 this.text(fret_left + (string_number - 1) * this.string_spacing, this.margin_top - 8, "x").attr({stroke: this.tab_text_color, "font-size":"9px"}); 713 } else if (fret_number == 0 ) { 714 // open 715 this.text(fret_left + (string_number - 1) * this.string_spacing, this.margin_top - 8, "o").attr({stroke: this.tab_text_color, "font-size":"9px"}); 716 } else { 717 var fret_dy = (fret_number - position - 0.5) * this.fret_spacing; 718 //var circle = 719 this.circle( 720 fret_left + (string_number - 1) * this.string_spacing, 721 this.margin_top + fret_dy, this.note_radius).attr({stroke: this.color, fill: this.color}); 722 if ( ! (note[1] === undefined) ) { 723 this.text( fret_left + (string_number - 1) * this.string_spacing, 724 this.margin_top + fret_dy, note[1] ).attr({fill: this.fingering_text_color, "font-size":"12px"}); 725 } 726 } 727 728 if ( this.has_tab && fret_number >= 0 ) { 729 this.draw_tab_note( (this.strings_drawn - string_number + 1), fret_number, this.margin_left + this.string_spacing * 2.5 ); 730 } 731 } 732 733 734 // extend the tab drawing area 735 Raphael.fn.tab_extend = function (width) { 736 if (this.has_tab == false) return; 737 for (var i = 0; i < this.strings_drawn; i++ ) { 738 this.path(this.svg_params(this.current_offset, this.tab_top + (i * this.tab_spacing),width, 0)).attr({stroke: this.color}) 739 } 740 } 741 742 743 // start the tab 744 Raphael.fn.tab_start = function () { 745 if (this.has_tab == false) return; 746 var width = this.tab_char_width * 3; 747 // start bar 748 this.path(this.svg_params(this.current_offset, this.tab_top,0, this.tab_height)).attr({stroke: this.color, "stroke-width":1 }) 749 750 // extend tab 751 this.tab_extend(width); 752 753 //write TAB 754 this.text(this.current_offset + this.tab_char_width, this.tab_top + this.tab_spacing * 1.5, "T").attr({stroke: this.color, "font-size":"14px"}); 755 this.text(this.current_offset + this.tab_char_width, this.tab_top + this.tab_spacing * 2.5, "A").attr({stroke: this.color, "font-size":"14px"}); 756 this.text(this.current_offset + this.tab_char_width, this.tab_top + this.tab_spacing * 3.5, "B").attr({stroke: this.color, "font-size":"14px"}); 757 this.increment_offset(width); 758 759 } 760 761 762 // draw an individual note in the tab 763 Raphael.fn.draw_tab_note = function (string_number, token, left_offset) { 764 // NB: internal string_number in tab counts from high to low 765 this.text(this.current_offset + left_offset, 766 this.tab_top + this.tab_spacing * (string_number - 1), 767 token).attr({fill: this.color, "font-size":"16px"}); 768 } 769 770 // gets string number from token $[1-6|EADGBe] 771 Raphael.fn.get_string_number = function (token) { 772 var string_number = null; 773 if ( token.match( /^\$[1-6]/ ) != null ) { 774 string_number = token.substr(1,1); 775 } else if ( token.match( /^\$[EADGBe]/ ) != null ) { 776 string_number = 6 - "EADGBe".indexOf(token.substr(1,1)); 777 } 778 return string_number; 779 } 780 781 782 // identify if full chord of notes specified i.e. A:1 = X02220 or C:4 = 8.10.10.9.8.8 783 // returns: 784 // false = not a full chord representation 785 // array = array of notes (low to high) 786 Raphael.fn.get_fullchord_notes = function (token) { 787 var rc = false; 788 if ( token.match( /[^\.xX0-9]/ ) != null ) { 789 rc = false; 790 } else { 791 if ( token.match( /\./ ) != null ) { 792 rc = token.split('.'); 793 } else { 794 rc = token.split(''); 795 } 796 if (rc.length != 6) rc = false; 797 } 798 return rc; 799 } 800 801 802 // draw a token on the tab 803 Raphael.fn.tab_note = function (token) { 804 if (this.has_tab == false) return; 805 806 if ( token.match( /\$/ ) != null ) { // contains a string specifier 807 if ( token.match( /\./ ) != null ) { // is a multi-string specifier 808 var parts = token.split("."); 809 var width = 2; 810 for (var i = 0; i < parts.length ; i++) { // get the max length of the multi-string specifiers 811 if ( parts[i].length > width ) width = parts[i].length; 812 } 813 width *= this.tab_char_width + 1; 814 this.tab_extend( width ); 815 for (var i = 0; i < parts.length ; i++) { 816 var part = parts[i]; 817 var string_number = this.get_string_number(part); 818 if (string_number != null) { 819 this.tab_current_string = string_number; 820 } else if ( this.tab_current_string > 0 ) { 821 this.draw_tab_note( this.tab_current_string, part, width * 0.5 ); 822 } 823 } 824 this.increment_offset( width ); 825 826 } else { // just a string setting 827 this.tab_current_string = this.get_string_number(token); 828 } 829 } else { 830 var fullchord_notes = this.get_fullchord_notes(token); 831 if ( fullchord_notes ) { 832 var max_chars = fullchord_notes.max_chars(); 833 var width = this.tab_char_width * (max_chars + 2); 834 this.tab_extend( width ); 835 for (var i = 0; i < fullchord_notes.length ; i++) { 836 this.draw_tab_note( 6 - i, fullchord_notes[i], width * 0.5 ); 837 } 838 this.increment_offset( width ); 839 } else if ( this.tab_current_string > 0 ) { // else draw literal, but only if a current string selected 840 var width = this.tab_char_width * ( token.length + 2 ); 841 this.tab_extend( width ); 842 this.draw_tab_note( this.tab_current_string, token, width * 0.5 ); 843 this.increment_offset( width ); 844 } 845 } 846 } 847 848 849 // main drawing routine entry point: to render a token - chord or tab 850 Raphael.fn.render_token = function (token) { 851 852 var c = new jtabChord(token); 853 854 if ( c.isValid ) { // draw chord 855 var chord = c.chordArray; 856 // this.chord_fretboard(chord[0], c.fullChordName ); 857 this.chord_fretboard(chord[0], c.chordName ); 858 for (var i = 1; i < chord.length ; i++) { 859 this.chord_note(chord[0], i, chord[i]); 860 } 861 this.increment_offset(); 862 863 } else { 864 if (token == "/" ) { 865 this.stroke(); 866 } else if (token == "|" ) { 867 this.bar(); 868 } else if (token == "||" ) { 869 this.doublebar(); 870 } else if ( this.has_tab ) { 871 this.tab_note( token ); 872 } 873 874 } 875 } 876 877 878 // 879 // add jtab class methods 880 // 881 882 883 // determine nature of the token stream 884 // returns: 885 // 1 : chord and tab present 886 // 2 : chord only 887 // 3 : tab only 888 // 0 : unknown 889 jtab.characterize = function (notation) { 890 var tabtype = 0; 891 892 if(notation == undefined){ 893 notation = ''; 894 } 895 896 var gotCustomChord = ( notation.match( /[\%]([0-4|T|X])?/ ) != undefined ); 897 var gotNormalChord = ( notation.match( /[^\$][A-G]|^[A-G]/ ) != undefined ); 898 var gotTab = ( ( notation.match( /\$/ ) != null ) || ( notation.match( /[^\%][0-9|Xx|\.]{6,}/ ) != null ) ); 899 var gotChord = gotNormalChord || gotCustomChord ; 900 901 // set defaults - apply scaling here (TODO) 902 Raphael.fn.current_offset = Raphael.fn.margin_left; 903 if ( gotChord && gotTab ) { // chord and tab 904 tabtype = 1; 905 Raphael.fn.has_chord = true; 906 Raphael.fn.has_tab = true; 907 Raphael.fn.tab_top = Raphael.fn.chord_height + Raphael.fn.tab_margin_top; 908 Raphael.fn.total_height = Raphael.fn.tab_top + Raphael.fn.tab_height + Raphael.fn.margin_bottom; 909 } else if ( gotChord ) { // chord only 910 tabtype = 2; 911 Raphael.fn.has_chord = true; 912 Raphael.fn.has_tab = false; 913 Raphael.fn.tab_top = Raphael.fn.chord_height + Raphael.fn.tab_margin_top; 914 Raphael.fn.total_height = Raphael.fn.chord_height; 915 } else if ( gotTab ) { // tab only 916 tabtype = 3; 917 Raphael.fn.has_chord = false; 918 Raphael.fn.has_tab = true; 919 Raphael.fn.tab_top = Raphael.fn.tab_margin_top; 920 Raphael.fn.total_height = Raphael.fn.tab_top + Raphael.fn.tab_height + Raphael.fn.margin_bottom; 921 } 922 Raphael.fn.tabtype = tabtype; 923 return tabtype; 924 } 925 926 // utility function to get calculated style based on given element 927 jtab.getStyle = function (element, style) { 928 var value = element.css(style); 929 if(!value) { 930 if(document.defaultView) { 931 value = document.defaultView.getComputedStyle(element[0], "").getPropertyValue(style); 932 } else if(element.currentStyle) { 933 value = element.currentStyle[style]; 934 } 935 } 936 937 return value; 938 } 939 940 // set color pallette for the jtab rendering 941 jtab.setPalette = function (element) { 942 var fgColor = jtab.getStyle( jQuery(element), 'color' ); 943 if (!fgColor) { 944 fgColor = '#000'; 945 } 946 Raphael.fn.color = fgColor; 947 Raphael.fn.tab_text_color = fgColor; 948 949 bgColor = jtab.getStyle( jQuery(element), 'background-color' ); 950 if (!bgColor || (bgColor == 'transparent') || (bgColor == 'rgba(0, 0, 0, 0)')) { 951 bgColor = '#fff'; 952 } 953 Raphael.fn.fingering_text_color = bgColor; 954 } 955 956 // Render the tab for a given +element+. 957 // +element+ is a DOM node 958 // +notation_text+ is the optional notation to render (if not specified, +element+ text content will be used) 959 // After rendering, the +element+ will be given the additional "rendered" class. 960 jtab.render = function (element,notation_text) { 961 962 var notation = notation_text || jQuery(element).text() || ''; 963 964 var tabtype = jtab.characterize( notation ); 965 if (tabtype == 0 ) return; 966 967 var rndID="builder_"+jtab.element_count++; 968 969 // add the Raphael canvas in its own DIV. this gets around an IE6 issue with not removing previous renderings 970 var canvas_holder = jQuery('<div id="'+rndID+'"></div>').css({height: Raphael.fn.total_height}); 971 972 jQuery(element).html(canvas_holder); 973 jtab.setPalette(element); 974 canvas = Raphael(rndID, 80, Raphael.fn.total_height ); 975 canvas.tab_start(); 976 977 var tokens = notation.split(/\s/); 978 for(var i = 0; i < tokens.length; i++) { 979 canvas.render_token(tokens[i]); 980 } 981 jQuery(element).addClass('rendered'); 982 } 983 984 // Render all nodes with class 'jtab'. 985 // +within_scope+ is an optional selector that will restrict rendering to only those nodes contained within. 986 jtab.renderimplicit = function(within_scope) { 987 jQuery('.jtab',within_scope).not('.rendered').each( function(name, index) { jtab.render(this); } ); 988 } 989 990 // initialize jtab library. 991 // Sets up to run implicit rendering on window.onload 992 jtab.init = function() { 993 var oldonload = window.onload; 994 window.onload = function() { 995 if (typeof oldonload == 'function') oldonload(); 996 jtab.renderimplicit(null); 997 } 998 } 999 1000 // bootstrap jtab when jQuery is ready 1001 jQuery(document).ready(function($) { 1002 jtab.init(); 1003 }); 1004