source: main/trunk/model-sites-dev/respooled/collect/popup-video-respooled/js/jtab.js@ 29882

Last change on this file since 29882 was 29882, checked in by davidb, 9 years ago

Supporting files for guitar tab and better mouse/touch event integration

  • Property svn:executable set to *
File size: 50.2 KB
Line 
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
371Array.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
395function 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
408 if (this.isCaged) {
409 var parts = this.fullChordName.split(':');
410 this.chordName = parts[0];
411 this.cagedPos = parts[1];
412 } else if (this.isCustom){
413 var parts = this.fullChordName.match( /\[(.+?)\]/ );
414 if(parts){
415 this.chordName = parts[1];
416 } else {
417 this.chordName = '';
418 }
419 } else {
420 this.chordName = this.fullChordName;
421 this.cagedPos = 1;
422 }
423 this.rootExt = this.chordName.replace(/^[A-G#b]{1,2}/,'');
424 this.rootNote = this.chordName.substr(0, this.chordName.length - this.rootExt.length);
425 var baseNoteInfo = this.baseNotes[this.rootNote];
426 if (baseNoteInfo) {
427 this.baseName = baseNoteInfo[0] + this.rootExt;
428 this.cagedBaseShape = baseNoteInfo[1];
429 this.cagedBaseFret = baseNoteInfo[2];
430 } else {
431 this.cagedBaseShape = '';
432 this.cagedBaseFret = 0;
433 }
434
435 if ( ( this.isCaged ) && ( this.cagedPos > 1 ) ) {
436 this.setCagedChordArray();
437 } else if (this.isCustom){
438 this.setCustomChordArray();
439 } else {
440 this.setChordArray(this.baseName);
441 }
442}
443
444jtabChord.prototype.setCustomChordArray = function(){
445 this.chordArray = new Array();
446 this.chordArray = this.parseCustomChordArrayFromToken();
447};
448
449jtabChord.prototype.parseCustomChordArrayFromToken = function() {
450 notes = this.fullChordName.replace(/(\%|\[.+\])/g, '');
451 pairs = notes.split('.');
452 if (pairs.length < 6){
453 this.isValid = false;
454 return;
455 }
456 this.isValid = true;
457
458 array = [];
459 for (var i = 0; i < pairs.length; i++){
460 pair = pairs[i].split('/')
461 if (pair[0].match(/X/)){
462 pair = [-1]
463 }
464 array.push(pair)
465 }
466
467 // fingeredFrets = array.reject(function(p){
468 // return p.length === 1
469 // }).collect(function(p){
470 // return parseInt(p[0])
471 // }).flatten().without(0,-1)
472
473 // `array` is an array of string/fretnumber pairs like [0,1].
474
475 fingeredFrets = jQuery.grep(array, function(pair){
476 // get only the pairs with two elements
477 return (pair.length != 1);
478 }).map(function(pair){
479 return parseInt(pair[0]);
480 }).map(function(i){
481 if ((i != 0) || (i != -1)){
482 return i;
483 } else {
484 return null;
485 }
486 })
487
488 fingeredFrets = jQuery.grep(fingeredFrets,function(n){
489 return(n);
490 });
491
492 //find all the fret positions which arent X or 0. I'm sure there's a better way to do this.
493
494 min = Math.min.apply( Math, fingeredFrets );
495
496 array.unshift(min-1);
497 return array;
498};
499
500jtabChord.prototype.setChordArray = function(chordName) { // clones chord array (position 0) from chord ref data into this object
501 this.chordArray = new Array();
502 if (this.baseChords[chordName] === undefined ) {
503 this.isValid = false;
504 return;
505 }
506 this.isValid = true;
507 var modelRef = this.baseChords[chordName][0];
508 this.chordArray[0] = modelRef[0]
509 for (var i = 1; i < modelRef.length ; i++) {
510 this.chordArray[i] = modelRef[i]; // TODO: this.chordArray[i] = modelRef[i].clone();
511 }
512};
513
514jtabChord.prototype.setCagedChordArray = function() {
515 if ( ! this.cagedBaseShape.match( /[CAGED]/ ) ) return;
516 var caged_index = "CAGED".indexOf(this.cagedBaseShape) + 1; // get 1-based index
517 var fret_widths = [3,2,3,2,2];
518
519 var starting_fret = this.cagedBaseFret;
520
521 for (var i = 1; i < this.cagedPos ; i++) {
522 var index = (caged_index - 1) % 5;
523 caged_index = ( caged_index >= 5) ? 1 : caged_index + 1;
524 starting_fret += fret_widths[index];
525 }
526
527 var modelChord = "CAGED".charAt( caged_index - 1 ) + this.rootExt;
528 this.setChordArray(modelChord);
529 this.shiftChordArray(starting_fret,modelChord);
530};
531
532jtabChord.prototype.shiftChordArray = function(atFret,modelChord) { // shift chord to new fret position
533 var initFret = this.chordArray[0];
534 if (atFret != initFret) {
535 var use_caged_fingering = ( (this.isCaged) && (this.cagedPos > 0) && ( ! ( this.baseChords[modelChord][1][0] === undefined ) ) );
536
537 this.chordArray[0] = atFret - 1;
538 for (var i = 1; i < this.chordArray.length ; i++) {
539 var fret = (this.chordArray[i][0] >= 0 ) ? this.chordArray[i][0] + atFret - initFret : this.chordArray[i][0];
540 var finger = (use_caged_fingering) ? this.baseChords[modelChord][1][i][1] : this.chordArray[i][1];
541 this.chordArray[i] = [ fret , finger ];
542 }
543 }
544};
545
546
547
548//
549// define extensions to the Raphael class
550//
551
552Raphael.fn.tabtype = 0; // 0 = none, 1 = tab & chord, 2 = chord, 3 = tab
553Raphael.fn.has_chord = false;
554Raphael.fn.has_tab = false;
555
556Raphael.fn.debug = false;
557Raphael.fn.scale = 1;
558Raphael.fn.margin_top = 36;
559Raphael.fn.margin_bottom = 10;
560Raphael.fn.margin_left = 16;
561Raphael.fn.margin_right = 10;
562
563Raphael.fn.current_offset = Raphael.fn.margin_left;
564
565Raphael.fn.string_spacing = 16;
566Raphael.fn.strings_drawn = 6;
567Raphael.fn.fret_spacing = 16;
568Raphael.fn.frets_drawn = 4;
569Raphael.fn.note_radius = 7;
570
571Raphael.fn.fret_width = Raphael.fn.string_spacing * ( Raphael.fn.strings_drawn - 1 );
572Raphael.fn.fret_height = Raphael.fn.fret_spacing * (Raphael.fn.frets_drawn + 0.5);
573Raphael.fn.chord_width = Raphael.fn.margin_left + Raphael.fn.fret_width + Raphael.fn.string_spacing + Raphael.fn.margin_right;
574Raphael.fn.chord_height = Raphael.fn.margin_top + Raphael.fn.fret_height + Raphael.fn.margin_bottom;
575
576Raphael.fn.tab_current_string = 0; // 1,2,3,4,5,6 or 0 = not set
577Raphael.fn.tab_margin_top = 10;
578Raphael.fn.tab_top = Raphael.fn.chord_height + Raphael.fn.tab_margin_top;
579Raphael.fn.tab_spacing = Raphael.fn.fret_spacing;
580Raphael.fn.tab_height = Raphael.fn.tab_spacing * 5;
581Raphael.fn.tab_char_width = 8;
582
583Raphael.fn.total_height = Raphael.fn.tab_top + Raphael.fn.tab_height + Raphael.fn.margin_bottom;
584
585Raphael.fn.color = "#000";
586Raphael.fn.fingering_text_color = "#fff";
587Raphael.fn.tab_text_color = "#000";
588
589
590// debug helper - puts grid marks on the rendered image
591Raphael.fn.debug_grid = function (width) {
592 // h ticks
593 this.path(this.svg_params(this.current_offset, 0,0,4)).attr({stroke: this.color, "stroke-width":0.2 })
594 this.path(this.svg_params( this.current_offset + this.margin_left, 0,0,2)).attr({stroke: this.color, "stroke-width":0.2 })
595 this.path(this.svg_params( this.current_offset + width - this.margin_right, 0,0,2)).attr({stroke: this.color, "stroke-width":0.2 })
596 // v ticks
597 if (this.tabtype == 3) {
598 this.path(this.svg_params(this.current_offset, this.tab_margin_top,2,0)).attr({stroke: this.color, "stroke-width":0.2 })
599 } else {
600 this.path(this.svg_params(this.current_offset, this.margin_top,2, 0)).attr({stroke: this.color, "stroke-width":0.2 })
601 }
602}
603
604
605// step the current position for drawing
606Raphael.fn.increment_offset = function (width) {
607 w = ( width === undefined ) ? this.chord_width : width;
608 if (this.debug) this.debug_grid(w);
609 this.current_offset += w;
610 this.setSize( this.current_offset, this.total_height );
611}
612
613Raphael.fn.svg_params = function(x,y,l1,l2) {
614 // http://www.w3.org/TR/SVG/paths.html#PathData --helpful reading
615 var move_line_to = "m"+x+" "+y+"l"+l1+" "+l2
616 if(arguments.length == 4) return move_line_to
617}
618
619// draw the fretboard
620Raphael.fn.chord_fretboard = function ( position, chord_name ) {
621 var fret_left = this.current_offset + this.margin_left;
622 // conventional fret labels
623 var fret_labels = [ '', '', '', 'III', '', 'V', '', 'VII', '', 'IX', '', '', 'XII', '', '', 'XV', '', 'XVII', '', 'XIX', '', 'XXI', '' ];
624 // alternative friendly fret labels. Currently disabled, maybe bring these back as a configurable option?
625 // var fret_labels = [ '', '1fr', '2fr', '3fr', '4fr', '5fr', '6fr', '7fr', '8fr', '9fr', '10fr', '11fr', '12fr', '13fr', '14fr', '15fr', '16fr', '17fr', '18fr', '19fr', '20fr', '21fr', '' ];
626
627 this.text( // chord name
628 fret_left + 2.5 * this.string_spacing,
629 this.margin_top - 20,
630 chord_name).attr({fill: this.tab_text_color, "font-size":"20px"});
631
632 var stroke_width = position == 0 ? 3 : 0 // nut
633 var chord_fretboard_path = this.path(this.svg_params(fret_left,this.margin_top,this.string_spacing * (this.strings_drawn - 1),0))
634 chord_fretboard_path.attr({stroke: this.color, "stroke-width":stroke_width })
635
636 for (var i = 0; i <= this.frets_drawn; i++ ) { // frets
637
638 this.path(this.svg_params(fret_left,this.margin_top + (i * this.fret_spacing),this.string_spacing * (this.strings_drawn - 1), 0))
639
640 pos = ( fret_labels[ position + i ] === undefined ) ? '' : fret_labels[ position + i ];
641
642 if ( pos.length > 0 ) { // draw fret position
643 this.text(
644 fret_left + this.fret_width + this.string_spacing * 1.0,
645 this.margin_top + ( ( i - 0.5 ) * this.fret_spacing),
646 pos).attr({stroke: this.tab_text_color, "font-size":"12px"});
647 }
648 }
649 for (var i = 0; i < this.strings_drawn; i++ ) {
650 this.path(this.svg_params(fret_left + (i * this.string_spacing),this.margin_top,0, this.fret_spacing * (this.frets_drawn + 0.5))) // strings
651 }
652 this.tab_extend(this.chord_width); // extend the tab if present
653}
654
655
656// draw a stroke (/)
657Raphael.fn.stroke = function () {
658
659 if (this.has_tab) {
660 var width = this.tab_char_width * 3;
661 // extend tab
662 this.tab_extend(width);
663 // stroke
664 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))
665 stroke_path.attr({stroke: this.tab_text_color, "stroke-width":4 })
666
667 this.increment_offset(width);
668 } else if (this.has_chord) {
669 var dx = this.string_spacing;
670 var dy = 2 * this.fret_spacing;
671 this.path(this.svg_params(this.current_offset + this.margin_left,
672 this.margin_top + this.fret_spacing + dy,dx,-dy)).attr({stroke: this.tab_text_color, "stroke-width":4 })
673
674 this.increment_offset( this.margin_left + dx + this.margin_right );
675 }
676}
677
678
679// draw a bar
680Raphael.fn.bar = function () {
681
682 if (this.has_tab) {
683 var width = this.tab_char_width * 2;
684 // extend tab
685 this.tab_extend(width);
686 var bar_stroke=this.path(this.svg_params(this.current_offset + this.tab_char_width, this.tab_top,0, this.tab_height))
687 this.increment_offset(width);
688
689 } else if (this.has_chord) {
690 var fret_left = this.current_offset + this.margin_left;
691 var bar_stroke=this.path(this.svg_params(this.current_offset + this.margin_left, this.margin_top,0, 0, this.fret_height))
692 this.increment_offset( this.margin_left + this.margin_right );
693 }
694 bar_stroke.attr({stroke: this.color, "stroke-width":1 })
695
696}
697
698
699// draw double bar
700Raphael.fn.doublebar = function () {
701 if (this.has_tab) {
702 var width = this.tab_char_width + 8;
703 // extend tab
704 this.tab_extend(width);
705 // bar
706 var path_1 = this.path(this.svg_params(this.current_offset + this.tab_char_width, this.tab_top,0, this.tab_height))
707 var path_2 = this.path(this.svg_params(this.current_offset + this.tab_char_width + 6, this.tab_top,0, this.tab_height ))
708 this.increment_offset(width);
709
710 } else if (this.has_chord) {
711 var left = this.current_offset + this.margin_left;
712
713 var path_1 = this.path(this.svg_params(left, this.margin_top,0, this.fret_height))
714 var path_2 = this.path(this.svg_params(left + 6, this.margin_top,0, this.fret_height))
715
716 this.increment_offset( this.margin_left + 6 + this.margin_right );
717 }
718 path_1.attr({stroke: this.color, "stroke-width":1 })
719 path_2.attr({stroke: this.color, "stroke-width":4 })
720}
721
722
723// draw a note in a chord
724Raphael.fn.chord_note = function (position, string_number, note) {
725 // NB: internal string_number in chords counts from low to high
726 var fret_number = note[0];
727 var fret_left = this.current_offset + this.margin_left;
728
729 if (fret_number < 0 ) {
730 // muted/not played
731 this.text(fret_left + (string_number - 1) * this.string_spacing, this.margin_top - 8, "x").attr({stroke: this.tab_text_color, "font-size":"9px"});
732 } else if (fret_number == 0 ) {
733 // open
734 this.text(fret_left + (string_number - 1) * this.string_spacing, this.margin_top - 8, "o").attr({stroke: this.tab_text_color, "font-size":"9px"});
735 } else {
736 var fret_dy = (fret_number - position - 0.5) * this.fret_spacing;
737 //var circle =
738 this.circle(
739 fret_left + (string_number - 1) * this.string_spacing,
740 this.margin_top + fret_dy, this.note_radius).attr({stroke: this.color, fill: this.color});
741 if ( ! (note[1] === undefined) ) {
742 //console.log("*** fret_dy = " + fret_dy);
743 this.text( fret_left + (string_number - 1) * this.string_spacing,
744 this.margin_top + fret_dy, note[1] ).attr({fill: this.fingering_text_color, "font-size":"12px"});
745 }
746 }
747
748 if ( this.has_tab && fret_number >= 0 ) {
749 this.draw_tab_note( (this.strings_drawn - string_number + 1), fret_number, this.margin_left + this.string_spacing * 2.5 );
750 }
751}
752
753
754// extend the tab drawing area
755Raphael.fn.tab_extend = function (width) {
756 if (this.has_tab == false) return;
757 for (var i = 0; i < this.strings_drawn; i++ ) {
758 this.path(this.svg_params(this.current_offset, this.tab_top + (i * this.tab_spacing),width, 0)).attr({stroke: this.color})
759 }
760}
761
762
763// start the tab
764Raphael.fn.tab_start = function () {
765 if (this.has_tab == false) return;
766 var width = this.tab_char_width * 3;
767 // start bar
768 this.path(this.svg_params(this.current_offset, this.tab_top,0, this.tab_height)).attr({stroke: this.color, "stroke-width":1 })
769
770 // extend tab
771 this.tab_extend(width);
772
773 //write TAB
774 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"});
775 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"});
776 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"});
777 this.increment_offset(width);
778
779}
780
781
782// draw an individual note in the tab
783Raphael.fn.draw_tab_note = function (string_number, token, left_offset) {
784 // NB: internal string_number in tab counts from high to low
785 this.text(this.current_offset + left_offset,
786 this.tab_top + this.tab_spacing * (string_number - 1),
787 token).attr({fill: this.color, "font-size":"16px"});
788}
789
790// gets string number from token $[1-6|EADGBe]
791Raphael.fn.get_string_number = function (token) {
792 var string_number = null;
793 if ( token.match( /^\$[1-6]/ ) != null ) {
794 string_number = token.substr(1,1);
795 } else if ( token.match( /^\$[EADGBe]/ ) != null ) {
796 string_number = 6 - "EADGBe".indexOf(token.substr(1,1));
797 }
798 return string_number;
799}
800
801
802// identify if full chord of notes specified i.e. A:1 = X02220 or C:4 = 8.10.10.9.8.8
803// returns:
804// false = not a full chord representation
805// array = array of notes (low to high)
806Raphael.fn.get_fullchord_notes = function (token) {
807 var rc = false;
808 if ( token.match( /[^\.xX0-9]/ ) != null ) {
809 rc = false;
810 } else {
811 if ( token.match( /\./ ) != null ) {
812 rc = token.split('.');
813 } else {
814 rc = token.split('');
815 }
816 if (rc.length != 6) rc = false;
817 }
818 return rc;
819}
820
821
822// draw a token on the tab
823Raphael.fn.tab_note = function (token) {
824 if (this.has_tab == false) return;
825
826 if ( token.match( /\$/ ) != null ) { // contains a string specifier
827 if ( token.match( /\./ ) != null ) { // is a multi-string specifier
828 var parts = token.split(".");
829 var width = 2;
830 for (var i = 0; i < parts.length ; i++) { // get the max length of the multi-string specifiers
831 if ( parts[i].length > width ) width = parts[i].length;
832 }
833 width *= this.tab_char_width + 1;
834 this.tab_extend( width );
835 for (var i = 0; i < parts.length ; i++) {
836 var part = parts[i];
837 var string_number = this.get_string_number(part);
838 if (string_number != null) {
839 this.tab_current_string = string_number;
840 } else if ( this.tab_current_string > 0 ) {
841 this.draw_tab_note( this.tab_current_string, part, width * 0.5 );
842 }
843 }
844 this.increment_offset( width );
845
846 } else { // just a string setting
847 this.tab_current_string = this.get_string_number(token);
848 }
849 } else {
850 var fullchord_notes = this.get_fullchord_notes(token);
851 if ( fullchord_notes ) {
852 var max_chars = fullchord_notes.max_chars();
853 var width = this.tab_char_width * (max_chars + 2);
854 this.tab_extend( width );
855 for (var i = 0; i < fullchord_notes.length ; i++) {
856 this.draw_tab_note( 6 - i, fullchord_notes[i], width * 0.5 );
857 }
858 this.increment_offset( width );
859 } else if ( this.tab_current_string > 0 ) { // else draw literal, but only if a current string selected
860 var width = this.tab_char_width * ( token.length + 2 );
861 this.tab_extend( width );
862 this.draw_tab_note( this.tab_current_string, token, width * 0.5 );
863 this.increment_offset( width );
864 }
865 }
866}
867
868
869// main drawing routine entry point: to render a token - chord or tab
870Raphael.fn.render_token = function (token) {
871
872 var c = new jtabChord(token);
873
874 if ( c.isValid ) { // draw chord
875 var chord = c.chordArray;
876 // this.chord_fretboard(chord[0], c.fullChordName );
877 this.chord_fretboard(chord[0], c.chordName );
878 for (var i = 1; i < chord.length ; i++) {
879 this.chord_note(chord[0], i, chord[i]);
880 }
881 this.increment_offset();
882
883 } else {
884 if (token == "/" ) {
885 this.stroke();
886 } else if (token == "|" ) {
887 this.bar();
888 } else if (token == "||" ) {
889 this.doublebar();
890 } else if ( this.has_tab ) {
891 this.tab_note( token );
892 }
893
894 }
895}
896
897
898//
899// add jtab class methods
900//
901
902
903// determine nature of the token stream
904// returns:
905// 1 : chord and tab present
906// 2 : chord only
907// 3 : tab only
908// 0 : unknown
909jtab.characterize = function (notation) {
910 var tabtype = 0;
911
912 if(notation == undefined){
913 notation = '';
914 }
915
916 var gotCustomChord = ( notation.match( /[\%]([0-4|T|X])?/ ) != undefined );
917 var gotNormalChord = ( notation.match( /[^\$][A-G]|^[A-G]/ ) != undefined );
918 var gotTab = ( ( notation.match( /\$/ ) != null ) || ( notation.match( /[^\%][0-9|Xx|\.]{6,}/ ) != null ) );
919 var gotChord = gotNormalChord || gotCustomChord ;
920
921 // set defaults - apply scaling here (TODO)
922 Raphael.fn.current_offset = Raphael.fn.margin_left;
923 if ( gotChord && gotTab ) { // chord and tab
924 tabtype = 1;
925 Raphael.fn.has_chord = true;
926 Raphael.fn.has_tab = true;
927 Raphael.fn.tab_top = Raphael.fn.chord_height + Raphael.fn.tab_margin_top;
928 Raphael.fn.total_height = Raphael.fn.tab_top + Raphael.fn.tab_height + Raphael.fn.margin_bottom;
929 } else if ( gotChord ) { // chord only
930 tabtype = 2;
931 Raphael.fn.has_chord = true;
932 Raphael.fn.has_tab = false;
933 Raphael.fn.tab_top = Raphael.fn.chord_height + Raphael.fn.tab_margin_top;
934 Raphael.fn.total_height = Raphael.fn.chord_height;
935 } else if ( gotTab ) { // tab only
936 tabtype = 3;
937 Raphael.fn.has_chord = false;
938 Raphael.fn.has_tab = true;
939 Raphael.fn.tab_top = Raphael.fn.tab_margin_top;
940 Raphael.fn.total_height = Raphael.fn.tab_top + Raphael.fn.tab_height + Raphael.fn.margin_bottom;
941 }
942 Raphael.fn.tabtype = tabtype;
943 return tabtype;
944}
945
946// utility function to get calculated style based on given element
947jtab.getStyle = function (element, style) {
948 var value = element.css(style);
949 if(!value) {
950 if(document.defaultView) {
951 value = document.defaultView.getComputedStyle(element[0], "").getPropertyValue(style);
952 } else if(element.currentStyle) {
953 value = element.currentStyle[style];
954 }
955 }
956
957 return value;
958}
959
960// set color pallette for the jtab rendering
961jtab.setPalette = function (element) {
962 var fgColor = jtab.getStyle( jQuery(element), 'color' );
963 if (!fgColor) {
964 fgColor = '#000';
965 }
966 Raphael.fn.color = fgColor;
967 Raphael.fn.tab_text_color = fgColor;
968
969 bgColor = jtab.getStyle( jQuery(element), 'background-color' );
970 if (!bgColor || (bgColor == 'transparent') || (bgColor == 'rgba(0, 0, 0, 0)')) {
971 bgColor = '#fff';
972 }
973 Raphael.fn.fingering_text_color = bgColor;
974}
975
976// Render the tab for a given +element+.
977// +element+ is a DOM node
978// +notation_text+ is the optional notation to render (if not specified, +element+ text content will be used)
979// After rendering, the +element+ will be given the additional "rendered" class.
980jtab.render = function (element,notation_text) {
981
982 var notation = notation_text || jQuery(element).text() || '';
983
984 var tabtype = jtab.characterize( notation );
985 if (tabtype == 0 ) return;
986
987 var rndID="builder_"+jtab.element_count++;
988
989 // add the Raphael canvas in its own DIV. this gets around an IE6 issue with not removing previous renderings
990 var canvas_holder = jQuery('<div id="'+rndID+'"></div>').css({height: Raphael.fn.total_height});
991
992 jQuery(element).html(canvas_holder);
993 jtab.setPalette(element);
994 canvas = Raphael(rndID, 80, Raphael.fn.total_height );
995 canvas.tab_start();
996
997 var tokens = notation.split(/\s/);
998 for(var i = 0; i < tokens.length; i++) {
999 canvas.render_token(tokens[i]);
1000 }
1001 jQuery(element).addClass('rendered');
1002}
1003
1004// Render all nodes with class 'jtab'.
1005// +within_scope+ is an optional selector that will restrict rendering to only those nodes contained within.
1006jtab.renderimplicit = function(within_scope) {
1007 jQuery('.jtab',within_scope).not('.rendered').each( function(name, index) { jtab.render(this); } );
1008}
1009
1010// initialize jtab library.
1011// Sets up to run implicit rendering on window.onload
1012jtab.init = function() {
1013 var oldonload = window.onload;
1014 window.onload = function() {
1015 if (typeof oldonload == 'function') oldonload();
1016 jtab.renderimplicit(null);
1017 }
1018}
1019
1020// bootstrap jtab when jQuery is ready
1021jQuery(document).ready(function($) {
1022 jtab.init();
1023});
Note: See TracBrowser for help on using the repository browser.