Compare commits

...

22 Commits
main ... atlas

Author SHA1 Message Date
Austin Chen
0f5401f82d Stop hardcoding quick bet size 2022-06-15 09:05:26 -07:00
Austin Chen
d010ec17c0 Increase ante to 25 2022-06-15 07:15:22 -07:00
Austin Chen
f70308762f Reduce quick bet size for Atlas 2022-06-14 03:48:15 -07:00
Austin Chen
bd3cd5bfa3 Fix import 2022-06-14 03:45:06 -07:00
Austin Chen
6614833cb1 Show one decimal point on clips 2022-06-14 03:44:14 -07:00
Austin Chen
8d97eb6f63 Remove deprecated antes 2022-06-14 03:39:14 -07:00
Austin Chen
14864a9f7e Change currency constants 2022-06-14 03:34:50 -07:00
Austin Chen
f4c7148e7e Design in the Atlas logo 2022-06-14 03:13:10 -07:00
Austin Chen
65f19ff56d Fix ESLint 2022-06-14 02:49:13 -07:00
Austin Chen
39fe9f0acc Fix import 2022-06-14 02:46:48 -07:00
Austin Chen
26bb228e90 Start off Atlas users with A$5000 2022-06-14 02:46:00 -07:00
Austin Chen
2dfe939656 Fix build 2022-06-14 02:44:37 -07:00
Austin Chen
f3233955e8 Use firestore-based search for private instances 2022-06-14 02:35:51 -07:00
Austin Chen
1f67d90f84 Hide "Get M$" on private instances 2022-06-14 02:08:55 -07:00
Austin Chen
0c9f1b1745 Try removing embed/analytics to fix build 2022-06-14 01:50:03 -07:00
Austin Chen
fd7f7afabd Update README.md 2022-06-14 01:35:34 -07:00
Austin Chen
e6df6bd53c Update firestore.indexes.json 2022-06-14 01:35:24 -07:00
Austin Chen
7745851d4c Update function endpoints 2022-06-14 01:35:20 -07:00
Austin Chen
a1368abd66 Merge branch 'main' into atlas 2022-06-14 00:46:25 -07:00
Austin Chen
cd9f065be2 Prettier format 2022-06-12 21:12:20 -07:00
Austin Chen
2661c76d23 Add Atlas favicon 2022-06-12 21:05:48 -07:00
Austin Chen
eae5a70d52 Set up Atlas Firebase 2022-06-12 21:02:16 -07:00
18 changed files with 388 additions and 45 deletions

View File

@ -10,12 +10,9 @@ import {
import { User } from './user' import { User } from './user'
import { LiquidityProvision } from './liquidity-provision' import { LiquidityProvision } from './liquidity-provision'
import { noFees } from './fees' import { noFees } from './fees'
import { ENV_CONFIG } from './envs/constants'
export const FIXED_ANTE = 100 export const FIXED_ANTE = ENV_CONFIG.fixedAnte ?? 10
// deprecated
export const PHANTOM_ANTE = 0.001
export const MINIMUM_ANTE = 50
export const HOUSE_LIQUIDITY_PROVIDER_ID = 'IPTOzEqrpkWmEzh6hwvAyY9PqFb2' // @ManifoldMarkets' id export const HOUSE_LIQUIDITY_PROVIDER_ID = 'IPTOzEqrpkWmEzh6hwvAyY9PqFb2' // @ManifoldMarkets' id

35
common/envs/atlas.ts Normal file
View File

@ -0,0 +1,35 @@
import { EnvConfig, PROD_CONFIG } from './prod'
export const ATLAS_CONFIG: EnvConfig = {
domain: 'atlas.manifold.markets',
firebaseConfig: {
apiKey: 'AIzaSyCQvm7AjL1NjULPaEYjAiUjiVhfXmHGh_w',
authDomain: 'atlas-manifold.firebaseapp.com',
projectId: 'atlas-manifold',
storageBucket: 'atlas-manifold.appspot.com',
messagingSenderId: '802386508975',
appId: '1:802386508975:web:1b1ff75deec469945ca85a',
measurementId: 'G-FR9SJTFF2K',
region: 'us-central1',
},
functionEndpoints: {
placebet: 'https://placebet-txwwmth7kq-uc.a.run.app',
sellshares: 'https://sellshares-txwwmth7kq-uc.a.run.app',
sellbet: 'https://sellbet-txwwmth7kq-uc.a.run.app',
createmarket: 'https://createmarket-txwwmth7kq-uc.a.run.app',
},
adminEmails: [...PROD_CONFIG.adminEmails],
whitelistEmail: '',
moneyMoniker: '📎',
fixedAnte: 25,
startingBalance: 500,
visibility: 'PRIVATE',
// faviconPath: '/atlas/atlas-favicon.png',
navbarLogoPath: '/atlas/atlas-logo-white.svg',
newQuestionPlaceholders: [
'Will we have at least 5 new team members by the end of this quarter?',
'Will we meet or exceed our goals this sprint?',
'Will we sign on 3 or more new clients this month?',
'Will Paul shave his beard by the end of the month?',
],
}

View File

@ -1,4 +1,5 @@
import { escapeRegExp } from 'lodash' import { escapeRegExp } from 'lodash'
import { ATLAS_CONFIG } from './atlas'
import { DEV_CONFIG } from './dev' import { DEV_CONFIG } from './dev'
import { EnvConfig, PROD_CONFIG } from './prod' import { EnvConfig, PROD_CONFIG } from './prod'
import { THEOREMONE_CONFIG } from './theoremone' import { THEOREMONE_CONFIG } from './theoremone'
@ -9,6 +10,7 @@ const CONFIGS: { [env: string]: EnvConfig } = {
PROD: PROD_CONFIG, PROD: PROD_CONFIG,
DEV: DEV_CONFIG, DEV: DEV_CONFIG,
THEOREMONE: THEOREMONE_CONFIG, THEOREMONE: THEOREMONE_CONFIG,
ATLAS: ATLAS_CONFIG,
} }
export const ENV_CONFIG = CONFIGS[ENV] export const ENV_CONFIG = CONFIGS[ENV]

