mandioca-tabs-mcp 0.2.14 → 0.2.15

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.
Files changed (2) hide show
  1. package/index.mjs +625 -148
  2. package/package.json +1 -1
package/index.mjs CHANGED
@@ -12308,6 +12308,10 @@ function ordenar(mapa) {
12308
12308
  return salida;
12309
12309
  }
12310
12310
  function ticsDeFigura(figura) {
12311
+ return Math.round(ticsExactosDeFigura(figura));
12312
+ }
12313
+ function ticsExactosDeFigura(figura) {
12314
+ if (figura.adorno) return 0;
12311
12315
  let tics = TICS_POR_NEGRA * 4 / figura.valor;
12312
12316
  let agregado = tics;
12313
12317
  for (let i2 = 0; i2 < figura.puntillos; i2++) {
@@ -12317,7 +12321,7 @@ function ticsDeFigura(figura) {
12317
12321
  if (figura.tupletNumerador > 0 && figura.tupletDenominador > 0) {
12318
12322
  tics = tics * figura.tupletDenominador / figura.tupletNumerador;
12319
12323
  }
12320
- return Math.round(tics);
12324
+ return tics;
12321
12325
  }
12322
12326
  function migrarMarcasPorGrado(guardadas, pintarGradosViejo) {
12323
12327
  const salida = {};
@@ -13297,6 +13301,7 @@ function normalizarNota(crudo) {
13297
13301
  deslizamientoEntrada: numero(crudo.deslizamientoEntrada, 0),
13298
13302
  deslizamientoSalida: numero(crudo.deslizamientoSalida, 0),
13299
13303
  armonico: numero(crudo.armonico, 0),
13304
+ armonicoValor: numero(crudo.armonicoValor, 0),
13300
13305
  bend: lista(crudo.bend),
13301
13306
  // ── Los signos de Guitar Pro. Ausente = no lo tenía. ────────────────────
13302
13307
  acento: numero(crudo.acento, 0),
@@ -13790,7 +13795,7 @@ function volcar(documento) {
13790
13795
  const notas = [...notasPorFigura.get(id2) ?? []].sort((a, b) => a.cuerda - b.cuerda);
13791
13796
  totalNotasPista += notas.length;
13792
13797
  return {
13793
- voz: datos.voz,
13798
+ voz: datos.voz + 1,
13794
13799
  tiempo: datos.tiempo,
13795
13800
  duracion: nombreDeDuracion(datos),
13796
13801
  tics: ticsDeFigura(datos),
@@ -14156,6 +14161,25 @@ var init_enBlanco = __esm({
14156
14161
  }
14157
14162
  });
14158
14163
 
14164
+ // packages/model/src/armadura.ts
14165
+ function armaduraEscrita(concierto, transposicion) {
14166
+ if (!transposicion) return concierto;
14167
+ return normalizar(concierto - 7 * transposicion);
14168
+ }
14169
+ function armaduraDeConcierto(escrita, transposicion) {
14170
+ if (!transposicion) return escrita;
14171
+ return normalizar(escrita + 7 * transposicion);
14172
+ }
14173
+ var normalizar;
14174
+ var init_armadura = __esm({
14175
+ "packages/model/src/armadura.ts"() {
14176
+ normalizar = (quintas) => {
14177
+ const k = (quintas % 12 + 12) % 12;
14178
+ return k > 6 ? k - 12 : k;
14179
+ };
14180
+ }
14181
+ });
14182
+
14159
14183
  // packages/model/src/index.ts
14160
14184
  var init_src2 = __esm({
14161
14185
  "packages/model/src/index.ts"() {
@@ -14168,6 +14192,7 @@ var init_src2 = __esm({
14168
14192
  init_migrar();
14169
14193
  init_kit();
14170
14194
  init_tipos();
14195
+ init_armadura();
14171
14196
  }
14172
14197
  });
14173
14198
 
@@ -14184,7 +14209,7 @@ function posicionesEscribibles(indice, cursor) {
14184
14209
  }
14185
14210
  function cursorInicial(indice, pistaId) {
14186
14211
  const pista = pistaId !== void 0 ? indice.pista(pistaId) : indice.pistas[0];
14187
- return normalizar(indice, {
14212
+ return normalizar2(indice, {
14188
14213
  pistaId: pista?.id ?? "",
14189
14214
  compas: 0,
14190
14215
  voz: 0,
@@ -14192,7 +14217,7 @@ function cursorInicial(indice, pistaId) {
14192
14217
  cuerda: 1
14193
14218
  });
14194
14219
  }
14195
- function normalizar(indice, cursor) {
14220
+ function normalizar2(indice, cursor) {
14196
14221
  const pista = indice.pista(cursor.pistaId) ?? indice.pistas[0];
14197
14222
  const cuerdas = pista?.datos.afinacion.length ?? 6;
14198
14223
  const ultimoCompas = Math.max(0, indice.cantidadDeCompases - 1);
@@ -14345,6 +14370,50 @@ var init_dinamicas = __esm({
14345
14370
  }
14346
14371
  });
14347
14372
 
14373
+ // packages/editor/src/ligaduras.ts
14374
+ function repararLigaduras(documento, pistas, modo) {
14375
+ const indice = indexar(documento);
14376
+ let tocadas = 0;
14377
+ for (const pistaId of new Set(pistas)) {
14378
+ if (indice.pista(pistaId)?.datos.tipo !== "trastes") continue;
14379
+ const ultimas = /* @__PURE__ */ new Map();
14380
+ for (let c = 0; c < indice.cantidadDeCompases; c++) {
14381
+ const figuras = [...indice.figuras(indice.compasId(pistaId, c))].sort(
14382
+ (a, b) => a.datos.voz - b.datos.voz || a.datos.tiempo - b.datos.tiempo
14383
+ );
14384
+ for (const figura of figuras) {
14385
+ for (const nota of indice.notas(figura.id)) {
14386
+ const clave = `${figura.datos.voz}|${nota.datos.cuerda}`;
14387
+ const origen = ultimas.get(clave);
14388
+ const mapa = documento.notas.get(nota.id);
14389
+ let traste = nota.datos.traste;
14390
+ if (nota.datos.ligadaAAnterior && mapa) {
14391
+ if (origen === void 0) {
14392
+ mapa.set("ligadaAAnterior", false);
14393
+ tocadas++;
14394
+ } else if (origen !== traste) {
14395
+ if (modo === "seguir") {
14396
+ mapa.set("traste", origen);
14397
+ traste = origen;
14398
+ } else {
14399
+ mapa.set("ligadaAAnterior", false);
14400
+ }
14401
+ tocadas++;
14402
+ }
14403
+ }
14404
+ ultimas.set(clave, traste);
14405
+ }
14406
+ }
14407
+ }
14408
+ }
14409
+ return tocadas;
14410
+ }
14411
+ var init_ligaduras = __esm({
14412
+ "packages/editor/src/ligaduras.ts"() {
14413
+ init_src2();
14414
+ }
14415
+ });
14416
+
14348
14417
  // packages/editor/src/comandos.ts
14349
14418
  function masLarga(duracion) {
14350
14419
  const i2 = VALORES.indexOf(duracion.valor);
@@ -14384,7 +14453,12 @@ function escribirEnLaCuerda(documento, indice, cursor, cuerda, resolverTraste, d
14384
14453
  let notaId;
14385
14454
  if (notaExistente && figuraExistente && figuraId === figuraExistente.id) {
14386
14455
  notaId = notaExistente.id;
14387
- documento.notas.get(notaId)?.set("traste", traste);
14456
+ const mapa = documento.notas.get(notaId);
14457
+ mapa?.set("traste", traste);
14458
+ if (traste !== notaExistente.datos.traste) {
14459
+ if (notaExistente.datos.ligadaAAnterior) mapa?.set("ligadaAAnterior", false);
14460
+ repararLigaduras(documento, [cursor.pistaId], "seguir");
14461
+ }
14388
14462
  } else {
14389
14463
  notaId = documento.agregarNota(notaNueva(figuraId, cuerda, traste));
14390
14464
  }
@@ -14457,6 +14531,9 @@ function borrarPercusion(documento, indice, cursor, articulacion) {
14457
14531
  function escribirTraste(documento, indice, cursor, cuerda, traste, opciones = {}) {
14458
14532
  const tope = opciones.maxTraste ?? MAX_TRASTE;
14459
14533
  const acotado = Math.max(0, Math.min(tope, Math.round(traste)));
14534
+ const pista = indice.pista(cursor.pistaId);
14535
+ const cuerdas = pista?.datos.afinacion.length ?? 0;
14536
+ if (pista?.datos.tipo === "trastes" && (cuerda < 1 || cuerda > cuerdas || !Number.isInteger(cuerda))) return null;
14460
14537
  return escribirEnLaCuerda(
14461
14538
  documento,
14462
14539
  indice,
@@ -14514,7 +14591,7 @@ function cambiarDuracion(documento, indice, cursor, duracion, seleccion) {
14514
14591
  function retejerLosCompasesDe(documento, golpes) {
14515
14592
  const compases = /* @__PURE__ */ new Map();
14516
14593
  for (const g of golpes) compases.set(`${g.compasId} ${g.voz}`, g);
14517
- for (const { compasId, voz } of compases.values()) retejerVoz(documento, compasId, voz);
14594
+ retejerVoces(documento, compases.values());
14518
14595
  }
14519
14596
  function escalarDuracion(documento, indice, cursor, direccion, seleccion) {
14520
14597
  const golpes = golpesAlcanzados(indice, cursor, seleccion);
@@ -14554,17 +14631,31 @@ function duracionesAlcanzadas(indice, cursor, seleccion) {
14554
14631
  }
14555
14632
  return [...vistas.values()].sort((a, b) => a.valor - b.valor || a.puntillos - b.puntillos);
14556
14633
  }
14557
- function retejerVoz(documento, compasId, voz) {
14558
- const figuras = [];
14634
+ function retejerVoces(documento, voces) {
14635
+ const pedidas = /* @__PURE__ */ new Map();
14636
+ for (const v of voces) {
14637
+ const clave = `${v.compasId} ${v.voz}`;
14638
+ const ya = pedidas.get(clave);
14639
+ if (!ya) pedidas.set(clave, { desde: v.desde, figuras: [] });
14640
+ else if (v.desde !== void 0) ya.desde = ya.desde === void 0 ? v.desde : Math.min(ya.desde, v.desde);
14641
+ }
14642
+ if (pedidas.size === 0) return;
14559
14643
  for (const [id2, entidad] of documento.figuras.entries()) {
14560
- const datos = entidad.toJSON();
14561
- if (datos.compasId === compasId && datos.voz === voz) figuras.push({ id: id2, datos });
14644
+ const compasId = entidad.get("compasId");
14645
+ const voz = entidad.get("voz");
14646
+ const pedida = pedidas.get(`${compasId} ${voz}`);
14647
+ if (pedida) pedida.figuras.push({ id: id2, datos: entidad.toJSON() });
14562
14648
  }
14563
- figuras.sort((a, b) => a.datos.tiempo - b.datos.tiempo);
14564
- let tiempo = figuras[0]?.datos.tiempo ?? 0;
14565
- for (const { id: id2, datos } of figuras) {
14566
- if (datos.tiempo !== tiempo) documento.figuras.get(id2)?.set("tiempo", tiempo);
14567
- tiempo += ticsDeFigura(datos);
14649
+ for (const { desde, figuras } of pedidas.values()) {
14650
+ figuras.sort((a, b) => a.datos.tiempo - b.datos.tiempo);
14651
+ const primera = figuras.findIndex((f) => desde === void 0 || f.datos.tiempo >= desde);
14652
+ if (primera < 0) continue;
14653
+ let exacto = desde ?? figuras[primera].datos.tiempo;
14654
+ for (const { id: id2, datos } of figuras.slice(primera)) {
14655
+ const tiempo = Math.round(exacto);
14656
+ if (datos.tiempo !== tiempo) documento.figuras.get(id2)?.set("tiempo", tiempo);
14657
+ exacto += ticsExactosDeFigura(datos);
14658
+ }
14568
14659
  }
14569
14660
  }
14570
14661
  function figuraNueva(compasId, cursor, duracion) {
@@ -14610,6 +14701,7 @@ var init_comandos = __esm({
14610
14701
  "packages/editor/src/comandos.ts"() {
14611
14702
  init_dinamicas();
14612
14703
  init_src2();
14704
+ init_ligaduras();
14613
14705
  init_seleccion();
14614
14706
  DURACION_INICIAL = { valor: 4, puntillos: 0 };
14615
14707
  VALORES = [1, 2, 4, 8, 16, 32, 64];
@@ -14626,6 +14718,14 @@ var init_comandos = __esm({
14626
14718
  });
14627
14719
 
14628
14720
  // packages/editor/src/pasajes.ts
14721
+ function rellenarConSilencios(documento, compasId, voz, desde, hasta) {
14722
+ let t = desde;
14723
+ while (hasta - t >= ticsDeFigura({ valor: 64, puntillos: 0, tupletNumerador: 0, tupletDenominador: 0 })) {
14724
+ const valor = VALORES.find((v) => ticsDeFigura({ valor: v, puntillos: 0, tupletNumerador: 0, tupletDenominador: 0 }) <= hasta - t);
14725
+ documento.agregarFigura(normalizarFigura({ compasId, voz, tiempo: t, valor, puntillos: 0, esSilencio: true }));
14726
+ t += ticsDeFigura({ valor, puntillos: 0, tupletNumerador: 0, tupletDenominador: 0 });
14727
+ }
14728
+ }
14629
14729
  function copiar(indice, seleccion) {
14630
14730
  const figuras = figurasDelPasaje(indice, seleccion);
14631
14731
  if (figuras.length === 0) return null;
@@ -14684,6 +14784,7 @@ function pegar(documento, indice, cursor, portapapeles2) {
14684
14784
  }
14685
14785
  }
14686
14786
  const aBorrar = [];
14787
+ const restos = [];
14687
14788
  for (const [compasDelTramo, tramo] of tramos) {
14688
14789
  const compasId = indice.compasId(cursor.pistaId, compasDelTramo, cursor.pentagrama);
14689
14790
  for (const figura of indice.figuras(compasId, cursor.voz)) {
@@ -14691,6 +14792,8 @@ function pegar(documento, indice, cursor, portapapeles2) {
14691
14792
  const fin = inicio + ticsDeFigura(figura.datos);
14692
14793
  if (inicio < tramo.hasta && fin > tramo.desde) {
14693
14794
  aBorrar.push({ figuraId: figura.id, notas: indice.notas(figura.id).map((n) => n.id) });
14795
+ if (inicio < tramo.desde) restos.push({ compas: compasDelTramo, desde: inicio, hasta: tramo.desde });
14796
+ if (fin > tramo.hasta) restos.push({ compas: compasDelTramo, desde: tramo.hasta, hasta: fin });
14694
14797
  }
14695
14798
  }
14696
14799
  }
@@ -14729,9 +14832,15 @@ function pegar(documento, indice, cursor, portapapeles2) {
14729
14832
  });
14730
14833
  for (const nota of notas) documento.agregarNota({ ...nota, figuraId });
14731
14834
  }
14732
- for (const compasId of compasesDestino.values()) {
14733
- if (compasId) retejerVoz(documento, compasId, cursor.voz);
14835
+ for (const resto of restos) {
14836
+ const compasId = compasesDestino.get(resto.compas);
14837
+ if (compasId) rellenarConSilencios(documento, compasId, cursor.voz, resto.desde, resto.hasta);
14734
14838
  }
14839
+ retejerVoces(
14840
+ documento,
14841
+ [...compasesDestino.values()].flatMap((compasId) => compasId ? [{ compasId, voz: cursor.voz }] : [])
14842
+ );
14843
+ repararLigaduras(documento, [cursor.pistaId], "soltar");
14735
14844
  });
14736
14845
  return true;
14737
14846
  }
@@ -14775,9 +14884,45 @@ function duplicarUltima(documento, indice, cursor, opciones = {}) {
14775
14884
  };
14776
14885
  return pegar(documento, indice, cursor, portapapeles2);
14777
14886
  }
14887
+ function origenEnElPasaje(indice, pistaId, notaId, enElPasaje) {
14888
+ const datos = enElPasaje.get(notaId);
14889
+ if (!datos) return false;
14890
+ const nota = { datos };
14891
+ const enOrden = [];
14892
+ for (let c = 0; c < indice.cantidadDeCompases; c++)
14893
+ for (const f of [...indice.figuras(indice.compasId(pistaId, c))].sort((a, b) => a.datos.tiempo - b.datos.tiempo))
14894
+ enOrden.push({ id: f.id, voz: f.datos.voz });
14895
+ const donde = enOrden.findIndex((f) => f.id === nota.datos.figuraId);
14896
+ for (let k = donde - 1; k >= 0; k--) {
14897
+ if (enOrden[k].voz !== enOrden[donde].voz) continue;
14898
+ const anterior = indice.notaEnCuerda(enOrden[k].id, nota.datos.cuerda);
14899
+ if (anterior) return enElPasaje.has(anterior.id);
14900
+ }
14901
+ return false;
14902
+ }
14778
14903
  function transponer(documento, indice, seleccion, trastes, maxTraste = MAX_TRASTE) {
14779
14904
  const figuras = figurasDelPasaje(indice, seleccion);
14905
+ const tipo = indice.pista(seleccion.pistaId)?.datos.tipo;
14906
+ if (tipo === "percusion") return { hecho: false, motivo: "no-se-transpone" };
14907
+ if (tipo === "altura") {
14908
+ const alturas = [];
14909
+ for (const figura of figuras) {
14910
+ for (const nota of indice.notas(figura.id)) {
14911
+ if (nota.datos.altura === null || nota.datos.altura === void 0) continue;
14912
+ const nueva = nota.datos.altura + trastes;
14913
+ if (nueva < 0 || nueva > 127) return { hecho: false, motivo: "fuera-del-rango" };
14914
+ alturas.push({ notaId: nota.id, altura: nueva });
14915
+ }
14916
+ }
14917
+ if (alturas.length === 0) return { hecho: false, motivo: "sin-notas" };
14918
+ documento.doc.transact(() => {
14919
+ for (const c of alturas) documento.notas.get(c.notaId)?.set("altura", c.altura);
14920
+ });
14921
+ return { hecho: true, notas: alturas.length };
14922
+ }
14780
14923
  const cambios = [];
14924
+ const enElPasaje = /* @__PURE__ */ new Map();
14925
+ for (const figura of figuras) for (const nota of indice.notas(figura.id)) enElPasaje.set(nota.id, nota.datos);
14781
14926
  for (const figura of figuras) {
14782
14927
  for (const nota of indice.notas(figura.id)) {
14783
14928
  const nuevo = nota.datos.traste + trastes;
@@ -14788,6 +14933,12 @@ function transponer(documento, indice, seleccion, trastes, maxTraste = MAX_TRAST
14788
14933
  if (cambios.length === 0) return { hecho: false, motivo: "sin-notas" };
14789
14934
  documento.doc.transact(() => {
14790
14935
  for (const cambio of cambios) documento.notas.get(cambio.notaId)?.set("traste", cambio.traste);
14936
+ for (const cambio of cambios) {
14937
+ const nota = documento.notas.get(cambio.notaId);
14938
+ if (nota?.get("ligadaAAnterior") && !origenEnElPasaje(indice, seleccion.pistaId, cambio.notaId, enElPasaje))
14939
+ nota.set("ligadaAAnterior", false);
14940
+ }
14941
+ repararLigaduras(documento, [seleccion.pistaId], "seguir");
14791
14942
  });
14792
14943
  return { hecho: true, notas: cambios.length };
14793
14944
  }
@@ -14798,17 +14949,18 @@ function borrarPasaje(documento, indice, seleccion) {
14798
14949
  id: f.id,
14799
14950
  notas: indice.notas(f.id).map((n) => n.id)
14800
14951
  }));
14801
- const compases = new Set(
14802
- figuras.map((f) => indice.compasId(seleccion.pistaId, f.compas, seleccion.pentagrama)).filter(Boolean)
14803
- );
14952
+ const desdeEn = /* @__PURE__ */ new Map();
14953
+ for (const f of figuras) {
14954
+ const compasId = indice.compasId(seleccion.pistaId, f.compas, seleccion.pentagrama);
14955
+ if (compasId) desdeEn.set(compasId, Math.min(desdeEn.get(compasId) ?? Infinity, f.tiempo));
14956
+ }
14804
14957
  documento.doc.transact(() => {
14805
14958
  for (const figura of aBorrar) {
14806
14959
  for (const notaId of figura.notas) documento.notas.delete(notaId);
14807
14960
  documento.figuras.delete(figura.id);
14808
14961
  }
14809
- for (const compasId of compases) {
14810
- if (compasId) retejerVoz(documento, compasId, seleccion.voz);
14811
- }
14962
+ retejerVoces(documento, [...desdeEn].map(([compasId, desde]) => ({ compasId, voz: seleccion.voz, desde })));
14963
+ repararLigaduras(documento, [seleccion.pistaId], "soltar");
14812
14964
  });
14813
14965
  return aBorrar.length;
14814
14966
  }
@@ -14896,6 +15048,7 @@ function borrarCompas(documento, indice, compas) {
14896
15048
  }
14897
15049
  for (const compasId of compases) documento.compases.delete(compasId);
14898
15050
  documento.compasesMaestros.delete(maestro.id);
15051
+ repararLigaduras(documento, indice.pistas.map((p) => p.id), "soltar");
14899
15052
  });
14900
15053
  return true;
14901
15054
  }
@@ -14950,6 +15103,7 @@ function borrarRango(documento, indice, desde, hasta) {
14950
15103
  }
14951
15104
  for (const compasId of compases) documento.compases.delete(compasId);
14952
15105
  for (const id2 of maestros) documento.compasesMaestros.delete(id2);
15106
+ repararLigaduras(documento, indice.pistas.map((p) => p.id), "soltar");
14953
15107
  });
14954
15108
  return maestros.length;
14955
15109
  }
@@ -14974,6 +15128,7 @@ var init_pasajes = __esm({
14974
15128
  "packages/editor/src/pasajes.ts"() {
14975
15129
  init_src2();
14976
15130
  init_comandos();
15131
+ init_ligaduras();
14977
15132
  init_seleccion();
14978
15133
  }
14979
15134
  });
@@ -20780,7 +20935,7 @@ function notasDeLaPista(indice, pistaId) {
20780
20935
  if (!compasId) continue;
20781
20936
  for (const figura of indice.figuras(compasId)) {
20782
20937
  for (const nota of indice.notas(figura.id)) {
20783
- salida.push({ id: nota.id, cuerda: nota.datos.cuerda });
20938
+ salida.push({ id: nota.id, cuerda: nota.datos.cuerda, figuraId: figura.id });
20784
20939
  }
20785
20940
  }
20786
20941
  }
@@ -20817,11 +20972,15 @@ function quitarCuerda(documento, indice, pistaId, donde) {
20817
20972
  const todas = notasDeLaPista(indice, pistaId);
20818
20973
  const aBorrar = todas.filter((n) => n.cuerda === cuerdaQueSeVa);
20819
20974
  const aRenumerar = donde === "grave" ? todas.filter((n) => n.cuerda > 1) : [];
20975
+ const quedan = /* @__PURE__ */ new Map();
20976
+ for (const n of todas) quedan.set(n.figuraId, (quedan.get(n.figuraId) ?? 0) + (n.cuerda === cuerdaQueSeVa ? 0 : 1));
20820
20977
  documento.doc.transact(() => {
20821
20978
  for (const nota of aBorrar) documento.notas.delete(nota.id);
20822
20979
  for (const nota of aRenumerar) {
20823
20980
  documento.notas.get(nota.id)?.set("cuerda", nota.cuerda - 1);
20824
20981
  }
20982
+ for (const [figuraId, cuantas] of quedan)
20983
+ if (cuantas === 0) documento.figuras.get(figuraId)?.set("esSilencio", true);
20825
20984
  documento.pistas.get(pistaId)?.set("afinacion", nuevaAfinacion);
20826
20985
  });
20827
20986
  return { hecho: true, cuerdas: nuevaAfinacion.length, notasBorradas: aBorrar.length };
@@ -88453,7 +88612,7 @@ function prepararMusicXml(xml) {
88453
88612
  });
88454
88613
  if (atributosMovidos) {
88455
88614
  correcciones.push(
88456
- `${atributosMovidos} cambios de clave, armadura o comp\xE1s escritos antes de la barra pasaron al comp\xE1s siguiente.`
88615
+ `${atributosMovidos} cambios de clave, armadura o comp\xE1s escritos entre las notas se pusieron al principio del comp\xE1s donde rigen.`
88457
88616
  );
88458
88617
  }
88459
88618
  if (acordesSeparados) {
@@ -88474,6 +88633,17 @@ function prepararMusicXml(xml) {
88474
88633
  });
88475
88634
  });
88476
88635
  if (juntados) correcciones.push(`${juntados} indicaciones de texto en varios renglones se juntaron en una.`);
88636
+ let silabas2 = 0;
88637
+ salida = salida.replace(/<lyric\b[^>]*>[\s\S]*?<\/lyric>/g, (lyric) => {
88638
+ const tipo = /<syllabic>\s*(\w+)\s*<\/syllabic>/.exec(lyric)?.[1];
88639
+ if (tipo !== "begin" && tipo !== "middle") return lyric;
88640
+ return lyric.replace(/(<text\b[^>]*>)([\s\S]*?)(<\/text>)/, (m, a, texto4, b) => {
88641
+ if (texto4.trimEnd().endsWith("-")) return m;
88642
+ silabas2++;
88643
+ return `${a}${texto4.trimEnd()}-${b}`;
88644
+ });
88645
+ });
88646
+ if (silabas2) correcciones.push(`${silabas2} s\xEDlabas unidas de la letra se marcaron con su guion.`);
88477
88647
  let tempos = 0;
88478
88648
  salida = salida.replace(/<metronome\b[^>]*>[\s\S]*?<\/metronome>/g, (met) => {
88479
88649
  const unidad = /<beat-unit>\s*([\w-]+)\s*<\/beat-unit>/.exec(met)?.[1];
@@ -88507,6 +88677,16 @@ function rearmar(parte, compases, nuevos) {
88507
88677
  });
88508
88678
  return salida + parte.slice(cursor);
88509
88679
  }
88680
+ function tiempoAl(pedazo) {
88681
+ let t = 0;
88682
+ for (const m of pedazo.matchAll(/<(note|backup|forward)\b[\s\S]*?<\/\1>/g)) {
88683
+ const dur = entero(m[0], /<duration>\s*(\d+)\s*<\/duration>/) ?? 0;
88684
+ if (m[1] === "backup") t -= dur;
88685
+ else if (m[1] === "forward") t += dur;
88686
+ else if (!/<chord\s*\/>/.test(m[0]) && !/<grace\b/.test(m[0])) t += dur;
88687
+ }
88688
+ return t;
88689
+ }
88510
88690
  function moverAtributosDeFinDeCompas(parte) {
88511
88691
  const compases = compasesDe(parte);
88512
88692
  let cuantos = 0;
@@ -88516,15 +88696,18 @@ function moverAtributosDeFinDeCompas(parte) {
88516
88696
  const primeraNota = contenido.search(/<note\b/);
88517
88697
  if (primeraNota >= 0) {
88518
88698
  let llevar = "";
88519
- contenido = contenido.slice(0, primeraNota) + contenido.slice(primeraNota).replace(/<attributes\b[^>]*>([\s\S]*?)<\/attributes>/g, (bloque, adentro) => {
88699
+ let alPrincipio = "";
88700
+ const despues = contenido.slice(primeraNota);
88701
+ contenido = contenido.slice(0, primeraNota) + despues.replace(/<attributes\b[^>]*>([\s\S]*?)<\/attributes>/g, (bloque, adentro, donde) => {
88520
88702
  const hijos = adentro.match(HIJO_QUE_SE_MUEVE);
88521
88703
  if (!hijos) return bloque;
88522
88704
  cuantos += hijos.length;
88523
- llevar += hijos.join("");
88705
+ if (tiempoAl(despues.slice(0, donde)) <= 0) alPrincipio += hijos.join("");
88706
+ else llevar += hijos.join("");
88524
88707
  const resto = adentro.replace(HIJO_QUE_SE_MUEVE, "");
88525
88708
  return resto.trim() ? `<attributes>${resto}</attributes>` : "";
88526
88709
  });
88527
- const entra2 = arrastre;
88710
+ const entra2 = arrastre + alPrincipio;
88528
88711
  arrastre = llevar;
88529
88712
  return (entra2 ? `<attributes>${entra2}</attributes>` : "") + contenido;
88530
88713
  }
@@ -88759,6 +88942,13 @@ var init_musicxmlEntrada = __esm({
88759
88942
  });
88760
88943
 
88761
88944
  // packages/io/src/importarGp.ts
88945
+ function piezaDeBateria(pista, numero2) {
88946
+ if (numero2 < 0) return null;
88947
+ const delArchivo = pista.percussionArticulations ?? [];
88948
+ const midi = numero2 < delArchivo.length ? delArchivo[numero2].outputMidiNumber : SALIDA_DE_ID_GP[numero2] ?? numero2;
88949
+ const buscada = PARIENTE_GM[midi] ?? midi;
88950
+ return KIT.find((p) => p.midi === buscada)?.indice ?? null;
88951
+ }
88762
88952
  function importarGp(bytes, opciones = {}) {
88763
88953
  const xml = textoMusicXml(bytes);
88764
88954
  if (xml === null) {
@@ -88803,18 +88993,21 @@ function importarScore(score, opciones = {}, datos = {}) {
88803
88993
  "La autor\xEDa qued\xF3 sin completar: se import\xF3 como transcripci\xF3n con los datos del archivo. Hay que confirmarla antes de publicar o compartir el documento."
88804
88994
  );
88805
88995
  }
88996
+ const saltosEscritos = saltosDelTexto(score);
88806
88997
  const idsDeCompasMaestro = score.masterBars.map(
88807
88998
  (maestro) => documento.agregarCompasMaestro(normalizarCompasMaestro({
88808
88999
  numerador: maestro.timeSignatureNumerator,
88809
89000
  denominador: maestro.timeSignatureDenominator,
88810
- tonalidad: numeroDeTonalidad(maestro.keySignature),
89001
+ tonalidad: numeroDeTonalidad(tonalidadDeConcierto(score, maestro.index)),
88811
89002
  // ⚠️ El ensayo de un MusicXML (`<rehearsal>A</rehearsal>`) llena sólo `section.marker`;
88812
89003
  // `text` queda vacío y las letras A, B, C… se perdían todas. Un `.gp` trae las dos y
88813
89004
  // manda el texto, como siempre.
88814
89005
  seccion: maestro.section?.text || maestro.section?.marker || "",
88815
- // Solo interesa el cambio de tempo que arranca en este compás; los que caen
88816
- // en el medio son F02 y todavía no tienen dónde ir.
88817
- tempo: maestro.tempoAutomations?.[0]?.value ?? null,
89006
+ // El cambio de tempo que arranca EN este compás. Los que caen a mitad van a su figura
89007
+ // (ver `temposAMitad` abajo).
89008
+ // ⛔ (2026-11-10) Antes era `tempoAutomations[0]` sin mirar dónde caía: un 140 a mitad
89009
+ // del compás 2 se aplicaba desde su principio y la primera mitad sonaba a 140.
89010
+ tempo: maestro.tempoAutomations?.find((a) => a.ratioPosition <= 1e-6)?.value ?? null,
88818
89011
  repiteDesdeAca: maestro.isRepeatStart,
88819
89012
  repiteVeces: maestro.repeatCount,
88820
89013
  // ⚠️ Novena pérdida silenciosa de la misma familia: 2 de los 15 `.gp` de Daniel
@@ -88842,7 +89035,7 @@ function importarScore(score, opciones = {}, datos = {}) {
88842
89035
  //
88843
89036
  // ★ El nombre y no el número, además, porque acá es una LISTA y se lee: un
88844
89037
  // `["JumpDalSegnoAlCoda"]` en el documento dice algo; un `[10]` no.
88845
- direcciones: maestro.directions ? [...maestro.directions].map(
89038
+ direcciones: maestro.directions ? [...saltosEscritos.precisos.get(maestro.index) ?? maestro.directions].map(
88846
89039
  (d) => _barrel_exports$4.Direction[d] ?? String(d)
88847
89040
  ) : []
88848
89041
  }))
@@ -88853,7 +89046,7 @@ function importarScore(score, opciones = {}, datos = {}) {
88853
89046
  const id2 = idsDeCompasMaestro[i2];
88854
89047
  if (id2 !== void 0 && i2 > 0) documento.ponerSaltoDeRenglon(id2, true);
88855
89048
  }
88856
- const letrasDobles = { cuantas: 0 };
89049
+ const letrasDobles = { cuantas: 0, versosDeMas: 0 };
88857
89050
  const tipoDelPentagrama = (p) => p.isPercussion ? "percusion" : p.tuning.length === 0 ? "altura" : "trastes";
88858
89051
  for (const pista of score.tracks) {
88859
89052
  if (pista.staves.length === 0) {
@@ -88868,6 +89061,8 @@ function importarScore(score, opciones = {}, datos = {}) {
88868
89061
  const nombreCortoDePista = variosPentagramas ? `${pista.shortName ?? ""} ${numeroDePentagrama + 1}`.trim() : pista.shortName ?? "";
88869
89062
  const pentagramaEnLaPista = unInstrumento ? numeroDePentagrama : 0;
88870
89063
  const tipo = tipoDelPentagrama(pentagrama);
89064
+ const sinPieza = /* @__PURE__ */ new Map();
89065
+ const articulacionDe = (n) => piezaDeBateria(pista, n.percussionArticulation);
88871
89066
  const idPista = unInstrumento && idDelInstrumento || documento.agregarPista({
88872
89067
  tipo,
88873
89068
  nombre: nombreDePista,
@@ -88945,7 +89140,7 @@ function importarScore(score, opciones = {}, datos = {}) {
88945
89140
  // ★ Acá viene la letra. En la canción de Daniel cada sílaba está escrita
88946
89141
  // como texto del golpe, que es como se hace en la práctica en Guitar Pro.
88947
89142
  // Sin este campo, importar y exportar la borraba sin decir nada.
88948
- texto: textoDelGolpe(golpe, letrasDobles),
89143
+ texto: saltosEscritos.textos.has(golpe) ? "" : textoDelGolpe(golpe, letrasDobles),
88949
89144
  // ═══════════════════════════════════════════════════════════════════
88950
89145
  // ⛔⛔ LOS CIFRADOS DE ACORDE SE PERDÍAN TODOS (2026-11-09)
88951
89146
  // ═══════════════════════════════════════════════════════════════════
@@ -89003,6 +89198,11 @@ function importarScore(score, opciones = {}, datos = {}) {
89003
89198
  })
89004
89199
  );
89005
89200
  for (const nota of golpe.notes) {
89201
+ if (tipo === "percusion" && articulacionDe(nota) === null) {
89202
+ const n = nota.percussionArticulation;
89203
+ sinPieza.set(n, (sinPieza.get(n) ?? 0) + 1);
89204
+ continue;
89205
+ }
89006
89206
  documento.agregarNota(
89007
89207
  normalizarNota({
89008
89208
  figuraId: idFigura,
@@ -89025,7 +89225,7 @@ function importarScore(score, opciones = {}, datos = {}) {
89025
89225
  // `percussionArticulation`, que es lo que `proyectar` le pone. Así la ida y la
89026
89226
  // vuelta son simétricas: lo que se exporta se vuelve a importar idéntico.
89027
89227
  altura: tipo === "altura" ? nota.calculateRealValue(false, false) : null,
89028
- articulacion: tipo === "percusion" ? nota.percussionArticulation : null,
89228
+ articulacion: tipo === "percusion" ? articulacionDe(nota) : null,
89029
89229
  ligadaAAnterior: nota.isTieDestination,
89030
89230
  muerta: nota.isDead,
89031
89231
  fantasma: nota.isGhost,
@@ -89042,6 +89242,8 @@ function importarScore(score, opciones = {}, datos = {}) {
89042
89242
  deslizamientoEntrada: nota.slideInType,
89043
89243
  deslizamientoSalida: nota.slideOutType,
89044
89244
  armonico: nota.harmonicType,
89245
+ // El natural se recalcula del traste al proyectar: se guarda sólo si es otro.
89246
+ armonicoValor: nota.harmonicType !== _barrel_exports$4.HarmonicType.None && nota.harmonicType !== _barrel_exports$4.HarmonicType.Natural ? nota.harmonicValue : 0,
89045
89247
  // ── Los signos de Guitar Pro, a nivel de nota ──────────────────
89046
89248
  acento: nota.accentuated,
89047
89249
  ligaduraDeExpresion: nota.isSlurDestination || nota.slurDestination !== null,
@@ -89077,6 +89279,12 @@ function importarScore(score, opciones = {}, datos = {}) {
89077
89279
  }
89078
89280
  }
89079
89281
  }
89282
+ if (sinPieza.size > 0) {
89283
+ const total = [...sinPieza.values()].reduce((a, b) => a + b, 0);
89284
+ avisos.push(
89285
+ `La bater\xEDa "${pista.name}" trae ${total} golpe(s) de piezas que el kit todav\xEDa no tiene (n\xFAmeros ${[...sinPieza.keys()].join(", ")}): no se importaron, para no cambiarlas por otra pieza.`
89286
+ );
89287
+ }
89080
89288
  }
89081
89289
  }
89082
89290
  if (letrasDobles.cuantas > 0) {
@@ -89084,6 +89292,11 @@ function importarScore(score, opciones = {}, datos = {}) {
89084
89292
  `${letrasDobles.cuantas} golpe(s) tra\xEDan letra Y un texto libre: se guard\xF3 la letra. Tabs lleva un solo texto por golpe.`
89085
89293
  );
89086
89294
  }
89295
+ if (letrasDobles.versosDeMas > 0) {
89296
+ avisos.push(
89297
+ `${letrasDobles.versosDeMas} golpe(s) tra\xEDan letra de un segundo verso o m\xE1s: se guard\xF3 el primero. Tabs lleva un rengl\xF3n de letra.`
89298
+ );
89299
+ }
89087
89300
  const audioEmbebido = importarAudioYSync(score, documento, idsDeCompasMaestro, avisos);
89088
89301
  return { documento, avisos, ...audioEmbebido ? { audioEmbebido } : {} };
89089
89302
  }
@@ -89128,11 +89341,43 @@ function importarAudioYSync(score, documento, idsDeCompasMaestro, avisos) {
89128
89341
  }
89129
89342
  return { fuenteId, bytes };
89130
89343
  }
89344
+ function saltosDelTexto(score) {
89345
+ const precisos = /* @__PURE__ */ new Map();
89346
+ const textos = /* @__PURE__ */ new Set();
89347
+ for (const pista of score.tracks)
89348
+ for (const pentagrama of pista.staves)
89349
+ for (const barra of pentagrama.bars) {
89350
+ const maestro = score.masterBars[barra.index];
89351
+ if (!maestro?.directions) continue;
89352
+ for (const voz of barra.voices)
89353
+ for (const golpe of voz.beats) {
89354
+ const regla = golpe.text ? SALTO_POR_TEXTO[claveDeSalto(golpe.text)] : void 0;
89355
+ if (!regla) continue;
89356
+ const actuales = precisos.get(maestro.index) ?? new Set(maestro.directions);
89357
+ if (!actuales.has(regla[0]) && !actuales.has(regla[1])) continue;
89358
+ actuales.delete(regla[0]);
89359
+ actuales.add(regla[1]);
89360
+ precisos.set(maestro.index, actuales);
89361
+ textos.add(golpe);
89362
+ }
89363
+ }
89364
+ return { precisos, textos };
89365
+ }
89366
+ function tonalidadDeConcierto(score, indice) {
89367
+ const pentagramas = score.tracks.flatMap((t) => t.staves).filter((s) => !s.isPercussion);
89368
+ const llano = pentagramas.find((s) => !s.displayTranspositionPitch && s.bars[indice]);
89369
+ if (llano) return llano.bars[indice].keySignature;
89370
+ const primero = pentagramas.find((s) => s.bars[indice]);
89371
+ if (!primero) return score.masterBars[indice]?.keySignature ?? 0;
89372
+ return armaduraDeConcierto(primero.bars[indice].keySignature, primero.displayTranspositionPitch);
89373
+ }
89131
89374
  function numeroDeTonalidad(armadura) {
89132
89375
  return armadura;
89133
89376
  }
89134
89377
  function textoDelGolpe(golpe, letrasDobles) {
89135
- const letra = (golpe.lyrics ?? []).find((l) => l && l.trim()) ?? "";
89378
+ const versos = golpe.lyrics ?? [];
89379
+ const letra = versos[0]?.trim() ? versos[0] : "";
89380
+ if (versos.slice(1).some((v) => v && v.trim())) letrasDobles.versosDeMas++;
89136
89381
  const libre = golpe.text ?? "";
89137
89382
  if (letra && libre && letra !== libre) letrasDobles.cuantas++;
89138
89383
  return letra || libre;
@@ -89170,24 +89415,107 @@ function ortografiaDe(ortografia, parte, pentagrama, compas, tic, nota) {
89170
89415
  const base = `${parte}|${pentagrama}|${compas}|${tic}|`;
89171
89416
  return ortografia.get(base + nota.calculateRealValue(false, false)) ?? ortografia.get(base + (nota.octave * 12 + nota.tone));
89172
89417
  }
89418
+ var SALIDA_DE_ID_GP, PARIENTE_GM, DIR, SALTO_POR_TEXTO, claveDeSalto;
89173
89419
  var init_importarGp = __esm({
89174
89420
  "packages/io/src/importarGp.ts"() {
89175
89421
  init_alphaTab();
89176
89422
  init_src2();
89423
+ init_src2();
89177
89424
  init_musicxmlEntrada();
89425
+ SALIDA_DE_ID_GP = {
89426
+ 31: 40,
89427
+ 83: 53,
89428
+ 84: 53,
89429
+ 91: 38,
89430
+ 92: 46,
89431
+ 93: 51,
89432
+ 94: 51,
89433
+ 95: 55,
89434
+ 96: 52,
89435
+ 97: 49,
89436
+ 98: 57,
89437
+ 99: 56,
89438
+ 100: 56,
89439
+ 101: 56,
89440
+ 102: 56,
89441
+ 103: 56,
89442
+ 104: 60,
89443
+ 105: 60,
89444
+ 106: 61,
89445
+ 107: 61,
89446
+ 108: 64,
89447
+ 109: 64,
89448
+ 110: 63,
89449
+ 111: 54,
89450
+ 112: 54,
89451
+ 113: 54,
89452
+ 114: 43,
89453
+ 115: 49,
89454
+ 116: 49,
89455
+ 117: 69,
89456
+ 118: 70,
89457
+ 119: 70,
89458
+ 120: 70,
89459
+ 122: 82,
89460
+ 123: 53,
89461
+ 124: 62,
89462
+ 125: 62,
89463
+ 126: 59,
89464
+ 127: 59
89465
+ };
89466
+ PARIENTE_GM = {
89467
+ 35: 36,
89468
+ // bombo acústico → bombo
89469
+ 40: 38,
89470
+ // caja eléctrica → caja
89471
+ 43: 41,
89472
+ // tom de piso agudo → tom de piso
89473
+ 47: 45,
89474
+ // tom medio grave → tom medio
89475
+ 50: 48,
89476
+ // tom muy agudo → tom agudo
89477
+ 57: 49,
89478
+ // crash 2 → crash
89479
+ 59: 51
89480
+ // ride 2 → ride
89481
+ };
89482
+ DIR = _barrel_exports$4.Direction;
89483
+ SALTO_POR_TEXTO = {
89484
+ dsalcoda: [DIR.JumpDalSegno, DIR.JumpDalSegnoAlCoda],
89485
+ dsalcoda2: [DIR.JumpDalSegno, DIR.JumpDalSegnoAlDoubleCoda],
89486
+ dsalfine: [DIR.JumpDalSegno, DIR.JumpDalSegnoAlFine],
89487
+ dssalcoda: [DIR.JumpDalSegno, DIR.JumpDalSegnoSegnoAlCoda],
89488
+ dssalfine: [DIR.JumpDalSegno, DIR.JumpDalSegnoSegnoAlFine],
89489
+ dss: [DIR.JumpDalSegno, DIR.JumpDalSegnoSegno],
89490
+ dcalcoda: [DIR.JumpDaCapo, DIR.JumpDaCapoAlCoda],
89491
+ dcalcoda2: [DIR.JumpDaCapo, DIR.JumpDaCapoAlDoubleCoda],
89492
+ dcalfine: [DIR.JumpDaCapo, DIR.JumpDaCapoAlFine],
89493
+ ds: [DIR.JumpDalSegno, DIR.JumpDalSegno],
89494
+ dc: [DIR.JumpDaCapo, DIR.JumpDaCapo],
89495
+ tocoda: [DIR.JumpDaCoda, DIR.JumpDaCoda],
89496
+ tocoda2: [DIR.JumpDaCoda, DIR.JumpDaDoubleCoda],
89497
+ fine: [DIR.TargetFine, DIR.TargetFine]
89498
+ };
89499
+ claveDeSalto = (texto4) => texto4.toLowerCase().replace(/dals*segno/g, "ds").replace(/das*capo/g, "dc").replace(/[^a-z0-9]/g, "");
89178
89500
  }
89179
89501
  });
89180
89502
 
89181
89503
  // packages/io/src/archivoMtabs.ts
89182
89504
  function formatoQueNecesita(documento) {
89183
89505
  for (const pista of documento.pistas.values()) {
89184
- const pentagramas = pista.get("pentagramas");
89185
- if (typeof pentagramas === "number" && pentagramas > 1) return 5;
89186
89506
  const transposicion = pista.get("transposicion");
89187
- if (typeof transposicion === "number" && transposicion !== 0) return 5;
89507
+ if (typeof transposicion === "number" && transposicion !== 0) return 6;
89508
+ }
89509
+ for (const nota of documento.notas.values()) {
89510
+ const v = nota.get("armonicoValor");
89511
+ if (typeof v === "number" && v !== 0) return 6;
89188
89512
  }
89189
89513
  for (const figura of documento.figuras.values()) {
89190
- if (figura.get("octava") !== void 0 || figura.get("tempo") !== void 0) return 5;
89514
+ if (figura.get("octava") !== void 0 || figura.get("tempo") !== void 0) return 6;
89515
+ }
89516
+ for (const pista of documento.pistas.values()) {
89517
+ const pentagramas = pista.get("pentagramas");
89518
+ if (typeof pentagramas === "number" && pentagramas > 1) return 5;
89191
89519
  }
89192
89520
  return 4;
89193
89521
  }
@@ -89234,6 +89562,9 @@ function desempaquetar(bytes) {
89234
89562
  } catch {
89235
89563
  throw new ArchivoIlegible("El manifiesto del archivo est\xE1 da\xF1ado.");
89236
89564
  }
89565
+ if (!manifiesto || typeof manifiesto !== "object") {
89566
+ throw new ArchivoIlegible("El manifiesto del archivo est\xE1 da\xF1ado.");
89567
+ }
89237
89568
  if (!Number.isFinite(manifiesto.formato) || manifiesto.formato > VERSION_DEL_FORMATO) {
89238
89569
  throw new ArchivoIlegible(
89239
89570
  `Este archivo se guard\xF3 con una versi\xF3n m\xE1s nueva de Mandioca Tabs (formato ${manifiesto.formato}; esta versi\xF3n entiende hasta el ${VERSION_DEL_FORMATO}). Abrirlo igual podr\xEDa borrarte lo que esa versi\xF3n guard\xF3.`
@@ -89267,7 +89598,7 @@ var init_archivoMtabs = __esm({
89267
89598
  "packages/io/src/archivoMtabs.ts"() {
89268
89599
  init_esm();
89269
89600
  init_src2();
89270
- VERSION_DEL_FORMATO = 5;
89601
+ VERSION_DEL_FORMATO = 6;
89271
89602
  MANIFIESTO = "mandioca.json";
89272
89603
  DOCUMENTO = "documento.ydoc";
89273
89604
  CARPETA_DE_AUDIO = "audio/";
@@ -89338,7 +89669,7 @@ function gruposDeTresillo(beats) {
89338
89669
  continue;
89339
89670
  }
89340
89671
  let j = i2;
89341
- while (j + 1 < beats.length && beats[j + 1].tupletNumerator === b.tupletNumerator && beats[j + 1].tupletDenominator === b.tupletDenominator)
89672
+ while (j + 1 < beats.length && beats[j + 1].tupletNumerator === b.tupletNumerator && beats[j + 1].tupletDenominator === b.tupletDenominator && (b.tupletGroup === null || beats[j + 1].tupletGroup === b.tupletGroup))
89342
89673
  j++;
89343
89674
  abren.add(i2);
89344
89675
  cierran.add(j);
@@ -89346,6 +89677,16 @@ function gruposDeTresillo(beats) {
89346
89677
  }
89347
89678
  return { abren, cierran };
89348
89679
  }
89680
+ function saltosDelCompas(master) {
89681
+ const s = [];
89682
+ for (const [direccion, salto] of SALTOS) {
89683
+ if (!master?.directions?.has(direccion)) continue;
89684
+ s.push('<direction placement="above">', "<direction-type>");
89685
+ s.push(salto.simbolo ? `<${salto.simbolo}/>` : `<words>${escapar(salto.texto ?? "")}</words>`);
89686
+ s.push("</direction-type>", `<sound ${salto.sonido}/>`, "</direction>");
89687
+ }
89688
+ return s;
89689
+ }
89349
89690
  function nombreDeFigura(duracion) {
89350
89691
  return NOMBRE_DE_LA_FIGURA2.get(duracion) ?? "quarter";
89351
89692
  }
@@ -89370,6 +89711,8 @@ function posicionDePercusion(staffLine) {
89370
89711
  }
89371
89712
  function escribirNota(note, beat, staff, opciones) {
89372
89713
  const s = ["<note>"];
89714
+ const esAdorno = beat.graceType !== _barrel_exports$4.GraceType.None;
89715
+ if (esAdorno) s.push(beat.graceType === _barrel_exports$4.GraceType.BeforeBeat ? "<grace/>" : '<grace slash="yes"/>');
89373
89716
  if (opciones.esAcorde) s.push("<chord/>");
89374
89717
  const esGolpeDeKit = staff.isPercussion && note.percussionArticulation >= 0;
89375
89718
  if (esGolpeDeKit) {
@@ -89391,7 +89734,7 @@ function escribirNota(note, beat, staff, opciones) {
89391
89734
  s.push(`<octave>${octava}</octave>`);
89392
89735
  s.push("</pitch>");
89393
89736
  }
89394
- s.push(`<duration>${opciones.duracion}</duration>`);
89737
+ if (!esAdorno) s.push(`<duration>${opciones.duracion}</duration>`);
89395
89738
  if (note.isTieDestination) s.push('<tie type="stop"/>');
89396
89739
  if (note.isTieOrigin) s.push('<tie type="start"/>');
89397
89740
  const idDeInstrumento = opciones.instrumentos.get(note.percussionArticulation);
@@ -89422,8 +89765,17 @@ function escribirNota(note, beat, staff, opciones) {
89422
89765
  tecnica.push(`<string>${staff.tuning.length - note.string + 1}</string>`);
89423
89766
  tecnica.push(`<fret>${note.fret}</fret>`);
89424
89767
  }
89425
- if (note.isHammerPullOrigin) tecnica.push('<hammer-on type="start">H</hammer-on>');
89426
- if (note.hammerPullOrigin !== null) tecnica.push('<pull-off type="stop">P</pull-off>');
89768
+ const ligado = (desde, hasta) => hasta >= desde ? "hammer-on" : "pull-off";
89769
+ const origen = note.hammerPullOrigin;
89770
+ if (origen !== null) {
89771
+ const nombre = ligado(origen.fret, note.fret);
89772
+ tecnica.push(`<${nombre} type="stop"/>`);
89773
+ }
89774
+ const destino = note.hammerPullDestination;
89775
+ if (note.isHammerPullOrigin && destino) {
89776
+ const nombre = ligado(note.fret, destino.fret);
89777
+ tecnica.push(`<${nombre} type="start">${nombre === "hammer-on" ? "H" : "P"}</${nombre}>`);
89778
+ }
89427
89779
  if (note.harmonicType !== _barrel_exports$4.HarmonicType.None) tecnica.push("<harmonic/>");
89428
89780
  if (beat.isPalmMute) tecnica.push("<other-technical>palm-mute</other-technical>");
89429
89781
  if (beat.isLetRing) tecnica.push("<other-technical>let-ring</other-technical>");
@@ -89447,9 +89799,14 @@ function letraDelGolpe(beat) {
89447
89799
  const s = [];
89448
89800
  beat.lyrics.forEach((verso, i2) => {
89449
89801
  if (!verso) return;
89802
+ const sigue = verso.endsWith("-") && verso.length > 1;
89803
+ let anterior = beat.previousBeat;
89804
+ while (anterior && !anterior.lyrics?.[i2]) anterior = anterior.previousBeat;
89805
+ const viene = !!anterior?.lyrics?.[i2]?.endsWith("-");
89806
+ const silabico = sigue ? viene ? "middle" : "begin" : viene ? "end" : "single";
89450
89807
  s.push(`<lyric number="${i2 + 1}">`);
89451
- s.push("<syllabic>single</syllabic>");
89452
- s.push(...elemento("text", verso));
89808
+ s.push(`<syllabic>${silabico}</syllabic>`);
89809
+ s.push(...elemento("text", sigue ? verso.slice(0, -1) : verso));
89453
89810
  s.push("</lyric>");
89454
89811
  });
89455
89812
  return s;
@@ -89535,7 +89892,7 @@ function exportarMusicXml(score) {
89535
89892
  for (let indiceDeCompas2 = 0; indiceDeCompas2 < cantidadDeCompases; indiceDeCompas2++) {
89536
89893
  const master = score.masterBars[indiceDeCompas2];
89537
89894
  l.push(`<measure number="${indiceDeCompas2 + 1}">`);
89538
- const fifths = master?.keySignature ?? 0;
89895
+ const fifths = (pentagramas[0]?.bars[indiceDeCompas2] ?? pentagramas[0]?.bars[0])?.keySignature ?? master?.keySignature ?? 0;
89539
89896
  const modo = master?.keySignatureType === _barrel_exports$4.KeySignatureType.Minor ? "minor" : "major";
89540
89897
  const armadura = `${fifths}/${modo}`;
89541
89898
  const numerador = master?.timeSignatureNumerator ?? 4;
@@ -89590,10 +89947,15 @@ function exportarMusicXml(score) {
89590
89947
  clavesAnteriores = firmaDeClaves;
89591
89948
  }
89592
89949
  if (cambios.length > 0) l.push("<attributes>", ...cambios, "</attributes>");
89593
- if (master?.isRepeatStart) {
89950
+ const casilla = master?.alternateEndings ?? 0;
89951
+ const casillaAntes = score.masterBars[indiceDeCompas2 - 1]?.alternateEndings ?? 0;
89952
+ const casillaDespues = score.masterBars[indiceDeCompas2 + 1]?.alternateEndings ?? 0;
89953
+ const numerosDeCasilla = [0, 1, 2, 3, 4, 5, 6, 7].filter((b) => casilla & 1 << b).map((b) => b + 1).join(", ");
89954
+ if (master?.isRepeatStart || casilla && casilla !== casillaAntes) {
89594
89955
  l.push('<barline location="left">');
89595
- l.push("<bar-style>heavy-light</bar-style>");
89596
- l.push('<repeat direction="forward"/>');
89956
+ if (master?.isRepeatStart) l.push("<bar-style>heavy-light</bar-style>");
89957
+ if (casilla && casilla !== casillaAntes) l.push(`<ending number="${numerosDeCasilla}" type="start"/>`);
89958
+ if (master?.isRepeatStart) l.push('<repeat direction="forward"/>');
89597
89959
  l.push("</barline>");
89598
89960
  }
89599
89961
  if (master?.section?.text || master?.section?.marker)
@@ -89604,8 +89966,14 @@ function exportarMusicXml(score) {
89604
89966
  "</direction-type>",
89605
89967
  "</direction>"
89606
89968
  );
89607
- if (indiceDeCompas2 === 0 && score.tempo) {
89608
- const bpm = Math.round(score.tempo);
89969
+ l.push(...saltosDelCompas(master));
89970
+ const ticsDelCompas = DIVISIONES_POR_NEGRA * 4 * numerador / denominador;
89971
+ const tempos = (master?.tempoAutomations ?? []).map((a) => ({ bpm: a.value, desde: a.ratioPosition }));
89972
+ if (indiceDeCompas2 === 0 && score.tempo && !tempos.some((t) => t.desde <= 1e-6))
89973
+ tempos.unshift({ bpm: score.tempo, desde: 0 });
89974
+ for (const t of tempos) {
89975
+ const bpm = Math.round(t.bpm);
89976
+ const offset = Math.round(t.desde * ticsDelCompas);
89609
89977
  l.push(
89610
89978
  '<direction placement="above">',
89611
89979
  "<direction-type>",
@@ -89614,6 +89982,7 @@ function exportarMusicXml(score) {
89614
89982
  `<per-minute>${bpm}</per-minute>`,
89615
89983
  "</metronome>",
89616
89984
  "</direction-type>",
89985
+ ...offset > 0 ? [`<offset>${offset}</offset>`] : [],
89617
89986
  `<sound tempo="${bpm}"/>`,
89618
89987
  "</direction>"
89619
89988
  );
@@ -89632,7 +90001,7 @@ function exportarMusicXml(score) {
89632
90001
  let avance = 0;
89633
90002
  voice.beats.forEach((beat, i2) => {
89634
90003
  const duracion = beat.displayDuration;
89635
- avance += duracion;
90004
+ if (beat.graceType === _barrel_exports$4.GraceType.None) avance += duracion;
89636
90005
  if (beat.isRest || beat.notes.length === 0) {
89637
90006
  l.push(...escribirSilencio2(beat, duracion, indiceDeVoz + 1, numeroDePentagrama));
89638
90007
  return;
@@ -89658,10 +90027,14 @@ function exportarMusicXml(score) {
89658
90027
  hayAlgoEscrito = true;
89659
90028
  });
89660
90029
  }
89661
- if (master?.isRepeatEnd || master?.isDoubleBar) {
90030
+ const cierraCasilla = casilla !== 0 && casilla !== casillaDespues;
90031
+ if (master?.isRepeatEnd || master?.isDoubleBar || cierraCasilla) {
89662
90032
  l.push('<barline location="right">');
89663
- l.push(`<bar-style>${master.isRepeatEnd ? "light-heavy" : "light-light"}</bar-style>`);
89664
- if (master.isRepeatEnd)
90033
+ if (master?.isRepeatEnd || master?.isDoubleBar)
90034
+ l.push(`<bar-style>${master.isRepeatEnd ? "light-heavy" : "light-light"}</bar-style>`);
90035
+ if (cierraCasilla)
90036
+ l.push(`<ending number="${numerosDeCasilla}" type="${master?.isRepeatEnd ? "stop" : "discontinue"}"/>`);
90037
+ if (master?.isRepeatEnd)
89665
90038
  l.push(`<repeat direction="backward" times="${Math.max(2, master.repeatCount)}"/>`);
89666
90039
  l.push("</barline>");
89667
90040
  }
@@ -89706,7 +90079,7 @@ function exportarMusicXmlComprimido(score) {
89706
90079
  { mtime: FECHA_FIJA_DEL_ZIP }
89707
90080
  );
89708
90081
  }
89709
- var DIVISIONES_POR_NEGRA, FECHA_FIJA_DEL_ZIP, PASOS, NOMBRE_DE_LA_FIGURA2, ALTERACION_POR_MODO;
90082
+ var DIVISIONES_POR_NEGRA, FECHA_FIJA_DEL_ZIP, PASOS, NOMBRE_DE_LA_FIGURA2, ALTERACION_POR_MODO, D, SALTOS;
89710
90083
  var init_musicxml = __esm({
89711
90084
  "packages/io/src/musicxml.ts"() {
89712
90085
  init_alphaTab();
@@ -89736,6 +90109,28 @@ var init_musicxml = __esm({
89736
90109
  [256, "256th"]
89737
90110
  ]);
89738
90111
  ALTERACION_POR_MODO = { 2: 0, 3: 1, 4: 2, 5: -1, 6: -2 };
90112
+ D = _barrel_exports$4.Direction;
90113
+ SALTOS = [
90114
+ [D.TargetSegno, { simbolo: "segno", sonido: 'segno="segno"' }],
90115
+ [D.TargetSegnoSegno, { simbolo: "segno", sonido: 'segno="segno2"' }],
90116
+ [D.TargetCoda, { simbolo: "coda", sonido: 'coda="coda"' }],
90117
+ [D.TargetDoubleCoda, { simbolo: "coda", sonido: 'coda="coda2"' }],
90118
+ [D.TargetFine, { texto: "Fine", sonido: 'fine="yes"' }],
90119
+ [D.JumpDaCapo, { texto: "D.C.", sonido: 'dacapo="yes"' }],
90120
+ [D.JumpDaCapoAlCoda, { texto: "D.C. al Coda", sonido: 'dacapo="yes"' }],
90121
+ [D.JumpDaCapoAlDoubleCoda, { texto: "D.C. al Coda 2", sonido: 'dacapo="yes"' }],
90122
+ [D.JumpDaCapoAlFine, { texto: "D.C. al Fine", sonido: 'dacapo="yes"' }],
90123
+ [D.JumpDalSegno, { texto: "D.S.", sonido: 'dalsegno="segno"' }],
90124
+ [D.JumpDalSegnoAlCoda, { texto: "D.S. al Coda", sonido: 'dalsegno="segno"' }],
90125
+ [D.JumpDalSegnoAlDoubleCoda, { texto: "D.S. al Coda 2", sonido: 'dalsegno="segno"' }],
90126
+ [D.JumpDalSegnoAlFine, { texto: "D.S. al Fine", sonido: 'dalsegno="segno"' }],
90127
+ [D.JumpDalSegnoSegno, { texto: "D.S.S.", sonido: 'dalsegno="segno2"' }],
90128
+ [D.JumpDalSegnoSegnoAlCoda, { texto: "D.S.S. al Coda", sonido: 'dalsegno="segno2"' }],
90129
+ [D.JumpDalSegnoSegnoAlDoubleCoda, { texto: "D.S.S. al Coda 2", sonido: 'dalsegno="segno2"' }],
90130
+ [D.JumpDalSegnoSegnoAlFine, { texto: "D.S.S. al Fine", sonido: 'dalsegno="segno2"' }],
90131
+ [D.JumpDaCoda, { texto: "To Coda", sonido: 'tocoda="coda"' }],
90132
+ [D.JumpDaDoubleCoda, { texto: "To Coda 2", sonido: 'tocoda="coda2"' }]
90133
+ ];
89739
90134
  }
89740
90135
  });
89741
90136
 
@@ -89849,7 +90244,7 @@ var init_src4 = __esm({
89849
90244
  });
89850
90245
 
89851
90246
  // apps/mcp/src/obra.ts
89852
- import { readFile, writeFile } from "node:fs/promises";
90247
+ import { readFile, rename, writeFile } from "node:fs/promises";
89853
90248
  import { extname, basename } from "node:path";
89854
90249
  function reconciliarGrabaciones(obra) {
89855
90250
  const fichas = new Set(obra.documento.fuentesDeAudioEnOrden().map((f) => f.id));
@@ -89992,7 +90387,9 @@ async function guardar(rutaPedida) {
89992
90387
  fuentes: obra.fuentes,
89993
90388
  guardado: (/* @__PURE__ */ new Date()).toISOString()
89994
90389
  });
89995
- await writeFile(ruta, paquete);
90390
+ const parcial = `${ruta}.guardando`;
90391
+ await writeFile(parcial, paquete);
90392
+ await rename(parcial, ruta);
89996
90393
  const fichas = new Set(obra.documento.fuentesDeAudioEnOrden().map((f) => f.id));
89997
90394
  const conBytes = new Set(obra.grabaciones.map((g) => g.fuenteId));
89998
90395
  const mudas = [...fichas].filter((id2) => !conBytes.has(id2)).length;
@@ -90072,7 +90469,7 @@ var VERSION_DEL_CONECTOR;
90072
90469
  var init_version = __esm({
90073
90470
  "apps/mcp/src/version.ts"() {
90074
90471
  "use strict";
90075
- VERSION_DEL_CONECTOR = true ? "0.2.14" : null;
90472
+ VERSION_DEL_CONECTOR = true ? "0.2.15" : null;
90076
90473
  }
90077
90474
  });
90078
90475
 
@@ -90424,7 +90821,13 @@ function abrirDeVerdad(puerto) {
90424
90821
  );
90425
90822
  });
90426
90823
  servidor2.on("connection", (conexion, peticion) => {
90427
- const pedida = decodeURIComponent((peticion.url ?? "").replace(/^\/+/, "").split("?")[0] ?? "");
90824
+ let pedida;
90825
+ try {
90826
+ pedida = decodeURIComponent((peticion.url ?? "").replace(/^\/+/, "").split("?")[0] ?? "");
90827
+ } catch {
90828
+ conexion.close(1008, "sala mal escrita");
90829
+ return;
90830
+ }
90428
90831
  const sala = salaValida(pedida) ? pedida : SALA_DE_LA_OBRA;
90429
90832
  const doc = docDeLaSala(sala);
90430
90833
  if (esDeObra(sala) && deLaSala(sala).length > 0) {
@@ -90574,7 +90977,7 @@ async function pedirALaPesta\u00F1a(herramienta, argumentos = {}, msDelAcuse = E
90574
90977
  const p = exigirPesta\u00F1a();
90575
90978
  const canal = await canalDePedidos(p, herramienta);
90576
90979
  const mapa = canal.getMap("pedidos");
90577
- const id2 = `p${siguienteId += 1}`;
90980
+ const id2 = `p${INSTANCIA}-${siguienteId += 1}`;
90578
90981
  try {
90579
90982
  return await new Promise((resolver, rechazar) => {
90580
90983
  let acusado = false;
@@ -90632,7 +91035,7 @@ async function pedirALaPesta\u00F1a(herramienta, argumentos = {}, msDelAcuse = E
90632
91035
  canal.transact(() => mapa.delete(id2));
90633
91036
  }
90634
91037
  }
90635
- var envoltoriosPorDoc, SINCRONIZAR, PRESENCIA, SALA_DE_LA_OBRA, SALA_DE_PEDIDOS, PUERTO_POR_OMISION, ORIGENES_DE_TABS, puente, reclamado, ESPERA_POR_LA_PESTA\u00D1A, mostrador, casillero, TIPOS, abriendo, siguienteId, ESPERA_DEL_ACUSE_MS, LATIDO_MS, LATIDO_DEL_PUENTE_MS, AUSENCIA_PARA_DARLA_POR_IDA_MS, MARGEN_PARA_QUE_ENTRE_MS;
91038
+ var envoltoriosPorDoc, SINCRONIZAR, PRESENCIA, SALA_DE_LA_OBRA, SALA_DE_PEDIDOS, PUERTO_POR_OMISION, ORIGENES_DE_TABS, puente, reclamado, ESPERA_POR_LA_PESTA\u00D1A, mostrador, casillero, TIPOS, abriendo, siguienteId, INSTANCIA, ESPERA_DEL_ACUSE_MS, LATIDO_MS, LATIDO_DEL_PUENTE_MS, AUSENCIA_PARA_DARLA_POR_IDA_MS, MARGEN_PARA_QUE_ENTRE_MS;
90636
91039
  var init_puente = __esm({
90637
91040
  "apps/mcp/src/puente.ts"() {
90638
91041
  "use strict";
@@ -90666,6 +91069,7 @@ var init_puente = __esm({
90666
91069
  );
90667
91070
  abriendo = null;
90668
91071
  siguienteId = 0;
91072
+ INSTANCIA = `${Date.now().toString(36)}${Math.random().toString(36).slice(2, 8)}`;
90669
91073
  ESPERA_DEL_ACUSE_MS = Number(process.env["MANDIOCA_TABS_ACUSE_MS"] ?? 5e3);
90670
91074
  LATIDO_MS = 250;
90671
91075
  LATIDO_DEL_PUENTE_MS = 1e4;
@@ -97994,6 +98398,48 @@ var init_estilo = __esm({
97994
98398
  });
97995
98399
 
97996
98400
  // packages/projection/src/proyectar.ts
98401
+ function silenciosQueLlenan(tics) {
98402
+ const valores = [];
98403
+ let quedan = tics;
98404
+ for (const valor of [1, 2, 4, 8, 16, 32, 64]) {
98405
+ const dura = 3840 / valor;
98406
+ while (quedan >= dura) {
98407
+ valores.push(valor);
98408
+ quedan -= dura;
98409
+ }
98410
+ }
98411
+ return valores;
98412
+ }
98413
+ function valorDeArmonicoNatural(traste) {
98414
+ switch (traste) {
98415
+ case 2:
98416
+ return 2.4;
98417
+ case 3:
98418
+ return 3.2;
98419
+ case 4:
98420
+ case 5:
98421
+ case 7:
98422
+ case 9:
98423
+ case 12:
98424
+ case 16:
98425
+ case 17:
98426
+ case 19:
98427
+ case 24:
98428
+ return traste;
98429
+ case 8:
98430
+ return 8.2;
98431
+ case 10:
98432
+ return 9.6;
98433
+ case 14:
98434
+ case 15:
98435
+ return 14.7;
98436
+ case 21:
98437
+ case 22:
98438
+ return 21.7;
98439
+ default:
98440
+ return 12;
98441
+ }
98442
+ }
97997
98443
  function canalesDeLasPistas(tipos) {
97998
98444
  const libres = Array.from({ length: 16 }, (_, i2) => i2).filter((c) => c !== 9);
97999
98445
  const conAltura = tipos.filter((t) => t !== "percusion").length;
@@ -98147,20 +98593,24 @@ function proyectar(documento, opciones = {}) {
98147
98593
  cantidadDeVoces = Math.max(cantidadDeVoces, datos2.voz + 1);
98148
98594
  }
98149
98595
  }
98596
+ const deLaPista = [...compasesPorPista.entries()].filter(([clave]) => clave.startsWith(`${idPista}|`)).map(([, mapa]) => mapa);
98150
98597
  const acordesEscritos = [];
98151
98598
  maestros.forEach((m, indiceDeCompas2) => {
98152
- const id2 = porMaestro.get(m.id);
98153
- for (const { datos: f } of id2 ? figurasPorCompas.get(id2) ?? [] : []) {
98154
- if (f.acorde) {
98155
- acordesEscritos.push({ compas: indiceDeCompas2, tiempo: f.tiempo, nombre: f.acorde });
98599
+ for (const mapa of deLaPista) {
98600
+ const id2 = mapa.get(m.id);
98601
+ for (const { datos: f } of id2 ? figurasPorCompas.get(id2) ?? [] : []) {
98602
+ if (f.acorde) {
98603
+ acordesEscritos.push({ compas: indiceDeCompas2, tiempo: f.tiempo, nombre: f.acorde });
98604
+ }
98156
98605
  }
98157
98606
  }
98158
98607
  });
98608
+ acordesEscritos.sort((a, b) => a.compas - b.compas || a.tiempo - b.tiempo);
98159
98609
  const acordeVigente = buscadorDeAcorde(acordesEscritos);
98160
98610
  maestros.forEach((maestro, indiceDeCompas2) => {
98161
98611
  const barra = new _barrel_exports$4.Bar();
98162
98612
  pentagrama.addBar(barra);
98163
- barra.keySignature = maestro.datos.tonalidad;
98613
+ barra.keySignature = armaduraEscrita(maestro.datos.tonalidad, pista.transposicion ?? 0);
98164
98614
  barra.simileMark = maestro.datos.repiteAnterior;
98165
98615
  const idCompas = porMaestro.get(maestro.id);
98166
98616
  const figuras = idCompas ? figurasPorCompas.get(idCompas) ?? [] : [];
@@ -98170,8 +98620,8 @@ function proyectar(documento, opciones = {}) {
98170
98620
  barra.clefOttava = datosDelCompas.claveOctava;
98171
98621
  }
98172
98622
  const ticsDelCompas = 960 * 4 * maestro.datos.numerador / maestro.datos.denominador;
98173
- for (const { datos: figura } of figuras) {
98174
- if (!figura.pedal) continue;
98623
+ const conPedal = figuras.map((f) => f.datos).filter((f) => f.pedal).sort((a, b) => a.tiempo - b.tiempo).filter((f, k, todas) => k === 0 || todas[k - 1].tiempo !== f.tiempo);
98624
+ for (const figura of conPedal) {
98175
98625
  const marcador = new _barrel_exports$4.SustainPedalMarker();
98176
98626
  marcador.ratioPosition = ticsDelCompas > 0 ? figura.tiempo / ticsDelCompas : 0;
98177
98627
  marcador.pedalType = figura.pedal - 1;
@@ -98181,7 +98631,17 @@ function proyectar(documento, opciones = {}) {
98181
98631
  const voz = new _barrel_exports$4.Voice();
98182
98632
  barra.addVoice(voz);
98183
98633
  const deEstaVoz = figuras.filter((f) => f.datos.voz === indiceDeVoz).sort((a, b) => a.datos.tiempo - b.datos.tiempo);
98634
+ let posicion = 0;
98184
98635
  for (const { id: idFigura, datos: figura } of deEstaVoz) {
98636
+ if (!figura.adorno && figura.tiempo - posicion >= 30) {
98637
+ for (const valor of silenciosQueLlenan(figura.tiempo - Math.round(posicion))) {
98638
+ const silencio = new _barrel_exports$4.Beat();
98639
+ silencio.duration = valor;
98640
+ voz.addBeat(silencio);
98641
+ }
98642
+ posicion = figura.tiempo;
98643
+ }
98644
+ posicion += figura.adorno ? 0 : ticsExactosDeFigura(figura);
98185
98645
  const golpe = new _barrel_exports$4.Beat();
98186
98646
  golpe.duration = figura.valor;
98187
98647
  golpe.dots = figura.puntillos;
@@ -98270,6 +98730,8 @@ function proyectar(documento, opciones = {}) {
98270
98730
  notaAlphaTab.slideInType = nota.deslizamientoEntrada;
98271
98731
  notaAlphaTab.slideOutType = nota.deslizamientoSalida;
98272
98732
  notaAlphaTab.harmonicType = nota.armonico;
98733
+ if (nota.armonico)
98734
+ notaAlphaTab.harmonicValue = nota.armonicoValor || (nota.armonico === _barrel_exports$4.HarmonicType.Natural ? valorDeArmonicoNatural(nota.traste) : 12);
98273
98735
  notaAlphaTab.vibrato = nota.anchoDeVibrato;
98274
98736
  notaAlphaTab.accentuated = nota.acento;
98275
98737
  notaAlphaTab.isLeftHandTapped = nota.tappingIzquierda;
@@ -122593,7 +123055,16 @@ function duracionDesde(figura, puntillos) {
122593
123055
  return { valor: figura, puntillos: puntillos ?? 0 };
122594
123056
  }
122595
123057
  function ticsDelGolpe(indice, pistaId, compas, voz, golpe, tics, pentagrama = 0) {
122596
- if (tics !== void 0) return tics;
123058
+ if (tics !== void 0) {
123059
+ const maestro = indice.compasMaestro(compas);
123060
+ const largo = maestro ? 3840 * maestro.datos.numerador / maestro.datos.denominador : 3840;
123061
+ if (!Number.isInteger(tics) || tics < 0 || tics >= largo) {
123062
+ throw new ProblemaConLaObra(
123063
+ `${tics} tics queda fuera del comp\xE1s ${compas + 1}, que mide ${largo} (de 0 a ${largo - 1}; 960 por negra).`
123064
+ );
123065
+ }
123066
+ return tics;
123067
+ }
122597
123068
  if (golpe === void 0) return 0;
122598
123069
  const compasId = indice.compasId(pistaId, compas, pentagrama);
122599
123070
  const figuras = indice.figuras(compasId, voz);
@@ -122642,7 +123113,7 @@ function segundaParaLeer(texto4, marcas) {
122642
123113
  // apps/mcp/src/herramientas/documento.ts
122643
123114
  var unaNota = {
122644
123115
  compas: external_exports.number().int().min(1).max(9999),
122645
- cuerda: external_exports.number().int().min(1).max(24, { error: (i2) => `\xAB${i2.input}\xBB no es una cuerda: van de 1 (la m\xE1s grave) a 24.` }).optional().describe("La cuerda, numerada desde la M\xC1S GRAVE empezando en 1. En una guitarra est\xE1ndar, 1 es el mi grave y 6 el mi agudo. Solo en pistas de tablatura."),
123116
+ cuerda: external_exports.number().int().min(1).max(24, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB no es una cuerda: van de 1 (la m\xE1s grave) a 24.` }).optional().describe("La cuerda, numerada desde la M\xC1S GRAVE empezando en 1. En una guitarra est\xE1ndar, 1 es el mi grave y 6 el mi agudo. Solo en pistas de tablatura."),
122646
123117
  altura: external_exports.number().int().min(0).max(127).optional().describe("La altura en n\xFAmero MIDI: 60 es el Do central. Solo en pistas de altura (piano, vientos, cuerdas frotadas, voz)."),
122647
123118
  pieza: external_exports.string().optional().describe("La pieza del kit: \xABBombo\xBB, \xABCaja\xBB, \xABCharles cerrado\xBB\u2026 Solo en pistas de percusi\xF3n. La lista entera la da `piezas_de_bateria`."),
122648
123119
  golpe: external_exports.number().int().min(1).max(999).optional(),
@@ -122917,7 +123388,7 @@ function registrarHerramientasDelDocumento(servidor2) {
122917
123388
  title: "Leer un pasaje",
122918
123389
  description: "La m\xFAsica de un rango de compases: cada golpe con su duraci\xF3n, y cada nota con su cuerda, su traste, su altura MIDI y sus efectos.",
122919
123390
  inputSchema: {
122920
- desde: external_exports.number().int().min(1).max(9999, { error: (i2) => `\xAB${i2.input}\xBB se pasa: va de 1 a 9999.` }).describe("Primer comp\xE1s, como lo lee el m\xFAsico."),
123391
+ desde: external_exports.number().int().min(1).max(9999, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB se pasa: va de 1 a 9999.` }).describe("Primer comp\xE1s, como lo lee el m\xFAsico."),
122921
123392
  hasta: external_exports.number().int().min(1).max(9999).optional().describe("\xDAltimo comp\xE1s, incluido. Por omisi\xF3n, el mismo que `desde`."),
122922
123393
  pista: external_exports.number().int().min(1).max(999).optional().describe("Cu\xE1l pista. Por omisi\xF3n, todas.")
122923
123394
  }
@@ -122974,7 +123445,7 @@ function registrarHerramientasDelDocumento(servidor2) {
122974
123445
  description: "Escribe notas en el golpe que se le diga. **C\xF3mo se nombra cada nota depende del tipo de la pista**: en una de tablatura (guitarra, bajo) se dan `cuerda` y `traste`; en una de altura (piano, vientos, voz) se da `altura`, el n\xFAmero MIDI. Varias notas en el mismo comp\xE1s y el mismo golpe forman un acorde. Es exactamente lo que hace el m\xFAsico en el pliego: usa el mismo comando del editor, as\xED que respeta el retejido de la voz y entra en el deshacer.",
122975
123446
  inputSchema: {
122976
123447
  pista: external_exports.number().int().min(1).max(999).optional(),
122977
- figura: external_exports.number().int().min(1).max(64, { error: (i2) => `\xAB${i2.input}\xBB no es una figura: 1 redonda, 2 blanca, 4 negra, 8 corchea, 16, 32, 64.` }).optional().describe("La duraci\xF3n: 1 redonda, 2 blanca, 4 negra, 8 corchea, 16 semicorchea, 32, 64. Por omisi\xF3n, negra."),
123448
+ figura: external_exports.number().int().min(1).max(64, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB no es una figura: 1 redonda, 2 blanca, 4 negra, 8 corchea, 16, 32, 64.` }).optional().describe("La duraci\xF3n: 1 redonda, 2 blanca, 4 negra, 8 corchea, 16 semicorchea, 32, 64. Por omisi\xF3n, negra."),
122978
123449
  puntillos: external_exports.number().int().min(0).max(2).optional(),
122979
123450
  notas: external_exports.array(external_exports.object({ ...unaNota, traste: external_exports.number().int().min(0).max(24).optional().describe("El traste. 0 es la cuerda al aire. Solo en pistas de tablatura.") })).min(1).describe("Las notas a escribir, en orden.")
122980
123451
  }
@@ -122984,62 +123455,69 @@ function registrarHerramientasDelDocumento(servidor2) {
122984
123455
  empezarUnPaso();
122985
123456
  const duracion = duracionDesde(figura, puntillos);
122986
123457
  const escritas = [];
122987
- for (const nota of notas) {
122988
- const indice = indexar(documento);
122989
- const volcado = volcar(documento);
122990
- const laPista = pistaDelMusico(pista ?? 1, volcado, documento);
122991
- const pistaId = laPista.id;
122992
- const compas = indiceDeCompas(nota.compas, indice);
122993
- const voz = (nota.voz ?? 1) - 1;
122994
- const pentagrama = pentagramaDelMusico(nota.pentagrama, indice, pistaId, pista ?? 1);
122995
- const tiempo = ticsDelGolpe(indice, pistaId, compas, voz, nota.golpe, nota.tics, pentagrama);
122996
- const nombrada = comoSeEscribeLaNota(laPista.tipo, laPista.nombre, pista ?? 1, nota);
122997
- if (nombrada.clase === "altura") {
122998
- const resultado2 = escribirAltura(
122999
- documento,
123000
- indice,
123001
- cursorEn(indice, pistaId, compas, voz, tiempo, 1, pentagrama),
123002
- nombrada.altura,
123003
- duracion ? { duracion } : {}
123004
- );
123005
- if (!resultado2) {
123006
- throw new ProblemaConLaObra(
123007
- `No se pudo escribir la altura ${nombrada.altura} en el comp\xE1s ${nota.compas} de la pista ${pista ?? 1} \xAB${laPista.nombre}\xBB.`
123458
+ const laPista = pistaDelMusico(pista ?? 1, volcar(documento), documento);
123459
+ const pistaId = laPista.id;
123460
+ try {
123461
+ for (const nota of notas) {
123462
+ const indice = indexar(documento);
123463
+ const compas = indiceDeCompas(nota.compas, indice);
123464
+ const voz = (nota.voz ?? 1) - 1;
123465
+ const pentagrama = pentagramaDelMusico(nota.pentagrama, indice, pistaId, pista ?? 1);
123466
+ const tiempo = ticsDelGolpe(indice, pistaId, compas, voz, nota.golpe, nota.tics, pentagrama);
123467
+ const nombrada = comoSeEscribeLaNota(laPista.tipo, laPista.nombre, pista ?? 1, nota);
123468
+ if (nombrada.clase === "altura") {
123469
+ const resultado2 = escribirAltura(
123470
+ documento,
123471
+ indice,
123472
+ cursorEn(indice, pistaId, compas, voz, tiempo, 1, pentagrama),
123473
+ nombrada.altura,
123474
+ duracion ? { duracion } : {}
123008
123475
  );
123476
+ if (!resultado2) {
123477
+ throw new ProblemaConLaObra(
123478
+ `No se pudo escribir la altura ${nombrada.altura} en el comp\xE1s ${nota.compas} de la pista ${pista ?? 1} \xAB${laPista.nombre}\xBB.`
123479
+ );
123480
+ }
123481
+ escritas.push(`c${nota.compas} altura ${nombrada.altura}`);
123482
+ continue;
123009
123483
  }
123010
- escritas.push(`c${nota.compas} altura ${nombrada.altura}`);
123011
- continue;
123012
- }
123013
- if (nombrada.clase === "percusion") {
123014
- const resultado2 = escribirPercusion(
123484
+ if (nombrada.clase === "percusion") {
123485
+ const resultado2 = escribirPercusion(
123486
+ documento,
123487
+ indice,
123488
+ cursorEn(indice, pistaId, compas, voz, tiempo, 1, pentagrama),
123489
+ nombrada.articulacion,
123490
+ duracion ? { duracion } : {}
123491
+ );
123492
+ if (!resultado2) {
123493
+ throw new ProblemaConLaObra(
123494
+ `No se pudo escribir \xAB${nombrada.nombre}\xBB en el comp\xE1s ${nota.compas} de la pista ${pista ?? 1} \xAB${laPista.nombre}\xBB.`
123495
+ );
123496
+ }
123497
+ escritas.push(`c${nota.compas} ${nombrada.nombre}`);
123498
+ continue;
123499
+ }
123500
+ const resultado = escribirTraste(
123015
123501
  documento,
123016
123502
  indice,
123017
- cursorEn(indice, pistaId, compas, voz, tiempo, 1, pentagrama),
123018
- nombrada.articulacion,
123503
+ cursorEn(indice, pistaId, compas, voz, tiempo, nombrada.cuerda, pentagrama),
123504
+ nombrada.cuerda,
123505
+ nombrada.traste,
123019
123506
  duracion ? { duracion } : {}
123020
123507
  );
123021
- if (!resultado2) {
123508
+ if (!resultado) {
123022
123509
  throw new ProblemaConLaObra(
123023
- `No se pudo escribir \xAB${nombrada.nombre}\xBB en el comp\xE1s ${nota.compas} de la pista ${pista ?? 1} \xAB${laPista.nombre}\xBB.`
123510
+ `No se pudo escribir el traste ${nombrada.traste} en la cuerda ${nombrada.cuerda} del comp\xE1s ${nota.compas}. La cuerda ${nombrada.cuerda} puede no existir en esa pista.`
123024
123511
  );
123025
123512
  }
123026
- escritas.push(`c${nota.compas} ${nombrada.nombre}`);
123027
- continue;
123513
+ escritas.push(`c${nota.compas} cuerda ${nombrada.cuerda} traste ${nombrada.traste}`);
123028
123514
  }
123029
- const resultado = escribirTraste(
123030
- documento,
123031
- indice,
123032
- cursorEn(indice, pistaId, compas, voz, tiempo, nombrada.cuerda, pentagrama),
123033
- nombrada.cuerda,
123034
- nombrada.traste,
123035
- duracion ? { duracion } : {}
123515
+ } catch (e) {
123516
+ if (escritas.length > 0) documento.historial().undo();
123517
+ const motivo = e instanceof Error ? e.message : String(e);
123518
+ throw new ProblemaConLaObra(
123519
+ escritas.length > 0 ? `${motivo} No se escribi\xF3 ninguna nota de esta tanda: las ${escritas.length} anteriores se deshicieron.` : motivo
123036
123520
  );
123037
- if (!resultado) {
123038
- throw new ProblemaConLaObra(
123039
- `No se pudo escribir el traste ${nombrada.traste} en la cuerda ${nombrada.cuerda} del comp\xE1s ${nota.compas}. La cuerda ${nombrada.cuerda} puede no existir en esa pista.`
123040
- );
123041
- }
123042
- escritas.push(`c${nota.compas} cuerda ${nombrada.cuerda} traste ${nombrada.traste}`);
123043
123521
  }
123044
123522
  return texto2({ escritas: escritas.length, detalle: escritas });
123045
123523
  }
@@ -123058,11 +123536,10 @@ function registrarHerramientasDelDocumento(servidor2) {
123058
123536
  const { documento } = obraAbierta();
123059
123537
  empezarUnPaso();
123060
123538
  let borradas = 0;
123539
+ const laPista = pistaDelMusico(pista ?? 1, volcar(documento), documento);
123540
+ const pistaId = laPista.id;
123061
123541
  for (const nota of notas) {
123062
123542
  const indice = indexar(documento);
123063
- const volcado = volcar(documento);
123064
- const laPista = pistaDelMusico(pista ?? 1, volcado, documento);
123065
- const pistaId = laPista.id;
123066
123543
  const compas = indiceDeCompas(nota.compas, indice);
123067
123544
  const voz = (nota.voz ?? 1) - 1;
123068
123545
  const pentagrama = pentagramaDelMusico(nota.pentagrama, indice, pistaId, pista ?? 1);
@@ -123323,8 +123800,8 @@ function registrarHerramientasDelPuente(servidor2) {
123323
123800
  title: "Cambiar c\xF3mo se ve la partitura",
123324
123801
  description: "Renglones, horizontal o en hoja, y ver una pista o todas. Sirve para se\xF1alarle algo al m\xFAsico en la maqueta donde se ve mejor.",
123325
123802
  inputSchema: {
123326
- vista: external_exports.enum(["renglones", "horizontal", "hoja"], { error: (i2) => `\xAB${i2.input}\xBB no es una vista: renglones, horizontal u hoja.` }).optional(),
123327
- pistas: external_exports.enum(["una", "todas"], { error: (i2) => `\xAB${i2.input}\xBB no dice cu\xE1ntas pistas: una o todas.` }).optional(),
123803
+ vista: external_exports.enum(["renglones", "horizontal", "hoja"], { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB no es una vista: renglones, horizontal u hoja.` }).optional(),
123804
+ pistas: external_exports.enum(["una", "todas"], { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB no dice cu\xE1ntas pistas: una o todas.` }).optional(),
123328
123805
  /**
123329
123806
  * ★ Los valores son EXACTAMENTE los que ofrece el menú: «los que entren» (−1) y 1, 2,
123330
123807
  * 3, 4, 5, 6, 8, 10, 12. No es una lista caprichosa, es la que el músico puede
@@ -123396,7 +123873,7 @@ function registrarHerramientasDelPuente(servidor2) {
123396
123873
  compas: external_exports.number().int().min(1).max(9999).describe("El primer comp\xE1s, contando desde 1."),
123397
123874
  hasta: external_exports.number().int().min(1).max(9999).optional().describe("El \xFAltimo comp\xE1s, incluido."),
123398
123875
  golpe: external_exports.number().int().min(1).optional().describe("Empezar en un golpe concreto del primer comp\xE1s, en vez de en su comienzo."),
123399
- cuerda: external_exports.number().int().min(1).max(24, { error: (i2) => `\xAB${i2.input}\xBB no es una cuerda: van de 1 (la m\xE1s grave) a 24.` }).optional().describe("La cuerda, desde la m\xE1s grave.")
123876
+ cuerda: external_exports.number().int().min(1).max(24, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB no es una cuerda: van de 1 (la m\xE1s grave) a 24.` }).optional().describe("La cuerda, desde la m\xE1s grave.")
123400
123877
  }
123401
123878
  },
123402
123879
  async (args2) => texto3(await pedirALaPesta\u00F1a("seleccionar", args2))
@@ -123476,7 +123953,7 @@ function registrarHerramientasDelPuente(servidor2) {
123476
123953
  description: "Marca el pulso mientras suena la tablatura. \u2605 Para qu\xE9 sirve: es lo que se prende para **sincronizar a o\xEDdo** \u2014 con el click puesto se escucha enseguida si la grabaci\xF3n entra antes o despu\xE9s del comp\xE1s. \u26A0\uFE0F Suena con el sintetizador de la obra, no con el audio: existe con o sin grabaci\xF3n cargada. \u26A0\uFE0F El pulso lo marca el DENOMINADOR del comp\xE1s: en 6/8 son seis clicks, no dos. \u2605 Mientras est\xE1 puesto aparece como una fila m\xE1s del mezclador, con su volumen. Sin `puesto` ni `volumen`, alterna; con s\xF3lo `volumen`, cambia el volumen y deja el metr\xF3nomo como estaba.",
123477
123954
  inputSchema: {
123478
123955
  puesto: external_exports.boolean().optional().describe("true lo pone, false lo saca. Sin esto, alterna."),
123479
- volumen: external_exports.number().int().min(0).max(16, { error: (i2) => `\xAB${i2.input}\xBB se sale de la escala del volumen, que va de 0 a 16. No es un porcentaje.` }).optional().describe(
123956
+ volumen: external_exports.number().int().min(0).max(16, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB se sale de la escala del volumen, que va de 0 a 16. No es un porcentaje.` }).optional().describe(
123480
123957
  "El volumen del click, de 0 a 16 \u2014la misma escala que `volumen_general`\u2014. Se recuerda aunque se lo saque, y no se guarda en la obra: es de quien escucha."
123481
123958
  )
123482
123959
  }
@@ -123569,7 +124046,7 @@ function registrarHerramientasDelPuente(servidor2) {
123569
124046
  silenciada: external_exports.boolean().optional(),
123570
124047
  enSolo: external_exports.boolean().optional(),
123571
124048
  visible: external_exports.boolean().optional().describe("Mostrarla u ocultarla en el pliego."),
123572
- volumen: external_exports.number().int().min(0).max(32, { error: (i2) => `\xAB${i2.input}\xBB se sale de la escala del volumen, que va de 0 a 32 (16 = como est\xE1 escrito, 32 \u2248 +6 dB). No es un porcentaje.` }).optional().describe("De 0 a 32. 16 = como est\xE1 escrito (0 dB); 32 \u2248 +6 dB."),
124049
+ volumen: external_exports.number().int().min(0).max(32, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB se sale de la escala del volumen, que va de 0 a 32 (16 = como est\xE1 escrito, 32 \u2248 +6 dB). No es un porcentaje.` }).optional().describe("De 0 a 32. 16 = como est\xE1 escrito (0 dB); 32 \u2248 +6 dB."),
123573
124050
  balance: external_exports.number().int().min(0).max(16).optional().describe("El paneo, de 0 a 16. **8 es el centro**, 0 todo a la izquierda y 16 todo a la derecha.")
123574
124051
  }
123575
124052
  },
@@ -123787,7 +124264,7 @@ function registrarHerramientasDelPuente(servidor2) {
123787
124264
  title: "El volumen general de la escucha",
123788
124265
  description: "El master del mezclador: sube o baja TODO junto, la tablatura y la grabaci\xF3n de referencia. \u26A0\uFE0F **No se guarda en la obra.** Es de quien est\xE1 escuchando ahora, igual que silenciar y el solo \u2014 subir el master no es una decisi\xF3n musical, es el volumen del cuarto. Al cerrar vuelve a su valor de arranque. \u26A0\uFE0F Va de **0 a 16**, la misma escala que el volumen de una pista: compartirla evita una tabla de traducci\xF3n, que es donde se cuela el error de conversi\xF3n.",
123789
124266
  inputSchema: {
123790
- volumen: external_exports.number().int().min(0).max(16, { error: (i2) => `\xAB${i2.input}\xBB se sale de la escala del volumen, que va de 0 a 16 (16 = como est\xE1 escrito). No es un porcentaje.` }).describe("De 0 a 16. 0 es mudo.")
124267
+ volumen: external_exports.number().int().min(0).max(16, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB se sale de la escala del volumen, que va de 0 a 16 (16 = como est\xE1 escrito). No es un porcentaje.` }).describe("De 0 a 16. 0 es mudo.")
123791
124268
  }
123792
124269
  },
123793
124270
  async (args2) => texto3(await pedirALaPesta\u00F1a("volumen_general", args2))
@@ -124107,7 +124584,7 @@ function registrarHerramientasDeSignos(servidor2) {
124107
124584
  description: "Los signos que ya est\xE1n puestos en una nota o en un golpe. Sirve para comprobar lo que se escribi\xF3 sin tener que mirar el pliego.",
124108
124585
  inputSchema: {
124109
124586
  compas: external_exports.number().int().min(1).max(9999),
124110
- cuerda: external_exports.number().int().min(1).max(24, { error: (i2) => `\xAB${i2.input}\xBB no es una cuerda: van de 1 (la m\xE1s grave) a 24.` }).describe("La cuerda, desde la m\xE1s grave empezando en 1."),
124587
+ cuerda: external_exports.number().int().min(1).max(24, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB no es una cuerda: van de 1 (la m\xE1s grave) a 24.` }).describe("La cuerda, desde la m\xE1s grave empezando en 1."),
124111
124588
  golpe: external_exports.number().int().min(1).max(999).optional(),
124112
124589
  tics: external_exports.number().int().min(0).max(99999).optional(),
124113
124590
  pista: external_exports.number().int().min(1).max(999).optional(),
@@ -124209,7 +124686,7 @@ function registrarHerramientasDeDuraciones(servidor2) {
124209
124686
  description: "Sube o baja la figura de lo escrito un escal\xF3n: de negra a blanca, de corchea a negra. Es lo que hacen las teclas + y \u2212 en el programa.",
124210
124687
  inputSchema: {
124211
124688
  ...DONDE,
124212
- direccion: external_exports.enum(["mas-larga", "mas-corta"], { error: (i2) => `\xAB${i2.input}\xBB no es una direcci\xF3n: mas-larga o mas-corta.` })
124689
+ direccion: external_exports.enum(["mas-larga", "mas-corta"], { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB no es una direcci\xF3n: mas-larga o mas-corta.` })
124213
124690
  }
124214
124691
  },
124215
124692
  ({ direccion, ...donde }) => {
@@ -124664,7 +125141,7 @@ function registrarHerramientasDeEstructura(servidor2) {
124664
125141
  {
124665
125142
  title: "Agregar compases al final",
124666
125143
  description: "Alarga la obra. Los compases nuevos heredan la cifra de comp\xE1s del \xFAltimo.",
124667
- inputSchema: { cuantos: external_exports.number().int().min(1).max(500, { error: (i2) => `\xAB${i2.input}\xBB son demasiados compases de una vez: van de 1 a 500.` }) }
125144
+ inputSchema: { cuantos: external_exports.number().int().min(1).max(500, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB son demasiados compases de una vez: van de 1 a 500.` }) }
124668
125145
  },
124669
125146
  ({ cuantos }) => {
124670
125147
  const { documento } = obraAbierta();
@@ -124678,8 +125155,8 @@ function registrarHerramientasDeEstructura(servidor2) {
124678
125155
  title: "Insertar un comp\xE1s",
124679
125156
  description: "Mete un comp\xE1s vac\xEDo al lado del que se diga, y corre el resto. \u26A0\uFE0F Hay que decir UNO de los dos: `despuesDel` o `antesDel`. \u2605 `antesDel: 1` mete un comp\xE1s **al principio de la obra**, que es lo que hace falta cuando la grabaci\xF3n entra tarde y hay que dejarle espacio antes de lo ya escrito. El comp\xE1s nuevo hereda la m\xE9trica y la armadura de su vecino, y nunca su secci\xF3n ni sus repeticiones.",
124680
125157
  inputSchema: {
124681
- despuesDel: external_exports.number().int().min(1).max(9999, { error: (i2) => `\xAB${i2.input}\xBB se pasa: los compases van de 1 a 9999.` }).optional().describe("El comp\xE1s despu\xE9s del cual insertar, como lo lee el m\xFAsico."),
124682
- antesDel: external_exports.number().int().min(1).max(9999, { error: (i2) => `\xAB${i2.input}\xBB se pasa: los compases van de 1 a 9999.` }).optional().describe("El comp\xE1s antes del cual insertar. Con 1, al principio de la obra.")
125158
+ despuesDel: external_exports.number().int().min(1).max(9999, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB se pasa: los compases van de 1 a 9999.` }).optional().describe("El comp\xE1s despu\xE9s del cual insertar, como lo lee el m\xFAsico."),
125159
+ antesDel: external_exports.number().int().min(1).max(9999, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB se pasa: los compases van de 1 a 9999.` }).optional().describe("El comp\xE1s antes del cual insertar. Con 1, al principio de la obra.")
124683
125160
  }
124684
125161
  },
124685
125162
  ({ despuesDel, antesDel }) => {
@@ -125230,7 +125707,7 @@ function registrarHerramientasDeMusica(servidor2) {
125230
125707
  inputSchema: {
125231
125708
  ...RANGO,
125232
125709
  hasta: external_exports.number().int().min(1).max(9999),
125233
- semitonos: external_exports.number().int().min(-24).max(24, { error: (i2) => `\xAB${i2.input}\xBB se pasa: se transpone entre -24 y 24 semitonos, o sea dos octavas para cada lado.` })
125710
+ semitonos: external_exports.number().int().min(-24).max(24, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB se pasa: se transpone entre -24 y 24 semitonos, o sea dos octavas para cada lado.` })
125234
125711
  }
125235
125712
  },
125236
125713
  ({ semitonos, ...donde }) => {
@@ -125250,7 +125727,7 @@ function registrarHerramientasDeMusica(servidor2) {
125250
125727
  {
125251
125728
  title: "Deshacer",
125252
125729
  description: "Vuelve atr\xE1s un paso. Es el MISMO historial que el Ctrl+Z del m\xFAsico: si \xE9l escribi\xF3 lo \xFAltimo, esto deshace lo suyo.",
125253
- inputSchema: { pasos: external_exports.number().int().min(1).max(50, { error: (i2) => `\xAB${i2.input}\xBB son demasiados pasos de una vez: van de 1 a 50.` }).optional() }
125730
+ inputSchema: { pasos: external_exports.number().int().min(1).max(50, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB son demasiados pasos de una vez: van de 1 a 50.` }).optional() }
125254
125731
  },
125255
125732
  ({ pasos }) => {
125256
125733
  const { documento } = obraAbierta();
@@ -125269,7 +125746,7 @@ function registrarHerramientasDeMusica(servidor2) {
125269
125746
  {
125270
125747
  title: "Rehacer",
125271
125748
  description: "Vuelve adelante lo que se deshizo.",
125272
- inputSchema: { pasos: external_exports.number().int().min(1).max(50, { error: (i2) => `\xAB${i2.input}\xBB son demasiados pasos de una vez: van de 1 a 50.` }).optional() }
125749
+ inputSchema: { pasos: external_exports.number().int().min(1).max(50, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB son demasiados pasos de una vez: van de 1 a 50.` }).optional() }
125273
125750
  },
125274
125751
  ({ pasos }) => {
125275
125752
  const { documento } = obraAbierta();
@@ -125418,7 +125895,7 @@ function registrarHerramientasDeMusica(servidor2) {
125418
125895
  golpe: external_exports.number().int().min(1).max(999).optional(),
125419
125896
  pista: external_exports.number().int().min(1).max(999).optional(),
125420
125897
  voz: external_exports.number().int().min(1).max(4).optional(),
125421
- figura: external_exports.number().int().min(1).max(64, { error: (i2) => `\xAB${i2.input}\xBB no es una figura: 1 redonda, 2 blanca, 4 negra, 8 corchea, 16, 32, 64.` }).optional().describe("1 redonda, 2 blanca, 4 negra\u2026 Por omisi\xF3n, negra."),
125898
+ figura: external_exports.number().int().min(1).max(64, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB no es una figura: 1 redonda, 2 blanca, 4 negra, 8 corchea, 16, 32, 64.` }).optional().describe("1 redonda, 2 blanca, 4 negra\u2026 Por omisi\xF3n, negra."),
125422
125899
  puntillos: external_exports.number().int().min(0).max(2).optional()
125423
125900
  }
125424
125901
  },
@@ -125503,8 +125980,8 @@ function registrarHerramientasDeMusica(servidor2) {
125503
125980
  description: "\u26A0\uFE0F CONSERVA EL TRASTE, NO LA ALTURA: un 5 en la 3\xAA pasa a ser un 5 en la 4\xAA, as\xED que SUENA DISTINTO. Es para cuando uno se equivoc\xF3 de cuerda y quiso escribir esos n\xFAmeros en la otra \u2014 no para pasar la misma melod\xEDa a otra posici\xF3n del m\xE1stil. Para que suene igual hay que reescribir los trastes. O se mueven todas las notas o no se mueve ninguna: si una sola no entra, no pasa nada.",
125504
125981
  inputSchema: {
125505
125982
  ...RANGO,
125506
- cuerda: external_exports.number().int().min(1).max(24, { error: (i2) => `\xAB${i2.input}\xBB no es una cuerda: van de 1 (la m\xE1s grave) a 24.` }).optional(),
125507
- hacia: external_exports.enum(["arriba", "abajo"], { error: (i2) => `\xAB${i2.input}\xBB no es una direcci\xF3n: arriba o abajo.` })
125983
+ cuerda: external_exports.number().int().min(1).max(24, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB no es una cuerda: van de 1 (la m\xE1s grave) a 24.` }).optional(),
125984
+ hacia: external_exports.enum(["arriba", "abajo"], { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB no es una direcci\xF3n: arriba o abajo.` })
125508
125985
  }
125509
125986
  },
125510
125987
  ({ hacia, ...donde }) => {
@@ -125572,7 +126049,7 @@ function registrarHerramientasDeMusica(servidor2) {
125572
126049
  title: "La letra alineada contra la grabaci\xF3n",
125573
126050
  description: "Las s\xEDlabas tal como quedaron despu\xE9s de sincronizar, con **el segundo en que cada una se canta**. Numeradas desde 1: ese n\xFAmero es el que piden `refinar_silaba`, `dividir_silaba` y `quitar_silaba`. \u26A0\uFE0F `confianza` es de la m\xE1quina: 0 quiere decir que la puso una persona y no hay duda; cuanto m\xE1s alta, m\xE1s dudosa es la hip\xF3tesis del alineador.",
125574
126051
  inputSchema: {
125575
- desde: external_exports.number().int().min(1).max(9999, { error: (i2) => `\xAB${i2.input}\xBB se pasa: va de 1 a 9999.` }).optional().describe("Desde qu\xE9 s\xEDlaba. Por omisi\xF3n, la 1."),
126052
+ desde: external_exports.number().int().min(1).max(9999, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB se pasa: va de 1 a 9999.` }).optional().describe("Desde qu\xE9 s\xEDlaba. Por omisi\xF3n, la 1."),
125576
126053
  cuantas: external_exports.number().int().min(1).max(999).optional().describe("Cu\xE1ntas traer. Por omisi\xF3n, 50: una canci\xF3n tiene entre 300 y 900.")
125577
126054
  }
125578
126055
  },
@@ -125600,7 +126077,7 @@ function registrarHerramientasDeMusica(servidor2) {
125600
126077
  title: "Corregir una s\xEDlaba de la letra sincronizada",
125601
126078
  description: "Le cambia el texto, el tiempo, o las dos cosas; con `restablecer` la devuelve a donde la hab\xEDa puesto el alineador. \u26A0\uFE0F Cambiar el texto **no toca el tiempo** \u2014corregir \xABgran\xBB por \xABgrande\xBB no cambia cu\xE1ndo se canta\u2014 y mover el tiempo no toca el texto. \u2605 Tocarla a mano le pone la confianza en 0: deja de ser una hip\xF3tesis de la m\xE1quina, y queda como puesta por una persona.",
125602
126079
  inputSchema: {
125603
- silaba: external_exports.number().int().min(1).max(9999, { error: (i2) => `\xAB${i2.input}\xBB se pasa: las s\xEDlabas van de 1 a 9999.` }).describe("Su n\xFAmero, de `letra_sincronizada`."),
126080
+ silaba: external_exports.number().int().min(1).max(9999, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB se pasa: las s\xEDlabas van de 1 a 9999.` }).describe("Su n\xFAmero, de `letra_sincronizada`."),
125604
126081
  texto: external_exports.string().optional(),
125605
126082
  desde: external_exports.number().optional().describe("En qu\xE9 segundo empieza a cantarse."),
125606
126083
  hasta: external_exports.number().optional().describe("En qu\xE9 segundo termina."),
@@ -125643,7 +126120,7 @@ function registrarHerramientasDeMusica(servidor2) {
125643
126120
  title: "Copiar una s\xEDlaba a otro instante",
125644
126121
  description: "Para un coro o una palabra que se repite y el alineador no vio: la original se queda donde est\xE1 y la copia entra en su lugar por tiempo, as\xED que los n\xFAmeros de las siguientes se corren. Es arrastrar la s\xEDlaba con Alt.",
125645
126122
  inputSchema: {
125646
- silaba: external_exports.number().int().min(1).max(9999, { error: (i2) => `\xAB${i2.input}\xBB se pasa: las s\xEDlabas van de 1 a 9999.` }),
126123
+ silaba: external_exports.number().int().min(1).max(9999, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB se pasa: las s\xEDlabas van de 1 a 9999.` }),
125647
126124
  desde: external_exports.number().describe("En qu\xE9 segundo empieza la copia."),
125648
126125
  hasta: external_exports.number().optional().describe("En qu\xE9 segundo termina. Por omisi\xF3n, dura lo mismo que la original.")
125649
126126
  }
@@ -125668,7 +126145,7 @@ function registrarHerramientasDeMusica(servidor2) {
125668
126145
  title: "Partir una s\xEDlaba en dos",
125669
126146
  description: "Cuando el alineador dej\xF3 dos s\xEDlabas pegadas en una. La nueva queda justo despu\xE9s, y el tiempo de la original se reparte entre las dos por la mitad.",
125670
126147
  inputSchema: {
125671
- silaba: external_exports.number().int().min(1).max(9999, { error: (i2) => `\xAB${i2.input}\xBB se pasa: las s\xEDlabas van de 1 a 9999.` }).describe("Su n\xFAmero, de `letra_sincronizada`."),
126148
+ silaba: external_exports.number().int().min(1).max(9999, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB se pasa: las s\xEDlabas van de 1 a 9999.` }).describe("Su n\xFAmero, de `letra_sincronizada`."),
125672
126149
  izquierda: external_exports.string().describe("El texto que queda en la primera."),
125673
126150
  derecha: external_exports.string().describe("El texto de la nueva.")
125674
126151
  }
@@ -125688,8 +126165,8 @@ function registrarHerramientasDeMusica(servidor2) {
125688
126165
  title: "Sacar una s\xEDlaba de la letra sincronizada",
125689
126166
  description: "Cuando el alineador invent\xF3 una que no se canta. \u26A0\uFE0F Saca la s\xEDlaba de la ALINEACI\xD3N, no la letra escrita en el pliego: para eso est\xE1 `poner_silaba`. Con `hasta` saca el tramo entero, de un solo paso de deshacer.",
125690
126167
  inputSchema: {
125691
- silaba: external_exports.number().int().min(1).max(9999, { error: (i2) => `\xAB${i2.input}\xBB se pasa: las s\xEDlabas van de 1 a 9999.` }).describe("Su n\xFAmero, de `letra_sincronizada`."),
125692
- hasta: external_exports.number().int().min(1).max(9999, { error: (i2) => `\xAB${i2.input}\xBB se pasa: las s\xEDlabas van de 1 a 9999.` }).optional().describe("La \xFAltima del tramo, incluida.")
126168
+ silaba: external_exports.number().int().min(1).max(9999, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB se pasa: las s\xEDlabas van de 1 a 9999.` }).describe("Su n\xFAmero, de `letra_sincronizada`."),
126169
+ hasta: external_exports.number().int().min(1).max(9999, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB se pasa: las s\xEDlabas van de 1 a 9999.` }).optional().describe("La \xFAltima del tramo, incluida.")
125693
126170
  }
125694
126171
  },
125695
126172
  ({ silaba, hasta }) => {
@@ -125732,7 +126209,7 @@ function registrarHerramientasDeMusica(servidor2) {
125732
126209
  campo: external_exports.string().describe(`Cu\xE1l: ${Object.keys(VARIANTES).join(", ")}. De \`variantes_disponibles\`.`),
125733
126210
  variante: external_exports.string().describe("El nombre de la variante, de `variantes_disponibles`."),
125734
126211
  compas: external_exports.number().int().min(1).max(9999),
125735
- cuerda: external_exports.number().int().min(1).max(24, { error: (i2) => `\xAB${i2.input}\xBB no es una cuerda: van de 1 (la m\xE1s grave) a 24.` }),
126212
+ cuerda: external_exports.number().int().min(1).max(24, { error: (i2) => i2.input === void 0 ? "Falta este dato." : `\xAB${i2.input}\xBB no es una cuerda: van de 1 (la m\xE1s grave) a 24.` }),
125736
126213
  golpe: external_exports.number().int().min(1).max(999).optional(),
125737
126214
  tics: external_exports.number().int().min(0).max(99999).optional(),
125738
126215
  pista: external_exports.number().int().min(1).max(999).optional(),