danoniplus 46.5.2 → 46.6.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/js/danoni_main.js CHANGED
@@ -4,12 +4,12 @@
4
4
  *
5
5
  * Source by tickle
6
6
  * Created : 2018/10/08
7
- * Revised : 2026/03/31
7
+ * Revised : 2026/04/07
8
8
  *
9
9
  * https://github.com/cwtickle/danoniplus
10
10
  */
11
- const g_version = `Ver 46.5.2`;
12
- const g_revisedDate = `2026/03/31`;
11
+ const g_version = `Ver 46.6.0`;
12
+ const g_revisedDate = `2026/04/07`;
13
13
 
14
14
  // カスタム用バージョン (danoni_custom.js 等で指定可)
15
15
  let g_localVersion = ``;
@@ -1213,7 +1213,7 @@ const safeExecuteCustomHooks = (_hookName, _funcArray, ...args) => {
1213
1213
  }
1214
1214
  }
1215
1215
  }
1216
- }
1216
+ };
1217
1217
 
1218
1218
  /**
1219
1219
  * 与えられたパスより、キーワードとディレクトリに分割
@@ -1233,7 +1233,7 @@ const getFilePath = (_fileName, _directory = ``) => {
1233
1233
  }
1234
1234
  const dirPos = fullPath.lastIndexOf(`/`);
1235
1235
  return [fullPath.slice(dirPos + 1), fullPath.slice(0, dirPos + 1)];
1236
- }
1236
+ };
1237
1237
 
1238
1238
  /**
1239
1239
  * 画像ファイルの存在チェック後、プリロードする処理
@@ -1445,6 +1445,32 @@ const getStrWidth = (_str, _fontsize, _font) => {
1445
1445
  return g_ctx.measureText(unEscapeHtml(_str)).width;
1446
1446
  };
1447
1447
 
1448
+ const getStrHeight = (_str, _fontsize, _font = getBasicFont()) => {
1449
+ g_ctx.font = `${wUnit(_fontsize)} ${_font}`;
1450
+ const lines = unEscapeHtml(_str).split(`<br>`);
1451
+
1452
+ let totalHeight = 0;
1453
+ const lineGap = 1;
1454
+
1455
+ lines.forEach((line, index) => {
1456
+ const metrics = g_ctx.measureText(line);
1457
+
1458
+ // 基本の高さ(フォントサイズ)を取得
1459
+ // fontBoundingBox が使えれば正確ですが、なければ _fontsize を使用
1460
+ const h = metrics.fontBoundingBoxAscent
1461
+ ? (metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent)
1462
+ : _fontsize;
1463
+
1464
+ if (index < lines.length - 1) {
1465
+ totalHeight += h * lineGap; // 途中の行は行間を足す
1466
+ } else {
1467
+ totalHeight += h; // 最終行
1468
+ }
1469
+ });
1470
+
1471
+ return totalHeight;
1472
+ };
1473
+
1448
1474
  /**
1449
1475
  * Canvas上で使用する絵文字を取得
1450
1476
  * - HTMLのdiv要素に絵文字を設定することで、Canvas上で使用できるようにする
@@ -1457,7 +1483,7 @@ const getEmojiForCanvas = _str => {
1457
1483
  const result = div.innerHTML;
1458
1484
  div.remove();
1459
1485
  return result;
1460
- }
1486
+ };
1461
1487
 
1462
1488
  /**
1463
1489
  * 指定した横幅に合ったフォントサイズを取得
@@ -1489,7 +1515,7 @@ const getLongestStr = _array => {
1489
1515
  return _array.reduce((longest, current) => {
1490
1516
  return current.length > longest.length ? current : longest;
1491
1517
  }, ``);
1492
- }
1518
+ };
1493
1519
 
1494
1520
  /**
1495
1521
  * 補足説明部分のラベル作成
@@ -2098,7 +2124,7 @@ const getCssCustomProperties = () => {
2098
2124
  // 上記でもNGの場合は何もしない
2099
2125
  }
2100
2126
  }
2101
- }
2127
+ };
2102
2128
 
2103
2129
  /**
2104
2130
  * 背景・マスク用画像の描画
@@ -3221,7 +3247,7 @@ const getFullMusicUrl = (_musicUrl = ``) => {
3221
3247
  }
3222
3248
  const [musicFile, musicPath] = getFilePath(baseMusicUrl, baseDir);
3223
3249
  return `${musicPath}${musicFile}`;
3224
- }
3250
+ };
3225
3251
 
3226
3252
  /**
3227
3253
  * 譜面ファイル読込後処理(譜面詳細情報取得用)
@@ -3731,9 +3757,20 @@ const headerConvert = _dosObj => {
3731
3757
  obj.musicTitlesForView[0] = escapeHtmlForArray(getMusicNameMultiLine(alternativeTitle));
3732
3758
  }
3733
3759
 
3734
- // 選曲機能の利用有無
3735
- obj.packageNames = (_dosObj.packageName || ``).split(`<br>`);
3760
+ // 選曲機能の利用有無(最後のカンマ後の文字をBGM利用フラグとして利用)
3761
+ const rawPackageName = _dosObj.packageName || ``;
3762
+ const packageNameParts = rawPackageName.split(`,`);
3763
+ const bgmUseSwitch = setVal(trimStr(packageNameParts.at(-1)), ``, C_TYP_SWITCH);
3764
+ const packageName = bgmUseSwitch === ``
3765
+ ? rawPackageName
3766
+ : packageNameParts.slice(0, -1).join(`,`);
3767
+ obj.packageNames = (packageName || ``).split(`<br>`);
3736
3768
  obj.musicSelectUse = _dosObj.packageName !== undefined;
3769
+ obj.bgmUseFlg = bgmUseSwitch === C_FLG_ON;
3770
+
3771
+ if (!obj.bgmUseFlg) {
3772
+ g_stateObj.bgmMuteFlg = true;
3773
+ }
3737
3774
 
3738
3775
  // 最小・最大速度の設定
3739
3776
  obj.minSpeed = Math.round(setVal(_dosObj.minSpeed, C_MIN_SPEED, C_TYP_FLOAT) * 4) / 4;
@@ -3806,6 +3843,7 @@ const headerConvert = _dosObj => {
3806
3843
  obj.lifeDamages = [];
3807
3844
  obj.lifeInits = [];
3808
3845
  obj.creatorNames = [];
3846
+ obj.difficulties = [];
3809
3847
  g_stateObj.scoreId = (g_stateObj.scoreId < difs.length ? g_stateObj.scoreId : 0);
3810
3848
 
3811
3849
  difs.forEach(dif => {
@@ -3827,10 +3865,12 @@ const headerConvert = _dosObj => {
3827
3865
  if (hasVal(difDetails[difpos.Name])) {
3828
3866
  const difNameInfo = difDetails[difpos.Name].split(`::`);
3829
3867
  obj.difLabels.push(escapeHtml(difNameInfo[0] ?? `Normal`));
3830
- obj.creatorNames.push(difNameInfo.length > 1 ? escapeHtml(difNameInfo[1]) : obj.tuning);
3868
+ obj.creatorNames.push(setVal(escapeHtml(difNameInfo[1]), obj.tuning));
3869
+ obj.difficulties.push(setIntVal(difNameInfo[2], 0));
3831
3870
  } else {
3832
3871
  obj.difLabels.push(`Normal`);
3833
3872
  obj.creatorNames.push(obj.tuning);
3873
+ obj.difficulties.push(0);
3834
3874
  }
3835
3875
 
3836
3876
  // 初期速度
@@ -3846,6 +3886,7 @@ const headerConvert = _dosObj => {
3846
3886
  obj.lifeDamages = [40];
3847
3887
  obj.lifeInits = [25];
3848
3888
  obj.creatorNames = [obj.tuning];
3889
+ obj.difficulties = [0];
3849
3890
  }
3850
3891
  const keyLists = makeDedupliArray(obj.keyLabels);
3851
3892
  obj.viewLists = [...Array(obj.keyLabels.length).keys()];
@@ -3865,6 +3906,54 @@ const headerConvert = _dosObj => {
3865
3906
  obj.musicIdxList = [...Array(Math.max(...obj.musicNos) + 1).keys()];
3866
3907
  }
3867
3908
 
3909
+ // 難易度配色の設定(選曲画面でのみ使用)
3910
+ const normalizeCssColor = _color => {
3911
+ const tmp = document.createElement(`span`);
3912
+ tmp.style.color = ``;
3913
+ tmp.style.color = trimStr(_color ?? ``);
3914
+ return tmp.style.color;
3915
+ };
3916
+ obj.difColorList = [
3917
+ { threshold: Infinity, color: `` }
3918
+ ];
3919
+ if (hasVal(_dosObj.difColor)) {
3920
+ _dosObj.difColor.split(`,`).forEach(val => {
3921
+ const difColorSet = val.split(`/`);
3922
+ obj.difColorList.push({
3923
+ threshold: setIntVal(difColorSet[0]),
3924
+ color: hasVal(difColorSet[1]) ? normalizeCssColor(difColorSet[1]) : ``
3925
+ });
3926
+ })
3927
+ }
3928
+ obj.difColorList.sort((a, b) => a.threshold - b.threshold);
3929
+
3930
+ const sanitizeCustomLink = _link => {
3931
+ try {
3932
+ const raw = trimStr(_link);
3933
+ if (!hasVal(raw)) return undefined;
3934
+ const url = new URL(raw, location.href); // allows relative inputs
3935
+ const allowed = g_isFile ? [`http:`, `https:`, `file:`] : [`http:`, `https:`];
3936
+ return allowed.includes(url.protocol) ? url.href : undefined;
3937
+ } catch {
3938
+ return undefined;
3939
+ }
3940
+ };
3941
+ obj.difCustomLink = [];
3942
+ if (hasVal(_dosObj.difCustomLink)) {
3943
+ splitLF2(_dosObj.difCustomLink).forEach(val => {
3944
+ const commaPos = val.indexOf(`,`);
3945
+ if (commaPos < 0) return;
3946
+ const idxStr = trimStr(val.slice(0, commaPos));
3947
+ const linkStr = val.slice(commaPos + 1);
3948
+ const idx = setIntVal(idxStr, -1);
3949
+ if (!Number.isFinite(idx) || idx < 0 || idx >= obj.difLabels.length) return;
3950
+ const safeHref = sanitizeCustomLink(linkStr);
3951
+ if (safeHref !== undefined) {
3952
+ obj.difCustomLink[idx] = safeHref;
3953
+ }
3954
+ });
3955
+ }
3956
+
3868
3957
  // 譜面変更セレクターの利用有無
3869
3958
  obj.difSelectorUse = getDifSelectorUse(_dosObj.difSelectorUse, obj.viewLists);
3870
3959
 
@@ -4227,9 +4316,10 @@ const headerConvert = _dosObj => {
4227
4316
 
4228
4317
  // ローカルストレージに保存済みのColorType設定からDisplayのColor設定を反映
4229
4318
  if (g_localStorage.colorType !== undefined) {
4230
- g_colorType = g_localStorage.colorType;
4319
+ g_colorType = g_keycons.colorTypes.concat(g_keycons.colorSelf).includes(g_localStorage.colorType)
4320
+ ? g_localStorage.colorType : `Default`;
4231
4321
  if (obj.colorUse) {
4232
- g_stateObj.d_color = boolToSwitch(g_keycons.colorDefTypes.findIndex(val => val === g_colorType) !== -1);
4322
+ g_stateObj.d_color = boolToSwitch(g_keycons.colorDefTypes.includes(g_colorType));
4233
4323
  }
4234
4324
  }
4235
4325
 
@@ -5331,22 +5421,36 @@ const titleInit = (_initFlg = false) => {
5331
5421
  changeMSelect(Math.floor(Math.random() * (g_headerObj.musicIdxList.length - 1)) + 1),
5332
5422
  g_lblPosObj.btnMusicSelectRandom, g_cssObj.button_Default),
5333
5423
  createDivCss2Label(`lblMusicCnt`, ``, g_lblPosObj.lblMusicCnt),
5334
- createDivCss2Label(`lblCommentM`, ``, g_lblPosObj.lblComment_music),
5335
-
5336
- createDivCss2Label(`lblBgmVolume`, `BGM Volume`, g_lblPosObj.lblBgmVolume),
5337
- createCss2Button(`btnBgmMute`, g_stateObj.bgmMuteFlg ? g_emojiObj.muted : g_emojiObj.speaker, evt => {
5338
- g_stateObj.bgmMuteFlg = !g_stateObj.bgmMuteFlg;
5339
- g_stateObj.bgmMuteFlg ? pauseBGM() : playBGM(0);
5340
- evt.target.innerHTML = g_stateObj.bgmMuteFlg ? g_emojiObj.muted : g_emojiObj.speaker;
5341
- }, g_lblPosObj.btnBgmMute, g_cssObj.button_Default),
5342
- createCss2Button(`btnBgmVolume`, `${g_stateObj.bgmVolume}${g_lblNameObj.percent}`, () => setBGMVolume(), {
5343
- ...g_lblPosObj.btnBgmVolume, cxtFunc: () => setBGMVolume(-1),
5344
- }, g_cssObj.button_Default),
5345
- createCss2Button(`btnBgmVolumeL`, `<`, () => setBGMVolume(-1),
5346
- g_lblPosObj.btnBgmVolumeL, g_cssObj.button_Setting),
5347
- createCss2Button(`btnBgmVolumeR`, `>`, () => setBGMVolume(),
5348
- g_lblPosObj.btnBgmVolumeR, g_cssObj.button_Setting),
5349
5424
  );
5425
+ createEmptySprite(divRoot, `lblCommentM`, g_lblPosObj.lblComment_music);
5426
+ multiAppend(lblCommentM,
5427
+ createDivCss2Label(`lblDifNameInfoM`, ``, g_lblPosObj.lblDifNameInfoM),
5428
+ createDivCss2Label(`lblDiffiInfoM`, ``, g_lblPosObj.lblDiffiInfoM),
5429
+ createDivCss2Label(`lblNotesInfoM`, ``, g_lblPosObj.lblNotesInfoM),
5430
+ createDivCss2Label(`lblCommentInfoM`, ``, g_lblPosObj.lblCommentInfoM),
5431
+ );
5432
+
5433
+ if (g_headerObj.bgmUseFlg) {
5434
+ multiAppend(divRoot,
5435
+ createDivCss2Label(`lblBgmVolume`, g_lblNameObj.bgmVolume, g_lblPosObj.lblBgmVolume),
5436
+ createCss2Button(`btnBgmMute`, g_stateObj.bgmMuteFlg ? g_emojiObj.muted : g_emojiObj.speaker, evt => {
5437
+ g_stateObj.bgmMuteFlg = !g_stateObj.bgmMuteFlg;
5438
+ g_stateObj.bgmMuteFlg ? pauseBGM() : playBGM(0);
5439
+ evt.target.innerHTML = g_stateObj.bgmMuteFlg ? g_emojiObj.muted : g_emojiObj.speaker;
5440
+ }, g_lblPosObj.btnBgmMute, g_cssObj.button_Default),
5441
+ createCss2Button(`btnBgmVolume`, `${g_stateObj.bgmVolume}${g_lblNameObj.percent}`, () => setBGMVolume(), {
5442
+ ...g_lblPosObj.btnBgmVolume, cxtFunc: () => setBGMVolume(-1),
5443
+ }, g_cssObj.button_Default),
5444
+ createCss2Button(`btnBgmVolumeL`, `<`, () => setBGMVolume(-1),
5445
+ g_lblPosObj.btnBgmVolumeL, g_cssObj.button_Setting),
5446
+ createCss2Button(`btnBgmVolumeR`, `>`, () => setBGMVolume(),
5447
+ g_lblPosObj.btnBgmVolumeR, g_cssObj.button_Setting),
5448
+ );
5449
+ } else {
5450
+ multiAppend(divRoot,
5451
+ createDivCss2Label(`lblBgmVolume`, `${g_lblNameObj.bgmMuted} ${g_emojiObj.muted}`, g_lblPosObj.btnBgmVolume),
5452
+ );
5453
+ }
5350
5454
  changeMSelect(0, _initFlg);
5351
5455
 
5352
5456
  let wheelCnt = 0;
@@ -5697,7 +5801,7 @@ const getCreatorInfo = (_creatorList) => {
5697
5801
  const creatorIdx = g_headerObj.tuningNames.findIndex(val => val === creatorName);
5698
5802
  const creatorUrl = creatorIdx >= 0 ? g_headerObj.tuningUrls[creatorIdx] : ``;
5699
5803
  return [creatorName, creatorUrl, creatorIdx];
5700
- }
5804
+ };
5701
5805
 
5702
5806
  /**
5703
5807
  * BGMの停止
@@ -6015,20 +6119,23 @@ const changeMSelect = (_num, _initFlg = false) => {
6015
6119
 
6016
6120
  // 選択した楽曲に対応する譜面番号、製作者情報、曲長を取得
6017
6121
  g_headerObj.viewLists = [];
6018
- const tmpKeyList = [], tmpCreatorList = [], tmpPlayingFrameList = [], tmpBpmList = [];
6122
+ const keyList = [], creatorList = [], playingFrameList = [], bpmList = [], difNameList = [], diffiList = [], notesList = [];
6019
6123
  const targetIdx = g_headerObj.musicIdxList[(g_settings.musicIdxNum + g_headerObj.musicIdxList.length * 20) % g_headerObj.musicIdxList.length];
6020
6124
  g_headerObj.musicNos.forEach((val, j) => {
6021
6125
  if ((g_headerObj.musicGroups?.[val] ?? val) === targetIdx) {
6022
6126
  g_headerObj.viewLists.push(j);
6023
- tmpKeyList.push(g_headerObj.keyLabels[j]);
6024
- tmpCreatorList.push(g_headerObj.creatorNames[j]);
6025
- tmpPlayingFrameList.push(g_detailObj.playingFrameWithBlank[j]);
6026
- tmpBpmList.push(g_headerObj.bpms[g_headerObj.musicNos[j]]);
6127
+ keyList.push(g_headerObj.keyLabels[j]);
6128
+ creatorList.push(g_headerObj.creatorNames[j]);
6129
+ playingFrameList.push(g_detailObj.playingFrameWithBlank[j]);
6130
+ bpmList.push(g_headerObj.bpms[g_headerObj.musicNos[j]]);
6131
+ difNameList.push(`${g_headerObj.keyLabels[j]} / ${g_headerObj.difLabels[j]}`);
6132
+ diffiList.push(g_headerObj.difficulties[j]);
6133
+ notesList.push(`Arrows: ${sumData(g_detailObj.arrowCnt[j])}+${sumData(g_detailObj.frzCnt[j])}`);
6027
6134
  }
6028
6135
  });
6029
- const playingFrames = makeDedupliArray(tmpPlayingFrameList.map(val => transFrameToTimer(val))).join(`, `);
6030
- const bpm = makeDedupliArray(tmpBpmList).join(`, `);
6031
- const [creatorName, creatorUrl, creatorIdx] = getCreatorInfo(tmpCreatorList);
6136
+ const playingFrames = makeDedupliArray(playingFrameList.map(val => transFrameToTimer(val))).join(`, `);
6137
+ const bpm = makeDedupliArray(bpmList).join(`, `);
6138
+ const [creatorName, creatorUrl, creatorIdx] = getCreatorInfo(creatorList);
6032
6139
  const creatorLink = creatorIdx >= 0 ?
6033
6140
  `<a href="${creatorUrl}" target="_blank">${creatorName}</a>` : creatorName;
6034
6141
 
@@ -6043,7 +6150,7 @@ const changeMSelect = (_num, _initFlg = false) => {
6043
6150
 
6044
6151
  // 選択した楽曲で使われているキー種の一覧を作成
6045
6152
  deleteChildspriteAll(`keyTitleSprite`);
6046
- makeDedupliArray(tmpKeyList).sort((a, b) => parseInt(a) - parseInt(b))
6153
+ makeDedupliArray(keyList).sort((a, b) => parseInt(a) - parseInt(b))
6047
6154
  .forEach((val, j) => keyTitleSprite.appendChild(
6048
6155
  createDivCss2Label(`btnKeyTitle${val}`, val, { ...g_lblPosObj.btnKeyTitle, x: 10 + j * 40 })));
6049
6156
 
@@ -6060,8 +6167,35 @@ const changeMSelect = (_num, _initFlg = false) => {
6060
6167
  g_settings.speedNum = getCurrentNo(g_settings.speeds, g_stateObj.speed);
6061
6168
  }
6062
6169
 
6063
- // コメント文の加工
6064
- lblCommentM.innerHTML = convertStrToVal(g_headerObj[`commentVal${g_settings.musicIdxNum}`]);
6170
+ // 譜面情報、コメント文の加工
6171
+ lblDifNameInfoM.innerHTML = ``;
6172
+ lblDiffiInfoM.innerHTML = ``;
6173
+ lblNotesInfoM.innerHTML = ``;
6174
+ let notesInfo = ``;
6175
+ for (let j = 0; j < difNameList.length; j++) {
6176
+ let noteInfo = `${difNameList[j]}`;
6177
+ if (makeDedupliArray(creatorList).length > 1) {
6178
+ noteInfo += ` (${creatorList[j]})`;
6179
+ }
6180
+ lblDifNameInfoM.innerHTML += g_headerObj.difCustomLink[g_headerObj.viewLists[j]] !== undefined
6181
+ ? `<a href="${g_headerObj.difCustomLink[g_headerObj.viewLists[j]]}" target="_blank" rel="noopener noreferrer">${noteInfo}</a>`
6182
+ : noteInfo;
6183
+ lblDifNameInfoM.innerHTML += `<br>`;
6184
+ notesInfo += `${noteInfo}<br>`;
6185
+
6186
+ const difColorPart = g_headerObj.difColorList.find(val => diffiList[j] < val.threshold);
6187
+ lblDiffiInfoM.innerHTML += `${diffiList[j] > 0
6188
+ ? `<span style="color:${difColorPart?.color || ''}">${diffiList[j]}</span>`
6189
+ : `-`}<br>`;
6190
+ lblNotesInfoM.innerHTML += `/ ${notesList[j]}<br>`;
6191
+ }
6192
+ lblDifNameInfoM.style.fontSize = wUnit(getFontSize2(notesInfo,
6193
+ g_lblPosObj.lblDifNameInfoM.w, { maxSiz: g_lblPosObj.lblDifNameInfoM.siz }));
6194
+ lblDiffiInfoM.style.fontSize = lblDifNameInfoM.style.fontSize;
6195
+ lblNotesInfoM.style.fontSize = lblDifNameInfoM.style.fontSize;
6196
+ lblCommentInfoM.style.top = `${getStrHeight(lblDifNameInfoM.innerHTML, parseFloat(lblDifNameInfoM.style.fontSize))}px`;
6197
+ lblCommentInfoM.innerHTML = convertStrToVal(g_headerObj[`commentVal${g_settings.musicIdxNum}`]);
6198
+ lblCommentM.scrollTop = 0;
6065
6199
 
6066
6200
  // BGM再生処理
6067
6201
  if (!g_stateObj.bgmMuteFlg) {
@@ -8894,7 +9028,7 @@ const createGeneralSettingEx = (_spriteList, _name, { defaultList = [C_FLG_OFF],
8894
9028
  setExpandedBtnSiz();
8895
9029
  createExpandedScView();
8896
9030
  }
8897
- }
9031
+ };
8898
9032
 
8899
9033
  /*-----------------------------------------------------------*/
