wiydarrr commited on
Commit
5f685fd
1 Parent(s): 6ea6dc1

Upload folder using huggingface_hub

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .database/template_asset_db.json +47 -0
  2. .gitattributes +36 -35
  3. .github/CHANGE_LOG.md +34 -0
  4. .github/CODEOWNERS +6 -0
  5. .github/CODE_OF_CONDUCT.md +127 -0
  6. .github/CONTRIBUTING.md +21 -0
  7. .github/ISSUE_TEMPLATE/bug_report.yaml +99 -0
  8. .github/ISSUE_TEMPLATE/feature_request.yaml +36 -0
  9. .github/ISSUE_TEMPLATE/question.yaml +17 -0
  10. .github/SECURITY.md +28 -0
  11. .github/config.yml +21 -0
  12. .github/issue_label_bot.yaml +4 -0
  13. .github/pull_request_template.md +30 -0
  14. .github/settings.yml +190 -0
  15. .github/workflows/generate_release-changelog.yaml +33 -0
  16. .github/workflows/update_space.yml +28 -0
  17. .gitignore +28 -0
  18. CHANGES.txt +14 -0
  19. LICENSE +35 -0
  20. README.md +199 -9
  21. assets/img/logo.png +0 -0
  22. docs/.gitignore +20 -0
  23. docs/README.md +10 -0
  24. docs/babel.config.js +3 -0
  25. docs/docs/how-to-install.mdx +121 -0
  26. docs/docusaurus.config.js +135 -0
  27. docs/package.json +51 -0
  28. docs/plugins/my-loaders/index.js +18 -0
  29. docs/plugins/tailwind-loader/index.js +19 -0
  30. docs/sidebars.js +20 -0
  31. docs/src/components/Home.js +356 -0
  32. docs/src/css/custom.css +198 -0
  33. docs/src/css/fragments.css +2275 -0
  34. docs/src/pages/index.js +17 -0
  35. docs/static/img/assets/configuration.svg +0 -0
  36. docs/static/img/assets/implementation.svg +1 -0
  37. docs/static/img/assets/scraping.svg +1 -0
  38. docs/static/img/favicon.ico +0 -0
  39. docs/static/img/logo.png +0 -0
  40. docs/tailwind.config.js +12 -0
  41. docs/yarn.lock +0 -0
  42. gui/asset_components.py +87 -0
  43. gui/asset_library_ui.py +114 -0
  44. gui/content_automation_ui.py +24 -0
  45. gui/gui_gradio.py +38 -0
  46. gui/ui_abstract_base.py +19 -0
  47. gui/ui_abstract_component.py +5 -0
  48. gui/ui_components_html.py +56 -0
  49. gui/ui_tab_asset_library.py +197 -0
  50. gui/ui_tab_config.py +92 -0
