fifadotjs commited on
Commit
6a0e7a0
·
1 Parent(s): cb54b7a

Upload 7 files

Browse files
Files changed (7) hide show
  1. .gitignore +160 -0
  2. README.md +2 -13
  3. TEEOR.png +0 -0
  4. aib_logo.png +0 -0
  5. app.py +166 -0
  6. requirements.txt +141 -0
  7. style.css +8 -0
.gitignore ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # poetry
98
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
102
+ #poetry.lock
103
+
104
+ # pdm
105
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
106
+ #pdm.lock
107
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
108
+ # in version control.
109
+ # https://pdm.fming.dev/#use-with-ide
110
+ .pdm.toml
111
+
112
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
113
+ __pypackages__/
114
+
115
+ # Celery stuff
116
+ celerybeat-schedule
117
+ celerybeat.pid
118
+
119
+ # SageMath parsed files
120
+ *.sage.py
121
+
122
+ # Environments
123
+ .env
124
+ .venv
125
+ env/
126
+ venv/
127
+ ENV/
128
+ env.bak/
129
+ venv.bak/
130
+
131
+ # Spyder project settings
132
+ .spyderproject
133
+ .spyproject
134
+
135
+ # Rope project settings
136
+ .ropeproject
137
+
138
+ # mkdocs documentation
139
+ /site
140
+
141
+ # mypy
142
+ .mypy_cache/
143
+ .dmypy.json
144
+ dmypy.json
145
+
146
+ # Pyre type checker
147
+ .pyre/
148
+
149
+ # pytype static type analyzer
150
+ .pytype/
151
+
152
+ # Cython debug symbols
153
+ cython_debug/
154
+
155
+ # PyCharm
156
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
157
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
158
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
159
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
160
+ #.idea/
README.md CHANGED
@@ -1,13 +1,2 @@
1
- ---
2
- title: TEEOR AI BUILDER
3
- emoji: 📈
4
- colorFrom: green
5
- colorTo: pink
6
- sdk: streamlit
7
- sdk_version: 1.21.0
8
- app_file: app.py
9
- pinned: false
10
- license: mit
11
- ---
12
-
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
+ # -AIB3-Deployment--Checker-Tool-for-procurement-books
2
+ TEEOR (Deployment for Checker Tool for procurement books)
 
 
 
 
 
 
 
 
 
 
 
