@vibe2founder/tests2dialects 0.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.
Files changed (74) hide show
  1. package/CHANGELOG.md +73 -0
  2. package/bun.lock +22 -0
  3. package/bunfig.toml +2 -0
  4. package/critica.md +77 -0
  5. package/docs/4-ideias.md +66 -0
  6. package/docs/api-api.md +93 -0
  7. package/docs/api-imperativo.md +125 -0
  8. package/docs/api-matematico.md +145 -0
  9. package/docs/api-narrativo.md +181 -0
  10. package/docs/guia-rapido.md +189 -0
  11. package/docs/whitepaper.md +21 -0
  12. package/examples/imperative.spec.ts +58 -0
  13. package/examples/math.spec.ts +52 -0
  14. package/examples/narrative.spec.ts +61 -0
  15. package/examples/polyglot-shopping-cart.spec.ts +212 -0
  16. package/examples/sanity.spec.ts +54 -0
  17. package/examples/showcase-api.spec.ts +70 -0
  18. package/examples/test-api.ts +36 -0
  19. package/infograficos/detalhado.png +0 -0
  20. package/infograficos/mobile.png +0 -0
  21. package/infograficos/normal.png +0 -0
  22. package/landing-page/README.md +38 -0
  23. package/landing-page/bun.lock +609 -0
  24. package/landing-page/eslint.config.js +23 -0
  25. package/landing-page/index.html +17 -0
  26. package/landing-page/package-lock.json +2962 -0
  27. package/landing-page/package.json +34 -0
  28. package/landing-page/postcss.config.js +6 -0
  29. package/landing-page/public/vite.svg +1 -0
  30. package/landing-page/src/App.tsx +358 -0
  31. package/landing-page/src/assets/react.svg +1 -0
  32. package/landing-page/src/index.css +34 -0
  33. package/landing-page/src/main.tsx +10 -0
  34. package/landing-page/tailwind.config.js +59 -0
  35. package/landing-page/tsconfig.app.json +28 -0
  36. package/landing-page/tsconfig.json +7 -0
  37. package/landing-page/tsconfig.node.json +26 -0
  38. package/landing-page/vite.config.ts +7 -0
  39. package/logo.png +0 -0
  40. package/output.log +60 -0
  41. package/package.json +36 -0
  42. package/packages/api-test-dialect/README.md +30 -0
  43. package/packages/api-test-dialect/index.ts +132 -0
  44. package/packages/api-test-dialect/openapi.json +64 -0
  45. package/packages/reqify/README.md +33 -0
  46. package/packages/reqify/index.ts +48 -0
  47. package/podcast/O_Matem/303/241tico,_o_Narrador_e_o_Engenheiro.json +0 -0
  48. package/podcast/O_Matem/303/241tico,_o_Narrador_e_o_Engenheiro.md +0 -0
  49. package/podcast/critica-Dialetos_de_teste__inova/303/247/303/243o_ou_fragmenta/303/247/303/243o_.json +0 -0
  50. package/podcast/critica-Dialetos_de_teste__inova/303/247/303/243o_ou_fragmenta/303/247/303/243o_.md +0 -0
  51. package/podcast/critica-Unificar_filosofia_e_pr/303/241tica_na_documenta/303/247/303/243o_(7_words__covers_t.md +1 -0
  52. package/podcast/critica-Unificar_filosofia_e_pr/303/241tica_na_documenta/303/247/303/243o__7_words__covers_t.ogg +0 -0
  53. package/podcast/critica2-Sil/303/252ncio_estrat/303/251gico_e_sobrecarga_em_READMEs.ogg +0 -0
  54. package/podcast/critica2.json +3191 -0
  55. package/podcast/critica2.md +1 -0
  56. package/podcast/debate-Dialetos_de_teste__inova/303/247/303/243o_ou_fragmenta/303/247/303/243o_.json +0 -0
  57. package/podcast/debate-Dialetos_de_teste__inova/303/247/303/243o_ou_fragmenta/303/247/303/243o_.md +0 -0
  58. package/readme.md +58 -0
  59. package/reports/01-01-2026_00-45.md +40 -0
  60. package/reports/01-01-2026_02-30.md +37 -0
  61. package/reports/03-02-2026_10-55.md +8 -0
  62. package/reports/03-02-2026_11-45.md +13 -0
  63. package/reports/03-02-2026_11-50.md +10 -0
  64. package/reports/26-01-2026_16-25.md +31 -0
  65. package/reports/26-01-2026_19-20.md +27 -0
  66. package/reports/31-12-2025_22-35.md +25 -0
  67. package/reports/31-12-2025_22-45.md +15 -0
  68. package/slides/Dialetos_de_Teste_Um_Executor_M/303/272ltiplos_Vocabul/303/241rios.pdf +0 -0
  69. package/src/cli.ts +445 -0
  70. package/src/index.ts +539 -0
  71. package/tabela.html +350 -0
  72. package/tsconfig.json +22 -0
  73. package/types/api-types.ts +11 -0
  74. package/www/index.html +1344 -0
package/src/index.ts ADDED
@@ -0,0 +1,539 @@
1
+ // ============================================================================
2
+ // 1. ATOMIC CORE ENGINE (O Motor)
3
+ // ============================================================================
4
+
5
+ type VoidFn = () => void | Promise<void>;
6
+ type HookType = "beforeAll" | "afterAll" | "beforeEach" | "afterEach";
7
+
8
+ interface SuiteNode {
9
+ name: string;
10
+ tests: { name: string; fn: VoidFn }[];
11
+ hooks: Record<HookType, VoidFn[]>;
12
+ parent?: SuiteNode;
13
+ }
14
+
15
+ class AtomicCore {
16
+ private static instance: AtomicCore;
17
+ private rootSuite: SuiteNode = {
18
+ name: "ROOT",
19
+ tests: [],
20
+ hooks: { beforeAll: [], afterAll: [], beforeEach: [], afterEach: [] },
21
+ };
22
+ private currentSuite: SuiteNode = this.rootSuite;
23
+ private suiteStarted = new Set<SuiteNode>();
24
+
25
+ static get() {
26
+ if (!AtomicCore.instance) AtomicCore.instance = new AtomicCore();
27
+ return AtomicCore.instance;
28
+ }
29
+
30
+ // --- Atomic Actions ---
31
+
32
+ defineGroup(name: string, fn: VoidFn) {
33
+ const parent = this.currentSuite;
34
+ const newSuite: SuiteNode = {
35
+ name,
36
+ tests: [],
37
+ hooks: { beforeAll: [], afterAll: [], beforeEach: [], afterEach: [] },
38
+ parent,
39
+ };
40
+
41
+ this.currentSuite = newSuite;
42
+ console.log(`\n📂 [GROUP] ${name}`);
43
+ try {
44
+ fn();
45
+ // Se houve algum afterAll, rodamos no fim do grupo
46
+ newSuite.hooks.afterAll.forEach((h) => h());
47
+ } finally {
48
+ this.currentSuite = parent;
49
+ }
50
+ }
51
+
52
+ defineCase(name: string, fn: VoidFn) {
53
+ console.log(` └─ 📝 [CASE] ${name}`);
54
+ this.runTestSafe(this.currentSuite, name, fn);
55
+ }
56
+
57
+ addHook(type: HookType, fn: VoidFn) {
58
+ this.currentSuite.hooks[type].push(fn);
59
+ }
60
+
61
+ // --- Internal Runner Logic ---
62
+
63
+ private async runTestSafe(suite: SuiteNode, name: string, fn: VoidFn) {
64
+ // Run beforeAll if first test in this suite
65
+ if (!this.suiteStarted.has(suite)) {
66
+ suite.hooks.beforeAll.forEach((h) => h());
67
+ this.suiteStarted.add(suite);
68
+ }
69
+
70
+ try {
71
+ // Run BeforeEach hooks
72
+ suite.hooks.beforeEach.forEach((h) => h());
73
+
74
+ await fn();
75
+ console.log(` ✅ PASS: ${suite.name} › ${name}`);
76
+
77
+ // Run AfterEach hooks
78
+ suite.hooks.afterEach.forEach((h) => h());
79
+ } catch (e) {
80
+ console.error(
81
+ ` ❌ FAIL: ${suite.name} › ${name} › ${(e as Error).message}`,
82
+ );
83
+ }
84
+ }
85
+
86
+ reset() {
87
+ this.rootSuite = {
88
+ name: "ROOT",
89
+ tests: [],
90
+ hooks: { beforeAll: [], afterAll: [], beforeEach: [], afterEach: [] },
91
+ };
92
+ this.currentSuite = this.rootSuite;
93
+ this.suiteStarted.clear();
94
+ }
95
+ }
96
+
97
+ const core = AtomicCore.get();
98
+
99
+ export const resetAtomicCore = () => core.reset();
100
+
101
+ // ============================================================================
102
+ // 2. UNIVERSAL MOCK (O Ator/Dublê)
103
+ // ============================================================================
104
+
105
+ class UniversalMockHandler {
106
+ public calls: any[][] = [];
107
+ private impl: ((...args: any[]) => any) | null = null;
108
+ private defaultReturn: any = undefined;
109
+ private isResolved: boolean = false;
110
+ private parent: UniversalMockHandler | null = null;
111
+
112
+ constructor(originalImpl?: (...args: any[]) => any) {
113
+ this.impl = originalImpl || null;
114
+ }
115
+
116
+ setParent(parent: UniversalMockHandler) {
117
+ this.parent = parent;
118
+ }
119
+
120
+ // O método que é chamado quando alguém invoca o mock
121
+ invoke(...args: any[]) {
122
+ this.calls.push(args);
123
+ // Notifica o pai que houve uma interação (útil para to(obj).wasCalled())
124
+ if (this.parent) this.parent.invoke(...args);
125
+
126
+ if (this.impl) return this.impl(...args);
127
+ if (this.isResolved) return Promise.resolve(this.defaultReturn);
128
+ return this.defaultReturn;
129
+ }
130
+
131
+ // --- Setup Methods (Aliases Internos) ---
132
+ setReturn(val: any) {
133
+ this.defaultReturn = val;
134
+ this.isResolved = false;
135
+ }
136
+ setResolved(val: any) {
137
+ this.defaultReturn = val;
138
+ this.isResolved = true;
139
+ }
140
+ setImplementation(fn: any) {
141
+ this.impl = fn;
142
+ }
143
+ clear() {
144
+ this.calls = [];
145
+ }
146
+ getDefaultReturn() {
147
+ return this.defaultReturn;
148
+ }
149
+ }
150
+
151
+ export interface AtomicMock extends Function {
152
+ (...args: any[]): any;
153
+ _handler: UniversalMockHandler;
154
+ // Jest compatible
155
+ mockReturnValue(v: any): void;
156
+ mockResolvedValue(v: any): void;
157
+ mockImplementation(fn: any): void;
158
+ // Math dialect
159
+ yields(v: any): void;
160
+ mapsTo(v: any): void;
161
+ convergesTo(v: any): void;
162
+ derive(fn: any): void;
163
+ // Narrative dialect
164
+ respondsWith(v: any): void;
165
+ eventuallyGives(v: any): void;
166
+ actsLike(fn: any): void;
167
+ // Imperative dialect
168
+ forceReturn(v: any): void;
169
+ resolveWith(v: any): void;
170
+ executes(fn: any): void;
171
+ // Shared
172
+ clear(): void;
173
+ reset(): void;
174
+ // Support for arbitrary method mocks (Deep Proxy)
175
+ [key: string]: any;
176
+ }
177
+
178
+ // A função mágica que é ao mesmo tempo executável e configurável
179
+ function createAtomicMock(
180
+ implementation?: (...args: any[]) => any,
181
+ parentHandler?: UniversalMockHandler,
182
+ ): AtomicMock {
183
+ const handler = new UniversalMockHandler(implementation);
184
+ if (parentHandler) handler.setParent(parentHandler);
185
+ const subMocks = new Map<string, any>();
186
+
187
+ const mockFn = (...args: any[]) => handler.invoke(...args);
188
+
189
+ // Mapeamento de TODOS os métodos de configuração de mocks
190
+ const config: Record<string, any> = {
191
+ _handler: handler,
192
+ // Jest
193
+ mockReturnValue: (v: any) => handler.setReturn(v),
194
+ mockResolvedValue: (v: any) => handler.setResolved(v),
195
+ mockImplementation: (fn: any) => handler.setImplementation(fn),
196
+
197
+ // Matemático
198
+ yields: (v: any) => handler.setReturn(v),
199
+ mapsTo: (v: any) => handler.setReturn(v),
200
+ convergesTo: (v: any) => handler.setResolved(v),
201
+ derive: (fn: any) => handler.setImplementation(fn),
202
+
203
+ // Narrativo
204
+ respondsWith: (v: any) => handler.setReturn(v),
205
+ eventuallyGives: (v: any) => handler.setResolved(v),
206
+ actsLike: (fn: any) => handler.setImplementation(fn),
207
+
208
+ // Imperativo
209
+ forceReturn: (v: any) => handler.setReturn(v),
210
+ resolveWith: (v: any) => handler.setResolved(v),
211
+ executes: (fn: any) => handler.setImplementation(fn),
212
+
213
+ // Common
214
+ clear: () => {
215
+ handler.clear();
216
+ subMocks.forEach((m) => m.clear());
217
+ },
218
+ reset: () => {
219
+ handler.clear();
220
+ handler.setImplementation(null);
221
+ handler.setReturn(undefined);
222
+ subMocks.clear();
223
+ },
224
+ };
225
+
226
+ // Retornamos um Proxy para permitir acesso a propriedades arbitrárias (como métodos)
227
+ return new Proxy(mockFn, {
228
+ get(target, prop: string) {
229
+ // 1. Se for um método de configuração ou propriedade interna, retorna do config
230
+ if (prop in config) return config[prop];
231
+ if (prop === "then") return undefined; // Evita problemas com Promises
232
+
233
+ // 2. Se o mock foi configurado para retornar um objeto, tentamos pegar a propriedade dele
234
+ const currentReturn = handler.getDefaultReturn();
235
+ if (
236
+ currentReturn &&
237
+ typeof currentReturn === "object" &&
238
+ prop in currentReturn
239
+ ) {
240
+ return currentReturn[prop];
241
+ }
242
+
243
+ // 3. Se for uma propriedade arbitrária e não temos valor, retornamos um sub-mock (lazy creation)
244
+ if (!subMocks.has(prop)) {
245
+ subMocks.set(prop, createAtomicMock(undefined, handler));
246
+ }
247
+ return subMocks.get(prop);
248
+ },
249
+ // Permite Object.assign e outras operações
250
+ set(target, prop: string, value: any) {
251
+ config[prop] = value;
252
+ return true;
253
+ },
254
+ }) as unknown as AtomicMock;
255
+ }
256
+
257
+ function createAtomicSpy(obj: any, method: string) {
258
+ const original = obj[method];
259
+ const mock = createAtomicMock(original);
260
+ obj[method] = mock;
261
+ return mock; // Retorna o mock para asserções
262
+ }
263
+
264
+ // ============================================================================
265
+ // 3. UNIVERSAL ASSERTION (O Juiz)
266
+ // ============================================================================
267
+
268
+ class UniversalAssertion<T> {
269
+ constructor(
270
+ private actual: T,
271
+ private isNegated: boolean = false,
272
+ ) {}
273
+
274
+ get not() {
275
+ return new UniversalAssertion(this.actual, !this.isNegated);
276
+ }
277
+
278
+ private pass(condition: boolean, msg: string) {
279
+ const success = this.isNegated ? !condition : condition;
280
+ if (!success) throw new Error(this.isNegated ? `[NOT] ${msg}` : msg);
281
+ }
282
+
283
+ // --- Equality & Truthiness ---
284
+
285
+ // Jest / Classic
286
+ toBe(expected: T) {
287
+ this.pass(
288
+ this.actual === expected,
289
+ `Expected ${this.actual} to be ${expected}`,
290
+ );
291
+ }
292
+ toEqual(expected: T) {
293
+ this.pass(
294
+ JSON.stringify(this.actual) === JSON.stringify(expected),
295
+ `Expected ${this.actual} to equal ${expected}`,
296
+ );
297
+ }
298
+
299
+ // Matemático
300
+ is(expected: T) {
301
+ this.toBe(expected);
302
+ }
303
+
304
+ // Narrativo
305
+ be(expected: T) {
306
+ this.toBe(expected);
307
+ }
308
+
309
+ // Imperativo
310
+ isOk() {
311
+ this.pass(!!this.actual, `Ensure ${this.actual} is truthy`);
312
+ }
313
+ matches(regex: RegExp) {
314
+ if (typeof this.actual !== "string")
315
+ throw new Error("Value must be string");
316
+ this.pass(
317
+ regex.test(this.actual),
318
+ `Ensure '${this.actual}' matches ${regex}`,
319
+ );
320
+ }
321
+
322
+ // Narrativo
323
+ have(prop: string) {
324
+ this.pass(
325
+ typeof this.actual === "object" &&
326
+ this.actual !== null &&
327
+ prop in (this.actual as any),
328
+ `Intend object to have '${prop}'`,
329
+ );
330
+ }
331
+ uploaded(...args: any[]) {
332
+ this.received(...args);
333
+ }
334
+
335
+ // --- Mock Assertions ---
336
+
337
+ // Helper para pegar o handler do mock
338
+ private getMockHandler(mockFn: any) {
339
+ if (!mockFn._handler)
340
+ throw new Error(
341
+ "Assertion target is not a registered Mock/Spy function.",
342
+ );
343
+ return mockFn._handler as UniversalMockHandler;
344
+ }
345
+
346
+ // Jest
347
+ toHaveBeenCalled() {
348
+ const h = this.getMockHandler(this.actual);
349
+ this.pass(h.calls.length > 0, "Expected mock to have been called");
350
+ }
351
+ toHaveBeenCalledWith(...args: any[]) {
352
+ const h = this.getMockHandler(this.actual);
353
+ const match = h.calls.some(
354
+ (call) => JSON.stringify(call) === JSON.stringify(args),
355
+ );
356
+ this.pass(match, `Expected mock called with ${JSON.stringify(args)}`);
357
+ }
358
+ toHaveBeenCalledTimes(n: number) {
359
+ const h = this.getMockHandler(this.actual);
360
+ this.pass(
361
+ h.calls.length === n,
362
+ `Expected mock called ${n} times, got ${h.calls.length}`,
363
+ );
364
+ }
365
+
366
+ // Matemático
367
+ wasEvaluated() {
368
+ this.toHaveBeenCalled();
369
+ }
370
+ appliedTo(...args: any[]) {
371
+ this.toHaveBeenCalledWith(...args);
372
+ }
373
+ get evaluated() {
374
+ const h = this.getMockHandler(this.actual);
375
+ return (n: number) => ({ times: this.toHaveBeenCalledTimes(n) }); // Currying simulado para sintaxe .evaluated(n).times
376
+ }
377
+
378
+ // Narrativo
379
+ wasCalled() {
380
+ this.toHaveBeenCalled();
381
+ }
382
+ received(...args: any[]) {
383
+ this.toHaveBeenCalledWith(...args);
384
+ }
385
+ get called() {
386
+ const h = this.getMockHandler(this.actual);
387
+ return (n: number) => ({ times: this.toHaveBeenCalledTimes(n) });
388
+ }
389
+
390
+ // Imperativo
391
+ triggered() {
392
+ this.toHaveBeenCalled();
393
+ }
394
+ calledWith(...args: any[]) {
395
+ this.toHaveBeenCalledWith(...args);
396
+ }
397
+ triggeredCount(n: number) {
398
+ this.toHaveBeenCalledTimes(n);
399
+ }
400
+ }
401
+
402
+ // Factory para assertions
403
+ const assertValue = <T>(val: T) => new UniversalAssertion(val);
404
+
405
+ // ============================================================================
406
+ // 4. DIALECT EXPORTS (A Pedra de Roseta)
407
+ // ============================================================================
408
+
409
+ // --- 📐 MATEMÁTICO (MathDialect) ---
410
+ export const MathDialect = {
411
+ // Structure
412
+ axiom: (n: string, f: VoidFn) => core.defineGroup(n, f),
413
+ proof: (n: string, f: VoidFn) => core.defineCase(n, f),
414
+ implies: assertValue,
415
+
416
+ // Mocks (Creation)
417
+ arbitrary: createAtomicMock,
418
+ lambda: createAtomicMock,
419
+ monitor: createAtomicSpy,
420
+
421
+ // Lifecycle
422
+ postulate: (f: VoidFn) => core.addHook("beforeAll", f),
423
+ conclude: (f: VoidFn) => core.addHook("afterAll", f),
424
+ given: (f: VoidFn) => core.addHook("beforeEach", f),
425
+ };
426
+
427
+ // --- 📖 NARRATIVO (NarrativeDialect) ---
428
+ export const NarrativeDialect = {
429
+ // Structure
430
+ intend: (n: string, f: VoidFn) => core.defineGroup(n, f),
431
+ story: (n: string, f: VoidFn) => core.defineGroup(n, f),
432
+ detail: (n: string, f: VoidFn) => core.defineCase(n, f),
433
+ scenario: (n: string, f: VoidFn) => core.defineCase(n, f),
434
+ to: assertValue,
435
+
436
+ // Mocks (Creation)
437
+ dummy: createAtomicMock,
438
+ standIn: createAtomicMock,
439
+ watch: createAtomicSpy,
440
+ shadow: createAtomicSpy,
441
+
442
+ // Lifecycle
443
+ background: (f: VoidFn) => core.addHook("beforeAll", f),
444
+ cleanup: (f: VoidFn) => core.addHook("afterAll", f),
445
+ before: (f: VoidFn) => core.addHook("beforeEach", f),
446
+ };
447
+
448
+ // --- 🛡️ IMPERATIVO (ImperativeDialect) ---
449
+ export const ImperativeDialect = {
450
+ // Structure
451
+ ensure: (n: string, f: VoidFn) => core.defineGroup(n, f),
452
+ suite: (n: string, f: VoidFn) => core.defineGroup(n, f),
453
+ check: (n: string, f: VoidFn) => core.defineCase(n, f),
454
+ verify: (n: string, f: VoidFn) => core.defineCase(n, f),
455
+ that: assertValue,
456
+
457
+ // Mocks (Creation)
458
+ stub: createAtomicMock,
459
+ mock: createAtomicMock,
460
+ inspect: createAtomicSpy,
461
+ spy: createAtomicSpy,
462
+
463
+ // Lifecycle
464
+ initAll: (f: VoidFn) => core.addHook("beforeAll", f),
465
+ disposeAll: (f: VoidFn) => core.addHook("afterAll", f),
466
+ reset: (f: VoidFn) => core.addHook("beforeEach", f),
467
+ clear: () => {}, // No-op for global clear
468
+ };
469
+
470
+ // --- 🤡 JEST / CLASSIC ---
471
+ export const ClassicDialect = {
472
+ describe: (n: string, f: VoidFn) => core.defineGroup(n, f),
473
+ it: (n: string, f: VoidFn) => core.defineCase(n, f),
474
+ test: (n: string, f: VoidFn) => core.defineCase(n, f),
475
+ expect: assertValue,
476
+
477
+ // Objeto Jest Global (simulado)
478
+ jest: {
479
+ fn: createAtomicMock,
480
+ spyOn: createAtomicSpy,
481
+ },
482
+
483
+ beforeAll: (f: VoidFn) => core.addHook("beforeAll", f),
484
+ afterAll: (f: VoidFn) => core.addHook("afterAll", f),
485
+ beforeEach: (f: VoidFn) => core.addHook("beforeEach", f),
486
+ afterEach: (f: VoidFn) => core.addHook("afterEach", f),
487
+ };
488
+
489
+ // --- Top-Level Exports for Ease of Use ---
490
+ export const {
491
+ axiom,
492
+ proof,
493
+ implies,
494
+ arbitrary,
495
+ lambda,
496
+ monitor,
497
+ postulate,
498
+ conclude,
499
+ given,
500
+ } = MathDialect;
501
+ export const {
502
+ intend,
503
+ story,
504
+ detail,
505
+ scenario,
506
+ to,
507
+ dummy,
508
+ standIn,
509
+ watch,
510
+ shadow,
511
+ background,
512
+ cleanup,
513
+ before,
514
+ } = NarrativeDialect;
515
+ export const {
516
+ ensure,
517
+ suite,
518
+ check,
519
+ verify,
520
+ that,
521
+ stub,
522
+ mock,
523
+ inspect,
524
+ spy,
525
+ initAll,
526
+ disposeAll,
527
+ reset,
528
+ clear,
529
+ } = ImperativeDialect;
530
+ export const {
531
+ describe,
532
+ it,
533
+ test,
534
+ expect,
535
+ beforeAll,
536
+ afterAll,
537
+ beforeEach,
538
+ afterEach,
539
+ } = ClassicDialect;