main #21

Merged
VPhung24 merged 3 commits from snowball/testnet-onboarding-app:main into main 2024-08-09 00:58:46 +00:00
15 changed files with 441 additions and 148 deletions

View File

@ -1,40 +1,42 @@
# testnet-onboarding-app
React app for onboarding participants to laconicd chain with Nitro/Cosmos key attestation
## Setup for testnet-onboarding-app
1. Clone the repository
```
```zsh
git clone git@git.vdb.to:cerc-io/testnet-onboarding-app.git
```
2. Enter the project directory
```
```zsh
cd testnet-onboarding-app
```
3. Install dependencies
```
```zsh
yarn
```
4. Setup .env
- Copy and update `.env`
```
```zsh
cp .env.example .env
```
- In the `.env` file, add the WalletConnect project ID used in your [laconic-wallet](https://git.vdb.to/cerc-io/laconic-wallet) setup.
```
```zsh
WALLET_CONNECT_PROJECT_ID=39bc93c...
```
5. Start the application
```
```zsh
yarn start
```

View File

@ -1,56 +1,56 @@
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const resolve = require('resolve');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');
const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
const ESLintPlugin = require('eslint-webpack-plugin');
const paths = require('./paths');
const modules = require('./modules');
const getClientEnvironment = require('./env');
const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin');
const fs = require("fs");
const path = require("path");
const webpack = require("webpack");
const resolve = require("resolve");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const CaseSensitivePathsPlugin = require("case-sensitive-paths-webpack-plugin");
const InlineChunkHtmlPlugin = require("react-dev-utils/InlineChunkHtmlPlugin");
const TerserPlugin = require("terser-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const { WebpackManifestPlugin } = require("webpack-manifest-plugin");
const InterpolateHtmlPlugin = require("react-dev-utils/InterpolateHtmlPlugin");
const WorkboxWebpackPlugin = require("workbox-webpack-plugin");
const ModuleScopePlugin = require("react-dev-utils/ModuleScopePlugin");
const getCSSModuleLocalIdent = require("react-dev-utils/getCSSModuleLocalIdent");
const ESLintPlugin = require("eslint-webpack-plugin");
const paths = require("./paths");
const modules = require("./modules");
const getClientEnvironment = require("./env");
const ModuleNotFoundPlugin = require("react-dev-utils/ModuleNotFoundPlugin");
const ForkTsCheckerWebpackPlugin =
process.env.TSC_COMPILE_ON_ERROR === 'true'
? require('react-dev-utils/ForkTsCheckerWarningWebpackPlugin')
: require('react-dev-utils/ForkTsCheckerWebpackPlugin');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
process.env.TSC_COMPILE_ON_ERROR === "true"
? require("react-dev-utils/ForkTsCheckerWarningWebpackPlugin")
: require("react-dev-utils/ForkTsCheckerWebpackPlugin");
const ReactRefreshWebpackPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
const createEnvironmentHash = require('./webpack/persistentCache/createEnvironmentHash');
const createEnvironmentHash = require("./webpack/persistentCache/createEnvironmentHash");
// Source maps are resource heavy and can cause out of memory issue for large source files.
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== "false";
const reactRefreshRuntimeEntry = require.resolve('react-refresh/runtime');
const reactRefreshRuntimeEntry = require.resolve("react-refresh/runtime");
const reactRefreshWebpackPluginRuntimeEntry = require.resolve(
'@pmmmwh/react-refresh-webpack-plugin'
"@pmmmwh/react-refresh-webpack-plugin"
);
const babelRuntimeEntry = require.resolve('babel-preset-react-app');
const babelRuntimeEntry = require.resolve("babel-preset-react-app");
const babelRuntimeEntryHelpers = require.resolve(
'@babel/runtime/helpers/esm/assertThisInitialized',
"@babel/runtime/helpers/esm/assertThisInitialized",
{ paths: [babelRuntimeEntry] }
);
const babelRuntimeRegenerator = require.resolve('@babel/runtime/regenerator', {
const babelRuntimeRegenerator = require.resolve("@babel/runtime/regenerator", {
paths: [babelRuntimeEntry],
});
// Some apps do not need the benefits of saving a web request, so not inlining the chunk
// makes for a smoother build process.
const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false';
const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== "false";
const emitErrorsAsWarnings = process.env.ESLINT_NO_DEV_ERRORS === 'true';
const disableESLintPlugin = process.env.DISABLE_ESLINT_PLUGIN === 'true';
const emitErrorsAsWarnings = process.env.ESLINT_NO_DEV_ERRORS === "true";
const disableESLintPlugin = process.env.DISABLE_ESLINT_PLUGIN === "true";
const imageInlineSizeLimit = parseInt(
process.env.IMAGE_INLINE_SIZE_LIMIT || '10000'
process.env.IMAGE_INLINE_SIZE_LIMIT || "10000"
);
// Check if TypeScript is setup
@ -58,7 +58,7 @@ const useTypeScript = fs.existsSync(paths.appTsConfig);
// Check if Tailwind config exists
const useTailwind = fs.existsSync(
path.join(paths.appPath, 'tailwind.config.js')
path.join(paths.appPath, "tailwind.config.ts")
);
// Get the path to the uncompiled service worker (if it exists).
@ -71,12 +71,12 @@ const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
const hasJsxRuntime = (() => {
if (process.env.DISABLE_NEW_JSX_TRANSFORM === 'true') {
if (process.env.DISABLE_NEW_JSX_TRANSFORM === "true") {
return false;
}
try {
require.resolve('react/jsx-runtime');
require.resolve("react/jsx-runtime");
return true;
} catch (e) {
return false;
@ -86,13 +86,13 @@ const hasJsxRuntime = (() => {
// This is the production and development configuration.
// It is focused on developer experience, fast rebuilds, and a minimal bundle.
module.exports = function (webpackEnv) {
const isEnvDevelopment = webpackEnv === 'development';
const isEnvProduction = webpackEnv === 'production';
const isEnvDevelopment = webpackEnv === "development";
const isEnvProduction = webpackEnv === "production";
// Variable used for enabling profiling in Production
// passed into alias object. Uses a flag if passed into the build command
const isEnvProductionProfile =
isEnvProduction && process.argv.includes('--profile');
isEnvProduction && process.argv.includes("--profile");
// We will provide `paths.publicUrlOrPath` to our app
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
@ -105,38 +105,38 @@ module.exports = function (webpackEnv) {
// common function to get style loaders
const getStyleLoaders = (cssOptions, preProcessor) => {
const loaders = [
isEnvDevelopment && require.resolve('style-loader'),
isEnvDevelopment && require.resolve("style-loader"),
isEnvProduction && {
loader: MiniCssExtractPlugin.loader,
// css is located in `static/css`, use '../../' to locate index.html folder
// in production `paths.publicUrlOrPath` can be a relative path
options: paths.publicUrlOrPath.startsWith('.')
? { publicPath: '../../' }
options: paths.publicUrlOrPath.startsWith(".")
? { publicPath: "../../" }
: {},
},
{
loader: require.resolve('css-loader'),
loader: require.resolve("css-loader"),
options: cssOptions,
},
{
// Options for PostCSS as we reference these options twice
// Adds vendor prefixing based on your specified browser support in
// package.json
loader: require.resolve('postcss-loader'),
loader: require.resolve("postcss-loader"),
options: {
postcssOptions: {
// Necessary for external CSS imports to work
// https://github.com/facebook/create-react-app/issues/2677
ident: 'postcss',
ident: "postcss",
config: false,
plugins: !useTailwind
? [
'postcss-flexbugs-fixes',
"postcss-flexbugs-fixes",
[
'postcss-preset-env',
"postcss-preset-env",
{
autoprefixer: {
flexbox: 'no-2009',
flexbox: "no-2009",
},
stage: 3,
},
@ -144,16 +144,16 @@ module.exports = function (webpackEnv) {
// Adds PostCSS Normalize as the reset css with default options,
// so that it honors browserslist config in package.json
// which in turn let's users customize the target behavior as per their needs.
'postcss-normalize',
"postcss-normalize",
]
: [
'tailwindcss',
'postcss-flexbugs-fixes',
"tailwindcss",
"postcss-flexbugs-fixes",
[
'postcss-preset-env',
"postcss-preset-env",
{
autoprefixer: {
flexbox: 'no-2009',
flexbox: "no-2009",
},
stage: 3,
},
@ -167,7 +167,7 @@ module.exports = function (webpackEnv) {
if (preProcessor) {
loaders.push(
{
loader: require.resolve('resolve-url-loader'),
loader: require.resolve("resolve-url-loader"),
options: {
sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
root: paths.appSrc,
@ -185,17 +185,17 @@ module.exports = function (webpackEnv) {
};
return {
target: ['browserslist'],
target: ["browserslist"],
// Webpack noise constrained to errors and warnings
stats: 'errors-warnings',
mode: isEnvProduction ? 'production' : isEnvDevelopment && 'development',
stats: "errors-warnings",
mode: isEnvProduction ? "production" : isEnvDevelopment && "development",
// Stop compilation early in production
bail: isEnvProduction,
devtool: isEnvProduction
? shouldUseSourceMap
? 'source-map'
? "source-map"
: false
: isEnvDevelopment && 'cheap-module-source-map',
: isEnvDevelopment && "cheap-module-source-map",
// These are the "entry points" to our application.
// This means they will be the "root" imports that are included in JS bundle.
entry: paths.appIndexJs,
@ -207,41 +207,42 @@ module.exports = function (webpackEnv) {
// There will be one main bundle, and one file per asynchronous chunk.
// In development, it does not produce real files.
filename: isEnvProduction
? 'static/js/[name].[contenthash:8].js'
: isEnvDevelopment && 'static/js/bundle.js',
? "static/js/[name].[contenthash:8].js"
: isEnvDevelopment && "static/js/bundle.js",
// There are also additional JS chunk files if you use code splitting.
chunkFilename: isEnvProduction
? 'static/js/[name].[contenthash:8].chunk.js'
: isEnvDevelopment && 'static/js/[name].chunk.js',
assetModuleFilename: 'static/media/[name].[hash][ext]',
? "static/js/[name].[contenthash:8].chunk.js"
: isEnvDevelopment && "static/js/[name].chunk.js",
assetModuleFilename: "static/media/[name].[hash][ext]",
// webpack uses `publicPath` to determine where the app is being served from.
// It requires a trailing slash, or the file assets will get an incorrect path.
// We inferred the "public path" (such as / or /my-project) from homepage.
publicPath: paths.publicUrlOrPath,
// Point sourcemap entries to original disk location (format as URL on Windows)
devtoolModuleFilenameTemplate: isEnvProduction
? info =>
? (info) =>
path
.relative(paths.appSrc, info.absoluteResourcePath)
.replace(/\\/g, '/')
.replace(/\\/g, "/")
: isEnvDevelopment &&
(info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')),
((info) =>
path.resolve(info.absoluteResourcePath).replace(/\\/g, "/")),
},
cache: {
type: 'filesystem',
type: "filesystem",
version: createEnvironmentHash(env.raw),
cacheDirectory: paths.appWebpackCache,
store: 'pack',
store: "pack",
buildDependencies: {
defaultWebpack: ['webpack/lib/'],
defaultWebpack: ["webpack/lib/"],
config: [__filename],
tsconfig: [paths.appTsConfig, paths.appJsConfig].filter(f =>
tsconfig: [paths.appTsConfig, paths.appJsConfig].filter((f) =>
fs.existsSync(f)
),
},
},
infrastructureLogging: {
level: 'none',
level: "none",
},
optimization: {
minimize: isEnvProduction,
@ -312,16 +313,16 @@ module.exports = function (webpackEnv) {
// `web` extension prefixes have been added for better support
// for React Native Web.
extensions: paths.moduleFileExtensions
.map(ext => `.${ext}`)
.filter(ext => useTypeScript || !ext.includes('ts')),
.map((ext) => `.${ext}`)
.filter((ext) => useTypeScript || !ext.includes("ts")),
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-native': 'react-native-web',
"react-native": "react-native-web",
// Allows for better profiling with ReactDevTools
...(isEnvProductionProfile && {
'react-dom$': 'react-dom/profiling',
'scheduler/tracing': 'scheduler/tracing-profiling',
"react-dom$": "react-dom/profiling",
"scheduler/tracing": "scheduler/tracing-profiling",
}),
...(modules.webpackAliases || {}),
},
@ -346,10 +347,10 @@ module.exports = function (webpackEnv) {
rules: [
// Handle node_modules packages that contain sourcemaps
shouldUseSourceMap && {
enforce: 'pre',
enforce: "pre",
exclude: /@babel(?:\/|\\{1,2})runtime/,
test: /\.(js|mjs|jsx|ts|tsx|css)$/,
loader: require.resolve('source-map-loader'),
loader: require.resolve("source-map-loader"),
},
{
// "oneOf" will traverse all following loaders until one will
@ -360,8 +361,8 @@ module.exports = function (webpackEnv) {
// https://github.com/jshttp/mime-db
{
test: [/\.avif$/],
type: 'asset',
mimetype: 'image/avif',
type: "asset",
mimetype: "image/avif",
parser: {
dataUrlCondition: {
maxSize: imageInlineSizeLimit,
@ -373,7 +374,7 @@ module.exports = function (webpackEnv) {
// A missing `test` is equivalent to a match.
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
type: 'asset',
type: "asset",
parser: {
dataUrlCondition: {
maxSize: imageInlineSizeLimit,
@ -384,7 +385,7 @@ module.exports = function (webpackEnv) {
test: /\.svg$/,
use: [
{
loader: require.resolve('@svgr/webpack'),
loader: require.resolve("@svgr/webpack"),
options: {
prettier: false,
svgo: false,
@ -396,9 +397,9 @@ module.exports = function (webpackEnv) {
},
},
{
loader: require.resolve('file-loader'),
loader: require.resolve("file-loader"),
options: {
name: 'static/media/[name].[hash].[ext]',
name: "static/media/[name].[hash].[ext]",
},
},
],
@ -411,16 +412,16 @@ module.exports = function (webpackEnv) {
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: paths.appSrc,
loader: require.resolve('babel-loader'),
loader: require.resolve("babel-loader"),
options: {
customize: require.resolve(
'babel-preset-react-app/webpack-overrides'
"babel-preset-react-app/webpack-overrides"
),
presets: [
[
require.resolve('babel-preset-react-app'),
require.resolve("babel-preset-react-app"),
{
runtime: hasJsxRuntime ? 'automatic' : 'classic',
runtime: hasJsxRuntime ? "automatic" : "classic",
},
],
],
@ -428,7 +429,7 @@ module.exports = function (webpackEnv) {
plugins: [
isEnvDevelopment &&
shouldUseReactRefresh &&
require.resolve('react-refresh/babel'),
require.resolve("react-refresh/babel"),
].filter(Boolean),
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
@ -444,14 +445,14 @@ module.exports = function (webpackEnv) {
{
test: /\.(js|mjs)$/,
exclude: /@babel(?:\/|\\{1,2})runtime/,
loader: require.resolve('babel-loader'),
loader: require.resolve("babel-loader"),
options: {
babelrc: false,
configFile: false,
compact: false,
presets: [
[
require.resolve('babel-preset-react-app/dependencies'),
require.resolve("babel-preset-react-app/dependencies"),
{ helpers: true },
],
],
@ -482,7 +483,7 @@ module.exports = function (webpackEnv) {
? shouldUseSourceMap
: isEnvDevelopment,
modules: {
mode: 'icss',
mode: "icss",
},
}),
// Don't consider CSS imports dead code even if the
@ -501,7 +502,7 @@ module.exports = function (webpackEnv) {
? shouldUseSourceMap
: isEnvDevelopment,
modules: {
mode: 'local',
mode: "local",
getLocalIdent: getCSSModuleLocalIdent,
},
}),
@ -519,10 +520,10 @@ module.exports = function (webpackEnv) {
? shouldUseSourceMap
: isEnvDevelopment,
modules: {
mode: 'icss',
mode: "icss",
},
},
'sass-loader'
"sass-loader"
),
// Don't consider CSS imports dead code even if the
// containing package claims to have no side effects.
@ -541,11 +542,11 @@ module.exports = function (webpackEnv) {
? shouldUseSourceMap
: isEnvDevelopment,
modules: {
mode: 'local',
mode: "local",
getLocalIdent: getCSSModuleLocalIdent,
},
},
'sass-loader'
"sass-loader"
),
},
// "file" loader makes sure those assets get served by WebpackDevServer.
@ -559,7 +560,7 @@ module.exports = function (webpackEnv) {
// Also exclude `html` and `json` extensions so they get processed
// by webpacks internal loaders.
exclude: [/^$/, /\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
type: 'asset/resource',
type: "asset/resource",
},
// ** STOP ** Are you adding a new loader?
// Make sure to add the new loader(s) before the "file" loader.
@ -633,8 +634,8 @@ module.exports = function (webpackEnv) {
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: 'static/css/[name].[contenthash:8].css',
chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
filename: "static/css/[name].[contenthash:8].css",
chunkFilename: "static/css/[name].[contenthash:8].chunk.css",
}),
// Generate an asset manifest file with the following content:
// - "files" key: Mapping of all asset filenames to their corresponding
@ -643,7 +644,7 @@ module.exports = function (webpackEnv) {
// - "entrypoints" key: Array of files which are included in `index.html`,
// can be used to reconstruct the HTML if necessary
new WebpackManifestPlugin({
fileName: 'asset-manifest.json',
fileName: "asset-manifest.json",
publicPath: paths.publicUrlOrPath,
generate: (seed, files, entrypoints) => {
const manifestFiles = files.reduce((manifest, file) => {
@ -651,7 +652,7 @@ module.exports = function (webpackEnv) {
return manifest;
}, seed);
const entrypointFiles = entrypoints.main.filter(
fileName => !fileName.endsWith('.map')
(fileName) => !fileName.endsWith(".map")
);
return {
@ -687,7 +688,7 @@ module.exports = function (webpackEnv) {
new ForkTsCheckerWebpackPlugin({
async: isEnvDevelopment,
typescript: {
typescriptPath: resolve.sync('typescript', {
typescriptPath: resolve.sync("typescript", {
basedir: paths.appNodeModules,
}),
configOverwrite: {
@ -707,7 +708,7 @@ module.exports = function (webpackEnv) {
diagnosticOptions: {
syntactic: true,
},
mode: 'write-references',
mode: "write-references",
// profile: true,
},
issue: {
@ -716,41 +717,41 @@ module.exports = function (webpackEnv) {
// '../cra-template-typescript/template/src/App.tsx'
// otherwise.
include: [
{ file: '../**/src/**/*.{ts,tsx}' },
{ file: '**/src/**/*.{ts,tsx}' },
{ file: "../**/src/**/*.{ts,tsx}" },
{ file: "**/src/**/*.{ts,tsx}" },
],
exclude: [
{ file: '**/src/**/__tests__/**' },
{ file: '**/src/**/?(*.){spec|test}.*' },
{ file: '**/src/setupProxy.*' },
{ file: '**/src/setupTests.*' },
{ file: "**/src/**/__tests__/**" },
{ file: "**/src/**/?(*.){spec|test}.*" },
{ file: "**/src/setupProxy.*" },
{ file: "**/src/setupTests.*" },
],
},
logger: {
infrastructure: 'silent',
infrastructure: "silent",
},
}),
!disableESLintPlugin &&
new ESLintPlugin({
// Plugin options
extensions: ['js', 'mjs', 'jsx', 'ts', 'tsx'],
formatter: require.resolve('react-dev-utils/eslintFormatter'),
eslintPath: require.resolve('eslint'),
extensions: ["js", "mjs", "jsx", "ts", "tsx"],
formatter: require.resolve("react-dev-utils/eslintFormatter"),
eslintPath: require.resolve("eslint"),
failOnError: !(isEnvDevelopment && emitErrorsAsWarnings),
context: paths.appSrc,
cache: true,
cacheLocation: path.resolve(
paths.appNodeModules,
'.cache/.eslintcache'
".cache/.eslintcache"
),
// ESLint class options
cwd: paths.appPath,
resolvePluginsRelativeTo: __dirname,
baseConfig: {
extends: [require.resolve('eslint-config-react-app/base')],
extends: [require.resolve("eslint-config-react-app/base")],
rules: {
...(!hasJsxRuntime && {
'react/react-in-jsx-scope': 'error',
"react/react-in-jsx-scope": "error",
}),
},
},

View File

@ -33,7 +33,7 @@
"resolve": "^1.20.0",
"semver": "^7.3.5",
"stream-browserify": "^3.0.0",
"tailwindcss": "^3.0.2",
"tailwindcss": "^3.4.9",
"typescript": "^4.9.5"
},
"scripts": {
@ -66,8 +66,10 @@
"@types/node": "^16.18.90",
"@types/react": "^18.2.67",
"@types/react-dom": "^18.2.22",
"@types/tailwindcss": "^3.1.0",
"@typescript-eslint/eslint-plugin": "^6.13.2",
"@typescript-eslint/parser": "^6.13.2",
"autoprefixer": "^10.4.20",
"babel-jest": "^27.4.2",
"babel-loader": "^8.2.3",
"babel-plugin-named-asset-import": "^0.3.8",
@ -92,7 +94,7 @@
"jest-resolve": "^27.4.2",
"jest-watch-typeahead": "^1.0.0",
"mini-css-extract-plugin": "^2.4.5",
"postcss": "^8.4.4",
"postcss": "^8.4.41",
"postcss-flexbugs-fixes": "^5.0.2",
"postcss-loader": "^6.2.1",
"postcss-normalize": "^10.0.1",

6
postcss.config.js Normal file
View File

@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

3
public/laconic_logo.svg Normal file
View File

@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.04924 12.6164C6.84238 9.85387 8.57128 6.03867 8.57051 1.82634C8.57154 1.25458 8.53962 0.689188 8.47618 0.130795L0 0.131558L0.000257231 16.2401C-0.000514887 18.1926 0.75217 20.1458 2.25767 21.6349C3.7633 23.124 5.73941 23.8693 7.71384 23.8683L7.71333 23.8688L24 23.8692L23.9994 15.4843C23.4361 15.4228 22.8645 15.3911 22.2851 15.391C18.0274 15.3915 14.17 17.1014 11.3769 19.864C9.34443 21.8239 6.08571 21.8243 4.07833 19.8388C2.07224 17.8545 2.07133 14.6303 4.04924 12.6164ZM22.2419 1.87395C19.9011 -0.441217 16.0981 -0.442108 13.7566 1.87395C11.415 4.18987 11.4159 7.95136 13.7566 10.2664C16.0985 12.5828 19.9003 12.5825 22.2419 10.2664C24.5835 7.95047 24.5838 4.19026 22.2419 1.87395Z" fill="#FBFBFB"/>
</svg>

After

Width:  |  Height:  |  Size: 859 B

View File

@ -0,0 +1,10 @@
<svg width="117" height="21" viewBox="0 0 117 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.22282 11.0194C6.57609 8.69185 8.03272 5.47748 8.03206 1.92852C8.03293 1.44681 8.00604 0.970455 7.95259 0.499999L0.811272 0.500642L0.811488 14.0723C0.810838 15.7174 1.44499 17.3629 2.7134 18.6175C3.98191 19.8721 5.64682 20.5001 7.31031 20.4992L7.30988 20.4997L21.0317 20.5L21.0311 13.4355C20.5566 13.3838 20.075 13.357 19.5869 13.3569C15.9997 13.3574 12.7498 14.798 10.3965 17.1255C8.6841 18.7768 5.93858 18.7771 4.24733 17.1043C2.55716 15.4325 2.5564 12.7161 4.22282 11.0194ZM19.5504 1.96863C17.5783 0.0180696 14.3742 0.017319 12.4014 1.96863C10.4286 3.91984 10.4293 7.08895 12.4014 9.03941C14.3745 10.991 17.5776 10.9907 19.5504 9.03941C21.5232 7.0882 21.5236 3.92016 19.5504 1.96863Z" fill="#FBFBFB"/>
<path d="M32.6326 19.0836H40.4995V16.83H35.2622V1.91329H32.6326V19.0836Z" fill="#FBFBFB"/>
<path d="M51.1715 1.91329H46.8108L42.2528 19.0836H44.97L46.1095 14.791H51.7413L52.8808 19.0836H55.7295L51.1715 1.91329ZM46.6574 12.6448L48.9363 3.75909H49.024L51.2153 12.6448H46.6574Z" fill="#FBFBFB"/>
<path d="M64.4348 8.56823H67.5027C67.5027 3.67471 65.903 1.57134 62.1777 1.57134C58.2552 1.57134 56.5679 4.23278 56.5679 10.4785C56.5679 16.7456 58.2552 19.4285 62.1777 19.4285C65.903 19.4285 67.5027 17.3895 67.5246 12.6462H64.4567C64.4348 16.3593 63.9746 17.2822 62.1777 17.2822C60.1179 17.2822 59.6138 15.93 59.6357 10.4785C59.6357 5.04833 60.1398 3.69616 62.1777 3.71761C63.9746 3.71761 64.4348 4.68351 64.4348 8.56823Z" fill="#FBFBFB"/>
<path d="M75.4027 1.57146C79.391 1.59302 81.1002 4.27581 81.1002 10.5C81.1002 16.7243 79.391 19.4072 75.4027 19.4286C71.3926 19.4501 69.6833 16.7672 69.6833 10.5C69.6833 4.23291 71.3926 1.55002 75.4027 1.57146ZM72.7512 10.5C72.7512 15.9302 73.2772 17.2823 75.4027 17.2823C77.5064 17.2823 78.0324 15.9302 78.0324 10.5C78.0324 5.04846 77.5064 3.69629 75.4027 3.71784C73.2772 3.73929 72.7512 5.09146 72.7512 10.5Z" fill="#FBFBFB"/>
<path d="M86.8315 19.0621L84.2019 19.0836V1.91329H88.8257L93.1427 15.9071H93.1865V1.91329H95.8156V19.0836H91.4773L86.8755 4.01667H86.8315V19.0621Z" fill="#FBFBFB"/>
<path d="M102.387 1.91329H99.7577V19.0836H102.387V1.91329Z" fill="#FBFBFB"/>
<path d="M113.176 8.56823H116.244C116.244 3.67471 114.644 1.57134 110.919 1.57134C106.997 1.57134 105.309 4.23278 105.309 10.4785C105.309 16.7456 106.997 19.4285 110.919 19.4285C114.644 19.4285 116.244 17.3895 116.266 12.6462H113.198C113.176 16.3593 112.716 17.2822 110.919 17.2822C108.859 17.2822 108.355 15.93 108.377 10.4785C108.377 5.04833 108.881 3.69616 110.919 3.71761C112.716 3.71761 113.176 4.68351 113.176 8.56823Z" fill="#FBFBFB"/>
</svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -15,6 +15,8 @@ import VerifyEmail from "./pages/VerifyEmail";
import Email from "./pages/Email";
import Thanks from "./pages/Thanks";
import "./App.css";
function App() {
return (
<Router>
@ -23,19 +25,13 @@ function App() {
<Routes>
<Route path="/" element={<TermsAndConditions />} />
<Route path="/verify-email" element={<VerifyEmail />} />
<Route path="/email" element={<Email/>} />
<Route path="/email" element={<Email />} />
<Route path="/connect-wallet" element={<ConnectWallet />} />
<Route path="/thanks" element={<Thanks />} />
<Route element={<SignPageLayout />}>
<Route path="/sign-with-nitro-key" element={<SignWithNitroKey />} />
<Route
path="/user-verification"
element={<UserVerification />}
/>
<Route
path="/sign-with-cosmos"
element={<SignWithCosmos />}
/>
<Route path="/user-verification" element={<UserVerification />} />
<Route path="/sign-with-cosmos" element={<SignWithCosmos />} />
<Route
path="/onboarding-success"
element={<OnboardingSuccess />}

View File

@ -0,0 +1,30 @@
import React, { ComponentPropsWithoutRef } from "react";
export interface CustomIconProps extends ComponentPropsWithoutRef<"svg"> {
size?: number | string; // width and height will both be set as the same value
name?: string;
}
export const CustomIcon: React.FC<CustomIconProps> = ({
children,
width = 24,
height = 24,
size,
viewBox = "0 0 24 24",
name,
...rest
}: CustomIconProps) => {
return (
<svg
aria-labelledby={name}
height={size || height}
role="presentation"
viewBox={viewBox}
width={size || width}
xmlns="http://www.w3.org/2000/svg"
{...rest}
>
{children}
</svg>
);
};

View File

@ -0,0 +1,78 @@
# CustomIcon
`CustomIcon` is a flexible and reusable React component for rendering SVG icons. It allows for easy customization of size, color, and other SVG properties.
- Viewbox "0 0 24 24": From where you're exporting from, please make sure the icon is using viewBox="0 0 24 24" before downloading/exporting. Not doing so will result in incorrect icon scaling
## Create a Custom Icon
1. Duplicate a current icon e.g. `LaconicIcon` and rename it accordingly.
2. Rename the function inside the new file you duplicated too
3. Replace the markup with your SVG markup (make sure it complies with the above section's rule)
4. Depending on the svg you pasted...
A. If the `<svg>` has only 1 child, remove the `<svg>` parent entirely so you only have the path left
B. If your component has more than 1 paths, rename `<svg>` tag with the `<g>` tag. Then, remove all attributes of this `<g>` tag so that it's just `<g>`
5. Usually, icons are single colored. If that's the case, replace all fill/stroke color with `currentColor`. E.g. `<path d="..." fill="currentColor">`. Leave the other attributes without removing them.
6. If your icon has more than one color, then it's up to you to decide whether we want to use tailwind to help set the fill and stroke colors
7. Lastly, export your icon in `index.ts` by following what was done for `LaconicIcon`
8. Make sure to provide a `name` for the `<CustomIcon>` component for accessibility
9. Done!
Example:
```tsx
import { CustomIcon, CustomIconProps } from "../CustomIcon";
export const LaconicIcon = (props: CustomIconProps) => {
return (
<CustomIcon
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
{...props}
>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M4.04924 12.6164C6.84238 9.85387 8.57128 6.03867 8.57051 1.82634C8.57154 1.25458 8.53962 0.689188 8.47618 0.130795L0 0.131558L0.000257231 16.2401C-0.000514887 18.1926 0.75217 20.1458 2.25767 21.6349C3.7633 23.124 5.73941 23.8693 7.71384 23.8683L7.71333 23.8688L24 23.8692L23.9994 15.4843C23.4361 15.4228 22.8645 15.3911 22.2851 15.391C18.0274 15.3915 14.17 17.1014 11.3769 19.864C9.34443 21.8239 6.08571 21.8243 4.07833 19.8388C2.07224 17.8545 2.07133 14.6303 4.04924 12.6164ZM22.2419 1.87395C19.9011 -0.441217 16.0981 -0.442108 13.7566 1.87395C11.415 4.18987 11.4159 7.95136 13.7566 10.2664C16.0985 12.5828 19.9003 12.5825 22.2419 10.2664C24.5835 7.95047 24.5838 4.19026 22.2419 1.87395Z"
fill="currentColor"
/>
</CustomIcon>
);
};
```
## Usage
```tsx
import { LaconicIcon } from './components/CustomIcon';
...
<LaconicIcon size={32} />
```
## Props
The `CustomIcon` component accepts the following props:
- `children`: SVG content (paths, groups, etc.)
- `size`: Sets both width and height (number or string)
- `width`: SVG width (default: 24)
- `height`: SVG height (default: 24)
- `viewBox`: SVG viewBox (default: "0 0 24 24")
- `name`: Icon name for accessibility (sets aria-labelledby)
- ...other SVG props
## Accessibility
Always provide a `name` prop to the CustomIcon for improved accessibility. This sets the `aria-labelledby` attribute on the SVG.
```tsx
<CustomIcon name="laconic-logo-icon">
{/* SVG content */}
</CustomIcon>
```
For icons that are purely decorative, the component sets `role="presentation"` by default.

View File

@ -0,0 +1,23 @@
import React from "react";
import { CustomIcon, CustomIconProps } from "../CustomIcon";
export const LaconicIcon: React.FC<CustomIconProps> = (props) => {
return (
<CustomIcon
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
name="laconic-logo-icon"
{...props}
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M4.04924 12.6164C6.84238 9.85387 8.57128 6.03867 8.57051 1.82634C8.57154 1.25458 8.53962 0.689188 8.47618 0.130795L0 0.131558L0.000257231 16.2401C-0.000514887 18.1926 0.75217 20.1458 2.25767 21.6349C3.7633 23.124 5.73941 23.8693 7.71384 23.8683L7.71333 23.8688L24 23.8692L23.9994 15.4843C23.4361 15.4228 22.8645 15.3911 22.2851 15.391C18.0274 15.3915 14.17 17.1014 11.3769 19.864C9.34443 21.8239 6.08571 21.8243 4.07833 19.8388C2.07224 17.8545 2.07133 14.6303 4.04924 12.6164ZM22.2419 1.87395C19.9011 -0.441217 16.0981 -0.442108 13.7566 1.87395C11.415 4.18987 11.4159 7.95136 13.7566 10.2664C16.0985 12.5828 19.9003 12.5825 22.2419 10.2664C24.5835 7.95047 24.5838 4.19026 22.2419 1.87395Z"
fill="currentColor"
/>
</CustomIcon>
);
};

View File

@ -0,0 +1,50 @@
import React from "react";
import { CustomIcon, CustomIconProps } from "../CustomIcon";
export const LaconicWithTextIcon: React.FC<CustomIconProps> = (props) => {
return (
<CustomIcon
width="117"
height="21"
viewBox="0 0 117 21"
fill="none"
{...props}
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M4.22282 11.0194C6.57609 8.69185 8.03272 5.47748 8.03206 1.92852C8.03293 1.44681 8.00604 0.970455 7.95259 0.499999L0.811272 0.500642L0.811488 14.0723C0.810838 15.7174 1.44499 17.3629 2.7134 18.6175C3.98191 19.8721 5.64682 20.5001 7.31031 20.4992L7.30988 20.4997L21.0317 20.5L21.0311 13.4355C20.5566 13.3838 20.075 13.357 19.5869 13.3569C15.9997 13.3574 12.7498 14.798 10.3965 17.1255C8.6841 18.7768 5.93858 18.7771 4.24733 17.1043C2.55716 15.4325 2.5564 12.7161 4.22282 11.0194ZM19.5504 1.96863C17.5783 0.0180696 14.3742 0.017319 12.4014 1.96863C10.4286 3.91984 10.4293 7.08895 12.4014 9.03941C14.3745 10.991 17.5776 10.9907 19.5504 9.03941C21.5232 7.0882 21.5236 3.92016 19.5504 1.96863Z"
fill="currentColor"
/>
<path
d="M32.6326 19.0836H40.4995V16.83H35.2622V1.91329H32.6326V19.0836Z"
fill="currentColor"
/>
<path
d="M51.1715 1.91329H46.8108L42.2528 19.0836H44.97L46.1095 14.791H51.7413L52.8808 19.0836H55.7295L51.1715 1.91329ZM46.6574 12.6448L48.9363 3.75909H49.024L51.2153 12.6448H46.6574Z"
fill="currentColor"
/>
<path
d="M64.4348 8.56823H67.5027C67.5027 3.67471 65.903 1.57134 62.1777 1.57134C58.2552 1.57134 56.5679 4.23278 56.5679 10.4785C56.5679 16.7456 58.2552 19.4285 62.1777 19.4285C65.903 19.4285 67.5027 17.3895 67.5246 12.6462H64.4567C64.4348 16.3593 63.9746 17.2822 62.1777 17.2822C60.1179 17.2822 59.6138 15.93 59.6357 10.4785C59.6357 5.04833 60.1398 3.69616 62.1777 3.71761C63.9746 3.71761 64.4348 4.68351 64.4348 8.56823Z"
fill="currentColor"
/>
<path
d="M75.4027 1.57146C79.391 1.59302 81.1002 4.27581 81.1002 10.5C81.1002 16.7243 79.391 19.4072 75.4027 19.4286C71.3926 19.4501 69.6833 16.7672 69.6833 10.5C69.6833 4.23291 71.3926 1.55002 75.4027 1.57146ZM72.7512 10.5C72.7512 15.9302 73.2772 17.2823 75.4027 17.2823C77.5064 17.2823 78.0324 15.9302 78.0324 10.5C78.0324 5.04846 77.5064 3.69629 75.4027 3.71784C73.2772 3.73929 72.7512 5.09146 72.7512 10.5Z"
fill="currentColor"
/>
<path
d="M86.8315 19.0621L84.2019 19.0836V1.91329H88.8257L93.1427 15.9071H93.1865V1.91329H95.8156V19.0836H91.4773L86.8755 4.01667H86.8315V19.0621Z"
fill="currentColor"
/>
<path
d="M102.387 1.91329H99.7577V19.0836H102.387V1.91329Z"
fill="currentColor"
/>
<path
d="M113.176 8.56823H116.244C116.244 3.67471 114.644 1.57134 110.919 1.57134C106.997 1.57134 105.309 4.23278 105.309 10.4785C105.309 16.7456 106.997 19.4285 110.919 19.4285C114.644 19.4285 116.244 17.3895 116.266 12.6462H113.198C113.176 16.3593 112.716 17.2822 110.919 17.2822C108.859 17.2822 108.355 15.93 108.377 10.4785C108.377 5.04833 108.881 3.69616 110.919 3.71761C112.716 3.71761 113.176 4.68351 113.176 8.56823Z"
fill="currentColor"
/>
</CustomIcon>
);
};

View File

@ -0,0 +1,2 @@
export { LaconicIcon } from "./icons/LaconicIcon";
export { LaconicWithTextIcon } from "./icons/LaconicWithTextIcon";

View File

@ -1,13 +1,17 @@
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
}

15
tailwind.config.ts Normal file
View File

@ -0,0 +1,15 @@
import type { Config } from "tailwindcss";
const config: Config = {
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: {
extend: {
colors: {
snowball: "#0f86f5",
},
},
},
plugins: [],
};
export default config;

View File

@ -3629,6 +3629,13 @@
resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8"
integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==
"@types/tailwindcss@^3.1.0":
version "3.1.0"
resolved "https://registry.yarnpkg.com/@types/tailwindcss/-/tailwindcss-3.1.0.tgz#1185e4b3437c6e0f19d6cc8cd42738a94fd7b64f"
integrity sha512-JxPzrm609hzvF4nmOI3StLjbBEP3WWQxDDJESqR1nh94h7gyyy3XSl0hn5RBMJ9mPudlLjtaXs5YEBtLw7CnPA==
dependencies:
tailwindcss "*"
"@types/testing-library__jest-dom@^5.9.1":
version "5.14.9"
resolved "https://registry.yarnpkg.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz#0fb1e6a0278d87b6737db55af5967570b67cb466"
@ -4607,6 +4614,18 @@ autoprefixer@^10.4.13:
picocolors "^1.0.0"
postcss-value-parser "^4.2.0"
autoprefixer@^10.4.20:
version "10.4.20"
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.20.tgz#5caec14d43976ef42e32dcb4bd62878e96be5b3b"
integrity sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==
dependencies:
browserslist "^4.23.3"
caniuse-lite "^1.0.30001646"
fraction.js "^4.3.7"
normalize-range "^0.1.2"
picocolors "^1.0.1"
postcss-value-parser "^4.2.0"
available-typed-arrays@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846"
@ -5017,6 +5036,16 @@ browserslist@^4.0.0, browserslist@^4.18.1, browserslist@^4.21.10, browserslist@^
node-releases "^2.0.14"
update-browserslist-db "^1.0.13"
browserslist@^4.23.3:
version "4.23.3"
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.3.tgz#debb029d3c93ebc97ffbc8d9cbb03403e227c800"
integrity sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==
dependencies:
caniuse-lite "^1.0.30001646"
electron-to-chromium "^1.5.4"
node-releases "^2.0.18"
update-browserslist-db "^1.1.0"
bs58@^4.0.0, bs58@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a"
@ -5127,6 +5156,11 @@ caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001587, caniuse-lite@^1.0.30001591:
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001599.tgz#571cf4f3f1506df9bf41fcbb6d10d5d017817bce"
integrity sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA==
caniuse-lite@^1.0.30001646:
version "1.0.30001651"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001651.tgz#52de59529e8b02b1aedcaaf5c05d9e23c0c28138"
integrity sha512-9Cf+Xv1jJNe1xPZLGuUXLNkE1BoDkqRqYyFJ9TDYSqhduqA4hu4oR9HluGoWYQC/aj8WHjsGVV+bwkh0+tegRg==
canonical-json@^0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/canonical-json/-/canonical-json-0.0.4.tgz#6579c072c3db5c477ec41dc978fbf2b8f41074a3"
@ -6225,6 +6259,11 @@ electron-to-chromium@^1.4.668:
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.710.tgz#d0ec4ea8a97df4c5eaeb8c69d45bf81f248b3855"
integrity sha512-w+9yAVHoHhysCa+gln7AzbO9CdjFcL/wN/5dd+XW/Msl2d/4+WisEaCF1nty0xbAKaxdaJfgLB2296U7zZB7BA==
electron-to-chromium@^1.5.4:
version "1.5.5"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.5.tgz#03bfdf422bdd2c05ee2657efedde21264a1a566b"
integrity sha512-QR7/A7ZkMS8tZuoftC/jfqNkZLQO779SSW3YuZHP4eXpj3EffGLFcB/Xu9AAZQzLccTiCV+EmUo3ha4mQ9wnlA==
elliptic@6.5.4:
version "6.5.4"
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
@ -6508,7 +6547,7 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
escalade@^3.1.1:
escalade@^3.1.1, escalade@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27"
integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==
@ -8869,7 +8908,7 @@ jest@^27.4.3:
import-local "^3.0.2"
jest-cli "^27.5.1"
jiti@^1.19.1, jiti@^1.21.0:
jiti@^1.21.0:
version "1.21.0"
resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d"
integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==
@ -9710,6 +9749,11 @@ node-releases@^2.0.14:
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b"
integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==
node-releases@^2.0.18:
version "2.0.18"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.18.tgz#f010e8d35e2fe8d6b2944f03f70213ecedc4ca3f"
integrity sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==
node-yaml@^4.0.1:
version "4.0.1"
resolved "https://registry.yarnpkg.com/node-yaml/-/node-yaml-4.0.1.tgz#3675d27c275fbea9c02e2b0faa18bb1699444cb3"
@ -10171,6 +10215,11 @@ picocolors@^1.0.0:
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
picocolors@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1"
integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==
picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3, picomatch@^2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
@ -10792,7 +10841,7 @@ postcss@^7.0.35:
picocolors "^0.2.1"
source-map "^0.6.1"
postcss@^8.3.5, postcss@^8.4.23, postcss@^8.4.33, postcss@^8.4.4:
postcss@^8.3.5, postcss@^8.4.23, postcss@^8.4.33:
version "8.4.36"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.36.tgz#dba513c3c3733c44e0288a712894f8910bbaabc6"
integrity sha512-/n7eumA6ZjFHAsbX30yhHup/IMkOmlmvtEi7P+6RMYf+bGJSUHc3geH4a0NSZxAz/RJfiS9tooCTs9LAVYUZKw==
@ -10801,6 +10850,15 @@ postcss@^8.3.5, postcss@^8.4.23, postcss@^8.4.33, postcss@^8.4.4:
picocolors "^1.0.0"
source-map-js "^1.1.0"
postcss@^8.4.41:
version "8.4.41"
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.41.tgz#d6104d3ba272d882fe18fc07d15dc2da62fa2681"
integrity sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==
dependencies:
nanoid "^3.3.7"
picocolors "^1.0.1"
source-map-js "^1.2.0"
prelude-ls@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396"
@ -11823,6 +11881,11 @@ source-map-js@^1.0.1, source-map-js@^1.1.0:
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.1.0.tgz#9e7d5cb46f0689fb6691b30f226937558d0fa94b"
integrity sha512-9vC2SfsJzlej6MAaMPLu8HiBSHGdRAJ9hVFYN1ibZoNkeanmDmLUcIrj6G9DGL7XMJ54AKg/G75akXl1/izTOw==
source-map-js@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af"
integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==
source-map-loader@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.2.tgz#af23192f9b344daa729f6772933194cc5fa54fee"
@ -12249,10 +12312,10 @@ system-architecture@^0.1.0:
resolved "https://registry.yarnpkg.com/system-architecture/-/system-architecture-0.1.0.tgz#71012b3ac141427d97c67c56bc7921af6bff122d"
integrity sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA==
tailwindcss@^3.0.2:
version "3.4.1"
resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.1.tgz#f512ca5d1dd4c9503c7d3d28a968f1ad8f5c839d"
integrity sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA==
tailwindcss@*, tailwindcss@^3.4.9:
version "3.4.9"
resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.9.tgz#9e04cddce1924d530df62af37d3520f0e2a9d85e"
integrity sha512-1SEOvRr6sSdV5IDf9iC+NU4dhwdqzF4zKKq3sAbasUWHEM6lsMhX+eNN5gkPx1BvLFEnZQEUFbXnGj8Qlp83Pg==
dependencies:
"@alloc/quick-lru" "^5.2.0"
arg "^5.0.2"
@ -12262,7 +12325,7 @@ tailwindcss@^3.0.2:
fast-glob "^3.3.0"
glob-parent "^6.0.2"
is-glob "^4.0.3"
jiti "^1.19.1"
jiti "^1.21.0"
lilconfig "^2.1.0"
micromatch "^4.0.5"
normalize-path "^3.0.0"
@ -12751,6 +12814,14 @@ update-browserslist-db@^1.0.13:
escalade "^3.1.1"
picocolors "^1.0.0"
update-browserslist-db@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e"
integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==
dependencies:
escalade "^3.1.2"
picocolors "^1.0.1"
uqr@^0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/uqr/-/uqr-0.1.2.tgz#5c6cd5dcff9581f9bb35b982cb89e2c483a41d7d"