neba 1.3.0 → 1.4.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.
@@ -0,0 +1 @@
1
+ import{jsx as e,jsxs as t,Fragment as i}from"react/jsx-runtime";import*as r from"react";import{useRender as n}from"@base-ui/react/use-render";import{transitionProps as a}from"../../internal/animate";import{MockupCutout as o,defaultNotch as s,elevationFilters as d,finishSlots as h,mockupChrome as l,mockupMetrics as c,resolveOs as u,shellClasses as f}from"../../internal/mockup";import{surfaceSlots as m}from"../../internal/styles";const p="undefined"==typeof document?r.useEffect:r.useLayoutEffect;export const Mockup=r.forwardRef(function({device:g,os:b,hardware:v="monitor",size:w="md",resolution:y,orientation:x="portrait",bezel:k="standard",finish:R="graphite",notch:N,systemUi:z=!0,scroll:$=!1,wallpaper:M,time:j="9:41",width:W,height:B,color:H="primary",elevation:C=0,transition:E,render:L,className:O,style:P,children:S,...F},I){const T=u(g,b),U=N??s(g,T),q="desktop"!==g&&"landscape"===x,A=c({device:g,size:w,resolution:y,orientation:x,bezel:k,hardware:v}),{screen:D,frame:G,body:J,stand:K,base:Q}=A,V=r.useRef(null),[X,Y]=r.useState(null);p(()=>{const e=V.current;if(!e)return;const t=()=>{const t=e.getBoundingClientRect();if(t.width<=0||t.height<=0)return;const i=Math.min(t.width/G.width,t.height/G.height);Y(e=>null!==e&&Math.abs(e-i)<1e-4?e:i)};if(t(),"undefined"==typeof ResizeObserver)return;const i=new ResizeObserver(t);return i.observe(e),()=>i.disconnect()},[G.width,G.height]);const Z=r.useCallback(e=>{V.current=e,"function"==typeof I?I(e):I&&(I.current=e)},[I]),_=z?l({os:T,notch:U,landscape:q,time:j}):{},ee=a(E),te="none"===k,ie=t("div",{className:"neba-mockup-screen relative flex flex-col overflow-hidden",style:{width:D.width,height:D.height,borderRadius:A.screenRadius,background:M??"var(--neba-surface)",boxShadow:te?void 0:"inset 0 0 0 1px var(--n-shell-shade)"},children:[_.top?.node,t("div",{className:"flex min-h-0 flex-1",children:[_.start?.node,e("div",{className:"min-w-0 flex-1 "+($?"overflow-auto":"overflow-hidden"),style:{containerType:"size",containerName:"neba-screen"},children:S})]}),_.bottom?.node,e(o,{notch:U,screen:D,landscape:q})]}),re=["neba-mockup relative block",ee.className,O??""].filter(Boolean).join(" ");return n({render:L,ref:Z,props:{className:re,style:{...m(H,C),...h[R],...ee.style,width:W??(void 0===B?"100%":"auto"),height:B??"auto",aspectRatio:`${G.width} / ${G.height}`,filter:d[C],...P},children:t("div",{className:"absolute top-1/2 left-1/2 flex flex-col items-center",style:{width:G.width,height:G.height,transform:`translate(-50%, -50%) scale(${X??1})`,visibility:null===X?"hidden":void 0},children:[e("div",{className:te?"":f,style:{width:J.width,height:J.height,borderRadius:A.frameRadius,paddingBlock:`${A.bezel.top}px ${A.bezel.bottom}px`,paddingInline:A.bezel.x},children:ie}),K?t(i,{children:[e("div",{"aria-hidden":"true",style:{width:K.neckWidth,height:K.neckHeight,background:"var(--n-shell-shade)",clipPath:"polygon(16% 0, 84% 0, 100% 100%, 0 100%)"}}),e("div",{"aria-hidden":"true",className:f,style:{width:K.footWidth,height:K.footHeight,borderRadius:K.footHeight/2}})]}):null,Q?e("div",{"aria-hidden":"true",className:`relative ${f}`,style:{width:Q.width,height:Q.height,borderRadius:`0 0 ${Math.round(.55*Q.height)}px ${Math.round(.55*Q.height)}px`,clipPath:"polygon(0 0, 100% 0, 98.5% 100%, 1.5% 100%)"},children:e("div",{className:"absolute top-0 left-1/2",style:{width:Q.lipWidth,height:Math.round(.34*Q.height),marginLeft:-Q.lipWidth/2,borderRadius:`0 0 ${Math.round(.2*Q.height)}px ${Math.round(.2*Q.height)}px`,background:"var(--n-shell-shade)"}})}):null]}),...F}})});
@@ -0,0 +1,2 @@
1
+ export { Mockup } from './Mockup';
2
+ export type { MockupProps, NebaMockupBezel, NebaMockupDevice, NebaMockupFinish, NebaMockupHardware, NebaMockupNotch, NebaMockupOrientation, NebaMockupOs, NebaMockupResolution } from './Mockup';
@@ -0,0 +1 @@
1
+ export{Mockup}from"./Mockup";
package/dist/index.d.ts CHANGED
@@ -28,12 +28,14 @@ export * from './components/chip';
28
28
  export * from './components/color-picker';
29
29
  export * from './components/combobox';
30
30
  export * from './components/container';
31
+ export * from './components/data-table';
31
32
  export * from './components/date-picker';
32
33
  export * from './components/date-range-picker';
33
34
  export * from './components/date-time-picker';
34
35
  export * from './components/dialog';
35
36
  export * from './components/divider';
36
37
  export * from './components/drawer';
38
+ export * from './components/empty';
37
39
  export * from './components/file-picker';
38
40
  export * from './components/grid';
39
41
  export * from './components/grid-container';
@@ -42,6 +44,7 @@ export * from './components/icon';
42
44
  export * from './components/icon-button';
43
45
  export * from './components/list';
44
46
  export * from './components/menu';
47
+ export * from './components/mockup';
45
48
  export * from './components/number-field';
46
49
  export * from './components/otp-field';
