commit a22c8828b205ec0cab8fd7d69a8420b2729e5529 Author: Max Date: Mon Apr 21 21:05:52 2025 +0200 Create template diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..da96190 --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +client/.vite +client/dist diff --git a/README.md b/README.md new file mode 100644 index 0000000..cb7c6bc --- /dev/null +++ b/README.md @@ -0,0 +1,145 @@ +# React Template with Vite and Deno + +This is a GitHub template project to set up a [React](https://react.dev/) app +with TypeScript running on [Deno](https://deno.com). It uses +[Vite](https://vite.dev) as the dev server and an [oak](https://jsr.io/@oak/oak) +http server on the backend to serve the built project. + +## Features + +- React with TypeScript on the frontend +- Vite for the development server +- Deno for server-side JavaScript/TypeScript +- Oak framework for building web applications +- Static file serving +- Router setup + +## Getting Started + +### Prerequisites + +To run this app, you will need to have [Deno](https://docs.deno.com/runtime/) +installed. + +### Installation + +1. Create a new repository using this template. From the repository page, click + the "Use this template" button in the top right hand of the page: + +Use this template button + +2. Use the Owner dropdown menu to select the account you want to own the + repository and set the repository name and visibility. + +3. Clone the repository created to your local machine. + +```sh +git clone https://github.com/your-username/your-repo-name.git +cd your-repo-name +``` + +> For a step by step guide to using a GitHub template +> [follow this walkthrough](https://docs.github.com/en/repositories/creating-and-managing-repositories/creating-a-repository-from-a-template) + +## Install the dependencies + +To install the dependencies for the frontend and backend, run the following +command: + +```sh +deno install +``` + +## Run the dev server with vite + +The app uses a Vite dev server to run in development mode. To start the dev +server, run the following command: + +```sh +deno run dev +``` + +## Build the app + +To build the app for production, run the following command: + +```sh +deno run build +``` + +## Run the backend server + +The backend server uses Deno and the Oak framework to serve the built React app. +To start the backend server, run the following command: + +```sh +deno run serve +``` + +## Running Tests + +To run the tests, use the following command: + +```sh +deno test -A +``` + +## Project Structure + +```sh +. +├── client +│ ├── dist +│ ├── public +│ └── src +│ ├── App.tsx +│ └── main.tsx +└── server + ├── main.ts + ├── main_test.ts + └── util + └── routeStaticFilesFrom.ts +``` + +- `App.tsx`: The main React component +- `main.tsx`: The entry point for the React app +- `main.ts`: The entry point for the Deno server +- `main_test.ts`: The test file for the Deno server +- `routeStaticFilesFrom.ts`: A utility function to serve static files +- `dist`: The output directory for the built React app +- `public`: The public directory for the React app + +## Points of note + +The React app is contained in the `client` directory. This is also where Vite +will install its dependencies and build the app. + +There is a `vite.config.ts` file in the root of the project that configures Vite +to build the app in the `client/dist` directory and serve the app on port 3000. + +The `deno.json` file contains the tasks to run the dev server, build the app, +and serve the app, along with the dependencies and the compiler configuration +required to use JSX and React. + +The Deno server is contained in the `server` directory. The server serves the +built React app from the `client/dist` directory and listens on port 8000. This +is what should be used in production. + +## Deploying + +You can deploy the app with [Deno Deploy](https://dash.deno.com/new_project). + +1. Link your github account +2. Select the repository +3. Give the project a name +4. Set the "Build Step" to `deno task build` +5. Set the entry point to `./server/main.ts` +6. Click 'deploy project' + +## Contributing + +Contributions are welcome! Please open an issue or submit a pull request. + +## License + +This project is licensed under the MIT License. diff --git a/client/index.html b/client/index.html new file mode 100644 index 0000000..e0d1c84 --- /dev/null +++ b/client/index.html @@ -0,0 +1,13 @@ + + + + + + + Vite + React + TS + + +
+ + + diff --git a/client/public/react.svg b/client/public/react.svg new file mode 100644 index 0000000..6c87de9 --- /dev/null +++ b/client/public/react.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/client/public/vite.svg b/client/public/vite.svg new file mode 100644 index 0000000..de4aedd --- /dev/null +++ b/client/public/vite.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/client/src/App.css b/client/src/App.css new file mode 100644 index 0000000..9013b49 --- /dev/null +++ b/client/src/App.css @@ -0,0 +1,46 @@ +#root { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +.logo { + height: 6em; + padding: 1.5em; + will-change: filter; + transition: filter 300ms; +} +.logo:hover { + filter: drop-shadow(0 0 2em #646cffaa); +} +.logo.react:hover { + filter: drop-shadow(0 0 2em #61dafbaa); +} + +@keyframes logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} + +@media (prefers-reduced-motion: no-preference) { + a:nth-of-type(2) .logo { + animation: logo-spin infinite 20s linear; + } +} + +.card { + padding: 2em; +} + +.read-the-docs { + color: #888; +} + +.dinosaur { + display: block; +} \ No newline at end of file diff --git a/client/src/App.tsx b/client/src/App.tsx new file mode 100644 index 0000000..06bc02c --- /dev/null +++ b/client/src/App.tsx @@ -0,0 +1,17 @@ +import { BrowserRouter, Route, Routes } from "react-router-dom"; +import Index from "./pages/Index.tsx"; +import Dinosaur from "./pages/Dinosaur.tsx"; +import "./App.css"; + +function App() { + return ( + + + } /> + } /> + + + ); +} + +export default App; diff --git a/client/src/index.css b/client/src/index.css new file mode 100644 index 0000000..6119ad9 --- /dev/null +++ b/client/src/index.css @@ -0,0 +1,68 @@ +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/client/src/main.tsx b/client/src/main.tsx new file mode 100644 index 0000000..eff7ccc --- /dev/null +++ b/client/src/main.tsx @@ -0,0 +1,10 @@ +import { StrictMode } from "react"; +import { createRoot } from "react-dom/client"; +import "./index.css"; +import App from "./App.tsx"; + +createRoot(document.getElementById("root")!).render( + + + , +); diff --git a/client/src/pages/Dinosaur.tsx b/client/src/pages/Dinosaur.tsx new file mode 100644 index 0000000..6facc93 --- /dev/null +++ b/client/src/pages/Dinosaur.tsx @@ -0,0 +1,24 @@ +import { useEffect, useState } from "react"; +import { Link, useParams } from "react-router-dom"; +import { Dino } from "../types"; + +export default function Dinosaur() { + const { selectedDinosaur } = useParams(); + const [dinosaur, setDino] = useState({ name: "", description: "" }); + + useEffect(() => { + (async () => { + const resp = await fetch(`/api/dinosaurs/${selectedDinosaur}`); + const dino = await resp.json() as Dino; + setDino(dino); + })(); + }, [selectedDinosaur]); + + return ( +
+

{dinosaur.name}

+

{dinosaur.description}

