deploy.
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
@@ -169,10 +169,10 @@ one, or handing one to somebody else means taking the folder.</p>
|
||||
beside the page name, is set to <strong>Project</strong> — the root that exists only while a project is open, and
|
||||
that resolves to the folder holding the open project file — and the path field reads <code>.</code>, the root
|
||||
folder itself. Three folders sit at the top, <strong>MachineTool</strong>, <strong>NC</strong> and <strong>Output</strong>, and five files
|
||||
below them: the cutting parameters and the workpiece material, the project file itself at about
|
||||
135 KB, the spindle capability, and a cutter material. The right-hand pane is the explorer's text
|
||||
below them: the cutting parameters and the workpiece material, the project file itself at
|
||||
138.1 KB, the spindle capability, and a cutter material. The right-hand pane is the explorer's text
|
||||
editor, waiting on a file to be given to it.</p>
|
||||
<p><img src="projects-img/project-folder.en.png" alt="The File Explorer showing the open project's folder under the Project root: the folders MachineTool, NC and Output above five files with their sizes, among them the project file at 135.2 KB and four side files named for a cutting parameter set, a workpiece material, a spindle capability and a cutter material, with the empty text editor pane on the right"></p>
|
||||
<p><img src="projects-img/project-folder.en.png" alt="The File Explorer showing the open project's folder under the Project root: the folders MachineTool, NC and Output above five files with their sizes, among them the project file at 138.1 KB and four side files named for a cutting parameter set, a workpiece material, a spindle capability and a cutter material, with the empty text editor pane on the right"></p>
|
||||
<div class="WARNING">
|
||||
<h5>Warning</h5>
|
||||
<p><strong>A Save As into a new folder can produce a project that finds none of its programs.</strong> Save As
|
||||
|
||||
@@ -131,7 +131,7 @@ is placeable anywhere, and <a href="building-a-mission.html">Building a Mission<
|
||||
<td>5</td>
|
||||
<td><strong>Record Meshed Geometry</strong></td>
|
||||
<td>Output</td>
|
||||
<td><code>Cache/<stage>-init.wct</code> — the stock, meshed once; drop this row where the stock is already a recorded mesh</td>
|
||||
<td><code>Cache/<stage>-init.wct</code> — the stock, meshed once. Keep this row whenever the stock is an STL; drop it where the stock is procedural, or is already a recorded mesh (<a href="#the-stage-0-cache-goes-stale-silently">which, and why</a>)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>6</td>
|
||||
@@ -234,12 +234,49 @@ what the run starts from — so <strong>changing the workpiece geometry, its ini
|
||||
Machining Resolution has no effect until the cache is cleared.</strong> Nothing warns you: the run simply
|
||||
reproduces the previous one. After changing any of those three, Reset the stage-0 record (or delete
|
||||
its file) before reading anything into the result.</p>
|
||||
<p><strong>Give a stage a stage-0 record only when the stock costs real time to mesh</strong> — a large mesh or a
|
||||
solid the kernel has to build. Where a stage's stock is itself a recorded mesh, as it is for the
|
||||
second operation in a chained pair, a stage-0 record buys no time at all and freezes the chain: the
|
||||
upstream stage can be re-run all it likes and this one keeps reading the copy it took the first
|
||||
time. There, the previous stage's own end-of-stage file is already the cache, and the stage needs
|
||||
no record above its program.</p>
|
||||
<p><strong>Give a stage a stage-0 record when the stock costs real time to mesh, and not otherwise.</strong> The
|
||||
test is what the workpiece's initial geometry actually is:</p>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Stock geometry</th>
|
||||
<th>Stage-0 record</th>
|
||||
<th>Why</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><strong>An STL of any size that is not trivial</strong> — a CAD export, a scanned blank, anything with more than a few thousand triangles</td>
|
||||
<td><strong>Yes</strong></td>
|
||||
<td>meshing it is a fixed, single-threaded cost paid on every play, and it does not shrink with a shorter program</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>A box, a cylindroid, or another procedural solid</td>
|
||||
<td>No</td>
|
||||
<td>the kernel builds it in moments; the record would cost more than it saves</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>A mesh recorded by an earlier stage</td>
|
||||
<td><strong>No</strong> — see below</td>
|
||||
<td>it is already a cache</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<p>The first row is the case worth spelling out, because the cost does not look like it belongs to the
|
||||
geometry. A stock STL is meshed into the cube tree when the first program plays, so the time lands
|
||||
inside the run and reads as if the NC were slow. It is not: it is a constant. One measured example
|
||||
is a 8.9 MB stock STL whose mesh build was <strong>168 s of every play, unchanged when the program was
|
||||
swapped for a 4.8 KB one</strong> — on a 193 s run, 168 s of it was the stock. Recording that mesh once
|
||||
turns the second and every later play into a file read of a few hundredths of a second.</p>
|
||||
<p>The cost climbs steeply with triangle count, so the finer the tessellation the more a stage-0 record
|
||||
is worth: a 1.17-million-triangle stock at 0.125 mm had still not finished meshing after 268 s.</p>
|
||||
<p>Where a stage's stock is itself a recorded mesh, as it is for the second operation in a chained
|
||||
pair, a stage-0 record buys no time at all and freezes the chain: the upstream stage can be re-run
|
||||
all it likes and this one keeps reading the copy it took the first time. There, the previous
|
||||
stage's own end-of-stage file is already the cache, and the stage needs no record above its program.</p>
|
||||
<p>One thing the record does not do is make a stock that the kernel cannot mesh meshable. The record
|
||||
writes what the build produced; if the build itself fails, there is nothing to write, and the
|
||||
mission fails in the same place on every run.</p>
|
||||
<h2 id="resuming-then-cutting-finer">Resuming, then cutting finer</h2>
|
||||
<p>A record freezes the workpiece <strong>as meshed at the width in force when it ran</strong>. Reading one back
|
||||
does not pin the rest of the run to that width: put a finer Machining Resolution below the record
|
||||
|
||||
|
Before Width: | Height: | Size: 116 KiB After Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 115 KiB After Width: | Height: | Size: 128 KiB |
@@ -144,8 +144,8 @@ is what narrows them, and the first result is highlighted ready for <kbd>Enter</
|
||||
<h2 id="read-a-row">Read a row</h2>
|
||||
<p>Each row shows the command's kind followed by the detail that identifies it, in brackets. Where you
|
||||
can name a command that detail is the title you typed, so a row still says what it is after it has
|
||||
been named: <code>List [Roughing]</code>, <code>NC Code [Face check]</code>. Where you cannot, the command brackets what
|
||||
it holds instead — <code>Program File [NC/facing.ptp]</code>, <code>Machining Resolution [0.25 mm]</code>,
|
||||
been named: <code>List [Roughing]</code>, <code>NC Code [Inline finishing pass]</code>. Where you cannot, the command brackets what
|
||||
it holds instead — <code>Program File [NC/circle.ptp]</code>, <code>Machining Resolution [1 mm]</code>,
|
||||
<code>Collision Detection [On]</code> — so a mission is readable without opening anything.</p>
|
||||
<p>Beside the label sit four buttons — <strong>up</strong>, <strong>down</strong>, <strong>duplicate</strong> and <strong>delete</strong>. Up and down are
|
||||
disabled at the ends of the list. Delete asks first, in a dialog naming the command. Duplicate is a
|
||||
@@ -165,11 +165,12 @@ mission can be grouped by operation rather than left flat.</p>
|
||||
<p>A list carries an optional title, entered on its own node above the embedded editor. The row reads
|
||||
<code>List</code> while the title is empty and <code>List [title]</code> once it says something; a title of nothing but
|
||||
spaces counts as unset. The Mission root is the one list with no title field — it reads <strong>Mission</strong>.</p>
|
||||
<p>The demo mission at <code>/execution?tree=execution/mission</code>: three groups and four loose entries. The
|
||||
tree above shows <strong>List [Setup]</strong> opened, with the three settings commands inside it bracketing
|
||||
their values; the editor below shows the same seven entries as rows. The greyed <strong>Script</strong> row is an
|
||||
entry left in place with its checkbox cleared — part of the mission, and not run.</p>
|
||||
<p><img src="building-a-mission-img/grouped-mission.en.png" alt="The Mission branch of the Control Tree with List Setup expanded over Machining Resolution 0.25 mm, Collision Detection On and Physics On, then NC Optimization Config, List Roughing, List Finishing, NC Code Face check, Post-Execution and a greyed Script Export result row with its checkbox cleared; below it the list editor shows the same seven entries, each with up, down, duplicate and delete buttons, above the line reading that commands run top-down"></p>
|
||||
<p>The demo mission at <code>/execution?tree=execution/mission</code>: two groups and seven loose entries. The
|
||||
tree above shows <strong>List [Roughing]</strong> and <strong>List [Finishing]</strong> opened, with the two Program File
|
||||
entries inside each bracketing their files; the editor below shows the same nine root entries as
|
||||
rows. The greyed <strong>Program File</strong> and <strong>Post-Execution</strong> rows are entries left in place with their
|
||||
checkboxes cleared — part of the mission, and not run.</p>
|
||||
<p><img src="building-a-mission-img/grouped-mission.en.png" alt="The Mission branch of the Control Tree showing Machining Resolution 1 mm and Collision Detection On, then List Roughing expanded over Program File NC/circle.ptp and Program File NC/drill_slot.ptp, List Finishing expanded over Program File NC/side.ptp and Program File NC/slide.ptp, then Program File NC/circle.ptp, NC Code Inline finishing pass, a greyed Program File NC/slide-test-resolution-script.ptp with its checkbox cleared, NC Optimization Config and a greyed Post-Execution with its checkbox cleared; below it the list editor shows the same nine root entries under an Add Command button and a Commands badge reading 9, each row with up, down, duplicate and delete buttons, above the line reading that commands run top-down"></p>
|
||||
<h2 id="reorder-and-move-in-and-out">Reorder, and move in and out</h2>
|
||||
<p>Up and down move an entry within its own list and never change which list owns it. Dragging does
|
||||
more, and where you drop decides which:</p>
|
||||
|
||||
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 119 KiB |
@@ -177,7 +177,7 @@ the cutter was touching there” become one picture rather than two.</p>
|
||||
<p>The column with the demo mission paused and a step selected: Sentence Syntax at the top, the step
|
||||
badge on the bar below it, then Step Properties, CWE and the two simulated cycle charts. The two sensor charts are folded away at the bottom — this project carries no measured data,
|
||||
so nothing is lost by leaving them shut.</p>
|
||||
<p><img src="inspecting-a-step-img/step-info.en.png" alt="The Execution page's Step Info column filled: a Sentence Syntax panel showing an NC block and its parsed form, a group bar carrying a step number badge, a Step Properties list of named values, a CWE panel showing the cut footprint in a small 3D view, and two cycle charts plotting force and moment against spindle angle"></p>
|
||||
<p><img src="inspecting-a-step-img/step-info.en.png" alt="The Execution page's Step Info column filled: a Sentence Syntax panel showing the arc block N0120 G02 I0.0 J11. above its parsed form, a group bar badged step #500, a Step Properties list reading FileNo 1, LineNo 13, FilePath NC/circle.ptp and a Time of four seconds, a CWE panel whose small 3D view draws the cutter's flute contours against an orange contact patch on the workpiece, and two cycle charts carrying X, Y and Z traces of cutting force and spindle moment across a full 0 to 360 degree spindle revolution"></p>
|
||||
<h2 id="choosing-what-step-properties-shows">Choosing what Step Properties shows</h2>
|
||||
<p>Step Properties does not show everything a step carries — it shows what you asked for, out of a much
|
||||
longer list. The small button on that panel's header opens the chooser, beside the list it
|
||||
|
||||
|
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 124 KiB |
@@ -207,10 +207,10 @@ counts sit below it and follow what you type.</p>
|
||||
<p><strong>Nothing is checked while you type.</strong> The text is stored exactly as written, and a mistake in it
|
||||
surfaces when the mission plays it — in <strong>NC Diagnostics</strong>, see
|
||||
<a href="when-something-goes-wrong.html">When Something Goes Wrong</a>.</p>
|
||||
<p>The demo mission's short hand-written pass, at <code>/execution?tree=execution/mission/4</code>. The title
|
||||
<p>The demo mission's short hand-written pass, at <code>/execution?tree=execution/mission/5</code>. The title
|
||||
above the editor is what the row brackets, and the line and character counts below it are the whole
|
||||
of the feedback this editor gives.</p>
|
||||
<p><img src="playing-a-program-img/nc-code.en.png" alt="The NC Code command panel: a Title field reading Face check above a monospace text area holding a short NC program, with line and character counts and the Trim Blank Lines and Clear buttons below it"></p>
|
||||
<p><img src="playing-a-program-img/nc-code.en.png" alt="The NC Code command panel: a Title field reading Inline finishing pass above a monospace text area holding a short NC program, with line and character counts and the Trim Blank Lines and Clear buttons below it"></p>
|
||||
<h2 id="after-it-has-played">After it has played</h2>
|
||||
<p>Every program a session read appears under the <strong>Program</strong> branch, with the passes that went over it
|
||||
and the marks the run left on each line. That is where you see what happened to a line, as opposed
|
||||
|
||||
|
Before Width: | Height: | Size: 88 KiB After Width: | Height: | Size: 96 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 61 KiB |
@@ -205,9 +205,10 @@ transport. The footer along the bottom of the window carries the session's own m
|
||||
<p>The same page with the mission paused part way through. The badge now reads <em>paused</em> in orange, Pause
|
||||
has gone grey, and Stop has joined the live ones — so the bar alone tells you a run is open and held.
|
||||
On the canvas the tool path the run has laid down so far is now drawn over the block, and the tabs
|
||||
under it are counting what the run has reported: this mission trips the collision check, which is
|
||||
what the red line in the footer and the number on <strong>Step Diagnostics</strong> are saying.</p>
|
||||
<p><img src="running-a-simulation-img/transport-paused.en.png" alt="The Execution page with the Control Tree on the left, its Execution item carrying an orange paused badge, the transport row above the editor panel with the pause button greyed and the rest live, the 3D canvas showing the block with the covered tool path drawn over it, and a footer line reporting a collision"></p>
|
||||
under it are counting what the run has reported: <strong>Shell</strong> is badged with the eleven messages the
|
||||
load and the run have written between them and <strong>NC Diagnostics</strong> with the one the parser raised,
|
||||
while <strong>Step Diagnostics</strong> and <strong>NC Manipulation</strong> carry no badge at all.</p>
|
||||
<p><img src="running-a-simulation-img/transport-paused.en.png" alt="The Execution page with the Control Tree on the left, its Execution item carrying an orange paused badge, the transport row above the editor panel with the pause button greyed and the rest live, the 3D canvas showing a gold disc cutter sunk into the top face of the white block on its grey fixture with a single thin green tool path entering from the upper left and dropping to it, and a footer reading Ready"></p>
|
||||
<h2 id="the-keys-and-where-they-stop">The keys, and where they stop</h2>
|
||||
<p><kbd>F5</kbd> to <kbd>F8</kbd> are bound only while the Execution page is the one on screen. On every
|
||||
other page <kbd>F5</kbd> is the browser's own reload, and the same is true here in two cases: when
|
||||
|
||||
|
Before Width: | Height: | Size: 112 KiB After Width: | Height: | Size: 116 KiB |
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 108 KiB |
@@ -152,7 +152,7 @@ add and nothing to look for.</p>
|
||||
<p><strong>NC Optimization Config</strong> is the Optimization category's one command, and it exists so the
|
||||
optimizer's settings sit at a point in the run rather than over all of it. Everything played below
|
||||
it optimizes under those values, and a second one further down re-points them mid-mission.</p>
|
||||
<p>Its own node carries four switches — <strong>Enable Optimization</strong>, <strong>Enable Feedrate Optimization</strong>,
|
||||
<p>Its own node carries five switches. The fifth, <strong>Omit Leading Zero in Output (.348, not 0.348)</strong>, only formats the numbers written out; the other four steer the optimizer — <strong>Enable Optimization</strong>, <strong>Enable Feedrate Optimization</strong>,
|
||||
<strong>Enable Depth Splition</strong> and <strong>Enable Interpolation</strong> — and the values live on five child nodes
|
||||
beneath it:</p>
|
||||
<table>
|
||||
@@ -191,10 +191,11 @@ optimizer is on, which is the first switch on its panel.</p>
|
||||
<p>The command takes no title: its row always reads <strong>NC Optimization Config</strong>. What each quantity
|
||||
means, and why an optimized result can look wrong, is
|
||||
<a href="../../technique/nc-optimization/index.html">NC Optimization</a>.</p>
|
||||
<p>The demo mission's optimizer command, at <code>/execution?tree=execution/mission/1</code>, sitting above the
|
||||
two program groups it governs. The four switches are on the command's own panel; the five value
|
||||
nodes are indented under it in the tree.</p>
|
||||
<p><img src="the-other-commands-img/nc-optimization-config.en.png" alt="The NC Optimization Config command selected in the Mission branch, with Distances, Feedrate, Motion Dynamics, Force and Safety and Compensation child nodes listed beneath it, and the panel below showing the Enable Optimization, Enable Feedrate Optimization, Enable Depth Splition and Enable Interpolation checkboxes"></p>
|
||||
<p>The demo mission's optimizer command, at <code>/execution?tree=execution/mission/7</code>. In this mission it
|
||||
sits below both program groups rather than above them, so the ordering rule at the top of this
|
||||
section is what decides how much of the run it reaches. The five switches are on the command's own
|
||||
panel; the five value nodes are indented under it in the tree.</p>
|
||||
<p><img src="the-other-commands-img/nc-optimization-config.en.png" alt="The NC Optimization Config command selected in the Mission branch, with Distances, Feedrate, Motion Dynamics, Force and Safety and Compensation child nodes listed beneath it, and the panel below showing the Enable Optimization, Enable Feedrate Optimization, Enable Depth Splition and Enable Interpolation checkboxes ticked above an unticked Omit Leading Zero in Output checkbox"></p>
|
||||
<h2 id="writing-out-what-the-run-produced">Writing out what the run produced</h2>
|
||||
<p>The <strong>Output</strong> category holds three commands: <strong>Post-Execution</strong>, <strong>Record Meshed Geometry</strong> and
|
||||
<strong>Export Meshed Geometry (STL)</strong>.</p>
|
||||
@@ -257,7 +258,7 @@ not what can be prepared. The outputs are written in an order of the command's o
|
||||
step files, optimization, the writeback, then the geometry difference — which is not the order the
|
||||
tree lists them in, and which matters only if you are reading their timestamps.</p>
|
||||
<p>The demo mission's Post-Execution command with <strong>Step Files Output</strong> selected, at
|
||||
<code>/execution?tree=execution/mission/5/step-files</code>. Each output is a child node with its own
|
||||
<code>/execution?tree=execution/mission/8/step-files</code>. Each output is a child node with its own
|
||||
checkbox — that tick is what switches the output on — and the template field for the selected one
|
||||
sits in the panel below.</p>
|
||||
<p><img src="the-other-commands-img/post-execution.en.png" alt="The Post-Execution command in the Mission branch with its five child nodes, each carrying its own checkbox, and the Step File Template field in the panel below"></p>
|
||||
|
||||
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
@@ -116,7 +116,7 @@ command has one, under its title.</em></p>
|
||||
not name — a subprogram call nests its callee under the caller. The panel's badge changes from
|
||||
<em>not run yet</em> to <em>run data</em>, and a file the run made more than one pass over takes a <code>×</code> and a
|
||||
count in its tree label.</p>
|
||||
<p><img src="the-program-branch-img/program-after-run.en.png" alt="The same page after the run has finished: the Execution root badge reads finished, the first Program node now reads circle.ptp ×2, the branch panel is badged run data beside 5 files, and the Session Messages tabs carry counts — Shell 10 and NC Diagnostics 7, with Step Diagnostics and NC Manipulation still unbadged"></p>
|
||||
<p><img src="the-program-branch-img/program-after-run.en.png" alt="The same page after the run has finished: the Execution root badge reads finished, the first Program node now reads circle.ptp ×2, the branch panel is badged run data beside 5 files, and the Session Messages tabs carry counts — Shell 11 and NC Diagnostics 7, with Step Diagnostics and NC Manipulation still unbadged"></p>
|
||||
<p><em>The same deep link once the run has finished. <code>circle.ptp ×2</code> is one node holding two passes,
|
||||
because two Program File commands named the same file.</em></p>
|
||||
<div class="IMPORTANT">
|
||||
|
||||
|
Before Width: | Height: | Size: 163 KiB After Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 129 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
@@ -120,7 +120,7 @@ account of itself is on <strong>Shell</strong>.</li>
|
||||
<p>A message about a <code>G</code> word and a message about a move are different problems, and they never share a
|
||||
list. Looking in the wrong one reads as silence.</p>
|
||||
<h2 id="reading-a-row">Reading a row</h2>
|
||||
<p><img src="when-something-goes-wrong-img/nc-diagnostics.en.png" alt="The Execution page with the left and right columns switched off: the canvas above, and below it the Session Messages panel with the NC Diagnostics tab selected. The tab row shows Shell badged 10 and NC Diagnostics badged 7, with Step Diagnostics and NC Manipulation carrying no badge at all. Under a filter toolbar of Severity, Category, a text box, Reset and Export, seven rows are listed: six System rows reading Sys-Init–FileLines with each file and its line count, and one warning row whose anchor column reads Sn 2105, category Unsupported, id Parsing–Unconsumed, text Unconsumed Parsing entries: G02"></p>
|
||||
<p><img src="when-something-goes-wrong-img/nc-diagnostics.en.png" alt="The Execution page with the left and right columns switched off: the canvas above, and below it the Session Messages panel with the NC Diagnostics tab selected. The tab row shows Shell badged 11 and NC Diagnostics badged 7, with Step Diagnostics and NC Manipulation carrying no badge at all. Under a filter toolbar of Severity, Category, a text box, Reset and Export, seven rows are listed: six System rows reading Sys-Init–FileLines with each file and its line count, and one warning row whose anchor column reads Sn 2105, category Unsupported, id Parsing–Unconsumed, text Unconsumed Parsing entries: G02"></p>
|
||||
<p><em>The four lists at <code>/execution</code>, with NC Diagnostics selected. Two of the four tabs carry no badge,
|
||||
which is how an empty sink looks.</em></p>
|
||||
<p>A row carries, left to right, the position it is about, the category, the message's own id, and its
|
||||
|
||||
@@ -178,7 +178,7 @@ failure to draw.</p>
|
||||
<li><a href="mech-builder.html">Mechanism Builder</a> — another of the supporting screens the Page menu lists, for assembling a machine chain</li>
|
||||
<li><a href="../setup/controller.html">Controller</a> — the branch that owns controller setup for a project, and every setting this screen does not exclusively hold</li>
|
||||
<li><a href="../setup/program-zero-alignment.html">Program Zero Alignment</a> — which direction an alignment runs, where program zero sits on the workpiece, and why this screen's table is not the one a run reads</li>
|
||||
<li><a class="xref" href="../../anatomy/legacy-controller.html">Legacy Controller Page</a> — the component behind this page: its seven tabs, the model it edits and the one it does not</li>
|
||||
<li><a class="xref" href="../../anatomy/legacy-controller.html">Legacy Controller Page</a> — the component behind this page: its seven tabs, how an edit commits, and its viewer</li>
|
||||
</ul>
|
||||
|
||||
</article>
|
||||
|
||||