The author found the pages too technical and did not want a dark
background. With the frontend design guidance:
- The site is always light, whatever the system asks.
- A capsule is a letter posted to the future: white paper, blue ink,
an old-style serif for the voice of the page (Palatino, Iowan) and a
DIN-like sans for the form (Bahnschrift), all system fonts, as the
CSP allows no other origin. Blue is what you act on.
- /create asks three questions, with short sentences: what it keeps,
when it opens, who can open it. The date it opens is set large on an
airmail envelope with the button that creates the capsule; quick
dates of 1, 5 and 10 years; sizes in KB and MB; everything technical
folded in "Detalles técnicos". The messages of the rules no longer
name R4 or §29.6.
Fixes of the review of the pages:
- /inspect labels the start of a single file as content of the
creator, unchecked, so that it cannot pass for a verdict; keeps ZWNJ
and ZWJ in the comment and the author, which R4b allows; and says
the right thing without files and without a comment.
- /create pins at most 500 more rows with problems and counts the
rest; shows what happened with a drop, not only to screen readers;
a comment or an author over its limit is its own problem, not that
of the files; a writing cannot start after the page is destroyed.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
constR7='se distinguen solo por mayúsculas, por cómo se escribe un acento o por un invisible, y en Windows o en macOS serían el mismo nombre (R7).';
constR7='se distinguen solo por mayúsculas, por cómo se escribe un acento o por un invisible, y en Windows o en macOS serían el mismo nombre.';
describe('pathProblem',()=>{
it.each([
['','Escribe la ruta del fichero (R1).'],
['\ud800','La ruta tiene un carácter mal formado (R1).'],
['a'.repeat(1025),'La ruta ocupa 1.025 bytes en UTF-8, más de 1.024 (R1).'],
[`${'a/'.repeat(32)}a`,'La ruta tiene 33 niveles, más de 32 (R2).'],
['a//b','La ruta tiene un nombre vacío: no puede empezar ni acabar por «/», ni llevar «//» (R2).'],
['/a','La ruta tiene un nombre vacío: no puede empezar ni acabar por «/», ni llevar «//» (R2).'],
['a'.repeat(256),`El nombre «${'a'.repeat(57)}…» ocupa 256 bytes en UTF-8, más de 255 (R3).`],
['.','«.» y «..» no valen como nombre: son la carpeta actual y la de arriba (R3).'],
['fotos/..','«.» y «..» no valen como nombre: son la carpeta actual y la de arriba (R3).'],
['.\u200d','El nombre «.\\u200d», sin los invisibles ZWNJ, ZWJ, VS15 y VS16, queda vacío o es «.» o «..» (R3).'],
['\u0390'.repeat(127),`El nombre «${'\u0390'.repeat(57)}…», descompuesto en NFD como lo guarda macOS, mide 381 unidades UTF-16, más de 255 (R3).`],
['a\u0001b','El nombre «a\\u0001b» lleva el carácter de control U+0001 (R4).'],
['a:b','El nombre «a:b» lleva «:», que Windows no admite en un nombre (R4).'],
['x:y/b','La carpeta «x:y» lleva «:», que Windows no admite en un nombre (R4).'],
['a\u2028b','El nombre «a\\u2028b» lleva el separador U+2028 (R4).'],
['a\u200bb','El nombre «a\\u200bb» lleva el carácter invisible U+200B, con el que dos nombres distintos se ven iguales (R4).'],
['a\uf03ab','El nombre «a\\uf03ab» lleva U+F03A, del área de uso privado, con el que Cygwin, WSL y macOS representan un carácter que Windows no admite (R4).'],
['a\u0378','El nombre «a\\u0378» lleva U+0378, que Unicode 18.0.0 no asigna (R4).'],
['a\ufe0f','El nombre «a\ufe0f» lleva el selector de variante U+FE0F sin un emoji delante que lo admita (R4b).'],
['\u200da','El nombre «\\u200da» empieza por el invisible U+200D (R4b).'],
['a\u200c/b','La carpeta «a\\u200c» acaba en el invisible U+200C (R4b).'],
['a\u200d\u200cb','El nombre «a\\u200d\\u200cb» lleva dos invisibles seguidos, U+200D y U+200C (R4b).'],
[' a','El nombre « a» empieza por un espacio (R5).'],
['a ','El nombre «a » acaba en un espacio, que Windows quita (R5).'],
['a.','El nombre «a.» acaba en punto, que Windows quita (R5).'],
['con.txt','El nombre «con.txt» usa CON, un nombre que Windows reserva para un dispositivo (R6).'],
['COM\u00b9.txt','El nombre «COM\u00b9.txt» usa COM\u00b9, un nombre que Windows reserva para un dispositivo (R6).'],
['nul .txt','El nombre «nul .txt» usa NUL, un nombre que Windows reserva para un dispositivo (R6).'],
['ABCDEF~1.TXT','El nombre «ABCDEF~1.TXT» tiene la forma de un nombre corto de Windows, como «PROGRA~1», que puede apuntar a otro fichero (R6b).'],
['a\u2236b','En la página de códigos 1250 de Windows, el nombre «a\u2236b» se convierte en un nombre con «:» (R6c).'],
['x\u00a5y','En la página de códigos 932 de Windows, el nombre «x\u00a5y» se convierte en un nombre con «\\» (R6c).'],
['\uff23\uff2f\uff2e.txt','En la página de códigos 874 de Windows, el nombre «\uff23\uff2f\uff2e.txt» se convierte en un nombre que incumple R6 (R6c).'],
['\u3000a','En la página de códigos 1250 de Windows, el nombre «\\u3000a» se convierte en un nombre que incumple R5 (R6c).'],
['fotos/\uff0e\uff0e','En la página de códigos 874 de Windows, el nombre «\uff0e\uff0e» se convierte en un nombre que incumple R3 (R6c).'],
['.datekeys-x/a','La carpeta «.datekeys-x» empieza por «.datekeys-», que la CLI usa al abrir una cápsula (R10).'],
['.DATEKEYS-a','El nombre «.DATEKEYS-a» empieza por «.datekeys-», que la CLI usa al abrir una cápsula (R10).'],
['','Escribe la ruta del fichero.'],
['\ud800','La ruta tiene un carácter mal formado.'],
['a'.repeat(1025),'La ruta ocupa 1.025 bytes en UTF-8, más de 1.024.'],
[`${'a/'.repeat(32)}a`,'La ruta tiene 33 niveles, más de 32.'],
['a//b','La ruta tiene un nombre vacío: no puede empezar ni acabar por «/», ni llevar «//».'],
['/a','La ruta tiene un nombre vacío: no puede empezar ni acabar por «/», ni llevar «//».'],
['a'.repeat(256),`El nombre «${'a'.repeat(57)}…» ocupa 256 bytes en UTF-8, más de 255.`],
['.','«.» y «..» no valen como nombre: son la carpeta actual y la de arriba.'],
['fotos/..','«.» y «..» no valen como nombre: son la carpeta actual y la de arriba.'],
['.\u200d','El nombre «.\\u200d», sin los invisibles ZWNJ, ZWJ, VS15 y VS16, queda vacío o es «.» o «..».'],
['\u0390'.repeat(127),`El nombre «${'\u0390'.repeat(57)}…», descompuesto en NFD como lo guarda macOS, mide 381 unidades UTF-16, más de 255.`],
['a\u0001b','El nombre «a\\u0001b» lleva el carácter de control U+0001.'],
['a:b','El nombre «a:b» lleva «:», que Windows no admite en un nombre.'],
['x:y/b','La carpeta «x:y» lleva «:», que Windows no admite en un nombre.'],
['a\u2028b','El nombre «a\\u2028b» lleva el separador U+2028.'],
['a\u200bb','El nombre «a\\u200bb» lleva el carácter invisible U+200B, con el que dos nombres distintos se ven iguales.'],
['a\uf03ab','El nombre «a\\uf03ab» lleva U+F03A, del área de uso privado, con el que Cygwin, WSL y macOS representan un carácter que Windows no admite.'],
['a\u0378','El nombre «a\\u0378» lleva U+0378, que Unicode 18.0.0 no asigna.'],
['a\ufe0f','El nombre «a\ufe0f» lleva el selector de variante U+FE0F sin un emoji delante que lo admita.'],
['\u200da','El nombre «\\u200da» empieza por el invisible U+200D.'],
['a\u200c/b','La carpeta «a\\u200c» acaba en el invisible U+200C.'],
['a\u200d\u200cb','El nombre «a\\u200d\\u200cb» lleva dos invisibles seguidos, U+200D y U+200C.'],
[' a','El nombre « a» empieza por un espacio.'],
['a ','El nombre «a » acaba en un espacio, que Windows quita.'],
['a.','El nombre «a.» acaba en punto, que Windows quita.'],
['con.txt','El nombre «con.txt» usa CON, un nombre que Windows reserva para un dispositivo.'],
['COM\u00b9.txt','El nombre «COM\u00b9.txt» usa COM\u00b9, un nombre que Windows reserva para un dispositivo.'],
['nul .txt','El nombre «nul .txt» usa NUL, un nombre que Windows reserva para un dispositivo.'],
['ABCDEF~1.TXT','El nombre «ABCDEF~1.TXT» tiene la forma de un nombre corto de Windows, como «PROGRA~1», que puede apuntar a otro fichero.'],
['a\u2236b','En la página de códigos 1250 de Windows, el nombre «a\u2236b» se convierte en un nombre con «:».'],
['x\u00a5y','En la página de códigos 932 de Windows, el nombre «x\u00a5y» se convierte en un nombre con «\\».'],
['\uff23\uff2f\uff2e.txt','En la página de códigos 874 de Windows, el nombre «\uff23\uff2f\uff2e.txt» se convierte en un nombre que incumple R6.'],
['\u3000a','En la página de códigos 1250 de Windows, el nombre «\\u3000a» se convierte en un nombre que incumple R5.'],
['fotos/\uff0e\uff0e','En la página de códigos 874 de Windows, el nombre «\uff0e\uff0e» se convierte en un nombre que incumple R3.'],
['.datekeys-x/a','La carpeta «.datekeys-x» empieza por «.datekeys-», que la CLI usa al abrir una cápsula.'],
['.DATEKEYS-a','El nombre «.DATEKEYS-a» empieza por «.datekeys-», que la CLI usa al abrir una cápsula.'],
])('%j',(path,want)=>{
expect(pathProblem(path)).toBe(want);
});
@ -64,14 +64,14 @@ describe('checkPaths', () => {
expect(checkPaths(['\u00e9.txt','e\u0301.txt']).problems).toEqual([`Choca con «e\u0301.txt»: ${R7}`,`Choca con «\u00e9.txt»: ${R7}`]);
expect(checkPaths(['ab','a\u200cb']).problems).toEqual([`Choca con «a\\u200cb»: ${R7}`,`Choca con «ab»: ${R7}`]);
expect(checkPaths(['Fotos/a','fotos/b']).problems).toEqual([`Choca con «fotos/b»: ${R7}`,`Choca con «Fotos/a»: ${R7}`]);
expect(checkPaths(['a','a/b']).problems).toEqual(['Choca con «a/b»: «a» sería a la vez un fichero y una carpeta (R7).','Choca con «a»: «a» sería a la vez un fichero y una carpeta (R7).']);
expect(checkPaths(['x/y/z','x/y']).problems).toEqual(['Choca con «x/y»: «x/y» sería a la vez un fichero y una carpeta (R7).','Choca con «x/y/z»: «x/y» sería a la vez un fichero y una carpeta (R7).']);
expect(checkPaths(['a','a/b']).problems).toEqual(['Choca con «a/b»: «a» sería a la vez un fichero y una carpeta.','Choca con «a»: «a» sería a la vez un fichero y una carpeta.']);
expect(checkPaths(['x/y/z','x/y']).problems).toEqual(['Choca con «x/y»: «x/y» sería a la vez un fichero y una carpeta.','Choca con «x/y/z»: «x/y» sería a la vez un fichero y una carpeta.']);
expect(checkPaths(['x','x']).problems).toEqual(['Repite la ruta de otro fichero de la lista.','Repite la ruta de otro fichero de la lista.']);
// The first path keeps its first collision; the third repeats the first.
expect(checkPaths(['a','A','a']).problems).toEqual([`Choca con «A»: ${R7}`,`Choca con «a»: ${R7}`,'Repite la ruta de otro fichero de la lista.']);
collide(problems,n,old.path,(other)=>`Choca con «${shown(other)}»: se distinguen solo por mayúsculas, por cómo se escribe un acento o por un invisible, y en Windows o en macOS serían el mismo nombre (R7).`,paths);
collide(problems,n,old.path,(other)=>`Choca con «${shown(other)}»: se distinguen solo por mayúsculas, por cómo se escribe un acento o por un invisible, y en Windows o en macOS serían el mismo nombre.`,paths);
return;
}elseif(old.dir!==dir){
constprefix=segs.slice(0,i+1).join('/');
collide(problems,n,old.path,(other)=>`Choca con «${shown(other)}»: «${shown(prefix)}» sería a la vez un fichero y una carpeta (R7).`,paths);
collide(problems,n,old.path,(other)=>`Choca con «${shown(other)}»: «${shown(prefix)}» sería a la vez un fichero y una carpeta.`,paths);
return;
}elseif(!dir){
collide(problems,n,old.path,()=>'Repite la ruta de otro fichero de la lista.',paths);
...(dirs.size>MAX_IMPLICIT_DIRS?{overall:`Las rutas forman ${formatInteger(dirs.size)} carpetas, más de ${formatInteger(MAX_IMPLICIT_DIRS)} (R9).`}:{}),
...(dirs.size>MAX_IMPLICIT_DIRS?{overall:`Las rutas forman ${formatInteger(dirs.size)} carpetas, más de ${formatInteger(MAX_IMPLICIT_DIRS)}.`}:{}),
['R3',/^(\d+) bytes, more than \d+$/,(who,m)=>`${who} ocupa ${formatInteger(Number(m[1]))} bytes en UTF-8, más de ${MAX_SEGMENT_LEN} (R3).`],
['R3',/^the segment is (a dot|two dots)$/,()=>'«.» y «..» no valen como nombre: son la carpeta actual y la de arriba (R3).'],
['R3',/^the segment is .* without ZWNJ, ZWJ, VS15 and VS16$/,(who)=>`${who}, sin los invisibles ZWNJ, ZWJ, VS15 y VS16, queda vacío o es «.» o «..» (R3).`],
['R3',/^(\d+) bytes, more than \d+$/,(who,m)=>`${who} ocupa ${formatInteger(Number(m[1]))} bytes en UTF-8, más de ${MAX_SEGMENT_LEN}.`],
['R3',/^the segment is (a dot|two dots)$/,()=>'«.» y «..» no valen como nombre: son la carpeta actual y la de arriba.'],
['R3',/^the segment is .* without ZWNJ, ZWJ, VS15 and VS16$/,(who)=>`${who}, sin los invisibles ZWNJ, ZWJ, VS15 y VS16, queda vacío o es «.» o «..».`],
[
'R3',
/^its NFD is (\d+) UTF-16 code units, more than \d+$/,
(who,m)=>`${who}, descompuesto en NFD como lo guarda macOS, mide ${formatInteger(Number(m[1]))} unidades UTF-16, más de ${MAX_SEGMENT_UTF16} (R3).`,
(who,m)=>`${who}, descompuesto en NFD como lo guarda macOS, mide ${formatInteger(Number(m[1]))} unidades UTF-16, más de ${MAX_SEGMENT_UTF16}.`,
],
['R4',newRegExp(`^control ${CODE_POINT}$`),(who,m)=>`${who} lleva el carácter de control U+${m[1]} (R4).`],
['R4',newRegExp(`^character ${CODE_POINT}$`),(who,m)=>`${who} lleva ${character(m[1]!)}, que Windows no admite en un nombre (R4).`],
['R4',newRegExp(`^separator ${CODE_POINT}$`),(who,m)=>`${who} lleva el separador U+${m[1]} (R4).`],
['R4',newRegExp(`^invisible ${CODE_POINT}$`),(who,m)=>`${who} lleva el carácter invisible U+${m[1]}, con el que dos nombres distintos se ven iguales (R4).`],
['R4',newRegExp(`^control ${CODE_POINT}$`),(who,m)=>`${who} lleva el carácter de control U+${m[1]}.`],
['R4',newRegExp(`^character ${CODE_POINT}$`),(who,m)=>`${who} lleva ${character(m[1]!)}, que Windows no admite en un nombre.`],
['R4',newRegExp(`^separator ${CODE_POINT}$`),(who,m)=>`${who} lleva el separador U+${m[1]}.`],
['R4',newRegExp(`^invisible ${CODE_POINT}$`),(who,m)=>`${who} lleva el carácter invisible U+${m[1]}, con el que dos nombres distintos se ven iguales.`],
[
'R4',
newRegExp(`^private use ${CODE_POINT}$`),
(who,m)=>`${who} lleva U+${m[1]}, del área de uso privado, con el que Cygwin, WSL y macOS representan un carácter que Windows no admite (R4).`,
(who,m)=>`${who} lleva U+${m[1]}, del área de uso privado, con el que Cygwin, WSL y macOS representan un carácter que Windows no admite.`,
],
['R4',newRegExp(`^unassigned ${CODE_POINT}$`),(who,m)=>`${who} lleva U+${m[1]}, que Unicode 18.0.0 no asigna (R4).`],
['R5',/^the segment starts with U\+0020$/,(who)=>`${who} empieza por un espacio (R5).`],
['R5',/^the segment ends with U\+0020$/,(who)=>`${who} acaba en un espacio, que Windows quita (R5).`],
['R5',/^the segment ends with '\.'$/,(who)=>`${who} acaba en punto, que Windows quita (R5).`],
['R6',/^(.+) is a reserved device name$/,(who,m)=>`${who} usa ${m[1]}, un nombre que Windows reserva para un dispositivo (R6).`],
['R6b',/^the segment has the form of an 8\.3 alias$/,(who)=>`${who} tiene la forma de un nombre corto de Windows, como «PROGRA~1», que puede apuntar a otro fichero (R6b).`],
['R4',newRegExp(`^unassigned ${CODE_POINT}$`),(who,m)=>`${who} lleva U+${m[1]}, que Unicode 18.0.0 no asigna.`],
['R5',/^the segment starts with U\+0020$/,(who)=>`${who} empieza por un espacio.`],
['R5',/^the segment ends with U\+0020$/,(who)=>`${who} acaba en un espacio, que Windows quita.`],
['R5',/^the segment ends with '\.'$/,(who)=>`${who} acaba en punto, que Windows quita.`],
['R6',/^(.+) is a reserved device name$/,(who,m)=>`${who} usa ${m[1]}, un nombre que Windows reserva para un dispositivo.`],
['R6b',/^the segment has the form of an 8\.3 alias$/,(who)=>`${who} tiene la forma de un nombre corto de Windows, como «PROGRA~1», que puede apuntar a otro fichero.`],
[
'R6c',
newRegExp(`^code page (\\d+) maps the segment to one with ${CODE_POINT}$`),
(who,m)=>`En la página de códigos ${m[1]} de Windows, ${lower(who)} se convierte en un nombre con ${character(m[2]!)} (R6c).`,
(who,m)=>`En la página de códigos ${m[1]} de Windows, ${lower(who)} se convierte en un nombre con ${character(m[2]!)}.`,
],
['R6c',/^code page (\d+) maps the segment to one that breaks (R\w+): /,(who,m)=>`En la página de códigos ${m[1]} de Windows, ${lower(who)} se convierte en un nombre que incumple ${m[2]} (R6c).`],
['R6c',/^code page (\d+) maps the segment to one that breaks (R\w+): /,(who,m)=>`En la página de códigos ${m[1]} de Windows, ${lower(who)} se convierte en un nombre que incumple ${m[2]}.`],
// R4b on a segment, or on a line of a text: its details.
functionplacementRules():readonlyRule[]{
return[
[newRegExp(`^${CODE_POINT} is not part of an emoji variation sequence$`),(who,m)=>`${who} lleva el selector de variante U+${m[1]} sin un emoji delante que lo admita (${rule}).`],
[newRegExp(`^${CODE_POINT} at the start$`),(who,m)=>`${who} empieza por el invisible U+${m[1]} (${rule}).`],
[newRegExp(`^${CODE_POINT} at the end$`),(who,m)=>`${who} acaba en el invisible U+${m[1]} (${rule}).`],
[newRegExp(`^${CODE_POINT} right after ${CODE_POINT}$`),(who,m)=>`${who} lleva dos invisibles seguidos, U+${m[2]} y U+${m[1]} (${rule}).`],
[newRegExp(`^${CODE_POINT} is not part of an emoji variation sequence$`),(who,m)=>`${who} lleva el selector de variante U+${m[1]} sin un emoji delante que lo admita.`],
[newRegExp(`^${CODE_POINT} at the start$`),(who,m)=>`${who} empieza por el invisible U+${m[1]}.`],
[newRegExp(`^${CODE_POINT} at the end$`),(who,m)=>`${who} acaba en el invisible U+${m[1]}.`],
[newRegExp(`^${CODE_POINT} right after ${CODE_POINT}$`),(who,m)=>`${who} lleva dos invisibles seguidos, U+${m[2]} y U+${m[1]}.`],
?'La ruta tiene un nombre vacío: no puede empezar ni acabar por «/», ni llevar «//» (R2).'
:`La ruta tiene ${formatInteger(Number(count[1]))} niveles, más de ${MAX_SEGMENTS} (R2).`;
?'La ruta tiene un nombre vacío: no puede empezar ni acabar por «/», ni llevar «//».'
:`La ruta tiene ${formatInteger(Number(count[1]))} niveles, más de ${MAX_SEGMENTS}.`;
}
/* v8 ignore next -- @preserve: every detail of pathrule.ts has its words, and R10 is the last rule */
if(err.rule!=='R10')return`La ruta no vale: ${err.message}.`;
return`${subject(segs,0)} empieza por «.datekeys-», que la CLI usa al abrir una cápsula (R10).`;
return`${subject(segs,0)} empieza por «.datekeys-», que la CLI usa al abrir una cápsula.`;
}
// The details of the rules of the texts, from pathrule.ts, and their words.
constTEXT_RULES: readonlyRule[]=[
[newRegExp(`^control ${CODE_POINT} in the declared author$`),()=>'El autor no puede llevar tabuladores ni saltos de línea (§29.6).'],
[newRegExp(`^control ${CODE_POINT}$`),(who,m)=>`${who} lleva el carácter de control U+${m[1]} (§29.6).`],
[newRegExp(`^bidirectional control ${CODE_POINT}$`),(who,m)=>`${who} lleva el control bidireccional U+${m[1]}, que cambia el orden en que se ve el texto (§29.6).`],
[newRegExp(`^separator ${CODE_POINT}$`),(who,m)=>`${who} lleva el separador U+${m[1]} (§29.6).`],
[newRegExp(`^byte order mark ${CODE_POINT}$`),(who)=>`${who} lleva la marca de orden de bytes U+FEFF (§29.6).`],
[newRegExp(`^noncharacter ${CODE_POINT}$`),(who,m)=>`${who} lleva U+${m[1]}, que Unicode reserva como no carácter (§29.6).`],
[newRegExp(`^invisible ${CODE_POINT}$`),(who,m)=>`${who} lleva el carácter invisible U+${m[1]}, con el que se puede esconder texto (§29.6).`],
[/^the declared author starts or ends with U\+0020$/,()=>'El autor no puede empezar ni acabar por un espacio (§29.6).'],
[newRegExp(`^control ${CODE_POINT} in the declared author$`),()=>'El autor no puede llevar tabuladores ni saltos de línea.'],
[newRegExp(`^control ${CODE_POINT}$`),(who,m)=>`${who} lleva el carácter de control U+${m[1]}.`],
[newRegExp(`^bidirectional control ${CODE_POINT}$`),(who,m)=>`${who} lleva el control bidireccional U+${m[1]}, que cambia el orden en que se ve el texto.`],
[newRegExp(`^separator ${CODE_POINT}$`),(who,m)=>`${who} lleva el separador U+${m[1]}.`],
[newRegExp(`^byte order mark ${CODE_POINT}$`),(who)=>`${who} lleva la marca de orden de bytes U+FEFF.`],
[newRegExp(`^noncharacter ${CODE_POINT}$`),(who,m)=>`${who} lleva U+${m[1]}, que Unicode reserva como no carácter.`],
[newRegExp(`^invisible ${CODE_POINT}$`),(who,m)=>`${who} lleva el carácter invisible U+${m[1]}, con el que se puede esconder texto.`],
[/^the declared author starts or ends with U\+0020$/,()=>'El autor no puede empezar ni acabar por un espacio.'],
];
/** The problem of the comment of the form, or undefined; '' has none. */
'Las rutas y los datos de los ficheros ocupan 16.777.217 bytes en la cabecera cifrada, más de 16.777.216 bytes: marca menos ficheros o acorta sus rutas (§29.4).',
'Las rutas y los datos de los ficheros ocupan 16.777.217 bytes en la cabecera cifrada, más de 16.777.216 bytes: marca menos ficheros o acorta sus rutas.',
expect(problem({files: huge})).toEqual(['files',`Los ficheros ocupan más de ${formatByteCount(MAX_PAYLOAD_LENGTH-over)}, el máximo de una cápsula (§29.1).`]);
expect(problem({files: huge})).toEqual(['files',`Los ficheros ocupan más de ${formatByteCount(MAX_PAYLOAD_LENGTH-over)}, el máximo de una cápsula.`]);
});
it('leaves a comment or an author over its limit to its own field, not to the files',()=>{
`Las rutas y los datos de los ficheros ocupan ${formatByteCount(head)} en la cabecera cifrada, más de ${formatByteCount(MAX_HEAD_LEN)}: marca menos ficheros o acorta sus rutas (§29.4).`,
`Las rutas y los datos de los ficheros ocupan ${formatByteCount(head)} en la cabecera cifrada, más de ${formatByteCount(MAX_HEAD_LEN)}: marca menos ficheros o acorta sus rutas.`,
);
}
// BODY holds the files with its frame, security area and head (§29.2).
// BODY holds the files with its frame, security area and head.
constlength=bodyLengthOf(measured,texts);
if(length>MAX_PAYLOAD_LENGTH){
returnfail('files',`Los ficheros ocupan más de ${formatByteCount(MAX_PAYLOAD_LENGTH-(length-measured.content))}, el máximo de una cápsula (§29.1).`);
returnfail('files',`Los ficheros ocupan más de ${formatByteCount(MAX_PAYLOAD_LENGTH-(length-measured.content))}, el máximo de una cápsula.`);
}
if(input.date==='')returnfail('date','Elige el día de apertura.');
if(input.time==='')returnfail('time','Elige la hora de apertura.');