├── .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 | 
6 |
7 |
8 |
9 |
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 | [](https://starlight.astro.build)
4 |
5 | ```
6 | npm create astro@latest -- --template starlight
7 | ```
8 |
9 | [](https://stackblitz.com/github/withastro/starlight/tree/main/examples/basics)
10 | [](https://codesandbox.io/p/sandbox/github/withastro/starlight/tree/main/examples/basics)
11 | [](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 | 
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 | 
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 |
--------------------------------------------------------------------------------