@jjlmoya/utils-streaming 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +60 -0
- package/src/category/i18n/en.ts +134 -0
- package/src/category/i18n/es.ts +134 -0
- package/src/category/i18n/fr.ts +134 -0
- package/src/category/index.ts +12 -0
- package/src/category/seo.astro +14 -0
- package/src/components/PreviewNavSidebar.astro +116 -0
- package/src/components/PreviewToolbar.astro +143 -0
- package/src/data.ts +11 -0
- package/src/env.d.ts +5 -0
- package/src/index.ts +24 -0
- package/src/layouts/PreviewLayout.astro +117 -0
- package/src/pages/[locale]/[slug].astro +148 -0
- package/src/pages/[locale].astro +251 -0
- package/src/pages/index.astro +4 -0
- package/src/tests/faq_count.test.ts +19 -0
- package/src/tests/locale_completeness.test.ts +42 -0
- package/src/tests/mocks/astro_mock.js +2 -0
- package/src/tests/no_h1_in_components.test.ts +48 -0
- package/src/tests/schemas_fulfillment.test.ts +23 -0
- package/src/tests/seo_length.test.ts +22 -0
- package/src/tests/title_quality.test.ts +55 -0
- package/src/tests/tool_validation.test.ts +17 -0
- package/src/tool/sorteo/bibliography.astro +14 -0
- package/src/tool/sorteo/component.astro +1319 -0
- package/src/tool/sorteo/engine.ts +143 -0
- package/src/tool/sorteo/i18n/en.ts +253 -0
- package/src/tool/sorteo/i18n/es.ts +253 -0
- package/src/tool/sorteo/i18n/fr.ts +253 -0
- package/src/tool/sorteo/index.ts +29 -0
- package/src/tool/sorteo/seo.astro +14 -0
- package/src/tool/sorteo/ui-manager.ts +81 -0
- package/src/tool/sorteo/ui.ts +30 -0
- package/src/tool/tebasCheck/bibliography.astro +14 -0
- package/src/tool/tebasCheck/component.astro +587 -0
- package/src/tool/tebasCheck/engine.ts +116 -0
- package/src/tool/tebasCheck/i18n/en.ts +254 -0
- package/src/tool/tebasCheck/i18n/es.ts +254 -0
- package/src/tool/tebasCheck/i18n/fr.ts +254 -0
- package/src/tool/tebasCheck/index.ts +29 -0
- package/src/tool/tebasCheck/ips.json +31 -0
- package/src/tool/tebasCheck/seo.astro +14 -0
- package/src/tool/tebasCheck/types.ts +45 -0
- package/src/tool/tebasCheck/ui-manager.ts +31 -0
- package/src/tools.ts +8 -0
- package/src/types.ts +71 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import type { WithContext, FAQPage, HowTo, SoftwareApplication } from 'schema-dts';
|
|
2
|
+
import type { ToolLocaleContent } from '../../../types';
|
|
3
|
+
import type { TebasCheckUI } from '../types';
|
|
4
|
+
|
|
5
|
+
const slug = 'detecteur-blocage-isp';
|
|
6
|
+
const title = 'Détecteur de Blocages FAI Tebas Check';
|
|
7
|
+
const description = 'Outil de diagnostic pour détecter les blocages illégitimes d\'adresses IP partagées Cloudflare par les serveurs espagnols.';
|
|
8
|
+
|
|
9
|
+
const faqData = [
|
|
10
|
+
{
|
|
11
|
+
question: 'Qu\'est-ce que le Tebas-Check?',
|
|
12
|
+
answer: 'C\'est un outil de diagnostic qui tente de se connecter à des IP Cloudflare connues qui ont été bloquées judiciairement en Espagne pour empêcher l\'accès aux diffusions pirates. Le problème est qu\'en bloquant une IP partagée, des milliers de sites web légitimes sont impactés.',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
question: 'Pourquoi mon fournisseur d\'accès bloque-t-il une IP Cloudflare?',
|
|
16
|
+
answer: 'En raison de mesures conservatoires dynamiques où les FAI doivent bloquer les IP des serveurs diffusant prétendument du contenu protégé. En utilisant Cloudflare (CDN), de nombreux sites partagent la même IP, causant des dommages collatéraux aux utilisateurs innocents.',
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
question: 'Comment fonctionne le test?',
|
|
20
|
+
answer: 'Nous tentons de charger une petite ressource depuis les IP signalées comme bloquées. Si la connexion échoue par "Timeout" ou réinitialisation uniquement sur ces IP, c\'est un indicateur clair que votre FAI applique un filtrage IP.',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
question: 'Puis-je contourner ce blocage?',
|
|
24
|
+
answer: 'Les blocages IP sont difficiles à contourner simplement en changeant de DNS. La solution passe généralement par l\'utilisation d\'un VPN, du navigateur Tor, ou l\'attente que Cloudflare assigne une nouvelle IP au service légitime.',
|
|
25
|
+
},
|
|
26
|
+
];
|
|
27
|
+
|
|
28
|
+
const howToData = [
|
|
29
|
+
{
|
|
30
|
+
name: 'Désactiver le VPN ou les Proxys',
|
|
31
|
+
text: 'Pour que le test soit précis, vous devez utiliser la connexion directe de votre routeur (Fibre ou 4G/5G) sans couches intermédiaires.',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: 'Démarrer le scan',
|
|
35
|
+
text: 'Cliquez sur le bouton de diagnostic. L\'outil enverra des paquets de test aux IP soupçonnées de blocage.',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'Interpréter les résultats',
|
|
39
|
+
text: 'Si vous voyez des résultats en rouge, cela signifie que cette IP est injoignable. Si c\'est vert, votre trafic circule normalement.',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'Générer un rapport',
|
|
43
|
+
text: 'Vous pouvez utiliser les résultats pour signaler l\'incident à votre FAI s\'ils bloquent des services légitimes.',
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
|
|
47
|
+
const faqSchema: WithContext<FAQPage> = {
|
|
48
|
+
'@context': 'https://schema.org',
|
|
49
|
+
'@type': 'FAQPage',
|
|
50
|
+
mainEntity: faqData.map((item) => ({
|
|
51
|
+
'@type': 'Question',
|
|
52
|
+
name: item.question,
|
|
53
|
+
acceptedAnswer: { '@type': 'Answer', text: item.answer },
|
|
54
|
+
})),
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const howToSchema: WithContext<HowTo> = {
|
|
58
|
+
'@context': 'https://schema.org',
|
|
59
|
+
'@type': 'HowTo',
|
|
60
|
+
name: title,
|
|
61
|
+
description,
|
|
62
|
+
step: howToData.map((step, i) => ({
|
|
63
|
+
'@type': 'HowToStep',
|
|
64
|
+
position: i + 1,
|
|
65
|
+
name: step.name,
|
|
66
|
+
text: step.text,
|
|
67
|
+
})),
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const appSchema: WithContext<SoftwareApplication> = {
|
|
71
|
+
'@context': 'https://schema.org',
|
|
72
|
+
'@type': 'SoftwareApplication',
|
|
73
|
+
name: title,
|
|
74
|
+
description,
|
|
75
|
+
applicationCategory: 'UtilityApplication',
|
|
76
|
+
operatingSystem: 'All',
|
|
77
|
+
offers: { '@type': 'Offer', price: '0', priceCurrency: 'EUR' },
|
|
78
|
+
inLanguage: 'fr',
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const content: ToolLocaleContent<TebasCheckUI> = {
|
|
82
|
+
slug,
|
|
83
|
+
title,
|
|
84
|
+
description,
|
|
85
|
+
faqTitle: 'Questions Fréquemment Posées',
|
|
86
|
+
faq: faqData,
|
|
87
|
+
bibliographyTitle: 'Références et Contexte',
|
|
88
|
+
bibliography: [
|
|
89
|
+
{
|
|
90
|
+
name: 'Cloudflare: Understanding IP Blocking',
|
|
91
|
+
url: 'https://www.cloudflare.com/learning/network-layer/what-is-ip-blocking/',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: 'Réglementation espagnole sur les blocages dynamiques',
|
|
95
|
+
url: 'https://www.poderjudicial.es/',
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
howTo: howToData,
|
|
99
|
+
schemas: [faqSchema as any, howToSchema as any, appSchema as any],
|
|
100
|
+
seo: [
|
|
101
|
+
{
|
|
102
|
+
type: 'title',
|
|
103
|
+
text: 'Pourquoi tout a-t-il arrêté de fonctionner ?',
|
|
104
|
+
level: 2,
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
type: 'paragraph',
|
|
108
|
+
html: 'Bienvenue dans le merveilleux monde de la <strong>"Justice Préventive"</strong>. Si vous êtes ici un dimanche après-midi et que des sites web légitimes ont cessé de charger tandis que Twitter fonctionne parfaitement, vous êtes probablement une victime collatérale de la croisade contre le football illégal.',
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
type: 'paragraph',
|
|
112
|
+
html: 'En Espagne, les juges ont remis un "bouton rouge" à certaines entités sportives. Ce bouton leur permet de bloquer les adresses IP en temps réel sans supervision judiciaire directe minute par minute. Le problème est qu\'ils visent avec un fusil de foire, et ils tirent souvent sur des serveurs partagés où, en plus de "matchs illégaux", vivent des sites web d\'hôpitaux, d\'universités ou votre blog de cuisine préféré.',
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
type: 'title',
|
|
116
|
+
text: 'La Théorie du Bâtiment en Feu',
|
|
117
|
+
level: 3,
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
type: 'paragraph',
|
|
121
|
+
html: 'Imaginez qu\'une diffusion illégale soit transmise depuis l\'appartement 4B d\'un gratte-ciel. La solution logique serait de frapper à la porte du 4B et de couper son électricité, non ?',
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
type: 'paragraph',
|
|
125
|
+
html: 'Eh bien, non. La solution actuelle est de <strong>faire exploser les fondations de tout le bâtiment</strong>.',
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
type: 'paragraph',
|
|
129
|
+
html: 'En bloquant l\'IP d\'un service comme Cloudflare, le fournisseur Internet élimine non seulement le pirate, mais aussi les 50 000 autres sites web légitimes qui partageaient cette même adresse numérique. Si vous travailliez ou étudiiez et que votre site utilisait cette IP : malchance, dégâts collatéraux. Déposer plainte auprès du maître armurier.',
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
type: 'title',
|
|
133
|
+
text: 'Que fait exactement cet outil de diagnostic ?',
|
|
134
|
+
level: 3,
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
type: 'paragraph',
|
|
138
|
+
html: 'Cet outil effectue une analyse technique en trois étapes pour identifier si votre FAI applique un blocage sélectif d\'adresses IP :',
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
type: 'comparative',
|
|
142
|
+
columns: 3,
|
|
143
|
+
items: [
|
|
144
|
+
{
|
|
145
|
+
title: 'Ping Google',
|
|
146
|
+
description: 'Nous vérifions si vous avez un pouls. Si Google ne charge pas, le problème est que vous n\'avez pas payé votre facture Wi-Fi. Il s\'agit du test de connectivité de base.',
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
title: 'Ping Cloudflare',
|
|
150
|
+
description: 'Nous essayons de joindre 1.1.1.1. C\'est le "canari dans la mine de charbon" du blocage en Espagne et la cible principale des blocages judiciaires.',
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
title: 'Verdict',
|
|
154
|
+
description: 'Si Google fonctionne et Cloudflare échoue, c\'est crystal clear : votre FAI applique un blocage IP sélectif de Cloudflare.',
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
type: 'title',
|
|
160
|
+
text: 'Impact du Blocage Dynamique',
|
|
161
|
+
level: 3,
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
type: 'comparative',
|
|
165
|
+
columns: 3,
|
|
166
|
+
items: [
|
|
167
|
+
{
|
|
168
|
+
title: 'Faux Positifs',
|
|
169
|
+
description: 'Les sites web d\'entreprises, les blogs personnels et les services gouvernementaux peuvent cesser de fonctionner s\'ils partagent une IP avec un serveur de streaming non autorisé.',
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
title: 'Filtrage IP',
|
|
173
|
+
description: 'Contrairement au blocage DNS, le filtrage IP empêche la connexion au niveau du réseau, ce qui rend le changement de DNS insuffisant pour résoudre le problème.',
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
title: 'Manque de Transparence',
|
|
177
|
+
description: 'Souvent, l\'utilisateur ne voit qu\'une erreur de "Timeout" sans savoir si le problème vient de sa connexion ou d\'un blocage FAI actif.',
|
|
178
|
+
},
|
|
179
|
+
],
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
type: 'title',
|
|
183
|
+
text: 'Les questions que personne ne veut répondre',
|
|
184
|
+
level: 3,
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
type: 'list',
|
|
188
|
+
items: [
|
|
189
|
+
'<strong>Est-il illégal d\'utiliser ceci ?</strong> Non. Faire un "ping" à un serveur est aussi illégal que regarder une vitrine. Cet outil est un diagnostic réseau passif. Il ne casse pas le chiffrement, ne craque pas les mots de passe et n\'accède pas au contenu protégé. Il vous dit simplement pourquoi vous ne pouvez pas accéder à vos sites habituels.',
|
|
190
|
+
'<strong>Comment puis-je le réparer ?</strong> Si vous avez un blocage actif, changer les DNS n\'aide plus (ils connaissent tous les trucs). La seule véritable solution aujourd\'hui est un <strong>VPN</strong>. En chiffrant votre trafic, votre FAI ne peut pas voir ce que vous demandez ou à qui, et par conséquent, ne peut pas vous bloquer "sélectivement" (ou par erreur).',
|
|
191
|
+
],
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
type: 'title',
|
|
195
|
+
text: 'Mode Streamer / OBS Widget',
|
|
196
|
+
level: 3,
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
type: 'paragraph',
|
|
200
|
+
html: 'Êtes-vous un streameur et voulez-vous montrer l\'état de la censure en temps réel sur votre flux ? Nous avons créé un mode spécial ultra-minimaliste, avec arrière-plan transparent (prêt pour chroma) et auto-actualisation toutes les 5 minutes.',
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
type: 'list',
|
|
204
|
+
items: [
|
|
205
|
+
'<strong>Étape 1 :</strong> Ajoutez une nouvelle source <strong>Navigateur</strong> dans OBS.',
|
|
206
|
+
'<strong>Étape 2 :</strong> Utilisez cette URL : <code>https://jjlmoya.es/utilidades/tebas-check/stream/</code>',
|
|
207
|
+
'<strong>Étape 3 :</strong> C\'est fait ! Une grande icône (Vert/Rouge) apparaîtra indiquant si votre connexion est propre ou sous attaque judiciaire.',
|
|
208
|
+
],
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
type: 'tip',
|
|
212
|
+
title: 'Notice Légale',
|
|
213
|
+
html: '<p>Cet outil n\'a aucune affiliation avec une entité sportive, ne facilite pas l\'accès au contenu protégé et ne contourne pas les mesures de protection technologique (DRM). Il informe simplement l\'utilisateur que sa connexion Internet est artificiellement dégradée.</p>',
|
|
214
|
+
},
|
|
215
|
+
],
|
|
216
|
+
ui: {
|
|
217
|
+
scanning: 'Scan de la matrix...',
|
|
218
|
+
seekingBlocks: 'Recherche de blocs de béton dans votre fibre...',
|
|
219
|
+
blockedTitle: 'BLOCAGE...',
|
|
220
|
+
blockedDiagnosis: 'Diagnostic: "Censure Sélective"',
|
|
221
|
+
blockedReason: 'Nous avons détecté une interférence chez votre FAI. Cloudflare ou le DNS sont manipulés.',
|
|
222
|
+
noInternetTitle: 'PAS DE CONNEXION',
|
|
223
|
+
noInternetReason: 'Il semble que vous n\'ayez pas d\'accès internet. Vérifiez votre câble ou la facture.',
|
|
224
|
+
successTitle: 'VOUS ÊTES LIBRE',
|
|
225
|
+
successReason: 'Votre connexion semble propre. Si des blocages globaux existent, ils ne vous affectent pas.',
|
|
226
|
+
retryBtn: 'Provoquer à nouveau la justice',
|
|
227
|
+
authorNoteTitle: 'Note de l\'auteur:',
|
|
228
|
+
authorNoteText: 'Je n\'ai pas pu tester pleinement cet utilitaire car je ne suis pas affecté par la "main noire" de Tebas. Si vous voulez m\'aider, contactez-moi.',
|
|
229
|
+
consoleHeader: 'TEBAS_OS v3.2.0',
|
|
230
|
+
statusNegotiating: 'Négociation avec votre routeur...',
|
|
231
|
+
statusDodging: 'Esquive de la circulaire du tribunal...',
|
|
232
|
+
statusCheckingPirate: 'Vérification si vous êtes un pirate (clin d\'œil, clin d\'œil)...',
|
|
233
|
+
statusPinging: 'Ping vers Google pour voir si vous existez...',
|
|
234
|
+
statusConsulting: 'Consultation de l\'oracle des IP partagées...',
|
|
235
|
+
statusCheckingFee: 'Vérification si Tebas a payé sa cotisation...',
|
|
236
|
+
statusCalculating: 'Calcul de la probabilité de gagner à la loterie...',
|
|
237
|
+
statusDeciphering: 'Tentative de décryptage de votre contrat FAI...',
|
|
238
|
+
logStarted: "LANCEMENT DU PROTOCOLE AUTONOME 'TEBAS_WATCH'...",
|
|
239
|
+
logDetecting: '> Détection du FAI et connectivité de base...',
|
|
240
|
+
logIspFound: '> FAI détecté : ',
|
|
241
|
+
logConnError: '> Erreur de connexion de base',
|
|
242
|
+
logDnsCross: '> Exécution du recoupement DNS (DoH vs Local)...',
|
|
243
|
+
logDnsGoogle: '> DNS Réel (Google) : ',
|
|
244
|
+
logDnsPoisoned: '> ALERTE : DNS empoisonné détecté.',
|
|
245
|
+
logDnsNoDoh: '> DoH indisponible, saut du recoupement DNS.',
|
|
246
|
+
logLaunchingProbes: '> Lancement des sondes sur les objectifs critiques...',
|
|
247
|
+
logIpBlocked: '> Cible {ip} : NE RÉPOND PAS (Blocage IP suspect)',
|
|
248
|
+
logIpActive: '> Cible {ip} : ACTIVE',
|
|
249
|
+
logAlertInterference: '!!! ALERTE D\'INTERFÉRENCE JUDICIAIRE !!!',
|
|
250
|
+
logNoInternet: 'PAS D\'ACCÈS INTERNET',
|
|
251
|
+
logClean: 'CONNEXION PROPRE. PROFITEZ.',
|
|
252
|
+
logDiagError: 'ERREUR DE DIAGNOSTIC',
|
|
253
|
+
},
|
|
254
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { StreamingToolEntry, ToolLocaleContent, ToolDefinition } from '../../types';
|
|
2
|
+
import TebasCheckComponent from './component.astro';
|
|
3
|
+
import TebasCheckSEO from './seo.astro';
|
|
4
|
+
import TebasCheckBibliography from './bibliography.astro';
|
|
5
|
+
import type { TebasCheckUI } from './types';
|
|
6
|
+
|
|
7
|
+
export type TebasCheckLocaleContent = ToolLocaleContent<TebasCheckUI>;
|
|
8
|
+
|
|
9
|
+
export const tebasCheck: StreamingToolEntry<TebasCheckUI> = {
|
|
10
|
+
id: 'tebas-check',
|
|
11
|
+
icons: {
|
|
12
|
+
bg: 'mdi:shield-search',
|
|
13
|
+
fg: 'mdi:security',
|
|
14
|
+
},
|
|
15
|
+
i18n: {
|
|
16
|
+
es: () => import('./i18n/es').then((m) => m.content),
|
|
17
|
+
en: () => import('./i18n/en').then((m) => m.content),
|
|
18
|
+
fr: () => import('./i18n/fr').then((m) => m.content),
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export { TebasCheckComponent, TebasCheckSEO, TebasCheckBibliography };
|
|
23
|
+
|
|
24
|
+
export const TEBAS_CHECK_TOOL: ToolDefinition = {
|
|
25
|
+
entry: tebasCheck,
|
|
26
|
+
Component: TebasCheckComponent,
|
|
27
|
+
SEOComponent: TebasCheckSEO,
|
|
28
|
+
BibliographyComponent: TebasCheckBibliography,
|
|
29
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
[
|
|
2
|
+
"104.16.174.226",
|
|
3
|
+
"104.16.175.226",
|
|
4
|
+
"104.18.2.236",
|
|
5
|
+
"104.18.3.236",
|
|
6
|
+
"104.18.4.181",
|
|
7
|
+
"104.18.5.181",
|
|
8
|
+
"104.18.42.227",
|
|
9
|
+
"104.21.10.14",
|
|
10
|
+
"104.21.11.126",
|
|
11
|
+
"104.21.11.171",
|
|
12
|
+
"104.21.12.160",
|
|
13
|
+
"104.21.14.169",
|
|
14
|
+
"104.21.14.239",
|
|
15
|
+
"104.21.15.142",
|
|
16
|
+
"104.21.16.108",
|
|
17
|
+
"104.21.16.231",
|
|
18
|
+
"104.21.16.237",
|
|
19
|
+
"104.21.17.158",
|
|
20
|
+
"104.21.17.223",
|
|
21
|
+
"104.21.18.223",
|
|
22
|
+
"104.21.19.85",
|
|
23
|
+
"104.21.2.204",
|
|
24
|
+
"104.21.22.45",
|
|
25
|
+
"104.21.23.212",
|
|
26
|
+
"104.21.24.32",
|
|
27
|
+
"104.21.25.102",
|
|
28
|
+
"104.21.25.193",
|
|
29
|
+
"104.21.25.45",
|
|
30
|
+
"104.21.25.78"
|
|
31
|
+
]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { SEORenderer } from '@jjlmoya/utils-shared';
|
|
3
|
+
import { TEBAS_CHECK_TOOL } from './index';
|
|
4
|
+
import type { KnownLocale } from '../../types';
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
locale?: KnownLocale;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const { locale = 'es' } = Astro.props;
|
|
11
|
+
const content = await TEBAS_CHECK_TOOL.entry.i18n[locale]?.();
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
{content && <SEORenderer content={{ locale, sections: content.seo }} />}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export interface TebasCheckUI {
|
|
2
|
+
[key: string]: string | string[];
|
|
3
|
+
scanning: string;
|
|
4
|
+
seekingBlocks: string;
|
|
5
|
+
blockedTitle: string;
|
|
6
|
+
blockedDiagnosis: string;
|
|
7
|
+
blockedReason: string;
|
|
8
|
+
noInternetTitle: string;
|
|
9
|
+
noInternetReason: string;
|
|
10
|
+
successTitle: string;
|
|
11
|
+
successReason: string;
|
|
12
|
+
retryBtn: string;
|
|
13
|
+
authorNoteTitle: string;
|
|
14
|
+
authorNoteText: string;
|
|
15
|
+
consoleHeader: string;
|
|
16
|
+
logStarted: string;
|
|
17
|
+
logDetecting: string;
|
|
18
|
+
logIspFound: string;
|
|
19
|
+
logConnError: string;
|
|
20
|
+
logDnsCross: string;
|
|
21
|
+
logDnsGoogle: string;
|
|
22
|
+
logDnsPoisoned: string;
|
|
23
|
+
logDnsNoDoh: string;
|
|
24
|
+
logLaunchingProbes: string;
|
|
25
|
+
logIpBlocked: string;
|
|
26
|
+
logIpActive: string;
|
|
27
|
+
logAlertInterference: string;
|
|
28
|
+
logNoInternet: string;
|
|
29
|
+
logClean: string;
|
|
30
|
+
logDiagError: string;
|
|
31
|
+
statusNegotiating: string;
|
|
32
|
+
statusDodging: string;
|
|
33
|
+
statusCheckingPirate: string;
|
|
34
|
+
statusPinging: string;
|
|
35
|
+
statusConsulting: string;
|
|
36
|
+
statusCheckingFee: string;
|
|
37
|
+
statusCalculating: string;
|
|
38
|
+
statusDeciphering: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface ProbeResult {
|
|
42
|
+
ip: string;
|
|
43
|
+
status: 'ok' | 'blocked';
|
|
44
|
+
time: number;
|
|
45
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export class TebasUIManager {
|
|
2
|
+
private output: HTMLElement | null;
|
|
3
|
+
|
|
4
|
+
constructor(outputId: string) {
|
|
5
|
+
this.output = document.getElementById(outputId);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
log(msg: string, type: 'neutral' | 'error' | 'success' | 'info' = 'neutral') {
|
|
9
|
+
if (!this.output) return;
|
|
10
|
+
|
|
11
|
+
let colorClass = 'tebas-log-neutral';
|
|
12
|
+
if (type === 'error') {
|
|
13
|
+
colorClass = 'tebas-log-error';
|
|
14
|
+
} else if (type === 'success') {
|
|
15
|
+
colorClass = 'tebas-log-success';
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const div = document.createElement('div');
|
|
19
|
+
div.className = `tebas-log-line ${colorClass}`;
|
|
20
|
+
|
|
21
|
+
const time = new Date().toLocaleTimeString().split(' ')[0];
|
|
22
|
+
div.innerHTML = `<span class="tebas-log-time">[${time}]</span> ${msg}`;
|
|
23
|
+
|
|
24
|
+
this.output.appendChild(div);
|
|
25
|
+
this.output.scrollTop = this.output.scrollHeight;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
clearLog() {
|
|
29
|
+
if (this.output) this.output.innerHTML = '';
|
|
30
|
+
}
|
|
31
|
+
}
|
package/src/tools.ts
ADDED
package/src/types.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { SEOSection } from '@jjlmoya/utils-shared';
|
|
2
|
+
import type { WithContext, Thing } from 'schema-dts';
|
|
3
|
+
|
|
4
|
+
export type { SEOSection };
|
|
5
|
+
|
|
6
|
+
export type KnownLocale =
|
|
7
|
+
| 'ar' | 'da' | 'de' | 'en' | 'es' | 'fi'
|
|
8
|
+
| 'fr' | 'it' | 'ja' | 'ko' | 'nb' | 'nl'
|
|
9
|
+
| 'pl' | 'pt' | 'ru' | 'sv' | 'tr' | 'zh';
|
|
10
|
+
|
|
11
|
+
export interface FAQItem {
|
|
12
|
+
question: string;
|
|
13
|
+
answer: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface BibliographyEntry {
|
|
17
|
+
name: string;
|
|
18
|
+
url: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface HowToStep {
|
|
22
|
+
name: string;
|
|
23
|
+
text: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface ToolLocaleContent<TUI extends Record<string, string | string[]> = Record<string, string | string[]>> {
|
|
27
|
+
slug: string;
|
|
28
|
+
title: string;
|
|
29
|
+
description: string;
|
|
30
|
+
ui: TUI;
|
|
31
|
+
seo: SEOSection[];
|
|
32
|
+
faqTitle?: string;
|
|
33
|
+
faq: FAQItem[];
|
|
34
|
+
bibliographyTitle?: string;
|
|
35
|
+
bibliography: BibliographyEntry[];
|
|
36
|
+
howTo: HowToStep[];
|
|
37
|
+
schemas: WithContext<Thing>[];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export interface CategoryLocaleContent {
|
|
41
|
+
slug: string;
|
|
42
|
+
title: string;
|
|
43
|
+
description: string;
|
|
44
|
+
seo: SEOSection[];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export type LocaleLoader<T> = () => Promise<T>;
|
|
48
|
+
|
|
49
|
+
export type LocaleMap<T> = Partial<Record<KnownLocale, LocaleLoader<T>>>;
|
|
50
|
+
|
|
51
|
+
export interface StreamingToolEntry<TUI extends Record<string, string | string[]> = Record<string, string | string[]>> {
|
|
52
|
+
id: string;
|
|
53
|
+
icons: {
|
|
54
|
+
bg: string;
|
|
55
|
+
fg: string;
|
|
56
|
+
};
|
|
57
|
+
i18n: LocaleMap<ToolLocaleContent<TUI>>;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export interface StreamingCategoryEntry {
|
|
61
|
+
icon: string;
|
|
62
|
+
tools: StreamingToolEntry[];
|
|
63
|
+
i18n: LocaleMap<CategoryLocaleContent>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface ToolDefinition {
|
|
67
|
+
entry: StreamingToolEntry;
|
|
68
|
+
Component: unknown;
|
|
69
|
+
SEOComponent: unknown;
|
|
70
|
+
BibliographyComponent: unknown;
|
|
71
|
+
}
|