@artooi/ag-ui-web-component 0.49.0 → 0.50.1
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/CHANGELOG.md +175 -1
- package/README.md +25 -14
- package/dist/ag-ui-web-component.bundle.js +168 -125
- package/dist/ag-ui-web-component.bundle.js.map +3 -3
- package/dist/core/ag_ui_chat.d.ts.map +1 -1
- package/dist/index.js +530 -110
- package/dist/index.js.map +2 -2
- package/dist/tools/chat_surface_tools.d.ts +8 -5
- package/dist/tools/chat_surface_tools.d.ts.map +1 -1
- package/dist/ui/placement/collapse_styles.d.ts.map +1 -1
- package/dist/ui/placement/panel_placement.d.ts +15 -1
- package/dist/ui/placement/panel_placement.d.ts.map +1 -1
- package/dist/ui/placement/resize_styles.d.ts.map +1 -1
- package/dist/ui/shell/frame_styles.d.ts.map +1 -1
- package/dist/ui/shell/token_styles.d.ts.map +1 -1
- package/dist/ui/themes/classic_tokens.d.ts.map +1 -1
- package/dist/ui/themes/ledger_styles.d.ts.map +1 -1
- package/dist/ui/themes/ledger_tokens.d.ts.map +1 -1
- package/dist/ui/themes/quiet_styles.d.ts.map +1 -1
- package/dist/ui/themes/soft_styles.d.ts.map +1 -1
- package/dist/ui/themes/soft_tokens.d.ts.map +1 -1
- package/dist/ui/transcript/transcript_styles.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/core/ag_ui_chat.ts +73 -7
- package/src/tools/chat_surface_tools.ts +8 -5
- package/src/ui/placement/collapse_styles.ts +8 -0
- package/src/ui/placement/panel_placement.ts +512 -99
- package/src/ui/placement/resize_styles.ts +9 -0
- package/src/ui/shell/frame_styles.ts +22 -2
- package/src/ui/shell/token_styles.ts +7 -6
- package/src/ui/themes/classic_tokens.ts +1 -0
- package/src/ui/themes/ledger_styles.ts +4 -3
- package/src/ui/themes/ledger_tokens.ts +1 -0
- package/src/ui/themes/quiet_styles.ts +2 -15
- package/src/ui/themes/soft_styles.ts +4 -3
- package/src/ui/themes/soft_tokens.ts +1 -0
- package/src/ui/transcript/transcript_styles.ts +14 -1
- package/src/version.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,178 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.50.1] — 2026-11-09
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **A corner panel a grip placed goes full-bleed on a phone after a move is
|
|
15
|
+
undone.** Under `collapse-to="auto"`, with no spot stated, the sequence of a grip
|
|
16
|
+
on an edge the layout holds, `moveTo` with its announcement, another such grip and
|
|
17
|
+
the undo left an inline `--ag-ui-inset` that read as a host's own, so a phone kept
|
|
18
|
+
it, and the panel stood off the screen by as much as the grip had moved it. It now
|
|
19
|
+
fills the screen with no inline inset, and widening gives the grip's place back.
|
|
20
|
+
An undo also keeps the inset that stands a panel at the start of a window a host
|
|
21
|
+
fills, so the panel rests again once that fill has gone. **A host has nothing to
|
|
22
|
+
do.**
|
|
23
|
+
- **A moved panel under `data-launcher-drag="false"` gives way when a host's size
|
|
24
|
+
stands it off the screen.** Since 0.50.0 such a panel stays where it was moved
|
|
25
|
+
until the next window resize or reopen, and it still does while the reader types.
|
|
26
|
+
A host that then filled the window left it at -524,-144 at 1280x800, its header
|
|
27
|
+
out of reach, until one of those came. Any size that stands it off an edge of the
|
|
28
|
+
screen now hands it to the host's CSS at once, and a host that fills the window
|
|
29
|
+
gets it at 0,0. The stored spot stays for the day the attribute comes off. A size
|
|
30
|
+
that still fits moves nothing. **A host has nothing to do.**
|
|
31
|
+
- **A docked panel a host fills stands at 0,0.** Under `collapse-to="bar"` and
|
|
32
|
+
`"none"`, a panel a host sized to the whole window stood past the top of the window
|
|
33
|
+
by what the resting inset spends: at 1200x760, -24,-65 under the bar, where
|
|
34
|
+
the whole header was out of reach, and -24,-24 under a host's own control. It now
|
|
35
|
+
stands at the start of the room the host left free, moved or not, as a corner panel
|
|
36
|
+
has since 0.50.0, and under `data-launcher-drag="false"` too. While it does the bar
|
|
37
|
+
and the grips go, as they do on a phone, with `ag-ui-bar-height` saying 0 and the
|
|
38
|
+
header's minimise control as the way back, because the strip would draw over the
|
|
39
|
+
composer's foot. The bar comes back when the panel is collapsed, and both when the
|
|
40
|
+
size stops filling. A host that writes that height into its own
|
|
41
|
+
`--ag-ui-viewport-inset-bottom` settles with the bar gone: the panel stays judged
|
|
42
|
+
against the box it filled while the box has only grown by the bar's height on the same
|
|
43
|
+
window, where it would otherwise flip the bar and jump the header every frame. The
|
|
44
|
+
dock's stored spot stays unchanged, and the panel goes back
|
|
45
|
+
to its spot or its dock when the size stops filling. A host's own inline `--ag-ui-inset` stays
|
|
46
|
+
where the host wrote it, and a placement that owns its position is left alone. **A
|
|
47
|
+
host has nothing to do.**
|
|
48
|
+
- **A viewport inset token wider than the card holding an embedded chat adds no
|
|
49
|
+
scroll.** The box the component reads the four `--ag-ui-viewport-inset-*`
|
|
50
|
+
tokens from took its size from them, so a 200px card under a 240px left token
|
|
51
|
+
scrolled by 40px, and the same on the other axis. The tokens read back as
|
|
52
|
+
before, a percentage against the same box. **A host has nothing to do.**
|
|
53
|
+
- **A hidden panel stays where it was moved.** Hiding the element, or anything
|
|
54
|
+
holding it, had it place itself from a box of nothing and write that as its
|
|
55
|
+
inset, so a script reading the panel straight after showing it again found it
|
|
56
|
+
off the screen, until a few frames later it stood at its spot. A window resize
|
|
57
|
+
while hidden, connecting hidden and expanding hidden did the same. None of those
|
|
58
|
+
writes an inset now, and showing the element places it against the window as it
|
|
59
|
+
then is. The stored spot was never touched, and `ag-ui-bar-height` still says 0
|
|
60
|
+
while hidden. **A host has nothing to do.**
|
|
61
|
+
|
|
62
|
+
## [0.50.0] — 2026-11-08
|
|
63
|
+
|
|
64
|
+
### Changed
|
|
65
|
+
|
|
66
|
+
- **The themes demo sets `--ag-ui-header-btn-hover`.** A new control on its
|
|
67
|
+
page draws the header buttons' hover square in a colour you pick. The suite
|
|
68
|
+
now tests that square as a browser without relative colour syntax draws it,
|
|
69
|
+
mixed from the header text, which only a string check saw before. Demo and
|
|
70
|
+
tests only, nothing shipped changes. **A host has nothing to do.**
|
|
71
|
+
|
|
72
|
+
### Fixed
|
|
73
|
+
|
|
74
|
+
- **A corner panel that was moved goes full-bleed on a phone, and stays there.**
|
|
75
|
+
Under `collapse-to="auto"`, a panel moved by its header, its launcher or
|
|
76
|
+
`moveTo` on a wide window kept an inline `--ag-ui-inset` when the window
|
|
77
|
+
narrowed below the small-viewport breakpoint, which held it 8px off two edges
|
|
78
|
+
and past the other two. It now fills the screen, with no inline inset, while
|
|
79
|
+
its launcher stays on the screen for when it is collapsed. A header drag no
|
|
80
|
+
longer moves a panel that is the screen, as `moveTo` already refused to, and its
|
|
81
|
+
cursor stops offering one. The
|
|
82
|
+
place the user put the panel is now kept as they stated it: a window that
|
|
83
|
+
narrows, by any amount, holds the panel inside it without changing the record,
|
|
84
|
+
and widening gives that place back, as a reload already did. A gesture made in
|
|
85
|
+
the narrower window states a new one. **A host has nothing to do.**
|
|
86
|
+
- **A corner panel remembers the corner a resize grip moved.** Under
|
|
87
|
+
`collapse-to="auto"`, growing a moved panel by a grip on its free edges, which
|
|
88
|
+
moves its top-left corner while the layout holds the opposite one, was lost on
|
|
89
|
+
the next reopen or reload: the panel came back at its old top-left, grown away
|
|
90
|
+
from its launcher. It now comes back as it was drawn, a host's maximum included,
|
|
91
|
+
and `resetSize()` keeps the panel where the size came off. The top-left stays as the
|
|
92
|
+
grip left it while the host's own `--ag-ui-width` or `--ag-ui-height` is in force at
|
|
93
|
+
that moment, and the stored spot stays as it was under `data-launcher-drag="false"`.
|
|
94
|
+
**A host has nothing to do.**
|
|
95
|
+
- **`read_chat_surface` reports the page's setting for `draggable`, whatever the
|
|
96
|
+
placement.** A sidebar, embedded, side, page or full panel under `collapse-to="auto"`
|
|
97
|
+
reported `draggable: false` with `movable: false`, so `move_chat` answered that
|
|
98
|
+
the page had turned off moving the panel when the placement owned its position,
|
|
99
|
+
while the same placement under `collapse-to="none"` or `"bar"` reported `true`.
|
|
100
|
+
`draggable` is now `true` for every placement unless the page sets
|
|
101
|
+
`data-launcher-drag="false"`, and whether this panel moves stays in `movable`.
|
|
102
|
+
The refusal names the placement. **A host has nothing to do.**
|
|
103
|
+
- **Every theme's header buttons follow `--ag-ui-header-fg`.** 0.49.0 did this
|
|
104
|
+
for Quiet alone, so the accent recipe still fell short under the others:
|
|
105
|
+
white on a `#3d5afe` header read 1.1 to 1.6:1 at rest under Soft and Ledger,
|
|
106
|
+
and 4.16:1 at rest and 3.75:1 hovered under Classic and code. Once a host sets
|
|
107
|
+
`--ag-ui-header-fg`, the buttons draw in it at full opacity under every theme
|
|
108
|
+
and scheme, and the hover square is the opposite of that text at 18%: that
|
|
109
|
+
pair now reads 5.13:1 at rest and 6.95:1 hovered under all of them. What
|
|
110
|
+
changes for a host that sets it, by theme. Soft: the glyph was the third ink,
|
|
111
|
+
the accent's ink hovered, on a square of `--ag-ui-tint-2`. Ledger: the glyph
|
|
112
|
+
was the third ink, the full ink hovered, on a square of `--ag-ui-hover`.
|
|
113
|
+
Classic and code: the glyph already was the header text, but at 0.85 opacity,
|
|
114
|
+
and the square was 18% white, so under white text it now darkens where it
|
|
115
|
+
lightened. Browsers without relative colour syntax (Firefox 120 to 127,
|
|
116
|
+
Safari 17.5 and 17.6) mix the square from the text itself, as under Quiet, at
|
|
117
|
+
3.75:1 hovered for that pair.
|
|
118
|
+
**`--ag-ui-header-btn-hover`, inert until now under Soft, Ledger, Classic and
|
|
119
|
+
code, works under them**, as it does under Quiet: drawn exactly as given,
|
|
120
|
+
whether or not the header text is set. A host that set it for Quiet and also
|
|
121
|
+
wears one of these themes will now see it. With neither token set, every
|
|
122
|
+
theme's header buttons are exactly as they were, whatever the header colour
|
|
123
|
+
or `--ag-ui-hover`. **No opt-in is needed.** A page's own
|
|
124
|
+
`::part(header-button)` rules still win: a host that wrote one to get here may
|
|
125
|
+
delete it, and should at least delete a `:hover` background of 18% of the text,
|
|
126
|
+
which keeps the glyph at 3.75:1 on a mid-tone accent. A host that sets neither
|
|
127
|
+
token, the Django admin among them, sees no change.
|
|
128
|
+
- **A corner panel a host's own size makes the window stands at 0,0.** A host that
|
|
129
|
+
fills a wide window with `--ag-ui-width` and `--ag-ui-height` found a panel the
|
|
130
|
+
user had moved standing at 8,8 after a window resize, 8px past the right and
|
|
131
|
+
bottom edges. It now exactly fills the window, from the start of whatever the
|
|
132
|
+
viewport inset tokens reserve, as a
|
|
133
|
+
phone's full-bleed panel does, and comes back to where the user put it when the
|
|
134
|
+
host's size drops. A host's own `--ag-ui-inset` rule that already stands the box
|
|
135
|
+
on the screen is left alone. **A host has nothing to do.**
|
|
136
|
+
- **A panel placed only by a resize grip goes full-bleed on a phone.** A grip on
|
|
137
|
+
an edge the layout holds moves an unmoved corner panel without storing a spot,
|
|
138
|
+
and that inline inset stayed on when the window narrowed, which held the panel
|
|
139
|
+
off two edges and past the other two. It now fills the screen with no inline
|
|
140
|
+
inset, and widening gives the place back. An inset the host wrote inline stays
|
|
141
|
+
where the host wrote it. An unmoved panel a host's own size makes the window
|
|
142
|
+
stands at 0,0 as well. **A host has nothing to do.**
|
|
143
|
+
- **`data-launcher-drag="false"` on a moved panel hands it to the host's CSS.**
|
|
144
|
+
Turned on after the user had moved the panel, the attribute left an inline
|
|
145
|
+
inset behind for good, which put the panel off the screen on a phone. Nothing
|
|
146
|
+
moves when it goes on. The next window resize or reopen rests the panel where
|
|
147
|
+
the host's CSS puts it, as a reload under the attribute always did, and on a
|
|
148
|
+
phone that is full-bleed. The stored spot stays, and comes back at the first
|
|
149
|
+
restore after the attribute comes off. **A host has nothing to do.**
|
|
150
|
+
- **Undoing a move after the surface changed leaves everything in agreement.** A
|
|
151
|
+
move undone once the panel had gone from a corner to a sidebar, a side panel, a
|
|
152
|
+
page or a dock wrote the corner's inset back onto the new surface, which pinned
|
|
153
|
+
a sidebar or a page off the screen and took a docked panel off its dock, and
|
|
154
|
+
left the stored spot on the move the reader had just undone. Going the other way
|
|
155
|
+
left a docked panel's stored spot on the move too. The undo now puts both
|
|
156
|
+
records back, in memory and in storage, and leaves the new surface standing where
|
|
157
|
+
its own layout puts it; the spot comes back with the surface it belongs to.
|
|
158
|
+
**A host has nothing to do.**
|
|
159
|
+
- **A moved panel answers a host's size when the size changes.** A change to
|
|
160
|
+
`--ag-ui-width` or `--ag-ui-height` fires no event, so a panel the user had moved
|
|
161
|
+
stayed as the last restore left it until the next window resize or reopen. Reopened
|
|
162
|
+
under a host's size that then dropped, it stood short of its spot, at 716,232 for a
|
|
163
|
+
spot of 376,96, with the stored spot still right; sized up with no reopen, it could
|
|
164
|
+
grow past the top of the window. It now goes back to its spot as the size drops, and
|
|
165
|
+
under a bigger size it stands where a reopen already put it, held on the screen from
|
|
166
|
+
that spot, rather than growing away from the corner the layout held. A window-filling
|
|
167
|
+
size stands it at 0,0 at once, with no resize needed. **A host has nothing to do.**
|
|
168
|
+
- **A moved panel answers a viewport inset token when the token changes.** A page
|
|
169
|
+
that publishes `--ag-ui-viewport-inset-top` from its own `ResizeObserver`, as the
|
|
170
|
+
README recommends, does so after the window's resize event, so the restore that event
|
|
171
|
+
starts read the bar at its old height. Widening a window past the width where the bar
|
|
172
|
+
shrinks left the panel 35px below its spot on the playground, top 224 for a spot of
|
|
173
|
+
189, and narrowing left it under a bar that had grown. It now settles from the token
|
|
174
|
+
as it stands, a frame later, on any of the four viewport inset tokens and however
|
|
175
|
+
late the page writes them. **A host has nothing to do.**
|
|
176
|
+
- **The header's cursor no longer offers a drag that cannot happen.** A panel that
|
|
177
|
+
had become the screen on a narrow window with a mouse, or a docked panel under
|
|
178
|
+
`collapse-to="bar"` or `"none"` that a host's own size had made the window, showed
|
|
179
|
+
`cursor: move` although its header could not move it. The cursor is now `auto` there,
|
|
180
|
+
and stays `move` everywhere the drag is allowed. **A host has nothing to do.**
|
|
181
|
+
|
|
10
182
|
## [0.49.0] — 2026-11-07
|
|
11
183
|
|
|
12
184
|
### Added
|
|
@@ -5048,7 +5220,9 @@ hosts that both arrange the page the way it expects.
|
|
|
5048
5220
|
### Notes
|
|
5049
5221
|
- First release — exercising the automated npm OIDC publish pipeline end-to-end.
|
|
5050
5222
|
|
|
5051
|
-
[Unreleased]: https://github.com/Artui/ag-ui-web-component/compare/v0.
|
|
5223
|
+
[Unreleased]: https://github.com/Artui/ag-ui-web-component/compare/v0.50.1...HEAD
|
|
5224
|
+
[0.50.1]: https://github.com/Artui/ag-ui-web-component/compare/v0.50.0...v0.50.1
|
|
5225
|
+
[0.50.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.49.0...v0.50.0
|
|
5052
5226
|
[0.49.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.48.0...v0.49.0
|
|
5053
5227
|
[0.48.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.47.0...v0.48.0
|
|
5054
5228
|
[0.47.0]: https://github.com/Artui/ag-ui-web-component/compare/v0.46.0...v0.47.0
|
package/README.md
CHANGED
|
@@ -1467,7 +1467,11 @@ the bar's height. The component never writes your CSS, and a custom property can
|
|
|
1467
1467
|
height up to your page (it inherits down, never up), so it hands you a number:
|
|
1468
1468
|
`barHeight` (CSS px, read-only) and an `ag-ui-bar-height` event (the `BAR_HEIGHT_EVENT`
|
|
1469
1469
|
constant, detail `{ height }`) on every change, including a font-size change. Both read `0`
|
|
1470
|
-
where no bar is drawn: under `auto` and `none`,
|
|
1470
|
+
where no bar is drawn: under `auto` and `none`, on a phone while the panel is open, and while your
|
|
1471
|
+
size fills the window with the panel open. If you write the height into
|
|
1472
|
+
`--ag-ui-viewport-inset-bottom`, a panel that fills the box that leaves stays judged against that
|
|
1473
|
+
box once the bar goes and the box grows by the bar's height: it settles with the bar gone and room
|
|
1474
|
+
at its foot. Writing some other share of the height does not settle; publish it to your page as below.
|
|
1471
1475
|
|
|
1472
1476
|
```js
|
|
1473
1477
|
const chat = document.querySelector("ag-ui-chat");
|
|
@@ -1509,6 +1513,13 @@ launcher to drag: the bar and your own control stay where they are.
|
|
|
1509
1513
|
forgetting the stored spot, so a reload opens it there too.
|
|
1510
1514
|
- **Keeping it fixed.** `data-launcher-drag="false"` turns the header drag and `moveTo` off here as
|
|
1511
1515
|
everywhere else, and the panel stays on its dock.
|
|
1516
|
+
- **A host's size that fills the window.** Set `--ag-ui-width` and `--ag-ui-height` to the whole
|
|
1517
|
+
window, with `--ag-ui-max-width` and `--ag-ui-max-height` out of the way (the defaults stop short
|
|
1518
|
+
of it), and the panel stands at the start of the room you left free, whether it was moved or not.
|
|
1519
|
+
The bar and the grips go while it does, as on a phone, with `barHeight` at 0 and the header's
|
|
1520
|
+
minimise control as the way back. The bar comes back when the panel is collapsed, and both when
|
|
1521
|
+
your size stops filling. The stored spot stays, and the panel goes back to it, or to its dock,
|
|
1522
|
+
once your size stops filling. An inline `--ag-ui-inset` of your own stays where you wrote it.
|
|
1512
1523
|
|
|
1513
1524
|
Placements that own their position (`side` and `full` under `bar`, `sidebar` and `embedded`
|
|
1514
1525
|
under `none`) do not move, as without `collapse-to`.
|
|
@@ -3330,7 +3341,8 @@ and set a mid-tone accent, set `--ag-ui-on-accent` yourself. There is no script
|
|
|
3330
3341
|
|
|
3331
3342
|
Quiet draws the header, the launcher and the tool names in the panel's own colours, so a host that
|
|
3332
3343
|
sets only `--ag-ui-accent` gets a neutral header. To put the accent back without leaving Quiet, set
|
|
3333
|
-
the surfaces to the accent and the text on them to a colour that reads on it
|
|
3344
|
+
the surfaces to the accent and the text on them to a colour that reads on it. The same recipe holds
|
|
3345
|
+
under every other theme:
|
|
3334
3346
|
|
|
3335
3347
|
```css
|
|
3336
3348
|
ag-ui-chat {
|
|
@@ -3342,19 +3354,19 @@ ag-ui-chat {
|
|
|
3342
3354
|
}
|
|
3343
3355
|
```
|
|
3344
3356
|
|
|
3345
|
-
- **The header buttons follow `--ag-ui-header-fg
|
|
3346
|
-
0.85 opacity,
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3357
|
+
- **The header buttons follow `--ag-ui-header-fg`, under every theme.** Unset, each theme draws
|
|
3358
|
+
them its own way at 0.85 opacity: Quiet, Soft and Ledger in their third ink, Classic and Code in
|
|
3359
|
+
the header text, each on its own hover square. Once you set the header text they draw in it at
|
|
3360
|
+
full opacity, and the hover square is the opposite of that text at about a fifth (a darker square
|
|
3361
|
+
under white text, a lighter one under dark text), so a hovered button reads at least what your
|
|
3362
|
+
header pair reads. A theme word of your own starts from Quiet, so it holds there too. No
|
|
3363
|
+
`::part(header-button)` rule is needed. The opposite is computed with relative
|
|
3351
3364
|
colour syntax; the browsers without it (see the fallback above) mix the square from the text
|
|
3352
3365
|
itself, which on a mid-tone header can take the hovered glyph under your pair (white on
|
|
3353
3366
|
`#3d5afe`: 3.75:1).
|
|
3354
|
-
- **`--ag-ui-header-btn-hover` sets the hover square outright** under
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
instead, at the cost of contrast on a mid-tone header:
|
|
3367
|
+
- **`--ag-ui-header-btn-hover` sets the hover square outright** under every theme, whether or not
|
|
3368
|
+
the header text is set, and is drawn exactly as given. For a square that lightens under white
|
|
3369
|
+
text instead, at the cost of contrast on a mid-tone header:
|
|
3358
3370
|
|
|
3359
3371
|
```css
|
|
3360
3372
|
ag-ui-chat { --ag-ui-header-btn-hover: color-mix(in srgb, #ffffff 18%, transparent); }
|
|
@@ -3362,8 +3374,7 @@ ag-ui-chat {
|
|
|
3362
3374
|
- **`--ag-ui-tool-fg` colours every tool call**, in a step group as well as in the card displays.
|
|
3363
3375
|
Unset, a grouped call is drawn in the second ink (`--ag-ui-ink-2`) under every theme.
|
|
3364
3376
|
- Pick the pair yourself: `--ag-ui-header-fg` is not derived from the header colour the way
|
|
3365
|
-
`--ag-ui-on-accent` is from the accent.
|
|
3366
|
-
third ink whatever you set.
|
|
3377
|
+
`--ag-ui-on-accent` is from the accent.
|
|
3367
3378
|
|
|
3368
3379
|
#### Overriding a theme, lightest layer first
|
|
3369
3380
|
|