text-guitar-chart 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/FORMAT.md CHANGED
@@ -14,11 +14,13 @@ Strings are numbered 1-6 from right to left in the diagram. In standard guitar t
14
14
  - String 1 (rightmost) is the highest pitch (E4)
15
15
 
16
16
  ### Color values
17
- The format supports two colors for fingering markers:
17
+ The format supports four colors for fingering markers:
18
18
  - `#000000` (black) for regular fingering positions
19
19
  - `#e74c3c` (red/root marker color) for special positions (typically root notes)
20
+ - `#9B9B9B` (grey) for grey marker positions
21
+ - `#4A90E2` (blue) for blue marker positions
20
22
 
21
- Any color value other than `#000000` is treated as a root marker and rendered with the special marker symbol.
23
+ Any color value not matching one of the four known colors is treated as a root marker (red) and rendered with the root marker symbol.
22
24
 
23
25
  ## ascii format
24
26
 
@@ -47,7 +49,9 @@ The first line can optionally have an indication of the starting fret on the lef
47
49
  These different characters are used:
48
50
  - "|" indicates that there is no fingering in this position
49
51
  - "o" indicates that this position is fingered with a regular dot (color #000000)
50
- - "*" indicates that this position is fingered with a root marker (non-black color, typically #e74c3c)
52
+ - "*" indicates that this position is fingered with a root marker (color #e74c3c or any unrecognized color)
53
+ - "O" (uppercase) indicates that this position is fingered with a grey marker (color #9B9B9B)
54
+ - "+" indicates that this position is fingered with a blue marker (color #4A90E2)
51
55
  - any other character is displayed as text on the fretboard at that position (commonly used for finger numbers or note names)
52
56
 
53
57
  Examples:
@@ -139,7 +143,9 @@ The second line can optionally have an indication of the starting fret on the le
139
143
  The even rows contain characters representing the fingering:
140
144
  - "│" indicates that there is no fingering in this position
141
145
  - "○" indicates that this position is fingered with a regular dot (color #000000)
142
- - "●" indicates that this position is fingered with a root marker (non-black color, typically #e74c3c)
146
+ - "●" indicates that this position is fingered with a root marker (color #e74c3c or any unrecognized color)
147
+ - "□" indicates that this position is fingered with a grey marker (color #9B9B9B)
148
+ - "■" indicates that this position is fingered with a blue marker (color #4A90E2)
143
149
  - any other character is displayed as text on the fretboard at that position (commonly used for finger numbers or note names)
144
150
 
145
151
  Example:
package/docs/bundle.js CHANGED
@@ -1,4 +1,15 @@
1
1
  // lib/fingeringToString.js
2
+ var COLOR_GREY = "#9B9B9B";
3
+ var COLOR_BLUE = "#4A90E2";
4
+ function getMarkerChar(color, isUnicode) {
5
+ if (color === COLOR_GREY) {
6
+ return isUnicode ? "\u25A1" : "O";
7
+ }
8
+ if (color === COLOR_BLUE) {
9
+ return isUnicode ? "\u25A0" : "+";
10
+ }
11
+ return isUnicode ? "\u25CF" : "*";
12
+ }
2
13
  function fingeringToString(chord, options = {}) {
3
14
  const { useUnicode = false } = options;
4
15
  const { fingers = [], title = "", position: position2 } = chord;
@@ -84,7 +95,7 @@ function buildAsciiOutput(title, stringData, openStrings, mutedStrings, numFrets
84
95
  const fingerInfo = (_a12 = stringData.get(str)) == null ? void 0 : _a12.get(fret);
85
96
  if (fingerInfo) {
86
97
  if (fingerInfo.color !== "#000000") {
87
- line += "*";
98
+ line += getMarkerChar(fingerInfo.color, false);
88
99
  } else if (fingerInfo.text) {
89
100
  line += fingerInfo.text[0];
90
101
  } else {
@@ -141,7 +152,7 @@ function buildUnicodeOutput(title, stringData, openStrings, mutedStrings, numFre
141
152
  const fingerInfo = (_a12 = stringData.get(str)) == null ? void 0 : _a12.get(fret);
142
153
  if (fingerInfo) {
143
154
  if (fingerInfo.color !== "#000000") {
144
- line += "\u25CF";
155
+ line += getMarkerChar(fingerInfo.color, true);
145
156
  } else if (fingerInfo.text) {
146
157
  line += fingerInfo.text[0];
147
158
  } else {
@@ -7420,7 +7431,9 @@ var SVGuitarChord = (
7420
7431
  // lib/editableSVGuitar.js
7421
7432
  var DOT_COLORS = {
7422
7433
  RED: "#e74c3c",
7423
- BLACK: "#000000"
7434
+ BLACK: "#000000",
7435
+ GREY: "#9B9B9B",
7436
+ BLUE: "#4A90E2"
7424
7437
  };
7425
7438
  var EditableSVGuitarChord = class {
7426
7439
  /**
@@ -7491,7 +7504,7 @@ var EditableSVGuitarChord = class {
7491
7504
  padding: 20px;
7492
7505
  box-shadow: 0 4px 20px rgba(0,0,0,0.3);
7493
7506
  z-index: 1000;
7494
- min-width: 280px;
7507
+ min-width: 220px;
7495
7508
  `;
7496
7509
  const title = document.createElement("h3");
7497
7510
  title.textContent = "Chord Settings";
@@ -7499,28 +7512,32 @@ var EditableSVGuitarChord = class {
7499
7512
  const titleSection = document.createElement("div");
7500
7513
  titleSection.style.cssText = "margin-bottom: 15px;";
7501
7514
  const titleLabel = document.createElement("label");
7502
- titleLabel.textContent = "Title (optional): ";
7503
- titleLabel.style.cssText = "display: block; margin-bottom: 5px; font-weight: bold;";
7515
+ titleLabel.textContent = "Title: ";
7516
+ titleLabel.htmlFor = "editable-svguitar-title-input";
7517
+ titleLabel.style.cssText = "display: inline-block; margin-bottom: 5px; font-weight: bold; width: 80px;";
7504
7518
  this.titleInput = document.createElement("input");
7519
+ this.titleInput.id = "editable-svguitar-title-input";
7505
7520
  this.titleInput.type = "text";
7506
7521
  this.titleInput.placeholder = "e.g. A min";
7507
7522
  this.titleInput.maxLength = 10;
7508
7523
  this.titleInput.style.cssText = "width: 10em; padding: 6px; border: 1px solid #ccc; border-radius: 3px; box-sizing: border-box;";
7509
- titleLabel.appendChild(this.titleInput);
7510
7524
  titleSection.appendChild(titleLabel);
7525
+ titleSection.appendChild(this.titleInput);
7511
7526
  const positionSection = document.createElement("div");
7512
7527
  positionSection.style.cssText = "margin-bottom: 15px;";
7513
7528
  const positionLabel = document.createElement("label");
7514
- positionLabel.textContent = "Position (optional): ";
7515
- positionLabel.style.cssText = "display: block; margin-bottom: 5px; font-weight: bold;";
7529
+ positionLabel.textContent = "Position: ";
7530
+ positionLabel.htmlFor = "editable-svguitar-position-input";
7531
+ positionLabel.style.cssText = "display: inline-block; margin-bottom: 5px; font-weight: bold; width: 80px;";
7516
7532
  this.positionInput = document.createElement("input");
7533
+ this.positionInput.id = "editable-svguitar-position-input";
7517
7534
  this.positionInput.type = "number";
7518
7535
  this.positionInput.min = "1";
7519
7536
  this.positionInput.max = "30";
7520
7537
  this.positionInput.placeholder = "1-30";
7521
7538
  this.positionInput.style.cssText = "width: 5em; padding: 6px; border: 1px solid #ccc; border-radius: 3px; box-sizing: border-box;";
7522
- positionLabel.appendChild(this.positionInput);
7523
7539
  positionSection.appendChild(positionLabel);
7540
+ positionSection.appendChild(this.positionInput);
7524
7541
  const buttonDiv = document.createElement("div");
7525
7542
  buttonDiv.style.cssText = "display: flex; gap: 10px; justify-content: flex-end;";
7526
7543
  const cancelBtn = document.createElement("button");
@@ -7568,60 +7585,82 @@ var EditableSVGuitarChord = class {
7568
7585
  padding: 20px;
7569
7586
  box-shadow: 0 4px 20px rgba(0,0,0,0.3);
7570
7587
  z-index: 1000;
7571
- min-width: 250px;
7588
+ min-width: 200px;
7572
7589
  `;
7573
7590
  const title = document.createElement("h3");
7574
7591
  title.textContent = "Edit Dot";
7575
7592
  title.style.cssText = "margin: 0 0 15px 0; font-size: 16px;";
7576
7593
  const colorSection = document.createElement("div");
7577
7594
  colorSection.style.cssText = "margin-bottom: 15px;";
7578
- const colorLabel = document.createElement("div");
7579
- colorLabel.textContent = "Color:";
7580
- colorLabel.style.cssText = "font-weight: bold; margin-bottom: 8px;";
7581
- colorSection.appendChild(colorLabel);
7582
7595
  const colorOptions = document.createElement("div");
7583
- colorOptions.style.cssText = "display: flex; gap: 15px;";
7596
+ colorOptions.style.cssText = "display: flex; gap: 8px; align-items: center;";
7597
+ const hiddenRadioStyle = "position:absolute;opacity:0;width:0;height:0;";
7598
+ const swatchStyle = (color) => `width:28px;height:28px;display:block;background:${color};border-radius:3px;cursor:pointer;box-sizing:border-box;`;
7584
7599
  const redOption = document.createElement("label");
7585
- redOption.style.cssText = "display: flex; align-items: center; cursor: pointer;";
7600
+ redOption.style.cssText = "display:inline-block;position:relative;cursor:pointer;";
7586
7601
  this.redRadio = document.createElement("input");
7587
7602
  this.redRadio.type = "radio";
7588
7603
  this.redRadio.name = "dotColor";
7589
7604
  this.redRadio.value = DOT_COLORS.RED;
7605
+ this.redRadio.style.cssText = hiddenRadioStyle;
7590
7606
  this.redRadio.addEventListener("change", () => this.updateDotColor());
7591
- const redLabel = document.createElement("span");
7592
- redLabel.textContent = "Red";
7593
- redLabel.style.cssText = "margin-left: 5px; color: #e74c3c; font-weight: bold;";
7607
+ const redSwatch = document.createElement("span");
7608
+ redSwatch.className = "color-swatch";
7609
+ redSwatch.style.cssText = swatchStyle(DOT_COLORS.RED);
7594
7610
  redOption.appendChild(this.redRadio);
7595
- redOption.appendChild(redLabel);
7611
+ redOption.appendChild(redSwatch);
7612
+ const greyOption = document.createElement("label");
7613
+ greyOption.style.cssText = "display:inline-block;position:relative;cursor:pointer;";
7614
+ this.greyRadio = document.createElement("input");
7615
+ this.greyRadio.type = "radio";
7616
+ this.greyRadio.name = "dotColor";
7617
+ this.greyRadio.value = DOT_COLORS.GREY;
7618
+ this.greyRadio.style.cssText = hiddenRadioStyle;
7619
+ this.greyRadio.addEventListener("change", () => this.updateDotColor());
7620
+ const greySwatch = document.createElement("span");
7621
+ greySwatch.className = "color-swatch";
7622
+ greySwatch.style.cssText = swatchStyle(DOT_COLORS.GREY);
7623
+ greyOption.appendChild(this.greyRadio);
7624
+ greyOption.appendChild(greySwatch);
7625
+ const blueOption = document.createElement("label");
7626
+ blueOption.style.cssText = "display:inline-block;position:relative;cursor:pointer;";
7627
+ this.blueRadio = document.createElement("input");
7628
+ this.blueRadio.type = "radio";
7629
+ this.blueRadio.name = "dotColor";
7630
+ this.blueRadio.value = DOT_COLORS.BLUE;
7631
+ this.blueRadio.style.cssText = hiddenRadioStyle;
7632
+ this.blueRadio.addEventListener("change", () => this.updateDotColor());
7633
+ const blueSwatch = document.createElement("span");
7634
+ blueSwatch.className = "color-swatch";
7635
+ blueSwatch.style.cssText = swatchStyle(DOT_COLORS.BLUE);
7636
+ blueOption.appendChild(this.blueRadio);
7637
+ blueOption.appendChild(blueSwatch);
7596
7638
  const blackOption = document.createElement("label");
7597
- blackOption.style.cssText = "display: flex; align-items: center; cursor: pointer;";
7639
+ blackOption.style.cssText = "display:inline-block;position:relative;cursor:pointer;";
7598
7640
  this.blackRadio = document.createElement("input");
7599
7641
  this.blackRadio.type = "radio";
7600
7642
  this.blackRadio.name = "dotColor";
7601
7643
  this.blackRadio.value = DOT_COLORS.BLACK;
7602
7644
  this.blackRadio.checked = true;
7645
+ this.blackRadio.style.cssText = hiddenRadioStyle;
7603
7646
  this.blackRadio.addEventListener("change", () => this.updateDotColor());
7604
- const blackLabel = document.createElement("span");
7605
- blackLabel.textContent = "Black";
7606
- blackLabel.style.cssText = "margin-left: 5px; color: #000000; font-weight: bold;";
7647
+ const blackSwatch = document.createElement("span");
7648
+ blackSwatch.className = "color-swatch";
7649
+ blackSwatch.style.cssText = swatchStyle(DOT_COLORS.BLACK);
7607
7650
  blackOption.appendChild(this.blackRadio);
7608
- blackOption.appendChild(blackLabel);
7651
+ blackOption.appendChild(blackSwatch);
7609
7652
  colorOptions.appendChild(redOption);
7653
+ colorOptions.appendChild(greyOption);
7654
+ colorOptions.appendChild(blueOption);
7610
7655
  colorOptions.appendChild(blackOption);
7611
- colorSection.appendChild(colorOptions);
7612
- this.textSection = document.createElement("div");
7613
- this.textSection.style.cssText = "margin-bottom: 15px;";
7614
- const textLabel = document.createElement("label");
7615
- textLabel.textContent = "Text (optional): ";
7616
- textLabel.style.cssText = "display: block; margin-bottom: 5px; font-weight: bold;";
7617
7656
  this.textInput = document.createElement("input");
7618
7657
  this.textInput.type = "text";
7619
- this.textInput.maxLength = 2;
7620
- this.textInput.placeholder = "1-2 chars";
7621
- this.textInput.style.cssText = "width: 60px; padding: 4px; border: 1px solid #ccc; border-radius: 3px;";
7658
+ this.textInput.maxLength = 1;
7659
+ this.textInput.placeholder = "Aa";
7660
+ this.textInput.style.cssText = "width:32px;height:28px;padding:0 4px;margin-left:4px;border:1px solid #ccc;border-radius:3px;box-sizing:border-box;";
7622
7661
  this.textInput.addEventListener("input", () => this.updateDotText());
7623
- textLabel.appendChild(this.textInput);
7624
- this.textSection.appendChild(textLabel);
7662
+ colorOptions.appendChild(this.textInput);
7663
+ colorSection.appendChild(colorOptions);
7625
7664
  const buttonDiv = document.createElement("div");
7626
7665
  buttonDiv.style.cssText = "display: flex; gap: 10px; justify-content: flex-end;";
7627
7666
  const removeBtn = document.createElement("button");
@@ -7636,7 +7675,6 @@ var EditableSVGuitarChord = class {
7636
7675
  buttonDiv.appendChild(doneBtn);
7637
7676
  this.dialog.appendChild(title);
7638
7677
  this.dialog.appendChild(colorSection);
7639
- this.dialog.appendChild(this.textSection);
7640
7678
  this.dialog.appendChild(buttonDiv);
7641
7679
  document.body.appendChild(this.dialog);
7642
7680
  this.backdrop = document.createElement("div");
@@ -7670,60 +7708,59 @@ var EditableSVGuitarChord = class {
7670
7708
  padding: 20px;
7671
7709
  box-shadow: 0 4px 20px rgba(0,0,0,0.3);
7672
7710
  z-index: 1000;
7673
- min-width: 250px;
7711
+ min-width: 165px;
7674
7712
  `;
7675
7713
  const title = document.createElement("h3");
7676
7714
  title.textContent = "Edit Open String";
7677
7715
  title.style.cssText = "margin: 0 0 15px 0; font-size: 16px;";
7678
7716
  const typeSection = document.createElement("div");
7679
7717
  typeSection.style.cssText = "margin-bottom: 15px;";
7680
- const typeLabel = document.createElement("div");
7681
- typeLabel.textContent = "Type:";
7682
- typeLabel.style.cssText = "font-weight: bold; margin-bottom: 8px;";
7683
- typeSection.appendChild(typeLabel);
7684
7718
  const typeOptions = document.createElement("div");
7685
- typeOptions.style.cssText = "display: flex; gap: 15px;";
7719
+ typeOptions.style.cssText = "display: flex; gap: 8px; align-items: center;";
7720
+ const hiddenRadioStyle = "position:absolute;opacity:0;width:0;height:0;";
7721
+ const openStringSwatchStyle = "width:28px;height:28px;display:flex;align-items:center;justify-content:center;background:#fff;border:1px solid #ccc;border-radius:3px;cursor:pointer;box-sizing:border-box;font-size:16px;font-weight:bold;user-select:none;";
7722
+ const mutedOption = document.createElement("label");
7723
+ mutedOption.style.cssText = "display:inline-block;position:relative;cursor:pointer;";
7724
+ this.mutedRadio = document.createElement("input");
7725
+ this.mutedRadio.type = "radio";
7726
+ this.mutedRadio.name = "openStringType";
7727
+ this.mutedRadio.value = "x";
7728
+ this.mutedRadio.style.cssText = hiddenRadioStyle;
7729
+ this.mutedRadio.addEventListener("change", () => this.updateOpenStringType());
7730
+ const mutedSwatch = document.createElement("span");
7731
+ mutedSwatch.className = "open-string-swatch";
7732
+ mutedSwatch.textContent = "\xD7";
7733
+ mutedSwatch.style.cssText = openStringSwatchStyle;
7734
+ mutedOption.appendChild(this.mutedRadio);
7735
+ mutedOption.appendChild(mutedSwatch);
7686
7736
  const openOption = document.createElement("label");
7687
- openOption.style.cssText = "display: flex; align-items: center; cursor: pointer;";
7737
+ openOption.style.cssText = "display:inline-block;position:relative;cursor:pointer;";
7688
7738
  this.openRadio = document.createElement("input");
7689
7739
  this.openRadio.type = "radio";
7690
7740
  this.openRadio.name = "openStringType";
7691
7741
  this.openRadio.value = "0";
7692
7742
  this.openRadio.checked = true;
7743
+ this.openRadio.style.cssText = hiddenRadioStyle;
7693
7744
  this.openRadio.addEventListener("change", () => this.updateOpenStringType());
7694
- const openLabel = document.createElement("span");
7695
- openLabel.textContent = "Open";
7696
- openLabel.style.cssText = "margin-left: 5px; font-weight: bold;";
7745
+ const openSwatch = document.createElement("span");
7746
+ openSwatch.className = "open-string-swatch";
7747
+ openSwatch.textContent = "\u25CB";
7748
+ openSwatch.style.cssText = openStringSwatchStyle;
7697
7749
  openOption.appendChild(this.openRadio);
7698
- openOption.appendChild(openLabel);
7699
- const mutedOption = document.createElement("label");
7700
- mutedOption.style.cssText = "display: flex; align-items: center; cursor: pointer;";
7701
- this.mutedRadio = document.createElement("input");
7702
- this.mutedRadio.type = "radio";
7703
- this.mutedRadio.name = "openStringType";
7704
- this.mutedRadio.value = "x";
7705
- this.mutedRadio.addEventListener("change", () => this.updateOpenStringType());
7706
- const mutedLabel = document.createElement("span");
7707
- mutedLabel.textContent = "Muted";
7708
- mutedLabel.style.cssText = "margin-left: 5px; font-weight: bold;";
7709
- mutedOption.appendChild(this.mutedRadio);
7710
- mutedOption.appendChild(mutedLabel);
7711
- typeOptions.appendChild(openOption);
7750
+ openOption.appendChild(openSwatch);
7712
7751
  typeOptions.appendChild(mutedOption);
7713
- typeSection.appendChild(typeOptions);
7714
- this.openStringTextSection = document.createElement("div");
7715
- this.openStringTextSection.style.cssText = "margin-bottom: 15px;";
7716
- const textLabel = document.createElement("label");
7717
- textLabel.textContent = "Text (optional): ";
7718
- textLabel.style.cssText = "display: block; margin-bottom: 5px; font-weight: bold;";
7752
+ typeOptions.appendChild(openOption);
7719
7753
  this.openStringTextInput = document.createElement("input");
7720
7754
  this.openStringTextInput.type = "text";
7721
- this.openStringTextInput.maxLength = 2;
7722
- this.openStringTextInput.placeholder = "1-2 chars";
7723
- this.openStringTextInput.style.cssText = "width: 60px; padding: 4px; border: 1px solid #ccc; border-radius: 3px;";
7724
- this.openStringTextInput.addEventListener("input", () => this.updateOpenStringText());
7725
- textLabel.appendChild(this.openStringTextInput);
7726
- this.openStringTextSection.appendChild(textLabel);
7755
+ this.openStringTextInput.maxLength = 1;
7756
+ this.openStringTextInput.placeholder = "Aa";
7757
+ this.openStringTextInput.style.cssText = "width:32px;height:28px;padding:0 4px;margin-left:4px;border:1px solid #ccc;border-radius:3px;box-sizing:border-box;";
7758
+ this.openStringTextInput.addEventListener(
7759
+ "input",
7760
+ () => this.updateOpenStringText()
7761
+ );
7762
+ typeOptions.appendChild(this.openStringTextInput);
7763
+ typeSection.appendChild(typeOptions);
7727
7764
  const buttonDiv = document.createElement("div");
7728
7765
  buttonDiv.style.cssText = "display: flex; gap: 10px; justify-content: flex-end;";
7729
7766
  const removeBtn = document.createElement("button");
@@ -7738,7 +7775,6 @@ var EditableSVGuitarChord = class {
7738
7775
  buttonDiv.appendChild(doneBtn);
7739
7776
  this.openStringDialog.appendChild(title);
7740
7777
  this.openStringDialog.appendChild(typeSection);
7741
- this.openStringDialog.appendChild(this.openStringTextSection);
7742
7778
  this.openStringDialog.appendChild(buttonDiv);
7743
7779
  document.body.appendChild(this.openStringDialog);
7744
7780
  this.openStringBackdrop = document.createElement("div");
@@ -7983,9 +8019,14 @@ var EditableSVGuitarChord = class {
7983
8019
  this.currentEditFret = fret;
7984
8020
  const currentColor = typeof finger[2] === "object" && ((_a12 = finger[2]) == null ? void 0 : _a12.color) || DOT_COLORS.BLACK;
7985
8021
  const currentText = typeof finger[2] === "object" && ((_b = finger[2]) == null ? void 0 : _b.text) || "";
7986
- const normalizedColor = currentColor === DOT_COLORS.RED ? DOT_COLORS.RED : DOT_COLORS.BLACK;
8022
+ let normalizedColor = DOT_COLORS.BLACK;
8023
+ if (currentColor === DOT_COLORS.RED) normalizedColor = DOT_COLORS.RED;
8024
+ else if (currentColor === DOT_COLORS.GREY) normalizedColor = DOT_COLORS.GREY;
8025
+ else if (currentColor === DOT_COLORS.BLUE) normalizedColor = DOT_COLORS.BLUE;
7987
8026
  this.redRadio.checked = normalizedColor === DOT_COLORS.RED;
7988
8027
  this.blackRadio.checked = normalizedColor === DOT_COLORS.BLACK;
8028
+ this.greyRadio.checked = normalizedColor === DOT_COLORS.GREY;
8029
+ this.blueRadio.checked = normalizedColor === DOT_COLORS.BLUE;
7989
8030
  this.textInput.value = currentText;
7990
8031
  this.updateTextSectionVisibility();
7991
8032
  this.openDialog();
@@ -8207,6 +8248,14 @@ var EditableSVGuitarChord = class {
8207
8248
  .editable-svguitar-settings-btn:hover {
8208
8249
  background: #f0f0f0;
8209
8250
  }
8251
+
8252
+ .editable-svguitar-dialog input[name="dotColor"]:checked + .color-swatch {
8253
+ box-shadow: 0 0 0 2px white, 0 0 0 4px grey;
8254
+ }
8255
+
8256
+ .editable-svguitar-open-string-dialog input[name="openStringType"]:checked + .open-string-swatch {
8257
+ box-shadow: 0 0 0 2px white, 0 0 0 4px grey;
8258
+ }
8210
8259
  `;
8211
8260
  document.head.appendChild(style);
8212
8261
  }
@@ -8238,23 +8287,19 @@ var EditableSVGuitarChord = class {
8238
8287
  * Update text section visibility based on color selection
8239
8288
  */
8240
8289
  updateTextSectionVisibility() {
8241
- if (!this.textSection) return;
8290
+ if (!this.textInput) return;
8242
8291
  const isBlack = this.blackRadio && this.blackRadio.checked;
8243
- this.textSection.style.display = isBlack ? "block" : "none";
8244
- if (this.textInput) {
8245
- this.textInput.disabled = !isBlack;
8246
- }
8292
+ this.textInput.style.display = isBlack ? "inline-block" : "none";
8293
+ this.textInput.disabled = !isBlack;
8247
8294
  }
8248
8295
  /**
8249
8296
  * Update text section visibility for open string dialog based on type selection
8250
8297
  */
8251
8298
  updateOpenStringTextSectionVisibility() {
8252
- if (!this.openStringTextSection) return;
8299
+ if (!this.openStringTextInput) return;
8253
8300
  const isOpen = this.openRadio && this.openRadio.checked;
8254
- this.openStringTextSection.style.display = isOpen ? "block" : "none";
8255
- if (this.openStringTextInput) {
8256
- this.openStringTextInput.disabled = !isOpen;
8257
- }
8301
+ this.openStringTextInput.style.display = isOpen ? "inline-block" : "none";
8302
+ this.openStringTextInput.disabled = !isOpen;
8258
8303
  }
8259
8304
  /**
8260
8305
  * Update dot text in real-time
@@ -8308,10 +8353,13 @@ var EditableSVGuitarChord = class {
8308
8353
  if (!this.currentEditFinger[2]) {
8309
8354
  this.currentEditFinger[2] = {};
8310
8355
  }
8311
- const selectedColor = this.redRadio.checked ? DOT_COLORS.RED : DOT_COLORS.BLACK;
8356
+ let selectedColor = DOT_COLORS.BLACK;
8357
+ if (this.redRadio.checked) selectedColor = DOT_COLORS.RED;
8358
+ else if (this.greyRadio.checked) selectedColor = DOT_COLORS.GREY;
8359
+ else if (this.blueRadio.checked) selectedColor = DOT_COLORS.BLUE;
8312
8360
  const fingerOptions = typeof this.currentEditFinger[2] === "object" ? this.currentEditFinger[2] : {};
8313
8361
  this.currentEditFinger[2] = { ...fingerOptions, color: selectedColor };
8314
- if (selectedColor === DOT_COLORS.RED) {
8362
+ if (selectedColor !== DOT_COLORS.BLACK) {
8315
8363
  this.currentEditFinger[2].text = "";
8316
8364
  this.textInput.value = "";
8317
8365
  }
@@ -8327,7 +8375,10 @@ var EditableSVGuitarChord = class {
8327
8375
  if (!this.currentEditFinger[2]) {
8328
8376
  this.currentEditFinger[2] = {};
8329
8377
  }
8330
- const selectedColor = this.redRadio.checked ? DOT_COLORS.RED : DOT_COLORS.BLACK;
8378
+ let selectedColor = DOT_COLORS.BLACK;
8379
+ if (this.redRadio.checked) selectedColor = DOT_COLORS.RED;
8380
+ else if (this.greyRadio.checked) selectedColor = DOT_COLORS.GREY;
8381
+ else if (this.blueRadio.checked) selectedColor = DOT_COLORS.BLUE;
8331
8382
  this.currentEditFinger[2] = { text: this.textInput.value, color: selectedColor };
8332
8383
  this.closeDialog();
8333
8384
  this.redraw();
@@ -8543,13 +8594,17 @@ var ASCII_EQUALS = "=";
8543
8594
  var ASCII_OPEN = "o";
8544
8595
  var ASCII_MUTED = "x";
8545
8596
  var ASCII_ROOT = "*";
8597
+ var ASCII_GREY = "O";
8598
+ var ASCII_BLUE = "+";
8546
8599
  var UNICODE_VERTICAL = "\u2502";
8547
8600
  var UNICODE_OPEN = "\u25CB";
8548
8601
  var UNICODE_MUTED = "\xD7";
8549
8602
  var UNICODE_ROOT = "\u25CF";
8603
+ var UNICODE_GREY = "\u25A1";
8604
+ var UNICODE_BLUE = "\u25A0";
8550
8605
  var UNICODE_BOX_CHARS = "\u2552\u2550\u2564\u2555\u251C\u2500\u253C\u2524\u2514\u2534\u2518\u250C\u252C\u2510";
8551
8606
  function isUnicodeFormat(str) {
8552
- return str.includes(UNICODE_VERTICAL) || str.includes(UNICODE_OPEN) || str.includes(UNICODE_ROOT) || str.includes(UNICODE_MUTED) || [...UNICODE_BOX_CHARS].some((c2) => str.includes(c2));
8607
+ return str.includes(UNICODE_VERTICAL) || str.includes(UNICODE_OPEN) || str.includes(UNICODE_ROOT) || str.includes(UNICODE_MUTED) || str.includes(UNICODE_GREY) || str.includes(UNICODE_BLUE) || [...UNICODE_BOX_CHARS].some((c2) => str.includes(c2));
8553
8608
  }
8554
8609
  function findUnicodeGridBoundaries(lines, firstGridRowIdx) {
8555
8610
  const firstLine = lines[firstGridRowIdx];
@@ -8626,7 +8681,12 @@ function isGridRow(line, isUnicode) {
8626
8681
  }
8627
8682
  }
8628
8683
  function stringToFingering(fingeringStr, options = {}) {
8629
- const { redColor = "#e74c3c", blackColor = "#000000" } = options;
8684
+ const {
8685
+ redColor = "#e74c3c",
8686
+ blackColor = "#000000",
8687
+ greyColor = "#9B9B9B",
8688
+ blueColor = "#4A90E2"
8689
+ } = options;
8630
8690
  if (!fingeringStr || fingeringStr.trim() === "") {
8631
8691
  return null;
8632
8692
  }
@@ -8635,6 +8695,8 @@ function stringToFingering(fingeringStr, options = {}) {
8635
8695
  const openChar = isUnicode ? UNICODE_OPEN : ASCII_OPEN;
8636
8696
  const mutedChar = isUnicode ? UNICODE_MUTED : ASCII_MUTED;
8637
8697
  const rootChar = isUnicode ? UNICODE_ROOT : ASCII_ROOT;
8698
+ const greyChar = isUnicode ? UNICODE_GREY : ASCII_GREY;
8699
+ const blueChar = isUnicode ? UNICODE_BLUE : ASCII_BLUE;
8638
8700
  const fingers = [];
8639
8701
  let title;
8640
8702
  let position2;
@@ -8746,6 +8808,10 @@ function stringToFingering(fingeringStr, options = {}) {
8746
8808
  }
8747
8809
  if (char === rootChar) {
8748
8810
  fingers.push([stringNum, fretNumber, { text: "", color: redColor }]);
8811
+ } else if (char === greyChar) {
8812
+ fingers.push([stringNum, fretNumber, { text: "", color: greyColor }]);
8813
+ } else if (char === blueChar) {
8814
+ fingers.push([stringNum, fretNumber, { text: "", color: blueColor }]);
8749
8815
  } else if (char === UNICODE_OPEN || char === ASCII_OPEN) {
8750
8816
  fingers.push([stringNum, fretNumber, { text: "", color: blackColor }]);
8751
8817
  } else if (/\S/.test(char)) {