diff --git a/functions/assets/demo.svg b/functions/assets/demo.svg
new file mode 100644
index 0000000..e653231
--- /dev/null
+++ b/functions/assets/demo.svg
@@ -0,0 +1,2678 @@
+
+
\ No newline at end of file
diff --git a/functions/assets/master.afdesign b/functions/assets/master.afdesign
new file mode 100644
index 0000000..2f972f9
Binary files /dev/null and b/functions/assets/master.afdesign differ
diff --git a/functions/assets/master.svg b/functions/assets/master.svg
new file mode 100644
index 0000000..c7f01a1
--- /dev/null
+++ b/functions/assets/master.svg
@@ -0,0 +1,12683 @@
+
+
+
diff --git a/functions/assets/suit.afdesign b/functions/assets/suit.afdesign
new file mode 100644
index 0000000..1175a0f
Binary files /dev/null and b/functions/assets/suit.afdesign differ
diff --git a/functions/modules/firebase.js b/functions/modules/firebase.js
index 169d7bd..2d4d81e 100644
--- a/functions/modules/firebase.js
+++ b/functions/modules/firebase.js
@@ -1,12 +1,13 @@
// Dependencies
-const admin = require( 'firebase-admin' )
+const { initializeApp } = require( 'firebase-admin/app' )
+const { getFirestore, FieldValue, FieldPath } = require( 'firebase-admin/firestore' )
// Admin api
-const app = admin.initializeApp()
-const db = app.firestore()
-const { FieldValue, FieldPath } = admin.firestore
+const app = initializeApp()
+const db = getFirestore()
module.exports = {
+ app: app,
db: db,
FieldValue: FieldValue,
FieldPath: FieldPath
diff --git a/functions/modules/helpers.js b/functions/modules/helpers.js
new file mode 100644
index 0000000..5bc3362
--- /dev/null
+++ b/functions/modules/helpers.js
@@ -0,0 +1,93 @@
+// ///////////////////////////////
+// Helper functions
+// ///////////////////////////////
+
+// Pick random item from an array
+const pickRandomArrayEntry = array => array[ Math.floor( Math.random() * array.length ) ]
+exports.pickRandomArrayEntry = pickRandomArrayEntry
+
+// Generate random number between x and y
+exports.randomNumberBetween = ( min, max ) => Math.floor( Math.random() * ( max - min + 1 ) + min )
+
+// Random attribute picker
+exports.pickRandomAttributes = ( attributes ) => {
+
+ // Decimal accuracy, if probabilities have the lowest 0.01 then 100 is enough, for 0.001 1000 is needed
+ const probabilityDecimals = 3
+
+ // Remap the trait so it has a 'lottery ticket box' based on probs
+ const attributeLottery = attributes.map( ( { values, ...attribute } ) => ( {
+ // Attribute meta stays the same
+ ...attribute,
+ // Values are reduced from objects with probabilities to an array with elements
+ values: values.reduce( ( acc, val ) => {
+
+ const { probability, value } = val
+
+ // Map probabilities to a flat array of items
+ const amountToAdd = 10 * probabilityDecimals * probability
+ for ( let i = 0; i < amountToAdd; i++ ) acc.push( value )
+ return acc
+
+ }, [] )
+ } ) )
+
+ // Pick a random element from the lottery box array items
+ return attributeLottery.map( ( { values, ...attribute } ) => ( {
+ // Attribute meta stays the same
+ ...attribute,
+ // Select random entry from array
+ value: pickRandomArrayEntry( values )
+ } ) )
+
+}
+
+// ///////////////////////////////
+// Attribute sources
+// ///////////////////////////////
+exports.globalAttributes = [
+ { trait_type: "helmet", values: [
+ { value: 'classic', probability: .2 },
+ { value: 'racer', probability: .1 },
+ { value: 'punk', probability: .1 },
+ { value: 'knight', probability: .2 },
+ { value: 'geek', probability: .2 }
+
+ ] },
+ { trait_type: "patch", values: [
+ { value: 'nimbus', probability: .1 },
+ { value: 'teku', probability: .1 },
+ { value: 'lighthouse', probability: .1 },
+ { value: 'prysm', probability: .2 },
+ { value: 'rocketpool', probability: .5 }
+
+ ] },
+ { trait_type: "backpack", values: [
+ { value: 'yes', probability: .9 },
+ { value: 'no', probability: .1 }
+ ] },
+ { trait_type: "panel", values: [
+ { value: 'yes', probability: .9 },
+ { value: 'no', probability: .1 }
+ ] },
+ { trait_type: "background", values: [
+ { value: 'planets', probability: .2 },
+ { value: 'system', probability: .2 },
+ { value: 'playful', probability: .1 },
+ { value: 'moon', probability: .05 },
+ { value: 'galaxy', probability: .2 },
+ { value: 'chip', probability: .05 }
+
+ ] },
+ { trait_type: "background complexity", values: [
+ { value: 1, probability: .4 },
+ { value: 2, probability: .3 },
+ { value: 3, probability: .2 },
+ { value: 4, probability: .1 }
+ ] }
+
+
+]
+exports.heavenlyBodies = [ "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto", "the Moon", "the Sun" ]
+exports.web2domain = 'https://rocketeer.fans'
+exports.lorem = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
diff --git a/functions/modules/rocketeer.js b/functions/modules/rocketeer.js
index ddf8f6d..6f3254d 100644
--- a/functions/modules/rocketeer.js
+++ b/functions/modules/rocketeer.js
@@ -1,60 +1,8 @@
const name = require( 'random-name' )
const { db } = require( './firebase' )
const { getTotalSupply } = require( './contract' )
-
-// ///////////////////////////////
-// Attribute sources
-// ///////////////////////////////
-const globalAttributes = [
- { trait_type: "Age", display_type: "number", values: [
- { value: 35, probability: .5 },
- { value: 45, probability: .25 },
- { value: 25, probability: .25 }
- ] }
-]
-const heavenlyBodies = [ "Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto", "the Moon", "the Sun" ]
-const web2domain = 'https://rocketeer.fans'
-const lorem = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
-
-// ///////////////////////////////
-// Rocketeer helpers
-// ///////////////////////////////
-
-// Pick random item from array with equal probability
-const pickRandomArrayEntry = array => array[ Math.floor( Math.random() * array.length ) ]
-
-// Pick random attributes based on global attribute array
-function pickRandomAttributes( attributes ) {
-
- // Decimal accuracy, if probabilities have the lowest 0.01 then 100 is enough, for 0.001 1000 is needed
- const probabilityDecimals = 3
-
- // Remap the trait so it has a 'lottery ticket box' based on probs
- const attributeLottery = attributes.map( ( { values, ...attribute } ) => ( {
- // Attribute meta stays the same
- ...attribute,
- // Values are reduced from objects with probabilities to an array with elements
- values: values.reduce( ( acc, val ) => {
-
- const { probability, value } = val
-
- // Map probabilities to a flat array of items
- const amountToAdd = 10 * probabilityDecimals * probability
- for ( let i = 0; i < amountToAdd; i++ ) acc.push( value )
- return acc
-
- }, [] )
- } ) )
-
- // Pick a random element from the lottery box array items
- return attributeLottery.map( ( { values, ...attribute } ) => ( {
- // Attribute meta stays the same
- ...attribute,
- // Select random entry from array
- value: pickRandomArrayEntry( values )
- } ) )
-
-}
+const { pickRandomArrayEntry, pickRandomAttributes, randomNumberBetween, globalAttributes, heavenlyBodies, web2domain, lorem } = require( './helpers' )
+const svgFromAttributes = require( './svg-generator' )
// ///////////////////////////////
// Caching
@@ -106,15 +54,36 @@ async function generateRocketeer( id, network='mainnet' ) {
name: `${ name.first() } ${ name.middle() } ${ name.last() } of ${ pickRandomArrayEntry( heavenlyBodies ) }`,
description: lorem,
image: ``,
- external_url: `https://viewer.rocketeer.fans/?rocketeer=${ id }` + network == 'mainnet' ? '' : '&testnet=true',
+ external_url: `https://viewer.rocketeer.fans/?rocketeer=${ id }` + ( network == 'mainnet' ? '' : '&testnet=true' ),
attributes: []
}
// Generate randomized attributes
rocketeer.attributes = pickRandomAttributes( globalAttributes )
+ // Generate color attributes
+ rocketeer.attributes.push( {
+ "trait_type": "outfit color",
+ value: `rgb( ${ randomNumberBetween( 0, 255 ) }, ${ randomNumberBetween( 0, 255 ) }, ${ randomNumberBetween( 0, 255 ) } )`
+ } )
+ rocketeer.attributes.push( {
+ "trait_type": "outfit accent color",
+ value: `rgb( ${ randomNumberBetween( 0, 255 ) }, ${ randomNumberBetween( 0, 255 ) }, ${ randomNumberBetween( 0, 255 ) } )`
+ } )
+ rocketeer.attributes.push( {
+ "trait_type": "backpack color",
+ value: `rgb( ${ randomNumberBetween( 0, 255 ) }, ${ randomNumberBetween( 0, 255 ) }, ${ randomNumberBetween( 0, 255 ) } )`
+ } )
+ rocketeer.attributes.push( {
+ "trait_type": "visor color",
+ value: `rgb( ${ randomNumberBetween( 0, 255 ) }, ${ randomNumberBetween( 0, 255 ) }, ${ randomNumberBetween( 0, 255 ) } )`
+ } )
+
+ // Write to demo file
+
+
// TODO: Generate, compile and upload image
- rocketeer.image = `${web2domain}/assets/draft-rocketeer.png`
+ rocketeer.image = await svgFromAttributes( rocketeer.attributes )
// Save new Rocketeer
await db.collection( `${ network }Rocketeers` ).doc( id ).set( rocketeer )
@@ -125,13 +94,13 @@ async function generateRocketeer( id, network='mainnet' ) {
async function safelyReturnRocketeer( id, network ) {
- // Chech if this is an illegal ID
- const invalidId = await isInvalidRocketeerId( id, network )
- if( invalidId ) throw invalidId
+ // // Chech if this is an illegal ID
+ // const invalidId = await isInvalidRocketeerId( id, network )
+ // if( invalidId ) throw invalidId
- // Get old rocketeer if it exists
- const oldRocketeer = await getExistingRocketeer( id, network )
- if( oldRocketeer ) return oldRocketeer
+ // // Get old rocketeer if it exists
+ // const oldRocketeer = await getExistingRocketeer( id, network )
+ // if( oldRocketeer ) return oldRocketeer
// If no old rocketeer exists, make a new one and save it
return generateRocketeer( id, network )
diff --git a/functions/modules/svg-generator.js b/functions/modules/svg-generator.js
new file mode 100644
index 0000000..117d71c
--- /dev/null
+++ b/functions/modules/svg-generator.js
@@ -0,0 +1,134 @@
+const masterPath = `${ __dirname }/../assets/master.svg`
+const jsdom = require("jsdom")
+const { JSDOM } = jsdom
+const { promises: fs } = require( 'fs' )
+
+const { getStorage } = require( 'firebase-admin/storage' )
+
+
+module.exports = async function svgFromAttributes( attributes=[] ) {
+
+ const { value: primary_color } = attributes.find( ( { trait_type } ) => trait_type == "outfit color" )
+ const { value: accent_color } = attributes.find( ( { trait_type } ) => trait_type == "outfit accent color" )
+ const { value: backpack_color } = attributes.find( ( { trait_type } ) => trait_type == "backpack color" )
+ const { value: visor_color } = attributes.find( ( { trait_type } ) => trait_type == "visor color" )
+ const { value: backpack } = attributes.find( ( { trait_type } ) => trait_type == "backpack" )
+ const { value: panel } = attributes.find( ( { trait_type } ) => trait_type == "panel" )
+ const { value: patch } = attributes.find( ( { trait_type } ) => trait_type == "patch" )
+ const { value: helmet } = attributes.find( ( { trait_type } ) => trait_type == "helmet" )
+ const { value: background } = attributes.find( ( { trait_type } ) => trait_type == "background" )
+ const { value: background_complexity } = attributes.find( ( { trait_type } ) => trait_type == "background complexity" )
+
+ // Generate DOM to work with
+ const svgString = await fs.readFile( masterPath, 'utf8' )
+ const { window: { document } } = new JSDOM( svgString )
+
+ // ///////////////////////////////
+ // Attribute selection
+ // ///////////////////////////////
+
+ // Remove obsolete patches
+ const obsoletePatches = [ 'nimbus', 'teku', 'lighthouse', 'prysm', 'rocketpool' ].filter( p => p !== patch )
+ for ( let i = obsoletePatches.length - 1; i >= 0; i-- ) {
+ const element = document.querySelector( `#${ obsoletePatches[i] }` )
+ if( element ) element.remove()
+ else console.log( `Could not find #${ obsoletePatches[i] }` )
+ }
+
+ // Remove obsolete hemets
+ const obsoleteHelmets = [ 'classic', 'racer', 'punk', 'knight', 'geek' ].filter( p => p !== helmet )
+ for ( let i = obsoleteHelmets.length - 1; i >= 0; i-- ) {
+ const element = document.querySelector( `#${ obsoleteHelmets[i] }` )
+ if( element ) element.remove()
+ else console.log( `Could not find #${ obsoleteHelmets[i] }` )
+ }
+
+ // Remove panel if need be
+ if( panel === 'no' ) {
+ const element = document.querySelector( `#panel` )
+ if( element ) element.remove()
+ else console.log( `Could not find #panel` )
+ }
+
+ // Remove backpack if need be
+ if( backpack === 'no' ) {
+ const element = document.querySelector( `#backpack` )
+ if( element ) element.remove()
+ else console.log( 'Could not find #backpack' )
+ }
+
+ // Remove obsolete backgrounds
+ const obsoleteBackgrounds = [ 'planets', 'system', 'playful', 'moon', 'galaxy', 'chip' ].filter( p => p !== background )
+ for ( let i = obsoleteBackgrounds.length - 1; i >= 0; i-- ) {
+ const element = document.querySelector( `#${ obsoleteBackgrounds[i] }` )
+ if( element ) element.remove()
+ else console.log( `Could not find #${ obsoleteBackgrounds[i] }` )
+ }
+
+ // ///////////////////////////////
+ // Background customisation
+ // ///////////////////////////////
+
+ // In playful, keeping things is basic, removing them is cool
+ if( background === 'playful' ) {
+
+ const toRemove = background_complexity
+ for ( let i = 1; i <= toRemove; i++ ) {
+ const element = document.querySelector( `#playful-element-${ 5 - i }` )
+ if( element ) element.remove()
+ else console.log( `Could not find #playful-element-${ 5 - i }` )
+ }
+
+ } else {
+
+ // In others, keeping is cool, and removing is less cool
+ // so higher rarity means less looping
+ const toRemove = 4 - background_complexity
+ console.log( `Removing ${ toRemove } background props` )
+ for ( let i = 1; i <= toRemove; i++ ) {
+ console.log( `Remove #${ background }-element-${ 5 - i }` )
+ const element = document.querySelector( `#${ background }-element-${ 5 - i }` )
+ if( element ) element.remove()
+ else console.log( `Could not find #${ background }-element-${ 5 - i }` )
+ }
+
+ }
+
+ // ///////////////////////////////
+ // Color substitutions
+ // ///////////////////////////////
+ const defaultPrimary = /rgb\( ?252 ?, ?186 ?, ?157 ?\)/ig
+ const defaultVisor = /rgb\( ?71 ?, ?22 ?, ?127 ?\)/ig
+ const defaultAccent = /rgb\( ?243 ?, ?99 ?, ?113 ?\)/ig
+ const defaultBackpack = /rgb\( ?195 ?, ?178 ?, ?249 ?\)/ig
+
+ // Substitutions
+ const replace = ( from, to ) => {
+ const replaced = document.querySelector( 'svg' ).innerHTML.replace( from, to )
+ document.querySelector( 'svg' ).innerHTML = replaced
+ }
+ replace( defaultPrimary, primary_color )
+ replace( defaultAccent, accent_color )
+ replace( defaultVisor, visor_color )
+ replace( defaultBackpack, backpack_color )
+
+ const bakedSvg = `\n${ document.querySelector( 'svg' ).outerHTML }`
+
+ // Store file on firebase
+ const storage = getStorage()
+ const bucket = storage.bucket()
+
+ // Make file reference
+ const file = bucket.file( `rocketeers/demo-${ Date.now() }.svg` )
+
+ // Save file buffer
+ await file.save( bakedSvg )
+
+ // Make file public
+ await file.makePublic( )
+
+ // Return public url
+ return file.publicUrl()
+
+
+}
\ No newline at end of file
diff --git a/functions/modules/testnet.js b/functions/modules/testnet.js
index 2236ff0..4376330 100644
--- a/functions/modules/testnet.js
+++ b/functions/modules/testnet.js
@@ -21,6 +21,7 @@ app.get( '/testnetapi/rocketeer/:id', async ( req, res ) => {
// Log error for debugging
console.error( `Testnet api error for ${ id }: `, Object.keys( e ) )
+ console.log( e )
// Return error to frontend
return res.json( { error: e.mesage || e.toString() } )
diff --git a/functions/package-lock.json b/functions/package-lock.json
index 02087be..2fc547c 100644
--- a/functions/package-lock.json
+++ b/functions/package-lock.json
@@ -592,9 +592,9 @@
}
},
"@firebase/database": {
- "version": "0.12.1",
- "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.12.1.tgz",
- "integrity": "sha512-Ethk0hc476qnkSKNBa+8Yc7iM8AO69HYWsaD+QUC983FZtnuMyNLHtEeSUbLQYvyHo7cOjcc52slop14WmfZeQ==",
+ "version": "0.12.2",
+ "resolved": "https://registry.npmjs.org/@firebase/database/-/database-0.12.2.tgz",
+ "integrity": "sha512-Y1LZR1LIQM8YKMkeUPpAq3/e53hcfcXO+JEZ6vCzBeD6xRawqmpw6B5/DzePdCNNvjcqheXzSaR7T39eRZo/wA==",
"requires": {
"@firebase/auth-interop-types": "0.1.6",
"@firebase/component": "0.5.7",
@@ -605,12 +605,12 @@
}
},
"@firebase/database-compat": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.1.1.tgz",
- "integrity": "sha512-K3DFWiw0YkLZtlfA9TOGPw6zVXKu5dQ1XqIGztUufFVRYW8IizReXVxzSSmJNR4Adr2LiU9j66Wenc6e5UfwaQ==",
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/@firebase/database-compat/-/database-compat-0.1.2.tgz",
+ "integrity": "sha512-sV32QIRSNIBj/6OYtpmPzA/SfQz1/NBZbhxg9dIhGaSt9e5HaMxXRuz2lImudX0Sd/v8DKdExrxa++K6rKrRtA==",
"requires": {
"@firebase/component": "0.5.7",
- "@firebase/database": "0.12.1",
+ "@firebase/database": "0.12.2",
"@firebase/database-types": "0.9.1",
"@firebase/logger": "0.3.0",
"@firebase/util": "1.4.0",
@@ -711,9 +711,9 @@
"optional": true
},
"@google-cloud/storage": {
- "version": "5.15.2",
- "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.15.2.tgz",
- "integrity": "sha512-41gmpyy9BUiEJIjbL9RvGsCsnBGzuZj5A4lnigyTeGNKXghnnnw89Zf1/I+pVGItk3L8lVMvxXakKWLVZP1Mmg==",
+ "version": "5.15.3",
+ "resolved": "https://registry.npmjs.org/@google-cloud/storage/-/storage-5.15.3.tgz",
+ "integrity": "sha512-a2Y+mvfbzznWorQiv6c+qdPDlBpe47tikV8tpQSnvYXz1Ed/rjin41k2nKUQUcAPGHtYeTzGfKnCNKC+lv8qRg==",
"optional": true,
"requires": {
"@google-cloud/common": "^3.7.4",
@@ -738,18 +738,19 @@
}
},
"@grpc/grpc-js": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.3.8.tgz",
- "integrity": "sha512-4qJqqn+CU/nBydz9ePJP+oa8dz0U42Ut/GejlbyaQ1xTkynCc+ndNHHnISlNeHawDsv4MOAyP3mV/EnDNUw2zA==",
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.4.2.tgz",
+ "integrity": "sha512-aUN6oGk9un8rfYWz73nQgFxPCYJQYd8LpIGguZHBsNduBMyqG6EWANrsVBuTG+nl/l4dKb3x+qi1l9+oxDxqGg==",
"optional": true,
"requires": {
+ "@grpc/proto-loader": "^0.6.4",
"@types/node": ">=12.12.47"
}
},
"@grpc/proto-loader": {
- "version": "0.6.5",
- "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.5.tgz",
- "integrity": "sha512-GZdzyVQI1Bln/kCzIYgTKu+rQJ5dno0gVrfmLe4jqQu7T2e7svSwJzpCBqVU5hhBSJP3peuPjOMWsj5GR61YmQ==",
+ "version": "0.6.6",
+ "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.6.tgz",
+ "integrity": "sha512-cdMaPZ8AiFz6ua6PUbP+LKbhwJbFXnrQ/mlnKGUyzDUZ3wp7vPLksnmLCBX6SHgSmjX7CbNVNLFYD5GmmjO4GQ==",
"optional": true,
"requires": {
"@types/long": "^4.0.1",
@@ -861,8 +862,7 @@
"@tootallnate/once": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
- "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
- "optional": true
+ "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A=="
},
"@types/bn.js": {
"version": "4.11.6",
@@ -989,6 +989,11 @@
"@types/node": "*"
}
},
+ "abab": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz",
+ "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q=="
+ },
"abort-controller": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
@@ -1010,8 +1015,16 @@
"acorn": {
"version": "7.4.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz",
- "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==",
- "dev": true
+ "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A=="
+ },
+ "acorn-globals": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz",
+ "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==",
+ "requires": {
+ "acorn": "^7.1.1",
+ "acorn-walk": "^7.1.1"
+ }
},
"acorn-jsx": {
"version": "5.3.2",
@@ -1019,11 +1032,15 @@
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
"dev": true
},
+ "acorn-walk": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz",
+ "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA=="
+ },
"agent-base": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
"integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
- "optional": true,
"requires": {
"debug": "4"
}
@@ -1236,6 +1253,11 @@
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
"integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
},
+ "browser-process-hrtime": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz",
+ "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow=="
+ },
"browserify-aes": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
@@ -1724,6 +1746,26 @@
"integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==",
"optional": true
},
+ "cssom": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz",
+ "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw=="
+ },
+ "cssstyle": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz",
+ "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==",
+ "requires": {
+ "cssom": "~0.3.6"
+ },
+ "dependencies": {
+ "cssom": {
+ "version": "0.3.8",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz",
+ "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg=="
+ }
+ }
+ },
"d": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz",
@@ -1741,6 +1783,40 @@
"assert-plus": "^1.0.0"
}
},
+ "data-urls": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.1.tgz",
+ "integrity": "sha512-Ds554NeT5Gennfoo9KN50Vh6tpgtvYEwraYjejXnyTpu1C7oXKxdFk75REooENHE8ndTVOJuv+BEs4/J/xcozw==",
+ "requires": {
+ "abab": "^2.0.3",
+ "whatwg-mimetype": "^3.0.0",
+ "whatwg-url": "^10.0.0"
+ },
+ "dependencies": {
+ "tr46": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
+ "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
+ "requires": {
+ "punycode": "^2.1.1"
+ }
+ },
+ "webidl-conversions": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="
+ },
+ "whatwg-url": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-10.0.0.tgz",
+ "integrity": "sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w==",
+ "requires": {
+ "tr46": "^3.0.0",
+ "webidl-conversions": "^7.0.0"
+ }
+ }
+ }
+ },
"date-and-time": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/date-and-time/-/date-and-time-2.0.1.tgz",
@@ -1755,6 +1831,11 @@
"ms": "2.1.2"
}
},
+ "decimal.js": {
+ "version": "10.3.1",
+ "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz",
+ "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ=="
+ },
"decode-uri-component": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
@@ -1771,8 +1852,7 @@
"deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
- "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
- "dev": true
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
},
"defer-to-connect": {
"version": "1.1.3",
@@ -1843,6 +1923,21 @@
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.2.tgz",
"integrity": "sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w=="
},
+ "domexception": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz",
+ "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==",
+ "requires": {
+ "webidl-conversions": "^7.0.0"
+ },
+ "dependencies": {
+ "webidl-conversions": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="
+ }
+ }
+ },
"dot-prop": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
@@ -2026,6 +2121,66 @@
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
"dev": true
},
+ "escodegen": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz",
+ "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==",
+ "requires": {
+ "esprima": "^4.0.1",
+ "estraverse": "^5.2.0",
+ "esutils": "^2.0.2",
+ "optionator": "^0.8.1",
+ "source-map": "~0.6.1"
+ },
+ "dependencies": {
+ "estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="
+ },
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "requires": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ }
+ },
+ "optionator": {
+ "version": "0.8.3",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
+ "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+ "requires": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.6",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "word-wrap": "~1.2.3"
+ }
+ },
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "optional": true
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "requires": {
+ "prelude-ls": "~1.1.2"
+ }
+ }
+ }
+ },
"eslint": {
"version": "7.32.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-7.32.0.tgz",
@@ -2146,8 +2301,7 @@
"esprima": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
- "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
- "dev": true
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
},
"esquery": {
"version": "1.4.0",
@@ -2192,8 +2346,7 @@
"esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
- "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
- "dev": true
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
},
"etag": {
"version": "1.8.1",
@@ -2422,8 +2575,7 @@
"fast-levenshtein": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
- "dev": true
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
},
"fast-text-encoding": {
"version": "1.0.3",
@@ -2478,9 +2630,9 @@
}
},
"firebase-admin": {
- "version": "9.12.0",
- "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-9.12.0.tgz",
- "integrity": "sha512-AtA7OH5RbIFGoc0gZOQgaYC6cdjdhZv4w3XgWoupkPKO1HY+0GzixOuXDa75kFeoVyhIyo4PkLg/GAC1dC1P6w==",
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/firebase-admin/-/firebase-admin-10.0.0.tgz",
+ "integrity": "sha512-EOAk5ZaqXhBBvx9ZyXd28kw8glMTt3xl0g3BepGRCy0RSSUPGOzfAqjGhc65guSKgFOpT5mAUycYcJbqullKUQ==",
"requires": {
"@firebase/database-compat": "^0.1.1",
"@firebase/database-types": "^0.7.2",
@@ -2732,9 +2884,9 @@
}
},
"google-auth-library": {
- "version": "7.10.0",
- "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.10.0.tgz",
- "integrity": "sha512-ICsqaU+lxMHVlDUzMrfVIEqnARw2AwBiZ/2KnNM6BcTf9Nott+Af87DTIzmlnW865p3REUP2MVL0xkPC3a61aQ==",
+ "version": "7.10.1",
+ "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-7.10.1.tgz",
+ "integrity": "sha512-nQxgM1ZopUMcpMnu95kOSzI+9tJl4YDOZJomSTBGlRLpxfBopdwto7WvzoI87HuN0nQqVETgOsHi/C/po1rppA==",
"optional": true,
"requires": {
"arrify": "^2.0.0",
@@ -2749,12 +2901,12 @@
}
},
"google-gax": {
- "version": "2.27.1",
- "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.27.1.tgz",
- "integrity": "sha512-8j8hfY42mGZt52C1L23srr2WTxOsOGUsC3s07Aw/f1UrbofsHdRaGf72Jax4jWEFXe/2x1MVBkwMvZxHMbO1Ag==",
+ "version": "2.28.0",
+ "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-2.28.0.tgz",
+ "integrity": "sha512-kuqc8a4+CTCMBcF3tlOL7Sa74JWkTzcZxatAQTCVK35WToXkHnJ0qncFOJuegUv3EbV9IQY4j/+NZdFLv+lbTA==",
"optional": true,
"requires": {
- "@grpc/grpc-js": "~1.3.0",
+ "@grpc/grpc-js": "~1.4.0",
"@grpc/proto-loader": "^0.6.1",
"@types/long": "^4.0.0",
"abort-controller": "^3.0.0",
@@ -2916,6 +3068,14 @@
"minimalistic-crypto-utils": "^1.0.1"
}
},
+ "html-encoding-sniffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz",
+ "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==",
+ "requires": {
+ "whatwg-encoding": "^2.0.0"
+ }
+ },
"http-cache-semantics": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
@@ -2954,7 +3114,6 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
"integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
- "optional": true,
"requires": {
"@tootallnate/once": "2",
"agent-base": "6",
@@ -2975,7 +3134,6 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz",
"integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==",
- "optional": true,
"requires": {
"agent-base": "6",
"debug": "4"
@@ -3166,6 +3324,11 @@
"resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
"integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4="
},
+ "is-potential-custom-element-name": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz",
+ "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ=="
+ },
"is-regex": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz",
@@ -3292,6 +3455,94 @@
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
},
+ "jsdom": {
+ "version": "18.0.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-18.0.0.tgz",
+ "integrity": "sha512-HVLuBcFmwdWulStv5U+J59b1AyzXhM92KXlM8HQ3ecYtRM2OQEUCPMa4oNuDeCBmtRcC7tJvb0Xz5OeFXMOKTA==",
+ "requires": {
+ "abab": "^2.0.5",
+ "acorn": "^8.5.0",
+ "acorn-globals": "^6.0.0",
+ "cssom": "^0.5.0",
+ "cssstyle": "^2.3.0",
+ "data-urls": "^3.0.1",
+ "decimal.js": "^10.3.1",
+ "domexception": "^4.0.0",
+ "escodegen": "^2.0.0",
+ "form-data": "^4.0.0",
+ "html-encoding-sniffer": "^3.0.0",
+ "http-proxy-agent": "^5.0.0",
+ "https-proxy-agent": "^5.0.0",
+ "is-potential-custom-element-name": "^1.0.1",
+ "nwsapi": "^2.2.0",
+ "parse5": "6.0.1",
+ "saxes": "^5.0.1",
+ "symbol-tree": "^3.2.4",
+ "tough-cookie": "^4.0.0",
+ "w3c-hr-time": "^1.0.2",
+ "w3c-xmlserializer": "^3.0.0",
+ "webidl-conversions": "^7.0.0",
+ "whatwg-encoding": "^2.0.0",
+ "whatwg-mimetype": "^3.0.0",
+ "whatwg-url": "^10.0.0",
+ "ws": "^8.2.3",
+ "xml-name-validator": "^4.0.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.5.0.tgz",
+ "integrity": "sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q=="
+ },
+ "form-data": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
+ "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "tough-cookie": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz",
+ "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==",
+ "requires": {
+ "psl": "^1.1.33",
+ "punycode": "^2.1.1",
+ "universalify": "^0.1.2"
+ }
+ },
+ "tr46": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz",
+ "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==",
+ "requires": {
+ "punycode": "^2.1.1"
+ }
+ },
+ "webidl-conversions": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
+ "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g=="
+ },
+ "whatwg-url": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-10.0.0.tgz",
+ "integrity": "sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w==",
+ "requires": {
+ "tr46": "^3.0.0",
+ "webidl-conversions": "^7.0.0"
+ }
+ },
+ "ws": {
+ "version": "8.2.3",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz",
+ "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA=="
+ }
+ }
+ },
"jsesc": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
@@ -3416,9 +3667,9 @@
}
},
"jwks-rsa": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.0.4.tgz",
- "integrity": "sha512-iJqVCECYZZ+3oPmY1qXv3Fq+3ywDtuNEVBvG41pPlaR0zyGxa12nC0beAOBBUhETJmc05puS50mRQN4NkCGhmg==",
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/jwks-rsa/-/jwks-rsa-2.0.5.tgz",
+ "integrity": "sha512-fliHfsiBRzEU0nXzSvwnh0hynzGB0WihF+CinKbSRlaqRxbqqKf2xbBPgwc8mzf18/WgwlG8e5eTpfSTBcU4DQ==",
"requires": {
"@types/express-jwt": "0.0.42",
"debug": "^4.3.2",
@@ -3833,6 +4084,11 @@
}
}
},
+ "nwsapi": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz",
+ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ=="
+ },
"oauth-sign": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
@@ -3961,6 +4217,11 @@
"resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.4.tgz",
"integrity": "sha512-psZ9iZoCNFLrgRjZ1d8mn0h9WRqJwFxM9q3x7iUjN/YT2OksthDJ5TiPCu2F38kS4zutqfW+YdVVkBZZx3/1aw=="
},
+ "parse5": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw=="
+ },
"parseurl": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
@@ -4034,9 +4295,9 @@
"dev": true
},
"proto3-json-serializer": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-0.1.4.tgz",
- "integrity": "sha512-bFzdsKU/zaTobWrRxRniMZIzzcgKYlmBWL1gAcTXZ2M7TQTGPI0JoYYs6bN7tpWj59ZCfwg7Ii/A2e8BbQGYnQ==",
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-0.1.5.tgz",
+ "integrity": "sha512-G395jcZkgNXNeS+6FGqd09TsXeoCs9wmBWByDiwFy7Yd7HD8pyfyvf6q+rGh7PhT4AshRpG4NowzoKYUtkNjKg==",
"optional": true
},
"protobufjs": {
@@ -4310,6 +4571,14 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
+ "saxes": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz",
+ "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==",
+ "requires": {
+ "xmlchars": "^2.2.0"
+ }
+ },
"scrypt-js": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/scrypt-js/-/scrypt-js-3.0.1.tgz",
@@ -4682,6 +4951,11 @@
}
}
},
+ "symbol-tree": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz",
+ "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw=="
+ },
"table": {
"version": "6.7.2",
"resolved": "https://registry.npmjs.org/table/-/table-6.7.2.tgz",
@@ -4984,6 +5258,22 @@
"extsprintf": "^1.2.0"
}
},
+ "w3c-hr-time": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz",
+ "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==",
+ "requires": {
+ "browser-process-hrtime": "^1.0.0"
+ }
+ },
+ "w3c-xmlserializer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz",
+ "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==",
+ "requires": {
+ "xml-name-validator": "^4.0.0"
+ }
+ },
"web3": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/web3/-/web3-1.6.0.tgz",
@@ -5321,6 +5611,29 @@
"resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz",
"integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg=="
},
+ "whatwg-encoding": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz",
+ "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==",
+ "requires": {
+ "iconv-lite": "0.6.3"
+ },
+ "dependencies": {
+ "iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ }
+ }
+ }
+ },
+ "whatwg-mimetype": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz",
+ "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q=="
+ },
"whatwg-url": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
@@ -5368,8 +5681,7 @@
"word-wrap": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
- "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
- "dev": true
+ "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ=="
},
"wrap-ansi": {
"version": "7.0.0",
@@ -5463,6 +5775,16 @@
"cookiejar": "^2.1.1"
}
},
+ "xml-name-validator": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz",
+ "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw=="
+ },
+ "xmlchars": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz",
+ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw=="
+ },
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
diff --git a/functions/package.json b/functions/package.json
index 3dc89fb..3a695af 100644
--- a/functions/package.json
+++ b/functions/package.json
@@ -16,8 +16,9 @@
"dependencies": {
"cors": "^2.8.5",
"express": "^4.17.1",
- "firebase-admin": "^9.12.0",
+ "firebase-admin": "^10.0.0",
"firebase-functions": "^3.11.0",
+ "jsdom": "^18.0.0",
"random-name": "^0.1.2",
"web3": "^1.6.0"
},
diff --git a/storage.rules b/storage.rules
index 4eda34f..e71cf62 100644
--- a/storage.rules
+++ b/storage.rules
@@ -2,7 +2,8 @@ rules_version = '2';
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
- allow read, write: if request.auth!=null;
+ allow write: if request.auth!=null;
+ allow read: if true;
}
}
}