ageitgey / face_recognition

The world's simplest facial recognition api for Python and the command line
MIT License
53.01k stars 13.45k forks source link

Freeze your script with Pyinstaller #357

Closed masoudr closed 5 years ago

masoudr commented 6 years ago

Hi, You might want to freeze your script into a standalone executable to run on any system without the need of installing python or face_recognition and maybe you want to create a demo for your application and want to give it to someone else without giving your source code. Here is a simple tutorial to do that. I tested this method with python3.6 on Windows 10, but I think you can get it working on Linux with a similar method.

  1. Make sure you have correctly installed both face_recognition and dlib and you see no error when importing them into your script.
  2. Make sure your script works fine, and all its dependencies are right next to it, and you can run it fine with python yourscript.py.
  3. Install Pyinstaller with pip: pip install pyinstaller
  4. Create a new directory and move your python script and all dependencies into it. I call it myproject and myscript.py
  5. Copy face_recognition_models and scipy-extra-dll from your python installed directory to your project directory.
  6. Create an empty file called <yourscriptname>.spec like myscript.spec next to your python script.
  7. Use below Pyinstaller spec file sample and edit some parts according to your needs: (I mark it with <> tag)
    
    # -*- mode: python -*-

block_cipher = None

face_models = [ ('.\face_recognition_models\models\dlib_face_recognition_resnet_model_v1.dat', './face_recognition_models/models'), ('.\face_recognition_models\models\mmod_human_face_detector.dat', './face_recognition_models/models'), ('.\face_recognition_models\models\shape_predictor_5_face_landmarks.dat', './face_recognition_models/models'), ('.\face_recognition_models\models\shape_predictor_68_face_landmarks.dat', './face_recognition_models/models'), ]

a = Analysis([''], pathex=[''], binaries=face_models, datas=[], hiddenimports=['scipy._lib.messagestream', 'scipy', 'scipy.signal', 'scipy.signal.bsplines', 'scipy.special', 'scipy.special._ufuncs_cxx', 'scipy.linalg.cython_blas', 'scipy.linalg.cython_lapack', 'scipy.integrate', 'scipy.integrate.quadrature', 'scipy.integrate.odepack', 'scipy.integrate._odepack', 'scipy.integrate.quadpack', 'scipy.integrate._quadpack', 'scipy.integrate._ode', 'scipy.integrate.vode', 'scipy.integrate._dop', 'scipy._lib', 'scipy._build_utils','scipy.config', 'scipy.integrate.lsoda', 'scipy.cluster', 'scipy.constants','scipy.fftpack','scipy.interpolate','scipy.io','scipy.linalg','scipy.misc','scipy.ndimage','scipy.odr','scipy.optimize','scipy.setup','scipy.sparse','scipy.spatial','scipy.special','scipy.stats','scipy.version'],

         hookspath=[],
         runtime_hooks=[],
         excludes=[],
         win_no_prefer_redirects=False,
         win_private_assemblies=False,
         cipher=block_cipher)

a.datas += Tree('./scipy-extra-dll', prefix=None)

pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) exe = EXE(pyz, a.scripts, a.binaries, a.zipfiles, a.datas, name='', debug=False, strip=False, upx=True, runtime_tmpdir=None, console=True )


8. Generate your executable with `python -m pyinstaller myscript.spec`
9. If you see no error then your executable can be found in `dist` directory.
10. Enjoy!

Thanks to @ageitgey and @davisking for their awesome work.
ageitgey commented 6 years ago

Cool, thanks for sharing!

vgreis commented 6 years ago

I found this worked very well when running on Windows desktop, but the application would crash on Windows Server 2012 - 2016 with an unhelpful, vague unable to execute DLL error. I found this issue was caused by using the latest version of dlib linked in the project install guide under issue 175 (currently 19.9.99). However, by using 'pip install dlib', which installs 19.9.0 (again, currently as of writing this). The frozen executable is running without errors on both desktop and server. I've also been testing freezing this in both 32-bit and 64-bit python and both are working. Thanks

masoudr commented 6 years ago

