├── .env.example ├── .github └── workflows │ ├── ci.yml │ └── pullrequest_validation.yml ├── .gitignore ├── LICENSE ├── README.md ├── app ├── api │ ├── stacks │ │ ├── basic-openai │ │ │ └── route.ts │ │ ├── boilerplate-basic │ │ │ └── route.ts │ │ ├── chat-gemini-streaming-langchain │ │ │ └── route.ts │ │ ├── chat-with-gemini-langchain │ │ │ └── route.ts │ │ ├── chat-with-gemini-streaming │ │ │ └── route.ts │ │ ├── chat-with-gemini │ │ │ └── route.ts │ │ ├── chat-with-openai-streaming-helicone │ │ │ └── route.ts │ │ ├── chat-with-openai-streaming-langchain │ │ │ └── route.ts │ │ ├── chat-with-openai-streaming │ │ │ └── route.ts │ │ ├── cover-image-and-subtitle │ │ │ └── route.ts │ │ ├── create-stack-boilerplate │ │ │ ├── create-stack.ts │ │ │ ├── get-file-from-github.ts │ │ │ ├── push-multiple-files-to-branch.ts │ │ │ └── route.ts │ │ ├── elevenlabs-tts │ │ │ └── route.ts │ │ ├── get-image-description-openai │ │ │ └── route.ts │ │ ├── image-sharpener │ │ │ └── route.ts │ │ ├── image-to-music │ │ │ └── route.ts │ │ ├── rag-pdf-with-langchain │ │ │ └── route.ts │ │ ├── stable-video-diffusion │ │ │ └── route.ts │ │ ├── text-to-qr │ │ │ └── route.ts │ │ └── use-openai-assistant │ │ │ └── route.ts │ └── utils │ │ └── getAWSPresignedUrl │ │ └── route.ts ├── components │ ├── shared │ │ ├── ContactButton.tsx │ │ └── clipboard.tsx │ └── stacks │ │ ├── boilerplate-basic.tsx │ │ ├── chat-gemini-streaming-langchain.tsx │ │ ├── chat-with-gemini-langchain.tsx │ │ ├── chat-with-gemini-streaming.tsx │ │ ├── chat-with-gemini.tsx │ │ ├── chat-with-openai-streaming-helicone.tsx │ │ ├── chat-with-openai-streaming-langchain.tsx │ │ ├── chat-with-openai-streaming.tsx │ │ ├── cover-image-and-subtitle.tsx │ │ ├── create-ai-canvas.tsx │ │ ├── create-stack-boilerplate.tsx │ │ ├── creation │ │ ├── Inputs.tsx │ │ ├── content.tsx │ │ ├── input-with-button.tsx │ │ ├── main-content.tsx │ │ └── outputs.tsx │ │ ├── elevenlabs-tts.tsx │ │ ├── get-image-description-openai.tsx │ │ ├── image-sharpener.tsx │ │ ├── image-to-music.tsx │ │ ├── instant-video-to-image.tsx │ │ ├── rag-pdf-with-langchain.tsx │ │ ├── stable-video-diffusion.tsx │ │ ├── text-to-qr.tsx │ │ ├── use-openai-assistant.tsx │ │ └── utils │ │ ├── actions.ts │ │ ├── search-stacks.tsx │ │ ├── signIn.tsx │ │ ├── signOut.tsx │ │ └── stack-db.ts ├── favicon.ico ├── globals.css ├── layout.tsx └── stacks │ ├── [slug] │ └── page.tsx │ └── page.tsx ├── next.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── apocalyptic_car.png ├── boat_example.webp ├── caesar.jpeg ├── next.svg ├── placeholder.png ├── stack-pictures │ ├── boilerplate-basic.png │ ├── chat-gemini-streaming-langchain.png │ ├── chat-with-gemini-langchain.png │ ├── chat-with-gemini-streaming.png │ ├── chat-with-gemini.png │ ├── chat-with-openai-streaming-helicone.png │ ├── chat-with-openai-streaming-langchain.png │ ├── chat-with-openai-streaming.png │ ├── cover-image-and-subtitle.png │ ├── create-ai-canvas.png │ ├── create-stack-boilerplate.png │ ├── elevenlabs-tts.png │ ├── generate-a-cover-image-and-subtitle-on-uploading-a-video.png │ ├── get-image-description-openai.png │ ├── image-sharpener.png │ ├── image-to-music.png │ ├── instant-video-to-image.png │ ├── rag-pdf-with-langchain.png │ ├── stable-video-diffusion.png │ ├── stack-example.png │ ├── stackwise-onboarding.png │ ├── text-to-qr.png │ └── use-openai-assistant.png ├── stacks │ ├── boilerplate-basic.tsx │ ├── chat-gemini-streaming-langchain.tsx │ ├── chat-with-gemini-langchain.tsx │ ├── chat-with-gemini-streaming.tsx │ ├── chat-with-gemini.tsx │ ├── chat-with-openai-streaming-helicone.tsx │ ├── chat-with-openai-streaming-langchain.tsx │ ├── chat-with-openai-streaming.tsx │ ├── cover-image-and-subtitle.tsx │ ├── create-ai-canvas.tsx │ ├── create-stack-boilerplate.tsx │ ├── creation │ │ ├── Inputs.tsx │ │ ├── content.tsx │ │ ├── input-with-button.tsx │ │ ├── main-content.tsx │ │ └── outputs.tsx │ ├── elevenlabs-tts.tsx │ ├── get-image-description-openai.tsx │ ├── image-sharpener.tsx │ ├── image-to-music.tsx │ ├── instant-video-to-image.tsx │ ├── rag-pdf-with-langchain.tsx │ ├── stable-video-diffusion.tsx │ ├── stacks │ │ ├── basic-openai │ │ │ └── route.ts │ │ ├── boilerplate-basic │ │ │ └── route.ts │ │ ├── chat-gemini-streaming-langchain │ │ │ └── route.ts │ │ ├── chat-with-gemini-langchain │ │ │ └── route.ts │ │ ├── chat-with-gemini-streaming │ │ │ └── route.ts │ │ ├── chat-with-gemini │ │ │ └── route.ts │ │ ├── chat-with-openai-streaming-helicone │ │ │ └── route.ts │ │ ├── chat-with-openai-streaming-langchain │ │ │ └── route.ts │ │ ├── chat-with-openai-streaming │ │ │ └── route.ts │ │ ├── cover-image-and-subtitle │ │ │ └── route.ts │ │ ├── create-stack-boilerplate │ │ │ ├── create-stack.ts │ │ │ ├── get-file-from-github.ts │ │ │ ├── push-multiple-files-to-branch.ts │ │ │ └── route.ts │ │ ├── elevenlabs-tts │ │ │ └── route.ts │ │ ├── get-image-description-openai │ │ │ └── route.ts │ │ ├── image-sharpener │ │ │ └── route.ts │ │ ├── image-to-music │ │ │ └── route.ts │ │ ├── rag-pdf-with-langchain │ │ │ └── route.ts │ │ ├── stable-video-diffusion │ │ │ └── route.ts │ │ ├── text-to-qr │ │ │ └── route.ts │ │ └── use-openai-assistant │ │ │ └── route.ts │ ├── text-to-qr.tsx │ ├── use-openai-assistant.tsx │ └── utils │ │ ├── actions.ts │ │ ├── getAWSPresignedUrl │ │ └── route.ts │ │ ├── search-stacks.tsx │ │ ├── signIn.tsx │ │ ├── signOut.tsx │ │ └── stack-db.ts ├── stacks_homepage.png └── stackwise_logo.png ├── scripts ├── .gitignore ├── sync-stacks.ts └── tsconfig.json ├── tailwind.config.ts ├── tooling ├── eslint-config │ ├── base.js │ ├── nextjs.js │ ├── package.json │ ├── react.js │ └── tsconfig.json ├── github │ ├── package.json │ └── setup │ │ └── action.yml ├── prettier-config │ ├── index.mjs │ ├── package.json │ └── tsconfig.json ├── tailwind-config │ ├── index.ts │ ├── node_modules │ │ ├── .bin │ │ │ ├── tailwind │ │ │ └── tailwindcss │ │ └── tailwindcss │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── base.css │ │ │ ├── colors.d.ts │ │ │ ├── colors.js │ │ │ ├── components.css │ │ │ ├── defaultConfig.d.ts │ │ │ ├── defaultConfig.js │ │ │ ├── defaultTheme.d.ts │ │ │ ├── defaultTheme.js │ │ │ ├── lib │ │ │ ├── cli-peer-dependencies.js │ │ │ ├── cli.js │ │ │ ├── cli │ │ │ │ ├── build │ │ │ │ │ ├── deps.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── plugin.js │ │ │ │ │ ├── utils.js │ │ │ │ │ └── watching.js │ │ │ │ ├── help │ │ │ │ │ └── index.js │ │ │ │ ├── index.js │ │ │ │ └── init │ │ │ │ │ └── index.js │ │ │ ├── corePluginList.js │ │ │ ├── corePlugins.js │ │ │ ├── css │ │ │ │ ├── LICENSE │ │ │ │ └── preflight.css │ │ │ ├── featureFlags.js │ │ │ ├── index.js │ │ │ ├── lib │ │ │ │ ├── cacheInvalidation.js │ │ │ │ ├── collapseAdjacentRules.js │ │ │ │ ├── collapseDuplicateDeclarations.js │ │ │ │ ├── content.js │ │ │ │ ├── defaultExtractor.js │ │ │ │ ├── detectNesting.js │ │ │ │ ├── evaluateTailwindFunctions.js │ │ │ │ ├── expandApplyAtRules.js │ │ │ │ ├── expandTailwindAtRules.js │ │ │ │ ├── findAtConfigPath.js │ │ │ │ ├── generateRules.js │ │ │ │ ├── getModuleDependencies.js │ │ │ │ ├── load-config.js │ │ │ │ ├── normalizeTailwindDirectives.js │ │ │ │ ├── offsets.js │ │ │ │ ├── partitionApplyAtRules.js │ │ │ │ ├── regex.js │ │ │ │ ├── remap-bitfield.js │ │ │ │ ├── resolveDefaultsAtRules.js │ │ │ │ ├── setupContextUtils.js │ │ │ │ ├── setupTrackingContext.js │ │ │ │ ├── sharedState.js │ │ │ │ └── substituteScreenAtRules.js │ │ │ ├── oxide │ │ │ │ ├── cli.js │ │ │ │ ├── cli │ │ │ │ │ ├── build │ │ │ │ │ │ ├── deps.js │ │ │ │ │ │ ├── index.js │ │ │ │ │ │ ├── plugin.js │ │ │ │ │ │ ├── utils.js │ │ │ │ │ │ └── watching.js │ │ │ │ │ ├── help │ │ │ │ │ │ └── index.js │ │ │ │ │ ├── index.js │ │ │ │ │ └── init │ │ │ │ │ │ └── index.js │ │ │ │ └── postcss-plugin.js │ │ │ ├── plugin.js │ │ │ ├── postcss-plugins │ │ │ │ └── nesting │ │ │ │ │ ├── README.md │ │ │ │ │ ├── index.js │ │ │ │ │ └── plugin.js │ │ │ ├── processTailwindFeatures.js │ │ │ ├── public │ │ │ │ ├── colors.js │ │ │ │ ├── create-plugin.js │ │ │ │ ├── default-config.js │ │ │ │ ├── default-theme.js │ │ │ │ ├── load-config.js │ │ │ │ └── resolve-config.js │ │ │ ├── util │ │ │ │ ├── applyImportantSelector.js │ │ │ │ ├── bigSign.js │ │ │ │ ├── buildMediaQuery.js │ │ │ │ ├── cloneDeep.js │ │ │ │ ├── cloneNodes.js │ │ │ │ ├── color.js │ │ │ │ ├── colorNames.js │ │ │ │ ├── configurePlugins.js │ │ │ │ ├── createPlugin.js │ │ │ │ ├── createUtilityPlugin.js │ │ │ │ ├── dataTypes.js │ │ │ │ ├── defaults.js │ │ │ │ ├── escapeClassName.js │ │ │ │ ├── escapeCommas.js │ │ │ │ ├── flattenColorPalette.js │ │ │ │ ├── formatVariantSelector.js │ │ │ │ ├── getAllConfigs.js │ │ │ │ ├── hashConfig.js │ │ │ │ ├── isKeyframeRule.js │ │ │ │ ├── isPlainObject.js │ │ │ │ ├── isSyntacticallyValidPropertyValue.js │ │ │ │ ├── log.js │ │ │ │ ├── nameClass.js │ │ │ │ ├── negateValue.js │ │ │ │ ├── normalizeConfig.js │ │ │ │ ├── normalizeScreens.js │ │ │ │ ├── parseAnimationValue.js │ │ │ │ ├── parseBoxShadowValue.js │ │ │ │ ├── parseDependency.js │ │ │ │ ├── parseGlob.js │ │ │ │ ├── parseObjectStyles.js │ │ │ │ ├── pluginUtils.js │ │ │ │ ├── prefixSelector.js │ │ │ │ ├── pseudoElements.js │ │ │ │ ├── removeAlphaVariables.js │ │ │ │ ├── resolveConfig.js │ │ │ │ ├── resolveConfigPath.js │ │ │ │ ├── responsive.js │ │ │ │ ├── splitAtTopLevelOnly.js │ │ │ │ ├── tap.js │ │ │ │ ├── toColorValue.js │ │ │ │ ├── toPath.js │ │ │ │ ├── transformThemeValue.js │ │ │ │ ├── validateConfig.js │ │ │ │ ├── validateFormalSyntax.js │ │ │ │ └── withAlphaVariable.js │ │ │ └── value-parser │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── index.d.js │ │ │ │ ├── index.js │ │ │ │ ├── parse.js │ │ │ │ ├── stringify.js │ │ │ │ ├── unit.js │ │ │ │ └── walk.js │ │ │ ├── loadConfig.d.ts │ │ │ ├── loadConfig.js │ │ │ ├── nesting │ │ │ ├── index.d.ts │ │ │ └── index.js │ │ │ ├── package.json │ │ │ ├── peers │ │ │ └── index.js │ │ │ ├── plugin.d.ts │ │ │ ├── plugin.js │ │ │ ├── prettier.config.js │ │ │ ├── resolveConfig.d.ts │ │ │ ├── resolveConfig.js │ │ │ ├── screens.css │ │ │ ├── scripts │ │ │ ├── create-plugin-list.js │ │ │ ├── generate-types.js │ │ │ ├── release-channel.js │ │ │ ├── release-notes.js │ │ │ ├── swap-engines.js │ │ │ └── type-utils.js │ │ │ ├── src │ │ │ ├── cli-peer-dependencies.js │ │ │ ├── cli.js │ │ │ ├── cli │ │ │ │ ├── build │ │ │ │ │ ├── deps.js │ │ │ │ │ ├── index.js │ │ │ │ │ ├── plugin.js │ │ │ │ │ ├── utils.js │ │ │ │ │ └── watching.js │ │ │ │ ├── help │ │ │ │ │ └── index.js │ │ │ │ ├── index.js │ │ │ │ └── init │ │ │ │ │ └── index.js │ │ │ ├── corePluginList.js │ │ │ ├── corePlugins.js │ │ │ ├── css │ │ │ │ ├── LICENSE │ │ │ │ └── preflight.css │ │ │ ├── featureFlags.js │ │ │ ├── index.js │ │ │ ├── lib │ │ │ │ ├── cacheInvalidation.js │ │ │ │ ├── collapseAdjacentRules.js │ │ │ │ ├── collapseDuplicateDeclarations.js │ │ │ │ ├── content.js │ │ │ │ ├── defaultExtractor.js │ │ │ │ ├── detectNesting.js │ │ │ │ ├── evaluateTailwindFunctions.js │ │ │ │ ├── expandApplyAtRules.js │ │ │ │ ├── expandTailwindAtRules.js │ │ │ │ ├── findAtConfigPath.js │ │ │ │ ├── generateRules.js │ │ │ │ ├── getModuleDependencies.js │ │ │ │ ├── load-config.ts │ │ │ │ ├── normalizeTailwindDirectives.js │ │ │ │ ├── offsets.js │ │ │ │ ├── partitionApplyAtRules.js │ │ │ │ ├── regex.js │ │ │ │ ├── remap-bitfield.js │ │ │ │ ├── resolveDefaultsAtRules.js │ │ │ │ ├── setupContextUtils.js │ │ │ │ ├── setupTrackingContext.js │ │ │ │ ├── sharedState.js │ │ │ │ └── substituteScreenAtRules.js │ │ │ ├── oxide │ │ │ │ ├── cli.ts │ │ │ │ ├── cli │ │ │ │ │ ├── build │ │ │ │ │ │ ├── deps.ts │ │ │ │ │ │ ├── index.ts │ │ │ │ │ │ ├── plugin.ts │ │ │ │ │ │ ├── utils.ts │ │ │ │ │ │ └── watching.ts │ │ │ │ │ ├── help │ │ │ │ │ │ └── index.ts │ │ │ │ │ ├── index.ts │ │ │ │ │ └── init │ │ │ │ │ │ └── index.ts │ │ │ │ └── postcss-plugin.ts │ │ │ ├── plugin.js │ │ │ ├── postcss-plugins │ │ │ │ └── nesting │ │ │ │ │ ├── README.md │ │ │ │ │ ├── index.js │ │ │ │ │ └── plugin.js │ │ │ ├── processTailwindFeatures.js │ │ │ ├── public │ │ │ │ ├── colors.js │ │ │ │ ├── create-plugin.js │ │ │ │ ├── default-config.js │ │ │ │ ├── default-theme.js │ │ │ │ ├── load-config.js │ │ │ │ └── resolve-config.js │ │ │ ├── util │ │ │ │ ├── applyImportantSelector.js │ │ │ │ ├── bigSign.js │ │ │ │ ├── buildMediaQuery.js │ │ │ │ ├── cloneDeep.js │ │ │ │ ├── cloneNodes.js │ │ │ │ ├── color.js │ │ │ │ ├── colorNames.js │ │ │ │ ├── configurePlugins.js │ │ │ │ ├── createPlugin.js │ │ │ │ ├── createUtilityPlugin.js │ │ │ │ ├── dataTypes.js │ │ │ │ ├── defaults.js │ │ │ │ ├── escapeClassName.js │ │ │ │ ├── escapeCommas.js │ │ │ │ ├── flattenColorPalette.js │ │ │ │ ├── formatVariantSelector.js │ │ │ │ ├── getAllConfigs.js │ │ │ │ ├── hashConfig.js │ │ │ │ ├── isKeyframeRule.js │ │ │ │ ├── isPlainObject.js │ │ │ │ ├── isSyntacticallyValidPropertyValue.js │ │ │ │ ├── log.js │ │ │ │ ├── nameClass.js │ │ │ │ ├── negateValue.js │ │ │ │ ├── normalizeConfig.js │ │ │ │ ├── normalizeScreens.js │ │ │ │ ├── parseAnimationValue.js │ │ │ │ ├── parseBoxShadowValue.js │ │ │ │ ├── parseDependency.js │ │ │ │ ├── parseGlob.js │ │ │ │ ├── parseObjectStyles.js │ │ │ │ ├── pluginUtils.js │ │ │ │ ├── prefixSelector.js │ │ │ │ ├── pseudoElements.js │ │ │ │ ├── removeAlphaVariables.js │ │ │ │ ├── resolveConfig.js │ │ │ │ ├── resolveConfigPath.js │ │ │ │ ├── responsive.js │ │ │ │ ├── splitAtTopLevelOnly.js │ │ │ │ ├── tap.js │ │ │ │ ├── toColorValue.js │ │ │ │ ├── toPath.js │ │ │ │ ├── transformThemeValue.js │ │ │ │ ├── validateConfig.js │ │ │ │ ├── validateFormalSyntax.js │ │ │ │ └── withAlphaVariable.js │ │ │ └── value-parser │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── index.d.ts │ │ │ │ ├── index.js │ │ │ │ ├── parse.js │ │ │ │ ├── stringify.js │ │ │ │ ├── unit.js │ │ │ │ └── walk.js │ │ │ ├── stubs │ │ │ ├── .npmignore │ │ │ ├── .prettierrc.json │ │ │ ├── config.full.js │ │ │ ├── config.simple.js │ │ │ ├── postcss.config.cjs │ │ │ ├── postcss.config.js │ │ │ ├── tailwind.config.cjs │ │ │ ├── tailwind.config.js │ │ │ └── tailwind.config.ts │ │ │ ├── tailwind.css │ │ │ ├── types │ │ │ ├── config.d.ts │ │ │ ├── generated │ │ │ │ ├── .gitkeep │ │ │ │ ├── colors.d.ts │ │ │ │ ├── corePluginList.d.ts │ │ │ │ └── default-theme.d.ts │ │ │ └── index.d.ts │ │ │ ├── utilities.css │ │ │ └── variants.css │ ├── package.json │ └── tsconfig.json └── tsconfig │ ├── base.json │ └── package.json └── tsconfig.json /.env.example: -------------------------------------------------------------------------------- 1 | # Dependant on what stack you want to run 2 | 3 | OPENAI_API_KEY=sk- 4 | HELICONE_API_KEY=sk- 5 | PINECONE_API_KEY= 6 | PINECONE_ENVIRONMENT= 7 | # SUPABASE_URL= 8 | # SUPABASE_KEY= 9 | GEMINI_API_KEY= -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: TypeScript Build and Test 2 | 3 | on: 4 | push: 5 | branches: [main, "ci-test*"] 6 | pull_request_target: 7 | branches: [main, "ci-test*"] 8 | 9 | jobs: 10 | build: 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - name: Checkout Repository 15 | uses: actions/checkout@v2 16 | 17 | - name: Change to 'stacks' directory 18 | run: cd stacks 19 | 20 | - name: Remove node_modules 21 | run: rm -rf node_modules 22 | 23 | - name: Install System Dependencies 24 | run: | 25 | sudo apt-get update 26 | sudo apt-get install -y build-essential libxtst-dev 27 | 28 | - name: Update Node.js and npm 29 | run: | 30 | npm install -g npm@latest 31 | 32 | - name: Update robotjs 33 | run: | 34 | npm install robotjs@latest 35 | 36 | - name: Setup Node.js 37 | uses: actions/setup-node@v2 38 | with: 39 | node-version: "18" # You can specify your Node.js version here 40 | 41 | - name: Install Dependencies 42 | run: npm install 43 | 44 | - name: Fetch Latest Changes 45 | run: git fetch 46 | 47 | - name: Run Jest on Modified Folder 48 | run: npx jest --onlyChanged 49 | -------------------------------------------------------------------------------- /.github/workflows/pullrequest_validation.yml: -------------------------------------------------------------------------------- 1 | name: Validate Pull Request 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - opened 7 | - synchronize 8 | 9 | jobs: 10 | check-format: 11 | name: Validate Stack PR 12 | 13 | # Only run if the PR branch starts with `stack/` 14 | if: startsWith(github.head_ref, 'stack/') 15 | 16 | runs-on: ubuntu-latest # can also change to: windows-latest || macos-latest 17 | 18 | steps: 19 | - uses: actions/checkout@v4 20 | with: 21 | fetch-depth: 0 # OR "2" -> To retrieve the preceding commit. 22 | 23 | - name: Get all changed files 24 | id: changed-files 25 | uses: tj-actions/changed-files@v40 26 | 27 | - name: List all changed files 28 | run: | 29 | for file in ${{ steps.changed-files.outputs.all_changed_files }}; do 30 | echo "$file was changed" 31 | done 32 | 33 | - name: Fail if unexpected files were changed 34 | run: | 35 | for file in ${{ steps.changed-files.outputs.all_changed_files }}; do 36 | if [[ ! "$file" =~ ^(stacks/[^/]*/index.test.ts|stacks/[^/]*/index.ts|stacks/[^/]*/index.test.txt)$ ]]; then 37 | echo "😡 File '$file' was changed. This is not allowed in a stack Pull Request." 38 | echo "" 39 | echo "You're only allowed to change the following:" 40 | echo " - stacks/*/index.ts" 41 | echo " - stacks/*/index.test.ts" 42 | echo " - stacks/*/index.test.txt" 43 | exit 1 44 | fi 45 | done 46 | 47 | - name: Fail if more than one (1) stack was made 48 | run: | 49 | if ((${{ steps.changed-files.outputs.all_changed_files_count }} > 3)); then 50 | echo "😡 Detected more than 1 stack. Please make only 1 stack per pull request." 51 | exit 1 52 | fi 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | .vscode 6 | /.pnp 7 | .pnp.js 8 | .yarn/install-state.gz 9 | 10 | # testing 11 | /coverage 12 | 13 | # next.js 14 | /.next/ 15 | /out/ 16 | 17 | # production 18 | /build 19 | 20 | # misc 21 | .DS_Store 22 | *.pem 23 | 24 | # debug 25 | npm-debug.log* 26 | yarn-debug.log* 27 | yarn-error.log* 28 | 29 | # local env files 30 | .env*.local 31 | 32 | # vercel 33 | .vercel 34 | 35 | # typescript 36 | *.tsbuildinfo 37 | next-env.d.ts 38 | 39 | .env -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Stackwise, Inc. 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The open source AI app collection. 2 | 3 | [![Discord Follow](https://dcbadge.vercel.app/api/server/KfUxa8h3s6?style=flat)](https://discord.gg/KfUxa8h3s6) 4 | [![Twitter Follow](https://img.shields.io/twitter/follow/stackwiseai?style=social)](https://twitter.com/stackwiseai) 5 | [![GitHub Repo stars](https://img.shields.io/github/stars/stackwiseai/stackwise?style=social)](https://github.com/stackwiseai/stackwise/stargazers) 6 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 7 | 8 | ### [Visit the Stackwise collection](https://stackwise.ai/stacks) 9 | 10 | ![Stackwise stacks collections](public/stacks_homepage.png) 11 | 12 | ### Join The Community 13 | 14 | [![Discord Follow](https://dcbadge.vercel.app/api/server/KfUxa8h3s6?style=flat)](https://discord.gg/KfUxa8h3s6) 15 | 16 | We welcome contributions, feedback, and suggestions to further enhance Stackwise. If you made it here you're at the very least intrigued and we'd love to have you :) 17 | 18 | --- 19 | 20 | This project is licensed under the [MIT License](LICENSE). 21 | -------------------------------------------------------------------------------- /app/api/stacks/basic-openai/route.ts: -------------------------------------------------------------------------------- 1 | import OpenAI from 'openai'; 2 | 3 | const openai = new OpenAI({ 4 | apiKey: process.env.OPENAI_API_KEY, 5 | }); 6 | 7 | export async function POST(req: Request) { 8 | const { messages } = await req.json(); 9 | const response = await openai.chat.completions.create({ 10 | model: 'gpt-3.5-turbo', 11 | messages: [{ role: 'user', content: messages }], 12 | }); 13 | const content = response.choices[0].message.content; 14 | return new Response(JSON.stringify({ content })); 15 | } 16 | -------------------------------------------------------------------------------- /app/api/stacks/boilerplate-basic/route.ts: -------------------------------------------------------------------------------- 1 | export async function POST(req: Request) { 2 | const { input } = await req.json(); 3 | return new Response( 4 | JSON.stringify({ output: `You sent this message to the server: ${input}` }), 5 | ); 6 | } 7 | -------------------------------------------------------------------------------- /app/api/stacks/chat-gemini-streaming-langchain/route.ts: -------------------------------------------------------------------------------- 1 | import { ChatGoogleGenerativeAI } from '@langchain/google-genai'; 2 | 3 | export async function POST(req: Request) { 4 | const chat = new ChatGoogleGenerativeAI(); 5 | const { messages } = await req.json(); 6 | 7 | try { 8 | const textResponse = await chat.invoke([['human', messages]]); 9 | const stream = await chat.stream([ 10 | ['human', 'Tell me a joke about bears.'], 11 | ]); 12 | 13 | for await (const chunk of stream) { 14 | console.log(chunk); 15 | } 16 | const output = textResponse.content; // assuming the text you want is in `content` 17 | 18 | const responseJson = JSON.stringify({ output }); 19 | 20 | return new Response(responseJson, { 21 | headers: { 'Content-Type': 'application/json' }, 22 | }); 23 | } catch (error) { 24 | console.error(error); 25 | return new Response(JSON.stringify({ error: 'An error occurred' }), { 26 | status: 500, 27 | headers: { 'Content-Type': 'application/json' }, 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/api/stacks/chat-with-gemini-langchain/route.ts: -------------------------------------------------------------------------------- 1 | import { ChatGoogleGenerativeAI } from '@langchain/google-genai'; 2 | 3 | export async function POST(req: Request) { 4 | const llm = new ChatGoogleGenerativeAI(); 5 | const { messages } = await req.json(); 6 | 7 | try { 8 | const textResponse = await llm.invoke([['human', messages]]); 9 | const output = textResponse.content; // assuming the text you want is in `content` 10 | 11 | const responseJson = JSON.stringify({ output }); 12 | 13 | return new Response(responseJson, { 14 | headers: { 'Content-Type': 'application/json' }, 15 | }); 16 | } catch (error) { 17 | console.error(error); 18 | return new Response(JSON.stringify({ error: 'An error occurred' }), { 19 | status: 500, 20 | headers: { 'Content-Type': 'application/json' }, 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/api/stacks/chat-with-gemini/route.ts: -------------------------------------------------------------------------------- 1 | import { StreamingTextResponse } from 'ai'; 2 | 3 | export async function POST(req: Request) { 4 | const { GoogleGenerativeAI } = require('@google/generative-ai'); 5 | const { messages } = await req.json(); 6 | 7 | const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY); 8 | const model = genAI.getGenerativeModel({ model: 'gemini-pro' }); 9 | 10 | try { 11 | const result = await model.generateContent(messages); 12 | const response = await result.response; 13 | const text = await response.text(); 14 | return new StreamingTextResponse(text); 15 | } catch (error) { 16 | // Handle the error here 17 | console.error('Error occurred:', error); 18 | return new StreamingTextResponse(error); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/api/stacks/chat-with-openai-streaming-helicone/route.ts: -------------------------------------------------------------------------------- 1 | import { OpenAIStream, StreamingTextResponse } from 'ai'; 2 | import OpenAI from 'openai'; 3 | 4 | const openai = new OpenAI({ 5 | apiKey: process.env.OPENAI_API_KEY, 6 | baseURL: 'https://oai.hconeai.com/v1', 7 | defaultHeaders: { 8 | 'Helicone-Auth': `Bearer ${process.env.HELICONE_API_KEY}`, 9 | }, 10 | }); 11 | export const runtime = 'edge'; 12 | export async function POST(req: Request) { 13 | const { messages } = await req.json(); 14 | const response = await openai.chat.completions.create({ 15 | model: 'gpt-3.5-turbo', 16 | stream: true, 17 | messages: [{ role: 'user', content: messages }], 18 | }); 19 | const stream = OpenAIStream(response); 20 | return new StreamingTextResponse(stream); 21 | } 22 | -------------------------------------------------------------------------------- /app/api/stacks/chat-with-openai-streaming-langchain/route.ts: -------------------------------------------------------------------------------- 1 | import { NextRequest, NextResponse } from "next/server"; 2 | import { Message as VercelChatMessage, StreamingTextResponse } from "ai"; 3 | 4 | import { ChatOpenAI } from "langchain/chat_models/openai"; 5 | import { BytesOutputParser } from "langchain/schema/output_parser"; 6 | import { PromptTemplate } from "langchain/prompts"; 7 | 8 | export const runtime = "edge"; 9 | 10 | const formatMessage = (message: VercelChatMessage) => { 11 | return `${message.role}: ${message.content}`; 12 | }; 13 | 14 | const TEMPLATE = ` 15 | Current conversation: 16 | {chat_history} 17 | 18 | User: {input} 19 | AI:`; 20 | 21 | export async function POST(req: NextRequest) { 22 | try { 23 | const body = await req.json(); 24 | const messages = body.messages ?? []; 25 | const formattedPreviousMessages = messages.slice(0, -1).map(formatMessage); 26 | const currentMessageContent = messages[messages.length - 1].content; 27 | const prompt = PromptTemplate.fromTemplate(TEMPLATE); 28 | 29 | 30 | const model = new ChatOpenAI({ 31 | temperature: 0.8, 32 | }); 33 | 34 | const outputParser = new BytesOutputParser(); 35 | const chain = prompt.pipe(model).pipe(outputParser); 36 | 37 | const stream = await chain.stream({ 38 | chat_history: formattedPreviousMessages.join("\n"), 39 | input: currentMessageContent, 40 | }); 41 | 42 | return new StreamingTextResponse(stream); 43 | } catch (e: any) { 44 | return NextResponse.json({ error: e.message }, { status: 500 }); 45 | } 46 | } -------------------------------------------------------------------------------- /app/api/stacks/chat-with-openai-streaming/route.ts: -------------------------------------------------------------------------------- 1 | import { OpenAIStream, StreamingTextResponse } from 'ai'; 2 | import OpenAI from 'openai'; 3 | 4 | const openai = new OpenAI({ 5 | apiKey: process.env.OPENAI_API_KEY, 6 | }); 7 | export const runtime = 'edge'; 8 | export async function POST(req: Request) { 9 | const { messages } = await req.json(); 10 | const response = await openai.chat.completions.create({ 11 | model: 'gpt-3.5-turbo', 12 | stream: true, 13 | messages: [{ role: 'user', content: messages }], 14 | }); 15 | const stream = OpenAIStream(response); 16 | return new StreamingTextResponse(stream); 17 | } 18 | -------------------------------------------------------------------------------- /app/api/stacks/create-stack-boilerplate/get-file-from-github.ts: -------------------------------------------------------------------------------- 1 | export default async function getFileFromGithub(path, token) { 2 | const owner = 'stackwiseai'; 3 | const repo = 'stackwise'; 4 | const sourceBranch = process.env.VERCEL_GIT_COMMIT_REF ?? ''; // or 'master', depending on your repository 5 | 6 | const url = `https://api.github.com/repos/${owner}/${repo}/contents/${path}?ref=main`; 7 | console.log(url, 'url'); 8 | const response = await fetch(url, { 9 | headers: { 10 | Authorization: `token ${token}`, 11 | }, 12 | }); 13 | return response.json(); 14 | } 15 | -------------------------------------------------------------------------------- /app/api/stacks/create-stack-boilerplate/route.ts: -------------------------------------------------------------------------------- 1 | import { Octokit } from '@octokit/rest'; 2 | 3 | import createStack from './create-stack'; 4 | 5 | const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN }); 6 | 7 | const vercelToken = process.env.VERCEL_TOKEN; 8 | const teamId = process.env.TEAM_ID; 9 | const repoId = process.env.REPO_ID; 10 | 11 | const owner = 'stackwiseai'; 12 | const repo = 'stackwise'; 13 | const sourceBranch = process.env.VERCEL_GIT_COMMIT_REF ?? ''; // or 'master', depending on your repository 14 | export const fetchCache = 'force-no-store'; // TODO: remove this line to enable caching but without making the app completely static 15 | export const revalidate = 0; 16 | export async function POST(req: Request) { 17 | const data = await req.json(); 18 | // get the token from header and strip the Bearer 19 | try { 20 | if (req.headers) { 21 | const header = req.headers.get('Authorization'); 22 | if (header) { 23 | const token = header.split(' ')[1]; 24 | const prLink = await createStack(data, token); 25 | return new Response(JSON.stringify({prLink}), { 26 | status: 200, 27 | headers: { 28 | 'Content-Type': 'application/json', 29 | }, 30 | }); 31 | } else { 32 | throw new Error('No token provided'); 33 | 34 | }} else { 35 | throw new Error('No headers provided'); 36 | } 37 | } catch (error) { 38 | console.error('Error during data insertion:', error); 39 | return new Response(JSON.stringify({ message: error.message }), { 40 | status: 500, 41 | headers: { 42 | 'Content-Type': 'application/json', 43 | }, 44 | }); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/api/stacks/get-image-description-openai/route.ts: -------------------------------------------------------------------------------- 1 | import { OpenAIStream, StreamingTextResponse } from 'ai'; 2 | import OpenAI from 'openai'; 3 | 4 | // Create an OpenAI API client (that's edge friendly!) 5 | const openai = new OpenAI({ 6 | apiKey: process.env.OPENAI_API_KEY || '', 7 | }); 8 | 9 | // IMPORTANT! Set the runtime to edge 10 | export const runtime = 'edge'; 11 | 12 | export async function POST(req: Request) { 13 | // 'data' contains the additional data that you have sent: 14 | const { messages, data } = await req.json(); 15 | 16 | const initialMessages = messages.slice(0, -1); 17 | const currentMessage = messages[messages.length - 1]; 18 | 19 | // Ask OpenAI for a streaming chat completion given the prompt 20 | const response = await openai.chat.completions.create({ 21 | model: 'gpt-4-vision-preview', 22 | stream: true, 23 | max_tokens: 150, 24 | messages: [ 25 | ...initialMessages, 26 | { 27 | ...currentMessage, 28 | content: [ 29 | { type: 'text', text: currentMessage.content }, 30 | 31 | // forward the image information to OpenAI: 32 | { 33 | type: 'image_url', 34 | image_url: data.imageUrl, 35 | }, 36 | ], 37 | }, 38 | ], 39 | }); 40 | 41 | // Convert the response into a friendly text-stream 42 | const stream = OpenAIStream(response); 43 | // Respond with the stream 44 | return new StreamingTextResponse(stream); 45 | } 46 | -------------------------------------------------------------------------------- /app/api/stacks/image-sharpener/route.ts: -------------------------------------------------------------------------------- 1 | import Replicate from 'replicate'; 2 | 3 | const replicate = new Replicate({ 4 | auth: process.env.REPLICATE_API_TOKEN!, 5 | }); 6 | 7 | export const maxDuration = 300; 8 | 9 | export async function POST(request: Request) { 10 | const form = await request.formData(); 11 | const imgFile = form.get('img') as Blob; 12 | const imgBuffer = Buffer.from(await imgFile.arrayBuffer()); 13 | const imgBase64 = imgBuffer.toString('base64'); 14 | const imgUri = `data:${imgFile.type};base64,${imgBase64}`; 15 | 16 | try { 17 | const esrganVersion = 18 | 'nightmareai/real-esrgan:42fed1c4974146d4d2414e2be2c5277c7fcf05fcc3a73abf41610695738c1d7b'; 19 | const esrgan = await replicate.run(esrganVersion, { 20 | input: { 21 | image: imgUri, 22 | face_enhance: true, 23 | }, 24 | }); 25 | 26 | return new Response(JSON.stringify(esrgan), { 27 | status: 200, 28 | headers: { 'Content-Type': 'application/json' }, 29 | }); 30 | } catch (error) { 31 | console.log(error); 32 | return new Response(JSON.stringify({ error }), { 33 | status: 500, 34 | }); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/api/stacks/stable-video-diffusion/route.ts: -------------------------------------------------------------------------------- 1 | import * as fal from '@fal-ai/serverless-client'; 2 | 3 | fal.config({ 4 | credentials: `${process.env.FAL_KEY_ID}:${process.env.FAL_KEY_SECRET}`, 5 | }); 6 | 7 | export const maxDuration = 300; 8 | 9 | export async function POST(request: Request) { 10 | let resp = null; 11 | 12 | const form = await request.formData(); 13 | const imgFile = form.get('img') as Blob; 14 | const maskFile = form.get('mask') as Blob; 15 | const degreeOfMotion = form.get('degreeOfMotion') as string; 16 | 17 | const imgBuffer = Buffer.from(await imgFile.arrayBuffer()); 18 | const maskBuffer = Buffer.from(await maskFile.arrayBuffer()); 19 | 20 | const imgBase64 = imgBuffer.toString('base64'); 21 | const maskBase64 = maskBuffer.toString('base64'); 22 | 23 | // Generate a full URI 24 | const imgUri = `data:${imgFile.type};base64,${imgBase64}`; 25 | const maskUri = `data:${maskFile.type};base64,${maskBase64}`; 26 | 27 | const payload = { 28 | subscriptionId: '110602490-svd', 29 | input: { 30 | image_url: imgUri, 31 | mask_image_url: maskUri, 32 | motion_bucket_id: Number(degreeOfMotion), 33 | cond_aug: 0.02, 34 | steps: 100, 35 | }, 36 | pollInterval: 500, 37 | logs: true, 38 | }; 39 | 40 | try { 41 | const result: any = await fal.subscribe(payload.subscriptionId, payload); 42 | 43 | resp = result; 44 | } catch (error) { 45 | console.log(error); 46 | return new Response(JSON.stringify({ error }), { 47 | status: 500, 48 | }); 49 | } 50 | 51 | return new Response(JSON.stringify(resp), { 52 | status: 200, 53 | headers: { 'Content-Type': 'application/json' }, 54 | }); 55 | } 56 | -------------------------------------------------------------------------------- /app/api/stacks/text-to-qr/route.ts: -------------------------------------------------------------------------------- 1 | import Replicate from 'replicate'; 2 | 3 | const replicate = new Replicate({ 4 | auth: process.env.REPLICATE_API_TOKEN!, 5 | }); 6 | 7 | export const maxDuration = 300; 8 | 9 | export async function POST(req: Request) { 10 | const { qrPrompt, url } = await req.json(); 11 | 12 | try { 13 | const controlNetVersion = 14 | 'zylim0702/qr_code_controlnet:628e604e13cf63d8ec58bd4d238474e8986b054bc5e1326e50995fdbc851c557'; 15 | const qrCode = await replicate.run(controlNetVersion, { 16 | input: { 17 | url: url, 18 | prompt: qrPrompt, 19 | qr_conditioning_scale: 1.3, 20 | }, 21 | }); 22 | 23 | return new Response( 24 | JSON.stringify({ 25 | img: qrCode, 26 | }), 27 | { 28 | status: 200, 29 | headers: { 'Content-Type': 'application/json' }, 30 | }, 31 | ); 32 | } catch (error) { 33 | console.log(error); 34 | return new Response(JSON.stringify({ error }), { 35 | status: 500, 36 | }); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/api/utils/getAWSPresignedUrl/route.ts: -------------------------------------------------------------------------------- 1 | import AWS from 'aws-sdk'; 2 | 3 | AWS.config.update({ 4 | region: process.env.AWS_REGION, 5 | accessKeyId: process.env.AWS_ACCESS_KEY_ID, 6 | secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, 7 | }); 8 | 9 | export async function POST(req: Request) { 10 | try { 11 | const body = await req.json(); 12 | const s3 = new AWS.S3(); 13 | const { fileName, fileType } = body; 14 | const params = { 15 | Bucket: 'cover-image-and-subtitle-stack', 16 | Key: fileName, 17 | Expires: 60, // URL expiration time in seconds 18 | ContentType: fileType, 19 | }; 20 | 21 | try { 22 | const presignedUrl = await s3.getSignedUrlPromise('putObject', params); 23 | return new Response(JSON.stringify({ url: presignedUrl }), { 24 | status: 200, 25 | }); 26 | } catch (error) { 27 | return new Response( 28 | JSON.stringify({ error: 'Error creating presigned URL' }), 29 | { status: 500 }, 30 | ); 31 | } 32 | } catch (error) { 33 | return new Response(JSON.stringify({ error: 'Bad Request' }), { 34 | status: 400, 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/components/shared/ContactButton.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { useState } from 'react'; 4 | import tw from 'tailwind-styled-components'; 5 | 6 | const glowingShadowStyle = { 7 | boxShadow: `0 0 10px rgba(0, 0, 0, 0.6), 8 | 0 0 20px rgba(0, 0, 0, 0.4), 9 | 0 0 30px rgba(0, 0, 0, 0.2)`, 10 | }; 11 | 12 | const glowingShadowHoverStyle = { 13 | boxShadow: `0 0 10px rgba(0, 0, 0, 0.7), 14 | 0 0 20px rgba(0, 0, 0, 0.5), 15 | 0 0 30px rgba(0, 0, 0, 0.3), 16 | 0 0 40px rgba(0, 0, 0, 0.1)`, 17 | }; 18 | 19 | const ContactButton: React.FC = () => { 20 | const [isHovered, setIsHovered] = useState(false); 21 | 22 | return ( 23 | 30 | ); 31 | }; 32 | 33 | export default ContactButton; 34 | 35 | const Button = tw.button` 36 | bg-black 37 | text-white 38 | font-bold 39 | py-2 40 | px-4 41 | rounded-full 42 | absolute 43 | top-4 44 | right-4 45 | transition duration-300 ease-in-out 46 | `; 47 | -------------------------------------------------------------------------------- /app/components/shared/clipboard.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import React, { useState } from 'react'; 4 | import { FaCheckCircle, FaClipboard } from 'react-icons/fa'; // Importing icons 5 | 6 | interface ClipboardComponentProps { 7 | code: string; 8 | title?: any; 9 | } 10 | 11 | const ClipboardComponent: React.FC = ({ 12 | code, 13 | title, 14 | }) => { 15 | const [icon, setIcon] = useState(); // Clipboard icon in black 16 | 17 | const handleClick = async () => { 18 | try { 19 | await navigator.clipboard.writeText(code); 20 | console.log('Text copied to clipboard'); 21 | setIcon(); 22 | setTimeout(() => { 23 | setIcon(); 24 | }, 3000); 25 | } catch (err) { 26 | console.error('Failed to copy: ', err); 27 | } 28 | }; 29 | 30 | return ( 31 | 38 | ); 39 | }; 40 | 41 | export default ClipboardComponent; 42 | -------------------------------------------------------------------------------- /app/components/stacks/creation/Inputs.tsx: -------------------------------------------------------------------------------- 1 | import parse from 'html-react-parser'; 2 | import tw from 'tailwind-styled-components'; 3 | 4 | interface InputsProps { 5 | formAction: (payload: FormData) => void; 6 | state: string; 7 | } 8 | 9 | const Inputs: React.FC = ({ formAction, state }) => { 10 | return ( 11 |
12 | {parse(state)} 13 | 14 |
15 | ); 16 | }; 17 | 18 | export default Inputs; 19 | 20 | const Form = tw.form` 21 | flex 22 | flex-col 23 | space-y-2 24 | w-1/2 25 | `; 26 | -------------------------------------------------------------------------------- /app/components/stacks/creation/content.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { useState } from 'react'; 4 | import { useFormState } from 'react-dom'; 5 | import tw from 'tailwind-styled-components'; 6 | 7 | import { callStack, parseFormData } from '../utils/actions'; 8 | import InputWithButton from './input-with-button'; 9 | import Inputs from './Inputs'; 10 | import Outputs from './outputs'; 11 | 12 | const Content = ({ stackDB }) => { 13 | const [outputState, functionAction] = useFormState(parseFormData, null); 14 | const [stackIO, createStack] = useFormState(callStack, { 15 | input: '', 16 | output: '', 17 | }); 18 | const [brief, setBrief] = useState(''); 19 | 20 | return ( 21 | <> 22 | 27 | {brief ? `"${brief}"` : ''} 28 | 29 | {stackIO.input && ( 30 | <> 31 | 35 | 39 | 40 | )} 41 | 42 | {stackIO.input && Deploy} 43 | 44 | ); 45 | }; 46 | 47 | const Brief = tw.div` 48 | font-bold 49 | text-lg 50 | mb-2 51 | h-8 52 | `; 53 | 54 | const Container = tw.div` 55 | flex 56 | justify-center 57 | items-center 58 | w-2/3 59 | space-x-6 60 | `; 61 | 62 | const DeployButton = tw.button` 63 | text-white 64 | bg-black 65 | font-bold 66 | py-3 67 | px-6 68 | rounded 69 | mt-4 70 | `; 71 | 72 | export default Content; 73 | -------------------------------------------------------------------------------- /app/components/stacks/creation/main-content.tsx: -------------------------------------------------------------------------------- 1 | 'use server'; 2 | 3 | import tw from 'tailwind-styled-components'; 4 | 5 | import Content from './content'; 6 | 7 | export default async function MainContent({ stackDB }) { 8 | return ( 9 | 10 | 11 |
12 | 13 |
14 | The open source AI app collection. 15 |
16 | 17 | 18 | 19 |
20 | ); 21 | } 22 | 23 | const Container = tw.div` 24 | flex 25 | flex-col 26 | justify-end 27 | //pt-60 28 | pt-24 29 | pb-5 30 | //pb-10 31 | `; 32 | 33 | const TitleContainer = tw.div` 34 | text-center 35 | `; 36 | 37 | const Subtitle = tw.p` 38 | text-lg 39 | `; 40 | 41 | const MainWrapper = tw.div` 42 | w-full 43 | flex 44 | flex-col 45 | justify-center 46 | items-center 47 | `; 48 | -------------------------------------------------------------------------------- /app/components/stacks/creation/outputs.tsx: -------------------------------------------------------------------------------- 1 | import tw from 'tailwind-styled-components'; 2 | 3 | interface InputsProps { 4 | state: string; 5 | value: any; 6 | } 7 | 8 | const Inputs: React.FC = ({ state, value }) => { 9 | const renderContent = () => { 10 | // Split the string by your placeholder pattern 11 | const parts = state.split(/({[^}]+})/).filter(Boolean); 12 | 13 | return parts.map((part, index) => { 14 | if (part.startsWith('{') && part.endsWith('}')) { 15 | // Extract and evaluate the expression 16 | const expression = part.slice(1, -1); 17 | 18 | // Check if the expression is trying to access a property of 'value' 19 | if (expression.startsWith('value.')) { 20 | const property = expression.slice(6); 21 | 22 | // Check if 'value' is an object and the property is not null/undefined 23 | if (value && typeof value === 'object' && value[property] != null) { 24 | return value[property].toString(); 25 | } 26 | return ''; // Return an empty string if the property is null/undefined 27 | } 28 | 29 | // Handle the direct 'value' expression 30 | if (expression === 'value') { 31 | return value != null ? value.toString() : ''; 32 | } 33 | 34 | return ''; // If the expression cannot be evaluated, return an empty string 35 | } else { 36 | // If part is not an expression, return it as is 37 | return part; 38 | } 39 | }); 40 | }; 41 | 42 | return ( 43 | 44 |
45 | 46 | ); 47 | }; 48 | 49 | export default Inputs; 50 | 51 | const Outputs = tw.form` 52 | w-1/2 53 | flex 54 | justify-center 55 | items-center 56 | `; 57 | -------------------------------------------------------------------------------- /app/components/stacks/utils/actions.ts: -------------------------------------------------------------------------------- 1 | 'use server'; 2 | 3 | const MAILCHIMP_URL = 4 | 'https://us17.api.mailchimp.com/3.0/lists/77b1abf780/members/'; 5 | const MAILCHIMP_API_KEY = process.env.MAILCHIMP_API_KEY; 6 | 7 | export const subscribeEmail = async (prevState, formData) => { 8 | console.log(prevState, formData); 9 | const email = formData.get('email') as string; 10 | 11 | const data = { 12 | email_address: email, 13 | status: 'subscribed', // or 'pending' for double opt-in 14 | }; 15 | 16 | try { 17 | const response = await fetch(MAILCHIMP_URL, { 18 | method: 'POST', 19 | headers: { 20 | Authorization: `Basic ${btoa(`anystring:${MAILCHIMP_API_KEY}`)}`, 21 | 'Content-Type': 'application/json', 22 | }, 23 | body: JSON.stringify(data), 24 | }); 25 | if (response.ok) { 26 | console.log('Subscription successful'); 27 | return { status: 'success' }; 28 | } else { 29 | const errorData = await response.json(); 30 | console.error('Subscription error:', errorData); 31 | return { status: 'error', error: errorData }; 32 | } 33 | } catch (error) { 34 | console.error('Error:', error); 35 | } 36 | }; 37 | 38 | // import { stack } from 'stackwise'; 39 | 40 | export const callStack = async (prevState: any, formData: FormData) => { 41 | const userRequest = formData.get('stack') as string; 42 | // const message = await stack(userRequest); 43 | const message = 'remove'; 44 | 45 | return message; 46 | }; 47 | 48 | export const parseFormData = async (prevState: any, formData: FormData) => { 49 | const num1 = Number(formData.get('num1')); 50 | const num2 = Number(formData.get('num2')); 51 | 52 | return await multiplyNumbers(num1, num2); 53 | }; 54 | 55 | /** 56 | * Brief: Multiply two numbers together 57 | */ 58 | async function multiplyNumbers(num1: number, num2: number): Promise { 59 | return num1 * num2; 60 | } 61 | -------------------------------------------------------------------------------- /app/components/stacks/utils/signIn.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { supabaseClient } from './stack-db'; 4 | 5 | export default function signIn() { 6 | const baseUrl = 7 | process.env.NODE_ENV === 'production' 8 | ? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}` // Use Vercel's environment variable in production 9 | : 'http://localhost:3000'; // Default to localhost in development 10 | 11 | async function signInWithGithub() { 12 | const { data, error } = await supabaseClient.auth.signInWithOAuth({ 13 | provider: 'github', 14 | options: { 15 | scopes: 'public_repo', 16 | redirectTo: `${baseUrl}/stacks/create-stack-boilerplate`, 17 | }, 18 | }); 19 | } 20 | return ( 21 | 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /app/components/stacks/utils/signOut.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { supabaseClient } from "./stack-db"; 4 | 5 | 6 | 7 | export default function signOut() { 8 | async function signOut() { 9 | 10 | const { error } = await supabaseClient.auth.signOut() 11 | } 12 | return ; 13 | } 14 | 15 | -------------------------------------------------------------------------------- /app/components/stacks/utils/stack-db.ts: -------------------------------------------------------------------------------- 1 | import { createBrowserClient } from '@supabase/ssr'; 2 | import { createClient } from '@supabase/supabase-js'; 3 | 4 | type Status = 'published' | 'starred' | 'expansion'; 5 | export const supabaseClient = createBrowserClient( 6 | process.env.NEXT_PUBLIC_SUPABASE_URL!, 7 | process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY! 8 | ) 9 | export async function getSupabaseClient() { 10 | return createClient( 11 | process.env.NEXT_PUBLIC_SUPABASE_URL || '', 12 | process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || '', 13 | ); 14 | } 15 | 16 | export async function getStackDB() { 17 | const supabase = createClient( 18 | process.env.NEXT_PUBLIC_SUPABASE_URL || '', 19 | process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || '', 20 | ); 21 | const { data: projectsArray, error } = await supabase 22 | .from('stack') // Replace with your actual table name 23 | .select('*'); 24 | 25 | if (error) { 26 | console.error('Error fetching data:', error); 27 | return null; 28 | } 29 | 30 | const projectsObject: Record = {}; 31 | if (projectsArray) { 32 | projectsArray.forEach((project) => { 33 | projectsObject[project.id] = { 34 | name: project.name, 35 | description: project.description, 36 | tags: project.tags, 37 | }; 38 | }); 39 | } 40 | 41 | return projectsObject; 42 | } 43 | 44 | export interface StackDescription { 45 | name: string; 46 | description: string; 47 | tags: Status[]; 48 | } 49 | 50 | export const statusesToDisplay: Status[] = ['published']; 51 | -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/app/favicon.ico -------------------------------------------------------------------------------- /app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | .common-styled input { 6 | @apply w-full 7 | rounded-md 8 | border 9 | border-gray-300 10 | p-3 11 | transition 12 | duration-200 13 | focus:border-blue-500 14 | focus:outline-none; 15 | } 16 | 17 | .common-styled button, 18 | .common-styled [type='button'], 19 | .common-styled [type='reset'], 20 | .common-styled [type='submit'] { 21 | @apply rounded 22 | bg-blue-500 23 | px-4 24 | py-3 25 | font-bold 26 | text-white 27 | hover:bg-blue-700 28 | disabled:bg-slate-500; 29 | } 30 | -------------------------------------------------------------------------------- /app/layout.tsx: -------------------------------------------------------------------------------- 1 | import type { Metadata } from 'next'; 2 | import { Mulish } from 'next/font/google'; 3 | import { Analytics } from '@vercel/analytics/react'; 4 | 5 | import './globals.css'; 6 | 7 | const inter = Mulish({ subsets: ['latin'] }); 8 | 9 | export const metadata: Metadata = { 10 | title: 'Stackwise UI', 11 | description: 'Explain what you want to do you, and AI builds it.', 12 | }; 13 | 14 | export default function RootLayout({ 15 | children, 16 | }: { 17 | children: React.ReactNode; 18 | }) { 19 | return ( 20 | 21 | 22 | {children} 23 | 24 | 25 | ); 26 | } 27 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | 3 | const nextConfig = { 4 | async redirects() { 5 | return [ 6 | { 7 | source: '/', 8 | destination: 'https://github.com/stackwiseai/stackwise', 9 | permanent: true, 10 | }, 11 | { 12 | source: '/stack', 13 | destination: '/stacks', 14 | permanent: true, 15 | }, 16 | // these are the old uuid-slugged links which were published 17 | // these redirects keep the old links working and we can still use the new slugs 18 | { 19 | source: '/stacks/gbkm2sk', 20 | destination: '/stacks/chat-with-openai-streaming', 21 | permanent: true, 22 | }, 23 | { 24 | source: '/stacks/aekmwsk', 25 | destination: '/stacks/elevenlabs-tts', 26 | permanent: true, 27 | }, 28 | { 29 | source: '/stacks/fedcba5', 30 | destination: '/stacks/get-image-description-openai', 31 | permanent: true, 32 | }, 33 | { 34 | source: '/stacks/abc1234', 35 | destination: '/stacks/use-openai-assistant', 36 | permanent: true, 37 | }, 38 | { 39 | source: '/stacks/blkfsSK', 40 | destination: '/stacks/create-ai-canvas', 41 | permanent: true, 42 | }, 43 | { 44 | source: '/stacks/ayqflsq', 45 | destination: '/stacks/chat-with-openai-streaming-helicone', 46 | permanent: true, 47 | }, 48 | { 49 | source: '/stacks/e4w5wrc', 50 | destination: '/stacks/stable-video-diffusion', 51 | permanent: true, 52 | }, 53 | { 54 | source: '/stacks/f2w5orq', 55 | destination: '/stacks/basic-gemini-vision', 56 | permanent: true, 57 | }, 58 | ]; 59 | }, 60 | }; 61 | 62 | module.exports = nextConfig; 63 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /public/apocalyptic_car.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/apocalyptic_car.png -------------------------------------------------------------------------------- /public/boat_example.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/boat_example.webp -------------------------------------------------------------------------------- /public/caesar.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/caesar.jpeg -------------------------------------------------------------------------------- /public/next.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/placeholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/placeholder.png -------------------------------------------------------------------------------- /public/stack-pictures/boilerplate-basic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/boilerplate-basic.png -------------------------------------------------------------------------------- /public/stack-pictures/chat-gemini-streaming-langchain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/chat-gemini-streaming-langchain.png -------------------------------------------------------------------------------- /public/stack-pictures/chat-with-gemini-langchain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/chat-with-gemini-langchain.png -------------------------------------------------------------------------------- /public/stack-pictures/chat-with-gemini-streaming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/chat-with-gemini-streaming.png -------------------------------------------------------------------------------- /public/stack-pictures/chat-with-gemini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/chat-with-gemini.png -------------------------------------------------------------------------------- /public/stack-pictures/chat-with-openai-streaming-helicone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/chat-with-openai-streaming-helicone.png -------------------------------------------------------------------------------- /public/stack-pictures/chat-with-openai-streaming-langchain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/chat-with-openai-streaming-langchain.png -------------------------------------------------------------------------------- /public/stack-pictures/chat-with-openai-streaming.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/chat-with-openai-streaming.png -------------------------------------------------------------------------------- /public/stack-pictures/cover-image-and-subtitle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/cover-image-and-subtitle.png -------------------------------------------------------------------------------- /public/stack-pictures/create-ai-canvas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/create-ai-canvas.png -------------------------------------------------------------------------------- /public/stack-pictures/create-stack-boilerplate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/create-stack-boilerplate.png -------------------------------------------------------------------------------- /public/stack-pictures/elevenlabs-tts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/elevenlabs-tts.png -------------------------------------------------------------------------------- /public/stack-pictures/generate-a-cover-image-and-subtitle-on-uploading-a-video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/generate-a-cover-image-and-subtitle-on-uploading-a-video.png -------------------------------------------------------------------------------- /public/stack-pictures/get-image-description-openai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/get-image-description-openai.png -------------------------------------------------------------------------------- /public/stack-pictures/image-sharpener.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/image-sharpener.png -------------------------------------------------------------------------------- /public/stack-pictures/image-to-music.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/image-to-music.png -------------------------------------------------------------------------------- /public/stack-pictures/instant-video-to-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/instant-video-to-image.png -------------------------------------------------------------------------------- /public/stack-pictures/rag-pdf-with-langchain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/rag-pdf-with-langchain.png -------------------------------------------------------------------------------- /public/stack-pictures/stable-video-diffusion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/stable-video-diffusion.png -------------------------------------------------------------------------------- /public/stack-pictures/stack-example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/stack-example.png -------------------------------------------------------------------------------- /public/stack-pictures/stackwise-onboarding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/stackwise-onboarding.png -------------------------------------------------------------------------------- /public/stack-pictures/text-to-qr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/text-to-qr.png -------------------------------------------------------------------------------- /public/stack-pictures/use-openai-assistant.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stack-pictures/use-openai-assistant.png -------------------------------------------------------------------------------- /public/stacks/creation/Inputs.tsx: -------------------------------------------------------------------------------- 1 | import parse from 'html-react-parser'; 2 | import tw from 'tailwind-styled-components'; 3 | 4 | interface InputsProps { 5 | formAction: (payload: FormData) => void; 6 | state: string; 7 | } 8 | 9 | const Inputs: React.FC = ({ formAction, state }) => { 10 | return ( 11 |
12 | {parse(state)} 13 | 14 |
15 | ); 16 | }; 17 | 18 | export default Inputs; 19 | 20 | const Form = tw.form` 21 | flex 22 | flex-col 23 | space-y-2 24 | w-1/2 25 | `; 26 | -------------------------------------------------------------------------------- /public/stacks/creation/content.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { useState } from 'react'; 4 | import { useFormState } from 'react-dom'; 5 | import tw from 'tailwind-styled-components'; 6 | 7 | import { callStack, parseFormData } from '../utils/actions'; 8 | import InputWithButton from './input-with-button'; 9 | import Inputs from './Inputs'; 10 | import Outputs from './outputs'; 11 | 12 | const Content = ({ stackDB }) => { 13 | const [outputState, functionAction] = useFormState(parseFormData, null); 14 | const [stackIO, createStack] = useFormState(callStack, { 15 | input: '', 16 | output: '', 17 | }); 18 | const [brief, setBrief] = useState(''); 19 | 20 | return ( 21 | <> 22 | 27 | {brief ? `"${brief}"` : ''} 28 | 29 | {stackIO.input && ( 30 | <> 31 | 35 | 39 | 40 | )} 41 | 42 | {stackIO.input && Deploy} 43 | 44 | ); 45 | }; 46 | 47 | const Brief = tw.div` 48 | font-bold 49 | text-lg 50 | mb-2 51 | h-8 52 | `; 53 | 54 | const Container = tw.div` 55 | flex 56 | justify-center 57 | items-center 58 | w-2/3 59 | space-x-6 60 | `; 61 | 62 | const DeployButton = tw.button` 63 | text-white 64 | bg-black 65 | font-bold 66 | py-3 67 | px-6 68 | rounded 69 | mt-4 70 | `; 71 | 72 | export default Content; 73 | -------------------------------------------------------------------------------- /public/stacks/creation/main-content.tsx: -------------------------------------------------------------------------------- 1 | 'use server'; 2 | 3 | import tw from 'tailwind-styled-components'; 4 | 5 | import Content from './content'; 6 | 7 | export default async function MainContent({ stackDB }) { 8 | return ( 9 | 10 | 11 |
12 | 13 |
14 | The open source AI app collection. 15 |
16 | 17 | 18 | 19 |
20 | ); 21 | } 22 | 23 | const Container = tw.div` 24 | flex 25 | flex-col 26 | justify-end 27 | //pt-60 28 | pt-24 29 | pb-5 30 | //pb-10 31 | `; 32 | 33 | const TitleContainer = tw.div` 34 | text-center 35 | `; 36 | 37 | const Subtitle = tw.p` 38 | text-lg 39 | `; 40 | 41 | const MainWrapper = tw.div` 42 | w-full 43 | flex 44 | flex-col 45 | justify-center 46 | items-center 47 | `; 48 | -------------------------------------------------------------------------------- /public/stacks/creation/outputs.tsx: -------------------------------------------------------------------------------- 1 | import tw from 'tailwind-styled-components'; 2 | 3 | interface InputsProps { 4 | state: string; 5 | value: any; 6 | } 7 | 8 | const Inputs: React.FC = ({ state, value }) => { 9 | const renderContent = () => { 10 | // Split the string by your placeholder pattern 11 | const parts = state.split(/({[^}]+})/).filter(Boolean); 12 | 13 | return parts.map((part, index) => { 14 | if (part.startsWith('{') && part.endsWith('}')) { 15 | // Extract and evaluate the expression 16 | const expression = part.slice(1, -1); 17 | 18 | // Check if the expression is trying to access a property of 'value' 19 | if (expression.startsWith('value.')) { 20 | const property = expression.slice(6); 21 | 22 | // Check if 'value' is an object and the property is not null/undefined 23 | if (value && typeof value === 'object' && value[property] != null) { 24 | return value[property].toString(); 25 | } 26 | return ''; // Return an empty string if the property is null/undefined 27 | } 28 | 29 | // Handle the direct 'value' expression 30 | if (expression === 'value') { 31 | return value != null ? value.toString() : ''; 32 | } 33 | 34 | return ''; // If the expression cannot be evaluated, return an empty string 35 | } else { 36 | // If part is not an expression, return it as is 37 | return part; 38 | } 39 | }); 40 | }; 41 | 42 | return ( 43 | 44 |
45 | 46 | ); 47 | }; 48 | 49 | export default Inputs; 50 | 51 | const Outputs = tw.form` 52 | w-1/2 53 | flex 54 | justify-center 55 | items-center 56 | `; 57 | -------------------------------------------------------------------------------- /public/stacks/stacks/basic-openai/route.ts: -------------------------------------------------------------------------------- 1 | import OpenAI from 'openai'; 2 | 3 | const openai = new OpenAI({ 4 | apiKey: process.env.OPENAI_API_KEY, 5 | }); 6 | 7 | export async function POST(req: Request) { 8 | const { messages } = await req.json(); 9 | const response = await openai.chat.completions.create({ 10 | model: 'gpt-3.5-turbo', 11 | messages: [{ role: 'user', content: messages }], 12 | }); 13 | const content = response.choices[0].message.content; 14 | return new Response(JSON.stringify({ content })); 15 | } 16 | -------------------------------------------------------------------------------- /public/stacks/stacks/boilerplate-basic/route.ts: -------------------------------------------------------------------------------- 1 | export async function POST(req: Request) { 2 | const { input } = await req.json(); 3 | return new Response( 4 | JSON.stringify({ output: `You sent this message to the server: ${input}` }), 5 | ); 6 | } 7 | -------------------------------------------------------------------------------- /public/stacks/stacks/chat-gemini-streaming-langchain/route.ts: -------------------------------------------------------------------------------- 1 | import { ChatGoogleGenerativeAI } from '@langchain/google-genai'; 2 | 3 | export async function POST(req: Request) { 4 | const chat = new ChatGoogleGenerativeAI(); 5 | const { messages } = await req.json(); 6 | 7 | try { 8 | const textResponse = await chat.invoke([['human', messages]]); 9 | const stream = await chat.stream([ 10 | ['human', 'Tell me a joke about bears.'], 11 | ]); 12 | 13 | for await (const chunk of stream) { 14 | console.log(chunk); 15 | } 16 | const output = textResponse.content; // assuming the text you want is in `content` 17 | 18 | const responseJson = JSON.stringify({ output }); 19 | 20 | return new Response(responseJson, { 21 | headers: { 'Content-Type': 'application/json' }, 22 | }); 23 | } catch (error) { 24 | console.error(error); 25 | return new Response(JSON.stringify({ error: 'An error occurred' }), { 26 | status: 500, 27 | headers: { 'Content-Type': 'application/json' }, 28 | }); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /public/stacks/stacks/chat-with-gemini-langchain/route.ts: -------------------------------------------------------------------------------- 1 | import { ChatGoogleGenerativeAI } from '@langchain/google-genai'; 2 | 3 | export async function POST(req: Request) { 4 | const llm = new ChatGoogleGenerativeAI(); 5 | const { messages } = await req.json(); 6 | 7 | try { 8 | const textResponse = await llm.invoke([['human', messages]]); 9 | const output = textResponse.content; // assuming the text you want is in `content` 10 | 11 | const responseJson = JSON.stringify({ output }); 12 | 13 | return new Response(responseJson, { 14 | headers: { 'Content-Type': 'application/json' }, 15 | }); 16 | } catch (error) { 17 | console.error(error); 18 | return new Response(JSON.stringify({ error: 'An error occurred' }), { 19 | status: 500, 20 | headers: { 'Content-Type': 'application/json' }, 21 | }); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /public/stacks/stacks/chat-with-gemini/route.ts: -------------------------------------------------------------------------------- 1 | import { StreamingTextResponse } from 'ai'; 2 | 3 | export async function POST(req: Request) { 4 | const { GoogleGenerativeAI } = require('@google/generative-ai'); 5 | const { messages } = await req.json(); 6 | 7 | const genAI = new GoogleGenerativeAI(process.env.GEMINI_API_KEY); 8 | const model = genAI.getGenerativeModel({ model: 'gemini-pro' }); 9 | 10 | try { 11 | const result = await model.generateContent(messages); 12 | const response = await result.response; 13 | const text = await response.text(); 14 | return new StreamingTextResponse(text); 15 | } catch (error) { 16 | // Handle the error here 17 | console.error('Error occurred:', error); 18 | return new StreamingTextResponse(error); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /public/stacks/stacks/chat-with-openai-streaming-helicone/route.ts: -------------------------------------------------------------------------------- 1 | import { OpenAIStream, StreamingTextResponse } from 'ai'; 2 | import OpenAI from 'openai'; 3 | 4 | const openai = new OpenAI({ 5 | apiKey: process.env.OPENAI_API_KEY, 6 | baseURL: 'https://oai.hconeai.com/v1', 7 | defaultHeaders: { 8 | 'Helicone-Auth': `Bearer ${process.env.HELICONE_API_KEY}`, 9 | }, 10 | }); 11 | export const runtime = 'edge'; 12 | export async function POST(req: Request) { 13 | const { messages } = await req.json(); 14 | const response = await openai.chat.completions.create({ 15 | model: 'gpt-3.5-turbo', 16 | stream: true, 17 | messages: [{ role: 'user', content: messages }], 18 | }); 19 | const stream = OpenAIStream(response); 20 | return new StreamingTextResponse(stream); 21 | } 22 | -------------------------------------------------------------------------------- /public/stacks/stacks/chat-with-openai-streaming-langchain/route.ts: -------------------------------------------------------------------------------- 1 | import { NextRequest, NextResponse } from "next/server"; 2 | import { Message as VercelChatMessage, StreamingTextResponse } from "ai"; 3 | 4 | import { ChatOpenAI } from "langchain/chat_models/openai"; 5 | import { BytesOutputParser } from "langchain/schema/output_parser"; 6 | import { PromptTemplate } from "langchain/prompts"; 7 | 8 | export const runtime = "edge"; 9 | 10 | const formatMessage = (message: VercelChatMessage) => { 11 | return `${message.role}: ${message.content}`; 12 | }; 13 | 14 | const TEMPLATE = ` 15 | Current conversation: 16 | {chat_history} 17 | 18 | User: {input} 19 | AI:`; 20 | 21 | export async function POST(req: NextRequest) { 22 | try { 23 | const body = await req.json(); 24 | const messages = body.messages ?? []; 25 | const formattedPreviousMessages = messages.slice(0, -1).map(formatMessage); 26 | const currentMessageContent = messages[messages.length - 1].content; 27 | const prompt = PromptTemplate.fromTemplate(TEMPLATE); 28 | 29 | 30 | const model = new ChatOpenAI({ 31 | temperature: 0.8, 32 | }); 33 | 34 | const outputParser = new BytesOutputParser(); 35 | const chain = prompt.pipe(model).pipe(outputParser); 36 | 37 | const stream = await chain.stream({ 38 | chat_history: formattedPreviousMessages.join("\n"), 39 | input: currentMessageContent, 40 | }); 41 | 42 | return new StreamingTextResponse(stream); 43 | } catch (e: any) { 44 | return NextResponse.json({ error: e.message }, { status: 500 }); 45 | } 46 | } -------------------------------------------------------------------------------- /public/stacks/stacks/chat-with-openai-streaming/route.ts: -------------------------------------------------------------------------------- 1 | import { OpenAIStream, StreamingTextResponse } from 'ai'; 2 | import OpenAI from 'openai'; 3 | 4 | const openai = new OpenAI({ 5 | apiKey: process.env.OPENAI_API_KEY, 6 | }); 7 | export const runtime = 'edge'; 8 | export async function POST(req: Request) { 9 | const { messages } = await req.json(); 10 | const response = await openai.chat.completions.create({ 11 | model: 'gpt-3.5-turbo', 12 | stream: true, 13 | messages: [{ role: 'user', content: messages }], 14 | }); 15 | const stream = OpenAIStream(response); 16 | return new StreamingTextResponse(stream); 17 | } 18 | -------------------------------------------------------------------------------- /public/stacks/stacks/create-stack-boilerplate/get-file-from-github.ts: -------------------------------------------------------------------------------- 1 | export default async function getFileFromGithub(path, token) { 2 | const owner = 'stackwiseai'; 3 | const repo = 'stackwise'; 4 | const sourceBranch = process.env.VERCEL_GIT_COMMIT_REF ?? ''; // or 'master', depending on your repository 5 | 6 | const url = `https://api.github.com/repos/${owner}/${repo}/contents/${path}?ref=main`; 7 | console.log(url, 'url'); 8 | const response = await fetch(url, { 9 | headers: { 10 | Authorization: `token ${token}`, 11 | }, 12 | }); 13 | return response.json(); 14 | } 15 | -------------------------------------------------------------------------------- /public/stacks/stacks/create-stack-boilerplate/route.ts: -------------------------------------------------------------------------------- 1 | import { Octokit } from '@octokit/rest'; 2 | 3 | import createStack from './create-stack'; 4 | 5 | const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN }); 6 | 7 | const vercelToken = process.env.VERCEL_TOKEN; 8 | const teamId = process.env.TEAM_ID; 9 | const repoId = process.env.REPO_ID; 10 | 11 | const owner = 'stackwiseai'; 12 | const repo = 'stackwise'; 13 | const sourceBranch = process.env.VERCEL_GIT_COMMIT_REF ?? ''; // or 'master', depending on your repository 14 | export const fetchCache = 'force-no-store'; // TODO: remove this line to enable caching but without making the app completely static 15 | export const revalidate = 0; 16 | export async function POST(req: Request) { 17 | const data = await req.json(); 18 | // get the token from header and strip the Bearer 19 | try { 20 | if (req.headers) { 21 | const header = req.headers.get('Authorization'); 22 | if (header) { 23 | const token = header.split(' ')[1]; 24 | const prLink = await createStack(data, token); 25 | return new Response(JSON.stringify({prLink}), { 26 | status: 200, 27 | headers: { 28 | 'Content-Type': 'application/json', 29 | }, 30 | }); 31 | } else { 32 | throw new Error('No token provided'); 33 | 34 | }} else { 35 | throw new Error('No headers provided'); 36 | } 37 | } catch (error) { 38 | console.error('Error during data insertion:', error); 39 | return new Response(JSON.stringify({ message: error.message }), { 40 | status: 500, 41 | headers: { 42 | 'Content-Type': 'application/json', 43 | }, 44 | }); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /public/stacks/stacks/get-image-description-openai/route.ts: -------------------------------------------------------------------------------- 1 | import { OpenAIStream, StreamingTextResponse } from 'ai'; 2 | import OpenAI from 'openai'; 3 | 4 | // Create an OpenAI API client (that's edge friendly!) 5 | const openai = new OpenAI({ 6 | apiKey: process.env.OPENAI_API_KEY || '', 7 | }); 8 | 9 | // IMPORTANT! Set the runtime to edge 10 | export const runtime = 'edge'; 11 | 12 | export async function POST(req: Request) { 13 | // 'data' contains the additional data that you have sent: 14 | const { messages, data } = await req.json(); 15 | 16 | const initialMessages = messages.slice(0, -1); 17 | const currentMessage = messages[messages.length - 1]; 18 | 19 | // Ask OpenAI for a streaming chat completion given the prompt 20 | const response = await openai.chat.completions.create({ 21 | model: 'gpt-4-vision-preview', 22 | stream: true, 23 | max_tokens: 150, 24 | messages: [ 25 | ...initialMessages, 26 | { 27 | ...currentMessage, 28 | content: [ 29 | { type: 'text', text: currentMessage.content }, 30 | 31 | // forward the image information to OpenAI: 32 | { 33 | type: 'image_url', 34 | image_url: data.imageUrl, 35 | }, 36 | ], 37 | }, 38 | ], 39 | }); 40 | 41 | // Convert the response into a friendly text-stream 42 | const stream = OpenAIStream(response); 43 | // Respond with the stream 44 | return new StreamingTextResponse(stream); 45 | } 46 | -------------------------------------------------------------------------------- /public/stacks/stacks/image-sharpener/route.ts: -------------------------------------------------------------------------------- 1 | import Replicate from 'replicate'; 2 | 3 | const replicate = new Replicate({ 4 | auth: process.env.REPLICATE_API_TOKEN!, 5 | }); 6 | 7 | export const maxDuration = 300; 8 | 9 | export async function POST(request: Request) { 10 | const form = await request.formData(); 11 | const imgFile = form.get('img') as Blob; 12 | const imgBuffer = Buffer.from(await imgFile.arrayBuffer()); 13 | const imgBase64 = imgBuffer.toString('base64'); 14 | const imgUri = `data:${imgFile.type};base64,${imgBase64}`; 15 | 16 | try { 17 | const esrganVersion = 18 | 'nightmareai/real-esrgan:42fed1c4974146d4d2414e2be2c5277c7fcf05fcc3a73abf41610695738c1d7b'; 19 | const esrgan = await replicate.run(esrganVersion, { 20 | input: { 21 | image: imgUri, 22 | face_enhance: true, 23 | }, 24 | }); 25 | 26 | return new Response(JSON.stringify(esrgan), { 27 | status: 200, 28 | headers: { 'Content-Type': 'application/json' }, 29 | }); 30 | } catch (error) { 31 | console.log(error); 32 | return new Response(JSON.stringify({ error }), { 33 | status: 500, 34 | }); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /public/stacks/stacks/stable-video-diffusion/route.ts: -------------------------------------------------------------------------------- 1 | import * as fal from '@fal-ai/serverless-client'; 2 | 3 | fal.config({ 4 | credentials: `${process.env.FAL_KEY_ID}:${process.env.FAL_KEY_SECRET}`, 5 | }); 6 | 7 | export const maxDuration = 300; 8 | 9 | export async function POST(request: Request) { 10 | let resp = null; 11 | 12 | const form = await request.formData(); 13 | const imgFile = form.get('img') as Blob; 14 | const maskFile = form.get('mask') as Blob; 15 | const degreeOfMotion = form.get('degreeOfMotion') as string; 16 | 17 | const imgBuffer = Buffer.from(await imgFile.arrayBuffer()); 18 | const maskBuffer = Buffer.from(await maskFile.arrayBuffer()); 19 | 20 | const imgBase64 = imgBuffer.toString('base64'); 21 | const maskBase64 = maskBuffer.toString('base64'); 22 | 23 | // Generate a full URI 24 | const imgUri = `data:${imgFile.type};base64,${imgBase64}`; 25 | const maskUri = `data:${maskFile.type};base64,${maskBase64}`; 26 | 27 | const payload = { 28 | subscriptionId: '110602490-svd', 29 | input: { 30 | image_url: imgUri, 31 | mask_image_url: maskUri, 32 | motion_bucket_id: Number(degreeOfMotion), 33 | cond_aug: 0.02, 34 | steps: 100, 35 | }, 36 | pollInterval: 500, 37 | logs: true, 38 | }; 39 | 40 | try { 41 | const result: any = await fal.subscribe(payload.subscriptionId, payload); 42 | 43 | resp = result; 44 | } catch (error) { 45 | console.log(error); 46 | return new Response(JSON.stringify({ error }), { 47 | status: 500, 48 | }); 49 | } 50 | 51 | return new Response(JSON.stringify(resp), { 52 | status: 200, 53 | headers: { 'Content-Type': 'application/json' }, 54 | }); 55 | } 56 | -------------------------------------------------------------------------------- /public/stacks/stacks/text-to-qr/route.ts: -------------------------------------------------------------------------------- 1 | import Replicate from 'replicate'; 2 | 3 | const replicate = new Replicate({ 4 | auth: process.env.REPLICATE_API_TOKEN!, 5 | }); 6 | 7 | export const maxDuration = 300; 8 | 9 | export async function POST(req: Request) { 10 | const { qrPrompt, url } = await req.json(); 11 | 12 | try { 13 | const controlNetVersion = 14 | 'zylim0702/qr_code_controlnet:628e604e13cf63d8ec58bd4d238474e8986b054bc5e1326e50995fdbc851c557'; 15 | const qrCode = await replicate.run(controlNetVersion, { 16 | input: { 17 | url: url, 18 | prompt: qrPrompt, 19 | qr_conditioning_scale: 1.3, 20 | }, 21 | }); 22 | 23 | return new Response( 24 | JSON.stringify({ 25 | img: qrCode, 26 | }), 27 | { 28 | status: 200, 29 | headers: { 'Content-Type': 'application/json' }, 30 | }, 31 | ); 32 | } catch (error) { 33 | console.log(error); 34 | return new Response(JSON.stringify({ error }), { 35 | status: 500, 36 | }); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /public/stacks/utils/actions.ts: -------------------------------------------------------------------------------- 1 | 'use server'; 2 | 3 | const MAILCHIMP_URL = 4 | 'https://us17.api.mailchimp.com/3.0/lists/77b1abf780/members/'; 5 | const MAILCHIMP_API_KEY = process.env.MAILCHIMP_API_KEY; 6 | 7 | export const subscribeEmail = async (prevState, formData) => { 8 | console.log(prevState, formData); 9 | const email = formData.get('email') as string; 10 | 11 | const data = { 12 | email_address: email, 13 | status: 'subscribed', // or 'pending' for double opt-in 14 | }; 15 | 16 | try { 17 | const response = await fetch(MAILCHIMP_URL, { 18 | method: 'POST', 19 | headers: { 20 | Authorization: `Basic ${btoa(`anystring:${MAILCHIMP_API_KEY}`)}`, 21 | 'Content-Type': 'application/json', 22 | }, 23 | body: JSON.stringify(data), 24 | }); 25 | if (response.ok) { 26 | console.log('Subscription successful'); 27 | return { status: 'success' }; 28 | } else { 29 | const errorData = await response.json(); 30 | console.error('Subscription error:', errorData); 31 | return { status: 'error', error: errorData }; 32 | } 33 | } catch (error) { 34 | console.error('Error:', error); 35 | } 36 | }; 37 | 38 | // import { stack } from 'stackwise'; 39 | 40 | export const callStack = async (prevState: any, formData: FormData) => { 41 | const userRequest = formData.get('stack') as string; 42 | // const message = await stack(userRequest); 43 | const message = 'remove'; 44 | 45 | return message; 46 | }; 47 | 48 | export const parseFormData = async (prevState: any, formData: FormData) => { 49 | const num1 = Number(formData.get('num1')); 50 | const num2 = Number(formData.get('num2')); 51 | 52 | return await multiplyNumbers(num1, num2); 53 | }; 54 | 55 | /** 56 | * Brief: Multiply two numbers together 57 | */ 58 | async function multiplyNumbers(num1: number, num2: number): Promise { 59 | return num1 * num2; 60 | } 61 | -------------------------------------------------------------------------------- /public/stacks/utils/getAWSPresignedUrl/route.ts: -------------------------------------------------------------------------------- 1 | import AWS from 'aws-sdk'; 2 | 3 | AWS.config.update({ 4 | region: process.env.AWS_REGION, 5 | accessKeyId: process.env.AWS_ACCESS_KEY_ID, 6 | secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, 7 | }); 8 | 9 | export async function POST(req: Request) { 10 | try { 11 | const body = await req.json(); 12 | const s3 = new AWS.S3(); 13 | const { fileName, fileType } = body; 14 | const params = { 15 | Bucket: 'cover-image-and-subtitle-stack', 16 | Key: fileName, 17 | Expires: 60, // URL expiration time in seconds 18 | ContentType: fileType, 19 | }; 20 | 21 | try { 22 | const presignedUrl = await s3.getSignedUrlPromise('putObject', params); 23 | return new Response(JSON.stringify({ url: presignedUrl }), { 24 | status: 200, 25 | }); 26 | } catch (error) { 27 | return new Response( 28 | JSON.stringify({ error: 'Error creating presigned URL' }), 29 | { status: 500 }, 30 | ); 31 | } 32 | } catch (error) { 33 | return new Response(JSON.stringify({ error: 'Bad Request' }), { 34 | status: 400, 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /public/stacks/utils/signIn.tsx: -------------------------------------------------------------------------------- 1 | 'use client'; 2 | 3 | import { supabaseClient } from './stack-db'; 4 | 5 | export default function signIn() { 6 | const baseUrl = 7 | process.env.NODE_ENV === 'production' 8 | ? `https://${process.env.NEXT_PUBLIC_VERCEL_URL}` // Use Vercel's environment variable in production 9 | : 'http://localhost:3000'; // Default to localhost in development 10 | 11 | async function signInWithGithub() { 12 | const { data, error } = await supabaseClient.auth.signInWithOAuth({ 13 | provider: 'github', 14 | options: { 15 | scopes: 'public_repo', 16 | redirectTo: `${baseUrl}/stacks/create-stack-boilerplate`, 17 | }, 18 | }); 19 | } 20 | return ( 21 | 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /public/stacks/utils/signOut.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { supabaseClient } from "./stack-db"; 4 | 5 | 6 | 7 | export default function signOut() { 8 | async function signOut() { 9 | 10 | const { error } = await supabaseClient.auth.signOut() 11 | } 12 | return ; 13 | } 14 | 15 | -------------------------------------------------------------------------------- /public/stacks/utils/stack-db.ts: -------------------------------------------------------------------------------- 1 | import { createBrowserClient } from '@supabase/ssr'; 2 | import { createClient } from '@supabase/supabase-js'; 3 | 4 | type Status = 'published' | 'starred' | 'expansion'; 5 | export const supabaseClient = createBrowserClient( 6 | process.env.NEXT_PUBLIC_SUPABASE_URL!, 7 | process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY! 8 | ) 9 | export async function getSupabaseClient() { 10 | return createClient( 11 | process.env.NEXT_PUBLIC_SUPABASE_URL || '', 12 | process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || '', 13 | ); 14 | } 15 | 16 | export async function getStackDB() { 17 | const supabase = createClient( 18 | process.env.NEXT_PUBLIC_SUPABASE_URL || '', 19 | process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY || '', 20 | ); 21 | const { data: projectsArray, error } = await supabase 22 | .from('stack') // Replace with your actual table name 23 | .select('*'); 24 | 25 | if (error) { 26 | console.error('Error fetching data:', error); 27 | return null; 28 | } 29 | 30 | const projectsObject: Record = {}; 31 | if (projectsArray) { 32 | projectsArray.forEach((project) => { 33 | projectsObject[project.id] = { 34 | name: project.name, 35 | description: project.description, 36 | tags: project.tags, 37 | }; 38 | }); 39 | } 40 | 41 | return projectsObject; 42 | } 43 | 44 | export interface StackDescription { 45 | name: string; 46 | description: string; 47 | tags: Status[]; 48 | } 49 | 50 | export const statusesToDisplay: Status[] = ['published']; 51 | -------------------------------------------------------------------------------- /public/stacks_homepage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stacks_homepage.png -------------------------------------------------------------------------------- /public/stackwise_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/public/stackwise_logo.png -------------------------------------------------------------------------------- /scripts/.gitignore: -------------------------------------------------------------------------------- 1 | dist -------------------------------------------------------------------------------- /scripts/sync-stacks.ts: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import * as fs from 'fs-extra'; 3 | 4 | async function removeDirectory(dirPath: string): Promise { 5 | try { 6 | await fs.remove(dirPath); 7 | console.log(`Removed directory: ${dirPath}`); 8 | } catch (err) { 9 | console.error(`Error removing directory ${dirPath}:`, err); 10 | } 11 | } 12 | 13 | async function copyRecursively(src: string, dest: string): Promise { 14 | // Create destination folder if it doesn't exist 15 | await fs.ensureDir(dest); 16 | 17 | // Read the source directory 18 | const items = await fs.readdir(src); 19 | 20 | for (const item of items) { 21 | const srcPath = path.join(src, item); 22 | const destPath = path.join(dest, item); 23 | 24 | const stats = await fs.stat(srcPath); 25 | 26 | if (stats.isDirectory()) { 27 | // If it's a directory, call recursively 28 | await copyRecursively(srcPath, destPath); 29 | } else { 30 | // If it's a file, check if it exists in destination 31 | if (!(await fs.pathExists(destPath))) { 32 | // Copy file if it doesn't exist in destination 33 | await fs.copy(srcPath, destPath); 34 | } 35 | } 36 | } 37 | } 38 | 39 | async function main() { 40 | let destinationFolder = '../public/stacks'; 41 | 42 | try { 43 | await removeDirectory(destinationFolder); 44 | console.log(`Folder ${destinationFolder} deleted`); 45 | 46 | // Usage example 47 | let sourceFolder = '../app/components/stacks'; 48 | await copyRecursively(sourceFolder, destinationFolder); 49 | console.log('Copy completed.'); 50 | 51 | sourceFolder = '../app/api'; 52 | await copyRecursively(sourceFolder, destinationFolder); 53 | console.log('Copy completed.'); 54 | } catch (err) { 55 | console.error('Error during operation:', err); 56 | } 57 | } 58 | 59 | main(); 60 | -------------------------------------------------------------------------------- /scripts/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "moduleResolution": "node", 4 | "esModuleInterop": true, 5 | "allowSyntheticDefaultImports": true, 6 | "outDir": "./dist" // Output directory for compiled files 7 | 8 | // other necessary options 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from 'tailwindcss'; 2 | 3 | import baseConfig from '@stackwise-tooling/tailwind-config'; 4 | 5 | export default { 6 | darkMode: 'class', 7 | content: [ 8 | './pages/**/*.{js,ts,jsx,tsx,mdx}', 9 | './components/**/*.{js,ts,jsx,tsx,mdx}', 10 | './app/**/*.{js,ts,jsx,tsx,mdx}', 11 | ], 12 | presets: [baseConfig], 13 | } satisfies Config; 14 | -------------------------------------------------------------------------------- /tooling/eslint-config/base.js: -------------------------------------------------------------------------------- 1 | /** @type {import("eslint").Linter.Config} */ 2 | const config = { 3 | extends: [ 4 | 'turbo', 5 | 'eslint:recommended', 6 | 'plugin:@typescript-eslint/recommended', 7 | 'plugin:@typescript-eslint/recommended-type-checked', 8 | 'plugin:@typescript-eslint/stylistic-type-checked', 9 | 'prettier', 10 | ], 11 | env: { 12 | es2022: true, 13 | node: true, 14 | }, 15 | parser: '@typescript-eslint/parser', 16 | parserOptions: { 17 | project: true, 18 | }, 19 | plugins: ['@typescript-eslint', 'import', 'only-warn'], 20 | rules: { 21 | 'turbo/no-undeclared-env-vars': 'off', 22 | '@typescript-eslint/no-unused-vars': [ 23 | 'error', 24 | { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }, 25 | ], 26 | '@typescript-eslint/consistent-type-imports': [ 27 | 'warn', 28 | { prefer: 'type-imports', fixStyle: 'separate-type-imports' }, 29 | ], 30 | '@typescript-eslint/no-misused-promises': [2, { checksVoidReturn: { attributes: false } }], 31 | 'import/consistent-type-specifier-style': ['error', 'prefer-top-level'], 32 | }, 33 | ignorePatterns: [ 34 | '**/.eslintrc.cjs', 35 | '**/*.config.js', 36 | '**/*.config.cjs', 37 | '.next', 38 | '.turbo', 39 | 'pnpm-lock.yaml', 40 | ], 41 | reportUnusedDisableDirectives: true, 42 | }; 43 | 44 | module.exports = config; 45 | -------------------------------------------------------------------------------- /tooling/eslint-config/nextjs.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | const config = { 3 | extends: ['plugin:@next/next/recommended'], 4 | rules: { 5 | '@next/next/no-html-link-for-pages': 'off', 6 | }, 7 | }; 8 | 9 | module.exports = config; 10 | -------------------------------------------------------------------------------- /tooling/eslint-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@stackwise-tooling/eslint-config", 3 | "version": "0.2.0", 4 | "private": true, 5 | "license": "MIT", 6 | "files": [ 7 | "./base.js", 8 | "./nextjs.js", 9 | "./react.js" 10 | ], 11 | "scripts": { 12 | "clean": "rm -rf .turbo node_modules", 13 | "lint": "eslint .", 14 | "format": "prettier --check . --ignore-path ../../.gitignore", 15 | "typecheck": "tsc --noEmit" 16 | }, 17 | "dependencies": { 18 | "@next/eslint-plugin-next": "^14.0.3", 19 | "@typescript-eslint/eslint-plugin": "^6.13.2", 20 | "@typescript-eslint/parser": "^6.13.2", 21 | "eslint-config-prettier": "^9.1.0", 22 | "eslint-config-turbo": "^1.10.16", 23 | "eslint-plugin-import": "^2.29.0", 24 | "eslint-plugin-jsx-a11y": "^6.8.0", 25 | "eslint-plugin-react": "^7.33.2", 26 | "eslint-plugin-react-hooks": "^4.6.0" 27 | }, 28 | "devDependencies": { 29 | "@stackwise-tooling/prettier-config": "*", 30 | "@stackwise-tooling/tsconfig": "*", 31 | "@types/eslint": "^8.44.8", 32 | "eslint": "^8.55.0", 33 | "eslint-plugin-only-warn": "^1.1.0", 34 | "typescript": "^5.3.2" 35 | }, 36 | "eslintConfig": { 37 | "root": true, 38 | "extends": [ 39 | "./base.js" 40 | ] 41 | }, 42 | "prettier": "@stackwise-tooling/prettier-config" 43 | } 44 | -------------------------------------------------------------------------------- /tooling/eslint-config/react.js: -------------------------------------------------------------------------------- 1 | /** @type {import('eslint').Linter.Config} */ 2 | const config = { 3 | extends: [ 4 | 'plugin:react/recommended', 5 | 'plugin:react-hooks/recommended', 6 | 'plugin:jsx-a11y/recommended', 7 | ], 8 | rules: { 9 | 'react/prop-types': 'off', 10 | }, 11 | globals: { 12 | React: 'writable', 13 | }, 14 | settings: { 15 | react: { 16 | version: 'detect', 17 | }, 18 | }, 19 | env: { 20 | browser: true, 21 | }, 22 | }; 23 | 24 | module.exports = config; 25 | -------------------------------------------------------------------------------- /tooling/eslint-config/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@stackwise-tooling/tsconfig/base.json", 3 | "compilerOptions": { 4 | "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json" 5 | }, 6 | "include": ["."], 7 | "exclude": ["node_modules"] 8 | } 9 | -------------------------------------------------------------------------------- /tooling/github/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@stackwise-tooling/github" 3 | } 4 | -------------------------------------------------------------------------------- /tooling/github/setup/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Setup and install' 2 | description: 'Common setup steps for Actions' 3 | 4 | runs: 5 | using: composite 6 | steps: 7 | - uses: actions/setup-node@v4 8 | with: 9 | node-version: 20 10 | cache: 'npm' 11 | 12 | - shell: bash 13 | run: npm install 14 | 15 | - shell: bash 16 | run: npm run build 17 | -------------------------------------------------------------------------------- /tooling/prettier-config/index.mjs: -------------------------------------------------------------------------------- 1 | import { fileURLToPath } from 'url'; 2 | 3 | /** @typedef {import("prettier").Config} PrettierConfig */ 4 | /** @typedef {import("prettier-plugin-tailwindcss").PluginOptions} TailwindConfig */ 5 | /** @typedef {import("@ianvs/prettier-plugin-sort-imports").PluginConfig} SortImportsConfig */ 6 | 7 | /** @type { PrettierConfig | SortImportsConfig | TailwindConfig } */ 8 | const config = { 9 | printWidth: 80, 10 | tabWidth: 2, 11 | singleQuote: true, 12 | trailingComma: 'all', 13 | arrowParens: 'always', 14 | semi: true, 15 | plugins: ['@ianvs/prettier-plugin-sort-imports', 'prettier-plugin-tailwindcss'], 16 | tailwindConfig: fileURLToPath(new URL('../../tooling/tailwind-config/index.ts', import.meta.url)), 17 | importOrder: [ 18 | '^(react/(.*)$)|^(react$)|^(react-native(.*)$)', 19 | '^(next/(.*)$)|^(next$)', 20 | '^(expo(.*)$)|^(expo$)', 21 | '', 22 | '', 23 | '^@stackwise/(.*)$', 24 | '^@stackwise-tooling/(.*)$', 25 | '', 26 | '^~/', 27 | '^[../]', 28 | '^[./]', 29 | ], 30 | importOrderParserPlugins: ['typescript', 'jsx', 'decorators-legacy'], 31 | importOrderTypeScriptVersion: '4.4.0', 32 | }; 33 | 34 | export default config; 35 | -------------------------------------------------------------------------------- /tooling/prettier-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@stackwise-tooling/prettier-config", 3 | "private": true, 4 | "version": "0.1.0", 5 | "main": "index.mjs", 6 | "scripts": { 7 | "clean": "rm -rf .turbo node_modules", 8 | "format": "prettier --check . --ignore-path ../../.gitignore", 9 | "typecheck": "tsc --noEmit" 10 | }, 11 | "dependencies": { 12 | "@ianvs/prettier-plugin-sort-imports": "^4.1.1", 13 | "prettier": "^3.1.0", 14 | "prettier-plugin-tailwindcss": "^0.5.7" 15 | }, 16 | "devDependencies": { 17 | "@stackwise-tooling/tsconfig": "*", 18 | "typescript": "^5.3.2" 19 | }, 20 | "prettier": "@stackwise-tooling/prettier-config" 21 | } 22 | -------------------------------------------------------------------------------- /tooling/prettier-config/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@stackwise-tooling/tsconfig/base.json", 3 | "compilerOptions": { 4 | "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json" 5 | }, 6 | "include": ["."], 7 | "exclude": ["node_modules"] 8 | } 9 | -------------------------------------------------------------------------------- /tooling/tailwind-config/index.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from 'tailwindcss'; 2 | 3 | const config: Config = { 4 | content: [''], 5 | theme: { 6 | extend: {}, 7 | }, 8 | plugins: [], 9 | variants: { 10 | extend: { 11 | backgroundColor: ['disabled'], 12 | }, 13 | }, 14 | }; 15 | export default config; 16 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/.bin/tailwind: -------------------------------------------------------------------------------- 1 | ../tailwindcss/lib/cli.js -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/.bin/tailwindcss: -------------------------------------------------------------------------------- 1 | ../tailwindcss/lib/cli.js -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Tailwind Labs, Inc. 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 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/base.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/colors.d.ts: -------------------------------------------------------------------------------- 1 | import type { DefaultColors } from './types/generated/colors' 2 | declare const colors: DefaultColors 3 | export = colors 4 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/colors.js: -------------------------------------------------------------------------------- 1 | let colors = require('./lib/public/colors') 2 | module.exports = (colors.__esModule ? colors : { default: colors }).default 3 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/components.css: -------------------------------------------------------------------------------- 1 | @tailwind components; 2 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/defaultConfig.d.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from './types/config' 2 | declare const config: Config 3 | export = config 4 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/defaultConfig.js: -------------------------------------------------------------------------------- 1 | let defaultConfig = require('./lib/public/default-config') 2 | module.exports = (defaultConfig.__esModule ? defaultConfig : { default: defaultConfig }).default 3 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/defaultTheme.d.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from './types/config' 2 | import { DefaultTheme } from './types/generated/default-theme' 3 | declare const theme: Config['theme'] & DefaultTheme 4 | export = theme 5 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/defaultTheme.js: -------------------------------------------------------------------------------- 1 | let defaultTheme = require('./lib/public/default-theme') 2 | module.exports = (defaultTheme.__esModule ? defaultTheme : { default: defaultTheme }).default 3 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/cli-peer-dependencies.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | function _export(target, all) { 6 | for(var name in all)Object.defineProperty(target, name, { 7 | enumerable: true, 8 | get: all[name] 9 | }); 10 | } 11 | _export(exports, { 12 | lazyPostcss: function() { 13 | return lazyPostcss; 14 | }, 15 | lazyPostcssImport: function() { 16 | return lazyPostcssImport; 17 | }, 18 | lazyAutoprefixer: function() { 19 | return lazyAutoprefixer; 20 | }, 21 | lazyCssnano: function() { 22 | return lazyCssnano; 23 | } 24 | }); 25 | function lazyPostcss() { 26 | return require("postcss"); 27 | } 28 | function lazyPostcssImport() { 29 | return require("postcss-import"); 30 | } 31 | function lazyAutoprefixer() { 32 | return require("autoprefixer"); 33 | } 34 | function lazyCssnano() { 35 | return require("cssnano"); 36 | } 37 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | "use strict"; 3 | if (false) { 4 | module.exports = require("./oxide/cli"); 5 | } else { 6 | module.exports = require("./cli/index"); 7 | } 8 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/cli/build/deps.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | "use strict"; 3 | Object.defineProperty(exports, "__esModule", { 4 | value: true 5 | }); 6 | function _export(target, all) { 7 | for(var name in all)Object.defineProperty(target, name, { 8 | enumerable: true, 9 | get: all[name] 10 | }); 11 | } 12 | _export(exports, { 13 | loadPostcss: function() { 14 | return loadPostcss; 15 | }, 16 | loadPostcssImport: function() { 17 | return loadPostcssImport; 18 | }, 19 | loadCssNano: function() { 20 | return loadCssNano; 21 | }, 22 | loadAutoprefixer: function() { 23 | return loadAutoprefixer; 24 | } 25 | }); 26 | const _index = require("../../../peers/index.js"); 27 | function loadPostcss() { 28 | // Try to load a local `postcss` version first 29 | try { 30 | return require("postcss"); 31 | } catch {} 32 | return (0, _index.lazyPostcss)(); 33 | } 34 | function loadPostcssImport() { 35 | // Try to load a local `postcss-import` version first 36 | try { 37 | return require("postcss-import"); 38 | } catch {} 39 | return (0, _index.lazyPostcssImport)(); 40 | } 41 | function loadCssNano() { 42 | let options = { 43 | preset: [ 44 | "default", 45 | { 46 | cssDeclarationSorter: false 47 | } 48 | ] 49 | }; 50 | // Try to load a local `cssnano` version first 51 | try { 52 | return require("cssnano"); 53 | } catch {} 54 | return (0, _index.lazyCssnano)()(options); 55 | } 56 | function loadAutoprefixer() { 57 | // Try to load a local `autoprefixer` version first 58 | try { 59 | return require("autoprefixer"); 60 | } catch {} 61 | return (0, _index.lazyAutoprefixer)(); 62 | } 63 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/css/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Nicolas Gallagher 4 | Copyright (c) Jonathan Neal 5 | Copyright (c) Sindre Sorhus (sindresorhus.com) 6 | Copyright (c) Adam Wathan 7 | Copyright (c) Jonathan Reinink 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | module.exports = require("./plugin"); 3 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/lib/detectNesting.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return _default; 9 | } 10 | }); 11 | function isRoot(node) { 12 | return node.type === "root"; 13 | } 14 | function isAtLayer(node) { 15 | return node.type === "atrule" && node.name === "layer"; 16 | } 17 | function _default(_context) { 18 | return (root, result)=>{ 19 | let found = false; 20 | root.walkAtRules("tailwind", (node)=>{ 21 | if (found) return false; 22 | if (node.parent && !(isRoot(node.parent) || isAtLayer(node.parent))) { 23 | found = true; 24 | node.warn(result, [ 25 | "Nested @tailwind rules were detected, but are not supported.", 26 | "Consider using a prefix to scope Tailwind's classes: https://tailwindcss.com/docs/configuration#prefix", 27 | "Alternatively, use the important selector strategy: https://tailwindcss.com/docs/configuration#selector-strategy" 28 | ].join("\n")); 29 | return false; 30 | } 31 | }); 32 | root.walkRules((rule)=>{ 33 | if (found) return false; 34 | rule.walkRules((nestedRule)=>{ 35 | found = true; 36 | nestedRule.warn(result, [ 37 | "Nested CSS was detected, but CSS nesting has not been configured correctly.", 38 | "Please enable a CSS nesting plugin *before* Tailwind in your configuration.", 39 | "See how here: https://tailwindcss.com/docs/using-with-preprocessors#nesting" 40 | ].join("\n")); 41 | return false; 42 | }); 43 | }); 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/lib/load-config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | function _export(target, all) { 6 | for(var name in all)Object.defineProperty(target, name, { 7 | enumerable: true, 8 | get: all[name] 9 | }); 10 | } 11 | _export(exports, { 12 | useCustomJiti: function() { 13 | return useCustomJiti; 14 | }, 15 | loadConfig: function() { 16 | return loadConfig; 17 | } 18 | }); 19 | const _jiti = /*#__PURE__*/ _interop_require_default(require("jiti")); 20 | const _sucrase = require("sucrase"); 21 | function _interop_require_default(obj) { 22 | return obj && obj.__esModule ? obj : { 23 | default: obj 24 | }; 25 | } 26 | let jiti = null; 27 | function useCustomJiti(_jiti) { 28 | jiti = _jiti; 29 | } 30 | function lazyJiti() { 31 | return jiti !== null && jiti !== void 0 ? jiti : jiti = (0, _jiti.default)(__filename, { 32 | interopDefault: true, 33 | transform: (opts)=>{ 34 | return (0, _sucrase.transform)(opts.source, { 35 | transforms: [ 36 | "typescript", 37 | "imports" 38 | ] 39 | }); 40 | } 41 | }); 42 | } 43 | function loadConfig(path) { 44 | let config = function() { 45 | try { 46 | return path ? require(path) : {}; 47 | } catch { 48 | return lazyJiti()(path); 49 | } 50 | }(); 51 | var _config_default; 52 | return (_config_default = config.default) !== null && _config_default !== void 0 ? _config_default : config; 53 | } 54 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/lib/partitionApplyAtRules.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return expandApplyAtRules; 9 | } 10 | }); 11 | function partitionRules(root) { 12 | if (!root.walkAtRules) return; 13 | let applyParents = new Set(); 14 | root.walkAtRules("apply", (rule)=>{ 15 | applyParents.add(rule.parent); 16 | }); 17 | if (applyParents.size === 0) { 18 | return; 19 | } 20 | for (let rule of applyParents){ 21 | let nodeGroups = []; 22 | let lastGroup = []; 23 | for (let node of rule.nodes){ 24 | if (node.type === "atrule" && node.name === "apply") { 25 | if (lastGroup.length > 0) { 26 | nodeGroups.push(lastGroup); 27 | lastGroup = []; 28 | } 29 | nodeGroups.push([ 30 | node 31 | ]); 32 | } else { 33 | lastGroup.push(node); 34 | } 35 | } 36 | if (lastGroup.length > 0) { 37 | nodeGroups.push(lastGroup); 38 | } 39 | if (nodeGroups.length === 1) { 40 | continue; 41 | } 42 | for (let group of [ 43 | ...nodeGroups 44 | ].reverse()){ 45 | let clone = rule.clone({ 46 | nodes: [] 47 | }); 48 | clone.append(group); 49 | rule.after(clone); 50 | } 51 | rule.remove(); 52 | } 53 | } 54 | function expandApplyAtRules() { 55 | return (root)=>{ 56 | partitionRules(root); 57 | }; 58 | } 59 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/lib/substituteScreenAtRules.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return _default; 9 | } 10 | }); 11 | const _normalizeScreens = require("../util/normalizeScreens"); 12 | const _buildMediaQuery = /*#__PURE__*/ _interop_require_default(require("../util/buildMediaQuery")); 13 | function _interop_require_default(obj) { 14 | return obj && obj.__esModule ? obj : { 15 | default: obj 16 | }; 17 | } 18 | function _default({ tailwindConfig: { theme } }) { 19 | return function(css) { 20 | css.walkAtRules("screen", (atRule)=>{ 21 | let screen = atRule.params; 22 | let screens = (0, _normalizeScreens.normalizeScreens)(theme.screens); 23 | let screenDefinition = screens.find(({ name })=>name === screen); 24 | if (!screenDefinition) { 25 | throw atRule.error(`No \`${screen}\` screen found.`); 26 | } 27 | atRule.name = "media"; 28 | atRule.params = (0, _buildMediaQuery.default)(screenDefinition); 29 | }); 30 | }; 31 | } 32 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/oxide/cli.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | require("./cli/index"); 6 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/oxide/postcss-plugin.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | module.exports = require("../plugin.js"); 3 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/postcss-plugins/nesting/README.md: -------------------------------------------------------------------------------- 1 | # tailwindcss/nesting 2 | 3 | This is a PostCSS plugin that wraps [postcss-nested](https://github.com/postcss/postcss-nested) or [postcss-nesting](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-nesting) and acts as a compatibility layer to make sure your nesting plugin of choice properly understands Tailwind's custom syntax like `@apply` and `@screen`. 4 | 5 | Add it to your PostCSS configuration, somewhere before Tailwind itself: 6 | 7 | ```js 8 | // postcss.config.js 9 | module.exports = { 10 | plugins: [ 11 | require('postcss-import'), 12 | require('tailwindcss/nesting'), 13 | require('tailwindcss'), 14 | require('autoprefixer'), 15 | ] 16 | } 17 | ``` 18 | 19 | By default, it uses the [postcss-nested](https://github.com/postcss/postcss-nested) plugin under the hood, which uses a Sass-like syntax and is the plugin that powers nesting support in the [Tailwind CSS plugin API](https://tailwindcss.com/docs/plugins#css-in-js-syntax). 20 | 21 | If you'd rather use [postcss-nesting](https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-nesting) (which is based on the work-in-progress [CSS Nesting](https://drafts.csswg.org/css-nesting-1/) specification), first install the plugin alongside: 22 | 23 | ```shell 24 | npm install postcss-nesting 25 | ``` 26 | 27 | Then pass the plugin itself as an argument to `tailwindcss/nesting` in your PostCSS configuration: 28 | 29 | ```js 30 | // postcss.config.js 31 | module.exports = { 32 | plugins: [ 33 | require('postcss-import'), 34 | require('tailwindcss/nesting')(require('postcss-nesting')), 35 | require('tailwindcss'), 36 | require('autoprefixer'), 37 | ] 38 | } 39 | ``` 40 | 41 | This can also be helpful if for whatever reason you need to use a very specific version of `postcss-nested` and want to override the version we bundle with `tailwindcss/nesting` itself. 42 | 43 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/postcss-plugins/nesting/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return _default; 9 | } 10 | }); 11 | const _plugin = require("./plugin"); 12 | const _default = Object.assign(function(opts) { 13 | return { 14 | postcssPlugin: "tailwindcss/nesting", 15 | Once (root, { result }) { 16 | return (0, _plugin.nesting)(opts)(root, result); 17 | } 18 | }; 19 | }, { 20 | postcss: true 21 | }); 22 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/public/create-plugin.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return _default; 9 | } 10 | }); 11 | const _createPlugin = /*#__PURE__*/ _interop_require_default(require("../util/createPlugin")); 12 | function _interop_require_default(obj) { 13 | return obj && obj.__esModule ? obj : { 14 | default: obj 15 | }; 16 | } 17 | const _default = _createPlugin.default; 18 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/public/default-config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return _default; 9 | } 10 | }); 11 | const _cloneDeep = require("../util/cloneDeep"); 12 | const _configfull = /*#__PURE__*/ _interop_require_default(require("../../stubs/config.full")); 13 | function _interop_require_default(obj) { 14 | return obj && obj.__esModule ? obj : { 15 | default: obj 16 | }; 17 | } 18 | const _default = (0, _cloneDeep.cloneDeep)(_configfull.default); 19 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/public/default-theme.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return _default; 9 | } 10 | }); 11 | const _cloneDeep = require("../util/cloneDeep"); 12 | const _configfull = /*#__PURE__*/ _interop_require_default(require("../../stubs/config.full")); 13 | function _interop_require_default(obj) { 14 | return obj && obj.__esModule ? obj : { 15 | default: obj 16 | }; 17 | } 18 | const _default = (0, _cloneDeep.cloneDeep)(_configfull.default.theme); 19 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/public/load-config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return _default; 9 | } 10 | }); 11 | const _loadconfig = require("../lib/load-config"); 12 | const _default = _loadconfig.loadConfig; 13 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/public/resolve-config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return resolveConfig; 9 | } 10 | }); 11 | const _resolveConfig = /*#__PURE__*/ _interop_require_default(require("../util/resolveConfig")); 12 | const _getAllConfigs = /*#__PURE__*/ _interop_require_default(require("../util/getAllConfigs")); 13 | function _interop_require_default(obj) { 14 | return obj && obj.__esModule ? obj : { 15 | default: obj 16 | }; 17 | } 18 | function resolveConfig(...configs) { 19 | let [, ...defaultConfigs] = (0, _getAllConfigs.default)(configs[0]); 20 | return (0, _resolveConfig.default)([ 21 | ...configs, 22 | ...defaultConfigs 23 | ]); 24 | } 25 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/applyImportantSelector.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "applyImportantSelector", { 6 | enumerable: true, 7 | get: function() { 8 | return applyImportantSelector; 9 | } 10 | }); 11 | const _postcssselectorparser = /*#__PURE__*/ _interop_require_default(require("postcss-selector-parser")); 12 | const _pseudoElements = require("./pseudoElements"); 13 | function _interop_require_default(obj) { 14 | return obj && obj.__esModule ? obj : { 15 | default: obj 16 | }; 17 | } 18 | function applyImportantSelector(selector, important) { 19 | let sel = (0, _postcssselectorparser.default)().astSync(selector); 20 | sel.each((sel)=>{ 21 | // Wrap with :is if it's not already wrapped 22 | let isWrapped = sel.nodes[0].type === "pseudo" && sel.nodes[0].value === ":is" && sel.nodes.every((node)=>node.type !== "combinator"); 23 | if (!isWrapped) { 24 | sel.nodes = [ 25 | _postcssselectorparser.default.pseudo({ 26 | value: ":is", 27 | nodes: [ 28 | sel.clone() 29 | ] 30 | }) 31 | ]; 32 | } 33 | (0, _pseudoElements.movePseudos)(sel); 34 | }); 35 | return `${important} ${sel.toString()}`; 36 | } 37 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/bigSign.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return bigSign; 9 | } 10 | }); 11 | function bigSign(bigIntValue) { 12 | return (bigIntValue > 0n) - (bigIntValue < 0n); 13 | } 14 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/buildMediaQuery.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return buildMediaQuery; 9 | } 10 | }); 11 | function buildMediaQuery(screens) { 12 | screens = Array.isArray(screens) ? screens : [ 13 | screens 14 | ]; 15 | return screens.map((screen)=>{ 16 | let values = screen.values.map((screen)=>{ 17 | if (screen.raw !== undefined) { 18 | return screen.raw; 19 | } 20 | return [ 21 | screen.min && `(min-width: ${screen.min})`, 22 | screen.max && `(max-width: ${screen.max})` 23 | ].filter(Boolean).join(" and "); 24 | }); 25 | return screen.not ? `not all and ${values}` : values; 26 | }).join(", "); 27 | } 28 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/cloneDeep.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "cloneDeep", { 6 | enumerable: true, 7 | get: function() { 8 | return cloneDeep; 9 | } 10 | }); 11 | function cloneDeep(value) { 12 | if (Array.isArray(value)) { 13 | return value.map((child)=>cloneDeep(child)); 14 | } 15 | if (typeof value === "object" && value !== null) { 16 | return Object.fromEntries(Object.entries(value).map(([k, v])=>[ 17 | k, 18 | cloneDeep(v) 19 | ])); 20 | } 21 | return value; 22 | } 23 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/configurePlugins.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return _default; 9 | } 10 | }); 11 | function _default(pluginConfig, plugins) { 12 | if (pluginConfig === undefined) { 13 | return plugins; 14 | } 15 | const pluginNames = Array.isArray(pluginConfig) ? pluginConfig : [ 16 | ...new Set(plugins.filter((pluginName)=>{ 17 | return pluginConfig !== false && pluginConfig[pluginName] !== false; 18 | }).concat(Object.keys(pluginConfig).filter((pluginName)=>{ 19 | return pluginConfig[pluginName] !== false; 20 | }))) 21 | ]; 22 | return pluginNames; 23 | } 24 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/createPlugin.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return _default; 9 | } 10 | }); 11 | function createPlugin(plugin, config) { 12 | return { 13 | handler: plugin, 14 | config 15 | }; 16 | } 17 | createPlugin.withOptions = function(pluginFunction, configFunction = ()=>({})) { 18 | const optionsFunction = function(options) { 19 | return { 20 | __options: options, 21 | handler: pluginFunction(options), 22 | config: configFunction(options) 23 | }; 24 | }; 25 | optionsFunction.__isOptionsFunction = true; 26 | // Expose plugin dependencies so that `object-hash` returns a different 27 | // value if anything here changes, to ensure a rebuild is triggered. 28 | optionsFunction.__pluginFunction = pluginFunction; 29 | optionsFunction.__configFunction = configFunction; 30 | return optionsFunction; 31 | }; 32 | const _default = createPlugin; 33 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/defaults.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "defaults", { 6 | enumerable: true, 7 | get: function() { 8 | return defaults; 9 | } 10 | }); 11 | function defaults(target, ...sources) { 12 | for (let source of sources){ 13 | for(let k in source){ 14 | var _target_hasOwnProperty; 15 | if (!(target === null || target === void 0 ? void 0 : (_target_hasOwnProperty = target.hasOwnProperty) === null || _target_hasOwnProperty === void 0 ? void 0 : _target_hasOwnProperty.call(target, k))) { 16 | target[k] = source[k]; 17 | } 18 | } 19 | for (let k of Object.getOwnPropertySymbols(source)){ 20 | var _target_hasOwnProperty1; 21 | if (!(target === null || target === void 0 ? void 0 : (_target_hasOwnProperty1 = target.hasOwnProperty) === null || _target_hasOwnProperty1 === void 0 ? void 0 : _target_hasOwnProperty1.call(target, k))) { 22 | target[k] = source[k]; 23 | } 24 | } 25 | } 26 | return target; 27 | } 28 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/escapeClassName.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return escapeClassName; 9 | } 10 | }); 11 | const _postcssselectorparser = /*#__PURE__*/ _interop_require_default(require("postcss-selector-parser")); 12 | const _escapeCommas = /*#__PURE__*/ _interop_require_default(require("./escapeCommas")); 13 | function _interop_require_default(obj) { 14 | return obj && obj.__esModule ? obj : { 15 | default: obj 16 | }; 17 | } 18 | function escapeClassName(className) { 19 | var _node_raws; 20 | let node = _postcssselectorparser.default.className(); 21 | node.value = className; 22 | var _node_raws_value; 23 | return (0, _escapeCommas.default)((_node_raws_value = node === null || node === void 0 ? void 0 : (_node_raws = node.raws) === null || _node_raws === void 0 ? void 0 : _node_raws.value) !== null && _node_raws_value !== void 0 ? _node_raws_value : node.value); 24 | } 25 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/escapeCommas.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return escapeCommas; 9 | } 10 | }); 11 | function escapeCommas(className) { 12 | return className.replace(/\\,/g, "\\2c "); 13 | } 14 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/flattenColorPalette.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return _default; 9 | } 10 | }); 11 | const flattenColorPalette = (colors)=>Object.assign({}, ...Object.entries(colors !== null && colors !== void 0 ? colors : {}).flatMap(([color, values])=>typeof values == "object" ? Object.entries(flattenColorPalette(values)).map(([number, hex])=>({ 12 | [color + (number === "DEFAULT" ? "" : `-${number}`)]: hex 13 | })) : [ 14 | { 15 | [`${color}`]: values 16 | } 17 | ])); 18 | const _default = flattenColorPalette; 19 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/hashConfig.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return hashConfig; 9 | } 10 | }); 11 | const _objecthash = /*#__PURE__*/ _interop_require_default(require("object-hash")); 12 | function _interop_require_default(obj) { 13 | return obj && obj.__esModule ? obj : { 14 | default: obj 15 | }; 16 | } 17 | function hashConfig(config) { 18 | return (0, _objecthash.default)(config, { 19 | ignoreUnknown: true 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/isKeyframeRule.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return isKeyframeRule; 9 | } 10 | }); 11 | function isKeyframeRule(rule) { 12 | return rule.parent && rule.parent.type === "atrule" && /keyframes$/.test(rule.parent.name); 13 | } 14 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/isPlainObject.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return isPlainObject; 9 | } 10 | }); 11 | function isPlainObject(value) { 12 | if (Object.prototype.toString.call(value) !== "[object Object]") { 13 | return false; 14 | } 15 | const prototype = Object.getPrototypeOf(value); 16 | return prototype === null || Object.getPrototypeOf(prototype) === null; 17 | } 18 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/log.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | function _export(target, all) { 6 | for(var name in all)Object.defineProperty(target, name, { 7 | enumerable: true, 8 | get: all[name] 9 | }); 10 | } 11 | _export(exports, { 12 | dim: function() { 13 | return dim; 14 | }, 15 | default: function() { 16 | return _default; 17 | } 18 | }); 19 | const _picocolors = /*#__PURE__*/ _interop_require_default(require("picocolors")); 20 | function _interop_require_default(obj) { 21 | return obj && obj.__esModule ? obj : { 22 | default: obj 23 | }; 24 | } 25 | let alreadyShown = new Set(); 26 | function log(type, messages, key) { 27 | if (typeof process !== "undefined" && process.env.JEST_WORKER_ID) return; 28 | if (key && alreadyShown.has(key)) return; 29 | if (key) alreadyShown.add(key); 30 | console.warn(""); 31 | messages.forEach((message)=>console.warn(type, "-", message)); 32 | } 33 | function dim(input) { 34 | return _picocolors.default.dim(input); 35 | } 36 | const _default = { 37 | info (key, messages) { 38 | log(_picocolors.default.bold(_picocolors.default.cyan("info")), ...Array.isArray(key) ? [ 39 | key 40 | ] : [ 41 | messages, 42 | key 43 | ]); 44 | }, 45 | warn (key, messages) { 46 | log(_picocolors.default.bold(_picocolors.default.yellow("warn")), ...Array.isArray(key) ? [ 47 | key 48 | ] : [ 49 | messages, 50 | key 51 | ]); 52 | }, 53 | risk (key, messages) { 54 | log(_picocolors.default.bold(_picocolors.default.magenta("risk")), ...Array.isArray(key) ? [ 55 | key 56 | ] : [ 57 | messages, 58 | key 59 | ]); 60 | } 61 | }; 62 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/nameClass.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | function _export(target, all) { 6 | for(var name in all)Object.defineProperty(target, name, { 7 | enumerable: true, 8 | get: all[name] 9 | }); 10 | } 11 | _export(exports, { 12 | asClass: function() { 13 | return asClass; 14 | }, 15 | default: function() { 16 | return nameClass; 17 | }, 18 | formatClass: function() { 19 | return formatClass; 20 | } 21 | }); 22 | const _escapeClassName = /*#__PURE__*/ _interop_require_default(require("./escapeClassName")); 23 | const _escapeCommas = /*#__PURE__*/ _interop_require_default(require("./escapeCommas")); 24 | function _interop_require_default(obj) { 25 | return obj && obj.__esModule ? obj : { 26 | default: obj 27 | }; 28 | } 29 | function asClass(name) { 30 | return (0, _escapeCommas.default)(`.${(0, _escapeClassName.default)(name)}`); 31 | } 32 | function nameClass(classPrefix, key) { 33 | return asClass(formatClass(classPrefix, key)); 34 | } 35 | function formatClass(classPrefix, key) { 36 | if (key === "DEFAULT") { 37 | return classPrefix; 38 | } 39 | if (key === "-" || key === "-DEFAULT") { 40 | return `-${classPrefix}`; 41 | } 42 | if (key.startsWith("-")) { 43 | return `-${classPrefix}${key}`; 44 | } 45 | if (key.startsWith("/")) { 46 | return `${classPrefix}${key}`; 47 | } 48 | return `${classPrefix}-${key}`; 49 | } 50 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/negateValue.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return negateValue; 9 | } 10 | }); 11 | function negateValue(value) { 12 | value = `${value}`; 13 | if (value === "0") { 14 | return "0"; 15 | } 16 | // Flip sign of numbers 17 | if (/^[+-]?(\d+|\d*\.\d+)(e[+-]?\d+)?(%|\w+)?$/.test(value)) { 18 | return value.replace(/^[+-]?/, (sign)=>sign === "-" ? "" : "-"); 19 | } 20 | // What functions we support negating numeric values for 21 | // var() isn't inherently a numeric function but we support it anyway 22 | // The trigonometric functions are omitted because you'll need to use calc(…) with them _anyway_ 23 | // to produce generally useful results and that will be covered already 24 | let numericFunctions = [ 25 | "var", 26 | "calc", 27 | "min", 28 | "max", 29 | "clamp" 30 | ]; 31 | for (const fn of numericFunctions){ 32 | if (value.includes(`${fn}(`)) { 33 | return `calc(${value} * -1)`; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/parseDependency.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | /** 3 | * @typedef {{type: 'dependency', file: string} | {type: 'dir-dependency', dir: string, glob: string}} Dependency 4 | */ /** 5 | * 6 | * @param {import('../lib/content.js').ContentPath} contentPath 7 | * @returns {Dependency[]} 8 | */ "use strict"; 9 | Object.defineProperty(exports, "__esModule", { 10 | value: true 11 | }); 12 | Object.defineProperty(exports, "default", { 13 | enumerable: true, 14 | get: function() { 15 | return parseDependency; 16 | } 17 | }); 18 | function parseDependency(contentPath) { 19 | if (contentPath.ignore) { 20 | return []; 21 | } 22 | if (!contentPath.glob) { 23 | return [ 24 | { 25 | type: "dependency", 26 | file: contentPath.base 27 | } 28 | ]; 29 | } 30 | if (process.env.ROLLUP_WATCH === "true") { 31 | // rollup-plugin-postcss does not support dir-dependency messages 32 | // but directories can be watched in the same way as files 33 | return [ 34 | { 35 | type: "dependency", 36 | file: contentPath.base 37 | } 38 | ]; 39 | } 40 | return [ 41 | { 42 | type: "dir-dependency", 43 | dir: contentPath.base, 44 | glob: contentPath.glob 45 | } 46 | ]; 47 | } 48 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/parseGlob.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "parseGlob", { 6 | enumerable: true, 7 | get: function() { 8 | return parseGlob; 9 | } 10 | }); 11 | const _globparent = /*#__PURE__*/ _interop_require_default(require("glob-parent")); 12 | function _interop_require_default(obj) { 13 | return obj && obj.__esModule ? obj : { 14 | default: obj 15 | }; 16 | } 17 | function parseGlob(pattern) { 18 | let glob = pattern; 19 | let base = (0, _globparent.default)(pattern); 20 | if (base !== ".") { 21 | glob = pattern.substr(base.length); 22 | if (glob.charAt(0) === "/") { 23 | glob = glob.substr(1); 24 | } 25 | } 26 | if (glob.substr(0, 2) === "./") { 27 | glob = glob.substr(2); 28 | } 29 | if (glob.charAt(0) === "/") { 30 | glob = glob.substr(1); 31 | } 32 | return { 33 | base, 34 | glob 35 | }; 36 | } 37 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/parseObjectStyles.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return parseObjectStyles; 9 | } 10 | }); 11 | const _postcss = /*#__PURE__*/ _interop_require_default(require("postcss")); 12 | const _postcssnested = /*#__PURE__*/ _interop_require_default(require("postcss-nested")); 13 | const _postcssjs = /*#__PURE__*/ _interop_require_default(require("postcss-js")); 14 | function _interop_require_default(obj) { 15 | return obj && obj.__esModule ? obj : { 16 | default: obj 17 | }; 18 | } 19 | function parseObjectStyles(styles) { 20 | if (!Array.isArray(styles)) { 21 | return parseObjectStyles([ 22 | styles 23 | ]); 24 | } 25 | return styles.flatMap((style)=>{ 26 | return (0, _postcss.default)([ 27 | (0, _postcssnested.default)({ 28 | bubble: [ 29 | "screen" 30 | ] 31 | }) 32 | ]).process(style, { 33 | parser: _postcssjs.default 34 | }).root.nodes; 35 | }); 36 | } 37 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/prefixSelector.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, /** 6 | * @template {string | import('postcss-selector-parser').Root} T 7 | * 8 | * Prefix all classes in the selector with the given prefix 9 | * 10 | * It can take either a string or a selector AST and will return the same type 11 | * 12 | * @param {string} prefix 13 | * @param {T} selector 14 | * @param {boolean} prependNegative 15 | * @returns {T} 16 | */ "default", { 17 | enumerable: true, 18 | get: function() { 19 | return _default; 20 | } 21 | }); 22 | const _postcssselectorparser = /*#__PURE__*/ _interop_require_default(require("postcss-selector-parser")); 23 | function _interop_require_default(obj) { 24 | return obj && obj.__esModule ? obj : { 25 | default: obj 26 | }; 27 | } 28 | function _default(prefix, selector, prependNegative = false) { 29 | if (prefix === "") { 30 | return selector; 31 | } 32 | /** @type {import('postcss-selector-parser').Root} */ let ast = typeof selector === "string" ? (0, _postcssselectorparser.default)().astSync(selector) : selector; 33 | ast.walkClasses((classSelector)=>{ 34 | let baseClass = classSelector.value; 35 | let shouldPlaceNegativeBeforePrefix = prependNegative && baseClass.startsWith("-"); 36 | classSelector.value = shouldPlaceNegativeBeforePrefix ? `-${prefix}${baseClass.slice(1)}` : `${prefix}${baseClass}`; 37 | }); 38 | return typeof selector === "string" ? ast.toString() : ast; 39 | } 40 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/removeAlphaVariables.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This function removes any uses of CSS variables used as an alpha channel 3 | * 4 | * This is required for selectors like `:visited` which do not allow 5 | * changes in opacity or external control using CSS variables. 6 | * 7 | * @param {import('postcss').Container} container 8 | * @param {string[]} toRemove 9 | */ "use strict"; 10 | Object.defineProperty(exports, "__esModule", { 11 | value: true 12 | }); 13 | Object.defineProperty(exports, "removeAlphaVariables", { 14 | enumerable: true, 15 | get: function() { 16 | return removeAlphaVariables; 17 | } 18 | }); 19 | function removeAlphaVariables(container, toRemove) { 20 | container.walkDecls((decl)=>{ 21 | if (toRemove.includes(decl.prop)) { 22 | decl.remove(); 23 | return; 24 | } 25 | for (let varName of toRemove){ 26 | if (decl.value.includes(`/ var(${varName})`)) { 27 | decl.value = decl.value.replace(`/ var(${varName})`, ""); 28 | } 29 | } 30 | }); 31 | } 32 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/responsive.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return responsive; 9 | } 10 | }); 11 | const _postcss = /*#__PURE__*/ _interop_require_default(require("postcss")); 12 | const _cloneNodes = /*#__PURE__*/ _interop_require_default(require("./cloneNodes")); 13 | function _interop_require_default(obj) { 14 | return obj && obj.__esModule ? obj : { 15 | default: obj 16 | }; 17 | } 18 | function responsive(rules) { 19 | return _postcss.default.atRule({ 20 | name: "responsive" 21 | }).append((0, _cloneNodes.default)(Array.isArray(rules) ? rules : [ 22 | rules 23 | ])); 24 | } 25 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/tap.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "tap", { 6 | enumerable: true, 7 | get: function() { 8 | return tap; 9 | } 10 | }); 11 | function tap(value, mutator) { 12 | mutator(value); 13 | return value; 14 | } 15 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/toColorValue.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "default", { 6 | enumerable: true, 7 | get: function() { 8 | return toColorValue; 9 | } 10 | }); 11 | function toColorValue(maybeFunction) { 12 | return typeof maybeFunction === "function" ? maybeFunction({}) : maybeFunction; 13 | } 14 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/toPath.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Parse a path string into an array of path segments. 3 | * 4 | * Square bracket notation `a[b]` may be used to "escape" dots that would otherwise be interpreted as path separators. 5 | * 6 | * Example: 7 | * a -> ['a'] 8 | * a.b.c -> ['a', 'b', 'c'] 9 | * a[b].c -> ['a', 'b', 'c'] 10 | * a[b.c].e.f -> ['a', 'b.c', 'e', 'f'] 11 | * a[b][c][d] -> ['a', 'b', 'c', 'd'] 12 | * 13 | * @param {string|string[]} path 14 | **/ "use strict"; 15 | Object.defineProperty(exports, "__esModule", { 16 | value: true 17 | }); 18 | Object.defineProperty(exports, "toPath", { 19 | enumerable: true, 20 | get: function() { 21 | return toPath; 22 | } 23 | }); 24 | function toPath(path) { 25 | if (Array.isArray(path)) return path; 26 | let openBrackets = path.split("[").length - 1; 27 | let closedBrackets = path.split("]").length - 1; 28 | if (openBrackets !== closedBrackets) { 29 | throw new Error(`Path is invalid. Has unbalanced brackets: ${path}`); 30 | } 31 | return path.split(/\.(?![^\[]*\])|[\[\]]/g).filter(Boolean); 32 | } 33 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/validateConfig.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "validateConfig", { 6 | enumerable: true, 7 | get: function() { 8 | return validateConfig; 9 | } 10 | }); 11 | const _log = /*#__PURE__*/ _interop_require_default(require("./log")); 12 | function _interop_require_default(obj) { 13 | return obj && obj.__esModule ? obj : { 14 | default: obj 15 | }; 16 | } 17 | function validateConfig(config) { 18 | if (config.content.files.length === 0) { 19 | _log.default.warn("content-problems", [ 20 | "The `content` option in your Tailwind CSS configuration is missing or empty.", 21 | "Configure your content sources or your generated CSS will be missing styles.", 22 | "https://tailwindcss.com/docs/content-configuration" 23 | ]); 24 | } 25 | // Warn if the line-clamp plugin is installed 26 | try { 27 | let plugin = require("@tailwindcss/line-clamp"); 28 | if (config.plugins.includes(plugin)) { 29 | _log.default.warn("line-clamp-in-core", [ 30 | "As of Tailwind CSS v3.3, the `@tailwindcss/line-clamp` plugin is now included by default.", 31 | "Remove it from the `plugins` array in your configuration to eliminate this warning." 32 | ]); 33 | config.plugins = config.plugins.filter((p)=>p !== plugin); 34 | } 35 | } catch {} 36 | return config; 37 | } 38 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/util/validateFormalSyntax.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { 3 | value: true 4 | }); 5 | Object.defineProperty(exports, "backgroundSize", { 6 | enumerable: true, 7 | get: function() { 8 | return backgroundSize; 9 | } 10 | }); 11 | const _dataTypes = require("./dataTypes"); 12 | const _splitAtTopLevelOnly = require("./splitAtTopLevelOnly"); 13 | function backgroundSize(value) { 14 | let keywordValues = [ 15 | "cover", 16 | "contain" 17 | ]; 18 | // the type will probably be a css function 19 | // so we have to use `splitAtTopLevelOnly` 20 | return (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(value, ",").every((part)=>{ 21 | let sizes = (0, _splitAtTopLevelOnly.splitAtTopLevelOnly)(part, "_").filter(Boolean); 22 | if (sizes.length === 1 && keywordValues.includes(sizes[0])) return true; 23 | if (sizes.length !== 1 && sizes.length !== 2) return false; 24 | return sizes.every((size)=>(0, _dataTypes.length)(size) || (0, _dataTypes.percentage)(size) || size === "auto"); 25 | }); 26 | } 27 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/value-parser/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) Bogdan Chadkin 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/value-parser/README.md: -------------------------------------------------------------------------------- 1 | # postcss-value-parser (forked + inlined) 2 | 3 | This is a customized version of of [PostCSS Value Parser](https://github.com/TrySound/postcss-value-parser) to fix some bugs around parsing CSS functions. 4 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/value-parser/index.d.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | module.exports = postcssValueParser; 3 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/value-parser/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var parse = require("./parse"); 3 | var walk = require("./walk"); 4 | var stringify = require("./stringify"); 5 | function ValueParser(value) { 6 | if (this instanceof ValueParser) { 7 | this.nodes = parse(value); 8 | return this; 9 | } 10 | return new ValueParser(value); 11 | } 12 | ValueParser.prototype.toString = function() { 13 | return Array.isArray(this.nodes) ? stringify(this.nodes) : ""; 14 | }; 15 | ValueParser.prototype.walk = function(cb, bubble) { 16 | walk(this.nodes, cb, bubble); 17 | return this; 18 | }; 19 | ValueParser.unit = require("./unit"); 20 | ValueParser.walk = walk; 21 | ValueParser.stringify = stringify; 22 | module.exports = ValueParser; 23 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/value-parser/stringify.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function stringifyNode(node, custom) { 3 | var type = node.type; 4 | var value = node.value; 5 | var buf; 6 | var customResult; 7 | if (custom && (customResult = custom(node)) !== undefined) { 8 | return customResult; 9 | } else if (type === "word" || type === "space") { 10 | return value; 11 | } else if (type === "string") { 12 | buf = node.quote || ""; 13 | return buf + value + (node.unclosed ? "" : buf); 14 | } else if (type === "comment") { 15 | return "/*" + value + (node.unclosed ? "" : "*/"); 16 | } else if (type === "div") { 17 | return (node.before || "") + value + (node.after || ""); 18 | } else if (Array.isArray(node.nodes)) { 19 | buf = stringify(node.nodes, custom); 20 | if (type !== "function") { 21 | return buf; 22 | } 23 | return value + "(" + (node.before || "") + buf + (node.after || "") + (node.unclosed ? "" : ")"); 24 | } 25 | return value; 26 | } 27 | function stringify(nodes, custom) { 28 | var result, i; 29 | if (Array.isArray(nodes)) { 30 | result = ""; 31 | for(i = nodes.length - 1; ~i; i -= 1){ 32 | result = stringifyNode(nodes[i], custom) + result; 33 | } 34 | return result; 35 | } 36 | return stringifyNode(nodes, custom); 37 | } 38 | module.exports = stringify; 39 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/lib/value-parser/walk.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | module.exports = function walk(nodes, cb, bubble) { 3 | var i, max, node, result; 4 | for(i = 0, max = nodes.length; i < max; i += 1){ 5 | node = nodes[i]; 6 | if (!bubble) { 7 | result = cb(node, i, nodes); 8 | } 9 | if (result !== false && node.type === "function" && Array.isArray(node.nodes)) { 10 | walk(node.nodes, cb, bubble); 11 | } 12 | if (bubble) { 13 | cb(node, i, nodes); 14 | } 15 | } 16 | }; 17 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/loadConfig.d.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from './types/config' 2 | 3 | declare function loadConfig(path: string): Config 4 | export = loadConfig 5 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/loadConfig.js: -------------------------------------------------------------------------------- 1 | let loadConfig = require('./lib/public/load-config') 2 | module.exports = (loadConfig.__esModule ? loadConfig : { default: loadConfig }).default 3 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/nesting/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { AcceptedPlugin, PluginCreator } from 'postcss' 2 | 3 | declare const plugin: PluginCreator 4 | export = plugin 5 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/nesting/index.js: -------------------------------------------------------------------------------- 1 | let nesting = require('../lib/postcss-plugins/nesting') 2 | module.exports = (nesting.__esModule ? nesting : { default: nesting }).default 3 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/plugin.d.ts: -------------------------------------------------------------------------------- 1 | import type { Config, PluginCreator } from './types/config' 2 | type Plugin = { 3 | withOptions( 4 | plugin: (options: T) => PluginCreator, 5 | config?: (options: T) => Partial 6 | ): { (options: T): { handler: PluginCreator; config?: Partial }; __isOptionsFunction: true } 7 | (plugin: PluginCreator, config?: Partial): { handler: PluginCreator; config?: Partial } 8 | } 9 | 10 | declare const plugin: Plugin 11 | export = plugin 12 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/plugin.js: -------------------------------------------------------------------------------- 1 | let createPlugin = require('./lib/public/create-plugin') 2 | module.exports = (createPlugin.__esModule ? createPlugin : { default: createPlugin }).default 3 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // These settings are duplicated in .editorconfig: 3 | tabWidth: 2, // indent_size = 2 4 | useTabs: false, // indent_style = space 5 | endOfLine: 'lf', // end_of_line = lf 6 | semi: false, // default: true 7 | singleQuote: true, // default: false 8 | printWidth: 100, // default: 80 9 | trailingComma: 'es5', 10 | bracketSpacing: true, 11 | overrides: [ 12 | { 13 | files: '*.js', 14 | options: { 15 | parser: 'flow', 16 | }, 17 | }, 18 | ], 19 | } 20 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/resolveConfig.d.ts: -------------------------------------------------------------------------------- 1 | import { Config, ResolvableTo, ThemeConfig } from './types/config' 2 | import { DefaultTheme } from './types/generated/default-theme' 3 | import { DefaultColors } from './types/generated/colors' 4 | 5 | type ResolvedConfig = Omit & { 6 | theme: MergeThemes< 7 | UnwrapResolvables>, 8 | T['theme'] extends { extend: infer TExtend } ? UnwrapResolvables : {} 9 | > 10 | } 11 | 12 | type UnwrapResolvables = { 13 | [K in keyof T]: T[K] extends ResolvableTo ? R : T[K] 14 | } 15 | 16 | type ThemeConfigResolved = UnwrapResolvables 17 | type DefaultThemeFull = DefaultTheme & { colors: DefaultColors } 18 | 19 | type MergeThemes = { 20 | [K in keyof ThemeConfigResolved | keyof Overrides]: (K extends keyof Overrides 21 | ? Overrides[K] 22 | : K extends keyof DefaultThemeFull 23 | ? DefaultThemeFull[K] 24 | : K extends keyof ThemeConfigResolved 25 | ? ThemeConfigResolved[K] 26 | : never) & 27 | (K extends keyof Extensions ? Extensions[K] : {}) 28 | } 29 | 30 | declare function resolveConfig(config: T): ResolvedConfig 31 | export = resolveConfig 32 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/resolveConfig.js: -------------------------------------------------------------------------------- 1 | let resolveConfig = require('./lib/public/resolve-config') 2 | module.exports = (resolveConfig.__esModule ? resolveConfig : { default: resolveConfig }).default 3 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/screens.css: -------------------------------------------------------------------------------- 1 | @tailwind screens; 2 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/scripts/create-plugin-list.js: -------------------------------------------------------------------------------- 1 | import { corePlugins } from '../src/corePlugins' 2 | import fs from 'fs' 3 | import path from 'path' 4 | 5 | let corePluginList = Object.keys(corePlugins) 6 | 7 | fs.writeFileSync( 8 | path.join(process.cwd(), 'src', 'corePluginList.js'), 9 | `export default ${JSON.stringify(corePluginList)}` 10 | ) 11 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/scripts/release-channel.js: -------------------------------------------------------------------------------- 1 | // Given a version, figure out what the release channel is so that we can publish to the correct 2 | // channel on npm. 3 | // 4 | // E.g.: 5 | // 6 | // 1.2.3 -> latest (default) 7 | // 0.0.0-insiders.ffaa88 -> insiders 8 | // 4.1.0-alpha.4 -> alpha 9 | 10 | let version = 11 | process.argv[2] || process.env.npm_package_version || require('../package.json').version 12 | 13 | let match = /\d+\.\d+\.\d+-(.*)\.\d+/g.exec(version) 14 | if (match) { 15 | console.log(match[1]) 16 | } else { 17 | console.log('latest') 18 | } 19 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/scripts/release-notes.js: -------------------------------------------------------------------------------- 1 | // Given a version, figure out what the release notes are so that we can use this to pre-fill the 2 | // relase notes on a GitHub release for the current version. 3 | 4 | let path = require('path') 5 | let fs = require('fs') 6 | 7 | let version = 8 | process.argv[2] || process.env.npm_package_version || require('../package.json').version 9 | 10 | let changelog = fs.readFileSync(path.resolve(__dirname, '..', 'CHANGELOG.md'), 'utf8') 11 | let match = new RegExp( 12 | `## \\[${version}\\] - (.*)\\n\\n([\\s\\S]*?)\\n(?:(?:##\\s)|(?:\\[))`, 13 | 'g' 14 | ).exec(changelog) 15 | 16 | if (match) { 17 | let [, , notes] = match 18 | console.log(notes.trim()) 19 | } else { 20 | console.log(`Placeholder release notes for version: v${version}`) 21 | } 22 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/scripts/swap-engines.js: -------------------------------------------------------------------------------- 1 | let fs = require('fs') 2 | let path = require('path') 3 | 4 | let engines = { 5 | stable: { 6 | files: [ 7 | path.resolve(__dirname, '..', 'package.stable.json'), 8 | path.resolve(__dirname, '..', 'package-lock.stable.json'), 9 | ], 10 | }, 11 | oxide: { 12 | files: [ 13 | path.resolve(__dirname, '..', 'package.oxide.json'), 14 | path.resolve(__dirname, '..', 'package-lock.oxide.json'), 15 | ], 16 | }, 17 | } 18 | 19 | // Find out what the current engine is that we are using: 20 | let [otherEngine, info] = Object.entries(engines).find(([, info]) => 21 | info.files.every((file) => fs.existsSync(file)) 22 | ) 23 | let currentEngine = otherEngine === 'oxide' ? 'stable' : 'oxide' 24 | 25 | console.log(`Current engine: \`${currentEngine}\`, swapping to \`${otherEngine}\``) 26 | 27 | // Swap the engines 28 | for (let file of info.files) { 29 | fs.renameSync( 30 | file.replace(`.${otherEngine}`, ''), 31 | file.replace(`.${otherEngine}`, `.${currentEngine}`) 32 | ) 33 | } 34 | for (let file of engines[otherEngine].files) { 35 | fs.renameSync(file, file.replace(`.${otherEngine}`, '')) 36 | } 37 | 38 | console.log( 39 | 'Engines have been swapped. Make sure to run `npm install` to update your dependencies.' 40 | ) 41 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/scripts/type-utils.js: -------------------------------------------------------------------------------- 1 | export function union(types) { 2 | return [...new Set(types)].join(' | ') 3 | } 4 | 5 | export function unionValues(values) { 6 | return union(values.map(forValue)) 7 | } 8 | 9 | export function forKeys(value) { 10 | return union(Object.keys(value).map((key) => `'${key}'`)) 11 | } 12 | 13 | export function forValue(value) { 14 | if (Array.isArray(value)) { 15 | return `(${unionValues(value)})[]` 16 | } 17 | 18 | if (typeof value === 'object') { 19 | return `Record<${forKeys(value)}, ${unionValues(Object.values(value))}>` 20 | } 21 | 22 | if (typeof value === 'string') { 23 | return `string` 24 | } 25 | 26 | return `any` 27 | } 28 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/cli-peer-dependencies.js: -------------------------------------------------------------------------------- 1 | export function lazyPostcss() { 2 | return require('postcss') 3 | } 4 | 5 | export function lazyPostcssImport() { 6 | return require('postcss-import') 7 | } 8 | 9 | export function lazyAutoprefixer() { 10 | return require('autoprefixer') 11 | } 12 | 13 | export function lazyCssnano() { 14 | return require('cssnano') 15 | } 16 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/cli.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | if (__OXIDE__) { 4 | module.exports = require('./oxide/cli') 5 | } else { 6 | module.exports = require('./cli/index') 7 | } 8 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/cli/build/deps.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | import { 4 | // @ts-ignore 5 | lazyPostcss, 6 | 7 | // @ts-ignore 8 | lazyPostcssImport, 9 | 10 | // @ts-ignore 11 | lazyCssnano, 12 | 13 | // @ts-ignore 14 | lazyAutoprefixer, 15 | } from '../../../peers/index.js' 16 | 17 | /** 18 | * @returns {import('postcss')} 19 | */ 20 | export function loadPostcss() { 21 | // Try to load a local `postcss` version first 22 | try { 23 | return require('postcss') 24 | } catch {} 25 | 26 | return lazyPostcss() 27 | } 28 | 29 | export function loadPostcssImport() { 30 | // Try to load a local `postcss-import` version first 31 | try { 32 | return require('postcss-import') 33 | } catch {} 34 | 35 | return lazyPostcssImport() 36 | } 37 | 38 | export function loadCssNano() { 39 | let options = { preset: ['default', { cssDeclarationSorter: false }] } 40 | 41 | // Try to load a local `cssnano` version first 42 | try { 43 | return require('cssnano') 44 | } catch {} 45 | 46 | return lazyCssnano()(options) 47 | } 48 | 49 | export function loadAutoprefixer() { 50 | // Try to load a local `autoprefixer` version first 51 | try { 52 | return require('autoprefixer') 53 | } catch {} 54 | 55 | return lazyAutoprefixer() 56 | } 57 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/cli/build/index.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | import fs from 'fs' 4 | import path from 'path' 5 | import { resolveDefaultConfigPath } from '../../util/resolveConfigPath.js' 6 | import { createProcessor } from './plugin.js' 7 | 8 | export async function build(args) { 9 | let input = args['--input'] 10 | let shouldWatch = args['--watch'] 11 | 12 | // TODO: Deprecate this in future versions 13 | if (!input && args['_'][1]) { 14 | console.error('[deprecation] Running tailwindcss without -i, please provide an input file.') 15 | input = args['--input'] = args['_'][1] 16 | } 17 | 18 | if (input && input !== '-' && !fs.existsSync((input = path.resolve(input)))) { 19 | console.error(`Specified input file ${args['--input']} does not exist.`) 20 | process.exit(9) 21 | } 22 | 23 | if (args['--config'] && !fs.existsSync((args['--config'] = path.resolve(args['--config'])))) { 24 | console.error(`Specified config file ${args['--config']} does not exist.`) 25 | process.exit(9) 26 | } 27 | 28 | // TODO: Reference the @config path here if exists 29 | let configPath = args['--config'] ? args['--config'] : resolveDefaultConfigPath() 30 | 31 | let processor = await createProcessor(args, configPath) 32 | 33 | if (shouldWatch) { 34 | // Abort the watcher if stdin is closed to avoid zombie processes 35 | // You can disable this behavior with --watch=always 36 | if (args['--watch'] !== 'always') { 37 | process.stdin.on('end', () => process.exit(0)) 38 | } 39 | 40 | process.stdin.resume() 41 | 42 | await processor.watch() 43 | } else { 44 | await processor.build().catch((e) => { 45 | console.error(e) 46 | process.exit(1) 47 | }) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/css/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Nicolas Gallagher 4 | Copyright (c) Jonathan Neal 5 | Copyright (c) Sindre Sorhus (sindresorhus.com) 6 | Copyright (c) Adam Wathan 7 | Copyright (c) Jonathan Reinink 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy 10 | of this software and associated documentation files (the "Software"), to deal 11 | in the Software without restriction, including without limitation the rights 12 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | copies of the Software, and to permit persons to whom the Software is 14 | furnished to do so, subject to the following conditions: 15 | 16 | The above copyright notice and this permission notice shall be included in all 17 | copies or substantial portions of the Software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/index.js: -------------------------------------------------------------------------------- 1 | module.exports = require('./plugin') 2 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/lib/cacheInvalidation.js: -------------------------------------------------------------------------------- 1 | import crypto from 'crypto' 2 | import * as sharedState from './sharedState' 3 | 4 | /** 5 | * Calculate the hash of a string. 6 | * 7 | * This doesn't need to be cryptographically secure or 8 | * anything like that since it's used only to detect 9 | * when the CSS changes to invalidate the context. 10 | * 11 | * This is wrapped in a try/catch because it's really dependent 12 | * on how Node itself is build and the environment and OpenSSL 13 | * version / build that is installed on the user's machine. 14 | * 15 | * Based on the environment this can just outright fail. 16 | * 17 | * See https://github.com/nodejs/node/issues/40455 18 | * 19 | * @param {string} str 20 | */ 21 | function getHash(str) { 22 | try { 23 | return crypto.createHash('md5').update(str, 'utf-8').digest('binary') 24 | } catch (err) { 25 | return '' 26 | } 27 | } 28 | 29 | /** 30 | * Determine if the CSS tree is different from the 31 | * previous version for the given `sourcePath`. 32 | * 33 | * @param {string} sourcePath 34 | * @param {import('postcss').Node} root 35 | */ 36 | export function hasContentChanged(sourcePath, root) { 37 | let css = root.toString() 38 | 39 | // We only care about files with @tailwind directives 40 | // Other files use an existing context 41 | if (!css.includes('@tailwind')) { 42 | return false 43 | } 44 | 45 | let existingHash = sharedState.sourceHashMap.get(sourcePath) 46 | let rootHash = getHash(css) 47 | let didChange = existingHash !== rootHash 48 | 49 | sharedState.sourceHashMap.set(sourcePath, rootHash) 50 | 51 | return didChange 52 | } 53 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/lib/collapseAdjacentRules.js: -------------------------------------------------------------------------------- 1 | let comparisonMap = { 2 | atrule: ['name', 'params'], 3 | rule: ['selector'], 4 | } 5 | let types = new Set(Object.keys(comparisonMap)) 6 | 7 | export default function collapseAdjacentRules() { 8 | function collapseRulesIn(root) { 9 | let currentRule = null 10 | root.each((node) => { 11 | if (!types.has(node.type)) { 12 | currentRule = null 13 | return 14 | } 15 | 16 | if (currentRule === null) { 17 | currentRule = node 18 | return 19 | } 20 | 21 | let properties = comparisonMap[node.type] 22 | 23 | if (node.type === 'atrule' && node.name === 'font-face') { 24 | currentRule = node 25 | } else if ( 26 | properties.every( 27 | (property) => 28 | (node[property] ?? '').replace(/\s+/g, ' ') === 29 | (currentRule[property] ?? '').replace(/\s+/g, ' ') 30 | ) 31 | ) { 32 | // An AtRule may not have children (for example if we encounter duplicate @import url(…) rules) 33 | if (node.nodes) { 34 | currentRule.append(node.nodes) 35 | } 36 | 37 | node.remove() 38 | } else { 39 | currentRule = node 40 | } 41 | }) 42 | 43 | // After we've collapsed adjacent rules & at-rules, we need to collapse 44 | // adjacent rules & at-rules that are children of at-rules. 45 | // We do not care about nesting rules because Tailwind CSS 46 | // explicitly does not handle rule nesting on its own as 47 | // the user is expected to use a nesting plugin 48 | root.each((node) => { 49 | if (node.type === 'atrule') { 50 | collapseRulesIn(node) 51 | } 52 | }) 53 | } 54 | 55 | return (root) => { 56 | collapseRulesIn(root) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/lib/detectNesting.js: -------------------------------------------------------------------------------- 1 | function isRoot(node) { 2 | return node.type === 'root' 3 | } 4 | 5 | function isAtLayer(node) { 6 | return node.type === 'atrule' && node.name === 'layer' 7 | } 8 | 9 | export default function (_context) { 10 | return (root, result) => { 11 | let found = false 12 | 13 | root.walkAtRules('tailwind', (node) => { 14 | if (found) return false 15 | 16 | if (node.parent && !(isRoot(node.parent) || isAtLayer(node.parent))) { 17 | found = true 18 | node.warn( 19 | result, 20 | [ 21 | 'Nested @tailwind rules were detected, but are not supported.', 22 | "Consider using a prefix to scope Tailwind's classes: https://tailwindcss.com/docs/configuration#prefix", 23 | 'Alternatively, use the important selector strategy: https://tailwindcss.com/docs/configuration#selector-strategy', 24 | ].join('\n') 25 | ) 26 | return false 27 | } 28 | }) 29 | 30 | root.walkRules((rule) => { 31 | if (found) return false 32 | 33 | rule.walkRules((nestedRule) => { 34 | found = true 35 | nestedRule.warn( 36 | result, 37 | [ 38 | 'Nested CSS was detected, but CSS nesting has not been configured correctly.', 39 | 'Please enable a CSS nesting plugin *before* Tailwind in your configuration.', 40 | 'See how here: https://tailwindcss.com/docs/using-with-preprocessors#nesting', 41 | ].join('\n') 42 | ) 43 | return false 44 | }) 45 | }) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/lib/findAtConfigPath.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs' 2 | import path from 'path' 3 | 4 | /** 5 | * Find the @config at-rule in the given CSS AST and return the relative path to the config file 6 | * 7 | * @param {import('postcss').Root} root 8 | * @param {import('postcss').Result} result 9 | */ 10 | export function findAtConfigPath(root, result) { 11 | let configPath = null 12 | let relativeTo = null 13 | 14 | root.walkAtRules('config', (rule) => { 15 | relativeTo = rule.source?.input.file ?? result.opts.from ?? null 16 | 17 | if (relativeTo === null) { 18 | throw rule.error( 19 | 'The `@config` directive cannot be used without setting `from` in your PostCSS config.' 20 | ) 21 | } 22 | 23 | if (configPath) { 24 | throw rule.error('Only one `@config` directive is allowed per file.') 25 | } 26 | 27 | let matches = rule.params.match(/(['"])(.*?)\1/) 28 | if (!matches) { 29 | throw rule.error('A path is required when using the `@config` directive.') 30 | } 31 | 32 | let inputPath = matches[2] 33 | if (path.isAbsolute(inputPath)) { 34 | throw rule.error('The `@config` directive cannot be used with an absolute path.') 35 | } 36 | 37 | configPath = path.resolve(path.dirname(relativeTo), inputPath) 38 | if (!fs.existsSync(configPath)) { 39 | throw rule.error( 40 | `The config file at "${inputPath}" does not exist. Make sure the path is correct and the file exists.` 41 | ) 42 | } 43 | 44 | rule.remove() 45 | }) 46 | 47 | return configPath ? configPath : null 48 | } 49 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/lib/load-config.ts: -------------------------------------------------------------------------------- 1 | import jitiFactory from 'jiti' 2 | import { transform } from 'sucrase' 3 | 4 | import { Config } from '../../types/config' 5 | 6 | let jiti: ReturnType | null = null 7 | 8 | // @internal 9 | // This WILL be removed in some future release 10 | // If you rely on this your stuff WILL break 11 | export function useCustomJiti(_jiti: ReturnType) { 12 | jiti = _jiti 13 | } 14 | 15 | function lazyJiti() { 16 | return ( 17 | jiti ?? 18 | (jiti = jitiFactory(__filename, { 19 | interopDefault: true, 20 | transform: (opts) => { 21 | return transform(opts.source, { 22 | transforms: ['typescript', 'imports'], 23 | }) 24 | }, 25 | })) 26 | ) 27 | } 28 | 29 | export function loadConfig(path: string): Config { 30 | let config = (function () { 31 | try { 32 | return path ? require(path) : {} 33 | } catch { 34 | return lazyJiti()(path) 35 | } 36 | })() 37 | 38 | return config.default ?? config 39 | } 40 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/lib/partitionApplyAtRules.js: -------------------------------------------------------------------------------- 1 | function partitionRules(root) { 2 | if (!root.walkAtRules) return 3 | 4 | let applyParents = new Set() 5 | 6 | root.walkAtRules('apply', (rule) => { 7 | applyParents.add(rule.parent) 8 | }) 9 | 10 | if (applyParents.size === 0) { 11 | return 12 | } 13 | 14 | for (let rule of applyParents) { 15 | let nodeGroups = [] 16 | let lastGroup = [] 17 | 18 | for (let node of rule.nodes) { 19 | if (node.type === 'atrule' && node.name === 'apply') { 20 | if (lastGroup.length > 0) { 21 | nodeGroups.push(lastGroup) 22 | lastGroup = [] 23 | } 24 | nodeGroups.push([node]) 25 | } else { 26 | lastGroup.push(node) 27 | } 28 | } 29 | 30 | if (lastGroup.length > 0) { 31 | nodeGroups.push(lastGroup) 32 | } 33 | 34 | if (nodeGroups.length === 1) { 35 | continue 36 | } 37 | 38 | for (let group of [...nodeGroups].reverse()) { 39 | let clone = rule.clone({ nodes: [] }) 40 | clone.append(group) 41 | rule.after(clone) 42 | } 43 | 44 | rule.remove() 45 | } 46 | } 47 | 48 | export default function expandApplyAtRules() { 49 | return (root) => { 50 | partitionRules(root) 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/lib/sharedState.js: -------------------------------------------------------------------------------- 1 | import pkg from '../../package.json' 2 | 3 | export const env = 4 | typeof process !== 'undefined' 5 | ? { 6 | NODE_ENV: process.env.NODE_ENV, 7 | DEBUG: resolveDebug(process.env.DEBUG), 8 | ENGINE: pkg.tailwindcss.engine, 9 | } 10 | : { 11 | NODE_ENV: 'production', 12 | DEBUG: false, 13 | ENGINE: pkg.tailwindcss.engine, 14 | } 15 | 16 | export const contextMap = new Map() 17 | export const configContextMap = new Map() 18 | export const contextSourcesMap = new Map() 19 | export const sourceHashMap = new Map() 20 | export const NOT_ON_DEMAND = new String('*') 21 | 22 | export const NONE = Symbol('__NONE__') 23 | 24 | export function resolveDebug(debug) { 25 | if (debug === undefined) { 26 | return false 27 | } 28 | 29 | // Environment variables are strings, so convert to boolean 30 | if (debug === 'true' || debug === '1') { 31 | return true 32 | } 33 | 34 | if (debug === 'false' || debug === '0') { 35 | return false 36 | } 37 | 38 | // Keep the debug convention into account: 39 | // DEBUG=* -> This enables all debug modes 40 | // DEBUG=projectA,projectB,projectC -> This enables debug for projectA, projectB and projectC 41 | // DEBUG=projectA:* -> This enables all debug modes for projectA (if you have sub-types) 42 | // DEBUG=projectA,-projectB -> This enables debug for projectA and explicitly disables it for projectB 43 | 44 | if (debug === '*') { 45 | return true 46 | } 47 | 48 | let debuggers = debug.split(',').map((d) => d.split(':')[0]) 49 | 50 | // Ignoring tailwindcss 51 | if (debuggers.includes('-tailwindcss')) { 52 | return false 53 | } 54 | 55 | // Including tailwindcss 56 | if (debuggers.includes('tailwindcss')) { 57 | return true 58 | } 59 | 60 | return false 61 | } 62 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/lib/substituteScreenAtRules.js: -------------------------------------------------------------------------------- 1 | import { normalizeScreens } from '../util/normalizeScreens' 2 | import buildMediaQuery from '../util/buildMediaQuery' 3 | 4 | export default function ({ tailwindConfig: { theme } }) { 5 | return function (css) { 6 | css.walkAtRules('screen', (atRule) => { 7 | let screen = atRule.params 8 | let screens = normalizeScreens(theme.screens) 9 | let screenDefinition = screens.find(({ name }) => name === screen) 10 | 11 | if (!screenDefinition) { 12 | throw atRule.error(`No \`${screen}\` screen found.`) 13 | } 14 | 15 | atRule.name = 'media' 16 | atRule.params = buildMediaQuery(screenDefinition) 17 | }) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/oxide/cli.ts: -------------------------------------------------------------------------------- 1 | import './cli/index' 2 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/oxide/cli/build/index.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs' 2 | import path from 'path' 3 | import { resolveDefaultConfigPath } from '../../../util/resolveConfigPath' 4 | import { createProcessor } from './plugin' 5 | 6 | export async function build(args) { 7 | let input = args['--input'] 8 | let shouldWatch = args['--watch'] 9 | 10 | // TODO: Deprecate this in future versions 11 | if (!input && args['_'][1]) { 12 | console.error('[deprecation] Running tailwindcss without -i, please provide an input file.') 13 | input = args['--input'] = args['_'][1] 14 | } 15 | 16 | if (input && input !== '-' && !fs.existsSync((input = path.resolve(input)))) { 17 | console.error(`Specified input file ${args['--input']} does not exist.`) 18 | process.exit(9) 19 | } 20 | 21 | if (args['--config'] && !fs.existsSync((args['--config'] = path.resolve(args['--config'])))) { 22 | console.error(`Specified config file ${args['--config']} does not exist.`) 23 | process.exit(9) 24 | } 25 | 26 | // TODO: Reference the @config path here if exists 27 | let configPath = args['--config'] ? args['--config'] : resolveDefaultConfigPath() 28 | 29 | let processor = await createProcessor(args, configPath) 30 | 31 | if (shouldWatch) { 32 | // Abort the watcher if stdin is closed to avoid zombie processes 33 | // You can disable this behavior with --watch=always 34 | if (args['--watch'] !== 'always') { 35 | process.stdin.on('end', () => process.exit(0)) 36 | } 37 | 38 | process.stdin.resume() 39 | 40 | await processor.watch() 41 | } else { 42 | await processor.build().catch((e) => { 43 | console.error(e) 44 | process.exit(1) 45 | }) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/oxide/postcss-plugin.ts: -------------------------------------------------------------------------------- 1 | module.exports = require('../plugin.js') 2 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/postcss-plugins/nesting/index.js: -------------------------------------------------------------------------------- 1 | import { nesting } from './plugin' 2 | 3 | export default Object.assign( 4 | function (opts) { 5 | return { 6 | postcssPlugin: 'tailwindcss/nesting', 7 | Once(root, { result }) { 8 | return nesting(opts)(root, result) 9 | }, 10 | } 11 | }, 12 | { postcss: true } 13 | ) 14 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/public/create-plugin.js: -------------------------------------------------------------------------------- 1 | import createPlugin from '../util/createPlugin' 2 | export default createPlugin 3 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/public/default-config.js: -------------------------------------------------------------------------------- 1 | import { cloneDeep } from '../util/cloneDeep' 2 | import defaultConfig from '../../stubs/config.full' 3 | 4 | export default cloneDeep(defaultConfig) 5 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/public/default-theme.js: -------------------------------------------------------------------------------- 1 | import { cloneDeep } from '../util/cloneDeep' 2 | import defaultFullConfig from '../../stubs/config.full' 3 | 4 | export default cloneDeep(defaultFullConfig.theme) 5 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/public/load-config.js: -------------------------------------------------------------------------------- 1 | import { loadConfig } from '../lib/load-config' 2 | export default loadConfig 3 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/public/resolve-config.js: -------------------------------------------------------------------------------- 1 | import resolveConfigObjects from '../util/resolveConfig' 2 | import getAllConfigs from '../util/getAllConfigs' 3 | 4 | export default function resolveConfig(...configs) { 5 | let [, ...defaultConfigs] = getAllConfigs(configs[0]) 6 | return resolveConfigObjects([...configs, ...defaultConfigs]) 7 | } 8 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/applyImportantSelector.js: -------------------------------------------------------------------------------- 1 | import parser from 'postcss-selector-parser' 2 | import { movePseudos } from './pseudoElements' 3 | 4 | export function applyImportantSelector(selector, important) { 5 | let sel = parser().astSync(selector) 6 | 7 | sel.each((sel) => { 8 | // Wrap with :is if it's not already wrapped 9 | let isWrapped = 10 | sel.nodes[0].type === 'pseudo' && 11 | sel.nodes[0].value === ':is' && 12 | sel.nodes.every((node) => node.type !== 'combinator') 13 | 14 | if (!isWrapped) { 15 | sel.nodes = [ 16 | parser.pseudo({ 17 | value: ':is', 18 | nodes: [sel.clone()], 19 | }), 20 | ] 21 | } 22 | 23 | movePseudos(sel) 24 | }) 25 | 26 | return `${important} ${sel.toString()}` 27 | } 28 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/bigSign.js: -------------------------------------------------------------------------------- 1 | export default function bigSign(bigIntValue) { 2 | return (bigIntValue > 0n) - (bigIntValue < 0n) 3 | } 4 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/buildMediaQuery.js: -------------------------------------------------------------------------------- 1 | export default function buildMediaQuery(screens) { 2 | screens = Array.isArray(screens) ? screens : [screens] 3 | 4 | return screens 5 | .map((screen) => { 6 | let values = screen.values.map((screen) => { 7 | if (screen.raw !== undefined) { 8 | return screen.raw 9 | } 10 | 11 | return [ 12 | screen.min && `(min-width: ${screen.min})`, 13 | screen.max && `(max-width: ${screen.max})`, 14 | ] 15 | .filter(Boolean) 16 | .join(' and ') 17 | }) 18 | 19 | return screen.not ? `not all and ${values}` : values 20 | }) 21 | .join(', ') 22 | } 23 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/cloneDeep.js: -------------------------------------------------------------------------------- 1 | export function cloneDeep(value) { 2 | if (Array.isArray(value)) { 3 | return value.map((child) => cloneDeep(child)) 4 | } 5 | 6 | if (typeof value === 'object' && value !== null) { 7 | return Object.fromEntries(Object.entries(value).map(([k, v]) => [k, cloneDeep(v)])) 8 | } 9 | 10 | return value 11 | } 12 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/cloneNodes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {import('postcss').Container[]} nodes 3 | * @param {any} source 4 | * @param {any} raws 5 | * @returns {import('postcss').Container[]} 6 | */ 7 | export default function cloneNodes(nodes, source = undefined, raws = undefined) { 8 | return nodes.map((node) => { 9 | let cloned = node.clone() 10 | 11 | if (raws !== undefined) { 12 | cloned.raws.tailwind = { 13 | ...cloned.raws.tailwind, 14 | ...raws, 15 | } 16 | } 17 | 18 | if (source !== undefined) { 19 | traverse(cloned, (node) => { 20 | // Do not traverse nodes that have opted 21 | // to preserve their original source 22 | let shouldPreserveSource = node.raws.tailwind?.preserveSource === true && node.source 23 | if (shouldPreserveSource) { 24 | return false 25 | } 26 | 27 | // Otherwise we can safely replace the source 28 | // And continue traversing 29 | node.source = source 30 | }) 31 | } 32 | 33 | return cloned 34 | }) 35 | } 36 | 37 | /** 38 | * Traverse a tree of nodes and don't traverse children if the callback 39 | * returns false. Ideally we'd use Container#walk instead of this 40 | * function but it stops traversing siblings too. 41 | * 42 | * @param {import('postcss').Container} node 43 | * @param {(node: import('postcss').Container) => boolean} onNode 44 | */ 45 | function traverse(node, onNode) { 46 | if (onNode(node) !== false) { 47 | node.each?.((child) => traverse(child, onNode)) 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/configurePlugins.js: -------------------------------------------------------------------------------- 1 | export default function (pluginConfig, plugins) { 2 | if (pluginConfig === undefined) { 3 | return plugins 4 | } 5 | 6 | const pluginNames = Array.isArray(pluginConfig) 7 | ? pluginConfig 8 | : [ 9 | ...new Set( 10 | plugins 11 | .filter((pluginName) => { 12 | return pluginConfig !== false && pluginConfig[pluginName] !== false 13 | }) 14 | .concat( 15 | Object.keys(pluginConfig).filter((pluginName) => { 16 | return pluginConfig[pluginName] !== false 17 | }) 18 | ) 19 | ), 20 | ] 21 | 22 | return pluginNames 23 | } 24 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/createPlugin.js: -------------------------------------------------------------------------------- 1 | function createPlugin(plugin, config) { 2 | return { 3 | handler: plugin, 4 | config, 5 | } 6 | } 7 | 8 | createPlugin.withOptions = function (pluginFunction, configFunction = () => ({})) { 9 | const optionsFunction = function (options) { 10 | return { 11 | __options: options, 12 | handler: pluginFunction(options), 13 | config: configFunction(options), 14 | } 15 | } 16 | 17 | optionsFunction.__isOptionsFunction = true 18 | 19 | // Expose plugin dependencies so that `object-hash` returns a different 20 | // value if anything here changes, to ensure a rebuild is triggered. 21 | optionsFunction.__pluginFunction = pluginFunction 22 | optionsFunction.__configFunction = configFunction 23 | 24 | return optionsFunction 25 | } 26 | 27 | export default createPlugin 28 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/createUtilityPlugin.js: -------------------------------------------------------------------------------- 1 | import transformThemeValue from './transformThemeValue' 2 | 3 | export default function createUtilityPlugin( 4 | themeKey, 5 | utilityVariations = [[themeKey, [themeKey]]], 6 | { filterDefault = false, ...options } = {} 7 | ) { 8 | let transformValue = transformThemeValue(themeKey) 9 | return function ({ matchUtilities, theme }) { 10 | for (let utilityVariation of utilityVariations) { 11 | let group = Array.isArray(utilityVariation[0]) ? utilityVariation : [utilityVariation] 12 | 13 | matchUtilities( 14 | group.reduce((obj, [classPrefix, properties]) => { 15 | return Object.assign(obj, { 16 | [classPrefix]: (value) => { 17 | return properties.reduce((obj, name) => { 18 | if (Array.isArray(name)) { 19 | return Object.assign(obj, { [name[0]]: name[1] }) 20 | } 21 | return Object.assign(obj, { [name]: transformValue(value) }) 22 | }, {}) 23 | }, 24 | }) 25 | }, {}), 26 | { 27 | ...options, 28 | values: filterDefault 29 | ? Object.fromEntries( 30 | Object.entries(theme(themeKey) ?? {}).filter(([modifier]) => modifier !== 'DEFAULT') 31 | ) 32 | : theme(themeKey), 33 | } 34 | ) 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/defaults.js: -------------------------------------------------------------------------------- 1 | export function defaults(target, ...sources) { 2 | for (let source of sources) { 3 | for (let k in source) { 4 | if (!target?.hasOwnProperty?.(k)) { 5 | target[k] = source[k] 6 | } 7 | } 8 | 9 | for (let k of Object.getOwnPropertySymbols(source)) { 10 | if (!target?.hasOwnProperty?.(k)) { 11 | target[k] = source[k] 12 | } 13 | } 14 | } 15 | 16 | return target 17 | } 18 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/escapeClassName.js: -------------------------------------------------------------------------------- 1 | import parser from 'postcss-selector-parser' 2 | import escapeCommas from './escapeCommas' 3 | 4 | export default function escapeClassName(className) { 5 | let node = parser.className() 6 | node.value = className 7 | return escapeCommas(node?.raws?.value ?? node.value) 8 | } 9 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/escapeCommas.js: -------------------------------------------------------------------------------- 1 | export default function escapeCommas(className) { 2 | return className.replace(/\\,/g, '\\2c ') 3 | } 4 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/flattenColorPalette.js: -------------------------------------------------------------------------------- 1 | const flattenColorPalette = (colors) => 2 | Object.assign( 3 | {}, 4 | ...Object.entries(colors ?? {}).flatMap(([color, values]) => 5 | typeof values == 'object' 6 | ? Object.entries(flattenColorPalette(values)).map(([number, hex]) => ({ 7 | [color + (number === 'DEFAULT' ? '' : `-${number}`)]: hex, 8 | })) 9 | : [{ [`${color}`]: values }] 10 | ) 11 | ) 12 | 13 | export default flattenColorPalette 14 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/getAllConfigs.js: -------------------------------------------------------------------------------- 1 | import defaultFullConfig from '../../stubs/config.full.js' 2 | import { flagEnabled } from '../featureFlags' 3 | 4 | export default function getAllConfigs(config) { 5 | const configs = (config?.presets ?? [defaultFullConfig]) 6 | .slice() 7 | .reverse() 8 | .flatMap((preset) => getAllConfigs(preset instanceof Function ? preset() : preset)) 9 | 10 | const features = { 11 | // Add experimental configs here... 12 | respectDefaultRingColorOpacity: { 13 | theme: { 14 | ringColor: ({ theme }) => ({ 15 | DEFAULT: '#3b82f67f', 16 | ...theme('colors'), 17 | }), 18 | }, 19 | }, 20 | 21 | disableColorOpacityUtilitiesByDefault: { 22 | corePlugins: { 23 | backgroundOpacity: false, 24 | borderOpacity: false, 25 | divideOpacity: false, 26 | placeholderOpacity: false, 27 | ringOpacity: false, 28 | textOpacity: false, 29 | }, 30 | }, 31 | } 32 | 33 | const experimentals = Object.keys(features) 34 | .filter((feature) => flagEnabled(config, feature)) 35 | .map((feature) => features[feature]) 36 | 37 | return [config, ...experimentals, ...configs] 38 | } 39 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/hashConfig.js: -------------------------------------------------------------------------------- 1 | import hash from 'object-hash' 2 | 3 | export default function hashConfig(config) { 4 | return hash(config, { ignoreUnknown: true }) 5 | } 6 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/isKeyframeRule.js: -------------------------------------------------------------------------------- 1 | export default function isKeyframeRule(rule) { 2 | return rule.parent && rule.parent.type === 'atrule' && /keyframes$/.test(rule.parent.name) 3 | } 4 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/isPlainObject.js: -------------------------------------------------------------------------------- 1 | export default function isPlainObject(value) { 2 | if (Object.prototype.toString.call(value) !== '[object Object]') { 3 | return false 4 | } 5 | 6 | const prototype = Object.getPrototypeOf(value) 7 | return prototype === null || Object.getPrototypeOf(prototype) === null 8 | } 9 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/isSyntacticallyValidPropertyValue.js: -------------------------------------------------------------------------------- 1 | let matchingBrackets = new Map([ 2 | ['{', '}'], 3 | ['[', ']'], 4 | ['(', ')'], 5 | ]) 6 | let inverseMatchingBrackets = new Map( 7 | Array.from(matchingBrackets.entries()).map(([k, v]) => [v, k]) 8 | ) 9 | 10 | let quotes = new Set(['"', "'", '`']) 11 | 12 | // Arbitrary values must contain balanced brackets (), [] and {}. Escaped 13 | // values don't count, and brackets inside quotes also don't count. 14 | // 15 | // E.g.: w-[this-is]w-[weird-and-invalid] 16 | // E.g.: w-[this-is\\]w-\\[weird-but-valid] 17 | // E.g.: content-['this-is-also-valid]-weirdly-enough'] 18 | export default function isSyntacticallyValidPropertyValue(value) { 19 | let stack = [] 20 | let inQuotes = false 21 | 22 | for (let i = 0; i < value.length; i++) { 23 | let char = value[i] 24 | 25 | if (char === ':' && !inQuotes && stack.length === 0) { 26 | return false 27 | } 28 | 29 | // Non-escaped quotes allow us to "allow" anything in between 30 | if (quotes.has(char) && value[i - 1] !== '\\') { 31 | inQuotes = !inQuotes 32 | } 33 | 34 | if (inQuotes) continue 35 | if (value[i - 1] === '\\') continue // Escaped 36 | 37 | if (matchingBrackets.has(char)) { 38 | stack.push(char) 39 | } else if (inverseMatchingBrackets.has(char)) { 40 | let inverse = inverseMatchingBrackets.get(char) 41 | 42 | // Nothing to pop from, therefore it is unbalanced 43 | if (stack.length <= 0) { 44 | return false 45 | } 46 | 47 | // Popped value must match the inverse value, otherwise it is unbalanced 48 | if (stack.pop() !== inverse) { 49 | return false 50 | } 51 | } 52 | } 53 | 54 | // If there is still something on the stack, it is also unbalanced 55 | if (stack.length > 0) { 56 | return false 57 | } 58 | 59 | // All good, totally balanced! 60 | return true 61 | } 62 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/log.js: -------------------------------------------------------------------------------- 1 | import colors from 'picocolors' 2 | 3 | let alreadyShown = new Set() 4 | 5 | function log(type, messages, key) { 6 | if (typeof process !== 'undefined' && process.env.JEST_WORKER_ID) return 7 | 8 | if (key && alreadyShown.has(key)) return 9 | if (key) alreadyShown.add(key) 10 | 11 | console.warn('') 12 | messages.forEach((message) => console.warn(type, '-', message)) 13 | } 14 | 15 | export function dim(input) { 16 | return colors.dim(input) 17 | } 18 | 19 | export default { 20 | info(key, messages) { 21 | log(colors.bold(colors.cyan('info')), ...(Array.isArray(key) ? [key] : [messages, key])) 22 | }, 23 | warn(key, messages) { 24 | log(colors.bold(colors.yellow('warn')), ...(Array.isArray(key) ? [key] : [messages, key])) 25 | }, 26 | risk(key, messages) { 27 | log(colors.bold(colors.magenta('risk')), ...(Array.isArray(key) ? [key] : [messages, key])) 28 | }, 29 | } 30 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/nameClass.js: -------------------------------------------------------------------------------- 1 | import escapeClassName from './escapeClassName' 2 | import escapeCommas from './escapeCommas' 3 | 4 | export function asClass(name) { 5 | return escapeCommas(`.${escapeClassName(name)}`) 6 | } 7 | 8 | export default function nameClass(classPrefix, key) { 9 | return asClass(formatClass(classPrefix, key)) 10 | } 11 | 12 | export function formatClass(classPrefix, key) { 13 | if (key === 'DEFAULT') { 14 | return classPrefix 15 | } 16 | 17 | if (key === '-' || key === '-DEFAULT') { 18 | return `-${classPrefix}` 19 | } 20 | 21 | if (key.startsWith('-')) { 22 | return `-${classPrefix}${key}` 23 | } 24 | 25 | if (key.startsWith('/')) { 26 | return `${classPrefix}${key}` 27 | } 28 | 29 | return `${classPrefix}-${key}` 30 | } 31 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/negateValue.js: -------------------------------------------------------------------------------- 1 | export default function negateValue(value) { 2 | value = `${value}` 3 | 4 | if (value === '0') { 5 | return '0' 6 | } 7 | 8 | // Flip sign of numbers 9 | if (/^[+-]?(\d+|\d*\.\d+)(e[+-]?\d+)?(%|\w+)?$/.test(value)) { 10 | return value.replace(/^[+-]?/, (sign) => (sign === '-' ? '' : '-')) 11 | } 12 | 13 | // What functions we support negating numeric values for 14 | // var() isn't inherently a numeric function but we support it anyway 15 | // The trigonometric functions are omitted because you'll need to use calc(…) with them _anyway_ 16 | // to produce generally useful results and that will be covered already 17 | let numericFunctions = ['var', 'calc', 'min', 'max', 'clamp'] 18 | 19 | for (const fn of numericFunctions) { 20 | if (value.includes(`${fn}(`)) { 21 | return `calc(${value} * -1)` 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/parseDependency.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | 3 | /** 4 | * @typedef {{type: 'dependency', file: string} | {type: 'dir-dependency', dir: string, glob: string}} Dependency 5 | */ 6 | 7 | /** 8 | * 9 | * @param {import('../lib/content.js').ContentPath} contentPath 10 | * @returns {Dependency[]} 11 | */ 12 | export default function parseDependency(contentPath) { 13 | if (contentPath.ignore) { 14 | return [] 15 | } 16 | 17 | if (!contentPath.glob) { 18 | return [ 19 | { 20 | type: 'dependency', 21 | file: contentPath.base, 22 | }, 23 | ] 24 | } 25 | 26 | if (process.env.ROLLUP_WATCH === 'true') { 27 | // rollup-plugin-postcss does not support dir-dependency messages 28 | // but directories can be watched in the same way as files 29 | return [ 30 | { 31 | type: 'dependency', 32 | file: contentPath.base, 33 | }, 34 | ] 35 | } 36 | 37 | return [ 38 | { 39 | type: 'dir-dependency', 40 | dir: contentPath.base, 41 | glob: contentPath.glob, 42 | }, 43 | ] 44 | } 45 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/parseGlob.js: -------------------------------------------------------------------------------- 1 | import globParent from 'glob-parent' 2 | 3 | // Based on `glob-base` 4 | // https://github.com/micromatch/glob-base/blob/master/index.js 5 | export function parseGlob(pattern) { 6 | let glob = pattern 7 | let base = globParent(pattern) 8 | 9 | if (base !== '.') { 10 | glob = pattern.substr(base.length) 11 | if (glob.charAt(0) === '/') { 12 | glob = glob.substr(1) 13 | } 14 | } 15 | 16 | if (glob.substr(0, 2) === './') { 17 | glob = glob.substr(2) 18 | } 19 | if (glob.charAt(0) === '/') { 20 | glob = glob.substr(1) 21 | } 22 | 23 | return { base, glob } 24 | } 25 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/parseObjectStyles.js: -------------------------------------------------------------------------------- 1 | import postcss from 'postcss' 2 | import postcssNested from 'postcss-nested' 3 | import postcssJs from 'postcss-js' 4 | 5 | export default function parseObjectStyles(styles) { 6 | if (!Array.isArray(styles)) { 7 | return parseObjectStyles([styles]) 8 | } 9 | 10 | return styles.flatMap((style) => { 11 | return postcss([ 12 | postcssNested({ 13 | bubble: ['screen'], 14 | }), 15 | ]).process(style, { 16 | parser: postcssJs, 17 | }).root.nodes 18 | }) 19 | } 20 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/prefixSelector.js: -------------------------------------------------------------------------------- 1 | import parser from 'postcss-selector-parser' 2 | 3 | /** 4 | * @template {string | import('postcss-selector-parser').Root} T 5 | * 6 | * Prefix all classes in the selector with the given prefix 7 | * 8 | * It can take either a string or a selector AST and will return the same type 9 | * 10 | * @param {string} prefix 11 | * @param {T} selector 12 | * @param {boolean} prependNegative 13 | * @returns {T} 14 | */ 15 | export default function (prefix, selector, prependNegative = false) { 16 | if (prefix === '') { 17 | return selector 18 | } 19 | 20 | /** @type {import('postcss-selector-parser').Root} */ 21 | let ast = typeof selector === 'string' ? parser().astSync(selector) : selector 22 | 23 | ast.walkClasses((classSelector) => { 24 | let baseClass = classSelector.value 25 | let shouldPlaceNegativeBeforePrefix = prependNegative && baseClass.startsWith('-') 26 | 27 | classSelector.value = shouldPlaceNegativeBeforePrefix 28 | ? `-${prefix}${baseClass.slice(1)}` 29 | : `${prefix}${baseClass}` 30 | }) 31 | 32 | return typeof selector === 'string' ? ast.toString() : ast 33 | } 34 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/removeAlphaVariables.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This function removes any uses of CSS variables used as an alpha channel 3 | * 4 | * This is required for selectors like `:visited` which do not allow 5 | * changes in opacity or external control using CSS variables. 6 | * 7 | * @param {import('postcss').Container} container 8 | * @param {string[]} toRemove 9 | */ 10 | export function removeAlphaVariables(container, toRemove) { 11 | container.walkDecls((decl) => { 12 | if (toRemove.includes(decl.prop)) { 13 | decl.remove() 14 | 15 | return 16 | } 17 | 18 | for (let varName of toRemove) { 19 | if (decl.value.includes(`/ var(${varName})`)) { 20 | decl.value = decl.value.replace(`/ var(${varName})`, '') 21 | } 22 | } 23 | }) 24 | } 25 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/resolveConfigPath.js: -------------------------------------------------------------------------------- 1 | import fs from 'fs' 2 | import path from 'path' 3 | 4 | const defaultConfigFiles = [ 5 | './tailwind.config.js', 6 | './tailwind.config.cjs', 7 | './tailwind.config.mjs', 8 | './tailwind.config.ts', 9 | ] 10 | 11 | function isObject(value) { 12 | return typeof value === 'object' && value !== null 13 | } 14 | 15 | function isEmpty(obj) { 16 | return Object.keys(obj).length === 0 17 | } 18 | 19 | function isString(value) { 20 | return typeof value === 'string' || value instanceof String 21 | } 22 | 23 | export default function resolveConfigPath(pathOrConfig) { 24 | // require('tailwindcss')({ theme: ..., variants: ... }) 25 | if (isObject(pathOrConfig) && pathOrConfig.config === undefined && !isEmpty(pathOrConfig)) { 26 | return null 27 | } 28 | 29 | // require('tailwindcss')({ config: 'custom-config.js' }) 30 | if ( 31 | isObject(pathOrConfig) && 32 | pathOrConfig.config !== undefined && 33 | isString(pathOrConfig.config) 34 | ) { 35 | return path.resolve(pathOrConfig.config) 36 | } 37 | 38 | // require('tailwindcss')({ config: { theme: ..., variants: ... } }) 39 | if ( 40 | isObject(pathOrConfig) && 41 | pathOrConfig.config !== undefined && 42 | isObject(pathOrConfig.config) 43 | ) { 44 | return null 45 | } 46 | 47 | // require('tailwindcss')('custom-config.js') 48 | if (isString(pathOrConfig)) { 49 | return path.resolve(pathOrConfig) 50 | } 51 | 52 | // require('tailwindcss') 53 | return resolveDefaultConfigPath() 54 | } 55 | 56 | export function resolveDefaultConfigPath() { 57 | for (const configFile of defaultConfigFiles) { 58 | try { 59 | const configPath = path.resolve(configFile) 60 | fs.accessSync(configPath) 61 | return configPath 62 | } catch (err) {} 63 | } 64 | 65 | return null 66 | } 67 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/responsive.js: -------------------------------------------------------------------------------- 1 | import postcss from 'postcss' 2 | import cloneNodes from './cloneNodes' 3 | 4 | export default function responsive(rules) { 5 | return postcss 6 | .atRule({ 7 | name: 'responsive', 8 | }) 9 | .append(cloneNodes(Array.isArray(rules) ? rules : [rules])) 10 | } 11 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/splitAtTopLevelOnly.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This splits a string on a top-level character. 3 | * 4 | * Regex doesn't support recursion (at least not the JS-flavored version). 5 | * So we have to use a tiny state machine to keep track of paren placement. 6 | * 7 | * Expected behavior using commas: 8 | * var(--a, 0 0 1px rgb(0, 0, 0)), 0 0 1px rgb(0, 0, 0) 9 | * ─┬─ ┬ ┬ ┬ 10 | * x x x ╰──────── Split because top-level 11 | * ╰──────────────┴──┴───────────── Ignored b/c inside >= 1 levels of parens 12 | * 13 | * @param {string} input 14 | * @param {string} separator 15 | */ 16 | export function splitAtTopLevelOnly(input, separator) { 17 | let stack = [] 18 | let parts = [] 19 | let lastPos = 0 20 | let isEscaped = false 21 | 22 | for (let idx = 0; idx < input.length; idx++) { 23 | let char = input[idx] 24 | 25 | if (stack.length === 0 && char === separator[0] && !isEscaped) { 26 | if (separator.length === 1 || input.slice(idx, idx + separator.length) === separator) { 27 | parts.push(input.slice(lastPos, idx)) 28 | lastPos = idx + separator.length 29 | } 30 | } 31 | 32 | if (isEscaped) { 33 | isEscaped = false 34 | } else if (char === '\\') { 35 | isEscaped = true 36 | } 37 | 38 | if (char === '(' || char === '[' || char === '{') { 39 | stack.push(char) 40 | } else if ( 41 | (char === ')' && stack[stack.length - 1] === '(') || 42 | (char === ']' && stack[stack.length - 1] === '[') || 43 | (char === '}' && stack[stack.length - 1] === '{') 44 | ) { 45 | stack.pop() 46 | } 47 | } 48 | 49 | parts.push(input.slice(lastPos)) 50 | 51 | return parts 52 | } 53 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/tap.js: -------------------------------------------------------------------------------- 1 | export function tap(value, mutator) { 2 | mutator(value) 3 | return value 4 | } 5 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/toColorValue.js: -------------------------------------------------------------------------------- 1 | export default function toColorValue(maybeFunction) { 2 | return typeof maybeFunction === 'function' ? maybeFunction({}) : maybeFunction 3 | } 4 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/toPath.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Parse a path string into an array of path segments. 3 | * 4 | * Square bracket notation `a[b]` may be used to "escape" dots that would otherwise be interpreted as path separators. 5 | * 6 | * Example: 7 | * a -> ['a'] 8 | * a.b.c -> ['a', 'b', 'c'] 9 | * a[b].c -> ['a', 'b', 'c'] 10 | * a[b.c].e.f -> ['a', 'b.c', 'e', 'f'] 11 | * a[b][c][d] -> ['a', 'b', 'c', 'd'] 12 | * 13 | * @param {string|string[]} path 14 | **/ 15 | export function toPath(path) { 16 | if (Array.isArray(path)) return path 17 | 18 | let openBrackets = path.split('[').length - 1 19 | let closedBrackets = path.split(']').length - 1 20 | 21 | if (openBrackets !== closedBrackets) { 22 | throw new Error(`Path is invalid. Has unbalanced brackets: ${path}`) 23 | } 24 | 25 | return path.split(/\.(?![^\[]*\])|[\[\]]/g).filter(Boolean) 26 | } 27 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/validateConfig.js: -------------------------------------------------------------------------------- 1 | import log from './log' 2 | 3 | export function validateConfig(config) { 4 | if (config.content.files.length === 0) { 5 | log.warn('content-problems', [ 6 | 'The `content` option in your Tailwind CSS configuration is missing or empty.', 7 | 'Configure your content sources or your generated CSS will be missing styles.', 8 | 'https://tailwindcss.com/docs/content-configuration', 9 | ]) 10 | } 11 | 12 | // Warn if the line-clamp plugin is installed 13 | try { 14 | let plugin = require('@tailwindcss/line-clamp') 15 | if (config.plugins.includes(plugin)) { 16 | log.warn('line-clamp-in-core', [ 17 | 'As of Tailwind CSS v3.3, the `@tailwindcss/line-clamp` plugin is now included by default.', 18 | 'Remove it from the `plugins` array in your configuration to eliminate this warning.', 19 | ]) 20 | 21 | config.plugins = config.plugins.filter((p) => p !== plugin) 22 | } 23 | } catch {} 24 | 25 | return config 26 | } 27 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/validateFormalSyntax.js: -------------------------------------------------------------------------------- 1 | import { length, percentage } from './dataTypes' 2 | import { splitAtTopLevelOnly } from './splitAtTopLevelOnly' 3 | 4 | /** 5 | * 6 | * https://developer.mozilla.org/en-US/docs/Web/CSS/background-size#formal_syntax 7 | * 8 | * background-size = 9 | * # 10 | * 11 | * = 12 | * [ | auto ]{1,2} | 13 | * cover | 14 | * contain 15 | * 16 | * = 17 | * | 18 | * 19 | * 20 | * @param {string} value 21 | */ 22 | export function backgroundSize(value) { 23 | let keywordValues = ['cover', 'contain'] 24 | // the type will probably be a css function 25 | // so we have to use `splitAtTopLevelOnly` 26 | return splitAtTopLevelOnly(value, ',').every((part) => { 27 | let sizes = splitAtTopLevelOnly(part, '_').filter(Boolean) 28 | if (sizes.length === 1 && keywordValues.includes(sizes[0])) return true 29 | 30 | if (sizes.length !== 1 && sizes.length !== 2) return false 31 | 32 | return sizes.every((size) => length(size) || percentage(size) || size === 'auto') 33 | }) 34 | } 35 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/util/withAlphaVariable.js: -------------------------------------------------------------------------------- 1 | import { parseColor, formatColor } from './color' 2 | 3 | export function withAlphaValue(color, alphaValue, defaultValue) { 4 | if (typeof color === 'function') { 5 | return color({ opacityValue: alphaValue }) 6 | } 7 | 8 | let parsed = parseColor(color, { loose: true }) 9 | 10 | if (parsed === null) { 11 | return defaultValue 12 | } 13 | 14 | return formatColor({ ...parsed, alpha: alphaValue }) 15 | } 16 | 17 | export default function withAlphaVariable({ color, property, variable }) { 18 | let properties = [].concat(property) 19 | if (typeof color === 'function') { 20 | return { 21 | [variable]: '1', 22 | ...Object.fromEntries( 23 | properties.map((p) => { 24 | return [p, color({ opacityVariable: variable, opacityValue: `var(${variable})` })] 25 | }) 26 | ), 27 | } 28 | } 29 | 30 | const parsed = parseColor(color) 31 | 32 | if (parsed === null) { 33 | return Object.fromEntries(properties.map((p) => [p, color])) 34 | } 35 | 36 | if (parsed.alpha !== undefined) { 37 | // Has an alpha value, return color as-is 38 | return Object.fromEntries(properties.map((p) => [p, color])) 39 | } 40 | 41 | return { 42 | [variable]: '1', 43 | ...Object.fromEntries( 44 | properties.map((p) => { 45 | return [p, formatColor({ ...parsed, alpha: `var(${variable})` })] 46 | }) 47 | ), 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/value-parser/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) Bogdan Chadkin 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/value-parser/README.md: -------------------------------------------------------------------------------- 1 | # postcss-value-parser (forked + inlined) 2 | 3 | This is a customized version of of [PostCSS Value Parser](https://github.com/TrySound/postcss-value-parser) to fix some bugs around parsing CSS functions. 4 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/value-parser/index.js: -------------------------------------------------------------------------------- 1 | var parse = require('./parse') 2 | var walk = require('./walk') 3 | var stringify = require('./stringify') 4 | 5 | function ValueParser(value) { 6 | if (this instanceof ValueParser) { 7 | this.nodes = parse(value) 8 | return this 9 | } 10 | return new ValueParser(value) 11 | } 12 | 13 | ValueParser.prototype.toString = function () { 14 | return Array.isArray(this.nodes) ? stringify(this.nodes) : '' 15 | } 16 | 17 | ValueParser.prototype.walk = function (cb, bubble) { 18 | walk(this.nodes, cb, bubble) 19 | return this 20 | } 21 | 22 | ValueParser.unit = require('./unit') 23 | 24 | ValueParser.walk = walk 25 | 26 | ValueParser.stringify = stringify 27 | 28 | module.exports = ValueParser 29 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/value-parser/stringify.js: -------------------------------------------------------------------------------- 1 | function stringifyNode(node, custom) { 2 | var type = node.type 3 | var value = node.value 4 | var buf 5 | var customResult 6 | 7 | if (custom && (customResult = custom(node)) !== undefined) { 8 | return customResult 9 | } else if (type === 'word' || type === 'space') { 10 | return value 11 | } else if (type === 'string') { 12 | buf = node.quote || '' 13 | return buf + value + (node.unclosed ? '' : buf) 14 | } else if (type === 'comment') { 15 | return '/*' + value + (node.unclosed ? '' : '*/') 16 | } else if (type === 'div') { 17 | return (node.before || '') + value + (node.after || '') 18 | } else if (Array.isArray(node.nodes)) { 19 | buf = stringify(node.nodes, custom) 20 | if (type !== 'function') { 21 | return buf 22 | } 23 | return value + '(' + (node.before || '') + buf + (node.after || '') + (node.unclosed ? '' : ')') 24 | } 25 | return value 26 | } 27 | 28 | function stringify(nodes, custom) { 29 | var result, i 30 | 31 | if (Array.isArray(nodes)) { 32 | result = '' 33 | for (i = nodes.length - 1; ~i; i -= 1) { 34 | result = stringifyNode(nodes[i], custom) + result 35 | } 36 | return result 37 | } 38 | return stringifyNode(nodes, custom) 39 | } 40 | 41 | module.exports = stringify 42 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/src/value-parser/walk.js: -------------------------------------------------------------------------------- 1 | module.exports = function walk(nodes, cb, bubble) { 2 | var i, max, node, result 3 | 4 | for (i = 0, max = nodes.length; i < max; i += 1) { 5 | node = nodes[i] 6 | if (!bubble) { 7 | result = cb(node, i, nodes) 8 | } 9 | 10 | if (result !== false && node.type === 'function' && Array.isArray(node.nodes)) { 11 | walk(node.nodes, cb, bubble) 12 | } 13 | 14 | if (bubble) { 15 | cb(node, i, nodes) 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/stubs/.npmignore: -------------------------------------------------------------------------------- 1 | !* 2 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/stubs/.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 120, 3 | "semi": false, 4 | "singleQuote": true, 5 | "trailingComma": "es5" 6 | } 7 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/stubs/config.simple.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | content: [], 3 | theme: { 4 | extend: {}, 5 | }, 6 | plugins: [], 7 | } 8 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/stubs/postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/stubs/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/stubs/tailwind.config.cjs: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = __CONFIG__ 3 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/stubs/tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | export default __CONFIG__ 3 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/stubs/tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from 'tailwindcss' 2 | 3 | export default __CONFIG__ satisfies Config 4 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/tailwind.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | 3 | @tailwind components; 4 | 5 | @tailwind utilities; 6 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/types/generated/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stackwiseai/stackwise/c49a192df253bea4d6c8889049816cbcbb57cce1/tooling/tailwind-config/node_modules/tailwindcss/types/generated/.gitkeep -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/types/index.d.ts: -------------------------------------------------------------------------------- 1 | import type { PluginCreator } from 'postcss' 2 | import type { Config } from 'tailwindcss/types/config' 3 | 4 | declare const plugin: PluginCreator 5 | 6 | declare type _Config = Config 7 | declare namespace plugin { 8 | export type { _Config as Config } 9 | } 10 | 11 | export = plugin 12 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/utilities.css: -------------------------------------------------------------------------------- 1 | @tailwind utilities; 2 | -------------------------------------------------------------------------------- /tooling/tailwind-config/node_modules/tailwindcss/variants.css: -------------------------------------------------------------------------------- 1 | @tailwind variants; 2 | -------------------------------------------------------------------------------- /tooling/tailwind-config/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@stackwise-tooling/tailwind-config", 3 | "version": "0.1.0", 4 | "private": true, 5 | "main": "index.ts", 6 | "license": "MIT", 7 | "files": [ 8 | "index.ts" 9 | ], 10 | "scripts": { 11 | "clean": "rm -rf .turbo node_modules", 12 | "lint": "eslint .", 13 | "format": "prettier --check . --ignore-path ../../.gitignore", 14 | "typecheck": "tsc --noEmit" 15 | }, 16 | "dependencies": { 17 | "autoprefixer": "^10.4.16", 18 | "tailwindcss": "3.3.6" 19 | }, 20 | "devDependencies": { 21 | "@stackwise-tooling/eslint-config": "*", 22 | "@stackwise-tooling/prettier-config": "*", 23 | "@stackwise-tooling/tsconfig": "*", 24 | "eslint": "^8.55.0", 25 | "prettier": "^3.1.0", 26 | "typescript": "^5.3.2" 27 | }, 28 | "eslintConfig": { 29 | "root": true, 30 | "extends": [ 31 | "@stackwise-tooling/eslint-config/base" 32 | ] 33 | }, 34 | "prettier": "@stackwise-tooling/prettier-config" 35 | } 36 | -------------------------------------------------------------------------------- /tooling/tailwind-config/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@stackwise-tooling/tsconfig/base.json", 3 | "compilerOptions": { 4 | "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json" 5 | }, 6 | "include": ["."], 7 | "exclude": ["node_modules"] 8 | } 9 | -------------------------------------------------------------------------------- /tooling/tsconfig/base.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "noEmit": true, 8 | "esModuleInterop": true, 9 | "module": "esnext", 10 | "moduleResolution": "bundler", 11 | "resolveJsonModule": true, 12 | "isolatedModules": true, 13 | "jsx": "preserve", 14 | "incremental": true, 15 | "strict": false, 16 | "strictNullChecks": true, 17 | "noImplicitAny": false, 18 | "noImplicitThis": false, 19 | "alwaysStrict": false, 20 | "plugins": [ 21 | { 22 | "name": "next" 23 | } 24 | ], 25 | "paths": { 26 | "@/*": ["./*"] 27 | } 28 | }, 29 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", "app/stacks/[slug]"], 30 | "exclude": ["node_modules", "scripts"] 31 | } 32 | -------------------------------------------------------------------------------- /tooling/tsconfig/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@stackwise-tooling/tsconfig", 3 | "private": true, 4 | "version": "0.1.0", 5 | "files": [ 6 | "base.json" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@stackwise-tooling/tsconfig/base.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "@/*": ["./*"] 7 | }, 8 | "plugins": [ 9 | { 10 | "name": "next" 11 | } 12 | ], 13 | "tsBuildInfoFile": "node_modules/.cache/tsbuildinfo.json" 14 | }, 15 | "include": [".", ".next/types/**/*.ts"], 16 | "exclude": ["node_modules"] 17 | } 18 | --------------------------------------------------------------------------------