@akcelik/strct 4.23.0 → 4.24.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/fesm2022/akcelik-strct.mjs +608 -10
- package/fesm2022/akcelik-strct.mjs.map +1 -1
- package/package.json +1 -1
- package/types/akcelik-strct.d.ts +86 -3
|
@@ -1515,13 +1515,79 @@ class StrctLogin {
|
|
|
1515
1515
|
...(ngDevMode ? [{ debugName: "maxWidth" }] : /* istanbul ignore next */ []));
|
|
1516
1516
|
/** Enable two-panel split layout. */
|
|
1517
1517
|
split = input(false, { ...(ngDevMode ? { debugName: "split" } : /* istanbul ignore next */ {}), transform: booleanAttribute });
|
|
1518
|
+
/**
|
|
1519
|
+
* The aside's built-in art: `network` is the node diagram over the glow and
|
|
1520
|
+
* dot grid; `grid` is the glow and grid alone. Palette tokens only, so it
|
|
1521
|
+
* follows every scheme, and it is decorative — hidden from assistive tech.
|
|
1522
|
+
*/
|
|
1523
|
+
art = input('none', /* @ts-ignore */
|
|
1524
|
+
...(ngDevMode ? [{ debugName: "art" }] : /* istanbul ignore next */ []));
|
|
1525
|
+
/** An icon tile beside the product name. */
|
|
1526
|
+
brandIcon = input('', /* @ts-ignore */
|
|
1527
|
+
...(ngDevMode ? [{ debugName: "brandIcon" }] : /* istanbul ignore next */ []));
|
|
1528
|
+
/** The product name, in the aside's brand row. */
|
|
1529
|
+
brandName = input('', /* @ts-ignore */
|
|
1530
|
+
...(ngDevMode ? [{ debugName: "brandName" }] : /* istanbul ignore next */ []));
|
|
1531
|
+
/** The kicker line above the aside's content. */
|
|
1532
|
+
tagline = input('', /* @ts-ignore */
|
|
1533
|
+
...(ngDevMode ? [{ debugName: "tagline" }] : /* istanbul ignore next */ []));
|
|
1534
|
+
/** The network's nodes: x, y, radius and which pulse phase they follow. */
|
|
1535
|
+
NODES = [
|
|
1536
|
+
{ x: 48, y: 96, r: 3, phase: 1 },
|
|
1537
|
+
{ x: 142, y: 158, r: 4.5, phase: 2 },
|
|
1538
|
+
{ x: 262, y: 118, r: 3, phase: 3 },
|
|
1539
|
+
{ x: 104, y: 272, r: 3, phase: 2 },
|
|
1540
|
+
{ x: 224, y: 312, r: 4.5, phase: 3 },
|
|
1541
|
+
{ x: 300, y: 222, r: 3, phase: 1 },
|
|
1542
|
+
];
|
|
1518
1543
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctLogin, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1519
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctLogin, isStandalone: true, selector: "strct-login", inputs: { maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, split: { classPropertyName: "split", publicName: "split", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "strct-login" }, ngImport: i0, template: `
|
|
1544
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctLogin, isStandalone: true, selector: "strct-login", inputs: { maxWidth: { classPropertyName: "maxWidth", publicName: "maxWidth", isSignal: true, isRequired: false, transformFunction: null }, split: { classPropertyName: "split", publicName: "split", isSignal: true, isRequired: false, transformFunction: null }, art: { classPropertyName: "art", publicName: "art", isSignal: true, isRequired: false, transformFunction: null }, brandIcon: { classPropertyName: "brandIcon", publicName: "brandIcon", isSignal: true, isRequired: false, transformFunction: null }, brandName: { classPropertyName: "brandName", publicName: "brandName", isSignal: true, isRequired: false, transformFunction: null }, tagline: { classPropertyName: "tagline", publicName: "tagline", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "strct-login" }, ngImport: i0, template: `
|
|
1520
1545
|
@if (split()) {
|
|
1521
1546
|
<div class="strct-login__card" [style.max-width.px]="maxWidth()">
|
|
1522
|
-
<aside class="strct-login__aside">
|
|
1547
|
+
<aside class="strct-login__aside" [attr.data-art]="art() === 'none' ? null : art()">
|
|
1548
|
+
@if (art() !== 'none') {
|
|
1549
|
+
<!-- Ambient layers, from palette tokens only, so the art follows
|
|
1550
|
+
every scheme. Decorative: hidden from assistive tech. -->
|
|
1551
|
+
<div class="strct-login__glow strct-login__glow--a" aria-hidden="true"></div>
|
|
1552
|
+
<div class="strct-login__glow strct-login__glow--b" aria-hidden="true"></div>
|
|
1553
|
+
<div class="strct-login__matrix" aria-hidden="true"></div>
|
|
1554
|
+
@if (art() === 'network') {
|
|
1555
|
+
<svg class="strct-login__net" viewBox="0 0 340 430" aria-hidden="true">
|
|
1556
|
+
<path
|
|
1557
|
+
class="strct-login__link"
|
|
1558
|
+
d="M48 96 L142 158 L262 118 M142 158 L104 272 L224 312 L300 222 L262 118"
|
|
1559
|
+
/>
|
|
1560
|
+
@for (n of NODES; track $index) {
|
|
1561
|
+
<circle
|
|
1562
|
+
class="strct-login__node strct-login__node--p{{ n.phase }}"
|
|
1563
|
+
[attr.cx]="n.x"
|
|
1564
|
+
[attr.cy]="n.y"
|
|
1565
|
+
[attr.r]="n.r"
|
|
1566
|
+
/>
|
|
1567
|
+
}
|
|
1568
|
+
</svg>
|
|
1569
|
+
}
|
|
1570
|
+
}
|
|
1523
1571
|
<div class="strct-login__aside-inner">
|
|
1524
|
-
|
|
1572
|
+
@if (brandIcon() || brandName()) {
|
|
1573
|
+
<div class="strct-login__brand">
|
|
1574
|
+
@if (brandIcon()) {
|
|
1575
|
+
<span class="strct-login__mark">
|
|
1576
|
+
<strct-icon [name]="brandIcon()" [size]="18" [strokeWidth]="1.5" />
|
|
1577
|
+
</span>
|
|
1578
|
+
}
|
|
1579
|
+
@if (brandName()) {
|
|
1580
|
+
<span class="strct-login__brandname">{{ brandName() }}</span>
|
|
1581
|
+
}
|
|
1582
|
+
</div>
|
|
1583
|
+
}
|
|
1584
|
+
<div class="strct-login__asidebody">
|
|
1585
|
+
@if (tagline()) {
|
|
1586
|
+
<div class="strct-login__kicker">{{ tagline() }}</div>
|
|
1587
|
+
}
|
|
1588
|
+
<ng-content select="[strctLoginAside]" />
|
|
1589
|
+
</div>
|
|
1590
|
+
<div class="strct-login__status"><ng-content select="[strctLoginStatus]" /></div>
|
|
1525
1591
|
</div>
|
|
1526
1592
|
</aside>
|
|
1527
1593
|
<div class="strct-login__main"><ng-content select="[strctLoginMain]" /></div>
|
|
@@ -1529,16 +1595,57 @@ class StrctLogin {
|
|
|
1529
1595
|
} @else {
|
|
1530
1596
|
<div class="strct-login__inner" [style.max-width.px]="maxWidth()"><ng-content /></div>
|
|
1531
1597
|
}
|
|
1532
|
-
`, isInline: true, styles: [".strct-login{display:flex;align-items:center;justify-content:center;width:100%;min-height:100%;padding:32px}.strct-login__inner{width:100%}.strct-login__card{display:grid;grid-template-columns:1.05fr 1fr;width:100%;overflow:hidden}.strct-login__main{padding:40px 38px;display:flex;flex-direction:column;justify-content:center}.strct-login__aside{position:relative;overflow:hidden;min-height:420px;color:var(--t1);border-inline-end:1px solid var(--b2)}.strct-login__aside:before,.strct-login__aside:after{display:none}.strct-login__aside-inner{position:relative;z-index:var(--z-base);height:100%;display:flex;flex-direction:column;justify-content:space-between;padding:34px 36px}@media(max-width:720px){.strct-login__card{grid-template-columns:1fr}.strct-login__aside{min-height:220px}.strct-login__main{padding:30px 26px}}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1598
|
+
`, isInline: true, styles: [".strct-login{display:flex;align-items:center;justify-content:center;width:100%;min-height:100%;padding:32px}.strct-login__inner{width:100%}.strct-login__card{display:grid;grid-template-columns:1.05fr 1fr;width:100%;overflow:hidden}.strct-login__main{padding:40px 38px;display:flex;flex-direction:column;justify-content:center}.strct-login__aside{position:relative;overflow:hidden;min-height:420px;color:var(--t1);border-inline-end:1px solid var(--b2)}.strct-login__aside:before,.strct-login__aside:after{display:none}.strct-login__aside-inner{position:relative;z-index:var(--z-base);height:100%;display:flex;flex-direction:column;justify-content:space-between;gap:var(--space-5);padding:34px 36px}.strct-login__glow,.strct-login__matrix,.strct-login__net{position:absolute;inset:-36px;pointer-events:none}.strct-login__glow{filter:blur(46px)}.strct-login__glow--a{background:radial-gradient(360px 300px at 12% 8%,var(--acc30),transparent 70%)}.strct-login__glow--b{background:radial-gradient(320px 300px at 92% 96%,var(--acc18),transparent 70%)}.strct-login__matrix{background-image:radial-gradient(var(--acc30) 1px,transparent 1.4px);background-size:22px 22px;opacity:.4;-webkit-mask-image:linear-gradient(155deg,rgba(0,0,0,.9),transparent 72%);mask-image:linear-gradient(155deg,rgba(0,0,0,.9),transparent 72%)}.strct-login__net{width:calc(100% + 72px);height:calc(100% + 72px)}.strct-login__link{fill:none;stroke:var(--acc30);stroke-width:1}.strct-login__node{fill:var(--acc);opacity:.55}@media(prefers-reduced-motion:no-preference){.strct-login__node{animation:strct-login-pulse 4.5s ease-in-out infinite}.strct-login__node--p2{animation-delay:1.4s}.strct-login__node--p3{animation-delay:2.8s}}@keyframes strct-login-pulse{0%,to{opacity:.35}50%{opacity:.85}}.strct-login__brand{position:relative;display:flex;align-items:center;flex-wrap:wrap;gap:10px}.strct-login__mark{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:9px;background:var(--acc-m);border:1px solid var(--acc30);color:var(--acc)}.strct-login__brandname{font-size:13px;font-weight:700;letter-spacing:2px;color:var(--t1)}.strct-login__asidebody{position:relative}.strct-login__kicker{font-size:11.5px;font-weight:700;letter-spacing:1.6px;text-transform:uppercase;margin-block-end:10px;color:var(--acc)}.strct-login__status:empty{display:none}.strct-login__status{position:relative}@media(max-width:720px){.strct-login__card{grid-template-columns:1fr}.strct-login__aside{min-height:220px}.strct-login__main{padding:30px 26px}}\n"], dependencies: [{ kind: "component", type: StrctIcon, selector: "strct-icon", inputs: ["name", "strictName", "size", "strokeWidth", "badge", "ariaLabel", "count", "countMax", "countStatus", "countLabel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
1533
1599
|
}
|
|
1534
1600
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctLogin, decorators: [{
|
|
1535
1601
|
type: Component,
|
|
1536
|
-
args: [{ selector: 'strct-login', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: `
|
|
1602
|
+
args: [{ selector: 'strct-login', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, imports: [StrctIcon], template: `
|
|
1537
1603
|
@if (split()) {
|
|
1538
1604
|
<div class="strct-login__card" [style.max-width.px]="maxWidth()">
|
|
1539
|
-
<aside class="strct-login__aside">
|
|
1605
|
+
<aside class="strct-login__aside" [attr.data-art]="art() === 'none' ? null : art()">
|
|
1606
|
+
@if (art() !== 'none') {
|
|
1607
|
+
<!-- Ambient layers, from palette tokens only, so the art follows
|
|
1608
|
+
every scheme. Decorative: hidden from assistive tech. -->
|
|
1609
|
+
<div class="strct-login__glow strct-login__glow--a" aria-hidden="true"></div>
|
|
1610
|
+
<div class="strct-login__glow strct-login__glow--b" aria-hidden="true"></div>
|
|
1611
|
+
<div class="strct-login__matrix" aria-hidden="true"></div>
|
|
1612
|
+
@if (art() === 'network') {
|
|
1613
|
+
<svg class="strct-login__net" viewBox="0 0 340 430" aria-hidden="true">
|
|
1614
|
+
<path
|
|
1615
|
+
class="strct-login__link"
|
|
1616
|
+
d="M48 96 L142 158 L262 118 M142 158 L104 272 L224 312 L300 222 L262 118"
|
|
1617
|
+
/>
|
|
1618
|
+
@for (n of NODES; track $index) {
|
|
1619
|
+
<circle
|
|
1620
|
+
class="strct-login__node strct-login__node--p{{ n.phase }}"
|
|
1621
|
+
[attr.cx]="n.x"
|
|
1622
|
+
[attr.cy]="n.y"
|
|
1623
|
+
[attr.r]="n.r"
|
|
1624
|
+
/>
|
|
1625
|
+
}
|
|
1626
|
+
</svg>
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1540
1629
|
<div class="strct-login__aside-inner">
|
|
1541
|
-
|
|
1630
|
+
@if (brandIcon() || brandName()) {
|
|
1631
|
+
<div class="strct-login__brand">
|
|
1632
|
+
@if (brandIcon()) {
|
|
1633
|
+
<span class="strct-login__mark">
|
|
1634
|
+
<strct-icon [name]="brandIcon()" [size]="18" [strokeWidth]="1.5" />
|
|
1635
|
+
</span>
|
|
1636
|
+
}
|
|
1637
|
+
@if (brandName()) {
|
|
1638
|
+
<span class="strct-login__brandname">{{ brandName() }}</span>
|
|
1639
|
+
}
|
|
1640
|
+
</div>
|
|
1641
|
+
}
|
|
1642
|
+
<div class="strct-login__asidebody">
|
|
1643
|
+
@if (tagline()) {
|
|
1644
|
+
<div class="strct-login__kicker">{{ tagline() }}</div>
|
|
1645
|
+
}
|
|
1646
|
+
<ng-content select="[strctLoginAside]" />
|
|
1647
|
+
</div>
|
|
1648
|
+
<div class="strct-login__status"><ng-content select="[strctLoginStatus]" /></div>
|
|
1542
1649
|
</div>
|
|
1543
1650
|
</aside>
|
|
1544
1651
|
<div class="strct-login__main"><ng-content select="[strctLoginMain]" /></div>
|
|
@@ -1546,8 +1653,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
1546
1653
|
} @else {
|
|
1547
1654
|
<div class="strct-login__inner" [style.max-width.px]="maxWidth()"><ng-content /></div>
|
|
1548
1655
|
}
|
|
1549
|
-
`, host: { class: 'strct-login' }, styles: [".strct-login{display:flex;align-items:center;justify-content:center;width:100%;min-height:100%;padding:32px}.strct-login__inner{width:100%}.strct-login__card{display:grid;grid-template-columns:1.05fr 1fr;width:100%;overflow:hidden}.strct-login__main{padding:40px 38px;display:flex;flex-direction:column;justify-content:center}.strct-login__aside{position:relative;overflow:hidden;min-height:420px;color:var(--t1);border-inline-end:1px solid var(--b2)}.strct-login__aside:before,.strct-login__aside:after{display:none}.strct-login__aside-inner{position:relative;z-index:var(--z-base);height:100%;display:flex;flex-direction:column;justify-content:space-between;padding:34px 36px}@media(max-width:720px){.strct-login__card{grid-template-columns:1fr}.strct-login__aside{min-height:220px}.strct-login__main{padding:30px 26px}}\n"] }]
|
|
1550
|
-
}], propDecorators: { maxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxWidth", required: false }] }], split: [{ type: i0.Input, args: [{ isSignal: true, alias: "split", required: false }] }] } });
|
|
1656
|
+
`, host: { class: 'strct-login' }, styles: [".strct-login{display:flex;align-items:center;justify-content:center;width:100%;min-height:100%;padding:32px}.strct-login__inner{width:100%}.strct-login__card{display:grid;grid-template-columns:1.05fr 1fr;width:100%;overflow:hidden}.strct-login__main{padding:40px 38px;display:flex;flex-direction:column;justify-content:center}.strct-login__aside{position:relative;overflow:hidden;min-height:420px;color:var(--t1);border-inline-end:1px solid var(--b2)}.strct-login__aside:before,.strct-login__aside:after{display:none}.strct-login__aside-inner{position:relative;z-index:var(--z-base);height:100%;display:flex;flex-direction:column;justify-content:space-between;gap:var(--space-5);padding:34px 36px}.strct-login__glow,.strct-login__matrix,.strct-login__net{position:absolute;inset:-36px;pointer-events:none}.strct-login__glow{filter:blur(46px)}.strct-login__glow--a{background:radial-gradient(360px 300px at 12% 8%,var(--acc30),transparent 70%)}.strct-login__glow--b{background:radial-gradient(320px 300px at 92% 96%,var(--acc18),transparent 70%)}.strct-login__matrix{background-image:radial-gradient(var(--acc30) 1px,transparent 1.4px);background-size:22px 22px;opacity:.4;-webkit-mask-image:linear-gradient(155deg,rgba(0,0,0,.9),transparent 72%);mask-image:linear-gradient(155deg,rgba(0,0,0,.9),transparent 72%)}.strct-login__net{width:calc(100% + 72px);height:calc(100% + 72px)}.strct-login__link{fill:none;stroke:var(--acc30);stroke-width:1}.strct-login__node{fill:var(--acc);opacity:.55}@media(prefers-reduced-motion:no-preference){.strct-login__node{animation:strct-login-pulse 4.5s ease-in-out infinite}.strct-login__node--p2{animation-delay:1.4s}.strct-login__node--p3{animation-delay:2.8s}}@keyframes strct-login-pulse{0%,to{opacity:.35}50%{opacity:.85}}.strct-login__brand{position:relative;display:flex;align-items:center;flex-wrap:wrap;gap:10px}.strct-login__mark{display:inline-flex;align-items:center;justify-content:center;width:34px;height:34px;border-radius:9px;background:var(--acc-m);border:1px solid var(--acc30);color:var(--acc)}.strct-login__brandname{font-size:13px;font-weight:700;letter-spacing:2px;color:var(--t1)}.strct-login__asidebody{position:relative}.strct-login__kicker{font-size:11.5px;font-weight:700;letter-spacing:1.6px;text-transform:uppercase;margin-block-end:10px;color:var(--acc)}.strct-login__status:empty{display:none}.strct-login__status{position:relative}@media(max-width:720px){.strct-login__card{grid-template-columns:1fr}.strct-login__aside{min-height:220px}.strct-login__main{padding:30px 26px}}\n"] }]
|
|
1657
|
+
}], propDecorators: { maxWidth: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxWidth", required: false }] }], split: [{ type: i0.Input, args: [{ isSignal: true, alias: "split", required: false }] }], art: [{ type: i0.Input, args: [{ isSignal: true, alias: "art", required: false }] }], brandIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "brandIcon", required: false }] }], brandName: [{ type: i0.Input, args: [{ isSignal: true, alias: "brandName", required: false }] }], tagline: [{ type: i0.Input, args: [{ isSignal: true, alias: "tagline", required: false }] }] } });
|
|
1551
1658
|
|
|
1552
1659
|
/** Marks the breadcrumb row projected above the title. */
|
|
1553
1660
|
class StrctPageHeaderCrumbs {
|
|
@@ -24050,6 +24157,497 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
24050
24157
|
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], maxRows: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxRows", required: false }] }], sendLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "sendLabel", required: false }] }], send: [{ type: i0.Output, args: ["send"] }] } });
|
|
24051
24158
|
let composerCounter = 0;
|
|
24052
24159
|
|
|
24160
|
+
/**
|
|
24161
|
+
* A small, dependency-free QR encoder: byte mode, versions 1–10, the four error
|
|
24162
|
+
* correction levels. Enough for an `otpauth://` URI, which is what the library
|
|
24163
|
+
* needs it for — and nothing more, so it stays readable.
|
|
24164
|
+
*
|
|
24165
|
+
* The maths is the standard one (ISO/IEC 18004): the data is split into
|
|
24166
|
+
* codewords, Reed–Solomon parity is appended per block, the result is laid into
|
|
24167
|
+
* the matrix around the function patterns, and each of the eight masks is
|
|
24168
|
+
* scored so the best one is chosen.
|
|
24169
|
+
*/
|
|
24170
|
+
/** Total codewords per version (1–10), index 0 = version 1. */
|
|
24171
|
+
const TOTAL_CODEWORDS = [26, 44, 70, 100, 134, 172, 196, 242, 292, 346];
|
|
24172
|
+
/**
|
|
24173
|
+
* Per version and level: [ec codewords per block, block count group 1,
|
|
24174
|
+
* block count group 2]. Group 2's blocks hold one more data codeword each.
|
|
24175
|
+
*/
|
|
24176
|
+
const ECC_TABLE = {
|
|
24177
|
+
L: [
|
|
24178
|
+
[7, 1, 0],
|
|
24179
|
+
[10, 1, 0],
|
|
24180
|
+
[15, 1, 0],
|
|
24181
|
+
[20, 1, 0],
|
|
24182
|
+
[26, 1, 0],
|
|
24183
|
+
[18, 2, 0],
|
|
24184
|
+
[20, 2, 0],
|
|
24185
|
+
[24, 2, 0],
|
|
24186
|
+
[30, 2, 0],
|
|
24187
|
+
[18, 2, 2],
|
|
24188
|
+
],
|
|
24189
|
+
M: [
|
|
24190
|
+
[10, 1, 0],
|
|
24191
|
+
[16, 1, 0],
|
|
24192
|
+
[26, 1, 0],
|
|
24193
|
+
[18, 2, 0],
|
|
24194
|
+
[24, 2, 0],
|
|
24195
|
+
[16, 4, 0],
|
|
24196
|
+
[18, 4, 0],
|
|
24197
|
+
[22, 2, 2],
|
|
24198
|
+
[22, 3, 2],
|
|
24199
|
+
[26, 4, 1],
|
|
24200
|
+
],
|
|
24201
|
+
Q: [
|
|
24202
|
+
[13, 1, 0],
|
|
24203
|
+
[22, 1, 0],
|
|
24204
|
+
[18, 2, 0],
|
|
24205
|
+
[26, 2, 0],
|
|
24206
|
+
[18, 2, 2],
|
|
24207
|
+
[24, 4, 0],
|
|
24208
|
+
[18, 2, 4],
|
|
24209
|
+
[22, 4, 2],
|
|
24210
|
+
[20, 4, 4],
|
|
24211
|
+
[24, 6, 2],
|
|
24212
|
+
],
|
|
24213
|
+
H: [
|
|
24214
|
+
[17, 1, 0],
|
|
24215
|
+
[28, 1, 0],
|
|
24216
|
+
[22, 2, 0],
|
|
24217
|
+
[16, 4, 0],
|
|
24218
|
+
[22, 2, 2],
|
|
24219
|
+
[28, 4, 0],
|
|
24220
|
+
[26, 4, 1],
|
|
24221
|
+
[26, 4, 2],
|
|
24222
|
+
[24, 4, 4],
|
|
24223
|
+
[28, 6, 2],
|
|
24224
|
+
],
|
|
24225
|
+
};
|
|
24226
|
+
/** Alignment-pattern centres per version (1–10). */
|
|
24227
|
+
const ALIGNMENT = [
|
|
24228
|
+
[],
|
|
24229
|
+
[6, 18],
|
|
24230
|
+
[6, 22],
|
|
24231
|
+
[6, 26],
|
|
24232
|
+
[6, 30],
|
|
24233
|
+
[6, 34],
|
|
24234
|
+
[6, 22, 38],
|
|
24235
|
+
[6, 24, 42],
|
|
24236
|
+
[6, 26, 46],
|
|
24237
|
+
[6, 28, 50],
|
|
24238
|
+
];
|
|
24239
|
+
/** Format-information bits per (level, mask), already masked per the spec. */
|
|
24240
|
+
const FORMAT_BITS = {
|
|
24241
|
+
L: [0x77c4, 0x72f3, 0x7daa, 0x789d, 0x662f, 0x6318, 0x6c41, 0x6976],
|
|
24242
|
+
M: [0x5412, 0x5125, 0x5e7c, 0x5b4b, 0x45f9, 0x40ce, 0x4f97, 0x4aa0],
|
|
24243
|
+
Q: [0x355f, 0x3068, 0x3f31, 0x3a06, 0x24b4, 0x2183, 0x2eda, 0x2bed],
|
|
24244
|
+
H: [0x1689, 0x13be, 0x1ce7, 0x19d0, 0x0762, 0x0255, 0x0d0c, 0x083b],
|
|
24245
|
+
};
|
|
24246
|
+
// ── Galois field (2^8) with the QR primitive polynomial 0x11d ───────────────
|
|
24247
|
+
const EXP = new Uint8Array(512);
|
|
24248
|
+
const LOG = new Uint8Array(256);
|
|
24249
|
+
{
|
|
24250
|
+
let x = 1;
|
|
24251
|
+
for (let i = 0; i < 255; i++) {
|
|
24252
|
+
EXP[i] = x;
|
|
24253
|
+
LOG[x] = i;
|
|
24254
|
+
x <<= 1;
|
|
24255
|
+
if (x & 0x100)
|
|
24256
|
+
x ^= 0x11d;
|
|
24257
|
+
}
|
|
24258
|
+
for (let i = 255; i < 512; i++)
|
|
24259
|
+
EXP[i] = EXP[i - 255];
|
|
24260
|
+
}
|
|
24261
|
+
const mul = (a, b) => (a && b ? EXP[LOG[a] + LOG[b]] : 0);
|
|
24262
|
+
/** The generator polynomial for `degree` error-correction codewords. */
|
|
24263
|
+
function generator(degree) {
|
|
24264
|
+
let poly = [1];
|
|
24265
|
+
for (let i = 0; i < degree; i++) {
|
|
24266
|
+
const next = new Array(poly.length + 1).fill(0);
|
|
24267
|
+
for (let j = 0; j < poly.length; j++) {
|
|
24268
|
+
// Descending coefficients: x * poly keeps the index, α^i * poly shifts.
|
|
24269
|
+
next[j] ^= poly[j];
|
|
24270
|
+
next[j + 1] ^= mul(poly[j], EXP[i]);
|
|
24271
|
+
}
|
|
24272
|
+
poly = next;
|
|
24273
|
+
}
|
|
24274
|
+
return poly;
|
|
24275
|
+
}
|
|
24276
|
+
/** Reed–Solomon parity for one block. */
|
|
24277
|
+
function remainder(data, degree) {
|
|
24278
|
+
const gen = generator(degree);
|
|
24279
|
+
const out = new Array(degree).fill(0);
|
|
24280
|
+
for (const byte of data) {
|
|
24281
|
+
const factor = byte ^ out[0];
|
|
24282
|
+
out.shift();
|
|
24283
|
+
out.push(0);
|
|
24284
|
+
for (let i = 0; i < degree; i++)
|
|
24285
|
+
out[i] ^= mul(gen[i + 1], factor);
|
|
24286
|
+
}
|
|
24287
|
+
return out;
|
|
24288
|
+
}
|
|
24289
|
+
/** The smallest version (1–10) that holds `byteLength` bytes at `ecc`. */
|
|
24290
|
+
function chooseVersion(byteLength, ecc) {
|
|
24291
|
+
for (let version = 1; version <= 10; version++) {
|
|
24292
|
+
const [ecPerBlock, g1, g2] = ECC_TABLE[ecc][version - 1];
|
|
24293
|
+
const dataCodewords = TOTAL_CODEWORDS[version - 1] - ecPerBlock * (g1 + g2);
|
|
24294
|
+
// 4 bits of mode + 8 or 16 bits of length, rounded up to whole codewords.
|
|
24295
|
+
const headerBits = 4 + (version < 10 ? 8 : 16);
|
|
24296
|
+
if (dataCodewords * 8 >= headerBits + byteLength * 8)
|
|
24297
|
+
return version;
|
|
24298
|
+
}
|
|
24299
|
+
throw new Error('strct-qr: the value is too long (versions 1–10, byte mode)');
|
|
24300
|
+
}
|
|
24301
|
+
/** The data codewords: mode, length, the bytes, a terminator, then padding. */
|
|
24302
|
+
function dataCodewords(bytes, version, ecc) {
|
|
24303
|
+
const [ecPerBlock, g1, g2] = ECC_TABLE[ecc][version - 1];
|
|
24304
|
+
const capacity = TOTAL_CODEWORDS[version - 1] - ecPerBlock * (g1 + g2);
|
|
24305
|
+
const bits = [];
|
|
24306
|
+
const push = (value, length) => {
|
|
24307
|
+
for (let i = length - 1; i >= 0; i--)
|
|
24308
|
+
bits.push((value >> i) & 1);
|
|
24309
|
+
};
|
|
24310
|
+
push(0b0100, 4); // byte mode
|
|
24311
|
+
push(bytes.length, version < 10 ? 8 : 16);
|
|
24312
|
+
for (const b of bytes)
|
|
24313
|
+
push(b, 8);
|
|
24314
|
+
push(0, Math.min(4, capacity * 8 - bits.length)); // terminator
|
|
24315
|
+
while (bits.length % 8)
|
|
24316
|
+
bits.push(0);
|
|
24317
|
+
const words = [];
|
|
24318
|
+
for (let i = 0; i < bits.length; i += 8) {
|
|
24319
|
+
words.push(bits.slice(i, i + 8).reduce((acc, bit) => (acc << 1) | bit, 0));
|
|
24320
|
+
}
|
|
24321
|
+
// Alternating pad bytes, as the spec prescribes.
|
|
24322
|
+
for (let i = 0; words.length < capacity; i++)
|
|
24323
|
+
words.push(i % 2 === 0 ? 0xec : 0x11);
|
|
24324
|
+
return words;
|
|
24325
|
+
}
|
|
24326
|
+
/** Interleave the blocks' data and parity, as the spec lays them out. */
|
|
24327
|
+
function interleave(words, version, ecc) {
|
|
24328
|
+
const [ecPerBlock, g1, g2] = ECC_TABLE[ecc][version - 1];
|
|
24329
|
+
const blocks = g1 + g2;
|
|
24330
|
+
const shortLen = Math.floor(words.length / blocks);
|
|
24331
|
+
const data = [];
|
|
24332
|
+
const parity = [];
|
|
24333
|
+
let at = 0;
|
|
24334
|
+
for (let i = 0; i < blocks; i++) {
|
|
24335
|
+
const len = i < g1 ? shortLen : shortLen + 1;
|
|
24336
|
+
const block = words.slice(at, at + len);
|
|
24337
|
+
at += len;
|
|
24338
|
+
data.push(block);
|
|
24339
|
+
parity.push(remainder(block, ecPerBlock));
|
|
24340
|
+
}
|
|
24341
|
+
const out = [];
|
|
24342
|
+
for (let i = 0; i < shortLen + 1; i++) {
|
|
24343
|
+
for (const block of data)
|
|
24344
|
+
if (i < block.length)
|
|
24345
|
+
out.push(block[i]);
|
|
24346
|
+
}
|
|
24347
|
+
for (let i = 0; i < ecPerBlock; i++)
|
|
24348
|
+
for (const block of parity)
|
|
24349
|
+
out.push(block[i]);
|
|
24350
|
+
return out;
|
|
24351
|
+
}
|
|
24352
|
+
var Cell;
|
|
24353
|
+
(function (Cell) {
|
|
24354
|
+
Cell[Cell["Empty"] = -1] = "Empty";
|
|
24355
|
+
Cell[Cell["Light"] = 0] = "Light";
|
|
24356
|
+
Cell[Cell["Dark"] = 1] = "Dark";
|
|
24357
|
+
})(Cell || (Cell = {}));
|
|
24358
|
+
/** Draw the finder, timing and alignment patterns, and reserve the format area. */
|
|
24359
|
+
function functionPatterns(size, version) {
|
|
24360
|
+
const m = Array.from({ length: size }, () => new Array(size).fill(Cell.Empty));
|
|
24361
|
+
const finder = (r0, c0) => {
|
|
24362
|
+
for (let dr = -1; dr <= 7; dr++) {
|
|
24363
|
+
for (let dc = -1; dc <= 7; dc++) {
|
|
24364
|
+
const r = r0 + dr;
|
|
24365
|
+
const c = c0 + dc;
|
|
24366
|
+
if (r < 0 || r >= size || c < 0 || c >= size)
|
|
24367
|
+
continue;
|
|
24368
|
+
const inner = Math.max(Math.abs(dr - 3), Math.abs(dc - 3));
|
|
24369
|
+
m[r][c] = inner === 2 || inner > 3 ? Cell.Light : Cell.Dark;
|
|
24370
|
+
}
|
|
24371
|
+
}
|
|
24372
|
+
};
|
|
24373
|
+
finder(0, 0);
|
|
24374
|
+
finder(0, size - 7);
|
|
24375
|
+
finder(size - 7, 0);
|
|
24376
|
+
for (let i = 8; i < size - 8; i++) {
|
|
24377
|
+
m[6][i] = m[i][6] = i % 2 === 0 ? Cell.Dark : Cell.Light;
|
|
24378
|
+
}
|
|
24379
|
+
const centres = ALIGNMENT[version - 1];
|
|
24380
|
+
for (const r of centres) {
|
|
24381
|
+
for (const c of centres) {
|
|
24382
|
+
// Not over a finder pattern.
|
|
24383
|
+
if ((r === 6 && c === 6) || (r === 6 && c === size - 7) || (r === size - 7 && c === 6))
|
|
24384
|
+
continue;
|
|
24385
|
+
for (let dr = -2; dr <= 2; dr++) {
|
|
24386
|
+
for (let dc = -2; dc <= 2; dc++) {
|
|
24387
|
+
m[r + dr][c + dc] = Math.max(Math.abs(dr), Math.abs(dc)) === 1 ? Cell.Light : Cell.Dark;
|
|
24388
|
+
}
|
|
24389
|
+
}
|
|
24390
|
+
}
|
|
24391
|
+
}
|
|
24392
|
+
// The dark module, always set.
|
|
24393
|
+
m[size - 8][8] = Cell.Dark;
|
|
24394
|
+
// Reserve the format areas so the data does not land there.
|
|
24395
|
+
for (let i = 0; i < 9; i++) {
|
|
24396
|
+
if (m[8][i] === Cell.Empty)
|
|
24397
|
+
m[8][i] = Cell.Light;
|
|
24398
|
+
if (m[i][8] === Cell.Empty)
|
|
24399
|
+
m[i][8] = Cell.Light;
|
|
24400
|
+
}
|
|
24401
|
+
for (let i = 0; i < 8; i++) {
|
|
24402
|
+
if (m[8][size - 1 - i] === Cell.Empty)
|
|
24403
|
+
m[8][size - 1 - i] = Cell.Light;
|
|
24404
|
+
if (m[size - 1 - i][8] === Cell.Empty)
|
|
24405
|
+
m[size - 1 - i][8] = Cell.Light;
|
|
24406
|
+
}
|
|
24407
|
+
return m;
|
|
24408
|
+
}
|
|
24409
|
+
const MASKS = [
|
|
24410
|
+
(r, c) => (r + c) % 2 === 0,
|
|
24411
|
+
(r) => r % 2 === 0,
|
|
24412
|
+
(_r, c) => c % 3 === 0,
|
|
24413
|
+
(r, c) => (r + c) % 3 === 0,
|
|
24414
|
+
(r, c) => (Math.floor(r / 2) + Math.floor(c / 3)) % 2 === 0,
|
|
24415
|
+
(r, c) => ((r * c) % 2) + ((r * c) % 3) === 0,
|
|
24416
|
+
(r, c) => (((r * c) % 2) + ((r * c) % 3)) % 2 === 0,
|
|
24417
|
+
(r, c) => (((r + c) % 2) + ((r * c) % 3)) % 2 === 0,
|
|
24418
|
+
];
|
|
24419
|
+
/** The spec's penalty score — lower is better. */
|
|
24420
|
+
function penalty(m) {
|
|
24421
|
+
const size = m.length;
|
|
24422
|
+
let score = 0;
|
|
24423
|
+
const run = (line) => {
|
|
24424
|
+
let last = line[0];
|
|
24425
|
+
let length = 1;
|
|
24426
|
+
for (let i = 1; i < line.length; i++) {
|
|
24427
|
+
if (line[i] === last)
|
|
24428
|
+
length++;
|
|
24429
|
+
else {
|
|
24430
|
+
if (length >= 5)
|
|
24431
|
+
score += 3 + (length - 5);
|
|
24432
|
+
last = line[i];
|
|
24433
|
+
length = 1;
|
|
24434
|
+
}
|
|
24435
|
+
}
|
|
24436
|
+
if (length >= 5)
|
|
24437
|
+
score += 3 + (length - 5);
|
|
24438
|
+
};
|
|
24439
|
+
for (let i = 0; i < size; i++) {
|
|
24440
|
+
run(m[i]);
|
|
24441
|
+
run(m.map((row) => row[i]));
|
|
24442
|
+
}
|
|
24443
|
+
for (let r = 0; r < size - 1; r++) {
|
|
24444
|
+
for (let c = 0; c < size - 1; c++) {
|
|
24445
|
+
const v = m[r][c];
|
|
24446
|
+
if (v === m[r][c + 1] && v === m[r + 1][c] && v === m[r + 1][c + 1])
|
|
24447
|
+
score += 3;
|
|
24448
|
+
}
|
|
24449
|
+
}
|
|
24450
|
+
const pattern = [1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0];
|
|
24451
|
+
const hasPattern = (line, at) => pattern.every((bit, i) => line[at + i] === bit);
|
|
24452
|
+
for (let i = 0; i < size; i++) {
|
|
24453
|
+
const row = m[i];
|
|
24454
|
+
const col = m.map((r) => r[i]);
|
|
24455
|
+
for (let j = 0; j + 11 <= size; j++) {
|
|
24456
|
+
if (hasPattern(row, j))
|
|
24457
|
+
score += 40;
|
|
24458
|
+
if (hasPattern(col, j))
|
|
24459
|
+
score += 40;
|
|
24460
|
+
const rRev = [...row].reverse();
|
|
24461
|
+
const cRev = [...col].reverse();
|
|
24462
|
+
if (hasPattern(rRev, j))
|
|
24463
|
+
score += 40;
|
|
24464
|
+
if (hasPattern(cRev, j))
|
|
24465
|
+
score += 40;
|
|
24466
|
+
}
|
|
24467
|
+
}
|
|
24468
|
+
const dark = m.flat().filter((v) => v === Cell.Dark).length;
|
|
24469
|
+
const ratio = (dark * 100) / (size * size);
|
|
24470
|
+
score += Math.floor(Math.abs(ratio - 50) / 5) * 10;
|
|
24471
|
+
return score;
|
|
24472
|
+
}
|
|
24473
|
+
/**
|
|
24474
|
+
* Encode `value` as a QR matrix of booleans (true = dark module), without the
|
|
24475
|
+
* quiet zone — the renderer adds that.
|
|
24476
|
+
*/
|
|
24477
|
+
function strctQrMatrix(value, ecc = 'M') {
|
|
24478
|
+
const bytes = new TextEncoder().encode(value);
|
|
24479
|
+
const version = chooseVersion(bytes.length, ecc);
|
|
24480
|
+
const size = version * 4 + 17;
|
|
24481
|
+
const codewords = interleave(dataCodewords(bytes, version, ecc), version, ecc);
|
|
24482
|
+
const base = functionPatterns(size, version);
|
|
24483
|
+
const reserved = base.map((row) => row.map((v) => v !== Cell.Empty));
|
|
24484
|
+
// Lay the data in the zig-zag, skipping the vertical timing column.
|
|
24485
|
+
const bits = [];
|
|
24486
|
+
for (const word of codewords)
|
|
24487
|
+
for (let i = 7; i >= 0; i--)
|
|
24488
|
+
bits.push((word >> i) & 1);
|
|
24489
|
+
let bit = 0;
|
|
24490
|
+
const matrix = base.map((row) => [...row]);
|
|
24491
|
+
for (let right = size - 1; right >= 1; right -= 2) {
|
|
24492
|
+
if (right === 6)
|
|
24493
|
+
right = 5;
|
|
24494
|
+
for (let vert = 0; vert < size; vert++) {
|
|
24495
|
+
for (let j = 0; j < 2; j++) {
|
|
24496
|
+
const c = right - j;
|
|
24497
|
+
const upward = ((right + 1) & 2) === 0;
|
|
24498
|
+
const r = upward ? size - 1 - vert : vert;
|
|
24499
|
+
if (reserved[r][c])
|
|
24500
|
+
continue;
|
|
24501
|
+
matrix[r][c] = bit < bits.length ? bits[bit++] : Cell.Light;
|
|
24502
|
+
}
|
|
24503
|
+
}
|
|
24504
|
+
}
|
|
24505
|
+
// Pick the mask with the lowest penalty, then write the format bits.
|
|
24506
|
+
let best = null;
|
|
24507
|
+
let bestMask = 0;
|
|
24508
|
+
let bestScore = Infinity;
|
|
24509
|
+
for (let mask = 0; mask < 8; mask++) {
|
|
24510
|
+
const candidate = matrix.map((row, r) => row.map((v, c) => (reserved[r][c] ? v : v ^ (MASKS[mask](r, c) ? 1 : 0))));
|
|
24511
|
+
writeFormat(candidate, ecc, mask);
|
|
24512
|
+
const score = penalty(candidate);
|
|
24513
|
+
if (score < bestScore) {
|
|
24514
|
+
bestScore = score;
|
|
24515
|
+
best = candidate;
|
|
24516
|
+
bestMask = mask;
|
|
24517
|
+
}
|
|
24518
|
+
}
|
|
24519
|
+
void bestMask;
|
|
24520
|
+
return best.map((row) => row.map((v) => v === Cell.Dark));
|
|
24521
|
+
}
|
|
24522
|
+
/** The 15 format bits, written in both of their places. */
|
|
24523
|
+
function writeFormat(m, ecc, mask) {
|
|
24524
|
+
const size = m.length;
|
|
24525
|
+
const bits = FORMAT_BITS[ecc][mask];
|
|
24526
|
+
const at = (i) => (bits >> i) & 1;
|
|
24527
|
+
for (let i = 0; i <= 5; i++)
|
|
24528
|
+
m[8][i] = at(i);
|
|
24529
|
+
m[8][7] = at(6);
|
|
24530
|
+
m[8][8] = at(7);
|
|
24531
|
+
m[7][8] = at(8);
|
|
24532
|
+
for (let i = 9; i <= 14; i++)
|
|
24533
|
+
m[14 - i][8] = at(i);
|
|
24534
|
+
for (let i = 0; i <= 6; i++)
|
|
24535
|
+
m[size - 1 - i][8] = at(i);
|
|
24536
|
+
for (let i = 7; i <= 14; i++)
|
|
24537
|
+
m[8][size - 15 + i] = at(i);
|
|
24538
|
+
m[size - 8][8] = 1; // the dark module, which is not a format bit
|
|
24539
|
+
}
|
|
24540
|
+
/** Internals, exported for the vector tests only. */
|
|
24541
|
+
const __qrInternals = { dataCodewords, remainder };
|
|
24542
|
+
|
|
24543
|
+
/**
|
|
24544
|
+
* A QR code the library draws, with the quiet zone and contrast a scanner needs
|
|
24545
|
+
* in every theme — not an image the consumer frames on white by hand.
|
|
24546
|
+
*
|
|
24547
|
+
* <strct-qr [value]="otpauthUri" label="Scan with your authenticator app" />
|
|
24548
|
+
*
|
|
24549
|
+
* **Dark modules on a light quiet zone, in every scheme.** That is a deliberate
|
|
24550
|
+
* exception to "tokens only": a themed QR code is an unscannable one. Show the
|
|
24551
|
+
* secret as text beside it, so enrolment works without a camera.
|
|
24552
|
+
*/
|
|
24553
|
+
class StrctQr {
|
|
24554
|
+
/** What the code carries — an `otpauth://` URI, a URL, any text. */
|
|
24555
|
+
value = input.required(/* @ts-ignore */
|
|
24556
|
+
...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
|
|
24557
|
+
/** Rendered size in px (the code is square). */
|
|
24558
|
+
size = input(176, /* @ts-ignore */
|
|
24559
|
+
...(ngDevMode ? [{ debugName: "size" }] : /* istanbul ignore next */ []));
|
|
24560
|
+
/** The code's accessible name. */
|
|
24561
|
+
label = input('QR code', /* @ts-ignore */
|
|
24562
|
+
...(ngDevMode ? [{ debugName: "label" }] : /* istanbul ignore next */ []));
|
|
24563
|
+
/** How much of the code a scanner may lose and still read it. */
|
|
24564
|
+
errorCorrection = input('M', /* @ts-ignore */
|
|
24565
|
+
...(ngDevMode ? [{ debugName: "errorCorrection" }] : /* istanbul ignore next */ []));
|
|
24566
|
+
/** The quiet zone, in modules. Four is what the spec asks for. */
|
|
24567
|
+
quietZone = input(4, /* @ts-ignore */
|
|
24568
|
+
...(ngDevMode ? [{ debugName: "quietZone" }] : /* istanbul ignore next */ []));
|
|
24569
|
+
matrix = computed(() => strctQrMatrix(this.value(), this.errorCorrection()), /* @ts-ignore */
|
|
24570
|
+
...(ngDevMode ? [{ debugName: "matrix" }] : /* istanbul ignore next */ []));
|
|
24571
|
+
/** The whole drawing's span in modules: the code plus its quiet zone. */
|
|
24572
|
+
span = computed(() => this.matrix().length + this.quietZone() * 2, /* @ts-ignore */
|
|
24573
|
+
...(ngDevMode ? [{ debugName: "span" }] : /* istanbul ignore next */ []));
|
|
24574
|
+
viewBox = computed(() => `0 0 ${this.span()} ${this.span()}`, /* @ts-ignore */
|
|
24575
|
+
...(ngDevMode ? [{ debugName: "viewBox" }] : /* istanbul ignore next */ []));
|
|
24576
|
+
/** Dark modules merged into horizontal runs — far fewer rects to paint. */
|
|
24577
|
+
rows = computed(() => {
|
|
24578
|
+
const m = this.matrix();
|
|
24579
|
+
const pad = this.quietZone();
|
|
24580
|
+
return m.map((row, y) => {
|
|
24581
|
+
const runs = [];
|
|
24582
|
+
let start = -1;
|
|
24583
|
+
for (let x = 0; x <= row.length; x++) {
|
|
24584
|
+
if (row[x]) {
|
|
24585
|
+
if (start < 0)
|
|
24586
|
+
start = x;
|
|
24587
|
+
}
|
|
24588
|
+
else if (start >= 0) {
|
|
24589
|
+
runs.push({ x: start + pad, width: x - start });
|
|
24590
|
+
start = -1;
|
|
24591
|
+
}
|
|
24592
|
+
}
|
|
24593
|
+
return { y: y + pad, runs };
|
|
24594
|
+
});
|
|
24595
|
+
}, /* @ts-ignore */
|
|
24596
|
+
...(ngDevMode ? [{ debugName: "rows" }] : /* istanbul ignore next */ []));
|
|
24597
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctQr, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
24598
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "22.1.4", type: StrctQr, isStandalone: true, selector: "strct-qr", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, size: { classPropertyName: "size", publicName: "size", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, errorCorrection: { classPropertyName: "errorCorrection", publicName: "errorCorrection", isSignal: true, isRequired: false, transformFunction: null }, quietZone: { classPropertyName: "quietZone", publicName: "quietZone", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "strct-qr" }, ngImport: i0, template: `
|
|
24599
|
+
<svg
|
|
24600
|
+
class="strct-qr__svg"
|
|
24601
|
+
[attr.viewBox]="viewBox()"
|
|
24602
|
+
[attr.width]="size()"
|
|
24603
|
+
[attr.height]="size()"
|
|
24604
|
+
role="img"
|
|
24605
|
+
[attr.aria-label]="label()"
|
|
24606
|
+
shape-rendering="crispEdges"
|
|
24607
|
+
>
|
|
24608
|
+
<rect class="strct-qr__quiet" [attr.width]="span()" [attr.height]="span()" />
|
|
24609
|
+
@for (row of rows(); track row.y) {
|
|
24610
|
+
@for (run of row.runs; track run.x) {
|
|
24611
|
+
<rect
|
|
24612
|
+
class="strct-qr__module"
|
|
24613
|
+
[attr.x]="run.x"
|
|
24614
|
+
[attr.y]="row.y"
|
|
24615
|
+
[attr.width]="run.width"
|
|
24616
|
+
height="1"
|
|
24617
|
+
/>
|
|
24618
|
+
}
|
|
24619
|
+
}
|
|
24620
|
+
</svg>
|
|
24621
|
+
`, isInline: true, styles: [".strct-qr{display:inline-flex;line-height:0}.strct-qr__svg{border-radius:var(--radius-md)}.strct-qr__quiet{fill:#fff}.strct-qr__module{fill:#000}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None });
|
|
24622
|
+
}
|
|
24623
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: StrctQr, decorators: [{
|
|
24624
|
+
type: Component,
|
|
24625
|
+
args: [{ selector: 'strct-qr', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: `
|
|
24626
|
+
<svg
|
|
24627
|
+
class="strct-qr__svg"
|
|
24628
|
+
[attr.viewBox]="viewBox()"
|
|
24629
|
+
[attr.width]="size()"
|
|
24630
|
+
[attr.height]="size()"
|
|
24631
|
+
role="img"
|
|
24632
|
+
[attr.aria-label]="label()"
|
|
24633
|
+
shape-rendering="crispEdges"
|
|
24634
|
+
>
|
|
24635
|
+
<rect class="strct-qr__quiet" [attr.width]="span()" [attr.height]="span()" />
|
|
24636
|
+
@for (row of rows(); track row.y) {
|
|
24637
|
+
@for (run of row.runs; track run.x) {
|
|
24638
|
+
<rect
|
|
24639
|
+
class="strct-qr__module"
|
|
24640
|
+
[attr.x]="run.x"
|
|
24641
|
+
[attr.y]="row.y"
|
|
24642
|
+
[attr.width]="run.width"
|
|
24643
|
+
height="1"
|
|
24644
|
+
/>
|
|
24645
|
+
}
|
|
24646
|
+
}
|
|
24647
|
+
</svg>
|
|
24648
|
+
`, host: { class: 'strct-qr' }, styles: [".strct-qr{display:inline-flex;line-height:0}.strct-qr__svg{border-radius:var(--radius-md)}.strct-qr__quiet{fill:#fff}.strct-qr__module{fill:#000}\n"] }]
|
|
24649
|
+
}], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: true }] }], size: [{ type: i0.Input, args: [{ isSignal: true, alias: "size", required: false }] }], label: [{ type: i0.Input, args: [{ isSignal: true, alias: "label", required: false }] }], errorCorrection: [{ type: i0.Input, args: [{ isSignal: true, alias: "errorCorrection", required: false }] }], quietZone: [{ type: i0.Input, args: [{ isSignal: true, alias: "quietZone", required: false }] }] } });
|
|
24650
|
+
|
|
24053
24651
|
/**
|
|
24054
24652
|
* A value change, as one phrase: "v10.27 → v10.28". The old value is muted, the
|
|
24055
24653
|
* arrow is the library's, the new one is emphasised — and assistive tech hears
|
|
@@ -25966,5 +26564,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
|
|
|
25966
26564
|
* Generated bundle index. Do not edit.
|
|
25967
26565
|
*/
|
|
25968
26566
|
|
|
25969
|
-
export { FOCUSABLE_SELECTOR, STRCT_DP_DOW, STRCT_DP_DOW_FULL, STRCT_DP_MONTHS, STRCT_ICONS, STRCT_ICON_GROUPS, STRCT_ICON_NAMES, STRCT_MASKS, STRCT_NOTIFICATION_HISTORY_LIMIT, STRCT_PALETTES, STRCT_RAW_ICONS, STRCT_TIME_RANGE_PRESETS, STRCT_WIZARD_DEFAULTS, StrctAccordion, StrctAccordionPanel, StrctAlert, StrctAnnouncer, StrctAvatar, StrctBadge, StrctBreadcrumb, StrctBreadcrumbItem, StrctButton, StrctButtonGroup, StrctBytesPipe, StrctCard, StrctCardBlock, StrctCardFooter, StrctCardHeader, StrctCardHeaderActions, StrctCardHeaderMeta, StrctCardHeaderNote, StrctCascadeColumn, StrctCascadeHost, StrctCascadeSelect, StrctCellDef, StrctCellStatus, StrctChange, StrctChart, StrctChatAttachment, StrctChatComposer, StrctChatMessage, StrctChatThread, StrctCheckbox, StrctChips, StrctCode, StrctCodeInline, StrctColorPicker, StrctCombobox, StrctCommandPalette, StrctConfirmOutlet, StrctConfirmService, StrctContextMenu, StrctContextMenuTrigger, StrctControlDescription, StrctCopy, StrctDatagrid, StrctDatagridActionBar, StrctDatagridActionBarCaption, StrctDatepicker, StrctDatetimePicker, StrctDesc, StrctDescriptionList, StrctDiff, StrctDivider, StrctDonut, StrctDrawer, StrctDrawerFooter, StrctDropdown, StrctDropdownDivider, StrctDropdownItem, StrctDropdownItemAction, StrctDropdownTrigger, StrctDurationPipe, StrctEmptyState, StrctField, StrctFieldGroup, StrctFieldHint, StrctFieldPrefix, StrctFieldSuffix, StrctFile, StrctFilterBar, StrctFlow, StrctFlowNodeTemplate, StrctFooter, StrctGauge, StrctHeader, StrctHeatmap, StrctHero, StrctHotkeysHelp, StrctHotkeysService, StrctIcon, StrctInlineEdit, StrctInput, StrctInputMask, StrctInputOtp, StrctKbd, StrctKnob, StrctLegend, StrctList, StrctListItem, StrctListItemDescription, StrctListItemLeading, StrctListItemMeta, StrctListItemTrailing, StrctLiveIndicator, StrctLogViewer, StrctLogin, StrctMediaFrame, StrctMenuPanel, StrctMenuService, StrctMenubar, StrctMetricTile, StrctModal, StrctModalContent, StrctNav, StrctNavItem, StrctNotificationCenter, StrctNumber, StrctOverlay, StrctPageHeader, StrctPageHeaderActions, StrctPageHeaderCrumbs, StrctPageHeaderTitleMeta, StrctPagination, StrctPassword, StrctPopover, StrctPopoverTrigger, StrctProgress, StrctRadio, StrctRadioGroup, StrctRail, StrctRange, StrctRatePipe, StrctRating, StrctReorder, StrctReorderGroup, StrctReorderHandle, StrctReorderItem, StrctResizeHandle, StrctRowDetailDef, StrctSearchbox, StrctSectionHeader, StrctSectionHeaderActions, StrctSectionHeaderMeta, StrctSectionMenu, StrctSegmented, StrctSelect, StrctShell, StrctShellService, StrctSiPipe, StrctSignpost, StrctSignpostTrigger, StrctSkeleton, StrctSparkline, StrctSpeedDial, StrctSpinner, StrctSplitButton, StrctSplitter, StrctStack, StrctStackItem, StrctStatusDot, StrctStep, StrctStepAction, StrctSteps, StrctSubmenu, StrctTab, StrctTable, StrctTabs, StrctTag, StrctTagLeading, StrctThemeService, StrctThemeSwitcher, StrctTimeRangePicker, StrctTimeline, StrctTimelineItem, StrctToastOutlet, StrctToastService, StrctToggle, StrctToolbar, StrctToolbarCaption, StrctToolbarSpacer, StrctTooltip, StrctTour, StrctTransfer, StrctTree, StrctTreeNode, StrctTreeSelect, StrctVerticalNav, StrctWatermark, StrctWindow, StrctWindowDock, StrctWindowService, StrctWizard, StrctWizardAside, focusFirstIn, keepTabInside, lockBodyScroll, parseAnsi, provideStrctWizardDefaults, registerStrctIcon, restoreFocus, saveFocusedElement, strctComputeDiff, strctDpPad, strctFormatBytes, strctFormatDuration, strctFormatRate, strctFormatSi, strctValidationIcon, strctValidationTone, unlockBodyScroll };
|
|
26567
|
+
export { FOCUSABLE_SELECTOR, STRCT_DP_DOW, STRCT_DP_DOW_FULL, STRCT_DP_MONTHS, STRCT_ICONS, STRCT_ICON_GROUPS, STRCT_ICON_NAMES, STRCT_MASKS, STRCT_NOTIFICATION_HISTORY_LIMIT, STRCT_PALETTES, STRCT_RAW_ICONS, STRCT_TIME_RANGE_PRESETS, STRCT_WIZARD_DEFAULTS, StrctAccordion, StrctAccordionPanel, StrctAlert, StrctAnnouncer, StrctAvatar, StrctBadge, StrctBreadcrumb, StrctBreadcrumbItem, StrctButton, StrctButtonGroup, StrctBytesPipe, StrctCard, StrctCardBlock, StrctCardFooter, StrctCardHeader, StrctCardHeaderActions, StrctCardHeaderMeta, StrctCardHeaderNote, StrctCascadeColumn, StrctCascadeHost, StrctCascadeSelect, StrctCellDef, StrctCellStatus, StrctChange, StrctChart, StrctChatAttachment, StrctChatComposer, StrctChatMessage, StrctChatThread, StrctCheckbox, StrctChips, StrctCode, StrctCodeInline, StrctColorPicker, StrctCombobox, StrctCommandPalette, StrctConfirmOutlet, StrctConfirmService, StrctContextMenu, StrctContextMenuTrigger, StrctControlDescription, StrctCopy, StrctDatagrid, StrctDatagridActionBar, StrctDatagridActionBarCaption, StrctDatepicker, StrctDatetimePicker, StrctDesc, StrctDescriptionList, StrctDiff, StrctDivider, StrctDonut, StrctDrawer, StrctDrawerFooter, StrctDropdown, StrctDropdownDivider, StrctDropdownItem, StrctDropdownItemAction, StrctDropdownTrigger, StrctDurationPipe, StrctEmptyState, StrctField, StrctFieldGroup, StrctFieldHint, StrctFieldPrefix, StrctFieldSuffix, StrctFile, StrctFilterBar, StrctFlow, StrctFlowNodeTemplate, StrctFooter, StrctGauge, StrctHeader, StrctHeatmap, StrctHero, StrctHotkeysHelp, StrctHotkeysService, StrctIcon, StrctInlineEdit, StrctInput, StrctInputMask, StrctInputOtp, StrctKbd, StrctKnob, StrctLegend, StrctList, StrctListItem, StrctListItemDescription, StrctListItemLeading, StrctListItemMeta, StrctListItemTrailing, StrctLiveIndicator, StrctLogViewer, StrctLogin, StrctMediaFrame, StrctMenuPanel, StrctMenuService, StrctMenubar, StrctMetricTile, StrctModal, StrctModalContent, StrctNav, StrctNavItem, StrctNotificationCenter, StrctNumber, StrctOverlay, StrctPageHeader, StrctPageHeaderActions, StrctPageHeaderCrumbs, StrctPageHeaderTitleMeta, StrctPagination, StrctPassword, StrctPopover, StrctPopoverTrigger, StrctProgress, StrctQr, StrctRadio, StrctRadioGroup, StrctRail, StrctRange, StrctRatePipe, StrctRating, StrctReorder, StrctReorderGroup, StrctReorderHandle, StrctReorderItem, StrctResizeHandle, StrctRowDetailDef, StrctSearchbox, StrctSectionHeader, StrctSectionHeaderActions, StrctSectionHeaderMeta, StrctSectionMenu, StrctSegmented, StrctSelect, StrctShell, StrctShellService, StrctSiPipe, StrctSignpost, StrctSignpostTrigger, StrctSkeleton, StrctSparkline, StrctSpeedDial, StrctSpinner, StrctSplitButton, StrctSplitter, StrctStack, StrctStackItem, StrctStatusDot, StrctStep, StrctStepAction, StrctSteps, StrctSubmenu, StrctTab, StrctTable, StrctTabs, StrctTag, StrctTagLeading, StrctThemeService, StrctThemeSwitcher, StrctTimeRangePicker, StrctTimeline, StrctTimelineItem, StrctToastOutlet, StrctToastService, StrctToggle, StrctToolbar, StrctToolbarCaption, StrctToolbarSpacer, StrctTooltip, StrctTour, StrctTransfer, StrctTree, StrctTreeNode, StrctTreeSelect, StrctVerticalNav, StrctWatermark, StrctWindow, StrctWindowDock, StrctWindowService, StrctWizard, StrctWizardAside, __qrInternals, focusFirstIn, keepTabInside, lockBodyScroll, parseAnsi, provideStrctWizardDefaults, registerStrctIcon, restoreFocus, saveFocusedElement, strctComputeDiff, strctDpPad, strctFormatBytes, strctFormatDuration, strctFormatRate, strctFormatSi, strctQrMatrix, strctValidationIcon, strctValidationTone, unlockBodyScroll };
|
|
25970
26568
|
//# sourceMappingURL=akcelik-strct.mjs.map
|