@vgreis I haven't tested Pyinstaller with the new version of dlib but I think you can get it working by just add the missing DLL's to binaries it will then be extracted when running the app and again remember that it doesn't matter if you install dlib by source or pip, just make sure your installation is successful.

mariocesarc commented 6 years ago

Thanks! It works

inewlife commented 6 years ago

Incompatible library version: dlib.so requires version 51.0.0 or later, but libpng16.16.dylib provides version 38.0.0

masoudr commented 6 years ago

@inewlife Can you post the complete error log? I haven't tested this method with the new version of dlib but I think it is not related because what you need here is just adding scipy and face_recognition_modules manually not the dlib itself.

fordffx commented 6 years ago

I did as what the first floor told,but still got this: Traceback (most recent call last): File "C:\PyInstaller-3.3.1\temp_classroom.py", line 16, in import face_recognition File "", line 961, in _find_and_load File "", line 950, in _find_and_load_unlocked File "", line 655, in _load_unlocked File "C:\PyInstaller-3.3.1\PyInstaller\loader\pyimod03_importers.py", line 631 , in exec_module exec(bytecode, module.dict) File "C:\ProgramData\Anaconda3\Lib\site-packages\face_recognition__init__.py" , line 7, in from .api import load_image_file, face_locations, batch_face_locations, face _landmarks, face_encodings, compare_faces, face_distance File "", line 961, in _find_and_load File "", line 950, in _find_and_load_unlocked File "", line 655, in _load_unlocked File "C:\PyInstaller-3.3.1\PyInstaller\loader\pyimod03_importers.py", line 631 , in exec_module exec(bytecode, module.dict) File "C:\ProgramData\Anaconda3\Lib\site-packages\face_recognition\api.py", lin e 21, in pose_predictor_5_point = dlib.shape_predictor(predictor_5_point_model) RuntimeError: Unable to open C:\Users\ADMINI~1\AppData\Local\Temp_MEI71042\face _recognition_models\models\shape_predictor_5_face_landmarks.dat [5948] Failed to execute script temp_classroom

how did the exe file come to this dir ? and _MEI71042 changes every time the exe file run

when i use nuitka to make exe file ,and it jumped out this as the exe file run : Please install face_recognition_models with this command before using face_recognition: pip install git+https://github.com/ageitgey/face_recognition_models actruly, I did installed them successfully.

thanks

masoudr commented 6 years ago

@fordffx Hi, As I said in the first post you must first install all dependencies for your python. About the _MEI71042, every time you run the executable pyinstaller tries to extract dependencies in the temp directory and when your program ends without exception it deletes that folder automatically,

fordffx commented 6 years ago

i replaced datas=[] with datas=[('shape_predictor_68_face_landmarks.dat','./face_recognition_models/models'),('shape_predictor_5_face_landmarks.dat','./face_recognition_models/models'),('mmod_human_face_detector.dat','./face_recognition_models/models'),('dlib_face_recognition_resnet_model_v1.dat','./face_recognition_models/models')] that works,thanks

roiksail commented 6 years ago

thanks for sharing your knowledge...i can't find scipy-extra-dll ...how i can to find them in python directory??i am in ubuntu 16.04, thank you in advance

masoudr commented 6 years ago

@roiksail Hi, dll files are not made for Linux systems so you can't find any. I think you don't need to add scipy dependencies. Just build your binary file and try to run it. If It complains about some files just find that and add it manually like above method. That is it.

roiksail commented 6 years ago

thank you,how i change myscript.spec file??

On Tue, Apr 10, 2018 at 10:19 PM, Masoud R. notifications@github.com wrote:

@roiksail https://github.com/roiksail Hi, dll files are not made for Linux systems so you can't find any. I think you don't need to add scipy dependencies. Just build your binary file and try to run it. If It complains about some files just find that and add it manually like above method. That is it.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ageitgey/face_recognition/issues/357#issuecomment-380189308, or mute the thread https://github.com/notifications/unsubscribe-auth/Ahjqp8SBtcZj6ua74UNX5VENf0B4MbY4ks5tnPCdgaJpZM4SBU9b .

masoudr commented 6 years ago

