@cardanvil/frame-kit 0.5.0 → 0.7.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/README.md +119 -0
- package/dist/authoring/collectorInfo.d.ts +17 -0
- package/dist/authoring/collectorInfo.js +62 -0
- package/dist/authoring/index.d.ts +2 -0
- package/dist/authoring/index.js +2 -0
- package/dist/authoring/layoutDefaults.d.ts +20 -2
- package/dist/authoring/layoutDefaults.js +48 -13
- package/dist/authoring/opacityStops.d.ts +8 -0
- package/dist/authoring/opacityStops.js +17 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +1 -0
- package/dist/cli/loadFrame.js +1 -1
- package/dist/cli/main.js +88 -0
- package/dist/cli/sourceWatcher.d.ts +40 -0
- package/dist/cli/sourceWatcher.js +100 -0
- package/dist/cli/studio/boxSets.d.ts +33 -0
- package/dist/cli/studio/boxSets.js +90 -0
- package/dist/cli/studio/edit/applyEdits.d.ts +71 -0
- package/dist/cli/studio/edit/applyEdits.js +177 -0
- package/dist/cli/studio/edit/impact.d.ts +53 -0
- package/dist/cli/studio/edit/impact.js +87 -0
- package/dist/cli/studio/edit/resolveModule.d.ts +10 -0
- package/dist/cli/studio/edit/resolveModule.js +55 -0
- package/dist/cli/studio/edit/resolvePath.d.ts +53 -0
- package/dist/cli/studio/edit/resolvePath.js +606 -0
- package/dist/cli/studio/edit/sourceIndex.d.ts +29 -0
- package/dist/cli/studio/edit/sourceIndex.js +73 -0
- package/dist/cli/studio/edit/ts.d.ts +14 -0
- package/dist/cli/studio/edit/ts.js +34 -0
- package/dist/cli/studio/serve.d.ts +23 -0
- package/dist/cli/studio/serve.js +516 -0
- package/dist/cli/studio/session.d.ts +73 -0
- package/dist/cli/studio/session.js +154 -0
- package/dist/cli/trim.d.ts +62 -0
- package/dist/cli/trim.js +251 -0
- package/dist/cli/watch.d.ts +3 -0
- package/dist/cli/watch.js +20 -89
- package/dist/layout/assetPlacement.d.ts +71 -0
- package/dist/layout/assetPlacement.js +104 -0
- package/dist/layout/border.d.ts +27 -0
- package/dist/layout/border.js +31 -0
- package/dist/layout/boxOverrides.d.ts +28 -0
- package/dist/layout/boxOverrides.js +95 -0
- package/dist/layout/color.d.ts +23 -0
- package/dist/layout/color.js +53 -0
- package/dist/layout/cutouts.d.ts +28 -0
- package/dist/layout/cutouts.js +29 -0
- package/dist/layout/decorations.d.ts +73 -0
- package/dist/layout/decorations.js +104 -0
- package/dist/layout/frameLayers.d.ts +163 -0
- package/dist/layout/frameLayers.js +433 -0
- package/dist/layout/index.d.ts +27 -0
- package/dist/layout/index.js +27 -0
- package/dist/layout/paint.d.ts +36 -0
- package/dist/layout/paint.js +148 -0
- package/dist/layout/powerToughnessRow.d.ts +26 -0
- package/dist/layout/powerToughnessRow.js +13 -0
- package/dist/layout/resolveFrameAsset.d.ts +37 -0
- package/dist/layout/resolveFrameAsset.js +66 -0
- package/dist/layout/rulesSlide.d.ts +13 -0
- package/dist/layout/rulesSlide.js +33 -0
- package/dist/layout/settings.d.ts +26 -0
- package/dist/layout/settings.js +62 -0
- package/dist/layout/textStyle.d.ts +29 -0
- package/dist/layout/textStyle.js +28 -0
- package/dist/layout/turn.d.ts +54 -0
- package/dist/layout/turn.js +107 -0
- package/dist/manifest/contract.d.ts +6103 -9063
- package/dist/manifest/contract.js +48 -1
- package/dist/manifest/testFrame.js +9 -0
- package/dist/schema/collectorInfo.d.ts +95 -0
- package/dist/schema/collectorInfo.js +80 -0
- package/dist/schema/condition.d.ts +67 -0
- package/dist/schema/condition.js +47 -0
- package/dist/schema/frame.d.ts +17213 -24450
- package/dist/schema/frame.js +418 -14
- package/dist/schema/frameAssets.d.ts +56 -34
- package/dist/schema/frameAssets.js +96 -2
- package/dist/schema/index.d.ts +3 -0
- package/dist/schema/index.js +3 -0
- package/dist/schema/layout.d.ts +29 -4
- package/dist/schema/layout.js +27 -2
- package/dist/schema/paint.d.ts +202 -0
- package/dist/schema/paint.js +109 -0
- package/dist/studio/assets/PlantinMTProRgIt-D0FB51kb.woff2 +0 -0
- package/dist/studio/assets/beleren-b-B3lFvodX.ttf +0 -0
- package/dist/studio/assets/beleren-bsc-yvL6mU7X.ttf +0 -0
- package/dist/studio/assets/index-BnhNwm_r.js +74 -0
- package/dist/studio/index.html +12 -0
- package/package.json +16 -5
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import type { FrameAssets, FrameColor } from "../schema/frameAssets.js";
|
|
2
|
+
import { type FrameDetails } from "./frameLayers.js";
|
|
3
|
+
/**
|
|
4
|
+
* The type-line facts the decoration colours turn on.
|
|
5
|
+
*
|
|
6
|
+
* A `CardShape` satisfies this structurally, and so does a card the app has
|
|
7
|
+
* already read a type line from.
|
|
8
|
+
*/
|
|
9
|
+
export interface DecorationFacts {
|
|
10
|
+
readonly isLand?: boolean;
|
|
11
|
+
readonly isArtifact?: boolean;
|
|
12
|
+
readonly isVehicle?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/** One colour, or the two halves of a two-colour banner. */
|
|
15
|
+
export type BannerColors = FrameColor | [FrameColor, FrameColor];
|
|
16
|
+
/**
|
|
17
|
+
* The colour a card's banners take.
|
|
18
|
+
*
|
|
19
|
+
* Driven by the resolved identity rather than the background, so a crown, a
|
|
20
|
+
* nickname plate and a PT box on the same card always agree with each other
|
|
21
|
+
* and with the pinlines.
|
|
22
|
+
*/
|
|
23
|
+
export declare function identityColors(details: FrameDetails, facts?: DecorationFacts): BannerColors;
|
|
24
|
+
/** Legendary crown colour(s). */
|
|
25
|
+
export declare function crownColors(details: FrameDetails, facts?: DecorationFacts): BannerColors;
|
|
26
|
+
/** Nickname banner colour(s). */
|
|
27
|
+
export declare function nicknameColors(details: FrameDetails, facts?: DecorationFacts): BannerColors;
|
|
28
|
+
/**
|
|
29
|
+
* PT box colour.
|
|
30
|
+
*
|
|
31
|
+
* Only a true two-colour hybrid takes the colourless box. A card built from
|
|
32
|
+
* monocoloured-hybrid pips in three or more colours is an ordinary gold card
|
|
33
|
+
* and must resolve by identity length instead.
|
|
34
|
+
*/
|
|
35
|
+
export declare function ptBoxColor(details: FrameDetails, facts?: DecorationFacts): FrameColor;
|
|
36
|
+
/** Combined crown + nickname banner; the UB variant falls back to the plain one. */
|
|
37
|
+
export declare function resolveCrownNicknameAsset(assets: FrameAssets, color: FrameColor, useUBCrowns: boolean): string | undefined;
|
|
38
|
+
/**
|
|
39
|
+
* Legendary crown art.
|
|
40
|
+
*
|
|
41
|
+
* A nicknamed card prefers the combined crown+nickname asset, and falls back
|
|
42
|
+
* to the plain crown when a frame does not ship one.
|
|
43
|
+
*/
|
|
44
|
+
export declare function resolveCrownAsset(assets: FrameAssets, color: FrameColor, opts: {
|
|
45
|
+
nickname: boolean;
|
|
46
|
+
useUBCrowns: boolean;
|
|
47
|
+
}): string | undefined;
|
|
48
|
+
export declare function resolveNicknameAsset(assets: FrameAssets, color: FrameColor): string | undefined;
|
|
49
|
+
export declare function resolvePtBoxAsset(assets: FrameAssets, color: FrameColor): string | undefined;
|
|
50
|
+
export declare function resolveNyxInsertAsset(assets: FrameAssets, color: FrameColor, useUBCrowns?: boolean): string | undefined;
|
|
51
|
+
/** What a card is, for deciding which banners it gets. */
|
|
52
|
+
export interface DecorationCard {
|
|
53
|
+
readonly isLegendary?: boolean;
|
|
54
|
+
/** The nickname text; a card has a nickname when this is non-empty. */
|
|
55
|
+
readonly nickname?: string;
|
|
56
|
+
readonly power?: string;
|
|
57
|
+
readonly toughness?: string;
|
|
58
|
+
}
|
|
59
|
+
export interface DecorationState {
|
|
60
|
+
readonly crown: boolean;
|
|
61
|
+
/** The bar behind the crown, drawn on the same condition. */
|
|
62
|
+
readonly crownBlackBar: boolean;
|
|
63
|
+
readonly nickname: boolean;
|
|
64
|
+
readonly ptBox: boolean;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Which banners a card draws.
|
|
68
|
+
*
|
|
69
|
+
* Mirrors the renderer's conditions: crowns are legendary-only, the nickname
|
|
70
|
+
* plate needs nickname text, and the PT box needs *both* a power and a
|
|
71
|
+
* toughness — a card with only one is not a creature and gets no plate.
|
|
72
|
+
*/
|
|
73
|
+
export declare function decorationsFor(card: DecorationCard): DecorationState;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { splitTwoColor } from "./frameLayers.js";
|
|
2
|
+
/**
|
|
3
|
+
* The colour a card's banners take.
|
|
4
|
+
*
|
|
5
|
+
* Driven by the resolved identity rather than the background, so a crown, a
|
|
6
|
+
* nickname plate and a PT box on the same card always agree with each other
|
|
7
|
+
* and with the pinlines.
|
|
8
|
+
*/
|
|
9
|
+
export function identityColors(details, facts = {}) {
|
|
10
|
+
const split = splitTwoColor(details.identity);
|
|
11
|
+
if (split) {
|
|
12
|
+
return split;
|
|
13
|
+
}
|
|
14
|
+
if (details.identity.length === 1) {
|
|
15
|
+
return details.identity.toLowerCase();
|
|
16
|
+
}
|
|
17
|
+
if (details.identity.length > 1) {
|
|
18
|
+
return "m";
|
|
19
|
+
}
|
|
20
|
+
// No identity: a land takes the land token so its banners match its land
|
|
21
|
+
// pinlines, and a colourless artifact the artifact token so they match its
|
|
22
|
+
// artifact pinlines; anything else stays colourless.
|
|
23
|
+
if (facts.isLand === true) {
|
|
24
|
+
return "l";
|
|
25
|
+
}
|
|
26
|
+
return facts.isArtifact === true ? "a" : "c";
|
|
27
|
+
}
|
|
28
|
+
/** Legendary crown colour(s). */
|
|
29
|
+
export function crownColors(details, facts = {}) {
|
|
30
|
+
return identityColors(details, facts);
|
|
31
|
+
}
|
|
32
|
+
/** Nickname banner colour(s). */
|
|
33
|
+
export function nicknameColors(details, facts = {}) {
|
|
34
|
+
return identityColors(details, facts);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* PT box colour.
|
|
38
|
+
*
|
|
39
|
+
* Only a true two-colour hybrid takes the colourless box. A card built from
|
|
40
|
+
* monocoloured-hybrid pips in three or more colours is an ordinary gold card
|
|
41
|
+
* and must resolve by identity length instead.
|
|
42
|
+
*/
|
|
43
|
+
export function ptBoxColor(details, facts = {}) {
|
|
44
|
+
if (facts.isVehicle === true) {
|
|
45
|
+
return "v"; // vehicles use the dedicated plate whatever their colour
|
|
46
|
+
}
|
|
47
|
+
if (details.isHybrid) {
|
|
48
|
+
return "c";
|
|
49
|
+
}
|
|
50
|
+
if (details.identity.length === 1) {
|
|
51
|
+
return details.identity.toLowerCase();
|
|
52
|
+
}
|
|
53
|
+
if (details.identity.length > 1) {
|
|
54
|
+
return "m";
|
|
55
|
+
}
|
|
56
|
+
return facts.isArtifact === true ? "a" : "c";
|
|
57
|
+
}
|
|
58
|
+
/** Combined crown + nickname banner; the UB variant falls back to the plain one. */
|
|
59
|
+
export function resolveCrownNicknameAsset(assets, color, useUBCrowns) {
|
|
60
|
+
return ((useUBCrowns ? assets.crown?.nicknameUb?.[color] : undefined) ??
|
|
61
|
+
assets.crown?.nickname?.[color]);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Legendary crown art.
|
|
65
|
+
*
|
|
66
|
+
* A nicknamed card prefers the combined crown+nickname asset, and falls back
|
|
67
|
+
* to the plain crown when a frame does not ship one.
|
|
68
|
+
*/
|
|
69
|
+
export function resolveCrownAsset(assets, color, opts) {
|
|
70
|
+
if (opts.nickname) {
|
|
71
|
+
const combined = resolveCrownNicknameAsset(assets, color, opts.useUBCrowns);
|
|
72
|
+
if (combined !== undefined) {
|
|
73
|
+
return combined;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return ((opts.useUBCrowns ? assets.crown?.ub?.[color] : undefined) ??
|
|
77
|
+
assets.crown?.base?.[color]);
|
|
78
|
+
}
|
|
79
|
+
export function resolveNicknameAsset(assets, color) {
|
|
80
|
+
return assets.nickname?.[color];
|
|
81
|
+
}
|
|
82
|
+
export function resolvePtBoxAsset(assets, color) {
|
|
83
|
+
return assets.pt?.[color];
|
|
84
|
+
}
|
|
85
|
+
export function resolveNyxInsertAsset(assets, color, useUBCrowns = false) {
|
|
86
|
+
return ((useUBCrowns ? assets.crown?.nyxInsertUb?.[color] : undefined) ??
|
|
87
|
+
assets.crown?.nyxInsert?.[color]);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Which banners a card draws.
|
|
91
|
+
*
|
|
92
|
+
* Mirrors the renderer's conditions: crowns are legendary-only, the nickname
|
|
93
|
+
* plate needs nickname text, and the PT box needs *both* a power and a
|
|
94
|
+
* toughness — a card with only one is not a creature and gets no plate.
|
|
95
|
+
*/
|
|
96
|
+
export function decorationsFor(card) {
|
|
97
|
+
const legendary = card.isLegendary === true;
|
|
98
|
+
return {
|
|
99
|
+
crown: legendary,
|
|
100
|
+
crownBlackBar: legendary,
|
|
101
|
+
nickname: (card.nickname ?? "") !== "",
|
|
102
|
+
ptBox: (card.power ?? "") !== "" && (card.toughness ?? "") !== "",
|
|
103
|
+
};
|
|
104
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import type { FrameColor, FrameRef } from "../schema/frameAssets.js";
|
|
2
|
+
/**
|
|
3
|
+
* The subset of Proxyshop's `LAYERS` enum the frame logic needs: canonical
|
|
4
|
+
* colour letters plus the identity labels. Mirrors Card Anvil's
|
|
5
|
+
* `utils/frameLogic.ts`, which is where the card-parsing half still lives.
|
|
6
|
+
*/
|
|
7
|
+
export declare const LAYERS: {
|
|
8
|
+
readonly WHITE: "W";
|
|
9
|
+
readonly BLUE: "U";
|
|
10
|
+
readonly BLACK: "B";
|
|
11
|
+
readonly RED: "R";
|
|
12
|
+
readonly GREEN: "G";
|
|
13
|
+
readonly ARTIFACT: "Artifact";
|
|
14
|
+
readonly COLORLESS: "Colorless";
|
|
15
|
+
readonly LAND: "Land";
|
|
16
|
+
readonly GOLD: "Gold";
|
|
17
|
+
readonly VEHICLE: "Vehicle";
|
|
18
|
+
readonly HYBRID: "Hybrid";
|
|
19
|
+
};
|
|
20
|
+
/** WUBRG in canonical order, which every multi-colour string is sorted into. */
|
|
21
|
+
export declare const COLOR_ORDER: readonly ["W", "U", "B", "R", "G"];
|
|
22
|
+
/** The five colour letters, for checking a string is made of them. */
|
|
23
|
+
export declare const COLOR_LETTERS: ReadonlySet<string>;
|
|
24
|
+
/**
|
|
25
|
+
* Two or three colours in the order cards print them (`UW` → `WU`, `UGW` →
|
|
26
|
+
* `GWU`); anything else as it came.
|
|
27
|
+
*/
|
|
28
|
+
export declare function printedColorOrder(colors: string): string;
|
|
29
|
+
/**
|
|
30
|
+
* What the frame logic concluded about a card, before any art is chosen.
|
|
31
|
+
*
|
|
32
|
+
* This is the seam between parsing a card and picking its frame: Card Anvil
|
|
33
|
+
* derives it from a Scryfall card, and the studio builds it from a colour
|
|
34
|
+
* picker, but both feed the same selection below.
|
|
35
|
+
*/
|
|
36
|
+
export interface FrameDetails {
|
|
37
|
+
/** Drives the base frame: a colour, `Artifact`, `Land`, `Gold`… */
|
|
38
|
+
background: string;
|
|
39
|
+
/** Colours the pinlines and text box. */
|
|
40
|
+
pinlines: string;
|
|
41
|
+
/** Colours the name and type boxes. */
|
|
42
|
+
twins: string;
|
|
43
|
+
/** The card's colour identity; what a land's base frame uses. */
|
|
44
|
+
identity: string;
|
|
45
|
+
isColorless: boolean;
|
|
46
|
+
isHybrid: boolean;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Which set of frame art a card draws from. Lands use `land`, enchantments
|
|
50
|
+
* `nyx` when nyx borders are on, everything else the plain colour frames.
|
|
51
|
+
*/
|
|
52
|
+
export type FrameFamily = "normal" | "land" | "nyx";
|
|
53
|
+
/** A mask that recolours one section of the frame. */
|
|
54
|
+
export type OverlayMaskName = "pinlines" | "rules" | "titleAndType" | "title" | "rightHalf" | "rulesRight" | "adventureRules" | "adventureRulesRight" | "wings";
|
|
55
|
+
export interface FrameOverlay {
|
|
56
|
+
frame: FrameRef;
|
|
57
|
+
mask: OverlayMaskName;
|
|
58
|
+
/** Applied after the primary mask. */
|
|
59
|
+
secondaryMask?: "rightHalf";
|
|
60
|
+
/** Blend RGB only, keeping the existing alpha. */
|
|
61
|
+
preserveAlpha?: boolean;
|
|
62
|
+
}
|
|
63
|
+
export interface FrameLayers {
|
|
64
|
+
baseFrame: FrameRef;
|
|
65
|
+
overlays?: FrameOverlay[];
|
|
66
|
+
}
|
|
67
|
+
/** Maps a `LAYERS` value to a single frame colour token. */
|
|
68
|
+
export declare function colorToken(value: string): FrameColor;
|
|
69
|
+
/** Splits a two-colour combo like `WU`, or `null` if it is not one. */
|
|
70
|
+
export declare function splitTwoColor(value: string): [FrameColor, FrameColor] | null;
|
|
71
|
+
/**
|
|
72
|
+
* The ref for a colour within a family.
|
|
73
|
+
*
|
|
74
|
+
* Families do not all carry every colour, and the fallbacks are deliberate:
|
|
75
|
+
* nyx has no vehicle frame, and a land that is not one of WUBRG or gold falls
|
|
76
|
+
* back to the colourless land in the base family.
|
|
77
|
+
*/
|
|
78
|
+
export declare function makeFamilyRef(color: FrameColor | "c2", family: FrameFamily): FrameRef;
|
|
79
|
+
/** The family a type line implies. */
|
|
80
|
+
export declare function frameFamily(typeLine: string, useNyxBorder?: boolean): FrameFamily;
|
|
81
|
+
export interface SelectOptions {
|
|
82
|
+
readonly family?: FrameFamily;
|
|
83
|
+
/** Mask for the colourless wash over a two-colour hybrid. */
|
|
84
|
+
readonly hybridTitleMask?: "title" | "titleAndType";
|
|
85
|
+
/**
|
|
86
|
+
* Whether the layout ships a `pinlines` mask. A coloured artifact normally
|
|
87
|
+
* keeps the Artifact base and carries its colour in the overlays; a layout
|
|
88
|
+
* with no pinlines mask can never draw those, so it falls back to a
|
|
89
|
+
* colour-based base rather than losing the colour entirely.
|
|
90
|
+
*/
|
|
91
|
+
readonly hasPinlineMask?: boolean;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* The art to composite for a set of frame details.
|
|
95
|
+
*
|
|
96
|
+
* The selection half of Card Anvil's `getFrameLayers`, with the card parsing
|
|
97
|
+
* lifted out: mono and three-plus-colour cards are a single base frame, gold
|
|
98
|
+
* two-colour cards get split pinlines, and two-colour hybrids render as two
|
|
99
|
+
* halves under a colourless wash.
|
|
100
|
+
*/
|
|
101
|
+
export declare function selectFrameLayers(details: FrameDetails, options?: SelectOptions): FrameLayers;
|
|
102
|
+
/**
|
|
103
|
+
* The art to composite for a storybook Adventure, whose text box is an open
|
|
104
|
+
* book: the card's rules on the right page, its adventure on the left.
|
|
105
|
+
*
|
|
106
|
+
* Everything outside the book is selected as for any card, as though the
|
|
107
|
+
* layout had pinlines, with one exception: the book has no pinline art, so a
|
|
108
|
+
* two-colour gold card halves its base frame between its colours, which
|
|
109
|
+
* splits the frame's own pinlines, and lays gold over the title and type bars
|
|
110
|
+
* as the regular frame has them, and over the book's page edges (`wings`).
|
|
111
|
+
* Each page is then coloured on its own: the right by the card's pinline
|
|
112
|
+
* colours, the left by `adventureColors`, the adventure's colours in the
|
|
113
|
+
* order cards print them (see `printedColorOrder`). An adventure with no
|
|
114
|
+
* colours takes the card's.
|
|
115
|
+
*/
|
|
116
|
+
export declare function selectStorybookFrameLayers(details: FrameDetails, adventureColors: string, options?: SelectOptions): FrameLayers;
|
|
117
|
+
/**
|
|
118
|
+
* What a card is, reduced to the switches that actually change its frame.
|
|
119
|
+
*
|
|
120
|
+
* Card Anvil derives these from a Scryfall card; the studio has no card, so it
|
|
121
|
+
* offers them as controls. Everything here maps onto a real Scryfall
|
|
122
|
+
* distinction — `devoid` is the Battle for Zendikar keyword, `vehicle` and
|
|
123
|
+
* `artifact` are type-line terms, `land` and `enchantment` pick the frame
|
|
124
|
+
* family.
|
|
125
|
+
*/
|
|
126
|
+
export interface CardShape {
|
|
127
|
+
/** Colour identity, in any order; sorted into WUBRG here. */
|
|
128
|
+
readonly colors?: readonly FrameColor[];
|
|
129
|
+
readonly isArtifact?: boolean;
|
|
130
|
+
readonly isVehicle?: boolean;
|
|
131
|
+
readonly isLand?: boolean;
|
|
132
|
+
readonly isEnchantment?: boolean;
|
|
133
|
+
/** Devoid: coloured by identity, but framed colourless. */
|
|
134
|
+
readonly isDevoid?: boolean;
|
|
135
|
+
/** A card with no colours at all — Eldrazi, most artifacts' pinlines. */
|
|
136
|
+
readonly isColorless?: boolean;
|
|
137
|
+
/** Two colours paid with hybrid mana, which splits the frame down the middle. */
|
|
138
|
+
readonly isHybrid?: boolean;
|
|
139
|
+
/** Legendary cards get the crown. */
|
|
140
|
+
readonly isLegendary?: boolean;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* A card's colours as one string, in the order cards print them: `GW`, not
|
|
144
|
+
* `WG`. Card Anvil orders a card's identity the same way, and a two-colour
|
|
145
|
+
* split reads its left half from the first letter, so a plain WUBRG sort
|
|
146
|
+
* would swap the halves of GW, GU and RW cards. Four colours stay WUBRG.
|
|
147
|
+
*/
|
|
148
|
+
export declare function orderColors(colors: readonly FrameColor[]): string;
|
|
149
|
+
/**
|
|
150
|
+
* The frame details a card shape implies.
|
|
151
|
+
*
|
|
152
|
+
* Mirrors the branch order of Card Anvil's `getFrameDetailsNonland` so the
|
|
153
|
+
* studio and the app agree on the awkward cases: devoid multicolour keeps gold
|
|
154
|
+
* plates over a colourless body, a colourless card goes colourless throughout,
|
|
155
|
+
* vehicles and artifacts override the background while their colours stay in
|
|
156
|
+
* the pinlines, and a hybrid pair takes land-coloured twins.
|
|
157
|
+
*
|
|
158
|
+
* Lands are simplified on purpose: the app reads basic-land types and fetch
|
|
159
|
+
* text to infer a land's colours, which a picker states outright.
|
|
160
|
+
*/
|
|
161
|
+
export declare function frameDetailsFor(shape: CardShape): FrameDetails;
|
|
162
|
+
/** The frame family a card shape implies, without a type line to parse. */
|
|
163
|
+
export declare function familyFor(shape: CardShape, useNyxBorder?: boolean): FrameFamily;
|