use spaces over tabs

This commit is contained in:
Nathan Wang 2020-06-20 01:10:27 -07:00
parent 952776c608
commit 0265353bd3
17 changed files with 1639 additions and 1639 deletions

View file

@ -1,9 +1,9 @@
{
"endOfLine": "lf",
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"useTabs": true,
"trailingComma": "es5",
"arrowParens": "avoid"
"endOfLine": "lf",
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"useTabs": false,
"trailingComma": "es5",
"arrowParens": "avoid"
}

View file

@ -3,84 +3,84 @@ import React from 'react';
import { MDXProvider } from '@mdx-js/react';
const SpoilerComponent = ({ children, title }) => {
const [show, setShow] = React.useState(false);
const [show, setShow] = React.useState(false);
return (
<div className={`border border-gray-200 rounded-md`}>
<p
className="p-4 flex items-start"
onClick={e => setShow(!show)}
style={{ marginBottom: 0 }}
>
{show && (
<svg
className="h-6 w-6 text-gray-500 mr-4"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fill-rule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clip-rule="evenodd"
></path>
</svg>
)}
{!show && (
<svg
className="h-6 w-6 text-gray-500 mr-4"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fill-rule="evenodd"
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clip-rule="evenodd"
></path>
</svg>
)}
{title}
</p>
return (
<div className={`border border-gray-200 rounded-md`}>
<p
className="p-4 flex items-start"
onClick={e => setShow(!show)}
style={{ marginBottom: 0 }}
>
{show && (
<svg
className="h-6 w-6 text-gray-500 mr-4"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fill-rule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clip-rule="evenodd"
></path>
</svg>
)}
{!show && (
<svg
className="h-6 w-6 text-gray-500 mr-4"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fill-rule="evenodd"
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clip-rule="evenodd"
></path>
</svg>
)}
{title}
</p>
{show && <div className="p-4 pt-0 spoiler-body">{children}</div>}
</div>
);
{show && <div className="p-4 pt-0 spoiler-body">{children}</div>}
</div>
);
};
const components = {
wrapper: ({ excerptOnly = false, children }) => {
if (excerptOnly) {
for (let child of children) {
if (child.props.originalType === 'module-excerpt') return child;
}
return null;
}
wrapper: ({ excerptOnly = false, children }) => {
if (excerptOnly) {
for (let child of children) {
if (child.props.originalType === 'module-excerpt') return child;
}
return null;
}
return children;
},
'module-excerpt': props => <div {...props} />,
spoiler: SpoilerComponent,
'info-block': ({ children }) => (
<div className="rounded-md bg-blue-50 p-4 info-block mb-4">
<div className="flex">
<div className="flex-shrink-0">
<svg
className="h-5 w-5 text-blue-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
clipRule="evenodd"
/>
</svg>
</div>
<div className="ml-3">{children}</div>
</div>
</div>
),
return children;
},
'module-excerpt': props => <div {...props} />,
spoiler: SpoilerComponent,
'info-block': ({ children }) => (
<div className="rounded-md bg-blue-50 p-4 info-block mb-4">
<div className="flex">
<div className="flex-shrink-0">
<svg
className="h-5 w-5 text-blue-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
clipRule="evenodd"
/>
</svg>
</div>
<div className="ml-3">{children}</div>
</div>
</div>
),
};
export const wrapRootElement = ({ element }) => (
<MDXProvider components={components}>{element}</MDXProvider>
<MDXProvider components={components}>{element}</MDXProvider>
);

View file

@ -4,82 +4,82 @@ const tailwindConfig = require('./tailwind.config.js');
const fullConfig = resolveConfig(tailwindConfig);
module.exports = {
siteMetadata: {
title: `USACO Guide`,
description: `A collection of curated, high-quality resources to take you from Bronze to Platinum.`,
author: `@usacoteam`,
},
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${__dirname}/content`,
name: `content`,
},
},
{
resolve: `gatsby-plugin-mdx`,
options: {
extensions: [`.mdx`, `.md`],
gatsbyRemarkPlugins: [
`gatsby-remark-autolink-headers`,
{
resolve: 'gatsby-remark-custom-blocks',
options: {
blocks: {
info: {
containerElement: 'info-block',
title: 'optional',
},
},
},
},
{
resolve: `gatsby-remark-katex`,
options: {
// Add any KaTeX options from https://github.com/KaTeX/KaTeX/blob/master/docs/options.md here
strict: `ignore`,
},
},
{
resolve: `gatsby-remark-prismjs`,
options: {
noInlineHighlight: true,
},
},
],
plugins: [`gatsby-remark-autolink-headers`],
},
},
{
resolve: `gatsby-plugin-postcss`,
options: {
postCssPlugins: [
require(`tailwindcss`)(tailwindConfig),
require(`autoprefixer`),
...(process.env.NODE_ENV === `production`
? [require(`cssnano`)]
: []),
],
},
},
`gatsby-plugin-react-helmet`,
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,
// {
// resolve: `gatsby-plugin-manifest`,
// options: {
// name: `gatsby-starter-default`,
// short_name: `starter`,
// start_url: `/`,
// background_color: `#663399`,
// theme_color: `#663399`,
// display: `minimal-ui`,
// // icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
// },
// },
// this (optional) plugin enables Progressive Web App + Offline functionality
// To learn more, visit: https://gatsby.dev/offline
// `gatsby-plugin-offline`,
],
siteMetadata: {
title: `USACO Guide`,
description: `A collection of curated, high-quality resources to take you from Bronze to Platinum.`,
author: `@usacoteam`,
},
plugins: [
{
resolve: `gatsby-source-filesystem`,
options: {
path: `${__dirname}/content`,
name: `content`,
},
},
{
resolve: `gatsby-plugin-mdx`,
options: {
extensions: [`.mdx`, `.md`],
gatsbyRemarkPlugins: [
`gatsby-remark-autolink-headers`,
{
resolve: 'gatsby-remark-custom-blocks',
options: {
blocks: {
info: {
containerElement: 'info-block',
title: 'optional',
},
},
},
},
{
resolve: `gatsby-remark-katex`,
options: {
// Add any KaTeX options from https://github.com/KaTeX/KaTeX/blob/master/docs/options.md here
strict: `ignore`,
},
},
{
resolve: `gatsby-remark-prismjs`,
options: {
noInlineHighlight: true,
},
},
],
plugins: [`gatsby-remark-autolink-headers`],
},
},
{
resolve: `gatsby-plugin-postcss`,
options: {
postCssPlugins: [
require(`tailwindcss`)(tailwindConfig),
require(`autoprefixer`),
...(process.env.NODE_ENV === `production`
? [require(`cssnano`)]
: []),
],
},
},
`gatsby-plugin-react-helmet`,
`gatsby-transformer-sharp`,
`gatsby-plugin-sharp`,
// {
// resolve: `gatsby-plugin-manifest`,
// options: {
// name: `gatsby-starter-default`,
// short_name: `starter`,
// start_url: `/`,
// background_color: `#663399`,
// theme_color: `#663399`,
// display: `minimal-ui`,
// // icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
// },
// },
// this (optional) plugin enables Progressive Web App + Offline functionality
// To learn more, visit: https://gatsby.dev/offline
// `gatsby-plugin-offline`,
],
};

View file

