@jjlmoya/utils-creative 1.26.0 → 1.27.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/package.json +2 -2
  2. package/src/category/i18n/de.ts +2 -2
  3. package/src/category/i18n/en.ts +2 -2
  4. package/src/category/i18n/es.ts +2 -2
  5. package/src/category/i18n/fr.ts +2 -2
  6. package/src/category/i18n/id.ts +2 -2
  7. package/src/category/i18n/it.ts +2 -2
  8. package/src/category/i18n/ja.ts +2 -2
  9. package/src/category/i18n/ko.ts +2 -2
  10. package/src/category/i18n/nl.ts +2 -2
  11. package/src/category/i18n/pl.ts +2 -2
  12. package/src/category/i18n/pt.ts +2 -2
  13. package/src/category/i18n/ru.ts +2 -2
  14. package/src/category/i18n/sv.ts +2 -2
  15. package/src/category/i18n/tr.ts +2 -2
  16. package/src/category/i18n/zh.ts +2 -2
  17. package/src/category/seo.astro +1 -1
  18. package/src/components/PreviewNavSidebar.astro +1 -1
  19. package/src/components/PreviewToolbar.astro +1 -1
  20. package/src/env.d.ts +1 -1
  21. package/src/pages/index.astro +1 -1
  22. package/src/tests/bibliography_wellformed_export.test.ts +46 -0
  23. package/src/tests/category_seo_quality.test.ts +74 -0
  24. package/src/tests/faq_count.test.ts +1 -1
  25. package/src/tests/mocks/astro_mock.js +1 -1
  26. package/src/tests/no_h1_in_components.test.ts +1 -1
  27. package/src/tests/seo_parity.test.ts +2 -2
  28. package/src/tests/seo_translation_completeness.test.ts +69 -0
  29. package/src/tests/seo_wellformed_export.test.ts +65 -0
  30. package/src/tests/tool_validation.test.ts +17 -17
  31. package/src/tool/bead-pattern-generator/bibliography.astro +8 -8
  32. package/src/tool/bead-pattern-generator/i18n/de.ts +111 -111
  33. package/src/tool/bead-pattern-generator/i18n/en.ts +111 -111
  34. package/src/tool/bead-pattern-generator/i18n/es.ts +104 -104
  35. package/src/tool/bead-pattern-generator/i18n/fr.ts +111 -111
  36. package/src/tool/bead-pattern-generator/i18n/id.ts +111 -111
  37. package/src/tool/bead-pattern-generator/i18n/it.ts +111 -111
  38. package/src/tool/bead-pattern-generator/i18n/ja.ts +111 -111
  39. package/src/tool/bead-pattern-generator/i18n/ko.ts +111 -111
  40. package/src/tool/bead-pattern-generator/i18n/nl.ts +111 -111
  41. package/src/tool/bead-pattern-generator/i18n/pl.ts +111 -111
  42. package/src/tool/bead-pattern-generator/i18n/pt.ts +111 -111
  43. package/src/tool/bead-pattern-generator/i18n/ru.ts +111 -111
  44. package/src/tool/bead-pattern-generator/i18n/sv.ts +111 -111
  45. package/src/tool/bead-pattern-generator/i18n/tr.ts +111 -111
  46. package/src/tool/bead-pattern-generator/i18n/zh.ts +111 -111
  47. package/src/tool/bead-pattern-generator/seo.astro +19 -19
  48. package/src/tool/dice-roller/bibliography.astro +8 -8
  49. package/src/tool/dice-roller/i18n/de.ts +134 -134
  50. package/src/tool/dice-roller/i18n/en.ts +134 -134
  51. package/src/tool/dice-roller/i18n/es.ts +125 -125
  52. package/src/tool/dice-roller/i18n/fr.ts +134 -134
  53. package/src/tool/dice-roller/i18n/id.ts +134 -134
  54. package/src/tool/dice-roller/i18n/it.ts +134 -134
  55. package/src/tool/dice-roller/i18n/ja.ts +134 -134
  56. package/src/tool/dice-roller/i18n/ko.ts +134 -134
  57. package/src/tool/dice-roller/i18n/nl.ts +134 -134
  58. package/src/tool/dice-roller/i18n/pl.ts +134 -134
  59. package/src/tool/dice-roller/i18n/pt.ts +134 -134
  60. package/src/tool/dice-roller/i18n/ru.ts +134 -134
  61. package/src/tool/dice-roller/i18n/sv.ts +134 -134
  62. package/src/tool/dice-roller/i18n/tr.ts +134 -134
  63. package/src/tool/dice-roller/i18n/zh.ts +134 -134
  64. package/src/tool/dice-roller/seo.astro +15 -15
  65. package/src/tool/excuse-generator/bibliography.astro +8 -8
  66. package/src/tool/excuse-generator/i18n/de.ts +120 -120
  67. package/src/tool/excuse-generator/i18n/en.ts +120 -120
  68. package/src/tool/excuse-generator/i18n/es.ts +118 -118
  69. package/src/tool/excuse-generator/i18n/fr.ts +120 -120
  70. package/src/tool/excuse-generator/i18n/id.ts +120 -120
  71. package/src/tool/excuse-generator/i18n/it.ts +120 -120
  72. package/src/tool/excuse-generator/i18n/ja.ts +120 -120
  73. package/src/tool/excuse-generator/i18n/ko.ts +120 -120
  74. package/src/tool/excuse-generator/i18n/nl.ts +120 -120
  75. package/src/tool/excuse-generator/i18n/pl.ts +120 -120
  76. package/src/tool/excuse-generator/i18n/pt.ts +120 -120
  77. package/src/tool/excuse-generator/i18n/ru.ts +120 -120
  78. package/src/tool/excuse-generator/i18n/sv.ts +120 -120
  79. package/src/tool/excuse-generator/i18n/tr.ts +120 -120
  80. package/src/tool/excuse-generator/i18n/zh.ts +120 -120
  81. package/src/tool/excuse-generator/seo.astro +15 -15
  82. package/src/tool/fortune-cookie/bibliography.astro +8 -8
  83. package/src/tool/fortune-cookie/i18n/de.ts +124 -124
  84. package/src/tool/fortune-cookie/i18n/en.ts +124 -124
  85. package/src/tool/fortune-cookie/i18n/es.ts +125 -125
  86. package/src/tool/fortune-cookie/i18n/fr.ts +124 -124
  87. package/src/tool/fortune-cookie/i18n/id.ts +124 -124
  88. package/src/tool/fortune-cookie/i18n/it.ts +124 -124
  89. package/src/tool/fortune-cookie/i18n/ja.ts +124 -124
  90. package/src/tool/fortune-cookie/i18n/ko.ts +124 -124
  91. package/src/tool/fortune-cookie/i18n/nl.ts +124 -124
  92. package/src/tool/fortune-cookie/i18n/pl.ts +124 -124
  93. package/src/tool/fortune-cookie/i18n/pt.ts +124 -124
  94. package/src/tool/fortune-cookie/i18n/ru.ts +124 -124
  95. package/src/tool/fortune-cookie/i18n/sv.ts +124 -124
  96. package/src/tool/fortune-cookie/i18n/tr.ts +124 -124
  97. package/src/tool/fortune-cookie/i18n/zh.ts +124 -124
  98. package/src/tool/fortune-cookie/seo.astro +15 -15
  99. package/src/tool/synesthesia-painter/bibliography.astro +8 -8
  100. package/src/tool/synesthesia-painter/i18n/de.ts +118 -118
  101. package/src/tool/synesthesia-painter/i18n/en.ts +118 -118
  102. package/src/tool/synesthesia-painter/i18n/es.ts +110 -110
  103. package/src/tool/synesthesia-painter/i18n/fr.ts +118 -118
  104. package/src/tool/synesthesia-painter/i18n/id.ts +118 -118
  105. package/src/tool/synesthesia-painter/i18n/it.ts +118 -118
  106. package/src/tool/synesthesia-painter/i18n/ja.ts +118 -118
  107. package/src/tool/synesthesia-painter/i18n/ko.ts +118 -118
  108. package/src/tool/synesthesia-painter/i18n/nl.ts +118 -118
  109. package/src/tool/synesthesia-painter/i18n/pl.ts +118 -118
  110. package/src/tool/synesthesia-painter/i18n/pt.ts +118 -118
  111. package/src/tool/synesthesia-painter/i18n/ru.ts +118 -118
  112. package/src/tool/synesthesia-painter/i18n/sv.ts +118 -118
  113. package/src/tool/synesthesia-painter/i18n/tr.ts +118 -118
  114. package/src/tool/synesthesia-painter/i18n/zh.ts +118 -118
  115. package/src/tool/synesthesia-painter/seo.astro +15 -15
  116. package/src/tool/zalgo-generator/bibliography.astro +8 -8
  117. package/src/tool/zalgo-generator/i18n/de.ts +109 -109
  118. package/src/tool/zalgo-generator/i18n/en.ts +109 -109
  119. package/src/tool/zalgo-generator/i18n/es.ts +109 -109
  120. package/src/tool/zalgo-generator/i18n/fr.ts +109 -109
  121. package/src/tool/zalgo-generator/i18n/id.ts +109 -109
  122. package/src/tool/zalgo-generator/i18n/it.ts +109 -109
  123. package/src/tool/zalgo-generator/i18n/ja.ts +109 -109
  124. package/src/tool/zalgo-generator/i18n/ko.ts +109 -109
  125. package/src/tool/zalgo-generator/i18n/nl.ts +109 -109
  126. package/src/tool/zalgo-generator/i18n/pl.ts +109 -109
  127. package/src/tool/zalgo-generator/i18n/pt.ts +109 -109
  128. package/src/tool/zalgo-generator/i18n/ru.ts +109 -109
  129. package/src/tool/zalgo-generator/i18n/sv.ts +109 -109
  130. package/src/tool/zalgo-generator/i18n/tr.ts +109 -109
  131. package/src/tool/zalgo-generator/i18n/zh.ts +109 -109
  132. package/src/tool/zalgo-generator/seo.astro +15 -15
  133. package/src/types.ts +1 -1
