summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDominic DiTaranto <domdit@gmail.com>2024-09-22 21:30:28 -0400
committerDominic DiTaranto <domdit@gmail.com>2024-09-22 21:30:28 -0400
commit75e802e5b27425db95d000f714e3b3363a5e1a9c (patch)
tree1ed046b10702a9340934adeb6859f5322ef4920b
inital commitHEADmaster
-rw-r--r--app.py27
-rw-r--r--constants.py16
-rw-r--r--generate_chord_tones.py57
-rw-r--r--requirements.txt26
-rw-r--r--static/fretboard.pngbin0 -> 4468 bytes
-rw-r--r--static/main.css94
-rw-r--r--static/main.js29
-rw-r--r--templates/index.html151
8 files changed, 400 insertions, 0 deletions
diff --git a/app.py b/app.py
new file mode 100644
index 0000000..32c1237
--- /dev/null
+++ b/app.py
@@ -0,0 +1,27 @@
+import ast
+from flask import Flask, render_template, request
+from constants import chords
+from generate_chord_tones import ChordToneGenerator
+
+
+app = Flask(__name__)
+
+
+@app.route('/', methods=('GET', 'POST'))
+def index():
+ chord_map = None
+ counts = None
+ if request.method == 'POST':
+ selected_chords = []
+ for chord in request.form:
+ current_chord = request.form.get(chord)
+ if current_chord:
+ selected_chords.append(current_chord)
+
+ if selected_chords:
+ generator = ChordToneGenerator(selected_chords)
+ generator.main()
+ chord_map = generator.prepped_chord_map
+ counts = generator.counts
+
+ return render_template('index.html', chords=chords, chord_map=chord_map, counts=counts)
diff --git a/constants.py b/constants.py
new file mode 100644
index 0000000..37bc7c9
--- /dev/null
+++ b/constants.py
@@ -0,0 +1,16 @@
+chords = [None ,'Ab5', 'Abno5', 'Abomit5', 'Abm(no5)', 'Abm(omit5)', 'Ab', 'Abmaj', 'Abm', 'Abmin', 'Ab-', 'Abdim', 'Ab(b5)', 'Abaug', 'Absus2', 'Absus4', 'Absus', 'Ab6', 'Ab6b5', 'Ab6-5', 'Ab7', 'Ab7-5', 'Ab7b5', 'Ab7+5', 'Ab7#5', 'Ab7sus4', 'Abm6', 'Abm7', 'Abm7-5', 'Abm7b5', 'Abm7+5', 'Abm7#5', 'Abdim6', 'Abdim7', 'AbM7', 'Abmaj7', 'Abmaj7+5', 'AbM7+5', 'Abmmaj7', 'AbmM7', 'Abadd4', 'Abmajadd4', 'AbMadd4', 'Abmadd4', 'Abadd9', 'Abmajadd9', 'AbMadd9', 'Abmadd9', 'Absus4add9', 'Absus4add2', 'Ab2', 'Abadd11', 'Ab4', 'Abm69', 'Ab69', 'Ab9', 'Abm9', 'AbM9', 'Abmaj9', 'Ab9sus4', 'Ab7-9', 'Ab7b9', 'Ab7(b9)', 'Ab7+9', 'Ab7#9', 'Ab9-5', 'Ab9b5', 'Ab9+5', 'Ab9#5', 'Ab7#9b5', 'Ab7#9#5', 'Abm7b9b5', 'Ab7b9b5', 'Ab7b9#5', 'Ab11', 'Ab7+11', 'Ab7#11', 'Abmaj7+11', 'AbM7+11', 'Abmaj7#11', 'AbM7#11', 'Ab7b9#9', 'Ab7b9#11', 'Ab7#9#11', 'Ab7-13', 'Ab7b13', 'Abm7add11', 'Abmaj7add11', 'AbM7add11', 'Abmmaj7add11', 'AbmM7add11', 'Ab7b9b13', 'Ab9+11', 'Ab9#11', 'Abm11', 'Ab13', 'Ab13-9', 'Ab13b9', 'Ab13+9', 'Ab13#9', 'Ab13+11', 'Ab13#11', 'Abmaj13', 'AbM13', 'Abmaj7add13', 'AbM7add13', 'A5', 'Ano5', 'Aomit5', 'Am(no5)', 'Am(omit5)', 'A', 'Amaj', 'Am', 'Amin', 'A-', 'Adim', 'A(b5)', 'Aaug', 'Asus2', 'Asus4', 'Asus', 'A6', 'A6b5', 'A6-5', 'A7', 'A7-5', 'A7b5', 'A7+5', 'A7#5', 'A7sus4', 'Am6', 'Am7', 'Am7-5', 'Am7b5', 'Am7+5', 'Am7#5', 'Adim6', 'Adim7', 'AM7', 'Amaj7', 'Amaj7+5', 'AM7+5', 'Ammaj7', 'AmM7', 'Aadd4', 'Amajadd4', 'AMadd4', 'Amadd4', 'Aadd9', 'Amajadd9', 'AMadd9', 'Amadd9', 'Asus4add9', 'Asus4add2', 'A2', 'Aadd11', 'A4', 'Am69', 'A69', 'A9', 'Am9', 'AM9', 'Amaj9', 'A9sus4', 'A7-9', 'A7b9', 'A7(b9)', 'A7+9', 'A7#9', 'A9-5', 'A9b5', 'A9+5', 'A9#5', 'A7#9b5', 'A7#9#5', 'Am7b9b5', 'A7b9b5', 'A7b9#5', 'A11', 'A7+11', 'A7#11', 'Amaj7+11', 'AM7+11', 'Amaj7#11', 'AM7#11', 'A7b9#9', 'A7b9#11', 'A7#9#11', 'A7-13', 'A7b13', 'Am7add11', 'Amaj7add11', 'AM7add11', 'Ammaj7add11', 'AmM7add11', 'A7b9b13', 'A9+11', 'A9#11', 'Am11', 'A13', 'A13-9', 'A13b9', 'A13+9', 'A13#9', 'A13+11', 'A13#11', 'Amaj13', 'AM13', 'Amaj7add13', 'AM7add13', 'A#5', 'A#no5', 'A#omit5', 'A#m(no5)', 'A#m(omit5)', 'A#', 'A#maj', 'A#m', 'A#min', 'A#-', 'A#dim', 'A#(b5)', 'A#aug', 'A#sus2', 'A#sus4', 'A#sus', 'A#6', 'A#6b5', 'A#6-5', 'A#7', 'A#7-5', 'A#7b5', 'A#7+5', 'A#7#5', 'A#7sus4', 'A#m6', 'A#m7', 'A#m7-5', 'A#m7b5', 'A#m7+5', 'A#m7#5', 'A#dim6', 'A#dim7', 'A#M7', 'A#maj7', 'A#maj7+5', 'A#M7+5', 'A#mmaj7', 'A#mM7', 'A#add4', 'A#majadd4', 'A#Madd4', 'A#madd4', 'A#add9', 'A#majadd9', 'A#Madd9', 'A#madd9', 'A#sus4add9', 'A#sus4add2', 'A#2', 'A#add11', 'A#4', 'A#m69', 'A#69', 'A#9', 'A#m9', 'A#M9', 'A#maj9', 'A#9sus4', 'A#7-9', 'A#7b9', 'A#7(b9)', 'A#7+9', 'A#7#9', 'A#9-5', 'A#9b5', 'A#9+5', 'A#9#5', 'A#7#9b5', 'A#7#9#5', 'A#m7b9b5', 'A#7b9b5', 'A#7b9#5', 'A#11', 'A#7+11', 'A#7#11', 'A#maj7+11', 'A#M7+11', 'A#maj7#11', 'A#M7#11', 'A#7b9#9', 'A#7b9#11', 'A#7#9#11', 'A#7-13', 'A#7b13', 'A#m7add11', 'A#maj7add11', 'A#M7add11', 'A#mmaj7add11', 'A#mM7add11', 'A#7b9b13', 'A#9+11', 'A#9#11', 'A#m11', 'A#13', 'A#13-9', 'A#13b9', 'A#13+9', 'A#13#9', 'A#13+11', 'A#13#11', 'A#maj13', 'A#M13', 'A#maj7add13', 'A#M7add13', 'Bb5', 'Bbno5', 'Bbomit5', 'Bbm(no5)', 'Bbm(omit5)', 'Bb', 'Bbmaj', 'Bbm', 'Bbmin', 'Bb-', 'Bbdim', 'Bb(b5)', 'Bbaug', 'Bbsus2', 'Bbsus4', 'Bbsus', 'Bb6', 'Bb6b5', 'Bb6-5', 'Bb7', 'Bb7-5', 'Bb7b5', 'Bb7+5', 'Bb7#5', 'Bb7sus4', 'Bbm6', 'Bbm7', 'Bbm7-5', 'Bbm7b5', 'Bbm7+5', 'Bbm7#5', 'Bbdim6', 'Bbdim7', 'BbM7', 'Bbmaj7', 'Bbmaj7+5', 'BbM7+5', 'Bbmmaj7', 'BbmM7', 'Bbadd4', 'Bbmajadd4', 'BbMadd4', 'Bbmadd4', 'Bbadd9', 'Bbmajadd9', 'BbMadd9', 'Bbmadd9', 'Bbsus4add9', 'Bbsus4add2', 'Bb2', 'Bbadd11', 'Bb4', 'Bbm69', 'Bb69', 'Bb9', 'Bbm9', 'BbM9', 'Bbmaj9', 'Bb9sus4', 'Bb7-9', 'Bb7b9', 'Bb7(b9)', 'Bb7+9', 'Bb7#9', 'Bb9-5', 'Bb9b5', 'Bb9+5', 'Bb9#5', 'Bb7#9b5', 'Bb7#9#5', 'Bbm7b9b5', 'Bb7b9b5', 'Bb7b9#5', 'Bb11', 'Bb7+11', 'Bb7#11', 'Bbmaj7+11', 'BbM7+11', 'Bbmaj7#11', 'BbM7#11', 'Bb7b9#9', 'Bb7b9#11', 'Bb7#9#11', 'Bb7-13', 'Bb7b13', 'Bbm7add11', 'Bbmaj7add11', 'BbM7add11', 'Bbmmaj7add11', 'BbmM7add11', 'Bb7b9b13', 'Bb9+11', 'Bb9#11', 'Bbm11', 'Bb13', 'Bb13-9', 'Bb13b9', 'Bb13+9', 'Bb13#9', 'Bb13+11', 'Bb13#11', 'Bbmaj13', 'BbM13', 'Bbmaj7add13', 'BbM7add13', 'B5', 'Bno5', 'Bomit5', 'Bm(no5)', 'Bm(omit5)', 'B', 'Bmaj', 'Bm', 'Bmin', 'B-', 'Bdim', 'B(b5)', 'Baug', 'Bsus2', 'Bsus4', 'Bsus', 'B6', 'B6b5', 'B6-5', 'B7', 'B7-5', 'B7b5', 'B7+5', 'B7#5', 'B7sus4', 'Bm6', 'Bm7', 'Bm7-5', 'Bm7b5', 'Bm7+5', 'Bm7#5', 'Bdim6', 'Bdim7', 'BM7', 'Bmaj7', 'Bmaj7+5', 'BM7+5', 'Bmmaj7', 'BmM7', 'Badd4', 'Bmajadd4', 'BMadd4', 'Bmadd4', 'Badd9', 'Bmajadd9', 'BMadd9', 'Bmadd9', 'Bsus4add9', 'Bsus4add2', 'B2', 'Badd11', 'B4', 'Bm69', 'B69', 'B9', 'Bm9', 'BM9', 'Bmaj9', 'B9sus4', 'B7-9', 'B7b9', 'B7(b9)', 'B7+9', 'B7#9', 'B9-5', 'B9b5', 'B9+5', 'B9#5', 'B7#9b5', 'B7#9#5', 'Bm7b9b5', 'B7b9b5', 'B7b9#5', 'B11', 'B7+11', 'B7#11', 'Bmaj7+11', 'BM7+11', 'Bmaj7#11', 'BM7#11', 'B7b9#9', 'B7b9#11', 'B7#9#11', 'B7-13', 'B7b13', 'Bm7add11', 'Bmaj7add11', 'BM7add11', 'Bmmaj7add11', 'BmM7add11', 'B7b9b13', 'B9+11', 'B9#11', 'Bm11', 'B13', 'B13-9', 'B13b9', 'B13+9', 'B13#9', 'B13+11', 'B13#11', 'Bmaj13', 'BM13', 'Bmaj7add13', 'BM7add13', 'Cb5', 'Cbno5', 'Cbomit5', 'Cbm(no5)', 'Cbm(omit5)', 'Cb', 'Cbmaj', 'Cbm', 'Cbmin', 'Cb-', 'Cbdim', 'Cb(b5)', 'Cbaug', 'Cbsus2', 'Cbsus4', 'Cbsus', 'Cb6', 'Cb6b5', 'Cb6-5', 'Cb7', 'Cb7-5', 'Cb7b5', 'Cb7+5', 'Cb7#5', 'Cb7sus4', 'Cbm6', 'Cbm7', 'Cbm7-5', 'Cbm7b5', 'Cbm7+5', 'Cbm7#5', 'Cbdim6', 'Cbdim7', 'CbM7', 'Cbmaj7', 'Cbmaj7+5', 'CbM7+5', 'Cbmmaj7', 'CbmM7', 'Cbadd4', 'Cbmajadd4', 'CbMadd4', 'Cbmadd4', 'Cbadd9', 'Cbmajadd9', 'CbMadd9', 'Cbmadd9', 'Cbsus4add9', 'Cbsus4add2', 'Cb2', 'Cbadd11', 'Cb4', 'Cbm69', 'Cb69', 'Cb9', 'Cbm9', 'CbM9', 'Cbmaj9', 'Cb9sus4', 'Cb7-9', 'Cb7b9', 'Cb7(b9)', 'Cb7+9', 'Cb7#9', 'Cb9-5', 'Cb9b5', 'Cb9+5', 'Cb9#5', 'Cb7#9b5', 'Cb7#9#5', 'Cbm7b9b5', 'Cb7b9b5', 'Cb7b9#5', 'Cb11', 'Cb7+11', 'Cb7#11', 'Cbmaj7+11', 'CbM7+11', 'Cbmaj7#11', 'CbM7#11', 'Cb7b9#9', 'Cb7b9#11', 'Cb7#9#11', 'Cb7-13', 'Cb7b13', 'Cbm7add11', 'Cbmaj7add11', 'CbM7add11', 'Cbmmaj7add11', 'CbmM7add11', 'Cb7b9b13', 'Cb9+11', 'Cb9#11', 'Cbm11', 'Cb13', 'Cb13-9', 'Cb13b9', 'Cb13+9', 'Cb13#9', 'Cb13+11', 'Cb13#11', 'Cbmaj13', 'CbM13', 'Cbmaj7add13', 'CbM7add13', 'C5', 'Cno5', 'Comit5', 'Cm(no5)', 'Cm(omit5)', 'C', 'Cmaj', 'Cm', 'Cmin', 'C-', 'Cdim', 'C(b5)', 'Caug', 'Csus2', 'Csus4', 'Csus', 'C6', 'C6b5', 'C6-5', 'C7', 'C7-5', 'C7b5', 'C7+5', 'C7#5', 'C7sus4', 'Cm6', 'Cm7', 'Cm7-5', 'Cm7b5', 'Cm7+5', 'Cm7#5', 'Cdim6', 'Cdim7', 'CM7', 'Cmaj7', 'Cmaj7+5', 'CM7+5', 'Cmmaj7', 'CmM7', 'Cadd4', 'Cmajadd4', 'CMadd4', 'Cmadd4', 'Cadd9', 'Cmajadd9', 'CMadd9', 'Cmadd9', 'Csus4add9', 'Csus4add2', 'C2', 'Cadd11', 'C4', 'Cm69', 'C69', 'C9', 'Cm9', 'CM9', 'Cmaj9', 'C9sus4', 'C7-9', 'C7b9', 'C7(b9)', 'C7+9', 'C7#9', 'C9-5', 'C9b5', 'C9+5', 'C9#5', 'C7#9b5', 'C7#9#5', 'Cm7b9b5', 'C7b9b5', 'C7b9#5', 'C11', 'C7+11', 'C7#11', 'Cmaj7+11', 'CM7+11', 'Cmaj7#11', 'CM7#11', 'C7b9#9', 'C7b9#11', 'C7#9#11', 'C7-13', 'C7b13', 'Cm7add11', 'Cmaj7add11', 'CM7add11', 'Cmmaj7add11', 'CmM7add11', 'C7b9b13', 'C9+11', 'C9#11', 'Cm11', 'C13', 'C13-9', 'C13b9', 'C13+9', 'C13#9', 'C13+11', 'C13#11', 'Cmaj13', 'CM13', 'Cmaj7add13', 'CM7add13', 'C#5', 'C#no5', 'C#omit5', 'C#m(no5)', 'C#m(omit5)', 'C#', 'C#maj', 'C#m', 'C#min', 'C#-', 'C#dim', 'C#(b5)', 'C#aug', 'C#sus2', 'C#sus4', 'C#sus', 'C#6', 'C#6b5', 'C#6-5', 'C#7', 'C#7-5', 'C#7b5', 'C#7+5', 'C#7#5', 'C#7sus4', 'C#m6', 'C#m7', 'C#m7-5', 'C#m7b5', 'C#m7+5', 'C#m7#5', 'C#dim6', 'C#dim7', 'C#M7', 'C#maj7', 'C#maj7+5', 'C#M7+5', 'C#mmaj7', 'C#mM7', 'C#add4', 'C#majadd4', 'C#Madd4', 'C#madd4', 'C#add9', 'C#majadd9', 'C#Madd9', 'C#madd9', 'C#sus4add9', 'C#sus4add2', 'C#2', 'C#add11', 'C#4', 'C#m69', 'C#69', 'C#9', 'C#m9', 'C#M9', 'C#maj9', 'C#9sus4', 'C#7-9', 'C#7b9', 'C#7(b9)', 'C#7+9', 'C#7#9', 'C#9-5', 'C#9b5', 'C#9+5', 'C#9#5', 'C#7#9b5', 'C#7#9#5', 'C#m7b9b5', 'C#7b9b5', 'C#7b9#5', 'C#11', 'C#7+11', 'C#7#11', 'C#maj7+11', 'C#M7+11', 'C#maj7#11', 'C#M7#11', 'C#7b9#9', 'C#7b9#11', 'C#7#9#11', 'C#7-13', 'C#7b13', 'C#m7add11', 'C#maj7add11', 'C#M7add11', 'C#mmaj7add11', 'C#mM7add11', 'C#7b9b13', 'C#9+11', 'C#9#11', 'C#m11', 'C#13', 'C#13-9', 'C#13b9', 'C#13+9', 'C#13#9', 'C#13+11', 'C#13#11', 'C#maj13', 'C#M13', 'C#maj7add13', 'C#M7add13', 'Db5', 'Dbno5', 'Dbomit5', 'Dbm(no5)', 'Dbm(omit5)', 'Db', 'Dbmaj', 'Dbm', 'Dbmin', 'Db-', 'Dbdim', 'Db(b5)', 'Dbaug', 'Dbsus2', 'Dbsus4', 'Dbsus', 'Db6', 'Db6b5', 'Db6-5', 'Db7', 'Db7-5', 'Db7b5', 'Db7+5', 'Db7#5', 'Db7sus4', 'Dbm6', 'Dbm7', 'Dbm7-5', 'Dbm7b5', 'Dbm7+5', 'Dbm7#5', 'Dbdim6', 'Dbdim7', 'DbM7', 'Dbmaj7', 'Dbmaj7+5', 'DbM7+5', 'Dbmmaj7', 'DbmM7', 'Dbadd4', 'Dbmajadd4', 'DbMadd4', 'Dbmadd4', 'Dbadd9', 'Dbmajadd9', 'DbMadd9', 'Dbmadd9', 'Dbsus4add9', 'Dbsus4add2', 'Db2', 'Dbadd11', 'Db4', 'Dbm69', 'Db69', 'Db9', 'Dbm9', 'DbM9', 'Dbmaj9', 'Db9sus4', 'Db7-9', 'Db7b9', 'Db7(b9)', 'Db7+9', 'Db7#9', 'Db9-5', 'Db9b5', 'Db9+5', 'Db9#5', 'Db7#9b5', 'Db7#9#5', 'Dbm7b9b5', 'Db7b9b5', 'Db7b9#5', 'Db11', 'Db7+11', 'Db7#11', 'Dbmaj7+11', 'DbM7+11', 'Dbmaj7#11', 'DbM7#11', 'Db7b9#9', 'Db7b9#11', 'Db7#9#11', 'Db7-13', 'Db7b13', 'Dbm7add11', 'Dbmaj7add11', 'DbM7add11', 'Dbmmaj7add11', 'DbmM7add11', 'Db7b9b13', 'Db9+11', 'Db9#11', 'Dbm11', 'Db13', 'Db13-9', 'Db13b9', 'Db13+9', 'Db13#9', 'Db13+11', 'Db13#11', 'Dbmaj13', 'DbM13', 'Dbmaj7add13', 'DbM7add13', 'D5', 'Dno5', 'Domit5', 'Dm(no5)', 'Dm(omit5)', 'D', 'Dmaj', 'Dm', 'Dmin', 'D-', 'Ddim', 'D(b5)', 'Daug', 'Dsus2', 'Dsus4', 'Dsus', 'D6', 'D6b5', 'D6-5', 'D7', 'D7-5', 'D7b5', 'D7+5', 'D7#5', 'D7sus4', 'Dm6', 'Dm7', 'Dm7-5', 'Dm7b5', 'Dm7+5', 'Dm7#5', 'Ddim6', 'Ddim7', 'DM7', 'Dmaj7', 'Dmaj7+5', 'DM7+5', 'Dmmaj7', 'DmM7', 'Dadd4', 'Dmajadd4', 'DMadd4', 'Dmadd4', 'Dadd9', 'Dmajadd9', 'DMadd9', 'Dmadd9', 'Dsus4add9', 'Dsus4add2', 'D2', 'Dadd11', 'D4', 'Dm69', 'D69', 'D9', 'Dm9', 'DM9', 'Dmaj9', 'D9sus4', 'D7-9', 'D7b9', 'D7(b9)', 'D7+9', 'D7#9', 'D9-5', 'D9b5', 'D9+5', 'D9#5', 'D7#9b5', 'D7#9#5', 'Dm7b9b5', 'D7b9b5', 'D7b9#5', 'D11', 'D7+11', 'D7#11', 'Dmaj7+11', 'DM7+11', 'Dmaj7#11', 'DM7#11', 'D7b9#9', 'D7b9#11', 'D7#9#11', 'D7-13', 'D7b13', 'Dm7add11', 'Dmaj7add11', 'DM7add11', 'Dmmaj7add11', 'DmM7add11', 'D7b9b13', 'D9+11', 'D9#11', 'Dm11', 'D13', 'D13-9', 'D13b9', 'D13+9', 'D13#9', 'D13+11', 'D13#11', 'Dmaj13', 'DM13', 'Dmaj7add13', 'DM7add13', 'D#5', 'D#no5', 'D#omit5', 'D#m(no5)', 'D#m(omit5)', 'D#', 'D#maj', 'D#m', 'D#min', 'D#-', 'D#dim', 'D#(b5)', 'D#aug', 'D#sus2', 'D#sus4', 'D#sus', 'D#6', 'D#6b5', 'D#6-5', 'D#7', 'D#7-5', 'D#7b5', 'D#7+5', 'D#7#5', 'D#7sus4', 'D#m6', 'D#m7', 'D#m7-5', 'D#m7b5', 'D#m7+5', 'D#m7#5', 'D#dim6', 'D#dim7', 'D#M7', 'D#maj7', 'D#maj7+5', 'D#M7+5', 'D#mmaj7', 'D#mM7', 'D#add4', 'D#majadd4', 'D#Madd4', 'D#madd4', 'D#add9', 'D#majadd9', 'D#Madd9', 'D#madd9', 'D#sus4add9', 'D#sus4add2', 'D#2', 'D#add11', 'D#4', 'D#m69', 'D#69', 'D#9', 'D#m9', 'D#M9', 'D#maj9', 'D#9sus4', 'D#7-9', 'D#7b9', 'D#7(b9)', 'D#7+9', 'D#7#9', 'D#9-5', 'D#9b5', 'D#9+5', 'D#9#5', 'D#7#9b5', 'D#7#9#5', 'D#m7b9b5', 'D#7b9b5', 'D#7b9#5', 'D#11', 'D#7+11', 'D#7#11', 'D#maj7+11', 'D#M7+11', 'D#maj7#11', 'D#M7#11', 'D#7b9#9', 'D#7b9#11', 'D#7#9#11', 'D#7-13', 'D#7b13', 'D#m7add11', 'D#maj7add11', 'D#M7add11', 'D#mmaj7add11', 'D#mM7add11', 'D#7b9b13', 'D#9+11', 'D#9#11', 'D#m11', 'D#13', 'D#13-9', 'D#13b9', 'D#13+9', 'D#13#9', 'D#13+11', 'D#13#11', 'D#maj13', 'D#M13', 'D#maj7add13', 'D#M7add13', 'Eb5', 'Ebno5', 'Ebomit5', 'Ebm(no5)', 'Ebm(omit5)', 'Eb', 'Ebmaj', 'Ebm', 'Ebmin', 'Eb-', 'Ebdim', 'Eb(b5)', 'Ebaug', 'Ebsus2', 'Ebsus4', 'Ebsus', 'Eb6', 'Eb6b5', 'Eb6-5', 'Eb7', 'Eb7-5', 'Eb7b5', 'Eb7+5', 'Eb7#5', 'Eb7sus4', 'Ebm6', 'Ebm7', 'Ebm7-5', 'Ebm7b5', 'Ebm7+5', 'Ebm7#5', 'Ebdim6', 'Ebdim7', 'EbM7', 'Ebmaj7', 'Ebmaj7+5', 'EbM7+5', 'Ebmmaj7', 'EbmM7', 'Ebadd4', 'Ebmajadd4', 'EbMadd4', 'Ebmadd4', 'Ebadd9', 'Ebmajadd9', 'EbMadd9', 'Ebmadd9', 'Ebsus4add9', 'Ebsus4add2', 'Eb2', 'Ebadd11', 'Eb4', 'Ebm69', 'Eb69', 'Eb9', 'Ebm9', 'EbM9', 'Ebmaj9', 'Eb9sus4', 'Eb7-9', 'Eb7b9', 'Eb7(b9)', 'Eb7+9', 'Eb7#9', 'Eb9-5', 'Eb9b5', 'Eb9+5', 'Eb9#5', 'Eb7#9b5', 'Eb7#9#5', 'Ebm7b9b5', 'Eb7b9b5', 'Eb7b9#5', 'Eb11', 'Eb7+11', 'Eb7#11', 'Ebmaj7+11', 'EbM7+11', 'Ebmaj7#11', 'EbM7#11', 'Eb7b9#9', 'Eb7b9#11', 'Eb7#9#11', 'Eb7-13', 'Eb7b13', 'Ebm7add11', 'Ebmaj7add11', 'EbM7add11', 'Ebmmaj7add11', 'EbmM7add11', 'Eb7b9b13', 'Eb9+11', 'Eb9#11', 'Ebm11', 'Eb13', 'Eb13-9', 'Eb13b9', 'Eb13+9', 'Eb13#9', 'Eb13+11', 'Eb13#11', 'Ebmaj13', 'EbM13', 'Ebmaj7add13', 'EbM7add13', 'E5', 'Eno5', 'Eomit5', 'Em(no5)', 'Em(omit5)', 'E', 'Emaj', 'Em', 'Emin', 'E-', 'Edim', 'E(b5)', 'Eaug', 'Esus2', 'Esus4', 'Esus', 'E6', 'E6b5', 'E6-5', 'E7', 'E7-5', 'E7b5', 'E7+5', 'E7#5', 'E7sus4', 'Em6', 'Em7', 'Em7-5', 'Em7b5', 'Em7+5', 'Em7#5', 'Edim6', 'Edim7', 'EM7', 'Emaj7', 'Emaj7+5', 'EM7+5', 'Emmaj7', 'EmM7', 'Eadd4', 'Emajadd4', 'EMadd4', 'Emadd4', 'Eadd9', 'Emajadd9', 'EMadd9', 'Emadd9', 'Esus4add9', 'Esus4add2', 'E2', 'Eadd11', 'E4', 'Em69', 'E69', 'E9', 'Em9', 'EM9', 'Emaj9', 'E9sus4', 'E7-9', 'E7b9', 'E7(b9)', 'E7+9', 'E7#9', 'E9-5', 'E9b5', 'E9+5', 'E9#5', 'E7#9b5', 'E7#9#5', 'Em7b9b5', 'E7b9b5', 'E7b9#5', 'E11', 'E7+11', 'E7#11', 'Emaj7+11', 'EM7+11', 'Emaj7#11', 'EM7#11', 'E7b9#9', 'E7b9#11', 'E7#9#11', 'E7-13', 'E7b13', 'Em7add11', 'Emaj7add11', 'EM7add11', 'Emmaj7add11', 'EmM7add11', 'E7b9b13', 'E9+11', 'E9#11', 'Em11', 'E13', 'E13-9', 'E13b9', 'E13+9', 'E13#9', 'E13+11', 'E13#11', 'Emaj13', 'EM13', 'Emaj7add13', 'EM7add13', 'F5', 'Fno5', 'Fomit5', 'Fm(no5)', 'Fm(omit5)', 'F', 'Fmaj', 'Fm', 'Fmin', 'F-', 'Fdim', 'F(b5)', 'Faug', 'Fsus2', 'Fsus4', 'Fsus', 'F6', 'F6b5', 'F6-5', 'F7', 'F7-5', 'F7b5', 'F7+5', 'F7#5', 'F7sus4', 'Fm6', 'Fm7', 'Fm7-5', 'Fm7b5', 'Fm7+5', 'Fm7#5', 'Fdim6', 'Fdim7', 'FM7', 'Fmaj7', 'Fmaj7+5', 'FM7+5', 'Fmmaj7', 'FmM7', 'Fadd4', 'Fmajadd4', 'FMadd4', 'Fmadd4', 'Fadd9', 'Fmajadd9', 'FMadd9', 'Fmadd9', 'Fsus4add9', 'Fsus4add2', 'F2', 'Fadd11', 'F4', 'Fm69', 'F69', 'F9', 'Fm9', 'FM9', 'Fmaj9', 'F9sus4', 'F7-9', 'F7b9', 'F7(b9)', 'F7+9', 'F7#9', 'F9-5', 'F9b5', 'F9+5', 'F9#5', 'F7#9b5', 'F7#9#5', 'Fm7b9b5', 'F7b9b5', 'F7b9#5', 'F11', 'F7+11', 'F7#11', 'Fmaj7+11', 'FM7+11', 'Fmaj7#11', 'FM7#11', 'F7b9#9', 'F7b9#11', 'F7#9#11', 'F7-13', 'F7b13', 'Fm7add11', 'Fmaj7add11', 'FM7add11', 'Fmmaj7add11', 'FmM7add11', 'F7b9b13', 'F9+11', 'F9#11', 'Fm11', 'F13', 'F13-9', 'F13b9', 'F13+9', 'F13#9', 'F13+11', 'F13#11', 'Fmaj13', 'FM13', 'Fmaj7add13', 'FM7add13', 'F#5', 'F#no5', 'F#omit5', 'F#m(no5)', 'F#m(omit5)', 'F#', 'F#maj', 'F#m', 'F#min', 'F#-', 'F#dim', 'F#(b5)', 'F#aug', 'F#sus2', 'F#sus4', 'F#sus', 'F#6', 'F#6b5', 'F#6-5', 'F#7', 'F#7-5', 'F#7b5', 'F#7+5', 'F#7#5', 'F#7sus4', 'F#m6', 'F#m7', 'F#m7-5', 'F#m7b5', 'F#m7+5', 'F#m7#5', 'F#dim6', 'F#dim7', 'F#M7', 'F#maj7', 'F#maj7+5', 'F#M7+5', 'F#mmaj7', 'F#mM7', 'F#add4', 'F#majadd4', 'F#Madd4', 'F#madd4', 'F#add9', 'F#majadd9', 'F#Madd9', 'F#madd9', 'F#sus4add9', 'F#sus4add2', 'F#2', 'F#add11', 'F#4', 'F#m69', 'F#69', 'F#9', 'F#m9', 'F#M9', 'F#maj9', 'F#9sus4', 'F#7-9', 'F#7b9', 'F#7(b9)', 'F#7+9', 'F#7#9', 'F#9-5', 'F#9b5', 'F#9+5', 'F#9#5', 'F#7#9b5', 'F#7#9#5', 'F#m7b9b5', 'F#7b9b5', 'F#7b9#5', 'F#11', 'F#7+11', 'F#7#11', 'F#maj7+11', 'F#M7+11', 'F#maj7#11', 'F#M7#11', 'F#7b9#9', 'F#7b9#11', 'F#7#9#11', 'F#7-13', 'F#7b13', 'F#m7add11', 'F#maj7add11', 'F#M7add11', 'F#mmaj7add11', 'F#mM7add11', 'F#7b9b13', 'F#9+11', 'F#9#11', 'F#m11', 'F#13', 'F#13-9', 'F#13b9', 'F#13+9', 'F#13#9', 'F#13+11', 'F#13#11', 'F#maj13', 'F#M13', 'F#maj7add13', 'F#M7add13', 'Gb5', 'Gbno5', 'Gbomit5', 'Gbm(no5)', 'Gbm(omit5)', 'Gb', 'Gbmaj', 'Gbm', 'Gbmin', 'Gb-', 'Gbdim', 'Gb(b5)', 'Gbaug', 'Gbsus2', 'Gbsus4', 'Gbsus', 'Gb6', 'Gb6b5', 'Gb6-5', 'Gb7', 'Gb7-5', 'Gb7b5', 'Gb7+5', 'Gb7#5', 'Gb7sus4', 'Gbm6', 'Gbm7', 'Gbm7-5', 'Gbm7b5', 'Gbm7+5', 'Gbm7#5', 'Gbdim6', 'Gbdim7', 'GbM7', 'Gbmaj7', 'Gbmaj7+5', 'GbM7+5', 'Gbmmaj7', 'GbmM7', 'Gbadd4', 'Gbmajadd4', 'GbMadd4', 'Gbmadd4', 'Gbadd9', 'Gbmajadd9', 'GbMadd9', 'Gbmadd9', 'Gbsus4add9', 'Gbsus4add2', 'Gb2', 'Gbadd11', 'Gb4', 'Gbm69', 'Gb69', 'Gb9', 'Gbm9', 'GbM9', 'Gbmaj9', 'Gb9sus4', 'Gb7-9', 'Gb7b9', 'Gb7(b9)', 'Gb7+9', 'Gb7#9', 'Gb9-5', 'Gb9b5', 'Gb9+5', 'Gb9#5', 'Gb7#9b5', 'Gb7#9#5', 'Gbm7b9b5', 'Gb7b9b5', 'Gb7b9#5', 'Gb11', 'Gb7+11', 'Gb7#11', 'Gbmaj7+11', 'GbM7+11', 'Gbmaj7#11', 'GbM7#11', 'Gb7b9#9', 'Gb7b9#11', 'Gb7#9#11', 'Gb7-13', 'Gb7b13', 'Gbm7add11', 'Gbmaj7add11', 'GbM7add11', 'Gbmmaj7add11', 'GbmM7add11', 'Gb7b9b13', 'Gb9+11', 'Gb9#11', 'Gbm11', 'Gb13', 'Gb13-9', 'Gb13b9', 'Gb13+9', 'Gb13#9', 'Gb13+11', 'Gb13#11', 'Gbmaj13', 'GbM13', 'Gbmaj7add13', 'GbM7add13', 'G5', 'Gno5', 'Gomit5', 'Gm(no5)', 'Gm(omit5)', 'G', 'Gmaj', 'Gm', 'Gmin', 'G-', 'Gdim', 'G(b5)', 'Gaug', 'Gsus2', 'Gsus4', 'Gsus', 'G6', 'G6b5', 'G6-5', 'G7', 'G7-5', 'G7b5', 'G7+5', 'G7#5', 'G7sus4', 'Gm6', 'Gm7', 'Gm7-5', 'Gm7b5', 'Gm7+5', 'Gm7#5', 'Gdim6', 'Gdim7', 'GM7', 'Gmaj7', 'Gmaj7+5', 'GM7+5', 'Gmmaj7', 'GmM7', 'Gadd4', 'Gmajadd4', 'GMadd4', 'Gmadd4', 'Gadd9', 'Gmajadd9', 'GMadd9', 'Gmadd9', 'Gsus4add9', 'Gsus4add2', 'G2', 'Gadd11', 'G4', 'Gm69', 'G69', 'G9', 'Gm9', 'GM9', 'Gmaj9', 'G9sus4', 'G7-9', 'G7b9', 'G7(b9)', 'G7+9', 'G7#9', 'G9-5', 'G9b5', 'G9+5', 'G9#5', 'G7#9b5', 'G7#9#5', 'Gm7b9b5', 'G7b9b5', 'G7b9#5', 'G11', 'G7+11', 'G7#11', 'Gmaj7+11', 'GM7+11', 'Gmaj7#11', 'GM7#11', 'G7b9#9', 'G7b9#11', 'G7#9#11', 'G7-13', 'G7b13', 'Gm7add11', 'Gmaj7add11', 'GM7add11', 'Gmmaj7add11', 'GmM7add11', 'G7b9b13', 'G9+11', 'G9#11', 'Gm11', 'G13', 'G13-9', 'G13b9', 'G13+9', 'G13#9', 'G13+11', 'G13#11', 'Gmaj13', 'GM13', 'Gmaj7add13', 'GM7add13', 'G#5', 'G#no5', 'G#omit5', 'G#m(no5)', 'G#m(omit5)', 'G#', 'G#maj', 'G#m', 'G#min', 'G#-', 'G#dim', 'G#(b5)', 'G#aug', 'G#sus2', 'G#sus4', 'G#sus', 'G#6', 'G#6b5', 'G#6-5', 'G#7', 'G#7-5', 'G#7b5', 'G#7+5', 'G#7#5', 'G#7sus4', 'G#m6', 'G#m7', 'G#m7-5', 'G#m7b5', 'G#m7+5', 'G#m7#5', 'G#dim6', 'G#dim7', 'G#M7', 'G#maj7', 'G#maj7+5', 'G#M7+5', 'G#mmaj7', 'G#mM7', 'G#add4', 'G#majadd4', 'G#Madd4', 'G#madd4', 'G#add9', 'G#majadd9', 'G#Madd9', 'G#madd9', 'G#sus4add9', 'G#sus4add2', 'G#2', 'G#add11', 'G#4', 'G#m69', 'G#69', 'G#9', 'G#m9', 'G#M9', 'G#maj9', 'G#9sus4', 'G#7-9', 'G#7b9', 'G#7(b9)', 'G#7+9', 'G#7#9', 'G#9-5', 'G#9b5', 'G#9+5', 'G#9#5', 'G#7#9b5', 'G#7#9#5', 'G#m7b9b5', 'G#7b9b5', 'G#7b9#5', 'G#11', 'G#7+11', 'G#7#11', 'G#maj7+11', 'G#M7+11', 'G#maj7#11', 'G#M7#11', 'G#7b9#9', 'G#7b9#11', 'G#7#9#11', 'G#7-13', 'G#7b13', 'G#m7add11', 'G#maj7add11', 'G#M7add11', 'G#mmaj7add11', 'G#mM7add11', 'G#7b9b13', 'G#9+11', 'G#9#11', 'G#m11', 'G#13', 'G#13-9', 'G#13b9', 'G#13+9', 'G#13#9', 'G#13+11', 'G#13#11', 'G#maj13', 'G#M13', 'G#maj7add13', 'G#M7add13']
+
+notes = ['A', 'A#', 'B', 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#']
+
+strings = ['E', 'B', 'G', 'D', 'A', 'E']
+
+enharmonic_map = {
+ 'Ab': 'G#',
+ 'Bb': 'A#',
+ 'Cb': 'B',
+ 'Db': 'C#',
+ 'Eb': 'D#',
+ 'Gb': 'F#'
+}
+
+html_string_ids = ['e', 'b', 'g', 'd', 'a', 'ee'] \ No newline at end of file
diff --git a/generate_chord_tones.py b/generate_chord_tones.py
new file mode 100644
index 0000000..dbc990e
--- /dev/null
+++ b/generate_chord_tones.py
@@ -0,0 +1,57 @@
+from pychord import Chord
+from constants import notes, strings, enharmonic_map, html_string_ids
+
+
+class ChordToneGenerator:
+ def __init__(self, chords):
+ self.chords = chords
+ self.chord_map = {}
+ self.note_to_fret_map = {}
+ self.prepped_chord_map = {}
+ self.all_frets = []
+ self.counts = None
+
+ def main(self):
+ self.generate_chord_map()
+ self.prepare_chord_map()
+ self.prepare_counts()
+
+ def generate_chord_map(self):
+ for chord in self.chords:
+ if chord not in self.chord_map:
+ self.chord_map[chord] = {}
+ c = Chord(chord)
+ for note in c.components():
+ self.chord_map[chord][note] = self.determine_frets(note)
+
+ def determine_frets(self, note):
+ if note not in self.note_to_fret_map:
+ frets = []
+ for string in strings:
+ current_string = (notes[notes.index(string):] + notes[:notes.index(string)]) * 2
+ if note in enharmonic_map:
+ note = enharmonic_map[note]
+ frets.append([i for i, x in enumerate(current_string) if x == note and i <= 12])
+
+ self.note_to_fret_map[note] = frets
+ return self.note_to_fret_map[note]
+
+ def prepare_chord_map(self):
+ for chord, data in self.chord_map.items():
+ self.prepped_chord_map[chord] = []
+ for note, strings in data.items():
+ for idx, string in enumerate(strings):
+ for fret in string:
+ html_fret = f'{html_string_ids[idx]}{fret}'
+ self.prepped_chord_map[chord].append(html_fret)
+ self.all_frets.append(html_fret)
+
+ def prepare_counts(self):
+ self.counts = {x:self.all_frets.count(x) for x in self.all_frets}
+
+
+if __name__ == '__main__':
+ t = ChordToneGenerator(["Ab", "Dsus2"])
+ t.main()
+
+
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..aaa787d
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,26 @@
+attrdict==2.0.0
+blinker==1.8.2
+click==8.1.7
+cssselect2==0.7.0
+Flask==3.0.3
+freetype-py==2.3.0
+fretboardgtr==0.2.7
+itsdangerous==2.2.0
+Jinja2==3.1.4
+lxml==5.3.0
+MarkupSafe==2.1.5
+pillow==10.4.0
+pycairo==1.27.0
+pychord==1.2.2
+pyparsing==3.1.4
+pypdf==5.0.0
+PyYAML==6.0.2
+reportlab==4.0.0
+rlPyCairo==0.3.0
+six==1.16.0
+svglib==1.5.1
+svgwrite==1.1.9
+tinycss2==1.3.0
+webencodings==0.5.1
+Werkzeug==3.0.4
+wheel==0.44.0
diff --git a/static/fretboard.png b/static/fretboard.png
new file mode 100644
index 0000000..eab2b88
--- /dev/null
+++ b/static/fretboard.png
Binary files differ
diff --git a/static/main.css b/static/main.css
new file mode 100644
index 0000000..63f6bc7
--- /dev/null
+++ b/static/main.css
@@ -0,0 +1,94 @@
+.fretboard-container {
+ position: relative;
+ padding: 30px;
+ padding-left: 50px;
+}
+
+.fretboard-container div {
+ position: absolute;
+ height: 20px;
+ width: 30px;
+}
+
+.fretboard-container div div {
+ width:100%;
+ height: 100%;
+ float:left;
+ position: relative;
+}
+
+.e {
+ top: 20px
+}
+
+.b {
+ top: 60px;
+}
+
+.g {
+ top: 100px;
+}
+
+.d {
+ top: 140px;
+}
+
+.a {
+ top: 180px;
+}
+
+.E {
+ top: 220px;
+}
+
+.zero {
+ left: 10px;
+}
+
+.one {
+ left: 70px;
+}
+
+.two {
+ left: 125px
+}
+
+.three {
+ left: 177px;
+}
+
+.four {
+ left: 230px;
+}
+
+.five {
+ left: 282px;
+}
+
+.six {
+ left: 335px;
+}
+
+.seven {
+ left: 385px;
+}
+
+.eight {
+ left: 438px;
+}
+
+.nine {
+ left: 491px;
+}
+
+.ten {
+ left: 542px;
+}
+
+.eleven {
+ left: 597px;
+}
+
+.twelve {
+ left: 647px;
+} \ No newline at end of file
diff --git a/static/main.js b/static/main.js
new file mode 100644
index 0000000..4fcb1bd
--- /dev/null
+++ b/static/main.js
@@ -0,0 +1,29 @@
+var colors = ['red', 'green', 'blue', 'grey']
+var stats = document.getElementById("stats")
+
+function generateFretMarkers(chordMap, counts) {
+ var chordCount = 0;
+ for (const [chord, notes] of Object.entries(chordMap)) {
+ for (let i = 0; i < notes.length; i++) {
+ var fret = document.getElementById(notes[i]);
+ var fretMarker = document.createElement("div");
+ fretMarker.style.backgroundColor = colors[chordCount]
+
+ if (counts[notes[i]] == 2) {
+ fretMarker.style.width = "50%"
+ }
+
+ if (counts[notes[i]] == 3) {
+ fretMarker.style.width = "33%"
+ }
+
+ if (counts[notes[i]] == 4) {
+ fretMarker.style.width = "25%"
+ }
+
+ fret.appendChild(fretMarker)
+ }
+ stats.innerHTML += '<button style="height:20px; width:20px; background-color:' + colors[chordCount] + ';"></button>' + chord + ' ';
+ chordCount++
+ }
+}
diff --git a/templates/index.html b/templates/index.html
new file mode 100644
index 0000000..6da1376
--- /dev/null
+++ b/templates/index.html
@@ -0,0 +1,151 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>Chord Tone</title>
+ <link rel="stylesheet" href="/static/main.css">
+</head>
+<body>
+ <h1>Chord Tone Map Generator</h1>
+ <hr>
+ <p>This will map the notes of multiple chords on the fretboard in different colors.
+ Use this to map out chord tones for improvisation, melody construction,
+ and whatever else you can think of. If this has helped you at all,
+ please consider <a href="https://www.domdit.com/donate" target="_blank">donating</a>!</p>
+
+ <form method="post">
+
+ <datalist id="chords">
+ {% for chord in chords %}
+ <option value="{{chord}}">{{chord}}</option>
+ {% endfor %}
+ </datalist>
+
+ <label for="chord_1">Chord 1:</label>
+ <input list="chords" name="chord_1" id="chord_1">
+
+ <label for="chord_2">Chord 2:</label>
+ <input list="chords" name="chord_2" id="chord_2">
+ <br>
+ <label for="chord_3">Chord 3:</label>
+ <input list="chords" name="chord_3" id="chord_3">
+
+ <label for="chord_4">Chord 4:</label>
+ <input list="chords" name="chord_4" id="chord_4">
+
+ <br><br>
+ <input type="submit" value="Submit">
+ </form>
+
+ <br>
+
+ <div class="fretboard-container">
+
+ <img src="{{ url_for('static', filename='fretboard.png') }}">
+
+ <div id="e0" class="e zero"></div>
+ <div id="e1" class="e one"></div>
+ <div id="e2" class="e two"></div>
+ <div id="e3" class="e three"></div>
+ <div id="e4" class="e four"></div>
+ <div id="e5" class="e five"></div>
+ <div id="e6" class="e six"></div>
+ <div id="e7" class="e seven"></div>
+ <div id="e8" class="e eight"></div>
+ <div id="e9" class="e nine"></div>
+ <div id="e10" class="e ten"></div>
+ <div id="e11" class="e eleven"></div>
+ <div id="e12" class="e twelve"></div>
+
+ <div id="b0" class="b zero"></div>
+ <div id="b1" class="b one"></div>
+ <div id="b2" class="b two"></div>
+ <div id="b3" class="b three"></div>
+ <div id="b4" class="b four"></div>
+ <div id="b5" class="b five"></div>
+ <div id="b6" class="b six"></div>
+ <div id="b7" class="b seven"></div>
+ <div id="b8" class="b eight"></div>
+ <div id="b9" class="b nine"></div>
+ <div id="b10" class="b ten"></div>
+ <div id="b11" class="b eleven"></div>
+ <div id="b12" class="b twelve"></div>
+
+ <div id="g0" class="g zero"></div>
+ <div id="g1" class="g one"></div>
+ <div id="g2" class="g two"></div>
+ <div id="g3" class="g three"></div>
+ <div id="g4" class="g four"></div>
+ <div id="g5" class="g five"></div>
+ <div id="g6" class="g six"></div>
+ <div id="g7" class="g seven"></div>
+ <div id="g8" class="g eight"></div>
+ <div id="g9" class="g nine"></div>
+ <div id="g10" class="g ten"></div>
+ <div id="g11" class="g eleven"></div>
+ <div id="g12" class="g twelve"></div>
+
+ <div id="d0" class="d zero"></div>
+ <div id="d1" class="d one"></div>
+ <div id="d2" class="d two"></div>
+ <div id="d3" class="d three"></div>
+ <div id="d4" class="d four"></div>
+ <div id="d5" class="d five"></div>
+ <div id="d6" class="d six"></div>
+ <div id="d7" class="d seven"></div>
+ <div id="d8" class="d eight"></div>
+ <div id="d9" class="d nine"></div>
+ <div id="d10" class="d ten"></div>
+ <div id="d11" class="d eleven"></div>
+ <div id="d12" class="d twelve"></div>
+
+ <div id="a0" class="a zero"></div>
+ <div id="a1" class="a one"></div>
+ <div id="a2" class="a two"></div>
+ <div id="a3" class="a three"></div>
+ <div id="a4" class="a four"></div>
+ <div id="a5" class="a five"></div>
+ <div id="a6" class="a six"></div>
+ <div id="a7" class="a seven"></div>
+ <div id="a8" class="a eight"></div>
+ <div id="a9" class="a nine"></div>
+ <div id="a10" class="a ten"></div>
+ <div id="a11" class="a eleven"></div>
+ <div id="a12" class="a twelve"></div>
+
+ <div id="ee0" class="E zero"></div>
+ <div id="ee1" class="E one"></div>
+ <div id="ee2" class="E two"></div>
+ <div id="ee3" class="E three"></div>
+ <div id="ee4" class="E four"></div>
+ <div id="ee5" class="E five"></div>
+ <div id="ee6" class="E six"></div>
+ <div id="ee7" class="E seven"></div>
+ <div id="ee8" class="E eight"></div>
+ <div id="ee9" class="E nine"></div>
+ <div id="ee10" class="E ten"></div>
+ <div id="ee11" class="E eleven"></div>
+ <div id="ee12" class="E twelve"></div>
+ </div>
+
+ <div id="stats"></div>
+
+ <hr>
+ <h4>Upcoming Features:</h4>
+ <ul>
+ <li>Select Your Own Colors</li>
+ <li>Fix the fret dots so they are more visible</li>
+ <li>Add up to 24 frets</li>
+ <li>Add option to choose your which frets you want to see</li>
+ <li>Improve the overall look of the app</li>
+ </ul>
+ <hr>
+ <small>Version 1.0 | Created By <a href="https://www.domdit.com" target="_blank">Dominic DiTaranto</a> | Questions/Suggestions: me@domdit.com | Last Update 09/22/2024</small>
+
+ <script src="static/main.js"></script>
+ <script>
+ generateFretMarkers(JSON.parse('{{chord_map | tojson}}'), JSON.parse('{{counts | tojson}}'))
+ </script>
+
+</body>
+</html> \ No newline at end of file