├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── config.yml │ ├── enhancement_request.md │ └── feature_request.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── greetings.yml │ ├── publish.yml │ ├── release-tag.yml │ └── semantic-pull-request.yml ├── .gitignore ├── .husky ├── pre-commit └── pre-push ├── .prettierignore ├── .prettierrc ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── assets ├── Rasengan-with-text-black.svg ├── Rasengan-with-text.svg ├── Rasengan-without-text-black.svg ├── Rasengan-without-text.svg └── cards │ └── 1.png ├── docs ├── .gitignore ├── package.json ├── public │ ├── assets │ │ ├── blog │ │ │ ├── authors │ │ │ │ └── dilane-kombou.jpeg │ │ │ ├── rasengan-beta1.png │ │ │ └── rasengan-stable1.png │ │ └── images │ │ │ ├── 404.webp │ │ │ ├── metadata │ │ │ ├── blog.png │ │ │ ├── docs.png │ │ │ ├── home.png │ │ │ └── showcase.png │ │ │ └── showcase │ │ │ ├── biccas.png │ │ │ ├── enver.png │ │ │ ├── hano.png │ │ │ ├── kronix.png │ │ │ └── rasengan.png │ ├── icons │ │ └── github.svg │ ├── rasengan-large-normal.svg │ ├── rasengan-large-white.svg │ ├── rasengan.svg │ ├── robots.txt │ └── sitemap.xml ├── rasengan-env.d.ts ├── rasengan.config.js ├── src │ ├── api │ │ ├── index.ts │ │ └── newsletter │ │ │ └── index.ts │ ├── app │ │ ├── _404.tsx │ │ ├── app.layout.tsx │ │ ├── app.router.ts │ │ ├── blog │ │ │ ├── blog.layout.tsx │ │ │ ├── blog.router.ts │ │ │ └── pages │ │ │ │ ├── rasengan-1-beta.page.mdx │ │ │ │ └── rasengan-v1-stable.page.mdx │ │ ├── docs │ │ │ ├── components │ │ │ │ └── layout │ │ │ │ │ └── sidebar.tsx │ │ │ ├── docs.layout.tsx │ │ │ ├── docs.router.ts │ │ │ └── pages │ │ │ │ ├── home │ │ │ │ ├── api │ │ │ │ │ ├── api.group.ts │ │ │ │ │ ├── components │ │ │ │ │ │ ├── component.page.mdx │ │ │ │ │ │ ├── components.group.ts │ │ │ │ │ │ ├── layout-component.page.mdx │ │ │ │ │ │ ├── link.page.mdx │ │ │ │ │ │ ├── outlet.page.mdx │ │ │ │ │ │ ├── page-component.page.mdx │ │ │ │ │ │ ├── router-component.page.mdx │ │ │ │ │ │ └── template.page.mdx │ │ │ │ │ ├── conventions │ │ │ │ │ │ ├── conventions.group.ts │ │ │ │ │ │ ├── layout.page.mdx │ │ │ │ │ │ ├── page.page.mdx │ │ │ │ │ │ └── router.page.mdx │ │ │ │ │ ├── create-rasengan-cli.page.mdx │ │ │ │ │ ├── functions │ │ │ │ │ │ ├── define-config.page.mdx │ │ │ │ │ │ ├── define-router.page.mdx │ │ │ │ │ │ ├── define-routes-group.page.mdx │ │ │ │ │ │ ├── functions.group.ts │ │ │ │ │ │ └── render-app.page.mdx │ │ │ │ │ ├── rasengan-cli.page.mdx │ │ │ │ │ └── rasengan-config.page.mdx │ │ │ │ ├── core-concepts │ │ │ │ │ ├── configuring │ │ │ │ │ │ ├── aliases.page.mdx │ │ │ │ │ │ ├── config.group.ts │ │ │ │ │ │ ├── env.page.mdx │ │ │ │ │ │ └── typescript.page.mdx │ │ │ │ │ ├── core.group.ts │ │ │ │ │ ├── deploying │ │ │ │ │ │ ├── deploying.group.ts │ │ │ │ │ │ ├── node.page.mdx │ │ │ │ │ │ └── vercel.page.mdx │ │ │ │ │ ├── optimizing │ │ │ │ │ │ ├── image.page.mdx │ │ │ │ │ │ ├── metadata.page.mdx │ │ │ │ │ │ ├── optimizing.group.ts │ │ │ │ │ │ └── static-assets.page.mdx │ │ │ │ │ ├── rendering │ │ │ │ │ │ ├── csr.page.mdx │ │ │ │ │ │ ├── prerendering.page.mdx │ │ │ │ │ │ ├── rendering.group.ts │ │ │ │ │ │ └── ssr.page.mdx │ │ │ │ │ ├── routing │ │ │ │ │ │ ├── base-concepts.page.mdx │ │ │ │ │ │ ├── dynamic-routes.page.mdx │ │ │ │ │ │ ├── error-handling.page.mdx │ │ │ │ │ │ ├── layouts.page.mdx │ │ │ │ │ │ ├── linking.page.mdx │ │ │ │ │ │ ├── redirecting.page.mdx │ │ │ │ │ │ ├── router.page.mdx │ │ │ │ │ │ ├── routes.page.mdx │ │ │ │ │ │ └── routing.group.ts │ │ │ │ │ └── styling │ │ │ │ │ │ ├── css-modules.page.mdx │ │ │ │ │ │ ├── css-processors.page.mdx │ │ │ │ │ │ ├── styling.group.ts │ │ │ │ │ │ └── tailwind.page.mdx │ │ │ │ ├── getting-started │ │ │ │ │ ├── getting-started.group.ts │ │ │ │ │ ├── installation.page.mdx │ │ │ │ │ ├── introduction.page.mdx │ │ │ │ │ └── project-structure.page.mdx │ │ │ │ └── home.group.ts │ │ │ │ └── packages │ │ │ │ ├── introduction.page.mdx │ │ │ │ ├── module │ │ │ │ ├── create-rasengan.page.mdx │ │ │ │ ├── image.page.mdx │ │ │ │ ├── kurama.page.mdx │ │ │ │ ├── mdx.page.mdx │ │ │ │ ├── modules.group.ts │ │ │ │ ├── serve.page.mdx │ │ │ │ ├── theme.page.mdx │ │ │ │ └── vercel.page.mdx │ │ │ │ └── package.group.ts │ │ └── root │ │ │ ├── pages │ │ │ ├── blog.page.tsx │ │ │ ├── home.page.tsx │ │ │ ├── learn.page.tsx │ │ │ └── showcase.page.tsx │ │ │ ├── root.layout.tsx │ │ │ └── root.router.tsx │ ├── assets │ │ ├── font │ │ │ ├── GeistMono-Light.ttf │ │ │ ├── GeistMono-Regular.ttf │ │ │ ├── Lexend-Bold.ttf │ │ │ ├── Lexend-Light.ttf │ │ │ ├── Lexend-Medium.ttf │ │ │ └── Lexend-Regular.ttf │ │ ├── images │ │ │ ├── icons │ │ │ │ ├── folder.svg │ │ │ │ ├── grid.svg │ │ │ │ ├── lock.svg │ │ │ │ ├── rasengan-large.svg │ │ │ │ └── speed.svg │ │ │ ├── illustrations │ │ │ │ ├── blue-light.svg │ │ │ │ ├── cta-grid.svg │ │ │ │ ├── cta-light.png │ │ │ │ └── learn-loading.gif │ │ │ └── logo │ │ │ │ ├── logo-black.svg │ │ │ │ ├── logo-text-black.svg │ │ │ │ ├── logo-text-white.svg │ │ │ │ ├── logo-text.svg │ │ │ │ ├── logo-white.svg │ │ │ │ └── logo.svg │ │ └── logo.svg │ ├── components │ │ ├── atoms │ │ │ ├── alerts │ │ │ │ └── index.tsx │ │ │ ├── badges │ │ │ │ └── badge.tsx │ │ │ ├── buttons │ │ │ │ ├── button.tsx │ │ │ │ ├── copy-button.tsx │ │ │ │ └── theme-button.tsx │ │ │ └── logo │ │ │ │ └── index.tsx │ │ ├── layout │ │ │ ├── footer.tsx │ │ │ └── navbar.tsx │ │ └── molecules │ │ │ ├── blog-author-card.tsx │ │ │ ├── blog-card.tsx │ │ │ ├── blog-header-details.tsx │ │ │ ├── cta.tsx │ │ │ ├── editor.tsx │ │ │ ├── feature-card.tsx │ │ │ ├── heading.tsx │ │ │ ├── pagination.tsx │ │ │ ├── showcase-card.tsx │ │ │ ├── step-item.tsx │ │ │ └── tab.tsx │ ├── data │ │ ├── blog │ │ │ ├── authors.ts │ │ │ └── index.tsx │ │ └── docs │ │ │ └── index.tsx │ ├── index.ts │ ├── main.tsx │ ├── store │ │ ├── blog │ │ │ └── index.ts │ │ └── navigation │ │ │ └── index.ts │ ├── styles │ │ ├── index.css │ │ └── mdx.scss │ ├── template.tsx │ └── utils │ │ └── index.ts └── tsconfig.json ├── examples ├── shadcn-js │ └── README.md └── shadcn-ts │ └── README.md ├── package.json ├── packages ├── create-rasengan │ ├── .gitignore │ ├── .npmignore │ ├── CHANGELOG.md │ ├── CODE_OF_CONDUCT.md │ ├── CONTRIBUTING.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── release │ │ └── README.md │ ├── src │ │ ├── constants │ │ │ └── index.ts │ │ ├── data │ │ │ └── logo.ts │ │ ├── main.ts │ │ ├── scripts │ │ │ ├── log-info.ts │ │ │ └── template.ts │ │ └── utils │ │ │ ├── dirname.ts │ │ │ └── sleep.ts │ ├── templates │ │ ├── blank-js │ │ │ ├── gitignore │ │ │ ├── jsconfig.json │ │ │ ├── pkg.json │ │ │ ├── public │ │ │ │ ├── rasengan.svg │ │ │ │ └── robots.txt │ │ │ ├── rasengan.config.js │ │ │ └── src │ │ │ │ ├── app │ │ │ │ ├── app.layout.jsx │ │ │ │ ├── app.router.js │ │ │ │ └── home.page.jsx │ │ │ │ ├── assets │ │ │ │ └── logo.svg │ │ │ │ ├── index.jsx │ │ │ │ ├── main.jsx │ │ │ │ ├── styles │ │ │ │ └── index.css │ │ │ │ └── template.jsx │ │ ├── blank-ts │ │ │ ├── gitignore │ │ │ ├── pkg.json │ │ │ ├── public │ │ │ │ ├── rasengan.svg │ │ │ │ └── robots.txt │ │ │ ├── rasengan-env.d.ts │ │ │ ├── rasengan.config.js │ │ │ ├── src │ │ │ │ ├── app │ │ │ │ │ ├── app.layout.tsx │ │ │ │ │ ├── app.router.ts │ │ │ │ │ └── home.page.tsx │ │ │ │ ├── assets │ │ │ │ │ └── logo.svg │ │ │ │ ├── index.ts │ │ │ │ ├── main.tsx │ │ │ │ ├── styles │ │ │ │ │ └── index.css │ │ │ │ └── template.tsx │ │ │ └── tsconfig.json │ │ ├── tailwind-v3-js │ │ │ ├── gitignore │ │ │ ├── jsconfig.json │ │ │ ├── pkg.json │ │ │ ├── postcss.config.js │ │ │ ├── public │ │ │ │ ├── rasengan.svg │ │ │ │ └── robots.txt │ │ │ ├── rasengan.config.js │ │ │ ├── src │ │ │ │ ├── app │ │ │ │ │ ├── app.layout.jsx │ │ │ │ │ ├── app.router.js │ │ │ │ │ └── home.page.jsx │ │ │ │ ├── assets │ │ │ │ │ └── logo.svg │ │ │ │ ├── index.jsx │ │ │ │ ├── main.jsx │ │ │ │ ├── styles │ │ │ │ │ └── index.css │ │ │ │ └── template.jsx │ │ │ └── tailwind.config.js │ │ ├── tailwind-v3-ts │ │ │ ├── gitignore │ │ │ ├── pkg.json │ │ │ ├── postcss.config.js │ │ │ ├── public │ │ │ │ ├── rasengan.svg │ │ │ │ └── robots.txt │ │ │ ├── rasengan-env.d.ts │ │ │ ├── rasengan.config.js │ │ │ ├── src │ │ │ │ ├── app │ │ │ │ │ ├── app.layout.tsx │ │ │ │ │ ├── app.router.ts │ │ │ │ │ └── home.page.tsx │ │ │ │ ├── assets │ │ │ │ │ └── logo.svg │ │ │ │ ├── index.ts │ │ │ │ ├── main.tsx │ │ │ │ ├── styles │ │ │ │ │ └── index.css │ │ │ │ └── template.tsx │ │ │ ├── tailwind.config.js │ │ │ └── tsconfig.json │ │ ├── tailwind-v4-js │ │ │ ├── gitignore │ │ │ ├── jsconfig.json │ │ │ ├── pkg.json │ │ │ ├── public │ │ │ │ ├── rasengan.svg │ │ │ │ └── robots.txt │ │ │ ├── rasengan.config.js │ │ │ └── src │ │ │ │ ├── app │ │ │ │ ├── app.layout.jsx │ │ │ │ ├── app.router.js │ │ │ │ └── home.page.jsx │ │ │ │ ├── assets │ │ │ │ └── logo.svg │ │ │ │ ├── index.js │ │ │ │ ├── main.jsx │ │ │ │ ├── styles │ │ │ │ └── index.css │ │ │ │ └── template.jsx │ │ └── tailwind-v4-ts │ │ │ ├── gitignore │ │ │ ├── pkg.json │ │ │ ├── public │ │ │ ├── rasengan.svg │ │ │ └── robots.txt │ │ │ ├── rasengan-env.d.ts │ │ │ ├── rasengan.config.js │ │ │ ├── src │ │ │ ├── app │ │ │ │ ├── app.layout.tsx │ │ │ │ ├── app.router.ts │ │ │ │ └── home.page.tsx │ │ │ ├── assets │ │ │ │ └── logo.svg │ │ │ ├── index.ts │ │ │ ├── main.tsx │ │ │ ├── styles │ │ │ │ └── index.css │ │ │ └── template.tsx │ │ │ └── tsconfig.json │ └── tsconfig.json ├── rasengan-image │ ├── .gitignore │ ├── .npmignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── release │ │ └── README.md │ ├── src │ │ ├── components │ │ │ ├── image.tsx │ │ │ └── index.tsx │ │ ├── index.ts │ │ ├── styles │ │ │ └── index.css │ │ ├── types │ │ │ ├── index.ts │ │ │ └── styles.d.ts │ │ └── utils │ │ │ └── index.ts │ └── tsconfig.json ├── rasengan-mdx │ ├── .gitignore │ ├── .npmignore │ ├── CHANGELOG.md │ ├── CODE_OF_CONDUCT.md │ ├── CONTRIBUTING.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── release │ │ └── README.md │ ├── src │ │ ├── components │ │ │ ├── codeblock.tsx │ │ │ ├── codeblock2.tsx │ │ │ ├── heading.tsx │ │ │ ├── index.ts │ │ │ ├── markdown.tsx │ │ │ ├── renderer.tsx │ │ │ ├── table.tsx │ │ │ └── toc.tsx │ │ ├── index.ts │ │ ├── scripts │ │ │ └── compile-css.js │ │ ├── styles │ │ │ └── rasengan-mdx.css │ │ ├── types │ │ │ └── index.ts │ │ └── utils │ │ │ ├── create-filter.ts │ │ │ ├── define-mdx-config.ts │ │ │ ├── extract-toc.ts │ │ │ ├── generate-navigation.ts │ │ │ ├── index.ts │ │ │ ├── mark-to-html.ts │ │ │ ├── plugin.ts │ │ │ └── polyfill.ts │ └── tsconfig.json ├── rasengan-serve │ ├── .gitignore │ ├── .npmignore │ ├── CHANGELOG.md │ ├── bin.js │ ├── cli.ts │ ├── package.json │ └── tsconfig.json ├── rasengan-shuriken │ ├── .gitignore │ ├── .npmignore │ ├── CHANGELOG.md │ ├── CODE_OF_CONDUCT.md │ ├── CONTRIBUTING.md │ ├── LICENSE │ ├── README.md │ ├── bin.js │ ├── cli.ts │ ├── package.json │ ├── release │ │ └── README.md │ ├── scripts │ │ └── template.ts │ ├── tsconfig.json │ └── utils │ │ ├── log-info.ts │ │ └── sleep.ts ├── rasengan-theme │ ├── .gitignore │ ├── .npmignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── package.json │ ├── release │ │ └── README.md │ ├── src │ │ ├── components │ │ │ ├── Provider.tsx │ │ │ └── index.tsx │ │ ├── contexts │ │ │ └── themes.ts │ │ ├── hooks │ │ │ ├── useColorScheme.ts │ │ │ └── useTheme.ts │ │ ├── index.ts │ │ ├── types │ │ │ └── index.ts │ │ └── utils │ │ │ └── index.ts │ └── tsconfig.json ├── rasengan-vercel │ ├── .gitignore │ ├── .npmignore │ ├── CHANGELOG.md │ ├── index.ts │ ├── package.json │ └── tsconfig.json └── rasengan │ ├── .gitignore │ ├── .npmignore │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── bin.js │ ├── package.json │ ├── release │ └── README.md │ ├── src │ ├── cli │ │ └── index.ts │ ├── client.ts │ ├── core │ │ ├── config │ │ │ ├── index.ts │ │ │ ├── type.ts │ │ │ ├── utils │ │ │ │ ├── define-config.ts │ │ │ │ ├── load-modules.ts │ │ │ │ └── path.ts │ │ │ └── vite │ │ │ │ └── defaults.ts │ │ ├── dynamic │ │ │ └── index.tsx │ │ ├── index.ts │ │ ├── middlewares │ │ │ ├── index.ts │ │ │ └── logger.ts │ │ ├── plugins │ │ │ └── index.ts │ │ ├── types.ts │ │ └── utils │ │ │ └── log.ts │ ├── entries │ │ ├── client │ │ │ └── render.tsx │ │ └── server │ │ │ ├── entry.server.tsx │ │ │ └── index.tsx │ ├── index.ts │ ├── plugin.ts │ ├── routing │ │ ├── components │ │ │ ├── index.tsx │ │ │ └── template.tsx │ │ ├── index.ts │ │ ├── interfaces.tsx │ │ ├── providers │ │ │ └── metadata.tsx │ │ ├── types.ts │ │ └── utils │ │ │ ├── define-router.tsx │ │ │ ├── define-routes-group.tsx │ │ │ ├── generate-metadata.tsx │ │ │ ├── generate-routes.tsx │ │ │ └── index.tsx │ ├── scripts │ │ ├── build-command.js │ │ ├── generate-package-json.js │ │ └── utils │ │ │ ├── check-os.js │ │ │ └── copy.js │ ├── server.ts │ └── server │ │ ├── build │ │ ├── index.ts │ │ ├── manifest.tsx │ │ └── rendering.tsx │ │ ├── dev │ │ ├── handlers.tsx │ │ ├── server.ts │ │ └── utils.ts │ │ ├── node │ │ ├── index.tsx │ │ ├── rendering.ts │ │ ├── stream.ts │ │ └── utils.ts │ │ ├── runtime │ │ ├── mode.ts │ │ └── utils.ts │ │ └── virtual │ │ └── index.ts │ ├── tsconfig.base.json │ ├── tsconfig.cjs.json │ ├── tsconfig.esm.json │ ├── tsconfig.json │ ├── tsconfig.types.json │ ├── types │ └── client.d.ts │ └── vite.config.ts ├── playground ├── file-based-routing │ ├── .rasengan │ │ └── deps │ │ │ ├── _metadata.json │ │ │ ├── chunk-3TODNECC.js │ │ │ ├── chunk-3TODNECC.js.map │ │ │ ├── chunk-5NZ5KQVF.js │ │ │ ├── chunk-5NZ5KQVF.js.map │ │ │ ├── chunk-5XWD2ACU.js │ │ │ ├── chunk-5XWD2ACU.js.map │ │ │ ├── chunk-6GFY52XF.js │ │ │ ├── chunk-6GFY52XF.js.map │ │ │ ├── chunk-DC5AMYBS.js │ │ │ ├── chunk-DC5AMYBS.js.map │ │ │ ├── chunk-I46PM5IZ.js │ │ │ ├── chunk-I46PM5IZ.js.map │ │ │ ├── chunk-IUKRAPEX.js │ │ │ ├── chunk-IUKRAPEX.js.map │ │ │ ├── chunk-QJIADCDW.js │ │ │ ├── chunk-QJIADCDW.js.map │ │ │ ├── chunk-U2GIRGWN.js │ │ │ ├── chunk-U2GIRGWN.js.map │ │ │ ├── chunk-W3RG5IXQ.js │ │ │ ├── chunk-W3RG5IXQ.js.map │ │ │ ├── chunk-ZRKR3IOO.js │ │ │ ├── chunk-ZRKR3IOO.js.map │ │ │ ├── package.json │ │ │ ├── prism-react-renderer.js │ │ │ ├── prism-react-renderer.js.map │ │ │ ├── react-dom.js │ │ │ ├── react-dom.js.map │ │ │ ├── react-dom_client.js │ │ │ ├── react-dom_client.js.map │ │ │ ├── react-dom_server.js │ │ │ ├── react-dom_server.js.map │ │ │ ├── react-markdown.js │ │ │ ├── react-markdown.js.map │ │ │ ├── react-router.js │ │ │ ├── react-router.js.map │ │ │ ├── react.js │ │ │ ├── react.js.map │ │ │ ├── react_jsx-dev-runtime.js │ │ │ ├── react_jsx-dev-runtime.js.map │ │ │ ├── react_jsx-runtime.js │ │ │ ├── react_jsx-runtime.js.map │ │ │ ├── rehype-stringify.js │ │ │ ├── rehype-stringify.js.map │ │ │ ├── remark-gfm.js │ │ │ ├── remark-gfm.js.map │ │ │ ├── remark-parse.js │ │ │ ├── remark-parse.js.map │ │ │ ├── remark-rehype.js │ │ │ └── remark-rehype.js.map │ └── dist │ │ ├── .vite │ │ └── manifest.json │ │ ├── assets │ │ ├── config.json │ │ ├── index-CYtBea_7.css │ │ ├── index-Cz8AdUSF.js │ │ ├── index-DmXVamtx.js │ │ └── vendor-DAQpAcEA.js │ │ ├── client │ │ ├── .vite │ │ │ └── manifest.json │ │ ├── assets │ │ │ ├── config.json │ │ │ ├── index-CYtBea_7.css │ │ │ ├── index-CuiqHVc4.js │ │ │ ├── index-DmXVamtx.js │ │ │ ├── page-index-XOAD-EmU.js │ │ │ ├── page-signin--4d4tlDW.js │ │ │ └── vendor-DAQpAcEA.js │ │ ├── rasengan.svg │ │ └── robots.txt │ │ ├── index.html │ │ ├── rasengan.svg │ │ ├── robots.txt │ │ └── server │ │ ├── app.router.js │ │ ├── assets │ │ ├── index-CaGjM28j.js │ │ ├── page-index-FclJ1kNm.js │ │ ├── page-signin-BBokP9vt.js │ │ ├── template-CEO8RV0b.js │ │ └── vendor-CsqfrH1N.js │ │ ├── entry.server.js │ │ ├── main.js │ │ ├── rasengan.svg │ │ ├── robots.txt │ │ └── template.js └── rasengan-v1-test │ ├── .gitignore │ ├── package.json │ ├── public │ ├── rasengan.svg │ └── robots.txt │ ├── rasengan-env.d.ts │ ├── rasengan.config.js │ ├── src │ ├── app │ │ ├── app.layout.tsx │ │ ├── app.router.ts │ │ ├── blog.page.mdx │ │ └── sub-router │ │ │ ├── about.page.tsx │ │ │ ├── group │ │ │ ├── contact.page.tsx │ │ │ ├── index.group.ts │ │ │ └── pricing.page.tsx │ │ │ ├── home.page.tsx │ │ │ └── sub-router.router.ts │ ├── assets │ │ └── logo.svg │ ├── index.ts │ ├── main.tsx │ ├── styles │ │ └── index.css │ └── template.tsx │ └── tsconfig.json ├── pnpm-lock.yaml ├── pnpm-workspace.yaml └── scripts ├── build.ts ├── pack.ts ├── publishCI.ts ├── release.ts └── tsconfig.json /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 12 | polar: # Replace with a single Polar username 13 | buy_me_a_coffee: dilane3 14 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 15 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: Report a bug to help us improve RasenganJS 4 | title: '[BUG] - ' 5 | labels: bug 6 | assignees: '' 7 | --- 8 | 9 | **Describe the bug** 10 | A clear and concise description of what the bug is. 11 | 12 | **Steps to Reproduce** 13 | Steps to reproduce the behavior: 14 | 15 | 1. Go to '...' 16 | 2. Click on '...' 17 | 3. Scroll down to '...' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Environment (please complete the following information):** 27 | 28 | - **OS:** [e.g., Windows, macOS, Linux] 29 | - **Node.js Version:** [e.g., 14.x, 16.x] 30 | - **Package manager Version:** [e.g., 6.x] 31 | - **Browser (if applicable):** [e.g., Chrome, Safari] 32 | - **Affected Package(s):** [Specify if the bug is in a specific package inside the `packages/` folder] 33 | - **Additional context:** [Include any relevant details about the environment, such as any changes in the `playground/` examples or special configuration settings] 34 | 35 | **Additional context** 36 | Add any other context about the problem here. 37 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: GitHub Community Support 4 | url: https://github.com/orgs/rasengan-dev/discussions 5 | about: Please ask and answer questions here. 6 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/enhancement_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Enhancement Request 3 | about: Propose an improvement to an existing feature in Rasengan.js 4 | title: '[ENHANCEMENT] - ' 5 | labels: enhancement 6 | assignees: '' 7 | --- 8 | 9 | **Enhancement description** 10 | Briefly describe the improvement you'd like to make to an existing feature. 11 | 12 | **Current behavior** 13 | Describe how the feature currently works and what its limitations are. 14 | 15 | **Proposed change** 16 | Summarize the change or improvement you'd like to see. 17 | 18 | **Additional context** 19 | Include any relevant use cases, comparisons, or suggestions. 20 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature Request 3 | about: Suggest a new feature for Rasengan.js 4 | title: '[FEATURE] - ' 5 | labels: enhancement 6 | assignees: '' 7 | --- 8 | 9 | **Feature description** 10 | Briefly describe the new feature you would like to see added. 11 | 12 | **Use case** 13 | Explain the context or problem this feature solves. 14 | 15 | **Describe alternatives you've considered** 16 | Mention any alternative solutions or workarounds you've explored. 17 | 18 | **Additional context** 19 | Add any other relevant information, links, or examples. 20 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 🔗 Related Issue 4 | 5 | 6 | 7 | ## 🚀 Type of Change 8 | 9 | 10 | 11 | - [ ] 📖 Documentation (Updates to README, API docs, or comments) 12 | - [ ] 🐞 Bug Fix (Non-breaking fix for an issue) 13 | - [ ] ⚡ Performance (Optimizations for faster execution) 14 | - [ ] ✨ Feature (New functionality without breaking changes) 15 | - [ ] 🔧 Refactor (Code improvements without changing behavior) 16 | - [ ] 🧹 Chore (Build process, tooling, dependencies) 17 | - [ ] ⚠️ Breaking Change (Modifications that impact existing usage) 18 | 19 | ## 📜 Description 20 | 21 | 22 | 23 | 24 | 25 | ## 📸 Screenshots / Demos (if applicable) 26 | 27 | 28 | 29 | ## ✅ Checklist 30 | 31 | 32 | 33 | - [ ] I have linked a related issue or discussion. 34 | - [ ] I have updated documentation if needed. 35 | - [ ] I have tested the changes in a real project. 36 | - [ ] I have added tests or confirmed that existing tests pass. 37 | 38 | ## 💡 Additional Notes 39 | 40 | 41 | -------------------------------------------------------------------------------- /.github/workflows/greetings.yml: -------------------------------------------------------------------------------- 1 | name: Greetings 2 | 3 | on: [pull_request_target, issues] 4 | 5 | jobs: 6 | greeting: 7 | runs-on: ubuntu-latest 8 | permissions: 9 | issues: write 10 | pull-requests: write 11 | steps: 12 | - uses: actions/first-interaction@v1 13 | with: 14 | repo-token: ${{ secrets.TOKEN_GITHUB }} 15 | issue-message: "Thanks for your interest by sharing what's going wrong with Rasengan.js, your contribution will help more than one." 16 | pr-message: 'Oh nice, this is your first pull request on Rasengan.js repository. Thanks for contributing to the project.' 17 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish Package 2 | 3 | on: 4 | push: 5 | tags: 6 | - "v*" # Push events to matching v*, i.e. v1.0, v20.15.10 7 | - "create-rasengan*" # Push events to matching plugin-*, i.e. create-rasengan@1.0.0 8 | - "rasengan-*" # # Push events to matching @rasenganjs/*, i.e. @rasenganjs/serve@1.0.0 9 | 10 | jobs: 11 | publish: 12 | # prevents this action from running on forks 13 | if: github.repository == 'rasengan-dev/rasenganjs' 14 | runs-on: ubuntu-latest 15 | permissions: 16 | contents: read 17 | id-token: write 18 | environment: Release 19 | steps: 20 | - name: Checkout 21 | uses: actions/checkout@v4 22 | 23 | - name: Install pnpm 24 | uses: pnpm/action-setup@v4.1.0 25 | 26 | - name: Set node version to 20 27 | uses: actions/setup-node@v4 28 | with: 29 | node-version: 20 30 | registry-url: https://registry.npmjs.org/ 31 | cache: "pnpm" 32 | 33 | - name: Install deps 34 | run: pnpm install 35 | 36 | - name: Build package 37 | run: pnpm run build 38 | 39 | - name: Get token 40 | id: tag 41 | run: | 42 | if [[ $GITHUB_REF_NAME =~ ^rasengan-.+ ]]; then 43 | token="${{ secrets.SECONDARY_NPM_TOKEN }}" 44 | else 45 | token="${{ secrets.MAIN_NPM_TOKEN }}" 46 | fi 47 | 48 | echo "npmToken=$token" >> $GITHUB_OUTPUT 49 | 50 | - name: Publish package 51 | run: pnpm run ci-publish ${{ github.ref_name }} 52 | env: 53 | NODE_AUTH_TOKEN: ${{ steps.tag.outputs.npmToken }} -------------------------------------------------------------------------------- /.github/workflows/semantic-pull-request.yml: -------------------------------------------------------------------------------- 1 | name: Semantic Pull Request 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | - edited 8 | - synchronize 9 | 10 | jobs: 11 | main: 12 | if: github.repository == 'rasengan-dev/rasenganjs' 13 | runs-on: ubuntu-latest 14 | name: Semantic Pull Request 15 | steps: 16 | - name: Validate PR title 17 | uses: amannn/action-semantic-pull-request@v5 18 | with: 19 | subjectPattern: ^(?![A-Z]).+$ 20 | subjectPatternError: | 21 | The subject "{subject}" found in the pull request title "{title}" 22 | didn't match the configured pattern. Please ensure that the subject 23 | doesn't start with an uppercase character. 24 | env: 25 | GITHUB_TOKEN: ${{ secrets.TOKEN_GITHUB }} -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | lib 3 | yarn.lock 4 | package-lock.json 5 | *.tgz 6 | .DS_Store -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | pnpm lint-staged -------------------------------------------------------------------------------- /.husky/pre-push: -------------------------------------------------------------------------------- 1 | current_branch=$(git symbolic-ref --short HEAD) 2 | 3 | if [ "$current_branch" = "main" ]; then 4 | echo "Error: You are not allowed to push to main branch" 5 | exit 1 6 | fi -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build 3 | dist 4 | docs/**/*.mdx -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "singleQuote": true, 4 | "tabWidth": 2, 5 | "trailingComma": "es5" 6 | } 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023-Present Dilane Kombou 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /assets/cards/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/assets/cards/1.png -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | *.local 14 | 15 | # Cache 16 | .vite 17 | .rasengan 18 | 19 | # Editor directories and files 20 | .vscode/* 21 | !.vscode/extensions.json 22 | .idea 23 | .DS_Store 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw? 29 | 30 | # Local Netlify folder 31 | .netlify 32 | 33 | # Local Vercel folder 34 | .vercel 35 | 36 | # Env variables 37 | .env 38 | .env-* -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rasengan-docs", 3 | "private": false, 4 | "version": "1.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "rasengan dev", 8 | "build": "rasengan build", 9 | "serve": "rasengan-serve ./dist" 10 | }, 11 | "dependencies": { 12 | "@rasenganjs/image": "^1.0.0", 13 | "@rasenganjs/mdx": "^1.1.1", 14 | "@rasenganjs/serve": "^1.0.0", 15 | "@rasenganjs/theme": "^1.0.1", 16 | "@rasenganjs/vercel": "^1.0.0", 17 | "@tailwindcss/vite": "^4.*", 18 | "@vercel/analytics": "^1.5.0", 19 | "axios": "^1.8.3", 20 | "lucide-react": "^0.477.0", 21 | "motion": "^12.4.10", 22 | "rasengan": "^1.0.0", 23 | "react": "^19.0.0", 24 | "react-dom": "^19.0.0", 25 | "tailwind-merge": "^3.0.2", 26 | "tailwindcss": "^4.*", 27 | "zustand": "^5.0.3" 28 | }, 29 | "devDependencies": { 30 | "@types/react": "^19.0.0", 31 | "@types/react-dom": "^19.0.0", 32 | "cross-env": "^7.0.3", 33 | "sass": "^1.85.1", 34 | "typescript": "^5.1.3", 35 | "vite": "^6.2.6" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /docs/public/assets/blog/authors/dilane-kombou.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/public/assets/blog/authors/dilane-kombou.jpeg -------------------------------------------------------------------------------- /docs/public/assets/blog/rasengan-beta1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/public/assets/blog/rasengan-beta1.png -------------------------------------------------------------------------------- /docs/public/assets/blog/rasengan-stable1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/public/assets/blog/rasengan-stable1.png -------------------------------------------------------------------------------- /docs/public/assets/images/404.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/public/assets/images/404.webp -------------------------------------------------------------------------------- /docs/public/assets/images/metadata/blog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/public/assets/images/metadata/blog.png -------------------------------------------------------------------------------- /docs/public/assets/images/metadata/docs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/public/assets/images/metadata/docs.png -------------------------------------------------------------------------------- /docs/public/assets/images/metadata/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/public/assets/images/metadata/home.png -------------------------------------------------------------------------------- /docs/public/assets/images/metadata/showcase.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/public/assets/images/metadata/showcase.png -------------------------------------------------------------------------------- /docs/public/assets/images/showcase/biccas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/public/assets/images/showcase/biccas.png -------------------------------------------------------------------------------- /docs/public/assets/images/showcase/enver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/public/assets/images/showcase/enver.png -------------------------------------------------------------------------------- /docs/public/assets/images/showcase/hano.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/public/assets/images/showcase/hano.png -------------------------------------------------------------------------------- /docs/public/assets/images/showcase/kronix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/public/assets/images/showcase/kronix.png -------------------------------------------------------------------------------- /docs/public/assets/images/showcase/rasengan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/public/assets/images/showcase/rasengan.png -------------------------------------------------------------------------------- /docs/public/icons/github.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /docs/public/robots.txt: -------------------------------------------------------------------------------- 1 | user-agent: * 2 | disallow: /downloads/ 3 | disallow: /private/ 4 | allow: / 5 | 6 | user-agent: magicsearchbot 7 | disallow: /uploads/ -------------------------------------------------------------------------------- /docs/rasengan-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /docs/rasengan.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'rasengan'; 2 | import { rasengan } from 'rasengan/plugin'; 3 | import tailwindcss from '@tailwindcss/vite'; 4 | import mdx from '@rasenganjs/mdx/plugin'; 5 | import { configure } from '@rasenganjs/vercel'; 6 | 7 | export default defineConfig(async () => { 8 | return { 9 | vite: { 10 | plugins: [mdx(), tailwindcss(), rasengan({ adapter: configure() })], 11 | }, 12 | 13 | async redirects() { 14 | return [ 15 | { 16 | source: '/docs', 17 | destination: '/docs/getting-started/installation', 18 | permanent: true, 19 | }, 20 | ]; 21 | }, 22 | }; 23 | }); 24 | 25 | /** 26 | * prerender: boolean | string[] | { 27 | * routes: string[] 28 | * } 29 | */ 30 | 31 | // git clone https://token@github.com/rasenganjs/docs.git 32 | -------------------------------------------------------------------------------- /docs/src/api/index.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | 3 | export const instance = axios.create({ 4 | baseURL: 'https://api.smadmail.com/api/v1', 5 | timeout: 10000, 6 | }); 7 | -------------------------------------------------------------------------------- /docs/src/api/newsletter/index.ts: -------------------------------------------------------------------------------- 1 | import { instance } from '..'; 2 | 3 | const env = import.meta.env; 4 | 5 | export const newsletterProvider = { 6 | subscribe: async (email: string) => { 7 | try { 8 | const payload = { 9 | email, 10 | project_id: env.RASENGAN_SMAD_PROJECT_ID, 11 | private_key: env.RASENGAN_SMAD_PRIVATE_KEY, 12 | }; 13 | const response = await instance.post('/email/save', payload); 14 | 15 | if (response.status === 201) { 16 | return { 17 | data: 'Your subscrition has been done', 18 | }; 19 | } 20 | 21 | return { 22 | error: 'Error while subscribing to the newsletter', 23 | }; 24 | } catch (error) { 25 | return { 26 | error: 'Error while subscribing to the newsletter', 27 | }; 28 | } 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /docs/src/app/_404.tsx: -------------------------------------------------------------------------------- 1 | import Button from '@/components/atoms/buttons/button'; 2 | import { Link } from 'rasengan'; 3 | 4 | export default function NotFound() { 5 | return ( 6 |
7 |

