diff --git a/app/pages/home.tsx b/app/pages/home.tsx new file mode 100644 index 000000000..87f0faf2f --- /dev/null +++ b/app/pages/home.tsx @@ -0,0 +1,7 @@ +import Home from '@zoolabs/core/pages/home' + +export default function Home() { + return ( + + ) +} diff --git a/app/pages/home/AnimalFamilySection.tsx b/app/pages/home/AnimalFamilySection.tsx deleted file mode 100644 index 52bfe8b00..000000000 --- a/app/pages/home/AnimalFamilySection.tsx +++ /dev/null @@ -1,247 +0,0 @@ -import React from 'react' -import Image from 'next/image' -import Link from 'next/link' - -import { useGif } from '../../context/GifContext' -//import BabylonAnim from "components/Babylon"; - -import dynamic from 'next/dynamic' -const ModelViewer = dynamic(() => import('../../components/ModelViewer'), { - ssr: false, -}) - -const animalFamilyData = [ - { - id: '1', - cameraZ: 100, - upLimit: 120, - lowLimit: 40, - glb: '/models/ELEPHANT_ADULT.glb', - image: 'https://res.cloudinary.com/diu8hjwwe/image/upload/v1644332888/zoo/images/sumatran-elephant_s3nww5.png', - gif: 'https://res.cloudinary.com/diu8hjwwe/video/upload/v1644330488/zoo/sumatran-elephant_bowsev.mov', - name: 'Sumatran Elephant', - slug: 'sumatran-elephant', - scientificName: ' Elephas Maximus Sumatranus', - description: `Sumatran elephants feed on a variety of plants and deposit seeds - wherever they go, contributing to a healthy forest ecosystem. - They also share their lush forest habitat with other endangered - species.`, - status: 'Critically Endangered', - population: '2,400 - 2,800', - size: '6.6 - 10.5 Feet', - habitat: 'Tropical Forests', - images: [ - 'https://res.cloudinary.com/diu8hjwwe/image/upload/v1644332888/zoo/images/sumatran-elephant_s3nww5.png', - 'https://res.cloudinary.com/diu8hjwwe/image/upload/v1644332888/zoo/images/sumatran-elephant_s3nww5.png', - 'https://res.cloudinary.com/diu8hjwwe/image/upload/v1644332888/zoo/images/sumatran-elephant_s3nww5.png', - ], - }, - { - id: '2', - cameraZ: 80, - upLimit: 120, - lowLimit: 40, - glb: '/models/RHINO_ADULT.glb', - image: 'https://res.cloudinary.com/diu8hjwwe/image/upload/v1644332905/zoo/images/javan-rhino_aoxijc.png', - gif: 'https://res.cloudinary.com/diu8hjwwe/video/upload/v1644330489/zoo/javan-rhino_nkm1sw.mov', - name: 'Javan Rhino', - slug: 'javan-rhino', - scientificName: 'Rhinoceros Sondaicus', - description: `Once the most widespread of Asian rhinoceroses, the Javan - rhinoceros ranged from the islands of Java and Sumatra, - throughout Southeast Asia, and into India and China. The species - is critically endangered, with only one known population in the - wild, and no individuals in captivity. It is possibly the rarest - large mammal on Earth.`, - status: 'Critically Endangered', - population: '18', - size: '6.6 - 10.5 Feet', - habitat: 'Forests', - images: [ - 'https://res.cloudinary.com/diu8hjwwe/image/upload/v1644332905/zoo/images/javan-rhino_aoxijc.png', - 'https://res.cloudinary.com/diu8hjwwe/image/upload/v1644332905/zoo/images/javan-rhino_aoxijc.png', - 'https://res.cloudinary.com/diu8hjwwe/image/upload/v1644332905/zoo/images/javan-rhino_aoxijc.png', - ], - }, - { - id: '3', - cameraZ: 50, - upLimit: 80, - lowLimit: 35, - glb: '/models/TIGER_ADULT.glb', - image: 'https://res.cloudinary.com/diu8hjwwe/image/upload/v1644332724/zoo/images/siberian-tiger_djt67i.png', - gif: 'https://res.cloudinary.com/diu8hjwwe/video/upload/v1644330487/zoo/siberian-tiger_gn44b5.mov', - name: 'Siberian Tiger', - slug: 'siberian-tiger', - scientificName: 'Panthera Tigris Altaica', - description: `The Siberian tiger is a tiger from a specific population of the - Panthera tigris tigris subspecies native to the Russian Far - East, Northeast China. It once ranged throughout the Korean - Peninsula, north China, and eastern Mongolia. The population - currently inhabits mainly the Sikhote-Alin mountain region in - southwest Primorye Province in East Russia.`, - status: 'endangered', - population: '2,400 - 2,800', - size: '6.6 - 10.5 Feet', - habitat: 'Tropical Forests', - images: [ - 'https://res.cloudinary.com/diu8hjwwe/image/upload/v1644332724/zoo/images/siberian-tiger_djt67i.png', - 'https://res.cloudinary.com/diu8hjwwe/image/upload/v1644332724/zoo/images/siberian-tiger_djt67i.png', - 'https://res.cloudinary.com/diu8hjwwe/image/upload/v1644332724/zoo/images/siberian-tiger_djt67i.png', - ], - }, -] - -const AnimalFamilySection = () => { - const { state } = useGif() - const { gifMode } = state - - return ( -
-
-