@ -1,53 +1,53 @@
import ModuleOrdering, { divisions } from './content/ordering';
exports.createPages = async ({ actions, graphql, reporter }) => {
const { createPage } = actions;
const { createPage } = actions;
// Generate Module Pages //
const moduleTemplate = require.resolve(`./src/templates/moduleTemplate.tsx`);
Object.keys(ModuleOrdering).forEach(division => {
const processItem = item => {
if (typeof item === 'object') {
// this is a nested module
item.items.forEach(x => processItem(x));
} else {
createPage({
path: `/${division}/${item}`,
component: moduleTemplate,
context: {
// additional data can be passed via context
id: item,
division: division,
},
});
}
};
ModuleOrdering[division].forEach(item => processItem(item));
});
// End Generate Module Pages //
// Generate Module Pages //
const moduleTemplate = require.resolve(`./src/templates/moduleTemplate.tsx`);
Object.keys(ModuleOrdering).forEach(division => {
const processItem = item => {
if (typeof item === 'object') {
// this is a nested module
item.items.forEach(x => processItem(x));
} else {
createPage({
path: `/${division}/${item}`,
component: moduleTemplate,
context: {
// additional data can be passed via context
id: item,
division: division,
},
});
}
};
ModuleOrdering[division].forEach(item => processItem(item));
});
// End Generate Module Pages //
// Generate Syllabus Pages //
const syllabusTemplate = require.resolve(
`./src/templates/syllabusTemplate.js`
);
divisions.forEach(division => {
createPage({
path: `/${division}`,
component: syllabusTemplate,
context: {
division: division,
},
});
});
// End Generate Syllabus Pages //
// Generate Syllabus Pages //
const syllabusTemplate = require.resolve(
`./src/templates/syllabusTemplate.js`
);
divisions.forEach(division => {
createPage({
path: `/${division}`,
component: syllabusTemplate,
context: {
division: division,
},
});
});
// End Generate Syllabus Pages //
};
exports.createSchemaCustomization = ({ actions }) => {
const { createTypes } = actions;
const typeDefs = `
const { createTypes } = actions;
const typeDefs = `
type MarkdownRemarkFrontmatter implements Node {
prerequisites: [[String]]
}
`;
createTypes(typeDefs);
createTypes(typeDefs);
};

View file

@ -6,11 +6,11 @@ import '../styles/prism-theme.css';
import { MDXRenderer } from 'gatsby-plugin-mdx';
const Markdown = ({ body, className, excerptOnly = false }) => {
return (
<div className={`markdown ${className}`}>
<MDXRenderer excerptOnly={excerptOnly}>{body}</MDXRenderer>
</div>
);
return (
<div className={`markdown ${className}`}>
<MDXRenderer excerptOnly={excerptOnly}>{body}</MDXRenderer>
</div>
);
};
export default Markdown;

View file

@ -2,118 +2,118 @@ import React from 'react';
import { Link } from 'gatsby';
const CompletedCheck = () => (
<svg
className="h-6 w-6 mr-2 text-green-500"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fillRule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clipRule="evenodd"
/>
</svg>
<svg
className="h-6 w-6 mr-2 text-green-500"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fillRule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clipRule="evenodd"
/>
</svg>
);
const IncompleteCheck = () => (
<svg
className="h-6 w-6 mr-2 text-gray-200"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fillRule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clipRule="evenodd"
/>
</svg>
<svg
className="h-6 w-6 mr-2 text-gray-200"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fillRule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clipRule="evenodd"
/>
</svg>
);
const renderProblem = (problem, idx) => {
return (
<li className="flex items-center" key={problem}>
{idx > 0 ? <IncompleteCheck /> : <CompletedCheck />}
{/* todo make url legit */}
<a className="text-blue-600" href="https://google.com/">
{problem}
</a>
</li>
);
return (
<li className="flex items-center" key={problem}>
{idx > 0 ? <IncompleteCheck /> : <CompletedCheck />}
{/* todo make url legit */}
<a className="text-blue-600" href="https://google.com/">
{problem}
</a>
</li>
);
};
const renderPrerequisite = prerequisite => {
const link = prerequisite.length > 1 ? prerequisite[1] : null;
return (
<li key={prerequisite[0]}>
{link && (
<a href={link} className="text-blue-600">
{prerequisite[0]}
</a>
)}
{!link && prerequisite[0]}
</li>
);
const link = prerequisite.length > 1 ? prerequisite[1] : null;
return (
<li key={prerequisite[0]}>
{link && (
<a href={link} className="text-blue-600">
{prerequisite[0]}
</a>
)}
{!link && prerequisite[0]}
</li>
);
};
const SyllabusModule = ({
title,
children,
author,
problems,
prerequisites,
url,
title,
children,
author,
problems,
prerequisites,
url,
}) => {
// in the future, fetch this data either from localStorage or from server.
const isComplete = title === 'Prerequisites' || title === 'Getting Started';
// in the future, fetch this data either from localStorage or from server.
const isComplete = title === 'Prerequisites' || title === 'Getting Started';
return (
<div className="bg-white overflow-hidden shadow rounded-lg mb-8" id={url}>
<div className="border-b border-gray-200 px-4 py-4 sm:px-6 flex items-center">
<h2 className="font-bold text-xl mr-2">{title}</h2>
{isComplete && (
<svg
className="h-8 w-8 text-green-500"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
viewBox="0 0 24 24"
stroke="currentColor"
>
<path d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
)}
</div>
{prerequisites && (
<div className="p-4 sm:p-6 border-b border-gray-200">
Prerequisites:{' '}
<ul className="ml-8 list-disc">
{prerequisites.map(renderPrerequisite)}
</ul>
</div>
)}
<div className="px-4 py-4 sm:p-6">
{children}
return (
<div className="bg-white overflow-hidden shadow rounded-lg mb-8" id={url}>
<div className="border-b border-gray-200 px-4 py-4 sm:px-6 flex items-center">
<h2 className="font-bold text-xl mr-2">{title}</h2>
{isComplete && (
<svg
className="h-8 w-8 text-green-500"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
viewBox="0 0 24 24"
stroke="currentColor"
>
<path d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
)}
</div>
{prerequisites && (
<div className="p-4 sm:p-6 border-b border-gray-200">
Prerequisites:{' '}
<ul className="ml-8 list-disc">
{prerequisites.map(renderPrerequisite)}
</ul>
</div>
)}
<div className="px-4 py-4 sm:p-6">
{children}
{problems && (
<>
Problems:
<ul className="ml-3 space-y-1 py-2">
{problems.map(renderProblem)}
</ul>
</>
)}
{problems && (
<>
Problems:
<ul className="ml-3 space-y-1 py-2">
{problems.map(renderProblem)}
</ul>
</>
)}
{author && <p className="mt-2">Author: {author}</p>}
</div>
<Link
to={url || '/'}
className="block border-t border-gray-200 px-4 py-4 sm:px-6 text-blue-600 font-bold uppercase text-sm hover:bg-gray-50 transition duration-150"
>
View Module
</Link>
</div>
);
{author && <p className="mt-2">Author: {author}</p>}
</div>
<Link
to={url || '/'}
className="block border-t border-gray-200 px-4 py-4 sm:px-6 text-blue-600 font-bold uppercase text-sm hover:bg-gray-50 transition duration-150"
>
View Module
</Link>
</div>
);
};
export default SyllabusModule;

View file

@ -3,108 +3,108 @@ import * as React from 'react';
import { useRef, useEffect, useContext } from 'react';
const TransitionContext = React.createContext({
parent: {},
parent: {},
});
function useIsInitialRender() {
const isInitialRender = useRef(true);
useEffect(() => {
isInitialRender.current = false;
}, []);
return isInitialRender.current;
const isInitialRender = useRef(true);
useEffect(() => {
isInitialRender.current = false;
}, []);
return isInitialRender.current;
}
function CSSTransition({
show,
enter = '',
enterFrom = '',
enterTo = '',
leave = '',
leaveFrom = '',
leaveTo = '',
appear,
children,
show,
enter = '',
enterFrom = '',
enterTo = '',
leave = '',
leaveFrom = '',
leaveTo = '',
appear,
children,
}) {
const enterClasses = enter.split(' ').filter(s => s.length);
const enterFromClasses = enterFrom.split(' ').filter(s => s.length);
const enterToClasses = enterTo.split(' ').filter(s => s.length);
const leaveClasses = leave.split(' ').filter(s => s.length);
const leaveFromClasses = leaveFrom.split(' ').filter(s => s.length);
const leaveToClasses = leaveTo.split(' ').filter(s => s.length);
const enterClasses = enter.split(' ').filter(s => s.length);
const enterFromClasses = enterFrom.split(' ').filter(s => s.length);
const enterToClasses = enterTo.split(' ').filter(s => s.length);
const leaveClasses = leave.split(' ').filter(s => s.length);
const leaveFromClasses = leaveFrom.split(' ').filter(s => s.length);
const leaveToClasses = leaveTo.split(' ').filter(s => s.length);
function addClasses(node, classes) {
classes.length && node.classList.add(...classes);
}
function addClasses(node, classes) {
classes.length && node.classList.add(...classes);
}
function removeClasses(node, classes) {
classes.length && node.classList.remove(...classes);
}
function removeClasses(node, classes) {
classes.length && node.classList.remove(...classes);
}
return (
<ReactCSSTransition
appear={appear}
unmountOnExit
in={show}
addEndListener={(node, done) => {
node.addEventListener('transitionend', done, false);
}}
onEnter={node => {
addClasses(node, [...enterClasses, ...enterFromClasses]);
}}
onEntering={node => {
removeClasses(node, enterFromClasses);
addClasses(node, enterToClasses);
}}
onEntered={node => {
removeClasses(node, [...enterToClasses, ...enterClasses]);
}}
onExit={node => {
addClasses(node, [...leaveClasses, ...leaveFromClasses]);
}}
onExiting={node => {
removeClasses(node, leaveFromClasses);
addClasses(node, leaveToClasses);
}}
onExited={node => {
removeClasses(node, [...leaveToClasses, ...leaveClasses]);
}}
>
{children}
</ReactCSSTransition>
);
return (
<ReactCSSTransition
appear={appear}
unmountOnExit
in={show}
addEndListener={(node, done) => {
node.addEventListener('transitionend', done, false);
}}
onEnter={node => {
addClasses(node, [...enterClasses, ...enterFromClasses]);
}}
onEntering={node => {
removeClasses(node, enterFromClasses);
addClasses(node, enterToClasses);
}}
onEntered={node => {
removeClasses(node, [...enterToClasses, ...enterClasses]);
}}
onExit={node => {
addClasses(node, [...leaveClasses, ...leaveFromClasses]);
}}
onExiting={node => {
removeClasses(node, leaveFromClasses);
addClasses(node, leaveToClasses);
}}
onExited={node => {
removeClasses(node, [...leaveToClasses, ...leaveClasses]);
}}
>
{children}
</ReactCSSTransition>
);
}
function Transition({ show, appear, ...rest }: any) {
const { parent }: { parent: any } = useContext(TransitionContext);
const isInitialRender = useIsInitialRender();
const isChild = show === undefined;
const { parent }: { parent: any } = useContext(TransitionContext);
const isInitialRender = useIsInitialRender();
const isChild = show === undefined;
if (isChild) {
return (
// @ts-ignore
<CSSTransition
appear={parent.appear || !parent.isInitialRender}
show={parent.show}
{...rest}
/>
);
}
if (isChild) {
return (
// @ts-ignore
<CSSTransition
appear={parent.appear || !parent.isInitialRender}
show={parent.show}
{...rest}
/>
);
}
return (
<TransitionContext.Provider
value={{
parent: {
show,
isInitialRender,
appear,
},
}}
>
{/*
return (
<TransitionContext.Provider
value={{
parent: {
show,
isInitialRender,
appear,
},
}}
>
{/*
// @ts-ignore*/}
<CSSTransition appear={appear} show={show} {...rest} />
</TransitionContext.Provider>
);
<CSSTransition appear={appear} show={show} {...rest} />
</TransitionContext.Provider>
);
}
export default Transition;

View file

@ -1,7 +1,7 @@
import * as React from 'react';
const Layout = ({ children }) => {
return <>{children}</>;
return <>{children}</>;
};
export default Layout;

View file

@ -11,78 +11,78 @@ import { Helmet } from 'react-helmet';
import { useStaticQuery, graphql } from 'gatsby';
function SEO({ description, lang, meta, title }) {
const { site } = useStaticQuery(
graphql`
query {
site {
siteMetadata {
title
description
author
}
}
}
`
);
const { site } = useStaticQuery(
graphql`
query {
site {
siteMetadata {
title
description
author
}
}
}
`
);
const metaDescription = description || site.siteMetadata.description;
const metaDescription = description || site.siteMetadata.description;
return (
<Helmet
htmlAttributes={{
lang,
}}
title={title}
titleTemplate={`%s | ${site.siteMetadata.title}`}
meta={[
{
name: `description`,
content: metaDescription,
},
{
property: `og:title`,
content: title,
},
{
property: `og:description`,
content: metaDescription,
},
{
property: `og:type`,
content: `website`,
},
{
name: `twitter:card`,
content: `summary`,
},
{
name: `twitter:creator`,
content: site.siteMetadata.author,
},
{
name: `twitter:title`,
content: title,
},
{
name: `twitter:description`,
content: metaDescription,
},
].concat(meta)}
/>
);
return (
<Helmet
htmlAttributes={{
lang,
}}
title={title}
titleTemplate={`%s | ${site.siteMetadata.title}`}
meta={[
{
name: `description`,
content: metaDescription,
},
{
property: `og:title`,
content: title,
},
{
property: `og:description`,
content: metaDescription,
},
{
property: `og:type`,
content: `website`,
},
{
name: `twitter:card`,
content: `summary`,
},
{
name: `twitter:creator`,
content: site.siteMetadata.author,
},
{
name: `twitter:title`,
content: title,
},
{
name: `twitter:description`,
content: metaDescription,
},
].concat(meta)}
/>
);
}
SEO.defaultProps = {
lang: `en`,
meta: [],
description: ``,
lang: `en`,
meta: [],
description: ``,
};
SEO.propTypes = {
description: PropTypes.string,
lang: PropTypes.string,
meta: PropTypes.arrayOf(PropTypes.object),
title: PropTypes.string.isRequired,
description: PropTypes.string,
lang: PropTypes.string,
meta: PropTypes.arrayOf(PropTypes.object),
title: PropTypes.string.isRequired,
};
export default SEO;

View file

@ -2,35 +2,35 @@ import React from 'react';
import PropTypes from 'prop-types';
export default function HTML(props) {
return (
<html {...props.htmlAttributes}>
<head>
<meta charSet="utf-8" />
<meta httpEquiv="x-ua-compatible" content="ie=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
{props.headComponents}
</head>
<body {...props.bodyAttributes}>
{props.preBodyComponents}
<div
key={`body`}
id="___gatsby"
dangerouslySetInnerHTML={{ __html: props.body }}
/>
{props.postBodyComponents}
</body>
</html>
);
return (
<html {...props.htmlAttributes}>
<head>
<meta charSet="utf-8" />
<meta httpEquiv="x-ua-compatible" content="ie=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
{props.headComponents}
</head>
<body {...props.bodyAttributes}>
{props.preBodyComponents}
<div
key={`body`}
id="___gatsby"
dangerouslySetInnerHTML={{ __html: props.body }}
/>
{props.postBodyComponents}
</body>
</html>
);
}
HTML.propTypes = {
htmlAttributes: PropTypes.object,
headComponents: PropTypes.array,
bodyAttributes: PropTypes.object,
preBodyComponents: PropTypes.array,
body: PropTypes.string,
postBodyComponents: PropTypes.array,
htmlAttributes: PropTypes.object,
headComponents: PropTypes.array,
bodyAttributes: PropTypes.object,
preBodyComponents: PropTypes.array,
body: PropTypes.string,
postBodyComponents: PropTypes.array,
};

View file

@ -4,448 +4,448 @@ import Layout from '../components/layout';
import SEO from '../components/seo';
export default function IndexPage(props: PageProps) {
return (
<Layout>
<SEO title="" />
return (
<Layout>
<SEO title="" />
{/* Begin Hero */}
<div className="relative bg-white overflow-hidden">
<div className="hidden lg:block lg:absolute lg:inset-0">
<svg
className="absolute top-0 left-1/2 transform translate-x-64 -translate-y-8"
width="640"
height="784"
fill="none"
viewBox="0 0 640 784"
>
<defs>
<pattern
id="9ebea6f4-a1f5-4d96-8c4e-4c2abf658047"
x="118"
y="0"
width="20"
height="20"
patternUnits="userSpaceOnUse"
>
<rect
x="0"
y="0"
width="4"
height="4"
className="text-gray-200"
fill="currentColor"
/>
</pattern>
</defs>
<rect
y="72"
width="640"
height="640"
className="text-gray-50"
fill="currentColor"
/>
<rect
x="118"
width="404"
height="784"
fill="url(#9ebea6f4-a1f5-4d96-8c4e-4c2abf658047)"
/>
</svg>
</div>
{/* Begin Hero */}
<div className="relative bg-white overflow-hidden">
<div className="hidden lg:block lg:absolute lg:inset-0">
<svg
className="absolute top-0 left-1/2 transform translate-x-64 -translate-y-8"
width="640"
height="784"
fill="none"
viewBox="0 0 640 784"
>
<defs>
<pattern
id="9ebea6f4-a1f5-4d96-8c4e-4c2abf658047"
x="118"
y="0"
width="20"
height="20"
patternUnits="userSpaceOnUse"
>
<rect
x="0"
y="0"
width="4"
height="4"
className="text-gray-200"
fill="currentColor"
/>
</pattern>
</defs>
<rect
y="72"
width="640"
height="640"
className="text-gray-50"
fill="currentColor"
/>
<rect
x="118"
width="404"
height="784"
fill="url(#9ebea6f4-a1f5-4d96-8c4e-4c2abf658047)"
/>
</svg>
</div>
<div
className="relative pt-6 pb-16 md:pb-20 lg:pb-24 xl:pb-32 border-blue-600"
style={{ borderTopWidth: '12px' }}
>
<main className="mt-8 mx-auto max-w-6xl px-4 sm:mt-12 sm:px-6 md:mt-20 xl:mt-24">
<div className="lg:grid lg:grid-cols-12 lg:gap-8">
<div className="sm:text-center md:max-w-2xl md:mx-auto lg:col-span-6 lg:text-left lg:flex lg:flex-col lg:justify-center">
<div className="text-sm font-semibold uppercase tracking-wide text-gray-500 sm:text-base lg:text-sm xl:text-base">
Pre-Release
</div>
<h2 className="mt-1 text-4xl tracking-tight leading-10 font-extrabold text-gray-900 sm:leading-none sm:text-6xl lg:text-5xl xl:text-6xl">
USACO <span className="text-blue-600">Guide</span>
</h2>
<p className="mt-3 text-base text-gray-500 sm:mt-5 sm:text-xl lg:text-lg xl:text-xl">
A free collection of <b>curated, high-quality resources</b> to
take you from Bronze to Platinum and beyond.
</p>
<div className="mt-5 sm:mt-8 sm:flex sm:justify-center lg:justify-start">
<div className="rounded-md shadow">
<Link
to="/intro"
className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base leading-6 font-medium rounded-md text-white bg-blue-600 hover:bg-blue-500 focus:outline-none focus:border-blue-700 focus:shadow-outline-blue transition duration-150 ease-in-out md:py-4 md:text-lg md:px-10"
>
View Guide
</Link>
</div>
<div className="mt-3 sm:mt-0 sm:ml-3">
<a
href="#learn-more"
className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base leading-6 font-medium rounded-md text-blue-700 bg-blue-100 hover:text-blue-600 hover:bg-blue-50 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 transition duration-150 ease-in-out md:py-4 md:text-lg md:px-10"
>
Learn More
</a>
</div>
</div>
</div>
<div className="mt-12 relative sm:max-w-lg sm:mx-auto lg:mt-0 lg:max-w-none lg:mx-0 lg:col-span-6 lg:flex lg:items-center">
<svg
className="absolute top-0 left-1/2 transform -translate-x-1/2 -translate-y-8 scale-75 origin-top sm:scale-100 lg:hidden"
width="640"
height="784"
fill="none"
viewBox="0 0 640 784"
>
<defs>
<pattern
id="4f4f415c-a0e9-44c2-9601-6ded5a34a13e"
x="118"
y="0"
width="20"
height="20"
patternUnits="userSpaceOnUse"
>
<rect
x="0"
y="0"
width="4"
height="4"
className="text-gray-200"
fill="currentColor"
/>
</pattern>
</defs>
<rect
y="72"
width="640"
height="640"
className="text-gray-50"
fill="currentColor"
/>
<rect
x="118"
width="404"
height="784"
fill="url(#4f4f415c-a0e9-44c2-9601-6ded5a34a13e)"
/>
</svg>
<div className="relative mx-auto xl:mr-0 w-full rounded-lg shadow-lg lg:max-w-md">
<a
href="https://www.youtube.com/watch?v=ueNT-w7Oluw"
target="_blank"
className="relative block w-full rounded-lg overflow-hidden focus:outline-none focus:shadow-outline"
>
<img
className="w-full"
src="https://img.youtube.com/vi/ueNT-w7Oluw/maxresdefault.jpg"
alt="Woman making a sale"
/>
<div className="absolute inset-0 w-full h-full flex items-center justify-center">
<svg
className="h-20 w-20 text-blue-500"
fill="currentColor"
viewBox="0 0 84 84"
>
<circle
opacity="0.9"
cx="42"
cy="42"
r="42"
fill="white"
/>
<path d="M55.5039 40.3359L37.1094 28.0729C35.7803 27.1869 34 28.1396 34 29.737V54.263C34 55.8604 35.7803 56.8131 37.1094 55.9271L55.5038 43.6641C56.6913 42.8725 56.6913 41.1275 55.5039 40.3359Z" />
</svg>
</div>
</a>
</div>
</div>
</div>
</main>
</div>
</div>
{/* End Hero */}
<div
className="relative pt-6 pb-16 md:pb-20 lg:pb-24 xl:pb-32 border-blue-600"
style={{ borderTopWidth: '12px' }}
>
<main className="mt-8 mx-auto max-w-6xl px-4 sm:mt-12 sm:px-6 md:mt-20 xl:mt-24">
<div className="lg:grid lg:grid-cols-12 lg:gap-8">
<div className="sm:text-center md:max-w-2xl md:mx-auto lg:col-span-6 lg:text-left lg:flex lg:flex-col lg:justify-center">
<div className="text-sm font-semibold uppercase tracking-wide text-gray-500 sm:text-base lg:text-sm xl:text-base">
Pre-Release
</div>
<h2 className="mt-1 text-4xl tracking-tight leading-10 font-extrabold text-gray-900 sm:leading-none sm:text-6xl lg:text-5xl xl:text-6xl">
USACO <span className="text-blue-600">Guide</span>
</h2>
<p className="mt-3 text-base text-gray-500 sm:mt-5 sm:text-xl lg:text-lg xl:text-xl">
A free collection of <b>curated, high-quality resources</b> to
take you from Bronze to Platinum and beyond.
</p>
<div className="mt-5 sm:mt-8 sm:flex sm:justify-center lg:justify-start">
<div className="rounded-md shadow">
<Link
to="/intro"
className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base leading-6 font-medium rounded-md text-white bg-blue-600 hover:bg-blue-500 focus:outline-none focus:border-blue-700 focus:shadow-outline-blue transition duration-150 ease-in-out md:py-4 md:text-lg md:px-10"
>
View Guide
</Link>
</div>
<div className="mt-3 sm:mt-0 sm:ml-3">
<a
href="#learn-more"
className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base leading-6 font-medium rounded-md text-blue-700 bg-blue-100 hover:text-blue-600 hover:bg-blue-50 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 transition duration-150 ease-in-out md:py-4 md:text-lg md:px-10"
>
Learn More
</a>
</div>
</div>
</div>
<div className="mt-12 relative sm:max-w-lg sm:mx-auto lg:mt-0 lg:max-w-none lg:mx-0 lg:col-span-6 lg:flex lg:items-center">
<svg
className="absolute top-0 left-1/2 transform -translate-x-1/2 -translate-y-8 scale-75 origin-top sm:scale-100 lg:hidden"
width="640"
height="784"
fill="none"
viewBox="0 0 640 784"
>
<defs>
<pattern
id="4f4f415c-a0e9-44c2-9601-6ded5a34a13e"
x="118"
y="0"
width="20"
height="20"
patternUnits="userSpaceOnUse"
>
<rect
x="0"
y="0"
width="4"
height="4"
className="text-gray-200"
fill="currentColor"
/>
</pattern>
</defs>
<rect
y="72"
width="640"
height="640"
className="text-gray-50"
fill="currentColor"
/>
<rect
x="118"
width="404"
height="784"
fill="url(#4f4f415c-a0e9-44c2-9601-6ded5a34a13e)"
/>
</svg>
<div className="relative mx-auto xl:mr-0 w-full rounded-lg shadow-lg lg:max-w-md">
<a
href="https://www.youtube.com/watch?v=ueNT-w7Oluw"
target="_blank"
className="relative block w-full rounded-lg overflow-hidden focus:outline-none focus:shadow-outline"
>
<img
className="w-full"
src="https://img.youtube.com/vi/ueNT-w7Oluw/maxresdefault.jpg"
alt="Woman making a sale"
/>
<div className="absolute inset-0 w-full h-full flex items-center justify-center">
<svg
className="h-20 w-20 text-blue-500"
fill="currentColor"
viewBox="0 0 84 84"
>
<circle
opacity="0.9"
cx="42"
cy="42"
r="42"
fill="white"
/>
<path d="M55.5039 40.3359L37.1094 28.0729C35.7803 27.1869 34 28.1396 34 29.737V54.263C34 55.8604 35.7803 56.8131 37.1094 55.9271L55.5038 43.6641C56.6913 42.8725 56.6913 41.1275 55.5039 40.3359Z" />
</svg>
</div>
</a>
</div>
</div>
</div>
</main>
</div>
</div>
{/* End Hero */}
<div className="py-12 bg-white" id="learn-more">
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="lg:text-center">
<p className="text-base leading-6 text-blue-600 font-semibold tracking-wide uppercase">
About This Guide
</p>
<h3 className="mt-2 text-3xl leading-8 font-extrabold tracking-tight text-gray-900 sm:text-4xl sm:leading-10">
Not Just Another Resource.
</h3>
<p className="mt-4 max-w-4xl text-xl leading-7 text-gray-500 lg:mx-auto">
This is more than "just another resource." This is the first-ever
comprehensive, organized roadmap carefully designed and crafted
for USACO contestants available to everyone, for free.
</p>
<div className="py-12 bg-white" id="learn-more">
<div className="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="lg:text-center">
<p className="text-base leading-6 text-blue-600 font-semibold tracking-wide uppercase">
About This Guide
</p>
<h3 className="mt-2 text-3xl leading-8 font-extrabold tracking-tight text-gray-900 sm:text-4xl sm:leading-10">
Not Just Another Resource.
</h3>
<p className="mt-4 max-w-4xl text-xl leading-7 text-gray-500 lg:mx-auto">
This is more than "just another resource." This is the first-ever
comprehensive, organized roadmap carefully designed and crafted
for USACO contestants available to everyone, for free.
</p>
<div className="max-w-3xl mx-auto bg-yellow-50 rounded-md border-yellow-400 border p-4 mt-8">
<div className="flex">
<div className="flex-shrink-0">
<svg
className="h-5 w-5 text-yellow-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z"
clipRule="evenodd"
/>
</svg>
</div>
<div className="ml-3 flex-1 md:flex md:justify-between">
<p className="text-sm leading-5 text-yellow-700 text-left">
This guide is not a syllabus. Topics on this guide reflect{' '}
<i>past</i> problems, not future problems.
</p>
<p className="mt-3 text-sm leading-5 md:mt-0 md:ml-6">
<a
href="#"
className="whitespace-no-wrap font-medium text-yellow-700 hover:text-yellow-600 transition ease-in-out duration-150"
>
Learn More &rarr;
</a>
</p>
</div>
</div>
</div>
</div>
<div className="max-w-3xl mx-auto bg-yellow-50 rounded-md border-yellow-400 border p-4 mt-8">
<div className="flex">
<div className="flex-shrink-0">
<svg
className="h-5 w-5 text-yellow-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z"
clipRule="evenodd"
/>
</svg>
</div>
<div className="ml-3 flex-1 md:flex md:justify-between">
<p className="text-sm leading-5 text-yellow-700 text-left">
This guide is not a syllabus. Topics on this guide reflect{' '}
<i>past</i> problems, not future problems.
</p>
<p className="mt-3 text-sm leading-5 md:mt-0 md:ml-6">
<a
href="#"
className="whitespace-no-wrap font-medium text-yellow-700 hover:text-yellow-600 transition ease-in-out duration-150"
>
Learn More &rarr;
</a>
</p>
</div>
</div>
</div>
</div>
<div className="mt-16">
<ul className="md:grid md:grid-cols-2 md:col-gap-8 md:row-gap-10">
<li>
<div className="flex">
<div className="flex-shrink-0">
<div className="flex items-center justify-center h-12 w-12 rounded-md bg-blue-500 text-white">
<svg
className="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"
/>
</svg>
</div>
</div>
<div className="ml-4">
<h4 className="text-lg leading-6 font-medium text-gray-900">
Experienced Authors
</h4>
<p className="mt-2 text-base leading-6 text-gray-500">
This guide is written by top USACO contestants, including
two-time IOI winner and USACO Problemsetter{' '}
<a
href="https://github.com/bqi343"
className="underline text-blue-500"
>
Benjamin Qi
</a>
.
</p>
</div>
</div>
</li>
<li className="mt-10 md:mt-0">
<div className="flex">
<div className="flex-shrink-0">
<div className="flex items-center justify-center h-12 w-12 rounded-md bg-blue-500 text-white">
<svg
className="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M3 6l3 1m0 0l-3 9a5.002 5.002 0 006.001 0M6 7l3 9M6 7l6-2m6 2l3-1m-3 1l-3 9a5.002 5.002 0 006.001 0M18 7l3 9m-3-9l-6-2m0-2v2m0 16V5m0 16H9m3 0h3"
/>
</svg>
</div>
</div>
<div className="ml-4">
<h4 className="text-lg leading-6 font-medium text-gray-900">
Calibrated Difficulty
</h4>
<p className="mt-2 text-base leading-6 text-gray-500">
This guide is targeted towards all contestants, regardless
of their division. You'll find problems suitable for you.
</p>
</div>
</div>
</li>
<li className="mt-10 md:mt-0">
<div className="flex">
<div className="flex-shrink-0">
<div className="flex items-center justify-center h-12 w-12 rounded-md bg-blue-500 text-white">
<svg
className="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M13 10V3L4 14h7v7l9-11h-7z"
/>
</svg>
</div>
</div>
<div className="ml-4">
<h4 className="text-lg leading-6 font-medium text-gray-900">
Improve Faster
</h4>
<p className="mt-2 text-base leading-6 text-gray-500">
Stop wasting time learning topics you already know. Skip
over easy topics or delve deeper into difficult ones; the
choice is yours.
</p>
</div>
</div>
</li>
<li className="mt-10 md:mt-0">
<div className="flex">
<div className="flex-shrink-0">
<div className="flex items-center justify-center h-12 w-12 rounded-md bg-blue-500 text-white">
<svg
className="h-6 w-6"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
</svg>
</div>
</div>
<div className="ml-4">
<h4 className="text-lg leading-6 font-medium text-gray-900">
Officially Recognized
</h4>
<p className="mt-2 text-base leading-6 text-gray-500">
This guide is developed in collaboration with USACO Staff
and USACO Director Dr. Brian Dean.
</p>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
<div className="mt-16">
<ul className="md:grid md:grid-cols-2 md:col-gap-8 md:row-gap-10">
<li>
<div className="flex">
<div className="flex-shrink-0">
<div className="flex items-center justify-center h-12 w-12 rounded-md bg-blue-500 text-white">
<svg
className="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"
/>
</svg>
</div>
</div>
<div className="ml-4">
<h4 className="text-lg leading-6 font-medium text-gray-900">
Experienced Authors
</h4>
<p className="mt-2 text-base leading-6 text-gray-500">
This guide is written by top USACO contestants, including
two-time IOI winner and USACO Problemsetter{' '}
<a
href="https://github.com/bqi343"
className="underline text-blue-500"
>
Benjamin Qi
</a>
.
</p>
</div>
</div>
</li>
<li className="mt-10 md:mt-0">
<div className="flex">
<div className="flex-shrink-0">
<div className="flex items-center justify-center h-12 w-12 rounded-md bg-blue-500 text-white">
<svg
className="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M3 6l3 1m0 0l-3 9a5.002 5.002 0 006.001 0M6 7l3 9M6 7l6-2m6 2l3-1m-3 1l-3 9a5.002 5.002 0 006.001 0M18 7l3 9m-3-9l-6-2m0-2v2m0 16V5m0 16H9m3 0h3"
/>
</svg>
</div>
</div>
<div className="ml-4">
<h4 className="text-lg leading-6 font-medium text-gray-900">
Calibrated Difficulty
</h4>
<p className="mt-2 text-base leading-6 text-gray-500">
This guide is targeted towards all contestants, regardless
of their division. You'll find problems suitable for you.
</p>
</div>
</div>
</li>
<li className="mt-10 md:mt-0">
<div className="flex">
<div className="flex-shrink-0">
<div className="flex items-center justify-center h-12 w-12 rounded-md bg-blue-500 text-white">
<svg
className="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M13 10V3L4 14h7v7l9-11h-7z"
/>
</svg>
</div>
</div>
<div className="ml-4">
<h4 className="text-lg leading-6 font-medium text-gray-900">
Improve Faster
</h4>
<p className="mt-2 text-base leading-6 text-gray-500">
Stop wasting time learning topics you already know. Skip
over easy topics or delve deeper into difficult ones; the
choice is yours.
</p>
</div>
</div>
</li>
<li className="mt-10 md:mt-0">
<div className="flex">
<div className="flex-shrink-0">
<div className="flex items-center justify-center h-12 w-12 rounded-md bg-blue-500 text-white">
<svg
className="h-6 w-6"
fill="none"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" />
</svg>
</div>
</div>
<div className="ml-4">
<h4 className="text-lg leading-6 font-medium text-gray-900">
Officially Recognized
</h4>
<p className="mt-2 text-base leading-6 text-gray-500">
This guide is developed in collaboration with USACO Staff
and USACO Director Dr. Brian Dean.
</p>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
<div className="bg-blue-900">
<div className="max-w-6xl mx-auto px-4 sm:px-6 py-20 text-center">
<p className="text-xl md:text-2xl font-bold text-blue-200">
Unsure how to get started?
<br />
Overwhelmed by too many resources?
<br />
Looking to take your CP skills to the next level?
<br />
</p>
<div className="bg-blue-900">
<div className="max-w-6xl mx-auto px-4 sm:px-6 py-20 text-center">
<p className="text-xl md:text-2xl font-bold text-blue-200">
Unsure how to get started?
<br />
Overwhelmed by too many resources?
<br />
Looking to take your CP skills to the next level?
<br />
</p>
<p className="text-3xl sm:text-4xl md:text-6xl font-extrabold text-white mt-8">
This is the guide for you.
</p>
<p className="text-3xl sm:text-4xl md:text-6xl font-extrabold text-white mt-8">
This is the guide for you.
</p>
<div className="mt-8 flex justify-center">
<div className="rounded-md shadow">
<Link
to="/intro"
className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base leading-6 font-medium rounded-md text-white bg-blue-600 hover:bg-blue-500 focus:outline-none focus:border-blue-700 focus:shadow-outline-blue transition duration-150 ease-in-out md:py-4 md:text-lg md:px-10"
>
View Guide
</Link>
</div>
</div>
</div>
</div>
<div className="mt-8 flex justify-center">
<div className="rounded-md shadow">
<Link
to="/intro"
className="w-full flex items-center justify-center px-8 py-3 border border-transparent text-base leading-6 font-medium rounded-md text-white bg-blue-600 hover:bg-blue-500 focus:outline-none focus:border-blue-700 focus:shadow-outline-blue transition duration-150 ease-in-out md:py-4 md:text-lg md:px-10"
>
View Guide
</Link>
</div>
</div>
</div>
</div>
{/* Begin FAQ */}
<div className="bg-white">
<div className="max-w-screen-xl mx-auto pt-12 pb-16 sm:pt-16 sm:pb-20 px-4 sm:px-6 lg:pt-20 lg:pb-28 lg:px-8">
<h2 className="text-3xl leading-9 font-extrabold text-gray-900">
Frequently asked questions
</h2>
<div className="mt-6 border-t-2 border-gray-100 pt-10">
<dl className="md:grid md:grid-cols-2 md:gap-8">
<div>
<div>
<dt className="text-lg leading-6 font-medium text-gray-900">
Is this a Syllabus?
</dt>
<dd className="mt-2">
<p className="text-base leading-6 text-gray-500">
<b>No. This guide is NOT a syllabus.</b> USACO does not
have an official syllabus. This guide merely lists topics
that have <i>historically</i> appeared in USACO contests;
it makes no guarantees about the topics in future USACO
contests.
</p>
</dd>
</div>
<div className="mt-12">
<dt className="text-lg leading-6 font-medium text-gray-900">
How can I contribute/report a problem?
</dt>
<dd className="mt-2">
<p className="text-base leading-6 text-gray-500">
If you would like to contribute towards this guide or
report an issue, please contact Nathan Wang at{' '}
<a
className="text-blue-600 underline"
href="mailto:nathan.r.wang@gmail.com"
>
nathan.r.wang@gmail.com
</a>
.
</p>
</dd>
</div>
</div>
<div className="mt-12 md:mt-0">
<div>
<dt className="text-lg leading-6 font-medium text-gray-900">
Is this guide for Platinum contestants?
</dt>
<dd className="mt-2">
<p className="text-base leading-6 text-gray-500">
While we offer some resources that platinum contestants
may find useful, the platinum division has too many topics
for us to effectively cover. For platinum contestants, we
recommend you treat this as more of a <i>resource</i> than
a <i>guide</i>.
</p>
</dd>
</div>
<div className="mt-12">
<dt className="text-lg leading-6 font-medium text-gray-900">
How can I get help?
</dt>
<dd className="mt-2">
<p className="text-base leading-6 text-gray-500">uh.....</p>
</dd>
</div>
</div>
</dl>
</div>
</div>
</div>
{/*End FAQ*/}
</Layout>
);
{/* Begin FAQ */}
<div className="bg-white">
<div className="max-w-screen-xl mx-auto pt-12 pb-16 sm:pt-16 sm:pb-20 px-4 sm:px-6 lg:pt-20 lg:pb-28 lg:px-8">
<h2 className="text-3xl leading-9 font-extrabold text-gray-900">
Frequently asked questions
</h2>
<div className="mt-6 border-t-2 border-gray-100 pt-10">
<dl className="md:grid md:grid-cols-2 md:gap-8">
<div>
<div>
<dt className="text-lg leading-6 font-medium text-gray-900">
Is this a Syllabus?
</dt>
<dd className="mt-2">
<p className="text-base leading-6 text-gray-500">
<b>No. This guide is NOT a syllabus.</b> USACO does not
have an official syllabus. This guide merely lists topics
that have <i>historically</i> appeared in USACO contests;
it makes no guarantees about the topics in future USACO
contests.
</p>
</dd>
</div>
<div className="mt-12">
<dt className="text-lg leading-6 font-medium text-gray-900">
How can I contribute/report a problem?
</dt>
<dd className="mt-2">
<p className="text-base leading-6 text-gray-500">
If you would like to contribute towards this guide or
report an issue, please contact Nathan Wang at{' '}
<a
className="text-blue-600 underline"
href="mailto:nathan.r.wang@gmail.com"
>
nathan.r.wang@gmail.com
</a>
.
</p>
</dd>
</div>
</div>
<div className="mt-12 md:mt-0">
<div>
<dt className="text-lg leading-6 font-medium text-gray-900">
Is this guide for Platinum contestants?
</dt>
<dd className="mt-2">
<p className="text-base leading-6 text-gray-500">
While we offer some resources that platinum contestants
may find useful, the platinum division has too many topics
for us to effectively cover. For platinum contestants, we
recommend you treat this as more of a <i>resource</i> than
a <i>guide</i>.
</p>
</dd>
</div>
<div className="mt-12">
<dt className="text-lg leading-6 font-medium text-gray-900">
How can I get help?
</dt>
<dd className="mt-2">
<p className="text-base leading-6 text-gray-500">uh.....</p>
</dd>
</div>
</div>
</dl>
</div>
</div>
</div>
{/*End FAQ*/}
</Layout>
);
}

View file

@ -1,155 +1,155 @@
/*! purgecss start ignore */
/* Additional vertical padding used by kbd tag. */
.py-05 {
padding-top: 0.125rem;
padding-bottom: 0.125rem;
padding-top: 0.125rem;
padding-bottom: 0.125rem;
}
.markdown {
@apply text-gray-900 leading-normal break-words;
@apply text-gray-900 leading-normal break-words;
}
.markdown > * + * {
@apply mt-0 mb-4;
@apply mt-0 mb-4;
}
.markdown li + li {
@apply mt-1;
@apply mt-1;
}
.markdown li > p + p {
@apply mt-6;
@apply mt-6;
}
.markdown strong {
@apply font-semibold;
@apply font-semibold;
}
.markdown a {
@apply text-blue-600 font-semibold;
@apply text-blue-600 font-semibold;
}
.markdown strong a {
@apply font-bold;
@apply font-bold;
}
.markdown h1 {
@apply leading-tight border-b text-4xl font-semibold mb-4 mt-6 pb-2;
@apply leading-tight border-b text-4xl font-semibold mb-4 mt-6 pb-2;
}
.markdown h2 {
@apply leading-tight border-b text-2xl font-semibold mb-4 mt-6 pb-2;
@apply leading-tight border-b text-2xl font-semibold mb-4 mt-6 pb-2;
}
.markdown h3 {
@apply leading-snug text-lg font-semibold mb-4 mt-6;
@apply leading-snug text-lg font-semibold mb-4 mt-6;
}
.markdown h4 {
@apply leading-none text-base font-semibold mb-4 mt-6;
@apply leading-none text-base font-semibold mb-4 mt-6;
}
.markdown h5 {
@apply leading-tight text-sm font-semibold mb-4 mt-6;
@apply leading-tight text-sm font-semibold mb-4 mt-6;
}
.markdown h6 {
@apply leading-tight text-sm font-semibold text-gray-600 mb-4 mt-6;
@apply leading-tight text-sm font-semibold text-gray-600 mb-4 mt-6;
}
.markdown blockquote {
@apply text-base border-l-4 border-gray-300 pl-4 pr-4 text-gray-600;
@apply text-base border-l-4 border-gray-300 pl-4 pr-4 text-gray-600;
}
.markdown code:not([class*='language-']) {
@apply font-mono text-sm inline bg-gray-200 rounded px-1 py-05;
@apply font-mono text-sm inline bg-gray-200 rounded px-1 py-05;
}
.markdown pre {
@apply rounded;
@apply rounded;
}
.markdown pre:not([class*='language-']) {
@apply bg-gray-100 p-4;
@apply bg-gray-100 p-4;
}
.markdown pre:not([class*='language-']) code {
@apply block bg-transparent p-0 overflow-visible rounded-none;
@apply block bg-transparent p-0 overflow-visible rounded-none;
}
.markdown ul {
@apply text-base list-disc mb-4;
@apply text-base list-disc mb-4;
}
.markdown ul ul {
list-style-type: circle;
list-style-type: circle;
}
.markdown ul ul ul {
list-style-type: square;
list-style-type: square;
}
.markdown--module ul {
@apply pl-8;
@apply pl-8;
}
.markdown--syllabus ul {
@apply pl-5;
@apply pl-5;
}
.markdown p {
@apply mb-4;
@apply mb-4;
}
.markdown ul ul {
@apply mb-0;
@apply mb-0;
}
.markdown ul p {
@apply mb-0;
@apply mb-0;
}
.markdown ol {
@apply text-base pl-8 list-decimal mb-4;
@apply text-base pl-8 list-decimal mb-4;
}
.markdown kbd {
@apply text-xs inline-block rounded border px-1 py-05 align-middle font-normal font-mono shadow;
@apply text-xs inline-block rounded border px-1 py-05 align-middle font-normal font-mono shadow;
}
.markdown table {
@apply text-base border-gray-600;
@apply text-base border-gray-600;
}
.markdown th {
@apply border py-1 px-3;
@apply border py-1 px-3;
}
.markdown td {
@apply border py-1 px-3;
@apply border py-1 px-3;
}
/* Override pygments style background color. */
.markdown .highlight pre {
@apply bg-gray-100 !important;
@apply bg-gray-100 !important;
}
.markdown--module .syllabus-only {
display: none;
display: none;
}
.spoiler-body pre {
margin-left: -1rem !important;
margin-right: -1rem !important;
margin-bottom: -1rem !important;
margin-left: -1rem !important;
margin-right: -1rem !important;
margin-bottom: -1rem !important;
}
.info-block .custom-block-heading {
@apply text-sm leading-5 font-medium text-blue-800;
@apply text-sm leading-5 font-medium text-blue-800;
}
.info-block .custom-block-body {
@apply text-sm leading-5 text-blue-700 mt-2;
@apply text-sm leading-5 text-blue-700 mt-2;
}
.info-block .custom-block-body p:last-child {
@apply mb-0;
@apply mb-0;
}
/*! purgecss end ignore */

View file

@ -1,212 +1,212 @@
/*! purgecss start ignore */
code[class*='language-'],
pre[class*='language-'] {
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
color: #c3cee3;
background: #263238;
font-family: Roboto Mono, monospace;
font-size: 1em;
line-height: 1.5em;
text-align: left;
white-space: pre;
word-spacing: normal;
word-break: normal;
word-wrap: normal;
color: #c3cee3;
background: #263238;
font-family: Roboto Mono, monospace;
font-size: 1em;
line-height: 1.5em;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-moz-tab-size: 4;
-o-tab-size: 4;
tab-size: 4;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
-webkit-hyphens: none;
-moz-hyphens: none;
-ms-hyphens: none;
hyphens: none;
}
code[class*='language-']::-moz-selection,
pre[class*='language-']::-moz-selection,
code[class*='language-'] ::-moz-selection,
pre[class*='language-'] ::-moz-selection {
background: #363636;
background: #363636;
}
code[class*='language-']::selection,
pre[class*='language-']::selection,
code[class*='language-'] ::selection,
pre[class*='language-'] ::selection {
background: #363636;
background: #363636;
}
:not(pre) > code[class*='language-'] {
white-space: normal;
border-radius: 0.2em;
padding: 0.1em;
white-space: normal;
border-radius: 0.2em;
padding: 0.1em;
}
pre[class*='language-'] {
overflow: auto;
position: relative;
margin: 0.5em 0;
padding: 1.25em 1em;
overflow: auto;
position: relative;
margin: 0.5em 0;
padding: 1.25em 1em;
}
.language-css > code,
.language-sass > code,
.language-scss > code {
color: #fd9170;
color: #fd9170;
}
[class*='language-'] .namespace {
opacity: 0.7;
opacity: 0.7;
}
.token.atrule {
color: #c792ea;
color: #c792ea;
}
.token.attr-name {
color: #ffcb6b;
color: #ffcb6b;
}
.token.attr-value {
color: #c3e88d;
color: #c3e88d;
}
.token.attribute {
color: #c3e88d;
color: #c3e88d;
}
.token.boolean {
color: #c792ea;
color: #c792ea;
}
.token.builtin {
color: #ffcb6b;
color: #ffcb6b;
}
.token.cdata {
color: #80cbc4;
color: #80cbc4;
}
.token.char {
color: #80cbc4;
color: #80cbc4;
}
.token.class {
color: #ffcb6b;
color: #ffcb6b;
}
.token.class-name {
color: #f2ff00;
color: #f2ff00;
}
.token.color {
color: #f2ff00;
color: #f2ff00;
}
.token.comment {
color: #546e7a;
color: #546e7a;
}
.token.constant {
color: #c792ea;
color: #c792ea;
}
.token.deleted {
color: #f07178;
color: #f07178;
}
.token.doctype {
color: #546e7a;
color: #546e7a;
}
.token.entity {
color: #f07178;
color: #f07178;
}
.token.function {
color: #c792ea;
color: #c792ea;
}
.token.hexcode {
color: #f2ff00;
color: #f2ff00;
}
.token.id {
color: #c792ea;
font-weight: bold;
color: #c792ea;
font-weight: bold;
}
.token.important {
color: #c792ea;
font-weight: bold;
color: #c792ea;
font-weight: bold;
}
.token.inserted {
color: #80cbc4;
color: #80cbc4;
}
.token.keyword {
color: #c792ea;
font-style: italic;
color: #c792ea;
font-style: italic;
}
.token.number {
color: #fd9170;
color: #fd9170;
}
.token.operator {
color: #89ddff;
color: #89ddff;
}
.token.prolog {
color: #546e7a;
color: #546e7a;
}
.token.property {
color: #80cbc4;
color: #80cbc4;
}
.token.pseudo-class {
color: #c3e88d;
color: #c3e88d;
}
.token.pseudo-element {
color: #c3e88d;
color: #c3e88d;
}
.token.punctuation {
color: #89ddff;
color: #89ddff;
}
.token.regex {
color: #f2ff00;
color: #f2ff00;
}
.token.selector {
color: #f07178;
color: #f07178;
}
.token.string {
color: #c3e88d;
color: #c3e88d;
}
.token.symbol {
color: #c792ea;
color: #c792ea;
}
.token.tag {
color: #f07178;
color: #f07178;
}
.token.unit {
color: #f07178;
color: #f07178;
}
.token.url {
color: #fd9170;
color: #fd9170;
}
.token.variable {
color: #f07178;
color: #f07178;
}
/*! purgecss end ignore */

View file

@ -9,363 +9,363 @@ import Transition from '../components/Transition';
import { graphqlToModulesObject } from '../utils';
const renderPrerequisite = prerequisite => {
const link = prerequisite.length > 1 ? prerequisite[1] : null;
return (
<li key={prerequisite[0]}>
{link && (
<a href={link} className="text-blue-600 underline">
{prerequisite[0]}
</a>
)}
{!link && prerequisite[0]}
</li>
);
const link = prerequisite.length > 1 ? prerequisite[1] : null;
return (
<li key={prerequisite[0]}>
{link && (
<a href={link} className="text-blue-600 underline">
{prerequisite[0]}
</a>
)}
{!link && prerequisite[0]}
</li>
);
};
const Breadcrumbs = ({ division }) => (
<nav className="flex items-center text-sm leading-5 font-medium">
<Link
to="/"
className="text-gray-500 hover:text-gray-700 transition duration-150 ease-in-out"
>
Home
</Link>
<svg
className="flex-shrink-0 mx-2 h-5 w-5 text-gray-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clipRule="evenodd"
/>
</svg>
<Link
to={`/${division}`}
className="text-gray-500 hover:text-gray-700 transition duration-150 ease-in-out"
>
{divisionLabels[division]}
</Link>
<svg
className="flex-shrink-0 mx-2 h-5 w-5 text-gray-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clipRule="evenodd"
/>
</svg>
<span className="text-gray-500">Getting Started</span>
</nav>
<nav className="flex items-center text-sm leading-5 font-medium">
<Link
to="/"
className="text-gray-500 hover:text-gray-700 transition duration-150 ease-in-out"
>
Home
</Link>
<svg
className="flex-shrink-0 mx-2 h-5 w-5 text-gray-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clipRule="evenodd"
/>
</svg>
<Link
to={`/${division}`}
className="text-gray-500 hover:text-gray-700 transition duration-150 ease-in-out"
>
{divisionLabels[division]}
</Link>
<svg
className="flex-shrink-0 mx-2 h-5 w-5 text-gray-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clipRule="evenodd"
/>
</svg>
<span className="text-gray-500">Getting Started</span>
</nav>
);
const SidebarBottomButtons = () => (
<>
<div className="flex-shrink-0 border-t border-gray-200 flex">
<button className="group flex-1 flex items-center p-4 text-sm leading-5 font-medium text-gray-600 hover:text-gray-900 hover:bg-gray-50 focus:outline-none focus:bg-gray-100 transition ease-in-out duration-150">
<svg
className="mr-4 h-6 w-6 text-gray-400 group-hover:text-gray-500 group-focus:text-gray-500 transition ease-in-out duration-150"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
>
<path d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
Report an Issue
</button>
</div>
<div className="flex-shrink-0 border-t border-gray-200 flex">
<button className="group flex-1 flex items-center p-4 text-sm leading-5 font-medium text-gray-600 hover:text-gray-900 hover:bg-gray-50 focus:outline-none focus:bg-gray-100 transition ease-in-out duration-150">
<svg
className="mr-4 h-6 w-6 text-gray-400 group-hover:text-gray-500 group-focus:text-gray-500 transition ease-in-out duration-150"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
>
<path d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z" />
</svg>
Get Help
</button>
</div>
</>
<>
<div className="flex-shrink-0 border-t border-gray-200 flex">
<button className="group flex-1 flex items-center p-4 text-sm leading-5 font-medium text-gray-600 hover:text-gray-900 hover:bg-gray-50 focus:outline-none focus:bg-gray-100 transition ease-in-out duration-150">
<svg
className="mr-4 h-6 w-6 text-gray-400 group-hover:text-gray-500 group-focus:text-gray-500 transition ease-in-out duration-150"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
>
<path d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
</svg>
Report an Issue
</button>
</div>
<div className="flex-shrink-0 border-t border-gray-200 flex">
<button className="group flex-1 flex items-center p-4 text-sm leading-5 font-medium text-gray-600 hover:text-gray-900 hover:bg-gray-50 focus:outline-none focus:bg-gray-100 transition ease-in-out duration-150">
<svg
className="mr-4 h-6 w-6 text-gray-400 group-hover:text-gray-500 group-focus:text-gray-500 transition ease-in-out duration-150"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
>
<path d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z" />
</svg>
Get Help
</button>
</div>
</>
);
interface NavLink {
kind: 'link';
label: string;
href: string;
kind: 'link';
label: string;
href: string;
}
interface NavLinkGroup {
kind: 'group';
label: string;
children: NavLink[];
kind: 'group';
label: string;
children: NavLink[];
}
type NavLinkItem = NavLink | NavLinkGroup;
const SidebarNavLinks = ({ links }) => {
const renderLink = link => {
if (link.kind === 'link') {
return (
<Link
to={link.href}
className={`flex items-center px-6 py-3 text-sm leading-5 text-gray-600 hover:text-gray-900 hover:bg-gray-100 focus:outline-none focus:bg-gray-200 transition ease-in-out duration-150`}
>
{link.label}
</Link>
);
}
return (
<div className="bg-gray-100 mb-4">
<div
className={`flex items-center px-6 py-3 text-sm leading-5 font-medium text-gray-600 border-b border-gray-200`}
>
{link.label}
</div>
{link.children.map(renderLink)}
</div>
);
};
return <>{links.map(renderLink)}</>;
const renderLink = link => {
if (link.kind === 'link') {
return (
<Link
to={link.href}
className={`flex items-center px-6 py-3 text-sm leading-5 text-gray-600 hover:text-gray-900 hover:bg-gray-100 focus:outline-none focus:bg-gray-200 transition ease-in-out duration-150`}
>
{link.label}
</Link>
);
}
return (
<div className="bg-gray-100 mb-4">
<div
className={`flex items-center px-6 py-3 text-sm leading-5 font-medium text-gray-600 border-b border-gray-200`}
>
{link.label}
</div>
{link.children.map(renderLink)}
</div>
);
};
return <>{links.map(renderLink)}</>;
};
export default function Template(props) {
const { mdx, allMdx } = props.data; // data.markdownRemark holds your post data
const { body } = mdx;
const prereqs = mdx.frontmatter.prerequisites;
const division = props.pageContext.division;
const { mdx, allMdx } = props.data; // data.markdownRemark holds your post data
const { body } = mdx;
const prereqs = mdx.frontmatter.prerequisites;
const division = props.pageContext.division;
const [isMobileNavOpen, setIsMobileNavOpen] = useState(false);
const navLinks: NavLinkItem[] = React.useMemo(() => {
const modules = graphqlToModulesObject(allMdx);
const getLinks = module => {
if (module.hasOwnProperty('name')) {
return {
kind: 'group',
label: module.name,
children: module.items.map(getLinks),
};
}
if (!modules.hasOwnProperty(module)) {
throw `${module} not found!`;
}
return {
kind: 'link',
label: modules[module].frontmatter.title,
href: `/${division}/${module}`,
};
};
return ModuleOrdering[division].map(getLinks);
}, []);
const [isMobileNavOpen, setIsMobileNavOpen] = useState(false);
const navLinks: NavLinkItem[] = React.useMemo(() => {
const modules = graphqlToModulesObject(allMdx);
const getLinks = module => {
if (module.hasOwnProperty('name')) {
return {
kind: 'group',
label: module.name,
children: module.items.map(getLinks),
};
}
if (!modules.hasOwnProperty(module)) {
throw `${module} not found!`;
}
return {
kind: 'link',
label: modules[module].frontmatter.title,
href: `/${division}/${module}`,
};
};
return ModuleOrdering[division].map(getLinks);
}, []);
return (
<Layout>
<div className="h-screen flex overflow-hidden bg-white">
{/* Off-canvas menu for mobile */}
<Transition show={isMobileNavOpen}>
<div className="lg:hidden">
<div className="fixed inset-0 flex z-40">
<Transition
enter="transition-opacity ease-linear duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition-opacity ease-linear duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div
className="fixed inset-0"
onClick={() => setIsMobileNavOpen(false)}
>
<div className="absolute inset-0 bg-gray-600 opacity-75" />
</div>
</Transition>
return (
<Layout>
<div className="h-screen flex overflow-hidden bg-white">
{/* Off-canvas menu for mobile */}
<Transition show={isMobileNavOpen}>
<div className="lg:hidden">
<div className="fixed inset-0 flex z-40">
<Transition
enter="transition-opacity ease-linear duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition-opacity ease-linear duration-300"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div
className="fixed inset-0"
onClick={() => setIsMobileNavOpen(false)}
>
<div className="absolute inset-0 bg-gray-600 opacity-75" />
</div>
</Transition>
<Transition
enter="transition ease-in-out duration-300 transform"
enterFrom="-translate-x-full"
enterTo="translate-x-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="translate-x-0"
leaveTo="-translate-x-full"
>
<div className="relative flex-1 flex flex-col max-w-xs w-full bg-white">
<div className="absolute top-0 right-0 -mr-14 p-1">
<button
className="flex items-center justify-center h-12 w-12 rounded-full focus:outline-none focus:bg-gray-600"
aria-label="Close sidebar"
onClick={() => setIsMobileNavOpen(false)}
>
<svg
className="h-6 w-6 text-white"
stroke="currentColor"
fill="none"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
</div>
<div className="flex-1 h-0 pt-5 pb-4 overflow-y-auto">
<div className="flex-shrink-0 flex items-center px-4">
<img
className="h-8 w-auto"
src="https://tailwindui.com/img/logos/workflow-logo-on-white.svg"
alt="Workflow"
/>
</div>
<div className="mt-8 px-6">
<Breadcrumbs division={division} />
</div>
<nav className="mt-2">
<SidebarNavLinks links={navLinks} />
</nav>
</div>
<SidebarBottomButtons />
</div>
</Transition>
<div className="flex-shrink-0 w-14">
{/* Force sidebar to shrink to fit close icon */}
</div>
</div>
</div>
</Transition>
{/* Static sidebar for desktop */}
<div className="hidden lg:flex lg:flex-shrink-0">
<div className="flex flex-col w-64 border-r border-gray-200 bg-white">
<div className="h-0 flex-1 flex flex-col pt-5 pb-4 overflow-y-auto">
<div className="flex items-center flex-shrink-0 px-4">
<img
className="h-8 w-auto"
src="https://tailwindui.com/img/logos/workflow-logo-on-white.svg"
alt="Workflow"
/>
</div>
{/* Sidebar component, swap this element with another sidebar if you like */}
<nav className="mt-5 flex-1 bg-white">
<SidebarNavLinks links={navLinks} />
</nav>
</div>
<SidebarBottomButtons />
</div>
</div>
<div className="flex flex-col w-0 flex-1 overflow-hidden">
<div className="lg:hidden pl-1 pt-1 sm:pl-3 sm:pt-3">
<button
className="-ml-0.5 -mt-0.5 h-12 w-12 inline-flex items-center justify-center rounded-md text-gray-500 hover:text-gray-900 focus:outline-none focus:bg-gray-200 transition ease-in-out duration-150"
aria-label="Open sidebar"
onClick={() => setIsMobileNavOpen(true)}
>
<svg
className="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M4 6h16M4 12h16M4 18h16"
/>
</svg>
</button>
</div>
<main
className="flex-1 relative z-0 overflow-y-auto sm:pt-2 pb-6 focus:outline-none lg:py-6"
tabIndex={0}
>
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
<div>
<div className="hidden lg:block">
<Breadcrumbs division={division} />
</div>
<div className="lg:mt-12 mb-4">
<div className="flex-1 min-w-0">
<h1 className="text-2xl font-bold text-gray-900 sm:text-3xl">
{mdx.frontmatter.title}
</h1>
<p className={`text-gray-500`}>
Author: {mdx.frontmatter.author}
</p>
</div>
</div>
</div>
<div className="py-4">
{prereqs && (
<div className="rounded-md bg-blue-50 p-4 mb-12">
<div className="flex">
<div className="flex-shrink-0">
<svg
className="h-5 w-5 text-blue-400"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fillRule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
clipRule="evenodd"
/>
</svg>
</div>
<div className="ml-3">
<h3 className="text-sm leading-5 font-medium text-blue-800">
Prerequisites
</h3>
<div className="mt-2 text-sm leading-5 text-blue-800">
<ul className="list-disc list-inside pl-3 space-y-1">
{prereqs.map(renderPrerequisite)}
</ul>
</div>
</div>
</div>
</div>
)}
<Transition
enter="transition ease-in-out duration-300 transform"
enterFrom="-translate-x-full"
enterTo="translate-x-0"
leave="transition ease-in-out duration-300 transform"
leaveFrom="translate-x-0"
leaveTo="-translate-x-full"
>
<div className="relative flex-1 flex flex-col max-w-xs w-full bg-white">
<div className="absolute top-0 right-0 -mr-14 p-1">
<button
className="flex items-center justify-center h-12 w-12 rounded-full focus:outline-none focus:bg-gray-600"
aria-label="Close sidebar"
onClick={() => setIsMobileNavOpen(false)}
>
<svg
className="h-6 w-6 text-white"
stroke="currentColor"
fill="none"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M6 18L18 6M6 6l12 12"
/>
</svg>
</button>
</div>
<div className="flex-1 h-0 pt-5 pb-4 overflow-y-auto">
<div className="flex-shrink-0 flex items-center px-4">
<img
className="h-8 w-auto"
src="https://tailwindui.com/img/logos/workflow-logo-on-white.svg"
alt="Workflow"
/>
</div>
<div className="mt-8 px-6">
<Breadcrumbs division={division} />
</div>
<nav className="mt-2">
<SidebarNavLinks links={navLinks} />
</nav>
</div>
<SidebarBottomButtons />
</div>
</Transition>
<div className="flex-shrink-0 w-14">
{/* Force sidebar to shrink to fit close icon */}
</div>
</div>
</div>
</Transition>
{/* Static sidebar for desktop */}
<div className="hidden lg:flex lg:flex-shrink-0">
<div className="flex flex-col w-64 border-r border-gray-200 bg-white">
<div className="h-0 flex-1 flex flex-col pt-5 pb-4 overflow-y-auto">
<div className="flex items-center flex-shrink-0 px-4">
<img
className="h-8 w-auto"
src="https://tailwindui.com/img/logos/workflow-logo-on-white.svg"
alt="Workflow"
/>
</div>
{/* Sidebar component, swap this element with another sidebar if you like */}
<nav className="mt-5 flex-1 bg-white">
<SidebarNavLinks links={navLinks} />
</nav>
</div>
<SidebarBottomButtons />
</div>
</div>
<div className="flex flex-col w-0 flex-1 overflow-hidden">
<div className="lg:hidden pl-1 pt-1 sm:pl-3 sm:pt-3">
<button
className="-ml-0.5 -mt-0.5 h-12 w-12 inline-flex items-center justify-center rounded-md text-gray-500 hover:text-gray-900 focus:outline-none focus:bg-gray-200 transition ease-in-out duration-150"
aria-label="Open sidebar"
onClick={() => setIsMobileNavOpen(true)}
>
<svg
className="h-6 w-6"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M4 6h16M4 12h16M4 18h16"
/>
</svg>
</button>
</div>
<main
className="flex-1 relative z-0 overflow-y-auto sm:pt-2 pb-6 focus:outline-none lg:py-6"
tabIndex={0}
>
<div className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8">
<div>
<div className="hidden lg:block">
<Breadcrumbs division={division} />
</div>
<div className="lg:mt-12 mb-4">
<div className="flex-1 min-w-0">
<h1 className="text-2xl font-bold text-gray-900 sm:text-3xl">
{mdx.frontmatter.title}
</h1>
<p className={`text-gray-500`}>
Author: {mdx.frontmatter.author}
</p>
</div>
</div>
</div>
<div className="py-4">
{prereqs && (
<div className="rounded-md bg-blue-50 p-4 mb-12">
<div className="flex">
<div className="flex-shrink-0">
<svg
className="h-5 w-5 text-blue-400"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fillRule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
clipRule="evenodd"
/>
</svg>
</div>
<div className="ml-3">
<h3 className="text-sm leading-5 font-medium text-blue-800">
Prerequisites
</h3>
<div className="mt-2 text-sm leading-5 text-blue-800">
<ul className="list-disc list-inside pl-3 space-y-1">
{prereqs.map(renderPrerequisite)}
</ul>
</div>
</div>
</div>
</div>
)}
<Markdown body={body} className="markdown--module" />
</div>
</div>
</main>
</div>
</div>
</Layout>
);
<Markdown body={body} className="markdown--module" />
</div>
</div>
</main>
</div>
</div>
</Layout>
);
}
export const pageQuery = graphql`
query($id: String!) {
mdx(frontmatter: { id: { eq: $id } }) {
body
frontmatter {
title
author
id
prerequisites
}
}
allMdx {
edges {
node {
frontmatter {
title
id
}
}
}
}
}
query($id: String!) {
mdx(frontmatter: { id: { eq: $id } }) {
body
frontmatter {
title
author
id
prerequisites
}
}
allMdx {
edges {
node {
frontmatter {
title
id
}
}
}
}
}
`;

View file

@ -8,50 +8,50 @@ import { getModule, graphqlToModulesObject } from '../utils';
import SyllabusModule from '../components/SyllabusModule';
const renderModule = (node, idx, parentIdx = -1) => {
if (node.hasOwnProperty('items')) {
return node.items.map((x, i) => renderModule(x, i, idx));
}
if (node.hasOwnProperty('items')) {
return node.items.map((x, i) => renderModule(x, i, idx));
}
const data = node.frontmatter;
if (!data.title) return;
const data = node.frontmatter;
if (!data.title) return;
return (
<SyllabusModule
title={`${parentIdx !== -1 ? parentIdx + 1 + '.' : ''}${idx + 1}. ${
data.title
}`}
url={node.slug}
key={node.slug}
problems={data.problems}
prerequisites={data.prerequisites}
author={data.author}
>
{data.description}
</SyllabusModule>
);
return (
<SyllabusModule
title={`${parentIdx !== -1 ? parentIdx + 1 + '.' : ''}${idx + 1}. ${
data.title
}`}
url={node.slug}
key={node.slug}
problems={data.problems}
prerequisites={data.prerequisites}
author={data.author}
>
{data.description}
</SyllabusModule>
);
};
export default function Template(props) {
const data = props.data;
const data = props.data;
const allModules = graphqlToModulesObject(data.modules);
const allModules = graphqlToModulesObject(data.modules);
const [selectedDivision, setSelectedDivision] = React.useState(
props.pageContext.division
);
const colors = {
intro: 'blue',
general: 'pink',
bronze: 'orange',
silver: 'teal',
gold: 'yellow',
plat: 'purple',
};
const color = colors[selectedDivision];
const module = getModule(allModules, selectedDivision);
const [selectedDivision, setSelectedDivision] = React.useState(
props.pageContext.division
);
const colors = {
intro: 'blue',
general: 'pink',
bronze: 'orange',
silver: 'teal',
gold: 'yellow',
plat: 'purple',
};
const color = colors[selectedDivision];
const module = getModule(allModules, selectedDivision);
// for purgecss, we have to list all the classes that are dynamically generated...
/*
// for purgecss, we have to list all the classes that are dynamically generated...
/*
bg-blue-500 hover:bg-blue-50 hover:text-blue-600 focus:shadow-outline-blue
bg-pink-500 hover:bg-pink-50 hover:text-pink-600 focus:shadow-outline-pink
bg-orange-500 hover:bg-orange-50 hover:text-orange-600 focus:shadow-outline-orange
@ -65,230 +65,230 @@ export default function Template(props) {
border-yellow-500 text-yellow-600 focus:text-yellow-800 focus:border-yellow-700 border-yellow-300 focus:border-yellow-300 text-yellow-500 text-yellow-300 bg-yellow-600
border-purple-500 text-purple-600 focus:text-purple-800 focus:border-purple-700 border-purple-300 focus:border-purple-300 text-purple-500 text-purple-300 bg-purple-600
*/
// alternatively we can just not dynamically generate classes, but that seems more tedious.
// alternatively we can just not dynamically generate classes, but that seems more tedious.
const selectedTabClasses = `flex-1 py-4 px-1 text-center border-b-2 border-${color}-500 font-bold text-lg leading-5 text-${color}-600 focus:outline-none focus:text-${color}-800 focus:border-${color}-700`,
unselectedTabClasses = `flex-1 py-4 px-1 text-center border-b-2 border-transparent font-bold text-lg leading-5 text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300`;
const selectedTabClasses = `flex-1 py-4 px-1 text-center border-b-2 border-${color}-500 font-bold text-lg leading-5 text-${color}-600 focus:outline-none focus:text-${color}-800 focus:border-${color}-700`,
unselectedTabClasses = `flex-1 py-4 px-1 text-center border-b-2 border-transparent font-bold text-lg leading-5 text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300`;
const handleDivisionChange = d => {
setSelectedDivision(d);
window.history.pushState(null, '', `/${d}/`);
};
const handleDivisionChange = d => {
setSelectedDivision(d);
window.history.pushState(null, '', `/${d}/`);
};
return (
<Layout>
<SEO title="Home" />
return (
<Layout>
<SEO title="Home" />
<div className="min-h-screen bg-gray-50">
{/* Begin Hero Section */}
<div
className={`relative bg-${color}-600 overflow-hidden transition duration-300 pb-48`}
>
<div className="hidden sm:block sm:absolute sm:inset-y-0 sm:h-full sm:w-full">
<div className="relative h-full max-w-screen-xl mx-auto">
<svg
className="absolute right-full transform translate-y-1/4 translate-x-1/4 lg:translate-x-1/2"
width={404}
height={784}
fill="none"
viewBox="0 0 404 784"
>
<defs>
<pattern
id="f210dbf6-a58d-4871-961e-36d5016a0f49"
x={0}
y={0}
width={20}
height={20}
patternUnits="userSpaceOnUse"
>
<rect
x={0}
y={0}
width={4}
height={4}
className={`text-${color}-500 transition duration-300`}
fill="currentColor"
/>
</pattern>
</defs>
<rect
width={404}
height={784}
fill="url(#f210dbf6-a58d-4871-961e-36d5016a0f49)"
/>
</svg>
<svg
className="absolute left-full transform -translate-y-3/4 -translate-x-1/4 md:-translate-y-1/2 lg:-translate-x-1/2"
width={404}
height={784}
fill="none"
viewBox="0 0 404 784"
>
<defs>
<pattern
id="5d0dd344-b041-4d26-bec4-8d33ea57ec9b"
x={0}
y={0}
width={20}
height={20}
patternUnits="userSpaceOnUse"
>
<rect
x={0}
y={0}
width={4}
height={4}
className={`text-${color}-500 transition duration-300`}
fill="currentColor"
/>
</pattern>
</defs>
<rect
width={404}
height={784}
fill="url(#5d0dd344-b041-4d26-bec4-8d33ea57ec9b)"
/>
</svg>
</div>
</div>
<div className="relative pt-6 pb-12 sm:pb-16 md:pb-20 lg:pb-28 xl:pb-32">
<div className="mt-10 mx-auto max-w-screen-xl px-4 sm:mt-12 sm:px-6 md:mt-16 lg:mt-20 xl:mt-28">
<div className="text-center">
<h2 className="text-4xl tracking-tight leading-10 font-extrabold text-white sm:text-5xl sm:leading-none md:text-6xl">
USACO Guide
</h2>
<p
className={`mt-3 max-w-md mx-auto text-base text-${color}-300 sm:text-lg md:mt-5 md:text-xl md:max-w-3xl`}
>
A collection of curated, high-quality resources to take you
from Bronze to Platinum.
</p>
<div className="mt-5 max-w-md mx-auto sm:flex sm:justify-center md:mt-8">
<div className="rounded-md shadow">
<Link
to="/"
className={`w-full flex items-center justify-center px-8 py-3 border border-transparent text-base leading-6 font-medium rounded-md text-white bg-${color}-500 hover:bg-${color}-50 hover:text-${color}-600 focus:outline-none focus:shadow-outline-${color} transition duration-300 ease-in-out md:py-4 md:text-lg md:px-10`}
>
About This Guide
</Link>
</div>
</div>
</div>
</div>
</div>
</div>
{/* End Hero Section */}
<div className="min-h-screen bg-gray-50">
{/* Begin Hero Section */}
<div
className={`relative bg-${color}-600 overflow-hidden transition duration-300 pb-48`}
>
<div className="hidden sm:block sm:absolute sm:inset-y-0 sm:h-full sm:w-full">
<div className="relative h-full max-w-screen-xl mx-auto">
<svg
className="absolute right-full transform translate-y-1/4 translate-x-1/4 lg:translate-x-1/2"
width={404}
height={784}
fill="none"
viewBox="0 0 404 784"
>
<defs>
<pattern
id="f210dbf6-a58d-4871-961e-36d5016a0f49"
x={0}
y={0}
width={20}
height={20}
patternUnits="userSpaceOnUse"
>
<rect
x={0}
y={0}
width={4}
height={4}
className={`text-${color}-500 transition duration-300`}
fill="currentColor"
/>
</pattern>
</defs>
<rect
width={404}
height={784}
fill="url(#f210dbf6-a58d-4871-961e-36d5016a0f49)"
/>
</svg>
<svg
className="absolute left-full transform -translate-y-3/4 -translate-x-1/4 md:-translate-y-1/2 lg:-translate-x-1/2"
width={404}
height={784}
fill="none"
viewBox="0 0 404 784"
>
<defs>
<pattern
id="5d0dd344-b041-4d26-bec4-8d33ea57ec9b"
x={0}
y={0}
width={20}
height={20}
patternUnits="userSpaceOnUse"
>
<rect
x={0}
y={0}
width={4}
height={4}
className={`text-${color}-500 transition duration-300`}
fill="currentColor"
/>
</pattern>
</defs>
<rect
width={404}
height={784}
fill="url(#5d0dd344-b041-4d26-bec4-8d33ea57ec9b)"
/>
</svg>
</div>
</div>
<div className="relative pt-6 pb-12 sm:pb-16 md:pb-20 lg:pb-28 xl:pb-32">
<div className="mt-10 mx-auto max-w-screen-xl px-4 sm:mt-12 sm:px-6 md:mt-16 lg:mt-20 xl:mt-28">
<div className="text-center">
<h2 className="text-4xl tracking-tight leading-10 font-extrabold text-white sm:text-5xl sm:leading-none md:text-6xl">
USACO Guide
</h2>
<p
className={`mt-3 max-w-md mx-auto text-base text-${color}-300 sm:text-lg md:mt-5 md:text-xl md:max-w-3xl`}
>
A collection of curated, high-quality resources to take you
from Bronze to Platinum.
</p>
<div className="mt-5 max-w-md mx-auto sm:flex sm:justify-center md:mt-8">
<div className="rounded-md shadow">
<Link
to="/"
className={`w-full flex items-center justify-center px-8 py-3 border border-transparent text-base leading-6 font-medium rounded-md text-white bg-${color}-500 hover:bg-${color}-50 hover:text-${color}-600 focus:outline-none focus:shadow-outline-${color} transition duration-300 ease-in-out md:py-4 md:text-lg md:px-10`}
>
About This Guide
</Link>
</div>
</div>
</div>
</div>
</div>
</div>
{/* End Hero Section */}
<div className="pb-8" id="content">
<div className="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 pb-4">
<div
className="mb-8 bg-white shadow-md rounded-lg relative"
style={{ marginTop: '-12rem' }}
>
<div className="sm:hidden">
<select
aria-label="Selected tab"
className="form-select block w-full"
onChange={e => handleDivisionChange(e.target.value)}
value={selectedDivision}
>
{divisions.map(division => (
<option key={division} value={division}>
{divisionLabels[division]}
</option>
))}
</select>
</div>
<div className="hidden sm:block border-b border-gray-200">
<nav className="flex -mb-px">
{divisions.map(division => (
<a
key={division}
href={`/${division}`}
onClick={e => {
e.preventDefault();
handleDivisionChange(division);
}}
className={
selectedDivision === division
? selectedTabClasses
: unselectedTabClasses
}
>
{divisionLabels[division]}
</a>
))}
</nav>
</div>
<div className="pb-8" id="content">
<div className="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8 pb-4">
<div
className="mb-8 bg-white shadow-md rounded-lg relative"
style={{ marginTop: '-12rem' }}
>
<div className="sm:hidden">
<select
aria-label="Selected tab"
className="form-select block w-full"
onChange={e => handleDivisionChange(e.target.value)}
value={selectedDivision}
>
{divisions.map(division => (
<option key={division} value={division}>
{divisionLabels[division]}
</option>
))}
</select>
</div>
<div className="hidden sm:block border-b border-gray-200">
<nav className="flex -mb-px">
{divisions.map(division => (
<a
key={division}
href={`/${division}`}
onClick={e => {
e.preventDefault();
handleDivisionChange(division);
}}
className={
selectedDivision === division
? selectedTabClasses
: unselectedTabClasses
}
>
{divisionLabels[division]}
</a>
))}
</nav>
</div>
<ol className="list-inside py-8 px-8 text-lg space-y-1">
{module.map((m, idx) => {
if (m.hasOwnProperty('items')) {
return (
<li key={m.name}>
<span className="inline-block w-4 text-right">
{idx + 1}.{' '}
</span>
<span className="ml-2">{m.name}</span>
<ol className="list-inside px-6 text-lg space-y-1 mb-2">
{m.items.map((m, idx2) => (
<li key={m.slug}>
<span className="inline-block w-8 text-right">
{idx + 1}.{idx2 + 1}.{' '}
</span>
<Link
className="ml-2 text-blue-600 underline"
to={m.slug}
>
{m.frontmatter.title}
</Link>
</li>
))}
</ol>
</li>
);
}
return (
<li key={m.frontmatter.id}>
<span className="inline-block w-4 text-right">
{idx + 1}.{' '}
</span>
<Link
className="ml-2 text-blue-600 underline"
to={m.slug}
>
{m.frontmatter.title}
</Link>
</li>
);
})}
</ol>
</div>
<ol className="list-inside py-8 px-8 text-lg space-y-1">
{module.map((m, idx) => {
if (m.hasOwnProperty('items')) {
return (
<li key={m.name}>
<span className="inline-block w-4 text-right">
{idx + 1}.{' '}
</span>
<span className="ml-2">{m.name}</span>
<ol className="list-inside px-6 text-lg space-y-1 mb-2">
{m.items.map((m, idx2) => (
<li key={m.slug}>
<span className="inline-block w-8 text-right">
{idx + 1}.{idx2 + 1}.{' '}
</span>
<Link
className="ml-2 text-blue-600 underline"
to={m.slug}
>
{m.frontmatter.title}
</Link>
</li>
))}
</ol>
</li>
);
}
return (
<li key={m.frontmatter.id}>
<span className="inline-block w-4 text-right">
{idx + 1}.{' '}
</span>
<Link
className="ml-2 text-blue-600 underline"
to={m.slug}
>
{m.frontmatter.title}
</Link>
</li>
);
})}
</ol>
</div>
{module.map((x, idx) => renderModule(x, idx))}
</div>
</div>
</div>
</Layout>
);
{module.map((x, idx) => renderModule(x, idx))}
</div>
</div>
</div>
</Layout>
);
}
export const pageQuery = graphql`
query {
modules: allMdx {
edges {
node {
id
frontmatter {
title
id
author
problems
prerequisites
description
}
}
}
}
}
query {
modules: allMdx {
edges {
node {
id
frontmatter {
title
id
author
problems
prerequisites
description
}
}
}
}
}
`;

View file

@ -1,36 +1,36 @@
import ModuleOrdering from '../content/ordering';
export const getModule = (allModules, division) => {
return ModuleOrdering[division].map(k => {
// rip spaghetti code, clean this up
if (typeof k === 'object') {
return {
name: k.name,
items: k.items.map(k2 => {
if (!allModules.hasOwnProperty(k2)) {
throw 'Module not found: ' + k2;
}
return {
...allModules[k2],
slug: `/${division}/${allModules[k2].frontmatter.id}`,
};
}),
};
} else {
if (!allModules.hasOwnProperty(k)) {
throw 'Module not found: ' + k;
}
return {
...allModules[k],
slug: `/${division}/${allModules[k].frontmatter.id}`,
};
}
});
return ModuleOrdering[division].map(k => {
// rip spaghetti code, clean this up
if (typeof k === 'object') {
return {
name: k.name,
items: k.items.map(k2 => {
if (!allModules.hasOwnProperty(k2)) {
throw 'Module not found: ' + k2;
}
return {
...allModules[k2],
slug: `/${division}/${allModules[k2].frontmatter.id}`,
};
}),
};
} else {
if (!allModules.hasOwnProperty(k)) {
throw 'Module not found: ' + k;
}
return {
...allModules[k],
slug: `/${division}/${allModules[k].frontmatter.id}`,
};
}
});
};
export const graphqlToModulesObject = allMdx => {
return allMdx.edges.reduce((acc, cur) => {
acc[cur.node.frontmatter.id] = cur.node;
return acc;
}, {});
return allMdx.edges.reduce((acc, cur) => {
acc[cur.node.frontmatter.id] = cur.node;
return acc;
}, {});
};

View file

@ -1,6 +1,6 @@
module.exports = {
plugins: [require('@tailwindcss/ui')],
purge: {
content: ['./src/**/*.js', './src/**/*.ts', './src/**/*.tsx'],
},
plugins: [require('@tailwindcss/ui')],
purge: {
content: ['./src/**/*.js', './src/**/*.ts', './src/**/*.tsx'],
},
};