View File

@ -19,6 +19,10 @@ export type EnvConfig = {
faviconPath?: string // Should be a file in /public faviconPath?: string // Should be a file in /public
navbarLogoPath?: string navbarLogoPath?: string
newQuestionPlaceholders: string[] newQuestionPlaceholders: string[]
// Currency controls
fixedAnte?: number
startingBalance?: number
} }
type FirebaseConfig = { type FirebaseConfig = {

View File

@ -1,3 +1,5 @@
import { ENV_CONFIG } from './envs/constants'
export type User = { export type User = {
id: string id: string
createdTime: number createdTime: number
@ -21,8 +23,9 @@ export type User = {
followedCategories?: string[] followedCategories?: string[]
} }
export const STARTING_BALANCE = 1000 export const STARTING_BALANCE = ENV_CONFIG.startingBalance ?? 1000
export const SUS_STARTING_BALANCE = 10 // for sus users, i.e. multiple sign ups for same person // for sus users, i.e. multiple sign ups for same person
export const SUS_STARTING_BALANCE = ENV_CONFIG.startingBalance ?? 10
export type PrivateUser = { export type PrivateUser = {
id: string // same as User.id id: string // same as User.id

View File

@ -7,9 +7,13 @@ const formatter = new Intl.NumberFormat('en-US', {
minimumFractionDigits: 0, minimumFractionDigits: 0,
}) })
// export function formatMoney(amount: number) {
// const newAmount = Math.round(amount) === 0 ? 0 : Math.floor(amount) // handle -0 case
// return ENV_CONFIG.moneyMoniker + formatter.format(newAmount).replace('$', '')
// }
export function formatMoney(amount: number) { export function formatMoney(amount: number) {
const newAmount = Math.round(amount) === 0 ? 0 : Math.floor(amount) // handle -0 case return ENV_CONFIG.moneyMoniker + amount.toFixed(1)
return ENV_CONFIG.moneyMoniker + formatter.format(newAmount).replace('$', '')
} }
export function formatWithCommas(amount: number) { export function formatWithCommas(amount: number) {

View File

@ -1,5 +1,69 @@
{ {
"indexes": [ "indexes": [
{
"collectionGroup": "bets",
"queryScope": "COLLECTION_GROUP",
"fields": [
{
"fieldPath": "isAnte",
"order": "ASCENDING"
},
{
"fieldPath": "isRedemption",
"order": "ASCENDING"
},
{
"fieldPath": "userId",
"order": "ASCENDING"
},
{
"fieldPath": "createdTime",
"order": "ASCENDING"
}
]
},
{
"collectionGroup": "bets",
"queryScope": "COLLECTION_GROUP",
"fields": [
{
"fieldPath": "userId",
"order": "ASCENDING"
},
{
"fieldPath": "createdTime",
"order": "DESCENDING"
}
]
},
{
"collectionGroup": "comments",
"queryScope": "COLLECTION_GROUP",
"fields": [
{
"fieldPath": "userId",
"order": "ASCENDING"
},
{
"fieldPath": "createdTime",
"order": "DESCENDING"
}
]
},
{
"collectionGroup": "contracts",
"queryScope": "COLLECTION",
"fields": [
{
"fieldPath": "creatorId",
"order": "ASCENDING"
},
{
"fieldPath": "createdTime",
"order": "ASCENDING"
}
]
},
{ {
"collectionGroup": "contracts", "collectionGroup": "contracts",
"queryScope": "COLLECTION", "queryScope": "COLLECTION",
@ -104,6 +168,24 @@
} }
] ]
}, },
{
"collectionGroup": "contracts",
"queryScope": "COLLECTION",
"fields": [
{
"fieldPath": "isResolved",
"order": "ASCENDING"
},
{
"fieldPath": "visibility",
"order": "ASCENDING"
},
{
"fieldPath": "volume7Days",
"order": "ASCENDING"
}
]
},
{ {
"collectionGroup": "contracts", "collectionGroup": "contracts",
"queryScope": "COLLECTION", "queryScope": "COLLECTION",
@ -118,6 +200,84 @@
} }
] ]
}, },
{
"collectionGroup": "contracts",
"queryScope": "COLLECTION",
"fields": [
{
"fieldPath": "isResolved",
"order": "ASCENDING"
},
{
"fieldPath": "volume7Days",
"order": "ASCENDING"
}
]
},
{
"collectionGroup": "contracts",
"queryScope": "COLLECTION",
"fields": [
{
"fieldPath": "isResolved",
"order": "ASCENDING"
},
{
"fieldPath": "volume7Days",
"order": "ASCENDING"
},
{
"fieldPath": "closeTime",
"order": "ASCENDING"
}
]
},
{
"collectionGroup": "contracts",
"queryScope": "COLLECTION",
"fields": [
{
"fieldPath": "isResolved",
"order": "ASCENDING"
},
{
"fieldPath": "volume7Days",
"order": "ASCENDING"
},
{
"fieldPath": "createdTime",
"order": "ASCENDING"
}
]
},
{
"collectionGroup": "contracts",
"queryScope": "COLLECTION",
"fields": [
{
"fieldPath": "isResolved",
"order": "ASCENDING"
},
{
"fieldPath": "volume7Days",
"order": "DESCENDING"
}
]
},
{
"collectionGroup": "contracts",
"queryScope": "COLLECTION",
"fields": [
{
"fieldPath": "lowercaseTags",
"arrayConfig": "CONTAINS"
},
{
"fieldPath": "createdTime",
"order": "DESCENDING"
}
]
},
{ {
"collectionGroup": "contracts", "collectionGroup": "contracts",
"queryScope": "COLLECTION", "queryScope": "COLLECTION",
@ -131,6 +291,24 @@
"order": "DESCENDING" "order": "DESCENDING"
} }
] ]
},
{
"collectionGroup": "txns",
"queryScope": "COLLECTION",
"fields": [
{
"fieldPath": "toId",
"order": "ASCENDING"
},
{
"fieldPath": "toType",
"order": "ASCENDING"
},
{
"fieldPath": "createdTime",
"order": "DESCENDING"
}
]
} }
], ],
"fieldOverrides": [ "fieldOverrides": [
@ -295,6 +473,28 @@
"queryScope": "COLLECTION_GROUP" "queryScope": "COLLECTION_GROUP"
} }
] ]
},
{
"collectionGroup": "follows",
"fieldPath": "userId",
"indexes": [
{
"order": "ASCENDING",
"queryScope": "COLLECTION"
},
{
"order": "DESCENDING",
"queryScope": "COLLECTION"
},
{
"arrayConfig": "CONTAINS",
"queryScope": "COLLECTION"
},
{
"order": "ASCENDING",
"queryScope": "COLLECTION_GROUP"
}
]
} }
] ]
} }

