@onjmin/dtm 0.1.11 → 0.1.13

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/dist/index.mjs CHANGED
@@ -1104,6 +1104,9 @@ var ICONS = {
1104
1104
  settings: {
1105
1105
  d: "M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065zM15 12a3 3 0 11-6 0 3 3 0 016 0z",
1106
1106
  stroke: true
1107
+ },
1108
+ info: {
1109
+ d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z"
1107
1110
  }
1108
1111
  };
1109
1112
  var icon = (name, size = 20) => {
@@ -1214,19 +1217,32 @@ var buildUI = (target, options) => {
1214
1217
  <summary>MIDI / MML \u5165\u529B</summary>
1215
1218
  <div class="dtm-panel-body">
1216
1219
  <div class="dtm-row">
1217
- <span class="dtm-label">MIDI</span>
1220
+ <div style="display: inline-flex; flex-direction: column; align-items: center; gap: 4px; justify-content: center; min-width: 48px;">
1221
+ <span class="dtm-label" style="line-height: 1;">MIDI</span>
1222
+ <button class="dtm-infobtn" data-dtm="midi-info" title="MIDI\u306E\u8AAD\u307F\u8FBC\u307F\u89E3\u8AAC">${icon("info", 12)}</button>
1223
+ </div>
1218
1224
  <input type="file" class="dtm-input dtm-grow" accept=".mid,.midi" data-dtm="midi-input">
1219
1225
  <button class="dtm-btn dtm-btn--success" data-dtm="midi-load">\u8AAD\u8FBC</button>
1220
1226
  </div>
1221
1227
  <div class="dtm-row dtm-hidden" data-dtm="midi-track-selection"></div>
1222
1228
  <div class="dtm-row">
1223
- <span class="dtm-label">MML</span>
1229
+ <div style="display: inline-flex; flex-direction: column; align-items: center; gap: 4px; justify-content: center; min-width: 48px;">
1230
+ <span class="dtm-label" style="line-height: 1;">MML</span>
1231
+ <button class="dtm-infobtn" data-dtm="mml-info" title="MML\u306E\u66F8\u304D\u65B9\u89E3\u8AAC">${icon("info", 12)}</button>
1232
+ </div>
1224
1233
  <textarea class="dtm-textarea dtm-grow" data-dtm="mml-input" placeholder="MML\u3092\u5165\u529B"></textarea>
1225
1234
  <button class="dtm-btn dtm-btn--primary" data-dtm="mml-load">\u8AAD\u8FBC</button>
1226
1235
  </div>
1236
+ </div>
1237
+ </details>
1238
+
1239
+ <details class="dtm-panel">
1240
+ <summary>\u30DE\u30AF\u30ED</summary>
1241
+ <div class="dtm-panel-body">
1227
1242
  <div class="dtm-row">
1228
1243
  <span class="dtm-label">\u5168\u4F53\u30B7\u30D5\u30C8</span>
1229
1244
  <select class="dtm-select" data-dtm="shift-select">
1245
+ <option value="-192">-1\u5C0F\u7BC0</option>
1230
1246
  <option value="-96">-2\u5206</option>
1231
1247
  <option value="-48">-4\u5206</option>
1232
1248
  <option value="-24">-8\u5206</option>
@@ -1235,15 +1251,10 @@ var buildUI = (target, options) => {
1235
1251
  <option value="24">+8\u5206</option>
1236
1252
  <option value="48">+4\u5206</option>
1237
1253
  <option value="96">+2\u5206</option>
1254
+ <option value="192">+1\u5C0F\u7BC0</option>
1238
1255
  </select>
1239
1256
  <button class="dtm-btn dtm-btn--primary" data-dtm="shift-apply">\u9069\u7528</button>
1240
1257
  </div>
1241
- </div>
1242
- </details>
1243
-
1244
- <details class="dtm-panel">
1245
- <summary>\u30DE\u30AF\u30ED</summary>
1246
- <div class="dtm-panel-body">
1247
1258
  <div class="dtm-row">
1248
1259
  <button class="dtm-btn dtm-btn--danger" data-dtm="macro-clear">\u5168\u6D88\u53BB</button>
1249
1260
  <button class="dtm-btn dtm-btn--accent" data-dtm="macro-random">\u30E9\u30F3\u30C0\u30E0\u914D\u7F6E</button>
@@ -1293,6 +1304,17 @@ var buildUI = (target, options) => {
1293
1304
  </div>
1294
1305
  </div>
1295
1306
  </details>
1307
+
1308
+ <!-- \u2550\u2550\u2550\u2550 \u89E3\u8AAC\u30E2\u30FC\u30C0\u30EB \u2550\u2550\u2550\u2550 -->
1309
+ <div class="dtm-modal-overlay" data-dtm="modal-overlay" hidden>
1310
+ <div class="dtm-win dtm-modal">
1311
+ <div class="dtm-modal-header">
1312
+ <span class="dtm-modal-title" data-dtm="modal-title"></span>
1313
+ <button class="dtm-modal-close" data-dtm="modal-close">&times;</button>
1314
+ </div>
1315
+ <div class="dtm-modal-body" data-dtm="modal-body"></div>
1316
+ </div>
1317
+ </div>
1296
1318
  </div>`;
1297
1319
  const root = q(target, '[data-dtm="root"]');
1298
1320
  const sel = (name) => q(root, `[data-dtm="${name}"]`);
@@ -1331,6 +1353,7 @@ var buildUI = (target, options) => {
1331
1353
  drumVolumeLabel: sel("drum-volume-label"),
1332
1354
  midiInput: sel("midi-input"),
1333
1355
  midiLoadBtn: sel("midi-load"),
1356
+ midiInfoBtn: sel("midi-info"),
1334
1357
  midiTrackSelection: sel("midi-track-selection"),
1335
1358
  midiPanel: sel("midi-panel"),
1336
1359
  mmlInput: sel("mml-input"),
@@ -1352,7 +1375,12 @@ var buildUI = (target, options) => {
1352
1375
  outputMini: sel("output-mini"),
1353
1376
  copyFullBtn: sel("copy-full"),
1354
1377
  copyMiniBtn: sel("copy-mini"),
1355
- overlay: sel("overlay")
1378
+ overlay: sel("overlay"),
1379
+ mmlInfoBtn: sel("mml-info"),
1380
+ modalOverlay: sel("modal-overlay"),
1381
+ modalTitle: sel("modal-title"),
1382
+ modalBody: sel("modal-body"),
1383
+ modalClose: sel("modal-close")
1356
1384
  };
1357
1385
  };
1358
1386
 
@@ -2759,7 +2787,7 @@ var analyzeMidiTracks = (midi) => {
2759
2787
  currentTime += event.deltaTime;
2760
2788
  const data = event.data;
2761
2789
  if (event.type === 9 && data && data[1]) {
2762
- notes.push({ pitch: data[0] });
2790
+ notes.push({ pitch: data[0], channel: event.channel ?? 0 });
2763
2791
  } else if (event.type === 8) {
2764
2792
  for (let k = notes.length - 1; k >= 0; k--) {
2765
2793
  if (notes[k].pitch === data[0] && notes[k].end === void 0) {
@@ -2770,11 +2798,13 @@ var analyzeMidiTracks = (midi) => {
2770
2798
  }
2771
2799
  }
2772
2800
  const validNotes = notes.filter((n) => n.end !== void 0);
2801
+ const editableNotes = validNotes.filter((n) => n.channel !== 9);
2802
+ if (validNotes.length > 0 && editableNotes.length === 0) continue;
2773
2803
  result.push({
2774
2804
  index: i,
2775
- name: `Ch${i}`,
2776
- noteCount: validNotes.length,
2777
- selected: validNotes.length > 0
2805
+ name: `Ch${i + 1}`,
2806
+ noteCount: editableNotes.length,
2807
+ selected: editableNotes.length > 0
2778
2808
  });
2779
2809
  }
2780
2810
  return result;
@@ -4755,6 +4785,128 @@ var DAW_CSS = `
4755
4785
  @keyframes dtm-blink { 0%,100%{opacity:1} 50%{opacity:0} }
4756
4786
  .dtm-blink { animation: dtm-blink 1s steps(1) infinite; }
4757
4787
 
4788
+ /* \u2500\u2500\u2500 \u30A4\u30F3\u30D5\u30A9\u30DC\u30BF\u30F3 \u2500\u2500\u2500 */
4789
+ .dtm-infobtn {
4790
+ display: inline-flex;
4791
+ align-items: center;
4792
+ justify-content: center;
4793
+ width: 20px;
4794
+ height: 20px;
4795
+ flex: 0 0 auto;
4796
+ border: 2px solid var(--dtm-border2);
4797
+ background: var(--dtm-surface);
4798
+ color: var(--dtm-muted);
4799
+ cursor: pointer;
4800
+ box-shadow: 1px 1px 0 var(--c-black);
4801
+ padding: 0;
4802
+ margin: 0;
4803
+ }
4804
+ .dtm-infobtn:hover {
4805
+ color: var(--dtm-primary);
4806
+ border-color: var(--dtm-primary);
4807
+ }
4808
+ .dtm-infobtn:active {
4809
+ transform: translate(1px, 1px);
4810
+ box-shadow: none;
4811
+ }
4812
+
4813
+ /* \u2500\u2500\u2500 \u89E3\u8AAC\u30E2\u30FC\u30C0\u30EB \u2500\u2500\u2500 */
4814
+ .dtm-modal-overlay {
4815
+ position: fixed;
4816
+ inset: 0;
4817
+ z-index: 10000;
4818
+ background: rgba(0, 0, 0, 0.7);
4819
+ display: flex;
4820
+ align-items: center;
4821
+ justify-content: center;
4822
+ padding: 16px;
4823
+ backdrop-filter: blur(2px);
4824
+ }
4825
+ .dtm-modal-overlay[hidden] {
4826
+ display: none !important;
4827
+ }
4828
+ .dtm-modal {
4829
+ max-width: 500px;
4830
+ width: 100%;
4831
+ max-height: 80vh;
4832
+ display: flex;
4833
+ flex-direction: column;
4834
+ background: var(--dtm-surface);
4835
+ border: 2px solid var(--c-black);
4836
+ box-shadow:
4837
+ inset 0 0 0 2px var(--c-black),
4838
+ 0 0 0 2px var(--dtm-primary),
4839
+ 4px 4px 0 var(--c-black);
4840
+ overflow: hidden;
4841
+ }
4842
+ .dtm-modal-header {
4843
+ display: flex;
4844
+ align-items: center;
4845
+ justify-content: space-between;
4846
+ background: var(--dtm-deep);
4847
+ padding: 8px 12px;
4848
+ border-bottom: 2px solid var(--c-black);
4849
+ }
4850
+ .dtm-modal-title {
4851
+ font-family: var(--dtm-font);
4852
+ font-size: 14px;
4853
+ color: var(--dtm-gold);
4854
+ font-weight: bold;
4855
+ }
4856
+ .dtm-modal-close {
4857
+ background: transparent;
4858
+ border: none;
4859
+ color: var(--dtm-text);
4860
+ font-size: 20px;
4861
+ cursor: pointer;
4862
+ padding: 0;
4863
+ line-height: 1;
4864
+ }
4865
+ .dtm-modal-close:hover {
4866
+ color: var(--dtm-danger);
4867
+ }
4868
+ .dtm-modal-body {
4869
+ padding: 12px;
4870
+ overflow-y: auto;
4871
+ font-size: 13px;
4872
+ line-height: 1.6;
4873
+ }
4874
+ .dtm-modal-body h4 {
4875
+ margin: 12px 0 6px 0;
4876
+ color: var(--dtm-primary);
4877
+ font-size: 13px;
4878
+ }
4879
+ .dtm-modal-body h4:first-child {
4880
+ margin-top: 0;
4881
+ }
4882
+ .dtm-modal-body p {
4883
+ margin: 0 0 8px 0;
4884
+ }
4885
+ .dtm-modal-body ul {
4886
+ margin: 0 0 8px 0;
4887
+ padding-left: 16px;
4888
+ }
4889
+ .dtm-modal-body li {
4890
+ margin-bottom: 4px;
4891
+ }
4892
+ .dtm-modal-body code {
4893
+ background: var(--dtm-deep);
4894
+ color: var(--dtm-accent);
4895
+ padding: 1px 4px;
4896
+ font-family: var(--dtm-font);
4897
+ font-size: 12px;
4898
+ }
4899
+ .dtm-modal-body pre {
4900
+ background: var(--dtm-deep);
4901
+ color: var(--dtm-success);
4902
+ padding: 8px;
4903
+ border: 1px solid var(--dtm-border2);
4904
+ margin: 6px 0;
4905
+ overflow-x: auto;
4906
+ font-family: var(--dtm-font);
4907
+ font-size: 12px;
4908
+ }
4909
+
4758
4910
  .dtm-hidden { display: none !important; }
4759
4911
  .dtm-grow { flex: 1 1 auto; }
4760
4912
  .dtm-lyric-icon {
@@ -5024,6 +5176,118 @@ var VOICE_IMAGES = {
5024
5176
  };
5025
5177
 
5026
5178
  // src/daw.ts
5179
+ var CHORD_INFO_HTML = `
5180
+ <div class="dtm-modal-body-content">
5181
+ <h4>1. \u57FA\u672C\u306E\u66F8\u304D\u65B9</h4>
5182
+ <p>\u30B3\u30FC\u30C9\u540D\uFF08\u548C\u97F3\u8A18\u53F7\uFF09\u3092\u7E26\u7DDA <code>|</code>\u3001\u30B9\u30DA\u30FC\u30B9\u3001\u307E\u305F\u306F\u30AB\u30F3\u30DE\u3067\u533A\u5207\u3063\u3066\u5165\u529B\u3057\u307E\u3059\u3002\u7E26\u7DDA\u3067\u533A\u5207\u308B\u30681\u5C0F\u7BC0\u3054\u3068\u306E\u914D\u7F6E\u306B\u306A\u308A\u307E\u3059\u3002</p>
5183
+ <pre>\u4F8B: C | G | Am | F</pre>
5184
+ <p style="margin-top:4px;"><small>\u30B3\u30FC\u30C9\u9032\u884C\u3092\u81EA\u5206\u3067\u8003\u3048\u308B\u306E\u304C\u96E3\u3057\u3044\u3068\u304D\u306F\u3001\u30B3\u30FC\u30C9\u9032\u884C\u306E\u5171\u6709\u30B5\u30A4\u30C8\uFF08\u4F8B: <a href="https://rechord.cc/scores" target="_blank" rel="noopener">rechord.cc</a>\uFF09\u304B\u3089\u597D\u304D\u306A\u9032\u884C\u3092\u63A2\u3057\u3066\u30B3\u30D4\u30DA\u3059\u308B\u306E\u3082\u624B\u3067\u3059\u3002\u533A\u5207\u308A\u6587\u5B57\uFF08<code>|</code> / \u30B9\u30DA\u30FC\u30B9 / \u30AB\u30F3\u30DE\uFF09\u3060\u3051\u4E0A\u306E\u5F62\u5F0F\u306B\u5408\u308F\u305B\u308C\u3070\u3001\u305D\u306E\u307E\u307E\u4F7F\u3048\u307E\u3059\u3002</small></p>
5185
+
5186
+ <h4>2. 1\u5C0F\u7BC0\u306B\u8907\u6570\u30B3\u30FC\u30C9\u3092\u5165\u308C\u308B</h4>
5187
+ <p>\u5C0F\u7BC0\u306E\u533A\u5207\u308A\uFF08\u7E26\u7DDA <code>|</code>\uFF09\u306E\u4E2D\u306B\u3001\u30B9\u30DA\u30FC\u30B9\u533A\u5207\u308A\u3067\u30B3\u30FC\u30C9\u3092\u4E26\u3079\u307E\u3059\u3002\u7B49\u9593\u9694\u306B\u914D\u7F6E\u3055\u308C\u307E\u3059\u3002</p>
5188
+ <pre>\u4F8B: C G | Am F</pre>
5189
+ <p style="margin-top:4px;"><small>\uFF081\u5C0F\u7BC0\u76EE\uFF1A\u524D\u534AC\u30FB\u5F8C\u534AG\u30012\u5C0F\u7BC0\u76EE\uFF1A\u524D\u534AAm\u30FB\u5F8C\u534AF\uFF09</small></p>
5190
+
5191
+ <h4>3. \u5BFE\u5FDC\u30B3\u30FC\u30C9\u540D</h4>
5192
+ <ul>
5193
+ <li>\u30E1\u30B8\u30E3\u30FC / \u30DE\u30A4\u30CA\u30FC: <code>C</code>, <code>Dm</code>, <code>Am</code> \u306A\u3069</li>
5194
+ <li>\u30BB\u30D6\u30F3\u30B9: <code>C7</code>, <code>Am7</code>, <code>FM7</code> \u306A\u3069</li>
5195
+ <li>\u305D\u306E\u4ED6: <code>Csus4</code>, <code>Cdim</code>, <code>Caug</code>, <code>Cadd9</code> \u306A\u3069</li>
5196
+ </ul>
5197
+
5198
+ <h4>4. \u6F14\u594F\u30D1\u30BF\u30FC\u30F3</h4>
5199
+ <ul>
5200
+ <li><strong>\u30D6\u30ED\u30C3\u30AF</strong>: \u548C\u97F3\u306E\u69CB\u6210\u97F3\u3092\u3059\u3079\u3066\u540C\u6642\u306B\u4F38\u3070\u3057\u3066\u6F14\u594F\u3057\u307E\u3059\u3002</li>
5201
+ <li><strong>\u30A2\u30EB\u30DA\u30B8\u30AA</strong>: \u548C\u97F3\u306E\u69CB\u6210\u97F3\u3092\u4F4E\u3044\u9806\u306B\u5206\u6563\u3057\u3066\u6F14\u594F\u3057\u307E\u3059\u3002</li>
5202
+ <li><strong>\u30A2\u30EB\u30DA\u30B8\u30AA\uFF08\u30B8\u30E3\u30E9\u30FC\u30F3\uFF09</strong>: \u7D20\u65E9\u304F\u30A2\u30EB\u30DA\u30B8\u30AA\u3092\u9CF4\u3089\u3057\u307E\u3059\u3002</li>
5203
+ <li><strong>\u88CF\u6253\u3061</strong>: \u5404\u62CD\u306E\u88CF\uFF088\u5206\u88CF\uFF09\u306E\u30BF\u30A4\u30DF\u30F3\u30B0\u3067\u30B3\u30FC\u30C9\u3092\u523B\u307F\u307E\u3059\u3002</li>
5204
+ <li><strong>\u30E4\u30C4\u30E1\u7A74</strong>: \u30EA\u30BA\u30DF\u30AB\u30EB\u306A\u30D4\u30B3\u30D4\u30B3\u30B2\u30FC\u30E0\u98A8\u306E\u4F34\u594F\u30D1\u30BF\u30FC\u30F3\u3067\u3059\u3002</li>
5205
+ <li><strong>\u4EA4\u4E92\u594F</strong>: \u30EB\u30FC\u30C8\u97F3\uFF08\u4F4E\u97F3\uFF09\u3068\u30B3\u30FC\u30C9\u69CB\u6210\u97F3\uFF08\u9AD8\u97F3\uFF09\u3092\u4EA4\u4E92\u306B\u523B\u307F\u307E\u3059\u3002</li>
5206
+ </ul>
5207
+ </div>
5208
+ `;
5209
+ var MML_INFO_HTML = `
5210
+ <div class="dtm-modal-body-content">
5211
+ <h4>1. \u97F3\u7B26\u3068\u4F11\u7B26</h4>
5212
+ <p><code>c</code>(\u30C9) <code>d</code>(\u30EC) <code>e</code>(\u30DF) <code>f</code>(\u30D5\u30A1) <code>g</code>(\u30BD) <code>a</code>(\u30E9) <code>b</code>(\u30B7) \u306E\u30A2\u30EB\u30D5\u30A1\u30D9\u30C3\u30C8\u3067\u8868\u3057\u307E\u3059\u3002</p>
5213
+ <ul>
5214
+ <li>\u534A\u97F3\u4E0A\u3052\u308B: <code>c#</code> \u307E\u305F\u306F <code>c+</code></li>
5215
+ <li>\u534A\u97F3\u4E0B\u3052\u308B: <code>d-</code></li>
5216
+ <li>\u4F11\u7B26: <code>r</code></li>
5217
+ </ul>
5218
+
5219
+ <h4>2. \u97F3\u306E\u9577\u3055</h4>
5220
+ <p>\u97F3\u540D\u3084\u4F11\u7B26\u306E\u5F8C\u306B\u6570\u5024\u3067\u6307\u5B9A\u3057\u307E\u3059\uFF08\u4F8B: <code>4</code> = 4\u5206\u97F3\u7B26, <code>8</code> = 8\u5206\u97F3\u7B26, <code>16</code> = 16\u5206\u97F3\u7B26\uFF09\u3002</p>
5221
+ <ul>
5222
+ <li><code>c4</code> : 4\u5206\u97F3\u7B26\u306E\u30C9</li>
5223
+ <li><code>r8</code> : 8\u5206\u4F11\u7B26</li>
5224
+ <li><code>c4.</code> : \u4ED8\u70B94\u5206\u97F3\u7B26\u306E\u30C9\uFF08\u9577\u3055\u30921.5\u500D\u306B\uFF09</li>
5225
+ <li>\u6570\u5024\u3092\u7701\u7565\u3059\u308B\u3068\u3001<code>l</code> \u30B3\u30DE\u30F3\u30C9\u3067\u8A2D\u5B9A\u3055\u308C\u305F\u30C7\u30D5\u30A9\u30EB\u30C8\u9577\uFF08\u901A\u5E3816\u5206\uFF09\u306B\u306A\u308A\u307E\u3059\u3002</li>
5226
+ </ul>
5227
+
5228
+ <h4>3. \u30AA\u30AF\u30BF\u30FC\u30D6\uFF08\u97F3\u306E\u9AD8\u3055\uFF09</h4>
5229
+ <ul>
5230
+ <li><code>o4</code>, <code>o5</code> : \u9AD8\u3055\u3092\u76F4\u63A5\u6307\u5B9A\uFF08\u3075\u3064\u3046\u306F o4 \u304B o5\uFF09</li>
5231
+ <li><code>&gt;</code> : 1\u30AA\u30AF\u30BF\u30FC\u30D6\u4E0A\u3052\u308B</li>
5232
+ <li><code>&lt;</code> : 1\u30AA\u30AF\u30BF\u30FC\u30D6\u4E0B\u3052\u308B</li>
5233
+ </ul>
5234
+
5235
+ <h4>4. \u30C6\u30F3\u30DD</h4>
5236
+ <ul>
5237
+ <li><code>t120</code> : \u66F2\u306E\u901F\u3055\u3092BPM120\u306B\u6307\u5B9A\u3002\u203B\u30E1\u30ED\u30C7\u30A3\uFF08@0\uFF09\u306E\u30C6\u30F3\u30DD\u6307\u5B9A\u304C\u66F2\u5168\u4F53\u306B\u53CD\u6620\u3055\u308C\u307E\u3059\u3002</li>
5238
+ </ul>
5239
+
5240
+ <h4>5. \u548C\u97F3</h4>
5241
+ <p>\u97F3\u7B26\u3092 <code>[</code> \u3068 <code>]</code> \u3067\u56F2\u3080\u3068\u540C\u6642\u306B\u767A\u97F3\u3057\u307E\u3059\u3002</p>
5242
+ <pre>\u4F8B: [ceg]4 \uFF08\u30C9\u30FB\u30DF\u30FB\u30BD\u30924\u5206\u97F3\u7B26\u3067\u540C\u6642\u306B\u767A\u97F3\uFF09</pre>
5243
+
5244
+ <h4>6. \u30C8\u30E9\u30C3\u30AF\u306E\u533A\u5207\u308A</h4>
5245
+ <p><code>;</code> \u307E\u305F\u306F <code>@0</code>\u301C<code>@3</code> \u3067\u30C8\u30E9\u30C3\u30AF\u3092\u5207\u308A\u66FF\u3048\u307E\u3059\u3002</p>
5246
+ <ul>
5247
+ <li><code>@0</code>: \u30E1\u30ED\u30C7\u30A3</li>
5248
+ <li><code>@1</code>: \u30B5\u30D6\u30E1\u30ED</li>
5249
+ <li><code>@2</code>: \u30D9\u30FC\u30B9</li>
5250
+ <li><code>@3</code>: \u4F34\u594F</li>
5251
+ </ul>
5252
+
5253
+ <h4>7. \u6B4C\u58F0\u30FB\u6B4C\u8A5E\u5165\u529B</h4>
5254
+ <p><code>@@&lt;\u30C8\u30E9\u30C3\u30AF\u756A\u53F7&gt; &lt;\u97F3\u6E90\u540D&gt; &lt;\u6B4C\u8A5E&gt;</code> \u306E\u5F62\u5F0F\u3067\u3001\u97F3\u7B26\u3068\u540C\u671F\u3059\u308B\u6B4C\u8A5E\u3092\u5165\u529B\u3067\u304D\u307E\u3059\u3002</p>
5255
+ <pre>\u4F8B: @@0 klatt \u3061\u3087\u3046\u3061\u3087\u3046\u306A\u306E\u306F\u306B\u3068\u307E\u308C</pre>
5256
+ <p style="margin-top:4px;"><small>\uFF08\u97F3\u6E90\u540D\u306F <code>klatt</code> \u3084 <code>roze</code>, <code>teto</code> \u306A\u3069\u306E\u97F3\u58F0\u30E2\u30C7\u30EB\u3092\u6307\u5B9A\u3067\u304D\u307E\u3059\uFF09</small></p>
5257
+ </div>
5258
+ `;
5259
+ var MIDI_INFO_HTML = `
5260
+ <div class="dtm-modal-body-content">
5261
+ <h4>1. MIDI\u30D5\u30A1\u30A4\u30EB\u3068\u306F</h4>
5262
+ <p>\u300C\u3069\u306E\u97F3\u3092\u30FB\u3044\u3064\u30FB\u3069\u306E\u304F\u3089\u3044\u306E\u9577\u3055\u3067\u9CF4\u3089\u3059\u304B\u300D\u3092\u8A18\u9332\u3057\u305F\u3001\u6F14\u594F\u30C7\u30FC\u30BF\u306E\u30D5\u30A1\u30A4\u30EB\uFF08\u62E1\u5F35\u5B50 <code>.mid</code> / <code>.midi</code>\uFF09\u3067\u3059\u3002\u97F3\u305D\u306E\u3082\u306E\u3067\u306F\u306A\u304F\u697D\u8B5C\u306B\u8FD1\u3044\u30C7\u30FC\u30BF\u306A\u306E\u3067\u3001\u8AAD\u307F\u8FBC\u3093\u3067\u305D\u306E\u307E\u307E\u7DE8\u96C6\u3067\u304D\u307E\u3059\u3002</p>
5263
+
5264
+ <h4>2. \u8AAD\u307F\u8FBC\u307F\u306E\u3057\u304B\u305F</h4>
5265
+ <ul>
5266
+ <li>\u300C\u30D5\u30A1\u30A4\u30EB\u3092\u9078\u629E\u300D\u304B\u3089 <code>.mid</code> \u30D5\u30A1\u30A4\u30EB\u3092\u9078\u3073\u307E\u3059\u3002</li>
5267
+ <li>\u30D5\u30A1\u30A4\u30EB\u5185\u306E\u30C8\u30E9\u30C3\u30AF\u4E00\u89A7\u304C\u51FA\u308B\u306E\u3067\u3001\u53D6\u308A\u8FBC\u307F\u305F\u3044\u30C8\u30E9\u30C3\u30AF\u3092\u9078\u3073\u307E\u3059\u3002</li>
5268
+ <li>\u300C\u8AAD\u8FBC\u300D\u3092\u62BC\u3059\u3068\u53CD\u6620\u3055\u308C\u307E\u3059\u3002</li>
5269
+ </ul>
5270
+
5271
+ <h4>3. \u30E2\u30FC\u30C9\u306B\u3088\u308B\u53D6\u308A\u8FBC\u307F\u65B9\u306E\u9055\u3044</h4>
5272
+ <ul>
5273
+ <li><strong>SIMPLE</strong>: \u5404\u30C8\u30E9\u30C3\u30AF\u306E\u7279\u5FB4\u304B\u3089\u3001\u30E1\u30ED\u30C7\u30A3\u30FC\u30FB\u30B5\u30D6\u30E1\u30ED\u30FB\u30D9\u30FC\u30B9\u30FB\u4F34\u594F\u306E4\u3064\u306E\u5F79\u5272\u306B\u81EA\u52D5\u3067\u632F\u308A\u5206\u3051\u3089\u308C\u307E\u3059\u3002</li>
5274
+ <li><strong>ADVANCED</strong>: MIDI\u306E\u30C8\u30E9\u30C3\u30AF\u69CB\u6210\u304C\u305D\u306E\u307E\u307E\u53CD\u6620\u3055\u308C\u307E\u3059\uFF081\u5BFE1\uFF09\u3002</li>
5275
+ </ul>
5276
+
5277
+ <h4>4. MIDI\u30D5\u30A1\u30A4\u30EB\u3092\u624B\u306B\u5165\u308C\u308B</h4>
5278
+ <p>\u624B\u5143\u306BMIDI\u304C\u7121\u3044\u3068\u304D\u306F\u3001\u300C<code>\u66F2\u540D midi</code>\u300D\u306A\u3069\u3067\u691C\u7D22\u3059\u308C\u3070\u3001\u7121\u6599\u3067\u914D\u5E03\u3057\u3066\u3044\u308B\u30B5\u30A4\u30C8\u304C\u898B\u3064\u304B\u308A\u307E\u3059\u3002</p>
5279
+ <p style="margin-top:4px;"><small>\u307F\u3093\u306A\u304CMIDI\u3092\u6295\u7A3F\u3067\u304D\u308B\u6295\u7A3F\u578B\u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0: <a href="http://picotune.me/" target="_blank" rel="noopener">picotune.me</a>\uFF08\u3044\u308D\u3093\u306A\u30B8\u30E3\u30F3\u30EB\u306EMIDI\u3092\u7121\u6599\u30C0\u30A6\u30F3\u30ED\u30FC\u30C9\u3067\u304D\u307E\u3059\u3002\u30B5\u30A4\u30C8\u4E0A\u3067\u306F\u30C1\u30C3\u30D7\u30C1\u30E5\u30FC\u30F3\u98A8\u306B\u518D\u751F\u3055\u308C\u307E\u3059\uFF09</small></p>
5280
+ <p style="margin-top:4px;"><small>\u203B\u691C\u7D22\u3067\u898B\u3064\u304B\u308B\u914D\u5E03\u30B5\u30A4\u30C8\u306F\u3001\u500B\u4EBA\u904B\u55B6\u306E\u3082\u306E\u304B\u3089\u6A29\u5229\u7684\u306B\u30B0\u30EC\u30FC\u306A\u3082\u306E\u307E\u3067\u69D8\u3005\u3067\u3059\u3002\u305D\u306E\u305F\u3081\u3001\u305D\u308C\u3089\u3078\u306E\u76F4\u63A5\u30EA\u30F3\u30AF\u306F\u8F09\u305B\u3066\u3044\u307E\u305B\u3093\u3002\u5229\u7528\u306E\u969B\u306F\u914D\u5E03\u5143\u3084\u6A29\u5229\u95A2\u4FC2\u3092\u3054\u81EA\u8EAB\u3067\u3054\u78BA\u8A8D\u304F\u3060\u3055\u3044\u3002</small></p>
5281
+
5282
+ <h4>5. UST\uFF08UTAU\uFF09\u306E\u6B4C\u8A5E\u3092\u4F7F\u3046</h4>
5283
+ <p>UTAU\u306EUST\u30D5\u30A1\u30A4\u30EB\u304B\u3089\u6B4C\u8A5E\u3060\u3051\u3092\u53D6\u308A\u51FA\u3057\u3066\u3001\u6B4C\u308F\u305B\u308B\u3053\u3068\u3082\u3067\u304D\u307E\u3059\u3002</p>
5284
+ <ul>
5285
+ <li>\u97F3\u7B26: UTAU\u306A\u3069\u3067UST\u3092MIDI\u306B\u66F8\u304D\u51FA\u3057\u3001\u4E0A\u306E\u624B\u9806\u3067\u8AAD\u307F\u8FBC\u307F\u307E\u3059\u3002</li>
5286
+ <li>\u6B4C\u8A5E: \u4E0B\u8A18\u30B5\u30A4\u30C8\u3067UST\u304B\u3089\u6B4C\u8A5E\u30C6\u30AD\u30B9\u30C8\u3092\u629C\u304D\u51FA\u3057\u3001MML/\u6B4C\u8A5E\u5165\u529B\u6B04\u306E <code>@@</code> \u69CB\u6587\u306B\u8CBC\u308A\u4ED8\u3051\u307E\u3059\u3002</li>
5287
+ </ul>
5288
+ <p style="margin-top:4px;"><small>\u6B4C\u8A5E\u306E\u62BD\u51FA: <a href="https://rpgen3.github.io/ust2txt/" target="_blank" rel="noopener">ust2txt</a></small></p>
5289
+ </div>
5290
+ `;
5027
5291
  var BASE_STEP_WIDTH = 0.5;
5028
5292
  var BASE_KEY_HEIGHT = 15;
5029
5293
  var TRACKS_SIMPLE = [
@@ -5182,9 +5446,11 @@ var mountDAW = (target, options = {}) => {
5182
5446
  injectStyles();
5183
5447
  const getAudioTime = options.getAudioTime ?? (() => performance.now() / 1e3);
5184
5448
  const trackConfigs = options.tracks ?? DEFAULT_TRACKS;
5449
+ const mode = options.mode ?? (trackConfigs.length > TRACKS_SIMPLE.length ? "advanced" : "simple");
5450
+ const isAdvanced = mode === "advanced";
5185
5451
  const drumPatterns = options.drumPatterns ?? DRUM_PATTERNS;
5186
5452
  const showMidi = !!options.parseMidi;
5187
- const showChord = true;
5453
+ const showChord = !isAdvanced;
5188
5454
  const refs = buildUI(target, {
5189
5455
  tracks: trackConfigs,
5190
5456
  drumPatternNames: Object.keys(drumPatterns),
@@ -5276,6 +5542,7 @@ var mountDAW = (target, options = {}) => {
5276
5542
  return map;
5277
5543
  };
5278
5544
  const getActive = () => trackStates.find((t) => t.config.id === activeTrackId) ?? trackStates[0];
5545
+ let showModal;
5279
5546
  const getMaxNoteStep = () => {
5280
5547
  let maxStep = renderConfig.stepsPerBar * 4;
5281
5548
  for (const t of trackStates) {
@@ -5968,11 +6235,12 @@ var mountDAW = (target, options = {}) => {
5968
6235
  active.core.setVolume(active.volume);
5969
6236
  volLabel.textContent = String(active.volume);
5970
6237
  });
5971
- const lyricDiv = document.createElement("div");
5972
- lyricDiv.className = "dtm-row";
5973
- lyricDiv.style.flexDirection = "column";
5974
- lyricDiv.style.alignItems = "stretch";
5975
- lyricDiv.innerHTML = `
6238
+ if (isAdvanced || active.config.id !== "chord") {
6239
+ const lyricDiv = document.createElement("div");
6240
+ lyricDiv.className = "dtm-row";
6241
+ lyricDiv.style.flexDirection = "column";
6242
+ lyricDiv.style.alignItems = "stretch";
6243
+ lyricDiv.innerHTML = `
5976
6244
  <div class="dtm-row">
5977
6245
  <span class="dtm-label">\u266A \u6B4C\u8A5E</span>
5978
6246
  <select class="dtm-select" data-dtm="lyric-model" aria-label="\u6B4C\u5531\u30E2\u30C7\u30EB"></select>
@@ -6004,144 +6272,134 @@ var mountDAW = (target, options = {}) => {
6004
6272
  </div>
6005
6273
  <textarea class="dtm-textarea" data-dtm="lyric-input" rows="2" placeholder="\u3072\u3089\u304C\u306A\u30FB\u30AB\u30BF\u30AB\u30CA\u3067\u6B4C\u8A5E\uFF08\u4F8B: \u3069\u308C\u307F\u3075\u3041\u305D\u3089\u3057\u3069\uFF09"></textarea>
6006
6274
  </div>`;
6007
- refs.trackBody.appendChild(lyricDiv);
6008
- const lyricModelSel = lyricDiv.querySelector(
6009
- '[data-dtm="lyric-model"]'
6010
- );
6011
- const lyricOctaveSel = lyricDiv.querySelector(
6012
- '[data-dtm="lyric-octave"]'
6013
- );
6014
- const lyricIcon = lyricDiv.querySelector(
6015
- '[data-dtm="lyric-icon"]'
6016
- );
6017
- const lyricBody = lyricDiv.querySelector(
6018
- '[data-dtm="lyric-body"]'
6019
- );
6020
- const lyricInput = lyricDiv.querySelector(
6021
- '[data-dtm="lyric-input"]'
6022
- );
6023
- const lyricCount = lyricDiv.querySelector(
6024
- '[data-dtm="lyric-count"]'
6025
- );
6026
- const lyricVol = lyricDiv.querySelector(
6027
- '[data-dtm="lyric-vol"]'
6028
- );
6029
- const lyricVolLabel = lyricDiv.querySelector(
6030
- '[data-dtm="lyric-vol-label"]'
6031
- );
6032
- const lyricPan = lyricDiv.querySelector(
6033
- '[data-dtm="lyric-pan"]'
6034
- );
6035
- const lyricPanLabel = lyricDiv.querySelector(
6036
- '[data-dtm="lyric-pan-label"]'
6037
- );
6038
- const lyricTerms = lyricDiv.querySelector(
6039
- '[data-dtm="lyric-terms"]'
6040
- );
6041
- const lyricTermsLink = lyricDiv.querySelector(
6042
- '[data-dtm="lyric-terms-link"]'
6043
- );
6044
- const fmtPan = (pan) => pan === 64 ? "C" : pan < 64 ? `L${64 - pan}` : `R${pan - 64}`;
6045
- const addOpt = (value, label) => {
6046
- const o = document.createElement("option");
6047
- o.value = value;
6048
- o.textContent = label;
6049
- lyricModelSel.appendChild(o);
6050
- };
6051
- addOpt("", "\u306A\u3057");
6052
- for (const m of LYRIC_MODELS) addOpt(m, lyricModelLabel(m));
6053
- if (active.lyricModel && !LYRIC_MODELS.includes(active.lyricModel)) {
6054
- addOpt(active.lyricModel, lyricModelLabel(active.lyricModel));
6055
- }
6056
- lyricModelSel.value = active.lyricModel;
6057
- lyricOctaveSel.value = String(active.vocalOctave);
6058
- lyricInput.value = active.lyrics;
6059
- lyricVol.value = String(active.vocalVolume);
6060
- lyricVolLabel.textContent = String(active.vocalVolume);
6061
- lyricPan.value = String(active.vocalPan);
6062
- lyricPanLabel.textContent = fmtPan(active.vocalPan);
6063
- const updateLyricCount = () => {
6064
- const n = normalizeLyrics(lyricInput.value).length;
6065
- lyricCount.textContent = active.lyricModel && n > 0 ? `${n}\u97F3\u7BC0` : "";
6066
- };
6067
- const syncLyricTerms = () => {
6068
- const url = active.lyricModel ? KOE_VOICEBANK_TERMS[active.lyricModel] : void 0;
6069
- if (url) {
6070
- const label = lyricModelLabel(active.lyricModel);
6071
- lyricTermsLink.textContent = `${label}UTAU\u97F3\u6E90`;
6072
- lyricTermsLink.href = url;
6073
- lyricTerms.classList.remove("dtm-hidden");
6074
- } else {
6075
- lyricTerms.classList.add("dtm-hidden");
6076
- }
6077
- };
6078
- const syncLyricIcon = () => {
6079
- const imgKey = active.lyricModel ? VOICE_IMAGE_KEY[active.lyricModel.toLowerCase()] : void 0;
6080
- const src = imgKey ? VOICE_IMAGES[imgKey] : void 0;
6081
- if (src) {
6082
- lyricIcon.src = src;
6083
- lyricIcon.classList.remove("dtm-hidden");
6084
- } else {
6085
- lyricIcon.removeAttribute("src");
6086
- lyricIcon.classList.add("dtm-hidden");
6275
+ refs.trackBody.appendChild(lyricDiv);
6276
+ const lyricModelSel = lyricDiv.querySelector(
6277
+ '[data-dtm="lyric-model"]'
6278
+ );
6279
+ const lyricOctaveSel = lyricDiv.querySelector(
6280
+ '[data-dtm="lyric-octave"]'
6281
+ );
6282
+ const lyricIcon = lyricDiv.querySelector(
6283
+ '[data-dtm="lyric-icon"]'
6284
+ );
6285
+ const lyricBody = lyricDiv.querySelector(
6286
+ '[data-dtm="lyric-body"]'
6287
+ );
6288
+ const lyricInput = lyricDiv.querySelector(
6289
+ '[data-dtm="lyric-input"]'
6290
+ );
6291
+ const lyricCount = lyricDiv.querySelector(
6292
+ '[data-dtm="lyric-count"]'
6293
+ );
6294
+ const lyricVol = lyricDiv.querySelector(
6295
+ '[data-dtm="lyric-vol"]'
6296
+ );
6297
+ const lyricVolLabel = lyricDiv.querySelector(
6298
+ '[data-dtm="lyric-vol-label"]'
6299
+ );
6300
+ const lyricPan = lyricDiv.querySelector(
6301
+ '[data-dtm="lyric-pan"]'
6302
+ );
6303
+ const lyricPanLabel = lyricDiv.querySelector(
6304
+ '[data-dtm="lyric-pan-label"]'
6305
+ );
6306
+ const lyricTerms = lyricDiv.querySelector(
6307
+ '[data-dtm="lyric-terms"]'
6308
+ );
6309
+ const lyricTermsLink = lyricDiv.querySelector(
6310
+ '[data-dtm="lyric-terms-link"]'
6311
+ );
6312
+ const fmtPan = (pan) => pan === 64 ? "C" : pan < 64 ? `L${64 - pan}` : `R${pan - 64}`;
6313
+ const addOpt = (value, label) => {
6314
+ const o = document.createElement("option");
6315
+ o.value = value;
6316
+ o.textContent = label;
6317
+ lyricModelSel.appendChild(o);
6318
+ };
6319
+ addOpt("", "\u306A\u3057");
6320
+ for (const m of LYRIC_MODELS) addOpt(m, lyricModelLabel(m));
6321
+ if (active.lyricModel && !LYRIC_MODELS.includes(active.lyricModel)) {
6322
+ addOpt(active.lyricModel, lyricModelLabel(active.lyricModel));
6087
6323
  }
6088
- };
6089
- const syncLyricVisibility = () => {
6090
- lyricBody.style.display = active.lyricModel ? "" : "none";
6091
- lyricOctaveSel.style.display = active.lyricModel ? "" : "none";
6092
- updateLyricCount();
6093
- syncLyricTerms();
6094
- syncLyricIcon();
6095
- };
6096
- syncLyricVisibility();
6097
- lyricModelSel.addEventListener("change", () => {
6098
- active.lyricModel = lyricModelSel.value;
6099
- syncLyricVisibility();
6100
- });
6101
- lyricOctaveSel.addEventListener("change", () => {
6102
- active.vocalOctave = Number.parseInt(lyricOctaveSel.value, 10);
6103
- });
6104
- lyricInput.addEventListener("input", () => {
6105
- active.lyrics = lyricInput.value;
6106
- updateLyricCount();
6107
- });
6108
- lyricVol.addEventListener("input", () => {
6109
- active.vocalVolume = Number.parseInt(lyricVol.value, 10);
6110
- lyricVolLabel.textContent = lyricVol.value;
6111
- });
6112
- lyricPan.addEventListener("input", () => {
6113
- active.vocalPan = Number.parseInt(lyricPan.value, 10);
6324
+ lyricModelSel.value = active.lyricModel;
6325
+ lyricOctaveSel.value = String(active.vocalOctave);
6326
+ lyricInput.value = active.lyrics;
6327
+ lyricVol.value = String(active.vocalVolume);
6328
+ lyricVolLabel.textContent = String(active.vocalVolume);
6329
+ lyricPan.value = String(active.vocalPan);
6114
6330
  lyricPanLabel.textContent = fmtPan(active.vocalPan);
6115
- });
6116
- lyricPanLabel.style.cursor = "pointer";
6117
- lyricPanLabel.title = "\u30BF\u30C3\u30D7\u3067\u4E2D\u592E(C)\u3078";
6118
- lyricPanLabel.addEventListener("click", () => {
6119
- active.vocalPan = 64;
6120
- lyricPan.value = "64";
6121
- lyricPanLabel.textContent = fmtPan(64);
6122
- });
6331
+ const updateLyricCount = () => {
6332
+ const n = normalizeLyrics(lyricInput.value).length;
6333
+ lyricCount.textContent = active.lyricModel && n > 0 ? `${n}\u97F3\u7BC0` : "";
6334
+ };
6335
+ const syncLyricTerms = () => {
6336
+ const url = active.lyricModel ? KOE_VOICEBANK_TERMS[active.lyricModel] : void 0;
6337
+ if (url) {
6338
+ const label = lyricModelLabel(active.lyricModel);
6339
+ lyricTermsLink.textContent = `${label}UTAU\u97F3\u6E90`;
6340
+ lyricTermsLink.href = url;
6341
+ lyricTerms.classList.remove("dtm-hidden");
6342
+ } else {
6343
+ lyricTerms.classList.add("dtm-hidden");
6344
+ }
6345
+ };
6346
+ const syncLyricIcon = () => {
6347
+ const imgKey = active.lyricModel ? VOICE_IMAGE_KEY[active.lyricModel.toLowerCase()] : void 0;
6348
+ const src = imgKey ? VOICE_IMAGES[imgKey] : void 0;
6349
+ if (src) {
6350
+ lyricIcon.src = src;
6351
+ lyricIcon.classList.remove("dtm-hidden");
6352
+ } else {
6353
+ lyricIcon.removeAttribute("src");
6354
+ lyricIcon.classList.add("dtm-hidden");
6355
+ }
6356
+ };
6357
+ const syncLyricVisibility = () => {
6358
+ lyricBody.style.display = active.lyricModel ? "" : "none";
6359
+ lyricOctaveSel.style.display = active.lyricModel ? "" : "none";
6360
+ updateLyricCount();
6361
+ syncLyricTerms();
6362
+ syncLyricIcon();
6363
+ };
6364
+ syncLyricVisibility();
6365
+ lyricModelSel.addEventListener("change", () => {
6366
+ active.lyricModel = lyricModelSel.value;
6367
+ syncLyricVisibility();
6368
+ });
6369
+ lyricOctaveSel.addEventListener("change", () => {
6370
+ active.vocalOctave = Number.parseInt(lyricOctaveSel.value, 10);
6371
+ });
6372
+ lyricInput.addEventListener("input", () => {
6373
+ active.lyrics = lyricInput.value;
6374
+ updateLyricCount();
6375
+ });
6376
+ lyricVol.addEventListener("input", () => {
6377
+ active.vocalVolume = Number.parseInt(lyricVol.value, 10);
6378
+ lyricVolLabel.textContent = lyricVol.value;
6379
+ });
6380
+ lyricPan.addEventListener("input", () => {
6381
+ active.vocalPan = Number.parseInt(lyricPan.value, 10);
6382
+ lyricPanLabel.textContent = fmtPan(active.vocalPan);
6383
+ });
6384
+ lyricPanLabel.style.cursor = "pointer";
6385
+ lyricPanLabel.title = "\u30BF\u30C3\u30D7\u3067\u4E2D\u592E(C)\u3078";
6386
+ lyricPanLabel.addEventListener("click", () => {
6387
+ active.vocalPan = 64;
6388
+ lyricPan.value = "64";
6389
+ lyricPanLabel.textContent = fmtPan(64);
6390
+ });
6391
+ }
6123
6392
  if (active.config.id === "chord" && showChord) {
6124
6393
  const div = document.createElement("div");
6125
6394
  div.className = "dtm-row";
6126
6395
  div.style.flexDirection = "column";
6127
6396
  div.style.alignItems = "stretch";
6128
- const roots = [
6129
- "C",
6130
- "C#",
6131
- "D",
6132
- "D#",
6133
- "E",
6134
- "F",
6135
- "F#",
6136
- "G",
6137
- "G#",
6138
- "A",
6139
- "A#",
6140
- "B"
6141
- ];
6142
6397
  div.innerHTML = `
6143
- <div class="dtm-row">
6144
- <span class="dtm-label">\u548C\u97F3</span>
6398
+ <div class="dtm-row" style="justify-content: space-between; align-items: center;">
6399
+ <div style="display: inline-flex; align-items: center; gap: 6px;">
6400
+ <span class="dtm-label">\u548C\u97F3</span>
6401
+ <button class="dtm-infobtn" data-dtm="chord-info" title="\u30B3\u30FC\u30C9\u9032\u884C\u306E\u66F8\u304D\u65B9\u89E3\u8AAC">${icon("info", 12)}</button>
6402
+ </div>
6145
6403
  <select class="dtm-select" data-dtm="chord-pattern">
6146
6404
  <option value="block">\u30D6\u30ED\u30C3\u30AF</option>
6147
6405
  <option value="arpeggio">\u30A2\u30EB\u30DA\u30B8\u30AA</option>
@@ -6150,32 +6408,28 @@ var mountDAW = (target, options = {}) => {
6150
6408
  <option value="yatsume">\u30E4\u30C4\u30E1\u7A74</option>
6151
6409
  <option value="alternating">\u4EA4\u4E92\u594F</option>
6152
6410
  </select>
6153
- <select class="dtm-select" data-dtm="chord-root">
6154
- ${roots.map((r, i) => `<option value="${i}">${r}</option>`).join("")}
6155
- </select>
6156
- <button class="dtm-btn dtm-btn--primary" data-dtm="chord-apply">\u9069\u7528</button>
6157
6411
  </div>
6158
- <textarea class="dtm-textarea" data-dtm="chord-input" placeholder="\u4F8B: C|G|Am|Em|F|C|F|G">${active.savedChordInput}</textarea>`;
6412
+ <div class="dtm-row">
6413
+ <textarea class="dtm-textarea dtm-grow" data-dtm="chord-input" placeholder="\u4F8B: C|G|Am|Em|F|C|F|G">${active.savedChordInput}</textarea>
6414
+ <button class="dtm-btn dtm-btn--primary" data-dtm="chord-apply">\u9069\u7528</button>
6415
+ </div>`;
6159
6416
  refs.trackBody.appendChild(div);
6160
6417
  const patternSel = div.querySelector(
6161
6418
  '[data-dtm="chord-pattern"]'
6162
6419
  );
6163
- const rootSel = div.querySelector(
6164
- '[data-dtm="chord-root"]'
6165
- );
6166
6420
  const input = div.querySelector(
6167
6421
  '[data-dtm="chord-input"]'
6168
6422
  );
6169
6423
  patternSel.value = active.savedChordPattern;
6170
- rootSel.value = String(active.savedChordRoot);
6171
6424
  const save = () => {
6172
6425
  active.savedChordInput = input.value;
6173
6426
  active.savedChordPattern = patternSel.value;
6174
- active.savedChordRoot = Number.parseInt(rootSel.value, 10);
6175
6427
  };
6176
6428
  patternSel.addEventListener("change", save);
6177
- rootSel.addEventListener("change", save);
6178
6429
  input.addEventListener("input", save);
6430
+ div.querySelector('[data-dtm="chord-info"]').addEventListener("click", () => {
6431
+ showModal("\u30B3\u30FC\u30C9\u9032\u884C\u306E\u81EA\u52D5\u5165\u529B\u89E3\u8AAC", CHORD_INFO_HTML);
6432
+ });
6179
6433
  div.querySelector('[data-dtm="chord-apply"]').addEventListener("click", () => {
6180
6434
  save();
6181
6435
  applyChord();
@@ -6188,16 +6442,16 @@ var mountDAW = (target, options = {}) => {
6188
6442
  updateUndoRedo();
6189
6443
  redrawAll();
6190
6444
  };
6191
- const setToolMode = (mode) => {
6192
- activeToolMode = mode;
6445
+ const setToolMode = (mode2) => {
6446
+ activeToolMode = mode2;
6193
6447
  for (const [btn, m] of [
6194
6448
  [refs.toolPen, "pen"],
6195
6449
  [refs.toolSelect, "select"],
6196
6450
  [refs.toolEraser, "eraser"]
6197
6451
  ]) {
6198
- btn.classList.toggle("dtm-segbtn--active", m === mode);
6452
+ btn.classList.toggle("dtm-segbtn--active", m === mode2);
6199
6453
  }
6200
- if (mode !== "select") {
6454
+ if (mode2 !== "select") {
6201
6455
  selectionRect = null;
6202
6456
  selectedNotes = [];
6203
6457
  }
@@ -6431,7 +6685,6 @@ var mountDAW = (target, options = {}) => {
6431
6685
  const applyMidiSelection = (midi, selectedIndices) => {
6432
6686
  clearAll();
6433
6687
  for (const t of trackStates) t.core.setLoadMode(true);
6434
- const isAdvanced = trackStates.length > TRACKS_SIMPLE.length;
6435
6688
  const { placements, bpm: parsedBpm } = isAdvanced ? extractMidiPlacementsByTrack(
6436
6689
  midi,
6437
6690
  selectedIndices,
@@ -6613,6 +6866,25 @@ var mountDAW = (target, options = {}) => {
6613
6866
  "click",
6614
6867
  () => overlayDuring(() => loadMML(refs.mmlInput.value))
6615
6868
  );
6869
+ showModal = (title, bodyHTML) => {
6870
+ refs.modalTitle.textContent = title;
6871
+ refs.modalBody.innerHTML = bodyHTML;
6872
+ refs.modalOverlay.removeAttribute("hidden");
6873
+ };
6874
+ refs.modalClose.addEventListener("click", () => {
6875
+ refs.modalOverlay.setAttribute("hidden", "");
6876
+ });
6877
+ refs.modalOverlay.addEventListener("click", (e) => {
6878
+ if (e.target === refs.modalOverlay) {
6879
+ refs.modalOverlay.setAttribute("hidden", "");
6880
+ }
6881
+ });
6882
+ refs.mmlInfoBtn.addEventListener("click", () => {
6883
+ showModal("MML\u306E\u66F8\u304D\u65B9\u89E3\u8AAC", MML_INFO_HTML);
6884
+ });
6885
+ refs.midiInfoBtn.addEventListener("click", () => {
6886
+ showModal("MIDI\u306E\u8AAD\u307F\u8FBC\u307F\u89E3\u8AAC", MIDI_INFO_HTML);
6887
+ });
6616
6888
  refs.shiftApplyBtn.addEventListener(
6617
6889
  "click",
6618
6890
  () => overlayDuring(() => {