47
50
  export * from './components/overlay';
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- export*from"./types";export*from"./components/accordion";export*from"./components/alert";export*from"./components/animate-appear";export*from"./components/animate-blink";export*from"./components/animate-fade";export*from"./components/animate-grow";export*from"./components/animate-headline";export*from"./components/animate-lighting";export*from"./components/animate-marquee";export*from"./components/animate-rotate";export*from"./components/animate-slide";export*from"./components/animate-typing";export*from"./components/animate-zoom";export*from"./components/aspect-ratio";export*from"./components/avatar";export*from"./components/badge";export*from"./components/blockquote";export*from"./components/box";export*from"./components/breadcrumb";export*from"./components/button";export*from"./components/button-group";export*from"./components/card";export*from"./components/carousel";export*from"./components/chat-bubble";export*from"./components/checkbox";export*from"./components/chip";export*from"./components/color-picker";export*from"./components/combobox";export*from"./components/container";export*from"./components/date-picker";export*from"./components/date-range-picker";export*from"./components/date-time-picker";export*from"./components/dialog";export*from"./components/divider";export*from"./components/drawer";export*from"./components/file-picker";export*from"./components/grid";export*from"./components/grid-container";export*from"./components/highlight";export*from"./components/icon";export*from"./components/icon-button";export*from"./components/list";export*from"./components/menu";export*from"./components/number-field";export*from"./components/otp-field";export*from"./components/overlay";export*from"./components/pagination";export*from"./components/panes";export*from"./components/pill";export*from"./components/popover";export*from"./components/progress-box";export*from"./components/progress-circular";export*from"./components/progress-linear";export*from"./components/radio-group";export*from"./components/segmented-button";export*from"./components/select";export*from"./components/shortcut";export*from"./components/skeleton";export*from"./components/slider";export*from"./components/spoiler";export*from"./components/statistic";export*from"./components/switch";export*from"./components/table";export*from"./components/tabs";export*from"./components/text-field";export*from"./components/text-link";export*from"./components/time-picker";export*from"./components/timeline";export*from"./components/toast";export*from"./components/toolbar";export*from"./components/tooltip";export*from"./components/tree-view";export*from"./components/typography";
1
+ export*from"./types";export*from"./components/accordion";export*from"./components/alert";export*from"./components/animate-appear";export*from"./components/animate-blink";export*from"./components/animate-fade";export*from"./components/animate-grow";export*from"./components/animate-headline";export*from"./components/animate-lighting";export*from"./components/animate-marquee";export*from"./components/animate-rotate";export*from"./components/animate-slide";export*from"./components/animate-typing";export*from"./components/animate-zoom";export*from"./components/aspect-ratio";export*from"./components/avatar";export*from"./components/badge";export*from"./components/blockquote";export*from"./components/box";export*from"./components/breadcrumb";export*from"./components/button";export*from"./components/button-group";export*from"./components/card";export*from"./components/carousel";export*from"./components/chat-bubble";export*from"./components/checkbox";export*from"./components/chip";export*from"./components/color-picker";export*from"./components/combobox";export*from"./components/container";export*from"./components/data-table";export*from"./components/date-picker";export*from"./components/date-range-picker";export*from"./components/date-time-picker";export*from"./components/dialog";export*from"./components/divider";export*from"./components/drawer";export*from"./components/empty";export*from"./components/file-picker";export*from"./components/grid";export*from"./components/grid-container";export*from"./components/highlight";export*from"./components/icon";export*from"./components/icon-button";export*from"./components/list";export*from"./components/menu";export*from"./components/mockup";export*from"./components/number-field";export*from"./components/otp-field";export*from"./components/overlay";export*from"./components/pagination";export*from"./components/panes";export*from"./components/pill";export*from"./components/popover";export*from"./components/progress-box";export*from"./components/progress-circular";export*from"./components/progress-linear";export*from"./components/radio-group";export*from"./components/segmented-button";export*from"./components/select";export*from"./components/shortcut";export*from"./components/skeleton";export*from"./components/slider";export*from"./components/spoiler";export*from"./components/statistic";export*from"./components/switch";export*from"./components/table";export*from"./components/tabs";export*from"./components/text-field";export*from"./components/text-link";export*from"./components/time-picker";export*from"./components/timeline";export*from"./components/toast";export*from"./components/toolbar";export*from"./components/tooltip";export*from"./components/tree-view";export*from"./components/typography";
@@ -0,0 +1,170 @@
1
+ /**
2
+ * The arithmetic a DataTable is made of.
3
+ *
4
+ * Here rather than in the component for the reason `progress.ts` and `color.ts`
5
+ * are here: none of it is layout and none of it is a class name. Sorting rows,
6
+ * matching a query against them, cutting a page out of the result and working
7
+ * out which twenty of forty thousand rows are actually on screen are four
8
+ * questions with numeric answers, and a component file that also has to draw a
9
+ * resize handle is not where they can be read.
10
+ *
11
+ * `color.ts` is the precedent for a single-consumer file: the test is whether
12
+ * the thing is separable, not whether two components happen to want it. Every
13
+ * function below takes plain values and returns plain values — there is no
14
+ * React in this file, and nothing in it knows what a column is.
15
+ */
16
+ import type { NebaDensity, NebaSize } from '../types';
17
+ /**
18
+ * Row height, in **pixels**, and the one number in the library that has to be a
19
+ * number rather than a class.
20
+ *
21
+ * Virtual scrolling is arithmetic on this value: how far down the list a scroll
22
+ * offset lands, how tall the spacer above the first rendered row is, how many
23
+ * rows fit in the viewport for PageDown. A Tailwind class cannot be added up.
24
+ *
25
+ * The ladder is deliberately below `controlHeightClasses` at every step — 28px
26
+ * at `md` against a Button's 32 — because a DataTable is a hundred rows on one
27
+ * screen and a Table is eight. A row here is the height of the text plus enough
28
+ * air to click, and nothing more; `density` is what takes the last of the air
29
+ * out. A caller who puts a Chip or an Avatar in a cell raises `rowHeight`.
30
+ */
31
+ export declare const dataRowHeights: Record<NebaDensity, Record<NebaSize, number>>;
32
+ /**
33
+ * The header, one step taller than the rows under it.
34
+ *
35
+ * A fixed number rather than "whatever the content measures", because a sticky
36
+ * header over a group row needs an offset to stick the second row at, and a
37
+ * measured one would be a layout read on every scroll frame.
38
+ */
39
+ export declare const dataHeaderHeights: Record<NebaDensity, Record<NebaSize, number>>;
40
+ /**
41
+ * The tick column, and the resize handle's grab area.
42
+ *
43
+ * The tick column is `tickSizeClasses` plus the two padding tracks, rounded to
44
+ * a whole pixel: a column narrower than the box in it clips the focus ring.
45
+ */
46
+ export declare const dataTickWidths: Record<NebaSize, number>;
47
+ /** How wide a column is when neither the caller nor a drag has said. */
48
+ export declare const defaultColumnWidth = 160;
49
+ /** How narrow a drag may make one. Below this the heading is a single letter. */
50
+ export declare const minColumnWidth = 48;
51
+ export type SortDirection = 'asc' | 'desc';
52
+ /** One key of a sort, and which way it runs. */
53
+ export interface SortEntry {
54
+ key: string;
55
+ direction: SortDirection;
56
+ }
57
+ /**
58
+ * The default comparison, for the columns that do not bring one.
59
+ *
60
+ * Empty sorts last in both directions, which is the one asymmetry here and the
61
+ * one every spreadsheet has: a blank is not the smallest value, it is the
62
+ * absence of one, and a descending sort whose first screen is forty blanks has
63
+ * answered the wrong question.
64
+ *
65
+ * Numbers compare as numbers, dates as instants, booleans with `false` first,
66
+ * and everything else through the collator — which is `numeric`, so `item2`
67
+ * comes before `item10` rather than after it.
68
+ */
69
+ export declare function compareValues(a: unknown, b: unknown, collator: Intl.Collator): number;
70
+ /**
71
+ * Sorts by every key at once, first key outermost.
72
+ *
73
+ * The sort is **stable** — `Array.prototype.sort` has been since ES2019 — which
74
+ * is what makes a multi-key sort composable: sorting by name and then adding
75
+ * date to the end of the list leaves rows with the same date in name order,
76
+ * because that is the order they were already in.
77
+ *
78
+ * `comparatorFor` returns `null` for a key no column claims, so a sort left
79
+ * over from a column that has since been removed is skipped rather than
80
+ * throwing.
81
+ */
82
+ export declare function sortRows<T>(rows: readonly T[], sort: readonly SortEntry[], comparatorFor: (key: string) => ((a: T, b: T) => number) | null): T[];
83
+ /**
84
+ * What pressing a heading does, given what the sort already says.
85
+ *
86
+ * Three states rather than two — ascending, descending, unsorted — because the
87
+ * order the rows arrived in is a state a caller cannot get back to by pressing
88
+ * anything if the cycle only has two. This is the opposite of the choice
89
+ * TreeView's single select makes, and for the same reason: there, "nothing
90
+ * chosen" is reachable by pressing something else; here it is not.
91
+ *
92
+ * `additive` is what a Shift-click sets. It keeps the column where it already
93
+ * is in the list rather than moving it to the end, so flipping the second key
94
+ * of a two-key sort does not silently make it the first.
95
+ */
96
+ export declare function nextSort(current: readonly SortEntry[], key: string, additive: boolean): SortEntry[];
97
+ /**
98
+ * A cell value as something a query can be matched against.
99
+ *
100
+ * Case-folded and stripped of combining marks, so `jose` finds `José` and
101
+ * `SEOUL` finds `Seoul`. `NFD` splits an accented letter into the letter and
102
+ * its accent and the range then deletes the accent; a search field is the one
103
+ * place where losing that distinction is the point.
104
+ *
105
+ * A `Date` is deliberately *not* formatted here. What a reader sees in the cell
106
+ * came out of the caller's `render`, and guessing a format the search would
107
+ * agree with is how a table ends up not finding a date that is on the screen —
108
+ * a column that wants its dates searchable gives them a `value`.
109
+ */
110
+ export declare function searchText(value: unknown): string;
111
+ /** Where one page starts and stops, and how many there are. */
112
+ export interface PageBounds {
113
+ /** How many pages the rows come to. Never below `1`. */
114
+ pages: number;
115
+ /** The page actually shown, clamped into range. */
116
+ page: number;
117
+ /** Index of the first row on it. */
118
+ start: number;
119
+ /** One past the last. */
120
+ end: number;
121
+ }
122
+ /**
123
+ * The page arithmetic, with the clamp in it.
124
+ *
125
+ * The clamp is the whole reason this is a function: a filter that cuts a
126
+ * twenty-page table to three leaves the caller's `page` at 14, and a table that
127
+ * answers with an empty screen has told the reader their search found nothing.
128
+ * The page moves to the last one that exists instead.
129
+ */
130
+ export declare function pageBounds(total: number, page: number, pageSize: number): PageBounds;
131
+ /** Which rows are rendered, and how much empty space stands in for the rest. */
132
+ export interface VirtualWindow {
133
+ /** Index of the first row rendered. */
134
+ start: number;
135
+ /** One past the last. */
136
+ end: number;
137
+ /** The height of the spacer row above, in pixels. */
138
+ before: number;
139
+ /** And of the one below. */
140
+ after: number;
141
+ }
142
+ /**
143
+ * The rows a scroll offset puts on screen, plus a margin either side.
144
+ *
145
+ * Two spacer rows rather than a translated `<tbody>`: a transform on the body
146
+ * of a table breaks `position: sticky` on the header above it, and the library
147
+ * has a rule about transforms anyway. Padding is also what keeps the scrollbar
148
+ * honest — the scroll height is the real one, so dragging the thumb to the
149
+ * middle lands in the middle of the data.
150
+ *
151
+ * `viewport` of `0` is the first render, before anything has been measured. It
152
+ * cannot mean "no rows" — the layout effect that measures runs after a render
153
+ * and there would be nothing to measure — so it renders a screen's worth on
154
+ * spec and corrects before the frame is painted.
155
+ */
156
+ export declare function virtualWindow(scrollTop: number, viewport: number, rowHeight: number, count: number, overscan: number): VirtualWindow;
157
+ /**
158
+ * Every key between two, inclusive, in the order the rows are currently in.
159
+ *
160
+ * "Currently" is the point: a Shift-click selects what the reader can see
161
+ * between the two rows they clicked, so the range is taken from the sorted,
162
+ * filtered order rather than from the order `items` arrived in. Which of the
163
+ * two keys is the anchor does not matter — dragging up selects the same rows as
164
+ * dragging down.
165
+ *
166
+ * A key that is no longer in the list (a row the current filter hides) yields
167
+ * an empty range rather than a range from one end, which is what an index of
168
+ * `-1` would silently produce.
169
+ */
170
+ export declare function keysBetween(order: readonly string[], from: string, to: string): string[];
@@ -0,0 +1 @@
1
+ export const dataRowHeights={default:{xs:24,sm:28,md:32,lg:38,xl:44},compact:{xs:20,sm:24,md:28,lg:32,xl:38}};export const dataHeaderHeights={default:{xs:28,sm:32,md:36,lg:42,xl:48},compact:{xs:24,sm:28,md:32,lg:36,xl:42}};export const dataTickWidths={xs:30,sm:34,md:38,lg:42,xl:50};export const defaultColumnWidth=160;export const minColumnWidth=48;export function compareValues(t,e,n){const o=null==t||""===t,r=null==e||""===e;return o||r?o&&r?0:o?1:-1:"number"==typeof t&&"number"==typeof e?Number.isNaN(t)||Number.isNaN(e)?Number.isNaN(t)&&Number.isNaN(e)?0:Number.isNaN(t)?1:-1:t-e:"boolean"==typeof t&&"boolean"==typeof e?Number(t)-Number(e):t instanceof Date&&e instanceof Date?t.getTime()-e.getTime():n.compare(String(t),String(e))}export function sortRows(t,e,n){if(0===e.length)return t;const o=e.map(t=>{const e=n(t.key);return e?{compare:e,sign:"desc"===t.direction?-1:1}:null}).filter(t=>null!==t);return 0===o.length?t:[...t].sort((t,e)=>{for(const n of o){const o=n.compare(t,e);if(0!==o)return o*n.sign}return 0})}export function nextSort(t,e,n){const o=t.find(t=>t.key===e),r=void 0===o?"asc":"asc"===o.direction?"desc":null;return n?null===r?t.filter(t=>t.key!==e):void 0===o?[...t,{key:e,direction:r}]:t.map(t=>t.key===e?{key:e,direction:r}:t):null===r?[]:[{key:e,direction:r}]}export function searchText(t){return null==t||"object"==typeof t?"":String(t).normalize("NFD").replace(/[\u0300-\u036f]/g,"").toLowerCase()}export function pageBounds(t,e,n){const o=Math.max(1,Math.floor(n)),r=Math.max(1,Math.ceil(t/o)),a=Math.min(Math.max(Math.floor(e),1),r),i=(a-1)*o;return{pages:r,page:a,start:i,end:Math.min(i+o,t)}}export function virtualWindow(t,e,n,o,r){const a=e>0?Math.ceil(e/n):3*r,i=Math.max(0,Math.floor(t/n)-r),s=Math.min(o,i+a+2*r);return{start:i,end:s,before:i*n,after:Math.max(0,(o-s)*n)}}export function keysBetween(t,e,n){const o=t.indexOf(e),r=t.indexOf(n);return-1===o||-1===r?[]:t.slice(Math.min(o,r),Math.max(o,r)+1)}
@@ -62,6 +62,46 @@ export interface NebaMessages {
62
62
  /** What the three dots mean. */
63
63
  typing: string;
64
64
  };