Our Animal Family

- {animalFamilyData.map((data) => { - return ( -
-
-
-
- {gifMode === 'gif' ? ( -
-
- -
-
- ) : ( -
- -
- )} -
-
-
-

{data.name}

- - Coming Soon - -
-
-

{data.scientificName}

-

{data.description}

- - Learn more - -
-
-
- ) - })} - -
- - See the entire First Generation Animal NFT series - -
-
-
- ) -} - -export default AnimalFamilySection - -{ - /* Another section */ -} -{ - /*
-
-
- -
-
-

Javan Rhino

- - Buy NFT - -
-
-

Rhinoceros Sondaicus

-

- Once the most widespread of Asian rhinoceroses, the Javan - rhinoceros ranged from the islands of Java and Sumatra, - throughout Southeast Asia, and into India and China. The species - is critically endangered, with only one known population in the - wild, and no individuals in captivity. It is possibly the rarest - large mammal on Earth. -

- - Learn more - -
-
-
*/ -} -{ - /* Another section */ -} -{ - /*
-
-
- -
-
-

Siberian Tiger

- - Buy NFT - -
-
-

Siberian Tiger

-

- The Siberian tiger is a tiger from a specific population of the - Panthera tigris tigris subspecies native to the Russian Far - East, Northeast China. It once ranged throughout the Korean - Peninsula, north China, and eastern Mongolia. The population - currently inhabits mainly the Sikhote-Alin mountain region in - southwest Primorye Province in East Russia. -

- - Learn more - -
-
-
*/ -} diff --git a/app/pages/home/BuyZooSection.tsx b/app/pages/home/BuyZooSection.tsx deleted file mode 100644 index 2806b0ae5..000000000 --- a/app/pages/home/BuyZooSection.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react' -import { handleFunds } from '../../utils/handleFunds' -import { useWeb3React } from '@web3-react/core' -import { useBuyZoo } from '../../state/zoo/hooks' - -const BuyZooSection = () => { - const { chainId } = useWeb3React() - const buyZoo = useBuyZoo() - - return ( -
-
-

Fully Transparent Ecosystem

-

- Each animal NFT uses blockchain technology to establish a verified and public proof of ownership. This - establishes credibility for each NFT and its unchangeable nature. -

- -
-
- ) -} - -export default BuyZooSection diff --git a/app/pages/home/FaqSection.tsx b/app/pages/home/FaqSection.tsx deleted file mode 100644 index 50865add7..000000000 --- a/app/pages/home/FaqSection.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import React, { useEffect } from 'react' -import Link from 'next/link' -// animation -import { fadeInOnScroll } from '../../animation' - -const FaqSection = () => { - // const faqsRef = React.useRef(); - - // useEffect(() => { - // fadeInOnScroll(faqsRef.current); - // }, []); - - return ( -
-
-

Game FAQ

-
-
-

What is ZOO?

-

- ZOO is a Liquidity Protocol that exists to bridge tokens and NFTs at the intersection of Defi and gaming. - Each of our NFTs (animal or egg) yield our native currency, $ZOO. Each NFT is collateralized by $ZOO, - which appreciates over time based on rarity, age and by playing our game.{' '} -

