@flesh-and-blood/search 5.0.3 → 5.0.5

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/dist/filters.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Foiling, Hero, Rarity, Release, Treatment } from "@flesh-and-blood/types";
1
+ import { Card, Foiling, Hero, Printing, Rarity, Release, Treatment } from "@flesh-and-blood/types";
2
2
  import { CatalogueIndex } from "./searchIndex.js";
3
3
  export interface AppliedFilter {
4
4
  filterToPropertyMapping: FilterToPropertyMapping;
@@ -21,9 +21,22 @@ export type Modifier = ">=" | ">" | "<=" | "<";
21
21
  export declare const availableModifiers: Modifier[];
22
22
  export type Exclusion = "!" | "-";
23
23
  export declare const availableExclusions: Exclusion[];
24
+ /** The card field a mapping reads. */
25
+ export type CardPropertyName = keyof Card;
26
+ /**
27
+ * The property of a mapping that reads no card field: a meta filter expands
28
+ * into other filters before any card is read, and a relation filter matches
29
+ * the identifiers the parser resolved.
30
+ */
31
+ export declare const NO_CARD_PROPERTY = "n/a";
32
+ /**
33
+ * The field holding the value a card prints where a number would be, which a
34
+ * numeric filter falls back to for a card carrying no number.
35
+ */
36
+ export type CardSpecialPropertyName = "specialArcane" | "specialCost" | "specialDefense" | "specialLife" | "specialPower";
24
37
  export interface FilterToPropertyMapping {
25
- nestedProperty?: string;
26
- property: string;
38
+ nestedProperty?: keyof Printing;
39
+ property: CardPropertyName | typeof NO_CARD_PROPERTY;
27
40
  exclusion?: Exclusion;
28
41
  isArray?: boolean;
29
42
  isNestedPropertyArray?: boolean;
@@ -47,7 +60,7 @@ export interface FilterToPropertyMapping {
47
60
  isNormalized?: boolean;
48
61
  modifier?: Modifier;
49
62
  partialMatch?: boolean;
50
- specialProperty?: string;
63
+ specialProperty?: CardSpecialPropertyName;
51
64
  }
52
65
  export declare const filtersToCardPropertyMappings: {
53
66
  arcane: FilterToPropertyMapping;
package/dist/filters.js CHANGED
@@ -5,7 +5,6 @@ import {
5
5
  Release,
6
6
  Treatment,
7
7
  Type,
8
- setIdentifierToSetMappings,
9
8
  setToSetIdentifierMappings
10
9
  } from "@flesh-and-blood/types";
11
10
  import { getAbbreviation } from "./abbreviations.js";
@@ -13,6 +12,10 @@ import { getExcludedMetaFilters, getMetaFilters } from "./metaFilters.js";
13
12
  import { multiWordShorthands, singleWordShorthands } from "./shorthands.js";
14
13
  import { PUNCTUATION } from "./constants.js";
15
14
  import { getTextWithoutMarkup } from "./helpers.js";
15
+ import {
16
+ getLookupWithoutInheritedKeys,
17
+ releasesBySetIdentifier
18
+ } from "./lookups.js";
16
19
  import {
17
20
  getCardsByName,
18
21
  getCardsReferencedBy,
@@ -20,6 +23,7 @@ import {
20
23
  } from "./searchIndex.js";
21
24
  const availableModifiers = [">=", ">", "<=", "<"];
22
25
  const availableExclusions = ["!", "-"];
26
+ const NO_CARD_PROPERTY = "n/a";
23
27
  const arcaneFilter = {
24
28
  property: "arcane",
25
29
  specialProperty: "specialArcane",
@@ -32,7 +36,7 @@ const artistFilter = {
32
36
  partialMatch: true
33
37
  };
34
38
  const bannedFilter = {
35
- property: "n/a",
39
+ property: NO_CARD_PROPERTY,
36
40
  isMeta: true
37
41
  };
38
42
  const bondFilter = {
@@ -60,7 +64,7 @@ const getRelationAppliedFilter = (cardIdentifiers, {
60
64
  isOptional
61
65
  });
62
66
  const chainFilter = {
63
- property: "n/a"
67
+ property: NO_CARD_PROPERTY
64
68
  };
65
69
  const classFilter = {
66
70
  property: "classes",
@@ -101,7 +105,7 @@ const keywordFilter = {
101
105
  // partialMatch: true,
102
106
  };
103
107
  const legalFilter = {
104
- property: "n/a",
108
+ property: NO_CARD_PROPERTY,
105
109
  isMeta: true
106
110
  };
107
111
  const lifeFilter = {
@@ -137,14 +141,14 @@ const setIdentifiersFilter = {
137
141
  partialMatch: true
138
142
  };
139
143
  const rarityFilter = {
140
- property: "n/a",
144
+ property: NO_CARD_PROPERTY,
141
145
  isMeta: true
142
146
  };
143
147
  const referencedByFilter = {
144
- property: "n/a"
148
+ property: NO_CARD_PROPERTY
145
149
  };
146
150
  const referencesFilter = {
147
- property: "n/a"
151
+ property: NO_CARD_PROPERTY
148
152
  };
149
153
  const setFilter = {
150
154
  property: "sets",
@@ -274,6 +278,7 @@ const filtersToCardPropertyMappings = {
274
278
  x: typeTextFilter,
275
279
  year: yearFilter
276
280
  };
281
+ const filtersToCardPropertyMappingsByKey = getLookupWithoutInheritedKeys(filtersToCardPropertyMappings);
277
282
  const punctuationOverrides = [
278
283
  {
279
284
  text: Release.ClassicBattlesRhinarDorinthea.toLowerCase(),
@@ -540,7 +545,7 @@ const getKeywordsAndAppliedFiltersFromText = (text, index, additionalHeroes = []
540
545
  } else if (["pitch", "p", "color"].includes(filterKey)) {
541
546
  values = getPitchValuesFromText(values);
542
547
  }
543
- const filterToPropertyMapping = filtersToCardPropertyMappings[filterKey];
548
+ const filterToPropertyMapping = filtersToCardPropertyMappingsByKey[filterKey];
544
549
  if (filterToPropertyMapping && !areValuesAlreadyApplied) {
545
550
  appliedFilters.push({
546
551
  filterToPropertyMapping,
@@ -595,7 +600,7 @@ const getMatchingReleasesFromRawValue = (rawValue, additionalSets = []) => {
595
600
  releases.push(setFromValue);
596
601
  }
597
602
  if (releases.length === 0) {
598
- const setFromSetIdentifier = setIdentifierToSetMappings[rawValue];
603
+ const setFromSetIdentifier = releasesBySetIdentifier[rawValue];
599
604
  if (setFromSetIdentifier) {
600
605
  releases.push(setFromSetIdentifier);
601
606
  }
@@ -618,20 +623,21 @@ const getMatchingReleasesFromRawValue = (rawValue, additionalSets = []) => {
618
623
  }
619
624
  return releases;
620
625
  };
621
- const pitchValuesMapping = {
626
+ const pitchValuesMapping = getLookupWithoutInheritedKeys({
622
627
  purple: 4,
623
628
  blue: 3,
624
629
  yellow: 2,
625
630
  red: 1,
626
631
  white: 0
627
- };
632
+ });
628
633
  const getPitchValuesFromText = (rawValues) => {
629
634
  const values = [];
630
635
  for (const rawValue of rawValues) {
631
- if (pitchValuesMapping[rawValue] || pitchValuesMapping[rawValue] === 0) {
632
- values.push(pitchValuesMapping[rawValue].toString());
633
- } else {
636
+ const pitchValue = pitchValuesMapping[rawValue];
637
+ if (pitchValue === void 0) {
634
638
  values.push(rawValue);
639
+ } else {
640
+ values.push(pitchValue.toString());
635
641
  }
636
642
  }
637
643
  return values;
@@ -645,22 +651,20 @@ const getTodayAsReleaseDate = () => {
645
651
  const dayOfMonth = `${now.getDate()}`.padStart(2, "0");
646
652
  return `${now.getFullYear()}-${month}-${dayOfMonth}`;
647
653
  };
648
- const metaValuesMapping = {
654
+ const metaValuesMapping = getLookupWithoutInheritedKeys({
649
655
  dual: Meta.DualClass,
650
656
  exp: Meta.Expansion,
651
657
  expansion: Meta.Expansion,
652
- expansionSlot: Meta.Expansion,
653
658
  rainbow: Meta.Rainbow,
654
659
  reprint: Meta.Reprint,
655
660
  reprints: Meta.Reprint
656
- };
661
+ });
657
662
  const getMetaValuesFromText = (rawValues) => {
658
663
  const values = [];
659
664
  for (const rawValue of rawValues) {
660
- if (metaValuesMapping[rawValue]) {
661
- values.push(metaValuesMapping[rawValue]);
662
- } else if (Meta[rawValue]) {
663
- values.push(Meta[rawValue]);
665
+ const meta = metaValuesMapping[rawValue];
666
+ if (meta) {
667
+ values.push(meta);
664
668
  }
665
669
  }
666
670
  if (rawValues.length > 0 && values.length === 0) {
@@ -675,7 +679,7 @@ const getMetaValuesFromText = (rawValues) => {
675
679
  }
676
680
  return values;
677
681
  };
678
- const foilingValuesMapping = {
682
+ const foilingValuesMapping = getLookupWithoutInheritedKeys({
679
683
  r: Foiling.Rainbow,
680
684
  rf: Foiling.Rainbow,
681
685
  rainbow: Foiling.Rainbow,
@@ -685,7 +689,7 @@ const foilingValuesMapping = {
685
689
  g: Foiling.Gold,
686
690
  gf: Foiling.Gold,
687
691
  gold: Foiling.Gold
688
- };
692
+ });
689
693
  const getFoilingValuesFromText = (rawValues) => {
690
694
  const values = [];
691
695
  for (const rawValue of rawValues) {
@@ -695,11 +699,14 @@ const getFoilingValuesFromText = (rawValues) => {
695
699
  }
696
700
  return values;
697
701
  };
698
- const treatmentValuesMapping = {
699
- ...Object.values(Treatment).reduce((obj, treatment) => {
700
- obj[treatment.toLowerCase()] = treatment;
701
- return obj;
702
- }, {}),
702
+ const treatmentValuesMapping = getLookupWithoutInheritedKeys({
703
+ ...Object.values(Treatment).reduce(
704
+ (treatmentsByLowercasedName, treatment) => {
705
+ treatmentsByLowercasedName[treatment.toLowerCase()] = treatment;
706
+ return treatmentsByLowercasedName;
707
+ },
708
+ {}
709
+ ),
703
710
  ...{
704
711
  aa: Treatment.AA,
705
712
  alt: Treatment.AA,
@@ -717,19 +724,22 @@ const treatmentValuesMapping = {
717
724
  full: Treatment.FA,
718
725
  "full art": Treatment.FA
719
726
  }
720
- };
727
+ });
728
+ const treatmentsByAbbreviation = getLookupWithoutInheritedKeys(Treatment);
721
729
  const getTreatmentValuesFromText = (rawValues) => {
722
730
  const values = [];
723
731
  for (const rawValue of rawValues) {
724
- if (treatmentValuesMapping[rawValue]) {
725
- values.push(treatmentValuesMapping[rawValue]);
726
- } else if (Treatment[rawValue.toUpperCase()]) {
727
- values.push(Treatment[rawValue.toUpperCase()]);
732
+ const treatmentFromMapping = treatmentValuesMapping[rawValue];
733
+ const treatmentFromAbbreviation = treatmentsByAbbreviation[rawValue.toUpperCase()];
734
+ if (treatmentFromMapping) {
735
+ values.push(treatmentFromMapping);
736
+ } else if (treatmentFromAbbreviation) {
737
+ values.push(treatmentFromAbbreviation);
728
738
  }
729
739
  }
730
740
  return values;
731
741
  };
732
- const RARITY_VALUES_MAPPING = {
742
+ const RARITY_VALUES_MAPPING = getLookupWithoutInheritedKeys({
733
743
  b: Rarity.Basic,
734
744
  c: Rarity.Common,
735
745
  f: Rarity.Fabled,
@@ -740,7 +750,7 @@ const RARITY_VALUES_MAPPING = {
740
750
  s: Rarity.SuperRare,
741
751
  t: Rarity.Token,
742
752
  v: Rarity.Marvel
743
- };
753
+ });
744
754
  const getRarityValuesFromText = (rawValues) => {
745
755
  const values = [];
746
756
  for (const rawValue of rawValues) {
@@ -818,9 +828,10 @@ const getFilterKeyAndExcludedOrOptional = (unparsedFilterKey) => {
818
828
  const hasFilter = (text) => text.indexOf(":") >= 0;
819
829
  const filterIsAnd = (text) => text.indexOf("+") >= 0;
820
830
  const filterIsOr = (text) => text.indexOf(",") >= 0;
821
- const filterIsMeta = (filterKey) => !!filtersToCardPropertyMappings[filterKey]?.isMeta;
831
+ const filterIsMeta = (filterKey) => !!filtersToCardPropertyMappingsByKey[filterKey]?.isMeta;
822
832
  const getExclusion = (text) => availableExclusions.find((exclusion) => text.includes(exclusion))?.slice(0, 1);
823
833
  export {
834
+ NO_CARD_PROPERTY,
824
835
  RARITY_VALUES_MAPPING,
825
836
  availableExclusions,
826
837
  availableModifiers,
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- var hr=Object.create;var Z=Object.defineProperty;var Cr=Object.getOwnPropertyDescriptor;var br=Object.getOwnPropertyNames;var mr=Object.getPrototypeOf,Tr=Object.prototype.hasOwnProperty;var Mr=(e,r)=>{for(var t in r)Z(e,t,{get:r[t],enumerable:!0})},Ee=(e,r,t,a)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of br(r))!Tr.call(e,i)&&i!==t&&Z(e,i,{get:()=>r[i],enumerable:!(a=Cr(r,i))||a.enumerable});return e};var Fr=(e,r,t)=>(t=e!=null?hr(mr(e)):{},Ee(r||!e||!e.__esModule?Z(t,"default",{value:e,enumerable:!0}):t,e)),vr=e=>Ee(Z({},"__esModule",{value:!0}),e);var Pt={};Mr(Pt,{FilterProperty:()=>Ne,MARKUP:()=>ge,PUNCTUATION:()=>T,RARITY_VALUES_MAPPING:()=>ke,abbreviations:()=>ye,availableExclusions:()=>pr,availableModifiers:()=>cr,default:()=>gr,filterCard:()=>yr,filtersToCardPropertyMappings:()=>Ie,getAbbreviation:()=>ee,getAbbreviationByCard:()=>Ar,getCardsByName:()=>se,getCardsByReferencedCardIdentifier:()=>xt,getCardsReferencedBy:()=>ne,getCardsReferencing:()=>oe,getCatalogueIndex:()=>Me,getCleanText:()=>$,getExcludedMetaFilters:()=>Ce,getKeywordsAndAppliedFiltersFromText:()=>Be,getMetaFilters:()=>he,getNormalizedText:()=>J,getOtherPitches:()=>vt,getReferencedCards:()=>At,getTextWithoutMarkup:()=>Y,getTokensReferencedByCards:()=>St,multiWordShorthands:()=>me,shorthands:()=>be,singleWordShorthands:()=>Te});module.exports=vr(Pt);var pe=require("@flesh-and-blood/types"),Le=Fr(require("fuse.js"),1);var T=/[!"#$%&'’(),./:;<=>?@[\]^_`|~]/g,ge=/\*/g;var d=require("@flesh-and-blood/types");var ee=e=>ye.find(({abbreviations:r})=>r.find(t=>t.toLowerCase()===e)),Ar=e=>ye.find(({card:r})=>r.toLowerCase()===e.name.toLowerCase()),ye=[{abbreviations:["10k"],card:"10,000 Year Reunion"},{abbreviations:["Pajamas","PJs"],card:"Alluvion Constellas"},{abbreviations:["Slippy","Arakni Slipped Through the Cracks","Arakni, Slipped Through the Cracks"],card:"Arakni, 5L!p3d 7hRu 7h3 cR4X"},{abbreviations:["Dullcap"],card:"Arcanite Skullcap"},{abbreviations:["ALS"],card:"Arc Light Sentinel"},{abbreviations:["AoW"],card:"Art of War"},{abbreviations:["BBD"],card:"Barraging Beatdown"},{abbreviations:["BBS"],card:"Big Blue Sky"},{abbreviations:["Starvo"],card:"Bravo, Star of the Show"},{abbreviations:["BEB"],card:"Bull's Eye Bracers"},{abbreviations:["BLW"],card:"Be Like Water"},{abbreviations:["BoJ"],card:"Balance of Justice"},{abbreviations:["BOHH"],card:"Blood on Her Hands"},{abbreviations:["BRB"],card:"Bloodrush Bellow"},{abbreviations:["Breezies"],card:"Breeze Rider Boots"},{abbreviations:["BTA"],card:"Burn Them All"},{abbreviations:["CStrike","C-Strike","C Strike"],card:"Celestial Cataclysm"},{abbreviations:["CBelly"],card:"Cerebellum Processor"},{abbreviations:["CLF"],card:"Channel Lake Frigid"},{abbreviations:["CLV"],card:"Channel Lightning Valley"},{abbreviations:["CMH"],card:"Channel Mount Heroic"},{abbreviations:["CMI"],card:"Channel Mount Isen"},{abbreviations:["CMT"],card:"Channel the Millennium Tree"},{abbreviations:["CnC","C&C"],card:"Command and Conquer"},{abbreviations:["Sea and Sea"],card:"Conqueror of the High Seas"},{abbreviations:["CYB"],card:"Count Your Blessings"},{abbreviations:["Cat","Kitty"],card:"Crouching Tiger"},{abbreviations:["CoD"],card:"Crown of Dominion"},{abbreviations:["CoP"],card:"Crown of Providence"},{abbreviations:["CtW"],card:"Crush the Weak"},{abbreviations:["DD"],card:"Death Dealer"},{abbreviations:["DnD"],card:"Devotion Never Dies"},{abbreviations:["DIO"],card:"Dash I/O"},{abbreviations:["EBTT"],card:"Even Bigger Than That!"},{abbreviations:["NewNigma"],card:"Enigma, New Moon"},{abbreviations:["EPot","E Pot"],card:"Energy Potion"},{abbreviations:["EStrike","E-Strike","E Strike"],card:"Enlightened Strike"},{abbreviations:["FFS"],card:"Fyendal's Fighting Spirit"},{abbreviations:["FoN"],card:"Force of Nature"},{abbreviations:["Frosty","\u{1F976}","\u{1F9CA}","\u2744\uFE0F"],card:"Frostbite"},{abbreviations:["Yum yum"],card:"Fruits of the Forest"},{abbreviations:["GnT"],card:"Give and Take"},{abbreviations:["Habibi"],card:"Hanabi Blaster"},{abbreviations:["HMH"],card:"Hope Merchant's Hood"},{abbreviations:["HoI"],card:"Heart of Ice"},{abbreviations:["Pumpkin"],card:"Jack-o'-lantern"},{abbreviations:["RKO","Cheato"],card:"Kayo, Underhanded Cheat"},{abbreviations:["KKBB"],card:"Knick Knack Bric-a-brac"},{abbreviations:["BStrike"],card:"Levels of Enlightenment"},{abbreviations:["LAG","Twominaris"],card:"Luminaris, Angel's Glow"},{abbreviations:["LCF","Newminaris"],card:"Luminaris, Celestial Fury"},{abbreviations:["LDE"],card:"Last Ditch Effort"},{abbreviations:["LtC"],card:"Lead the Charge"},{abbreviations:["LNW"],card:"Leave No Witnesses"},{abbreviations:["LFaL","L4aL"],card:"Life for a Life"},{abbreviations:["LiT"],card:"Lost in Thought"},{abbreviations:["MMB"],card:"Mage Master Boots"},{abbreviations:["MaxV"],card:"Maximum Velocity"},{abbreviations:["MoM"],card:"Mask of Momentum"},{abbreviations:["MoPL"],card:"Mask of the Pouncing Lynx"},{abbreviations:["MnG"],card:"Meat and Greet"},{abbreviations:["Cake","\u{1F382}"],card:"Ninth Blade of the Blood Oath"},{abbreviations:["PoM"],card:"Peace of Mind"},{abbreviations:["P-Bone"],card:"Performance Bonus"},{abbreviations:["PF","\u{1F525}"],card:"Phoenix Flame"},{abbreviations:["PtW"],card:"Poison the Well"},{abbreviations:["Thanos","Infinity Gauntlet"],card:"Polarity Reversal Script"},{abbreviations:["DPot","D Pot"],card:"Potion of D\xE9j\xE0 Vu"},{abbreviations:["Ponder Run"],card:"Premeditate"},{abbreviations:["Qi Unbound"],card:"Qi Unleashed"},{abbreviations:["RitL"],card:"Red in the Ledger"},{abbreviations:["Cats","Ghost cat","Ghost cats"],card:"Restless Coalescence"},{abbreviations:["Eugene"],card:"Rhinar, Reckless Rampage",isHidden:!0},{abbreviations:["SSGB"],card:"Sandscour Greatbow"},{abbreviations:["SSP"],card:"Sand Sketched Plan"},{abbreviations:["SFaS","S4aS"],card:"Scar for a Scar"},{abbreviations:["Tyler"],card:"Scurv, Stowaway",isHidden:!0},{abbreviations:["SWOMB"],card:"Shifting Winds of the Mystic Beast"},{abbreviations:["Snaps"],card:"Snapdragon Scalers"},{abbreviations:["SWK"],card:"Spinning Wheel Kick"},{abbreviations:["SFTL"],card:"Swing Fist, Think Later"},{abbreviations:["TTT"],card:"Take the Tempo"},{abbreviations:["Ultron"],card:"Teklovossen, the Mechropotent"},{abbreviations:["ToS"],card:"Test of Strength"},{abbreviations:["TAYG"],card:"That All You Got?"},{abbreviations:["TROM"],card:"This Round's on Me"},{abbreviations:["3oak"],card:"Three of a Kind"},{abbreviations:["Pox Malone","Post Malone"],card:"Virulent Touch"},{abbreviations:["Cast Homes"],card:"Visit Goldmane Estate"},{abbreviations:["Frosty Hammer"],card:"Winter's Wail"},{abbreviations:["Wreckless Wing"],card:"War Cry of Bellona"},{abbreviations:["ZTS"],card:"Zero to Sixty"}];var I=require("@flesh-and-blood/types");var Ne=(a=>(a.BannedFormats="bannedFormats",a.LegalFormats="legalFormats",a.LegalHeroes="legalHeroes",a))(Ne||{}),ie=Array.from(Array(50).keys()).map(e=>`${e}`),xr=[{format:I.Format.ClassicConstructed,nicknames:["cc","classic"]},{format:I.Format.LivingLegend,nicknames:["cc ll","classic constructed ll","ll cc","ll","living legend"]},{format:I.Format.SilverAge,nicknames:["sage"]},{format:I.Format.GoldenAge,nicknames:["gage"]},{format:I.Format.UltimatePitFight,nicknames:["upf"]}],Sr=Object.values(I.Format).map(e=>{let r=xr.find(({format:a})=>a===e),t=e.toLowerCase().replaceAll(T,"");return r?{...r,format:t}:{format:t}}),Pr=[{hero:I.Hero.DataDoll,nicknames:["data","datadoll"]},{hero:I.Hero.Dorinthea,nicknames:["dori"]},{hero:I.Hero.Genis,nicknames:["genis"]},{hero:I.Hero.GravyBones,nicknames:["gravy"]},{hero:I.Hero.Iyslander,nicknames:["islander"]}],wr=Object.values(I.Hero).map(e=>{let r=Pr.find(({hero:a})=>a===e),t=e.toLowerCase().replaceAll(T,"");return r?{...r,hero:t}:{hero:t}}),re=["common","rare","super rare","majestic","legendary","fabled"],kr=(e,r,t,a)=>{let i=[];if(!r)i.push(...e);else for(let s of e)switch(r){case">=":{let o=!1;for(let n of re)o?i.push(n):n===s&&(o=!0,i.push(n));break}case">":{let o=!1;for(let n of re)o?i.push(n):n===s&&(o=!0);break}case"<=":{let o=!1;for(let n of re.slice().reverse())o?i.push(n):n===s&&(o=!0,i.push(n));break}case"<":{let o=!1;for(let n of re.slice().reverse())o?i.push(n):n===s&&(o=!0);break}default:break}return{filterToPropertyMapping:{nestedProperty:"rarity",property:"printings",isArray:!0},isExcluded:t,isOptional:a,isOr:!0,values:i}},De=(e,r,t,a,i)=>{let s=a.map(g=>({hero:g.toLowerCase().replaceAll(T,"")})),o=[],n=[],c=[];for(let g of e){let f=Sr.find(({format:m,nicknames:M})=>m===g||!!M&&M.includes(g));if(f)n.push(f.format);else{let m=wr.find(({hero:M,nicknames:x})=>M===g||!!x&&x.includes(g))||s.find(({hero:M})=>M===g);m&&c.push(m.hero)}}let F=i||"legalFormats";return n.length>0&&o.push({filterToPropertyMapping:{property:F,isArray:!0},values:n,isOr:!0,isExcluded:r,isOptional:t}),c.length>0&&o.push({filterToPropertyMapping:{property:"legalHeroes",isArray:!0},values:c,isOr:!0,isExcluded:r,isOptional:t}),o},Ir=(e,r,t,a)=>De(e,r,t,a,"bannedFormats"),he=(e,r,t,a,i,s)=>{let o=[];return Lr(t)?o.push(...De(a,e,r,s)):Nr(t)?o.push(...Ir(a,e,r,s)):Or(t)&&o.push(kr(a,i,e,r)),o},_=[{filterToPropertyMapping:{property:"cost",isNumber:!0},isExcluded:!0,values:ie},{filterToPropertyMapping:{property:"specialCost",isString:!0,partialMatch:!0},isExcluded:!0,values:["*","x"]},{filterToPropertyMapping:{property:"types",isArray:!0,partialMatch:!0},isExcluded:!0,values:["equipment","hero","placeholder","token","weapon"]}],G=[{filterToPropertyMapping:{property:"defense",isNumber:!0},isExcluded:!0,values:ie},{filterToPropertyMapping:{property:"specialDefense",isString:!0,partialMatch:!0},isExcluded:!0,values:["*","x"]},{filterToPropertyMapping:{property:"types",isArray:!0,partialMatch:!0},isExcluded:!0,values:["hero","placeholder","token","weapon"]}],te=[{filterToPropertyMapping:{property:"pitch",isNumber:!0},isExcluded:!0,values:ie},{filterToPropertyMapping:{property:"types",isArray:!0,partialMatch:!0},isExcluded:!0,values:["equipment","hero","placeholder","token","weapon"]},{filterToPropertyMapping:{property:"isCardBack",isBoolean:!0},isExcluded:!0,values:["true"]}],z=[{filterToPropertyMapping:{property:"power",isNumber:!0},isExcluded:!0,values:ie},{filterToPropertyMapping:{property:"specialPower",isString:!0,partialMatch:!0},isExcluded:!0,values:["*","x"]},{filterToPropertyMapping:{property:"types",isArray:!0,partialMatch:!0},isExcluded:!0,values:["equipment","hero","placeholder","token"]}],ae=[{filterToPropertyMapping:{property:"talents",isArray:!0},isExcluded:!0,values:Object.values(I.Talent).map(e=>e.toLowerCase())}],Br={"!co":_,"-co":_,"!cost":_,"-cost":_,"!color":_,"-color":_,"!b":G,"-b":G,"!block":G,"-block":G,"!d":G,"-d":G,"!def":G,"-def":G,"!defense":G,"-defense":G,"!pitch":te,"-pitch":te,"!p":te,"-p":te,"!attack":z,"-attack":z,"!power":z,"-power":z,"!pwr":z,"-pwr":z,"!pow":z,"-pow":z,"!talents":ae,"-talents":ae,"!tal":ae,"-tal":ae},Ce=e=>{let r=[],t=Br[e];return t&&r.push(...t),r},Rr=["l","legal","hero"],Lr=e=>Rr.includes(e),Er=["banned"],Nr=e=>Er.includes(e),Dr=["r","rarity"],Or=e=>Dr.includes(e);var O=require("@flesh-and-blood/types"),be=[{description:"Attack actions",expanded:["st:attack"],filters:{subtypes:[O.Subtype.Attack]},isCardProperty:!1,shorthands:["AA"]},{description:"Arcane barrier",expanded:['k:"arcane barrier"'],filters:{keywords:[O.Keyword.ArcaneBarrier]},isCardProperty:!1,shorthands:["AB"]},{description:"Attack reactions",expanded:['t:"attack reaction"'],filters:{types:[O.Type.AttackReaction]},isCardProperty:!1,shorthands:["AR"]},{description:"Defense reactions",expanded:['t:"defense reaction"'],filters:{types:[O.Type.DefenseReaction]},isCardProperty:!1,shorthands:["DR"]},{description:"Gain life",expanded:["gain {h}"],filters:{functionalText:"gain {h}"},isCardProperty:!1,shorthands:["Gain life","Gains life"]},{description:"Go again",expanded:['k:"go again"'],filters:{keywords:[O.Keyword.GoAgain]},isCardProperty:!1,shorthands:["GA"]},{description:"Non-attack actions",expanded:["t:action","st:non-attack"],filters:{subtypes:[O.Subtype.NonAttack],types:[O.Type.Action]},isCardProperty:!1,shorthands:["NAA"]},{description:"Plus defense",expanded:["+ {d}"],filters:{functionalText:"+ {d}"},isCardProperty:!1,shorthands:["Pump defense","Pumps defense","Buff defense","Buffs defense"]},{description:"Spellvoid",expanded:['k:"spellvoid"'],filters:{keywords:[O.Keyword.Spellvoid]},isCardProperty:!1,shorthands:["SV"]}],me=be.filter(({shorthands:e})=>e.some(r=>r.includes(" "))).map(e=>({...e,shorthands:e.shorthands.filter(r=>r.includes(" ")).map(r=>r.toLowerCase()).sort((r,t)=>t.length-r.length)})),Te=be.filter(({shorthands:e})=>e.some(r=>!r.includes(" "))).map(e=>({...e,shorthands:e.shorthands.filter(r=>!r.includes(" ")).map(r=>r.toLowerCase()).sort((r,t)=>t.length-r.length)}));var $=e=>J(e.toLowerCase().trim().replace(T,"")),J=e=>e.normalize("NFD").replace(/\p{Diacritic}/gu,""),Y=e=>e.replace(ge,"");var q=require("@flesh-and-blood/types");var Oe=new WeakMap,K=Object.freeze([]),Hr=Number.MAX_SAFE_INTEGER,He=(e,r)=>{let t=new Map;for(let a of e)for(let i of r(a)||[]){let s=t.get(i);s?s.push(a):t.set(i,[a])}return t},Vr=e=>{let r=new Map;for(let t of e){let a=t.types.includes(q.Type.Hero)&&!t.isCardBack,i=a?q.CardRole.Hero:(0,q.getCardRole)(t);if(a||i!==q.CardRole.Hero){let o=r.get(i);o?o.push(t):r.set(i,[t])}}return r},Gr=e=>{let r,t,a,i,s,o=()=>{if(!r){let l=new Map,u=new Map,p=[],y=new Map,b=0;for(let B of e){l.set(B.cardIdentifier,B),u.set(B.cardIdentifier,b),b++;let A=$(B.name),E=y.get(A);E?E.push(B):(y.set(A,[B]),p.push(A))}r={cardByCardIdentifier:l,corpusPositionByCardIdentifier:u,cleanedNames:p,pitchCycleByCleanedName:y}}return r},n=l=>{let{corpusPositionByCardIdentifier:u}=o(),p=({cardIdentifier:y})=>u.get(y)??Hr;return[...l].sort((y,b)=>p(y)-p(b))},c=l=>o().cardByCardIdentifier.get(l),F=l=>{let{cardByCardIdentifier:u}=o(),p=[];for(let y of l||[]){let b=u.get(y);b&&p.push(b)}return n(p)},g=l=>{let u=new Map;return p=>{let y=u.get(p);if(!y){let b=c(p),B=F(b&&l(b)),A=B.length>0;y=A?B:K,A&&u.set(p,y)}return y}},f=l=>{let{pitchCycleByCleanedName:u}=o(),p=c(l);return p?u.get($(p.name))??K:K},m=l=>{let{cleanedNames:u,pitchCycleByCleanedName:p}=o(),y=$(l),b=p.get(y);if(!b&&y.length>0){let A=u.find(E=>E.includes(y));A&&(b=p.get(A))}return b??K},M=l=>{let{pitchCycleByCleanedName:u}=o();return u.get($(l))??K},x=()=>{if(!s){let l=new Set;for(let u of e)for(let p of u.artists)l.add(p);s=[...l].sort((u,p)=>u.localeCompare(p,"en",{sensitivity:"base"}))}return s},R=g(({oppositeSideCardIdentifiers:l})=>l),W=g(({referencedCards:l})=>l),P=l=>(t||(t=He(e,({referencedCards:u})=>u)),t.get(l)??K),w=g(({createdExtras:l})=>l);return{cards:e,getCard:c,getPitchCycle:f,getCardsByName:m,getCardsByExactName:M,getArtists:x,getOppositeSide:R,getReferences:W,getReferencedBy:P,getCreates:w,getCreatedBy:l=>(a||(a=He(e,({createdExtras:u})=>u)),a.get(l)??K),getCreatedClosure:l=>{let u=new Map,p=new Set,y=[...l];for(let b of y)if(!p.has(b)){p.add(b);for(let A of w(b))u.set(A.cardIdentifier,A),y.push(A.cardIdentifier)}return n([...u.values()])},getByRole:l=>(i||(i=Vr(e)),i.get(l)??K),getCardsInCorpusOrder:n}},Me=e=>{let r=Oe.get(e);return r||(r=Gr(e),Oe.set(e,r)),r},Fe=(e,r)=>e.getPitchCycle(r.cardIdentifier),se=(e,r)=>e.getCardsByName(r),Ve=(e,r)=>{let t=new Map;for(let a of r)for(let i of Fe(e,a))t.set(i.cardIdentifier,i);return e.getCardsInCorpusOrder([...t.values()])},oe=(e,r)=>{let t=[];for(let a of Fe(e,r))t.push(...e.getReferencedBy(a.cardIdentifier));return Ve(e,t)},ne=(e,r)=>{let t=[];for(let a of Fe(e,r))t.push(...e.getReferences(a.cardIdentifier));return Ve(e,t)};var cr=[">=",">","<=","<"],pr=["!","-"],Wr={property:"arcane",specialProperty:"specialArcane",isNumber:!0,partialMatch:!0},ve={property:"artists",isArray:!0,partialMatch:!0},Ge={property:"n/a",isMeta:!0},We={property:"bonds",isArray:!0},Ur={property:"cardIdentifier",isString:!0,isNormalized:!0},Ue=(e,{isAnd:r,isExcluded:t,isOptional:a,modifier:i})=>({filterToPropertyMapping:Ur,values:[...e],valuesSet:e,isAnd:r,isOr:!0,modifier:i,isExcluded:t,isOptional:a}),zr={property:"n/a"},ze={property:"classes",isArray:!0,partialMatch:!0},Ke={property:"cost",specialProperty:"specialCost",isNumber:!0,partialMatch:!0},Q={property:"defense",specialProperty:"specialDefense",isNumber:!0},je={property:"flows",isArray:!0},qe={nestedProperty:"foiling",property:"printings",isArray:!0},_e={property:"fusions",isArray:!0},$e={property:"intellect",isNumber:!0},Ye={property:"keywords",isArray:!0},Ae={property:"n/a",isMeta:!0},Je={property:"life",specialProperty:"specialLife",isNumber:!0},we={property:"meta",isArray:!0},Qe={property:"name",isString:!0,partialMatch:!0},xe={property:"pitch",isNumber:!0},Xe={property:"firstReleaseDate",isDate:!0},le={property:"power",specialProperty:"specialPower",isNumber:!0},Kr={property:"setIdentifiers",isArray:!0,partialMatch:!0},Ze={property:"n/a",isMeta:!0},jr={property:"n/a"},qr={property:"n/a"},er={property:"sets",isArray:!0,partialMatch:!0},Se={property:"shorthands",isArray:!0,partialMatch:!0},de={property:"specializations",isArray:!0,partialMatch:!0},rr={property:"subtypes",isArray:!0},tr={property:"types",isArray:!0},ar={property:"talents",isArray:!0},_r={property:"functionalText",hasMarkup:!0,isString:!0,partialMatch:!0},$r={property:"traits",isArray:!0,partialMatch:!0},Yr={property:"typeText",isString:!0,partialMatch:!0},ce={nestedProperty:"treatments",property:"printings",isArray:!0,isNestedPropertyArray:!0},Jr={property:"firstReleaseDate",isString:!0,partialMatch:!0},Ie={arcane:Wr,a:ve,artist:ve,art:ve,attack:le,b:Q,block:Q,banned:Ge,bond:We,bonds:We,c:ze,class:ze,chain:zr,co:Ke,cost:Ke,color:xe,d:Q,def:Q,defense:Q,flow:je,flows:je,f:_e,fusion:_e,foil:qe,foiling:qe,i:$e,intellect:$e,is:we,k:Ye,keyword:Ye,l:Ae,legal:Ae,hero:Ae,li:Je,life:Je,meta:we,n:Qe,name:Qe,p:xe,pitch:xe,pwr:le,pow:le,power:le,print:Kr,r:Ze,rarity:Ze,referencedby:jr,references:qr,rf:Ge,s:er,set:er,short:Se,shorthand:Se,shorthands:Se,sp:de,spec:de,specialization:de,specializations:de,st:rr,subtype:rr,t:tr,type:tr,tal:ar,talent:ar,text:_r,trait:$r,treat:ce,treatment:ce,var:ce,variation:ce,x:Yr,year:Jr},Qr=[{text:d.Release.ClassicBattlesRhinarDorinthea.toLowerCase(),override:d.Release.ClassicBattlesRhinarDorinthea.toLowerCase().replaceAll(T,"")}],Xr=e=>{let r=[],t=e.replaceAll("\u201D",'"');for(let{text:i,override:s}of Qr)t.includes(i)&&(t=t.replace(i,s));if(ee(t)?.card)r.push(t);else{let i=t.split(/[ ]+/),s="",o=0;for(let n of i)o===2&&(r.push(s.trim().replaceAll('"',"")),s="",o=0),o<2&&n.split('"').length===2?(s+=" "+n,o++):o===0&&s===""?r.push(n):o===1&&(s+=" "+n);o===2&&(r.push(s.trim().replaceAll('"',"")),s="",o=0)}return r},Zr=20,Be=(e,r,t=[],a=[],i=ot())=>{let s=e.trim().toLowerCase();for(let{expanded:P,shorthands:w}of me)for(let h of w)if(s.includes(h)){s=s.replace(h,P.join(" "));break}for(let[P,w]of Object.entries(d.setToSetIdentifierMappings))s.includes(P.toLowerCase())&&(s=s.replace(P.toLowerCase(),w[0]));let o=Xr(s),n=[];for(let P of o){let w=Te.find(({shorthands:h})=>h.includes(P));w&&!w.isCardProperty?n.push(...w.expanded):n.push(P)}let c=[],F=[],g=[],f=[],m=!1,M=[],x=[],R=[],W=[];for(let P of n)if(ft(P)){let[w,h]=P.split(":"),{modifier:D,values:C,isAnd:l,isOr:u}=pt(h),{filterKey:p,isExcluded:y,isOptional:b,isMeta:B}=ut(w),A=!1;if(B){if(["rarity","r"].includes(p)){let E=ct(C);y||(x=[...E]),C=E.map(S=>S.toLowerCase())}["legal","l","hero"].includes(p),c.push(...he(y,b,p,C,D,t))}else{if(["chain"].includes(p)){let S=new Set,L=[],H=new Set,V=k=>{S.add(k.cardIdentifier),H.has(k.name)||(H.add(k.name),L.push(k))},j=k=>{k.types.includes(d.Type.Hero)||V(k)};for(let k of C)if(k)for(let N of se(r,k))V(N);let U=0;for(let k of L){if(U>Zr)break;for(let fe of ne(r,k))j(fe);if(U===0)for(let fe of oe(r,k))j(fe);U++}c.push(Ue(S,{isAnd:l,isExcluded:y,isOptional:b,modifier:D})),A=!0}else if(["referencedby","references"].includes(p)){let S=["referencedby"].includes(p),L=new Set;for(let H of C)if(H)for(let V of se(r,H)){let j=S?ne(r,V):oe(r,V);for(let U of j)L.add(U.cardIdentifier)}c.push(Ue(L,{isAnd:l,isExcluded:y,isOptional:b,modifier:D})),A=!0}else if(["art","artist"].includes(p))F=C;else if(["print","prints","printing","printings"].includes(p))M=C;else if(["is","meta"].includes(p)){let S=[],L=[],H=[],V=[];for(let N of C)at.includes(N)?S.push(N):it.includes(N)?L.push(N):st.includes(N)?H.push(N):V.push(N);S.length>0&&(c.push({filterToPropertyMapping:we,values:[d.Meta.Reprint.toLowerCase().replaceAll(T,"")],isAnd:l,isOr:u,isExcluded:!y,isOptional:b}),A=V.length===0);let j=L.length>0;j&&c.push({filterToPropertyMapping:Xe,values:[i],isAnd:l,isOr:u,isExcluded:y,isOptional:b});let U=H.length>0;U&&c.push({filterToPropertyMapping:Xe,values:[i],isAnd:l,isOr:u,isExcluded:!y,isOptional:b}),(j||U)&&(A=V.length===0);let k=nt(V);C=k.map(N=>N.toLowerCase().replaceAll(T,"")),k.includes(d.Meta.Expansion)&&!y&&(m=!0)}else["foiling","foil"].includes(p)?(f=lt(C),C=f.map(S=>S.toLowerCase())):["treat","treatment","var","variation"].includes(p)?(W=dt(C),C=W.map(S=>S.toLowerCase())):["set","s"].includes(p)?(R=et(C,a),C=R.map(S=>S.toLowerCase().replaceAll(T,""))):["pitch","p","color"].includes(p)&&(C=tt(C));let E=Ie[p];E&&!A&&c.push({filterToPropertyMapping:E,values:E.hasMarkup?C.map(S=>Y(S)):C,isAnd:l,isOr:u,modifier:D,isExcluded:y,isOptional:b})}}else if(P){let w=ee(P)?.card,h=Ce(P);w?g.push(`"${w.toLowerCase().replace(T,"")}"`):h&&h.length>0?c.push(...h):g.push(P.replace(T,""))}return{appliedFilters:c,attributes:{artists:F,foilings:f,isExpansionSlot:m,prints:M,rarities:x,releases:R,treatments:W},keywords:g}},et=(e,r=[])=>{let t=[];for(let a of e)t.push(...rt(a,r));return t},rt=(e,r=[])=>{let t=[],a=Object.values(d.Release).find(i=>i.toLowerCase().replaceAll(T,"")===e);if(a&&t.push(a),t.length===0){let i=d.setIdentifierToSetMappings[e];i&&t.push(i)}if(t.length===0){let i=Object.values(d.Release).filter(s=>s.toLowerCase().includes(e));i.length>0&&t.push(...i)}if(t.length===0){let i=r.find(s=>s.toLowerCase().replaceAll(T,"")===e);i&&t.push(i)}return t},Pe={purple:4,blue:3,yellow:2,red:1,white:0},tt=e=>{let r=[];for(let t of e)Pe[t]||Pe[t]===0?r.push(Pe[t].toString()):r.push(t);return r},at=["unique"],it=["preview","spoiler","unreleased"],st=["released"],ot=()=>{let e=new Date,r=`${e.getMonth()+1}`.padStart(2,"0"),t=`${e.getDate()}`.padStart(2,"0");return`${e.getFullYear()}-${r}-${t}`},ir={dual:d.Meta.DualClass,exp:d.Meta.Expansion,expansion:d.Meta.Expansion,expansionSlot:d.Meta.Expansion,rainbow:d.Meta.Rainbow,reprint:d.Meta.Reprint,reprints:d.Meta.Reprint},nt=e=>{let r=[];for(let t of e)ir[t]?r.push(ir[t]):d.Meta[t]&&r.push(d.Meta[t]);if(e.length>0&&r.length===0){for(let t of Object.values(d.Meta))for(let a of e)if(t.toLowerCase().includes(a)){r.push(t);break}}return r},sr={r:d.Foiling.Rainbow,rf:d.Foiling.Rainbow,rainbow:d.Foiling.Rainbow,c:d.Foiling.Cold,cf:d.Foiling.Cold,cold:d.Foiling.Cold,g:d.Foiling.Gold,gf:d.Foiling.Gold,gold:d.Foiling.Gold},lt=e=>{let r=[];for(let t of e)sr[t]&&r.push(sr[t]);return r},or={...Object.values(d.Treatment).reduce((e,r)=>(e[r.toLowerCase()]=r,e),{}),aa:d.Treatment.AA,alt:d.Treatment.AA,"alt art":d.Treatment.AA,ab:d.Treatment.AB,"alt border":d.Treatment.AB,at:d.Treatment.AT,"alt text":d.Treatment.AT,ea:d.Treatment.EA,extended:d.Treatment.EA,"extended art":d.Treatment.EA,fa:d.Treatment.FA,full:d.Treatment.FA,"full art":d.Treatment.FA},dt=e=>{let r=[];for(let t of e)or[t]?r.push(or[t]):d.Treatment[t.toUpperCase()]&&r.push(d.Treatment[t.toUpperCase()]);return r},ke={b:d.Rarity.Basic,c:d.Rarity.Common,f:d.Rarity.Fabled,l:d.Rarity.Legendary,m:d.Rarity.Majestic,p:d.Rarity.Promo,r:d.Rarity.Rare,s:d.Rarity.SuperRare,t:d.Rarity.Token,v:d.Rarity.Marvel},ct=e=>{let r=[];for(let t of e)ke[t]?r.push(ke[t]):r.push(t);return r},pt=e=>{let r=[],t,a,i=cr.find(s=>e.includes(s));if(i){let[,s]=e.split(i);nr(s)?(t=!0,r.push(...s.trim().split("+").map(o=>o.replace(T,"")))):lr(s)?(a=!0,r.push(...s.trim().split(",").map(o=>o.replace(T,"")))):r.push(s.trim().replace(T,""))}else nr(e)?(t=!0,r.push(...e.trim().split("+").map(s=>s.replace(T,"")))):lr(e)?(a=!0,r.push(...e.trim().split(",").map(s=>s.replace(T,"")))):e.startsWith('"')&&e.endsWith('"')?r.push(e.trim().replaceAll('"',"").replace(T,"")):r.push(e.trim().replace(T,""));return{modifier:i,values:r,isAnd:t,isOr:a}},ut=e=>{let r=gt(e);if(r){let[,t]=e.split(r);return{filterKey:t,isExcluded:!0,isOptional:!1,isMeta:dr(t)}}else return{filterKey:e,isExcluded:!1,isOptional:!1,isMeta:dr(e)}},ft=e=>e.indexOf(":")>=0,nr=e=>e.indexOf("+")>=0,lr=e=>e.indexOf(",")>=0,dr=e=>!!Ie[e]?.isMeta,gt=e=>pr.find(r=>e.includes(r))?.slice(0,1);var v=require("@flesh-and-blood/types"),ur={artists:["Hoodwill"],cardIdentifier:"fangs-a-lot-blue",classes:[v.Class.Generic],defaultImage:"FNG000",firstReleaseDate:"2022-06-02",functionalText:"If Fangs A Lot is put into your banished zone from your graveyard, instead put it into your hand.",legalFormats:[],legalHeroes:[v.Hero.Kayo,v.Hero.Levia,v.Hero.Rhinar],printings:[{artists:["Hoodwill"],identifier:"FNG000",image:"FNG000",print:"FNG000",rarity:v.Rarity.Rare,set:v.Release.Promos},{artists:["Hoodwill"],identifier:"FNG000",image:"FNG000_Marvel",print:`FNG000-${v.Treatment.FA}`,rarity:v.Rarity.Marvel,set:v.Release.Promos,treatment:v.Treatment.FA}],name:"Fangs A Lot",rarities:[v.Rarity.Rare,v.Rarity.Marvel],rarity:v.Rarity.Rare,sets:[v.Release.Promos],setIdentifiers:["FNG000"],specialImage:"FNG000_Marvel",subtypes:[v.Subtype.Attack],types:[v.Type.Action],typeText:"Generic Action - Attack"},fr=[{keyword:ur.name.toLowerCase(),card:ur}];var yt={getFn:(e,r)=>{let t=Le.default.config.getFn(e,r),a=t;if(Array.isArray(t))a=t.map(i=>J(i.replace(T,"")));else if(t){let i=J(t).replace(T,"");a=r.includes("functionalText")?Y(i):i}return a},ignoreLocation:!0,includeScore:!0,keys:[{name:"name",weight:10},{name:"functionalText",weight:6},{name:"shorthands",weight:4},{name:"setIdentifiers",weight:2},{name:"traits",weight:4},{name:"typeText",weight:6}],threshold:.15,useExtendedSearch:!0},Re=class{constructor(r,t=[],a=[],i=!1){this.getFuse=()=>(this.fuse||(this.fuse=new Le.default(this.cards,yt)),this.fuse);this.log=(r,...t)=>{this.debug&&console.log(r,...t)};this.search=(r,t)=>{let a,{appliedFilters:i,attributes:s,keywords:o}=Be(r,this.index,this.additionalHeroes,this.additionalSets),n=o.join(" "),c=t?fr.filter(h=>h.keyword===n):[];if(c.length>0?a=c.map(({card:h})=>h):o.length?a=this.getFuse().search(n).map(h=>h.item):a=[...this.cards],i.length&&(a=a.filter(h=>h&&yr(h,i))),o.length===0){let h="";if(s.releases.length===1)try{let l=s.releases[0];h=pe.setToSetIdentifierMappings[l][0].toUpperCase()}catch(l){console.error("Error getting set identifier from search",l)}if(!h&&s.prints.length===1)try{let l=s.prints[0];pe.setIdentifierToSetMappings[l]&&(h=l.toUpperCase())}catch(l){console.error("Error getting set identifier from search",l)}h?a.sort((l,u)=>{let p=l.setIdentifiers.find(b=>b.includes(h))?.replace(h,""),y=u.setIdentifiers.find(b=>b.includes(h))?.replace(h,"");return p&&y?p.localeCompare(y):-1}):a.sort((l,u)=>l.name===u.name?`${l.pitch}`.localeCompare(`${u.pitch}`):l.name.localeCompare(u.name))}else{let h=[],D=[],C=o.map(l=>l.toLowerCase().replace(T,"")).join(" ");for(let l of a)l.name.toLowerCase().replace(T,"")===C?h.push(l):D.push(l);a=[...h,...D]}let F,{artists:g,isExpansionSlot:f,foilings:m,prints:M,rarities:x,releases:R,treatments:W}=s;(g.length>0||f||m.length>0||M.length>0||x.length>0||R.length>0||W.length>0)&&(F=a.map(h=>{let D=h.printings.filter(C=>{let l=!!C.image,u=g.length===0||g.some(L=>C.artists.find(H=>H.replace(T,"").toLowerCase().includes(L))),p=!f||f===C.isExpansionSlot,y=m.length===0||m.includes(C.foiling),b=M.length===0||M.some(L=>C.identifier.includes(L.toUpperCase())),B=x.length===0||x.includes(C.rarity),A=R.length===0||R.includes(C.set),E=W.length===0||C.treatments?.some(L=>W.includes(L));return l&&u&&p&&y&&b&&B&&A&&E});return{...h,matchingPrintings:D}}));let w=F?.length>0?F:a;return{appliedFilters:i,attributes:s,keywords:o,searchResults:w}};let s=Array.isArray(t)?{additionalHeroes:t,additionalSets:a,debug:i}:t;this.additionalHeroes=s.additionalHeroes||[],this.additionalSets=s.additionalSets||[],this.cards=[...r],this.debug=s.debug||!1,this.index=s.index||Me(r)}},gr=Re,yr=(e,r)=>{let t=!0,a=!1;for(let i of r){let s=i.isOptional,{isNumber:o,isString:n,isArray:c,isBoolean:F,isDate:g}=i.filterToPropertyMapping;if(o){let f=ht(e,i);s?f&&(a=!0):t=t&&f}else if(n){let f=Ct(e,i);s?f&&(a=!0):t=t&&f}else if(c){let f=bt(e,i,r);s?f&&(a=!0):t=t&&f}else if(F){let f=mt(e,i);s?f&&(a=!0):t=t&&f}else if(g){let f=Tt(e,i);s?f&&(a=!0):t=t&&f}}return t},ht=(e,r)=>{if(X(r,e)){let{values:t,modifier:a,isExcluded:i,filterToPropertyMapping:{partialMatch:s}}=r,o=ue(e,r);if(o!=null&&!isNaN(o))if(o=parseInt(o),a)switch(a){case">=":{let n=t?.some(c=>o>=parseInt(c));return i?!n:n}case">":{let n=t?.some(c=>o>parseInt(c));return i?!n:n}case"<=":{let n=t?.some(c=>o<=parseInt(c));return i?!n:n}case"<":{let n=t?.some(c=>o<parseInt(c));return i?!n:n}default:return!1}else{let n=t?.some(c=>o===parseInt(c));return i?!n:n}else{let n=Ft(e,r)?.toLowerCase(),c=s?t?.some(F=>n?.includes(F)):t?.some(F=>n===F);return i?!c:c}}else return!0},Ct=(e,r)=>{if(X(r,e)){let{values:t,valuesSet:a,isAnd:i,isExcluded:s,filterToPropertyMapping:{hasMarkup:o,isNormalized:n,partialMatch:c}}=r,F=ue(e,r),g=n?F:F?.replaceAll(T,"").toLowerCase(),f=o&&g?Y(g):g;if(c){let m=i?t?.every(M=>f?.includes(M)):t?.some(M=>f?.includes(M));return s?!m:m}else{let m;return i?m=t?.every(M=>f===M):a?m=a.has(f):m=t?.some(M=>f===M),s?!m:m}}else return!0},bt=(e,r,t)=>{if(X(r,e)){let{values:a,isAnd:i,isExcluded:s,filterToPropertyMapping:{partialMatch:o}}=r,n=Mt(e,r,t).map(c=>c?.replaceAll(T,""));if(o){let c=i?a.every(g=>n?.some(f=>f?.toLowerCase().includes(g))):a.some(g=>n?.some(f=>f?.toLowerCase().includes(g))),F=n.length===0;return s?!c||F:c}else{let c=i?a.every(F=>n?.some(g=>g?.toLowerCase()===F)):a.some(F=>n?.some(g=>g?.toLowerCase()===F));return s?!c:c}}else return!0},mt=(e,r)=>{if(X(r,e)){let{isExcluded:t}=r,a=ue(e,r);return t?!a:a}else return!0},Tt=(e,r)=>{if(X(r,e)){let{values:t,isExcluded:a}=r,i=ue(e,r),s=t?.some(o=>i>o);return a?!s:s}else return!0},ue=(e,r)=>{let{filterToPropertyMapping:t}=r;return e[t.property]},Mt=(e,r,t)=>{let{filterToPropertyMapping:{isNestedPropertyArray:a,nestedProperty:i,property:s}}=r,o=e[s]||[],n=[],c=Object.keys(e.legalOverrides||{}).length>0,F=r.filterToPropertyMapping.property==="legalHeroes",g=t.find(({filterToPropertyMapping:m})=>m.property==="legalFormats");if(c&&F&&!!g){let m=new Set;for(let{format:M,heroes:x}of e.legalOverrides||[])if(g.values.includes(M.toLowerCase()))for(let R of x)m.add(R);n=Array.from(m)}if(n.length===0)if(i){let m=new Set;for(let M of o)if(a){let x=M[i]||[];for(let R of x)m.add(R)}else{let x=M[i];x&&m.add(x)}n=Array.from(m)}else n=o;return n},Ft=(e,r)=>{let{filterToPropertyMapping:t}=r;return e[t.specialProperty]},X=({cardTypes:e},{types:r,subtypes:t})=>!e||e?.some(a=>r.map(i=>i.toLowerCase()).includes(a.toLowerCase())||t.map(i=>i.toLowerCase()).includes(a.toLowerCase()));var vt=(e,r)=>{let t=[];if(e)for(let a of r){let i=a.name===e.name,s=a.cardIdentifier!==e.cardIdentifier,o=a.pitch!==e.pitch;i&&s&&o&&t.push(a)}return t},At=(e,r)=>{let t=new Set(e?.referencedCards),a=[];for(let i of r)t.has(i.cardIdentifier)&&a.push(i);return a},xt=e=>{let r=new Map;for(let t of e)for(let a of t.referencedCards||[]){let i=r.get(a);i?i.push(t):r.set(a,[t])}return r},St=(e,r)=>{let t=new Set;for(let i of e)for(let s of i.createdExtras||[])t.add(s);let a=[];for(let i of r)t.has(i.cardIdentifier)&&a.push(i);return a};0&&(module.exports={FilterProperty,MARKUP,PUNCTUATION,RARITY_VALUES_MAPPING,abbreviations,availableExclusions,availableModifiers,filterCard,filtersToCardPropertyMappings,getAbbreviation,getAbbreviationByCard,getCardsByName,getCardsByReferencedCardIdentifier,getCardsReferencedBy,getCardsReferencing,getCatalogueIndex,getCleanText,getExcludedMetaFilters,getKeywordsAndAppliedFiltersFromText,getMetaFilters,getNormalizedText,getOtherPitches,getReferencedCards,getTextWithoutMarkup,getTokensReferencedByCards,multiWordShorthands,shorthands,singleWordShorthands});
1
+ "use strict";var mr=Object.create;var ae=Object.defineProperty;var br=Object.getOwnPropertyDescriptor;var Tr=Object.getOwnPropertyNames;var Mr=Object.getPrototypeOf,Fr=Object.prototype.hasOwnProperty;var vr=(e,r)=>{for(var t in r)ae(e,t,{get:r[t],enumerable:!0})},De=(e,r,t,a)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of Tr(r))!Fr.call(e,i)&&i!==t&&ae(e,i,{get:()=>r[i],enumerable:!(a=br(r,i))||a.enumerable});return e};var Ar=(e,r,t)=>(t=e!=null?mr(Mr(e)):{},De(r||!e||!e.__esModule?ae(t,"default",{value:e,enumerable:!0}):t,e)),xr=e=>De(ae({},"__esModule",{value:!0}),e);var Lt={};vr(Lt,{FilterProperty:()=>X,MARKUP:()=>me,NO_CARD_PROPERTY:()=>K,PUNCTUATION:()=>b,RARITY_VALUES_MAPPING:()=>Be,abbreviations:()=>be,availableExclusions:()=>pr,availableModifiers:()=>cr,default:()=>hr,filterCard:()=>Cr,filtersToCardPropertyMappings:()=>ur,getAbbreviation:()=>ie,getAbbreviationByCard:()=>Pr,getCardsByName:()=>pe,getCardsByReferencedCardIdentifier:()=>It,getCardsReferencedBy:()=>fe,getCardsReferencing:()=>ue,getCatalogueIndex:()=>xe,getCleanText:()=>J,getExcludedMetaFilters:()=>Me,getKeywordsAndAppliedFiltersFromText:()=>Le,getMetaFilters:()=>Te,getNormalizedText:()=>Z,getOtherPitches:()=>kt,getReferencedCards:()=>Rt,getTextWithoutMarkup:()=>Q,getTokensReferencedByCards:()=>Bt,multiWordShorthands:()=>ve,shorthands:()=>Fe,singleWordShorthands:()=>Ae});module.exports=xr(Lt);var Ee=Ar(require("fuse.js"),1);var b=/[!"#$%&'’(),./:;<=>?@[\]^_`|~]/g,me=/\*/g;var d=require("@flesh-and-blood/types");var ie=e=>be.find(({abbreviations:r})=>r.find(t=>t.toLowerCase()===e)),Pr=e=>be.find(({card:r})=>r.toLowerCase()===e.name.toLowerCase()),be=[{abbreviations:["10k"],card:"10,000 Year Reunion"},{abbreviations:["Pajamas","PJs"],card:"Alluvion Constellas"},{abbreviations:["Slippy","Arakni Slipped Through the Cracks","Arakni, Slipped Through the Cracks"],card:"Arakni, 5L!p3d 7hRu 7h3 cR4X"},{abbreviations:["Dullcap"],card:"Arcanite Skullcap"},{abbreviations:["ALS"],card:"Arc Light Sentinel"},{abbreviations:["AoW"],card:"Art of War"},{abbreviations:["BBD"],card:"Barraging Beatdown"},{abbreviations:["BBS"],card:"Big Blue Sky"},{abbreviations:["Starvo"],card:"Bravo, Star of the Show"},{abbreviations:["BEB"],card:"Bull's Eye Bracers"},{abbreviations:["BLW"],card:"Be Like Water"},{abbreviations:["BoJ"],card:"Balance of Justice"},{abbreviations:["BOHH"],card:"Blood on Her Hands"},{abbreviations:["BRB"],card:"Bloodrush Bellow"},{abbreviations:["Breezies"],card:"Breeze Rider Boots"},{abbreviations:["BTA"],card:"Burn Them All"},{abbreviations:["CStrike","C-Strike","C Strike"],card:"Celestial Cataclysm"},{abbreviations:["CBelly"],card:"Cerebellum Processor"},{abbreviations:["CLF"],card:"Channel Lake Frigid"},{abbreviations:["CLV"],card:"Channel Lightning Valley"},{abbreviations:["CMH"],card:"Channel Mount Heroic"},{abbreviations:["CMI"],card:"Channel Mount Isen"},{abbreviations:["CMT"],card:"Channel the Millennium Tree"},{abbreviations:["CnC","C&C"],card:"Command and Conquer"},{abbreviations:["Sea and Sea"],card:"Conqueror of the High Seas"},{abbreviations:["CYB"],card:"Count Your Blessings"},{abbreviations:["Cat","Kitty"],card:"Crouching Tiger"},{abbreviations:["CoD"],card:"Crown of Dominion"},{abbreviations:["CoP"],card:"Crown of Providence"},{abbreviations:["CtW"],card:"Crush the Weak"},{abbreviations:["DD"],card:"Death Dealer"},{abbreviations:["DnD"],card:"Devotion Never Dies"},{abbreviations:["DIO"],card:"Dash I/O"},{abbreviations:["EBTT"],card:"Even Bigger Than That!"},{abbreviations:["NewNigma"],card:"Enigma, New Moon"},{abbreviations:["EPot","E Pot"],card:"Energy Potion"},{abbreviations:["EStrike","E-Strike","E Strike"],card:"Enlightened Strike"},{abbreviations:["FFS"],card:"Fyendal's Fighting Spirit"},{abbreviations:["FoN"],card:"Force of Nature"},{abbreviations:["Frosty","\u{1F976}","\u{1F9CA}","\u2744\uFE0F"],card:"Frostbite"},{abbreviations:["Yum yum"],card:"Fruits of the Forest"},{abbreviations:["GnT"],card:"Give and Take"},{abbreviations:["Habibi"],card:"Hanabi Blaster"},{abbreviations:["HMH"],card:"Hope Merchant's Hood"},{abbreviations:["HoI"],card:"Heart of Ice"},{abbreviations:["Pumpkin"],card:"Jack-o'-lantern"},{abbreviations:["RKO","Cheato"],card:"Kayo, Underhanded Cheat"},{abbreviations:["KKBB"],card:"Knick Knack Bric-a-brac"},{abbreviations:["BStrike"],card:"Levels of Enlightenment"},{abbreviations:["LAG","Twominaris"],card:"Luminaris, Angel's Glow"},{abbreviations:["LCF","Newminaris"],card:"Luminaris, Celestial Fury"},{abbreviations:["LDE"],card:"Last Ditch Effort"},{abbreviations:["LtC"],card:"Lead the Charge"},{abbreviations:["LNW"],card:"Leave No Witnesses"},{abbreviations:["LFaL","L4aL"],card:"Life for a Life"},{abbreviations:["LiT"],card:"Lost in Thought"},{abbreviations:["MMB"],card:"Mage Master Boots"},{abbreviations:["MaxV"],card:"Maximum Velocity"},{abbreviations:["MoM"],card:"Mask of Momentum"},{abbreviations:["MoPL"],card:"Mask of the Pouncing Lynx"},{abbreviations:["MnG"],card:"Meat and Greet"},{abbreviations:["Cake","\u{1F382}"],card:"Ninth Blade of the Blood Oath"},{abbreviations:["PoM"],card:"Peace of Mind"},{abbreviations:["P-Bone"],card:"Performance Bonus"},{abbreviations:["PF","\u{1F525}"],card:"Phoenix Flame"},{abbreviations:["PtW"],card:"Poison the Well"},{abbreviations:["Thanos","Infinity Gauntlet"],card:"Polarity Reversal Script"},{abbreviations:["DPot","D Pot"],card:"Potion of D\xE9j\xE0 Vu"},{abbreviations:["Ponder Run"],card:"Premeditate"},{abbreviations:["Qi Unbound"],card:"Qi Unleashed"},{abbreviations:["RitL"],card:"Red in the Ledger"},{abbreviations:["Cats","Ghost cat","Ghost cats"],card:"Restless Coalescence"},{abbreviations:["Eugene"],card:"Rhinar, Reckless Rampage",isHidden:!0},{abbreviations:["SSGB"],card:"Sandscour Greatbow"},{abbreviations:["SSP"],card:"Sand Sketched Plan"},{abbreviations:["SFaS","S4aS"],card:"Scar for a Scar"},{abbreviations:["Tyler"],card:"Scurv, Stowaway",isHidden:!0},{abbreviations:["SWOMB"],card:"Shifting Winds of the Mystic Beast"},{abbreviations:["Snaps"],card:"Snapdragon Scalers"},{abbreviations:["SWK"],card:"Spinning Wheel Kick"},{abbreviations:["SFTL"],card:"Swing Fist, Think Later"},{abbreviations:["TTT"],card:"Take the Tempo"},{abbreviations:["Ultron"],card:"Teklovossen, the Mechropotent"},{abbreviations:["ToS"],card:"Test of Strength"},{abbreviations:["TAYG"],card:"That All You Got?"},{abbreviations:["TROM"],card:"This Round's on Me"},{abbreviations:["3oak"],card:"Three of a Kind"},{abbreviations:["Pox Malone","Post Malone"],card:"Virulent Touch"},{abbreviations:["Cast Homes"],card:"Visit Goldmane Estate"},{abbreviations:["Frosty Hammer"],card:"Winter's Wail"},{abbreviations:["Wreckless Wing"],card:"War Cry of Bellona"},{abbreviations:["ZTS"],card:"Zero to Sixty"}];var k=require("@flesh-and-blood/types");var se=require("@flesh-and-blood/types"),E=e=>Object.assign(Object.create(null),e),oe=E(se.setIdentifierToSetMappings),Oe=E(se.setToSetIdentifierMappings);var X={BannedFormats:"bannedFormats",LegalFormats:"legalFormats",LegalHeroes:"legalHeroes"},ce=Array.from(Array(50).keys()).map(e=>`${e}`),Sr=[{format:k.Format.ClassicConstructed,nicknames:["cc","classic"]},{format:k.Format.LivingLegend,nicknames:["cc ll","classic constructed ll","ll cc","ll","living legend"]},{format:k.Format.SilverAge,nicknames:["sage"]},{format:k.Format.GoldenAge,nicknames:["gage"]},{format:k.Format.UltimatePitFight,nicknames:["upf"]}],wr=Object.values(k.Format).map(e=>{let r=Sr.find(({format:a})=>a===e),t=e.toLowerCase().replaceAll(b,"");return r?{...r,format:t}:{format:t}}),kr=[{hero:k.Hero.DataDoll,nicknames:["data","datadoll"]},{hero:k.Hero.Dorinthea,nicknames:["dori"]},{hero:k.Hero.Genis,nicknames:["genis"]},{hero:k.Hero.GravyBones,nicknames:["gravy"]},{hero:k.Hero.Iyslander,nicknames:["islander"]}],Rr=Object.values(k.Hero).map(e=>{let r=kr.find(({hero:a})=>a===e),t=e.toLowerCase().replaceAll(b,"");return r?{...r,hero:t}:{hero:t}}),ne=["common","rare","super rare","majestic","legendary","fabled"],Ir=(e,r,t,a)=>{let i=[];if(!r)i.push(...e);else for(let s of e)switch(r){case">=":{let o=!1;for(let n of ne)o?i.push(n):n===s&&(o=!0,i.push(n));break}case">":{let o=!1;for(let n of ne)o?i.push(n):n===s&&(o=!0);break}case"<=":{let o=!1;for(let n of ne.slice().reverse())o?i.push(n):n===s&&(o=!0,i.push(n));break}case"<":{let o=!1;for(let n of ne.slice().reverse())o?i.push(n):n===s&&(o=!0);break}default:break}return{filterToPropertyMapping:{nestedProperty:"rarity",property:"printings",isArray:!0},isExcluded:t,isOptional:a,isOr:!0,values:i}},He=(e,r,t,a,i)=>{let s=a.map(p=>({hero:p.toLowerCase().replaceAll(b,"")})),o=[],n=[],c=[];for(let p of e){let f=wr.find(({format:T,nicknames:M})=>T===p||!!M&&M.includes(p));if(f)n.push(f.format);else{let T=Rr.find(({hero:M,nicknames:L})=>M===p||!!L&&L.includes(p))||s.find(({hero:M})=>M===p);T&&c.push(T.hero)}}let F=i||"legalFormats";return n.length>0&&o.push({filterToPropertyMapping:{property:F,isArray:!0},values:n,isOr:!0,isExcluded:r,isOptional:t}),c.length>0&&o.push({filterToPropertyMapping:{property:X.LegalHeroes,isArray:!0},values:c,isOr:!0,isExcluded:r,isOptional:t}),o},Br=(e,r,t,a)=>He(e,r,t,a,"bannedFormats"),Te=(e,r,t,a,i,s)=>{let o=[];return Er(t)?o.push(...He(a,e,r,s)):Or(t)?o.push(...Br(a,e,r,s)):Vr(t)&&o.push(Ir(a,i,e,r)),o},$=[{filterToPropertyMapping:{property:"cost",isNumber:!0},isExcluded:!0,values:ce},{filterToPropertyMapping:{property:"specialCost",isString:!0,partialMatch:!0},isExcluded:!0,values:["*","x"]},{filterToPropertyMapping:{property:"types",isArray:!0,partialMatch:!0},isExcluded:!0,values:["equipment","hero","placeholder","token","weapon"]}],W=[{filterToPropertyMapping:{property:"defense",isNumber:!0},isExcluded:!0,values:ce},{filterToPropertyMapping:{property:"specialDefense",isString:!0,partialMatch:!0},isExcluded:!0,values:["*","x"]},{filterToPropertyMapping:{property:"types",isArray:!0,partialMatch:!0},isExcluded:!0,values:["hero","placeholder","token","weapon"]}],le=[{filterToPropertyMapping:{property:"pitch",isNumber:!0},isExcluded:!0,values:ce},{filterToPropertyMapping:{property:"types",isArray:!0,partialMatch:!0},isExcluded:!0,values:["equipment","hero","placeholder","token","weapon"]},{filterToPropertyMapping:{property:"isCardBack",isBoolean:!0},isExcluded:!0,values:["true"]}],_=[{filterToPropertyMapping:{property:"power",isNumber:!0},isExcluded:!0,values:ce},{filterToPropertyMapping:{property:"specialPower",isString:!0,partialMatch:!0},isExcluded:!0,values:["*","x"]},{filterToPropertyMapping:{property:"types",isArray:!0,partialMatch:!0},isExcluded:!0,values:["equipment","hero","placeholder","token"]}],de=[{filterToPropertyMapping:{property:"talents",isArray:!0},isExcluded:!0,values:Object.values(k.Talent).map(e=>e.toLowerCase())}],Lr=E({"!co":$,"-co":$,"!cost":$,"-cost":$,"!color":$,"-color":$,"!b":W,"-b":W,"!block":W,"-block":W,"!d":W,"-d":W,"!def":W,"-def":W,"!defense":W,"-defense":W,"!pitch":le,"-pitch":le,"!p":le,"-p":le,"!attack":_,"-attack":_,"!power":_,"-power":_,"!pwr":_,"-pwr":_,"!pow":_,"-pow":_,"!talents":de,"-talents":de,"!tal":de,"-tal":de}),Me=e=>{let r=[],t=Lr[e];return t&&r.push(...t),r},Nr=["l","legal","hero"],Er=e=>Nr.includes(e),Dr=["banned"],Or=e=>Dr.includes(e),Hr=["r","rarity"],Vr=e=>Hr.includes(e);var O=require("@flesh-and-blood/types"),Fe=[{description:"Attack actions",expanded:["st:attack"],filters:{subtypes:[O.Subtype.Attack]},isCardProperty:!1,shorthands:["AA"]},{description:"Arcane barrier",expanded:['k:"arcane barrier"'],filters:{keywords:[O.Keyword.ArcaneBarrier]},isCardProperty:!1,shorthands:["AB"]},{description:"Attack reactions",expanded:['t:"attack reaction"'],filters:{types:[O.Type.AttackReaction]},isCardProperty:!1,shorthands:["AR"]},{description:"Defense reactions",expanded:['t:"defense reaction"'],filters:{types:[O.Type.DefenseReaction]},isCardProperty:!1,shorthands:["DR"]},{description:"Gain life",expanded:["gain {h}"],filters:{functionalText:"gain {h}"},isCardProperty:!1,shorthands:["Gain life","Gains life"]},{description:"Go again",expanded:['k:"go again"'],filters:{keywords:[O.Keyword.GoAgain]},isCardProperty:!1,shorthands:["GA"]},{description:"Non-attack actions",expanded:["t:action","st:non-attack"],filters:{subtypes:[O.Subtype.NonAttack],types:[O.Type.Action]},isCardProperty:!1,shorthands:["NAA"]},{description:"Plus defense",expanded:["+ {d}"],filters:{functionalText:"+ {d}"},isCardProperty:!1,shorthands:["Pump defense","Pumps defense","Buff defense","Buffs defense"]},{description:"Spellvoid",expanded:['k:"spellvoid"'],filters:{keywords:[O.Keyword.Spellvoid]},isCardProperty:!1,shorthands:["SV"]}],ve=Fe.filter(({shorthands:e})=>e.some(r=>r.includes(" "))).map(e=>({...e,shorthands:e.shorthands.filter(r=>r.includes(" ")).map(r=>r.toLowerCase()).sort((r,t)=>t.length-r.length)})),Ae=Fe.filter(({shorthands:e})=>e.some(r=>!r.includes(" "))).map(e=>({...e,shorthands:e.shorthands.filter(r=>!r.includes(" ")).map(r=>r.toLowerCase()).sort((r,t)=>t.length-r.length)}));var J=e=>Z(e.toLowerCase().trim().replace(b,"")),Z=e=>e.normalize("NFD").replace(/\p{Diacritic}/gu,""),Q=e=>e.replace(me,"");var Y=require("@flesh-and-blood/types");var Ve=new WeakMap,z=Object.freeze([]),Gr=Number.MAX_SAFE_INTEGER,Ge=(e,r)=>{let t=new Map;for(let a of e)for(let i of r(a)||[]){let s=t.get(i);s?s.push(a):t.set(i,[a])}return t},Wr=e=>{let r=new Map;for(let t of e){let a=t.types.includes(Y.Type.Hero)&&!t.isCardBack,i=a?Y.CardRole.Hero:(0,Y.getCardRole)(t);if(a||i!==Y.CardRole.Hero){let o=r.get(i);o?o.push(t):r.set(i,[t])}}return r},Ur=e=>{let r,t,a,i,s,o=()=>{if(!r){let l=new Map,g=new Map,u=[],y=new Map,m=0;for(let R of e){l.set(R.cardIdentifier,R),g.set(R.cardIdentifier,m),m++;let A=J(R.name),B=y.get(A);B?B.push(R):(y.set(A,[R]),u.push(A))}r={cardByCardIdentifier:l,corpusPositionByCardIdentifier:g,cleanedNames:u,pitchCycleByCleanedName:y}}return r},n=l=>{let{corpusPositionByCardIdentifier:g}=o(),u=({cardIdentifier:y})=>g.get(y)??Gr;return[...l].sort((y,m)=>u(y)-u(m))},c=l=>o().cardByCardIdentifier.get(l),F=l=>{let{cardByCardIdentifier:g}=o(),u=[];for(let y of l||[]){let m=g.get(y);m&&u.push(m)}return n(u)},p=l=>{let g=new Map;return u=>{let y=g.get(u);if(!y){let m=c(u),R=F(m&&l(m)),A=R.length>0;y=A?R:z,A&&g.set(u,y)}return y}},f=l=>{let{pitchCycleByCleanedName:g}=o(),u=c(l);return u?g.get(J(u.name))??z:z},T=l=>{let{cleanedNames:g,pitchCycleByCleanedName:u}=o(),y=J(l),m=u.get(y);if(!m&&y.length>0){let A=g.find(B=>B.includes(y));A&&(m=u.get(A))}return m??z},M=l=>{let{pitchCycleByCleanedName:g}=o();return g.get(J(l))??z},L=()=>{if(!s){let l=new Set;for(let g of e)for(let u of g.artists)l.add(u);s=[...l].sort((g,u)=>g.localeCompare(u,"en",{sensitivity:"base"}))}return s},H=p(({oppositeSideCardIdentifiers:l})=>l),U=p(({referencedCards:l})=>l),P=l=>(t||(t=Ge(e,({referencedCards:g})=>g)),t.get(l)??z),S=p(({createdExtras:l})=>l);return{cards:e,getCard:c,getPitchCycle:f,getCardsByName:T,getCardsByExactName:M,getArtists:L,getOppositeSide:H,getReferences:U,getReferencedBy:P,getCreates:S,getCreatedBy:l=>(a||(a=Ge(e,({createdExtras:g})=>g)),a.get(l)??z),getCreatedClosure:l=>{let g=new Map,u=new Set,y=[...l];for(let m of y)if(!u.has(m)){u.add(m);for(let A of S(m))g.set(A.cardIdentifier,A),y.push(A.cardIdentifier)}return n([...g.values()])},getByRole:l=>(i||(i=Wr(e)),i.get(l)??z),getCardsInCorpusOrder:n}},xe=e=>{let r=Ve.get(e);return r||(r=Ur(e),Ve.set(e,r)),r},Pe=(e,r)=>e.getPitchCycle(r.cardIdentifier),pe=(e,r)=>e.getCardsByName(r),We=(e,r)=>{let t=new Map;for(let a of r)for(let i of Pe(e,a))t.set(i.cardIdentifier,i);return e.getCardsInCorpusOrder([...t.values()])},ue=(e,r)=>{let t=[];for(let a of Pe(e,r))t.push(...e.getReferencedBy(a.cardIdentifier));return We(e,t)},fe=(e,r)=>{let t=[];for(let a of Pe(e,r))t.push(...e.getReferences(a.cardIdentifier));return We(e,t)};var cr=[">=",">","<=","<"],pr=["!","-"],K="n/a",Kr={property:"arcane",specialProperty:"specialArcane",isNumber:!0,partialMatch:!0},Se={property:"artists",isArray:!0,partialMatch:!0},Ue={property:K,isMeta:!0},Ke={property:"bonds",isArray:!0},jr={property:"cardIdentifier",isString:!0,isNormalized:!0},je=(e,{isAnd:r,isExcluded:t,isOptional:a,modifier:i})=>({filterToPropertyMapping:jr,values:[...e],valuesSet:e,isAnd:r,isOr:!0,modifier:i,isExcluded:t,isOptional:a}),_r={property:K},_e={property:"classes",isArray:!0,partialMatch:!0},ze={property:"cost",specialProperty:"specialCost",isNumber:!0,partialMatch:!0},ee={property:"defense",specialProperty:"specialDefense",isNumber:!0},qe={property:"flows",isArray:!0},Ye={nestedProperty:"foiling",property:"printings",isArray:!0},$e={property:"fusions",isArray:!0},Je={property:"intellect",isNumber:!0},Qe={property:"keywords",isArray:!0},we={property:K,isMeta:!0},Xe={property:"life",specialProperty:"specialLife",isNumber:!0},Ie={property:"meta",isArray:!0},Ze={property:"name",isString:!0,partialMatch:!0},ke={property:"pitch",isNumber:!0},er={property:"firstReleaseDate",isDate:!0},ge={property:"power",specialProperty:"specialPower",isNumber:!0},zr={property:"setIdentifiers",isArray:!0,partialMatch:!0},rr={property:K,isMeta:!0},qr={property:K},Yr={property:K},tr={property:"sets",isArray:!0,partialMatch:!0},Re={property:"shorthands",isArray:!0,partialMatch:!0},ye={property:"specializations",isArray:!0,partialMatch:!0},ar={property:"subtypes",isArray:!0},ir={property:"types",isArray:!0},sr={property:"talents",isArray:!0},$r={property:"functionalText",hasMarkup:!0,isString:!0,partialMatch:!0},Jr={property:"traits",isArray:!0,partialMatch:!0},Qr={property:"typeText",isString:!0,partialMatch:!0},he={nestedProperty:"treatments",property:"printings",isArray:!0,isNestedPropertyArray:!0},Xr={property:"firstReleaseDate",isString:!0,partialMatch:!0},ur={arcane:Kr,a:Se,artist:Se,art:Se,attack:ge,b:ee,block:ee,banned:Ue,bond:Ke,bonds:Ke,c:_e,class:_e,chain:_r,co:ze,cost:ze,color:ke,d:ee,def:ee,defense:ee,flow:qe,flows:qe,f:$e,fusion:$e,foil:Ye,foiling:Ye,i:Je,intellect:Je,is:Ie,k:Qe,keyword:Qe,l:we,legal:we,hero:we,li:Xe,life:Xe,meta:Ie,n:Ze,name:Ze,p:ke,pitch:ke,pwr:ge,pow:ge,power:ge,print:zr,r:rr,rarity:rr,referencedby:qr,references:Yr,rf:Ue,s:tr,set:tr,short:Re,shorthand:Re,shorthands:Re,sp:ye,spec:ye,specialization:ye,specializations:ye,st:ar,subtype:ar,t:ir,type:ir,tal:sr,talent:sr,text:$r,trait:Jr,treat:he,treatment:he,var:he,variation:he,x:Qr,year:Xr},fr=E(ur),Zr=[{text:d.Release.ClassicBattlesRhinarDorinthea.toLowerCase(),override:d.Release.ClassicBattlesRhinarDorinthea.toLowerCase().replaceAll(b,"")}],et=e=>{let r=[],t=e.replaceAll("\u201D",'"');for(let{text:i,override:s}of Zr)t.includes(i)&&(t=t.replace(i,s));if(ie(t)?.card)r.push(t);else{let i=t.split(/[ ]+/),s="",o=0;for(let n of i)o===2&&(r.push(s.trim().replaceAll('"',"")),s="",o=0),o<2&&n.split('"').length===2?(s+=" "+n,o++):o===0&&s===""?r.push(n):o===1&&(s+=" "+n);o===2&&(r.push(s.trim().replaceAll('"',"")),s="",o=0)}return r},rt=20,Le=(e,r,t=[],a=[],i=dt())=>{let s=e.trim().toLowerCase();for(let{expanded:P,shorthands:S}of ve)for(let h of S)if(s.includes(h)){s=s.replace(h,P.join(" "));break}for(let[P,S]of Object.entries(d.setToSetIdentifierMappings))s.includes(P.toLowerCase())&&(s=s.replace(P.toLowerCase(),S[0]));let o=et(s),n=[];for(let P of o){let S=Ae.find(({shorthands:h})=>h.includes(P));S&&!S.isCardProperty?n.push(...S.expanded):n.push(P)}let c=[],F=[],p=[],f=[],T=!1,M=[],L=[],H=[],U=[];for(let P of n)if(bt(P)){let[S,h]=P.split(":"),{modifier:D,values:C,isAnd:l,isOr:g}=Ct(h),{filterKey:u,isExcluded:y,isOptional:m,isMeta:R}=mt(S),A=!1;if(R){if(["rarity","r"].includes(u)){let B=ht(C);y||(L=[...B]),C=B.map(x=>x.toLowerCase())}["legal","l","hero"].includes(u),c.push(...Te(y,m,u,C,D,t))}else{if(["chain"].includes(u)){let x=new Set,I=[],V=new Set,G=w=>{x.add(w.cardIdentifier),V.has(w.name)||(V.add(w.name),I.push(w))},q=w=>{w.types.includes(d.Type.Hero)||G(w)};for(let w of C)if(w)for(let N of pe(r,w))G(N);let j=0;for(let w of I){if(j>rt)break;for(let Ce of fe(r,w))q(Ce);if(j===0)for(let Ce of ue(r,w))q(Ce);j++}c.push(je(x,{isAnd:l,isExcluded:y,isOptional:m,modifier:D})),A=!0}else if(["referencedby","references"].includes(u)){let x=["referencedby"].includes(u),I=new Set;for(let V of C)if(V)for(let G of pe(r,V)){let q=x?fe(r,G):ue(r,G);for(let j of q)I.add(j.cardIdentifier)}c.push(je(I,{isAnd:l,isExcluded:y,isOptional:m,modifier:D})),A=!0}else if(["art","artist"].includes(u))F=C;else if(["print","prints","printing","printings"].includes(u))M=C;else if(["is","meta"].includes(u)){let x=[],I=[],V=[],G=[];for(let N of C)ot.includes(N)?x.push(N):nt.includes(N)?I.push(N):lt.includes(N)?V.push(N):G.push(N);x.length>0&&(c.push({filterToPropertyMapping:Ie,values:[d.Meta.Reprint.toLowerCase().replaceAll(b,"")],isAnd:l,isOr:g,isExcluded:!y,isOptional:m}),A=G.length===0);let q=I.length>0;q&&c.push({filterToPropertyMapping:er,values:[i],isAnd:l,isOr:g,isExcluded:y,isOptional:m});let j=V.length>0;j&&c.push({filterToPropertyMapping:er,values:[i],isAnd:l,isOr:g,isExcluded:!y,isOptional:m}),(q||j)&&(A=G.length===0);let w=pt(G);C=w.map(N=>N.toLowerCase().replaceAll(b,"")),w.includes(d.Meta.Expansion)&&!y&&(T=!0)}else["foiling","foil"].includes(u)?(f=ut(C),C=f.map(x=>x.toLowerCase())):["treat","treatment","var","variation"].includes(u)?(U=yt(C),C=U.map(x=>x.toLowerCase())):["set","s"].includes(u)?(H=tt(C,a),C=H.map(x=>x.toLowerCase().replaceAll(b,""))):["pitch","p","color"].includes(u)&&(C=st(C));let B=fr[u];B&&!A&&c.push({filterToPropertyMapping:B,values:B.hasMarkup?C.map(x=>Q(x)):C,isAnd:l,isOr:g,modifier:D,isExcluded:y,isOptional:m})}}else if(P){let S=ie(P)?.card,h=Me(P);S?p.push(`"${S.toLowerCase().replace(b,"")}"`):h&&h.length>0?c.push(...h):p.push(P.replace(b,""))}return{appliedFilters:c,attributes:{artists:F,foilings:f,isExpansionSlot:T,prints:M,rarities:L,releases:H,treatments:U},keywords:p}},tt=(e,r=[])=>{let t=[];for(let a of e)t.push(...at(a,r));return t},at=(e,r=[])=>{let t=[],a=Object.values(d.Release).find(i=>i.toLowerCase().replaceAll(b,"")===e);if(a&&t.push(a),t.length===0){let i=oe[e];i&&t.push(i)}if(t.length===0){let i=Object.values(d.Release).filter(s=>s.toLowerCase().includes(e));i.length>0&&t.push(...i)}if(t.length===0){let i=r.find(s=>s.toLowerCase().replaceAll(b,"")===e);i&&t.push(i)}return t},it=E({purple:4,blue:3,yellow:2,red:1,white:0}),st=e=>{let r=[];for(let t of e){let a=it[t];a===void 0?r.push(t):r.push(a.toString())}return r},ot=["unique"],nt=["preview","spoiler","unreleased"],lt=["released"],dt=()=>{let e=new Date,r=`${e.getMonth()+1}`.padStart(2,"0"),t=`${e.getDate()}`.padStart(2,"0");return`${e.getFullYear()}-${r}-${t}`},ct=E({dual:d.Meta.DualClass,exp:d.Meta.Expansion,expansion:d.Meta.Expansion,rainbow:d.Meta.Rainbow,reprint:d.Meta.Reprint,reprints:d.Meta.Reprint}),pt=e=>{let r=[];for(let t of e){let a=ct[t];a&&r.push(a)}if(e.length>0&&r.length===0){for(let t of Object.values(d.Meta))for(let a of e)if(t.toLowerCase().includes(a)){r.push(t);break}}return r},or=E({r:d.Foiling.Rainbow,rf:d.Foiling.Rainbow,rainbow:d.Foiling.Rainbow,c:d.Foiling.Cold,cf:d.Foiling.Cold,cold:d.Foiling.Cold,g:d.Foiling.Gold,gf:d.Foiling.Gold,gold:d.Foiling.Gold}),ut=e=>{let r=[];for(let t of e)or[t]&&r.push(or[t]);return r},ft=E({...Object.values(d.Treatment).reduce((e,r)=>(e[r.toLowerCase()]=r,e),{}),aa:d.Treatment.AA,alt:d.Treatment.AA,"alt art":d.Treatment.AA,ab:d.Treatment.AB,"alt border":d.Treatment.AB,at:d.Treatment.AT,"alt text":d.Treatment.AT,ea:d.Treatment.EA,extended:d.Treatment.EA,"extended art":d.Treatment.EA,fa:d.Treatment.FA,full:d.Treatment.FA,"full art":d.Treatment.FA}),gt=E(d.Treatment),yt=e=>{let r=[];for(let t of e){let a=ft[t],i=gt[t.toUpperCase()];a?r.push(a):i&&r.push(i)}return r},Be=E({b:d.Rarity.Basic,c:d.Rarity.Common,f:d.Rarity.Fabled,l:d.Rarity.Legendary,m:d.Rarity.Majestic,p:d.Rarity.Promo,r:d.Rarity.Rare,s:d.Rarity.SuperRare,t:d.Rarity.Token,v:d.Rarity.Marvel}),ht=e=>{let r=[];for(let t of e)Be[t]?r.push(Be[t]):r.push(t);return r},Ct=e=>{let r=[],t,a,i=cr.find(s=>e.includes(s));if(i){let[,s]=e.split(i);nr(s)?(t=!0,r.push(...s.trim().split("+").map(o=>o.replace(b,"")))):lr(s)?(a=!0,r.push(...s.trim().split(",").map(o=>o.replace(b,"")))):r.push(s.trim().replace(b,""))}else nr(e)?(t=!0,r.push(...e.trim().split("+").map(s=>s.replace(b,"")))):lr(e)?(a=!0,r.push(...e.trim().split(",").map(s=>s.replace(b,"")))):e.startsWith('"')&&e.endsWith('"')?r.push(e.trim().replaceAll('"',"").replace(b,"")):r.push(e.trim().replace(b,""));return{modifier:i,values:r,isAnd:t,isOr:a}},mt=e=>{let r=Tt(e);if(r){let[,t]=e.split(r);return{filterKey:t,isExcluded:!0,isOptional:!1,isMeta:dr(t)}}else return{filterKey:e,isExcluded:!1,isOptional:!1,isMeta:dr(e)}},bt=e=>e.indexOf(":")>=0,nr=e=>e.indexOf("+")>=0,lr=e=>e.indexOf(",")>=0,dr=e=>!!fr[e]?.isMeta,Tt=e=>pr.find(r=>e.includes(r))?.slice(0,1);var v=require("@flesh-and-blood/types"),gr={artists:["Hoodwill"],cardIdentifier:"fangs-a-lot-blue",classes:[v.Class.Generic],defaultImage:"FNG000",firstReleaseDate:"2022-06-02",functionalText:"If Fangs A Lot is put into your banished zone from your graveyard, instead put it into your hand.",legalFormats:[],legalHeroes:[v.Hero.Kayo,v.Hero.Levia,v.Hero.Rhinar],printings:[{artists:["Hoodwill"],identifier:"FNG000",image:"FNG000",print:"FNG000",rarity:v.Rarity.Rare,set:v.Release.Promos},{artists:["Hoodwill"],identifier:"FNG000",image:"FNG000_Marvel",print:`FNG000-${v.Treatment.FA}`,rarity:v.Rarity.Marvel,set:v.Release.Promos,treatment:v.Treatment.FA}],name:"Fangs A Lot",rarities:[v.Rarity.Rare,v.Rarity.Marvel],rarity:v.Rarity.Rare,sets:[v.Release.Promos],setIdentifiers:["FNG000"],specialImage:"FNG000_Marvel",subtypes:[v.Subtype.Attack],types:[v.Type.Action],typeText:"Generic Action - Attack"},yr=[{keyword:gr.name.toLowerCase(),card:gr}];var Mt={getFn:(e,r)=>{let t=Ee.default.config.getFn(e,r),a=t;if(Array.isArray(t))a=t.map(i=>Z(i.replace(b,"")));else if(t){let i=Z(t).replace(b,"");a=r.includes("functionalText")?Q(i):i}return a},ignoreLocation:!0,includeScore:!0,keys:[{name:"name",weight:10},{name:"functionalText",weight:6},{name:"shorthands",weight:4},{name:"setIdentifiers",weight:2},{name:"traits",weight:4},{name:"typeText",weight:6}],threshold:.15,useExtendedSearch:!0},Ne=class{constructor(r,t=[],a=[],i=!1){this.getFuse=()=>(this.fuse||(this.fuse=new Ee.default(this.cards,Mt)),this.fuse);this.log=(r,...t)=>{this.debug&&console.log(r,...t)};this.search=(r,t)=>{let a,{appliedFilters:i,attributes:s,keywords:o}=Le(r,this.index,this.additionalHeroes,this.additionalSets),n=o.join(" "),c=t?yr.filter(h=>h.keyword===n):[];if(c.length>0?a=c.map(({card:h})=>h):o.length?a=this.getFuse().search(n).map(h=>h.item):a=[...this.cards],i.length&&(a=a.filter(h=>h&&Cr(h,i))),o.length===0){let h="";if(s.releases.length===1){let l=Oe[s.releases[0]];l?.length&&(h=l[0].toUpperCase())}if(!h&&s.prints.length===1){let l=s.prints[0];oe[l]&&(h=l.toUpperCase())}h?a.sort((l,g)=>{let u=l.setIdentifiers.find(m=>m.includes(h))?.replace(h,""),y=g.setIdentifiers.find(m=>m.includes(h))?.replace(h,"");return u&&y?u.localeCompare(y):-1}):a.sort((l,g)=>l.name===g.name?`${l.pitch}`.localeCompare(`${g.pitch}`):l.name.localeCompare(g.name))}else{let h=[],D=[],C=o.map(l=>l.toLowerCase().replace(b,"")).join(" ");for(let l of a)l.name.toLowerCase().replace(b,"")===C?h.push(l):D.push(l);a=[...h,...D]}let F=[],{artists:p,isExpansionSlot:f,foilings:T,prints:M,rarities:L,releases:H,treatments:U}=s;(p.length>0||f||T.length>0||M.length>0||L.length>0||H.length>0||U.length>0)&&(F=a.map(h=>{let D=h.printings.filter(C=>{let l=!!C.image,g=p.length===0||p.some(I=>C.artists.find(V=>V.replace(b,"").toLowerCase().includes(I))),u=!f||f===C.isExpansionSlot,y=T.length===0||!!C.foiling&&T.includes(C.foiling),m=M.length===0||M.some(I=>C.identifier.includes(I.toUpperCase())),R=L.length===0||L.includes(C.rarity),A=H.length===0||H.includes(C.set),B=U.length===0||C.treatments?.some(I=>U.includes(I));return l&&g&&u&&y&&m&&R&&A&&B});return{...h,matchingPrintings:D}}));let S=F.length>0?F:a;return{appliedFilters:i,attributes:s,keywords:o,searchResults:S}};let s=Array.isArray(t)?{additionalHeroes:t,additionalSets:a,debug:i}:t;this.additionalHeroes=s.additionalHeroes||[],this.additionalSets=s.additionalSets||[],this.cards=[...r],this.debug=s.debug||!1,this.index=s.index||xe(r)}},hr=Ne,Cr=(e,r)=>{let t=!0,a=!1;for(let i of r){let s=i.isOptional,{isNumber:o,isString:n,isArray:c,isBoolean:F,isDate:p}=i.filterToPropertyMapping;if(o){let f=Ft(e,i);s?f&&(a=!0):t=t&&f}else if(n){let f=vt(e,i);s?f&&(a=!0):t=t&&f}else if(c){let f=At(e,i,r);s?f&&(a=!0):t=t&&f}else if(F){let f=xt(e,i);s?f&&(a=!0):t=t&&f}else if(p){let f=Pt(e,i);s?f&&(a=!0):t=t&&f}}return t},Ft=(e,r)=>{if(te(r,e)){let{values:t,modifier:a,isExcluded:i,filterToPropertyMapping:{partialMatch:s}}=r,o=re(e,r);if(o!=null&&!isNaN(o))if(o=parseInt(o),a)switch(a){case">=":{let n=t?.some(c=>o>=parseInt(c));return i?!n:n}case">":{let n=t?.some(c=>o>parseInt(c));return i?!n:n}case"<=":{let n=t?.some(c=>o<=parseInt(c));return i?!n:n}case"<":{let n=t?.some(c=>o<parseInt(c));return i?!n:n}default:return!1}else{let n=t?.some(c=>o===parseInt(c));return i?!n:n}else{let n=wt(e,r)?.toLowerCase(),c=s?t?.some(F=>n?.includes(F)):t?.some(F=>n===F);return i?!c:c}}else return!0},vt=(e,r)=>{if(te(r,e)){let{values:t,valuesSet:a,isAnd:i,isExcluded:s,filterToPropertyMapping:{hasMarkup:o,isNormalized:n,partialMatch:c}}=r,F=re(e,r),p=n?F:F?.replaceAll(b,"").toLowerCase(),f=o&&p?Q(p):p;if(c){let T=i?t?.every(M=>f?.includes(M)):t?.some(M=>f?.includes(M));return s?!T:T}else{let T;return i?T=t?.every(M=>f===M):a?T=a.has(f):T=t?.some(M=>f===M),s?!T:T}}else return!0},At=(e,r,t)=>{if(te(r,e)){let{values:a,isAnd:i,isExcluded:s,filterToPropertyMapping:{partialMatch:o}}=r,n=St(e,r,t).map(c=>c?.replaceAll(b,""));if(o){let c=i?a.every(p=>n?.some(f=>f?.toLowerCase().includes(p))):a.some(p=>n?.some(f=>f?.toLowerCase().includes(p))),F=n.length===0;return s?!c||F:c}else{let c=i?a.every(F=>n?.some(p=>p?.toLowerCase()===F)):a.some(F=>n?.some(p=>p?.toLowerCase()===F));return s?!c:c}}else return!0},xt=(e,r)=>{if(te(r,e)){let{isExcluded:t}=r,a=re(e,r);return t?!a:a}else return!0},Pt=(e,r)=>{if(te(r,e)){let{values:t,isExcluded:a}=r,i=re(e,r),s=t?.some(o=>i>o);return a?!s:s}else return!0},re=(e,r)=>{let{filterToPropertyMapping:{property:t}}=r,a;return t!==K&&(a=e[t]),a},St=(e,r,t)=>{let{filterToPropertyMapping:{isNestedPropertyArray:a,nestedProperty:i}}=r,s=[],o=Object.keys(e.legalOverrides||{}).length>0,n=r.filterToPropertyMapping.property===X.LegalHeroes,c=t.find(({filterToPropertyMapping:p})=>p.property===X.LegalFormats);if(o&&n&&!!c){let p=new Set;for(let{format:f,heroes:T}of e.legalOverrides||[])if(c.values.includes(f.toLowerCase()))for(let M of T)p.add(M);s=Array.from(p)}if(s.length===0)if(i){let p=new Set;for(let f of e.printings){let T=f[i];if(a){if(Array.isArray(T))for(let M of T)p.add(M)}else T&&typeof T=="string"&&p.add(T)}s=Array.from(p)}else{let p=re(e,r);if(Array.isArray(p))for(let f of p)typeof f=="string"&&s.push(f)}return s},wt=(e,r)=>{let{filterToPropertyMapping:{specialProperty:t}}=r,a;return t&&(a=e[t]),a},te=({cardTypes:e},{types:r,subtypes:t})=>!e||e?.some(a=>r.map(i=>i.toLowerCase()).includes(a.toLowerCase())||t.map(i=>i.toLowerCase()).includes(a.toLowerCase()));var kt=(e,r)=>{let t=[];if(e)for(let a of r){let i=a.name===e.name,s=a.cardIdentifier!==e.cardIdentifier,o=a.pitch!==e.pitch;i&&s&&o&&t.push(a)}return t},Rt=(e,r)=>{let t=new Set(e?.referencedCards),a=[];for(let i of r)t.has(i.cardIdentifier)&&a.push(i);return a},It=e=>{let r=new Map;for(let t of e)for(let a of t.referencedCards||[]){let i=r.get(a);i?i.push(t):r.set(a,[t])}return r},Bt=(e,r)=>{let t=new Set;for(let i of e)for(let s of i.createdExtras||[])t.add(s);let a=[];for(let i of r)t.has(i.cardIdentifier)&&a.push(i);return a};0&&(module.exports={FilterProperty,MARKUP,NO_CARD_PROPERTY,PUNCTUATION,RARITY_VALUES_MAPPING,abbreviations,availableExclusions,availableModifiers,filterCard,filtersToCardPropertyMappings,getAbbreviation,getAbbreviationByCard,getCardsByName,getCardsByReferencedCardIdentifier,getCardsReferencedBy,getCardsReferencing,getCatalogueIndex,getCleanText,getExcludedMetaFilters,getKeywordsAndAppliedFiltersFromText,getMetaFilters,getNormalizedText,getOtherPitches,getReferencedCards,getTextWithoutMarkup,getTokensReferencedByCards,multiWordShorthands,shorthands,singleWordShorthands});
@@ -0,0 +1,21 @@
1
+ import { Release } from "@flesh-and-blood/types";
2
+ /**
3
+ * Copies a lookup table onto a null prototype so that a key can only ever match
4
+ * a real entry. Keys here come from raw search text, and a plain object literal
5
+ * answers `constructor`, `__proto__` and the rest of `Object.prototype` with an
6
+ * inherited member, handing the caller a function where it expects a value.
7
+ *
8
+ * Deliberately not re-exported from the package barrel: it guards an internal
9
+ * invariant rather than serving consumers.
10
+ */
11
+ export declare const getLookupWithoutInheritedKeys: <T>(entries: {
12
+ [key: string]: T;
13
+ }) => {
14
+ [key: string]: T;
15
+ };
16
+ export declare const releasesBySetIdentifier: {
17
+ [key: string]: Release;
18
+ };
19
+ export declare const setIdentifiersByRelease: {
20
+ [key: string]: string[] | undefined;
21
+ };
@@ -0,0 +1,14 @@
1
+ import {
2
+ setIdentifierToSetMappings,
3
+ setToSetIdentifierMappings
4
+ } from "@flesh-and-blood/types";
5
+ const getLookupWithoutInheritedKeys = (entries) => Object.assign(/* @__PURE__ */ Object.create(null), entries);
6
+ const releasesBySetIdentifier = getLookupWithoutInheritedKeys(
7
+ setIdentifierToSetMappings
8
+ );
9
+ const setIdentifiersByRelease = getLookupWithoutInheritedKeys(setToSetIdentifierMappings);
10
+ export {
11
+ getLookupWithoutInheritedKeys,
12
+ releasesBySetIdentifier,
13
+ setIdentifiersByRelease
14
+ };
@@ -1,9 +1,10 @@
1
1
  import { Hero } from "@flesh-and-blood/types";
2
- export declare enum FilterProperty {
3
- BannedFormats = "bannedFormats",
4
- LegalFormats = "legalFormats",
5
- LegalHeroes = "legalHeroes"
6
- }
2
+ import type { FilterToPropertyMapping, Modifier } from "./filters.js";
3
+ export declare const FilterProperty: {
4
+ readonly BannedFormats: "bannedFormats";
5
+ readonly LegalFormats: "legalFormats";
6
+ readonly LegalHeroes: "legalHeroes";
7
+ };
7
8
  interface AppliedFilter {
8
9
  filterToPropertyMapping: FilterToPropertyMapping;
9
10
  values: string[];
@@ -15,21 +16,6 @@ interface AppliedFilter {
15
16
  modifier?: Modifier;
16
17
  cardTypes?: string[];
17
18
  }
18
- interface FilterToPropertyMapping {
19
- nestedProperty?: string;
20
- property: string;
21
- exclusion?: Exclusion;
22
- isArray?: boolean;
23
- isNumber?: boolean;
24
- isString?: boolean;
25
- isBoolean?: boolean;
26
- isMeta?: boolean;
27
- modifier?: Modifier;
28
- partialMatch?: boolean;
29
- specialProperty?: string;
30
- }
31
- type Exclusion = "!" | "-";
32
- type Modifier = ">=" | ">" | "<=" | "<";
33
19
  export declare const getMetaFilters: (isExcluded: boolean, isOptional: boolean, filterKey: string, values: string[], modifier: string, additionalHeroes: Hero[]) => AppliedFilter[];
34
20
  export declare const getExcludedMetaFilters: (filterKey: string) => AppliedFilter[];
35
21
  export {};
@@ -1,11 +1,11 @@
1
1
  import { Format, Hero, Talent } from "@flesh-and-blood/types";
2
2
  import { PUNCTUATION } from "./constants.js";
3
- var FilterProperty = /* @__PURE__ */ ((FilterProperty2) => {
4
- FilterProperty2["BannedFormats"] = "bannedFormats";
5
- FilterProperty2["LegalFormats"] = "legalFormats";
6
- FilterProperty2["LegalHeroes"] = "legalHeroes";
7
- return FilterProperty2;
8
- })(FilterProperty || {});
3
+ import { getLookupWithoutInheritedKeys } from "./lookups.js";
4
+ const FilterProperty = {
5
+ BannedFormats: "bannedFormats",
6
+ LegalFormats: "legalFormats",
7
+ LegalHeroes: "legalHeroes"
8
+ };
9
9
  const oneToFifty = Array.from(Array(50).keys()).map((value) => `${value}`);
10
10
  const nicknameFormatMappings = [
11
11
  {
@@ -188,7 +188,7 @@ const getLegalFilters = (values, isExcluded, isOptional, additionalHeroes, filte
188
188
  if (heroes.length > 0) {
189
189
  filters.push({
190
190
  filterToPropertyMapping: {
191
- property: "legalHeroes" /* LegalHeroes */,
191
+ property: FilterProperty.LegalHeroes,
192
192
  isArray: true
193
193
  },
194
194
  values: heroes,
@@ -344,7 +344,7 @@ const noTalents = [
344
344
  values: Object.values(Talent).map((talent) => talent.toLowerCase())
345
345
  }
346
346
  ];
347
- const excludedFilters = {
347
+ const excludedFilters = getLookupWithoutInheritedKeys({
348
348
  "!co": noCost,
349
349
  "-co": noCost,
350
350
  "!cost": noCost,
@@ -377,7 +377,7 @@ const excludedFilters = {
377
377
  "-talents": noTalents,
378
378
  "!tal": noTalents,
379
379
  "-tal": noTalents
380
- };
380
+ });
381
381
  const getExcludedMetaFilters = (filterKey) => {
382
382
  const filters = [];
383
383
  const matchingFilters = excludedFilters[filterKey];
package/dist/search.d.ts CHANGED
@@ -40,7 +40,7 @@ declare class Search {
40
40
  constructor(cards: DoubleSidedCard[], options?: SearchOptions);
41
41
  constructor(cards: DoubleSidedCard[], additionalHeroes?: Hero[], additionalSets?: Release[], debug?: boolean);
42
42
  private getFuse;
43
- log: (message?: any, ...optionalParams: any[]) => void;
43
+ log: (message?: unknown, ...optionalParams: unknown[]) => void;
44
44
  search: (text: string, includeMemes?: boolean) => SearchResults;
45
45
  }
46
46
  export default Search;
package/dist/search.js CHANGED
@@ -1,14 +1,12 @@
1
- import {
2
- setIdentifierToSetMappings,
3
- setToSetIdentifierMappings
4
- } from "@flesh-and-blood/types";
5
1
  import Fuse from "fuse.js";
6
2
  import { PUNCTUATION } from "./constants.js";
7
3
  import {
8
- getKeywordsAndAppliedFiltersFromText
4
+ getKeywordsAndAppliedFiltersFromText,
5
+ NO_CARD_PROPERTY
9
6
  } from "./filters.js";
10
7
  import { memes } from "./memes.js";
11
8
  import { getNormalizedText, getTextWithoutMarkup } from "./helpers.js";
9
+ import { releasesBySetIdentifier, setIdentifiersByRelease } from "./lookups.js";
12
10
  import { FilterProperty } from "./metaFilters.js";
13
11
  import { getCatalogueIndex } from "./searchIndex.js";
14
12
  const searchOptions = {
@@ -76,33 +74,25 @@ class Search {
76
74
  );
77
75
  }
78
76
  if (keywords.length === 0) {
79
- let setIdentifieToSortBy = "";
77
+ let setIdentifierToSortBy = "";
80
78
  const shouldSortByRelease = attributes.releases.length === 1;
81
79
  if (shouldSortByRelease) {
82
- try {
83
- const setToSort = attributes.releases[0];
84
- const matchingSetIdentifiers = setToSetIdentifierMappings[setToSort];
85
- setIdentifieToSortBy = matchingSetIdentifiers[0].toUpperCase();
86
- } catch (e) {
87
- console.error(`Error getting set identifier from search`, e);
80
+ const matchingSetIdentifiers = setIdentifiersByRelease[attributes.releases[0]];
81
+ if (matchingSetIdentifiers?.length) {
82
+ setIdentifierToSortBy = matchingSetIdentifiers[0].toUpperCase();
88
83
  }
89
84
  }
90
- const shouldSortByPrint = !setIdentifieToSortBy && attributes.prints.length === 1;
85
+ const shouldSortByPrint = !setIdentifierToSortBy && attributes.prints.length === 1;
91
86
  if (shouldSortByPrint) {
92
- try {
93
- const setToSort = attributes.prints[0];
94
- const matchingSetIdentifiers = setIdentifierToSetMappings[setToSort];
95
- if (matchingSetIdentifiers) {
96
- setIdentifieToSortBy = setToSort.toUpperCase();
97
- }
98
- } catch (e) {
99
- console.error(`Error getting set identifier from search`, e);
87
+ const setToSort = attributes.prints[0];
88
+ if (releasesBySetIdentifier[setToSort]) {
89
+ setIdentifierToSortBy = setToSort.toUpperCase();
100
90
  }
101
91
  }
102
- if (setIdentifieToSortBy) {
92
+ if (setIdentifierToSortBy) {
103
93
  results.sort((c1, c2) => {
104
- const c1SetNumber = c1.setIdentifiers.find((identifier) => identifier.includes(setIdentifieToSortBy))?.replace(setIdentifieToSortBy, "");
105
- const c2SetNumber = c2.setIdentifiers.find((identifier) => identifier.includes(setIdentifieToSortBy))?.replace(setIdentifieToSortBy, "");
94
+ const c1SetNumber = c1.setIdentifiers.find((identifier) => identifier.includes(setIdentifierToSortBy))?.replace(setIdentifierToSortBy, "");
95
+ const c2SetNumber = c2.setIdentifiers.find((identifier) => identifier.includes(setIdentifierToSortBy))?.replace(setIdentifierToSortBy, "");
106
96
  return c1SetNumber && c2SetNumber ? c1SetNumber.localeCompare(c2SetNumber) : -1;
107
97
  });
108
98
  } else {
@@ -123,7 +113,7 @@ class Search {
123
113
  }
124
114
  results = [...nameMatches, ...nonMatches];
125
115
  }
126
- let searchResultsWithMatchingPrinting;
116
+ let searchResultsWithMatchingPrinting = [];
127
117
  const {
128
118
  artists,
129
119
  isExpansionSlot,
@@ -144,7 +134,7 @@ class Search {
144
134
  )
145
135
  );
146
136
  const matchesExpansionSlot = !isExpansionSlot || isExpansionSlot === printing.isExpansionSlot;
147
- const matchesFoiling = foilings.length === 0 || foilings.includes(printing.foiling);
137
+ const matchesFoiling = foilings.length === 0 || !!printing.foiling && foilings.includes(printing.foiling);
148
138
  const matchesPrint = prints.length === 0 || prints.some(
149
139
  (print) => printing.identifier.includes(print.toUpperCase())
150
140
  );
@@ -162,7 +152,7 @@ class Search {
162
152
  };
163
153
  });
164
154
  }
165
- const searchResults = searchResultsWithMatchingPrinting?.length > 0 ? searchResultsWithMatchingPrinting : results;
155
+ const searchResults = searchResultsWithMatchingPrinting.length > 0 ? searchResultsWithMatchingPrinting : results;
166
156
  return {
167
157
  appliedFilters,
168
158
  attributes,
@@ -394,18 +384,19 @@ const getDoesCardMatchDateFilter = (card, filter) => {
394
384
  }
395
385
  };
396
386
  const getCardValue = (card, appliedFilter) => {
397
- const { filterToPropertyMapping } = appliedFilter;
398
- return card[filterToPropertyMapping.property];
387
+ const {
388
+ filterToPropertyMapping: { property }
389
+ } = appliedFilter;
390
+ let cardValue = void 0;
391
+ if (property !== NO_CARD_PROPERTY) {
392
+ cardValue = card[property];
393
+ }
394
+ return cardValue;
399
395
  };
400
396
  const getCardValues = (card, filter, filters) => {
401
397
  const {
402
- filterToPropertyMapping: {
403
- isNestedPropertyArray,
404
- nestedProperty,
405
- property
406
- }
398
+ filterToPropertyMapping: { isNestedPropertyArray, nestedProperty }
407
399
  } = filter;
408
- const propertyValues = card[property] || [];
409
400
  let values = [];
410
401
  const cardHasLegalOverrides = Object.keys(card.legalOverrides || {}).length > 0;
411
402
  const isCheckingForLegalHeroes = filter.filterToPropertyMapping.property === FilterProperty.LegalHeroes;
@@ -427,29 +418,41 @@ const getCardValues = (card, filter, filters) => {
427
418
  if (values.length === 0) {
428
419
  if (nestedProperty) {
429
420
  const valuesSet = /* @__PURE__ */ new Set();
430
- for (const rawValue of propertyValues) {
421
+ for (const printing of card.printings) {
422
+ const printingValue = printing[nestedProperty];
431
423
  if (isNestedPropertyArray) {
432
- const rawValues = rawValue[nestedProperty] || [];
433
- for (const value of rawValues) {
434
- valuesSet.add(value);
435
- }
436
- } else {
437
- const value = rawValue[nestedProperty];
438
- if (value) {
439
- valuesSet.add(value);
424
+ if (Array.isArray(printingValue)) {
425
+ for (const value of printingValue) {
426
+ valuesSet.add(value);
427
+ }
440
428
  }
429
+ } else if (printingValue && typeof printingValue === "string") {
430
+ valuesSet.add(printingValue);
441
431
  }
442
432
  }
443
433
  values = Array.from(valuesSet);
444
434
  } else {
445
- values = propertyValues;
435
+ const cardValue = getCardValue(card, filter);
436
+ if (Array.isArray(cardValue)) {
437
+ for (const value of cardValue) {
438
+ if (typeof value === "string") {
439
+ values.push(value);
440
+ }
441
+ }
442
+ }
446
443
  }
447
444
  }
448
445
  return values;
449
446
  };
450
447
  const getCardSpecialValue = (card, appliedFilter) => {
451
- const { filterToPropertyMapping } = appliedFilter;
452
- return card[filterToPropertyMapping.specialProperty];
448
+ const {
449
+ filterToPropertyMapping: { specialProperty }
450
+ } = appliedFilter;
451
+ let specialValue;
452
+ if (specialProperty) {
453
+ specialValue = card[specialProperty];
454
+ }
455
+ return specialValue;
453
456
  };
454
457
  const doesFilterMatchCardType = ({ cardTypes }, { types, subtypes }) => !cardTypes || cardTypes?.some(
455
458
  (cardType) => types.map((type) => type.toLowerCase()).includes(cardType.toLowerCase()) || subtypes.map((subtype) => subtype.toLowerCase()).includes(cardType.toLowerCase())
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@flesh-and-blood/search",
3
3
  "description": "TypeScript search engine for Flesh and Blood cards",
4
- "version": "5.0.3",
4
+ "version": "5.0.5",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "main": "dist/index.cjs",
@@ -46,8 +46,8 @@
46
46
  "@flesh-and-blood/types": "^5.0.0"
47
47
  },
48
48
  "devDependencies": {
49
- "@flesh-and-blood/cards": "^5.0.3",
50
- "@flesh-and-blood/types": "^5.0.0",
49
+ "@flesh-and-blood/cards": "^5.0.5",
50
+ "@flesh-and-blood/types": "^5.0.5",
51
51
  "@types/jest": "^29.5.11",
52
52
  "@types/node": "^20.10.5",
53
53
  "esbuild": "^0.19.10",
@@ -77,5 +77,5 @@
77
77
  "FAB",
78
78
  "FABTCG"
79
79
  ],
80
- "gitHead": "e32d80c88cb7ead4f7ad644a7f3f8848b3a71e9c"
80
+ "gitHead": "f0584b7f17254f1abce4397e5127b4503b2ad951"
81
81
  }