Files
the-biergarten-app/docs/pipeline/diagrams/current/output/class.svg
2026-06-20 22:59:28 -04:00

1 line
71 KiB
XML

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" contentStyleType="text/css" data-diagram-type="CLASS" height="1339px" preserveAspectRatio="none" style="width:3121px;height:1339px;background:#FAFCF9;" version="1.1" viewBox="0 0 3121 1339" width="3121px" zoomAndPan="magnify"><?plantuml 1.2026.3?><defs/><g><rect fill="#FAFCF9" height="1339" style="stroke:none;stroke-width:1;" width="3121" x="0" y="0"/><g class="title" data-source-line="25"><text fill="#28342A" font-family="'Volkhov'" font-size="20" font-weight="700" lengthAdjust="spacing" textLength="443.18" x="1335.8507" y="29.42">The Biergarten Data Pipeline - Class Diagram</text></g><!--class BiergartenPipelineOrchestrator--><g class="entity" data-qualified-name="BiergartenPipelineOrchestrator" data-source-line="27" id="ent0002"><rect fill="#FAFCF9" height="226.508" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="441.7737" x="1536.12" y="53.8"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="441.7737" x="1536.12" y="53.8"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="441.7737" x="1536.12" y="79.528"/><rect fill="none" height="226.508" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="441.7737" x="1536.12" y="53.8"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="201.9644" x="1656.0247" y="72.688">BiergartenPipelineOrchestrator</text><line style="stroke:#547461;stroke-width:0.5;" x1="1537.12" x2="1976.8937" y1="82.028" y2="82.028"/><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1544.12" y="93.642"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="223.0099" x="1555.12" y="99.916">logger_ : std::shared_ptr&lt;ILogger&gt;</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1544.12" y="111.87"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="366.6779" x="1555.12" y="118.144">context_service_ : std::unique_ptr&lt;IEnrichmentService&gt;</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1544.12" y="130.098"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="294.8859" x="1555.12" y="136.372">generator_ : std::unique_ptr&lt;DataGenerator&gt;</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1544.12" y="148.326"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="284.2809" x="1555.12" y="154.6">exporter_ : std::unique_ptr&lt;IExportService&gt;</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1544.12" y="166.554"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="276.4022" x="1555.12" y="172.828">application_options_ : ApplicationOptions</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1544.12" y="184.782"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="366.9547" x="1555.12" y="191.056">generated_breweries_ : std::vector&lt;GeneratedBrewery&gt;</text><line style="stroke:#547461;stroke-width:0.5;" x1="1537.12" x2="1976.8937" y1="199.396" y2="199.396"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1547.12" cy="214.01" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="73.5806" x="1555.12" y="217.284">Run() : bool</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1544.12" y="229.238"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="332.658" x="1555.12" y="235.512">QueryCitiesWithCountries() : std::vector&lt;Location&gt;</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1544.12" y="247.466"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="416.7737" x="1555.12" y="253.74">GenerateBreweries(cities : std::span&lt;const EnrichedCity&gt;) : void</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1544.12" y="265.694"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="118.9687" x="1555.12" y="271.968">LogResults() : void</text></g><!--class LogLevel--><g class="entity" data-qualified-name="LogLevel" data-source-line="40" id="ent0003"><rect fill="#FAFCF9" height="135.368" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="97.144" x="85.44" y="1161.35"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="97.144" x="85.44" y="1161.35"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="97.144" x="85.44" y="1205.306"/><rect fill="none" height="135.368" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="97.144" x="85.44" y="1161.35"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="95.144" x="86.44" y="1180.238">&#171;enumeration&#187;</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="57.2636" x="105.3802" y="1198.466">LogLevel</text><line style="stroke:#547461;stroke-width:0.5;" x1="86.44" x2="181.584" y1="1207.806" y2="1207.806"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="42.1925" x="91.44" y="1225.694">Debug</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="24.3636" x="91.44" y="1243.922">Info</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="34.3736" x="91.44" y="1262.15">Warn</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="31.7487" x="91.44" y="1280.378">Error</text><line style="stroke:#547461;stroke-width:0.5;" x1="86.44" x2="181.584" y1="1288.718" y2="1288.718"/></g><!--class PipelinePhase--><g class="entity" data-qualified-name="PipelinePhase" data-source-line="47" id="ent0004"><rect fill="#FAFCF9" height="190.052" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="193.3283" x="231.34" y="1134.01"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="193.3283" x="231.34" y="1134.01"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="193.3283" x="231.34" y="1177.966"/><rect fill="none" height="190.052" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="193.3283" x="231.34" y="1134.01"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="95.144" x="280.4321" y="1152.898">&#171;enumeration&#187;</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="89.4356" x="283.2864" y="1171.126">PipelinePhase</text><line style="stroke:#547461;stroke-width:0.5;" x1="232.34" x2="423.6683" y1="1180.466" y2="1180.466"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="48.6816" x="237.34" y="1198.354">Startup</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="101.8642" x="237.34" y="1216.582">UserGeneration</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="181.3283" x="237.34" y="1234.81">BreweryAndBeerGeneration</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="125.0097" x="237.34" y="1253.038">CheckinGeneration</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="113.1377" x="237.34" y="1271.266">RatingGeneration</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="113.5472" x="237.34" y="1289.494">FollowGeneration</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="64.3931" x="237.34" y="1307.722">Teardown</text><line style="stroke:#547461;stroke-width:0.5;" x1="232.34" x2="423.6683" y1="1316.062" y2="1316.062"/></g><!--class LogDTO--><g class="entity" data-qualified-name="LogDTO" data-source-line="57" id="ent0005"><rect fill="#FAFCF9" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="164.1286" x="15.94" y="927.75"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="164.1286" x="15.94" y="927.75"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="164.1286" x="15.94" y="953.478"/><rect fill="none" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="164.1286" x="15.94" y="927.75"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="51.8139" x="72.0973" y="946.638">LogDTO</text><line style="stroke:#547461;stroke-width:0.5;" x1="16.94" x2="179.0686" y1="955.978" y2="955.978"/><g data-visibility-modifier="PUBLIC_FIELD"><ellipse cx="26.94" cy="970.592" fill="none" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="97.0657" x="34.94" y="973.866">level : LogLevel</text><g data-visibility-modifier="PUBLIC_FIELD"><ellipse cx="26.94" cy="988.82" fill="none" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="139.1286" x="34.94" y="992.094">phase : PipelinePhase</text><g data-visibility-modifier="PUBLIC_FIELD"><ellipse cx="26.94" cy="1007.048" fill="none" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="131.9748" x="34.94" y="1010.322">message : std::string</text><line style="stroke:#547461;stroke-width:0.5;" x1="16.94" x2="179.0686" y1="1018.662" y2="1018.662"/></g><!--class LogEntry--><g class="entity" data-qualified-name="LogEntry" data-source-line="63" id="ent0006"><rect fill="#FAFCF9" height="153.596" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="353.9828" x="215.02" y="900.41"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="353.9828" x="215.02" y="900.41"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="353.9828" x="215.02" y="926.138"/><rect fill="none" height="153.596" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="353.9828" x="215.02" y="900.41"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="57.8762" x="363.0733" y="919.298">LogEntry</text><line style="stroke:#547461;stroke-width:0.5;" x1="216.02" x2="568.0028" y1="928.638" y2="928.638"/><g data-visibility-modifier="PUBLIC_FIELD"><ellipse cx="226.02" cy="943.252" fill="none" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="328.9828" x="234.02" y="946.526">timestamp : std::chrono::system_clock::time_point</text><g data-visibility-modifier="PUBLIC_FIELD"><ellipse cx="226.02" cy="961.48" fill="none" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="179.2073" x="234.02" y="964.754">origin : std::source_location</text><g data-visibility-modifier="PUBLIC_FIELD"><ellipse cx="226.02" cy="979.708" fill="none" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="162.4842" x="234.02" y="982.982">thread_id : std::thread::id</text><g data-visibility-modifier="PUBLIC_FIELD"><ellipse cx="226.02" cy="997.936" fill="none" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="97.0657" x="234.02" y="1001.21">level : LogLevel</text><g data-visibility-modifier="PUBLIC_FIELD"><ellipse cx="226.02" cy="1016.164" fill="none" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="139.1286" x="234.02" y="1019.438">phase : PipelinePhase</text><g data-visibility-modifier="PUBLIC_FIELD"><ellipse cx="226.02" cy="1034.392" fill="none" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="131.9748" x="234.02" y="1037.666">message : std::string</text><line style="stroke:#547461;stroke-width:0.5;" x1="216.02" x2="568.0028" y1="1046.006" y2="1046.006"/></g><!--class ILogger--><g class="entity" data-qualified-name="ILogger" data-source-line="72" id="ent0007"><rect fill="#FAFCF9" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="218.438" x="710.79" y="369.42"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="218.438" x="710.79" y="369.42"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="218.438" x="710.79" y="413.376"/><rect fill="none" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="218.438" x="710.79" y="369.42"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="71.148" x="784.435" y="388.308">&#171;interface&#187;</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="47.684" x="796.167" y="406.536">ILogger</text><line style="stroke:#547461;stroke-width:0.5;" x1="711.79" x2="928.228" y1="415.876" y2="415.876"/><line style="stroke:#547461;stroke-width:0.5;" x1="711.79" x2="928.228" y1="423.876" y2="423.876"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="721.79" cy="438.49" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="186.0882" x="729.79" y="441.764">Log(payload : LogDTO) : void</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="718.79" y="453.718"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="193.438" x="729.79" y="459.992">DoLog(entry : LogEntry) : void</text></g><!--class LogProducer--><g class="entity" data-qualified-name="LogProducer" data-source-line="77" id="ent0008"><rect fill="#FAFCF9" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="290.0167" x="7" y="648.59"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="290.0167" x="7" y="648.59"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="290.0167" x="7" y="674.318"/><rect fill="none" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="290.0167" x="7" y="648.59"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="83.0307" x="110.493" y="667.478">LogProducer</text><line style="stroke:#547461;stroke-width:0.5;" x1="8" x2="296.0167" y1="676.818" y2="676.818"/><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="15" y="688.432"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="265.0167" x="26" y="694.706">channel_ : BoundedChannel&lt;LogEntry&gt;&amp;</text><line style="stroke:#547461;stroke-width:0.5;" x1="8" x2="296.0167" y1="703.046" y2="703.046"/><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="15" y="714.66"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="192.5179" x="26" y="720.934">DoLog(entry : LogEntry) : void</text></g><!--class LogDispatcher--><g class="entity" data-qualified-name="LogDispatcher" data-source-line="82" id="ent0009"><rect fill="#FAFCF9" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="329.9764" x="332.02" y="639.47"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="329.9764" x="332.02" y="639.47"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="329.9764" x="332.02" y="665.198"/><rect fill="none" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="329.9764" x="332.02" y="639.47"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="94.5561" x="449.7301" y="658.358">LogDispatcher</text><line style="stroke:#547461;stroke-width:0.5;" x1="333.02" x2="660.9964" y1="667.698" y2="667.698"/><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="340.02" y="679.312"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="265.0167" x="351.02" y="685.586">channel_ : BoundedChannel&lt;LogEntry&gt;&amp;</text><line style="stroke:#547461;stroke-width:0.5;" x1="333.02" x2="660.9964" y1="693.926" y2="693.926"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="343.02" cy="708.54" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="72.8876" x="351.02" y="711.814">Run() : void</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="340.02" y="723.768"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="304.9764" x="351.02" y="730.042">ToSpdlogLevel(level) : spdlog::level::level_enum</text></g><!--class IEnrichmentService--><g class="entity" data-qualified-name="IEnrichmentService" data-source-line="88" id="ent0010"><rect fill="#FAFCF9" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="379.3302" x="1015.34" y="378.54"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="379.3302" x="1015.34" y="378.54"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="379.3302" x="1015.34" y="422.496"/><rect fill="none" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="379.3302" x="1015.34" y="378.54"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="71.148" x="1169.4311" y="397.428">&#171;interface&#187;</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="125.692" x="1142.1591" y="415.656">IEnrichmentService</text><line style="stroke:#547461;stroke-width:0.5;" x1="1016.34" x2="1393.6702" y1="424.996" y2="424.996"/><line style="stroke:#547461;stroke-width:0.5;" x1="1016.34" x2="1393.6702" y1="432.996" y2="432.996"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1026.34" cy="447.61" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="354.3302" x="1034.34" y="450.884">GetLocationContext(loc : const Location&amp;) : std::string</text></g><!--class MockEnrichmentService--><g class="entity" data-qualified-name="MockEnrichmentService" data-source-line="92" id="ent0011"><rect fill="#FAFCF9" height="62.456" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="379.3302" x="697.34" y="657.7"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="379.3302" x="697.34" y="657.7"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="379.3302" x="697.34" y="683.428"/><rect fill="none" height="62.456" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="379.3302" x="697.34" y="657.7"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="157.5527" x="808.2288" y="676.588">MockEnrichmentService</text><line style="stroke:#547461;stroke-width:0.5;" x1="698.34" x2="1075.6702" y1="685.928" y2="685.928"/><line style="stroke:#547461;stroke-width:0.5;" x1="698.34" x2="1075.6702" y1="693.928" y2="693.928"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="708.34" cy="708.542" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="354.3302" x="716.34" y="711.816">GetLocationContext(loc : const Location&amp;) : std::string</text></g><!--class WikipediaEnrichmentService--><g class="entity" data-qualified-name="WikipediaEnrichmentService" data-source-line="96" id="ent0012"><rect fill="#FAFCF9" height="117.14" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="422.6147" x="1111.7" y="630.36"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="422.6147" x="1111.7" y="630.36"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="422.6147" x="1111.7" y="656.088"/><rect fill="none" height="117.14" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="422.6147" x="1111.7" y="630.36"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="186.1932" x="1229.9107" y="649.248">WikipediaEnrichmentService</text><line style="stroke:#547461;stroke-width:0.5;" x1="1112.7" x2="1533.3147" y1="658.588" y2="658.588"/><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1119.7" y="670.202"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="238.9101" x="1130.7" y="676.476">client_ : std::unique_ptr&lt;WebClient&gt;</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1119.7" y="688.43"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="397.6147" x="1130.7" y="694.704">extract_cache_ : std::unordered_map&lt;std::string, std::string&gt;</text><line style="stroke:#547461;stroke-width:0.5;" x1="1112.7" x2="1533.3147" y1="703.044" y2="703.044"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1122.7" cy="717.658" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="354.3302" x="1130.7" y="720.932">GetLocationContext(loc : const Location&amp;) : std::string</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1119.7" y="732.886"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="318.5638" x="1130.7" y="739.16">FetchExtract(query : std::string_view) : std::string</text></g><!--class WebClient--><g class="entity" data-qualified-name="WebClient" data-source-line="103" id="ent0013"><rect fill="#FAFCF9" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="335.0342" x="1155.49" y="927.75"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="335.0342" x="1155.49" y="927.75"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="335.0342" x="1155.49" y="971.706"/><rect fill="none" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="335.0342" x="1155.49" y="927.75"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="71.148" x="1287.4331" y="946.638">&#171;interface&#187;</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="68.222" x="1288.8961" y="964.866">WebClient</text><line style="stroke:#547461;stroke-width:0.5;" x1="1156.49" x2="1489.5242" y1="974.206" y2="974.206"/><line style="stroke:#547461;stroke-width:0.5;" x1="1156.49" x2="1489.5242" y1="982.206" y2="982.206"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1166.49" cy="996.82" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="249.8552" x="1174.49" y="1000.094">Get(url : const std::string&amp;) : std::string</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1166.49" cy="1015.048" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="310.0342" x="1174.49" y="1018.322">UrlEncode(value : const std::string&amp;) : std::string</text></g><!--class HttpWebClient--><g class="entity" data-qualified-name="HttpWebClient" data-source-line="108" id="ent0014"><rect fill="#FAFCF9" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="335.0342" x="1155.49" y="1188.69"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="335.0342" x="1155.49" y="1188.69"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="335.0342" x="1155.49" y="1214.418"/><rect fill="none" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="335.0342" x="1155.49" y="1188.69"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="97.5276" x="1274.2433" y="1207.578">HttpWebClient</text><line style="stroke:#547461;stroke-width:0.5;" x1="1156.49" x2="1489.5242" y1="1216.918" y2="1216.918"/><line style="stroke:#547461;stroke-width:0.5;" x1="1156.49" x2="1489.5242" y1="1224.918" y2="1224.918"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1166.49" cy="1239.532" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="249.8552" x="1174.49" y="1242.806">Get(url : const std::string&amp;) : std::string</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1166.49" cy="1257.76" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="310.0342" x="1174.49" y="1261.034">UrlEncode(value : const std::string&amp;) : std::string</text></g><!--class DataGenerator--><g class="entity" data-qualified-name="DataGenerator" data-source-line="113" id="ent0015"><rect fill="#FAFCF9" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="653.8885" x="1430.06" y="369.42"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="653.8885" x="1430.06" y="369.42"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="653.8885" x="1430.06" y="413.376"/><rect fill="none" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="653.8885" x="1430.06" y="369.42"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="71.148" x="1721.4302" y="388.308">&#171;interface&#187;</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="97.062" x="1708.4732" y="406.536">DataGenerator</text><line style="stroke:#547461;stroke-width:0.5;" x1="1431.06" x2="2082.9485" y1="415.876" y2="415.876"/><line style="stroke:#547461;stroke-width:0.5;" x1="1431.06" x2="2082.9485" y1="423.876" y2="423.876"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1441.06" cy="438.49" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="628.8885" x="1449.06" y="441.764">GenerateBrewery(location : const Location&amp;, region_context : const std::string&amp;) : BreweryResult</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1441.06" cy="456.718" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="343.1897" x="1449.06" y="459.992">GenerateUser(locale : const std::string&amp;) : UserResult</text></g><!--class MockGenerator--><g class="entity" data-qualified-name="MockGenerator" data-source-line="118" id="ent0016"><rect fill="#FAFCF9" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="374.5106" x="1569.75" y="639.47"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="374.5106" x="1569.75" y="639.47"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="374.5106" x="1569.75" y="665.198"/><rect fill="none" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="374.5106" x="1569.75" y="639.47"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="101.4686" x="1706.271" y="658.358">MockGenerator</text><line style="stroke:#547461;stroke-width:0.5;" x1="1570.75" x2="1943.2606" y1="667.698" y2="667.698"/><line style="stroke:#547461;stroke-width:0.5;" x1="1570.75" x2="1943.2606" y1="675.698" y2="675.698"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1580.75" cy="690.312" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="236.0966" x="1588.75" y="693.586">GenerateBrewery(...) : BreweryResult</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1580.75" cy="708.54" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="188.4403" x="1588.75" y="711.814">GenerateUser(...) : UserResult</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1577.75" y="723.768"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="349.5106" x="1588.75" y="730.042">DeterministicHash(location : const Location&amp;) : size_t</text></g><!--class LlamaGenerator--><g class="entity" data-qualified-name="LlamaGenerator" data-source-line="124" id="ent0017"><rect fill="#FAFCF9" height="226.508" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="397.138" x="1979.44" y="575.68"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="397.138" x="1979.44" y="575.68"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="397.138" x="1979.44" y="601.408"/><rect fill="none" height="226.508" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="397.138" x="1979.44" y="575.68"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="104.5242" x="2125.7469" y="594.568">LlamaGenerator</text><line style="stroke:#547461;stroke-width:0.5;" x1="1980.44" x2="2375.578" y1="603.908" y2="603.908"/><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1987.44" y="615.522"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="145.1239" x="1998.44" y="621.796">model_ : ModelHandle</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1987.44" y="633.75"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="167.0061" x="1998.44" y="640.024">context_ : ContextHandle</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1987.44" y="651.978"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="372.138" x="1998.44" y="658.252">prompt_formatter_ : std::unique_ptr&lt;IPromptFormatter&gt;</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1987.44" y="670.206"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="365.4283" x="1998.44" y="676.48">prompt_directory_ : std::unique_ptr&lt;IPromptDirectory&gt;</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1987.44" y="688.434"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="123.1442" x="1998.44" y="694.708">rng_ : std::mt19937</text><line style="stroke:#547461;stroke-width:0.5;" x1="1980.44" x2="2375.578" y1="703.048" y2="703.048"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1990.44" cy="717.662" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="236.0966" x="1998.44" y="720.936">GenerateBrewery(...) : BreweryResult</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1990.44" cy="735.89" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="188.4403" x="1998.44" y="739.164">GenerateUser(...) : UserResult</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1987.44" y="751.118"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="285.3309" x="1998.44" y="757.392">Load(model_path : const std::string&amp;) : void</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1987.44" y="769.346"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="122.0454" x="1998.44" y="775.62">Infer(...) : std::string</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="1987.44" y="787.574"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="190.817" x="1998.44" y="793.848">InferFormatted(...) : std::string</text></g><!--class IPromptFormatter--><g class="entity" data-qualified-name="IPromptFormatter" data-source-line="137" id="ent0018"><rect fill="#FAFCF9" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="580.1605" x="1648.93" y="936.87"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="580.1605" x="1648.93" y="936.87"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="580.1605" x="1648.93" y="980.826"/><rect fill="none" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="580.1605" x="1648.93" y="936.87"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="71.148" x="1903.4363" y="955.758">&#171;interface&#187;</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="116.48" x="1880.7703" y="973.986">IPromptFormatter</text><line style="stroke:#547461;stroke-width:0.5;" x1="1649.93" x2="2228.0905" y1="983.326" y2="983.326"/><line style="stroke:#547461;stroke-width:0.5;" x1="1649.93" x2="2228.0905" y1="991.326" y2="991.326"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1659.93" cy="1005.94" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="555.1605" x="1667.93" y="1009.214">Format(system_prompt : std::string_view, user_prompt : std::string_view) : std::string</text></g><!--class Gemma4JinjaPromptFormatter--><g class="entity" data-qualified-name="Gemma4JinjaPromptFormatter" data-source-line="141" id="ent0019"><rect fill="#FAFCF9" height="62.456" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="580.1605" x="1637.93" y="1197.81"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="580.1605" x="1637.93" y="1197.81"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="580.1605" x="1637.93" y="1223.538"/><rect fill="none" height="62.456" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="580.1605" x="1637.93" y="1197.81"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="202.5557" x="1826.7324" y="1216.698">Gemma4JinjaPromptFormatter</text><line style="stroke:#547461;stroke-width:0.5;" x1="1638.93" x2="2217.0905" y1="1226.038" y2="1226.038"/><line style="stroke:#547461;stroke-width:0.5;" x1="1638.93" x2="2217.0905" y1="1234.038" y2="1234.038"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="1648.93" cy="1248.652" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="555.1605" x="1656.93" y="1251.926">Format(system_prompt : std::string_view, user_prompt : std::string_view) : std::string</text></g><!--class IPromptDirectory--><g class="entity" data-qualified-name="IPromptDirectory" data-source-line="145" id="ent0020"><rect fill="#FAFCF9" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="277.1055" x="2286.46" y="936.87"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="277.1055" x="2286.46" y="936.87"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="277.1055" x="2286.46" y="980.826"/><rect fill="none" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="277.1055" x="2286.46" y="936.87"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="71.148" x="2389.4388" y="955.758">&#171;interface&#187;</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="112.49" x="2368.7678" y="973.986">IPromptDirectory</text><line style="stroke:#547461;stroke-width:0.5;" x1="2287.46" x2="2562.5655" y1="983.326" y2="983.326"/><line style="stroke:#547461;stroke-width:0.5;" x1="2287.46" x2="2562.5655" y1="991.326" y2="991.326"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="2297.46" cy="1005.94" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="252.1055" x="2305.46" y="1009.214">Load(key : std::string_view) : std::string</text></g><!--class PromptDirectory--><g class="entity" data-qualified-name="PromptDirectory" data-source-line="149" id="ent0021"><rect fill="#FAFCF9" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="366.6985" x="2252.66" y="1179.58"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="366.6985" x="2252.66" y="1179.58"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="366.6985" x="2252.66" y="1205.308"/><rect fill="none" height="98.912" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="366.6985" x="2252.66" y="1179.58"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="109.2106" x="2381.4039" y="1198.468">PromptDirectory</text><line style="stroke:#547461;stroke-width:0.5;" x1="2253.66" x2="2618.3585" y1="1207.808" y2="1207.808"/><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="2260.66" y="1219.422"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="224.5147" x="2271.66" y="1225.696">prompt_dir_ : std::filesystem::path</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="2260.66" y="1237.65"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="341.6985" x="2271.66" y="1243.924">cache_ : std::unordered_map&lt;std::string, std::string&gt;</text><line style="stroke:#547461;stroke-width:0.5;" x1="2253.66" x2="2618.3585" y1="1252.264" y2="1252.264"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="2263.66" cy="1266.878" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="252.1055" x="2271.66" y="1270.152">Load(key : std::string_view) : std::string</text></g><!--class JsonLoader--><g class="entity" data-qualified-name="JsonLoader" data-source-line="155" id="ent0022"><rect fill="#FAFCF9" height="62.456" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="522.092" x="2118.96" y="387.65"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="522.092" x="2118.96" y="387.65"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="522.092" x="2118.96" y="413.378"/><rect fill="none" height="62.456" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="522.092" x="2118.96" y="387.65"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="75.5861" x="2342.213" y="406.538">JsonLoader</text><line style="stroke:#547461;stroke-width:0.5;" x1="2119.96" x2="2640.052" y1="415.878" y2="415.878"/><line style="stroke:#547461;stroke-width:0.5;" x1="2119.96" x2="2640.052" y1="423.878" y2="423.878"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="2129.96" cy="438.492" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" text-decoration="underline" textLength="497.092" x="2137.96" y="441.766">LoadLocations(filepath : const std::filesystem::path&amp;) : std::vector&lt;Location&gt;</text></g><!--class IExportService--><g class="entity" data-qualified-name="IExportService" data-source-line="159" id="ent0023"><rect fill="#FAFCF9" height="117.14" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="409.0383" x="2676.49" y="360.31"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="409.0383" x="2676.49" y="360.31"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="409.0383" x="2676.49" y="404.266"/><rect fill="none" height="117.14" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="409.0383" x="2676.49" y="360.31"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="71.148" x="2845.4351" y="379.198">&#171;interface&#187;</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="93.786" x="2834.1161" y="397.426">IExportService</text><line style="stroke:#547461;stroke-width:0.5;" x1="2677.49" x2="3084.5283" y1="406.766" y2="406.766"/><line style="stroke:#547461;stroke-width:0.5;" x1="2677.49" x2="3084.5283" y1="414.766" y2="414.766"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="2687.49" cy="429.38" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="100.4677" x="2695.49" y="432.654">Initialize() : void</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="2687.49" cy="447.608" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="384.0383" x="2695.49" y="450.882">ProcessRecord(brewery : const GeneratedBrewery&amp;) : void</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="2687.49" cy="465.836" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="95.8547" x="2695.49" y="469.11">Finalize() : void</text></g><!--class SqliteExportService--><g class="entity" data-qualified-name="SqliteExportService" data-source-line="165" id="ent0024"><rect fill="#FAFCF9" height="262.964" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="451.7415" x="2655.14" y="557.45"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="451.7415" x="2655.14" y="557.45"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="451.7415" x="2655.14" y="583.178"/><rect fill="none" height="262.964" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="451.7415" x="2655.14" y="557.45"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="127.3512" x="2817.3351" y="576.338">SqliteExportService</text><line style="stroke:#547461;stroke-width:0.5;" x1="2656.14" x2="3105.8815" y1="585.678" y2="585.678"/><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="2663.14" y="597.292"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="387.0232" x="2674.14" y="603.566">date_time_provider_ : std::unique_ptr&lt;IDateTimeProvider&gt;</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="2663.14" y="615.52"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="215.2222" x="2674.14" y="621.794">run_timestamp_utc_ : std::string</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="2663.14" y="633.748"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="249.0218" x="2674.14" y="640.022">database_path_ : std::filesystem::path</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="2663.14" y="651.976"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="140.5635" x="2674.14" y="658.25">db_handle_ : sqlite3*</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="2663.14" y="670.204"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="248.1571" x="2674.14" y="676.478">insert_location_stmt_ : sqlite3_stmt*</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="2663.14" y="688.432"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="249.4312" x="2674.14" y="694.706">insert_brewery_stmt_ : sqlite3_stmt*</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="2663.14" y="706.66"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="164.4616" x="2674.14" y="712.934">transaction_open_ : bool</text><g data-visibility-modifier="PRIVATE_FIELD"><rect fill="none" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="2663.14" y="724.888"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="426.7415" x="2674.14" y="731.162">location_cache_ : std::unordered_map&lt;std::string, sqlite3_int64&gt;</text><line style="stroke:#547461;stroke-width:0.5;" x1="2656.14" x2="3105.8815" y1="739.502" y2="739.502"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="2666.14" cy="754.116" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="100.4677" x="2674.14" y="757.39">Initialize() : void</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="2666.14" cy="772.344" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="384.0383" x="2674.14" y="775.618">ProcessRecord(brewery : const GeneratedBrewery&amp;) : void</text><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="2666.14" cy="790.572" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="95.8547" x="2674.14" y="793.846">Finalize() : void</text><g data-visibility-modifier="PRIVATE_METHOD"><rect fill="#F24D5C" height="6" style="stroke:#C82930;stroke-width:1;" width="6" x="2663.14" y="805.8"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="152.6842" x="2674.14" y="812.074">InitializeSchema() : void</text></g><!--class IDateTimeProvider--><g class="entity" data-qualified-name="IDateTimeProvider" data-source-line="180" id="ent0025"><rect fill="#FAFCF9" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="229.2673" x="2766.37" y="936.87"/><rect fill="#EAF0E8" height="46.456" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="229.2673" x="2766.37" y="936.87"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="229.2673" x="2766.37" y="980.826"/><rect fill="none" height="80.684" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="229.2673" x="2766.37" y="936.87"/><text fill="#28342A" font-family="DM Sans" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="71.148" x="2845.4297" y="955.758">&#171;interface&#187;</text><text fill="#28342A" font-family="'DM Sans'" font-size="14" font-style="italic" lengthAdjust="spacing" textLength="120.176" x="2820.9157" y="973.986">IDateTimeProvider</text><line style="stroke:#547461;stroke-width:0.5;" x1="2767.37" x2="2994.6373" y1="983.326" y2="983.326"/><line style="stroke:#547461;stroke-width:0.5;" x1="2767.37" x2="2994.6373" y1="991.326" y2="991.326"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="2777.37" cy="1005.94" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="204.2673" x="2785.37" y="1009.214">GetUtcTimestamp() : std::string</text></g><!--class SystemDateTimeProvider--><g class="entity" data-qualified-name="SystemDateTimeProvider" data-source-line="184" id="ent0026"><rect fill="#FAFCF9" height="62.456" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="229.2673" x="2766.37" y="1197.81"/><rect fill="#EAF0E8" height="28.228" rx="2.5" ry="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="229.2673" x="2766.37" y="1197.81"/><rect fill="#EAF0E8" height="2.5" style="stroke:#EAF0E8;stroke-width:0.5;" width="229.2673" x="2766.37" y="1223.538"/><rect fill="none" height="62.456" rx="2.5" ry="2.5" style="stroke:#547461;stroke-width:0.5;" width="229.2673" x="2766.37" y="1197.81"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="165.4241" x="2798.2916" y="1216.698">SystemDateTimeProvider</text><line style="stroke:#547461;stroke-width:0.5;" x1="2767.37" x2="2994.6373" y1="1226.038" y2="1226.038"/><line style="stroke:#547461;stroke-width:0.5;" x1="2767.37" x2="2994.6373" y1="1234.038" y2="1234.038"/><g data-visibility-modifier="PUBLIC_METHOD"><ellipse cx="2777.37" cy="1248.652" fill="#84BE84" rx="3" ry="3" style="stroke:#038048;stroke-width:1;"/></g><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="204.2673" x="2785.37" y="1251.926">GetUtcTimestamp() : std::string</text></g><!--reverse link BiergartenPipelineOrchestrator to ILogger--><g class="link" data-entity-1="ent0002" data-entity-2="ent0007" data-link-type="composition" data-source-line="189" id="lnk27"><path codeLine="189" d="M1524.2957,222.8584 C1372.3257,259.5784 1177.94,308.48 998.01,360.31 C975.69,366.74 951.96,374.06 929.34,381.29" fill="none" id="BiergartenPipelineOrchestrator-backto-ILogger" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="1535.96,220.04,1529.1884,217.5611,1524.2957,222.8584,1531.0673,225.3373,1535.96,220.04" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="34.0411" x="1164.34" y="325.198">owns</text></g><!--reverse link BiergartenPipelineOrchestrator to IEnrichmentService--><g class="link" data-entity-1="ent0002" data-entity-2="ent0010" data-link-type="composition" data-source-line="190" id="lnk28"><path codeLine="190" d="M1524.7374,273.1775 C1439.7074,311.6575 1358.39,348.46 1292.99,378.06" fill="none" id="BiergartenPipelineOrchestrator-backto-IEnrichmentService" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="1535.67,268.23,1528.5545,267.0596,1524.7374,273.1775,1531.8529,274.348,1535.67,268.23" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="34.0411" x="1432.57" y="325.198">owns</text></g><!--reverse link BiergartenPipelineOrchestrator to DataGenerator--><g class="link" data-entity-1="ent0002" data-entity-2="ent0015" data-link-type="composition" data-source-line="191" id="lnk29"><path codeLine="191" d="M1757.01,292.54 C1757.01,323.62 1757.01,343.74 1757.01,369.1" fill="none" id="BiergartenPipelineOrchestrator-backto-DataGenerator" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="1757.01,280.54,1753.01,286.54,1757.01,292.54,1761.01,286.54,1757.01,280.54" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="34.0411" x="1758.01" y="325.198">owns</text></g><!--reverse link BiergartenPipelineOrchestrator to IExportService--><g class="link" data-entity-1="ent0002" data-entity-2="ent0023" data-link-type="composition" data-source-line="192" id="lnk30"><path codeLine="192" d="M1989.9276,214.78 C2172.9076,252.13 2427.6,305.67 2659.01,360.31 C2664.63,361.63 2670.32,363 2676.07,364.38" fill="none" id="BiergartenPipelineOrchestrator-backto-IExportService" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="1978.17,212.38,1983.2488,217.4992,1989.9276,214.78,1984.8488,209.6608,1978.17,212.38" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="34.0411" x="2512.95" y="325.198">owns</text></g><!--reverse link LogEntry to LogLevel--><g class="link" data-entity-1="ent0006" data-entity-2="ent0003" data-link-type="composition" data-source-line="194" id="lnk31"><path codeLine="194" d="M290.9671,1062.0554 C262.5871,1086.6854 240.83,1106.81 214.01,1134.01 C203.47,1144.69 192.72,1156.56 182.65,1168.17" fill="none" id="LogEntry-backto-LogLevel" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="300.03,1054.19,292.8768,1055.1017,290.9671,1062.0554,298.1203,1061.1436,300.03,1054.19" style="stroke:#628A5B;stroke-width:1;"/></g><!--reverse link LogEntry to PipelinePhase--><g class="link" data-entity-1="ent0006" data-entity-2="ent0004" data-link-type="composition" data-source-line="195" id="lnk32"><path codeLine="195" d="M369.5699,1065.8041 C363.1299,1090.9241 358.87,1107.56 352.13,1133.88" fill="none" id="LogEntry-backto-PipelinePhase" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="372.55,1054.18,367.1853,1058.9987,369.5699,1065.8041,374.9347,1060.9854,372.55,1054.18" style="stroke:#628A5B;stroke-width:1;"/></g><!--reverse link LogDTO to LogLevel--><g class="link" data-entity-1="ent0005" data-entity-2="ent0003" data-link-type="composition" data-source-line="196" id="lnk33"><path codeLine="196" d="M106.7432,1038.8471 C112.2532,1077.0471 118.26,1118.73 124.34,1160.97" fill="none" id="LogDTO-backto-LogLevel" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="105.03,1026.97,101.9276,1033.4796,106.7432,1038.8471,109.8456,1032.3375,105.03,1026.97" style="stroke:#628A5B;stroke-width:1;"/></g><!--reverse link LogDTO to PipelinePhase--><g class="link" data-entity-1="ent0005" data-entity-2="ent0004" data-link-type="composition" data-source-line="197" id="lnk34"><path codeLine="197" d="M151.0271,1035.7989 C178.9371,1066.1189 207.63,1097.28 241.08,1133.61" fill="none" id="LogDTO-backto-PipelinePhase" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="142.9,1026.97,144.0206,1034.0935,151.0271,1035.7989,149.9065,1028.6754,142.9,1026.97" style="stroke:#628A5B;stroke-width:1;"/></g><!--reverse link ILogger to LogProducer--><g class="link" data-entity-1="ent0007" data-entity-2="ent0008" data-link-type="extension" data-source-line="198" id="lnk35"><path codeLine="198" d="M692.6926,439.577 C587.1226,458.507 442.78,492.46 315.01,557.45 C268.64,581.03 223.04,619.17 191.92,648.14" fill="none" id="ILogger-backto-LogProducer" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="710.41,436.4,691.6336,433.6711,693.7516,445.4828,710.41,436.4" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="420.88" y="522.338">implements</text></g><!--link LogProducer to LogEntry--><g class="link" data-entity-1="ent0008" data-entity-2="ent0006" data-link-type="dependency" data-source-line="199" id="lnk36"><path codeLine="199" d="M185.38,729.74 C222.15,773.6 278.3053,840.582 324.2053,895.332" fill="none" id="LogProducer-to-LogEntry" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="#628A5B" points="328.06,899.93,325.3432,890.4633,324.8477,896.0984,319.2126,895.6029,328.06,899.93" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="36.2985" x="301.56" y="865.298">emits</text></g><!--link LogDispatcher to LogEntry--><g class="link" data-entity-1="ent0009" data-entity-2="ent0006" data-link-type="dependency" data-source-line="200" id="lnk37"><path codeLine="200" d="M479.08,738.82 C462.85,783.05 440.7667,843.2772 422.0067,894.4072" fill="none" id="LogDispatcher-to-LogEntry" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="#628A5B" points="419.94,900.04,426.7953,892.9686,421.6623,895.346,419.2849,890.213,419.94,900.04" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="66.857" x="436.1" y="865.298">consumes</text></g><!--reverse link IEnrichmentService to WikipediaEnrichmentService--><g class="link" data-entity-1="ent0010" data-entity-2="ent0012" data-link-type="extension" data-source-line="202" id="lnk38"><path codeLine="202" d="M1229.8004,476.1952 C1249.6304,521.2552 1274.87,578.58 1297.51,630.01" fill="none" id="IEnrichmentService-backto-WikipediaEnrichmentService" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="1222.55,459.72,1224.3087,478.612,1235.2921,473.7784,1222.55,459.72" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="1250.97" y="522.338">implements</text></g><!--reverse link IEnrichmentService to MockEnrichmentService--><g class="link" data-entity-1="ent0010" data-entity-2="ent0011" data-link-type="extension" data-source-line="203" id="lnk39"><path codeLine="203" d="M1143.9776,471.3216 C1079.9676,525.2816 980.85,608.83 923.16,657.46" fill="none" id="IEnrichmentService-backto-MockEnrichmentService" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="1157.74,459.72,1140.1104,466.7341,1147.8448,475.9091,1157.74,459.72" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="1094.07" y="522.338">implements</text></g><!--reverse link WikipediaEnrichmentService to WebClient--><g class="link" data-entity-1="ent0012" data-entity-2="ent0013" data-link-type="composition" data-source-line="204" id="lnk40"><path codeLine="204" d="M1323.01,759.86 C1323.01,812.64 1323.01,877.7 1323.01,927.41" fill="none" id="WikipediaEnrichmentService-backto-WebClient" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="1323.01,747.86,1319.01,753.86,1323.01,759.86,1327.01,753.86,1323.01,747.86" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="34.0411" x="1324.01" y="865.298">owns</text></g><!--reverse link WebClient to HttpWebClient--><g class="link" data-entity-1="ent0013" data-entity-2="ent0014" data-link-type="extension" data-source-line="206" id="lnk41"><path codeLine="206" d="M1323.01,1044.97 C1323.01,1092.12 1323.01,1144.66 1323.01,1188.44" fill="none" id="WebClient-backto-HttpWebClient" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="1323.01,1026.97,1317.01,1044.97,1329.01,1044.97,1323.01,1026.97" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="1324.01" y="1098.898">implements</text></g><!--reverse link DataGenerator to MockGenerator--><g class="link" data-entity-1="ent0015" data-entity-2="ent0016" data-link-type="extension" data-source-line="208" id="lnk42"><path codeLine="208" d="M1757.01,486.73 C1757.01,535.2 1757.01,591.06 1757.01,639.41" fill="none" id="DataGenerator-backto-MockGenerator" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="1757.01,468.73,1751.01,486.73,1763.01,486.73,1757.01,468.73" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="1758.01" y="522.338">implements</text></g><!--reverse link DataGenerator to LlamaGenerator--><g class="link" data-entity-1="ent0015" data-entity-2="ent0017" data-link-type="extension" data-source-line="209" id="lnk43"><path codeLine="209" d="M1848.9235,478.3975 C1895.8835,508.2975 1942.82,538.19 2001.36,575.46" fill="none" id="DataGenerator-backto-LlamaGenerator" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="1833.74,468.73,1845.701,483.4587,1852.146,473.3364,1833.74,468.73" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="1918.42" y="522.338">implements</text></g><!--reverse link LlamaGenerator to IPromptFormatter--><g class="link" data-entity-1="ent0017" data-entity-2="ent0018" data-link-type="composition" data-source-line="211" id="lnk44"><path codeLine="211" d="M2076.2001,811.8723 C2036.7501,859.1323 2001.12,901.81 1972.23,936.42" fill="none" id="LlamaGenerator-backto-IPromptFormatter" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="2083.89,802.66,2076.9743,804.7028,2076.2001,811.8723,2083.1158,809.8294,2083.89,802.66" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="30.044" x="2038.1" y="865.298">uses</text></g><!--reverse link LlamaGenerator to IPromptDirectory--><g class="link" data-entity-1="ent0017" data-entity-2="ent0020" data-link-type="composition" data-source-line="212" id="lnk45"><path codeLine="212" d="M2283.1084,811.7462 C2323.8784,859.0062 2360.81,901.81 2390.68,936.42" fill="none" id="LlamaGenerator-backto-IPromptDirectory" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="2275.27,802.66,2276.1605,809.8159,2283.1084,811.7462,2282.2179,804.5903,2275.27,802.66" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="30.044" x="2331.9" y="865.298">uses</text></g><!--reverse link IPromptFormatter to Gemma4JinjaPromptFormatter--><g class="link" data-entity-1="ent0018" data-entity-2="ent0019" data-link-type="extension" data-source-line="214" id="lnk46"><path codeLine="214" d="M1936.4778,1035.7826 C1934.2778,1085.7226 1931.33,1152.54 1929.35,1197.67" fill="none" id="IPromptFormatter-backto-Gemma4JinjaPromptFormatter" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="1937.27,1017.8,1930.4836,1035.5185,1942.472,1036.0466,1937.27,1017.8" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="1935.17" y="1098.898">implements</text></g><!--reverse link IPromptDirectory to PromptDirectory--><g class="link" data-entity-1="ent0020" data-entity-2="ent0021" data-link-type="extension" data-source-line="215" id="lnk47"><path codeLine="215" d="M2427.5433,1035.7825 C2429.4733,1079.5325 2431.78,1132.05 2433.86,1179.2" fill="none" id="IPromptDirectory-backto-PromptDirectory" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="2426.75,1017.8,2421.5491,1036.0469,2433.5375,1035.5181,2426.75,1017.8" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="2431.51" y="1098.898">implements</text></g><!--link BiergartenPipelineOrchestrator to JsonLoader--><g class="link" data-entity-1="ent0002" data-entity-2="ent0022" data-link-type="dependency" data-source-line="217" id="lnk48"><path codeLine="217" d="M1977.97,256.66 C2091.51,302.19 2217.0509,352.5371 2297.8609,384.9371" fill="none" id="BiergartenPipelineOrchestrator-to-JsonLoader" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="#628A5B" points="2303.43,387.17,2296.565,380.108,2298.7891,385.3093,2293.5878,387.5334,2303.43,387.17" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="30.044" x="2161.71" y="325.198">uses</text></g><!--reverse link IExportService to SqliteExportService--><g class="link" data-entity-1="ent0023" data-entity-2="ent0024" data-link-type="extension" data-source-line="219" id="lnk49"><path codeLine="219" d="M2881.01,495.71 C2881.01,519.1 2881.01,529.14 2881.01,556.99" fill="none" id="IExportService-backto-SqliteExportService" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="2881.01,477.71,2875.01,495.71,2887.01,495.71,2881.01,477.71" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="2882.01" y="522.338">implements</text></g><!--reverse link SqliteExportService to IDateTimeProvider--><g class="link" data-entity-1="ent0024" data-entity-2="ent0025" data-link-type="composition" data-source-line="220" id="lnk50"><path codeLine="220" d="M2881.01,832.5 C2881.01,874.68 2881.01,906.32 2881.01,936.63" fill="none" id="SqliteExportService-backto-IDateTimeProvider" style="stroke:#628A5B;stroke-width:1;"/><polygon fill="#628A5B" points="2881.01,820.5,2877.01,826.5,2881.01,832.5,2885.01,826.5,2881.01,820.5" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="34.0411" x="2882.01" y="865.298">owns</text></g><!--reverse link IDateTimeProvider to SystemDateTimeProvider--><g class="link" data-entity-1="ent0025" data-entity-2="ent0026" data-link-type="extension" data-source-line="221" id="lnk51"><path codeLine="221" d="M2881.01,1035.8 C2881.01,1085.74 2881.01,1152.54 2881.01,1197.67" fill="none" id="IDateTimeProvider-backto-SystemDateTimeProvider" style="stroke:#628A5B;stroke-width:1;stroke-dasharray:7,7;"/><polygon fill="none" points="2881.01,1017.8,2875.01,1035.8,2887.01,1035.8,2881.01,1017.8" style="stroke:#628A5B;stroke-width:1;"/><text fill="#28342A" font-family="'DM Sans'" font-size="14" lengthAdjust="spacing" textLength="76.65" x="2882.01" y="1098.898">implements</text></g><?plantuml-src lLXjKziu4FwUNw7fpN1fALnBwPk7oGma1DgXLmxeyT6Zs4kY8akkB8Uc7F_zLfBjM8wTGg_NBtNGFlkYVTDkisicKgfeGZAzu83_AXRfFE6zhAB4S4LphiTIw3zf0kJHw0Cvfo9xr8uvPz-0FD-j4JNJ79RiVqj-FPFpHsq8oxpph4QQqEXwgcGkug7aKf7VnllZuVXjk-u2ilFcnUxEVflyBi2-KlAc8BxQURF_yg1NeqQSPXcvxH5oq64D8ST0Or0hzCFzyRF3DuPJAgGNfoztN---UewdBNe9MJNqhcwDa1hQZVcEibQvrZNaOWRaW86QKgL1a17Lb9oo53WJGBR8q3fWnEWK3UZrd3-M-1BvKKKpm1IY6dKO2xS8bzCfg904c5fn46GpgY0EKwtstfrOqi328ZGDlkem0pLd4LJuNB0lEJZyeS3Sd2M0MU9GZdKA0gp6DYPpaQCIuF3mDPLej6hNOOcUV9gcd4LKCob2cPfFPbZtbySVtMdT6hpZHC4DA0PPfMWE4LgnTrH23YnYOTHiahDSz1yZSY8bjvB-of4sP1ebN38z6sASjH5dKNLv9zAPuSmjfH-KwlkHbL558ALY3zsTQU8S2Z4gMGoCrBbaiHM2eJc338lAQRFdTsNSaNW2S-1aRmz4dXXjHll0Hdm4atoAttVYIkBdaYg1dqDCSxMKKERBwOncq2hcN6DYvId--eGfKTm9oIQtdTVsHNm03T9m1X6MYNTsXZ_4r3iQIyxbZNTq0LJ5yaROIjCgZxIvvkZYexLcat1xuQ2wkprChVc1VnrBII3Bw1GgdsFWnDINVOZHN1JIDKC6JPEqP8XcIWg9Z8jCGn96N4RNGM1WOIgPq9PBAZPbej8XSuM5mujaS79d2hjIoE8Iv0w2m8RvvzqABG9rHICWHL5ZJAkp8gARHai_fGikQUnqedkzhBkb4zCy8dr7HjAWmVeegDpLcekdIiPv16N3YMPK2E2cw0vCQyJqTYTxfPJ1XWK-GCM8OTLeB9K7AbbMTNN72tcUnhpmTzy6mDQpFGm2Ur1yGbCM3VUkzC1MJn-1Bfl2q3NMFkO5gd5rNz8s7g-6qjtv0-RRgggV9FoINMDgnOosQq3lSePdRVtv4YP3IonRkKsNCA8OcnhUldxOWXEQxjLCU5gtP_2VBcEqZm5Juj2PqFzYkhKF2kSCRXwlgvRgEbrHxEUALyRKnBJOiqa-ANue8Xb3Vqvv3lVYgu9oh7MwDEUN6h3qX_TQT_Ya_hej-cMxMutOKw9WQjxiOhJejAOGvTuxJubvUgm6tdqNWobOlUfPNgFTyEtjxNieBr0r9RPp0RebOO9bcaN7D9kjSOFrDmxLOSs-4quJwXkuHHACcsre7yoFOofY3jveXgIYH6h4LCaarU6LL0dLNKFLgGMDIyoWpXapPQUOnHhEKObnd0fBgmGd-ldRjozU_tGNd-0ZrNSkmSu_wmn_rTTntbaAQtOAIopl7xUX_2xVS5Xh9JXglvWGd3TR-izJakFDkkcT3U48aeJklcVYCssQytyRiEA9AW4wvWgCrJKi7dAxfjpRHavM2NR5EBWh1e7915SIF_pU_8YjxpCf35_b-LkS5R7oxwoqijAplZ5rDLcR5zZeNXyQeqPz5Mfr_3k1cmNbs5tgCywcSMw4e-8PHEYOljk35fLLpVLdm-CTCz6GMFdX_0jd6dopNDnY51UwwLZ9EOix-X0-Bt21gDC2LBIJN8JL01xcEWfRAXWrq0dEmRORh4-EU1BER8EqC6lpYoUMmWHMWgv6z33JYQw1xDyUid3T6Y0E7oB3-SCjfo32-WPPARf_lXOACDQlTWU_CCYkIvQQpj7SX7efK4lCPXYxXgTFEheeuzhlhAvp6xyLcVUMyZlkgcQdonNbv0ouAyOPIpFo1xxK69COHBJ0stq66wVUT_xVvCdMLhL61GHtqknU7Al3zFsP_Rdh8KgzOYmOUzLsQp3LRkcT-ijbiMetuUMP3wvMp7-sjxtzBo0iIJaO5sIzEc5xUx3Sk0C22NE0sbhNW9WapZ7elLxRncKKhrbYF3kw-DitB8zrZGhZbUMqNlgzjauO5Vv8xudkDIRjqg9w4jJWBUZ63EbBRn1jgZI7YC3C1TaQwF9nBg2zrRd8MB9cKF4ZiJ9B6EvLNVMBVAS6JDRKNkVApiRJQVIqFLwUhZQ0zSPAQoh2tT87hQBsVkRf-XS0?></g></svg>