import { WishListRoll , DimWishList , WishListAndInfo } from "./types.js" ; const EMPTY_NUMBER_SET = new Set < number > ( ) ; let _blockNotes ; /**
 * Extracts rolls, title, and description from the meat of
 * a wish list text file.
 */ export function toWishList ( fileText ) { return { wishListRolls : toWishListRolls ( fileText ) , title : getTitle ( fileText ) , description : getDescription ( fileText ) , } ; } function expectedMatchResultsLength ( matchResults ) { return matchResults . length === 4 ; } const blockNoteLineRegex = /^\/\/notes:(?<blockNotes>.*)/ ; /** Side effect-y function that will set/unset block notes */ function parseBlockNoteLine ( blockNoteLine ) { const blockMatchResults = blockNoteLineRegex . exec ( blockNoteLine ) ; _blockNotes = blockMatchResults ?. groups ?. blockNotes ; return null ; } function getPerks ( matchResults ) { if ( ! matchResults . groups || matchResults . groups . itemPerks === undefined ) { return EMPTY_NUMBER_SET ; } const split = matchResults [ 2 ] . split ( "," ) ; const s = new Set < number > ( ) ; for ( const perkHash of split ) { const n = Number ( perkHash ) ; if ( n > 0 ) { s . add ( n ) ; } } return s ; } function getNotes ( matchResults ) { return matchResults . groups ?. wishListNotes || _blockNotes ; } function getItemHash ( matchResults ) { if ( ! matchResults . groups ) { return 0 ; } return Number ( matchResults . groups . itemHash ) ; } const dtrTextLineRegex = /^https:\/\/destinytracker\.com\/destiny-2\/db\/items\/(?<itemHash>\d+)(?:.*)?perks=(?<itemPerks>[\d,]*)(?:#notes:)?(?<wishListNotes>.*)?/ ; function toDtrWishListRoll ( dtrTextLine ) { if ( ! dtrTextLine || dtrTextLine . length === 0 ) { return null ; } if ( dtrTextLine . startsWith ( "//" ) ) { return null ; } const matchResults = dtrTextLineRegex . exec ( dtrTextLine ) ; if ( ! matchResults || ! expectedMatchResultsLength ( matchResults ) ) { return null ; } const itemHash = getItemHash ( matchResults ) ; const recommendedPerks = getPerks ( matchResults ) ; const notes = getNotes ( matchResults ) ; return { itemHash , recommendedPerks , isExpertMode : false , notes , } ; } const bansheeTextLineRegex = /^https:\/\/banshee-44\.com\/\?weapon=(?<itemHash>\d.+)&socketEntries=(?<itemPerks>[\d,]*)(?:#notes:)?(?<wishListNotes>.*)?/ ; /** Translate a single banshee-44.com URL -> WishListRoll. */ function toBansheeWishListRoll ( bansheeTextLine ) { if ( ! bansheeTextLine || bansheeTextLine . length === 0 ) { return null ; } if ( bansheeTextLine . startsWith ( "//" ) ) { return null ; } const matchResults = bansheeTextLineRegex . exec ( bansheeTextLine ) ; if ( ! matchResults || ! expectedMatchResultsLength ( matchResults ) ) { return null ; } const itemHash = getItemHash ( matchResults ) ; const recommendedPerks = getPerks ( matchResults ) ; const notes = getNotes ( matchResults ) ; return { itemHash , recommendedPerks , isExpertMode : false , notes , } ; } const textLineRegex = /^dimwishlist:item=(?<itemHash>-?\d+)(?:&perks=)?(?<itemPerks>[\d|,]*)?(?:#notes:)?(?<wishListNotes>.*)?/ ; export function toDimWishListRoll ( textLine ) { if ( ! textLine || textLine . length === 0 ) { return null ; } if ( textLine . startsWith ( "//" ) ) { return null ; } const matchResults = textLineRegex . exec ( textLine ) ; if ( ! matchResults || ! expectedMatchResultsLength ( matchResults ) ) { return null ; } let itemHash = getItemHash ( matchResults ) ; const isUndesirable = itemHash < 0 && itemHash !== DimWishList . WildcardItemId ; const recommendedPerks = getPerks ( matchResults ) ; const notes = getNotes ( matchResults ) ; if ( isUndesirable && itemHash !== DimWishList . WildcardItemId ) { itemHash = Math . abs ( itemHash ) ; } return { itemHash , recommendedPerks , isExpertMode : true , notes , isUndesirable , } ; } function sortedSetToString ( set ) { return [ ... set ] . sort ( ( a , b ) => a - b ) . toString ( ) ; } /** Newline-separated banshee-44.com text -> WishListRolls. */ function toWishListRolls ( fileText ) { const textArray = fileText . split ( "\n" ) ; const rolls = [ ] ; for ( const line of textArray ) { const roll = toDimWishListRoll ( line ) || toBansheeWishListRoll ( line ) || toDtrWishListRoll ( line ) || parseBlockNoteLine ( line ) ; if ( roll ) { rolls . push ( roll ) ; } } const seen = new Set < string > ( ) ; const ret = [ ] ; for ( const roll of rolls ) { const rollHash = `${ roll . itemHash };${ roll . isExpertMode };${ sortedSetToString ( roll . recommendedPerks ) }` ; if ( ! seen . has ( rollHash ) ) { seen . add ( rollHash ) ; ret . push ( roll ) ; } } return ret ; } function findMatch ( sourceFileLine , regExToMatch ) { if ( ! sourceFileLine || ! sourceFileLine . length ) { return undefined ; } const matchResults = sourceFileLine . match ( regExToMatch ) ; if ( ! matchResults || matchResults . length !== 2 ) { return undefined ; } return matchResults [ 1 ] ; } function findTitle ( sourceFileLine ) { return findMatch ( sourceFileLine , /^title:(.*)/ ) ; } function findDescription ( sourceFileLine ) { return findMatch ( sourceFileLine , /^description:(.*)/ ) ; } function getTitle ( sourceFileText ) { if ( ! sourceFileText ) { return undefined ; } const sourceFileLineArray = sourceFileText . split ( "\n" ) . slice ( 0 , 20 ) ; return sourceFileLineArray . map ( findTitle ) . find ( ( s ) => s ) ; } function getDescription ( sourceFileText ) { if ( ! sourceFileText ) { return undefined ; } const sourceFileLineArray = sourceFileText . split ( "\n" ) . slice ( 0 , 20 ) ; return sourceFileLineArray . map ( findDescription ) . find ( Boolean ) ; }