zhichyu commited on
Commit
59ca130
·
1 Parent(s): 96edfc5

Rework Dockerfile.scratch (#2525)

Browse files

### What problem does this PR solve?

Rework Dockerfile.scratch
- Multiple stage Dockerfile
- Removed conda
- Replaced pip with poetry
- Added missing dependencies and fixed package version conflicts
- Added deepdoc models

### Type of change

- [x] Refactoring
- [ ] Performance Improvement
- [ ] Other (please describe):

Dockerfile.scratch CHANGED
@@ -1,56 +1,91 @@
1
- FROM ubuntu:22.04
 
2
  USER root
3
 
4
  WORKDIR /ragflow
5
 
6
- RUN apt-get update && apt-get install -y wget curl build-essential libopenmpi-dev
 
7
 
8
- RUN wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O ~/miniconda.sh && \
9
- bash ~/miniconda.sh -b -p /root/miniconda3 && \
10
- rm ~/miniconda.sh && ln -s /root/miniconda3/etc/profile.d/conda.sh /etc/profile.d/conda.sh && \
11
- echo ". /root/miniconda3/etc/profile.d/conda.sh" >> ~/.bashrc && \
12
- echo "conda activate base" >> ~/.bashrc
13
 
14
- ENV PATH /root/miniconda3/bin:$PATH
 
15
 
16
- RUN conda create -y --name py11 python=3.11
 
 
 
17
 
18
- ENV CONDA_DEFAULT_ENV py11
19
- ENV CONDA_PREFIX /root/miniconda3/envs/py11
20
- ENV PATH $CONDA_PREFIX/bin:$PATH
21
 
22
- RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -
23
- RUN apt-get install -y nodejs
 
 
 
24
 
25
- RUN apt-get install -y nginx
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
- ADD ./web ./web
28
- ADD ./api ./api
29
- ADD ./conf ./conf
30
- ADD ./deepdoc ./deepdoc
31
- ADD ./rag ./rag
32
- ADD ./requirements.txt ./requirements.txt
33
- ADD ./agent ./agent
34
- ADD ./graphrag ./graphrag
35
 
36
- RUN apt install openmpi-bin openmpi-common libopenmpi-dev
37
- ENV LD_LIBRARY_PATH /usr/lib/x86_64-linux-gnu/openmpi/lib:$LD_LIBRARY_PATH
38
- RUN rm /root/miniconda3/envs/py11/compiler_compat/ld
39
- RUN cd ./web && npm i --force && npm run build
40
- RUN conda run -n py11 pip install -i https://mirrors.aliyun.com/pypi/simple/ -r ./requirements.txt
41
 
42
- RUN apt-get update && \
43
- apt-get install -y libglib2.0-0 libgl1-mesa-glx && \
 
 
44
  rm -rf /var/lib/apt/lists/*
45
 
46
- RUN conda run -n py11 pip install -i https://mirrors.aliyun.com/pypi/simple/ ollama
47
- RUN conda run -n py11 python -m nltk.downloader punkt
48
- RUN conda run -n py11 python -m nltk.downloader wordnet
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
  ENV PYTHONPATH=/ragflow/
51
- ENV HF_ENDPOINT=https://hf-mirror.com
52
 
53
- ADD docker/entrypoint.sh ./entrypoint.sh
54
  RUN chmod +x ./entrypoint.sh
55
 
56
  ENTRYPOINT ["./entrypoint.sh"]
 
1
+ # base stage
2
+ FROM ubuntu:24.04 AS base
3
  USER root
4
 
5
  WORKDIR /ragflow
6
 
7
+ RUN rm -f /etc/apt/apt.conf.d/docker-clean \
8
+ && echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache
9
 
10
+ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
11
+ apt update && apt-get --no-install-recommends install -y ca-certificates
 
 
 
12
 
13
+ # if you located in China, you can use tsinghua mirror to speed up apt
14
+ RUN sed -i 's|http://archive.ubuntu.com|https://mirrors.tuna.tsinghua.edu.cn|g' /etc/apt/sources.list.d/ubuntu.sources
15
 
16
+ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
17
+ apt update && apt install -y curl libpython3-dev nginx openmpi-bin openmpi-common libopenmpi-dev libglib2.0-0 libglx-mesa0 \
18
+ && rm -rf /var/lib/apt/lists/* \
19
+ && curl -sSL https://install.python-poetry.org | python3 -
20
 
21
+ ENV PYTHONDONTWRITEBYTECODE=1 LD_LIBRARY_PATH=usr/lib/x86_64-linux-gnu/openmpi/lib:$LD_LIBRARY_PATH
 
 
22
 
23
+ # Configure Poetry
24
+ ENV POETRY_NO_INTERACTION=1
25
+ ENV POETRY_VIRTUALENVS_IN_PROJECT=true
26
+ ENV POETRY_VIRTUALENVS_CREATE=true
27
+ ENV POETRY_REQUESTS_TIMEOUT=15
28
 
29
+ # builder stage
30
+ FROM base AS builder
31
+ USER root
32
+
33
+ WORKDIR /ragflow
34
+
35
+ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
36
+ apt update && apt install -y nodejs npm && \
37
+ rm -rf /var/lib/apt/lists/*
38
+
39
+ # if you located in China, you can use taobao registry to speed up npm and yarn
40
+ RUN npm config set registry https://registry.npmmirror.com/
41
+
42
+ # https://yarnpkg.com/getting-started/install
43
+ COPY web web
44
+ RUN cd web && npm install -g corepack && corepack enable && yarn install && yarn run build
45
 
46
+ # install dependencies from poetry.lock file
47
+ COPY pyproject.toml poetry.toml poetry.lock ./
48
+ RUN --mount=type=cache,target=/root/.cache/pypoetry,sharing=locked \
49
+ /root/.local/bin/poetry install --sync --no-cache --no-root
 
 
 
 
50
 
51
+ # production stage
52
+ FROM base AS production
53
+ USER root
54
+
55
+ WORKDIR /ragflow
56
 
57
+ # Install python packages' dependencies
58
+ # cv2 requires libGL.so.1
59
+ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
60
+ apt update && apt install -y --no-install-recommends nginx libgl1 vim less && \
61
  rm -rf /var/lib/apt/lists/*
62
 
63
+ COPY web web
64
+ COPY api api
65
+ COPY conf conf
66
+ COPY deepdoc deepdoc
67
+ COPY rag rag
68
+ COPY agent agent
69
+ COPY graphrag graphrag
70
+ COPY pyproject.toml poetry.toml poetry.lock ./
71
+
72
+ # Copy compiled web pages
73
+ COPY --from=builder /ragflow/web/dist /ragflow/web/dist
74
+
75
+ # Copy Python environment and packages
76
+ ENV VIRTUAL_ENV=/ragflow/.venv
77
+ COPY --from=builder ${VIRTUAL_ENV} ${VIRTUAL_ENV}
78
+ ENV PATH="${VIRTUAL_ENV}/bin:/root/.local/bin:${PATH}"
79
+
80
+ # Download nltk data
81
+ RUN python3 -m nltk.downloader wordnet punkt punkt_tab
82
+
83
+ # Copy models downloaded via download_deps.sh
84
+ COPY det.onnx layout.laws.onnx layout.manual.onnx layout.onnx layout.paper.onnx ocr.res rec.onnx tsr.onnx updown_concat_xgb.model /ragflow/rag/res/deepdoc/
85
 
86
  ENV PYTHONPATH=/ragflow/
 
87
 
88
+ COPY docker/entrypoint.sh ./entrypoint.sh
89
  RUN chmod +x ./entrypoint.sh
90
 
91
  ENTRYPOINT ["./entrypoint.sh"]
api/ragflow_server.py CHANGED
@@ -46,7 +46,7 @@ def update_progress():
46
 
47
 
48
  if __name__ == '__main__':
49
- print("""
50
  ____ ______ __
51
  / __ \ ____ _ ____ _ / ____// /____ _ __
52
  / /_/ // __ `// __ `// /_ / // __ \| | /| / /
 
46
 
47
 
48
  if __name__ == '__main__':
49
+ print(r"""
50
  ____ ______ __
51
  / __ \ ____ _ ____ _ / ____// /____ _ __
52
  / /_/ // __ `// __ `// /_ / // __ \| | /| / /
docker/.env CHANGED
@@ -33,10 +33,13 @@ REDIS_PASSWORD=infini_rag_flow
33
 
34
  SVR_HTTP_PORT=9380
35
 
36
- RAGFLOW_VERSION=dev
37
 
38
  TIMEZONE='Asia/Shanghai'
39
 
 
 
 
40
  ######## OS setup for ES ###########
41
  # sysctl vm.max_map_count
42
  # sudo sysctl -w vm.max_map_count=262144
 
33
 
34
  SVR_HTTP_PORT=9380
35
 
36
+ RAGFLOW_VERSION=poetry
37
 
38
  TIMEZONE='Asia/Shanghai'
39
 
40
+ # Inside GFW, we need the following huggingface.co mirror:
41
+ HF_ENDPOINT=https://hf-mirror.com
42
+
43
  ######## OS setup for ES ###########
44
  # sysctl vm.max_map_count
45
  # sudo sysctl -w vm.max_map_count=262144
docker/docker-compose.yml CHANGED
@@ -15,6 +15,7 @@ services:
15
  - ${SVR_HTTP_PORT}:9380
16
  - 80:80
17
  - 443:443
 
18
  volumes:
19
  - ./service_conf.yaml:/ragflow/conf/service_conf.yaml
20
  - ./ragflow-logs:/ragflow/logs
@@ -23,7 +24,7 @@ services:
23
  - ./nginx/nginx.conf:/etc/nginx/nginx.conf
24
  environment:
25
  - TZ=${TIMEZONE}
26
- - HF_ENDPOINT=https://huggingface.co
27
  - MACOS=${MACOS}
28
  networks:
29
  - ragflow
 
15
  - ${SVR_HTTP_PORT}:9380
16
  - 80:80
17
  - 443:443
18
+ - 5678:5678
19
  volumes:
20
  - ./service_conf.yaml:/ragflow/conf/service_conf.yaml
21
  - ./ragflow-logs:/ragflow/logs
 
24
  - ./nginx/nginx.conf:/etc/nginx/nginx.conf
25
  environment:
26
  - TZ=${TIMEZONE}
27
+ - HF_ENDPOINT=${HF_ENDPOINT}
28
  - MACOS=${MACOS}
29
  networks:
30
  - ragflow
download_deps.sh ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env bash
2
+
3
+ download()
4
+ {
5
+ echo "download $1"
6
+ # https://stackoverflow.com/questions/3162385/how-to-split-a-string-in-shell-and-get-the-last-field
7
+ fn=${1##*/}
8
+ if [ ! -f $fn ] ; then
9
+ wget --no-check-certificate $1
10
+ fi
11
+ }
12
+
13
+ # https://stackoverflow.com/questions/24628076/convert-multiline-string-to-array
14
+ names="https://huggingface.co/InfiniFlow/deepdoc/resolve/main/det.onnx
15
+ https://huggingface.co/InfiniFlow/deepdoc/resolve/main/layout.laws.onnx
16
+ https://huggingface.co/InfiniFlow/deepdoc/resolve/main/layout.manual.onnx
17
+ https://huggingface.co/InfiniFlow/deepdoc/resolve/main/layout.onnx
18
+ https://huggingface.co/InfiniFlow/deepdoc/resolve/main/layout.paper.onnx
19
+ https://huggingface.co/InfiniFlow/deepdoc/resolve/main/ocr.res
20
+ https://huggingface.co/InfiniFlow/deepdoc/resolve/main/rec.onnx
21
+ https://huggingface.co/InfiniFlow/deepdoc/resolve/main/tsr.onnx
22
+ https://huggingface.co/InfiniFlow/text_concat_xgb_v1.0/resolve/main/updown_concat_xgb.model"
23
+
24
+ SAVEIFS=$IFS # Save current IFS (Internal Field Separator)
25
+ IFS=$'\n' # Change IFS to newline char
26
+ names=($names) # split the `names` string into an array by the same name
27
+ IFS=$SAVEIFS # Restore original IFS
28
+
29
+ find . -size 0 | xargs rm -f
30
+ # https://stackoverflow.com/questions/15466808/shell-iterate-over-array
31
+ for ((i=0; i<${#names[@]}; i+=1)); do
32
+ url="${names[$i]}"
33
+ download $url
34
+ if [ $? != 0 ]; then
35
+ exit -1
36
+ fi
37
+ done
38
+ find . -size 0 | xargs rm -f
poetry.lock ADDED
The diff for this file is too large to render. See raw diff
 
poetry.toml ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ [virtualenvs]
2
+ in-project = true
3
+ create = true
4
+ prefer-active-python = true
pyproject.toml ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [tool.poetry]
2
+ name = "ragflow"
3
+ version = "0.11.0"
4
+ description = "[RAGFlow](https://ragflow.io/) is an open-source RAG (Retrieval-Augmented Generation) engine based on deep document understanding. It offers a streamlined RAG workflow for businesses of any scale, combining LLM (Large Language Models) to provide truthful question-answering capabilities, backed by well-founded citations from various complex formatted data."
5
+ authors = ["Your Name <[email protected]>"]
6
+ license = "https://github.com/infiniflow/ragflow/blob/main/LICENSE"
7
+ readme = "README.md"
8
+ package-mode = false
9
+
10
+ [tool.poetry.dependencies]
11
+ python = ">=3.12,<3.13"
12
+ datrie = "0.8.2"
13
+ akshare = "1.14.72"
14
+ azure-storage-blob = "12.22.0"
15
+ azure-identity = "1.17.1"
16
+ azure-storage-file-datalake = "12.16.0"
17
+ anthropic = "=0.34.1"
18
+ arxiv = "2.1.3"
19
+ aspose-slides = "24.8.0"
20
+ bcembedding = "0.1.3"
21
+ bio = "1.7.1"
22
+ boto3 = "1.34.140"
23
+ botocore = "1.34.140"
24
+ cachetools = "5.3.3"
25
+ chardet = "5.2.0"
26
+ cn2an = "0.5.22"
27
+ cohere = "5.6.2"
28
+ dashscope = "1.14.1"
29
+ deepl = "1.18.0"
30
+ demjson3 = "3.0.6"
31
+ discord-py = "2.3.2"
32
+ duckduckgo-search = "6.1.9"
33
+ editdistance = "0.8.1"
34
+ elastic-transport = "8.12.0"
35
+ elasticsearch = "8.12.1"
36
+ elasticsearch-dsl = "8.12.0"
37
+ fastembed = "^0.3.6"
38
+ fasttext = "0.9.3"
39
+ filelock = "3.15.4"
40
+ flagembedding = "1.2.10"
41
+ flask = "3.0.3"
42
+ flask-cors = "5.0.0"
43
+ flask-login = "0.6.3"
44
+ flask-session = "0.8.0"
45
+ google-search-results = "2.4.2"
46
+ groq = "0.9.0"
47
+ hanziconv = "0.3.2"
48
+ html-text = "0.6.2"
49
+ httpx = "0.27.0"
50
+ huggingface-hub = "^0.25.0"
51
+ infinity-emb = "0.0.51"
52
+ itsdangerous = "2.1.2"
53
+ markdown = "3.6"
54
+ markdown-to-json = "2.1.1"
55
+ minio = "7.2.4"
56
+ mistralai = "0.4.2"
57
+ nltk = "3.9.1"
58
+ numpy = "1.26.4"
59
+ ollama = "0.2.1"
60
+ onnxruntime = "1.17.3"
61
+ onnxruntime-gpu = "1.17.1"
62
+ openai = "1.12.0"
63
+ opencv-python = "4.9.0.80"
64
+ opencv-python-headless = "4.9.0.80"
65
+ openpyxl = "3.1.2"
66
+ ormsgpack = "1.5.0"
67
+ pandas = "2.2.2"
68
+ pdfplumber = "0.10.4"
69
+ peewee = "3.17.1"
70
+ pillow = "10.3.0"
71
+ protobuf = "5.27.2"
72
+ psycopg2-binary = "2.9.9"
73
+ pyclipper = "1.3.0.post5"
74
+ pycryptodomex = "3.20.0"
75
+ pypdf = "^5.0.0"
76
+ pytest = "8.2.2"
77
+ python-dotenv = "1.0.1"
78
+ python-dateutil = "2.8.2"
79
+ python-pptx = "0.6.23"
80
+ pywencai = "0.12.2"
81
+ qianfan = "0.4.6"
82
+ ranx = "0.3.20"
83
+ readability-lxml = "0.8.1"
84
+ redis = "5.0.3"
85
+ requests = "2.32.2"
86
+ replicate = "0.31.0"
87
+ roman-numbers = "1.0.2"
88
+ ruamel-base = "1.0.0"
89
+ scholarly = "1.7.11"
90
+ scikit-learn = "1.5.0"
91
+ selenium = "4.22.0"
92
+ setuptools = "70.0.0"
93
+ shapely = "2.0.5"
94
+ six = "1.16.0"
95
+ strenum = "0.4.15"
96
+ tabulate = "0.9.0"
97
+ tencentcloud-sdk-python = "3.0.1215"
98
+ tika = "2.6.0"
99
+ tiktoken = "0.6.0"
100
+ torch = "2.3.0"
101
+ transformers = "4.38.1"
102
+ umap = "0.1.1"
103
+ vertexai = "1.64.0"
104
+ volcengine = "1.0.146"
105
+ voyageai = "0.2.3"
106
+ webdriver-manager = "4.0.1"
107
+ werkzeug = "3.0.3"
108
+ wikipedia = "1.4.0"
109
+ word2number = "1.1"
110
+ xgboost = "2.1.0"
111
+ xpinyin = "0.7.6"
112
+ yfinance = "0.1.96"
113
+ zhipuai = "2.0.1"
114
+ ruamel-yaml = "^0.18.6"
115
+ google-generativeai = "^0.8.1"
116
+ python-docx = "^1.1.2"
117
+ pypdf2 = "^3.0.1"
118
+ graspologic = "^3.4.1"
119
+ pymysql = "^1.1.1"
120
+
121
+
122
+ [[tool.poetry.source]]
123
+ name = "tsinghua"
124
+ url = "https://pypi.tuna.tsinghua.edu.cn/simple/"
125
+ priority = "primary"
126
+
127
+ [build-system]
128
+ requires = ["poetry-core"]
129
+ build-backend = "poetry.core.masonry.api"
requirements.txt CHANGED
@@ -4,7 +4,7 @@ azure-identity==1.17.1
4
  azure-storage-file-datalake==12.16.0
5
  anthropic===0.34.1
6
  arxiv==2.1.3
7
- Aspose.Slides==24.2.0
8
  BCEmbedding==0.1.3
9
  Bio==1.7.1
10
  boto3==1.34.140
@@ -43,7 +43,7 @@ Markdown==3.6
43
  markdown_to_json==2.1.1
44
  minio==7.2.4
45
  mistralai==0.4.2
46
- nltk==3.9
47
  numpy==1.26.4
48
  ollama==0.2.1
49
  onnxruntime==1.17.3
@@ -57,7 +57,6 @@ pandas==2.2.2
57
  pdfplumber==0.10.4
58
  peewee==3.17.1
59
  Pillow==10.3.0
60
- pipreqs==0.5.0
61
  protobuf==5.27.2
62
  psycopg2-binary==2.9.9
63
  pyclipper==1.3.0.post5
 
4
  azure-storage-file-datalake==12.16.0
5
  anthropic===0.34.1
6
  arxiv==2.1.3
7
+ Aspose.Slides==24.8.0
8
  BCEmbedding==0.1.3
9
  Bio==1.7.1
10
  boto3==1.34.140
 
43
  markdown_to_json==2.1.1
44
  minio==7.2.4
45
  mistralai==0.4.2
46
+ nltk==3.9.1
47
  numpy==1.26.4
48
  ollama==0.2.1
49
  onnxruntime==1.17.3
 
57
  pdfplumber==0.10.4
58
  peewee==3.17.1
59
  Pillow==10.3.0
 
60
  protobuf==5.27.2
61
  psycopg2-binary==2.9.9
62
  pyclipper==1.3.0.post5
ubuntu.sources ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Types: deb
2
+ URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu
3
+ Suites: noble noble-updates noble-backports
4
+ Components: main restricted universe multiverse
5
+ Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
6
+
7
+ # 默认注释了源码镜像以提高 apt update 速度,如有需要可自行取消注释
8
+ # Types: deb-src
9
+ # URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu
10
+ # Suites: noble noble-updates noble-backports
11
+ # Components: main restricted universe multiverse
12
+ # Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
13
+
14
+ # 以下安全更新软件源包含了官方源与镜像站配置,如有需要可自行修改注释切换
15
+ Types: deb
16
+ URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu
17
+ Suites: noble-security
18
+ Components: main restricted universe multiverse
19
+ Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
20
+
21
+ # Types: deb-src
22
+ # URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu
23
+ # Suites: noble-security
24
+ # Components: main restricted universe multiverse
25
+ # Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
26
+
27
+ # 预发布软件源,不建议启用
28
+
29
+ # Types: deb
30
+ # URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu
31
+ # Suites: noble-proposed
32
+ # Components: main restricted universe multiverse
33
+ # Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
34
+
35
+ # # Types: deb-src
36
+ # # URIs: https://mirrors.tuna.tsinghua.edu.cn/ubuntu
37
+ # # Suites: noble-proposed
38
+ # # Components: main restricted universe multiverse
39
+ # # Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg
web/package-lock.json DELETED
The diff for this file is too large to render. See raw diff
 
web/package.json CHANGED
@@ -8,7 +8,7 @@
8
  "lint": "umi lint --eslint-only",
9
  "prepare": "cd .. && husky web/.husky",
10
  "setup": "umi setup",
11
- "start": "npm run dev",
12
  "test": "jest --no-cache --coverage"
13
  },
14
  "lint-staged": {
 
8
  "lint": "umi lint --eslint-only",
9
  "prepare": "cd .. && husky web/.husky",
10
  "setup": "umi setup",
11
+ "start": "yarn dev",
12
  "test": "jest --no-cache --coverage"
13
  },
14
  "lint-staged": {
web/yarn.lock ADDED
The diff for this file is too large to render. See raw diff