chore: import upstream snapshot with attribution
i18n - Build Validation / Validate i18n Builds (24) (push) Has been cancelled
CI - Node.js / Lint (24) (push) Has been cancelled
CI - Node.js / Build (24) (push) Has been cancelled
CI - Node.js / Test (24) (push) Has been cancelled
CI - Node.js / Test - Upcoming Changes (24) (push) Has been cancelled
CI - Node.js / Test - i18n (italian, 24) (push) Has been cancelled
CI - Node.js / Test - i18n (portuguese, 24) (push) Has been cancelled
CD - Docker - GHCR Images / Build and Push Images (push) Has been cancelled
i18n - Build Validation / Validate i18n Builds (24) (push) Has been cancelled
CI - Node.js / Lint (24) (push) Has been cancelled
CI - Node.js / Build (24) (push) Has been cancelled
CI - Node.js / Test (24) (push) Has been cancelled
CI - Node.js / Test - Upcoming Changes (24) (push) Has been cancelled
CI - Node.js / Test - i18n (italian, 24) (push) Has been cancelled
CI - Node.js / Test - i18n (portuguese, 24) (push) Has been cancelled
CD - Docker - GHCR Images / Build and Push Images (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
/* eslint-disable filenames-simple/naming-convention */
|
||||
require('dotenv').config({ path: '../.env' });
|
||||
const config = {
|
||||
presets: [
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
loose: true,
|
||||
modules: false,
|
||||
useBuiltIns: 'usage',
|
||||
corejs: 3,
|
||||
shippedProposals: true,
|
||||
targets: {
|
||||
browsers: ['>0.25%', 'not dead']
|
||||
}
|
||||
}
|
||||
],
|
||||
[
|
||||
'@babel/preset-react',
|
||||
{
|
||||
useBuiltIns: true,
|
||||
pragma: 'React.createElement'
|
||||
}
|
||||
],
|
||||
'@babel/preset-typescript'
|
||||
],
|
||||
plugins: [
|
||||
'preval',
|
||||
'@babel/plugin-syntax-dynamic-import',
|
||||
'babel-plugin-macros',
|
||||
[
|
||||
'@babel/plugin-transform-runtime',
|
||||
{
|
||||
helpers: true,
|
||||
regenerator: true
|
||||
}
|
||||
],
|
||||
[
|
||||
'prismjs',
|
||||
{
|
||||
languages: [
|
||||
'bash',
|
||||
'c',
|
||||
'clike',
|
||||
'cpp',
|
||||
'css',
|
||||
'csharp',
|
||||
'html',
|
||||
'javascript',
|
||||
'json',
|
||||
'jsx',
|
||||
'markup',
|
||||
'mathml',
|
||||
'pug',
|
||||
'python',
|
||||
'scss',
|
||||
'sass',
|
||||
'sql',
|
||||
'svg',
|
||||
'typescript',
|
||||
'tsx',
|
||||
'xml'
|
||||
],
|
||||
theme: 'default',
|
||||
css: true,
|
||||
plugins: ['line-numbers']
|
||||
}
|
||||
]
|
||||
]
|
||||
};
|
||||
module.exports = config;
|
||||
@@ -0,0 +1,31 @@
|
||||
# Project dependencies
|
||||
.cache
|
||||
node_modules
|
||||
yarn-error.log
|
||||
|
||||
# Build directory
|
||||
/public
|
||||
.DS_Store
|
||||
|
||||
/static/js
|
||||
/static/css
|
||||
/static/curriculum-data
|
||||
|
||||
# i18n build script copies non-English translations from i18n-curriculum submodule
|
||||
/i18n/locales/*/translations.json
|
||||
/i18n/locales/*/intro.json
|
||||
/i18n/locales/*/meta-tags.json
|
||||
/i18n/locales/*/motivation.json
|
||||
# english is a special case and is commited in this repo
|
||||
!/i18n/locales/english/translations.json
|
||||
!/i18n/locales/english/intro.json
|
||||
!/i18n/locales/english/meta-tags.json
|
||||
!/i18n/locales/english/motivation.json
|
||||
|
||||
# Generated for all locales
|
||||
i18n/locales/**/trending.json
|
||||
i18n/locales/**/search-bar.json
|
||||
|
||||
# Config
|
||||
|
||||
config/env.json
|
||||
@@ -0,0 +1,4 @@
|
||||
/* eslint-disable filenames-simple/naming-convention */
|
||||
import { createLintStagedConfig } from '@freecodecamp/eslint-config/lintstaged';
|
||||
|
||||
export default createLintStagedConfig(import.meta.dirname);
|
||||
@@ -0,0 +1,33 @@
|
||||
import React from 'react';
|
||||
import type { GatsbyLinkProps } from 'gatsby';
|
||||
import { vi } from 'vitest';
|
||||
import gatsby from 'gatsby';
|
||||
|
||||
import envData from '../config/env.json';
|
||||
const { clientLocale } = envData;
|
||||
|
||||
export const navigate = vi.fn();
|
||||
export const graphql = vi.fn();
|
||||
export const Link = vi
|
||||
.fn()
|
||||
.mockImplementation(({ to, ...rest }: GatsbyLinkProps<undefined | boolean>) =>
|
||||
React.createElement('a', { ...rest, href: to })
|
||||
);
|
||||
export const withPrefix = vi.fn().mockImplementation((path: string) => {
|
||||
const pathPrefix = clientLocale === 'english' ? '' : '/' + clientLocale;
|
||||
return pathPrefix + path;
|
||||
});
|
||||
export const StaticQuery = vi.fn();
|
||||
export const useStaticQuery = vi.fn();
|
||||
|
||||
export default {
|
||||
// ...existing code...
|
||||
// spread the actual gatsby module to keep other exports working
|
||||
...gatsby,
|
||||
navigate,
|
||||
graphql,
|
||||
Link,
|
||||
withPrefix,
|
||||
StaticQuery,
|
||||
useStaticQuery
|
||||
};
|
||||
Vendored
+67
@@ -0,0 +1,67 @@
|
||||
import React from 'react';
|
||||
|
||||
// modified from https://github.com/i18next/react-i18next/blob/master/example/test-jest/src/__mocks__/react-i18next.js
|
||||
const hasChildren = node =>
|
||||
node && (node.children || (node.props && node.props.children));
|
||||
|
||||
const getChildren = node =>
|
||||
node && node.children ? node.children : node.props && node.props.children;
|
||||
|
||||
const renderNodes = reactNodes => {
|
||||
if (typeof reactNodes === 'string') {
|
||||
return reactNodes;
|
||||
}
|
||||
|
||||
return Object.keys(reactNodes).map((key, i) => {
|
||||
const child = reactNodes[key];
|
||||
const isElement = React.isValidElement(child);
|
||||
|
||||
if (typeof child === 'string') {
|
||||
return child;
|
||||
}
|
||||
if (hasChildren(child)) {
|
||||
const inner = renderNodes(getChildren(child));
|
||||
return React.cloneElement(child, { ...child.props, key: i }, inner);
|
||||
}
|
||||
if (typeof child === 'object' && !isElement) {
|
||||
return Object.keys(child).reduce(
|
||||
(str, childKey) => `${str}${child[childKey]}`,
|
||||
''
|
||||
);
|
||||
}
|
||||
|
||||
return child;
|
||||
});
|
||||
};
|
||||
|
||||
const withTranslation = () => Component => {
|
||||
const WrappedComponent = props =>
|
||||
React.createElement(Component, {
|
||||
...props,
|
||||
t: props.t ?? (str => str)
|
||||
});
|
||||
|
||||
WrappedComponent.WrappedComponent = Component;
|
||||
WrappedComponent.displayName = `withTranslation(${Component.displayName || Component.name || 'Component'})`;
|
||||
|
||||
return WrappedComponent;
|
||||
};
|
||||
|
||||
const useTranslation = () => {
|
||||
return {
|
||||
t: str => str,
|
||||
i18n: {
|
||||
changeLanguage: () => new Promise(() => {})
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const Trans = ({ children }) =>
|
||||
Array.isArray(children) ? renderNodes(children) : renderNodes([children]);
|
||||
|
||||
// translate isn't being used anywhere, uncomment if needed
|
||||
/* const translate = () => Component => props => (
|
||||
<Component t={() => ''} {...props} />
|
||||
); */
|
||||
|
||||
module.exports = { withTranslation, useTranslation, Trans };
|
||||
@@ -0,0 +1,4 @@
|
||||
import React from 'react';
|
||||
|
||||
// eslint-disable-next-line react/display-name
|
||||
export default () => <div>Spinner</div>;
|
||||
@@ -0,0 +1,2 @@
|
||||
export const prodAnalyticsId = 'GTM-57R6KJM';
|
||||
export const devAnalyticsId = 'GTM-WSS47LM';
|
||||
@@ -0,0 +1,77 @@
|
||||
import path from 'node:path';
|
||||
import fs from 'node:fs';
|
||||
import { describe, test, expect } from 'vitest';
|
||||
|
||||
import { getContentDir } from '@freecodecamp/curriculum/file-handler';
|
||||
import { buildCertification } from '@freecodecamp/curriculum/build-certification';
|
||||
|
||||
import { allCerts } from './cert-and-project-map';
|
||||
|
||||
describe('certifications', () => {
|
||||
const certificationsDir = path.resolve(
|
||||
getContentDir('english'),
|
||||
'certifications'
|
||||
);
|
||||
|
||||
const certificationFiles = fs.readdirSync(certificationsDir);
|
||||
|
||||
certificationFiles.forEach(filename => {
|
||||
test(`${filename} should have matching items in cert-and-project-map`, () => {
|
||||
const filePath = path.join(certificationsDir, filename);
|
||||
const result = buildCertification(filePath);
|
||||
|
||||
const certData = result.challenges[0];
|
||||
const certTests = certData.tests;
|
||||
|
||||
const matchingCert = allCerts.find(cert => cert.id === certData.id);
|
||||
|
||||
expect(
|
||||
matchingCert,
|
||||
`Cert ID ${certData.id} not found in allCerts.`
|
||||
).toBeDefined();
|
||||
expect(
|
||||
matchingCert,
|
||||
`Matching cert has no 'projects' property`
|
||||
).toHaveProperty('projects');
|
||||
|
||||
// skip legacy-full-stack as it has no projects
|
||||
if (filename === 'legacy-full-stack.yml') {
|
||||
return;
|
||||
}
|
||||
|
||||
expect(
|
||||
Array.isArray(matchingCert?.projects),
|
||||
`Matching cert 'projects' is not an array`
|
||||
).toBe(true);
|
||||
|
||||
const certProjects = matchingCert?.projects;
|
||||
|
||||
expect(
|
||||
certProjects?.length,
|
||||
`Project count mismatch: allCerts has ${certProjects?.length} projects, YAML has ${certTests.length} tests`
|
||||
).toBe(certTests.length);
|
||||
|
||||
certTests.forEach((test, i) => {
|
||||
expect(
|
||||
test,
|
||||
`Test at index ${i} in missing id property`
|
||||
).toHaveProperty('id');
|
||||
expect(
|
||||
test,
|
||||
`Test at index ${i} missing title property`
|
||||
).toHaveProperty('title');
|
||||
|
||||
const matchingProject = certProjects?.[i];
|
||||
|
||||
expect(
|
||||
matchingProject,
|
||||
`No project found at index ${i} for test ${test.id}`
|
||||
).toBeDefined();
|
||||
expect(
|
||||
matchingProject?.id,
|
||||
`Project ID mismatch at index ${i}: allCerts has "${matchingProject?.id}", YAML has "${test.id}"`
|
||||
).toBe(test.id);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,130 @@
|
||||
{
|
||||
"aa-test": {
|
||||
"defaultValue": false
|
||||
},
|
||||
"aa-test-in-component": {
|
||||
"defaultValue": false
|
||||
},
|
||||
"rdb-codespaces-instructions": {
|
||||
"defaultValue": true
|
||||
},
|
||||
"rdb-local-instructions": {
|
||||
"defaultValue": true
|
||||
},
|
||||
"rdb-ona-instructions": {
|
||||
"defaultValue": true
|
||||
},
|
||||
"landing-top-skill-focused": {
|
||||
"defaultValue": false,
|
||||
"rules": [
|
||||
{
|
||||
"coverage": 1,
|
||||
"hashAttribute": "id",
|
||||
"seed": "landing-top-skill-focused",
|
||||
"hashVersion": 2,
|
||||
"variations": [false, true],
|
||||
"weights": [0.5, 0.5],
|
||||
"key": "landing-top-skill-focused",
|
||||
"meta": [
|
||||
{
|
||||
"key": "0",
|
||||
"name": "Control"
|
||||
},
|
||||
{
|
||||
"key": "1",
|
||||
"name": "Variation 1"
|
||||
}
|
||||
],
|
||||
"phase": "0",
|
||||
"name": "tests the conversion rate of the new design comparing to the old one"
|
||||
}
|
||||
]
|
||||
},
|
||||
"replace-20-with-25": {
|
||||
"defaultValue": false,
|
||||
"rules": [
|
||||
{
|
||||
"coverage": 1,
|
||||
"hashAttribute": "id",
|
||||
"seed": "replace-20-with-25",
|
||||
"hashVersion": 2,
|
||||
"variations": [false, true],
|
||||
"weights": [0.5, 0.5],
|
||||
"key": "replace-20-with-25",
|
||||
"meta": [
|
||||
{
|
||||
"key": "0",
|
||||
"name": "Control"
|
||||
},
|
||||
{
|
||||
"key": "1",
|
||||
"name": "Variation 1"
|
||||
}
|
||||
],
|
||||
"phase": "0",
|
||||
"name": "stg replace 20 with 25"
|
||||
}
|
||||
]
|
||||
},
|
||||
"show-modal-randomly": {
|
||||
"defaultValue": false,
|
||||
"rules": [
|
||||
{
|
||||
"coverage": 1,
|
||||
"hashAttribute": "id",
|
||||
"seed": "show-modal-randomly",
|
||||
"hashVersion": 2,
|
||||
"variations": [false, true],
|
||||
"weights": [0.5, 0.5],
|
||||
"key": "show-modal-randomly",
|
||||
"meta": [
|
||||
{
|
||||
"key": "0",
|
||||
"name": "Control"
|
||||
},
|
||||
{
|
||||
"key": "1",
|
||||
"name": "Variation 1"
|
||||
}
|
||||
],
|
||||
"phase": "0",
|
||||
"name": "stg show modal randomly"
|
||||
}
|
||||
]
|
||||
},
|
||||
"landing-two-button-cta": {
|
||||
"defaultValue": false,
|
||||
"rules": [
|
||||
{
|
||||
"coverage": 1,
|
||||
"hashAttribute": "id",
|
||||
"seed": "landing-two-button-cta",
|
||||
"hashVersion": 2,
|
||||
"variations": [false, true],
|
||||
"weights": [0.5, 0.5],
|
||||
"key": "landing-two-button-cta",
|
||||
"meta": [
|
||||
{
|
||||
"key": "0",
|
||||
"name": "Control"
|
||||
},
|
||||
{
|
||||
"key": "1",
|
||||
"name": "Variation 1"
|
||||
}
|
||||
],
|
||||
"phase": "0",
|
||||
"name": "prod-landing-two-button-cta"
|
||||
}
|
||||
]
|
||||
},
|
||||
"classroom-mode": {
|
||||
"defaultValue": false
|
||||
},
|
||||
"disabled_blocks": {
|
||||
"defaultValue": []
|
||||
},
|
||||
"show-socrates": {
|
||||
"defaultValue": false
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
export const MAX_MOBILE_WIDTH = 767;
|
||||
export const EX_SMALL_VIEWPORT_HEIGHT = 300;
|
||||
export const TOOL_PANEL_HEIGHT = 37;
|
||||
export const SEARCH_EXPOSED_WIDTH = 980;
|
||||
export const GITHUB_LOCATION = 'https://github.com/freeCodeCamp';
|
||||
@@ -0,0 +1,78 @@
|
||||
import {
|
||||
config,
|
||||
configTypeChecked,
|
||||
configReact,
|
||||
configTestingLibrary,
|
||||
jsFiles,
|
||||
tsFiles
|
||||
} from '@freecodecamp/eslint-config/base';
|
||||
import globals from 'globals';
|
||||
|
||||
import { defineConfig, globalIgnores } from 'eslint/config';
|
||||
|
||||
const baseLanguageOptions = {
|
||||
globals: {
|
||||
...globals.browser,
|
||||
...globals.mocha,
|
||||
...globals.node,
|
||||
Promise: true,
|
||||
window: true,
|
||||
$: true,
|
||||
ga: true,
|
||||
jQuery: true,
|
||||
router: true,
|
||||
globalThis: true
|
||||
}
|
||||
};
|
||||
|
||||
const baseConfig = {
|
||||
settings: {
|
||||
react: {
|
||||
version: '16.4.2'
|
||||
},
|
||||
|
||||
'import/resolver': {
|
||||
typescript: true,
|
||||
node: true
|
||||
}
|
||||
},
|
||||
|
||||
rules: {
|
||||
'import/no-cycle': [
|
||||
2,
|
||||
{
|
||||
maxDepth: 2
|
||||
}
|
||||
],
|
||||
'react/prop-types': 'off',
|
||||
'react/jsx-no-useless-fragment': 'error'
|
||||
}
|
||||
};
|
||||
|
||||
// Order matters here; later configs can override settings in earlier ones.
|
||||
export default defineConfig(
|
||||
globalIgnores(['static', '.cache', 'public']),
|
||||
{
|
||||
files: jsFiles,
|
||||
extends: [configReact, configTestingLibrary, config],
|
||||
...baseConfig,
|
||||
languageOptions: {
|
||||
...baseLanguageOptions,
|
||||
|
||||
parserOptions: {
|
||||
babelOptions: {
|
||||
presets: ['@babel/preset-react'],
|
||||
configFile: './.babelrc.js'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
files: tsFiles,
|
||||
extends: [configReact, configTestingLibrary, configTypeChecked],
|
||||
...baseConfig,
|
||||
languageOptions: {
|
||||
...baseLanguageOptions
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,50 @@
|
||||
import type { GatsbyBrowser } from 'gatsby';
|
||||
import { LocationProvider } from '@gatsbyjs/reach-router';
|
||||
import cookies from 'browser-cookies';
|
||||
import React from 'react';
|
||||
import { I18nextProvider } from 'react-i18next';
|
||||
import { Provider } from 'react-redux';
|
||||
import { Elements } from '@stripe/react-stripe-js';
|
||||
|
||||
import i18n from './i18n/config';
|
||||
import { stripe } from './src/utils/stripe';
|
||||
import AppMountNotifier from './src/components/app-mount-notifier';
|
||||
import { createStore } from './src/redux/create-store';
|
||||
import layoutSelector from './utils/gatsby/layout-selector';
|
||||
import GrowthBookProvider from './src/components/growth-book/growth-book-wrapper';
|
||||
|
||||
const store = createStore();
|
||||
|
||||
export const wrapRootElement: GatsbyBrowser['wrapRootElement'] = ({
|
||||
element
|
||||
}) => {
|
||||
return (
|
||||
<LocationProvider>
|
||||
<Provider store={store}>
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<GrowthBookProvider>
|
||||
<AppMountNotifier>
|
||||
<Elements stripe={stripe}>{element}</Elements>
|
||||
</AppMountNotifier>
|
||||
</GrowthBookProvider>
|
||||
</I18nextProvider>
|
||||
</Provider>
|
||||
</LocationProvider>
|
||||
);
|
||||
};
|
||||
|
||||
export const wrapPageElement: GatsbyBrowser['wrapPageElement'] = layoutSelector;
|
||||
|
||||
export const disableCorePrefetching: GatsbyBrowser['disableCorePrefetching'] =
|
||||
() => true;
|
||||
|
||||
export const onRouteUpdate: GatsbyBrowser['onRouteUpdate'] = () => {
|
||||
store.dispatch({ type: 'app.routeUpdated' });
|
||||
};
|
||||
|
||||
export const onClientEntry: GatsbyBrowser['onClientEntry'] = () => {
|
||||
// Letting the users' browsers expire the cookie seems to have caused issues
|
||||
// for some users. Until we have time to investigate further, we should remove
|
||||
// the cookie on every page load.
|
||||
cookies.erase('csrf_token');
|
||||
};
|
||||
@@ -0,0 +1,70 @@
|
||||
import path from 'path';
|
||||
import type { GatsbyConfig } from 'gatsby';
|
||||
|
||||
import envData from './config/env.json';
|
||||
import {
|
||||
buildChallenges,
|
||||
replaceChallengeNodes,
|
||||
localeChallengesRootDir
|
||||
} from './utils/build-challenges';
|
||||
import { pathPrefix } from './utils/gatsby/path-prefix';
|
||||
|
||||
const { homeLocation } = envData;
|
||||
|
||||
const config: GatsbyConfig = {
|
||||
flags: {
|
||||
DEV_SSR: false
|
||||
},
|
||||
trailingSlash: 'ignore',
|
||||
siteMetadata: {
|
||||
title: 'freeCodeCamp',
|
||||
siteUrl: homeLocation
|
||||
},
|
||||
pathPrefix: pathPrefix,
|
||||
plugins: [
|
||||
'gatsby-plugin-pnpm-gatsby-5',
|
||||
{
|
||||
resolve: 'gatsby-plugin-webpack-bundle-analyser-v2',
|
||||
options: {
|
||||
analyzerMode: 'disabled',
|
||||
// It doesn't matter if the file is generated or not as far as caching
|
||||
// is concerned. It doesn't affect any tasks in any way, so we can
|
||||
// ignore it.
|
||||
|
||||
// eslint-disable-next-line turbo/no-undeclared-env-vars
|
||||
generateStatsFile: process.env.CI
|
||||
}
|
||||
},
|
||||
'gatsby-plugin-react-helmet',
|
||||
{
|
||||
resolve: 'gatsby-plugin-postcss',
|
||||
options: {
|
||||
postcssOptions: {
|
||||
config: path.resolve(__dirname, 'postcss.config.js')
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
resolve: path.resolve(
|
||||
__dirname,
|
||||
'../tools/client-plugins/gatsby-source-challenges'
|
||||
),
|
||||
options: {
|
||||
name: 'challenges',
|
||||
source: buildChallenges,
|
||||
onSourceChange: replaceChallengeNodes(),
|
||||
curriculumPath: localeChallengesRootDir
|
||||
}
|
||||
},
|
||||
'gatsby-plugin-remove-serviceworker',
|
||||
{
|
||||
resolve: 'gatsby-plugin-schema-snapshot',
|
||||
options: {
|
||||
path: 'schema.gql',
|
||||
update: process.env.GATSBY_UPDATE_SCHEMA_SNAPSHOT === 'true'
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -0,0 +1,138 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-require-imports, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */
|
||||
|
||||
const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');
|
||||
const webpack = require('webpack');
|
||||
|
||||
const env = require('./config/env.json');
|
||||
const { createSuperBlockIntroPages } = require('./utils/gatsby');
|
||||
|
||||
exports.createPages = async function createPages({
|
||||
actions,
|
||||
graphql,
|
||||
reporter
|
||||
}: any) {
|
||||
if (!env.algoliaAPIKey || !env.algoliaAppId) {
|
||||
if (process.env.FREECODECAMP_NODE_ENV === 'production') {
|
||||
throw new Error(
|
||||
'Algolia App id and API key are required to start the client!'
|
||||
);
|
||||
} else {
|
||||
reporter.info(
|
||||
'Algolia keys missing or invalid. Required for search to yield results.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!env.stripePublicKey) {
|
||||
if (process.env.FREECODECAMP_NODE_ENV === 'production') {
|
||||
throw new Error('Stripe public key is required to start the client!');
|
||||
} else {
|
||||
reporter.info(
|
||||
'Stripe public key is missing or invalid. Required for Stripe integration.'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const { createPage } = actions;
|
||||
|
||||
const result = await graphql(`
|
||||
{
|
||||
allSuperBlockStructure {
|
||||
nodes {
|
||||
superBlock
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
if (result.errors) {
|
||||
reporter.panic('createPages GraphQL query failed', result.errors);
|
||||
}
|
||||
|
||||
const {
|
||||
data: { allSuperBlockStructure }
|
||||
} = result;
|
||||
|
||||
const superBlocks = allSuperBlockStructure.nodes.map(
|
||||
(node: { superBlock: string }) => node.superBlock
|
||||
);
|
||||
|
||||
superBlocks.forEach((superBlock: string) => {
|
||||
createSuperBlockIntroPages(createPage)({ superBlock });
|
||||
});
|
||||
};
|
||||
|
||||
exports.onCreateWebpackConfig = ({ stage, actions }: any) => {
|
||||
const newPlugins = [
|
||||
// We add the shims of the node globals to the global scope
|
||||
new webpack.ProvidePlugin({
|
||||
Buffer: ['buffer', 'Buffer']
|
||||
}),
|
||||
new webpack.ProvidePlugin({
|
||||
process: 'process/browser'
|
||||
})
|
||||
];
|
||||
|
||||
// The monaco editor relies on some browser only globals so should not be
|
||||
// involved in SSR. Also, if the plugin is used during the 'build-html' or
|
||||
// 'develop-html' stage it overwrites the minfied files with ordinary ones.
|
||||
|
||||
if (stage !== 'build-html' && stage !== 'develop-html') {
|
||||
newPlugins.push(
|
||||
new MonacoWebpackPlugin({
|
||||
filename: '[name].worker-[contenthash].js'
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
actions.setWebpackConfig({
|
||||
resolve: {
|
||||
fallback: {
|
||||
fs: false,
|
||||
path: 'path-browserify',
|
||||
assert: 'assert',
|
||||
crypto: 'crypto-browserify',
|
||||
util: 'util/util',
|
||||
buffer: 'buffer',
|
||||
stream: 'stream-browserify',
|
||||
process: 'process/browser',
|
||||
url: 'url'
|
||||
}
|
||||
},
|
||||
plugins: newPlugins,
|
||||
ignoreWarnings: [
|
||||
(warning: Error) => {
|
||||
if (warning instanceof Error) {
|
||||
if (warning.message.includes('mini-css-extract-plugin')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
]
|
||||
});
|
||||
};
|
||||
|
||||
exports.onCreateBabelConfig = ({ actions }: any) => {
|
||||
actions.setBabelPlugin({
|
||||
name: '@babel/plugin-proposal-function-bind'
|
||||
});
|
||||
|
||||
actions.setBabelPlugin({
|
||||
name: '@babel/plugin-proposal-export-default-from'
|
||||
});
|
||||
};
|
||||
|
||||
exports.createSchemaCustomization = ({ actions }: any) => {
|
||||
const { createTypes } = actions;
|
||||
|
||||
// This hook is supported by the test runner, but is not currently used by the
|
||||
// client, so we have to tell Gatsby that it exists.
|
||||
const typeDefs = `
|
||||
type ChallengeNodeChallengeHooks {
|
||||
afterEach: String
|
||||
}
|
||||
`;
|
||||
|
||||
createTypes(typeDefs);
|
||||
};
|
||||
@@ -0,0 +1,66 @@
|
||||
import type { GatsbySSR } from 'gatsby';
|
||||
import React from 'react';
|
||||
import { I18nextProvider } from 'react-i18next';
|
||||
import { Provider } from 'react-redux';
|
||||
import { Elements } from '@stripe/react-stripe-js';
|
||||
|
||||
import i18n from './i18n/config';
|
||||
import { stripe } from './src/utils/stripe';
|
||||
import { createStore } from './src/redux/create-store';
|
||||
import layoutSelector from './utils/gatsby/layout-selector';
|
||||
import { webmanifestComponents } from './src/components/webmanifest';
|
||||
import {
|
||||
getheadTagComponents,
|
||||
getPostBodyComponents,
|
||||
getPreBodyThemeScript
|
||||
} from './utils/tags';
|
||||
import GrowthBookProvider from './src/components/growth-book/growth-book-wrapper';
|
||||
|
||||
const store = createStore();
|
||||
|
||||
export const wrapRootElement: GatsbySSR['wrapRootElement'] = ({ element }) => {
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<I18nextProvider i18n={i18n}>
|
||||
<GrowthBookProvider>
|
||||
<Elements stripe={stripe}>{element}</Elements>
|
||||
</GrowthBookProvider>
|
||||
</I18nextProvider>
|
||||
</Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export const wrapPageElement: GatsbySSR['wrapPageElement'] = layoutSelector;
|
||||
|
||||
export const onRenderBody: GatsbySSR['onRenderBody'] = ({
|
||||
pathname,
|
||||
setHeadComponents,
|
||||
setPreBodyComponents,
|
||||
setPostBodyComponents
|
||||
}) => {
|
||||
setHeadComponents([...getheadTagComponents(), ...webmanifestComponents]);
|
||||
setPreBodyComponents(getPreBodyThemeScript());
|
||||
setPostBodyComponents(getPostBodyComponents(pathname));
|
||||
};
|
||||
|
||||
export const onPreRenderHTML: GatsbySSR['onPreRenderHTML'] = ({
|
||||
getHeadComponents,
|
||||
replaceHeadComponents
|
||||
}) => {
|
||||
const isBootstrapScript = (key: React.Key | null) =>
|
||||
key === 'bootstrap-min-preload' || key === 'bootstrap-min';
|
||||
|
||||
const headComponents = getHeadComponents();
|
||||
headComponents.sort((x, y) => {
|
||||
const xKey = React.isValidElement(x) ? x.key : null;
|
||||
const yKey = React.isValidElement(y) ? y.key : null;
|
||||
|
||||
if (isBootstrapScript(xKey)) {
|
||||
return -1;
|
||||
} else if (isBootstrapScript(yKey)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
});
|
||||
replaceHeadComponents(headComponents);
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
import i18n from 'i18next';
|
||||
import { initReactI18next } from 'react-i18next';
|
||||
|
||||
i18n
|
||||
.use(initReactI18next)
|
||||
.init({
|
||||
debug: true,
|
||||
defaultNS: 'translations',
|
||||
fallbackLng: 'en',
|
||||
interpolation: {
|
||||
escapeValue: false
|
||||
},
|
||||
lng: 'en',
|
||||
ns: ['intro', 'translations'],
|
||||
resources: { en: { intro: {}, translations: {} } },
|
||||
returnNull: false
|
||||
})
|
||||
.catch((error: Error) => {
|
||||
throw Error(error.message);
|
||||
});
|
||||
|
||||
export default i18n;
|
||||
@@ -0,0 +1,91 @@
|
||||
/* global preval */
|
||||
|
||||
import i18n from 'i18next';
|
||||
import { initReactI18next } from 'react-i18next';
|
||||
import { i18nextCodes } from '@freecodecamp/shared/config/i18n';
|
||||
|
||||
import translations from './locales/english/translations.json';
|
||||
import trending from './locales/english/trending.json';
|
||||
import intro from './locales/english/intro.json';
|
||||
import metaTags from './locales/english/meta-tags.json';
|
||||
import links from './locales/english/links.json';
|
||||
import searchBar from './locales/english/search-bar.json';
|
||||
|
||||
import envData from '../config/env.json';
|
||||
|
||||
const { clientLocale } = envData;
|
||||
|
||||
const i18nextCode = i18nextCodes[clientLocale];
|
||||
|
||||
// Non-english locale resources are loaded via preval so that webpack only
|
||||
// bundles the single locale selected by CLIENT_LOCALE and the english fallback.
|
||||
// For english the preval returns undefined, so webpack will not bundle the
|
||||
// english resources twice.
|
||||
i18n.use(initReactI18next).init({
|
||||
fallbackLng: 'en',
|
||||
lng: i18nextCode,
|
||||
resources: {
|
||||
[i18nextCode]: {
|
||||
translations: preval`
|
||||
const { clientLocale } = require('../config/env.json');
|
||||
if (clientLocale !== 'english') {
|
||||
module.exports = require('./locales/' + clientLocale + '/translations.json');
|
||||
}
|
||||
`,
|
||||
trending: preval`
|
||||
const { clientLocale } = require('../config/env.json');
|
||||
if (clientLocale !== 'english') {
|
||||
module.exports = require('./locales/' + clientLocale + '/trending.json');
|
||||
}
|
||||
`,
|
||||
intro: preval`
|
||||
const { clientLocale } = require('../config/env.json');
|
||||
if (clientLocale !== 'english') {
|
||||
module.exports = require('./locales/' + clientLocale + '/intro.json');
|
||||
}
|
||||
`,
|
||||
metaTags: preval`
|
||||
const { clientLocale } = require('../config/env.json');
|
||||
if (clientLocale !== 'english') {
|
||||
module.exports = require('./locales/' + clientLocale + '/meta-tags.json');
|
||||
}
|
||||
`,
|
||||
links: preval`
|
||||
const { clientLocale } = require('../config/env.json');
|
||||
if (clientLocale !== 'english') {
|
||||
module.exports = require('./locales/' + clientLocale + '/links.json');
|
||||
}
|
||||
`,
|
||||
'search-bar': preval`
|
||||
const { clientLocale } = require('../config/env.json');
|
||||
if (clientLocale !== 'english') {
|
||||
module.exports = require('./locales/' + clientLocale + '/search-bar.json');
|
||||
}
|
||||
`
|
||||
},
|
||||
en: {
|
||||
translations,
|
||||
trending,
|
||||
intro,
|
||||
metaTags,
|
||||
links,
|
||||
'search-bar': searchBar
|
||||
}
|
||||
},
|
||||
ns: ['translations', 'trending', 'intro', 'metaTags', 'links', 'search-bar'],
|
||||
defaultNS: 'translations',
|
||||
returnObjects: true,
|
||||
// Uncomment the next line for debug logging
|
||||
// debug: true,
|
||||
interpolation: {
|
||||
escapeValue: false
|
||||
},
|
||||
react: {
|
||||
useSuspense: true
|
||||
},
|
||||
returnNull: false
|
||||
});
|
||||
|
||||
i18n.languages = clientLocale;
|
||||
|
||||
export default i18n;
|
||||
@@ -0,0 +1,120 @@
|
||||
import { dirname } from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
import { describe, test, expect } from 'vitest';
|
||||
|
||||
import {
|
||||
availableLangs,
|
||||
LangNames,
|
||||
LangCodes
|
||||
} from '@freecodecamp/shared/config/i18n';
|
||||
import {
|
||||
SuperBlocks,
|
||||
superBlockStages,
|
||||
SuperBlockStage
|
||||
} from '@freecodecamp/shared/config/curriculum';
|
||||
import { getCurriculum } from '../tools/get-curriculum';
|
||||
import intro from './locales/english/intro.json';
|
||||
|
||||
interface Intro {
|
||||
[key: string]: {
|
||||
title: string;
|
||||
summary?: string[];
|
||||
intro: string[];
|
||||
blocks: {
|
||||
[block: string]: {
|
||||
title: string;
|
||||
intro: string[];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
|
||||
describe('Locale tests:', () => {
|
||||
availableLangs.client.forEach(lang => {
|
||||
describe(`-- ${lang} --`, () => {
|
||||
test(`has an entry in the langDisplayNames enum`, () => {
|
||||
expect(
|
||||
Object.keys(LangNames)
|
||||
.map(langCode => langCode.toLowerCase())
|
||||
.includes(lang)
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test(`has an entry in the langCodes enum`, () => {
|
||||
expect(
|
||||
Object.keys(LangCodes)
|
||||
.map(langCode => langCode.toLowerCase())
|
||||
.includes(lang)
|
||||
).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Intro file structure tests:', () => {
|
||||
const typedIntro = intro as unknown as Intro;
|
||||
const superblocks = Object.values(SuperBlocks);
|
||||
const catalogSuperBlocks = superBlockStages[SuperBlockStage.Catalog];
|
||||
for (const superBlock of superblocks) {
|
||||
test(`superBlock ${superBlock} has required properties`, () => {
|
||||
expect(typeof typedIntro[superBlock].title).toBe('string');
|
||||
|
||||
// catalog superblocks should have a summary
|
||||
expect(
|
||||
!catalogSuperBlocks.includes(superBlock) ||
|
||||
Array.isArray(typedIntro[superBlock].summary)
|
||||
).toBe(true);
|
||||
|
||||
expect(typedIntro[superBlock].intro).toBeInstanceOf(Array);
|
||||
expect(typedIntro[superBlock].blocks).toBeInstanceOf(Object);
|
||||
const blocks = Object.keys(typedIntro[superBlock].blocks);
|
||||
blocks.forEach(block => {
|
||||
expect(typeof typedIntro[superBlock].blocks[block].title).toBe(
|
||||
'string'
|
||||
);
|
||||
expect(typedIntro[superBlock].blocks[block].intro).toBeInstanceOf(
|
||||
Array
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
type SuperBlockInfo = {
|
||||
blocks: Record<string, unknown>;
|
||||
};
|
||||
|
||||
describe('Curriculum validation', () => {
|
||||
const curriculum = getCurriculum() as Record<string, SuperBlockInfo>;
|
||||
// certifications are not superblocks, they're just mixed in with them.
|
||||
const superblocks = Object.entries(curriculum).filter(
|
||||
([key]) => key !== 'certifications'
|
||||
);
|
||||
|
||||
// It's important that we check that each block in the curriculum has a title
|
||||
// in the intro, rather than the other way around, because the intro must
|
||||
// include upcoming changes. The curriculum only does if SHOW_UPCOMING_CHANGES
|
||||
// is true.
|
||||
superblocks.forEach(superblock => {
|
||||
const [name, superBlockInfo] = superblock;
|
||||
const blockObject = superBlockInfo.blocks;
|
||||
describe(`${name}`, () => {
|
||||
test('should have titles for each block in intro.json', () => {
|
||||
const blocks = Object.keys(blockObject);
|
||||
|
||||
blocks.forEach(block => {
|
||||
const blockFromIntro = (intro as unknown as Intro)[superblock[0]]
|
||||
.blocks[block];
|
||||
expect(
|
||||
blockFromIntro.title,
|
||||
`block ${block} needs a non-empty title`
|
||||
).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"help-translate-link-url": "https://contribute.freecodecamp.org/getting-started/#translations",
|
||||
"top-contributors": "https://www.freecodecamp.org/news/freecodecamp-top-contributors/",
|
||||
"footer": {
|
||||
"about-url": "https://chinese.freecodecamp.org/news/about/",
|
||||
"shop-url": "https://shop.freecodecamp.org/",
|
||||
"support-url": "https://chinese.freecodecamp.org/news/support/",
|
||||
"sponsors-url": "https://www.freecodecamp.org/news/sponsors/",
|
||||
"honesty-url": "https://chinese.freecodecamp.org/news/academic-honesty-policy/",
|
||||
"coc-url": "https://chinese.freecodecamp.org/news/code-of-conduct/",
|
||||
"privacy-url": "https://www.freecodecamp.org/news/privacy-policy/",
|
||||
"tos-url": "https://www.freecodecamp.org/news/terms-of-service/",
|
||||
"copyright-url": "https://www.freecodecamp.org/news/copyright-policy/"
|
||||
},
|
||||
"donate": {
|
||||
"other-ways-url": "https://chinese.freecodecamp.org/news/how-to-donate-to-free-code-camp/",
|
||||
"download-irs-url": "https://s3.amazonaws.com/freecodecamp/Free+Code+Camp+Inc+IRS+Determination+Letter.pdf",
|
||||
"download-990-url": "https://freecodecamp.s3.amazonaws.com/freeCodeCamp+2019+f990.pdf",
|
||||
"one-time-url": "https://paypal.me/freecodecamp"
|
||||
},
|
||||
"nav": {
|
||||
"contribute": "https://contribute.freecodecamp.org/#/i18n/chinese/index",
|
||||
"forum": "https://forum.freecodecamp.org/",
|
||||
"news": "https://chinese.freecodecamp.org/news/",
|
||||
"podcast": "open.spotify.com/show/3dIVV6XRRPMs75z2xDtsOg?si=Ugm6rwlcTgiEJ1Udw9WzVQ"
|
||||
},
|
||||
"help": {
|
||||
"HTML-CSS": "curriculum-help",
|
||||
"JavaScript": "curriculum-help",
|
||||
"Python": "curriculum-help",
|
||||
"Backend Development": "curriculum-help",
|
||||
"C-Sharp": "curriculum-help",
|
||||
"English": "curriculum-help",
|
||||
"Spanish Curriculum": "curriculum-help",
|
||||
"Chinese Curriculum": "curriculum-help",
|
||||
"Odin": "curriculum-help",
|
||||
"Euler": "curriculum-help",
|
||||
"Rosetta": "curriculum-help",
|
||||
"General": "curriculum-help"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"help-translate-link-url": "https://contribute.freecodecamp.org/getting-started/#translations",
|
||||
"top-contributors": "https://www.freecodecamp.org/news/freecodecamp-top-contributors/",
|
||||
"footer": {
|
||||
"about-url": "https://chinese.freecodecamp.org/news/about/",
|
||||
"shop-url": "https://shop.freecodecamp.org/",
|
||||
"support-url": "https://chinese.freecodecamp.org/news/support/",
|
||||
"sponsors-url": "https://www.freecodecamp.org/news/sponsors/",
|
||||
"honesty-url": "https://chinese.freecodecamp.org/news/academic-honesty-policy/",
|
||||
"coc-url": "https://chinese.freecodecamp.org/news/code-of-conduct/",
|
||||
"privacy-url": "https://www.freecodecamp.org/news/privacy-policy/",
|
||||
"tos-url": "https://www.freecodecamp.org/news/terms-of-service/",
|
||||
"copyright-url": "https://www.freecodecamp.org/news/copyright-policy/"
|
||||
},
|
||||
"donate": {
|
||||
"other-ways-url": "https://chinese.freecodecamp.org/news/how-to-donate-to-free-code-camp/",
|
||||
"download-irs-url": "https://s3.amazonaws.com/freecodecamp/Free+Code+Camp+Inc+IRS+Determination+Letter.pdf",
|
||||
"download-990-url": "https://freecodecamp.s3.amazonaws.com/freeCodeCamp+2019+f990.pdf",
|
||||
"one-time-url": "https://paypal.me/freecodecamp"
|
||||
},
|
||||
"nav": {
|
||||
"contribute": "https://contribute.freecodecamp.org/#/i18n/chinese/index",
|
||||
"forum": "https://forum.freecodecamp.org/",
|
||||
"news": "https://chinese.freecodecamp.org/news/",
|
||||
"podcast": "open.spotify.com/show/3dIVV6XRRPMs75z2xDtsOg?si=Ugm6rwlcTgiEJ1Udw9WzVQ"
|
||||
},
|
||||
"help": {
|
||||
"HTML-CSS": "curriculum-help",
|
||||
"JavaScript": "curriculum-help",
|
||||
"Python": "curriculum-help",
|
||||
"Backend Development": "curriculum-help",
|
||||
"C-Sharp": "curriculum-help",
|
||||
"English": "curriculum-help",
|
||||
"Spanish Curriculum": "curriculum-help",
|
||||
"Chinese Curriculum": "curriculum-help",
|
||||
"Odin": "curriculum-help",
|
||||
"Euler": "curriculum-help",
|
||||
"Rosetta": "curriculum-help",
|
||||
"General": "curriculum-help"
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"help-translate-link-url": "https://contribute.freecodecamp.org/getting-started/#translations",
|
||||
"top-contributors": "https://www.freecodecamp.org/news/freecodecamp-top-contributors/",
|
||||
"footer": {
|
||||
"about-url": "https://www.freecodecamp.org/news/about/",
|
||||
"shop-url": "https://shop.freecodecamp.org/",
|
||||
"support-url": "https://www.freecodecamp.org/news/support/",
|
||||
"sponsors-url": "https://www.freecodecamp.org/news/sponsors/",
|
||||
"honesty-url": "https://www.freecodecamp.org/news/academic-honesty-policy/",
|
||||
"coc-url": "https://www.freecodecamp.org/news/code-of-conduct/",
|
||||
"privacy-url": "https://www.freecodecamp.org/news/privacy-policy/",
|
||||
"tos-url": "https://www.freecodecamp.org/news/terms-of-service/",
|
||||
"copyright-url": "https://www.freecodecamp.org/news/copyright-policy/"
|
||||
},
|
||||
"donate": {
|
||||
"other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp",
|
||||
"download-irs-url": "https://cdn.freecodecamp.org/non-profit-docs/freeCodeCamp-determination-letter.pdf",
|
||||
"download-990-url": "https://cdn.freecodecamp.org/non-profit-docs/freeCodeCamp-2019-f990.pdf",
|
||||
"one-time-url": "https://paypal.me/freecodecamp",
|
||||
"one-time-external-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp/#how-can-i-make-a-one-time-donation",
|
||||
"mail-check-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp/#can-i-mail-a-physical-check"
|
||||
},
|
||||
"nav": {
|
||||
"contribute": "https://contribute.freecodecamp.org/#/",
|
||||
"forum": "https://forum.freecodecamp.org/",
|
||||
"news": "https://freecodecamp.org/news/",
|
||||
"podcast": "https://freecodecamp.libsyn.com/"
|
||||
},
|
||||
"help": {
|
||||
"HTML-CSS": "curriculum-help",
|
||||
"JavaScript": "curriculum-help",
|
||||
"Python": "curriculum-help",
|
||||
"Backend Development": "curriculum-help",
|
||||
"C-Sharp": "curriculum-help",
|
||||
"English": "curriculum-help",
|
||||
"Spanish Curriculum": "curriculum-help",
|
||||
"Chinese Curriculum": "curriculum-help",
|
||||
"Odin": "curriculum-help",
|
||||
"Euler": "curriculum-help",
|
||||
"Rosetta": "curriculum-help",
|
||||
"General": "curriculum-help"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"title": "Learn to Code — For Free — Coding Courses for Busy People",
|
||||
"description": "Learn to Code — For Free",
|
||||
"social-description": "Learn to Code — For Free",
|
||||
"keywords": [
|
||||
"python",
|
||||
"javascript",
|
||||
"js",
|
||||
"git",
|
||||
"github",
|
||||
"website",
|
||||
"web",
|
||||
"development",
|
||||
"free",
|
||||
"code",
|
||||
"camp",
|
||||
"course",
|
||||
"courses",
|
||||
"html",
|
||||
"css",
|
||||
"react",
|
||||
"redux",
|
||||
"api",
|
||||
"front",
|
||||
"back",
|
||||
"end",
|
||||
"learn",
|
||||
"tutorial",
|
||||
"programming"
|
||||
],
|
||||
"youre-unsubscribed": "You have been unsubscribed"
|
||||
}
|
||||
@@ -0,0 +1,891 @@
|
||||
{
|
||||
"compliments": [
|
||||
"Over the top!",
|
||||
"Down the rabbit hole we go!",
|
||||
"Bring that rain!",
|
||||
"Target acquired.",
|
||||
"Feel that need for speed!",
|
||||
"You've got guts!",
|
||||
"We have liftoff!",
|
||||
"To infinity and beyond!",
|
||||
"Encore!",
|
||||
"Onward!",
|
||||
"Challenge destroyed!",
|
||||
"It's on like Donkey Kong!",
|
||||
"Power level? It's over 9000!",
|
||||
"Coding spree!",
|
||||
"Code long and prosper.",
|
||||
"The crowd goes wild!",
|
||||
"One for the Guinness book!",
|
||||
"Flawless victory!",
|
||||
"Most efficient!",
|
||||
"You've got the touch!",
|
||||
"You're on fire!",
|
||||
"The town is now red!",
|
||||
"To the nines!",
|
||||
"To the Batmobile!",
|
||||
"Pull out all the stops!",
|
||||
"You're a wizard, Harry!",
|
||||
"You're an all star!",
|
||||
"Way to go!",
|
||||
"Outta sight!",
|
||||
"You're crushing it!",
|
||||
"What sorcery is this?",
|
||||
"The world rejoices!",
|
||||
"That's the way it's done!",
|
||||
"You rock!",
|
||||
"Woo-hoo!",
|
||||
"We knew you could do it!",
|
||||
"Hyper Combo Finish!",
|
||||
"Nothing but net!",
|
||||
"Boom-shakalaka!",
|
||||
"You're a shooting star!",
|
||||
"You're unstoppable!",
|
||||
"Way cool!",
|
||||
"Walk on that sunshine!",
|
||||
"Keep on trucking!",
|
||||
"Off the charts!",
|
||||
"There is no spoon!",
|
||||
"Cranked it up to 11!",
|
||||
"Escape velocity reached!",
|
||||
"You make this look easy!",
|
||||
"Passed with flying colors!",
|
||||
"You've got this!",
|
||||
"Happy, happy, joy, joy!",
|
||||
"Tomorrow, the world!",
|
||||
"Your powers combined!",
|
||||
"It's alive. It's alive!",
|
||||
"Sonic Boom!",
|
||||
"Here's looking at you, Code!",
|
||||
"Ride like the wind!",
|
||||
"Legen - wait for it - dary!",
|
||||
"Ludicrous Speed! Go!",
|
||||
"Most triumphant!",
|
||||
"One loop to rule them all!",
|
||||
"By the power of Grayskull!",
|
||||
"You did it!",
|
||||
"Storm that castle!",
|
||||
"Face-melting guitar solo!",
|
||||
"Checkmate!",
|
||||
"Bodacious!",
|
||||
"Tubular!",
|
||||
"You're outta sight!",
|
||||
"Keep calm and code on!",
|
||||
"Even sad panda smiles!",
|
||||
"Even grumpy cat approves!",
|
||||
"Kool Aid Man says oh yeah!",
|
||||
"Bullseye!",
|
||||
"Far out!",
|
||||
"You're heating up!",
|
||||
"Standing ovation!",
|
||||
"Nice one!",
|
||||
"All right!",
|
||||
"Hasta la vista, challenge!",
|
||||
"Terminated.",
|
||||
"Off the hook!",
|
||||
"Thundercats, Hooo!",
|
||||
"Shiver me timbers!",
|
||||
"Raise the roof!",
|
||||
"Bingo!",
|
||||
"Even Honey Badger cares!",
|
||||
"Helm, Warp Nine. Engage!",
|
||||
"Gotta code 'em all!",
|
||||
"Spool up the FTL drive!",
|
||||
"Cool beans!",
|
||||
"They're in another castle.",
|
||||
"Power UP!",
|
||||
"Pikachu chooses you!",
|
||||
"I gotta have more cowbell.",
|
||||
"Gotta go fast!",
|
||||
"Yippee!",
|
||||
"Cowabunga!",
|
||||
"Moon Prism Power!",
|
||||
"Plus Ultra!",
|
||||
"Everything's coming up Milhouse!",
|
||||
"King of the Pirates!",
|
||||
"Thunder Breathing First Form!",
|
||||
"It's time to duel!",
|
||||
"You better believe it!",
|
||||
"Do a barrel roll!",
|
||||
"You can do this all day!",
|
||||
"It's super effective!",
|
||||
"This is the way!",
|
||||
"You're king of the world!",
|
||||
"It's morphin' time!",
|
||||
"Just keep swimming!",
|
||||
"You are the one who knocks!",
|
||||
"Inconceivable!",
|
||||
"Great Scott!",
|
||||
"By Grabthar's hammer!",
|
||||
"Get to the choppa!",
|
||||
"It's clobberin' time!",
|
||||
"Somebody stop me!",
|
||||
"Oh, hi Mark!",
|
||||
"Groovy!",
|
||||
"The Dude abides!",
|
||||
"Are you not entertained?",
|
||||
"There can be only one!",
|
||||
"You are the danger!",
|
||||
"You know kung fu!",
|
||||
"Elementary, my dear Watson!",
|
||||
"Maximum effort!"
|
||||
],
|
||||
"motivationalQuotes": [
|
||||
{
|
||||
"quote": "Whatever you are, be a good one.",
|
||||
"author": "Abraham Lincoln"
|
||||
},
|
||||
{
|
||||
"quote": "A change in perspective is worth 80 IQ points.",
|
||||
"author": "Alan Kay"
|
||||
},
|
||||
{
|
||||
"quote": "The best way to predict the future is to invent it.",
|
||||
"author": "Alan Kay"
|
||||
},
|
||||
{
|
||||
"quote": "The future is not laid out on a track. It is something that we can decide, and to the extent that we do not violate any known laws of the universe, we can probably make it work the way that we want to.",
|
||||
"author": "Alan Kay"
|
||||
},
|
||||
{
|
||||
"quote": "We can only see a short distance ahead, but we can see plenty there that needs to be done.",
|
||||
"author": "Alan Turing"
|
||||
},
|
||||
{
|
||||
"quote": "In the depth of winter, I finally learned that within me there lay an invincible summer.",
|
||||
"author": "Albert Camus"
|
||||
},
|
||||
{
|
||||
"quote": "A person who never made a mistake never tried anything new.",
|
||||
"author": "Albert Einstein"
|
||||
},
|
||||
{
|
||||
"quote": "Creativity is intelligence having fun.",
|
||||
"author": "Albert Einstein"
|
||||
},
|
||||
{
|
||||
"quote": "I have no special talents. I am only passionately curious.",
|
||||
"author": "Albert Einstein"
|
||||
},
|
||||
{
|
||||
"quote": "Life is like riding a bicycle. To keep your balance, you must keep moving.",
|
||||
"author": "Albert Einstein"
|
||||
},
|
||||
{
|
||||
"quote": "Make everything as simple as possible, but not simpler.",
|
||||
"author": "Albert Einstein"
|
||||
},
|
||||
{
|
||||
"quote": "Never memorize something that you can look up.",
|
||||
"author": "Albert Einstein"
|
||||
},
|
||||
{
|
||||
"quote": "Once we accept our limits, we go beyond them.",
|
||||
"author": "Albert Einstein"
|
||||
},
|
||||
{
|
||||
"quote": "Play is the highest form of research.",
|
||||
"author": "Albert Einstein"
|
||||
},
|
||||
{
|
||||
"quote": "We cannot solve our problems with the same thinking we used when we created them.",
|
||||
"author": "Albert Einstein"
|
||||
},
|
||||
{
|
||||
"quote": "Wisdom is not a product of schooling but of the lifelong attempt to acquire it.",
|
||||
"author": "Albert Einstein"
|
||||
},
|
||||
{
|
||||
"quote": "Your imagination is your preview of life's coming attractions.",
|
||||
"author": "Albert Einstein"
|
||||
},
|
||||
{
|
||||
"quote": "There is only one corner of the universe you can be certain of improving, and that's your own self.",
|
||||
"author": "Aldous Huxley"
|
||||
},
|
||||
{
|
||||
"quote": "I am thankful for my struggle because, without it, I wouldn't have stumbled across my strength.",
|
||||
"author": "Alex Elle"
|
||||
},
|
||||
{
|
||||
"quote": "The most common way people give up their power is by thinking they don't have any.",
|
||||
"author": "Alice Walker"
|
||||
},
|
||||
{
|
||||
"quote": "Follow your inner moonlight. Don't hide the madness.",
|
||||
"author": "Allen Ginsberg"
|
||||
},
|
||||
{
|
||||
"quote": "The most difficult thing is the decision to act. The rest is merely tenacity.",
|
||||
"author": "Amelia Earhart"
|
||||
},
|
||||
{
|
||||
"quote": "Life shrinks or expands in proportion with one's courage.",
|
||||
"author": "Anaïs Nin"
|
||||
},
|
||||
{
|
||||
"quote": "Weeks of programming can save you hours of planning.",
|
||||
"author": "Unknown"
|
||||
},
|
||||
{
|
||||
"quote": "Quality is not an act, it is a habit.",
|
||||
"author": "Aristotle"
|
||||
},
|
||||
{
|
||||
"quote": "Start where you are. Use what you have. Do what you can.",
|
||||
"author": "Arthur Ashe"
|
||||
},
|
||||
{
|
||||
"quote": "Nothing is impossible, the word itself says 'I'm possible'!",
|
||||
"author": "Audrey Hepburn"
|
||||
},
|
||||
{
|
||||
"quote": "Every strike brings me closer to the next home run.",
|
||||
"author": "Babe Ruth"
|
||||
},
|
||||
{
|
||||
"quote": "By failing to prepare, you are preparing to fail.",
|
||||
"author": "Benjamin Franklin"
|
||||
},
|
||||
{
|
||||
"quote": "Tell me and I forget. Teach me and I remember. Involve me and I learn.",
|
||||
"author": "Benjamin Franklin"
|
||||
},
|
||||
{
|
||||
"quote": "Well done is better than well said.",
|
||||
"author": "Benjamin Franklin"
|
||||
},
|
||||
{
|
||||
"quote": "There are no short cuts to any place worth going.",
|
||||
"author": "Beverly Sills"
|
||||
},
|
||||
{
|
||||
"quote": "Controlling complexity is the essence of computer programming.",
|
||||
"author": "Brian Kernighan"
|
||||
},
|
||||
{
|
||||
"quote": "I fear not the man who has practiced 10,000 kicks once, but I fear the man who has practiced one kick 10,000 times.",
|
||||
"author": "Bruce Lee"
|
||||
},
|
||||
{
|
||||
"quote": "There are far, far better things ahead than any we leave behind.",
|
||||
"author": "C.S. Lewis"
|
||||
},
|
||||
{
|
||||
"quote": "We are what we believe we are.",
|
||||
"author": "C.S. Lewis"
|
||||
},
|
||||
{
|
||||
"quote": "With the possible exception of the equator, everything begins somewhere.",
|
||||
"author": "C.S. Lewis"
|
||||
},
|
||||
{
|
||||
"quote": "You are never too old to set another goal, or to dream a new dream.",
|
||||
"author": "C.S. Lewis"
|
||||
},
|
||||
{
|
||||
"quote": "Somewhere, something incredible is waiting to be known.",
|
||||
"author": "Carl Sagan"
|
||||
},
|
||||
{
|
||||
"quote": "When you have a dream, you've got to grab it and never let go.",
|
||||
"author": "Carol Burnett"
|
||||
},
|
||||
{
|
||||
"quote": "If you're not making mistakes, then you're not making decisions.",
|
||||
"author": "Catherine Cook"
|
||||
},
|
||||
{
|
||||
"quote": "Find what you love and let it kill you.",
|
||||
"author": "Charles Bukowski"
|
||||
},
|
||||
{
|
||||
"quote": "What matters most is how well you walk through the fire.",
|
||||
"author": "Charles Bukowski"
|
||||
},
|
||||
{
|
||||
"quote": "It is not the strongest of the species that survive, nor the most intelligent, but the one most responsive to change.",
|
||||
"author": "Charles Darwin"
|
||||
},
|
||||
{
|
||||
"quote": "The details are not the details. They make the design.",
|
||||
"author": "Charles Eames"
|
||||
},
|
||||
{
|
||||
"quote": "Creativity is more than just being different. Anybody can plan weird. That's easy. What's hard is to be as simple as Bach. Making the simple, awesomely simple, that's creativity.",
|
||||
"author": "Charles Mingus"
|
||||
},
|
||||
{
|
||||
"quote": "Life is 10% what happens to you and 90% how you react to it.",
|
||||
"author": "Charles R. Swindoll"
|
||||
},
|
||||
{
|
||||
"quote": "You will do foolish things, but do them with enthusiasm.",
|
||||
"author": "Colette"
|
||||
},
|
||||
{
|
||||
"quote": "It does not matter how slowly you go as long as you do not stop.",
|
||||
"author": "Confucius"
|
||||
},
|
||||
{
|
||||
"quote": "Real knowledge is to know the extent of one's ignorance.",
|
||||
"author": "Confucius"
|
||||
},
|
||||
{
|
||||
"quote": "The past cannot be changed. The future is yet in your power.",
|
||||
"author": "Confucius"
|
||||
},
|
||||
{
|
||||
"quote": "Looking at code you wrote more than two weeks ago is like looking at code you are seeing for the first time.",
|
||||
"author": "Dan Hurvitz"
|
||||
},
|
||||
{
|
||||
"quote": "Someday is not a day of the week.",
|
||||
"author": "Denise Brennan-Nelson"
|
||||
},
|
||||
{
|
||||
"quote": "UNIX is simple. It just takes a genius to understand its simplicity.",
|
||||
"author": "Dennis Ritchie"
|
||||
},
|
||||
{
|
||||
"quote": "The way I see it, if you want the rainbow, you gotta put up with the rain!",
|
||||
"author": "Dolly Parton"
|
||||
},
|
||||
{
|
||||
"quote": "Computers are good at following instructions, but not at reading your mind.",
|
||||
"author": "Donald Knuth"
|
||||
},
|
||||
{
|
||||
"quote": "A good programmer is someone who always looks both ways before crossing a one-way street.",
|
||||
"author": "Doug Linder"
|
||||
},
|
||||
{
|
||||
"quote": "Creativity is a wild mind and a disciplined eye.",
|
||||
"author": "Dorothy Parker"
|
||||
},
|
||||
{
|
||||
"quote": "Tough times never last, but tough people do.",
|
||||
"author": "Dr. Robert Schuller"
|
||||
},
|
||||
{
|
||||
"quote": "If things start happening, don't worry, don't stew, just go right along and you'll start happening too.",
|
||||
"author": "Dr. Seuss"
|
||||
},
|
||||
{
|
||||
"quote": "Do not go gentle into that good night. Rage, rage against the dying of the light.",
|
||||
"author": "Dylan Thomas"
|
||||
},
|
||||
{
|
||||
"quote": "The question of whether computers can think is like the question of whether submarines can swim.",
|
||||
"author": "E.W. Dijkstra"
|
||||
},
|
||||
{
|
||||
"quote": "Any code of your own that you haven't looked at for six or more months might as well have been written by someone else.",
|
||||
"author": "Eagleson's Law"
|
||||
},
|
||||
{
|
||||
"quote": "Do one thing every day that scares you.",
|
||||
"author": "Eleanor Roosevelt"
|
||||
},
|
||||
{
|
||||
"quote": "With the new day comes new strength and new thoughts.",
|
||||
"author": "Eleanor Roosevelt"
|
||||
},
|
||||
{
|
||||
"quote": "You must do the things you think you cannot do.",
|
||||
"author": "Eleanor Roosevelt"
|
||||
},
|
||||
{
|
||||
"quote": "Light tomorrow with today.",
|
||||
"author": "Elizabeth Barrett Browning"
|
||||
},
|
||||
{
|
||||
"quote": "If your dreams do not scare you, they are not big enough.",
|
||||
"author": "Ellen Johnson Sirleaf"
|
||||
},
|
||||
{
|
||||
"quote": "Forever is composed of nows.",
|
||||
"author": "Emily Dickinson"
|
||||
},
|
||||
{
|
||||
"quote": "Computer science education cannot make anybody an expert programmer any more than studying brushes and pigment can make somebody an expert painter.",
|
||||
"author": "Eric Raymond"
|
||||
},
|
||||
{
|
||||
"quote": "If you don't risk anything, you risk even more.",
|
||||
"author": "Erica Jong"
|
||||
},
|
||||
{
|
||||
"quote": "The world breaks everyone, and afterward, many are strong at the broken places.",
|
||||
"author": "Ernest Hemingway"
|
||||
},
|
||||
{
|
||||
"quote": "There is nothing noble in being superior to your fellow man; true nobility is being superior to your former self.",
|
||||
"author": "Ernest Hemingway"
|
||||
},
|
||||
{
|
||||
"quote": "Never confuse a single defeat with a final defeat.",
|
||||
"author": "F. Scott Fitzgerald"
|
||||
},
|
||||
{
|
||||
"quote": "I attribute my success to this - I never gave or took any excuse.",
|
||||
"author": "Florence Nightingale"
|
||||
},
|
||||
{
|
||||
"quote": "The best revenge is massive success.",
|
||||
"author": "Frank Sinatra"
|
||||
},
|
||||
{
|
||||
"quote": "The only limit to our realization of tomorrow, will be our doubts of today.",
|
||||
"author": "Franklin D. Roosevelt"
|
||||
},
|
||||
{
|
||||
"quote": "Right or wrong, it's very pleasant to break something from time to time.",
|
||||
"author": "Fyodor Dostoevsky"
|
||||
},
|
||||
{
|
||||
"quote": "The harder I work, the luckier I get.",
|
||||
"author": "Gary Player"
|
||||
},
|
||||
{
|
||||
"quote": "Giving up is the only sure way to fail.",
|
||||
"author": "Gena Showalter"
|
||||
},
|
||||
{
|
||||
"quote": "The only truly secure system is one that is powered off, cast in a block of concrete and sealed in a lead-lined room with armed guards.",
|
||||
"author": "Gene Spafford"
|
||||
},
|
||||
{
|
||||
"quote": "A life spent making mistakes is not only more honorable, but more useful than a life spent doing nothing.",
|
||||
"author": "George Bernard Shaw"
|
||||
},
|
||||
{
|
||||
"quote": "First learn computer science and all the theory. Next develop a programming style. Then forget all that and just hack.",
|
||||
"author": "George Carrette"
|
||||
},
|
||||
{
|
||||
"quote": "Discovering the unexpected is more important than confirming the known.",
|
||||
"author": "George Box"
|
||||
},
|
||||
{
|
||||
"quote": "We only see what we know.",
|
||||
"author": "Goethe"
|
||||
},
|
||||
{
|
||||
"quote": "Without hard work, nothing grows but weeds.",
|
||||
"author": "Gordon B. Hinckley"
|
||||
},
|
||||
{
|
||||
"quote": "The function of good software is to make the complex appear to be simple.",
|
||||
"author": "Grady Booch"
|
||||
},
|
||||
{
|
||||
"quote": "When you know that you're capable of dealing with whatever comes, you have the only security the world has to offer.",
|
||||
"author": "Harry Browne"
|
||||
},
|
||||
{
|
||||
"quote": "Pain is inevitable. Suffering is optional.",
|
||||
"author": "Haruki Murakami"
|
||||
},
|
||||
{
|
||||
"quote": "Optimism is the faith that leads to achievement. Nothing can be done without hope and confidence.",
|
||||
"author": "Helen Keller"
|
||||
},
|
||||
{
|
||||
"quote": "The price of anything is the amount of life you exchange for it.",
|
||||
"author": "Henry David Thoreau"
|
||||
},
|
||||
{
|
||||
"quote": "Whether you think you can or think you can't, you're right.",
|
||||
"author": "Henry Ford"
|
||||
},
|
||||
{
|
||||
"quote": "The most exciting phrase to hear in science, the one that heralds discoveries, is not 'Eureka!' but 'Now that's funny…'",
|
||||
"author": "Isaac Asimov"
|
||||
},
|
||||
{
|
||||
"quote": "What you do makes a difference. And you have to decide what kind of difference you want to make.",
|
||||
"author": "Jane Goodall"
|
||||
},
|
||||
{
|
||||
"quote": "We are all failures. At least the best of us are.",
|
||||
"author": "J.M. Barrie"
|
||||
},
|
||||
{
|
||||
"quote": "You can't wait for inspiration. You have to go after it with a club.",
|
||||
"author": "Jack London"
|
||||
},
|
||||
{
|
||||
"quote": "Don't wish it were easier, wish you were better.",
|
||||
"author": "Jim Rohn"
|
||||
},
|
||||
{
|
||||
"quote": "By seeking and blundering we learn.",
|
||||
"author": "Johann Wolfgang von Goethe"
|
||||
},
|
||||
{
|
||||
"quote": "Knowing is not enough; we must apply. Wishing is not enough; we must do.",
|
||||
"author": "Johann Wolfgang von Goethe"
|
||||
},
|
||||
{
|
||||
"quote": "We first make our habits, then our habits make us.",
|
||||
"author": "John Dryden"
|
||||
},
|
||||
{
|
||||
"quote": "The power of imagination makes us infinite.",
|
||||
"author": "John Muir"
|
||||
},
|
||||
{
|
||||
"quote": "May you live every day of your life.",
|
||||
"author": "Jonathan Swift"
|
||||
},
|
||||
{
|
||||
"quote": "Perseverance is failing 19 times and succeeding the 20th.",
|
||||
"author": "Julie Andrews"
|
||||
},
|
||||
{
|
||||
"quote": "The work of today is the history of tomorrow, and we are its makers.",
|
||||
"author": "Juliette Gordon Low"
|
||||
},
|
||||
{
|
||||
"quote": "If you reveal your secrets to the wind, you should not blame the wind for revealing them to the trees.",
|
||||
"author": "Kahlil Gibran"
|
||||
},
|
||||
{
|
||||
"quote": "Optimism is an occupational hazard of programming; feedback is the treatment.",
|
||||
"author": "Kent Beck"
|
||||
},
|
||||
{
|
||||
"quote": "Opportunity does not knock, it presents itself when you beat down the door.",
|
||||
"author": "Kyle Chandler"
|
||||
},
|
||||
{
|
||||
"quote": "To iterate is human, to recurse divine.",
|
||||
"author": "Peter Deutsch"
|
||||
},
|
||||
{
|
||||
"quote": "A good traveler has no fixed plans and is not intent on arriving.",
|
||||
"author": "Lao Tzu"
|
||||
},
|
||||
{
|
||||
"quote": "An ant on the move does more than a dozing ox.",
|
||||
"author": "Lao Tzu"
|
||||
},
|
||||
{
|
||||
"quote": "Do the difficult things while they are easy and do the great things while they are small. A journey of a thousand miles must begin with a single step.",
|
||||
"author": "Lao Tzu"
|
||||
},
|
||||
{
|
||||
"quote": "That's the thing about people who think they hate computers. What they really hate is lousy programmers.",
|
||||
"author": "Larry Niven"
|
||||
},
|
||||
{
|
||||
"quote": "It had long since come to my attention that people of accomplishment rarely sat back and let things happen to them. They went out and happened to things.",
|
||||
"author": "Elinor Smith"
|
||||
},
|
||||
{
|
||||
"quote": "If you're any good at all, you know you can be better.",
|
||||
"author": "Lindsay Buckingham"
|
||||
},
|
||||
{
|
||||
"quote": "If people never did silly things, nothing intelligent would ever get done.",
|
||||
"author": "Ludwig Wittgenstein"
|
||||
},
|
||||
{
|
||||
"quote": "You only live once, but if you do it right, once is enough.",
|
||||
"author": "Mae West"
|
||||
},
|
||||
{
|
||||
"quote": "Live as if you were to die tomorrow. Learn as if you were to live forever.",
|
||||
"author": "Mahatma Gandhi"
|
||||
},
|
||||
{
|
||||
"quote": "Strength does not come from physical capacity. It comes from an indomitable will.",
|
||||
"author": "Mahatma Gandhi"
|
||||
},
|
||||
{
|
||||
"quote": "One person's 'paranoia' is another person's 'engineering redundancy'.",
|
||||
"author": "Marcus J. Ranum"
|
||||
},
|
||||
{
|
||||
"quote": "Nothing in life is to be feared, it is only to be understood. Now is the time to understand more, so that we may fear less.",
|
||||
"author": "Marie Curie"
|
||||
},
|
||||
{
|
||||
"quote": "If you have everything under control, you're not moving fast enough.",
|
||||
"author": "Mario Andretti"
|
||||
},
|
||||
{
|
||||
"quote": "Education: the path from cocky ignorance to miserable uncertainty.",
|
||||
"author": "Mark Twain"
|
||||
},
|
||||
{
|
||||
"quote": "It ain't what you don't know that gets you into trouble. It's what you know for sure that just ain't so.",
|
||||
"author": "Mark Twain"
|
||||
},
|
||||
{
|
||||
"quote": "The secret of getting ahead is getting started.",
|
||||
"author": "Mark Twain"
|
||||
},
|
||||
{
|
||||
"quote": "The two most important days in your life are the day you are born and the day you find out why.",
|
||||
"author": "Mark Twain"
|
||||
},
|
||||
{
|
||||
"quote": "Twenty years from now you will be more disappointed by the things that you didn't do than by the ones you did do. So throw off the bowlines. Sail away from the safe harbor. Catch the trade winds in your sails.",
|
||||
"author": "Mark Twain"
|
||||
},
|
||||
{
|
||||
"quote": "Any fool can write code that a computer can understand. Good programmers write code that humans can understand.",
|
||||
"author": "Martin Fowler"
|
||||
},
|
||||
{
|
||||
"quote": "I know, somehow, that only when it is dark enough can you see the stars.",
|
||||
"author": "Martin Luther King Jr."
|
||||
},
|
||||
{
|
||||
"quote": "It is never too late to be what you might have been.",
|
||||
"author": "Mary Anne Evans"
|
||||
},
|
||||
{
|
||||
"quote": "Nothing will work unless you do.",
|
||||
"author": "Maya Angelou"
|
||||
},
|
||||
{
|
||||
"quote": "You can't use up creativity. The more you use, the more you have.",
|
||||
"author": "Maya Angelou"
|
||||
},
|
||||
{
|
||||
"quote": "We delight in the beauty of the butterfly, but rarely admit the changes it has gone through to achieve that beauty.",
|
||||
"author": "Maya Angelou"
|
||||
},
|
||||
{
|
||||
"quote": "We may encounter many defeats, but we must not be defeated.",
|
||||
"author": "Maya Angelou"
|
||||
},
|
||||
{
|
||||
"quote": "Everybody has talent, but ability takes hard work.",
|
||||
"author": "Michael Jordan"
|
||||
},
|
||||
{
|
||||
"quote": "I've missed more than 9,000 shots during my career. I've lost almost 300 games. 26 times, I've been trusted to take the game winning shot and missed. I've failed over and over and over again in my life. And that is why I succeed.",
|
||||
"author": "Michael Jordan"
|
||||
},
|
||||
{
|
||||
"quote": "Impossible is just a big word thrown around by small men who find it easier to live in the world they've been given than to explore the power they have to change it. Impossible is not a fact. It's an opinion. Impossible is not a declaration. It's a dare. Impossible is potential. Impossible is temporary. Impossible is nothing.",
|
||||
"author": "Muhammad Ali"
|
||||
},
|
||||
{
|
||||
"quote": "A winner is a dreamer who never gives up.",
|
||||
"author": "Nelson Mandela"
|
||||
},
|
||||
{
|
||||
"quote": "It always seems impossible until it's done.",
|
||||
"author": "Nelson Mandela"
|
||||
},
|
||||
{
|
||||
"quote": "Failure will never overtake me if my determination to succeed is strong enough.",
|
||||
"author": "Og Mandino"
|
||||
},
|
||||
{
|
||||
"quote": "I am not young enough to know everything.",
|
||||
"author": "Oscar Wilde"
|
||||
},
|
||||
{
|
||||
"quote": "There is only one thing that makes a dream impossible to achieve: the fear of failure.",
|
||||
"author": "Paulo Coelho"
|
||||
},
|
||||
{
|
||||
"quote": "Never go to bed mad. Stay up and fight.",
|
||||
"author": "Phyllis Diller"
|
||||
},
|
||||
{
|
||||
"quote": "You can't cross the sea merely by standing and staring at the water.",
|
||||
"author": "Rabindranath Tagore"
|
||||
},
|
||||
{
|
||||
"quote": "The only person you are destined to become is the person you decide to be.",
|
||||
"author": "Ralph Waldo Emerson"
|
||||
},
|
||||
{
|
||||
"quote": "What you do speaks so loudly that I cannot hear what you say.",
|
||||
"author": "Ralph Waldo Emerson"
|
||||
},
|
||||
{
|
||||
"quote": "People who are crazy enough to think they can change the world, are the ones who do.",
|
||||
"author": "Rob Siltanen"
|
||||
},
|
||||
{
|
||||
"quote": "The best way out is always through.",
|
||||
"author": "Robert Frost"
|
||||
},
|
||||
{
|
||||
"quote": "Today's accomplishments were yesterday's impossibilities.",
|
||||
"author": "Robert H. Schuller"
|
||||
},
|
||||
{
|
||||
"quote": "Don't be satisfied with stories, how things have gone with others. Unfold your own myth.",
|
||||
"author": "Rumi"
|
||||
},
|
||||
{
|
||||
"quote": "Forget safety. Live where you fear to live. Destroy your reputation. Be notorious.",
|
||||
"author": "Rumi"
|
||||
},
|
||||
{
|
||||
"quote": "Sell your cleverness and buy bewilderment.",
|
||||
"author": "Rumi"
|
||||
},
|
||||
{
|
||||
"quote": "The cure for pain is in the pain.",
|
||||
"author": "Rumi"
|
||||
},
|
||||
{
|
||||
"quote": "Have no fear of perfection - you'll never reach it.",
|
||||
"author": "Salvador Dalí"
|
||||
},
|
||||
{
|
||||
"quote": "Don't watch the clock. Do what it does. Keep going.",
|
||||
"author": "Sam Levenson"
|
||||
},
|
||||
{
|
||||
"quote": "Ever Tried. Ever failed. No matter. Try again. Fail again. Fail better.",
|
||||
"author": "Samuel Beckett"
|
||||
},
|
||||
{
|
||||
"quote": "The more you know, the more you realize you know nothing.",
|
||||
"author": "Socrates"
|
||||
},
|
||||
{
|
||||
"quote": "The greatest enemy of knowledge is not ignorance, it is the illusion of knowledge.",
|
||||
"author": "Stephen Hawking"
|
||||
},
|
||||
{
|
||||
"quote": "The universe doesn't allow perfection.",
|
||||
"author": "Stephen Hawking"
|
||||
},
|
||||
{
|
||||
"quote": "Whether you want to uncover the secrets of the universe, or you want to pursue a career in the 21st century, basic computer programming is an essential skill to learn.",
|
||||
"author": "Stephen Hawking"
|
||||
},
|
||||
{
|
||||
"quote": "The scariest moment is always just before you start.",
|
||||
"author": "Stephen King"
|
||||
},
|
||||
{
|
||||
"quote": "You can, you should, and if you're brave enough to start, you will.",
|
||||
"author": "Stephen King"
|
||||
},
|
||||
{
|
||||
"quote": "Arise, Awake and Stop not until the goal is reached.",
|
||||
"author": "Swami Vivekananda"
|
||||
},
|
||||
{
|
||||
"quote": "It is said that your life flashes before your eyes just before you die. That is true, it's called Life.",
|
||||
"author": "Terry Pratchett"
|
||||
},
|
||||
{
|
||||
"quote": "Believe you can and you're halfway there.",
|
||||
"author": "Theodore Roosevelt"
|
||||
},
|
||||
{
|
||||
"quote": "I have not failed. I've just found 10,000 ways that won't work.",
|
||||
"author": "Thomas A. Edison"
|
||||
},
|
||||
{
|
||||
"quote": "Our greatest weakness lies in giving up. The most certain way to succeed is always to try just one more time.",
|
||||
"author": "Thomas A. Edison"
|
||||
},
|
||||
{
|
||||
"quote": "The harder the conflict, the more glorious the triumph.",
|
||||
"author": "Thomas Paine"
|
||||
},
|
||||
{
|
||||
"quote": "The Web as I envisaged it, we have not seen it yet. The future is still so much bigger than the past.",
|
||||
"author": "Tim Berners-Lee"
|
||||
},
|
||||
{
|
||||
"quote": "Failure is the condiment that gives success its flavor.",
|
||||
"author": "Truman Capote"
|
||||
},
|
||||
{
|
||||
"quote": "Those who say it cannot be done should not interrupt the person doing it.",
|
||||
"author": "Unknown"
|
||||
},
|
||||
{
|
||||
"quote": "Look at usual things with unusual eyes.",
|
||||
"author": "Vico Magistetti"
|
||||
},
|
||||
{
|
||||
"quote": "Even if you fall on your face, you're still moving forward.",
|
||||
"author": "Victor Kiam"
|
||||
},
|
||||
{
|
||||
"quote": "It's not whether you get knocked down, it's whether you get up.",
|
||||
"author": "Vince Lombardi"
|
||||
},
|
||||
{
|
||||
"quote": "I dream my painting and I paint my dream.",
|
||||
"author": "Vincent van Gogh"
|
||||
},
|
||||
{
|
||||
"quote": "Great things are done by a series of small things brought together.",
|
||||
"author": "Vincent van Gogh"
|
||||
},
|
||||
{
|
||||
"quote": "Let us cultivate our garden.",
|
||||
"author": "Voltaire"
|
||||
},
|
||||
{
|
||||
"quote": "Aim for the moon. If you miss, you may hit a star.",
|
||||
"author": "W. Clement Stone"
|
||||
},
|
||||
{
|
||||
"quote": "The way to get started is to quit talking and begin doing.",
|
||||
"author": "Walt Disney"
|
||||
},
|
||||
{
|
||||
"quote": "You miss 100% of the shots you don't take.",
|
||||
"author": "Wayne Gretzky"
|
||||
},
|
||||
{
|
||||
"quote": "Don't let yesterday take up too much of today.",
|
||||
"author": "Will Rogers"
|
||||
},
|
||||
{
|
||||
"quote": "Even if you're on the right track, you'll get run over if you just sit there.",
|
||||
"author": "Will Rogers"
|
||||
},
|
||||
{
|
||||
"quote": "Do not wait to strike till the iron is hot; but make it hot by striking.",
|
||||
"author": "William Butler Yeats"
|
||||
},
|
||||
{
|
||||
"quote": "You cannot swim for new horizons until you have courage to lose sight of the shore.",
|
||||
"author": "William Faulkner"
|
||||
},
|
||||
{
|
||||
"quote": "Be not afraid of greatness. Some are born great, some achieve greatness, and others have greatness thrust upon them.",
|
||||
"author": "William Shakespeare"
|
||||
},
|
||||
{
|
||||
"quote": "We know what we are, but not what we may be.",
|
||||
"author": "William Shakespeare"
|
||||
},
|
||||
{
|
||||
"quote": "In theory there is no difference between theory and practice. In practice there is.",
|
||||
"author": "Yogi Berra"
|
||||
},
|
||||
{
|
||||
"quote": "You can see a lot by just looking.",
|
||||
"author": "Yogi Berra"
|
||||
},
|
||||
{
|
||||
"quote": "There is no elevator to success, you have to take the stairs.",
|
||||
"author": "Zig Ziglar"
|
||||
},
|
||||
{
|
||||
"quote": "You don't have to be great to start, but you have to start to be great.",
|
||||
"author": "Zig Ziglar"
|
||||
}
|
||||
]
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"help-translate-link-url": "https://contribute.freecodecamp.org/getting-started/#translations",
|
||||
"top-contributors": "https://www.freecodecamp.org/news/freecodecamp-top-contributors/",
|
||||
"footer": {
|
||||
"about-url": "https://www.freecodecamp.org/espanol/news/acerca-de-freecodecamp-preguntas-frecuentes/",
|
||||
"shop-url": "https://shop.freecodecamp.org/",
|
||||
"support-url": "https://www.freecodecamp.org/espanol/news/preguntas-comunes-de-soporte-tecnico/",
|
||||
"sponsors-url": "https://www.freecodecamp.org/news/sponsors/",
|
||||
"honesty-url": "https://www.freecodecamp.org/espanol/news/politica-de-honestidad-academica/",
|
||||
"coc-url": "https://www.freecodecamp.org/espanol/news/codigo-de-conducta/",
|
||||
"privacy-url": "https://www.freecodecamp.org/news/privacy-policy/",
|
||||
"tos-url": "https://www.freecodecamp.org/news/terms-of-service/",
|
||||
"copyright-url": "https://www.freecodecamp.org/news/copyright-policy/"
|
||||
},
|
||||
"donate": {
|
||||
"other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp",
|
||||
"download-irs-url": "https://s3.amazonaws.com/freecodecamp/Free+Code+Camp+Inc+IRS+Determination+Letter.pdf",
|
||||
"download-990-url": "https://freecodecamp.s3.amazonaws.com/freeCodeCamp+2019+f990.pdf",
|
||||
"one-time-url": "https://paypal.me/freecodecamp"
|
||||
},
|
||||
"nav": {
|
||||
"contribute": "https://contribute.freecodecamp.org/#/i18n/espanol/index",
|
||||
"forum": "https://forum.freecodecamp.org/",
|
||||
"news": "https://freecodecamp.org/espanol/news/",
|
||||
"podcast": "https://www.freecodecamp.org/espanol/news/el-podcast-de-freecodecamp-en-espanol/"
|
||||
},
|
||||
"help": {
|
||||
"HTML-CSS": "curriculum-help",
|
||||
"JavaScript": "curriculum-help",
|
||||
"Python": "curriculum-help",
|
||||
"Backend Development": "curriculum-help",
|
||||
"C-Sharp": "curriculum-help",
|
||||
"English": "curriculum-help",
|
||||
"Spanish Curriculum": "curriculum-help",
|
||||
"Chinese Curriculum": "curriculum-help",
|
||||
"Odin": "curriculum-help",
|
||||
"Euler": "curriculum-help",
|
||||
"Rosetta": "curriculum-help",
|
||||
"General": "curriculum-help"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"help-translate-link-url": "https://contribute.freecodecamp.org/getting-started/#translations",
|
||||
"top-contributors": "https://www.freecodecamp.org/news/freecodecamp-top-contributors/",
|
||||
"footer": {
|
||||
"about-url": "https://www.freecodecamp.org/news/about/",
|
||||
"shop-url": "https://shop.freecodecamp.org/",
|
||||
"support-url": "https://www.freecodecamp.org/news/support/",
|
||||
"sponsors-url": "https://www.freecodecamp.org/news/sponsors/",
|
||||
"honesty-url": "https://www.freecodecamp.org/news/academic-honesty-policy/",
|
||||
"coc-url": "https://www.freecodecamp.org/news/code-of-conduct/",
|
||||
"privacy-url": "https://www.freecodecamp.org/news/privacy-policy/",
|
||||
"tos-url": "https://www.freecodecamp.org/news/terms-of-service/",
|
||||
"copyright-url": "https://www.freecodecamp.org/news/copyright-policy/"
|
||||
},
|
||||
"donate": {
|
||||
"other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp",
|
||||
"download-irs-url": "https://s3.amazonaws.com/freecodecamp/Free+Code+Camp+Inc+IRS+Determination+Letter.pdf",
|
||||
"download-990-url": "https://freecodecamp.s3.amazonaws.com/freeCodeCamp+2019+f990.pdf",
|
||||
"one-time-url": "https://paypal.me/freecodecamp"
|
||||
},
|
||||
"nav": {
|
||||
"contribute": "https://contribute.freecodecamp.org/#/i18n/german/index",
|
||||
"forum": "https://forum.freecodecamp.org/",
|
||||
"news": "https://freecodecamp.org/german/news/",
|
||||
"podcast": "https://freecodecamp.libsyn.com/"
|
||||
},
|
||||
"help": {
|
||||
"HTML-CSS": "curriculum-help",
|
||||
"JavaScript": "curriculum-help",
|
||||
"Python": "curriculum-help",
|
||||
"Backend Development": "curriculum-help",
|
||||
"C-Sharp": "curriculum-help",
|
||||
"English": "curriculum-help",
|
||||
"Spanish Curriculum": "curriculum-help",
|
||||
"Chinese Curriculum": "curriculum-help",
|
||||
"Odin": "curriculum-help",
|
||||
"Euler": "curriculum-help",
|
||||
"Rosetta": "curriculum-help",
|
||||
"General": "curriculum-help"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"help-translate-link-url": "https://contribute.freecodecamp.org/getting-started/#translations",
|
||||
"top-contributors": "https://www.freecodecamp.org/news/freecodecamp-top-contributors/",
|
||||
"footer": {
|
||||
"about-url": "https://www.freecodecamp.org/news/about/",
|
||||
"shop-url": "https://shop.freecodecamp.org/",
|
||||
"support-url": "https://www.freecodecamp.org/news/support/",
|
||||
"sponsors-url": "https://www.freecodecamp.org/news/sponsors/",
|
||||
"honesty-url": "https://www.freecodecamp.org/news/academic-honesty-policy/",
|
||||
"coc-url": "https://www.freecodecamp.org/news/code-of-conduct/",
|
||||
"privacy-url": "https://www.freecodecamp.org/news/privacy-policy/",
|
||||
"tos-url": "https://www.freecodecamp.org/news/terms-of-service/",
|
||||
"copyright-url": "https://www.freecodecamp.org/news/copyright-policy/"
|
||||
},
|
||||
"donate": {
|
||||
"other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp",
|
||||
"download-irs-url": "https://s3.amazonaws.com/freecodecamp/Free+Code+Camp+Inc+IRS+Determination+Letter.pdf",
|
||||
"download-990-url": "https://freecodecamp.s3.amazonaws.com/freeCodeCamp+2019+f990.pdf",
|
||||
"one-time-url": "https://paypal.me/freecodecamp"
|
||||
},
|
||||
"nav": {
|
||||
"contribute": "https://contribute.freecodecamp.org/#/i18n/italian/index",
|
||||
"forum": "https://forum.freecodecamp.org/",
|
||||
"news": "https://freecodecamp.org/italian/news/",
|
||||
"podcast": "https://freecodecamp.libsyn.com/"
|
||||
},
|
||||
"help": {
|
||||
"HTML-CSS": "curriculum-help",
|
||||
"JavaScript": "curriculum-help",
|
||||
"Python": "curriculum-help",
|
||||
"Backend Development": "curriculum-help",
|
||||
"C-Sharp": "curriculum-help",
|
||||
"English": "curriculum-help",
|
||||
"Spanish Curriculum": "curriculum-help",
|
||||
"Chinese Curriculum": "curriculum-help",
|
||||
"Odin": "curriculum-help",
|
||||
"Euler": "curriculum-help",
|
||||
"Rosetta": "curriculum-help",
|
||||
"General": "curriculum-help"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"help-translate-link-url": "https://contribute.freecodecamp.org/getting-started/#translations",
|
||||
"top-contributors": "https://www.freecodecamp.org/news/freecodecamp-top-contributors/",
|
||||
"footer": {
|
||||
"about-url": "https://www.freecodecamp.org/japanese/news/about/",
|
||||
"shop-url": "https://shop.freecodecamp.org/",
|
||||
"support-url": "https://www.freecodecamp.org/japanese/news/support/",
|
||||
"sponsors-url": "https://www.freecodecamp.org/news/sponsors/",
|
||||
"honesty-url": "https://www.freecodecamp.org/japanese/news/academic-honesty-policy/",
|
||||
"coc-url": "https://www.freecodecamp.org/japanese/news/code-of-conduct/",
|
||||
"privacy-url": "https://www.freecodecamp.org/news/privacy-policy/",
|
||||
"tos-url": "https://www.freecodecamp.org/news/terms-of-service/",
|
||||
"copyright-url": "https://www.freecodecamp.org/news/copyright-policy/"
|
||||
},
|
||||
"donate": {
|
||||
"other-ways-url": "https://www.freecodecamp.org/japanese/news/how-to-donate-to-free-code-camp",
|
||||
"download-irs-url": "https://s3.amazonaws.com/freecodecamp/Free+Code+Camp+Inc+IRS+Determination+Letter.pdf",
|
||||
"download-990-url": "https://freecodecamp.s3.amazonaws.com/freeCodeCamp+2019+f990.pdf",
|
||||
"one-time-url": "https://paypal.me/freecodecamp"
|
||||
},
|
||||
"nav": {
|
||||
"contribute": "https://contribute.freecodecamp.org/#/i18n/japanese/index",
|
||||
"forum": "https://forum.freecodecamp.org/",
|
||||
"news": "https://www.freecodecamp.org/japanese/news/",
|
||||
"podcast": "https://freecodecamp.libsyn.com/"
|
||||
},
|
||||
"help": {
|
||||
"HTML-CSS": "curriculum-help",
|
||||
"JavaScript": "curriculum-help",
|
||||
"Python": "curriculum-help",
|
||||
"Backend Development": "curriculum-help",
|
||||
"C-Sharp": "curriculum-help",
|
||||
"English": "curriculum-help",
|
||||
"Spanish Curriculum": "curriculum-help",
|
||||
"Chinese Curriculum": "curriculum-help",
|
||||
"Odin": "curriculum-help",
|
||||
"Euler": "curriculum-help",
|
||||
"Rosetta": "curriculum-help",
|
||||
"General": "curriculum-help"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{
|
||||
"help-translate-link-url": "https://contribute.freecodecamp.org/getting-started/#translations",
|
||||
"top-contributors": "https://www.freecodecamp.org/news/freecodecamp-top-contributors/",
|
||||
"footer": {
|
||||
"about-url": "https://www.freecodecamp.org/news/about/",
|
||||
"shop-url": "https://shop.freecodecamp.org/",
|
||||
"support-url": "https://www.freecodecamp.org/news/support/",
|
||||
"sponsors-url": "https://www.freecodecamp.org/news/sponsors/",
|
||||
"honesty-url": "https://www.freecodecamp.org/news/academic-honesty-policy/",
|
||||
"coc-url": "https://www.freecodecamp.org/news/code-of-conduct/",
|
||||
"privacy-url": "https://www.freecodecamp.org/news/privacy-policy/",
|
||||
"tos-url": "https://www.freecodecamp.org/news/terms-of-service/",
|
||||
"copyright-url": "https://www.freecodecamp.org/news/copyright-policy/"
|
||||
},
|
||||
"donate": {
|
||||
"other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp",
|
||||
"download-irs-url": "https://s3.amazonaws.com/freecodecamp/Free+Code+Camp+Inc+IRS+Determination+Letter.pdf",
|
||||
"download-990-url": "https://freecodecamp.s3.amazonaws.com/freeCodeCamp+2019+f990.pdf",
|
||||
"one-time-url": "https://paypal.me/freecodecamp",
|
||||
"one-time-external-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp/#how-can-i-make-a-one-time-donation",
|
||||
"mail-check-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp/#can-i-mail-a-physical-check"
|
||||
},
|
||||
"nav": {
|
||||
"contribute": "https://contribute.freecodecamp.org/#/",
|
||||
"forum": "https://forum.freecodecamp.org/",
|
||||
"news": "https://www.freecodecamp.org/korean/news/search/",
|
||||
"podcast": "https://freecodecamp.libsyn.com/"
|
||||
},
|
||||
"help": {
|
||||
"HTML-CSS": "curriculum-help",
|
||||
"JavaScript": "curriculum-help",
|
||||
"Python": "curriculum-help",
|
||||
"Backend Development": "curriculum-help",
|
||||
"C-Sharp": "curriculum-help",
|
||||
"English": "curriculum-help",
|
||||
"Spanish Curriculum": "curriculum-help",
|
||||
"Chinese Curriculum": "curriculum-help",
|
||||
"Odin": "curriculum-help",
|
||||
"Euler": "curriculum-help",
|
||||
"Rosetta": "curriculum-help",
|
||||
"General": "curriculum-help"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"help-translate-link-url": "https://contribute.freecodecamp.org/getting-started/#translations",
|
||||
"top-contributors": "https://www.freecodecamp.org/news/freecodecamp-top-contributors/",
|
||||
"footer": {
|
||||
"about-url": "https://www.freecodecamp.org/portuguese/news/sobre-o-freecodecamp-perguntas-frequentes/",
|
||||
"shop-url": "https://shop.freecodecamp.org/",
|
||||
"support-url": "https://www.freecodecamp.org/portuguese/news/perguntas-frequentes-sobre-suporte-tecnico-faq-do-freecodecamp/",
|
||||
"sponsors-url": "https://www.freecodecamp.org/news/sponsors/",
|
||||
"honesty-url": "https://www.freecodecamp.org/portuguese/news/politica-de-honestidade-academica-do-freecodecamp/",
|
||||
"coc-url": "https://www.freecodecamp.org/portuguese/news/codigo-de-conduta-do-freecodecamp/",
|
||||
"privacy-url": "https://www.freecodecamp.org/news/privacy-policy/",
|
||||
"tos-url": "https://www.freecodecamp.org/news/terms-of-service/",
|
||||
"copyright-url": "https://www.freecodecamp.org/news/copyright-policy/"
|
||||
},
|
||||
"donate": {
|
||||
"other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp",
|
||||
"download-irs-url": "https://s3.amazonaws.com/freecodecamp/Free+Code+Camp+Inc+IRS+Determination+Letter.pdf",
|
||||
"download-990-url": "https://freecodecamp.s3.amazonaws.com/freeCodeCamp+2019+f990.pdf",
|
||||
"one-time-url": "https://paypal.me/freecodecamp"
|
||||
},
|
||||
"nav": {
|
||||
"contribute": "https://contribute.freecodecamp.org/#/i18n/portuguese/index",
|
||||
"forum": "https://forum.freecodecamp.org/",
|
||||
"news": "https://freecodecamp.org/portuguese/news/",
|
||||
"podcast": "https://open.spotify.com/show/70m92At5oht4zY4f87lLEE?si=6tozUAOBQFSVyaqixy6aCg"
|
||||
},
|
||||
"help": {
|
||||
"HTML-CSS": "curriculum-help",
|
||||
"JavaScript": "curriculum-help",
|
||||
"Python": "curriculum-help",
|
||||
"Backend Development": "curriculum-help",
|
||||
"C-Sharp": "curriculum-help",
|
||||
"English": "curriculum-help",
|
||||
"Spanish Curriculum": "curriculum-help",
|
||||
"Chinese Curriculum": "curriculum-help",
|
||||
"Odin": "curriculum-help",
|
||||
"Euler": "curriculum-help",
|
||||
"Rosetta": "curriculum-help",
|
||||
"General": "curriculum-help"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"help-translate-link-url": "https://contribute.freecodecamp.org/getting-started/#translations",
|
||||
"top-contributors": "https://www.freecodecamp.org/news/freecodecamp-top-contributors/",
|
||||
"footer": {
|
||||
"about-url": "https://www.freecodecamp.org/news/about/",
|
||||
"shop-url": "https://shop.freecodecamp.org/",
|
||||
"support-url": "https://www.freecodecamp.org/news/support/",
|
||||
"sponsors-url": "https://www.freecodecamp.org/news/sponsors/",
|
||||
"honesty-url": "https://www.freecodecamp.org/news/academic-honesty-policy/",
|
||||
"coc-url": "https://www.freecodecamp.org/news/code-of-conduct/",
|
||||
"privacy-url": "https://www.freecodecamp.org/news/privacy-policy/",
|
||||
"tos-url": "https://www.freecodecamp.org/news/terms-of-service/",
|
||||
"copyright-url": "https://www.freecodecamp.org/news/copyright-policy/"
|
||||
},
|
||||
"donate": {
|
||||
"other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp",
|
||||
"download-irs-url": "https://s3.amazonaws.com/freecodecamp/Free+Code+Camp+Inc+IRS+Determination+Letter.pdf",
|
||||
"download-990-url": "https://freecodecamp.s3.amazonaws.com/freeCodeCamp+2019+f990.pdf",
|
||||
"one-time-url": "https://paypal.me/freecodecamp"
|
||||
},
|
||||
"nav": {
|
||||
"contribute": "https://contribute.freecodecamp.org/#/",
|
||||
"forum": "https://forum.freecodecamp.org/",
|
||||
"news": "https://freecodecamp.org/news/",
|
||||
"podcast": "https://freecodecamp.libsyn.com/"
|
||||
},
|
||||
"help": {
|
||||
"HTML-CSS": "curriculum-help",
|
||||
"JavaScript": "curriculum-help",
|
||||
"Python": "curriculum-help",
|
||||
"Backend Development": "curriculum-help",
|
||||
"C-Sharp": "curriculum-help",
|
||||
"English": "curriculum-help",
|
||||
"Spanish Curriculum": "curriculum-help",
|
||||
"Chinese Curriculum": "curriculum-help",
|
||||
"Odin": "curriculum-help",
|
||||
"Euler": "curriculum-help",
|
||||
"Rosetta": "curriculum-help",
|
||||
"General": "curriculum-help"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"help-translate-link-url": "https://contribute.freecodecamp.org/getting-started/#translations",
|
||||
"top-contributors": "https://www.freecodecamp.org/news/freecodecamp-top-contributors/",
|
||||
"footer": {
|
||||
"about-url": "https://www.freecodecamp.org/ukrainian/news/chapy-freecodecamp/",
|
||||
"shop-url": "https://shop.freecodecamp.org/",
|
||||
"support-url": "https://www.freecodecamp.org/ukrainian/news/chapy-freecodecamp-populyarni-zapytannya-tekhnichniy-pidtrymtsi/",
|
||||
"sponsors-url": "https://www.freecodecamp.org/news/sponsors/",
|
||||
"honesty-url": "https://www.freecodecamp.org/ukrainian/news/polityka-akademichnoyi-dobrochesnosti-freecodecamp/",
|
||||
"coc-url": "https://www.freecodecamp.org/ukrainian/news/kodeks-povedinky-freecodecamp/",
|
||||
"privacy-url": "https://www.freecodecamp.org/news/privacy-policy/",
|
||||
"tos-url": "https://www.freecodecamp.org/news/terms-of-service/",
|
||||
"copyright-url": "https://www.freecodecamp.org/news/copyright-policy/"
|
||||
},
|
||||
"donate": {
|
||||
"other-ways-url": "https://www.freecodecamp.org/news/how-to-donate-to-free-code-camp",
|
||||
"download-irs-url": "https://s3.amazonaws.com/freecodecamp/Free+Code+Camp+Inc+IRS+Determination+Letter.pdf",
|
||||
"download-990-url": "https://freecodecamp.s3.amazonaws.com/freeCodeCamp+2019+f990.pdf",
|
||||
"one-time-url": "https://paypal.me/freecodecamp"
|
||||
},
|
||||
"nav": {
|
||||
"contribute": "https://contribute.freecodecamp.org/#/i18n/ukrainian/index",
|
||||
"forum": "https://forum.freecodecamp.org/",
|
||||
"news": "https://www.freecodecamp.org/ukrainian/news/",
|
||||
"podcast": "https://freecodecamp.libsyn.com/"
|
||||
},
|
||||
"help": {
|
||||
"HTML-CSS": "curriculum-help",
|
||||
"JavaScript": "curriculum-help",
|
||||
"Python": "curriculum-help",
|
||||
"Backend Development": "curriculum-help",
|
||||
"C-Sharp": "curriculum-help",
|
||||
"English": "curriculum-help",
|
||||
"Spanish Curriculum": "curriculum-help",
|
||||
"Chinese Curriculum": "curriculum-help",
|
||||
"Odin": "curriculum-help",
|
||||
"Euler": "curriculum-help",
|
||||
"Rosetta": "curriculum-help",
|
||||
"General": "curriculum-help"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
import path from 'path';
|
||||
import { readFile } from 'fs/promises';
|
||||
import { availableLangs } from '@freecodecamp/shared/config/i18n';
|
||||
import introSchema from './locales/english/intro.json';
|
||||
import linksSchema from './locales/english/links.json';
|
||||
import metaTagsSchema from './locales/english/meta-tags.json';
|
||||
import motivationSchema from './locales/english/motivation.json';
|
||||
import translationsSchema from './locales/english/translations.json';
|
||||
|
||||
type MotivationalQuotes = { quote: string; author: string }[];
|
||||
|
||||
/**
|
||||
* Flattens a nested object structure into a single
|
||||
* object with property chains as keys.
|
||||
* @param {Object} obj Object to flatten
|
||||
* @param {String} namespace Used for property chaining
|
||||
*/
|
||||
const flattenAnObject = (obj: Record<string, unknown>, namespace = '') => {
|
||||
const flattened: Record<string, unknown> = {};
|
||||
Object.keys(obj).forEach(key => {
|
||||
const value = obj[key];
|
||||
const field = namespace ? `${namespace}.${key}` : key;
|
||||
if (Array.isArray(value)) {
|
||||
flattened[field] = value;
|
||||
} else if (typeof value === 'object') {
|
||||
Object.assign(
|
||||
flattened,
|
||||
flattenAnObject(value as Record<string, unknown>, field)
|
||||
);
|
||||
} else {
|
||||
flattened[field] = value;
|
||||
}
|
||||
});
|
||||
return flattened;
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if a translation object is missing keys
|
||||
* that are present in the schema.
|
||||
* @param {String[]} file Array of translation object's keys
|
||||
* @param {String[]} schema Array of matching schema's keys
|
||||
* @param {String} path string path to file
|
||||
*/
|
||||
const findMissingKeys = (file: string[], schema: string[], path: string) => {
|
||||
const missingKeys = [];
|
||||
for (const key of schema) {
|
||||
if (!file.includes(key)) {
|
||||
missingKeys.push(key);
|
||||
}
|
||||
}
|
||||
if (missingKeys.length) {
|
||||
console.warn(
|
||||
`${path} is missing these required keys: ${missingKeys.join(', ')}`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if a translation object has extra
|
||||
* keys which are NOT present in the schema.
|
||||
* @param {String[]} file Array of translation object's keys
|
||||
* @param {String[]} schema Array of matching schema's keys
|
||||
* @param {String} path string path to file
|
||||
*/
|
||||
const findExtraneousKeys = (file: string[], schema: string[], path: string) => {
|
||||
const extraKeys = [];
|
||||
for (const key of file) {
|
||||
if (!schema.includes(key)) {
|
||||
extraKeys.push(key);
|
||||
}
|
||||
}
|
||||
if (extraKeys.length) {
|
||||
console.warn(
|
||||
`${path} has these keys that are not in the schema: ${extraKeys.join(
|
||||
', '
|
||||
)}`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Validates that all values in the object are non-empty. Includes
|
||||
* validation of nested objects.
|
||||
* @param {Object} obj The object to check the values of
|
||||
* @param {String} namespace String for tracking nested properties
|
||||
*/
|
||||
const noEmptyObjectValues = (
|
||||
obj: Record<string, unknown>,
|
||||
namespace = ''
|
||||
): string[] => {
|
||||
const emptyKeys = [];
|
||||
for (const key of Object.keys(obj)) {
|
||||
const value = obj[key];
|
||||
const field = namespace ? `${namespace}.${key}` : key;
|
||||
if (Array.isArray(value)) {
|
||||
if (!value.length) {
|
||||
emptyKeys.push(field);
|
||||
}
|
||||
} else if (typeof value === 'object') {
|
||||
emptyKeys.push(
|
||||
noEmptyObjectValues(value as Record<string, unknown>, field)
|
||||
);
|
||||
} else if (!value) {
|
||||
emptyKeys.push(field);
|
||||
}
|
||||
}
|
||||
return emptyKeys.flat();
|
||||
};
|
||||
|
||||
/**
|
||||
* Grab the schema keys once, to avoid overhead of
|
||||
* fetching within iterative function.
|
||||
*/
|
||||
const translationSchemaKeys = Object.keys(flattenAnObject(translationsSchema));
|
||||
const motivationSchemaKeys = Object.keys(flattenAnObject(motivationSchema));
|
||||
const introSchemaKeys = Object.keys(flattenAnObject(introSchema));
|
||||
const metaTagsSchemaKeys = Object.keys(flattenAnObject(metaTagsSchema));
|
||||
const linksSchemaKeys = Object.keys(flattenAnObject(linksSchema));
|
||||
|
||||
/**
|
||||
* Function that checks the translations.json file
|
||||
* for each available client language.
|
||||
* @param {String[]} languages List of languages to test
|
||||
*/
|
||||
const translationSchemaValidation = (languages: string[]) => {
|
||||
languages.forEach(language => {
|
||||
void readJsonFile(language, 'translations').then(fileJson => {
|
||||
schemaValidation(
|
||||
language,
|
||||
'translations',
|
||||
fileJson,
|
||||
translationSchemaKeys
|
||||
);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Function that checks the motivation.json file
|
||||
* for each available client language.
|
||||
* @param {String[]} languages List of languages to test
|
||||
*/
|
||||
const motivationSchemaValidation = (languages: string[]) => {
|
||||
languages.forEach(language => {
|
||||
void readJsonFile(language, 'motivation').then(fileJson => {
|
||||
schemaValidation(language, 'motivation', fileJson, motivationSchemaKeys);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Function that checks the intro.json file
|
||||
* for each available client language.
|
||||
* @param {String[]} languages List of languages to test
|
||||
*/
|
||||
const introSchemaValidation = (languages: string[]) => {
|
||||
languages.forEach(language => {
|
||||
void readJsonFile(language, 'intro').then(fileJson => {
|
||||
schemaValidation(language, 'intro', fileJson, introSchemaKeys);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Function that checks the meta-tags.json file
|
||||
* for each available client language.
|
||||
* @param {String[]} languages List of languages to test
|
||||
*/
|
||||
const metaTagsSchemaValidation = (languages: string[]) => {
|
||||
languages.forEach(language => {
|
||||
void readJsonFile(language, 'meta-tags').then(fileJson => {
|
||||
schemaValidation(language, 'meta-tags', fileJson, metaTagsSchemaKeys);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Function that checks the links.json file
|
||||
* for each available client language.
|
||||
* @param {String[]} languages List of languages to test
|
||||
*/
|
||||
const linksSchemaValidation = (languages: string[]) => {
|
||||
languages.forEach(language => {
|
||||
void readJsonFile(language, 'links').then(fileJson => {
|
||||
schemaValidation(language, 'links', fileJson, linksSchemaKeys);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Common Function that checks the json file
|
||||
* @param {String} language the language to test
|
||||
* @param {String} fileName the fileName of json file to test
|
||||
* @param {Object} fileJson the fileJson got by readJsonFile
|
||||
* @param {String[]} schemaKeys Array of matching schema's keys
|
||||
*/
|
||||
const schemaValidation = (
|
||||
language: string,
|
||||
fileName: string,
|
||||
fileJson: Record<string, unknown>,
|
||||
schemaKeys: string[]
|
||||
) => {
|
||||
const fileKeys = Object.keys(flattenAnObject(fileJson));
|
||||
findMissingKeys(fileKeys, schemaKeys, `${language}/${fileName}.json`);
|
||||
findExtraneousKeys(fileKeys, schemaKeys, `${language}/${fileName}.json`);
|
||||
const emptyKeys = noEmptyObjectValues(fileJson);
|
||||
if (emptyKeys.length) {
|
||||
console.warn(
|
||||
`${language}/${fileName}.json has these empty keys: ${emptyKeys.join(
|
||||
', '
|
||||
)}`
|
||||
);
|
||||
}
|
||||
// Special line to assert that objects in motivational quote are correct
|
||||
if (
|
||||
fileName === 'motivation' &&
|
||||
!(fileJson.motivationalQuotes as MotivationalQuotes).every(
|
||||
object =>
|
||||
Object.prototype.hasOwnProperty.call(object, 'quote') &&
|
||||
Object.prototype.hasOwnProperty.call(object, 'author')
|
||||
)
|
||||
) {
|
||||
console.warn(`${language}/${fileName}.json has malformed quote objects.`);
|
||||
}
|
||||
console.info(`${language} ${fileName}.json validation complete`);
|
||||
};
|
||||
|
||||
const readJsonFile = async (language: string, fileName: string) => {
|
||||
const filePath = path.join(
|
||||
__dirname,
|
||||
`/locales/${language}/${fileName}.json`
|
||||
);
|
||||
const file = await readFile(filePath, 'utf8');
|
||||
const fileJson = JSON.parse(file) as Record<string, unknown>;
|
||||
return fileJson;
|
||||
};
|
||||
|
||||
const translatedLangs = availableLangs.client.filter(
|
||||
x => String(x) !== 'english'
|
||||
);
|
||||
|
||||
translationSchemaValidation(translatedLangs);
|
||||
motivationSchemaValidation(translatedLangs);
|
||||
introSchemaValidation(translatedLangs);
|
||||
metaTagsSchemaValidation(translatedLangs);
|
||||
linksSchemaValidation(translatedLangs);
|
||||
@@ -0,0 +1,189 @@
|
||||
{
|
||||
"name": "@freecodecamp/client",
|
||||
"version": "0.0.1",
|
||||
"description": "The freeCodeCamp.org open-source codebase and curriculum",
|
||||
"license": "BSD-3-Clause",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": ">=24",
|
||||
"pnpm": ">=10"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/freeCodeCamp/freeCodeCamp.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/freeCodeCamp/freeCodeCamp/issues"
|
||||
},
|
||||
"homepage": "https://github.com/freeCodeCamp/freeCodeCamp#readme",
|
||||
"author": "freeCodeCamp <team@freecodecamp.org>",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "NODE_OPTIONS=\"--max-old-space-size=7168 --no-deprecation\" gatsby build --prefix-paths",
|
||||
"clean": "gatsby clean",
|
||||
"copy:scripts": "tsx ./tools/copy-browser-scripts.ts",
|
||||
"create:i18n": "tsx ./tools/create-i18n.ts",
|
||||
"create:env": "DEBUG=fcc:* tsx ./tools/create-env.ts",
|
||||
"create:external-curriculum": "tsx ./tools/external-curriculum/build",
|
||||
"create:trending": "tsx ./tools/download-trending.ts",
|
||||
"create:search-placeholder": "tsx ./tools/generate-search-placeholder",
|
||||
"develop": "NODE_OPTIONS=\"--max-old-space-size=7168 --no-deprecation\" gatsby develop --inspect=9230",
|
||||
"lint": "eslint --max-warnings 0",
|
||||
"setup": "pnpm clean && pnpm create:env && pnpm create:i18n && pnpm create:trending && pnpm create:search-placeholder && pnpm create:external-curriculum && pnpm copy:scripts",
|
||||
"serve": "gatsby serve -p 8000",
|
||||
"serve-ci": "serve -l 8000 -c serve.json public",
|
||||
"prestand-alone": "pnpm run prebuild",
|
||||
"stand-alone": "gatsby develop",
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest",
|
||||
"test:ui": "vitest --ui",
|
||||
"type-check": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/plugin-proposal-export-default-from": "7.23.3",
|
||||
"@babel/plugin-proposal-function-bind": "7.23.3",
|
||||
"@babel/plugin-transform-runtime": "^7.19.6",
|
||||
"@babel/preset-env": "7.23.7",
|
||||
"@babel/preset-react": "7.23.3",
|
||||
"@babel/preset-typescript": "7.23.3",
|
||||
"@codesandbox/sandpack-react": "2.20.0",
|
||||
"@codesandbox/sandpack-themes": "2.0.21",
|
||||
"@fortawesome/fontawesome-svg-core": "7.2.0",
|
||||
"@fortawesome/free-brands-svg-icons": "7.2.0",
|
||||
"@fortawesome/free-solid-svg-icons": "7.2.0",
|
||||
"@fortawesome/react-fontawesome": "3.3.1",
|
||||
"@freecodecamp/challenge-builder": "workspace:*",
|
||||
"@freecodecamp/ui": "6.0.1",
|
||||
"@gatsbyjs/reach-router": "1.3.9",
|
||||
"@growthbook/growthbook-react": "1.6.5",
|
||||
"@loadable/component": "5.16.7",
|
||||
"@redux-devtools/extension": "3.3.0",
|
||||
"@redux-saga/core": "^1.4.2",
|
||||
"@reduxjs/toolkit": "2.11.2",
|
||||
"@stripe/react-stripe-js": "1.16.5",
|
||||
"@stripe/stripe-js": "1.54.2",
|
||||
"@types/react-speech-recognition": "3.9.6",
|
||||
"@xterm/addon-fit": "0.11.0",
|
||||
"@xterm/xterm": "6.0.0",
|
||||
"algoliasearch": "4.27.0",
|
||||
"assert": "2.0.0",
|
||||
"babel-plugin-preval": "5.1.0",
|
||||
"babel-plugin-prismjs": "2.1.0",
|
||||
"bezier-easing": "2.1.0",
|
||||
"browser-cookies": "1.2.0",
|
||||
"canvas-confetti": "^1.6.0",
|
||||
"crypto-browserify": "3.12.1",
|
||||
"date-fns": "4.1.0",
|
||||
"date-fns-tz": "3.2.0",
|
||||
"eslint-config-react-app": "^7.0.1",
|
||||
"final-form": "4.20.10",
|
||||
"gatsby": "5.16.1",
|
||||
"gatsby-cli": "5.16.0",
|
||||
"gatsby-plugin-postcss": "6.16.0",
|
||||
"gatsby-plugin-react-helmet": "6.16.0",
|
||||
"gatsby-plugin-remove-serviceworker": "1.0.0",
|
||||
"gatsby-source-filesystem": "5.16.0",
|
||||
"gatsby-transformer-remark": "6.16.0",
|
||||
"i18next": "25.10.10",
|
||||
"instantsearch.js": "4.95.0",
|
||||
"lodash": "4.18.1",
|
||||
"lodash-es": "4.18.1",
|
||||
"micromark": "4.0.2",
|
||||
"monaco-editor": "0.55.1",
|
||||
"nanoid": "3.3.12",
|
||||
"normalize-url": "6.1.0",
|
||||
"path-browserify": "1.0.1",
|
||||
"pinyin-tone": "2.4.0",
|
||||
"postcss": "8.5.13",
|
||||
"prismjs": "1.30.0",
|
||||
"process": "0.11.10",
|
||||
"prop-types": "15.8.1",
|
||||
"qrcode.react": "^3.1.0",
|
||||
"query-string": "7.1.3",
|
||||
"react": "18.3.1",
|
||||
"react-calendar-heatmap": "1.10.0",
|
||||
"react-dom": "18.3.1",
|
||||
"react-final-form": "6.5.9",
|
||||
"react-gtm-module": "2.0.11",
|
||||
"react-helmet": "6.1.0",
|
||||
"react-hotkeys": "2.0.0",
|
||||
"react-i18next": "15.7.4",
|
||||
"react-instantsearch": "7.31.0",
|
||||
"react-instantsearch-core": "7.31.0",
|
||||
"react-monaco-editor": "0.59.0",
|
||||
"react-redux": "8.1.3",
|
||||
"react-reflex": "4.2.7",
|
||||
"react-responsive": "9.0.2",
|
||||
"react-scroll": "1.9.3",
|
||||
"react-speech-recognition": "4.0.1",
|
||||
"react-spinkit": "3.0.0",
|
||||
"react-tooltip": "4.5.1",
|
||||
"react-transition-group": "4.4.5",
|
||||
"react-youtube": "10.1.0",
|
||||
"redux": "4.2.1",
|
||||
"redux-actions": "2.6.5",
|
||||
"redux-observable": "1.2.0",
|
||||
"redux-saga": "1.4.2",
|
||||
"reselect": "4.1.8",
|
||||
"rxjs": "6.6.7",
|
||||
"sanitize-html": "2.17.3",
|
||||
"store": "2.0.12",
|
||||
"stream-browserify": "3.0.0",
|
||||
"tone": "15.1.22",
|
||||
"typescript": "5.9.3",
|
||||
"util": "0.12.5",
|
||||
"uuid": "8.3.2",
|
||||
"validator": "13.15.35"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-syntax-dynamic-import": "7.8.3",
|
||||
"@freecodecamp/browser-scripts": "workspace:*",
|
||||
"@freecodecamp/curriculum": "workspace:*",
|
||||
"@freecodecamp/eslint-config": "workspace:*",
|
||||
"@freecodecamp/shared": "workspace:*",
|
||||
"@testing-library/jest-dom": "^6.8.0",
|
||||
"@testing-library/react": "14.3.1",
|
||||
"@testing-library/user-event": "14.6.1",
|
||||
"@total-typescript/ts-reset": "^0.5.0",
|
||||
"@types/canvas-confetti": "^1.6.0",
|
||||
"@types/gatsbyjs__reach-router": "1.3.0",
|
||||
"@types/js-yaml": "4.0.9",
|
||||
"@types/loadable__component": "5.13.10",
|
||||
"@types/lodash-es": "^4.17.6",
|
||||
"@types/prismjs": "^1.26.0",
|
||||
"@types/react": "18.3.28",
|
||||
"@types/react-dom": "18.3.7",
|
||||
"@types/react-gtm-module": "2.0.4",
|
||||
"@types/react-helmet": "6.1.11",
|
||||
"@types/react-redux": "7.1.34",
|
||||
"@types/react-scroll": "1.8.10",
|
||||
"@types/react-spinkit": "3.0.10",
|
||||
"@types/react-test-renderer": "16.9.12",
|
||||
"@types/react-transition-group": "4.4.12",
|
||||
"@types/redux-actions": "2.6.5",
|
||||
"@types/sanitize-html": "^2.8.0",
|
||||
"@types/store": "^2.0.2",
|
||||
"@types/validator": "^13.7.12",
|
||||
"@vitest/ui": "^4.0.15",
|
||||
"autoprefixer": "10.4.27",
|
||||
"babel-plugin-macros": "3.1.0",
|
||||
"core-js": "3.49.0",
|
||||
"dotenv": "16.6.1",
|
||||
"eslint": "^9.39.1",
|
||||
"eslint-plugin-flowtype": "^8.0.3",
|
||||
"gatsby-plugin-pnpm-gatsby-5": "1.2.11",
|
||||
"gatsby-plugin-schema-snapshot": "4.16.0",
|
||||
"gatsby-plugin-webpack-bundle-analyser-v2": "1.1.32",
|
||||
"i18next-fs-backend": "2.6.5",
|
||||
"joi": "18.1.2",
|
||||
"js-yaml": "4.1.0",
|
||||
"monaco-editor-webpack-plugin": "7.1.1",
|
||||
"react-test-renderer": "18.3.1",
|
||||
"readdirp": "3.6.0",
|
||||
"redux-saga-test-plan": "4.0.6",
|
||||
"serve": "13.0.4",
|
||||
"url": "0.11.4",
|
||||
"vitest": "^4.0.15",
|
||||
"webpack": "5.106.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
autoprefixer: {
|
||||
overrideBrowserslist: ['last 2 versions']
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,577 @@
|
||||
### Type definitions saved at 2026-03-10T08:56:46.271Z ###
|
||||
|
||||
enum RemoteFileFit {
|
||||
COVER
|
||||
FILL
|
||||
OUTSIDE
|
||||
CONTAIN
|
||||
}
|
||||
|
||||
enum RemoteFileFormat {
|
||||
AUTO
|
||||
JPG
|
||||
PNG
|
||||
WEBP
|
||||
AVIF
|
||||
}
|
||||
|
||||
enum RemoteFileLayout {
|
||||
FIXED
|
||||
FULL_WIDTH
|
||||
CONSTRAINED
|
||||
}
|
||||
|
||||
enum RemoteFilePlaceholder {
|
||||
DOMINANT_COLOR
|
||||
BLURRED
|
||||
TRACED_SVG
|
||||
NONE
|
||||
}
|
||||
|
||||
enum RemoteFileCropFocus {
|
||||
CENTER
|
||||
TOP
|
||||
RIGHT
|
||||
BOTTOM
|
||||
LEFT
|
||||
ENTROPY
|
||||
EDGES
|
||||
FACES
|
||||
}
|
||||
|
||||
type RemoteFileResize {
|
||||
width: Int
|
||||
height: Int
|
||||
src: String
|
||||
}
|
||||
|
||||
"""
|
||||
Remote Interface
|
||||
"""
|
||||
interface RemoteFile {
|
||||
id: ID!
|
||||
mimeType: String!
|
||||
filename: String!
|
||||
filesize: Int
|
||||
width: Int
|
||||
height: Int
|
||||
publicUrl: String!
|
||||
resize(
|
||||
width: Int
|
||||
height: Int
|
||||
aspectRatio: Float
|
||||
fit: RemoteFileFit = COVER
|
||||
|
||||
"""
|
||||
The image formats to generate. Valid values are AUTO (meaning the same
|
||||
format as the source image), JPG, PNG, WEBP and AVIF.
|
||||
The default value is [AUTO, WEBP, AVIF], and you should rarely need to
|
||||
change this. Take care if you specify JPG or PNG when you do
|
||||
not know the formats of the source images, as this could lead to unwanted
|
||||
results such as converting JPEGs to PNGs. Specifying
|
||||
both PNG and JPG is not supported and will be ignored.
|
||||
"""
|
||||
format: RemoteFileFormat = AUTO
|
||||
cropFocus: [RemoteFileCropFocus]
|
||||
quality: Int = 75
|
||||
): RemoteFileResize
|
||||
|
||||
"""
|
||||
Data used in the <GatsbyImage /> component. See https://gatsby.dev/img for more info.
|
||||
"""
|
||||
gatsbyImage(
|
||||
"""
|
||||
The layout for the image.
|
||||
FIXED: A static image sized, that does not resize according to the screen width
|
||||
FULL_WIDTH: The image resizes to fit its container. Pass a "sizes" option if
|
||||
it isn't going to be the full width of the screen.
|
||||
CONSTRAINED: Resizes to fit its container, up to a maximum width, at which point it will remain fixed in size.
|
||||
"""
|
||||
layout: RemoteFileLayout = CONSTRAINED
|
||||
|
||||
"""
|
||||
The display width of the generated image for layout = FIXED, and the display
|
||||
width of the largest image for layout = CONSTRAINED.
|
||||
The actual largest image resolution will be this value multiplied by the largest value in outputPixelDensities
|
||||
Ignored if layout = FLUID.
|
||||
"""
|
||||
width: Int
|
||||
|
||||
"""
|
||||
If set, the height of the generated image. If omitted, it is calculated from
|
||||
the supplied width, matching the aspect ratio of the source image.
|
||||
"""
|
||||
height: Int
|
||||
|
||||
"""
|
||||
Format of generated placeholder image, displayed while the main image loads.
|
||||
BLURRED: a blurred, low resolution image, encoded as a base64 data URI
|
||||
DOMINANT_COLOR: a solid color, calculated from the dominant color of the image (default).
|
||||
TRACED_SVG: deprecated. Will use DOMINANT_COLOR.
|
||||
NONE: no placeholder. Set the argument "backgroundColor" to use a fixed background color.
|
||||
"""
|
||||
placeholder: RemoteFilePlaceholder = DOMINANT_COLOR
|
||||
|
||||
"""
|
||||
If set along with width or height, this will set the value of the other
|
||||
dimension to match the provided aspect ratio, cropping the image if needed.
|
||||
If neither width or height is provided, height will be set based on the intrinsic width of the source image.
|
||||
"""
|
||||
aspectRatio: Float
|
||||
|
||||
"""
|
||||
The image formats to generate. Valid values are AUTO (meaning the same
|
||||
format as the source image), JPG, PNG, WEBP and AVIF.
|
||||
The default value is [AUTO, WEBP, AVIF], and you should rarely need to
|
||||
change this. Take care if you specify JPG or PNG when you do
|
||||
not know the formats of the source images, as this could lead to unwanted
|
||||
results such as converting JPEGs to PNGs. Specifying
|
||||
both PNG and JPG is not supported and will be ignored.
|
||||
"""
|
||||
formats: [RemoteFileFormat!] = [AUTO, WEBP, AVIF]
|
||||
|
||||
"""
|
||||
A list of image pixel densities to generate for FIXED and CONSTRAINED
|
||||
images. You should rarely need to change this. It will never generate images
|
||||
larger than the source, and will always include a 1x image.
|
||||
Default is [ 1, 2 ] for fixed images, meaning 1x, 2x, and [0.25, 0.5, 1, 2]
|
||||
for fluid. In this case, an image with a fluid layout and width = 400 would
|
||||
generate images at 100, 200, 400 and 800px wide.
|
||||
"""
|
||||
outputPixelDensities: [Float] = [0.25, 0.5, 1, 2]
|
||||
|
||||
"""
|
||||
Specifies the image widths to generate. You should rarely need to change
|
||||
this. For FIXED and CONSTRAINED images it is better to allow these to be
|
||||
determined automatically,
|
||||
based on the image size. For FULL_WIDTH images this can be used to override
|
||||
the default, which is [750, 1080, 1366, 1920].
|
||||
It will never generate any images larger than the source.
|
||||
"""
|
||||
breakpoints: [Int] = [750, 1080, 1366, 1920]
|
||||
|
||||
"""
|
||||
The "sizes" property, passed to the img tag. This describes the display size of the image.
|
||||
This does not affect the generated images, but is used by the browser to
|
||||
decide which images to download. You can leave this blank for fixed images,
|
||||
or if the responsive image
|
||||
container will be the full width of the screen. In these cases we will generate an appropriate value.
|
||||
"""
|
||||
sizes: String
|
||||
|
||||
"""
|
||||
Background color applied to the wrapper, or when "letterboxing" an image to another aspect ratio.
|
||||
"""
|
||||
backgroundColor: String
|
||||
fit: RemoteFileFit = COVER
|
||||
cropFocus: [RemoteFileCropFocus]
|
||||
quality: Int = 75
|
||||
): GatsbyImageData
|
||||
}
|
||||
|
||||
type File implements Node @dontInfer {
|
||||
sourceInstanceName: String!
|
||||
absolutePath: String!
|
||||
relativePath: String!
|
||||
extension: String!
|
||||
size: Int!
|
||||
prettySize: String!
|
||||
modifiedTime: Date! @dateformat
|
||||
accessTime: Date! @dateformat
|
||||
changeTime: Date! @dateformat
|
||||
birthTime: Date! @dateformat
|
||||
root: String!
|
||||
dir: String!
|
||||
base: String!
|
||||
ext: String!
|
||||
name: String!
|
||||
relativeDirectory: String!
|
||||
dev: Int!
|
||||
mode: Int!
|
||||
nlink: Int!
|
||||
uid: Int!
|
||||
gid: Int!
|
||||
rdev: Int!
|
||||
ino: Float!
|
||||
atimeMs: Float!
|
||||
mtimeMs: Float!
|
||||
ctimeMs: Float!
|
||||
atime: Date! @dateformat
|
||||
mtime: Date! @dateformat
|
||||
ctime: Date! @dateformat
|
||||
birthtime: Date @deprecated(reason: "Use `birthTime` instead")
|
||||
birthtimeMs: Float @deprecated(reason: "Use `birthTime` instead")
|
||||
}
|
||||
|
||||
type Directory implements Node @dontInfer {
|
||||
sourceInstanceName: String!
|
||||
absolutePath: String!
|
||||
relativePath: String!
|
||||
extension: String!
|
||||
size: Int!
|
||||
prettySize: String!
|
||||
modifiedTime: Date! @dateformat
|
||||
accessTime: Date! @dateformat
|
||||
changeTime: Date! @dateformat
|
||||
birthTime: Date! @dateformat
|
||||
root: String!
|
||||
dir: String!
|
||||
base: String!
|
||||
ext: String!
|
||||
name: String!
|
||||
relativeDirectory: String!
|
||||
dev: Int!
|
||||
mode: Int!
|
||||
nlink: Int!
|
||||
uid: Int!
|
||||
gid: Int!
|
||||
rdev: Int!
|
||||
ino: Float!
|
||||
atimeMs: Float!
|
||||
mtimeMs: Float!
|
||||
ctimeMs: Float!
|
||||
atime: Date! @dateformat
|
||||
mtime: Date! @dateformat
|
||||
ctime: Date! @dateformat
|
||||
birthtime: Date @deprecated(reason: "Use `birthTime` instead")
|
||||
birthtimeMs: Float @deprecated(reason: "Use `birthTime` instead")
|
||||
}
|
||||
|
||||
type Site implements Node @derivedTypes @dontInfer {
|
||||
buildTime: Date @dateformat
|
||||
siteMetadata: SiteSiteMetadata
|
||||
port: Int
|
||||
host: String
|
||||
flags: SiteFlags
|
||||
trailingSlash: String
|
||||
pathPrefix: String
|
||||
polyfill: Boolean
|
||||
jsxRuntime: String
|
||||
graphqlTypegen: Boolean
|
||||
}
|
||||
|
||||
type SiteSiteMetadata {
|
||||
title: String
|
||||
description: String
|
||||
siteUrl: String
|
||||
}
|
||||
|
||||
type SiteFlags {
|
||||
DEV_SSR: Boolean
|
||||
}
|
||||
|
||||
type SiteFunction implements Node @dontInfer {
|
||||
functionRoute: String!
|
||||
pluginName: String!
|
||||
originalAbsoluteFilePath: String!
|
||||
originalRelativeFilePath: String!
|
||||
relativeCompiledFilePath: String!
|
||||
absoluteCompiledFilePath: String!
|
||||
matchPath: String
|
||||
}
|
||||
|
||||
type SitePage implements Node @dontInfer {
|
||||
path: String!
|
||||
component: String!
|
||||
internalComponentName: String!
|
||||
componentChunkName: String!
|
||||
matchPath: String
|
||||
pageContext: JSON @proxy(from: "context", fromNode: false)
|
||||
pluginCreator: SitePlugin @link(by: "id", from: "pluginCreatorId")
|
||||
}
|
||||
|
||||
type SitePlugin implements Node @dontInfer {
|
||||
resolve: String
|
||||
name: String
|
||||
version: String
|
||||
nodeAPIs: [String]
|
||||
browserAPIs: [String]
|
||||
ssrAPIs: [String]
|
||||
pluginFilepath: String
|
||||
pluginOptions: JSON
|
||||
packageJson: JSON
|
||||
}
|
||||
|
||||
type SiteBuildMetadata implements Node @dontInfer {
|
||||
buildTime: Date @dateformat
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeHooks {
|
||||
afterEach: String
|
||||
beforeAll: String
|
||||
beforeEach: String
|
||||
afterAll: String
|
||||
}
|
||||
|
||||
type SuperBlockStructure implements Node @derivedTypes @dontInfer {
|
||||
chapters: [SuperBlockStructureChapters]
|
||||
superBlock: String
|
||||
blocks: [String]
|
||||
}
|
||||
|
||||
type SuperBlockStructureChapters @derivedTypes {
|
||||
dashedName: String
|
||||
modules: [SuperBlockStructureChaptersModules]
|
||||
chapterType: String
|
||||
comingSoon: Boolean
|
||||
}
|
||||
|
||||
type SuperBlockStructureChaptersModules {
|
||||
dashedName: String
|
||||
blocks: [String]
|
||||
moduleType: String
|
||||
comingSoon: Boolean
|
||||
}
|
||||
|
||||
type ChallengeNode implements Node @derivedTypes @dontInfer {
|
||||
sourceInstanceName: String
|
||||
challenge: ChallengeNodeChallenge
|
||||
}
|
||||
|
||||
type ChallengeNodeChallenge @derivedTypes {
|
||||
id: String
|
||||
title: String
|
||||
challengeType: Int
|
||||
dashedName: String
|
||||
demoType: String
|
||||
challengeFiles: [ChallengeNodeChallengeChallengeFiles]
|
||||
solutions: [[ChallengeNodeChallengeSolutions]]
|
||||
assignments: [String]
|
||||
tests: [ChallengeNodeChallengeTests]
|
||||
description: String
|
||||
translationPending: Boolean
|
||||
sourceLocation: String
|
||||
block: String
|
||||
blockLabel: String
|
||||
blockLayout: String
|
||||
hasEditableBoundaries: Boolean
|
||||
order: Int
|
||||
instructions: String
|
||||
questions: [ChallengeNodeChallengeQuestions]
|
||||
superBlock: String
|
||||
superOrder: Int
|
||||
challengeOrder: Int
|
||||
isLastChallengeInBlock: Boolean
|
||||
required: [ChallengeNodeChallengeRequired]
|
||||
helpCategory: String
|
||||
usesMultifileEditor: Boolean
|
||||
disableLoopProtectTests: Boolean
|
||||
disableLoopProtectPreview: Boolean
|
||||
certification: String
|
||||
fields: ChallengeNodeChallengeFields
|
||||
quizzes: [ChallengeNodeChallengeQuizzes]
|
||||
chapter: String
|
||||
module: String
|
||||
hooks: ChallengeNodeChallengeHooks
|
||||
nodules: [ChallengeNodeChallengeNodules]
|
||||
forumTopicId: Int
|
||||
videoId: String
|
||||
bilibiliIds: ChallengeNodeChallengeBilibiliIds
|
||||
saveSubmissionToDB: Boolean
|
||||
lang: String
|
||||
scene: ChallengeNodeChallengeScene
|
||||
explanation: String
|
||||
fillInTheBlank: ChallengeNodeChallengeFillInTheBlank
|
||||
inputType: String
|
||||
videoUrl: String
|
||||
url: String
|
||||
template: String
|
||||
transcript: String
|
||||
isExam: Boolean
|
||||
videoLocaleIds: ChallengeNodeChallengeVideoLocaleIds
|
||||
notes: String
|
||||
prerequisites: [ChallengeNodeChallengePrerequisites]
|
||||
msTrophyId: String
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeChallengeFiles {
|
||||
head: String
|
||||
tail: String
|
||||
id: String
|
||||
editableRegionBoundaries: [Int]
|
||||
history: [String]
|
||||
name: String
|
||||
ext: String
|
||||
path: String
|
||||
fileKey: String
|
||||
contents: String
|
||||
seed: String
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeSolutions {
|
||||
head: String
|
||||
tail: String
|
||||
id: String
|
||||
history: [String]
|
||||
name: String
|
||||
ext: String
|
||||
path: String
|
||||
fileKey: String
|
||||
contents: String
|
||||
seed: String
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeTests {
|
||||
text: String
|
||||
testString: String
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeQuestions @derivedTypes {
|
||||
text: String
|
||||
answers: [ChallengeNodeChallengeQuestionsAnswers]
|
||||
solution: Int
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeQuestionsAnswers {
|
||||
answer: String
|
||||
feedback: String
|
||||
audioId: String
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeRequired {
|
||||
src: String
|
||||
link: String
|
||||
raw: Boolean
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeFields {
|
||||
slug: String
|
||||
blockHashSlug: String
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeQuizzes @derivedTypes {
|
||||
questions: [ChallengeNodeChallengeQuizzesQuestions]
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeQuizzesQuestions @derivedTypes {
|
||||
text: String
|
||||
distractors: [String]
|
||||
answer: String
|
||||
audioData: ChallengeNodeChallengeQuizzesQuestionsAudioData
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeQuizzesQuestionsAudioData @derivedTypes {
|
||||
audio: ChallengeNodeChallengeQuizzesQuestionsAudioDataAudio
|
||||
transcript: [ChallengeNodeChallengeQuizzesQuestionsAudioDataTranscript]
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeQuizzesQuestionsAudioDataAudio {
|
||||
filename: String
|
||||
startTimestamp: Float
|
||||
finishTimestamp: Float
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeQuizzesQuestionsAudioDataTranscript {
|
||||
character: String
|
||||
text: String
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeNodules @derivedTypes {
|
||||
type: String
|
||||
contents: String
|
||||
files: [ChallengeNodeChallengeNodulesFiles]
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeNodulesFiles {
|
||||
contents: String
|
||||
ext: String
|
||||
name: String
|
||||
contentsHtml: String
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeBilibiliIds {
|
||||
aid: Int
|
||||
bvid: String
|
||||
cid: Int
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeScene @derivedTypes {
|
||||
setup: ChallengeNodeChallengeSceneSetup
|
||||
commands: [ChallengeNodeChallengeSceneCommands]
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeSceneSetup @derivedTypes {
|
||||
background: String
|
||||
characters: [ChallengeNodeChallengeSceneSetupCharacters]
|
||||
audio: ChallengeNodeChallengeSceneSetupAudio
|
||||
alwaysShowDialogue: Boolean
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeSceneSetupCharacters @derivedTypes {
|
||||
character: String
|
||||
position: ChallengeNodeChallengeSceneSetupCharactersPosition
|
||||
opacity: Int
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeSceneSetupCharactersPosition {
|
||||
x: Int
|
||||
y: Int
|
||||
z: Float
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeSceneSetupAudio {
|
||||
filename: String
|
||||
startTime: Float
|
||||
startTimestamp: Float
|
||||
finishTimestamp: Float
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeSceneCommands @derivedTypes {
|
||||
character: String
|
||||
opacity: Int
|
||||
startTime: Float
|
||||
finishTime: Float
|
||||
dialogue: ChallengeNodeChallengeSceneCommandsDialogue
|
||||
position: ChallengeNodeChallengeSceneCommandsPosition
|
||||
background: String
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeSceneCommandsDialogue {
|
||||
text: String
|
||||
align: String
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeSceneCommandsPosition {
|
||||
x: Int
|
||||
y: Int
|
||||
z: Float
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeFillInTheBlank @derivedTypes {
|
||||
sentence: String
|
||||
blanks: [ChallengeNodeChallengeFillInTheBlankBlanks]
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeFillInTheBlankBlanks {
|
||||
answer: String
|
||||
feedback: String
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengeVideoLocaleIds {
|
||||
espanol: String
|
||||
italian: String
|
||||
portuguese: String
|
||||
}
|
||||
|
||||
type ChallengeNodeChallengePrerequisites {
|
||||
id: String
|
||||
title: String
|
||||
}
|
||||
|
||||
type CertificateNode implements Node @derivedTypes @dontInfer {
|
||||
sourceInstanceName: String
|
||||
challenge: CertificateNodeChallenge
|
||||
}
|
||||
|
||||
type CertificateNodeChallenge @derivedTypes {
|
||||
id: String
|
||||
title: String
|
||||
certification: String
|
||||
challengeType: Int
|
||||
tests: [CertificateNodeChallengeTests]
|
||||
}
|
||||
|
||||
type CertificateNodeChallengeTests {
|
||||
id: String
|
||||
title: String
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import {
|
||||
wrapHandledError,
|
||||
unwrapHandledError
|
||||
} from '../../utils/handled-error';
|
||||
|
||||
describe('handled-error integration', () => {
|
||||
const handledA = {
|
||||
type: 'info',
|
||||
message: 'something helpful',
|
||||
redirectTo: '/a-path-we-choose'
|
||||
};
|
||||
const handledB = {
|
||||
type: 'danger',
|
||||
message: 'Oh noes!',
|
||||
redirectTo: '/whoops'
|
||||
};
|
||||
const handledC = {
|
||||
type: 'success',
|
||||
message: 'great news!',
|
||||
redirectTo: '/awesome'
|
||||
};
|
||||
const handledD = {};
|
||||
|
||||
it('can wrap and unwrap handled errors', () => {
|
||||
expect.assertions(4);
|
||||
const wrappedA = wrapHandledError(new Error(), handledA);
|
||||
const wrappedB = wrapHandledError(new Error(), handledB);
|
||||
const wrappedC = wrapHandledError(new Error(), handledC);
|
||||
const wrappedD = wrapHandledError(new Error(), handledD);
|
||||
|
||||
const unwrappedA = unwrapHandledError(wrappedA);
|
||||
const unwrappedB = unwrapHandledError(wrappedB);
|
||||
const unwrappedC = unwrapHandledError(wrappedC);
|
||||
const unwrappedD = unwrapHandledError(wrappedD);
|
||||
|
||||
expect(unwrappedA).toEqual(handledA);
|
||||
expect(unwrappedB).toEqual(handledB);
|
||||
expect(unwrappedC).toEqual(handledC);
|
||||
expect(unwrappedD).toEqual(handledD);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,7 @@
|
||||
const analytics = {
|
||||
event: function (): void {
|
||||
// comment necessary for linting.
|
||||
}
|
||||
};
|
||||
|
||||
export default analytics;
|
||||
@@ -0,0 +1,136 @@
|
||||
import {
|
||||
DonationAmount,
|
||||
DonationDuration
|
||||
} from '@freecodecamp/shared/config/donation-settings';
|
||||
import { ChallengeFiles } from '../redux/prop-types';
|
||||
import TagManager from '.';
|
||||
|
||||
type DonationEventAction =
|
||||
| 'Donate Page PayPal Payment Submission'
|
||||
| 'Donate Page Stripe Card Payment Submission'
|
||||
| 'Donate Page Stripe Payment Submission'
|
||||
| 'Modal PayPal Payment Submission'
|
||||
| 'Modal Stripe Card Payment Submission'
|
||||
| 'Modal Stripe Payment Submission'
|
||||
| 'Certificate PayPal Payment Submission'
|
||||
| 'Certificate Stripe Card Payment Submission'
|
||||
| 'Certificate Stripe Payment Submission';
|
||||
|
||||
interface DonationEvent {
|
||||
event: 'donation';
|
||||
action: DonationEventAction;
|
||||
duration: DonationDuration;
|
||||
amount: DonationAmount;
|
||||
completed_challenges: number;
|
||||
completed_challenges_session: number;
|
||||
isSignedIn: boolean;
|
||||
}
|
||||
|
||||
type DonationRelatedEventAction =
|
||||
| 'Learn Donation Alert Click'
|
||||
| 'Certification Donation Alert Click'
|
||||
| 'Modal Become Supporter Click'
|
||||
| 'Socrates LowerJaw Become Supporter Click'
|
||||
| 'Donate Page Patreon Payment Redirection'
|
||||
| 'Modal Patreon Payment Redirection'
|
||||
| 'Amount Confirmation Clicked'
|
||||
| 'Select Amount Tab Clicked'
|
||||
| 'Edit Amount Clicked'
|
||||
| 'Certificate Patreon Payment Redirection';
|
||||
|
||||
interface DonationRelatedEvent {
|
||||
event: 'donation_related';
|
||||
action: DonationRelatedEventAction;
|
||||
amount?: DonationAmount;
|
||||
}
|
||||
|
||||
type DonationViewEventAction =
|
||||
| 'Displayed Block Donation Modal'
|
||||
| 'Displayed Progress Donation Modal'
|
||||
| 'Displayed Donate Page'
|
||||
| 'Displayed Certificate Donation';
|
||||
|
||||
interface DonationViewEvent {
|
||||
event: 'donation_view';
|
||||
action: DonationViewEventAction;
|
||||
}
|
||||
|
||||
interface PageViewEvent {
|
||||
event: 'pageview';
|
||||
pagePath: string;
|
||||
}
|
||||
|
||||
interface ExperimentViewEvent {
|
||||
event: 'experiment_viewed';
|
||||
event_category: 'experiment';
|
||||
experiment_id: string;
|
||||
variation_id: number;
|
||||
}
|
||||
|
||||
interface ChallengeFailedEvent {
|
||||
event: 'challenge_failed';
|
||||
challenge_id: string;
|
||||
challenge_path: string;
|
||||
challenge_files: ChallengeFiles;
|
||||
}
|
||||
|
||||
interface UserData {
|
||||
event: 'user_data';
|
||||
user_id: string;
|
||||
}
|
||||
|
||||
interface SignIn {
|
||||
event: 'sign_in';
|
||||
}
|
||||
|
||||
interface SignOut {
|
||||
event: 'sign_out';
|
||||
user_id: undefined;
|
||||
}
|
||||
|
||||
interface ChallengeTestCodeButtonClickEvent {
|
||||
event: 'challenge_test_code_button_click';
|
||||
}
|
||||
|
||||
interface ChallengeSubmitButtonClickEvent {
|
||||
event: 'challenge_submit_button_click';
|
||||
}
|
||||
|
||||
interface CallSocratesEvent {
|
||||
event: 'call_socrates';
|
||||
action: 'Socrates LowerJaw Button Click';
|
||||
is_donating: boolean;
|
||||
attempts: number | null;
|
||||
limit: number | null;
|
||||
optimized_request: Record<string, unknown> | null;
|
||||
}
|
||||
|
||||
interface SendSocratesEvent {
|
||||
event: 'send_socrates';
|
||||
action: 'Socrates Request Sent';
|
||||
is_donating: boolean;
|
||||
attempts: number | null;
|
||||
limit: number | null;
|
||||
optimized_request: Record<string, unknown> | null;
|
||||
}
|
||||
|
||||
export type GAevent =
|
||||
| DonationViewEvent
|
||||
| DonationEvent
|
||||
| DonationRelatedEvent
|
||||
| PageViewEvent
|
||||
| ExperimentViewEvent
|
||||
| ChallengeFailedEvent
|
||||
| UserData
|
||||
| SignOut
|
||||
| SignIn
|
||||
| ChallengeTestCodeButtonClickEvent
|
||||
| ChallengeSubmitButtonClickEvent
|
||||
| CallSocratesEvent
|
||||
| SendSocratesEvent;
|
||||
|
||||
export default function callGA(payload: GAevent) {
|
||||
TagManager.dataLayer({
|
||||
dataLayer: payload
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import TagManager from 'react-gtm-module';
|
||||
|
||||
import {
|
||||
devAnalyticsId,
|
||||
prodAnalyticsId
|
||||
} from '../../config/analytics-settings';
|
||||
|
||||
import envData from '../../config/env.json';
|
||||
|
||||
const { deploymentEnv } = envData;
|
||||
|
||||
const analyticsIDSelector = () => {
|
||||
if (deploymentEnv === 'staging') return devAnalyticsId;
|
||||
else return prodAnalyticsId;
|
||||
};
|
||||
|
||||
const gtmId = analyticsIDSelector();
|
||||
|
||||
if (typeof document !== `undefined`) {
|
||||
TagManager.initialize({ gtmId });
|
||||
}
|
||||
|
||||
export default TagManager;
|
||||
@@ -0,0 +1,73 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
A1SpanishChapters,
|
||||
FsdChapters,
|
||||
A1ChineseChapters
|
||||
} from '@freecodecamp/shared/config/chapters';
|
||||
import DatabaseIcon from './icons/database';
|
||||
import JavaScriptIcon from './icons/javascript';
|
||||
import ReactIcon from './icons/react';
|
||||
import ResponsiveDesign from './icons/responsive-design';
|
||||
import FreeCodeCampIcon from './icons/freecodecamp';
|
||||
import Html from './icons/html';
|
||||
import Css from './icons/css';
|
||||
import NodeIcon from './icons/node';
|
||||
import Python from './icons/python';
|
||||
import Graduation from './icons/graduation';
|
||||
import {
|
||||
faBuilding,
|
||||
faComments,
|
||||
faCubes,
|
||||
faDoorOpen,
|
||||
faHands,
|
||||
faIdCard
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
|
||||
const iconMap = {
|
||||
[FsdChapters.Welcome]: FreeCodeCampIcon,
|
||||
[FsdChapters.Html]: Html,
|
||||
[FsdChapters.Css]: Css,
|
||||
[FsdChapters.Javascript]: JavaScriptIcon,
|
||||
[FsdChapters.FrontendLibraries]: ReactIcon,
|
||||
[FsdChapters.RelationalDatabases]: DatabaseIcon,
|
||||
[FsdChapters.BackendJavascript]: NodeIcon,
|
||||
[FsdChapters.Python]: Python,
|
||||
[FsdChapters.Career]: Graduation,
|
||||
[FsdChapters.RwdExam]: Graduation,
|
||||
[FsdChapters.JsExam]: Graduation,
|
||||
[FsdChapters.Fed]: ReactIcon,
|
||||
[FsdChapters.FedExam]: Graduation,
|
||||
[FsdChapters.PythonExam]: Graduation,
|
||||
[FsdChapters.RdbExam]: Graduation,
|
||||
[FsdChapters.Bed]: NodeIcon,
|
||||
[FsdChapters.BedExam]: Graduation,
|
||||
[FsdChapters.FsdExam]: Graduation,
|
||||
[A1ChineseChapters.zhA1Welcome]: faDoorOpen,
|
||||
[A1ChineseChapters.zhA1PinYin]: faCubes,
|
||||
[A1ChineseChapters.zhA1Greetings]: faComments,
|
||||
[A1ChineseChapters.zhA1GreetingsLegacy]: faComments,
|
||||
[A1ChineseChapters.zhA1NumbersAndPersonalInformation]: faIdCard,
|
||||
[A1ChineseChapters.zhA1Family]: faIdCard,
|
||||
[A1ChineseChapters.zhA1Expressing]: faHands,
|
||||
[A1SpanishChapters.esA1Welcome]: faDoorOpen,
|
||||
[A1SpanishChapters.esA1Fundamentals]: faCubes,
|
||||
[A1SpanishChapters.esA1Greetings]: faComments,
|
||||
[A1SpanishChapters.esA1Details]: faIdCard,
|
||||
[A1SpanishChapters.esA1Describing]: faBuilding
|
||||
};
|
||||
|
||||
type ChapterIconProps = {
|
||||
chapter: FsdChapters;
|
||||
} & React.SVGProps<SVGSVGElement>;
|
||||
|
||||
export function ChapterIcon(props: ChapterIconProps): JSX.Element {
|
||||
const { chapter, ...iconProps } = props;
|
||||
const Icon = iconMap[chapter] ?? ResponsiveDesign;
|
||||
|
||||
if (typeof Icon === 'object') {
|
||||
return <FontAwesomeIcon icon={Icon} size='lg' />;
|
||||
}
|
||||
|
||||
return <Icon {...iconProps} />;
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
import React from 'react';
|
||||
|
||||
function A1ChineseIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 48 48'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M38 2.5H25.5V22.5H45.5V6C45.5 3.79086 43.7091 2 41.5 2.5H38ZM45.5 25.5H25.5V45.5H41.5C43.7091 45.5 45.5 43.7091 45.5 41.5V25.5ZM22.5 22.5V2.5H10H6.5C4.29086 2.5 2.5 4.29086 2.5 6.5V22.5H22.5ZM2.5 25.5H22.5V45.5H6.5C4.29086 45.5 2.5 43.7091 2.5 41.5V25.5ZM6.5 0C2.91015 0 0 2.91015 0 6.5V41.5C0 45.0899 2.91015 48 6.5 48H41.5C45.0899 48 48 45.0899 48 41.5V6.5C48 2.91015 45.0899 0 41.5 0H6.5Z'
|
||||
/>
|
||||
<text
|
||||
x={12}
|
||||
y={14}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
A
|
||||
</text>
|
||||
<text
|
||||
x={36}
|
||||
y={14}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
1
|
||||
</text>
|
||||
<text
|
||||
x={12}
|
||||
y={37}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
Z
|
||||
</text>
|
||||
<text
|
||||
x={36}
|
||||
y={37}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
H
|
||||
</text>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
A1ChineseIcon.displayName = 'A1ChineseIcon';
|
||||
|
||||
export default A1ChineseIcon;
|
||||
@@ -0,0 +1,77 @@
|
||||
import React from 'react';
|
||||
|
||||
function A1SpanishIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 48 48'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M38 2.5H25.5V22.5H45.5V6C45.5 3.79086 43.7091 2 41.5 2.5H38ZM45.5 25.5H25.5V45.5H41.5C43.7091 45.5 45.5 43.7091 45.5 41.5V25.5ZM22.5 22.5V2.5H10H6.5C4.29086 2.5 2.5 4.29086 2.5 6.5V22.5H22.5ZM2.5 25.5H22.5V45.5H6.5C4.29086 45.5 2.5 43.7091 2.5 41.5V25.5ZM6.5 0C2.91015 0 0 2.91015 0 6.5V41.5C0 45.0899 2.91015 48 6.5 48H41.5C45.0899 48 48 45.0899 48 41.5V6.5C48 2.91015 45.0899 0 41.5 0H6.5Z'
|
||||
/>
|
||||
<text
|
||||
x={12}
|
||||
y={14}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
A
|
||||
</text>
|
||||
<text
|
||||
x={36}
|
||||
y={14}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
1
|
||||
</text>
|
||||
<text
|
||||
x={12}
|
||||
y={37}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
E
|
||||
</text>
|
||||
<text
|
||||
x={36}
|
||||
y={37}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
S
|
||||
</text>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
A1SpanishIcon.displayName = 'A1SpanishIcon';
|
||||
|
||||
export default A1SpanishIcon;
|
||||
@@ -0,0 +1,77 @@
|
||||
import React from 'react';
|
||||
|
||||
function A2ChineseIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 48 48'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M38 2.5H25.5V22.5H45.5V6C45.5 3.79086 43.7091 2 41.5 2.5H38ZM45.5 25.5H25.5V45.5H41.5C43.7091 45.5 45.5 43.7091 45.5 41.5V25.5ZM22.5 22.5V2.5H10H6.5C4.29086 2.5 2.5 4.29086 2.5 6.5V22.5H22.5ZM2.5 25.5H22.5V45.5H6.5C4.29086 45.5 2.5 43.7091 2.5 41.5V25.5ZM6.5 0C2.91015 0 0 2.91015 0 6.5V41.5C0 45.0899 2.91015 48 6.5 48H41.5C45.0899 48 48 45.0899 48 41.5V6.5C48 2.91015 45.0899 0 41.5 0H6.5Z'
|
||||
/>
|
||||
<text
|
||||
x={12}
|
||||
y={14}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
A
|
||||
</text>
|
||||
<text
|
||||
x={36}
|
||||
y={14}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
2
|
||||
</text>
|
||||
<text
|
||||
x={12}
|
||||
y={37}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
Z
|
||||
</text>
|
||||
<text
|
||||
x={36}
|
||||
y={37}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
H
|
||||
</text>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
A2ChineseIcon.displayName = 'A2ChineseIcon';
|
||||
|
||||
export default A2ChineseIcon;
|
||||
@@ -0,0 +1,80 @@
|
||||
import React from 'react';
|
||||
|
||||
function A2EnglishIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 48 48'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M38 2.5H25.5V22.5H45.5V6C45.5 3.79086 43.7091 2 41.5 2.5H38ZM45.5 25.5H25.5V45.5H41.5C43.7091 45.5 45.5 43.7091 45.5 41.5V25.5ZM22.5 22.5V2.5H10H6.5C4.29086 2.5 2.5 4.29086 2.5 6.5V22.5H22.5ZM2.5 25.5H22.5V45.5H6.5C4.29086 45.5 2.5 43.7091 2.5 41.5V25.5ZM6.5 0C2.91015 0 0 2.91015 0 6.5V41.5C0 45.0899 2.91015 48 6.5 48H41.5C45.0899 48 48 45.0899 48 41.5V6.5C48 2.91015 45.0899 0 41.5 0H6.5Z'
|
||||
/>
|
||||
<text
|
||||
x={12}
|
||||
y={14}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
A
|
||||
</text>
|
||||
|
||||
<text
|
||||
x={36}
|
||||
y={14}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
2
|
||||
</text>
|
||||
|
||||
<text
|
||||
x={12}
|
||||
y={37}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
E
|
||||
</text>
|
||||
|
||||
<text
|
||||
x={36}
|
||||
y={37}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
N
|
||||
</text>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
A2EnglishIcon.displayName = 'A2EnglishIcon';
|
||||
|
||||
export default A2EnglishIcon;
|
||||
@@ -0,0 +1,77 @@
|
||||
import React from 'react';
|
||||
|
||||
function A2SpanishIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 48 48'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M38 2.5H25.5V22.5H45.5V6C45.5 3.79086 43.7091 2 41.5 2.5H38ZM45.5 25.5H25.5V45.5H41.5C43.7091 45.5 45.5 43.7091 45.5 41.5V25.5ZM22.5 22.5V2.5H10H6.5C4.29086 2.5 2.5 4.29086 2.5 6.5V22.5H22.5ZM2.5 25.5H22.5V45.5H6.5C4.29086 45.5 2.5 43.7091 2.5 41.5V25.5ZM6.5 0C2.91015 0 0 2.91015 0 6.5V41.5C0 45.0899 2.91015 48 6.5 48H41.5C45.0899 48 48 45.0899 48 41.5V6.5C48 2.91015 45.0899 0 41.5 0H6.5Z'
|
||||
/>
|
||||
<text
|
||||
x={12}
|
||||
y={14}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
A
|
||||
</text>
|
||||
<text
|
||||
x={36}
|
||||
y={14}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
2
|
||||
</text>
|
||||
<text
|
||||
x={12}
|
||||
y={37}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
E
|
||||
</text>
|
||||
<text
|
||||
x={36}
|
||||
y={37}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
S
|
||||
</text>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
A2SpanishIcon.displayName = 'A2SpanishIcon';
|
||||
|
||||
export default A2SpanishIcon;
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
function Algorithm(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 640 512'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path d='M568 368c-19.1 0-36.3 7.6-49.2 19.7L440.6 343c4.5-12.2 7.4-25.2 7.4-39 0-61.9-50.1-112-112-112-8.4 0-16.6 1.1-24.4 2.9l-32.2-69c15-13.2 24.6-32.3 24.6-53.8 0-39.8-32.2-72-72-72s-72 32.2-72 72 32.2 72 72 72c.9 0 1.8-.2 2.7-.3l33.5 71.7C241.5 235.9 224 267.8 224 304c0 61.9 50.1 112 112 112 30.7 0 58.6-12.4 78.8-32.5l82.2 47c-.4 3.1-1 6.3-1 9.5 0 39.8 32.2 72 72 72s72-32.2 72-72-32.2-72-72-72zM232 96c-13.2 0-24-10.8-24-24s10.8-24 24-24 24 10.8 24 24-10.8 24-24 24zm104 272c-35.3 0-64-28.7-64-64s28.7-64 64-64 64 28.7 64 64-28.7 64-64 64zm232 96c-13.2 0-24-10.8-24-24s10.8-24 24-24 24 10.8 24 24-10.8 24-24 24zm-54.4-261.2l-19.2-25.6-48 36 19.2 25.6 48-36zM576 192c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zM152 320h48v-32h-48v32zm-88-80c-35.3 0-64 28.7-64 64s28.7 64 64 64 64-28.7 64-64-28.7-64-64-64z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Algorithm.displayName = 'Algorithm';
|
||||
|
||||
export default Algorithm;
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
function Analytics(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 576 512'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path d='M510.62 92.63C516.03 94.74 521.85 96 528 96c26.51 0 48-21.49 48-48S554.51 0 528 0s-48 21.49-48 48c0 2.43.37 4.76.71 7.09l-95.34 76.27c-5.4-2.11-11.23-3.37-17.38-3.37s-11.97 1.26-17.38 3.37L255.29 55.1c.35-2.33.71-4.67.71-7.1 0-26.51-21.49-48-48-48s-48 21.49-48 48c0 4.27.74 8.34 1.78 12.28l-101.5 101.5C56.34 160.74 52.27 160 48 160c-26.51 0-48 21.49-48 48s21.49 48 48 48 48-21.49 48-48c0-4.27-.74-8.34-1.78-12.28l101.5-101.5C199.66 95.26 203.73 96 208 96c6.15 0 11.97-1.26 17.38-3.37l95.34 76.27c-.35 2.33-.71 4.67-.71 7.1 0 26.51 21.49 48 48 48s48-21.49 48-48c0-2.43-.37-4.76-.71-7.09l95.32-76.28zM400 320h-64c-8.84 0-16 7.16-16 16v160c0 8.84 7.16 16 16 16h64c8.84 0 16-7.16 16-16V336c0-8.84-7.16-16-16-16zm160-128h-64c-8.84 0-16 7.16-16 16v288c0 8.84 7.16 16 16 16h64c8.84 0 16-7.16 16-16V208c0-8.84-7.16-16-16-16zm-320 0h-64c-8.84 0-16 7.16-16 16v288c0 8.84 7.16 16 16 16h64c8.84 0 16-7.16 16-16V208c0-8.84-7.16-16-16-16zM80 352H16c-8.84 0-16 7.16-16 16v128c0 8.84 7.16 16 16 16h64c8.84 0 16-7.16 16-16V368c0-8.84-7.16-16-16-16z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Analytics.displayName = 'Analytics';
|
||||
|
||||
export default Analytics;
|
||||
@@ -0,0 +1,19 @@
|
||||
import React from 'react';
|
||||
function APIIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 512 512'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path d='M424 400c0 13.255-10.745 24-24 24s-24-10.745-24-24 10.745-24 24-24 24 10.745 24 24zm-88-24c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm64-144c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm-64 0c-13.255 0-24 10.745-24 24s10.745 24 24 24 24-10.745 24-24-10.745-24-24-24zm176-72a47.758 47.758 0 01-6.438 24A47.758 47.758 0 01512 208v96a47.758 47.758 0 01-6.438 24A47.758 47.758 0 01512 352v96c0 26.51-21.49 48-48 48H48c-26.51 0-48-21.49-48-48v-96a47.758 47.758 0 016.438-24A47.758 47.758 0 010 304v-96a47.758 47.758 0 016.438-24A47.758 47.758 0 010 160V64c0-26.51 21.49-48 48-48h416c26.51 0 48 21.49 48 48v96zm-464 0h416V64H48v96zm416 48H48v96h416v-96zm0 144H48v96h416v-96zm-64-216c13.255 0 24-10.745 24-24s-10.745-24-24-24-24 10.745-24 24 10.745 24 24 24zm-64 0c13.255 0 24-10.745 24-24s-10.745-24-24-24-24 10.745-24 24 10.745 24 24 24z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
APIIcon.displayName = 'APIIcon';
|
||||
|
||||
export default APIIcon;
|
||||
@@ -0,0 +1,80 @@
|
||||
import React from 'react';
|
||||
|
||||
function B1EnglishIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 48 48'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M38 2.5H25.5V22.5H45.5V6C45.5 3.79086 43.7091 2 41.5 2.5H38ZM45.5 25.5H25.5V45.5H41.5C43.7091 45.5 45.5 43.7091 45.5 41.5V25.5ZM22.5 22.5V2.5H10H6.5C4.29086 2.5 2.5 4.29086 2.5 6.5V22.5H22.5ZM2.5 25.5H22.5V45.5H6.5C4.29086 45.5 2.5 43.7091 2.5 41.5V25.5ZM6.5 0C2.91015 0 0 2.91015 0 6.5V41.5C0 45.0899 2.91015 48 6.5 48H41.5C45.0899 48 48 45.0899 48 41.5V6.5C48 2.91015 45.0899 0 41.5 0H6.5Z'
|
||||
/>
|
||||
<text
|
||||
x={12}
|
||||
y={14}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
B
|
||||
</text>
|
||||
|
||||
<text
|
||||
x={36}
|
||||
y={14}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
1
|
||||
</text>
|
||||
|
||||
<text
|
||||
x={12}
|
||||
y={37}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
E
|
||||
</text>
|
||||
|
||||
<text
|
||||
x={36}
|
||||
y={37}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
N
|
||||
</text>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
B1EnglishIcon.displayName = 'B1EnglishIcon';
|
||||
|
||||
export default B1EnglishIcon;
|
||||
@@ -0,0 +1,80 @@
|
||||
import React from 'react';
|
||||
|
||||
function B2EnglishIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 48 48'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M38 2.5H25.5V22.5H45.5V6C45.5 3.79086 43.7091 2 41.5 2.5H38ZM45.5 25.5H25.5V45.5H41.5C43.7091 45.5 45.5 43.7091 45.5 41.5V25.5ZM22.5 22.5V2.5H10H6.5C4.29086 2.5 2.5 4.29086 2.5 6.5V22.5H22.5ZM2.5 25.5H22.5V45.5H6.5C4.29086 45.5 2.5 43.7091 2.5 41.5V25.5ZM6.5 0C2.91015 0 0 2.91015 0 6.5V41.5C0 45.0899 2.91015 48 6.5 48H41.5C45.0899 48 48 45.0899 48 41.5V6.5C48 2.91015 45.0899 0 41.5 0H6.5Z'
|
||||
/>
|
||||
<text
|
||||
x={12}
|
||||
y={14}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
B
|
||||
</text>
|
||||
|
||||
<text
|
||||
x={36}
|
||||
y={14}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
2
|
||||
</text>
|
||||
|
||||
<text
|
||||
x={12}
|
||||
y={37}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
E
|
||||
</text>
|
||||
|
||||
<text
|
||||
x={36}
|
||||
y={37}
|
||||
fontSize={16}
|
||||
fontFamily='Lato, sans-serif'
|
||||
fontWeight='bold'
|
||||
textAnchor='middle'
|
||||
dominantBaseline='middle'
|
||||
fill='currentColor'
|
||||
stroke='none'
|
||||
>
|
||||
N
|
||||
</text>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
B2EnglishIcon.displayName = 'B2EnglishIcon';
|
||||
|
||||
export default B2EnglishIcon;
|
||||
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
|
||||
function CSharpLogo(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
width='72'
|
||||
height='72'
|
||||
viewBox='0 0 340 378'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d='M158.167 2.502C150.135 4.76 148.205 5.812 82 44.013 12.831 83.925 11.995 84.521 5.228 98.692L1.5 106.5v165l3.728 7.808c6.797 14.235 7.384 14.65 78.772 55.756 76.299 43.933 71.084 41.424 86 41.381 13.647-.039 15.215-.595 36.5-12.943 7.7-4.468 36.204-20.913 63.342-36.545 52.729-30.374 55.406-32.179 61.334-41.351C339.297 273.041 339 276.712 339 189c0-87.712.297-84.041-7.824-96.606-5.928-9.172-8.605-10.977-61.334-41.351C242.704 35.411 214.2 18.95 206.5 14.464 184.503 1.648 172.115-1.418 158.167 2.502M87.929 129.367c-9.93 2.678-19.154 10.497-24.085 20.417-3.685 7.414-3.661 71.065.03 78.496 10.37 20.877 35.098 27.776 53.885 15.032 19.078-12.942 21.674-42.283 3.741-42.283-6.196 0-12.5 6.137-12.5 12.169 0 10.617-13.203 15.734-20.25 7.848L86 217.968v-57.936l2.75-3.078c7.047-7.886 20.25-2.769 20.25 7.848 0 6.032 6.304 12.169 12.5 12.169 13.356 0 16.388-17.097 5.805-32.73-8.589-12.686-24.791-18.806-39.376-14.874m99.983.913c-4.692 3.162-5.88 6.078-5.897 14.47L182 152h-6.532c-11.322 0-17.501 4.39-17.433 12.385.077 8.874 4.866 12.599 16.215 12.608L182 177v24l-7.75.007c-11.349.009-16.138 3.734-16.215 12.608-.068 7.995 6.111 12.385 17.433 12.385H182l.015 7.25c.027 13.279 7.631 19.859 17.525 15.164 5.079-2.41 6.754-5.788 7.268-14.652l.449-7.762H230v6.766c0 8.126 2.123 12.758 7.062 15.407 9.798 5.255 17.927-1.51 17.934-14.923L255 226h6.532c11.207 0 17.468-4.384 17.468-12.231C279 205 273.861 201 262.596 201H255v-24h7.596c11.265 0 16.404-4 16.404-12.769 0-7.847-6.261-12.231-17.468-12.231H255l-.004-7.25c-.007-13.413-8.136-20.178-17.934-14.923-4.939 2.649-7.062 7.281-7.062 15.407V152H207.257l-.449-7.762c-.796-13.744-9.582-20.235-18.896-13.958M207 189v12h23v-24h-23v12'
|
||||
fillRule='evenodd'
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
CSharpLogo.displayName = 'CSharpLogo';
|
||||
export default CSharpLogo;
|
||||
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
|
||||
function C1EnglishIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
viewBox='0 0 175 170'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M138 9H83V79.476H147V18C147 13.029 142.971 9 138 9ZM147 88.476H83V156H138C142.971 156 147 151.971 147 147V88.476ZM74 79.476V9H18C13.029 9 9 13.029 9 18V79.476H72H74ZM9 88.476H74V156H18C13.029 156 9 151.971 9 147V88.476ZM18 0C8.059 0 0 8.059 0 18V147C0 156.941 8.059 165 18 165H138C147.941 165 156 156.941 156 147V18C156 8.059 147.941 0 138 0H18ZM27.54 48.434C27.54 57.2485 34.6855 64.394 43.5 64.394V64.394L46.331 64.1709C47.7603 64.0583 49.1486 63.6397 50.4019 62.9434L51.6206 62.2664C52.5288 61.7618 53.3133 61.0614 53.9172 60.2159L54.8378 58.927C55.2754 58.3145 55.5937 57.6251 55.7763 56.8948L56.1417 55.4332C56.3797 54.4813 56.5 53.5039 56.5 52.5227V49.5H50.5V50.5379C50.5 58.8752 38.9538 61.0218 35.9573 53.2416V53.2416C35.7683 52.751 35.6665 52.2311 35.6565 51.7054L35.5 43.5L35.6407 37.3508C35.6609 36.4689 35.9343 35.6114 36.4282 34.8806V34.8806C40.3476 29.0819 49.3494 31.1378 50.3629 38.063L50.5 39H56.5V36.6522C56.5 34.6005 55.8689 32.5984 54.6923 30.9176L53.4017 29.0738C53.1344 28.692 52.8343 28.3343 52.5047 28.0047L51.9111 27.4111C49.7233 25.2233 46.7702 23.9725 43.6765 23.9234V23.9234C34.8063 23.7824 27.54 30.9343 27.54 39.8056V48.434ZM100.301 64.394V57.355H111V45.5C111 44 111 39 111 37.5C111 38.661 111 36.2586 111 37.5C111 38.574 111 36.339 111 37.5C111 38.693 111 36.307 111 37.5C111 35.5 111 35.569 111 35C112.194 35 109.5 35 111 35C111 36 111 34.069 111 35C109.5 36 105 39 104 39.5C103.5 38.5 101 34.5 100.5 33.5C99.2921 35.4577 102 31.069 100.5 33.5C102 32.5 111.5 25.167 114 23.667C118.5 23.667 119 23.667 120.5 23.667C120.5 24.7787 120.5 22.5 120.5 25C120.5 28 120.5 27.931 120.5 29.931C120.5 32.431 120.5 33.154 120.5 35.5C120.5 37.038 120.5 39 120.5 40.5C120.5 42.285 120.5 44 120.5 46C120.5 48.5 120.5 55 120.5 57.355H129.335V64.394H100.301ZM27.54 142V101.273H54.983V108.372H36.151V118.077H53.571V125.176H36.151V134.901H55.063V142H27.54ZM131.605 142V101.273H123.034V126.886H122.676L105.097 101.273H97.54V142H106.151V116.366H106.449L124.168 142H131.605Z'
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
C1EnglishIcon.displayName = 'C1EnglishIcon';
|
||||
|
||||
export default C1EnglishIcon;
|
||||
@@ -0,0 +1,25 @@
|
||||
import React from 'react';
|
||||
|
||||
function C2EnglishIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 175 170'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M138 9H83V79.5H147V18C147 13 143 9 138 9ZM147 88.5H83V156H138C143 156 147 152 147 147V88.5ZM74 79.5V9H18C13 9 9 13 9 18V79.5H72H74ZM9 88.5H74V156H18C13 156 9 152 9 147V88.5ZM18 0C8.1 0 0 8.1 0 18V147C0 156.9 8.1 165 18 165H138C147.9 165 156 156.9 156 147V18C156 8.1 147.9 0 138 0H18ZM27.5 48.4C27.5 57.2 34.6 64.4 43.5 64.4L46.3 64.2C47.7 64.1 49.1 63.7 50.4 63L51.6 62.3C52.5 61.8 53.3 61.1 53.9 60.2L54.8 58.9C55.2 58.3 55.6 57.6 55.7 56.9L56.1 55.4C56.3 54.4 56.5 53.5 56.5 52.5V49.5H50.5V50.5C50.5 58.9 39 61 36 53.2C35.8 52.7 35.7 52.2 35.7 51.7L35.5 43.5L35.6 37.4C35.6 36.5 35.9 35.7 36.4 34.9C40.3 29.1 49.3 31.2 50.3 38.1L50.4 39H56.4V36.7C56.4 34.6 55.8 32.6 54.6 31L53.3 29.2C53 28.8 52.7 28.5 52.4 28.1L51.8 27.5C49.6 25.3 46.7 24.1 43.6 24C34.7 23.9 27.5 31 27.5 39.9V48.4ZM27.5 142V101.3H55V108.4H36.2V118.1H53.6V125.2H36.2V134.9H55.1V142H27.5ZM131.6 142V101.3H123V126.9H122.6L105 101.3H97.4V142H106V116.4H106.3L124 142H131.6ZM100.7 64.9V58.7L115.2 45.3C116.4 44.1 117.5 43 118.3 42.1C119.1 41.1 119.8 40.2 120.2 39.3C120.6 38.4 120.9 37.4 120.9 36.3C120.9 35.1 120.6 34.1 120.1 33.2C119.6 32.3 118.8 31.7 117.9 31.2C117 30.7 115.9 30.5 114.7 30.5C113.5 30.5 112.4 30.8 111.4 31.3C110.5 31.8 109.8 32.5 109.3 33.5C108.8 34.4 108.5 35.6 108.5 36.9H100.3C100.3 34.2 100.9 31.9 102.1 30C103.3 28 105 26.5 107.2 25.4C109.4 24.3 111.9 23.8 114.7 23.8C117.6 23.8 120.2 24.3 122.3 25.4C124.5 26.4 126.2 27.8 127.4 29.7C128.6 31.5 129.2 33.6 129.2 35.9C129.2 37.4 128.9 39 128.3 40.5C127.7 42 126.6 43.7 125.1 45.5C123.6 47.3 121.4 49.5 118.6 52L112.7 57.8V58.1H129.8V65.1H100.7V64.9Z'
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
C2EnglishIcon.displayName = 'C2EnglishIcon';
|
||||
|
||||
export default C2EnglishIcon;
|
||||
@@ -0,0 +1,21 @@
|
||||
import React from 'react';
|
||||
|
||||
function CalendarIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 448 512'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path d='M128 0c17.7 0 32 14.3 32 32l0 32 128 0 0-32c0-17.7 14.3-32 32-32s32 14.3 32 32l0 32 48 0c26.5 0 48 21.5 48 48l0 48L0 160l0-48C0 85.5 21.5 64 48 64l48 0 0-32c0-17.7 14.3-32 32-32zM0 192l448 0 0 272c0 26.5-21.5 48-48 48L48 512c-26.5 0-48-21.5-48-48L0 192zm64 80l0 32c0 8.8 7.2 16 16 16l32 0c8.8 0 16-7.2 16-16l0-32c0-8.8-7.2-16-16-16l-32 0c-8.8 0-16 7.2-16 16zm128 0l0 32c0 8.8 7.2 16 16 16l32 0c8.8 0 16-7.2 16-16l0-32c0-8.8-7.2-16-16-16l-32 0c-8.8 0-16 7.2-16 16zm144-16c-8.8 0-16 7.2-16 16l0 32c0 8.8 7.2 16 16 16l32 0c8.8 0 16-7.2 16-16l0-32c0-8.8-7.2-16-16-16l-32 0zM64 400l0 32c0 8.8 7.2 16 16 16l32 0c8.8 0 16-7.2 16-16l0-32c0-8.8-7.2-16-16-16l-32 0c-8.8 0-16 7.2-16 16zm144-16c-8.8 0-16 7.2-16 16l0 32c0 8.8 7.2 16 16 16l32 0c8.8 0 16-7.2 16-16l0-32c0-8.8-7.2-16-16-16l-32 0zm112 16l0 32c0 8.8 7.2 16 16 16l32 0c8.8 0 16-7.2 16-16l0-32c0-8.8-7.2-16-16-16l-32 0c-8.8 0-16 7.2-16 16z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
CalendarIcon.displayName = 'CalendarIcon';
|
||||
|
||||
export default CalendarIcon;
|
||||
@@ -0,0 +1,29 @@
|
||||
import React from 'react';
|
||||
function CapIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
width='61'
|
||||
height='60'
|
||||
viewBox='0 0 61 60'
|
||||
fill='none'
|
||||
aria-hidden='true'
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d='M10.1154 48.7552L10.1154 30.7553L28.1154 42.7553L47.1154 30.7553L47.1154 48.7552C47.1154 48.7552 39.854 59.7899 28.1154 59.7553C16.3769 59.7206 10.1154 48.7552 10.1154 48.7552Z'
|
||||
fill='black'
|
||||
/>
|
||||
<path
|
||||
d='M53.0108 46.5927L60.0108 46.5927L57.1154 36.5926L57.1154 20.6612L28.1574 0.0826199L0.115235 20.6612L28.1154 38.7553L56.0108 21.3504L56.0108 36.5926L53.0108 46.5927Z'
|
||||
fill='black'
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
CapIcon.displayName = 'CapIcon';
|
||||
|
||||
export default CapIcon;
|
||||
@@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
|
||||
function Caret(): JSX.Element {
|
||||
return (
|
||||
<svg viewBox='0 0 100 100' width='25px'>
|
||||
<polygon
|
||||
points='-6.04047,17.1511 81.8903,58.1985 -3.90024,104.196'
|
||||
style={{
|
||||
stroke: 'var(--primary-color)',
|
||||
fill: 'var(--primary-color)',
|
||||
strokeWidth: '1px'
|
||||
}}
|
||||
transform={
|
||||
'matrix(0.999729, 0.023281, -0.023281, 0.999729, 7.39321, -10.0425)'
|
||||
}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Caret.displayName = 'Caret';
|
||||
|
||||
export default Caret;
|
||||
@@ -0,0 +1,68 @@
|
||||
import React from 'react';
|
||||
|
||||
function CertificationIcon(): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
height='248.21'
|
||||
preserveAspectRatio='xMidYMid meet'
|
||||
version='1.1'
|
||||
viewBox='232 241.57142857142856 156.8571428571429 262.2051282051284'
|
||||
width='142.86'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
xmlnsXlink='http://www.w3.org/1999/xlink'
|
||||
>
|
||||
<defs>
|
||||
<path
|
||||
d='M239 303.14L310.43 248.57L381.86 303.14L354.57 391.43L266.28 391.43L239 303.14Z'
|
||||
id='aZt9D86Ps'
|
||||
/>
|
||||
<path
|
||||
d='M327.11 393.59L344.3 496.78L309.91 479.58L275.51 496.78L292.71 393.59L327.11 393.59Z'
|
||||
id='b7LyrCUAE'
|
||||
/>
|
||||
</defs>
|
||||
<g>
|
||||
<g>
|
||||
<use
|
||||
fill='var(--primary-color)'
|
||||
fillOpacity='0'
|
||||
opacity='1'
|
||||
xlinkHref='#aZt9D86Ps'
|
||||
/>
|
||||
<g>
|
||||
<use
|
||||
fillOpacity='0'
|
||||
opacity='1'
|
||||
stroke='var(--primary-color)'
|
||||
strokeOpacity='1'
|
||||
strokeWidth='14'
|
||||
xlinkHref='#aZt9D86Ps'
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<use
|
||||
fill='var(--primary-color)'
|
||||
fillOpacity='0'
|
||||
opacity='1'
|
||||
xlinkHref='#b7LyrCUAE'
|
||||
/>
|
||||
<g>
|
||||
<use
|
||||
fillOpacity='0'
|
||||
opacity='1'
|
||||
stroke='var(--primary-color)'
|
||||
strokeOpacity='1'
|
||||
strokeWidth='14'
|
||||
xlinkHref='#b7LyrCUAE'
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
CertificationIcon.displayName = 'CertificationIcon';
|
||||
|
||||
export default CertificationIcon;
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
function Clipboard(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 384 512'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path d='M126.2 286.4l64.2-63.6c2.1-2.1 2.1-5.5 0-7.6l-12.6-12.7c-2.1-2.1-5.5-2.1-7.6 0l-47.6 47.2-20.6-20.9c-2.1-2.1-5.5-2.1-7.6 0l-12.7 12.6c-2.1 2.1-2.1 5.5 0 7.6l37.1 37.4c1.9 2.1 5.3 2.1 7.4 0zM336 64h-80c0-35.3-28.7-64-64-64s-64 28.7-64 64H48C21.5 64 0 85.5 0 112v352c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48V112c0-26.5-21.5-48-48-48zM192 48c8.8 0 16 7.2 16 16s-7.2 16-16 16-16-7.2-16-16 7.2-16 16-16zm144 408c0 4.4-3.6 8-8 8H56c-4.4 0-8-3.6-8-8V120c0-4.4 3.6-8 8-8h40v32c0 8.8 7.2 16 16 16h160c8.8 0 16-7.2 16-16v-32h40c4.4 0 8 3.6 8 8v336zM112 328c-13.3 0-24 10.7-24 24s10.7 24 24 24 24-10.7 24-24-10.7-24-24-24zm168-88h-63.3c-1.3 1.8-2.1 3.9-3.7 5.5L186.2 272H280c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8zm0 96H168c-4.4 0-8 3.6-8 8v16c0 4.4 3.6 8 8 8h112c4.4 0 8-3.6 8-8v-16c0-4.4-3.6-8-8-8z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Clipboard.displayName = 'Clipboard';
|
||||
|
||||
export default Clipboard;
|
||||
@@ -0,0 +1,19 @@
|
||||
import React from 'react';
|
||||
|
||||
function ClosedCaptionsIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
viewBox='0 0 576 512'
|
||||
fill={props.fill || 'var(--gray-00)'}
|
||||
>
|
||||
<path d='M0 96C0 60.7 28.7 32 64 32l448 0c35.3 0 64 28.7 64 64l0 320c0 35.3-28.7 64-64 64L64 480c-35.3 0-64-28.7-64-64L0 96zM200 208c14.2 0 27 6.1 35.8 16c8.8 9.9 24 10.7 33.9 1.9s10.7-24 1.9-33.9c-17.5-19.6-43.1-32-71.5-32c-53 0-96 43-96 96s43 96 96 96c28.4 0 54-12.4 71.5-32c8.8-9.9 8-25-1.9-33.9s-25-8-33.9 1.9c-8.8 9.9-21.6 16-35.8 16c-26.5 0-48-21.5-48-48s21.5-48 48-48zm144 48c0-26.5 21.5-48 48-48c14.2 0 27 6.1 35.8 16c8.8 9.9 24 10.7 33.9 1.9s10.7-24 1.9-33.9c-17.5-19.6-43.1-32-71.5-32c-53 0-96 43-96 96s43 96 96 96c28.4 0 54-12.4 71.5-32c8.8-9.9 8-25-1.9-33.9s-25-8-33.9 1.9c-8.8 9.9-21.6 16-35.8 16c-26.5 0-48-21.5-48-48z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
ClosedCaptionsIcon.displayName = 'ClosedCaptionsIcon';
|
||||
|
||||
export default ClosedCaptionsIcon;
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
function Code(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
viewBox='0 0 640 512'
|
||||
fill='none'
|
||||
{...props}
|
||||
>
|
||||
<path d='M392.8 1.2c-17-4.9-34.7 5-39.6 22l-128 448c-4.9 17 5 34.7 22 39.6s34.7-5 39.6-22l128-448c4.9-17-5-34.7-22-39.6zm80.6 120.1c-12.5 12.5-12.5 32.8 0 45.3L562.7 256l-89.4 89.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0l112-112c12.5-12.5 12.5-32.8 0-45.3l-112-112c-12.5-12.5-32.8-12.5-45.3 0zm-306.7 0c-12.5-12.5-32.8-12.5-45.3 0l-112 112c-12.5 12.5-12.5 32.8 0 45.3l112 112c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L77.3 256l89.4-89.4c12.5-12.5 12.5-32.8 0-45.3z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Code.displayName = 'Code';
|
||||
|
||||
export default Code;
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
function CollegeAlgebra(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 640 512'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path d='M289 24.2C292.5 10 305.3 0 320 0H544c17.7 0 32 14.3 32 32s-14.3 32-32 32H345L239 487.8c-3.2 13-14.2 22.6-27.6 24s-26.1-5.5-32.1-17.5L76.2 288H32c-17.7 0-32-14.3-32-32s14.3-32 32-32H96c12.1 0 23.2 6.8 28.6 17.7l73.3 146.6L289 24.2zM393.4 233.4c12.5-12.5 32.8-12.5 45.3 0L480 274.7l41.4-41.4c12.5-12.5 32.8-12.5 45.3 0s12.5 32.8 0 45.3L525.3 320l41.4 41.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L480 365.3l-41.4 41.4c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L434.7 320l-41.4-41.4c-12.5-12.5-12.5-32.8 0-45.3z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
CollegeAlgebra.displayName = 'CollegeAlgebra';
|
||||
|
||||
export default CollegeAlgebra;
|
||||
@@ -0,0 +1,45 @@
|
||||
import React from 'react';
|
||||
function CommunityIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
width='60'
|
||||
height='60'
|
||||
viewBox='0 0 60 60'
|
||||
fill='none'
|
||||
aria-hidden='true'
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d='M18.1176 7.11765C18.1176 11.0486 14.9309 14.2353 10.9999 14.2353C7.06896 14.2353 3.88228 11.0486 3.88228 7.11765C3.88228 3.18668 7.06896 0 10.9999 0C14.9309 0 18.1176 3.18668 18.1176 7.11765Z'
|
||||
fill='black'
|
||||
/>
|
||||
<path
|
||||
d='M48.9999 14.2353C52.9309 14.2353 56.1176 11.0486 56.1176 7.11765C56.1176 3.18668 52.9309 0 48.9999 0C45.069 0 41.8823 3.18668 41.8823 7.11765C41.8823 11.0486 45.069 14.2353 48.9999 14.2353Z'
|
||||
fill='black'
|
||||
/>
|
||||
<path
|
||||
d='M13 47H0V21.3531C-1.63171e-05 17.8904 2.69272 15.6097 5 14C6.94118 15.4503 8.44322 16 10.9999 16C13.5566 16 15.0588 15.2941 17 14C17.857 14.5978 18.615 14.9334 19.4511 15.814C19.1576 16.8238 19 17.8932 19 19C19 21.574 19.8523 24.0831 21.2851 26.1359C17.7193 28.6696 13 33.1608 13 38.6113V47Z'
|
||||
fill='black'
|
||||
/>
|
||||
<path
|
||||
d='M40.5488 15.814C41.385 14.9334 42.143 14.5979 43 14C44.9412 15.4503 46.4433 16 49 16C51.5567 16 53.0588 15.2941 55 14C57.3073 15.6097 60 17.8904 60 21.3531V47H47V38.6113C47 33.1608 42.2807 28.6696 38.7149 26.1359C40.1477 24.0831 41 21.574 41 19C41 17.8932 40.8424 16.8238 40.5488 15.814Z'
|
||||
fill='black'
|
||||
/>
|
||||
<path
|
||||
d='M39.5 19.1851C39.5 24.8102 35.3604 29 29.9999 29C24.6395 29 21 24.8102 21 19.1851C21 13.56 24.6395 10 29.9999 10C35.3604 10 39.5 13.56 39.5 19.1851Z'
|
||||
fill='black'
|
||||
/>
|
||||
<path
|
||||
d='M15 39.5558C15 34.6007 19.3537 30.3034 22.5 28C25.1471 30.0753 26.5135 31 29.9999 31C33.4863 31 35.3529 29.8518 38 28C41.1463 30.3034 45 34.6007 45 39.5558C45 54.3705 45 60 45 60H15C15 60 15.0001 55.2965 15 39.5558Z'
|
||||
fill='black'
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
CommunityIcon.displayName = 'CommunityIcon';
|
||||
|
||||
export default CommunityIcon;
|
||||
@@ -0,0 +1,15 @@
|
||||
import React from 'react';
|
||||
|
||||
function Css(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 384 512' {...props}>
|
||||
<path d='M0 32l34.9 395.8L192 480l157.1-52.2L384 32H0zm313.1 80l-4.8 47.3L193 208.6l-.3 .1h111.5l-12.8 146.6-98.2 28.7-98.8-29.2-6.4-73.9h48.9l3.2 38.3 52.6 13.3 54.7-15.4 3.7-61.6-166.3-.5v-.1l-.2 .1-3.6-46.3L193.1 162l6.5-2.7H76.7L70.9 112h242.2z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Css.displayName = 'Css';
|
||||
|
||||
export default Css;
|
||||
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
function CurriculumIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
width='60'
|
||||
height='60'
|
||||
viewBox='0 0 60 60'
|
||||
fill='none'
|
||||
aria-hidden='true'
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M15 6L0 0V55L15 60L30 55L45 60L60 55L60 0L45 6L30 0L15 6ZM12.5 24C15.1285 24 17.3264 22.1561 17.8707 19.6912C19.8628 19.3554 22.2378 19.0587 24.5904 19.0077C27.4964 18.9447 30.121 19.2649 31.9469 20.1449C32.8296 20.5703 33.4622 21.0962 33.8796 21.7178C34.2893 22.3279 34.5735 23.151 34.5735 24.3188C34.5735 25.1295 34.3378 25.6225 33.9959 25.998C33.6073 26.4247 32.9532 26.8343 31.9219 27.1922C30.0008 27.859 27.4496 28.1393 24.5266 28.4606C24.2102 28.4954 23.8895 28.5306 23.5648 28.5669C20.4252 28.9175 16.8925 29.3676 14.1462 30.6563C12.7329 31.3196 11.4204 32.2504 10.4666 33.5976C9.49867 34.9646 9 36.6199 9 38.5481C9.00001 40.5376 9.92037 42.1227 11.3028 43.285C12.6248 44.3965 14.3792 45.1412 16.2448 45.6607C19.9853 46.7022 24.8335 47.0124 29.5055 46.9996C34.2155 46.9868 38.9077 46.6433 42.4108 46.3054L42.5226 46.2946C43.5201 47.6901 45.1538 48.5997 47 48.5997C50.0376 48.5997 52.5 46.1373 52.5 43.0997C52.5 40.4036 50.5601 38.1607 48 37.6904V24.8L56.0001 19.9998L46 14L46 16V26V37.6904C43.675 38.1175 41.8615 40.0066 41.5481 42.3694C38.175 42.6849 33.8267 42.9878 29.4945 42.9996C24.9166 43.0122 20.5147 42.6974 17.3177 41.8073C15.7146 41.3609 14.5783 40.8131 13.8769 40.2234C13.2359 39.6844 13 39.1595 13 38.5481C13 37.34 13.3005 36.5172 13.7311 35.909C14.1759 35.2809 14.8613 34.7393 15.8455 34.2774C17.8942 33.316 20.7549 32.9056 24.0087 32.5422C24.3375 32.5054 24.6711 32.4692 25.008 32.4326L25.0081 32.4326C27.8155 32.1274 30.8531 31.7972 33.2334 30.9711C34.5996 30.4969 35.9434 29.8002 36.9534 28.6911C38.01 27.5308 38.5735 26.0585 38.5735 24.3188C38.5735 22.4581 38.1061 20.8368 37.2004 19.4879C36.3024 18.1506 35.0559 17.2029 33.6836 16.5416C30.9995 15.2479 27.6109 14.9413 24.5037 15.0087C21.9248 15.0646 19.368 15.3841 17.2573 15.7381C16.3047 14.1007 14.5309 13 12.5 13C9.46243 13 7 15.4624 7 18.5C7 21.5376 9.46243 24 12.5 24Z'
|
||||
fill='black'
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
CurriculumIcon.displayName = 'CurriculumIcon';
|
||||
|
||||
export default CurriculumIcon;
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
function D3Icon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='-10 -10 116 111'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path d='M0 0h7.75a45.5 45.5 0 110 91H0V71h7.75a25.5 25.5 0 100-51H0zm36.251 0h32a27.75 27.75 0 0121.331 45.5A27.75 27.75 0 0168.251 91h-32a53.69 53.69 0 0018.746-20H68.25a7.75 7.75 0 100-15.5H60.5a53.69 53.69 0 000-20h7.75a7.75 7.75 0 100-15.5H54.997A53.69 53.69 0 0036.251 0z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
D3Icon.displayName = 'D3';
|
||||
|
||||
export default D3Icon;
|
||||
@@ -0,0 +1,21 @@
|
||||
import React from 'react';
|
||||
|
||||
function DailyCodingChallengeIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 512 512'
|
||||
fill='none'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path d='M152.1 38.2c9.9 8.9 10.7 24 1.8 33.9l-72 80c-4.4 4.9-10.6 7.8-17.2 7.9s-12.9-2.4-17.6-7L7 113C-2.3 103.6-2.3 88.4 7 79s24.6-9.4 33.9 0l22.1 22.1 55.1-61.2c8.9-9.9 24-10.7 33.9-1.8zm0 160c9.9 8.9 10.7 24 1.8 33.9l-72 80c-4.4 4.9-10.6 7.8-17.2 7.9s-12.9-2.4-17.6-7L7 273c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l22.1 22.1 55.1-61.2c8.9-9.9 24-10.7 33.9-1.8zM224 96c0-17.7 14.3-32 32-32l224 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-224 0c-17.7 0-32-14.3-32-32zm0 160c0-17.7 14.3-32 32-32l224 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-224 0c-17.7 0-32-14.3-32-32zM160 416c0-17.7 14.3-32 32-32l288 0c17.7 0 32 14.3 32 32s-14.3 32-32 32l-288 0c-17.7 0-32-14.3-32-32zM48 368a48 48 0 1 1 0 96 48 48 0 1 1 0-96z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
DailyCodingChallengeIcon.displayName = 'DailyCodingChallengeIcon';
|
||||
|
||||
export default DailyCodingChallengeIcon;
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
function DatabaseIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 448 512'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path d='M448 73.143v45.714C448 159.143 347.667 192 224 192S0 159.143 0 118.857V73.143C0 32.857 100.333 0 224 0s224 32.857 224 73.143zM448 176v102.857C448 319.143 347.667 352 224 352S0 319.143 0 278.857V176c48.125 33.143 136.208 48.572 224 48.572S399.874 209.143 448 176zm0 160v102.857C448 479.143 347.667 512 224 512S0 479.143 0 438.857V336c48.125 33.143 136.208 48.572 224 48.572S399.874 369.143 448 336z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
DatabaseIcon.displayName = 'Database';
|
||||
|
||||
export default DatabaseIcon;
|
||||
@@ -0,0 +1,95 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
function DefaultAvatar(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<svg
|
||||
height='500px'
|
||||
version='1.1'
|
||||
viewBox='0 0 500 500'
|
||||
width='500px'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
xmlnsXlink='http://www.w3.org/1999/xlink'
|
||||
aria-hidden='true'
|
||||
{...props}
|
||||
>
|
||||
<title>{t('icons.avatar')}</title>
|
||||
<desc>{t('icons.avatar-2')}</desc>
|
||||
<g fill='none' fillRule='evenodd'>
|
||||
<g id='g'>
|
||||
<rect fill='#D0D0D5' height='500' width='500' />
|
||||
<path
|
||||
d='m251.34 49c23.859 58.47 34.222 90.121 31.088 94.954-4.701 7.2493-15.381 32.924 0 50.968s77.487 6.439 92.029 23.897c14.542 17.458 12.196 68.184 14.542 135.56-22.154 0.54208-68.154 1.0837-138 1.6248l0.062-56h-0.124l0.062 56c-69.846-0.54109-115.85-1.0827-138-1.6248 2.3463-67.372 0-118.1 14.542-135.56 14.542-17.458 76.649-5.852 92.029-23.897s4.701-43.719 0-50.968c-3.134-4.8329 7.2285-36.484 31.088-94.954l0.13247 120h0.415z'
|
||||
fill='#242440'
|
||||
/>
|
||||
<path
|
||||
d='m250.13 185c47.577 0 66.872-66.034 66.872-90.434 0-42.286-29.773-76.566-66.5-76.566s-66.5 34.28-66.5 76.566c0 24.7 18.552 90.434 66.128 90.434z'
|
||||
fill='#242440'
|
||||
id='c'
|
||||
stroke='#D0D0D5'
|
||||
strokeWidth='17'
|
||||
/>
|
||||
<path
|
||||
d='m77.011 459c-19.341-119.95-29.011-183.79-29.011-191.53 0-11.605 6.2167-16.473 17.298-16.473h370.4c11.082 0 17.298 4.8681 17.298 16.473 0 7.7366-9.6704 71.579-29.011 191.53z'
|
||||
fill='#5F5F8C'
|
||||
stroke='#D0D0D5'
|
||||
strokeWidth='16'
|
||||
/>
|
||||
<rect
|
||||
fill='#5F5F8C'
|
||||
height='23'
|
||||
stroke='#D0D0D5'
|
||||
strokeWidth='6'
|
||||
width='339'
|
||||
x='81'
|
||||
y='459'
|
||||
/>
|
||||
<g fillRule='nonzero' transform='translate(162 283)'>
|
||||
<ellipse cx='88.5' cy='79' fill='#0A0A23' rx='88.5' ry='79' />
|
||||
<g transform='translate(20 40)'>
|
||||
<g id='Group' transform='translate(42.462 4)'>
|
||||
<g fill='#fff' id='e'>
|
||||
<path
|
||||
d='m38.312 39.042c-3.9186-0.91476 12.174-18.263-16.43-39.034 0 0 3.7555 10.879-15.169 35.157-18.933 24.27 8.418 38.725 8.418 38.725s-12.834-6.24 2.0846-28.459c2.6734-4.0329 6.1663-7.6847 10.507-15.899 0 0 3.839 4.9441 1.834 15.671-2.9996 16.208 13.005 11.569 13.256 11.794 5.5895 6.0077-4.6307 16.564-5.2513 16.894-0.62061 0.32307 29.185-16.36 8.0083-41.469-1.4521 1.325-3.3338 7.5359-7.2564 6.6212z'
|
||||
id='i'
|
||||
/>
|
||||
</g>
|
||||
<g fill='#000' fillOpacity='0' stroke='#000' strokeOpacity='0'>
|
||||
<path d='m38.312 39.042c-3.9186-0.91476 12.174-18.263-16.43-39.034 0 0 3.7555 10.879-15.169 35.157-18.933 24.27 8.418 38.725 8.418 38.725s-12.834-6.24 2.0846-28.459c2.6734-4.0329 6.1663-7.6847 10.507-15.899 0 0 3.839 4.9441 1.834 15.671-2.9996 16.208 13.005 11.569 13.256 11.794 5.5895 6.0077-4.6307 16.564-5.2513 16.894-0.62061 0.32307 29.185-16.36 8.0083-41.469-1.4521 1.325-3.3338 7.5359-7.2564 6.6212z' />
|
||||
</g>
|
||||
</g>
|
||||
<g id='b' transform='translate(110.13)'>
|
||||
<g fill='#fff' id='d'>
|
||||
<path
|
||||
d='m0.96996 0.62339c-0.47786 0.41439-0.95166 1.0162-0.95166 1.6215-0.0040664 1.045 1.3846 2.4611 3.9577 4.7889 10.713 9.1022 16.104 20.251 16.068 33.692-0.040843 14.875-5.7099 26.82-16.729 36.077-2.3158 1.8305-3.2674 3.2647-3.2715 4.4935 0 0.60537 0.4697 1.2324 0.94347 1.8341 0.44519 0.4216 1.3927 0.83962 2.0748 0.83962 2.5486 0.0071777 6.1183-2.6521 10.774-7.8266 9.0712-9.8085 13.172-20.64 13.401-35.4 0.21238-14.77-5.0319-24.784-15.308-35.126-3.6963-3.6935-6.7759-5.6141-8.8834-5.6177-0.68208 0-1.3927 0.20539-2.0748 0.62339z'
|
||||
id='a'
|
||||
/>
|
||||
</g>
|
||||
<g fill='#000' fillOpacity='0' stroke='#000' strokeOpacity='0'>
|
||||
<path d='m0.96996 0.62339c-0.47786 0.41439-0.95166 1.0162-0.95166 1.6215-0.0040664 1.045 1.3846 2.4611 3.9577 4.7889 10.713 9.1022 16.104 20.251 16.068 33.692-0.040843 14.875-5.7099 26.82-16.729 36.077-2.3158 1.8305-3.2674 3.2647-3.2715 4.4935 0 0.60537 0.4697 1.2324 0.94347 1.8341 0.44519 0.4216 1.3927 0.83962 2.0748 0.83962 2.5486 0.0071777 6.1183-2.6521 10.774-7.8266 9.0712-9.8085 13.172-20.64 13.401-35.4 0.21238-14.77-5.0319-24.784-15.308-35.126-3.6963-3.6935-6.7759-5.6141-8.8834-5.6177-0.68208 0-1.3927 0.20539-2.0748 0.62339z' />
|
||||
</g>
|
||||
</g>
|
||||
<g fill='#fff' id='h'>
|
||||
<path
|
||||
d='m26.367 0.6342c0.47409 0.41439 0.9482 1.0162 0.9482 1.6215 0.004069 1.045-1.3855 2.4611-3.9603 4.7889-10.72 9.1022-16.111 20.251-16.078 33.692 0.04087 14.875 5.7136 26.82 16.74 36.077 2.3173 1.8305 3.2696 3.2647 3.2737 4.4935 0 0.60537-0.47001 1.2324-0.9441 1.8341-0.44548 0.4216-1.3896 0.83962-2.0762 0.83962-2.5503 0.0071777-6.1223-2.6521-10.782-7.8266-9.0773-9.8085-13.181-20.64-13.409-35.4-0.21252-14.77 5.0352-24.784 15.318-35.126 3.6987-3.6935 6.7844-5.6141 8.8892-5.6177 0.68253 0 1.3937 0.20539 2.0803 0.62339z'
|
||||
id='f'
|
||||
/>
|
||||
</g>
|
||||
<g fill='#000' fillOpacity='0' stroke='#000' strokeOpacity='0'>
|
||||
<path d='m26.367 0.6342c0.47409 0.41439 0.9482 1.0162 0.9482 1.6215 0.004069 1.045-1.3855 2.4611-3.9603 4.7889-10.72 9.1022-16.111 20.251-16.078 33.692 0.04087 14.875 5.7136 26.82 16.74 36.077 2.3173 1.8305 3.2696 3.2647 3.2737 4.4935 0 0.60537-0.47001 1.2324-0.9441 1.8341-0.44548 0.4216-1.3896 0.83962-2.0762 0.83962-2.5503 0.0071777-6.1223-2.6521-10.782-7.8266-9.0773-9.8085-13.181-20.64-13.409-35.4-0.21252-14.77 5.0352-24.784 15.318-35.126 3.6987-3.6935 6.7844-5.6141 8.8892-5.6177 0.68253 0 1.3937 0.20539 2.0803 0.62339z' />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
DefaultAvatar.displayName = 'DefaultAvatar';
|
||||
|
||||
export default DefaultAvatar;
|
||||
@@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
|
||||
function DotNetLogo(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
role='img'
|
||||
viewBox='0 0 24 24'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<title>.NET</title>
|
||||
<path
|
||||
d='M24 8.77h-2.468v7.565h-1.425V8.77h-2.462V7.53H24zm-6.852 7.565h-4.821V7.53h4.63v1.24h-3.205v2.494h2.953v1.234h-2.953v2.604h3.396zm-6.708 0H8.882L4.78 9.863a2.896 2.896 0 0 1-.258-.51h-.036c.032.189.048.592.048 1.21v5.772H3.157V7.53h1.659l3.965 6.32c.167.261.275.442.323.54h.024c-.04-.233-.06-.629-.06-1.185V7.529h1.372zm-8.703-.693a.868.829 0 0 1-.869.829.868.829 0 0 1-.868-.83.868.829 0 0 1 .868-.828.868.829 0 0 1 .869.829Z'
|
||||
fill='var(--primary-color)'
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
DotNetLogo.displayName = 'DotNetLogo';
|
||||
export default DotNetLogo;
|
||||
@@ -0,0 +1,28 @@
|
||||
import React from 'react';
|
||||
|
||||
function DropDown(): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
width='10'
|
||||
height='10'
|
||||
viewBox='0 0 389 254'
|
||||
fill='none'
|
||||
className='dropdown-icon'
|
||||
>
|
||||
<path
|
||||
d='M194.5 0L388.5 254H307.5L194.5 99L78.5 254H0.5L194.5 0Z'
|
||||
style={{
|
||||
stroke: 'var(--primary-color)',
|
||||
fill: 'var(--primary-color)',
|
||||
strokeWidth: '1px'
|
||||
}}
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
DropDown.displayName = 'DropDown';
|
||||
|
||||
export default DropDown;
|
||||
@@ -0,0 +1,50 @@
|
||||
import React from 'react';
|
||||
function DumbbellIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
width='62'
|
||||
height='55'
|
||||
viewBox='0 0 62 42'
|
||||
fill='none'
|
||||
{...props}
|
||||
>
|
||||
<rect y='17.2132' width='61.5396' height='7.69244' fill='#d0d0d5' />
|
||||
<rect
|
||||
x='12.8208'
|
||||
y='0.973633'
|
||||
width='8.54716'
|
||||
height='41.0264'
|
||||
fill='#d0d0d5'
|
||||
/>
|
||||
<rect
|
||||
x='39.3169'
|
||||
y='0.973633'
|
||||
width='8.54716'
|
||||
height='41.0264'
|
||||
fill='#d0d0d5'
|
||||
/>
|
||||
<rect
|
||||
x='4.14014'
|
||||
y='5.84572'
|
||||
width='8.77419'
|
||||
height='31.2822'
|
||||
fill='#d0d0d5'
|
||||
/>
|
||||
<rect
|
||||
x='47.0361'
|
||||
y='5.84572'
|
||||
width='8.77419'
|
||||
height='31.2822'
|
||||
fill='#d0d0d5'
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
DumbbellIcon.displayName = 'DumbbellIcon';
|
||||
|
||||
export default DumbbellIcon;
|
||||
@@ -0,0 +1,52 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
function RedFail(): JSX.Element {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<svg
|
||||
height='50'
|
||||
viewBox='0 0 200 200'
|
||||
width='50'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
aria-hidden='true'
|
||||
>
|
||||
<g>
|
||||
<title>{t('icons.fail')}</title>
|
||||
<circle
|
||||
cx='100'
|
||||
cy='99'
|
||||
fill='var(--primary-color)'
|
||||
r='95'
|
||||
stroke='(var--primary-color)'
|
||||
strokeDasharray='null'
|
||||
/>
|
||||
<rect
|
||||
fill='var(--primary-background)'
|
||||
height='30'
|
||||
stroke='var(--primary-background)'
|
||||
strokeDasharray='null'
|
||||
transform='rotate(-45, 100, 103.321)'
|
||||
width='128.85878'
|
||||
x='35'
|
||||
y='88'
|
||||
/>
|
||||
<rect
|
||||
fill='var(--primary-background)'
|
||||
height='30'
|
||||
stroke='var(--primary-background)'
|
||||
strokeDasharray='null'
|
||||
transform='rotate(45, 99.5, 104)'
|
||||
width='128.85878'
|
||||
x='35'
|
||||
y='88'
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
RedFail.displayName = 'RedFail';
|
||||
|
||||
export default RedFail;
|
||||
@@ -0,0 +1,27 @@
|
||||
import React from 'react';
|
||||
function FreeIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
width='60'
|
||||
height='60'
|
||||
viewBox='0 0 60 60'
|
||||
fill='none'
|
||||
aria-hidden='true'
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fillRule='evenodd'
|
||||
clipRule='evenodd'
|
||||
d='M14.9393 17.0607L7.7525 9.87383C2.93461 15.1962 0 22.2554 0 30C0 46.5685 13.4315 60 30 60C37.7446 60 44.8038 57.0654 50.1262 52.2475L42.9393 45.0607L45.0607 42.9393L52.2475 50.1262C57.0654 44.8038 60 37.7446 60 30C60 13.4315 46.5685 0 30 0C22.2554 0 15.1962 2.93461 9.87383 7.75251L17.0607 14.9393L14.9393 17.0607ZM31.5 11.5523V7H28.5V11.5383C26.4603 11.6476 24.1085 12.0266 22.0959 13.1193C20.8041 13.8207 19.6338 14.8258 18.7947 16.244C17.9561 17.6612 17.5 19.4035 17.5 21.5C17.5 23.0594 17.9306 24.3879 18.7277 25.4956C19.5089 26.5812 20.5812 27.3712 21.742 27.9786C23.686 28.9958 26.1584 29.6304 28.5 30.2141V45.4771C26.5399 45.4091 24.7338 45.1643 23.3339 44.4126C22.5029 43.9663 21.8229 43.3427 21.3361 42.4384C20.8415 41.5196 20.5 40.2237 20.5 38.3727H17.5C17.5 40.5854 17.9082 42.3997 18.6946 43.8604C19.4887 45.3357 20.6209 46.3609 21.9146 47.0556C23.9294 48.1375 26.344 48.4138 28.5 48.4802V52H31.5V48.4438C33.764 48.2729 36.1711 47.693 38.17 46.4435C40.7066 44.8578 42.5 42.2345 42.5 38.3727C42.5 34.6878 40.8257 32.2579 38.3954 30.6353C36.4028 29.305 33.8961 28.513 31.5 27.88V14.5609C33.2192 14.7025 35.0055 15.1059 36.4432 15.9274C38.1994 16.9309 39.5 18.5785 39.5 21.5H42.5C42.5 17.4215 40.5506 14.8191 37.9315 13.3226C35.9247 12.1759 33.5735 11.698 31.5 11.5523ZM28.5 14.5437C26.7464 14.6512 24.9593 14.9783 23.5274 15.7557C22.632 16.2419 21.8965 16.893 21.3766 17.7717C20.8561 18.6513 20.5 19.8465 20.5 21.5C20.5 22.4724 20.7568 23.1791 21.1628 23.7434C21.5848 24.3298 22.2312 24.8487 23.1329 25.3205C24.5777 26.0765 26.4192 26.5914 28.5 27.1195V14.5437ZM31.5 30.9894V45.4338C33.349 45.2686 35.1618 44.786 36.5798 43.8997C38.2933 42.8285 39.5 41.1382 39.5 38.3727C39.5 35.8025 38.4243 34.2618 36.7296 33.1303C35.3311 32.1966 33.5267 31.5557 31.5 30.9894Z'
|
||||
fill='black'
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
FreeIcon.displayName = 'FreeIcon';
|
||||
|
||||
export default FreeIcon;
|
||||
@@ -0,0 +1,114 @@
|
||||
import React from 'react';
|
||||
|
||||
function FreeCodeCampLogo(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
height={24}
|
||||
version='1.1'
|
||||
viewBox='0 0 210 24'
|
||||
width={210}
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
xmlnsXlink='http://www.w3.org/1999/xlink'
|
||||
{...props}
|
||||
>
|
||||
<defs>
|
||||
<path
|
||||
d='m35.42 5.56 0.43 0.05 0.42 0.08 0.39 0.09 0.37 0.12 0.36 0.14 0.32 0.16 0.31 0.18 0.28 0.21 0.27 0.22 0.24 0.24 0.22 0.27 0.2 0.28 0.18 0.31 0.16 0.33 0.13 0.35 0.12 0.37 0.09 0.39 0.08 0.41 0.05 0.44 0.03 0.45 0.01 0.47v0.12 0.11l-0.01 0.1-0.04 0.2-0.04 0.18-0.03 0.08-0.07 0.15-0.04 0.06-0.05 0.06-0.04 0.06-0.06 0.05-0.05 0.05-0.06 0.03-0.06 0.04-0.07 0.03-0.08 0.02-0.07 0.02-0.16 0.02h-8.9v-0.07h-0.02v1.84l0.01 0.24 0.03 0.24 0.03 0.23 0.06 0.22 0.07 0.2 0.09 0.2 0.1 0.17 0.12 0.18 0.13 0.15 0.15 0.16 0.17 0.13 0.18 0.13 0.2 0.11 0.21 0.11 0.23 0.09 0.24 0.09 0.27 0.06 0.27 0.07 0.3 0.05 0.31 0.03 0.32 0.03 0.34 0.02 0.36 0.01h0.13l0.13-0.01h0.13l0.12-0.01h0.13l0.24-0.02 0.23-0.02 0.11-0.01 0.11-0.02 0.21-0.03 0.1-0.01 0.1-0.02 0.29-0.06 0.09-0.03 0.09-0.02 0.08-0.03 0.09-0.03 0.08-0.03 0.05-0.01 0.15-0.06 0.06-0.03 0.06-0.02 0.12-0.06 0.21-0.11 0.08-0.04 0.07-0.05 0.17-0.09 0.08-0.05 0.09-0.05 0.09-0.06 0.19-0.13 0.1-0.06 0.1-0.07 0.11-0.07 0.12-0.12 0.13-0.1 0.06-0.05 0.05-0.04 0.06-0.04 0.05-0.05 0.09-0.07 0.1-0.06 0.04-0.03 0.04-0.02 0.04-0.03 0.07-0.03 0.03-0.01 0.04-0.01 0.02-0.01 0.05-0.01h0.09l0.1 0.01 0.15 0.03 0.04 0.02 0.07 0.04 0.04 0.03 0.09 0.09 0.03 0.04 0.04 0.08 0.01 0.05 0.02 0.05 0.01 0.06 0.02 0.1v0.07 0.07 0.06l-0.01 0.07-0.01 0.06-0.01 0.07-0.06 0.2-0.03 0.06-0.04 0.07-0.03 0.07-0.04 0.07-0.05 0.07-0.05 0.06-0.1 0.14-0.13 0.13-0.13 0.14-0.16 0.14-0.09 0.06-0.08 0.08-0.15 0.1-0.15 0.11-0.32 0.2-0.17 0.09-0.18 0.09-0.18 0.08-0.19 0.07-0.19 0.08-0.21 0.07-0.42 0.12-0.22 0.05-0.23 0.05-0.47 0.09-0.5 0.06-0.52 0.04-0.27 0.01-0.28 0.01h-0.28-0.48l-0.47-0.03-0.45-0.04-0.42-0.07-0.41-0.07-0.38-0.09-0.36-0.11-0.34-0.13-0.31-0.15-0.3-0.16-0.27-0.18-0.26-0.2-0.22-0.21-0.21-0.23-0.19-0.25-0.16-0.26-0.14-0.29-0.13-0.29-0.1-0.32-0.07-0.34-0.06-0.35-0.03-0.37-0.01-0.39v-4.71l0.01-0.14 0.01-0.12 0.01-0.13 0.04-0.26 0.04-0.13 0.03-0.12 0.08-0.24 0.1-0.24 0.12-0.23 0.06-0.11 0.07-0.12 0.08-0.1 0.08-0.11 0.08-0.1 0.09-0.11 0.19-0.2 0.23-0.23 0.3-0.24 0.15-0.11 0.17-0.11 0.17-0.1 0.17-0.09 0.18-0.09 0.38-0.16 0.2-0.07 0.42-0.12 0.22-0.05 0.23-0.05 0.22-0.04 0.24-0.03 0.24-0.04 0.24-0.02 0.25-0.02 0.52-0.02h0.27l0.47 0.01 0.47 0.03zm-2.04 1.6-0.41 0.07-0.39 0.1-0.38 0.13-0.37 0.15-0.35 0.18-0.32 0.25-0.27 0.26-0.23 0.28-0.19 0.3-0.13 0.31-0.08 0.32-0.03 0.35v0.96h8.19l-0.09-0.98-0.25-0.83-0.43-0.69-0.6-0.53-0.76-0.38-0.95-0.23-1.11-0.07-0.43 0.01-0.42 0.04z'
|
||||
id='k'
|
||||
/>
|
||||
<path
|
||||
d='m107.21 5.56 0.43 0.05 0.42 0.08 0.39 0.09 0.37 0.12 0.35 0.14 0.33 0.16 0.31 0.18 0.29 0.21 0.26 0.22 0.24 0.24 0.22 0.27 0.21 0.28 0.17 0.31 0.16 0.33 0.14 0.35 0.11 0.37 0.1 0.39 0.07 0.41 0.05 0.44 0.03 0.45 0.01 0.47v0.12l-0.01 0.11-0.02 0.2-0.02 0.1-0.02 0.09-0.03 0.09-0.02 0.08-0.03 0.07-0.04 0.08-0.04 0.06-0.1 0.12-0.1 0.1-0.13 0.07-0.13 0.05-0.08 0.02-0.16 0.02-8.92 0.01v1.76l0.01 0.24 0.02 0.24 0.04 0.23 0.06 0.22 0.07 0.2 0.08 0.2 0.11 0.17 0.11 0.18 0.14 0.15 0.15 0.16 0.17 0.13 0.18 0.13 0.19 0.11 0.22 0.11 0.23 0.09 0.24 0.09 0.26 0.06 0.28 0.07 0.3 0.05 0.31 0.03 0.32 0.03 0.34 0.02 0.36 0.01h0.13l0.13-0.01h0.13l0.25-0.01 0.24-0.02 0.22-0.02 0.12-0.01 0.11-0.02 0.31-0.04 0.2-0.04 0.19-0.04 0.09-0.03 0.09-0.02 0.09-0.03 0.08-0.03 0.13-0.04 0.04-0.02 0.06-0.02 0.05-0.02 0.06-0.03 0.05-0.02 0.07-0.03 0.2-0.1 0.14-0.08 0.08-0.05 0.08-0.04 0.08-0.05 0.18-0.1 0.18-0.12 0.2-0.13 0.1-0.07 0.11-0.07 0.06-0.06 0.07-0.06 0.05-0.05 0.07-0.05 0.05-0.05 0.06-0.04 0.11-0.09 0.05-0.03 0.05-0.04 0.04-0.03 0.05-0.03 0.04-0.03 0.04-0.02 0.04-0.03 0.07-0.03 0.12-0.04h0.02 0.09 0.05l0.06 0.01 0.09 0.02 0.05 0.01 0.12 0.06 0.12 0.12 0.03 0.04 0.04 0.08 0.01 0.05 0.02 0.05 0.02 0.11 0.01 0.05v0.07 0.13l-0.01 0.07-0.01 0.06-0.01 0.07-0.04 0.14-0.02 0.06-0.03 0.06-0.04 0.07-0.03 0.07-0.09 0.14-0.05 0.06-0.05 0.07-0.11 0.14-0.21 0.2-0.23 0.2-0.09 0.08-0.3 0.21-0.15 0.1-0.17 0.1-0.17 0.09-0.18 0.09-0.18 0.08-0.19 0.07-0.2 0.08-0.2 0.07-0.42 0.12-0.22 0.05-0.23 0.05-0.23 0.04-0.24 0.05-0.5 0.06-0.52 0.04-0.55 0.02h-0.28-0.49l-0.46-0.03-0.45-0.04-0.43-0.07-0.39-0.07-0.39-0.09-0.36-0.11-0.33-0.13-0.33-0.15-0.29-0.16-0.27-0.18-0.25-0.2-0.23-0.21-0.22-0.23-0.18-0.25-0.17-0.26-0.14-0.29-0.12-0.29-0.1-0.32-0.08-0.34-0.05-0.35-0.04-0.37-0.01-0.39v-4.58l0.01-0.13v-0.14l0.02-0.12 0.01-0.13 0.02-0.13 0.05-0.26 0.12-0.36 0.1-0.24 0.11-0.23 0.07-0.11 0.07-0.12 0.07-0.1 0.09-0.11 0.08-0.1 0.09-0.11 0.19-0.2 0.1-0.1 0.14-0.13 0.14-0.12 0.15-0.12 0.15-0.11 0.17-0.11 0.17-0.1 0.17-0.09 0.19-0.09 0.18-0.08 0.19-0.08 0.2-0.07 0.42-0.12 0.44-0.1 0.23-0.04 0.23-0.03 0.25-0.04 0.24-0.02 0.25-0.02 0.52-0.02h0.27l0.48 0.01 0.46 0.03zm-2.04 1.6-0.41 0.07-0.39 0.1-0.38 0.13-0.37 0.15-0.34 0.18-0.34 0.25-0.29 0.26-0.23 0.28-0.17 0.3-0.13 0.31-0.07 0.32-0.03 0.35v0.96h8.19l-0.09-0.98-0.25-0.83-0.43-0.69-0.6-0.53-0.76-0.38-0.95-0.23-1.11-0.07-0.43 0.01-0.42 0.04z'
|
||||
id='j'
|
||||
/>
|
||||
<path
|
||||
d='m203.57 0.17c-0.12 0.12-0.24 0.29-0.24 0.45 0 0.29 0.34 0.69 0.97 1.33 2.63 2.53 3.95 5.62 3.94 9.35-0.01 4.13-1.4 7.45-4.1 10.01-0.57 0.51-0.8 0.91-0.8 1.25 0 0.17 0.12 0.34 0.23 0.51 0.11 0.12 0.34 0.23 0.51 0.23 0.62 0 1.5-0.73 2.64-2.17 2.22-2.72 3.22-5.73 3.28-9.82 0.05-4.1-1.23-6.88-3.75-9.75-0.9-1.03-1.66-1.56-2.17-1.56-0.17 0-0.35 0.06-0.51 0.17z'
|
||||
id='b'
|
||||
/>
|
||||
<path
|
||||
d='m124.75 1.76c1.14 0.86 1.73 2.07 1.73 3.55 0 0.68-0.29 1.02-0.86 1.02-0.39 0-0.68-0.34-0.85-1.02-0.11-0.57-0.34-1.08-0.62-1.62-0.52-0.9-1.61-1.32-3.32-1.32-1.49 0-2.52 0.34-3.14 1.08-0.57 0.68-0.91 1.72-0.91 3.26v5.95c0 1.55 0.34 2.63 0.97 3.31 0.68 0.74 1.72 1.13 3.2 1.13 2.23 0 3.54-0.79 3.82-2.34 0.12-0.57 0.17-0.86 0.17-0.91 0.12-0.34 0.35-0.51 0.68-0.51 0.57 0 0.86 0.34 0.86 1.02 0 1.44-0.57 2.52-1.78 3.38-0.97 0.62-2.18 0.96-3.77 0.96-1.84 0-3.26-0.4-4.3-1.25-1.16-0.8-1.73-2.16-1.73-3.94v-7.16c0-3.77 1.95-5.61 5.95-5.61 1.61 0 2.86 0.34 3.9 1.02z'
|
||||
id='n'
|
||||
/>
|
||||
<path
|
||||
d='m14.21 6.57c0-0.56 0.34-0.79 1.02-0.79h3.32c0.57 0 0.85 0.51 0.85 1.44 1.02-1.08 2.12-1.73 3.26-1.73 0.96 0 1.72 0.29 2.23 0.86 0.57 0.57 0.8 1.38 0.8 2.29 0 0.63-0.29 0.97-0.8 0.97-0.34 0-0.57-0.23-0.68-0.63-0.23-0.8-0.34-1.19-0.4-1.25-0.22-0.39-0.68-0.62-1.25-0.62-0.62 0-1.25 0.23-1.78 0.68-0.34 0.23-0.8 0.74-1.38 1.49v7.67h3.08c0.68 0 1.03 0.29 1.03 0.8 0 0.57-0.35 0.86-1.03 0.86h-7.33c-0.68 0-1.02-0.29-1.02-0.8 0-0.57 0.34-0.8 1.02-0.8h2.52v-0.07h0.02v-9.57h-2.46c-0.68 0-1.02-0.28-1.02-0.8z'
|
||||
id='l'
|
||||
/>
|
||||
<path
|
||||
d='m96.68 0.04 0.06 0.02 0.06 0.03 0.05 0.03 0.06 0.04 0.13 0.13 0.03 0.06 0.04 0.06 0.03 0.07 0.02 0.07 0.04 0.16 0.04 0.18 0.01 0.2v0.1 16.84 0.08l-0.01 0.07v0.07l-0.04 0.13-0.01 0.05-0.03 0.06-0.02 0.05-0.06 0.09-0.07 0.08-0.05 0.03-0.04 0.03-0.05 0.03-0.1 0.04-0.06 0.02-0.12 0.02-0.07 0.01h-0.11l-0.13-0.02-0.04-0.01-0.04-0.02-0.04-0.01-0.03-0.02-0.03-0.01-0.03-0.03-0.03-0.02-0.06-0.05-0.02-0.03-0.07-0.12-0.01-0.04-0.02-0.05-0.01-0.04-0.02-0.05v-0.05-0.08-0.04-0.04l-0.01-0.04v-0.04l-0.01-0.04v-0.04-0.04l-0.01-0.05v-0.04-0.05l-0.01-0.09v-0.06l-0.01-0.04v-0.06-0.11l-0.01-0.06v-0.13l-0.13 0.09-0.13 0.08-0.13 0.09-0.24 0.14-0.11 0.08-0.12 0.07-0.21 0.12-0.1 0.06-0.09 0.06-0.1 0.05-0.25 0.14-0.14 0.08-0.14 0.06-0.12 0.05-0.05 0.02-0.09 0.04-0.09 0.03-0.09 0.02-0.19 0.06-0.4 0.08-0.21 0.03-0.22 0.03-0.11 0.02-0.23 0.02h-0.12l-0.12 0.01h-0.11l-0.12 0.01h-0.46l-0.21-0.01-0.2-0.01-0.2-0.02-0.19-0.01-0.2-0.03-0.18-0.02-0.37-0.07-0.34-0.08-0.18-0.05-0.32-0.1-0.32-0.12-0.15-0.07-0.15-0.06-0.42-0.24-0.13-0.08-0.14-0.1-0.28-0.22-0.12-0.11-0.12-0.13-0.11-0.12-0.11-0.13-0.1-0.14-0.09-0.14-0.17-0.29-0.07-0.15-0.07-0.16-0.06-0.16-0.05-0.16-0.05-0.18-0.04-0.18-0.03-0.17-0.02-0.19-0.03-0.19-0.01-0.19v-5.21l0.01-0.19 0.03-0.18 0.02-0.18 0.03-0.18 0.08-0.34 0.05-0.16 0.06-0.16 0.06-0.15 0.08-0.15 0.07-0.15 0.18-0.28 0.2-0.26 0.1-0.12 0.24-0.24 0.26-0.22 0.14-0.1 0.39-0.24 0.15-0.07 0.28-0.14 0.31-0.12 0.15-0.05 0.33-0.1 0.33-0.08 0.72-0.12 0.37-0.03 0.38-0.02h0.45l0.25 0.02h0.12 0.13l0.12 0.02 0.12 0.01 0.22 0.02 0.22 0.04 0.11 0.01 0.21 0.04 0.1 0.02 0.09 0.02 0.28 0.08 0.09 0.03 0.09 0.04 0.08 0.03 0.09 0.03 0.08 0.04 0.09 0.03 0.09 0.04 0.1 0.05 0.17 0.09 0.29 0.16 0.09 0.05 0.29 0.19 0.2 0.14 0.09 0.07 0.4 0.32v-5.89l0.01-0.1v-0.2l0.04-0.18 0.01-0.08 0.03-0.08 0.02-0.07 0.03-0.07 0.03-0.06 0.04-0.06 0.04-0.04 0.04-0.05 0.04-0.04 0.05-0.04 0.1-0.06 0.06-0.02 0.13-0.03 0.06-0.01h0.14l0.07 0.01 0.14 0.03zm-5.7 7.19-0.26 0.03-0.26 0.02-0.25 0.05-0.24 0.05-0.23 0.05-0.42 0.16-0.19 0.09-0.18 0.1-0.2 0.15-0.2 0.16-0.17 0.17-0.15 0.17-0.14 0.19-0.11 0.2-0.1 0.2-0.08 0.23-0.05 0.23-0.04 0.23-0.01 0.26v4.52l0.01 0.26 0.03 0.25 0.05 0.23 0.07 0.23 0.09 0.21 0.12 0.2 0.13 0.19 0.16 0.17 0.17 0.16 0.2 0.14 0.22 0.14 0.19 0.09 0.42 0.16 0.22 0.07 0.22 0.06 0.24 0.06 0.25 0.04 0.26 0.04 0.27 0.03 0.56 0.02 0.47-0.01 0.44-0.04 0.43-0.06 0.21-0.04 0.2-0.06 0.38-0.12 0.17-0.07 0.14-0.1 0.16-0.11 0.15-0.11 0.16-0.12 0.17-0.12 0.16-0.13 0.18-0.13 0.17-0.15 0.18-0.15 0.36-0.32v-6.59l-0.21-0.16-0.21-0.14-0.2-0.14-0.2-0.13-0.19-0.12-0.18-0.11-0.17-0.11-0.16-0.09-0.3-0.14-0.13-0.06-0.19-0.07-0.38-0.12-0.2-0.05-0.4-0.08-0.21-0.03-0.21-0.02-0.21-0.01-0.43-0.01h-0.28l-0.27 0.01z'
|
||||
id='c'
|
||||
/>
|
||||
<path
|
||||
d='m195.66 12.04c-0.99-0.25 3.06-5.03-4.13-10.75 0 0 0.94 3-3.81 9.69-4.76 6.68 2.11 10.66 2.11 10.66s-3.22-1.72 0.53-7.84c0.67-1.11 1.55-2.11 2.64-4.38 0 0 0.96 1.37 0.46 4.32-0.75 4.47 3.27 3.19 3.33 3.25 1.41 1.65-1.16 4.56-1.32 4.65s7.34-4.5 2.01-11.42c-0.36 0.36-0.83 2.08-1.82 1.82z'
|
||||
id='e'
|
||||
/>
|
||||
<path
|
||||
d='m135.26 5.37 0.19 0.01 0.18 0.02 0.18 0.01 0.18 0.02 0.34 0.04 0.16 0.02 0.16 0.04 0.15 0.02 0.14 0.04 0.15 0.03 0.28 0.08 0.26 0.08 0.36 0.15 0.12 0.06 0.11 0.05 0.1 0.06 0.11 0.06 0.12 0.08 0.1 0.09 0.11 0.09 0.2 0.2 0.18 0.22 0.16 0.24 0.07 0.12 0.14 0.26 0.12 0.29 0.05 0.14 0.04 0.15 0.05 0.16 0.04 0.15 0.03 0.17 0.02 0.16 0.04 0.36 0.01 0.18 0.02 0.18v6.1 0.08 0.08l0.02 0.28 0.01 0.07 0.02 0.12 0.02 0.06 0.01 0.06 0.03 0.11 0.02 0.05 0.06 0.14 0.03 0.04 0.02 0.04 0.03 0.04 0.06 0.07 0.08 0.08 0.02 0.01v0.01h0.03l0.01 0.02 0.05 0.02 0.02 0.01 0.05 0.02 0.03 0.02 0.04 0.01 0.11 0.04 0.12 0.05 0.1 0.04 0.04 0.01 0.05 0.02 0.05 0.03 0.09 0.03 0.07 0.03 0.02 0.02 0.03 0.02 0.05 0.04 0.02 0.02 0.02 0.03 0.02 0.02 0.04 0.06 0.03 0.06 0.01 0.04 0.01 0.03 0.02 0.08v0.04l0.01 0.04 0.01 0.05v0.05l0.01 0.05v0.21l-0.02 0.05v0.04l-0.01 0.05-0.01 0.04-0.02 0.04-0.01 0.04-0.02 0.03-0.03 0.04-0.05 0.06-0.02 0.03-0.04 0.02-0.11 0.06-0.08 0.04-0.1 0.02-0.1 0.01h-0.06-0.11-0.02-0.01l-0.03-0.01h-0.02-0.02l-0.1-0.02-0.03-0.02h-0.03l-0.06-0.02-0.11-0.03-0.12-0.03-0.05-0.01-0.04-0.01-0.05-0.02-0.21-0.07-0.07-0.02-0.07-0.03-0.24-0.08-0.1-0.04-0.05-0.01-0.04-0.02-0.05-0.01-0.04-0.01-0.04-0.02-0.03-0.01-0.07-0.02-0.07-0.03-0.03-0.01-0.01-0.01-0.02-0.01h-0.03-0.04l-0.03-0.02-0.03-0.01-0.04-0.01-0.02-0.02-0.06-0.04-0.03-0.03-0.02-0.03-0.03-0.03-0.02-0.03-0.02-0.04-0.03-0.04-0.02-0.04-0.01-0.04-0.03-0.04-0.02-0.05-0.03-0.09-0.06-0.21-0.02-0.06-0.23 0.16-0.22 0.15-0.1 0.07-0.2 0.12-0.1 0.07-0.34 0.22-0.08 0.04-0.07 0.05-0.21 0.12-0.06 0.04-0.16 0.08-0.05 0.02-0.09 0.04-0.04 0.01-0.06 0.04-0.07 0.02-0.15 0.05-0.4 0.1-0.08 0.01-0.18 0.03-0.09 0.01-0.09 0.02-0.28 0.03-0.2 0.02h-0.1l-0.11 0.01h-0.1-0.49-0.16l-0.16-0.01-0.31-0.02-0.3-0.03-0.15-0.02-0.15-0.03-0.28-0.05-0.27-0.06-0.14-0.04-0.13-0.04-0.12-0.04-0.13-0.05-0.24-0.09-0.12-0.06-0.11-0.05-0.11-0.06-0.11-0.07-0.11-0.06-0.1-0.07-0.24-0.16-0.22-0.19-0.1-0.1-0.09-0.1-0.1-0.1-0.24-0.33-0.14-0.24-0.06-0.12-0.06-0.13-0.05-0.12-0.05-0.13-0.08-0.27-0.06-0.28-0.04-0.3-0.02-0.3v-0.32l0.01-0.15 0.01-0.16 0.02-0.14 0.05-0.3 0.07-0.28 0.05-0.14 0.11-0.26 0.12-0.26 0.15-0.24 0.16-0.22 0.09-0.11 0.1-0.11 0.2-0.2 0.11-0.09 0.23-0.18 0.13-0.08 0.33-0.24 0.24-0.13 0.26-0.13 0.13-0.05 0.26-0.11 0.14-0.05 0.42-0.12 0.15-0.03 0.14-0.04 0.15-0.02 0.15-0.03 0.16-0.02 0.15-0.01 0.16-0.02 0.48-0.03h0.3l0.13 0.01h0.14l0.29 0.02 0.14 0.02 0.15 0.02 0.14 0.02 0.16 0.02 0.14 0.02 0.15 0.04 0.16 0.02 0.15 0.03 0.32 0.08 0.49 0.12 0.16 0.05 0.51 0.15 0.36 0.12 0.17 0.06v-2.01-0.12l-0.01-0.11-0.01-0.1-0.01-0.12-0.02-0.09-0.02-0.11-0.04-0.1-0.03-0.1-0.03-0.09-0.05-0.09-0.04-0.09-0.11-0.16-0.06-0.09-0.06-0.07-0.07-0.08-0.15-0.14-0.08-0.07-0.18-0.12-0.1-0.06-0.2-0.1-0.11-0.06-0.07-0.03-0.16-0.06-0.34-0.11-0.26-0.06-0.1-0.02-0.09-0.01-0.1-0.02-0.09-0.01-0.3-0.03-0.1-0.02h-0.1l-0.11-0.01-0.1-0.01h-0.11-0.1-0.47l-0.25 0.01-0.24 0.01-0.23 0.02-0.42 0.06-0.2 0.03-0.19 0.04-0.17 0.05-0.17 0.06-0.16 0.05-0.15 0.07-0.14 0.07-0.13 0.07-0.12 0.09-0.12 0.08-0.1 0.1-0.09 0.1-0.09 0.11-0.08 0.11-0.06 0.11-0.06 0.13-0.05 0.13-0.04 0.14-0.03 0.14-0.01 0.07-0.02 0.06-0.04 0.22-0.02 0.09-0.01 0.05-0.01 0.04-0.01 0.03v0.04l-0.02 0.06-0.01 0.06-0.01 0.04v0.02l-0.01 0.02v0.01 0.01 0.03l-0.02 0.03-0.03 0.07-0.01 0.02-0.05 0.06-0.01 0.02-0.03 0.02-0.05 0.05-0.02 0.01-0.02 0.02-0.03 0.01-0.03 0.02-0.09 0.03-0.04 0.01-0.06 0.02h-0.04-0.04l-0.03 0.01h-0.15l-0.06-0.01-0.13-0.02-0.06-0.01-0.15-0.06-0.1-0.06-0.04-0.04-0.04-0.03-0.08-0.08-0.03-0.05-0.05-0.09-0.03-0.06-0.01-0.06-0.04-0.12-0.01-0.06v-0.07l-0.01-0.08v-0.17l0.01-0.1v-0.1l0.02-0.1 0.01-0.1 0.04-0.2 0.05-0.2 0.03-0.1 0.03-0.09 0.08-0.2 0.05-0.1 0.09-0.19 0.18-0.28 0.06-0.09 0.07-0.09 0.22-0.27 0.08-0.09 0.1-0.11 0.22-0.2 0.12-0.09 0.26-0.18 0.14-0.08 0.15-0.08 0.16-0.08 0.15-0.06 0.17-0.07 0.18-0.06 0.18-0.05 0.38-0.1 0.2-0.04 0.42-0.08 0.44-0.05 0.46-0.04 0.24-0.01h0.25l0.25-0.01h0.2l0.2 0.01h0.2zm-2.41 7.31-0.68 0.24-0.54 0.35-0.38 0.44-0.23 0.54-0.07 0.64 0.02 0.34 0.06 0.31 0.11 0.3 0.15 0.27 0.2 0.25 0.25 0.2 0.29 0.17 0.25 0.13 0.28 0.12 0.3 0.09 0.32 0.08 0.34 0.05 0.36 0.03 0.38 0.01 0.34-0.01 0.32-0.02 0.32-0.04 0.31-0.07 0.3-0.07 0.3-0.11 0.29-0.13 0.2-0.12 0.22-0.15 0.25-0.16 0.26-0.18 0.28-0.21 0.3-0.22 0.31-0.23v-2.41l-0.54-0.16-0.53-0.14-0.53-0.11-0.52-0.09-0.51-0.07-0.49-0.04-0.48-0.01-0.98 0.05-0.83 0.14z'
|
||||
id='m'
|
||||
/>
|
||||
<path
|
||||
d='m0.97 5.8h1.84v-1.61c0-2.8 1.44-4.19 4.24-4.19 1.14 0 2.12 0.23 2.86 0.63 0.96 0.57 1.5 1.5 1.5 2.58 0 0.73-0.29 1.02-0.8 1.02-0.34 0-0.68-0.23-0.86-0.63-0.22-0.73-0.45-1.13-0.56-1.32-0.34-0.4-1.03-0.63-2.01-0.63-1.72 0-2.57 0.85-2.57 2.58v1.55h3.31c0.74 0 1.08 0.29 1.08 0.79 0 0.57-0.34 0.8-1.08 0.8h-3.31v10.48c0 0.62-0.29 0.96-0.8 0.96-0.57 0-0.8-0.34-0.8-0.96v-10.46h-2.04c-0.63 0-0.97-0.28-0.97-0.79 0-0.58 0.34-0.8 0.97-0.8z'
|
||||
id='a'
|
||||
/>
|
||||
<path
|
||||
d='m78.8 5.55 0.61 0.08 0.56 0.12 0.52 0.15 0.48 0.18 0.43 0.22 0.38 0.25 0.34 0.29 0.29 0.32 0.25 0.35 0.21 0.39 0.16 0.42 0.11 0.45 0.07 0.49 0.02 0.51v4.71l-0.02 0.52-0.07 0.48-0.11 0.46-0.15 0.42-0.2 0.38-0.24 0.35-0.29 0.32-0.33 0.29-0.38 0.25-0.42 0.22-0.47 0.19-0.51 0.15-0.55 0.11-0.6 0.09-0.64 0.05-0.68 0.02-0.72-0.01-0.68-0.04-0.63-0.08-0.58-0.11-0.53-0.15-0.48-0.18-0.43-0.22-0.39-0.25-0.34-0.29-0.3-0.32-0.25-0.36-0.21-0.38-0.15-0.43-0.11-0.46-0.07-0.49-0.02-0.53v-4.71l0.02-0.51 0.07-0.49 0.11-0.45 0.16-0.42 0.2-0.39 0.26-0.35 0.29-0.32 0.34-0.29 0.39-0.25 0.43-0.22 0.47-0.18 0.52-0.15 0.56-0.12 0.61-0.08 0.65-0.06 0.7-0.01 0.69 0.01 0.65 0.06zm-2.67 1.61-0.53 0.1-0.47 0.13-0.42 0.17-0.37 0.21-0.31 0.24-0.25 0.28-0.2 0.32-0.14 0.35-0.09 0.39-0.02 0.42v4.71l0.02 0.42 0.09 0.39 0.14 0.36 0.21 0.31 0.26 0.28 0.31 0.24 0.37 0.2 0.43 0.17 0.49 0.12 0.55 0.09 0.6 0.04h0.66 0.64l0.59-0.04 0.54-0.08 0.48-0.12 0.42-0.16 0.37-0.2 0.31-0.23 0.26-0.28 0.2-0.32 0.14-0.36 0.09-0.4 0.03-0.43v-4.71l-0.03-0.42-0.09-0.39-0.14-0.35-0.2-0.32-0.27-0.28-0.31-0.24-0.38-0.21-0.44-0.17-0.49-0.13-0.55-0.1-0.62-0.05-0.67-0.02-0.63 0.02-0.58 0.05z'
|
||||
id='i'
|
||||
/>
|
||||
<path
|
||||
d='m181.88 0.18c0.12 0.11 0.23 0.28 0.23 0.45 0 0.29-0.34 0.68-0.97 1.32-2.62 2.53-3.94 5.62-3.93 9.36 0.01 4.12 1.4 7.44 4.1 10.01 0.56 0.5 0.8 0.9 0.8 1.24 0 0.17-0.12 0.35-0.23 0.51-0.11 0.12-0.34 0.24-0.51 0.24-0.63 0-1.5-0.74-2.64-2.18-2.22-2.72-3.22-5.72-3.28-9.82-0.05-4.1 1.23-6.88 3.75-9.75 0.9-1.02 1.66-1.56 2.17-1.56 0.17 0 0.34 0.06 0.51 0.18z'
|
||||
id='f'
|
||||
/>
|
||||
<path
|
||||
d='m149.59 6.94c0.45-0.57 0.85-0.92 1.25-1.08 0.39-0.23 0.96-0.34 1.6-0.34 1.96 0 2.98 0.96 2.98 2.85v9.29c0 0.79-0.28 1.14-0.85 1.14s-0.8-0.35-0.8-1.14v-8.7c0-1.19-0.51-1.83-1.49-1.83-0.74 0-1.5 0.45-2.12 1.32v9.29c0 0.79-0.29 1.13-0.8 1.13s-0.8-0.34-0.8-1.13v-8.59c0-1.33-0.56-1.95-1.61-1.95-0.68 0-1.32 0.46-2 1.33v9.22c0 0.8-0.29 1.14-0.86 1.14s-0.79-0.34-0.79-1.14v-11.38c0-0.57 0.22-0.8 0.68-0.8 0.23 0 0.45 0.17 0.57 0.51 0.11 0.15 0.17 0.44 0.17 0.78 0.53-0.57 0.87-0.91 1.02-1.03 0.34-0.22 0.8-0.34 1.44-0.34 0.91 0 1.72 0.46 2.41 1.45z'
|
||||
id='g'
|
||||
/>
|
||||
<path
|
||||
d='m49.79 5.56 0.44 0.05 0.41 0.08 0.4 0.09 0.37 0.12 0.35 0.14 0.33 0.16 0.31 0.18 0.28 0.21 0.27 0.22 0.24 0.24 0.22 0.27 0.2 0.28 0.18 0.31 0.16 0.33 0.13 0.35 0.11 0.37 0.1 0.39 0.07 0.41 0.06 0.44 0.03 0.45 0.01 0.47v0.12l-0.01 0.11-0.01 0.1-0.03 0.2-0.02 0.09-0.03 0.09-0.02 0.08-0.08 0.15-0.03 0.06-0.1 0.12-0.05 0.05-0.06 0.05-0.05 0.03-0.07 0.04-0.07 0.03-0.14 0.04-0.08 0.01-0.09 0.01h-8.89v-0.07h-0.02v1.84l0.01 0.24 0.02 0.24 0.04 0.23 0.06 0.22 0.06 0.2 0.09 0.2 0.1 0.17 0.12 0.18 0.14 0.15 0.15 0.16 0.16 0.13 0.18 0.13 0.2 0.11 0.22 0.11 0.22 0.09 0.25 0.09 0.26 0.06 0.28 0.07 0.29 0.05 0.31 0.03 0.33 0.03 0.34 0.02 0.36 0.01h0.13l0.13-0.01h0.12l0.13-0.01h0.12l0.24-0.02 0.23-0.02 0.11-0.01 0.12-0.02 0.31-0.04 0.1-0.02 0.09-0.02 0.1-0.02 0.09-0.02 0.1-0.03 0.09-0.02 0.16-0.06 0.09-0.03 0.04-0.01 0.05-0.02 0.06-0.02 0.05-0.02 0.05-0.03 0.06-0.02 0.06-0.03 0.07-0.03 0.14-0.07 0.14-0.08 0.08-0.05 0.08-0.04 0.08-0.05 0.18-0.1 0.08-0.06 0.19-0.13 0.1-0.06 0.11-0.07 0.1-0.07 0.13-0.12 0.13-0.1 0.05-0.05 0.06-0.04 0.05-0.04 0.06-0.05 0.09-0.07 0.09-0.06 0.05-0.03 0.04-0.02 0.04-0.03 0.07-0.03 0.09-0.03 0.05-0.01h0.09l0.1 0.01 0.15 0.03 0.04 0.02 0.07 0.04 0.04 0.03 0.09 0.09 0.03 0.04 0.04 0.08 0.02 0.1 0.02 0.06v0.05l0.01 0.05v0.07l0.01 0.07-0.01 0.06v0.07l-0.01 0.06-0.01 0.07-0.07 0.2-0.03 0.06-0.06 0.14-0.09 0.14-0.05 0.06-0.11 0.14-0.12 0.13-0.14 0.14-0.16 0.14-0.08 0.06-0.08 0.08-0.15 0.1-0.15 0.11-0.32 0.2-0.17 0.09-0.18 0.09-0.18 0.08-0.19 0.07-0.2 0.08-0.2 0.07-0.21 0.06-0.22 0.06-0.44 0.1-0.47 0.09-0.5 0.06-0.52 0.04-0.55 0.02h-0.28-0.49l-0.47-0.03-0.44-0.04-0.43-0.07-0.4-0.07-0.38-0.09-0.36-0.11-0.34-0.13-0.32-0.15-0.29-0.16-0.27-0.18-0.26-0.2-0.23-0.21-0.21-0.23-0.19-0.25-0.16-0.26-0.14-0.29-0.12-0.29-0.1-0.32-0.08-0.34-0.06-0.35-0.03-0.37-0.01-0.39v-4.71l0.01-0.14 0.01-0.12 0.06-0.39 0.03-0.13 0.03-0.12 0.05-0.12 0.08-0.24 0.06-0.12 0.11-0.23 0.07-0.11 0.07-0.12 0.07-0.1 0.08-0.11 0.09-0.1 0.09-0.11 0.18-0.2 0.1-0.1 0.14-0.13 0.29-0.24 0.32-0.22 0.17-0.1 0.36-0.18 0.38-0.16 0.2-0.07 0.42-0.12 0.44-0.1 0.23-0.04 0.23-0.03 0.24-0.04 0.24-0.02 0.26-0.02 0.52-0.02h0.26l0.48 0.01 0.46 0.03zm-2.04 1.6-0.4 0.07-0.4 0.1-0.38 0.13-0.36 0.15-0.35 0.18-0.34 0.25-0.28 0.26-0.23 0.28-0.17 0.3-0.13 0.31-0.08 0.32-0.02 0.35v0.96h8.18l-0.08-0.98-0.26-0.83-0.42-0.69-0.6-0.53-0.77-0.38-0.94-0.23-1.11-0.07-0.44 0.01-0.42 0.04z'
|
||||
id='h'
|
||||
/>
|
||||
<path
|
||||
d='m67.34 1.76c1.14 0.86 1.73 2.07 1.73 3.55 0 0.68-0.29 1.02-0.86 1.02-0.4 0-0.68-0.34-0.85-1.02-0.12-0.57-0.34-1.08-0.62-1.62-0.52-0.9-1.61-1.32-3.32-1.32-1.5 0-2.52 0.34-3.14 1.08-0.57 0.68-0.92 1.72-0.92 3.26v5.95c0 1.55 0.35 2.63 0.97 3.31 0.68 0.74 1.73 1.13 3.21 1.13 2.23 0 3.54-0.79 3.82-2.34 0.11-0.57 0.17-0.86 0.17-0.91 0.11-0.34 0.34-0.51 0.68-0.51 0.57 0 0.86 0.34 0.86 1.02 0 1.44-0.58 2.52-1.79 3.38-0.96 0.62-2.18 0.96-3.77 0.96-1.83 0-3.25-0.4-4.3-1.25-1.21-0.8-1.72-2.16-1.72-3.94v-7.16c0-3.77 1.93-5.61 5.95-5.61 1.61 0 2.86 0.34 3.9 1.02z'
|
||||
id='o'
|
||||
/>
|
||||
<path
|
||||
d='m158.79 5.43 0.12 0.04 0.03 0.02 0.03 0.01 0.03 0.03 0.06 0.04 0.03 0.03 0.03 0.02 0.1 0.14 0.06 0.08 0.02 0.05 0.02 0.04 0.01 0.04 0.02 0.09 0.01 0.04 0.02 0.04 0.01 0.05 0.01 0.04 0.02 0.04 0.01 0.05 0.05 0.12 0.02 0.05 0.03 0.08 0.01 0.05 0.03 0.12 0.02 0.04 0.02 0.08 0.25-0.12 0.49-0.23 0.24-0.11 0.23-0.1 0.46-0.18 0.22-0.08 0.21-0.08 0.21-0.07 0.2-0.06 0.2-0.07 0.2-0.05 0.38-0.09 0.19-0.04 0.34-0.06 0.17-0.02 0.32-0.02h0.16l0.46 0.01 0.44 0.03 0.43 0.04 0.39 0.06 0.38 0.09 0.36 0.1 0.33 0.12 0.31 0.14 0.29 0.15 0.27 0.17 0.25 0.2 0.22 0.2 0.21 0.23 0.18 0.24 0.16 0.26 0.14 0.28 0.12 0.3 0.09 0.31 0.08 0.33 0.06 0.35 0.03 0.36 0.01 0.38v4.76l-0.01 0.19-0.01 0.18-0.01 0.17-0.03 0.18-0.02 0.17-0.08 0.32-0.05 0.16-0.05 0.15-0.12 0.3-0.08 0.14-0.07 0.14-0.09 0.14-0.09 0.13-0.09 0.12-0.1 0.13-0.11 0.12-0.12 0.12-0.11 0.12-0.26 0.22-0.24 0.18-0.26 0.16-0.14 0.07-0.13 0.07-0.15 0.07-0.15 0.06-0.15 0.05-0.32 0.11-0.33 0.08-0.17 0.04-0.36 0.06-0.36 0.04-0.19 0.02-0.2 0.01h-0.19-0.44l-0.24-0.01-0.24-0.02-0.23-0.01-0.46-0.06-0.22-0.04-0.44-0.09-0.21-0.06-0.21-0.05-0.21-0.07-0.21-0.08-0.4-0.16-0.2-0.1-0.19-0.1-0.2-0.1-0.19-0.11-0.19-0.12-0.36-0.26v5.49l-0.02 0.2-0.01 0.09-0.02 0.09-0.06 0.24-0.03 0.07-0.04 0.07-0.03 0.05-0.04 0.06-0.08 0.1-0.1 0.08-0.06 0.02-0.05 0.03-0.06 0.02-0.06 0.01-0.07 0.01h-0.14-0.06l-0.07-0.02-0.05-0.02-0.06-0.02-0.11-0.06-0.04-0.04-0.05-0.04-0.08-0.1-0.04-0.06-0.03-0.06-0.02-0.07-0.03-0.08-0.04-0.16-0.02-0.1-0.01-0.09-0.01-0.11v-0.1-16.31-0.1l0.01-0.09 0.01-0.1 0.01-0.09 0.01-0.08 0.02-0.08 0.03-0.07 0.02-0.08 0.05-0.12 0.04-0.06 0.03-0.05 0.04-0.05 0.04-0.03 0.05-0.04 0.04-0.03 0.05-0.03 0.11-0.03 0.06-0.01h0.09l0.03 0.01h0.03zm4.49 1.74-0.46 0.04-0.22 0.03-0.21 0.03-0.21 0.05-0.38 0.1-0.36 0.14-0.15 0.07-0.16 0.08-0.15 0.1-0.17 0.11-0.16 0.12-0.17 0.14-0.17 0.15-0.18 0.16-0.18 0.18-0.2 0.19-0.2 0.2v6.54h0.06v-0.03l0.47 0.28 0.45 0.25 0.45 0.24 0.42 0.19 0.41 0.18 0.4 0.14 0.38 0.12 0.36 0.09 0.35 0.07 0.34 0.04 0.32 0.02 0.28-0.01 0.27-0.01 0.26-0.03 0.24-0.03 0.25-0.04 0.23-0.05 0.22-0.06 0.21-0.07 0.2-0.08 0.19-0.09 0.17-0.1 0.21-0.13 0.18-0.15 0.17-0.15 0.14-0.16 0.12-0.17 0.1-0.19 0.08-0.19 0.06-0.2 0.05-0.22 0.02-0.22 0.01-0.23v-4.75l-0.01-0.28-0.03-0.26-0.05-0.23-0.07-0.23-0.09-0.21-0.11-0.2-0.14-0.18-0.15-0.17-0.18-0.15-0.2-0.15-0.22-0.12-0.18-0.09-0.19-0.09-0.2-0.06-0.21-0.07-0.22-0.05-0.24-0.05-0.24-0.04-0.26-0.03-0.27-0.02-0.28-0.01-0.29-0.01-0.25 0.01h-0.26z'
|
||||
id='d'
|
||||
/>
|
||||
</defs>
|
||||
<use fill='#ffffff' xlinkHref='#k' />
|
||||
<use fillOpacity={0} stroke='#000000' strokeOpacity={0} xlinkHref='#k' />
|
||||
<use fill='#ffffff' xlinkHref='#j' />
|
||||
<use fillOpacity={0} stroke='#000000' strokeOpacity={0} xlinkHref='#j' />
|
||||
<use fill='#ffffff' xlinkHref='#b' />
|
||||
<use fillOpacity={0} stroke='#000000' strokeOpacity={0} xlinkHref='#b' />
|
||||
<use fill='#ffffff' xlinkHref='#n' />
|
||||
<use fillOpacity={0} stroke='#000000' strokeOpacity={0} xlinkHref='#n' />
|
||||
<use fill='#ffffff' xlinkHref='#l' />
|
||||
<use fillOpacity={0} stroke='#000000' strokeOpacity={0} xlinkHref='#l' />
|
||||
<use fill='#ffffff' xlinkHref='#c' />
|
||||
<use fillOpacity={0} stroke='#000000' strokeOpacity={0} xlinkHref='#c' />
|
||||
<use fill='#ffffff' xlinkHref='#e' />
|
||||
<use fillOpacity={0} stroke='#000000' strokeOpacity={0} xlinkHref='#e' />
|
||||
<use fill='#ffffff' xlinkHref='#m' />
|
||||
<use fillOpacity={0} stroke='#000000' strokeOpacity={0} xlinkHref='#m' />
|
||||
<use fill='#ffffff' xlinkHref='#a' />
|
||||
<use fillOpacity={0} stroke='#000000' strokeOpacity={0} xlinkHref='#a' />
|
||||
<use fill='#ffffff' xlinkHref='#i' />
|
||||
<use fillOpacity={0} stroke='#000000' strokeOpacity={0} xlinkHref='#i' />
|
||||
<use fill='#ffffff' xlinkHref='#f' />
|
||||
<use fillOpacity={0} stroke='#000000' strokeOpacity={0} xlinkHref='#f' />
|
||||
<use fill='#ffffff' xlinkHref='#g' />
|
||||
<use fillOpacity={0} stroke='#000000' strokeOpacity={0} xlinkHref='#g' />
|
||||
<use fill='#ffffff' xlinkHref='#h' />
|
||||
<use fillOpacity={0} stroke='#000000' strokeOpacity={0} xlinkHref='#h' />
|
||||
<use fill='#ffffff' xlinkHref='#o' />
|
||||
<use fillOpacity={0} stroke='#000000' strokeOpacity={0} xlinkHref='#o' />
|
||||
<use fill='#ffffff' xlinkHref='#d' />
|
||||
<use fillOpacity={0} stroke='#000000' strokeOpacity={0} xlinkHref='#d' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
FreeCodeCampLogo.displayName = 'FreeCodeCampLogo';
|
||||
|
||||
export default FreeCodeCampLogo;
|
||||
@@ -0,0 +1,15 @@
|
||||
import React from 'react';
|
||||
|
||||
function FreeCodeCampIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 576 512' {...props}>
|
||||
<path d='M97.2 96.2c10.4-10.7 16-17.1 16-21.9 0-2.8-1.9-5.5-3.8-7.4A14.8 14.8 0 0 0 101 64.1c-8.5 0-20.9 8.8-35.8 25.7C23.7 137 2.5 182.8 3.4 250.3s17.5 117 54.1 161.9C76.2 435.9 90.6 448 100.9 448a13.6 13.6 0 0 0 8.4-3.8c1.9-2.8 3.8-5.6 3.8-8.4 0-5.6-3.9-12.2-13.2-20.6-44.5-42.3-67.3-97-67.5-165C32.3 188.8 54 137.8 97.2 96.2zM239.5 420.1c.6 .4 .9 .6 .9 .6zm93.8 .6 .2-.1C333.2 420.6 333.2 420.7 333.3 420.6zm3.1-158.2c-16.2-4.2 50.4-82.9-68.1-177.2 0 0 15.5 49.4-62.8 159.6-74.3 104.4 23.5 168.7 34 175.2-6.7-4.4-47.4-35.7 9.6-128.6 11-18.3 25.5-34.9 43.5-72.2 0 0 15.9 22.5 7.6 71.1C287.7 364 354 342.9 355 343.9c22.8 26.8-17.7 73.5-21.6 76.6 5.5-3.7 117.7-78 33-188.1C360.4 238.4 352.6 266.6 336.4 262.4zM510.9 89.7C496 72.8 483.5 64 475 64a14.8 14.8 0 0 0 -8.4 2.8c-1.9 1.9-3.8 4.7-3.8 7.4 0 4.8 5.6 11.3 16 21.9 43.2 41.6 65 92.6 64.8 154.1-.2 68-23 122.6-67.5 165-9.3 8.4-13.2 14.9-13.2 20.6 0 2.8 1.9 5.6 3.8 8.4A13.6 13.6 0 0 0 475.1 448c10.3 0 24.7-12.1 43.5-35.8 36.6-44.9 53.1-94.4 54.1-161.9S552.3 137 510.9 89.7z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
FreeCodeCampIcon.displayName = 'FreeCodeCampIcon';
|
||||
|
||||
export default FreeCodeCampIcon;
|
||||
@@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
|
||||
function Graduation(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
height='60'
|
||||
width='60'
|
||||
version='1.1'
|
||||
viewBox='0 0 245.827 245.827'
|
||||
{...props}
|
||||
>
|
||||
<path d='M223.336,148.384l-0.137-23.527l22.628-12.662L122.576,47.195L0,113.495l49.144,28.216 l0.098,16.766l0.01,1.339l0.449-0.215c-0.518,0.703-0.85,1.426-0.84,2.149c0.039,8.246,33.326,14.772,74.41,14.548 c41.064-0.215,74.302-7.122,74.273-15.349c0-0.723-0.381-1.426-0.889-2.149l0.449,0.215v-1.339l-0.088-16.834l21.309-13.258 l0.117,20.83c-2.345,1.006-3.976,3.312-3.957,6.009c0.02,3.537,2.892,6.399,6.458,6.37c3.586-0.02,6.429-2.912,6.409-6.439 C227.332,151.657,225.691,149.371,223.336,148.384z M123.241,170.621c-36.452,0.205-66.017-3.801-66.046-8.91 c-0.029-5.11,29.496-9.399,65.949-9.585c36.462-0.205,66.017,3.781,66.037,8.881 C189.209,166.098,159.703,170.426,123.241,170.621z M195.335,127.183c-4.934-5.188-22.618-18.886-72.426-18.602 c-49.877,0.264-67.336,14.128-72.211,19.394l-0.029-4.963c0,0,14.147-21.524,72.202-21.827 c58.025-0.313,72.436,21.045,72.436,21.045L195.335,127.183z M215.755,162.199l-2.511,36.433 c7.767-12.203,14.255-7.66,14.255-7.66l-0.156-28.832C218.998,165.414,215.755,162.199,215.755,162.199z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Graduation.displayName = 'Graduation';
|
||||
|
||||
export default Graduation;
|
||||
@@ -0,0 +1,45 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
interface GreenNotCompletedProps
|
||||
extends JSX.IntrinsicAttributes, React.SVGProps<SVGSVGElement> {
|
||||
hushScreenReaderText?: boolean;
|
||||
}
|
||||
|
||||
function GreenNotCompleted(props: GreenNotCompletedProps): JSX.Element {
|
||||
const { t } = useTranslation();
|
||||
const { hushScreenReaderText = false, ...rest } = props;
|
||||
return (
|
||||
<>
|
||||
{!hushScreenReaderText && (
|
||||
<span className='sr-only'>{t('icons.not-passed')}</span>
|
||||
)}
|
||||
<svg
|
||||
data-testid='green-not-completed'
|
||||
aria-hidden='true'
|
||||
height='15'
|
||||
viewBox='0 0 200 200'
|
||||
width='15'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...rest}
|
||||
>
|
||||
<g>
|
||||
<title>{t('icons.not-passed')}</title>
|
||||
<circle
|
||||
cx='100'
|
||||
cy='99'
|
||||
fill='var(--primary-background)'
|
||||
r='95'
|
||||
stroke='var(--primary-color)'
|
||||
strokeDasharray='null'
|
||||
strokeWidth='10'
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
GreenNotCompleted.displayName = 'GreenNotCompleted';
|
||||
|
||||
export default GreenNotCompleted;
|
||||
@@ -0,0 +1,59 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
interface GreenPassProps
|
||||
extends JSX.IntrinsicAttributes, React.SVGProps<SVGSVGElement> {
|
||||
hushScreenReaderText?: boolean;
|
||||
}
|
||||
function GreenPass(props: GreenPassProps): JSX.Element {
|
||||
const { t } = useTranslation();
|
||||
const { hushScreenReaderText = false, ...rest } = props;
|
||||
return (
|
||||
<svg
|
||||
data-testid='green-pass'
|
||||
{...(hushScreenReaderText && { 'aria-hidden': true })}
|
||||
{...(!hushScreenReaderText && { 'aria-label': t('icons.passed') })}
|
||||
height='15'
|
||||
viewBox='0 0 200 200'
|
||||
width='15'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...rest}
|
||||
>
|
||||
<g aria-hidden='true'>
|
||||
<title>{t('icons.passed')}</title>
|
||||
<circle
|
||||
cx='100'
|
||||
cy='99'
|
||||
fill='var(--primary-color)'
|
||||
r='95'
|
||||
stroke='var(--primary-color)'
|
||||
strokeDasharray='null'
|
||||
/>
|
||||
<rect
|
||||
fill='var(--primary-background)'
|
||||
height='30'
|
||||
stroke='var(--primary-background)'
|
||||
strokeDasharray='null'
|
||||
transform='rotate(-45, 120, 106.321)'
|
||||
width='128.85878'
|
||||
x='55.57059'
|
||||
y='91.32089'
|
||||
/>
|
||||
<rect
|
||||
fill='var(--primary-background)'
|
||||
height='30'
|
||||
stroke='var(--primary-background)'
|
||||
strokeDasharray='null'
|
||||
transform='rotate(45, 66.75, 123.75)'
|
||||
width='80.66548'
|
||||
x='26.41726'
|
||||
y='108.75'
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
GreenPass.displayName = 'GreenPass';
|
||||
|
||||
export default GreenPass;
|
||||
@@ -0,0 +1,26 @@
|
||||
import React from 'react';
|
||||
|
||||
function Help(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
viewBox='0 0 512 512'
|
||||
width='1.25rem'
|
||||
height='1.3rem'
|
||||
fill='currentColor'
|
||||
aria-hidden='true'
|
||||
{...props}
|
||||
>
|
||||
<path d='M160 368c26.5 0 48 21.5 48 48v16l72.5-54.4c8.3-6.2 18.4-9.6 28.8-9.6H448c8.8 0 16-7.2 16-16V64c0-8.8-7.2-16-16-16H64c-8.8 0-16 7.2-16 16V352c0 8.8 7.2 16 16 16h96zm48 124l-.2.2-5.1 3.8-17.1 12.8c-4.8 3.6-11.3 4.2-16.8 1.5s-8.8-8.2-8.8-14.3V474.7v-6.4V468v-4V416H64c-35.3 0-64-28.7-64-64V64C0 28.7 28.7 0 64 0H448c35.3 0 64 28.7 64 64V352c0 35.3-28.7 64-64 64H309.3L208 492z' />
|
||||
<g transform='translate(168 52) scale(.55)'>
|
||||
<path d='M64 160c0-35.3 28.7-64 64-64h32c35.3 0 64 28.7 64 64v3.6c0 21.8-11.1 42.1-29.4 53.8l-42.2 27.1c-25.2 16.2-40.4 44.1-40.4 74V320c0 17.7 14.3 32 32 32s32-14.3 32-32v-1.4c0-8.2 4.2-15.8 11-20.2l42.2-27.1c36.6-23.6 58.8-64.1 58.8-107.7V160c0-70.7-57.3-128-128-128H128C57.3 32 0 89.3 0 160c0 17.7 14.3 32 32 32s32-14.3 32-32zm80 320a40 40 0 1 0 0-80 40 40 0 1 0 0 80z' />
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Help.displayName = 'Help';
|
||||
|
||||
export default Help;
|
||||
@@ -0,0 +1,15 @@
|
||||
import React from 'react';
|
||||
|
||||
function Html(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 384 512' {...props}>
|
||||
<path d='M0 32l34.9 395.8L191.5 480l157.6-52.2L384 32H0zm308.2 127.9H124.4l4.1 49.4h175.6l-13.6 148.4-97.9 27v.3h-1.1l-98.7-27.3-6-75.8h47.7L138 320l53.5 14.5 53.7-14.5 6-62.2H84.3L71.5 112.2h241.1l-4.4 47.7z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Html.displayName = 'Html';
|
||||
|
||||
export default Html;
|
||||
@@ -0,0 +1,58 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
function Initial(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<svg
|
||||
height='50'
|
||||
viewBox='0 0 200 200'
|
||||
width='50'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<g>
|
||||
<title>{t('icons.initial')}</title>
|
||||
<circle
|
||||
cx='100'
|
||||
cy='99'
|
||||
fill='var(--primary-color)'
|
||||
r='95'
|
||||
stroke='var(--primary-color)'
|
||||
strokeDasharray='null'
|
||||
/>
|
||||
<svg
|
||||
height='200'
|
||||
viewBox='-13 -12 50 50'
|
||||
width='200'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<path
|
||||
d={
|
||||
'M8 1c0-.552.448-1 1-1h6c.553 0 1 .448 1 1s-.447 1-1 1h-6c-' +
|
||||
'.552 0-1-.448-1-1zm13 20.554c0 1.284-1.023 2.446-2.424 ' +
|
||||
'2.446h-13.153c-1.4 0-2.423-1.162-2.423-2.445 0-.35.076-.709.' +
|
||||
'242-1.057l3.743-7.856c1.04-2.186 2.015-4.581 2.015-7.007v-1.' +
|
||||
'635h2l-.006 2c-.087 2.623-1.09 5.092-1.973 7h3.682l4.377 9h1.' +
|
||||
'496c.309 0 .52-.342.377-.644l-3.743-7.854c-1.046-2.197-2.12-4' +
|
||||
'.791-2.21-7.502v-2h2v1.635c0 2.426.975 4.82 2.016 7.006l3.743' +
|
||||
' 7.856c.165.348.241.707.241 1.057zm-12-1.054c0-.829-.671-1.5-' +
|
||||
'1.5-1.5s-1.5.671-1.5 1.5.671 1.5 1.5 1.5 1.5-.671 1.5-1.5zm2-' +
|
||||
'3.5c0-.553-.448-1-1-1-.553 0-1 .447-1 1s.447 1 1 1c.552 0 1-.' +
|
||||
'447 1-1zm3 3c0-.552-.448-1-1-1s-1 .448-1 1 .448 1 1 1 1-.448 ' +
|
||||
'1-1z'
|
||||
}
|
||||
fill='var(--primary-background)'
|
||||
/>
|
||||
</svg>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Initial.displayName = 'Initial';
|
||||
|
||||
export default Initial;
|
||||
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const InputReset = (): JSX.Element => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<>
|
||||
<span className='sr-only'>{t('icons.input-reset')}</span>
|
||||
<svg
|
||||
className='ais-SearchBox-resetIcon'
|
||||
height='10'
|
||||
viewBox='0 0 20 20'
|
||||
width='10'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<path d='M8.114 10L.944 2.83 0 1.885 1.886 0l.943.943L10 8.113l7.17-7.17.944-.943L20 1.886l-.943.943-7.17 7.17 7.17 7.17.943.944L18.114 20l-.943-.943-7.17-7.17-7.17 7.17-.944.943L0 18.114l.943-.943L8.113 10z'></path>
|
||||
</svg>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
InputReset.displayName = 'InputReset';
|
||||
export default InputReset;
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
function JavaScriptIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 448 512'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path d='M0 32v448h448V32H0zm243.8 349.4c0 43.6-25.6 63.5-62.9 63.5-33.7 0-53.2-17.4-63.2-38.5l34.3-20.7c6.6 11.7 12.6 21.6 27.1 21.6 13.8 0 22.6-5.4 22.6-26.5V237.7h42.1v143.7zm99.6 63.5c-39.1 0-64.4-18.6-76.7-43l34.3-19.8c9 14.7 20.8 25.6 41.5 25.6 17.4 0 28.6-8.7 28.6-20.8 0-14.4-11.4-19.5-30.7-28l-10.5-4.5c-30.4-12.9-50.5-29.2-50.5-63.5 0-31.6 24.1-55.6 61.6-55.6 26.8 0 46 9.3 59.8 33.7L368 290c-7.2-12.9-15-18-27.1-18-12.3 0-20.1 7.8-20.1 18 0 12.6 7.8 17.7 25.9 25.6l10.5 4.5c35.8 15.3 55.9 31 55.9 66.2 0 37.8-29.8 58.6-69.7 58.6z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
JavaScriptIcon.displayName = 'JavaScriptIcon';
|
||||
|
||||
export default JavaScriptIcon;
|
||||
@@ -0,0 +1,56 @@
|
||||
import React from 'react';
|
||||
|
||||
function LanguageGlobe(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden={true}
|
||||
height={24}
|
||||
viewBox='0 0 24 24'
|
||||
width={24}
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d='M2 12C2 17.5228 6.47715 22 12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12Z'
|
||||
stroke='currentColor'
|
||||
strokeWidth='1.5'
|
||||
strokeLinecap='round'
|
||||
strokeLinejoin='round'
|
||||
/>
|
||||
<path
|
||||
d='M13 2.04932C13 2.04932 16 5.99994 16 11.9999C16 17.9999 13 21.9506 13 21.9506'
|
||||
stroke='currentColor'
|
||||
strokeWidth='1.5'
|
||||
strokeLinecap='round'
|
||||
strokeLinejoin='round'
|
||||
/>
|
||||
<path
|
||||
d='M11 21.9506C11 21.9506 8 17.9999 8 11.9999C8 5.99994 11 2.04932 11 2.04932'
|
||||
stroke='currentColor'
|
||||
strokeWidth='1.5'
|
||||
strokeLinecap='round'
|
||||
strokeLinejoin='round'
|
||||
/>
|
||||
<path
|
||||
d='M2.62964 15.5H21.3704'
|
||||
stroke='currentColor'
|
||||
strokeWidth='1.5'
|
||||
strokeLinecap='round'
|
||||
strokeLinejoin='round'
|
||||
/>
|
||||
<path
|
||||
d='M2.62964 8.5H21.3704'
|
||||
stroke='currentColor'
|
||||
strokeWidth='1.5'
|
||||
strokeLinecap='round'
|
||||
strokeLinejoin='round'
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
LanguageGlobe.displayName = 'LanguageGlobe';
|
||||
|
||||
export default LanguageGlobe;
|
||||
@@ -0,0 +1,42 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
function LightBulb(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<svg
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
width='50'
|
||||
height='50'
|
||||
viewBox='0 0 50 50'
|
||||
fill='none'
|
||||
{...props}
|
||||
>
|
||||
<g aria-hidden='true'>
|
||||
<title>{t('icons.hint')}</title>
|
||||
|
||||
<path
|
||||
d='M25 48.5C38.1168 48.5 48.75 37.8668 48.75 24.75C48.75 11.6332 38.1168 1 25 1C11.8832 1 1.25 11.6332 1.25 24.75C1.25 37.8668 11.8832 48.5 25 48.5Z'
|
||||
fill='var(--primary-color)'
|
||||
stroke='var(--primary-color)'
|
||||
strokeWidth='0.25'
|
||||
/>
|
||||
<path
|
||||
d='M31.3494 27.9901C33.0751 26.3241 35 24.4657 35 19.5C35 14 30.2467 10 25 10C19.7533 10 15 14 15 19.5C15 24.5098 16.6928 26.3561 18.2307 28.0335C19.4555 29.3695 20.0464 30.4781 20.1412 33.1128C23.0869 33.1553 26.0383 33.1713 28.9835 33.1128C28.9835 30.45 29.9475 29.3436 31.3494 27.9901Z'
|
||||
fill='var(--primary-background)'
|
||||
/>
|
||||
<path
|
||||
d='M20.1247 35.2025H28.9835C28.9835 35.2025 28.7011 38.7811 28.4835 39.2025C28.1437 39.8603 26.9835 41.7025 24.5404 41.7025C21.4835 41.7025 20.8417 39.8603 20.4835 39.2025C20.254 38.7811 20.1247 35.2025 20.1247 35.2025Z'
|
||||
fill='var(--primary-background)'
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
LightBulb.displayName = 'LightBulb';
|
||||
|
||||
export default LightBulb;
|
||||
@@ -0,0 +1,36 @@
|
||||
import React from 'react';
|
||||
|
||||
export default function LinkButton(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
height='20px'
|
||||
version='1.1'
|
||||
viewBox='0 0 16 20'
|
||||
width='18px'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
xmlnsXlink='http://www.w3.org/1999/xlink'
|
||||
{...props}
|
||||
fill='inherit'
|
||||
>
|
||||
<g>
|
||||
<polygon
|
||||
points={
|
||||
'-2.68014473e-15 -1.06357708e-13 2.01917516 ' +
|
||||
'-1.06357708e-13 8.99824941 9.00746464 2.01917516 ' +
|
||||
'18.0149293 -2.66453526e-15 18.0149293 7.00955027 9'
|
||||
}
|
||||
/>
|
||||
<polygon
|
||||
points={
|
||||
'7.99971435 -1.06357708e-13 10.0188895 ' +
|
||||
'-1.06357708e-13 16.9979638 9.00746464 ' +
|
||||
'10.0188895 18.0149293 7.99971435 18.0149293 15.0092646 9'
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import React from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
const Magnifier = (): JSX.Element => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<>
|
||||
<span className='sr-only'>{t('icons.magnifier')}</span>
|
||||
<svg
|
||||
className='ais-SearchBox-submitIcon'
|
||||
height='10'
|
||||
viewBox='0 0 40 40'
|
||||
width='10'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
>
|
||||
<path d='M26.804 29.01c-2.832 2.34-6.465 3.746-10.426 3.746C7.333 32.756 0 25.424 0 16.378 0 7.333 7.333 0 16.378 0c9.046 0 16.378 7.333 16.378 16.378 0 3.96-1.406 7.594-3.746 10.426l10.534 10.534c.607.607.61 1.59-.004 2.202-.61.61-1.597.61-2.202.004L26.804 29.01zm-10.426.627c7.323 0 13.26-5.936 13.26-13.26 0-7.32-5.937-13.257-13.26-13.257C9.056 3.12 3.12 9.056 3.12 16.378c0 7.323 5.936 13.26 13.258 13.26z' />
|
||||
</svg>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
Magnifier.displayName = 'Magnifier';
|
||||
export default Magnifier;
|
||||
@@ -0,0 +1,26 @@
|
||||
import React from 'react';
|
||||
|
||||
function MicrosoftLogo(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
version='1.1'
|
||||
viewBox='0 0 610 130'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill='#FFF'
|
||||
d='M213.2 74.3l-3.6 10.2h-.3c-.6-2.3-1.7-5.8-3.5-10L186.5 26h-18.9v77.3h12.5V55.6c0-3 0-6.4-.1-10.6-.1-2.1-.3-3.7-.4-4.9h.3c.6 3 1.3 5.2 1.8 6.6l23.2 56.4h8.8l23-56.9c.5-1.3 1-3.9 1.5-6.1h.3c-.3 5.7-.5 10.8-.6 13.9v49h13.3V25.8H233zm50.6-26.7h13V103h-13zm6.6-23.4c-2.2 0-4 .8-5.5 2.2-1.5 1.4-2.3 3.2-2.3 5.4 0 2.1.8 3.9 2.3 5.3 1.5 1.4 3.3 2.1 5.5 2.1s4.1-.8 5.5-2.1c1.5-1.4 2.3-3.2 2.3-5.3 0-2.1-.8-3.9-2.3-5.4-1.3-1.4-3.2-2.2-5.5-2.2m52.5 22.9c-2.4-.5-4.9-.8-7.3-.8-5.9 0-11.3 1.3-15.8 3.9-4.5 2.6-8.1 6.2-10.4 10.7-2.4 4.6-3.6 9.9-3.6 16 0 5.3 1.2 10 3.5 14.3 2.3 4.2 5.5 7.6 9.8 9.9 4.1 2.3 8.9 3.5 14.3 3.5 6.2 0 11.5-1.3 15.7-3.7l.1-.1v-12l-.5.4c-1.9 1.4-4.1 2.6-6.3 3.3-2.3.8-4.4 1.2-6.2 1.2-5.2 0-9.3-1.5-12.2-4.8-3-3.2-4.5-7.6-4.5-13.1 0-5.7 1.5-10.2 4.6-13.5 3.1-3.3 7.2-5 12.2-5 4.2 0 8.5 1.4 12.4 4.2l.5.4V49.2l-.1-.1c-1.7-.7-3.6-1.5-6.2-2m42.9-.4c-3.2 0-6.2 1-8.8 3.1-2.2 1.8-3.7 4.4-5 7.5h-.1v-9.7h-13V103h13V74.7c0-4.8 1-8.8 3.2-11.7 2.2-3 5-4.5 8.4-4.5 1.2 0 2.4.3 3.9.5 1.4.4 2.4.8 3.1 1.3l.5.4v-13l-.3-.1c-.9-.6-2.7-.9-4.9-.9m35.4-.3c-9.1 0-16.4 2.7-21.5 8-5.2 5.3-7.7 12.6-7.7 21.8 0 8.6 2.6 15.6 7.6 20.7 5 5 11.8 7.6 20.3 7.6 8.9 0 16-2.7 21.1-8.1 5.2-5.4 7.7-12.6 7.7-21.5 0-8.8-2.4-15.8-7.3-20.9-4.7-5.1-11.6-7.6-20.2-7.6M411.6 89c-2.4 3.1-6.2 4.6-10.9 4.6s-8.5-1.5-11.2-4.8c-2.7-3.1-4-7.6-4-13.3 0-5.9 1.4-10.4 4-13.6 2.7-3.2 6.4-4.8 11.1-4.8 4.6 0 8.2 1.5 10.8 4.6 2.6 3.1 4 7.6 4 13.5-.2 6-1.3 10.7-3.8 13.8m46.1-18.4c-4.1-1.7-6.7-3-7.9-4.1-1-1-1.5-2.4-1.5-4.2 0-1.5.6-3 2.1-4s3.2-1.5 5.7-1.5c2.2 0 4.5.4 6.7 1s4.2 1.5 5.8 2.7l.5.4V48.7l-.3-.1c-1.5-.6-3.5-1.2-5.9-1.7-2.4-.4-4.6-.6-6.4-.6-6.2 0-11.3 1.5-15.3 4.8-4 3.1-5.9 7.3-5.9 12.2 0 2.6.4 4.9 1.3 6.8.9 1.9 2.2 3.7 4 5.2 1.8 1.4 4.4 3 8 4.5 3 1.3 5.3 2.3 6.7 3.1 1.4.8 2.3 1.7 3 2.4.5.8.8 1.8.8 3.1 0 3.7-2.8 5.5-8.5 5.5-2.2 0-4.5-.4-7.2-1.3s-5.2-2.2-7.3-3.7l-.5-.4v12.7l.3.1c1.9.9 4.2 1.5 7 2.2 2.8.5 5.3.9 7.5.9 6.7 0 12.2-1.5 16.1-4.8 4-3.2 6.1-7.3 6.1-12.6 0-3.7-1-7-3.2-9.5-2.9-2.4-6.5-4.9-11.7-6.9m49.2-24.2c-9.1 0-16.4 2.7-21.5 8-5.1 5.3-7.7 12.6-7.7 21.8 0 8.6 2.6 15.6 7.6 20.7 5 5 11.8 7.6 20.3 7.6 8.9 0 16-2.7 21.1-8.1 5.2-5.4 7.7-12.6 7.7-21.5 0-8.8-2.4-15.8-7.3-20.9-4.7-5.1-11.6-7.6-20.2-7.6M517.2 89c-2.4 3.1-6.2 4.6-10.9 4.6-4.8 0-8.5-1.5-11.2-4.8-2.7-3.1-4-7.6-4-13.3 0-5.9 1.4-10.4 4-13.6 2.7-3.2 6.4-4.8 11.1-4.8 4.5 0 8.2 1.5 10.8 4.6 2.6 3.1 4 7.6 4 13.5 0 6-1.3 10.7-3.8 13.8m86.7-30.7V47.6h-13.1V31.2l-.4.1L578 35l-.3.1v12.5h-19.6v-7c0-3.2.8-5.7 2.2-7.3 1.4-1.6 3.5-2.4 6.1-2.4 1.8 0 3.7.4 5.8 1.3l.5.3V21.2l-.3-.1c-1.8-.6-4.2-1-7.3-1-3.9 0-7.3.9-10.4 2.4-3.1 1.7-5.4 4-7.1 7.1-1.7 3-2.6 6.4-2.6 10.3v7.7h-9.1v10.6h9.1V103h13.1V58.3h19.6v28.5c0 11.7 5.5 17.6 16.5 17.6 1.8 0 3.7-.3 5.5-.6 1.9-.4 3.3-.9 4.1-1.3l.1-.1V91.7l-.5.4c-.8.5-1.5.9-2.7 1.2-1 .3-1.9.4-2.6.4-2.6 0-4.4-.6-5.7-2.1-1.2-1.4-1.8-3.7-1.8-7.1V58.3z'
|
||||
/>
|
||||
<path d='M0 0h61.3v61.3H0z' fill='#F25022' />
|
||||
<path d='M67.7 0H129v61.3H67.7z' fill='#7FBA00' />
|
||||
<path d='M0 67.7h61.3V129H0z' fill='#00A4EF' />
|
||||
<path d='M67.7 67.7H129V129H67.7z' fill='#FFB900' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
MicrosoftLogo.displayName = 'MicrosoftLogo';
|
||||
export default MicrosoftLogo;
|
||||
@@ -0,0 +1,15 @@
|
||||
import React from 'react';
|
||||
|
||||
function NodeIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 448 512' {...props}>
|
||||
<path d='M224 508c-6.7 0-13.5-1.8-19.4-5.2l-61.7-36.5c-9.2-5.2-4.7-7-1.7-8 12.3-4.3 14.8-5.2 27.9-12.7 1.4-.8 3.2-.5 4.6 .4l47.4 28.1c1.7 1 4.1 1 5.7 0l184.7-106.6c1.7-1 2.8-3 2.8-5V149.3c0-2.1-1.1-4-2.9-5.1L226.8 37.7c-1.7-1-4-1-5.7 0L36.6 144.3c-1.8 1-2.9 3-2.9 5.1v213.1c0 2 1.1 4 2.9 4.9l50.6 29.2c27.5 13.7 44.3-2.4 44.3-18.7V167.5c0-3 2.4-5.3 5.4-5.3h23.4c2.9 0 5.4 2.3 5.4 5.3V378c0 36.6-20 57.6-54.7 57.6-10.7 0-19.1 0-42.5-11.6l-48.4-27.9C8.1 389.2 .7 376.3 .7 362.4V149.3c0-13.8 7.4-26.8 19.4-33.7L204.6 9c11.7-6.6 27.2-6.6 38.8 0l184.7 106.7c12 6.9 19.4 19.8 19.4 33.7v213.1c0 13.8-7.4 26.7-19.4 33.7L243.4 502.8c-5.9 3.4-12.6 5.2-19.4 5.2zm149.1-210.1c0-39.9-27-50.5-83.7-58-57.4-7.6-63.2-11.5-63.2-24.9 0-11.1 4.9-25.9 47.4-25.9 37.9 0 51.9 8.2 57.7 33.8 .5 2.4 2.7 4.2 5.2 4.2h24c1.5 0 2.9-.6 3.9-1.7s1.5-2.6 1.4-4.1c-3.7-44.1-33-64.6-92.2-64.6-52.7 0-84.1 22.2-84.1 59.5 0 40.4 31.3 51.6 81.8 56.6 60.5 5.9 65.2 14.8 65.2 26.7 0 20.6-16.6 29.4-55.5 29.4-48.9 0-59.6-12.3-63.2-36.6-.4-2.6-2.6-4.5-5.3-4.5h-23.9c-3 0-5.3 2.4-5.3 5.3 0 31.1 16.9 68.2 97.8 68.2 58.4-.1 92-23.2 92-63.4z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
NodeIcon.displayName = 'NodeIcon';
|
||||
|
||||
export default NodeIcon;
|
||||
@@ -0,0 +1,29 @@
|
||||
import React from 'react';
|
||||
|
||||
function OutlineLightbulb(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
viewBox='5 2.5 14 20.2'
|
||||
width='1.31rem'
|
||||
height='1.4rem'
|
||||
fill='none'
|
||||
stroke='currentColor'
|
||||
strokeWidth='1.8'
|
||||
strokeLinecap='round'
|
||||
strokeLinejoin='round'
|
||||
aria-hidden='true'
|
||||
{...props}
|
||||
>
|
||||
<path d='M12 3.5a6 6 0 0 0-3.86 10.59c.9.78 1.43 1.57 1.43 2.41v1h4.86v-1c0-.84.53-1.63 1.43-2.41A6 6 0 0 0 12 3.5z' />
|
||||
<path d='M9.75 17.5h4.5' />
|
||||
<path d='M9.8 19.3a2.2 2.2 0 0 0 4.4 0' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
OutlineLightbulb.displayName = 'OutlineLightbulb';
|
||||
|
||||
export default OutlineLightbulb;
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
function PythonIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 448 512'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path d='M439.8 200.5c-7.7-30.9-22.3-54.2-53.4-54.2h-40.1v47.4c0 36.8-31.2 67.8-66.8 67.8H172.7c-29.2 0-53.4 25-53.4 54.3v101.8c0 29 25.2 46 53.4 54.3 33.8 9.9 66.3 11.7 106.8 0 26.9-7.8 53.4-23.5 53.4-54.3v-40.7H226.2v-13.6h160.2c31.1 0 42.6-21.7 53.4-54.2 11.2-33.5 10.7-65.7 0-108.6zM286.2 404c11.1 0 20.1 9.1 20.1 20.3 0 11.3-9 20.4-20.1 20.4-11 0-20.1-9.2-20.1-20.4.1-11.3 9.1-20.3 20.1-20.3zM167.8 248.1h106.8c29.7 0 53.4-24.5 53.4-54.3V91.9c0-29-24.4-50.7-53.4-55.6-35.8-5.9-74.7-5.6-106.8.1-45.2 8-53.4 24.7-53.4 55.6v40.7h106.9v13.6h-147c-31.1 0-58.3 18.7-66.8 54.2-9.8 40.7-10.2 66.1 0 108.6 7.6 31.6 25.7 54.2 56.8 54.2H101v-48.8c0-35.3 30.5-66.4 66.8-66.4zm-6.7-142.6c-11.1 0-20.1-9.1-20.1-20.3.1-11.3 9-20.4 20.1-20.4 11 0 20.1 9.2 20.1 20.4s-9 20.3-20.1 20.3z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
PythonIcon.displayName = 'PythonIcon';
|
||||
|
||||
export default PythonIcon;
|
||||
@@ -0,0 +1,34 @@
|
||||
import React from 'react';
|
||||
|
||||
function Quote(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
width='50'
|
||||
height='50'
|
||||
viewBox='0 0 50 50'
|
||||
fill='none'
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d='M25 48.5C38.1168 48.5 48.75 37.8668 48.75 24.75C48.75 11.6332 38.1168 1 25 1C11.8832 1 1.25 11.6332 1.25 24.75C1.25 37.8668 11.8832 48.5 25 48.5Z'
|
||||
fill='var(--primary-color)'
|
||||
stroke='var(--primary-color)'
|
||||
/>
|
||||
<path
|
||||
d='M11 35.9837C13.7505 34.1517 16.501 32.3197 16.5032 25.0085C15.6296 24.9918 11.9169 24.9918 11 24.9918C11 24.0759 11.0181 15.3097 11 14H22V25.0085C22 36.8997 11 35.9837 11 35.9837Z'
|
||||
fill='var(--primary-background)'
|
||||
/>
|
||||
<path
|
||||
d='M29 35.9837C31.7505 34.1517 34.501 32.3197 34.5032 25.0084C33.6296 24.9919 29.9168 24.9919 29 24.9919C29 24.0759 29.018 15.3097 29 14H40V25.0084C40 36.8997 29 35.9837 29 35.9837Z'
|
||||
fill='var(--primary-background)'
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Quote.displayName = 'Quote';
|
||||
|
||||
export default Quote;
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
function ReactIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 512 512'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path d='M418.2 177.2c-5.4-1.8-10.8-3.5-16.2-5.1.9-3.7 1.7-7.4 2.5-11.1 12.3-59.6 4.2-107.5-23.1-123.3-26.3-15.1-69.2.6-112.6 38.4-4.3 3.7-8.5 7.6-12.5 11.5-2.7-2.6-5.5-5.2-8.3-7.7-45.5-40.4-91.1-57.4-118.4-41.5-26.2 15.2-34 60.3-23 116.7 1.1 5.6 2.3 11.1 3.7 16.7-6.4 1.8-12.7 3.8-18.6 5.9C38.3 196.2 0 225.4 0 255.6c0 31.2 40.8 62.5 96.3 81.5 4.5 1.5 9 3 13.6 4.3-1.5 6-2.8 11.9-4 18-10.5 55.5-2.3 99.5 23.9 114.6 27 15.6 72.4-.4 116.6-39.1 3.5-3.1 7-6.3 10.5-9.7 4.4 4.3 9 8.4 13.6 12.4 42.8 36.8 85.1 51.7 111.2 36.6 27-15.6 35.8-62.9 24.4-120.5-.9-4.4-1.9-8.9-3-13.5 3.2-.9 6.3-1.9 9.4-2.9 57.7-19.1 99.5-50 99.5-81.7 0-30.3-39.4-59.7-93.8-78.4zM282.9 92.3c37.2-32.4 71.9-45.1 87.7-36 16.9 9.7 23.4 48.9 12.8 100.4-.7 3.4-1.4 6.7-2.3 10-22.2-5-44.7-8.6-67.3-10.6-13-18.6-27.2-36.4-42.6-53.1 3.9-3.7 7.7-7.2 11.7-10.7zM167.2 307.5c5.1 8.7 10.3 17.4 15.8 25.9-15.6-1.7-31.1-4.2-46.4-7.5 4.4-14.4 9.9-29.3 16.3-44.5 4.6 8.8 9.3 17.5 14.3 26.1zm-30.3-120.3c14.4-3.2 29.7-5.8 45.6-7.8-5.3 8.3-10.5 16.8-15.4 25.4-4.9 8.5-9.7 17.2-14.2 26-6.3-14.9-11.6-29.5-16-43.6zm27.4 68.9c6.6-13.8 13.8-27.3 21.4-40.6s15.8-26.2 24.4-38.9c15-1.1 30.3-1.7 45.9-1.7s31 .6 45.9 1.7c8.5 12.6 16.6 25.5 24.3 38.7s14.9 26.7 21.7 40.4c-6.7 13.8-13.9 27.4-21.6 40.8-7.6 13.3-15.7 26.2-24.2 39-14.9 1.1-30.4 1.6-46.1 1.6s-30.9-.5-45.6-1.4c-8.7-12.7-16.9-25.7-24.6-39s-14.8-26.8-21.5-40.6zm180.6 51.2c5.1-8.8 9.9-17.7 14.6-26.7 6.4 14.5 12 29.2 16.9 44.3-15.5 3.5-31.2 6.2-47 8 5.4-8.4 10.5-17 15.5-25.6zm14.4-76.5c-4.7-8.8-9.5-17.6-14.5-26.2-4.9-8.5-10-16.9-15.3-25.2 16.1 2 31.5 4.7 45.9 8-4.6 14.8-10 29.2-16.1 43.4zM256.2 118.3c10.5 11.4 20.4 23.4 29.6 35.8-19.8-.9-39.7-.9-59.5 0 9.8-12.9 19.9-24.9 29.9-35.8zM140.2 57c16.8-9.8 54.1 4.2 93.4 39 2.5 2.2 5 4.6 7.6 7-15.5 16.7-29.8 34.5-42.9 53.1-22.6 2-45 5.5-67.2 10.4-1.3-5.1-2.4-10.3-3.5-15.5-9.4-48.4-3.2-84.9 12.6-94zm-24.5 263.6c-4.2-1.2-8.3-2.5-12.4-3.9-21.3-6.7-45.5-17.3-63-31.2-10.1-7-16.9-17.8-18.8-29.9 0-18.3 31.6-41.7 77.2-57.6 5.7-2 11.5-3.8 17.3-5.5 6.8 21.7 15 43 24.5 63.6-9.6 20.9-17.9 42.5-24.8 64.5zm116.6 98c-16.5 15.1-35.6 27.1-56.4 35.3-11.1 5.3-23.9 5.8-35.3 1.3-15.9-9.2-22.5-44.5-13.5-92 1.1-5.6 2.3-11.2 3.7-16.7 22.4 4.8 45 8.1 67.9 9.8 13.2 18.7 27.7 36.6 43.2 53.4-3.2 3.1-6.4 6.1-9.6 8.9zm24.5-24.3c-10.2-11-20.4-23.2-30.3-36.3 9.6.4 19.5.6 29.5.6 10.3 0 20.4-.2 30.4-.7-9.2 12.7-19.1 24.8-29.6 36.4zm130.7 30c-.9 12.2-6.9 23.6-16.5 31.3-15.9 9.2-49.8-2.8-86.4-34.2-4.2-3.6-8.4-7.5-12.7-11.5 15.3-16.9 29.4-34.8 42.2-53.6 22.9-1.9 45.7-5.4 68.2-10.5 1 4.1 1.9 8.2 2.7 12.2 4.9 21.6 5.7 44.1 2.5 66.3zm18.2-107.5c-2.8.9-5.6 1.8-8.5 2.6-7-21.8-15.6-43.1-25.5-63.8 9.6-20.4 17.7-41.4 24.5-62.9 5.2 1.5 10.2 3.1 15 4.7 46.6 16 79.3 39.8 79.3 58 0 19.6-34.9 44.9-84.8 61.4zm-149.7-15c25.3 0 45.8-20.5 45.8-45.8s-20.5-45.8-45.8-45.8c-25.3 0-45.8 20.5-45.8 45.8s20.5 45.8 45.8 45.8z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
ReactIcon.displayName = 'ReactIcon';
|
||||
|
||||
export default ReactIcon;
|
||||
@@ -0,0 +1,11 @@
|
||||
import React from 'react';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { faTrashCan } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
function Reset(): JSX.Element {
|
||||
return <FontAwesomeIcon icon={faTrashCan} aria-hidden='true' />;
|
||||
}
|
||||
|
||||
Reset.displayName = 'Reset';
|
||||
|
||||
export default Reset;
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
function ResponsiveDesign(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 640 512'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path d='M112 48h352v48h48V32a32.09 32.09 0 00-32-32H96a32.09 32.09 0 00-32 32v256H16a16 16 0 00-16 16v16a64.14 64.14 0 0063.91 64H352v-96H112zm492 80H420a36 36 0 00-36 36v312a36 36 0 0036 36h184a36 36 0 0036-36V164a36 36 0 00-36-36zm-12 336H432V176h160z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
ResponsiveDesign.displayName = 'ResponsiveDesign';
|
||||
|
||||
export default ResponsiveDesign;
|
||||
@@ -0,0 +1,22 @@
|
||||
import React from 'react';
|
||||
|
||||
function RosettaCodeIcon(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
height='16'
|
||||
width='14'
|
||||
viewBox='0 0 448 512'
|
||||
{...props}
|
||||
>
|
||||
<path d='M64 0C28.7 0 0 28.7 0 64V448c0 35.3 28.7 64 64 64H384c35.3 0 64-28.7 64-64V64c0-35.3-28.7-64-64-64H64zM176 432h96c8.8 0 16 7.2 16 16s-7.2 16-16 16H176c-8.8 0-16-7.2-16-16s7.2-16 16-16z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
RosettaCodeIcon.displayName = 'RosettaCodeIcon';
|
||||
|
||||
export default RosettaCodeIcon;
|
||||
@@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
|
||||
function Shield(
|
||||
props: JSX.IntrinsicAttributes & React.SVGProps<SVGSVGElement>
|
||||
): JSX.Element {
|
||||
return (
|
||||
<svg
|
||||
aria-hidden='true'
|
||||
viewBox='0 0 512 512'
|
||||
xmlns='http://www.w3.org/2000/svg'
|
||||
{...props}
|
||||
>
|
||||
<path d='M466.5 83.7l-192-80a48.15 48.15 0 00-36.9 0l-192 80C27.7 91.1 16 108.6 16 128c0 198.5 114.5 335.7 221.5 380.3 11.8 4.9 25.1 4.9 36.9 0C360.1 472.6 496 349.3 496 128c0-19.4-11.7-36.9-29.5-44.3zm-47.2 114.2l-184 184c-6.2 6.2-16.4 6.2-22.6 0l-104-104c-6.2-6.2-6.2-16.4 0-22.6l22.6-22.6c6.2-6.2 16.4-6.2 22.6 0l70.1 70.1 150.1-150.1c6.2-6.2 16.4-6.2 22.6 0l22.6 22.6c6.3 6.3 6.3 16.4 0 22.6z' />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
Shield.displayName = 'Shield';
|
||||
|
||||
export default Shield;
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user