,
+ children: ()}))
+ }
+ />}
+ >
+ );
+}
+export function ScenarioTitleCtr(props: {data:Scenario}) {
+ return (
+
+ {props.data.Status === 0 ? () :}
+ { `SCENARIO: ${props.data.ScenarioTitle}`}
+
+ );
+}
+export function ScenarioCtr(props: {data:Scenario}) {
+ return (
+ )} style={{width:"auto"}}>
+ ({
+ dot: value.Status === 3 ? () :,
+ children: ()}))
+ }
+ />
+
+ );
+}
+
+function generateTableOfContent(data:Scenario[])
+{
+ const dirPaths : string[] = data.map(d => getDirectoryPath(d.FilePath))
+ const rootDir = findLongestCommonPrefix(dirPaths);
+ return createDirectoryTree(data, rootDir);
+}
+
+function retriveData(): Scenario[]
+{
+ const dataStorage = document.getElementById('ScenarioData') as HTMLElement;
+ if(dataStorage!=null && dataStorage.innerText.trim().length >0)
+ {
+ try {
+ return JSON.parse(dataStorage.innerText) as Scenario[];
+ }catch
+ {
+ return [];
+ }
+ }
+ return [];
+}
+
+function App() {
+ const scenarioData = retriveData();
+ const treeData = generateTableOfContent(scenarioData);
+
+ const [scenarioState, setScenarioState] = useState(scenarioData)
+ const [treeState, setTreeState] = useState(treeData)
+
+ useEffect( () => {
+ (async ()=>{
+ if(scenarioData.length === 0)
+ {
+ const response = await fetch("/scenarios.json")
+ const sampleData = await response.json();
+ setScenarioState(sampleData as Scenario[])
+ setTreeState(generateTableOfContent(sampleData))
+ }
+ })()
+ });
+
+ return (
+
+
+
+ {
+ if(a.node.isLeaf && a.node.title != null) {
+
+ document.location = "#" + a.node.title.toString().replace(/\W+/g,"-")
+ }
+ }} />
+
+
+
+
+
+
+
+
+ {scenarioState.map(value => )}
+
+
+
+
+
+
+ );
+}
+
+export default App;
diff --git a/src/nscenario-report-browser/src/index.css b/src/nscenario-report-browser/src/index.css
new file mode 100644
index 0000000..af357d8
--- /dev/null
+++ b/src/nscenario-report-browser/src/index.css
@@ -0,0 +1,17 @@
+body {
+ margin: 0;
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
+ 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
+ sans-serif;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+code {
+ font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
+ monospace;
+}
+.ant-timeline-item
+{
+ padding-bottom: 5px!important;
+}
\ No newline at end of file
diff --git a/src/nscenario-report-browser/src/index.tsx b/src/nscenario-report-browser/src/index.tsx
new file mode 100644
index 0000000..6c16322
--- /dev/null
+++ b/src/nscenario-report-browser/src/index.tsx
@@ -0,0 +1,25 @@
+import React from 'react';
+import ReactDOM from 'react-dom/client';
+import './index.css';
+import App from './App';
+import reportWebVitals from './reportWebVitals';
+
+
+document.addEventListener('DOMContentLoaded', (event) => {
+ const root = ReactDOM.createRoot(
+ document.getElementById('root') as HTMLElement
+ );
+ root.render(
+
+
+
+ );
+ // If you want to start measuring performance in your app, pass a function
+// to log results (for example: reportWebVitals(console.log))
+// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
+ reportWebVitals();
+});
+
+
+
+
diff --git a/src/nscenario-report-browser/src/logo.svg b/src/nscenario-report-browser/src/logo.svg
new file mode 100644
index 0000000..9dfc1c0
--- /dev/null
+++ b/src/nscenario-report-browser/src/logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/nscenario-report-browser/src/react-app-env.d.ts b/src/nscenario-report-browser/src/react-app-env.d.ts
new file mode 100644
index 0000000..6431bc5
--- /dev/null
+++ b/src/nscenario-report-browser/src/react-app-env.d.ts
@@ -0,0 +1 @@
+///
diff --git a/src/nscenario-report-browser/src/reportWebVitals.ts b/src/nscenario-report-browser/src/reportWebVitals.ts
new file mode 100644
index 0000000..49a2a16
--- /dev/null
+++ b/src/nscenario-report-browser/src/reportWebVitals.ts
@@ -0,0 +1,15 @@
+import { ReportHandler } from 'web-vitals';
+
+const reportWebVitals = (onPerfEntry?: ReportHandler) => {
+ if (onPerfEntry && onPerfEntry instanceof Function) {
+ import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
+ getCLS(onPerfEntry);
+ getFID(onPerfEntry);
+ getFCP(onPerfEntry);
+ getLCP(onPerfEntry);
+ getTTFB(onPerfEntry);
+ });
+ }
+};
+
+export default reportWebVitals;
diff --git a/src/nscenario-report-browser/src/setupTests.ts b/src/nscenario-report-browser/src/setupTests.ts
new file mode 100644
index 0000000..8f2609b
--- /dev/null
+++ b/src/nscenario-report-browser/src/setupTests.ts
@@ -0,0 +1,5 @@
+// jest-dom adds custom jest matchers for asserting on DOM nodes.
+// allows you to do things like:
+// expect(element).toHaveTextContent(/react/i)
+// learn more: https://github.com/testing-library/jest-dom
+import '@testing-library/jest-dom';
diff --git a/src/nscenario-report-browser/tsconfig.json b/src/nscenario-report-browser/tsconfig.json
new file mode 100644
index 0000000..a273b0c
--- /dev/null
+++ b/src/nscenario-report-browser/tsconfig.json
@@ -0,0 +1,26 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": [
+ "dom",
+ "dom.iterable",
+ "esnext"
+ ],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "strict": true,
+ "forceConsistentCasingInFileNames": true,
+ "noFallthroughCasesInSwitch": true,
+ "module": "esnext",
+ "moduleResolution": "node",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "noEmit": true,
+ "jsx": "react-jsx"
+ },
+ "include": [
+ "src"
+ ]
+}