TEEOR.png ADDED
aib_logo.png ADDED
app.py ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ from PIL import Image
3
+ import numpy as np
4
+ from streamlit_cropper import st_cropper
5
+ from tesserocr import PyTessBaseAPI
6
+ from annotated_text import annotated_text
7
+ from simpletransformers.ner import NERModel
8
+
9
+ # Function to resize the image based on desired DPI
10
+ def resize_image(image, desired_dpi):
11
+ # Calculate the current DPI
12
+ current_dpi = image.info.get('dpi', (72, 72))
13
+
14
+ # Calculate the scale factor based on the desired and current DPI
15
+ scale_factor = desired_dpi / current_dpi[0]
16
+
17
+ # Resize the image based on the scale factor
18
+ new_size = (int(image.width * scale_factor), int(image.height * scale_factor))
19
+ resized_image = image.resize(new_size)
20
+
21
+ return resized_image
22
+
23
+ # Function to perform OCR on the image
24
+ def perform_ocr(image):
25
+ with PyTessBaseAPI(path=r'model', lang="tha") as api:
26
+ api.SetVariable('preserve_interword_spaces', '1')
27
+
28
+ im_gray = image.convert("L")
29
+ cropped_img_bytes = im_gray.tobytes() # Convert grayscale image to bytes
30
+ api.SetImage(Image.frombytes('L', im_gray.size, cropped_img_bytes)) # Set the image from bytes
31
+
32
+ extracted_text = api.GetUTF8Text()
33
+
34
+ return extracted_text
35
+
36
+ # Main function
37
+ def main():
38
+
39
+
40
+ st.info('''
41
+ การใช้งาน
42
+ กรอกลักษณะของครุภัณฑ์ที่ต้องการตรวจสอบ โดยในขณะนี้รองรับเฉพาะ เครื่องปรับอากาศเเบบเเยกส่วน ตู้เหล็ก เครื่องทำลายเอกสาร เครื่องถ่ายเอกสารระบบดิจิตอล 1.) เลือกไฟล์รูป 2.) Crop ส่วนที่ต้องการตรวจสอบ 3.) ตรวจสอบข้อความ 4.) กดปุ่มตรวจสอบ
43
+ ''', icon="ℹ️")
44
+
45
+
46
+ st.set_option('deprecation.showfileUploaderEncoding', False)
47
+
48
+ img_file = st.sidebar.file_uploader(label='Upload a file', type=['png', 'jpg'])
49
+ if img_file:
50
+ st.write("Crop ส่วนที่ต้องการ (คุณลักษณะ)")
51
+ aspect_ratio = None
52
+
53
+ col1, col2 = st.sidebar.columns(2)
54
+ with col1:
55
+ box_color = st.color_picker(label="Box Color", value='#0000FF')
56
+ return_type = "image"
57
+ realtime_update = st.sidebar.checkbox(label="Update in Real Time", value=True)
58
+
59
+ img = Image.open(img_file)
60
+ width, height = img.size
61
+
62
+ if not realtime_update:
63
+ st.write("Double click to save crop")
64
+
65
+ if return_type == 'box':
66
+ rect = st_cropper(
67
+ img,
68
+ realtime_update=realtime_update,
69
+ box_color=box_color,
70
+ aspect_ratio=aspect_ratio,
71
+ return_type=return_type
72
+ )
73
+ raw_image = np.asarray(img).astype('uint8')
74
+ left, top, width, height = tuple(map(int, rect.values()))
75
+ st.write(rect)
76
+ masked_image = np.zeros(raw_image.shape, dtype='uint8')
77
+ masked_image[top:top + height, left:left + width] = raw_image[top:top + height, left:left + width]
78
+ st.image(Image.fromarray(masked_image))
79
+ else:
80
+ # Get a cropped image from the frontend
81
+ cropped_img = st_cropper(
82
+ img,
83
+ realtime_update=realtime_update,
84
+ box_color=box_color,
85
+ aspect_ratio=aspect_ratio,
86
+ return_type=return_type
87
+ )
88
+
89
+ # Manipulate cropped image at will
90
+ st.write("Preview")
91
+ _ = cropped_img.thumbnail((1000, 1000))
92
+
93
+ desired_dpi = 300
94
+
95
+ # Resize the image
96
+ resized_image = resize_image(cropped_img, desired_dpi)
97
+
98
+ # Display the image
99
+ st.image(resized_image)
100
+ # Perform OCR
101
+ extracted_text = perform_ocr(resized_image)
102
+
103
+ # Display extracted text
104
+ txt_input = st.text_area("โปรดตรวจสอบความถูกต้อง", extracted_text)
105
+
106
+ word_output = ""
107
+ word_tuple = ()
108
+ check = st.button("Check",type="primary",use_container_width=True)
109
+ if check:
110
+ st.header("สรุปผล")
111
+ predictions, raw_outputs = model.predict([txt_input])
112
+ wrongword_lst = []
113
+
114
+ for i in predictions[0]:
115
+ word = i.values()
116
+ label = list(word)[0]
117
+ if label == "1":
118
+ wrong_word = list(i.keys())[0]
119
+ wrongword_lst.append(wrong_word)
120
+
121
+ word_tuple = ()
122
+ for i in predictions[0]:
123
+ label = i.values()
124
+ word = list(i.keys())[0]
125
+ label = list(label)[0]
126
+ if label == "1":
127
+ word_tuple = (*word_tuple, (f'{word} ', 'มีการล็อคสเปค', '#F41B15'))
128
+ else:
129
+ word_tuple = (*word_tuple, f'{word} ')
130
+ word_output = wrongword_lst
131
+
132
+ if word_output != "":
133
+ annotated_text(list(word_tuple))
134
+
135
+ col1, col2 = st.columns(2)
136
+ with col1:
137
+ st.header("คำที่สุ่มเสี่ยง")
138
+ st.write(word_output)
139
+
140
+
141
+ if __name__ == '__main__':
142
+ st.title("TEEOR")
143
+ teeor_logo = Image.open(r'TEEOR.png')
144
+ logo = st.sidebar.image(teeor_logo)
145
+ st.sidebar.write("[AI BUILDER 3] [ภัทรดนัย อัคราช สังกัด Arcane Whales] - ตรวจสอบการล็อคสเปคในหนังสือจัดซื้อจัดจ้าง (ครุภัณฑ์)")
146
+ genre = st.sidebar.radio(
147
+ "Hardware",
148
+ ('Cpu', 'Cuda (GPU)'))
149
+ if genre == 'Cuda':
150
+ Hardware_Type = True
151
+ elif genre == 'Cpu':
152
+ Hardware_Type = False
153
+ # Model initialization
154
+ _NER_TAGS = ['0', '1']
155
+ try:
156
+ model = NERModel(
157
+ model_name=r"model",
158
+ model_type="camembert",
159
+ labels=_NER_TAGS,
160
+ use_cuda=Hardware_Type
161
+ )
162
+ main()
163
+ except:
164
+ st.warning("Cuda not available, Please checking your hardware")
165
+ aib_logo = Image.open(r'aib_logo.png')
166
+ add_logo = st.sidebar.image(aib_logo)
requirements.txt ADDED
@@ -0,0 +1,141 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ absl-py==1.4.0
2
+ aiohttp==3.8.4
3
+ aiosignal==1.3.1
4
+ altair @ file:///tmp/build/80754af9/altair_1599835197802/work
5
+ appdirs==1.4.4
6
+ asttokens @ file:///opt/conda/conda-bld/asttokens_1646925590279/work
7
+ async-timeout==4.0.2
8
+ attrs @ file:///C:/ci_311/attrs_1676422272484/work
9
+ backcall @ file:///home/ktietz/src/ci/backcall_1611930011877/work
10
+ blinker==1.4
11
+ Bottleneck @ file:///C:/ci_311/bottleneck_1676500016583/work
12
+ brotlipy==0.7.0
13
+ cachetools @ file:///tmp/build/80754af9/cachetools_1619597386817/work
14
+ certifi==2023.5.7
15
+ cffi @ file:///C:/ci_311/cffi_1676423759166/work
16
+ charset-normalizer @ file:///tmp/build/80754af9/charset-normalizer_1630003229654/work
17
+ click @ file:///C:/ci_311/click_1676433091657/work
18
+ colorama @ file:///C:/ci_311/colorama_1676422310965/work
19
+ comm @ file:///C:/ci_311/comm_1678376562840/work
20
+ cryptography @ file:///C:/ci_311/cryptography_1679419210767/work
21
+ datasets==2.12.0
22
+ debugpy @ file:///C:/ci_311/debugpy_1676426137692/work
23
+ decorator @ file:///opt/conda/conda-bld/decorator_1643638310831/work
24
+ dill==0.3.6
25
+ docker-pycreds==0.4.0
26
+ entrypoints @ file:///C:/ci_311/entrypoints_1676423328987/work
27
+ executing @ file:///opt/conda/conda-bld/executing_1646925071911/work
28
+ filelock==3.12.0
29
+ frozenlist==1.3.3
30
+ fsspec==2023.5.0
31
+ gitdb @ file:///tmp/build/80754af9/gitdb_1617117951232/work
32
+ GitPython @ file:///C:/ci_311/gitpython_1677727002425/work
33
+ google-auth==2.19.0
34
+ google-auth-oauthlib==1.0.0
35
+ grpcio==1.54.2
36
+ htbuilder==0.6.1
37
+ huggingface-hub==0.14.1
38
+ idna @ file:///C:/ci_311/idna_1676424932545/work
39
+ importlib-metadata @ file:///C:/b/abs_20ndzb2j6v/croot/importlib-metadata_1678997085534/work
40
+ ipykernel @ file:///C:/ci_311/ipykernel_1678734799670/work
41
+ ipython @ file:///C:/b/abs_d1yx5tjhli/croot/ipython_1680701887259/work
42
+ ipywidgets @ file:///C:/b/abs_5awapknmz_/croot/ipywidgets_1679394824767/work
43
+ jedi @ file:///C:/ci_311/jedi_1679427407646/work
44
+ Jinja2 @ file:///C:/ci_311/jinja2_1676424968965/work
45
+ joblib==1.2.0
46
+ jsonschema @ file:///C:/b/abs_d40z05b6r1/croot/jsonschema_1678983446576/work
47
+ jupyter_client @ file:///C:/b/abs_059idvdagk/croot/jupyter_client_1680171872444/work
48
+ jupyter_core @ file:///C:/b/abs_9d0ttho3bs/croot/jupyter_core_1679906581955/work
49
+ jupyterlab-widgets @ file:///C:/b/abs_38ad427jkz/croot/jupyterlab_widgets_1679055289211/work
50
+ Markdown==3.4.3
51
+ markdown-it-py @ file:///C:/b/abs_a5bfngz6fu/croot/markdown-it-py_1684279915556/work
52
+ MarkupSafe @ file:///C:/ci_311/markupsafe_1676424152318/work
53
+ matplotlib-inline @ file:///C:/ci_311/matplotlib-inline_1676425798036/work
54
+ mdurl @ file:///C:/ci_311/mdurl_1676442676678/work
55
+ mkl-fft==1.3.6
56
+ mkl-random @ file:///C:/Users/dev-admin/mkl/mkl_random_1682977971003/work
57
+ mkl-service==2.4.0
58
+ more-itertools==9.1.0
59
+ mpmath==1.2.1
60
+ multidict==6.0.4
61
+ multiprocess==0.70.14
62
+ nest-asyncio @ file:///C:/ci_311/nest-asyncio_1676423519896/work
63
+ networkx @ file:///C:/b/abs_b935xy_9g6/croot/networkx_1678964342510/work
64
+ numexpr @ file:///C:/b/abs_afm0oewmmt/croot/numexpr_1683221839116/work
65
+ numpy @ file:///C:/Users/dev-admin/mkl/numpy_and_numpy_base_1682982345978/work
66
+ oauthlib==3.2.2
67
+ packaging @ file:///C:/b/abs_ed_kb9w6g4/croot/packaging_1678965418855/work
68
+ pandas @ file:///C:/ci_311_rebuilds/pandas_1679004481142/work
69
+ parso @ file:///opt/conda/conda-bld/parso_1641458642106/work
70
+ pathtools==0.1.2
71
+ pickleshare @ file:///tmp/build/80754af9/pickleshare_1606932040724/work
72
+ Pillow==9.4.0
73
+ platformdirs @ file:///C:/ci_311/platformdirs_1676422658103/work
74
+ prompt-toolkit @ file:///C:/ci_311/prompt-toolkit_1676425940920/work
75
+ protobuf==3.20.3
76
+ psutil @ file:///C:/ci_311_rebuilds/psutil_1679005906571/work
77
+ pure-eval @ file:///opt/conda/conda-bld/pure_eval_1646925070566/work
78
+ pyarrow==11.0.0
79
+ pyasn1==0.5.0
80
+ pyasn1-modules==0.3.0
81
+ pycparser @ file:///tmp/build/80754af9/pycparser_1636541352034/work
82
+ pydeck @ file:///C:/ci_311/pydeck_1678294245657/work
83
+ Pygments @ file:///C:/b/abs_fay9dpq4n_/croot/pygments_1684279990574/work
84
+ Pympler @ file:///tmp/build/80754af9/pympler_1602785470644/work
85
+ pyOpenSSL @ file:///C:/b/abs_de215ipd18/croot/pyopenssl_1678965319166/work
86
+ pyrsistent @ file:///C:/ci_311/pyrsistent_1676422695500/work
87
+ PySocks @ file:///C:/ci_311/pysocks_1676425991111/work
88
+ python-dateutil @ file:///tmp/build/80754af9/python-dateutil_1626374649649/work
89
+ pytz @ file:///C:/ci_311/pytz_1676427070848/work
90
+ pywin32==305.1
91
+ PyYAML @ file:///C:/ci_311/pyyaml_1676432488822/work
92
+ pyzmq @ file:///C:/b/abs_8b16zbmf46/croot/pyzmq_1682697651374/work
93
+ regex==2023.5.5
94
+ requests @ file:///C:/b/abs_41owkd5ymz/croot/requests_1682607524657/work
95
+ requests-oauthlib==1.3.1
96
+ responses==0.18.0
97
+ rich @ file:///C:/b/abs_09j2g5qnu8/croot/rich_1684282185530/work
98
+ rsa==4.9
99
+ scikit-learn==1.2.2
100
+ scipy==1.10.1
101
+ semver @ file:///tmp/build/80754af9/semver_1603822362442/work
102
+ sentencepiece==0.1.99
103
+ sentry-sdk==1.24.0
104
+ seqeval==1.2.2
105
+ setproctitle==1.3.2
106
+ simpletransformers==0.63.11
107
+ six @ file:///tmp/build/80754af9/six_1644875935023/work
108
+ smmap @ file:///tmp/build/80754af9/smmap_1611694433573/work
109
+ st-annotated-text==4.0.0
110
+ stack-data @ file:///opt/conda/conda-bld/stack_data_1646927590127/work
111
+ streamlit==1.22.0
112
+ streamlit-cropper==0.2.1
113
+ sympy @ file:///C:/ci_311_rebuilds/sympy_1679009400182/work
114
+ tenacity==8.2.2
115
+ tensorboard==2.13.0
116
+ tensorboard-data-server==0.7.0
117
+ tesserocr==2.5.2
118
+ threadpoolctl==3.1.0
119
+ tokenizers==0.13.3
120
+ toml @ file:///tmp/build/80754af9/toml_1616166611790/work
121
+ toolz @ file:///C:/ci_311/toolz_1676431406517/work
122
+ torch==2.0.1
123
+ torchaudio==2.0.2
124
+ torchvision==0.15.2
125
+ tornado @ file:///C:/ci_311/tornado_1676423689414/work
126
+ tqdm==4.65.0
127
+ traitlets @ file:///C:/ci_311/traitlets_1676423290727/work
128
+ transformers==4.29.2
129
+ typing_extensions @ file:///C:/b/abs_a1bb332wcs/croot/typing_extensions_1681939523095/work
130
+ tzlocal @ file:///C:/ci_311/tzlocal_1676439620276/work
131
+ urllib3 @ file:///C:/b/abs_3ce53vrdcr/croot/urllib3_1680254693505/work
132
+ validators @ file:///tmp/build/80754af9/validators_1612286467315/work
133
+ wandb==0.15.3
134
+ watchdog @ file:///C:/ci_311/watchdog_1676457923624/work
135
+ wcwidth @ file:///Users/ktietz/demo/mc3/conda-bld/wcwidth_1629357192024/work
136
+ Werkzeug==2.3.4
137
+ widgetsnbextension @ file:///C:/b/abs_882k4_4kdf/croot/widgetsnbextension_1679313880295/work
138
+ win-inet-pton @ file:///C:/ci_311/win_inet_pton_1676425458225/work
139
+ xxhash==3.2.0
140
+ yarl==1.9.2
141
+ zipp @ file:///C:/ci_311/zipp_1676426100491/work
style.css ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ @import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Sans+Thai&display=swap');
2
+ html, body, [class*="css"] {
3
+ /* transition: all .5s; */
4
+ font-family: 'IBM Plex Sans Thai', sans-serif;
5
+ /* font-size: 18px;
6
+ font-weight: 500;
7
+ color: #091747; */
8
+ }