@roiksail First you need to freeze your script with pyinstaller script.py then the spec file should be generated next to your script file.

roiksail commented 6 years ago

thank you so much,i mmaked executable application in ubuntu but when i copied this file in ubuntu then it was simply file and it does not executed,how i fix this??

masoudr commented 6 years ago

@roiksail I think you need to find out what is Pyinstaller and how to use it in from here. In general, after you run the command you should find the executable with the exact name of the script. I think Pyinstaller will make the file as executable binary so you can just use ./yourscriptname command and if it didn't work try to make it executable with sudo chmod +x yourscriptname. That is it.

sincerefly commented 6 years ago

@vgreis thanks, when I build use dlib from github source code, The version is 19.10.99, It can only run on x64 system, and when I use pip install dlib, the version is 19.10.0, It can run on x86 system

sincerefly commented 6 years ago

@masoudr

I'm not find scipy-extra-dll in my site-packages, should I need install scipy?

1, when I am not install scipy, I can run face_recognition, Is scipy necessary? 2, I install scipy, and copy scipy dir from site-packages to project dir, with a.datas += Tree('./scipy-extra-dll', prefix=None), I can't find scipy-extra-dll, but I find extra-dll in scipy dir, can I write scipy/extra-dll instead it or not

thank you

masoudr commented 6 years ago

@sincerefly Hi, If I remember correctly there are some examples that need scipy so if you are using scipy with your project you need those files but if you don't, just use face_models no need for hidden imports that is it. And remember you just need to first freeze your script normally and if you got any errors about missing packages, you need to feed them manually in your spec file.

ratijas commented 6 years ago

@sincerefly @masoudr Confirmed. My app works with face_recognition without touching scipy at all. No hidden_imports nor datas needed in this case.

Also, for now face_recognition_models/**/*.dat resources get copied automatically without any extra code in .spec file.

Thanks for your efforts!

-- Windows 10.0.17134.81 Python 3.6 (32bit) pyinstaller 3.3.1

tinshade commented 5 years ago

@masoudr Can you please explain to me how can I get the face_recognition_models/*/.dat resources added from the .spec file? It does not seem to work for me. It says unable to open shape_predictor_68_face_landmarks.dat for some reason.

So far, I have tried:

masoudr commented 5 years ago

@tinshade I've already added all 4 model files in the example above, you just need to use the above sample spec file and fill parameters and this should solve your problem. But if you still need to add other models you can just add this to your spec file.

a = Analysis(...
     datas= [ ('face_recognition_models/**/*.dat', './face_recognition_models/models' ) ],
     ...
     )
alexpardede commented 5 years ago

i already install Pyinstaller, and while i check the directory its true no module name Pyinstaller. when i check in /home/attendance/anaconda3/envs/attendance_env/bin/python3.6/site-packages i find the module.

(attendance_env) attendance@attendance-desktop:~/Documents/face_attendance$ python -m Pyinstaller attendance.spec
/home/attendance/anaconda3/envs/attendance_env/bin/python: No module named Pyinstaller

can u help me

masoudr commented 5 years ago

@alexpardede I'm not familiar with Conda but I would suggest you first check your naming, it is case sensitive (python -m PyInstaller). Second, you can check your installed modules with pip freeze. Also if you have any problem with installing PyInstaller you should ask in its repo.

zkywalker commented 5 years ago

image

can you help me for this error ? i already have face-recognition-models while i check with pip freeze. and i already create and execute the attendance.spec. please help me. Thank You

try to copy the dependencies that open fail to your output dependencies dir, its helpful for me

zkywalker commented 5 years ago

image i have new issue. my main script refere to a other script. and the script call library "frozen_inference_graph_face.pb" from another folder. can you help me to solve the problem ? thank for your attention.

lol, the solution is same to dependencies no find, just copy them to the output dependencies dir. And its helpful when you do not use the -f arg, which will generate a file with all dependencies in it.

alexpardede commented 5 years ago

[image: image.png] can you help me with this problem ?

[image: image.png] i already insert the library. please help me thank you

Pada tanggal Jum, 29 Mar 2019 pukul 00.41 Masoud R. < notifications@github.com> menulis:

@alexpardede https://github.com/alexpardede I'm not familiar with Conda but I would suggest you first check your naming, it is case sensitive (python -m PyInstaller). Second, you can check your installed modules with pip freeze. Also if you have any problem with installing PyInstaller you should ask in its repo https://github.com/pyinstaller/pyinstaller.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ageitgey/face_recognition/issues/357#issuecomment-477689748, or mute the thread https://github.com/notifications/unsubscribe-auth/Ap6Yx00vbFHCqupMPLV5tSqekZmWJrBTks5vbPidgaJpZM4SBU9b .

libohao666 commented 4 years ago

I found this worked very well when running on Windows desktop, but the application would crash on Windows Server 2012 - 2016 with an unhelpful, vague unable to execute DLL error. I found this issue was caused by using the latest version of dlib linked in the project install guide under issue 175 (currently 19.9.99). However, by using 'pip install dlib', which installs 19.9.0 (again, currently as of writing this). The frozen executable is running without errors on both desktop and server. I've also been testing freezing this in both 32-bit and 64-bit python and both are working. Thanks

sorry to bother you.I don't understand.is 19.9.0dlib installed in the computer which pyinstaller the file or in winserver2012?My my application can run in my windows computer,but it can't work on my windows server2012.And my dlib package can't be uninstalled completely now....

fordffx commented 4 years ago

I found this worked very well when running on Windows desktop, but the application would crash on Windows Server 2012 - 2016 with an unhelpful, vague unable to execute DLL error. I found this issue was caused by using the latest version of dlib linked in the project install guide under issue 175 (currently 19.9.99). However, by using 'pip install dlib', which installs 19.9.0 (again, currently as of writing this). The frozen executable is running without errors on both desktop and server. I've also been testing freezing this in both 32-bit and 64-bit python and both are working. Thanks

sorry to bother you.I don't understand.is 19.9.0dlib installed in the computer which pyinstaller the file or in winserver2012?My my application can run in my windows computer,but it can't work on my windows server2012.And my dlib package can't be uninstalled completely now....

maybe you could try building the latest version of dlib on the target platform

rageshhub commented 4 years ago

I can't find the scipy-extra-dll in windows although I installed scipy. Help me.

masoudr commented 4 years ago

@Ragesh77 I haven't tested the new version. But check if you can import scipy without any problem and then double-check the file existence. If you still can't find it skip it and check if the executable works or not.

rageshhub commented 4 years ago

@Ragesh77 I haven't tested the new version. But check if you can import scipy without any problem and then double-check the file existence. If you still can't find it skip it and check if the executable works or not.

@masoudr Thanks for answering. I downgraded scipy to 1.3.0 and could locate all the files.

HAKANMAZI commented 4 years ago

I can't find the scipy-extra-dll in windows although I installed scipy. Help me.

You can search extra-dll using below code on cmd dir extra-dll /s /p I hope you will find it in scipy directory. After create scipy-extra-dll directory. Then all dll files transfer to scipy-extra-dll directory.

HAKANMAZI commented 4 years ago

Hi, You might want to freeze your script into a standalone executable to run on any system without the need of installing python or face_recognition and maybe you want to create a demo for your application and want to give it to someone else without giving your source code. Here is a simple tutorial to do that. I tested this method with python3.6 on Windows 10 but I think you can get it working on Linux with similar method.

  1. Make sure you have correctly installed both face_recognition and dlib correctly and you see no error when importing them into your script.
  2. Make sure your script works fine and all it dependencies are right next to it and you can run it fine with python yourscript.py.
  3. Install Pyinstaller with pip: pip install pyinstaller
  4. Create a new directory and move your python script and all dependencies into it. I call it myproject and myscript.py
  5. Copy face_recognition_models and scipy-extra-dll from your python installed directory to your project directory.
  6. Create an empty file called <yourscriptname>.spec like myscript.spec next to your python script.
  7. Use below Pyinstaller spec file sample and edit some parts according to your needs: (I mark it with <> tag)
# -*- mode: python -*-

block_cipher = None