.database/template_asset_db.json ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "asset_collection": {
3
+ "1": {
4
+ "_id": "local_assets",
5
+ "white_reddit_template": {
6
+ "path": "public/white_reddit_template.png",
7
+ "type": "image",
8
+ "ts": "2023-07-03 19:41:55",
9
+ "required": true
10
+ },
11
+ "subscribe-animation": {
12
+ "path": "public/subscribe-animation.mp4",
13
+ "type": "video",
14
+ "ts": "2023-07-03 21:37:53",
15
+ "required": true
16
+ }
17
+ },
18
+ "2": {
19
+ "_id": "remote_assets",
20
+ "Music joakim karud dreams": {
21
+ "type": "background music",
22
+ "url": "https://www.youtube.com/watch?v=p56gqDhUYbU",
23
+ "ts": "2023-07-05 04:35:03"
24
+ },
25
+ "Music dj quads": {
26
+ "type": "background music",
27
+ "url": "https://www.youtube.com/watch?v=uUu1NcSHg2E",
28
+ "ts": "2023-07-05 05:03:44"
29
+ },
30
+ "Car race gameplay": {
31
+ "type": "background video",
32
+ "url": "https://www.youtube.com/watch?v=gBsJA8tCeyc",
33
+ "ts": "2023-07-04 23:07:44"
34
+ },
35
+ "Minecraft jumping circuit": {
36
+ "url": "https://www.youtube.com/watch?v=Pt5_GSKIWQM",
37
+ "type": "background video",
38
+ "ts": "2023-07-07 04:13:36"
39
+ },
40
+ "Ski gameplay": {
41
+ "url": "https://www.youtube.com/watch?v=8ao1NAOVKTU",
42
+ "type": "background video",
43
+ "ts": "2023-07-07 04:54:16"
44
+ }
45
+ }
46
+ }
47
+ }
.gitattributes CHANGED
@@ -1,35 +1,36 @@
1
- *.7z filter=lfs diff=lfs merge=lfs -text
2
- *.arrow filter=lfs diff=lfs merge=lfs -text
3
- *.bin filter=lfs diff=lfs merge=lfs -text
4
- *.bz2 filter=lfs diff=lfs merge=lfs -text
5
- *.ckpt filter=lfs diff=lfs merge=lfs -text
6
- *.ftz filter=lfs diff=lfs merge=lfs -text
7
- *.gz filter=lfs diff=lfs merge=lfs -text
8
- *.h5 filter=lfs diff=lfs merge=lfs -text
9
- *.joblib filter=lfs diff=lfs merge=lfs -text
10
- *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
- *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
- *.model filter=lfs diff=lfs merge=lfs -text
13
- *.msgpack filter=lfs diff=lfs merge=lfs -text
14
- *.npy filter=lfs diff=lfs merge=lfs -text
15
- *.npz filter=lfs diff=lfs merge=lfs -text
16
- *.onnx filter=lfs diff=lfs merge=lfs -text
17
- *.ot filter=lfs diff=lfs merge=lfs -text
18
- *.parquet filter=lfs diff=lfs merge=lfs -text
19
- *.pb filter=lfs diff=lfs merge=lfs -text
20
- *.pickle filter=lfs diff=lfs merge=lfs -text
21
- *.pkl filter=lfs diff=lfs merge=lfs -text
22
- *.pt filter=lfs diff=lfs merge=lfs -text
23
- *.pth filter=lfs diff=lfs merge=lfs -text
24
- *.rar filter=lfs diff=lfs merge=lfs -text
25
- *.safetensors filter=lfs diff=lfs merge=lfs -text
26
- saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
- *.tar.* filter=lfs diff=lfs merge=lfs -text
28
- *.tar filter=lfs diff=lfs merge=lfs -text
29
- *.tflite filter=lfs diff=lfs merge=lfs -text
30
- *.tgz filter=lfs diff=lfs merge=lfs -text
31
- *.wasm filter=lfs diff=lfs merge=lfs -text
32
- *.xz filter=lfs diff=lfs merge=lfs -text
33
- *.zip filter=lfs diff=lfs merge=lfs -text
34
- *.zst filter=lfs diff=lfs merge=lfs -text
35
- *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ public/subscribe-animation.mp4 filter=lfs diff=lfs merge=lfs -text
.github/CHANGE_LOG.md ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## [Unreleased]
6
+
7
+ <!--
8
+ Notes for any unreleased changes do here. When a new release is cut, move these from
9
+ the unreleased section to the section for the new release.
10
+ -->
11
+
12
+ Upcoming changes.
13
+
14
+ ### Added
15
+
16
+ ### Changed
17
+
18
+ ### Removed
19
+
20
+ ## [0.0.1] - YYYY-MM-DD
21
+
22
+ Initial Release.
23
+
24
+ ### Added
25
+
26
+ - What was added.
27
+
28
+
29
+ <!--
30
+ These Markdown anchors provide a link to the diff for each release. They should be
31
+ updated any time a new release is cut.
32
+ -->
33
+ [Unreleased]: /
34
+ [0.0.1]: /v0.0.1
.github/CODEOWNERS ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ # These owners will be the default owners for everything in
2
+ # the repo. Unless a later match takes precedence,
3
+ # @USER will be requested for
4
+ # review when someone opens a pull request.
5
+ # if you want to add more owners just write it after the demo user @DemoUser
6
+ * @RayVentura
.github/CODE_OF_CONDUCT.md ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We as members, contributors, and leaders pledge to make participation in our
6
+ community a harassment-free experience for everyone, regardless of age, body
7
+ size, visible or invisible disability, ethnicity, sex characteristics, gender
8
+ identity and expression, level of experience, education, socio-economic status,
9
+ nationality, personal appearance, race, religion, or sexual identity
10
+ and orientation.
11
+
12
+ We pledge to act and interact in ways that contribute to an open, welcoming,
13
+ diverse, inclusive, and healthy community.
14
+
15
+ ## Our Standards
16
+
17
+ Examples of behavior that contributes to a positive environment for our
18
+ community include:
19
+
20
+ * Demonstrating empathy and kindness toward other people
21
+ * Being respectful of differing opinions, viewpoints, and experiences
22
+ * Giving and gracefully accepting constructive feedback
23
+ * Accepting responsibility and apologizing to those affected by our mistakes,
24
+ and learning from the experience
25
+ * Focusing on what is best not just for us as individuals, but for the
26
+ overall community
27
+
28
+ Examples of unacceptable behavior include:
29
+
30
+ * The use of sexualized language or imagery, and sexual attention or
31
+ advances of any kind
32
+ * Trolling, insulting or derogatory comments, and personal or political attacks
33
+ * Public or private harassment
34
+ * Publishing others' private information, such as a physical or email
35
+ address, without their explicit permission
36
+ * Other conduct which could reasonably be considered inappropriate in a
37
+ professional setting
38
+
39
+ ## Enforcement Responsibilities
40
+
41
+ Community leaders are responsible for clarifying and enforcing our standards of
42
+ acceptable behavior and will take appropriate and fair corrective action in
43
+ response to any behavior that they deem inappropriate, threatening, offensive,
44
+ or harmful.
45
+
46
+ Community leaders have the right and responsibility to remove, edit, or reject
47
+ comments, commits, code, wiki edits, issues, and other contributions that are
48
+ not aligned to this Code of Conduct, and will communicate reasons for moderation
49
+ decisions when appropriate.
50
+
51
+ ## Scope
52
+
53
+ This Code of Conduct applies within all community spaces, and also applies when
54
+ an individual is officially representing the community in public spaces.
55
+ Examples of representing our community include using an official e-mail address,
56
+ posting via an official social media account, or acting as an appointed
57
+ representative at an online or offline event.
58
+
59
+ ## Enforcement
60
+
61
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
62
+ reported to the community leaders responsible for enforcement.
63
+ All complaints will be reviewed and investigated promptly and fairly.
64
+
65
+ All community leaders are obligated to respect the privacy and security of the
66
+ reporter of any incident.
67
+
68
+ ## Enforcement Guidelines
69
+
70
+ Community leaders will follow these Community Impact Guidelines in determining
71
+ the consequences for any action they deem in violation of this Code of Conduct:
72
+
73
+ ### 1. Correction
74
+
75
+ **Community Impact**: Use of inappropriate language or other behavior deemed
76
+ unprofessional or unwelcome in the community.
77
+
78
+ **Consequence**: A private, written warning from community leaders, providing
79
+ clarity around the nature of the violation and an explanation of why the
80
+ behavior was inappropriate. A public apology may be requested.
81
+
82
+ ### 2. Warning
83
+
84
+ **Community Impact**: A violation through a single incident or series
85
+ of actions.
86
+
87
+ **Consequence**: A warning with consequences for continued behavior. No
88
+ interaction with the people involved, including unsolicited interaction with
89
+ those enforcing the Code of Conduct, for a specified period of time. This
90
+ includes avoiding interactions in community spaces as well as external channels
91
+ like social media. Violating these terms may lead to a temporary or
92
+ permanent ban.
93
+
94
+ ### 3. Temporary Ban
95
+
96
+ **Community Impact**: A serious violation of community standards, including
97
+ sustained inappropriate behavior.
98
+
99
+ **Consequence**: A temporary ban from any sort of interaction or public
100
+ communication with the community for a specified period of time. No public or
101
+ private interaction with the people involved, including unsolicited interaction
102
+ with those enforcing the Code of Conduct, is allowed during this period.
103
+ Violating these terms may lead to a permanent ban.
104
+
105
+ ### 4. Permanent Ban
106
+
107
+ **Community Impact**: Demonstrating a pattern of violation of community
108
+ standards, including sustained inappropriate behavior, harassment of an
109
+ individual, or aggression toward or disparagement of classes of individuals.
110
+
111
+ **Consequence**: A permanent ban from any sort of public interaction within
112
+ the community.
113
+
114
+ ## Attribution
115
+
116
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
117
+ version 2.0, available at
118
+ https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
119
+
120
+ Community Impact Guidelines were inspired by [Mozilla's code of conduct
121
+ enforcement ladder](https://github.com/mozilla/diversity).
122
+
123
+ [homepage]: https://www.contributor-covenant.org
124
+
125
+ For answers to common questions about this code of conduct, see the FAQ at
126
+ https://www.contributor-covenant.org/faq. Translations are available at
127
+ https://www.contributor-covenant.org/translations.
.github/CONTRIBUTING.md ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 🌟💻📚
2
+
3
+ ## Contributing
4
+
5
+ There are many exciting ways to contribute to ShortGPT, our AI automated content creation framework. 👏
6
+
7
+ See below for everything you can do and the processes to follow for each contribution method. Note that no matter how you contribute, your participation is governed by our ✨[Code of Conduct](CODE_OF_CONDUCT.md)✨.
8
+
9
+ ## 🛠️ Make changes to the code or docs
10
+
11
+ - 🍴 Fork the project,
12
+ - 💡 make your changes,
13
+ - 🔀 and send a pull request! 🙌
14
+
15
+ Make sure you read and follow the instructions in the [pull request template](pull_request_template.md). And note that all participation in this project (including code submissions) is governed by our ✨[Code of Conduct](CODE_OF_CONDUCT.md)✨.
16
+
17
+ ## 🐞📝 Submit bug reports or feature requests
18
+
19
+ Just use the GitHub issue tracker to submit your bug reports and feature requests. We appreciate your feedback! 🐛🔧
20
+
21
+ Let's make ShortGPT even better together! 🚀❤️
.github/ISSUE_TEMPLATE/bug_report.yaml ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: 🐛 Bug Report
2
+ description: File a bug report
3
+ title: '🐛 [Bug]: '
4
+ labels: ['bug']
5
+
6
+ body:
7
+ - type: markdown
8
+ attributes:
9
+ value: |
10
+ Thanks for taking the time to fill out this bug report!
11
+
12
+ - type: textarea
13
+ id: what-happened
14
+ attributes:
15
+ label: What happened?
16
+ description: Describe the issue here.
17
+ placeholder: Tell us what you see!
18
+ validations:
19
+ required: true
20
+
21
+ - type: dropdown
22
+ id: browsers
23
+ attributes:
24
+ label: What type of browser are you seeing the problem on?
25
+ multiple: true
26
+ options:
27
+ - Firefox
28
+ - Chrome
29
+ - Safari
30
+ - Microsoft Edge
31
+ validations:
32
+ required: true
33
+
34
+ - type: dropdown
35
+ id: operating-systems
36
+ attributes:
37
+ label: What type of Operating System are you seeing the problem on?
38
+ multiple: true
39
+ options:
40
+ - Linux
41
+ - Windows
42
+ - Mac
43
+ - Google Colab
44
+ - Other
45
+ validations:
46
+ required: true
47
+
48
+ - type: input
49
+ id: python-version
50
+ attributes:
51
+ label: Python Version
52
+ description: What version of Python are you using?
53
+ placeholder: e.g. Python 3.9.0
54
+ validations:
55
+ required: true
56
+
57
+ - type: input
58
+ id: application-version
59
+ attributes:
60
+ label: Application Version
61
+ description: What version of the application are you using?
62
+ placeholder: e.g. v1.2.3
63
+ validations:
64
+ required: true
65
+
66
+ - type: textarea
67
+ id: expected-behavior
68
+ attributes:
69
+ label: Expected Behavior
70
+ description: What did you expect to happen?
71
+ placeholder: What did you expect?
72
+ validations:
73
+ required: true
74
+
75
+ - type: textarea
76
+ id: error-message
77
+ attributes:
78
+ label: Error Message
79
+ description: What error message did you receive?
80
+ placeholder:
81
+ render: shell
82
+ validations:
83
+ required: false
84
+
85
+ - type: textarea
86
+ id: logs
87
+ attributes:
88
+ label: Code to produce this issue.
89
+ description: Please copy and paste any relevant code to re-produce this issue.
90
+ render: shell
91
+
92
+ - type: textarea
93
+ id: screenshots-assets
94
+ attributes:
95
+ label: Screenshots/Assets/Relevant links
96
+ description: If applicable, add screenshots, assets or any relevant links that can help understand the issue.
97
+ placeholder: Provide any relevant material here
98
+ validations:
99
+ required: false
.github/ISSUE_TEMPLATE/feature_request.yaml ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: ✨ Feature request
2
+ description: Suggest an feature / idea for this project
3
+ title: '✨ [Feature Request / Suggestion]: '
4
+ labels: ['feature']
5
+ body:
6
+ - type: markdown
7
+ attributes:
8
+ value: |
9
+ We appreciate your feedback on how to improve this project. Please be sure to include as much details & any resources if possible!
10
+
11
+ - type: textarea
12
+ id: Suggestion
13
+ attributes:
14
+ label: Suggestion / Feature Request
15
+ description: Describe the feature(s) you would like to see added.
16
+ placeholder: Tell us your suggestion
17
+ validations:
18
+ required: true
19
+
20
+ - type: textarea
21
+ id: why-usage
22
+ attributes:
23
+ label: Why would this be useful?
24
+ description: Describe why this feature would be useful.
25
+ placeholder: Tell us why this would be useful to have this feature
26
+ validations:
27
+ required: false
28
+
29
+ - type: textarea
30
+ id: screenshots-assets
31
+ attributes:
32
+ label: Screenshots/Assets/Relevant links
33
+ description: If applicable, add screenshots, assets or any relevant links that can help understand the issue.
34
+ placeholder: Provide any relevant material here
35
+ validations:
36
+ required: false
.github/ISSUE_TEMPLATE/question.yaml ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: ❓ Question
2
+ description: Ask a question about this project
3
+ title: '❓ [Question]: '
4
+ labels: ['question']
5
+ body:
6
+ - type: markdown
7
+ attributes:
8
+ value: |
9
+ We appreciate your interest in this project. Please be sure to include as much detail & context about your question as possible!
10
+
11
+ - type: textarea
12
+ id: Question
13
+ attributes:
14
+ label: Your Question
15
+ description: Describe your question in detail.
16
+ validations:
17
+ required: true
.github/SECURITY.md ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Security Policy
2
+
3
+ ## Supported Versions
4
+
5
+ | Version | Supported |
6
+ | ------- | ------------------ |
7
+ | 0.0.x | :x: |
8
+
9
+ ## 🔒️ Reporting a Vulnerability
10
+
11
+ If you have identified a security vulnerability in system or product please `RayVentura` with your findings. We strongly recommend using our `PGP key` to prevent this information from falling into the wrong hands.
12
+
13
+ ### Disclosure Policy
14
+
15
+ Upon receipt of a security report the following steps will be taken:
16
+
17
+ - Acknowledge your report within 48 hours, and provide a further more detailed update within 48 hours.
18
+ - Confirm the problem and determine the affected versions
19
+ - Keep you informed of the progress towards resolving the problem and notify you when the vulnerability has been fixed.
20
+ - Audit code to find any potential similar problems.
21
+ - Prepare fixes for all releases still under maintenance. These fixes will be released as fast as possible.
22
+ - Handle your report with strict confidentiality, and not pass on your personal details to third parties without your permission.
23
+
24
+ Whilst the issue is under investigation
25
+
26
+ - **Do** provide as much information as possible.
27
+ - **Do not** exploit of the vulnerability or problem you have discovered.
28
+ - **Do not** reveal the problem to others until it has been resolved.
.github/config.yml ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Configuration for new-issue-welcome - https://github.com/behaviorbot/new-issue-welcome
2
+
3
+ # Comment to be posted to on first time issues
4
+ newIssueWelcomeComment: >
5
+ Thanks for opening your first issue! Reports like these help improve the project!
6
+
7
+ # Configuration for new-pr-welcome - https://github.com/behaviorbot/new-pr-welcome
8
+
9
+ # Comment to be posted to on PRs from first time contributors in your repository
10
+ newPRWelcomeComment: >
11
+ Thanks for opening this pull request!
12
+
13
+ # Configuration for first-pr-merge - https://github.com/behaviorbot/first-pr-merge
14
+
15
+ # Comment to be posted to on pull requests merged by a first time user
16
+ firstPRMergeComment: >
17
+ Congrats on merging your first pull request!
18
+
19
+ # The keyword to find for Todo Bot issue
20
+ todo:
21
+ keyword: '@todo'
.github/issue_label_bot.yaml ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ label-alias:
2
+ bug: 'Type: Bug'
3
+ feature_request: 'Type: Feature'
4
+ question: 'Type: Question'
.github/pull_request_template.md ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Proposed changes
2
+
3
+ Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request. If it fixes a bug or resolves a feature request, be sure to link to that issue. 👀🔧
4
+
5
+ ## Types of changes
6
+
7
+ What types of changes does your code introduce to this project?
8
+ _Put an `x` in the boxes that apply_ 😄🚀
9
+
10
+ - [ ] Bugfix (non-breaking change which fixes an issue) 🐛
11
+ - [ ] New feature (non-breaking change which adds functionality) ✨
12
+ - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) 💥
13
+ - [ ] Documentation Update (if none of the other choices apply) 📖
14
+
15
+ ## Checklist
16
+
17
+ _Put an `x` in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code._ ✅
18
+
19
+ - [ ] I have read the CONTRIBUTING.md 📚
20
+ - [ ] I have added tests that prove my fix is effective or that my feature works ✅✔️
21
+ - [ ] I have added necessary documentation (if appropriate) 📝
22
+
23
+ ## Further comments
24
+
25
+ If this is a relatively large or complex change, kick off the discussion by explaining why you chose the solution you did and what alternatives you considered, etc... 💡❓
26
+
27
+
28
+ ## References and related issues (e.g. #1234)
29
+
30
+ N/A 📌
.github/settings.yml ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ repository:
2
+ # See https://developer.github.com/v3/repos/#edit for all available settings.
3
+
4
+ # The name of the repository. Changing this will rename the repository
5
+ #name: repo-name
6
+
7
+ # A short description of the repository that will show up on GitHub
8
+ #description: description of repo
9
+
10
+ # A URL with more information about the repository
11
+ #homepage: https://example.github.io/
12
+
13
+ # A comma-separated list of topics to set on the repository
14
+ #topics: project, template, project-template
15
+
16
+ # Either `true` to make the repository private, or `false` to make it public.
17
+ #private: false
18
+
19
+ # Either `true` to enable issues for this repository, `false` to disable them.
20
+ has_issues: true
21
+
22
+ # Either `true` to enable the wiki for this repository, `false` to disable it.
23
+ has_wiki: true
24
+
25
+ # Either `true` to enable downloads for this repository, `false` to disable them.
26
+ #has_downloads: true
27
+
28
+ # Updates the default branch for this repository.
29
+ default_branch: stable
30
+
31
+ # Either `true` to allow squash-merging pull requests, or `false` to prevent
32
+ # squash-merging.
33
+ #allow_squash_merge: true
34
+
35
+ # Either `true` to allow merging pull requests with a merge commit, or `false`
36
+ # to prevent merging pull requests with merge commits.
37
+ #allow_merge_commit: true
38
+
39
+ # Either `true` to allow rebase-merging pull requests, or `false` to prevent
40
+ # rebase-merging.
41
+ #allow_rebase_merge: true
42
+
43
+ # Labels: define labels for Issues and Pull Requests
44
+ labels:
45
+ - name: 'Type: Bug'
46
+ color: e80c0c
47
+ description: Something isn't working as expected.
48
+
49
+ - name: 'Type: Enhancement'
50
+ color: 54b2ff
51
+ description: Suggest an improvement for an existing feature.
52
+
53
+ - name: 'Type: Feature'
54
+ color: 54b2ff
55
+ description: Suggest a new feature.
56
+
57
+ - name: 'Type: Security'
58
+ color: fbff00
59
+ description: A problem or enhancement related to a security issue.
60
+
61
+ - name: 'Type: Question'
62
+ color: 9309ab
63
+ description: Request for information.
64
+
65
+ - name: 'Type: Test'
66
+ color: ce54e3
67
+ description: A problem or enhancement related to a test.
68
+
69
+ - name: 'Status: Awaiting Review'
70
+ color: 24d15d
71
+ description: Ready for review.
72
+
73
+ - name: 'Status: WIP'
74
+ color: 07b340
75
+ description: Currently being worked on.
76
+
77
+ - name: 'Status: Waiting'
78
+ color: 38C968
79
+ description: Waiting on something else to be ready.
80
+
81
+ - name: 'Status: Stale'
82
+ color: 66b38a
83
+ description: Has had no activity for some time.
84
+
85
+ - name: 'Duplicate'
86
+ color: EB862D
87
+ description: Duplicate of another issue.
88
+
89
+ - name: 'Invalid'
90
+ color: faef50
91
+ description: This issue doesn't seem right.
92
+
93
+ - name: 'Priority: High +'
94
+ color: ff008c
95
+ description: Task is considered higher-priority.
96
+
97
+ - name: 'Priority: Low -'
98
+ color: 690a34
99
+ description: Task is considered lower-priority.
100
+
101
+ - name: 'Documentation'
102
+ color: 2fbceb
103
+ description: An issue/change with the documentation.
104
+
105
+ - name: "Won't fix"
106
+ color: C8D9E6
107
+ description: Reported issue is working as intended.
108
+
109
+ - name: '3rd party issue'
110
+ color: e88707
111
+ description: This issue might be caused by a 3rd party script/package/other reasons
112
+
113
+ - name: 'Os: Windows'
114
+ color: AEB1C2
115
+ description: Is Windows-specific
116
+
117
+ - name: 'Os: Mac'
118
+ color: AEB1C2
119
+ description: Is Mac-specific
120
+
121
+ - name: 'Os: Linux'
122
+ color: AEB1C2
123
+ description: Is Linux-specific
124
+
125
+ - name: 'Os: Google Colab'
126
+ color: AEB1C2
127
+ description: Is Google Colab-specific
128
+ #
129
+ #
130
+ # # Collaborators: give specific users access to this repository.
131
+ # # See https://developer.github.com/v3/repos/collaborators/#add-user-as-a-collaborator for available options
132
+ # collaborators:
133
+ # # - username: bkeepers
134
+ # # permission: push
135
+ # # - username: hubot
136
+ # # permission: pull
137
+
138
+ # # Note: `permission` is only valid on organization-owned repositories.
139
+ # # The permission to grant the collaborator. Can be one of:
140
+ # # * `pull` - can pull, but not push to or administer this repository.
141
+ # # * `push` - can pull and push, but not administer this repository.
142
+ # # * `admin` - can pull, push and administer this repository.
143
+ # # * `maintain` - Recommended for project managers who need to manage the repository without access to sensitive or destructive actions.
144
+ # # * `triage` - Recommended for contributors who need to proactively manage issues and pull requests without write access.
145
+
146
+ # # See https://developer.github.com/v3/teams/#add-or-update-team-repository for available options
147
+ # teams:
148
+ # - name: core
149
+ # # The permission to grant the team. Can be one of:
150
+ # # * `pull` - can pull, but not push to or administer this repository.
151
+ # # * `push` - can pull and push, but not administer this repository.
152
+ # # * `admin` - can pull, push and administer this repository.
153
+ # # * `maintain` - Recommended for project managers who need to manage the repository without access to sensitive or destructive actions.
154
+ # # * `triage` - Recommended for contributors who need to proactively manage issues and pull requests without write access.
155
+ # permission: admin
156
+ # - name: docs
157
+ # permission: push
158
+
159
+ # branches:
160
+ # - name: master
161
+ # # https://developer.github.com/v3/repos/branches/#update-branch-protection
162
+ # # Branch Protection settings. Set to null to disable
163
+ # protection:
164
+ # # Required. Require at least one approving review on a pull request, before merging. Set to null to disable.
165
+ # required_pull_request_reviews:
166
+ # # The number of approvals required. (1-6)
167
+ # required_approving_review_count: 1
168
+ # # Dismiss approved reviews automatically when a new commit is pushed.
169
+ # dismiss_stale_reviews: true
170
+ # # Blocks merge until code owners have reviewed.
171
+ # require_code_owner_reviews: true
172
+ # # Specify which users and teams can dismiss pull request reviews. Pass an empty dismissal_restrictions object to disable. User and team dismissal_restrictions are only available for organization-owned repositories. Omit this parameter for personal repositories.
173
+ # dismissal_restrictions:
174
+ # users: []
175
+ # teams: []
176
+ # # Required. Require status checks to pass before merging. Set to null to disable
177
+ # required_status_checks:
178
+ # # Required. Require branches to be up to date before merging.
179
+ # strict: true
180
+ # # Required. The list of status checks to require in order to merge into this branch
181
+ # contexts: []
182
+ # # Required. Enforce all configured restrictions for administrators. Set to true to enforce required status checks for repository administrators. Set to null to disable.
183
+ # enforce_admins: true
184
+ # # Prevent merge commits from being pushed to matching branches
185
+ # required_linear_history: true
186
+ # # Required. Restrict who can push to this branch. Team and user restrictions are only available for organization-owned repositories. Set to null to disable.
187
+ # restrictions:
188
+ # apps: []
189
+ # users: []
190
+ # teams: []
.github/workflows/generate_release-changelog.yaml ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Create Release
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
7
+
8
+ jobs:
9
+ build:
10
+ name: Create Release
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - name: Checkout code
14
+ uses: actions/checkout@v2
15
+ with:
16
+ fetch-depth: 0
17
+ - name: Changelog
18
+ uses: Bullrich/generate-release-changelog@master
19
+ id: Changelog
20
+ env:
21
+ REPO: ${{ github.repository }}
22
+ - name: Create Release
23
+ id: create_release
24
+ uses: actions/create-release@latest
25
+ env:
26
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
27
+ with:
28
+ tag_name: ${{ github.ref }}
29
+ release_name: Release ${{ github.ref }}
30
+ body: |
31
+ ${{ steps.Changelog.outputs.changelog }}
32
+ draft: false
33
+ prerelease: false
.github/workflows/update_space.yml ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Run Python script
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+
8
+ jobs:
9
+ build:
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - name: Checkout
14
+ uses: actions/checkout@v2
15
+
16
+ - name: Set up Python
17
+ uses: actions/setup-python@v2
18
+ with:
19
+ python-version: '3.9'
20
+
21
+ - name: Install Gradio
22
+ run: python -m pip install gradio
23
+
24
+ - name: Log in to Hugging Face
25
+ run: python -c 'import huggingface_hub; huggingface_hub.login(token="${{ secrets.hf_token }}")'
26
+
27
+ - name: Deploy to Spaces
28
+ run: gradio deploy
.gitignore ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ !*.py
2
+ !*.json
3
+ !*.yaml
4
+ !*.template
5
+ *.pyc
6
+ **/__pycache__/
7
+ test.py
8
+ public/*
9
+ !public/white_reddit_template.png
10
+ !public/subscribe-animation.mp4
11
+ z_doc/*
12
+ z_other/*
13
+ videos/*
14
+ .logs/
15
+ .editing_assets/*
16
+ .database/api_db.json
17
+ .database/content_db.json
18
+ .database/asset_db.json
19
+ flagged/
20
+ .vscode
21
+ .env
22
+ ShortGPT.egg-info
23
+ dist
24
+ build
25
+ setup
26
+ test.ipynb
27
+ .venv/
28
+ MANIFEST.in
CHANGES.txt ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # CHANGES
2
+
3
+ ## Version 0.1.2
4
+ - Improving logs in content engines
5
+ ## Version 0.1.1
6
+ - Adding AssetType in AssetDatabase
7
+ - Adding ApiProvider in api_db
8
+ - Fixing pip libary missing editing_framework module, prompt_template module
9
+ ## Version 0.1.0
10
+ - Fixing the AssetDatabase when it's empty
11
+ ## Version 0.0.2
12
+ - Implemented the content_translation_engine; a multilingual video dubbing content engine. The source can be found at shortGPT/engine/content_translation_engine.py.
13
+ - Implemented the new EdgeTTS voice module; it can be found at shortgpt/audio/edge_voice_module.
14
+ - Added documentation which can be found under docs/.
LICENSE ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ShortGPT License
2
+
3
+ Depending on the type of your legal entity, you are granted permission to use ShortGPT for your project. Individuals and small companies are allowed to use ShortGPT to create videos for free (even commercial), while a company license is required for for-profit organizations of a certain size. This two-tier system was designed to ensure funding for this project while still allowing the source code to be available and the program to be free for most. Read below for the exact terms of use.
4
+
5
+ Free license
6
+ Company license
7
+
8
+ Free license
9
+
10
+ Copyright © 2023 ShortGPT
11
+ Eligibility
12
+
13
+ You are eligible to use ShortGPT for free if you are:
14
+
15
+ an individual
16
+ a for-profit organization with a gross revenue up to 314 159$ a year.
17
+ a non-profit or not-for-profit organization
18
+ evaluating whether ShortGPT is a good fit, and are not yet using it in a commercial way
19
+
20
+ Allowed use cases
21
+
22
+ Permission is hereby granted, free of charge, to any person eligible for the "Free license", to use the software non-commercially or commercially for the purpose of creating videos and images and to modify the software to their own liking, for the purpose of fulfilling their custom use case or to contribute bug fixes or improvements back to ShortGPT.
23
+ Disallowed use cases
24
+
25
+ It is not allowed to copy or modify ShortGPT code for the purpose of selling, renting, licensing, relicensing, or sublicensing your own derivate of ShortGPT.
26
+ Warranty notice
27
+
28
+ 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 non-infringement. In no event shall the author 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.
29
+ Support
30
+
31
+ Support is provided on a best-we-can-do basis via GitHub Issues and Discord.
32
+ Company license
33
+
34
+ You are required to obtain a company license to use ShortGPT if you are not within the group of entities eligible for a free license. This license will enable you to use ShortGPT for the allowed use cases specified in the free license, and give you access to prioritized support.
35
+ We will deduct 10% of the revenue generated from ShortGPT as part of the payment for the company license.
README.md CHANGED
@@ -1,13 +1,203 @@
1
  ---
2
- title: SHORTgpt
3
- emoji: 📚
4
- colorFrom: blue
5
- colorTo: gray
6
  sdk: gradio
7
- sdk_version: 4.37.2
8
- app_file: app.py
9
- pinned: false
10
- license: apache-2.0
11
  ---
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: sHORTgpt
3
+ app_file: runShortGPTColab.py
 
 
4
  sdk: gradio
5
+ sdk_version: 3.38.0
 
 
 
6
  ---
7
+ # 🚀🎬 ShortGPT
8
+ [![](https://dcbadge.vercel.app/api/server/uERx39ru3R?compact=true&style=flat)](https://discord.gg/uERx39ru3R)
9
+ [![Twitter](https://img.shields.io/twitter/url/https/twitter.com/rayventurahq.svg?style=social&label=Follow%20%40RayVentura)](https://twitter.com/RayVenturaHQ)
10
+ [![GitHub star chart](https://img.shields.io/github/stars/rayventura/shortgpt?style=social)](https://star-history.com/#rayventura/shortgpt)
11
+ <div align="center">
12
+ <img src="https://github.com/RayVentura/ShortGPT/assets/121462835/083c8dc3-bac5-42c1-a08d-3ff9686d18c5" alt="ShortGPT-logo" style="border-radius: 20px;" width="22%"/>
13
+ </div>
14
+ <div align="center">
15
+ <a href="https://discord.gg/uERx39ru3R">
16
+ <img src="https://img.shields.io/badge/discord-join%20chat-blue.svg" alt="Join our Discord" height="34">
17
+ </a>
18
+ </div>
19
 
20
+ <div align="center">
21
+ ⚡ Automating video and short content creation with AI ⚡
22
+ </div>
23
+
24
+ ## 🎥 Showcase ([Full video on YouTube](https://youtu.be/hpoSHq-ER8U))
25
+
26
+ https://github.com/RayVentura/ShortGPT/assets/121462835/a802faad-0fd7-4fcb-aa82-6365c27ea5fe
27
+ ## 🎥 Voice Dubbing
28
+
29
+
30
+ https://github.com/RayVentura/ShortGPT/assets/121462835/06f51b2d-f8b1-4a23-b299-55e0e18902ef
31
+
32
+ ## 🌟 Show Your Support
33
+ We hope you find ShortGPT helpful! If you do, let us know by giving us a star ⭐ on the repo. It's easy, just click on the 'Star' button at the top right of the page. Your support means a lot to us and keeps us motivated to improve and expand ShortGPT. Thank you and happy content creating! 🎉
34
+
35
+ [![GitHub star chart](https://img.shields.io/github/stars/rayventura/shortgpt?style=social)](https://github.com/RayVentura/ShortGPT/stargazers)
36
+ ## 🛠️ How it works
37
+ ![alt text](https://github.com/RayVentura/ShortGPT/assets/121462835/fcee74d4-f856-4481-949f-244558bf3bfa)
38
+ ## 📝 Introduction to ShortGPT
39
+ ShortGPT is a powerful framework for automating content creation. It simplifies video creation, footage sourcing, voiceover synthesis, and editing tasks.
40
+
41
+ - 🎞️ **Automated editing framework**: Streamlines the video creation process with an LLM oriented video editing language.
42
+
43
+ - 📃 **Scripts and Prompts**: Provides ready-to-use scripts and prompts for various LLM automated editing processes.
44
+
45
+ - 🗣️ **Voiceover / Content Creation**: Supports multiple languages including English 🇺🇸, Spanish 🇪🇸, Arabic 🇦🇪, French 🇫🇷, Polish 🇵🇱, German 🇩🇪, Italian 🇮🇹, and Portuguese 🇵🇹.
46
+
47
+ - 🔗 **Caption Generation**: Automates the generation of video captions.
48
+
49
+ - 🌐🎥 **Asset Sourcing**: Sources images and video footage from the internet, connecting with the web and Pexels API as necessary.
50
+
51
+ - 🧠 **Memory and persistency**: Ensures long-term persistency of automated editing variables with TinyDB.
52
+
53
+ ## 🚀 Quick Start: Run ShortGPT on Google Colab (https://colab.research.google.com/drive/1_2UKdpF6lqxCqWaAcZb3rwMVQqtbisdE?usp=sharing)
54
+
55
+ If you prefer not to install the prerequisites on your local system, you can use the Google Colab notebook. This option is free and requires no installation setup.
56
+
57
+ 1. Click on the link to the Google Colab notebook: [https://colab.research.google.com/drive/1_2UKdpF6lqxCqWaAcZb3rwMVQqtbisdE?usp=sharing](https://colab.research.google.com/drive/1_2UKdpF6lqxCqWaAcZb3rwMVQqtbisdE?usp=sharing)
58
+
59
+ 2. Once you're in the notebook, simply run the cells in order from top to bottom. You can do this by clicking on each cell and pressing the 'Play' button, or by using the keyboard . Enjoy using ShortGPT!
60
+
61
+ # Instructions for running shortGPT
62
+ This guide provides step-by-step instructions for installing ImageMagick and FFmpeg on your system, which are both required to do automated editing. Once installed, you can proceed to run `runShortGPT.py` successfully.
63
+
64
+ ## Prerequisites
65
+ Before you begin, ensure that you have the following prerequisites installed on your system:
66
+ - Python 3.x
67
+ - Pip (Python package installer)
68
+
69
+ ## Installation Steps
70
+ Follow the instructions below to install ImageMagick, FFmpeg, and clone the shortGPT repository:
71
+
72
+ ### Step 1: Install ImageMagick
73
+ 1. For `Windows` download the installer from the official ImageMagick website and follow the installation instructions.
74
+
75
+ [https://imagemagick.org/script/download.php](https://imagemagick.org/script/download.php)
76
+
77
+ 2. For Ubuntu/Debian-based systems, use the command:
78
+ ```
79
+ sudo apt-get install imagemagick
80
+ ```
81
+ Then run the following command to fix a moviepy Imagemagick policy.xml incompatibility problem:
82
+ ```
83
+ !sed -i '/<policy domain="path" rights="none" pattern="@\*"/d' /etc/ImageMagick-6/policy.xml
84
+ ```
85
+ 4. For macOS using Homebrew, use the command:
86
+ ```
87
+ brew install imagemagick
88
+ ```
89
+ 2. Verify the installation by running the following command:
90
+ ```
91
+ convert --version
92
+ ```
93
+ You should see the ImageMagick version information if the installation was successful.
94
+
95
+ ### Step 2: Install FFmpeg (REQUIRED FOR SHORTGPT TO WORK)
96
+ 1. For `Windows`Download the FFmpeg binaries from this Windows Installer (It will download ffmpeg, ffprobe and add it to your path).
97
+
98
+ [https://github.com/icedterminal/ffmpeg-installer/releases/tag/6.0.0.20230306](https://github.com/icedterminal/ffmpeg-installer/releases/tag/6.0.0.20230306)
99
+
100
+ 2. For macOS using Homebrew, use the command:
101
+ ```
102
+ brew install ffmpeg
103
+ ```
104
+ For Ubuntu/Debian-based systems, use the command:
105
+ ```
106
+ sudo apt-get install ffmpeg
107
+ ```
108
+ 2. Verify the installation by running the following command:
109
+ ```
110
+ ffmpeg -version
111
+ ```
112
+ You should see the FFmpeg version information if the installation was successful.
113
+
114
+ ### Step 3: Clone the shortGPT Repository
115
+
116
+ 1. Open a terminal or command prompt.
117
+ 2. Execute the following command to clone the shortGPT repository:
118
+ ```
119
+ git clone https://github.com/rayventura/shortgpt.git
120
+ ```
121
+
122
+ ### Step 4: Install Python Dependencies
123
+
124
+ 1. Open a terminal or command prompt.
125
+ 2. Navigate to the directory where `runShortGPT.py` is located (the cloned repo).
126
+ 3. Execute the following command to install the required Python dependencies:
127
+ ```
128
+ pip install -r requirements.txt
129
+ ```
130
+
131
+ This command will install the necessary packages specified in the `requirements.txt` file.
132
+
133
+ ## Running runShortGPT.py Web Interface
134
+
135
+ Once you have successfully installed ImageMagick, FFmpeg, and the Python dependencies, you can run `runShortGPT.py` by following these steps:
136
+
137
+ 1. Open a terminal or command prompt.
138
+ 2. Navigate to the directory where `runShortGPT.py` is located (the cloned repo).
139
+ 3. Execute the following command to run the script:
140
+ ```
141
+ python runShortGPT.py
142
+ ```
143
+ 4. After running the script, a Gradio interface should open at your local host on port 31415 (http://localhost:31415).
144
+
145
+ ## Putting API Keys
146
+ The ShortGPT UI needs you to input at least OpenAI and ElevenLabs api keys for running short automations. For video automations, you will also need to add a Pexels API.
147
+
148
+ Follow these steps to add your OpenAI and ElevenLabs API keys:
149
+
150
+ 1. Open [http://localhost:31415/?__theme=light](http://localhost:31415/?__theme=light) from a web browser.
151
+ 2. Click on the `config` tab located at the left side bar of the user interface.
152
+ 3. Add your `OPENAI API KEY` and `ELEVENLABS API KEY` in the corresponding input fields.
153
+ 4. Click `Save` to save your API keys.
154
+
155
+ That's it! You have successfully set up your API keys and can now utilize the functionality of ShortGPT in the Gradio interface.
156
+
157
+ ## Framework overview
158
+
159
+ - 🎬 The `ContentShortEngine` is designed for creating shorts, handling tasks from script generation to final rendering, including adding YouTube metadata.
160
+
161
+ - 🎥 The `ContentVideoEngine` is ideal for longer videos, taking care of tasks like generating audio, automatically sourcing background video footage, timing captions, and preparing background assets.
162
+
163
+ - 🎞️ The automated `EditingEngine`, using Editing Markup Language and JSON, breaks down the editing process into manageable and customizable blocks, comprehensible to Large Language Models.
164
+
165
+ 💡 ShortGPT offers customization options to suit your needs, from language selection to watermark addition.
166
+
167
+ 🔧 As a framework, ShortGPT is adaptable and flexible, offering the potential for efficient, creative content creation.
168
+
169
+ More documentation incomming, please be patient.
170
+
171
+
172
+ ## Technologies Used
173
+
174
+ ShortGPT utilizes the following technologies to power its functionality:
175
+
176
+ - **Moviepy**: Moviepy is used for video editing, allowing ShortGPT to make video editing and rendering
177
+
178
+ - **Openai**: Openai is used for automating the entire process, including generating scripts and prompts for LLM automated editing processes.
179
+
180
+ - **ElevenLabs**: ElevenLabs is used for voice synthesis, supporting multiple languages for voiceover creation.
181
+
182
+ - **Pexels**: Pexels is used for sourcing background footage, allowing ShortGPT to connect with the web and access a wide range of images and videos.
183
+
184
+ - **Bing Image**: Bing Image is used for sourcing images, providing a comprehensive database for ShortGPT to retrieve relevant visuals.
185
+
186
+ These technologies work together to provide a seamless and efficient experience in automating video and short content creation with AI.
187
+
188
+ ## 💁 Contributing
189
+
190
+ As an open-source project in a rapidly developing field, we are extremely open to contributions, whether it would be in the form of a new feature, improved infrastructure, or better documentation.
191
+
192
+ ## 🔗 Get in touch on Twitter 🐦
193
+
194
+ Keep up with the latest happenings, announcements, and insights about Short-GPT by checking out our Twitter accounts. Spark a conversation with our developer and the AI's own account for fascinating dialogues, latest news about the project, and more.
195
+
196
+ - **Developer**: Stay updated [@RayVentura](https://twitter.com/RayVenturaHQ). Deep-dive into behind-the-scenes, project news, and related topics from the person behind ShortGPT.
197
+
198
+ We're eager to interact with you and listen to your feedback, concepts, and experiences with Short-GPT. Come on board on Twitter and let's navigate the future of AI as a team! 💡🤖
199
+ <p align="center">
200
+ <a href="https://star-history.com/#RayVentura/ShortGPT&Date">
201
+ <img src="https://api.star-history.com/svg?repos=RayVentura/ShortGPT&type=Date" alt="Star History Chart">
202
+ </a>
203
+ </p>
assets/img/logo.png ADDED
docs/.gitignore ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Dependencies
2
+ /node_modules
3
+
4
+ # Production
5
+ /build
6
+
7
+ # Generated files
8
+ .docusaurus
9
+ .cache-loader
10
+
11
+ # Misc
12
+ .DS_Store
13
+ .env.local
14
+ .env.development.local
15
+ .env.test.local
16
+ .env.production.local
17
+
18
+ npm-debug.log*
19
+ yarn-debug.log*
20
+ yarn-error.log*
docs/README.md ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ # ShortGPT Documentation
2
+ # Installation
3
+
4
+ 1. `yarn install` in the root of this repository (two level above this directory).
5
+ 1. In this directory, do `yarn start`.
6
+ 1. A browser window will open up, pointing to the docs.
7
+
8
+ # Deployment
9
+
10
+ Vercel handles the deployment of this website.
docs/babel.config.js ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ module.exports = {
2
+ presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
3
+ };
docs/docs/how-to-install.mdx ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ title: Step-by-Step Guide to Installing ShortGPT
3
+ sidebar_label: Installation Guide
4
+ ---
5
+ import Tabs from '@theme/Tabs';
6
+ import TabItem from '@theme/TabItem';
7
+
8
+ # Launching Your ShortGPT Experience
9
+
10
+ This guide will walk you through the process of setting up your machine to run the **ShortGPT** library. The setup requires two key components, ImageMagick and FFmpeg. Follow the steps below to get these dependencies installed.
11
+
12
+ ## Before You Begin
13
+
14
+ Make sure you have the following installed on your machine:
15
+
16
+ - Python 3.x
17
+ - Pip (Python package installer)
18
+
19
+ ## Installation Process
20
+
21
+ Here are the steps to install ImageMagick, FFmpeg, and the ShortGPT library.
22
+
23
+ <Tabs groupId="operating-systems">
24
+ <TabItem value="win" label="Windows">
25
+
26
+ ### Step 1: Install ImageMagick
27
+
28
+ ImageMagick is a crucial component for ShortGPT. Download the installer from the official ImageMagick website. Click on the link below to get started.
29
+
30
+ > **[👉 Download ImageMagick Here 👈](https://imagemagick.org/script/download.php)**
31
+
32
+ After downloading, follow the installation instructions provided on the website.
33
+
34
+ ### Step 2: Install FFmpeg (Essential for ShortGPT)
35
+
36
+ FFmpeg is another key component for ShortGPT. Download the FFmpeg binaries from the link below:
37
+
38
+ > **[👉 Download FFmpeg Here (click on
39
+ FFmpeg_Full.msi ) 👈](https://github.com/icedterminal/ffmpeg-installer/releases/tag/6.0.0.20230306)**
40
+
41
+ The download will include ffmpeg and ffprobe and will add it to your path. Follow the installation instructions as guided.
42
+ <details open>
43
+ <summary><b>Step 3: Install ShortGPT Library</b></summary>
44
+
45
+ - Open a terminal or command prompt.
46
+ - Execute the following command:
47
+
48
+ ```bash
49
+ pip install --upgrade shortgpt
50
+ ```
51
+
52
+ </details>
53
+
54
+ </TabItem>
55
+
56
+ <TabItem value="mac" label="macOS">
57
+
58
+ ### Step 1: Install ImageMagick
59
+
60
+ Run the command below in your command line:
61
+
62
+ ```bash
63
+ brew install imagemagick
64
+ ```
65
+
66
+ ### Step 2: Install FFmpeg (Essential for ShortGPT)
67
+
68
+ Run the command below in your command line:
69
+
70
+ ```bash
71
+ brew install ffmpeg
72
+ ```
73
+
74
+ <details open>
75
+ <summary><b>Step 3: Install ShortGPT Library</b></summary>
76
+
77
+ - Open a terminal or command prompt.
78
+ - Execute the following command:
79
+
80
+ ```bash
81
+ pip install --upgrade shortgpt
82
+ ```
83
+
84
+ </details>
85
+
86
+ </TabItem>
87
+
88
+ <TabItem value="ubuntu" label="Ubuntu/Debian-based systems">
89
+
90
+ ### Step 1: Install ImageMagick
91
+
92
+ Execute the following command:
93
+
94
+ ```bash
95
+ sudo apt-get install imagemagick
96
+ ```
97
+
98
+ ### Step 2: Install FFmpeg
99
+
100
+ Execute the following command:
101
+
102
+ ```bash
103
+ sudo apt-get install ffmpeg
104
+ ```
105
+
106
+ <details open>
107
+ <summary><b>Step 3: Install ShortGPT Library</b></summary>
108
+
109
+ - Open a terminal or command prompt.
110
+ - Execute the following command:
111
+
112
+ ```bash
113
+ pip install --upgrade shortgpt
114
+ ```
115
+
116
+ </details>
117
+
118
+ </TabItem>
119
+ </Tabs>
120
+
121
+ And there you have it! Your machine is now ready to run ShortGPT. Dive into the world of automated video content creation with ShortGPT!
docs/docusaurus.config.js ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* eslint-disable @typescript-eslint/no-var-requires */
2
+ const darkCodeTheme = require('prism-react-renderer/themes/dracula');
3
+ const lightCodeTheme = require('prism-react-renderer/themes/github');
4
+
5
+ // With JSDoc @type annotations, IDEs can provide config autocompletion
6
+ /** @type {import('@docusaurus/types').DocusaurusConfig} */
7
+ (
8
+ module.exports = {
9
+ title: 'ShortGPT',
10
+ tagline:
11
+ 'Open-Source Framework for AI content automation',
12
+ url: 'https://dev.shortgpt.ai',
13
+ baseUrl: '/',
14
+ favicon: 'img/favicon.ico',
15
+ organizationName: 'RayVentura',
16
+ projectName: 'ShortGPT',
17
+ onBrokenLinks: 'throw',
18
+ onBrokenMarkdownLinks: 'throw',
19
+ presets: [
20
+ [
21
+ '@docusaurus/preset-classic',
22
+ /** @type {import('@docusaurus/preset-classic').Options} */
23
+ ({
24
+ docs: {
25
+ path: 'docs',
26
+ sidebarPath: 'sidebars.js',
27
+ editUrl:
28
+ 'https://github.com/RayVentura/ShortGPT/edit/stable/docs/',
29
+ versions: {
30
+ current: {
31
+ label: 'current',
32
+ },
33
+ },
34
+ lastVersion: 'current',
35
+ showLastUpdateAuthor: true,
36
+ showLastUpdateTime: true,
37
+ },
38
+ theme: {
39
+ customCss: require.resolve('./src/css/custom.css'),
40
+ },
41
+ }),
42
+ ],
43
+ ],
44
+ plugins: ['tailwind-loader'],
45
+ themeConfig:
46
+ /** @type {import('@docusaurus/preset-classic').ThemeConfig} */
47
+ ({
48
+
49
+ navbar: {
50
+ hideOnScroll: true,
51
+ logo: {
52
+ alt: 'ShortGPT',
53
+ src: 'img/logo.png',
54
+ },
55
+ items: [
56
+ // left
57
+ {
58
+ label: 'Docs',
59
+ to: 'docs/how-to-install',
60
+ position: 'right',
61
+ },
62
+ // right
63
+ {
64
+ type: 'docsVersionDropdown',
65
+ position: 'right',
66
+ },
67
+ {
68
+ href: 'https://github.com/RayVentura/ShortGPT',
69
+ position: 'right',
70
+ className: 'header-github-link',
71
+ },
72
+ ],
73
+ },
74
+ colorMode: {
75
+ defaultMode: 'light',
76
+ disableSwitch: false,
77
+ respectPrefersColorScheme: true,
78
+ },
79
+ announcementBar: {
80
+ content:
81
+ '⭐️ If you like ShortGPT, give it a star on <a target="_blank" rel="noopener noreferrer" href="https://github.com/rayventura/shortgpt">GitHub</a>! ⭐️',
82
+ },
83
+ footer: {
84
+ links: [
85
+ {
86
+ title: 'Docs',
87
+ items: [
88
+ {
89
+ label: 'Getting Started',
90
+ to: 'docs/how-to-install',
91
+ },
92
+
93
+ ],
94
+ },
95
+ {
96
+ title: 'ShortGPT',
97
+ items: [
98
+ {
99
+ label: 'Issues',
100
+ to: 'https://github.com/RayVentura/ShortGPT/issues',
101
+ },
102
+ ],
103
+ },
104
+ {
105
+ title: 'Community',
106
+ items: [
107
+ {
108
+ label: 'Discord',
109
+ to: 'https://discord.com/invite/bRTacwYrfX',
110
+ },
111
+ ],
112
+ },
113
+ {
114
+ title: 'Social',
115
+ items: [
116
+ {
117
+ label: 'GitHub',
118
+ to: 'https://github.com/RayVentura/ShortGPT',
119
+ },
120
+ {
121
+ label: 'Twitter',
122
+ to: 'https://twitter.com/RayVenturaHQ',
123
+ },
124
+ ],
125
+ },
126
+ ],
127
+ copyright: `ShortGPT ${new Date().getFullYear()}`,
128
+ },
129
+ prism: {
130
+ theme: lightCodeTheme,
131
+ darkTheme: darkCodeTheme,
132
+ },
133
+ }),
134
+ }
135
+ );
docs/package.json ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "shortgpt-documentation",
3
+ "version": "3.5.1",
4
+ "private": true,
5
+ "scripts": {
6
+ "build:clean": "rm -rf dist build .docusaurus node_modules",
7
+ "docusaurus": "docusaurus",
8
+ "start": "docusaurus start",
9
+ "build": "docusaurus build",
10
+ "swizzle": "docusaurus swizzle",
11
+ "deploy": "docusaurus deploy",
12
+ "clear": "docusaurus clear",
13
+ "serve": "docusaurus serve",
14
+ "write-translations": "docusaurus write-translations",
15
+ "write-heading-ids": "docusaurus write-heading-ids"
16
+ },
17
+ "dependencies": {
18
+ "@algolia/ui-library": "9.10.2",
19
+ "@docsearch/react": "3.5.1",
20
+ "@docusaurus/core": "2.4.1",
21
+ "@docusaurus/preset-classic": "2.4.1",
22
+ "@mdx-js/react": "^1.6.22",
23
+ "clsx": "^1.1.1",
24
+ "file-loader": "6.2.0",
25
+ "my-loaders": "file:plugins/my-loaders",
26
+ "postcss": "8.4.25",
27
+ "postcss-import": "15.0.0",
28
+ "postcss-preset-env": "7.8.2",
29
+ "prism-react-renderer": "1.2.1",
30
+ "react": "^18.2.0",
31
+ "react-dom": "^18.2.0",
32
+ "tailwind-loader": "file:plugins/tailwind-loader",
33
+ "url-loader": "4.1.1"
34
+ },
35
+ "devDependencies": {
36
+ "postcss-loader": "6.2.1",
37
+ "tailwindcss": "npm:@tailwindcss/postcss7-compat"
38
+ },
39
+ "browserslist": {
40
+ "production": [
41
+ ">0.5%",
42
+ "not dead",
43
+ "not op_mini all"
44
+ ],
45
+ "development": [
46
+ "last 1 chrome version",
47
+ "last 1 firefox version",
48
+ "last 1 safari version"
49
+ ]
50
+ }
51
+ }
docs/plugins/my-loaders/index.js ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ module.exports = function () {
2
+ return {
3
+ name: 'loaders',
4
+ configureWebpack() {
5
+ return {
6
+ module: {
7
+ rules: [
8
+ {
9
+ test: /\.(gif|png|jpe?g|svg)$/i,
10
+ exclude: /\.(mdx?)$/i,
11
+ use: ['file-loader', { loader: 'image-webpack-loader' }],
12
+ },
13
+ ],
14
+ },
15
+ };
16
+ },
17
+ };
18
+ };
docs/plugins/tailwind-loader/index.js ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* eslint-disable @typescript-eslint/no-var-requires */
2
+ module.exports = function () {
3
+ return {
4
+ name: 'postcss-tailwindcss-loader',
5
+ configurePostCss(postcssOptions) {
6
+ postcssOptions.plugins.push(
7
+ require('postcss-import'),
8
+ require('tailwindcss'),
9
+ require('postcss-preset-env')({
10
+ autoprefixer: {
11
+ flexbox: 'no-2009',
12
+ },
13
+ stage: 4,
14
+ })
15
+ );
16
+ return postcssOptions;
17
+ },
18
+ };
19
+ };
docs/sidebars.js ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /**
2
+ * Creating a sidebar enables you to:
3
+ * - create an ordered group of docs
4
+ * - render a sidebar for each doc of that group
5
+ * - provide next/previous navigation.
6
+ *
7
+ * The sidebars can be generated from the filesystem, or explicitly defined here.
8
+ *
9
+ * Create as many sidebars as you want.
10
+ */
11
+
12
+ module.exports = {
13
+ docs: [
14
+ {
15
+ type: 'category',
16
+ label: 'Introduction',
17
+ items: ['how-to-install'],
18
+ },
19
+ ],
20
+ };
docs/src/components/Home.js ADDED
@@ -0,0 +1,356 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { Hero } from '@algolia/ui-library';
2
+ import { useColorMode } from '@docusaurus/theme-common';
3
+ import { useBaseUrlUtils } from '@docusaurus/useBaseUrl';
4
+ import React from 'react';
5
+ import { Link } from 'react-router-dom';
6
+
7
+ function Home() {
8
+ const { withBaseUrl } = useBaseUrlUtils();
9
+ const { colorMode } = useColorMode();
10
+
11
+ React.useEffect(() => {
12
+ if (colorMode === 'dark') {
13
+ document.querySelector('html').classList.add('dark');
14
+ } else {
15
+ document.querySelector('html').classList.remove('dark');
16
+ }
17
+ }, [colorMode]);
18
+
19
+ function Header() {
20
+ return (
21
+ <Hero
22
+ id="hero"
23
+ title={
24
+ <>
25
+
26
+ <span className="hero-title text-4xl leading-10 font-extrabold text-blue-600 md:text-4xl lg:text-4xl md:leading-11 max-w-xs inline-block">
27
+ 🚀🎬 SHORTGPT
28
+ </span>
29
+ <span className="hero-title text-3xl leading-9 font-extrabold md:text-3xl lg:text-3xl md:leading-10 max-w-xxs inline-block">
30
+ Opensource AI Content Automation Framework
31
+ </span>
32
+ </>
33
+ }
34
+ background="cubes"
35
+ cta={[
36
+ <Link
37
+ key="get-started"
38
+ to="/docs/how-to-install"
39
+ className="inline-flex items-center justify-center px-6 py-3 border border-transparent text-base font-semibold rounded-full text-white bg-gradient-to-r from-purple-500 to-indigo-500 hover:from-purple-600 hover:to-indigo-600 hover:no-underline"
40
+ >
41
+ Get started
42
+ </Link>
43
+ ]}
44
+ />
45
+ );
46
+ }
47
+
48
+ function Description() {
49
+ return (
50
+ <>
51
+ {/* Description */}
52
+ <div className="py-8 overflow-hidden">
53
+ <div className="relative max-w-xl mx-auto px-4 md:px-6 lg:px-8 lg:max-w-screen-xl">
54
+ <div className="relative">
55
+ <h3 className="text-center text-3xl leading-8 font-extrabold tracking-tight md:text-4xl md:leading-10">
56
+ Automating video and short content creation with AI
57
+ </h3>
58
+ <p className="mt-4 max-w-3xl mx-auto text-center text-xl leading-7 text-description">
59
+ ShortGPT is a powerful framework for automating content creation. It simplifies video creation, footage sourcing, voiceover synthesis, and editing tasks.
60
+ </p>
61
+ </div>
62
+
63
+ <div className="pt-16">
64
+ <ul className="lg:grid lg:grid-cols-3 lg:col-gap-8 lg:row-gap-10">
65
+ <li>
66
+ <div className="flex">
67
+ <div className="flex-shrink-0">
68
+ <div className="flex items-center justify-center h-12 w-12 rounded-md bg-indigo-500 text-white">
69
+ <svg
70
+ viewBox="0 0 20 20"
71
+ fill="currentColor"
72
+ className="search w-6 h-6"
73
+ >
74
+ <path
75
+ fillRule="evenodd"
76
+ d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
77
+ clipRule="evenodd"
78
+ ></path>
79
+ </svg>
80
+ </div>
81
+ </div>
82
+ <div className="ml-4">
83
+ <h4 className="text-lg leading-6 font-medium">
84
+ Automated editing framework
85
+ </h4>
86
+ <p className="mt-2 text-base leading-6 text-description">
87
+ ShortGPT streamlines the video creation process with an LLM oriented video editing language, making it easier to automate editing tasks.
88
+ </p>
89
+ </div>
90
+ </div>
91
+ </li>
92
+ <li className="mt-10 lg:mt-0">
93
+ <div className="flex">
94
+ <div className="flex-shrink-0">
95
+ <div className="flex items-center justify-center h-12 w-12 rounded-md bg-indigo-500 text-white">
96
+ <svg
97
+ fill="none"
98
+ viewBox="0 0 24 24"
99
+ stroke="currentColor"
100
+ className="user-group w-6 h-6"
101
+ >
102
+ <path
103
+ strokeLinecap="round"
104
+ strokeLinejoin="round"
105
+ strokeWidth="2"
106
+ d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z"
107
+ ></path>
108
+ </svg>
109
+ </div>
110
+ </div>
111
+ <div className="ml-4">
112
+ <h4 className="text-lg leading-6 font-medium">
113
+ Voiceover / Content Creation
114
+ </h4>
115
+ <p className="mt-2 text-base leading-6 text-description">
116
+ ShortGPT supports multiple languages for voiceover synthesis, making it easy to create content in various languages.
117
+ </p>
118
+ </div>
119
+ </div>
120
+ </li>
121
+ <li className="mt-10 lg:mt-0">
122
+ <div className="flex">
123
+ <div className="flex-shrink-0">
124
+ <div className="flex items-center justify-center h-12 w-12 rounded-md bg-indigo-500 text-white">
125
+ <svg
126
+ fill="none"
127
+ viewBox="0 0 24 24"
128
+ stroke="currentColor"
129
+ className="device-mobile w-6 h-6"
130
+ >
131
+ <path
132
+ strokeLinecap="round"
133
+ strokeLinejoin="round"
134
+ strokeWidth="2"
135
+ d="M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z"
136
+ ></path>
137
+ </svg>
138
+ </div>
139
+ </div>
140
+ <div className="ml-4">
141
+ <h4 className="text-lg leading-6 font-medium">
142
+ Asset Sourcing
143
+ </h4>
144
+ <p className="mt-2 text-base leading-6 text-description">
145
+ ShortGPT can source images and video footage from the internet, allowing you to easily find and use relevant visuals.
146
+ </p>
147
+ </div>
148
+ </div>
149
+ </li>
150
+ </ul>
151
+ </div>
152
+ </div>
153
+ </div>
154
+
155
+ {/* How it works */}
156
+ <div className="diagonal-box py-16 bg-gray-200 overflow-hidden">
157
+ <div className="diagonal-content max-w-xl mx-auto px-4 md:px-6 lg:px-8 lg:max-w-screen-xl">
158
+ <div className="max-w-screen-xl mx-auto pt-6 px-4 md:px-6 lg:px-8">
159
+ <div className="max-w-4xl mx-auto text-center">
160
+ <h2 className="text-3xl leading-9 font-extrabold text-gray-900 md:text-4xl md:leading-10">
161
+ How it works
162
+ </h2>
163
+ <p className="mt-4 max-w-2xl text-xl leading-7 text-gray-500 lg:mx-auto">
164
+ ShortGPT is an AI-powered framework that automates the process of content creation, from script generation to asset sourcing and video editing.
165
+ </p>
166
+ </div>
167
+ </div>
168
+
169
+ <div className="py-16">
170
+ <div className="max-w-xl mx-auto px-4 md:px-6 lg:max-w-screen-lg lg:px-8 ">
171
+ <div className="lg:grid lg:grid-cols-3 lg:gap-8">
172
+ <div>
173
+ <div className="flex items-center justify-center">
174
+ <img
175
+ className="h-200"
176
+ src={withBaseUrl('img/assets/scraping.svg')}
177
+ width="190px"
178
+ height="220px"
179
+ />
180
+ </div>
181
+ <div className="mt-10 lg:mt-0 p-4">
182
+ <h5 className="text-lg leading-6 font-medium text-gray-900">
183
+ Automated Editing Framework
184
+ </h5>
185
+ <p className="mt-2 text-base leading-6 text-gray-600">
186
+ ShortGPT employs a heavy usage of LLMs and automated video editing libraries to streamline the video creation process (Ffmpeg, moviepy, ffprobe).
187
+ </p>
188
+ </div>
189
+ </div>
190
+ <div className="mt-10 lg:mt-0 p-4">
191
+ <div className="h-200 flex items-center justify-center">
192
+ <img
193
+ src={withBaseUrl('img/assets/configuration.svg')}
194
+ width="140px"
195
+ height="220px"
196
+ alt="Configuration of your crawler"
197
+ />
198
+ </div>
199
+ <div>
200
+ <h5 className="text-lg leading-6 font-medium text-gray-900">
201
+ Voiceover / Content Creation
202
+ </h5>
203
+ <p className="mt-2 text-base leading-6 text-gray-600">
204
+ ShortGPT integrates multiple neural voice synthesis engines (ElevenLabs, EdgeTTS), to allow human-like voice quality in the audio generated.
205
+ </p>
206
+ </div>
207
+ </div>
208
+ <div className="mt-10 lg:mt-0 p-4">
209
+ <div className="h-200 flex items-center justify-center">
210
+ <img
211
+ src={withBaseUrl('img/assets/implementation.svg')}
212
+ width="220px"
213
+ height="220px"
214
+ alt="Implementation on your website"
215
+ />
216
+ </div>
217
+ <div>
218
+ <h5 className="text-lg leading-6 font-medium text-gray-900">
219
+ Asset Sourcing
220
+ </h5>
221
+ <p className="mt-2 text-base leading-6 text-gray-600">
222
+ ShortGPT is equipped with an advanced asset sourcing module that can retrieve images and video footage from the internet. This feature allows for the easy incorporation of relevant visuals into the content (Pexels, youtube, and more soon).
223
+ </p>
224
+ </div>
225
+ </div>
226
+ </div>
227
+ </div>
228
+ </div>
229
+ </div>
230
+ </div>
231
+
232
+
233
+
234
+ {/* Powered by AI */}
235
+ <div className="py-16 bg-indigo-600 overflow-hidden lg:py-24">
236
+ <div className="text-center">
237
+ <h3 className="mt-2 text-3xl leading-8 font-extrabold text-white tracking-tight md:text-4xl md:leading-10">
238
+ Powered by AI
239
+ </h3>
240
+ </div>
241
+ <div className="relative max-w-xl mx-auto px-4 md:px-6 lg:px-8 lg:max-w-screen-xl">
242
+ <div className="relative lg:grid lg:grid-cols-2 lg:gap-8 lg:items-center">
243
+ <div className="relative">
244
+ <ul className="mt-10">
245
+ <li className="mt-10">
246
+ <div className="flex">
247
+ <div className="flex-shrink-0">
248
+ <div className="flex items-center justify-center h-12 w-12 rounded-md bg-white text-indigo-500">
249
+ <svg
250
+ fill="none"
251
+ viewBox="0 0 24 24"
252
+ stroke="currentColor"
253
+ className="chip w-6 h-6"
254
+ >
255
+ <path
256
+ strokeLinecap="round"
257
+ strokeLinejoin="round"
258
+ strokeWidth="2"
259
+ d="M9 3v2m6-2v2M9 19v2m6-2v2M5 9H3m2 6H3m18-6h-2m2 6h-2M7 19h10a2 2 0 002-2V7a2 2 0 00-2-2H7a2 2 0 00-2 2v10a2 2 0 002 2zM9 9h6v6H9V9z"
260
+ ></path>
261
+ </svg>
262
+ </div>
263
+ </div>
264
+ <div className="ml-4">
265
+ <h5 className="text-lg leading-6 font-medium text-white">
266
+ Automated Editing
267
+ </h5>
268
+ <p className="mt-2 text-base leading-6 text-gray-300">
269
+ ShortGPT automates the video editing process, making it faster and more efficient with the help of AI.
270
+ </p>
271
+ </div>
272
+ </div>
273
+ </li>
274
+ <li className="mt-10">
275
+ <div className="flex">
276
+ <div className="flex-shrink-0">
277
+ <div className="flex items-center justify-center h-12 w-12 rounded-md bg-white text-indigo-500">
278
+ <svg
279
+ fill="none"
280
+ viewBox="0 0 24 24"
281
+ stroke="currentColor"
282
+ className="chat w-6 h-6"
283
+ >
284
+ <path
285
+ strokeLinecap="round"
286
+ strokeLinejoin="round"
287
+ strokeWidth="2"
288
+ d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z"
289
+ ></path>
290
+ </svg>
291
+ </div>
292
+ </div>
293
+ <div className="ml-4">
294
+ <h5 className="text-lg leading-6 font-medium text-white">
295
+ Voiceover / Content Creation
296
+ </h5>
297
+ <p className="mt-2 text-base leading-6 text-gray-300">
298
+ ShortGPT supports multiple languages for voiceover synthesis, making it easy to create content in various languages.
299
+ </p>
300
+ </div>
301
+ </div>
302
+ </li>
303
+ </ul>
304
+ </div>
305
+
306
+ <div className="relative">
307
+ <ul className="mt-10">
308
+ <li className="mt-10">
309
+ <div className="flex">
310
+ <div className="flex-shrink-0">
311
+ <div className="flex items-center justify-center h-12 w-12 rounded-md bg-white text-indigo-500">
312
+ <svg
313
+ fill="none"
314
+ viewBox="0 0 24 24"
315
+ stroke="currentColor"
316
+ className="backspace w-6 h-6"
317
+ >
318
+ <path
319
+ strokeLinecap="round"
320
+ strokeLinejoin="round"
321
+ strokeWidth="2"
322
+ d="M12 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2M3 12l6.414 6.414a2 2 0 001.414.586H19a2 2 0 002-2V7a2 2 0 00-2-2h-8.172a2 2 0 00-1.414.586L3 12z"
323
+ ></path>
324
+ </svg>
325
+ </div>
326
+ </div>
327
+ <div className="ml-4">
328
+ <h5 className="text-lg leading-6 font-medium text-white">
329
+ Asset Sourcing
330
+ </h5>
331
+ <p className="mt-2 text-base leading-6 text-gray-300">
332
+ ShortGPT can source images and video footage from the internet, allowing you to easily find and use relevant visuals.
333
+ </p>
334
+ </div>
335
+ </div>
336
+ </li>
337
+ </ul>
338
+ </div>
339
+ </div>
340
+ </div>
341
+ </div>
342
+ </>
343
+ )
344
+ }
345
+
346
+
347
+
348
+ return (
349
+ <div id="tailwind">
350
+ <Header />
351
+ <Description />
352
+ </div>
353
+ );
354
+ }
355
+
356
+ export default Home;
docs/src/css/custom.css ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @import url(fragments.css);
2
+ @import 'tailwindcss/tailwind.css';
3
+
4
+ :root {
5
+ --ifm-font-size-base: 16px;
6
+ --ifm-code-font-size: 90%;
7
+ --ifm-background-color: var(--white);
8
+ --ifm-color-primary: var(--nebula-500);
9
+ --ifm-footer-background-color: var(--grey-100);
10
+ --ifm-menu-color-background-active: var(--ifm-color-emphasis-200);
11
+ }
12
+
13
+ html[data-theme='dark'] {
14
+ --ifm-font-base-color: #dee0f2;
15
+ --ifm-navbar-link-hover-color: #8b9dff;
16
+ --ifm-link-color: #8b9dff;
17
+ --ifm-menu-color-active: #8b9dff;
18
+ --ifm-background-color: #0a141c;
19
+ --ifm-footer-background-color: #0a141c;
20
+ --ifm-navbar-background-color: #21243d;
21
+ --ifm-menu-color-background-active: #21243d;
22
+ }
23
+
24
+ .docusaurus-highlight-code-line {
25
+ background-color: rgba(0, 0, 0, 0.1);
26
+ display: block;
27
+ margin: 0 calc(-1 * var(--ifm-pre-padding));
28
+ padding: 0 var(--ifm-pre-padding);
29
+ }
30
+
31
+ html[data-theme='dark'] .docusaurus-highlight-code-line {
32
+ background-color: rgba(0, 0, 0, 0.3);
33
+ }
34
+
35
+ .diagonal-box {
36
+ transform: skewY(-6deg);
37
+ }
38
+
39
+ .diagonal-content {
40
+ transform: skewY(6deg);
41
+ }
42
+
43
+ [class^='announcementBar'] {
44
+ z-index: 10;
45
+ }
46
+
47
+ .showcase {
48
+ background-color: #fff;
49
+ }
50
+
51
+ html[data-theme='dark'] .showcase {
52
+ background-color: #21243d;
53
+ }
54
+
55
+ .showcase-border {
56
+ border-color: rgba(243, 244, 246, 1);
57
+ }
58
+
59
+ html[data-theme='dark'] .showcase-border {
60
+ border-color: rgba(55, 65, 81, 1);
61
+ }
62
+
63
+ .text-description {
64
+ color: rgba(107, 114, 128, 1);
65
+ }
66
+
67
+ html[data-theme='dark'] .text-description {
68
+ color: rgba(209, 213, 219, 1);
69
+ }
70
+
71
+ /* apply */
72
+ #hero-apply {
73
+ z-index: -1;
74
+ background-image: linear-gradient(
75
+ var(--ifm-footer-background-color),
76
+ var(--ifm-navbar-background-color)
77
+ );
78
+ }
79
+
80
+ html[data-theme='dark'] #hero-apply {
81
+ background-image: linear-gradient(
82
+ var(--ifm-navbar-background-color),
83
+ var(--ifm-background-color)
84
+ );
85
+ }
86
+
87
+ html[data-theme='dark'] #hero-apply > div:first-child {
88
+ opacity: 0.4;
89
+ }
90
+
91
+ .apply-form {
92
+ background-image: linear-gradient(#fff, #f5f5fa);
93
+ max-width: 600px;
94
+ }
95
+
96
+ html[data-theme='dark'] .apply-form {
97
+ background-image: radial-gradient(
98
+ circle at 50% 0px,
99
+ rgb(72, 76, 122),
100
+ rgb(35, 38, 59)
101
+ );
102
+ }
103
+
104
+ .apply-text {
105
+ color: #36395a;
106
+ }
107
+
108
+ html[data-theme='dark'] .apply-text {
109
+ color: #fff;
110
+ }
111
+
112
+ /* index */
113
+ #hero {
114
+ background-image: linear-gradient(
115
+ var(--ifm-footer-background-color),
116
+ var(--ifm-navbar-background-color)
117
+ );
118
+ }
119
+
120
+ html[data-theme='dark'] #hero {
121
+ background-image: linear-gradient(
122
+ var(--ifm-navbar-background-color),
123
+ var(--ifm-background-color)
124
+ );
125
+ }
126
+
127
+ html[data-theme='dark'] #hero > div:first-child {
128
+ opacity: 0.4;
129
+ }
130
+
131
+ /**
132
+ * Hero component title overrides to match other heading styles
133
+ */
134
+ .hero-title {
135
+ color: rgb(28, 30, 33);
136
+ font-family: var(--ifm-heading-font-family);
137
+ }
138
+
139
+ html[data-theme='dark'] .hero-title {
140
+ color: rgb(227, 227, 227);
141
+ }
142
+
143
+
144
+ .apply-button:hover {
145
+ color: #000000;
146
+ }
147
+
148
+ /* GitHub */
149
+ .header-github-link:hover {
150
+ opacity: 0.6;
151
+ }
152
+
153
+ .header-github-link:before {
154
+ content: '';
155
+ width: 24px;
156
+ height: 24px;
157
+ display: flex;
158
+ background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
159
+ no-repeat;
160
+ }
161
+
162
+ html[data-theme='dark'] .header-github-link:before {
163
+ background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E")
164
+ no-repeat;
165
+ }
166
+
167
+ /* Images */
168
+ .image-rendering-crisp {
169
+ image-rendering: crisp-edges;
170
+
171
+ /* alias for google chrome */
172
+ image-rendering: -webkit-optimize-contrast;
173
+ }
174
+
175
+ .image-rendering-pixel {
176
+ image-rendering: pixelated;
177
+ }
178
+
179
+ /* Tailwindcss */
180
+
181
+ #tailwind dd,
182
+ #tailwind dt {
183
+ margin: 0;
184
+ }
185
+
186
+ #tailwind *,
187
+ #tailwind ::before,
188
+ #tailwind ::after {
189
+ border-width: 0;
190
+ border-style: solid;
191
+ }
192
+
193
+ #tailwind ol,
194
+ #tailwind ul {
195
+ list-style: none;
196
+ margin: 0;
197
+ padding: 0;
198
+ }
docs/src/css/fragments.css ADDED
@@ -0,0 +1,2275 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ :root {
2
+ --transparent: transparent;
3
+ --white: #fff;
4
+ --grey-900: #23263b;
5
+ --grey-800: #36395a;
6
+ --grey-700: #484c7a;
7
+ --grey-600: #5a5e9a;
8
+ --grey-500: #777aaf;
9
+ --grey-400: #9698c3;
10
+ --grey-300: #b6b7d5;
11
+ --grey-200: #d6d6e7;
12
+ --grey-100: #f5f5fa;
13
+ --grey-050: #fcfcfd;
14
+ --grey-000: #fff;
15
+ --pink-900: #59063d;
16
+ --pink-800: #88085c;
17
+ --pink-700: #b80979;
18
+ --pink-600: #e90a96;
19
+ --pink-500: #f82caa;
20
+ --pink-400: #fb5abc;
21
+ --pink-300: #fd89ce;
22
+ --pink-200: #feb9e2;
23
+ --pink-100: #ffeaf6;
24
+ --nebula-900: #141d61;
25
+ --nebula-800: #1e2b8f;
26
+ --nebula-700: #2b3cbb;
27
+ --nebula-600: #3c4fe0;
28
+ --nebula-500: #5468ff;
29
+ --nebula-400: #7c8aff;
30
+ --nebula-300: #a3acff;
31
+ --nebula-200: #cacfff;
32
+ --nebula-100: #f2f3ff;
33
+ --cyan-900: #00526c;
34
+ --cyan-800: #00769b;
35
+ --cyan-700: #009bcb;
36
+ --cyan-600: #0db7eb;
37
+ --cyan-500: #2cc8f7;
38
+ --cyan-400: #5adaff;
39
+ --cyan-300: #89e5ff;
40
+ --cyan-200: #b9efff;
41
+ --cyan-100: #e8faff;
42
+ --green-900: #005e36;
43
+ --green-800: #028950;
44
+ --green-700: #06b66c;
45
+ --green-600: #0de589;
46
+ --green-500: #5feb9e;
47
+ --green-400: #88f0b3;
48
+ --green-300: #aaf4c8;
49
+ --green-200: #c9f8de;
50
+ --green-100: #e6fcf3;
51
+ --orange-900: #963209;
52
+ --orange-800: #bf470a;
53
+ --orange-700: #e8600a;
54
+ --orange-600: #f78125;
55
+ --orange-500: #faa04b;
56
+ --orange-400: #fcbc73;
57
+ --orange-300: #fed59a;
58
+ --orange-200: #ffe9c3;
59
+ --orange-100: #fff9ec;
60
+ --red-900: #83111e;
61
+ --red-800: #ab1325;
62
+ --red-700: #d4142a;
63
+ --red-600: #ee243c;
64
+ --red-500: #f4495d;
65
+ --red-400: #f86e7e;
66
+ --red-300: #fc95a1;
67
+ --red-200: #febdc5;
68
+ --red-100: #ffe6e9;
69
+ --current: currentColor;
70
+ }
71
+ .uil-bgc-transparent {
72
+ background-color: transparent;
73
+ }
74
+ .uil-bgc-white {
75
+ background-color: #fff;
76
+ }
77
+ .uil-bgc-grey-900 {
78
+ background-color: #23263b;
79
+ }
80
+ .uil-bgc-grey-800 {
81
+ background-color: #36395a;
82
+ }
83
+ .uil-bgc-grey-200 {
84
+ background-color: #d6d6e7;
85
+ }
86
+ .hover\:uil-bgc-grey-100:focus,
87
+ .hover\:uil-bgc-grey-100:hover,
88
+ .uil-bgc-grey-100 {
89
+ background-color: #f5f5fa;
90
+ }
91
+ .uil-bgc-pink-200 {
92
+ background-color: #feb9e2;
93
+ }
94
+ .uil-bgc-nebula-500 {
95
+ background-color: #5468ff;
96
+ }
97
+ .uil-bgc-nebula-200 {
98
+ background-color: #cacfff;
99
+ }
100
+ .uil-bgc-green-200 {
101
+ background-color: #c9f8de;
102
+ }
103
+ .uil-bgc-orange-200 {
104
+ background-color: #ffe9c3;
105
+ }
106
+ .uil-bgc-red-600 {
107
+ background-color: #ee243c;
108
+ }
109
+ .uil-bgc-red-500 {
110
+ background-color: #f4495d;
111
+ }
112
+ .uil-bgc-current {
113
+ background-color: currentColor;
114
+ }
115
+ @media (min-width: 960px) {
116
+ .md\:uil-bgc-transparent {
117
+ background-color: transparent;
118
+ }
119
+ }
120
+ @media (min-width: 960px) {
121
+ .md\:uil-bgc-white {
122
+ background-color: #fff;
123
+ }
124
+ }
125
+ @media (min-width: 960px) {
126
+ .md\:uil-bgc-grey-900 {
127
+ background-color: #23263b;
128
+ }
129
+ }
130
+ .uil-bgp-center {
131
+ background-position: 50%;
132
+ }
133
+ .uil-bgp-bottom {
134
+ background-position: bottom;
135
+ }
136
+ .uil-bgr-no-repeat {
137
+ background-repeat: no-repeat;
138
+ }
139
+ @media (min-width: 960px) {
140
+ .md\:uil-bgr-no-repeat {
141
+ background-repeat: no-repeat;
142
+ }
143
+ }
144
+ .uil-bgs-cover {
145
+ background-size: cover;
146
+ }
147
+ .uil-bgs-contain {
148
+ background-size: contain;
149
+ }
150
+ @media (min-width: 960px) {
151
+ .md\:uil-bgs-contain {
152
+ background-size: contain;
153
+ }
154
+ }
155
+ @media (min-width: 1200px) {
156
+ .lg\:uil-bgs-cover {
157
+ background-size: cover;
158
+ }
159
+ }
160
+ .uil-bd-none {
161
+ border: none;
162
+ }
163
+ .uil-bdc-transparent {
164
+ border-color: transparent;
165
+ }
166
+ .uil-bdc-grey-800 {
167
+ border-color: #36395a;
168
+ }
169
+ .uil-bdc-grey-700 {
170
+ border-color: #484c7a;
171
+ }
172
+ .uil-bdc-grey-200 {
173
+ border-color: #d6d6e7;
174
+ }
175
+ .uil-bdc-grey-100 {
176
+ border-color: #f5f5fa;
177
+ }
178
+ .uil-bdc-pink-600 {
179
+ border-color: #e90a96;
180
+ }
181
+ .uil-bdc-nebula-500 {
182
+ border-color: #5468ff;
183
+ }
184
+ .uil-bdc-green-700 {
185
+ border-color: #06b66c;
186
+ }
187
+ .uil-bdc-orange-600 {
188
+ border-color: #f78125;
189
+ }
190
+ .uil-bdc-red-600 {
191
+ border-color: #ee243c;
192
+ }
193
+ @media (min-width: 960px) {
194
+ .md\:uil-bdc-transparent {
195
+ border-color: transparent;
196
+ }
197
+ }
198
+ @media (min-width: 960px) {
199
+ .md\:uil-bdc-white {
200
+ border-color: #fff;
201
+ }
202
+ }
203
+ @media (min-width: 960px) {
204
+ .md\:uil-bdc-grey-800 {
205
+ border-color: #36395a;
206
+ }
207
+ }
208
+ @media (min-width: 960px) {
209
+ .md\:uil-bdc-grey-200 {
210
+ border-color: #d6d6e7;
211
+ }
212
+ }
213
+ @media (min-width: 960px) {
214
+ .md\:uil-bdc-pink-600 {
215
+ border-color: #e90a96;
216
+ }
217
+ }
218
+ @media (min-width: 960px) {
219
+ .md\:uil-bdc-nebula-500 {
220
+ border-color: #5468ff;
221
+ }
222
+ }
223
+ @media (min-width: 960px) {
224
+ .md\:uil-bdc-green-700 {
225
+ border-color: #06b66c;
226
+ }
227
+ }
228
+ @media (min-width: 960px) {
229
+ .md\:uil-bdc-orange-600 {
230
+ border-color: #f78125;
231
+ }
232
+ }
233
+ @media (min-width: 960px) {
234
+ .md\:uil-bdc-red-600 {
235
+ border-color: #ee243c;
236
+ }
237
+ }
238
+ .uil-bdr-0 {
239
+ border-radius: 0;
240
+ }
241
+ .uil-bdr-2 {
242
+ border-radius: 2px;
243
+ }
244
+ .uil-bdr-4 {
245
+ border-radius: 4px;
246
+ }
247
+ .uil-bdr-6 {
248
+ border-radius: 6px;
249
+ }
250
+ .uil-bdr-8 {
251
+ border-radius: 8px;
252
+ }
253
+ .uil-bdr-20 {
254
+ border-radius: 20px;
255
+ }
256
+ .uil-bdr-max {
257
+ border-radius: 9999px;
258
+ }
259
+ @media (min-width: 960px) {
260
+ .md\:uil-bdr-4 {
261
+ border-radius: 4px;
262
+ }
263
+ }
264
+ .uil-bdtlr-0 {
265
+ border-top-left-radius: 0;
266
+ }
267
+ .uil-bdtlr-2 {
268
+ border-top-left-radius: 2px;
269
+ }
270
+ .uil-bdtlr-4 {
271
+ border-top-left-radius: 4px;
272
+ }
273
+ .uil-bdtlr-6 {
274
+ border-top-left-radius: 6px;
275
+ }
276
+ .uil-bdtlr-8 {
277
+ border-top-left-radius: 8px;
278
+ }
279
+ .uil-bdtlr-20 {
280
+ border-top-left-radius: 20px;
281
+ }
282
+ .uil-bdtrr-0 {
283
+ border-top-right-radius: 0;
284
+ }
285
+ .uil-bdtrr-2 {
286
+ border-top-right-radius: 2px;
287
+ }
288
+ .uil-bdtrr-4 {
289
+ border-top-right-radius: 4px;
290
+ }
291
+ .uil-bdtrr-6 {
292
+ border-top-right-radius: 6px;
293
+ }
294
+ .uil-bdtrr-8 {
295
+ border-top-right-radius: 8px;
296
+ }
297
+ .uil-bdtrr-20 {
298
+ border-top-right-radius: 20px;
299
+ }
300
+ .uil-bdblr-0 {
301
+ border-bottom-left-radius: 0;
302
+ }
303
+ .uil-bdblr-6 {
304
+ border-bottom-left-radius: 6px;
305
+ }
306
+ .uil-bdbrr-0 {
307
+ border-bottom-right-radius: 0;
308
+ }
309
+ .uil-bdbrr-6 {
310
+ border-bottom-right-radius: 6px;
311
+ }
312
+ @media (min-width: 960px) {
313
+ .md\:uil-bdbr-6 {
314
+ border-bottom-left-radius: 6px;
315
+ border-bottom-right-radius: 6px;
316
+ }
317
+ }
318
+ .uil-bds-solid {
319
+ border-style: solid;
320
+ }
321
+ @media (min-width: 960px) {
322
+ .md\:uil-bds-solid {
323
+ border-style: solid;
324
+ }
325
+ }
326
+ .uil-bdts-solid {
327
+ border-top-style: solid;
328
+ }
329
+ .uil-bdrs-solid {
330
+ border-right-style: solid;
331
+ }
332
+ .uil-bdbs-solid {
333
+ border-bottom-style: solid;
334
+ }
335
+ @media (min-width: 960px) {
336
+ .md\:uil-bdbs-solid {
337
+ border-bottom-style: solid;
338
+ }
339
+ }
340
+ .uil-bdw-0 {
341
+ border-width: 0;
342
+ }
343
+ .uil-bdw-1 {
344
+ border-width: 1px;
345
+ }
346
+ @media (min-width: 960px) {
347
+ .md\:uil-bdw-0 {
348
+ border-width: 0;
349
+ }
350
+ }
351
+ @media (min-width: 960px) {
352
+ .md\:uil-bdw-2 {
353
+ border-width: 2px;
354
+ }
355
+ }
356
+ @media (min-width: 960px) {
357
+ .md\:uil-bdlw-1 {
358
+ border-left-width: 1px;
359
+ }
360
+ }
361
+ .uil-bdtw-1 {
362
+ border-top-width: 1px;
363
+ }
364
+ .uil-bdtw-2 {
365
+ border-top-width: 2px;
366
+ }
367
+ @media (min-width: 960px) {
368
+ .md\:uil-bdtw-1 {
369
+ border-top-width: 1px;
370
+ }
371
+ }
372
+ .uil-bdrw-1 {
373
+ border-right-width: 1px;
374
+ }
375
+ .uil-bdbw-0 {
376
+ border-bottom-width: 0;
377
+ }
378
+ .uil-bdbw-1 {
379
+ border-bottom-width: 1px;
380
+ }
381
+ @media (min-width: 960px) {
382
+ .md\:uil-bdbw-1 {
383
+ border-bottom-width: 1px;
384
+ }
385
+ }
386
+ .uil-d-none {
387
+ display: none;
388
+ }
389
+ .uil-d-block {
390
+ display: block;
391
+ }
392
+ .uil-d-inline-block {
393
+ display: inline-block;
394
+ }
395
+ .uil-d-flex {
396
+ display: flex;
397
+ }
398
+ .uil-d-inline-flex {
399
+ display: inline-flex;
400
+ }
401
+ .uil-d-grid {
402
+ display: grid;
403
+ }
404
+ @media (min-width: 500px) {
405
+ .xs\:uil-d-block {
406
+ display: block;
407
+ }
408
+ }
409
+ @media (min-width: 768px) {
410
+ .sm\:uil-d-flex {
411
+ display: flex;
412
+ }
413
+ }
414
+ @media (min-width: 768px) {
415
+ .sm\:uil-d-grid {
416
+ display: grid;
417
+ }
418
+ }
419
+ @media (min-width: 960px) {
420
+ .md\:uil-d-none {
421
+ display: none;
422
+ }
423
+ }
424
+ @media (min-width: 960px) {
425
+ .md\:uil-d-block {
426
+ display: block;
427
+ }
428
+ }
429
+ @media (min-width: 960px) {
430
+ .md\:uil-d-flex {
431
+ display: flex;
432
+ }
433
+ }
434
+ @media (min-width: 960px) {
435
+ .md\:uil-d-grid {
436
+ display: grid;
437
+ }
438
+ }
439
+ @media (min-width: 1200px) {
440
+ .lg\:uil-d-none {
441
+ display: none;
442
+ }
443
+ }
444
+ @media (min-width: 1200px) {
445
+ .lg\:uil-d-block {
446
+ display: block;
447
+ }
448
+ }
449
+ @media (min-width: 1440px) {
450
+ .xl\:uil-d-inline-block {
451
+ display: inline-block;
452
+ }
453
+ }
454
+ .uil-m-0 {
455
+ margin: 0;
456
+ }
457
+ .uil-m-8 {
458
+ margin: 8px;
459
+ }
460
+ .uil-m-auto {
461
+ margin: auto;
462
+ }
463
+ @media (min-width: 960px) {
464
+ .md\:uil-m-0 {
465
+ margin: 0;
466
+ }
467
+ }
468
+ @media (min-width: 960px) {
469
+ .md\:uil-m-auto {
470
+ margin: auto;
471
+ }
472
+ }
473
+ .uil-ml-0 {
474
+ margin-left: 0;
475
+ }
476
+ .uil-ml-8 {
477
+ margin-left: 8px;
478
+ }
479
+ .uil-ml-12 {
480
+ margin-left: 12px;
481
+ }
482
+ .uil-ml-auto {
483
+ margin-left: auto;
484
+ }
485
+ @media (min-width: 500px) {
486
+ .xs\:uil-ml-24 {
487
+ margin-left: 24px;
488
+ }
489
+ }
490
+ @media (min-width: 768px) {
491
+ .sm\:uil-ml-12 {
492
+ margin-left: 12px;
493
+ }
494
+ }
495
+ @media (min-width: 768px) {
496
+ .sm\:uil-ml-24 {
497
+ margin-left: 24px;
498
+ }
499
+ }
500
+ @media (min-width: 960px) {
501
+ .md\:uil-ml-0 {
502
+ margin-left: 0;
503
+ }
504
+ }
505
+ @media (min-width: 960px) {
506
+ .md\:uil-ml-8 {
507
+ margin-left: 8px;
508
+ }
509
+ }
510
+ @media (min-width: 960px) {
511
+ .md\:uil-ml-50p {
512
+ margin-left: 50%;
513
+ }
514
+ }
515
+ @media (min-width: 960px) {
516
+ .md\:uil-ml-auto {
517
+ margin-left: auto;
518
+ }
519
+ }
520
+ @media (min-width: 1200px) {
521
+ .lg\:uil-ml-16 {
522
+ margin-left: 16px;
523
+ }
524
+ }
525
+ @media (min-width: 1200px) {
526
+ .lg\:uil-ml-48 {
527
+ margin-left: 48px;
528
+ }
529
+ }
530
+ @media (min-width: 1440px) {
531
+ .xl\:uil-ml-16 {
532
+ margin-left: 16px;
533
+ }
534
+ }
535
+ .uil-mt-0 {
536
+ margin-top: 0;
537
+ }
538
+ .uil-mt-4 {
539
+ margin-top: 4px;
540
+ }
541
+ .uil-mt-8 {
542
+ margin-top: 8px;
543
+ }
544
+ .uil-mt-12 {
545
+ margin-top: 12px;
546
+ }
547
+ .uil-mt-16 {
548
+ margin-top: 16px;
549
+ }
550
+ .uil-mt-20 {
551
+ margin-top: 20px;
552
+ }
553
+ .uil-mt-24 {
554
+ margin-top: 24px;
555
+ }
556
+ .uil-mt-32 {
557
+ margin-top: 32px;
558
+ }
559
+ .uil-mt-48 {
560
+ margin-top: 48px;
561
+ }
562
+ .uil-mt-80 {
563
+ margin-top: 80px;
564
+ }
565
+ @media (min-width: 500px) {
566
+ .xs\:uil-mt-0 {
567
+ margin-top: 0;
568
+ }
569
+ }
570
+ @media (min-width: 768px) {
571
+ .sm\:uil-mt-0 {
572
+ margin-top: 0;
573
+ }
574
+ }
575
+ @media (min-width: 960px) {
576
+ .md\:uil-mt-0 {
577
+ margin-top: 0;
578
+ }
579
+ }
580
+ @media (min-width: 960px) {
581
+ .md\:uil-mt-8 {
582
+ margin-top: 8px;
583
+ }
584
+ }
585
+ @media (min-width: 960px) {
586
+ .md\:uil-mt-12 {
587
+ margin-top: 12px;
588
+ }
589
+ }
590
+ @media (min-width: 960px) {
591
+ .md\:uil-mt-auto {
592
+ margin-top: auto;
593
+ }
594
+ }
595
+ @media (min-width: 1200px) {
596
+ .lg\:uil-mt-8 {
597
+ margin-top: 8px;
598
+ }
599
+ }
600
+ @media (min-width: 1200px) {
601
+ .lg\:uil-mt-12 {
602
+ margin-top: 12px;
603
+ }
604
+ }
605
+ @media (min-width: 1200px) {
606
+ .lg\:uil-mt-20 {
607
+ margin-top: 20px;
608
+ }
609
+ }
610
+ @media (min-width: 1200px) {
611
+ .lg\:uil-mt-48 {
612
+ margin-top: 48px;
613
+ }
614
+ }
615
+ @media (min-width: 1200px) {
616
+ .lg\:uil-mt-120 {
617
+ margin-top: 120px;
618
+ }
619
+ }
620
+ .uil-mr-0 {
621
+ margin-right: 0;
622
+ }
623
+ .uil-mr-4 {
624
+ margin-right: 4px;
625
+ }
626
+ .uil-mr-8 {
627
+ margin-right: 8px;
628
+ }
629
+ .uil-mr-16 {
630
+ margin-right: 16px;
631
+ }
632
+ .uil-mr-32 {
633
+ margin-right: 32px;
634
+ }
635
+ .uil-mr-auto {
636
+ margin-right: auto;
637
+ }
638
+ @media (min-width: 960px) {
639
+ .md\:uil-mr-0 {
640
+ margin-right: 0;
641
+ }
642
+ }
643
+ @media (min-width: 960px) {
644
+ .md\:uil-mr-8 {
645
+ margin-right: 8px;
646
+ }
647
+ }
648
+ @media (min-width: 960px) {
649
+ .md\:uil-mr-20 {
650
+ margin-right: 20px;
651
+ }
652
+ }
653
+ @media (min-width: 1200px) {
654
+ .lg\:uil-mr-12 {
655
+ margin-right: 12px;
656
+ }
657
+ }
658
+ .uil-mb-0 {
659
+ margin-bottom: 0;
660
+ }
661
+ .uil-mb-8 {
662
+ margin-bottom: 8px;
663
+ }
664
+ .uil-mb-12 {
665
+ margin-bottom: 12px;
666
+ }
667
+ .uil-mb-16 {
668
+ margin-bottom: 16px;
669
+ }
670
+ .uil-mb-20 {
671
+ margin-bottom: 20px;
672
+ }
673
+ .uil-mb-24 {
674
+ margin-bottom: 24px;
675
+ }
676
+ .uil-mb-48 {
677
+ margin-bottom: 48px;
678
+ }
679
+ @media (min-width: 768px) {
680
+ .sm\:uil-mb-0 {
681
+ margin-bottom: 0;
682
+ }
683
+ }
684
+ @media (min-width: 960px) {
685
+ .md\:uil-mb-0 {
686
+ margin-bottom: 0;
687
+ }
688
+ }
689
+ @media (min-width: 960px) {
690
+ .md\:uil-mb-16 {
691
+ margin-bottom: 16px;
692
+ }
693
+ }
694
+ @media (min-width: 960px) {
695
+ .md\:uil-mb-24 {
696
+ margin-bottom: 24px;
697
+ }
698
+ }
699
+ @media (min-width: 1200px) {
700
+ .lg\:uil-mb-20 {
701
+ margin-bottom: 20px;
702
+ }
703
+ }
704
+ @media (min-width: 1200px) {
705
+ .lg\:uil-mb-24 {
706
+ margin-bottom: 24px;
707
+ }
708
+ }
709
+ @media (min-width: 1200px) {
710
+ .lg\:uil-mb-80 {
711
+ margin-bottom: 80px;
712
+ }
713
+ }
714
+ .uil-mv-0 {
715
+ margin-top: 0;
716
+ margin-bottom: 0;
717
+ }
718
+ .uil-mv-8 {
719
+ margin-top: 8px;
720
+ margin-bottom: 8px;
721
+ }
722
+ .uil-mh-0 {
723
+ margin-left: 0;
724
+ margin-right: 0;
725
+ }
726
+ .uil-mh-auto {
727
+ margin-left: auto;
728
+ margin-right: auto;
729
+ }
730
+ @media (min-width: 960px) {
731
+ .md\:uil-mh-12 {
732
+ margin-left: 12px;
733
+ margin-right: 12px;
734
+ }
735
+ }
736
+ .uil-ov-visible {
737
+ overflow: visible;
738
+ }
739
+ .uil-ov-hidden {
740
+ overflow: hidden;
741
+ }
742
+ .uil-ov-auto {
743
+ overflow: auto;
744
+ }
745
+ @media (min-width: 960px) {
746
+ .md\:uil-ov-hidden {
747
+ overflow: hidden;
748
+ }
749
+ }
750
+ .uil-ovx-scroll {
751
+ overflow-x: scroll;
752
+ }
753
+ .uil-ovx-auto {
754
+ overflow-x: auto;
755
+ }
756
+ .uil-ovy-hidden {
757
+ overflow-y: hidden;
758
+ }
759
+ .uil-ovy-auto {
760
+ overflow-y: auto;
761
+ }
762
+ .uil-p-0 {
763
+ padding: 0;
764
+ }
765
+ .uil-p-8 {
766
+ padding: 8px;
767
+ }
768
+ .uil-p-12 {
769
+ padding: 12px;
770
+ }
771
+ .uil-p-20 {
772
+ padding: 20px;
773
+ }
774
+ .uil-p-24 {
775
+ padding: 24px;
776
+ }
777
+ .uil-p-48 {
778
+ padding: 48px;
779
+ }
780
+ @media (min-width: 960px) {
781
+ .md\:uil-p-48 {
782
+ padding: 48px;
783
+ }
784
+ }
785
+ .uil-pl-0 {
786
+ padding-left: 0;
787
+ }
788
+ .uil-pl-8 {
789
+ padding-left: 8px;
790
+ }
791
+ .uil-pl-12 {
792
+ padding-left: 12px;
793
+ }
794
+ .uil-pl-16 {
795
+ padding-left: 16px;
796
+ }
797
+ .uil-pl-24 {
798
+ padding-left: 24px;
799
+ }
800
+ .uil-pl-48 {
801
+ padding-left: 48px;
802
+ }
803
+ @media (min-width: 960px) {
804
+ .md\:uil-pl-24 {
805
+ padding-left: 24px;
806
+ }
807
+ }
808
+ @media (min-width: 960px) {
809
+ .md\:uil-pl-48 {
810
+ padding-left: 48px;
811
+ }
812
+ }
813
+ @media (min-width: 1200px) {
814
+ .lg\:uil-pl-32 {
815
+ padding-left: 32px;
816
+ }
817
+ }
818
+ @media (min-width: 1200px) {
819
+ .lg\:uil-pl-48 {
820
+ padding-left: 48px;
821
+ }
822
+ }
823
+ .uil-pt-0 {
824
+ padding-top: 0;
825
+ }
826
+ .uil-pt-12 {
827
+ padding-top: 12px;
828
+ }
829
+ .uil-pt-16 {
830
+ padding-top: 16px;
831
+ }
832
+ .uil-pt-24 {
833
+ padding-top: 24px;
834
+ }
835
+ .uil-pt-32 {
836
+ padding-top: 32px;
837
+ }
838
+ .uil-pt-48 {
839
+ padding-top: 48px;
840
+ }
841
+ @media (min-width: 960px) {
842
+ .md\:uil-pt-0 {
843
+ padding-top: 0;
844
+ }
845
+ }
846
+ @media (min-width: 960px) {
847
+ .md\:uil-pt-24 {
848
+ padding-top: 24px;
849
+ }
850
+ }
851
+ @media (min-width: 1200px) {
852
+ .lg\:uil-pt-24 {
853
+ padding-top: 24px;
854
+ }
855
+ }
856
+ @media (min-width: 1200px) {
857
+ .lg\:uil-pt-32 {
858
+ padding-top: 32px;
859
+ }
860
+ }
861
+ @media (min-width: 1200px) {
862
+ .lg\:uil-pt-48 {
863
+ padding-top: 48px;
864
+ }
865
+ }
866
+ @media (min-width: 1200px) {
867
+ .lg\:uil-pt-80 {
868
+ padding-top: 80px;
869
+ }
870
+ }
871
+ .uil-pr-0 {
872
+ padding-right: 0;
873
+ }
874
+ .uil-pr-8 {
875
+ padding-right: 8px;
876
+ }
877
+ .uil-pr-16 {
878
+ padding-right: 16px;
879
+ }
880
+ .uil-pr-24 {
881
+ padding-right: 24px;
882
+ }
883
+ .uil-pr-32 {
884
+ padding-right: 32px;
885
+ }
886
+ .uil-pr-48 {
887
+ padding-right: 48px;
888
+ }
889
+ .uil-pr-80 {
890
+ padding-right: 80px;
891
+ }
892
+ @media (min-width: 960px) {
893
+ .md\:uil-pr-0 {
894
+ padding-right: 0;
895
+ }
896
+ }
897
+ @media (min-width: 960px) {
898
+ .md\:uil-pr-24 {
899
+ padding-right: 24px;
900
+ }
901
+ }
902
+ @media (min-width: 960px) {
903
+ .md\:uil-pr-48 {
904
+ padding-right: 48px;
905
+ }
906
+ }
907
+ @media (min-width: 1200px) {
908
+ .lg\:uil-pr-8 {
909
+ padding-right: 8px;
910
+ }
911
+ }
912
+ @media (min-width: 1200px) {
913
+ .lg\:uil-pr-48 {
914
+ padding-right: 48px;
915
+ }
916
+ }
917
+ .uil-pb-0 {
918
+ padding-bottom: 0;
919
+ }
920
+ .uil-pb-12 {
921
+ padding-bottom: 12px;
922
+ }
923
+ .uil-pb-16 {
924
+ padding-bottom: 16px;
925
+ }
926
+ .uil-pb-24 {
927
+ padding-bottom: 24px;
928
+ }
929
+ .uil-pb-48 {
930
+ padding-bottom: 48px;
931
+ }
932
+ .uil-pb-80 {
933
+ padding-bottom: 80px;
934
+ }
935
+ @media (min-width: 960px) {
936
+ .md\:uil-pb-24 {
937
+ padding-bottom: 24px;
938
+ }
939
+ }
940
+ @media (min-width: 1200px) {
941
+ .lg\:uil-pb-24 {
942
+ padding-bottom: 24px;
943
+ }
944
+ }
945
+ @media (min-width: 1200px) {
946
+ .lg\:uil-pb-48 {
947
+ padding-bottom: 48px;
948
+ }
949
+ }
950
+ @media (min-width: 1200px) {
951
+ .lg\:uil-pb-80 {
952
+ padding-bottom: 80px;
953
+ }
954
+ }
955
+ @media (min-width: 1200px) {
956
+ .lg\:uil-pb-120 {
957
+ padding-bottom: 120px;
958
+ }
959
+ }
960
+ .uil-pv-8 {
961
+ padding-top: 8px;
962
+ padding-bottom: 8px;
963
+ }
964
+ .uil-pv-16 {
965
+ padding-top: 16px;
966
+ padding-bottom: 16px;
967
+ }
968
+ .uil-pv-20 {
969
+ padding-top: 20px;
970
+ padding-bottom: 20px;
971
+ }
972
+ .uil-pv-24 {
973
+ padding-top: 24px;
974
+ padding-bottom: 24px;
975
+ }
976
+ .uil-pv-32 {
977
+ padding-top: 32px;
978
+ padding-bottom: 32px;
979
+ }
980
+ .uil-pv-48 {
981
+ padding-top: 48px;
982
+ padding-bottom: 48px;
983
+ }
984
+ .uil-pv-80 {
985
+ padding-top: 80px;
986
+ padding-bottom: 80px;
987
+ }
988
+ @media (min-width: 960px) {
989
+ .md\:uil-pv-120 {
990
+ padding-top: 120px;
991
+ padding-bottom: 120px;
992
+ }
993
+ }
994
+ @media (min-width: 1200px) {
995
+ .lg\:uil-pv-32 {
996
+ padding-top: 32px;
997
+ padding-bottom: 32px;
998
+ }
999
+ }
1000
+ @media (min-width: 1200px) {
1001
+ .lg\:uil-pv-48 {
1002
+ padding-top: 48px;
1003
+ padding-bottom: 48px;
1004
+ }
1005
+ }
1006
+ @media (min-width: 1200px) {
1007
+ .lg\:uil-pv-120 {
1008
+ padding-top: 120px;
1009
+ padding-bottom: 120px;
1010
+ }
1011
+ }
1012
+ .uil-ph-0 {
1013
+ padding-left: 0;
1014
+ padding-right: 0;
1015
+ }
1016
+ .uil-ph-4 {
1017
+ padding-left: 4px;
1018
+ padding-right: 4px;
1019
+ }
1020
+ .uil-ph-8 {
1021
+ padding-left: 8px;
1022
+ padding-right: 8px;
1023
+ }
1024
+ .uil-ph-12 {
1025
+ padding-left: 12px;
1026
+ padding-right: 12px;
1027
+ }
1028
+ .uil-ph-16 {
1029
+ padding-left: 16px;
1030
+ padding-right: 16px;
1031
+ }
1032
+ .uil-ph-20 {
1033
+ padding-left: 20px;
1034
+ padding-right: 20px;
1035
+ }
1036
+ .uil-ph-24 {
1037
+ padding-left: 24px;
1038
+ padding-right: 24px;
1039
+ }
1040
+ .uil-ph-32 {
1041
+ padding-left: 32px;
1042
+ padding-right: 32px;
1043
+ }
1044
+ @media (min-width: 768px) {
1045
+ .sm\:uil-ph-16 {
1046
+ padding-left: 16px;
1047
+ padding-right: 16px;
1048
+ }
1049
+ }
1050
+ @media (min-width: 960px) {
1051
+ .md\:uil-ph-0 {
1052
+ padding-left: 0;
1053
+ padding-right: 0;
1054
+ }
1055
+ }
1056
+ @media (min-width: 960px) {
1057
+ .md\:uil-ph-20 {
1058
+ padding-left: 20px;
1059
+ padding-right: 20px;
1060
+ }
1061
+ }
1062
+ @media (min-width: 960px) {
1063
+ .md\:uil-ph-48 {
1064
+ padding-left: 48px;
1065
+ padding-right: 48px;
1066
+ }
1067
+ }
1068
+ @media (min-width: 1200px) {
1069
+ .lg\:uil-ph-20 {
1070
+ padding-left: 20px;
1071
+ padding-right: 20px;
1072
+ }
1073
+ }
1074
+ @media (min-width: 1200px) {
1075
+ .lg\:uil-ph-32 {
1076
+ padding-left: 32px;
1077
+ padding-right: 32px;
1078
+ }
1079
+ }
1080
+ @media (min-width: 1200px) {
1081
+ .lg\:uil-ph-48 {
1082
+ padding-left: 48px;
1083
+ padding-right: 48px;
1084
+ }
1085
+ }
1086
+ .uil-v-visible {
1087
+ visibility: visible;
1088
+ }
1089
+ .uil-v-hidden {
1090
+ visibility: hidden;
1091
+ }
1092
+ @media (min-width: 960px) {
1093
+ .md\:uil-v-visible {
1094
+ visibility: visible;
1095
+ }
1096
+ }
1097
+ @media (min-width: 960px) {
1098
+ .md\:uil-v-hidden {
1099
+ visibility: hidden;
1100
+ }
1101
+ }
1102
+ .hover\:uil-color-white:focus,
1103
+ .hover\:uil-color-white:hover,
1104
+ .uil-color-white {
1105
+ color: #fff;
1106
+ }
1107
+ .hover\:uil-color-grey-900:focus,
1108
+ .hover\:uil-color-grey-900:hover,
1109
+ .uil-color-grey-900 {
1110
+ color: #23263b;
1111
+ }
1112
+ .uil-color-grey-800 {
1113
+ color: #36395a;
1114
+ }
1115
+ .hover\:uil-color-grey-700:focus,
1116
+ .hover\:uil-color-grey-700:hover,
1117
+ .uil-color-grey-700 {
1118
+ color: #484c7a;
1119
+ }
1120
+ .hover\:uil-color-grey-600:focus,
1121
+ .hover\:uil-color-grey-600:hover,
1122
+ .uil-color-grey-600 {
1123
+ color: #5a5e9a;
1124
+ }
1125
+ .uil-color-grey-500 {
1126
+ color: #777aaf;
1127
+ }
1128
+ .hover\:uil-color-grey-400:focus,
1129
+ .hover\:uil-color-grey-400:hover,
1130
+ .uil-color-grey-400 {
1131
+ color: #9698c3;
1132
+ }
1133
+ .uil-color-grey-300 {
1134
+ color: #b6b7d5;
1135
+ }
1136
+ .hover\:uil-color-grey-200:focus,
1137
+ .hover\:uil-color-grey-200:hover,
1138
+ .uil-color-grey-200 {
1139
+ color: #d6d6e7;
1140
+ }
1141
+ .hover\:uil-color-grey-100:focus,
1142
+ .hover\:uil-color-grey-100:hover,
1143
+ .uil-color-grey-100 {
1144
+ color: #f5f5fa;
1145
+ }
1146
+ .uil-color-pink-600 {
1147
+ color: #e90a96;
1148
+ }
1149
+ .uil-color-nebula-500 {
1150
+ color: #5468ff;
1151
+ }
1152
+ .uil-color-green-700 {
1153
+ color: #06b66c;
1154
+ }
1155
+ .uil-color-orange-600 {
1156
+ color: #f78125;
1157
+ }
1158
+ .uil-color-red-600 {
1159
+ color: #ee243c;
1160
+ }
1161
+ .uil-color-red-500 {
1162
+ color: #f4495d;
1163
+ }
1164
+ .uil-color-current {
1165
+ color: currentColor;
1166
+ }
1167
+ .uil-fill-white {
1168
+ fill: #fff;
1169
+ }
1170
+ .uil-ai-center {
1171
+ align-items: center;
1172
+ }
1173
+ .uil-ai-end {
1174
+ align-items: flex-end;
1175
+ }
1176
+ @media (min-width: 768px) {
1177
+ .sm\:uil-ai-start {
1178
+ align-items: flex-start;
1179
+ }
1180
+ }
1181
+ @media (min-width: 960px) {
1182
+ .md\:uil-ai-start {
1183
+ align-items: flex-start;
1184
+ }
1185
+ }
1186
+ @media (min-width: 960px) {
1187
+ .md\:uil-ai-center {
1188
+ align-items: center;
1189
+ }
1190
+ }
1191
+ @media (min-width: 960px) {
1192
+ .md\:uil-ai-end {
1193
+ align-items: flex-end;
1194
+ }
1195
+ }
1196
+ @media (min-width: 1200px) {
1197
+ .lg\:uil-ai-end {
1198
+ align-items: flex-end;
1199
+ }
1200
+ }
1201
+ .uil-as-end {
1202
+ align-self: flex-end;
1203
+ }
1204
+ .uil-fxd-column {
1205
+ flex-direction: column;
1206
+ }
1207
+ .uil-fxd-row {
1208
+ flex-direction: row;
1209
+ }
1210
+ @media (min-width: 500px) {
1211
+ .xs\:uil-fxd-row {
1212
+ flex-direction: row;
1213
+ }
1214
+ }
1215
+ @media (min-width: 768px) {
1216
+ .sm\:uil-fxd-row {
1217
+ flex-direction: row;
1218
+ }
1219
+ }
1220
+ @media (min-width: 960px) {
1221
+ .md\:uil-fxd-column {
1222
+ flex-direction: column;
1223
+ }
1224
+ }
1225
+ @media (min-width: 960px) {
1226
+ .md\:uil-fxd-row {
1227
+ flex-direction: row;
1228
+ }
1229
+ }
1230
+ @media (min-width: 960px) {
1231
+ .md\:uil-fxd-row-reverse {
1232
+ flex-direction: row-reverse;
1233
+ }
1234
+ }
1235
+ .uil-fxg-0 {
1236
+ flex-grow: 0;
1237
+ }
1238
+ .uil-fxg-1 {
1239
+ flex-grow: 1;
1240
+ }
1241
+ @media (min-width: 960px) {
1242
+ .md\:uil-fxg-1 {
1243
+ flex-grow: 1;
1244
+ }
1245
+ }
1246
+ .uil-fxs-0 {
1247
+ flex-shrink: 0;
1248
+ }
1249
+ .uil-fxs-1 {
1250
+ flex-shrink: 1;
1251
+ }
1252
+ .uil-fx-1 {
1253
+ flex: 0 1 8.333333%;
1254
+ }
1255
+ .uil-fx-4 {
1256
+ flex: 0 1 33.333333%;
1257
+ }
1258
+ .uil-fx-5 {
1259
+ flex: 0 1 41.666667%;
1260
+ }
1261
+ .uil-fx-6 {
1262
+ flex: 0 1 50%;
1263
+ }
1264
+ .uil-fx-12 {
1265
+ flex: 0 1 100%;
1266
+ }
1267
+ @media (min-width: 960px) {
1268
+ .md\:uil-fx-5 {
1269
+ flex: 0 1 41.666667%;
1270
+ }
1271
+ }
1272
+ @media (min-width: 960px) {
1273
+ .md\:uil-fx-6 {
1274
+ flex: 0 1 50%;
1275
+ }
1276
+ }
1277
+ @media (min-width: 960px) {
1278
+ .md\:uil-fx-7 {
1279
+ flex: 0 1 58.333333%;
1280
+ }
1281
+ }
1282
+ @media (min-width: 960px) {
1283
+ .md\:uil-fx-9 {
1284
+ flex: 0 1 75%;
1285
+ }
1286
+ }
1287
+ .uil-jc-center {
1288
+ justify-content: center;
1289
+ }
1290
+ .uil-jc-end {
1291
+ justify-content: flex-end;
1292
+ }
1293
+ .uil-jc-between {
1294
+ justify-content: space-between;
1295
+ }
1296
+ .uil-jc-around {
1297
+ justify-content: space-around;
1298
+ }
1299
+ @media (min-width: 500px) {
1300
+ .xs\:uil-jc-center {
1301
+ justify-content: center;
1302
+ }
1303
+ }
1304
+ @media (min-width: 768px) {
1305
+ .sm\:uil-jc-start {
1306
+ justify-content: flex-start;
1307
+ }
1308
+ }
1309
+ @media (min-width: 768px) {
1310
+ .sm\:uil-jc-center {
1311
+ justify-content: center;
1312
+ }
1313
+ }
1314
+ @media (min-width: 960px) {
1315
+ .md\:uil-jc-start {
1316
+ justify-content: flex-start;
1317
+ }
1318
+ }
1319
+ @media (min-width: 960px) {
1320
+ .md\:uil-jc-center {
1321
+ justify-content: center;
1322
+ }
1323
+ }
1324
+ @media (min-width: 960px) {
1325
+ .md\:uil-jc-end {
1326
+ justify-content: flex-end;
1327
+ }
1328
+ }
1329
+ @media (min-width: 960px) {
1330
+ .md\:uil-jc-between {
1331
+ justify-content: space-between;
1332
+ }
1333
+ }
1334
+ @media (min-width: 960px) {
1335
+ .md\:uil-jc-around {
1336
+ justify-content: space-around;
1337
+ }
1338
+ }
1339
+ @media (min-width: 1200px) {
1340
+ .lg\:uil-jc-end {
1341
+ justify-content: flex-end;
1342
+ }
1343
+ }
1344
+ @media (min-width: 960px) {
1345
+ .md\:uil-gcstart-1 {
1346
+ grid-column-start: 1;
1347
+ }
1348
+ }
1349
+ @media (min-width: 960px) {
1350
+ .md\:uil-gcstart-2 {
1351
+ grid-column-start: 2;
1352
+ }
1353
+ }
1354
+ @media (min-width: 960px) {
1355
+ .md\:uil-gcend-3 {
1356
+ grid-column-end: 3;
1357
+ }
1358
+ }
1359
+ @media (min-width: 960px) {
1360
+ .md\:uil-grstart-1 {
1361
+ grid-row-start: 1;
1362
+ }
1363
+ }
1364
+ @media (min-width: 960px) {
1365
+ .md\:uil-grstart-2 {
1366
+ grid-row-start: 2;
1367
+ }
1368
+ }
1369
+ @media (min-width: 960px) {
1370
+ .md\:uil-grend-3 {
1371
+ grid-row-end: 3;
1372
+ }
1373
+ }
1374
+ @media (min-width: 960px) {
1375
+ .md\:uil-grend-4 {
1376
+ grid-row-end: 4;
1377
+ }
1378
+ }
1379
+ .uil-g-2 {
1380
+ grid-template-columns: repeat(2, 1fr);
1381
+ }
1382
+ @media (min-width: 768px) {
1383
+ .sm\:uil-g-2 {
1384
+ grid-template-columns: repeat(2, 1fr);
1385
+ }
1386
+ }
1387
+ @media (min-width: 768px) {
1388
+ .sm\:uil-g-3 {
1389
+ grid-template-columns: repeat(3, 1fr);
1390
+ }
1391
+ }
1392
+ @media (min-width: 768px) {
1393
+ .sm\:uil-g-4 {
1394
+ grid-template-columns: repeat(4, 1fr);
1395
+ }
1396
+ }
1397
+ @media (min-width: 768px) {
1398
+ .sm\:uil-g-5 {
1399
+ grid-template-columns: repeat(5, 1fr);
1400
+ }
1401
+ }
1402
+ @media (min-width: 768px) {
1403
+ .sm\:uil-g-6 {
1404
+ grid-template-columns: repeat(6, 1fr);
1405
+ }
1406
+ }
1407
+ @media (min-width: 960px) {
1408
+ .md\:uil-g-2 {
1409
+ grid-template-columns: repeat(2, 1fr);
1410
+ }
1411
+ }
1412
+ @media (min-width: 960px) {
1413
+ .md\:uil-g-3 {
1414
+ grid-template-columns: repeat(3, 1fr);
1415
+ }
1416
+ }
1417
+ @media (min-width: 960px) {
1418
+ .md\:uil-g-4 {
1419
+ grid-template-columns: repeat(4, 1fr);
1420
+ }
1421
+ }
1422
+ @media (min-width: 960px) {
1423
+ .md\:uil-g-5 {
1424
+ grid-template-columns: repeat(5, 1fr);
1425
+ }
1426
+ }
1427
+ @media (min-width: 960px) {
1428
+ .md\:uil-g-6 {
1429
+ grid-template-columns: repeat(6, 1fr);
1430
+ }
1431
+ }
1432
+ .uil-ggap-24 {
1433
+ grid-gap: 24px;
1434
+ }
1435
+ .uil-ggap-48 {
1436
+ grid-gap: 48px;
1437
+ }
1438
+ @media (min-width: 1200px) {
1439
+ .lg\:uil-ggap-24 {
1440
+ grid-gap: 24px;
1441
+ }
1442
+ }
1443
+ @media (min-width: 1200px) {
1444
+ .lg\:uil-ggap-32 {
1445
+ grid-gap: 32px;
1446
+ }
1447
+ }
1448
+ @media (min-width: 1200px) {
1449
+ .lg\:uil-ggap-48 {
1450
+ grid-gap: 48px;
1451
+ }
1452
+ }
1453
+ @media (min-width: 1200px) {
1454
+ .lg\:uil-ggap-80 {
1455
+ grid-gap: 80px;
1456
+ }
1457
+ }
1458
+ .uil-gvgap-8 {
1459
+ grid-column-gap: 8px;
1460
+ }
1461
+ @media (min-width: 768px) {
1462
+ .sm\:uil-gvgap-48 {
1463
+ grid-column-gap: 48px;
1464
+ }
1465
+ }
1466
+ .uil-ghgap-48 {
1467
+ grid-row-gap: 48px;
1468
+ }
1469
+ .uil-obf-contain {
1470
+ -o-object-fit: contain;
1471
+ object-fit: contain;
1472
+ }
1473
+ .uil-obf-cover {
1474
+ -o-object-fit: cover;
1475
+ object-fit: cover;
1476
+ }
1477
+ .uil-obp-center {
1478
+ -o-object-position: center;
1479
+ object-position: center;
1480
+ }
1481
+ .uil-bot-0 {
1482
+ bottom: 0;
1483
+ }
1484
+ .uil-bot-70 {
1485
+ bottom: 70px;
1486
+ }
1487
+ @media (min-width: 960px) {
1488
+ .md\:uil-bot-0 {
1489
+ bottom: 0;
1490
+ }
1491
+ }
1492
+ @media (min-width: 960px) {
1493
+ .md\:uil-fl-right {
1494
+ float: right;
1495
+ }
1496
+ }
1497
+ .uil-left-0 {
1498
+ left: 0;
1499
+ }
1500
+ .uil-left-50p {
1501
+ left: 50%;
1502
+ }
1503
+ @media (min-width: 960px) {
1504
+ .md\:uil-left-0 {
1505
+ left: 0;
1506
+ }
1507
+ }
1508
+ @media (min-width: 960px) {
1509
+ .md\:uil-left-50p {
1510
+ left: 50%;
1511
+ }
1512
+ }
1513
+ .uil-pos-relative {
1514
+ position: relative;
1515
+ }
1516
+ .uil-pos-absolute {
1517
+ position: absolute;
1518
+ }
1519
+ .uil-pos-fixed {
1520
+ position: fixed;
1521
+ }
1522
+ .uil-pos-sticky {
1523
+ position: sticky;
1524
+ }
1525
+ @media (min-width: 768px) {
1526
+ .sm\:uil-pos-absolute {
1527
+ position: absolute;
1528
+ }
1529
+ }
1530
+ @media (min-width: 960px) {
1531
+ .md\:uil-pos-relative {
1532
+ position: relative;
1533
+ }
1534
+ }
1535
+ @media (min-width: 960px) {
1536
+ .md\:uil-pos-absolute {
1537
+ position: absolute;
1538
+ }
1539
+ }
1540
+ @media (min-width: 960px) {
1541
+ .md\:uil-pos-fixed {
1542
+ position: fixed;
1543
+ }
1544
+ }
1545
+ @media (min-width: 960px) {
1546
+ .md\:uil-pos-sticky {
1547
+ position: sticky;
1548
+ }
1549
+ }
1550
+ .uil-right-0 {
1551
+ right: 0;
1552
+ }
1553
+ @media (min-width: 960px) {
1554
+ .md\:uil-right-0 {
1555
+ right: 0;
1556
+ }
1557
+ }
1558
+ @media (min-width: 960px) {
1559
+ .md\:uil-right-50p {
1560
+ right: 50%;
1561
+ }
1562
+ }
1563
+ .uil-top-0 {
1564
+ top: 0;
1565
+ }
1566
+ .uil-top-32 {
1567
+ top: 32px;
1568
+ }
1569
+ .uil-top-50p {
1570
+ top: 50%;
1571
+ }
1572
+ @media (min-width: 768px) {
1573
+ .sm\:uil-top-0 {
1574
+ top: 0;
1575
+ }
1576
+ }
1577
+ @media (min-width: 960px) {
1578
+ .md\:uil-top-0 {
1579
+ top: 0;
1580
+ }
1581
+ }
1582
+ @media (min-width: 960px) {
1583
+ .md\:uil-top-50p {
1584
+ top: 50%;
1585
+ }
1586
+ }
1587
+ .uil-va-middle {
1588
+ vertical-align: middle;
1589
+ }
1590
+ .uil-z-1 {
1591
+ z-index: 1;
1592
+ }
1593
+ .uil-z-2 {
1594
+ z-index: 2;
1595
+ }
1596
+ .uil-z-3 {
1597
+ z-index: 3;
1598
+ }
1599
+ .uil-z-4 {
1600
+ z-index: 4;
1601
+ }
1602
+ .uil-z-5 {
1603
+ z-index: 5;
1604
+ }
1605
+ .uil-z-max {
1606
+ z-index: 100;
1607
+ }
1608
+ @media (min-width: 960px) {
1609
+ .md\:uil-z-5 {
1610
+ z-index: 5;
1611
+ }
1612
+ }
1613
+ @media (min-width: 960px) {
1614
+ .md\:uil-z-max {
1615
+ z-index: 100;
1616
+ }
1617
+ }
1618
+ .uil-app-none {
1619
+ -webkit-appearance: none;
1620
+ -moz-appearance: none;
1621
+ appearance: none;
1622
+ }
1623
+ .uil-bxs-default {
1624
+ box-shadow: 0 5px 15px 0 rgba(37, 44, 97, 0.15),
1625
+ 0 2px 4px 0 rgba(93, 100, 148, 0.2);
1626
+ }
1627
+ .uil-bxs-large {
1628
+ box-shadow: 0 24px 41px 0 rgba(37, 44, 97, 0.13);
1629
+ }
1630
+ .uil-bxs-none {
1631
+ box-shadow: none;
1632
+ }
1633
+ @media (min-width: 960px) {
1634
+ .md\:uil-bxs-default {
1635
+ box-shadow: 0 5px 15px 0 rgba(37, 44, 97, 0.15),
1636
+ 0 2px 4px 0 rgba(93, 100, 148, 0.2);
1637
+ }
1638
+ }
1639
+ .uil-cursor-auto {
1640
+ cursor: auto;
1641
+ }
1642
+ .uil-cursor-pointer {
1643
+ cursor: pointer;
1644
+ }
1645
+ .uil-cursor-not-allowed {
1646
+ cursor: not-allowed;
1647
+ }
1648
+ .uil-op-0 {
1649
+ opacity: 0;
1650
+ }
1651
+ .uil-op-50p {
1652
+ opacity: 0.5;
1653
+ }
1654
+ .uil-op-40p {
1655
+ opacity: 0.4;
1656
+ }
1657
+ .uil-op-75p {
1658
+ opacity: 0.75;
1659
+ }
1660
+ .uil-op-100p {
1661
+ opacity: 1;
1662
+ }
1663
+ @media (min-width: 960px) {
1664
+ .md\:uil-op-0 {
1665
+ opacity: 0;
1666
+ }
1667
+ }
1668
+ @media (min-width: 960px) {
1669
+ .md\:uil-op-25p {
1670
+ opacity: 0.25;
1671
+ }
1672
+ }
1673
+ @media (min-width: 960px) {
1674
+ .md\:uil-op-100p {
1675
+ opacity: 1;
1676
+ }
1677
+ }
1678
+ .uil-pe-auto {
1679
+ pointer-events: auto;
1680
+ }
1681
+ .uil-pe-none {
1682
+ pointer-events: none;
1683
+ }
1684
+ @media (min-width: 960px) {
1685
+ .md\:uil-pe-none {
1686
+ pointer-events: none;
1687
+ }
1688
+ }
1689
+ .uil-us-none {
1690
+ -webkit-user-select: none;
1691
+ -moz-user-select: none;
1692
+ -ms-user-select: none;
1693
+ user-select: none;
1694
+ }
1695
+ .uil-h-0 {
1696
+ height: 0;
1697
+ }
1698
+ .uil-h-10 {
1699
+ height: 10px;
1700
+ }
1701
+ .uil-h-14 {
1702
+ height: 14px;
1703
+ }
1704
+ .uil-h-16 {
1705
+ height: 16px;
1706
+ }
1707
+ .uil-h-18 {
1708
+ height: 18px;
1709
+ }
1710
+ .uil-h-20 {
1711
+ height: 20px;
1712
+ }
1713
+ .uil-h-24 {
1714
+ height: 24px;
1715
+ }
1716
+ .uil-h-25 {
1717
+ height: 25px;
1718
+ }
1719
+ .uil-h-30 {
1720
+ height: 30px;
1721
+ }
1722
+ .uil-h-40 {
1723
+ height: 40px;
1724
+ }
1725
+ .uil-h-50 {
1726
+ height: 50px;
1727
+ }
1728
+ .uil-h-60 {
1729
+ height: 60px;
1730
+ }
1731
+ .uil-h-70 {
1732
+ height: 70px;
1733
+ }
1734
+ .uil-h-80 {
1735
+ height: 80px;
1736
+ }
1737
+ .uil-h-200 {
1738
+ height: 200px;
1739
+ }
1740
+ .uil-h-10p {
1741
+ height: 10%;
1742
+ }
1743
+ .uil-h-20p {
1744
+ height: 20%;
1745
+ }
1746
+ .uil-h-25p {
1747
+ height: 25%;
1748
+ }
1749
+ .uil-h-30p {
1750
+ height: 30%;
1751
+ }
1752
+ .uil-h-40p {
1753
+ height: 40%;
1754
+ }
1755
+ .uil-h-50p {
1756
+ height: 50%;
1757
+ }
1758
+ .uil-h-60p {
1759
+ height: 60%;
1760
+ }
1761
+ .uil-h-70p {
1762
+ height: 70%;
1763
+ }
1764
+ .uil-h-80p {
1765
+ height: 80%;
1766
+ }
1767
+ .uil-h-90p {
1768
+ height: 90%;
1769
+ }
1770
+ .uil-h-100p {
1771
+ height: 100%;
1772
+ }
1773
+ .uil-h-100vh {
1774
+ height: 100vh;
1775
+ }
1776
+ .uil-h-auto {
1777
+ height: auto;
1778
+ }
1779
+ @media (min-width: 960px) {
1780
+ .md\:uil-h-10 {
1781
+ height: 10px;
1782
+ }
1783
+ }
1784
+ @media (min-width: 960px) {
1785
+ .md\:uil-h-30 {
1786
+ height: 30px;
1787
+ }
1788
+ }
1789
+ @media (min-width: 960px) {
1790
+ .md\:uil-h-60p {
1791
+ height: 60%;
1792
+ }
1793
+ }
1794
+ @media (min-width: 960px) {
1795
+ .md\:uil-h-100p {
1796
+ height: 100%;
1797
+ }
1798
+ }
1799
+ @media (min-width: 960px) {
1800
+ .md\:uil-h-100vh {
1801
+ height: 100vh;
1802
+ }
1803
+ }
1804
+ @media (min-width: 960px) {
1805
+ .md\:uil-h-auto {
1806
+ height: auto;
1807
+ }
1808
+ }
1809
+ @media (min-width: 1200px) {
1810
+ .lg\:uil-h-18 {
1811
+ height: 18px;
1812
+ }
1813
+ }
1814
+ @media (min-width: 1200px) {
1815
+ .lg\:uil-h-20 {
1816
+ height: 20px;
1817
+ }
1818
+ }
1819
+ @media (min-width: 1200px) {
1820
+ .lg\:uil-h-24 {
1821
+ height: 24px;
1822
+ }
1823
+ }
1824
+ @media (min-width: 1200px) {
1825
+ .lg\:uil-h-30 {
1826
+ height: 30px;
1827
+ }
1828
+ }
1829
+ @media (min-width: 1200px) {
1830
+ .lg\:uil-h-40 {
1831
+ height: 40px;
1832
+ }
1833
+ }
1834
+ @media (min-width: 1200px) {
1835
+ .lg\:uil-h-70 {
1836
+ height: 70px;
1837
+ }
1838
+ }
1839
+ @media (min-width: 1200px) {
1840
+ .lg\:uil-h-80 {
1841
+ height: 80px;
1842
+ }
1843
+ }
1844
+ @media (min-width: 1200px) {
1845
+ .lg\:uil-h-100 {
1846
+ height: 100px;
1847
+ }
1848
+ }
1849
+ @media (min-width: 1200px) {
1850
+ .lg\:uil-h-100p {
1851
+ height: 100%;
1852
+ }
1853
+ }
1854
+ .uil-mah-100p {
1855
+ max-height: 100%;
1856
+ }
1857
+ .uil-mah-100vh {
1858
+ max-height: 100vh;
1859
+ }
1860
+ @media (min-width: 960px) {
1861
+ .md\:uil-mah-100p {
1862
+ max-height: 100%;
1863
+ }
1864
+ }
1865
+ .uil-maw-500 {
1866
+ max-width: 500px;
1867
+ }
1868
+ .uil-maw-700 {
1869
+ max-width: 700px;
1870
+ }
1871
+ .uil-maw-800 {
1872
+ max-width: 800px;
1873
+ }
1874
+ .uil-maw-1200 {
1875
+ max-width: 1200px;
1876
+ }
1877
+ .uil-maw-1440 {
1878
+ max-width: 1440px;
1879
+ }
1880
+ .uil-maw-35ch {
1881
+ max-width: 35ch;
1882
+ }
1883
+ .uil-maw-100p {
1884
+ max-width: 100%;
1885
+ }
1886
+ @media (min-width: 960px) {
1887
+ .md\:uil-maw-600 {
1888
+ max-width: 600px;
1889
+ }
1890
+ }
1891
+ @media (min-width: 960px) {
1892
+ .md\:uil-maw-900 {
1893
+ max-width: 900px;
1894
+ }
1895
+ }
1896
+ @media (min-width: 960px) {
1897
+ .md\:uil-maw-1200 {
1898
+ max-width: 1200px;
1899
+ }
1900
+ }
1901
+ @media (min-width: 960px) {
1902
+ .md\:uil-maw-100p {
1903
+ max-width: 100%;
1904
+ }
1905
+ }
1906
+ @media (min-width: 1200px) {
1907
+ .lg\:uil-maw-1200 {
1908
+ max-width: 1200px;
1909
+ }
1910
+ }
1911
+ .uil-miw-200 {
1912
+ min-width: 200px;
1913
+ }
1914
+ @media (min-width: 960px) {
1915
+ .md\:uil-miw-300 {
1916
+ min-width: 300px;
1917
+ }
1918
+ }
1919
+ .uil-w-10 {
1920
+ width: 10px;
1921
+ }
1922
+ .uil-w-14 {
1923
+ width: 14px;
1924
+ }
1925
+ .uil-w-16 {
1926
+ width: 16px;
1927
+ }
1928
+ .uil-w-18 {
1929
+ width: 18px;
1930
+ }
1931
+ .uil-w-20 {
1932
+ width: 20px;
1933
+ }
1934
+ .uil-w-25 {
1935
+ width: 25px;
1936
+ }
1937
+ .uil-w-30 {
1938
+ width: 30px;
1939
+ }
1940
+ .uil-w-40 {
1941
+ width: 40px;
1942
+ }
1943
+ .uil-w-50 {
1944
+ width: 50px;
1945
+ }
1946
+ .uil-w-60 {
1947
+ width: 60px;
1948
+ }
1949
+ .uil-w-100 {
1950
+ width: 100px;
1951
+ }
1952
+ .uil-w-200 {
1953
+ width: 200px;
1954
+ }
1955
+ .uil-w-50p {
1956
+ width: 50%;
1957
+ }
1958
+ .uil-w-70p {
1959
+ width: 70%;
1960
+ }
1961
+ .uil-w-80p {
1962
+ width: 80%;
1963
+ }
1964
+ .uil-w-100p {
1965
+ width: 100%;
1966
+ }
1967
+ .uil-w-auto {
1968
+ width: auto;
1969
+ }
1970
+ @media (min-width: 500px) {
1971
+ .xs\:uil-w-60p {
1972
+ width: 60%;
1973
+ }
1974
+ }
1975
+ @media (min-width: 500px) {
1976
+ .xs\:uil-w-70p {
1977
+ width: 70%;
1978
+ }
1979
+ }
1980
+ @media (min-width: 960px) {
1981
+ .md\:uil-w-10 {
1982
+ width: 10px;
1983
+ }
1984
+ }
1985
+ @media (min-width: 960px) {
1986
+ .md\:uil-w-30 {
1987
+ width: 30px;
1988
+ }
1989
+ }
1990
+ @media (min-width: 960px) {
1991
+ .md\:uil-w-400 {
1992
+ width: 400px;
1993
+ }
1994
+ }
1995
+ @media (min-width: 960px) {
1996
+ .md\:uil-w-40p {
1997
+ width: 40%;
1998
+ }
1999
+ }
2000
+ @media (min-width: 960px) {
2001
+ .md\:uil-w-50p {
2002
+ width: 50%;
2003
+ }
2004
+ }
2005
+ @media (min-width: 960px) {
2006
+ .md\:uil-w-60p {
2007
+ width: 60%;
2008
+ }
2009
+ }
2010
+ @media (min-width: 960px) {
2011
+ .md\:uil-w-70p {
2012
+ width: 70%;
2013
+ }
2014
+ }
2015
+ @media (min-width: 960px) {
2016
+ .md\:uil-w-100p {
2017
+ width: 100%;
2018
+ }
2019
+ }
2020
+ @media (min-width: 960px) {
2021
+ .md\:uil-w-auto {
2022
+ width: auto;
2023
+ }
2024
+ }
2025
+ @media (min-width: 1200px) {
2026
+ .lg\:uil-w-18 {
2027
+ width: 18px;
2028
+ }
2029
+ }
2030
+ @media (min-width: 1200px) {
2031
+ .lg\:uil-w-20 {
2032
+ width: 20px;
2033
+ }
2034
+ }
2035
+ @media (min-width: 1200px) {
2036
+ .lg\:uil-w-24 {
2037
+ width: 24px;
2038
+ }
2039
+ }
2040
+ @media (min-width: 1200px) {
2041
+ .lg\:uil-w-30 {
2042
+ width: 30px;
2043
+ }
2044
+ }
2045
+ @media (min-width: 1200px) {
2046
+ .lg\:uil-w-40 {
2047
+ width: 40px;
2048
+ }
2049
+ }
2050
+ @media (min-width: 1200px) {
2051
+ .lg\:uil-w-50 {
2052
+ width: 50px;
2053
+ }
2054
+ }
2055
+ @media (min-width: 1200px) {
2056
+ .lg\:uil-w-80 {
2057
+ width: 80px;
2058
+ }
2059
+ }
2060
+ @media (min-width: 1200px) {
2061
+ .lg\:uil-w-200 {
2062
+ width: 200px;
2063
+ }
2064
+ }
2065
+ @media (min-width: 1200px) {
2066
+ .lg\:uil-w-50p {
2067
+ width: 50%;
2068
+ }
2069
+ }
2070
+ @media (min-width: 1200px) {
2071
+ .lg\:uil-w-70p {
2072
+ width: 70%;
2073
+ }
2074
+ }
2075
+ @media (min-width: 1200px) {
2076
+ .lg\:uil-w-80p {
2077
+ width: 80%;
2078
+ }
2079
+ }
2080
+ @media (min-width: 1200px) {
2081
+ .lg\:uil-w-90p {
2082
+ width: 90%;
2083
+ }
2084
+ }
2085
+ @media (min-width: 1200px) {
2086
+ .lg\:uil-w-100p {
2087
+ width: 100%;
2088
+ }
2089
+ }
2090
+ .uil-ff-hind {
2091
+ font-family: Hind, Arial, sans-serif;
2092
+ }
2093
+ .uil-ff-poppins {
2094
+ font-family: Poppins, Arial, sans-serif;
2095
+ }
2096
+ .uil-ff-mono {
2097
+ font-family: SFMono-Regular, Consolas, Andale Mono WT, Andale Mono,
2098
+ Lucida Console, Lucida Sans Typewriter, DejaVu Sans Mono,
2099
+ Bitstream Vera Sans Mono, Liberation Mono, Nimbus Mono L, Monaco,
2100
+ Courier New, Courier, monospace;
2101
+ }
2102
+ @media (min-width: 1200px) {
2103
+ .lg\:uil-ff-hind {
2104
+ font-family: Hind, Arial, sans-serif;
2105
+ }
2106
+ }
2107
+ .uil-fsz-10 {
2108
+ font-size: 10px;
2109
+ }
2110
+ .uil-fsz-11 {
2111
+ font-size: 11px;
2112
+ }
2113
+ .uil-fsz-12 {
2114
+ font-size: 12px;
2115
+ }
2116
+ .uil-fsz-14 {
2117
+ font-size: 14px;
2118
+ }
2119
+ .uil-fsz-16 {
2120
+ font-size: 16px;
2121
+ }
2122
+ .uil-fsz-18 {
2123
+ font-size: 18px;
2124
+ }
2125
+ .uil-fsz-24 {
2126
+ font-size: 24px;
2127
+ }
2128
+ .uil-fsz-36 {
2129
+ font-size: 36px;
2130
+ }
2131
+ @media (min-width: 960px) {
2132
+ .md\:uil-fsz-16 {
2133
+ font-size: 16px;
2134
+ }
2135
+ }
2136
+ @media (min-width: 1200px) {
2137
+ .lg\:uil-fsz-12 {
2138
+ font-size: 12px;
2139
+ }
2140
+ }
2141
+ @media (min-width: 1200px) {
2142
+ .lg\:uil-fsz-14 {
2143
+ font-size: 14px;
2144
+ }
2145
+ }
2146
+ @media (min-width: 1200px) {
2147
+ .lg\:uil-fsz-16 {
2148
+ font-size: 16px;
2149
+ }
2150
+ }
2151
+ @media (min-width: 1200px) {
2152
+ .lg\:uil-fsz-18 {
2153
+ font-size: 18px;
2154
+ }
2155
+ }
2156
+ @media (min-width: 1200px) {
2157
+ .lg\:uil-fsz-24 {
2158
+ font-size: 24px;
2159
+ }
2160
+ }
2161
+ @media (min-width: 1200px) {
2162
+ .lg\:uil-fsz-36 {
2163
+ font-size: 36px;
2164
+ }
2165
+ }
2166
+ @media (min-width: 1200px) {
2167
+ .lg\:uil-fsz-56 {
2168
+ font-size: 56px;
2169
+ }
2170
+ }
2171
+ .uil-fst-normal {
2172
+ font-style: normal;
2173
+ }
2174
+ .uil-fw-light {
2175
+ font-weight: 300;
2176
+ }
2177
+ .uil-fw-normal {
2178
+ font-weight: 400;
2179
+ }
2180
+ .uil-fw-semibold {
2181
+ font-weight: 600;
2182
+ }
2183
+ .uil-fw-bold {
2184
+ font-weight: 700;
2185
+ }
2186
+ .uil-lsp-small {
2187
+ letter-spacing: -1px;
2188
+ }
2189
+ .uil-lsp-big {
2190
+ letter-spacing: 1.5px;
2191
+ }
2192
+ .uil-lsp-normal {
2193
+ letter-spacing: normal;
2194
+ }
2195
+ @media (min-width: 1200px) {
2196
+ .lg\:uil-lsp-medium {
2197
+ letter-spacing: 0.7px;
2198
+ }
2199
+ }
2200
+ .uil-lh-small {
2201
+ line-height: 1;
2202
+ }
2203
+ .uil-lh-big {
2204
+ line-height: 1.33;
2205
+ }
2206
+ .uil-lh-bigger {
2207
+ line-height: 1.78;
2208
+ }
2209
+ .uil-lis-none {
2210
+ list-style: none;
2211
+ }
2212
+ .uil-ta-left {
2213
+ text-align: left;
2214
+ }
2215
+ .uil-ta-center {
2216
+ text-align: center;
2217
+ }
2218
+ .uil-ta-right {
2219
+ text-align: right;
2220
+ }
2221
+ @media (min-width: 768px) {
2222
+ .sm\:uil-ta-left {
2223
+ text-align: left;
2224
+ }
2225
+ }
2226
+ @media (min-width: 960px) {
2227
+ .md\:uil-ta-left {
2228
+ text-align: left;
2229
+ }
2230
+ }
2231
+ @media (min-width: 960px) {
2232
+ .md\:uil-ta-center {
2233
+ text-align: center;
2234
+ }
2235
+ }
2236
+ @media (min-width: 960px) {
2237
+ .md\:uil-ta-right {
2238
+ text-align: right;
2239
+ }
2240
+ }
2241
+ .hover\:uil-td-none:focus,
2242
+ .hover\:uil-td-none:hover,
2243
+ .uil-td-none {
2244
+ text-decoration: none;
2245
+ }
2246
+ @media (min-width: 960px) {
2247
+ .md\:uil-td-none {
2248
+ text-decoration: none;
2249
+ }
2250
+ }
2251
+ .uil-to-ellipsis {
2252
+ text-overflow: ellipsis;
2253
+ }
2254
+ @media (min-width: 1200px) {
2255
+ .lg\:uil-to-ellipsis {
2256
+ text-overflow: ellipsis;
2257
+ }
2258
+ }
2259
+ .uil-tt-upper {
2260
+ text-transform: uppercase;
2261
+ }
2262
+ .uil-tt-lower {
2263
+ text-transform: lowercase;
2264
+ }
2265
+ .uil-ws-nowrap {
2266
+ white-space: nowrap;
2267
+ }
2268
+ @media (min-width: 1200px) {
2269
+ .lg\:uil-ws-nowrap {
2270
+ white-space: nowrap;
2271
+ }
2272
+ }
2273
+ .uil-wb-break {
2274
+ word-break: break-word;
2275
+ }
docs/src/pages/index.js ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import Layout from '@theme/Layout';
2
+ import React from 'react';
3
+
4
+ import Home from '../components/Home';
5
+
6
+ function HomePage() {
7
+ return (
8
+ <Layout
9
+ title="ShortGPT: Automate Content Creation with AI"
10
+ description="Automating video and short content creation with AI "
11
+ >
12
+ <Home />
13
+ </Layout>
14
+ );
15
+ }
16
+
17
+ export default HomePage;
docs/static/img/assets/configuration.svg ADDED
docs/static/img/assets/implementation.svg ADDED
docs/static/img/assets/scraping.svg ADDED
docs/static/img/favicon.ico ADDED
docs/static/img/logo.png ADDED
docs/tailwind.config.js ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ module.exports = {
2
+ purge: ['./src/**/*.html', './src/**/*.js', './src/**/*.tsx'],
3
+ corePlugins: { preflight: false, container: false },
4
+ important: '#tailwind',
5
+ theme: {
6
+ extend: {
7
+ maxWidth: {
8
+ xxs: '18rem',
9
+ },
10
+ },
11
+ },
12
+ };
docs/yarn.lock ADDED
The diff for this file is too large to render. See raw diff
 