+ 🠠 Back to all dinosaurs +
+ ); +} diff --git a/client/src/pages/Index.tsx b/client/src/pages/Index.tsx new file mode 100644 index 0000000..93999a7 --- /dev/null +++ b/client/src/pages/Index.tsx @@ -0,0 +1,33 @@ +import { useEffect, useState } from "react"; +import { Link } from "react-router-dom"; +import { Dino } from "../types.ts"; + +export default function Index() { + const [dinosaurs, setDinosaurs] = useState([]); + + useEffect(() => { + (async () => { + const response = await fetch(`/api/dinosaurs/`); + const allDinosaurs = await response.json() as Dino[]; + setDinosaurs(allDinosaurs); + })(); + }, []); + + return ( +
+

Welcome to the Dinosaur app

+

Click on a dinosaur below to learn more.

+ {dinosaurs.map((dinosaur: Dino) => { + return ( + + {dinosaur.name} + + ); + })} +
+ ); +} diff --git a/client/src/types.ts b/client/src/types.ts new file mode 100644 index 0000000..fb5cdca --- /dev/null +++ b/client/src/types.ts @@ -0,0 +1 @@ +export type Dino = { name: string; description: string }; \ No newline at end of file diff --git a/client/src/vite-env.d.ts b/client/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/client/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/deno.json b/deno.json new file mode 100644 index 0000000..c1b412a --- /dev/null +++ b/deno.json @@ -0,0 +1,34 @@ +{ + "tasks": { + "dev": "deno run -A --node-modules-dir=auto npm:vite & deno run server:start", + "build": "deno run -A --node-modules-dir=auto npm:vite build", + "server:start": "deno run -A --node-modules-dir --watch ./server/main.ts", + "serve": "deno run build && deno run server:start" + }, + "imports": { + "@deno/vite-plugin": "npm:@deno/vite-plugin@^1.0.0", + "@oak/oak": "jsr:@oak/oak@^17.1.3", + "@std/assert": "jsr:@std/assert@1", + "@tajpouria/cors": "jsr:@tajpouria/cors@^1.2.1", + "@types/react": "npm:@types/react@^18.3.12", + "@vitejs/plugin-react": "npm:@vitejs/plugin-react@^4.3.3", + "react": "npm:react@^18.3.1", + "react-dom": "npm:react-dom@^18.3.1", + "react-router-dom": "npm:react-router-dom@^7.5.1", + "vite": "npm:vite@^5.4.11" + }, + "compilerOptions": { + "types": [ + "react", + "react-dom", + "@types/react" + ], + "lib": [ + "dom", + "dom.iterable", + "deno.ns" + ], + "jsx": "react-jsx", + "jsxImportSource": "react" + } +} diff --git a/deno.lock b/deno.lock new file mode 100644 index 0000000..d44895e --- /dev/null +++ b/deno.lock @@ -0,0 +1,698 @@ +{ + "version": "4", + "specifiers": { + "jsr:@oak/commons@1": "1.0.0", + "jsr:@oak/oak@*": "17.1.3", + "jsr:@oak/oak@^17.1.3": "17.1.3", + "jsr:@std/assert@*": "1.0.8", + "jsr:@std/assert@1": "1.0.8", + "jsr:@std/assert@^1.0.8": "1.0.8", + "jsr:@std/bytes@1": "1.0.4", + "jsr:@std/bytes@^1.0.2": "1.0.4", + "jsr:@std/crypto@1": "1.0.3", + "jsr:@std/encoding@1": "1.0.5", + "jsr:@std/encoding@^1.0.5": "1.0.5", + "jsr:@std/expect@*": "1.0.8", + "jsr:@std/http@1": "1.0.10", + "jsr:@std/internal@^1.0.5": "1.0.5", + "jsr:@std/io@0.224": "0.224.9", + "jsr:@std/media-types@1": "1.1.0", + "jsr:@std/path@1": "1.0.8", + "jsr:@std/testing@*": "1.0.5", + "jsr:@tajpouria/cors@^1.2.1": "1.2.1", + "npm:@deno/vite-plugin@1": "1.0.0_vite@5.4.11__@types+node@22.5.4_@types+node@22.5.4", + "npm:@types/node@*": "22.5.4", + "npm:@types/react@^18.3.12": "18.3.12", + "npm:@vitejs/plugin-react@^4.3.3": "4.3.3_vite@5.4.11__@types+node@22.5.4_@babel+core@7.26.0_@types+node@22.5.4", + "npm:path-to-regexp@6.2.1": "6.2.1", + "npm:react-dom@^18.3.1": "18.3.1_react@18.3.1", + "npm:react-router-dom@^7.5.1": "7.5.1_react@18.3.1_react-dom@18.3.1__react@18.3.1", + "npm:react@^18.3.1": "18.3.1", + "npm:vite@*": "5.4.11_@types+node@22.5.4", + "npm:vite@^5.4.11": "5.4.11_@types+node@22.5.4" + }, + "jsr": { + "@oak/commons@1.0.0": { + "integrity": "49805b55603c3627a9d6235c0655aa2b6222d3036b3a13ff0380c16368f607ac", + "dependencies": [ + "jsr:@std/assert@1", + "jsr:@std/bytes@1", + "jsr:@std/crypto", + "jsr:@std/encoding@1", + "jsr:@std/http", + "jsr:@std/media-types" + ] + }, + "@oak/oak@17.1.3": { + "integrity": "d89296c22db91681dd3a2a1e1fd14e258d0d5a9654de55637aee5b661c159f33", + "dependencies": [ + "jsr:@oak/commons", + "jsr:@std/assert@1", + "jsr:@std/bytes@1", + "jsr:@std/crypto", + "jsr:@std/http", + "jsr:@std/io", + "jsr:@std/media-types", + "jsr:@std/path", + "npm:path-to-regexp" + ] + }, + "@std/assert@1.0.8": { + "integrity": "ebe0bd7eb488ee39686f77003992f389a06c3da1bbd8022184804852b2fa641b", + "dependencies": [ + "jsr:@std/internal" + ] + }, + "@std/bytes@1.0.4": { + "integrity": "11a0debe522707c95c7b7ef89b478c13fb1583a7cfb9a85674cd2cc2e3a28abc" + }, + "@std/crypto@1.0.3": { + "integrity": "a2a32f51ddef632d299e3879cd027c630dcd4d1d9a5285d6e6788072f4e51e7f" + }, + "@std/encoding@1.0.5": { + "integrity": "ecf363d4fc25bd85bd915ff6733a7e79b67e0e7806334af15f4645c569fefc04" + }, + "@std/expect@1.0.8": { + "integrity": "27e40d8f3aefb372fc6a703fb0b69e34560e72a2f78705178babdffa00119a5f", + "dependencies": [ + "jsr:@std/assert@^1.0.8", + "jsr:@std/internal" + ] + }, + "@std/http@1.0.10": { + "integrity": "4e32d11493ab04e3ef09f104f0cb9beb4228b1d4b47c5469573c2c294c0d3692", + "dependencies": [ + "jsr:@std/encoding@^1.0.5" + ] + }, + "@std/internal@1.0.5": { + "integrity": "54a546004f769c1ac9e025abd15a76b6671ddc9687e2313b67376125650dc7ba" + }, + "@std/io@0.224.9": { + "integrity": "4414664b6926f665102e73c969cfda06d2c4c59bd5d0c603fd4f1b1c840d6ee3", + "dependencies": [ + "jsr:@std/bytes@^1.0.2" + ] + }, + "@std/media-types@1.1.0": { + "integrity": "c9d093f0c05c3512932b330e3cc1fe1d627b301db33a4c2c2185c02471d6eaa4" + }, + "@std/path@1.0.8": { + "integrity": "548fa456bb6a04d3c1a1e7477986b6cffbce95102d0bb447c67c4ee70e0364be" + }, + "@std/testing@1.0.5": { + "integrity": "6e693cbec94c81a1ad3df668685c7ba8e20742bb10305bc7137faa5cf16d2ec4", + "dependencies": [ + "jsr:@std/assert@^1.0.8", + "jsr:@std/internal" + ] + }, + "@tajpouria/cors@1.2.1": { + "integrity": "eca42e4fb7cb3906ef0ee3d1e565dd6bb4632ccd8e70a95cf4279759743328f0" + } + }, + "npm": { + "@ampproject/remapping@2.3.0": { + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dependencies": [ + "@jridgewell/gen-mapping", + "@jridgewell/trace-mapping" + ] + }, + "@babel/code-frame@7.26.2": { + "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", + "dependencies": [ + "@babel/helper-validator-identifier", + "js-tokens", + "picocolors" + ] + }, + "@babel/compat-data@7.26.2": { + "integrity": "sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==" + }, + "@babel/core@7.26.0": { + "integrity": "sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==", + "dependencies": [ + "@ampproject/remapping", + "@babel/code-frame", + "@babel/generator", + "@babel/helper-compilation-targets", + "@babel/helper-module-transforms", + "@babel/helpers", + "@babel/parser", + "@babel/template", + "@babel/traverse", + "@babel/types", + "convert-source-map", + "debug", + "gensync", + "json5", + "semver" + ] + }, + "@babel/generator@7.26.2": { + "integrity": "sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==", + "dependencies": [ + "@babel/parser", + "@babel/types", + "@jridgewell/gen-mapping", + "@jridgewell/trace-mapping", + "jsesc" + ] + }, + "@babel/helper-compilation-targets@7.25.9": { + "integrity": "sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==", + "dependencies": [ + "@babel/compat-data", + "@babel/helper-validator-option", + "browserslist", + "lru-cache", + "semver" + ] + }, + "@babel/helper-module-imports@7.25.9": { + "integrity": "sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==", + "dependencies": [ + "@babel/traverse", + "@babel/types" + ] + }, + "@babel/helper-module-transforms@7.26.0_@babel+core@7.26.0": { + "integrity": "sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==", + "dependencies": [ + "@babel/core", + "@babel/helper-module-imports", + "@babel/helper-validator-identifier", + "@babel/traverse" + ] + }, + "@babel/helper-plugin-utils@7.25.9": { + "integrity": "sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==" + }, + "@babel/helper-string-parser@7.25.9": { + "integrity": "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==" + }, + "@babel/helper-validator-identifier@7.25.9": { + "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==" + }, + "@babel/helper-validator-option@7.25.9": { + "integrity": "sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==" + }, + "@babel/helpers@7.26.0": { + "integrity": "sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==", + "dependencies": [ + "@babel/template", + "@babel/types" + ] + }, + "@babel/parser@7.26.2": { + "integrity": "sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==", + "dependencies": [ + "@babel/types" + ] + }, + "@babel/plugin-transform-react-jsx-self@7.25.9_@babel+core@7.26.0": { + "integrity": "sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==", + "dependencies": [ + "@babel/core", + "@babel/helper-plugin-utils" + ] + }, + "@babel/plugin-transform-react-jsx-source@7.25.9_@babel+core@7.26.0": { + "integrity": "sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==", + "dependencies": [ + "@babel/core", + "@babel/helper-plugin-utils" + ] + }, + "@babel/template@7.25.9": { + "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "dependencies": [ + "@babel/code-frame", + "@babel/parser", + "@babel/types" + ] + }, + "@babel/traverse@7.25.9": { + "integrity": "sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==", + "dependencies": [ + "@babel/code-frame", + "@babel/generator", + "@babel/parser", + "@babel/template", + "@babel/types", + "debug", + "globals" + ] + }, + "@babel/types@7.26.0": { + "integrity": "sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==", + "dependencies": [ + "@babel/helper-string-parser", + "@babel/helper-validator-identifier" + ] + }, + "@deno/vite-plugin@1.0.0_vite@5.4.11__@types+node@22.5.4_@types+node@22.5.4": { + "integrity": "sha512-Q9UeWqs3s7B5lqzu1Z5QrzYAzqTj3+F9YW17tWobGRbT2G40ihwis6zK/+QgMgcG4fm3IqdIfXmpQYhkZpdMfw==", + "dependencies": [ + "vite" + ] + }, + "@esbuild/aix-ppc64@0.21.5": { + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==" + }, + "@esbuild/android-arm64@0.21.5": { + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==" + }, + "@esbuild/android-arm@0.21.5": { + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==" + }, + "@esbuild/android-x64@0.21.5": { + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==" + }, + "@esbuild/darwin-arm64@0.21.5": { + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==" + }, + "@esbuild/darwin-x64@0.21.5": { + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==" + }, + "@esbuild/freebsd-arm64@0.21.5": { + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==" + }, + "@esbuild/freebsd-x64@0.21.5": { + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==" + }, + "@esbuild/linux-arm64@0.21.5": { + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==" + }, + "@esbuild/linux-arm@0.21.5": { + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==" + }, + "@esbuild/linux-ia32@0.21.5": { + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==" + }, + "@esbuild/linux-loong64@0.21.5": { + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==" + }, + "@esbuild/linux-mips64el@0.21.5": { + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==" + }, + "@esbuild/linux-ppc64@0.21.5": { + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==" + }, + "@esbuild/linux-riscv64@0.21.5": { + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==" + }, + "@esbuild/linux-s390x@0.21.5": { + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==" + }, + "@esbuild/linux-x64@0.21.5": { + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==" + }, + "@esbuild/netbsd-x64@0.21.5": { + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==" + }, + "@esbuild/openbsd-x64@0.21.5": { + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==" + }, + "@esbuild/sunos-x64@0.21.5": { + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==" + }, + "@esbuild/win32-arm64@0.21.5": { + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==" + }, + "@esbuild/win32-ia32@0.21.5": { + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==" + }, + "@esbuild/win32-x64@0.21.5": { + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==" + }, + "@jridgewell/gen-mapping@0.3.5": { + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "dependencies": [ + "@jridgewell/set-array", + "@jridgewell/sourcemap-codec", + "@jridgewell/trace-mapping" + ] + }, + "@jridgewell/resolve-uri@3.1.2": { + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==" + }, + "@jridgewell/set-array@1.2.1": { + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==" + }, + "@jridgewell/sourcemap-codec@1.5.0": { + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "@jridgewell/trace-mapping@0.3.25": { + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", + "dependencies": [ + "@jridgewell/resolve-uri", + "@jridgewell/sourcemap-codec" + ] + }, + "@rollup/rollup-android-arm-eabi@4.27.3": { + "integrity": "sha512-EzxVSkIvCFxUd4Mgm4xR9YXrcp976qVaHnqom/Tgm+vU79k4vV4eYTjmRvGfeoW8m9LVcsAy/lGjcgVegKEhLQ==" + }, + "@rollup/rollup-android-arm64@4.27.3": { + "integrity": "sha512-LJc5pDf1wjlt9o/Giaw9Ofl+k/vLUaYsE2zeQGH85giX2F+wn/Cg8b3c5CDP3qmVmeO5NzwVUzQQxwZvC2eQKw==" + }, + "@rollup/rollup-darwin-arm64@4.27.3": { + "integrity": "sha512-OuRysZ1Mt7wpWJ+aYKblVbJWtVn3Cy52h8nLuNSzTqSesYw1EuN6wKp5NW/4eSre3mp12gqFRXOKTcN3AI3LqA==" + }, + "@rollup/rollup-darwin-x64@4.27.3": { + "integrity": "sha512-xW//zjJMlJs2sOrCmXdB4d0uiilZsOdlGQIC/jjmMWT47lkLLoB1nsNhPUcnoqyi5YR6I4h+FjBpILxbEy8JRg==" + }, + "@rollup/rollup-freebsd-arm64@4.27.3": { + "integrity": "sha512-58E0tIcwZ+12nK1WiLzHOD8I0d0kdrY/+o7yFVPRHuVGY3twBwzwDdTIBGRxLmyjciMYl1B/U515GJy+yn46qw==" + }, + "@rollup/rollup-freebsd-x64@4.27.3": { + "integrity": "sha512-78fohrpcVwTLxg1ZzBMlwEimoAJmY6B+5TsyAZ3Vok7YabRBUvjYTsRXPTjGEvv/mfgVBepbW28OlMEz4w8wGA==" + }, + "@rollup/rollup-linux-arm-gnueabihf@4.27.3": { + "integrity": "sha512-h2Ay79YFXyQi+QZKo3ISZDyKaVD7uUvukEHTOft7kh00WF9mxAaxZsNs3o/eukbeKuH35jBvQqrT61fzKfAB/Q==" + }, + "@rollup/rollup-linux-arm-musleabihf@4.27.3": { + "integrity": "sha512-Sv2GWmrJfRY57urktVLQ0VKZjNZGogVtASAgosDZ1aUB+ykPxSi3X1nWORL5Jk0sTIIwQiPH7iE3BMi9zGWfkg==" + }, + "@rollup/rollup-linux-arm64-gnu@4.27.3": { + "integrity": "sha512-FPoJBLsPW2bDNWjSrwNuTPUt30VnfM8GPGRoLCYKZpPx0xiIEdFip3dH6CqgoT0RnoGXptaNziM0WlKgBc+OWQ==" + }, + "@rollup/rollup-linux-arm64-musl@4.27.3": { + "integrity": "sha512-TKxiOvBorYq4sUpA0JT+Fkh+l+G9DScnG5Dqx7wiiqVMiRSkzTclP35pE6eQQYjP4Gc8yEkJGea6rz4qyWhp3g==" + }, + "@rollup/rollup-linux-powerpc64le-gnu@4.27.3": { + "integrity": "sha512-v2M/mPvVUKVOKITa0oCFksnQQ/TqGrT+yD0184/cWHIu0LoIuYHwox0Pm3ccXEz8cEQDLk6FPKd1CCm+PlsISw==" + }, + "@rollup/rollup-linux-riscv64-gnu@4.27.3": { + "integrity": "sha512-LdrI4Yocb1a/tFVkzmOE5WyYRgEBOyEhWYJe4gsDWDiwnjYKjNs7PS6SGlTDB7maOHF4kxevsuNBl2iOcj3b4A==" + }, + "@rollup/rollup-linux-s390x-gnu@4.27.3": { + "integrity": "sha512-d4wVu6SXij/jyiwPvI6C4KxdGzuZOvJ6y9VfrcleHTwo68fl8vZC5ZYHsCVPUi4tndCfMlFniWgwonQ5CUpQcA==" + }, + "@rollup/rollup-linux-x64-gnu@4.27.3": { + "integrity": "sha512-/6bn6pp1fsCGEY5n3yajmzZQAh+mW4QPItbiWxs69zskBzJuheb3tNynEjL+mKOsUSFK11X4LYF2BwwXnzWleA==" + }, + "@rollup/rollup-linux-x64-musl@4.27.3": { + "integrity": "sha512-nBXOfJds8OzUT1qUreT/en3eyOXd2EH5b0wr2bVB5999qHdGKkzGzIyKYaKj02lXk6wpN71ltLIaQpu58YFBoQ==" + }, + "@rollup/rollup-win32-arm64-msvc@4.27.3": { + "integrity": "sha512-ogfbEVQgIZOz5WPWXF2HVb6En+kWzScuxJo/WdQTqEgeyGkaa2ui5sQav9Zkr7bnNCLK48uxmmK0TySm22eiuw==" + }, + "@rollup/rollup-win32-ia32-msvc@4.27.3": { + "integrity": "sha512-ecE36ZBMLINqiTtSNQ1vzWc5pXLQHlf/oqGp/bSbi7iedcjcNb6QbCBNG73Euyy2C+l/fn8qKWEwxr+0SSfs3w==" + }, + "@rollup/rollup-win32-x64-msvc@4.27.3": { + "integrity": "sha512-vliZLrDmYKyaUoMzEbMTg2JkerfBjn03KmAw9CykO0Zzkzoyd7o3iZNam/TpyWNjNT+Cz2iO3P9Smv2wgrR+Eg==" + }, + "@types/babel__core@7.20.5": { + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dependencies": [ + "@babel/parser", + "@babel/types", + "@types/babel__generator", + "@types/babel__template", + "@types/babel__traverse" + ] + }, + "@types/babel__generator@7.6.8": { + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dependencies": [ + "@babel/types" + ] + }, + "@types/babel__template@7.4.4": { + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dependencies": [ + "@babel/parser", + "@babel/types" + ] + }, + "@types/babel__traverse@7.20.6": { + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dependencies": [ + "@babel/types" + ] + }, + "@types/estree@1.0.6": { + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" + }, + "@types/node@22.5.4": { + "integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==", + "dependencies": [ + "undici-types" + ] + }, + "@types/prop-types@15.7.13": { + "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==" + }, + "@types/react@18.3.12": { + "integrity": "sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==", + "dependencies": [ + "@types/prop-types", + "csstype" + ] + }, + "@vitejs/plugin-react@4.3.3_vite@5.4.11__@types+node@22.5.4_@babel+core@7.26.0_@types+node@22.5.4": { + "integrity": "sha512-NooDe9GpHGqNns1i8XDERg0Vsg5SSYRhRxxyTGogUdkdNt47jal+fbuYi+Yfq6pzRCKXyoPcWisfxE6RIM3GKA==", + "dependencies": [ + "@babel/core", + "@babel/plugin-transform-react-jsx-self", + "@babel/plugin-transform-react-jsx-source", + "@types/babel__core", + "react-refresh", + "vite" + ] + }, + "browserslist@4.24.2": { + "integrity": "sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==", + "dependencies": [ + "caniuse-lite", + "electron-to-chromium", + "node-releases", + "update-browserslist-db" + ] + }, + "caniuse-lite@1.0.30001680": { + "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==" + }, + "convert-source-map@2.0.0": { + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, + "cookie@1.0.2": { + "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==" + }, + "csstype@3.1.3": { + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, + "debug@4.3.7": { + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dependencies": [ + "ms" + ] + }, + "electron-to-chromium@1.5.63": { + "integrity": "sha512-ddeXKuY9BHo/mw145axlyWjlJ1UBt4WK3AlvkT7W2AbqfRQoacVoRUCF6wL3uIx/8wT9oLKXzI+rFqHHscByaA==" + }, + "esbuild@0.21.5": { + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dependencies": [ + "@esbuild/aix-ppc64", + "@esbuild/android-arm", + "@esbuild/android-arm64", + "@esbuild/android-x64", + "@esbuild/darwin-arm64", + "@esbuild/darwin-x64", + "@esbuild/freebsd-arm64", + "@esbuild/freebsd-x64", + "@esbuild/linux-arm", + "@esbuild/linux-arm64", + "@esbuild/linux-ia32", + "@esbuild/linux-loong64", + "@esbuild/linux-mips64el", + "@esbuild/linux-ppc64", + "@esbuild/linux-riscv64", + "@esbuild/linux-s390x", + "@esbuild/linux-x64", + "@esbuild/netbsd-x64", + "@esbuild/openbsd-x64", + "@esbuild/sunos-x64", + "@esbuild/win32-arm64", + "@esbuild/win32-ia32", + "@esbuild/win32-x64" + ] + }, + "escalade@3.2.0": { + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==" + }, + "fsevents@2.3.3": { + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==" + }, + "gensync@1.0.0-beta.2": { + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==" + }, + "globals@11.12.0": { + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" + }, + "js-tokens@4.0.0": { + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "jsesc@3.0.2": { + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==" + }, + "json5@2.2.3": { + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" + }, + "loose-envify@1.4.0": { + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": [ + "js-tokens" + ] + }, + "lru-cache@5.1.1": { + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": [ + "yallist" + ] + }, + "ms@2.1.3": { + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "nanoid@3.3.7": { + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==" + }, + "node-releases@2.0.18": { + "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" + }, + "path-to-regexp@6.2.1": { + "integrity": "sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==" + }, + "picocolors@1.1.1": { + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==" + }, + "postcss@8.4.49": { + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", + "dependencies": [ + "nanoid", + "picocolors", + "source-map-js" + ] + }, + "react-dom@18.3.1_react@18.3.1": { + "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", + "dependencies": [ + "loose-envify", + "react", + "scheduler" + ] + }, + "react-refresh@0.14.2": { + "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==" + }, + "react-router-dom@7.5.1_react@18.3.1_react-dom@18.3.1__react@18.3.1": { + "integrity": "sha512-5DPSPc7ENrt2tlKPq0FtpG80ZbqA9aIKEyqX6hSNJDlol/tr6iqCK4crqdsusmOSSotq6zDsn0y3urX9TuTNmA==", + "dependencies": [ + "react", + "react-dom", + "react-router" + ] + }, + "react-router@7.5.1_react@18.3.1_react-dom@18.3.1__react@18.3.1": { + "integrity": "sha512-/jjU3fcYNd2bwz9Q0xt5TwyiyoO8XjSEFXJY4O/lMAlkGTHWuHRAbR9Etik+lSDqMC7A7mz3UlXzgYT6Vl58sA==", + "dependencies": [ + "cookie", + "react", + "react-dom", + "set-cookie-parser", + "turbo-stream" + ] + }, + "react@18.3.1": { + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "dependencies": [ + "loose-envify" + ] + }, + "rollup@4.27.3": { + "integrity": "sha512-SLsCOnlmGt9VoZ9Ek8yBK8tAdmPHeppkw+Xa7yDlCEhDTvwYei03JlWo1fdc7YTfLZ4tD8riJCUyAgTbszk1fQ==", + "dependencies": [ + "@rollup/rollup-android-arm-eabi", + "@rollup/rollup-android-arm64", + "@rollup/rollup-darwin-arm64", + "@rollup/rollup-darwin-x64", + "@rollup/rollup-freebsd-arm64", + "@rollup/rollup-freebsd-x64", + "@rollup/rollup-linux-arm-gnueabihf", + "@rollup/rollup-linux-arm-musleabihf", + "@rollup/rollup-linux-arm64-gnu", + "@rollup/rollup-linux-arm64-musl", + "@rollup/rollup-linux-powerpc64le-gnu", + "@rollup/rollup-linux-riscv64-gnu", + "@rollup/rollup-linux-s390x-gnu", + "@rollup/rollup-linux-x64-gnu", + "@rollup/rollup-linux-x64-musl", + "@rollup/rollup-win32-arm64-msvc", + "@rollup/rollup-win32-ia32-msvc", + "@rollup/rollup-win32-x64-msvc", + "@types/estree", + "fsevents" + ] + }, + "scheduler@0.23.2": { + "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", + "dependencies": [ + "loose-envify" + ] + }, + "semver@6.3.1": { + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==" + }, + "set-cookie-parser@2.7.1": { + "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==" + }, + "source-map-js@1.2.1": { + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==" + }, + "turbo-stream@2.4.0": { + "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==" + }, + "undici-types@6.19.8": { + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" + }, + "update-browserslist-db@1.1.1_browserslist@4.24.2": { + "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", + "dependencies": [ + "browserslist", + "escalade", + "picocolors" + ] + }, + "vite@5.4.11_@types+node@22.5.4": { + "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", + "dependencies": [ + "@types/node", + "esbuild", + "fsevents", + "postcss", + "rollup" + ] + }, + "yallist@3.1.1": { + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + } + }, + "workspace": { + "dependencies": [ + "jsr:@oak/oak@^17.1.3", + "jsr:@std/assert@1", + "jsr:@tajpouria/cors@^1.2.1", + "npm:@deno/vite-plugin@1", + "npm:@types/react@^18.3.12", + "npm:@vitejs/plugin-react@^4.3.3", + "npm:react-dom@^18.3.1", + "npm:react-router-dom@^7.5.1", + "npm:react@^18.3.1", + "npm:vite@^5.4.11" + ] + } +} diff --git a/server/api/data.json b/server/api/data.json new file mode 100644 index 0000000..197c362 --- /dev/null +++ b/server/api/data.json @@ -0,0 +1,3022 @@ +[ + { + "name": "Aardonyx", + "description": "An early stage in the evolution of sauropods." + }, + { + "name": "Abelisaurus", + "description": "\"Abel's lizard\" has been reconstructed from a single skull." + }, + { + "name": "Abrictosaurus", + "description": "An early relative of Heterodontosaurus." + }, + { + "name": "Abrosaurus", + "description": "A close Asian relative of Camarasaurus." + }, + { + "name": "Abydosaurus", + "description": "This sauropod's intact skull was discovered in 2010." + }, + { + "name": "Acanthopholis", + "description": "No, it's not a city in Greece." + }, + { + "name": "Achelousaurus", + "description": "Might this have been a growth stage of Pachyrhinosaurus?" + }, + { + "name": "Achillobator", + "description": "This fierce raptor was discovered in modern-day Mongolia." + }, + { + "name": "Acristavus", + "description": "This early hadrosaur lacked any ornamentation on its skull." + }, + { + "name": "Acrocanthosaurus", + "description": "The largest meat-eating dinosaur of the early Cretaceous period." + }, + { + "name": "Acrotholus", + "description": "North America's earliest bone-headed dinosaur." + }, + { + "name": "Adamantisaurus", + "description": "This titanosaur was named 50 years after its discovery." + }, + { + "name": "Adasaurus", + "description": "This raptor's hind claws were unusually small." + }, + { + "name": "Adeopapposaurus", + "description": "A close relative of Massospondylus." + }, + { + "name": "Aegyptosaurus", + "description": "Try and guess which country this dinosaur was found in." + }, + { + "name": "Aeolosaurus", + "description": "Could this titanosaur have reared up on its hind legs?" + }, + { + "name": "Aerosteon", + "description": "This air-boned dinosaur may have breathed like a bird." + }, + { + "name": "Afrovenator", + "description": "One of the few carnivores ever to be dug up in northern Africa." + }, + { + "name": "Agathaumas", + "description": "The first ceratopsian dinosaur ever discovered." + }, + { + "name": "Agilisaurus", + "description": "This \"agile lizard\" was one of the earliest ornithopods." + }, + { + "name": "Agujaceratops", + "description": "It was once classified as a species of Chasmosaurus." + }, + { + "name": "Agustinia", + "description": "A large, spiny-backed sauropod." + }, + { + "name": "Ajkaceratops", + "description": "The first ceratopsian ever to be discovered in Europe." + }, + { + "name": "Alamosaurus", + "description": "No, it wasn't named after the Alamo, but it should have been." + }, + { + "name": "Alaskacephale", + "description": "Can you guess which state this pachycephalosaur was found in?" + }, + { + "name": "Albalophosaurus", + "description": "One of the few dinosaurs ever to be discovered in Japan." + }, + { + "name": "Albertaceratops", + "description": "The most basal \"centrosaurine\" yet identified." + }, + { + "name": "Albertadromeus", + "description": "This petite ornithopod was recently discovered in Canada." + }, + { + "name": "Albertonykus", + "description": "A tiny, birdlike, North American dinosaur." + }, + { + "name": "Albertosaurus", + "description": "This carnivorous dinosaur was a close relative of T. Rex." + }, + { + "name": "Alectrosaurus", + "description": "Few specimens of this \"unmarried lizard\" have been found." + }, + { + "name": "Aletopelta", + "description": "The first ankylosaur known to have lived in Mexico." + }, + { + "name": "Alioramus", + "description": "Everything we know about this tyrannosaur is based on a single skull." + }, + { + "name": "Allosaurus", + "description": "The apex predator of late Jurassic North America." + }, + { + "name": "Altirhinus", + "description": "This \"high-nosed\" plant eater resembled an early hadrosaur." + }, + { + "name": "Alvarezsaurus", + "description": "A bird-like dinosaur of the late Cretaceous." + }, + { + "name": "Alwalkeria", + "description": "This Indian dinosaur was one of the earliest saurischians." + }, + { + "name": "Alxasaurus", + "description": "An early relative of the bizarre Therizinosaurus." + }, + { + "name": "Amargasaurus", + "description": "A bizarre, spined sauropod from South America." + }, + { + "name": "Amazonsaurus", + "description": "One of the few dinosaurs to be found in the Amazon basin." + }, + { + "name": "Ammosaurus", + "description": "This may (or may not) have been the same dinosaur as Anchisaurus." + }, + { + "name": "Ampelosaurus", + "description": "One of the best-known of the armored titanosaurs." + }, + { + "name": "Amphicoelias", + "description": "Could it have been the biggest dinosaur that ever lived?" + }, + { + "name": "Amurosaurus", + "description": "The most complete hadrosaur to be discovered in Russia." + }, + { + "name": "Anabisetia", + "description": "The best-attested South American ornithopod." + }, + { + "name": "Anatosaurus", + "description": "This dinosaur is now known as either Anatotitan or Edmontosaurus." + }, + { + "name": "Anatotitan", + "description": "This hadrosaur's name means \"giant duck\"." + }, + { + "name": "Anchiceratops", + "description": "This dinosaur had a distinctively shaped frill." + }, + { + "name": "Anchiornis", + "description": "A four-winged dino-bird that resembled Microraptor." + }, + { + "name": "Anchisaurus", + "description": "One of the first dinosaurs ever to be dug up in the U.S." + }, + { + "name": "Andesaurus", + "description": "This titanosaur rivaled Argentinosaurus in size." + }, + { + "name": "Angaturama", + "description": "A Brazilian relative of Spinosaurus." + }, + { + "name": "Angolatitan", + "description": "The first dinosaur ever to be discovered in Angola." + }, + { + "name": "Angulomastacator", + "description": "This dinosaur had a strangely shaped upper jaw." + }, + { + "name": "Animantarx", + "description": "This \"living fortress\" was discovered in an unusual way." + }, + { + "name": "Ankylosaurus", + "description": "This dinosaur was the Cretaceous equivalent of a Sherman tank." + }, + { + "name": "Anodontosaurus", + "description": "This \"toothless lizard\" actually had a full set of choppers." + }, + { + "name": "Anserimimus", + "description": "This \"goose mimic\" didn’t bear much of a resemblance." + }, + { + "name": "Antarctopelta", + "description": "The first dinosaur fossil ever discovered in Antarctica." + }, + { + "name": "Antarctosaurus", + "description": "This titanosaur may or may not have lived in Antarctica." + }, + { + "name": "Antetonitrus", + "description": "Either a very late prosauropod or a very early sauropod." + }, + { + "name": "Anzu", + "description": "This Oviraptor relative was recently discovered in North America." + }, + { + "name": "Aorun", + "description": "A small theropod of late Jurassic Asia." + }, + { + "name": "Apatosaurus", + "description": "The dinosaur formerly known as Brontosaurus." + }, + { + "name": "Appalachiosaurus", + "description": "One of the few dinosaurs ever to be found in Alabama." + }, + { + "name": "Aquilops", + "description": "The earliest ceratopsian ever to be discovered in North America." + }, + { + "name": "Aragosaurus", + "description": "named after the Aragon region of Spain." + }, + { + "name": "Aralosaurus", + "description": "Not much is known about this central Asian duck-billed dinosaur." + }, + { + "name": "Archaeoceratops", + "description": "Possibly the smallest ceratopsian that ever lived." + }, + { + "name": "Archaeopteryx", + "description": "This ancient dino-bird was about the size of a modern pigeon." + }, + { + "name": "Archaeornithomimus", + "description": "A likely ancestor of Ornithomimus." + }, + { + "name": "Arcovenator", + "description": "This fierce abelisaur was recently discovered in France." + }, + { + "name": "Arcusaurus", + "description": "This prosauropod was recently discovered in South Africa." + }, + { + "name": "Argentinosaurus", + "description": "Possibly the largest dinosaur that ever lived." + }, + { + "name": "Argyrosaurus", + "description": "A plus-sized titanosaur from South America." + }, + { + "name": "Aristosuchus", + "description": "This \"noble crocodile\" was actually a dinosaur." + }, + { + "name": "Arrhinoceratops", + "description": "This ceratopsian was named for its \"missing\" nose horn." + }, + { + "name": "Astrodon", + "description": "The official state dinosaur of Maryland." + }, + { + "name": "Asylosaurus", + "description": "This \"unharmed lizard\" escaped destruction in World War II." + }, + { + "name": "Atlasaurus", + "description": "This sauropod had unusually long legs." + }, + { + "name": "Atlascopcosaurus", + "description": "named after a manufacturer of digging equipment." + }, + { + "name": "Atrociraptor", + "description": "This \"cruel thief\" wasn't as atrocious as its name implies." + }, + { + "name": "Aublysodon", + "description": "This tyrannosaur was named after a single tooth." + }, + { + "name": "Aucasaurus", + "description": "This predator was a close relative of Carnotaurus." + }, + { + "name": "Auroraceratops", + "description": "A close relative of Archaeoceratops." + }, + { + "name": "Australodocus", + "description": "This sauropod was found in modern-day Tanzania." + }, + { + "name": "Australovenator", + "description": "A recently discovered carnivore from Australia." + }, + { + "name": "Austroraptor", + "description": "The largest raptor from South America." + }, + { + "name": "Austrosaurus", + "description": "This titanosaur was discovered near a train station." + }, + { + "name": "Avaceratops", + "description": "This ceratopsian is represented by a single juvenile." + }, + { + "name": "Aviatyrannis", + "description": "This \"grandmother tyrant\" was one of the first tyrannosaurs." + }, + { + "name": "Avimimus", + "description": "A particularly bird-like cousin of Oviraptor." + }, + { + "name": "Bactrosaurus", + "description": "One of the earliest of the duck-billed dinosaurs." + }, + { + "name": "Bagaceratops", + "description": "A small ceratopsian from central Asia." + }, + { + "name": "Bagaraatan", + "description": "No one is quite sure how to classify this theropod." + }, + { + "name": "Bahariasaurus", + "description": "This obscure carnivore may have been the size of T. Rex." + }, + { + "name": "Balaur", + "description": "This \"stocky dragon\" was recently discovered in Romania." + }, + { + "name": "Bambiraptor", + "description": "Yes, this tiny raptor was named after you-know-who." + }, + { + "name": "Barapasaurus", + "description": "Probably the first of the giant sauropods." + }, + { + "name": "Barilium", + "description": "Yet another iguanodontid ornithopod of the British Isles." + }, + { + "name": "Barosaurus", + "description": "An enormous plant-eater with a tiny head." + }, + { + "name": "Barsboldia", + "description": "This hadrosaur was named after Rinchen Barsbold." + }, + { + "name": "Baryonyx", + "description": "You wouldn't want to clip this dinosaur's claws." + }, + { + "name": "Batyrosaurus", + "description": "One of the most basal hadrosaurs yet identified." + }, + { + "name": "Becklespinax", + "description": "A strangely named theropod of the early Cretaceous period." + }, + { + "name": "Beipiaosaurus", + "description": "The only known feathered therizinosaur." + }, + { + "name": "Beishanlong", + "description": "This bird mimic weighed over half a ton." + }, + { + "name": "Bellusaurus", + "description": "A herd of this sauropod drowned in a flash flood." + }, + { + "name": "Berberosaurus", + "description": "This \"Berber lizard\" has proven difficult to classify." + }, + { + "name": "Bicentenaria", + "description": "This dinosaur was named for Argentina's 200th anniversary." + }, + { + "name": "Bistahieversor", + "description": "This tyrannosaur had more teeth than T. Rex." + }, + { + "name": "Bonapartenykus", + "description": "This feathered dinosaur was found in close proximity to its eggs." + }, + { + "name": "Bonitasaura", + "description": "This titanosaur wasn't as beautiful as its name implies." + }, + { + "name": "Borogovia", + "description": "This theropod was named after a Lewis Carroll poem." + }, + { + "name": "Bothriospondylus", + "description": "A case study in dinosaur confusion." + }, + { + "name": "Brachiosaurus", + "description": "This dinosaur was a giant, gentle, long-necked plant-eater." + }, + { + "name": "Brachyceratops", + "description": "A little-known ceratopsian from North America." + }, + { + "name": "Brachylophosaurus", + "description": "This duck-billed dinosaur's beak looked more like a parrot's." + }, + { + "name": "Brachytrachelopan", + "description": "This sauropod had an unusually short neck." + }, + { + "name": "Bravoceratops", + "description": "This ceratopsian was recently discovered in Texas." + }, + { + "name": "Brontomerus", + "description": "Its name is Greek for \"thunder thighs\"." + }, + { + "name": "Bruhathkayosaurus", + "description": "Was this titanosaur bigger than Argentinosaurus?" + }, + { + "name": "Buitreraptor", + "description": "The oldest raptor ever discovered in South America." + }, + { + "name": "Byronosaurus", + "description": "This theropod was a close relative of Troodon." + }, + { + "name": "Camarasaurus", + "description": "The most common sauropod of Jurassic North America." + }, + { + "name": "Camarillasaurus", + "description": "A ceratosaur of early Cretaceous western Europe." + }, + { + "name": "Camelotia", + "description": "An early member of the line that evolved into sauropods." + }, + { + "name": "Camptosaurus", + "description": "A close relative of Iguanodon." + }, + { + "name": "Carcharodontosaurus", + "description": "Its name means \"great white shark lizard.\" Impressed yet?" + }, + { + "name": "Carnotaurus", + "description": "The shortest arms of any meat-eating dinosaur with horns to match." + }, + { + "name": "Caudipteryx", + "description": "A birdlike dinosaur that changed the views of paleontologists." + }, + { + "name": "Centrosaurus", + "description": "Like a unicorn, this ceratopsian only had one horn." + }, + { + "name": "Cerasinops", + "description": "A small ceratopsian of the late Cretaceous." + }, + { + "name": "Ceratonykus", + "description": "This dino-bird was discovered in Mongolia in 2009." + }, + { + "name": "Ceratosaurus", + "description": "This primitive carnivore is hard to classify." + }, + { + "name": "Cetiosauriscus", + "description": "Not to be confused with the more famous Cetiosaurus." + }, + { + "name": "Cetiosaurus", + "description": "This \"whale lizard\" was once mistaken for the Loch Ness Monster." + }, + { + "name": "Changyuraptor", + "description": "Was this feathered dinosaur capable of flight?" + }, + { + "name": "Chaoyangsaurus", + "description": "An early ceratopsian of the late Jurassic period." + }, + { + "name": "Charonosaurus", + "description": "This duck-billed dinosaur was much bigger than an elephant." + }, + { + "name": "Chasmosaurus", + "description": "The only dinosaur that came with its own awning." + }, + { + "name": "Chialingosaurus", + "description": "One of the earliest Asian stegosaurs." + }, + { + "name": "Chilantaisaurus", + "description": "This large theropod may have been ancestral to Spinosaurus." + }, + { + "name": "Chilesaurus", + "description": "This plant-eating theropod was recently discovered in Chile." + }, + { + "name": "Chindesaurus", + "description": "This early dinosaur was a close relative of Herrerasaurus." + }, + { + "name": "Chirostenotes", + "description": "This birdlike dinosaur has been known by three different names." + }, + { + "name": "Chubutisaurus", + "description": "This titanosaur was on Tyrannotitan's lunch menu." + }, + { + "name": "Chungkingosaurus", + "description": "This early stegosaur had some primitive characteristics." + }, + { + "name": "Citipati", + "description": "This Mongolian theropod was a close relative of Oviraptor." + }, + { + "name": "Claosaurus", + "description": "This \"broken lizard\" was a primitive hadrosaur." + }, + { + "name": "Coahuilaceratops", + "description": "It had the longest horns of any known ceratopsian dinosaur." + }, + { + "name": "Coelophysis", + "description": "One of the most ancient dinosaurs ever to roam the earth." + }, + { + "name": "Coelurus", + "description": "This tiny dinosaur was a close relative of Compsognathus." + }, + { + "name": "Colepiocephale", + "description": "This thick-skulled dinosaur's name is Greek for \"knucklehead\"." + }, + { + "name": "Compsognathus", + "description": "This dinosaur was the size of a chicken, but much meaner." + }, + { + "name": "Concavenator", + "description": "This large theropod had a bizarre hump on its back." + }, + { + "name": "Conchoraptor", + "description": "This \"conch thief\" may have lunched on mollusks." + }, + { + "name": "Condorraptor", + "description": "A small theropod of middle Jurassic South America." + }, + { + "name": "Coronosaurus", + "description": "This \"crown lizard\" was once classified as a species of Centrosaurus." + }, + { + "name": "Corythosaurus", + "description": "This \"Corinthian-helmeted\" dino had a distinctive mating call." + }, + { + "name": "Crichtonsaurus", + "description": "This dinosaur was named after the author of Jurassic Park." + }, + { + "name": "Cruxicheiros", + "description": "This \"cross-handed\" dinosaur was named in 2010." + }, + { + "name": "Cryolophosaurus", + "description": "This crested dinosaur was once known as \"Elvisaurus\"." + }, + { + "name": "Cryptovolans", + "description": "Was this the same dinosaur as Microraptor?" + }, + { + "name": "Cumnoria", + "description": "It was once mistakenly classified as a species of Iguanodon." + }, + { + "name": "Dacentrurus", + "description": "The first stegosaur ever to be described." + }, + { + "name": "Daemonosauru 0s", + "description": "This \"evil lizard\" was a close relative of Coelophysis." + }, + { + "name": "Dahalokely", + "description": "A rare theropod from the island of Madagascar." + }, + { + "name": "Dakotaraptor", + "description": "This giant raptor was recently discovered in South Dakota." + }, + { + "name": "Daspletosaurus", + "description": "This \"frightful lizard\" was a close cousin of T. Rex." + }, + { + "name": "Datousaurus", + "description": "A medium-sized sauropod from middle Jurassic Asia." + }, + { + "name": "Darwinsaurus", + "description": "\"Darwin's lizard\" may or may not be a valid dinosaur genus." + }, + { + "name": "Deinocheirus", + "description": "All we know for sure about this dinosaur is the shape of its arms." + }, + { + "name": "Deinodon", + "description": "This \"terrible tooth\" is important from a historical perspective." + }, + { + "name": "Deinonychus", + "description": "One of the most fearsome raptors of the Cretaceous period." + }, + { + "name": "Delapparentia", + "description": "This ornithopod was initially classified as a species of Iguanodon." + }, + { + "name": "Deltadromeus", + "description": "An unusually speedy theropod of the middle Cretaceous." + }, + { + "name": "Demandasaurus", + "description": "A poorly understood sauropod of early Cretaceous Europe." + }, + { + "name": "Diabloceratops", + "description": "It looked like a cross between a Triceratops and a Centrosaurus." + }, + { + "name": "Diamantinasaurus", + "description": "This titanosaur was recently discovered in Australia." + }, + { + "name": "Diceratops", + "description": "Was this two-horned dinosaur really a specimen of Triceratops?" + }, + { + "name": "Dicraeosaurus", + "description": "A medium-sized, spiny-necked sauropod." + }, + { + "name": "Dilong", + "description": "This \"emperor dragon\" may have been an ancestor of T. Rex." + }, + { + "name": "Dilophosaurus", + "description": "This dinosaur was distinguished by the bony crests on its noggin." + }, + { + "name": "Dimetrodon", + "description": "This ancient synapsid had a huge sail on its back." + }, + { + "name": "Diplodocus", + "description": "Thin at one end, much thicker in the middle, and thin again at the far end." + }, + { + "name": "Dollodon", + "description": "named after the Belgian paleontologist Louis Dollo." + }, + { + "name": "Draconyx", + "description": "This \"dragon claw\" lived in late Jurassic Portugal." + }, + { + "name": "Dracopelta", + "description": "This early ankylosaur was discovered in Portugal." + }, + { + "name": "Dracorex", + "description": "The only dinosaur to be named after the \"Harry Potter\" books." + }, + { + "name": "Dracovenator", + "description": "This \"dragon hunter\" was a close relative of Dilophosaurus." + }, + { + "name": "Dravidosaurus", + "description": "This \"dinosaur\" may actually have been a marine reptile." + }, + { + "name": "Dreadnoughtus", + "description": "This huge titanosaur was recently discovered in Argentina." + }, + { + "name": "Drinker", + "description": "named after the famous paleontologist Edward Drinker Cope." + }, + { + "name": "Dromaeosauroides", + "description": "The only dinosaur ever to be discovered in Denmark." + }, + { + "name": "Dromaeosaurus", + "description": "This \"running lizard\" was probably covered with feathers." + }, + { + "name": "Dromiceiomimus", + "description": "Possibly the fastest dinosaur that ever lived." + }, + { + "name": "Dryosaurus", + "description": "A typical ornithopod of the late Jurassic." + }, + { + "name": "Dryptosaurus", + "description": "The first tyrannosaur to be discovered in the U.S." + }, + { + "name": "Dubreuillosaurus", + "description": "This megalosaur had a long, low snout." + }, + { + "name": "Duriavenator", + "description": "Yet another theropod that was once assigned to Megalosaurus." + }, + { + "name": "Dyoplosaurus", + "description": "This ankylosaur was once confused with Euoplocephalus." + }, + { + "name": "Dysalotosaurus", + "description": "We know a lot about this dinosaur's growth stages." + }, + { + "name": "Dyslocosaurus", + "description": "Its name means \"hard-to-place lizard\"." + }, + { + "name": "Dystrophaeus", + "description": "This Diplodocus-like sauropod was named by Edward Cope." + }, + { + "name": "Echinodon", + "description": "One of the few ornithopods to sport a set of canines." + }, + { + "name": "Edmarka", + "description": "This may have been a species of Torvosaurus." + }, + { + "name": "Edmontonia", + "description": "This armored dinosaur never actually lived in Edmonton." + }, + { + "name": "Edmontosaurus", + "description": "This large, duck-billed herbivore was a contemporary of T. Rex." + }, + { + "name": "Efraasia", + "description": "This Triassic herbivore may have been ancestral to sauropods." + }, + { + "name": "Einiosaurus", + "description": "This ceratopsian was a close relative of Centrosaurus." + }, + { + "name": "Ekrixinatosaurus", + "description": "Its name means \"explosion-born lizard\"." + }, + { + "name": "Elaphrosaurus", + "description": "A lightweight theropod from the late Jurassic." + }, + { + "name": "Elmisaurus", + "description": "This \"foot lizard\" was a close relative of Oviraptor." + }, + { + "name": "Elopteryx", + "description": "This Transylvanian dinosaur is almost as controversial as Dracula." + }, + { + "name": "Elrhazosaurus", + "description": "Once classified as a species of Valdosaurus." + }, + { + "name": "Enigmosaurus", + "description": "This \"puzzle lizard\" was closely related to Therizinosaurus." + }, + { + "name": "Eoabelisaurus", + "description": "The earliest abelisaurid theropod yet identified." + }, + { + "name": "Eobrontosaurus", + "description": "This \"dawn brontosaurus\" isn't accepted by most experts." + }, + { + "name": "Eocarcharia", + "description": "This \"dawn shark\" prowled the woodlands of northern Africa." + }, + { + "name": "Eocursor", + "description": "This late Triassic reptile was one of the earliest true dinosaurs." + }, + { + "name": "Eodromaeus", + "description": "Yet another ancient theropod from South America." + }, + { + "name": "Eolambia", + "description": "An early hadrosaur from North America." + }, + { + "name": "Eoraptor", + "description": "This tiny dinosaur was among the first of its kind." + }, + { + "name": "Eosinopteryx", + "description": "A tiny feathered dinosaur of the late Jurassic period." + }, + { + "name": "Eotriceratops", + "description": "This \"dawn Triceratops\" was recently discovered in Canada." + }, + { + "name": "Eotyrannus", + "description": "This early tyrannosaur looked more like a raptor." + }, + { + "name": "Epachthosaurus", + "description": "This \"heavy lizard\" was relatively primitive for its time and place." + }, + { + "name": "Epidendrosaurus", + "description": "Did this tiny dino-bird spend its life up a tree?" + }, + { + "name": "Epidexipteryx", + "description": "This feathered dinosaur predated Archaeopteryx." + }, + { + "name": "Equijubus", + "description": "Its name is Greek for \"horse mane\"." + }, + { + "name": "Erectopus", + "description": "This \"upright-footed\" dinosaur is a 19th-century enigma." + }, + { + "name": "Erketu", + "description": "This titanosaur had an unusually long neck." + }, + { + "name": "Erliansaurus", + "description": "A basal therizinosaur from central Asia." + }, + { + "name": "Erlikosaurus", + "description": "This late therizinosaur roamed the Mongolian forests." + }, + { + "name": "Euhelopus", + "description": "The first sauropod to be discovered in China." + }, + { + "name": "Euoplocephalus", + "description": "Even this ankylosaur's eyelids were armored." + }, + { + "name": "Europasaurus", + "description": "The smallest sauropod ever discovered." + }, + { + "name": "Europelta", + "description": "This early nodosaur was recently discovered in Spain." + }, + { + "name": "Euskelosaurus", + "description": "The first dinosaur ever to be discovered in Africa." + }, + { + "name": "Eustreptospondylus", + "description": "A close cousin of Megalosaurus." + }, + { + "name": "Fabrosaurus", + "description": "This early ornithopod may have been a species of Lesothosaurus." + }, + { + "name": "Falcarius", + "description": "A bizarre, feathered theropod from North America." + }, + { + "name": "Ferganasaurus", + "description": "The first dinosaur ever to be discovered in the USSR." + }, + { + "name": "Fruitadens", + "description": "One of the tiniest dinosaurs ever to live in North America." + }, + { + "name": "Fukuiraptor", + "description": "One of the few carnivorous dinosaurs ever to be dug up in Japan." + }, + { + "name": "Fukuisaurus", + "description": "This ornithopod was discovered in Japan." + }, + { + "name": "Fulgurotherium", + "description": "Very little is known about this \"lightning beast\"." + }, + { + "name": "Futalognkosaurus", + "description": "A very big, and very strangely named sauropod." + }, + { + "name": "Gallimimus", + "description": "This \"chicken mimic\" roamed the plains of the late Cretaceous." + }, + { + "name": "Gargoyleosaurus", + "description": "This \"gargoyle lizard\" was an ancestor of Ankylosaurus." + }, + { + "name": "Garudimimus", + "description": "A relative slowpoke compared to other ornithomimids." + }, + { + "name": "Gasosaurus", + "description": "Yes, that's its real name, and no, it isn't for the reason you think." + }, + { + "name": "Gasparinisaura", + "description": "One of the few ornithopods known to have lived in South America." + }, + { + "name": "Gastonia", + "description": "This ankylosaur was probably on Utahraptor's lunch menu." + }, + { + "name": "Genyodectes", + "description": "This dinosaur is represented by an impressive set of teeth." + }, + { + "name": "Gideonmantellia", + "description": "Guess what naturalist this dinosaur was named after." + }, + { + "name": "Giganotosaurus", + "description": "Not quite a \"Gigantosaurus,\" but close enough." + }, + { + "name": "Gigantoraptor", + "description": "This huge oviraptorosaur weighed over two tons." + }, + { + "name": "Gigantspinosaurus", + "description": "It may or may not have been a true stegosaur." + }, + { + "name": "Gilmoreosaurus", + "description": "One of the few dinosaurs known to have suffered from cancer." + }, + { + "name": "Giraffatitan", + "description": "Might this \"giant giraffe\" have been a species of Brachiosaurus?" + }, + { + "name": "Glacialisaurus", + "description": "This \"frozen lizard\" was a close relative of Lufengosaurus." + }, + { + "name": "Gobiceratops", + "description": "This ceratopsian's tiny skull was found in the Gobi Desert." + }, + { + "name": "Gobisaurus", + "description": "An unusually large ankylosaur of central Asia." + }, + { + "name": "Gobivenator", + "description": "This feathered dinosaur gave Velociraptor a run for its money." + }, + { + "name": "Gojirasaurus", + "description": "This early predator was named after Godzilla." + }, + { + "name": "Gondwanatitan", + "description": "Yet another titanosaur from South America." + }, + { + "name": "Gorgosaurus", + "description": "Might this tyrannosaur have been a species of Albertosaurus?" + }, + { + "name": "Goyocephale", + "description": "A primitive bonehead from Asia." + }, + { + "name": "Graciliraptor", + "description": "This tiny dino-bird was a close relative of Microraptor." + }, + { + "name": "Gryphoceratops", + "description": "A tiny ceratopsian of Cretaceous North America." + }, + { + "name": "Gryponyx", + "description": "This \"hooked claw\" was a distant sauropod ancestor." + }, + { + "name": "Gryposaurus", + "description": "One of the most common of the duck-billed dinosaurs." + }, + { + "name": "Guaibasaurus", + "description": "Was this early dinosaur a theropod or a prosauropod?" + }, + { + "name": "Guanlong", + "description": "Probably the first tyrannosaur ever to walk the earth." + }, + { + "name": "Hadrosaurus", + "description": "The official state dinosaur of New Jersey." + }, + { + "name": "Hagryphus", + "description": "The largest North American oviraptor yet discovered." + }, + { + "name": "Halticosaurus", + "description": "A \"nomen dubium\" theropod of the early 20th century." + }, + { + "name": "Haplocanthosaurus", + "description": "A typical sauropod of the late Jurassic period." + }, + { + "name": "Haplocheirus", + "description": "This feathered dinosaur predated Archaeopteryx by millions of years." + }, + { + "name": "Harpymimus", + "description": "named after the winged creature of Greek myth." + }, + { + "name": "Haya", + "description": "This dinosaur was named after a horse-headed Mongolian god." + }, + { + "name": "Herrerasaurus", + "description": "This carnivore roamed present-day South America." + }, + { + "name": "Hesperonychus", + "description": "A tiny North American dinosaur." + }, + { + "name": "Hesperosaurus", + "description": "The oldest stegosaur discovered in North America." + }, + { + "name": "Heterodontosaurus", + "description": "This \"different-toothed\" dinosaur was a dentist's nightmare." + }, + { + "name": "Hexing", + "description": "This early ornithomimid was recently discovered in China." + }, + { + "name": "Hexinlusaurus", + "description": "named after the Chinese professor He Xin-Lu." + }, + { + "name": "Heyuannia", + "description": "Yet another close relative of Oviraptor." + }, + { + "name": "Hippodraco", + "description": "This \"horse dragon\" was recently discovered in Utah." + }, + { + "name": "Homalocephale", + "description": "This herbivore had a very flat--and very thick--skull." + }, + { + "name": "Hongshanosaurus", + "description": "This early ceratopsian is known by two skulls." + }, + { + "name": "Hoplitosaurus", + "description": "named after the heavily armored soldiers of classical Greece." + }, + { + "name": "Huabeisaurus", + "description": "A titanosaur from northern China." + }, + { + "name": "Huanghetitan", + "description": "Yet another contender for the biggest dinosaur that ever lived." + }, + { + "name": "Huaxiagnathus", + "description": "One of the biggest dino-birds of its time." + }, + { + "name": "Huaxiaosaurus", + "description": "Might it be an unusually large specimen of Shantungosaurus?" + }, + { + "name": "Huayangosaurus", + "description": "Could this have been the ancestor of all the stegosaurs?" + }, + { + "name": "Huehuecanauhtlus", + "description": "Its name is Aztec for \"ancient duck\"." + }, + { + "name": "Hungarosaurus", + "description": "The best-attested ankylosaur ever discovered in Europe." + }, + { + "name": "Huxleysaurus", + "description": "named after the famous biologist Thomas Henry Huxley." + }, + { + "name": "Hylaeosaurus", + "description": "One of the first creatures ever to be called a dinosaur." + }, + { + "name": "Hypacrosaurus", + "description": "We know a lot about this dinosaur's family life." + }, + { + "name": "Hypselosaurus", + "description": "This titanosaur's eggs were a foot in diameter." + }, + { + "name": "Hypselospinus", + "description": "It was once classified as a species of Iguanodon." + }, + { + "name": "Hypsibema", + "description": "The official state dinosaur of Missouri." + }, + { + "name": "Hypsilophodon", + "description": "This man-sized herbivore liked to eat and run." + }, + { + "name": "Ichthyovenator", + "description": "This sail-backed dinosaur was recently discovered in Laos." + }, + { + "name": "Ignavusaurus", + "description": "Its name means \"cowardly lizard\"." + }, + { + "name": "Iguanacolossus", + "description": "A brand-new ornithopod from North America." + }, + { + "name": "Iguanodon", + "description": "The second dinosaur in history ever to receive a name." + }, + { + "name": "Ilokelesia", + "description": "A primitive abelisaur from South America." + }, + { + "name": "Incisivosaurus", + "description": "This buck-toothed dinosaur was the Cretaceous equivalent of a beaver." + }, + { + "name": "Indosuchus", + "description": "This \"Indian crocodile\" was actually a dinosaur." + }, + { + "name": "Ingenia", + "description": "A small, birdlike dinosaur from central Asia." + }, + { + "name": "Irritator", + "description": "This spinosaur was named by a very frustrated paleontologist." + }, + { + "name": "Isanosaurus", + "description": "One of the first sauropods ever to walk the earth." + }, + { + "name": "Isisaurus", + "description": "Otherwise known as the Indian Statistical Institute Lizard." + }, + { + "name": "Jainosaurus", + "description": "named after the Indian paleontologist Sohan Lal Jain." + }, + { + "name": "Janenschia", + "description": "The earliest titanosaur in the fossil record." + }, + { + "name": "Jaxartosaurus", + "description": "A poorly known hadrosaur from central Asia." + }, + { + "name": "Jeholosaurus", + "description": "This ornithopod may have had an omnivorous diet." + }, + { + "name": "Jeyawati", + "description": "Its name is Zuni for \"grinding mouth\"." + }, + { + "name": "Jianchangosaurus", + "description": "One of the earliest therizinosaurs in the fossil record." + }, + { + "name": "Jinfengopteryx", + "description": "This feathered dinosaur was once thought to be a true bird." + }, + { + "name": "Jingshanosaurus", + "description": "A close relative of Yunnanosaurus." + }, + { + "name": "Jinzhousaurus", + "description": "This Asian dinosaur was one of the first hadrosaurs." + }, + { + "name": "Jobaria", + "description": "A strange, short-tailed African sauropod." + }, + { + "name": "Judiceratops", + "description": "The earliest Chasmosaurus ancestor yet identified." + }, + { + "name": "Juratyrant", + "description": "This early tyrannosaur was discovered in England." + }, + { + "name": "Juravenator", + "description": "Why didn't this presumed \"dino-bird\" have feathers?" + }, + { + "name": "Kaatedocus", + "description": "This Diplodocus relative had a characteristic grin." + }, + { + "name": "Kaijiangosaurus", + "description": "This might have been the same dinosaur as Gasosaurus." + }, + { + "name": "Kazaklambia", + "description": "This duck-billed dinosaur was discovered in Kazakhstan." + }, + { + "name": "Kentrosaurus", + "description": "A smaller, African cousin of Stegosaurus." + }, + { + "name": "Kerberosaurus", + "description": "named after the three-headed dog of Greek myth." + }, + { + "name": "Khaan", + "description": "Few small mammals dared face the wrath of this dinosaur." + }, + { + "name": "Kileskus", + "description": "Yet another \"basal\" tyrannosaur from central Asia." + }, + { + "name": "Kinnareemimus", + "description": "This \"bird mimic\" dinosaur was recently discovered in Thailand." + }, + { + "name": "Kol", + "description": "It's tied with Mei for \"shortest dinosaur name\"." + }, + { + "name": "Koreaceratops", + "description": "There's evidence that this ceratopsian liked to go swimming." + }, + { + "name": "Koreanosaurus", + "description": "Guess what country this ornithopod was discovered in." + }, + { + "name": "Kosmoceratops", + "description": "This ceratopsian had a bizarre, downward-folding frill." + }, + { + "name": "Kotasaurus", + "description": "One of the few sauropods to be discovered in India." + }, + { + "name": "Kritosaurus", + "description": "A famous, but poorly understood hadrosaur." + }, + { + "name": "Kryptops", + "description": "This dinosaur came equipped with its own face mask." + }, + { + "name": "Kukufeldia", + "description": "Yet another ornithopod that was once lumped in with Iguanodon." + }, + { + "name": "Kulindadromeus", + "description": "Why did this ornithopod dinosaur have feathers?" + }, + { + "name": "Kundurosaurus", + "description": "This hadrosaur was discovered in the far east of Russia." + }, + { + "name": "Labocania", + "description": "It may or may not have been a true tyrannosaur." + }, + { + "name": "Lagosuchus", + "description": "Could this have been the ancestor of all the dinosaurs?" + }, + { + "name": "Lambeosaurus", + "description": "This duck-billed dinosaur had a hatchet-shaped crest on its noggin." + }, + { + "name": "Lamplughsaura", + "description": "This early sauropod was discovered in India." + }, + { + "name": "Lanzhousaurus", + "description": "This herbivore's teeth were half a foot long." + }, + { + "name": "Laosaurus", + "description": "This dubious ornithopod was named by Othniel C. Marsh." + }, + { + "name": "Lapparentosaurus", + "description": "This sauropod was discovered in Madagascar." + }, + { + "name": "Laquintasaura", + "description": "The first plant-eating dinosaur ever to be discovered in Venezuela." + }, + { + "name": "Latirhinus", + "description": "This duck-billed dinosaur had an enormous nose." + }, + { + "name": "Leaellynasaura", + "description": "One of the few dinosaurs to be named after a little girl." + }, + { + "name": "Leinkupal", + "description": "The latest surviving diplodocid sauropod." + }, + { + "name": "Leonerasaurus", + "description": "This prosauropod was recently discovered in Argentina." + }, + { + "name": "Leptoceratops", + "description": "One of the most primitive of all ceratopsians." + }, + { + "name": "Leshansaurus", + "description": "Did this meat-eater feast on small, armored dinosaurs?" + }, + { + "name": "Lesothosaurus", + "description": "One of the earliest of all the ornithischian dinosaurs." + }, + { + "name": "Lessemsaurus", + "description": "named after the popular science writer Don Lessem." + }, + { + "name": "Lexovisaurus", + "description": "One of the oldest European stegosaurs." + }, + { + "name": "Leyesaurus", + "description": "A newly discovered prosauropod from South America." + }, + { + "name": "Liaoceratops", + "description": "A tiny ceratopsian of early Cretaceous Asia." + }, + { + "name": "Liaoningosaurus", + "description": "One of the smallest ankylosaurs in the fossil record." + }, + { + "name": "Liliensternus", + "description": "One of the largest carnivores of the Triassic period." + }, + { + "name": "Limaysaurus", + "description": "It was once classified as a species of Rebbachisaurus." + }, + { + "name": "Limusaurus", + "description": "Was this toothless theropod a vegetarian?" + }, + { + "name": "Linhenykus", + "description": "This tiny dinosaur had single-clawed hands." + }, + { + "name": "Linheraptor", + "description": "This Mongolian raptor was discovered in 2008." + }, + { + "name": "Linhevenato", + "description": "r This troodont was recently discovered in Mongolia." + }, + { + "name": "Lophorhothon", + "description": "The first dinosaur ever to be discovered in Alabama." + }, + { + "name": "Lophostropheus", + "description": "This theropod lived near the Triassic/Jurassic boundary." + }, + { + "name": "Loricatosaurus", + "description": "This stegosaur was once classified as a species of Lexovisaurus." + }, + { + "name": "Lourinhanosaurus", + "description": "Not to be confused with Lourinhasaurus, below." + }, + { + "name": "Lourinhasaurus", + "description": "Not to be confused with Lourinhanosaurus, above." + }, + { + "name": "Luanchuanraptor", + "description": "A small, poorly understood Asian raptor." + }, + { + "name": "Lufengosaurus", + "description": "A common sight at Chinese natural history museums." + }, + { + "name": "Lurdusaurus", + "description": "This ornithopod resembled a giant sloth." + }, + { + "name": "Lusotitan", + "description": "This sauropod was once classified as a species of Brachiosaurus." + }, + { + "name": "Lycorhinus", + "description": "This dinosaur was once thought to be a mammal-like reptile." + }, + { + "name": "Lythronax", + "description": "This tyrannosaur lived on the island of Laramidia." + }, + { + "name": "Machairasaurus", + "description": "This \"short scimitar lizard\" was a close relative of Oviraptor." + }, + { + "name": "Macrogryphosaurus", + "description": "Otherwise known as the Big Enigmatic Lizard." + }, + { + "name": "Magnapaulia", + "description": "The largest lambeosaurine hadrosaur yet identified." + }, + { + "name": "Magnirostris", + "description": "This ceratopsian had an unusually big beak." + }, + { + "name": "Magnosaurus", + "description": "Once thought to be a species of Megalosaurus." + }, + { + "name": "Magyarosaurus", + "description": "This dwarf titanosaur was probably confined to a small island." + }, + { + "name": "Mahakala", + "description": "This dino-bird was named after a Buddhist deity." + }, + { + "name": "Maiasaura", + "description": "This \"good mother lizard\" kept close tabs on her young." + }, + { + "name": "Majungasaurus", + "description": "Fairly--or unfairly--known as the \"cannibal dinosaur\"." + }, + { + "name": "Malawisaurus", + "description": "The first titanosaur to be found with an intact skull." + }, + { + "name": "Mamenchisaurus", + "description": "The longest-necked dinosaur that ever lived." + }, + { + "name": "Manidens", + "description": "A strangely toothed relative of Heterodontosaurus." + }, + { + "name": "Mantellisaurus", + "description": "named after the famous fossil hunter Gideon Mantell." + }, + { + "name": "Mantellodon", + "description": "This Iguanodon refugee may or may not deserve its own genus." + }, + { + "name": "Mapusaurus", + "description": "This huge carnivore was closely related to Giganotosaurus." + }, + { + "name": "Marshosaurus", + "description": "named after the famous paleontologist Othniel C. Marsh." + }, + { + "name": "Martharaptor", + "description": "This dinosaur was named after a Utah paleontologist." + }, + { + "name": "Masiakasaurus", + "description": "A bizarre, buck-toothed predator of the late Cretaceous." + }, + { + "name": "Massospondylus", + "description": "This small, lithe, bipedal plant-eater roamed the plains of South Africa." + }, + { + "name": "Maxakalisaurus", + "description": "One of the biggest titanosaurs ever found in Brazil." + }, + { + "name": "Medusaceratops", + "description": "This frilled dinosaur was a close relative of Centrosaurus." + }, + { + "name": "Megalosaurus", + "description": "The first dinosaur ever to be discovered and named." + }, + { + "name": "Megapnosaurus", + "description": "Its name is Greek for \"big dead lizard\"." + }, + { + "name": "Megaraptor", + "description": "Despite its name, it wasn't really a raptor." + }, + { + "name": "Mei", + "description": "The current record-holder for \"shortest dinosaur name\"." + }, + { + "name": "Melanorosaurus", + "description": "Probably the largest prosauropod that ever lived." + }, + { + "name": "Mendozasaurus", + "description": "This titanosaur was ancestral to Futalognkosaurus." + }, + { + "name": "Mercuriceratops", + "description": "This ceratopsian was discovered on the U.S./Canada border." + }, + { + "name": "Metriacanthosaurus", + "description": "Yet another dinosaur that was once mistaken for Megalosaurus." + }, + { + "name": "Microceratops", + "description": "Probably the smallest ceratopsian that ever lived." + }, + { + "name": "Micropachycephalosaurus", + "description": "The current record-holder for longest dinosaur name." + }, + { + "name": "Microraptor", + "description": "This tiny feathered dinosaur had four wings rather than two." + }, + { + "name": "Microvenator", + "description": "This \"tiny hunter\" actually measured 10 feet from head to tail." + }, + { + "name": "Minmi", + "description": "An early (and very dumb) ankylosaur from Australia." + }, + { + "name": "Minotaurasaurus", + "description": "named after the half-man, half-bull of Greek myth." + }, + { + "name": "Miragaia", + "description": "This stegosaur had an unusually long neck." + }, + { + "name": "Mirischia", + "description": "Its name means \"wonderful pelvis\"." + }, + { + "name": "Mochlodon", + "description": "One of the few dinosaurs ever to be discovered in Austria." + }, + { + "name": "Mojoceratops", + "description": "This ceratopsian had a heart-shaped frill." + }, + { + "name": "Monkonosaurus", + "description": "The first dinosaur ever to be discovered in modern-day Tibet." + }, + { + "name": "Monoclonius", + "description": "Might this have been a species of Centrosaurus?" + }, + { + "name": "Monolophosaurus", + "description": "This Jurassic predator had a single crest on its skull." + }, + { + "name": "Mononykus", + "description": "This dinosaur may have dug into termite mounds for its lunch." + }, + { + "name": "Montanoceratops", + "description": "A primitive ceratopsian of the late Cretaceous period." + }, + { + "name": "Mussaurus", + "description": "This \"mouse lizard\" lived in Triassic South America." + }, + { + "name": "Muttaburrasaurus", + "description": "The most complete dinosaur fossil ever found in Australia." + }, + { + "name": "Mymoorapelta", + "description": "named after the Mygand-Moore quarry in Colorado." + }, + { + "name": "Nankangia", + "description": "A recently discovered oviraptor from China." + }, + { + "name": "Nanosaurus", + "description": "This \"tiny lizard\" was named by Othniel C. Marsh." + }, + { + "name": "Nanotyrannus", + "description": "Could this have been a juvenile T. Rex?" + }, + { + "name": "Nanshiungosaurus", + "description": "A bizarre therizinosaur from Asia." + }, + { + "name": "Nanuqsaurus", + "description": "This \"polar lizard\" was recently discovered in Alaska." + }, + { + "name": "Nanyangosaurus", + "description": "An iguanodontid ornithopod of middle Cretaceous Asia." + }, + { + "name": "Nasutoceratops", + "description": "This dinosaur had horns like a modern steer." + }, + { + "name": "Nebulasaurus", + "description": "This \"nebula lizard\" was recently discovered in China." + }, + { + "name": "Nedcolbertia", + "description": "named after the famous paleontologist Edwin Colbert." + }, + { + "name": "Neimongosaurus", + "description": "A rare therizinosaur from inner Mongolia." + }, + { + "name": "Nemegtomaia", + "description": "This dinosaur had a bizarrely shaped skull." + }, + { + "name": "Nemegtosaurus", + "description": "This titanosaur has been recreated from a single, incomplete skull." + }, + { + "name": "Neovenator", + "description": "One of the largest carnivorous dinosaurs of western Europe." + }, + { + "name": "Neuquenraptor", + "description": "It may actually be a species (or specimen) of Unenlagia." + }, + { + "name": "Neuquensaurus", + "description": "Was this titanosaur really a species of Saltasaurus?" + }, + { + "name": "Nigersaurus", + "description": "This African sauropod had a huge number of teeth." + }, + { + "name": "Nipponosaurus", + "description": "This hadrosaur was discovered on the island of Sakhalin." + }, + { + "name": "Noasaurus", + "description": "Were this predator's giant claws on its hands, or on its feet?" + }, + { + "name": "Nodocephalosaurus", + "description": "This armored dinosaur has been reconstructed from a single skull." + }, + { + "name": "Nodosaurus", + "description": "One of the first armored dinosaurs ever discovered in North America." + }, + { + "name": "Nomingia", + "description": "This small dinosaur had a peacock-like tail." + }, + { + "name": "Nothronychus", + "description": "The first therizonosaur to be found outside Asia." + }, + { + "name": "Notohypsilophodon", + "description": "A rare South American ornithopod." + }, + { + "name": "Nqwebasaurus", + "description": "One of the few theropods to be discovered in sub-Saharan Africa." + }, + { + "name": "Nuthetes", + "description": "This raptor was named after the modern monitor lizard." + }, + { + "name": "Nyasasaurus", + "description": "Could this be the earliest dinosaur in the fossil record?" + }, + { + "name": "Ojoceratops", + "description": "A very close relative of Triceratops." + }, + { + "name": "Olorotitan", + "description": "One of the most complete dinosaur fossils ever found in Russia." + }, + { + "name": "Omeisaurus", + "description": "One of the most common Chinese sauropods." + }, + { + "name": "Oohkotokia", + "description": "Its name is Blackfoot for \"large stone\"." + }, + { + "name": "Opisthocoelicaudia", + "description": "A clumsily named titanosaur of the late Cretaceous period." + }, + { + "name": "Orkoraptor", + "description": "The southernmost theropod ever to live in South America." + }, + { + "name": "Ornithodesmus", + "description": "This mysterious raptor was once thought to be a pterosaur." + }, + { + "name": "Ornitholestes", + "description": "This \"bird robber\" probably preyed on small lizards instead." + }, + { + "name": "Ornithomimus", + "description": "This \"bird mimic\" resembled a modern ostrich." + }, + { + "name": "Ornithopsis", + "description": "This \"bird face\" was actually a genus of titanosaur." + }, + { + "name": "Orodromeus", + "description": "This tiny herbivore was on Troodon's dinner menu." + }, + { + "name": "Orthomerus", + "description": "One of the few dinosaurs to be discovered in Holland." + }, + { + "name": "Oryctodromeus", + "description": "The only ornithopod known to have lived in burrows." + }, + { + "name": "Ostafrikasaurus", + "description": "Could this have been the earliest known spinosaur?" + }, + { + "name": "Othnielia", + "description": "named after the famous paleontologist Othniel C. Marsh." + }, + { + "name": "Othnielosaurus", + "description": "Also named after the famous paleontologist Othniel C. Marsh." + }, + { + "name": "Ouranosaurus", + "description": "Scientists can't decide if this herbivore had a sail or a hump." + }, + { + "name": "Overosaurus", + "description": "This dwarf titanosaur was announced to the world in 2013." + }, + { + "name": "Oviraptor", + "description": "Turns out that this \"egg thief\" got a bad rap." + }, + { + "name": "Oxalaia", + "description": "This spinosaur was recently discovered in Brazil." + }, + { + "name": "Ozraptor", + "description": "Not much is known about this Australian theropod." + }, + { + "name": "Pachycephalosaurus", + "description": "This plant-eater gave new meaning to the word \"blockhead\"." + }, + { + "name": "Pachyrhinosaurus", + "description": "This \"thick-nosed lizard\" roamed the North American forests." + }, + { + "name": "Palaeoscincus", + "description": "This \"ancient skink\" was actually an armored dinosaur." + }, + { + "name": "Paluxysaurus", + "description": "The official Texas state dinosaur." + }, + { + "name": "Pampadromaeus", + "description": "This \"Pampas runner\" was ancestral to sauropods." + }, + { + "name": "Pamparaptor", + "description": "This raptor was discovered in the Argentinian Pampas." + }, + { + "name": "Panamericansaurus", + "description": "This titanosaur was named after an energy company." + }, + { + "name": "Panoplosaurus", + "description": "A squat, stocky nodosaur of the late Cretaceous." + }, + { + "name": "Panphagia", + "description": "Its name is Greek for \"eats everything\"." + }, + { + "name": "Pantydraco", + "description": "No, this dinosaur didn't wear you-know-what." + }, + { + "name": "Paralititan", + "description": "This huge sauropod was discovered recently in Egypt." + }, + { + "name": "Paranthodon", + "description": "This stegosaur was discovered over 150 years ago." + }, + { + "name": "Pararhabdodon", + "description": "The western European equivalent of Tsintaosaurus." + }, + { + "name": "Parasaurolophus", + "description": "Possibly the loudest dinosaur ever to roam the earth." + }, + { + "name": "Parksosaurus", + "description": "It was once classified as a species of Thescelosaurus." + }, + { + "name": "Paronychodon", + "description": "This \"tooth taxon\" didn't make it out of the 19th century." + }, + { + "name": "Parvicursor", + "description": "One of the smallest dinosaurs yet identified." + }, + { + "name": "Patagosaurus", + "description": "This \"Patagonian lizard\" hailed from South America." + }, + { + "name": "Pawpawsaurus", + "description": "This ancient nodosaur was discovered in Texas." + }, + { + "name": "Pedopenna", + "description": "One of the earliest known dino-birds." + }, + { + "name": "Pegomastax", + "description": "This dinosaur was covered with porcupine-like bristles." + }, + { + "name": "Pelecanimimus", + "description": "This \"pelican mimic\" sported over 200 teeth." + }, + { + "name": "Peloroplites", + "description": "This \"monstrous Hoplite\" was recently discovered in Utah." + }, + { + "name": "Pelorosaurus", + "description": "The first sauropod ever to be discovered." + }, + { + "name": "Pentaceratops", + "description": "This \"five-horned\" herbivore really had only three." + }, + { + "name": "Philovenator", + "description": "As its name says this dinosaur \"loved to hunt\"." + }, + { + "name": "Phuwiangosaurus", + "description": "This titanosaur was discovered in modern-day Thailand." + }, + { + "name": "Piatnitzkysaurus", + "description": "Its teeth were as sharp as its name is funny." + }, + { + "name": "Pinacosaurus", + "description": "Did this ankylosaur roam central Asia in herds?" + }, + { + "name": "Pisanosaurus", + "description": "One of the earliest known ornithischian dinosaurs." + }, + { + "name": "Piveteausaurus", + "description": "No one is quite sure what to make of this theropod dinosaur." + }, + { + "name": "Planicoxa", + "description": "A medium-sized iguanodont of early Cretaceous North America." + }, + { + "name": "Plateosaurus", + "description": "This herd dinosaur blackened the plains of the late Triassic." + }, + { + "name": "Pleurocoelus", + "description": "It was the official state dinosaur of Texas." + }, + { + "name": "Pneumatoraptor", + "description": "This \"air thief\" was recently discovered in Hungary." + }, + { + "name": "Podokesaurus", + "description": "One of the earliest dinosaurs to live in eastern North America." + }, + { + "name": "Poekilopleuron", + "description": "It may (or may not) have been a species of Megalosaurus." + }, + { + "name": "Polacanthus", + "description": "An extremely spiky ankylosaur of the middle Cretaceous." + }, + { + "name": "Prenocephale", + "description": "This \"bonehead\" had a round, thick skull." + }, + { + "name": "Prenoceratops", + "description": "A close relative of Leptoceratops." + }, + { + "name": "Proa", + "description": "This ornithopod was named after its prow-shaped jaw." + }, + { + "name": "Probactrosaurus", + "description": "An early stage in hadrosaur evolution." + }, + { + "name": "Proceratosaurus", + "description": "Despite its name, not a close relative of Ceratosaurus." + }, + { + "name": "Procompsognathus", + "description": "Was it an archosaur or an early dinosaur?" + }, + { + "name": "Propanoplosaurus", + "description": "This baby ankylosaur was recently discovered in Maryland." + }, + { + "name": "Prosaurolophus", + "description": "The likely ancestor of both Saurolophus and Parasaurolophus." + }, + { + "name": "Protarchaeopteryx", + "description": "Before Archaeopteryx? It actually lived millions of years later." + }, + { + "name": "Protoceratops", + "description": "A famous dinosaur with a very funky frill." + }, + { + "name": "Protohadros", + "description": "Despite its name, it wasn't really the \"first\" hadrosaur." + }, + { + "name": "Psittacosaurus", + "description": "This dinosaur's noggin wouldn't have looked out of place on a parrot." + }, + { + "name": "Puertasaurus", + "description": "This titanosaur rivaled Argentinosaurus in size." + }, + { + "name": "Pyroraptor", + "description": "This \"fire thief\" prowled the plains of prehistoric France." + }, + { + "name": "Qantassaurus", + "description": "named after the national airline of Australia." + }, + { + "name": "Qianzhousaurus", + "description": "This long-snouted tyrannosaur has been nicknamed Pinocchio Rex." + }, + { + "name": "Qiaowanlong", + "description": "An Asian relative of Brachiosaurus." + }, + { + "name": "Qiupalong", + "description": "This \"bird mimic\" dinosaur was recently discovered in China." + }, + { + "name": "Quaesitosaurus", + "description": "This titanosaur may have had remarkably sharp hearing." + }, + { + "name": "Quilmesaurus", + "description": "This dinosaur was named after an indigenous South American tribe." + }, + { + "name": "Rahiolisaurus", + "description": "This Indian dinosaur is represented by seven tangled individuals." + }, + { + "name": "Rahonavis", + "description": "Was it a raptor-like bird or a bird-like raptor?" + }, + { + "name": "Rajasaurus", + "description": "This \"prince lizard\" lived in what is now modern-day India." + }, + { + "name": "Rapator", + "description": "No, this mysterious Australian theropod wasn't a raptor." + }, + { + "name": "Rapetosaurus", + "description": "The only sauropod ever to be discovered on modern-day Madagascar." + }, + { + "name": "Raptorex", + "description": "A pint-sized precursor of T. Rex." + }, + { + "name": "Rebbachisaurus", + "description": "A poorly understood sauropod from northern Africa." + }, + { + "name": "Regaliceratops", + "description": "This ceratopsian had a huge, crown-shaped frill." + }, + { + "name": "Regnosaurus", + "description": "This stegosaur lived in what is now modern-day England." + }, + { + "name": "Rhabdodon", + "description": "A possible \"missing link\" between Iguanodon and Hypsilophodon." + }, + { + "name": "Rhinorex", + "description": "This duck-billed dinosaur had an unusually large nose." + }, + { + "name": "Rhoetosaurus", + "description": "A medium-sized sauropod from Down Under." + }, + { + "name": "Richardoestesia", + "description": "named after the paleontologist Richard Estes." + }, + { + "name": "Rinchenia", + "description": "named after the famous paleontologist Rinchen Barsbold." + }, + { + "name": "Rinconsaurus", + "description": "A modestly sized titanosaur of South America." + }, + { + "name": "Riojasaurus", + "description": "One of the few prosauropods known to have lived in South America." + }, + { + "name": "Rubeosaurus", + "description": "A ceratopsian dinosaur from the Two Medicine Formation." + }, + { + "name": "Rugops", + "description": "This wrinkly-faced carnivore probably fed on abandoned carcasses." + }, + { + "name": "Sahaliyania", + "description": "This hadrosaur's name is Manchurian for \"black\"." + }, + { + "name": "Saichania", + "description": "This ankylosaur's name is Chinese for \"beautiful\"." + }, + { + "name": "Saltasaurus", + "description": "The first armored sauropod ever to be discovered." + }, + { + "name": "Saltopus", + "description": "Experts aren't sure if this was a dinosaur or an archosaur." + }, + { + "name": "Sanjuansaurus", + "description": "An early theropod from South America." + }, + { + "name": "Santanaraptor", + "description": "named after Brazil's Santana formation." + }, + { + "name": "Sarahsaurus", + "description": "This prosauropod had unusually strong hands." + }, + { + "name": "Sarcolestes", + "description": "The most likely ancestor of the ankylosaurs." + }, + { + "name": "Sarcosaurus", + "description": "This \"flesh lizard\" roamed early Jurassic England." + }, + { + "name": "Saturnalia", + "description": "The earliest dinosaur known to have had a herbivorous diet." + }, + { + "name": "Saurolophus", + "description": "One of the few hadrosaurs known to have lived on two continents." + }, + { + "name": "Sauroniops", + "description": "This dinosaur's name means \"Eye of Sauron\"." + }, + { + "name": "Sauropelta", + "description": "This ankylosaur's armor helped keep raptors at bay." + }, + { + "name": "Saurophaganax", + "description": "The official state dinosaur of Oklahoma." + }, + { + "name": "Sauroposeidon", + "description": "One of the tallest dinosaurs ever to walk the earth." + }, + { + "name": "Saurornithoides", + "description": "A Troodon-like predator from central Asia." + }, + { + "name": "Saurornitholestes", + "description": "A close cousin of Velociraptor." + }, + { + "name": "Savannasaurus", + "description": "This titanosaur was recently discovered in Australia." + }, + { + "name": "Scansoriopteryx", + "description": "This early proto-bird probably lived in trees." + }, + { + "name": "Scelidosaurus", + "description": "Among the earliest of all the armored dinosaurs." + }, + { + "name": "Scipionyx", + "description": "One of the most perfectly preserved dinosaur fossils ever found." + }, + { + "name": "Sciurumimus", + "description": "This \"squirrel mimic\" was one of the earliest feathered dinosaurs." + }, + { + "name": "Scolosaurus", + "description": "It was once classified as a species of Euoplocephalus." + }, + { + "name": "Scutellosaurus", + "description": "Probably the smallest of all the armored dinosaurs." + }, + { + "name": "Secernosaurus", + "description": "The first hadrosaur to be discovered in South America." + }, + { + "name": "Seitaad", + "description": "This small dinosaur may have been buried in an avalanche." + }, + { + "name": "Segisaurus", + "description": "An early dinosaur closely related to Coelophysis." + }, + { + "name": "Segnosaurus", + "description": "One of the most unusual (and poorly understood) Cretaceous dinosaurs." + }, + { + "name": "Seismosaurus", + "description": "It was huge, to be sure, but might it have been a species of Diplodocus?" + }, + { + "name": "Sellosaurus", + "description": "Another early prosauropod of the Triassic period." + }, + { + "name": "Serendipaceratops", + "description": "Was this really an Australian ceratopsian?" + }, + { + "name": "Shamosaurus", + "description": "This Mongolian ankylosaur was a close relative of Gobisaurus." + }, + { + "name": "Shanag", + "description": "A basal raptor of early Cretaceous Asia." + }, + { + "name": "Shantungosaurus", + "description": "The biggest of all the duck-billed dinosaurs." + }, + { + "name": "Shaochilong", + "description": "Its name is Chinese for \"shark-toothed dragon\"." + }, + { + "name": "Shenzhousaurus", + "description": "A small, primitive ornithomimid from China." + }, + { + "name": "Shunosaurus", + "description": "Anatomically speaking, probably the best known of all the sauropods." + }, + { + "name": "Shuvosaurus", + "description": "Was this meat eater an early dinosaur or a two-legged crocodile?" + }, + { + "name": "Shuvuuia", + "description": "Scientists can't decide if it was a dinosaur or a bird." + }, + { + "name": "Siamodon", + "description": "This ornithopod was recently discovered in Thailand." + }, + { + "name": "Siamosaurus", + "description": "This may (or may not) have been a spinosaur from Thailand." + }, + { + "name": "Siamotyrannus", + "description": "Despite its name, it wasn't a true tyrannosaur." + }, + { + "name": "Siats", + "description": "One of the largest theropods ever to live in North America." + }, + { + "name": "Sigilmassasaurus", + "description": "Was this really a species of Carcharodontosaurus?" + }, + { + "name": "Silvisaurus", + "description": "This primitive nodosaur was discovered in Kansas." + }, + { + "name": "Similicaudipteryx", + "description": "The juveniles may have been differently feathered than the adults." + }, + { + "name": "Sinocalliopteryx", + "description": "The biggest \"dino-bird\" yet discovered." + }, + { + "name": "Sinoceratops", + "description": "A rare ceratopsian from late Cretaceous China." + }, + { + "name": "Sinornithoides", + "description": "A small, feathered dinosaur closely related to Troodon." + }, + { + "name": "Sinornithomimus", + "description": "This ornithomimid is known from over a dozen skeletons." + }, + { + "name": "Sinornithosaurus", + "description": "A typical dino-bird of the early Cretaceous." + }, + { + "name": "Sinosauropteryx", + "description": "The first dinosaur proven to have feathers." + }, + { + "name": "Sinosaurus", + "description": "It was once classified as an Asian species of Dilophosaurus." + }, + { + "name": "Sinotyrannus", + "description": "This \"Chinese tyrant\" was an ancient ancestor of tyrannosaurs." + }, + { + "name": "Sinovenator", + "description": "This \"Chinese hunter\" preyed on its fellow dino-birds." + }, + { + "name": "Sinraptor", + "description": "Despite its name, this allosaur wasn't any better or worse than other dinosaurs." + }, + { + "name": "Sinusonasus", + "description": "It sounds like a disease, but it was actually a feathered dinosaur." + }, + { + "name": "Skorpiovenator", + "description": "This \"scorpion hunter\" really ate meat." + }, + { + "name": "Sonorasaurus", + "description": "The remains of this sauropod were discovered in Arizona." + }, + { + "name": "Sphaerotholus", + "description": "Yet another dome-headed dino from North America." + }, + { + "name": "Spinophorosaurus", + "description": "This early sauropod had a \"thagomizer\" on its tail." + }, + { + "name": "Spinops", + "description": "This ceratopsian was named 100 years after its bones were found." + }, + { + "name": "Spinosaurus", + "description": "This dinosaur was distinguished by the sail-like structure on its back." + }, + { + "name": "Spinostropheus", + "description": "This theropod was once thought to be a species of Elaphrosaurus." + }, + { + "name": "Staurikosaurus", + "description": "Another primitive theropod of the Triassic period." + }, + { + "name": "Stegoceras", + "description": "This small herbivore was built for high-speed head-butting." + }, + { + "name": "Stegosaurus", + "description": "The small-brained, spike-tailed, plant-eating dinosaur." + }, + { + "name": "Stenopelix", + "description": "Experts aren't sure how to classify this dinosaur." + }, + { + "name": "Stokesosaurus", + "description": "Some experts think this was the earliest tyrannosaur." + }, + { + "name": "Struthiomimus", + "description": "This \"ostrich mimic\" roamed the plains of North America." + }, + { + "name": "Struthiosaurus", + "description": "The smallest nodosaur yet discovered." + }, + { + "name": "Stygimoloch", + "description": "Its name means \"demon from the river of death.\" Got your attention yet?" + }, + { + "name": "Styracosaurus", + "description": "Winner of the \"most elaborate head display\" competition." + }, + { + "name": "Suchomimus", + "description": "A fish-eating dinosaur with a distinct crocodilian profile." + }, + { + "name": "Sulaimanisaurus", + "description": "One of the few dinosaurs ever to be discovered in Pakistan." + }, + { + "name": "Supersaurus", + "description": "No, it didn't wear a cape, but this giant dino was still impressive." + }, + { + "name": "Suuwassea", + "description": "Its name is Native American for \"ancient thunder\"." + }, + { + "name": "Suzhousaurus", + "description": "A large, early Cretaceous therizinosaur." + }, + { + "name": "Szechuanosaurus", + "description": "This theropod was a close relative of Sinraptor." + }, + { + "name": "Tachiraptor", + "description": "The first meat-eating dinosaur ever to be discovered in Venezuela." + }, + { + "name": "Talarurus", + "description": "This ankylosaur was discovered in the Gobi Desert." + }, + { + "name": "Talos", + "description": "This dinosaur was found with an injured big toe." + }, + { + "name": "Tangvayosaurus", + "description": "This Laotian titanosaur was closely related to Phuwiangosaurus." + }, + { + "name": "Tanius", + "description": "Not much is known about this Chinese hadrosaur." + }, + { + "name": "Tanycolagreus", + "description": "This mysterious theropod was once thought to be a species of Coelurus." + }, + { + "name": "Taohelong", + "description": "The first \"polacanthine\" ankylosaur ever to be discovered in Asia." + }, + { + "name": "Tapuiasaurus", + "description": "A recently discovered titanosaur from South America." + }, + { + "name": "Tarascosaurus", + "description": "The only known abelisaur of the northern hemisphere." + }, + { + "name": "Tarbosaurus", + "description": "The second-biggest tyrannosaur after T. Rex." + }, + { + "name": "Tarchia", + "description": "Its name means \"brainy,\" but that may be an exaggeration." + }, + { + "name": "Tastavinsaurus", + "description": "This titanosaur was discovered in Spain." + }, + { + "name": "Tatankacephalus", + "description": "A brand-new ankylosaur from North America." + }, + { + "name": "Tatankaceratops", + "description": "Was this really a juvenile specimen of Triceratops?" + }, + { + "name": "Tataouinea", + "description": "No, this dinosaur wasn't named after Tatooine in Star Wars." + }, + { + "name": "Tawa", + "description": "This ancient theropod points to a South American origin for dinosaurs." + }, + { + "name": "Tazoudasaurus", + "description": "This Vulcanodon relative was one of the earliest sauropods." + }, + { + "name": "Technosaurus", + "description": "This early herbivore was named after Texas Tech university." + }, + { + "name": "Tehuelchesaurus", + "description": "This sauropod was named after an indigenous South American people." + }, + { + "name": "Telmatosaurus", + "description": "This duck-billed dinosaur was discovered in Transylvania." + }, + { + "name": "Tendaguria", + "description": "This Tanzanian sauropod has proven difficult to classify." + }, + { + "name": "Tenontosaurus", + "description": "This long-tailed herbivore was hunted by Deinonychus." + }, + { + "name": "Teratophoneus", + "description": "This \"monstrous murderer\" wasn't all that big." + }, + { + "name": "Tethyshadros", + "description": "One of the few dinosaurs to be found in modern-day Italy." + }, + { + "name": "Texacephale", + "description": "This Texan pachycephalosaur was named in 2010." + }, + { + "name": "Thecocoelurus", + "description": "Is this the earliest ornithomimid in the fossil record?" + }, + { + "name": "Thecodontosaurus", + "description": "The first prosauropod ever to be discovered." + }, + { + "name": "Theiophytalia", + "description": "Its name means \"garden of the gods\"." + }, + { + "name": "Therizinosaurus", + "description": "What did Little Orphan Annie say to this dinosaur? \"Reaping lizards!\"" + }, + { + "name": "Thescelosaurus", + "description": "Did paleontologists find this dinosaur's mummified heart?" + }, + { + "name": "Tianchisaurus", + "description": "This dinosaur's species name honors \"Jurassic Park\"." + }, + { + "name": "Tianyulong", + "description": "Why did this ornithopod have feathers?" + }, + { + "name": "Tianyuraptor", + "description": "A small, long-legged raptor from eastern Asia." + }, + { + "name": "Tianzhenosaurus", + "description": "This ankylosaur's skull has been spectacularly preserved." + }, + { + "name": "Timimus", + "description": "The only ornithomimid ever discovered in Australia." + }, + { + "name": "Titanoceratops", + "description": "The biggest of all the horned, frilled dinosaurs." + }, + { + "name": "Titanosaurus", + "description": "This sauropod may—or may not—have been a unique member of its genus." + }, + { + "name": "Tochisaurus", + "description": "A large troodont of late Cretaceous Asia." + }, + { + "name": "Tornieria", + "description": "This sauropod has a complicated taxonomic history." + }, + { + "name": "Torosaurus", + "description": "Was it really an elderly specimen of Triceratops?" + }, + { + "name": "Torvosaurus", + "description": "One of the largest predators of Jurassic North America." + }, + { + "name": "Triceratops", + "description": "The famous, three-horned, plant-eating dinosaur." + }, + { + "name": "Trinisaura", + "description": "The first ornithopod ever to be discovered in Antarctica." + }, + { + "name": "Troodon", + "description": "Possibly the smartest dinosaur that ever lived." + }, + { + "name": "Tsaagan", + "description": "One of the earliest raptors yet discovered." + }, + { + "name": "Tsintaosaurus", + "description": "Also known as the \"Unicorn Dinosaur\"." + }, + { + "name": "Tuojiangosaurus", + "description": "One of the most well-known Chinese stegosaurs." + }, + { + "name": "Turanoceratops", + "description": "What was this ceratopsian doing in late Cretaceous Asia?" + }, + { + "name": "Turiasaurus", + "description": "The largest dinosaur ever to be discovered in Europe." + }, + { + "name": "Tylocephale", + "description": "The tallest-domed of all the pachycephalosaurs." + }, + { + "name": "Tyrannosaurus Rex", + "description": "The once—and always—king of the dinosaurs." + }, + { + "name": "Tyrannotitan", + "description": "We know very little about this fearsomely named dinosaur." + }, + { + "name": "Uberabatitan", + "description": "Discovered in the Uberaba region of Brazil." + }, + { + "name": "Udanoceratops", + "description": "The largest ceratopsian to run on two legs." + }, + { + "name": "Unaysaurus", + "description": "One of the oldest prosauropods yet discovered." + }, + { + "name": "Unenlagia", + "description": "This bird-like raptor was native to South America." + }, + { + "name": "Unescoceratops", + "description": "named after the United Nation's UNESCO." + }, + { + "name": "Urbacodon", + "description": "This Troodon-like predator was discovered in Uzbekistan." + }, + { + "name": "Utahceratops", + "description": "Guess what state this dinosaur was discovered in." + }, + { + "name": "Utahraptor", + "description": "Probably the biggest raptor that ever lived." + }, + { + "name": "Uteodon", + "description": "It was once classified as a species of Camptosaurus." + }, + { + "name": "Vagaceratops", + "description": "This big-frilled dinosaur was closely related to Kosmoceratops." + }, + { + "name": "Vahiny", + "description": "Its name is Malagasy for \"traveler\"." + }, + { + "name": "Valdoraptor", + "description": "This early \"bird mimic\" dinosaur lived in England." + }, + { + "name": "Valdosaurus", + "description": "This ornithopod was discovered on the Isle of Wight." + }, + { + "name": "Variraptor", + "description": "The first raptor ever to be discovered in France." + }, + { + "name": "Velafrons", + "description": "A new addition to the duck-billed dinosaur family." + }, + { + "name": "Velociraptor", + "description": "This dinosaur was vicious but a lot smaller than you thought." + }, + { + "name": "Velocisaurus", + "description": "A small, speedy theropod of late Cretaceous South America." + }, + { + "name": "Venenosaurus", + "description": "This \"poison lizard\" was really a gentle plant-eater." + }, + { + "name": "Veterupristisaurus", + "description": "One of the earliest carcharodontosaurs yet identified." + }, + { + "name": "Vulcanodon", + "description": "An early sauropod of the Jurassic period." + }, + { + "name": "Wannanosaurus", + "description": "Probably the smallest of all the bone-headed dinosaurs." + }, + { + "name": "Wellnhoferia", + "description": "Was it really a species of Archaeopteryx?" + }, + { + "name": "Wendiceratops", + "description": "This dinosaur honors Canadian fossil hunter Wendy Sloboda." + }, + { + "name": "Willinakaqe", + "description": "A rare duck-billed dinosaur from South America." + }, + { + "name": "Wintonotitan", + "description": "Another new titanosaur from Australia." + }, + { + "name": "Wuerhosaurus", + "description": "Could this have been the last of the stegosaurs?" + }, + { + "name": "Wulagasaurus", + "description": "The earliest saurolophine hadrosaur in the fossil record." + }, + { + "name": "Xenoceratops", + "description": "This \"alien horned face\" was announced in 2012." + }, + { + "name": "Xenoposeidon", + "description": "Experts aren't sure how to classify this sauropod." + }, + { + "name": "Xenotarsosaurus", + "description": "A poorly understood abelisaur from South America." + }, + { + "name": "Xiaosaurus", + "description": "A small ornithopod from late Jurassic Asia." + }, + { + "name": "Xiaotingia", + "description": "This feathered dinosaur predated Archaeopteryx." + }, + { + "name": "Xinjiangtitan", + "description": "This huge sauropod was a close relative of Mamenchisaurus." + }, + { + "name": "Xiongguanlong", + "description": "A small, primitive tyrannosaur from Asia." + }, + { + "name": "Xixianykus", + "description": "A long-legged dino-bird from eastern Asia." + }, + { + "name": "Xuanhanosaurus", + "description": "You didn't think there'd be so many \"X\"'s on this list, did you?" + }, + { + "name": "Xuanhuaceratops", + "description": "An early ceratopsian of the late Jurassic." + }, + { + "name": "Xuwulong", + "description": "This iguanodontid ornithopod was recently discovered in China." + }, + { + "name": "Yamaceratops", + "description": "No, it didn't have a sweet potato for a head." + }, + { + "name": "Yandusaurus", + "description": "A small ornithopod of middle Jurassic China." + }, + { + "name": "Yangchuanosaurus", + "description": "A large theropod of late Jurassic Asia." + }, + { + "name": "Yaverlandia", + "description": "A classic case of mistaken dinosaur identity." + }, + { + "name": "Yi Qi", + "description": "This strange Jurassic dinosaur had bat-like wings." + }, + { + "name": "Yimenosaurus", + "description": "One of the better-known Chinese prosauropods." + }, + { + "name": "Yinlong", + "description": "This \"hidden dragon\" was an early ceratopsian." + }, + { + "name": "Yixianosaurus", + "description": "How did this dino-bird use its long fingers?" + }, + { + "name": "Yizhousaurus", + "description": "The earliest intact sauropod yet discovered." + }, + { + "name": "Yongjinglong", + "description": "This titanosaur was recently discovered in China." + }, + { + "name": "Yueosaurus", + "description": "This basal ornithopod was discovered by construction workers." + }, + { + "name": "Yulong", + "description": "The smallest oviraptor yet identified." + }, + { + "name": "Yunnanosaurus", + "description": "One of the last prosauropods to walk the earth." + }, + { + "name": "Yutyrannus", + "description": "The largest feathered tyrannosaur yet identified." + }, + { + "name": "Zalmoxes", + "description": "A strange-looking ornithopod from Romania." + }, + { + "name": "Zanabazar", + "description": "named after a Buddhist spiritual leader." + }, + { + "name": "Zapalasaurus", + "description": "This \"diplodocoid\" sauropod lived in early Cretaceous South America." + }, + { + "name": "Zby", + "description": "This dinosaur's name was inversely proportional to its size." + }, + { + "name": "Zephyrosaurus", + "description": "Otherwise known as the Western Wind Lizard." + }, + { + "name": "Zhanghenglong", + "description": "A transitional hadrosaur of late Cretaceous Asia." + }, + { + "name": "Zhejiangosaurus", + "description": "The first identified nodosaur from Asia." + }, + { + "name": "Zhenyuanlong", + "description": "Also known as the \"fluffy feathered poodle from hell\"." + }, + { + "name": "Zhongyuansaurus", + "description": "The only known ankylosaur to lack a tail club." + }, + { + "name": "Zhuchengceratops", + "description": "It probably figured on the lunch menu of Zhuchengtyrannus." + }, + { + "name": "Zhuchengosaurus", + "description": "This hadrosaur was even bigger than Shantungosaurus." + }, + { + "name": "Zhuchengtyrannus", + "description": "This Asian tyrannosaur was the size of T. Rex." + }, + { + "name": "Zuniceratops", + "description": "This horned dinosaur was discovered by an eight-year-old boy." + }, + { + "name": "Zuolong", + "description": "It was named after General Tso, of Chinese restaurant fame." + }, + { + "name": "Zupaysaurus", + "description": "This \"devil lizard\" was one of the earliest theropods." + } +] diff --git a/server/main.ts b/server/main.ts new file mode 100644 index 0000000..38b3ed5 --- /dev/null +++ b/server/main.ts @@ -0,0 +1,38 @@ +import { Application } from "jsr:@oak/oak/application"; +import { Router } from "jsr:@oak/oak/router"; +import { oakCors } from "@tajpouria/cors"; +import routeStaticFilesFrom from "./util/routeStaticFilesFrom.ts"; +import data from "./api/data.json" with { type: "json" }; + +export const app = new Application(); +const router = new Router(); + +router.get("/api/dinosaurs", (context) => { + context.response.body = data; +}); + +router.get("/api/dinosaurs/:dinosaur", (context) => { + if (!context?.params?.dinosaur) { + context.response.body = "No dinosaur name provided."; + } + + const dinosaur = data.find((item) => + item.name.toLowerCase() === context.params.dinosaur.toLowerCase() + ); + + context.response.body = dinosaur ?? "No dinosaur found."; +}); + + +app.use(oakCors()); +app.use(router.routes()); +app.use(router.allowedMethods()); +app.use(routeStaticFilesFrom([ + `${Deno.cwd()}/client/dist`, + `${Deno.cwd()}/client/public`, +])); + +if (import.meta.main) { + console.log("Server listening on port http://localhost:8000"); + await app.listen({ port: 8000 }); +} diff --git a/server/main_test.ts b/server/main_test.ts new file mode 100644 index 0000000..c6e5e10 --- /dev/null +++ b/server/main_test.ts @@ -0,0 +1,68 @@ +import { assertEquals, assertExists } from "jsr:@std/assert"; +import { afterAll, beforeAll, describe, it } from "jsr:@std/testing/bdd"; +import { expect } from "jsr:@std/expect"; +import { Application } from "jsr:@oak/oak/application"; +import { Router } from "jsr:@oak/oak/router"; + +import { app } from "./main.ts"; +import routeStaticFilesFrom from "./util/routeStaticFilesFrom.ts"; + +describe("Application", () => { + let serverInfo: { baseUrl: string; abortController: AbortController }; + beforeAll(async () => { + console.log("Starting server"); + serverInfo = await serve(); + }); + + afterAll(() => { + console.log("Shutting down server"); + serverInfo.abortController.abort(); + }); + + it("can be created", () => { + assertExists(app); + assertEquals(app instanceof Application, true); + }); + + it("router accepts routes without throwing errors", () => { + const router = new Router(); + app.use(router.routes()); + assertExists(router); + }); + + it("can configure static routes", () => { + const staticFileMiddleware = routeStaticFilesFrom([ + `${Deno.cwd()}/client/dist`, + `${Deno.cwd()}/client/public`, + ]); + app.use(staticFileMiddleware); + assertExists(staticFileMiddleware); + }); + + it("can request home page from running server", async () => { + const response = await fetch(serverInfo.baseUrl); + const body = await response.text(); + + assertEquals(response.status, 200); + expect(body).toContain("Vite + React + TS"); + }); +}); + +async function serve(abortController = new AbortController()) { + let randomPort = 0; + + app.listen({ port: randomPort, signal: abortController.signal }); + + await new Promise((resolve) => { + app.addEventListener("listen", (ev) => { + randomPort = ev.port; + console.log(`Server running on http://localhost:${ev.port}`); + resolve(); + }); + }); + + return { + baseUrl: `http://localhost:${randomPort}`, + abortController: abortController, + }; +} diff --git a/server/util/routeStaticFilesFrom.ts b/server/util/routeStaticFilesFrom.ts new file mode 100644 index 0000000..8c2667c --- /dev/null +++ b/server/util/routeStaticFilesFrom.ts @@ -0,0 +1,19 @@ +import { Next } from "jsr:@oak/oak/middleware"; +import { Context } from "jsr:@oak/oak/context"; + +// Configure static site routes so that we can serve +// the Vite build output and the public folder +export default function routeStaticFilesFrom(staticPaths: string[]) { + return async (context: Context>, next: Next) => { + for (const path of staticPaths) { + try { + await context.send({ root: path, index: "index.html" }); + return; + } catch { + continue; + } + } + + await next(); + }; +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..e0f9190 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,26 @@ +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; +import deno from "@deno/vite-plugin"; + +import "react"; +import "react-dom"; + +export default defineConfig({ + root: "./client", + server: { + port: 3000, + proxy: { + "/api": { + target: "http://localhost:8000", + changeOrigin: true, + }, + }, + }, + plugins: [ + react(), + deno(), + ], + optimizeDeps: { + include: ["react/jsx-runtime"], + }, +});