-
- -
-

What are the Key Features in ZOO?

-

- {`Our key features include: growing, - breeding. In the near future we will - also launch the ZOO AR App which will enable you to - play with your animals in AR. With the app you will be able - to see your NFT and pet, play, shake hands and more.`} -

-
- -
-

What is the $ZOO token?

-

- The $ZOO token is the native currency in the game. It allows token holders to play, invest, use our NFT - marketplace and be part of the game. -

-
- -
-

How Do I Get Started?

-

- Players will be able to get access to the game through our DApp as well as ZOO {`Labs'`} official website. -

-
- {/* flex flex-col mb-12 text-left lg:basis-1/2, pl-4 mb-4 text-xl font-bold text-left text-green lg:text-2xl lg:pl-0, max-w-sm px-4 mx-auto text-white list-disc lg:mx-0*/} -
-

How do I buy $ZOO?

-
  • - - Click here - -
  • -
    - -
    -

    Still have questions?

    -

    - If you are having difficulty, please{' '} - - join our Discord server - {' '} - and post in the #new-player-help channel and our community will be happy to help! -

    -

    - In addition, a complete list of guides can be found{' '} - - here - - . -

    -
    -
    -
    - - - See more - - -
    -
    -
    - ) -} - -export default FaqSection diff --git a/app/pages/home/GetStartedSection.tsx b/app/pages/home/GetStartedSection.tsx deleted file mode 100644 index 00bd0bcdb..000000000 --- a/app/pages/home/GetStartedSection.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import React, { useEffect } from "react"; -import Image from "next/image"; - -// animation -import { fadeInFromLeft, fadeInFromRight } from "../../animation"; - -const GetStartedSection = () => { - // const getStartedContentRef = React.useRef(); - // const getStartedImageRef = React.useRef(); - - // useEffect(() => { - // fadeInFromLeft(getStartedContentRef.current); - // fadeInFromRight(getStartedImageRef.current); - // }, []); - return ( -
    -
    -
    -

    - Make yield and do good. -

    -

    - ZOO is a DeFi game that allows players to collect NFT animals - representative of endangered species in the real world. Based on - your game interactions users make more or less $ZOO. -

    - - - Get Started - -
    -
    - -
    -
    -
    - ); -}; - -export default GetStartedSection; diff --git a/app/pages/home/HeroSection.tsx b/app/pages/home/HeroSection.tsx deleted file mode 100644 index f2d15dd46..000000000 --- a/app/pages/home/HeroSection.tsx +++ /dev/null @@ -1,88 +0,0 @@ -import React, { useState, useEffect, useRef } from 'react' -import Image from 'next/image' - -// animation -import { fadeInFromLeft, fadeInOnScroll } from '../../animation' -import Tiger from '../../../public/gifs/siberian-tiger.gif' - -import { useDispatch, useSelector } from 'react-redux' -import { useBuyZoo } from '../../state/zoo/hooks' -import { useWeb3React } from '@web3-react/core' -// import { useFaucet } from 'hooks' -import { getZooBalance } from '../../state/zoo/actions' -import { handleFunds } from '../../utils/handleFunds' -import { useGif } from '../../context/GifContext' -import { createRequire } from 'module' - -const HeroSection = ({ animal3d }) => { - const { account, library, chainId } = useWeb3React() - const buyZoo = useBuyZoo() - // const faucet = useFaucet() - - // const heroContent = useRef(); - // const heroImage = useRef(); - - const { state } = useGif() - const { gifMode } = state - - // useEffect(() => { - // fadeInFromLeft(heroContent.current); - // fadeInOnScroll(heroImage.current); - // }, []); - - return ( -
    -
    -
    -

    Nfts made Fun.

    - -

    Exotic animals for everyone.

    -

    - Pet, play, feed, grow, and breed your very own animal NFT’s in our Sims-like metaverse to increase their - value and earn greater rewards, all while contributing to saving endangered animals. -

    -
    -
    handleFunds(chainId, buyZoo)} - className="px-5 py-3 text-sm font-semibold text-white rounded-full bg-gradient-to-b from-purple to-blue md:text-base md:px-6 md:py-4 lg:px-10 hover:cursor-pointer" - > - Buy $ZOO -
    - - Learn More - -
    -
    -
    -
    {animal3d}
    - {/* {gifMode === "gif" ? ( - - ) : ( - leopard - )} */} -
    -
    -
    - ) -} - -export default HeroSection diff --git a/app/pages/home/JoinZooSection.tsx b/app/pages/home/JoinZooSection.tsx deleted file mode 100644 index 1f6fdd415..000000000 --- a/app/pages/home/JoinZooSection.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import React from 'react' -import Image from 'next/image' -import InstagramIcon from '../../components/Icons/instagram-icon' - -import TwitterIcon from '../../components/Icons/twitter-icon' - -const JoinZooSection = () => { - return ( -
    -
    -

    Join the ZOO family!

    -

    Follow us on social media

    -
    - - - - - - - - - - - - - - {' '} - -
    - - {/*
    -
    - - -
    -
    */} -
    -
    - ) -} - -export default JoinZooSection diff --git a/app/pages/home/MarketPlaceSection.tsx b/app/pages/home/MarketPlaceSection.tsx deleted file mode 100644 index d740683b4..000000000 --- a/app/pages/home/MarketPlaceSection.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import React, { useRef, useEffect } from 'react' -import Image from 'next/image' -import Link from 'next/link' -import { useActiveWeb3React } from 'hooks' -import Web3Status from '../../components/Web3Status' - -// animation -import { fadeInOnScroll } from '../../animation' -import { i18n } from '@lingui/core' -import { t } from '@lingui/macro' - -const MarketPlaceSection = () => { - const { account, chainId, library } = useActiveWeb3React() - - // const marketRef = useRef(); - - // useEffect(() => { - // fadeInOnScroll(marketRef.current); - // }, []); - - return ( -
    -
    -
    - -
    -
    -

    - Buy, list and bid on our NFT marketplace. -

    -
    - - - Coming Soon - - - {/* {!account ? ( - - - - ) : ( - - Marketplace - - )} */} -
    -
    -
    -
    - ) -} - -export default MarketPlaceSection diff --git a/app/pages/home/OpportunitySection.tsx b/app/pages/home/OpportunitySection.tsx deleted file mode 100644 index a7bd51f7a..000000000 --- a/app/pages/home/OpportunitySection.tsx +++ /dev/null @@ -1,146 +0,0 @@ -import React, { useState, useEffect } from 'react' -import Image from 'next/image' - -// animation -// import { fadeInOnScroll } from "animation"; - -import EndangeredSpecies from '../../components/EndangeredSpecies' - -import { useDispatch } from 'react-redux' -import { useBuyZoo } from '../../state/zoo/hooks' -import { useWeb3React } from '@web3-react/core' -// import { useFaucet } from 'hooks' -import { getZooBalance } from '../../state/zoo/actions' -import { handleFunds } from '../../utils/handleFunds' - -const OpportunitySection = () => { - const { account, library, chainId } = useWeb3React() - const buyZoo = useBuyZoo() - const [fetching, setFetching] = useState(false) - const [confirmation, setConfirmation] = useState(false) - const [rejection, setRejection] = useState(false) - // const faucet = useFaucet() - const dispatch = useDispatch() - const [stage, setStage] = useState('') - const [hovered, setHovered] = useState(false) - - // const sectionRef = React.useRef(); - - // useEffect(() => { - // fadeInOnScroll(sectionRef.current); - // }, []); - - const displayContent = (desc: string) => { - setStage(desc) - handleHover() - } - - const handleHover = () => { - setHovered(!hovered) - } - const style = { - animationPlayState: 'paused', - } - - return ( -
    -
    -

    - Endless Yield Opportunity -

    - -
    - - -
    -
    -
    {stage &&

    {stage}

    }
    -
    displayContent('Your NFT Egg to reveal the animal within and learn about it')} - onMouseOut={() => displayContent('')} - > - -
    -
    displayContent('Your animal $ZOO to increase the value of your animal NFT.')} - onMouseOut={() => displayContent('')} - // style={hovered ? style : undefined} - > - -
    -
    - displayContent('Your fully mature animal to mint new Egg NFT’s. Breed the animals up to 6x.') - } - onMouseOut={() => displayContent('')} - // style={hovered ? style : undefined} - > - -
    -
    - displayContent('Your animal and watch it transition through its different stages of maturity.') - } - onMouseOut={() => displayContent('')} - // style={hovered ? style : undefined} - > - -
    -
    -
    -
    - -
    -

    - Fully Transparent Ecosystem -

    -

    - Each animal NFT uses blockchain technology to establish a verified and public proof of ownership. This - establishes credibility for each NFT and its unchangeable nature. -

    -
    handleFunds(chainId, buyZoo)} - className="border border-green text-green font-semibold text-sm md:text-base px-8 py-3 md:px-6 lg:px-16 rounded-full hover:cursor-pointer" - > - Buy $ZOO -
    -
    -
    -
    - ) -} - -export default OpportunitySection diff --git a/app/pages/home/PartnersSection.tsx b/app/pages/home/PartnersSection.tsx deleted file mode 100644 index 565db6490..000000000 --- a/app/pages/home/PartnersSection.tsx +++ /dev/null @@ -1,89 +0,0 @@ -import React from "react"; -import Image from "next/image"; -import Link from "next/link"; - -const PartnersSection = () => { - return ( -
    -
    -
    - - - -
    - - - -
    -
    -
    - - - -
    -
    - - - - - - -
    - - - - - - -
    -
    - ); -}; - -export default PartnersSection; diff --git a/app/pages/home/PopularNftsSection.tsx b/app/pages/home/PopularNftsSection.tsx deleted file mode 100644 index 7e58f30ae..000000000 --- a/app/pages/home/PopularNftsSection.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import React, { useEffect } from 'react' -import Image from 'next/image' -import NftCard from '../../components/NftCard' - -// animation -import { fadeInOnScroll, fadeInOnScrollAndStagger } from '../../animation' - -const PopularNftsSection = () => { - // const popularRef = React.useRef(); - // const nftsRef = React.useRef(); - - // useEffect(() => { - // fadeInOnScroll(popularRef.current); - // }, []); - - // useEffect(() => { - // fadeInOnScrollAndStagger('.PopularNft_nft', nftsRef.current); - // }, []); - - return ( -
    -
    -
    -

    Popular NFTs

    -

    - Browse and bid on the hottest ZOO NFTs on the marketplace.{' '} -

    -
    -
    - } - name="Girrafe (1589)" - price="500k" - address="0x070...09cb" - days="3" - highestBid="1M" - yields="200" - /> - } - name="Siberian Tiger (1589)" - price="500k" - address="0x070...09cb" - days="3" - highestBid="1M" - yields="200" - /> - } - name="Javan Rhino (1589)" - price="500k" - address="0x070...09cb" - days="3" - highestBid="1M" - yields="200" - /> - } - name="Amur Leopard (1589)" - price="500k" - address="0x070...09cb" - days="3" - highestBid="1M" - yields="200" - /> -
    -
    -
    - ) -} - -export default PopularNftsSection diff --git a/app/pages/home/ZooNewsSection.tsx b/app/pages/home/ZooNewsSection.tsx deleted file mode 100644 index e3eae1cdc..000000000 --- a/app/pages/home/ZooNewsSection.tsx +++ /dev/null @@ -1,67 +0,0 @@ -import React, { useEffect } from "react"; -import Image from "next/image"; - -// animation -import { fadeInOnScroll } from "../../animation"; - -const ZooNewsSection = () => { - // const zooRef = React.useRef(); - // useEffect(() => { - // fadeInOnScroll(zooRef.current); - // }, []); - return ( -
    -
    -
    -

    - ZOO News -

    -

    - Learn all about Zoo, our cutting-edge 3D/AR-enabled NFTs & the - critically-endangered animals they are inspired by, how we are - contributing to conservation efforts, and browse through our helpful - educational guides & resources -

    -
    -
    -
    - -
    -
    -
    -

    - New -

    -

    - Introducing - Zoo Labs: Wildlife Conservation Powered by DeFi -

    -

    - Zoo Labs, a new NFT-based P2E (Play-to-Earn) game that utilizes - the $ZOO token in its ecosystem, is launching in Q1 of 2022 with - the mission to aid... -

    - - Blog - -
    -
    -
    -
    -
    - ); -}; - -// px-4 py-4 -mt-4 lg:py-0 bg-black100 rounded-b-2xl lg:rounded-2xl lg:-ml-1 - -export default ZooNewsSection; diff --git a/core/pages/home/HeroSection.tsx b/core/pages/home/HeroSection.tsx index f2d15dd46..644cab991 100644 --- a/core/pages/home/HeroSection.tsx +++ b/core/pages/home/HeroSection.tsx @@ -7,7 +7,7 @@ import Tiger from '../../../public/gifs/siberian-tiger.gif' import { useDispatch, useSelector } from 'react-redux' import { useBuyZoo } from '../../state/zoo/hooks' -import { useWeb3React } from '@web3-react/core' +import { useActiveWeb3React } from '../../hooks/useActiveWeb3React' // import { useFaucet } from 'hooks' import { getZooBalance } from '../../state/zoo/actions' import { handleFunds } from '../../utils/handleFunds' @@ -15,7 +15,7 @@ import { useGif } from '../../context/GifContext' import { createRequire } from 'module' const HeroSection = ({ animal3d }) => { - const { account, library, chainId } = useWeb3React() + const { account, library, chainId } = useActiveWeb3React() const buyZoo = useBuyZoo() // const faucet = useFaucet() diff --git a/core/pages/home/MarketPlaceSection.tsx b/core/pages/home/MarketPlaceSection.tsx index d740683b4..2de779726 100644 --- a/core/pages/home/MarketPlaceSection.tsx +++ b/core/pages/home/MarketPlaceSection.tsx @@ -2,7 +2,6 @@ import React, { useRef, useEffect } from 'react' import Image from 'next/image' import Link from 'next/link' import { useActiveWeb3React } from 'hooks' -import Web3Status from '../../components/Web3Status' // animation import { fadeInOnScroll } from '../../animation' @@ -36,23 +35,6 @@ const MarketPlaceSection = () => { Coming Soon - {/* {!account ? ( - - - - ) : ( - - Marketplace - - )} */} diff --git a/core/pages/home/OpportunitySection.tsx b/core/pages/home/OpportunitySection.tsx index a7bd51f7a..7f543a87a 100644 --- a/core/pages/home/OpportunitySection.tsx +++ b/core/pages/home/OpportunitySection.tsx @@ -8,13 +8,13 @@ import EndangeredSpecies from '../../components/EndangeredSpecies' import { useDispatch } from 'react-redux' import { useBuyZoo } from '../../state/zoo/hooks' -import { useWeb3React } from '@web3-react/core' +import { useActiveWeb3React } from '../../hooks/useActiveWeb3React' // import { useFaucet } from 'hooks' import { getZooBalance } from '../../state/zoo/actions' import { handleFunds } from '../../utils/handleFunds' const OpportunitySection = () => { - const { account, library, chainId } = useWeb3React() + const { account, library, chainId } = useActiveWeb3React() const buyZoo = useBuyZoo() const [fetching, setFetching] = useState(false) const [confirmation, setConfirmation] = useState(false) diff --git a/app/pages/home/index.tsx b/core/pages/home/index.tsx similarity index 92% rename from app/pages/home/index.tsx rename to core/pages/home/index.tsx index bf9178b3b..4027c439e 100644 --- a/app/pages/home/index.tsx +++ b/core/pages/home/index.tsx @@ -1,7 +1,7 @@ import _ from 'lodash' //import ZooBabyAnim from "../../components/Babylon"; import dynamic from 'next/dynamic' -const ModelViewer = dynamic(() => import('@zoolabs/core/components/ModelViewer'), { +const ModelViewer = dynamic(() => import('../../components/ModelViewer'), { ssr: false, }) @@ -17,7 +17,7 @@ const ZooNewsSection = dynamic(() => import('./ZooNewsSection')) const AnimalFamilySection = dynamic(() => import('./AnimalFamilySection')) const JoinZooSection = dynamic(() => import('./JoinZooSection')) const FaqSection = dynamic(() => import('./FaqSection')) -import { useTokenTypes } from '@zoolabs/core/zoo/state' +import { useTokenTypes } from '../../zoo/state' const BASE_NFT_URL = 'https://db.zoolabs.io'