gui/asset_components.py ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import platform
3
+ import subprocess
4
+
5
+ import gradio as gr
6
+
7
+ from shortGPT.api_utils.eleven_api import ElevenLabsAPI
8
+ from shortGPT.config.api_db import ApiKeyManager
9
+ from shortGPT.config.asset_db import AssetDatabase
10
+
11
+
12
+ class AssetComponentsUtils:
13
+ EDGE_TTS = "Free EdgeTTS (lower quality)"
14
+ ELEVEN_TTS = "ElevenLabs(Very High Quality)"
15
+ instance_background_video_checkbox = None
16
+ instance_background_music_checkbox = None
17
+ instance_voiceChoice = None
18
+ instance_voiceChoiceTranslation = None
19
+
20
+ @classmethod
21
+ def getBackgroundVideoChoices(cls):
22
+ df = AssetDatabase.get_df()
23
+ choices = list(df.loc['background video' == df['type']]['name'])[:20]
24
+ return choices
25
+
26
+ @classmethod
27
+ def getBackgroundMusicChoices(cls):
28
+ df = AssetDatabase.get_df()
29
+ choices = list(df.loc['background music' == df['type']]['name'])[:20]
30
+ return choices
31
+
32
+ @classmethod
33
+ def getElevenlabsVoices(cls):
34
+ api_key = ApiKeyManager.get_api_key("ELEVEN LABS")
35
+ voices = list(reversed(ElevenLabsAPI(api_key).get_voices().keys()))
36
+ return voices
37
+
38
+ @classmethod
39
+ def start_file(cls, path):
40
+ if platform.system() == "Windows":
41
+ os.startfile(path)
42
+ elif platform.system() == "Darwin":
43
+ subprocess.Popen(["open", path])
44
+ else:
45
+ subprocess.Popen(["xdg-open", path])
46
+
47
+ @classmethod
48
+ def background_video_checkbox(cls):
49
+ if cls.instance_background_video_checkbox is None:
50
+ cls.instance_background_video_checkbox = gr.CheckboxGroup(
51
+ choices=cls.getBackgroundVideoChoices(),
52
+ interactive=True,
53
+ label="Choose background video",
54
+ )
55
+ return cls.instance_background_video_checkbox
56
+
57
+ @classmethod
58
+ def background_music_checkbox(cls):
59
+ if cls.instance_background_music_checkbox is None:
60
+ cls.instance_background_music_checkbox = gr.CheckboxGroup(
61
+ choices=cls.getBackgroundMusicChoices(),
62
+ interactive=True,
63
+ label="Choose background music",
64
+ )
65
+ return cls.instance_background_music_checkbox
66
+
67
+ @classmethod
68
+ def voiceChoice(cls):
69
+ if cls.instance_voiceChoice is None:
70
+ cls.instance_voiceChoice = gr.Radio(
71
+ cls.getElevenlabsVoices(),
72
+ label="Elevenlabs voice",
73
+ value="Antoni",
74
+ interactive=True,
75
+ )
76
+ return cls.instance_voiceChoice
77
+
78
+ @classmethod
79
+ def voiceChoiceTranslation(cls):
80
+ if cls.instance_voiceChoiceTranslation is None:
81
+ cls.instance_voiceChoiceTranslation = gr.Radio(
82
+ cls.getElevenlabsVoices(),
83
+ label="Elevenlabs voice",
84
+ value="Antoni",
85
+ interactive=True,
86
+ )
87
+ return cls.instance_voiceChoiceTranslation
gui/asset_library_ui.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ import re
3
+
4
+ import gradio as gr
5
+
6
+ from gui.asset_components import (background_music_checkbox,
7
+ background_video_checkbox,
8
+ getBackgroundMusicChoices,
9
+ getBackgroundVideoChoices)
10
+ from gui.ui_abstract_component import AbstractComponentUI
11
+ from shortGPT.config.asset_db import AssetDatabase
12
+
13
+
14
+ class AssetLibrary(AbstractComponentUI):
15
+ def __init__(self):
16
+ pass
17
+
18
+ def create_ui(self):
19
+ '''Create the asset library UI'''
20
+ with gr.Tab("Asset library") as asset_library_ui:
21
+ with gr.Column():
22
+ with gr.Accordion("Add your own video / audio / image", open=False) as accordion:
23
+ with gr.Column(visible=True):
24
+ asset_name = gr.Textbox(label="Name (required)")
25
+ asset_type = gr.Radio(["background video", "background music"], value="background video", label="Type")
26
+ youtube_url = gr.Textbox(label="URL (https://youtube.com/xyz)")
27
+ add_youtube_link = gr.Button("ADD")
28
+ with gr.Row():
29
+ with gr.Column(scale=3):
30
+ asset_dataframe_ui = gr.Dataframe(self.__fulfill_df, interactive=False)
31
+ with gr.Column(scale=2):
32
+ gr.Markdown("Preview")
33
+ asset_preview_ui = gr.HTML(self.__get_first_preview)
34
+ delete_button = gr.Button("🗑️ Delete", scale=0, variant="primary")
35
+ delete_button.click(self.__delete_clicked, [delete_button], [asset_dataframe_ui, asset_preview_ui, delete_button, background_video_checkbox, background_music_checkbox])
36
+ asset_dataframe_ui.select(self.__preview_asset, [asset_dataframe_ui], [asset_preview_ui, delete_button])
37
+ add_youtube_link.click(
38
+ self.__verify_youtube_asset_inputs, [asset_name, youtube_url, asset_type], []).success(self.__add_youtube_asset, [asset_name, youtube_url, asset_type], [asset_dataframe_ui, asset_preview_ui, delete_button, accordion, background_video_checkbox, background_music_checkbox])
39
+ return asset_library_ui
40
+
41
+ def __fulfill_df(self):
42
+ '''Get the asset dataframe'''
43
+ return AssetDatabase.get_df()
44
+
45
+ def __verify_youtube_asset_inputs(self, asset_name, yt_url, type):
46
+ if not asset_name or not re.match("^[A-Za-z0-9 _-]*$", asset_name):
47
+ raise gr.Error('Invalid asset name. Please provide a valid name that you will recognize (Only use letters and numbers)')
48
+ if not yt_url.startswith("https://youtube.com/") and not yt_url.startswith("https://www.youtube.com/"):
49
+ raise gr.Error('Invalid YouTube URL. Please provide a valid URL.')
50
+ if AssetDatabase.asset_exists(asset_name):
51
+ raise gr.Error('An asset already exists with this name, please choose a different name.')
52
+
53
+ def __add_youtube_asset(self, asset_name, yt_url, type):
54
+ '''Add a youtube asset'''
55
+ AssetDatabase.add_remote_asset(asset_name, type, yt_url)
56
+ latest_df = AssetDatabase.get_df()
57
+ return gr.DataFrame.update(value=latest_df), gr.HTML.update(value=self.__get_asset_embed(latest_df, 0)),\
58
+ gr.update(value=f"🗑️ Delete {latest_df.iloc[0]['name']}"),\
59
+ gr.Accordion.update(open=False),\
60
+ gr.CheckboxGroup.update(choices=getBackgroundVideoChoices(), interactive=True),\
61
+ gr.CheckboxGroup.update(choices=getBackgroundMusicChoices(), interactive=True)
62
+
63
+ def __get_first_preview(self):
64
+ '''Get the first preview'''
65
+ return self.__get_asset_embed(AssetDatabase.get_df(), 0)
66
+
67
+ def __delete_clicked(self, button_name):
68
+ '''Delete an asset'''
69
+ asset_name = button_name.split("🗑️ Delete ")[-1]
70
+ AssetDatabase.remove_asset(asset_name)
71
+ data = AssetDatabase.get_df()
72
+ if len(data) > 0:
73
+ return gr.update(value=data),\
74
+ gr.HTML.update(value=self.__get_asset_embed(data, 0)),\
75
+ gr.update(value=f"🗑️ Delete {data.iloc[0]['name']}"),\
76
+ gr.CheckboxGroup.update(choices=getBackgroundVideoChoices(), interactive=True),\
77
+ gr.CheckboxGroup.update(choices=getBackgroundMusicChoices(), interactive=True)
78
+ return gr.Dataframe.update(value=data),\
79
+ gr.HTML.update(visible=True),\
80
+ gr.Button.update(value="🗑️ Delete"),\
81
+ gr.CheckboxGroup.update(choices=getBackgroundVideoChoices(), interactive=True),\
82
+ gr.CheckboxGroup.update(choices=getBackgroundMusicChoices(), interactive=True)
83
+
84
+ def __preview_asset(self, data, evt: gr.SelectData):
85
+ '''Preview an asset'''
86
+ html_embed = self.__get_asset_embed(data, evt.index[0])
87
+ return gr.HTML.update(value=html_embed), gr.update(value=f"🗑️ Delete {data.iloc[evt.index[0]]['name']}")
88
+
89
+ def __get_asset_embed(self, data, row):
90
+ '''Get the asset embed'''
91
+ embed_height = 300
92
+ embed_width = 300
93
+ asset_link = data.iloc[row]['link']
94
+
95
+ if 'youtube.com' in asset_link:
96
+ asset_link = f"https://youtube.com/embed/{asset_link.split('?v=')[-1]}"
97
+ embed_html = f'<iframe width="{embed_width}" height="{embed_height}" src="{asset_link}"></iframe>'
98
+ elif 'public/' in asset_link:
99
+ asset_link = f"http://localhost:31415/file={asset_link}"
100
+ file_ext = asset_link.split('.')[-1]
101
+
102
+ if file_ext in ['mp3', 'wav', 'ogg']:
103
+ audio_type = 'audio/mpeg' if file_ext == 'mp3' else f'audio/{file_ext}'
104
+ embed_html = f'<audio controls><source src="{asset_link}" type="{audio_type}">Your browser does not support the audio tag.</audio>'
105
+ elif file_ext in ['mp4', 'webm', 'ogg', 'mov']:
106
+ video_type = 'video/mp4' if file_ext == 'mp4' else f'video/{file_ext}'
107
+ embed_html = f'<video width="{embed_width}" height="{embed_height}" style="max-height: 100%;" controls><source src="{asset_link}" type="{video_type}">Your browser does not support the video tag.</video>'
108
+ elif file_ext in ['jpg', 'jpeg', 'png', 'gif']:
109
+ embed_html = f'<img src="{asset_link}" width="{embed_width}" height="{embed_height}">'
110
+ else:
111
+ embed_html = 'Unsupported file type'
112
+ return embed_html
113
+
114
+ """
gui/content_automation_ui.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+
3
+ from gui.ui_tab_short_automation import ShortAutomationUI
4
+ from gui.ui_tab_video_automation import VideoAutomationUI
5
+ from gui.ui_tab_video_translation import VideoTranslationUI
6
+
7
+
8
+ class GradioContentAutomationUI:
9
+ def __init__(self, shortGPTUI):
10
+ self.shortGPTUI = shortGPTUI
11
+ self.content_automation_ui = None
12
+
13
+ def create_ui(self):
14
+ '''Create Gradio interface'''
15
+ with gr.Tab("Content Automation") as self.content_automation_ui:
16
+ gr.Markdown("# 🏆 Content Automation 🚀")
17
+ gr.Markdown("## Choose your desired automation task.")
18
+ choice = gr.Radio(['🎬 Automate the creation of shorts', '🎞️ Automate a video with stock assets', '🌐 Automate multilingual video dubbing'], label="Choose an option")
19
+ video_automation_ui = VideoAutomationUI(self.shortGPTUI).create_ui()
20
+ short_automation_ui = ShortAutomationUI(self.shortGPTUI).create_ui()
21
+ video_translation_ui = VideoTranslationUI(self.shortGPTUI).create_ui()
22
+ choice.change(lambda x: (gr.update(visible=x == choice.choices[1]), gr.update(visible=x == choice.choices[0]), gr.update(
23
+ visible=x == choice.choices[2])), [choice], [video_automation_ui, short_automation_ui, video_translation_ui])
24
+ return self.content_automation_ui
gui/gui_gradio.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+
3
+ from gui.content_automation_ui import GradioContentAutomationUI
4
+ from gui.ui_abstract_base import AbstractBaseUI
5
+ from gui.ui_components_html import GradioComponentsHTML
6
+ from gui.ui_tab_asset_library import AssetLibrary
7
+ from gui.ui_tab_config import ConfigUI
8
+ from shortGPT.utils.cli import CLI
9
+
10
+
11
+ class ShortGptUI(AbstractBaseUI):
12
+ '''Class for the GUI. This class is responsible for creating the UI and launching the server.'''
13
+
14
+ def __init__(self, colab=False):
15
+ super().__init__(ui_name='gradio_shortgpt')
16
+ self.colab = colab
17
+ CLI.display_header()
18
+
19
+ def create_interface(self):
20
+ '''Create Gradio interface'''
21
+ with gr.Blocks(css="footer {visibility: hidden}", title="ShortGPT Demo") as shortGptUI:
22
+ with gr.Row(variant='compact'):
23
+ gr.HTML(GradioComponentsHTML.get_html_header())
24
+
25
+ self.content_automation = GradioContentAutomationUI(shortGptUI).create_ui()
26
+ self.asset_library_ui = AssetLibrary().create_ui()
27
+ self.config_ui = ConfigUI().create_ui()
28
+ return shortGptUI
29
+
30
+ def launch(self):
31
+ '''Launch the server'''
32
+ shortGptUI = self.create_interface()
33
+ shortGptUI.queue(concurrency_count=5, max_size=20).launch(server_port=31415, height=1000, share=self.colab)
34
+
35
+
36
+ if __name__ == "__main__":
37
+ app = ShortGptUI()
38
+ app.launch()
gui/ui_abstract_base.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import gradio as gr
3
+
4
+
5
+ class AbstractBaseUI:
6
+ '''Base class for the GUI. This class is responsible for creating the UI and launching the server.'''
7
+ max_choices = 20
8
+ ui_asset_dataframe = gr.Dataframe(interactive=False)
9
+ LOGO_PATH = "http://localhost:31415/file=public/logo.png"
10
+ LOGO_DIM = 64
11
+
12
+ def __init__(self, ui_name='default'):
13
+ self.ui_name = ui_name
14
+ self.content_automation = None
15
+ self.asset_library_ui = None
16
+ self.config_ui = None
17
+
18
+ def create_interface(self):
19
+ raise NotImplementedError
gui/ui_abstract_component.py ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+
2
+
3
+ class AbstractComponentUI:
4
+ def create_ui(self):
5
+ raise NotImplementedError
gui/ui_components_html.py ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class GradioComponentsHTML:
2
+
3
+ @staticmethod
4
+ def get_html_header() -> str:
5
+ '''Create HTML for the header'''
6
+ return '''
7
+ <div style="display: flex; justify-content: space-between; align-items: center; padding: 5px;">
8
+ <h1 style="margin-left: 0px; font-size: 35px;">ShortGPT</h1>
9
+ <div style="flex-grow: 1; text-align: right;">
10
+ <a href="https://discord.gg/uERx39ru3R" target="_blank" style="text-decoration: none;">
11
+ <button style="margin-right: 10px; padding: 10px 20px; font-size: 16px; color: #fff; background-color: #7289DA; border: none; border-radius: 5px; cursor: pointer;">Join Discord</button>
12
+ </a>
13
+ <a href="https://github.com/RayVentura/ShortGPT" target="_blank" style="text-decoration: none;">
14
+ <button style="padding: 10px 20px; font-size: 16px; color: #fff; background-color: #333; border: none; border-radius: 5px; cursor: pointer;">Add a Star on Github ⭐</button>
15
+ </a>
16
+ </div>
17
+ </div>
18
+ '''
19
+
20
+ @staticmethod
21
+ def get_html_error_template() -> str:
22
+ return '''
23
+ <div style='text-align: center; background: #f2dede; color: #a94442; padding: 20px; border-radius: 5px; margin: 10px;'>
24
+ <h2 style='margin: 0;'>ERROR : {error_message}</h2>
25
+ <p style='margin: 10px 0;'>Traceback Info : {stack_trace}</p>
26
+ <p style='margin: 10px 0;'>If the problem persists, don't hesitate to contact our support. We're here to assist you.</p>
27
+ <a href='https://discord.gg/qn2WJaRH' target='_blank' style='background: #a94442; color: #fff; border: none; padding: 10px 20px; border-radius: 5px; cursor: pointer; text-decoration: none;'>Get Help on Discord</a>
28
+ </div>
29
+ '''
30
+
31
+ @staticmethod
32
+ def get_html_video_template(file_url_path, file_name, width="auto", height="auto"):
33
+ """
34
+ Generate an HTML code snippet for embedding and downloading a video.
35
+
36
+ Parameters:
37
+ file_url_path (str): The URL or path to the video file.
38
+ file_name (str): The name of the video file.
39
+ width (str, optional): The width of the video. Defaults to "auto".
40
+ height (str, optional): The height of the video. Defaults to "auto".
41
+
42
+ Returns:
43
+ str: The generated HTML code snippet.
44
+ """
45
+ html = f'''
46
+ <div style="display: flex; flex-direction: column; align-items: center;">
47
+ <video width="{width}" height="{height}" style="max-height: 100%;" controls>
48
+ <source src="{file_url_path}" type="video/mp4">
49
+ Your browser does not support the video tag.
50
+ </video>
51
+ <a href="{file_url_path}" download="{file_name}" style="margin-top: 10px;">
52
+ <button style="font-size: 1em; padding: 10px; border: none; cursor: pointer; color: white; background: #007bff;">Download Video</button>
53
+ </a>
54
+ </div>
55
+ '''
56
+ return html
gui/ui_tab_asset_library.py ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+ import shutil
4
+
5
+ import gradio as gr
6
+
7
+ from gui.asset_components import AssetComponentsUtils
8
+ from gui.ui_abstract_component import AbstractComponentUI
9
+ from shortGPT.config.asset_db import AssetDatabase, AssetType
10
+
11
+
12
+ class AssetLibrary(AbstractComponentUI):
13
+ def __init__(self):
14
+ pass
15
+
16
+ def create_ui(self):
17
+ '''Create the asset library UI'''
18
+ with gr.Tab("Asset library") as asset_library_ui:
19
+ with gr.Column():
20
+ with gr.Accordion("➕ Add your own local assets or from Youtube", open=False) as accordion:
21
+ remote = "Add youtube video / audio"
22
+ local = "Add local video / audio / image "
23
+ assetFlows = gr.Radio([remote, local], label="", value=remote)
24
+ with gr.Column(visible=True) as youtubeFlow:
25
+ asset_name = gr.Textbox(label="Name (required)")
26
+ asset_type = gr.Radio([AssetType.BACKGROUND_VIDEO.value, AssetType.BACKGROUND_MUSIC.value,], value=AssetType.BACKGROUND_VIDEO.value, label="Type")
27
+ youtube_url = gr.Textbox(label="URL (https://youtube.com/xyz)")
28
+ add_youtube_link = gr.Button("ADD")
29
+
30
+ with gr.Column(visible=False) as localFileFlow:
31
+ local_upload_name = gr.Textbox(label="Name (required)")
32
+ upload_type = gr.Radio([AssetType.BACKGROUND_VIDEO.value, AssetType.BACKGROUND_MUSIC.value, AssetType.IMAGE.value], value="background video", interactive=True, label="Type")
33
+ video_upload = gr.Video(visible=True, source="upload", type="filepath", interactive=True)
34
+ audio_upload = gr.Audio(visible=False, source="upload", type="filepath", interactive=True)
35
+ image_upload = gr.Image(visible=False, source="upload", type="filepath", interactive=True)
36
+ upload_button = gr.Button("ADD")
37
+ upload_type.change(lambda x: (gr.update(visible='video' in x),
38
+ gr.update(visible=any(type in x for type in ['audio', 'music'])),
39
+ gr.update(visible=x == 'image')),
40
+ [upload_type], [video_upload, audio_upload, image_upload])
41
+ assetFlows.change(lambda x: (gr.update(visible=x == remote), gr.update(visible=x == local)), [assetFlows], [youtubeFlow, localFileFlow])
42
+ with gr.Row():
43
+ with gr.Column(scale=3):
44
+ asset_dataframe_ui = gr.Dataframe(self.__fulfill_df, interactive=False)
45
+ video_choise = gr.Radio(["background video", "background music"], value="background video", label="Type")
46
+ with gr.Column(scale=2):
47
+ gr.Markdown("Preview")
48
+ asset_preview_ui = gr.HTML(self.__get_first_preview)
49
+ delete_button = gr.Button("🗑️ Delete", scale=0, variant="primary")
50
+ delete_button.click(self.__delete_clicked, [delete_button], [asset_dataframe_ui, asset_preview_ui, delete_button, AssetComponentsUtils.background_video_checkbox(), AssetComponentsUtils.background_music_checkbox()])
51
+ asset_dataframe_ui.select(self.__preview_asset, [asset_dataframe_ui], [asset_preview_ui, delete_button])
52
+
53
+ add_youtube_link.click(
54
+ self.__verify_youtube_asset_inputs, [asset_name, youtube_url, asset_type], []).success(self.__add_youtube_asset, [asset_name, youtube_url, asset_type], [asset_dataframe_ui, asset_preview_ui, delete_button, accordion, AssetComponentsUtils.background_video_checkbox(), AssetComponentsUtils.background_music_checkbox()]).success(lambda: gr.update(open=False), [accordion])
55
+
56
+ upload_button.click(
57
+ self.__verify_and_upload_local_asset, [upload_type, local_upload_name, video_upload, audio_upload, image_upload, ], []).success(self.__upload_local_asset, [upload_type, local_upload_name, video_upload, audio_upload, image_upload, ], [asset_dataframe_ui, asset_preview_ui, delete_button, accordion, AssetComponentsUtils.background_video_checkbox(), AssetComponentsUtils.background_music_checkbox()]).success(lambda: gr.update(open=False), [accordion])
58
+
59
+ return asset_library_ui
60
+
61
+ def __fulfill_df(self):
62
+ '''Get the dataframe of assets'''
63
+ return AssetDatabase.get_df()
64
+
65
+ def __verify_youtube_asset_inputs(self, asset_name, yt_url, type):
66
+ if not asset_name or not re.match("^[A-Za-z0-9 _-]*$", asset_name):
67
+ raise gr.Error('Invalid asset name. Please provide a valid name that you will recognize (Only use letters and numbers)')
68
+ if not yt_url.startswith("https://youtube.com/") and not yt_url.startswith("https://www.youtube.com/"):
69
+ raise gr.Error('Invalid YouTube URL. Please provide a valid URL.')
70
+ if AssetDatabase.asset_exists(asset_name):
71
+ raise gr.Error('An asset already exists with this name, please choose a different name.')
72
+
73
+ def __validate_asset_name(self, asset_name):
74
+ '''Validate asset name'''
75
+ if not asset_name or not re.match("^[A-Za-z0-9 _-]*$", asset_name):
76
+ raise gr.Error('Invalid asset name. Please provide a valid name that you will recognize (Only use letters and numbers)')
77
+ if AssetDatabase.asset_exists(asset_name):
78
+ raise gr.Error('An asset already exists with this name, please choose a different name.')
79
+
80
+ def __validate_youtube_url(self, yt_url):
81
+ '''Validate YouTube URL'''
82
+ if not yt_url.startswith("https://youtube.com/") and not yt_url.startswith("https://www.youtube.com/"):
83
+ raise gr.Error('Invalid YouTube URL. Please provide a valid URL.')
84
+
85
+ def __verify_and_add_youtube_asset(self, asset_name, yt_url, type):
86
+ '''Verify and add a youtube asset to the database'''
87
+ self.__validate_asset_name(asset_name)
88
+ self.__validate_youtube_url(yt_url)
89
+ return self.__add_youtube_asset(asset_name, yt_url, type)
90
+
91
+ def __add_youtube_asset(self, asset_name, yt_url, type):
92
+ '''Add a youtube asset'''
93
+ AssetDatabase.add_remote_asset(asset_name, AssetType(type), yt_url)
94
+ latest_df = AssetDatabase.get_df()
95
+ return gr.DataFrame.update(value=latest_df), gr.HTML.update(value=self.__get_asset_embed(latest_df, 0)),\
96
+ gr.update(value=f"🗑️ Delete {latest_df.iloc[0]['name']}"),\
97
+ gr.Accordion.update(open=False),\
98
+ gr.CheckboxGroup.update(choices=AssetComponentsUtils.getBackgroundVideoChoices(), interactive=True),\
99
+ gr.CheckboxGroup.update(choices=AssetComponentsUtils.getBackgroundMusicChoices(), interactive=True)
100
+
101
+ def __get_first_preview(self):
102
+ '''Get the first preview'''
103
+ return self.__get_asset_embed(AssetDatabase.get_df(), 0)
104
+
105
+ def __delete_clicked(self, button_name):
106
+ '''Delete an asset'''
107
+ asset_name = button_name.split("🗑️ Delete ")[-1]
108
+ AssetDatabase.remove_asset(asset_name)
109
+ data = AssetDatabase.get_df()
110
+ if len(data) > 0:
111
+ return gr.update(value=data),\
112
+ gr.HTML.update(value=self.__get_asset_embed(data, 0)),\
113
+ gr.update(value=f"🗑️ Delete {data.iloc[0]['name']}"),\
114
+ gr.CheckboxGroup.update(choices=AssetComponentsUtils.getBackgroundVideoChoices(), interactive=True),\
115
+ gr.CheckboxGroup.update(choices=AssetComponentsUtils.getBackgroundMusicChoices(), interactive=True)
116
+ return gr.Dataframe.update(value=data),\
117
+ gr.HTML.update(visible=True),\
118
+ gr.Button.update(value="🗑️ Delete"),\
119
+ gr.CheckboxGroup.update(choices=AssetComponentsUtils.getBackgroundVideoChoices(), interactive=True),\
120
+ gr.CheckboxGroup.update(choices=AssetComponentsUtils.getBackgroundMusicChoices(), interactive=True)
121
+
122
+ def __preview_asset(self, data, evt: gr.SelectData):
123
+ '''Preview the asset with the given name'''
124
+ html_embed = self.__get_asset_embed(data, evt.index[0])
125
+ return gr.HTML.update(value=html_embed), gr.update(value=f"🗑️ Delete {data.iloc[evt.index[0]]['name']}")
126
+
127
+ def __get_asset_embed(self, data, row):
128
+ '''Get the embed html for the asset at the given row'''
129
+ embed_height = 300
130
+ embed_width = 300
131
+ asset_link = data.iloc[row]['link']
132
+
133
+ if 'youtube.com' in asset_link:
134
+ asset_link_split = asset_link.split('?v=')
135
+ if asset_link_split[0] == asset_link:
136
+ asset_link_split = asset_link.split('/')
137
+ # if the last character is a /, remove it
138
+ if asset_link_split[-1] == '/':
139
+ asset_link_split = asset_link_split[:-1]
140
+ asset_link_split = asset_link_split[-1]
141
+ else:
142
+ asset_link_split = asset_link_split[-1]
143
+ asset_link = f"https://youtube.com/embed/{asset_link_split}"
144
+ embed_html = f'<iframe width="{embed_width}" height="{embed_height}" src="{asset_link}"></iframe>'
145
+ elif 'public/' in asset_link:
146
+ asset_link = f"http://localhost:31415/file={asset_link}"
147
+ file_ext = asset_link.split('.')[-1]
148
+
149
+ if file_ext in ['mp3', 'wav', 'ogg']:
150
+ audio_type = 'audio/mpeg' if file_ext == 'mp3' else f'audio/{file_ext}'
151
+ embed_html = f'<audio controls><source src="{asset_link}" type="{audio_type}">Your browser does not support the audio tag.</audio>'
152
+ elif file_ext in ['mp4', 'webm', 'ogg', 'mov']:
153
+ video_type = 'video/mp4' if file_ext == 'mp4' else f'video/{file_ext}'
154
+ embed_html = f'<video width="{embed_width}" height="{embed_height}" style="max-height: 100%;" controls><source src="{asset_link}" type="{video_type}">Your browser does not support the video tag.</video>'
155
+ elif file_ext in ['jpg', 'jpeg', 'png', 'gif']:
156
+ embed_html = f'<img src="{asset_link}" width="{embed_width}" height="{embed_height}">'
157
+ else:
158
+ embed_html = 'Unsupported file type'
159
+ return embed_html
160
+
161
+ @staticmethod
162
+ def __clean_filename(filename):
163
+ '''Clean the filename'''
164
+ return re.sub('[\\\\/:*?"<>|]', '', filename)
165
+
166
+ def __verify_and_upload_local_asset(self, upload_type, upload_name, video_path, audio_path, image_path):
167
+ '''Verify and upload a local asset to the database'''
168
+ self.__validate_asset_name(upload_name)
169
+ path_dict = {
170
+ AssetType.VIDEO.value: video_path,
171
+ AssetType.BACKGROUND_VIDEO.value: video_path,
172
+ AssetType.AUDIO.value: audio_path,
173
+ AssetType.BACKGROUND_MUSIC.value: audio_path,
174
+ AssetType.IMAGE.value: image_path
175
+ }
176
+ if not os.path.exists(path_dict[upload_type]):
177
+ raise gr.Error(f'The file does not exist at the given path.')
178
+ return self.__upload_local_asset(upload_type, upload_name, video_path, audio_path, image_path)
179
+
180
+ def __upload_local_asset(self, upload_type, upload_name, video_path, audio_path, image_path):
181
+ '''Upload a local asset to the database'''
182
+ path_dict = {
183
+ AssetType.VIDEO.value: video_path,
184
+ AssetType.BACKGROUND_VIDEO.value: video_path,
185
+ AssetType.AUDIO.value: audio_path,
186
+ AssetType.BACKGROUND_MUSIC.value: audio_path,
187
+ AssetType.IMAGE.value: image_path
188
+ }
189
+ new_path = "public/" + self.__clean_filename(upload_name) + "." + path_dict[upload_type].split(".")[-1]
190
+ shutil.move(path_dict[upload_type], new_path)
191
+ AssetDatabase.add_local_asset(upload_name, AssetType(upload_type), new_path)
192
+ latest_df = AssetDatabase.get_df()
193
+ return gr.DataFrame.update(value=latest_df), gr.HTML.update(value=self.__get_asset_embed(latest_df, 0)),\
194
+ gr.update(value=f"🗑️ Delete {latest_df.iloc[0]['name']}"),\
195
+ gr.Accordion.update(open=False),\
196
+ gr.CheckboxGroup.update(choices=AssetComponentsUtils.getBackgroundVideoChoices(), interactive=True),\
197
+ gr.CheckboxGroup.update(choices=AssetComponentsUtils.getBackgroundMusicChoices(), interactive=True)
gui/ui_tab_config.py ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+
3
+ import gradio as gr
4
+
5
+ from gui.asset_components import AssetComponentsUtils
6
+ from gui.ui_abstract_component import AbstractComponentUI
7
+ from shortGPT.api_utils.eleven_api import ElevenLabsAPI
8
+ from shortGPT.config.api_db import ApiKeyManager
9
+
10
+
11
+ class ConfigUI(AbstractComponentUI):
12
+ def __init__(self):
13
+ self.api_key_manager = ApiKeyManager()
14
+ eleven_key = self.api_key_manager.get_api_key('ELEVEN LABS')
15
+ self.eleven_labs_api = ElevenLabsAPI(eleven_key) if eleven_key else None
16
+
17
+ def on_show(self, button_text, textbox, button):
18
+ '''Show or hide the API key'''
19
+ if button_text == "Show":
20
+ return gr.Textbox.update(type="text"), gr.Button.update(value="Hide")
21
+ return gr.Textbox.update(type="password"), gr.Button.update(value="Show")
22
+
23
+ def verify_eleven_key(self, eleven_key, remaining_chars):
24
+ '''Verify the ElevenLabs API key'''
25
+ if (eleven_key and self.api_key_manager.get_api_key('ELEVEN LABS') != eleven_key):
26
+ try:
27
+ self.eleven_labs_api = ElevenLabsAPI(eleven_key)
28
+ print(self.eleven_labs_api)
29
+ return self.eleven_labs_api.get_remaining_characters()
30
+ except Exception as e:
31
+ raise gr.Error(e.args[0])
32
+ return remaining_chars
33
+
34
+ def save_keys(self, openai_key, eleven_key, pexels_key):
35
+ '''Save the keys in the database'''
36
+ if (self.api_key_manager.get_api_key('OPENAI') != openai_key):
37
+ self.api_key_manager.set_api_key("OPENAI", openai_key)
38
+ if (self.api_key_manager.get_api_key('PEXELS') != pexels_key):
39
+ self.api_key_manager.set_api_key("PEXELS", pexels_key)
40
+ if (self.api_key_manager.get_api_key('ELEVEN LABS') != eleven_key):
41
+ self.api_key_manager.set_api_key("ELEVEN LABS", eleven_key)
42
+ new_eleven_voices = AssetComponentsUtils.getElevenlabsVoices()
43
+ return gr.Textbox.update(value=openai_key),\
44
+ gr.Textbox.update(value=eleven_key),\
45
+ gr.Textbox.update(value=pexels_key),\
46
+ gr.Radio.update(choices=new_eleven_voices),\
47
+ gr.Radio.update(choices=new_eleven_voices)
48
+
49
+ return gr.Textbox.update(value=openai_key),\
50
+ gr.Textbox.update(value=eleven_key),\
51
+ gr.Textbox.update(value=pexels_key),\
52
+ gr.Radio.update(visible=True),\
53
+ gr.Radio.update(visible=True)
54
+
55
+ def get_eleven_remaining(self,):
56
+ '''Get the remaining characters from ElevenLabs API'''
57
+ if (self.eleven_labs_api):
58
+ try:
59
+ return self.eleven_labs_api.get_remaining_characters()
60
+ except Exception as e:
61
+ return e.args[0]
62
+ return ""
63
+
64
+ def back_to_normal(self):
65
+ '''Back to normal after 3 seconds'''
66
+ time.sleep(3)
67
+ return gr.Button.update(value="save")
68
+
69
+ def create_ui(self):
70
+ '''Create the config UI'''
71
+ with gr.Tab("Config") as config_ui:
72
+ with gr.Row():
73
+ with gr.Column():
74
+ with gr.Row():
75
+ openai_textbox = gr.Textbox(value=self.api_key_manager.get_api_key("OPENAI"), label=f"OPENAI API KEY", show_label=True, interactive=True, show_copy_button=True, type="password", scale=40)
76
+ show_openai_key = gr.Button("Show", size="sm", scale=1)
77
+ show_openai_key.click(self.on_show, [show_openai_key], [openai_textbox, show_openai_key])
78
+ with gr.Row():
79
+ eleven_labs_textbox = gr.Textbox(value=self.api_key_manager.get_api_key("ELEVEN LABS"), label=f"ELEVEN LABS API KEY", show_label=True, interactive=True, show_copy_button=True, type="password", scale=40)
80
+ eleven_characters_remaining = gr.Textbox(value=self.get_eleven_remaining(), label=f"CHARACTERS REMAINING", show_label=True, interactive=False, type="text", scale=40)
81
+ show_eleven_key = gr.Button("Show", size="sm", scale=1)
82
+ show_eleven_key.click(self.on_show, [show_eleven_key], [eleven_labs_textbox, show_eleven_key])
83
+ with gr.Row():
84
+ pexels_textbox = gr.Textbox(value=self.api_key_manager.get_api_key("PEXELS"), label=f"PEXELS KEY", show_label=True, interactive=True, show_copy_button=True, type="password", scale=40)
85
+ show_pexels_key = gr.Button("Show", size="sm", scale=1)
86
+ show_pexels_key.click(self.on_show, [show_pexels_key], [pexels_textbox, show_pexels_key])
87
+ save_button = gr.Button("save", size="sm", scale=1)
88
+ save_button.click(self.verify_eleven_key, [eleven_labs_textbox, eleven_characters_remaining], [eleven_characters_remaining]).success(
89
+ self.save_keys, [openai_textbox, eleven_labs_textbox, pexels_textbox], [openai_textbox, eleven_labs_textbox, pexels_textbox, AssetComponentsUtils.voiceChoice(), AssetComponentsUtils.voiceChoiceTranslation()])
90
+ save_button.click(lambda _: gr.Button.update(value="Keys Saved !"), [], [save_button])
91
+ save_button.click(self.back_to_normal, [], [save_button])
92
+ return config_ui