├── .changeset ├── README.md └── config.json ├── .dockerignore ├── .github └── workflows │ ├── ci.yml │ ├── release.yml │ └── website-docs.yml ├── .gitignore ├── .husky └── pre-commit ├── .vscode └── extensions.json ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── apps ├── api │ ├── CHANGELOG.md │ ├── Dockerfile │ ├── Dockerfile.dev │ ├── README.md │ ├── biome.json │ ├── docker-compose.yml │ ├── package.json │ ├── prisma │ │ ├── migrations │ │ │ ├── 20230425065839_initial │ │ │ │ └── migration.sql │ │ │ └── migration_lock.toml │ │ ├── schema.prisma │ │ └── taco.db │ ├── scripts │ │ └── build.ts │ ├── src │ │ ├── app.ts │ │ ├── infrastructure │ │ │ ├── env.ts │ │ │ ├── primaClient.ts │ │ │ └── seed │ │ │ │ ├── amino-acids.ts │ │ │ │ ├── categories.ts │ │ │ │ ├── fatty-acids.ts │ │ │ │ ├── foods.ts │ │ │ │ ├── index.ts │ │ │ │ ├── nutrients.ts │ │ │ │ └── units │ │ │ │ ├── index.ts │ │ │ │ ├── types.ts │ │ │ │ └── unitsToSave.ts │ │ └── modules │ │ │ ├── aminoAcid │ │ │ ├── index.ts │ │ │ ├── schema.ts │ │ │ └── typeDef.ts │ │ │ ├── category │ │ │ ├── index.ts │ │ │ ├── schema.ts │ │ │ └── typeDef.ts │ │ │ ├── fattyAcid │ │ │ ├── index.ts │ │ │ ├── schema.ts │ │ │ └── typeDef.ts │ │ │ ├── food │ │ │ ├── index.ts │ │ │ ├── schema.ts │ │ │ └── typeDef.ts │ │ │ ├── index.ts │ │ │ ├── main │ │ │ ├── index.ts │ │ │ └── schema.ts │ │ │ ├── nutrient │ │ │ ├── index.ts │ │ │ ├── schema.ts │ │ │ └── typeDef.ts │ │ │ └── unit │ │ │ ├── index.ts │ │ │ ├── schema.ts │ │ │ └── typeDefs.ts │ └── tsconfig.json └── website │ ├── .gitignore │ ├── README.md │ ├── astro.config.mjs │ ├── package.json │ ├── public │ └── favicon.svg │ ├── src │ ├── assets │ │ └── graphql-playground.png │ ├── content │ │ ├── config.ts │ │ └── docs │ │ │ ├── about.mdx │ │ │ ├── api-docs.mdx │ │ │ ├── contributing.mdx │ │ │ ├── data-processing.mdx │ │ │ ├── database.mdx │ │ │ ├── deploy-docker.mdx │ │ │ ├── deploy-node.mdx │ │ │ ├── en │ │ │ ├── about.mdx │ │ │ ├── api-docs.mdx │ │ │ ├── contributing.mdx │ │ │ ├── data-processing.mdx │ │ │ ├── database.mdx │ │ │ ├── deploy-docker.mdx │ │ │ ├── deploy-node.mdx │ │ │ ├── faq.mdx │ │ │ ├── getting-started.mdx │ │ │ └── tech.mdx │ │ │ ├── faq.mdx │ │ │ ├── getting-started.mdx │ │ │ └── tech.mdx │ └── env.d.ts │ └── tsconfig.json ├── biome.json ├── bun.lock ├── package.json ├── references ├── README.md ├── csv │ ├── amino-acids.csv │ ├── categories.csv │ ├── fatty-acids.csv │ ├── food.csv │ └── nutrients.csv ├── normalization │ ├── taco_phase_1_no_format.xlsx │ ├── taco_phase_2_normalize_values.xlsx │ ├── taco_phase_3_rename_labels.xlsx │ ├── taco_phase_4_decouple_category.xlsx │ └── taco_phase_5_decouple_food.xlsx ├── original-Taco_4a_edicao_2011.xls └── taco_4_edicao_ampliada_e_revisada.pdf ├── scripts ├── build-image.ts └── fix-graphql-types.ts ├── tsconfig.json └── turbo.json /.changeset/README.md: -------------------------------------------------------------------------------- 1 | # Changesets 2 | 3 | Hello and welcome! This folder has been automatically generated by `@changesets/cli`, a build tool that works 4 | with multi-package repos, or single-package repos to help you version and publish your code. You can 5 | find the full documentation for it [in our repository](https://github.com/changesets/changesets) 6 | 7 | We have a quick list of common questions to get you started engaging with this project in 8 | [our documentation](https://github.com/changesets/changesets/blob/main/docs/common-questions.md) 9 | -------------------------------------------------------------------------------- /.changeset/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://unpkg.com/@changesets/config@2.3.1/schema.json", 3 | "changelog": "@changesets/cli/changelog", 4 | "commit": false, 5 | "fixed": [], 6 | "linked": [], 7 | "access": "restricted", 8 | "baseBranch": "main", 9 | "updateInternalDependencies": "patch", 10 | "ignore": ["website"] 11 | } 12 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .changeset 2 | .dockerignore 3 | .env 4 | .git 5 | .github 6 | .gitignore 7 | .history 8 | .husky 9 | .vscode 10 | coverage* 11 | Dockerfile* 12 | documentation 13 | LICENSE 14 | node_modules 15 | README.md 16 | references 17 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - name: Checkout to repository 10 | uses: actions/checkout@v4.1.1 11 | 12 | - name: Setup Bun 13 | uses: oven-sh/setup-bun@v1 14 | with: 15 | bun-version: 1.2.2 16 | 17 | - name: Install Dependencies 18 | run: bun install --frozen-lockfile --no-cache 19 | 20 | # Necessary because it's being used in the code 21 | - name: Linting/Formating 22 | run: bun run lint:ci 23 | 24 | - name: Build 25 | run: bun run build 26 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | concurrency: ${{ github.workflow }}-${{ github.ref }} 9 | 10 | jobs: 11 | release: 12 | name: Release 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout Repo 16 | uses: actions/checkout@v4.1.1 17 | 18 | - name: Setup Bun 19 | uses: oven-sh/setup-bun@v1 20 | with: 21 | bun-version: 1.2.2 22 | 23 | - name: Install Dependencies 24 | run: bun install --frozen-lockfile --no-cache 25 | 26 | - name: Create Release Pull Request 27 | id: changesets 28 | uses: changesets/action@v1.4.5 29 | env: 30 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 31 | with: 32 | createGithubReleases: true 33 | 34 | - name: Login to Docker Hub 35 | uses: docker/login-action@v3 36 | if: steps.changesets.outputs.hasChangesets == 'false' 37 | with: 38 | username: raulfdm 39 | password: ${{ secrets.DOCKERHUB_TOKEN }} 40 | 41 | - name: Build and Push Docker Image 42 | if: steps.changesets.outputs.hasChangesets == 'false' 43 | run: bun run image:build --deploy 44 | -------------------------------------------------------------------------------- /.github/workflows/website-docs.yml: -------------------------------------------------------------------------------- 1 | name: Website Docs 2 | 3 | on: [push] 4 | 5 | permissions: 6 | pull-requests: write 7 | 8 | env: 9 | BRANCH_NAME: ${{ github.head_ref || github.ref_name }} 10 | 11 | jobs: 12 | website: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Checkout to repository 16 | uses: actions/checkout@v4.1.1 17 | 18 | - name: Setup Bun 19 | uses: oven-sh/setup-bun@v1 20 | with: 21 | bun-version: 1.2.2 22 | 23 | - name: Install dependencies 24 | run: bun install --no-cache 25 | 26 | - name: Add Netlify CLI globally 27 | run: bun add -g netlify-cli@17.10.1 28 | 29 | - name: Build website 30 | run: bun run build --filter=website 31 | 32 | - name: Deploy to Netlify 33 | id: netlify_deploy 34 | run: | 35 | additional_flags="" 36 | if [ "$BRANCH_NAME" = "main" ]; then additional_flags="--prod"; fi 37 | netlify deploy \ 38 | --dir apps/website/dist \ 39 | --site ${{ secrets.NETLIFY_SITE_ID }} \ 40 | --filter taco-api \ 41 | --auth ${{ secrets.NETLIFY_AUTH_TOKEN }} \ 42 | $additional_flags \ 43 | > deploy_output.txt 44 | 45 | - name: Generate URL Preview 46 | id: url_preview 47 | if: ${{ env.BRANCH_NAME != 'main' }} 48 | run: | 49 | NETLIFY_PREVIEW_URL=$(cat deploy_output.txt | grep "Website draft URL: " | cut -d' ' -f4) 50 | echo "NETLIFY_PREVIEW_URL=$NETLIFY_PREVIEW_URL" >> "$GITHUB_OUTPUT" 51 | 52 | - name: Comment URL Preview on PR 53 | uses: actions/github-script@v7 54 | if: ${{ env.BRANCH_NAME != 'main' }} 55 | env: 56 | NETLIFY_PREVIEW_URL: ${{ steps.url_preview.outputs.NETLIFY_PREVIEW_URL }} 57 | with: 58 | github-token: ${{ secrets.GITHUB_TOKEN }} 59 | script: | 60 | async function comment(){ 61 | const result = await github.rest.repos.listPullRequestsAssociatedWithCommit({ 62 | owner: context.repo.owner, 63 | repo: context.repo.repo, 64 | commit_sha: context.sha, 65 | }) 66 | 67 | const issueNumber = result.data[0].number 68 | 69 | if(issueNumber){ 70 | await github.rest.issues.createComment({ 71 | issue_number: issueNumber, 72 | owner: context.repo.owner, 73 | repo: context.repo.repo, 74 | body: 'Preview URL: ' + process.env.NETLIFY_PREVIEW_URL 75 | }) 76 | }else{ 77 | console.log('No PR found for commit ' + context.sha) 78 | } 79 | } 80 | 81 | comment() 82 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # parcel-bundler cache (https://parceljs.org/) 61 | .cache 62 | 63 | # next.js build output 64 | .next 65 | 66 | # nuxt.js build output 67 | .nuxt 68 | 69 | # vuepress build output 70 | .vuepress/dist 71 | 72 | # Serverless directories 73 | .serverless 74 | 75 | ## macOS 76 | .DS_Store 77 | 78 | ## Misc 79 | .temp 80 | .cache 81 | documentation/.vuepress/dist 82 | dist/ 83 | .turbo 84 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | . "$(dirname -- "$0")/_/husky.sh" 3 | 4 | bunx lint-staged 5 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "astro-build.astro-vscode", 4 | "prisma.prisma", 5 | "biomejs.biome" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 2.3.0 4 | 5 | ### Minor Changes 6 | 7 | - 003ecdb: Minor updates 8 | 9 | - update from node18 to node20; 10 | - bump all dev and prod dependencies to its latest versions; 11 | - add `packageManager` to package.json; 12 | - add `.nvmrc` to enforce node version; 13 | - pin `pnpm` on Docker image; 14 | 15 | ## 2.2.0 16 | 17 | ### Minor Changes 18 | 19 | - aa9b51c: update all dependencies, including [Prisma 5](https://www.prisma.io/blog/prisma-5-f66prwkjx72s) which brings huge performance improvement 20 | - aa9b51c: add a build step and run the production with node itself instead `tsx` 21 | 22 | All notable changes to this project will be documented in this file. 23 | 24 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 25 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 26 | 27 | 36 | 37 | ## [2.1.0] 38 | 39 | ### What has changed? 40 | 41 | - add new `getFoodByName` query: 42 | 43 | ```gql 44 | query FoodByName { 45 | getFoodByName(name: "carne") { 46 | name 47 | } 48 | } 49 | ``` 50 | 51 | ## [2.0.0] 52 | 53 | This is the major change after 5 years of this project creation. 54 | 55 | I've decided to revamp completely the project using modern tech and implementing a few features some people asked a couple years ago. 56 | 57 | ### What has changed? 58 | 59 | The main change here is now the project is complete type-safe thanks to [Prisma](https://prisma.io). 60 | 61 | Also, instead Rest API, I've decide to switch completely to GraphQL. This will makes the documentation and the ability to fetch data easier. 62 | 63 | ### all changes 64 | 65 | - refactor everything to TypeScript; 66 | - re-done the data processing to fix data mistakes such as keeping strings with numbers; 67 | - remove APIDoc in favor of GraphQL api docs; 68 | - update docs; 69 | - switch from `npm` to `pnpm`; 70 | - use relational database (`SQLite`) instead local `json` files for storing data; 71 | - implement filter ability. Now for in a few endpoints you can pass `skip` and `take` ([see more here](https://www.prisma.io/docs/concepts/components/prisma-client/pagination#offset-pagination)); 72 | - migrate to Node18; 73 | - use full ESM instead CJS; 74 | 75 | ## [1.0.1] 76 | 77 | - tag docker image with `v1` 78 | 79 | ## [1.0.0] 80 | 81 | - create a tag version to prep v2 to get in place 82 | 83 | ## [0.1.0] 84 | 85 | ### Added 86 | 87 | - MIT License; 88 | - Changelog file; 89 | - CI with Travis; 90 | - Unit/integration tests with Jest; 91 | - Prettier/eslint to keep code quality; 92 | - API Documentation with [apidocJS](http://apidocjs.com/#param-api-success) 93 | 94 | ### Changed 95 | 96 | - Improve `package.json` information; 97 | - Rename all files/methods/code in general to ENGLISH; 98 | - Refactor routes 99 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright 2022 Raul de Melo 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Taco GraphQL API 2 | 3 | > Brazilian Table of Food Composition 4 | 5 | ![GraphQL Client](/apps/website/src/assets/graphql-playground.png) 6 | 7 |

8 | 9 | build status 11 | 12 |