Oops

8 |

404 - Page Not Found

9 | 10 | 13 | 14 |
15 | ); 16 | } 17 | -------------------------------------------------------------------------------- /docs/src/app/app.router.ts: -------------------------------------------------------------------------------- 1 | import { RouterComponent, defineRouter } from 'rasengan'; 2 | import RootRouter from '@/app/root/root.router'; 3 | import AppLayout from '@/app/app.layout'; 4 | import DocsRouter from '@/app/docs/docs.router'; 5 | import NotFound from './_404'; 6 | import BlogRouter from '@/app/blog/blog.router'; 7 | 8 | class AppRouter extends RouterComponent {} 9 | 10 | export default defineRouter({ 11 | imports: [RootRouter, DocsRouter, BlogRouter], 12 | layout: AppLayout, 13 | pages: [], 14 | notFoundComponent: NotFound, 15 | })(AppRouter); 16 | -------------------------------------------------------------------------------- /docs/src/app/blog/blog.layout.tsx: -------------------------------------------------------------------------------- 1 | import Footer from '@/components/layout/footer'; 2 | import Navbar from '@/components/layout/navbar'; 3 | import { LayoutComponent, Outlet } from 'rasengan'; 4 | 5 | const BlogLayout: LayoutComponent = () => { 6 | return ( 7 |
8 | 9 | 10 |
11 | 12 |
13 | 14 |
15 |
16 | ); 17 | }; 18 | 19 | BlogLayout.path = '/blog'; 20 | BlogLayout.metadata = { 21 | openGraph: { 22 | title: 'Rasengan.js - Blog', 23 | description: 'Insights, tips, and updates from the Rasengan.js community.', 24 | url: 'https://rasengan.dev', 25 | image: 'https://rasengan.dev/assets/images/metadata/blog.png', 26 | }, 27 | twitter: { 28 | card: 'summary_large_image', 29 | title: 'Rasengan.js - Blog', 30 | description: 'Insights, tips, and updates from the Rasengan.js community.', 31 | image: 'https://rasengan.dev/assets/images/metadata/blog.png', 32 | }, 33 | }; 34 | 35 | export default BlogLayout; 36 | -------------------------------------------------------------------------------- /docs/src/app/blog/blog.router.ts: -------------------------------------------------------------------------------- 1 | import { defineRouter, RouterComponent } from 'rasengan'; 2 | import RasenganBeta1 from '@/app/blog/pages/rasengan-1-beta.page.mdx'; 3 | import RasenganV1Stable from '@/app/blog/pages/rasengan-v1-stable.page.mdx'; 4 | import BlogLayout from '@/app/blog/blog.layout'; 5 | 6 | class BlogRouter extends RouterComponent {} 7 | 8 | export default defineRouter({ 9 | layout: BlogLayout, 10 | pages: [RasenganBeta1, RasenganV1Stable], 11 | })(BlogRouter); 12 | -------------------------------------------------------------------------------- /docs/src/app/docs/docs.router.ts: -------------------------------------------------------------------------------- 1 | import { RouterComponent, defineRouter } from 'rasengan'; 2 | import DocsLayout from '@/app/docs/docs.layout'; 3 | import DocsGroup from './pages/home/home.group'; 4 | import PackageGroup from './pages/packages/package.group'; 5 | 6 | class DocsRouter extends RouterComponent {} 7 | 8 | export default defineRouter({ 9 | imports: [], 10 | layout: DocsLayout, 11 | pages: [DocsGroup, PackageGroup], 12 | // useParentLayout: false, 13 | })(DocsRouter); 14 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/home/api/api.group.ts: -------------------------------------------------------------------------------- 1 | import { defineRoutesGroup } from 'rasengan'; 2 | import componentsGroup from './components/components.group'; 3 | import functionsGroup from './functions/functions.group'; 4 | import conventionsGroup from './conventions/conventions.group'; 5 | import RasenganConfigPage from './rasengan-config.page.mdx'; 6 | import CreateRasenganCliPage from './create-rasengan-cli.page.mdx'; 7 | import RasenganCliPage from './rasengan-cli.page.mdx'; 8 | 9 | export default defineRoutesGroup({ 10 | path: '/api-reference', 11 | children: [ 12 | componentsGroup, 13 | functionsGroup, 14 | conventionsGroup, 15 | RasenganConfigPage, 16 | CreateRasenganCliPage, 17 | RasenganCliPage, 18 | ], 19 | }); 20 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/home/api/components/components.group.ts: -------------------------------------------------------------------------------- 1 | import { defineRoutesGroup } from 'rasengan'; 2 | import LinkPage from './link.page.mdx'; 3 | import OutletPage from './outlet.page.mdx'; 4 | import ComponentPage from './component.page.mdx'; 5 | import LayoutComponentPage from './layout-component.page.mdx'; 6 | import PageComponentPage from './page-component.page.mdx'; 7 | import RouterComponentPage from './router-component.page.mdx'; 8 | import TemplatePage from './template.page.mdx'; 9 | 10 | export default defineRoutesGroup({ 11 | path: '/components', 12 | children: [ 13 | LinkPage, 14 | OutletPage, 15 | ComponentPage, 16 | LayoutComponentPage, 17 | PageComponentPage, 18 | RouterComponentPage, 19 | TemplatePage, 20 | ], 21 | }); 22 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/home/api/conventions/conventions.group.ts: -------------------------------------------------------------------------------- 1 | import { defineRoutesGroup } from 'rasengan'; 2 | import LayoutPage from './layout.page.mdx'; 3 | import PageConventionPage from './page.page.mdx'; 4 | import RouterConventionPage from './router.page.mdx'; 5 | 6 | export default defineRoutesGroup({ 7 | path: '/conventions', 8 | children: [LayoutPage, PageConventionPage, RouterConventionPage], 9 | }); 10 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/home/api/create-rasengan-cli.page.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | path: create-rasengan-cli 3 | metadata: 4 | title: Create Rasengan CLI | API Reference | Rasengan.js 5 | description: Create a new project with the Rasengan.js CLI. 6 | toc: true 7 | --- 8 | 9 | import Pagination from '@/components/molecules/pagination'; 10 | import { Link } from "rasengan"; 11 | import StepItem from '@/components/molecules/step-item'; 12 | 13 | 14 | API REFERENCE 15 | 16 | # Create Rasengan CLI 17 | 18 | Rasengan.js comes with a CLI that can be used to create a new project. This CLI is very useful for creating automatically a new project with the a clear process of steps. 19 | 20 |
21 | 22 | To use the CLI, you can run the following command: 23 | 24 | ```bash title="Terminal" 25 | npx create-rasengan@latest my-app 26 | ``` 27 | 28 | ## Configuration 29 | 30 | Learn more about the Create Rasengan CLI in the `packages` page. 31 | 32 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/home/api/functions/functions.group.ts: -------------------------------------------------------------------------------- 1 | import { defineRoutesGroup } from 'rasengan'; 2 | import DefineConfigPage from './define-config.page.mdx'; 3 | import DefineRoutesGroupPage from './define-routes-group.page.mdx'; 4 | import DefineRouterPage from './define-router.page.mdx'; 5 | import renderAppPage from './render-app.page.mdx'; 6 | 7 | export default defineRoutesGroup({ 8 | path: '/functions', 9 | children: [ 10 | DefineConfigPage, 11 | DefineRoutesGroupPage, 12 | DefineRouterPage, 13 | renderAppPage, 14 | ], 15 | }); 16 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/home/api/functions/render-app.page.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | path: render-app 3 | metadata: 4 | title: Render App - Functions | API Reference | Rasengan.js 5 | description: How to use the renderApp function in Rasengan.js. 6 | toc: true 7 | --- 8 | 9 | import Pagination from '@/components/molecules/pagination'; 10 | import { Link } from "rasengan"; 11 | import StepItem from '@/components/molecules/step-item'; 12 | 13 | 14 | API REFERENCE 15 | 16 | # Render App 17 | 18 | `renderApp()` is a function that renders the application on the client side. 19 | 20 | ## Usage 21 | 22 | ```js title="main.js" showLineNumbers 23 | import { renderApp } from 'rasengan/client'; 24 | import App from "./main"; 25 | 26 | renderApp(App, { reactStrictMode: true }); 27 | ``` 28 | 29 | ## Options 30 | 31 | | Option | Type | Description | Default | 32 | |-----------------------------|--------------------------------------------|-------------|---------| 33 | | `App` | `React.FunctionComponent` | The root component of the application | - | 34 | | `reactStrictMode` | `boolean` | Enable React Strict Mode | `true` | 35 | 36 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/home/core-concepts/configuring/config.group.ts: -------------------------------------------------------------------------------- 1 | import { defineRoutesGroup } from 'rasengan'; 2 | import TypescriptPage from './typescript.page.mdx'; 3 | import EnvPage from './env.page.mdx'; 4 | import ModuleAliasesPage from './aliases.page.mdx'; 5 | 6 | export default defineRoutesGroup({ 7 | path: '/configuring', 8 | children: [TypescriptPage, EnvPage, ModuleAliasesPage], 9 | }); 10 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/home/core-concepts/configuring/env.page.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | path: environment-variables 3 | metadata: 4 | title: Environment Variables - Configuring | Core concepts | Rasengan.js 5 | description: Environment Variables in Rasengan.js 6 | toc: true 7 | --- 8 | 9 | import Pagination from '@/components/molecules/pagination'; 10 | import { Link } from "rasengan"; 11 | import StepItem from '@/components/molecules/step-item'; 12 | 13 | 14 | CORE CONCEPTS 15 | 16 | # Environment Variables 17 | 18 | Rasengan.js comes with built-in support for environment variables, which allows you to do the following: 19 | 20 | - Use `.env` to load environment variables 21 | - Bundle environment variables for the browser by prefixing with `RASENGAN_` 22 | 23 | ## Load Environment Variables 24 | 25 | Rasengan.js has built-in support for loading environment variables from `.env` into `import.meta.env`. 26 | 27 | ```txt title=".env" showLineNumbers copy 28 | RASENGAN_API_URL=https://api.example.com 29 | RASENGAN_API_KEY=abc123 30 | RASENGAN_PORT=3000 31 | ``` 32 | 33 | ## Access to Environment Variables 34 | 35 | Using environment variables in your application is easy. You can access them like follow: 36 | 37 | ```js title="src/app/home.page.js" showLineNumbers 38 | import.meta.env.RASENGAN_API_URL; // 'https://api.example.com' 39 | import.meta.env.RASENGAN_API_KEY; // 'abc123' 40 | import.meta.env.RASENGAN_PORT; // '3000' 41 | ``` 42 | 43 | {/* 44 | Only variables that start with `RASENGAN_` will be available in the browser. 45 | */} 46 | 47 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/home/core-concepts/core.group.ts: -------------------------------------------------------------------------------- 1 | import { defineRoutesGroup } from 'rasengan'; 2 | import RoutingGroup from './routing/routing.group'; 3 | import StylingGroup from './styling/styling.group'; 4 | import OptimizingGroup from './optimizing/optimizing.group'; 5 | import ConfigGroup from './configuring/config.group'; 6 | import DeployingGroup from './deploying/deploying.group'; 7 | import RenderingGroup from './rendering/rendering.group'; 8 | import ApiGroup from '../api/api.group'; 9 | 10 | export default defineRoutesGroup({ 11 | path: '/', 12 | children: [ 13 | RoutingGroup, 14 | RenderingGroup, 15 | StylingGroup, 16 | OptimizingGroup, 17 | ConfigGroup, 18 | DeployingGroup, 19 | ApiGroup, 20 | ], 21 | }); 22 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/home/core-concepts/deploying/deploying.group.ts: -------------------------------------------------------------------------------- 1 | import { defineRoutesGroup } from 'rasengan'; 2 | import NodeServerPage from './node.page.mdx'; 3 | import VercelPage from './vercel.page.mdx'; 4 | 5 | export default defineRoutesGroup({ 6 | path: '/deploying', 7 | children: [NodeServerPage, VercelPage], 8 | }); 9 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/home/core-concepts/deploying/node.page.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | path: node 3 | metadata: 4 | title: Deploying to Node.js Server - Deploying | Core concepts | Rasengan.js 5 | description: Deploy your Rasengan.js app to a Node.js server 6 | toc: true 7 | --- 8 | 9 | import Pagination from '@/components/molecules/pagination'; 10 | import { Link } from "rasengan"; 11 | import StepItem from '@/components/molecules/step-item'; 12 | 13 | 14 | CORE CONCEPTS 15 | 16 | # Deploying to Node.js Server 17 | 18 | Rasengan.js is a framework for building web applications using React. It is designed to be used with Node.js. 19 | 20 |
21 | In this guide, you will learn how to deploy a Rasengan.js app to a Node Server. 22 | 23 | ## Deploy 24 | 25 | To deploy your Rasengan.js app to a Node.js server, you need to configure your project to use the `@rasenganjs/serve` adapter. 26 | Have a look at the `Node adapter documentation` for more information. 27 | 28 | 29 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/home/core-concepts/deploying/vercel.page.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | path: vercel 3 | metadata: 4 | title: Deploying to Vercel - Deploying | Core concepts | Rasengan.js 5 | description: Deploy your Rasengan.js app to Vercel 6 | toc: true 7 | --- 8 | 9 | import Pagination from '@/components/molecules/pagination'; 10 | import { Link } from "rasengan"; 11 | import StepItem from '@/components/molecules/step-item'; 12 | 13 | 14 | CORE CONCEPTS 15 | 16 | # Deploying to Vercel 17 | 18 | Vercel is a cloud platform for static sites and Serverless Functions that fits perfectly with Rasengan.js. It enables developers to host websites and web services that deploy instantly, scale automatically, and require no supervision, all with minimal configuration. 19 | 20 |
21 | In this guide, you will learn how to deploy a Rasengan.js app to Vercel. 22 | 23 | ## Deploy 24 | 25 | To deploy your Rasengan.js app to Vercel, you need to configure your project to use the `@rasenganjs/vercel` adapter. 26 | Have a look at the `Vercel adapter documentation` for more information. 27 | 28 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/home/core-concepts/optimizing/optimizing.group.ts: -------------------------------------------------------------------------------- 1 | import { defineRoutesGroup } from 'rasengan'; 2 | import ImagesPage from './image.page.mdx'; 3 | import MetadataPage from './metadata.page.mdx'; 4 | import StaticAssetsPage from './static-assets.page.mdx'; 5 | 6 | export default defineRoutesGroup({ 7 | path: '/optimizing', 8 | children: [ImagesPage, MetadataPage, StaticAssetsPage], 9 | }); 10 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/home/core-concepts/rendering/prerendering.page.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | path: prerendering 3 | metadata: 4 | title: Prerendering - Rendering | Core concepts | Rasengan.js 5 | description: 6 | toc: true 7 | --- 8 | 9 | import Tabs from '@/components/molecules/tab'; 10 | import Pagination from '@/components/molecules/pagination'; 11 | 12 | 13 | CORE CONCEPTS 14 | 15 | # Prerendering -------------------------------------------------------------------------------- /docs/src/app/docs/pages/home/core-concepts/rendering/rendering.group.ts: -------------------------------------------------------------------------------- 1 | import { defineRoutesGroup } from 'rasengan'; 2 | import SSRPage from './ssr.page.mdx'; 3 | import CSRPage from './csr.page.mdx'; 4 | import PrerenderingPage from './prerendering.page.mdx'; 5 | 6 | export default defineRoutesGroup({ 7 | path: '/rendering', 8 | children: [SSRPage, CSRPage, PrerenderingPage], 9 | }); 10 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/home/core-concepts/routing/routing.group.ts: -------------------------------------------------------------------------------- 1 | import { defineRoutesGroup } from 'rasengan'; 2 | import BaseConceptsPage from './base-concepts.page.mdx'; 3 | import RoutesPage from './routes.page.mdx'; 4 | import RouterConfigurationPage from './router.page.mdx'; 5 | import LayoutsPage from './layouts.page.mdx'; 6 | import LinkingAndNavigatingPage from './linking.page.mdx'; 7 | import DynamicRoutesPage from './dynamic-routes.page.mdx'; 8 | import ErrorHandlingPage from './error-handling.page.mdx'; 9 | import RedirectingPage from './redirecting.page.mdx'; 10 | 11 | export default defineRoutesGroup({ 12 | path: '/routing', 13 | children: [ 14 | BaseConceptsPage, 15 | RouterConfigurationPage, 16 | RoutesPage, 17 | LayoutsPage, 18 | LinkingAndNavigatingPage, 19 | DynamicRoutesPage, 20 | ErrorHandlingPage, 21 | RedirectingPage, 22 | ], 23 | }); 24 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/home/core-concepts/styling/styling.group.ts: -------------------------------------------------------------------------------- 1 | import { defineRoutesGroup } from 'rasengan'; 2 | import CSSModulesPage from './css-modules.page.mdx'; 3 | import TailwindCSSPage from './tailwind.page.mdx'; 4 | import CSSPreprocessorsPage from './css-processors.page.mdx'; 5 | 6 | export default defineRoutesGroup({ 7 | path: '/styling', 8 | children: [CSSModulesPage, TailwindCSSPage, CSSPreprocessorsPage], 9 | }); 10 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/home/getting-started/getting-started.group.ts: -------------------------------------------------------------------------------- 1 | import { defineRoutesGroup } from 'rasengan'; 2 | import IntroductionPage from './introduction.page.mdx'; 3 | import InstallationPage from './installation.page.mdx'; 4 | import ProjectStructurePage from './project-structure.page.mdx'; 5 | 6 | export default defineRoutesGroup({ 7 | path: '/getting-started', 8 | children: [IntroductionPage, InstallationPage, ProjectStructurePage], 9 | }); 10 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/home/home.group.ts: -------------------------------------------------------------------------------- 1 | import { defineRoutesGroup } from 'rasengan'; 2 | import GettingStartedGroup from './getting-started/getting-started.group'; 3 | import CoreGroup from './core-concepts/core.group'; 4 | 5 | export default defineRoutesGroup({ 6 | path: '/docs', 7 | children: [GettingStartedGroup, CoreGroup], 8 | }); 9 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/packages/module/kurama.page.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | path: kurama 3 | metadata: 4 | title: Kurama Package - Modules | Packages | Rasengan.js 5 | description: Documentation for the Kurama package. 6 | toc: true 7 | --- 8 | 9 | 10 | PACKAGES 11 | 12 | # Kurama 13 | 14 | ## Installation 15 | 16 | ```bash title="Terminal" 17 | npm install @rasenganjs/kurama 18 | ``` 19 | 20 | ## Community 21 | 22 | Join the Rasengan.js community to get support, ask questions, and share your projects: 23 | 24 | - GitHub Discussions – Ask questions and share ideas. 25 | {/* - **Discord** – Chat with the community. */} 26 | - X (Twitter) – Stay updated with the latest news. 27 | - Linkedin – Follow the company page. 28 | 29 | Let's build something amazing with Rasengan.js! 🚀 30 | 31 | ## License 32 | 33 | This package is [MIT licensed](https://github.com/rasengan-dev/rasenganjs/blob/main/LICENSE). 34 | 35 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/packages/module/modules.group.ts: -------------------------------------------------------------------------------- 1 | import { defineRoutesGroup } from 'rasengan'; 2 | import ImagePage from './image.page.mdx'; 3 | import CreateRasenganPage from './create-rasengan.page.mdx'; 4 | import KuramaPage from './kurama.page.mdx'; 5 | import MDXPage from './mdx.page.mdx'; 6 | import ThemePage from './theme.page.mdx'; 7 | import ServePage from './serve.page.mdx'; 8 | import VercelPage from './vercel.page.mdx'; 9 | 10 | export default defineRoutesGroup({ 11 | path: '/', 12 | children: [ 13 | ImagePage, 14 | CreateRasenganPage, 15 | KuramaPage, 16 | MDXPage, 17 | ThemePage, 18 | ServePage, 19 | VercelPage, 20 | ], 21 | }); 22 | -------------------------------------------------------------------------------- /docs/src/app/docs/pages/packages/package.group.ts: -------------------------------------------------------------------------------- 1 | import { defineRoutesGroup } from 'rasengan'; 2 | import IntroductionPage from './introduction.page.mdx'; 3 | import ModulesGroup from './module/modules.group'; 4 | 5 | export default defineRoutesGroup({ 6 | path: '/packages', 7 | children: [IntroductionPage, ModulesGroup], 8 | }); 9 | -------------------------------------------------------------------------------- /docs/src/app/root/pages/blog.page.tsx: -------------------------------------------------------------------------------- 1 | import BlogCard from '@/components/molecules/blog-card'; 2 | import CTA from '@/components/molecules/cta'; 3 | import Heading from '@/components/molecules/heading'; 4 | import { useBlogStore } from '@/store/blog'; 5 | import { PageComponent } from 'rasengan'; 6 | 7 | const Blog: PageComponent = () => { 8 | const { blog: posts } = useBlogStore(); 9 | 10 | return ( 11 |
12 |
13 | 17 | 18 |
19 | {posts.map((post, index) => ( 20 | 21 | ))} 22 |
23 |
24 | 25 |
26 | 27 |
28 |
29 | ); 30 | }; 31 | 32 | Blog.path = '/blog'; 33 | Blog.metadata = { 34 | title: 'Rasengan.js - Blog', 35 | description: 'Discover the latest news and updates about Rasengan.js.', 36 | openGraph: { 37 | title: 'Rasengan.js - Blog', 38 | description: 'Discover the latest news and updates about Rasengan.js.', 39 | url: 'https://rasengan.dev', 40 | image: 'https://rasengan.dev/assets/images/metadata/blog.png', 41 | }, 42 | twitter: { 43 | card: 'summary_large_image', 44 | title: 'Rasengan.js - Blog', 45 | description: 'Discover the latest news and updates about Rasengan.js.', 46 | image: 'https://rasengan.dev/assets/images/metadata/blog.png', 47 | }, 48 | }; 49 | 50 | export default Blog; 51 | -------------------------------------------------------------------------------- /docs/src/app/root/pages/learn.page.tsx: -------------------------------------------------------------------------------- 1 | import { Link, PageComponent } from 'rasengan'; 2 | import Image from '@rasenganjs/image'; 3 | import image from '@/assets/images/illustrations/learn-loading.gif'; 4 | import Button from '@/components/atoms/buttons/button'; 5 | 6 | const Learn: PageComponent = () => { 7 | return ( 8 |
9 | 13 | Learn Rasengan.js loading gif 14 | 15 | 16 |

17 | Learn Rasengan.js 18 |

19 |

20 | This is a work in progress. You can help us by contributing to the docs 21 |

22 | 23 |
24 | 25 | 28 | 29 | 30 | 33 | 34 |
35 |
36 | ); 37 | }; 38 | 39 | Learn.path = '/learn'; 40 | Learn.metadata = { 41 | title: 'Rasengan.js - Learn', 42 | description: 'Learn how to use Rasengan.js', 43 | }; 44 | 45 | export default Learn; 46 | -------------------------------------------------------------------------------- /docs/src/app/root/root.layout.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Outlet, LayoutComponent } from 'rasengan'; 3 | import Navbar from '@/components/layout/navbar'; 4 | import Footer from '@/components/layout/footer'; 5 | 6 | const AppLayout: LayoutComponent = () => { 7 | return ( 8 |
9 | 10 | 11 |
12 | 13 |
14 | 15 |
16 |
17 | ); 18 | }; 19 | 20 | AppLayout.path = '/'; 21 | 22 | export default AppLayout; 23 | -------------------------------------------------------------------------------- /docs/src/app/root/root.router.tsx: -------------------------------------------------------------------------------- 1 | import { RouterComponent, defineRouter } from 'rasengan'; 2 | import RootLayout from '@/app/root/root.layout'; 3 | import Home from '@/app/root/pages/home.page'; 4 | import Blog from '@/app/root/pages/blog.page'; 5 | import Showcase from '@/app/root/pages/showcase.page'; 6 | import Learn from '@/app/root/pages/learn.page'; 7 | 8 | class RootRouter extends RouterComponent {} 9 | 10 | export default defineRouter({ 11 | imports: [], 12 | layout: RootLayout, 13 | pages: [Home, Blog, Showcase, Learn], 14 | })(RootRouter); 15 | -------------------------------------------------------------------------------- /docs/src/assets/font/GeistMono-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/src/assets/font/GeistMono-Light.ttf -------------------------------------------------------------------------------- /docs/src/assets/font/GeistMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/src/assets/font/GeistMono-Regular.ttf -------------------------------------------------------------------------------- /docs/src/assets/font/Lexend-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/src/assets/font/Lexend-Bold.ttf -------------------------------------------------------------------------------- /docs/src/assets/font/Lexend-Light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/src/assets/font/Lexend-Light.ttf -------------------------------------------------------------------------------- /docs/src/assets/font/Lexend-Medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/src/assets/font/Lexend-Medium.ttf -------------------------------------------------------------------------------- /docs/src/assets/font/Lexend-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/src/assets/font/Lexend-Regular.ttf -------------------------------------------------------------------------------- /docs/src/assets/images/illustrations/blue-light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/src/assets/images/illustrations/cta-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/src/assets/images/illustrations/cta-light.png -------------------------------------------------------------------------------- /docs/src/assets/images/illustrations/learn-loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/docs/src/assets/images/illustrations/learn-loading.gif -------------------------------------------------------------------------------- /docs/src/components/atoms/badges/badge.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentProps } from 'react'; 2 | import { twMerge } from 'tailwind-merge'; 3 | 4 | type Props = { 5 | text: string; 6 | children?: React.ReactNode; 7 | className?: ComponentProps<'span'>['className']; 8 | }; 9 | 10 | export function AnnonceBadge({ children, text, className }: Props) { 11 | return ( 12 | 18 | {text} 19 | {children} 20 | 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /docs/src/components/atoms/buttons/button.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentProps } from 'react'; 2 | import { twMerge } from 'tailwind-merge'; 3 | import { motion } from 'motion/react'; 4 | 5 | type ButtonProps = { 6 | children: React.ReactNode; 7 | className?: ComponentProps<'button'>['className']; 8 | onClick?: () => void; 9 | hover?: boolean; 10 | tap?: boolean; 11 | } & ComponentProps<'button'>; 12 | 13 | export default function Button({ 14 | children, 15 | onClick, 16 | className, 17 | hover = false, 18 | tap = false, 19 | ...props 20 | }: ButtonProps) { 21 | return ( 22 | 26 | 36 | 37 | ); 38 | } 39 | -------------------------------------------------------------------------------- /docs/src/components/atoms/buttons/theme-button.tsx: -------------------------------------------------------------------------------- 1 | import { useTheme } from '@rasenganjs/theme'; 2 | import { Moon, Sun } from 'lucide-react'; 3 | import { motion, AnimatePresence } from 'motion/react'; 4 | import { twMerge } from 'tailwind-merge'; 5 | 6 | type Props = { 7 | size?: 'normal' | 'small'; 8 | }; 9 | 10 | export default function ThemeButton({ size = 'normal' }: Props) { 11 | const { setTheme, isDark } = useTheme(); 12 | 13 | const handleThemeChange = () => { 14 | setTheme(isDark ? 'light' : 'dark'); 15 | }; 16 | 17 | return ( 18 | 26 | 27 | {isDark ? ( 28 | 35 | 36 | 37 | ) : ( 38 | 45 | 46 | 47 | )} 48 | 49 | 50 | ); 51 | } 52 | -------------------------------------------------------------------------------- /docs/src/components/atoms/logo/index.tsx: -------------------------------------------------------------------------------- 1 | import { Link } from 'rasengan'; 2 | import Image from '@rasenganjs/image'; 3 | import { useTheme } from '@rasenganjs/theme'; 4 | 5 | type Props = { 6 | size?: 'sm' | 'md' | 'lg'; 7 | }; 8 | 9 | export default function AppLogo({ size = 'md' }: Props) { 10 | const { isDark } = useTheme(); 11 | 12 | return ( 13 | 14 | Rasengan Logo 22 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /docs/src/components/molecules/blog-author-card.tsx: -------------------------------------------------------------------------------- 1 | import { twMerge } from 'tailwind-merge'; 2 | import { Author } from '@/data/blog/authors'; 3 | import { Link } from 'rasengan'; 4 | import Image from '@rasenganjs/image'; 5 | 6 | type Props = { 7 | author: Author; 8 | }; 9 | 10 | export default function BlogAuthorCard({ author }: Props) { 11 | return ( 12 | 13 |
18 | Author name 25 | 26 |
27 | {author.name} 28 | 29 | {author.username} 30 | 31 |
32 |
33 | 34 | ); 35 | } 36 | -------------------------------------------------------------------------------- /docs/src/components/molecules/feature-card.tsx: -------------------------------------------------------------------------------- 1 | import { ComponentProps } from 'react'; 2 | import { twMerge } from 'tailwind-merge'; 3 | 4 | type Props = { 5 | title: string; 6 | description: string; 7 | icon: React.ReactNode; 8 | className?: ComponentProps<'article'>['className']; 9 | }; 10 | 11 | export default function FeatureCard({ 12 | title, 13 | description, 14 | icon, 15 | className, 16 | }: Props) { 17 | return ( 18 |
24 | 25 | {icon} 26 | 27 |

{title}

28 |

{description}

29 |
30 | ); 31 | } 32 | -------------------------------------------------------------------------------- /docs/src/components/molecules/heading.tsx: -------------------------------------------------------------------------------- 1 | import { twMerge } from 'tailwind-merge'; 2 | 3 | type Props = { 4 | title: string; 5 | description: string; 6 | className?: string; 7 | }; 8 | 9 | export default function Heading({ title, description, className = '' }: Props) { 10 | return ( 11 |
12 |

{title}

13 |

14 | {description} 15 |

16 |
17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /docs/src/components/molecules/pagination.tsx: -------------------------------------------------------------------------------- 1 | import { ChevronLeft, ChevronRight } from 'lucide-react'; 2 | import { Link } from 'rasengan'; 3 | 4 | type Props = { 5 | next: { 6 | label: string; 7 | href: string; 8 | }; 9 | prev: { 10 | label: string; 11 | href: string; 12 | }; 13 | }; 14 | 15 | export default function Pagination({ next, prev }: Props) { 16 | return ( 17 |
18 | 22 |
23 | 24 | {prev.label} 25 |
26 | 27 | 28 | {next && ( 29 | 33 |
34 | {next.label} 35 | 36 |
37 | 38 | )} 39 |
40 | ); 41 | } 42 | -------------------------------------------------------------------------------- /docs/src/components/molecules/showcase-card.tsx: -------------------------------------------------------------------------------- 1 | import Image from '@rasenganjs/image'; 2 | import { ExternalLink } from 'lucide-react'; 3 | import { motion } from 'motion/react'; 4 | import { Link } from 'rasengan'; 5 | import { ComponentProps } from 'react'; 6 | import { twMerge } from 'tailwind-merge'; 7 | 8 | type Props = { 9 | image: string; 10 | title: string; 11 | link: string; 12 | className?: ComponentProps<'article'>['className']; 13 | }; 14 | 15 | export const ShowcaseCard = ({ image, title, link, className }: Props) => { 16 | return ( 17 | 22 | 30 | Showcase 37 | 38 |
39 |

{title}

40 | 41 | 42 | 43 |
44 |
45 | 46 | ); 47 | }; 48 | -------------------------------------------------------------------------------- /docs/src/components/molecules/step-item.tsx: -------------------------------------------------------------------------------- 1 | import { Markdown } from '@rasenganjs/mdx'; 2 | import { ComponentProps, ReactNode } from 'react'; 3 | import { twMerge } from 'tailwind-merge'; 4 | 5 | type Props = { 6 | children: ReactNode; 7 | content: string; 8 | title: string; 9 | step: string; 10 | className?: ComponentProps<'article'>['className']; 11 | }; 12 | 13 | export default function StepItem({ 14 | children, 15 | step, 16 | title, 17 | content, 18 | className, 19 | }: Props) { 20 | return ( 21 |
24 |
25 |
26 | [{step}] 27 | {title} 28 |
29 | 30 | 31 | 32 | {/* {content} */} 33 | 34 |
35 |
{children}
36 |
37 | ); 38 | } 39 | -------------------------------------------------------------------------------- /docs/src/data/blog/authors.ts: -------------------------------------------------------------------------------- 1 | export type Author = { 2 | id: number; 3 | name: string; 4 | username: string; 5 | avatar: string; 6 | link: string; 7 | }; 8 | 9 | export const AuthorUsernames = { 10 | dilaneKombou: '@dilanekombou', 11 | } as const; 12 | 13 | type AuthorUsername = (typeof AuthorUsernames)[keyof typeof AuthorUsernames]; 14 | 15 | export const Authors: Record = { 16 | [AuthorUsernames.dilaneKombou]: { 17 | id: 1, 18 | name: 'Dilane Kombou', 19 | username: AuthorUsernames.dilaneKombou, 20 | avatar: '/assets/blog/authors/dilane-kombou.jpeg', 21 | link: 'https://twitter.com/dilanekombou', 22 | }, 23 | }; 24 | -------------------------------------------------------------------------------- /docs/src/data/blog/index.tsx: -------------------------------------------------------------------------------- 1 | import { Author, Authors, AuthorUsernames } from './authors'; 2 | 3 | export type BlogDataType = { 4 | id: number; 5 | title: string; 6 | description: string; 7 | authors: Array; 8 | postedAt: string; 9 | link: string; 10 | image: string; 11 | readingTime: string; 12 | }; 13 | 14 | export const BlogData: Array = [ 15 | { 16 | id: 1, 17 | title: 'Rasengan v1 Stable', 18 | description: ` 19 | Rasengan v1 is now stable and ready for production use. This release includes a lot of new features and code base improvements. 20 | `, 21 | authors: [Authors[AuthorUsernames.dilaneKombou]], 22 | postedAt: 'April 26, 2025', 23 | link: '/blog/rasengan-v1-stable', 24 | image: '/assets/blog/rasengan-stable1.png', 25 | readingTime: '5 min', 26 | }, 27 | { 28 | id: 2, 29 | title: 'Rasengan 1.0.0 Beta', 30 | description: ` 31 | We are launching the first beta version of Rasengan.js, a modern React Framework that you can use to create high-quality web applications. 32 | `, 33 | authors: [Authors[AuthorUsernames.dilaneKombou]], 34 | postedAt: 'April 25, 2024', 35 | link: '/blog/rasengan-1-beta', 36 | image: '/assets/blog/rasengan-beta1.png', 37 | readingTime: '3 min', 38 | }, 39 | ]; 40 | -------------------------------------------------------------------------------- /docs/src/index.ts: -------------------------------------------------------------------------------- 1 | import { renderApp } from 'rasengan/client'; 2 | import App from './main'; 3 | 4 | renderApp(App, { reactStrictMode: true }); 5 | -------------------------------------------------------------------------------- /docs/src/main.tsx: -------------------------------------------------------------------------------- 1 | import '@rasenganjs/image/css'; 2 | import '@rasenganjs/mdx/css'; 3 | import '@/styles/index.css'; 4 | import '@/styles/mdx.scss'; 5 | import { type AppProps } from 'rasengan'; 6 | import AppRouter from '@/app/app.router'; 7 | import ThemeProvider from '@rasenganjs/theme'; 8 | import { Analytics } from '@vercel/analytics/react'; 9 | 10 | export default function App({ Component, children }: AppProps) { 11 | return ( 12 | 13 | {children} 14 | 15 | 16 | 17 | ); 18 | } 19 | -------------------------------------------------------------------------------- /docs/src/store/blog/index.ts: -------------------------------------------------------------------------------- 1 | import { BlogData, BlogDataType } from '@/data/blog'; 2 | import { create } from 'zustand'; 3 | 4 | type State = { 5 | blog: Array; 6 | }; 7 | 8 | export const useBlogStore = create(() => ({ 9 | blog: BlogData, 10 | })); 11 | -------------------------------------------------------------------------------- /docs/src/store/navigation/index.ts: -------------------------------------------------------------------------------- 1 | import { create } from 'zustand'; 2 | 3 | type State = { 4 | isOpen: boolean; 5 | }; 6 | 7 | type Actions = { 8 | toggle: () => void; 9 | }; 10 | 11 | export const useNavigationStore = create((set) => ({ 12 | isOpen: false, 13 | toggle: () => set((state) => ({ isOpen: !state.isOpen })), 14 | })); 15 | -------------------------------------------------------------------------------- /docs/src/template.tsx: -------------------------------------------------------------------------------- 1 | import { type TemplateProps } from 'rasengan'; 2 | 3 | export default function Template({ Head, Body, Script }: TemplateProps) { 4 | return ( 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
4 | -------------------------------------------------------------------------------- /playground/file-based-routing/dist/robots.txt: -------------------------------------------------------------------------------- 1 | user-agent: * 2 | disallow: /downloads/ 3 | disallow: /private/ 4 | allow: / 5 | 6 | user-agent: magicsearchbot 7 | disallow: /uploads/ -------------------------------------------------------------------------------- /playground/file-based-routing/dist/server/assets/page-signin-BBokP9vt.js: -------------------------------------------------------------------------------- 1 | import { jsx } from "react/jsx-runtime"; 2 | const Signin = () => { 3 | return /* @__PURE__ */ jsx("section", { className: "w-full h-full bg-white flex flex-col items-center justify-center px-[20px] md:px-[50px] xl:px-[200px] font-comfortaa", children: "Signin page" }); 4 | }; 5 | const metadata = { 6 | title: "Signin", 7 | description: "Signin page" 8 | }; 9 | Signin.metadata = metadata; 10 | const __vite_glob_0_1 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({ 11 | __proto__: null, 12 | default: Signin 13 | }, Symbol.toStringTag, { value: "Module" })); 14 | export { 15 | __vite_glob_0_1 as _ 16 | }; 17 | -------------------------------------------------------------------------------- /playground/file-based-routing/dist/server/main.js: -------------------------------------------------------------------------------- 1 | import { jsx } from "react/jsx-runtime"; 2 | import AppRouter from "./app.router.js"; 3 | import "./assets/template-CEO8RV0b.js"; 4 | import "react"; 5 | import "./assets/vendor-CsqfrH1N.js"; 6 | import "react-dom/server"; 7 | import "./assets/page-index-FclJ1kNm.js"; 8 | import "./assets/page-signin-BBokP9vt.js"; 9 | function App({ Component, children }) { 10 | return /* @__PURE__ */ jsx(Component, { router: AppRouter, children }); 11 | } 12 | export { 13 | App as default 14 | }; 15 | -------------------------------------------------------------------------------- /playground/file-based-routing/dist/server/robots.txt: -------------------------------------------------------------------------------- 1 | user-agent: * 2 | disallow: /downloads/ 3 | disallow: /private/ 4 | allow: / 5 | 6 | user-agent: magicsearchbot 7 | disallow: /uploads/ -------------------------------------------------------------------------------- /playground/file-based-routing/dist/server/template.js: -------------------------------------------------------------------------------- 1 | import { jsxs, jsx } from "react/jsx-runtime"; 2 | function Template({ Head, Body, Script }) { 3 | return /* @__PURE__ */ jsxs("html", { lang: "en", children: [ 4 | /* @__PURE__ */ jsxs(Head, { children: [ 5 | /* @__PURE__ */ jsx("meta", { charSet: "UTF-8" }), 6 | /* @__PURE__ */ jsx("link", { rel: "icon", type: "image/svg+xml", href: "/rasengan.svg" }), 7 | /* @__PURE__ */ jsx("meta", { name: "viewport", content: "width=device-width, initial-scale=1.0" }) 8 | ] }), 9 | /* @__PURE__ */ jsx(Body, { children: /* @__PURE__ */ jsx(Script, {}) }) 10 | ] }); 11 | } 12 | export { 13 | Template as default 14 | }; 15 | -------------------------------------------------------------------------------- /playground/rasengan-v1-test/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | dist 12 | dist-ssr 13 | .vercel 14 | *.local 15 | 16 | # Cache 17 | .vite 18 | .rasengan 19 | 20 | # Editor directories and files 21 | .vscode/* 22 | !.vscode/extensions.json 23 | .idea 24 | .DS_Store 25 | *.suo 26 | *.ntvs* 27 | *.njsproj 28 | *.sln 29 | *.sw? 30 | 31 | # Local Netlify folder 32 | .netlify 33 | -------------------------------------------------------------------------------- /playground/rasengan-v1-test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "rasengan-v2-test", 3 | "private": true, 4 | "version": "1.0.0", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "rasengan dev", 8 | "build": "rasengan build", 9 | "serve": "rasengan-serve ./dist" 10 | }, 11 | "dependencies": { 12 | "@rasenganjs/image": "workspace:*", 13 | "@rasenganjs/mdx": "workspace:*", 14 | "@rasenganjs/serve": "workspace:*", 15 | "@rasenganjs/vercel": "workspace:*", 16 | "@tailwindcss/vite": "^4.*", 17 | "lucide-react": "^0.477.0", 18 | "rasengan": "workspace:*", 19 | "react": "^19.0.0", 20 | "react-dom": "^19.0.0", 21 | "tailwindcss": "^4.*" 22 | }, 23 | "devDependencies": { 24 | "@types/react": "^19.0.0", 25 | "@types/react-dom": "^19.0.0", 26 | "autoprefixer": "^10.4.16", 27 | "cross-env": "^7.0.3", 28 | "postcss": "^8.4.31", 29 | "typescript": "^5.1.3", 30 | "vite": "^6.2.6" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /playground/rasengan-v1-test/public/robots.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rasengan-dev/rasenganjs/4c3b1bdb3836b0b5d48a6009b4a502cda76d448f/playground/rasengan-v1-test/public/robots.txt -------------------------------------------------------------------------------- /playground/rasengan-v1-test/rasengan-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /playground/rasengan-v1-test/rasengan.config.js: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'rasengan'; 2 | import { rasengan } from 'rasengan/plugin'; 3 | import mdx from '@rasenganjs/mdx/plugin'; 4 | import tailwindcss from '@tailwindcss/vite'; 5 | import { configure } from '@rasenganjs/vercel'; 6 | 7 | export default defineConfig({ 8 | // ssr: false, 9 | vite: { 10 | plugins: [ 11 | mdx(), 12 | tailwindcss(), 13 | rasengan({ 14 | adapter: configure({}), 15 | }), 16 | ], 17 | }, 18 | }); 19 | -------------------------------------------------------------------------------- /playground/rasengan-v1-test/src/app/app.router.ts: -------------------------------------------------------------------------------- 1 | import { RouterComponent, defineRouter } from 'rasengan'; 2 | import AppLayout from '@/app/app.layout'; 3 | import Blog from '@/app/blog.page.mdx'; 4 | import SubRouter from '@/app/sub-router/sub-router.router'; 5 | 6 | class AppRouter extends RouterComponent {} 7 | 8 | export default defineRouter({ 9 | imports: [SubRouter], 10 | layout: AppLayout, 11 | pages: [Blog], 12 | })(AppRouter); 13 | -------------------------------------------------------------------------------- /playground/rasengan-v1-test/src/app/sub-router/about.page.tsx: -------------------------------------------------------------------------------- 1 | import { Link, PageComponent } from 'rasengan'; 2 | 3 | export const About: PageComponent = () => { 4 | return ( 5 |
6 |

About page

7 | 8 | 9 | Home 10 | 11 |
12 | ); 13 | }; 14 | 15 | About.path = '/about'; 16 | 17 | About.metadata = { 18 | title: 'About', 19 | description: 'About page', 20 | }; 21 | -------------------------------------------------------------------------------- /playground/rasengan-v1-test/src/app/sub-router/group/index.group.ts: -------------------------------------------------------------------------------- 1 | import { defineRoutesGroup } from 'rasengan'; 2 | import { Contact } from './contact.page'; 3 | import { Pricing } from './pricing.page'; 4 | 5 | export default defineRoutesGroup({ 6 | path: '/group', 7 | children: [Contact, Pricing], 8 | }); 9 | -------------------------------------------------------------------------------- /playground/rasengan-v1-test/src/app/sub-router/group/pricing.page.tsx: -------------------------------------------------------------------------------- 1 | import { PageComponent } from 'rasengan'; 2 | 3 | export const Pricing: PageComponent = () => { 4 | return ( 5 |
6 |

Pricing page

7 |
8 | ); 9 | }; 10 | 11 | Pricing.path = '/pricing'; 12 | 13 | Pricing.metadata = { 14 | title: 'Pricing', 15 | description: 'Pricing page', 16 | }; 17 | -------------------------------------------------------------------------------- /playground/rasengan-v1-test/src/app/sub-router/sub-router.router.ts: -------------------------------------------------------------------------------- 1 | import { defineRouter, RouterComponent } from 'rasengan'; 2 | import { About } from '@/app/sub-router/about.page'; 3 | import Group1 from './group/index.group'; 4 | import Home from './home.page'; 5 | 6 | class SubRouter extends RouterComponent {} 7 | 8 | export default defineRouter({ 9 | imports: [], 10 | pages: [Home, About, Group1], 11 | useParentLayout: false, 12 | })(SubRouter); 13 | -------------------------------------------------------------------------------- /playground/rasengan-v1-test/src/index.ts: -------------------------------------------------------------------------------- 1 | import { renderApp } from 'rasengan/client'; 2 | import App from './main'; 3 | 4 | renderApp(App, { reactStrictMode: true }); 5 | -------------------------------------------------------------------------------- /playground/rasengan-v1-test/src/main.tsx: -------------------------------------------------------------------------------- 1 | import '@rasenganjs/image/css'; 2 | import '@/styles/index.css'; 3 | import '@rasenganjs/mdx/css'; 4 | import { type AppProps } from 'rasengan'; 5 | import AppRouter from '@/app/app.router'; 6 | 7 | export default function App({ Component, children }: AppProps) { 8 | return {children}; 9 | } 10 | -------------------------------------------------------------------------------- /playground/rasengan-v1-test/src/styles/index.css: -------------------------------------------------------------------------------- 1 | /* Load Urbanist and Comfortaa font */ 2 | @import url('https://fonts.googleapis.com/css2?family=Comfortaa:wght@200;300;400;500;600&family=Urbanist:wght@100;200;300;400;500;600;700&display=swap'); 3 | @import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap'); 4 | @import url('https://fonts.googleapis.com/css2?family=Geist+Mono:wght@100..900&family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap'); 5 | 6 | @import 'tailwindcss'; 7 | 8 | @theme { 9 | --color-primary: #2a7fff; 10 | --color-border: #eee; 11 | 12 | --font-urbanist: Urbanist, sans-serif; 13 | --font-comfortaa: Comfortaa, sans-serif; 14 | --font-inter: Inter, sans-serif; 15 | --font-mono: 'Geist Mono', sans-serif; 16 | } 17 | 18 | :root { 19 | --main-width: calc(100% - 280px); 20 | } 21 | 22 | body, 23 | html { 24 | box-sizing: border-box; 25 | margin: 0; 26 | padding: 0; 27 | width: 100vw; 28 | min-height: 100vh; 29 | overflow: hidden; 30 | font-family: 'Inter'; 31 | /* font-weight: 100; */ 32 | } 33 | -------------------------------------------------------------------------------- /playground/rasengan-v1-test/src/template.tsx: -------------------------------------------------------------------------------- 1 | import { type TemplateProps } from 'rasengan'; 2 | 3 | export default function Template({ Head, Body, Script }: TemplateProps) { 4 | return ( 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |