flowstride 1.0.6 → 1.0.8

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.
@@ -73,11 +73,11 @@ async function runAction(targetPath, options) {
73
73
  process.env.GITHUB_ACTIONS ||
74
74
  process.env.GITLAB_CI ||
75
75
  process.env.CIRCLECI ||
76
- process.env.JENKINS_URL);
76
+ process.env.JENKINS_URL ||
77
+ process.env.FLOWSTRIDE_API_KEY);
77
78
  if (isCI) {
78
79
  console.log("\n[CI/CD]: Environment detected. Engaging Smart Automation Behaviors...");
79
80
  }
80
- // The CLI (index.ts) now strictly guarantees targetPath is the absolute path to ./flows
81
81
  const resolvedPath = targetPath;
82
82
  if (!fs.existsSync(resolvedPath)) {
83
83
  console.error(`\n[Error]: Cannot find strict target path "${resolvedPath}".`);
@@ -135,12 +135,13 @@ async function runAction(targetPath, options) {
135
135
  let ActiveFlowWorker = flow_worker_1.FlowWorker;
136
136
  let ActiveFlowOrchestrator = flow_orchestrator_1.FlowOrchestrator;
137
137
  let engineMode = "Open Source";
138
- // Check the local node_modules for the Pro engine
139
138
  const proWorkerPath = path.join(process.cwd(), "node_modules", "@flowstride", "pro", "dist", "runner", "flow_worker.js");
140
139
  const proOrchPath = path.join(process.cwd(), "node_modules", "@flowstride", "pro", "dist", "runner", "flow_orchestrator.js");
141
- if (fs.existsSync(proWorkerPath) && fs.existsSync(proOrchPath)) {
140
+ // We only attempt to load the Pro Engine if the DRM Bouncer (index.ts) did NOT force OS Mode
141
+ if (!options.forceOS &&
142
+ fs.existsSync(proWorkerPath) &&
143
+ fs.existsSync(proOrchPath)) {
142
144
  try {
143
- // Dynamically load the Pro classes using native absolute URL resolution
144
145
  const proWorkerModule = await import((0, url_1.pathToFileURL)(proWorkerPath).href);
145
146
  const proOrchModule = await import((0, url_1.pathToFileURL)(proOrchPath).href);
146
147
  ActiveFlowWorker = proWorkerModule.FlowWorker;
@@ -153,7 +154,6 @@ async function runAction(targetPath, options) {
153
154
  }
154
155
  console.log(`\n[Engine]: Booting Flowstride in ${engineMode} mode...`);
155
156
  // ==========================================
156
- // Instantiate the chosen engine (OS or Pro)
157
157
  const worker = new ActiveFlowWorker(config, web, api, store, sessions, pluginManager);
158
158
  const orchestrator = new ActiveFlowOrchestrator(worker, workerCount, config);
159
159
  try {
package/dist/cli/index.js CHANGED
@@ -44,15 +44,16 @@ const init_1 = require("./commands/init");
44
44
  const fs = __importStar(require("fs"));
45
45
  const path = __importStar(require("path"));
46
46
  const os = __importStar(require("os"));
47
- const child_process_1 = require("child_process");
47
+ const tar = __importStar(require("tar"));
48
48
  const prompts_1 = require("@inquirer/prompts");
49
49
  const chalk_1 = __importDefault(require("chalk"));
50
50
  const ora_1 = __importDefault(require("ora"));
51
51
  const program = new commander_1.Command();
52
+ const API_BASE = process.env.FLOWSTRIDE_API_URL || "https://cloud.flowstride.io";
52
53
  program
53
54
  .name("flowstride")
54
55
  .description("Flowstride: The Enterprise Flow-First Automation CLI")
55
- .version("1.0.6");
56
+ .version("1.0.8");
56
57
  program
57
58
  .command("init")
58
59
  .description("Initialise a new Flowstride workspace in the current directory")
@@ -63,18 +64,41 @@ program
63
64
  .command("login")
64
65
  .description("Authenticate this machine with Flowstride Enterprise Cloud")
65
66
  .action(async () => {
67
+ const localPackageJsonPath = path.join(process.cwd(), "package.json");
68
+ if (!fs.existsSync(localPackageJsonPath)) {
69
+ console.error(chalk_1.default.red("✖ Error: Please navigate to a valid Flowstride project directory before logging in."));
70
+ process.exit(1);
71
+ }
72
+ const pkg = JSON.parse(fs.readFileSync(localPackageJsonPath, "utf8"));
73
+ const deps = {
74
+ ...(pkg.dependencies || {}),
75
+ ...(pkg.devDependencies || {}),
76
+ };
77
+ if (!deps["flowstride"] && !deps["flowstride-os"]) {
78
+ console.error(chalk_1.default.red("✖ Error: Please navigate to a valid Flowstride project directory before logging in."));
79
+ process.exit(1);
80
+ }
66
81
  console.log(chalk_1.default.bold.blue("\n🌐 Flowstride Enterprise Cloud Sync\n"));
67
- const userEmail = await (0, prompts_1.input)({ message: "Enter your Flowstride email:" });
68
- const userPass = await (0, prompts_1.password)({ message: "Enter your password:" });
82
+ let authHeader = "";
83
+ if (process.env.FLOWSTRIDE_API_KEY) {
84
+ console.log(chalk_1.default.yellow("🤖 CI/CD Environment Detected. Authenticating via API Key..."));
85
+ authHeader = `Bearer ${process.env.FLOWSTRIDE_API_KEY}`;
86
+ }
87
+ else {
88
+ const userEmail = await (0, prompts_1.input)({
89
+ message: "Enter your Flowstride email:",
90
+ });
91
+ const userPass = await (0, prompts_1.password)({ message: "Enter your password:" });
92
+ authHeader = `Basic ${Buffer.from(`${userEmail}:${userPass}`).toString("base64")}`;
93
+ }
69
94
  const deviceName = os.hostname();
70
95
  const spinner = (0, ora_1.default)("Authenticating with Cloud...").start();
71
96
  try {
72
- const authString = Buffer.from(`${userEmail}:${userPass}`).toString("base64");
73
- const response = await fetch("https://cloud.flowstride.io/api/auth/cli-sync", {
97
+ const response = await fetch(`${API_BASE}/api/auth/cli-sync`, {
74
98
  method: "POST",
75
99
  headers: {
76
100
  "Content-Type": "application/json",
77
- Authorization: `Basic ${authString}`,
101
+ Authorization: authHeader,
78
102
  },
79
103
  body: JSON.stringify({ deviceName }),
80
104
  });
@@ -84,56 +108,65 @@ program
84
108
  process.exit(1);
85
109
  }
86
110
  spinner.succeed(chalk_1.default.green("Authentication Successful!"));
87
- const configDir = path.join(os.homedir(), ".flowstride");
111
+ const configDir = path.join(process.cwd(), ".flowstride", "login");
88
112
  if (!fs.existsSync(configDir)) {
89
113
  fs.mkdirSync(configDir, { recursive: true });
90
114
  }
91
- const credentialsPath = path.join(configDir, "credentials.json");
115
+ const credentialsPath = path.join(configDir, "login.json");
92
116
  fs.writeFileSync(credentialsPath, JSON.stringify({
93
117
  machineToken: data.machineToken,
94
118
  workspaceId: data.workspaceId,
95
119
  deviceName: deviceName,
96
120
  syncedAt: new Date().toISOString(),
97
121
  }, null, 2));
98
- console.log(chalk_1.default.gray(`\nCredentials saved to ${credentialsPath}`));
99
- console.log(chalk_1.default.bold.green(`\n✅ Machine synchronized with Flowstride Enterprise.`));
100
- if (data.githubToken || data.isProEligible) {
122
+ console.log(chalk_1.default.gray(`\nCredentials securely scoped to ${credentialsPath}`));
123
+ if (data.isProEligible) {
101
124
  console.log(chalk_1.default.yellow(`\n⚙️ System Check: You have access to Enterprise features (AI Healing, Parallel Workers).`));
102
- const localPackageJsonPath = path.join(process.cwd(), "package.json");
103
- const nodeModulesPath = path.join(process.cwd(), "node_modules", "@heroamogs", "pro");
104
- if (fs.existsSync(localPackageJsonPath) &&
105
- !fs.existsSync(nodeModulesPath)) {
106
- const installPro = await (0, prompts_1.confirm)({
107
- message: "The Pro Engine is not installed in this project. Would you like Flowstride to automatically install it now?",
108
- default: true,
109
- });
125
+ const nodeModulesPath = path.join(process.cwd(), "node_modules", "@flowstride", "pro");
126
+ if (!fs.existsSync(nodeModulesPath)) {
127
+ let installPro = true;
128
+ if (!process.env.FLOWSTRIDE_API_KEY && !process.env.CI) {
129
+ installPro = await (0, prompts_1.confirm)({
130
+ message: "The Pro Engine is not installed in this project. Would you like Flowstride to automatically install it now?",
131
+ default: true,
132
+ });
133
+ }
110
134
  if (installPro) {
111
135
  const installSpinner = (0, ora_1.default)("Downloading Enterprise Engine via secure proxy...").start();
112
136
  const tarballPath = path.join(process.cwd(), "flowstride-pro.tgz");
113
137
  try {
114
- const tarballResponse = await fetch("https://cloud.flowstride.io/api/workspace/download-pro", {
138
+ const tarballResponse = await fetch(`${API_BASE}/api/workspace/download-pro`, {
115
139
  method: "GET",
116
- headers: {
117
- Authorization: `Bearer ${data.machineToken}`,
118
- },
140
+ headers: { Authorization: `Bearer ${data.machineToken}` },
119
141
  });
120
142
  if (!tarballResponse.ok) {
121
143
  throw new Error(`Secure proxy rejected request: ${tarballResponse.statusText}`);
122
144
  }
123
145
  const buffer = await tarballResponse.arrayBuffer();
124
146
  fs.writeFileSync(tarballPath, Buffer.from(buffer));
125
- installSpinner.stop();
126
- console.log(chalk_1.default.cyan("Starting secure local install..."));
127
- (0, child_process_1.execSync)("npm install ./flowstride-pro.tgz --save-dev", {
128
- stdio: "inherit",
129
- cwd: process.cwd(),
147
+ installSpinner.text = "Silently extracting Enterprise Engine...";
148
+ installSpinner.color = "cyan";
149
+ if (!fs.existsSync(nodeModulesPath)) {
150
+ fs.mkdirSync(nodeModulesPath, { recursive: true });
151
+ }
152
+ await tar.x({
153
+ file: tarballPath,
154
+ cwd: nodeModulesPath,
155
+ strip: 1,
130
156
  });
131
- console.log(chalk_1.default.green("\n✅ Enterprise Engine installed successfully!"));
157
+ installSpinner.succeed(chalk_1.default.green("Enterprise Engine installed successfully!"));
132
158
  }
133
159
  catch (installError) {
134
160
  installSpinner.stop();
135
- console.log(chalk_1.default.red("\n✖ Failed to install the Enterprise Engine automatically."));
136
- console.error(chalk_1.default.gray(String(installError)));
161
+ console.log(chalk_1.default.red("\n✖ Failed to install the Enterprise Engine. Please check your internet connection or verify your project configuration."));
162
+ if (fs.existsSync(nodeModulesPath)) {
163
+ fs.rmSync(nodeModulesPath, { recursive: true, force: true });
164
+ }
165
+ // THE FIX: Strict Rollback on Failure
166
+ console.log(chalk_1.default.yellow("⚠️ Reverting login: Enterprise Engine is required to sync."));
167
+ if (fs.existsSync(credentialsPath))
168
+ fs.unlinkSync(credentialsPath);
169
+ process.exit(1);
137
170
  }
138
171
  finally {
139
172
  if (fs.existsSync(tarballPath)) {
@@ -142,16 +175,77 @@ program
142
175
  }
143
176
  }
144
177
  else {
145
- console.log(chalk_1.default.gray(`\nSkipped installation.`));
178
+ // THE FIX: Strict Rollback on Decline
179
+ console.log(chalk_1.default.yellow(`\n⚠️ Installation skipped.`));
180
+ console.log(chalk_1.default.red(`✖ Reverting login: You must install the Enterprise Engine to sync this workspace.`));
181
+ if (fs.existsSync(credentialsPath))
182
+ fs.unlinkSync(credentialsPath);
183
+ process.exit(1);
146
184
  }
147
185
  }
148
186
  }
187
+ // Only print this if the engine was successfully verified or installed
188
+ console.log(chalk_1.default.bold.green(`\n✅ Machine synchronized with Flowstride Enterprise.`));
149
189
  }
150
190
  catch (error) {
151
191
  spinner.fail(chalk_1.default.red(`Network Error: Could not connect to cloud.flowstride.io`));
152
192
  process.exit(1);
153
193
  }
154
194
  });
195
+ program
196
+ .command("status")
197
+ .description("Display the current Flowstride CLI authentication and engine tier")
198
+ .action(async () => {
199
+ let token = process.env.FLOWSTRIDE_API_KEY || null;
200
+ const credentialsPath = path.join(process.cwd(), ".flowstride", "login", "login.json");
201
+ const nodeModulesPath = path.join(process.cwd(), "node_modules", "@flowstride", "pro");
202
+ if (!token && fs.existsSync(credentialsPath)) {
203
+ try {
204
+ const credentials = JSON.parse(fs.readFileSync(credentialsPath, "utf8"));
205
+ token = credentials.machineToken;
206
+ }
207
+ catch (err) { }
208
+ }
209
+ // THE FIX: Defensive Self-Healing. If login exists but engine is missing, drop to OS.
210
+ if (!process.env.FLOWSTRIDE_API_KEY &&
211
+ token &&
212
+ !fs.existsSync(nodeModulesPath)) {
213
+ if (fs.existsSync(credentialsPath))
214
+ fs.unlinkSync(credentialsPath);
215
+ token = null;
216
+ }
217
+ if (!token) {
218
+ console.log(chalk_1.default.white("⚪ [OS]: (Local Mode / Not Logged In)"));
219
+ return;
220
+ }
221
+ try {
222
+ const response = await fetch(`${API_BASE}/api/auth/verify-cli`, {
223
+ method: "GET",
224
+ headers: { Authorization: `Bearer ${token}` },
225
+ });
226
+ if (response.status === 401) {
227
+ console.log(chalk_1.default.red("🔴 AUTH EXPIRED: Your device session was revoked or expired."));
228
+ if (fs.existsSync(credentialsPath))
229
+ fs.unlinkSync(credentialsPath);
230
+ }
231
+ else if (response.ok) {
232
+ const data = await response.json();
233
+ const tier = data.tier.toUpperCase();
234
+ if (tier === "PERSONAL") {
235
+ console.log(chalk_1.default.yellow(`🟡 [OS]: [${data.workspaceName}] (Tier: PERSONAL)`));
236
+ }
237
+ else {
238
+ console.log(chalk_1.default.green(`🟢 [PRO]: [${data.workspaceName}] (Tier: ${tier})`));
239
+ }
240
+ }
241
+ else {
242
+ console.log(chalk_1.default.yellow("🛜 OFFLINE: Unable to reach Flowstride Cloud. Enterprise Sync paused."));
243
+ }
244
+ }
245
+ catch (err) {
246
+ console.log(chalk_1.default.yellow("🛜 OFFLINE: Unable to reach Flowstride Cloud. Enterprise Sync paused."));
247
+ }
248
+ });
155
249
  program
156
250
  .command("run")
157
251
  .description("Execute all .flow automation journeys in the ./flows directory")
@@ -160,20 +254,58 @@ program
160
254
  .option("--headless <boolean>", "Run browser in headless mode", (val) => val === "true", true)
161
255
  .option("--workers <number>", "Number of parallel workers to spawn (Pro feature)")
162
256
  .action(async (options) => {
163
- const credentialsPath = path.join(os.homedir(), ".flowstride", "credentials.json");
164
- let isPro = false;
165
- if (fs.existsSync(credentialsPath)) {
257
+ let token = process.env.FLOWSTRIDE_API_KEY || null;
258
+ let forceOS = false;
259
+ const credentialsPath = path.join(process.cwd(), ".flowstride", "login", "login.json");
260
+ const nodeModulesPath = path.join(process.cwd(), "node_modules", "@flowstride", "pro");
261
+ if (!token && fs.existsSync(credentialsPath)) {
166
262
  try {
167
263
  const credentials = JSON.parse(fs.readFileSync(credentialsPath, "utf8"));
168
- isPro = true;
169
- console.log(`[PRO]: Machine Synced to Enterprise Cloud`);
170
- }
171
- catch (err) {
172
- console.log(`[AUTH ERROR]: Invalid credentials file. Run 'flowstride login' to reconnect.`);
264
+ token = credentials.machineToken;
173
265
  }
266
+ catch (err) { }
267
+ }
268
+ // THE FIX: Defensive Self-Healing
269
+ if (!process.env.FLOWSTRIDE_API_KEY &&
270
+ token &&
271
+ !fs.existsSync(nodeModulesPath)) {
272
+ if (fs.existsSync(credentialsPath))
273
+ fs.unlinkSync(credentialsPath);
274
+ token = null;
275
+ }
276
+ if (!token) {
277
+ console.log(chalk_1.default.white("⚪ [OS]: (Local Mode / Not Logged In)"));
278
+ forceOS = true;
174
279
  }
175
280
  else {
176
- console.log(`[OS]: Local Mode (Run 'flowstride login' to sync to Enterprise Cloud)`);
281
+ try {
282
+ const response = await fetch(`${API_BASE}/api/auth/verify-cli`, {
283
+ method: "GET",
284
+ headers: { Authorization: `Bearer ${token}` },
285
+ });
286
+ if (response.status === 401) {
287
+ console.log(chalk_1.default.red("🔴 AUTH EXPIRED: Your device session was revoked or expired."));
288
+ if (fs.existsSync(credentialsPath))
289
+ fs.unlinkSync(credentialsPath);
290
+ forceOS = true;
291
+ }
292
+ else if (response.ok) {
293
+ const data = await response.json();
294
+ const tier = data.tier.toUpperCase();
295
+ if (tier === "PERSONAL") {
296
+ console.log(chalk_1.default.yellow(`🟡 [OS]: [${data.workspaceName}] (Tier: PERSONAL)`));
297
+ }
298
+ else {
299
+ console.log(chalk_1.default.green(`🟢 [PRO]: [${data.workspaceName}] (Tier: ${tier})`));
300
+ }
301
+ }
302
+ else {
303
+ forceOS = await handleOfflinePrompt();
304
+ }
305
+ }
306
+ catch (err) {
307
+ forceOS = await handleOfflinePrompt();
308
+ }
177
309
  }
178
310
  if (options.headed) {
179
311
  options.headless = false;
@@ -184,8 +316,25 @@ program
184
316
  console.error(`Flowstride requires all UI tests to be inside a './flows' directory.`);
185
317
  process.exit(1);
186
318
  }
319
+ // Inject our DRM state into options before passing to runner
320
+ options.forceOS = forceOS;
187
321
  await (0, run_1.runAction)(strictUiFlowsDir, options);
188
322
  });
323
+ async function handleOfflinePrompt() {
324
+ console.log(chalk_1.default.yellow("🛜 OFFLINE: Unable to reach Flowstride Cloud. Enterprise Sync paused."));
325
+ if (process.env.CI || process.env.FLOWSTRIDE_API_KEY) {
326
+ console.log(chalk_1.default.yellow("⚠️ CI/CD Environment: Automatically falling back to OS Engine."));
327
+ return true; // Force OS
328
+ }
329
+ const runAnyway = await (0, prompts_1.confirm)({
330
+ message: "⚠️ Execute a local OS run anyway? (Pro features are disabled on OS)",
331
+ default: true,
332
+ });
333
+ if (!runAnyway) {
334
+ process.exit(0);
335
+ }
336
+ return true; // User said yes, Force OS
337
+ }
189
338
  program
190
339
  .command("report")
191
340
  .description("Launch the interactive Debug Dashboard")
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flowstride",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "An opensource flowfirst test automation framework",
5
5
  "workspaces": [
6
6
  "packages/flowstride_report"
@@ -41,6 +41,7 @@
41
41
  "playwright": "^1.59.1",
42
42
  "playwright-extra": "^4.3.6",
43
43
  "puppeteer-extra-plugin-stealth": "^2.11.2",
44
+ "tar": "^7.5.16",
44
45
  "ts-node": "^10.9.2",
45
46
  "undici": "^7.25.0",
46
47
  "ws": "^8.20.1"
@@ -245,7 +245,7 @@ Error generating stack: `+o.message+`
245
245
  *
246
246
  * This source code is licensed under the ISC license.
247
247
  * See the LICENSE file in the root directory of this source tree.
248
- */const ih=O("X",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]),sh=""+new URL("flow_logo-CjiL4Lvy.png",import.meta.url).href,uh=({isTestFlowsOpen:e,setTestFlowsOpen:t})=>{const{activeView:n,setActiveView:r}=Se(),l=[{id:"Flows",icon:Qp,label:"Flows"},{id:"Logs",icon:th,label:"Logs"},{id:"Reports",icon:Pc,label:"Reports"},{id:"TestCase",icon:Lc,label:"TestCase"}];return s.jsxs("nav",{style:{width:"75px",backgroundColor:"#0d1117",borderRight:"1px solid #30363d",display:"flex",flexDirection:"column",alignItems:"center",flexShrink:0,height:"100%",overflow:"hidden"},children:[s.jsx("div",{style:{padding:"25px 0",cursor:"pointer"},onClick:()=>r("Flows"),children:s.jsx("img",{src:sh,alt:"Flowstride",style:{width:"42px",height:"auto"}})}),n==="Flows"&&s.jsxs("div",{onClick:()=>t(!e),style:{width:"100%",display:"flex",flexDirection:"column",alignItems:"center",padding:"12px 0",cursor:"pointer",color:e?"#a78bfa":"#8b949e",borderBottom:"1px solid #21262d",marginBottom:"10px"},children:[s.jsx(Yp,{size:22}),s.jsx("span",{style:{fontSize:"10px",marginTop:"4px",fontWeight:"bold"},children:e?"Hide":"Show"})]}),s.jsx("div",{style:{flex:1,width:"100%"},children:l.map(o=>{const i=n===o.id;return s.jsxs("div",{onClick:()=>r(o.id),style:{width:"100%",display:"flex",flexDirection:"column",alignItems:"center",padding:"18px 0",cursor:"pointer",backgroundColor:i?"rgba(124, 58, 237, 0.08)":"transparent",borderLeft:i?"3px solid #7c3aed":"3px solid transparent",color:i?"#a78bfa":"#8b949e",transition:"color 0.2s ease"},children:[s.jsx(o.icon,{size:22,strokeWidth:i?2.5:2}),s.jsx("span",{style:{fontSize:"10px",marginTop:"6px",fontWeight:i?"600":"400"},children:o.label})]},o.id)})}),s.jsxs("div",{style:{padding:"25px 0",width:"100%",borderTop:"1px solid #30363d",display:"flex",flexDirection:"column",alignItems:"center"},children:[s.jsx("div",{style:{width:"38px",height:"38px",borderRadius:"50%",border:"2px solid #30363d",backgroundColor:"#1f2937",display:"flex",alignItems:"center",justifyContent:"center",color:"#a78bfa",fontWeight:"bold",fontSize:"14px"},children:"OS"}),s.jsx("span",{style:{fontSize:"11px",marginTop:"10px",fontWeight:"bold",color:"#ffffff"},children:"Open Source"}),s.jsx("span",{style:{fontSize:"9px",color:"#8b949e",marginTop:"2px",textAlign:"center",padding:"0 4px"},children:"COMMUNITY EDITION"})]})]})},ah=()=>{const{currentUrls:e,pageTitles:t,browserFrames:n,testScenarios:r,activeStepId:l,setActiveStepId:o,isRunning:i,activeTestFile:u,setActiveTestFile:a}=Se();F.useEffect(()=>{if(i){const c=r.find(p=>p.steps.some(g=>g.status==="running"));c&&c.fileName!==u&&a(c.fileName)}},[r,i,u,a]);let d=i?u:null,m=l;if(l&&l.includes(":::")){const c=l.split(":::");d=c[0],m=c[1]}const y=r.filter(c=>!d||c.fileName===d).flatMap(c=>c.steps).find(c=>c.id===m),h=!i&&!!(y&&y.screenshot),x=e[u]||"about:blank",v=t[u]||"New Tab",w=n[u]||null,_=h?y.screenshot:w,f=Array.from(new Set(r.map(c=>c.fileName)));return s.jsxs("div",{style:{height:"100%",display:"flex",flexDirection:"column",backgroundColor:"#1c2128"},children:[s.jsxs("div",{onWheel:c=>{c.currentTarget.scrollLeft+=c.deltaY},style:{display:"flex",alignItems:"center",padding:"8px 8px 0 8px",gap:"4px",overflowX:"auto",overflowY:"hidden",scrollbarWidth:"none",msOverflowStyle:"none"},children:[s.jsx("style",{children:`
248
+ */const ih=O("X",[["path",{d:"M18 6 6 18",key:"1bl5f8"}],["path",{d:"m6 6 12 12",key:"d8bk6v"}]]),sh=""+new URL("flow_logo-CjiL4Lvy.png",import.meta.url).href,uh=({isTestFlowsOpen:e,setTestFlowsOpen:t})=>{const{activeView:n,setActiveView:r}=Se(),l=[{id:"Flows",icon:Qp,label:"Flows"},{id:"Logs",icon:th,label:"Logs"},{id:"Reports",icon:Pc,label:"Reports"},{id:"TestCase",icon:Lc,label:"TestCase"}];return s.jsxs("nav",{style:{width:"75px",backgroundColor:"#0d1117",borderRight:"1px solid #30363d",display:"flex",flexDirection:"column",alignItems:"center",flexShrink:0,height:"100%",overflow:"hidden"},children:[s.jsx("div",{style:{padding:"25px 0",cursor:"pointer"},onClick:()=>r("Flows"),children:s.jsx("img",{src:sh,alt:"Flowstride",style:{width:"42px",height:"auto"}})}),n==="Flows"&&s.jsxs("div",{onClick:()=>t(!e),style:{width:"100%",display:"flex",flexDirection:"column",alignItems:"center",padding:"12px 0",cursor:"pointer",color:e?"#a78bfa":"#8b949e",borderBottom:"1px solid #21262d",marginBottom:"10px"},children:[s.jsx(Yp,{size:22}),s.jsx("span",{style:{fontSize:"10px",marginTop:"4px",fontWeight:"bold"},children:e?"Hide":"Show"})]}),s.jsx("div",{style:{flex:1,width:"100%"},children:l.map(o=>{const i=n===o.id;return s.jsxs("div",{onClick:()=>r(o.id),style:{width:"100%",display:"flex",flexDirection:"column",alignItems:"center",padding:"18px 0",cursor:"pointer",backgroundColor:i?"rgba(124, 58, 237, 0.08)":"transparent",borderLeft:i?"3px solid #7c3aed":"3px solid transparent",color:i?"#a78bfa":"#8b949e",transition:"color 0.2s ease"},children:[s.jsx(o.icon,{size:22,strokeWidth:i?2.5:2}),s.jsx("span",{style:{fontSize:"10px",marginTop:"6px",fontWeight:i?"600":"400"},children:o.label})]},o.id)})}),s.jsxs("a",{href:"https://cloud.flowstride.io/register",target:"_blank",rel:"noopener noreferrer",style:{padding:"25px 0",width:"100%",borderTop:"1px solid #30363d",display:"flex",flexDirection:"column",alignItems:"center",textDecoration:"none"},children:[s.jsx("div",{style:{width:"38px",height:"38px",borderRadius:"50%",border:"2px solid #30363d",backgroundColor:"#1f2937",display:"flex",alignItems:"center",justifyContent:"center",color:"#a78bfa",fontWeight:"bold",fontSize:"14px"},children:"OS"}),s.jsx("span",{style:{fontSize:"11px",marginTop:"10px",fontWeight:"bold",color:"#ffffff"},children:"Open Source"}),s.jsx("span",{style:{fontSize:"9px",color:"#8b949e",marginTop:"2px",textAlign:"center",padding:"0 4px"},children:"COMMUNITY EDITION"})]})]})},ah=()=>{const{currentUrls:e,pageTitles:t,browserFrames:n,testScenarios:r,activeStepId:l,setActiveStepId:o,isRunning:i,activeTestFile:u,setActiveTestFile:a}=Se();F.useEffect(()=>{if(i){const c=r.find(p=>p.steps.some(g=>g.status==="running"));c&&c.fileName!==u&&a(c.fileName)}},[r,i,u,a]);let d=i?u:null,m=l;if(l&&l.includes(":::")){const c=l.split(":::");d=c[0],m=c[1]}const y=r.filter(c=>!d||c.fileName===d).flatMap(c=>c.steps).find(c=>c.id===m),h=!i&&!!(y&&y.screenshot),x=e[u]||"about:blank",v=t[u]||"New Tab",w=n[u]||null,_=h?y.screenshot:w,f=Array.from(new Set(r.map(c=>c.fileName)));return s.jsxs("div",{style:{height:"100%",display:"flex",flexDirection:"column",backgroundColor:"#1c2128"},children:[s.jsxs("div",{onWheel:c=>{c.currentTarget.scrollLeft+=c.deltaY},style:{display:"flex",alignItems:"center",padding:"8px 8px 0 8px",gap:"4px",overflowX:"auto",overflowY:"hidden",scrollbarWidth:"none",msOverflowStyle:"none"},children:[s.jsx("style",{children:`
249
249
  div::-webkit-scrollbar { display: none; }
250
250
  `}),f.length>0?f.map((c,p)=>{const g=u===c;return s.jsxs("div",{onClick:()=>a(c),style:{backgroundColor:g?"var(--fs-bg-base)":"rgba(255,255,255,0.05)",padding:"6px 15px",borderRadius:"8px 8px 0 0",display:"flex",alignItems:"center",gap:"8px",border:g?"1px solid var(--fs-border)":"1px solid transparent",borderBottom:"none",minWidth:"130px",maxWidth:"200px",flexShrink:0,cursor:"pointer",opacity:g?1:.6},children:[s.jsx(no,{size:12,color:g?"var(--fs-accent-purple)":"#8b949e",style:{flexShrink:0}}),s.jsx("span",{style:{fontSize:"10px",color:g?"white":"#8b949e",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis",fontWeight:g?"bold":"normal"},children:c})]},p)}):s.jsxs("div",{style:{backgroundColor:"var(--fs-bg-base)",padding:"6px 15px",borderRadius:"8px 8px 0 0",display:"flex",alignItems:"center",gap:"8px",border:"1px solid var(--fs-border)",borderBottom:"none",minWidth:"140px",flexShrink:0},children:[s.jsx(no,{size:12,color:"var(--fs-accent-purple)"}),s.jsx("span",{style:{fontSize:"10px",color:"white"},children:v})]})]}),s.jsxs("div",{style:{backgroundColor:"var(--fs-bg-base)",borderTop:"1px solid var(--fs-border)",padding:"6px 12px",display:"flex",alignItems:"center",gap:"12px"},children:[s.jsxs("div",{style:{display:"flex",gap:"8px",color:"#8b949e"},children:[s.jsx(Bp,{size:14}),s.jsx(or,{size:14}),s.jsx(Mc,{size:14}),s.jsx(Gp,{size:14})]}),s.jsxs("div",{style:{flex:1,backgroundColor:"#05070a",border:"1px solid var(--fs-border)",borderRadius:"15px",padding:"3px 12px",display:"flex",alignItems:"center",gap:"8px"},children:[s.jsx(Xp,{size:10,color:"#22c55e"}),s.jsx("span",{style:{fontSize:"10px",color:"#8b949e",whiteSpace:"nowrap",overflow:"hidden"},children:x})]}),s.jsxs("div",{style:{display:"flex",gap:"10px",color:"#444",borderLeft:"1px solid #333",paddingLeft:"12px"},children:[s.jsx(Zp,{size:14,color:"var(--fs-accent-purple)"}),s.jsx(lh,{size:14}),s.jsx(nh,{size:14}),s.jsx($p,{size:14})]})]}),s.jsxs("div",{style:{flex:1,margin:"10px",backgroundColor:"white",borderRadius:"4px",boxShadow:"0 4px 12px rgba(0,0,0,0.5)",display:"flex",alignItems:"center",justifyContent:"center",overflow:"hidden",position:"relative"},children:[h&&s.jsxs("div",{style:{position:"absolute",top:"12px",left:"12px",right:"12px",backgroundColor:"rgba(15, 23, 42, 0.95)",border:"1px solid rgba(167, 139, 250, 0.3)",padding:"10px 16px",borderRadius:"6px",display:"flex",justifyContent:"space-between",alignItems:"center",zIndex:30,boxShadow:"0 4px 20px rgba(0,0,0,0.4)",backdropFilter:"blur(4px)"},children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"10px"},children:[s.jsx("div",{style:{backgroundColor:"rgba(167, 139, 250, 0.1)",padding:"6px",borderRadius:"4px"},children:s.jsx(Hp,{size:14,color:"#a78bfa"})}),s.jsxs("div",{children:[s.jsx("div",{style:{fontSize:"11px",fontWeight:"bold",color:"#a78bfa",textTransform:"uppercase",letterSpacing:"0.05em"},children:"Viewing Historical State"}),s.jsx("div",{style:{fontSize:"12px",color:"#e2e8f0",fontFamily:"monospace",marginTop:"2px"},children:y==null?void 0:y.command})]})]}),s.jsx("button",{onClick:()=>o(null),style:{backgroundColor:"#7c3aed",color:"white",border:"none",padding:"6px 14px",borderRadius:"4px",fontSize:"11px",fontWeight:"bold",cursor:"pointer",transition:"background 0.2s"},onMouseEnter:c=>c.currentTarget.style.backgroundColor="#6d28d9",onMouseLeave:c=>c.currentTarget.style.backgroundColor="#7c3aed",children:"Return to Live"})]}),_?s.jsx("img",{src:`data:image/png;base64,${_}`,style:{width:"100%",height:"100%",objectFit:"contain",opacity:h?.95:1},alt:"Browser frame"}):s.jsxs("div",{style:{textAlign:"center",color:"#ccc"},children:[s.jsx(no,{size:40,style:{marginBottom:"8px",opacity:.1}}),s.jsx("div",{style:{fontSize:"11px",fontWeight:500,opacity:.3},children:"WAITING FOR RENDER..."})]})]})]})},ch=()=>{const{networkLogs:e,activeNetworkTab:t,setNetworkTab:n,setSelectedLogId:r,setActiveView:l}=Se(),o=["REST","GraphQL","Network","WS"],i=e.filter(a=>t==="GraphQL"?a.url.includes("graphql"):t==="REST"?!a.url.includes("graphql")&&!a.url.includes("ws"):!0),u=a=>{r(a),l("Logs")};return s.jsxs("div",{style:{height:"100%",display:"flex",flexDirection:"column",backgroundColor:"#0d1117"},children:[s.jsx("div",{style:{display:"flex",borderBottom:"1px solid var(--fs-border)",backgroundColor:"#05070a"},children:o.map(a=>s.jsx("button",{onClick:()=>n(a),style:{padding:"10px 16px",fontSize:"11px",fontWeight:"600",background:"none",border:"none",color:t===a?"#a78bfa":"#444",borderBottom:t===a?"2px solid #7c3aed":"2px solid transparent",cursor:"pointer",transition:"all 0.2s"},children:a},a))}),s.jsxs("div",{style:{padding:"8px 12px",display:"flex",gap:"10px",alignItems:"center",borderBottom:"1px solid #161b22"},children:[s.jsxs("div",{style:{flex:1,position:"relative"},children:[s.jsx(Gi,{size:12,style:{position:"absolute",left:"8px",top:"50%",transform:"translateY(-50%)",color:"#444"}}),s.jsx("input",{type:"text",placeholder:`Filter ${t}...`,style:{width:"100%",background:"#05070a",border:"1px solid #30363d",borderRadius:"4px",padding:"4px 8px 4px 28px",fontSize:"10px",color:"white"}})]}),s.jsx(bp,{size:14,color:"#444"})]}),s.jsx("div",{style:{flex:1,overflowY:"auto"},children:i.length===0?s.jsxs("div",{style:{padding:"40px",textAlign:"center",color:"#444",fontSize:"11px"},children:["No ",t," traffic detected"]}):i.map((a,d)=>s.jsx("div",{onClick:()=>u(a.id),style:{borderBottom:"1px solid #161b22",cursor:"pointer",transition:"background 0.2s"},onMouseEnter:m=>m.currentTarget.style.backgroundColor="#161b22",onMouseLeave:m=>m.currentTarget.style.backgroundColor="transparent",children:s.jsxs("div",{style:{display:"flex",alignItems:"center",padding:"8px 12px",fontSize:"11px",gap:"10px"},children:[s.jsx("span",{style:{color:a.status<400?"#34d399":"#f87171",fontWeight:"bold",width:"25px"},children:a.status}),s.jsx("span",{style:{fontWeight:"bold",width:"35px",color:"#8b949e"},children:a.method}),s.jsx("span",{style:{flex:1,color:"white",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:a.name||a.url}),s.jsx("span",{style:{color:"#444",fontSize:"10px"},children:a.time})]})},d))})]})},dh=()=>{const{logs:e}=Se(),t=F.useRef(null);return F.useEffect(()=>{t.current&&(t.current.scrollTop=t.current.scrollHeight)},[e]),s.jsxs("div",{ref:t,style:{flex:1,backgroundColor:"#0d1117",padding:"10px 15px",fontFamily:"monospace",fontSize:"12px",overflowY:"auto",color:"#d1d5db",lineHeight:"1.5"},children:[e.length===0&&s.jsx("div",{style:{color:"#4b5563",fontStyle:"italic"},children:"System ready. Awaiting execution..."}),e.map((n,r)=>{const l=(n.type||n.status||"INFO").toUpperCase();let o="#34d399";return(n.status==="error"||n.type==="ERROR")&&(o="#f87171"),n.status==="warning"&&(o="#fbbf24"),n.type==="ACTION"&&(o="#60a5fa"),s.jsxs("div",{style:{marginBottom:"4px",display:"flex",gap:"8px"},children:[s.jsxs("span",{style:{color:"#6e7681",flexShrink:0},children:["[",n.timestamp||"--:--:--","]"]}),s.jsx("span",{style:{color:o,fontWeight:"bold",flexShrink:0,width:"55px"},children:l}),s.jsx("span",{style:{color:"#c9d1d9",wordBreak:"break-all"},children:n.summary})]},n.id||r)})]})},fh=({isRightPanelOpen:e})=>{const{logs:t,pageTitles:n,activeTestFile:r}=Se(),l=t[t.length-1],o=n[r]||"New Tab";return s.jsxs("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,display:"flex",flexDirection:"column",backgroundColor:"var(--fs-bg-base)",overflow:"hidden"},children:[s.jsxs("div",{style:{height:"35px",backgroundColor:"#161b22",borderBottom:"1px solid var(--fs-border)",display:"flex",alignItems:"center",padding:"0 15px",fontSize:"11px",color:"#8b949e",flexShrink:0},children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"8px",flex:1},children:[s.jsx("span",{style:{color:"#a78bfa",fontWeight:"bold"},children:"LOG:"}),s.jsx("span",{style:{color:"#c9d1d9",fontFamily:"monospace",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:(l==null?void 0:l.summary)||"System ready. Awaiting connection..."})]}),s.jsx("div",{style:{opacity:.5,fontStyle:"italic"},children:o})]}),s.jsxs("div",{style:{flex:1,display:"flex",overflow:"hidden"},children:[s.jsx("div",{style:{flex:1,borderRight:"1px solid var(--fs-border)",height:"100%",overflow:"hidden"},children:s.jsx(ah,{})}),s.jsxs("div",{style:{width:e?"400px":"0px",transition:"width 0.2s ease",display:"flex",flexDirection:"column",height:"100%",backgroundColor:"#0d1117",overflow:"hidden",flexShrink:0},children:[s.jsx("div",{style:{flex:1,overflow:"hidden",display:"flex",flexDirection:"column"},children:s.jsx(ch,{})}),s.jsxs("div",{style:{flex:1,borderTop:"1px solid var(--fs-border)",backgroundColor:"#0d1117",overflow:"hidden",display:"flex",flexDirection:"column"},children:[s.jsx("div",{style:{padding:"8px 15px",fontSize:"11px",fontWeight:"bold",color:"#8b949e",borderBottom:"1px solid var(--fs-border)",flexShrink:0},children:"LIVE INFO"}),s.jsx("div",{style:{flex:1,overflow:"hidden",position:"relative"},children:s.jsx(dh,{})})]})]})]})]})},ph=()=>{var h,x;const[e,t]=F.useState(null),{testScenarios:n,logs:r}=Se(),l=n.reduce((v,w)=>v+w.steps.length,0),o=n.reduce((v,w)=>v+w.steps.filter(_=>["pass","passed","success"].includes(_.status)).length,0),i=n.reduce((v,w)=>v+w.steps.filter(_=>_.status==="failed").length,0),u=n.reduce((v,w)=>{const _=w.fileName||"General";return v[_]||(v[_]=[]),v[_].push(w),v},{});let a="Verified.",d=null,m=null,y=null;if(e){const v=e.status==="failed",w=["pass","passed","success"].includes(e.status);if(m=e.screenshot,v){const f=`${e.type} ${e.description}`,c=r.slice().reverse().find(p=>p.type==="ERROR"&&p.fileName===e.fileName&&p.stepContext===f);a=c?c.summary:"Validation Failed.",!m&&((h=c==null?void 0:c.details)!=null&&h.screenshot)&&(m=c.details.screenshot),(x=c==null?void 0:c.details)!=null&&x.boundingBox&&(y=c.details.boundingBox)}else e.status==="running"?a="Executing...":w&&(a="Action verified successfully.");const _=r.slice().reverse().find(f=>(f.type==="REST"||f.type==="GRAPHQL")&&f.fileName===e.fileName);d=_?_.details:null}return s.jsxs("div",{style:{height:"100%",width:"100%",backgroundColor:"#f8fafc",overflowY:"auto",position:"relative",color:"#0f172a"},children:[s.jsxs("div",{style:{maxWidth:"1200px",margin:"0 auto",padding:"40px 20px",marginRight:e?"450px":"auto",transition:"margin-right 0.3s"},children:[s.jsxs("header",{style:{display:"flex",justifyContent:"space-between",alignItems:"flex-end",borderBottom:"1px solid #e2e8f0",paddingBottom:"24px",marginBottom:"40px"},children:[s.jsxs("div",{children:[s.jsx("h1",{style:{fontSize:"30px",fontWeight:"800",margin:0,color:"#1e293b"},children:"Flowstride Reports"}),s.jsx("p",{style:{color:"#64748b",margin:"4px 0 0 0",fontWeight:"500"},children:"Multi-Flow Execution Analysis"})]}),s.jsxs("div",{style:{display:"flex",gap:"16px"},children:[s.jsx(ro,{label:"PASSED",value:o,color:"#10b981",icon:s.jsx(Tc,{size:20})}),s.jsx(ro,{label:"FAILED",value:i,color:"#ef4444",icon:s.jsx(_c,{size:20})}),s.jsx(ro,{label:"TOTAL",value:l,color:"#3b82f6",icon:s.jsx(Pc,{size:20})})]})]}),Object.keys(u).map(v=>s.jsxs("div",{style:{marginBottom:"60px"},children:[s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"20px",marginBottom:"24px"},children:[s.jsx("div",{style:{height:"2px",flex:1,backgroundColor:"#7c3aed",opacity:.15}}),s.jsxs("div",{style:{display:"flex",alignItems:"center",gap:"10px",color:"#7c3aed",fontWeight:"900",fontSize:"11px",textTransform:"uppercase",letterSpacing:"0.1em",backgroundColor:"rgba(124, 58, 237, 0.05)",padding:"6px 16px",borderRadius:"20px",border:"1px solid rgba(124, 58, 237, 0.1)"},children:[s.jsx(Nc,{size:14})," ",v]}),s.jsx("div",{style:{height:"2px",flex:1,backgroundColor:"#7c3aed",opacity:.15}})]}),s.jsx("div",{style:{backgroundColor:"white",borderRadius:"12px",border:"1px solid #e2e8f0",boxShadow:"0 1px 3px rgba(0,0,0,0.05)",overflow:"hidden"},children:s.jsxs("table",{style:{width:"100%",borderCollapse:"collapse",textAlign:"left"},children:[s.jsx("thead",{style:{backgroundColor:"#f1f5f9",borderBottom:"1px solid #e2e8f0"},children:s.jsx("tr",{children:["S/N","Scenario","Action","Status",""].map((w,_)=>s.jsx("th",{style:{padding:"16px 24px",fontSize:"10px",fontWeight:"800",color:"#64748b",textTransform:"uppercase"},children:w},_))})}),s.jsx("tbody",{children:u[v].flatMap(w=>w.steps.map((_,f)=>s.jsxs("tr",{onClick:()=>t({..._,scenarioName:w.name,fileName:v}),style:{cursor:"pointer",borderBottom:"1px solid #f1f5f9",backgroundColor:(e==null?void 0:e.id)===_.id?"#eff6ff":"transparent"},children:[s.jsx("td",{style:{padding:"18px 24px",fontSize:"12px",color:"#94a3b8",fontFamily:"monospace",fontWeight:"bold"},children:f+1}),s.jsx("td",{style:{padding:"18px 24px",fontWeight:"600",color:"#334155"},children:w.name}),s.jsxs("td",{style:{padding:"18px 24px",fontSize:"14px",color:"#475569"},children:[s.jsx("b",{style:{color:"#7c3aed",marginRight:"8px"},children:_.type})," ",_.description]}),s.jsx("td",{style:{padding:"18px 24px"},children:s.jsx(yh,{status:_.status})}),s.jsx("td",{style:{padding:"18px 24px",textAlign:"right"},children:s.jsx(or,{size:16,color:(e==null?void 0:e.id)===_.id?"#3b82f6":"#cbd5e1",style:{transform:(e==null?void 0:e.id)===_.id?"rotate(90deg)":"none",transition:"0.2s"}})})]},_.id)))})]})})]},v))]}),s.jsx("aside",{style:{position:"fixed",top:0,right:0,height:"100%",width:"450px",backgroundColor:"white",boxShadow:"-10px 0 40px rgba(0,0,0,0.1)",borderLeft:"1px solid #e2e8f0",zIndex:100,transform:e?"translateX(0)":"translateX(100%)",transition:"transform 0.3s cubic-bezier(0.4, 0, 0.2, 1)",padding:"30px",overflowY:"auto"},children:e&&s.jsxs(s.Fragment,{children:[s.jsxs("div",{style:{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:"32px"},children:[s.jsxs("h2",{style:{fontSize:"18px",fontWeight:"700",display:"flex",alignItems:"center",gap:"10px"},children:[s.jsx(oh,{size:18,color:"#3b82f6"})," Step Diagnostics"]}),s.jsx(ih,{onClick:()=>t(null),style:{cursor:"pointer",color:"#94a3b8"}})]}),m&&s.jsx(Rn,{label:`Visual State (${(e.status||"").toUpperCase()})`,children:s.jsx(hh,{screenshot:m,boundingBox:y})}),s.jsx(Rn,{label:"Context",children:s.jsx("div",{style:{fontWeight:"bold",color:"#1e293b"},children:e.scenarioName})}),s.jsx(Rn,{label:"Requirement Proof",children:s.jsxs("div",{style:{padding:"16px",backgroundColor:"#f8fafc",borderRadius:"8px",fontSize:"14px",fontStyle:"italic",color:"#475569",border:"1px solid #f1f5f9"},children:['"',e.type," ",e.description,'"']})}),s.jsx(Rn,{label:"Runtime Outcome",children:s.jsx("div",{style:{padding:"16px",borderRadius:"8px",fontSize:"14px",fontWeight:"500",backgroundColor:["pass","success","passed"].includes(e.status)?"#ecfdf5":"#fef2f2",color:["pass","success","passed"].includes(e.status)?"#065f46":"#991b1b",border:`1px solid ${["pass","success","passed"].includes(e.status)?"#d1fae5":"#fee2e2"}`},children:a})}),d&&s.jsx(Rn,{label:"Network Activity",children:s.jsx("div",{style:{backgroundColor:"#0f172a",padding:"16px",borderRadius:"8px",color:"#7dd3fc",fontFamily:"monospace",fontSize:"11px",overflowX:"auto"},children:s.jsx("pre",{children:JSON.stringify({status:d.responseStatus,url:d.url},null,2)})})})]})})]})},hh=({screenshot:e,boundingBox:t})=>{const[n,r]=F.useState({w:0,h:0}),[l,o]=F.useState(!1),i=()=>{const u=window.open();u&&(u.document.write(`
251
251
  <html>
@@ -5,7 +5,7 @@
5
5
  <link rel="icon" type="image/png" href="./favicon.png" />
6
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
7
  <title>Flowstride</title>
8
- <script type="module" crossorigin src="./assets/index-Brl3nrIZ.js"></script>
8
+ <script type="module" crossorigin src="./assets/index-BrbAbAha.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="./assets/index-DXTn_ThB.css">
10
10
  </head>
11
11
  <body>