13 | 14 | ## Getting started 15 | 16 | [https://taco-api.netlify.app/getting-started/](https://taco-api.netlify.app/getting-started/) 17 | 18 | ## Structure 19 | 20 | This project is a monorepo: 21 | 22 | - [The API project](./apps/api/) 23 | - [The DOCs project](./apps/website) 24 | 25 | The monorepo handling is done by Turbo and Bun. 26 | 27 | ## Docs 28 | 29 | For more details about this API, check the official docs: 30 | 31 | - [Portuguese](https://taco-api.netlify.app/about) 32 | - [English](https://taco-api.netlify.app/en/about) 33 | 34 | ## License 35 | 36 | [MIT](./LICENSE.md) 37 | -------------------------------------------------------------------------------- /apps/api/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # taco-api 2 | 3 | ## 4.0.1 4 | 5 | ### Patch Changes 6 | 7 | - 7fce14c: Fix Dockerfile 8 | 9 | ## 4.0.0 10 | 11 | ### Major Changes 12 | 13 | - 38d751c: Upgrade all dependencies 14 | 15 | In theory, nothing has changed except the dependencies version. This is a major because I've migrated from Prisma 5 to 6. 16 | 17 | ## 3.2.0 18 | 19 | ### Minor Changes 20 | 21 | - eba8667: update dependencies 22 | 23 | ### Patch Changes 24 | 25 | - eba8667: fix dev and start command 26 | 27 | ## 3.1.0 28 | 29 | ### Minor Changes 30 | 31 | - 12d8a88: build api with --compile and reduce the docker image 76%~ 32 | 33 | ## 3.0.2 34 | 35 | ### Patch Changes 36 | 37 | - 76e7f1a: update bun to 1.0.20 38 | 39 | ## 3.0.1 40 | 41 | ### Patch Changes 42 | 43 | - 5257a21: fix optional options 44 | 45 | ## 3.0.0 46 | 47 | ### Major Changes 48 | 49 | - 65ccf6d: replace express with elysia. 50 | 51 | Taco API now runs on top of bun and we have faster and better HTTP frameworks. 52 | 53 | We don't do anything fancy that only express could do. To provide an HTTP client for a single endpoint, we can rely on something more modern. 54 | 55 | - bc854f6: Switch from node to bun 56 | 57 | In case you don't know bun, I strongly recommend you to take a look in [their docs](https://bun.sh/). In summary, it's a fast JavaScript runtime that provides tons of performance and great nodejs compat. 58 | 59 | The advantage of using Bun instead Node is: 60 | 61 | - We don't need `tsx` for handling TypeScript files (such as scripts) or running the dev locally; 62 | - We don't need `esbuild` to build the final file; 63 | - We don't need `pnpm` to install dependencies; 64 | - everything is fast 65 | 66 | Though, because we're using Prisma and it relies on NodeJS to do some generation, you may still have Node installed. 67 | 68 | Some differences from the previous setup: 69 | 70 | Install dependencies: 71 | 72 | ```diff 73 | -pnpm install 74 | +bun install 75 | ``` 76 | 77 | Run dev server: 78 | 79 | ```diff 80 | -pnpm run dev 81 | +bun run dev 82 | ``` 83 | 84 | Build the project: 85 | 86 | ```diff 87 | -pnpm run build 88 | +bun run build 89 | ``` 90 | 91 | etc.. 92 | 93 | Because we're changing the runner, it's a major bump. If you still want to use Node, I'd recommend you to be in the version 2. 94 | 95 | - 5384de3: new docs website. 96 | 97 | Now, instead using vuepress, I've switch to starlight and refactor the whole docs. 98 | -------------------------------------------------------------------------------- /apps/api/Dockerfile: -------------------------------------------------------------------------------- 1 | # It needs to be node. Prisma still depends on something from node 2 | # to generate the client. 3 | FROM node:20-slim as base 4 | 5 | # Install OpenSSL. Required for prisma to work. 6 | RUN apt-get update -y && apt-get install -y openssl 7 | 8 | WORKDIR /app 9 | 10 | # Install bun to be available in all stages. 11 | RUN npm install -g bun@1.2.2 12 | 13 | FROM base as setup 14 | 15 | COPY package.json bun.lock ./ 16 | COPY /apps/api/package.json ./apps/api/package.json 17 | COPY /apps/website/package.json ./apps/website/package.json 18 | COPY /scripts/fix-graphql-types.ts ./scripts/fix-graphql-types.ts 19 | 20 | RUN bun install 21 | 22 | COPY . . 23 | 24 | RUN bun run db:generate --filter=taco-api 25 | # this build command generates a standalone binary 26 | RUN bun run build --filter=taco-api 27 | 28 | # node:20-slim is based on debian:bookworm-slim, but I don't want node 29 | FROM debian:bookworm-slim as release 30 | 31 | # Install OpenSSL. Required for prisma to work. 32 | RUN apt-get update -y && apt-get install -y openssl 33 | 34 | COPY --from=setup /app/apps/api/dist/taco-api-standalone . 35 | COPY --from=setup /app/node_modules/.prisma ./node_modules/.prisma 36 | COPY --from=setup /app/apps/api/prisma ./apps/api/prisma 37 | 38 | # run the app 39 | EXPOSE 4000 40 | ENV NODE_ENV production 41 | ENTRYPOINT ./taco-api-standalone -------------------------------------------------------------------------------- /apps/api/Dockerfile.dev: -------------------------------------------------------------------------------- 1 | # It needs to be node. Prisma still depends on something from node 2 | # to generate the client. 3 | FROM node:20-slim as base 4 | 5 | # Install OpenSSL. Required for prisma to work. 6 | RUN apt-get update -y && apt-get install -y openssl 7 | 8 | WORKDIR /app 9 | 10 | RUN npm install -g bun@1.2.2 11 | 12 | # Setup 13 | COPY package.json bun.lock ./ 14 | COPY /apps/api/package.json /app/apps/api/package.json 15 | COPY /apps/website/package.json /app/apps/website/package.json 16 | 17 | RUN --mount=type=cache,id=buncache,target=/root/.bun/install/cache\ 18 | bun install --frozen-lockfile --ignore-scripts 19 | 20 | COPY . . 21 | 22 | EXPOSE 4000 23 | ENTRYPOINT bun run dev --filter=taco-api -------------------------------------------------------------------------------- /apps/api/README.md: -------------------------------------------------------------------------------- 1 | # Taco GraphQL API 2 | 3 | For more info, please refer to the docs: 4 | 5 | - [Portuguese](https://taco-api.netlify.app/) 6 | - [English](https://taco-api.netlify.app/en) 7 | -------------------------------------------------------------------------------- /apps/api/biome.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://biomejs.dev/schemas/1.4.0/schema.json", 3 | "extends": ["../../biome.json"] 4 | } 5 | -------------------------------------------------------------------------------- /apps/api/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.9' 2 | 3 | services: 4 | taco_api_dev: 5 | working_dir: /app 6 | build: 7 | context: ../../ 8 | dockerfile: ./apps/api/Dockerfile.dev 9 | environment: 10 | PORT: 4000 11 | 12 | ports: 13 | - 4000:4000 14 | -------------------------------------------------------------------------------- /apps/api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "taco-api", 3 | "description": "Brazilian Table of Food Composition (TACO) - GraphQL API", 4 | "version": "4.0.1", 5 | "type": "module", 6 | "homepage": "https://github.com/raulfdm/taco-api", 7 | "bugs": { 8 | "url": "https://github.com/raulfdm/taco-api/issues" 9 | }, 10 | "scripts": { 11 | "start": "bun run build && NODE_ENV=production ./dist/taco-api-standalone", 12 | "dev": "prisma generate && NODE_ENV=development bun --watch src/app.ts", 13 | "studio": "prisma studio", 14 | "build": "bun build src/app.ts --compile --outfile dist/taco-api-standalone", 15 | "lint": "biome lint src", 16 | "lint:ci": "biome ci src", 17 | "db:migrate": "NODE_ENV=development prisma migrate dev", 18 | "db:generate": "prisma generate", 19 | "db:seed": "NODE_ENV=development prisma db seed", 20 | "db:reset": "NODE_ENV=development prisma migrate reset" 21 | }, 22 | "dependencies": { 23 | "@elysiajs/cors": "1.2.0", 24 | "@elysiajs/graphql-yoga": "1.2.0", 25 | "@envelop/graphql-modules": "6.0.0", 26 | "@prisma/client": "6.3.1", 27 | "elysia": "1.2.12", 28 | "graphql-modules": "2.4.0", 29 | "graphql": "16.10.0", 30 | "zod": "3.24.1" 31 | }, 32 | "devDependencies": { 33 | "@types/bun": "1.2.2", 34 | "csvtojson": "2.0.10", 35 | "prisma": "6.3.1", 36 | "typescript": "5.7.3" 37 | }, 38 | "packageManager": "bun@1.2.2", 39 | "engines": { 40 | "bun": "1.2.2" 41 | }, 42 | "prisma": { 43 | "seed": "bun run ./src/infrastructure/seed/index.ts", 44 | "schema": "./prisma/schema.prisma" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /apps/api/prisma/migrations/20230425065839_initial/migration.sql: -------------------------------------------------------------------------------- 1 | -- CreateTable 2 | CREATE TABLE "categories" ( 3 | "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 4 | "name" TEXT NOT NULL 5 | ); 6 | 7 | -- CreateTable 8 | CREATE TABLE "foods" ( 9 | "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 10 | "name" TEXT NOT NULL, 11 | "categoryId" INTEGER NOT NULL, 12 | CONSTRAINT "foods_categoryId_fkey" FOREIGN KEY ("categoryId") REFERENCES "categories" ("id") ON DELETE RESTRICT ON UPDATE CASCADE 13 | ); 14 | 15 | -- CreateTable 16 | CREATE TABLE "amino_acids" ( 17 | "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 18 | "foodId" INTEGER NOT NULL, 19 | "tryptophan" REAL NOT NULL, 20 | "threonine" REAL NOT NULL, 21 | "isoleucine" REAL NOT NULL, 22 | "leucine" REAL NOT NULL, 23 | "lysine" REAL NOT NULL, 24 | "methionine" REAL NOT NULL, 25 | "cystine" REAL NOT NULL, 26 | "phenylalanine" REAL NOT NULL, 27 | "tyrosine" REAL NOT NULL, 28 | "valine" REAL NOT NULL, 29 | "arginine" REAL NOT NULL, 30 | "histidine" REAL NOT NULL, 31 | "alanine" REAL NOT NULL, 32 | "asparticAcid" REAL NOT NULL, 33 | "glutamicAcid" REAL NOT NULL, 34 | "glycine" REAL NOT NULL, 35 | "proline" REAL NOT NULL, 36 | "serine" REAL NOT NULL, 37 | CONSTRAINT "amino_acids_foodId_fkey" FOREIGN KEY ("foodId") REFERENCES "foods" ("id") ON DELETE RESTRICT ON UPDATE CASCADE 38 | ); 39 | 40 | -- CreateTable 41 | CREATE TABLE "fatty_acids" ( 42 | "foodId" INTEGER NOT NULL, 43 | "saturated" REAL NOT NULL, 44 | "monounsaturated" REAL NOT NULL, 45 | "polyunsaturated" REAL NOT NULL, 46 | "12:0" REAL, 47 | "14:0" REAL, 48 | "14:1" REAL, 49 | "16:0" REAL, 50 | "16:1" REAL, 51 | "18:0" REAL, 52 | "18:1" REAL, 53 | "18:1t" REAL, 54 | "18:2n6" REAL, 55 | "18:2t" REAL, 56 | "18:3n3" REAL, 57 | "20:0" REAL, 58 | "20:1" REAL, 59 | "20:4" REAL, 60 | "20:5" REAL, 61 | "22:0" REAL, 62 | "22:5" REAL, 63 | "22:6" REAL, 64 | "24:0" REAL, 65 | CONSTRAINT "fatty_acids_foodId_fkey" FOREIGN KEY ("foodId") REFERENCES "foods" ("id") ON DELETE RESTRICT ON UPDATE CASCADE 66 | ); 67 | 68 | -- CreateTable 69 | CREATE TABLE "nutrients" ( 70 | "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 71 | "foodId" INTEGER NOT NULL, 72 | "moisture" REAL, 73 | "kcal" REAL, 74 | "kJ" REAL, 75 | "protein" REAL, 76 | "lipids" REAL, 77 | "cholesterol" REAL, 78 | "carbohydrates" REAL, 79 | "dietaryFiber" REAL, 80 | "ash" REAL, 81 | "calcium" REAL, 82 | "magnesium" REAL, 83 | "manganese" REAL, 84 | "phosphorus" REAL, 85 | "iron" REAL, 86 | "sodium" REAL, 87 | "potassium" REAL, 88 | "copper" REAL, 89 | "zinc" REAL, 90 | "retinol" REAL, 91 | "re" REAL, 92 | "rae" REAL, 93 | "thiamin" REAL, 94 | "riboflavin" REAL, 95 | "pyridoxine" REAL, 96 | "niacin" REAL, 97 | "vitaminC" REAL, 98 | CONSTRAINT "nutrients_foodId_fkey" FOREIGN KEY ("foodId") REFERENCES "foods" ("id") ON DELETE RESTRICT ON UPDATE CASCADE 99 | ); 100 | 101 | -- CreateTable 102 | CREATE TABLE "units" ( 103 | "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, 104 | "fieldName" TEXT NOT NULL, 105 | "unit" TEXT NOT NULL, 106 | "labelPt" TEXT NOT NULL, 107 | "infoodsTagname" TEXT, 108 | "systematicName" TEXT, 109 | "commonName" TEXT 110 | ); 111 | 112 | -- CreateIndex 113 | CREATE UNIQUE INDEX "categories_name_key" ON "categories"("name"); 114 | 115 | -- CreateIndex 116 | CREATE UNIQUE INDEX "foods_name_key" ON "foods"("name"); 117 | 118 | -- CreateIndex 119 | CREATE UNIQUE INDEX "amino_acids_foodId_key" ON "amino_acids"("foodId"); 120 | 121 | -- CreateIndex 122 | CREATE UNIQUE INDEX "fatty_acids_foodId_key" ON "fatty_acids"("foodId"); 123 | 124 | -- CreateIndex 125 | CREATE UNIQUE INDEX "nutrients_foodId_key" ON "nutrients"("foodId"); 126 | -------------------------------------------------------------------------------- /apps/api/prisma/migrations/migration_lock.toml: -------------------------------------------------------------------------------- 1 | # Please do not edit this file manually 2 | # It should be added in your version-control system (i.e. Git) 3 | provider = "sqlite" -------------------------------------------------------------------------------- /apps/api/prisma/schema.prisma: -------------------------------------------------------------------------------- 1 | // This is your Prisma schema file, 2 | // learn more about it in the docs: https://pris.ly/d/prisma-schema 3 | 4 | generator client { 5 | provider = "prisma-client-js" 6 | } 7 | 8 | datasource db { 9 | provider = "sqlite" 10 | url = "file:./taco.db" 11 | } 12 | 13 | model Category { 14 | id Int @id @default(autoincrement()) 15 | name String @unique 16 | foods Food[] 17 | 18 | @@map("categories") 19 | } 20 | 21 | model Food { 22 | id Int @id @default(autoincrement()) 23 | name String @unique 24 | 25 | aminoAcids AminoAcid? 26 | fattyAcids FattyAcid? 27 | nutrients Nutrient? 28 | 29 | category Category @relation(fields: [categoryId], references: [id]) 30 | categoryId Int 31 | 32 | @@map("foods") 33 | } 34 | 35 | model AminoAcid { 36 | id Int @id @default(autoincrement()) 37 | 38 | food Food @relation(fields: [foodId], references: [id]) 39 | foodId Int @unique 40 | 41 | tryptophan Float 42 | threonine Float 43 | isoleucine Float 44 | leucine Float 45 | lysine Float 46 | methionine Float 47 | cystine Float 48 | phenylalanine Float 49 | tyrosine Float 50 | valine Float 51 | arginine Float 52 | histidine Float 53 | alanine Float 54 | asparticAcid Float 55 | glutamicAcid Float 56 | glycine Float 57 | proline Float 58 | serine Float 59 | 60 | @@map("amino_acids") 61 | } 62 | 63 | model FattyAcid { 64 | food Food @relation(fields: [foodId], references: [id]) 65 | foodId Int @unique 66 | 67 | saturated Float 68 | monounsaturated Float 69 | polyunsaturated Float 70 | 71 | twelveZero Float? @map("12:0") 72 | fourteenZero Float? @map("14:0") 73 | fourteenOne Float? @map("14:1") 74 | sixteenZero Float? @map("16:0") 75 | sixteenOne Float? @map("16:1") 76 | eighteenZero Float? @map("18:0") 77 | eighteenOne Float? @map("18:1") 78 | eighteenOneT Float? @map("18:1t") 79 | eighteenTwoN6 Float? @map("18:2n6") 80 | eighteenTwoT Float? @map("18:2t") 81 | eighteenThreeN3 Float? @map("18:3n3") 82 | twentyZero Float? @map("20:0") 83 | twentyOne Float? @map("20:1") 84 | twentyFour Float? @map("20:4") 85 | twentyFive Float? @map("20:5") 86 | twentyTwoZero Float? @map("22:0") 87 | twentyTwoFive Float? @map("22:5") 88 | twentyTwoSix Float? @map("22:6") 89 | twentyFourZero Float? @map("24:0") 90 | 91 | @@map("fatty_acids") 92 | } 93 | 94 | model Nutrient { 95 | id Int @id @default(autoincrement()) 96 | food Food @relation(fields: [foodId], references: [id]) 97 | foodId Int @unique 98 | 99 | moisture Float? 100 | kcal Float? 101 | kJ Float? 102 | protein Float? 103 | lipids Float? 104 | cholesterol Float? 105 | carbohydrates Float? 106 | dietaryFiber Float? 107 | ash Float? 108 | calcium Float? 109 | magnesium Float? 110 | manganese Float? 111 | phosphorus Float? 112 | iron Float? 113 | sodium Float? 114 | potassium Float? 115 | copper Float? 116 | zinc Float? 117 | retinol Float? 118 | re Float? 119 | rae Float? 120 | thiamin Float? 121 | riboflavin Float? 122 | pyridoxine Float? 123 | niacin Float? 124 | vitaminC Float? 125 | 126 | @@map("nutrients") 127 | } 128 | 129 | model Unit { 130 | id Int @id @default(autoincrement()) 131 | fieldName String 132 | unit String 133 | labelPt String 134 | 135 | infoodsTagname String? 136 | systematicName String? 137 | commonName String? 138 | 139 | @@map("units") 140 | } 141 | -------------------------------------------------------------------------------- /apps/api/prisma/taco.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raulfdm/taco-api/06e466ad2f3d76064b587808b1804564b2c40f67/apps/api/prisma/taco.db -------------------------------------------------------------------------------- /apps/api/scripts/build.ts: -------------------------------------------------------------------------------- 1 | import { dependencies } from "../package.json"; 2 | 3 | await Bun.build({ 4 | entrypoints: ["./src/app.ts"], 5 | outdir: "./dist", 6 | external: Object.keys(dependencies), 7 | target: "bun", 8 | splitting: true, 9 | }); 10 | -------------------------------------------------------------------------------- /apps/api/src/app.ts: -------------------------------------------------------------------------------- 1 | import { cors } from "@elysiajs/cors"; 2 | import { yoga } from "@elysiajs/graphql-yoga"; 3 | import { useGraphQLModules } from "@envelop/graphql-modules"; 4 | import { Elysia } from "elysia"; 5 | 6 | import { createApplication } from "graphql-modules"; 7 | 8 | import { env } from "@/infrastructure/env"; 9 | import { 10 | aminoAcidModules, 11 | categoryModule, 12 | fattyAcidModule, 13 | foodModule, 14 | mainModule, 15 | nutrientModule, 16 | unitModule, 17 | } from "@/modules"; 18 | 19 | const application = createApplication({ 20 | modules: [ 21 | mainModule, 22 | unitModule, 23 | foodModule, 24 | categoryModule, 25 | aminoAcidModules, 26 | fattyAcidModule, 27 | nutrientModule, 28 | ], 29 | }); 30 | 31 | new Elysia() 32 | .use(cors()) 33 | .use( 34 | yoga({ 35 | typeDefs: application.typeDefs, 36 | plugins: [useGraphQLModules(application)], 37 | /** 38 | * There's some type difference between those libraries but it's integrating 39 | * as expected. 40 | * 41 | * To see the Yoga API we need to remove the `as any`. 42 | */ 43 | // biome-ignore lint/suspicious/noExplicitAny: 44 | } as any), 45 | ) 46 | .listen(env.PORT, ({ port }) => { 47 | console.log(`🚀 Server ready at http://localhost:${port}/graphql`); 48 | }); 49 | -------------------------------------------------------------------------------- /apps/api/src/infrastructure/env.ts: -------------------------------------------------------------------------------- 1 | import { z } from "zod"; 2 | 3 | export const envSchema = z.object({ 4 | NODE_ENV: z.enum(["development", "production"]), 5 | PORT: z.string().default("4000"), 6 | }); 7 | 8 | export const env = envSchema.parse(process.env); 9 | -------------------------------------------------------------------------------- /apps/api/src/infrastructure/primaClient.ts: -------------------------------------------------------------------------------- 1 | import { PrismaClient } from "@prisma/client"; 2 | 3 | import { env } from "./env"; 4 | 5 | type GetPrismaOpts = { 6 | disableLogs?: boolean; 7 | }; 8 | 9 | export function getPrismaClient({ 10 | disableLogs, 11 | }: GetPrismaOpts = {}): PrismaClient { 12 | let shouldLog = true; 13 | 14 | if (disableLogs === true) { 15 | shouldLog = false; 16 | } 17 | 18 | if (env.NODE_ENV === "production") { 19 | shouldLog = false; 20 | } 21 | 22 | const prisma = new PrismaClient({ 23 | log: shouldLog ? ["error", "info", "query", "warn"] : undefined, 24 | }); 25 | 26 | return prisma; 27 | } 28 | -------------------------------------------------------------------------------- /apps/api/src/infrastructure/seed/amino-acids.ts: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | 3 | import * as url from "node:url"; 4 | import csvtojson from "csvtojson/v2"; 5 | import { z } from "zod"; 6 | 7 | const __dirname = url.fileURLToPath(new URL(".", import.meta.url)); 8 | 9 | const aminoAcidsSchema = z.array( 10 | z.object({ 11 | foodId: z.string().transform((id) => Number(id)), 12 | tryptophan: z.string().transform((id) => Number(id)), 13 | threonine: z.string().transform((id) => Number(id)), 14 | isoleucine: z.string().transform((id) => Number(id)), 15 | leucine: z.string().transform((id) => Number(id)), 16 | lysine: z.string().transform((id) => Number(id)), 17 | methionine: z.string().transform((id) => Number(id)), 18 | cystine: z.string().transform((id) => Number(id)), 19 | phenylalanine: z.string().transform((id) => Number(id)), 20 | tyrosine: z.string().transform((id) => Number(id)), 21 | valine: z.string().transform((id) => Number(id)), 22 | arginine: z.string().transform((id) => Number(id)), 23 | histidine: z.string().transform((id) => Number(id)), 24 | alanine: z.string().transform((id) => Number(id)), 25 | asparticAcid: z.string().transform((id) => Number(id)), 26 | glutamicAcid: z.string().transform((id) => Number(id)), 27 | glycine: z.string().transform((id) => Number(id)), 28 | proline: z.string().transform((id) => Number(id)), 29 | serine: z.string().transform((id) => Number(id)), 30 | }), 31 | ); 32 | 33 | export type AminoAcid = z.infer[number]; 34 | 35 | export type AminoAcidMap = Map>; 36 | 37 | export async function getAminoAcidsMap(): Promise { 38 | const aminoAcidsJson = await csvtojson().fromFile( 39 | path.resolve(__dirname, "../../../references/csv/amino-acids.csv"), 40 | ); 41 | 42 | const aminoAcids = aminoAcidsSchema.parse(aminoAcidsJson); 43 | 44 | const aminoAcidsMap: AminoAcidMap = new Map(); 45 | 46 | for (const aminoAcid of aminoAcids) { 47 | const { foodId, ...rest } = aminoAcid; 48 | aminoAcidsMap.set(aminoAcid.foodId, rest); 49 | } 50 | 51 | return aminoAcidsMap; 52 | } 53 | -------------------------------------------------------------------------------- /apps/api/src/infrastructure/seed/categories.ts: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | 3 | import * as url from "node:url"; 4 | import type { PrismaClient } from "@prisma/client"; 5 | import csvtojson from "csvtojson/v2"; 6 | import { z } from "zod"; 7 | 8 | const __dirname = url.fileURLToPath(new URL(".", import.meta.url)); 9 | 10 | const categoriesSchema = z.array( 11 | z.object({ 12 | id: z.string().transform((id) => Number(id)), 13 | name: z.string(), 14 | }), 15 | ); 16 | 17 | export async function seedCategories(client: PrismaClient) { 18 | const categoriesJson = await csvtojson().fromFile( 19 | path.resolve(__dirname, "../../../references/csv/categories.csv"), 20 | ); 21 | 22 | const categories = categoriesSchema.parse(categoriesJson); 23 | 24 | console.group("Seeding categories"); 25 | 26 | for (const category of categories) { 27 | console.log(`Creating category "${category.name}"`); 28 | await client.category.create({ 29 | data: category, 30 | }); 31 | 32 | console.log("Done."); 33 | } 34 | 35 | console.log("All categories created successfully."); 36 | console.groupEnd(); 37 | } 38 | -------------------------------------------------------------------------------- /apps/api/src/infrastructure/seed/fatty-acids.ts: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | 3 | import * as url from "node:url"; 4 | import csvtojson from "csvtojson/v2"; 5 | import { z } from "zod"; 6 | 7 | const __dirname = url.fileURLToPath(new URL(".", import.meta.url)); 8 | 9 | const fattyAcidsSchema = z.array( 10 | z 11 | .object({ 12 | foodId: z.string().transform((id) => Number(id)), 13 | saturated: z.string().transform((id) => Number(id)), 14 | monounsaturated: z.string().transform((id) => Number(id)), 15 | polyunsaturated: z.string().transform((id) => Number(id)), 16 | "12:0": z.string().transform((id) => (id ? Number(id) : null)), 17 | "14:0": z.string().transform((id) => (id ? Number(id) : null)), 18 | "16:0": z.string().transform((id) => (id ? Number(id) : null)), 19 | "18:0": z.string().transform((id) => (id ? Number(id) : null)), 20 | "20:0": z.string().transform((id) => (id ? Number(id) : null)), 21 | "22:0": z.string().transform((id) => (id ? Number(id) : null)), 22 | "24:0": z.string().transform((id) => (id ? Number(id) : null)), 23 | "14:1": z.string().transform((id) => (id ? Number(id) : null)), 24 | "16:1": z.string().transform((id) => (id ? Number(id) : null)), 25 | "18:1": z.string().transform((id) => (id ? Number(id) : null)), 26 | "20:1": z.string().transform((id) => (id ? Number(id) : null)), 27 | "18:2n6": z.string().transform((id) => (id ? Number(id) : null)), 28 | "18:3n3": z.string().transform((id) => (id ? Number(id) : null)), 29 | "20:4": z.string().transform((id) => (id ? Number(id) : null)), 30 | "20:5": z.string().transform((id) => (id ? Number(id) : null)), 31 | "22:5": z.string().transform((id) => (id ? Number(id) : null)), 32 | "22:6": z.string().transform((id) => (id ? Number(id) : null)), 33 | "18:1t": z.string().transform((id) => (id ? Number(id) : null)), 34 | "18:2t": z.string().transform((id) => (id ? Number(id) : null)), 35 | }) 36 | .transform((input) => { 37 | return { 38 | foodId: input.foodId, 39 | saturated: input.saturated, 40 | monounsaturated: input.monounsaturated, 41 | polyunsaturated: input.polyunsaturated, 42 | twelveZero: input["12:0"], 43 | fourteenZero: input["14:0"], 44 | fourteenOne: input["14:1"], 45 | sixteenZero: input["16:0"], 46 | sixteenOne: input["16:1"], 47 | eighteenZero: input["18:0"], 48 | eighteenOne: input["18:1"], 49 | eighteenOneT: input["18:1t"], 50 | eighteenTwoN6: input["18:2n6"], 51 | eighteenTwoT: input["18:2t"], 52 | eighteenThreeN3: input["18:3n3"], 53 | twentyZero: input["20:0"], 54 | twentyOne: input["20:1"], 55 | twentyFour: input["20:4"], 56 | twentyFive: input["20:5"], 57 | twentyTwoZero: input["22:0"], 58 | twentyTwoFive: input["22:5"], 59 | twentyTwoSix: input["22:6"], 60 | twentyFourZero: input["24:0"], 61 | }; 62 | }), 63 | ); 64 | 65 | export type FattyAcid = z.infer[number]; 66 | 67 | export type FattyAcidMap = Map>; 68 | 69 | export async function getFattyAcidsMap(): Promise { 70 | const fattyAcidsJson = await csvtojson().fromFile( 71 | path.resolve(__dirname, "../../../references/csv/fatty-acids.csv"), 72 | ); 73 | 74 | const fattyAcids = fattyAcidsSchema.parse(fattyAcidsJson); 75 | 76 | const fattyAcidsMap: FattyAcidMap = new Map(); 77 | 78 | for (const fattyAcid of fattyAcids) { 79 | const { foodId, ...rest } = fattyAcid; 80 | fattyAcidsMap.set(fattyAcid.foodId, rest); 81 | } 82 | 83 | return fattyAcidsMap; 84 | } 85 | -------------------------------------------------------------------------------- /apps/api/src/infrastructure/seed/foods.ts: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | 3 | import * as url from "node:url"; 4 | import type { PrismaClient } from "@prisma/client"; 5 | import csvtojson from "csvtojson/v2"; 6 | import { z } from "zod"; 7 | 8 | import type { AminoAcid, AminoAcidMap } from "./amino-acids"; 9 | import { getAminoAcidsMap } from "./amino-acids"; 10 | import type { FattyAcid, FattyAcidMap } from "./fatty-acids"; 11 | import { getFattyAcidsMap } from "./fatty-acids"; 12 | import type { Nutrients, NutrientsMap } from "./nutrients"; 13 | import { getNutrientsMap } from "./nutrients"; 14 | 15 | const __dirname = url.fileURLToPath(new URL(".", import.meta.url)); 16 | 17 | const foodSchema = z.array( 18 | z.object({ 19 | id: z.string().transform((id) => Number(id)), 20 | categoryId: z.string().transform((id) => Number(id)), 21 | name: z.string(), 22 | }), 23 | ); 24 | 25 | type Food = z.infer[number]; 26 | 27 | type PrismaFood = Food & { 28 | aminoAcids?: { 29 | create: Omit; 30 | }; 31 | fattyAcids?: { 32 | create: Omit; 33 | }; 34 | nutrients?: { 35 | create: Omit; 36 | }; 37 | }; 38 | 39 | type GetFoodOptions = { 40 | fattyAcidsMap: FattyAcidMap; 41 | aminoAcidsMap: AminoAcidMap; 42 | nutrientsMap: NutrientsMap; 43 | }; 44 | 45 | async function getFoods({ 46 | aminoAcidsMap, 47 | fattyAcidsMap, 48 | nutrientsMap, 49 | }: GetFoodOptions): Promise { 50 | const foodJson = await csvtojson().fromFile( 51 | path.resolve(__dirname, "../../../references/csv/food.csv"), 52 | ); 53 | 54 | const foods = foodSchema.parse(foodJson); 55 | 56 | const foodsMap: PrismaFood[] = []; 57 | 58 | for (const food of foods) { 59 | const foodMap: PrismaFood = { 60 | ...food, 61 | aminoAcids: undefined, 62 | fattyAcids: undefined, 63 | }; 64 | 65 | const aminoAcids = aminoAcidsMap.get(food.id); 66 | const fattyAcids = fattyAcidsMap.get(food.id); 67 | const nutrients = nutrientsMap.get(food.id); 68 | 69 | if (aminoAcids) { 70 | foodMap.aminoAcids = { 71 | create: aminoAcids, 72 | }; 73 | } 74 | 75 | if (fattyAcids) { 76 | foodMap.fattyAcids = { 77 | create: fattyAcids, 78 | }; 79 | } 80 | 81 | if (nutrients) { 82 | foodMap.nutrients = { 83 | create: nutrients, 84 | }; 85 | } 86 | 87 | foodsMap.push(foodMap); 88 | } 89 | 90 | return foodsMap; 91 | } 92 | 93 | export async function seedFood(client: PrismaClient) { 94 | const [aminoAcidsMap, fattyAcidsMap, nutrientsMap] = await Promise.all([ 95 | getAminoAcidsMap(), 96 | getFattyAcidsMap(), 97 | getNutrientsMap(), 98 | ]); 99 | 100 | const foods = await getFoods({ aminoAcidsMap, fattyAcidsMap, nutrientsMap }); 101 | 102 | console.group("Seeding foods"); 103 | for (const food of foods) { 104 | console.log(`Creating food "${food.name}"`); 105 | 106 | await client.food.upsert({ 107 | create: food, 108 | where: { 109 | id: food.id, 110 | }, 111 | update: {}, 112 | }); 113 | 114 | console.log("Done."); 115 | } 116 | 117 | console.log("All foods created successfully."); 118 | console.groupEnd(); 119 | } 120 | -------------------------------------------------------------------------------- /apps/api/src/infrastructure/seed/index.ts: -------------------------------------------------------------------------------- 1 | import { getPrismaClient } from "../primaClient"; 2 | import { seedCategories } from "./categories"; 3 | import { seedFood } from "./foods"; 4 | import { seedUnits } from "./units"; 5 | 6 | const prisma = getPrismaClient({ 7 | disableLogs: true, 8 | }); 9 | 10 | try { 11 | await seedCategories(prisma); 12 | await seedUnits(prisma); 13 | await seedFood(prisma); 14 | 15 | await prisma.$disconnect(); 16 | } catch (error) { 17 | await prisma.$disconnect(); 18 | 19 | if ( 20 | error instanceof Error && 21 | error.message.includes("Unique constraint failed") 22 | ) { 23 | console.log("Row already created"); 24 | process.exit(0); 25 | } 26 | 27 | console.error(error); 28 | process.exit(1); 29 | } 30 | -------------------------------------------------------------------------------- /apps/api/src/infrastructure/seed/nutrients.ts: -------------------------------------------------------------------------------- 1 | import path from "node:path"; 2 | 3 | import * as url from "node:url"; 4 | import csvtojson from "csvtojson/v2"; 5 | import { z } from "zod"; 6 | 7 | const __dirname = url.fileURLToPath(new URL(".", import.meta.url)); 8 | 9 | const nutrientsSchema = z.array( 10 | z.object({ 11 | foodId: z.string().transform((id) => Number(id)), 12 | moisture: z.string().transform((value) => (value ? Number(value) : null)), 13 | kcal: z.string().transform((value) => (value ? Number(value) : null)), 14 | kJ: z.string().transform((value) => (value ? Number(value) : null)), 15 | protein: z.string().transform((value) => (value ? Number(value) : null)), 16 | lipids: z.string().transform((value) => (value ? Number(value) : null)), 17 | cholesterol: z 18 | .string() 19 | .transform((value) => (value ? Number(value) : null)), 20 | carbohydrates: z 21 | .string() 22 | .transform((value) => (value ? Number(value) : null)), 23 | dietaryFiber: z 24 | .string() 25 | .transform((value) => (value ? Number(value) : null)), 26 | ash: z.string().transform((value) => (value ? Number(value) : null)), 27 | calcium: z.string().transform((value) => (value ? Number(value) : null)), 28 | magnesium: z.string().transform((value) => (value ? Number(value) : null)), 29 | manganese: z.string().transform((value) => (value ? Number(value) : null)), 30 | phosphorus: z.string().transform((value) => (value ? Number(value) : null)), 31 | iron: z.string().transform((value) => (value ? Number(value) : null)), 32 | sodium: z.string().transform((value) => (value ? Number(value) : null)), 33 | potassium: z.string().transform((value) => (value ? Number(value) : null)), 34 | copper: z.string().transform((value) => (value ? Number(value) : null)), 35 | zinc: z.string().transform((value) => (value ? Number(value) : null)), 36 | retinol: z.string().transform((value) => (value ? Number(value) : null)), 37 | re: z.string().transform((value) => (value ? Number(value) : null)), 38 | rae: z.string().transform((value) => (value ? Number(value) : null)), 39 | thiamin: z.string().transform((value) => (value ? Number(value) : null)), 40 | riboflavin: z.string().transform((value) => (value ? Number(value) : null)), 41 | pyridoxine: z.string().transform((value) => (value ? Number(value) : null)), 42 | niacin: z.string().transform((value) => (value ? Number(value) : null)), 43 | vitaminC: z.string().transform((value) => (value ? Number(value) : null)), 44 | }), 45 | ); 46 | 47 | export type Nutrients = z.infer[number]; 48 | 49 | export type NutrientsMap = Map>; 50 | 51 | export async function getNutrientsMap(): Promise { 52 | const aminoAcidsJson = await csvtojson().fromFile( 53 | path.resolve(__dirname, "../../../references/csv/nutrients.csv"), 54 | ); 55 | 56 | const nutrients = nutrientsSchema.parse(aminoAcidsJson); 57 | 58 | const nutrientsMap: NutrientsMap = new Map(); 59 | 60 | for (const aminoAcid of nutrients) { 61 | const { foodId, ...rest } = aminoAcid; 62 | nutrientsMap.set(aminoAcid.foodId, rest); 63 | } 64 | 65 | return nutrientsMap; 66 | } 67 | -------------------------------------------------------------------------------- /apps/api/src/infrastructure/seed/units/index.ts: -------------------------------------------------------------------------------- 1 | import type { PrismaClient } from "@prisma/client"; 2 | 3 | import { unitsToSave } from "./unitsToSave"; 4 | 5 | export async function seedUnits(client: PrismaClient) { 6 | console.group("Seeding units"); 7 | for (const unit of unitsToSave) { 8 | console.log(`Creating unit: "${unit.fieldName}"`); 9 | 10 | await client.unit.create({ 11 | data: unit, 12 | }); 13 | 14 | console.log("Done."); 15 | } 16 | 17 | console.log("All units created successfully."); 18 | console.groupEnd(); 19 | } 20 | -------------------------------------------------------------------------------- /apps/api/src/infrastructure/seed/units/types.ts: -------------------------------------------------------------------------------- 1 | import type { AminoAcid, FattyAcid, Nutrient, Unit } from "@prisma/client"; 2 | 3 | export type ValidUnit = Omit & { 4 | fieldName: NutrientKeys | AminoAcidKeys | FattyAcidKeys; 5 | }; 6 | 7 | type NutrientKeys = keyof Pick< 8 | Nutrient, 9 | | "moisture" 10 | | "kcal" 11 | | "kJ" 12 | | "protein" 13 | | "lipids" 14 | | "cholesterol" 15 | | "carbohydrates" 16 | | "dietaryFiber" 17 | | "ash" 18 | | "calcium" 19 | | "magnesium" 20 | | "manganese" 21 | | "phosphorus" 22 | | "iron" 23 | | "sodium" 24 | | "potassium" 25 | | "copper" 26 | | "zinc" 27 | | "retinol" 28 | | "re" 29 | | "rae" 30 | | "thiamin" 31 | | "riboflavin" 32 | | "pyridoxine" 33 | | "niacin" 34 | | "vitaminC" 35 | >; 36 | 37 | type AminoAcidKeys = keyof Pick< 38 | AminoAcid, 39 | | "tryptophan" 40 | | "threonine" 41 | | "isoleucine" 42 | | "leucine" 43 | | "lysine" 44 | | "methionine" 45 | | "cystine" 46 | | "phenylalanine" 47 | | "tyrosine" 48 | | "valine" 49 | | "arginine" 50 | | "histidine" 51 | | "alanine" 52 | | "asparticAcid" 53 | | "glutamicAcid" 54 | | "glycine" 55 | | "proline" 56 | | "serine" 57 | >; 58 | 59 | type FattyAcidKeys = keyof Pick< 60 | FattyAcid, 61 | | "saturated" 62 | | "monounsaturated" 63 | | "polyunsaturated" 64 | | "twelveZero" 65 | | "fourteenZero" 66 | | "fourteenOne" 67 | | "sixteenZero" 68 | | "sixteenOne" 69 | | "eighteenZero" 70 | | "eighteenOne" 71 | | "eighteenOneT" 72 | | "eighteenTwoN6" 73 | | "eighteenTwoT" 74 | | "eighteenThreeN3" 75 | | "twentyZero" 76 | | "twentyOne" 77 | | "twentyFour" 78 | | "twentyFive" 79 | | "twentyTwoZero" 80 | | "twentyTwoFive" 81 | | "twentyTwoSix" 82 | | "twentyFourZero" 83 | >; 84 | -------------------------------------------------------------------------------- /apps/api/src/infrastructure/seed/units/unitsToSave.ts: -------------------------------------------------------------------------------- 1 | import type { ValidUnit } from "./types"; 2 | 3 | type PartialUnit = Pick & 4 | Partial>; 5 | 6 | function createUnit(unit: PartialUnit): ValidUnit { 7 | const nextUnit = { 8 | ...unit, 9 | infoodsTagname: null, 10 | systematicName: null, 11 | commonName: null, 12 | } satisfies ValidUnit; 13 | 14 | return nextUnit; 15 | } 16 | 17 | export const unitsToSave = [ 18 | createUnit({ 19 | fieldName: "moisture", 20 | unit: "%", 21 | labelPt: "Umidade", 22 | infoodsTagname: "WATER", 23 | }), 24 | createUnit({ 25 | fieldName: "kcal", 26 | unit: "kcal", 27 | labelPt: "Energia", 28 | infoodsTagname: "ENERC", 29 | }), 30 | createUnit({ 31 | fieldName: "kJ", 32 | unit: "kj", 33 | labelPt: "Energia", 34 | infoodsTagname: "ENERC", 35 | }), 36 | createUnit({ 37 | fieldName: "protein", 38 | unit: "g", 39 | labelPt: "Proteína", 40 | infoodsTagname: "PROCNT", 41 | }), 42 | createUnit({ 43 | fieldName: "lipids", 44 | unit: "g", 45 | labelPt: "Lipídeos", 46 | infoodsTagname: "FAT", 47 | }), 48 | createUnit({ 49 | fieldName: "cholesterol", 50 | unit: "mg", 51 | labelPt: "Colesterol", 52 | infoodsTagname: "CHOLE", 53 | }), 54 | createUnit({ 55 | fieldName: "carbohydrates", 56 | unit: "g", 57 | labelPt: "Carboidrato", 58 | infoodsTagname: "CHOCDF", 59 | }), 60 | createUnit({ 61 | fieldName: "dietaryFiber", 62 | unit: "g", 63 | labelPt: "Fibra Alimentar", 64 | infoodsTagname: "FIBTG", 65 | }), 66 | createUnit({ 67 | fieldName: "ash", 68 | unit: "g", 69 | labelPt: "Cinzas", 70 | infoodsTagname: "ASH", 71 | }), 72 | createUnit({ 73 | fieldName: "calcium", 74 | unit: "mg", 75 | labelPt: "Cálcio", 76 | infoodsTagname: "CA", 77 | }), 78 | createUnit({ 79 | fieldName: "magnesium", 80 | unit: "mg", 81 | labelPt: "Magnésio", 82 | infoodsTagname: "MG", 83 | }), 84 | createUnit({ 85 | fieldName: "manganese", 86 | unit: "mg", 87 | labelPt: "Manganês", 88 | infoodsTagname: "MN", 89 | }), 90 | createUnit({ 91 | fieldName: "phosphorus", 92 | unit: "mg", 93 | labelPt: "Fósforo", 94 | infoodsTagname: "P", 95 | }), 96 | createUnit({ 97 | fieldName: "iron", 98 | unit: "mg", 99 | labelPt: "Ferro", 100 | infoodsTagname: "FE", 101 | }), 102 | createUnit({ 103 | fieldName: "sodium", 104 | unit: "mg", 105 | labelPt: "Sódio", 106 | infoodsTagname: "NA", 107 | }), 108 | createUnit({ 109 | fieldName: "potassium", 110 | unit: "mg", 111 | labelPt: "Potássio", 112 | infoodsTagname: "K", 113 | }), 114 | createUnit({ 115 | fieldName: "copper", 116 | unit: "mg", 117 | labelPt: "Cobre", 118 | infoodsTagname: "CU", 119 | }), 120 | createUnit({ 121 | fieldName: "zinc", 122 | unit: "mg", 123 | labelPt: "Zinco", 124 | infoodsTagname: "ZN", 125 | }), 126 | createUnit({ 127 | fieldName: "retinol", 128 | unit: "μg", 129 | labelPt: "Retinol", 130 | infoodsTagname: "RETOL", 131 | }), 132 | createUnit({ 133 | fieldName: "re", 134 | unit: "μg", 135 | labelPt: "RE", 136 | infoodsTagname: "VITA", 137 | }), 138 | createUnit({ 139 | fieldName: "rae", 140 | unit: "μg", 141 | labelPt: "RAE", 142 | infoodsTagname: "VITA", 143 | }), 144 | createUnit({ 145 | fieldName: "thiamin", 146 | unit: "mg", 147 | labelPt: "Tiamina", 148 | infoodsTagname: "THIA", 149 | }), 150 | createUnit({ 151 | fieldName: "riboflavin", 152 | unit: "mg", 153 | labelPt: "Riboflavina", 154 | infoodsTagname: "RIFB", 155 | }), 156 | createUnit({ 157 | fieldName: "pyridoxine", 158 | unit: "mg", 159 | labelPt: "Piridoxina", 160 | }), 161 | createUnit({ 162 | fieldName: "niacin", 163 | unit: "mg", 164 | labelPt: "Niacina", 165 | infoodsTagname: "NIA", 166 | }), 167 | createUnit({ 168 | fieldName: "vitaminC", 169 | unit: "mg", 170 | labelPt: "Vitamina C", 171 | infoodsTagname: "VITC", 172 | }), 173 | createUnit({ 174 | fieldName: "tryptophan", 175 | unit: "g", 176 | labelPt: "Triptofano", 177 | infoodsTagname: "TRP G", 178 | }), 179 | createUnit({ 180 | fieldName: "threonine", 181 | unit: "g", 182 | labelPt: "Treonina", 183 | infoodsTagname: "THR G", 184 | }), 185 | createUnit({ 186 | fieldName: "isoleucine", 187 | unit: "g", 188 | labelPt: "Isoleucina", 189 | infoodsTagname: "LE_G", 190 | }), 191 | createUnit({ 192 | fieldName: "leucine", 193 | unit: "g", 194 | labelPt: "Leucina", 195 | infoodsTagname: "LEU G", 196 | }), 197 | createUnit({ 198 | fieldName: "lysine", 199 | unit: "g", 200 | labelPt: "Lisina", 201 | infoodsTagname: "LYS G", 202 | }), 203 | createUnit({ 204 | fieldName: "methionine", 205 | unit: "g", 206 | labelPt: "Metionina", 207 | infoodsTagname: "MET G", 208 | }), 209 | createUnit({ 210 | fieldName: "cystine", 211 | unit: "g", 212 | labelPt: "Cistina", 213 | infoodsTagname: "CYS G", 214 | }), 215 | createUnit({ 216 | fieldName: "phenylalanine", 217 | unit: "g", 218 | labelPt: "Fenilalanina", 219 | infoodsTagname: "PHE G", 220 | }), 221 | createUnit({ 222 | fieldName: "tyrosine", 223 | unit: "g", 224 | labelPt: "Tirosina", 225 | infoodsTagname: "TYR G", 226 | }), 227 | createUnit({ 228 | fieldName: "valine", 229 | unit: "g", 230 | labelPt: "Valina", 231 | infoodsTagname: "VAL_ G", 232 | }), 233 | createUnit({ 234 | fieldName: "arginine", 235 | unit: "g", 236 | labelPt: "Arginina", 237 | infoodsTagname: "ARG G", 238 | }), 239 | createUnit({ 240 | fieldName: "histidine", 241 | unit: "g", 242 | labelPt: "Histidina", 243 | infoodsTagname: "HIS G", 244 | }), 245 | createUnit({ 246 | fieldName: "alanine", 247 | unit: "g", 248 | labelPt: "Alanina", 249 | infoodsTagname: "ALA G", 250 | }), 251 | createUnit({ 252 | fieldName: "asparticAcid", 253 | unit: "g", 254 | labelPt: "Ácido Aspártico", 255 | infoodsTagname: "ASP G", 256 | }), 257 | createUnit({ 258 | fieldName: "glutamicAcid", 259 | unit: "g", 260 | labelPt: "Ácido Glutâmico", 261 | infoodsTagname: "GLU G", 262 | }), 263 | createUnit({ 264 | fieldName: "glycine", 265 | unit: "g", 266 | labelPt: "Glicina", 267 | infoodsTagname: "GLY G", 268 | }), 269 | createUnit({ 270 | fieldName: "proline", 271 | unit: "g", 272 | labelPt: "Prolina", 273 | infoodsTagname: "PRO G", 274 | }), 275 | createUnit({ 276 | fieldName: "serine", 277 | unit: "g", 278 | labelPt: "Serina", 279 | infoodsTagname: "SER_G", 280 | }), 281 | createUnit({ 282 | fieldName: "saturated", 283 | unit: "g", 284 | labelPt: "Saturados", 285 | }), 286 | createUnit({ 287 | fieldName: "monounsaturated", 288 | unit: "g", 289 | labelPt: "Monoinsaturados", 290 | }), 291 | createUnit({ 292 | fieldName: "polyunsaturated", 293 | unit: "g", 294 | labelPt: "Poliinsaturados", 295 | }), 296 | createUnit({ 297 | fieldName: "twelveZero", 298 | unit: "g", 299 | labelPt: "12:0", 300 | infoodsTagname: "F12D0", 301 | systematicName: "Dodecanóico", 302 | commonName: "Láurico", 303 | }), 304 | createUnit({ 305 | fieldName: "fourteenZero", 306 | unit: "g", 307 | labelPt: "14:0", 308 | infoodsTagname: "F14D0", 309 | systematicName: "Tetradecanóico", 310 | commonName: "Mirístico", 311 | }), 312 | createUnit({ 313 | fieldName: "fourteenOne", 314 | unit: "g", 315 | labelPt: "14:1", 316 | infoodsTagname: "F14D1C", 317 | systematicName: "Tetradecenoico", 318 | commonName: "Miristoléico", 319 | }), 320 | createUnit({ 321 | fieldName: "sixteenZero", 322 | unit: "g", 323 | labelPt: "16:0", 324 | infoodsTagname: "F16D0", 325 | systematicName: "Hexadecanóico", 326 | commonName: "Palmítico", 327 | }), 328 | createUnit({ 329 | fieldName: "sixteenOne", 330 | unit: "g", 331 | labelPt: "16:1", 332 | infoodsTagname: "F16D1C", 333 | systematicName: "Hexadecenóico", 334 | commonName: "Palmitoléico", 335 | }), 336 | createUnit({ 337 | fieldName: "eighteenZero", 338 | unit: "g", 339 | labelPt: "18:0", 340 | infoodsTagname: "F18D0C", 341 | systematicName: "Octadecanóico", 342 | commonName: "Esteárico", 343 | }), 344 | createUnit({ 345 | fieldName: "eighteenOne", 346 | unit: "g", 347 | labelPt: "18:1", 348 | infoodsTagname: "F18D1C", 349 | systematicName: "Octadecenóico", 350 | commonName: "Oléico", 351 | }), 352 | createUnit({ 353 | fieldName: "eighteenOneT", 354 | unit: "g", 355 | labelPt: "18:1t", 356 | infoodsTagname: "F18D1T", 357 | systematicName: "Trans-octadecenóico", 358 | commonName: "Elaídico", 359 | }), 360 | createUnit({ 361 | fieldName: "eighteenTwoN6", 362 | unit: "g", 363 | labelPt: "18:2n6", 364 | infoodsTagname: "F18D2CN6", 365 | }), 366 | createUnit({ 367 | fieldName: "eighteenTwoT", 368 | unit: "g", 369 | labelPt: "18:2t", 370 | infoodsTagname: "F18D2TN9", 371 | systematicName: "Trans-octadecadienóico", 372 | }), 373 | createUnit({ 374 | fieldName: "eighteenThreeN3", 375 | unit: "g", 376 | labelPt: "18:3n3", 377 | infoodsTagname: "F18D3CN3", 378 | }), 379 | createUnit({ 380 | fieldName: "twentyZero", 381 | unit: "g", 382 | labelPt: "20:0", 383 | infoodsTagname: "F20D0", 384 | systematicName: "Eicosanóico", 385 | commonName: "Araquídico", 386 | }), 387 | createUnit({ 388 | fieldName: "twentyOne", 389 | unit: "g", 390 | labelPt: "20:1", 391 | infoodsTagname: "F20D1C", 392 | systematicName: "Eicosenóico", 393 | commonName: "Gadoléico", 394 | }), 395 | createUnit({ 396 | fieldName: "twentyFour", 397 | unit: "g", 398 | labelPt: "20:4", 399 | infoodsTagname: "F20D4", 400 | }), 401 | createUnit({ 402 | fieldName: "twentyFive", 403 | unit: "g", 404 | labelPt: "20:5", 405 | infoodsTagname: "F20D5", 406 | systematicName: "Eicosapentaenóico (EPA)", 407 | commonName: "Timnodônico", 408 | }), 409 | createUnit({ 410 | fieldName: "twentyTwoZero", 411 | unit: "g", 412 | labelPt: "22:0", 413 | infoodsTagname: "F22D0", 414 | systematicName: "Docosanóico", 415 | commonName: "Behênico", 416 | }), 417 | createUnit({ 418 | fieldName: "twentyTwoFive", 419 | unit: "g", 420 | labelPt: "22:5", 421 | infoodsTagname: "F22D5", 422 | systematicName: "Docosapentaenóico (DPA)", 423 | commonName: "Clupanodônico", 424 | }), 425 | createUnit({ 426 | fieldName: "twentyTwoSix", 427 | unit: "g", 428 | labelPt: "22:6", 429 | infoodsTagname: "F22D6", 430 | systematicName: "Docosahexaenóico (DHA)", 431 | }), 432 | createUnit({ 433 | fieldName: "twentyFourZero", 434 | unit: "g", 435 | labelPt: "24:0", 436 | infoodsTagname: "F24D0", 437 | systematicName: "Tetracosanóico", 438 | commonName: "Lignocérico", 439 | }), 440 | ] satisfies ValidUnit[]; 441 | -------------------------------------------------------------------------------- /apps/api/src/modules/aminoAcid/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./schema"; 2 | -------------------------------------------------------------------------------- /apps/api/src/modules/aminoAcid/schema.ts: -------------------------------------------------------------------------------- 1 | import { createModule } from "graphql-modules"; 2 | 3 | import { typeDefs } from "./typeDef"; 4 | 5 | export const aminoAcidModules = createModule({ 6 | id: "amino-acid-module", 7 | dirname: import.meta.dir, 8 | typeDefs: typeDefs, 9 | }); 10 | -------------------------------------------------------------------------------- /apps/api/src/modules/aminoAcid/typeDef.ts: -------------------------------------------------------------------------------- 1 | import { gql } from "graphql-modules"; 2 | 3 | const aminoAcidTypeDef = gql` 4 | type AminoAcid { 5 | id: Int! 6 | tryptophan: Float 7 | threonine: Float 8 | isoleucine: Float 9 | leucine: Float 10 | lysine: Float 11 | methionine: Float 12 | cystine: Float 13 | phenylalanine: Float 14 | tyrosine: Float 15 | valine: Float 16 | arginine: Float 17 | histidine: Float 18 | alanine: Float 19 | asparticAcid: Float 20 | glutamicAcid: Float 21 | glycine: Float 22 | proline: Float 23 | serine: Float 24 | } 25 | `; 26 | 27 | export const typeDefs = [aminoAcidTypeDef]; 28 | -------------------------------------------------------------------------------- /apps/api/src/modules/category/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./schema"; 2 | -------------------------------------------------------------------------------- /apps/api/src/modules/category/schema.ts: -------------------------------------------------------------------------------- 1 | import type { Prisma } from "@prisma/client"; 2 | import { createModule } from "graphql-modules"; 3 | 4 | import { getPrismaClient } from "../../infrastructure/primaClient"; 5 | import { typeDefs } from "./typeDef"; 6 | 7 | type FoodFilters = Pick; 8 | 9 | export const categoryModule = createModule({ 10 | id: "category-module", 11 | dirname: import.meta.dir, 12 | typeDefs: typeDefs, 13 | resolvers: { 14 | Query: { 15 | getAllCategories: async ( 16 | _: unknown, 17 | { opts }: { opts?: { foodFilters: FoodFilters } }, 18 | ) => { 19 | return getPrismaClient().category.findMany({ 20 | include: { 21 | foods: { 22 | ...opts?.foodFilters, 23 | include: { 24 | nutrients: true, 25 | aminoAcids: true, 26 | category: true, 27 | fattyAcids: true, 28 | }, 29 | }, 30 | }, 31 | }); 32 | }, 33 | getCategoryById: async ( 34 | _: unknown, 35 | { id, opts }: { id: number; opts?: { foodFilters: FoodFilters } }, 36 | ) => { 37 | return getPrismaClient().category.findUnique({ 38 | where: { 39 | id, 40 | }, 41 | include: { 42 | foods: { 43 | ...opts?.foodFilters, 44 | include: { 45 | nutrients: true, 46 | aminoAcids: true, 47 | category: true, 48 | fattyAcids: true, 49 | }, 50 | }, 51 | }, 52 | }); 53 | }, 54 | }, 55 | }, 56 | }); 57 | -------------------------------------------------------------------------------- /apps/api/src/modules/category/typeDef.ts: -------------------------------------------------------------------------------- 1 | import { gql } from "graphql-modules"; 2 | 3 | const categoryTypeDef = gql` 4 | type Category { 5 | id: Int! 6 | name: String! 7 | foods: [Food]! 8 | } 9 | `; 10 | 11 | const queryTypeDef = gql` 12 | input GetCategoryByIdOpts { 13 | foodFilters: PrismaQueryOptions 14 | } 15 | 16 | extend type Query { 17 | getAllCategories(opts: GetCategoryByIdOpts): [Category]! 18 | getCategoryById(id: Int!, opts: GetCategoryByIdOpts): Category 19 | } 20 | `; 21 | 22 | export const typeDefs = [categoryTypeDef, queryTypeDef]; 23 | -------------------------------------------------------------------------------- /apps/api/src/modules/fattyAcid/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./schema"; 2 | -------------------------------------------------------------------------------- /apps/api/src/modules/fattyAcid/schema.ts: -------------------------------------------------------------------------------- 1 | import { createModule } from "graphql-modules"; 2 | 3 | import { typeDefs } from "./typeDef"; 4 | 5 | export const fattyAcidModule = createModule({ 6 | id: "fatty-acid-module", 7 | dirname: import.meta.dir, 8 | typeDefs: typeDefs, 9 | }); 10 | -------------------------------------------------------------------------------- /apps/api/src/modules/fattyAcid/typeDef.ts: -------------------------------------------------------------------------------- 1 | import { gql } from "graphql-modules"; 2 | 3 | const fattyAcidTypeDef = gql` 4 | type FattyAcid { 5 | saturated: Float! 6 | monounsaturated: Float! 7 | polyunsaturated: Float! 8 | twelveZero: Float 9 | fourteenZero: Float 10 | fourteenOne: Float 11 | sixteenZero: Float 12 | sixteenOne: Float 13 | eighteenZero: Float 14 | eighteenOne: Float 15 | eighteenOneT: Float 16 | eighteenTwoN6: Float 17 | eighteenTwoT: Float 18 | eighteenThreeN3: Float 19 | twentyZero: Float 20 | twentyOne: Float 21 | twentyFour: Float 22 | twentyFive: Float 23 | twentyTwoZero: Float 24 | twentyTwoFive: Float 25 | twentyTwoSix: Float 26 | twentyFourZero: Float 27 | } 28 | `; 29 | 30 | export const typeDefs = [fattyAcidTypeDef]; 31 | -------------------------------------------------------------------------------- /apps/api/src/modules/food/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./schema"; 2 | -------------------------------------------------------------------------------- /apps/api/src/modules/food/schema.ts: -------------------------------------------------------------------------------- 1 | import type { Prisma } from "@prisma/client"; 2 | import { createModule } from "graphql-modules"; 3 | 4 | import { getPrismaClient } from "../../infrastructure/primaClient"; 5 | import { typeDefs } from "./typeDef"; 6 | 7 | export const foodModule = createModule({ 8 | id: "food-module", 9 | dirname: import.meta.dir, 10 | typeDefs: typeDefs, 11 | resolvers: { 12 | Query: { 13 | getAllFood: async ( 14 | _: unknown, 15 | { opts }: { opts: Pick }, 16 | ) => { 17 | return getPrismaClient().food.findMany({ 18 | ...opts, 19 | include: { 20 | category: true, 21 | nutrients: true, 22 | aminoAcids: true, 23 | fattyAcids: true, 24 | }, 25 | }); 26 | }, 27 | getFoodById: async (_: unknown, { id }: { id: number }) => { 28 | return getPrismaClient().food.findUnique({ 29 | where: { 30 | id, 31 | }, 32 | include: { 33 | category: true, 34 | nutrients: true, 35 | aminoAcids: true, 36 | fattyAcids: true, 37 | }, 38 | }); 39 | }, 40 | getFoodByName: async (_: unknown, { name }: { name: string }) => { 41 | return getPrismaClient().food.findMany({ 42 | where: { 43 | name: { 44 | contains: name, 45 | }, 46 | }, 47 | include: { 48 | category: true, 49 | nutrients: true, 50 | aminoAcids: true, 51 | fattyAcids: true, 52 | }, 53 | }); 54 | }, 55 | }, 56 | }, 57 | }); 58 | -------------------------------------------------------------------------------- /apps/api/src/modules/food/typeDef.ts: -------------------------------------------------------------------------------- 1 | import { gql } from "graphql-modules"; 2 | 3 | const foodTypeDef = gql` 4 | type Food { 5 | id: Int! 6 | name: String! 7 | category: Category! 8 | 9 | aminoAcids: AminoAcid 10 | fattyAcids: FattyAcid 11 | nutrients: Nutrient 12 | } 13 | `; 14 | 15 | const queryTypeDef = gql` 16 | extend type Query { 17 | getAllFood(opts: PrismaQueryOptions): [Food]! 18 | getFoodById(id: Int!): Food 19 | getFoodByName(name: String!): [Food]! 20 | } 21 | `; 22 | 23 | export const typeDefs = [queryTypeDef, foodTypeDef]; 24 | -------------------------------------------------------------------------------- /apps/api/src/modules/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./aminoAcid"; 2 | export * from "./category"; 3 | export * from "./fattyAcid"; 4 | export * from "./food"; 5 | export * from "./main"; 6 | export * from "./nutrient"; 7 | export * from "./unit"; 8 | -------------------------------------------------------------------------------- /apps/api/src/modules/main/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./schema"; 2 | -------------------------------------------------------------------------------- /apps/api/src/modules/main/schema.ts: -------------------------------------------------------------------------------- 1 | import { createModule, gql } from "graphql-modules"; 2 | 3 | export const mainModule = createModule({ 4 | id: "main-module", 5 | dirname: import.meta.dir, 6 | typeDefs: [ 7 | gql` 8 | input PrismaQueryOptions { 9 | skip: Int 10 | take: Int 11 | } 12 | 13 | type Query 14 | `, 15 | ], 16 | resolvers: { 17 | Query: {}, 18 | }, 19 | }); 20 | -------------------------------------------------------------------------------- /apps/api/src/modules/nutrient/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./schema"; 2 | -------------------------------------------------------------------------------- /apps/api/src/modules/nutrient/schema.ts: -------------------------------------------------------------------------------- 1 | import { createModule } from "graphql-modules"; 2 | 3 | import { typeDefs } from "./typeDef"; 4 | 5 | export const nutrientModule = createModule({ 6 | id: "nutrient-module", 7 | dirname: import.meta.dir, 8 | typeDefs: typeDefs, 9 | }); 10 | -------------------------------------------------------------------------------- /apps/api/src/modules/nutrient/typeDef.ts: -------------------------------------------------------------------------------- 1 | import { gql } from "graphql-modules"; 2 | 3 | const nutrientTypeDef = gql` 4 | type Nutrient { 5 | moisture: Float 6 | kcal: Float 7 | kJ: Float 8 | protein: Float 9 | lipids: Float 10 | cholesterol: Float 11 | carbohydrates: Float 12 | dietaryFiber: Float 13 | ash: Float 14 | calcium: Float 15 | magnesium: Float 16 | manganese: Float 17 | phosphorus: Float 18 | iron: Float 19 | sodium: Float 20 | potassium: Float 21 | copper: Float 22 | zinc: Float 23 | retinol: Float 24 | re: Float 25 | rae: Float 26 | thiamin: Float 27 | riboflavin: Float 28 | pyridoxine: Float 29 | niacin: Float 30 | vitaminC: Float 31 | } 32 | `; 33 | 34 | export const typeDefs = [nutrientTypeDef]; 35 | -------------------------------------------------------------------------------- /apps/api/src/modules/unit/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./schema"; 2 | -------------------------------------------------------------------------------- /apps/api/src/modules/unit/schema.ts: -------------------------------------------------------------------------------- 1 | import { createModule } from "graphql-modules"; 2 | 3 | import { getPrismaClient } from "../../infrastructure/primaClient"; 4 | import { typeDefs } from "./typeDefs"; 5 | 6 | export const unitModule = createModule({ 7 | id: "unit-module", 8 | dirname: import.meta.dir, 9 | typeDefs, 10 | resolvers: { 11 | Query: { 12 | getUnits: async () => { 13 | return await getPrismaClient().unit.findMany(); 14 | }, 15 | getUnitByFieldName: async ( 16 | _: unknown, 17 | { fieldName }: { fieldName: string }, 18 | ) => { 19 | return await getPrismaClient().unit.findFirst({ 20 | where: { 21 | fieldName, 22 | }, 23 | }); 24 | }, 25 | }, 26 | }, 27 | }); 28 | -------------------------------------------------------------------------------- /apps/api/src/modules/unit/typeDefs.ts: -------------------------------------------------------------------------------- 1 | import { gql } from "graphql-modules"; 2 | 3 | const unitTypeDef = gql` 4 | type Unit { 5 | id: Int! 6 | fieldName: String! 7 | unit: String! 8 | labelPt: String! 9 | infoodsTagname: String 10 | systematicName: String 11 | commonName: String 12 | } 13 | `; 14 | 15 | const queryTypeDef = gql` 16 | extend type Query { 17 | getUnits: [Unit]! 18 | getUnitByFieldName(fieldName: String!): Unit 19 | } 20 | `; 21 | 22 | export const typeDefs = [queryTypeDef, unitTypeDef]; 23 | -------------------------------------------------------------------------------- /apps/api/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": [ 4 | "ESNext" 5 | ], 6 | "esModuleInterop": true, 7 | "verbatimModuleSyntax": true, 8 | "isolatedModules": true, 9 | "resolveJsonModule": true, 10 | "module": "esnext", 11 | "target": "esnext", 12 | "moduleResolution": "bundler", 13 | "moduleDetection": "force", 14 | "allowImportingTsExtensions": true, 15 | "noEmit": true, 16 | "composite": true, 17 | "strict": true, 18 | "noUncheckedIndexedAccess": true, 19 | "downlevelIteration": true, 20 | "skipLibCheck": true, 21 | "jsx": "react-jsx", 22 | "allowSyntheticDefaultImports": true, 23 | "forceConsistentCasingInFileNames": true, 24 | "allowJs": true, 25 | "baseUrl": ".", 26 | "paths": { 27 | "@/*": [ 28 | "src/*" 29 | ], 30 | "@prisma/client": [ 31 | "dist/generated" 32 | ] 33 | }, 34 | } 35 | } -------------------------------------------------------------------------------- /apps/website/.gitignore: -------------------------------------------------------------------------------- 1 | # build output 2 | dist/ 3 | # generated types 4 | .astro/ 5 | 6 | # dependencies 7 | node_modules/ 8 | 9 | # logs 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | pnpm-debug.log* 14 | 15 | 16 | # environment variables 17 | .env 18 | .env.production 19 | 20 | # macOS-specific files 21 | .DS_Store 22 | -------------------------------------------------------------------------------- /apps/website/README.md: -------------------------------------------------------------------------------- 1 | # Starlight Starter Kit: Basics 2 | 3 | [![Built with Starlight](https://astro.badg.es/v2/built-with-starlight/tiny.svg)](https://starlight.astro.build) 4 | 5 | ``` 6 | npm create astro@latest -- --template starlight 7 | ``` 8 | 9 | [![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/starlight/tree/main/examples/basics) 10 | [![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/basics) 11 | [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fwithastro%2Fstarlight%2Ftree%2Fmain%2Fexamples%2Fbasics&project-name=my-starlight-docs&repository-name=my-starlight-docs) 12 | 13 | > 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun! 14 | 15 | ## 🚀 Project Structure 16 | 17 | Inside of your Astro + Starlight project, you'll see the following folders and files: 18 | 19 | ``` 20 | . 21 | ├── public/ 22 | ├── src/ 23 | │ ├── assets/ 24 | │ ├── content/ 25 | │ │ ├── docs/ 26 | │ │ └── config.ts 27 | │ └── env.d.ts 28 | ├── astro.config.mjs 29 | ├── package.json 30 | └── tsconfig.json 31 | ``` 32 | 33 | Starlight looks for `.md` or `.mdx` files in the `src/content/docs/` directory. Each file is exposed as a route based on its file name. 34 | 35 | Images can be added to `src/assets/` and embedded in Markdown with a relative link. 36 | 37 | Static assets, like favicons, can be placed in the `public/` directory. 38 | 39 | ## 🧞 Commands 40 | 41 | All commands are run from the root of the project, from a terminal: 42 | 43 | | Command | Action | 44 | | :------------------------ | :----------------------------------------------- | 45 | | `npm install` | Installs dependencies | 46 | | `npm run dev` | Starts local dev server at `localhost:4321` | 47 | | `npm run build` | Build your production site to `./dist/` | 48 | | `npm run preview` | Preview your build locally, before deploying | 49 | | `npm run astro ...` | Run CLI commands like `astro add`, `astro check` | 50 | | `npm run astro -- --help` | Get help using the Astro CLI | 51 | 52 | ## 👀 Want to learn more? 53 | 54 | Check out [Starlight’s docs](https://starlight.astro.build/), read [the Astro documentation](https://docs.astro.build), or jump into the [Astro Discord server](https://astro.build/chat). 55 | -------------------------------------------------------------------------------- /apps/website/astro.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig, sharpImageService } from "astro/config"; 2 | import starlight from "@astrojs/starlight"; 3 | 4 | // https://astro.build/config 5 | export default defineConfig({ 6 | redirects: { 7 | "/": "/about", 8 | }, 9 | image: { 10 | imageService: sharpImageService(), 11 | }, 12 | integrations: [ 13 | starlight({ 14 | title: "TACO API", 15 | defaultLocale: "root", 16 | locales: { 17 | root: { 18 | label: "Português", 19 | lang: "pt-BR", 20 | }, 21 | en: { 22 | label: "English", 23 | }, 24 | }, 25 | social: { 26 | github: "https://github.com/raulfdm/taco-api", 27 | }, 28 | sidebar: [ 29 | { 30 | label: "Introdução", 31 | items: [ 32 | { 33 | label: "Sobre", 34 | link: "/about", 35 | translations: { 36 | en: "About", 37 | }, 38 | }, 39 | { 40 | label: "Tecnologias", 41 | link: "/tech", 42 | translations: { 43 | en: "Technologies", 44 | }, 45 | }, 46 | ], 47 | }, 48 | { 49 | label: "Início", 50 | translations: { 51 | en: "Getting Started", 52 | }, 53 | items: [ 54 | { 55 | label: "Começando", 56 | link: "/getting-started", 57 | translations: { 58 | en: "Getting Started", 59 | }, 60 | }, 61 | { 62 | label: "Documentação da API", 63 | link: "/api-docs", 64 | translations: { 65 | en: "API Docs", 66 | }, 67 | }, 68 | { 69 | label: "Banco de dados", 70 | link: "/database", 71 | translations: { 72 | en: "Database", 73 | }, 74 | }, 75 | ], 76 | }, 77 | { 78 | label: "Deploy", 79 | items: [ 80 | { 81 | label: "NodeJS", 82 | link: "/deploy-node", 83 | }, 84 | { 85 | label: "Docker", 86 | link: "/deploy-docker", 87 | }, 88 | ], 89 | }, 90 | { 91 | label: "Referências", 92 | translations: { 93 | en: "References", 94 | }, 95 | items: [ 96 | { 97 | label: "Processamento de dados", 98 | link: "/data-processing", 99 | translations: { 100 | en: "Data Processing", 101 | }, 102 | }, 103 | { 104 | label: "Perguntas Frequentes", 105 | link: "/faq", 106 | translations: { 107 | en: "FAQ", 108 | }, 109 | }, 110 | { 111 | label: "Contribuindo", 112 | link: "/contributing", 113 | translations: { 114 | en: "Contributing", 115 | }, 116 | }, 117 | ], 118 | }, 119 | ], 120 | }), 121 | ], 122 | }); 123 | -------------------------------------------------------------------------------- /apps/website/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "website", 3 | "type": "module", 4 | "private": true, 5 | "version": "0.0.0-development", 6 | "scripts": { 7 | "dev": "astro dev", 8 | "start": "astro dev", 9 | "build": "astro check && astro build", 10 | "preview": "astro preview", 11 | "astro": "astro" 12 | }, 13 | "dependencies": { 14 | "@astrojs/starlight": "0.31.1", 15 | "astro": "5.2.5", 16 | "sharp": "0.33.5" 17 | }, 18 | "devDependencies": { 19 | "@astrojs/check": "0.9.4", 20 | "typescript": "5.7.3" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /apps/website/public/favicon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /apps/website/src/assets/graphql-playground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raulfdm/taco-api/06e466ad2f3d76064b587808b1804564b2c40f67/apps/website/src/assets/graphql-playground.png -------------------------------------------------------------------------------- /apps/website/src/content/config.ts: -------------------------------------------------------------------------------- 1 | import { docsSchema, i18nSchema } from "@astrojs/starlight/schema"; 2 | import { defineCollection } from "astro:content"; 3 | 4 | export const collections = { 5 | docs: defineCollection({ schema: docsSchema() }), 6 | i18n: defineCollection({ type: "data", schema: i18nSchema() }), 7 | }; 8 | -------------------------------------------------------------------------------- /apps/website/src/content/docs/about.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Sobre" 3 | --- 4 | 5 | ## TACO 6 | 7 | O projeto TACO (Tabela Brasileira de Composição de Alimentos), coordenado pelo Núcleo de Estudos e Pesquisas em Alimentação (NEPA) da UNICAMP e com financiamento do Ministério da Saúde – MS e do Ministério do Desenvolvimento Social e Combate à Fome – MDS, é uma iniciativa para proporcionar dados de um grande número de nutrientes em alimentos nacionais e regionais, obtidos por meio de amostragem representativa e análises realizadas por laboratórios com competência analítica comprovada por estudos interlaboratoriais, segundo critérios internacionais. 8 | 9 | :::tip 10 | Para saber mais, leia o [site oficial](http://www.nepa.unicamp.br/taco/home.php?ativo=home) 11 | ::: 12 | 13 | ## Este projeto 14 | 15 | Originalmente, o projeto TACO possui apenas duas maneiras de consumir esses dados. São elas: 16 | 17 | 1. Através de um arquivo PDF. Neste caso, você precisa buscar o alimento desejado e seus respectivos valores; 18 | 2. Através de um arquivo Excel (xls) que, em tese, representa o "banco de dados" dos alimentos. 19 | 20 | Em ambos os casos, a construção de uma aplicação é quase impossível, dado que precisamos dos dados corretamente formatados, bem estruturados e com relações claras entre as informações. 21 | 22 | Assim, o objetivo principal deste projeto é usar os dados originais da pesquisa TACO e estruturá-los de tal forma que fique fácil para a construção de um cliente (mobile ou web). 23 | -------------------------------------------------------------------------------- /apps/website/src/content/docs/api-docs.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Documentação da API" 3 | --- 4 | 5 | GraphQL é uma linguagem tipada para a construção de APIs. 6 | 7 | Pelo fato de termos de tipar todos os esquemas, é possível encontrar a documentação na própria aplicação em que estamos executando as queries, as quais se beneficiam da técnica de ["introspection"](https://graphql.org/learn/introspection/). 8 | 9 | O projeto utiliza GraphQL Yoga, que além de criar e implementar a integração da rota `/graphql` para o método POST, ao receber um GET, retorna um playground interativo: 10 | 11 | ![GraphiQL rodador de queries](../../assets/graphql-playground.png) 12 | 13 | Outra alternativa é utilizar uma ferramenta própria para isso. Há várias opções, como: 14 | 15 | - [Postman](https://www.postman.com/) 16 | - [Insomnia](https://insomnia.rest/) 17 | - [Altair](https://altairgraphql.dev/) - Focada em GraphQL. 18 | -------------------------------------------------------------------------------- /apps/website/src/content/docs/contributing.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Contribuindo" 3 | --- 4 | 5 | ## Bem-vindo(a)! 6 | 7 | Primeiramente, obrigado por você estar interessado(a) em contribuir para a TACO GraphQL API! Este documento contém diretrizes para ajudar você a se tornar um(a) contribuidor(a) efetivo(a). 8 | 9 | ## Como Contribuir 10 | 11 | Você pode contribuir de várias maneiras: 12 | 13 | - Reportando bugs 14 | - Sugerindo melhorias 15 | - Escrevendo ou melhorando a documentação 16 | - Enviando pull requests 17 | 18 | ### Reportando Bugs 19 | 20 | Antes de reportar um bug, por favor, verifique se ele já foi reportado. Se não, crie uma nova issue explicando: 21 | 22 | - O comportamento esperado 23 | - O comportamento observado 24 | - Passos para reproduzir o bug 25 | 26 | ### Sugerindo Melhorias 27 | 28 | Novas ideias são sempre bem-vindas. Abra uma discussão na aba [discussions no Github](https://github.com/raulfdm/taco-api/discussions) descrevendo sua sugestão e como ela pode melhorar o projeto. 29 | 30 | ### Documentação 31 | 32 | A documentação é crucial para entender um projeto. Se você notar falta de documentação ou erros, sinta-se à vontade para corrigir ou adicionar. 33 | 34 | ### Enviando Pull Requests 35 | 36 | Siga estes passos para enviar um pull request: 37 | 38 | 1. Faça um fork do projeto e crie uma nova branch para suas mudanças. 39 | 2. Faça suas alterações e escreva testes quando aplicável. 40 | 3. Siga as convenções de código do projeto. 41 | 4. Atualize a documentação se necessário. 42 | 5. Envie um pull request descrevendo as mudanças propostas. 43 | 44 | ## Processo de Revisão 45 | 46 | Cada contribuição será revisada por mim. Eu posso pedir mudanças ou dar sugestões. 47 | 48 | ## Perguntas 49 | 50 | Se tiver dúvidas, acesse a página das [perguntas frequentes](/faq). Caso sua dúvida não esteja lá, abra uma nova discussão na aba [discussions](https://github.com/raulfdm/taco-api/discussions). 51 | 52 | Obrigado por contribuir com o projeto! 53 | -------------------------------------------------------------------------------- /apps/website/src/content/docs/data-processing.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Processamento de Dados" 3 | --- 4 | 5 | O início do processo se baseia inteiramente no banco de dados (arquivo .xls) disponibilizado por eles. Entretanto, para conseguir um resultado satisfatório e poder inseri-los em um banco de dados relacional, as seguintes etapas foram feitas: 6 | 7 | 1. Baixei a planilha original e subi para o Google Sheets; 8 | 2. Converti de `.xls` (formato proprietário da Microsoft) para `.xlsx` (formato do Office Open XML) para dar mais acessibilidade; 9 | 3. Fiz a limpeza de todas as formatações de linhas, colunas, fontes. Removi as linhas vazias, unifiquei linhas duplicadas ou que foram adicionadas para melhor visualização no estudo; 10 | 4. Substitui os valores não numéricos, onde: 11 | - `NA` (não aplicável) foi convertido para vazio (`null`); 12 | - `*` (valores enviados para re-análise) foi convertido para vazio (`null`); 13 | - `Tr` (valores entre um certo range) foi convertido para para zero (`0`); 14 | 5. Defini nomes em inglês para as colunas; 15 | 6. Criei uma outra planilha (ainda no mesmo documento) que contém todas as categorias possíveis e linkei seus respectivos `id`s na planilha dos alimentos; 16 | 7. Criei uma outra planilha (ainda no mesmo documento) que contém informações nutricionais e linkei com o `id` do alimento; 17 | 8. Exportei cada planilha no documento para `.csv` e baixei dentro do projeto; 18 | 9. Fiz a modelagem do banco de dados usando uma ferramenta chamada `Prisma`; 19 | 10. Criei um scripts para popular o banco de dados na ordem correta, e fazendo a relação entre a informação e o alimento 20 | 21 | ### Dados oficiais 22 | 23 | Para manter os dados originais da pesquisa utilizado para realização desse projeto, [salvei todos os arquivos do site original](https://www.nepa.unicamp.br/taco/tabela.php?ativo=tabela) e você pode consultados na pasta `/references/*` 24 | -------------------------------------------------------------------------------- /apps/website/src/content/docs/database.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Banco de dados" 3 | --- 4 | 5 | O projeto usa SQLite, um banco de dados relacional escrito em C que gera um arquivo local. Isso significa que você não precisa instalar nenhum software adicional para lidar com a estrutura e armazenamento de dados. 6 | 7 | Além disso, o projeto usa um ORM (Object-Relational Mapping) chamado [Prisma](https://www.prisma.io/), que permite a gente interagir com o banco de dados sem precisar escrever queries SQL e definir as estruturas de tabelas e suas relações em uma linguagem mais fácil. 8 | 9 | Caso você queira forkar o projeto e fizer qualquer alteração nos modelos, você precisará fazer [`migrations`](https://www.prisma.io/docs/orm/prisma-migrate/workflows/data-migration) no banco de dados para que as novas colunas/tabelas sejam inseridas. 10 | 11 | Ao fazer qualquer alteração no arquivo `apps/api/src/infrastructure/prisma/schema.prisma`, rode (dentro da pasta do projeto da API) o seguinte comando: 12 | 13 | ```bash 14 | bun run db:migrate --name 15 | ``` 16 | 17 | Isso irá criar um arquivo de migration que deve ser commitado. 18 | 19 | ## Resetando o banco de dados 20 | 21 | Caso queira limpar o banco de dados e reinserir os dados originais, pode usar o comando: 22 | 23 | ```bash 24 | bun run db:reset 25 | ``` 26 | 27 | ## Visualizando os dados 28 | 29 | Caso queira ver o banco de dados em um dashboard, você pode subir o Prisma studio: 30 | 31 | ```bash 32 | bun run studio 33 | ``` 34 | -------------------------------------------------------------------------------- /apps/website/src/content/docs/deploy-docker.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Deploy via Docker" 3 | --- 4 | 5 | Outra opção é você fazer o deploy da aplicação via Docker. 6 | 7 | A cada nova versão, uma nova imagem pública é criada e pode ser vista no [DockerHUB](https://hub.docker.com/repository/docker/raulfdm/taco-api/general). 8 | 9 | Logo, no serviço que você escolher, você pode usar a última versão disponível `raulfdm/taco-api`, ou se for via comando, seria algo como: 10 | 11 | ```bash 12 | docker run -it --rm --name taco -p 4000:4000 raulfdm/taco-api 13 | ``` 14 | -------------------------------------------------------------------------------- /apps/website/src/content/docs/deploy-node.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Deploy como aplicação NodeJS" 3 | --- 4 | 5 | Existem várias maneiras e várias plataformas para fazer o deploy desta API. 6 | 7 | Em qualquer plataforma, procure por uma máquina que tenha suporte para aplicações NodeJS. 8 | 9 | Apesar do projeto usar Bun, em uma máquina que tenha Node, você pode instalar Bun via npm: 10 | 11 | ```bash 12 | npm add -g bun@1.2.2 13 | ``` 14 | 15 | Instalado o Bun globalmente, agora você pode seguir os passos normais: 16 | 17 | Primeiro, instale as dependências: 18 | 19 | ```bash 20 | bun install --production 21 | ``` 22 | 23 | Em seguida, na raiz do projeto, rode o comando: 24 | 25 | ```bash 26 | bun run start --filter=taco-api 27 | ``` 28 | 29 | Isso vai fazer o build e executar o servidor. 30 | 31 | Lembrando que a porta que precisa estar aberta é a `4000`. 32 | -------------------------------------------------------------------------------- /apps/website/src/content/docs/en/about.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "About" 3 | --- 4 | 5 | ## TACO 6 | 7 | The TACO project (Brazilian Table of Food Composition), coordinated by the Center for Studies and Research in Food (NEPA) at UNICAMP and funded by the Ministry of Health – MS and the Ministry of Social Development and Fight Against Hunger – MDS, is an initiative to provide data on a large number of nutrients in national and regional foods, obtained through representative sampling and analyses carried out by laboratories with proven analytical competence through interlaboratory studies, according to international criteria. 8 | 9 | :::tip 10 | To learn more, read the [official website](http://www.nepa.unicamp.br/taco/home.php?ativo=home) 11 | ::: 12 | 13 | ## This Project 14 | 15 | Originally, the TACO project had only two ways of consuming this data. They are: 16 | 17 | 1. Through a PDF file. In this case, you need to search for the desired food and its respective values; 18 | 2. Through an Excel file (xls) which, in theory, represents the "database" of foods. 19 | 20 | In both cases, building an application is almost impossible, as we need the data to be correctly formatted, well-structured, and with clear relationships between the information. 21 | 22 | Thus, the main goal of this project is to use the original data from the TACO research and structure it in such a way that it becomes easy for the development of a client (mobile or web). 23 | -------------------------------------------------------------------------------- /apps/website/src/content/docs/en/api-docs.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "API Documentation" 3 | --- 4 | 5 | GraphQL is a typed language for building APIs. 6 | 7 | Due to the fact that we have to type all the schemas, it is possible to find the documentation in the very application where we are executing the queries, which benefit from the technique of ["introspection"](https://graphql.org/learn/introspection/). 8 | 9 | The project uses GraphQL Yoga, which, in addition to creating and implementing the integration of the `/graphql` route for the POST method, when it receives a GET, returns an interactive playground: 10 | 11 | ![GraphiQL query runner](../../../assets/graphql-playground.png) 12 | 13 | Another alternative is to use a dedicated tool for this. There are several options, such as: 14 | 15 | - [Postman](https://www.postman.com/) 16 | - [Insomnia](https://insomnia.rest/) 17 | - [Altair](https://altairgraphql.dev/) - Focused on GraphQL. 18 | -------------------------------------------------------------------------------- /apps/website/src/content/docs/en/contributing.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Contributing" 3 | --- 4 | 5 | ## Welcome! 6 | 7 | First of all, thank you for being interested in contributing to the TACO GraphQL API! This document contains guidelines to help you become an effective contributor. 8 | 9 | ## How to Contribute 10 | 11 | You can contribute in several ways: 12 | 13 | - Reporting bugs 14 | - Suggesting improvements 15 | - Writing or improving documentation 16 | - Submitting pull requests 17 | 18 | ### Reporting Bugs 19 | 20 | Before reporting a bug, please check if it has already been reported. If not, create a new issue explaining: 21 | 22 | - The expected behavior 23 | - The observed behavior 24 | - Steps to reproduce the bug 25 | 26 | ### Suggesting Improvements 27 | 28 | New ideas are always welcome. Open a discussion in the [discussions tab on Github](https://github.com/raulfdm/taco-api/discussions) describing your suggestion and how it can improve the project. 29 | 30 | ### Documentation 31 | 32 | Documentation is crucial to understanding a project. If you notice a lack of documentation or errors, feel free to correct or add. 33 | 34 | ### Submitting Pull Requests 35 | 36 | Follow these steps to submit a pull request: 37 | 38 | 1. Fork the project and create a new branch for your changes. 39 | 2. Make your changes and write tests when applicable. 40 | 3. Follow the project's coding conventions. 41 | 4. Update the documentation if necessary. 42 | 5. Submit a pull request describing the proposed changes. 43 | 44 | ## Review Process 45 | 46 | Each contribution will be reviewed by me. I may ask for changes or give suggestions. 47 | 48 | ## Questions 49 | 50 | If you have any questions, visit the [frequently asked questions page](/faq). If your question is not there, open a new discussion in the [discussions tab](https://github.com/raulfdm/taco-api/discussions). 51 | 52 | Thank you for contributing to the project! 53 | -------------------------------------------------------------------------------- /apps/website/src/content/docs/en/data-processing.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Data processing" 3 | --- 4 | 5 | The beginning of the process is based entirely on the database (.xls file) they made available. However, to achieve a satisfactory result and to be able to insert it into a relational database, the following steps were taken: 6 | 7 | 1. I downloaded the original spreadsheet and uploaded it to Google Sheets; 8 | 2. I converted it from `.xls` (proprietary Microsoft format) to `.xlsx` (Office Open XML format) for better accessibility; 9 | 3. I cleaned up all the rows, columns, and font formatting. I removed empty rows, merged duplicate rows or rows that were added for better visualization in the study; 10 | 4. Replaced the non-numeric values, where: 11 | - `NA` (not applicable) was converted to empty (`null`); 12 | - `*` (values sent for re-analysis) has been converted to empty (`null`); 13 | - `Tr` (values between a specific range) has been converted to zero (`0`); 14 | 5. I defined English names for the columns; 15 | 6. I created another worksheet (still in the same document) that contains all the possible categories and linked theirs `id's to the food worksheet; 16 | 7. I created another sheet (still in the same document) that contains nutritional information and linked it to the `id` of the food; 17 | 8. I exported each spreadsheet in the document to `.csv` and downloaded it into the project; 18 | 9. I modeled the database using a tool called `Prisma`; 19 | 10. I created a script to populate the database in the correct order and make the relationship between the information and the food. 20 | 21 | ## Official data 22 | 23 | To keep the original research data used for this project, [I have saved all the files from the original site](https://www.nepa.unicamp.br/taco/tabela.php?ativo=tabela) and you can consult them in the `/references/*` folder 24 | -------------------------------------------------------------------------------- /apps/website/src/content/docs/en/database.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Database" 3 | --- 4 | 5 | The project uses SQLite, a relational database written in C that generates a local file. This means you don't need to install any additional software to handle the structure and storage of data. 6 | 7 | Additionally, the project uses an ORM (Object-Relational Mapping) called [Prisma](https://www.prisma.io/), which allows us to interact with the database without needing to write SQL queries and define the structures of tables and their relationships in an easier language. 8 | 9 | If you want to fork the project and make any changes to the models, you will need to perform [`migrations`](https://www.prisma.io/docs/orm/prisma-migrate/workflows/data-migration) in the database so that the new columns/tables are inserted. 10 | 11 | When making any changes to the `apps/api/src/infrastructure/prisma/schema.prisma` file, run (inside the project's API folder) the following command: 12 | 13 | ```bash 14 | bun run db:migrate --name 15 | ``` 16 | 17 | This will create a migration file that should be committed. 18 | 19 | ## Resetting the Database 20 | 21 | If you want to clear the database and reinsert the original data, you can use the command: 22 | 23 | ```bash 24 | bun run db:reset 25 | ``` 26 | 27 | ## Viewing the Data 28 | 29 | If you want to see the database in a dashboard, you can launch Prisma Studio: 30 | 31 | ```bash 32 | bun run studio 33 | ``` 34 | -------------------------------------------------------------------------------- /apps/website/src/content/docs/en/deploy-docker.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Deploy via Docker" 3 | --- 4 | 5 | Another option is to deploy the application via Docker. 6 | 7 | With each new version, a new public image is created and can be seen on [DockerHUB](https://hub.docker.com/repository/docker/raulfdm/taco-api/general). 8 | 9 | Thus, in the service you choose, you can use the latest available version `raulfdm/taco-api`, or if it's via command, it would be something like: 10 | 11 | ```bash 12 | docker run -it --rm --name taco -p 4000:4000 raulfdm/taco-api 13 | ``` 14 | -------------------------------------------------------------------------------- /apps/website/src/content/docs/en/deploy-node.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Deploy as Node app" 3 | --- 4 | 5 | There are several ways and platforms to deploy this API. 6 | 7 | On any platform, look for a machine that supports NodeJS applications. 8 | 9 | Although the project uses Bun, on a machine that has Node, you can install Bun via npm: 10 | 11 | ```bash 12 | npm add -g bun@1.2.2 13 | ``` 14 | 15 | Having installed bun globally, you can now follow the normal steps: 16 | 17 | First, install the dependencies: 18 | 19 | ```bash 20 | bun install --production 21 | ``` 22 | 23 | Then, at the root of the project, run the command: 24 | 25 | ```bash 26 | bun run start --filter=taco-api 27 | ``` 28 | 29 | This will build and run the server. 30 | 31 | Remember that the port that needs to be open is `4000`. 32 | -------------------------------------------------------------------------------- /apps/website/src/content/docs/en/faq.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "FAQ" 3 | --- 4 | 5 | ### Why did you switch from Node to Bun? 6 | 7 | Bun is a JavaScript runtime that is entirely focused on performance. 8 | 9 | Bun has (almost) all of Node's APIs implemented with zero breaking changes, meaning there is no incompatibility with the Node ecosystem, at most, some APIs that have not yet been implemented. 10 | 11 | In addition, Bun includes various integrated functionalities and tools, such as native TypeScript support, dependency management, testing, etc. 12 | 13 | Even though it is still in version 1, Bun is already quite mature and ready for production. 14 | 15 | ### Is there an online demo? 16 | 17 | No. 18 | I used to leave a version hosted on Heroku, but people were building apps that hit it directly, and my usage quota expired very quickly. 19 | 20 | Also, Heroku stopped offering the free plan, making it even more difficult. 21 | 22 | ### Can I use this project to build a client application? 23 | 24 | Yes, the project is free for anyone to use. However, as I said before, it is no longer available online. You must upload the server to a cloud service if you want access. 25 | 26 | ### Is the project still maintained? 27 | 28 | More or less. 29 | When I created it, I intended to study API builds using NodeJS. 30 | When I want to test something new that fits this scope, I update one thing or another. Still, my career and professional focus is not that. I have little time available, and I always prefer other projects. 31 | 32 | ### Why did you convert the project from Rest to GraphQL? 33 | 34 | I took this decision precisely because I wanted to revisit the creation of APIs in Node but using the new tools, and also because I believe it is much easier and more intuitive to bring the information that the customer needs. 35 | If you are not so familiar with GraphQL, I strongly recommend that you study the basics to at least be able to consume it, or use version 1 of the project. 36 | 37 | ### Why a database instead of local files? 38 | 39 | In version 2, I chose a relational database because I believe that the structure of Taco's data is extremely relational. 40 | There is a relationship between the category and the food, the food and its amino acids, the food, and its nutrients, etc. 41 | Making these relationships using a database is much easier than using JSON files. 42 | 43 | ### Why SQLite and not Postgresql or another database? 44 | 45 | Initially, I started with Postgres. However, I think it offers much more than this application needs (5 or 6 tables with at most 500 rows) and adds complexity to the application deployment. 46 | SQLite allows us to save the database along with the rest of the files, making the whole process easier. 47 | 48 | ## Legal Information 49 | 50 | This is a non-profit project. 51 | All data used was researched and produced by [UNICAMP](http://Unicamp.br), and all copyrights are reserved to the institution. 52 | 53 | ## Doubts? 54 | 55 | If you have any questions or suggestions about this project, look in the "discussion" tab on the GitHub of this repository. If your question is not there, start a new thread [by clicking here](https://github.com/raulfdm/taco-api/discussions/new), and I will answer as soon as possible! 56 | -------------------------------------------------------------------------------- /apps/website/src/content/docs/en/getting-started.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Getting Started" 3 | --- 4 | 5 | ## Prerequisites 6 | 7 | Before you start the initial setup, you need to have 2 runtimes installed: 8 | 9 | - [NodeJS](https://nodejs.org/en) version 20 or higher 10 | - [Bun](https://bun.sh/) version 1.2.2 or higher 11 | 12 | Although Bun is the primary runtime, one of the dependencies ([Prisma](https://www.prisma.io/)) still requires Node to generate the initial files. 13 | 14 | :::tip 15 | 16 | If you already have Node installed, you can install `bun` via npm: 17 | 18 | ```bash 19 | npm install -g bun@1.2.2 20 | ``` 21 | 22 | ::: 23 | 24 | ## Configuration 25 | 26 | You can either fork this project or clone it, the choice is yours. 27 | 28 | Now, the first step is to install the project dependencies: 29 | 30 | ```bash 31 | bun install 32 | ``` 33 | 34 | ## Running the Server 35 | 36 | The project is set up as a [monorepo](https://turbo.build/repo/docs/handbook/what-is-a-monorepo) (or workspace) using a tool called [turbo repo](https://turbo.build/repo). 37 | 38 | This means that to run the server from the project root, you need to run: 39 | 40 | ```bash 41 | bun run dev --filter=taco-api 42 | ``` 43 | 44 | ## Running the Server with Docker 45 | 46 | If you want a fully configured environment, it's also possible to run the project via Docker. 47 | 48 | For this, at the project root, run the command: 49 | 50 | ```bash 51 | docker-compose -f ./apps/api/docker-compose.yml up 52 | ``` 53 | 54 | :::note 55 | The docker-compose is configured to run the API in development mode. To deploy as a docker image, visit the section [Deploy > Docker](/deploy-docker) 56 | ::: 57 | 58 | ## Running the Documentation 59 | 60 | If you want to edit the documentation, in the project's root directory, run the command: 61 | 62 | ```bash 63 | bun run dev --filter=website 64 | ``` 65 | -------------------------------------------------------------------------------- /apps/website/src/content/docs/en/tech.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Technologies" 3 | --- 4 | 5 | - [NodeJS](https://nodejs.org/en) - JavaScript runtime for Prisma to generate files (this is probably temporary) 6 | - [Bun](https://bun.sh/) - JavaScript runtime to run scripts and launch the server 7 | - [ElysiaJS](https://elysiajs.com/) - HTTP Framework to run with Bun 8 | - [GraphQL Yoga](https://elysiajs.com/plugins/graphql-yoga.html) - GraphQL handler 9 | - [Prisma](https://www.prisma.io/) - Object-Relational Mapping (ORM) in JavaScript to populate the database and define relationships 10 | - [SQLite](https://sqlite.org/) - Mini relational database 11 | - [GraphQL](https://graphql.org/) - Query language for the API 12 | - [Starlight](https://starlight.astro.build/) - Site generator for documentation 13 | -------------------------------------------------------------------------------- /apps/website/src/content/docs/faq.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Perguntas Frequentes" 3 | --- 4 | 5 | ## Por que você migrou de Node pra Bun? 6 | 7 | Bun é um runtime JavaScript que tem foco total em performance. 8 | 9 | Bun possui (quase) todas APIs do Node implementadas com zero breaking change, ou seja, não possui nenhum incompatibilidade com o ecossistema Node, no máximo, alguma API que ainda não foi implementada. 10 | 11 | Além disso, Bun conta com várias funcionalidades e ferramentas integradas, como por exemplo, suporte nativo à TypeScript, gerenciamento de dependencias, tests, etc. 12 | 13 | Ainda que esteja na versão 1, Bun já está bem maduro e pronto pra produção. 14 | 15 | ## Existe uma demo online? 16 | 17 | Não. 18 | Antigamente eu deixava uma versão hospedada no heroku, mas as pessoas estavam construindo aplicações que batiam diretamente nele e a minha quota de uso expirava muito rápido. 19 | 20 | Além disso, o Heroku deixou de oferecer o plano gratuito, dificultando ainda mais o processo. 21 | 22 | ## Posso utilizar esse projeto para construir uma aplicação cliente? 23 | 24 | Sim, o projeto é livre para qualquer pessoa utilizar. Porém, como disse anteriormente, ele não está mais disponível online, ou seja, você precisará subir o servidor em algum serviço de cloud caso queira ter acesso. 25 | 26 | ## O projeto ainda é mantido? 27 | 28 | Mais ou menos. 29 | Quando eu o criei, a intenção era estudar construções de API utilizando NodeJS. 30 | Quando quero testar algo novo e que cabe neste escopo, eu atualizo uma coisa ou outra, mas como meu foco de carreira e profissional não é esse e eu tenho pouco tempo disponível, sempre dou preferência para outros projetos. 31 | 32 | ## Por que você converteu o projeto de Rest para GraphQL? 33 | 34 | Eu tomei essa decisão justamente porque queria revisitar a criação de APIs em Node, mas utilizando as novas ferramentas, e também porque eu acredito ser muito mais fácil e intuitivo você trazer as informações que o consumidor precisa. 35 | Caso você não esteja tão familiarizado com GraphQL, recomendo fortemente que estude o básico para pelo menos conseguir consumir, ou então, utilize a versão 1 do projeto. 36 | 37 | ## Por que um banco de dados ao invés dos arquivos locais? 38 | 39 | Na versão 2, eu escolhi um banco de dados relacional porque acredito que a estrutura dos dados da Taco é extremamente relacional. 40 | Existe uma relação entre a categoria e o alimento, o alimento e seus aminoácidos, o alimento e seus nutrientes, etc. 41 | Fazer essas relações utilizando um banco de dados é muito mais fácil do que utilizar arquivos JSON. 42 | 43 | ## Por que SQLite e não Postgresql ou outro banco de dados? 44 | 45 | Inicialmente eu comecei com Postgres. Porém, acho que ele oferece muito mais do que essa aplicação de fato precisa (umas 5 ou 6 tabelas com no máximo 500 linhas), além de adicionar complexidade no deploy da aplicação. 46 | O SQLite permite a gente gravar a base de dados junto com o restante dos arquivos, e isso facilita todo o processo. 47 | 48 | ## Informações Legais 49 | 50 | Este é um projeto sem fins lucrativos. 51 | Todos os dados utilizados foram pesquisados e produzidos pela [UNICAMP](http://Unicamp.br), e todo direito autoral é reservado à instituição. 52 | 53 | ## Dúvidas? 54 | 55 | Se você tiver alguma dúvida ou sugestão sobre este projeto, procure na aba "discussão" no Github deste repositório. Caso sua dúvida não esteja lá, inicie uma nova discussão [clicando aqui](https://github.com/raulfdm/taco-api/discussions/new) e eu responderei o quanto antes! 56 | -------------------------------------------------------------------------------- /apps/website/src/content/docs/getting-started.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Começando" 3 | --- 4 | 5 | ## Pré-requisitos 6 | 7 | Antes de fazer a configuração inicial, você precisa ter 2 runtimes instalados: 8 | 9 | - [NodeJS](https://nodejs.org/en) versão 20 ou superior 10 | - [Bun](https://bun.sh/) versão 1.2.2 ou superior 11 | 12 | Apesar do Bun ser o runtime principal, uma das dependências ([Prisma](https://www.prisma.io/)) ainda precisa do Node para gerar os arquivos iniciais. 13 | 14 | :::tip 15 | 16 | Caso já tenha o Node instalado, você pode o `bun` via npm: 17 | 18 | ```bash 19 | npm install -g bun@1.2.2 20 | ``` 21 | 22 | ::: 23 | 24 | ## Configuração 25 | 26 | Você pode tanto fazer um fork deste projeto quanto cloná-lo, fica a seu critério. 27 | 28 | Agora, o primeiro passo é instalar as dependências do projeto: 29 | 30 | ```bash 31 | bun install 32 | ``` 33 | 34 | ## Rodando o servidor 35 | 36 | O projeto está configurado como um [monorepo](https://turbo.build/repo/docs/handbook/what-is-a-monorepo) (ou workspace) usando uma ferramenta chamada [turbo repo](https://turbo.build/repo). 37 | 38 | Isso significa que para rodar o servidor através da raiz do projeto, você precisa rodar: 39 | 40 | ```bash 41 | bun run dev --filter=taco-api 42 | ``` 43 | 44 | Esse comando vai gerar os arquivos necessarios e iniciar o servidor HTTP da API no endereço [http://localhost:4000/graphql](http://localhost:4000/graphql) 45 | 46 | ## Rodando o servidor com Docker 47 | 48 | Caso queira um ambiente totalmente configurado sem precisar instalar nada, é possível rodar o projeto via docker. 49 | 50 | Para isso, na raiz do projeto, rode o comando: 51 | 52 | ```bash 53 | docker-compose -f ./apps/api/docker-compose.yml up 54 | ``` 55 | 56 | :::note 57 | O docker-compose está configurado para rodar a API em modo de desenvolvimento. Para fazer o deploy como uma imagem docker, acesse a seção [Deploy > Docker](/deploy-docker) 58 | ::: 59 | 60 | ## Rodando a documentação 61 | 62 | Caso queira editar a documentação, na raíz do projeto rode o comando: 63 | 64 | ```bash 65 | bun run dev --filter=website 66 | ``` 67 | -------------------------------------------------------------------------------- /apps/website/src/content/docs/tech.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Tecnologias" 3 | --- 4 | 5 | - [NodeJS](https://nodejs.org/en) - JavaScript runtime para o Prisma conseguir gerar os arquivos (isso provavelmente é temporário) 6 | - [Bun](https://bun.sh/) - JavaScript runtime para rodar os scripts e subir o servidor 7 | - [ElysiaJS](https://elysiajs.com/) - Framework HTTP feito para rodar com Bun 8 | - [GraphQL Yoga](https://elysiajs.com/plugins/graphql-yoga.html) - Implementação do GraphQL 9 | - [Prisma](https://www.prisma.io/) - Object-Relational Mapping (ORM) em JavaScript para popular o banco de dados e definir as relações 10 | - [SQLite](https://sqlite.org/) - Mini banco de dados relacional 11 | - [GraphQL](https://graphql.org/) - Linguagem de consulta para a API 12 | - [Starlight](https://starlight.astro.build/) - Gerador de site para documentação 13 | -------------------------------------------------------------------------------- /apps/website/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | -------------------------------------------------------------------------------- /apps/website/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "astro/tsconfigs/strict", 3 | "exclude": [ 4 | "node_modules", 5 | "dist", 6 | ".astro", 7 | ".turbo" 8 | ] 9 | } -------------------------------------------------------------------------------- /biome.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://biomejs.dev/schemas/1.4.0/schema.json", 3 | "files": { 4 | "ignore": ["*.d.ts"] 5 | }, 6 | "organizeImports": { 7 | "enabled": true 8 | }, 9 | "json": { 10 | "parser": { 11 | "allowComments": true 12 | } 13 | }, 14 | "formatter": { 15 | "indentStyle": "space" 16 | }, 17 | "linter": { 18 | "enabled": true, 19 | "rules": { 20 | "recommended": true 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "taco-workspace", 3 | "private": true, 4 | "workspaces": ["apps/*"], 5 | "type": "module", 6 | "license": "MIT", 7 | "author": { 8 | "name": "Raul de Melo", 9 | "email": "contact@raulmelo.me" 10 | }, 11 | "scripts": { 12 | "prepare": "husky && bun run scripts/fix-graphql-types.ts", 13 | "build": "turbo build", 14 | "dev": "turbo dev", 15 | "dev:docker": "docker-compose -f ./apps/api/docker-compose.yml up", 16 | "start": "turbo start", 17 | "lint": "turbo lint", 18 | "lint:ci": "turbo lint:ci", 19 | "db:generate": "turbo db:generate", 20 | "image:build": "bun run scripts/build-image.ts", 21 | "image:deploy": "bun run image:build" 22 | }, 23 | "devDependencies": { 24 | "@biomejs/biome": "1.9.4", 25 | "@changesets/cli": "2.27.12", 26 | "@types/bun": "1.2.2", 27 | "husky": "9.1.7", 28 | "lint-staged": "15.4.3", 29 | "minimist": "1.2.8", 30 | "turbo": "2.4.0", 31 | "typescript": "5.7.3" 32 | }, 33 | "packageManager": "bun@1.2.2", 34 | "engines": { 35 | "bun": "1.2.2" 36 | }, 37 | "lint-staged": { 38 | "*.{js,ts,json}": "bunx @biomejs/biome check --apply" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /references/README.md: -------------------------------------------------------------------------------- 1 | # Referencias 2 | 3 | Os arquivos de referencias foram todos obtidos no site da própria UNICAMP ([http://www.nepa.unicamp.br/taco/tabela.php](http://www.nepa.unicamp.br/taco/tabela.php)). 4 | 5 | Para montar este projeto, 2 arquivos foram usados como base: 6 | 7 | - [original-Taco_4a_edicao_2011.xls](./original-Taco_4a_edicao_2011.xls) - Esse arquivo é a versão original e sem alterações do arquivo de banco de dados, disponibilizado no site; 8 | - [taco_4_edicao_ampliada_e_revisada.pdf](./taco_4_edicao_ampliada_e_revisada.pdf) - Esse é o estudo em completo com comentários e descrições de como as medições foram realizadas. Serviu como base de referencia para duvidas pontuais sobre os dados, legendas, etc. 9 | 10 | ## Processo de tratamento dos dados 11 | 12 | Dentro da pasta `./references/normalization`, você vai encontrar arquivos `.xlsx`. Cada arquivo representa uma etapa do tratamento, tendo foco na modelagem relacional que será feita posteriormente e inserção no banco de dados. 13 | 14 | Abaixo, a lista dos arquivos e suas descrições: 15 | 16 | - `taco_phase_1_no_format.xlsx` - a limpeza da formatação da tabela. Aqui, me concentrei em tirar linhas em branco, duplas ou duplicadas e qualquer coisa que dificultasse a transposição de `.xlsx` pra `.csv` no final do processo; 17 | - `taco_phase_2_normalize_values` - nessa etapa, eu normalizei valores de células que não fossem números. Isso é extremamente importante para a inserção dos valores no banco de dados posteriormente. As alterações foram as seguintes: 18 | - `NA` (Não Aplicável) -> deixei o espaço em branco 19 | - `*` (Amostras sendo reavaliadas) -> deixei o valor em branco 20 | - `Tr` (traço) -> Traço representa valores que entre 0.5 e 0, ou seja, valores que não tem relevância. Coloquei o valor de `0`. 21 | - `taco_phase_3_rename_labels` -> Nessa etapa, eu fiz uma limpeza nos nomes das colunas, removendo espaços, a unidade dos nutrientes e traduzindo para inglês; 22 | - `taco_phase_4_decouple_category` -> Nessa etapa, eu criei uma outra tabela somente com as categorias, assim, ao invés de duplicar o nome da categoria (por exemplo `Cereais e derivados`), eu faço uma referencia ao seu `id` em cada alimento (por exemplo, `1`); 23 | - `taco_phase_5_decouple_food` -> A última etapa foi separar o alimento dos nutrientes em outra planilha, criando uma relação pelo seu ID entre as outras tabelas. 24 | 25 | Por último, fiz a extração de todas as planilhas dentro do `taco_phase_5_decouple_food` para `.csv` (comma separated value). Isso facilita na transposição dos dados em JSON. 26 | -------------------------------------------------------------------------------- /references/csv/amino-acids.csv: -------------------------------------------------------------------------------- 1 | foodId,tryptophan,threonine,isoleucine,leucine,lysine,methionine,cystine,phenylalanine,tyrosine,valine,arginine,histidine,alanine,asparticAcid,glutamicAcid,glycine,proline,serine 2 | 56,0.12,0.30,0.41,0.81,0.39,0.19,0.07,0.50,0.36,0.50,0.41,0.18,0.31,0.54,3.37,0.30,1.18,0.47 3 | 80,0.00,0.03,0.03,0.06,0.05,0.01,0.00,0.04,0.04,0.04,0.06,0.02,0.05,0.05,0.11,0.04,0.03,0.03 4 | 83,0.01,0.03,0.04,0.07,0.08,0.01,0.00,0.05,0.06,0.05,0.08,0.02,0.06,0.05,0.18,0.05,0.03,0.04 5 | 123,0.00,0.01,0.03,0.04,0.02,0.00,0.02,0.02,0.00,0.02,0.02,0.04,0.04,0.09,0.32,0.01,0.06,0.01 6 | 147,0.01,0.05,0.04,0.08,0.07,0.01,0.00,0.05,0.03,0.06,0.11,0.02,0.07,0.27,0.33,0.05,0.04,0.06 7 | 151,0.01,0.03,0.06,0.07,0.07,0.01,0.00,0.05,0.04,0.07,0.07,0.04,0.10,0.17,0.53,0.06,0.08,0.08 8 | 176,0.00,0.01,0.02,0.04,0.00,0.00,0.02,0.01,0.01,0.03,0.01,0.03,0.02,0.08,0.09,0.00,0.00,0.03 9 | 185,0.00,0.02,0.02,0.04,0.03,0.01,0.00,0.02,0.02,0.03,0.03,0.01,0.06,0.07,0.08,0.02,0.02,0.02 10 | 224,0.00,0.01,0.01,0.01,0.00,0.01,0.01,0.00,0.02,0.00,0.02,0.03,0.01,0.04,0.02,0.00,0.00,0.03 11 | 227,0.00,0.02,0.00,0.00,0.00,0.01,0.01,0.01,0.02,0.01,0.02,0.04,0.01,0.01,0.01,0.01,0.01,0.03 12 | 229,0.02,0.01,0.02,0.03,0.02,0.01,0.00,0.02,0.01,0.02,0.02,0.01,0.03,0.03,0.04,0.02,0.02,0.02 13 | 248,0.00,0.01,0.01,0.02,0.02,0.00,0.00,0.01,0.01,0.01,0.02,0.00,0.02,0.03,0.04,0.01,0.01,0.01 14 | 323,0.16,0.67,0.74,1.16,1.26,0.45,0.24,0.69,0.59,0.79,1.19,0.77,0.86,1.36,2.54,0.76,0.67,0.64 15 | 424,0.14,0.57,0.61,0.94,1.05,0.39,0.30,0.59,0.52,0.66,1.08,0.48,0.88,1.18,2.16,1.00,0.74,0.60 16 | 438,0.11,0.73,0.71,1.17,1.35,0.47,0.23,0.67,0.58,0.74,1.22,0.91,0.90,1.41,2.39,0.81,0.70,0.68 17 | 439,0.15,0.71,0.69,1.15,1.28,0.48,0.22,0.63,0.55,0.72,1.20,0.89,0.88,1.37,2.36,0.73,0.65,0.68 18 | 441,0.02,0.35,0.40,0.78,0.93,0.23,0.04,0.46,0.45,0.48,0.85,0.50,0.65,1.00,2.16,0.51,0.47,0.45 19 | 443,0.28,1.22,1.21,2.02,0.07,0.79,0.35,1.08,0.97,1.30,1.96,1.30,1.61,2.34,4.24,1.55,1.38,1.15 20 | 463,0.38,1.05,1.39,2.38,2.06,0.85,0.36,1.27,1.61,1.77,1.13,0.86,0.79,1.76,5.91,0.55,2.76,1.50 21 | 467,0.48,1.01,1.21,2.19,1.94,0.82,0.36,1.13,1.43,1.47,1.14,0.84,0.81,1.66,5.33,0.56,2.76,1.54 22 | 468,0.00,0.03,0.05,0.10,0.10,0.02,0.02,0.06,0.02,0.07,0.33,0.03,0.41,0.23,0.44,0.99,0.58,0.09 23 | 501,0.03,0.23,0.28,0.56,0.34,0.12,0.02,0.23,0.21,0.34,0.18,0.07,0.22,0.44,1.28,0.09,0.57,0.28 24 | 506,0.20,0.02,0.00,0.01,0.01,0.01,0.01,0.01,0.02,0.01,0.02,0.04,0.01,0.05,0.01,0.02,0.01,0.04 25 | 509,0.07,0.21,0.23,0.42,0.33,0.10,0.03,0.20,0.16,0.26,0.48,0.06,0.31,0.36,0.75,0.16,0.22,0.36 26 | 510,0.02,0.02,0.00,0.01,0.01,0.01,0.02,0.01,0.03,0.01,0.03,0.06,0.00,0.16,0.04,0.02,0.02,0.05 27 | 580,0.07,0.34,0.50,0.97,0.48,0.14,0.09,0.75,0.54,0.58,1.87,0.25,0.63,1.80,3.09,0.91,0.62,0.69 -------------------------------------------------------------------------------- /references/csv/categories.csv: -------------------------------------------------------------------------------- 1 | id,name 2 | 1,Cereais e derivados 3 | 2,"Verduras, hortaliças e derivados" 4 | 3,Frutas e derivados 5 | 4,Gorduras e óleos 6 | 5,Pescados e frutos do mar 7 | 6,Carnes e derivados 8 | 7,Leite e derivados 9 | 8,Bebidas (alcoólicas e não alcoólicas) 10 | 9,Ovos e derivados 11 | 10,Produtos açucarados 12 | 11,Miscelâneas 13 | 12,Outros alimentos industrializados 14 | 13,Alimentos preparados 15 | 14,Leguminosas e derivados 16 | 15,Nozes e sementes -------------------------------------------------------------------------------- /references/csv/fatty-acids.csv: -------------------------------------------------------------------------------- 1 | foodId,saturated,monounsaturated,polyunsaturated,12:0,14:0,16:0,18:0,20:0,22:0,24:0,14:1,16:1,18:1,20:1,18:2n6,18:3n3,20:4,20:5,22:5,22:6,18:1t,18:2t 2 | 1,0.3,0.4,0.3,,0.00,0.25,0.02,0.00,0.00,0.00,,,0.36,0.00,0.31,0.01,,,0.00,,, 3 | 2,0.3,0.5,0.4,,0.01,0.24,0.02,0.01,0.00,0.00,,0.00,0.45,0.00,0.38,0.02,,,,,, 4 | 3,0.2,0.0,0.0,,0.00,0.16,0.01,,,,,,0.04,,0.06,,,,,,, 5 | 4,0.1,0.1,0.1,0.00,0.00,0.06,0.01,0.00,0.00,0.00,,,0.06,,0.08,0.00,,,,,,0.00 6 | 5,0.1,0.1,0.1,,0.00,0.12,0.02,,,,,0.00,0.12,0.00,0.09,0.00,,,,,, 7 | 6,0.1,0.1,0.1,,0.00,0.06,0.01,0.00,0.00,0.00,,,0.09,0.00,0.09,0.00,,,,,, 8 | 7,1.5,3.2,3.0,,0.02,1.37,0.14,0.00,,0.02,,0.00,3.10,0.05,2.95,0.06,,,,,, 9 | 8,3.9,3.7,2.2,0.03,0.07,2.76,0.94,0.03,0.02,0.01,,0.02,3.70,0.02,2.13,0.10,,,,,1.36,0.22 10 | 9,6.2,6.6,1.7,0.19,0.13,3.11,2.55,0.07,0.07,0.02,,0.02,6.55,0.04,1.68,0.06,,,,,3.84,0.37 11 | 10,6.1,6.5,1.7,0.07,0.07,3.35,2.41,0.06,,,,0.04,6.40,0.02,1.61,0.06,,,,,4.21,0.32 12 | 11,6.5,8.1,1.9,,0.02,3.21,3.02,0.09,0.12,0.02,0.02,0.02,8.07,0.02,1.84,0.09,,,,,6.63,0.42 13 | 12,6.7,8.9,1.8,,0.03,3.32,3.10,0.10,0.10,0.03,,0.03,8.83,0.03,1.77,0.08,,,,,7.24,0.56 14 | 13,4.4,4.6,2.9,0.01,0.07,2.99,1.24,0.04,0.03,0.01,,0.06,4.52,0.03,2.79,0.01,,,,,1.57,0.23 15 | 14,2.1,1.9,0.8,0.01,0.03,1.03,0.97,0.02,0.02,0.01,,0.01,1.88,0.01,0.78,0.03,,,,,0.93,0.15 16 | 15,5.0,3.9,1.1,0.98,0.48,1.88,1.28,0.04,0.04,0.01,,0.06,3.80,0.02,1.00,0.06,0.04,,,,1.99, 17 | 16,5.5,6.2,3.0,,0.06,2.97,2.33,0.07,0.06,0.02,,0.06,6.15,0.04,2.83,0.04,0.02,,,,2.49,0.42 18 | 17,4.9,3.0,1.8,1.00,0.48,1.82,1.24,0.03,0.03,0.01,,0.05,2.92,0.03,1.69,0.06,0.02,,,,0.89,0.19 19 | 18,4.5,3.9,1.5,0.79,0.37,1.79,1.19,0.04,0.05,0.01,,0.06,3.79,0.03,1.34,0.08,0.04,,,,1.82,0.17 20 | 19,0.3,0.2,0.4,,,0.27,0.03,0.00,,0.00,,0.00,0.24,0.00,0.38,0.01,,,,,, 21 | 20,0.6,0.4,0.1,0.01,0.08,0.37,0.15,0.00,,,,0.02,0.35,,0.15,0.00,,,,,0.02, 22 | 21,0.5,0.6,0.9,,0.00,0.39,0.05,0.01,0.00,0.01,,0.00,0.60,0.01,0.89,0.03,,,,,, 23 | 22,0.3,0.3,0.6,,0.00,0.27,0.03,0.01,0.00,0.00,,0.00,0.33,0.00,0.60,0.02,,,,,, 24 | 23,0.3,0.3,0.5,,0.00,0.26,0.03,0.00,0.00,,,,0.28,0.00,0.45,0.01,,,,,0.00,0.00 25 | 24,0.5,0.4,1.0,,0.00,0.43,0.03,0.00,0.00,0.00,,0.00,0.34,0.02,0.93,0.06,,,,,,0.01 26 | 25,0.4,0.3,0.3,,,0.32,0.04,0.00,0.00,0.00,,0.00,0.32,,0.31,0.00,,0.00,,,0.00, 27 | 26,0.2,0.3,0.3,,,0.20,0.03,0.00,0.00,0.00,,0.00,0.29,,0.33,0.00,,0.00,,,0.00, 28 | 27,0.4,0.3,0.4,,0.01,0.37,0.03,0.00,,0.01,,0.00,0.31,0.00,0.43,0.01,,,,,, 29 | 28,0.3,0.5,0.8,,,0.29,0.04,0.01,,0.00,,0.00,0.45,0.00,0.75,0.02,,,,,, 30 | 29,0.8,0.5,0.2,0.01,0.11,0.48,0.19,0.00,,,0.00,0.03,0.44,,0.17,0.00,,,,,0.04, 31 | 30,3.0,4.9,1.4,,0.01,1.55,1.30,0.05,0.06,0.03,, ,4.85,0.03,1.38,0.03,,,,,2.81,0.63 32 | 31,0.2,0.1,0.2,0.00,0.00,0.18,0.01,0.00,0.00,0.00,,0.00,0.08,0.00,0.17,0.01,,,,,0.00,0.00 33 | 32,0.3,0.3,0.8,,0.00,0.31,0.02,0.00,0.00,,,0.00,0.26,0.01,0.73,,,,,,,0.00 34 | 33,0.4,0.4,0.6,0.00,0.00,0.30,0.04,0.01,,,,0.00,0.38,0.00,0.63,0.02,,,,,, 35 | 34,0.6,0.4,0.8,0.01,0.02,0.44,0.07,0.00,,,,0.01,0.37,0.01,0.74,0.05,,,,,0.02,0.01 36 | 35,0.3,0.2,0.4,,0.00,0.30,0.01,0.00,0.00,0.00,,0.00,0.13,,0.43,0.01,,0.00,0.00,,,0.00 37 | 36,3.3,1.4,0.6,0.12,0.50,1.73,0.58,0.01,0.01,,0.03,0.11,1.20,,0.59,0.03,,,,,0.13,0.02 38 | 37,0.6,0.4,0.1,,,0.48,0.10,,,,,0.02,0.40,0.00,0.10,,,,,,, 39 | 38,0.5,0.4,0.4,,,0.39,0.08,,,,,0.01,0.39,0.00,0.38,0.01,,,,,, 40 | 41,0.5,0.4,0.8,,,0.46,0.07,0.00,0.00,0.00,,0.00,0.38,0.00,0.73,0.03,,,,,,0.00 41 | 43,0.4,0.9,1.3,,,0.35,0.07,0.02,0.00,0.00,,0.00,0.89,0.00,1.29,0.03,,,0.00,,, 42 | 44,0.2,0.2,0.6,,,0.16,0.01,0.00,0.00,0.00,,0.00,0.23,0.00,0.53,0.02,,,,,, 43 | 45,0.6,0.8,0.9,,,0.49,0.06,0.01,,,,0.00,0.78,0.00,0.88,0.03,,,,,, 44 | 46,0.1,0.0,0.1,0.00,,0.12,0.01,,,,,,0.05,,0.13,0.01,,,,,, 45 | 47,0.5,0.7,1.4,,0.01,0.37,0.12,0.01,0.01,0.01,, ,0.65,0.02,1.32,0.09,,,,,0.07,0.04 46 | 48,1.1,1.0,1.6,0.00,0.01,0.62,0.40,0.01,0.01,,,0.01,0.94,0.02,1.06,0.59,,,,,0.11,0.01 47 | 49,0.7,0.6,1.6,,0.01,0.52,0.16,0.01,0.01,,,0.01,0.62,0.01,1.41,0.14,,,,,0.01, 48 | 50,0.5,0.6,0.7,,0.00,0.39,0.08,0.01,0.01,,,0.01,0.56,0.01,0.69,0.04,,,,,0.11,0.05 49 | 51,0.6,0.6,1.0,0.01,0.01,0.47,0.11,0.01,0.01,,,0.01,0.62,0.01,0.98,0.03,,,,,0.07, 50 | 52,0.7,0.8,1.1,0.00,0.01,0.50,0.19,0.01,0.01,,,0.02,0.74,0.01,0.98,0.08,,,,,0.21,0.07 51 | 53,1.0,0.9,0.7,0.00,0.01,0.65,0.29,0.01,0.01,,,0.00,0.85,0.01,0.70,0.04,,,,,0.35,0.02 52 | 54,0.8,0.7,0.7,0.01,0.01,0.66,0.14,,,,,0.02,0.62,0.01,0.68,0.04,,,,,0.06, 53 | 55,3.7,2.9,1.1,0.07,0.12,2.47,1.00,0.03,0.01,0.01,0.01,0.05,2.82,0.01,1.06,0.04,,,,,0.52,0.07 54 | 56,4.8,5.9,7.6,,0.12,2.73,1.70,0.06,0.10,0.04,,0.08,5.74,0.04,6.97,0.59,0.02,,,,0.54,0.15 55 | 59,2.1,1.7,0.9,0.02,0.03,1.50,0.49,0.02,0.02,0.01,,0.01,1.66,0.01,0.91,0.03,,,,,0.47,0.05 56 | 60,6.9,10.1,21.2,,0.04,4.92,1.48,0.16,0.20,0.08,,0.00,9.75,0.33,19.61,1.32,,,,,, 57 | 61,2.4,3.7,9.2,,,1.77,0.46,0.05,0.06,0.03,,,3.67,0.03,8.48,0.69,,,,,, 58 | 63,0.9,0.8,1.0,,0.01,0.63,0.19,0.01,0.01,0.01,,0.01,0.76,0.01,0.99,0.05,,,,,0.38,0.07 59 | 64,0.1,0.2,0.2,,0.00,0.12,0.02,0.00,,,,0.00,0.22,0.00,0.15,0.08,,,,,, 60 | 65,0.1,0.1,0.0,,,0.11,0.01,,,,,,0.08,,0.04,0.01,,,,,, 61 | 68,0.1,0.2,0.4,,,0.09,0.03,0.00,0.00,,,,0.19,,0.40,0.05,,,,,, 62 | 70,0.1,0.0,0.1,,,0.05,0.00,0.00,0.00,0.00,,,0.00,,0.03,0.03,,,,,, 63 | 72,0.1,0.2,0.5,,,0.10,0.03,0.00,0.00,0.00,,,0.18,,0.40,0.06,,,,,, 64 | 81,0.1,0.0,0.2,0.00,0.00,0.11,0.02,0.00,0.00,0.00,,0.01,0.01,,0.04,0.16,,,,,, 65 | 85,0.8,1.1,2.6,,,0.53,0.19,0.02,0.02,0.00,,0.00,1.11,0.03,2.30,0.35,,,,,,0.04 66 | 90,12.9,11.9,4.0,0.10,0.25,10.98,1.30,0.11,0.02,0.02,,0.04,11.83,0.05,3.85,0.09,,,,,0.02,0.09 67 | 93,2.1,3.4,6.6,,0.01,1.41,0.52,0.05,0.06,0.01,,0.01,3.31,0.06,6.29,0.30,,,,,,0.07 68 | 94,0.3,0.2,0.4,0.02,0.01,0.19,0.07,0.00,0.00,,,,0.20,,0.33,0.03,,,,,, 69 | 99,2.4,4.3,0.6,,0.03,1.48,0.80,0.05,0.05,0.02,, ,4.25,0.01,0.56,,,,,,4.05,0.40 70 | 100,0.1,0.0,0.2,,0.00,0.08,0.01,0.00,0.00,0.00,0.00,0.01,0.02,,0.06,0.10,,,,,,0.00 71 | 101,0.1,0.1,0.2,,,0.12,0.02,0.00,,0.00,,0.02,0.04,,0.07,0.12,,,,,, 72 | 104,0.1,0.0,0.3,0.00,0.00,0.13,0.01,,0.00,0.00,,0.02,0.03,,0.09,0.17,,,,,, 73 | 105,0.1,0.0,0.1,0.00,,0.06,0.00,0.00,0.00,0.00,,0.00,0.00,,0.04,0.10,,,,,, 74 | 106,0.7,1.1,3.0,,,0.51,0.15,0.02,0.02,0.01,,0.01,1.04,0.02,2.48,0.48,,,,,,0.01 75 | 109,0.0,0.0,0.1,,,0.03,0.00,,,,, ,0.00,,0.12,0.00,,,,,, 76 | 115,0.1,0.0,0.1,,,0.10,0.02,,,,,0.02,0.02,,0.05,0.08,,,,,, 77 | 116,1.0,1.6,3.6,,,0.70,0.25,0.03,0.03,0.01,,,1.52,0.04,3.16,0.38,,,,,, 78 | 118,0.1,0.0,0.1,,,0.06,0.00,0.00,,,,0.00,0.02,,0.06,0.06,,,,,, 79 | 120,0.9,1.3,2.9,,,0.60,0.22,0.02,0.03,0.02,,0.00,1.27,0.04,2.55,0.38,,,,,,0.04 80 | 121,0.1,0.1,0.0,0.00,0.00,0.08,0.02,0.00,0.00,0.00,0.00,0.00,0.08,0.00,0.03,0.01,,,,,0.00,0.10 81 | 122,0.1,0.1,0.0,0.00,0.03,0.09,0.01,,,,,,0.08,,0.03,0.01,,,,,, 82 | 123,0.2,0.2,0.0,,,0.20,0.02,,,,,,0.19,,0.04,,,,,,, 83 | 126,0.1,0.0,0.1,,,0.08,0.00,0.00,0.00,0.00,,,0.04,,0.08,0.00,,,,,, 84 | 127,0.1,0.1,0.2,,,0.05,0.02,0.00,0.00,0.00,,0.00,0.05,,0.20,0.00,,,,,, 85 | 128,0.5,0.5,2.1,,,0.29,0.13,0.01,0.01,0.01,,0.03,0.48,0.00,2.09,0.03,,,,,, 86 | 129,0.1,0.1,0.1,,,0.07,0.00,,,,,,0.10,,0.05,0.01,,,,,, 87 | 130,0.1,0.1,0.0,,,0.06,0.00,0.00,0.00,0.00,,0.00,0.12,0.00,0.04,0.00,,,,,0.00, 88 | 131,1.9,2.4,2.5,0.00,0.03,1.26,0.54,0.03,0.02,0.01,,0.04,2.38,0.02,2.29,0.19,,,,,0.49,0.14 89 | 132,1.7,2.8,6.2,,,1.20,0.38,0.03,0.05,0.02,,,2.73,0.05,5.58,0.57,,,,,,0.04 90 | 133,0.1,0.0,0.3,,,0.11,0.02,0.00,,,,0.02,0.01,,0.05,0.21,,,,,, 91 | 136,0.6,0.5,0.8,0.02,0.01,0.40,0.15,0.00,0.00,0.00,,0.01,0.47,0.00,0.72,0.05,0.00,,,,, 92 | 138,0.1,0.0,0.1,0.00,0.00,0.07,0.00,0.00,0.00,0.01,,,0.03,,0.09,0.01,,,,,,0.00 93 | 141,3.4,3.0,4.1,0.08,0.29,2.00,0.74,0.03,0.03,,0.03,0.08,2.92, ,3.67,0.36,,,,,0.63,0.12 94 | 151,0.2,0.3,0.7,,,0.15,0.04,0.00,0.00,0.00,,,0.28,0.00,0.61,0.07,,,,,,0.00 95 | 153,0.1,0.0,0.2,,,0.08,0.00,0.00,0.00,0.00,,0.00,0.02,,0.11,0.09,,,0.00,,, 96 | 154,0.1,0.2,0.2,,,0.10,0.03,0.00,0.00,0.00,,,0.22,,0.20,0.01,,,,,0.00,0.00 97 | 155,0.1,0.1,0.3,0.00,0.00,0.13,0.02,0.02,0.02,0.00,, ,0.04,,0.07,0.26,,,,,, 98 | 156,0.2,0.1,0.4,0.00,0.00,0.18,0.04,0.02,0.00,0.01,,0.02,0.05,,0.12,0.25,,,,,, 99 | 159,0.1,0.1,0.2,0.00,0.00,0.06,0.02,0.00,0.00,0.00,,0.00,0.09,0.00,0.17,0.02,,,,,0.00,0.00 100 | 163,2.3,4.3,1.4,,0.01,2.20,0.10,0.02,,,,0.20,4.12,0.02,1.29,0.08,,,,,, 101 | 166,0.3,0.1,0.1,,,0.30,0.03,,,,,,0.11,,0.10,0.02,,,,,, 102 | 167,0.7,1.9,0.3,,0.00,0.58,0.07,0.00,,,,0.07,1.88,0.00,0.30,0.02,,,,,, 103 | 168,0.7,2.0,0.4,,0.00,0.66,0.07,0.00,,,,0.08,1.93,,0.35,0.02,,,,,, 104 | 173,0.1,0.0,0.1,,,0.07,0.02,0.01,,,,,0.03,0.01,0.07,0.01,,,,,, 105 | 174,0.1,0.0,0.1,,,0.09,0.03,0.00,0.00,0.00,,,0.01,,0.06,0.04,,,,,, 106 | 191,0.2,0.0,0.1,,0.01,0.11,0.02,,0.00,0.00,,,0.02,,0.07,0.03,,,,,, 107 | 192,0.4,0.2,0.1,,0.00,0.37,0.04,0.00,0.00,0.00,,0.01,0.20,,0.03,0.09,,,,,, 108 | 193,0.3,0.1,0.0,,0.00,0.26,0.03,0.00,0.00,0.00,,0.00,0.13,0.00,0.01,0.03,,,,,0.00, 109 | 196,0.1,0.0,0.0,,,0.08,0.00,0.00,0.00,0.00,,,0.02,,0.01,0.02,,,,,, 110 | 197,0.1,0.0,0.2,,,0.04,0.02,0.00,,0.00,,,0.03,,0.23,0.00,,,,,, 111 | 200,0.1,0.0,0.3,,,0.04,0.02,0.00,,0.00,,,0.04,,0.26,0.00,,,,,, 112 | 201,0.0,0.1,0.0,,,0.05,0.00,,,,,,0.08,,0.01,0.02,,,,,, 113 | 204,0.1,0.1,0.0,,,0.09,0.00,0.00,0.00,0.00,,0.00,0.07,,0.00,0.02,,,,,, 114 | 207,0.1,0.1,0.3,,,0.04,0.02,0.00,,,,0.00,0.10,,0.06,0.29,,,,,, 115 | 221,0.1,0.0,0.0,,0.00,0.04,0.02,0.00,0.00,0.00,,0.00,0.02,,0.04,0.01,,,,,, 116 | 223,7.1,25.3,6.5,,0.04,6.01,0.97,0.05,,,,0.67,24.57,0.04,6.18,0.30,,,,,, 117 | 228,0.1,0.1,0.0,0.00,0.00,0.07,0.00,0.00,0.00,0.00,,0.04,0.05,0.00,0.02,0.02,,,,,, 118 | 230,0.1,0.1,0.0,,0.01,0.07,0.00,,,,,0.03,0.05,,0.01,0.02,,,,,, 119 | 231,0.1,0.1,0.0,0.00,0.03,0.05,0.00,0.00,0.00,0.00,,0.04,0.04,0.00,0.00,0.04,,,,,0.00, 120 | 232,0.2,0.3,0.9,,,0.17,0.05,0.00,,,,0.00,0.28,,0.92,0.02,,,,,, 121 | 242,0.1,0.0,0.1,,0.00,0.05,0.01,0.01,0.01,0.01,,0.00,0.02,0.00,0.05,0.01,,,,,, 122 | 246,0.1,0.0,0.1,,,0.08,0.01,,0.00,0.00,,,0.03,,0.08,0.04,,,,,, 123 | 250,0.1,0.2,0.0,,0.00,0.09,0.01,0.00,0.00,0.00,,0.00,0.18,0.00,0.02,0.02,,,,,0.00, 124 | 253,4.7,9.7,0.9,,0.02,3.18,1.19,0.25,0.02,0.02,,,9.62,0.06,0.30,0.58,,,,,, 125 | 259,43.1,40.1,16.6,0.28,0.79,36.77,4.61,0.35,0.10,0.08,,0.14,39.86,0.24,15.69,0.83,,,,,,0.14 126 | 260,14.9,75.5,9.5,,,11.30,2.96,0.38,0.12,0.05,,1.09,74.01,0.25,8.74,0.75,,,,,, 127 | 261,49.2,20.4,1.2,2.09,8.06,23.01,9.30,0.15,,,0.81,0.98,17.94,0.13,0.89,0.27,,,,,2.50,0.80 128 | 262,51.5,21.9,1.5,2.11,7.96,23.87,9.64,0.14,,,0.78,0.98,19.80,0.12,1.22,0.27,,,,,2.31,0.51 129 | 263,14.9,18.2,21.4,0.06,0.11,8.29,5.75,0.23,0.28,0.09,,0.05,17.87,0.28,19.48,1.74,,,,,8.69,1.30 130 | 265,21.9,15.0,27.6,2.50,1.00,12.91,4.35,0.21,0.20,0.08,,0.06,14.70,0.26,24.85,2.64,,,,,0.09,0.24 131 | 266,20.9,14.4,26.5,2.35,0.94,12.41,4.15,0.20,0.19,0.08,,0.05,14.07,0.25,23.79,2.58,,,,,0.12,0.20 132 | 267,50.9,18.6,30.2,25.03,7.92,9.46,3.14,0.17,0.21,0.07,,,18.51,0.25,27.17,2.86,,,,,,0.19 133 | 268,7.9,62.6,28.4,,0.06,4.59,2.21,0.57,0.30,0.15,,0.20,61.14,1.11,20.87,6.78,,,,,,0.37 134 | 269,10.8,25.4,62.6,,0.07,6.10,3.42,0.26,0.67,0.25,,0.08,25.15,0.18,62.22,0.39,,,,,,1.14 135 | 270,15.2,33.4,50.9,,,12.12,2.18,0.49,0.18,0.19,,0.12,33.04,0.23,49.94,0.96,,,,,,0.48 136 | 271,39.9,55.8,4.2,,0.09,37.37,2.08,0.19,0.05,0.06,,0.83,54.73,0.14,3.74,0.51,,,,,, 137 | 272,15.2,23.3,60.0,,0.08,10.83,3.36,0.33,0.43,0.14,,0.09,22.98,0.60,53.85,5.72,,,,,,0.50 138 | 273,0.6,0.3,0.1,,0.01,0.44,0.11,,,,,0.02,0.29,0.02,0.02,0.00,0.00,0.06,0.00,0.07,0.00, 139 | 274,0.4,0.3,0.2,,0.00,0.29,0.08,,,,,0.01,0.22,0.02,0.03,,0.00,0.06,0.00,0.08,, 140 | 275,0.1,0.0,0.1,0.00,0.00,0.06,0.02,,,,,0.00,0.04,0.00,0.00,,0.01,0.01,0.00,0.08,, 141 | 276,0.6,0.3,0.6,,0.01,0.42,0.11,,,,,0.01,0.27,0.02,0.02,0.02,0.00,0.10,,0.42,, 142 | 277,1.0,1.3,3.2,,0.02,0.70,0.26,0.02,0.02,,,0.02,1.27,0.02,2.68,0.29,0.03,0.03,,0.19,,0.04 143 | 278,0.5,0.2,0.0,,0.01,0.27,0.17,0.00,0.00,0.00,,0.02,0.18,0.00,0.01,0.01,0.00,0.00,,0.01,0.00, 144 | 279,0.6,0.3,0.2,0.00,0.03,0.43,0.14,,0.00,0.00,,0.03,0.28,0.00,0.02,0.08,0.03,0.02,,0.06,0.00, 145 | 280,0.9,1.1,1.2,,0.02,0.65,0.23,0.02,0.02,0.00,,0.02,1.01,0.03,1.08,0.07,0.00,0.04,,0.04,0.03,0.01 146 | 281,1.5,2.2,5.2,,0.01,1.03,0.37,0.03,0.04,0.02,,0.01,2.17,0.03,4.62,0.47,0.02,0.01,0.02,0.07,, 147 | 282,0.2,0.1,0.2,,,0.07,0.12,,,,,0.00,0.08,0.01,0.00,,0.03,0.01,0.01,0.12,, 148 | 283,0.1,0.1,0.2,0.00,0.00,0.07,0.07,,,,,0.00,0.06,0.01,0.00,,0.02,0.02,0.02,0.10,, 149 | 284,0.4,0.2,0.2,,0.01,0.23,0.14,0.01,0.01,0.00,,0.05,0.16,0.01,0.03,0.00,0.04,0.08,0.01,0.09,0.01, 150 | 285,0.1,0.1,0.2,,0.00,0.08,0.04,0.00,,,,0.02,0.06,0.00,0.02,0.00,0.02,0.08,0.01,,0.00, 151 | 286,2.5,3.6,8.8,,,1.69,0.59,0.05,0.08,0.03,,0.05,3.54,,7.76,0.82,0.05,0.08,,0.10,, 152 | 287,0.2,0.2,0.0,,,0.10,0.09,0.01,0.01,,,0.01,0.14,,0.03,0.00,,,,,, 153 | 288,2.5,2.3,0.3,,0.30,1.57,0.31,0.01,0.02,,,1.21,1.02,0.01,0.09,0.12,0.03,0.04,0.01,0.03,0.04, 154 | 289,4.8,6.4,2.6,,0.51,3.25,0.83,,,,,2.91,3.22,0.26,0.43,0.17,0.16,0.84,0.33,0.26,, 155 | 290,4.5,6.5,2.3,,0.52,3.15,0.68,,,,,3.12,3.11,0.24,0.21,0.17,0.16,0.89,0.36,0.29,, 156 | 291,1.2,0.7,0.1,,0.04,0.75,0.26,0.01,0.01,0.01,,0.18,0.49,0.00,0.04,0.03,0.02,0.01,0.00,0.00,0.01, 157 | 292,0.7,0.5,0.1,,0.05,0.46,0.13,0.01,0.00,0.01,,0.20,0.27,0.02,0.01,0.02,0.02,0.03,0.03,0.04,0.01, 158 | 293,1.5,1.2,0.3,,0.12,0.99,0.32,0.02,0.01,0.00,0.01,0.42,0.69,0.03,0.03,,0.04,0.05,0.04,0.05,0.02, 159 | 294,0.7,0.6,0.6,,0.06,0.49,0.17,,,,,0.23,0.33,0.03,0.02,0.01,0.09,0.17,0.10,0.20,0.01, 160 | 295,3.0,1.4,0.4,0.01,0.19,1.85,0.66,0.03,0.05,0.04,,0.29,1.05,0.07,0.14,,0.06,0.02,0.03,0.04,0.02, 161 | 296,2.0,2.2,1.2,0.02,0.16,1.24,0.47,0.02,0.04,,,0.34,1.82,0.02,0.49,0.17,0.21,0.13,0.06,0.18,0.01, 162 | 297,5.5,7.0,8.1,,0.22,3.40,1.39,0.09,0.12,0.04,0.04,0.02,6.72,0.11,6.43,0.78,0.34,0.03,0.08,0.23,0.04,0.06 163 | 298,3.4,3.3,1.1,0.03,0.15,2.11,0.88,0.04,0.03,0.04,,0.39,2.84,0.05,0.57,,0.12,0.10,0.05,0.12,0.08,0.02 164 | 299,5.5,5.4,10.4,,0.28,3.74,1.08,0.09,0.11,0.04,,0.30,4.90,0.09,7.53,0.84,0.09,0.44,0.17,1.16,,0.04 165 | 300,5.3,6.0,11.7,,0.21,3.59,1.17,0.09,0.13,0.06,,0.23,5.53,0.15,8.92,0.87,0.08,0.35,0.14,1.13,, 166 | 301,0.2,0.1,0.3,,,0.12,0.06,,,0.00,,0.00,0.10,0.00,0.02,,0.02,0.03,0.00,0.23,, 167 | 302,0.9,0.5,0.4,,0.17,0.59,0.08,0.00,,0.02,,0.15,0.35,0.00,0.03,0.05,0.02,0.03,0.02,0.11,, 168 | 303,1.4,2.1,4.3,,0.08,1.03,0.26,,0.03,,,0.14,1.77,0.10,3.07,0.36,,0.19,0.00,0.60,, 169 | 304,0.8,2.4,0.9,,0.04,0.40,0.22,0.02,0.01,0.01,,0.75,1.61,0.00,0.04,0.05,0.05,0.18,0.13,0.43,0.01, 170 | 305,2.3,3.2,5.2,,0.14,1.55,0.48,0.04,0.05,0.02,,0.16,2.78,0.19,4.21,0.41,0.02,0.01,0.03,0.45,0.01,0.06 171 | 306,2.2,4.4,9.1,,,1.55,0.53,0.04,0.06,,,0.46,3.91,0.07,6.63,0.75,0.05,0.22,0.08,0.54,, 172 | 307,0.9,2.3,0.3,,0.05,0.47,0.24,0.02,0.01,0.01,,0.77,1.51,0.00,0.03,0.04,0.02,0.06,0.04,0.13,0.01, 173 | 308,1.0,1.1,1.2,,0.06,0.64,0.23,0.02,0.01,0.00,,0.10,0.98,0.04,0.87,0.07,0.02,0.02,0.01,0.12,0.02,0.01 174 | 309,1.3,2.9,4.3,,,0.96,0.28,0.03,0.03,,,0.09,2.82,0.04,3.75,0.41,,0.03,0.02,0.10,, 175 | 310,0.3,0.2,0.4,,0.02,0.19,0.05,,,0.00,,0.03,0.15,0.01,0.01,0.01,0.01,0.09,0.01,0.23,, 176 | 311,1.8,1.3,0.3,0.00,0.16,1.05,0.46,0.02,0.01,,0.02,0.18,0.97,0.06,0.12,0.06,0.04,0.01,,0.02,0.00,0.01 177 | 312,0.6,0.4,0.1,,0.03,0.40,0.12,0.00,0.00,0.00,,0.12,0.32,0.00,0.02,0.02,0.01,0.01,0.01,0.01,0.00, 178 | 313,1.1,0.7,0.2,0.00,0.04,0.61,0.34,0.01,0.01,,0.01,0.09,0.50,0.03,0.09,0.02,0.02,0.01,0.00,0.00,0.00,0.00 179 | 314,0.4,0.1,0.0,0.00,0.01,0.19,0.14,0.00,0.00,0.00,,0.01,0.11,0.00,0.02,0.00,0.00,0.00,,0.00,0.00, 180 | 315,3.1,4.4,7.0,,0.51,2.02,0.61,,,,,0.69,3.37,0.23,2.99,0.40,0.09,1.21,0.59,1.22,, 181 | 316,2.5,2.9,3.1,0.01,0.30,1.39,0.49,0.04,0.12,0.07,,0.36,2.26,0.19,1.73,0.03,0.04,0.43,0.22,0.46,, 182 | 317,3.6,4.1,5.0,0.01,0.42,2.00,0.73,0.05,0.17,0.10,,0.54,3.18,0.29,2.43,0.33,0.07,0.72,0.36,0.75,0.02, 183 | 318,1.7,0.5,0.3,,0.16,1.07,0.36,0.03,0.02,0.01,0.00,0.11,0.33,0.02,0.04,0.02,0.02,0.05,0.00,0.18,, 184 | 319,4.1,5.5,11.9,,0.32,2.66,0.84,0.11,0.11,0.04,,0.33,5.03,0.09,9.78,0.99,0.09,0.44,0.06,0.46,,0.07 185 | 320,2.6,3.1,6.1,,0.07,1.71,0.62,0.06,0.07,0.02,,0.06,2.92,0.04,5.13,0.43,0.03,0.09,0.01,0.36,,0.09 186 | 321,1.7,0.5,0.2,0.00,0.21,1.00,0.27,0.02,0.01,0.01,,0.13,0.28,0.02,0.03,0.02,0.01,0.03,0.00,0.06,0.00, 187 | 322,0.6,0.4,0.4,0.00,0.03,0.37,0.17,0.01,0.02,0.00,,0.08,0.26,0.01,0.09,0.02,0.10,,0.02,0.12,0.01,0.00 188 | 323,1.9,2.6,1.1,,0.07,1.23,0.61,,,,,0.13,2.39,0.04,1.00,0.04,,,,,, 189 | 324,7.8,2.5,0.1,,0.14,3.91,3.64,0.05,0.02,,,0.03,2.47,,0.13,,,,,,5.32,0.10 190 | 325,9.4,3.2,0.2,0.09,0.12,3.98,5.07,0.07,0.05,0.02,,0.04,3.14, ,0.25,,,,,,6.19,0.11 191 | 326,4.8,4.6,0.3,,0.27,2.50,1.83,0.01,0.01,,,0.33,4.17,0.03,0.22,0.02,0.02,,,,0.22,0.02 192 | 327,2.7,2.4,0.1,,0.14,1.35,1.09,0.01,0.01,,,0.18,2.22,0.01,0.12,0.01,0.01,,,,0.10, 193 | 328,5.5,3.7,0.3,0.01,0.36,2.68,2.16,0.01,0.01,,,0.33,3.32,0.04,0.22,0.03,0.01,,,,0.28,0.02 194 | 329,2.8,2.3,0.2,,0.14,1.33,1.19,0.01,,,,0.16,2.12,0.01,0.14,0.02,0.02,0.01,,,0.17,0.02 195 | 330,3.9,3.5,0.9,0.01,0.25,2.10,1.42,0.02,0.02,,,0.29,3.22,0.02,0.81,0.09,0.02,,,,0.25,0.11 196 | 331,4.2,5.0,5.5,,0.17,2.47,1.40,0.05,0.06,0.02,0.05,0.27,4.59,0.05,4.89,0.52,0.03,,,,0.17,0.05 197 | 332,2.4,1.4,0.1,,0.11,1.08,1.10,0.01,,0.01,,0.09,1.29,,0.07,0.01,0.01,,,,0.13,0.01 198 | 333,3.3,1.4,0.1,0.01,0.07,1.52,1.49,0.01,,0.02,,0.14,1.26,0.01,0.09,0.01,0.01,,,,0.07,0.01 199 | 334,6.9,6.2,0.1,0.01,0.53,3.82,2.03,0.01,,,,0.73,5.33,0.01,0.14,,0.01,,,,0.28,0.03 200 | 335,8.8,8.7,0.3,,0.53,4.93,2.82,0.02,,,,0.88,7.67,0.04,0.22,,0.04,0.02,,,0.28,0.02 201 | 336,1.9,1.9,0.1,,0.12,1.05,0.58,0.00,0.00,0.00,,0.20,1.66,0.01,0.07,0.00,0.01,,,,0.06,0.00 202 | 337,4.3,4.3,0.2,0.01,0.27,2.42,1.29,0.01,0.01,,,0.44,3.85,,0.16,0.04,0.04,,,,0.14,0.01 203 | 338,4.8,5.4,0.4,,0.31,2.61,1.73,0.01,0.02,,0.10,0.50,4.68,0.02,0.19,0.05,0.06,0.02,0.04,,0.32,0.08 204 | 339,8.7,6.6,0.2,,0.80,4.45,3.14,,,,,0.54,5.70, ,0.16,,,,,,0.80, 205 | 340,7.2,8.1,6.9,,0.33,4.21,2.35,0.05,0.06,0.02,0.09,0.45,7.36,0.03,6.22,0.61,0.05,,0.02,,0.36, 206 | 341,6.7,4.6,0.1,0.01,0.40,3.15,2.85,0.02,0.01,,,0.35,4.21,0.02,0.13,,,,,,0.24,0.01 207 | 342,8.8,5.6,0.2,0.02,0.59,4.28,3.53,0.02,,,,0.47,5.06,,0.17,0.03,0.02,,,,0.23,0.02 208 | 343,5.6,5.5,0.2,0.01,0.41,3.21,1.57,0.01,0.01,,,0.62,4.81,0.01,0.15,0.05,0.02,,,,0.17,0.02 209 | 344,7.4,6.3,0.2,0.01,0.50,4.24,2.24,0.01,,,,0.63,5.58,,0.14,0.03,0.01,,,,0.19,0.01 210 | 345,2.7,2.6,0.1,,0.15,1.48,0.89,0.01,,,,0.22,2.32,0.01,0.09,,0.02,0.01,,,0.08,0.01 211 | 346,2.0,1.9,0.1,,0.09,1.12,0.68,,,0.01,,0.16,1.75,,0.07,0.01,0.01,,,,0.04, 212 | 347,11.8,12.1,0.3,0.03,0.89,6.32,3.76,0.03,,,,1.17,10.64,0.08,0.13,0.15,0.03,,,,0.76,0.10 213 | 348,14.9,12.7,0.3,0.03,1.11,7.76,5.15,0.03,,,,1.31,11.05,0.12,0.15,0.12,,,,,0.76,0.15 214 | 349,3.5,4.1,0.2,,0.20,1.99,1.14,0.01,0.01,,,0.45,3.59,0.01,0.11,0.02,0.02,,,,0.16,0.08 215 | 350,2.9,2.4,0.1,,0.21,1.66,0.98,0.01,,,,0.22,2.12,,0.05,0.01,0.01,,,,0.10,0.04 216 | 351,4.3,3.4,0.2,,0.26,2.36,1.46,0.01,,,,0.28,3.10,0.01,0.14,0.01,0.02,,,,0.15,0.05 217 | 352,3.9,3.7,0.1,,0.29,2.34,1.06,0.01,,,,0.45,3.23,,0.08,0.01,0.01,,,,0.12,0.02 218 | 353,5.5,5.4,0.2,0.02,0.40,3.07,1.65,0.01,0.01,,,0.61,4.71,0.02,0.16,0.03,0.02,,,,0.22,0.01 219 | 354,6.8,6.4,0.2,0.01,0.46,3.80,2.06,0.01,0.01,,,0.71,5.56,0.04,0.15,0.06,,,,,0.30,0.03 220 | 355,2.8,1.5,0.1,0.00,0.18,1.28,1.44,0.01,0.01,0.00,,0.09,1.43,0.01,0.05,0.00,0.00,,0.00,,0.16,0.05 221 | 356,4.7,2.2,1.1,,0.14,2.30,1.86,0.01,0.12,0.02,,0.23,1.89,,0.37,0.10,0.31,0.07,0.16,0.04,0.09,0.02 222 | 357,2.9,1.9,0.2,,0.17,1.44,1.16,0.01,0.01,,,0.15,1.69,0.01,0.11,0.02,0.03,0.01,,,0.10,0.01 223 | 358,4.5,3.1,0.2,,0.25,2.21,1.76,0.01,,0.01,,0.23,2.87,,0.16,0.02,0.02,,,,0.14,0.02 224 | 359,3.9,2.8,0.1,,0.27,2.07,1.40,0.01,,,,0.28,2.49,0.01,0.08,0.01,,,,,0.16, 225 | 360,3.1,2.3,0.1,,0.19,1.65,1.13,0.01,,,,0.18,2.09,,0.07,0.01,0.01,,,,0.11,0.02 226 | 361,12.1,10.4,0.5,0.02,0.95,6.35,3.98,0.02,,,,1.10,9.07,0.07,0.29,0.12,0.05,,,,0.50,0.05 227 | 362,7.3,6.5,0.3,0.01,0.59,3.77,2.39,0.01,,,,0.71,5.63,0.06,0.16,0.09,0.01,,,,0.43, 228 | 363,3.9,4.0,0.2,,0.22,2.22,1.25,0.01,0.02,,,0.42,3.54,0.01,0.12,0.02,0.01,,,,0.15,0.07 229 | 364,2.3,2.3,0.1,,0.14,1.36,0.66,,0.00,,,0.25,1.98,,0.06,0.01,0.00,,,,0.08,0.00 230 | 365,11.2,10.3,0.5,,0.68,5.54,4.20,0.02,0.02,,,0.77,9.31,,0.43,0.09,0.02,,,,0.41,0.02 231 | 366,6.8,6.8,0.3,0.01,0.41,3.40,2.63,0.01,,,,0.48,6.11,0.06,0.26,0.04,0.01,,0.01,,0.29,0.01 232 | 367,3.1,3.1,0.1,0.01,0.21,1.71,0.93,0.01,,,,0.32,2.70,0.01,0.09,0.01,0.01,,,,0.08,0.01 233 | 368,9.7,7.7,0.2,0.02,0.63,4.96,3.49,0.04,0.02,,,0.77,6.79,0.04,0.19,0.04,0.02,,,,0.42,0.06 234 | 369,3.4,3.3,0.1,,0.20,1.79,1.10,0.01,0.01,,,0.36,2.85,0.02,,0.04,0.03,0.01,,,0.16,0.01 235 | 370,5.1,4.9,0.3,,0.32,2.82,1.61,0.01,0.01,,,0.52,4.28,0.03,0.16,0.04,0.04,0.01,,,0.21,0.01 236 | 371,2.9,2.8,0.1,,0.13,1.64,0.99,0.01,0.01,0.01,,0.26,2.48,0.01,0.09,0.03,0.01,,,,0.13,0.05 237 | 372,2.2,2.6,0.1,,0.12,1.27,0.71,0.01,0.01,,,0.21,2.35,0.01,0.07,0.01,0.01,,,,0.08,0.02 238 | 373,3.5,2.9,0.2,0.01,0.19,1.72,1.38,0.01,,,,0.24,2.60,0.02,0.12,0.01,0.01,,,,0.20,0.01 239 | 374,3.4,3.0,0.2,0.01,0.18,1.68,1.31,0.01,0.01,0.01,,0.23,2.69,0.02,0.16,0.01,0.01,,,,0.15,0.01 240 | 375,2.7,2.1,0.1,0.01,0.15,1.33,1.11,0.01,,,,0.16,1.90,0.01,0.11,,0.01,,,,0.15,0.03 241 | 376,2.0,1.9,0.2,,0.11,1.08,0.66,,0.01,,,0.17,1.65,0.01,0.10,0.02,0.03,,,,0.07,0.01 242 | 377,3.1,3.1,0.3,0.01,0.15,1.59,1.13,0.01,0.01,0.01,,0.25,2.81,0.04,0.17,0.03,0.05,0.01,0.03,,0.11,0.01 243 | 378,11.7,11.5,0.4,0.02,0.86,6.10,4.08,0.02,,,,1.09,10.21,0.07,0.32,0.10,0.02,,,,0.67,0.05 244 | 379,8.2,9.2,0.5,,0.56,4.40,2.62,0.02,,,,0.95,8.03,0.04,0.26,0.15,0.02,,,,0.54,0.04 245 | 380,6.1,6.7,0.3,,0.42,3.46,1.83,0.01,0.01,,,0.73,5.86,0.01,0.22,0.05,0.03,,,,0.22,0.03 246 | 381,7.9,9.2,0.4,,0.59,4.59,2.15,0.02,0.02,,,1.01,8.04,0.03,0.25,0.07,0.05,0.02,,,0.23,0.04 247 | 382,2.0,2.1,0.1,0.00,0.15,1.18,0.61,0.00,0.00,0.00,,0.22,1.83,0.01,0.08,0.00,0.01,,,,0.04,0.00 248 | 383,4.5,5.2,0.3,0.01,0.32,2.48,1.36,0.01,0.01,0.01,,0.51,4.64,,0.22,,0.04,,,,0.11,0.02 249 | 384,10.5,8.3,0.4,0.03,0.68,5.11,4.42,0.04,,,0.12,0.59,7.52,0.03,0.24,0.08,0.05,,0.05,,0.71,0.22 250 | 385,8.7,7.5,0.3,0.02,0.70,4.45,3.05,0.03,,,0.18,0.40,6.76,0.04,0.18,0.10,0.03,,0.05,,0.59,0.07 251 | 386,2.6,3.4,4.7,0.01,0.03,1.76,0.65,0.05,0.06,0.02,,0.02,3.32,0.07,4.33,0.32,0.01,,,,0.45,0.13 252 | 388,5.1,7.4,11.5,,0.13,3.13,1.51,0.08,0.10,0.04,,0.16,7.10,0.07,10.47,1.04,,,,,0.27, 253 | 390,5.4,5.2,1.4,,0.03,2.62,2.56,0.08,0.08,0.03,,0.04,5.12,0.03,1.22,0.07,,,,,6.21,0.96 254 | 391,4.4,6.6,3.0,,0.09,3.36,0.93,,0.03,,,0.80,5.75,,2.96,0.01,0.06,,,,0.03,0.01 255 | 392,4.4,7.5,2.3,,0.09,3.23,1.00,0.01,0.00,,,0.69,6.73,0.03,2.18,0.09,0.00,,0.00,0.00,0.03,0.01 256 | 393,2.2,3.4,1.2,,0.04,1.57,0.59,0.01,0.00,0.00,,0.26,3.14,0.02,1.16,0.04,0.00,,0.00,0.00,0.01, 257 | 394,4.9,6.3,3.4,,0.12,3.49,1.16,0.01,0.01,,,0.66,5.56,0.06,3.15,0.13,0.09,,,,0.09, 258 | 395,3.5,4.3,1.6,,0.06,2.33,1.03,0.02,0.02,0.01,0.01,0.37,0.08,0.04,1.41,0.04,0.08,,0.01,,0.08,0.02 259 | 396,3.1,3.8,2.2,,0.06,2.28,0.76,0.02,0.00,,0.01,0.38,3.35,0.02,2.11,0.09,0.00,0.00,,,0.12,0.02 260 | 397,3.0,4.1,2.2,,0.05,2.24,0.68,0.01,0.02,,,0.45,3.61,0.02,2.00,0.09,0.05,,,,0.04, 261 | 398,2.0,2.1,1.1,,0.12,1.31,0.50,0.01,0.00,,0.01,0.20,1.84,0.01,1.10,0.05,0.00,0.00,,,, 262 | 399,1.6,2.1,0.8,,0.03,1.19,0.40,0.00,0.01,,,0.24,1.82,0.01,0.80,0.02,0.03,,,,0.01, 263 | 400,1.3,0.7,0.6,0.00,0.02,0.69,0.58,0.01,0.01,0.01,,0.05,0.58,0.01,0.38,0.01,0.13,,0.03,0.02,0.01, 264 | 401,1.6,2.4,3.3,,0.02,1.09,0.44,0.03,0.04,0.02,,0.05,2.24,0.03,3.01,0.23,0.04,0.02,,,0.02,0.02 265 | 402,5.2,7.2,3.9,,0.11,3.94,1.01,0.02,0.03,,,0.88,6.31,0.03,3.57,0.20,0.07,,,,0.07, 266 | 403,2.1,2.6,1.8,,0.04,1.48,0.57,0.01,0.00,0.00,0.01,0.19,2.36,0.02,1.73,0.09,0.00,0.00,,,0.10,0.02 267 | 404,2.2,2.5,1.5,,0.04,1.58,0.55,0.01,0.00,,0.01,0.23,2.26,0.02,1.42,0.07,0.00,0.00,,,0.09,0.02 268 | 405,1.4,1.9,1.0,,0.03,1.04,0.31,0.00,0.01,,,0.23,1.63,0.01,0.92,0.04,0.05,,,,0.01, 269 | 406,2.2,2.7,1.8,,0.04,1.53,0.56,0.01,0.00,0.00,0.01,0.22,2.45,0.02,1.70,0.10,0.00,0.00,0.00,,0.10,0.02 270 | 407,2.2,3.2,0.9,,0.06,1.66,0.46,0.01,0.01,,,0.44,2.75,0.03,0.80,0.03,0.03,,,,0.03, 271 | 408,1.1,1.1,0.6,,0.02,0.74,0.33,0.01,0.00,0.00,,0.07,0.98,0.01,0.53,0.02,0.00,0.00,,,0.04,0.01 272 | 409,1.1,1.3,0.0,,0.03,0.79,0.25,0.00,0.01,,,0.16,1.16,0.01,0.00,0.01,0.02,,,,0.01, 273 | 410,0.9,0.9,0.3,,0.02,0.65,0.27,0.00,0.00,0.00,,0.07,0.80,0.01,0.31,0.01,0.00,0.00,,,0.04,0.00 274 | 411,4.2,5.4,3.9,,0.07,3.08,1.02,0.01,0.00,,0.02,0.50,4.80,0.04,3.64,0.21,0.00,0.00,,,0.19,0.04 275 | 412,6.5,9.6,3.6,,0.12,4.96,1.31,0.02,0.02,,,1.13,8.44,0.02,3.41,0.12,0.08,,,,0.06, 276 | 413,3.3,4.2,3.1,,0.06,2.41,0.82,0.01,0.00,,0.01,0.42,3.76,0.03,2.86,0.17,0.00,0.00,,,0.14,0.04 277 | 414,3.0,4.5,1.6,,0.06,2.30,0.61,0.01,0.02,,,0.57,3.87,0.02,1.45,0.04,0.05,,,,0.03, 278 | 415,5.7,5.8,0.8,0.02,0.39,3.06,1.97,0.02,,,0.12,0.58,4.96,0.03,0.68,0.08,0.03,,,0.01,0.81,0.19 279 | 416,5.9,6.0,3.7,,0.29,3.18,2.19,0.03,0.03,0.02,0.07,0.41,5.37,0.07,3.28,0.29,0.03,,0.02,,0.33,0.11 280 | 417,5.1,4.8,1.2,,0.26,2.72,2.01,0.02,0.01,,0.05,0.42,4.25,0.02,1.08,0.10,0.04,0.02,,,0.30,0.06 281 | 418,5.2,7.3,3.5,0.01,0.16,3.59,1.35,0.02,,,0.01,0.52,6.70,0.08,3.08,0.17,,,,,0.04, 282 | 419,5.0,7.2,4.3,,0.14,3.46,1.33,0.03,,,,0.45,6.60,0.10,3.85,0.25,0.09,,,,0.04, 283 | 420,4.7,6.8,3.4,,0.14,3.26,1.26,0.02,,,,0.44,6.20,0.09,3.00,0.17,0.09,,,,0.04, 284 | 421,4.0,5.0,1.7,0.01,0.15,2.52,1.24,0.02,,,,0.25,4.66,0.08,1.48,0.05,0.06,,,,0.03, 285 | 422,6.5,8.2,2.7,,0.25,4.17,2.01,0.03,,,,0.29,7.66,0.13,2.43,0.11,0.09,,,,0.03, 286 | 423,7.0,8.7,2.6,,0.27,4.47,2.17,0.03,,,,0.44,8.07,0.13,2.35,0.10,0.10,,,,0.03, 287 | 424,6.1,8.1,4.7,,0.17,4.15,1.74,,,,,0.60,7.36,0.12,4.41,0.28,,,,,, 288 | 425,1.6,1.2,1.4,,0.03,1.10,0.47,0.02,0.00,0.00,,0.11,1.60,0.01,1.41,0.03,0.00,0.00,,,0.02,0.00 289 | 426,0.4,0.4,0.7,0.01,0.01,0.26,0.14,0.00,0.01,,,0.03,0.41,0.00,0.63,0.03,0.06,,,,, 290 | 427,3.5,3.9,1.2,0.01,0.13,2.17,1.12,0.02,,,,0.21,3.37,0.06,1.12,0.05,0.05,,,,, 291 | 428,6.0,6.6,4.6,0.05,0.31,3.58,1.94,0.04,0.02,0.02,,0.25,6.17,0.11,4.07,0.32,0.07,,0.02,,0.16,0.05 292 | 429,7.5,7.7,1.2,0.02,0.27,4.27,2.82,0.03,,,,0.31,7.14,0.13,1.03,0.03,0.03,,,,0.09, 293 | 430,11.8,13.9,3.1,,0.34,7.10,4.16,0.06,,,,0.63,12.90,0.23,2.75,0.12,0.09,,,,0.06, 294 | 431,7.4,8.3,2.3,0.02,0.28,4.59,2.42,0.03,,,,0.45,7.64,0.12,2.11,0.09,0.08,,,,, 295 | 432,2.6,2.9,0.7,,0.08,1.54,0.97,0.01,,,,0.11,2.63,0.16,0.55,0.07,0.02,,,,0.02, 296 | 433,3.3,3.7,1.0,0.01,0.12,2.08,1.00,0.02,,,,0.22,3.39,0.06,0.88,0.04,0.05,,,,, 297 | 434,7.3,11.2,2.8,0.02,0.33,4.99,1.84,0.03,,,,0.90,10.15,0.19,2.58,0.11,0.09,,,,, 298 | 435,4.8,6.4,1.9,,0.15,2.96,1.59,0.03,,,,0.29,5.91,0.11,1.66,0.05,0.11,,,,, 299 | 436,4.2,5.0,1.7,0.01,0.16,2.58,1.29,0.02,0.02,,,0.26,4.64,0.09,1.51,0.06,0.08,,,,, 300 | 437,11.6,16.7,4.3,,0.37,7.37,3.58,0.07,,,,0.78,15.49,0.30,3.85,0.16,0.07,,,,0.07, 301 | 438,1.9,2.6,1.0,,0.06,1.22,0.63,0.01,,,,0.13,2.39,0.05,0.87,0.04,0.04,,,,0.01, 302 | 439,0.9,1.1,0.5,,0.03,0.55,0.27,,,,,0.07,1.04,0.02,0.38,0.01,0.04,,,,, 303 | 440,1.2,0.9,0.3,,0.08,0.68,0.43,,,,,0.06,0.87,,0.25,0.02,,,0.00,,0.06, 304 | 441,0.7,0.7,0.3,,0.03,0.35,0.24,,,,,0.06,0.63,0.01,0.21,0.03,0.02,0.01,0.01,,0.03, 305 | 442,4.6,5.0,5.0,,0.16,2.50,1.68,0.04,0.05,0.03,0.03,0.17,4.75,0.05,4.55,0.41,0.03,,,,0.18,0.08 306 | 443,9.6,12.1,4.7,,0.34,5.78,3.09,0.05,,,,0.55,11.21,0.23,4.23,0.19,0.03,,,,0.10, 307 | 444,17.7,20.1,10.1,0.06,0.75,11.42,5.21,0.09,,,,0.98,18.82,0.28,9.32,0.68,0.15,,,,0.21, 308 | 445,20.0,26.2,14.6,,0.64,12.89,6.17,0.12,0.07,,,1.02,24.55,0.45,12.93,0.86,,,0.06,,0.33,0.25 309 | 446,1.1,0.6,0.0,0.05,0.19,0.54,0.25,0.00,0.00,,0.01,0.02,0.53,0.01,0.03,0.02,0.00,,,,0.06,0.00 310 | 447,11.8,5.1,0.5,0.49,1.91,5.58,2.38,0.04,,,0.18,0.36,4.50,,0.33,0.07,,,,,0.63, 311 | 448,1.8,0.9,0.1,0.07,0.30,0.91,0.40,0.01,0.00,0.00,0.02,0.04,0.83,0.01,0.06,0.03,0.00,,0.00,0.00,, 312 | 449,0.2,0.1, ,0.01,0.03,0.10,0.05,,,,, ,0.09, ,0.00,,,,,,0.01, 313 | 451,1.4,0.7,0.1,0.07,0.26,0.70,0.29,0.00,,,0.01,0.03,0.62,0.00,0.05,0.02,0.00,,0.00,0.00,, 314 | 452,1.4,0.6,0.1,0.06,0.25,0.70,0.29,0.00,0.00,,0.01,0.03,0.59,0.00,0.04,0.02,0.00,,,,0.06,0.00 315 | 453,4.2,1.7,0.2,0.17,0.73,2.10,0.82,0.01,,,,0.14,1.47,0.02,0.10,0.04,,,,,0.20,0.03 316 | 454,2.4,0.8,0.1,0.10,0.29,1.00,0.60,0.01,0.00,,,0.03,0.79, ,0.11,0.01,0.01,,,,0.10,0.02 317 | 455,1.1,0.6,0.1,0.03,0.14,0.53,0.29,0.01,0.00,0.00,0.01,0.03,0.56,0.00,0.11,0.01,0.00,,,,0.19,0.03 318 | 456,0.6,0.2,0.0,0.02,0.09,0.29,0.12,0.00,0.01,0.00,0.01,0.02,0.20,,0.03,0.00,0.00,,,,0.02,0.00 319 | 458,1.4,0.7,0.1,0.06,0.25,0.71,0.29,,, ,0.01,0.03,0.65,,0.04,0.02,,,0.00,0.00,, 320 | 459,16.3,7.1,0.5,0.58,2.62,8.11,3.48,0.05,,0.03,0.15,0.56,6.25,0.05,0.41,0.10,,,,,0.84,0.10 321 | 461,11.4,5.8,0.4,0.41,1.73,5.78,2.53,0.04,0.02,0.02,0.16,0.39,5.14,0.04,0.28,0.06,0.02,,,,0.54,0.12 322 | 462,13.2,5.6,0.3,0.55,2.13,6.15,2.59,0.05,,,0.23,0.46,4.82,,0.24,0.10,,,,,0.99, 323 | 463,14.2,6.0,0.5,0.61,2.37,6.66,3.02,,,,0.22,0.43,5.22,,0.31,0.08,,,,,0.86, 324 | 464,19.7,8.7,0.4,0.70,3.26,10.07,4.24,0.06,0.03,0.03,0.32,0.63,7.67,0.03,0.29,0.11,0.03,,,,1.01,0.16 325 | 465,15.9,7.3,0.4,0.58,2.58,8.05,3.38,0.05,,,0.23,0.49,6.45,0.05,0.33,0.08,,,,,0.85,0.18 326 | 466,1.6,0.8,0.0,0.05,0.23,0.81,0.40,0.01,,,0.02,0.05,0.76, ,0.04,0.01,,,,,0.09, 327 | 467,16.3,6.8,0.5,0.71,2.67,7.59,3.16,,,,0.27,0.51,5.91,,0.42,0.11,,,,,0.87, 328 | 468,13.7,6.4,0.3,0.52,2.26,7.16,2.72,0.04,0.04,0.02,0.24,0.50,5.54,0.04,0.24,0.07,,,,,0.55,0.11 329 | 469,4.5,2.4,0.2,0.15,0.66,2.28,1.06,0.02,0.02,0.02,0.06,0.15,2.16,0.02,0.14,0.02,0.01,,,,0.21,0.04 330 | 484,6.4,7.0,6.2,0.08,0.42,4.20,1.56,0.04,0.05,0.02,0.04,0.26,6.61,0.05,5.53,0.44,0.15,,,0.04,0.15, 331 | 485,8.9,12.1,2.7,0.00,0.13,6.39,2.31,0.01,0.03,,0.03,1.07,11.01,0.03,2.20,0.10,0.44,,,,0.04,0.07 332 | 487,9.2,12.1,4.0,,0.08,6.56,2.43,,0.03,,,0.67,11.29,0.07,3.25,0.05,0.44,,,0.10,0.05,0.03 333 | 488,2.9,3.8,1.1,,0.02,2.07,0.76,,0.01,,,0.21,3.51,0.02,0.94,0.02,0.12,,,0.02,0.02, 334 | 489,2.6,3.6,1.2,,0.02,1.87,0.69,,0.01,0.01,,0.23,3.33,0.01,0.88,0.02,0.14,,0.05,0.04,, 335 | 490,4.1,5.7,4.9,,0.03,2.95,1.05,0.02,0.03,0.02,,0.23,5.45,0.04,4.34,0.33,0.17,,,0.03,0.02, 336 | 491,1.1,0.6,0.3,0.00,0.02,0.51,0.55,0.02,0.01,0.00,,0.01,0.62,,0.29,0.03,,,,,0.01, 337 | 495,17.5,10.0,0.9,0.09,0.34,7.46,9.12,0.26,0.03,,,0.14,9.75,0.06,0.91,0.03,,,,,0.17,0.10 338 | 496,14.1,9.3,3.2,0.10,0.33,6.24,6.73,0.20,0.04,0.02,,0.09,9.14,,3.09,0.07,,,,,0.20, 339 | 497,19.2,11.4,1.5,0.06,0.22,8.08,10.29,0.31,0.06,0.03,,0.10,11.32,,1.41,0.10,,,,,0.18, 340 | 498,13.1,8.1,1.0,0.01,0.06,5.61,7.08,0.21,0.04,0.02,,0.05,8.03,0.01,0.94,0.06,,,,,0.14, 341 | 499,8.4,0.4,0.1,4.56,1.56,0.61,0.20,,,,,,0.36,,0.07,,,,,,, 342 | 500,0.0,0.0,0.0,0.00,0.00,0.02,0.00,0.00,,0.00,,,0.02,,0.01,0.01,,,,,, 343 | 501,1.3,3.9,2.0,,,0.73,0.17,0.08,0.20,0.13,,,3.74,0.11,1.94,0.01,,,,,, 344 | 502,0.0,0.0,0.0,,,0.00,0.00,,,,,,0.00,,0.00,,,,,,, 345 | 509,11.3,4.8,4.7,4.10,1.60,2.97,1.47,0.04,0.04,,,0.16,4.55,0.04,4.19,0.35,0.11,,,,0.05, 346 | 511,5.3,1.1,4.9,,0.01,4.04,0.95,0.29,0.06,,,0.01,1.11,0.02,4.82,0.11,,,,,, 347 | 512,4.0,1.6,0.1,0.27,0.59,1.73,0.95,0.02,0.02,,0.05,0.10,1.50, ,0.11,0.04,,,,,0.55,0.04 348 | 518,0.0,0.0,0.0,0.00,0.00,0.00,0.00,,0.00,,,,0.01,,0.01,0.00,,,,,, 349 | 520,3.5,11.0,3.0,,,2.87,0.47,0.08,0.02,0.01,,0.29,10.57,0.04,2.77,0.19,,,,,, 350 | 521,2.3,8.3,1.0,,,1.93,0.29,0.05,0.01,0.01,,0.18,8.07,0.03,0.91,0.13,,,,,, 351 | 522,25.9,0.1,0.1,10.70,3.64,2.63,7.46,0.08,,0.03,, ,0.05,0.00,0.08,,,,,,, 352 | 523,15.6,0.9,0.2,8.25,2.99,1.33,0.51,0.01,,,,,0.92,,0.17,,,,,,, 353 | 524,4.1,6.4,15.4,,0.02,2.84,0.37,0.08,0.11,0.04,,0.04,6.24,0.14,13.86,1.43,,,,,,0.17 354 | 525,9.1,7.8,2.1,0.10,0.16,7.71,1.05,0.07,0.02,,,,7.81,,2.01,0.12,,,,,, 355 | 526,3.2,3.0,0.2,,0.19,1.61,1.29,0.01,,,0.04,0.24,2.64,0.01,0.16,0.03,0.01,,0.01,,0.18,0.03 356 | 527,0.6,1.0,1.5,,0.00,0.42,0.13,0.01,0.01,0.00,,0.02,0.95,0.00,1.36,0.13,0.00,0.00,,0.00,,0.01 357 | 528,3.3,4.3,1.4,,0.12,2.05,1.11,0.00,,,,0.20,3.96,0.05,1.24,0.06,0.05,0.00,0.02,,0.06, 358 | 529,7.9,8.2,3.3,,0.38,4.59,2.63,0.03,0.03,,0.10,0.57,7.32,0.05,2.88,0.26,0.07,,0.02,0.02,0.40, 359 | 530,1.8,2.5,3.5,,0.02,1.26,0.44,0.02,0.03,0.02,,0.05,2.39,0.05,3.22,0.24,0.04,,0.00,0.00,0.00,0.06 360 | 531,1.6,0.9,1.5,1.35,0.62,0.72,0.27,0.02,0.02,,,0.01,0.89,,1.33,0.13,0.01,0.03,,0.03,, 361 | 532,0.5,0.5,0.1,,0.02,0.24,0.20,,,,,0.03,0.44,,0.08,0.02,,,,,0.03, 362 | 533,0.2,0.2,0.3,,,0.15,0.02,0.00,,,, ,0.22,,0.26,0.00,,,,,, 363 | 534,1.8,1.8,0.8,0.03,0.15,1.12,0.41,0.01,0.02,0.01,0.01,0.07,1.64,,0.69,0.10,0.00,,,,0.04,0.00 364 | 535,0.6,1.3,1.5,,0.00,0.37,0.18,0.02,0.01,0.00,,0.01,1.25,0.01,1.44,0.06,0.00,0.02,,0.02,,0.02 365 | 536,2.5,1.2,0.1,0.00,0.11,1.06,1.19,0.02,0.02,0.01,0.00,0.09,1.11,0.00,0.07,0.01,0.03,,0.02,,0.18,0.02 366 | 537,5.3,3.3,0.9,0.12,0.65,2.81,1.57,0.02,0.02,,0.04,0.19,3.00,0.02,0.74,0.08,0.02,,0.01,,0.26,0.01 367 | 538,3.7,2.2,1.0,0.12,0.54,2.09,0.93,0.02,0.01,0.00,0.03,0.10,2.05,0.02,0.91,0.07,0.04,,0.00,,0.19,0.01 368 | 539,2.2,2.9,1.5,,0.06,1.39,0.67,,,,,0.13,2.69,0.04,1.25,0.19,0.05,,,,, 369 | 540,1.9,2.6,1.6,,0.07,1.25,0.58,,,,,0.13,2.41,0.04,1.35,0.18,0.02,,,,, 370 | 541,1.6,2.5,1.8,,0.03,1.24,0.34,0.00,0.00,,0.00,0.26,2.23,0.02,1.57,0.11,0.03,,0.00,,0.01, 371 | 542,0.3,0.3,0.3,,0.00,0.21,0.07,0.00,0.00,,,0.01,0.25,0.00,0.28,0.01,,0.00,,,0.00,0.00 372 | 543,2.9,3.7,1.7,,0.08,1.73,1.01,0.02,0.01,,,0.16,3.42,0.08,1.41,0.16,0.04,,,,0.04, 373 | 544,1.0,1.1,0.2,,0.08,0.61,0.32,0.00,,0.00,0.03,0.11,0.95,0.00,0.18,0.06,0.00,0.00,0.00,,0.06,0.00 374 | 545,1.1,1.8,3.8,,,0.79,0.26,0.02,0.03,0.00,,0.00,1.75,0.02,3.46,0.36,,,,,,0.01 375 | 546,0.1,0.0,0.2,,,0.05,0.01,0.00,,,,0.00,0.02,,0.07,0.08,,,,,, 376 | 547,1.3,2.1,4.0,,0.00,0.93,0.34,0.02,0.04,0.02,,0.04,2.02,0.02,3.60,0.36,0.04,,,,,0.02 377 | 548,1.4,1.1,0.7,,0.02,0.76,0.56,0.02,0.01,0.02,,0.03,1.04,0.01,0.61,0.03,0.04,0.00,,,0.00, 378 | 549,0.2,0.8,0.2,,,0.18,0.03,,,,,0.01,0.82,,0.20,0.03,,,,,, 379 | 550,0.2,0.1,0.0,,0.00,0.10,0.05,0.00,0.01,,,0.01,0.12,0.00,0.03,,,,,,, 380 | 551,6.0,3.0,0.2,0.25,1.08,3.38,1.38,0.02,,,0.08,0.18,2.64,0.02,0.17,0.02,,,,,0.30,0.03 381 | 552,0.1,0.1,0.0,,,0.06,0.00,,0.00,,,,0.15,0.00,0.04,0.00,,,,,, 382 | 553,4.1,3.2,1.2,,0.29,2.10,1.57,0.02,0.00,,0.04,0.21,2.81,0.02,1.11,0.12,,,,,0.21, 383 | 554,7.5,9.7,4.7,0.04,0.34,4.60,2.42,0.04,,,,0.34,9.07,0.17,4.21,0.30,0.06,,,,0.15, 384 | 555,8.3,10.6,5.1,0.05,0.37,5.12,2.64,0.05,,,,0.44,9.85,0.19,4.57,0.32,0.07,,,,0.17, 385 | 556,0.6,0.9,1.0,,0.00,0.39,0.19,0.00,,,,0.03,0.84,0.00,0.94,0.05,,0.00,,,0.01, 386 | 557,8.7,17.2,16.2,,,4.85,1.21,0.56,1.36,0.66,,0.03,16.67,0.45,16.17,0.04,,,,,, 387 | 558,9.7,29.1,14.2,,0.04,5.28,1.28,0.63,1.52,0.94,,,28.15,0.79,14.18,0.06,,,,,, 388 | 559,0.0,0.1,0.3,,0.00,,0.02,0.00,0.00,0.01,,0.00,0.08,0.00,0.27,0.04,,,,,, 389 | 560,0.1,0.1,0.2,,0.00,0.06,0.02,0.00,0.00,0.00,,,0.10,0.00,0.15,0.02,,,,,, 390 | 561,0.1,0.1,0.3,,,0.11,0.02,0.00,0.00,0.01,,0.00,0.08, ,0.16,0.14,,,,,, 391 | 562,0.2,0.1,0.9,,,0.14,0.03,0.00,0.01,0.01,,,0.11,,0.40,0.49,,,,,, 392 | 563,0.2,0.1,0.3,,0.00,0.18,0.03,0.01,0.02,0.01,,0.00,0.05,0.00,0.21,0.10,,,,,, 393 | 564,0.7,0.2,0.9,0.00,0.00,0.50,0.08,0.02,0.04,0.03,,,0.15,0.01,0.58,0.28,,,,,, 394 | 565,0.1,0.1,0.3,,0.00,0.10,0.01,0.00,0.00,0.01,,0.00,0.06,,0.11,0.20,,,,,, 395 | 566,0.3,0.2,0.6,,0.00,0.25,0.03,0.00,0.01,0.01,,0.00,0.15,,0.23,0.41,,,,,, 396 | 567,0.1,0.1,0.3,,,0.11,0.02,0.00,0.01,0.01,,,0.09,,0.16,0.11,,,,,, 397 | 568,0.2,0.1,0.8,,0.00,0.15,0.03,0.01,0.01,0.01,0.00,0.00,0.13,,0.38,0.47,,,,,, 398 | 569,0.1,0.0,0.2,,0.00,0.10,0.02,0.00,0.00,0.00,,0.00,0.03,,0.09,0.13,,,,,, 399 | 570,0.4,0.1,0.8,,0.00,0.30,0.04,0.01,0.01,0.01,,0.00,0.14,,0.29,0.46,,,,,, 400 | 571,0.2,0.0,0.2,,0.00,0.12,0.02,0.01,0.02,0.01,,0.00,0.04,0.00,0.16,0.07,,,,,, 401 | 572,0.6,0.1,0.7,,0.00,0.28,0.05,0.01,0.03,0.02,,,0.09,0.01,0.33,0.14,,,,,, 402 | 573,0.1,0.1,0.3,,0.00,0.10,0.01,0.00,0.00,0.00,,0.00,0.06,0.00,0.14,0.19,,,,,, 403 | 574,0.3,0.2,0.8,,0.00,0.27,0.03,0.00,0.01,0.01,,0.00,0.16,,0.34,0.46,,,,,, 404 | 575,0.9,1.4,2.8,,0.01,0.57,0.20,0.05,0.02,0.01,,0.01,1.42,0.02,2.71,0.13,,,,,, 405 | 576,0.6,0.2,0.9,,0.00,0.44,0.08,0.02,0.02,0.02,,0.00,0.13,0.00,0.86,0.06,,,,,0.00, 406 | 577,0.1,0.1,0.3,,0.00,0.08,0.01,0.00,0.00,0.00,,0.00,0.14,0.00,0.21,0.04,,,,,, 407 | 578,0.1,0.2,0.4,,0.01,0.10,0.01,0.01,0.00,0.00,0.00,0.00,0.16,0.01,0.33,0.09,,,,,, 408 | 579,4.1,10.0,7.3,,,2.24,0.56,0.27,0.65,0.34,,0.01,9.73,0.26,7.25,0.02,,,,,, 409 | 580,5.1,14.4,8.3,,,2.70,0.64,0.35,0.84,0.51,,0.02,13.91,0.41,8.25,,,,,,, 410 | 582,0.2,0.3,0.6,,0.00,0.12,0.05,0.00,0.01,0.00,,0.00,0.25,0.01,0.58,0.06,,,,,,0.01 411 | 583,3.3,6.4,12.9,,0.02,2.53,0.57,0.06,0.09,0.03,,0.02,6.30,0.05,11.67,1.23,,,,,, 412 | 584,0.4,0.5,1.7,,0.01,0.27,0.10,0.01,0.01,0.00,,0.00,0.51,0.00,1.48,0.20,,,,,, 413 | 585,1.2,5.4,1.7,,,0.61,0.19,0.10,0.26,0.05,,0.02,4.89,0.33,1.08,0.57,,,,,, 414 | 586,0.4,1.9,0.6,,,0.20,0.06,0.03,0.09,0.02,,0.00,1.82,0.12,0.40,0.22,,,,,, 415 | 587,4.8,32.3,16.2,,0.04,3.91,0.77,0.04,0.02,,,0.22,31.95,0.03,16.17,0.03,,,,,0.10,0.02 416 | 588,7.7,26.5,8.1,,,3.95,3.42,0.23,0.06,0.06,,0.13,26.27,0.08,8.00,0.08,,,,,0.11, 417 | 589,15.3,27.4,21.0,,0.04,0.04,6.14,0.16,0.03,,,0.18,27.14,0.04,20.97,0.04,,,,,, 418 | 590,30.0,1.5,0.3,15.37,6.12,2.74,0.97,,,,,,1.47,,0.32,,,,,,, 419 | 591,3.1,1.1,0.3,1.24,0.80,0.77,0.14,0.00,0.00,0.01,,0.00,1.15,0.00,0.28,,,,,,, 420 | 593,7.8,19.9,22.5,,0.03,4.86,2.58,0.26,,0.04,,0.07,19.72,0.09,22.39,0.16,,,,,, 421 | 594,4.2,7.1,25.3,,0.03,2.49,1.62,0.06,,0.04,,0.03,7.06,0.04,5.42,19.81,,,,,, 422 | 595,0.3,0.1,0.2,,,0.18,0.04,0.03,0.02,,,,0.09,,0.22,,,,,,, 423 | 596,3.1,6.8,0.4,,,2.77,0.26,0.03,,,,0.32,6.45,0.01,0.28,0.08,,,,,, 424 | 597,5.6,8.7,44.1,,,4.26,1.34,,,,,,8.66,0.09,35.30,8.82,,,,,, -------------------------------------------------------------------------------- /references/csv/food.csv: -------------------------------------------------------------------------------- 1 | id,categoryId,name 2 | 1,1,"Arroz, integral, cozido" 3 | 2,1,"Arroz, integral, cru" 4 | 3,1,"Arroz, tipo 1, cozido" 5 | 4,1,"Arroz, tipo 1, cru" 6 | 5,1,"Arroz, tipo 2, cozido" 7 | 6,1,"Arroz, tipo 2, cru" 8 | 7,1,"Aveia, flocos, crua" 9 | 8,1,"Biscoito, doce, maisena" 10 | 9,1,"Biscoito, doce, recheado com chocolate" 11 | 10,1,"Biscoito, doce, recheado com morango" 12 | 11,1,"Biscoito, doce, wafer, recheado de chocolate" 13 | 12,1,"Biscoito, doce, wafer, recheado de morango" 14 | 13,1,"Biscoito, salgado, cream cracker" 15 | 14,1,"Bolo, mistura para" 16 | 15,1,"Bolo, pronto, aipim" 17 | 16,1,"Bolo, pronto, chocolate" 18 | 17,1,"Bolo, pronto, coco" 19 | 18,1,"Bolo, pronto, milho" 20 | 19,1,"Canjica, branca, crua" 21 | 20,1,"Canjica, com leite integral" 22 | 21,1,"Cereais, milho, flocos, com sal" 23 | 22,1,"Cereais, milho, flocos, sem sal" 24 | 23,1,"Cereais, mingau, milho, infantil" 25 | 24,1,"Cereais, mistura para vitamina, trigo, cevada e aveia" 26 | 25,1,"Cereal matinal, milho" 27 | 26,1,"Cereal matinal, milho, açúcar" 28 | 27,1,"Creme de arroz, pó" 29 | 28,1,"Creme de milho, pó" 30 | 29,1,"Curau, milho verde" 31 | 30,1,"Curau, milho verde, mistura para" 32 | 31,1,"Farinha, de arroz, enriquecida" 33 | 32,1,"Farinha, de centeio, integral" 34 | 33,1,"Farinha, de milho, amarela" 35 | 34,1,"Farinha, de rosca" 36 | 35,1,"Farinha, de trigo" 37 | 36,1,"Farinha, láctea, de cereais" 38 | 37,1,"Lasanha, massa fresca, cozida" 39 | 38,1,"Lasanha, massa fresca, crua" 40 | 39,1,"Macarrão, instantâneo" 41 | 40,1,"Macarrão, trigo, cru" 42 | 41,1,"Macarrão, trigo, cru, com ovos" 43 | 42,1,"Milho, amido, cru" 44 | 43,1,"Milho, fubá, cru" 45 | 44,1,"Milho, verde, cru" 46 | 45,1,"Milho, verde, enlatado, drenado" 47 | 46,1,"Mingau tradicional, pó" 48 | 47,1,"Pamonha, barra para cozimento, pré-cozida" 49 | 48,1,"Pão, aveia, forma" 50 | 49,1,"Pão, de soja" 51 | 50,1,"Pão, glúten, forma" 52 | 51,1,"Pão, milho, forma" 53 | 52,1,"Pão, trigo, forma, integral" 54 | 53,1,"Pão, trigo, francês" 55 | 54,1,"Pão, trigo, sovado" 56 | 55,1,"Pastel, de carne, cru" 57 | 56,1,"Pastel, de carne, frito" 58 | 57,1,"Pastel, de queijo, cru" 59 | 58,1,"Pastel, de queijo, frito" 60 | 59,1,"Pastel, massa, crua" 61 | 60,1,"Pastel, massa, frita" 62 | 61,1,"Pipoca, com óleo de soja, sem sal" 63 | 62,1,"Polenta, pré-cozida" 64 | 63,1,"Torrada, pão francês" 65 | 64,2,"Abóbora, cabotian, cozida" 66 | 65,2,"Abóbora, cabotian, crua" 67 | 66,2,"Abóbora, menina brasileira, crua" 68 | 67,2,"Abóbora, moranga, crua" 69 | 68,2,"Abóbora, moranga, refogada" 70 | 69,2,"Abóbora, pescoço, crua" 71 | 70,2,"Abobrinha, italiana, cozida" 72 | 71,2,"Abobrinha, italiana, crua" 73 | 72,2,"Abobrinha, italiana, refogada" 74 | 73,2,"Abobrinha, paulista, crua" 75 | 74,2,"Acelga, crua" 76 | 75,2,"Agrião, cru" 77 | 76,2,"Aipo, cru" 78 | 77,2,"Alface, americana, crua" 79 | 78,2,"Alface, crespa, crua" 80 | 79,2,"Alface, lisa, crua" 81 | 80,2,"Alface, roxa, crua" 82 | 81,2,"Alfavaca, crua" 83 | 82,2,"Alho, cru" 84 | 83,2,"Alho-poró, cru" 85 | 84,2,"Almeirão, cru" 86 | 85,2,"Almeirão, refogado" 87 | 86,2,"Batata, baroa, cozida" 88 | 87,2,"Batata, baroa, crua" 89 | 88,2,"Batata, doce, cozida" 90 | 89,2,"Batata, doce, crua" 91 | 90,2,"Batata, frita, tipo chips, industrializada" 92 | 91,2,"Batata, inglesa, cozida" 93 | 92,2,"Batata, inglesa, crua" 94 | 93,2,"Batata, inglesa, frita" 95 | 94,2,"Batata, inglesa, sauté" 96 | 95,2,"Berinjela, cozida" 97 | 96,2,"Berinjela, crua" 98 | 97,2,"Beterraba, cozida" 99 | 98,2,"Beterraba, crua" 100 | 99,2,"Biscoito, polvilho doce" 101 | 100,2,"Brócolis, cozido" 102 | 101,2,"Brócolis, cru" 103 | 102,2,"Cará, cozido" 104 | 103,2,"Cará, cru" 105 | 104,2,"Caruru, cru" 106 | 105,2,"Catalonha, crua" 107 | 106,2,"Catalonha, refogada" 108 | 107,2,"Cebola, crua" 109 | 108,2,"Cebolinha, crua" 110 | 109,2,"Cenoura, cozida" 111 | 110,2,"Cenoura, crua" 112 | 111,2,"Chicória, crua" 113 | 112,2,"Chuchu, cozido" 114 | 113,2,"Chuchu, cru" 115 | 114,2,"Coentro, folhas desidratadas" 116 | 115,2,"Couve, manteiga, crua" 117 | 116,2,"Couve, manteiga, refogada " 118 | 117,2,"Couve-flor, crua" 119 | 118,2,"Couve-flor, cozida" 120 | 119,2,"Espinafre, Nova Zelândia, cru" 121 | 120,2,"Espinafre, Nova Zelândia, refogado" 122 | 121,2,"Farinha, de mandioca, crua" 123 | 122,2,"Farinha, de mandioca, torrada" 124 | 123,2,"Farinha, de puba" 125 | 124,2,"Fécula, de mandioca" 126 | 125,2,"Feijão, broto, cru" 127 | 126,2,"Inhame, cru" 128 | 127,2,"Jiló, cru" 129 | 128,2,"Jurubeba, crua" 130 | 129,2,"Mandioca, cozida" 131 | 130,2,"Mandioca, crua" 132 | 131,2,"Mandioca, farofa, temperada" 133 | 132,2,"Mandioca, frita" 134 | 133,2,"Manjericão, cru" 135 | 134,2,"Maxixe, cru" 136 | 135,2,"Mostarda, folha, crua" 137 | 136,2,"Nhoque, batata, cozido" 138 | 137,2,"Nabo, cru" 139 | 138,2,"Palmito, juçara, em conserva" 140 | 139,2,"Palmito, pupunha, em conserva" 141 | 140,2,"Pão, de queijo, assado" 142 | 141,2,"Pão, de queijo, cru" 143 | 142,2,"Pepino, cru" 144 | 143,2,"Pimentão, amarelo, cru" 145 | 144,2,"Pimentão, verde, cru" 146 | 145,2,"Pimentão, vermelho, cru" 147 | 146,2,"Polvilho, doce" 148 | 147,2,"Quiabo, cru" 149 | 148,2,"Rabanete, cru" 150 | 149,2,"Repolho, branco, cru" 151 | 150,2,"Repolho, roxo, cru" 152 | 151,2,"Repolho, roxo, refogado" 153 | 152,2,"Rúcula, crua" 154 | 153,2,"Salsa, crua" 155 | 154,2,"Seleta de legumes, enlatada" 156 | 155,2,"Serralha, crua" 157 | 156,2,"Taioba, crua" 158 | 157,2,"Tomate, com semente, cru" 159 | 158,2,"Tomate, extrato" 160 | 159,2,"Tomate, molho industrializado" 161 | 160,2,"Tomate, purê" 162 | 161,2,"Tomate, salada" 163 | 162,2,"Vagem, crua" 164 | 163,3,"Abacate, cru" 165 | 164,3,"Abacaxi, cru" 166 | 165,3,"Abacaxi, polpa, congelada" 167 | 166,3,"Abiu, cru" 168 | 167,3,"Açaí, polpa, com xarope de guaraná e glucose" 169 | 168,3,"Açaí, polpa, congelada" 170 | 169,3,"Acerola, crua" 171 | 170,3,"Acerola, polpa, congelada" 172 | 171,3,"Ameixa, calda, enlatada " 173 | 172,3,"Ameixa, crua" 174 | 173,3,"Ameixa, em calda, enlatada, drenada " 175 | 174,3,"Atemóia, crua" 176 | 175,3,"Banana, da terra, crua" 177 | 176,3,"Banana, doce em barra" 178 | 177,3,"Banana, figo, crua" 179 | 178,3,"Banana, maçã, crua" 180 | 179,3,"Banana, nanica, crua" 181 | 180,3,"Banana, ouro, crua" 182 | 181,3,"Banana, pacova, crua" 183 | 182,3,"Banana, prata, crua" 184 | 183,3,"Cacau, cru" 185 | 184,3,"Cajá-Manga, cru" 186 | 185,3,"Cajá, polpa, congelada" 187 | 186,3,"Caju, cru" 188 | 187,3,"Caju, polpa, congelada" 189 | 188,3,"Caju, suco concentrado, envasado" 190 | 189,3,"Caqui, chocolate, cru" 191 | 190,3,"Carambola, crua" 192 | 191,3,"Ciriguela, crua" 193 | 192,3,"Cupuaçu, cru" 194 | 193,3,"Cupuaçu, polpa, congelada" 195 | 194,3,"Figo, cru" 196 | 195,3,"Figo, enlatado, em calda" 197 | 196,3,"Fruta-pão, crua" 198 | 197,3,"Goiaba, branca, com casca, crua" 199 | 198,3,"Goiaba, doce em pasta" 200 | 199,3,"Goiaba, doce, cascão" 201 | 200,3,"Goiaba, vermelha, com casca, crua" 202 | 201,3,"Graviola, crua" 203 | 202,3,"Graviola, polpa, congelada" 204 | 203,3,"Jabuticaba, crua" 205 | 204,3,"Jaca, crua" 206 | 205,3,"Jambo, cru" 207 | 206,3,"Jamelão, cru" 208 | 207,3,"Kiwi, cru" 209 | 208,3,"Laranja, baía, crua" 210 | 209,3,"Laranja, baía, suco" 211 | 210,3,"Laranja, da terra, crua" 212 | 211,3,"Laranja, da terra, suco" 213 | 212,3,"Laranja, lima, crua" 214 | 213,3,"Laranja, lima, suco" 215 | 214,3,"Laranja, pêra, crua" 216 | 215,3,"Laranja, pêra, suco" 217 | 216,3,"Laranja, valência, crua" 218 | 217,3,"Laranja, valência, suco" 219 | 218,3,"Limão, cravo, suco" 220 | 219,3,"Limão, galego, suco" 221 | 220,3,"Limão, tahiti, cru" 222 | 221,3,"Maçã, Argentina, com casca, crua" 223 | 222,3,"Maçã, Fuji, com casca, crua" 224 | 223,3,"Macaúba, crua" 225 | 224,3," Mamão, doce em calda, drenado" 226 | 225,3,"Mamão, Formosa, cru" 227 | 226,3,"Mamão, Papaia, cru" 228 | 227,3," Mamão verde, doce em calda, drenado" 229 | 228,3,"Manga, Haden, crua" 230 | 229,3,"Manga, Palmer, crua" 231 | 230,3,"Manga, polpa, congelada" 232 | 231,3,"Manga, Tommy Atkins, crua" 233 | 232,3,"Maracujá, cru" 234 | 233,3,"Maracujá, polpa, congelada" 235 | 234,3,"Maracujá, suco concentrado, envasado" 236 | 235,3,"Melancia, crua" 237 | 236,3,"Melão, cru" 238 | 237,3,"Mexerica, Murcote, crua" 239 | 238,3,"Mexerica, Rio, crua" 240 | 239,3,"Morango, cru" 241 | 240,3,"Nêspera, crua" 242 | 241,3,"Pequi, cru" 243 | 242,3,"Pêra, Park, crua" 244 | 243,3,"Pêra, Williams, crua" 245 | 244,3,"Pêssego, Aurora, cru" 246 | 245,3,"Pêssego, enlatado, em calda" 247 | 246,3,"Pinha, crua" 248 | 247,3,"Pitanga, crua" 249 | 248,3,"Pitanga, polpa, congelada" 250 | 249,3,"Romã, crua" 251 | 250,3,"Tamarindo, cru" 252 | 251,3,"Tangerina, Poncã, crua" 253 | 252,3,"Tangerina, Poncã, suco" 254 | 253,3,"Tucumã, cru" 255 | 254,3,"Umbu, cru" 256 | 255,3,"Umbu, polpa, congelada" 257 | 256,3,"Uva, Itália, crua" 258 | 257,3,"Uva, Rubi, crua" 259 | 258,3,"Uva, suco concentrado, envasado" 260 | 259,4,"Azeite, de dendê" 261 | 260,4,"Azeite, de oliva, extra virgem" 262 | 261,4,"Manteiga, com sal" 263 | 262,4,"Manteiga, sem sal" 264 | 263,4,"Margarina, com óleo hidrogenado, com sal (65% de lipídeos)" 265 | 264,4,"Margarina, com óleo hidrogenado, sem sal (80% de lipídeos)" 266 | 265,4,"Margarina, com óleo interesterificado, com sal (65%de lipídeos)" 267 | 266,4,"Margarina, com óleo interesterificado, sem sal (65% de lipídeos)" 268 | 267,4,"Óleo, de babaçu" 269 | 268,4,"Óleo, de canola" 270 | 269,4,"Óleo, de girassol" 271 | 270,4,"Óleo, de milho" 272 | 271,4,"Óleo, de pequi" 273 | 272,4,"Óleo, de soja" 274 | 273,5,"Abadejo, filé, congelado, assado" 275 | 274,5,"Abadejo, filé, congelado,cozido" 276 | 275,5,"Abadejo, filé, congelado, cru" 277 | 276,5,"Abadejo, filé, congelado, grelhado" 278 | 277,5,"Atum, conserva em óleo" 279 | 278,5,"Atum, fresco, cru" 280 | 279,5,"Bacalhau, salgado, cru" 281 | 280,5,"Bacalhau, salgado, refogado" 282 | 281,5,"Cação, posta, com farinha de trigo, frita" 283 | 282,5,"Cação, posta, cozida" 284 | 283,5,"Cação, posta, crua" 285 | 284,5,"Camarão, Rio Grande, grande, cozido" 286 | 285,5,"Camarão, Rio Grande, grande, cru" 287 | 286,5,"Camarão, Sete Barbas, sem cabeça, com casca, frito" 288 | 287,5,"Caranguejo, cozido" 289 | 288,5,"Corimba, cru" 290 | 289,5,"Corimbatá, assado" 291 | 290,5,"Corimbatá, cozido" 292 | 291,5,"Corvina de água doce, crua" 293 | 292,5,"Corvina do mar, crua" 294 | 293,5,"Corvina grande, assada" 295 | 294,5,"Corvina grande, cozida" 296 | 295,5,"Dourada de água doce, fresca" 297 | 296,5,"Lambari, congelado, cru" 298 | 297,5,"Lambari, congelado, frito" 299 | 298,5,"Lambari, fresco, cru" 300 | 299,5,"Manjuba, com farinha de trigo, frita" 301 | 300,5,"Manjuba, frita" 302 | 301,5,"Merluza, filé, assado" 303 | 302,5,"Merluza, filé, cru" 304 | 303,5,"Merluza, filé, frito" 305 | 304,5,"Pescada, branca, crua" 306 | 305,5,"Pescada, branca, frita" 307 | 306,5,"Pescada, filé, com farinha de trigo, frito" 308 | 307,5,"Pescada, filé, cru" 309 | 308,5,"Pescada, filé, frito" 310 | 309,5,"Pescada, filé, molho escabeche" 311 | 310,5,"Pescadinha, crua" 312 | 311,5,"Pintado, assado" 313 | 312,5,"Pintado, cru" 314 | 313,5,"Pintado, grelhado" 315 | 314,5,"Porquinho, cru" 316 | 315,5,"Salmão, filé, com pele, fresco, grelhado" 317 | 316,5,"Salmão, sem pele, fresco, cru" 318 | 317,5,"Salmão, sem pele, fresco, grelhado" 319 | 318,5,"Sardinha, assada" 320 | 319,5,"Sardinha, conserva em óleo" 321 | 320,5,"Sardinha, frita" 322 | 321,5,"Sardinha, inteira, crua" 323 | 322,5,"Tucunaré, filé, congelado, cru" 324 | 323,6,Apresuntado 325 | 324,6,"Caldo de carne, tablete" 326 | 325,6,"Caldo de galinha, tablete" 327 | 326,6,"Carne, bovina, acém, moído, cozido" 328 | 327,6,"Carne, bovina, acém, moído, cru" 329 | 328,6,"Carne, bovina, acém, sem gordura, cozido" 330 | 329,6,"Carne, bovina, acém, sem gordura, cru" 331 | 330,6,"Carne, bovina, almôndegas, cruas" 332 | 331,6,"Carne, bovina, almôndegas, fritas" 333 | 332,6,"Carne, bovina, bucho, cozido" 334 | 333,6,"Carne, bovina, bucho, cru" 335 | 334,6,"Carne, bovina, capa de contra-filé, com gordura, crua" 336 | 335,6,"Carne, bovina, capa de contra-filé, com gordura, grelhada" 337 | 336,6,"Carne, bovina, capa de contra-filé, sem gordura, crua" 338 | 337,6,"Carne, bovina, capa de contra-filé, sem gordura, grelhada" 339 | 338,6,"Carne, bovina, charque, cozido" 340 | 339,6,"Carne, bovina, charque, cru" 341 | 340,6,"Carne, bovina, contra-filé, à milanesa" 342 | 341,6,"Carne, bovina, contra-filé de costela, cru" 343 | 342,6,"Carne, bovina, contra-filé de costela, grelhado" 344 | 343,6,"Carne, bovina, contra-filé, com gordura, cru" 345 | 344,6,"Carne, bovina, contra-filé, com gordura, grelhado" 346 | 345,6,"Carne, bovina, contra-filé, sem gordura, cru" 347 | 346,6,"Carne, bovina, contra-filé, sem gordura, grelhado" 348 | 347,6,"Carne, bovina, costela, assada" 349 | 348,6,"Carne, bovina, costela, crua" 350 | 349,6,"Carne, bovina, coxão duro, sem gordura, cozido" 351 | 350,6,"Carne, bovina, coxão duro, sem gordura, cru" 352 | 351,6,"Carne, bovina, coxão mole, sem gordura, cozido" 353 | 352,6,"Carne, bovina, coxão mole, sem gordura, cru" 354 | 353,6,"Carne, bovina, cupim, assado" 355 | 354,6,"Carne, bovina, cupim, cru" 356 | 355,6,"Carne, bovina, fígado, cru" 357 | 356,6,"Carne, bovina, fígado, grelhado" 358 | 357,6,"Carne, bovina, filé mingnon, sem gordura, cru" 359 | 358,6,"Carne, bovina, filé mingnon, sem gordura, grelhado" 360 | 359,6,"Carne, bovina, flanco, sem gordura, cozido" 361 | 360,6,"Carne, bovina, flanco, sem gordura, cru" 362 | 361,6,"Carne, bovina, fraldinha, com gordura, cozida" 363 | 362,6,"Carne, bovina, fraldinha, com gordura, crua" 364 | 363,6,"Carne, bovina, lagarto, cozido" 365 | 364,6,"Carne, bovina, lagarto, cru" 366 | 365,6,"Carne, bovina, língua, cozida" 367 | 366,6,"Carne, bovina, língua, crua" 368 | 367,6,"Carne, bovina, maminha, crua" 369 | 368,6,"Carne, bovina, maminha, grelhada" 370 | 369,6,"Carne, bovina, miolo de alcatra, sem gordura, cru" 371 | 370,6,"Carne, bovina, miolo de alcatra, sem gordura, grelhado" 372 | 371,6,"Carne, bovina, músculo, sem gordura, cozido" 373 | 372,6,"Carne, bovina, músculo, sem gordura, cru" 374 | 373,6,"Carne, bovina, paleta, com gordura, crua" 375 | 374,6,"Carne, bovina, paleta, sem gordura, cozida" 376 | 375,6,"Carne, bovina, paleta, sem gordura, crua" 377 | 376,6,"Carne, bovina, patinho, sem gordura, cru" 378 | 377,6,"Carne, bovina, patinho, sem gordura, grelhado" 379 | 378,6,"Carne, bovina, peito, sem gordura, cozido" 380 | 379,6,"Carne, bovina, peito, sem gordura, cru" 381 | 380,6,"Carne, bovina, picanha, com gordura, crua" 382 | 381,6,"Carne, bovina, picanha, com gordura, grelhada" 383 | 382,6,"Carne, bovina, picanha, sem gordura, crua" 384 | 383,6,"Carne, bovina, picanha, sem gordura, grelhada" 385 | 384,6,"Carne, bovina, seca, cozida" 386 | 385,6,"Carne, bovina, seca, crua" 387 | 386,6,"Coxinha de frango, frita" 388 | 387,6,"Croquete, de carne, cru" 389 | 388,6,"Croquete, de carne, frito" 390 | 389,6,"Empada de frango, pré-cozida, assada" 391 | 390,6,"Empada, de frango, pré-cozida" 392 | 391,6,"Frango, asa, com pele, crua" 393 | 392,6,"Frango, caipira, inteiro, com pele, cozido" 394 | 393,6,"Frango, caipira, inteiro, sem pele, cozido" 395 | 394,6,"Frango, coração, cru" 396 | 395,6,"Frango, coração, grelhado" 397 | 396,6,"Frango, coxa, com pele, assada" 398 | 397,6,"Frango, coxa, com pele, crua" 399 | 398,6,"Frango, coxa, sem pele, cozida" 400 | 399,6,"Frango, coxa, sem pele, crua" 401 | 400,6,"Frango, fígado, cru" 402 | 401,6,"Frango, filé, à milanesa" 403 | 402,6,"Frango, inteiro, com pele, cru" 404 | 403,6,"Frango, inteiro, sem pele, assado" 405 | 404,6,"Frango, inteiro, sem pele, cozido" 406 | 405,6,"Frango, inteiro, sem pele, cru" 407 | 406,6,"Frango, peito, com pele, assado" 408 | 407,6,"Frango, peito, com pele, cru" 409 | 408,6,"Frango, peito, sem pele, cozido" 410 | 409,6,"Frango, peito, sem pele, cru" 411 | 410,6,"Frango, peito, sem pele, grelhado" 412 | 411,6,"Frango, sobrecoxa, com pele, assada" 413 | 412,6,"Frango, sobrecoxa, com pele, crua" 414 | 413,6,"Frango, sobrecoxa, sem pele, assada" 415 | 414,6,"Frango, sobrecoxa, sem pele, crua" 416 | 415,6,"Hambúrguer, bovino, cru" 417 | 416,6,"Hambúrguer, bovino, frito" 418 | 417,6,"Hambúrguer, bovino, grelhado" 419 | 418,6,"Lingüiça, frango, crua" 420 | 419,6,"Lingüiça, frango, frita" 421 | 420,6,"Lingüiça, frango, grelhada" 422 | 421,6,"Lingüiça, porco, crua" 423 | 422,6,"Lingüiça, porco, frita" 424 | 423,6,"Lingüiça, porco, grelhada" 425 | 424,6,Mortadela 426 | 425,6,"Peru, congelado, assado" 427 | 426,6,"Peru, congelado, cru" 428 | 427,6,"Porco, bisteca, crua" 429 | 428,6,"Porco, bisteca, frita" 430 | 429,6,"Porco, bisteca, grelhada" 431 | 430,6,"Porco, costela, assada" 432 | 431,6,"Porco, costela, crua" 433 | 432,6,"Porco, lombo, assado" 434 | 433,6,"Porco, lombo, cru" 435 | 434,6,"Porco, orelha, salgada, crua" 436 | 435,6,"Porco, pernil, assado" 437 | 436,6,"Porco, pernil, cru" 438 | 437,6,"Porco, rabo, salgado, cru" 439 | 438,6,"Presunto, com capa de gordura" 440 | 439,6,"Presunto, sem capa de gordura" 441 | 440,6,"Quibe, assado" 442 | 441,6,"Quibe, cru" 443 | 442,6,"Quibe, frito" 444 | 443,6,Salame 445 | 444,6,"Toucinho, cru" 446 | 445,6,"Toucinho, frito" 447 | 446,7,"Bebida láctea, pêssego" 448 | 447,7,Creme de Leite 449 | 448,7,"Iogurte, natural" 450 | 449,7,"Iogurte, natural, desnatado" 451 | 450,7,"Iogurte, sabor abacaxi" 452 | 451,7,"Iogurte, sabor morango" 453 | 452,7,"Iogurte, sabor pêssego" 454 | 453,7,"Leite, condensado" 455 | 454,7,"Leite, de cabra" 456 | 455,7,"Leite, de vaca, achocolatado" 457 | 456,7,"Leite, de vaca, desnatado, pó" 458 | 457,7,"Leite, de vaca, desnatado, UHT" 459 | 458,7,"Leite, de vaca, integral" 460 | 459,7,"Leite, de vaca, integral, pó" 461 | 460,7,"Leite, fermentado" 462 | 461,7,"Queijo, minas, frescal" 463 | 462,7,"Queijo, minas, meia cura" 464 | 463,7,"Queijo, mozarela" 465 | 464,7,"Queijo, parmesão" 466 | 465,7,"Queijo, pasteurizado" 467 | 466,7,"Queijo, petit suisse, morango" 468 | 467,7,"Queijo, prato" 469 | 468,7,"Queijo, requeijão, cremoso" 470 | 469,7,"Queijo, ricota" 471 | 470,8,"Bebida isotônica, sabores variados" 472 | 471,8,"Café, infusão 10%" 473 | 472,8,"Cana, aguardente 1" 474 | 473,8,"Cana, caldo de" 475 | 474,8,"Cerveja, pilsen 2" 476 | 475,8,"Chá, erva-doce, infusão 5%" 477 | 476,8,"Chá, mate, infusão 5%" 478 | 477,8,"Chá, preto, infusão 5%" 479 | 478,8,"Coco, água de" 480 | 479,8,"Refrigerante, tipo água tônica" 481 | 480,8,"Refrigerante, tipo cola" 482 | 481,8,"Refrigerante, tipo guaraná" 483 | 482,8,"Refrigerante, tipo laranja" 484 | 483,8,"Refrigerante, tipo limão" 485 | 484,9,"Omelete, de queijo" 486 | 485,9,"Ovo, de codorna, inteiro, cru" 487 | 486,9,"Ovo, de galinha, clara, cozida/10minutos" 488 | 487,9,"Ovo, de galinha, gema, cozida/10minutos" 489 | 488,9,"Ovo, de galinha, inteiro, cozido/10minutos" 490 | 489,9,"Ovo, de galinha, inteiro, cru" 491 | 490,9,"Ovo, de galinha, inteiro, frito" 492 | 491,10,"Achocolatado, pó" 493 | 492,10,"Açúcar, cristal" 494 | 493,10,"Açúcar, mascavo" 495 | 494,10,"Açúcar, refinado" 496 | 495,10,"Chocolate, ao leite" 497 | 496,10,"Chocolate, ao leite, com castanha do Pará" 498 | 497,10,"Chocolate, ao leite, dietético" 499 | 498,10,"Chocolate, meio amargo" 500 | 499,10,Cocada branca 501 | 500,10,"Doce, de abóbora, cremoso" 502 | 501,10,"Doce, de leite, cremoso" 503 | 502,10,"Geléia, mocotó, natural" 504 | 503,10,Glicose de milho 505 | 504,10,Maria mole 506 | 505,10,"Maria mole, coco queimado" 507 | 506,10,Marmelada 508 | 507,10,"Mel, de abelha" 509 | 508,10,Melado 510 | 509,10,Quindim 511 | 510,10,Rapadura 512 | 511,11,"Café, pó, torrado" 513 | 512,11,"Capuccino, pó" 514 | 513,11,"Fermento em pó, químico" 515 | 514,11,"Fermento, biológico, levedura, tablete" 516 | 515,11,"Gelatina, sabores variados, pó" 517 | 516,11,"Sal, dietético" 518 | 517,11,"Sal, grosso" 519 | 518,11,Shoyu 520 | 519,11,Tempero a base de sal 521 | 520,12,"Azeitona, preta, conserva" 522 | 521,12,"Azeitona, verde, conserva" 523 | 522,12,"Chantilly, spray, com gordura vegetal" 524 | 523,12,"Leite, de coco" 525 | 524,12,"Maionese, tradicional com ovos" 526 | 525,13,Acarajé 527 | 526,13,Arroz carreteiro 528 | 527,13,"Baião de dois, arroz e feijão-de-corda" 529 | 528,13,Barreado 530 | 529,13,"Bife à cavalo, com contra filé" 531 | 530,13,Bolinho de arroz 532 | 531,13,Camarão à baiana 533 | 532,13,"Charuto, de repolho" 534 | 533,13,"Cuscuz, de milho, cozido com sal" 535 | 534,13,"Cuscuz, paulista" 536 | 535,13,"Cuxá, molho" 537 | 536,13,Dobradinha 538 | 537,13,Estrogonofe de carne 539 | 538,13,Estrogonofe de frango 540 | 539,13,Feijão tropeiro mineiro 541 | 540,13,Feijoada 542 | 541,13,"Frango, com açafrão" 543 | 542,13,"Macarrão, molho bolognesa" 544 | 543,13,Maniçoba 545 | 544,13,Quibebe 546 | 545,13,"Salada, de legumes, com maionese" 547 | 546,13,"Salada, de legumes, cozida no vapor" 548 | 547,13,"Salpicão, de frango" 549 | 548,13,Sarapatel 550 | 549,13,Tabule 551 | 550,13,Tacacá 552 | 551,13,"Tapioca, com manteiga" 553 | 552,13,"Tucupi, com pimenta-de-cheiro" 554 | 553,13,Vaca atolada 555 | 554,13,Vatapá 556 | 555,13,Virado à paulista 557 | 556,13,Yakisoba 558 | 557,14,"Amendoim, grão, cru" 559 | 558,14,"Amendoim, torrado, salgado" 560 | 559,14,"Ervilha, em vagem" 561 | 560,14,"Ervilha, enlatada, drenada" 562 | 561,14,"Feijão, carioca, cozido" 563 | 562,14,"Feijão, carioca, cru" 564 | 563,14,"Feijão, fradinho, cozido" 565 | 564,14,"Feijão, fradinho, cru" 566 | 565,14,"Feijão, jalo, cozido" 567 | 566,14,"Feijão, jalo, cru" 568 | 567,14,"Feijão, preto, cozido" 569 | 568,14,"Feijão, preto, cru" 570 | 569,14,"Feijão, rajado, cozido" 571 | 570,14,"Feijão, rajado, cru" 572 | 571,14,"Feijão, rosinha, cozido" 573 | 572,14,"Feijão, rosinha, cru" 574 | 573,14,"Feijão, roxo, cozido" 575 | 574,14,"Feijão, roxo, cru" 576 | 575,14,"Grão-de-bico, cru" 577 | 576,14,"Guandu, cru" 578 | 577,14,"Lentilha, cozida" 579 | 578,14,"Lentilha, crua" 580 | 579,14,"Paçoca, amendoim" 581 | 580,14,"Pé-de-moleque, amendoim" 582 | 581,14,"Soja, farinha" 583 | 582,14,"Soja, extrato solúvel, natural, fluido" 584 | 583,14,"Soja, extrato solúvel, pó" 585 | 584,14,"Soja, queijo (tofu)" 586 | 585,14,"Tremoço, cru" 587 | 586,14,"Tremoço, em conserva" 588 | 587,15,"Amêndoa, torrada, salgada" 589 | 588,15,"Castanha-de-caju, torrada, salgada" 590 | 589,15,"Castanha-do-Brasil, crua" 591 | 590,15,"Coco, cru" 592 | 591,15,"Coco, verde, cru" 593 | 592,15,"Farinha, de mesocarpo de babaçu, crua" 594 | 593,15,"Gergelim, semente" 595 | 594,15,"Linhaça, semente" 596 | 595,15,"Pinhão, cozido" 597 | 596,15,"Pupunha, cozida" 598 | 597,15,"Noz, crua" -------------------------------------------------------------------------------- /references/normalization/taco_phase_1_no_format.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raulfdm/taco-api/06e466ad2f3d76064b587808b1804564b2c40f67/references/normalization/taco_phase_1_no_format.xlsx -------------------------------------------------------------------------------- /references/normalization/taco_phase_2_normalize_values.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raulfdm/taco-api/06e466ad2f3d76064b587808b1804564b2c40f67/references/normalization/taco_phase_2_normalize_values.xlsx -------------------------------------------------------------------------------- /references/normalization/taco_phase_3_rename_labels.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raulfdm/taco-api/06e466ad2f3d76064b587808b1804564b2c40f67/references/normalization/taco_phase_3_rename_labels.xlsx -------------------------------------------------------------------------------- /references/normalization/taco_phase_4_decouple_category.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raulfdm/taco-api/06e466ad2f3d76064b587808b1804564b2c40f67/references/normalization/taco_phase_4_decouple_category.xlsx -------------------------------------------------------------------------------- /references/normalization/taco_phase_5_decouple_food.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raulfdm/taco-api/06e466ad2f3d76064b587808b1804564b2c40f67/references/normalization/taco_phase_5_decouple_food.xlsx -------------------------------------------------------------------------------- /references/original-Taco_4a_edicao_2011.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raulfdm/taco-api/06e466ad2f3d76064b587808b1804564b2c40f67/references/original-Taco_4a_edicao_2011.xls -------------------------------------------------------------------------------- /references/taco_4_edicao_ampliada_e_revisada.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/raulfdm/taco-api/06e466ad2f3d76064b587808b1804564b2c40f67/references/taco_4_edicao_ampliada_e_revisada.pdf -------------------------------------------------------------------------------- /scripts/build-image.ts: -------------------------------------------------------------------------------- 1 | import minimist from "minimist"; 2 | import { version } from "../apps/api/package.json"; 3 | 4 | const args = minimist<{ deploy?: boolean; build?: boolean }>(Bun.argv); 5 | 6 | const tagVersion = `raulfdm/taco-api:v${version}`; 7 | const latestVersion = "raulfdm/taco-api:latest"; 8 | 9 | console.log("Building..."); 10 | 11 | Bun.spawnSync( 12 | [ 13 | "docker", 14 | "build", 15 | "-f", 16 | "./apps/api/Dockerfile", 17 | "-t", 18 | tagVersion, 19 | "-t", 20 | latestVersion, 21 | ".", 22 | ], 23 | { 24 | stdio: ["inherit", "inherit", "inherit"], 25 | }, 26 | ); 27 | 28 | if (args.deploy) { 29 | console.log("Deploying..."); 30 | Bun.spawnSync(["docker", "push", latestVersion]); 31 | Bun.spawnSync(["docker", "push", tagVersion]); 32 | } else { 33 | console.log("Skipping deploy..."); 34 | } 35 | -------------------------------------------------------------------------------- /scripts/fix-graphql-types.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * This hack only exists until the types is fixed in graphql-modules: 3 | * @see https://github.com/Urigo/graphql-modules/issues/2480 4 | * @see https://github.com/Urigo/graphql-modules/pull/2481 5 | */ 6 | import path from "path"; 7 | 8 | const BASE_PATH = path.resolve( 9 | import.meta.dir, 10 | "../node_modules/graphql-modules", 11 | ); 12 | 13 | const GRAPHQL_MODULES_PKG_JSON_PATH = `${BASE_PATH}/package.json`; 14 | 15 | const graphqlModulesPkgJson = Bun.file(GRAPHQL_MODULES_PKG_JSON_PATH); 16 | 17 | const jsonContent = await graphqlModulesPkgJson.json(); 18 | 19 | jsonContent.exports["."].types = `./${jsonContent.typings}`; 20 | jsonContent.exports["./*"].types = "./*.d.ts"; 21 | 22 | Bun.write(GRAPHQL_MODULES_PKG_JSON_PATH, JSON.stringify(jsonContent, null, 2)); 23 | 24 | console.log("`graphql-modules` types fixed!"); 25 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "lib": [ 4 | "ESNext" 5 | ], 6 | "module": "esnext", 7 | "target": "esnext", 8 | "moduleResolution": "bundler", 9 | "moduleDetection": "force", 10 | "allowImportingTsExtensions": true, 11 | "noEmit": true, 12 | "composite": true, 13 | "strict": true, 14 | "downlevelIteration": true, 15 | "skipLibCheck": true, 16 | "jsx": "react-jsx", 17 | "allowSyntheticDefaultImports": true, 18 | "forceConsistentCasingInFileNames": true, 19 | "allowJs": true 20 | } 21 | } -------------------------------------------------------------------------------- /turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "./node_modules/turbo/schema.json", 3 | "tasks": { 4 | "build": { 5 | "dependsOn": ["db:generate"], 6 | "outputs": ["dist/**"], 7 | "env": ["NODE_ENV=production"] 8 | }, 9 | "db:generate": {}, 10 | "dev": { 11 | "dependsOn": ["db:generate"], 12 | "env": ["NODE_ENV=development"] 13 | }, 14 | "lint": {}, 15 | "lint:ci": {}, 16 | "start": { 17 | "dependsOn": ["build"] 18 | } 19 | } 20 | } 21 | --------------------------------------------------------------------------------