@refrakt-md/skeleton 0.44.0 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/styles/dimensions/metadata.css +23 -1
- package/styles/dimensions/sequence.css +6 -8
- package/styles/layouts/split.css +29 -0
- package/styles/runes/bg.css +6 -0
- package/styles/runes/cast.css +2 -5
- package/styles/runes/howto.css +2 -22
- package/styles/runes/playlist.css +7 -18
- package/styles/runes/pullquote.css +1 -1
- package/styles/runes/recipe.css +3 -22
- package/styles/runes/section.css +2 -0
- package/styles/runes/steps.css +4 -24
- package/styles/runes/track.css +21 -20
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@refrakt-md/skeleton",
|
|
3
3
|
"description": "The structural cascade layer + layer-order contract every refrakt theme builds on — ships `@layer skeleton` and the `@layer skeleton, skin;` order declaration, plus the token-name contract",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.46.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"styles"
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@refrakt-md/types": "0.
|
|
32
|
+
"@refrakt-md/types": "0.46.0"
|
|
33
33
|
},
|
|
34
34
|
"scripts": {
|
|
35
35
|
"build": "tsc"
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* metadata — structure. The zone-layout primitives (bar, definition-list
|
|
1
|
+
/* metadata — structure. The zone-layout primitives (bar, lead, ladder, definition-list) and the
|
|
2
2
|
* visually-hidden label mechanism. [data-zone-layout] is layout-uncontested (no
|
|
3
3
|
* layout file targets it), and a rune overriding these resolves correctly (skin
|
|
4
4
|
* beats skeleton). Spacing values (gap / padding / rhythm margins), borders,
|
|
@@ -10,6 +10,16 @@
|
|
|
10
10
|
display: inline-flex;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
/* The pill (ADR-043 decision 3, WORK-671) — `{% badge %}` and every
|
|
14
|
+
* `status`, `category` or `tag` value: one unbroken unit. Its fill, colour,
|
|
15
|
+
* padding and radius are skin. */
|
|
16
|
+
.rf-badge,
|
|
17
|
+
[data-meta-type="status"],
|
|
18
|
+
[data-meta-type="category"],
|
|
19
|
+
[data-meta-type="tag"] {
|
|
20
|
+
white-space: nowrap;
|
|
21
|
+
}
|
|
22
|
+
|
|
13
23
|
/* ── Layout: bar (SPEC-080) ──
|
|
14
24
|
* Horizontal flex row of fields; wraps by default (`data-wrap="false"` keeps it
|
|
15
25
|
* on one line); a field tagged `data-align="end"` (and everything after it) is
|
|
@@ -35,6 +45,18 @@
|
|
|
35
45
|
align-items: flex-start;
|
|
36
46
|
}
|
|
37
47
|
|
|
48
|
+
/* ── Layout: ladder (SPEC-156 D3) ──
|
|
49
|
+
* A list of peer items in a column, each free to arrange its own inside. A
|
|
50
|
+
* sequenced ladder takes its markers and gutter from the sequence dimension;
|
|
51
|
+
* the unsequenced one is only reset. */
|
|
52
|
+
[data-zone-layout="ladder"]:not([data-sequence]) {
|
|
53
|
+
list-style: none;
|
|
54
|
+
margin: 0;
|
|
55
|
+
padding: 0;
|
|
56
|
+
display: flex;
|
|
57
|
+
flex-direction: column;
|
|
58
|
+
}
|
|
59
|
+
|
|
38
60
|
/* ── Layout: definition-list ──
|
|
39
61
|
* Each row stacks dt over dd; rows flow into auto-fit columns that collapse to a
|
|
40
62
|
* single column on narrow containers without a media-query step. */
|
|
@@ -1,25 +1,23 @@
|
|
|
1
|
-
/* sequence — structure. The
|
|
2
|
-
*
|
|
1
|
+
/* sequence — structure. The list resets, item gutters, the numbered marker box
|
|
2
|
+
* placement (the ordinal is a node, WORK-583), and the connected-timeline geometry
|
|
3
3
|
* (item position/gutter, marker box). The connector *lines* are borders (skin),
|
|
4
4
|
* as are the marker fill / radius / shadow / colour / type — those live in
|
|
5
5
|
* Lumina's dimensions/sequence.css. [data-sequence] is uncontested by layouts and
|
|
6
6
|
* sections, so the split is behavior-preserving. */
|
|
7
7
|
|
|
8
|
-
/* Numbered —
|
|
8
|
+
/* Numbered — the item's ordinal (a `[data-name="ordinal"]` node the engine
|
|
9
|
+
* emits, WORK-583) in a circle to the left of each item */
|
|
9
10
|
[data-sequence="numbered"] {
|
|
10
|
-
counter-reset: sequence;
|
|
11
11
|
list-style: none;
|
|
12
12
|
padding-left: 0;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
[data-sequence="numbered"] > li {
|
|
16
|
-
counter-increment: sequence;
|
|
17
16
|
position: relative;
|
|
18
17
|
padding-left: 2.25rem;
|
|
19
18
|
}
|
|
20
19
|
|
|
21
|
-
[data-sequence="numbered"] > li
|
|
22
|
-
content: counter(sequence);
|
|
20
|
+
[data-sequence="numbered"] > li > [data-name="ordinal"] {
|
|
23
21
|
position: absolute;
|
|
24
22
|
left: 0;
|
|
25
23
|
top: 0.625rem;
|
|
@@ -89,7 +87,7 @@
|
|
|
89
87
|
padding-left: 1.75rem;
|
|
90
88
|
}
|
|
91
89
|
|
|
92
|
-
[data-density="compact"] [data-sequence="numbered"] > li
|
|
90
|
+
[data-density="compact"] [data-sequence="numbered"] > li > [data-name="ordinal"] {
|
|
93
91
|
width: 1.25rem;
|
|
94
92
|
height: 1.25rem;
|
|
95
93
|
}
|
package/styles/layouts/split.css
CHANGED
|
@@ -30,6 +30,20 @@
|
|
|
30
30
|
grid-column: 1;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
/* A split with nothing in its media zone (a testimonial with no avatar) emits no
|
|
34
|
+
* zone at all, and lays out as the content alone rather than in half a row. */
|
|
35
|
+
:is([data-media-position="start"], [data-media-position="end"]):not(
|
|
36
|
+
:has(> [data-section="media"], > [data-name="media"])
|
|
37
|
+
) {
|
|
38
|
+
grid-template-columns: minmax(0, 1fr);
|
|
39
|
+
}
|
|
40
|
+
:is([data-media-position="start"], [data-media-position="end"]):not(
|
|
41
|
+
:has(> [data-section="media"], > [data-name="media"])
|
|
42
|
+
)
|
|
43
|
+
> * {
|
|
44
|
+
grid-column: 1;
|
|
45
|
+
}
|
|
46
|
+
|
|
33
47
|
/* A portrait media zone (a round avatar) takes its portrait's width rather than
|
|
34
48
|
* a share of the row, unless a `media-ratio` asks for one. */
|
|
35
49
|
[data-media-position="start"]:not([data-media-ratio]):has(> [data-media="portrait"]) {
|
|
@@ -180,6 +194,13 @@
|
|
|
180
194
|
grid-column: auto;
|
|
181
195
|
grid-row: auto;
|
|
182
196
|
}
|
|
197
|
+
:is(
|
|
198
|
+
[data-media-position="end"][data-collapse="sm"],
|
|
199
|
+
[data-media-position="end"]:not([data-collapse])
|
|
200
|
+
)
|
|
201
|
+
> :is([data-section="media"], [data-name="media"]) {
|
|
202
|
+
order: 1;
|
|
203
|
+
}
|
|
183
204
|
}
|
|
184
205
|
@container (max-width: 768px) {
|
|
185
206
|
:is([data-media-position="start"], [data-media-position="end"])[data-collapse="md"] {
|
|
@@ -189,6 +210,10 @@
|
|
|
189
210
|
grid-column: auto;
|
|
190
211
|
grid-row: auto;
|
|
191
212
|
}
|
|
213
|
+
[data-media-position="end"][data-collapse="md"]
|
|
214
|
+
> :is([data-section="media"], [data-name="media"]) {
|
|
215
|
+
order: 1;
|
|
216
|
+
}
|
|
192
217
|
}
|
|
193
218
|
@container (max-width: 1024px) {
|
|
194
219
|
:is([data-media-position="start"], [data-media-position="end"])[data-collapse="lg"] {
|
|
@@ -198,4 +223,8 @@
|
|
|
198
223
|
grid-column: auto;
|
|
199
224
|
grid-row: auto;
|
|
200
225
|
}
|
|
226
|
+
[data-media-position="end"][data-collapse="lg"]
|
|
227
|
+
> :is([data-section="media"], [data-name="media"]) {
|
|
228
|
+
order: 1;
|
|
229
|
+
}
|
|
201
230
|
}
|
package/styles/runes/bg.css
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
/* bg — structure. The background/overlay/scrim layer placement (absolute fill +
|
|
2
2
|
* z-index + clip), the content-above-bg stacking, and the video fill. The images,
|
|
3
3
|
* gradients, blur/opacity, overlay tints, and scrim paint are skin. */
|
|
4
|
+
/* The host is the layer's containing block, or the layer would size against
|
|
5
|
+
* the nearest positioned ancestor (often the page). Zero specificity: a rune's
|
|
6
|
+
* own `position` (sticky, absolute) still wins. */
|
|
7
|
+
:where([data-bg]) {
|
|
8
|
+
position: relative;
|
|
9
|
+
}
|
|
4
10
|
[data-name="bg"] {
|
|
5
11
|
position: absolute;
|
|
6
12
|
inset: 0;
|
package/styles/runes/cast.css
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
/* cast — structure. The members list reset, grid
|
|
1
|
+
/* cast — structure. The members list reset, the grid arrangement (the list
|
|
2
|
+
* arrangement is the shared unsequenced ladder, dimensions/metadata.css), name/role
|
|
2
3
|
* block display, empty-body hide, the avatar box (size/crop/display), and the list
|
|
3
4
|
* variant flex. Surface chrome, type, radii, and margins are skin. */
|
|
4
5
|
.rf-cast__items {
|
|
@@ -8,10 +9,6 @@
|
|
|
8
9
|
display: grid;
|
|
9
10
|
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
|
10
11
|
}
|
|
11
|
-
.rf-cast--list .rf-cast__items {
|
|
12
|
-
display: flex;
|
|
13
|
-
flex-direction: column;
|
|
14
|
-
}
|
|
15
12
|
/* SPEC-100: carousel arrangement reuses the shared track (styles/runes/carousel.css,
|
|
16
13
|
* keyed on [data-layout="carousel"] [data-name="items"]); cast only sets its
|
|
17
14
|
* per-slide width. */
|
package/styles/runes/howto.css
CHANGED
|
@@ -1,26 +1,6 @@
|
|
|
1
|
-
/* howto — structure. The
|
|
2
|
-
*
|
|
3
|
-
* grid (+ mobile). The surfaced tools list chrome, the step-number glyph + chrome,
|
|
1
|
+
/* howto — structure. The metadata dense-tile grid (+ mobile). The numbered steps
|
|
2
|
+
* are the sequence dimension's (dimensions/sequence.css, BUG-024). The surfaced tools list chrome, the step-number glyph + chrome,
|
|
4
3
|
* tip callouts, and type/spacing stay skin. */
|
|
5
|
-
.rf-howto__content ol {
|
|
6
|
-
list-style: none;
|
|
7
|
-
counter-reset: howto-step;
|
|
8
|
-
}
|
|
9
|
-
.rf-howto__content ol > li {
|
|
10
|
-
counter-increment: howto-step;
|
|
11
|
-
position: relative;
|
|
12
|
-
}
|
|
13
|
-
.rf-howto__content ol > li::before {
|
|
14
|
-
content: counter(howto-step);
|
|
15
|
-
position: absolute;
|
|
16
|
-
left: 0;
|
|
17
|
-
top: 0.625rem;
|
|
18
|
-
width: 1.5rem;
|
|
19
|
-
height: 1.5rem;
|
|
20
|
-
display: flex;
|
|
21
|
-
align-items: center;
|
|
22
|
-
justify-content: center;
|
|
23
|
-
}
|
|
24
4
|
.rf-howto__metadata {
|
|
25
5
|
grid-template-columns: repeat(auto-fit, minmax(6rem, 1fr));
|
|
26
6
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
/* playlist — structure. The inner-header flex, the tracks list reset +
|
|
2
|
-
*
|
|
3
|
-
*
|
|
1
|
+
/* playlist — structure. The inner-header flex, the tracks list reset + clip, the
|
|
2
|
+
* track-row flex (overriding the sequence dimension's absolute marker, so the
|
|
3
|
+
* ordinal sits in the row, WORK-583), the
|
|
4
|
+
* track-cell flex sizing + ellipsis overflow, the meta hide,
|
|
4
5
|
* the cover aspect, and the narrow-screen column hides. The inset padding + split
|
|
5
6
|
* gaps + chrome + the track-number glyph stay skin. */
|
|
6
7
|
.rf-playlist__content > .rf-playlist__header {
|
|
@@ -9,7 +10,6 @@
|
|
|
9
10
|
}
|
|
10
11
|
.rf-playlist__tracks {
|
|
11
12
|
list-style: none;
|
|
12
|
-
counter-reset: track;
|
|
13
13
|
overflow: hidden;
|
|
14
14
|
}
|
|
15
15
|
.rf-playlist__tracks > li {
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
.rf-playlist__tracks > li > meta {
|
|
21
21
|
display: none;
|
|
22
22
|
}
|
|
23
|
-
.rf-playlist__tracks > li
|
|
23
|
+
.rf-playlist__tracks > li > [data-name="ordinal"] {
|
|
24
24
|
position: static;
|
|
25
25
|
width: auto;
|
|
26
26
|
height: auto;
|
|
@@ -32,17 +32,6 @@
|
|
|
32
32
|
min-width: 0;
|
|
33
33
|
overflow: hidden;
|
|
34
34
|
}
|
|
35
|
-
.rf-playlist__tracks [data-name="track-artist"] {
|
|
36
|
-
flex-shrink: 0;
|
|
37
|
-
}
|
|
38
|
-
.rf-playlist__tracks [data-name="track-duration"] {
|
|
39
|
-
flex-shrink: 0;
|
|
40
|
-
margin-left: auto;
|
|
41
|
-
min-width: 3rem;
|
|
42
|
-
}
|
|
43
|
-
.rf-playlist__tracks [data-name="track-meta"] {
|
|
44
|
-
flex-shrink: 0;
|
|
45
|
-
}
|
|
46
35
|
/* Cover aspect — defaults to square (album convention). Authors override via
|
|
47
36
|
* `frame-aspect="..."`; the engine lands `--frame-aspect` on the media zone
|
|
48
37
|
* (frameTarget defaults to 'media' since playlist has a media section), and
|
|
@@ -54,8 +43,8 @@
|
|
|
54
43
|
aspect-ratio: var(--frame-aspect, 1);
|
|
55
44
|
}
|
|
56
45
|
@media (max-width: 480px) {
|
|
57
|
-
.rf-playlist__tracks [data-
|
|
58
|
-
.rf-playlist__tracks [data-
|
|
46
|
+
.rf-playlist__tracks [data-meta="row"] [data-field="artist"],
|
|
47
|
+
.rf-playlist__tracks [data-meta="row"] [data-field="date"] {
|
|
59
48
|
display: none;
|
|
60
49
|
}
|
|
61
50
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/* pullquote — structure. The relative root (glyph anchor), the decorative-glyph
|
|
2
2
|
* positioning + the per-variant glyph hides + centred glyph re-centre, the
|
|
3
3
|
* centre/right auto-margins, and the float modes (+ responsive). The quote glyph,
|
|
4
|
-
* type, borders
|
|
4
|
+
* type, borders and backgrounds are skin. */
|
|
5
5
|
.rf-pullquote {
|
|
6
6
|
position: relative;
|
|
7
7
|
}
|
package/styles/runes/recipe.css
CHANGED
|
@@ -1,31 +1,12 @@
|
|
|
1
|
-
/* recipe — structure. The content flex column
|
|
2
|
-
*
|
|
3
|
-
*
|
|
1
|
+
/* recipe — structure. The content flex column and the metadata dense-tile grid
|
|
2
|
+
* (+ mobile). The numbered steps are the sequence dimension's
|
|
3
|
+
* (dimensions/sequence.css, BUG-024). The thin-edge inset padding + split gaps,
|
|
4
4
|
* the ingredients list chrome, the step-number glyph + chrome, tip callouts, media
|
|
5
5
|
* radius, and type stay skin. */
|
|
6
6
|
.rf-recipe__content {
|
|
7
7
|
display: flex;
|
|
8
8
|
flex-direction: column;
|
|
9
9
|
}
|
|
10
|
-
.rf-recipe__content ol {
|
|
11
|
-
list-style: none;
|
|
12
|
-
counter-reset: recipe-step;
|
|
13
|
-
}
|
|
14
|
-
.rf-recipe__content ol > li {
|
|
15
|
-
counter-increment: recipe-step;
|
|
16
|
-
position: relative;
|
|
17
|
-
}
|
|
18
|
-
.rf-recipe__content ol > li::before {
|
|
19
|
-
content: counter(recipe-step);
|
|
20
|
-
position: absolute;
|
|
21
|
-
left: 0;
|
|
22
|
-
top: 0.625rem;
|
|
23
|
-
width: 1.5rem;
|
|
24
|
-
height: 1.5rem;
|
|
25
|
-
display: flex;
|
|
26
|
-
align-items: center;
|
|
27
|
-
justify-content: center;
|
|
28
|
-
}
|
|
29
10
|
.rf-recipe__metadata {
|
|
30
11
|
grid-template-columns: repeat(auto-fit, minmax(6rem, 1fr));
|
|
31
12
|
}
|
package/styles/runes/section.css
CHANGED
package/styles/runes/steps.css
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
/* steps — structure. The
|
|
2
|
-
*
|
|
1
|
+
/* steps — structure. The preamble layout and the media-position flip. The step
|
|
2
|
+
* numbers, their box and the list reset are the sequence dimension's
|
|
3
|
+
* (dimensions/sequence.css, BUG-024). All spacing, type, surface, and the badge
|
|
3
4
|
* chrome stay skin (Lumina's styles/runes/steps.css). */
|
|
4
5
|
|
|
5
|
-
.rf-steps {
|
|
6
|
-
counter-reset: step;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
6
|
.rf-steps__preamble {
|
|
10
7
|
flex-direction: column;
|
|
11
8
|
align-items: flex-start;
|
|
12
9
|
}
|
|
13
10
|
|
|
14
|
-
.rf-
|
|
11
|
+
.rf-steps__steps {
|
|
15
12
|
list-style: none;
|
|
16
13
|
}
|
|
17
14
|
|
|
@@ -19,23 +16,6 @@
|
|
|
19
16
|
display: contents;
|
|
20
17
|
}
|
|
21
18
|
|
|
22
|
-
.rf-step {
|
|
23
|
-
counter-increment: step;
|
|
24
|
-
position: relative;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
.rf-step::before {
|
|
28
|
-
content: counter(step);
|
|
29
|
-
position: absolute;
|
|
30
|
-
left: 0;
|
|
31
|
-
top: 0.625rem;
|
|
32
|
-
width: 1.5rem;
|
|
33
|
-
height: 1.5rem;
|
|
34
|
-
display: flex;
|
|
35
|
-
align-items: center;
|
|
36
|
-
justify-content: center;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
19
|
.rf-step h1,
|
|
40
20
|
.rf-step h2,
|
|
41
21
|
.rf-step h3,
|
package/styles/runes/track.css
CHANGED
|
@@ -1,37 +1,40 @@
|
|
|
1
|
-
/* track — structure. The row flex
|
|
2
|
-
*
|
|
1
|
+
/* track — structure. The row flex, the cell flex sizing + ellipsis overflow,
|
|
2
|
+
* the details block (WORK-679: in the row its values are cells of the row, and
|
|
3
|
+
* the duration's push to the end is the bar's own `[data-align="end"]`; as a
|
|
4
|
+
* byline it is a row beneath the name), the description/cue full-row + wrap,
|
|
3
5
|
* the chapter row flex + time auto-push, and the narrow-screen hides. The
|
|
4
|
-
*
|
|
6
|
+
* separator glyphs, type and spacing stay skin. The track number, its box and the
|
|
7
|
+
* rule between tracks are the sequence dimension's (dimensions/sequence.css, BUG-024). */
|
|
5
8
|
.rf-track {
|
|
6
9
|
display: flex;
|
|
7
10
|
align-items: center;
|
|
8
|
-
counter-increment: track;
|
|
9
|
-
}
|
|
10
|
-
.rf-track::before {
|
|
11
|
-
content: counter(track);
|
|
12
|
-
min-width: 1.5rem;
|
|
13
|
-
flex-shrink: 0;
|
|
14
11
|
}
|
|
15
12
|
.rf-track__track-name {
|
|
16
13
|
flex: 1;
|
|
17
14
|
min-width: 0;
|
|
18
15
|
overflow: hidden;
|
|
19
16
|
}
|
|
20
|
-
.rf-
|
|
21
|
-
|
|
17
|
+
.rf-track[data-meta="row"] > .rf-track__details {
|
|
18
|
+
display: contents;
|
|
22
19
|
}
|
|
23
|
-
.rf-
|
|
20
|
+
.rf-track__details > [data-field] {
|
|
24
21
|
flex-shrink: 0;
|
|
25
|
-
|
|
22
|
+
}
|
|
23
|
+
.rf-track[data-meta="row"] > .rf-track__details > [data-field="duration"] {
|
|
26
24
|
min-width: 3rem;
|
|
27
25
|
}
|
|
28
|
-
.rf-
|
|
29
|
-
flex
|
|
26
|
+
.rf-track__heading {
|
|
27
|
+
flex: 1;
|
|
28
|
+
min-width: 0;
|
|
29
|
+
}
|
|
30
|
+
.rf-track__heading > .rf-track__track-name {
|
|
31
|
+
display: block;
|
|
30
32
|
}
|
|
31
33
|
.rf-track__track-description {
|
|
32
34
|
flex-basis: 100%;
|
|
33
35
|
}
|
|
34
|
-
|
|
36
|
+
/* A full-row part (a description, chapters, lyrics) starts a line of its own. */
|
|
37
|
+
.rf-track:has(> .rf-track__track-description, > [data-name="lyrics"], > [data-name="chapters"]) {
|
|
35
38
|
flex-wrap: wrap;
|
|
36
39
|
}
|
|
37
40
|
.rf-track [data-name="lyrics"],
|
|
@@ -46,10 +49,8 @@
|
|
|
46
49
|
margin-left: auto;
|
|
47
50
|
}
|
|
48
51
|
@media (max-width: 480px) {
|
|
49
|
-
.rf-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
.rf-track__track-meta {
|
|
52
|
+
.rf-track[data-meta="row"] [data-field="artist"],
|
|
53
|
+
.rf-track[data-meta="row"] [data-field="date"] {
|
|
53
54
|
display: none;
|
|
54
55
|
}
|
|
55
56
|
}
|