face_models = [
('.\\face_recognition_models\\models\\dlib_face_recognition_resnet_model_v1.dat', './face_recognition_models/models'),
('.\\face_recognition_models\\models\\mmod_human_face_detector.dat', './face_recognition_models/models'),
('.\\face_recognition_models\\models\\shape_predictor_5_face_landmarks.dat', './face_recognition_models/models'),
('.\\face_recognition_models\\models\\shape_predictor_68_face_landmarks.dat', './face_recognition_models/models'),
]

a = Analysis(['<your python script name.py>'],
             pathex=['<path to working directory>'],
             binaries=face_models,
             datas=[],
             hiddenimports=['scipy._lib.messagestream', 'scipy', 'scipy.signal', 'scipy.signal.bsplines', 'scipy.special', 'scipy.special._ufuncs_cxx',
                            'scipy.linalg.cython_blas',
                            'scipy.linalg.cython_lapack',
                            'scipy.integrate',
                            'scipy.integrate.quadrature',
                            'scipy.integrate.odepack',
                            'scipy.integrate._odepack',
                            'scipy.integrate.quadpack',
                            'scipy.integrate._quadpack',
                            'scipy.integrate._ode',
                            'scipy.integrate.vode',
                            'scipy.integrate._dop', 'scipy._lib', 'scipy._build_utils','scipy.__config__',
                            'scipy.integrate.lsoda', 'scipy.cluster', 'scipy.constants','scipy.fftpack','scipy.interpolate','scipy.io','scipy.linalg','scipy.misc','scipy.ndimage','scipy.odr','scipy.optimize','scipy.setup','scipy.sparse','scipy.spatial','scipy.special','scipy.stats','scipy.version'],

             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher)

a.datas += Tree('./scipy-extra-dll', prefix=None)

pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          name='<your python script name>',
          debug=False,
          strip=False,
          upx=True,
          runtime_tmpdir=None,
          console=True )
  1. Generate your executable with python -m pyinstaller myscript.spec
  2. If you see no error then your executable can be found in dist directory.
  3. Enjoy!

Thanks to @ageitgey and @davisking for their awesome work.

Thanks for everything all guys. I did what you said and I created an exe file successfully. But when I click exe file it's working only once then suddenly closes. Before close it says something but I don't read because it is so fastly close. How can I fix this problem

masoudr commented 4 years ago

@HAKANMAZI Try to run executable with CMD and you should get the error in the console. Then put the error.

rageshhub commented 4 years ago

Can Someone help me in deploying this app in docker.I searched google nothing is clear.Could someone guide me?

masoudr commented 4 years ago

@Ragesh77 It is not an app. But if you trying to deploy your app with docker you can follow this.

HAKANMAZI commented 4 years ago

@HAKANMAZI Try to run executable with CMD and you should get the error in the console. Then put the error.

Thanks @masoudr ; output error below, error says me No module named 'sklearn'. Yes true there is no sklearn because I don't use it. Even if when I run my .py file there is no error. But when I change from .py to .exe file it saying No module named 'sklearn'. Why ?

raceback (most recent call last): File "C:\Users\HH\Desktop\python\exe\test.py", line 94, in openCamera() File "C:\Users\HH\Desktop\python\exe\test.py", line 66, in openCamera predictions = predict(facePath, model_path=model_path) File "C:\Users\HH\Desktop\python\exe\test.py", line 30, in predict knn_clf = pickle.load(f) ModuleNotFoundError: No module named 'sklearn' [14372] Failed to execute script test [ WARN:0] global C:\projects\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (674) SourceReaderCB::~SourceReaderCB terminating async callback

masoudr commented 4 years ago

@HAKANMAZI Your error is not related to this tutorial (because you are using sklearn which is another module), but you can use this.

HAKANMAZI commented 4 years ago

@HAKANMAZI Try to run executable with CMD and you should get the error in the console. Then put the error.

Thanks @masoudr ; output error below, error says me No module named 'sklearn'. Yes true there is no sklearn because I don't use it. Even if when I run my .py file there is no error. But when I change from .py to .exe file it saying No module named 'sklearn'. Why ?