65
+ /** Empty. */
66
+ empty: {
67
+ /**
68
+ * The headline over a region with nothing in it.
69
+ *
70
+ * The one string in here that is *drawn* at full size rather than read out
71
+ * or written on a button, and it is here for the same reason the rest are:
72
+ * an empty state has nothing to take its words from. What is missing is the
73
+ * caller's — a search, an inbox, a folder — so the default says only that
74
+ * there is nothing, and anything more specific is the `title` prop.
75
+ */
76
+ title: string;
77
+ };
78
+ /**
79
+ * DataTable.
80
+ *
81
+ * A DataTable is the one component in the library that draws chrome of its
82
+ * own — a search field, a header tick that chooses everything at once, a
83
+ * footer counting what is on screen — so it is also the one that has the most
84
+ * to say without being handed the words.
85
+ */
86
+ table: {
87
+ /** Placeholder and accessible name of the search field. */
88
+ search: string;
89
+ /** The tick in the header row, which chooses every row at once. */
90
+ selectAll: string;
91
+ /** The tick on a row. */
92
+ selectRow: string;
93
+ /** Beside the footer's page-size Select. */
94
+ rowsPerPage: string;
95
+ /**
96
+ * Which rows are on screen, out of how many there are. `{start}`, `{end}`
97
+ * and `{total}` are replaced with the numbers, already formatted for the
98
+ * locale — a template rather than three fragments, because the order the
99
+ * three appear in is exactly what differs between languages.
100
+ */
101
+ range: string;
102
+ /** How many rows are chosen. `{count}` is replaced the same way. */
103
+ selected: string;
104
+ };
65
105
  /**
66
106
  * ColorPicker.
67
107
  *
@@ -101,3 +141,14 @@ export interface NebaMessages {
101
141
  export declare function resolveMessages(locale?: string): NebaMessages;
102
142
  /** The same, as a hook, for the components that read it during a render. */
103
143
  export declare function useMessages(locale?: string): NebaMessages;
