@lydt/geogebra-studio 0.0.0-stage → 0.4.0-rc.1

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 (183) hide show
  1. package/.agents/plugins/marketplace.json +21 -0
  2. package/.codex-plugin/plugin.json +21 -0
  3. package/.mcp.json +15 -0
  4. package/LICENSE +339 -0
  5. package/LICENSE-MIT +21 -0
  6. package/README.md +106 -2
  7. package/README.zh-CN.md +87 -0
  8. package/THIRD_PARTY_NOTICES.md +35 -0
  9. package/dist/cli.d.ts +27 -0
  10. package/dist/cli.d.ts.map +1 -0
  11. package/dist/cli.js +234 -0
  12. package/dist/cli.js.map +1 -0
  13. package/dist/export/files.d.ts +4 -0
  14. package/dist/export/files.d.ts.map +1 -0
  15. package/dist/export/files.js +43 -0
  16. package/dist/export/files.js.map +1 -0
  17. package/dist/export/gikz.d.ts +11 -0
  18. package/dist/export/gikz.d.ts.map +1 -0
  19. package/dist/export/gikz.js +28 -0
  20. package/dist/export/gikz.js.map +1 -0
  21. package/dist/export/html.d.ts +14 -0
  22. package/dist/export/html.d.ts.map +1 -0
  23. package/dist/export/html.js +97 -0
  24. package/dist/export/html.js.map +1 -0
  25. package/dist/export/semantic.d.ts +43 -0
  26. package/dist/export/semantic.d.ts.map +1 -0
  27. package/dist/export/semantic.js +212 -0
  28. package/dist/export/semantic.js.map +1 -0
  29. package/dist/export/viewer-themes.d.ts +76 -0
  30. package/dist/export/viewer-themes.d.ts.map +1 -0
  31. package/dist/export/viewer-themes.js +169 -0
  32. package/dist/export/viewer-themes.js.map +1 -0
  33. package/dist/gikz-browser.js +770 -0
  34. package/dist/index.d.ts +5 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +84 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/server.d.ts +35 -0
  39. package/dist/server.d.ts.map +1 -0
  40. package/dist/server.js +175 -0
  41. package/dist/server.js.map +1 -0
  42. package/dist/studio/artifact.d.ts +37 -0
  43. package/dist/studio/artifact.d.ts.map +1 -0
  44. package/dist/studio/artifact.js +61 -0
  45. package/dist/studio/artifact.js.map +1 -0
  46. package/dist/studio/browser.d.ts +7 -0
  47. package/dist/studio/browser.d.ts.map +1 -0
  48. package/dist/studio/browser.js +67 -0
  49. package/dist/studio/browser.js.map +1 -0
  50. package/dist/studio/install.d.ts +4 -0
  51. package/dist/studio/install.d.ts.map +1 -0
  52. package/dist/studio/install.js +60 -0
  53. package/dist/studio/install.js.map +1 -0
  54. package/dist/tools/apps-api-tools.d.ts +4 -0
  55. package/dist/tools/apps-api-tools.d.ts.map +1 -0
  56. package/dist/tools/apps-api-tools.js +96 -0
  57. package/dist/tools/apps-api-tools.js.map +1 -0
  58. package/dist/tools/educational-templates.d.ts +33 -0
  59. package/dist/tools/educational-templates.d.ts.map +1 -0
  60. package/dist/tools/educational-templates.js +261 -0
  61. package/dist/tools/educational-templates.js.map +1 -0
  62. package/dist/tools/export-tools.d.ts +3 -0
  63. package/dist/tools/export-tools.d.ts.map +1 -0
  64. package/dist/tools/export-tools.js +118 -0
  65. package/dist/tools/export-tools.js.map +1 -0
  66. package/dist/tools/geogebra-tools.d.ts +15 -0
  67. package/dist/tools/geogebra-tools.d.ts.map +1 -0
  68. package/dist/tools/geogebra-tools.js +3441 -0
  69. package/dist/tools/geogebra-tools.js.map +1 -0
  70. package/dist/tools/index.d.ts +43 -0
  71. package/dist/tools/index.d.ts.map +1 -0
  72. package/dist/tools/index.js +183 -0
  73. package/dist/tools/index.js.map +1 -0
  74. package/dist/tools/performance-tools.d.ts +7 -0
  75. package/dist/tools/performance-tools.d.ts.map +1 -0
  76. package/dist/tools/performance-tools.js +312 -0
  77. package/dist/tools/performance-tools.js.map +1 -0
  78. package/dist/tools/templates/algebra-templates.d.ts +7 -0
  79. package/dist/tools/templates/algebra-templates.d.ts.map +1 -0
  80. package/dist/tools/templates/algebra-templates.js +568 -0
  81. package/dist/tools/templates/algebra-templates.js.map +1 -0
  82. package/dist/tools/templates/geometry-templates.d.ts +7 -0
  83. package/dist/tools/templates/geometry-templates.d.ts.map +1 -0
  84. package/dist/tools/templates/geometry-templates.js +492 -0
  85. package/dist/tools/templates/geometry-templates.js.map +1 -0
  86. package/dist/types/geogebra.d.ts +103 -0
  87. package/dist/types/geogebra.d.ts.map +1 -0
  88. package/dist/types/geogebra.js +34 -0
  89. package/dist/types/geogebra.js.map +1 -0
  90. package/dist/types/mcp.d.ts +125 -0
  91. package/dist/types/mcp.d.ts.map +1 -0
  92. package/dist/types/mcp.js +19 -0
  93. package/dist/types/mcp.js.map +1 -0
  94. package/dist/utils/app-info.d.ts +12 -0
  95. package/dist/utils/app-info.d.ts.map +1 -0
  96. package/dist/utils/app-info.js +30 -0
  97. package/dist/utils/app-info.js.map +1 -0
  98. package/dist/utils/errors.d.ts +37 -0
  99. package/dist/utils/errors.d.ts.map +1 -0
  100. package/dist/utils/errors.js +72 -0
  101. package/dist/utils/errors.js.map +1 -0
  102. package/dist/utils/gemini-compatibility.d.ts +39 -0
  103. package/dist/utils/gemini-compatibility.d.ts.map +1 -0
  104. package/dist/utils/gemini-compatibility.js +154 -0
  105. package/dist/utils/gemini-compatibility.js.map +1 -0
  106. package/dist/utils/geogebra-instance.d.ts +252 -0
  107. package/dist/utils/geogebra-instance.d.ts.map +1 -0
  108. package/dist/utils/geogebra-instance.js +1559 -0
  109. package/dist/utils/geogebra-instance.js.map +1 -0
  110. package/dist/utils/geogebra-mock.d.ts +172 -0
  111. package/dist/utils/geogebra-mock.d.ts.map +1 -0
  112. package/dist/utils/geogebra-mock.js +732 -0
  113. package/dist/utils/geogebra-mock.js.map +1 -0
  114. package/dist/utils/logger.d.ts +4 -0
  115. package/dist/utils/logger.d.ts.map +1 -0
  116. package/dist/utils/logger.js +46 -0
  117. package/dist/utils/logger.js.map +1 -0
  118. package/dist/utils/performance/index.d.ts +76 -0
  119. package/dist/utils/performance/index.d.ts.map +1 -0
  120. package/dist/utils/performance/index.js +163 -0
  121. package/dist/utils/performance/index.js.map +1 -0
  122. package/dist/utils/performance/instance-pool.d.ts +78 -0
  123. package/dist/utils/performance/instance-pool.d.ts.map +1 -0
  124. package/dist/utils/performance/instance-pool.js +268 -0
  125. package/dist/utils/performance/instance-pool.js.map +1 -0
  126. package/dist/utils/validation.d.ts +92 -0
  127. package/dist/utils/validation.d.ts.map +1 -0
  128. package/dist/utils/validation.js +557 -0
  129. package/dist/utils/validation.js.map +1 -0
  130. package/dist/widget.html +110 -0
  131. package/docs/APPS-API-BRIDGE.md +28 -0
  132. package/docs/MODERNIZATION.md +15 -0
  133. package/docs/TANGENT-REGRESSION.md +31 -0
  134. package/docs/VALIDATION.md +23 -0
  135. package/docs/VISUAL-STANDARD.md +26 -0
  136. package/docs/images/native-construction.png +0 -0
  137. package/examples/tangent-construction.json +26 -0
  138. package/gikz/LICENSE +339 -0
  139. package/gikz/PROVENANCE.md +8 -0
  140. package/gikz/browser.cjs +2 -0
  141. package/gikz/cli.cjs +195 -0
  142. package/gikz/core.cjs +806 -0
  143. package/mcp.json +17 -0
  144. package/package.json +106 -4
  145. package/plugin.json +35 -0
  146. package/scripts/build-plugin.cjs +15 -0
  147. package/scripts/build-widget.cjs +7 -0
  148. package/skills/geogebra-construct/SKILL.md +37 -0
  149. package/skills/geogebra-setup/SKILL.md +33 -0
  150. package/skills/geometry-export/SKILL.md +29 -0
  151. package/src/cli.ts +212 -0
  152. package/src/export/files.ts +25 -0
  153. package/src/export/gikz.ts +22 -0
  154. package/src/export/html.ts +108 -0
  155. package/src/export/semantic.ts +180 -0
  156. package/src/export/viewer-themes.ts +165 -0
  157. package/src/index.ts +71 -0
  158. package/src/server.ts +156 -0
  159. package/src/studio/artifact.ts +50 -0
  160. package/src/studio/browser.ts +38 -0
  161. package/src/studio/install.ts +43 -0
  162. package/src/tools/apps-api-tools.ts +96 -0
  163. package/src/tools/educational-templates.ts +299 -0
  164. package/src/tools/export-tools.ts +110 -0
  165. package/src/tools/geogebra-tools.ts +3835 -0
  166. package/src/tools/index.ts +192 -0
  167. package/src/tools/performance-tools.ts +322 -0
  168. package/src/tools/templates/algebra-templates.ts +619 -0
  169. package/src/tools/templates/geometry-templates.ts +550 -0
  170. package/src/types/geogebra.ts +140 -0
  171. package/src/types/global.d.ts +31 -0
  172. package/src/types/mcp.ts +141 -0
  173. package/src/utils/app-info.ts +35 -0
  174. package/src/utils/errors.ts +97 -0
  175. package/src/utils/gemini-compatibility.ts +193 -0
  176. package/src/utils/geogebra-instance.ts +1711 -0
  177. package/src/utils/geogebra-mock.ts +867 -0
  178. package/src/utils/logger.ts +60 -0
  179. package/src/utils/performance/index.ts +211 -0
  180. package/src/utils/performance/instance-pool.ts +323 -0
  181. package/src/utils/validation.ts +647 -0
  182. package/tsconfig.json +35 -0
  183. package/widget/main.ts +12 -0