raceback (most recent call last): File "C:\Users\HH\Desktop\python\exe\test.py", line 94, in openCamera() File "C:\Users\HH\Desktop\python\exe\test.py", line 66, in openCamera predictions = predict(facePath, model_path=model_path) File "C:\Users\HH\Desktop\python\exe\test.py", line 30, in predict knn_clf = pickle.load(f) ModuleNotFoundError: No module named 'sklearn' [14372] Failed to execute script test [ WARN:0] global C:\projects\opencv-python\opencv\modules\videoio\src\cap_msmf.cpp (674) SourceReaderCB::~SourceReaderCB terminating async callback

Finally I solved my problem. As I said I don't use sklearn on my code but background sklearn was using. Then I add in hiddenimports=['sklearn','sklearn.neighbors._typedefs','sklearn.utils._cython_blas'] in my spec file. and it is okey, it solved :)

daynial132 commented 4 years ago

hello I am new to this freezer part,

I have made a separate folder as mentioned and move my python script and models in it. also i copied the freezer script(.spec) file. finally i got the build giving the error "ImportError: No module named 'face_recognition'" Please help me with it I am using anaconda, and not using scipy. I have attached the freezer script also.

freeze_app .txt

masoudr commented 4 years ago

@daynial132 First make sure that your script is working fine in your environment also you must be sure that you run PyInstaller from your environment (with using python -m PyInstaller). I think you are running the PyInstaller from your main Python installation which doesn't have face_recognition.

daynial132 commented 4 years ago

@masoudr I have placed my python script,3 pics and the freezer file (.spec) and the face_recognition_models in the folder only. do I need any thing else?

I have check my python script to run on my anaconda shell, it is running fine that's mean dlib and face_recognition lib is installed properly. Am i right or missing some thing?

Also I have used anaconda shell to run (python -m PyInstaller) command.

Thank you for your reply

masoudr commented 4 years ago

@daynial132 I haven't tested this with Conda yet, but I don't think it would be a problem. Your error means that PyInstaller can't find the face_recognition. Try to run pip freeze inside your console and make sure that face_recognition exists in the output. If it is there but you still get that error try to add face_recognition into the hidden_imports as I did for the scipy modules.

mend4x commented 4 years ago

I am having this output after freezing my code with this .spec file below. When I run my app on console on Linux I get this:

Traceback (most recent call last):
  File "main.py", line 6, in <module>
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "/home/neo/Desktop/faseez/dev/refasee/venv/lib/python3.6/site-packages/PyInstaller/loader/pyimod03_importers.py", line 623, in exec_module
    exec(bytecode, module.__dict__)
  File "face_recognition/__init__.py", line 7, in <module>
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "/home/neo/Desktop/faseez/dev/refasee/venv/lib/python3.6/site-packages/PyInstaller/loader/pyimod03_importers.py", line 623, in exec_module
    exec(bytecode, module.__dict__)
  File "face_recognition/api.py", line 20, in <module>
RuntimeError: Unable to open /tmp/_MEIHAOamS/face_recognition_models/models/shape_predictor_68_face_landmarks.dat
[11437] Failed to execute script main

Fascee.spec.txt

masoudr commented 4 years ago

@mend4x Make sure that you have the shape_predictor_68_face_landmarks.dat when building the project. Also if the error came double check that the shape_predictor_68_face_landmarks.dat exists in the given path (e.g /tmp/_MEIHAOamS/face_recognition_models/models).

mend4x commented 4 years ago

@masoudr I actually do have this file in script directory. The given path is tmp so each time it runs it's new directory

masoudr commented 4 years ago

@mend4x Double check that the files in models directory and also when you run the script check the tmp directory and verify the file and its size.

tingfengyinyue commented 4 years ago

@masoudr 我的问题是,打包的时候没有问题,打包后,点击exe 只有小黑窗口,程序没办法运行。 界面没办法显示。请教您帮忙

tingfengyinyue commented 4 years ago

窗口提示: Fatal Python error: initfsencoding: unable to load the file system codec zipimport.ZipImportError: can't find module' encodings

saadi-tech commented 4 years ago

Thank you sooooooooooooooooooooooooooooooooo much! :)