144
+ /**
145
+ * Fills the `{placeholders}` in one of the strings above.
146
+ *
147
+ * Two of them carry numbers, and neither could be assembled out of fragments:
148
+ * "1–25 of 1,204" is "전체 1,204개 중 1–25" in Korean and "1,204 kayıttan 1–25"
149
+ * in Turkish, so what differs between languages is the *order*, which only a
150
+ * whole sentence can state. A `{name}` with no value is left alone rather than
151
+ * blanked, so a mistranslated placeholder shows up as itself instead of as a
152
+ * hole in the middle of a sentence.
153
+ */
154
+ export declare function fillMessage(template: string, values: Record<string, string>): string;
@@ -1 +1 @@
1
- import*as e from"react";const a={link:{newTab:"(opens in a new tab)"},spoiler:{reveal:"Reveal",hide:"Hide",notice:"This may contain spoilers"},chat:{sending:"Sending",sent:"Sent",delivered:"Delivered",read:"Read",failed:"Not sent",typing:"Typing…"},color:{area:"Saturation and brightness",hue:"Hue",alpha:"Opacity",value:"Colour value",swatches:"Preset colours",clear:"Clear",empty:"Choose a colour"}},n={ko:{link:{newTab:"(새 창에서 열림)"},spoiler:{reveal:"내용 보기",hide:"숨기기",notice:"스포일러가 포함되어 있을 수 있습니다"},chat:{sending:"보내는 중",sent:"보냄",delivered:"전달됨",read:"읽음",failed:"전송 실패",typing:"입력 중…"},color:{area:"채도와 명도",hue:"색상",alpha:"불투명도",value:"색상 값",swatches:"기본 색상",clear:"지우기",empty:"색상 선택"}},ja:{link:{newTab:"(新しいタブで開きます)"},spoiler:{reveal:"表示する",hide:"隠す",notice:"ネタバレを含む可能性があります"},chat:{sending:"送信中",sent:"送信済み",delivered:"配信済み",read:"既読",failed:"送信できませんでした",typing:"入力中…"},color:{area:"彩度と明度",hue:"色相",alpha:"不透明度",value:"カラー値",swatches:"プリセットの色",clear:"クリア",empty:"色を選択"}},"zh-hans":{link:{newTab:"(在新标签页中打开)"},spoiler:{reveal:"显示内容",hide:"隐藏",notice:"此内容可能包含剧透"},chat:{sending:"发送中",sent:"已发送",delivered:"已送达",read:"已读",failed:"发送失败",typing:"正在输入…"},color:{area:"饱和度和明度",hue:"色相",alpha:"不透明度",value:"颜色值",swatches:"预设颜色",clear:"清除",empty:"选择颜色"}},"zh-hant":{link:{newTab:"(在新分頁中開啟)"},spoiler:{reveal:"顯示內容",hide:"隱藏",notice:"此內容可能包含劇透"},chat:{sending:"傳送中",sent:"已傳送",delivered:"已送達",read:"已讀",failed:"傳送失敗",typing:"正在輸入…"},color:{area:"飽和度與明度",hue:"色相",alpha:"不透明度",value:"顏色值",swatches:"預設顏色",clear:"清除",empty:"選擇顏色"}},es:{link:{newTab:"(se abre en una pestaña nueva)"},spoiler:{reveal:"Mostrar",hide:"Ocultar",notice:"Puede contener spoilers"},chat:{sending:"Enviando",sent:"Enviado",delivered:"Entregado",read:"Leído",failed:"No enviado",typing:"Escribiendo…"},color:{area:"Saturación y brillo",hue:"Tono",alpha:"Opacidad",value:"Valor del color",swatches:"Colores predefinidos",clear:"Borrar",empty:"Elegir un color"}},pt:{link:{newTab:"(abre em uma nova aba)"},spoiler:{reveal:"Mostrar",hide:"Ocultar",notice:"Pode conter spoilers"},chat:{sending:"Enviando",sent:"Enviado",delivered:"Entregue",read:"Lido",failed:"Não enviado",typing:"Digitando…"},color:{area:"Saturação e brilho",hue:"Matiz",alpha:"Opacidade",value:"Valor da cor",swatches:"Cores predefinidas",clear:"Limpar",empty:"Escolher uma cor"}},fr:{link:{newTab:"(s’ouvre dans un nouvel onglet)"},spoiler:{reveal:"Afficher",hide:"Masquer",notice:"Peut contenir des spoilers"},chat:{sending:"Envoi en cours",sent:"Envoyé",delivered:"Distribué",read:"Lu",failed:"Non envoyé",typing:"En train d’écrire…"},color:{area:"Saturation et luminosité",hue:"Teinte",alpha:"Opacité",value:"Valeur de la couleur",swatches:"Couleurs prédéfinies",clear:"Effacer",empty:"Choisir une couleur"}},de:{link:{newTab:"(wird in einem neuen Tab geöffnet)"},spoiler:{reveal:"Anzeigen",hide:"Ausblenden",notice:"Kann Spoiler enthalten"},chat:{sending:"Wird gesendet",sent:"Gesendet",delivered:"Zugestellt",read:"Gelesen",failed:"Nicht gesendet",typing:"Schreibt…"},color:{area:"Sättigung und Helligkeit",hue:"Farbton",alpha:"Deckkraft",value:"Farbwert",swatches:"Vorgegebene Farben",clear:"Löschen",empty:"Farbe auswählen"}},it:{link:{newTab:"(si apre in una nuova scheda)"},spoiler:{reveal:"Mostra",hide:"Nascondi",notice:"Può contenere spoiler"},chat:{sending:"Invio in corso",sent:"Inviato",delivered:"Consegnato",read:"Letto",failed:"Non inviato",typing:"Sta scrivendo…"},color:{area:"Saturazione e luminosità",hue:"Tonalità",alpha:"Opacità",value:"Valore del colore",swatches:"Colori predefiniti",clear:"Cancella",empty:"Scegli un colore"}},nl:{link:{newTab:"(opent in een nieuw tabblad)"},spoiler:{reveal:"Tonen",hide:"Verbergen",notice:"Kan spoilers bevatten"},chat:{sending:"Wordt verzonden",sent:"Verzonden",delivered:"Afgeleverd",read:"Gelezen",failed:"Niet verzonden",typing:"Aan het typen…"},color:{area:"Verzadiging en helderheid",hue:"Kleurtoon",alpha:"Dekking",value:"Kleurwaarde",swatches:"Vooraf ingestelde kleuren",clear:"Wissen",empty:"Kies een kleur"}},pl:{link:{newTab:"(otwiera się w nowej karcie)"},spoiler:{reveal:"Pokaż",hide:"Ukryj",notice:"Może zawierać spoilery"},chat:{sending:"Wysyłanie",sent:"Wysłano",delivered:"Dostarczono",read:"Przeczytano",failed:"Nie wysłano",typing:"Pisze…"},color:{area:"Nasycenie i jasność",hue:"Barwa",alpha:"Krycie",value:"Wartość koloru",swatches:"Kolory predefiniowane",clear:"Wyczyść",empty:"Wybierz kolor"}},ru:{link:{newTab:"(откроется в новой вкладке)"},spoiler:{reveal:"Показать",hide:"Скрыть",notice:"Может содержать спойлеры"},chat:{sending:"Отправляется",sent:"Отправлено",delivered:"Доставлено",read:"Прочитано",failed:"Не отправлено",typing:"Печатает…"},color:{area:"Насыщенность и яркость",hue:"Оттенок",alpha:"Непрозрачность",value:"Значение цвета",swatches:"Готовые цвета",clear:"Очистить",empty:"Выберите цвет"}},tr:{link:{newTab:"(yeni sekmede açılır)"},spoiler:{reveal:"Göster",hide:"Gizle",notice:"Spoiler içerebilir"},chat:{sending:"Gönderiliyor",sent:"Gönderildi",delivered:"İletildi",read:"Okundu",failed:"Gönderilemedi",typing:"Yazıyor…"},color:{area:"Doygunluk ve parlaklık",hue:"Renk tonu",alpha:"Opaklık",value:"Renk değeri",swatches:"Hazır renkler",clear:"Temizle",empty:"Bir renk seçin"}},ar:{link:{newTab:"(يفتح في علامة تبويب جديدة)"},spoiler:{reveal:"إظهار",hide:"إخفاء",notice:"قد يحتوي على حرق للأحداث"},chat:{sending:"جارٍ الإرسال",sent:"تم الإرسال",delivered:"تم التسليم",read:"تمت القراءة",failed:"لم يتم الإرسال",typing:"يكتب الآن…"},color:{area:"التشبع والسطوع",hue:"درجة اللون",alpha:"العتامة",value:"قيمة اللون",swatches:"ألوان جاهزة",clear:"مسح",empty:"اختر لونًا"}},hi:{link:{newTab:"(नए टैब में खुलता है)"},spoiler:{reveal:"दिखाएँ",hide:"छिपाएँ",notice:"इसमें स्पॉइलर हो सकते हैं"},chat:{sending:"भेजा जा रहा है",sent:"भेजा गया",delivered:"डिलीवर हुआ",read:"पढ़ा गया",failed:"नहीं भेजा गया",typing:"टाइप कर रहे हैं…"},color:{area:"संतृप्ति और चमक",hue:"रंग",alpha:"अपारदर्शिता",value:"रंग मान",swatches:"पूर्व निर्धारित रंग",clear:"साफ़ करें",empty:"एक रंग चुनें"}},id:{link:{newTab:"(terbuka di tab baru)"},spoiler:{reveal:"Tampilkan",hide:"Sembunyikan",notice:"Mungkin mengandung spoiler"},chat:{sending:"Mengirim",sent:"Terkirim",delivered:"Diterima",read:"Dibaca",failed:"Gagal terkirim",typing:"Sedang mengetik…"},color:{area:"Saturasi dan kecerahan",hue:"Rona",alpha:"Opasitas",value:"Nilai warna",swatches:"Warna preset",clear:"Hapus",empty:"Pilih warna"}},vi:{link:{newTab:"(mở trong tab mới)"},spoiler:{reveal:"Hiện nội dung",hide:"Ẩn",notice:"Có thể chứa nội dung tiết lộ"},chat:{sending:"Đang gửi",sent:"Đã gửi",delivered:"Đã nhận",read:"Đã xem",failed:"Chưa gửi được",typing:"Đang nhập…"},color:{area:"Độ bão hòa và độ sáng",hue:"Sắc độ",alpha:"Độ mờ đục",value:"Giá trị màu",swatches:"Màu dựng sẵn",clear:"Xóa",empty:"Chọn màu"}},th:{link:{newTab:"(เปิดในแท็บใหม่)"},spoiler:{reveal:"แสดงเนื้อหา",hide:"ซ่อน",notice:"อาจมีการเปิดเผยเนื้อหา"},chat:{sending:"กำลังส่ง",sent:"ส่งแล้ว",delivered:"ส่งถึงแล้ว",read:"อ่านแล้ว",failed:"ส่งไม่สำเร็จ",typing:"กำลังพิมพ์…"},color:{area:"ความอิ่มตัวและความสว่าง",hue:"เฉดสี",alpha:"ความทึบ",value:"ค่าสี",swatches:"สีที่กำหนดไว้",clear:"ล้าง",empty:"เลือกสี"}}},i={zh:"zh-hans","zh-cn":"zh-hans","zh-my":"zh-hans","zh-sg":"zh-hans","zh-hk":"zh-hant","zh-mo":"zh-hant","zh-tw":"zh-hant"};const r=new Map([["",a]]);export function resolveMessages(e){const l=e?.trim()??"",t=r.get(l);if(t)return t;const o=function(e){const a=e.toLowerCase().split(/[-_]/).filter(Boolean),n=a[0];if(!n)return[];const i=a.slice(1),r=i.find(e=>/^[a-z]{4}$/.test(e)),l=i.find(e=>/^([a-z]{2}|\d{3})$/.test(e));return[r?`${n}-${r}`:"",l?`${n}-${l}`:"",n].filter(Boolean)}(l).map(e=>n[e]??n[i[e]??""]).find(Boolean),s=o?{link:{...a.link,...o.link},spoiler:{...a.spoiler,...o.spoiler},chat:{...a.chat,...o.chat},color:{...a.color,...o.color}}:a;return r.set(l,s),s}export function useMessages(a){return e.useMemo(()=>resolveMessages(a),[a])}
1
+ import*as e from"react";const a={link:{newTab:"(opens in a new tab)"},spoiler:{reveal:"Reveal",hide:"Hide",notice:"This may contain spoilers"},chat:{sending:"Sending",sent:"Sent",delivered:"Delivered",read:"Read",failed:"Not sent",typing:"Typing…"},empty:{title:"Nothing here"},table:{search:"Search",selectAll:"Select all rows",selectRow:"Select row",rowsPerPage:"Rows per page",range:"{start}–{end} of {total}",selected:"{count} selected"},color:{area:"Saturation and brightness",hue:"Hue",alpha:"Opacity",value:"Colour value",swatches:"Preset colours",clear:"Clear",empty:"Choose a colour"}},t={ko:{link:{newTab:"(새 창에서 열림)"},spoiler:{reveal:"내용 보기",hide:"숨기기",notice:"스포일러가 포함되어 있을 수 있습니다"},chat:{sending:"보내는 중",sent:"보냄",delivered:"전달됨",read:"읽음",failed:"전송 실패",typing:"입력 중…"},empty:{title:"내용이 없습니다"},table:{search:"검색",selectAll:"모든 행 선택",selectRow:"행 선택",rowsPerPage:"페이지당 행 수",range:"전체 {total}개 중 {start}–{end}",selected:"{count}개 선택됨"},color:{area:"채도와 명도",hue:"색상",alpha:"불투명도",value:"색상 값",swatches:"기본 색상",clear:"지우기",empty:"색상 선택"}},ja:{link:{newTab:"(新しいタブで開きます)"},spoiler:{reveal:"表示する",hide:"隠す",notice:"ネタバレを含む可能性があります"},chat:{sending:"送信中",sent:"送信済み",delivered:"配信済み",read:"既読",failed:"送信できませんでした",typing:"入力中…"},empty:{title:"表示するものがありません"},table:{search:"検索",selectAll:"すべての行を選択",selectRow:"行を選択",rowsPerPage:"1 ページの行数",range:"{total} 件中 {start}–{end} 件",selected:"{count} 件を選択中"},color:{area:"彩度と明度",hue:"色相",alpha:"不透明度",value:"カラー値",swatches:"プリセットの色",clear:"クリア",empty:"色を選択"}},"zh-hans":{link:{newTab:"(在新标签页中打开)"},spoiler:{reveal:"显示内容",hide:"隐藏",notice:"此内容可能包含剧透"},chat:{sending:"发送中",sent:"已发送",delivered:"已送达",read:"已读",failed:"发送失败",typing:"正在输入…"},empty:{title:"暂无内容"},table:{search:"搜索",selectAll:"全选所有行",selectRow:"选择此行",rowsPerPage:"每页行数",range:"第 {start}–{end} 行,共 {total} 行",selected:"已选择 {count} 行"},color:{area:"饱和度和明度",hue:"色相",alpha:"不透明度",value:"颜色值",swatches:"预设颜色",clear:"清除",empty:"选择颜色"}},"zh-hant":{link:{newTab:"(在新分頁中開啟)"},spoiler:{reveal:"顯示內容",hide:"隱藏",notice:"此內容可能包含劇透"},chat:{sending:"傳送中",sent:"已傳送",delivered:"已送達",read:"已讀",failed:"傳送失敗",typing:"正在輸入…"},empty:{title:"沒有內容"},table:{search:"搜尋",selectAll:"全選所有列",selectRow:"選擇此列",rowsPerPage:"每頁列數",range:"第 {start}–{end} 列,共 {total} 列",selected:"已選擇 {count} 列"},color:{area:"飽和度與明度",hue:"色相",alpha:"不透明度",value:"顏色值",swatches:"預設顏色",clear:"清除",empty:"選擇顏色"}},es:{link:{newTab:"(se abre en una pestaña nueva)"},spoiler:{reveal:"Mostrar",hide:"Ocultar",notice:"Puede contener spoilers"},chat:{sending:"Enviando",sent:"Enviado",delivered:"Entregado",read:"Leído",failed:"No enviado",typing:"Escribiendo…"},empty:{title:"No hay nada aquí"},table:{search:"Buscar",selectAll:"Seleccionar todas las filas",selectRow:"Seleccionar fila",rowsPerPage:"Filas por página",range:"{start}–{end} de {total}",selected:"{count} seleccionadas"},color:{area:"Saturación y brillo",hue:"Tono",alpha:"Opacidad",value:"Valor del color",swatches:"Colores predefinidos",clear:"Borrar",empty:"Elegir un color"}},pt:{link:{newTab:"(abre em uma nova aba)"},spoiler:{reveal:"Mostrar",hide:"Ocultar",notice:"Pode conter spoilers"},chat:{sending:"Enviando",sent:"Enviado",delivered:"Entregue",read:"Lido",failed:"Não enviado",typing:"Digitando…"},empty:{title:"Nada por aqui"},table:{search:"Pesquisar",selectAll:"Selecionar todas as linhas",selectRow:"Selecionar linha",rowsPerPage:"Linhas por página",range:"{start}–{end} de {total}",selected:"{count} selecionadas"},color:{area:"Saturação e brilho",hue:"Matiz",alpha:"Opacidade",value:"Valor da cor",swatches:"Cores predefinidas",clear:"Limpar",empty:"Escolher uma cor"}},fr:{link:{newTab:"(s’ouvre dans un nouvel onglet)"},spoiler:{reveal:"Afficher",hide:"Masquer",notice:"Peut contenir des spoilers"},chat:{sending:"Envoi en cours",sent:"Envoyé",delivered:"Distribué",read:"Lu",failed:"Non envoyé",typing:"En train d’écrire…"},empty:{title:"Rien ici"},table:{search:"Rechercher",selectAll:"Sélectionner toutes les lignes",selectRow:"Sélectionner la ligne",rowsPerPage:"Lignes par page",range:"{start}–{end} sur {total}",selected:"{count} sélectionnées"},color:{area:"Saturation et luminosité",hue:"Teinte",alpha:"Opacité",value:"Valeur de la couleur",swatches:"Couleurs prédéfinies",clear:"Effacer",empty:"Choisir une couleur"}},de:{link:{newTab:"(wird in einem neuen Tab geöffnet)"},spoiler:{reveal:"Anzeigen",hide:"Ausblenden",notice:"Kann Spoiler enthalten"},chat:{sending:"Wird gesendet",sent:"Gesendet",delivered:"Zugestellt",read:"Gelesen",failed:"Nicht gesendet",typing:"Schreibt…"},empty:{title:"Nichts vorhanden"},table:{search:"Suchen",selectAll:"Alle Zeilen auswählen",selectRow:"Zeile auswählen",rowsPerPage:"Zeilen pro Seite",range:"{start}–{end} von {total}",selected:"{count} ausgewählt"},color:{area:"Sättigung und Helligkeit",hue:"Farbton",alpha:"Deckkraft",value:"Farbwert",swatches:"Vorgegebene Farben",clear:"Löschen",empty:"Farbe auswählen"}},it:{link:{newTab:"(si apre in una nuova scheda)"},spoiler:{reveal:"Mostra",hide:"Nascondi",notice:"Può contenere spoiler"},chat:{sending:"Invio in corso",sent:"Inviato",delivered:"Consegnato",read:"Letto",failed:"Non inviato",typing:"Sta scrivendo…"},empty:{title:"Non c’è nulla"},table:{search:"Cerca",selectAll:"Seleziona tutte le righe",selectRow:"Seleziona riga",rowsPerPage:"Righe per pagina",range:"{start}–{end} di {total}",selected:"{count} selezionate"},color:{area:"Saturazione e luminosità",hue:"Tonalità",alpha:"Opacità",value:"Valore del colore",swatches:"Colori predefiniti",clear:"Cancella",empty:"Scegli un colore"}},nl:{link:{newTab:"(opent in een nieuw tabblad)"},spoiler:{reveal:"Tonen",hide:"Verbergen",notice:"Kan spoilers bevatten"},chat:{sending:"Wordt verzonden",sent:"Verzonden",delivered:"Afgeleverd",read:"Gelezen",failed:"Niet verzonden",typing:"Aan het typen…"},empty:{title:"Hier is niets"},table:{search:"Zoeken",selectAll:"Alle rijen selecteren",selectRow:"Rij selecteren",rowsPerPage:"Rijen per pagina",range:"{start}–{end} van {total}",selected:"{count} geselecteerd"},color:{area:"Verzadiging en helderheid",hue:"Kleurtoon",alpha:"Dekking",value:"Kleurwaarde",swatches:"Vooraf ingestelde kleuren",clear:"Wissen",empty:"Kies een kleur"}},pl:{link:{newTab:"(otwiera się w nowej karcie)"},spoiler:{reveal:"Pokaż",hide:"Ukryj",notice:"Może zawierać spoilery"},chat:{sending:"Wysyłanie",sent:"Wysłano",delivered:"Dostarczono",read:"Przeczytano",failed:"Nie wysłano",typing:"Pisze…"},empty:{title:"Nic tu nie ma"},table:{search:"Szukaj",selectAll:"Zaznacz wszystkie wiersze",selectRow:"Zaznacz wiersz",rowsPerPage:"Wierszy na stronę",range:"{start}–{end} z {total}",selected:"Zaznaczono: {count}"},color:{area:"Nasycenie i jasność",hue:"Barwa",alpha:"Krycie",value:"Wartość koloru",swatches:"Kolory predefiniowane",clear:"Wyczyść",empty:"Wybierz kolor"}},ru:{link:{newTab:"(откроется в новой вкладке)"},spoiler:{reveal:"Показать",hide:"Скрыть",notice:"Может содержать спойлеры"},chat:{sending:"Отправляется",sent:"Отправлено",delivered:"Доставлено",read:"Прочитано",failed:"Не отправлено",typing:"Печатает…"},empty:{title:"Здесь пусто"},table:{search:"Поиск",selectAll:"Выбрать все строки",selectRow:"Выбрать строку",rowsPerPage:"Строк на странице",range:"{start}–{end} из {total}",selected:"Выбрано: {count}"},color:{area:"Насыщенность и яркость",hue:"Оттенок",alpha:"Непрозрачность",value:"Значение цвета",swatches:"Готовые цвета",clear:"Очистить",empty:"Выберите цвет"}},tr:{link:{newTab:"(yeni sekmede açılır)"},spoiler:{reveal:"Göster",hide:"Gizle",notice:"Spoiler içerebilir"},chat:{sending:"Gönderiliyor",sent:"Gönderildi",delivered:"İletildi",read:"Okundu",failed:"Gönderilemedi",typing:"Yazıyor…"},empty:{title:"Burada bir şey yok"},table:{search:"Ara",selectAll:"Tüm satırları seç",selectRow:"Satırı seç",rowsPerPage:"Sayfa başına satır",range:"{total} kayıttan {start}–{end}",selected:"{count} seçildi"},color:{area:"Doygunluk ve parlaklık",hue:"Renk tonu",alpha:"Opaklık",value:"Renk değeri",swatches:"Hazır renkler",clear:"Temizle",empty:"Bir renk seçin"}},ar:{link:{newTab:"(يفتح في علامة تبويب جديدة)"},spoiler:{reveal:"إظهار",hide:"إخفاء",notice:"قد يحتوي على حرق للأحداث"},chat:{sending:"جارٍ الإرسال",sent:"تم الإرسال",delivered:"تم التسليم",read:"تمت القراءة",failed:"لم يتم الإرسال",typing:"يكتب الآن…"},empty:{title:"لا يوجد شيء هنا"},table:{search:"بحث",selectAll:"تحديد كل الصفوف",selectRow:"تحديد الصف",rowsPerPage:"صفوف لكل صفحة",range:"{start}–{end} من {total}",selected:"تم تحديد {count}"},color:{area:"التشبع والسطوع",hue:"درجة اللون",alpha:"العتامة",value:"قيمة اللون",swatches:"ألوان جاهزة",clear:"مسح",empty:"اختر لونًا"}},hi:{link:{newTab:"(नए टैब में खुलता है)"},spoiler:{reveal:"दिखाएँ",hide:"छिपाएँ",notice:"इसमें स्पॉइलर हो सकते हैं"},chat:{sending:"भेजा जा रहा है",sent:"भेजा गया",delivered:"डिलीवर हुआ",read:"पढ़ा गया",failed:"नहीं भेजा गया",typing:"टाइप कर रहे हैं…"},empty:{title:"यहाँ कुछ नहीं है"},table:{search:"खोजें",selectAll:"सभी पंक्तियाँ चुनें",selectRow:"पंक्ति चुनें",rowsPerPage:"प्रति पृष्ठ पंक्तियाँ",range:"{total} में से {start}–{end}",selected:"{count} चुनी गईं"},color:{area:"संतृप्ति और चमक",hue:"रंग",alpha:"अपारदर्शिता",value:"रंग मान",swatches:"पूर्व निर्धारित रंग",clear:"साफ़ करें",empty:"एक रंग चुनें"}},id:{link:{newTab:"(terbuka di tab baru)"},spoiler:{reveal:"Tampilkan",hide:"Sembunyikan",notice:"Mungkin mengandung spoiler"},chat:{sending:"Mengirim",sent:"Terkirim",delivered:"Diterima",read:"Dibaca",failed:"Gagal terkirim",typing:"Sedang mengetik…"},empty:{title:"Tidak ada apa-apa di sini"},table:{search:"Cari",selectAll:"Pilih semua baris",selectRow:"Pilih baris",rowsPerPage:"Baris per halaman",range:"{start}–{end} dari {total}",selected:"{count} dipilih"},color:{area:"Saturasi dan kecerahan",hue:"Rona",alpha:"Opasitas",value:"Nilai warna",swatches:"Warna preset",clear:"Hapus",empty:"Pilih warna"}},vi:{link:{newTab:"(mở trong tab mới)"},spoiler:{reveal:"Hiện nội dung",hide:"Ẩn",notice:"Có thể chứa nội dung tiết lộ"},chat:{sending:"Đang gửi",sent:"Đã gửi",delivered:"Đã nhận",read:"Đã xem",failed:"Chưa gửi được",typing:"Đang nhập…"},empty:{title:"Không có gì ở đây"},table:{search:"Tìm kiếm",selectAll:"Chọn tất cả các hàng",selectRow:"Chọn hàng",rowsPerPage:"Số hàng mỗi trang",range:"{start}–{end} trên {total}",selected:"Đã chọn {count}"},color:{area:"Độ bão hòa và độ sáng",hue:"Sắc độ",alpha:"Độ mờ đục",value:"Giá trị màu",swatches:"Màu dựng sẵn",clear:"Xóa",empty:"Chọn màu"}},th:{link:{newTab:"(เปิดในแท็บใหม่)"},spoiler:{reveal:"แสดงเนื้อหา",hide:"ซ่อน",notice:"อาจมีการเปิดเผยเนื้อหา"},chat:{sending:"กำลังส่ง",sent:"ส่งแล้ว",delivered:"ส่งถึงแล้ว",read:"อ่านแล้ว",failed:"ส่งไม่สำเร็จ",typing:"กำลังพิมพ์…"},empty:{title:"ไม่มีอะไรที่นี่"},table:{search:"ค้นหา",selectAll:"เลือกทุกแถว",selectRow:"เลือกแถวนี้",rowsPerPage:"จำนวนแถวต่อหน้า",range:"{start}–{end} จาก {total}",selected:"เลือกแล้ว {count} รายการ"},color:{area:"ความอิ่มตัวและความสว่าง",hue:"เฉดสี",alpha:"ความทึบ",value:"ค่าสี",swatches:"สีที่กำหนดไว้",clear:"ล้าง",empty:"เลือกสี"}}},l={zh:"zh-hans","zh-cn":"zh-hans","zh-my":"zh-hans","zh-sg":"zh-hans","zh-hk":"zh-hant","zh-mo":"zh-hant","zh-tw":"zh-hant"};const n=new Map([["",a]]);export function resolveMessages(e){const r=e?.trim()??"",i=n.get(r);if(i)return i;const s=function(e){const a=e.toLowerCase().split(/[-_]/).filter(Boolean),t=a[0];if(!t)return[];const l=a.slice(1),n=l.find(e=>/^[a-z]{4}$/.test(e)),r=l.find(e=>/^([a-z]{2}|\d{3})$/.test(e));return[n?`${t}-${n}`:"",r?`${t}-${r}`:"",t].filter(Boolean)}(r).map(e=>t[e]??t[l[e]??""]).find(Boolean),o=s?{link:{...a.link,...s.link},spoiler:{...a.spoiler,...s.spoiler},chat:{...a.chat,...s.chat},empty:{...a.empty,...s.empty},table:{...a.table,...s.table},color:{...a.color,...s.color}}:a;return n.set(r,o),o}export function useMessages(a){return e.useMemo(()=>resolveMessages(a),[a])}export function fillMessage(e,a){return e.replace(/\{(\w+)\}/g,(e,t)=>a[t]??e)}
@@ -0,0 +1,193 @@
1
+ /**
2
+ * The device a Mockup is a picture of: the tables that say how big it is, and
3
+ * the drawings that go on its screen.
4
+ *
5
+ * It lives here for the reason `internal/color.ts` does. Only one component
6
+ * reads it, but what it holds is a body of reference data rather than a piece of
7
+ * that component — five resolutions per device, three shells, six systems' worth
8
+ * of chrome — and a component file with all of that in it would be a table with
9
+ * a `forwardRef` at the bottom.
10
+ *
11
+ * Two conventions run through the whole file:
12
+ *
13
+ * **Every length in here is a device pixel.** The screen is laid out at the
14
+ * resolution it claims to have and the whole frame is scaled once, at the top,
15
+ * so a 54px status bar is 54px on the phone rather than 54px on the page. That
16
+ * is also why the geometry is written as inline styles rather than as utilities:
17
+ * these are numbers off a table, computed per render, and Tailwind only ever
18
+ * sees class names that appear literally in the source. Utilities are still what
19
+ * does the layout — the inline styles are only ever the measurements.
20
+ *
21
+ * **The chrome draws no words except the clock.** A menu bar's titles, a dock's
22
+ * icons and a status bar's carrier are abstract shapes, which is what keeps this
23
+ * an impression of a system rather than a copy of one: nothing to translate,
24
+ * nothing to redraw when a version ships, and no other party's marks in the
25
+ * library. The clock is the exception because a blank rectangle where the time
26
+ * goes reads as a bug, and it is a prop.
27
+ */
28
+ import * as React from 'react';
29
+ import type { NebaSize } from '../types';
30
+ /** Which machine the mockup is a picture of. */
31
+ export type NebaMockupDevice = 'desktop' | 'tablet' | 'mobile';
32
+ /**
33
+ * The system whose chrome is drawn on the screen.
34
+ *
35
+ * One union across all three devices rather than one per device: a caller
36
+ * reading the type should see the whole set, and a device offered an OS that is
37
+ * not its own falls back to its default rather than failing to compile — which
38
+ * is the behaviour a single `Mockup` with a `device` prop has to have anyway.
39
+ */
40
+ export type NebaMockupOs = 'macos' | 'windows' | 'linux' | 'ios' | 'ipados' | 'android';
41
+ /** What the hardware around a desktop screen is. */
42
+ export type NebaMockupHardware = 'monitor' | 'laptop';
43
+ /**
44
+ * The camera cut-out at the top of a screen.
45
+ *
46
+ * Hardware, not chrome — it is drawn whether or not `systemUi` is on, because a
47
+ * phone with the status bar hidden still has a hole in its screen.
48
+ */
49
+ export type NebaMockupNotch = 'none' | 'notch' | 'dynamic-island' | 'punch-hole';
50
+ /**
51
+ * How much hardware there is around the screen.
52
+ *
53
+ * `none` is not a thinner bezel — it is no hardware at all: no frame, no stand,
54
+ * no laptop base, just the screen with its corners cut. It is what a mockup that
55
+ * only wants to say "this is a phone-shaped viewport" asks for.
56
+ *
57
+ * `thick` is an older device rather than a wider version of `standard`: the
58
+ * sides stay narrow and the forehead and chin grow, which is where a bezel
59
+ * actually goes when there is a lot of it.
60
+ */
61
+ export type NebaMockupBezel = 'none' | 'thin' | 'standard' | 'thick';
62
+ /** What the hardware is made of. */
63
+ export type NebaMockupFinish = 'graphite' | 'silver' | 'white';
64
+ /**
65
+ * Which way a handheld is held.
66
+ *
67
+ * `portrait`/`landscape` rather than `NebaOrientation`'s `vertical`/`horizontal`,
68
+ * and this is the one place the library spells the idea twice on purpose. A
69
+ * Divider running horizontally is not "landscape", and a device held upright is
70
+ * not "vertical" in any vocabulary a designer or a media query uses. CSS itself
71
+ * keeps both pairs for exactly this reason.
72
+ */
73
+ export type NebaMockupOrientation = 'portrait' | 'landscape';
74
+ /** A screen's logical resolution, in CSS pixels. */
75
+ export interface NebaMockupResolution {
76
+ width: number;
77
+ height: number;
78
+ }
79
+ /**
80
+ * The system a device will actually draw.
81
+ *
82
+ * An OS the device does not run falls back to its default, with one nicety: a
83
+ * caller who writes `ios` on a tablet or `ipados` on a phone meant the Apple one
84
+ * and gets it, rather than being sent back to the start of the list.
85
+ */
86
+ export declare function resolveOs(device: NebaMockupDevice, os?: NebaMockupOs): NebaMockupOs;
87
+ /** What a device puts in its screen when the caller says nothing. */
88
+ export declare function defaultNotch(device: NebaMockupDevice, os: NebaMockupOs): NebaMockupNotch;
89
+ export declare const resolutions: Record<NebaMockupDevice, Record<NebaSize, NebaMockupResolution>>;
90
+ /** How much hardware sits on each side of the screen. */
91
+ export interface MockupInset {
92
+ x: number;
93
+ top: number;
94
+ bottom: number;
95
+ }
96
+ /** Every number the component needs to lay a device out, in device pixels. */
97
+ export interface MockupMetrics {
98
+ /** The screen, after `orientation` has had its say. */
99
+ screen: NebaMockupResolution;
100
+ /** The hardware around it. Zero on all four sides when `bezel` is `none`. */
101
+ bezel: MockupInset;
102
+ /** Screen plus bezel: the part you would call the device's face. */
103
+ body: {
104
+ width: number;
105
+ height: number;
106
+ };
107
+ /** Face plus whatever holds it up. This is what gets scaled to fit. */
108
+ frame: {
109
+ width: number;
110
+ height: number;
111
+ };
112
+ frameRadius: number;
113
+ screenRadius: number;
114
+ /** A monitor's neck and foot, when there is one. */
115
+ stand: {
116
+ neckWidth: number;
117
+ neckHeight: number;
118
+ footWidth: number;
119
+ footHeight: number;
120
+ } | null;
121
+ /** A laptop's base, when there is one. */
122
+ base: {
123
+ width: number;
124
+ height: number;
125
+ lipWidth: number;
126
+ } | null;
127
+ }
128
+ export declare function mockupMetrics(options: {
129
+ device: NebaMockupDevice;
130
+ size: NebaSize;
131
+ resolution?: NebaMockupResolution;
132
+ orientation: NebaMockupOrientation;
133
+ bezel: NebaMockupBezel;
134
+ hardware: NebaMockupHardware;
135
+ }): MockupMetrics;
136
+ export declare const finishSlots: Record<NebaMockupFinish, React.CSSProperties>;
137
+ /**
138
+ * The hardware's surface: the finish, a light top edge and a hairline all the
139
+ * way round, which is the plate the design language puts on everything else. No
140
+ * dark bevel underneath — the shade is a ring, not a shadow.
141
+ */
142
+ export declare const shellClasses = "bg-(--n-shell) [box-shadow:inset_0_1px_0_var(--n-shell-edge),inset_0_0_0_1px_var(--n-shell-shade)]";
143
+ /** How far off the page the whole device sits, as a silhouette rather than a box.
144
+ *
145
+ * `drop-shadow` rather than `box-shadow` for one reason: the shadow has to
146
+ * follow a rounded lid on a narrow neck on a wide foot, and a box-shadow would
147
+ * draw the rectangle that contains all three. It also sits outside the scale,
148
+ * so a device shrunk to a third of its size does not get a third of its shadow.
149
+ */
150
+ export declare const elevationFilters: readonly ["none", "drop-shadow(0 1px 2px var(--neba-shadow-ambient))", "drop-shadow(0 2px 4px var(--neba-shadow-ambient)) drop-shadow(0 8px 12px var(--neba-shadow-ambient))", "drop-shadow(0 4px 6px var(--neba-shadow-ambient)) drop-shadow(0 18px 28px var(--neba-shadow-ambient))"];
151
+ /**
152
+ * The camera, drawn on the glass.
153
+ *
154
+ * Portrait puts it against the top edge and landscape against the leading one,
155
+ * which is where it goes on a real device turned the same way — and it is why
156
+ * the island does not collide with the status bar in landscape: it has moved out
157
+ * from under it.
158
+ */
159
+ export declare function MockupCutout({ notch, screen, landscape }: {
160
+ notch: NebaMockupNotch;
161
+ screen: NebaMockupResolution;
162
+ landscape: boolean;
163
+ }): React.JSX.Element | null;
164
+ /** What a system puts on the screen, and how much room it takes. */
165
+ export interface MockupChrome {
166
+ top?: {
167
+ size: number;
168
+ node: React.ReactNode;
169
+ };
170
+ bottom?: {
171
+ size: number;
172
+ node: React.ReactNode;
173
+ };
174
+ /** A dock down the leading edge. Only Linux has one. */
175
+ start?: {
176
+ size: number;
177
+ node: React.ReactNode;
178
+ };
179
+ }
180
+ /**
181
+ * The bars, per system.
182
+ *
183
+ * Each one takes its own space rather than floating over the content: a caller
184
+ * putting a screenshot in a mockup wants all of the screenshot, and a status bar
185
+ * that covered the top of it would be a crop nobody asked for. The cut-out is
186
+ * the exception, because that one really is a hole in the glass.
187
+ */
188
+ export declare function mockupChrome(options: {
189
+ os: NebaMockupOs;
190
+ notch: NebaMockupNotch;
191
+ landscape: boolean;
192
+ time: string;
193
+ }): MockupChrome;
@@ -0,0 +1 @@
1
+ import{jsx as e,jsxs as t}from"react/jsx-runtime";const i={desktop:["macos","windows","linux"],tablet:["ipados","android"],mobile:["ios","android"]};export function resolveOs(e,t){const n=i[e];return t&&n.includes(t)?t:"ios"===t&&"tablet"===e?"ipados":"ipados"===t&&"mobile"===e?"ios":n[0]}export function defaultNotch(e,t){return"mobile"!==e?"none":"android"===t?"punch-hole":"dynamic-island"}export const resolutions={mobile:{xs:{width:320,height:568},sm:{width:360,height:780},md:{width:390,height:844},lg:{width:414,height:896},xl:{width:430,height:932}},tablet:{xs:{width:744,height:1133},sm:{width:768,height:1024},md:{width:820,height:1180},lg:{width:834,height:1194},xl:{width:1024,height:1366}},desktop:{xs:{width:1024,height:640},sm:{width:1280,height:800},md:{width:1440,height:900},lg:{width:1680,height:1050},xl:{width:1920,height:1200}}};const n={mobile:{thin:{bezel:{x:8,top:8,bottom:8},frameRadius:50,screenRadius:42},standard:{bezel:{x:13,top:13,bottom:13},frameRadius:56,screenRadius:43},thick:{bezel:{x:16,top:62,bottom:62},frameRadius:40,screenRadius:4}},tablet:{thin:{bezel:{x:12,top:12,bottom:12},frameRadius:34,screenRadius:22},standard:{bezel:{x:20,top:20,bottom:20},frameRadius:42,screenRadius:22},thick:{bezel:{x:28,top:74,bottom:74},frameRadius:36,screenRadius:4}},desktop:{thin:{bezel:{x:8,top:8,bottom:8},frameRadius:12,screenRadius:4},standard:{bezel:{x:13,top:13,bottom:30},frameRadius:16,screenRadius:4},thick:{bezel:{x:22,top:22,bottom:62},frameRadius:18,screenRadius:3}}},a={mobile:42,tablet:24,desktop:8};export function mockupMetrics(e){const{device:t,size:i,resolution:r,orientation:d,bezel:h,hardware:s}=e,o=r??resolutions[t][i],l="desktop"!==t&&"landscape"===d,c=l?{width:o.height,height:o.width}:o;if("none"===h)return{screen:c,bezel:{x:0,top:0,bottom:0},body:{...c},frame:{...c},frameRadius:a[t],screenRadius:a[t],stand:null,base:null};const u=n[t][h],g=l?{x:u.bezel.top,top:u.bezel.x,bottom:u.bezel.x}:u.bezel,p="desktop"===t&&"laptop"===s,m=p?{...g,bottom:g.top}:g,x={width:c.width+2*m.x,height:c.height+m.top+m.bottom};if("desktop"!==t)return{screen:c,bezel:m,body:x,frame:{...x},frameRadius:u.frameRadius,screenRadius:u.screenRadius,stand:null,base:null};if(p){const e={width:Math.round(1.075*x.width),height:Math.round(.035*x.height),lipWidth:Math.round(.12*x.width)};return{screen:c,bezel:m,body:x,frame:{width:e.width,height:x.height+e.height},frameRadius:u.frameRadius,screenRadius:u.screenRadius,stand:null,base:e}}const b={neckWidth:Math.round(.11*x.width),neckHeight:Math.round(.09*x.height),footWidth:Math.round(.28*x.width),footHeight:Math.round(.018*x.height)};return{screen:c,bezel:m,body:x,frame:{width:x.width,height:x.height+b.neckHeight+b.footHeight},frameRadius:u.frameRadius,screenRadius:u.screenRadius,stand:b,base:null}}export const finishSlots={graphite:{"--n-shell":"oklch(27% 0.008 262)","--n-shell-edge":"rgb(255 255 255 / 0.16)","--n-shell-shade":"oklch(17% 0.008 262)"},silver:{"--n-shell":"oklch(83% 0.004 262)","--n-shell-edge":"rgb(255 255 255 / 0.75)","--n-shell-shade":"oklch(66% 0.006 262)"},white:{"--n-shell":"oklch(96% 0.002 262)","--n-shell-edge":"rgb(255 255 255 / 0.9)","--n-shell-shade":"oklch(80% 0.004 262)"}};export const shellClasses="bg-(--n-shell) [box-shadow:inset_0_1px_0_var(--n-shell-edge),inset_0_0_0_1px_var(--n-shell-shade)]";export const elevationFilters=["none","drop-shadow(0 1px 2px var(--neba-shadow-ambient))","drop-shadow(0 2px 4px var(--neba-shadow-ambient)) drop-shadow(0 8px 12px var(--neba-shadow-ambient))","drop-shadow(0 4px 6px var(--neba-shadow-ambient)) drop-shadow(0 18px 28px var(--neba-shadow-ambient))"];export function MockupCutout({notch:t,screen:i,landscape:n}){if("none"===t)return null;const a=n?i.height:i.width,r={position:"absolute",background:"oklch(12% 0.006 262)",pointerEvents:"none",zIndex:20},d="neba-mockup-cutout";if("punch-hole"===t){const t=Math.max(16,Math.round(.07*a)),i=Math.round(.55*t);return e("div",{"aria-hidden":"true",className:d,style:{...r,width:t,height:t,borderRadius:"50%",...n?{left:i,top:"50%",marginTop:-t/2}:{top:i,left:"50%",marginLeft:-t/2}}})}if("dynamic-island"===t){const t=Math.max(96,Math.round(.32*a)),i=Math.round(.29*t),h=Math.round(.32*i);return e("div",{"aria-hidden":"true",className:d,style:{...r,borderRadius:i,...n?{left:h,top:"50%",width:i,height:t,marginTop:-t/2}:{top:h,left:"50%",width:t,height:i,marginLeft:-t/2}}})}const h=Math.max(120,Math.round(.42*a)),s=Math.round(.23*h),o=Math.round(.6*s);return e("div",{"aria-hidden":"true",className:d,style:{...r,...n?{left:0,top:"50%",width:s,height:h,marginTop:-h/2,borderRadius:`0 ${o}px ${o}px 0`}:{top:0,left:"50%",width:h,height:s,marginLeft:-h/2,borderRadius:`0 0 ${o}px ${o}px`}}})}const r="relative z-10 flex shrink-0 items-center [background:color-mix(in_oklab,var(--neba-surface)_88%,transparent)]",d="font-medium text-(--neba-fg) tabular-nums";function h({width:t,height:i,radius:n,tone:a="muted"}){return e("div",{style:{width:t,height:i??t,borderRadius:n,background:"accent"===a?"var(--n-accent)":"faint"===a?"color-mix(in oklab, var(--neba-fg) 12%, transparent)":"color-mix(in oklab, var(--neba-fg) 26%, transparent)"}})}function s({count:t,size:i,radius:n,gap:a,accent:r=!1}){return e("div",{className:"flex items-center",style:{gap:a},children:Array.from({length:t},(t,a)=>e(h,{width:i,radius:n,tone:r&&0===a?"accent":"muted"},a))})}function o({height:i}){return t("svg",{viewBox:"0 0 17 11",height:i,width:17*i/11,fill:"currentColor","aria-hidden":"true",children:[e("rect",{y:"7.5",width:"3",height:"3.5",rx:"1"}),e("rect",{x:"4.7",y:"5",width:"3",height:"6",rx:"1"}),e("rect",{x:"9.4",y:"2.5",width:"3",height:"8.5",rx:"1"}),e("rect",{x:"14",width:"3",height:"11",rx:"1",opacity:"0.35"})]})}function l({height:i}){return t("svg",{viewBox:"0 0 16 12",height:i,width:16*i/12,fill:"none","aria-hidden":"true",children:[e("path",{d:"M1 4.2a10.5 10.5 0 0 1 14 0",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round"}),e("path",{d:"M3.6 7a6.8 6.8 0 0 1 8.8 0",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round"}),e("circle",{cx:"8",cy:"10.2",r:"1.6",fill:"currentColor"})]})}function c({height:i}){return t("svg",{viewBox:"0 0 25 12",height:i,width:25*i/12,fill:"none","aria-hidden":"true",children:[e("rect",{x:"0.7",y:"0.7",width:"20.6",height:"10.6",rx:"3.2",stroke:"currentColor",strokeWidth:"1.3",opacity:"0.45"}),e("rect",{x:"2.6",y:"2.6",width:"12.8",height:"6.8",rx:"1.8",fill:"currentColor"}),e("rect",{x:"22.8",y:"4",width:"1.8",height:"4",rx:"0.9",fill:"currentColor",opacity:"0.45"})]})}function u({height:i,gap:n}){return t("div",{className:"flex items-center text-(--neba-fg)",style:{gap:n},children:[e(o,{height:i}),e(l,{height:i}),e(c,{height:i})]})}function g({size:i,gap:n}){return t("div",{className:"flex items-center justify-center text-(--neba-fg)",style:{gap:n,opacity:.72},children:[e("svg",{viewBox:"0 0 16 16",width:i,height:i,fill:"none","aria-hidden":"true",children:e("path",{d:"M10 3 5 8l5 5",stroke:"currentColor",strokeWidth:"1.6",strokeLinecap:"round",strokeLinejoin:"round"})}),e("svg",{viewBox:"0 0 16 16",width:i,height:i,fill:"none","aria-hidden":"true",children:e("circle",{cx:"8",cy:"8",r:"5",stroke:"currentColor",strokeWidth:"1.6"})}),e("svg",{viewBox:"0 0 16 16",width:i,height:i,fill:"none","aria-hidden":"true",children:e("rect",{x:"3.5",y:"3.5",width:"9",height:"9",rx:"1.6",stroke:"currentColor",strokeWidth:"1.6"})})]})}function p({size:i}){return t("svg",{viewBox:"0 0 16 16",width:i,height:i,fill:"currentColor","aria-hidden":"true",children:[e("rect",{x:"1",y:"1",width:"6",height:"6",rx:"1.4"}),e("rect",{x:"9",y:"1",width:"6",height:"6",rx:"1.4"}),e("rect",{x:"1",y:"9",width:"6",height:"6",rx:"1.4"}),e("rect",{x:"9",y:"9",width:"6",height:"6",rx:"1.4"})]})}export function mockupChrome(i){const{os:n,notch:a,landscape:o,time:l}=i;if("ios"===n||"ipados"===n){const i="ipados"===n,h=i?30:!i&&!o&&"none"!==a&&"punch-hole"!==a?54:44;return{top:{size:h,node:t("div",{"aria-hidden":"true",className:`${r} justify-between`,style:{height:h,paddingInline:i?22:26},children:[e("span",{className:`${d} text-[15px]`,children:l}),e(u,{height:i?11:12,gap:6})]})},bottom:{size:i?22:34,node:e("div",{"aria-hidden":"true",className:`${r} justify-center`,style:{height:i?22:34,background:"transparent"},children:e("div",{style:{width:i?220:140,height:5,borderRadius:3,background:"color-mix(in oklab, var(--neba-fg) 55%, transparent)"}})})}}}return"android"===n?{top:{size:34,node:t("div",{"aria-hidden":"true",className:`${r} justify-between`,style:{height:34,paddingInline:18},children:[e("span",{className:`${d} text-[13px]`,children:l}),e(u,{height:11,gap:5})]})},bottom:{size:48,node:e("div",{"aria-hidden":"true",className:`${r} justify-center`,style:{height:48},children:e(g,{size:20,gap:72})})}}:"macos"===n?{top:{size:28,node:t("div",{"aria-hidden":"true",className:`${r} justify-between`,style:{height:28,paddingInline:16},children:[t("div",{className:"flex items-center",style:{gap:16},children:[e(h,{width:13,radius:4}),e(h,{width:34,height:7,radius:4}),e(h,{width:26,height:7,radius:4,tone:"faint"}),e(h,{width:30,height:7,radius:4,tone:"faint"}),e(h,{width:22,height:7,radius:4,tone:"faint"})]}),t("div",{className:"flex items-center",style:{gap:14},children:[e(h,{width:11,radius:3,tone:"faint"}),e(h,{width:11,radius:3,tone:"faint"}),e("span",{className:`${d} text-[13px]`,children:l})]})]})},bottom:{size:78,node:e("div",{"aria-hidden":"true",className:"flex shrink-0 items-end justify-center",style:{height:78},children:t("div",{className:`${r} [box-shadow:var(--neba-shadow-2),var(--neba-plate-glass)]`,style:{gap:10,padding:8,marginBottom:10,borderRadius:22},children:[e(s,{count:5,size:52,radius:14,gap:10,accent:!0}),e("div",{style:{width:1,height:44,background:"color-mix(in oklab, var(--neba-fg) 16%, transparent)"}}),e(s,{count:2,size:52,radius:14,gap:10})]})})}}:"windows"===n?{bottom:{size:52,node:t("div",{"aria-hidden":"true",className:`${r} justify-center [border-block-start:1px_solid_var(--neba-border)]`,style:{height:52,paddingInline:16},children:[t("div",{className:"flex items-center",style:{gap:10},children:[e("div",{className:"text-(--neba-fg)",style:{opacity:.7},children:e(p,{size:22})}),e(s,{count:6,size:30,radius:8,gap:10,accent:!0})]}),t("div",{className:"absolute flex items-center",style:{insetInlineEnd:16,gap:12},children:[e(h,{width:11,radius:3,tone:"faint"}),e(h,{width:11,radius:3,tone:"faint"}),e("span",{className:`${d} text-[12px]`,children:l})]})]})}}:{top:{size:34,node:t("div",{"aria-hidden":"true",className:`${r} justify-center`,style:{height:34,paddingInline:14},children:[e("div",{className:"absolute",style:{insetInlineStart:14},children:e(h,{width:52,height:9,radius:5})}),e("span",{className:`${d} text-[13px]`,children:l}),t("div",{className:"absolute flex items-center",style:{insetInlineEnd:14,gap:10},children:[e(h,{width:10,radius:3,tone:"faint"}),e(h,{width:10,radius:3,tone:"faint"}),e(h,{width:10,radius:3,tone:"faint"})]})]})},start:{size:66,node:t("div",{"aria-hidden":"true",className:`${r} flex-col justify-start [border-inline-end:1px_solid_var(--neba-border)]`,style:{width:66,height:"100%",gap:10,paddingBlock:12},children:[e(h,{width:44,radius:12,tone:"accent"}),e(h,{width:44,radius:12}),e(h,{width:44,radius:12}),e(h,{width:44,radius:12})]})}}}