package/dist/cli.d.ts ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * CLI entry point for GeoGebra Studio
4
+ * Enables npx usage: npx @lydt/geogebra-studio
5
+ */
6
+ /**
7
+ * Display help information
8
+ */
9
+ declare function showHelp(): void;
10
+ /**
11
+ * Display version information
12
+ */
13
+ declare function showVersion(): void;
14
+ /**
15
+ * Parse command line arguments
16
+ */
17
+ declare function parseArgs(args: string[]): {
18
+ help: boolean;
19
+ version: boolean;
20
+ logLevel: string;
21
+ port: string | undefined;
22
+ };
23
+ /**
24
+ * Main CLI function
25
+ */
26
+ declare function main(): Promise<void>;
27
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA;;;GAGG;AAEH;;GAEG;AACH,iBAAS,QAAQ,SA4BhB;AAED;;GAEG;AACH,iBAAS,WAAW,SAGnB;AAED;;GAEG;AACH,iBAAS,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE;;;;;EA8DhC;AAED;;GAEG;AACH,iBAAe,IAAI,kBAuFlB"}
package/dist/cli.js ADDED
@@ -0,0 +1,234 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * CLI entry point for GeoGebra Studio
5
+ * Enables npx usage: npx @lydt/geogebra-studio
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || (function () {
24
+ var ownKeys = function(o) {
25
+ ownKeys = Object.getOwnPropertyNames || function (o) {
26
+ var ar = [];
27
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
28
+ return ar;
29
+ };
30
+ return ownKeys(o);
31
+ };
32
+ return function (mod) {
33
+ if (mod && mod.__esModule) return mod;
34
+ var result = {};
35
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
36
+ __setModuleDefault(result, mod);
37
+ return result;
38
+ };
39
+ })();
40
+ /**
41
+ * Display help information
42
+ */
43
+ function showHelp() {
44
+ const packageJson = require('../package.json');
45
+ const homepage = packageJson.homepage || 'https://github.com/YZDame/geogebra-mcp-server';
46
+ console.log(`
47
+ GeoGebra Studio - Mathematical Visualization via Model Context Protocol
48
+
49
+ Usage:
50
+ npx @lydt/geogebra-studio [options]
51
+
52
+ Options:
53
+ install Install the complete Codex plugin (skills + MCP)
54
+ doctor Check built-in Gikz and browser launch
55
+ browser install Prepare Chrome or managed Chromium
56
+ mcp Start only the MCP server (also the no-argument default)
57
+
58
+ -h, --help Show this help message
59
+ -v, --version Show version information
60
+ --log-level LEVEL Set log level (error, warn, info, debug) [default: info]
61
+ --port PORT Serve Streamable HTTP at http://127.0.0.1:PORT/mcp
62
+
63
+ Examples:
64
+ npx @lydt/geogebra-studio # Start MCP server on stdin/stdout
65
+ npx @lydt/geogebra-studio --log-level debug # Start with debug logging
66
+ npx @lydt/geogebra-studio --help # Show this help
67
+
68
+ For more information, visit: ${homepage}
69
+ `);
70
+ }
71
+ /**
72
+ * Display version information
73
+ */
74
+ function showVersion() {
75
+ const packageJson = require('../package.json');
76
+ console.log(`GeoGebra Studio v${packageJson.version}`);
77
+ }
78
+ /**
79
+ * Parse command line arguments
80
+ */
81
+ function parseArgs(args) {
82
+ const options = {
83
+ help: false,
84
+ version: false,
85
+ logLevel: process.env['LOG_LEVEL'] || 'info',
86
+ port: process.env['PORT'] || undefined
87
+ };
88
+ for (let i = 0; i < args.length; i++) {
89
+ const arg = args[i];
90
+ // Type guard to ensure arg is defined
91
+ if (!arg)
92
+ continue;
93
+ switch (arg) {
94
+ case '-h':
95
+ case '--help':
96
+ options.help = true;
97
+ break;
98
+ case '-v':
99
+ case '--version':
100
+ options.version = true;
101
+ break;
102
+ case '--log-level':
103
+ if (i + 1 < args.length && args[i + 1]) {
104
+ const level = args[i + 1]; // Non-null assertion since we checked above
105
+ if (['error', 'warn', 'info', 'debug'].includes(level)) {
106
+ options.logLevel = level;
107
+ i++; // Skip next argument
108
+ }
109
+ else {
110
+ console.error(`Invalid log level: ${level}`);
111
+ process.exit(1);
112
+ }
113
+ }
114
+ else {
115
+ console.error('--log-level requires a value');
116
+ process.exit(1);
117
+ }
118
+ break;
119
+ case '--port':
120
+ if (i + 1 < args.length && args[i + 1]) {
121
+ options.port = args[i + 1]; // Non-null assertion since we checked above
122
+ i++; // Skip next argument
123
+ }
124
+ else {
125
+ console.error('--port requires a value');
126
+ process.exit(1);
127
+ }
128
+ break;
129
+ default:
130
+ if (arg.startsWith('-')) {
131
+ console.error(`Unknown option: ${arg}`);
132
+ console.error('Use --help for usage information');
133
+ process.exit(1);
134
+ }
135
+ break;
136
+ }
137
+ }
138
+ return options;
139
+ }
140
+ /**
141
+ * Main CLI function
142
+ */
143
+ async function main() {
144
+ try {
145
+ // Parse command line arguments first
146
+ const args = process.argv.slice(2);
147
+ if (args[0] === 'install') {
148
+ if (args.slice(1).some(arg => arg !== '--local'))
149
+ throw new Error('Usage: install [--local]');
150
+ await (await Promise.resolve().then(() => __importStar(require('./studio/install')))).installPlugin(args.includes('--local'));
151
+ return;
152
+ }
153
+ if (args[0] === 'doctor' || args[0] === 'browser') {
154
+ if (args[0] === 'browser' && (args.length !== 2 || args[1] !== 'install'))
155
+ throw new Error('Usage: browser install');
156
+ const { prepareBrowser } = await Promise.resolve().then(() => __importStar(require('./studio/browser')));
157
+ const { cleanWithGikz } = await Promise.resolve().then(() => __importStar(require('./export/gikz')));
158
+ await cleanWithGikz(String.raw `\begin{tikzpicture}\end{tikzpicture}`);
159
+ const executablePath = await prepareBrowser(args[0] === 'browser');
160
+ console.log(JSON.stringify({ success: true, version: require('../package.json').version, gikz: 'built-in', executablePath }));
161
+ return;
162
+ }
163
+ if (args[0] === 'mcp')
164
+ args.shift();
165
+ if (args[0] && !args[0].startsWith('-'))
166
+ throw new Error('Unknown command: ' + args[0]);
167
+ const options = parseArgs(args);
168
+ // Handle help and version BEFORE loading any dependencies
169
+ if (options.help) {
170
+ showHelp();
171
+ process.exit(0);
172
+ }
173
+ if (options.version) {
174
+ showVersion();
175
+ process.exit(0);
176
+ }
177
+ // Only import heavy dependencies if we're actually starting the server
178
+ await Promise.resolve().then(() => __importStar(require('dotenv/config')));
179
+ const { McpServer } = await Promise.resolve().then(() => __importStar(require('./server')));
180
+ const { getAppInfo } = await Promise.resolve().then(() => __importStar(require('./utils/app-info')));
181
+ const { default: logger } = await Promise.resolve().then(() => __importStar(require('./utils/logger')));
182
+ const appInfo = getAppInfo();
183
+ // Server configuration
184
+ const config = {
185
+ name: 'GeoGebra Studio',
186
+ version: appInfo.version,
187
+ description: appInfo.description,
188
+ logLevel: options.logLevel
189
+ };
190
+ logger.info('Starting GeoGebra Studio...');
191
+ logger.info(`Log level: ${config.logLevel}`);
192
+ // Create and start the MCP server
193
+ const server = new McpServer(config);
194
+ // Set up graceful shutdown
195
+ const shutdown = async (signal) => {
196
+ logger.info(`Received ${signal}, shutting down gracefully...`);
197
+ try {
198
+ await server.stop();
199
+ process.exit(0);
200
+ }
201
+ catch (error) {
202
+ logger.error('Error during shutdown:', error);
203
+ process.exit(1);
204
+ }
205
+ };
206
+ // Handle shutdown signals
207
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
208
+ process.on('SIGINT', () => shutdown('SIGINT'));
209
+ // Handle uncaught exceptions
210
+ process.on('uncaughtException', (error) => {
211
+ logger.error('Uncaught exception:', error);
212
+ process.exit(1);
213
+ });
214
+ process.on('unhandledRejection', (reason, promise) => {
215
+ logger.error('Unhandled rejection at:', promise, 'reason:', reason);
216
+ process.exit(1);
217
+ });
218
+ // Start the server
219
+ if (options.port)
220
+ await server.startHttp(Number(options.port));
221
+ else
222
+ await server.start();
223
+ }
224
+ catch (error) {
225
+ console.error('Failed to start server:', error);
226
+ process.exit(1);
227
+ }
228
+ }
229
+ // Start the CLI application
230
+ main().catch((error) => {
231
+ console.error('CLI startup failed:', error);
232
+ process.exit(1);
233
+ });
234
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ /** Restrict new export destinations, including existing ancestor symlinks, to workspace. */
2
+ export declare function saveFile(filename: unknown, content: string | Uint8Array): Promise<string | undefined>;
3
+ export declare const saveText: (filename: unknown, content: string) => Promise<string | undefined>;
4
+ //# sourceMappingURL=files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../src/export/files.ts"],"names":[],"mappings":"AAGA,4FAA4F;AAC5F,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAkB3G;AAED,eAAO,MAAM,QAAQ,GAAI,UAAU,OAAO,EAAE,SAAS,MAAM,gCAA+B,CAAC"}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.saveText = void 0;
7
+ exports.saveFile = saveFile;
8
+ const promises_1 = require("fs/promises");
9
+ const path_1 = __importDefault(require("path"));
10
+ /** Restrict new export destinations, including existing ancestor symlinks, to workspace. */
11
+ async function saveFile(filename, content) {
12
+ if (filename === undefined)
13
+ return undefined;
14
+ if (typeof filename !== 'string' || !filename.trim())
15
+ throw new Error('filename must be a nonempty string');
16
+ const root = await (0, promises_1.realpath)(process.env['VSCODE_WORKSPACE_FOLDER'] || process.cwd());
17
+ const target = path_1.default.resolve(root, filename);
18
+ const inside = (s) => s.startsWith(root + path_1.default.sep);
19
+ if (!inside(target))
20
+ throw new Error('Export path is outside workspace');
21
+ // Validate every existing component before creating directories.
22
+ let current = root;
23
+ for (const part of path_1.default.relative(root, target).split(path_1.default.sep)) {
24
+ current = path_1.default.join(current, part);
25
+ try {
26
+ const stat = await (0, promises_1.lstat)(current);
27
+ if (stat.isSymbolicLink())
28
+ throw new Error('Export paths may not contain symbolic links');
29
+ }
30
+ catch (e) {
31
+ if (e.code !== 'ENOENT')
32
+ throw e;
33
+ }
34
+ }
35
+ await (0, promises_1.mkdir)(path_1.default.dirname(target), { recursive: true });
36
+ if (!inside(await (0, promises_1.realpath)(path_1.default.dirname(target))) && path_1.default.dirname(target) !== root)
37
+ throw new Error('Export parent is outside workspace');
38
+ await (0, promises_1.writeFile)(target, content, { flag: 'wx' });
39
+ return target;
40
+ }
41
+ const saveText = (filename, content) => saveFile(filename, content);
42
+ exports.saveText = saveText;
43
+ //# sourceMappingURL=files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../src/export/files.ts"],"names":[],"mappings":";;;;;;AAIA,4BAkBC;AAtBD,0CAAgE;AAChE,gDAAwB;AAExB,4FAA4F;AACrF,KAAK,UAAU,QAAQ,CAAC,QAAiB,EAAE,OAA4B;IAC5E,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC7C,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IAC5G,MAAM,IAAI,GAAG,MAAM,IAAA,mBAAQ,EAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IACrF,MAAM,MAAM,GAAG,cAAI,CAAC,OAAO,CAAC,IAAI,EAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,GAAC,cAAI,CAAC,GAAG,CAAC,CAAC;IAC1D,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACzE,iEAAiE;IACjE,IAAI,OAAO,GAAC,IAAI,CAAC;IACjB,KAAK,MAAM,IAAI,IAAI,cAAI,CAAC,QAAQ,CAAC,IAAI,EAAC,MAAM,CAAC,CAAC,KAAK,CAAC,cAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC9D,OAAO,GAAC,cAAI,CAAC,IAAI,CAAC,OAAO,EAAC,IAAI,CAAC,CAAC;QAChC,IAAI,CAAC;YAAC,MAAM,IAAI,GAAC,MAAM,IAAA,gBAAK,EAAC,OAAO,CAAC,CAAC;YAAC,IAAG,IAAI,CAAC,cAAc,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAAC,CAAC;QAClI,OAAM,CAAC,EAAE,CAAC;YAAC,IAAK,CAA2B,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,CAAC,CAAC;QAAC,CAAC;IAC3E,CAAC;IACD,MAAM,IAAA,gBAAK,EAAC,cAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAC,EAAC,SAAS,EAAC,IAAI,EAAC,CAAC,CAAC;IACnD,IAAI,CAAC,MAAM,CAAC,MAAM,IAAA,mBAAQ,EAAC,cAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,cAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAG,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACxI,MAAM,IAAA,oBAAS,EAAC,MAAM,EAAC,OAAO,EAAC,EAAC,IAAI,EAAC,IAAI,EAAC,CAAC,CAAC;IAC5C,OAAO,MAAM,CAAC;AAChB,CAAC;AAEM,MAAM,QAAQ,GAAG,CAAC,QAAiB,EAAE,OAAe,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAC,OAAO,CAAC,CAAC;AAA9E,QAAA,QAAQ,YAAsE"}
@@ -0,0 +1,11 @@
1
+ interface GikzOptions {
2
+ standalone?: boolean;
3
+ points?: boolean;
4
+ labels?: boolean;
5
+ round?: boolean;
6
+ }
7
+ /** Source and GPL license travel with the viewer; no eval or external cleaner. */
8
+ export declare function gikzBrowserScripts(): string;
9
+ export declare function cleanWithGikz(source: string, options?: GikzOptions): Promise<string>;
10
+ export {};
11
+ //# sourceMappingURL=gikz.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gikz.d.ts","sourceRoot":"","sources":["../../src/export/gikz.ts"],"names":[],"mappings":"AAEA,UAAU,WAAW;IAAE,UAAU,CAAC,EAAC,OAAO,CAAC;IAAA,MAAM,CAAC,EAAC,OAAO,CAAC;IAAA,MAAM,CAAC,EAAC,OAAO,CAAC;IAAA,KAAK,CAAC,EAAC,OAAO,CAAA;CAAC;AAM1F,kFAAkF;AAClF,wBAAgB,kBAAkB,IAAI,MAAM,CAI3C;AACD,wBAAsB,aAAa,CAAC,MAAM,EAAC,MAAM,EAAC,OAAO,GAAC,WAAc,GAAE,OAAO,CAAC,MAAM,CAAC,CAOxF"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.gikzBrowserScripts = gikzBrowserScripts;
7
+ exports.cleanWithGikz = cleanWithGikz;
8
+ const path_1 = __importDefault(require("path"));
9
+ const fs_1 = require("fs");
10
+ const core = require('../../gikz/core.cjs');
11
+ /** Source and GPL license travel with the viewer; no eval or external cleaner. */
12
+ function gikzBrowserScripts() {
13
+ const source = (0, fs_1.readFileSync)(path_1.default.join(__dirname, '../../dist/gikz-browser.js'), 'utf8').replace(/<\/script/gi, '<\\/script');
14
+ const license = JSON.stringify((0, fs_1.readFileSync)(path_1.default.join(__dirname, '../../gikz/LICENSE'), 'utf8')).replace(/</g, '\\u003c');
15
+ return `<script id="gikz-license" type="application/json">${license}</script>\n<script id="gikz-browser">${source}</script>`;
16
+ }
17
+ async function cleanWithGikz(source, options = {}) {
18
+ if (source.length > 10_000_000)
19
+ throw new Error('Gikz input exceeds 10 MB');
20
+ let code = source.includes('<geogebra') && source.includes('<construction')
21
+ ? core.convertGeoGebraXML(source, options) : core.cleanTikZCode(source, options);
22
+ if (options.standalone)
23
+ code = core.wrapStandalone(code);
24
+ if (!code.includes('\\begin{tikzpicture}'))
25
+ throw new Error('Gikz returned invalid TikZ');
26
+ return code;
27
+ }
28
+ //# sourceMappingURL=gikz.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gikz.js","sourceRoot":"","sources":["../../src/export/gikz.ts"],"names":[],"mappings":";;;;;AASA,gDAIC;AACD,sCAOC;AArBD,gDAAwB;AACxB,2BAAkC;AAElC,MAAM,IAAI,GAAG,OAAO,CAAC,qBAAqB,CAIzC,CAAC;AACF,kFAAkF;AAClF,SAAgB,kBAAkB;IAChC,MAAM,MAAM,GAAC,IAAA,iBAAY,EAAC,cAAI,CAAC,IAAI,CAAC,SAAS,EAAC,4BAA4B,CAAC,EAAC,MAAM,CAAC,CAAC,OAAO,CAAC,aAAa,EAAC,YAAY,CAAC,CAAC;IACxH,MAAM,OAAO,GAAC,IAAI,CAAC,SAAS,CAAC,IAAA,iBAAY,EAAC,cAAI,CAAC,IAAI,CAAC,SAAS,EAAC,oBAAoB,CAAC,EAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAC,SAAS,CAAC,CAAC;IACrH,OAAO,qDAAqD,OAAO,wCAAwC,MAAM,WAAW,CAAC;AAC/H,CAAC;AACM,KAAK,UAAU,aAAa,CAAC,MAAa,EAAC,UAAoB,EAAE;IACtE,IAAG,MAAM,CAAC,MAAM,GAAC,UAAU;QAAC,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACxE,IAAI,IAAI,GAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAE,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAC;QACrE,CAAC,CAAA,IAAI,CAAC,kBAAkB,CAAC,MAAM,EAAC,OAAO,CAAC,CAAA,CAAC,CAAA,IAAI,CAAC,aAAa,CAAC,MAAM,EAAC,OAAO,CAAC,CAAC;IAC9E,IAAG,OAAO,CAAC,UAAU;QAAC,IAAI,GAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;IACrD,IAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QAAC,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;IACxF,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,14 @@
1
+ export interface HtmlOptions {
2
+ /** Kept for API compatibility; the viewer itself intentionally has no title. */
3
+ title?: string;
4
+ commands?: string[];
5
+ ggbBase64?: string;
6
+ /** Initial engine dimensions; the browser viewer resizes to its container. */
7
+ width?: number;
8
+ height?: number;
9
+ visibleLabels?: string[];
10
+ captionOverrides?: Record<string, string>;
11
+ }
12
+ /** A responsive, title-free viewer for an embedded GGB or a semantic command construction. */
13
+ export declare function constructionHtml(options?: HtmlOptions): string;
14
+ //# sourceMappingURL=html.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/export/html.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,gFAAgF;IAChF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AAKD,8FAA8F;AAC9F,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,WAAgB,GAAG,MAAM,CAwFlE"}
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.constructionHtml = constructionHtml;
4
+ const gikz_1 = require("./gikz");
5
+ const viewer_themes_1 = require("./viewer-themes");
6
+ const scriptJson = (value) => JSON.stringify(value)
7
+ .replace(/</g, '\\u003c').replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029');
8
+ /** A responsive, title-free viewer for an embedded GGB or a semantic command construction. */
9
+ function constructionHtml(options = {}) {
10
+ const cleaner = (0, gikz_1.gikzBrowserScripts)();
11
+ const payload = scriptJson({
12
+ commands: options.commands ?? [],
13
+ ...(options.ggbBase64 ? { ggbBase64: options.ggbBase64 } : {}),
14
+ visibleLabels: options.visibleLabels ?? [],
15
+ captionOverrides: options.captionOverrides ?? {}
16
+ });
17
+ return `<!doctype html>
18
+ <html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
19
+ <meta name="color-scheme" content="light dark"><title>GeoGebra</title>
20
+ <style>
21
+ :root{color-scheme:light;--paper:#fffcf0;--line:#e6e4d9;--ink:#100f0f;--muted:#6f6e69;--hover:#f2f0e5}
22
+ *{box-sizing:border-box}html,body{margin:0;height:100%;overflow:hidden;background:var(--paper);color:var(--ink);font:14px/1.4 -apple-system,BlinkMacSystemFont,"Segoe UI","PingFang SC","Noto Sans CJK SC",sans-serif}
23
+ main{height:100dvh;width:100%;padding:12px 16px 16px;display:flex;flex-direction:column}
24
+ header{position:relative;z-index:10;display:flex;justify-content:flex-end;align-items:center;gap:8px;flex-shrink:0;min-height:42px;margin-bottom:8px}
25
+ .menu-control{position:relative}.control-button{display:inline-flex;align-items:center;justify-content:center;gap:8px;appearance:none;height:38px;min-width:72px;padding:0 14px;border:1px solid var(--line);border-radius:9px;background:var(--paper);color:var(--ink);font:inherit;cursor:pointer}
26
+ .control-button:hover,.control-button[aria-expanded="true"]{background:var(--hover)}.control-button:focus-visible,.viewer-menu button:focus-visible{outline:2px solid var(--blue);outline-offset:2px}.icon-button{min-width:38px;width:38px;padding:0}.control-button svg{width:18px;height:18px;flex-shrink:0}.chevron{width:12px!important;height:12px!important}
27
+ .viewer-menu{position:absolute;top:43px;right:0;z-index:20;display:none;min-width:170px;padding:5px;border:1px solid var(--line);border-radius:10px;background:var(--paper);box-shadow:0 12px 32px rgb(16 15 15 / 12%)}
28
+ .viewer-menu.open{display:grid}.viewer-menu button{display:flex;align-items:center;gap:10px;min-height:34px;padding:0 10px;border:0;border-radius:6px;background:transparent;color:var(--ink);text-align:left;font:inherit;cursor:pointer}
29
+ .viewer-menu button:hover,.viewer-menu button[aria-checked="true"]{background:var(--hover)}.viewer-menu{max-height:min(70vh,400px);overflow:auto}.theme-name{flex:1}.swatch{width:12px;height:12px;border-radius:50%;border:1px solid rgb(128 128 128 / 35%)}.sidebar-toggle{position:absolute;top:10px;left:10px;z-index:3;box-shadow:0 2px 8px rgb(0 0 0 / 7%)}.viewer-menu button:disabled{opacity:.5;cursor:wait}
30
+ .stage{position:relative;width:100%;flex:1;min-height:200px;overflow:hidden;border:1px solid var(--line);border-radius:10px;background:var(--paper)}
31
+ #ggb-element{position:absolute;inset:0;width:100%!important;height:100%!important;overflow:hidden}
32
+ #status{position:absolute;inset:0;z-index:2;display:grid;place-items:center;margin:0;padding:16px;color:var(--muted);background:var(--paper);text-align:center;pointer-events:none}
33
+ #status[hidden]{display:none}#status.error{color:#af3029}
34
+ @media(max-width:640px){main{padding:8px}.stage{border-radius:7px}header{margin-bottom:6px}}
35
+ @media print{main{width:100%;padding:0}header,.sidebar-toggle{display:none}.stage{border:0;border-radius:0}}
36
+ </style></head><body><main>
37
+ <header><div class="menu-control"><button id="theme-toggle" class="control-button" type="button" aria-label="选择主题" aria-expanded="false" aria-haspopup="menu" aria-controls="theme-menu"><span id="theme-name">默认</span><svg class="chevron" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg></button><div id="theme-menu" class="viewer-menu" role="menu" aria-label="配色主题"></div></div>
38
+ <button id="mode-toggle" class="control-button icon-button" type="button" aria-label="切换深浅色"></button>
39
+ <div class="menu-control downloads"><button class="control-button download-toggle" id="download-toggle" type="button" aria-expanded="false" aria-haspopup="menu" aria-controls="download-menu">下载</button>
40
+ <div class="viewer-menu" id="download-menu" role="menu" aria-label="下载格式">
41
+ <button type="button" role="menuitem" data-format="ggb">GeoGebra 文件</button>
42
+ <button type="button" role="menuitem" data-format="png">PNG 图片</button>
43
+ <button type="button" role="menuitem" data-format="svg">SVG 矢量图</button>
44
+ <button type="button" role="menuitem" data-format="tikz">TikZ 源文件 (.tex)</button>
45
+ <button type="button" role="menuitem" data-format="pdf">PDF 文档</button>
46
+ <button type="button" role="menuitem" data-format="xml">XML 源文件</button>
47
+ <button type="button" role="menuitem" data-format="html">交互 HTML</button></div></div></header>
48
+ <section class="stage" aria-label="GeoGebra 图形"><button id="sidebar-toggle" class="control-button icon-button sidebar-toggle" type="button" aria-label="展开对象栏" title="展开对象栏" aria-expanded="false" disabled><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" aria-hidden="true"><rect x="3" y="4" width="18" height="16" rx="3"/><path d="M9 4v16m4-11 3 3-3 3"/></svg></button><p id="status" role="status" aria-live="polite">正在加载…</p><div id="ggb-element"></div></section></main>
49
+ <script id="construction-data" type="application/json">${payload}</script>
50
+ ${cleaner}
51
+ <script>
52
+ (()=>{
53
+ const specification=JSON.parse(document.getElementById('construction-data').textContent);
54
+ const host=document.getElementById('ggb-element'),status=document.getElementById('status');
55
+ const toggle=document.getElementById('download-toggle'),menu=document.getElementById('download-menu');
56
+ const themes=${scriptJson(viewer_themes_1.viewerThemes)};
57
+ const themeMenu=document.getElementById('theme-menu'),themeToggle=document.getElementById('theme-toggle'),modeToggle=document.getElementById('mode-toggle'),sidebarToggle=document.getElementById('sidebar-toggle');
58
+ const themeNames={default:'默认',ayu:'Ayu',catppuccin:'Catppuccin',everforest:'Everforest',gruvbox:'Gruvbox','rose-pine':'Rosé Pine',nord:'Nord',solarized:'Solarized',flexoki:'Flexoki'};
59
+ themeMenu.replaceChildren();
60
+ for(const name of Object.keys(themes)){const button=document.createElement('button');button.type='button';button.dataset.theme=name;button.setAttribute('role','menuitemradio');const label=document.createElement('span');label.className='theme-name';label.textContent=themeNames[name];button.append(label);for(const palette of themes[name]){const swatch=document.createElement('span');swatch.className='swatch';swatch.style.background=palette.paper;swatch.setAttribute('aria-hidden','true');button.append(swatch)}themeMenu.append(button)}
61
+ let api,ready=false,resizeObserver,resizeFrame,resizeVersion=0,sidebarOpen=false,objectThemeApplied=false;
62
+ const themeObjectColors=new Set(Object.values(themes).flat().flatMap(p=>[p.ink,p.blue]).concat(['#000000','#666666','#4d4dff']).map(c=>c.toLowerCase()));
63
+ const validTheme=value=>typeof value==='string'&&/^[a-z-]+:[01]$/.test(value)&&Object.hasOwn(themes,value.split(':')[0]);
64
+ let chosenTheme=validTheme(specification.theme)?specification.theme:'default:0';
65
+ try{const saved=localStorage.getItem('geogebra-viewer-theme');if(validTheme(saved))chosenTheme=saved}catch(_){}
66
+ function applyTheme(){const [name,mode]=chosenTheme.split(':');const palette=themes[name][Number(mode)];for(const [key,value]of Object.entries(palette))document.documentElement.style.setProperty('--'+key,value);document.documentElement.style.colorScheme=Number(mode)?'dark':'light';document.getElementById('theme-name').textContent=themeNames[name];for(const button of themeMenu.querySelectorAll('[data-theme]'))button.setAttribute('aria-checked',String(button.dataset.theme===name));const action=Number(mode)?'切换为浅色':'切换为深色';modeToggle.setAttribute('aria-label',action);modeToggle.title=action;modeToggle.setAttribute('aria-pressed',String(Boolean(Number(mode))));modeToggle.innerHTML='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">'+(Number(mode)?'<circle cx="12" cy="12" r="4"/><path d="M12 2v2m0 16v2M2 12h2m16 0h2M5 5l1.4 1.4m11.2 11.2L19 19M5 19l1.4-1.4M17.6 6.4 19 5"/>':'<path d="M20.8 13A9 9 0 0 1 11 3.2 9 9 0 1 0 20.8 13Z"/>')+'</svg>';if(api){const rgb=hex=>[1,3,5].map(i=>parseInt(hex.slice(i,i+2),16));api.setGraphicsOptions(1,{bgColor:palette.paper});for(const object of api.getAllObjectNames()){const type=api.getObjectType(object);if(['point','text','line','segment','ray','circle','conic'].includes(type)&&((!objectThemeApplied&&!specification.ggbBase64)||themeObjectColors.has(api.getColor(object).toLowerCase())))api.setColor(object,...rgb(type==='point'&&api.isMoveable(object)?palette.blue:palette.ink))}objectThemeApplied=true}}
67
+ function saveTheme(){try{localStorage.setItem('geogebra-viewer-theme',chosenTheme)}catch(_){}applyTheme()}
68
+ themeMenu.addEventListener('click',event=>{const button=event.target.closest('[data-theme]');if(!button)return;chosenTheme=button.dataset.theme+':'+chosenTheme.split(':')[1];saveTheme();closeMenus();themeToggle.focus()});
69
+ modeToggle.addEventListener('click',()=>{chosenTheme=chosenTheme.split(':')[0]+':'+(chosenTheme.endsWith(':1')?'0':'1');saveTheme()});applyTheme();
70
+ window.ggbReady=false;window.ggbError=null;
71
+ function setStatus(text,error=false){status.textContent=text;status.classList.toggle('error',error);status.hidden=!text;}
72
+ function equalAxes(){const v=JSON.parse(api.getViewProperties(1)),unit=Math.max(v.invXscale,v.invYscale),cx=v.xMin+v.width*v.invXscale/2,cy=v.yMin+v.height*v.invYscale/2;api.setCoordSystem(cx-v.width*unit/2,cx+v.width*unit/2,cy-v.height*unit/2,cy+v.height*unit/2)}
73
+ function readCamera(){const v=JSON.parse(api.getViewProperties(1));return{cx:v.xMin+v.width*v.invXscale/2,cy:v.yMin+v.height*v.invYscale/2,span:Math.min(v.width*v.invXscale,v.height*v.invYscale)}}
74
+ function setSize(camera){if(!api)return;camera=camera||readCamera();const version=++resizeVersion;cancelAnimationFrame(resizeFrame);resizeFrame=requestAnimationFrame(async()=>{const width=Math.round(host.clientWidth),height=Math.round(host.clientHeight);if(width<1||height<1)return;const {cx,cy,span}=camera;api.setSize(width,height);await new Promise(resolve=>requestAnimationFrame(()=>requestAnimationFrame(resolve)));if(version!==resizeVersion)return;const view=JSON.parse(api.getViewProperties(1)),unit=span/Math.min(view.width,view.height);api.setCoordSystem(cx-view.width*unit/2,cx+view.width*unit/2,cy-view.height*unit/2,cy+view.height*unit/2);equalAxes();sidebarToggle.style.top=Math.max(10,view.top-host.getBoundingClientRect().top+10)+'px';sidebarToggle.style.left=sidebarOpen?Math.max(10,view.left-host.getBoundingClientRect().left+10)+'px':'10px'})}
75
+ function toBytes(data){return Uint8Array.from(atob(data.replace(/^data:[^,]+,/,'')),c=>c.charCodeAt(0));}
76
+ function download(data,mime,extension,base64=false){const blob=new Blob([base64?toBytes(data):data],{type:mime});const url=URL.createObjectURL(blob);const link=document.createElement('a');link.href=url;link.download='construction.'+extension;link.click();setTimeout(()=>URL.revokeObjectURL(url),10000);}
77
+ function callbackExport(format){return new Promise((resolve,reject)=>{const timer=setTimeout(()=>reject(new Error('导出超时')),20000);const done=value=>{clearTimeout(timer);value?resolve(value):reject(new Error('GeoGebra 未返回文件'))};try{if(format==='ggb')api.getBase64(done);else if(format==='pdf')api.exportPDF(1,done);else if(format==='tikz')api.exportPGF(done);else api.exportSVG(done)}catch(error){clearTimeout(timer);reject(error)}})}
78
+ async function fitView(){api.showAllObjects();await new Promise(resolve=>setTimeout(resolve,650));const view=JSON.parse(api.getViewProperties(1));let xmin=Infinity,xmax=-Infinity,ymin=Infinity,ymax=-Infinity,hasCircle=false,unsupported=false;for(const name of api.getAllObjectNames()){if(!api.getVisible(name))continue;const type=api.getObjectType(name);if(type==='point'){const x=api.getXcoord(name),y=api.getYcoord(name);if(Number.isFinite(x)&&Number.isFinite(y)){xmin=Math.min(xmin,x);xmax=Math.max(xmax,x);ymin=Math.min(ymin,y);ymax=Math.max(ymax,y)}}else if(type==='circle'||type==='conic'){const xml=new DOMParser().parseFromString('<root>'+api.getXML(name)+'</root>','application/xml'),matrix=xml.querySelector('matrix');if(!matrix){unsupported=true;continue}const a=[0,1,2,3,4,5].map(i=>Number(matrix.getAttribute('A'+i)));if(Math.abs(a[0]-a[1])>1e-8||Math.abs(a[3])>1e-8||!a[0]){unsupported=true;continue}const x=-a[4]/a[0],y=-a[5]/a[0],r=Math.sqrt(x*x+y*y-a[2]/a[0]);if(Number.isFinite(r)){hasCircle=true;xmin=Math.min(xmin,x-r);xmax=Math.max(xmax,x+r);ymin=Math.min(ymin,y-r);ymax=Math.max(ymax,y+r)}}else if(!['line','ray','segment','text','numeric','boolean'].includes(type))unsupported=true}if(!hasCircle||unsupported){xmin=view.xMin;xmax=xmin+view.width*view.invXscale;ymin=view.yMin;ymax=ymin+view.height*view.invYscale}const unit=Math.max((xmax-xmin)*1.16/view.width,(ymax-ymin)*1.16/view.height,2/Math.min(view.width,view.height)),cx=(xmin+xmax)/2,cy=(ymin+ymax)/2;api.setCoordSystem(cx-view.width*unit/2,cx+view.width*unit/2,cy-view.height*unit/2,cy+view.height*unit/2)}
79
+
80
+ function applyMcpDefaults(){const names=api.getAllObjectNames();const visible=new Set(specification.visibleLabels||[]),captions=specification.captionOverrides||{};const view=JSON.parse(api.getViewProperties(1)),dx=10*view.invXscale,dy=10*view.invYscale;for(const name of names){try{const type=api.getObjectType(name),show=visible.size?visible.has(name):type==='point';api.setLabelVisible(name,false);if(type==='point')api.setPointSize(name,3);else if(['line','segment','ray','vector','circle','conic','polygon','function','curve'].includes(type))api.setLineThickness(name,3);if(show){let caption=captions[name]||name;caption=caption.replace(/^\\$|\\$$/g,'');const math=caption==='Γ'?'\\\\Gamma':caption==='ω'?'\\\\omega':/^[A-Za-z]+$/.test(caption)?'\\\\mathit{'+caption+'}':caption;const anchor=type==='point'?name:'Point('+name+',0.38)';const label='mcpLabel'+name;api.evalCommand(label+' = Text('+JSON.stringify(math).replaceAll(String.fromCharCode(92,92),String.fromCharCode(92))+', '+anchor+' + ('+dx+','+dy+'), true, true)');api.setLabelVisible(label,false);api.setFixed(label,true,false);api.setAuxiliary(label,true)}}catch(_){}}}
81
+
82
+ async function exportAs(format){if(!ready)return;try{if(format==='tikz'){if(typeof api.exportPGF!=='function')throw new Error('当前 GeoGebra 引擎不支持 TikZ 导出');setStatus('正在通过 Gikz 清洗…');const source=await callbackExport('tikz');if(!globalThis.Gikz)throw new Error('Gikz 未加载,已停止 TikZ 导出');const cleaned=Gikz.wrapStandalone(Gikz.cleanTikZCode(source));download(cleaned,'application/x-tex','tex')}else if(format==='xml'){download(api.getXML(),'application/xml','xml')}else if(format==='png'){download(api.getPNGBase64(2,false,144),'image/png','png',true)}else if(format==='html'){const base64=await callbackExport('ggb');const html=window.constructionTemplate.replace(/(<script id="construction-data" type="application\\/json">)[\\s\\S]*?(<\\/script>)/,'$1'+JSON.stringify({commands:[],ggbBase64:base64,theme:chosenTheme,visibleLabels:specification.visibleLabels||[],captionOverrides:specification.captionOverrides||{}})+'$2');download(html,'text/html','html')}else{const value=await callbackExport(format);download(value,format==='pdf'?'application/pdf':format==='ggb'?'application/vnd.geogebra.file':'image/svg+xml',format,format==='pdf'||format==='ggb')}setStatus('')}catch(error){setStatus(error.message||'导出失败',true)}}
83
+ const popupMenus=[[toggle,menu],[themeToggle,themeMenu]];
84
+ function closeMenus(){for(const [button,popup]of popupMenus){popup.classList.remove('open');button.setAttribute('aria-expanded','false')}}
85
+ for(const [button,popup]of popupMenus){button.addEventListener('click',()=>{const open=!popup.classList.contains('open');closeMenus();if(open){popup.classList.add('open');button.setAttribute('aria-expanded','true')}});button.addEventListener('keydown',event=>{if(event.key==='ArrowDown'){event.preventDefault();closeMenus();popup.classList.add('open');button.setAttribute('aria-expanded','true');popup.querySelector('button').focus()}});popup.addEventListener('keydown',event=>{const items=[...popup.querySelectorAll('button')],index=items.indexOf(document.activeElement);if(['ArrowDown','ArrowUp','Home','End'].includes(event.key)){event.preventDefault();items[event.key==='Home'?0:event.key==='End'?items.length-1:(index+(event.key==='ArrowDown'?1:items.length-1))%items.length].focus()}if(event.key==='Escape'){closeMenus();button.focus()}})}
86
+ menu.addEventListener('click',async event=>{const button=event.target.closest('[data-format]');if(!button)return;closeMenus();await exportAs(button.dataset.format)});
87
+ document.addEventListener('click',event=>{if(!event.target.closest('.menu-control'))closeMenus()});
88
+ document.addEventListener('keydown',event=>{if(event.key==='Escape')closeMenus()});
89
+ sidebarToggle.addEventListener('click',()=>{if(!ready)return;const camera=readCamera();sidebarOpen=!sidebarOpen;api.setPerspective(sidebarOpen?'AG':'G');api.showAlgebraInput(sidebarOpen);api.showToolBar(sidebarOpen);api.showMenuBar(sidebarOpen);sidebarToggle.setAttribute('aria-expanded',String(sidebarOpen));sidebarToggle.setAttribute('aria-label',sidebarOpen?'收起对象栏':'展开对象栏');sidebarToggle.title=sidebarOpen?'收起对象栏':'展开对象栏';sidebarToggle.querySelector('svg path').setAttribute('d',sidebarOpen?'M9 4v16m7-11-3 3 3 3':'M9 4v16m4-11 3 3-3 3');setSize(camera)});
90
+ // Initialize the native editing UI, then collapse it on load; starting with it disabled leaves lazy editor actions uninitialized.
91
+ window.startGeoGebra=()=>{window.constructionTemplate='<!doctype html>\\n'+document.documentElement.outerHTML;const width=Math.max(200,Math.round(host.clientWidth)),height=Math.max(200,Math.round(host.clientHeight));const applet=new GGBApplet({appName:'classic',width,height,disableAutoScale:true,showZoomButtons:false,borderColor:'transparent',language:'zh-CN',showToolBar:true,showMenuBar:true,showAlgebraInput:true,allowStyleBar:true,enableRightClick:true,showResetIcon:false,useBrowserForJS:false,preventFocus:true,enableLabelDrags:true,enableShiftDragZoom:true,...(specification.ggbBase64?{ggbBase64:specification.ggbBase64}:{}),appletOnLoad:async loaded=>{api=loaded;window.ggbApplet=api;try{api.setErrorDialogsActive(false);if(!specification.ggbBase64||(specification.commands||[]).length){api.setPerspective('G');api.setAxesVisible(false,false);api.setGridVisible(false);for(const command of specification.commands||[]){if(!api.evalCommand(command))throw new Error('GeoGebra 无法识别命令:'+command)}if((specification.commands||[]).length)await fitView();applyMcpDefaults()}api.setPerspective('G');api.showAlgebraInput(false);api.showToolBar(false);api.showMenuBar(false);api.setErrorDialogsActive(true);api.setAxesVisible(false,false);equalAxes();applyTheme();ready=true;sidebarToggle.disabled=false;window.ggbReady=true;status.hidden=true;resizeObserver=new ResizeObserver(()=>setSize());resizeObserver.observe(document.querySelector('.stage'));setSize()}catch(error){window.ggbError=error.message;setStatus(error.message,true)}}},true);applet.inject('ggb-element')};
92
+ setTimeout(()=>{if(!ready&&!window.ggbError){window.ggbError='GeoGebra 加载超时,请检查网络后刷新';setStatus(window.ggbError,true)}},30000);
93
+ })();
94
+ </script><script src="https://www.geogebra.org/apps/deployggb.js" onload="startGeoGebra()" onerror="window.ggbError='GeoGebra 加载失败';document.getElementById('status').className='error';document.getElementById('status').textContent=window.ggbError"></script>
95
+ </body></html>`;
96
+ }
97
+ //# sourceMappingURL=html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/export/html.ts"],"names":[],"mappings":";;AAmBA,4CAwFC;AA3GD,iCAA4C;AAC5C,mDAA+C;AAc/C,MAAM,UAAU,GAAG,CAAC,KAAc,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC;KACzD,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;AAExF,8FAA8F;AAC9F,SAAgB,gBAAgB,CAAC,UAAuB,EAAE;IACxD,MAAM,OAAO,GAAG,IAAA,yBAAkB,GAAE,CAAC;IACrC,MAAM,OAAO,GAAG,UAAU,CAAC;QACzB,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,EAAE;QAChC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,EAAE;QAC1C,gBAAgB,EAAE,OAAO,CAAC,gBAAgB,IAAI,EAAE;KACjD,CAAC,CAAC;IAEH,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yDAgCgD,OAAO;EAC9D,OAAO;;;;;;eAMM,UAAU,CAAC,4BAAY,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAuCxB,CAAC;AAChB,CAAC"}
@@ -0,0 +1,43 @@
1
+ export interface SceneObject {
2
+ name: string;
3
+ type: string;
4
+ visible: boolean;
5
+ labelVisible: boolean;
6
+ caption: string;
7
+ coordinates?: [number, number];
8
+ command?: {
9
+ name: string;
10
+ inputs: string[];
11
+ outputs: string[];
12
+ };
13
+ expression?: string;
14
+ style: {
15
+ color: [number, number, number];
16
+ thickness: number;
17
+ dash: number;
18
+ pointSize: number;
19
+ pointStyle: number;
20
+ fill: number;
21
+ };
22
+ }
23
+ export interface SemanticScene {
24
+ schemaVersion: '1.0';
25
+ source: 'geogebra-xml';
26
+ xml: string;
27
+ objects: SceneObject[];
28
+ }
29
+ /** Preserve command edges as well as evaluated coordinates and appearance. */
30
+ export declare function sceneFromXML(xml: string): SemanticScene;
31
+ export type SourceFormat = 'tikz' | 'asymptote' | 'tsqx';
32
+ export interface SourceResult {
33
+ format: SourceFormat;
34
+ code: string;
35
+ complete: boolean;
36
+ warnings: string[];
37
+ coordinateFallbacks: string[];
38
+ unsupportedObjects: string[];
39
+ semantics: 'preserved-subset' | 'partial';
40
+ }
41
+ /** Deliberately small semantic backend. Unsupported relations remain visible in the report. */
42
+ export declare function exportSource(scene: SemanticScene, format: SourceFormat, strict?: boolean, standalone?: boolean): SourceResult;
43
+ //# sourceMappingURL=semantic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"semantic.d.ts","sourceRoot":"","sources":["../../src/export/semantic.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,OAAO,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAChE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE;QAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAClI;AACD,MAAM,WAAW,aAAa;IAAG,aAAa,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,cAAc,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,EAAE,CAAC;CAAE;AAKrH,8EAA8E;AAC9E,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAkCvD;AAED,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;AACzD,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,YAAY,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,SAAS,EAAE,kBAAkB,GAAG,SAAS,CAAC;CAC3C;AAED,+FAA+F;AAC/F,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,UAAO,EAAE,UAAU,UAAO,GAAG,YAAY,CAgHvH"}