% corasdiagram package runtime. % - The shipped package version is mirrored from corasdiagram-version.tex. % - The \ProvidesPackage date must match the current CHANGELOG.md release date; % tools/check_release_tag.py enforces that before tagged releases. % - Canonical icon sources live in assets/icons-src/ and generated runtime % assets live in icons/. % - Contributor workflow, release procedure, and local verification commands % are documented in CONTRIBUTING.md at the repository root. \NeedsTeXFormat{LaTeX2e} \def\corasdiagramversion{0.0.0} \InputIfFileExists{corasdiagram-version.tex}{}{} \ProvidesPackage{corasdiagram}[2026/03/28 v\corasdiagramversion CORAS diagram package] \RequirePackage{graphicx} \RequirePackage{array} \RequirePackage{longtable} \RequirePackage{pgfkeys} \RequirePackage{tikz} \RequirePackage{xparse} \usetikzlibrary{arrows.meta,calc,decorations.markings,fit,positioning,shapes.geometric} \pgfdeclarelayer{corasbackground} \pgfsetlayers{corasbackground,main} \makeatletter \def\corasdiagram@iconsdirname{icons} \def\corasdiagram@iconfileprefix{corasdiagram-} \edef\corasdiagram@iconspath{\@currpath\corasdiagram@iconsdirname} \def\corasdiagram@iconsuffix{} \pgfkeys{ /corasdiagram/package/.is family, /corasdiagram/package, iconset/.code={% \def\corasdiagram@optionvalue{#1}% \def\corasdiagram@optioncolor{color}% \def\corasdiagram@optionbw{bw}% \ifx\corasdiagram@optionvalue\corasdiagram@optioncolor \def\corasdiagram@iconsuffix{}% \else\ifx\corasdiagram@optionvalue\corasdiagram@optionbw \def\corasdiagram@iconsuffix{_bw}% \else \PackageError{corasdiagram}{Unknown iconset `#1'}{Use `iconset=color` or `iconset=bw`.}% \fi\fi }, icons-path/.store in=\corasdiagram@iconspath, } \def\corasdiagram@parsepackageoption#1=#2\@nil{% \def\corasdiagram@optionkey{#1}% \def\corasdiagram@optionvalue{#2}% } \DeclareOption*{% \edef\corasdiagram@packageoption{\CurrentOption}% \expandafter\corasdiagram@parsepackageoption\corasdiagram@packageoption\@nil \def\corasdiagram@keyiconset{iconset}% \def\corasdiagram@keyiconspath{icons-path}% \ifx\corasdiagram@optionkey\corasdiagram@keyiconset \def\corasdiagram@optioncolor{color}% \def\corasdiagram@optionbw{bw}% \ifx\corasdiagram@optionvalue\corasdiagram@optioncolor \def\corasdiagram@iconsuffix{}% \else\ifx\corasdiagram@optionvalue\corasdiagram@optionbw \def\corasdiagram@iconsuffix{_bw}% \else \PackageError{corasdiagram}{Unknown iconset `\corasdiagram@optionvalue'}{Use `iconset=color` or `iconset=bw`.}% \fi\fi \else\ifx\corasdiagram@optionkey\corasdiagram@keyiconspath \edef\corasdiagram@iconspath{\corasdiagram@optionvalue}% \else \PackageError{corasdiagram}{Unknown package option `\CurrentOption'}{Supported options are `iconset=` and `icons-path=`.}% \fi\fi } \ProcessOptions\relax \tikzset{ corasdiagram/.style={ font=\sffamily\footnotesize, every node/.style={font=\sffamily\footnotesize,align=center}, >=Latex, min edge gap=8mm }, layout/.code={\def\corasdiagram@layoutmode{#1}}, min edge gap/.code={\def\corasdiagram@layoutmingap{#1}}, coras/asset diagram/.style={}, coras/threat diagram/.style={}, coras/risk diagram/.style={}, coras/treatment diagram/.style={}, coras/treatment overview diagram/.style={}, coras/base node/.style={ draw=none, inner sep=0pt, outer sep=0pt, align=center }, coras/invisible anchor/.style={ draw=none, fill=none, inner sep=0pt, outer sep=0pt }, coras/anchor ellipse/.style={ coras/invisible anchor, ellipse }, coras/anchor rectangle/.style={ coras/invisible anchor, rectangle }, coras/box/.style={ draw, rectangle, fill=white, line width=0.45pt, inner xsep=4pt, inner ysep=3pt, outer sep=1pt, align=center }, coras/ellipse/.style={ draw, ellipse, fill=white, line width=0.45pt, inner xsep=5pt, inner ysep=3pt, outer sep=1pt, align=center }, coras/incident body/.style={ coras/box, minimum height=8mm }, coras/risk body/.style={ coras/box, minimum height=11mm }, coras/treatment body/.style={ coras/ellipse, fill=white, minimum height=9mm }, coras/junction/.style={ circle, draw, fill=white, line width=0.45pt, minimum size=3.3mm, inner sep=0pt, outer sep=1pt }, coras/scope base/.style={ draw, rectangle, fill=black!2, line width=0.45pt, inner sep=7mm, outer sep=0pt }, coras/scope system/.style={coras/scope base}, coras/scope asset-scope/.style={ coras/scope base, fill=white, rounded corners=4mm }, coras/scope analysis/.style={coras/scope base}, coras/scope risk-group/.style={coras/scope base}, coras/scope treatment-scope/.style={coras/scope base}, coras/scope title/.style={ anchor=south west, inner sep=0pt, outer sep=0pt, font=\sffamily\footnotesize\bfseries }, coras/open arrow/.style={ postaction={decorate}, decoration={ markings, mark=at position 1 with { \draw[solid,line width=\pgflinewidth,line cap=round] (0,0) -- (-2.4mm,0.95mm); \draw[solid,line width=\pgflinewidth,line cap=round] (0,0) -- (-2.4mm,-0.95mm); } } }, coras/risk ref box/.style={ coras/box, minimum height=5mm, inner xsep=2.5pt, inner ysep=1.2pt, font=\sffamily\scriptsize }, coras/causal/.style={ draw, line width=0.45pt, coras/open arrow }, coras/relation/.style={ draw, line width=0.45pt, coras/open arrow }, coras/concern/.style={ draw, dashed, line width=0.45pt, coras/open arrow }, coras/association/.style={ draw, dashed, line width=0.45pt, coras/open arrow }, coras/treatment/.style={ draw, dashed, line width=0.45pt, coras/open arrow }, coras/overview/.style={ coras/treatment }, coras/asset anchor/.style={ coras/invisible anchor, shape=corasassetanchorshape }, coras/indirect asset anchor/.style={ coras/invisible anchor, shape=corasindirectassetanchorshape }, coras/stakeholder anchor/.style={ coras/invisible anchor, shape=corasstakeholderanchorshape }, coras/threat accidental anchor/.style={ coras/invisible anchor, shape=corasthreataccidentalanchorshape }, coras/threat deliberate anchor/.style={ coras/invisible anchor, shape=corasthreatdeliberateanchorshape }, coras/threat nonhuman anchor/.style={ coras/invisible anchor, shape=corasthreatnonhumananchorshape }, coras/vulnerability anchor/.style={ coras/invisible anchor, shape=corasvulnerabilityanchorshape }, } \newcommand{\corasdiagram@setsymbolmetric}[3]{% \expandafter\def\csname corasdiagram@anchordata@#1@#2\endcsname{#3}% } \newcommand{\corasdiagram@setsymbolanchor}[4]{% \expandafter\def\csname corasdiagram@anchordata@#1@#2x\endcsname{#3}% \expandafter\def\csname corasdiagram@anchordata@#1@#2y\endcsname{#4}% } \newcommand{\corasdiagram@setsymboloutline}[2]{% \expandafter\def\csname corasdiagram@anchordata@#1@outline\endcsname{#2}% } \newcommand{\corasdiagram@getsymbolmetric}[3]{% \expandafter\ifcsname corasdiagram@anchordata@#1@#2\endcsname \edef#3{\csname corasdiagram@anchordata@#1@#2\endcsname}% \else \let#3\@empty \fi } \newcommand{\corasdiagram@setsymbolpoint}[2]{% \expandafter\ifcsname corasdiagram@anchordata@#1@#2x\endcsname \pgf@x=\dimexpr\csname corasdiagram@anchordata@#1@#2x\endcsname\relax \pgf@y=\dimexpr\csname corasdiagram@anchordata@#1@#2y\endcsname\relax \else \pgf@x=0pt\relax \pgf@y=0pt\relax \fi } \newcommand{\corasdiagram@symbolpoint}[2]{% \pgfqpoint{% \csname corasdiagram@anchordata@#1@#2x\endcsname }{% \csname corasdiagram@anchordata@#1@#2y\endcsname }% } \newcommand{\corasdiagram@symbolbodycenter}[1]{% \pgf@x=0pt\relax \pgf@y=0pt\relax } \newcommand{\corasdiagram@symboltextanchor}[1]{% \pgf@x=0pt\relax \pgf@y=0pt\relax } \newcommand{\corasdiagram@symbolbaseanchor}[1]{% \pgf@x=0pt\relax \pgf@y=\dimexpr\csname corasdiagram@anchordata@#1@basey\endcsname\relax } \newcommand{\corasdiagram@symbolmidanchor}[1]{% \pgf@x=0pt\relax \pgf@y=\dimexpr\csname corasdiagram@anchordata@#1@midy\endcsname\relax } \newcommand{\corasdiagram@symbolbaseeastanchor}[1]{% \pgf@x=\dimexpr\csname corasdiagram@anchordata@#1@bodyhalfx\endcsname\relax \pgf@y=\dimexpr\csname corasdiagram@anchordata@#1@basey\endcsname\relax } \newcommand{\corasdiagram@symbolbasewestanchor}[1]{% \pgf@x=-\dimexpr\csname corasdiagram@anchordata@#1@bodyhalfx\endcsname\relax \pgf@y=\dimexpr\csname corasdiagram@anchordata@#1@basey\endcsname\relax } \newcommand{\corasdiagram@symbolmideastanchor}[1]{% \pgf@x=\dimexpr\csname corasdiagram@anchordata@#1@bodyhalfx\endcsname\relax \pgf@y=\dimexpr\csname corasdiagram@anchordata@#1@midy\endcsname\relax } \newcommand{\corasdiagram@symbolmidwestanchor}[1]{% \pgf@x=-\dimexpr\csname corasdiagram@anchordata@#1@bodyhalfx\endcsname\relax \pgf@y=\dimexpr\csname corasdiagram@anchordata@#1@midy\endcsname\relax } \newcommand{\corasdiagram@symboloutlinepath}[1]{% \pgfpathmoveto{\corasdiagram@symbolpoint{#1}{north}}% \pgfpathlineto{\corasdiagram@symbolpoint{#1}{northeast}}% \pgfpathlineto{\corasdiagram@symbolpoint{#1}{east}}% \pgfpathlineto{\corasdiagram@symbolpoint{#1}{southeast}}% \pgfpathlineto{\corasdiagram@symbolpoint{#1}{south}}% \pgfpathlineto{\corasdiagram@symbolpoint{#1}{southwest}}% \pgfpathlineto{\corasdiagram@symbolpoint{#1}{west}}% \pgfpathlineto{\corasdiagram@symbolpoint{#1}{northwest}}% \pgfpathclose% } \newcommand{\corasdiagram@symbolborderintersection}[1]{% \pgf@xa=\pgf@x% \pgf@ya=\pgf@y% \pgfmathsetmacro{\corasdiagram@dx}{\the\pgf@xa}% \pgfmathsetmacro{\corasdiagram@dy}{\the\pgf@ya}% \corasdiagram@setsnappeddirectionalanchor \expandafter\corasdiagram@setsymbolpoint\expandafter{#1}{\corasdiagram@snappeddirectionalanchor}% } \newcommand{\corasdiagram@declareiconsymbolshape}[2]{% \pgfdeclareshape{#1}{% \savedanchor\centerpoint{\corasdiagram@symbolbodycenter{#2}}% \anchor{center}{\corasdiagram@symbolbodycenter{#2}}% \anchor{text}{\corasdiagram@symboltextanchor{#2}}% \anchor{base}{\corasdiagram@symbolbaseanchor{#2}}% \anchor{mid}{\corasdiagram@symbolmidanchor{#2}}% \anchor{base east}{\corasdiagram@symbolbaseeastanchor{#2}}% \anchor{base west}{\corasdiagram@symbolbasewestanchor{#2}}% \anchor{mid east}{\corasdiagram@symbolmideastanchor{#2}}% \anchor{mid west}{\corasdiagram@symbolmidwestanchor{#2}}% \anchor{north}{\corasdiagram@setsymbolpoint{#2}{north}}% \anchor{north east}{\corasdiagram@setsymbolpoint{#2}{northeast}}% \anchor{east}{\corasdiagram@setsymbolpoint{#2}{east}}% \anchor{south east}{\corasdiagram@setsymbolpoint{#2}{southeast}}% \anchor{south}{\corasdiagram@setsymbolpoint{#2}{south}}% \anchor{south west}{\corasdiagram@setsymbolpoint{#2}{southwest}}% \anchor{west}{\corasdiagram@setsymbolpoint{#2}{west}}% \anchor{north west}{\corasdiagram@setsymbolpoint{#2}{northwest}}% \anchorborder{\corasdiagram@symbolborderintersection{#2}}% \backgroundpath{\corasdiagram@symboloutlinepath{#2}}% }% } \newcommand{\corasdiagram@defineanchors@stakeholder}{% \corasdiagram@setsymbolmetric{stakeholder}{bodyhalfx}{1.9mm}% \corasdiagram@setsymbolmetric{stakeholder}{bodyhalfy}{4.4mm}% \corasdiagram@setsymbolmetric{stakeholder}{basey}{-3.7mm}% \corasdiagram@setsymbolmetric{stakeholder}{midy}{0.5mm}% \corasdiagram@setsymbolanchor{stakeholder}{north}{0.1mm}{7.6mm}% \corasdiagram@setsymbolanchor{stakeholder}{northeast}{3.25mm}{4.35mm}% \corasdiagram@setsymbolanchor{stakeholder}{east}{3.8mm}{0.1mm}% \corasdiagram@setsymbolanchor{stakeholder}{southeast}{3.15mm}{-4.85mm}% \corasdiagram@setsymbolanchor{stakeholder}{south}{-0.1mm}{-7.8mm}% \corasdiagram@setsymbolanchor{stakeholder}{southwest}{-1.75mm}{-4.8mm}% \corasdiagram@setsymbolanchor{stakeholder}{west}{-3.8mm}{-0.05mm}% \corasdiagram@setsymbolanchor{stakeholder}{northwest}{-2.95mm}{4.2mm}% \corasdiagram@setsymboloutline{stakeholder}{north,northeast,east,southeast,south,southwest,west,northwest}% } \newcommand{\corasdiagram@defineanchors@asset}{% \corasdiagram@setsymbolmetric{asset}{bodyhalfx}{4.15mm}% \corasdiagram@setsymbolmetric{asset}{bodyhalfy}{4.85mm}% \corasdiagram@setsymbolmetric{asset}{basey}{-3.9mm}% \corasdiagram@setsymbolmetric{asset}{midy}{0.35mm}% \corasdiagram@setsymbolanchor{asset}{north}{0mm}{5.9mm}% \corasdiagram@setsymbolanchor{asset}{northeast}{3.15mm}{1.15mm}% \corasdiagram@setsymbolanchor{asset}{east}{5.25mm}{-1.45mm}% \corasdiagram@setsymbolanchor{asset}{southeast}{3.9mm}{-4.05mm}% \corasdiagram@setsymbolanchor{asset}{south}{0mm}{-5.8mm}% \corasdiagram@setsymbolanchor{asset}{southwest}{-4.45mm}{-3.75mm}% \corasdiagram@setsymbolanchor{asset}{west}{-4.8mm}{-1.25mm}% \corasdiagram@setsymbolanchor{asset}{northwest}{-2.3mm}{1.25mm}% \corasdiagram@setsymboloutline{asset}{north,northeast,east,southeast,south,southwest,west,northwest}% } \newcommand{\corasdiagram@defineanchors@indirectasset}{% \corasdiagram@setsymbolmetric{indirectasset}{bodyhalfx}{4.15mm}% \corasdiagram@setsymbolmetric{indirectasset}{bodyhalfy}{4.85mm}% \corasdiagram@setsymbolmetric{indirectasset}{basey}{-3.9mm}% \corasdiagram@setsymbolmetric{indirectasset}{midy}{0.35mm}% \corasdiagram@setsymbolanchor{indirectasset}{north}{0mm}{5.9mm}% \corasdiagram@setsymbolanchor{indirectasset}{northeast}{3.15mm}{1.15mm}% \corasdiagram@setsymbolanchor{indirectasset}{east}{5.25mm}{-1.45mm}% \corasdiagram@setsymbolanchor{indirectasset}{southeast}{3.9mm}{-4.05mm}% \corasdiagram@setsymbolanchor{indirectasset}{south}{0mm}{-5.8mm}% \corasdiagram@setsymbolanchor{indirectasset}{southwest}{-4.45mm}{-3.75mm}% \corasdiagram@setsymbolanchor{indirectasset}{west}{-4.8mm}{-1.25mm}% \corasdiagram@setsymbolanchor{indirectasset}{northwest}{-2.3mm}{1.25mm}% \corasdiagram@setsymboloutline{indirectasset}{north,northeast,east,southeast,south,southwest,west,northwest}% } \newcommand{\corasdiagram@defineanchors@threataccidental}{% \corasdiagram@setsymbolmetric{threataccidental}{bodyhalfx}{2.8mm}% \corasdiagram@setsymbolmetric{threataccidental}{bodyhalfy}{5.4mm}% \corasdiagram@setsymbolmetric{threataccidental}{basey}{-4.4mm}% \corasdiagram@setsymbolmetric{threataccidental}{midy}{0.5mm}% \corasdiagram@setsymbolanchor{threataccidental}{north}{-1.75mm}{6.6mm}% \corasdiagram@setsymbolanchor{threataccidental}{northeast}{2.05mm}{4.1mm}% \corasdiagram@setsymbolanchor{threataccidental}{east}{4.6mm}{0.35mm}% \corasdiagram@setsymbolanchor{threataccidental}{southeast}{0.1mm}{-3.4mm}% \corasdiagram@setsymbolanchor{threataccidental}{south}{-1.65mm}{-6.9mm}% \corasdiagram@setsymbolanchor{threataccidental}{southwest}{-3.6mm}{-3.5mm}% \corasdiagram@setsymbolanchor{threataccidental}{west}{-4.45mm}{0.15mm}% \corasdiagram@setsymbolanchor{threataccidental}{northwest}{-4.25mm}{3.8mm}% \corasdiagram@setsymboloutline{threataccidental}{north,northeast,east,southeast,south,southwest,west,northwest}% } \newcommand{\corasdiagram@defineanchors@threatdeliberate}{% \corasdiagram@setsymbolmetric{threatdeliberate}{bodyhalfx}{3.0mm}% \corasdiagram@setsymbolmetric{threatdeliberate}{bodyhalfy}{5.7mm}% \corasdiagram@setsymbolmetric{threatdeliberate}{basey}{-4.6mm}% \corasdiagram@setsymbolmetric{threatdeliberate}{midy}{0.6mm}% \corasdiagram@setsymbolanchor{threatdeliberate}{north}{-1.65mm}{6.85mm}% \corasdiagram@setsymbolanchor{threatdeliberate}{northeast}{1.1mm}{5mm}% \corasdiagram@setsymbolanchor{threatdeliberate}{east}{5mm}{-0.25mm}% \corasdiagram@setsymbolanchor{threatdeliberate}{southeast}{0.45mm}{-5.05mm}% \corasdiagram@setsymbolanchor{threatdeliberate}{south}{-1.75mm}{-7.35mm}% \corasdiagram@setsymbolanchor{threatdeliberate}{southwest}{-3.8mm}{-3.95mm}% \corasdiagram@setsymbolanchor{threatdeliberate}{west}{-5mm}{0.1mm}% \corasdiagram@setsymbolanchor{threatdeliberate}{northwest}{-4.05mm}{5.25mm}% \corasdiagram@setsymboloutline{threatdeliberate}{north,northeast,east,southeast,south,southwest,west,northwest}% } \newcommand{\corasdiagram@defineanchors@threatnonhuman}{% \corasdiagram@setsymbolmetric{threatnonhuman}{bodyhalfx}{4.1mm}% \corasdiagram@setsymbolmetric{threatnonhuman}{bodyhalfy}{4.3mm}% \corasdiagram@setsymbolmetric{threatnonhuman}{basey}{-3.1mm}% \corasdiagram@setsymbolmetric{threatnonhuman}{midy}{0.4mm}% \corasdiagram@setsymbolanchor{threatnonhuman}{north}{0mm}{4.7mm}% \corasdiagram@setsymbolanchor{threatnonhuman}{northeast}{5.65mm}{6.7mm}% \corasdiagram@setsymbolanchor{threatnonhuman}{east}{6.2mm}{0.05mm}% \corasdiagram@setsymbolanchor{threatnonhuman}{southeast}{6.2mm}{-6.05mm}% \corasdiagram@setsymbolanchor{threatnonhuman}{south}{-0.1mm}{-4.45mm}% \corasdiagram@setsymbolanchor{threatnonhuman}{southwest}{-6.3mm}{-3.55mm}% \corasdiagram@setsymbolanchor{threatnonhuman}{west}{-6.3mm}{0.05mm}% \corasdiagram@setsymbolanchor{threatnonhuman}{northwest}{-6.3mm}{4.95mm}% \corasdiagram@setsymboloutline{threatnonhuman}{north,northeast,east,southeast,south,southwest,west,northwest}% } \newcommand{\corasdiagram@defineanchors@vulnerability}{% \corasdiagram@setsymbolmetric{vulnerability}{bodyhalfx}{2.4mm}% \corasdiagram@setsymbolmetric{vulnerability}{bodyhalfy}{4.1mm}% \corasdiagram@setsymbolmetric{vulnerability}{basey}{-3.1mm}% \corasdiagram@setsymbolmetric{vulnerability}{midy}{0.4mm}% \corasdiagram@setsymbolanchor{vulnerability}{north}{-0.35mm}{5.2mm}% \corasdiagram@setsymbolanchor{vulnerability}{northeast}{2.3mm}{3.15mm}% \corasdiagram@setsymbolanchor{vulnerability}{east}{3.7mm}{-0.15mm}% \corasdiagram@setsymbolanchor{vulnerability}{southeast}{3.4mm}{-2.55mm}% \corasdiagram@setsymbolanchor{vulnerability}{south}{0mm}{-5.25mm}% \corasdiagram@setsymbolanchor{vulnerability}{southwest}{-3.4mm}{-3.1mm}% \corasdiagram@setsymbolanchor{vulnerability}{west}{-3.25mm}{-0.15mm}% \corasdiagram@setsymbolanchor{vulnerability}{northwest}{-3.25mm}{3.8mm}% \corasdiagram@setsymboloutline{vulnerability}{north,northeast,east,southeast,south,southwest,west,northwest}% } \corasdiagram@defineanchors@asset \corasdiagram@defineanchors@indirectasset \corasdiagram@defineanchors@stakeholder \corasdiagram@defineanchors@threataccidental \corasdiagram@defineanchors@threatdeliberate \corasdiagram@defineanchors@threatnonhuman \corasdiagram@defineanchors@vulnerability \corasdiagram@declareiconsymbolshape{corasassetanchorshape}{asset} \corasdiagram@declareiconsymbolshape{corasindirectassetanchorshape}{indirectasset} \corasdiagram@declareiconsymbolshape{corasstakeholderanchorshape}{stakeholder} \corasdiagram@declareiconsymbolshape{corasthreataccidentalanchorshape}{threataccidental} \corasdiagram@declareiconsymbolshape{corasthreatdeliberateanchorshape}{threatdeliberate} \corasdiagram@declareiconsymbolshape{corasthreatnonhumananchorshape}{threatnonhuman} \corasdiagram@declareiconsymbolshape{corasvulnerabilityanchorshape}{vulnerability} \newcount\corasdiagram@autonode \newcount\corasdiagram@diagramseq \newcount\corasdiagram@edgecoordseq \newcount\corasdiagram@placedcount \newcount\corasdiagram@placedindex \newdimen\corasdiagram@tmpdimen \newdimen\corasdiagram@compartmentwidth \newdimen\corasdiagram@compartmentheight \newdimen\corasdiagram@compartmentside \newdimen\corasdiagram@halfcompartmentside \newdimen\corasdiagram@scopewidth \newdimen\corasdiagram@scopeheight \newdimen\corasdiagram@finalscopewidth \newdimen\corasdiagram@finalscopeheight \newdimen\corasdiagram@labelwidth \newdimen\corasdiagram@labelheight \newdimen\corasdiagram@estimatedwidth \newdimen\corasdiagram@estimatedheight \newdimen\corasdiagram@currentx \newdimen\corasdiagram@currenty \newdimen\corasdiagram@previousx \newdimen\corasdiagram@previousy \newdimen\corasdiagram@currenthalfwidth \newdimen\corasdiagram@currenthalfheight \newdimen\corasdiagram@previoushalfwidth \newdimen\corasdiagram@previoushalfheight \newdimen\corasdiagram@overlapx \newdimen\corasdiagram@requiredy \newdimen\corasdiagram@overlapmarginx \newdimen\corasdiagram@overlapmarginy \newdimen\corasdiagram@minimumedgegap \newdimen\corasdiagram@minimumedgegapslack \newdimen\corasdiagram@requestedgap \newdimen\corasdiagram@neighborcenterdimen \newdimen\corasdiagram@neighborhalfdimen \def\corasdiagram@knownroles{stakeholder,asset,threatsource,vulnerability,scenario,incident,risk,treatment,junction,scope} \def\corasdiagram@currentfamily{} \def\corasdiagram@layoutmode{auto} \def\corasdiagram@layoutmingap{8mm} \def\corasdiagram@currentdiagramid{} \corasdiagram@minimumedgegapslack=0.6mm\relax \newcommand{\corasdiagram@ensurename}[1]{% \ifx#1\@empty \global\advance\corasdiagram@autonode by 1\relax \edef#1{coras-auto-\the\corasdiagram@autonode}% \fi } \newcommand{\corasdiagram@setdefault}[2]{% \ifx#1\@empty \def#1{#2}% \fi } \newcommand{\corasdiagram@normalize}[1]{% \edef#1{#1}% } \newcommand{\corasdiagram@iconfile}[1]{% \corasdiagram@iconspath/\corasdiagram@iconfileprefix#1\corasdiagram@iconsuffix.pdf% } \newcommand{\corasdiagram@resolveiconperspectivesuffix}[1]{% \def\corasdiagram@resolvedperspectivesuffix{}% \def\corasdiagram@perspectivebefore{before}% \def\corasdiagram@perspectivebeforeafter{before-after}% \def\corasdiagram@perspectiveafter{after}% \ifx#1\@empty \else\ifx#1\corasdiagram@perspectivebefore \else\ifx#1\corasdiagram@perspectivebeforeafter \def\corasdiagram@resolvedperspectivesuffix{_outlined}% \else\ifx#1\corasdiagram@perspectiveafter \def\corasdiagram@resolvedperspectivesuffix{_shaded}% \else \PackageError{corasdiagram}{Unknown perspective `#1'}{% Use `perspective=before`, `perspective=before-after`, or `perspective=after`.% }% \fi\fi\fi\fi } \newcommand{\corasdiagram@resolveiconstem}[3]{% \corasdiagram@resolveiconperspectivesuffix{#2}% \edef#3{#1\corasdiagram@resolvedperspectivesuffix}% } \newcommand{\corasdiagram@includeicon}[2]{% \includegraphics[width=#1]{\corasdiagram@iconfile{#2}}% } \newcommand{\corasdiagram@highlevelcauseicons}{% \begin{tikzpicture}[baseline=(current bounding box.center),x=1mm,y=1mm,scale=\corashlatable@iconscale,transform shape] \node[inner sep=0pt,outer sep=0pt] (deliberate) at (0,0) {\corasdiagram@includeicon{7.4mm}{threat-human-deliberate}}; \node[inner sep=0pt,outer sep=0pt] (accidental) at (10.5,0) {\corasdiagram@includeicon{7.4mm}{threat-human-accidental}}; \node[inner sep=0pt,outer sep=0pt] (nonhuman) at (23.5,0) {\corasdiagram@includeicon{10.8mm}{threat-non-human}}; \end{tikzpicture}% } \newcommand{\corasdiagram@highleveleventicons}{% \begin{tikzpicture}[baseline=(current bounding box.center),x=1mm,y=1mm,scale=\corashlatable@iconscale,transform shape] \node[coras/ellipse,minimum width=19mm,minimum height=8.5mm,inner sep=0pt] (scenario) at (0,0) {}; \node[coras/base node,anchor=center] at (scenario.north) {\corasdiagram@includeicon{5.1mm}{risk}}; \node[coras/incident body,minimum width=18.5mm,minimum height=8.5mm,inner sep=0pt] (incident) at (26,0) {}; \node[coras/base node,anchor=center] at ([xshift=-1.5mm]incident.north east) {\corasdiagram@includeicon{5.1mm}{unwanted-incident}}; \node[coras/base node,inner sep=0pt,outer sep=0pt] at (48,0) {\corasdiagram@includeicon{8.2mm}{asset}}; \end{tikzpicture}% } \newcommand{\corasdiagram@highlevelpossibilityicons}{% \begin{tikzpicture}[baseline=(current bounding box.center),scale=\corashlatable@iconscale,transform shape] \node[coras/base node,inner sep=0pt,outer sep=0pt] {\corasdiagram@includeicon{8.0mm}{vulnerability}}; \end{tikzpicture}% } \newcommand{\corasdiagram@ifincsv}[4]{% \edef\corasdiagram@membertest{#1}% \def\corasdiagram@ismember{0}% \@for\corasdiagram@candidate:=#2\do{% \edef\corasdiagram@candidatevalue{\corasdiagram@candidate}% \ifx\corasdiagram@candidatevalue\corasdiagram@membertest \def\corasdiagram@ismember{1}% \fi }% \ifnum\corasdiagram@ismember=1\relax #3% \else #4% \fi } \newcommand{\corasdiagram@setnodeprop}[3]{% \expandafter\edef\csname corasdiagram@node@#1@#2\endcsname{#3}% } \newcommand{\corasdiagram@getnodeprop}[3]{% \expandafter\ifcsname corasdiagram@node@#1@#2\endcsname \edef#3{\csname corasdiagram@node@#1@#2\endcsname}% \else \let#3\@empty \fi } \newcommand{\corasdiagram@getbordernode}[2]{% \corasdiagram@getnodeprop{bordernode}{#2}{#1}% \ifx#1\@empty \expandafter\ifcsname pgf@sh@ns@#2-anchor\endcsname \edef#1{#2-anchor}% \else \expandafter\ifcsname pgf@sh@ns@#2\endcsname \edef#1{#2}% \fi \fi \fi } \newcommand{\corasdiagram@getanchorlegendcoord}[5]{% \corasdiagram@getnodeprop{anchorsymbol}{#1}{\corasdiagram@anchorsymbol}% \ifx\corasdiagram@anchorsymbol\@empty \corasdiagram@getbordernode{\corasdiagram@legendbordernode}{#1}% \pgfextractx{\corasdiagram@tmpdimen}{% \pgfpointdiff{\pgfpointanchor{\corasdiagram@legendbordernode}{center}}% {\pgfpointanchor{\corasdiagram@legendbordernode}{#3}}% }% \edef#4{\the\corasdiagram@tmpdimen}% \pgfextracty{\corasdiagram@tmpdimen}{% \pgfpointdiff{\pgfpointanchor{\corasdiagram@legendbordernode}{center}}% {\pgfpointanchor{\corasdiagram@legendbordernode}{#3}}% }% \edef#5{\the\corasdiagram@tmpdimen}% \else \def\corasdiagram@legendid{#2}% \def\corasdiagram@legendcenter{center}% \def\corasdiagram@legendtext{text}% \def\corasdiagram@legendbase{base}% \def\corasdiagram@legendmid{mid}% \def\corasdiagram@legendbaseeast{baseeast}% \def\corasdiagram@legendbasewest{basewest}% \def\corasdiagram@legendmideast{mideast}% \def\corasdiagram@legendmidwest{midwest}% \ifx\corasdiagram@legendid\corasdiagram@legendcenter \edef#4{0pt}% \edef#5{0pt}% \else\ifx\corasdiagram@legendid\corasdiagram@legendtext \edef#4{0pt}% \edef#5{0pt}% \else\ifx\corasdiagram@legendid\corasdiagram@legendbase \edef#4{0pt}% \edef#5{\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @basey\endcsname}% \else\ifx\corasdiagram@legendid\corasdiagram@legendmid \edef#4{0pt}% \edef#5{\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @midy\endcsname}% \else\ifx\corasdiagram@legendid\corasdiagram@legendbaseeast \edef#4{\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @bodyhalfx\endcsname}% \edef#5{\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @basey\endcsname}% \else\ifx\corasdiagram@legendid\corasdiagram@legendbasewest \edef#4{-\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @bodyhalfx\endcsname}% \edef#5{\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @basey\endcsname}% \else\ifx\corasdiagram@legendid\corasdiagram@legendmideast \edef#4{\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @bodyhalfx\endcsname}% \edef#5{\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @midy\endcsname}% \else\ifx\corasdiagram@legendid\corasdiagram@legendmidwest \edef#4{-\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @bodyhalfx\endcsname}% \edef#5{\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @midy\endcsname}% \else \edef#4{\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @#2x\endcsname}% \edef#5{\csname corasdiagram@anchordata@\corasdiagram@anchorsymbol @#2y\endcsname}% \fi\fi\fi\fi\fi\fi\fi\fi \fi } \newcommand{\corasdiagram@setscopefit}[2]{% \expandafter\edef\csname corasdiagram@scopefit@#1\endcsname{#2}% } \newcommand{\corasdiagram@setroleordernode}[3]{% \expandafter\xdef\csname corasdiagram@roleindex@\corasdiagram@currentdiagramid @#1@#2\endcsname{#3}% } \newcommand{\corasdiagram@getroleordernode}[3]{% \expandafter\ifcsname corasdiagram@roleindex@\corasdiagram@currentdiagramid @#2@#3\endcsname \edef#1{\csname corasdiagram@roleindex@\corasdiagram@currentdiagramid @#2@#3\endcsname}% \else \let#1\@empty \fi } \newcommand{\corasdiagram@getscopefit}[2]{% \expandafter\ifcsname corasdiagram@scopefit@#2\endcsname \edef#1{\csname corasdiagram@scopefit@#2\endcsname}% \else \let#1\@empty \fi } \newcommand{\corasdiagram@scopekey}[1]{% \corasdiagram@currentdiagramid::#1% } \newcommand{\corasdiagram@registerscopemember}[2]{% \ifx#1\@empty \else \edef\corasdiagram@scopenodename{#2}% \edef\corasdiagram@currscopekey{\corasdiagram@scopekey{#1}}% \corasdiagram@getscopefit{\corasdiagram@scopefitlist}{\corasdiagram@currscopekey}% \ifx\corasdiagram@scopefitlist\@empty \corasdiagram@setscopefit{\corasdiagram@currscopekey}{(\corasdiagram@scopenodename)}% \else \expandafter\edef\csname corasdiagram@scopefit@\corasdiagram@currscopekey\endcsname{% \corasdiagram@scopefitlist\space (\corasdiagram@scopenodename)% }% \fi \fi } \expandafter\def\csname corasdiagram@allowednodes@asset\endcsname{stakeholder,asset,scope} \expandafter\def\csname corasdiagram@allowednodes@threat\endcsname{threatsource,vulnerability,scenario,incident,asset} \expandafter\def\csname corasdiagram@allowednodes@risk\endcsname{threatsource,risk,asset} \expandafter\def\csname corasdiagram@allowednodes@treatment\endcsname{treatment,threatsource,vulnerability,scenario,incident,asset} \expandafter\def\csname corasdiagram@allowednodes@treatmentoverview\endcsname{treatment,risk,asset,junction} \newcommand{\corasdiagram@getallowedroles}[1]{% \expandafter\ifcsname corasdiagram@allowednodes@#1\endcsname \edef\corasdiagram@allowedroles{\csname corasdiagram@allowednodes@#1\endcsname}% \else \let\corasdiagram@allowedroles\@empty \fi } \newcommand{\corasdiagram@familynamelabel}[1]{% \ifcsname corasdiagram@familylabel@#1\endcsname \csname corasdiagram@familylabel@#1\endcsname \else #1% \fi } \expandafter\def\csname corasdiagram@familylabel@asset\endcsname{asset diagram} \expandafter\def\csname corasdiagram@familylabel@threat\endcsname{threat diagram} \expandafter\def\csname corasdiagram@familylabel@risk\endcsname{risk diagram} \expandafter\def\csname corasdiagram@familylabel@treatment\endcsname{treatment diagram} \expandafter\def\csname corasdiagram@familylabel@treatmentoverview\endcsname{treatment overview diagram} \newcommand{\corasdiagram@rolelabel}[1]{% \ifcsname corasdiagram@rolelabel@#1\endcsname \csname corasdiagram@rolelabel@#1\endcsname \else #1% \fi } \expandafter\def\csname corasdiagram@rolelabel@stakeholder\endcsname{stakeholder} \expandafter\def\csname corasdiagram@rolelabel@asset\endcsname{asset} \expandafter\def\csname corasdiagram@rolelabel@threatsource\endcsname{threat source} \expandafter\def\csname corasdiagram@rolelabel@vulnerability\endcsname{vulnerability} \expandafter\def\csname corasdiagram@rolelabel@scenario\endcsname{threat scenario} \expandafter\def\csname corasdiagram@rolelabel@incident\endcsname{unwanted incident} \expandafter\def\csname corasdiagram@rolelabel@risk\endcsname{risk} \expandafter\def\csname corasdiagram@rolelabel@treatment\endcsname{treatment} \expandafter\def\csname corasdiagram@rolelabel@junction\endcsname{junction} \expandafter\def\csname corasdiagram@rolelabel@scope\endcsname{scope} \newcommand{\corasdiagram@semanticlabel}[1]{% \ifcsname corasdiagram@semanticlabel@#1\endcsname \csname corasdiagram@semanticlabel@#1\endcsname \else #1% \fi } \expandafter\def\csname corasdiagram@semanticlabel@causal\endcsname{causal} \expandafter\def\csname corasdiagram@semanticlabel@relation\endcsname{relation} \expandafter\def\csname corasdiagram@semanticlabel@concern\endcsname{concern} \expandafter\def\csname corasdiagram@semanticlabel@association\endcsname{association} \expandafter\def\csname corasdiagram@semanticlabel@treatment\endcsname{treatment} \newcommand{\corasdiagram@maptyperole}[1]{% \def\corasdiagram@mappedrole{#1}% \def\corasdiagram@typeindirectasset{indirectasset}% \ifx#1\corasdiagram@typeindirectasset \def\corasdiagram@mappedrole{asset}% \fi \corasdiagram@ifincsv{#1}{threataccidental,threatdeliberate,threatnonhuman}{% \def\corasdiagram@mappedrole{threatsource}% }{}% } \newcommand{\corasdiagram@validatecurrentrole}[2]{% \ifx\corasdiagram@currentfamily\@empty \else \corasdiagram@getallowedroles{\corasdiagram@currentfamily}% \corasdiagram@ifincsv{#2}{\corasdiagram@allowedroles}{}{% \PackageError{corasdiagram}{Node type `#1' is not allowed in the \corasdiagram@familynamelabel{\corasdiagram@currentfamily}}{% Allowed roles here are \corasdiagram@allowedroles.% }% }% \fi } \newcommand{\corasdiagram@validateedgepair}[4]{% \def\corasdiagram@edgepairvalid{0}% \def\corasdiagram@fromrole{#3}% \def\corasdiagram@torole{#4}% \expandafter\ifx\csname corasdiagram@edgecheck@#1@#2\endcsname\relax \else \csname corasdiagram@edgecheck@#1@#2\endcsname \fi } \def\corasdiagram@markedgevalid{\def\corasdiagram@edgepairvalid{1}} \expandafter\def\csname corasdiagram@edgecheck@asset@relation\endcsname{% \corasdiagram@ifincsv{\corasdiagram@fromrole}{asset}% {\corasdiagram@ifincsv{\corasdiagram@torole}{asset}{\corasdiagram@markedgevalid}{}}{}% } \expandafter\def\csname corasdiagram@edgecheck@asset@concern\endcsname{% \corasdiagram@ifincsv{\corasdiagram@fromrole}{stakeholder}% {\corasdiagram@ifincsv{\corasdiagram@torole}{asset}{\corasdiagram@markedgevalid}{}}{}% } \expandafter\def\csname corasdiagram@edgecheck@threat@causal\endcsname{% \corasdiagram@ifincsv{\corasdiagram@fromrole}{threatsource,vulnerability,scenario}% {\corasdiagram@ifincsv{\corasdiagram@torole}{vulnerability,scenario,incident}{\corasdiagram@markedgevalid}{}}{}% } \expandafter\def\csname corasdiagram@edgecheck@threat@relation\endcsname{% \corasdiagram@ifincsv{\corasdiagram@fromrole}{incident}% {\corasdiagram@ifincsv{\corasdiagram@torole}{asset}{\corasdiagram@markedgevalid}{}}{}% } \expandafter\def\csname corasdiagram@edgecheck@threat@association\endcsname{% \corasdiagram@ifincsv{\corasdiagram@fromrole}{scenario,incident}% {\corasdiagram@ifincsv{\corasdiagram@torole}{asset,incident,scenario}{\corasdiagram@markedgevalid}{}}{}% } \expandafter\def\csname corasdiagram@edgecheck@risk@causal\endcsname{% \corasdiagram@ifincsv{\corasdiagram@fromrole}{threatsource}% {\corasdiagram@ifincsv{\corasdiagram@torole}{risk}{\corasdiagram@markedgevalid}{}}{}% } \expandafter\def\csname corasdiagram@edgecheck@risk@relation\endcsname{% \corasdiagram@ifincsv{\corasdiagram@fromrole}{risk}% {\corasdiagram@ifincsv{\corasdiagram@torole}{asset}{\corasdiagram@markedgevalid}{}}{}% } \expandafter\def\csname corasdiagram@edgecheck@treatment@causal\endcsname{% \corasdiagram@ifincsv{\corasdiagram@fromrole}{threatsource,vulnerability,scenario}% {\corasdiagram@ifincsv{\corasdiagram@torole}{vulnerability,scenario,incident}{\corasdiagram@markedgevalid}{}}{}% } \expandafter\def\csname corasdiagram@edgecheck@treatment@relation\endcsname{% \corasdiagram@ifincsv{\corasdiagram@fromrole}{incident}% {\corasdiagram@ifincsv{\corasdiagram@torole}{asset}{\corasdiagram@markedgevalid}{}}{}% } \expandafter\def\csname corasdiagram@edgecheck@treatment@treatment\endcsname{% \corasdiagram@ifincsv{\corasdiagram@fromrole}{treatment}% {\corasdiagram@ifincsv{\corasdiagram@torole}{threatsource,vulnerability,scenario,incident,asset,risk,junction}{\corasdiagram@markedgevalid}{}}{}% } \expandafter\def\csname corasdiagram@edgecheck@treatmentoverview@relation\endcsname{% \corasdiagram@ifincsv{\corasdiagram@fromrole}{risk}% {\corasdiagram@ifincsv{\corasdiagram@torole}{asset}{\corasdiagram@markedgevalid}{}}{}% } \expandafter\def\csname corasdiagram@edgecheck@treatmentoverview@treatment\endcsname{% \corasdiagram@ifincsv{\corasdiagram@fromrole}{treatment,junction}% {\corasdiagram@ifincsv{\corasdiagram@torole}{junction,risk}{\corasdiagram@markedgevalid}{}}{}% } \newcommand{\corasdiagram@validateedge}[3]{% \ifx\corasdiagram@currentfamily\@empty \else \corasdiagram@validateedgepair{\corasdiagram@currentfamily}{#1}{#2}{#3}% \ifx\corasdiagram@edgepairvalid\@empty \fi \ifnum\corasdiagram@edgepairvalid=1\relax \else \PackageError{corasdiagram}{\corasdiagram@semanticlabel{#1} edge from \corasdiagram@rolelabel{#2} to \corasdiagram@rolelabel{#3} is not allowed in the \corasdiagram@familynamelabel{\corasdiagram@currentfamily}}{% Use the canonical CORAS node roles and semantic edge commands for this diagram family.% }% \fi \fi } \newcommand{\corasdiagram@begindiagram}[1]{% \global\advance\corasdiagram@diagramseq by 1\relax \edef\corasdiagram@currentdiagramid{diagram-\the\corasdiagram@diagramseq}% \def\corasdiagram@currentfamily{#1}% \def\corasdiagram@layoutmode{auto}% \global\corasdiagram@placedcount=0\relax \@for\corasdiagram@role:=\corasdiagram@knownroles\do{% \expandafter\def\csname corasdiagram@lane@#1@\corasdiagram@role\endcsname{0}% }% } \newcommand{\corasdiagram@nextlaneindex}[2]{% \expandafter\ifx\csname corasdiagram@lane@#1@#2\endcsname\relax \expandafter\def\csname corasdiagram@lane@#1@#2\endcsname{0}% \fi \edef\corasdiagram@currindex{\csname corasdiagram@lane@#1@#2\endcsname}% \pgfmathtruncatemacro{\corasdiagram@nextindex}{\corasdiagram@currindex + 1}% \expandafter\xdef\csname corasdiagram@lane@#1@#2\endcsname{\corasdiagram@nextindex}% \edef\corasdiagram@laneindex{\corasdiagram@nextindex}% } \newcommand{\corasdiagram@setautocoord}[2]{% \edef\corasnode@at{(#1,#2)}% } \newcommand{\corasdiagram@measurelabelcontent}{% \ifx\corasnode@textwidth\@empty \setbox\z@=\hbox{{\sffamily\footnotesize\let\\\space\corasnode@title}}% \corasdiagram@labelwidth=\wd\z@ \corasdiagram@labelheight=3.8ex\relax \edef\corasdiagram@measuretitle{\corasnode@title}% \in@{\\}{\corasdiagram@measuretitle}% \ifin@ \advance\corasdiagram@labelheight by 3.8ex\relax \fi \ifx\corasnode@meta\@empty \else \advance\corasdiagram@labelheight by 2.6ex\relax \fi \ifx\corasnode@level\@empty \else \advance\corasdiagram@labelheight by 2.6ex\relax \fi \else \setbox\z@=\hbox{{\sffamily\footnotesize\corasdiagram@composecontent{\corasnode@textwidth}}}% \corasdiagram@labelwidth=\wd\z@ \corasdiagram@labelheight=\dimexpr\ht\z@+\dp\z@\relax \fi } \newcommand{\corasdiagram@measureiconlabelsize}[2]{% \corasdiagram@measurelabelcontent \corasdiagram@estimatedwidth=#1\relax \ifdim\corasdiagram@labelwidth>\corasdiagram@estimatedwidth \corasdiagram@estimatedwidth=\corasdiagram@labelwidth \fi \corasdiagram@estimatedheight=\dimexpr#2+\corasdiagram@labelheight\relax \corasdiagram@tmpdimen=\corasnode@labelgap\relax \ifdim\corasdiagram@tmpdimen<0pt \corasdiagram@tmpdimen=-\corasdiagram@tmpdimen \fi \advance\corasdiagram@estimatedheight by \corasdiagram@tmpdimen } \newcommand{\corasdiagram@measurebodynodesize}[4]{% \corasdiagram@measurelabelcontent \corasdiagram@estimatedwidth=\dimexpr#1+#2\relax \corasdiagram@estimatedheight=\dimexpr\corasdiagram@labelheight+#3\relax \ifdim\corasdiagram@estimatedheight<#4\relax \corasdiagram@estimatedheight=#4\relax \fi \advance\corasdiagram@estimatedheight by \corasnode@iconwidth\relax } \newcommand{\corasdiagram@measureautonodesize}{% \def\corasdiagram@typeasset{asset}% \def\corasdiagram@typeindirectasset{indirectasset}% \def\corasdiagram@typestakeholder{stakeholder}% \def\corasdiagram@typethreataccidental{threataccidental}% \def\corasdiagram@typethreatdeliberate{threatdeliberate}% \def\corasdiagram@typethreatnonhuman{threatnonhuman}% \def\corasdiagram@typevulnerability{vulnerability}% \def\corasdiagram@typescenario{scenario}% \def\corasdiagram@typeincident{incident}% \def\corasdiagram@typerisk{risk}% \def\corasdiagram@typetreatment{treatment}% \def\corasdiagram@typejunction{junction}% \ifx\corasnode@type\corasdiagram@typeasset \corasdiagram@setdefault\corasnode@textwidth{26mm}% \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}% \corasdiagram@measureiconlabelsize{10mm}{10.2mm}% \else\ifx\corasnode@type\corasdiagram@typeindirectasset \corasdiagram@setdefault\corasnode@textwidth{26mm}% \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}% \corasdiagram@measureiconlabelsize{10mm}{10.2mm}% \else\ifx\corasnode@type\corasdiagram@typestakeholder \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}% \corasdiagram@measureiconlabelsize{7mm}{9.9mm}% \else\ifx\corasnode@type\corasdiagram@typethreataccidental \corasdiagram@setdefault\corasnode@textwidth{23mm}% \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}% \corasdiagram@measureiconlabelsize{10mm}{13.0mm}% \else\ifx\corasnode@type\corasdiagram@typethreatdeliberate \corasdiagram@setdefault\corasnode@textwidth{23mm}% \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}% \corasdiagram@measureiconlabelsize{10mm}{13.6mm}% \else\ifx\corasnode@type\corasdiagram@typethreatnonhuman \corasdiagram@setdefault\corasnode@textwidth{26mm}% \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}% \corasdiagram@measureiconlabelsize{13mm}{10.8mm}% \else\ifx\corasnode@type\corasdiagram@typevulnerability \corasdiagram@setdefault\corasnode@textwidth{22mm}% \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}% \corasdiagram@measureiconlabelsize{8mm}{9.0mm}% \else\ifx\corasnode@type\corasdiagram@typescenario \corasdiagram@setdefault\corasnode@textwidth{28mm}% \corasdiagram@setdefault\corasnode@iconwidth{6.2mm}% \corasdiagram@measurebodynodesize{\corasnode@textwidth}{10pt}{6pt}{10mm}% \else\ifx\corasnode@type\corasdiagram@typeincident \corasdiagram@setdefault\corasnode@textwidth{25mm}% \corasdiagram@setdefault\corasnode@iconwidth{5.6mm}% \corasdiagram@measurebodynodesize{\corasnode@textwidth}{8pt}{6pt}{8mm}% \else\ifx\corasnode@type\corasdiagram@typerisk \corasdiagram@setdefault\corasnode@textwidth{27mm}% \corasdiagram@setdefault\corasnode@iconwidth{6.5mm}% \corasdiagram@measurebodynodesize{\corasnode@textwidth}{8pt}{6pt}{11mm}% \else\ifx\corasnode@type\corasdiagram@typetreatment \corasdiagram@setdefault\corasnode@textwidth{24mm}% \corasdiagram@setdefault\corasnode@iconwidth{7mm}% \corasdiagram@measurebodynodesize{\corasnode@textwidth}{10pt}{6pt}{9mm}% \else\ifx\corasnode@type\corasdiagram@typejunction \corasdiagram@estimatedwidth=3.3mm\relax \corasdiagram@estimatedheight=3.3mm\relax \else \corasdiagram@estimatedwidth=15mm\relax \corasdiagram@estimatedheight=10mm\relax \fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi } \newcommand{\corasdiagram@resolveeffectivegap}{% \ifx\corasnode@minedgegap\@empty \corasdiagram@minimumedgegap=\corasdiagram@layoutmingap\relax \else \corasdiagram@minimumedgegap=\corasnode@minedgegap\relax \fi } \newcommand{\corasdiagram@preparecurrentplacementmetrics}{% \corasdiagram@measureautonodesize \corasdiagram@resolveeffectivegap \corasdiagram@currenthalfwidth=\dimexpr\corasdiagram@estimatedwidth/2\relax \corasdiagram@currenthalfheight=\dimexpr\corasdiagram@estimatedheight/2\relax } \newcommand{\corasdiagram@enforcehorizontalrelativegap}[1]{% \corasdiagram@requestedgap=#1\relax \corasdiagram@tmpdimen=\dimexpr \corasdiagram@currenthalfwidth+\corasdiagram@minimumedgegap+\corasdiagram@minimumedgegapslack\relax \ifdim\corasdiagram@requestedgap<\corasdiagram@tmpdimen \corasdiagram@requestedgap=\corasdiagram@tmpdimen \fi } \newcommand{\corasdiagram@enforceverticalrelativegap}[1]{% \corasdiagram@requestedgap=#1\relax \corasdiagram@tmpdimen=\dimexpr \corasdiagram@currenthalfheight+\corasdiagram@minimumedgegap+\corasdiagram@minimumedgegapslack\relax \ifdim\corasdiagram@requestedgap<\corasdiagram@tmpdimen \corasdiagram@requestedgap=\corasdiagram@tmpdimen \fi } \newcommand{\corasdiagram@registerplacednode}[1]{% \global\advance\corasdiagram@placedcount by 1\relax \expandafter\xdef\csname corasdiagram@placed@\corasdiagram@currentdiagramid @\the\corasdiagram@placedcount\endcsname{#1}% } \newcommand{\corasdiagram@getplacednode}[2]{% \expandafter\ifcsname corasdiagram@placed@\corasdiagram@currentdiagramid @#2\endcsname \edef#1{\csname corasdiagram@placed@\corasdiagram@currentdiagramid @#2\endcsname}% \else \let#1\@empty \fi } \def\corasdiagram@splitautocoord(#1,#2){% \def\corasdiagram@rawautox{#1}% \def\corasdiagram@rawautoy{#2}% } \newcommand{\corasdiagram@avoidautolayoutoverlap}{% \corasdiagram@measureautonodesize \corasdiagram@currenthalfwidth=\dimexpr\corasdiagram@estimatedwidth/2\relax \corasdiagram@currenthalfheight=\dimexpr\corasdiagram@estimatedheight/2\relax \corasdiagram@overlapmarginx=1.5mm\relax \corasdiagram@overlapmarginy=1.8mm\relax \corasdiagram@placedindex=1\relax \loop \ifnum\corasdiagram@placedindex<\numexpr\corasdiagram@placedcount+1\relax \corasdiagram@getplacednode{\corasdiagram@previousnode}{\the\corasdiagram@placedindex}% \ifx\corasdiagram@previousnode\@empty \else \corasdiagram@getnodeprop{publicwidth}{\corasdiagram@previousnode}{\corasdiagram@previouswidth}% \corasdiagram@getnodeprop{publicheight}{\corasdiagram@previousnode}{\corasdiagram@previousheight}% \corasdiagram@getnodeprop{centerx}{\corasdiagram@previousnode}{\corasdiagram@previouscenterx}% \corasdiagram@getnodeprop{centery}{\corasdiagram@previousnode}{\corasdiagram@previouscentery}% \ifx\corasdiagram@previouswidth\@empty \else \corasdiagram@previoushalfwidth=\dimexpr\corasdiagram@previouswidth/2\relax \corasdiagram@previoushalfheight=\dimexpr\corasdiagram@previousheight/2\relax \corasdiagram@previousx=\corasdiagram@previouscenterx\relax \corasdiagram@previousy=\corasdiagram@previouscentery\relax \corasdiagram@overlapx=\dimexpr\corasdiagram@currentx-\corasdiagram@previousx\relax \ifdim\corasdiagram@overlapx<0pt \corasdiagram@overlapx=-\corasdiagram@overlapx \fi \ifdim\corasdiagram@overlapx<\dimexpr\corasdiagram@currenthalfwidth+\corasdiagram@previoushalfwidth+\corasdiagram@overlapmarginx\relax \corasdiagram@requiredy=\dimexpr \corasdiagram@previousy-\corasdiagram@previoushalfheight-\corasdiagram@currenthalfheight-\corasdiagram@overlapmarginy\relax \ifdim\corasdiagram@currenty>\corasdiagram@requiredy \corasdiagram@currenty=\corasdiagram@requiredy \fi \fi \fi \fi \advance\corasdiagram@placedindex by 1\relax \repeat \corasdiagram@makenodecoordfromdimens } \newcommand{\corasdiagram@usespecifiedorder}{% \ifx\corasnode@order\@empty \corasdiagram@nextlaneindex{\corasdiagram@currentfamily}{\corasnode@role}% \edef\corasnode@resolvedorder{\corasdiagram@laneindex}% \else \edef\corasdiagram@laneindex{\corasnode@order}% \edef\corasnode@resolvedorder{\corasnode@order}% \fi } \newcommand{\corasdiagram@makenodecoordfromdimens}{% \edef\corasnode@at{(\the\corasdiagram@currentx,\the\corasdiagram@currenty)}% } \newcommand{\corasdiagram@enforcerightofnode}[1]{% \ifx#1\@empty \else \corasdiagram@getnodeprop{publicwidth}{#1}{\corasdiagram@neighborwidth}% \corasdiagram@getnodeprop{centerx}{#1}{\corasdiagram@neighborcenter}% \ifx\corasdiagram@neighborwidth\@empty \else \corasdiagram@neighborhalfdimen=\dimexpr\corasdiagram@neighborwidth/2\relax \corasdiagram@neighborcenterdimen=\corasdiagram@neighborcenter\relax \corasdiagram@tmpdimen=\dimexpr \corasdiagram@neighborcenterdimen+\corasdiagram@neighborhalfdimen+\corasdiagram@currenthalfwidth+\corasdiagram@minimumedgegap+\corasdiagram@minimumedgegapslack\relax \ifdim\corasdiagram@currentx<\corasdiagram@tmpdimen \corasdiagram@currentx=\corasdiagram@tmpdimen \fi \fi \fi } \newcommand{\corasdiagram@enforceleftofnode}[1]{% \ifx#1\@empty \else \corasdiagram@getnodeprop{publicwidth}{#1}{\corasdiagram@neighborwidth}% \corasdiagram@getnodeprop{centerx}{#1}{\corasdiagram@neighborcenter}% \ifx\corasdiagram@neighborwidth\@empty \else \corasdiagram@neighborhalfdimen=\dimexpr\corasdiagram@neighborwidth/2\relax \corasdiagram@neighborcenterdimen=\corasdiagram@neighborcenter\relax \corasdiagram@tmpdimen=\dimexpr \corasdiagram@neighborcenterdimen-\corasdiagram@neighborhalfdimen-\corasdiagram@currenthalfwidth-\corasdiagram@minimumedgegap-\corasdiagram@minimumedgegapslack\relax \ifdim\corasdiagram@currentx>\corasdiagram@tmpdimen \corasdiagram@currentx=\corasdiagram@tmpdimen \fi \fi \fi } \newcommand{\corasdiagram@enforceabovenode}[1]{% \ifx#1\@empty \else \corasdiagram@getnodeprop{publicheight}{#1}{\corasdiagram@neighborheight}% \corasdiagram@getnodeprop{centery}{#1}{\corasdiagram@neighborcenter}% \ifx\corasdiagram@neighborheight\@empty \else \corasdiagram@neighborhalfdimen=\dimexpr\corasdiagram@neighborheight/2\relax \corasdiagram@neighborcenterdimen=\corasdiagram@neighborcenter\relax \corasdiagram@tmpdimen=\dimexpr \corasdiagram@neighborcenterdimen+\corasdiagram@neighborhalfdimen+\corasdiagram@currenthalfheight+\corasdiagram@minimumedgegap+\corasdiagram@minimumedgegapslack\relax \ifdim\corasdiagram@currenty<\corasdiagram@tmpdimen \corasdiagram@currenty=\corasdiagram@tmpdimen \fi \fi \fi } \newcommand{\corasdiagram@enforcebelownode}[1]{% \ifx#1\@empty \else \corasdiagram@getnodeprop{publicheight}{#1}{\corasdiagram@neighborheight}% \corasdiagram@getnodeprop{centery}{#1}{\corasdiagram@neighborcenter}% \ifx\corasdiagram@neighborheight\@empty \else \corasdiagram@neighborhalfdimen=\dimexpr\corasdiagram@neighborheight/2\relax \corasdiagram@neighborcenterdimen=\corasdiagram@neighborcenter\relax \corasdiagram@tmpdimen=\dimexpr \corasdiagram@neighborcenterdimen-\corasdiagram@neighborhalfdimen-\corasdiagram@currenthalfheight-\corasdiagram@minimumedgegap-\corasdiagram@minimumedgegapslack\relax \ifdim\corasdiagram@currenty>\corasdiagram@tmpdimen \corasdiagram@currenty=\corasdiagram@tmpdimen \fi \fi \fi } \newcommand{\corasdiagram@enforcerightofrole}[1]{% \ifx\corasnode@resolvedorder\@empty \else \corasdiagram@getroleordernode{\corasdiagram@adjacentnode}{#1}{\corasnode@resolvedorder}% \corasdiagram@enforcerightofnode{\corasdiagram@adjacentnode}% \fi } \newcommand{\corasdiagram@enforceleftofrole}[1]{% \ifx\corasnode@resolvedorder\@empty \else \corasdiagram@getroleordernode{\corasdiagram@adjacentnode}{#1}{\corasnode@resolvedorder}% \corasdiagram@enforceleftofnode{\corasdiagram@adjacentnode}% \fi } \newcommand{\corasdiagram@enforceaboverole}[1]{% \ifx\corasnode@resolvedorder\@empty \else \corasdiagram@getroleordernode{\corasdiagram@adjacentnode}{#1}{\corasnode@resolvedorder}% \corasdiagram@enforceabovenode{\corasdiagram@adjacentnode}% \fi } \newcommand{\corasdiagram@enforcebelowsamerole}[1]{% \ifx\corasnode@resolvedorder\@empty \else \pgfmathtruncatemacro{\corasdiagram@previousorder}{\corasnode@resolvedorder - 1}% \ifnum\corasdiagram@previousorder>0\relax \corasdiagram@getroleordernode{\corasdiagram@adjacentnode}{#1}{\corasdiagram@previousorder}% \corasdiagram@enforcebelownode{\corasdiagram@adjacentnode}% \fi \fi } \newcommand{\corasdiagram@enforcebelowallplacedrole}[1]{% \corasdiagram@placedindex=1\relax \loop \ifnum\corasdiagram@placedindex<\numexpr\corasdiagram@placedcount+1\relax \corasdiagram@getplacednode{\corasdiagram@previousnode}{\the\corasdiagram@placedindex}% \ifx\corasdiagram@previousnode\@empty \else \corasdiagram@getnodeprop{role}{\corasdiagram@previousnode}{\corasdiagram@previousrole}% \def\corasdiagram@targetrole{#1}% \ifx\corasdiagram@previousrole\corasdiagram@targetrole \corasdiagram@enforcebelownode{\corasdiagram@previousnode}% \fi \fi \advance\corasdiagram@placedindex by 1\relax \repeat } \newcommand{\corasdiagram@enforcerightofsamerole}[1]{% \ifx\corasnode@resolvedorder\@empty \else \pgfmathtruncatemacro{\corasdiagram@previousorder}{\corasnode@resolvedorder - 1}% \ifnum\corasdiagram@previousorder>0\relax \corasdiagram@getroleordernode{\corasdiagram@adjacentnode}{#1}{\corasdiagram@previousorder}% \corasdiagram@enforcerightofnode{\corasdiagram@adjacentnode}% \fi \fi } \newcommand{\corasdiagram@applyautominedgegap}{% \expandafter\ifx\csname corasdiagram@autogap@\corasdiagram@currentfamily @\corasnode@role\endcsname\relax \else \csname corasdiagram@autogap@\corasdiagram@currentfamily @\corasnode@role\endcsname \fi } \newcommand{\corasdiagram@setroleplacement}[1]{% \corasdiagram@usespecifiedorder \corasdiagram@preparecurrentplacementmetrics \def\corasdiagram@x{0}% \def\corasdiagram@y{0}% \def\corasdiagram@family{#1}% \ifx\corasdiagram@family\@empty \else \ifx\corasdiagram@family\@empty\else\fi \fi \ifx\corasdiagram@family\@empty \else \expandafter\ifx\csname corasdiagram@autoplace@#1@\corasnode@role\endcsname\relax \edef\corasnode@at{(0,0)}% \else \csname corasdiagram@autoplace@#1@\corasnode@role\endcsname \corasdiagram@currentx=\dimexpr\corasdiagram@x cm\relax \corasdiagram@currenty=\dimexpr\corasdiagram@y cm\relax \corasdiagram@applyautominedgegap \corasdiagram@makenodecoordfromdimens \corasdiagram@avoidautolayoutoverlap \fi \fi } \newcommand{\corasdiagram@tryrelativeplacement}{% \ifx\corasnode@rightof\@empty \ifx\corasnode@belowof\@empty \ifx\corasnode@incidentof\@empty \ifx\corasnode@harms\@empty \ifx\corasnode@treats\@empty \else \corasdiagram@preparecurrentplacementmetrics \fi \else \corasdiagram@preparecurrentplacementmetrics \fi \else \corasdiagram@preparecurrentplacementmetrics \fi \else \corasdiagram@preparecurrentplacementmetrics \fi \else \corasdiagram@preparecurrentplacementmetrics \fi \ifx\corasnode@rightof\@empty \else \corasdiagram@enforcehorizontalrelativegap{\corasnode@horizontalgap}% \edef\corasnode@at{([xshift=\the\corasdiagram@requestedgap]\corasnode@rightof.east)}% \fi \ifx\corasnode@at\@empty \ifx\corasnode@belowof\@empty \else \corasdiagram@enforceverticalrelativegap{\corasnode@verticalgap}% \edef\corasnode@at{([yshift=-\the\corasdiagram@requestedgap]\corasnode@belowof.south)}% \fi \fi \ifx\corasnode@at\@empty \ifx\corasnode@incidentof\@empty \else \corasdiagram@enforcehorizontalrelativegap{\corasnode@horizontalgap}% \edef\corasnode@at{([xshift=\the\corasdiagram@requestedgap]\corasnode@incidentof.east)}% \fi \fi \ifx\corasnode@at\@empty \ifx\corasnode@harms\@empty \else \corasdiagram@enforcehorizontalrelativegap{\corasnode@horizontalgap}% \edef\corasnode@at{([xshift=-\the\corasdiagram@requestedgap]\corasnode@harms.west)}% \fi \fi \ifx\corasnode@at\@empty \ifx\corasnode@treats\@empty \else \corasdiagram@enforceverticalrelativegap{\corasnode@verticalgap}% \edef\corasnode@at{([yshift=\the\corasdiagram@requestedgap]\corasnode@treats.north)}% \fi \fi } \newcommand{\corasdiagram@resolveplacement}{% \ifx\corasnode@at\@empty \corasdiagram@tryrelativeplacement \fi \ifx\corasnode@at\@empty \edef\corasdiagram@layoutchoice{\corasnode@layout}% \ifx\corasdiagram@layoutchoice\@empty \edef\corasdiagram@layoutchoice{\corasdiagram@layoutmode}% \fi \def\corasdiagram@manual{manual}% \ifx\corasdiagram@layoutchoice\corasdiagram@manual \edef\corasnode@at{(0,0)}% \else \corasdiagram@setroleplacement{\corasdiagram@currentfamily}% \fi \fi } \expandafter\def\csname corasdiagram@autoplace@asset@stakeholder\endcsname{% \pgfmathtruncatemacro{\corasdiagram@lanegroup}{int((\corasdiagram@laneindex - 1)/2)}% \pgfmathtruncatemacro{\corasdiagram@isright}{mod(\corasdiagram@laneindex,2)}% \ifnum\corasdiagram@isright=1\relax \def\corasdiagram@x{0}% \else \def\corasdiagram@x{10}% \fi \pgfmathsetmacro{\corasdiagram@y}{3.1 - 3.4*\corasdiagram@lanegroup}% } \expandafter\def\csname corasdiagram@autoplace@asset@asset\endcsname{% \pgfmathtruncatemacro{\corasdiagram@lanegroup}{int((\corasdiagram@laneindex - 1)/2)}% \pgfmathtruncatemacro{\corasdiagram@isright}{mod(\corasdiagram@laneindex,2)}% \ifnum\corasdiagram@isright=1\relax \def\corasdiagram@x{3.8}% \pgfmathsetmacro{\corasdiagram@y}{1.4 - 2.6*\corasdiagram@lanegroup}% \else \def\corasdiagram@x{7.2}% \pgfmathsetmacro{\corasdiagram@y}{2.8 - 2.6*\corasdiagram@lanegroup}% \fi } \expandafter\def\csname corasdiagram@autoplace@threat@threatsource\endcsname{% \def\corasdiagram@x{0}% \pgfmathsetmacro{\corasdiagram@y}{2.8 - 3.1*(\corasdiagram@laneindex - 1)}% } \expandafter\def\csname corasdiagram@autoplace@threat@vulnerability\endcsname{% \def\corasdiagram@x{3.3}% \pgfmathsetmacro{\corasdiagram@y}{2.4 - 3.1*(\corasdiagram@laneindex - 1)}% } \expandafter\def\csname corasdiagram@autoplace@threat@scenario\endcsname{% \def\corasdiagram@x{6.6}% \pgfmathsetmacro{\corasdiagram@y}{3.8 - 2.4*(\corasdiagram@laneindex - 1)}% } \expandafter\def\csname corasdiagram@autoplace@threat@incident\endcsname{% \def\corasdiagram@x{10.2}% \pgfmathsetmacro{\corasdiagram@y}{2.8 - 3.1*(\corasdiagram@laneindex - 1)}% } \expandafter\def\csname corasdiagram@autoplace@threat@asset\endcsname{% \def\corasdiagram@x{13.3}% \pgfmathsetmacro{\corasdiagram@y}{2.6 - 3.1*(\corasdiagram@laneindex - 1)}% } \expandafter\def\csname corasdiagram@autoplace@risk@threatsource\endcsname{% \def\corasdiagram@x{0}% \pgfmathsetmacro{\corasdiagram@y}{1.8 - 3.1*(\corasdiagram@laneindex - 1)}% } \expandafter\def\csname corasdiagram@autoplace@risk@risk\endcsname{% \def\corasdiagram@x{4.2}% \pgfmathsetmacro{\corasdiagram@y}{2.8 - 2.4*(\corasdiagram@laneindex - 1)}% } \expandafter\def\csname corasdiagram@autoplace@risk@asset\endcsname{% \def\corasdiagram@x{8.1}% \pgfmathsetmacro{\corasdiagram@y}{2.4 - 3.1*(\corasdiagram@laneindex - 1)}% } \expandafter\def\csname corasdiagram@autoplace@treatment@treatment\endcsname{% \pgfmathsetmacro{\corasdiagram@x}{1.6 + 4.2*(\corasdiagram@laneindex - 1)}% \def\corasdiagram@y{5.2}% } \expandafter\def\csname corasdiagram@autoplace@treatment@threatsource\endcsname{% \def\corasdiagram@x{0}% \pgfmathsetmacro{\corasdiagram@y}{2.4 - 3.1*(\corasdiagram@laneindex - 1)}% } \expandafter\def\csname corasdiagram@autoplace@treatment@vulnerability\endcsname{% \def\corasdiagram@x{3.3}% \pgfmathsetmacro{\corasdiagram@y}{2.1 - 3.1*(\corasdiagram@laneindex - 1)}% } \expandafter\def\csname corasdiagram@autoplace@treatment@scenario\endcsname{% \def\corasdiagram@x{6.6}% \pgfmathsetmacro{\corasdiagram@y}{3.3 - 2.4*(\corasdiagram@laneindex - 1)}% } \expandafter\def\csname corasdiagram@autoplace@treatment@incident\endcsname{% \def\corasdiagram@x{10.3}% \pgfmathsetmacro{\corasdiagram@y}{2.6 - 3.1*(\corasdiagram@laneindex - 1)}% } \expandafter\def\csname corasdiagram@autoplace@treatment@asset\endcsname{% \def\corasdiagram@x{13.4}% \pgfmathsetmacro{\corasdiagram@y}{2.2 - 3.1*(\corasdiagram@laneindex - 1)}% } \expandafter\def\csname corasdiagram@autoplace@treatmentoverview@risk\endcsname{% \def\corasdiagram@x{4.2}% \pgfmathsetmacro{\corasdiagram@y}{2.4 - 3.0*(\corasdiagram@laneindex - 1)}% } \expandafter\def\csname corasdiagram@autoplace@treatmentoverview@asset\endcsname{% \def\corasdiagram@x{7.7}% \pgfmathsetmacro{\corasdiagram@y}{2.0 - 3.0*(\corasdiagram@laneindex - 1)}% } \expandafter\def\csname corasdiagram@autoplace@treatmentoverview@junction\endcsname{% \def\corasdiagram@x{5.0}% \def\corasdiagram@y{-3.2}% } \expandafter\def\csname corasdiagram@autoplace@treatmentoverview@treatment\endcsname{% \pgfmathsetmacro{\corasdiagram@x}{2.0 + 3.4*(\corasdiagram@laneindex - 1)}% \def\corasdiagram@y{-5.1}% } \expandafter\def\csname corasdiagram@autogap@threat@threatsource\endcsname{% \corasdiagram@enforceleftofrole{vulnerability}% } \expandafter\def\csname corasdiagram@autogap@threat@vulnerability\endcsname{% \corasdiagram@enforcerightofrole{threatsource}% \corasdiagram@enforceleftofrole{scenario}% } \expandafter\def\csname corasdiagram@autogap@threat@scenario\endcsname{% \corasdiagram@enforcerightofrole{vulnerability}% \corasdiagram@enforceleftofrole{incident}% \corasdiagram@enforcebelowsamerole{scenario}% } \expandafter\def\csname corasdiagram@autogap@threat@incident\endcsname{% \corasdiagram@enforcerightofrole{scenario}% \corasdiagram@enforceleftofrole{asset}% \corasdiagram@enforcebelowsamerole{incident}% } \expandafter\def\csname corasdiagram@autogap@threat@asset\endcsname{% \corasdiagram@enforcerightofrole{incident}% \corasdiagram@enforcebelowsamerole{asset}% } \expandafter\def\csname corasdiagram@autogap@risk@threatsource\endcsname{% \corasdiagram@enforceleftofrole{risk}% } \expandafter\def\csname corasdiagram@autogap@risk@risk\endcsname{% \corasdiagram@enforcerightofrole{threatsource}% \corasdiagram@enforceleftofrole{asset}% \corasdiagram@enforcebelowsamerole{risk}% } \expandafter\def\csname corasdiagram@autogap@risk@asset\endcsname{% \corasdiagram@enforcerightofrole{risk}% \corasdiagram@enforcebelowsamerole{asset}% } \expandafter\def\csname corasdiagram@autogap@treatment@threatsource\endcsname{% \corasdiagram@enforceleftofrole{vulnerability}% } \expandafter\def\csname corasdiagram@autogap@treatment@vulnerability\endcsname{% \corasdiagram@enforcerightofrole{threatsource}% \corasdiagram@enforceleftofrole{scenario}% } \expandafter\def\csname corasdiagram@autogap@treatment@scenario\endcsname{% \corasdiagram@enforcerightofrole{vulnerability}% \corasdiagram@enforceleftofrole{incident}% \corasdiagram@enforcebelowsamerole{scenario}% } \expandafter\def\csname corasdiagram@autogap@treatment@incident\endcsname{% \corasdiagram@enforcerightofrole{scenario}% \corasdiagram@enforceleftofrole{asset}% } \expandafter\def\csname corasdiagram@autogap@treatment@asset\endcsname{% \corasdiagram@enforcerightofrole{incident}% } \expandafter\def\csname corasdiagram@autogap@treatment@treatment\endcsname{% \corasdiagram@enforcerightofsamerole{treatment}% \corasdiagram@enforceaboverole{threatsource}% \corasdiagram@enforceaboverole{vulnerability}% \corasdiagram@enforceaboverole{scenario}% \corasdiagram@enforceaboverole{incident}% \corasdiagram@enforceaboverole{asset}% } \expandafter\def\csname corasdiagram@autogap@treatmentoverview@risk\endcsname{% \corasdiagram@enforcebelowsamerole{risk}% } \expandafter\def\csname corasdiagram@autogap@treatmentoverview@asset\endcsname{% \corasdiagram@enforcerightofrole{risk}% \corasdiagram@enforcebelowsamerole{asset}% } \expandafter\def\csname corasdiagram@autogap@treatmentoverview@junction\endcsname{% \corasdiagram@enforcebelowallplacedrole{risk}% } \expandafter\def\csname corasdiagram@autogap@treatmentoverview@treatment\endcsname{% \corasdiagram@enforcerightofsamerole{treatment}% \corasdiagram@enforcebelowallplacedrole{junction}% } \newcommand{\corasdiagram@secondarytext}[1]{% {\scriptsize\itshape\color{black!65}#1}% } \newcommand{\corasdiagram@composecontent}[1]{% \parbox{#1}{% \centering \strut\corasnode@title\strut \ifx\corasnode@meta\@empty \else \\[-0.1ex]\corasdiagram@secondarytext{\corasnode@meta}% \fi \ifx\corasnode@level\@empty \else \\[-0.1ex]\corasdiagram@secondarytext{[\corasnode@level]}% \fi }% } \newcommand{\corasdiagram@composeautocontent}{% \begin{tabular}{@{}c@{}} \strut\corasnode@title\strut \ifx\corasnode@meta\@empty \else \\[-0.1ex]\corasdiagram@secondarytext{\corasnode@meta}% \fi \ifx\corasnode@level\@empty \else \\[-0.1ex]\corasdiagram@secondarytext{[\corasnode@level]}% \fi \end{tabular}% } \newcommand{\corasdiagram@placenode}[3]{% \edef\corasdiagram@nodeoptions{#1,\corasnode@tikz}% \expandafter\node\expandafter[\corasdiagram@nodeoptions] (#2) at \corasnode@at {#3}; } \newcommand{\corasdiagram@placeauxnode}[4]{% \edef\corasdiagram@auxnodeoptions{#1,#4}% \expandafter\node\expandafter[\corasdiagram@auxnodeoptions] (#2) {#3}; } \newcommand{\corasdiagram@fitpublicnode}[2]{% \node[inner sep=0pt,outer sep=0pt,fit=#2] (#1) {}; } \newcommand{\corasdiagram@storepublicnodesize}[1]{% \pgfextractx{\corasdiagram@tmpdimen}{% \pgfpointdiff{\pgfpointanchor{#1}{west}}{\pgfpointanchor{#1}{east}}% }% \corasdiagram@compartmentwidth=\corasdiagram@tmpdimen\relax \ifdim\corasdiagram@compartmentwidth<0pt \corasdiagram@compartmentwidth=-\corasdiagram@compartmentwidth \fi \pgfextracty{\corasdiagram@tmpdimen}{% \pgfpointdiff{\pgfpointanchor{#1}{south}}{\pgfpointanchor{#1}{north}}% }% \corasdiagram@compartmentheight=\corasdiagram@tmpdimen\relax \ifdim\corasdiagram@compartmentheight<0pt \corasdiagram@compartmentheight=-\corasdiagram@compartmentheight \fi \corasdiagram@setnodeprop{publicwidth}{#1}{\the\corasdiagram@compartmentwidth}% \corasdiagram@setnodeprop{publicheight}{#1}{\the\corasdiagram@compartmentheight}% \pgfextractx{\corasdiagram@tmpdimen}{\pgfpointanchor{#1}{center}}% \corasdiagram@setnodeprop{centerx}{#1}{\the\corasdiagram@tmpdimen}% \pgfextracty{\corasdiagram@tmpdimen}{\pgfpointanchor{#1}{center}}% \corasdiagram@setnodeprop{centery}{#1}{\the\corasdiagram@tmpdimen}% } \newcommand{\corasdiagram@fitanchor}[3]{% \node[#1,fit=(#3),inner sep=0pt,outer sep=0pt] (#2-anchor) {}; } \newcommand{\corasdiagram@resolveendpoint}[1]{% \edef\corasdiagram@rawendpoint{#1}% \in@{(}{\corasdiagram@rawendpoint}% \ifin@ \edef\corasdiagram@resolvedendpoint{\corasdiagram@rawendpoint}% \else \in@{.}{\corasdiagram@rawendpoint}% \ifin@ \expandafter\corasdiagram@splitendpoint\corasdiagram@rawendpoint\@nil \else \def\corasdiagram@endpointbase{\corasdiagram@rawendpoint}% \let\corasdiagram@endpointsuffix\@empty \fi \expandafter\ifcsname pgf@sh@ns@\corasdiagram@endpointbase-anchor\endcsname \ifx\corasdiagram@endpointsuffix\@empty \edef\corasdiagram@resolvedendpoint{\corasdiagram@endpointbase-anchor}% \else \edef\corasdiagram@resolvedendpoint{\corasdiagram@endpointbase-anchor.\corasdiagram@endpointsuffix}% \fi \else \edef\corasdiagram@resolvedendpoint{\corasdiagram@rawendpoint}% \fi \fi } \def\corasdiagram@splitendpoint#1.#2\@nil{% \def\corasdiagram@endpointbase{#1}% \def\corasdiagram@endpointsuffix{#2}% } \newcommand{\corasdiagram@endpointbasename}[2]{% \edef\corasdiagram@rawendpoint{#2}% \in@{(}{\corasdiagram@rawendpoint}% \ifin@ \let#1\@empty \else \in@{.}{\corasdiagram@rawendpoint}% \ifin@ \expandafter\corasdiagram@splitendpoint\corasdiagram@rawendpoint\@nil \edef#1{\corasdiagram@endpointbase}% \else \edef#1{\corasdiagram@rawendpoint}% \fi \fi } \newcommand{\corasdiagram@lookupendpointrole}[2]{% \corasdiagram@endpointbasename{\corasdiagram@basename}{#2}% \ifx\corasdiagram@basename\@empty \let#1\@empty \else \corasdiagram@getnodeprop{role}{\corasdiagram@basename}{#1}% \fi } \newcommand{\corasdiagram@registernode}[1]{% \corasdiagram@validatecurrentrole{\corasnode@type}{\corasnode@role}% \corasdiagram@setnodeprop{role}{#1}{\corasnode@role}% \corasdiagram@setnodeprop{type}{#1}{\corasnode@type}% \corasdiagram@setnodeprop{scope}{#1}{\corasnode@scope}% \corasdiagram@setnodeprop{orderindex}{#1}{\corasnode@resolvedorder}% \ifx\corasnode@resolvedorder\@empty \else \corasdiagram@setroleordernode{\corasnode@role}{\corasnode@resolvedorder}{#1}% \fi \corasdiagram@registerscopemember{\corasnode@scope}{#1}% \corasdiagram@registerplacednode{#1}% } \newcommand{\corasdiagram@rendericonlabelnode}[1]{% \def\corasdiagram@iconanchoroptions{\corasnode@anchorstyle,coras/invisible anchor}% \ifx\corasnode@anchorwidth\@empty \else \edef\corasdiagram@iconanchoroptions{\corasdiagram@iconanchoroptions,minimum width=\corasnode@anchorwidth}% \fi \ifx\corasnode@anchorheight\@empty \else \edef\corasdiagram@iconanchoroptions{\corasdiagram@iconanchoroptions,minimum height=\corasnode@anchorheight}% \fi \corasdiagram@placenode{\corasdiagram@iconanchoroptions}{\corasnode@name-anchor}{}% \node[coras/base node] (\corasnode@name-graphic) at \corasnode@at {% \corasdiagram@includeicon{\corasnode@iconwidth}{#1}% }; \def\corasdiagram@labelnodeoptions{coras/base node,anchor=north}% \ifx\corasnode@textwidth\@empty \def\corasdiagram@labelcontent{\corasdiagram@composeautocontent}% \else \edef\corasdiagram@labelnodeoptions{\corasdiagram@labelnodeoptions,text width=\corasnode@textwidth}% \def\corasdiagram@labelcontent{\corasdiagram@composecontent{\corasnode@textwidth}}% \fi \corasdiagram@placeauxnode{\corasdiagram@labelnodeoptions}{\corasnode@name-label}{% \corasdiagram@labelcontent }{at={([yshift=\corasnode@labelgap]\corasnode@name-graphic.south)}}% \corasdiagram@fitpublicnode{\corasnode@name}{(\corasnode@name-graphic) (\corasnode@name-label)}% \corasdiagram@storepublicnodesize{\corasnode@name}% \corasdiagram@setnodeprop{bordernode}{\corasnode@name}{\corasnode@name-anchor}% \ifx\corasnode@anchorsymbol\@empty \else \corasdiagram@setnodeprop{anchorsymbol}{\corasnode@name}{\corasnode@anchorsymbol}% \fi } \newcommand{\corasdiagram@render@asset}{% \corasdiagram@setdefault\corasnode@textwidth{26mm}% \corasdiagram@setdefault\corasnode@iconwidth{10mm}% \corasdiagram@setdefault\corasnode@anchorstyle{coras/asset anchor}% \corasdiagram@setdefault\corasnode@anchorwidth{0pt}% \corasdiagram@setdefault\corasnode@anchorheight{0pt}% \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}% \corasdiagram@setdefault\corasnode@perspective{before}% \def\corasnode@anchorsymbol{asset}% \corasdiagram@resolveiconstem{asset}{\corasnode@perspective}{\corasdiagram@resolvediconstem}% \corasdiagram@rendericonlabelnode{\corasdiagram@resolvediconstem}% } \newcommand{\corasdiagram@render@indirectasset}{% \corasdiagram@setdefault\corasnode@textwidth{26mm}% \corasdiagram@setdefault\corasnode@iconwidth{10mm}% \corasdiagram@setdefault\corasnode@anchorstyle{coras/indirect asset anchor}% \corasdiagram@setdefault\corasnode@anchorwidth{0pt}% \corasdiagram@setdefault\corasnode@anchorheight{0pt}% \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}% \corasdiagram@setdefault\corasnode@perspective{before}% \def\corasnode@anchorsymbol{indirectasset}% \corasdiagram@resolveiconstem{indirect-asset}{\corasnode@perspective}{\corasdiagram@resolvediconstem}% \corasdiagram@rendericonlabelnode{\corasdiagram@resolvediconstem}% } \newcommand{\corasdiagram@render@stakeholder}{% \corasdiagram@setdefault\corasnode@iconwidth{7mm}% \corasdiagram@setdefault\corasnode@anchorstyle{coras/stakeholder anchor}% \corasdiagram@setdefault\corasnode@anchorwidth{0pt}% \corasdiagram@setdefault\corasnode@anchorheight{0pt}% \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}% \corasdiagram@setdefault\corasnode@perspective{before}% \def\corasnode@anchorsymbol{stakeholder}% \corasdiagram@resolveiconstem{stakeholder}{\corasnode@perspective}{\corasdiagram@resolvediconstem}% \corasdiagram@rendericonlabelnode{\corasdiagram@resolvediconstem}% } \newcommand{\corasdiagram@render@threataccidental}{% \corasdiagram@setdefault\corasnode@textwidth{23mm}% \corasdiagram@setdefault\corasnode@iconwidth{10mm}% \corasdiagram@setdefault\corasnode@anchorstyle{coras/threat accidental anchor}% \corasdiagram@setdefault\corasnode@anchorwidth{0pt}% \corasdiagram@setdefault\corasnode@anchorheight{0pt}% \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}% \corasdiagram@setdefault\corasnode@perspective{before}% \def\corasnode@anchorsymbol{threataccidental}% \corasdiagram@resolveiconstem{threat-human-accidental}{\corasnode@perspective}{\corasdiagram@resolvediconstem}% \corasdiagram@rendericonlabelnode{\corasdiagram@resolvediconstem}% } \newcommand{\corasdiagram@render@threatdeliberate}{% \corasdiagram@setdefault\corasnode@textwidth{23mm}% \corasdiagram@setdefault\corasnode@iconwidth{10mm}% \corasdiagram@setdefault\corasnode@anchorstyle{coras/threat deliberate anchor}% \corasdiagram@setdefault\corasnode@anchorwidth{0pt}% \corasdiagram@setdefault\corasnode@anchorheight{0pt}% \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}% \corasdiagram@setdefault\corasnode@perspective{before}% \def\corasnode@anchorsymbol{threatdeliberate}% \corasdiagram@resolveiconstem{threat-human-deliberate}{\corasnode@perspective}{\corasdiagram@resolvediconstem}% \corasdiagram@rendericonlabelnode{\corasdiagram@resolvediconstem}% } \newcommand{\corasdiagram@render@threatnonhuman}{% \corasdiagram@setdefault\corasnode@textwidth{26mm}% \corasdiagram@setdefault\corasnode@iconwidth{13mm}% \corasdiagram@setdefault\corasnode@anchorstyle{coras/threat nonhuman anchor}% \corasdiagram@setdefault\corasnode@anchorwidth{0pt}% \corasdiagram@setdefault\corasnode@anchorheight{0pt}% \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}% \corasdiagram@setdefault\corasnode@perspective{before}% \def\corasnode@anchorsymbol{threatnonhuman}% \corasdiagram@resolveiconstem{threat-non-human}{\corasnode@perspective}{\corasdiagram@resolvediconstem}% \corasdiagram@rendericonlabelnode{\corasdiagram@resolvediconstem}% } \newcommand{\corasdiagram@render@vulnerability}{% \corasdiagram@setdefault\corasnode@textwidth{22mm}% \corasdiagram@setdefault\corasnode@iconwidth{8mm}% \corasdiagram@setdefault\corasnode@anchorstyle{coras/vulnerability anchor}% \corasdiagram@setdefault\corasnode@anchorwidth{0pt}% \corasdiagram@setdefault\corasnode@anchorheight{0pt}% \corasdiagram@setdefault\corasnode@labelgap{-0.4mm}% \corasdiagram@setdefault\corasnode@perspective{before}% \def\corasnode@anchorsymbol{vulnerability}% \corasdiagram@resolveiconstem{vulnerability}{\corasnode@perspective}{\corasdiagram@resolvediconstem}% \corasdiagram@rendericonlabelnode{\corasdiagram@resolvediconstem}% } \newcommand{\corasdiagram@render@scenario}{% \corasdiagram@setdefault\corasnode@textwidth{28mm}% \corasdiagram@setdefault\corasnode@iconwidth{6.2mm}% \corasdiagram@setdefault\corasnode@perspective{before}% \corasdiagram@placenode{% coras/ellipse, text width=\corasnode@textwidth }{\corasnode@name-body}{\corasdiagram@composecontent{\corasnode@textwidth}}% \corasdiagram@resolveiconstem{risk}{\corasnode@perspective}{\corasdiagram@resolvediconstem}% \node[coras/base node,anchor=center] (\corasnode@name-icon) at (\corasnode@name-body.north) {\corasdiagram@includeicon{\corasnode@iconwidth}{\corasdiagram@resolvediconstem}}; \corasdiagram@fitanchor{coras/anchor ellipse}{\corasnode@name}{\corasnode@name-body}% \corasdiagram@fitpublicnode{\corasnode@name}{(\corasnode@name-body) (\corasnode@name-icon)}% \corasdiagram@storepublicnodesize{\corasnode@name}% \corasdiagram@setnodeprop{bordernode}{\corasnode@name}{\corasnode@name-body}% } \newcommand{\corasdiagram@render@incident}{% \corasdiagram@setdefault\corasnode@textwidth{25mm}% \corasdiagram@setdefault\corasnode@iconwidth{5.6mm}% \corasdiagram@setdefault\corasnode@perspective{before}% \corasdiagram@placenode{% coras/incident body, text width=\corasnode@textwidth }{\corasnode@name-body}{\corasdiagram@composecontent{\corasnode@textwidth}}% \corasdiagram@resolveiconstem{unwanted-incident}{\corasnode@perspective}{\corasdiagram@resolvediconstem}% \node[coras/base node,anchor=center] (\corasnode@name-icon) at ([xshift=-1.6mm]\corasnode@name-body.north east) {\corasdiagram@includeicon{\corasnode@iconwidth}{\corasdiagram@resolvediconstem}}; \corasdiagram@fitanchor{coras/anchor rectangle}{\corasnode@name}{\corasnode@name-body}% \corasdiagram@fitpublicnode{\corasnode@name}{(\corasnode@name-body) (\corasnode@name-icon)}% \corasdiagram@storepublicnodesize{\corasnode@name}% \corasdiagram@setnodeprop{bordernode}{\corasnode@name}{\corasnode@name-body}% } \newcommand{\corasdiagram@render@risk}{% \corasdiagram@setdefault\corasnode@textwidth{27mm}% \corasdiagram@setdefault\corasnode@iconwidth{6.5mm}% \corasdiagram@setdefault\corasnode@perspective{before}% \corasdiagram@placenode{% coras/risk body, text width=\corasnode@textwidth }{\corasnode@name-body}{\corasdiagram@composecontent{\corasnode@textwidth}}% \corasdiagram@resolveiconstem{risk}{\corasnode@perspective}{\corasdiagram@resolvediconstem}% \node[coras/base node,anchor=south] (\corasnode@name-icon) at ([yshift=0.5mm]\corasnode@name-body.north) {\corasdiagram@includeicon{\corasnode@iconwidth}{\corasdiagram@resolvediconstem}}; \corasdiagram@fitanchor{coras/anchor rectangle}{\corasnode@name}{\corasnode@name-body}% \corasdiagram@fitpublicnode{\corasnode@name}{(\corasnode@name-body) (\corasnode@name-icon)}% \corasdiagram@storepublicnodesize{\corasnode@name}% \corasdiagram@setnodeprop{bordernode}{\corasnode@name}{\corasnode@name-body}% } \newcommand{\corasdiagram@render@treatment}{% \corasdiagram@setdefault\corasnode@textwidth{24mm}% \corasdiagram@setdefault\corasnode@iconwidth{7mm}% \corasdiagram@setdefault\corasnode@perspective{before}% \corasdiagram@placenode{% coras/treatment body, text width=\corasnode@textwidth }{\corasnode@name-body}{\corasdiagram@composecontent{\corasnode@textwidth}}% \corasdiagram@resolveiconstem{treatment}{\corasnode@perspective}{\corasdiagram@resolvediconstem}% \node[coras/base node,anchor=center] (\corasnode@name-icon) at (\corasnode@name-body.north) {\corasdiagram@includeicon{\corasnode@iconwidth}{\corasdiagram@resolvediconstem}}; \corasdiagram@fitanchor{coras/anchor ellipse}{\corasnode@name}{\corasnode@name-body}% \corasdiagram@fitpublicnode{\corasnode@name}{(\corasnode@name-body) (\corasnode@name-icon)}% \corasdiagram@storepublicnodesize{\corasnode@name}% \corasdiagram@setnodeprop{bordernode}{\corasnode@name}{\corasnode@name-body}% } \newcommand{\corasdiagram@render@junction}{% \corasdiagram@placenode{coras/junction}{\corasnode@name}{}% \corasdiagram@fitanchor{coras/anchor ellipse}{\corasnode@name}{\corasnode@name}% \corasdiagram@storepublicnodesize{\corasnode@name}% \corasdiagram@setnodeprop{bordernode}{\corasnode@name}{\corasnode@name}% } \pgfkeys{ /coras/node/.is family, /coras/node, type/.store in=\corasnode@type, name/.store in=\corasnode@name, title/.store in=\corasnode@title, label/.store in=\corasnode@label, meta/.store in=\corasnode@meta, level/.store in=\corasnode@level, value/.store in=\corasnode@value, perspective/.store in=\corasnode@perspective, at/.store in=\corasnode@at, scope/.store in=\corasnode@scope, order/.store in=\corasnode@order, text width/.store in=\corasnode@textwidth, icon width/.store in=\corasnode@iconwidth, anchor style/.store in=\corasnode@anchorstyle, anchor width/.store in=\corasnode@anchorwidth, anchor height/.store in=\corasnode@anchorheight, label gap/.store in=\corasnode@labelgap, layout/.store in=\corasnode@layout, min edge gap/.store in=\corasnode@minedgegap, right of/.store in=\corasnode@rightof, below of/.store in=\corasnode@belowof, incident of/.store in=\corasnode@incidentof, treats/.store in=\corasnode@treats, harms/.store in=\corasnode@harms, horizontal gap/.store in=\corasnode@horizontalgap, vertical gap/.store in=\corasnode@verticalgap, tikz/.store in=\corasnode@tikz, } \NewDocumentCommand{\corasnode}{O{}}{% \pgfkeys{/coras/node/.cd,% type=asset,% name=,% title=,% label=,% meta=,% level=,% value=,% perspective=before,% at=,% scope=,% order=,% text width=,% icon width=,% anchor style=,% anchor width=,% anchor height=,% label gap=,% layout=,% min edge gap=,% right of=,% below of=,% incident of=,% treats=,% harms=,% horizontal gap=12mm,% vertical gap=14mm,% tikz=,% #1% }% \let\corasnode@resolvedorder\@empty \corasdiagram@ensurename\corasnode@name \ifx\corasnode@title\@empty \edef\corasnode@title{\corasnode@label}% \fi \corasdiagram@maptyperole{\corasnode@type}% \edef\corasnode@role{\corasdiagram@mappedrole}% \ifx\corasnode@level\@empty \ifx\corasnode@value\@empty \else \edef\corasnode@level{\corasnode@value}% \fi \fi \corasdiagram@resolveplacement \corasdiagram@normalize\corasnode@tikz \let\corasnode@anchorsymbol\@empty \@ifundefined{corasdiagram@render@\corasnode@type}{% \PackageError{corasdiagram}{Unknown node type `\corasnode@type'}{% Valid node types are asset, stakeholder, threataccidental, threatdeliberate, threatnonhuman, vulnerability, indirectasset, scenario, incident, risk, treatment, and junction.% }% }{% \csname corasdiagram@render@\corasnode@type\endcsname \corasdiagram@registernode{\corasnode@name}% }% } \pgfkeys{ /coras/edge/.is family, /coras/edge, from/.store in=\corasedge@from, to/.store in=\corasedge@to, type/.store in=\corasedge@type, semantic/.store in=\corasedge@semantic, label/.store in=\corasedge@label, pos/.store in=\corasedge@pos, path/.store in=\corasedge@path, route/.store in=\corasedge@route, tikz/.store in=\corasedge@tikz, label options/.store in=\corasedge@labeloptions, } \newcommand{\corasdiagram@resolvedgesemantic}{% \ifx\corasedge@semantic\@empty \edef\corasedge@semantic{\corasedge@type}% \def\corasdiagram@overview{overview}% \ifx\corasedge@semantic\corasdiagram@overview \def\corasedge@semantic{treatment}% \fi \fi } \newcommand{\corasdiagram@defaultpathforroute}{% \def\corasdiagram@edgepath{--}% \def\corasdiagram@routeauto{auto}% \def\corasdiagram@routestraight{straight}% \def\corasdiagram@routehv{hv}% \def\corasdiagram@routevh{vh}% \ifx\corasedge@route\corasdiagram@routehv \def\corasdiagram@edgepath{-|}% \else\ifx\corasedge@route\corasdiagram@routevh \def\corasdiagram@edgepath{|-}% \else\ifx\corasedge@route\corasdiagram@routestraight \def\corasdiagram@edgepath{--}% \else \def\corasdiagram@edgepath{--}% \def\corasdiagram@concern{concern}% \def\corasdiagram@treatmentsemantic{treatment}% \ifx\corasedge@semantic\corasdiagram@concern \def\corasdiagram@edgepath{-|}% \else\ifx\corasedge@semantic\corasdiagram@treatmentsemantic \def\corasdiagram@edgepath{--}% \fi\fi \fi\fi\fi } \newcommand{\corasdiagram@setcurveanchorsfromdelta}{% \pgfmathtruncatemacro{\corasdiagram@verticaldominant}{abs(\corasdiagram@dy) > abs(\corasdiagram@dx) ? 1 : 0}% \ifnum\corasdiagram@verticaldominant=1\relax \pgfmathtruncatemacro{\corasdiagram@targetabove}{\corasdiagram@dy > 0 ? 1 : 0}% \ifnum\corasdiagram@targetabove=1\relax \xdef\corasdiagram@fromanchorsuffix{north}% \xdef\corasdiagram@toanchorsuffix{south}% \xdef\corasdiagram@curveout{90}% \xdef\corasdiagram@curvein{-90}% \else \xdef\corasdiagram@fromanchorsuffix{south}% \xdef\corasdiagram@toanchorsuffix{north}% \xdef\corasdiagram@curveout{-90}% \xdef\corasdiagram@curvein{90}% \fi \else \pgfmathtruncatemacro{\corasdiagram@targetright}{\corasdiagram@dx > 0 ? 1 : 0}% \ifnum\corasdiagram@targetright=1\relax \xdef\corasdiagram@fromanchorsuffix{east}% \xdef\corasdiagram@toanchorsuffix{west}% \xdef\corasdiagram@curveout{0}% \xdef\corasdiagram@curvein{180}% \else \xdef\corasdiagram@fromanchorsuffix{west}% \xdef\corasdiagram@toanchorsuffix{east}% \xdef\corasdiagram@curveout{180}% \xdef\corasdiagram@curvein{0}% \fi \fi } \newcommand{\corasdiagram@newedgecoordname}[1]{% \global\advance\corasdiagram@edgecoordseq by 1\relax \edef#1{coras-edge-\the\corasdiagram@edgecoordseq}% } \newcommand{\corasdiagram@markbordereligible}[3]{% \corasdiagram@endpointbasename{#2}{#1}% \def#3{0}% \ifx#2\@empty \else \edef\corasdiagram@rawplain{#1}% \edef\corasdiagram@baseplain{#2}% \ifx\corasdiagram@rawplain\corasdiagram@baseplain \corasdiagram@getbordernode{\corasdiagram@lookupbordernode}{#2}% \ifx\corasdiagram@lookupbordernode\@empty \else \def#3{1}% \fi \fi \fi } \newcommand{\corasdiagram@makeedgecoord}[2]{% \path coordinate (#1) at #2; } \newcommand{\corasdiagram@setsnappeddirectionalanchor}{% \pgfmathtruncatemacro{\corasdiagram@zerodelta}{abs(\corasdiagram@dx) < 0.02 && abs(\corasdiagram@dy) < 0.02 ? 1 : 0}% \ifnum\corasdiagram@zerodelta=1\relax \xdef\corasdiagram@snappeddirectionalanchor{north}% \else \pgfmathsetmacro{\corasdiagram@borderangle}{atan2(\corasdiagram@dy,\corasdiagram@dx)}% \ifdim\corasdiagram@borderangle pt>157.5pt\relax \xdef\corasdiagram@snappeddirectionalanchor{west}% \else\ifdim\corasdiagram@borderangle pt>112.5pt\relax \xdef\corasdiagram@snappeddirectionalanchor{northwest}% \else\ifdim\corasdiagram@borderangle pt>67.5pt\relax \xdef\corasdiagram@snappeddirectionalanchor{north}% \else\ifdim\corasdiagram@borderangle pt>22.5pt\relax \xdef\corasdiagram@snappeddirectionalanchor{northeast}% \else\ifdim\corasdiagram@borderangle pt>-22.5pt\relax \xdef\corasdiagram@snappeddirectionalanchor{east}% \else\ifdim\corasdiagram@borderangle pt>-67.5pt\relax \xdef\corasdiagram@snappeddirectionalanchor{southeast}% \else\ifdim\corasdiagram@borderangle pt>-112.5pt\relax \xdef\corasdiagram@snappeddirectionalanchor{south}% \else \ifdim\corasdiagram@borderangle pt>-157.5pt\relax \xdef\corasdiagram@snappeddirectionalanchor{southwest}% \else \xdef\corasdiagram@snappeddirectionalanchor{west}% \fi \fi\fi\fi\fi\fi\fi\fi \fi } \newcommand{\corasdiagram@getnodeanchorname}[2]{% \expandafter\ifx\csname corasdiagram@nodeanchorname@#2\endcsname\relax \edef#1{west}% \else \edef#1{\csname corasdiagram@nodeanchorname@#2\endcsname}% \fi } \expandafter\def\csname corasdiagram@nodeanchorname@north\endcsname{north} \expandafter\def\csname corasdiagram@nodeanchorname@northeast\endcsname{north east} \expandafter\def\csname corasdiagram@nodeanchorname@east\endcsname{east} \expandafter\def\csname corasdiagram@nodeanchorname@southeast\endcsname{south east} \expandafter\def\csname corasdiagram@nodeanchorname@south\endcsname{south} \expandafter\def\csname corasdiagram@nodeanchorname@southwest\endcsname{south west} \expandafter\def\csname corasdiagram@nodeanchorname@west\endcsname{west} \expandafter\def\csname corasdiagram@nodeanchorname@northwest\endcsname{north west} \newcommand{\corasdiagram@makeiconbordercoord}[3]{% \corasdiagram@getbordernode{\corasdiagram@bordernodename}{#1}% \path let \p1=(\corasdiagram@bordernodename.center), \p2=(#2.center) in \pgfextra{% \pgfmathsetmacro{\corasdiagram@dx}{\x2-\x1}% \pgfmathsetmacro{\corasdiagram@dy}{\y2-\y1}% \corasdiagram@setsnappeddirectionalanchor };% \corasdiagram@getnodeanchorname{\corasdiagram@nodeanchorname}{\corasdiagram@snappeddirectionalanchor}% \pgf@process{\pgfpointanchor{\corasdiagram@bordernodename}{\corasdiagram@nodeanchorname}}% \edef\corasdiagram@borderx{\the\pgf@x}% \edef\corasdiagram@bordery{\the\pgf@y}% \path coordinate (#3) at (\corasdiagram@borderx,\corasdiagram@bordery); } \newcommand{\corasdiagram@makebordercoord}[3]{% \corasdiagram@getnodeprop{anchorsymbol}{#1}{\corasdiagram@bordersymbol}% \ifx\corasdiagram@bordersymbol\@empty \corasdiagram@getbordernode{\corasdiagram@bordernodename}{#1}% \edef\corasdiagram@borderrefname{#2}% \pgf@process{% \expandafter\pgfpointshapeborder\expandafter{\corasdiagram@bordernodename}{% \expandafter\pgfpointanchor\expandafter{\corasdiagram@borderrefname}{center}% }% }% \edef\corasdiagram@borderx{\the\pgf@x}% \edef\corasdiagram@bordery{\the\pgf@y}% \path coordinate (#3) at (\corasdiagram@borderx,\corasdiagram@bordery); \else \corasdiagram@makeiconbordercoord{#1}{#2}{#3}% \fi } \newcommand{\corasdiagram@applyexactborderanchors}{% \ifx\corasedge@path\@empty \corasdiagram@markbordereligible{\corasedge@rawfrom}{\corasdiagram@linefrombase}{\corasdiagram@applyfrom}% \corasdiagram@markbordereligible{\corasedge@rawto}{\corasdiagram@linetobase}{\corasdiagram@applyto}% \ifnum\corasdiagram@applyfrom=1\relax \def\corasdiagram@applyanchors{1}% \else\ifnum\corasdiagram@applyto=1\relax \def\corasdiagram@applyanchors{1}% \else \def\corasdiagram@applyanchors{0}% \fi\fi \ifnum\corasdiagram@applyanchors=1\relax \corasdiagram@newedgecoordname{\corasdiagram@actualfromcoord}% \corasdiagram@newedgecoordname{\corasdiagram@actualtocoord}% \corasdiagram@makeedgecoord{\corasdiagram@actualfromcoord}{(\corasedge@from)}% \corasdiagram@makeedgecoord{\corasdiagram@actualtocoord}{(\corasedge@to)}% \edef\corasdiagram@fromrefcoord{\corasdiagram@actualtocoord}% \edef\corasdiagram@torefcoord{\corasdiagram@actualfromcoord}% \def\corasdiagram@edgepathhv{-|}% \def\corasdiagram@edgepathvh{|-}% \ifx\corasdiagram@edgepath\corasdiagram@edgepathhv \corasdiagram@newedgecoordname{\corasdiagram@elbowcoord}% \corasdiagram@makeedgecoord{\corasdiagram@elbowcoord}{(\corasedge@from -| \corasedge@to)}% \edef\corasdiagram@fromrefcoord{\corasdiagram@elbowcoord}% \edef\corasdiagram@torefcoord{\corasdiagram@elbowcoord}% \else\ifx\corasdiagram@edgepath\corasdiagram@edgepathvh \corasdiagram@newedgecoordname{\corasdiagram@elbowcoord}% \corasdiagram@makeedgecoord{\corasdiagram@elbowcoord}{(\corasedge@from |- \corasedge@to)}% \edef\corasdiagram@fromrefcoord{\corasdiagram@elbowcoord}% \edef\corasdiagram@torefcoord{\corasdiagram@elbowcoord}% \fi\fi \ifnum\corasdiagram@applyfrom=1\relax \corasdiagram@newedgecoordname{\corasdiagram@frombordercoord}% \corasdiagram@makebordercoord{\corasdiagram@linefrombase}{\corasdiagram@fromrefcoord}{\corasdiagram@frombordercoord}% \edef\corasedge@from{\corasdiagram@frombordercoord}% \fi \ifnum\corasdiagram@applyto=1\relax \corasdiagram@newedgecoordname{\corasdiagram@tobordercoord}% \corasdiagram@makebordercoord{\corasdiagram@linetobase}{\corasdiagram@torefcoord}{\corasdiagram@tobordercoord}% \edef\corasedge@to{\corasdiagram@tobordercoord}% \fi \fi \fi } \newcommand{\corasdiagram@drawcurvededge}{% \corasdiagram@markbordereligible{\corasedge@rawfrom}{\corasdiagram@curvefrombase}{\corasdiagram@applycurvefrom}% \corasdiagram@markbordereligible{\corasedge@rawto}{\corasdiagram@curvetobase}{\corasdiagram@applycurveto}% \ifx\corasdiagram@curvefrombase\@empty \def\corasdiagram@curveavailable{0}% \else\ifx\corasdiagram@curvetobase\@empty \def\corasdiagram@curveavailable{0}% \else \def\corasdiagram@curveavailable{1}% \fi\fi \ifnum\corasdiagram@curveavailable=1\relax \corasdiagram@newedgecoordname{\corasdiagram@curvefromcenter}% \corasdiagram@newedgecoordname{\corasdiagram@curvetocenter}% \corasdiagram@makeedgecoord{\corasdiagram@curvefromcenter}{(\corasedge@from)}% \corasdiagram@makeedgecoord{\corasdiagram@curvetocenter}{(\corasedge@to)}% \path let \p1=(\corasdiagram@curvefromcenter), \p2=(\corasdiagram@curvetocenter) in \pgfextra{% \pgfmathsetmacro{\corasdiagram@dx}{\x2-\x1}% \pgfmathsetmacro{\corasdiagram@dy}{\y2-\y1}% \corasdiagram@setcurveanchorsfromdelta }; \corasdiagram@newedgecoordname{\corasdiagram@curvefirstcontrol}% \corasdiagram@newedgecoordname{\corasdiagram@curvesecondcontrol}% \corasdiagram@newedgecoordname{\corasdiagram@curvefirstborderref}% \corasdiagram@newedgecoordname{\corasdiagram@curvesecondborderref}% \corasdiagram@makeedgecoord{\corasdiagram@curvefirstcontrol}{($(\corasdiagram@curvefromcenter)+(\corasdiagram@curveout:8mm)$)}% \corasdiagram@makeedgecoord{\corasdiagram@curvesecondcontrol}{($(\corasdiagram@curvetocenter)+(\corasdiagram@curvein:8mm)$)}% \corasdiagram@makeedgecoord{\corasdiagram@curvefirstborderref}{($(\corasdiagram@curvefromcenter)+(\corasdiagram@curveout:40mm)$)}% \corasdiagram@makeedgecoord{\corasdiagram@curvesecondborderref}{($(\corasdiagram@curvetocenter)+(\corasdiagram@curvein:40mm)$)}% \edef\corasdiagram@curvefrom{\corasedge@from}% \edef\corasdiagram@curveto{\corasedge@to}% \ifnum\corasdiagram@applycurvefrom=1\relax \corasdiagram@newedgecoordname{\corasdiagram@curvefromborder}% \corasdiagram@makebordercoord{\corasdiagram@curvefrombase}{\corasdiagram@curvefirstborderref}{\corasdiagram@curvefromborder}% \edef\corasdiagram@curvefrom{\corasdiagram@curvefromborder}% \fi \ifnum\corasdiagram@applycurveto=1\relax \corasdiagram@newedgecoordname{\corasdiagram@curvetoborder}% \corasdiagram@makebordercoord{\corasdiagram@curvetobase}{\corasdiagram@curvesecondborderref}{\corasdiagram@curvetoborder}% \edef\corasdiagram@curveto{\corasdiagram@curvetoborder}% \fi \ifx\corasedge@label\@empty \expandafter\draw\expandafter[\corasdiagram@edgeoptions] (\corasdiagram@curvefrom) .. controls (\corasdiagram@curvefirstcontrol) and (\corasdiagram@curvesecondcontrol) .. (\corasdiagram@curveto); \else \edef\corasdiagram@edgelabelfragment{% node[\corasdiagram@edgelabeloptions]{% \unexpanded\expandafter{\corasedge@label}% }% }% \expandafter\draw\expandafter[\corasdiagram@edgeoptions] (\corasdiagram@curvefrom) .. controls (\corasdiagram@curvefirstcontrol) and (\corasdiagram@curvesecondcontrol) .. \corasdiagram@edgelabelfragment (\corasdiagram@curveto); \fi \else \ifx\corasedge@label\@empty \expandafter\draw\expandafter[\corasdiagram@edgeoptions] (\corasedge@from) \corasdiagram@edgepath (\corasedge@to); \else \edef\corasdiagram@edgelabelfragment{% node[\corasdiagram@edgelabeloptions]{% \unexpanded\expandafter{\corasedge@label}% }% }% \expandafter\draw\expandafter[\corasdiagram@edgeoptions] (\corasedge@from) \corasdiagram@edgepath (\corasedge@to) \corasdiagram@edgelabelfragment; \fi \fi } \NewDocumentCommand{\corasedge}{O{}}{% \pgfkeys{/coras/edge/.cd,% from=,% to=,% type=causal,% semantic=,% label=,% pos=.5,% path=,% route=auto,% tikz=,% label options={fill=white,inner sep=1pt},% #1% }% \corasdiagram@normalize\corasedge@tikz \corasdiagram@normalize\corasedge@labeloptions \ifx\corasedge@from\@empty \PackageError{corasdiagram}{Missing `from` key for \string\corasedge}{% Use \string\corasedge[from=,to=,type=