8900
9034
  /* Scene : KEYCONFIG [orange] */
@@ -10750,7 +10884,7 @@ const scoreConvert = (_dosObj, _scoreId, _preblankFrame, _dummyNo = ``,
10750
10884
  splitLF(data)?.filter(val => val?.startsWith(_header) && _dosObj[val] !== undefined)
10751
10885
  .forEach(val => dataStr = dataStr.replace(val, _dosObj[val]));
10752
10886
  return dataStr;
10753
- }
10887
+ };
10754
10888
 
10755
10889
  /**
10756
10890
  * 譜面データの優先順配列パターンの取得
@@ -11133,7 +11267,7 @@ const getSpeedFactor = _speed => {
11133
11267
  return (1 + Math.abs(_speed)) / 2 * Math.sign(_speed);
11134
11268
  }
11135
11269
  return _speed;
11136
- }
11270
+ };
11137
11271
 
11138
11272
  /**
11139
11273
  * 各フレームごとの速度を格納
@@ -13874,7 +14008,7 @@ const changeAppearanceBar = (_num = 10, _dirPlus = 2) => {
13874
14008
  }
13875
14009
  }
13876
14010
  }
13877
- }
14011
+ };
13878
14012
 
13879
14013
  /**
13880
14014
  * アルファマスクの再描画 (Appearance: Hidden+, Sudden+ 用)
@@ -14310,7 +14444,7 @@ const judgeArrow = _j => {
14310
14444
  stepDivHit.classList.value = ``;
14311
14445
  stepDivHit.classList.add(g_cssObj[`main_step${_resultJdg}`]);
14312
14446
  stepDivHit.setAttribute(`cnt`, C_FRM_HITMOTION);
14313
- }
14447
+ };
14314
14448
 
14315
14449
  if (g_stateObj.excessive === C_FLG_ON && _difFrame <= g_judgObj.arrowJ[g_judgPosObj.uwan] && _difFrame > g_judgObj.arrowJ[g_judgPosObj.shobon]) {
14316
14450
  // 空押し判定(有効かつ早押し時のみ)
@@ -15353,7 +15487,7 @@ const resultInit = () => {
15353
15487
  ...g_lblPosObj.btnRsGitter, resetFunc: () => openLink(g_linkObj.discord),
15354
15488
  }, g_cssObj.button_Discord),
15355
15489
  );
15356
- }
15490
+ };
15357
15491
 
15358
15492
  // ボタン描画
15359
15493
  multiAppend(divRoot,
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * Source by tickle
7
7
  * Created : 2019/11/19
8
- * Revised : 2026/03/31 (v46.5.2)
8
+ * Revised : 2026/04/07 (v46.6.0)
9
9
  *
10
10
  * https://github.com/cwtickle/danoniplus
11
11
  */
