{ "nodes": [ { "id": "d8e2aff974909103", "type": "group", "x": -3200, "y": 1720, "width": 4740, "height": 2520, "label": "Review" }, { "id": "617997c10ecbe3aa", "type": "group", "x": -2580, "y": -80, "width": 3380, "height": 1635, "label": "Flagging workflow" }, { "id": "c15be9ac1d7a839f", "type": "group", "x": -640, "y": 1980, "width": 2040, "height": 2220, "color": "3", "label": "Building the review" }, { "id": "7dca5bb0aec7f730", "type": "group", "x": -2560, "y": -55, "width": 1400, "height": 1440, "color": "1", "label": "Flagging" }, { "id": "5b84916acc0a0362", "type": "group", "x": -2080, "y": 2590, "width": 1300, "height": 1000, "color": "4", "label": "Report Filestructure" }, { "id": "41ae23152619c090", "type": "group", "x": -340, "y": -50, "width": 400, "height": 730, "label": "Notes" }, { "id": "45c0a03b2403c787", "type": "group", "x": -1090, "y": -50, "width": 450, "height": 500, "color": "6", "label": "\"Blatant Plagiarism\"" }, { "id": "b3e4ecac08c99999", "type": "group", "x": -1020, "y": 780, "width": 380, "height": 570, "color": "3", "label": "Manual checking" }, { "id": "91f43be181153a2f", "type": "text", "text": "No report if no flags", "styleAttributes": { "textAlign": "center" }, "x": -2180, "y": 1305, "width": 240, "height": 60, "color": "1" }, { "id": "e155f81df7567675", "type": "text", "text": "Show flagged areas:\n\n- Using comments in code\n- Highlights in LaTeX", "styleAttributes": {}, "x": -980, "y": 800, "width": 320, "height": 140 }, { "id": "cff5136ac15e7282", "type": "text", "text": "User edits % confidence for AI and/or confirms blatant plagiarism, by accepting or dismissing flagged areas", "styleAttributes": {}, "x": -980, "y": 1000, "width": 320, "height": 160 }, { "id": "369b3ccbec406b84", "type": "text", "text": "User can add comments to each accepted flagged area", "styleAttributes": {}, "x": -980, "y": 1220, "width": 320, "height": 100 }, { "id": "f70e12918d4a24f5", "type": "text", "text": "exports into a json, e.g. assuming that there are 5 exercises:\n```json\n[\n\t{\n\t\t\"student\": 1234567,\n\t\t\"per_exercise\": [\n\t\t\t{\n\t\t\t\t\"plagiarism\": {\n\t\t\t\t\t\"value\": 100.0,\n\t\t\t\t\t\"comment\": \"student plagiarized from s7654321 (this is added by user)\",\n\t\n\t\t\t\t},\n\t\t\t\t\"ai\": {\n\t\t\t\t\t\"value\": 10.00,\n\t\t\t\t\t\"comment\": \"ai-esque formatting\",\n\t\t\t\t}\n\t\t\t}\n\t\t\t// rest of exercises (first 100% plag, 10% ai, rest 0% PLAG, 100% ai)\n\t\t],\n\t\t\"overall\": {\n\t\t\t\"plagiarism\": {\n\t\t\t\t\"value\": 20.0, // student plagiarized on 1 exercise\n\t\t\t\t\"comment\": \"blah\"\n\t\t\t},\n\t\t\t\t\n\t\t\t\"ai\": {\n\t\t\t\t\"value\": 82.0 , // blatantly ai generated the rest + 1/10 * 1/5 * 100 = 2\n\t\t\t\t\"comment\":null\n\t\t\t}\n\t\t}\n\t\t\n\t}\n]\n```", "styleAttributes": { "textAlign": "center" }, "x": -420, "y": 738, "width": 870, "height": 818 }, { "id": "8b73e5aa1b99be1f", "type": "text", "text": "For each student", "styleAttributes": { "textAlign": "center" }, "x": -2040, "y": -35, "width": 222, "height": 60 }, { "id": "752136851c08fc83", "type": "text", "text": "Prepare for manual checking", "styleAttributes": { "textAlign": "center" }, "x": -1978, "y": 1115, "width": 248, "height": 100, "color": "4" }, { "id": "b037f6b77d5f7127", "type": "text", "text": "Get latest Themis submission", "styleAttributes": { "textAlign": "center" }, "x": -1860, "y": 105, "width": 260, "height": 60 }, { "id": "fedd34d7c9d8e05a", "type": "text", "text": "Run \"blatant\" plagiarism checks", "styleAttributes": { "textAlign": "center" }, "x": -1990, "y": 745, "width": 260, "height": 60, "color": "6" }, { "id": "81b169838f131921", "type": "text", "text": ">[!Warning]\n>All of the features described in the data extraction segments are **only to be used as markers**, as none of them are objective!", "styleAttributes": {}, "x": -320, "y": 220, "width": 360, "height": 240 }, { "id": "f1ddd6eba5309171", "type": "text", "text": "Cyan arrows mean **optional**, so just ideas for now.", "x": -320, "y": 460, "width": 360, "height": 193, "color": "5" }, { "id": "cd65de7baebaa0ac", "type": "text", "text": ">[!Warning]\n>If we want this data to be non-problematic, we CANNOT be sending any of this to third-parties (so unlicensed AI checkers don't work)", "styleAttributes": {}, "x": -320, "y": -20, "width": 360, "height": 240 }, { "id": "3f9f56795499e26f", "type": "text", "text": "Peer plagiarism check", "styleAttributes": {}, "x": -1020, "y": -35, "width": 260, "height": 80 }, { "id": "54d156c855d043cf", "type": "text", "text": "Blatant AI usage check\n- check for prompt leftovers, i.e.:\n> Sure, let's...\n> Here's...\n... existing code ...\n- Special character usage in code (any UTF-8 character)", "styleAttributes": {}, "x": -1080, "y": 165, "width": 410, "height": 260 }, { "id": "8babf02556920e0f", "type": "text", "text": ">[!Idea]\n>If we have a reliable way to determine AI usage, we can train our own in-house AI to check for this!", "styleAttributes": {}, "x": -740, "y": 520, "width": 360, "height": 180 }, { "id": "4a4004f9eb0df102", "type": "text", "text": ">[!Idea]\nRun some sort of language analysis.\n>\n> - Check for style changes in language - formal in one paragraph, informal in other\n> - Check for correctness - no grammatical or punctuation mistakes are very unlikely without AI\n> - telltale sign -> ’ vs ' - latex doesn't differentiate\n> - style in latex -> spacing and excessive bolding are characteristic of AI\n", "styleAttributes": { "shape": null, "textAlign": "center" }, "x": -2550, "y": 605, "width": 530, "height": 335 }, { "id": "ba75ad6041650471", "type": "text", "text": ">[!Idea]\nExtract data from code\n> - Comment to code ratio\n> - Changes in style (indentation, // vs /* \\*/, bracket placement)\n> - Advanced language usage depending on course (e.g. using const or inline during PF implies that you know your C or you're using AI)\n\n", "styleAttributes": { "shape": null }, "x": -1710, "y": 638, "width": 520, "height": 302 }, { "id": "f5acbdab9fb6755c", "type": "text", "text": "Get latest Brightspace submission", "styleAttributes": { "textAlign": "center" }, "x": -2210, "y": 95, "width": 260, "height": 80 }, { "id": "49fefa2c808800a0", "type": "text", "text": "OCR (latex) or use tex if provided", "styleAttributes": { "textAlign": "center" }, "x": -2220, "y": 275, "width": 280, "height": 60 }, { "id": "d130712eb1ba3ff9", "type": "text", "text": "Split code into \"blocks\" (functions and such)\n", "styleAttributes": { "textAlign": "center" }, "x": -1860, "y": 265, "width": 340, "height": 80 }, { "id": "8ec144e7b743ff08", "type": "text", "text": "Preprocess code sections into `.tex` files to be included (with highlighting)", "styleAttributes": { "textAlign": "center" }, "x": 250, "y": 2140, "width": 260, "height": 120 }, { "id": "a30b62a70efd5f99", "type": "text", "text": "Inject into the corresponding `.tex`es", "styleAttributes": {}, "x": 250, "y": 2340, "width": 260, "height": 100 }, { "id": "1161285c0887cec2", "type": "text", "text": "Add submission to `build/insertable.tex` document:\n```tex\n% It is possible for one of these sections to not exist (if folder is empty or d.n.e.)\n\\section{S1234567}\n\\input{review_1234567/overall.tex}\n% optional review_1234567/score.json included here\n\n\\subsection{Code Review}\n\\input{review_1234567/build/code.tex}\n\n\n\\subsection{Document Review}\n\\input{review_1234567/build/document.tex}\n```", "styleAttributes": {}, "x": -295, "y": 3760, "width": 820, "height": 405 }, { "id": "7d6ebe642a2f40cc", "type": "text", "text": "Python script automatically:", "styleAttributes": { "textAlign": "center" }, "x": 310, "y": 1995, "width": 140, "height": 120 }, { "id": "0da48d99a3484f6d", "type": "text", "text": "add to ```/report.tex```\n```tex\n% preamble\n\\begin{document}\n\n% intro\n\\section{Introduction}\nThis document is a comprehensive report of blah blah blah blah.\n\n% reports\n% s1234567\n\\input{reviews/review_1234567/build/insertable.tex}\n% other individual reports will go here\n\\end{document}\n```", "styleAttributes": { "textAlign": "center" }, "x": 605, "y": 3773, "width": 530, "height": 380 }, { "id": "c40385532044360f", "type": "text", "text": "Consolidate document sections into a `build/document.tex`\n```tex\n%% submittable 1 %%\n\\subsubsection{Section - Introduction} % the name will be added automatically from the filename\n\n% latex file - document/1_introduction/student.tex\n\\begin{student}\nI am the student. This is \\hl{\\textbf{AI Generated}: Generated by Artifical Intelligence.}\n\\end{student}\n\n% latex file - document/1_introduction/comment.tex\n\\begin{comment}\nJudging by the completely unnecessary definition, this seems to be AI generated\n\\end{comment}\n\n% optional, data sourced from score.json, all names sourced from config.json\n\\subsubsection{Metrics}\n\\begin{center}\n\\begin{tabular}{|c|c|}\n\\hline\nMetric & Percentage \\\\\n\\hline\nPeer Plagiarism & 20\\% \\\\\nAI & 82\\%\n\n\\end{tabular}\n\\end{center}\n\n\\begin{comment}\n\\textbf{Peer Plagiarism} % also sourced from config.json\nblah\n% \\textbf{AI} this doesn't exist since \t\"comment\":null, name sourced from config.json\n\n\\end{comment}\n```", "styleAttributes": { "textAlign": "center" }, "x": 380, "y": 2560, "width": 980, "height": 960 }, { "id": "c8603366bc48c5a8", "type": "text", "text": "Consolidate code sections into a `build/code.tex`:\n```tex\n%% submittable 1 %%\n\\subsubsection{Submittable 1} % value from config.json\n\n% Code file (code/1.py)\n\\begin{lstlisting} % highlighting will be added automatically based on file extension\n\nprint(\"not ai\")\n(*@ \\hl{print(\"ai)} @*) % print(\"ai\") \n\n\\end{lstlisting}\n\n% Latex file (code/1.tex)\n\\begin{comment} % will be enclosed in comment environment automatically\nThe user clearly used AI in the highlighted line\n\\end{comment}\n\n% optional, data sourced from score.json, all names sourced from config.json\n\\subsubsection{Metrics} \n\\begin{center}\n\\begin{tabular}{|c|c|}\n\\hline\nMetric & Percentage \\\\\n\\hline\nPeer Plagiarism & 20\\% \\\\ % config.json\nAI & 82\\% % config.json\n\n\\end{tabular}\n\\end{center}\n\n\\begin{comment}\n\\textbf{Peer Plagiarism} % also sourced from config.json\nblah\n% \\textbf{AI} this doesn't exist since \t\"comment\":null, name sourced from config.json\n\n\\end{comment}\n```", "styleAttributes": { "textAlign": "center" }, "x": -620, "y": 2560, "width": 945, "height": 960 }, { "id": "c38053aa7c2aad55", "type": "text", "text": "`/`", "styleAttributes": { "textAlign": "center" }, "x": -1713, "y": 2630, "width": 267, "height": 60 }, { "id": "718c00c9f0b2ae02", "type": "text", "text": "`score.json`", "styleAttributes": { "border": "dashed", "textAlign": "center" }, "x": -1866, "y": 2870, "width": 126, "height": 60 }, { "id": "d361b6a7e02f5ce8", "type": "text", "text": "`review_/`", "styleAttributes": { "textAlign": "center" }, "x": -1680, "y": 2870, "width": 200, "height": 60, "color": "6" }, { "id": "e8bb990cf4d5abbe", "type": "text", "text": "`overall.tex`\nThis contains overall comments and scores", "styleAttributes": { "textAlign": "center" }, "x": -1695, "y": 3025, "width": 231, "height": 100, "color": "5" }, { "id": "3b8351d46238b500", "type": "text", "text": "`code/`", "styleAttributes": { "textAlign": "center" }, "x": -1920, "y": 3030, "width": 108, "height": 40 }, { "id": "2d3d8299d2940c91", "type": "text", "text": "numbered folders per Themis submittable \n> 1/, 2/, 3/", "styleAttributes": { "textAlign": "center" }, "x": -1996, "y": 3145, "width": 260, "height": 100, "color": "6" }, { "id": "74e3b31fbf552352", "type": "text", "text": "`score.json`", "styleAttributes": { "border": "dashed", "textAlign": "center" }, "x": -1680, "y": 3165, "width": 126, "height": 60 }, { "id": "1a6ef38ff82e7f26", "type": "text", "text": "Corresponding latex file to be included as a comment\n\n> 1.tex, 2.tex, 3.tex", "styleAttributes": { "textAlign": "center" }, "x": -1760, "y": 3340, "width": 260, "height": 140, "color": "5" }, { "id": "426fecaf63cd032e", "type": "text", "text": "Suspicious text should be highlighted here using `\\hl{text}`\n\n (if you want highlighting)", "styleAttributes": { "border": "dashed", "textAlign": "center" }, "x": -1840, "y": 3650, "width": 420, "height": 140 }, { "id": "2d7a0b5a695bb9dd", "type": "text", "text": "Problematic sections (OCR or manual review)\n\n> student.tex\n\nIncluding original text", "styleAttributes": { "textAlign": "center" }, "x": -1445, "y": 3380, "width": 249, "height": 180, "color": "5" }, { "id": "d363ae68077580c2", "type": "text", "text": "Numbered, snake case-labelled problematic sections (exercises) in document (OCR or manual review)\n>1_exercise_1/", "styleAttributes": { "textAlign": "center" }, "x": -1315, "y": 3150, "width": 300, "height": 160, "color": "6" }, { "id": "af31afa6fefe62b9", "type": "text", "text": "Comments for problematic section\n> comment.tex", "styleAttributes": { "textAlign": "center" }, "x": -1165, "y": 3405, "width": 340, "height": 100, "color": "5" }, { "id": "18af4a0953772fca", "type": "text", "text": "`score.json`", "styleAttributes": { "border": "dashed", "textAlign": "center" }, "x": -951, "y": 3200, "width": 126, "height": 60 }, { "id": "fec21ca7aacbdb86", "type": "text", "text": "`reviews/`", "styleAttributes": { "textAlign": "center" }, "x": -1648, "y": 2730, "width": 136, "height": 60 }, { "id": "bf5ee292546142fe", "type": "text", "text": "`build/`\nwill house `code.tex`, `review.tex` and `insertable.tex`", "styleAttributes": { "textAlign": "center" }, "x": -1404, "y": 2840, "width": 260, "height": 120 }, { "id": "d4fffdc078b4aaeb", "type": "text", "text": "`document/`", "styleAttributes": { "textAlign": "center" }, "x": -1420, "y": 3035, "width": 146, "height": 40 }, { "id": "71ba916ec96ad1be", "type": "text", "text": "Things that user should fill in/annotate are marked in **CYAN**", "styleAttributes": { "border": "invisible" }, "x": -1040, "y": 2600, "width": 260, "height": 100 }, { "id": "19540bd3c895f9bc", "type": "text", "text": "Numbered flagged/suspicious exercises + file extension for highlighting\n> 1.c, 2.c, 3.c", "styleAttributes": { "textAlign": "center" }, "x": -2050, "y": 3330, "width": 260, "height": 160, "color": "5" }, { "id": "b6f9319ee8e11549", "type": "text", "text": "To highlight specific parts in the final document, surround the section in ``.\nE.g.:\n```python\n print(\"definitely not plagiarized\") \n```", "styleAttributes": { "textAlign": "center", "border": "dashed" }, "x": -2720, "y": 3320, "width": 600, "height": 180 }, { "id": "96defc0b2d99568c", "type": "text", "text": "> [!OPTIONAL]\n> The folders marked in **PURPLE** can contain a score.json file, which can be imported from the flagging toolkit or created manually and will be included as shown in the diagram on the right\n\n```json\n\"plagiarism\": {\n\t\"value\": 20.0, // student plagiarized on 1 exercise\n\t\"comment\": \"blah\"\n},\n\t\n\"ai\": {\n\t\"value\": 82.0 , // blatantly ai generated the rest + 1/10 * 1/5 * 100 = 2\n\t\"comment\":null\n}\n```", "styleAttributes": { "textAlign": "center" }, "x": -1812, "y": 2055, "width": 770, "height": 380 }, { "id": "ccd335e21a1d13a0", "type": "text", "text": "can be exported into the report", "styleAttributes": {}, "x": 510, "y": 1117, "width": 260, "height": 60, "color": "4" }, { "id": "bc5754540847ddbf", "type": "text", "text": "`config.json`\nIf doesn't exist, defaults will be loaded", "styleAttributes": { "border": "dashed", "textAlign": "center" }, "x": -2050, "y": 2610, "width": 260, "height": 100 }, { "id": "7c4588ca6e195422", "type": "text", "text": "`report.tex`\nfull, consolidated report", "styleAttributes": { "textAlign": "center" }, "x": -1347, "y": 2620, "width": 260, "height": 80 }, { "id": "2c91857ebd9d843d", "type": "text", "text": "The defaults and format for this are listed below:\n\n```json\n{\n\tstyle: {// Code subsection name\n\t\t\"per_submittable\": \"Submittable $num\", // Can use variable $num for automatic numbering\n\t\t// Or provide a list if you want specific exercise names\n\t\t\n\t\t// Document section name\n\t\t\"per_section\": \"Section - $section\", // same as above, but using $section\n\t\t// e.g. 1_introduction_robust.tex -> $section = \"Introduction Robust\"\n\t\n\t\t// optional metrics table subsection\n\t\t// you can leave this as None or omit it (table will not show even if score.json is there)\n\t\t\"table\": {\n\t\t\t\"heading\": \"Metrics\",\n\t\t\t\"key\": \"Metric\",\n\t\t\t\"value\": \"Percentage\",\n\t\t\t\"metrics\": [\"Peer Plagiarism\", \"AI\"] // be careful with the ordering here\n\t\t}\n\t}\n\t// TODO: add specific template parsing to automate the section splitting\n}\n```", "styleAttributes": { "textAlign": "center" }, "x": -3120, "y": 2330, "width": 940, "height": 560 }, { "id": "9ca8a0ce1a528850", "type": "text", "text": "Section folders should be named as such:\n`_name_in_snake_case/`", "styleAttributes": { "textAlign": "center", "border": "dashed" }, "x": -1271, "y": 3680, "width": 320, "height": 80 }, { "id": "f7cabd512e3cadf6", "type": "text", "text": "Assume student submitted:\n- `1.py` on Themis\n- `some.pdf` with an Introduction section\n\nThat means that the following files have been created and populated:\n- `code/1.tex` containing the student's code (highlighted with `` tags)\n- `document/1_introduction/`\n\t- `student.tex`, where the student's content resides (highlighted bad sections)\n\t- `comment`, user's notes about the student's content", "styleAttributes": { "textAlign": null, "border": "invisible" }, "x": -620, "y": 2000, "width": 760, "height": 360 } ], "edges": [ { "id": "8e8d7ef0e80c046b", "styleAttributes": {}, "fromNode": "f5acbdab9fb6755c", "fromSide": "bottom", "toNode": "49fefa2c808800a0", "toSide": "top" }, { "id": "92ed4f6045968900", "styleAttributes": {}, "fromNode": "8b73e5aa1b99be1f", "fromSide": "bottom", "toNode": "b037f6b77d5f7127", "toSide": "top" }, { "id": "3b77235037bc5066", "styleAttributes": {}, "fromNode": "b037f6b77d5f7127", "fromSide": "bottom", "toNode": "d130712eb1ba3ff9", "toSide": "top" }, { "id": "5df1d17014d43944", "styleAttributes": {}, "fromNode": "e155f81df7567675", "fromSide": "bottom", "toNode": "cff5136ac15e7282", "toSide": "top" }, { "id": "cbecdaa0e3be1f77", "styleAttributes": {}, "fromNode": "cff5136ac15e7282", "fromSide": "bottom", "toNode": "369b3ccbec406b84", "toSide": "top" }, { "id": "64137ceb549cf906", "styleAttributes": {}, "fromNode": "752136851c08fc83", "fromSide": "left", "toNode": "91f43be181153a2f", "toSide": "top" }, { "id": "42fc6cb48ce69029", "styleAttributes": {}, "fromNode": "7dca5bb0aec7f730", "fromSide": "right", "toNode": "b3e4ecac08c99999", "toSide": "left" }, { "id": "e3b40cdd7188d43d", "styleAttributes": { "path": "short-dashed" }, "fromNode": "d130712eb1ba3ff9", "fromSide": "bottom", "toNode": "ba75ad6041650471", "toSide": "top", "color": "5" }, { "id": "64d329645068a903", "styleAttributes": { "path": "short-dashed" }, "fromNode": "49fefa2c808800a0", "fromSide": "bottom", "toNode": "4a4004f9eb0df102", "toSide": "top", "color": "5" }, { "id": "83a98839dcf7dd27", "styleAttributes": { "path": "short-dashed" }, "fromNode": "4a4004f9eb0df102", "fromSide": "bottom", "toNode": "752136851c08fc83", "toSide": "top", "color": "5", "label": "- % confidence\n- flag" }, { "id": "d3e85094b4185281", "styleAttributes": { "path": "short-dashed" }, "fromNode": "ba75ad6041650471", "fromSide": "bottom", "toNode": "752136851c08fc83", "toSide": "top", "color": "5", "label": "- % confidence\n- flag" }, { "id": "69b329f74e07784e", "styleAttributes": {}, "fromNode": "49fefa2c808800a0", "fromSide": "bottom", "toNode": "fedd34d7c9d8e05a", "toSide": "top" }, { "id": "0f376a018c40ae7d", "styleAttributes": {}, "fromNode": "fedd34d7c9d8e05a", "fromSide": "bottom", "toNode": "752136851c08fc83", "toSide": "top", "color": "4" }, { "id": "0786e62aefcb8984", "styleAttributes": {}, "fromNode": "d130712eb1ba3ff9", "fromSide": "bottom", "toNode": "fedd34d7c9d8e05a", "toSide": "top" }, { "id": "25e364e83394d914", "styleAttributes": {}, "fromNode": "8b73e5aa1b99be1f", "fromSide": "bottom", "toNode": "f5acbdab9fb6755c", "toSide": "top" }, { "id": "b4b319007241ad48", "styleAttributes": { "path": null }, "fromNode": "3f9f56795499e26f", "fromSide": "bottom", "toNode": "54d156c855d043cf", "toSide": "top" }, { "id": "8d03658903c6fb5d", "styleAttributes": { "path": "short-dashed" }, "fromNode": "e155f81df7567675", "fromSide": "right", "toNode": "8babf02556920e0f", "toSide": "bottom", "color": "5" }, { "id": "f22c0f9a55c6e610", "styleAttributes": {}, "fromNode": "b3e4ecac08c99999", "fromSide": "right", "toNode": "f70e12918d4a24f5", "toSide": "left" }, { "id": "3a703beef796d867", "styleAttributes": {}, "fromNode": "f70e12918d4a24f5", "fromSide": "right", "toNode": "ccd335e21a1d13a0", "toSide": "left" }, { "id": "8d0bdc9968d633a0", "styleAttributes": {}, "fromNode": "7d6ebe642a2f40cc", "fromSide": "bottom", "toNode": "8ec144e7b743ff08", "toSide": "top" }, { "id": "b4ced4efc3627232", "styleAttributes": {}, "fromNode": "8ec144e7b743ff08", "fromSide": "bottom", "toNode": "a30b62a70efd5f99", "toSide": "top" }, { "id": "670d7d2200efa9f9", "styleAttributes": {}, "fromNode": "a30b62a70efd5f99", "fromSide": "bottom", "toNode": "c8603366bc48c5a8", "toSide": "top" }, { "id": "347cec7ec906aecd", "styleAttributes": {}, "fromNode": "a30b62a70efd5f99", "fromSide": "bottom", "toNode": "c40385532044360f", "toSide": "top" }, { "id": "5dcc6dc54efb340c", "styleAttributes": {}, "fromNode": "c8603366bc48c5a8", "fromSide": "bottom", "toNode": "1161285c0887cec2", "toSide": "top" }, { "id": "c8dade30befae4d8", "styleAttributes": {}, "fromNode": "c40385532044360f", "fromSide": "bottom", "toNode": "1161285c0887cec2", "toSide": "top" }, { "id": "61997437018005a6", "styleAttributes": {}, "fromNode": "5b84916acc0a0362", "fromSide": "right", "toNode": "c15be9ac1d7a839f", "toSide": "left" }, { "id": "314f2e0927224dc8", "styleAttributes": {}, "fromNode": "d361b6a7e02f5ce8", "fromSide": "bottom", "toNode": "3b8351d46238b500", "toSide": "top" }, { "id": "82d03327d8c56a9a", "styleAttributes": {}, "fromNode": "d361b6a7e02f5ce8", "fromSide": "bottom", "toNode": "d4fffdc078b4aaeb", "toSide": "top" }, { "id": "3184b78bd024f346", "styleAttributes": {}, "fromNode": "3b8351d46238b500", "fromSide": "bottom", "toNode": "2d3d8299d2940c91", "toSide": "top" }, { "id": "db8d91187dbf68f1", "styleAttributes": {}, "fromNode": "2d3d8299d2940c91", "fromSide": "bottom", "toNode": "19540bd3c895f9bc", "toSide": "top" }, { "id": "b8af26de9d987134", "styleAttributes": {}, "fromNode": "2d3d8299d2940c91", "fromSide": "bottom", "toNode": "1a6ef38ff82e7f26", "toSide": "top" }, { "id": "92ef33139ea3ea09", "styleAttributes": {}, "fromNode": "b6f9319ee8e11549", "fromSide": "right", "toNode": "19540bd3c895f9bc", "toSide": "left" }, { "id": "6b0cb3af5e48f939", "styleAttributes": {}, "fromNode": "d361b6a7e02f5ce8", "fromSide": "bottom", "toNode": "e8bb990cf4d5abbe", "toSide": "top" }, { "id": "5af6fd68d1b39be5", "styleAttributes": {}, "fromNode": "426fecaf63cd032e", "fromSide": "top", "toNode": "2d7a0b5a695bb9dd", "toSide": "bottom" }, { "id": "05fe4272caa0510d", "styleAttributes": {}, "fromNode": "d4fffdc078b4aaeb", "fromSide": "bottom", "toNode": "d363ae68077580c2", "toSide": "top" }, { "id": "7a92fa4714516fe9", "styleAttributes": {}, "fromNode": "d363ae68077580c2", "fromSide": "bottom", "toNode": "2d7a0b5a695bb9dd", "toSide": "top" }, { "id": "6180db98bc8ccb5e", "styleAttributes": {}, "fromNode": "d363ae68077580c2", "fromSide": "bottom", "toNode": "af31afa6fefe62b9", "toSide": "top" }, { "id": "6aa557c3b9f74bdb", "styleAttributes": {}, "fromNode": "d361b6a7e02f5ce8", "fromSide": "left", "toNode": "718c00c9f0b2ae02", "toSide": "right" }, { "id": "ca6c404763e9ec3c", "styleAttributes": {}, "fromNode": "d361b6a7e02f5ce8", "fromSide": "right", "toNode": "bf5ee292546142fe", "toSide": "left" }, { "id": "ec0ee9228c7815a9", "styleAttributes": {}, "fromNode": "2d3d8299d2940c91", "fromSide": "right", "toNode": "74e3b31fbf552352", "toSide": "left" }, { "id": "c79ea6ea84bd1c11", "styleAttributes": {}, "fromNode": "d363ae68077580c2", "fromSide": "right", "toNode": "18af4a0953772fca", "toSide": "left" }, { "id": "6a52caa5ca6d9526", "styleAttributes": {}, "fromNode": "1161285c0887cec2", "fromSide": "right", "toNode": "0da48d99a3484f6d", "toSide": "left" }, { "id": "ba00338272affff1", "styleAttributes": {}, "fromNode": "96defc0b2d99568c", "fromSide": "bottom", "toNode": "5b84916acc0a0362", "toSide": "top" }, { "id": "2e5c34d59036e16d", "styleAttributes": {}, "fromNode": "fec21ca7aacbdb86", "fromSide": "bottom", "toNode": "d361b6a7e02f5ce8", "toSide": "top" }, { "id": "758abca1dce0f6fd", "styleAttributes": {}, "fromNode": "c38053aa7c2aad55", "fromSide": "bottom", "toNode": "fec21ca7aacbdb86", "toSide": "top" }, { "id": "6745de2971525d94", "styleAttributes": {}, "fromNode": "c38053aa7c2aad55", "fromSide": "right", "toNode": "7c4588ca6e195422", "toSide": "left" }, { "id": "0a7fa6fd1305d008", "styleAttributes": {}, "fromNode": "c38053aa7c2aad55", "fromSide": "left", "toNode": "bc5754540847ddbf", "toSide": "right" }, { "id": "fd4dfc3bb23055d6", "styleAttributes": {}, "fromNode": "2c91857ebd9d843d", "fromSide": "right", "toNode": "bc5754540847ddbf", "toSide": "left" } ], "metadata": {} }