View File

@ -59,5 +59,5 @@ Adapted from https://firebase.google.com/docs/functions/get-started
Secrets are strings that shouldn't be checked into Git (eg API keys, passwords). We store these using [Google Secret Manager](https://console.cloud.google.com/security/secret-manager), which provides them as environment variables to functions that require them. Some useful workflows: Secrets are strings that shouldn't be checked into Git (eg API keys, passwords). We store these using [Google Secret Manager](https://console.cloud.google.com/security/secret-manager), which provides them as environment variables to functions that require them. Some useful workflows:
- Set a secret: `$ firebase functions:secrets:set stripe.test_secret="THE-API-KEY"`
- Read a secret: `$ firebase functions:secrets:access STRIPE_APIKEY` - Read a secret: `$ firebase functions:secrets:access STRIPE_APIKEY`
- Set a secret: `$ firebase functions:secrets:set STRIPE_APIKEY`

View File

@ -19,13 +19,14 @@ import { ContractsGrid } from './contract/contracts-list'
import { Row } from './layout/row' import { Row } from './layout/row'
import { useEffect, useMemo, useRef, useState } from 'react' import { useEffect, useMemo, useRef, useState } from 'react'
import { Spacer } from './layout/spacer' import { Spacer } from './layout/spacer'
import { ENV } from 'common/envs/constants' import { ENV, IS_PRIVATE_MANIFOLD } from 'common/envs/constants'
import { useUser } from 'web/hooks/use-user' import { useUser } from 'web/hooks/use-user'
import { useFollows } from 'web/hooks/use-follows' import { useFollows } from 'web/hooks/use-follows'
import { EditCategoriesButton } from './feed/category-selector' import { EditCategoriesButton } from './feed/category-selector'
import { CATEGORIES } from 'common/categories' import { CATEGORIES } from 'common/categories'
import { Tabs } from './layout/tabs' import { Tabs } from './layout/tabs'
import { EditFollowingButton } from './following-button' import { EditFollowingButton } from './following-button'
import ContractSearchFirestore from 'web/pages/contract-search-firestore'
const searchClient = algoliasearch( const searchClient = algoliasearch(
'GJQPAYENIF', 'GJQPAYENIF',
@ -119,6 +120,10 @@ export function ContractSearch(props: {
const indexName = `${indexPrefix}contracts-${sort}` const indexName = `${indexPrefix}contracts-${sort}`
if (IS_PRIVATE_MANIFOLD) {
return <ContractSearchFirestore querySortOptions={querySortOptions} />
}
return ( return (
<InstantSearch searchClient={searchClient} indexName={indexName}> <InstantSearch searchClient={searchClient} indexName={indexName}>
<Row className="gap-1 sm:gap-2"> <Row className="gap-1 sm:gap-2">

View File

@ -25,7 +25,7 @@ import { useSaveShares } from '../use-save-shares'
import { sellShares } from 'web/lib/firebase/api-call' import { sellShares } from 'web/lib/firebase/api-call'
import { calculateCpmmSale, getCpmmProbability } from 'common/calculate-cpmm' import { calculateCpmmSale, getCpmmProbability } from 'common/calculate-cpmm'
const BET_SIZE = 10 const BET_SIZE = 1
export function QuickBet(props: { contract: Contract; user: User }) { export function QuickBet(props: { contract: Contract; user: User }) {
const { contract, user } = props const { contract, user } = props
@ -159,7 +159,7 @@ export function QuickBet(props: { contract: Contract; user: User }) {
onClick={() => placeQuickBet('UP')} onClick={() => placeQuickBet('UP')}
/> />
<div className="mt-2 text-center text-xs text-transparent peer-hover:text-gray-400"> <div className="mt-2 text-center text-xs text-transparent peer-hover:text-gray-400">
{formatMoney(10)} {formatMoney(BET_SIZE)}
</div> </div>
{hasUpShares > 0 ? ( {hasUpShares > 0 ? (
@ -213,7 +213,7 @@ export function QuickBet(props: { contract: Contract; user: User }) {
/> />
)} )}
<div className="mb-2 text-center text-xs text-transparent peer-hover:text-gray-400"> <div className="mb-2 text-center text-xs text-transparent peer-hover:text-gray-400">
{formatMoney(10)} {formatMoney(BET_SIZE)}
</div> </div>
</div> </div>
)} )}

View File

@ -17,16 +17,23 @@ export function ManifoldLogo(props: {
return ( return (
<Link href={user ? '/home' : '/'}> <Link href={user ? '/home' : '/'}>
<a className={clsx('group flex flex-shrink-0 flex-row gap-4', className)}> <a className={clsx('group flex flex-shrink-0 flex-row gap-4', className)}>
{!ENV_CONFIG.navbarLogoPath && (
<img <img
className="transition-all group-hover:rotate-12" className="transition-all group-hover:rotate-12"
src={darkBackground ? '/logo-white.svg' : '/logo.svg'} src={darkBackground ? '/logo-white.svg' : '/logo.svg'}
width={45} width={45}
height={45} height={45}
/> />
)}
{!hideText && {!hideText &&
(ENV_CONFIG.navbarLogoPath ? ( (ENV_CONFIG.navbarLogoPath ? (
<img src={ENV_CONFIG.navbarLogoPath} width={245} height={45} /> <img
className="rounded-md bg-gradient-to-r from-cyan-500 to-sky-600 p-2"
src={ENV_CONFIG.navbarLogoPath}
width={350}
height={80}
/>
) : twoLine ? ( ) : twoLine ? (
<div <div
className={clsx( className={clsx(

View File

@ -48,7 +48,9 @@ function getNavigation(username: string) {
icon: NotificationsIcon, icon: NotificationsIcon,
}, },
{ name: 'Get M$', href: '/add-funds', icon: CashIcon }, ...(IS_PRIVATE_MANIFOLD
? []
: [{ name: 'Get M$', href: '/add-funds', icon: CashIcon }]),
] ]
} }
@ -102,7 +104,9 @@ const signedOutMobileNavigation = [
] ]
const mobileNavigation = [ const mobileNavigation = [
{ name: 'Get M$', href: '/add-funds', icon: CashIcon }, ...(IS_PRIVATE_MANIFOLD
? []
: [{ name: 'Get M$', href: '/add-funds', icon: CashIcon }]),
...signedOutMobileNavigation, ...signedOutMobileNavigation,
] ]

View File

@ -7,6 +7,7 @@
"devdev": "cross-env NEXT_PUBLIC_FIREBASE_ENV=DEV concurrently -n NEXT,TS -c magenta,cyan \"cross-env FIREBASE_ENV=DEV next dev -p 3000\" \"cross-env FIREBASE_ENV=DEV yarn ts --watch\"", "devdev": "cross-env NEXT_PUBLIC_FIREBASE_ENV=DEV concurrently -n NEXT,TS -c magenta,cyan \"cross-env FIREBASE_ENV=DEV next dev -p 3000\" \"cross-env FIREBASE_ENV=DEV yarn ts --watch\"",
"dev:dev": "yarn devdev", "dev:dev": "yarn devdev",
"dev:the": "cross-env NEXT_PUBLIC_FIREBASE_ENV=THEOREMONE concurrently -n NEXT,TS -c magenta,cyan \"cross-env FIREBASE_ENV=THEOREMONE next dev -p 3000\" \"cross-env FIREBASE_ENV=THEOREMONE yarn ts --watch\"", "dev:the": "cross-env NEXT_PUBLIC_FIREBASE_ENV=THEOREMONE concurrently -n NEXT,TS -c magenta,cyan \"cross-env FIREBASE_ENV=THEOREMONE next dev -p 3000\" \"cross-env FIREBASE_ENV=THEOREMONE yarn ts --watch\"",
"dev:atlas": "cross-env NEXT_PUBLIC_FIREBASE_ENV=ATLAS concurrently -n NEXT,TS -c magenta,cyan \"cross-env FIREBASE_ENV=ATLAS next dev -p 3000\" \"cross-env FIREBASE_ENV=ATLAS yarn ts --watch\"",
"dev:emulate": "cross-env NEXT_PUBLIC_FIREBASE_EMULATE=TRUE yarn devdev", "dev:emulate": "cross-env NEXT_PUBLIC_FIREBASE_EMULATE=TRUE yarn devdev",
"ts": "tsc --noEmit --incremental --preserveWatchOutput --pretty", "ts": "tsc --noEmit --incremental --preserveWatchOutput --pretty",
"build": "next build", "build": "next build",

View File

@ -0,0 +1,101 @@
import { Answer } from 'common/answer'
import { sortBy } from 'lodash'
import { useState } from 'react'
import { ContractsGrid } from 'web/components/contract/contracts-list'
import { LoadingIndicator } from 'web/components/loading-indicator'
import { useContracts } from 'web/hooks/use-contracts'
import {
Sort,
useInitialQueryAndSort,
} from 'web/hooks/use-sort-and-query-params'
export default function ContractSearchFirestore(props: {
querySortOptions?: {
defaultSort: Sort
shouldLoadFromStorage?: boolean
}
}) {
const contracts = useContracts()
const { querySortOptions } = props
const { initialSort, initialQuery } = useInitialQueryAndSort(querySortOptions)
const [sort, setSort] = useState(initialSort || 'newest')
const [query, setQuery] = useState(initialQuery)
const queryWords = query.toLowerCase().split(' ')
function check(corpus: string) {
return queryWords.every((word) => corpus.toLowerCase().includes(word))
}
let matches = (contracts ?? []).filter(
(c) =>
check(c.question) ||
check(c.description) ||
check(c.creatorName) ||
check(c.creatorUsername) ||
check(c.lowercaseTags.map((tag) => `#${tag}`).join(' ')) ||
check(
((c as any).answers ?? [])
.map((answer: Answer) => answer.text)
.join(' ')
)
)
if (sort === 'newest') {
matches.sort((a, b) => b.createdTime - a.createdTime)
} else if (sort === 'resolve-date') {
matches = sortBy(matches, (contract) => -1 * (contract.resolutionTime ?? 0))
} else if (sort === 'oldest') {
matches.sort((a, b) => a.createdTime - b.createdTime)
} else if (sort === 'close-date') {
matches = sortBy(matches, ({ volume24Hours }) => -1 * volume24Hours)
matches = sortBy(
matches,
(contract) =>
(sort === 'close-date' ? -1 : 1) * (contract.closeTime ?? Infinity)
)
} else if (sort === 'most-traded') {
matches.sort((a, b) => b.volume - a.volume)
} else if (sort === '24-hour-vol') {
// Use lodash for stable sort, so previous sort breaks all ties.
matches = sortBy(matches, ({ volume7Days }) => -1 * volume7Days)
matches = sortBy(matches, ({ volume24Hours }) => -1 * volume24Hours)
}
return (
<div>
{/* Show a search input next to a sort dropdown */}
<div className="mt-2 mb-8 flex justify-between gap-2">
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Search markets"
className="input input-bordered w-full"
/>
<select
className="select select-bordered"
value={sort}
onChange={(e) => setSort(e.target.value as Sort)}
>
<option value="newest">Newest</option>
<option value="oldest">Oldest</option>
<option value="most-traded">Most traded</option>
<option value="24-hour-vol">24h volume</option>
<option value="close-date">Closing soon</option>
</select>
</div>
{contracts === undefined ? (
<LoadingIndicator />
) : (
<ContractsGrid
contracts={matches}
loadMore={() => {}}
hasMore={false}
showCloseTime={['close-date', 'closed'].includes(sort)}
/>
)}
</div>
)
}

View File

@ -7,7 +7,7 @@ import { Spacer } from 'web/components/layout/spacer'
import { useUser } from 'web/hooks/use-user' import { useUser } from 'web/hooks/use-user'
import { Contract, contractPath } from 'web/lib/firebase/contracts' import { Contract, contractPath } from 'web/lib/firebase/contracts'
import { createMarket } from 'web/lib/firebase/api-call' import { createMarket } from 'web/lib/firebase/api-call'
import { FIXED_ANTE, MINIMUM_ANTE } from 'common/antes' import { FIXED_ANTE } from 'common/antes'
import { InfoTooltip } from 'web/components/info-tooltip' import { InfoTooltip } from 'web/components/info-tooltip'
import { Page } from 'web/components/page' import { Page } from 'web/components/page'
import { Row } from 'web/components/layout/row' import { Row } from 'web/components/layout/row'
@ -109,7 +109,6 @@ export function NewContract(props: { question: string }) {
question.length > 0 && question.length > 0 &&
ante !== undefined && ante !== undefined &&
ante !== null && ante !== null &&
ante >= MINIMUM_ANTE &&
(ante <= balance || (ante <= balance ||
(mustWaitForDailyFreeMarketStatus != 'loading' && (mustWaitForDailyFreeMarketStatus != 'loading' &&
!mustWaitForDailyFreeMarketStatus)) && !mustWaitForDailyFreeMarketStatus)) &&

View File

@ -1,20 +0,0 @@
import { Col } from 'web/components/layout/col'
import { Spacer } from 'web/components/layout/spacer'
import { fromPropz } from 'web/hooks/use-propz'
import Analytics, {
CustomAnalytics,
FirebaseAnalytics,
getStaticPropz,
} from '../stats'
export const getStaticProps = fromPropz(getStaticPropz)
export default function AnalyticsEmbed(props: Parameters<typeof Analytics>[0]) {
return (
<Col className="w-full bg-white px-2">
<CustomAnalytics {...props} />
<Spacer h={8} />
<FirebaseAnalytics />
</Col>
)
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 443.37"><defs><style>.d{fill:#fff;}</style></defs><g id="a"/><g id="b"><g id="c"><g><g><path class="d" d="M500.26,351.29v-78.83h50.58v5.93h-43.31v30.08h40.92v5.93h-40.92v36.9h-7.28Z"/><path class="d" d="M570.89,351.29v-78.83h51.78v5.93h-44.62v29.96h42.11v5.93h-42.11v31.08h44.62v5.93h-51.78Z"/><path class="d" d="M645.57,351.29v-78.83h7.28v72.68h43.9v6.15h-51.18Z"/><path class="d" d="M715.36,351.29v-78.83h7.28v72.68h43.9v6.15h-51.18Z"/><path class="d" d="M815.09,352.19c-7.72,0-14.38-1.64-19.98-4.92-5.61-3.28-9.94-7.94-13-13.98-3.06-6.04-4.59-13.19-4.59-21.47s1.51-15.43,4.53-21.47c3.02-6.04,7.36-10.68,13-13.92,5.65-3.24,12.33-4.86,20.04-4.86s14.49,1.62,20.1,4.86c5.61,3.24,9.94,7.87,13,13.86,3.06,6,4.59,13.14,4.59,21.41s-1.53,15.54-4.59,21.58c-3.06,6.04-7.42,10.7-13.06,13.98-5.65,3.28-12.33,4.92-20.04,4.92Zm0-6.26c9.46,0,16.82-2.98,22.07-8.94,5.25-5.96,7.87-14.35,7.87-25.16s-2.61-19.18-7.81-25.1c-5.21-5.93-12.59-8.89-22.13-8.89s-16.8,2.98-22.01,8.94c-5.21,5.96-7.81,14.31-7.81,25.05s2.6,19.1,7.81,25.1c5.21,6,12.54,9,22.01,9Z"/><path class="d" d="M897.76,351.29l-29.23-78.83h7.64l25.17,68.65,25.41-68.65h6.2l25.41,69.1,25.41-69.1h7.4l-29.23,78.83h-6.92l-25.17-68.43-25.41,68.43h-6.68Z"/><path class="d" d="M1037.11,352.19c-6.52,0-12.39-.8-17.6-2.4-5.21-1.6-9.72-3.97-13.54-7.1l2.86-5.7c4.13,3.06,8.37,5.31,12.71,6.76,4.33,1.45,9.52,2.18,15.57,2.18,7.55,0,13.22-1.38,17-4.14,3.78-2.76,5.67-6.37,5.67-10.85,0-3.73-1.37-6.63-4.12-8.72-2.74-2.09-7.26-3.73-13.54-4.92l-12.05-2.35c-7.48-1.41-13.06-3.8-16.76-7.16s-5.55-7.83-5.55-13.42c0-4.55,1.25-8.53,3.76-11.96,2.51-3.43,5.98-6.09,10.44-7.99,4.45-1.9,9.58-2.85,15.39-2.85,11.61,0,20.88,3.28,27.8,9.84l-2.86,5.59c-3.66-3.2-7.48-5.53-11.45-6.99-3.98-1.45-8.47-2.18-13.48-2.18-6.68,0-12.03,1.49-16.05,4.47-4.02,2.98-6.02,6.97-6.02,11.96,0,3.95,1.27,7.06,3.82,9.34,2.54,2.27,6.64,3.93,12.29,4.98l12.17,2.35c8.03,1.57,14,3.9,17.9,6.99,3.9,3.09,5.85,7.32,5.85,12.69,0,4.25-1.21,7.99-3.64,11.24-2.43,3.24-5.91,5.78-10.44,7.6-4.53,1.83-9.9,2.74-16.1,2.74Z"/><path class="d" d="M1089.24,351.29v-78.83h7.28v35.78h53.68v-35.78h7.28v78.83h-7.28v-36.9h-53.68v36.9h-7.28Z"/><path class="d" d="M1185.4,351.29v-78.83h7.28v78.83h-7.28Z"/><path class="d" d="M1220.59,351.29v-78.83h31.73c8.99,0,15.85,2.01,20.58,6.04,4.73,4.03,7.1,9.77,7.1,17.22s-2.37,13.1-7.1,17.16c-4.73,4.06-11.59,6.09-20.58,6.09h-24.46v32.31h-7.28Zm7.28-38.35h23.86c13.92,0,20.88-5.74,20.88-17.22s-6.96-17.33-20.88-17.33h-23.86v34.55Z"/></g><path class="d" d="M231.33,216.67L126.1,6.2c-1.9-3.8-5.79-6.2-10.03-6.2s-8.13,2.4-10.03,6.2L2.21,213.83c-.7,1.14-2.14,3.81-2.21,7.5-.07,3.48,1.11,6.08,1.74,7.26l104.29,208.57c1.9,3.8,5.79,6.2,10.03,6.2h.01c4.25,0,8.14-2.41,10.03-6.22l103.4-207.83c.73-1.26,1.81-3.47,2.19-6.43,.34-2.66-.02-4.86-.36-6.22ZM58.72,150.99h114.69l29.63,59.27H29.08l29.63-59.27ZM116.06,36.3l46.13,92.26H69.93L116.06,36.3Zm-.03,370.72l-46.08-92.15h64.99c6.49,0,11.75-5.02,11.75-11.22s-5.26-11.22-11.75-11.22H58.74l-29.87-59.74H202.77l-86.73,174.33Z"/><g><path class="d" d="M271.65,232.48l72.08-159.3h23.72l72.08,159.3h-29.37l-15.82-36.83h-77.73l-15.59,36.83h-29.37Zm83.6-127.89l-28.7,68.01h57.84l-28.7-68.01h-.45Z"/><path class="d" d="M500.32,232.48V97.36h-54.68v-24.18h138.28v24.18h-54.68V232.48h-28.92Z"/><path class="d" d="M624.81,232.48V73.18h28.92V207.85h76.37v24.63h-105.29Z"/><path class="d" d="M753.83,232.48l72.08-159.3h23.72l72.08,159.3h-29.37l-15.82-36.83h-77.73l-15.59,36.83h-29.37Zm83.6-127.89l-28.7,68.01h57.84l-28.7-68.01h-.45Z"/><path class="d" d="M1014.8,234.74c-12.5,0-24.1-1.62-34.8-4.86-10.7-3.24-19.74-7.64-27.11-13.22l8.81-22.82c7.38,5.27,15.48,9.34,24.29,12.2,8.81,2.86,18.41,4.29,28.81,4.29,11.9,0,20.56-1.99,25.98-5.99,5.42-3.99,8.13-9.15,8.13-15.48,0-5.27-1.92-9.41-5.76-12.43-3.84-3.01-10.43-5.5-19.77-7.46l-24.85-5.2c-28.32-6.02-42.48-20.56-42.48-43.61,0-9.94,2.63-18.6,7.91-25.98,5.27-7.38,12.58-13.1,21.92-17.17,9.34-4.07,20.11-6.1,32.31-6.1,10.85,0,21.01,1.62,30.5,4.86,9.49,3.24,17.4,7.8,23.72,13.67l-8.81,21.69c-12.51-10.54-27.72-15.82-45.64-15.82-10.39,0-18.53,2.19-24.4,6.55-5.87,4.37-8.81,10.09-8.81,17.17,0,5.42,1.81,9.76,5.42,12.99,3.62,3.24,9.79,5.76,18.53,7.57l24.63,5.2c14.91,3.16,26.02,8.13,33.33,14.91,7.3,6.78,10.96,15.82,10.96,27.11,0,9.49-2.56,17.85-7.68,25.08-5.12,7.23-12.39,12.84-21.8,16.83-9.42,3.99-20.53,5.99-33.33,5.99Z"/></g></g></g></g></svg>

After

Width:  |  Height:  |  Size: 4.3 KiB