@@ -301,6 +301,18 @@ const updateWindowSiz = () => {
301
301
  siz: g_limitObj.difSelectorSiz, align: C_ALIGN_LEFT,
302
302
  overflow: C_DIS_AUTO, whiteSpace: `normal`,
303
303
  },
304
+ lblDifNameInfoM: {
305
+ w: 180, siz: 12, align: C_ALIGN_LEFT, pointerEvents: C_DIS_AUTO, lineHeight: `16px`,
306
+ },
307
+ lblDiffiInfoM: {
308
+ x: 180, w: 20, siz: 12, align: C_ALIGN_RIGHT, lineHeight: `16px`, fontWeight: `bold`,
309
+ },
310
+ lblNotesInfoM: {
311
+ x: 220, w: 150, siz: 12, align: C_ALIGN_LEFT, lineHeight: `16px`,
312
+ },
313
+ lblCommentInfoM: {
314
+ siz: g_limitObj.difSelectorSiz, align: C_ALIGN_LEFT, pointerEvents: C_DIS_AUTO,
315
+ },
304
316
  btnBgmMute: {
305
317
  x: g_btnX() + 90, y: g_sHeight - 105, w: 40, h: 35, siz: 30,
306
318
  },
@@ -4355,6 +4367,8 @@ const g_lblNameObj = {
4355
4367
  dataSave: `Data Save`,
4356
4368
  clickHere: `Click Here!!`,
4357
4369
  comment: `Comment`,
4370
+ bgmVolume: `BGM Volume`,
4371
+ bgmMuted: `BGM Muted`,
4358
4372
 
4359
4373
  nowLoading: `Now Loading...`,
4360
4374
  pleaseWait: `Please Wait...`,
package/jsconfig.json CHANGED
@@ -1,7 +1,11 @@
1
1
  {
2
2
  "compilerOptions": {
3
3
  "target": "es2020",
4
- "baseUrl": "./"
4
+ "paths": {
5
+ "*": [
6
+ "./*"
7
+ ]
8
+ }
5
9
  },
6
10
  "exclude": [
7
11
  "node_modules"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "danoniplus",
3
- "version": "46.5.2",
3
+ "version": "46.6.0",
4
4
  "description": "Dancing☆Onigiri (CW Edition) - Web-based Rhythm Game",
5
5
  "main": "./js/danoni_main.js",
6
6
  "jsdelivr": "./js/danoni_main.js",