@@ -1,120 +1,120 @@
1
- import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
- import { bibliography } from '../bibliography';
3
- import type { ExcuseGeneratorLocaleContent } from '../index';
4
-
5
- const slug = 'gerador-de-desculpas';
6
- const title = 'Gerador de Desculpas';
7
- const description = 'Máquina de jogo semântica para se livrar de compromissos com estilo. Gere desculpas surreais e irrefutáveis instantaneamente.';
8
-
9
- const faq: ExcuseGeneratorLocaleContent['faq'] = [
10
- {
11
- question: 'Este gerador pode salvar o meu casamento?',
12
- answer: 'Embora não sejamos terapeutas, evitar aquele jantar com os sogros usando uma emergência técnica plausível pode reduzir significativamente a tensão. Use com responsabilidade.'
13
- },
14
- {
15
- question: 'Por que frases tão surreais?',
16
- answer: 'A estratégia baseia-se na Dissonância Cognitiva. Se disser algo aborrecido, é verificável. Se disser algo absurdo, a surpresa bloqueia a capacidade de sentir raiva.'
17
- }
18
- ];
19
-
20
- const howTo: ExcuseGeneratorLocaleContent['howTo'] = [
21
- { name: 'Gerar', text: 'Clique no botão gerar para criar uma nova desculpa.' },
22
- { name: 'Copiar', text: 'Clique no botão copiar para levar a desculpa para a área de transferência.' }
23
- ];
24
-
25
- const faqSchema: WithContext<FAQPage> = {
26
- '@context': 'https://schema.org',
27
- '@type': 'FAQPage',
28
- mainEntity: faq.map((item) => ({
29
- '@type': 'Question',
30
- name: item.question,
31
- acceptedAnswer: { '@type': 'Answer', text: item.answer },
32
- })),
33
- };
34
-
35
- const howToSchema: WithContext<HowTo> = {
36
- '@context': 'https://schema.org',
37
- '@type': 'HowTo',
38
- name: title,
39
- description,
40
- step: howTo.map((step) => ({
41
- '@type': 'HowToStep',
42
- name: step.name,
43
- text: step.text,
44
- })),
45
- };
46
-
47
- const appSchema: WithContext<SoftwareApplication> = {
48
- '@context': 'https://schema.org',
49
- '@type': 'SoftwareApplication',
50
- name: title,
51
- description,
52
- applicationCategory: 'UtilitiesApplication',
53
- operatingSystem: 'Web',
54
- offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
55
- inLanguage: 'pt',
56
- };
57
-
58
- export const content: ExcuseGeneratorLocaleContent = {
59
- slug,
60
- title,
61
- description,
62
- faqTitle: 'Perguntas Frequentes',
63
- ui: {
64
- title: 'Gerador de Desculpas Surreais',
65
- description: 'Calculadora de álibis de próxima geração.',
66
- subjectLabel: 'Sujeito',
67
- actionLabel: 'Ação',
68
- victimLabel: 'Vítima',
69
- generateBtn: 'GERAR DESCULPA',
70
- copyBtn: 'Copiar esta loucura',
71
- copied: 'Copiado!',
72
- starts: JSON.stringify([
73
- "O meu gato", "A minha avó", "O presidente", "Um alienígena", "O meu vizinho do 5º andar",
74
- "O wifi", "O meu horóscopo", "Um viajante do tempo", "A máquina de lavar", "O meu frigorífico",
75
- "O espírito do Natal", "A minha sombra", "Um ninja", "A polícia vegan", "Siri",
76
- "A minha planta carnívora", "O estafeta da Amazon", "O meu clone maligno", "Um feiticeiro", "Godzilla"
77
- ]),
78
- middles: JSON.stringify([
79
- "declarou guerra a", "comeu", "sequestrou", "incendiou",
80
- "está a organizar uma festa em", "vomitou em", "recusa-se a sair de",
81
- "hackeou", "roubou", "apaixonou-se por", "está a meditar sobre",
82
- "lançou um feitiço em", "está a protestar contra", "fundou um culto em",
83
- "está a dançar samba em", "invocou um demónio em", "bloqueou o acesso a",
84
- "transformou-se em ouro", "está a tentar vender", "escreveu um livro sobre"
85
- ]),
86
- ends: JSON.stringify([
87
- "as chaves da minha casa.", "a minha vontade de viver.", "o portão da garagem.",
88
- "as minhas calças favoritas.", "o router da sala.", "o meu único par de sapatos.",
89
- "as leis da física.", "a minha dignidade.", "o elevador do prédio.",
90
- "a minha conta da Netflix.", "a minha escova de dentes.", "as escrituras da casa.",
91
- "a minha coleção de pogs.", "o travão de mão do carro.", "o meu desejo de socializar.",
92
- "o meu stock de café.", "a tampa da sanita.", "o comando da TV.",
93
- "as minhas meias da sorte.", "a civilização ocidental."
94
- ]),
95
- faqTitle: 'FAQ',
96
- bibliographyTitle: 'Referências'
97
- },
98
- seo: [
99
- { type: 'title', text: 'A arte científica da desculpa perfeita', level: 2 },
100
- { type: 'paragraph', html: 'Vivemos na era da hiperconectividade. O seu telemóvel vibra, o seu relógio notifica-o e a sua agenda social parece um jogo de Tetris prestes a perder. A pressão para dizer "sim" a tudo criou uma epidemia de exaustão social.' },
101
- { type: 'title', text: 'O Renascimento do JOMO (Joy of Missing Out)', level: 3 },
102
- { type: 'paragraph', html: 'Enquanto o FOMO (Fear of Missing Out) dominou a última década, especialistas em bem-estar digital defendem agora o <strong>JOMO: a alegria de ficar de fora</strong>. Não se trata de isolamento, mas de intencionalidade.' },
103
- { type: 'tip', title: 'A fórmula para o álibi irrefutável', html: '<strong>O sujeito dissociado:</strong> você nunca é o culpado. É "o wifi", "o meu gato", "o universo". Transfira a culpa para uma entidade externa.<br><strong>A ação hiperbólica:</strong> a situação deve ser suficientemente absurda ou técnica para que ninguém peça detalhes.<br><strong>O bloqueio físico:</strong> o resultado final deve ser binário: ou eu vou ou fico em casa.' },
104
- { type: 'title', text: 'Breve história da desculpa', level: 3 },
105
- { type: 'list', items: [
106
- '<strong>Idade Média:</strong> "O meu cavalo perdeu uma herradura" (um clássico intemporal).',
107
- '<strong>Revolução Industrial:</strong> "A máquina a vapor sobreaqueceu".',
108
- '<strong>Era Digital:</strong> "A minha internet caiu bem no meio de uma atualização".',
109
- ]},
110
- { type: 'proscons', items: [
111
- { pro: 'Alivia instantaneamente a pressão social', con: 'O uso excessivo corrói a confiança' },
112
- { pro: 'Protege a sua energia e os seus limites', con: 'Pode gerar culpa se usado sem cuidado' },
113
- { pro: 'O tom criativo e humorístico dissipa a tensão', con: 'Não é adequado para contextos formais ou profissionais' },
114
- ]},
115
- ],
116
- faq,
117
- bibliography,
118
- howTo,
119
- schemas: [faqSchema as any, howToSchema as any, appSchema],
120
- };
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
+ import { bibliography } from '../bibliography';
3
+ import type { ExcuseGeneratorLocaleContent } from '../index';
4
+
5
+ const slug = 'gerador-de-desculpas';
6
+ const title = 'Gerador de Desculpas';
7
+ const description = 'Máquina de jogo semântica para se livrar de compromissos com estilo. Gere desculpas surreais e irrefutáveis instantaneamente.';
8
+
9
+ const faq: ExcuseGeneratorLocaleContent['faq'] = [
10
+ {
11
+ question: 'Este gerador pode salvar o meu casamento?',
12
+ answer: 'Embora não sejamos terapeutas, evitar aquele jantar com os sogros usando uma emergência técnica plausível pode reduzir significativamente a tensão. Use com responsabilidade.'
13
+ },
14
+ {
15
+ question: 'Por que frases tão surreais?',
16
+ answer: 'A estratégia baseia-se na Dissonância Cognitiva. Se disser algo aborrecido, é verificável. Se disser algo absurdo, a surpresa bloqueia a capacidade de sentir raiva.'
17
+ }
18
+ ];
19
+
20
+ const howTo: ExcuseGeneratorLocaleContent['howTo'] = [
21
+ { name: 'Gerar', text: 'Clique no botão gerar para criar uma nova desculpa.' },
22
+ { name: 'Copiar', text: 'Clique no botão copiar para levar a desculpa para a área de transferência.' }
23
+ ];
24
+
25
+ const faqSchema: WithContext<FAQPage> = {
26
+ '@context': 'https://schema.org',
27
+ '@type': 'FAQPage',
28
+ mainEntity: faq.map((item) => ({
29
+ '@type': 'Question',
30
+ name: item.question,
31
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
32
+ })),
33
+ };
34
+
35
+ const howToSchema: WithContext<HowTo> = {
36
+ '@context': 'https://schema.org',
37
+ '@type': 'HowTo',
38
+ name: title,
39
+ description,
40
+ step: howTo.map((step) => ({
41
+ '@type': 'HowToStep',
42
+ name: step.name,
43
+ text: step.text,
44
+ })),
45
+ };
46
+
47
+ const appSchema: WithContext<SoftwareApplication> = {
48
+ '@context': 'https://schema.org',
49
+ '@type': 'SoftwareApplication',
50
+ name: title,
51
+ description,
52
+ applicationCategory: 'UtilitiesApplication',
53
+ operatingSystem: 'Web',
54
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
55
+ inLanguage: 'pt',
56
+ };
57
+
58
+ export const content: ExcuseGeneratorLocaleContent = {
59
+ slug,
60
+ title,
61
+ description,
62
+ faqTitle: 'Perguntas Frequentes',
63
+ ui: {
64
+ title: 'Gerador de Desculpas Surreais',
65
+ description: 'Calculadora de álibis de próxima geração.',
66
+ subjectLabel: 'Sujeito',
67
+ actionLabel: 'Ação',
68
+ victimLabel: 'Vítima',
69
+ generateBtn: 'GERAR DESCULPA',
70
+ copyBtn: 'Copiar esta loucura',
71
+ copied: 'Copiado!',
72
+ starts: JSON.stringify([
73
+ "O meu gato", "A minha avó", "O presidente", "Um alienígena", "O meu vizinho do 5º andar",
74
+ "O wifi", "O meu horóscopo", "Um viajante do tempo", "A máquina de lavar", "O meu frigorífico",
75
+ "O espírito do Natal", "A minha sombra", "Um ninja", "A polícia vegan", "Siri",
76
+ "A minha planta carnívora", "O estafeta da Amazon", "O meu clone maligno", "Um feiticeiro", "Godzilla"
77
+ ]),
78
+ middles: JSON.stringify([
79
+ "declarou guerra a", "comeu", "sequestrou", "incendiou",
80
+ "está a organizar uma festa em", "vomitou em", "recusa-se a sair de",
81
+ "hackeou", "roubou", "apaixonou-se por", "está a meditar sobre",
82
+ "lançou um feitiço em", "está a protestar contra", "fundou um culto em",
83
+ "está a dançar samba em", "invocou um demónio em", "bloqueou o acesso a",
84
+ "transformou-se em ouro", "está a tentar vender", "escreveu um livro sobre"
85
+ ]),
86
+ ends: JSON.stringify([
87
+ "as chaves da minha casa.", "a minha vontade de viver.", "o portão da garagem.",
88
+ "as minhas calças favoritas.", "o router da sala.", "o meu único par de sapatos.",
89
+ "as leis da física.", "a minha dignidade.", "o elevador do prédio.",
90
+ "a minha conta da Netflix.", "a minha escova de dentes.", "as escrituras da casa.",
91
+ "a minha coleção de pogs.", "o travão de mão do carro.", "o meu desejo de socializar.",
92
+ "o meu stock de café.", "a tampa da sanita.", "o comando da TV.",
93
+ "as minhas meias da sorte.", "a civilização ocidental."
94
+ ]),
95
+ faqTitle: 'FAQ',
96
+ bibliographyTitle: 'Referências'
97
+ },
98
+ seo: [
99
+ { type: 'title', text: 'A arte científica da desculpa perfeita', level: 2 },
100
+ { type: 'paragraph', html: 'Vivemos na era da hiperconectividade. O seu telemóvel vibra, o seu relógio notifica-o e a sua agenda social parece um jogo de Tetris prestes a perder. A pressão para dizer "sim" a tudo criou uma epidemia de exaustão social.' },
101
+ { type: 'title', text: 'O Renascimento do JOMO (Joy of Missing Out)', level: 3 },
102
+ { type: 'paragraph', html: 'Enquanto o FOMO (Fear of Missing Out) dominou a última década, especialistas em bem-estar digital defendem agora o <strong>JOMO: a alegria de ficar de fora</strong>. Não se trata de isolamento, mas de intencionalidade.' },
103
+ { type: 'tip', title: 'A fórmula para o álibi irrefutável', html: '<strong>O sujeito dissociado:</strong> você nunca é o culpado. É "o wifi", "o meu gato", "o universo". Transfira a culpa para uma entidade externa.<br><strong>A ação hiperbólica:</strong> a situação deve ser suficientemente absurda ou técnica para que ninguém peça detalhes.<br><strong>O bloqueio físico:</strong> o resultado final deve ser binário: ou eu vou ou fico em casa.' },
104
+ { type: 'title', text: 'Breve história da desculpa', level: 3 },
105
+ { type: 'list', items: [
106
+ '<strong>Idade Média:</strong> "O meu cavalo perdeu uma herradura" (um clássico intemporal).',
107
+ '<strong>Revolução Industrial:</strong> "A máquina a vapor sobreaqueceu".',
108
+ '<strong>Era Digital:</strong> "A minha internet caiu bem no meio de uma atualização".',
109
+ ]},
110
+ { type: 'proscons', items: [
111
+ { pro: 'Alivia instantaneamente a pressão social', con: 'O uso excessivo corrói a confiança' },
112
+ { pro: 'Protege a sua energia e os seus limites', con: 'Pode gerar culpa se usado sem cuidado' },
113
+ { pro: 'O tom criativo e humorístico dissipa a tensão', con: 'Não é adequado para contextos formais ou profissionais' },
114
+ ]},
115
+ ],
116
+ faq,
117
+ bibliography,
118
+ howTo,
119
+ schemas: [faqSchema as any, howToSchema as any, appSchema],
120
+ };
@@ -1,120 +1,120 @@
1
- import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
- import { bibliography } from '../bibliography';
3
- import type { ExcuseGeneratorLocaleContent } from '../index';
4
-
5
- const slug = 'generator-otgovorki';
6
- const title = 'Генератор отговорок';
7
- const description = 'Семантическая машина для стильного избавления от обязательств. Мгновенно создавайте сюрреалистичные и неопровержимые отговорки.';
8
-
9
- const faq: ExcuseGeneratorLocaleContent['faq'] = [
10
- {
11
- question: 'Может ли этот генератор спасти мой брак?',
12
- answer: 'Хотя мы не терапевты, возможность избежать того самого ужина с родственниками с помощью правдоподобной технической заминки может значительно снизить напряжение. Используйте ответственно.'
13
- },
14
- {
15
- question: 'Почему фразы такие странные?',
16
- answer: 'Стратегия основана на когнитивном диссонансе. Если вы скажете что-то скучное, это легко проверить. Если вы скажете что-то абсурдное, эффект неожиданности блокирует способность к гневу.'
17
- }
18
- ];
19
-
20
- const howTo: ExcuseGeneratorLocaleContent['howTo'] = [
21
- { name: 'Создать', text: 'Нажмите кнопку генерации, чтобы создать новую отговорку.' },
22
- { name: 'Копировать', text: 'Нажмите кнопку копирования, чтобы сохранить отговорку в буфер обмена.' }
23
- ];
24
-
25
- const faqSchema: WithContext<FAQPage> = {
26
- '@context': 'https://schema.org',
27
- '@type': 'FAQPage',
28
- mainEntity: faq.map((item) => ({
29
- '@type': 'Question',
30
- name: item.question,
31
- acceptedAnswer: { '@type': 'Answer', text: item.answer },
32
- })),
33
- };
34
-
35
- const howToSchema: WithContext<HowTo> = {
36
- '@context': 'https://schema.org',
37
- '@type': 'HowTo',
38
- name: title,
39
- description,
40
- step: howTo.map((step) => ({
41
- '@type': 'HowToStep',
42
- name: step.name,
43
- text: step.text,
44
- })),
45
- };
46
-
47
- const appSchema: WithContext<SoftwareApplication> = {
48
- '@context': 'https://schema.org',
49
- '@type': 'SoftwareApplication',
50
- name: title,
51
- description,
52
- applicationCategory: 'UtilitiesApplication',
53
- operatingSystem: 'Web',
54
- offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
55
- inLanguage: 'ru',
56
- };
57
-
58
- export const content: ExcuseGeneratorLocaleContent = {
59
- slug,
60
- title,
61
- description,
62
- faqTitle: 'Часто задаваемые вопросы',
63
- ui: {
64
- title: 'Сюрреалистичный генератор отговорок',
65
- description: 'Калькулятор алиби нового поколения.',
66
- subjectLabel: 'Субъект',
67
- actionLabel: 'Действие',
68
- victimLabel: 'Объект',
69
- generateBtn: 'СОЗДАТЬ ОТГОВОРКУ',
70
- copyBtn: 'Скопировать это безумие',
71
- copied: 'Скопировано!',
72
- starts: JSON.stringify([
73
- "Мой кот", "Моя бабушка", "Президент", "Пришелец", "Сосед с 5-го этажа",
74
- "Wi-fi", "Мой гороскоп", "Путешественник во времени", "Стиральная машина", "Мой холодильник",
75
- "Дух Рождества", "Моя тень", "Ниндзя", "Веганская полиция", "Siri",
76
- "Мое плотоядное растение", "Курьер Amazon", "Мой злой клон", "Волшебник", "Годзилла"
77
- ]),
78
- middles: JSON.stringify([
79
- "объявил войну", "съел", "похитил", "поджег",
80
- "устраивает вечеринку в", "вырвал на", "отказывается покидать",
81
- "взломал", "украл", "влюбился в", "медитирует над",
82
- "наложил заклинание на", "протестует против", "основал секту в",
83
- "танцует самбу в", "вызвал демона в", "заблокировал доступ к",
84
- "превратился в золото", "пытается продать", "написал книгу о"
85
- ]),
86
- ends: JSON.stringify([
87
- "моих ключах от дома.", "моей воле к жизни.", "гаражных воротах.",
88
- "моих любимых штанах.", "роутере в гостиной.", "моей единственной паре обуви.",
89
- "законах физики.", "моем достоинстве.", "лифте в здании.",
90
- "моем аккаунте Netflix.", "моей зубной щетке.", "документах на дом.",
91
- "моей коллекции фишек.", "ручном тормозе машины.", "моем желании общаться.",
92
- "запасах кофе.", "крышке унитаза.", "пульте от телевизора.",
93
- "моих счастливых носках.", "западной цивилизации."
94
- ]),
95
- faqTitle: 'FAQ',
96
- bibliographyTitle: 'Ссылки'
97
- },
98
- seo: [
99
- { type: 'title', text: 'Научное искусство идеальной отговорки', level: 2 },
100
- { type: 'paragraph', html: 'Мы живем в эпоху гиперподключенности. Телефон вибрирует, часы присылают уведомления, а ваш социальный календарь напоминает игру в Тетрис за шаг до проигрыша. Давление говорить \"да\" всему вокруг создало эпидемию социального истощения.' },
101
- { type: 'title', text: 'Ренессанс JOMO (Радость от упущенного)', level: 3 },
102
- { type: 'paragraph', html: 'В то время как FOMO (страх что-то упустить) доминировал в прошлом десятилетии, эксперты по цифровому благополучию теперь выступают за <strong>JOMO: радость от того, что вы что-то пропустили</strong>. Это не про изоляцию, а про осознанность.' },
103
- { type: 'tip', title: 'Формула неопровержимого алиби', html: '<strong>Отстраненный субъект:</strong> вы никогда не виноваты. Это \"wi-fi\", \"мой кот\" или \"вселенная\". Переложите вину на внешние силы.<br><strong>Гиперболизированное действие:</strong> ситуация должна быть достаточно абсурдной или технически сложной, чтобы никто не захотел уточнять детали.<br><strong>Физическая преграда:</strong> итоговый результат должен быть бинарным: либо я иду, либо остаюсь дома.' },
104
- { type: 'title', text: 'Краткая история отговорки', level: 3 },
105
- { type: 'list', items: [
106
- '<strong>Средние века:</strong> \"Моя лошадь потеряла подкову\" (нестареющая классика).',
107
- '<strong>Промышленная революция:</strong> \"Паровой двигатель перегрелся\".',
108
- '<strong>Цифровая эра:</strong> \"Интернет пропал прямо посреди обновления\".'
109
- ]},
110
- { type: 'proscons', items: [
111
- { pro: 'Мгновенно снимает социальное давление', con: 'Чрезмерное использование разрушает доверие' },
112
- { pro: 'Защищает вашу энергию и границы', con: 'Может вызвать чувство вины при бездумном использовании' },
113
- { pro: 'Креативный и юмористический тон разряжает обстановку', con: 'Не подходит для официальных или рабочих ситуаций' }
114
- ]},
115
- ],
116
- faq,
117
- bibliography,
118
- howTo,
119
- schemas: [faqSchema as any, howToSchema as any, appSchema],
120
- };
1
+ import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
2
+ import { bibliography } from '../bibliography';
3
+ import type { ExcuseGeneratorLocaleContent } from '../index';
4
+
5
+ const slug = 'generator-otgovorki';
6
+ const title = 'Генератор отговорок';
7
+ const description = 'Семантическая машина для стильного избавления от обязательств. Мгновенно создавайте сюрреалистичные и неопровержимые отговорки.';
8
+
9
+ const faq: ExcuseGeneratorLocaleContent['faq'] = [
10
+ {
11
+ question: 'Может ли этот генератор спасти мой брак?',
12
+ answer: 'Хотя мы не терапевты, возможность избежать того самого ужина с родственниками с помощью правдоподобной технической заминки может значительно снизить напряжение. Используйте ответственно.'
13
+ },
14
+ {
15
+ question: 'Почему фразы такие странные?',
16
+ answer: 'Стратегия основана на когнитивном диссонансе. Если вы скажете что-то скучное, это легко проверить. Если вы скажете что-то абсурдное, эффект неожиданности блокирует способность к гневу.'
17
+ }
18
+ ];
19
+
20
+ const howTo: ExcuseGeneratorLocaleContent['howTo'] = [
21
+ { name: 'Создать', text: 'Нажмите кнопку генерации, чтобы создать новую отговорку.' },
22
+ { name: 'Копировать', text: 'Нажмите кнопку копирования, чтобы сохранить отговорку в буфер обмена.' }
23
+ ];
24
+
25
+ const faqSchema: WithContext<FAQPage> = {
26
+ '@context': 'https://schema.org',
27
+ '@type': 'FAQPage',
28
+ mainEntity: faq.map((item) => ({
29
+ '@type': 'Question',
30
+ name: item.question,
31
+ acceptedAnswer: { '@type': 'Answer', text: item.answer },
32
+ })),
33
+ };
34
+
35
+ const howToSchema: WithContext<HowTo> = {
36
+ '@context': 'https://schema.org',
37
+ '@type': 'HowTo',
38
+ name: title,
39
+ description,
40
+ step: howTo.map((step) => ({
41
+ '@type': 'HowToStep',
42
+ name: step.name,
43
+ text: step.text,
44
+ })),
45
+ };
46
+
47
+ const appSchema: WithContext<SoftwareApplication> = {
48
+ '@context': 'https://schema.org',
49
+ '@type': 'SoftwareApplication',
50
+ name: title,
51
+ description,
52
+ applicationCategory: 'UtilitiesApplication',
53
+ operatingSystem: 'Web',
54
+ offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
55
+ inLanguage: 'ru',
56
+ };
57
+
58
+ export const content: ExcuseGeneratorLocaleContent = {
59
+ slug,
60
+ title,
61
+ description,
62
+ faqTitle: 'Часто задаваемые вопросы',
63
+ ui: {
64
+ title: 'Сюрреалистичный генератор отговорок',
65
+ description: 'Калькулятор алиби нового поколения.',
66
+ subjectLabel: 'Субъект',
67
+ actionLabel: 'Действие',
68
+ victimLabel: 'Объект',
69
+ generateBtn: 'СОЗДАТЬ ОТГОВОРКУ',
70
+ copyBtn: 'Скопировать это безумие',
71
+ copied: 'Скопировано!',
72
+ starts: JSON.stringify([
73
+ "Мой кот", "Моя бабушка", "Президент", "Пришелец", "Сосед с 5-го этажа",
74
+ "Wi-fi", "Мой гороскоп", "Путешественник во времени", "Стиральная машина", "Мой холодильник",
75
+ "Дух Рождества", "Моя тень", "Ниндзя", "Веганская полиция", "Siri",
76
+ "Мое плотоядное растение", "Курьер Amazon", "Мой злой клон", "Волшебник", "Годзилла"
77
+ ]),
78
+ middles: JSON.stringify([
79
+ "объявил войну", "съел", "похитил", "поджег",
80
+ "устраивает вечеринку в", "вырвал на", "отказывается покидать",
81
+ "взломал", "украл", "влюбился в", "медитирует над",
82
+ "наложил заклинание на", "протестует против", "основал секту в",
83
+ "танцует самбу в", "вызвал демона в", "заблокировал доступ к",
84
+ "превратился в золото", "пытается продать", "написал книгу о"
85
+ ]),
86
+ ends: JSON.stringify([
87
+ "моих ключах от дома.", "моей воле к жизни.", "гаражных воротах.",
88
+ "моих любимых штанах.", "роутере в гостиной.", "моей единственной паре обуви.",
89
+ "законах физики.", "моем достоинстве.", "лифте в здании.",
90
+ "моем аккаунте Netflix.", "моей зубной щетке.", "документах на дом.",
91
+ "моей коллекции фишек.", "ручном тормозе машины.", "моем желании общаться.",
92
+ "запасах кофе.", "крышке унитаза.", "пульте от телевизора.",
93
+ "моих счастливых носках.", "западной цивилизации."
94
+ ]),
95
+ faqTitle: 'FAQ',
96
+ bibliographyTitle: 'Ссылки'
97
+ },
98
+ seo: [
99
+ { type: 'title', text: 'Научное искусство идеальной отговорки', level: 2 },
100
+ { type: 'paragraph', html: 'Мы живем в эпоху гиперподключенности. Телефон вибрирует, часы присылают уведомления, а ваш социальный календарь напоминает игру в Тетрис за шаг до проигрыша. Давление говорить \"да\" всему вокруг создало эпидемию социального истощения.' },
101
+ { type: 'title', text: 'Ренессанс JOMO (Радость от упущенного)', level: 3 },
102
+ { type: 'paragraph', html: 'В то время как FOMO (страх что-то упустить) доминировал в прошлом десятилетии, эксперты по цифровому благополучию теперь выступают за <strong>JOMO: радость от того, что вы что-то пропустили</strong>. Это не про изоляцию, а про осознанность.' },
103
+ { type: 'tip', title: 'Формула неопровержимого алиби', html: '<strong>Отстраненный субъект:</strong> вы никогда не виноваты. Это \"wi-fi\", \"мой кот\" или \"вселенная\". Переложите вину на внешние силы.<br><strong>Гиперболизированное действие:</strong> ситуация должна быть достаточно абсурдной или технически сложной, чтобы никто не захотел уточнять детали.<br><strong>Физическая преграда:</strong> итоговый результат должен быть бинарным: либо я иду, либо остаюсь дома.' },
104
+ { type: 'title', text: 'Краткая история отговорки', level: 3 },
105
+ { type: 'list', items: [
106
+ '<strong>Средние века:</strong> \"Моя лошадь потеряла подкову\" (нестареющая классика).',
107
+ '<strong>Промышленная революция:</strong> \"Паровой двигатель перегрелся\".',
108
+ '<strong>Цифровая эра:</strong> \"Интернет пропал прямо посреди обновления\".'
109
+ ]},
110
+ { type: 'proscons', items: [
111
+ { pro: 'Мгновенно снимает социальное давление', con: 'Чрезмерное использование разрушает доверие' },
112
+ { pro: 'Защищает вашу энергию и границы', con: 'Может вызвать чувство вины при бездумном использовании' },
113
+ { pro: 'Креативный и юмористический тон разряжает обстановку', con: 'Не подходит для официальных или рабочих ситуаций' }
114
+ ]},
115
+ ],
116
+ faq,
117
+ bibliography,
118
+ howTo,
119
+ schemas: [faqSchema as any, howToSchema as any, appSchema],
120
+ };