diff --git a/.env.production b/.env.production index 2f14a6e..5a9bfbe 100644 --- a/.env.production +++ b/.env.production @@ -45,16 +45,16 @@ NEXT_PUBLIC_SIGN_MESSAGE="Sign this message so our backend can verify you." # ---- Packstore ---- # 1 random Normal skin 1-Star Beast -NEXT_PUBLIC_ADDRESS_RESERVABLE_NORMAL_SKIN="0x6ec745e460cc646c" -NEXT_PUBLIC_ADDRESS_REFUNDABLE_NORMAL_SKIN="0xdca2fbd53ec45907" +NEXT_PUBLIC_ADDRESS_RESERVABLE_NORMAL_SKIN="0xfe20e2699d201976" +NEXT_PUBLIC_ADDRESS_REFUNDABLE_NORMAL_SKIN="0xfe20e2699d201976" # 1 random Cursed Black 1-Star Beast -NEXT_PUBLIC_ADDRESS_RESERVABLE_CURSED_BLACK="0xaba9241acafae206" -NEXT_PUBLIC_ADDRESS_REFUNDABLE_CURSED_BLACK="0x470d62928ea8efd7" +NEXT_PUBLIC_ADDRESS_RESERVABLE_CURSED_BLACK="0x24992fb21ce6969c" +NEXT_PUBLIC_ADDRESS_REFUNDABLE_CURSED_BLACK="0x24992fb21ce6969c" # 1 random Shiny Gold 1-Star Beast -NEXT_PUBLIC_ADDRESS_RESERVABLE_GOLD_STAR="0x5c0fe1b8a445ba22" -NEXT_PUBLIC_ADDRESS_REFUNDABLE_GOLD_STAR="0x6391a3fdd3253bf8" +NEXT_PUBLIC_ADDRESS_RESERVABLE_GOLD_STAR="0xb5b6a4baa475f86f" +NEXT_PUBLIC_ADDRESS_REFUNDABLE_GOLD_STAR="0xb5b6a4baa475f86f" # ------------------- NEXT_PUBLIC_GRAPHQL_ENDPOINT="https://basicbeasts-dev.graphcdn.app" diff --git a/.gitignore b/.gitignore index 1437c53..f38ab03 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,5 @@ yarn-error.log* # vercel .vercel +.env.production +.env.development diff --git a/components/common/Layout/Layout.tsx b/components/common/Layout/Layout.tsx index 32b9af0..269916b 100644 --- a/components/common/Layout/Layout.tsx +++ b/components/common/Layout/Layout.tsx @@ -2,7 +2,7 @@ import { FC, useState } from "react" import Navbar from "@components/common/Navbar" import Footer from "@components/common/Footer" import SideNavbar from "@components/common/SideNavbar" -import * as fcl from "@onflow/fcl" +import * as fcl from "@blocto/fcl" import Head from "next/head" import { useRouter } from "next/dist/client/router" import { ToastContainer, toast } from "react-toastify" @@ -11,7 +11,7 @@ import SlideOverNavbar from "../SlideOverNavbar" import profilePictures from "data/profilePictures" import Snowfall from "react-snowfall" -//Configure FCL +//Configure FCL. fcl .config() .put("accessNode.api", process.env.NEXT_PUBLIC_ACCESS_NODE_API) @@ -33,6 +33,7 @@ fcl .put("0xHunterScore", process.env.NEXT_PUBLIC_HUNTER_SCORE_ADDRESS) .put("0xPack", process.env.NEXT_PUBLIC_PACK_ADDRESS) .put("0xInbox", process.env.NEXT_PUBLIC_INBOX_ADDRESS) + .put("0xBasicBeastsInbox", process.env.NEXT_PUBLIC_INBOX_ADDRESS) .put("0xEvolution", process.env.NEXT_PUBLIC_EVOLUTION_ADDRESS) .put("0xProfile", process.env.NEXT_PUBLIC_PROFILE_ADDRESS) .put("0xFiatToken", process.env.NEXT_PUBLIC_FIAT_TOKEN_ADDRESS) @@ -82,8 +83,16 @@ fcl "0xBlackMarketplace", process.env.NEXT_PUBLIC_NFT_DAY_TREASURE_CHEST_ADDRESS, ) + .put( + "0xBasicBeastsDrop", + process.env.NEXT_PUBLIC_NFT_DAY_TREASURE_CHEST_ADDRESS, + ) // .put("0xBeastMarket", process.env.NEXT_PUBLIC_BEAST_MARKET_ADDRESS) // .put("0xBeastOffers", process.env.NEXT_PUBLIC_BEAST_OFFERS_ADDRESS) +// .put("0xLovePotion", process.env.NEXT_PUBLIC_BEAST_MARKET_ADDRESS) +// .put("0xLovePotionMinter", process.env.NEXT_PUBLIC_BEAST_OFFERS_ADDRESS) +// .put("0xEgg", process.env.NEXT_PUBLIC_BEAST_MARKET_ADDRESS) +// .put("0xBreeding", process.env.NEXT_PUBLIC_BEAST_OFFERS_ADDRESS) const Layout: FC = ({ children }) => { const [isSideNavbarOpen, setIsSideNavbarOpen] = useState(false) diff --git a/components/common/Navbar/Navbar.tsx b/components/common/Navbar/Navbar.tsx index fcb485a..3456c54 100644 --- a/components/common/Navbar/Navbar.tsx +++ b/components/common/Navbar/Navbar.tsx @@ -21,6 +21,7 @@ import { Menu, Transition } from "@headlessui/react" import { toast } from "react-toastify" import SearchBar from "@components/ui/SearchBar" import SearchBarMobileModal from "@components/ui/SearchBarMobileModal" +import { beastData } from "data/beastData" const Nav = styled.header<{ font: string; fontSize: string }>` background: #111823; @@ -592,7 +593,7 @@ const Navbar: FC = ({ cadence: ` import Profile from 0xProfile - pub fun main(address: Address) : Profile.UserProfile? { + access(all) fun main(address: Address) : Profile.UserProfile? { return getAccount(address) .getCapability<&{Profile.Public}>(Profile.publicPath) .borrow()?.asProfile() @@ -605,7 +606,7 @@ const Navbar: FC = ({ setProfile(res) //Resolve Profile Picture - let avatar = res.avatar + let avatar = res?.avatar for (let key in profilePictures) { let element = profilePictures[key as unknown as keyof typeof profilePictures] @@ -613,23 +614,13 @@ const Navbar: FC = ({ setProfilePicture(element.image) } } - console.log("Navbar.ts: getCurrentUserProfile()") + // console.log("Navbar.ts: getCurrentUserProfile()") } catch (error) { console.log(error) } } const { hunterData } = useUser() - const beastData = [ - { - name: "Dappy", - imageTransparentBg: "QmUGU1LszrYGmpPp25VL6bAd5d39VW6PuDZDYSuwbj3VFS", - }, - { - name: "Gecko", - imageTransparentBg: "QmVBqZGtah7sRV7YafvZuXm8nNgts8wR1ihgfvVHa7ykZQ", - }, - ] return ( <> @@ -668,7 +659,7 @@ const Navbar: FC = ({ setOpenMobileModal={setOpenMobileSearch} /> - + {/* = ({ Explore - + */} = ({ Rankings + {/* +
+ Wonderland +
+ +
+
+
*/}
{loggedIn && ( diff --git a/components/common/SideNavbar/SideNavbar.tsx b/components/common/SideNavbar/SideNavbar.tsx index 3296b73..4416ad5 100644 --- a/components/common/SideNavbar/SideNavbar.tsx +++ b/components/common/SideNavbar/SideNavbar.tsx @@ -185,7 +185,7 @@ const SideNavbar: FC = ({ isSideNavbarOpen, toggle }: Props) => { - + Store diff --git a/components/common/SlideOverNavbar/SlideOverNavbar.tsx b/components/common/SlideOverNavbar/SlideOverNavbar.tsx index ea49f01..c6862ae 100644 --- a/components/common/SlideOverNavbar/SlideOverNavbar.tsx +++ b/components/common/SlideOverNavbar/SlideOverNavbar.tsx @@ -284,10 +284,10 @@ const SlideOverNavbar: FC = ({ )} - + close()}> - Store + Drop @@ -305,6 +305,20 @@ const SlideOverNavbar: FC = ({ + + + Wonderland +
+ +
+
+
{/* close()}> diff --git a/components/ui/AcceptOfferModal/AcceptOfferModal.tsx b/components/ui/AcceptOfferModal/AcceptOfferModal.tsx index ab9104e..8e7cacb 100644 --- a/components/ui/AcceptOfferModal/AcceptOfferModal.tsx +++ b/components/ui/AcceptOfferModal/AcceptOfferModal.tsx @@ -164,6 +164,12 @@ const AcceptOfferModal: FC = ({ open, setOpen, beast, offer }) => { ${parseFloat(offer?.offerAmount) * 0.9} FUSD +
setOpen(false)} + > +
x
+
@@ -581,202 +661,6 @@ type Props = { // beasts: any } -// const DialogInfo: FC<{ -// id: any -// dialogOpen: any -// beast: any -// // left: any -// // right: any -// }> = ({ -// id, -// dialogOpen, -// beast, -// // left, right -// }) => { -// let centerX = document.documentElement.clientWidth / 2 -// let centerY = document.documentElement.clientHeight / 2 - -// // console.log("X: " + centerX, "Y: " + centerY) - -// // const elem = document.getElementById(id) -// // const box = elem?.getBoundingClientRect() -// // console.log("Box: " + box?.x) -// // var right = 50 -// // var left = 50 -// // if (box != null && box?.x > centerX) { -// // right = 0 -// // } else if (box != null && box?.x < centerX) { -// // left = 0 -// // } else { -// // left = 50 -// // right = 50 -// // } - -// // console.log("left: " + left, "right: " + right) - -// return dialogOpen == true ? ( -// -//
-// {beast.nickname.length < 13 ? ( -//
{beast.nickname}
-// ) : ( -//
{beast.nickname}
-// )} -//
#{beast.serialNumber}
-//
-//
-// Dex {"#" + ("00" + beast.dexNumber).slice(-3)} -//
-//

Attributes

-// -// -//

Skin

-//
{beast.skin}
-// % have this trait -//
-// -//

Element

-//
{beast.elements}
-// % have this trait -//
-// -//

Star Level

-//
{beast.starLevel}
-// % have this trait -//
-// -//

Gender

-//
{beast.sex}
-// -// % of {beast.name}
have this trait -//
-//
-// -//

Breeding Count

-//
{beast.breedingCount}
-// % have this trait -//
-// -//

Serial

-//
{beast.serialNumber}
-// % have this trait -//
-// -//

Number of Existing {beast.name}s

-//
{beast.numberOfMintedBeastTemplates}
-//
-//
-//

Details

-//
-//

Mint address

-//

0x23948

-//
-//
-// ) : ( -// <> -// ) -// } -// const ThumbnailDetailsFC: FC<{ -// beast: any -// }> = ({ beast }) => { -// const [dialogOpen, setDialogOpen] = useState(false) -// const [heart, setHeart] = useState(heartEmpty) -// const buttonColor = () => { -// var color = "none" -// { -// dialogOpen == true ? (color = "#FEDD64") : (color = "none") -// } -// return color -// } -// var btnColor = buttonColor() -// const heartChange = () => { -// { -// heart == heartEmpty ? setHeart(heartFull) : setHeart(heartEmpty) -// } -// } - -// // let centerX = document.documentElement.clientWidth / 2 -// // let centerY = document.documentElement.clientHeight / 2 -// // const elem = document.getElementById("element") -// // const box = elem?.getBoundingClientRect() -// // console.log("Box: " + box?.x) -// // var right = 50 -// // var left = 50 -// // if (box != null && box?.x > centerX) { -// // right = 0 -// // } else if (box != null && box?.x < centerX) { -// // left = 0 -// // } else { -// // left = 50 -// // right = 50 -// // } - -// return ( -//
-// -// -//
#{beast.serialNumber}
-// {beast.nickname.length < 13 ? ( -//
-// {beast.nickname} -//
-// ) : ( -//
{beast.nickname}
-// )} -//
-// setDialogOpen(!dialogOpen)} -// > -// Details -// -// -//
-// heartChange()} -// style={{ color: "grey" }} -// icon={heart} -// />{" "} -// 76 -//
-//
-// {beast.price != null -// ? parseFloat(beast.price).toFixed(2) -// : "not for sale"} -//
-// -// {Array(beast.starLevel) -// .fill(0) -// .map((_, i) => ( -// -// ))} -// -//
-//
-// ) -// } - const filterOptions = [ { value: "", @@ -796,6 +680,7 @@ const BeastMarket: FC = () => { const [displayBeasts, setDisplayBeasts] = useState(null) const [selectedBeast, setSelectedBeast] = useState(null) const [listBeastForSaleOpen, setListBeastForSaleOpen] = useState(false) + const [placeABidOpen, setPlaceABidOpen] = useState(false) const [open, setOpen] = useState(false) const [displayNickname, setDisplayNickname] = useState(null) const [sortBy, setSortBy] = useState("SORT BY") @@ -817,17 +702,29 @@ const BeastMarket: FC = () => { element: [], serialNumber: [], }) - // const [beasts, setBeasts] = useState([]) const [beastArray, setBeastArray] = useState([]) - // console.log(beastArray) const [selectedBeasts, setSelectedBeasts] = useState([]) const [favoriteBeasts, setFavoriteBeasts] = useState([]) const [favoriteToggled, setFavoriteToggled] = useState(false) + const [ownedToggled, setOwnedToggled] = useState(false) + + const { beasts, getAllBeasts, userBeasts } = useUser() - const { beasts, getAllBeasts } = useUser() + const [isMobile, setIsMobile] = useState(true) + + useEffect(() => { + if (typeof window !== "undefined") { + const mediaQuery = window.matchMedia("(max-width: 440px)") + const handleMediaChange = () => setIsMobile(mediaQuery.matches) + + setIsMobile(mediaQuery.matches) + mediaQuery.addListener(handleMediaChange) + return () => mediaQuery.removeListener(handleMediaChange) + } + }, []) const selectBeast = (beast: any) => { if (!selectedBeasts.includes(beast)) { @@ -871,10 +768,6 @@ const BeastMarket: FC = () => { return { btnColor, fontColor } } - useEffect(() => { - // getAllBeasts() - }, []) - //When beasts changes useEffect(() => { if (beasts != null) { @@ -906,13 +799,12 @@ const BeastMarket: FC = () => { } } + // useEffect(() => { if (favoriteToggled) { - // console.log(favoriteToggled) // const newBeasts = displayBeasts.filter((beast: any) => { // favoriteBeasts.includes(beast.id) // }) - console.log(favoriteBeasts) var newBeasts: any = [] for (let key in displayBeasts) { var beast = displayBeasts[key] @@ -922,13 +814,44 @@ const BeastMarket: FC = () => { } // setElementFilter((elementFilter: any) => [...elementFilter, "Electric"]) setDisplayBeasts(newBeasts) + } else if (ownedToggled) { + var newBeasts: any = [] + for (let key in beasts) { + var beast = beasts[key] + if (userBeasts?.map((beast: any) => beast.id).includes(beast.id)) { + newBeasts.push(beast) + } + } + setDisplayBeasts(newBeasts) } else { setDisplayBeasts(beasts) } - // console.log(favoriteBeasts.toString()) - // console.log(favoriteBeasts) }, [favoriteToggled]) + useEffect(() => { + if (ownedToggled) { + var newBeasts: any = [] + for (let key in displayBeasts) { + var beast = displayBeasts[key] + if (userBeasts?.map((beast: any) => beast.id).includes(beast.id)) { + newBeasts.push(beast) + } + } + setDisplayBeasts(newBeasts) + } else if (favoriteToggled) { + var newBeasts: any = [] + for (let key in beasts) { + var beast = beasts[key] + if (favoriteBeasts.includes(beast.id)) { + newBeasts.push(beast) + } + } + setDisplayBeasts(newBeasts) + } else { + setDisplayBeasts(beasts) + } + }, [ownedToggled]) + const [filter, setFilter] = useState() const [filters, setFilters] = useState([ @@ -943,12 +866,7 @@ const BeastMarket: FC = () => { }, ]) - // useEffect(() => { - // alert("filters changed") - // }, [filters.dexNumberOptions]) - useEffect(() => { - // beasts.map((beast: any) => console.log("Nickname: " + beast.nickname)) // Get skins const skins = beasts .map((beast: any) => beast.skin) @@ -1034,7 +952,6 @@ const BeastMarket: FC = () => { checked: false, }) } - // console.log(starLevels) // Get Dex Number e.g. value 1, label #001 Moon const dexNumbers = beasts @@ -1086,28 +1003,228 @@ const BeastMarket: FC = () => { ]) }, [beasts]) - //function that filter beasts - //(selectedFilter: any){} - //beats.filter() + const router = useRouter() - // filters = ["Water", "Fire"] - // beast.elemnts = ["Water"] + // Takes the values of the selectedFilters and returns it as a string + const showFilterKeyPlusValue = () => { + let filtersPlusValue = [] + for (let i in selectedFilters) { + if (selectedFilters[i].length >= 1) { + filtersPlusValue.push(`${i}=${selectedFilters[i].join(",")}`) + } + } + return filtersPlusValue + } - //filters.includes(beast.elements.map(element => element)) + const [sortObj, setSortObj] = useState({}) - // filters.element?.includes(beast.elements) && + // Change the url string based on filter and sort states + useEffect(() => { + let activeFilters = showFilterKeyPlusValue() + let filterObject: Record = {} + + activeFilters?.forEach((activeFilter) => { + const [key, value] = activeFilter.split("=") + filterObject[key] = value + }) + + if (Object.keys(filterObject).length > 0) { + // If not empty then add the filter object and sort object + router.replace( + { + pathname: "/marketplace", + query: { ...filterObject, ...sortObj }, + }, + undefined, + { shallow: true }, + ) // shallow true, to avoid page from doing hard-reload when selecting filters + } else if (Object.keys(filterObject).length === 0 && router.query) { + // If empty, then add only sort object + router.replace( + { + pathname: "/marketplace", + query: { ...sortObj }, + }, + undefined, + { shallow: true }, + ) + } + }, [selectedFilters, sortObj]) + + // Set sort object + useEffect(() => { + if (sortBy !== "SORT BY") { + setSortObj({ sort: sortBy }) + } + }, [sortBy]) + + const { query } = router + // Reads the url and update the filters and sort state. + useEffect(() => { + const { sort } = query + let changeValues = query + if (sort) { + setSortBy(typeof query.sort === "string" ? query.sort : "Sort By") + changeValues = Object.entries(query) + .filter(([key]) => key !== "sort") + .reduce((obj, [key, value]) => ({ ...obj, [key]: value }), {}) + } + handleMassChange(changeValues) + // handleMassChange(query) // if anything breaks cuz of the sorting just comment the code above and uncomment this one + }, [query]) + + useEffect(() => { + const { sort } = query + if (!beasts || !beasts.length) { + return + } + switch (sort) { + case "Price (Low-High)": + beasts.sort((a: any, b: any) => a.beastTemplateID - b.beastTemplateID) + beasts.sort((a: any, b: any) => { + if (a.price == null || a.price === 0) { + return 1 + } else if (b.price == null || b.price === 0) { + return -1 + } else { + return a.price - b.price + } + }) + break + + case "Price (High-Low)": + beasts.sort((a: any, b: any) => a.beastTemplateID - b.beastTemplateID) + beasts.sort((a: any, b: any) => b.price - a.price) + break + + case "Dex No. (Low-High)": + beasts.sort((a: any, b: any) => a.beastTemplateID - b.beastTemplateID) + beasts.sort((a: any, b: any) => a.dexNumber - b.dexNumber) + break + + case "Dex No. (High-Low)": + beasts.sort((a: any, b: any) => a.beastTemplateID - b.beastTemplateID) + beasts.sort((a: any, b: any) => b.dexNumber - a.dexNumber) + break + + case "Nickname A-Z": + beasts.sort((a: any, b: any) => (a.nickname > b.nickname ? 1 : -1)) + break + + case "Nickname Z-A": + beasts.sort((a: any, b: any) => (a.nickname < b.nickname ? 1 : -1)) + break + + case "Serial (Low-High)": + beasts.sort((a: any, b: any) => a.beastTemplateID - b.beastTemplateID) + beasts.sort((a: any, b: any) => a.serialNumber - b.serialNumber) + break + + case "Serial (High-Low)": + beasts.sort((a: any, b: any) => a.beastTemplateID - b.beastTemplateID) + beasts.sort((a: any, b: any) => b.serialNumber - a.serialNumber) + break + + case "Skin (Low-High)": + const dic = { + Normal: 1, + "Metallic Silver": 2, + "Cursed Black": 3, + "Shiny Gold": 4, + "Mythic Diamond": 5, + } + if (beasts != null) { + beasts.sort((a: any, b: any) => { + var aValue = 0 + var bValue = 0 + aValue = dic[a.skin as keyof typeof dic] + bValue = dic[b.skin as keyof typeof dic] + if (aValue < bValue) return -1 + if (aValue > bValue) return 1 + return 0 + }) + } + break + + case "Skin (High-Low)": + const dic2 = { + Normal: 1, + "Metallic Silver": 2, + "Cursed Black": 3, + "Shiny Gold": 4, + "Mythic Diamond": 5, + } + if (beasts != null) { + beasts.sort((a: any, b: any) => { + var aValue = 0 + var bValue = 0 + aValue = dic2[a.skin as keyof typeof dic2] + bValue = dic2[b.skin as keyof typeof dic2] + if (aValue < bValue) return 1 + if (aValue > bValue) return -1 + return 0 + }) + } + break + + case "Element Type": + const dict = { Electric: 1, Water: 2, Grass: 3, Fire: 4, Normal: 5 } + if (beasts != null) { + beasts.sort((a: any, b: any) => { + var aValue = 0 + var bValue = 0 + aValue = dict[a.elements[0] as keyof typeof dict] + bValue = dict[b.elements[0] as keyof typeof dict] + if (aValue < bValue) return -1 + if (aValue > bValue) return 1 + return 0 + }) + } + break + } + }, [beasts, query]) + + const handleMassChange = (query?: any) => { + if (Object.keys(query).length > 0) { + const selectedFiltersMockup: any = { + dexNumber: [], + skin: [], + starLevel: [], + element: [], + serialNumber: [], + } + for (const i in query) { + if (!query[i].includes(",")) { + selectedFiltersMockup[i].push(query[i]) + } else { + const valuesArr = query[i].split(",") + for (const k in valuesArr) { + selectedFiltersMockup[i].push(valuesArr[k]) + } + } + } + if ( + JSON.stringify(selectedFilters) !== + JSON.stringify(selectedFiltersMockup) + ) { + setSelectedFilters(selectedFiltersMockup) + } + } + } - // prettier-ignore const filterBeasts = (beasts: any, filters: any) => { - // console.log("TESTTT",filters.dexNumber?.length) return beasts.filter((beast: any) => { return ( - (filters.dexNumber?.length == 0 || filters.dexNumber?.includes(beast.dexNumber)) && - (filters.skin?.length == 0 || filters.skin?.includes(beast.skin)) && - (filters.starLevel?.length == 0 || filters.starLevel?.includes(beast.starLevel)) && - (filters.element?.length == 0 || filters.element?.every((e: any) => beast.elements.includes(e))) && - (filters.serialNumber?.length == 0 || filters.serialNumber?.includes(beast.serialNumber)) - ) + (filters.dexNumber?.length == 0 || + filters.dexNumber?.includes(beast.dexNumber)) && + (filters.skin?.length == 0 || filters.skin?.includes(beast.skin)) && + (filters.starLevel?.length == 0 || + filters.starLevel?.includes(beast.starLevel)) && + (filters.element?.length == 0 || + filters.element?.every((e: any) => beast.elements.includes(e))) && + (filters.serialNumber?.length == 0 || + filters.serialNumber?.includes(beast.serialNumber)) + ) }) } @@ -1124,87 +1241,13 @@ const BeastMarket: FC = () => { //useCallback //useMemo + // SETS BEASTS FOR DISPLAY AFTER FILTERS useEffect(() => { - // console.log("selectedFilters changed", selectedFilters) - //{SELECTED FILTER} - const newList = filterBeasts(beasts, selectedFilters) const checkFiltersResult = checkFilters(selectedFilters) - setDisplayBeasts(checkFiltersResult ? beasts : newList) - - console.log("BEASTS", beasts) - - //setDisplayBeasts() }, [selectedFilters, beasts]) - // const getAllBeasts = async () => { - // try { - // let res = await query({ - // cadence: ` - // import HunterScore from 0xHunterScore - // import BasicBeasts from 0xBasicBeasts - - // pub fun main(): [{String:AnyStruct}] { - - // let addresses = HunterScore.getHunterScores().keys - // var beasts: [{String: AnyStruct}] = [] - - // for address in addresses { - // let collectionRef = getAccount(address).getCapability(BasicBeasts.CollectionPublicPath) - // .borrow<&{BasicBeasts.BeastCollectionPublic}>() - // if (collectionRef != nil) { - // let IDs = collectionRef!.getIDs() - // var i = 0 - // while i < IDs.length { - // let token = collectionRef!.borrowBeast(id: IDs[i]) - // ?? panic("Couldn't borrow a reference to the specified beast") - - // let beastTemplate = token.getBeastTemplate() - - // var price: UFix64? = nil - - // if (i%2==0) { - // price = 69.0 + UFix64(i) - // } - - // let beast = { - // "name" : beastTemplate.name, - // "nickname" : token.getNickname(), - // "serialNumber" : token.serialNumber, - // "dexNumber" : beastTemplate.dexNumber, - // "skin" : beastTemplate.skin, - // "starLevel" : beastTemplate.starLevel, - // "elements" : beastTemplate.elements, - // "basicSkills" : beastTemplate.basicSkills, - // "ultimateSkill" : beastTemplate.ultimateSkill, - // "currentOwner" : address, - // "firstOwner" : token.getFirstOwner(), - // "sex" : token.sex, - // "breedingCount" : 0, - // "numberOfMintedBeastTemplates" : 100, - // "beastTemplateID" : beastTemplate.beastTemplateID, - // "price" : price, - // "id": token.id - // } - - // beasts.insert(at:i, beast) - - // i = i + 1 - // } - // } - // } - - // return beasts - // } - // `, - // }) - // setBeasts(res) - // } catch (error) { - // console.log(error) - // } - // } - return ( <> = () => { setOpen={setListBeastForSaleOpen} beast={selectedBeast} /> + = () => { */} + + + setSearch(e.target.value.toLowerCase())} + /> + {search != "" && ( + setSearch("")}>x + )} + + + setMobileFiltersOpen(true)} + > + Sort_Icon + Filters + {/* */} + + + + + + {isMobile && ( + + )} +
{(filterOpen || mobileFiltersOpen) && (
@@ -1311,6 +1399,8 @@ const BeastMarket: FC = () => { setMobileFiltersOpen={setMobileFiltersOpen} favoriteToggled={favoriteToggled} setFavoriteToggled={setFavoriteToggled} + ownedToggled={ownedToggled} + setOwnedToggled={setOwnedToggled} />
)} @@ -1324,6 +1414,9 @@ const BeastMarket: FC = () => { setListBeastForSaleOpen={setListBeastForSaleOpen} favoriteBeasts={favoriteBeasts} setFavoriteBeasts={setFavoriteBeasts} + setPlaceABidOpen={setPlaceABidOpen} + selectedFilters={selectedFilters} + setSelectedFilters={setSelectedFilters} // setOpen={setOpen} // setDisplayNickname={setDisplayNickname} /> @@ -1458,7 +1551,8 @@ const BeastMarket: FC = () => { )} {/*
*/} - + {/* wait with this */} + {/*
Information is coming here
setMobileCartOpen(true)}> View Cart @@ -1469,7 +1563,7 @@ const BeastMarket: FC = () => { open={mobileCartOpen} setOpen={setMobileCartOpen} /> -
+
*/}
) diff --git a/components/ui/BeastMarket/SelectedFiltersOverview.tsx b/components/ui/BeastMarket/SelectedFiltersOverview.tsx new file mode 100644 index 0000000..b4cfe1c --- /dev/null +++ b/components/ui/BeastMarket/SelectedFiltersOverview.tsx @@ -0,0 +1,180 @@ +import { FC, Fragment, useEffect, useState } from "react" +import styled from "styled-components" +import { useRouter } from "next/router" + +const FiltersWrapper = styled.div` + display: flex; + gap: 10px; + margin-bottom: 0.5rem; + max-width: 100%; + flex-wrap: wrap; + @media (max-width: 426px) { + overflow-x: scroll; + height: 40px; + flex-wrap: nowrap; + font-size: 0.8rem; + } +` + +const Filter = styled.div` + min-width: 120px; + height: 30px; + color: white; + border: 1px solid; + border-radius: 3px; + display: flex; + justify-content: space-between; + align-items: center; + background-color: rgba(255, 217, 102, 0.2); + border-color: #ffd966; + padding: 0 10px; + @media (max-width: 426px) { + padding: 0 8px; + } +` + +const DeleteFilter = styled.div` + padding-left: 1rem; + font-size: 1.2rem; + + &:hover { + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) + 14 0, + pointer !important; + } + @media (max-width: 426px) { + padding: 0; + } +` + +const ClearAllFiltersBtn = styled.div` + background-color: rgba(255, 217, 102, 0.2); + border: none; + border-color: rgba(255, 217, 102, 0.2); + &:hover { + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) + 14 0, + pointer !important; + } + @media (max-width: 426px) { + min-width: 55px; + } + // min-width: 70px; + height: 30px; + color: white; + border-radius: 3px; + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 10px; + @media (max-width: 426px) { + padding: 0 8px; + } +` + +interface selectedFilters { + [key: string]: string[] +} + +type Props = { + selectedFilters: selectedFilters + setSelectedFilters: React.Dispatch> +} + +const SelectedFiltersOverview: FC = ({ + selectedFilters, + setSelectedFilters, +}) => { + const router = useRouter() + const removeFilterOption = (filterName: string, filterValue: string) => { + if (router.query[filterName]?.includes(",")) { + const filteredValues = (router.query[filterName] as string) + ?.split(",") + .filter((fil: string) => fil !== filterValue) + const query = { ...router.query, [filterName]: filteredValues.join(",") } + router.push({ pathname: router.pathname, query }, undefined, { + shallow: true, + }) + } else { + const routerQueryMockup = router.query + console.log(Object.keys(routerQueryMockup).length) + if (Object.keys(routerQueryMockup).length <= 1) { + removeAllFilers() + } else { + delete routerQueryMockup[filterName] + router.push( + { pathname: router.pathname, query: routerQueryMockup }, + undefined, + { shallow: true }, + ) + } + } + } + + const removeAllFilers = () => { + setSelectedFilters({ + dexNumber: [], + skin: [], + starLevel: [], + element: [], + serialNumber: [], + }) + router.push({ pathname: router.pathname, query: "" }, undefined, { + shallow: true, + }) + } + + console.log( + Object.values(selectedFilters).filter((selFil: any) => selFil.length != 0), + ) + console.log(Object.values(selectedFilters)) + + return ( + <> + {Object.keys(router.query).length == 0 || + Object.values(selectedFilters).filter((selFil: any) => selFil.length != 0) + .length == 0 ? ( + "" + ) : ( + <> + + { + removeAllFilers() + }} + > + {" "} + Clear All + + {Object.entries(selectedFilters).map((filters) => + filters[1].map((filter: any) => { + return ( + +

+ {filters[0] == "dexNumber" + ? "Dex Number" + : filters[0] == "starLevel" + ? "Star Level" + : filters[0] == "serialNumber" + ? "Serial" + : filters[0].charAt(0).toUpperCase() + + filters[0].slice(1, filters[0].length)} + : {filter} +

+ removeFilterOption(filters[0], filter)} + > +

x

+
+
+ ) + }), + )} +
+ + )} + + ) +} + +export default SelectedFiltersOverview diff --git a/components/ui/BeastMarketBeastList/BeastMarketBeastList.tsx b/components/ui/BeastMarketBeastList/BeastMarketBeastList.tsx index 989e79a..b43e691 100644 --- a/components/ui/BeastMarketBeastList/BeastMarketBeastList.tsx +++ b/components/ui/BeastMarketBeastList/BeastMarketBeastList.tsx @@ -6,6 +6,8 @@ import BeastMarketThumbnail from "../BeastMarketThumbnail" import { faHeart as heartFull } from "@fortawesome/free-solid-svg-icons" import { faHeart as heartEmpty } from "@fortawesome/free-regular-svg-icons" import { useUser } from "@components/user/UserProvider" +import { useAuth } from "@components/auth/AuthProvider" +import SelectedFiltersOverview from "../BeastMarket/SelectedFiltersOverview" const MarketUl = styled.ul` padding-top: 5px; @@ -16,7 +18,7 @@ const MarketUl = styled.ul` overflow: hidden; overflow-y: scroll; - grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); + // grid-template-columns: repeat(auto-fill, minmax(200px, 2fr)); gap: 1.25rem; -ms-overflow-style: none; /* IE and Edge */ scrollbar-width: none; /* Firefox */ @@ -87,6 +89,13 @@ const QuickBuyButton = styled.button` /* &:hover { box-shadow: 2px 2px 5px 1px black; } not needed dense*/ + + @media (max-width: 420px) { + display: none; + ${BeastLi}:hover & { + display: none; + } + } ` const StarLevel = styled.div` @@ -240,6 +249,10 @@ const ThumbnailWrapper = styled.div` align-items: stretch; ` +const Container = styled.div` + width: 100%; +` + type Color = { bgColor: any } @@ -252,6 +265,9 @@ type Props = { setListBeastForSaleOpen: any favoriteBeasts: any setFavoriteBeasts: any + setPlaceABidOpen: any + selectedFilters: any + setSelectedFilters: any // setDisplayNickname: any } const BeastMarketBeastList: FC = ({ @@ -263,6 +279,9 @@ const BeastMarketBeastList: FC = ({ setListBeastForSaleOpen, favoriteBeasts, setFavoriteBeasts, + setPlaceABidOpen, + selectedFilters, + setSelectedFilters, // setDisplayNickname, }) => { const selectBeast = (beast: any) => { @@ -278,6 +297,19 @@ const BeastMarketBeastList: FC = ({ } } + const [isMobile, setIsMobile] = useState(true) + + useEffect(() => { + if (typeof window !== "undefined") { + const mediaQuery = window.matchMedia("(max-width: 440px)") + const handleMediaChange = () => setIsMobile(mediaQuery.matches) + + setIsMobile(mediaQuery.matches) + mediaQuery.addListener(handleMediaChange) + return () => mediaQuery.removeListener(handleMediaChange) + } + }, []) + // const [favoriteBeasts, setFavoriteBeasts] = useState([]) // const [selectedBeast, setSelectedBeast] = useState() @@ -469,19 +501,39 @@ const BeastMarketBeastList: FC = ({ - {beastsForSale + {userBeasts ?.map((beast: any) => beast.id) .includes(beast.id) ? ( +
+ Owned{" "} + {beastsForSale + ?.map((beast: any) => beast.id) + .includes(beast.id) && ( + <> + {parseFloat( + beastsForSale?.filter( + (beastForSale: any) => beastForSale.id == beast.id, + )[0].price, + ).toFixed(0)}{" "} + FUSD + + )} +
+ ) : ( <> - {parseFloat( - beastsForSale?.filter( - (beastForSale: any) => beastForSale.id == beast.id, - )[0].price, - ).toFixed(0)}{" "} - FUSD + {beastsForSale + ?.map((beast: any) => beast.id) + .includes(beast.id) && ( + <> + {parseFloat( + beastsForSale?.filter( + (beastForSale: any) => beastForSale.id == beast.id, + )[0].price, + ).toFixed(0)}{" "} + FUSD + + )} - ) : ( - <> )}
{/* @@ -572,128 +624,157 @@ const BeastMarketBeastList: FC = ({ } const { purchaseBeast, delistBeast } = useUser() + + const { loggedIn, logIn } = useAuth() + return ( - - {displayBeasts.map((beast: any) => ( - -
+ {!isMobile && ( + + )} + + + {displayBeasts.map((beast: any) => ( + - setBeastArray([...beastArray, beast])} - id={beast.id} - className="object-cover" - beastTemplateID={beast.beastTemplateID} - /> -
- {userBeasts?.map((beast: any) => beast.id).includes(beast.id) ? ( - <> - {beastsForSale - ?.map((beast: any) => beast.id) - .includes(beast.id) ? ( - { - setSelectedBeast(beast) - delistBeast(beast.id) - }} - > - Delist - - ) : ( - { - setSelectedBeast(beast) - setListBeastForSaleOpen(true) - }} - > - List for sale - - )} - - ) : ( - <> - {beastsForSale - ?.map((beast: any) => beast.id) - .includes(beast.id) ? ( - { - setSelectedBeast(beast) - // setQuickBidOpen(true) - purchaseBeast( - beastsForSale?.filter( - (beastForSale: any) => beastForSale.id == beast.id, - )[0].seller, - beast.id, - beastsForSale?.filter( - (beastForSale: any) => beastForSale.id == beast.id, - )[0].price, - ) - }} - > - Quick Buy - - ) : ( - <> - )} - - )} - - {/* Make thumbnail details into a component and useState inside that component and add DialogInfo to it */} - -
- ))} - {/* To prevent big gap due to fixed height, which is needed for the scroll */} -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
  • -
    +
    + setBeastArray([...beastArray, beast])} + id={beast.id} + className="object-cover" + beastTemplateID={beast.beastTemplateID} + /> +
    + {userBeasts?.map((beast: any) => beast.id).includes(beast.id) ? ( + <> + {/* Owned */} + {beastsForSale + ?.map((beast: any) => beast.id) + .includes(beast.id) ? ( + { + setSelectedBeast(beast) + delistBeast(beast.id) + }} + > + Delist + + ) : ( + { + setSelectedBeast(beast) + setListBeastForSaleOpen(true) + }} + > + List for sale + + )} + + ) : ( + <> + {/* Not owned */} + {beastsForSale + ?.map((beast: any) => beast.id) + .includes(beast.id) ? ( + { + setSelectedBeast(beast) + // setQuickBidOpen(true) + purchaseBeast( + beastsForSale?.filter( + (beastForSale: any) => beastForSale.id == beast.id, + )[0].seller, + beast.id, + beastsForSale?.filter( + (beastForSale: any) => beastForSale.id == beast.id, + )[0].price, + ) + }} + > + Quick Buy + + ) : ( + <> + {!loggedIn ? ( + logIn()}> + Make offer + + ) : ( + { + setSelectedBeast(beast) + setPlaceABidOpen(true) + }} + > + Make offer + + )} + + )} + + )} + + {/* Make thumbnail details into a component and useState inside that component and add DialogInfo to it */} + + + ))} + {/* To prevent big gap due to fixed height, which is needed for the scroll */} +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • +
  • + + ) } diff --git a/components/ui/BeastMarketFilters/BeastMarketFilters.tsx b/components/ui/BeastMarketFilters/BeastMarketFilters.tsx index b0cbba1..fccedc9 100644 --- a/components/ui/BeastMarketFilters/BeastMarketFilters.tsx +++ b/components/ui/BeastMarketFilters/BeastMarketFilters.tsx @@ -1,8 +1,10 @@ import styled from "styled-components" +import { useRouter } from "next/dist/client/router" import { FC, Fragment, useEffect, useState } from "react" import { Dialog, Disclosure, Menu, Transition } from "@headlessui/react" import { ChevronDownIcon, MinusIcon, PlusIcon } from "@heroicons/react/solid" +import { useAuth } from "@components/auth/AuthProvider" const Wrapper = styled.div` background: transparent; @@ -19,7 +21,9 @@ const FuncArgInput = styled.input` padding: 8px; padding-left: 15px; width: 100%; - cursor: pointer; + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) + 14 0, + pointer !important; margin-bottom: 0; outline: none; &::placeholder { @@ -61,7 +65,9 @@ const CheckboxWrapper = styled.div` margin-right: 0.5em; border: 0.2px solid #fff; outline: none; - cursor: pointer; + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) + 14 0, + pointer !important; } input[type="checkbox"]:disabled { border-color: #c0c0c0; @@ -82,6 +88,12 @@ const CheckboxWrapper = styled.div` input[type="checkbox"]:checked { background-color: #f3cb23; } + &:hover { + background-color: #181d24; + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) + 14 0, + pointer !important; + } ` const DialogPanel = styled(Dialog.Panel)` background: #111823; @@ -92,11 +104,13 @@ const Switch = styled.label` display: inline-block; width: 36px; height: 20px; - margin: 1rem 0; + margin: 0.8rem 0; ` const SwitchSlider = styled.span` position: absolute; - cursor: pointer; + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) + 14 0, + pointer !important; top: 0; left: 0; right: 0; @@ -134,6 +148,18 @@ const SwitchInput = styled.input` } ` +const Input = styled.input` + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) + 14 0, + pointer !important; +` + +const Label = styled.label` + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) + 14 0, + pointer !important; +` + type Props = { filters: any selectedFilters: any @@ -142,6 +168,8 @@ type Props = { setMobileFiltersOpen: any setFavoriteToggled: any favoriteToggled: any + ownedToggled: boolean + setOwnedToggled: any } const sortOptions = [ @@ -151,7 +179,10 @@ const sortOptions = [ { name: "Price: Low to High", href: "#", current: false }, { name: "Price: High to Low", href: "#", current: false }, ] -const subCategories = [{ name: "Favorites", href: "#" }] +const subCategories = [ + { name: "Favorites", href: "#" }, + { name: "Owned", href: "#" }, +] function classNames(...classes: any) { return classes.filter(Boolean).join(" ") @@ -165,10 +196,10 @@ const BeastMarketFilters: FC = ({ setMobileFiltersOpen, favoriteToggled, setFavoriteToggled, + ownedToggled, + setOwnedToggled, }) => { - // const [mobileFiltersOpen, setMobileFiltersOpen] = useState(false) - - useEffect(() => {}, [filters]) + const { loggedIn } = useAuth() type SelectedFilters = { dexNumber: [number] @@ -177,73 +208,35 @@ const BeastMarketFilters: FC = ({ element: [string] serialNumber: [number] } + const router = useRouter() + const { query } = router - //categoryId = dexNumber or skin... - const handleChange = (categoryId: any, optionValue: number | string) => { - console.log("CATEGORY IDDD", categoryId) - + const handleChange = ( + categoryId: any, + optionValue: number | string | string[] | any, + ) => { const removeCheckBox = (values: any, checkedValue: any) => { return values.filter((x: any) => x != checkedValue) } - let selectedFilter = selectedFilters as SelectedFilters + const categories = [ + "dexNumber", + "skin", + "starLevel", + "element", + "serialNumber", + ] - if (categoryId == "dexNumber") { - console.log("DexNumber added") - setSelectedFilters({ - ...selectedFilters, - dexNumber: selectedFilters.dexNumber.includes(optionValue) - ? removeCheckBox(selectedFilters.dexNumber, optionValue) - : [...selectedFilters.dexNumber, optionValue], - }) - } - if (categoryId == "skin") { - setSelectedFilters({ - ...selectedFilters, - skin: selectedFilters.skin.includes(optionValue) - ? removeCheckBox(selectedFilters.skin, optionValue) - : [...selectedFilters.skin, optionValue], - }) - } - if (categoryId == "starLevel") { - setSelectedFilters({ - ...selectedFilters, - starLevel: selectedFilters.starLevel.includes(optionValue) - ? removeCheckBox(selectedFilters.starLevel, optionValue) - : [...selectedFilters.starLevel, optionValue], - }) + if (!categories.includes(categoryId)) { + return } - if (categoryId == "element") { - setSelectedFilters({ - ...selectedFilters, - element: selectedFilters.element.includes(optionValue) - ? removeCheckBox(selectedFilters.element, optionValue) - : [...selectedFilters.element, optionValue], - }) - } - if (categoryId == "serialNumber") { - console.log("DexNumber added") - setSelectedFilters({ - ...selectedFilters, - serialNumber: selectedFilters.serialNumber.includes(optionValue) - ? removeCheckBox(selectedFilters.serialNumber, optionValue) - : [...selectedFilters.serialNumber, optionValue], - }) - } - // if (selectedFilter > 0) { - // selectedFilter = [...selectedFilter, optionValue] - // } - - console.log("UPDATED SELECTED FILTER", selectedFilter) - // setSelectedFilters({ - // ...selectedFilters, - // categoryId: selectedFilters.categoryId.includes(optionValue) - // ? removeCheckBox(selectedFilters.categoryId, optionValue) - // : [...selectedFilters.categoryId, optionValue], - // }) - - console.log(selectedFilters) + setSelectedFilters({ + ...selectedFilters, + [categoryId]: selectedFilters[categoryId].includes(optionValue) + ? removeCheckBox(selectedFilters[categoryId], optionValue) + : [...selectedFilters[categoryId], optionValue], + }) } return ( @@ -291,25 +284,27 @@ const BeastMarketFilters: FC = ({ - {/* Filters */} + {/* Filters for mobile*/}

    Categories

    -
      + @@ -347,28 +342,38 @@ const BeastMarketFilters: FC = ({
      {section.options?.map( (option: any, optionIdx: any) => ( - <> - - + + handleChange( + section.id, + option.value, + ) + } + className="h-4 w-4 rounded border-gray-300 focus:ring-indigo-500" - /> - - - + /> + + ), )}
      @@ -387,7 +392,7 @@ const BeastMarketFilters: FC = ({
      -
      +
      {/*

      New Arrivals

      */} @@ -452,102 +457,154 @@ const BeastMarketFilters: FC = ({
      -
      +

      Products

      - {/* Filters */} + {/* Filters for desktop */}

      Categories

      -
        +
          {subCategories.map((category) => ( -
        • - {category.name} - - { - setFavoriteToggled(!favoriteToggled) - }} - /> - - -
        • +
            + {category.name == "Owned" ? ( + <> + {loggedIn && ( +
          • + + {category.name} + + {category.name == "Owned" && ( + + { + setOwnedToggled(!ownedToggled) + }} + /> + + + )} +
          • + )} + + ) : ( +
          • + + {category.name} + + {category.name == "Favorites" && ( + + { + setFavoriteToggled(!favoriteToggled) + }} + /> + + + )} +
          • + )} +
          ))}
        - - {filters?.map((section: any) => ( - - {({ open }) => ( - <> -

        - - - {section.name} - - - {open ? ( - - -

        - -
        - {section.options?.map( - (option: any, optionIdx: any) => ( - + ) : ( + <> + {filters?.map((section: any) => ( + + {({ open }) => ( + <> +

        + + - - handleChange(section.id, option.value) - } - className="h-4 w-4 rounded border-gray-300 focus:ring-indigo-500" - /> - - - ), - )} -

        -
        - - )} -
        - ))} + {section.name} + + + {open ? ( + + + + +
        + {section.options?.map( + (option: any, optionIdx: any) => ( + + + handleChange( + section.id, + option.value, + ) + } + className="h-4 w-4 rounded border-gray-300 focus:ring-indigo-500" + /> + + + ), + )} +
        +
        + + )} + + ))} + + )}
      diff --git a/components/ui/BeastMarketHero/BeastMarketHero.tsx b/components/ui/BeastMarketHero/BeastMarketHero.tsx index f279184..3c25241 100644 --- a/components/ui/BeastMarketHero/BeastMarketHero.tsx +++ b/components/ui/BeastMarketHero/BeastMarketHero.tsx @@ -4,6 +4,7 @@ import BeastMarketSkinOverviewModal from "../BeastMarketSkinOverviewModal" import beastTemplates from "data/beastTemplates" import { FC, useState, Fragment, useEffect } from "react" import { useUser } from "@components/user/UserProvider" +import DappyImg from "public/139_normal.png" const Main = styled.main` display: flex; @@ -21,7 +22,7 @@ const Main = styled.main` const Header = styled.h1` font-size: 4rem; color: #fff; - max-width: 14ch; + // max-width: 14ch; text-transform: uppercase; line-height: 1; @media (max-width: 380px) { @@ -31,6 +32,7 @@ const Header = styled.h1` const P = styled.p` color: white; max-width: 56ch; + font-size: 1.2em; ` const H2 = styled.h2` font-size: 1.5rem; @@ -356,7 +358,7 @@ const ThumbnailDetailsFC: FC<{ > 50 FUSD - Place A Bid + Make offer setDialogOpen(!dialogOpen)} @@ -373,19 +375,18 @@ const BeastMarketHero: FC = ({ beast }) => { const [skinOverviewOpen, setSkinOverviewOpen] = useState(false) const { hunterData, beasts, highestSale } = useUser() - return ( <>
      {" "} -
      Discover The Beasts
      +
      Discover Beasts

      Basic Beasts is a collection of unique digital collectibles representing interactive beasts that can evolve, breed, and be loved.

      - + {/* */} setSkinOverviewOpen(true)}>

      {hunterData?.length}

      Hunters @@ -400,6 +401,7 @@ const BeastMarketHero: FC = ({ beast }) => {
      {" "} @@ -414,10 +416,11 @@ const BeastMarketHero: FC = ({ beast }) => { // beastTemplates[beastTemplateID as keyof typeof beastTemplates] // ?.marketThumbnail || thumbnail.src // } - src={ - "https://basicbeasts.mypinata.cloud/ipfs/" + - beastTemplates[691 as keyof typeof beastTemplates]?.image - } + // src={ + // "https://basicbeasts.mypinata.cloud/ipfs/" + + // beastTemplates[691 as keyof typeof beastTemplates]?.image + // } + src={DappyImg.src} /> {" "}
      diff --git a/components/ui/BeastMarketSkinOverviewModal/BeastMarketSkinOverviewModal.tsx b/components/ui/BeastMarketSkinOverviewModal/BeastMarketSkinOverviewModal.tsx index c266f8b..5af357d 100644 --- a/components/ui/BeastMarketSkinOverviewModal/BeastMarketSkinOverviewModal.tsx +++ b/components/ui/BeastMarketSkinOverviewModal/BeastMarketSkinOverviewModal.tsx @@ -7,9 +7,13 @@ import { toast } from "react-toastify" const Container = styled.div` align-items: center; + @media (max-width: 420px) { + padding: 0; + } ` const ItemInfo = styled.div` display: flex; + position: relative; padding: 1rem 2rem; align-items: center; // background-image: linear-gradient(to top, transparent, #ffdf7e); @@ -17,8 +21,11 @@ const ItemInfo = styled.div` justify-content: space-evenly; border-radius: 0.5rem; gap: 1px; - @media (max-width: 460px) { - flex-direction: column; + @media (max-width: 839px) { + padding: 0.5rem 10vw; + } + @media (max-width: 375px) { + padding: 0.5rem 5vw; } ` const Title = styled.h1` @@ -32,6 +39,9 @@ const Title = styled.h1` @media (max-width: 340px) { left: -10rem; } + @media (max-width: 839px) { + display: none; + } ` const H2 = styled.h2` @@ -54,9 +64,22 @@ const Item = styled.div` } ` const DialogPanel = styled(Dialog.Panel)` - padding: 20px; + padding: 80px; background: #1d1d21; color: white; + @media (max-width: 1024px) { + padding: 50px 60px; + } + @media (max-width: 839px) { + padding: 5px 0; + width: 90vw; + } + @media (max-width: 420px) { + width: 95%; + } + @media (max-width: 375px) { + width: 100%; + } ` const Panel = styled.div` display: grid; @@ -66,58 +89,220 @@ const Panel = styled.div` @media (min-width: 840px) { grid-template-columns: 1fr 1fr; } + @media (max-width: 839px) { + gap: 0; + } ` const Card = styled.div` padding: 1rem; border-radius: 10px; - text-align: center; + + text-align: end; + &:nth-child(3), + &:nth-child(5) { + text-align: start; + } @media (min-width: 840px) { &:first-child { grid-column: 1/3; } } + + @media (max-width: 839px) { + padding: 1rem 0; + } ` const P = styled.p` margin: 0 1.2rem; font-size: 1.75rem; line-height: 1; + @media (max-width: 839px) { + text-align: end; + } +` + +const Img = styled.img` + position: absolute; + width: 35%; + top: -94.5%; + + &.Normal { + transform: scaleX(-1) translateX(-10%); + top: -94%; + } + + &.Metallic, + &.Normal { + left: 0px; + } + + &.Metallic { + transform: translateX(-10%); + } + + &.Cursed { + left: 88.5%; + top: 50%; + transform: translateY(-62%) rotate(90deg); + } + + &.Shiny { + top: auto; + bottom: -94.5%; + rotate: 180deg; + left: 0px; + } + + &.Mythic { + right: 0; + transform: translateX(10%); + } + + @media (max-width: 839px) { + &.Mythic, + &.Shiny, + &.Cursed, + &.Metallic, + &.Normal { + bottom: auto; + right: auto; + top: -108%; + transform: translate(0, 0) rotate(0deg) scaleX(-1); + rotate: 0deg; + left: 0; + width: 98.1px; + height: 98.1px; + // scale: scaleX(1) + } + } +` + +const CloseModal = styled.div` + @media (max-width: 421px) { + transform: translateY(-5px); + } ` type Props = { // beastID: any open: boolean setOpen: any + beasts: any // had to pass the beasts array // fetchUserBeasts: any // beastModalSetOpen: any // setDisplayNickname: any // beastName: any } -const BeastMarketSkinItem: FC<{ background: any }> = ({ background }) => { +const BeastMarketSkinItem: FC<{ + background: any + beasts: any + imgSrc: any + imgClass: any +}> = ({ background, beasts, imgSrc, imgClass }) => { + const getFloorPrice = () => { + // function to get floor price + const prices = beasts + ?.filter( + (beast: any) => beast.price !== null && beast.price !== undefined, + ) //filter for the beasts that do have a price + .map((beast: any) => parseFloat(beast.price)) // transform string into number + + return prices?.length > 0 ? "$" + formatNumber(Math.min(...prices)) : "--" // returns the price + } + + // Alex: Format numbers everywhere, TODO + const formatNumber = (number: number) => { + if (number >= 1000000) { + return (number / 1000000).toFixed(1) + "M" + } else if (number >= 100000) { + return (number / 1000).toFixed(0) + "k" + } else if (number >= 10000) { + return (number / 1000).toFixed(1) + "k" + } else if (number >= 1000) { + return (number / 1000).toFixed(0) + "k" + } else { + return number.toString() + } + } + + const getHunters = () => { + // function to get the nr. of hunters + // returns new set (a set can only have unique values) of the array that contains all the currentOwners + return [ + ...new Set( + beasts + ?.filter((beast: any) => beast.currentOwner) + .map((beast: any) => beast.currentOwner), + ), + ].length + } + return ( -

      78

      Hunters +

      {getHunters()}

      Hunters
      -

      78K

      Beasts +

      {beasts?.length}

      Beasts
      -

      78K

      Floor +

      {getFloorPrice()}

      Floor
      +
      ) } + const BeastMarketSkinOverviewModal: FC = ({ // beastID, open, setOpen, + beasts, // fetchUserBeasts, // beastModalSetOpen, // setDisplayNickname, // beastName, }) => { + // Refactoring + const skinsMap = [ + { + name: "Normal", + background: "#E4E8E7", + src: "013_normal.png", + class: "Normal", + }, + { + name: "Metallic Silver", + background: "#C1D3E1", + src: "013_metallic_silver_face.gif", + class: "Metallic", + }, + { + name: "Cursed Black", + background: "#FCECF8", + src: "013_cursed_black_transparent_face.png", + class: "Cursed", + }, + { + name: "Shiny Gold", + background: "#FFF4CD", + src: "013_shiny_gold_face.gif", + class: "Shiny", + }, + { + name: "Mythic Diamond", + background: "#BDEBFB", + src: "013_mystery.png", + class: "Mythic", + }, + ] + + function getBeastsBySkin(skinName: string) { + return beasts?.filter((beast: any) => beast.skin == skinName) + } + return ( @@ -148,8 +333,8 @@ const BeastMarketSkinOverviewModal: FC = ({ style={{ borderRadius: "20px" }} className="relative rounded-lg text-left shadow-xl transform transition-all " > -
      setOpen(false)} > {/* = ({ icon={faChevronUp} /> */}
      x
      -
      + BASIC BEASTS SKINS{" "} - -

      Normal

      -
      - -

      Metallic Silver

      - -
      - -

      Cursed Black

      - -
      - - {" "} -

      Shiny Gold

      - -
      - -

      Mythic Diamond

      - -
      {" "} + {skinsMap.map((skin: any, idx: number) => { + //maps through the skinsMap and returns a new Card for each object + return ( + +

      {skin.name}

      + +
      + ) + })}
      diff --git a/components/ui/BeastMarketThumbnail/BeastMarketThumbnail.tsx b/components/ui/BeastMarketThumbnail/BeastMarketThumbnail.tsx index 0bf513e..e2ecb70 100644 --- a/components/ui/BeastMarketThumbnail/BeastMarketThumbnail.tsx +++ b/components/ui/BeastMarketThumbnail/BeastMarketThumbnail.tsx @@ -44,9 +44,7 @@ const BeastMarketThumbnail: FC = ({ ...props }: BeastThumbnailProps) => { return ( - console.log("Inview:", inView)} - > +
      <> diff --git a/components/ui/BeastModalView/BeastModalView.tsx b/components/ui/BeastModalView/BeastModalView.tsx index 1479356..05a0c09 100644 --- a/components/ui/BeastModalView/BeastModalView.tsx +++ b/components/ui/BeastModalView/BeastModalView.tsx @@ -153,8 +153,6 @@ const Content = styled.div` width: 576px; - overflow-y: auto; - background: #fff; padding: 3vw; font-size: 1.2em; @@ -168,7 +166,7 @@ const Content = styled.div` const Img = styled.img` width: 160px; margin: auto; - top: -60px; + top: -70px; position: relative; user-drag: none; -webkit-user-drag: none; @@ -415,9 +413,10 @@ const Select = styled.select` width: 100%; // border: 1px solid rgb(209 213 219); &:focus { - --tw-ring-color: rgb(99 102 241); + // --tw-ring-color: rgb(99 102 241); border-color: rgb(99 102 241); } + outline: none; ` const Button = styled.button` @@ -427,6 +426,7 @@ const Button = styled.button` padding: 4px 20px 5px; border-radius: 12px; font-size: 0.8em; + margin: 0.2rem 0 0.2rem 0; text-transform: capitalize; &:hover { color: rgb(255, 255, 255); @@ -478,6 +478,12 @@ type Props = { allEvolutionPairs: any getPersonalDexicon: any walletAddress: any + sushiBalance: any + emptyPotionBottleBalance: any + poopBalance: any + lovePotionBalance: any + beasts: any + selectFilter: any } const tabs = [ @@ -504,6 +510,12 @@ const BeastModalView: FC = ({ allEvolutionPairs, getPersonalDexicon, walletAddress, + sushiBalance, + emptyPotionBottleBalance, + poopBalance, + lovePotionBalance, + beasts, + selectFilter, }) => { const [open2, setOpen2] = useState(false) const [filter, setFilter] = useState("Info") @@ -569,6 +581,7 @@ const BeastModalView: FC = ({ import Evolution from 0xEvolution import BasicBeasts from 0xBasicBeasts import FUSD from 0xFUSD + import FungibleToken from 0xFungibleToken pub fun hasEvolver(_ address: Address): Bool { return getAccount(address) @@ -668,6 +681,46 @@ const BeastModalView: FC = ({ } } + interface Beast { + beastTemplateID: number + starLevel: number + // other properties of the beast + } + + function filterBeasts(beasts: any, starLevel: number): any { + return beasts + .filter((beast2: any) => { + const { beastTemplateID, starLevel: beastStarLevel } = beast2 + if (beastStarLevel < starLevel) { + return false + } + if (beastStarLevel === 1) { + return ( + beastTemplateID === beast?.beastTemplateID || + beastTemplateID === beast?.beastTemplateID + 1 || + beastTemplateID === beast?.beastTemplateID + 2 + ) + } + if (beastStarLevel === 2) { + return ( + beastTemplateID === beast?.beastTemplateID - 1 || + beastTemplateID === beast?.beastTemplateID || + beastTemplateID === beast?.beastTemplateID + 1 + ) + } + if (beastStarLevel === 3) { + return ( + beastTemplateID === beast?.beastTemplateID - 2 || + beastTemplateID === beast?.beastTemplateID - 1 || + beastTemplateID === beast?.beastTemplateID + ) + } + return beastTemplateID === beast?.beastTemplateID + }) + .filter((beast2: any) => beast?.id !== beast2.id) + .filter((beast2: any) => beast?.sex !== beast2.sex) + } + return ( @@ -713,11 +766,17 @@ const BeastModalView: FC = ({
      {beast != null ? ( @@ -838,7 +897,7 @@ const BeastModalView: FC = ({ ? "border-rose-500 text-rose-600" : "border-pink-500 text-pink-600" : "border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300", - "w-1/4 py-4 px-1 text-center border-b-2 font-medium text-md", + "w-1/4 py-4 px-1 text-center border-b-2 font-medium text-md focus:outline-none focus-visible:outline-none", )} aria-current={ tab.name === filter ? "page" : undefined @@ -961,7 +1020,7 @@ const BeastModalView: FC = ({ same skin and star level to do Evolution
      - + @@ -1129,16 +1188,56 @@ const BeastModalView: FC = ({ <> )} {filter === "Breeding" ? ( - // + // <> + // {filterBeasts(beasts, beast?.starLevel).length > + // 0 ? ( + // + // ) : ( + // + // + // You need a beast of the opposite sex for + // breeding + // + // + // + // )} + // = ({ fontSize: "1em", }} > - Coming soon + Coming ) : ( + // + // + // Coming + // + // <> )} {filter === "Trade" && ( diff --git a/components/ui/BeastTab/BeastTab.tsx b/components/ui/BeastTab/BeastTab.tsx index d50dddb..c1f8ed5 100644 --- a/components/ui/BeastTab/BeastTab.tsx +++ b/components/ui/BeastTab/BeastTab.tsx @@ -516,29 +516,11 @@ type Props = { allEvolutionPairs: any getPersonalDexicon: any walletAddress: any -} - -type Beast = { - beastTemplateID: number - generation: number - dexNumber: number - name: String - description: String - image: String - imageTransparentBg: String - animationUrl: String - externalUrl: String - rarity: String - skin: String - starLevel: number - asexual: boolean - breedableBeastTemplateID: number - maxAdminMintAllowed: number - ultimateSkill: String - basicSkills: String[] - elements: String[] - data: any - id: any + sushiBalance: any + emptyPotionBottleBalance: any + poopBalance: any + lovePotionBalance: any + selectFilter: any } const BeastTab: FC = ({ @@ -549,6 +531,11 @@ const BeastTab: FC = ({ allEvolutionPairs, getPersonalDexicon, walletAddress, + sushiBalance, + emptyPotionBottleBalance, + poopBalance, + lovePotionBalance, + selectFilter, }) => { // const query = useQuery() // const beasts = @@ -672,6 +659,12 @@ const BeastTab: FC = ({ allEvolutionPairs={allEvolutionPairs} getPersonalDexicon={getPersonalDexicon} walletAddress={walletAddress} + sushiBalance={sushiBalance} + emptyPotionBottleBalance={emptyPotionBottleBalance} + poopBalance={poopBalance} + lovePotionBalance={lovePotionBalance} + beasts={beasts} + selectFilter={selectFilter} /> setEvolutionModalOpen(false)} @@ -679,7 +672,7 @@ const BeastTab: FC = ({ packId={selectedBeast?.beastTemplateID || "1"} evolvedBeastId={evolvedBeastId} /> - {displayBeasts != null ? ( + {displayBeasts?.length > 0 ? (
        ` + background-color: #212127; + /* background-color: #243540; */ + height: 6.5vw; + border-radius: 0.5rem; + margin-bottom: 1.5%; + + display: grid; + grid-template-rows: 100%; + grid-template-columns: 20% 38% 40%; + align-items: center; + gap: 2%; + + transition: all 0.2s ease-in; + + & h3 { + color: #e5be24; + } + + &.chosen { + background: ${(props) => props.bgColor}; + color: black; + + & h3 { + color: black; + } + } + + &:hover { + scale: 1.05; + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) + 14 0, + pointer !important; + } + + @media (max-width: 1000px) { + height: 10vw; + } + + @media (max-width: 550px) { + height: 8vh; + grid-template-columns: 20% 30% 46%; + } +` + +const SkinImg = styled.img` + grid-column: 1; + height: 100%; +` + +const SkinName = styled.h2` + grid-column: 2; +` + +const SkinInfo = styled.div` + grid-column: 3; + + display: grid; + grid-template-columns: 50% 50%; + grid-template-rows: auto auto; + justify-content: space-between; + align-items: center; + + & p { + grid-column: 1; + width: fit-content; + } + + & h3 { + grid-column: 2; + width: fit-content; + display: flex; + align-items: right; + } +` + +const BeastTemplateContent: FC = ({ + currBeast, + beastsArr, + beasts, + beastTemplatesArr, +}) => { + const router = useRouter() + console.log(beasts) + + function getFloorPrice(beast: any) { + const beastsWithPrice = beasts?.filter( + (x: any) => x.beastTemplateID == beast.beastTemplateID && x.price, + ) + if (beastsWithPrice) { + let priceArray = [] + for (let i in beastsWithPrice) { + priceArray.push(beastsWithPrice[i].price) + } + let lowest = Math.min(...priceArray) + + return lowest == Infinity ? "--" : lowest + } + } + + function getPropPercentage(beast: any, property: any) { + const beastsWithProp = beasts?.filter((x: any) => { + let afterFiltering + switch (property) { + case "elements": + afterFiltering = x.elements[0] == beast.elements[0] + break + case "skin": + afterFiltering = x.skin == beast.skin + break + } + return afterFiltering + }).length + const allBeasts = beasts.length + let percentage = (beastsWithProp / allBeasts) * 100 + percentage = Math.trunc(percentage) + // console.log(percentage) + return percentage + } + + function getRarity(currBeast: any) { + // console.log(beastTemplatesArr) + // console.log(currBeast) + const beastsWithRarity = beastTemplatesArr?.filter( + (x: any) => x.rarity == currBeast.rarity, + ).length + + const allSkins = beastTemplatesArr.length + // console.log("1 " + beastsWithRarity) + // console.log("2 " + allSkins) + + let rarePercentage = (beastsWithRarity / allSkins) * 100 + rarePercentage = Math.trunc(rarePercentage) + // console.log(percentage) + return rarePercentage + } + + const ToggleCard = ({ + icon, + title, + content, + defaultActive, + }: { + icon: any + title: any + content: any + defaultActive: Boolean + }) => { + const [isActive, setIsActive] = useState(defaultActive) + + return ( + <> +
        setIsActive(!isActive)}> +
        + + {title} +
        + +
        + {isActive ? ( + + ) : ( + + )} +
        +
        + {isActive && {content}} + + ) + } + + const Description = () => { + return ( + <> +

        {currBeast.description}

        + + ) + } + + const Properties = () => { + return ( + <> + + +

        Skin

        +

        {currBeast ? currBeast.skin : "Loading..."}

        +

        {getPropPercentage(currBeast, "skin")}% have this trait

        +
        + +

        Element

        +

        {currBeast ? currBeast.elements : "Loading..."}

        +

        {getPropPercentage(currBeast, "elements")}% have this trait

        +
        + +

        Rarity

        +

        {currBeast ? currBeast.rarity : "Loading..."}

        +

        {getRarity(currBeast)}% have this trait

        +
        + +

        Generation

        +

        1

        +

        100% have this trait

        +
        + +

        basic skills

        + {currBeast ? ( + <> +

        {currBeast.basicSkills[0]}

        +

        {currBeast.basicSkills[1]}

        +

        {currBeast.basicSkills[2]}

        + + ) : ( + "Loading skills..." + )} +
        + +

        Ultimate skill

        +

        + {currBeast + ? currBeast.ultimateSkill + : "Loading ultimate skill..."} +

        +
        +
        + + ) + } + + const Overview = () => { + return ( + <> + + {beastsArr?.map((beast: any) => ( + { + router.push({ + pathname: `/beast/${ + beast.dexNumber + "-" + beast.skin.replace(/\s/g, "-") + }`, + }) + }} + > + + {beast?.skin} + +

        Floor

        +

        {getFloorPrice(beast)}

        + +

        Circulation

        +

        + { + beasts?.filter( + (x: any) => x.beastTemplateID == beast.beastTemplateID, + ).length + } +

        +
        +
        + ))} +
        + + ) + } + + return ( + + + + + + + + + + + + + + + + ) +} + +export default BeastTemplateContent diff --git a/components/ui/BeastTemplateContent/index.ts b/components/ui/BeastTemplateContent/index.ts new file mode 100644 index 0000000..cb90bab --- /dev/null +++ b/components/ui/BeastTemplateContent/index.ts @@ -0,0 +1 @@ +export { default } from "./BeastTemplateContent" diff --git a/components/ui/BeastTemplateHero/BeastTemplateHero.tsx b/components/ui/BeastTemplateHero/BeastTemplateHero.tsx new file mode 100644 index 0000000..2f48964 --- /dev/null +++ b/components/ui/BeastTemplateHero/BeastTemplateHero.tsx @@ -0,0 +1,514 @@ +import { FC } from "react" +import styled from "styled-components" +import star from "public/basic_starLevel.png" +import arrow from "public/arrowIcon.svg" +import infoIcon from "public/infoIcon.svg" + +type Props = { + beast: any + beasts: any +} + +// get all the beasts => filter beasts array by beast.dexNumber and pass the new array to the beastTemplateHero component + +const Container = styled.section` + margin: 2.5vw 12.5vw; + padding-top: 2rem; + color: white; + line-height: normal; + + display: grid; + grid-template-columns: 1fr 1fr; + grid-template-rows: auto auto auto; + gap: 0 4vw; + + & h1 { + font-size: 4rem; + } + & h2 { + font-size: 2.5rem; + } + & h3 { + font-size: 1.5rem; + display: inline; + } + & p { + font-size: 1rem; + } + + @media (max-width: 1450px) { + h1 { + font-size: 3.5rem; + } + h3 { + font-size: 1.2rem; + } + } + + @media (max-width: 1000px) { + grid-template-columns: 75vw; + grid-template-rows: auto auto auto auto; + + gap: 0 2vw; + + h1 { + font-size: 3.1rem; + } + + h2 { + font-size: 2.3rem; + } + } + + @media (max-width: 650px) { + h2 { + font-size: 2rem; + } + grid-template-columns: 80vw; + margin: 0 10vw; + gap: 0; + } +` + +const Header = styled.div` + grid-column: 1; + grid-row: 1 / span 2; + + @media (max-width: 1000px) { + grid-row: 1; + justify-items: center; + } +` + +const BeastImgContainer = styled.div` + // background-color: #ffd966; + background: ${(props) => props.backgroundColor}; + border-radius: 1rem; + position: relative; + top: 0; + left: 0; +` +const Stars = styled.div` + height: 2rem; + position: absolute; + z-index: 2; + margin: 1rem; + + @media (max-width: 800px) { + height: 1rem; + } +` + +const Star = styled.img` + max-height: 100%; + max-width: 100%; + object-fit: contain; + display: inline-block; +` + +const BeastImg = styled.img` + height: auto; + width: 35.5vw; + + @media (max-width: 1000px) { + margin: 0 auto; + } +` + +const BeastNameDex = styled.h1` + grid-column: 1 / span 2; + grid-row: 3; + margin-top: 0.5rem; + + @media (max-width: 1000px) { + grid-column: 1; + grid-row: 2; + } + + /* @media (max-width: 1000px) { + grid-column: 1; + grid-row: 2; + } */ +` + +const Stats = styled.div` + grid-column: 2; + text-align: center; + + display: grid; + + grid-template-columns: 1fr 1fr; + grid-template-rows: auto; + margin: 0 1rem; + align-items: center; + + /* @media (max-width: 1000px) { + grid-row: 1; + height: 80%; + margin: auto 1rem; + } */ + + @media (max-width: 1000px) { + grid-column: 1; + grid-row: 3; + margin: 1rem 0; + gap: 0 20vw; + } + /* + @media (max-width: 650px) { + margin: 1rem 0; + } */ +` + +const StatsLabel = styled.div` + text-transform: uppercase; + text-align: center; + grid-column: 1 / span 2; + + @media (max-width: 650px) { + text-align: left; + border-bottom: 2px solid #a3a4a5; + } +` + +const StatsCol1 = styled.div` + grid-column: 1; + text-align: left; + display: flex; + align-items: center; +` + +const StatsCol2 = styled.div` + grid-column: 2; + text-align: right; + color: #e4be23; +` + +const Info = styled.img` + height: 1rem; + width: auto; + display: inline; + padding-left: 0.5rem; +` + +const Evolutions = styled.div` + grid-column: 2; + grid-row: 2; + margin-top: 3rem; + + display: grid; + grid-template-rows: auto auto; + grid-auto-columns: auto auto auto auto auto; + /* align-content: center; */ + align-items: center; + gap: 1vw; + + @media (max-width: 1000px) { + grid-column: 1; + grid-row: 4; + gap: 4vw; + } + + @media (max-width: 650px) { + gap: 2vw; + } +` +const EvolLabel = styled.div` + text-transform: uppercase; + text-align: center; + grid-column: 1 / span 5; + + @media (max-width: 650px) { + text-align: left; + border-bottom: 2px solid #a3a4a5; + } +` + +const EvolutionCard = styled.div` + height: fit-content; + width: auto; + background-color: #212127; + /* background-color: #243540; */ + border-radius: 1rem; + text-align: center; + padding: 1rem 1.5rem; + + transition: all 0.2s ease-in; + + &:hover { + scale: 1.05; + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) + 14 0, + pointer !important; + } + + &.chosen { + background: ${(props) => props.bgColor}; + color: black; + } + + @media (max-width: 650px) { + padding: 0.5rem 1rem; + } +` +const EvolBeastImg = styled.img` + height: auto; + width: auto; + + /* @media (max-width: 1000px) { + height: 80%; + width: 80%; + padding: 0; + margin: 0; + } */ +` + +const EvolBeastName = styled.h3` + width: auto; +` + +const EvolBeastLvl = styled.div` + height: 1rem; + width: auto; + + @media (max-width: 650px) { + height: 0.8rem; + } +` + +const Arrow = styled.img` + width: auto; + display: flex; + transform: rotate(-90deg); + height: auto; +` + +const BeastTemplateHero: FC = ({ beast, beasts }) => { + function getFloorPrice() { + const beastsWithPrice = beasts?.filter( + (x: any) => x.beastTemplateID == beast.beastTemplateID && x.price, + ) + if (beastsWithPrice) { + let priceArray = [] + for (let i in beastsWithPrice) { + priceArray.push(beastsWithPrice[i].price) + } + let lowest = Math.min(...priceArray) + + return lowest == Infinity ? "--" : lowest + } + } + + function getDexLength() { + const dexLength = beast.dexNumber.toString().length + let newDexNumber = beast.dexNumber + + let zeroes + + switch (dexLength) { + case 1: + zeroes = "00" + newDexNumber = "00" + newDexNumber + break + case 2: + zeroes = "0" + newDexNumber = "0" + newDexNumber + break + default: + zeroes = "" + } + return newDexNumber + } + + function getMaxMinted() { + let maxMint + switch (beast.skin) { + case "Metallic Silver": + maxMint = Infinity + break + default: + maxMint = beast.maxAdminMintAllowed + } + return maxMint + } + + function maxMintByStar() { + const star = beast.starLevel + let newMaxMint + switch (star) { + case 1: + newMaxMint = getMaxMinted() + break + case 2: + newMaxMint = getMaxMinted() / 3 + break + case 3: + newMaxMint = getMaxMinted() / 9 + break + default: + } + + newMaxMint = Math.trunc(newMaxMint) + return newMaxMint == Infinity ? "--" : newMaxMint + } + + getDexLength() + + return ( +
        + +
        + + + {Array(beast?.starLevel) + .fill(0) + .map((_, i) => ( + + ))} + + + +
        + + {beast.name} #{getDexLength()} + + + + +

        Stats

        +
        + +

        Floor price

        + +
        + + +

        {getFloorPrice()} FUSD

        +
        + +

        Listed

        + +
        + +

        + { + beasts?.filter( + (x: any) => + x.beastTemplateID == beast.beastTemplateID && x.price, + ).length + } +

        +
        + +

        Circulation

        + +
        + +

        + { + beasts?.filter( + (x: any) => x.beastTemplateID == beast.beastTemplateID, + ).length + } +

        +
        + +

        Max Supply

        + +
        + +

        {maxMintByStar()}

        +
        +
        + {/**TODO show evolutionary line */} + + +

        Evolutions

        +
        + + + {beast.name} + + {Array(beast?.starLevel) + .fill(0) + .map((_, i) => ( + + ))} + + + + + + {beast.name} + + {Array(beast?.starLevel) + .fill(0) + .map((_, i) => ( + + ))} + + + + + + {beast.name} + + {Array(beast?.starLevel) + .fill(0) + .map((_, i) => ( + + ))} + + +
        +
        +
        + ) +} + +export default BeastTemplateHero diff --git a/components/ui/BeastTemplateHero/index.ts b/components/ui/BeastTemplateHero/index.ts new file mode 100644 index 0000000..8c5f191 --- /dev/null +++ b/components/ui/BeastTemplateHero/index.ts @@ -0,0 +1 @@ +export { default } from "./BeastTemplateHero" diff --git a/components/ui/Breeding/BreedableBeastThumbnail.tsx b/components/ui/Breeding/BreedableBeastThumbnail.tsx new file mode 100644 index 0000000..784fe4d --- /dev/null +++ b/components/ui/Breeding/BreedableBeastThumbnail.tsx @@ -0,0 +1,124 @@ +import React, { FC } from "react" +import styled from "styled-components" + +import star from "public/basic_starLevel.png" +import beastTemplates from "data/beastTemplates" + +const Container = styled.div` + width: 110px; + height: 110px; + background: ${(props) => props.backgroundColor || "#ffe8a3"}; + color: ${(props) => props.outset || "#c5b16e"}; + border-radius: 10px; + border: solid 1px ${(props) => props.inset || "#ffdda4"}; + padding: 5px; + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) + 14 0, + pointer !important; + + &:hover { + transform: scale(0.95); + } + box-shadow: ${(props) => + props.selected + ? `inset 0px 0px 20px ${props.outset}, 0px 0px 3px 3px ${props.outset}` + : "none"}; + /* scale: ${(props) => (props.selected ? "1.05" : "none")}; */ +` + +const Img = styled.img` + max-width: 60px; + user-drag: none; + margin: 0 auto; + -webkit-user-drag: none; +` + +const ThumbnailDetails = styled.div` + display: table; + clear: both; + width: 100%; + padding: 0px 5px; +` + +const ThumbnailLabel = styled.div` + margin-top: 2px; + float: left; +` + +const NicknameLabel = styled.div` + position: relative; + margin-top: -5px; + font-size: 12px; + margin-left: 5px; + margin-bottom: -13px; +` + +const Gender = styled.div` + margin-top: 8px; + float: right; + font-size: 14px; +` + +type Props = { beast: any; selected: any } + +const BreedableBeastThumbnail: FC = ({ beast, selected }) => { + return ( + + <> + {beast?.nickname === beast?.name ? ( + <> + ) : ( + {beast?.nickname} + )} + + #{beast?.serialNumber} + {beast?.sex === "Male" ? "♂" : "♀"} + + + + + ) +} +export default BreedableBeastThumbnail diff --git a/components/ui/Breeding/Breeding.tsx b/components/ui/Breeding/Breeding.tsx index a8f067e..9483912 100644 --- a/components/ui/Breeding/Breeding.tsx +++ b/components/ui/Breeding/Breeding.tsx @@ -4,18 +4,32 @@ import React, { FC, useEffect, useState } from "react" import styled from "styled-components" import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" import EvolvableBeastThumbnail from "../EvolvableBeastThumbnail" - import { faHeart } from "@fortawesome/free-solid-svg-icons" - import picture from "public/beasts/001_normal.png" import scroll from "public/beasts/001_unknown.png" -import potion from "/public/love_potion.png" +import potion from "/public/love_potion.gif" import { toast } from "react-toastify" import MakeLovePotionModal from "../MakeLovePotionModal" import EggObtainedModal from "../EggObtainedModal" import beastTemplates from "data/beastTemplates" +import SelectBreedingBeastModal from "./SelectBreedingBeastModal" +import { + send, + transaction, + args, + arg, + payer, + proposer, + authorizations, + limit, + authz, + decode, + tx, +} from "@onflow/fcl" +import { toastStatus } from "@framework/helpers/toastStatus" +import * as t from "@onflow/types" -const Wrapper = styled.section` +const Wrapper = styled.div` display: flex; flex-direction: column; justify-content: space-between; @@ -23,9 +37,12 @@ const Wrapper = styled.section` // height: 100%; padding-bottom: 2rem; margin-top: 1rem; + height: 300px; + // overflow-y: auto; ` const H2 = styled.h2` color: grey; + font-size: 1.5em; ` const BreedingSpot = styled.div` display: grid; @@ -38,15 +55,25 @@ const BreedingSpot = styled.div` ` const Img = styled.img` max-width: 10rem; + margin-bottom: 10px; ` const ImgDiv = styled.div` text-align: center; ` + +const SelectableBeast = styled.div` + text-align: center; + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) + 14 0, + pointer !important; +` + const PotionDiv = styled.div` width: max-content; cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) 14 0, pointer !important; + margin-top: 30px; ` const Potion = styled.div` position: relative; @@ -65,8 +92,8 @@ const Potion = styled.div` display: block; position: absolute; top: 50%; - left: -51%; - width: 3.5rem; + left: -31%; + width: 1.5rem; height: 1px; background: #ebebe9; } @@ -75,8 +102,8 @@ const Potion = styled.div` display: block; position: absolute; top: 50%; - right: -51%; - width: 3.5rem; + right: -31%; + width: 1.5rem; height: 1px; background: #ebebe9; } @@ -93,18 +120,18 @@ const PotionP = styled.p` font-size: 1rem; ` const RequiredNumber = styled.span` - color: #dc8494; + // color: #dc8494; ` const BreedButton = styled.button` position: relative; border: 1px solid ${(props) => props.buttonColors.buttonBorder}; border-radius: 0.25rem; - padding: 0.5rem 1rem; + padding: 1.5rem; width: max-content; line-height: 0; background: ${(props) => props.buttonColors.buttonBackground}; color: ${(props) => props.buttonColors.buttonColor}; - font-size: 1rem; + font-size: 1.5em; &::before { content: ""; display: block; @@ -119,8 +146,8 @@ const BreedButton = styled.button` const ListWrapper = styled.div` width: 100%; - overflow: hidden; - overflow-y: scroll; + // overflow: hidden; + // overflow-y: scroll; // height: 270px; margin-top: 15px; -ms-overflow-style: none; /* IE and Edge */ @@ -130,38 +157,53 @@ const ListWrapper = styled.div` } padding: 5px; ` +const Gender = styled.div` + font-size: 14px; +` type Props = { - evolvableBeasts: any + breedableBeasts: any beast: any makeLovePotionModalOpen: any setMakeLovePotionModalOpen: any eggObtainedModalOpen: any setEggObtainedModalOpen: any + sushiBalance: any + emptyPotionBottleBalance: any + poopBalance: any + lovePotionBalance: any } const Breeding: FC = ({ - evolvableBeasts, + breedableBeasts, beast, makeLovePotionModalOpen, setMakeLovePotionModalOpen, eggObtainedModalOpen, setEggObtainedModalOpen, + sushiBalance, + emptyPotionBottleBalance, + poopBalance, + lovePotionBalance, }) => { const [beastSelected, setBeastSelected] = useState(false) const [selectedBeasts, setSelectedBeasts] = useState([]) const [serialOneSelected, setSerialOneSelected] = useState(false) + const [open, setOpen] = useState(false) + + const [selectedGender, setSelectedGender] = useState() + const [selectedSerial, setSelectedSerial] = useState() - const potions = 200 + const potions = 1 const buttonColors = () => { let buttonBorder let buttonColor let buttonBackground { - potions >= 200 && beastSelected == true + false ? ((buttonBorder = "#d97586"), (buttonColor = "#d97586"), (buttonBackground = "#facdd7")) @@ -187,30 +229,141 @@ const Breeding: FC = ({ return beastImage } - const handleChange = (id: any, serial: any) => { - if (selectedBeasts.includes(id)) { - //remove - setSelectedBeasts(selectedBeasts.filter((beast: any) => beast != id)) - setBeastSelected(false) - // Check serial one - if (serial == 1) { - setSerialOneSelected(false) - toast.success("Serial #1 deselected") - } - } else if (selectedBeasts.length < 1) { - //add - setSelectedBeasts((selectedBeasts: any) => [...selectedBeasts, id]) - setBeastSelected(true) - // Check serial one - if (serial == 1) { - setSerialOneSelected(true) - toast.warning("Serial #1 selected for breeding") - } + // const handleChange = (id: any, serial: any) => { + // if (selectedBeasts.includes(id)) { + // //remove + // setSelectedBeasts(selectedBeasts.filter((beast: any) => beast != id)) + // setBeastSelected(false) + // // Check serial one + // if (serial == 1) { + // setSerialOneSelected(false) + // toast.success("Serial #1 deselected") + // } + // } else if (selectedBeasts.length < 1) { + // //add + // setSelectedBeasts((selectedBeasts: any) => [...selectedBeasts, id]) + // setBeastSelected(true) + // // Check serial one + // if (serial == 1) { + // setSerialOneSelected(true) + // toast.warning("Serial #1 selected for breeding") + // } + // } + // } + + const { fetchHunterData } = useUser() + + const breed = async () => { + const id = toast.loading("Initializing...") + + var ID1 = 0 + var ID2 = 0 + + if (selectedGender == "Male") { + ID1 = beast?.id + ID2 = selectedBeasts[0] + } else { + ID1 = selectedBeasts[0] + ID2 = beast?.id + } + + try { + const res = await send([ + transaction(` + import LovePotionMinter from 0xLovePotionMinter + import LovePotion from 0xLovePotion + import Breeding from 0xBreeding + import BasicBeasts from 0xBasicBeasts + import Egg from 0xEgg + import NonFungibleToken from 0xNonFungibleToken + import MetadataViews from 0xMetadataViews + + transaction(matronID: UInt64, sireID: UInt64) { + + prepare(acct: AuthAccount) { + + if acct.borrow<&Egg.Collection{Egg.EggCollectionPublic}>(from: Egg.CollectionStoragePath) == nil { + acct.save(<- Egg.createEmptyCollection(), to: Egg.CollectionStoragePath) + acct.unlink(Egg.CollectionPublicPath) + acct.link<&Egg.Collection{NonFungibleToken.Receiver, + NonFungibleToken.CollectionPublic, + Egg.EggCollectionPublic, + MetadataViews.ResolverCollection}> + (Egg.CollectionPublicPath, target: Egg.CollectionStoragePath) + } + + let eggCollectionRef = acct.borrow<&Egg.Collection>(from: Egg.CollectionStoragePath) + ?? panic("Couldn't get a reference to the egg collection") + + let lovePotionCollectionRef = acct.borrow<&LovePotion.Collection>(from: LovePotion.CollectionStoragePath) + ?? panic("Couldn't get a reference to the Love Potion collection") + + let beastCollectionRef = acct.borrow<&BasicBeasts.Collection>(from: BasicBeasts.CollectionStoragePath) + ?? panic("Couldn't get a reference to the beast collection") + + let beastReceiver = acct.getCapability<&BasicBeasts.Collection{BasicBeasts.BeastCollectionPublic}>(BasicBeasts.CollectionPublicPath) + + let IDs = lovePotionCollectionRef.getIDs() + + let lovePotion <- lovePotionCollectionRef.withdraw(withdrawID: IDs[0]) as! @LovePotion.NFT + + let matron <- beastCollectionRef.withdraw(withdrawID: matronID) as! @BasicBeasts.NFT + let sire <- beastCollectionRef.withdraw(withdrawID: sireID) as! @BasicBeasts.NFT + + let egg <- Breeding.publicBreed(matron: <-matron, sire: <-sire, lovePotion: <-lovePotion, beastReceiver: beastReceiver) + + eggCollectionRef.deposit(token: <-egg) + } + + } + `), + args([arg(ID1, t.UInt64), arg(ID2, t.UInt64)]), + payer(authz), + proposer(authz), + authorizations([authz]), + limit(9999), + ]).then(decode) + tx(res).subscribe((res: any) => { + toastStatus(id, res.status) + }) + await tx(res) + .onceSealed() + .then((result: any) => { + toast.update(id, { + render: "Transaction Sealed", + type: "success", + isLoading: false, + autoClose: 5000, + }) + }) + fetchHunterData() + setEggObtainedModalOpen(true) + } catch (err) { + toast.update(id, { + render: () =>
        Error, try again later...
        , + type: "error", + isLoading: false, + autoClose: 5000, + }) + console.log(err) } } return ( <> +
        @@ -223,23 +376,24 @@ const Breeding: FC = ({ beast?.beastTemplateID as keyof typeof beastTemplates ].imageTransparentBg } - style={{ transform: "scaleX(-1)" }} + // style={{ transform: "scaleX(-1)" }} />{" "} -

        BREED COUNT

        -

        1/7

        +

        + #{beast?.serialNumber} {beast?.sex === "Male" ? "♂" : "♀"} +

        setMakeLovePotionModalOpen(true)}> - Required Love Potions + {lovePotionBalance < 1 && Love Potion Needed}

        - {potions}/200 + {lovePotionBalance}/1

        - + setOpen(true)}> @@ -247,27 +401,33 @@ const Breeding: FC = ({ {!beastSelected ? (

        Select a Beast

        ) : ( -

        Selected Beast

        +

        + #{selectedSerial} {selectedGender === "Male" ? "♂" : "♀"} +

        )} -
        +
        - setEggObtainedModalOpen(true)} - > - Start Breeding - + {lovePotionBalance >= 1 && beastSelected && ( + { + breed() + // setEggObtainedModalOpen(true) + }} + > + 🍆 + + )}
        - {evolvableBeasts != null && ( + {/* {breedableBeasts != null && (
          - {evolvableBeasts[beast.beastTemplateID].map( + {breedableBeasts[beast.beastTemplateID]?.map( (beast: any, i: any) => ( <>
        • = ({ )}
        - )} + )} */} {/*
          = ({ + beastID, + open, + setOpen, + beastName, + breedableBeasts, + setBeastSelected, + beastSelected, + selectedBeasts, + setSelectedBeasts, + setSelectedSerial, + setSelectedGender, +}) => { + const handleChange = (id: any, gender: any, serialNumber: any) => { + if (selectedBeasts.includes(id)) { + //remove + setSelectedBeasts(selectedBeasts.filter((beast: any) => beast != id)) + setSelectedGender(null) + setSelectedSerial(null) + setBeastSelected(false) + } else if (selectedBeasts.length < 1) { + //add + setSelectedBeasts((selectedBeasts: any) => [...selectedBeasts, id]) + setSelectedGender(gender) + setSelectedSerial(serialNumber) + setBeastSelected(true) + } + } + + return ( + + + +
          + + +
          + + + + + + Select a Beast + +
            + {breedableBeasts != null && ( + <> + {breedableBeasts.map((beast: any, i: any) => ( + <> +
          • + handleChange( + beast?.id, + beast?.sex, + beast?.serialNumber, + ) + } + > +
            + +
            +
          • + + ))} + + )} +
          +
          + { + setOpen(false) + }} + > + Select + +
          +
          +
          +
          +
          +
          +
          +
          + ) +} +export default SelectBreedingBeastModal diff --git a/components/ui/BuyButton/BuyButton.tsx b/components/ui/BuyButton/BuyButton.tsx index 386acc5..d9bd950 100644 --- a/components/ui/BuyButton/BuyButton.tsx +++ b/components/ui/BuyButton/BuyButton.tsx @@ -31,7 +31,7 @@ type FuncProps = { const BuyButton: FC = ({ buttonText, onClick }) => { return ( ) } diff --git a/components/ui/ChangeNicknameModal/ChangeNicknameModal.tsx b/components/ui/ChangeNicknameModal/ChangeNicknameModal.tsx index a65eddb..1d18cf6 100644 --- a/components/ui/ChangeNicknameModal/ChangeNicknameModal.tsx +++ b/components/ui/ChangeNicknameModal/ChangeNicknameModal.tsx @@ -95,7 +95,7 @@ type Props = { beastName: any } -const BeastModalView: FC = ({ +const ChangeNicknameModal: FC = ({ beastID, open, setOpen, @@ -133,7 +133,7 @@ const BeastModalView: FC = ({ } } `), - args([arg(nickname, t.String), arg(parseInt(beastID), t.UInt64)]), + args([arg(nickname, t.String), arg(beastID, t.UInt64)]), payer(authz), proposer(authz), authorizations([authz]), @@ -252,4 +252,4 @@ const BeastModalView: FC = ({ ) } -export default BeastModalView +export default ChangeNicknameModal diff --git a/components/ui/Chests/Chests.tsx b/components/ui/Chests/Chests.tsx index e4442d4..12fb879 100644 --- a/components/ui/Chests/Chests.tsx +++ b/components/ui/Chests/Chests.tsx @@ -407,7 +407,7 @@ const Chests: FC = () => { cadence: ` import NFTDayTreasureChest from 0xNFTDayTreasureChest - pub fun main(): [Address] { + access(all) fun main(): [Address] { return NFTDayTreasureChest.getWhitelist() } `, @@ -424,7 +424,7 @@ const Chests: FC = () => { cadence: ` import BlackMarketplace from 0xBlackMarketplace - pub fun main(): [Address] { + access(all) fun main(): [Address] { return BlackMarketplace.getWhitelistUsed() } `, diff --git a/components/ui/EggObtainedModal/EggObtainedModal.tsx b/components/ui/EggObtainedModal/EggObtainedModal.tsx index d057e63..db57279 100644 --- a/components/ui/EggObtainedModal/EggObtainedModal.tsx +++ b/components/ui/EggObtainedModal/EggObtainedModal.tsx @@ -2,7 +2,7 @@ import { FC, Fragment, useEffect, useState } from "react" import { Dialog, Transition } from "@headlessui/react" import { CheckIcon, IdentificationIcon } from "@heroicons/react/outline" import poopPic from "public/fungible_tokens/fungible_tokens_images/basic_beasts_poop.png" -import picture from "public/001_normal.png" +import eggImage from "public/egg.png" import star from "public/basic_starLevel.png" import styled from "styled-components" import { @@ -23,6 +23,12 @@ import profilePictures from "data/profilePictures" import { toast } from "react-toastify" import beastTemplates from "data/beastTemplates" import { motion } from "framer-motion" +import eggDefault from "public/eggs/default_shine.png" +import eggElectric from "public/eggs/electric_shine.png" +import eggWater from "public/eggs/water_shine.png" +import eggGrass from "public/eggs/grass_shine.png" +import eggFire from "public/eggs/fire_shine.png" +import eggNormal from "public/eggs/normal_shine.png" const ActionItem = styled.div` padding: 10px 0; @@ -140,7 +146,7 @@ const Notice = styled.div` const Img = styled.img` z-index: 50; - max-width: 5rem; + max-width: 20rem; aspect-ratio: 1; border-radius: 10px; box-shadow: ${(props) => (props.selected ? `0px 0px 5px 4px #8F7A39` : `0`)}; @@ -197,9 +203,18 @@ const Backshine = styled.div` type Props = { open: boolean setOpen: any + beast: any + setOpenBeastModal: any + selectFilter: any } -const EggObtainedModal: FC = ({ open, setOpen }) => { +const EggObtainedModal: FC = ({ + open, + setOpen, + beast, + setOpenBeastModal, + selectFilter, +}) => { return ( @@ -231,10 +246,32 @@ const EggObtainedModal: FC = ({ open, setOpen }) => { Congratulations! You have recieved an egg!
          - - + + {/* */}
          - +
      {/* */} diff --git a/components/ui/EggTab/EggTab.tsx b/components/ui/EggTab/EggTab.tsx index 707703d..b81d288 100644 --- a/components/ui/EggTab/EggTab.tsx +++ b/components/ui/EggTab/EggTab.tsx @@ -10,6 +10,20 @@ import Egg from "public/egg.png" import GoldLight from "public/gold_light.png" import EggViewModal from "../EggViewModal" +import eggDefault from "public/eggs/default_shine.png" +import eggElectric from "public/eggs/electric_shine.png" +import eggWater from "public/eggs/water_shine.png" +import eggGrass from "public/eggs/grass_shine.png" +import eggFire from "public/eggs/fire_shine.png" +import eggNormal from "public/eggs/normal_shine.png" +import { useHoursLeft } from "./useHoursLeft" +import incubatorDefault from "public/eggs/incubator_default_testnet.gif" +import incubatorElectric from "public/eggs/incubator_electric_testnet.gif" +import incubatorWater from "public/eggs/incubator_water_testnet.gif" +import incubatorGrass from "public/eggs/incubator_grass_testnet.gif" +import incubatorFire from "public/eggs/incubator_fire_testnet.gif" +import incubatorNormal from "public/eggs/incubator_normal_testnet.gif" + const Wrapper = styled.div` padding: 20px 20px 100px; z-index: 1; @@ -150,7 +164,7 @@ const InputContainer = styled.div` ` const Img = styled.img` position: relative; - max-width: 5rem; + max-width: 10rem; ` const Light = styled.img` position: absolute; @@ -238,311 +252,32 @@ const MenuItems = styled(Menu.Items)` width: 100%; } ` -const EggDiv = styled.div` +const EggDiv = styled.div` display: flex; position: relative; justify-content: center; align-items: center; border-radius: 2rem; - background: #ffe8a3; + background: ${(props) => props.backgroundColor || "#ffe8a3"}; width: 10rem; aspect-ratio: 1; z-index: 1; overflow: hidden; + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) + 14 0, + pointer !important; ` const EggTimer = styled.div` position: absolute; - top: 0; - right: 0; + top: -3px; + right: 6px; color: rgba(0, 0, 0, 65%); font-size: 1.5rem; - margin-right: 1.2rem; margin-top: 0.25rem; ` -const DropDown: FC<{ - beasts: any - sortBy: any - setSortBy: any -}> = ({ beasts, sortBy, setSortBy }) => { - const sortByDexLowHigh = () => { - if (beasts != null) { - beasts.sort((a: any, b: any) => a.beastTemplateID - b.beastTemplateID) - beasts.sort((a: any, b: any) => a.dexNumber - b.dexNumber) - } - } - - const sortByDexHighLow = () => { - if (beasts != null) { - beasts.sort((a: any, b: any) => a.beastTemplateID - b.beastTemplateID) - beasts.sort((a: any, b: any) => b.dexNumber - a.dexNumber) - } - } - - const sortBySerialLowHigh = () => { - if (beasts != null) { - beasts.sort((a: any, b: any) => a.beastTemplateID - b.beastTemplateID) - beasts.sort((a: any, b: any) => a.serialNumber - b.serialNumber) - } - } - - const sortBySerialHighLow = () => { - if (beasts != null) { - beasts.sort((a: any, b: any) => a.beastTemplateID - b.beastTemplateID) - beasts.sort((a: any, b: any) => b.serialNumber - a.serialNumber) - } - } - - const sortByElement = () => { - const dic = { Electric: 1, Water: 2, Grass: 3, Fire: 4, Normal: 5 } - if (beasts != null) { - beasts.sort((a: any, b: any) => { - var aValue = 0 - var bValue = 0 - aValue = dic[a.elements[0] as keyof typeof dic] - bValue = dic[b.elements[0] as keyof typeof dic] - if (aValue < bValue) return -1 - if (aValue > bValue) return 1 - return 0 - }) - } - } - - const sortByNicknameAZ = () => { - if (beasts != null) { - beasts.sort((a: any, b: any) => (a.nickname > b.nickname ? 1 : -1)) - } - } - - const sortByNicknameZA = () => { - if (beasts != null) { - beasts.sort((a: any, b: any) => (a.nickname < b.nickname ? 1 : -1)) - } - } - - const sortBySkinLowHigh = () => { - const dic = { - Normal: 1, - "Metallic Silver": 2, - "Cursed Black": 3, - "Shiny Gold": 4, - "Mythic Diamond": 5, - } - if (beasts != null) { - beasts.sort((a: any, b: any) => { - var aValue = 0 - var bValue = 0 - aValue = dic[a.skin as keyof typeof dic] - bValue = dic[b.skin as keyof typeof dic] - if (aValue < bValue) return -1 - if (aValue > bValue) return 1 - return 0 - }) - } - } - - const sortBySkinHighLow = () => { - const dic = { - Normal: 1, - "Metallic Silver": 2, - "Cursed Black": 3, - "Shiny Gold": 4, - "Mythic Diamond": 5, - } - if (beasts != null) { - beasts.sort((a: any, b: any) => { - var aValue = 0 - var bValue = 0 - aValue = dic[a.skin as keyof typeof dic] - bValue = dic[b.skin as keyof typeof dic] - if (aValue < bValue) return 1 - if (aValue > bValue) return -1 - return 0 - }) - } - } - return ( - - -
      - - - {sortBy} - - -
      - - - - -
      - - {({ active }) => ( - { - sortByDexLowHigh() - setSortBy("Dex No. (Low-High)") - }} - className={classNames( - active ? "bg-gray-700" : "", - "block px-4 py-2 text-sm", - )} - > - Dex No. (Low-High) - - )} - - - {({ active }) => ( - { - setSortBy("Dex No. (High-Low)") - sortByDexHighLow() - }} - className={classNames( - active ? "bg-gray-700" : "", - "block px-4 py-2 text-sm", - )} - > - Dex No. (High-Low) - - )} - - - {({ active }) => ( - { - setSortBy("Nickname (A-Z)") - sortByNicknameAZ() - }} - className={classNames( - active ? "bg-gray-700" : "", - "block px-4 py-2 text-sm", - )} - > - Nickname A-Z - - )} - - - {({ active }) => ( - { - setSortBy("Nickname (Z-A)") - sortByNicknameZA() - }} - className={classNames( - active ? "bg-gray-700" : "", - "block px-4 py-2 text-sm", - )} - > - Nickname Z-A - - )} - - - {({ active }) => ( - { - setSortBy("Serial (Low-High)") - sortBySerialLowHigh() - }} - className={classNames( - active ? "bg-gray-700" : "", - "block px-4 py-2 text-sm", - )} - > - Serial (Low-High) - - )} - - - {({ active }) => ( - { - setSortBy("Serial (High-Low)") - sortBySerialHighLow() - }} - className={classNames( - active ? "bg-gray-700" : "", - "block px-4 py-2 text-sm", - )} - > - Serial (High-Low) - - )} - - - {({ active }) => ( - { - setSortBy("Skin (High-Low)") - sortBySkinHighLow() - }} - className={classNames( - active ? "bg-gray-700" : "", - "block px-4 py-2 text-sm", - )} - > - Skin (High-Low) - - )} - - - {({ active }) => ( - { - setSortBy("Skin (Low-High)") - sortBySkinLowHigh() - }} - className={classNames( - active ? "bg-gray-700" : "", - "block px-4 py-2 text-sm", - )} - > - Skin (Low-High) - - )} - - - {({ active }) => ( - { - setSortBy("Element Type") - sortByElement() - }} - className={classNames( - active ? "bg-gray-700" : "", - "block px-4 py-2 text-sm", - )} - > - Element Type - - )} - -
      -
      -
      -
      -
      -
      - ) -} - type Color = { bgColor: any } @@ -557,26 +292,44 @@ type Props = { allEvolutionPairs: any getPersonalDexicon: any walletAddress: any + eggs: any } -const eggs = [ - { - id: 1, - incubationDateEnding: 2, - }, - { - id: 2, - incubationDateEnding: 2, - }, - { - id: 3, - incubationDateEnding: 2, - }, - { - id: 4, - incubationDateEnding: 0, - }, -] +// const eggs = [ +// { +// id: 1, +// incubationDateEnding: 2, +// }, +// { +// id: 2, +// incubationDateEnding: 2, +// }, +// { +// id: 3, +// incubationDateEnding: 2, +// }, +// { +// id: 4, +// incubationDateEnding: 0, +// }, +// ] + +function EggTimerComponent({ egg }: any) { + const targetTimestamp = egg?.incubationTimer?.incubationDateEnding + const { hoursLeft, hasPassed } = useHoursLeft( + targetTimestamp ? targetTimestamp : 0, + ) + + if (hasPassed) { + return Ready + } + + if (!targetTimestamp) { + return null + } + + return {hoursLeft}h +} const EggTab: FC = ({ beasts, @@ -586,6 +339,7 @@ const EggTab: FC = ({ allEvolutionPairs, getPersonalDexicon, walletAddress, + eggs, }) => { const [displayBeasts, setDisplayBeasts] = useState(null) const [selectedBeast, setSelectedBeast] = useState(null) @@ -649,7 +403,7 @@ const EggTab: FC = ({ return ( <> - + {/* = ({ sortBy={sortBy} setSortBy={setSortBy} /> - + */} {/* example buttons start */} {/* @@ -674,7 +428,7 @@ const EggTab: FC = ({ {/* example buttons end */} - + setEvolutionModalOpen(false)} RevealModalOpen={evolutionModalOpen} @@ -696,71 +450,58 @@ const EggTab: FC = ({ setDisplayNickname(null) }} > - {/*
      - -
      -
      - - hej - - <>{egg?.sex === "Male" ? "♂" : "♀"} - - - {Array(egg.starLevel) - .fill(0) - .map((_, i) => ( - - ))} - - -
      */} - - - - {egg.incubationDateEnding != 0 ? ( + {/* */} + {egg?.incubationTimer != null ? ( + + ) : ( + + )} + + {egg?.incubationTimer != null && ( - {egg.incubationDateEnding}h{" "} - {/* Insert Hourglass icon here */} - {/* */} + - ) : ( - )} diff --git a/components/ui/EggTab/useHoursLeft.ts b/components/ui/EggTab/useHoursLeft.ts new file mode 100644 index 0000000..15e150e --- /dev/null +++ b/components/ui/EggTab/useHoursLeft.ts @@ -0,0 +1,35 @@ +import { useState, useEffect } from "react" + +interface HoursLeftResult { + hoursLeft: number + hasPassed: boolean +} + +export function useHoursLeft(targetTimestamp: number): HoursLeftResult { + const [hoursLeft, setHoursLeft] = useState(0) + const [hasPassed, setHasPassed] = useState(false) + + useEffect(() => { + const intervalId = setInterval(() => { + const currentTimestamp = Math.floor(Date.now() / 1000) // convert to seconds + const diffInSeconds = targetTimestamp - currentTimestamp + + if (diffInSeconds <= 0) { + clearInterval(intervalId) + setHoursLeft(0) + setHasPassed(true) + return + } + + const diffInHours = Math.floor(diffInSeconds / 3600) // convert to hours + setHoursLeft(diffInHours) + }, 1000) // update every second + + // clear interval on component unmount + return () => { + clearInterval(intervalId) + } + }, [targetTimestamp]) + + return { hoursLeft, hasPassed } +} diff --git a/components/ui/EggViewModal/EggViewModal.tsx b/components/ui/EggViewModal/EggViewModal.tsx index 102f3f6..1f6d4ba 100644 --- a/components/ui/EggViewModal/EggViewModal.tsx +++ b/components/ui/EggViewModal/EggViewModal.tsx @@ -26,48 +26,22 @@ import profilePictures from "data/profilePictures" import { toast } from "react-toastify" import beastTemplates from "data/beastTemplates" import { motion } from "framer-motion" - -const ActionItem = styled.div` - padding: 10px 0; - width: 100%; -` - -const FuncArgInput = styled.input` - background: transparent; - border: 1px solid #fff; - color: #fff; - font-size: 1.5em; - padding: 10px 0px 10px 20px; - border-radius: 8px 0 0 8px; - width: 50%; - cursor: pointer; - margin-right: -1px; - - outline: none; -` - -const FuncArgButton = styled.button` - background: transparent; - border: 1px solid #e4be23; - color: #e4be23; - font-size: 1.5em; - padding: 10px 20px; - border-radius: 0 8px 8px 0; - outline: none; - cursor: pointer; - - transition: all 0.2s ease 0s; - -moz-transition: all 0.2s ease 0s; - -webkit-transition: all 0.2s ease 0s; - &:hover { - background: #e4be23; - color: #212127; - - transition: all 0.2s ease 0s; - -moz-transition: all 0.2s ease 0s; - -webkit-transition: all 0.2s ease 0s; - } -` +import eggDefault from "public/eggs/default_shine.png" +import eggElectric from "public/eggs/electric_shine.png" +import eggWater from "public/eggs/water_shine.png" +import eggGrass from "public/eggs/grass_shine.png" +import eggFire from "public/eggs/fire_shine.png" +import eggNormal from "public/eggs/normal_shine.png" +import { toastStatus } from "@framework/helpers/toastStatus" +import { useUser } from "@components/user/UserProvider" +import { useHoursLeft } from "../EggTab/useHoursLeft" +import incubatorDefault from "public/eggs/incubator_default_testnet.gif" +import incubatorElectric from "public/eggs/incubator_electric_testnet.gif" +import incubatorWater from "public/eggs/incubator_water_testnet.gif" +import incubatorGrass from "public/eggs/incubator_grass_testnet.gif" +import incubatorFire from "public/eggs/incubator_fire_testnet.gif" +import incubatorNormal from "public/eggs/incubator_normal_testnet.gif" +import HatchingModal from "../HatchingModal" const DialogPanel = styled(Dialog.Panel)` position: relative; @@ -79,9 +53,9 @@ const DialogPanel = styled(Dialog.Panel)` height: 600px; ` -const Button = styled.button` +const Button = styled.button` margin-top: 20px; - background: #ffd966; + background: ${(props) => props.backgroundColor || "#ffe8a3"}; // border: 1px solid #e4be23; color: black; font-size: 1.5em; @@ -107,44 +81,12 @@ const Button = styled.button` // } ` -const Title = styled.div` - font-size: 2.5em; - text-align: center; - line-height: 1; -` - -const Wrapper = styled.div` - margin: 20px 20vw 0; - /* display: flex; - flex-direction: row; */ - /* justify-content: center; - align-items: center; - display: flex; */ - text-align: center; -` - -const BeastContainer = styled.div` - justify-content: center; - align-items: center; - display: flex; - flex-direction: column; -` - const Container = styled.div`` -const Box = styled.div` - height: 50px; - width: 50px; - background: ${(props) => (props.selected ? "#ffe595" : "#425066")}; -` - -const Notice = styled.div` - margin-top: 10px; -` - const Img = styled.img` position: relative; - max-width: 5rem; + max-width: 20rem; + margin-bottom: -120px; // z-index: 50; // aspect-ratio: 1; // border-radius: 10px; @@ -153,6 +95,12 @@ const Img = styled.img` // -moz-transition: all 0.3s ease 0s; // -webkit-transition: all 0.3s ease 0s; ` +const IncubatorImg = styled.img` + position: relative; + max-width: 25rem; + margin-bottom: -170px; +` + const ImgDiv = styled.div` border-radius: 1rem; padding: 0 1rem; @@ -195,18 +143,14 @@ const Backshine = styled.div` z-index: -1; box-shadow: 0 0 15px 1px gold; ` -const Header = styled.div` +const Header = styled.div` position: relative; - background: linear-gradient( - 180deg, - rgba(255, 232, 163, 1) 0%, - rgba(255, 217, 102, 1) 100% - ); + background: ${(props) => props.colorCode}; width: 100%; height: 9rem; display: flex; justify-content: center; - margin-bottom: 5rem; + margin-bottom: 10rem; ` const Light = styled.img` position: absolute; @@ -223,9 +167,148 @@ const EggDiv = styled.div` type Props = { open: boolean setOpen: any + egg: any } -const EggViewModal: FC = ({ open, setOpen }) => { +const EggViewModal: FC = ({ open, setOpen, egg }) => { + const { fetchHunterData } = useUser() + const [openHatchingModal, setOpenHatchingModal] = useState(false) + + const eggTimer = egg?.incubationTimer?.incubationDateEnding + const { hoursLeft, hasPassed } = useHoursLeft(eggTimer ? eggTimer : 0) + + useEffect(() => { + setOpenHatchingModal(false) + }, [egg]) + + const incubate = async () => { + const id = toast.loading("Initializing...") + + try { + const res = await send([ + transaction(` + import Egg from 0xEgg + + transaction(eggID: UInt64) { + + prepare(acct: AuthAccount) { + + let eggCollectionRef = acct.borrow<&Egg.Collection>(from: Egg.CollectionStoragePath) + ?? panic("Couldn't get a reference to the egg collection") + + let eggRef = eggCollectionRef.borrowEntireEgg(id: eggID) + + eggRef!.incubate() + + } + + } + `), + args([arg(egg?.id, t.UInt64)]), + payer(authz), + proposer(authz), + authorizations([authz]), + limit(9999), + ]).then(decode) + tx(res).subscribe((res: any) => { + toastStatus(id, res.status) + }) + await tx(res) + .onceSealed() + .then((result: any) => { + toast.update(id, { + render: "Transaction Sealed", + type: "success", + isLoading: false, + autoClose: 5000, + }) + }) + fetchHunterData() + setOpen(false) + } catch (err) { + toast.update(id, { + render: () =>
      Error, try again later...
      , + type: "error", + isLoading: false, + autoClose: 5000, + }) + console.log(err) + } + } + + const hatch = async () => { + const id = toast.loading("Initializing...") + + try { + const res = await send([ + transaction(` + import Egg from 0xEgg + import BasicBeasts from 0xBasicBeasts + import NonFungibleToken from 0xNonFungibleToken + import MetadataViews from 0xMetadataViews + + transaction(eggID: UInt64) { + + prepare(acct: AuthAccount) { + + let eggCollectionRef = acct.borrow<&Egg.Collection>(from: Egg.CollectionStoragePath) + ?? panic("Couldn't get a reference to the egg collection") + + if acct.borrow<&BasicBeasts.Collection{BasicBeasts.BeastCollectionPublic}>(from: BasicBeasts.CollectionStoragePath) == nil { + acct.save(<- BasicBeasts.createEmptyCollection(), to: BasicBeasts.CollectionStoragePath) + acct.unlink(BasicBeasts.CollectionPublicPath) + acct.link<&BasicBeasts.Collection{NonFungibleToken.Receiver, + NonFungibleToken.CollectionPublic, + BasicBeasts.BeastCollectionPublic, + MetadataViews.ResolverCollection}> + (BasicBeasts.CollectionPublicPath, target: BasicBeasts.CollectionStoragePath) + } + + let beastCollectionRef = acct.borrow<&BasicBeasts.Collection>(from: BasicBeasts.CollectionStoragePath) + ?? panic("Couldn't get a reference to the egg collection") + + let eggRef = eggCollectionRef.borrowEntireEgg(id: eggID) + + let beast <- eggRef!.hatch() + + beastCollectionRef.deposit(token: <- beast) + + } + + } + `), + args([arg(egg?.id, t.UInt64)]), + payer(authz), + proposer(authz), + authorizations([authz]), + limit(9999), + ]).then(decode) + tx(res).subscribe((res: any) => { + toastStatus(id, res.status) + }) + setOpenHatchingModal(true) + await tx(res) + .onceSealed() + .then((result: any) => { + toast.update(id, { + render: "Transaction Sealed", + type: "success", + isLoading: false, + autoClose: 5000, + }) + }) + fetchHunterData() + } catch (err) { + toast.update(id, { + render: () =>
      Error, try again later...
      , + type: "error", + isLoading: false, + autoClose: 5000, + }) + console.log(err) + } + } + return ( @@ -253,18 +336,138 @@ const EggViewModal: FC = ({ open, setOpen }) => { leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" > -
      + setOpenHatchingModal(false)} + RevealModalOpen={openHatchingModal} + packId={"1" || "1"} + evolvedBeastId={ + egg?.beast[Object.keys(egg?.beast ?? {})[0]]?.beastTemplate + .beastTemplateID + } + egg={egg} + /> +
      - - + {/* */} + {egg?.incubationTimer != null ? ( + + ) : ( + + )}
      -

      Your egg is ready to hatch!

      - - + {egg?.incubationTimer != null ? ( + <> + {Math.floor(Date.now() / 1000) < + egg?.incubationTimer?.incubationDateEnding ? ( + <> +

      Your egg is incubating

      +

      Hours left: {hoursLeft}

      + + ) : ( + <> +

      Your egg is ready to hatch!

      + + + )} + + ) : ( + <> +

      Incubate your egg to hatch it

      + + + )} + {/*

      Your egg is ready to hatch!

      + */}
      {/* */} diff --git a/components/ui/FUSDClaimModal/FUSDClaimModal.tsx b/components/ui/FUSDClaimModal/FUSDClaimModal.tsx index 8fe77df..052df72 100644 --- a/components/ui/FUSDClaimModal/FUSDClaimModal.tsx +++ b/components/ui/FUSDClaimModal/FUSDClaimModal.tsx @@ -350,7 +350,7 @@ const FUSDClaimModal: FC = ({ Claim FUSD from Chest
      - Current Balance: {balance?.slice(0, -6)} ₣USD + Current Balance: {balance != null ? balance : 0} ₣USD
      ` + background: rgba(255, 255, 255, 0.1); + height: 100%; + /* display: flex; */ + justify-content: center; + + //Responsive + @media (max-width: 1240px) { + padding-left: 50px; + padding-right: 150px; + } + @media (max-width: 600px) { + padding-left: 0px; + padding-right: 0px; + } +` + +const Content = styled.div` + /* background: grey; */ + padding-left: 20px; + display: table; + clear: both; +` + +const ContentLeft = styled.div` + float: left; + color: #fff; + margin-left: 100px; + + //Responsive + @media (max-width: 1240px) { + margin-left: 0px; + } +` +const ContentRight = styled.div` + /* float: right; + margin-left: -100px; + margin-top: 4vw; */ +` + +const StarLevelLabel = styled(motion.div)` + font-size: 10em; + + //Responsive + @media (max-width: 1240px) { + font-size: 8em; + } + @media (max-width: 1000px) { + font-size: 5em; + } + @media (max-width: 600px) { + font-size: 3em; + } +` + +const Star = styled(motion.div)`` + +const Beast = styled(motion.div)`` + +const BeastContainer = styled(motion.div)` + position: absolute; + width: 200px; + top: 250px; + + margin-left: auto; + margin-right: auto; + + left: 0; + right: 0; + + @media (max-width: 600px) { + width: 100px; + } +` + +const BeastContainer2 = styled(motion.div)` + position: absolute; + width: 200px; + top: 250px; + + margin-left: auto; + margin-right: auto; + + left: 0; + right: 0; + + @media (max-width: 600px) { + width: 100px; + } +` +const BeastContainer3 = styled(motion.div)` + position: absolute; + width: 200px; + top: 250px; + + margin-left: auto; + margin-right: auto; + left: 0; + right: 0; + + @media (max-width: 600px) { + width: 100px; + } +` + +const BeastImg = styled.img` + //Responsive + @media (max-width: 1240px) { + } + @media (max-width: 1000px) { + } + @media (max-width: 600px) { + } +` + +const CloseIcon = styled.div` + color: #fff; + position: absolute; + font-size: 100px; + right: 0px; + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) + 14 0, + pointer !important; + z-index: 30; + //Responsive + @media (max-width: 600px) { + font-size: 70px; + right: 10px; + } +` + +const dropIn = { + hidden: { opacity: 0 }, + visible: { opacity: 1, transition: { delayChildren: 4 } }, + exit: {}, +} + +const Circle = styled(motion.div)` + background: #fff; + background: radial-gradient( + circle, + rgba(255, 255, 255, 1) 0%, + rgba(255, 255, 255, 0) 100% + ); + border-radius: 50%; + position: absolute; + + margin-left: auto; + margin-right: auto; + left: 0; + right: 0; + + top: 250px; + + width: 150px; + height: 150px; +` + +const HatchingCircle = styled(motion.div)` + background: #fff; + border-radius: 50%; + position: absolute; + + margin: auto auto; + left: 0; + right: 0; + top: 0; + bottom: 0; + + width: 200px; + height: 200px; +` + +const EggImg = styled.img` + scale: 1.5; + position: relative; + z-index: 100; +` + +const EvolvedBeastImg = styled.img`` + +const EvolvedBeastContainer = styled(motion.div)` + position: absolute; + width: 400px; + top: 150px; + + margin-left: auto; + margin-right: auto; + left: 0; + right: 0; + + @media (max-width: 600px) { + width: 300px; + } +` + +const BeastName = styled(motion.div)` + position: absolute; + text-align: center; + top: 515px; + color: white; + margin-left: auto; + margin-right: auto; + left: 0; + right: 0; + font-size: 5em; + + //Responsive + @media (max-width: 1240px) { + } + @media (max-width: 1000px) { + } + @media (max-width: 600px) { + } +` + +const StarLevel = styled.div` + display: flex; + + position: absolute; + top: 610px; + + margin-left: auto; + margin-right: auto; + left: 0; + right: 0; + width: 100px; +` + +const StarImg = styled.img` + /* width: 50px; */ + /* margin-left: 0px; + margin-right: 10px; */ + padding: 1px; + + /* //Responsive + @media (max-width: 1240px) { + width: 70px; + margin-left: 0px; + margin-right: 5px; + margin-top: 10px; + } + @media (max-width: 1000px) { + width: 50px; + margin-left: 0px; + margin-right: 5px; + margin-top: 20px; + } + @media (max-width: 600px) { + width: 30px; + margin-left: 0px; + margin-right: 5px; + margin-top: 20px; + } */ +` + +const AnimationContainer = styled.div` + /* margin-top: 0px; */ + position: absolute; + top: 200px; + margin-left: auto; + margin-right: auto; + left: 0; + right: 0; + z-index: -1; + + transform: scale(5); +` + +type FuncProps = { + handleClose: () => void + RevealModalOpen: boolean + packId: string | "0" + evolvedBeastId: any + egg: any +} + +const HatchingModal: FC = ({ + handleClose, + packId, + RevealModalOpen, + evolvedBeastId, + egg, +}) => { + //TODO + const num: any = parseInt(packId) + + Object.entries(beastTemplates).forEach(([key, beastTemplate]) => { + const dexNumberFormatted = String(beastTemplate.dexNumber).padStart(3, "0") + let fileFormat = ".png" + + if ( + beastTemplate.skin === "Metallic Silver" || + beastTemplate.skin === "Shiny Gold" + ) { + fileFormat = ".gif" + } + + let imageTransparentBgCenter = `https://raw.githubusercontent.com/basicbeasts/basic-beasts-frontend/main/public/beasts/${dexNumberFormatted}_${beastTemplate.skin + .toLowerCase() + .replace(" ", "_")}${fileFormat}` + + ;(beastTemplate as any).imageTransparentBgCenter = imageTransparentBgCenter + }) + + const beast1 = beastTemplates[num as keyof typeof beastTemplates] + const evolvedBeast: any = + beastTemplates[evolvedBeastId as keyof typeof beastTemplates] + + return ( + <> + {!RevealModalOpen ? ( + <> + ) : ( + + e.stopPropagation()} + variants={dropIn} + initial="hidden" + animate="visible" + exit="exit" + > + + + {/* x */} + + + + + + + + + + + + + + + + + + + + + + + + + + + + {/* */} + + + + + {/* {evolvedBeast?.name} */} + + + {Array.from(Array(evolvedBeast.starLevel), (e, i) => { + return ( + + + + ) + })} + {Array.from( + Array(3 - (evolvedBeast.starLevel ?? 0)), + (e, i) => { + return ( + + + + ) + }, + )} + + + + + + + )} + + ) +} +export default HatchingModal diff --git a/components/ui/HatchingModal/index.ts b/components/ui/HatchingModal/index.ts new file mode 100644 index 0000000..e3f7a1f --- /dev/null +++ b/components/ui/HatchingModal/index.ts @@ -0,0 +1 @@ +export { default } from "./HatchingModal" diff --git a/components/ui/Hero/Hero.tsx b/components/ui/Hero/Hero.tsx index 419e64c..f9ee880 100644 --- a/components/ui/Hero/Hero.tsx +++ b/components/ui/Hero/Hero.tsx @@ -162,12 +162,12 @@ const Hero: FC = () => {

      {t("home:hero-description")}

      - + diff --git a/components/ui/InboxItemList/InboxItemList.tsx b/components/ui/InboxItemList/InboxItemList.tsx index c9ab63f..0a2517d 100644 --- a/components/ui/InboxItemList/InboxItemList.tsx +++ b/components/ui/InboxItemList/InboxItemList.tsx @@ -88,12 +88,13 @@ const InboxItemList: FC = () => { try { const res = await send([ transaction(` - import Inbox from 0xInbox + import BasicBeastsInbox from 0xInbox import Pack from 0xPack import NonFungibleToken from 0xNonFungibleToken + import FungibleToken from 0xFungibleToken import MetadataViews from 0xMetadataViews - pub fun hasPackCollection(_ address: Address): Bool { + access(all) fun hasPackCollection(_ address: Address): Bool { return getAccount(address) .getCapability<&Pack.Collection{NonFungibleToken.CollectionPublic, Pack.PackCollectionPublic}>(Pack.CollectionPublicPath) .check() @@ -101,12 +102,12 @@ const InboxItemList: FC = () => { transaction(adminAcct: Address) { - let centralizedInboxRef: &Inbox.CentralizedInbox{Inbox.Public} + let centralizedInboxRef: &BasicBeastsInbox.CentralizedInbox{Inbox.Public} let packCollectionRef: &Pack.Collection{NonFungibleToken.Receiver} prepare(acct: AuthAccount) { - self.centralizedInboxRef = getAccount(adminAcct).getCapability(Inbox.CentralizedInboxPublicPath) - .borrow<&Inbox.CentralizedInbox{Inbox.Public}>() + self.centralizedInboxRef = getAccount(adminAcct).getCapability(BasicBeastsInbox.CentralizedInboxPublicPath) + .borrow<&BasicBeastsInbox.CentralizedInbox{BasicBeastsInbox.Public}>() ?? panic("Could not get Centralized Inbox reference") if !hasPackCollection(acct.address) { diff --git a/components/ui/ListBeastForSaleModal/ListBeastForSaleModal.tsx b/components/ui/ListBeastForSaleModal/ListBeastForSaleModal.tsx index e6292bc..aad676b 100644 --- a/components/ui/ListBeastForSaleModal/ListBeastForSaleModal.tsx +++ b/components/ui/ListBeastForSaleModal/ListBeastForSaleModal.tsx @@ -193,7 +193,12 @@ const ListBeastForSaleModal: FC = ({ open, setOpen, beast }) => { FUSD - +
      setOpen(false)} + > +
      x
      +
      ` ` const Button = styled.button` - margin-top: 20px; + margin-top: 30px; background: #ffd966; // border: 1px solid #e4be23; color: black; @@ -157,7 +160,7 @@ const ImgDiv = styled.div` padding: 0 1rem; ` const LadyImg = styled.img` - --size: 10rem; + --size: 20rem; position: absolute; top: calc(var(--size) * -1); right: 0; @@ -172,9 +175,9 @@ const LadyImg = styled.img` -webkit-transition: all 0.3s ease 0s; ` const TextDiv = styled.div` - margin-top: 1rem; + margin-top: 50px; text-align: start; - font-size: 1.2rem; + font-size: 2rem; border: 0.45rem solid white; padding: 2rem; width: 100%; @@ -195,29 +198,131 @@ const MaterialNumber = styled.span` type Props = { open: boolean setOpen: any + sushiBalance: any + emptyPotionBottleBalance: any + poopBalance: any } -const MakeLovePotionModal: FC = ({ open, setOpen }) => { - const [sushiNumber, setSushiNumber] = useState(0) - const [bottleNumber, setBottleNumber] = useState(1) - const [poopNumber, setPoopNumber] = useState(2) +const MakeLovePotionModal: FC = ({ + open, + setOpen, + sushiBalance, + emptyPotionBottleBalance, + poopBalance, +}) => { + const SUSHI_REQUIRED = 5 + const POOP_REQUIRED = 5 + const BOTTLE_REQUIRED = 1 const numberColors = () => { let sushiColor let bottleColor let poopColor { - sushiNumber >= 2 ? (sushiColor = "white") : (sushiColor = "red") + sushiBalance >= SUSHI_REQUIRED + ? (sushiColor = "white") + : (sushiColor = "red") } { - bottleNumber >= 2 ? (bottleColor = "white") : (bottleColor = "red") + emptyPotionBottleBalance >= 2 + ? (bottleColor = "white") + : (bottleColor = "red") } { - poopNumber >= 2 ? (poopColor = "white") : (poopColor = "red") + poopBalance >= POOP_REQUIRED ? (poopColor = "white") : (poopColor = "red") } return { sushiColor, bottleColor, poopColor } } + const { fetchHunterData } = useUser() + + const mintLovePotion = async () => { + const id = toast.loading("Initializing...") + + try { + const res = await send([ + transaction(` + import LovePotionMinter from 0xLovePotionMinter + import LovePotion from 0xLovePotion + import Sushi from 0xSushi + import Poop from 0xPoop + import EmptyPotionBottle from 0xEmptyPotionBottle + import MetadataViews from 0xMetadataViews + import NonFungibleToken from 0xNonFungibleToken + + + transaction() { + + prepare(acct: AuthAccount) { + + if acct.borrow<&LovePotion.Collection{LovePotion.LovePotionCollectionPublic}>(from: LovePotion.CollectionStoragePath) == nil { + acct.save(<- LovePotion.createEmptyCollection(), to: LovePotion.CollectionStoragePath) + acct.unlink(LovePotion.CollectionPublicPath) + acct.link<&LovePotion.Collection{NonFungibleToken.Receiver, + NonFungibleToken.CollectionPublic, + LovePotion.LovePotionCollectionPublic, + MetadataViews.ResolverCollection}> + (LovePotion.CollectionPublicPath, target: LovePotion.CollectionStoragePath) + } + + //Get the love potion collection reference + let collectionRef = acct.borrow<&LovePotion.Collection>(from: LovePotion.CollectionStoragePath) + ?? panic("Couldn't get a reference to the Love Potion collection") + + let sushiRef = acct.borrow<&Sushi.Vault>(from: Sushi.VaultStoragePath) + ?? panic("Couldn't get a reference to the suhsi vault") + + let poopRef = acct.borrow<&Poop.Vault>(from: Poop.VaultStoragePath) + ?? panic("Couldn't get a reference to the suhsi vault") + + let emptyPotionBottleRef = acct.borrow<&EmptyPotionBottle.Vault>(from: EmptyPotionBottle.VaultStoragePath) + ?? panic("Couldn't get a reference to the suhsi vault") + + let sushi <-sushiRef.withdraw(amount: 5.0) as! @Sushi.Vault + + let poop <- poopRef.withdraw(amount: 5.0) as! @Poop.Vault + + let emptyPotionBottle <- emptyPotionBottleRef.withdraw(amount: 1.0) as! @EmptyPotionBottle.Vault + + let lovePotion <- LovePotionMinter.mintLovePotion(sushi: <-sushi, poop: <-poop, emptyPotionBottle: <-emptyPotionBottle) + + collectionRef.deposit(token: <-lovePotion) + + } + + }`), + payer(authz), + proposer(authz), + authorizations([authz]), + limit(9999), + ]).then(decode) + tx(res).subscribe((res: any) => { + toastStatus(id, res.status) + }) + await tx(res) + .onceSealed() + .then((result: any) => { + toast.update(id, { + render: "Transaction Sealed", + type: "success", + isLoading: false, + autoClose: 5000, + }) + }) + fetchHunterData() + + setOpen(false) + } catch (err) { + toast.update(id, { + render: () =>
      Error, try again later...
      , + type: "error", + isLoading: false, + autoClose: 5000, + }) + console.log(err) + } + } + return ( @@ -248,7 +353,7 @@ const MakeLovePotionModal: FC = ({ open, setOpen }) => {
      Love Potion
      -

      Required Materials

      +

      Required Materials

      @@ -256,9 +361,9 @@ const MakeLovePotionModal: FC = ({ open, setOpen }) => {

      - {sushiNumber} + {parseInt(sushiBalance)} - /2 + /{SUSHI_REQUIRED}

      @@ -271,9 +376,9 @@ const MakeLovePotionModal: FC = ({ open, setOpen }) => {

      - {bottleNumber} + {parseInt(emptyPotionBottleBalance)} - /2 + /{BOTTLE_REQUIRED}

      @@ -283,16 +388,19 @@ const MakeLovePotionModal: FC = ({ open, setOpen }) => {

      - {poopNumber} + {parseInt(poopBalance)} - /2 + /{POOP_REQUIRED}

      @@ -300,11 +408,10 @@ const MakeLovePotionModal: FC = ({ open, setOpen }) => {
      -

      Mysterious old lady

      +

      Mysterious Old Lady

      - Hey there, little adventurer. To be able to breed your - beasts you will nreed love potion. And to make love - potion.. you need potion empty bottle, sushi, and poop! + Ah, love's alchemy you seek? Bring these items, and + love's elixir is within your grasp.

      diff --git a/components/ui/PackRevealCard/PackRevealCard.tsx b/components/ui/PackRevealCard/PackRevealCard.tsx index c395ecb..1036fb8 100644 --- a/components/ui/PackRevealCard/PackRevealCard.tsx +++ b/components/ui/PackRevealCard/PackRevealCard.tsx @@ -220,19 +220,19 @@ const PackRevealCard: FC = ({ import MetadataViews from 0xMetadataViews import FUSD from 0xFUSD - pub fun hasSushiVault(_ address: Address): Bool { + access(all) fun hasSushiVault(_ address: Address): Bool { return getAccount(address) .getCapability<&Sushi.Vault{FungibleToken.Balance}>(Sushi.BalancePublicPath) .check() } - pub fun hasPoopVault(_ address: Address): Bool { + access(all) fun hasPoopVault(_ address: Address): Bool { return getAccount(address) .getCapability<&Poop.Vault{FungibleToken.Balance}>(Poop.BalancePublicPath) .check() } - pub fun hasEmptyPotionBottleVault(_ address: Address): Bool { + access(all) fun hasEmptyPotionBottleVault(_ address: Address): Bool { return getAccount(address) .getCapability<&EmptyPotionBottle.Vault{FungibleToken.Balance}>(EmptyPotionBottle.BalancePublicPath) .check() diff --git a/components/ui/PackStore/PackStore.tsx b/components/ui/PackStore/PackStore.tsx index 8f58b6b..dc7ab17 100644 --- a/components/ui/PackStore/PackStore.tsx +++ b/components/ui/PackStore/PackStore.tsx @@ -339,12 +339,12 @@ const TotalPrice = styled.div<{ color: ${(props) => props.fontColor}; font-size: 4vw; white-space: nowrap; - margin-bottom: 0.5vw; + margin: 20px 0; line-height: 40px; @media (max-width: 1010px) { font-size: 13vw; - margin: 3vw 0; + margin: 25px 0; } ` @@ -621,7 +621,7 @@ const Purchase: FC = ({ const { logIn, loggedIn } = useAuth() - const { balance, purchase } = useUser() + const { balance, purchase, purchasePackType } = useUser() const incrementQuantity = () => { if (quantity < maxQuantity) { @@ -716,7 +716,7 @@ const Purchase: FC = ({ > {calculateTotalPrice().toLocaleString()} ₣USD - setCheckboxValue(!checkboxValue)} fontColor={ packType === "Starter" @@ -738,7 +738,7 @@ const Purchase: FC = ({ {t("home:reserve-packs")} {t("home:reserve-packs-tooltip")} - + */} <> {!available ? ( <> @@ -854,7 +854,11 @@ const Purchase: FC = ({ const address = checkboxValue ? addressReservable : addressRefundable - const tx = await purchase(totalPrice, address) + const tx = await purchasePackType( + totalPrice, + address, + packType, + ) if (tx) { const txId = tx.events[0].transactionId as string if (tx) { @@ -906,7 +910,7 @@ const Purchase: FC = ({ You don't have enough FUSD.{" "} @@ -1108,10 +1112,10 @@ const PackStore: FC = () => { {t("home:place-your-order-date", { - dateAndTime: "Jan 7 - Jan 9, 12PM PST", + dateAndTime: "Jan 27 - Feb 3, 12PM PST", })} - {t("home:announce-winners", { date: "Jan 23" })} + {t("home:announce-winners", { date: "Feb 10" })} diff --git a/components/ui/PlaceABidModal/PlaceABidModal.tsx b/components/ui/PlaceABidModal/PlaceABidModal.tsx index 197692a..0d8e847 100644 --- a/components/ui/PlaceABidModal/PlaceABidModal.tsx +++ b/components/ui/PlaceABidModal/PlaceABidModal.tsx @@ -3,6 +3,7 @@ import { Dialog, Transition, Menu } from "@headlessui/react" import styled from "styled-components" import { useUser } from "@components/user/UserProvider" import beastTemplates from "data/beastTemplates" +import { useAuth } from "@components/auth/AuthProvider" const ContainerDiv = styled.div` align-items: center; @@ -99,6 +100,7 @@ type Props = { const PlaceABidModal: FC = ({ open, setOpen, beast }) => { const [price, setPrice] = useState(0.0) const { placeABid, balance } = useUser() + const { loggedIn, logIn } = useAuth() const handleChange = (event: any) => { event.preventDefault() @@ -157,7 +159,12 @@ const PlaceABidModal: FC = ({ open, setOpen, beast }) => { {beast?.nickname} )} FUSD Balance: {parseFloat(balance)} - +
      setOpen(false)} + > +
      x
      +
      = ({ open, setOpen, beast }) => { />
      - + {!loggedIn ? ( + + ) : ( + + )}
      diff --git a/components/ui/ProductBeastView/InfoMobile.tsx b/components/ui/ProductBeastView/InfoMobile.tsx new file mode 100644 index 0000000..6051e95 --- /dev/null +++ b/components/ui/ProductBeastView/InfoMobile.tsx @@ -0,0 +1,276 @@ +import { FC, useEffect, useState } from "react" +import styled from "styled-components" +import { useUser } from "@components/user/UserProvider" +import { useAuth } from "@components/auth/AuthProvider" +import { + PriceBox, + H1, + Owner, + Owners, + OwnerImg, + H2, + H3, + P, + SaleDiv, + Clickable, + BuyButton, + BidButton, +} from "./ProductBeastView" +import SocialMediaShare from "./SocialMediaShare" + +const InfoMobileWrapper = styled.div` + display: none; + width: 32%; + // padding: 0 10rem; + @media (max-width: 1024px) { + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + } +` + +const BeastDetailsMobile = styled.div` + display: none; + @media (max-width: 1024px) { + display: block; + } +` + +const SharingDiv = styled.div` + display: block; + width: fit-content; +` + +const HeaderDiv = styled.div` + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; +` + +type Props = { + beast: any + hunterData: any + user: any + allBeastOffers: any + bestOffer: any + beastsForSale: any + delistBeast: any + setListBeastForSaleOpen: any + purchaseBeast: any + setPlaceABidOpen: any + setAcceptOfferOpen: any +} + +export const InfoMobile: FC = ({ + beast, + hunterData, + user, + allBeastOffers, + bestOffer, + beastsForSale, + delistBeast, + setListBeastForSaleOpen, + purchaseBeast, + setPlaceABidOpen, + setAcceptOfferOpen, +}) => { + // const [acceptOfferOpen, setAcceptOfferOpen] = useState(false) + // const [bestOffer, setBestOffer] = useState(null) + + // useEffect(() => { + // if ( + // allBeastOffers?.filter((offer: any) => offer?.beastID == beast?.id) + // .length > 0 + // ) { + // var offers = allBeastOffers + // ?.filter((offer: any) => offer?.beastID == beast?.id) + // .sort((a: any, b: any) => b.offerAmount - a.offerAmount) + // setBestOffer(offers[0]) + // } + // }, [allBeastOffers, beast]) + + // useEffect(() => { + // getUserFUSDBalance("0xfa252d0aa22bf86a") + // }, []) + + return ( + + + + {beast ? ( +

      {beast?.nickname + " " + "#" + beast?.serialNumber}

      + ) : ( +

      Loading...

      + )} + + + +
      +
      + {/* Last sale price [price] FUSD */} + {/* TODO */} + {user?.addr == beast?.currentOwner ? ( + <> + {beastsForSale + ?.map((beast: any) => beast.id) + .includes(beast?.id) ? ( + delistBeast(beast?.id)}> + Delist + + ) : ( + setListBeastForSaleOpen(true)} + > + List for sale + + )} + + ) : ( + <> + {beast?.price != null && ( + + purchaseBeast(beast?.currentOwner, beast?.id, beast?.price) + } + > + Buy now for {parseFloat(parseFloat(beast?.price).toFixed(2))}{" "} + FUSD + + )} + + )} + {user?.addr != beast?.currentOwner && ( + setPlaceABidOpen(true)}> + Make offer + + )} + {user?.addr == beast?.currentOwner && bestOffer != null && ( + setAcceptOfferOpen(true)}> + Accept best offer + + )} + + {/*

      Sale ends in [time]

      */} + + + {beast ? ( + + + + hunter.address == beast?.firstOwner, + )?.[0]?.avatar + } + alt="first owner avatar" + /> +
      +

      first owner

      +

      + {hunterData?.filter( + (hunter: any) => hunter.address == beast?.firstOwner, + )?.[0]?.findName != "" + ? hunterData?.filter( + (hunter: any) => hunter.address == beast?.firstOwner, + )?.[0]?.findName + : beast?.firstOwner} +

      +
      +
      +
      + + + hunter.address == beast?.currentOwner, + )?.[0]?.avatar + } + alt="current owner avatar" + /> +
      +

      current owner

      +

      + {hunterData?.filter( + (hunter: any) => hunter.address == beast?.currentOwner, + )?.[0]?.findName != "" + ? hunterData?.filter( + (hunter: any) => + hunter.address == beast?.currentOwner, + )?.[0]?.findName + : beast?.currentOwner} +

      +
      +
      +
      +
      + ) : ( + + + + +
      +

      first owner

      +

      Owner address loading...

      +
      +
      +
      + + + +
      +

      Current owner

      +

      Owner address loading...

      +
      +
      +
      +
      + )} +
      + + ) +} diff --git a/components/ui/ProductBeastView/ProductBeastView.tsx b/components/ui/ProductBeastView/ProductBeastView.tsx index ab04653..dbf451d 100644 --- a/components/ui/ProductBeastView/ProductBeastView.tsx +++ b/components/ui/ProductBeastView/ProductBeastView.tsx @@ -1,20 +1,6 @@ import { FC, useEffect, useState } from "react" -import picture from "public/beasts/001_normal.png" -import BeastMarketThumbnail from "../BeastMarketThumbnail" import styled from "styled-components" import star from "public/basic_starLevel.png" -import pic from "public/profile_pictures/bb_face_028.png" -import dexNumIcon from "public/Dex_number_icon.png" -import { - faEllipsisH, - faShareSquare, - faHeart as heartFull, - faCaretUp, -} from "@fortawesome/free-solid-svg-icons" -import { faHeart as heartEmpty } from "@fortawesome/free-regular-svg-icons" -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" -import { RefreshIcon } from "@heroicons/react/outline" -import BeastMarketBeastList from "../BeastMarketBeastList" import beastTemplates from "data/beastTemplates" import { useUser } from "@components/user/UserProvider" import { useAuth } from "@components/auth/AuthProvider" @@ -22,6 +8,13 @@ import ListBeastForSaleModal from "../ListBeastForSaleModal" import PlaceABidModal from "../PlaceABidModal" import profilePictures from "data/profilePictures" import AcceptOfferModal from "../AcceptOfferModal" +import { InfoMobile } from "./InfoMobile" +import SocialMediaShare from "./SocialMediaShare" +import arrow from "public/arrowIcon.svg" +import listIcon from "public/icons8-list-48.png" +import document from "public/document.svg" +import lightning from "public/lightning.svg" +import emptyImg from "public/emptyImg.png" const StarLevel = styled.div` vertical-align: middle; @@ -39,10 +32,7 @@ const StarImg = styled.img` ` const Panel = styled.div` background: none; - /* border: 1px solid gray; - border-radius: 10px; */ color: #fff; - padding: 10px; margin: 1rem auto; text-align: left; @@ -51,27 +41,65 @@ const Panel = styled.div` outline: none; transition: 0.4s; ` + +const AccordionIcon = styled.img` + height: auto; + max-height: 1.5rem; + display: inline-block; + padding-right: 0.5rem; +` + const AccordionTitle = styled.div` + background-color: rgba(95, 81, 81, 0.07); display: flex; gap: 1rem; - margin-left: 10px; - + padding: 1rem; + border: 1px solid #2e3340; + border-radius: 0.5rem; + justify-content: space-between; + align-items: center; font-size: 2rem; - margin-bottom: 20px; - /* border-bottom: 1px solid rgba(220, 220, 220, 0.25); */ - line-height: 1; + + line-height: normal; + :hover { + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) + 14 0, + pointer !important; + } + + & div { + align-items: center; + } +` + +const Arrow = styled.img` + transform: rotate(180deg); + display: inline-block; + height: 1rem; + + &.opened { + transform: rotate(0deg); + position: relative; + top: -0.4rem; + } ` + const AccordionContent = styled.div` - padding: 1.5rem; + padding: 1rem; + border: 1px solid #2e3340; + border-radius: 0.5rem; font-size: 1.2em; - border: 1px solid #5c5e6c; - border-radius: 1rem; width: 100%; + + margin-top: 0.25rem; + @media (max-width: 1024px) { + padding: 0.5rem; + } ` const AccordionDiv = styled.div` width: 100%; ` -const BuyButton = styled.button` +export const BuyButton = styled.button` width: 100%; background: #ffd966; border-radius: 10px; @@ -83,7 +111,7 @@ const BuyButton = styled.button` transform: scale(0.95); } ` -const BidButton = styled.button` +export const BidButton = styled.button` width: 100%; background: transparent; border-radius: 10px; @@ -97,88 +125,117 @@ const BidButton = styled.button` ` const ImgDiv = styled.div` + grid-column: 1; + grid-row: 1; position: relative; - max-width: 40rem; - + width: auto; overflow: hidden; - margin: 0 auto 50px; + /* min-height: 20vh; + max-height: 70vh; */ + + @media (max-width: 1024px) { + grid-column: 1 / span 2; + grid-row: 1; + } ` -const Owners = styled.div` - display: flex; + +const Img = styled.img` + user-drag: none; + -webkit-user-drag: none; + border-radius: 1.5rem; + width: 100%; +` + +const EmptyImgDiv = styled.img` + border-radius: 1.5rem; + width: 100%; +` + +export const Owners = styled.div` + display: grid; + grid-template-columns: 1fr 1fr; gap: 1rem; - padding: 2rem 0; - border-bottom: 2px solid #2e3340; + padding: 2.5rem 0 0 0; justify-content: left; - @media (max-width: 1470px) { - flex-direction: column; + + @media (max-width: 1024px) { + margin-bottom: 2rem; + } + @media (max-width: 550px) { + grid-template-columns: 100%; + grid-template-rows: 1fr 1fr; + } + + & > a { + &.first-owner { + grid-column: 1; + } + + &.current-owner { + grid-column: 2; + } } ` -const OwnerImg = styled.img` - max-width: 3.5rem; + +export const OwnerImg = styled.img` + max-width: 2.5rem; + min-width: 1.5rem; + min-height: 1.5rem; + background-color: #5c5e6c; border: solid 2px #f3cb23; - border-radius: 8px; + border-radius: 0.5rem; height: max-content; object-fit: contain; + @media (max-width: 1024px) { + max-width: 3rem; + } ` -const Owner = styled.div` +export const Owner = styled.div` display: flex; gap: 1rem; align-items: center; ` -const P = styled.p` +export const P = styled.p` color: white; ` const Trait = styled.p` line-height: 0; text-transform: uppercase; margin: 1rem 0; + @media (max-width: 1024px) { + font-size: 1.2rem; + margin: 0.5rem 0; + } ` -const H1 = styled.h1` - width: 100%; +export const H1 = styled.h1` + width: fit-content; + display: inline-block; font-size: 4.25rem; color: white; + line-height: normal; + @media (max-width: 450px) { + font-size: 3rem; + } ` -const H2 = styled.h2` +export const H2 = styled.h2` font-size: 1.215rem; - line-height: 0.75; + line-height: 1; color: grey; ` -const H2Traits = styled.h2` +export const H2Traits = styled.h2` font-size: 1.215rem; color: white; ` -const H3 = styled.h3` +export const H3 = styled.h3` width: 100%; font-size: 2rem; color: white; -` - -const Ul = styled.ul` - font-size: 1.215rem; - display: flex; - width: 100%; - align-items: center; - gap: 2rem; -` -const Li = styled.li` - display: flex; - gap: 0.5rem; - align-items: center; - line-height: 1; - width: 33.33%; - color: grey; - &:hover { - cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) - 14 0, - pointer !important; - } - @media (max-width: 1500px) { - p { - display: none; - } + @media (max-width: 1024px) { + font-size: 1.2rem; } ` + const Attributes = styled.div` display: grid; width: 100%; @@ -200,7 +257,7 @@ const AttributeBlock = styled.div` gap: 5px; font-size: 1.5rem; background: #212127; - border-radius: 10px; + border-radius: 0.5rem; color: grey; &:last-child { grid-column: 1 / -1; @@ -211,26 +268,39 @@ const AttributeBlock = styled.div` div { color: white; } + + @media (max-width: 1024px) { + padding: 5px 15px 5px 15px; + gap: 0px; + } ` const Info = styled.div` + grid-column: 2; + grid-row: 1; display: flex; flex-direction: column; align-items: center; - width: 32%; - // padding: 0 10rem; + @media (max-width: 1024px) { + display: none; + } ` -const SaleDiv = styled.div` +export const SaleDiv = styled.div` display: flex; gap: 1.25rem; flex-direction: column; align-items: center; margin-top: 2rem; - border: 1px solid #5c5e6c; - border-radius: 1.2rem; - padding: 2.5rem; width: 100%; ` -const PriceBox = styled.div` + +const HeaderDiv = styled.div` + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; +` + +export const PriceBox = styled.div` background: #1e1e23; border-radius: 1rem; padding: 1rem; @@ -251,32 +321,92 @@ const OfferDetails = styled.div` align-items: center; border-bottom: 2px solid #2e3340; padding-bottom: 20px; + @media (max-width: 1024px) { + flex-direction: row; + } ` const Offeror = styled.div` display: flex; align-items: center; + @media (max-width: 1024px) { + flex-direction: row; + } ` -const Img = styled.img` - user-drag: none; - -webkit-user-drag: none; - border-radius: 20px; -` - -const AccordianToggle = styled.div` +const AccordionToggle = styled.div` cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) 14 0, pointer !important; ` -const Clickable = styled.span` +export const Clickable = styled.span` cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) 14 0, pointer !important; &:active { transform: scale(0.95); } + @media (max-width: 1024px) { + font-size: 1.2rem; + } +` + +const BeastDescription = styled.section` + margin: 3rem 12.5vw 0 12.5vw; + line-height: normal; + + display: grid; + grid-template-columns: 1fr 1fr; + grid-template-rows: auto; + gap: 1vw 4vw; + + position: relative; + z-index: 3; + color: white; + @media (max-width: 1024px) { + padding-left: 0; + padding-right: 0; + } +` + +const BeastDescriptionWrapper = styled.div` + grid-column: 1 / span 2; + grid-row: 2; + + align-content: center; +` + +const BeastDetails = styled.div` + display: block; + width: 100%; + @media (max-width: 1024px) { + display: none; + } +` + +const OfferorId = styled.span` + @media (max-width: 1024px) { + display: none; + } +` +const OfferorIdMobile = styled.span` + display: none; + @media (max-width: 1024px) { + display: block; + font-size: 1.2rem; + } +` + +const OfferorPrice = styled.span` + @media (max-width: 1024px) { + font-size: 1rem; + } +` + +const SharingDiv = styled.div` + display: inline-block; + width: fit-content; ` type Props = { @@ -285,12 +415,43 @@ type Props = { } const ProductBeastView: FC = ({ beast, hunterData }) => { - const [heart, setHeart] = useState(heartEmpty) + // const [heart, setHeart] = useState(heartEmpty) const [listBeastForSaleOpen, setListBeastForSaleOpen] = useState(false) const [placeABidOpen, setPlaceABidOpen] = useState(false) const [acceptOfferOpen, setAcceptOfferOpen] = useState(false) const [bestOffer, setBestOffer] = useState(null) + const [windowWidth, setWindowWidth] = useState() + const [isMobile, setIsMobile] = useState(false) + + useEffect(() => { + if (window.innerWidth) { + // window.addEventListener("resize", () => { + // if (window.innerWidth > 420) { + // console.log(window.innerWidth) + // setIsMobile(true) + // } + // setWindowWidth(window.innerWidth) + // }) + if (window.innerWidth < 420) { + console.log(window.innerWidth) + setIsMobile(true) + } + console.log(window.innerWidth) + } + }, []) + useEffect(() => { + if (window.innerWidth) { + window.addEventListener("resize", () => { + if (window.innerWidth < 420) { + console.log(window.innerWidth) + setIsMobile(true) + } + setWindowWidth(window.innerWidth) + }) + } + }, []) + const { purchaseBeast, delistBeast, @@ -317,16 +478,13 @@ const ProductBeastView: FC = ({ beast, hunterData }) => { getUserFUSDBalance("0xfa252d0aa22bf86a") }, []) - const heartChange = () => { - { - heart == heartEmpty ? setHeart(heartFull) : setHeart(heartEmpty) - } - } const Accordion = ({ + icon, title, content, defaultActive, }: { + icon: any title: any content: any defaultActive: Boolean @@ -334,22 +492,43 @@ const ProductBeastView: FC = ({ beast, hunterData }) => { const [isActive, setIsActive] = useState(defaultActive) return ( - - -
      {title}
      - <> - {" "} - setIsActive(!isActive)}> - {isActive ? ( -
      - ) : ( -
      - )} -
      - -
      - {isActive && {content}} -
      + <> + {beast ? ( + + setIsActive(!isActive)}> +
      + + {title} +
      + + {isActive ? ( + + ) : ( + + )} + +
      + {isActive && {content}} +
      + ) : ( + + setIsActive(!isActive)}> +
      + + {title} +
      + + {isActive ? ( + + ) : ( + + )} + +
      + {isActive && Loading...} +
      + )} + ) } @@ -362,39 +541,37 @@ const ProductBeastView: FC = ({ beast, hunterData }) => { {/* */}

      Dex number

      - #{("00" + beast?.dexNumber).slice(-3)} + + {/* DG CHecking if the beast is defined, and while it's not, we are displaying the message Loading... */} + #{beast ? ("00" + beast?.dexNumber).slice(-3) : "Loading..."} +
      Skin -

      {beast?.skin}

      +

      {beast ? beast?.skin : "Loading..."}

      Element -

      {beast?.elements}

      +

      {beast ? beast?.elements : "Loading..."}

      Star Level -

      {beast?.starLevel}

      +

      {beast ? beast?.starLevel : "Loading..."}

      - Basic Skills -
        - {beast?.basicSkills.map((skill: any, id: any) => ( -
      • - {skill} -
      • - ))} -
      + Gender +

      {beast ? beast?.sex : "Loading..."}

      Ultimate Skill -

      {beast?.ultimateSkill}

      +

      {beast ? beast?.ultimateSkill : "Loading..."}

      ) } + const accordionOffers: any = (beast: any) => { let offerday = 5 let offerweek = 3 @@ -406,64 +583,79 @@ const ProductBeastView: FC = ({ beast, hunterData }) => { ?.filter((offer: any) => offer?.beastID == beast?.id) .sort((a: any, b: any) => b.offerAmount - a.offerAmount) .map((offer: any) => ( - <> -
    • - - - hunter.address == offer?.offeror, - )?.[0]?.avatar || profilePictures[1].image - } - alt="first owner avatar" - /> -
      - - {hunterData?.filter( - (hunter: any) => hunter.address == offer?.offeror, - )?.[0]?.findName != null ? ( - <> - {hunterData?.filter( - (hunter: any) => - hunter.address == offer?.offeror, - )?.[0]?.findName != "" - ? hunterData?.filter( - (hunter: any) => - hunter.address == offer?.offeror, - )?.[0]?.findName - : offer?.offeror}{" "} - - ) : ( - offer?.offeror - )} - - {/* Wait with time of offers */} - {/*

      +
    • + + + hunter.address == offer?.offeror, + )?.[0]?.avatar || profilePictures[1].image + } + alt="first owner avatar" + /> +
      + + {hunterData?.filter( + (hunter: any) => hunter.address == offer?.offeror, + )?.[0]?.findName != null ? ( + <> + {hunterData?.filter( + (hunter: any) => hunter.address == offer?.offeror, + )?.[0]?.findName != "" + ? hunterData?.filter( + (hunter: any) => + hunter.address == offer?.offeror, + )?.[0]?.findName + : offer?.offeror + .slice(0, 6) + .concat("...") + .concat(offer?.offeror.slice(-4))}{" "} + + ) : ( + offer?.offeror + )} + + + {hunterData?.filter( + (hunter: any) => hunter.address == offer?.offeror, + )?.[0]?.findName != null ? ( + <> + {hunterData?.filter( + (hunter: any) => hunter.address == offer?.offeror, + )?.[0]?.findName != "" + ? hunterData?.filter( + (hunter: any) => + hunter.address == offer?.offeror, + )?.[0]?.findName + : offer?.offeror}{" "} + + ) : ( + offer?.offeror + )} + + {/* Wait with time of offers */} + {/*

      {offerday} day{offerday > 1 && "s "} ago | Expires in{" "} {offerweek} week {offerweek > 1 && "s "} | Floor bid

      */} -
      -
      - - {parseFloat( - parseFloat(offer?.offerAmount.toString()).toFixed(2), - )}{" "} - FUSD - - {user?.addr == offer?.offeror && ( - removeOffer(offer?.offerID)}> - Remove - - )} -
      -
    • - +

      +
      + + {parseFloat( + parseFloat(offer?.offerAmount.toString()).toFixed(2), + )}{" "} + FUSD + + {user?.addr == offer?.offeror && ( + removeOffer(offer?.offerID)}> + Remove + + )} +
      +
    • ))} - {/* {something.map((offer: any) => ( */} - - {/* ))} */}
    ) @@ -481,18 +673,16 @@ const ProductBeastView: FC = ({ beast, hunterData }) => { setOpen={setPlaceABidOpen} beast={beast} /> - -
    -
    + {/* className="mx-5 px-5" */} + + {/* className="mx-auto w-1/2" */} + {beast ? ( = ({ beast, hunterData }) => { ))} - + ) : ( + + + + )} + + + + console.log(windowWidth)}> - {allBeastOffers?.filter((offer: any) => offer?.beastID == beast?.id) - .length > 0 && ( - - - - )} -
    - -
    -

    {beast?.nickname + " " + "#" + beast?.serialNumber}

    - - - - hunter.address == beast?.firstOwner, - )?.[0]?.avatar - } - alt="first owner avatar" - /> -
    -

    first owner

    -

    - {hunterData?.filter( - (hunter: any) => hunter.address == beast?.firstOwner, - )?.[0]?.findName != "" - ? hunterData?.filter( - (hunter: any) => - hunter.address == beast?.firstOwner, - )?.[0]?.findName - : beast?.firstOwner} -

    -
    -
    -
    - - - hunter.address == beast?.currentOwner, - )?.[0]?.avatar - } - alt="current owner avatar" + {/* DG Checking if beast is defined, and while it's not, we are displaying a message Loading Offers... */} + {beast + ? allBeastOffers?.filter( + (offer: any) => offer?.beastID == beast?.id, + ).length > 0 && ( + + -
    -

    current owner

    -

    - {hunterData?.filter( - (hunter: any) => hunter.address == beast?.currentOwner, - )?.[0]?.findName != "" - ? hunterData?.filter( - (hunter: any) => - hunter.address == beast?.currentOwner, - )?.[0]?.findName - : beast?.currentOwner} -

    -
    -
    -
    -
    - {/* social share, refresh, favorite */} - {/*
    -
      -
    • heartChange()}> - {" "} -

      76

      -
    • -
    • - {" "} -

      Share

      -
    • -
    • - -

      Refresh

      -
    • -
    - -
    */} -
    + + ) + : "Loading Offers..."} + + + + {beast ? ( +

    {beast?.nickname + " " + "#" + beast?.serialNumber}

    + ) : ( +

    Loading...

    + )} + + + +
    +
    {beast?.price != null && ( @@ -667,11 +818,17 @@ const ProductBeastView: FC = ({ beast, hunterData }) => { {beastsForSale ?.map((beast: any) => beast.id) .includes(beast?.id) ? ( - delistBeast(beast?.id)}> + delistBeast(beast?.id)} + > Delist ) : ( - setListBeastForSaleOpen(true)}> + setListBeastForSaleOpen(true)} + > List for sale )} @@ -696,7 +853,7 @@ const ProductBeastView: FC = ({ beast, hunterData }) => { )} {user?.addr != beast?.currentOwner && ( setPlaceABidOpen(true)}> - Place a bid + Make offer )} {user?.addr == beast?.currentOwner && bestOffer != null && ( @@ -707,13 +864,91 @@ const ProductBeastView: FC = ({ beast, hunterData }) => { {/*

    Sale ends in [time]

    */} - {/* ) : ( -
    - Make an offer -
    - )} */} - {" "} -
    + + {beast ? ( + + + + hunter.address == beast?.firstOwner, + )?.[0]?.avatar + } + alt="first owner avatar" + /> +
    +

    first owner

    +

    + {hunterData?.filter( + (hunter: any) => hunter.address == beast?.firstOwner, + )?.[0]?.findName != "" + ? hunterData?.filter( + (hunter: any) => + hunter.address == beast?.firstOwner, + )?.[0]?.findName + : beast?.firstOwner} +

    +
    +
    +
    + + + + hunter.address == beast?.currentOwner, + )?.[0]?.avatar + } + alt="current owner avatar" + /> +
    +

    current owner

    +

    + {hunterData?.filter( + (hunter: any) => + hunter.address == beast?.currentOwner, + )?.[0]?.findName != "" + ? hunterData?.filter( + (hunter: any) => + hunter.address == beast?.currentOwner, + )?.[0]?.findName + : beast?.currentOwner} +

    +
    +
    +
    +
    + ) : ( + + + + +
    +

    first owner

    +

    Owner address loading...

    +
    +
    +
    + + + +
    +

    Current owner

    +

    Owner address loading...

    +
    +
    +
    +
    + )} + + {/* + + */} +
    + +
    {/* Maybe for later showcase more beasts */} {/*

    More Basic Beasts

    */} diff --git a/components/ui/ProductBeastView/SocialMediaShare.tsx b/components/ui/ProductBeastView/SocialMediaShare.tsx new file mode 100644 index 0000000..eed04cf --- /dev/null +++ b/components/ui/ProductBeastView/SocialMediaShare.tsx @@ -0,0 +1,312 @@ +import { FC, useEffect, useState } from "react" +import styled from "styled-components" +import { useRouter } from "next/router" +import FB from "public/social_icons/iconFacebook.svg" +import TW from "public/social_icons/iconTwitter.svg" +import WT from "public/social_icons/iconWhatsapp.svg" +import TG from "public/social_icons/iconTelegram.svg" +import COPY from "public/social_icons/copyIcon.svg" +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome" +import { RefreshIcon } from "@heroicons/react/outline" +import { + faEllipsisH, + faShareSquare, + faHeart as heartFull, + faCaretUp, +} from "@fortawesome/free-solid-svg-icons" +import { faHeart as heartEmpty } from "@fortawesome/free-regular-svg-icons" +import { toast } from "react-toastify" + +const SocialMedia = styled.div` + position: relative; + z-index: 1; + width: auto; + + display: grid; + grid-template-columns: auto auto auto; + gap: 1rem; + + justify-items: center; + justify-content: space-between; + align-items: center; + + @media (max-width: 400px) { + justify-content: center; + margin: 1rem auto 0 auto; + gap: 1rem; + } +` + +const HeartDiv = styled.div` + display: inline-block; + &:hover { + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) + 14 0, + pointer !important; + } +` + +const ShareDiv = styled.div` + display: inline-block; + &:hover { + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) + 14 0, + pointer !important; + } +` + +const RefreshDiv = styled.div` + display: inline-block; + + &:hover { + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) + 14 0, + pointer !important; + } +` + +const Refresh = styled.div` + width: 1rem; + height: auto; + grid-column: 1; +` + +const ShareDropdownDiv = styled.div` + position: absolute; + top: 150%; + right: 50%; + z-index: 3; + background-color: #212127; + border-radius: 0.5rem; + width: 220%; + border: 1px solid #626262; + + & ul { + list-style-type: none; + padding: 0; + width: fit-content; + + & li { + border-bottom: 0.5px solid #626262; + + &.first { + &:hover { + box-shadow: 0px 3px 7px -4px white; + } + } + + &.last { + border-bottom: none; + &:hover { + box-shadow: 0px -3px 7px -4px white; + } + } + + &:hover { + cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) + 14 0, + pointer !important; + /* background-color: #181d24;*/ + box-shadow: 0px 3px 7px -4px white, 0px -3px 7px -4px white; + } + + & button { + padding: 1rem; + display: grid; + grid-template-columns: 15% 80%; + gap: 5%; + width: 100%; + justify-content: space-between; + align-items: center; + + @media (max-width: 100px) { + width: 50%; + margin: 0; + } + + & h2 { + grid-column: 2; + width: fit-content; + padding: 0; + + @media (max-width: 1100px) { + font-size: 0.8rem; + } + } + } + } + } +` + +const Icon = styled.img` + grid-column: 1; + width: 100%; + height: auto; + padding: 0; + + &.copy { + height: 100%; + } +` + +const Share = styled.div` + display: flex; + width: fit-content; +` + +const SocialMediaShare: FC = ({}) => { + const router = useRouter() + + const url = "https://www.basicbeasts.io" + router.asPath + const text = "Check out this Beast! @basicbeastsnft" + const [heart, setHeart] = useState(heartEmpty) + + function shareTw() { + window.open( + "https://twitter.com/intent/tweet?text=" + + encodeURIComponent(text) + + "&url=" + + encodeURIComponent(url), + "", + "menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=350,width=600", + ) + return false + } + + function shareFb() { + window.open( + "http://www.facebook.com/share.php?u=" + encodeURIComponent(url), + ) + return false + } + + function shareTg() { + window.open( + "https://t.me/share/url?url=" + + encodeURIComponent(url) + + "&text=" + + encodeURIComponent(text), + ) + return false + } + + function shareWs() { + window.open( + "https://wa.me/?text=" + + encodeURIComponent(text) + + " " + + encodeURIComponent(url), + ) + return false + } + + const heartChange = () => { + { + heart == heartEmpty ? setHeart(heartFull) : setHeart(heartEmpty) + } + } + + const testURL = "http://localhost:3000/" + router.asPath + + const copyLink = (e: any) => { + navigator.clipboard.writeText(testURL) + toast("Copied to clipboard") + } + + const ShareToggle = ({ + title, + content, + defaultActive, + }: { + title: any + content: any + defaultActive: Boolean + }) => { + const [isActive, setIsActive] = useState(defaultActive) + + return ( + <> + setIsActive(!isActive)}> + + {/*

    {title}

    */} + {isActive && <>{content}} +
    + + ) + } + + const ShareDropdown = () => { + return ( + <> + +
      +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    • + +
    • +
    +
    + + ) + } + + function refreshPage() { + router.reload() + } + + return ( + + heartChange()}> + {" "} + + + + + refreshPage()}> + + + + + {/*

    Refresh

    */} +
    +
    + ) +} + +export default SocialMediaShare diff --git a/components/ui/ProfileTabs/ProfileTabs.tsx b/components/ui/ProfileTabs/ProfileTabs.tsx index e1dd486..fd1a784 100644 --- a/components/ui/ProfileTabs/ProfileTabs.tsx +++ b/components/ui/ProfileTabs/ProfileTabs.tsx @@ -60,6 +60,7 @@ type Props = { sushiBalance: any emptyPotionBottleBalance: any poopBalance: any + lovePotionBalance: any newBeast: any setNewBeast: any newTokens: any @@ -70,6 +71,7 @@ type Props = { allEvolutionPairs: any getPersonalDexicon: any walletAddress: any + eggs: any } const ProfileTabs: FC = ({ @@ -82,6 +84,7 @@ const ProfileTabs: FC = ({ sushiBalance, emptyPotionBottleBalance, poopBalance, + lovePotionBalance, newBeast, setNewBeast, newTokens, @@ -92,6 +95,7 @@ const ProfileTabs: FC = ({ allEvolutionPairs, getPersonalDexicon, walletAddress, + eggs, }) => { const [hasPacks, setHasPacks] = useState(false) @@ -165,7 +169,7 @@ const ProfileTabs: FC = ({ notify={filter !== "packs" && hasPacks} /> - {/* + { selectFilter("eggs") @@ -175,7 +179,7 @@ const ProfileTabs: FC = ({ buttonText={"Eggs"} // notify={filter !== "eggs" && newTokens} /> - */} + ) : ( <> @@ -191,6 +195,11 @@ const ProfileTabs: FC = ({ allEvolutionPairs={allEvolutionPairs} getPersonalDexicon={getPersonalDexicon} walletAddress={walletAddress} + sushiBalance={sushiBalance} + emptyPotionBottleBalance={emptyPotionBottleBalance} + poopBalance={poopBalance} + lovePotionBalance={lovePotionBalance} + selectFilter={selectFilter} /> )} {user?.addr == walletAddress ? ( @@ -198,6 +207,7 @@ const ProfileTabs: FC = ({ {filter === "eggs" && ( = ({ hunterData }) => { {table.getRowModel().rows.map((row, i) => ( - - - {row.getVisibleCells().map((cell) => ( - + + {row.getVisibleCells().map((cell) => ( + + {/*
    value: {row.getValue("address")}
    */} {cell.column.id == "findName" ? ( <> @@ -619,10 +619,10 @@ const RankingList: FC = ({ hunterData }) => { )} )} - - ))} - -
    + + + ))} + ))} diff --git a/components/ui/RevealOverlay/RevealOverlay.tsx b/components/ui/RevealOverlay/RevealOverlay.tsx index 0341902..cb10070 100644 --- a/components/ui/RevealOverlay/RevealOverlay.tsx +++ b/components/ui/RevealOverlay/RevealOverlay.tsx @@ -285,19 +285,19 @@ const RevealOverlay: FC = ({ import MetadataViews from 0xMetadataViews import FUSD from 0xFUSD - pub fun hasSushiVault(_ address: Address): Bool { + access(all) fun hasSushiVault(_ address: Address): Bool { return getAccount(address) .getCapability<&Sushi.Vault{FungibleToken.Balance}>(Sushi.BalancePublicPath) .check() } - pub fun hasPoopVault(_ address: Address): Bool { + access(all) fun hasPoopVault(_ address: Address): Bool { return getAccount(address) .getCapability<&Poop.Vault{FungibleToken.Balance}>(Poop.BalancePublicPath) .check() } - pub fun hasEmptyPotionBottleVault(_ address: Address): Bool { + access(all) fun hasEmptyPotionBottleVault(_ address: Address): Bool { return getAccount(address) .getCapability<&EmptyPotionBottle.Vault{FungibleToken.Balance}>(EmptyPotionBottle.BalancePublicPath) .check() diff --git a/components/ui/SearchBar/SearchBar.tsx b/components/ui/SearchBar/SearchBar.tsx index ead289e..27f7b37 100644 --- a/components/ui/SearchBar/SearchBar.tsx +++ b/components/ui/SearchBar/SearchBar.tsx @@ -502,9 +502,14 @@ const SearchBar: FC<{ {filterBeastData.slice(0, 15).map((value: any, key: any) => { return ( { setOpen(false) @@ -513,7 +518,13 @@ const SearchBar: FC<{ >

    {" "} - {value.name}{" "} + {" "} + {value.name}{" "}

    ) diff --git a/components/ui/SearchBarMobileModal/SearchBarMobileModal.tsx b/components/ui/SearchBarMobileModal/SearchBarMobileModal.tsx index e03b23d..93c1e3e 100644 --- a/components/ui/SearchBarMobileModal/SearchBarMobileModal.tsx +++ b/components/ui/SearchBarMobileModal/SearchBarMobileModal.tsx @@ -489,7 +489,12 @@ const SearchBar: FC<{ { setOpen(false) diff --git a/components/ui/UserProfile/UserProfile.tsx b/components/ui/UserProfile/UserProfile.tsx index 5960227..b491682 100644 --- a/components/ui/UserProfile/UserProfile.tsx +++ b/components/ui/UserProfile/UserProfile.tsx @@ -52,6 +52,7 @@ type FuncProps = { sushiBalance: any emptyPotionBottleBalance: any poopBalance: any + lovePotionBalance: any newBeast: any setNewBeast: any newTokens: any @@ -68,6 +69,7 @@ type FuncProps = { allEvolutionPairs: any getPersonalDexicon: any walletAddress: any + eggs: any } const UserProfile: FC = ({ @@ -78,6 +80,7 @@ const UserProfile: FC = ({ sushiBalance, emptyPotionBottleBalance, poopBalance, + lovePotionBalance, newBeast, setNewBeast, newTokens, @@ -94,6 +97,7 @@ const UserProfile: FC = ({ allEvolutionPairs, getPersonalDexicon, walletAddress, + eggs, }) => { const [filter, setFilter] = useState< "beast collection" | "items" | "packs" | "eggs" @@ -131,12 +135,14 @@ const UserProfile: FC = ({ filter={filter} selectFilter={setFilter} beasts={beasts} + eggs={eggs} toggle={toggle} selectPackType={selectPackType} packCount={packCount} sushiBalance={sushiBalance} emptyPotionBottleBalance={emptyPotionBottleBalance} poopBalance={poopBalance} + lovePotionBalance={lovePotionBalance} newBeast={newBeast} setNewBeast={setNewBeast} newTokens={newTokens} diff --git a/components/user/UserProvider.tsx b/components/user/UserProvider.tsx index 0d6fdf4..fd7d1b0 100644 --- a/components/user/UserProvider.tsx +++ b/components/user/UserProvider.tsx @@ -30,6 +30,7 @@ const UserProvider: FC = ({ children }) => { purchase, loading, getUserFUSDBalance, + purchasePackType, } = useFUSD(user) const { data: userBeasts, @@ -89,6 +90,7 @@ const UserProvider: FC = ({ children }) => { const { getClaimedFUSDRewards, claimedFUSDRewards } = useFUSDChestRewards() const { + data: beastMarketStuff, beastsForSale, getAllBeastsForSale, purchaseBeast, @@ -156,6 +158,8 @@ const UserProvider: FC = ({ children }) => { getUserFUSDBalance, highestSale, getHighestSale, + beastMarketStuff, + purchasePackType, }} > {children} diff --git a/data/beastData.ts b/data/beastData.ts new file mode 100644 index 0000000..488738c --- /dev/null +++ b/data/beastData.ts @@ -0,0 +1,3930 @@ +export const beastData = [ + { + beastTemplateID: 1, + dexNumber: 1, + name: "Moon", + description: + "A Moon slightly resembles a bunny. With strange ears on its head it shocks everything around it.", + image: "QmUxhM9Lt5tVEc9r6nJowZmTb4BNhP1TtwE92vHprXZ3gW", + imageTransparentBg: "QmYah8PdbRXwjxq4U6ETJeyRkRn8gTCj91fvL8Bc6akbUY", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 1, + maxAdminMintAllowed: 1000, + ultimateSkill: "Mega Volt Crash", + basicSkills: ["Triple Kick", "Moon Shock", "Gravity Pull"], + elements: ["Electric"], + packReveal: "QmQ6FVAEgw4PAoebS4STd9VpuPo4yoMj69oSYGR79fpwqW", + thumbnail: "QmdmHd6K8Fun2nTPtXpXs1yZVyP1wK9Uuat16EQfdFrX4Y", + }, + { + beastTemplateID: 2, + dexNumber: 1, + name: "Moon", + description: + "A Moon slightly resembles a bunny. With strange ears on its head it shocks everything around it.", + image: "QmTF3j75GzNF9fyyeBJ8pVqTws9t7hnVH5k7Q2PWBpBEX9", + imageTransparentBg: "QmctHb2Wm8xQxGrLymGxfHDjNHzsL9wqAjr2PoDpq6FL9e", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 1, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Mega Volt Crash", + basicSkills: ["Triple Kick", "Moon Shock", "Gravity Pull"], + elements: ["Electric"], + packReveal: "Qmd3vsQznQXnmaPeV33beg6EgcNei27Vjy5PeRqtUsfB5C", + thumbnail: "Qmbj4BA18AwC6LzTwzGGSuNQa8i6kiqVC8RrGBUD9F6m6z", + }, + { + beastTemplateID: 3, + dexNumber: 1, + name: "Moon", + description: + "A Moon slightly resembles a bunny. With strange ears on its head it shocks everything around it.", + image: "QmWXoDbvqAQhFPqcuLdWBwFtWDqXigpGMdShNk6VmKgtex", + imageTransparentBg: "Qmb4mBwUAWUDu8SuJVrH9WDgRnHD8hxrAR9m9trgeJ5gb6", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 1, + maxAdminMintAllowed: 200, + ultimateSkill: "Mega Volt Crash", + basicSkills: ["Triple Kick", "Moon Shock", "Gravity Pull"], + elements: ["Electric"], + packReveal: "QmRMuvDpMd3EEobBM2YvPkZKZYhhg889k8TE7N2fGjdJLk", + thumbnail: "Qmb6m1ZELeomHudKxha5HVH5mFcG3Hyq4Fhdd4tT72m46t", + }, + { + beastTemplateID: 4, + dexNumber: 1, + name: "Moon", + description: + "A Moon slightly resembles a bunny. With strange ears on its head it shocks everything around it.", + image: "QmUgcWoude3U1UvuUwqgiQUvxE5Nh9dCcEgv7fWeEov9hv", + imageTransparentBg: "Qmboq29s7MAJTaivf7tcZE1Gio7S4tmTdoWZ5YwJPYJonu", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 1, + maxAdminMintAllowed: 50, + ultimateSkill: "Mega Volt Crash", + basicSkills: ["Triple Kick", "Moon Shock", "Gravity Pull"], + elements: ["Electric"], + packReveal: "QmdWHmjirxhWfWCLfdWwL7L1AW1fZAYougTaErQaEDpLiM", + thumbnail: "QmYTV6LUuXYh5SN1hdhtD5hMCPjeuJXEg2it4wzNzrRa5i", + }, + { + beastTemplateID: 16, + dexNumber: 4, + name: "Saber", + description: + "A Saber loves to smile. It has teeth strong enough to break even diamond hands...", + image: "QmcHRwEDpwuw9BwkKjGAk2KPcf4pAzPA48tG2oFjM4PmbZ", + imageTransparentBg: "QmfBmw4iVZh4J5bfr3fLrgxdabQw4ZvLd6iaDkVUuRBkQy", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 16, + maxAdminMintAllowed: 1000, + ultimateSkill: "Supersonic Wave", + basicSkills: ["Frenzy", "Water Drop", "Saber Bite"], + elements: ["Water"], + packReveal: "QmdJ3SfbrR9TQzHUQYewYFPJiRyJWHmEpeEbkeLYrLqRMu", + thumbnail: "Qmbw3z7ataRF6L84JwuVfFKZ9MBdf6kJ2gz83BFjf1Bc1h", + }, + { + beastTemplateID: 17, + dexNumber: 4, + name: "Saber", + description: + "A Saber loves to smile. It has teeth strong enough to break even diamond hands...", + image: "QmPe7AWH6MRpBxU34hFmGeMyQGmF2yCCrVg1uPwudfKsdV", + imageTransparentBg: "QmcGVZhvpnq5P1dpKtCBKM6vJk2Q3hdfc4BS4o2yoZzDSD", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 16, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Supersonic Wave", + basicSkills: ["Frenzy", "Water Drop", "Saber Bite"], + elements: ["Water"], + packReveal: "QmcAfjSPyGo2QzpuuxEP9ucp9AeDfmRNFt3ox9QUybVP1E", + thumbnail: "QmVFWFxceRfLgSS7HZ7AsaMv7ChmeUbTsMFR7RJYt91T4R", + }, + { + beastTemplateID: 18, + dexNumber: 4, + name: "Saber", + description: + "A Saber loves to smile. It has teeth strong enough to break even diamond hands...", + image: "QmTUACUvfDuwvdYEZ5pDN4nfco1SmuupNpNEYcZ7T2pDxW", + imageTransparentBg: "QmaB2ywU97uWJX5436Y7scxtWxaBGu5d4e4uTPG1AH5wFa", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 16, + maxAdminMintAllowed: 200, + ultimateSkill: "Supersonic Wave", + basicSkills: ["Frenzy", "Water Drop", "Saber Bite"], + elements: ["Water"], + packReveal: "QmRKPgAYwvawGbJGAEvD9StH1gZiz8wbCZ1c9rZCzor8CK", + thumbnail: "QmQE3f5U2pQxxrPM9riRtzaDpPsNryh7joBCL5E1mDBbtH", + }, + { + beastTemplateID: 19, + dexNumber: 4, + name: "Saber", + description: + "A Saber loves to smile. It has teeth strong enough to break even diamond hands...", + image: "QmU7JrrzqMzaEGNgBNwvTU4Uzj2cCrTVN1oNSFG5pMwUgD", + imageTransparentBg: "QmWyPu4d15j5YZPLusm6Uh5fmBzZnHjyPAeZLavZxzSnUR", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 16, + maxAdminMintAllowed: 50, + ultimateSkill: "Supersonic Wave", + basicSkills: ["Frenzy", "Water Drop", "Saber Bite"], + elements: ["Water"], + packReveal: "QmYdVXSkZ81VTsNEfczJ7jSzG1H2H2yvZwR8aQArHPnUP5", + thumbnail: "QmUo17LgsqZeKMzBeYn4LdjxoD5PVQbNYmCZuDvYPVzSo4", + }, + { + beastTemplateID: 31, + dexNumber: 7, + name: "Shen", + description: "A Shen is said to be born from magical dust.", + image: "QmdB2djF1YqWMFT43ysbhzYLgWL4cQoH9ExdxjahGo8Wyd", + imageTransparentBg: "QmU9yyT58z8aHpbHFHZSoRcuVCnJKb3ReW8vo555gfmhsk", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 31, + maxAdminMintAllowed: 1000, + ultimateSkill: "Tackle", + basicSkills: ["Camouflage", "Magic Dust", "Petal Wish"], + elements: ["Grass"], + packReveal: "QmVAJWtLNAmT87DRbccCsd3ZQYZedyA8S678GdRVnWKnwD", + thumbnail: "Qmdz5iZ9pq4BY9enwv4u9DaGcgAxaPKjjoj7cw6NMVPSp1", + }, + { + beastTemplateID: 32, + dexNumber: 7, + name: "Shen", + description: "A Shen is said to be born from magical dust.", + image: "QmXRpCJUJAFnrf4znK1yiAmQCFjjv1fqdpA8Jf2bkYFV1X", + imageTransparentBg: "QmZCg7XyDq4gVJg82xkU3KnT4JApL9M2m9n1P53gdqcUa9", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 31, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Tackle", + basicSkills: ["Camouflage", "Magic Dust", "Petal Wish"], + elements: ["Grass"], + packReveal: "QmfM3dieRevRdEsWyekjmkW93aeBv7sFEzu3GnVmRuVHPS", + thumbnail: "QmYpNJXUyKiLzi3wsaaSfiHFcZ9ZMNjSWqNHBnMHq9qMNN", + }, + { + beastTemplateID: 33, + dexNumber: 7, + name: "Shen", + description: "A Shen is said to be born from magical dust.", + image: "QmRaH6fC4QprQvHAdwzoG6Jgsqqgr6sEd9n9Rx28shqU6o", + imageTransparentBg: "QmcaUeBKoNh5eDG5KndoTW9V6s3pEG8u35iYi3tcwGW8cW", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 31, + maxAdminMintAllowed: 200, + ultimateSkill: "Tackle", + basicSkills: ["Camouflage", "Magic Dust", "Petal Wish"], + elements: ["Grass"], + packReveal: "QmQ1iHAuFvTMN298z6sV8wbeuxZjLmBDNPP8Mj6xG1WCYp", + thumbnail: "QmcRv6rx1DbDsfNeGKEFWqHQGZwDVgC7jjTyRsd53RmZmP", + }, + { + beastTemplateID: 34, + dexNumber: 7, + name: "Shen", + description: "A Shen is said to be born from magical dust.", + image: "QmUvr5ohGuXNurvjdEyBBFmukNBeDKwEGhxFafStqNmxqw", + imageTransparentBg: "QmYmaZfD62B1qPsaEUrYSpVAYV6jbU8nTgDfgp38wiozgD", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 31, + maxAdminMintAllowed: 50, + ultimateSkill: "Tackle", + basicSkills: ["Camouflage", "Magic Dust", "Petal Wish"], + elements: ["Grass"], + packReveal: "QmfHvxMdLXoUHaaj6Mzp3HYVyksyqMXy9GZEnpXf6QzyC1", + thumbnail: "QmYx8Chpe5gHeFQ5nn79GZBLAFvSKEzucq5Dysq1hXqM3H", + }, + { + beastTemplateID: 46, + dexNumber: 10, + name: "Azazel", + description: + "An Azazel is afraid of darkness. It closes its eyes when it senses danger.", + image: "QmWNUuriEhvGimpBnvb83RGzis5enRGLFNJMpmCXa2EsGY", + imageTransparentBg: "QmcK3TEBeVZvjmMrcUH5vQSqPC1NF1WQuzvtH4ebEeML5Q", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 46, + maxAdminMintAllowed: 1000, + ultimateSkill: "Phantom Force", + basicSkills: ["Overheat", "Blazing Strike", "Fire Ball"], + elements: ["Fire"], + packReveal: "QmUKREEoTtYeEtgEhXNEkfUazQp65DVqw33FTf5o37k5Fo", + thumbnail: "QmPjke1EwzyHscB61qjJkS7mKwyH3r3KtxwrmjgVyRsJPi", + }, + { + beastTemplateID: 47, + dexNumber: 10, + name: "Azazel", + description: + "An Azazel is afraid of darkness. It closes its eyes when it senses danger.", + image: "QmQjtAT3G7A88u8jndZjDpmCSq1REN9ozRmngNu2pUbVQs", + imageTransparentBg: "Qmcs26Jvcv4x9xXTaYwVCmUgDYSxEKJgqwCWbrdgCqVLY2", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 46, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Phantom Force", + basicSkills: ["Overheat", "Blazing Strike", "Fire Ball"], + elements: ["Fire"], + packReveal: "Qma2evqX7MXocMJc9Sknn6Uhu6rbnyX3UKwcigACtsQ9YE", + thumbnail: "QmSKpvkTi4mKD8DeejEAuNn16FoWjYZhiy3CrLPCoi52PL", + }, + { + beastTemplateID: 48, + dexNumber: 10, + name: "Azazel", + description: + "An Azazel is afraid of darkness. It closes its eyes when it senses danger.", + image: "QmeHntpRCWMvB8fpTfDHfv8bAdcTqSBxqjZE8MZm7iimHh", + imageTransparentBg: "QmbP2ywYKpzwGCo9C8MTamhzUMdvtGdLFWLGrFww5TzPZz", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 46, + maxAdminMintAllowed: 200, + ultimateSkill: "Phantom Force", + basicSkills: ["Overheat", "Blazing Strike", "Fire Ball"], + elements: ["Fire"], + packReveal: "QmT46vJFvdMoCFT1Hmy4dsxh6ywb6CNLkCCfTXgM3vUy3a", + thumbnail: "QmaNSYrwBXi7E5ZzHLXKRYPV5i7MZCDt3GAQznouQwwE34", + }, + { + beastTemplateID: 49, + dexNumber: 10, + name: "Azazel", + description: + "An Azazel is afraid of darkness. It closes its eyes when it senses danger.", + image: "QmNsWWiuNEERpaetF9mWBL9NaiRpgM8eSf9YPZK8tkuvUM", + imageTransparentBg: "QmQsASAx7Xg5MZCfFejXMyucHW9T7YuMv4USBFkPb1sb3y", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 46, + maxAdminMintAllowed: 50, + ultimateSkill: "Phantom Force", + basicSkills: ["Overheat", "Blazing Strike", "Fire Ball"], + elements: ["Fire"], + packReveal: "QmbE3P2Gbc5vqfENvTHhDocmnLqFLgsgZasnXeSdbxJGP3", + thumbnail: "QmRtVfEqLfLCKv73YAeaAB7KY7zqys6NJgmMDDGeFsQWTt", + }, + { + beastTemplateID: 61, + dexNumber: 13, + name: "Teddy", + description: "A Teddy never sleeps. It eats when it's stressed.", + image: "QmTtQZg9KuBc1LjaWXGoB69SutxQUB5TJTssnvYbngBAsc", + imageTransparentBg: "QmZQwPJ1AoJUEkYj1aGamKAvrptoomsM4rL7zqzj1UGVnP", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 61, + maxAdminMintAllowed: 1000, + ultimateSkill: "Hyper Room", + basicSkills: ["Silent Fart", "Frustration", "Depression"], + elements: ["Normal"], + packReveal: "QmVR6gBob1fi6uK3MFXvc2Qw3pXQHP4MxsFuboRgbByMn4", + thumbnail: "QmNtQ57VRSPJVty4pTLhLDaQznbk6D7k5c9vse2kZ9L5FA", + }, + { + beastTemplateID: 62, + dexNumber: 13, + name: "Teddy", + description: "A Teddy never sleeps. It eats when it's stressed.", + image: "QmcvCizbCmUSxEC92KeXUM2RrKsnMJyQQgzR1QFdWGcdsD", + imageTransparentBg: "QmTgVExMrXr2EoakLB56N4gsnMunCVXUKGYpCyvFiJzMvF", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 61, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Hyper Room", + basicSkills: ["Silent Fart", "Frustration", "Depression"], + elements: ["Normal"], + packReveal: "QmStULB1yyB7cHXzLkPjtA5dpr1uVhX6So1Ch3nDSEDf55", + thumbnail: "QmW1GPyeAVhMQv1EMiBoPnZPh1CmGgfJhWdMjUbVHSkGCZ", + }, + { + beastTemplateID: 63, + dexNumber: 13, + name: "Teddy", + description: "A Teddy never sleeps. It eats when it's stressed.", + image: "QmfVbrt8juWubVfkG6Xu1UGDcZ9Y3KopebHDmRapVkFUba", + imageTransparentBg: "QmfL7qihCqbnJdsG6Bd2XM6RiDrJ8o1N5EVp4VxAg7Re2g", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 61, + maxAdminMintAllowed: 200, + ultimateSkill: "Hyper Room", + basicSkills: ["Silent Fart", "Frustration", "Depression"], + elements: ["Normal"], + packReveal: "Qmet3Jno54KtqngAXD7mXDfLxHyqNgnjhg4cYEn4ZXQkXV", + thumbnail: "QmNiMDmZtY7LZJdRVz6ijuHPt6PVQ7qhk5VX3kZU1cmFne", + }, + { + beastTemplateID: 64, + dexNumber: 13, + name: "Teddy", + description: "A Teddy never sleeps. It eats when it's stressed.", + image: "QmPHjhX3wLGTLYxL7kSZA41rnnEW8PizYKqLTM5tfT5doo", + imageTransparentBg: "QmdJrf3tsSBWw8wYWaKEyC84tPPgqDaGa7djFfhDipUxd1", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 61, + maxAdminMintAllowed: 50, + ultimateSkill: "Hyper Room", + basicSkills: ["Silent Fart", "Frustration", "Depression"], + elements: ["Normal"], + packReveal: "QmaWDCcSM9hShJJTqbEFeAyBzferYYWTLpBMbSHLG3znCu", + thumbnail: "QmTTH5UrKkgFCcWziCqQfjw2JP7tM9ehHf2FcseDzgrNxW", + }, + { + beastTemplateID: 76, + dexNumber: 16, + name: "Viper", + description: "A Viper moves at blinding speeds.", + image: "QmcjUMQnvfpzQ5SZBoCXXFZTNnrwSWmiYMgvjAgmPRX2PS", + imageTransparentBg: "QmTCqf3jHV6cDEHAQpSoEHupRPwavkyD6ddvJHaKffjKc1", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 76, + maxAdminMintAllowed: 1000, + ultimateSkill: "Lightning Wrap", + basicSkills: ["Paralyze Shot", "Twist", "Electric Shield"], + elements: ["Electric"], + packReveal: "QmcxN2bXBCfir8E8pJieRsBktSwAqYLnzhZL3KRp3RLgqZ", + thumbnail: "QmWjLTvGKj46sYHjdZrKPVjKg8JNXZoQ3QhBrPxF7sncWS", + }, + { + beastTemplateID: 77, + dexNumber: 16, + name: "Viper", + description: "A Viper moves at blinding speeds.", + image: "QmTzicCMRhhGunE7yD3jhgaLBiYEmGpkyv7W4AJMLJBAaA", + imageTransparentBg: "QmaREenRyDogBoJe6ZtrGuhy7DAGAFZbey9qqCZMJ9xQCr", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 76, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Lightning Wrap", + basicSkills: ["Paralyze Shot", "Twist", "Electric Shield"], + elements: ["Electric"], + packReveal: "Qma2Pcu6AzHU2KLkXDk2PgwnJTwN1AGEusMNfjCqkinKN3", + thumbnail: "QmWFKaxbuBBBGxZBPcmxz9iWahyoEYVzYacA6x2ivoWF99", + }, + { + beastTemplateID: 78, + dexNumber: 16, + name: "Viper", + description: "A Viper moves at blinding speeds.", + image: "Qmf8ZBGcNNnLrESGtfkBzpwogME7Zhf4AXPbysMkZYsRAk", + imageTransparentBg: "Qmdoc5tTQuEMpp96LAqLwC7MkFvST5jWqBPVykA1bie5ps", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 76, + maxAdminMintAllowed: 200, + ultimateSkill: "Lightning Wrap", + basicSkills: ["Paralyze Shot", "Twist", "Electric Shield"], + elements: ["Electric"], + packReveal: "QmQmzi7RPwayisyzAZX1qJ2MS1xAXTwZgQFgXSR4Ex9m2X", + thumbnail: "Qma5AM5fU6WmHLSEQ4nAy6HghxuFe4BrRzu4pnyWKRmbag", + }, + { + beastTemplateID: 79, + dexNumber: 16, + name: "Viper", + description: "A Viper moves at blinding speeds.", + image: "QmQVuF2kTkwBCLLkteRfyFNz5RgLQ9P2JKHAtivf5XkYLN", + imageTransparentBg: "QmdMCXEjgCmwy27NhK5jXaKdBksDTJujuuW1H9unXJYAKz", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 76, + maxAdminMintAllowed: 50, + ultimateSkill: "Lightning Wrap", + basicSkills: ["Paralyze Shot", "Twist", "Electric Shield"], + elements: ["Electric"], + packReveal: "QmT2hJqTeSgcfFtZtNXUcxzRzvLihoQUDgbjLria2fwFtU", + thumbnail: "QmZMbVmW29JiXC7cpM5yzXjNfQtfDRKNuaFqYqdid31edC", + }, + { + beastTemplateID: 91, + dexNumber: 19, + name: "Blob", + description: + "A Blob lives in secrecy underwater. It becomes invisible when wet.", + image: "QmQjoSc9UMM6Y38BhTm9pfzgW86xvrt2QDBKcQkjEvmkuR", + imageTransparentBg: "QmNRtxdTsmheKp551QxxnxkFS4wSX6S85hJ3BbZ5WxwcSe", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 91, + maxAdminMintAllowed: 1000, + ultimateSkill: "Bi Blast", + basicSkills: ["Water Punch", "Mambo", "Stinging Blow"], + elements: ["Water"], + packReveal: "QmZpPE5vSXgJuomGHpUZPZ7qK6UnZCUpQzzsWk4FaENFwq", + thumbnail: "QmbTf7WMX3F7ScRhNkmPUb8Wm9rkXd6r6LWRh1U1RG14S1", + }, + { + beastTemplateID: 92, + dexNumber: 19, + name: "Blob", + description: + "A Blob lives in secrecy underwater. It becomes invisible when wet.", + image: "QmbLg4Fj54HyYA9RMswjVxyGywcfVtZKFMnGVfhEyvgQPG", + imageTransparentBg: "QmfKmKMbj3UxPfEQi1shjGtATTTXTWciubAnKbgqN11c3g", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 91, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Bi Blast", + basicSkills: ["Water Punch", "Mambo", "Stinging Blow"], + elements: ["Water"], + packReveal: "QmWdAPvUZbvSEYpkmVh7QTtZsBKmSxC5GukpFtvWTA7PMk", + thumbnail: "QmWBz618bWhfVtdhaHzPfniTFXceaPyU6KqpEeeHXP69k3", + }, + { + beastTemplateID: 93, + dexNumber: 19, + name: "Blob", + description: + "A Blob lives in secrecy underwater. It becomes invisible when wet.", + image: "QmfTeBc77o1KcasRksZkKjp5BLGpxeANTuuxRdiXT3cCPG", + imageTransparentBg: "Qmb7qcHUYQcaBTSnYU2LBJfbWi39EGnKfWHbAamPGSaWWb", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 91, + maxAdminMintAllowed: 200, + ultimateSkill: "Bi Blast", + basicSkills: ["Water Punch", "Mambo", "Stinging Blow"], + elements: ["Water"], + packReveal: "QmSWZs7hsfdJCzJBP1oAkqdQPkAA6Fm7gHTKvVLRUeHypL", + thumbnail: "QmWVxfLz7FMBXLzYk97QQ8nUYsg2F7GKtsypkm6f2NA6qY", + }, + { + beastTemplateID: 94, + dexNumber: 19, + name: "Blob", + description: + "A Blob lives in secrecy underwater. It becomes invisible when wet.", + image: "QmTuXSBGFrZAy78b1WwgRfxYbhvznHvhUExi6PHRSycSUw", + imageTransparentBg: "QmdWiiAvEwRLue6XXefgQzgcwiXWXmzzh8pGbhQCzNLbPf", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 91, + maxAdminMintAllowed: 50, + ultimateSkill: "Bi Blast", + basicSkills: ["Water Punch", "Mambo", "Stinging Blow"], + elements: ["Water"], + packReveal: "QmbWpHvPdQbv1YqZh7QsKboD3Tug4RMkAKLd7tEqUMbXTz", + thumbnail: "QmUSXhYKRqo8KUVzwMP1g3iMibWyTBEm8TNS7DsTiBG2cB", + }, + { + beastTemplateID: 106, + dexNumber: 22, + name: "Coco", + description: + "A Coco loves to sneak into things, making it be unnoticeable to others.", + image: "QmdfTA9y2LZWXJmjsS8esxKXbmmEU3uEqKCJ2L8PbNEgja", + imageTransparentBg: "Qmd7FqDsnFowud8Fa7Ks5tT9ypn9sW7myT7kWREuYY9Pvd", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 106, + maxAdminMintAllowed: 1000, + ultimateSkill: "Savage Strikes", + basicSkills: ["Drain", "Coco Dance", "Attack and Hide"], + elements: ["Grass"], + packReveal: "QmatKzbvbzX9bsBkPSfZehhv18gUWn6njep1KoNb5McrQZ", + thumbnail: "Qmbb8h4nGvAC7n5ABimgYXqXrNaEn6nLHRuZqNzJHCz1vT", + }, + { + beastTemplateID: 107, + dexNumber: 22, + name: "Coco", + description: + "A Coco loves to sneak into things, making it be unnoticeable to others.", + image: "QmYjY65RbrSJ2KTND27NE74rD1oHG1tYdkmNVDbT815Dyf", + imageTransparentBg: "QmZUFZjfEVsy5W718SffgswV3SydYMLrpmXLoHUaH1RP9L", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 106, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Savage Strikes", + basicSkills: ["Drain", "Coco Dance", "Attack and Hide"], + elements: ["Grass"], + packReveal: "Qmb2Sx6nSEwqnTEKf6nypVaVPrfqmMXajEnuKYhfRjiSh9", + thumbnail: "QmW7MAtANXSQUHZUaS9iv58DeTvGoo9XxoUJQfcZ2TRycR", + }, + { + beastTemplateID: 108, + dexNumber: 22, + name: "Coco", + description: + "A Coco loves to sneak into things, making it be unnoticeable to others.", + image: "QmcutzKrzY6jPoj2E9oxkBnTnhQC9KYVL8P7yertwU9PBg", + imageTransparentBg: "QmXoMJgFbQ2Ggec73s27BtW8Dceyf6E5oj7F9CneZvWScD", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 106, + maxAdminMintAllowed: 200, + ultimateSkill: "Savage Strikes", + basicSkills: ["Drain", "Coco Dance", "Attack and Hide"], + elements: ["Grass"], + packReveal: "QmZJACk54PBuD1kpCMuPEurpkh9cdmkJC6wS7L5Y5mJtBY", + thumbnail: "Qmf9HQnYLrRkMSmYchXqN7GrtMGjQvDC8QjDRCERrC6YFr", + }, + { + beastTemplateID: 109, + dexNumber: 22, + name: "Coco", + description: + "A Coco loves to sneak into things, making it be unnoticeable to others.", + image: "QmbrARTN5cHBZXF9e1G4GzJA7uKQdEbzAbiuxasMRFck97", + imageTransparentBg: "QmPJ9RZ8jJAvByReSWUnrcEBdY98Ve8rD6wehyGq39e978", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 106, + maxAdminMintAllowed: 50, + ultimateSkill: "Savage Strikes", + basicSkills: ["Drain", "Coco Dance", "Attack and Hide"], + elements: ["Grass"], + packReveal: "QmRPFRPXh4nMx4F38Dx7TFp5dabPbEzZQ2ieJQc6UBi7yd", + thumbnail: "QmVTnfS3LdZrggwSd5mB6gpUBGpPwUUcMBGfoHaaUMB7Wh", + }, + { + beastTemplateID: 121, + dexNumber: 25, + name: "Drago", + description: "A Drago has small wings but cannot fly.", + image: "Qmdzj4Qd5RF3j8sDi7cT1SzC8ighxYDuiFmrAMajDTQqPD", + imageTransparentBg: "Qma2ZjyBNJaEpkKiKxuxnDdok2K6mTRqi3WzwUZCi81e7U", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 121, + maxAdminMintAllowed: 1000, + ultimateSkill: "Lava Bash", + basicSkills: ["Fire Fury ", "Burning Blow", "Ignite"], + elements: ["Fire"], + packReveal: "Qmb3d3vcHfrb4cZttWwq3JvwiHbASnhek93AfbaQYuxPEj", + thumbnail: "QmR5ncpJUNSvQo6w3eqakhsG9XjumZ6NgCwXbzJnPytN7o", + }, + { + beastTemplateID: 122, + dexNumber: 25, + name: "Drago", + description: "A Drago has small wings but cannot fly.", + image: "QmSm6SRPBsVh4tPUadRNaHnZv7r1kSaZGfZBkAMpWUJFSC", + imageTransparentBg: "QmfXXK6Yc9aa1K2zwFcY1U7PCDa4SKVvHJEwNkQBRgCCFm", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 121, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Lava Bash", + basicSkills: ["Fire Fury ", "Burning Blow", "Ignite"], + elements: ["Fire"], + packReveal: "QmVzMRHf32dDy2VB67qaHoPJ8nyNxPVEDAzHstky2Z2Mwv", + thumbnail: "QmchP5TeWTosjY8rcuSV5aqLPjGCBPoCD6WrLmf3YPwhqC", + }, + { + beastTemplateID: 123, + dexNumber: 25, + name: "Drago", + description: "A Drago has small wings but cannot fly.", + image: "QmdM41aUviK55ANaZny3DTwupsxWEM7oWAonvvkab6bG3q", + imageTransparentBg: "QmPBk6xg99T1untz1ghoGoXhvmKttSBEp4u5hp9FEpTmja", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 121, + maxAdminMintAllowed: 200, + ultimateSkill: "Lava Bash", + basicSkills: ["Fire Fury ", "Burning Blow", "Ignite"], + elements: ["Fire"], + packReveal: "Qma5SEyEpob9y4Gab8rRH8otwfEmfatznNX49rrxuabvcq", + thumbnail: "QmWcXV1xffBVLU2cha4aiHaVUUEDJKVRAwQehgDNXNrWXe", + }, + { + beastTemplateID: 124, + dexNumber: 25, + name: "Drago", + description: "A Drago has small wings but cannot fly.", + image: "QmbgZ4N36dBKJiU86yYDzfcD963svtCCEKP2dRZtRtx34P", + imageTransparentBg: "QmQnpWi4JhdfToXKZ3rn8KFRLMEWEv2KA8jcUJ4ygfevMH", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 121, + maxAdminMintAllowed: 50, + ultimateSkill: "Lava Bash", + basicSkills: ["Fire Fury ", "Burning Blow", "Ignite"], + elements: ["Fire"], + packReveal: "QmWwWsCUyqNjG3EFNAHYovi1N4DkoEz4QN7VxYmHXpSxjK", + thumbnail: "QmRbupt9ipXQHQa1Lo1DkXzrZWukMwA7ruVzKFvD1TFNPY", + }, + { + beastTemplateID: 136, + dexNumber: 28, + name: "Chan", + description: + "A Chan is said to steal one's spirit when looking into its eyes. It is very emotional.", + image: "QmRQbbWm91RffXc3cgLoyxSm3DCQVx59qZxwhGXA9g1Qgg", + imageTransparentBg: "QmePEqRbb14aMWjKiyHScw7pXkJ1ug5oVucY7VBMdcHLHh", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 136, + maxAdminMintAllowed: 1000, + ultimateSkill: "Explode", + basicSkills: ["Vanish", "Creep Show", "Summoning Clone"], + elements: ["Normal"], + packReveal: "QmV499c4Vc2nirfvq9vpCLogAMawYattSAZq9GSBGVx6qe", + thumbnail: "QmeGnwwp4xhRsENZWsoN8MicVJQ1ggBvPTvmKmYkCs7Kwp", + }, + { + beastTemplateID: 137, + dexNumber: 28, + name: "Chan", + description: + "A Chan is said to steal one's spirit when looking into its eyes. It is very emotional.", + image: "QmU4KkMQDyD5xbDcyC9nc9YYVQv5RcG2ZLcknygFMYavcy", + imageTransparentBg: "QmXSWyJcAQvjYQj59ZLwSse27bGuHhKBCHcTmHpzeEmPpy", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 136, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Explode", + basicSkills: ["Vanish", "Creep Show", "Summoning Clone"], + elements: ["Normal"], + packReveal: "QmfAAH21AR9mGiusy3M11NomtFuQJ1VJAj77tPc6hSAt89", + thumbnail: "QmYm67qkH3oFTDf6UiCRJrK4LSk6BNWZU7D9SjdXbNkurb", + }, + { + beastTemplateID: 138, + dexNumber: 28, + name: "Chan", + description: + "A Chan is said to steal one's spirit when looking into its eyes. It is very emotional.", + image: "QmYsdV8zGPjDYwPXmGm8BeGtv62bqVVMjBiydgYpYsRDad", + imageTransparentBg: "QmXMr6nnTPTYua3K8piEg71kagKwHU671V8ij3YS8HJp9G", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 136, + maxAdminMintAllowed: 200, + ultimateSkill: "Explode", + basicSkills: ["Vanish", "Creep Show", "Summoning Clone"], + elements: ["Normal"], + packReveal: "Qma645Xpzmv5YK66nptTKJnDTN1GULQ17vRD2wN1m8mBEX", + thumbnail: "QmShHzrWUF8qKT2mAiZuQ92YBDx5gu7WZwj9gWHTvDWyVx", + }, + { + beastTemplateID: 139, + dexNumber: 28, + name: "Chan", + description: + "A Chan is said to steal one's spirit when looking into its eyes. It is very emotional.", + image: "QmXzPX26v2db9XPSSby4icEBVqMjSg1nuhB2W39DG2BPSE", + imageTransparentBg: "QmddVpQ5vdd7vL69Gigh9AKy7hYWBUrV89KCdP4xSPNy1s", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 136, + maxAdminMintAllowed: 50, + ultimateSkill: "Explode", + basicSkills: ["Vanish", "Creep Show", "Summoning Clone"], + elements: ["Normal"], + packReveal: "QmaRMfMPekjih9gAva5torXWjo1RgN1JHKZbLkXeFgozZ3", + thumbnail: "QmbNrVjULDNzD8Lo38NaY6mBF4jeLyUjhcvsNyQ3ocFAfF", + }, + { + beastTemplateID: 151, + dexNumber: 31, + name: "Cron", + description: + "A Cron moves in a group. Together they create a strong magnetic field.", + image: "QmeVqi9najDf9tokjcE8SrRurjR2YJW6wTGzn41G5vcrKL", + imageTransparentBg: "QmYt7iJHgpTzf6mJyrdwpkfptDNhhNa2HAfNPfiffWFTeu", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 151, + maxAdminMintAllowed: 1000, + ultimateSkill: "Thunder Spin", + basicSkills: ["Volt Slam", "Recharge", "Magnetic Clutch"], + elements: ["Electric"], + packReveal: "Qmat3xuyNBpfuBRLtjBURaXDoZB6kVQA8v6Ty8uptx4YiB", + thumbnail: "Qmd6GNRbieqRDbLtbFcfEevGQoT583Mo82e3dHxZBmB4Kf", + }, + { + beastTemplateID: 152, + dexNumber: 31, + name: "Cron", + description: + "A Cron moves in a group. Together they create a strong magnetic field.", + image: "QmTUfZ9WpQjgwYXWf7XB96GPesULzPjEai1q8DxQGsKmHX", + imageTransparentBg: "QmVRXqSHdPqsH5MtJ9ysz41cx12dLTUmHw31AzoDrKfsVo", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 151, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Thunder Spin", + basicSkills: ["Volt Slam", "Recharge", "Magnetic Clutch"], + elements: ["Electric"], + packReveal: "QmQnfLknUjmP4JAodLEfmxNCg4jtibJ6DrKm2WDXFxYiM6", + thumbnail: "QmVb4ESyy5syYhomgExQoBth8k6P4We9wRX95tPq5XckJq", + }, + { + beastTemplateID: 153, + dexNumber: 31, + name: "Cron", + description: + "A Cron moves in a group. Together they create a strong magnetic field.", + image: "QmTBPaKSjKnasHug44p5HEKPDGXfySA6zwfajoLcvSWnUt", + imageTransparentBg: "QmVph8owU95jedyud75VwfUuutEmFCkvM8ghNNyyitVfa1", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 151, + maxAdminMintAllowed: 200, + ultimateSkill: "Thunder Spin", + basicSkills: ["Volt Slam", "Recharge", "Magnetic Clutch"], + elements: ["Electric"], + packReveal: "QmVGixNzmBHtXAwXjHTusBsvomzrjvc56uG3o615sf1MA8", + thumbnail: "Qmbuw3F6JSQmy5tnMP9xmaEPw5g6cAUzMZJN7q8RV4hquW", + }, + { + beastTemplateID: 154, + dexNumber: 31, + name: "Cron", + description: + "A Cron moves in a group. Together they create a strong magnetic field.", + image: "QmNhaX6zmtN5VGXQB3sGbAA48aA3spYVYBSTynjZgXn11k", + imageTransparentBg: "QmahCeybHoTSWjYvKCRStV2YCNpkgfW32DXVVaFvUP8QPK", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 151, + maxAdminMintAllowed: 50, + ultimateSkill: "Thunder Spin", + basicSkills: ["Volt Slam", "Recharge", "Magnetic Clutch"], + elements: ["Electric"], + packReveal: "QmarQnFuAhPmCzUC1YhcybjuWFUuyUxU1J5DJfpd49y4k6", + thumbnail: "QmNi23ZbkqsissfcneD7WidwbwRqh7uorabfd2YoWtPn8s", + }, + { + beastTemplateID: 166, + dexNumber: 34, + name: "Octo", + description: + "An Octo is a martial arts specialist. Give it the right tools and it will make delicious food.", + image: "QmeoPbkLwtw6VoeaA4hnsYowSjYEeEEwC5XFyoaUhECdQv", + imageTransparentBg: "QmbCuLfDBgWfyeN9m9KaJR2BFhw4qqJGk4ZzVrJNiZBye4", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 166, + maxAdminMintAllowed: 1000, + ultimateSkill: "Ink Bomb", + basicSkills: ["Aqua Jab", "Magic Whip", "Hydro Chop"], + elements: ["Water"], + packReveal: "QmSnfiWwqW54auD1zddquQvJERp3pjSSGMQ6dWYZjXRpcL", + thumbnail: "QmSD9KJds5oPv8Ldv31dFc5Pwo8yLonKCFB5C6VAB7Rvdy", + }, + { + beastTemplateID: 167, + dexNumber: 34, + name: "Octo", + description: + "An Octo is a martial arts specialist. Give it the right tools and it will make delicious food.", + image: "QmQBoVjKf4Hi9UfWqYsz82wJfzDuG7YsBDjv26fAqaMveZ", + imageTransparentBg: "QmWzFUj6dabMC7wB5H69J2AtjSrMVYBTAgdvK1uRHB2aDg", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 166, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Ink Bomb", + basicSkills: ["Aqua Jab", "Magic Whip", "Hydro Chop"], + elements: ["Water"], + packReveal: "QmdV6qGmdN6g3BDTj8Zr4fAsvBEhxu9DXwEr2N2thikA2Q", + thumbnail: "QmenKHRtMK7VBHmBwBUJYPQu4KeXyis49B7XvyMFKmpuUC", + }, + { + beastTemplateID: 168, + dexNumber: 34, + name: "Octo", + description: + "An Octo is a martial arts specialist. Give it the right tools and it will make delicious food.", + image: "QmcnVx9kvpNydtyxQCzyJcdhm7VrYqvYu6UqDrUh9QbmvY", + imageTransparentBg: "QmPn6bAkmDxwwxK6KfQ3FRSKv5FX9gY7VZQr2u5BYmVHhj", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 166, + maxAdminMintAllowed: 200, + ultimateSkill: "Ink Bomb", + basicSkills: ["Aqua Jab", "Magic Whip", "Hydro Chop"], + elements: ["Water"], + packReveal: "Qmaqz3NJB6o9XvubZKJWQymLbXCofd58PSX332ZCJvkjpD", + thumbnail: "QmVfMTU7euZzK4cyRxZDKGfJ1duefFB6D8umV8U5YCZqM9", + }, + { + beastTemplateID: 169, + dexNumber: 34, + name: "Octo", + description: + "An Octo is a martial arts specialist. Give it the right tools and it will make delicious food.", + image: "QmPieAzKAoJLf2rGdbGES4eATsrAx8h8pDMeuuDh18NKuM", + imageTransparentBg: "QmeUN8VfPX3goxAVLC7ZBNkCgDQ8HEv52KFzVH323BRRyQ", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 166, + maxAdminMintAllowed: 50, + ultimateSkill: "Ink Bomb", + basicSkills: ["Aqua Jab", "Magic Whip", "Hydro Chop"], + elements: ["Water"], + packReveal: "QmUPH5H1sqAwUaQavhDb4yS3X5Wsvm7VSoznEyFpAFGLV7", + thumbnail: "QmaP23uBisuDSRJrBtwtUcgW5fhRdQfWnXFUCJSyvdu2yD", + }, + { + beastTemplateID: 181, + dexNumber: 37, + name: "Ezme", + description: "An Ezme has a green, bright shine during the night.", + image: "QmQsYdFaS83SGGaMegPeacxibngq8hDvwHypZsjk9T6Vuw", + imageTransparentBg: "Qmf9tPJmbiC7xJrCseSmCdEjZZVsS6untDwqmfxpAA1LcS", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 181, + maxAdminMintAllowed: 1000, + ultimateSkill: "Powder", + basicSkills: ["Snap Trap", "Solar Heal", "Leaf Blade"], + elements: ["Grass"], + packReveal: "QmfBPNPBd8PqfCscrK61P2HGAbxXBZcJnN4nsBwkZjsezi", + thumbnail: "QmZbUBMyYvBHF5ohW6m6WERfnukYguK6vLehrmQGB2GQ7v", + }, + { + beastTemplateID: 182, + dexNumber: 37, + name: "Ezme", + description: "An Ezme has a green, bright shine during the night.", + image: "QmYGuRNKwkBEoWE1gCrexPk66WU8DYduhDHSCH619dRK9u", + imageTransparentBg: "QmUsm8S7KPTVV67L46UwGeW3W7qD2K9uR9bZwAXpi2dhGy", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 181, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Powder", + basicSkills: ["Snap Trap", "Solar Heal", "Leaf Blade"], + elements: ["Grass"], + packReveal: "QmW342Q6H6LpciBfpyUuA38BfxVHkDfpH9ygSvPXAaStNv", + thumbnail: "Qmdt1UGo6H6meH9n5h8jqKVG4TEWQd7ysrPyb3K4GqhmYg", + }, + { + beastTemplateID: 183, + dexNumber: 37, + name: "Ezme", + description: "An Ezme has a green, bright shine during the night.", + image: "QmNMBYn99HLenWLsVz3VX37eyrUFkyutiD77UVoF9VLsyH", + imageTransparentBg: "QmbxTvPfpqDkZ5FRF9ujqBkJkewHs8XhtzjMftyCaoNNnJ", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 181, + maxAdminMintAllowed: 200, + ultimateSkill: "Powder", + basicSkills: ["Snap Trap", "Solar Heal", "Leaf Blade"], + elements: ["Grass"], + packReveal: "QmPtBiZVBZghdZWSXTBBRKuAAG2fWUoNToVicqre6ULH5G", + thumbnail: "QmRPiw5CKR7AzVtSzMvyYi7SqAe4LTXPEnSoA54FjUeki2", + }, + { + beastTemplateID: 184, + dexNumber: 37, + name: "Ezme", + description: "An Ezme has a green, bright shine during the night.", + image: "QmUVruPvL5oHRyPnqoNp4nTwjWZWe8Eia8SnRJfcXr19Lq", + imageTransparentBg: "QmNotEst618s7oBEndT9H7zkAVgWx2wXASGfo3mHczoQFA", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 181, + maxAdminMintAllowed: 50, + ultimateSkill: "Powder", + basicSkills: ["Snap Trap", "Solar Heal", "Leaf Blade"], + elements: ["Grass"], + packReveal: "QmS1DwJt4yKSGDhv2EyzCNbPpCD9gvXp7zQ8seToAMqst3", + thumbnail: "QmeAfM9BLf3iKtRiDoAmzdAmx8jrhvoxwJuu9irVVBRsiE", + }, + { + beastTemplateID: 196, + dexNumber: 40, + name: "Luci", + description: + "A Luci is an infernal beast. When it's angered, its spearheaded tail will set anything on fire.", + image: "QmW7W86iJkxRDdozXqJQBD4L98vVhv3NEGd7zKGMRD3hwx", + imageTransparentBg: "QmV11zVnwEBDtu1VFtfePsPUJs4mvCNZCsqbpiytqVE85M", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 196, + maxAdminMintAllowed: 1000, + ultimateSkill: "End Game", + basicSkills: ["Burn Up", "Nightmare", "Fire Flare"], + elements: ["Fire"], + packReveal: "QmPLpS7V6Zty8vPeaNN7GNWystQC2isgKLnTN5UwpYYbDT", + thumbnail: "QmWnHQHcfFsjq2rmyobt8aCp1xCbH945tjXGABQYXHFvcD", + }, + { + beastTemplateID: 197, + dexNumber: 40, + name: "Luci", + description: + "A Luci is an infernal beast. When it's angered, its spearheaded tail will set anything on fire.", + image: "QmT3vQ66rHwkYqDEpHXg1MZhBwuAjhnmwrxt1Gk29qaH8V", + imageTransparentBg: "QmVyh6HbNv3brRpkgRDSG9Z5tcspW8NkgyMvP86et423hH", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 196, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "End Game", + basicSkills: ["Burn Up", "Nightmare", "Fire Flare"], + elements: ["Fire"], + packReveal: "QmNfpq4AbQaLUe8u8jCKu7Md4ZJrRPMQRvsW8rRQXi7wfA", + thumbnail: "QmZJQeZGgaNL6kXYF6t5XvnRjoLVAU7SSGZem8pFEN22hL", + }, + { + beastTemplateID: 198, + dexNumber: 40, + name: "Luci", + description: + "A Luci is an infernal beast. When it's angered, its spearheaded tail will set anything on fire.", + image: "QmZq2GbQLuhPXYuyp6P63HTJTkqH6WxNFzdDiSCRZisQoa", + imageTransparentBg: "QmWdD3LSi2jXqNCsyECX9G7C3B1aQbjW1YVoPdtFGhKptT", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 196, + maxAdminMintAllowed: 200, + ultimateSkill: "End Game", + basicSkills: ["Burn Up", "Nightmare", "Fire Flare"], + elements: ["Fire"], + packReveal: "QmPREvCuZqPMX6iX6BxfuNMhsvqtojWKMmg6CkA712kDbH", + thumbnail: "QmRzBHWtT8xbdu3bfQ93EWum6NwzGhXZHPci5qrnfg6kqC", + }, + { + beastTemplateID: 199, + dexNumber: 40, + name: "Luci", + description: + "A Luci is an infernal beast. When it's angered, its spearheaded tail will set anything on fire.", + image: "QmePZXdF3ChM7wR2kWTPrrC4JPffK97BE9tpmPx9RHYXTg", + imageTransparentBg: "QmTMAP9tu3hnPePFVmZW6f4jzCpgZB6WtXRBi5G9n8TNCz", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 196, + maxAdminMintAllowed: 50, + ultimateSkill: "End Game", + basicSkills: ["Burn Up", "Nightmare", "Fire Flare"], + elements: ["Fire"], + packReveal: "QmR37SY224MkxHQaPi19WiUECztErKm5iRvndKdyTeeTgr", + thumbnail: "QmUuQ9g6oJsBGQqrbixSRdkzT3GCQRfKwphV6QZAnSkpmK", + }, + { + beastTemplateID: 211, + dexNumber: 43, + name: "Stabby", + description: + "A Stabby holds a toy knife to persuade others to do its bidding.", + image: "QmWm1EpZH3pKtSrvq4Rm675JfwRDg58qhD3pQQ8eFR9Xwk", + imageTransparentBg: "QmRKe4i7Nm7ty6yM4PqHvbT1paMcv9wtS2Qi4xPKV6xMh6", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 211, + maxAdminMintAllowed: 1000, + ultimateSkill: "One-Sword Style", + basicSkills: ["Stab It", "Intimidate", "Duck-Ya Up"], + elements: ["Normal"], + packReveal: "QmbNbVQ6yEd1UdHuFVZq5MKvGb4VjnNV6No8cMWHm4DxVo", + thumbnail: "QmW47pcJanAKgNgngRP7HKgJPFARQGPMA2nQvS3YcYjHys", + }, + { + beastTemplateID: 212, + dexNumber: 43, + name: "Stabby", + description: + "A Stabby holds a toy knife to persuade others to do its bidding.", + image: "QmUWHPH2sEa9WPQYGHUQ7AjgA2uMzimtv1dkCaqzZfG4NJ", + imageTransparentBg: "QmeR388UWrXegyxkMNNEuUjShCC85PSGJfS6zkk4dJHkVP", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 211, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "One-Sword Style", + basicSkills: ["Stab It", "Intimidate", "Duck-Ya Up"], + elements: ["Normal"], + packReveal: "QmYC5jvm3Jpw7NaT6WMxR9T3wYC1KjfDM8W4FFUaCfPawF", + thumbnail: "QmPaHvhSBe9M1VbovqCWVQSRHwzWCQxo5bf4ajgsDkKjKu", + }, + { + beastTemplateID: 213, + dexNumber: 43, + name: "Stabby", + description: + "A Stabby holds a toy knife to persuade others to do its bidding.", + image: "QmX2iFZLyPGzUz3mjNYSSJn5pDteT2bViwoTWsGzeXUmSp", + imageTransparentBg: "QmTsyjo2pQtYDz7gtsmaGJsSqj1vEUiWyWLY2i6QGRNRk6", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 211, + maxAdminMintAllowed: 200, + ultimateSkill: "One-Sword Style", + basicSkills: ["Stab It", "Intimidate", "Duck-Ya Up"], + elements: ["Normal"], + packReveal: "QmQEW5BfoV56yV1j6W2Pn96X2QHx92GiLpPNDdB12TqRV7", + thumbnail: "QmTbj39JRfbwtK6Zg2AmSJFSrSaetDZg1M6eWcMwZwqrMA", + }, + { + beastTemplateID: 214, + dexNumber: 43, + name: "Stabby", + description: + "A Stabby holds a toy knife to persuade others to do its bidding.", + image: "QmfRWdcaZ4sh1pkd9LTJ6hPzPKw4CEAm59ngHqPUuGsEHt", + imageTransparentBg: "QmZVFZ3BhLaYAabyGBEbbbY6PrW9FZ1jCqRtG4AwPzpkyN", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 211, + maxAdminMintAllowed: 50, + ultimateSkill: "One-Sword Style", + basicSkills: ["Stab It", "Intimidate", "Duck-Ya Up"], + elements: ["Normal"], + packReveal: "QmZ8qW81zJKZP2UYRmv7GwTPYu2uUgRFu3kavgq18USgnW", + thumbnail: "QmZPqQPWX7wH4CmHtY8pEyX18Fxr8RTzNstzURG82K2Tmp", + }, + { + beastTemplateID: 226, + dexNumber: 46, + name: "Hiro", + description: "A Hiro is a noble beast. It possesses a heart of justice.", + image: "QmfDAfqbjnFGqdiM5jg4F8raRFCYGzzksHjcg1wV97BP74", + imageTransparentBg: "Qmc1tVJVWi839nye8dzTAYDqfCHkgmy4CfodyR4x2j1qn4", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 226, + maxAdminMintAllowed: 1000, + ultimateSkill: "Speedy Hurricane", + basicSkills: ["Afterimage", "Hyper Punch", "Flash"], + elements: ["Electric"], + packReveal: "QmRVKLzJnq5zwqUBXCKCDUMYYUSoPkZGKHmEkZN51SPQQK", + thumbnail: "QmWQxWNZ3CbSAQgLE8UtwpooMfmPS2LCbvbQdCFZZY9TcN", + }, + { + beastTemplateID: 227, + dexNumber: 46, + name: "Hiro", + description: "A Hiro is a noble beast. It possesses a heart of justice.", + image: "QmbtPJeR9UVQHDHYs6pUZc18dCSURQFUeCGbzHwpREd9jr", + imageTransparentBg: "QmTAqH9YgAzm2HrPqLjyZmbabwR2BEYPwX5aSRqbH8PoGp", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 226, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Speedy Hurricane", + basicSkills: ["Afterimage", "Hyper Punch", "Flash"], + elements: ["Electric"], + packReveal: "QmYRtYkJYJVhdFC1qZvmwQPRXrdeTF7jaqRtCjdkJWff3M", + thumbnail: "QmUHRxuKiie9XoMnuiVE5Tb4QGBGf3BHjaiRCGhmrXfXdk", + }, + { + beastTemplateID: 228, + dexNumber: 46, + name: "Hiro", + description: "A Hiro is a noble beast. It possesses a heart of justice.", + image: "QmYpDHFGqRs9ZVfY9FRJGqpX7WUECEu86hzJYMGHeryz4W", + imageTransparentBg: "QmPRnBfV6xdJVaJ7EvohQhRoTkSUzJQdAqANYCRhVgDNTW", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 226, + maxAdminMintAllowed: 200, + ultimateSkill: "Speedy Hurricane", + basicSkills: ["Afterimage", "Hyper Punch", "Flash"], + elements: ["Electric"], + packReveal: "QmbCvXiHLBxcUFjhmQN48ZbZ1Ygt5RMmMsoVxRRsw7J9vD", + thumbnail: "QmZgtGoGqetifrS1veeMkSXmPRY6FsSqMgfXHkD7d5UFWt", + }, + { + beastTemplateID: 229, + dexNumber: 46, + name: "Hiro", + description: "A Hiro is a noble beast. It possesses a heart of justice.", + image: "Qma5p9ysiHbKArxhv6qUNjgHpWqedVr9aeiZMGxXPsaNrQ", + imageTransparentBg: "QmfBMsrgb1oVkiBs5YYJ2imdrK8coxWF6qyBvooSUnjC1m", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 226, + maxAdminMintAllowed: 50, + ultimateSkill: "Speedy Hurricane", + basicSkills: ["Afterimage", "Hyper Punch", "Flash"], + elements: ["Electric"], + packReveal: "QmWLxfp9WxoxDRaQWdMEdGKHNiJcTeA7S66cxRxvTz3ZRe", + thumbnail: "QmWJKiSSvycxQ2MNEprVpjUkn6ZjQ4YRsohryMhd6sv6YJ", + }, + { + beastTemplateID: 241, + dexNumber: 49, + name: "Gama", + description: + "A Gama has a cowardly personality. During battle it makes a rumbling sound.", + image: "QmRPxi2xoMSGbkunR1imaA534gdNZaoFzxkxaEsPRTtkVU", + imageTransparentBg: "QmeVa8RCziG4YbBepyH3dpmZUUo3DZuea96K71Z575K2eC", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 241, + maxAdminMintAllowed: 1000, + ultimateSkill: "Last Resort", + basicSkills: ["Spit", "Sob", "Struggle"], + elements: ["Water"], + packReveal: "QmRorBncTGaQBVR7YqyzUhb8z8gbEwZK34PUJ1nwKQaM7v", + thumbnail: "QmWuBrVsMAwUZyKWU7xaML6EUcv4tqqJFam8n5SsN4WGTS", + }, + { + beastTemplateID: 242, + dexNumber: 49, + name: "Gama", + description: + "A Gama has a cowardly personality. During battle it makes a rumbling sound.", + image: "QmWBSSVkoX1UxKEcPHM5vRb2LgiFrkpeP1gLwSKRZZMPrc", + imageTransparentBg: "QmaX9L73qCPKQur9iiRUu2vXXDLFiCihmmtNV3Bqzxw8jc", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 241, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Last Resort", + basicSkills: ["Spit", "Sob", "Struggle"], + elements: ["Water"], + packReveal: "QmQ7EMQQnjByZ1Ede3SvkGeBVejG1ztiuGhwRYtgxcLukJ", + thumbnail: "QmUHbZzfckuZvmT6yCZ2Jywf54oyg7U72DN42mb1RxZmXK", + }, + { + beastTemplateID: 243, + dexNumber: 49, + name: "Gama", + description: + "A Gama has a cowardly personality. During battle it makes a rumbling sound.", + image: "QmfGTWfhHsnNCmZQrhCVXvYKvfXHrn8xz9x3WvzFvkUHRt", + imageTransparentBg: "QmPHeZL1CuWH875Sr3e7X8Qx83Lg9igsvhobAvcybwXpgY", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 241, + maxAdminMintAllowed: 200, + ultimateSkill: "Last Resort", + basicSkills: ["Spit", "Sob", "Struggle"], + elements: ["Water"], + packReveal: "QmUbVtR9vYE3WHsTNuBBcWi3ohesHShXp1fAH2zpFu9pch", + thumbnail: "Qmejx5AkBJndMssDyPTtSjY3oJ6cGVfFfbDqzvsFw5VGWh", + }, + { + beastTemplateID: 244, + dexNumber: 49, + name: "Gama", + description: + "A Gama has a cowardly personality. During battle it makes a rumbling sound.", + image: "QmdG6zJLgUwy96PXeQ6cAXN18wwMfpPNsTFNuUii1xWyoA", + imageTransparentBg: "QmbzY7mtCGtni5k4FfnhzYaP3XLzxqm9kheaQ6PurC4QRH", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 241, + maxAdminMintAllowed: 50, + ultimateSkill: "Last Resort", + basicSkills: ["Spit", "Sob", "Struggle"], + elements: ["Water"], + packReveal: "QmPU72LX3e8r5SF9gyGnADvDGHvpAvCwDnMqCKfmPDwKGQ", + thumbnail: "QmfMQm4xphCrXeNP8Kvb5KG2JGrkKroQsD3heDprDijie3", + }, + { + beastTemplateID: 256, + dexNumber: 52, + name: "Bloom", + description: + "A Bloom can often be found in gardens. The pollen it produces has an empowering effect.", + image: "QmZdPt3AKXduqLCFeCjzc1QZZgtJRmvvxV7xFngCxUSNU5", + imageTransparentBg: "QmSWtXA9drnHSbLLdFVbBAGJFVHSvcPd3QgcoJ6WL3V3Qt", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 256, + maxAdminMintAllowed: 1000, + ultimateSkill: "Ascension", + basicSkills: ["Synthesis", "Thorn Scatter", "Sweet Slap"], + elements: ["Grass"], + packReveal: "QmfHC626BvoeHYovmvxHaPfyGEUtdvwKDPGut8peW4ENiT", + thumbnail: "QmaEz2gpDH8AQj8xUavYQs1HkQbV72NkWbTukamYEgQvsX", + }, + { + beastTemplateID: 257, + dexNumber: 52, + name: "Bloom", + description: + "A Bloom can often be found in gardens. The pollen it produces has an empowering effect.", + image: "QmfHsaxH8usLY58xz2kLCbWmcBQ6XDKeyHZNisSHYHT5yx", + imageTransparentBg: "QmWQtnhfCUdmidsPDVgHaZ682Z7cFQbpsi9eXwXxFEbC3d", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 256, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Ascension", + basicSkills: ["Synthesis", "Thorn Scatter", "Sweet Slap"], + elements: ["Grass"], + packReveal: "QmX21RVDcKXoDCo2YEk6Lt7Ygtw8AYLhtSPjNpezbUiWMf", + thumbnail: "QmRfSUn62BMsT6kRXndMmVAfiNtMXK6oRKetj1jpT47pM1", + }, + { + beastTemplateID: 258, + dexNumber: 52, + name: "Bloom", + description: + "A Bloom can often be found in gardens. The pollen it produces has an empowering effect.", + image: "QmZZiojFbVyhRKY6PdiLzWMkkkSGCTj7m6y3TZcgUp3oYs", + imageTransparentBg: "QmbkTDCSZeKtRKtGFi2uCQpDmtHt7eyE9dzkWLaLmdkEH9", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 256, + maxAdminMintAllowed: 200, + ultimateSkill: "Ascension", + basicSkills: ["Synthesis", "Thorn Scatter", "Sweet Slap"], + elements: ["Grass"], + packReveal: "Qmaafbd4dps4hK3Gd69LUUd3p49j3r5g7HHVJbCgW8pxQW", + thumbnail: "QmdpU4ZKd4R1YyMVxsnGvyh7c4Tc4RjQvRZjYGfAHpUzFz", + }, + { + beastTemplateID: 259, + dexNumber: 52, + name: "Bloom", + description: + "A Bloom can often be found in gardens. The pollen it produces has an empowering effect.", + image: "QmUZXqyCJQkPJQ6VLLJGH1dQmqAXR29sKjqpA8vW1MC4Ao", + imageTransparentBg: "QmbPtJ78956Z3irKWXY9JGqyZT8kV2JMK9hLQgGH6mp3Sv", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 256, + maxAdminMintAllowed: 50, + ultimateSkill: "Ascension", + basicSkills: ["Synthesis", "Thorn Scatter", "Sweet Slap"], + elements: ["Grass"], + packReveal: "QmXHFBfPCdS7GjuyWiJDBp7s7DXrK96aFktVX5cLVpChmm", + thumbnail: "QmNzwLGb2T3MLmvaT7BjtmaGgxT3eqmpaaxmJXKAT4hmQn", + }, + { + beastTemplateID: 271, + dexNumber: 55, + name: "Pyro", + description: "A Pyro has a wild temperament.", + image: "QmXSm9v2Gmq8QssoWfipywQmJV99B8MnNqwdPbQpp6bLq9", + imageTransparentBg: "QmTKaypmpLcRFFZ6L2aVekygakmpyQKwVkPzUpLmx5J7LN", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 271, + maxAdminMintAllowed: 1000, + ultimateSkill: "Mighty Inferno", + basicSkills: ["Torch", "Bursting Blaze", "Vaporize"], + elements: ["Fire"], + packReveal: "QmSGZJNzVMd6q7FR8LoSKfBod4XrmiWeqbU72znCd9FF9D", + thumbnail: "Qmd9mreke16nh5tHdyKsBJDW7fgbYMn4eCS2YNu1bkPcPN", + }, + { + beastTemplateID: 272, + dexNumber: 55, + name: "Pyro", + description: "A Pyro has a wild temperament.", + image: "QmcRCvnkgHzUHtx29sBEe2jysbhxDbEo4kuuxCM4wvhiRV", + imageTransparentBg: "QmdJ6yissbzpZ65jpffajaocpJoQmvQxtUuehDTGxrUCEW", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 271, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Mighty Inferno", + basicSkills: ["Torch", "Bursting Blaze", "Vaporize"], + elements: ["Fire"], + packReveal: "QmNbBKACnRBkQZ4erwURAYBzmgkBmPZqoMYCsi7jpz9ZGP", + thumbnail: "QmdK4JA65DLcAjUFoJC4eq5weXUSp6Ga2XxhrnGVLcXJGk", + }, + { + beastTemplateID: 273, + dexNumber: 55, + name: "Pyro", + description: "A Pyro has a wild temperament.", + image: "QmbyYRKd7bEU7J9FofoHEz7iSzWXRdP53p4p6q9tJAtnF1", + imageTransparentBg: "QmXbzRxN7uJy9uKSTdTEbjA65GrJgwDyF26K1oZy8HhDJc", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 271, + maxAdminMintAllowed: 200, + ultimateSkill: "Mighty Inferno", + basicSkills: ["Torch", "Bursting Blaze", "Vaporize"], + elements: ["Fire"], + packReveal: "QmSzBDxRnXsCz3pfio2bvAidJ4ZBaMrfMGQeu1QQZ5b9fc", + thumbnail: "QmWMQR11Vu4oapfCRpVmEhgfGGfmDyKHLGWLFh4NpNNv4s", + }, + { + beastTemplateID: 274, + dexNumber: 55, + name: "Pyro", + description: "A Pyro has a wild temperament.", + image: "QmZibqiJv68jviWaPhJybFQzFbzi231AsaVEycWHNDYFK8", + imageTransparentBg: "QmdBs3gCK1rgtKMw73NWgSCYzqcZcr7T1AP3rAhYFaSeTd", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 271, + maxAdminMintAllowed: 50, + ultimateSkill: "Mighty Inferno", + basicSkills: ["Torch", "Bursting Blaze", "Vaporize"], + elements: ["Fire"], + packReveal: "QmejEzatug76DwhKHmdSjYWPUjbist6SPBwEAezwDZUSHa", + thumbnail: "QmQYPMdE64jSRoFxDkyVU3AXv7xbDEdQU6rTyAST5HqN9W", + }, + { + beastTemplateID: 286, + dexNumber: 58, + name: "Nova", + description: "A Nova loves pranks and sweets.", + image: "Qma3JqSzbqasgHoYgrAPtpWigC8dn58ke5ecgyG62WuJ4R", + imageTransparentBg: "QmTiQwdSwkYP57dUjy7DADzPMfGydhUJnSDtthJLi4XCkx", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 286, + maxAdminMintAllowed: 1000, + ultimateSkill: "Shapeshift", + basicSkills: ["Shadow Walk", "Phantom Blow", "Dark Pull"], + elements: ["Normal"], + packReveal: "QmTGhfpyub3LTRoCbXb3sh7TjUXva5UpiJ3DbqDiy97jCQ", + thumbnail: "QmaoNQqRhyVaWtaomrVSBWicvuVmSoB4ABAXz5EzXuEq6o", + }, + { + beastTemplateID: 287, + dexNumber: 58, + name: "Nova", + description: "A Nova loves pranks and sweets.", + image: "QmaranYgXQNiv2Z9rARgzBk75E7CXjhCqYHcyGKGxDFG6M", + imageTransparentBg: "QmV3Akbca8NCE6qPoKaauMZH9L1U2J1R7GK9JA9aGvBp55", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 286, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Shapeshift", + basicSkills: ["Shadow Walk", "Phantom Blow", "Dark Pull"], + elements: ["Normal"], + packReveal: "QmVoKbP1ATfrYBUgKmnXGHxjmQnjJBSqVJcVp8MAdiLUx8", + thumbnail: "QmStptQqKw1aoa1U4MUF64KaxGYAx2WRoGkBuafHkLoJyD", + }, + { + beastTemplateID: 288, + dexNumber: 58, + name: "Nova", + description: "A Nova loves pranks and sweets.", + image: "Qmdo9xSKk1MQaPsTye5jZZGt1dqSRYJXvohoY5cBqkHBYW", + imageTransparentBg: "QmegdDQEA7uFkQWaYVSZ7FSktFMEhDWecfN4B8RDN4mnfF", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 286, + maxAdminMintAllowed: 200, + ultimateSkill: "Shapeshift", + basicSkills: ["Shadow Walk", "Phantom Blow", "Dark Pull"], + elements: ["Normal"], + packReveal: "QmaQbkvbYbr1xmBuE8EHDnBaZRKwGWaEi52QxvR7Fs9pg8", + thumbnail: "QmVMQpy9HpQQYKLjjRKkqXFUf3YEU8EibHHKNxKkYNziFE", + }, + { + beastTemplateID: 289, + dexNumber: 58, + name: "Nova", + description: "A Nova loves pranks and sweets.", + image: "QmVz9T6b9FijPWwLUfSKZesn2tZMULW1jHHVA3PQcDeX51", + imageTransparentBg: "QmPHf148dkAw28Pf8oY7CwGRHbYf3D9gCNdNBBLKiFQDy2", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 286, + maxAdminMintAllowed: 50, + ultimateSkill: "Shapeshift", + basicSkills: ["Shadow Walk", "Phantom Blow", "Dark Pull"], + elements: ["Normal"], + packReveal: "QmScPyw376tpiKW8QypKU9umzCZ38imQiyF1oWmq59biQw", + thumbnail: "QmT64L9Tvnu5Lhdq4Nve4H1f3EeEXBZcauQJVMAehs5tdV", + }, + { + beastTemplateID: 301, + dexNumber: 61, + name: "Ferb", + description: + "A Ferb has a timid personality. Its fur becomes static when it's excited.", + image: "QmdEwqCrLPXa9AEqQQ4JN3zAMEdGFqnKXx1MDa4PLjregb", + imageTransparentBg: "Qma2swq6AyUkYDQMmkqgkVqvA4xgsraxaJc4AVnHD37wdp", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 301, + maxAdminMintAllowed: 1000, + ultimateSkill: "Big Buzz", + basicSkills: ["Mimic", "Lightning Dash", "Static Hug"], + elements: ["Electric"], + packReveal: "Qmb6x8dJAA6MEGm6kFtj25FtXhkeh7eV3YvHFEQj65yJhR", + thumbnail: "QmTwaBcsjFkwiTHCUxFfDta5ciVetaZ3HPjXDeN8MxvkQb", + }, + { + beastTemplateID: 302, + dexNumber: 61, + name: "Ferb", + description: + "A Ferb has a timid personality. Its fur becomes static when it's excited.", + image: "QmUtsrrdkvbfwhxiRakTq2amsY4zvAowti3rtK1YLVwtRq", + imageTransparentBg: "QmcdxUtmHJsawpxJ6VdgQE5JxwEfm9jWbLr9uCRoh8YgNC", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 301, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Big Buzz", + basicSkills: ["Mimic", "Lightning Dash", "Static Hug"], + elements: ["Electric"], + packReveal: "QmWCf7xBDPaeecBvpWC9b81zS5Yyx3AdtamMhzeJz2vYF8", + thumbnail: "QmSVHpWr4tZp3bVufE6v3m2xsn1Yji8a9dQpF6pPYBX9oh", + }, + { + beastTemplateID: 303, + dexNumber: 61, + name: "Ferb", + description: + "A Ferb has a timid personality. Its fur becomes static when it's excited.", + image: "QmctSTHHuRiCUBoKxyy5a7wzHU2fCzx8X12zrcP9hu9tmK", + imageTransparentBg: "QmfA7rCSAf7EEKaSRcKunr1mF1mBYHU5ksNtQBybgDzC1e", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 301, + maxAdminMintAllowed: 200, + ultimateSkill: "Big Buzz", + basicSkills: ["Mimic", "Lightning Dash", "Static Hug"], + elements: ["Electric"], + packReveal: "QmNpVr1VmeU4K1SkE2c6zkD6BFPyTHBe6BPFtiZunUSDSc", + thumbnail: "QmRpKL9iGLRJvP1LB5Cuq9JN1PdQaEBkwgJeHEtCtSMajb", + }, + { + beastTemplateID: 304, + dexNumber: 61, + name: "Ferb", + description: + "A Ferb has a timid personality. Its fur becomes static when it's excited.", + image: "QmeEfXbg6SeGirrY8ePujcWstDAJJ6cBofJhKe3xKTLsDH", + imageTransparentBg: "Qmdhk8u5u9KUz4WtCpnyUp3KvUEoSodvH3VsA5sKj7LePC", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 301, + maxAdminMintAllowed: 50, + ultimateSkill: "Big Buzz", + basicSkills: ["Mimic", "Lightning Dash", "Static Hug"], + elements: ["Electric"], + packReveal: "QmTsx7jxPkVyz64oMrV6H6q3vYUi1Mj8cBffAqyKQdcfH7", + thumbnail: "QmdUK7PpuYJopAXn1fqWWSTwfJVMYY13MjfGBode2GfpDN", + }, + { + beastTemplateID: 316, + dexNumber: 64, + name: "Frosty", + description: "A Frosty can often be found in winter. It has a chilly body.", + image: "QmV6TL7pUAZMxbLeQoY2gmmtiECJkMFhEuvx5aZf4zGnQy", + imageTransparentBg: "QmNWVZSTDGaeE5JQgzBJnuLN3ZYXosnTCDC5FmMnXEkiRW", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 316, + maxAdminMintAllowed: 1000, + ultimateSkill: "Blizzard", + basicSkills: ["Snow Ball", "Frozen Surface", "Cold Punch"], + elements: ["Water"], + packReveal: "QmdfEvNGYZscAB6KvPWqDdB4VCe3PVDJjVcsrFw9yejDHP", + thumbnail: "QmeDcwviCXuJbMHT273ANgwnhKyN3syeegCdAtsggGQSm5", + }, + { + beastTemplateID: 317, + dexNumber: 64, + name: "Frosty", + description: "A Frosty can often be found in winter. It has a chilly body.", + image: "QmaPsEsPnTPiNQMXxPmKTkGnJpSQJVDSbfEGL42JEsAxZp", + imageTransparentBg: "QmXhLyrSno9injhJufW7d14ybeadStPKGHDFE4YmRjTZ9o", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 316, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Blizzard", + basicSkills: ["Snow Ball", "Frozen Surface", "Cold Punch"], + elements: ["Water"], + packReveal: "QmZLhN17Xy7GgTU1A6Ad7Ae5N2cmmc8LZEkaeeHupYGeAg", + thumbnail: "QmTzcJNzRnMv4yVZuzmyA2FYddXo8yT14vmFzEmMm4wFzr", + }, + { + beastTemplateID: 318, + dexNumber: 64, + name: "Frosty", + description: "A Frosty can often be found in winter. It has a chilly body.", + image: "QmaSD12vveK1ukuVHtvTj3JMuzHjjmCQ21hZXpDVuQ5Ucn", + imageTransparentBg: "QmauMmKjvvAKVfycKdg9phfzjDcHdHfKWWeqyC8kuhKJxC", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 316, + maxAdminMintAllowed: 200, + ultimateSkill: "Blizzard", + basicSkills: ["Snow Ball", "Frozen Surface", "Cold Punch"], + elements: ["Water"], + packReveal: "QmdhiCvc1DoBvFmtpySvZLFB7g95Lw9c99oRsWzcPmVsR7", + thumbnail: "QmZ5LmmWBNJidVNZzyKxYEu6zPKSyNU8vLTcWRnJhfsae4", + }, + { + beastTemplateID: 319, + dexNumber: 64, + name: "Frosty", + description: "A Frosty can often be found in winter. It has a chilly body.", + image: "QmQCd8hRxZkUbz2aajUbZV49rFYFrzTHsQwgeua9fzqofn", + imageTransparentBg: "QmSy4rTHg1oZ85UBc3h4QZY4sH3sXL839ZF1PNMe2rMUV6", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 316, + maxAdminMintAllowed: 50, + ultimateSkill: "Blizzard", + basicSkills: ["Snow Ball", "Frozen Surface", "Cold Punch"], + elements: ["Water"], + packReveal: "QmZ95jZmBBshAipn2quh5uGkp82bSLL7k42QcyuwPN5PjU", + thumbnail: "QmeJikYZnjC3erzqbVS22Wzn9ayvbJRE7ekSczsEz92vfT", + }, + { + beastTemplateID: 331, + dexNumber: 67, + name: "Bello", + description: "A Bello is a tiny but powerful beast.", + image: "QmaXACWpdJ3CQ9x9n7ipDsXTLBnrx8TSd3QoBNuvbMPze3", + imageTransparentBg: "QmWKb9BtLBvMT7QUFyKbHg8D5HFfi4CQSPR1ntbPqetb1C", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 331, + maxAdminMintAllowed: 1000, + ultimateSkill: "Super Smash", + basicSkills: ["Infect", "Double Jump", "Body Slam"], + elements: ["Grass"], + packReveal: "QmUM3HckvHCa2pzheHMVrz6gxARnAzgvJBYGuSq51QDcVH", + thumbnail: "QmYzuMADPMkXXSFDomkxAWP8rVyuTuWUpsnA15wzxBTCEQ", + }, + { + beastTemplateID: 332, + dexNumber: 67, + name: "Bello", + description: "A Bello is a tiny but powerful beast.", + image: "QmNT6S3vP4rcpsUenK4mhScexwLhr4qMGNcr8BwjjJN6rq", + imageTransparentBg: "QmchbUAR3ofgKMkDXQaEWjoWJmcM3YDtCmv5YnbC84wFmz", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 331, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Super Smash", + basicSkills: ["Infect", "Double Jump", "Body Slam"], + elements: ["Grass"], + packReveal: "Qmc7RV94R6GKD4DK4BAzjMk6bMxp326X8LeRSKpGDDvYuL", + thumbnail: "Qmae2fXx4agL9odwPxo3bwzixNT5gvQJSr7UkcQNxdqgLN", + }, + { + beastTemplateID: 333, + dexNumber: 67, + name: "Bello", + description: "A Bello is a tiny but powerful beast.", + image: "QmU8qMLyQFUzj2AVc7yby8XxV1ixRfqfaK5Tt6X17qzJgM", + imageTransparentBg: "QmTeLTDfoigN3S1iohBt853ZagH2G5WopYHindyGQYXFkK", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 331, + maxAdminMintAllowed: 200, + ultimateSkill: "Super Smash", + basicSkills: ["Infect", "Double Jump", "Body Slam"], + elements: ["Grass"], + packReveal: "QmVopGSQ4WGvV6gRX59TVhfHhUCtdC4bPsQFxAvZVmsSFw", + thumbnail: "QmeFB3QCN6rBvjgKjXAFV6VgaF8qzHhfNNVAb53VjkTJMp", + }, + { + beastTemplateID: 334, + dexNumber: 67, + name: "Bello", + description: "A Bello is a tiny but powerful beast.", + image: "QmS8YRU87jGcPCyJMdR9BwdosaVEd83BvDcfUC8QAVB2wC", + imageTransparentBg: "QmYauKjDPnQDjoijVHPptWF61ewTnScXbxf8ToZKU9A7WH", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 331, + maxAdminMintAllowed: 50, + ultimateSkill: "Super Smash", + basicSkills: ["Infect", "Double Jump", "Body Slam"], + elements: ["Grass"], + packReveal: "QmSywuMn4eZaKWpfRb8bjS8d1tDdxQvQ4oYBaDgqSn5DZ8", + thumbnail: "QmR9dZTPb1ddjn64SKqJnJBoVttEquVyxzLjRhWBmtV4gS", + }, + { + beastTemplateID: 346, + dexNumber: 70, + name: "Slime", + description: + "A Slime is an elemental lifeform. Using its magma power, it can melt any metal.", + image: "QmXb7Qyz5tZ54RuBigYX4YGGFUQq4hnV4mtFfBs3rbH1Ef", + imageTransparentBg: "QmfXKviRcVkCHpMm2rjtrhf2ivBEgGrn6mjdKFByEB6Sxg", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 346, + maxAdminMintAllowed: 1000, + ultimateSkill: "Magma Blast", + basicSkills: ["Lava Bolt", "Fire Trail", "Melt"], + elements: ["Fire"], + packReveal: "QmNVtQSFSVRbn2wwdL2h367fk3XkTm4cnJvffyfaYS6wyd", + thumbnail: "QmQHVMBL5aoZoBhzp1eCxy8wbXR2QkiiyhAEXMBimGqG64", + }, + { + beastTemplateID: 347, + dexNumber: 70, + name: "Slime", + description: + "A Slime is an elemental lifeform. Using its magma power, it can melt any metal.", + image: "QmWzzEEorvPppVa6CQ6hjdJ3X8PPtNGiCw9MqJSLXxHoSd", + imageTransparentBg: "QmSs4tR5kEL4rPLVoZh4NsAEMjQTQvisjQqN97tcMZVM6P", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 346, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Magma Blast", + basicSkills: ["Lava Bolt", "Fire Trail", "Melt"], + elements: ["Fire"], + packReveal: "QmdfDURX8GvtKkCYLry5zaHVJLhUbMWrRuGdfP69tGhfA2", + thumbnail: "QmS5xstyuRfrEbhsn4JVYVudxvRdfVpLBADPU4ErVh8n3L", + }, + { + beastTemplateID: 348, + dexNumber: 70, + name: "Slime", + description: + "A Slime is an elemental lifeform. Using its magma power, it can melt any metal.", + image: "QmQDHUqyMJrvmGfdf1AHTZqGAXboC9MCNZjUKncPoAeGEA", + imageTransparentBg: "QmRBbLVyD3wcgnWJrmtCum12wirfuyFajZ3ZgdoeYgUeEE", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 346, + maxAdminMintAllowed: 200, + ultimateSkill: "Magma Blast", + basicSkills: ["Lava Bolt", "Fire Trail", "Melt"], + elements: ["Fire"], + packReveal: "QmTg9FcPwKhTBZZ4csvKps8oKJT8xkRo2DdFvFvwGXHXbH", + thumbnail: "QmbtVyPDQejRdfg5JjhqcPej8TwC4k8GV3BugQ4U83SH5j", + }, + { + beastTemplateID: 349, + dexNumber: 70, + name: "Slime", + description: + "A Slime is an elemental lifeform. Using its magma power, it can melt any metal.", + image: "QmZva7dFXAtZZ44CJGDL2qWW2WDNeTnBZxt1sChpNmviy7", + imageTransparentBg: "QmbsBY7u2q7yV5Gd8DZGz34R4zWCUYc9oj3e8dDgiNofd7", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 346, + maxAdminMintAllowed: 50, + ultimateSkill: "Magma Blast", + basicSkills: ["Lava Bolt", "Fire Trail", "Melt"], + elements: ["Fire"], + packReveal: "QmRTEri9mhdM4DBXJP95pHDPyJ1mHN4Dn4WRvaPc6yDdwX", + thumbnail: "QmTQnEn9KKEuvDGTzDjP5Q9vqhCP9XUWjs77gvVWCkR4mc", + }, + { + beastTemplateID: 361, + dexNumber: 73, + name: "Vlad", + description: + "A Vlad appears during the night. It stuns its prey in fear when attacking in the darkness.", + image: "QmRRJwtnFbC9d95S754jjvex6nxQmDpdPXAURwgNKs8w89", + imageTransparentBg: "QmWdygBtHy5VJDjExqNzahcnGfD32U2D227UP2jRppB7ps", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 361, + maxAdminMintAllowed: 1000, + ultimateSkill: "Demonic Hunt", + basicSkills: ["Prey", "Screech", "Mean Bite"], + elements: ["Normal"], + packReveal: "QmYWTgFhrQGWqPLsMMCPHkvA7xZ1qEymhsN6nSKvnBrJ8r", + thumbnail: "QmerDQkdycMHLMiZSTHeeJizrupa2qzeqc7Lzp2kmo4dFL", + }, + { + beastTemplateID: 362, + dexNumber: 73, + name: "Vlad", + description: + "A Vlad appears during the night. It stuns its prey in fear when attacking in the darkness.", + image: "QmPDdyAukkJoZejhF3AqXihykz491HkhfgSbxht7H4qHnX", + imageTransparentBg: "QmW5mCsePeyAq347G8Zw4F9qouZmrCxE8JViknENf5EGJA", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 361, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Demonic Hunt", + basicSkills: ["Prey", "Screech", "Mean Bite"], + elements: ["Normal"], + packReveal: "QmbV7ov6HVMEjqY6h5MoZxpgUdfuV82GC79npFkhHrWyS3", + thumbnail: "QmNMF9RB8xVRB4KGtXqbusURztBVmbR7aWDWdAdVE75957", + }, + { + beastTemplateID: 363, + dexNumber: 73, + name: "Vlad", + description: + "A Vlad appears during the night. It stuns its prey in fear when attacking in the darkness.", + image: "QmWA2EBEPgEm9ECDCnAQW94YZLuCMzwGn9R7XDoMoePFPq", + imageTransparentBg: "QmXgU4VYYE2PyWdd3nSYFFo6wK7cwE1LHPJy6vAgRWDjop", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 361, + maxAdminMintAllowed: 200, + ultimateSkill: "Demonic Hunt", + basicSkills: ["Prey", "Screech", "Mean Bite"], + elements: ["Normal"], + packReveal: "QmZZqRsdvkpoV1oHGPiNPfrehNXDEBbTSTKcm48HQd5r7a", + thumbnail: "QmZXaNG78bS8V259ohHDB8nifTMGEAvURKFuKnVCgYcCtz", + }, + { + beastTemplateID: 364, + dexNumber: 73, + name: "Vlad", + description: + "A Vlad appears during the night. It stuns its prey in fear when attacking in the darkness.", + image: "QmRdGCibKYH3u83KcWoZAUNpTj1XGhf7KmWVwCrViV2nYw", + imageTransparentBg: "QmQynPDZfRZH7RDXjzs1KnMaAy6FaDh76NtUZ3EeC9W8Ns", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 361, + maxAdminMintAllowed: 50, + ultimateSkill: "Demonic Hunt", + basicSkills: ["Prey", "Screech", "Mean Bite"], + elements: ["Normal"], + packReveal: "QmQF4DhfjQapkULBiUrrhBS6kMnzdfQKhWMmaWePgLr3rL", + thumbnail: "QmdYHoFVvzweSWN1hqrzj1LwVQDbGddixgPu2PhDFsz35s", + }, + { + beastTemplateID: 376, + dexNumber: 76, + name: "Pancy", + description: + "A Pancy has a shocking punch. It can make any object move two times faster.", + image: "QmbhCimibun2GHb2PXEfdCLFSdxMBxikEp2JkriyUVtjfS", + imageTransparentBg: "Qmb98UsvxaWWHDkwanaNTvTojZekw9v8xEfmbaxLKMoV11", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 376, + maxAdminMintAllowed: 1000, + ultimateSkill: "Thunder God", + basicSkills: ["Lightning Fist", "Zap", "Hidden Electron"], + elements: ["Electric"], + packReveal: "QmXCk8qXvTZARBq8N9MRuYi28aiVBXqnjbPnTXmgZt2NHW", + thumbnail: "QmUi7vpLEXUJkM9Ji9qz8w7Vimqo5HbPNS3UoqbNqedjwC", + }, + { + beastTemplateID: 377, + dexNumber: 76, + name: "Pancy", + description: + "A Pancy has a shocking punch. It can make any object move two times faster.", + image: "QmPzjLZPhDUtHFBZvjP7PN1Fb2ZGtPwtXm8gyRpTWYga3k", + imageTransparentBg: "Qmaq18Pa1zY4WuWEER3CQs73W1qJhwhVxex9Z1MhXgFNR3", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 376, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Thunder God", + basicSkills: ["Lightning Fist", "Zap", "Hidden Electron"], + elements: ["Electric"], + packReveal: "QmbPBa9EM7EPZYCqgdrS3vmSDkpwKxX3mGKRjVicjQiJw9", + thumbnail: "QmWpoxn7uJB8vfHkoQHYgYvasciyVJKzcgR5nan5UnwaqA", + }, + { + beastTemplateID: 378, + dexNumber: 76, + name: "Pancy", + description: + "A Pancy has a shocking punch. It can make any object move two times faster.", + image: "QmbX7CW9tLQWLYg6jrBxsCUeMYi152kmd3pBxdM5zh8cUP", + imageTransparentBg: "QmdQSPSAemmJvAeWUfKCcf6ZQXMHTtkp7ZvJMkWa4oQGsP", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 376, + maxAdminMintAllowed: 200, + ultimateSkill: "Thunder God", + basicSkills: ["Lightning Fist", "Zap", "Hidden Electron"], + elements: ["Electric"], + packReveal: "QmYH7izXDoFPHqujPvFgQPuGDnATFuXYUPbzkSbzdZdjAL", + thumbnail: "QmcaFPr1rQAFCoN2qQUPtSAzHAu9pHoxSnY8M6qnkmeB35", + }, + { + beastTemplateID: 379, + dexNumber: 76, + name: "Pancy", + description: + "A Pancy has a shocking punch. It can make any object move two times faster.", + image: "QmS693ZGzT9i2abedfgQM2SJn5HeeeBP5sTpQjRtzXBNpg", + imageTransparentBg: "QmRjpmN7D5C8b4maZwh4vZyoZDdL8YQmNUGFHZNuUa2VZm", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 376, + maxAdminMintAllowed: 50, + ultimateSkill: "Thunder God", + basicSkills: ["Lightning Fist", "Zap", "Hidden Electron"], + elements: ["Electric"], + packReveal: "QmYGvEeRZdzZS8qksNoqH7hBFGurv1i3BkzAR9AAwiQHE5", + thumbnail: "QmTHRQuATjpoChbvcVrW4hMsCCqD4uGBsjQ8av96d3UHdi", + }, + { + beastTemplateID: 391, + dexNumber: 79, + name: "Sheldon", + description: + "A Sheldon has a calm and stoic attitude. It appears most often underwater.", + image: "QmWFN4FubHyqeR9E5neBafDswDBat9DFrj7defDDZ6qydM", + imageTransparentBg: "QmeVuEJHpzwsYsD7h3WqoWAoYjXFZttHrG9dXYBwFXcaJR", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 391, + maxAdminMintAllowed: 1000, + ultimateSkill: "Transmission", + basicSkills: ["Hydro Boost", "Daddy Shell", "Sticky Acid"], + elements: ["Water"], + packReveal: "QmQkf7Qw6Mt4fq6LvwPWoynGyKU8Wrf2mvwHjzjiofD8px", + thumbnail: "QmYMgnPNP4WwNYJV1yf6Jn8NJM1VXVwygcRSC7ZdU7sFrb", + }, + { + beastTemplateID: 392, + dexNumber: 79, + name: "Sheldon", + description: + "A Sheldon has a calm and stoic attitude. It appears most often underwater.", + image: "QmVbFv12q9KVyoahwrin9XTmAzvAp6v19tHnrj2Jb8Snzu", + imageTransparentBg: "QmNZLQsop3vMLxhQGixRCoTzLc3NzRzmnjj8siA9dwzxuo", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 391, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Transmission", + basicSkills: ["Hydro Boost", "Daddy Shell", "Sticky Acid"], + elements: ["Water"], + packReveal: "QmZ7iB4P37oVF6DwWgvMtnqqVpFyWhdV4B58PaV5um9mcA", + thumbnail: "QmTDBYX3a5SJY8ivpd1wCPgGD59jGDdbkW63YrPL7o2VKh", + }, + { + beastTemplateID: 393, + dexNumber: 79, + name: "Sheldon", + description: + "A Sheldon has a calm and stoic attitude. It appears most often underwater.", + image: "QmR8kDc5dQtQfXxLr6tYSXNbi1fX7sPFpEr7MC7h17KkmP", + imageTransparentBg: "QmQnKhjCGZfMjjeSpvmpGW1VFkf7iEBjffrD1UdbP1RrBg", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 391, + maxAdminMintAllowed: 200, + ultimateSkill: "Transmission", + basicSkills: ["Hydro Boost", "Daddy Shell", "Sticky Acid"], + elements: ["Water"], + packReveal: "QmRoqYuce88KPZtPwFnn8Lr5Zc2ihxv8fTAigpyZZ1d2g3", + thumbnail: "QmYFQhGfbSov9Lvuz2i3Y2XMVnf6WsByKygR2dy65t1ZC9", + }, + { + beastTemplateID: 394, + dexNumber: 79, + name: "Sheldon", + description: + "A Sheldon has a calm and stoic attitude. It appears most often underwater.", + image: "QmYAkEMwzgDmN2sfMpAbZsKWYeFDp75yHvNw695KEw2Bk5", + imageTransparentBg: "QmZC7dPANktdbEskKfRfo9za3gQ7vxXwprdoXmHAw22o7z", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 391, + maxAdminMintAllowed: 50, + ultimateSkill: "Transmission", + basicSkills: ["Hydro Boost", "Daddy Shell", "Sticky Acid"], + elements: ["Water"], + packReveal: "QmSu33kZfwYjbqGx2VssqUbAHDDv9T1bkJQyeMNHpFrNad", + thumbnail: "QmanFerKsVzEgCaPemkbhpGRfChX6LMfssi7sHFcBPtGJM", + }, + { + beastTemplateID: 406, + dexNumber: 82, + name: "Ivy", + description: + "An Ivy is an extremely poisonous beast. It lives in solitude.", + image: "QmZxxU6pLzKr8SNLHvMFRfWpR22UC3JhJUsYz6QWgerJSh", + imageTransparentBg: "QmRn5DibUzfvEypmk4qirzFgYiw5sJ1sjRTcGMd5ihMBVz", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 406, + maxAdminMintAllowed: 1000, + ultimateSkill: "Venomoose", + basicSkills: ["Green Lash", "Clairvoyance", "Toxic"], + elements: ["Grass"], + packReveal: "QmXw7RBAHaTtdVpLC4u2Qd4UxGDnaQtGHqbWRD87K3X6Ww", + thumbnail: "QmQgSh4BxFJQMK99aNwnFztknbCfraLnvQ7cr42aK4Xbzg", + }, + { + beastTemplateID: 407, + dexNumber: 82, + name: "Ivy", + description: + "An Ivy is an extremely poisonous beast. It lives in solitude.", + image: "QmRkjYiGhFs2JFKDAuNTDgtkZqz9Es1iBAYGCDLEi3DDnq", + imageTransparentBg: "Qme1NeoWT4SuJbdPqj5Ubh9o7AMLSHzGcPJ4ZNAKr5Ev4w", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 406, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Venomoose", + basicSkills: ["Green Lash", "Clairvoyance", "Toxic"], + elements: ["Grass"], + packReveal: "Qmf8tniTXXsKyd2ZADsu6i4dddzLw1tkPq8tT2uNH66MAk", + thumbnail: "QmQu9GHiGZA8TQ6dunY6NB6MKu9687ypABJg9xULptHY6B", + }, + { + beastTemplateID: 408, + dexNumber: 82, + name: "Ivy", + description: + "An Ivy is an extremely poisonous beast. It lives in solitude.", + image: "QmPPmNe7nnwpmT9Nfju2BpVWKhXbRFa4j18hifvJp4oBuQ", + imageTransparentBg: "QmWL8BkLUSHWfCuQL7Z4gXCiLxv6BB7NY2jCferVCdPRmK", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 406, + maxAdminMintAllowed: 200, + ultimateSkill: "Venomoose", + basicSkills: ["Green Lash", "Clairvoyance", "Toxic"], + elements: ["Grass"], + packReveal: "QmZ7GaUZtkwYD24mwr8HSNT2u2E6J3WwvkcbUq2aKuARe4", + thumbnail: "QmT3fJWb2hjr6uPGWVi7S1zjmvkeHAjhmxL2Fqu2ivABQR", + }, + { + beastTemplateID: 409, + dexNumber: 82, + name: "Ivy", + description: + "An Ivy is an extremely poisonous beast. It lives in solitude.", + image: "QmUi38oEDxXi6VqPxN3wBXo2uVVgo6Gi2auJVAgwarkwpb", + imageTransparentBg: "QmYUWbepFEhhxQcPzJBhoYuJHUpmtrwYmWgD1tmnbd1qm4", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 406, + maxAdminMintAllowed: 50, + ultimateSkill: "Venomoose", + basicSkills: ["Green Lash", "Clairvoyance", "Toxic"], + elements: ["Grass"], + packReveal: "QmdeL8t4qcj9DLCSB4Ec81ScAkaiLKvxvrpVk1DURegsq5", + thumbnail: "QmUD6wTLEbsGLLTjMGQNcc4DJpYfc1D39UULsR4QDb9JeG", + }, + { + beastTemplateID: 421, + dexNumber: 85, + name: "Tamago", + description: "A Tamago loves to collect shiny things.", + image: "QmW6GewB3WuhQCTWTLko4SYcnnusNi1rZbzg8jdjs9AEHw", + imageTransparentBg: "QmVACrbwFYzgLYid8dcuR7f1hQFiELYrvxpiNFWVsfSKWW", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 421, + maxAdminMintAllowed: 1000, + ultimateSkill: "Blazing Beam", + basicSkills: ["Heat Up", "Overcook", "Flame Kick"], + elements: ["Fire"], + packReveal: "QmRsJ17ZYLauP2x7bjNb35roZvB1oD52XzarigcYjrZv79", + thumbnail: "QmNNfi7gCmwvN8fUy2pDBc9faQQ58NaSadsy4YCvtrs9Ya", + }, + { + beastTemplateID: 422, + dexNumber: 85, + name: "Tamago", + description: "A Tamago loves to collect shiny things.", + image: "QmRbEe9g2YMBLKFZms1SvPewiediE9Zv6AtdHr8DkUqFTJ", + imageTransparentBg: "QmXQD9zbiRDPPrWpLKujm4eW8obA3mobon3EfupBgfvVa4", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 421, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Blazing Beam", + basicSkills: ["Heat Up", "Overcook", "Flame Kick"], + elements: ["Fire"], + packReveal: "QmZq97tE9H6RUWsd3H6oNxUtrKLdM1jEA6qJKWSWqjfuFf", + thumbnail: "QmSUeRKtGLw45wxAfoxnTZw5qE8DCEpFyZC2EAcCPCXRxq", + }, + { + beastTemplateID: 423, + dexNumber: 85, + name: "Tamago", + description: "A Tamago loves to collect shiny things.", + image: "QmRz82GusYrRwA1vfejQ6bsKedVhCQGyk9pWK9VycTNtxX", + imageTransparentBg: "QmTzFvGmSbeyj8KhEE1L7Tq7UTeT5pS9m3ixEU1r7bHEaH", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 421, + maxAdminMintAllowed: 200, + ultimateSkill: "Blazing Beam", + basicSkills: ["Heat Up", "Overcook", "Flame Kick"], + elements: ["Fire"], + packReveal: "QmPhHEfoNi1LBM24hxiH7p3N8ASmK8QxYdrRxzhJqEof4i", + thumbnail: "QmVZRArCY16HfseVdoNe2gDCVugaesLVys9x3T4R1zDn5x", + }, + { + beastTemplateID: 424, + dexNumber: 85, + name: "Tamago", + description: "A Tamago loves to collect shiny things.", + image: "QmaPKv1QcCCSiyU5B3fF2zWfUphTFKsDfogja2z1hboNQ3", + imageTransparentBg: "QmQbRdThz3cmvqW4x4s5oxtGbX2KDe3NsRS3M4zGMmWKT7", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 421, + maxAdminMintAllowed: 50, + ultimateSkill: "Blazing Beam", + basicSkills: ["Heat Up", "Overcook", "Flame Kick"], + elements: ["Fire"], + packReveal: "QmcYtF89CyPDFD36emAeG9rruL6cv9GvoaHw9sJwWgcFEu", + thumbnail: "QmNWGz4kRFMTuDzQhRbd8enVfwBPs4E3DJktxHfVc6wcaP", + }, + { + beastTemplateID: 436, + dexNumber: 88, + name: "Mace", + description: "A Mace is a holy being. It passes judgement on all evil.", + image: "QmRuJ4fyd2twp8ASBSr8Mnq1FBMHp7B1MkzhFQ2uJyxzPX", + imageTransparentBg: "QmXSyrQZvk8771aT57eJw311qrYoBnoQUAQraArCm2G4xz", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 436, + maxAdminMintAllowed: 1000, + ultimateSkill: "Judgement", + basicSkills: ["Divine Health", "Divine Protection", "Divine Spirit"], + elements: ["Normal"], + packReveal: "QmWbbUvkDXJFuMnnr7SuTyrS8B1nvYD4PbDj6QpfL9fT3k", + thumbnail: "QmVAdqJz8QeA46y428qg7TNoTYjnRpQ2vqtsA4Vfuxiaem", + }, + { + beastTemplateID: 437, + dexNumber: 88, + name: "Mace", + description: "A Mace is a holy being. It passes judgement on all evil.", + image: "QmUEh7156A3pfg4PGucBZzjTKcEvVzTwXut7hVfnKxp9nJ", + imageTransparentBg: "QmZm5aXo436i7m5E4ricDYVghbTWnZy5STJKA9HFEG5gTm", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 436, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Judgement", + basicSkills: ["Divine Health", "Divine Protection", "Divine Spirit"], + elements: ["Normal"], + packReveal: "QmTGd4g1s8aDGKu6mPALsy57nbSSaoA1qzAJpUJ47NpM1y", + thumbnail: "QmfDEvrRJhV7TiZhZdbzj6FYsEE4gi1JaiL2hgVUUKFFn6", + }, + { + beastTemplateID: 438, + dexNumber: 88, + name: "Mace", + description: "A Mace is a holy being. It passes judgement on all evil.", + image: "QmY92BE4X7ZsutTmU1dMk5vsRiVVhynmjNQQ6VarpqBHqs", + imageTransparentBg: "QmefxrUG23orhEwYSqDezUuZtLYbkkxS2ia36rW9eZhhPG", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 436, + maxAdminMintAllowed: 200, + ultimateSkill: "Judgement", + basicSkills: ["Divine Health", "Divine Protection", "Divine Spirit"], + elements: ["Normal"], + packReveal: "QmXeRs8jFq5ANV5hkDZdWbpMBonYWMjZQc4a7e9RXdzVzo", + thumbnail: "QmY32XayB4RUQpziRKFfEHpxmHaoPeGSoyB7tvivNjRsRw", + }, + { + beastTemplateID: 439, + dexNumber: 88, + name: "Mace", + description: "A Mace is a holy being. It passes judgement on all evil.", + image: "QmPVLzR1GUHuYJcrPrq2qUV3ZxfZZQzHAH1wgXWaBnpS9W", + imageTransparentBg: "QmNoG6nMnoHxbrYZ33nNRU4N8wENYXR9wrZancBu3c1R8J", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 436, + maxAdminMintAllowed: 50, + ultimateSkill: "Judgement", + basicSkills: ["Divine Health", "Divine Protection", "Divine Spirit"], + elements: ["Normal"], + packReveal: "QmcAdnQX4WSKCK1WaYpR9x7E9Mk3goWCFhFEYqificso53", + thumbnail: "Qmbi4EdjGfBF5AHP1CYpUVeJCSuWX3qbz34R36eQBkDZEV", + }, + { + beastTemplateID: 451, + dexNumber: 91, + name: "Tanuki", + description: "A Tanuki has a maniacal laugh that can be heard miles away.", + image: "QmX9DQMEARAS4FM5BXJSKvF71isrTznFmu5uSwtRSn72ue", + imageTransparentBg: "QmTGJPC9Z2Nv2mvo3L8Nd8JkEQQt354jXzSbyLR7d3ph4Y", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 451, + maxAdminMintAllowed: 1000, + ultimateSkill: "Snatch", + basicSkills: ["Shock Wave", "Electric Body", "Loud Cry"], + elements: ["Electric"], + packReveal: "QmPGxHQTFw7dAXNkdontt4HqLteXZiJjHJzrpwW7Xs6GXy", + thumbnail: "QmUpVP5F8t7QSijNJx5DRdHcwzvYD4cQ1n51JfGL3uai6D", + }, + { + beastTemplateID: 452, + dexNumber: 91, + name: "Tanuki", + description: "A Tanuki has a maniacal laugh that can be heard miles away.", + image: "QmSjaP81mvGSdrdrBZ1V5dztNro5fSomXPweY2XG5dNych", + imageTransparentBg: "QmYgBT1wrnswDHq1S1W1CS2njQoioWCycQLoPmZB2eoxFS", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 451, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Snatch", + basicSkills: ["Shock Wave", "Electric Body", "Loud Cry"], + elements: ["Electric"], + packReveal: "QmdyZ74PuWittatmHfoeMMCJV8xCZz7pYuesUSr5DiB8yB", + thumbnail: "QmcjwqMahFf6zWPcMgHBtnTEQgd9c7RihtJuqY18CcabAR", + }, + { + beastTemplateID: 453, + dexNumber: 91, + name: "Tanuki", + description: "A Tanuki has a maniacal laugh that can be heard miles away.", + image: "QmTfZ3jF3pjh6svSXexADZSbAu2mbvtaoL89H14kWqppyV", + imageTransparentBg: "QmX6NU2M9sLfWamSiKRfEmNfPXA1hBJZyG5426nAbTRM7r", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 451, + maxAdminMintAllowed: 200, + ultimateSkill: "Snatch", + basicSkills: ["Shock Wave", "Electric Body", "Loud Cry"], + elements: ["Electric"], + packReveal: "QmWtWs8toAyEHhdmCtrjTNwB1836E74cTuPui2idxmw9Li", + thumbnail: "QmaAMiP2r6uX5oHxBkEfcMQ4BWLgnapVdTDqsX3crzk3ND", + }, + { + beastTemplateID: 454, + dexNumber: 91, + name: "Tanuki", + description: "A Tanuki has a maniacal laugh that can be heard miles away.", + image: "QmcTLHE9wiW14egkPKGcQGGWvSnsR23Km4BA3f8Y3mSSXR", + imageTransparentBg: "QmeBtjCqdot3mCJD54orJ2U69nA3wcyJFDHUch8jEPKuXm", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 451, + maxAdminMintAllowed: 50, + ultimateSkill: "Snatch", + basicSkills: ["Shock Wave", "Electric Body", "Loud Cry"], + elements: ["Electric"], + packReveal: "QmNiLs4TkBR6cZMmUq6RdUspRWKBKC4N6ScFSDd4xg8AHb", + thumbnail: "QmcyyJmdXuPWkqwAjeLS1DKg67xNbR6xrisj6S8Hw3zoYJ", + }, + { + beastTemplateID: 466, + dexNumber: 94, + name: "Plutus", + description: + "A Plutus has an ice tail that causes frostbites when touched.", + image: "QmaQpbWgvGBk7hkLkQUiLK4xdXwm5W9o3GiZ98yEKLRKbj", + imageTransparentBg: "QmbwCcjGFPFW53fqhWhoHN5UXUWnhVEJYdXsj9u4spNjib", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 466, + maxAdminMintAllowed: 1000, + ultimateSkill: "Ice Crystal", + basicSkills: ["Cold Slap", "Icicle Throw", "Happy Dance"], + elements: ["Water"], + packReveal: "QmQQVSPPor8CRGtRg6gwtCXNgzEHTjShpSfpyyMMdRoaFW", + thumbnail: "QmbW3jYWwC4fVsjxo9EHEuKt3DYSZc3WkYCX5bk19SkuPC", + }, + { + beastTemplateID: 467, + dexNumber: 94, + name: "Plutus", + description: + "A Plutus has an ice tail that causes frostbites when touched.", + image: "QmWKgbpVHtRufB9CusifCv2W2pqszPSewQHJopZr3jueg6", + imageTransparentBg: "QmYteFoGhptvFdUsPN44cXSEeXSsZR9pCCpyjf2grJXBKb", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 466, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Ice Crystal", + basicSkills: ["Cold Slap", "Icicle Throw", "Happy Dance"], + elements: ["Water"], + packReveal: "Qmbub48T6kCsDjo6ZZKkwvvEL6Yq7RGYxLGZGZczp9qSZM", + thumbnail: "QmTU2h7CMHJtqftZrF8YysZJm9idvP7JtaHGZXFnpNYaFX", + }, + { + beastTemplateID: 468, + dexNumber: 94, + name: "Plutus", + description: + "A Plutus has an ice tail that causes frostbites when touched.", + image: "QmPeC9SHA1GTyDaDFdWZVBxhdfi9BkkDfUdoNWCk8fvhR8", + imageTransparentBg: "QmRRE7aMjyVzN4XhdCz2mHSbnesP3KneXJLbTM6Fj1hk7p", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 466, + maxAdminMintAllowed: 200, + ultimateSkill: "Ice Crystal", + basicSkills: ["Cold Slap", "Icicle Throw", "Happy Dance"], + elements: ["Water"], + packReveal: "QmdEnH4V1RJH1Mk4v7z4ZH6uw18a2Becbzv3kcJdTB2j1m", + thumbnail: "QmcH8nG7DmeRHjseSL7izRZxP4dkjRzg3fM5sHaUAPfSVf", + }, + { + beastTemplateID: 469, + dexNumber: 94, + name: "Plutus", + description: + "A Plutus has an ice tail that causes frostbites when touched.", + image: "QmeD1TjhvnYCEQz6hrDQCPBpLUkJGqAr6qYDreTca1VRqT", + imageTransparentBg: "Qmb6guvSRuwMVtBSJbcr23DzFWS2gzSSzBCe8gzXCQFkeU", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 466, + maxAdminMintAllowed: 50, + ultimateSkill: "Ice Crystal", + basicSkills: ["Cold Slap", "Icicle Throw", "Happy Dance"], + elements: ["Water"], + packReveal: "QmTKZ1x44WUCjtF8YQ1Nr27CVYbhi39atd98HTUkWN1pcX", + thumbnail: "QmRrxSShu9HCDcN2hfchQXiFSWVq4eyC4LGXnaEyXfcxnF", + }, + { + beastTemplateID: 481, + dexNumber: 97, + name: "Leaf", + description: + "A Leaf moves with the wind. It lives peacefully in the hidden woods.", + image: "QmUx8aeGXbKksBs2ZjxFqM54ChPgxZZt6Uo5bVA6na5qZN", + imageTransparentBg: "QmaXHDx3k2Z1fhGmQeBXGgYhSw5788wb99Hj2C7GrHsEhD", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 481, + maxAdminMintAllowed: 1000, + ultimateSkill: "Cellular Extraction", + basicSkills: ["Wind Slash", "Absorb", "Swift Cut"], + elements: ["Grass"], + packReveal: "QmSWkEjqhzNzNNKDS3Bh3vfDPpGeMs6w7hphcSHM836XB1", + thumbnail: "Qmbku1ToZMgatZzXCfsEuZorecKM8VZ9Wszuz8AcNp6MRC", + }, + { + beastTemplateID: 482, + dexNumber: 97, + name: "Leaf", + description: + "A Leaf moves with the wind. It lives peacefully in the hidden woods.", + image: "QmWYfeM6tGNRKuAsPNhUfczMM68LtxACFi9k45TbpBnhqU", + imageTransparentBg: "Qmak6WQHC8fR8RRbFjgiVwPF7Syd4ChmyGAvRZuQGkoMvX", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 481, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Cellular Extraction", + basicSkills: ["Wind Slash", "Absorb", "Swift Cut"], + elements: ["Grass"], + packReveal: "QmVwUe8KRMZoiTy49Y1VJL8YQZzD7j9mzzna5DocKC65W1", + thumbnail: "Qmekz8nNZG3STv8asP8R6oTUnMdRFSsvWTbbE9bHoivCU1", + }, + { + beastTemplateID: 483, + dexNumber: 97, + name: "Leaf", + description: + "A Leaf moves with the wind. It lives peacefully in the hidden woods.", + image: "QmPtjVczuntfeBmGjUtzEF9YcQXWGPREkiTRtCmZicugcG", + imageTransparentBg: "QmVsJCZSXwSqXZc1MiLiMaJpN4LTTVoGDdufvkCZvwF6N1", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 481, + maxAdminMintAllowed: 200, + ultimateSkill: "Cellular Extraction", + basicSkills: ["Wind Slash", "Absorb", "Swift Cut"], + elements: ["Grass"], + packReveal: "QmTZrrskBXys9SL9FTZXPMMRtSRoVEifDvPDWF2ZsMbgHu", + thumbnail: "QmdTYhQzsWwpNetYQxkPwXqhrR4W7hjUC4KxrhCqhELFfY", + }, + { + beastTemplateID: 484, + dexNumber: 97, + name: "Leaf", + description: + "A Leaf moves with the wind. It lives peacefully in the hidden woods.", + image: "QmNwhz1HNp21f3auXdR1Hpuzwm4Njv3oPZVcyJCRsuE2E2", + imageTransparentBg: "QmURNeoy6ooScbsNeSFvkwtXnVG2FuV5mTaXAbAtUCGc8k", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 481, + maxAdminMintAllowed: 50, + ultimateSkill: "Cellular Extraction", + basicSkills: ["Wind Slash", "Absorb", "Swift Cut"], + elements: ["Grass"], + packReveal: "QmNtJBxabyh1gSpqmhAhWyAMBfhPZ5MjkmcZ6RFkzyzx7T", + thumbnail: "QmcazZuLxiTkNWqQnE58yEXCRphY2NerQQuPPboDmmqaHE", + }, + { + beastTemplateID: 496, + dexNumber: 100, + name: "Razor", + description: + "A Razor is mostly found inside a volcano. It dislikes sharp teeth.", + image: "QmNSk7KiytbuFiYuocUFFUjb56WUzWcVB18mKEGawjWdhs", + imageTransparentBg: "QmSPn4UehKBquAKe3ZXHb5R5y8dWFQ77N5qqVBxR1dya93", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 496, + maxAdminMintAllowed: 1000, + ultimateSkill: "Erupt", + basicSkills: ["Lava Shield", "Sear", "Explosive Punch"], + elements: ["Fire"], + packReveal: "QmUEVydnLMZEGJL1eAQgvcBrT35bNb1MQJyvqqQhBZ6WrY", + thumbnail: "QmetFrZaoPugigoCxQQU7bNY9RXX8AjUfqjtuBXVdWVhZ7", + }, + { + beastTemplateID: 497, + dexNumber: 100, + name: "Razor", + description: + "A Razor is mostly found inside a volcano. It dislikes sharp teeth.", + image: "QmPuBGU7zeUZfaRqw1kMd3EDzMiKz5xqzgqqen3EJPwD32", + imageTransparentBg: "QmbEDkh7jpJyFZUeEVK3hT8ZixQRnGgNxs3Fzrbpk91Kgf", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 496, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Erupt", + basicSkills: ["Lava Shield", "Sear", "Explosive Punch"], + elements: ["Fire"], + packReveal: "QmWbvDLKzPHVD4tqoaZns6Dfg5R4tigpKVtc5TBB7wqCUC", + thumbnail: "QmdX3vHpSXooXU8dpbnLpQm48ML2wjrreBDHJwWc5BBmLs", + }, + { + beastTemplateID: 498, + dexNumber: 100, + name: "Razor", + description: + "A Razor is mostly found inside a volcano. It dislikes sharp teeth.", + image: "QmRpYdhqzqcfbkKxEjeuJm7Uj7KQLBqjsvJdyiqdrPe52d", + imageTransparentBg: "QmPjeGm6shhkRaTyfZnFT4N1WsHTbkGYsubRdTATENcNva", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 496, + maxAdminMintAllowed: 200, + ultimateSkill: "Erupt", + basicSkills: ["Lava Shield", "Sear", "Explosive Punch"], + elements: ["Fire"], + packReveal: "QmQpf2YUhEjRFmtZsqCY4MjygetZFoiEfYYR32T8TeoE2j", + thumbnail: "QmVDKsQiK7HjLb9DZBbF4KrgRsJJ3tUUSNAT6EtjAZvZvr", + }, + { + beastTemplateID: 499, + dexNumber: 100, + name: "Razor", + description: + "A Razor is mostly found inside a volcano. It dislikes sharp teeth.", + image: "QmaQpqgq1D78RuG91Y6DuSLTgceKJNmgcG4nzT9sAUi37g", + imageTransparentBg: "QmeHf3HY1qi9fpR7jZvZJv8mxDDGPRmY27fK3ZbsyUBJ1f", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 496, + maxAdminMintAllowed: 50, + ultimateSkill: "Erupt", + basicSkills: ["Lava Shield", "Sear", "Explosive Punch"], + elements: ["Fire"], + packReveal: "QmVPQMyvaT7cStFhYZtmjjjhktdvSmpcBYGoWe927Gr3Gk", + thumbnail: "QmQjuJrRDrGvKZrY6PSdL6UTzwGdQUEnUYJHWuviJq757Z", + }, + { + beastTemplateID: 511, + dexNumber: 103, + name: "Unknown", + description: + "An Unknown is said to come from the ancient pyramids of Egypt.", + image: "QmNXZbqQU2xmctSfiveLasT9qSR7QZTN2DrQyQG884YjWM", + imageTransparentBg: "QmTpNqfCsYyDzsqP4VUEN79HTmS6aPpAP6oi4kfKq6u2RY", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 511, + maxAdminMintAllowed: 1000, + ultimateSkill: "Mummify", + basicSkills: ["Soul Steal", "Ratio", "Conjure"], + elements: ["Normal"], + packReveal: "QmXi381zHJFyzEiF3En2KAbBYXbtiVrLoadSzxxRd4qTF9", + thumbnail: "QmTpSogi7CPkcCmDfcZ2osPGYvxxWBHKFJ5nMT3zBQGjXX", + }, + { + beastTemplateID: 512, + dexNumber: 103, + name: "Unknown", + description: + "An Unknown is said to come from the ancient pyramids of Egypt.", + image: "QmeuxdrHu6HGVQaGghFiPAwEvvx6LyBUV9jEJbBVvh4NCg", + imageTransparentBg: "Qmegcf4ZrVgtCSe81t962Md4JEHGmRSdknjEJXmitrDv9N", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 511, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Mummify", + basicSkills: ["Soul Steal", "Ratio", "Conjure"], + elements: ["Normal"], + packReveal: "Qma8HpjYX31x58igjqh9cMiQJ1YSjkxc6GtkMrvuLG5JyT", + thumbnail: "QmQJzszEHd2CLdWEVqN7LC31FSdeZhXZANJW9J3LNgXtk5", + }, + { + beastTemplateID: 513, + dexNumber: 103, + name: "Unknown", + description: + "An Unknown is said to come from the ancient pyramids of Egypt.", + image: "QmTerCyD6N4UEpz8dNnqYvrWSQ7PDCaGQvRPvHSznXo5VA", + imageTransparentBg: "QmWgt6v6PtitSdCixkhSMBHDwMLD8bYmGRAFMeM2n3RCEw", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 511, + maxAdminMintAllowed: 200, + ultimateSkill: "Mummify", + basicSkills: ["Soul Steal", "Ratio", "Conjure"], + elements: ["Normal"], + packReveal: "QmVMpruYFBvDioSmPa1a1hihmYHomURPi63MVhoCN6UQgo", + thumbnail: "Qmaz27bEWXWhF4X3mP8ww9aPwExqckyFzo4oQAxxBzDqZm", + }, + { + beastTemplateID: 514, + dexNumber: 103, + name: "Unknown", + description: + "An Unknown is said to come from the ancient pyramids of Egypt.", + image: "QmYBY3UPbaa3RNqZZ1BvyRdrVR34GbasgncKybryHjBLLj", + imageTransparentBg: "QmUtUNR95rLK6tD31uKuekNVbd4gBLErRK36MupR14VGJn", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 511, + maxAdminMintAllowed: 50, + ultimateSkill: "Mummify", + basicSkills: ["Soul Steal", "Ratio", "Conjure"], + elements: ["Normal"], + packReveal: "QmbjeUvcvMEN32dEzxyF5rFaaDC91aadMz5mT7cPbQQR3R", + thumbnail: "QmS3uY8Xe8wMGxAqGzwVHcxq6z6yzwsfX3sdfpp4BA9Msq", + }, + { + beastTemplateID: 526, + dexNumber: 106, + name: "Buffy", + description: + "A Buffy can store a vast amount of energy inside its body. Its body expands by demand.", + image: "QmT7PrcHVZCoKEts5pxrHtmPG9RzvQAHnM8fsn5A5T2M13", + imageTransparentBg: "QmPFoGeTzNGuJVSWpHNCBtFXi21VSw8rSoDxLLyowwxxPU", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 526, + maxAdminMintAllowed: 1000, + ultimateSkill: "Bazooka", + basicSkills: ["Pamp It", "Quick Stamp", "Whip"], + elements: ["Electric"], + packReveal: "QmeBJoiv6PF4HS88bgD4G8HkNQiWmWf3Nn2dC2FaxcU1VT", + thumbnail: "QmUSUkcZyTWRwsVYrB4a2QCAVch4braYTMC7zechmoGv88", + }, + { + beastTemplateID: 527, + dexNumber: 106, + name: "Buffy", + description: + "A Buffy can store a vast amount of energy inside its body. Its body expands by demand.", + image: "QmSsHKocRRRYDDvzck9CsNhzmNV8jFTR5CFS9YA5CQLjAJ", + imageTransparentBg: "Qmce67CLoVHnsvBKfvvJsAJuZfpxyEVuwqLbM27s2a7ZX5", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 526, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Bazooka", + basicSkills: ["Pamp It", "Quick Stamp", "Whip"], + elements: ["Electric"], + packReveal: "QmXLdDrGcqCisq6QDegHb6PnCGhXrpZXa9DhfhxqGk8x2B", + thumbnail: "QmPtFVuqgB2wi1my4Re18mA4j35UjVYBqHGDcFzpaot9Jh", + }, + { + beastTemplateID: 528, + dexNumber: 106, + name: "Buffy", + description: + "A Buffy can store a vast amount of energy inside its body. Its body expands by demand.", + image: "QmbjxA625vzi1D1MUFTVLPffUnyMj8NN7v8god9Hzrj41S", + imageTransparentBg: "QmP1MyEDrpKEgMTXVy9ZWcx2dRLAd3qYjY5YMttHPis2Kw", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 526, + maxAdminMintAllowed: 200, + ultimateSkill: "Bazooka", + basicSkills: ["Pamp It", "Quick Stamp", "Whip"], + elements: ["Electric"], + packReveal: "QmeqjNMenBrQpUVXgcTJWGo3CNu86Jy7sU9cc11HbY2u6M", + thumbnail: "QmUMQNS1ANJzsiLSuTWCXMBSeYN2x7W3UVx9dqCewsKqm4", + }, + { + beastTemplateID: 529, + dexNumber: 106, + name: "Buffy", + description: + "A Buffy can store a vast amount of energy inside its body. Its body expands by demand.", + image: "QmbkjtkUEXM2mC3gsocgSG4tytY3JZ5xX35p3ricC3kB8i", + imageTransparentBg: "QmPySigeAHf3PhretY3PSFoyniBfT9sZFKPKDbk36hNVHU", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 526, + maxAdminMintAllowed: 50, + ultimateSkill: "Bazooka", + basicSkills: ["Pamp It", "Quick Stamp", "Whip"], + elements: ["Electric"], + packReveal: "Qmf6CdoaaUJp7T85UgPeUn1NmvoWm31BN9hxP4ZWoakZeP", + thumbnail: "QmRbK4c4MT8texq2xgQEYtrBwVUBCYudXnNwTGzWgiLdSg", + }, + { + beastTemplateID: 541, + dexNumber: 109, + name: "Loch", + description: "A Loch is said to live in the deepest parts of the ocean.", + image: "QmemithNnmGrzmoo4Z7c3FDRRBCLZNJh2PFmmh8Vx9vDbC", + imageTransparentBg: "QmQX7mhjx6d1BQf8FaJb6NHppx1hQ9YhqXFB6vJDfWz7W9", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 541, + maxAdminMintAllowed: 1000, + ultimateSkill: "Splash", + basicSkills: ["Dive", "Sea Splitter", "Pressure Plunge"], + elements: ["Water"], + packReveal: "QmWUQAc4sXbNGJVt7Dqk74KLaukVM95FrbSSb1s6XZZwXL", + thumbnail: "QmYYsfz8iNEY8feXUTQr6M3M8LqfQg9frSJ6zE4ogNYz8p", + }, + { + beastTemplateID: 542, + dexNumber: 109, + name: "Loch", + description: "A Loch is said to live in the deepest parts of the ocean.", + image: "QmadnSugs6enW1gGy4eq14AF1DrTjF1xDZi249f4RPvTap", + imageTransparentBg: "QmdzK5DGCx3WoJdVsbVPgjorpzycgfDwqPG6LK7WE1AvxH", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 541, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Splash", + basicSkills: ["Dive", "Sea Splitter", "Pressure Plunge"], + elements: ["Water"], + packReveal: "QmZV1MRuXKArLYscnjygTHL4XzgYLoBx7xZkNgZUH248hU", + thumbnail: "QmUbzLGRCyeLJDxUNVMY3AaspUFnSwBEmfRPxZmfA5AQpA", + }, + { + beastTemplateID: 543, + dexNumber: 109, + name: "Loch", + description: "A Loch is said to live in the deepest parts of the ocean.", + image: "QmbgwcZf3huDtsosWyWdLZkgS3kEfA5fS5QRVn9zeksqmn", + imageTransparentBg: "QmPjr6aRQKwpYB1A4xR86MVLrnXpvxh1rqfh47RURBVRt4", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 541, + maxAdminMintAllowed: 200, + ultimateSkill: "Splash", + basicSkills: ["Dive", "Sea Splitter", "Pressure Plunge"], + elements: ["Water"], + packReveal: "QmWKqCBFmvFGfkC3BfX5ioHxbaYVyRUqu9SWt1EH9WiQjF", + thumbnail: "QmUnY9rB9CDgBsKoJT9jt4Pw6Q79G3BDZBUGMMRFUe6yKP", + }, + { + beastTemplateID: 544, + dexNumber: 109, + name: "Loch", + description: "A Loch is said to live in the deepest parts of the ocean.", + image: "Qmc3w5Qw8551vBapVnX8NsvyudUqqkGYZftQEkuwBmtAGo", + imageTransparentBg: "QmW1LC4aNr7kdzTiJxUZANVmS34NaJbwTkzpt4i9m4TYPV", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 541, + maxAdminMintAllowed: 50, + ultimateSkill: "Splash", + basicSkills: ["Dive", "Sea Splitter", "Pressure Plunge"], + elements: ["Water"], + packReveal: "QmakKGevCVXkL44aEf8U9h4peK9K8L7czSZExxBJkPxTfK", + thumbnail: "QmdMknSxmteoB9Fb192dtXphQXmKGzuuYsQnmqm7NWrtJd", + }, + { + beastTemplateID: 556, + dexNumber: 112, + name: "Spike", + description: "A Spike loves to run around in empty desert areas.", + image: "QmXpDUkcFXYDN82Ko8u8Gs4j5Vb8MbcMGfPy2KKZMGmpCV", + imageTransparentBg: "QmVGJx72kqLWpWH7CYHZG83SvHtGf5meBusUWoYWX2E4TQ", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 556, + maxAdminMintAllowed: 1000, + ultimateSkill: "Left Hook", + basicSkills: ["Prickly Kick", "Puncture", "Sprint"], + elements: ["Grass"], + packReveal: "QmZksnm5Aoi6MwTrVathXkSsfykPwaDHaF8DTg8Xkku3fR", + thumbnail: "QmPTddspSh56i1JkPzpwHBKjDBewAahg6rfRfRtjkWpJj4", + }, + { + beastTemplateID: 557, + dexNumber: 112, + name: "Spike", + description: "A Spike loves to run around in empty desert areas.", + image: "QmX9SDcYfRVgUHm3xsCaGyx2muofYw2seFF2BR3BxTnWLJ", + imageTransparentBg: "QmPe475ERJfvGHA4Khk4sRcQDyrGgmfkTeudYPBrbCQMbh", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 556, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Left Hook", + basicSkills: ["Prickly Kick", "Puncture", "Sprint"], + elements: ["Grass"], + packReveal: "QmbXGbSW5GnnMK3zEu6m39gaYtEv9pW5YxJj94MB1dvFpi", + thumbnail: "QmVFqPvtbhTub8VCEy3Sx7cwAJcon6RwPd5uXGfm4qXRdv", + }, + { + beastTemplateID: 558, + dexNumber: 112, + name: "Spike", + description: "A Spike loves to run around in empty desert areas.", + image: "QmQQUYnCeRYJ71sL34LMJerqtCP4EnZwR4TjVBS2ATqpFi", + imageTransparentBg: "QmbMpTFEyB5pKup7FbYTQv93GsQcTazted6DS5BDEb6Som", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 556, + maxAdminMintAllowed: 200, + ultimateSkill: "Left Hook", + basicSkills: ["Prickly Kick", "Puncture", "Sprint"], + elements: ["Grass"], + packReveal: "QmdZnVa7VZirt9GNXXviGnHeAiJcranuDLJbb8oUU7aAgq", + thumbnail: "QmYhJEmzThRLaQP36YhkwzRYbiaCrTnrrytVKSs9LozQB5", + }, + { + beastTemplateID: 559, + dexNumber: 112, + name: "Spike", + description: "A Spike loves to run around in empty desert areas.", + image: "QmeHJvBvDL9Cqos6j9XcLXfy3X3sH2jECeVWy9LobVFtkd", + imageTransparentBg: "QmasbGtKxWVUcdBnE92mYyq2dVyoTaJw5bRsqtcwv1TAhd", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 556, + maxAdminMintAllowed: 50, + ultimateSkill: "Left Hook", + basicSkills: ["Prickly Kick", "Puncture", "Sprint"], + elements: ["Grass"], + packReveal: "QmXvCUV7h1hntDp2CfcrNRuqAyFeDSmaed3H49RTDfdBSw", + thumbnail: "QmYEZELWSfdcoE8C5mhKnxeP9U5hFuoWWQ34Gvi9ULkkBL", + }, + { + beastTemplateID: 571, + dexNumber: 115, + name: "Twilight", + description: + "A Twilight has a tsundere personality. It can ignite blue flames that hurt enemies but heal allies.", + image: "QmRY6cgVCGRuB9eSYNohQV3YfktoFsbEL12c3sQkSoXDRB", + imageTransparentBg: "QmULpA6VzkH9xnTaqREgRe3e8LohDFhvXaJ1G7WVFkiEXd", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 571, + maxAdminMintAllowed: 1000, + ultimateSkill: "Flame Dance", + basicSkills: ["Surprise Attack", "Blue Fire", "Behind You"], + elements: ["Fire"], + packReveal: "QmaqAC7yJVmvXpp4pyPDKPkGvLSRDWZd2AJnDRYSbFqKYv", + thumbnail: "QmS9swcK1Fo5Yr5FqZTrMfyXMzCtGwrGr1MPCpViq6bjjz", + }, + { + beastTemplateID: 572, + dexNumber: 115, + name: "Twilight", + description: + "A Twilight has a tsundere personality. It can ignite blue flames that hurt enemies but heal allies.", + image: "QmZ2hJW7YLLmu5TpyUFnrfnPFFNKcnEUyPiahxTfG9KZgv", + imageTransparentBg: "QmWGHcrY1NK3t8jvJyioaUXHmDuNtuh1EEBLNssraTtVYy", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 571, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Flame Dance", + basicSkills: ["Surprise Attack", "Blue Fire", "Behind You"], + elements: ["Fire"], + packReveal: "QmRCpvhS42PVfJbUYn1DiejeSTKPSMqucUnY53Yp1Wb1y2", + thumbnail: "Qmdu8ddAfH2EP5vftudKPSeeDPWBZZCo1qp8VzPmqb7sSL", + }, + { + beastTemplateID: 573, + dexNumber: 115, + name: "Twilight", + description: + "A Twilight has a tsundere personality. It can ignite blue flames that hurt enemies but heal allies.", + image: "QmYjYg5qaeBPSFZSjijPg1JQETxhtWTyYYK2tw2LwdpaDP", + imageTransparentBg: "QmZrxssW41VyA48CT6HgrqBsYdLUFgcy4z85TTK9npid3Q", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 571, + maxAdminMintAllowed: 200, + ultimateSkill: "Flame Dance", + basicSkills: ["Surprise Attack", "Blue Fire", "Behind You"], + elements: ["Fire"], + packReveal: "QmXw3EprgnHuRVAGWzD8FWJ7urQgTcghm9HqHU2VtoWdcb", + thumbnail: "QmecBkSY7VgLjQi6o7egrPZvMwfkZTDV6T9f8fkvUPmo85", + }, + { + beastTemplateID: 574, + dexNumber: 115, + name: "Twilight", + description: + "A Twilight has a tsundere personality. It can ignite blue flames that hurt enemies but heal allies.", + image: "QmZM4pLJNisiguWihEwckgmHCHyxEEFzxedZZNQ3t7uPKe", + imageTransparentBg: "QmdxrzooxxWs2Z82xixYt5sgFTDq7mb7oJTKxLJHDAtEYm", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 571, + maxAdminMintAllowed: 50, + ultimateSkill: "Flame Dance", + basicSkills: ["Surprise Attack", "Blue Fire", "Behind You"], + elements: ["Fire"], + packReveal: "QmW1U7C5drSMoDV2FStiPfHuW8p5VeTcpEmwGyRtZRbv9x", + thumbnail: "QmSRYPgnxydsWLmAzz57mVZHGYnJ5rHSFBh6YT4dSf2wM2", + }, + { + beastTemplateID: 586, + dexNumber: 118, + name: "Dusk", + description: + "A Dusk is a special breed that is trained by the Association of Assassins.", + image: "Qmaf528R1NWrTt1uvyiC1k4H69W4YYTZokRqJibAzvYT4q", + imageTransparentBg: "QmPdykTzg6iEm36SzPHTpjP4evgAM4JVcVpfR794xPd2xX", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 586, + maxAdminMintAllowed: 1000, + ultimateSkill: "Fullmental Breakdown", + basicSkills: ["Peck Talk", "Procrastination", "Panic"], + elements: ["Normal"], + packReveal: "QmNcWfb4UuVBY4Zt1Rp5R5xBESiPWEdSijWHQf9pTgduLx", + thumbnail: "Qmc2v7U37kCcxcRAEJQTz8zWhVfMXL5SQ34A2sfQbfrbtM", + }, + { + beastTemplateID: 587, + dexNumber: 118, + name: "Dusk", + description: + "A Dusk is a special breed that is trained by the Association of Assassins.", + image: "QmNjSiL58re4tkF3e6N2RW35XLL1M8BJHoYKRiPmEMXoJt", + imageTransparentBg: "QmaDn6VMxJVa9bTeZTd3z1WhEVQbfX5DdTxU71frtV8p7F", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 586, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Fullmental Breakdown", + basicSkills: ["Peck Talk", "Procrastination", "Panic"], + elements: ["Normal"], + packReveal: "QmNgVayX3ETn62Qf2RNUBpPvdoNcaqwPjSjBXoaKJTsKyy", + thumbnail: "QmTNfNogVPnLt53pBiksSELYJbqaqjr9NUzFCCByzkQsnK", + }, + { + beastTemplateID: 588, + dexNumber: 118, + name: "Dusk", + description: + "A Dusk is a special breed that is trained by the Association of Assassins.", + image: "QmfGQFguecvYesnLqp3uzMxFQXJ15beDX8H6Uv7X5zhBTR", + imageTransparentBg: "QmUKYtWYwLb65zBMYTU2v4cMohuVaGoV4REp6DLBWBEY95", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 586, + maxAdminMintAllowed: 200, + ultimateSkill: "Fullmental Breakdown", + basicSkills: ["Peck Talk", "Procrastination", "Panic"], + elements: ["Normal"], + packReveal: "QmXRzk7EaSnDbUxGMTKLPRwP4En1Mt3trHLrR9zJL6i42o", + thumbnail: "QmRjL3bwaZDddjXetaXkzpFrwFSNSn8EophUT8GiWGnMJ7", + }, + { + beastTemplateID: 589, + dexNumber: 118, + name: "Dusk", + description: + "A Dusk is a special breed that is trained by the Association of Assassins.", + image: "QmWmHmJ1aaERtJ4crJnzgV1ZWtqSNKebTEbR73sQN1dXaF", + imageTransparentBg: "QmfDdbsiwHPUJBBGa9xWjiS687d4dxwj31Nk4cTeU7H8om", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 586, + maxAdminMintAllowed: 50, + ultimateSkill: "Fullmental Breakdown", + basicSkills: ["Peck Talk", "Procrastination", "Panic"], + elements: ["Normal"], + packReveal: "QmSaYdSQffBtVJcQh5nMbxJtsFuofLaFXDUceB8paEksS8", + thumbnail: "QmPZ59VWTUqnjnG8E3QUcWJEJ54mRNKuZUdwz9VsEiZeDp", + }, + { + beastTemplateID: 601, + dexNumber: 121, + name: "Catfish", + description: + "A Catfish is a deceptive beast. It uses its appearance to pretend it's a harmless fish.", + image: "QmVDpYUCZXU1tQwS1KQCVo1GRCWv9WASa9WcYyRDtUHtnj", + imageTransparentBg: "QmYkvvrPyVgCaAbrq5UdvNqRPBM8seky1BKSk31FDNztiY", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 601, + maxAdminMintAllowed: 1000, + ultimateSkill: "Thor", + basicSkills: ["Fake It", "Lure", "Trap"], + elements: ["Electric"], + packReveal: "QmbpXEp6j1gLxzKLy4GQmcxoW5TyXDdV3a1Xmobo3viUfK", + thumbnail: "QmNvRqNpk6vCaXSYLe9HEcRdtDrMfx9ddwKt8gfoES9TMt", + }, + { + beastTemplateID: 602, + dexNumber: 121, + name: "Catfish", + description: + "A Catfish is a deceptive beast. It uses its appearance to pretend it's a harmless fish.", + image: "QmWHg9EfVnJ2eJWEWxhmvcC2gjMo643VhPjxEVRgnDhxqS", + imageTransparentBg: "QmXHyjtFTtgqYoEqkjBsnd7MneDsCa8gvm73dnZmQm8WgM", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 601, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Thor", + basicSkills: ["Fake It", "Lure", "Trap"], + elements: ["Electric"], + packReveal: "QmNuLDGofbG7hCRDiLffBsajZYYwo9RUCEc5Qc9QxWPSpD", + thumbnail: "QmTeu8B44M89o1jsrNRrvduiAe5jrYepMMDsCxKYM831PF", + }, + { + beastTemplateID: 603, + dexNumber: 121, + name: "Catfish", + description: + "A Catfish is a deceptive beast. It uses its appearance to pretend it's a harmless fish.", + image: "QmbGddEcE5kLNnn89MUNnQyz4Hejvs5dWVXZLaoc7dmkr6", + imageTransparentBg: "QmTEvyWVwNrFNKmUpBE33dexmfWhMdpJfmBtnoLH5Jm3kN", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 601, + maxAdminMintAllowed: 200, + ultimateSkill: "Thor", + basicSkills: ["Fake It", "Lure", "Trap"], + elements: ["Electric"], + packReveal: "QmazdvQre8nPivPQHm6sASZ463vjfcxypaefNzUehWxRsD", + thumbnail: "QmTgv2RNj7b3APtigZJjP9q4ESwnUjrZaezY231e49VsFo", + }, + { + beastTemplateID: 604, + dexNumber: 121, + name: "Catfish", + description: + "A Catfish is a deceptive beast. It uses its appearance to pretend it's a harmless fish.", + image: "QmcHBKKkaYBTAA9EFdQHtdMVwE1mAmkWUYGp26hceoj914", + imageTransparentBg: "QmPsk6nnUDFbbGbTGW7oG8c6xk4cMZiWjV4w9c9nvmBMrh", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 601, + maxAdminMintAllowed: 50, + ultimateSkill: "Thor", + basicSkills: ["Fake It", "Lure", "Trap"], + elements: ["Electric"], + packReveal: "QmV6bf8GKQYK2qy7JymUQqJRkqE2MKAdqUoAUGGm2EZGUo", + thumbnail: "QmaB1fefCV1DndSVMQLTxZ66aEpt5nzd5EhZtb7z9w6zjm", + }, + { + beastTemplateID: 616, + dexNumber: 124, + name: "Puppo", + description: + "A Puppo is always cheerful. It claps its flippers aggressively when eating delicious food.", + image: "QmezXxK6md19EPUscTtWraPAVsnC6VCcy1BVCugXZTiCiQ", + imageTransparentBg: "QmRAELHem36dfmzYQh1REQ7wBzxNzwgrJuYZviW9rV39ew", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 616, + maxAdminMintAllowed: 1000, + ultimateSkill: "Heaven's Rift", + basicSkills: ["Berserker Jump", "Red Incursion", "Almighty Punch"], + elements: ["Water"], + packReveal: "QmZTGSUywirNFGwH7UzcS6Tz3L82ecpNHDpnaMgpmRb9DR", + thumbnail: "Qmb1WCeYrNtS4UBQdjYaG9qV9XmirjBpfJYhxpGqj7igSY", + }, + { + beastTemplateID: 617, + dexNumber: 124, + name: "Puppo", + description: + "A Puppo is always cheerful. It claps its flippers aggressively when eating delicious food.", + image: "QmRoqNSH2BYqLkoahTkDYBW9SaXuo9jcBPw1cox4pNJD5Z", + imageTransparentBg: "QmVed1mRphp7NwKs1oHmAMDNFqtX2pzLDNMh7ZcCAnFYRE", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 616, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Heaven's Rift", + basicSkills: ["Berserker Jump", "Red Incursion", "Almighty Punch"], + elements: ["Water"], + packReveal: "QmXXnvvP145Fd2mimvPL157LMDkPpa7y6p9PrmhGaetreS", + thumbnail: "Qmc9R4sJ9RPuZEXDKfR4XTHTTLuXCuSL3QeuBBPNSnzLmz", + }, + { + beastTemplateID: 618, + dexNumber: 124, + name: "Puppo", + description: + "A Puppo is always cheerful. It claps its flippers aggressively when eating delicious food.", + image: "QmXkSaFp8AhenqnjkxTLAXYpJ9zqHw1PGm6dAGcj3YAdbC", + imageTransparentBg: "Qma7eQhTVSzypnqSh1jtf2Dg2VH8UcoekaYkXHepYyB8b5", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 616, + maxAdminMintAllowed: 200, + ultimateSkill: "Heaven's Rift", + basicSkills: ["Berserker Jump", "Red Incursion", "Almighty Punch"], + elements: ["Water"], + packReveal: "QmT71GMJHfJTqUyNxxvkrhLK4BVT54Bn97wPDj6JJmTWhi", + thumbnail: "QmYDJzGhAQoNY9Uqxswgs3Em4eAtr4T7BeB8znJJjnqCLJ", + }, + { + beastTemplateID: 619, + dexNumber: 124, + name: "Puppo", + description: + "A Puppo is always cheerful. It claps its flippers aggressively when eating delicious food.", + image: "QmVBg9efN37yEyiVQ16iHm5jNuLUMDz6ZQPrSafDs3tg1V", + imageTransparentBg: "QmS7zyTtoz9meqwjEUzHruvDEsL8dEkc15Uckw2GFYEBjD", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 616, + maxAdminMintAllowed: 50, + ultimateSkill: "Heaven's Rift", + basicSkills: ["Berserker Jump", "Red Incursion", "Almighty Punch"], + elements: ["Water"], + packReveal: "QmUDAsq6MafS8waXzwo6qzp8RPodpjre93GpyR8g2QrJxy", + thumbnail: "Qmf2MuWt9bx39yx57Hs9PuR4XAjfu2BbDK6Y242QGhRKNs", + }, + { + beastTemplateID: 631, + dexNumber: 127, + name: "Gecko", + description: + "A Gecko likes to discover many different coins. It uses its intellect to make candy.", + image: "QmRCMJYZwQtPyLKFuPsZaURzwkqvcXjTJPexsr9YTbTgdY", + imageTransparentBg: "QmVBqZGtah7sRV7YafvZuXm8nNgts8wR1ihgfvVHa7ykZQ", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 631, + maxAdminMintAllowed: 1000, + ultimateSkill: "Mega Shill", + basicSkills: ["Ransack", "Detect Cap", "Candy Toss"], + elements: ["Grass"], + packReveal: "QmaBU9D4XwAanPCAHtbw5NSEc8RTSPEGzWnQQAP6FzxyDj", + thumbnail: "QmWrVc8Z7JYmyr7u7rZCh88rCvqJfNuYD9zqBhantLn8sR", + }, + { + beastTemplateID: 632, + dexNumber: 127, + name: "Gecko", + description: + "A Gecko likes to discover many different coins. It uses its intellect to make candy.", + image: "QmXCDiB7ptPswwA2QvkgT99PCkP6eta6DK8cdtp9DgvneD", + imageTransparentBg: "QmdvJza6HnugJictVNmRWpLL8VsD9FpX4WxXM9hRCL28Hx", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 631, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Mega Shill", + basicSkills: ["Ransack", "Detect Cap", "Candy Toss"], + elements: ["Grass"], + packReveal: "QmQBzfKoh19TMzbzqUGwrqVdNPB6NR8sgyfzYokMXDivrn", + thumbnail: "QmaCLznpWQLTFGRRJ7ExDDo4EC8zs9i4ongR5dJisvvFm6", + }, + { + beastTemplateID: 633, + dexNumber: 127, + name: "Gecko", + description: + "A Gecko likes to discover many different coins. It uses its intellect to make candy.", + image: "Qme2d27gUwf7Pg8zrSUMLWeKxYNt33QHz1NtjNs3u7d6pB", + imageTransparentBg: "QmcGLxc2d8q438xSe5HgDv55L2h63u9Pfj1r3f16tX6P1F", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 631, + maxAdminMintAllowed: 200, + ultimateSkill: "Mega Shill", + basicSkills: ["Ransack", "Detect Cap", "Candy Toss"], + elements: ["Grass"], + packReveal: "QmNT37nkFESfNiddZNoY5hHgo9rDYGf6c299KqbnghuzmL", + thumbnail: "QmUpWg2tAtxxphbMvU1uhM7mztz873bNZyaJ3PfEmiEFZW", + }, + { + beastTemplateID: 634, + dexNumber: 127, + name: "Gecko", + description: + "A Gecko likes to discover many different coins. It uses its intellect to make candy.", + image: "QmPmXN5guxHFj5cgACFEf2fu7NPzK5LCSKGYAG9eJeBhKh", + imageTransparentBg: "QmWJ2nWSGF3fZW2SSGTpkKzfAkg89PgfA4pzsbV9Q1mDfB", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 631, + maxAdminMintAllowed: 50, + ultimateSkill: "Mega Shill", + basicSkills: ["Ransack", "Detect Cap", "Candy Toss"], + elements: ["Grass"], + packReveal: "QmNheVPcbMMQvEGfbqRKHkkzjGyyyv9CaVQ8xfE9V6ZcTX", + thumbnail: "QmZN5YXsY4Z4qrZ6MUHrdcUJBSfyrtP5iYf6SqSzHcnRhW", + }, + { + beastTemplateID: 646, + dexNumber: 130, + name: "Jack", + description: "A Jack appears during the scariest nights.", + image: "QmaNqRpphk3ejjRqZpeAa8DYFn1R2veMvkJDUApisVsutv", + imageTransparentBg: "QmZfQK6PmsdLkUC8JLcyjLeh7Vmxh5drmuTQYTXb1AnYxR", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 646, + maxAdminMintAllowed: 1000, + ultimateSkill: "Hellfire", + basicSkills: ["Spook", "Trick-or-Treat", "Exploding Grenade"], + elements: ["Fire"], + packReveal: "QmVndGsZiWpUuHLQXM3hP9xS744KP3QWsTSBsUyQ98ywYY", + thumbnail: "QmcRxQgZ1KJQaAQtpfNAGGb8MhXYKc9mMemLTsLotvx22h", + }, + { + beastTemplateID: 647, + dexNumber: 130, + name: "Jack", + description: "A Jack appears during the scariest nights.", + image: "QmWy2p69HGRdkwE2zbALPgHbLvEjeULCmK4SJer6JhLSCS", + imageTransparentBg: "QmPwcZuhNXgUnq7DLCotXTYLi9kEDV4Nown1mqjZkMj6gq", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 646, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Hellfire", + basicSkills: ["Spook", "Trick-or-Treat", "Exploding Grenade"], + elements: ["Fire"], + packReveal: "Qmad6JkUs8oYyTycTCJUnEAVG3DwBcFF5ePJqqvaBcJADQ", + thumbnail: "QmNkWLPGAg19Gnf8Rgu1bBQ2R7bsXzzs4AXiGfwfZcCvWj", + }, + { + beastTemplateID: 648, + dexNumber: 130, + name: "Jack", + description: "A Jack appears during the scariest nights.", + image: "QmQWuZ3XnBTXkHnB1auBM8pUifsbjStrNpPretmBMTLDHU", + imageTransparentBg: "QmU8prkhP5hgsi4geodqeD72vZHBgaJAfgpQ37Xk8z8ymx", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 646, + maxAdminMintAllowed: 200, + ultimateSkill: "Hellfire", + basicSkills: ["Spook", "Trick-or-Treat", "Exploding Grenade"], + elements: ["Fire"], + packReveal: "QmacPs9ACW59G8cVBkPoHeZ9uy2ZPheLgczaikPjjFp9xZ", + thumbnail: "QmehHHqJHGY7hAPmsyTTtWyGG1Uq4LSY3iVa625Phy3FtR", + }, + { + beastTemplateID: 649, + dexNumber: 130, + name: "Jack", + description: "A Jack appears during the scariest nights.", + image: "QmSnJKuUUf6vz1FYBNZwWyh54Qug9TGzyKBFtJzpRgHn7G", + imageTransparentBg: "QmPEaZGDeNdB3bsDCx46nsR1HLnE8d8ZGnfdJ2j8UJYejx", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 646, + maxAdminMintAllowed: 50, + ultimateSkill: "Hellfire", + basicSkills: ["Spook", "Trick-or-Treat", "Exploding Grenade"], + elements: ["Fire"], + packReveal: "QmXKxfhL398bMDyyyaGwYcvQR9MxrMqCH1wM68Ly3pgh6n", + thumbnail: "QmXzFHHMhSCB2NkyuPHaSYGW4JwUHWCEf62WZZ3pYcyxoM", + }, + { + beastTemplateID: 661, + dexNumber: 133, + name: "Shini", + description: "A Shini takes everything very emotionally. ", + image: "QmPxo93U8t512EoyLcgziwXxovpmqTmePpn12juLgSR2cp", + imageTransparentBg: "QmWTsWUokte15E1vhWtXDF9a7fHY1YBq6acVgZtyWqNX3r", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 661, + maxAdminMintAllowed: 1000, + ultimateSkill: "Infinite Illusion", + basicSkills: ["Arcane Circle", "Ominous Breeze", "Kamikaze Kick"], + elements: ["Normal"], + packReveal: "QmSnfq8qKaHuWCvsZimh334BgDbtR62sjExUbWxRZSGaTs", + thumbnail: "QmeC3LDjTBmZX9dDfwoXpgZhSQEbckvHmcouSQhxUDpNm7", + }, + { + beastTemplateID: 662, + dexNumber: 133, + name: "Shini", + description: "A Shini takes everything very emotionally. ", + image: "QmQj2YjxVJ54stk9XN8UyeAX1AAjgx5Cvjr4MSJvQ4ivbu", + imageTransparentBg: "QmeqkWAeRFMN2ymm5QPqETGszeGj1roVszmxjbtuVdpZWv", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 661, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Infinite Illusion", + basicSkills: ["Arcane Circle", "Ominous Breeze", "Kamikaze Kick"], + elements: ["Normal"], + packReveal: "QmaFXRPuDDuYHyx2WPJVtxB1DvW4HcWGMNDEM8XLyn86nJ", + thumbnail: "Qme1MEB8nS2atHV2FTBXmMwwjtFs5erwTKpdXBBPSspx7Z", + }, + { + beastTemplateID: 663, + dexNumber: 133, + name: "Shini", + description: "A Shini takes everything very emotionally. ", + image: "QmYcXdsQraVe9LNnD3K8R6xXrW41cr1nY3fyvJJT4Vcz4q", + imageTransparentBg: "QmdF8SQTedV9azsjYgvn21Wx7yQPAz3tiWBbKoyvdmJcwt", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 661, + maxAdminMintAllowed: 200, + ultimateSkill: "Infinite Illusion", + basicSkills: ["Arcane Circle", "Ominous Breeze", "Kamikaze Kick"], + elements: ["Normal"], + packReveal: "QmY2hfJtvRnyEqwqQWRqCYD8kdAaUuZgLiToGBwRciUmBy", + thumbnail: "QmTXAEULcEVZt4n65LG55phHRAgqesN4XaYJCvv1CHGeNP", + }, + { + beastTemplateID: 664, + dexNumber: 133, + name: "Shini", + description: "A Shini takes everything very emotionally. ", + image: "QmRScXQCpFW4p7avQJJvJQBJKjPDv8srKngn1Bg3mHSQUE", + imageTransparentBg: "QmZwgjbFcaPW2wqqRMcpXB74ae7PzA1wjDokxJ1WDzBVAD", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 661, + maxAdminMintAllowed: 50, + ultimateSkill: "Infinite Illusion", + basicSkills: ["Arcane Circle", "Ominous Breeze", "Kamikaze Kick"], + elements: ["Normal"], + packReveal: "QmRQszZt5Uy5B3MhUcdh92yUHiiU2e3LiBWND8N37CiGWK", + thumbnail: "QmaRRgAUfWCnKCU4e4mJb7DjqqjiDTg4nLd3GzoTHYTHQH", + }, + { + beastTemplateID: 676, + dexNumber: 136, + name: "Uni", + description: + "A Uni is a mysterious being that can hold tokens within its body.", + image: "QmR74p3K5DwHNuZjrWdmzFiSpqv5BETMTggjGrNLFBNFBr", + imageTransparentBg: "QmQAxuVa5oHxdKJ9M6W1Krj3ngpWGDpPUA3eEeqjJJW7Rq", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 676, + maxAdminMintAllowed: 1000, + ultimateSkill: "A Trillion Swaps", + basicSkills: ["Market Maker", "High Gas", "Congestion"], + elements: ["Electric"], + packReveal: "QmbCKmHPjFevMuh9AVBsj463FqDMvNdLQ6cuGok3XTCUZ5", + thumbnail: "QmP1kWFT4GHjyydaajRFCZvATnUzEwPEsbx6LqEnVhoXat", + }, + { + beastTemplateID: 677, + dexNumber: 136, + name: "Uni", + description: + "A Uni is a mysterious being that can hold tokens within its body.", + image: "QmVxvvb5zkxPA18ueU2TNb7fB3FUDJcjqnZkyCwtq3uY3L", + imageTransparentBg: "QmPaS2SDGutAenv5piWBQmH5kwaBXgHSfq1Ntay8PnkrKy", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 676, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "A Trillion Swaps", + basicSkills: ["Market Maker", "High Gas", "Congestion"], + elements: ["Electric"], + packReveal: "QmeGCgbm7nDRmGxNcne5KT2FDmd3uyyui7GxC4GCd7GRK5", + thumbnail: "QmWvhKSS9TSDfLob5cRFPCUPQEoyXJ1fm2cckNihTjknDZ", + }, + { + beastTemplateID: 678, + dexNumber: 136, + name: "Uni", + description: + "A Uni is a mysterious being that can hold tokens within its body.", + image: "QmYf88TkR7dSnYgKXEymDnVNWFeDFGyRsHKVLQUV52thUb", + imageTransparentBg: "QmNev4VUsirWLa7eupt6TbPrdMKTYCdbAj34A1JT72H7AX", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 676, + maxAdminMintAllowed: 200, + ultimateSkill: "A Trillion Swaps", + basicSkills: ["Market Maker", "High Gas", "Congestion"], + elements: ["Electric"], + packReveal: "Qmd4RzGVA3PhwoCHUbgWGVF5DzjzE9Bm5tUWtuZsKbeuRk", + thumbnail: "Qmbc5fytgzjBZMqTjHHAhkSJvTm2NukySoMCpwMmThWtbG", + }, + { + beastTemplateID: 679, + dexNumber: 136, + name: "Uni", + description: + "A Uni is a mysterious being that can hold tokens within its body.", + image: "QmQhVtvu4pHBpUJrk85KBobNknYpbyyNQfTrGJzxsrr5qU", + imageTransparentBg: "QmPFGvH5Kjy5KMKT2oUCu7NB7HobfQxsenUM6BCFk8Ztdw", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 676, + maxAdminMintAllowed: 50, + ultimateSkill: "A Trillion Swaps", + basicSkills: ["Market Maker", "High Gas", "Congestion"], + elements: ["Electric"], + packReveal: "QmQacyuhjrcmgrRdrrhE3cDpReRgT5dpEPV5AQ2z1AdkDW", + thumbnail: "QmVrZGFuXWhfNoSrCsLFJKdZ89BFBBjXDiuRWD77etqxUh", + }, + { + beastTemplateID: 691, + dexNumber: 139, + name: "Dappy", + description: + "A Dappy loves to play with silly kitties. It remembers every moment forever.", + image: "QmdWciz9H88fu2jT1Mfu3LszJuBjvjwbW1zh77135aEukE", + imageTransparentBg: "QmUGU1LszrYGmpPp25VL6bAd5d39VW6PuDZDYSuwbj3VFS", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 691, + maxAdminMintAllowed: 1000, + ultimateSkill: "Unlimited Flowverse", + basicSkills: ["Mewtation", "Fandom", "Digital Identity"], + elements: ["Water"], + packReveal: "QmXCML61jfjc4rsYMwyrE4barXKMLnQtAVQdRryjReL3Uq", + thumbnail: "QmNwhbL2fC14jVLQiqWEJDswRNBkcEibGu7tWT7nE7fWyg", + }, + { + beastTemplateID: 692, + dexNumber: 139, + name: "Dappy", + description: + "A Dappy loves to play with silly kitties. It remembers every moment forever.", + image: "QmdmEZNR14bAAVMDSfsHz7udb7qheYemxnCoDqU8ChLqTc", + imageTransparentBg: "QmQRbwBS68j7Jta2QpAa7nKuAH5JCt8Vbq3PjJSDd5kHWC", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 691, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Unlimited Flowverse", + basicSkills: ["Mewtation", "Fandom", "Digital Identity"], + elements: ["Water"], + packReveal: "QmYCFZ3Z7WEM7dduMmU6LAxxGyHQibdw56aS1Jm6x1QLq7", + thumbnail: "QmSQz5EVpdM3nLeUnCsSp6HZP5niQsQcLkKAeS416rryko", + }, + { + beastTemplateID: 693, + dexNumber: 139, + name: "Dappy", + description: + "A Dappy loves to play with silly kitties. It remembers every moment forever.", + image: "QmRogPDFpH72HLhtGktA5VoE7hbK6FYyn8rbFtMQafZFRm", + imageTransparentBg: "QmbcfVwk1MUdSg9RqUrLGpijy2CgMDTqHpgNkmd9ZG8G9V", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 691, + maxAdminMintAllowed: 200, + ultimateSkill: "Unlimited Flowverse", + basicSkills: ["Mewtation", "Fandom", "Digital Identity"], + elements: ["Water"], + packReveal: "QmaeG1n4sgpvUBLhzhM7R3DppLACNct3tr4TDUCPAgTfph", + thumbnail: "QmXNZxURAj2UgYFasxsaTdjCwE5MR5umXDNuqNzoKTQzYR", + }, + { + beastTemplateID: 694, + dexNumber: 139, + name: "Dappy", + description: + "A Dappy loves to play with silly kitties. It remembers every moment forever.", + image: "QmcQmyYRKsrKdd35TPHq5whikDzqyqsbLbTeqx2Lr5LPCi", + imageTransparentBg: "QmRvd91ZeWV7UGGLTEEg4u9xRMD2SUScU5vKB1T4LfgrZo", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 691, + maxAdminMintAllowed: 50, + ultimateSkill: "Unlimited Flowverse", + basicSkills: ["Mewtation", "Fandom", "Digital Identity"], + elements: ["Water"], + packReveal: "QmZhsT62GgALtaExA9PgoC6JDiVCATdKzYL9vAV6QqtZ21", + thumbnail: "QmeydomtTDL7gBVEyXVGGqBvSaQfdEtYaifXdyUU3a739R", + }, + { + beastTemplateID: 706, + dexNumber: 142, + name: "Taiga", + description: + "A Taiga likes serene atmospheres. It dwells in gardens with lots of trees.", + image: "QmUyy7NBtXwgq9YAPrLwidUaoZXimLVaxHcZ522BRV97aA", + imageTransparentBg: "QmXLUKyU5ediFYXqwaaKB3Ewkob1MduL3tbhYd6AqAZYmf", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 706, + maxAdminMintAllowed: 1000, + ultimateSkill: "1000 Sakuras", + basicSkills: ["Maple Syrup", "Imperial Pine", "Lilac Burst"], + elements: ["Grass"], + packReveal: "QmU7Mp3UhHkBbJx4uWB1JJd1M9mFeTxcnwNd4UwysMWQAs", + thumbnail: "QmWHpsGgCrekYNK7GPRpFKfAE5tzbHcaHbMbmMBUvb4cAS", + }, + { + beastTemplateID: 707, + dexNumber: 142, + name: "Taiga", + description: + "A Taiga likes serene atmospheres. It dwells in gardens with lots of trees.", + image: "QmdM3LhDJ9uy32BsWKkNXz4Tq5WNDhqmUggdm5Nm4g5V11", + imageTransparentBg: "QmUUon4Ai5ZYdeZD6tYq4XVC5nYaATBC6rVu5X1sLK5sz6", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 706, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "1000 Sakuras", + basicSkills: ["Maple Syrup", "Imperial Pine", "Lilac Burst"], + elements: ["Grass"], + packReveal: "Qmdm7XvcgvRNvcGEB9S9uMSUfvDnQSGBMTXGSAZNBW65Xu", + thumbnail: "QmfUmciYaQzk1FyCPH1Lz3KxYPq7AV6V7JWzGxaznGicto", + }, + { + beastTemplateID: 708, + dexNumber: 142, + name: "Taiga", + description: + "A Taiga likes serene atmospheres. It dwells in gardens with lots of trees.", + image: "QmQxxHUsE8PPYvaUHXmYFReUEGhEkukEkWtcPerLPjMZNk", + imageTransparentBg: "QmeUms54doaRtwVSEDACbbYndpXdGNLWhJmSWHNpmigUc7", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 706, + maxAdminMintAllowed: 200, + ultimateSkill: "1000 Sakuras", + basicSkills: ["Maple Syrup", "Imperial Pine", "Lilac Burst"], + elements: ["Grass"], + packReveal: "QmZ7yL95YEzDnxLJL4tZ9mshDdoyaJGKXePB83MjBqg1pu", + thumbnail: "QmTteGoRKpJPJ5ZcPGufxpRS6c6eKtAi99asiAzRhxTSbR", + }, + { + beastTemplateID: 709, + dexNumber: 142, + name: "Taiga", + description: + "A Taiga likes serene atmospheres. It dwells in gardens with lots of trees.", + image: "Qmf2FDCWb4KYUdHNF7q8yg2k4rop4AiQNqS2beVqRibcJJ", + imageTransparentBg: "QmeKjN3S1xR3Yf3cApay2A41S2YMPpVHJggKGvZkVnY8iT", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 706, + maxAdminMintAllowed: 50, + ultimateSkill: "1000 Sakuras", + basicSkills: ["Maple Syrup", "Imperial Pine", "Lilac Burst"], + elements: ["Grass"], + packReveal: "QmXCkcF3dZPE3j6p9sDW1UvuJmubCt9aoYxUDptY7NXTmu", + thumbnail: "QmNU4EAuZkbb6uPYp7QryagkPaf1Guu5dFu7hbcwEskQoX", + }, + { + beastTemplateID: 721, + dexNumber: 145, + name: "Cake", + description: + "A Cake is an avid gambler. It enjoys burning things at both ends.", + image: "QmW3bCtFgbdDCwPJAPahvBDZxU4KRffszCcnuvV4ngEgnG", + imageTransparentBg: "QmQH9rqb4MQx2UDQy2A5uYBWP1zbaWd9vk7mRL2HXATmxc", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 721, + maxAdminMintAllowed: 1000, + ultimateSkill: "Big Burn", + basicSkills: ["Lottery", "Yield Farm", "Syrup Pool"], + elements: ["Fire"], + packReveal: "QmfY5Zh9Wnhr8DSMU3ZCztSetNENC4swM4esFBRQaJnzC4", + thumbnail: "QmSqQbnAk2TxXFVYz5K5NVBCEWkZoXB4oKNPUX7yHNFrFX", + }, + { + beastTemplateID: 722, + dexNumber: 145, + name: "Cake", + description: + "A Cake is an avid gambler. It enjoys burning things at both ends.", + image: "QmPTvD5nreqWCFurWEVyTsYpMZeujxWUFWjGcNFNRCq6Ai", + imageTransparentBg: "QmcKbSsfZD9dzmvBFG66UPwuinpEpNuWYLX4k36FDhaFX9", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 721, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "Big Burn", + basicSkills: ["Lottery", "Yield Farm", "Syrup Pool"], + elements: ["Fire"], + packReveal: "QmeUHna4EUfdq12M8F4E8TGRMctEmQ28By4hvDJ8wyTqHe", + thumbnail: "QmeCm8iHKSppQikbEW7ijeAoGHdGqyTy713JuJB3qh7S22", + }, + { + beastTemplateID: 723, + dexNumber: 145, + name: "Cake", + description: + "A Cake is an avid gambler. It enjoys burning things at both ends.", + image: "QmTBqb9NGqL4qWLRKepf1wHTyAuvmgyDbBCGVPvoAA16PR", + imageTransparentBg: "QmYYaozeBaE7uH2FrBiN9GcZ3cpn6Lk2VDS2Zbz81GJG8o", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 721, + maxAdminMintAllowed: 200, + ultimateSkill: "Big Burn", + basicSkills: ["Lottery", "Yield Farm", "Syrup Pool"], + elements: ["Fire"], + packReveal: "QmSN8MzgHxHRSPRnq6RAEyEpmnxbKvFhA83dRKod4CFG7M", + thumbnail: "QmYNPBE6iyz8piPkRsdoAd3vp91WjuKsK5Nx8RJUrxNV8m", + }, + { + beastTemplateID: 724, + dexNumber: 145, + name: "Cake", + description: + "A Cake is an avid gambler. It enjoys burning things at both ends.", + image: "QmUuGmA8hgRZF1ctiFFixFXCZ4gP4Vh2HGxeXaBhAfSXup", + imageTransparentBg: "QmaFt3EA85aKSEkcnkciwS7Tx5kqU3ACpaBNufaKAZnQsQ", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 721, + maxAdminMintAllowed: 50, + ultimateSkill: "Big Burn", + basicSkills: ["Lottery", "Yield Farm", "Syrup Pool"], + elements: ["Fire"], + packReveal: "QmUdxXjk9A6WFSjgkbGhVCwLw5V2HULxoonZYb6ti6trmH", + thumbnail: "QmYEc4JP4nJZGhHDA9acobAjndsbLt5QEgb72tz9YRCxi1", + }, + { + beastTemplateID: 736, + dexNumber: 148, + name: "Baby Doge", + description: "A Baby Doge loves Moon. It wants to do only good everyday.", + image: "QmVvqzFNMeM1AdPjav2CiGsQHT9QUM9wRpZE2U5oodMQa1", + imageTransparentBg: "QmUPFz1ZvMTBR22pyqnPC2bHFXnCrkMea9NQowE7Sn9Q7S", + rarity: "Common", + skin: "Normal", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 736, + maxAdminMintAllowed: 1000, + ultimateSkill: "One Dollar", + basicSkills: ["Much Wow", "Such Bubble", "Very Blockchain"], + elements: ["Normal"], + packReveal: "QmavWr5Ds4guN2cXENu1dy4HxqUmExH6jgkHk9ps5Lypyn", + thumbnail: "QmWyrgjmByVt9hHGu4zKm3e7wPzrB5ghpiHf1gnCTy3MqV", + }, + { + beastTemplateID: 737, + dexNumber: 148, + name: "Baby Doge", + description: "A Baby Doge loves Moon. It wants to do only good everyday.", + image: "Qmf5HA2akf1qZ5Q7NVVQvVtXXDFjr9dYSx9GWMkSRGSDcH", + imageTransparentBg: "QmcCN47ctuxYejpWEhejFYqJXj83cNrEpjxHyafnRpdNR3", + rarity: "Common", + skin: "Metallic Silver", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 736, + maxAdminMintAllowed: 1000000000, + ultimateSkill: "One Dollar", + basicSkills: ["Much Wow", "Such Bubble", "Very Blockchain"], + elements: ["Normal"], + packReveal: "QmSbUw9rZvF59ygBhXPebtZkacc75WqUbvBEkyGvBJRHkg", + thumbnail: "QmanwWfQqLaVmejUSchcrbqP4zUPDpUYENH9sKdEx5ZeVQ", + }, + { + beastTemplateID: 738, + dexNumber: 148, + name: "Baby Doge", + description: "A Baby Doge loves Moon. It wants to do only good everyday.", + image: "QmWFCDhPnUMNLhVG3VztvGLv7zyz6xyQUsZ1yPMtrczosJ", + imageTransparentBg: "QmWCK4yvSQLSx1ZaGaYhj2kUmqUbM4G8WNgWv5Fgiq3NGV", + rarity: "Common", + skin: "Cursed Black", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 736, + maxAdminMintAllowed: 200, + ultimateSkill: "One Dollar", + basicSkills: ["Much Wow", "Such Bubble", "Very Blockchain"], + elements: ["Normal"], + packReveal: "QmZUAfbrzreAKYnVzNbhArUyasR9s5TZZooAhKJ1B44nhn", + thumbnail: "QmXX3DwyS7ctoJYtmhahHYV4v1aK8eDVjAbC1r6Qx6mone", + }, + { + beastTemplateID: 739, + dexNumber: 148, + name: "Baby Doge", + description: "A Baby Doge loves Moon. It wants to do only good everyday.", + image: "QmNSg6ExncNurWTvwo5hkaiJkxmY9h9gNYtsxkxAp4HEEJ", + imageTransparentBg: "QmYuKh4soS3jxyTh4ddBgXuUi3btmPe8YAhXZuPVPDBEgM", + rarity: "Common", + skin: "Shiny Gold", + starLevel: 1, + asexual: false, + breedableBeastTemplateID: 736, + maxAdminMintAllowed: 50, + ultimateSkill: "One Dollar", + basicSkills: ["Much Wow", "Such Bubble", "Very Blockchain"], + elements: ["Normal"], + packReveal: "Qma8yHePP5hDoFyNQN8rPCZkXBpiwQCS1LZi9KDyzsFFXS", + thumbnail: "QmZ3sCw6CRF1SFkZruwg1SweeettMCyhiWKHvzA1NHfe5i", + }, +] diff --git a/flow/scripts/script.get-collection-owned-beasts.ts b/flow/scripts/script.get-collection-owned-beasts.ts index 88fba5c..ac945ba 100644 --- a/flow/scripts/script.get-collection-owned-beasts.ts +++ b/flow/scripts/script.get-collection-owned-beasts.ts @@ -1,7 +1,7 @@ export const GET_COLLECTION_OWNED_BEASTS = ` import BasicBeasts from 0xBasicBeasts - pub fun main(account: Address): [&BasicBeasts.NFT{BasicBeasts.Public}] { + access(all) fun main(account: Address): [&BasicBeasts.NFT{BasicBeasts.Public}] { let acct = getAccount(account) diff --git a/flow/scripts/script.get-fusd-balance.ts b/flow/scripts/script.get-fusd-balance.ts index d0ba238..937cde8 100644 --- a/flow/scripts/script.get-fusd-balance.ts +++ b/flow/scripts/script.get-fusd-balance.ts @@ -2,7 +2,7 @@ export const GET_FUSD_BALANCE = ` import FungibleToken from 0xFungibleToken import FUSD from 0xFUSD - pub fun main(address: Address): UFix64? { + access(all) fun main(address: Address): UFix64? { let account = getAccount(address) if let vaultRef = account.getCapability(/public/fusdBalance).borrow<&FUSD.Vault{FungibleToken.Balance}>() { return vaultRef.balance diff --git a/flow/transactions/transaction.purchase-pack-type.ts b/flow/transactions/transaction.purchase-pack-type.ts new file mode 100644 index 0000000..b46a761 --- /dev/null +++ b/flow/transactions/transaction.purchase-pack-type.ts @@ -0,0 +1,35 @@ +export const PURCHASE_PACK_TYPE = ` +import FungibleToken from 0xFungibleToken +import FUSD from 0xFUSD +import BasicBeastsDrop from 0xBasicBeastsDrop +import Pack from 0xPack +import NonFungibleToken from 0xNonFungibleToken +import MetadataViews from 0xMetadataViews + +access(all) fun hasPackCollection(_ address: Address): Bool { + return getAccount(address) + .getCapability<&Pack.Collection{NonFungibleToken.CollectionPublic, Pack.PackCollectionPublic}>(Pack.CollectionPublicPath) + .check() +} + +transaction(amount: UFix64, to: Address, type: String) { + prepare(acct: AuthAccount) { + + // Check for pack collection + if !hasPackCollection(acct.address) { + if acct.borrow<&Pack.Collection>(from: Pack.CollectionStoragePath) == nil { + acct.save(<-Pack.createEmptyCollection(), to: Pack.CollectionStoragePath) + } + acct.unlink(Pack.CollectionPublicPath) + acct.link<&Pack.Collection{NonFungibleToken.Receiver, NonFungibleToken.CollectionPublic, Pack.PackCollectionPublic, MetadataViews.ResolverCollection}>(Pack.CollectionPublicPath, target: Pack.CollectionStoragePath) + } + + BasicBeastsDrop.participate(amount: amount, + vaultAddress: to, + type: type, + vault: <- acct.borrow<&FUSD.Vault>(from: /storage/fusdVault)!.withdraw(amount: amount), + address: acct.address + ) + } +} +` diff --git a/flow/transactions/transaction.purchase_setup_collection_and_vault.ts b/flow/transactions/transaction.purchase_setup_collection_and_vault.ts index 69be365..89f3971 100644 --- a/flow/transactions/transaction.purchase_setup_collection_and_vault.ts +++ b/flow/transactions/transaction.purchase_setup_collection_and_vault.ts @@ -5,7 +5,7 @@ export const PURCHASE_SETUP_COLLECTION = ` import NonFungibleToken from 0xNonFungibleToken import MetadataViews from 0xMetadataViews - pub fun hasPackCollection(_ address: Address): Bool { + access(all) fun hasPackCollection(_ address: Address): Bool { return getAccount(address) .getCapability<&Pack.Collection{NonFungibleToken.CollectionPublic, Pack.PackCollectionPublic}>(Pack.CollectionPublicPath) .check() diff --git a/framework/hooks/use-beast-market.hook.ts b/framework/hooks/use-beast-market.hook.ts index 938c9a1..8352e7b 100644 --- a/framework/hooks/use-beast-market.hook.ts +++ b/framework/hooks/use-beast-market.hook.ts @@ -39,13 +39,14 @@ export default function useBeastMarket() { }, []) const getAllBeasts = async () => { + dispatch({ type: "PROCESSING" }) try { let res = await query({ cadence: ` import HunterScore from 0xHunterScore import BasicBeasts from 0xBasicBeasts - pub fun main(): [{String:AnyStruct}] { + access(all) fun main(): [{String:AnyStruct}] { let addresses = HunterScore.getHunterScores().keys var beasts: [{String: AnyStruct}] = [] @@ -79,7 +80,8 @@ export default function useBeastMarket() { "breedingCount" : 0, "numberOfMintedBeastTemplates" : 100, "beastTemplateID" : beastTemplate.beastTemplateID, - "id": token.id + "id": token.id, + "breedableBeastTemplateID": beastTemplate.breedableBeastTemplateID } beasts.append(beast) @@ -133,11 +135,14 @@ export default function useBeastMarket() { beastTemplateID: element.beastTemplateID, price: beastPrice, id: element.id, + breedableBeastTemplateID: element.breedableBeastTemplateID, } allBeasts.push(beast) } setBeasts(allBeasts) + dispatch({ type: "SUCCESS" }) } catch (error) { + dispatch({ type: "ERROR" }) console.log(error) } } @@ -149,7 +154,7 @@ export default function useBeastMarket() { import BasicBeasts from 0xBasicBeasts import BeastMarket from 0xBeastMarket - pub fun main(): [{String:AnyStruct}] { + access(all) fun main(): [{String:AnyStruct}] { //Get all addresses let addresses = BeastMarket.getSellers() @@ -197,7 +202,7 @@ export default function useBeastMarket() { `, }) setBeastsForSale(res) - console.log(res) + // console.log(res) return res } catch (error) { console.log(error) @@ -216,11 +221,24 @@ export default function useBeastMarket() { transaction(` import FungibleToken from 0xFungibleToken import FUSD from 0xFUSD + import NonFungibleToken from 0xNonFungibleToken + import MetadataViews from 0xMetadataViews import BasicBeasts from 0xBasicBeasts import BeastMarket from 0xBeastMarket transaction(sellerAddress: Address, beastID: UInt64, purchaseAmount: UFix64) { prepare(acct: AuthAccount) { + + //Link the Beast collection + if acct.borrow<&BasicBeasts.Collection{BasicBeasts.BeastCollectionPublic}>(from: BasicBeasts.CollectionStoragePath) == nil { + acct.save(<- BasicBeasts.createEmptyCollection(), to: BasicBeasts.CollectionStoragePath) + acct.unlink(BasicBeasts.CollectionPublicPath) + acct.link<&BasicBeasts.Collection{NonFungibleToken.Receiver, + NonFungibleToken.CollectionPublic, + BasicBeasts.BeastCollectionPublic, + MetadataViews.ResolverCollection}> + (BasicBeasts.CollectionPublicPath, target: BasicBeasts.CollectionStoragePath) + } // borrow a reference to the signer's collection let collection = acct.borrow<&BasicBeasts.Collection>(from: BasicBeasts.CollectionStoragePath) ?? panic("Could not borrow reference to the Beast Collection") @@ -556,7 +574,7 @@ export default function useBeastMarket() { import BasicBeasts from 0xBasicBeasts import BeastOffers from 0xBeastOffers - pub fun main(): [{String:AnyStruct}] { + access(all) fun main(): [{String:AnyStruct}] { //Get all addresses let addresses = BeastOffers.getOfferors() @@ -601,7 +619,7 @@ export default function useBeastMarket() { `, }) setAllBeastOffers(res) - console.log("all offers", res) + // console.log("all offers", res) return res } catch (error) { console.log(error) @@ -679,56 +697,58 @@ export default function useBeastMarket() { import BeastOffers from 0xBeastOffers transaction(offerorAddress: Address, offerID: UInt64, beastID: UInt64) { - - let collectionRef: &BasicBeasts.Collection - let offer: &BeastOffers.Offer{BeastOffers.OfferPublic} - let receiverCapability: Capability<&FUSD.Vault{FungibleToken.Receiver}> - - prepare(acct: AuthAccount) { - // check for FUSD vault - if acct.borrow<&FUSD.Vault>(from: /storage/fusdVault) == nil { - // Create a new FUSD Vault and put it in storage - acct.save(<-FUSD.createEmptyVault(), to: /storage/fusdVault) - - // Create a public capability to the Vault that only exposes - // the deposit function through the Receiver interface - acct.link<&FUSD.Vault{FungibleToken.Receiver}>( - /public/fusdReceiver, - target: /storage/fusdVault - ) - - // Create a public capability to the Vault that only exposes - // the balance field through the Balance interface - acct.link<&FUSD.Vault{FungibleToken.Balance}>( - /public/fusdBalance, - target: /storage/fusdVault - ) - } - - // Get offer collection - let offerCollectionRef = getAccount(offerorAddress).getCapability(BeastOffers.CollectionPublicPath) - .borrow<&BeastOffers.OfferCollection{BeastOffers.OfferCollectionPublic}>() - ?? panic("Couldn't borrow offeror's offer collection") - - // Get offer - self.offer = offerCollectionRef.borrowOffer(id: offerID) - ?? panic("Couldn't find offer in the offer collection") - - // Get beast collection reference - self.collectionRef = acct.borrow<&BasicBeasts.Collection>(from: BasicBeasts.CollectionStoragePath) - ?? panic("No beast collection reference found") - - // Get FUSD receiver reference - self.receiverCapability = acct.getCapability<&FUSD.Vault{FungibleToken.Receiver}>(/public/fusdReceiver) - assert(self.receiverCapability.check(), message: "Missing or mis-typed FUSD vault provider") - } - - execute { - let beast <- self.collectionRef.withdraw(withdrawID: beastID) as! @BasicBeasts.NFT - self.offer.accept(beast: <-beast, receiverCapability: self.receiverCapability) - } - } + let collectionRef: &BasicBeasts.Collection + let offerCollectionRef: &BeastOffers.OfferCollection{BeastOffers.OfferCollectionPublic} + let offer: &BeastOffers.Offer{BeastOffers.OfferPublic} + let receiverCapability: Capability<&FUSD.Vault{FungibleToken.Receiver}> + + prepare(acct: AuthAccount) { + // check for FUSD vault + if acct.borrow<&FUSD.Vault>(from: /storage/fusdVault) == nil { + // Create a new FUSD Vault and put it in storage + acct.save(<-FUSD.createEmptyVault(), to: /storage/fusdVault) + + // Create a public capability to the Vault that only exposes + // the deposit function through the Receiver interface + acct.link<&FUSD.Vault{FungibleToken.Receiver}>( + /public/fusdReceiver, + target: /storage/fusdVault + ) + + // Create a public capability to the Vault that only exposes + // the balance field through the Balance interface + acct.link<&FUSD.Vault{FungibleToken.Balance}>( + /public/fusdBalance, + target: /storage/fusdVault + ) + } + + // Get offer collection + self.offerCollectionRef = getAccount(offerorAddress).getCapability(BeastOffers.CollectionPublicPath) + .borrow<&BeastOffers.OfferCollection{BeastOffers.OfferCollectionPublic}>() + ?? panic("Couldn't borrow offeror's offer collection") + + // Get offer + self.offer = self.offerCollectionRef.borrowOffer(id: offerID) + ?? panic("Couldn't find offer in the offer collection") + + // Get beast collection reference + self.collectionRef = acct.borrow<&BasicBeasts.Collection>(from: BasicBeasts.CollectionStoragePath) + ?? panic("No beast collection reference found") + + // Get FUSD receiver reference + self.receiverCapability = acct.getCapability<&FUSD.Vault{FungibleToken.Receiver}>(/public/fusdReceiver) + assert(self.receiverCapability.check(), message: "Missing or mis-typed FUSD vault provider") + } + + execute { + let beast <- self.collectionRef.withdraw(withdrawID: beastID) as! @BasicBeasts.NFT + self.offer.accept(beast: <-beast, receiverCapability: self.receiverCapability) + self.offerCollectionRef.cleanup(offerID: offerID) + } + } + `), args([ arg(address, t.Address), @@ -772,7 +792,7 @@ export default function useBeastMarket() { let res = await query({ cadence: ` import BeastMarket from 0xBeastMarket - pub fun main(): UFix64 { + access(all) fun main(): UFix64 { return BeastMarket.highestSale } `, diff --git a/framework/hooks/use-chest-sales.hook.ts b/framework/hooks/use-chest-sales.hook.ts index 7c560d7..1f65336 100644 --- a/framework/hooks/use-chest-sales.hook.ts +++ b/framework/hooks/use-chest-sales.hook.ts @@ -29,7 +29,7 @@ export default function useChestSales() { import NFTDayTreasureChest from 0xNFTDayTreasureChest // This script returns the available chest sales - pub fun main() : {Address:{UInt64: UFix64}} { + access(all) fun main() : {Address:{UInt64: UFix64}} { let addresses = BlackMarketplace.getSellers() diff --git a/framework/hooks/use-fusd-chest-rewards.hook.ts b/framework/hooks/use-fusd-chest-rewards.hook.ts index ada4487..74111fe 100644 --- a/framework/hooks/use-fusd-chest-rewards.hook.ts +++ b/framework/hooks/use-fusd-chest-rewards.hook.ts @@ -38,7 +38,7 @@ export default function useFUSDChestRewards() { cadence: ` import TreasureChestFUSDReward from 0xTreasureChestFUSDReward - pub fun main(adminAcct: Address): [UInt64] { + access(all) fun main(adminAcct: Address): [UInt64] { let centralizedInboxRef = getAccount(adminAcct).getCapability(TreasureChestFUSDReward.CentralizedInboxPublicPath) .borrow<&TreasureChestFUSDReward.CentralizedInbox{TreasureChestFUSDReward.Public}>() ?? panic("Could not get Centralized Inbox reference") diff --git a/framework/hooks/use-fusd.hook.ts b/framework/hooks/use-fusd.hook.ts index 0a9246d..02bae1f 100644 --- a/framework/hooks/use-fusd.hook.ts +++ b/framework/hooks/use-fusd.hook.ts @@ -18,6 +18,7 @@ import { import * as fcl from "@onflow/fcl" import * as FlowTypes from "@onflow/types" import { PURCHASE } from "flow/transactions/transaction.purchase" +import { PURCHASE_PACK_TYPE } from "flow/transactions/transaction.purchase-pack-type" import { toast } from "react-toastify" import { toastStatus } from "@framework/helpers/toastStatus" @@ -25,7 +26,7 @@ export default function useFUSD(user: any) { const [state, dispatch] = useReducer(defaultReducer, { loading: true, error: false, - data: null, + data: 0, }) useEffect(() => { @@ -44,7 +45,7 @@ export default function useFUSD(user: any) { args: (arg: any, t: any) => [arg(user?.addr, t.Address)], }) dispatch({ type: "SUCCESS", payload: response }) - console.log("use-fusd.hook.ts: getFUSDBalance()") + // console.log("use-fusd.hook.ts: getFUSDBalance()") } catch (err) { dispatch({ type: "ERROR" }) console.log(err) @@ -57,7 +58,7 @@ export default function useFUSD(user: any) { cadence: GET_FUSD_BALANCE, args: (arg: any, t: any) => [arg(address, t.Address)], }) - console.log("user fusd", response) + console.log("Admin FUSD vault", response) } catch (err) { console.log(err) } @@ -114,10 +115,56 @@ export default function useFUSD(user: any) { } } + const purchasePackType = async (amount: any, address: any, type: any) => { + dispatch({ type: "PROCESSING" }) + + const id = toast.loading("Initializing...") + + try { + const res = await send([ + transaction(PURCHASE_PACK_TYPE), + args([ + arg(amount, FlowTypes.UFix64), + arg(address, FlowTypes.Address), + arg(type, FlowTypes.String), + ]), + payer(authz), + proposer(authz), + authorizations([authz]), + limit(9999), + ]).then(decode) + tx(res).subscribe((res: any) => { + toastStatus(id, res.status) + }) + const trx = await tx(res) + .onceSealed() + .then((result: any) => { + toast.update(id, { + render: "Transaction Sealed", + type: "success", + isLoading: false, + autoClose: 5000, + }) + }) + getFUSDBalance() + return trx + } catch (err) { + toast.update(id, { + render: "Error, try again later...", + type: "error", + isLoading: false, + autoClose: 5000, + }) + dispatch({ type: "ERROR" }) + console.log(err) + } + } + return { ...state, getFUSDBalance, purchase, getUserFUSDBalance, + purchasePackType, } } diff --git a/framework/hooks/use-hunter-data.hook.ts b/framework/hooks/use-hunter-data.hook.ts index 0e7bcac..5735cb4 100644 --- a/framework/hooks/use-hunter-data.hook.ts +++ b/framework/hooks/use-hunter-data.hook.ts @@ -40,7 +40,7 @@ export default function useHunterData() { cadence: ` import HunterScore from 0xHunterScore - pub fun main(): {Address: UInt32} { + access(all) fun main(): {Address: UInt32} { return HunterScore.getHunterScores() } `, @@ -60,7 +60,7 @@ export default function useHunterData() { cadence: ` import HunterScore from 0xHunterScore - pub fun main(): {Address: [UInt64]} { + access(all) fun main(): {Address: [UInt64]} { return HunterScore.getAllBeastsCollected() } `, @@ -79,7 +79,7 @@ export default function useHunterData() { cadence: ` import Profile from 0xProfile - pub fun main(addresses: [Address]) : {Address: Profile.UserProfile} { + access(all) fun main(addresses: [Address]) : {Address: Profile.UserProfile} { var profiles: {Address: Profile.UserProfile} = {} for address in addresses { let user = getAccount(address) @@ -136,15 +136,16 @@ export default function useHunterData() { // First initiate name to shortened wallet address var name = address.slice(0, 6).concat("...").concat(address.slice(-4)) var findName = "" - - if (findProfiles[address] != null) { - if (findProfiles[address].name != "") { - name = findProfiles[address].name - } - if (findProfiles[address].findName != "") { - name = findProfiles[address].findName + ".find" - findName = name - findNames[findName] = address + if (findProfiles) { + if (findProfiles[address] != null) { + if (findProfiles[address].name != "") { + name = findProfiles[address].name + } + if (findProfiles[address].findName != "") { + name = findProfiles[address].findName + ".find" + findName = name + findNames[findName] = address + } } } @@ -192,14 +193,15 @@ export default function useHunterData() { let data = hunterDataRanked[item] //check avatar var avatar = profilePictures[1].image - - if (findProfiles[data.address] != null) { - for (let key in profilePictures) { - let picture = - profilePictures[key as unknown as keyof typeof profilePictures] - .image - if (findProfiles[data.address].avatar == picture) { - avatar = picture + if (findProfiles) { + if (findProfiles[data.address] != null) { + for (let key in profilePictures) { + let picture = + profilePictures[key as unknown as keyof typeof profilePictures] + .image + if (findProfiles[data.address].avatar == picture) { + avatar = picture + } } } } @@ -224,14 +226,14 @@ export default function useHunterData() { (a: any, b: any) => b.rankByHunterScore - a.rankByHunterScore, ) - console.log("hunterData", hunterDataRankedByTotalBeasts) + // console.log("hunterData", hunterDataRankedByTotalBeasts) - console.log( - "hunterData", - hunterDataRankedByTotalBeasts.filter( - (hunter: any) => hunter.address == "0x9b4180f13bbc9e4d", - )?.[0], - ) + // console.log( + // "hunterData", + // hunterDataRankedByTotalBeasts.filter( + // (hunter: any) => hunter.address == "0x9b4180f13bbc9e4d", + // )?.[0], + // ) dispatch({ type: "SUCCESS", payload: hunterDataRankedByTotalBeasts }) } diff --git a/framework/hooks/use-user-beasts.hook.ts b/framework/hooks/use-user-beasts.hook.ts index 329ea17..3304cfe 100644 --- a/framework/hooks/use-user-beasts.hook.ts +++ b/framework/hooks/use-user-beasts.hook.ts @@ -23,26 +23,26 @@ export default function useUserBeasts(user: any) { cadence: ` import BasicBeasts from 0xBasicBeasts - pub struct Beast { - pub let id: UInt64 - pub let serialNumber: UInt32 - pub let beastTemplateID: UInt32 - pub let nickname: String? - pub let firstOwner: Address? - pub let sex: String - pub let matron: BasicBeasts.BeastNftStruct? - pub let sire: BasicBeasts.BeastNftStruct? - pub let name: String - pub let starLevel: UInt32 - pub let data: {String: String} - pub let skin: String - pub let evolvedFrom: [BasicBeasts.BeastNftStruct]? - pub let maxAdminMintAllowed: UInt32 - pub let dexNumber: UInt32 - pub let description: String - pub let elements: [String] - pub let basicSkills: [String] - pub let ultimateSkill: String + access(all) struct Beast { + access(all) let id: UInt64 + access(all) let serialNumber: UInt32 + access(all) let beastTemplateID: UInt32 + access(all) let nickname: String? + access(all) let firstOwner: Address? + access(all) let sex: String + access(all) let matron: BasicBeasts.BeastNftStruct? + access(all) let sire: BasicBeasts.BeastNftStruct? + access(all) let name: String + access(all) let starLevel: UInt32 + access(all) let data: {String: String} + access(all) let skin: String + access(all) let evolvedFrom: [BasicBeasts.BeastNftStruct]? + access(all) let maxAdminMintAllowed: UInt32 + access(all) let dexNumber: UInt32 + access(all) let description: String + access(all) let elements: [String] + access(all) let basicSkills: [String] + access(all) let ultimateSkill: String init( @@ -88,17 +88,17 @@ export default function useUserBeasts(user: any) { } } - pub fun main(acct: Address): [Beast] { + access(all) fun main(acct: Address): [Beast] { var beastCollection: [Beast] = [] let collectionRef = getAccount(acct).getCapability(BasicBeasts.CollectionPublicPath) .borrow<&{BasicBeasts.BeastCollectionPublic}>() - ?? panic("Could not get public beast collection reference") - - let beastIDs = collectionRef.getIDs() + + if(collectionRef != nil) { + let beastIDs = collectionRef!.getIDs() for id in beastIDs { - let borrowedBeast = collectionRef.borrowBeast(id: id)! + let borrowedBeast = collectionRef!.borrowBeast(id: id)! let beast = Beast( id: borrowedBeast.id, serialNumber: borrowedBeast.serialNumber, @@ -123,6 +123,9 @@ export default function useUserBeasts(user: any) { ) beastCollection.append(beast) } + } + + return beastCollection } @@ -160,7 +163,7 @@ export default function useUserBeasts(user: any) { // setUserBeastCollection(mappedCollection) dispatch({ type: "SUCCESS", payload: mappedCollection }) - console.log("your beasts", mappedCollection) + // console.log("your beasts", mappedCollection) // Get evolvable beast dictionary {beastTemplateID: [beasts]} var beasts = [...mappedCollection] beasts.sort((a, b) => a.serialNumber - b.serialNumber) diff --git a/framework/hooks/use-user-chest.hook.ts b/framework/hooks/use-user-chest.hook.ts index b1e2811..092951f 100644 --- a/framework/hooks/use-user-chest.hook.ts +++ b/framework/hooks/use-user-chest.hook.ts @@ -29,7 +29,7 @@ export default function useUserChests(user: any) { cadence: ` import NFTDayTreasureChest from 0xNFTDayTreasureChest - pub fun main(address: Address) : [UInt64] { + access(all) fun main(address: Address) : [UInt64] { let account = getAccount(address) var IDs: [UInt64] = [] @@ -61,7 +61,7 @@ export default function useUserChests(user: any) { cadence: ` import BlackMarketplace from 0xBlackMarketplace - pub fun main(address: Address) : [UInt64] { + access(all) fun main(address: Address) : [UInt64] { let account = getAccount(address) var IDs: [UInt64] = [] diff --git a/framework/hooks/use-user-inbox.hook.ts b/framework/hooks/use-user-inbox.hook.ts index f831bfe..bae36ce 100644 --- a/framework/hooks/use-user-inbox.hook.ts +++ b/framework/hooks/use-user-inbox.hook.ts @@ -71,27 +71,49 @@ export default function useInbox(user: any) { try { const res = await send([ transaction(` - import Inbox from 0xInbox + import BasicBeastsInbox from 0xInbox import Pack from 0xPack import NonFungibleToken from 0xNonFungibleToken import MetadataViews from 0xMetadataViews + import FungibleToken from 0xFungibleToken + import FUSD from 0xFUSD - pub fun hasPackCollection(_ address: Address): Bool { + access(all) fun hasPackCollection(_ address: Address): Bool { return getAccount(address) .getCapability<&Pack.Collection{NonFungibleToken.CollectionPublic, Pack.PackCollectionPublic}>(Pack.CollectionPublicPath) .check() } transaction(adminAcct: Address, quantity: Int) { - let centralizedInboxRef: &Inbox.CentralizedInbox{Inbox.Public} + let centralizedInboxRef: &BasicBeastsInbox.CentralizedInbox{BasicBeastsInbox.Public} let packCollectionRef: &Pack.Collection{NonFungibleToken.Receiver} let length: Int let IDs: [UInt64] prepare(acct: AuthAccount) { - self.centralizedInboxRef = getAccount(adminAcct).getCapability(Inbox.CentralizedInboxPublicPath) - .borrow<&Inbox.CentralizedInbox{Inbox.Public}>() + // check for FUSD vault + if acct.borrow<&FUSD.Vault>(from: /storage/fusdVault) == nil { + // Create a new FUSD Vault and put it in storage + acct.save(<-FUSD.createEmptyVault(), to: /storage/fusdVault) + + // Create a public capability to the Vault that only exposes + // the deposit function through the Receiver interface + acct.link<&FUSD.Vault{FungibleToken.Receiver}>( + /public/fusdReceiver, + target: /storage/fusdVault + ) + + // Create a public capability to the Vault that only exposes + // the balance field through the Balance interface + acct.link<&FUSD.Vault{FungibleToken.Balance}>( + /public/fusdBalance, + target: /storage/fusdVault + ) + } + + self.centralizedInboxRef = getAccount(adminAcct).getCapability(BasicBeastsInbox.CentralizedInboxPublicPath) + .borrow<&BasicBeastsInbox.CentralizedInbox{BasicBeastsInbox.Public}>() ?? panic("Could not get Centralized Inbox reference") self.IDs = self.centralizedInboxRef.getIDs(wallet: acct.address)! @@ -169,14 +191,14 @@ export default function useInbox(user: any) { try { let res = await query({ cadence: ` - import Inbox from 0xInbox + import BasicBeastsInbox from 0xInbox import NonFungibleToken from 0xNonFungibleToken import Pack from 0xPack - pub fun main(adminAcct: Address, wallet: Address): [&Pack.NFT{Pack.Public}]? { + access(all) fun main(adminAcct: Address, wallet: Address): [&Pack.NFT{Pack.Public}]? { - let centralizedInboxRef = getAccount(adminAcct).getCapability(Inbox.CentralizedInboxPublicPath) - .borrow<&Inbox.CentralizedInbox{Inbox.Public}>() + let centralizedInboxRef = getAccount(adminAcct).getCapability(BasicBeastsInbox.CentralizedInboxPublicPath) + .borrow<&BasicBeastsInbox.CentralizedInbox{BasicBeastsInbox.Public}>() ?? panic("Could not get Centralized Inbox reference") let IDs = centralizedInboxRef.getIDs(wallet: wallet) @@ -203,7 +225,7 @@ export default function useInbox(user: any) { ], }) setCentralizedInbox(res) - console.log("use-user-inbox.hook.ts: fetchInbox()") + // console.log("use-user-inbox.hook.ts: fetchInbox()") } catch (err) { console.log(err) } diff --git a/framework/hooks/use-user-packs.hook.ts b/framework/hooks/use-user-packs.hook.ts index f373006..7c30662 100644 --- a/framework/hooks/use-user-packs.hook.ts +++ b/framework/hooks/use-user-packs.hook.ts @@ -40,21 +40,24 @@ export default function useUserPacks(user: any) { cadence: ` import Pack from 0xPack - pub fun main(acct: Address): [&Pack.NFT{Pack.Public}] { + access(all) fun main(acct: Address): [&Pack.NFT{Pack.Public}] { var packCollection: [&Pack.NFT{Pack.Public}] = [] let collectionRef = getAccount(acct).getCapability(Pack.CollectionPublicPath) .borrow<&{Pack.PackCollectionPublic}>() - ?? panic("Could not get public Pack collection reference") + // ?? panic("Could not get public Pack collection reference") + if (collectionRef != nil) { + let PackIDs = collectionRef!.getIDs() - let PackIDs = collectionRef.getIDs() - - for id in PackIDs { - let pack = collectionRef.borrowPack(id: id)! - - packCollection.append(pack) + for id in PackIDs { + let pack = collectionRef!.borrowPack(id: id)! + + packCollection.append(pack) + } } + + return packCollection } `, @@ -100,7 +103,7 @@ export default function useUserPacks(user: any) { mappedPacks.push(pack) } dispatch({ type: "SUCCESS", payload: mappedPacks }) - console.log("use-user-packs.hook.ts: fetchUserPacks()") + // console.log("use-user-packs.hook.ts: fetchUserPacks()") } catch (err) { dispatch({ type: "ERROR" }) console.log(err) diff --git a/i18n.json b/i18n.json index 13304a2..62b38da 100644 --- a/i18n.json +++ b/i18n.json @@ -4,6 +4,6 @@ "pages": { "*": ["common"], "/": ["home"], - "/store": ["home"] + "/drop": ["home"] } } diff --git a/locales/en-US/home.json b/locales/en-US/home.json index fea6372..5f10d39 100644 --- a/locales/en-US/home.json +++ b/locales/en-US/home.json @@ -1,8 +1,8 @@ { "collect": "Collect &", "evolve-beasts": " Evolve Beasts. ", - "play2earn": "Play-2-earn.", - "hero-description": "Pokémon-inspired NFT collectibles game made by an 10-year old and his brother.", + "play2earn": "Play-and-earn.", + "hero-description": "A fully on-chain interactive Pokémon-inspired NFT collectibles game.", "buy-now": "Buy Now", "beast-packs": "Beast Packs", "place-your-order": "Place your order for a chance to receive a 1-star beast or more!", diff --git a/package.json b/package.json index 1952b3f..c237471 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.1.0", "private": true, "scripts": { - "dev": "next dev", + "dev": "NODE_OPTIONS=--openssl-legacy-provider next dev", "build": "next build", "start": "next start", "lint": "next lint", @@ -11,6 +11,7 @@ "generate": "gqty generate" }, "dependencies": { + "@blocto/fcl": "^1.6.1", "@fortawesome/fontawesome-svg-core": "^1.2.36", "@fortawesome/free-brands-svg-icons": "^5.15.4", "@fortawesome/free-regular-svg-icons": "^6.2.0", @@ -18,8 +19,8 @@ "@fortawesome/react-fontawesome": "^0.1.15", "@headlessui/react": "^1.6.4", "@heroicons/react": "v1", - "@onflow/fcl": "1.1.0", - "@onflow/types": "^1.0.3", + "@onflow/fcl": "^1.5.1", + "@onflow/types": "^1.1.0", "@tailwindcss/aspect-ratio": "^0.4.0", "@tanstack/match-sorter-utils": "^8.1.1", "@tanstack/react-table": "^8.5.11", diff --git a/pages/_app.tsx b/pages/_app.tsx index 75ca7c5..e5a38e8 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -1,23 +1,55 @@ import "../styles/globals.css" import type { AppProps } from "next/app" +import { useRouter } from "next/router" import Head from "next/head" import favicon from "public/favicon.ico" import Layout from "@components/common/Layout" import AuthProvider from "@components/auth/AuthProvider" import UserProvider from "@components/user/UserProvider" +import ru from "../styles/ru.module.css" function MyApp({ Component, pageProps }: AppProps) { + const { locale } = useRouter() + console.log(locale) + + const translation = locale == "ru" ? ru : null + return ( - - - Basic Beasts | Play-2-Earn - - - - - +
    + + + Basic Beasts | Play-2-Earn + + + + {/* + + + + + */} + + {/* + + */} + + + +
    ) diff --git a/pages/beast-details/[beastID].tsx b/pages/beast-details/[beastID].tsx index 9d14fa9..88d5b93 100644 --- a/pages/beast-details/[beastID].tsx +++ b/pages/beast-details/[beastID].tsx @@ -2,6 +2,7 @@ import type { NextPage } from "next" import ProductBeastView from "@components/ui/ProductBeastView" import { useUser } from "@components/user/UserProvider" import { useRouter } from "next/router" +import useBeastMarket from "@framework/hooks/use-beast-market.hook" const dummyData = [ { @@ -137,6 +138,8 @@ const dummyData = [ const BeastDetails: NextPage = () => { const { beasts, hunterData } = useUser() + const { loading } = useBeastMarket() + const router = useRouter() const { beastID } = router.query diff --git a/pages/beast/[beastDexSkin].tsx b/pages/beast/[beastDexSkin].tsx new file mode 100644 index 0000000..4196928 --- /dev/null +++ b/pages/beast/[beastDexSkin].tsx @@ -0,0 +1,77 @@ +import type { NextPage } from "next" +import { useUser } from "@components/user/UserProvider" +import { useRouter } from "next/router" +import useBeastMarket from "@framework/hooks/use-beast-market.hook" +import BeastTemplateHero from "@components/ui/BeastTemplateHero" +import BeastTemplateContent from "@components/ui/BeastTemplateContent" +import beastTemplates from "data/beastTemplates" +import { useEffect } from "react" + +const BeastDetails: NextPage = () => { + const { beasts, hunterData } = useUser() + const { loading } = useBeastMarket() + + const router = useRouter() + + const { beastDexSkin } = router.query // e.g. 001-normal = 1 + const url = beastDexSkin as string + const parts = url.split("-") + + let newDexNumber: string = "" + let skinName: string = "" + + function getDexSkin() { + const partsCount = parts.length + + switch (partsCount) { + case 2: + newDexNumber = parts[0] + skinName = + parts[1][0].toUpperCase() + parts[1].slice(1, parts[1].length) + break + case 3: + newDexNumber = parts[0] + const skinFirst = + parts[1][0].toUpperCase() + parts[1].slice(1, parts[1].length) + const skinSecond = + parts[2][0].toUpperCase() + parts[2].slice(1, parts[2].length) + skinName = skinFirst + " " + skinSecond + break + default: + break + } + + return { newDexNumber, skinName } + } + + getDexSkin() + + const beastTemplatesArr = Object.values(beastTemplates) + //Get the beast that is to be displayed on the page + const newBeast = beastTemplatesArr.filter( + (index: any) => index.dexNumber == newDexNumber && index.skin == skinName, + )[0] + + //Get array of beasts with the same dexNumber + const newBeastsByDex = beastTemplatesArr?.filter( + (index: any) => index.dexNumber == newBeast.dexNumber, + ) + + return ( +
    + {beastDexSkin != null && ( + <> + + + + )} +
    + ) +} + +export default BeastDetails diff --git a/pages/chest-rankings.tsx b/pages/chest-rankings.tsx index 4d89f74..1568458 100644 --- a/pages/chest-rankings.tsx +++ b/pages/chest-rankings.tsx @@ -893,7 +893,7 @@ const ChestRankings: NextPage = () => { let res = await query({ cadence: ` import Profile from 0xProfile - pub fun main(addresses: [Address]) : {Address: Profile.UserProfile} { + access(all) fun main(addresses: [Address]) : {Address: Profile.UserProfile} { var profiles: {Address: Profile.UserProfile} = {} for address in addresses { let user = getAccount(address) @@ -920,7 +920,7 @@ const ChestRankings: NextPage = () => { cadence: ` import NFTDayTreasureChest from 0xNFTDayTreasureChest - pub fun main(addresses: [Address]) : {Address:[UInt64]} { + access(all) fun main(addresses: [Address]) : {Address:[UInt64]} { var dict: {Address:[UInt64]} = {} for address in addresses { @@ -958,7 +958,7 @@ const ChestRankings: NextPage = () => { cadence: ` import BlackMarketplace from 0xBlackMarketplace - pub fun main(addresses: [Address]) : {Address:[UInt64]} { + access(all) fun main(addresses: [Address]) : {Address:[UInt64]} { var dict: {Address:[UInt64]} = {} for address in addresses { diff --git a/pages/store.tsx b/pages/drop.tsx similarity index 79% rename from pages/store.tsx rename to pages/drop.tsx index a153ffc..92085e5 100644 --- a/pages/store.tsx +++ b/pages/drop.tsx @@ -3,8 +3,8 @@ import HeaderDark from "@components/ui/HeaderDark" import PackStore from "@components/ui/PackStore" import styled from "styled-components" -const Store: NextPage = () => { +const Drop: NextPage = () => { return } -export default Store +export default Drop diff --git a/pages/evolution.tsx b/pages/evolution.tsx index 19d9c4e..f6f1fc6 100644 --- a/pages/evolution.tsx +++ b/pages/evolution.tsx @@ -1,13 +1,22 @@ import type { NextPage } from "next" import DefaultHeroSection from "@components/ui/DefaultHeroSection" +import EvolutionModal from "@components/ui/EvolutionModal" +import { useState } from "react" const Evolution: NextPage = () => { + const [open, setOpen] = useState(true) return (
    + setOpen(true)} + RevealModalOpen={open} + packId={"1" || "1"} + evolvedBeastId={"2"} + />
    ) } diff --git a/pages/explorer.tsx b/pages/explorer.tsx new file mode 100644 index 0000000..a56bd4b --- /dev/null +++ b/pages/explorer.tsx @@ -0,0 +1,23 @@ +import type { NextPage } from "next" +import { useUser } from "@components/user/UserProvider" +import BeastExplorerHero from "@components/ui/BeastExplorer/Hero" +import BeastExplorerContent from "@components/ui/BeastExplorer/Content" +import beastTemplates from "data/beastTemplates" + +const BeastExplorer: NextPage = () => { + const { beasts, hunterData } = useUser() + + const beastTemplatesArr = Object.values(beastTemplates) + + return ( + <> + + + + ) +} + +export default BeastExplorer diff --git a/pages/hatching.tsx b/pages/hatching.tsx new file mode 100644 index 0000000..4152d88 --- /dev/null +++ b/pages/hatching.tsx @@ -0,0 +1,24 @@ +import type { NextPage } from "next" +import DefaultHeroSection from "@components/ui/DefaultHeroSection" +import HatchingModal from "@components/ui/HatchingModal" +import { useState } from "react" + +const Hatching: NextPage = () => { + const [open, setOpen] = useState(true) + return ( +
    + + {/* setOpen(true)} + RevealModalOpen={open} + packId={"1" || "1"} + evolvedBeastId={"2"} + /> */} +
    + ) +} + +export default Hatching diff --git a/pages/index.tsx b/pages/index.tsx index c3ad33e..60bcfae 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -8,7 +8,6 @@ const Home: NextPage = () => { return (
    -
    ) } diff --git a/pages/profile/[address].tsx b/pages/profile/[address].tsx index 4b0bab9..6d6cb13 100644 --- a/pages/profile/[address].tsx +++ b/pages/profile/[address].tsx @@ -23,9 +23,11 @@ const Profile: NextPage = () => { const [shinyPacks, setShinyPacks] = useState(null) const [packCount, setPackCount] = useState(null) const [userBeastCollection, setUserBeastCollection] = useState(null) + const [userEggCollection, setUserEggCollection] = useState(null) const [sushiBalance, setSushiBalance] = useState(0) const [emptyPotionBottleBalance, setEmptyPotionBottleBalance] = useState(0) const [poopBalance, setPoopBalance] = useState(0) + const [lovePotionBalance, setLovePotionBalance] = useState(0) const [newBeast, setNewBeast] = useState(false) const [newTokens, setNewTokens] = useState(false) const [hunterScore, setHunterScore] = useState(0) @@ -64,9 +66,11 @@ const Profile: NextPage = () => { } } fetchUserBeasts() + fetchUserEggs() fetchSushi() fetchEmptyPotionBottle() fetchPoop() + fetchLovePotion() getHunterScore() getPersonalDexicon() getProfile() @@ -163,26 +167,27 @@ const Profile: NextPage = () => { cadence: ` import BasicBeasts from 0xBasicBeasts - pub struct Beast { - pub let id: UInt64 - pub let serialNumber: UInt32 - pub let beastTemplateID: UInt32 - pub let nickname: String? - pub let firstOwner: Address? - pub let sex: String - pub let matron: BasicBeasts.BeastNftStruct? - pub let sire: BasicBeasts.BeastNftStruct? - pub let name: String - pub let starLevel: UInt32 - pub let data: {String: String} - pub let skin: String - pub let evolvedFrom: [BasicBeasts.BeastNftStruct]? - pub let maxAdminMintAllowed: UInt32 - pub let dexNumber: UInt32 - pub let description: String - pub let elements: [String] - pub let basicSkills: [String] - pub let ultimateSkill: String + access(all) struct Beast { + access(all) let id: UInt64 + access(all) let serialNumber: UInt32 + access(all) let beastTemplateID: UInt32 + access(all) let nickname: String? + access(all) let firstOwner: Address? + access(all) let sex: String + access(all) let matron: BasicBeasts.BeastNftStruct? + access(all) let sire: BasicBeasts.BeastNftStruct? + access(all) let name: String + access(all) let starLevel: UInt32 + access(all) let data: {String: String} + access(all) let skin: String + access(all) let evolvedFrom: [BasicBeasts.BeastNftStruct]? + access(all) let maxAdminMintAllowed: UInt32 + access(all) let dexNumber: UInt32 + access(all) let description: String + access(all) let elements: [String] + access(all) let basicSkills: [String] + access(all) let ultimateSkill: String + access(all) let breedableBeastTemplateID: UInt32 init( @@ -205,6 +210,7 @@ const Profile: NextPage = () => { elements: [String], basicSkills: [String], ultimateSkill: String, + breedableBeastTemplateID: UInt32 ) { self.id = id self.serialNumber = serialNumber @@ -225,20 +231,21 @@ const Profile: NextPage = () => { self.elements = elements self.basicSkills = basicSkills self.ultimateSkill = ultimateSkill + self.breedableBeastTemplateID = breedableBeastTemplateID } } - pub fun main(acct: Address): [Beast] { + access(all) fun main(acct: Address): [Beast] { var beastCollection: [Beast] = [] let collectionRef = getAccount(acct).getCapability(BasicBeasts.CollectionPublicPath) .borrow<&{BasicBeasts.BeastCollectionPublic}>() - ?? panic("Could not get public beast collection reference") - - let beastIDs = collectionRef.getIDs() + + if(collectionRef!=nil) { + let beastIDs = collectionRef!.getIDs() for id in beastIDs { - let borrowedBeast = collectionRef.borrowBeast(id: id)! + let borrowedBeast = collectionRef!.borrowBeast(id: id)! let beast = Beast( id: borrowedBeast.id, serialNumber: borrowedBeast.serialNumber, @@ -258,11 +265,14 @@ const Profile: NextPage = () => { description: borrowedBeast.getBeastTemplate().description, elements: borrowedBeast.getBeastTemplate().elements, basicSkills: borrowedBeast.getBeastTemplate().basicSkills, - ultimateSkill: borrowedBeast.getBeastTemplate().ultimateSkill + ultimateSkill: borrowedBeast.getBeastTemplate().ultimateSkill, + breedableBeastTemplateID: borrowedBeast.getBeastTemplate().breedableBeastTemplateID ) beastCollection.append(beast) } + } + return beastCollection } @@ -293,6 +303,7 @@ const Profile: NextPage = () => { elements: element.elements, basicSkills: element.basicSkills, ultimateSkill: element.ultimateSkill, + breedableBeastTemplateID: element.breedableBeastTemplateID, } mappedCollection.push(beast) } @@ -320,10 +331,51 @@ const Profile: NextPage = () => { } evolvableBeasts[element.beastTemplateID] = beastsOfSameTemplate } - console.log(evolvableBeasts) setEvolvableBeasts(evolvableBeasts) getHunterScore() - console.log("profile/[address].tsx: fetchUserBeasts()") + } catch (err) { + console.log(err) + } + } + + const fetchUserEggs = async () => { + try { + let res = await query({ + cadence: ` + import Egg from 0xEgg + import FungibleToken from 0xFungibleToken + + access(all) fun main(address: Address): [&Egg.NFT{Egg.Public}] { + let account = getAccount(address) + + let collectionRef = account.getCapability(Egg.CollectionPublicPath) + .borrow<&{Egg.EggCollectionPublic}>() + + var collection: [&Egg.NFT{Egg.Public}] = [] + if (collectionRef != nil) { + let IDs = collectionRef!.getIDs() + var i = 0 + while i < IDs.length { + let token = collectionRef!.borrowEgg(id: IDs[i]) + ?? panic("Couldn't borrow a reference to the specified egg") + + if(!token.isEmpty()){ + collection.append(token) + } + + i = i + 1 + } + } + + return collection + + } + `, + + args: (arg: any, t: any) => [arg(walletAddress, t.Address)], + }) + setUserEggCollection(res) + console.log("eggs", userEggCollection) } catch (err) { console.log(err) } @@ -336,13 +388,13 @@ const Profile: NextPage = () => { import Sushi from 0xSushi import FungibleToken from 0xFungibleToken - pub fun main(address: Address): UFix64? { + access(all) fun main(address: Address): UFix64? { let account = getAccount(address) if let vaultRef = account.getCapability(Sushi.BalancePublicPath).borrow<&Sushi.Vault{FungibleToken.Balance}>() { return vaultRef.balance } - return nil + return 0.0 } `, @@ -350,7 +402,6 @@ const Profile: NextPage = () => { args: (arg: any, t: any) => [arg(walletAddress, t.Address)], }) setSushiBalance(res) - console.log("profile/[address].tsx: fetchSushi()") } catch (err) { console.log(err) } @@ -363,13 +414,13 @@ const Profile: NextPage = () => { import EmptyPotionBottle from 0xEmptyPotionBottle import FungibleToken from 0xFungibleToken - pub fun main(address: Address): UFix64? { + access(all) fun main(address: Address): UFix64? { let account = getAccount(address) if let vaultRef = account.getCapability(EmptyPotionBottle.BalancePublicPath).borrow<&EmptyPotionBottle.Vault{FungibleToken.Balance}>() { return vaultRef.balance } - return nil + return 0.0 } `, @@ -377,7 +428,6 @@ const Profile: NextPage = () => { args: (arg: any, t: any) => [arg(walletAddress, t.Address)], }) setEmptyPotionBottleBalance(res) - console.log("profile/[address].tsx: fetchEmptyPotionBottle()") } catch (err) { console.log(err) } @@ -390,13 +440,13 @@ const Profile: NextPage = () => { import Poop from 0xPoop import FungibleToken from 0xFungibleToken - pub fun main(address: Address): UFix64? { + access(all) fun main(address: Address): UFix64? { let account = getAccount(address) if let vaultRef = account.getCapability(Poop.BalancePublicPath).borrow<&Poop.Vault{FungibleToken.Balance}>() { return vaultRef.balance } - return nil + return 0.0 } `, @@ -404,7 +454,39 @@ const Profile: NextPage = () => { args: (arg: any, t: any) => [arg(walletAddress, t.Address)], }) setPoopBalance(res) - console.log("profile/[address].tsx: fetchPoop()") + } catch (err) { + console.log(err) + } + } + + const fetchLovePotion = async () => { + try { + let res = await query({ + cadence: ` + import LovePotion from 0xLovePotion + import FungibleToken from 0xFungibleToken + + access(all) fun main(address: Address): Int { + let account = getAccount(address) + + let collectionRef = account.getCapability(LovePotion.CollectionPublicPath) + .borrow<&{LovePotion.LovePotionCollectionPublic}>() + + var count: Int = 0 + if (collectionRef != nil) { + let IDs = collectionRef!.getIDs() + count = IDs.length + } + + + return count + + } + `, + + args: (arg: any, t: any) => [arg(walletAddress, t.Address)], + }) + setLovePotionBalance(res) } catch (err) { console.log(err) } @@ -416,20 +498,22 @@ const Profile: NextPage = () => { cadence: ` import Pack from 0xPack - pub fun main(acct: Address): [&Pack.NFT{Pack.Public}] { + access(all) fun main(acct: Address): [&Pack.NFT{Pack.Public}] { var packCollection: [&Pack.NFT{Pack.Public}] = [] let collectionRef = getAccount(acct).getCapability(Pack.CollectionPublicPath) .borrow<&{Pack.PackCollectionPublic}>() - ?? panic("Could not get public Pack collection reference") - let PackIDs = collectionRef.getIDs() + if(collectionRef != nil) { + let PackIDs = collectionRef!.getIDs() - for id in PackIDs { - let pack = collectionRef.borrowPack(id: id)! - - packCollection.append(pack) - } + for id in PackIDs { + let pack = collectionRef!.borrowPack(id: id)! + + packCollection.append(pack) + } + } + return packCollection } @@ -477,7 +561,6 @@ const Profile: NextPage = () => { } getPacks(mappedPacks) - console.log("profile/[address].tsx: fetchUserPacks()") } catch (err) { console.log(err) } @@ -489,14 +572,13 @@ const Profile: NextPage = () => { cadence: ` import HunterScore from 0xHunterScore - pub fun main(acct: Address): UInt32? { + access(all) fun main(acct: Address): UInt32? { return HunterScore.getHunterScore(wallet: acct) } `, args: (arg: any, t: any) => [arg(walletAddress, t.Address)], }) setHunterScore(res) - console.log("profile/[address].tsx: getHunterScore()") } catch (error) { console.log(error) } @@ -508,7 +590,7 @@ const Profile: NextPage = () => { cadence: ` import HunterScore from 0xHunterScore - pub fun main(acct: Address): [UInt32]? { + access(all) fun main(acct: Address): [UInt32]? { return HunterScore.getBeastTemplatesCollected(wallet: acct) } `, @@ -528,7 +610,6 @@ const Profile: NextPage = () => { personalDex[dexNumber] = image } setDexicon(personalDex) - console.log("profile/[address].tsx: getPersonalDexicon()") } catch (error) { console.log(error) } @@ -540,7 +621,7 @@ const Profile: NextPage = () => { cadence: ` import Profile from 0xProfile - pub fun main(address: Address) : Profile.UserProfile? { + access(all) fun main(address: Address) : Profile.UserProfile? { return getAccount(address) .getCapability<&{Profile.Public}>(Profile.publicPath) .borrow()?.asProfile() @@ -549,11 +630,10 @@ const Profile: NextPage = () => { `, args: (arg: any, t: any) => [arg(walletAddress, t.Address)], }) - console.log("Profile:" + res) //Resolve Profile setProfile(res) //Resolve Profile Picture - let avatar = res.avatar + let avatar = res?.avatar for (let key in profilePictures) { let element = profilePictures[key as unknown as keyof typeof profilePictures] @@ -561,7 +641,6 @@ const Profile: NextPage = () => { setProfilePicture(element.image) } } - console.log("profile/[address].tsx: getProfile()") } catch (error) { console.log(error) } @@ -573,7 +652,7 @@ const Profile: NextPage = () => { cadence: ` import Evolution from 0xEvolution - pub fun main(): {UInt32: UInt32} { + access(all) fun main(): {UInt32: UInt32} { return Evolution.getAllEvolutionPairs() } `, @@ -622,9 +701,11 @@ const Profile: NextPage = () => { selectPackType={setSelectedPackType} packCount={packCount} beasts={userBeastCollection} + eggs={userEggCollection} sushiBalance={sushiBalance} emptyPotionBottleBalance={emptyPotionBottleBalance} poopBalance={poopBalance} + lovePotionBalance={lovePotionBalance} newBeast={newBeast} setNewBeast={setNewBeast} newTokens={newTokens} diff --git a/pages/setup.tsx b/pages/setup.tsx new file mode 100644 index 0000000..c180575 --- /dev/null +++ b/pages/setup.tsx @@ -0,0 +1,90 @@ +import type { NextPage } from "next" +import DefaultHeroSection from "@components/ui/DefaultHeroSection" +import { useState } from "react" +import { + query, + send, + transaction, + args, + arg, + payer, + proposer, + authorizations, + limit, + authz, + decode, + tx, +} from "@onflow/fcl" +import { toast } from "react-toastify" +import * as t from "@onflow/types" +import { useAuth } from "@components/auth/AuthProvider" +import { toastStatus } from "@framework/helpers/toastStatus" + +const Setup: NextPage = () => { + const [open, setOpen] = useState(true) + + const { user } = useAuth() + + const setup = async () => { + const id = toast.loading("Initializing...") + + try { + const res = await send([ + transaction(` + import BasicBeasts from 0xde7a5daf9df48c65 + import NonFungibleToken from 0x1d7e57aa55817448 + import MetadataViews from 0x1d7e57aa55817448 + + transaction() { + prepare(signer: AuthAccount) { + if signer.borrow<&BasicBeasts.Collection>(from: BasicBeasts.CollectionStoragePath) == nil { + signer.save(<-BasicBeasts.createEmptyCollection(), to: BasicBeasts.CollectionStoragePath) + + signer.unlink(BasicBeasts.CollectionPublicPath) + + signer.link<&BasicBeasts.Collection{BasicBeasts.BeastCollectionPublic, NonFungibleToken.CollectionPublic, NonFungibleToken.Receiver, MetadataViews.ResolverCollection}>(BasicBeasts.CollectionPublicPath, target: BasicBeasts.CollectionStoragePath) + + } + + } + } + `), + payer(authz), + proposer(authz), + authorizations([authz]), + limit(9999), + ]).then(decode) + tx(res).subscribe((res: any) => { + toastStatus(id, res.status) + }) + await tx(res) + .onceSealed() + .then((result: any) => { + toast.update(id, { + render: "Transaction Sealed", + type: "success", + isLoading: false, + autoClose: 5000, + }) + }) + // fetchHunterData() Don't have this otherwise /profile/user.find won't show packs and packs will be reloaded + } catch (err) { + toast.update(id, { + render: () =>
    Error, try again later...
    , + type: "error", + isLoading: false, + autoClose: 5000, + }) + console.log(err) + } + } + + return ( +
    setup()}> + + +
    + ) +} + +export default Setup diff --git a/pages/treasure-hunt.tsx b/pages/treasure-hunt.tsx index 7656dcd..7e5aae7 100644 --- a/pages/treasure-hunt.tsx +++ b/pages/treasure-hunt.tsx @@ -209,7 +209,7 @@ const Treasure: NextPage = () => { import MetadataViews from 0xMetadataViews import NFTDayTreasureChest from 0xNFTDayTreasureChest - pub fun hasChestCollection(_ address: Address): Bool { + access(all) fun hasChestCollection(_ address: Address): Bool { return getAccount(address) .getCapability<&NFTDayTreasureChest.Collection{NonFungibleToken.CollectionPublic, NFTDayTreasureChest.NFTDayTreasureChestCollectionPublic}>(NFTDayTreasureChest.CollectionPublicPath) .check() diff --git a/public/139_normal.png b/public/139_normal.png new file mode 100644 index 0000000..814bde4 Binary files /dev/null and b/public/139_normal.png differ diff --git a/public/arrowIcon.svg b/public/arrowIcon.svg new file mode 100644 index 0000000..a50ad6d --- /dev/null +++ b/public/arrowIcon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/beasts/001_unknown.png b/public/beasts/001_unknown.png index 1c7b1e4..ddec884 100644 Binary files a/public/beasts/001_unknown.png and b/public/beasts/001_unknown.png differ diff --git a/public/beasts/058_unknown.png b/public/beasts/058_unknown.png new file mode 100644 index 0000000..35cf11a Binary files /dev/null and b/public/beasts/058_unknown.png differ diff --git a/public/document.svg b/public/document.svg new file mode 100644 index 0000000..c842e9c --- /dev/null +++ b/public/document.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/eggAnimation.gif b/public/eggAnimation.gif new file mode 100644 index 0000000..610f169 Binary files /dev/null and b/public/eggAnimation.gif differ diff --git a/public/eggs/default_shine.png b/public/eggs/default_shine.png new file mode 100644 index 0000000..bc8c8c0 Binary files /dev/null and b/public/eggs/default_shine.png differ diff --git a/public/eggs/egg_hatching_default.gif b/public/eggs/egg_hatching_default.gif new file mode 100644 index 0000000..aed21c5 Binary files /dev/null and b/public/eggs/egg_hatching_default.gif differ diff --git a/public/eggs/egg_hatching_electric.gif b/public/eggs/egg_hatching_electric.gif new file mode 100644 index 0000000..1399f42 Binary files /dev/null and b/public/eggs/egg_hatching_electric.gif differ diff --git a/public/eggs/egg_hatching_fire.gif b/public/eggs/egg_hatching_fire.gif new file mode 100644 index 0000000..ad22f7a Binary files /dev/null and b/public/eggs/egg_hatching_fire.gif differ diff --git a/public/eggs/egg_hatching_grass.gif b/public/eggs/egg_hatching_grass.gif new file mode 100644 index 0000000..7e5f71e Binary files /dev/null and b/public/eggs/egg_hatching_grass.gif differ diff --git a/public/eggs/egg_hatching_normal.gif b/public/eggs/egg_hatching_normal.gif new file mode 100644 index 0000000..a7852f3 Binary files /dev/null and b/public/eggs/egg_hatching_normal.gif differ diff --git a/public/eggs/egg_hatching_water.gif b/public/eggs/egg_hatching_water.gif new file mode 100644 index 0000000..07069a2 Binary files /dev/null and b/public/eggs/egg_hatching_water.gif differ diff --git a/public/eggs/electric_shine.png b/public/eggs/electric_shine.png new file mode 100644 index 0000000..2f58616 Binary files /dev/null and b/public/eggs/electric_shine.png differ diff --git a/public/eggs/fire_shine.png b/public/eggs/fire_shine.png new file mode 100644 index 0000000..fa2fdab Binary files /dev/null and b/public/eggs/fire_shine.png differ diff --git a/public/eggs/grass_shine.png b/public/eggs/grass_shine.png new file mode 100644 index 0000000..075b8db Binary files /dev/null and b/public/eggs/grass_shine.png differ diff --git a/public/eggs/incubator_default_testnet.gif b/public/eggs/incubator_default_testnet.gif new file mode 100644 index 0000000..a04f9f8 Binary files /dev/null and b/public/eggs/incubator_default_testnet.gif differ diff --git a/public/eggs/incubator_electric_testnet.gif b/public/eggs/incubator_electric_testnet.gif new file mode 100644 index 0000000..7c29775 Binary files /dev/null and b/public/eggs/incubator_electric_testnet.gif differ diff --git a/public/eggs/incubator_fire_testnet.gif b/public/eggs/incubator_fire_testnet.gif new file mode 100644 index 0000000..186f652 Binary files /dev/null and b/public/eggs/incubator_fire_testnet.gif differ diff --git a/public/eggs/incubator_grass_testnet.gif b/public/eggs/incubator_grass_testnet.gif new file mode 100644 index 0000000..1a33bd9 Binary files /dev/null and b/public/eggs/incubator_grass_testnet.gif differ diff --git a/public/eggs/incubator_normal_testnet.gif b/public/eggs/incubator_normal_testnet.gif new file mode 100644 index 0000000..e951a25 Binary files /dev/null and b/public/eggs/incubator_normal_testnet.gif differ diff --git a/public/eggs/incubator_water_testnet.gif b/public/eggs/incubator_water_testnet.gif new file mode 100644 index 0000000..2c11ead Binary files /dev/null and b/public/eggs/incubator_water_testnet.gif differ diff --git a/public/eggs/normal_shine.png b/public/eggs/normal_shine.png new file mode 100644 index 0000000..36922db Binary files /dev/null and b/public/eggs/normal_shine.png differ diff --git a/public/eggs/water_shine.png b/public/eggs/water_shine.png new file mode 100644 index 0000000..b7314d5 Binary files /dev/null and b/public/eggs/water_shine.png differ diff --git a/public/emptyImg.png b/public/emptyImg.png new file mode 100644 index 0000000..00ad2a4 Binary files /dev/null and b/public/emptyImg.png differ diff --git a/public/fonts/PixeloidSans/PixeloidSans.ttf b/public/fonts/PixeloidSans/PixeloidSans.ttf new file mode 100644 index 0000000..445d9b8 Binary files /dev/null and b/public/fonts/PixeloidSans/PixeloidSans.ttf differ diff --git a/public/fungible_tokens/fungible_tokens_images/basic_beasts_empy_potion_bottle.png b/public/fungible_tokens/fungible_tokens_images/basic_beasts_empy_potion_bottle.png index b2e8d0e..f359f9c 100644 Binary files a/public/fungible_tokens/fungible_tokens_images/basic_beasts_empy_potion_bottle.png and b/public/fungible_tokens/fungible_tokens_images/basic_beasts_empy_potion_bottle.png differ diff --git a/public/icons8-list-48.png b/public/icons8-list-48.png new file mode 100644 index 0000000..f2e268e Binary files /dev/null and b/public/icons8-list-48.png differ diff --git a/public/infoIcon.svg b/public/infoIcon.svg new file mode 100644 index 0000000..86aa035 --- /dev/null +++ b/public/infoIcon.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/lightning.svg b/public/lightning.svg new file mode 100644 index 0000000..5275a09 --- /dev/null +++ b/public/lightning.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/love_potion.gif b/public/love_potion.gif new file mode 100644 index 0000000..cb30d78 Binary files /dev/null and b/public/love_potion.gif differ diff --git a/public/love_potion.png b/public/love_potion.png deleted file mode 100644 index 7cdaa21..0000000 Binary files a/public/love_potion.png and /dev/null differ diff --git a/public/mysterious_old_lady.png b/public/mysterious_old_lady.png index a865c38..3dd4c53 100644 Binary files a/public/mysterious_old_lady.png and b/public/mysterious_old_lady.png differ diff --git a/public/overview.svg b/public/overview.svg new file mode 100644 index 0000000..a47230a --- /dev/null +++ b/public/overview.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/social_icons/copyIcon.svg b/public/social_icons/copyIcon.svg new file mode 100644 index 0000000..dc847b1 --- /dev/null +++ b/public/social_icons/copyIcon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/social_icons/iconFacebook.svg b/public/social_icons/iconFacebook.svg new file mode 100644 index 0000000..8f1aca9 --- /dev/null +++ b/public/social_icons/iconFacebook.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/social_icons/iconTelegram.svg b/public/social_icons/iconTelegram.svg new file mode 100644 index 0000000..8db9d56 --- /dev/null +++ b/public/social_icons/iconTelegram.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/social_icons/iconTwitter.svg b/public/social_icons/iconTwitter.svg new file mode 100644 index 0000000..6e22120 --- /dev/null +++ b/public/social_icons/iconTwitter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/social_icons/iconWhatsapp.svg b/public/social_icons/iconWhatsapp.svg new file mode 100644 index 0000000..18134bf --- /dev/null +++ b/public/social_icons/iconWhatsapp.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/sort_icon.png b/public/sort_icon.png new file mode 100644 index 0000000..0180bb3 Binary files /dev/null and b/public/sort_icon.png differ diff --git a/public/teddies/013_cursed_black_transparent_face.png b/public/teddies/013_cursed_black_transparent_face.png new file mode 100644 index 0000000..b951e6b Binary files /dev/null and b/public/teddies/013_cursed_black_transparent_face.png differ diff --git a/public/teddies/013_metallic_silver_face.gif b/public/teddies/013_metallic_silver_face.gif new file mode 100644 index 0000000..6636002 Binary files /dev/null and b/public/teddies/013_metallic_silver_face.gif differ diff --git a/public/teddies/013_mystery.png b/public/teddies/013_mystery.png new file mode 100644 index 0000000..7f24533 Binary files /dev/null and b/public/teddies/013_mystery.png differ diff --git a/public/teddies/013_normal.png b/public/teddies/013_normal.png new file mode 100644 index 0000000..a35a1e1 Binary files /dev/null and b/public/teddies/013_normal.png differ diff --git a/public/teddies/013_shiny_gold_face.gif b/public/teddies/013_shiny_gold_face.gif new file mode 100644 index 0000000..3189403 Binary files /dev/null and b/public/teddies/013_shiny_gold_face.gif differ diff --git a/styles/globals.css b/styles/globals.css index d5ffca7..bcef87a 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -21,7 +21,7 @@ input { cursor: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAAzElEQVRYR+2X0Q6AIAhF5f8/2jYXZkwEjNSVvVUjDpcrGgT7FUkI2D9xRfQETwNIiWO85wfINfQUEyxBG2ArsLwC0jioGt5zFcwF4OYDPi/mBYKm4t0U8ATgRm3ThFoAqkhNgWkA0jJLvaOVSs7j3qMnSgXWBMiWPXe94QqMBMBc1VZIvaTu5u5pQewq0EqNZvIEMCmxAawK0DNkay9QmfFNAJUXfgGgUkLaE7j/h8fnASkxHTz0DGIBMCnBeeM7AArpUd3mz2x3C7wADglA8BcWMZhZAAAAAElFTkSuQmCC) 14 0, pointer !important; - user-select: none; + /* user-select: none; */ } a { diff --git a/styles/ru.module.css b/styles/ru.module.css new file mode 100644 index 0000000..539b520 --- /dev/null +++ b/styles/ru.module.css @@ -0,0 +1,8 @@ +@font-face { + font-family: PixeloidSans; + src: url(../public/fonts/PixeloidSans/PixeloidSans.ttf); +} + +.ruLang { + font-family: "PixeloidSans" !important; +} diff --git a/test.cdc b/test.cdc new file mode 100644 index 0000000..23aa939 --- /dev/null +++ b/test.cdc @@ -0,0 +1,61 @@ +import HunterScore from 0xfa252d0aa22bf86a +import BasicBeasts from 0xfa252d0aa22bf86a + +pub fun main(): [{String:AnyStruct}] { + + let addresses = HunterScore.getHunterScores().keys + var beasts: [{String: AnyStruct}] = [] + var index = 0 + let limit = 10 + + + for address in addresses { + let collectionRef = getAccount(address).getCapability(BasicBeasts.CollectionPublicPath) + .borrow<&{BasicBeasts.BeastCollectionPublic}>() + if (collectionRef != nil) { + let IDs = collectionRef!.getIDs() + var i = 0 + while i < IDs.length && index < limit { + let token = collectionRef!.borrowBeast(id: IDs[i]) + ?? panic("Couldn't borrow a reference to the specified beast") + + let beastTemplate = token.getBeastTemplate() + + let beast = { + "name" : beastTemplate.name, + "description" : beastTemplate.description, + "nickname" : token.getNickname(), + "serialNumber" : token.serialNumber, + "dexNumber" : beastTemplate.dexNumber, + "skin" : beastTemplate.skin, + "starLevel" : beastTemplate.starLevel, + "elements" : beastTemplate.elements, + "basicSkills" : beastTemplate.basicSkills, + "ultimateSkill" : beastTemplate.ultimateSkill, + "currentOwner" : address, + "firstOwner" : token.getFirstOwner(), + "sex" : token.sex, + "breedingCount" : 0, + "numberOfMintedBeastTemplates" : 100, + "beastTemplateID" : beastTemplate.beastTemplateID, + "id": token.id + } + + beasts.append(beast) + index = index + 1 + + i = i + 1 + + } + } + } + + + return beasts +} + +// flow scripts execute test.cdc -n=testnet + +// a b +// FRLabs join two objects +// let newArray = [...a, ...b] \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 1ce3877..7b4e4fd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + "@babel/code-frame@7.12.11": version "7.12.11" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" @@ -176,6 +181,42 @@ "@babel/helper-validator-identifier" "^7.14.9" to-fast-properties "^2.0.0" +"@blocto/fcl@^1.6.1": + version "1.6.1" + resolved "https://registry.yarnpkg.com/@blocto/fcl/-/fcl-1.6.1.tgz#1058561938c7a3762682e512ec1259ed7deead78" + integrity sha512-h1w83ZhcHty0RLMfzL9tS6oLfHUoJvnYHJ04ZJVAEwtz/yIXBV/d6A0RTu/23pwOYe94/SErKhNz+5nhrLTJ9Q== + dependencies: + "@babel/runtime" "^7.18.6" + "@blocto/flow-sdk" "^1.2.2" + "@onflow/config" "^1.1.2" + "@onflow/interaction" "0.0.11" + "@onflow/rlp" "^1.1.0" + "@onflow/types" "^1.1.0" + "@onflow/util-actor" "^1.2.0" + "@onflow/util-address" "^1.1.0" + "@onflow/util-invariant" "^1.1.0" + "@onflow/util-logger" "^1.2.2" + "@onflow/util-template" "^1.1.0" + "@onflow/util-uid" "^1.1.0" + cross-fetch "^3.1.6" + +"@blocto/flow-sdk@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@blocto/flow-sdk/-/flow-sdk-1.2.2.tgz#a9918e42dcc0870f914af8caa23a760b033930d8" + integrity sha512-4frWTLTfyJmEgNyDWvsLs7ZuT41sSfyp8oulLHP4Li1wdPO9V2jYUWzMFISEyzovZedAwdX7sVmoD99tBPLTcg== + dependencies: + "@babel/runtime" "^7.18.6" + "@onflow/config" "^1.1.1" + "@onflow/rlp" "^1.1.0" + "@onflow/transport-http" "^1.7.1" + "@onflow/util-actor" "^1.2.0" + "@onflow/util-address" "^1.1.0" + "@onflow/util-invariant" "^1.1.0" + "@onflow/util-logger" "^1.2.1" + "@onflow/util-template" "^1.1.0" + deepmerge "^4.2.2" + sha3 "^2.1.4" + "@emotion/is-prop-valid@^0.8.2", "@emotion/is-prop-valid@^0.8.8": version "0.8.8" resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" @@ -198,6 +239,27 @@ resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== +"@es-joy/jsdoccomment@~0.37.0": + version "0.37.1" + resolved "https://registry.yarnpkg.com/@es-joy/jsdoccomment/-/jsdoccomment-0.37.1.tgz#fa32a41ba12097452693343e09ad4d26d157aedd" + integrity sha512-5vxWJ1gEkEF0yRd0O+uK6dHJf7adrxwQSX8PuRiPfFSAbNLnY0ZJfXaZucoz14Jj2N11xn2DnlEPwWRpYpvRjg== + dependencies: + comment-parser "1.3.1" + esquery "^1.5.0" + jsdoc-type-pratt-parser "~4.0.0" + +"@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.6.1": + version "4.6.2" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.6.2.tgz#1816b5f6948029c5eaacb0703b850ee0cb37d8f8" + integrity sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw== + "@eslint/eslintrc@^0.4.3": version "0.4.3" resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" @@ -213,6 +275,26 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" +"@eslint/eslintrc@^2.1.2": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.2.tgz#c6936b4b328c64496692f76944e755738be62396" + integrity sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@^8.47.0": + version "8.47.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.47.0.tgz#5478fdf443ff8158f9de171c704ae45308696c7d" + integrity sha512-P6omY1zv5MItm93kLM8s2vr1HICJH8v0dvddDhysbIuZ+vcjOHg5Zbkf1mTkcmi2JA9oBG2anOkRnW8WJTS8Og== + "@fortawesome/fontawesome-common-types@6.2.0": version "6.2.0" resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.2.0.tgz#76467a94aa888aeb22aafa43eb6ff889df3a5a7f" @@ -288,6 +370,15 @@ resolved "https://registry.yarnpkg.com/@heroicons/react/-/react-1.0.6.tgz#35dd26987228b39ef2316db3b1245c42eb19e324" integrity sha512-JJCXydOFWMDpCP4q13iEplA503MQO3xLoZiKum+955ZCtHINWnx26CUxVxxFQu/uLb4LW3ge15ZpzIkXKkJ8oQ== +"@humanwhocodes/config-array@^0.11.10": + version "0.11.10" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" + integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.5" + "@humanwhocodes/config-array@^0.5.0": version "0.5.0" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" @@ -297,11 +388,21 @@ debug "^4.1.1" minimatch "^3.0.4" +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + "@humanwhocodes/object-schema@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.0.tgz#87de7af9c231826fdd68ac7258f77c429e0e5fcf" integrity sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w== +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + "@napi-rs/triples@^1.0.3": version "1.0.3" resolved "https://registry.yarnpkg.com/@napi-rs/triples/-/triples-1.0.3.tgz#76d6d0c3f4d16013c61e45dfca5ff1e6c31ae53c" @@ -386,7 +487,7 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== -"@nodelib/fs.walk@^1.2.3": +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": version "1.2.8" resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== @@ -394,121 +495,188 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@onflow/config@^1.0.2", "@onflow/config@^1.0.3", "@onflow/config@^1.0.4": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@onflow/config/-/config-1.0.5.tgz#7fb476c64eb6932420323a5bdd70b1c63dea6973" - integrity sha512-r2IUyY4SJgAY6YCzKL0cOOertHETp9BgVfCjTIq236WAHr7aMS1oNyqcVPPR++zjDK8n64lRgrxlcYSZB/LrFg== +"@onflow/config@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@onflow/config/-/config-1.1.1.tgz#89606681c69791619aeff5f1d41a592337ce109e" + integrity sha512-PqQbZ6sbMp0/puFrq9THEjduLAYyaQM10fAhw9ztWYnYzTeE2h7/TL4RvNqtNrV/yOkGgaChC6Rz7mRxZ9aAGQ== dependencies: "@babel/runtime" "^7.18.6" - "@onflow/util-actor" "^1.1.2" + "@onflow/util-actor" "^1.2.0" + eslint "^8.34.0" + eslint-plugin-jsdoc "^40.0.0" -"@onflow/fcl@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@onflow/fcl/-/fcl-1.1.0.tgz#1ac91170d5b0195ad84591569a4cadcc4c1b64eb" - integrity sha512-J69YfE/qMmeN3eBUyxLgEPlcnLpzMMjpabInSg4Dl2g81M+dgDpujbrW5JUc1BB6qHiIPRi5VB4pO73mmLd/NA== +"@onflow/config@^1.1.2": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@onflow/config/-/config-1.2.1.tgz#35cc94183a12a7d88e42a1aa7c44e1c4515f96d6" + integrity sha512-V/yV5HcujnI6k1UjCwdh61a6Pun+gayPGR4EWZXqMe5lWQWDhKLZO0q6/sYbHF2kDQFjfBnG4ROyZE/NxYEs3A== + dependencies: + "@babel/runtime" "^7.18.6" + "@onflow/util-actor" "^1.3.1" + "@onflow/util-invariant" "^1.2.1" + "@onflow/util-logger" "^1.3.1" + eslint "^8.34.0" + eslint-plugin-jsdoc "^40.0.0" + +"@onflow/fcl@^1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@onflow/fcl/-/fcl-1.5.1.tgz#3012c1013f8456a6119405023cd3f44a7c0bbcf6" + integrity sha512-1jDcpWD9/f5qLZjC1TddyAZWjP7x9b75ZfL29fchdanu+WfwTeqvw9qL3AlgqI73VIMt7xU7mK4+sQWAnXAgrg== dependencies: - "@onflow/config" "^1.0.2" + "@babel/runtime" "^7.18.6" + "@onflow/config" "^1.1.1" "@onflow/interaction" "0.0.11" - "@onflow/rlp" "^1.0.1" - "@onflow/sdk" "^1.1.0" - "@onflow/types" "^1.0.2" - "@onflow/util-actor" "^1.1.0" - "@onflow/util-address" "^1.0.1" - "@onflow/util-invariant" "^1.0.1" - "@onflow/util-logger" "^1.1.0" - "@onflow/util-template" "^1.0.2" - "@onflow/util-uid" "^1.0.1" + "@onflow/rlp" "^1.1.0" + "@onflow/sdk" "^1.2.1" + "@onflow/types" "^1.1.0" + "@onflow/util-actor" "^1.2.0" + "@onflow/util-address" "^1.1.0" + "@onflow/util-invariant" "^1.1.0" + "@onflow/util-logger" "^1.2.1" + "@onflow/util-template" "^1.1.0" + "@onflow/util-uid" "^1.1.0" + cross-fetch "^3.1.6" "@onflow/interaction@0.0.11": version "0.0.11" resolved "https://registry.yarnpkg.com/@onflow/interaction/-/interaction-0.0.11.tgz#4db8f4304039e33d6fc3b14c38b392d724113374" integrity sha512-Xuq1Mmx6Wyba/F/L+QLQs0yJeQDsIDwy5SKk5vrCuVgIj0yD8k506g5L8ODrbM1LWll8i0tQsoOi0F85vNl5sA== -"@onflow/rlp@^1.0.1", "@onflow/rlp@^1.0.2": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@onflow/rlp/-/rlp-1.0.4.tgz#9db83571d7212294e79c8416ce269c919ae982ab" - integrity sha512-/4jSoh9eXPoN9iUCsbI+PAuTRJyYgT+XR4NdZYmxILRwOtIsSd2I9XatA4rrSzk9DJ0h8l9SmYx1y0XLnD+ohQ== +"@onflow/rlp@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@onflow/rlp/-/rlp-1.1.0.tgz#e60e0919687cb6539a067bee2d65a0e5e6f01e77" + integrity sha512-JJj4dZpKaWmCOXnado+D3RU5xYAXui9kHOmCVfdLReYHIsYBgxwHCDO/hDiQjrbmfLpiybbJKTaIldu+xkCU3Q== dependencies: "@babel/runtime" "^7.18.6" buffer "^6.0.3" -"@onflow/sdk@^1.1.0": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@onflow/sdk/-/sdk-1.1.2.tgz#3aa8b63395a44ac0be45d1081785ebaf64993ada" - integrity sha512-HNfQ6Q91FfFwd2g1wa/YHvmv6BYeXGONkEJyfOaoPRIbp3lG9W35HYX7Yvgtn7fvcQG+TRL8n386mzJ6Vn4dmA== +"@onflow/sdk@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@onflow/sdk/-/sdk-1.2.1.tgz#ab6d7135d3768eefde6644c03ed2bbb2ad69bcc8" + integrity sha512-83nMq/NJTq8nnjDKfVNrXLyvqiU0/VrSjVqIO1AhdwUWlmsinp+csCeA88+I96EdqFB6VDRqMhs8OBVPz7/WLA== dependencies: "@babel/runtime" "^7.18.6" - "@onflow/config" "^1.0.3" - "@onflow/rlp" "^1.0.2" - "@onflow/transport-http" "^1.5.0" - "@onflow/util-actor" "^1.1.1" - "@onflow/util-address" "^1.0.2" - "@onflow/util-invariant" "^1.0.2" - "@onflow/util-logger" "^1.1.1" - "@onflow/util-template" "^1.0.3" + "@onflow/config" "^1.1.1" + "@onflow/rlp" "^1.1.0" + "@onflow/transport-http" "^1.7.0" + "@onflow/util-actor" "^1.2.0" + "@onflow/util-address" "^1.1.0" + "@onflow/util-invariant" "^1.1.0" + "@onflow/util-logger" "^1.2.1" + "@onflow/util-template" "^1.1.0" deepmerge "^4.2.2" sha3 "^2.1.4" -"@onflow/transport-http@^1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@onflow/transport-http/-/transport-http-1.5.0.tgz#eda720107d9d073b849a924a1444bed9c579b41a" - integrity sha512-CGgfPC1kI+ssqDgFXxGgKHLVtu1tCGtyGJiS/fplyVun9RC7AwEp2KkjTP2dxRlto3HmntoaBkOw7z38UCxRZw== +"@onflow/transport-http@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@onflow/transport-http/-/transport-http-1.7.0.tgz#e1f70c0fee81eeb31d56778c40251c359a72c919" + integrity sha512-7QbihtUl4qrISyCoJHtmD/hkTsGiedoTROMRQOPPOLJsfYFejsOPCpDuMFBuLR07CCc1JZnIW3ynAOXzz9s+/A== + dependencies: + "@babel/runtime" "^7.18.6" + "@onflow/util-address" "^1.1.0" + "@onflow/util-invariant" "^1.1.0" + "@onflow/util-logger" "^1.2.1" + "@onflow/util-template" "^1.1.0" + abort-controller "^3.0.0" + cross-fetch "^3.1.6" + +"@onflow/transport-http@^1.7.1": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@onflow/transport-http/-/transport-http-1.9.0.tgz#d948fd2d753e7e1d5d05a123ea8d1a02457bc62f" + integrity sha512-rfbvc1b8U4M8CXfJNRqu2ZvP63ciKkP7K2eNXn55bVt3CSdL9jChC+Ad5zLnrKJ2nCPm2IlPlZqfAV4JK8uICg== + dependencies: + "@babel/runtime" "^7.18.6" + "@onflow/util-address" "^1.2.1" + "@onflow/util-invariant" "^1.2.1" + "@onflow/util-logger" "^1.3.1" + "@onflow/util-template" "^1.2.1" + abort-controller "^3.0.0" + cross-fetch "^3.1.6" + +"@onflow/types@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@onflow/types/-/types-1.1.0.tgz#825b5ff38fc5163a646f8f48a5f25910c03a4e85" + integrity sha512-UUd2ZAFqdd8BHW//uTg+YRlh3EIH9Na+UYJ9qXpt6y87qjW0Lf4Zkhn6H5IqvhIJsjK17QYnXLFpoXItD/+ToQ== dependencies: "@babel/runtime" "^7.18.6" - "@onflow/util-address" "^1.0.2" - "@onflow/util-invariant" "^1.0.2" - "@onflow/util-logger" "^1.1.1" - "@onflow/util-template" "^1.0.3" - node-fetch "^2.6.7" -"@onflow/types@^1.0.2", "@onflow/types@^1.0.3": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@onflow/types/-/types-1.0.5.tgz#beaaed646a21d2e4e95939932033dc9a5a0609e8" - integrity sha512-Uf6APOwgkxPwgonQ8JRrOB0KZ5eJpNBVXlEiZIv5ddzsfM6qd9p3csEE5YmuLhAooAcisG3ROTzw2hT/zUNGbw== +"@onflow/util-actor@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@onflow/util-actor/-/util-actor-1.2.0.tgz#bb244d1f64f332f6ad0893494c8272bd30f721ab" + integrity sha512-voyHXE3qYNC+P75vzv55pGDDwpxxWKWH0aToR/3g9Bq8nKGcGoszxaMJkVy+fKX1akfdT0yKr/GxXRkjCS9SBg== dependencies: "@babel/runtime" "^7.18.6" + queue-microtask "1.2.3" -"@onflow/util-actor@^1.1.0", "@onflow/util-actor@^1.1.1", "@onflow/util-actor@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@onflow/util-actor/-/util-actor-1.1.2.tgz#d7c4939a54fd2d4b60ee1a0748b98e071fb208ad" - integrity sha512-fsRGw5c2idlG5T0u48tzah1iE0OIc4WmgrNYN0gQ1NHX+Ue8iySoQdCIcdSxJCHOXwpHWe68fWTonCzbRJOssQ== +"@onflow/util-actor@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@onflow/util-actor/-/util-actor-1.3.1.tgz#f4c185c0c1310028269be0733beacd41500fee37" + integrity sha512-nKOWb6UtAhJWz7YSveMdOJqNlpNdommWhkNVGYLvy7R+nI7hePCyQ4H1pNUc4AHjCjrCmXr2QPe/yyxNsfEvdg== dependencies: "@babel/runtime" "^7.18.6" - queue-microtask "1.1.2" + queue-microtask "1.2.3" -"@onflow/util-address@^1.0.1", "@onflow/util-address@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@onflow/util-address/-/util-address-1.0.3.tgz#7ffe0ed1c5544a60660ef45033aca78ad093e475" - integrity sha512-w8DPYSvYm5h0hhZ0hZwiCwu9UgJBtIv2KyhDiH3TZG8srT+9GxtTPX4NzZtAVuxqWTNVlTGePD/Upxusiwnk6g== +"@onflow/util-address@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@onflow/util-address/-/util-address-1.1.0.tgz#5ee895669320f4d29e2fa2170ee256e7f52febb3" + integrity sha512-HhJOIfNaYAoeYuTNUe85jt4fqnJhFmSbYqyufiJBrplwd3eKmNsan0NYvVYO4U1ecu3KyuY4D9R/NtjGpHjMlA== dependencies: "@babel/runtime" "^7.18.6" -"@onflow/util-invariant@^1.0.1", "@onflow/util-invariant@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@onflow/util-invariant/-/util-invariant-1.0.3.tgz#5c45e3281982e20021799304fef480fae502fbb1" - integrity sha512-+Hk93W9JwACLkM5/oOILqI9L55o5QxETBV5Du/2dLgNbjXDElMmQzURFXx6fTmODTLZ6Ri+d1nvb7AxapYFe0Q== +"@onflow/util-address@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@onflow/util-address/-/util-address-1.2.1.tgz#9520ba70cbf3017e510c16d3980d1b94804dbf2a" + integrity sha512-+pf8AlOsJoGsW5cJYFhJE0IOQZY6GvsvULK1MXMcIF6/4ROjjKUDkZM+1frMjxf2j9hY58UEgciEIVdzS+bIZA== dependencies: "@babel/runtime" "^7.18.6" -"@onflow/util-logger@^1.1.0", "@onflow/util-logger@^1.1.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@onflow/util-logger/-/util-logger-1.1.2.tgz#ca19fb1f9846ec139ac8bf03f0df482bde245293" - integrity sha512-BcVDzKNGv/j3gqnq1lc0fpJV7LCHWPJyzYR588/keiY90mFHwLe8ahXYG1UYPu02KymlVqlInfISKWlNwk4aug== +"@onflow/util-invariant@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@onflow/util-invariant/-/util-invariant-1.1.0.tgz#9a3ef03f82b9777033d1b109dbad4caed08bc623" + integrity sha512-5uxweKl5tqeqB1QLzs3dWWLtpNo7H4PgcmgnRIcC2oItAkELcnVCybDdlfYjKB4n/dlg3rIym8cJQE2tBeOpZQ== dependencies: "@babel/runtime" "^7.18.6" - "@onflow/config" "^1.0.4" -"@onflow/util-template@^1.0.2", "@onflow/util-template@^1.0.3": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@onflow/util-template/-/util-template-1.0.4.tgz#5affdb46713b5aa4c64d133788a996f02bc56c37" - integrity sha512-syTJzhFn+CaW/FAqVLJJ3Oq9pTuxS5Wk0+g9AkSKWJ8PCY+FLr7UC2mGr/5pO//L13Elz7cv/djXVxNA1ULQmw== +"@onflow/util-invariant@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@onflow/util-invariant/-/util-invariant-1.2.1.tgz#ef286ad3eaec651927484d9f597c79c2221ae91b" + integrity sha512-Xb0PQElfFjKiFFHVBZ3Fcu2BwTzF4+Gy5aOHVlJQt+IL+5ObEAxjDnFdFzl/IeRK9oVh/5R6wu0CiI3UYCw6Xg== dependencies: "@babel/runtime" "^7.18.6" -"@onflow/util-uid@^1.0.1": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@onflow/util-uid/-/util-uid-1.0.3.tgz#8c1035106fcb0a6cf04728e3412ed3fecaf760fc" - integrity sha512-hBdfV+0BSDphcvLvL8KFivyV5ZhpVyRcrOn0fuSD4is/hN5d1mLFBev9gur9gdmQUUwgFt0v+aA/Tc/7mRDctQ== +"@onflow/util-logger@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@onflow/util-logger/-/util-logger-1.2.1.tgz#2ed6f8dcd9041c51b00d943f745766c2fe8fe2ca" + integrity sha512-L8a6S1JakP0HNFI3isddoIRX/MOF+qEMZFsPV3Jbp0g0vIJpyMv7SOeh9DiupEbv0hZS0rH2EApDWGO0jNd0Eg== + dependencies: + "@babel/runtime" "^7.18.6" + "@onflow/config" "^1.1.1" + +"@onflow/util-logger@^1.2.2", "@onflow/util-logger@^1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@onflow/util-logger/-/util-logger-1.3.1.tgz#32239a93eb889df9d0191832f11c7a90eeb14240" + integrity sha512-LKsesUsrVFzaXO3K99Ifm8i+T1ofQNWixxiAei9WhbM2GlCBuaVj6OJ6ZF1eCnQOdwNGudYmxAx5mkFqHrOEEw== + dependencies: + "@babel/runtime" "^7.18.6" + +"@onflow/util-template@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@onflow/util-template/-/util-template-1.1.0.tgz#e3884bd31e0b95a86a18879f25d09b0244d22805" + integrity sha512-gGqJJH5OTPPRmHk6YxMw4t5Ecy7iHnj00ZlCE7lnlOnpGUNdHrNNfoeE//hO8TBGNNVpOkEQERWiLDph+/oIxg== + dependencies: + "@babel/runtime" "^7.18.6" + +"@onflow/util-template@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@onflow/util-template/-/util-template-1.2.1.tgz#764f987429402f84a090b9610799c4f8b4664039" + integrity sha512-FVNS+ixYxC4+pBCc2Y20+GqCqeJP8KxMJy8VxcJoKs7hl6z1w8WV7yy9ITOGH1PUsI5ykDWSLTPNqolJaZW7Fg== + dependencies: + "@babel/runtime" "^7.18.6" + "@onflow/util-logger" "^1.3.1" + +"@onflow/util-uid@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@onflow/util-uid/-/util-uid-1.1.0.tgz#551f448dea7e9178908ae45d326369a7c3f74c71" + integrity sha512-HmWfKCOXoz1/TIu7fRx6iR7Nfhq6q5Tmn4YWc868SIfFeWv/inpvVJyrKX0nORf87csSnRSqdDzrJGBowgcXVA== dependencies: "@babel/runtime" "^7.18.6" @@ -636,7 +804,14 @@ "@typescript-eslint/types" "4.33.0" eslint-visitor-keys "^2.0.0" -acorn-jsx@^5.3.1: +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +acorn-jsx@^5.3.1, acorn-jsx@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== @@ -660,6 +835,11 @@ acorn@^7.0.0, acorn@^7.4.0: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== +acorn@^8.9.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + ajv@^6.10.0, ajv@^6.12.4: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" @@ -729,6 +909,11 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + aria-query@^4.2.2: version "4.2.2" resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" @@ -1169,6 +1354,11 @@ colorette@^1.2.2: resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40" integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g== +comment-parser@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/comment-parser/-/comment-parser-1.3.1.tgz#3d7ea3adaf9345594aedee6563f422348f165c1b" + integrity sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA== + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -1242,6 +1432,13 @@ create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: safe-buffer "^5.0.1" sha.js "^2.4.8" +cross-fetch@^3.1.6: + version "3.1.8" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" + integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg== + dependencies: + node-fetch "^2.6.12" + cross-spawn@^7.0.2: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" @@ -1342,6 +1539,13 @@ debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: dependencies: ms "2.1.2" +debug@^4.3.2, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" @@ -1613,6 +1817,19 @@ eslint-plugin-import@^2.22.1: resolve "^1.20.0" tsconfig-paths "^3.11.0" +eslint-plugin-jsdoc@^40.0.0: + version "40.3.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-40.3.0.tgz#75a91ab71c41bb797db05a32d9528ce3ab613e90" + integrity sha512-EhCqpzRkxoT2DUB4AnrU0ggBYvTh3bWrLZzQTupq6vSVE6XzNwJVKsOHa41GCoevnsWMBNmoDVjXWGqckjuG1g== + dependencies: + "@es-joy/jsdoccomment" "~0.37.0" + comment-parser "1.3.1" + debug "^4.3.4" + escape-string-regexp "^4.0.0" + esquery "^1.5.0" + semver "^7.3.8" + spdx-expression-parse "^3.0.1" + eslint-plugin-jsx-a11y@^6.4.1: version "6.4.1" resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz#a2d84caa49756942f42f1ffab9002436391718fd" @@ -1663,6 +1880,14 @@ eslint-scope@^5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" +eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + eslint-utils@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" @@ -1680,6 +1905,11 @@ eslint-visitor-keys@^2.0.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + eslint@7.31.0: version "7.31.0" resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.31.0.tgz#f972b539424bf2604907a970860732c5d99d3aca" @@ -1726,6 +1956,49 @@ eslint@7.31.0: text-table "^0.2.0" v8-compile-cache "^2.0.3" +eslint@^8.34.0: + version "8.47.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.47.0.tgz#c95f9b935463fb4fad7005e626c7621052e90806" + integrity sha512-spUQWrdPt+pRVP1TTJLmfRNJJHHZryFmptzcafwSvHsceV81djHOdnEeDmkdotZyLNjDhrOasNK8nikkoG1O8Q== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.2" + "@eslint/js" "^8.47.0" + "@humanwhocodes/config-array" "^0.11.10" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + espree@^7.3.0, espree@^7.3.1: version "7.3.1" resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" @@ -1735,6 +2008,15 @@ espree@^7.3.0, espree@^7.3.1: acorn-jsx "^5.3.1" eslint-visitor-keys "^1.3.0" +espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== + dependencies: + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + esprima@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" @@ -1747,6 +2029,13 @@ esquery@^1.4.0: dependencies: estraverse "^5.1.0" +esquery@^1.4.2, esquery@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + esrecurse@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" @@ -1774,6 +2063,11 @@ etag@1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + events@^3.0.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" @@ -1869,6 +2163,14 @@ find-up@^4.0.0: locate-path "^5.0.0" path-exists "^4.0.0" +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + flat-cache@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" @@ -2004,6 +2306,13 @@ globals@^11.1.0: resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== +globals@^13.19.0: + version "13.21.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.21.0.tgz#163aae12f34ef502f5153cfbdd3600f36c63c571" + integrity sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg== + dependencies: + type-fest "^0.20.2" + globals@^13.6.0, globals@^13.9.0: version "13.11.0" resolved "https://registry.yarnpkg.com/globals/-/globals-13.11.0.tgz#40ef678da117fe7bd2e28f1fab24951bd0255be7" @@ -2028,6 +2337,11 @@ graceful-fs@^4.1.2: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + has-bigints@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" @@ -2155,6 +2469,11 @@ ignore@^5.1.4: resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== +ignore@^5.2.0: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + image-size@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/image-size/-/image-size-1.0.0.tgz#58b31fe4743b1cec0a0ac26f5c914d3c5b2f0750" @@ -2317,6 +2636,11 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" @@ -2394,6 +2718,18 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsdoc-type-pratt-parser@~4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz#136f0571a99c184d84ec84662c45c29ceff71114" + integrity sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ== + jsesc@^2.5.1: version "2.5.2" resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" @@ -2493,6 +2829,13 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + lodash.clonedeep@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" @@ -2591,6 +2934,13 @@ minimatch@^3.0.4: dependencies: brace-expansion "^1.1.7" +minimatch@^3.0.5, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + minimist@^1.2.0: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" @@ -2709,10 +3059,10 @@ node-fetch@2.6.1: resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== -node-fetch@^2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== +node-fetch@^2.6.12: + version "2.6.12" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.12.tgz#02eb8e22074018e3d5a83016649d04df0e348fba" + integrity sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g== dependencies: whatwg-url "^5.0.0" @@ -2874,12 +3224,24 @@ optionator@^0.9.1: type-check "^0.4.0" word-wrap "^1.2.3" +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + os-browserify@0.3.0, os-browserify@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= -p-limit@3.1.0: +p-limit@3.1.0, p-limit@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== @@ -2914,6 +3276,13 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + p-try@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" @@ -3205,12 +3574,7 @@ querystring@^0.2.0: resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd" integrity sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg== -queue-microtask@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.1.2.tgz#139bf8186db0c545017ec66c2664ac646d5c571e" - integrity sha512-F9wwNePtXrzZenAB3ax0Y8TSKGvuB7Qw16J30hspEUTbfUM+H827XyN3rlpwhVmtm5wuZtbKIHjOnwDn7MUxWQ== - -queue-microtask@^1.2.2: +queue-microtask@1.2.3, queue-microtask@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== @@ -3510,6 +3874,13 @@ semver@^7.2.1, semver@^7.3.5: dependencies: lru-cache "^6.0.0" +semver@^7.3.8: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + setimmediate@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" @@ -3620,7 +3991,7 @@ spdx-exceptions@^2.1.0: resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== -spdx-expression-parse@^3.0.0: +spdx-expression-parse@^3.0.0, spdx-expression-parse@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==