├── .env.example
├── .gitignore
├── .ruby-version
├── Gemfile
├── Gemfile.lock
├── Procfile.dev
├── README.md
├── Rakefile
├── app
├── assets
│ ├── builds
│ │ └── .keep
│ ├── images
│ │ └── icons
│ │ │ ├── facebook.svg
│ │ │ ├── github.svg
│ │ │ └── google.svg
│ └── stylesheets
│ │ ├── application.css
│ │ └── components
│ │ ├── base.css
│ │ ├── buttons.css
│ │ ├── cards.css
│ │ ├── forms.css
│ │ ├── modals.css
│ │ ├── overrides.css
│ │ ├── pagination.css
│ │ └── tables.css
├── controllers
│ ├── application_controller.rb
│ ├── articles_controller.rb
│ ├── errors_controller.rb
│ ├── home_controller.rb
│ ├── pages_controller.rb
│ ├── users
│ │ └── omniauth_callbacks_controller.rb
│ └── users_controller.rb
├── helpers
│ ├── application_helper.rb
│ ├── articles_helper.rb
│ └── users_helper.rb
├── javascript
│ ├── application.js
│ ├── components
│ │ ├── remote_modal.js
│ │ └── tooltip.js
│ └── controllers
│ │ ├── app.js
│ │ └── articles.js
├── mailers
│ └── application_mailer.rb
├── models
│ ├── ability.rb
│ ├── application_record.rb
│ ├── article.rb
│ └── user.rb
└── views
│ ├── application
│ ├── _error_messages.html.erb
│ ├── _flash_messages.html.erb
│ ├── _footer.html.erb
│ ├── _header.html.erb
│ └── _remote_modal.html.erb
│ ├── articles
│ ├── _form.html.erb
│ ├── edit.html.erb
│ ├── index.html.erb
│ ├── new.html.erb
│ └── show.html.erb
│ ├── devise
│ ├── passwords
│ │ ├── edit.html.erb
│ │ └── new.html.erb
│ ├── registrations
│ │ └── new.html.erb
│ ├── sessions
│ │ └── new.html.erb
│ └── shared
│ │ ├── _links.html.erb
│ │ └── _social_signin.html.erb
│ ├── errors
│ ├── _error_page.html.erb
│ ├── internal_server_error.html.erb
│ └── not_found.html.erb
│ ├── home
│ └── index.html.erb
│ ├── layouts
│ ├── application.html.erb
│ ├── mailer.html.erb
│ └── mailer.text.erb
│ ├── pages
│ ├── about.html.erb
│ ├── privacy_policy.html.erb
│ └── terms.html.erb
│ └── users
│ ├── edit.html.erb
│ ├── index.html.erb
│ └── show.html.erb
├── bin
├── dev
├── rails
├── rake
└── setup
├── config.ru
├── config
├── application.rb
├── boot.rb
├── credentials.yml.enc
├── database.yml
├── environment.rb
├── environments
│ ├── development.rb
│ ├── production.rb
│ └── test.rb
├── initializers
│ ├── action_text.rb
│ ├── content_security_policy.rb
│ ├── devise.rb
│ ├── filter_parameter_logging.rb
│ ├── heroicon.rb
│ ├── inflections.rb
│ └── permissions_policy.rb
├── locales
│ └── en.yml
├── puma.rb
├── routes.rb
└── storage.yml
├── db
├── migrate
│ ├── 20220831194622_create_articles.rb
│ ├── 20220831213127_devise_create_users.rb
│ ├── 20220831235947_add_name_to_users.rb
│ ├── 20221005175500_create_active_storage_tables.active_storage.rb
│ └── 20230525120314_create_action_text_tables.action_text.rb
├── schema.rb
└── seeds.rb
├── lib
└── tasks
│ └── .keep
├── log
└── .keep
├── package.json
├── public
├── favicon.ico
└── robots.txt
├── storage
└── .keep
├── tailwind.config.js
├── tmp
└── .keep
└── yarn.lock
/.env.example:
--------------------------------------------------------------------------------
1 | FACEBOOK_CLIENT_ID=facebook_client_id
2 | FACEBOOK_CLIENT_SECRET=facebook_client_secret
3 | GOOGLE_CLIENT_ID=google_client_id
4 | GOOGLE_CLIENT_SECRET=google_client_secret
5 | GITHUB_CLIENT_ID=github_client_id
6 | GITHUB_CLIENT_SECRET=github_client_secret
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Ignore bundler config.
2 | /.bundle
3 |
4 | # Ignore all logfiles and tempfiles.
5 | /log/*
6 | !/log/.keep
7 | /tmp/*
8 | !/tmp/.keep
9 |
10 | # Ignore uploaded files in development.
11 | /storage/*
12 | !/storage/.keep
13 |
14 | # Ignore master key for decrypting credentials and more.
15 | /config/master.key
16 |
17 | # Ignore compiled assets and node_modules
18 | /app/assets/builds/*
19 | !/app/assets/builds/.keep
20 | /public/assets
21 | /node_modules
22 |
23 | # Ignore ENV files
24 | .env
25 |
--------------------------------------------------------------------------------
/.ruby-version:
--------------------------------------------------------------------------------
1 | 3.3.5
2 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | ruby File.read(".ruby-version").strip
4 |
5 | gem "rails", "~> 7.2"
6 | gem "pg", "~> 1.5"
7 | gem "puma", "~> 6.4"
8 | gem "bootsnap", "~> 1.18", require: false
9 | gem "devise", "~> 4.9"
10 | gem "omniauth-facebook", "~> 9.0"
11 | gem "omniauth-github", "~> 2.0"
12 | gem "omniauth-google-oauth2", "~> 1.1"
13 | gem "omniauth-rails_csrf_protection", "~> 1.0"
14 | gem "cancancan", "~> 3.4"
15 | gem "ransack", "~> 4.2"
16 | gem "pagy", "~> 9.0"
17 | gem "image_processing", "~> 1.2"
18 | gem "faker", "~> 3"
19 |
20 | # Front-end
21 | gem "propshaft", "~> 1.1"
22 | gem "jsbundling-rails", "~> 1.0"
23 | gem "cssbundling-rails", "~> 1.1"
24 | gem "turbo-rails", "~> 2.0"
25 | gem "heroicon", "~> 1.0"
26 |
27 | group :development do
28 | gem "web-console"
29 | gem "debug"
30 | gem "dotenv-rails"
31 | end
32 |
--------------------------------------------------------------------------------
/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: https://rubygems.org/
3 | specs:
4 | actioncable (7.2.2.1)
5 | actionpack (= 7.2.2.1)
6 | activesupport (= 7.2.2.1)
7 | nio4r (~> 2.0)
8 | websocket-driver (>= 0.6.1)
9 | zeitwerk (~> 2.6)
10 | actionmailbox (7.2.2.1)
11 | actionpack (= 7.2.2.1)
12 | activejob (= 7.2.2.1)
13 | activerecord (= 7.2.2.1)
14 | activestorage (= 7.2.2.1)
15 | activesupport (= 7.2.2.1)
16 | mail (>= 2.8.0)
17 | actionmailer (7.2.2.1)
18 | actionpack (= 7.2.2.1)
19 | actionview (= 7.2.2.1)
20 | activejob (= 7.2.2.1)
21 | activesupport (= 7.2.2.1)
22 | mail (>= 2.8.0)
23 | rails-dom-testing (~> 2.2)
24 | actionpack (7.2.2.1)
25 | actionview (= 7.2.2.1)
26 | activesupport (= 7.2.2.1)
27 | nokogiri (>= 1.8.5)
28 | racc
29 | rack (>= 2.2.4, < 3.2)
30 | rack-session (>= 1.0.1)
31 | rack-test (>= 0.6.3)
32 | rails-dom-testing (~> 2.2)
33 | rails-html-sanitizer (~> 1.6)
34 | useragent (~> 0.16)
35 | actiontext (7.2.2.1)
36 | actionpack (= 7.2.2.1)
37 | activerecord (= 7.2.2.1)
38 | activestorage (= 7.2.2.1)
39 | activesupport (= 7.2.2.1)
40 | globalid (>= 0.6.0)
41 | nokogiri (>= 1.8.5)
42 | actionview (7.2.2.1)
43 | activesupport (= 7.2.2.1)
44 | builder (~> 3.1)
45 | erubi (~> 1.11)
46 | rails-dom-testing (~> 2.2)
47 | rails-html-sanitizer (~> 1.6)
48 | activejob (7.2.2.1)
49 | activesupport (= 7.2.2.1)
50 | globalid (>= 0.3.6)
51 | activemodel (7.2.2.1)
52 | activesupport (= 7.2.2.1)
53 | activerecord (7.2.2.1)
54 | activemodel (= 7.2.2.1)
55 | activesupport (= 7.2.2.1)
56 | timeout (>= 0.4.0)
57 | activestorage (7.2.2.1)
58 | actionpack (= 7.2.2.1)
59 | activejob (= 7.2.2.1)
60 | activerecord (= 7.2.2.1)
61 | activesupport (= 7.2.2.1)
62 | marcel (~> 1.0)
63 | activesupport (7.2.2.1)
64 | base64
65 | benchmark (>= 0.3)
66 | bigdecimal
67 | concurrent-ruby (~> 1.0, >= 1.3.1)
68 | connection_pool (>= 2.2.5)
69 | drb
70 | i18n (>= 1.6, < 2)
71 | logger (>= 1.4.2)
72 | minitest (>= 5.1)
73 | securerandom (>= 0.3)
74 | tzinfo (~> 2.0, >= 2.0.5)
75 | base64 (0.2.0)
76 | bcrypt (3.1.20)
77 | benchmark (0.4.0)
78 | bigdecimal (3.1.8)
79 | bindex (0.8.1)
80 | bootsnap (1.18.4)
81 | msgpack (~> 1.2)
82 | builder (3.3.0)
83 | cancancan (3.6.1)
84 | concurrent-ruby (1.3.4)
85 | connection_pool (2.4.1)
86 | crass (1.0.6)
87 | cssbundling-rails (1.4.1)
88 | railties (>= 6.0.0)
89 | date (3.4.1)
90 | debug (1.9.2)
91 | irb (~> 1.10)
92 | reline (>= 0.3.8)
93 | devise (4.9.4)
94 | bcrypt (~> 3.0)
95 | orm_adapter (~> 0.1)
96 | railties (>= 4.1.0)
97 | responders
98 | warden (~> 1.2.3)
99 | dotenv (3.1.4)
100 | dotenv-rails (3.1.4)
101 | dotenv (= 3.1.4)
102 | railties (>= 6.1)
103 | drb (2.2.1)
104 | erubi (1.13.0)
105 | faker (3.4.2)
106 | i18n (>= 1.8.11, < 2)
107 | faraday (2.12.0)
108 | faraday-net_http (>= 2.0, < 3.4)
109 | json
110 | logger
111 | faraday-net_http (3.3.0)
112 | net-http
113 | ffi (1.17.0-arm64-darwin)
114 | ffi (1.17.0-x86_64-darwin)
115 | ffi (1.17.0-x86_64-linux-gnu)
116 | globalid (1.2.1)
117 | activesupport (>= 6.1)
118 | hashie (5.0.0)
119 | heroicon (1.0.0)
120 | rails (>= 5.2)
121 | i18n (1.14.6)
122 | concurrent-ruby (~> 1.0)
123 | image_processing (1.13.0)
124 | mini_magick (>= 4.9.5, < 5)
125 | ruby-vips (>= 2.0.17, < 3)
126 | io-console (0.7.2)
127 | irb (1.14.1)
128 | rdoc (>= 4.0.0)
129 | reline (>= 0.4.2)
130 | jsbundling-rails (1.3.1)
131 | railties (>= 6.0.0)
132 | json (2.7.2)
133 | jwt (2.9.1)
134 | base64
135 | logger (1.6.2)
136 | loofah (2.23.1)
137 | crass (~> 1.0.2)
138 | nokogiri (>= 1.12.0)
139 | mail (2.8.1)
140 | mini_mime (>= 0.1.1)
141 | net-imap
142 | net-pop
143 | net-smtp
144 | marcel (1.0.4)
145 | mini_magick (4.13.2)
146 | mini_mime (1.1.5)
147 | minitest (5.25.4)
148 | msgpack (1.7.2)
149 | multi_xml (0.7.1)
150 | bigdecimal (~> 3.1)
151 | net-http (0.4.1)
152 | uri
153 | net-imap (0.4.20)
154 | date
155 | net-protocol
156 | net-pop (0.1.2)
157 | net-protocol
158 | net-protocol (0.2.2)
159 | timeout
160 | net-smtp (0.5.0)
161 | net-protocol
162 | nio4r (2.7.3)
163 | nokogiri (1.18.8-arm64-darwin)
164 | racc (~> 1.4)
165 | nokogiri (1.18.8-x86_64-darwin)
166 | racc (~> 1.4)
167 | nokogiri (1.18.8-x86_64-linux-gnu)
168 | racc (~> 1.4)
169 | oauth2 (2.0.9)
170 | faraday (>= 0.17.3, < 3.0)
171 | jwt (>= 1.0, < 3.0)
172 | multi_xml (~> 0.5)
173 | rack (>= 1.2, < 4)
174 | snaky_hash (~> 2.0)
175 | version_gem (~> 1.1)
176 | omniauth (2.1.2)
177 | hashie (>= 3.4.6)
178 | rack (>= 2.2.3)
179 | rack-protection
180 | omniauth-facebook (9.0.0)
181 | omniauth-oauth2 (~> 1.2)
182 | omniauth-github (2.0.1)
183 | omniauth (~> 2.0)
184 | omniauth-oauth2 (~> 1.8)
185 | omniauth-google-oauth2 (1.2.0)
186 | jwt (>= 2.9)
187 | oauth2 (~> 2.0)
188 | omniauth (~> 2.0)
189 | omniauth-oauth2 (~> 1.8)
190 | omniauth-oauth2 (1.8.0)
191 | oauth2 (>= 1.4, < 3)
192 | omniauth (~> 2.0)
193 | omniauth-rails_csrf_protection (1.0.2)
194 | actionpack (>= 4.2)
195 | omniauth (~> 2.0)
196 | orm_adapter (0.5.0)
197 | pagy (9.0.9)
198 | pg (1.5.8)
199 | propshaft (1.1.0)
200 | actionpack (>= 7.0.0)
201 | activesupport (>= 7.0.0)
202 | rack
203 | railties (>= 7.0.0)
204 | psych (5.1.2)
205 | stringio
206 | puma (6.4.3)
207 | nio4r (~> 2.0)
208 | racc (1.8.1)
209 | rack (3.1.16)
210 | rack-protection (4.0.0)
211 | base64 (>= 0.1.0)
212 | rack (>= 3.0.0, < 4)
213 | rack-session (2.1.1)
214 | base64 (>= 0.1.0)
215 | rack (>= 3.0.0)
216 | rack-test (2.1.0)
217 | rack (>= 1.3)
218 | rackup (2.1.0)
219 | rack (>= 3)
220 | webrick (~> 1.8)
221 | rails (7.2.2.1)
222 | actioncable (= 7.2.2.1)
223 | actionmailbox (= 7.2.2.1)
224 | actionmailer (= 7.2.2.1)
225 | actionpack (= 7.2.2.1)
226 | actiontext (= 7.2.2.1)
227 | actionview (= 7.2.2.1)
228 | activejob (= 7.2.2.1)
229 | activemodel (= 7.2.2.1)
230 | activerecord (= 7.2.2.1)
231 | activestorage (= 7.2.2.1)
232 | activesupport (= 7.2.2.1)
233 | bundler (>= 1.15.0)
234 | railties (= 7.2.2.1)
235 | rails-dom-testing (2.2.0)
236 | activesupport (>= 5.0.0)
237 | minitest
238 | nokogiri (>= 1.6)
239 | rails-html-sanitizer (1.6.1)
240 | loofah (~> 2.21)
241 | nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
242 | railties (7.2.2.1)
243 | actionpack (= 7.2.2.1)
244 | activesupport (= 7.2.2.1)
245 | irb (~> 1.13)
246 | rackup (>= 1.0.0)
247 | rake (>= 12.2)
248 | thor (~> 1.0, >= 1.2.2)
249 | zeitwerk (~> 2.6)
250 | rake (13.2.1)
251 | ransack (4.2.1)
252 | activerecord (>= 6.1.5)
253 | activesupport (>= 6.1.5)
254 | i18n
255 | rdoc (6.7.0)
256 | psych (>= 4.0.0)
257 | reline (0.5.10)
258 | io-console (~> 0.5)
259 | responders (3.1.1)
260 | actionpack (>= 5.2)
261 | railties (>= 5.2)
262 | ruby-vips (2.2.2)
263 | ffi (~> 1.12)
264 | logger
265 | securerandom (0.4.0)
266 | snaky_hash (2.0.1)
267 | hashie
268 | version_gem (~> 1.1, >= 1.1.1)
269 | stringio (3.1.1)
270 | thor (1.3.2)
271 | timeout (0.4.3)
272 | turbo-rails (2.0.10)
273 | actionpack (>= 6.0.0)
274 | railties (>= 6.0.0)
275 | tzinfo (2.0.6)
276 | concurrent-ruby (~> 1.0)
277 | uri (0.13.2)
278 | useragent (0.16.11)
279 | version_gem (1.1.4)
280 | warden (1.2.9)
281 | rack (>= 2.0.9)
282 | web-console (4.2.1)
283 | actionview (>= 6.0.0)
284 | activemodel (>= 6.0.0)
285 | bindex (>= 0.4.0)
286 | railties (>= 6.0.0)
287 | webrick (1.8.2)
288 | websocket-driver (0.7.6)
289 | websocket-extensions (>= 0.1.0)
290 | websocket-extensions (0.1.5)
291 | zeitwerk (2.6.18)
292 |
293 | PLATFORMS
294 | arm64-darwin-22
295 | x86_64-darwin-17
296 | x86_64-darwin-22
297 | x86_64-linux
298 |
299 | DEPENDENCIES
300 | bootsnap (~> 1.18)
301 | cancancan (~> 3.4)
302 | cssbundling-rails (~> 1.1)
303 | debug
304 | devise (~> 4.9)
305 | dotenv-rails
306 | faker (~> 3)
307 | heroicon (~> 1.0)
308 | image_processing (~> 1.2)
309 | jsbundling-rails (~> 1.0)
310 | omniauth-facebook (~> 9.0)
311 | omniauth-github (~> 2.0)
312 | omniauth-google-oauth2 (~> 1.1)
313 | omniauth-rails_csrf_protection (~> 1.0)
314 | pagy (~> 9.0)
315 | pg (~> 1.5)
316 | propshaft (~> 1.1)
317 | puma (~> 6.4)
318 | rails (~> 7.2)
319 | ransack (~> 4.2)
320 | turbo-rails (~> 2.0)
321 | web-console
322 |
323 | RUBY VERSION
324 | ruby 3.3.5p100
325 |
326 | BUNDLED WITH
327 | 2.5.20
328 |
--------------------------------------------------------------------------------
/Procfile.dev:
--------------------------------------------------------------------------------
1 | web: bin/rails server -p 3000
2 | js: yarn build --watch
3 | css: yarn build:css --watch
4 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 🚀 Rails + Ralix + Tailwind
2 |
3 | > Starter Kit to build modern Rails applications fast
4 |
5 | Powered by:
6 |
7 | - [Rails](https://rubyonrails.org)
8 | - [Ralix](https://github.com/ralixjs/ralix)
9 | - [Tailwind CSS](https://tailwindcss.com)
10 | - [PostgreSQL](https://www.postgresql.org)
11 | - [Turbo](https://turbo.hotwired.dev)
12 | - [esbuild](https://esbuild.github.io)
13 |
14 | Rails v7 application template ready to start building your next project, with a pre-configured modern front-end stack and some extras:
15 |
16 | - 🎨 Minimalistic and responsive, clean layout
17 | - 🎯 Icons pack, via [Heroicons](https://heroicons.com)
18 | - 🔐 Authentication, via [Devise](https://github.com/heartcombo/devise) + [OmniAuth](https://github.com/omniauth/omniauth) for Social Logins
19 | - 👥 Authorization, via [CanCanCan](https://github.com/CanCanCommunity/cancancan)
20 | - 🔍 Searching, via [Ransack](https://github.com/activerecord-hackery/ransack)
21 | - 📝 Rich text edition, via [Trix](https://trix-editor.org)
22 | - 🔢 Pagination, via [Pagy](https://github.com/ddnexus/pagy)
23 | - 📄 Static pages controller (About, Terms, ...)
24 | - 🔴 Custom errors pages: 404, 422, 500
25 | - 📦 *Ready-to-use* components: Tables, Buttons, Forms, Cards, Modals and Tooltips
26 |
27 | ## Install
28 |
29 | Clone this repository (or use the GitHub *template* button), then `cd` into the folder and run:
30 |
31 | ```
32 | > bin/setup
33 | ```
34 |
35 | ## Run
36 |
37 | Start the development server:
38 |
39 | ```
40 | > bin/dev
41 | ```
42 |
43 | And open your browser at [`localhost:3000`](http://localhost:3000).
44 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | # Add your own tasks in files placed in lib/tasks ending in .rake,
2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3 |
4 | require_relative "config/application"
5 |
6 | Rails.application.load_tasks
7 |
--------------------------------------------------------------------------------
/app/assets/builds/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ralixjs/rails-ralix-tailwind/f476049dd9c7ef07868148da8615cba4e463da09/app/assets/builds/.keep
--------------------------------------------------------------------------------
/app/assets/images/icons/facebook.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/app/assets/images/icons/github.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/app/assets/images/icons/google.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/application.css:
--------------------------------------------------------------------------------
1 | /* Dependencies */
2 | @import 'tailwindcss/base';
3 | @import 'tailwindcss/components';
4 | @import 'tailwindcss/utilities';
5 | @import 'tippy.js/dist/tippy.css';
6 | @import "trix/dist/trix";
7 |
8 | /* Components */
9 | @import 'components/base.css';
10 | @import 'components/modals.css';
11 | @import 'components/tables.css';
12 | @import 'components/buttons.css';
13 | @import 'components/forms.css';
14 | @import 'components/cards.css';
15 | @import 'components/pagination.css';
16 | @import 'components/overrides.css';
17 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/components/base.css:
--------------------------------------------------------------------------------
1 | body {
2 | @apply bg-slate-100 leading-relaxed;
3 | }
4 |
5 | h1 {
6 | @apply text-4xl font-bold mt-2 my-4;
7 | }
8 |
9 | h2 {
10 | @apply text-3xl font-bold mt-2 my-4;
11 | }
12 |
13 | h3 {
14 | @apply text-2xl font-bold my-2;
15 | }
16 |
17 | p {
18 | @apply mt-2 mb-3;
19 | }
20 |
21 | a {
22 | @apply text-indigo-600 outline-none;
23 | }
24 |
25 | img {
26 | display: inline-block;
27 | }
28 |
29 | ul {
30 | @apply list-disc;
31 | }
32 |
33 | ol {
34 | @apply list-decimal;
35 | }
36 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/components/buttons.css:
--------------------------------------------------------------------------------
1 | .btn {
2 | @apply bg-indigo-600 text-white border-2 border-indigo-600 py-3 px-6 rounded cursor-pointer outline-none;
3 | }
4 |
5 | .btn-outline {
6 | @apply bg-transparent text-indigo-600;
7 | }
8 |
9 | .btn-outline:hover {
10 | @apply bg-indigo-600 text-white;
11 | }
12 |
13 | .btn-danger {
14 | @apply bg-transparent border-red-600 text-red-600;
15 | }
16 |
17 | .btn-danger:hover {
18 | @apply bg-red-600 text-white;
19 | }
20 |
21 | .btn-facebook {
22 | background-color: #1877F2;
23 | border-color: #1877F2;
24 | }
25 |
26 | .btn-github {
27 | background-color: #333;
28 | border-color: #333;
29 | }
30 |
31 | .btn-google {
32 | background-color: #EA4335;
33 | border-color: #EA4335;
34 | }
35 |
36 | .btn svg {
37 | display: inline;
38 | vertical-align: text-top;
39 | }
40 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/components/cards.css:
--------------------------------------------------------------------------------
1 | .card {
2 | @apply rounded bg-white p-4;
3 | }
4 |
5 | .card-title a {
6 | @apply text-gray-900;
7 | }
8 |
9 | .card-subtitle {
10 | @apply text-sm text-slate-400;
11 | }
12 |
13 | .card-body {
14 | @apply text-slate-600 my-2;
15 | }
16 |
17 | .card-actions {
18 | @apply mt-8 mb-4;
19 | }
20 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/components/forms.css:
--------------------------------------------------------------------------------
1 | input:not([type="checkbox"]):not([type="radio"]):not([type="submit"]):not([type="button"]), textarea {
2 | @apply w-full max-w-lg mt-2 mb-4 block rounded focus:border-indigo-600 focus:ring focus:ring-indigo-300 focus:ring-opacity-50;
3 | }
4 |
5 | input[type="file"] {
6 | @apply text-slate-400 bg-white border border-gray-500 cursor-pointer focus:outline-none file:mr-4 file:py-2 file:px-4 file:border-0 file:bg-gray-500 file:text-white hover:file:bg-gray-600;
7 | }
8 |
9 | input[type="checkbox"], input[type="radio"] {
10 | @apply p-2 mr-1 rounded-full text-indigo-600 focus:border-indigo-600 focus:ring focus:ring-indigo-300 focus:ring-opacity-50;
11 | }
12 |
13 | input[hidden="true"] {
14 | @apply !hidden;
15 | }
16 |
17 | .form-actions {
18 | @apply flex gap-4 my-4;
19 | }
20 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/components/modals.css:
--------------------------------------------------------------------------------
1 | .modal {
2 | display: none;
3 | }
4 |
5 | .modal.is-open {
6 | display: block;
7 | }
8 |
9 | .modal-overlay {
10 | position: fixed;
11 | top: 0;
12 | left: 0;
13 | right: 0;
14 | bottom: 0;
15 | background: rgba(0,0,0,0.6);
16 | display: flex;
17 | justify-content: center;
18 | align-items: center;
19 | }
20 |
21 | .modal-container {
22 | background-color: #fff;
23 | padding: 30px;
24 | min-width: 450px;
25 | max-width: 650px;
26 | max-height: 90vh;
27 | border-radius: 4px;
28 | overflow-y: auto;
29 | box-sizing: border-box;
30 | }
31 |
32 | @keyframes mmfadeIn {
33 | from { opacity: 0; }
34 | to { opacity: 1; }
35 | }
36 |
37 | @keyframes mmslideIn {
38 | from { transform: translateY(15%); }
39 | to { transform: translateY(0); }
40 | }
41 |
42 | .modal[aria-hidden="false"] .modal-overlay {
43 | animation: mmfadeIn .3s cubic-bezier(0.0, 0.0, 0.2, 1);
44 | }
45 |
46 | .modal[aria-hidden="false"] .modal-container {
47 | animation: mmslideIn .3s cubic-bezier(0, 0, .2, 1);
48 | }
49 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/components/overrides.css:
--------------------------------------------------------------------------------
1 | /* Turbo */
2 | .turbo-progress-bar {
3 | @apply h-1 bg-indigo-600;
4 | }
5 |
6 | /* Tippy */
7 | .tippy-box {
8 | @apply bg-gray-800;
9 | }
10 |
11 | /* Trix */
12 | trix-editor {
13 | @apply bg-white min-h-60 border-gray-500 focus:border-indigo-600 focus:ring focus:ring-indigo-300 focus:ring-opacity-50;
14 | }
15 |
16 | trix-editor .trix-button--remove {
17 | @apply w-6 h-6 border-none;
18 | }
19 |
20 | trix-editor .attachment__caption-editor {
21 | @apply mt-2 p-1;
22 | }
23 |
24 | trix-editor [data-trix-mutable].attachment img {
25 | @apply shadow-none;
26 | }
27 |
28 | trix-toolbar .trix-button-group {
29 | @apply border-gray-500;
30 | }
31 |
32 | trix-toolbar .trix-button {
33 | @apply border-none;
34 | }
35 |
36 | trix-toolbar .trix-button.trix-active{
37 | @apply bg-indigo-100;
38 | }
39 |
40 | trix-toolbar .trix-dialog {
41 | @apply top-2 left-2 py-2 rounded border-none;
42 | }
43 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/components/pagination.css:
--------------------------------------------------------------------------------
1 | .pagy a {
2 | @apply text-xl p-2;
3 | }
4 |
5 | .pagy a.current {
6 | @apply bg-indigo-600 text-white rounded;
7 | }
8 |
--------------------------------------------------------------------------------
/app/assets/stylesheets/components/tables.css:
--------------------------------------------------------------------------------
1 | table {
2 | @apply w-full text-sm text-left;
3 | }
4 |
5 | table thead {
6 | @apply text-xs uppercase bg-slate-200;
7 | }
8 |
9 | table tbody {
10 | @apply bg-white;
11 | }
12 |
13 | table th, table td {
14 | @apply py-4 px-6;
15 | }
16 |
17 | table img {
18 | min-width: 30px;
19 | }
20 |
21 | .table-responsive {
22 | @apply overflow-x-auto relative;
23 | }
24 |
--------------------------------------------------------------------------------
/app/controllers/application_controller.rb:
--------------------------------------------------------------------------------
1 | class ApplicationController < ActionController::Base
2 | include Pagy::Backend
3 |
4 | rescue_from CanCan::AccessDenied do |exception|
5 | redirect_to request.referer || root_path, alert: exception.message
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/app/controllers/articles_controller.rb:
--------------------------------------------------------------------------------
1 | class ArticlesController < ApplicationController
2 | before_action :authenticate_user!, only: %i[new create edit update destroy]
3 | before_action :set_article, only: %i[show edit update destroy]
4 |
5 | authorize_resource
6 |
7 | def index
8 | @q = Article.ransack(params[:q])
9 | @pagy, @articles = pagy(@q.result.order(created_at: :desc), limit: 4)
10 | end
11 |
12 | def show
13 | end
14 |
15 | def new
16 | @article = Article.new
17 | end
18 |
19 | def edit
20 | end
21 |
22 | def create
23 | @article = Article.new(article_params.merge(user: current_user))
24 |
25 | if @article.save
26 | redirect_to @article, notice: "Article was successfully created."
27 | else
28 | render :new, status: :unprocessable_entity
29 | end
30 | end
31 |
32 | def update
33 | if @article.update(article_params)
34 | redirect_to @article, notice: "Article was successfully updated."
35 | else
36 | render :edit, status: :unprocessable_entity
37 | end
38 | end
39 |
40 | def destroy
41 | @article.destroy
42 |
43 | redirect_to articles_url, notice: "Article was successfully destroyed."
44 | end
45 |
46 | private
47 |
48 | def set_article
49 | @article = Article.find(params[:id])
50 | end
51 |
52 | def article_params
53 | params.require(:article).permit(:title, :body)
54 | end
55 | end
56 |
--------------------------------------------------------------------------------
/app/controllers/errors_controller.rb:
--------------------------------------------------------------------------------
1 | class ErrorsController < ApplicationController
2 | def not_found
3 | render status: 404
4 | end
5 |
6 | def internal_server_error
7 | render status: 500
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/app/controllers/home_controller.rb:
--------------------------------------------------------------------------------
1 | class HomeController < ApplicationController
2 | def index
3 | end
4 | end
5 |
--------------------------------------------------------------------------------
/app/controllers/pages_controller.rb:
--------------------------------------------------------------------------------
1 | class PagesController < ApplicationController
2 | def show
3 | render template: "pages/#{params[:page]}"
4 | rescue ActionView::MissingTemplate
5 | render "errors/not_found", status: 404
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/app/controllers/users/omniauth_callbacks_controller.rb:
--------------------------------------------------------------------------------
1 | class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
2 | def google_oauth2
3 | omniauth_callback('Google', 'google_data')
4 | end
5 |
6 | def github
7 | omniauth_callback('GitHub', 'github_data')
8 | end
9 |
10 | def facebook
11 | omniauth_callback('Facebook', 'facebook_data')
12 | end
13 |
14 | private
15 |
16 | def omniauth_callback(kind, session_key)
17 | @user = User.from_omniauth(request.env['omniauth.auth'])
18 |
19 | if @user.persisted?
20 | flash[:notice] = I18n.t 'devise.omniauth_callbacks.success', kind: kind
21 | sign_in_and_redirect @user, event: :authentication
22 | else
23 | session["devise.#{session_key}"] = request.env['omniauth.auth'].except('extra') # Removing extra as it can overflow some session stores
24 | redirect_to new_user_registration_url, alert: @user.errors.full_messages.join("\n")
25 | end
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/app/controllers/users_controller.rb:
--------------------------------------------------------------------------------
1 | class UsersController < ApplicationController
2 | before_action :authenticate_user!
3 |
4 | def index
5 | @q = User.ransack(params[:q])
6 | @pagy, @users = pagy(@q.result.order(created_at: :desc), limit: 10)
7 | end
8 |
9 | def show
10 | @user = User.find(params[:id])
11 |
12 | render layout: false
13 | end
14 |
15 | def edit
16 | end
17 |
18 | def update
19 | if current_user.update(user_params)
20 | redirect_to current_user, notice: "Account was successfully updated."
21 | else
22 | render :edit, status: :unprocessable_entity
23 | end
24 | end
25 |
26 | def destroy
27 | current_user.destroy
28 |
29 | redirect_to root_path, notice: "Account was successfully deleted."
30 | end
31 |
32 | private
33 |
34 | def user_params
35 | params.require(:user).permit(:avatar, :name, :email, :password, :password_confirmation)
36 | end
37 | end
38 |
--------------------------------------------------------------------------------
/app/helpers/application_helper.rb:
--------------------------------------------------------------------------------
1 | module ApplicationHelper
2 | include Pagy::Frontend
3 | include Heroicon::Engine.helpers
4 |
5 | def page_title
6 | "Rails + Ralix + Tailwind | #{controller_name.humanize}"
7 | end
8 |
9 | def body_class
10 | "#{controller_name}-#{action_name}"
11 | end
12 |
13 | def nav_link_class(section, extra = nil)
14 | if section == controller_name
15 | "bg-gray-900 text-white px-3 py-2 rounded-md text-sm font-medium #{extra}"
16 | else
17 | "text-gray-300 hover:bg-gray-700 hover:text-white px-3 py-2 rounded-md text-sm font-medium #{extra}"
18 | end
19 | end
20 |
21 | def time_ago(time_object)
22 | "#{time_ago_in_words(time_object)} ago"
23 | end
24 |
25 | def format_time(time_object)
26 | l(time_object, format: :long)
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/app/helpers/articles_helper.rb:
--------------------------------------------------------------------------------
1 | module ArticlesHelper
2 | def author_and_date(article)
3 | "by #{article.user.name} | #{format_time(article.created_at.to_date)}"
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/app/helpers/users_helper.rb:
--------------------------------------------------------------------------------
1 | module UsersHelper
2 | def avatar(user, size = 40)
3 | image_tag avatar_url(user, size),
4 | size: size,
5 | class: "rounded-full"
6 | end
7 |
8 | def avatar_url(user, size)
9 | if user.avatar.attached?
10 | url_for(user.avatar.variant(resize_to_fill: [size, size]))
11 | else
12 | gravatar_url(user.email, size)
13 | end
14 | end
15 |
16 | def gravatar_url(email, size)
17 | gravatar_id = Digest::MD5.hexdigest(email).downcase
18 | gravatar_options = {
19 | s: size,
20 | d: "retro"
21 | }
22 |
23 | "https://www.gravatar.com/avatar/#{gravatar_id}?#{gravatar_options.to_param}"
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/app/javascript/application.js:
--------------------------------------------------------------------------------
1 | // Dependencies
2 | import { RalixApp } from 'ralix'
3 | import "@hotwired/turbo-rails"
4 | import "trix"
5 | import "@rails/actiontext"
6 |
7 | // Controllers
8 | import AppCtrl from './controllers/app'
9 | import ArticlesCtrl from './controllers/articles'
10 |
11 | // Components
12 | import RemoteModal from './components/remote_modal'
13 | import Tooltip from './components/tooltip'
14 |
15 | const App = new RalixApp({
16 | routes: {
17 | '/articles$': ArticlesCtrl,
18 | '/.*': AppCtrl
19 | },
20 | components: [
21 | RemoteModal,
22 | Tooltip
23 | ]
24 | })
25 |
26 | App.start()
27 |
--------------------------------------------------------------------------------
/app/javascript/components/remote_modal.js:
--------------------------------------------------------------------------------
1 | import MicroModal from 'micromodal'
2 |
3 | export default class RemoteModal {
4 | static onload() {
5 | findAll('[data-modal-url]').forEach(el => {
6 | on(el, 'click', () => {
7 | this.show(data(el))
8 | })
9 | })
10 | }
11 |
12 | static show(data) {
13 | get(data.modalUrl).then(content => {
14 | insertHTML('#remote-modal .modal-title', data.modalTitle || '')
15 | insertHTML('#remote-modal main', content)
16 |
17 | MicroModal.show('remote-modal', {
18 | disableScroll: true
19 | })
20 | })
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/app/javascript/components/tooltip.js:
--------------------------------------------------------------------------------
1 | import tippy from 'tippy.js'
2 |
3 | export default class Tooltip {
4 | static onload() {
5 | tippy('[data-tippy-content]', {
6 | allowHTML: true,
7 | arrow: false
8 | })
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/app/javascript/controllers/app.js:
--------------------------------------------------------------------------------
1 | export default class AppCtrl {
2 | constructor() {
3 | this.isMobile = /Mobi/.test(navigator.userAgent)
4 | }
5 |
6 | toggleMenu() {
7 | toggleClass('.mobile-menu', 'hidden')
8 | }
9 |
10 | closeFlashAlert() {
11 | currentElement().parentElement.remove()
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/app/javascript/controllers/articles.js:
--------------------------------------------------------------------------------
1 | import AppCtrl from "./app"
2 |
3 | export default class ArticlesCtrl extends AppCtrl {
4 | constructor() {
5 | super()
6 |
7 | this.searchForm = find('.article_search')
8 | this.searchInput = find('.search-input')
9 | this.currentValue = this.searchInput.value
10 |
11 | if (!this.isMobile) this.searchInput.focus()
12 | }
13 |
14 | search() {
15 | setTimeout(() => {
16 | const newValue = this.searchInput.value
17 |
18 | if (this.currentValue != newValue)
19 | this.currentValue = newValue
20 | submit(this.searchForm)
21 | }, 500)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/app/mailers/application_mailer.rb:
--------------------------------------------------------------------------------
1 | class ApplicationMailer < ActionMailer::Base
2 | default from: "from@example.com"
3 | layout "mailer"
4 | end
5 |
--------------------------------------------------------------------------------
/app/models/ability.rb:
--------------------------------------------------------------------------------
1 | class Ability
2 | include CanCan::Ability
3 |
4 | def initialize(user)
5 | can [:read, :create], Article
6 | can [:update, :destroy], Article, user: user
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/app/models/application_record.rb:
--------------------------------------------------------------------------------
1 | class ApplicationRecord < ActiveRecord::Base
2 | primary_abstract_class
3 | end
4 |
--------------------------------------------------------------------------------
/app/models/article.rb:
--------------------------------------------------------------------------------
1 | class Article < ApplicationRecord
2 | belongs_to :user
3 |
4 | has_rich_text :body
5 | has_one :rich_text, class_name: 'ActionText::RichText', as: :record
6 |
7 | validates :title, :body, presence: true
8 | validates :title, length: { minimum: 5 }
9 |
10 | def self.ransackable_attributes(auth_object = nil)
11 | ["title"]
12 | end
13 |
14 | def self.ransackable_associations(auth_object = nil)
15 | ["rich_text"]
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/app/models/user.rb:
--------------------------------------------------------------------------------
1 | class User < ApplicationRecord
2 | devise :database_authenticatable,
3 | :registerable,
4 | :recoverable,
5 | :rememberable,
6 | :validatable,
7 | :omniauthable,
8 | omniauth_providers: [:facebook, :google_oauth2, :github]
9 |
10 | has_one_attached :avatar
11 |
12 | has_many :articles, dependent: :destroy
13 |
14 | def name
15 | @name ||= self[:name].presence || email.split("@").first
16 | end
17 |
18 | def self.from_omniauth(auth)
19 | data = auth.info
20 |
21 | User.where(email: data['email']).first_or_create do |user|
22 | user.name = data['name']
23 | user.password = Devise.friendly_token[0,20] if user.new_record?
24 | end
25 | end
26 |
27 | def self.ransackable_attributes(auth_object = nil)
28 | ["name", "email", "created_at"]
29 | end
30 |
31 | protected
32 |
33 | def password_required?
34 | new_record? || password.present?
35 | end
36 | end
37 |
--------------------------------------------------------------------------------
/app/views/application/_error_messages.html.erb:
--------------------------------------------------------------------------------
1 | <% if object.errors.any? %>
2 |
3 |
<%= pluralize(object.errors.count, "error") %> found:
4 |
5 |
6 | <% object.errors.each do |error| %>
7 | - <%= error.full_message %>
8 | <% end %>
9 |
10 |
11 | <% end %>
12 |
--------------------------------------------------------------------------------
/app/views/application/_flash_messages.html.erb:
--------------------------------------------------------------------------------
1 | <% flash.each do |key, msg| %>
2 |
3 | <%= msg %>
4 |
5 |
6 | <% end %>
7 |
--------------------------------------------------------------------------------
/app/views/application/_footer.html.erb:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/app/views/application/_header.html.erb:
--------------------------------------------------------------------------------
1 |
63 |
--------------------------------------------------------------------------------
/app/views/application/_remote_modal.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
10 |
11 | Loading ...
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/views/articles/_form.html.erb:
--------------------------------------------------------------------------------
1 | <%= form_with(model: article) do |form| %>
2 | <%= render "application/error_messages", object: article %>
3 |
4 |
5 | <%= form.label :title %>
6 | <%= form.text_field :title %>
7 |
8 |
9 |
10 | <%= form.label :body %>
11 | <%= form.rich_text_area :body %>
12 |
13 |
14 |
15 | <%= form.submit nil, class: 'btn' %>
16 |
17 | <% end %>
18 |
--------------------------------------------------------------------------------
/app/views/articles/edit.html.erb:
--------------------------------------------------------------------------------
1 | Editing article
2 |
3 | <%= render "form", article: @article %>
4 |
5 |
6 |
Be careful! This action is irreversible.
7 | <%= button_to "Destroy", @article, method: :delete, class: "btn btn-danger" %>
8 |
9 |
--------------------------------------------------------------------------------
/app/views/articles/index.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
Articles
3 | <%= link_to new_article_path, class: 'btn' do %>
4 | <%= heroicon "plus" %>
5 | New article
6 | <% end %>
7 |
8 |
9 | <%= search_form_for @q, data: { turbo_frame: "search" } do |f| %>
10 |
11 |
12 | <%= heroicon "magnifying-glass" %>
13 |
14 | <%= f.text_field :title_or_rich_text_body_cont, class: "search-input p-3 pl-10 text-sm", onkeyup: "search()", placeholder: "Search ..." %>
15 |
16 | <% end %>
17 |
18 | <%= turbo_frame_tag "search", target: "_top" do %>
19 |
20 | <% @articles.each do |article| %>
21 |
22 |
23 | <%= link_to article.title, article %>
24 |
25 |
26 | <%= author_and_date(article) %>
27 |
28 |
29 | <%= truncate strip_tags(article.body.to_s), length: 160 %>
30 |
31 |
32 | <%= link_to article, class: 'btn btn-outline' do %>
33 | Read more
34 | <%= heroicon 'chevron-right' %>
35 | <% end %>
36 |
37 |
38 | <% end %>
39 |
40 |
41 |
42 | <%== pagy_nav(@pagy) if @pagy.pages > 1 %>
43 |
44 | <% end %>
45 |
--------------------------------------------------------------------------------
/app/views/articles/new.html.erb:
--------------------------------------------------------------------------------
1 | New article
2 |
3 | <%= render "form", article: @article %>
4 |
--------------------------------------------------------------------------------
/app/views/articles/show.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
<%= @article.title %>
3 |
4 |
5 | <%= author_and_date(@article) %>
6 |
7 |
8 |
9 | <%= @article.body %>
10 |
11 |
12 |
13 | <%= link_to "Edit", edit_article_path(@article), class: 'btn' %>
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/views/devise/passwords/edit.html.erb:
--------------------------------------------------------------------------------
1 | Change your password
2 |
3 | <%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }, data: { turbo: "false" }) do |f| %>
4 | <%= render "application/error_messages", object: resource %>
5 | <%= f.hidden_field :reset_password_token %>
6 |
7 |
8 | <%= f.label :password, "New password" %>
9 | <%= f.password_field :password, autofocus: true, autocomplete: "new-password" %>
10 |
11 |
12 |
13 | <%= f.label :password_confirmation, "Confirm new password" %>
14 | <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
15 |
16 |
17 |
18 | <%= f.submit "Change my password", class: "btn" %>
19 |
20 | <% end %>
21 |
22 | <%= render "devise/shared/links" %>
23 |
--------------------------------------------------------------------------------
/app/views/devise/passwords/new.html.erb:
--------------------------------------------------------------------------------
1 | Forgot your password?
2 |
3 | <%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }, data: { turbo: "false" }) do |f| %>
4 | <%= render "application/error_messages", object: resource %>
5 |
6 |
7 | <%= f.label :email %>
8 | <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
9 |
10 |
11 |
12 | <%= f.submit "Send me reset password instructions", class: "btn" %>
13 |
14 | <% end %>
15 |
16 | <%= render "devise/shared/links" %>
17 |
--------------------------------------------------------------------------------
/app/views/devise/registrations/new.html.erb:
--------------------------------------------------------------------------------
1 | Sign up
2 |
3 | <%= form_for(resource, as: resource_name, url: registration_path(resource_name), data: { turbo: "false" }) do |f| %>
4 | <%= render "application/error_messages", object: resource %>
5 |
6 |
7 | <%= f.label :email %>
8 | <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
9 |
10 |
11 |
12 | <%= f.label :password %>
13 | <%= f.password_field :password, autocomplete: "new-password" %>
14 |
15 |
16 |
17 | <%= f.label :password_confirmation %>
18 | <%= f.password_field :password_confirmation, autocomplete: "new-password" %>
19 |
20 |
21 |
22 | <%= f.submit "Sign up", class: "btn" %>
23 |
24 | <% end %>
25 |
26 | <%= render "devise/shared/social_signin" %>
27 | <%= render "devise/shared/links" %>
28 |
--------------------------------------------------------------------------------
/app/views/devise/sessions/new.html.erb:
--------------------------------------------------------------------------------
1 | Sign in
2 |
3 | <%= form_for(resource, as: resource_name, url: session_path(resource_name), data: { turbo: "false" }) do |f| %>
4 |
5 | <%= f.label :email %>
6 | <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
7 |
8 |
9 |
10 | <%= f.label :password %>
11 | <%= f.password_field :password, autocomplete: "current-password" %>
12 |
13 |
14 | <% if devise_mapping.rememberable? %>
15 |
16 | <%= f.check_box :remember_me %>
17 | <%= f.label :remember_me %>
18 |
19 | <% end %>
20 |
21 |
22 | <%= f.submit "Sign in", class: "btn" %>
23 |
24 | <% end %>
25 |
26 | <%= render "devise/shared/social_signin" %>
27 | <%= render "devise/shared/links" %>
28 |
--------------------------------------------------------------------------------
/app/views/devise/shared/_links.html.erb:
--------------------------------------------------------------------------------
1 | <% if controller_name != 'sessions' %>
2 | <%= link_to "Sign in", new_session_path(resource_name) %>
3 | <% end %>
4 |
5 | <% if devise_mapping.registerable? && controller_name != 'registrations' %>
6 | <%= link_to "Sign up", new_registration_path(resource_name) %>
7 | <% end %>
8 |
9 | <% if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
10 | <%= link_to "Forgot your password?", new_password_path(resource_name) %>
11 | <% end %>
12 |
--------------------------------------------------------------------------------
/app/views/devise/shared/_social_signin.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= button_to user_github_omniauth_authorize_path, class: "btn btn-github", data: { turbo: "false" } do %>
3 | <%= image_tag "icons/github.svg", class: "h-4 w-4" %>
4 | Sign in with GitHub
5 | <% end %>
6 |
7 | <%= button_to user_google_oauth2_omniauth_authorize_path, class: "btn btn-google", data: { turbo: "false" } do %>
8 | <%= image_tag "icons/google.svg", class: "h-4 w-4" %>
9 | Sign in with Google
10 | <% end %>
11 |
12 | <%= button_to user_facebook_omniauth_authorize_path, class: "btn btn-facebook", data: { turbo: "false" } do %>
13 | <%= image_tag "icons/facebook.svg", class: "h-4 w-4" %>
14 | Sign in with Facebook
15 | <% end %>
16 |
17 |
--------------------------------------------------------------------------------
/app/views/errors/_error_page.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
<%= code %>
3 |
4 |
<%= error_title %>
5 |
<%= error_description %>
6 |
7 |
8 | Home
9 | Back
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/views/errors/internal_server_error.html.erb:
--------------------------------------------------------------------------------
1 | <%= render 'errors/error_page',
2 | code: 500,
3 | error_title: "OOOPS",
4 | error_description: "Looks like something went wrong!" %>
5 |
--------------------------------------------------------------------------------
/app/views/errors/not_found.html.erb:
--------------------------------------------------------------------------------
1 | <%= render 'errors/error_page',
2 | code: 404,
3 | error_title: "PAGE NOT FOUND",
4 | error_description: "The page you were looking for doesn't exist.
5 | You may have mistyped the address or the page may have moved." %>
6 |
--------------------------------------------------------------------------------
/app/views/home/index.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 | Starter Kit
4 | Rails + Ralix + Tailwind
5 |
6 |
7 |
8 | Starter Kit to build Rails applications fast, with Ralix, Tailwind and more!
9 |
10 |
11 |
12 | <%= heroicon 'book-open' %>
13 | Get started
14 |
15 |
16 | <%= heroicon 'squares-2x2' %>
17 | Explore app
18 |
19 |
20 |
--------------------------------------------------------------------------------
/app/views/layouts/application.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | <%= page_title %>
5 |
6 | <%= csrf_meta_tags %>
7 | <%= csp_meta_tag %>
8 |
9 | <%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
10 | <%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
11 |
12 |
13 |
14 | <%= render "application/header" %>
15 | <%= render "application/flash_messages" %>
16 |
17 |
18 | <%= yield %>
19 |
20 |
21 | <%= render "application/footer" %>
22 | <%= render "application/remote_modal" %>
23 |
24 |
25 |
--------------------------------------------------------------------------------
/app/views/layouts/mailer.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
8 |
9 |
10 |
11 | <%= yield %>
12 |
13 |
14 |
--------------------------------------------------------------------------------
/app/views/layouts/mailer.text.erb:
--------------------------------------------------------------------------------
1 | <%= yield %>
2 |
--------------------------------------------------------------------------------
/app/views/pages/about.html.erb:
--------------------------------------------------------------------------------
1 | About us
2 |
3 | <%= Faker::Lorem.paragraphs(number: 5).join.html_safe %>
4 |
5 | Mission
6 |
7 | <%= Faker::Lorem.paragraphs(number: 5).join.html_safe %>
8 | <%= Faker::Lorem.paragraphs(number: 5).join.html_safe %>
9 |
10 | Values
11 |
12 | <%= Faker::Lorem.paragraphs(number: 5).join.html_safe %>
13 | <%= Faker::Lorem.paragraphs(number: 5).join.html_safe %>
14 |
15 | Team
16 |
17 | <%= Faker::Lorem.paragraphs(number: 5).join.html_safe %>
18 | <%= Faker::Lorem.paragraphs(number: 5).join.html_safe %>
19 |
--------------------------------------------------------------------------------
/app/views/pages/privacy_policy.html.erb:
--------------------------------------------------------------------------------
1 | Privacy policy
2 |
3 | <%= Faker::Lorem.paragraphs(number: 5).join.html_safe %>
4 | <%= Faker::Lorem.paragraphs(number: 5).join.html_safe %>
5 | <%= Faker::Lorem.paragraphs(number: 5).join.html_safe %>
6 |
--------------------------------------------------------------------------------
/app/views/pages/terms.html.erb:
--------------------------------------------------------------------------------
1 | Terms
2 |
3 | <%= Faker::Lorem.paragraphs(number: 5).join.html_safe %>
4 | <%= Faker::Lorem.paragraphs(number: 5).join.html_safe %>
5 | <%= Faker::Lorem.paragraphs(number: 5).join.html_safe %>
6 |
--------------------------------------------------------------------------------
/app/views/users/edit.html.erb:
--------------------------------------------------------------------------------
1 | My account
2 |
3 | <%= form_with(model: current_user) do |form| %>
4 | <%= render "application/error_messages", object: current_user %>
5 |
6 |
7 | <%= avatar(current_user, 200) %>
8 |
9 |
10 |
11 | <%= form.label :avatar %>
12 | <%= form.file_field :avatar, accept: "image/*" %>
13 |
14 |
15 |
16 | <%= form.label :name %>
17 | <%= form.text_field :name %>
18 |
19 |
20 |
21 | <%= form.label :email %>
22 | <%= form.email_field :email %>
23 |
24 |
25 |
26 | <%= form.label :password %>
27 | <%= form.password_field :password %>
28 |
29 |
30 |
31 | <%= form.label :password_confirmation %>
32 | <%= form.password_field :password_confirmation %>
33 |
34 |
35 |
36 | <%= form.submit nil, class: 'btn' %>
37 |
38 | <% end %>
39 |
40 |
41 |
Sign out from my account.
42 | <%= button_to "Sign out", destroy_user_session_path, method: :delete, class: "btn btn-outline" %>
43 |
44 |
45 |
46 |
Be careful! This action is irreversible.
47 | <%= button_to "Delete my account", user_path(current_user), method: :delete, class: "btn btn-danger" %>
48 |
49 |
--------------------------------------------------------------------------------
/app/views/users/index.html.erb:
--------------------------------------------------------------------------------
1 | Users
2 |
3 |
4 |
5 |
6 |
7 | |
8 | <%= sort_link(@q, :name) %> |
9 | <%= sort_link(@q, :email) %> |
10 | <%= sort_link(@q, :created_at) %> |
11 | |
12 |
13 |
14 |
15 | <% @users.each do |user| %>
16 |
17 |
18 | <%= avatar(user, 60) %>
19 | |
20 |
21 | <%= user.name %>
22 | |
23 |
24 | <%= mail_to user.email, 'data-tippy-content': 'Click to send an email' %>
25 | |
26 |
27 | <%= time_ago user.created_at %>
28 | |
29 |
30 | " data-modal-title="User details" class="btn btn-outline">Details
31 | |
32 |
33 | <% end %>
34 |
35 |
36 |
37 |
38 |
39 | <%== pagy_nav(@pagy) if @pagy.pages > 1 %>
40 |
41 |
--------------------------------------------------------------------------------
/app/views/users/show.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= avatar(@user, 200) %>
3 |
<%= @user.name %>
4 |
<%= mail_to @user.email %>
5 |
6 |
7 |
8 |
9 | Created at
10 | <%= time_ago @user.created_at %>
11 | <%= format_time @user.created_at %>
12 |
13 |
14 | Updated at
15 | <%= time_ago @user.updated_at %>
16 | <%= format_time @user.updated_at %>
17 |
18 |
Total Articles <%= @user.articles.size %>
19 |
20 |
--------------------------------------------------------------------------------
/bin/dev:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | if ! foreman version &> /dev/null
4 | then
5 | echo "Installing foreman..."
6 | gem install foreman
7 | fi
8 |
9 | foreman start -f Procfile.dev "$@"
10 |
--------------------------------------------------------------------------------
/bin/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | APP_PATH = File.expand_path("../config/application", __dir__)
4 | require_relative "../config/boot"
5 | require "rails/commands"
6 |
--------------------------------------------------------------------------------
/bin/rake:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | require_relative "../config/boot"
4 | require "rake"
5 | Rake.application.run
6 |
--------------------------------------------------------------------------------
/bin/setup:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | require "fileutils"
4 |
5 | # path to your application root.
6 | APP_ROOT = File.expand_path("..", __dir__)
7 |
8 | def system!(*args)
9 | system(*args) || abort("\n== Command #{args} failed ==")
10 | end
11 |
12 | FileUtils.chdir APP_ROOT do
13 | puts "== Installing dependencies =="
14 | system! "gem install bundler --conservative"
15 | system("bundle check") || system!("bundle install")
16 |
17 | puts "\n== Installing front-end dependencies =="
18 | system! "yarn install"
19 |
20 | puts "\n== Preparing database =="
21 | system! "bin/rails db:prepare"
22 | system! "bin/rails db:seed"
23 |
24 | puts "\n== Removing old logs and tempfiles =="
25 | system! "bin/rails log:clear tmp:clear"
26 |
27 | puts "\n== Restarting application server =="
28 | system! "bin/rails restart"
29 | end
30 |
--------------------------------------------------------------------------------
/config.ru:
--------------------------------------------------------------------------------
1 | # This file is used by Rack-based servers to start the application.
2 |
3 | require_relative "config/environment"
4 |
5 | run Rails.application
6 | Rails.application.load_server
7 |
--------------------------------------------------------------------------------
/config/application.rb:
--------------------------------------------------------------------------------
1 | require_relative "boot"
2 |
3 | require "rails/all"
4 |
5 | # Require the gems listed in Gemfile, including any gems
6 | # you've limited to :test, :development, or :production.
7 | Bundler.require(*Rails.groups)
8 |
9 | module RailsRalixTailwind
10 | class Application < Rails::Application
11 | # Load Rails defaults
12 | config.load_defaults 7.2
13 |
14 | # This tells Rails to serve error pages from the app itself, rather than using static error pages in public/
15 | config.exceptions_app = self.routes
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/config/boot.rb:
--------------------------------------------------------------------------------
1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
2 |
3 | require "bundler/setup" # Set up gems listed in the Gemfile.
4 | require "bootsnap/setup" # Speed up boot time by caching expensive operations.
5 |
--------------------------------------------------------------------------------
/config/credentials.yml.enc:
--------------------------------------------------------------------------------
1 | qDh808AJiyxRn4Npr9Ux3LXJX3DGlIRpG888RrT3kfsq1j6yJkWOQ3PgMixQeoR61VHMWe3fOl3cyUcx8DDekkqSu568qzCPt+uy2R2tEl6JH7xP9jdvSVdmmEuNvyrVbpxayQlxna+JOqVzISadIFw0L974ZC1fLas5bND8r3mFrfApJrHClikMzV6g8C+FVywB1b4m7z4oQqEcg2A72uBwM67eAPibjXH0kDYc3H5JE4hdtcuWMnGXrQ3nybuZsY4c0BKqv3bq/1sl3OF7rzP+LmeqKCjKwIA3En/u0cvAZa+ToAmFVv435F7+MZfmaKJ15TRKypDxVYGyD3H6aYTzkX6Nu9gn8i+0P0Q9vabQM92Q/dgsztKH+nPX3CdtcI02qwTGKCoVLHlV/+OHDIe1eD3usIgcdFaa--X1OKn58uyWHMGamI--i30CtrHvN2/lDeRlD0OYyQ==
--------------------------------------------------------------------------------
/config/database.yml:
--------------------------------------------------------------------------------
1 | default: &default
2 | adapter: postgresql
3 | encoding: unicode
4 | pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
5 |
6 | development:
7 | <<: *default
8 | database: <%= ENV.fetch("DATABASE_NAME", "rails-ralix-tailwind_development") %>
9 |
10 | test:
11 | <<: *default
12 | database: <%= ENV.fetch("DATABASE_NAME", "rails-ralix-tailwind_test") %>
13 |
14 | production:
15 | <<: *default
16 | database: <%= ENV.fetch("DATABASE_NAME", "rails-ralix-tailwind_production") %>
17 |
--------------------------------------------------------------------------------
/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Load the Rails application.
2 | require_relative "application"
3 |
4 | # Initialize the Rails application.
5 | Rails.application.initialize!
6 |
--------------------------------------------------------------------------------
/config/environments/development.rb:
--------------------------------------------------------------------------------
1 | require "active_support/core_ext/integer/time"
2 |
3 | Rails.application.configure do
4 | # Settings specified here will take precedence over those in config/application.rb.
5 |
6 | # In the development environment your application's code is reloaded any time
7 | # it changes. This slows down response time but is perfect for development
8 | # since you don't have to restart the web server when you make code changes.
9 | config.enable_reloading = true
10 |
11 | # Do not eager load code on boot.
12 | config.eager_load = false
13 |
14 | # Show full error reports.
15 | config.consider_all_requests_local = true
16 |
17 | # Enable server timing.
18 | config.server_timing = true
19 |
20 | # Enable/disable caching. By default caching is disabled.
21 | # Run rails dev:cache to toggle caching.
22 | if Rails.root.join("tmp/caching-dev.txt").exist?
23 | config.action_controller.perform_caching = true
24 | config.action_controller.enable_fragment_cache_logging = true
25 |
26 | config.cache_store = :memory_store
27 | config.public_file_server.headers = { "Cache-Control" => "public, max-age=#{2.days.to_i}" }
28 | else
29 | config.action_controller.perform_caching = false
30 |
31 | config.cache_store = :null_store
32 | end
33 |
34 | # Store uploaded files on the local file system (see config/storage.yml for options).
35 | config.active_storage.service = :local
36 |
37 | # Don't care if the mailer can't send.
38 | config.action_mailer.raise_delivery_errors = false
39 |
40 | # Disable caching for Action Mailer templates even if Action Controller
41 | # caching is enabled.
42 | config.action_mailer.perform_caching = false
43 |
44 | config.action_mailer.default_url_options = { host: "localhost", port: 3000 }
45 |
46 | # Print deprecation notices to the Rails logger.
47 | config.active_support.deprecation = :log
48 |
49 | # Raise exceptions for disallowed deprecations.
50 | config.active_support.disallowed_deprecation = :raise
51 |
52 | # Tell Active Support which deprecation messages to disallow.
53 | config.active_support.disallowed_deprecation_warnings = []
54 |
55 | # Raise an error on page load if there are pending migrations.
56 | config.active_record.migration_error = :page_load
57 |
58 | # Highlight code that triggered database queries in logs.
59 | config.active_record.verbose_query_logs = true
60 |
61 | # Highlight code that enqueued background job in logs.
62 | config.active_job.verbose_enqueue_logs = true
63 |
64 | # Raises error for missing translations.
65 | # config.i18n.raise_on_missing_translations = true
66 |
67 | # Annotate rendered view with file names.
68 | config.action_view.annotate_rendered_view_with_filenames = true
69 |
70 | # Uncomment if you wish to allow Action Cable access from any origin.
71 | # config.action_cable.disable_request_forgery_protection = true
72 |
73 | # Raise error when a before_action's only/except options reference missing actions.
74 | config.action_controller.raise_on_missing_callback_actions = true
75 | end
76 |
--------------------------------------------------------------------------------
/config/environments/production.rb:
--------------------------------------------------------------------------------
1 | require "active_support/core_ext/integer/time"
2 |
3 | Rails.application.configure do
4 | # Settings specified here will take precedence over those in config/application.rb.
5 |
6 | # Code is not reloaded between requests.
7 | config.enable_reloading = false
8 |
9 | # Eager load code on boot. This eager loads most of Rails and
10 | # your application in memory, allowing both threaded web servers
11 | # and those relying on copy on write to perform better.
12 | # Rake tasks automatically ignore this option for performance.
13 | config.eager_load = true
14 |
15 | # Full error reports are disabled and caching is turned on.
16 | config.consider_all_requests_local = false
17 | config.action_controller.perform_caching = true
18 |
19 | # Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment
20 | # key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files).
21 | # config.require_master_key = true
22 |
23 | # Disable serving static files from `public/`, relying on NGINX/Apache to do so instead.
24 | # config.public_file_server.enabled = false
25 |
26 | # Enable serving of images, stylesheets, and JavaScripts from an asset server.
27 | # config.asset_host = "http://assets.example.com"
28 |
29 | # Specifies the header that your server uses for sending files.
30 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache
31 | # config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX
32 |
33 | # Store uploaded files on the local file system (see config/storage.yml for options).
34 | config.active_storage.service = :local
35 |
36 | # Mount Action Cable outside main process or domain.
37 | # config.action_cable.mount_path = nil
38 | # config.action_cable.url = "wss://example.com/cable"
39 | # config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ]
40 |
41 | # Assume all access to the app is happening through a SSL-terminating reverse proxy.
42 | # Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies.
43 | # config.assume_ssl = true
44 |
45 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
46 | config.force_ssl = true
47 |
48 | # Skip http-to-https redirect for the default health check endpoint.
49 | # config.ssl_options = { redirect: { exclude: ->(request) { request.path == "/up" } } }
50 |
51 | # Log to STDOUT by default
52 | config.logger = ActiveSupport::Logger.new(STDOUT)
53 | .tap { |logger| logger.formatter = ::Logger::Formatter.new }
54 | .then { |logger| ActiveSupport::TaggedLogging.new(logger) }
55 |
56 | # Prepend all log lines with the following tags.
57 | config.log_tags = [ :request_id ]
58 |
59 | # "info" includes generic and useful information about system operation, but avoids logging too much
60 | # information to avoid inadvertent exposure of personally identifiable information (PII). If you
61 | # want to log everything, set the level to "debug".
62 | config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info")
63 |
64 | # Use a different cache store in production.
65 | # config.cache_store = :mem_cache_store
66 |
67 | # Use a real queuing backend for Active Job (and separate queues per environment).
68 | # config.active_job.queue_adapter = :resque
69 | # config.active_job.queue_name_prefix = "rails_ralix_tailwind_production"
70 |
71 | # Disable caching for Action Mailer templates even if Action Controller
72 | # caching is enabled.
73 | config.action_mailer.perform_caching = false
74 |
75 | # Ignore bad email addresses and do not raise email delivery errors.
76 | # Set this to true and configure the email server for immediate delivery to raise delivery errors.
77 | # config.action_mailer.raise_delivery_errors = false
78 |
79 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
80 | # the I18n.default_locale when a translation cannot be found).
81 | config.i18n.fallbacks = true
82 |
83 | # Don't log any deprecations.
84 | config.active_support.report_deprecations = false
85 |
86 | # Do not dump schema after migrations.
87 | config.active_record.dump_schema_after_migration = false
88 |
89 | # Enable DNS rebinding protection and other `Host` header attacks.
90 | # config.hosts = [
91 | # "example.com", # Allow requests from example.com
92 | # /.*\.example\.com/ # Allow requests from subdomains like `www.example.com`
93 | # ]
94 | # Skip DNS rebinding protection for the default health check endpoint.
95 | # config.host_authorization = { exclude: ->(request) { request.path == "/up" } }
96 | end
97 |
--------------------------------------------------------------------------------
/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | require "active_support/core_ext/integer/time"
2 |
3 | # The test environment is used exclusively to run your application's
4 | # test suite. You never need to work with it otherwise. Remember that
5 | # your test database is "scratch space" for the test suite and is wiped
6 | # and recreated between test runs. Don't rely on the data there!
7 |
8 | Rails.application.configure do
9 | # Settings specified here will take precedence over those in config/application.rb.
10 |
11 | # While tests run files are not watched, reloading is not necessary.
12 | config.enable_reloading = false
13 |
14 | # Eager loading loads your entire application. When running a single test locally,
15 | # this is usually not necessary, and can slow down your test suite. However, it's
16 | # recommended that you enable it in continuous integration systems to ensure eager
17 | # loading is working properly before deploying your code.
18 | config.eager_load = ENV["CI"].present?
19 |
20 | # Configure public file server for tests with Cache-Control for performance.
21 | config.public_file_server.headers = { "Cache-Control" => "public, max-age=#{1.hour.to_i}" }
22 |
23 | # Show full error reports and disable caching.
24 | config.consider_all_requests_local = true
25 | config.action_controller.perform_caching = false
26 | config.cache_store = :null_store
27 |
28 | # Render exception templates for rescuable exceptions and raise for other exceptions.
29 | config.action_dispatch.show_exceptions = :rescuable
30 |
31 | # Disable request forgery protection in test environment.
32 | config.action_controller.allow_forgery_protection = false
33 |
34 | # Store uploaded files on the local file system in a temporary directory.
35 | config.active_storage.service = :test
36 |
37 | # Disable caching for Action Mailer templates even if Action Controller
38 | # caching is enabled.
39 | config.action_mailer.perform_caching = false
40 |
41 | # Tell Action Mailer not to deliver emails to the real world.
42 | # The :test delivery method accumulates sent emails in the
43 | # ActionMailer::Base.deliveries array.
44 | config.action_mailer.delivery_method = :test
45 |
46 | # Unlike controllers, the mailer instance doesn't have any context about the
47 | # incoming request so you'll need to provide the :host parameter yourself.
48 | config.action_mailer.default_url_options = { host: "www.example.com" }
49 |
50 | # Print deprecation notices to the stderr.
51 | config.active_support.deprecation = :stderr
52 |
53 | # Raise exceptions for disallowed deprecations.
54 | config.active_support.disallowed_deprecation = :raise
55 |
56 | # Tell Active Support which deprecation messages to disallow.
57 | config.active_support.disallowed_deprecation_warnings = []
58 |
59 | # Raises error for missing translations.
60 | # config.i18n.raise_on_missing_translations = true
61 |
62 | # Annotate rendered view with file names.
63 | # config.action_view.annotate_rendered_view_with_filenames = true
64 |
65 | # Raise error when a before_action's only/except options reference missing actions.
66 | config.action_controller.raise_on_missing_callback_actions = true
67 | end
68 |
--------------------------------------------------------------------------------
/config/initializers/action_text.rb:
--------------------------------------------------------------------------------
1 | class ActionText::Record < ActiveRecord::Base
2 | def self.ransackable_attributes(auth_object = nil)
3 | ["body"]
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/config/initializers/content_security_policy.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Define an application-wide content security policy.
4 | # See the Securing Rails Applications Guide for more information:
5 | # https://guides.rubyonrails.org/security.html#content-security-policy-header
6 |
7 | # Rails.application.configure do
8 | # config.content_security_policy do |policy|
9 | # policy.default_src :self, :https
10 | # policy.font_src :self, :https, :data
11 | # policy.img_src :self, :https, :data
12 | # policy.object_src :none
13 | # policy.script_src :self, :https
14 | # policy.style_src :self, :https
15 | # # Specify URI for violation reports
16 | # # policy.report_uri "/csp-violation-report-endpoint"
17 | # end
18 | #
19 | # # Generate session nonces for permitted importmap, inline scripts, and inline styles.
20 | # config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s }
21 | # config.content_security_policy_nonce_directives = %w(script-src style-src)
22 | #
23 | # # Report violations without enforcing the policy.
24 | # # config.content_security_policy_report_only = true
25 | # end
26 |
--------------------------------------------------------------------------------
/config/initializers/devise.rb:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | # Assuming you have not yet modified this file, each configuration option below
4 | # is set to its default value. Note that some are commented out while others
5 | # are not: uncommented lines are intended to protect your configuration from
6 | # breaking changes in upgrades (i.e., in the event that future versions of
7 | # Devise change the default values for those options).
8 | #
9 | # Use this hook to configure devise mailer, warden hooks and so forth.
10 | # Many of these configuration options can be set straight in your model.
11 | Devise.setup do |config|
12 | # The secret key used by Devise. Devise uses this key to generate
13 | # random tokens. Changing this key will render invalid all existing
14 | # confirmation, reset password and unlock tokens in the database.
15 | # Devise will use the `secret_key_base` as its `secret_key`
16 | # by default. You can change it below and use your own secret key.
17 | # config.secret_key = '6a79f69214018eba845c16fc7413df7428bb9fe9d07a579b26050f85e110825cf10cf45b91f65c1e5c394753ebf8813f0323cfcf4e26f7cd55133ee149af81a2'
18 |
19 | # ==> Controller configuration
20 | # Configure the parent class to the devise controllers.
21 | # config.parent_controller = 'DeviseController'
22 |
23 | # ==> Mailer Configuration
24 | # Configure the e-mail address which will be shown in Devise::Mailer,
25 | # note that it will be overwritten if you use your own mailer class
26 | # with default "from" parameter.
27 | # config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com'
28 |
29 | # Configure the class responsible to send e-mails.
30 | # config.mailer = 'Devise::Mailer'
31 |
32 | # Configure the parent class responsible to send e-mails.
33 | config.parent_mailer = 'ApplicationMailer'
34 |
35 | # ==> ORM configuration
36 | # Load and configure the ORM. Supports :active_record (default) and
37 | # :mongoid (bson_ext recommended) by default. Other ORMs may be
38 | # available as additional gems.
39 | require 'devise/orm/active_record'
40 |
41 | # ==> Configuration for any authentication mechanism
42 | # Configure which keys are used when authenticating a user. The default is
43 | # just :email. You can configure it to use [:username, :subdomain], so for
44 | # authenticating a user, both parameters are required. Remember that those
45 | # parameters are used only when authenticating and not when retrieving from
46 | # session. If you need permissions, you should implement that in a before filter.
47 | # You can also supply a hash where the value is a boolean determining whether
48 | # or not authentication should be aborted when the value is not present.
49 | # config.authentication_keys = [:email]
50 |
51 | # Configure parameters from the request object used for authentication. Each entry
52 | # given should be a request method and it will automatically be passed to the
53 | # find_for_authentication method and considered in your model lookup. For instance,
54 | # if you set :request_keys to [:subdomain], :subdomain will be used on authentication.
55 | # The same considerations mentioned for authentication_keys also apply to request_keys.
56 | # config.request_keys = []
57 |
58 | # Configure which authentication keys should be case-insensitive.
59 | # These keys will be downcased upon creating or modifying a user and when used
60 | # to authenticate or find a user. Default is :email.
61 | config.case_insensitive_keys = [:email]
62 |
63 | # Configure which authentication keys should have whitespace stripped.
64 | # These keys will have whitespace before and after removed upon creating or
65 | # modifying a user and when used to authenticate or find a user. Default is :email.
66 | config.strip_whitespace_keys = [:email]
67 |
68 | # Tell if authentication through request.params is enabled. True by default.
69 | # It can be set to an array that will enable params authentication only for the
70 | # given strategies, for example, `config.params_authenticatable = [:database]` will
71 | # enable it only for database (email + password) authentication.
72 | # config.params_authenticatable = true
73 |
74 | # Tell if authentication through HTTP Auth is enabled. False by default.
75 | # It can be set to an array that will enable http authentication only for the
76 | # given strategies, for example, `config.http_authenticatable = [:database]` will
77 | # enable it only for database authentication.
78 | # For API-only applications to support authentication "out-of-the-box", you will likely want to
79 | # enable this with :database unless you are using a custom strategy.
80 | # The supported strategies are:
81 | # :database = Support basic authentication with authentication key + password
82 | # config.http_authenticatable = false
83 |
84 | # If 401 status code should be returned for AJAX requests. True by default.
85 | # config.http_authenticatable_on_xhr = true
86 |
87 | # The realm used in Http Basic Authentication. 'Application' by default.
88 | # config.http_authentication_realm = 'Application'
89 |
90 | # It will change confirmation, password recovery and other workflows
91 | # to behave the same regardless if the e-mail provided was right or wrong.
92 | # Does not affect registerable.
93 | config.paranoid = true
94 |
95 | # By default Devise will store the user in session. You can skip storage for
96 | # particular strategies by setting this option.
97 | # Notice that if you are skipping storage for all authentication paths, you
98 | # may want to disable generating routes to Devise's sessions controller by
99 | # passing skip: :sessions to `devise_for` in your config/routes.rb
100 | config.skip_session_storage = [:http_auth]
101 |
102 | # By default, Devise cleans up the CSRF token on authentication to
103 | # avoid CSRF token fixation attacks. This means that, when using AJAX
104 | # requests for sign in and sign up, you need to get a new CSRF token
105 | # from the server. You can disable this option at your own risk.
106 | # config.clean_up_csrf_token_on_authentication = true
107 |
108 | # When false, Devise will not attempt to reload routes on eager load.
109 | # This can reduce the time taken to boot the app but if your application
110 | # requires the Devise mappings to be loaded during boot time the application
111 | # won't boot properly.
112 | # config.reload_routes = true
113 |
114 | # ==> Configuration for :database_authenticatable
115 | # For bcrypt, this is the cost for hashing the password and defaults to 12. If
116 | # using other algorithms, it sets how many times you want the password to be hashed.
117 | # The number of stretches used for generating the hashed password are stored
118 | # with the hashed password. This allows you to change the stretches without
119 | # invalidating existing passwords.
120 | #
121 | # Limiting the stretches to just one in testing will increase the performance of
122 | # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use
123 | # a value less than 10 in other environments. Note that, for bcrypt (the default
124 | # algorithm), the cost increases exponentially with the number of stretches (e.g.
125 | # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation).
126 | config.stretches = Rails.env.test? ? 1 : 12
127 |
128 | # Set up a pepper to generate the hashed password.
129 | # config.pepper = '7867dd16f8db2c36d1edfe0d8b3996b8c4af1b24e3b257bf5c14e5318434e819c51e9b2119a594f8ac531a2ef5edb45e445f8e1b8758c05d5bf4baa6a90e47a4'
130 |
131 | # Send a notification to the original email when the user's email is changed.
132 | # config.send_email_changed_notification = false
133 |
134 | # Send a notification email when the user's password is changed.
135 | # config.send_password_change_notification = false
136 |
137 | # ==> Configuration for :confirmable
138 | # A period that the user is allowed to access the website even without
139 | # confirming their account. For instance, if set to 2.days, the user will be
140 | # able to access the website for two days without confirming their account,
141 | # access will be blocked just in the third day.
142 | # You can also set it to nil, which will allow the user to access the website
143 | # without confirming their account.
144 | # Default is 0.days, meaning the user cannot access the website without
145 | # confirming their account.
146 | # config.allow_unconfirmed_access_for = 2.days
147 |
148 | # A period that the user is allowed to confirm their account before their
149 | # token becomes invalid. For example, if set to 3.days, the user can confirm
150 | # their account within 3 days after the mail was sent, but on the fourth day
151 | # their account can't be confirmed with the token any more.
152 | # Default is nil, meaning there is no restriction on how long a user can take
153 | # before confirming their account.
154 | # config.confirm_within = 3.days
155 |
156 | # If true, requires any email changes to be confirmed (exactly the same way as
157 | # initial account confirmation) to be applied. Requires additional unconfirmed_email
158 | # db field (see migrations). Until confirmed, new email is stored in
159 | # unconfirmed_email column, and copied to email column on successful confirmation.
160 | config.reconfirmable = true
161 |
162 | # Defines which key will be used when confirming an account
163 | # config.confirmation_keys = [:email]
164 |
165 | # ==> Configuration for :rememberable
166 | # The time the user will be remembered without asking for credentials again.
167 | config.remember_for = 1.week
168 |
169 | # Invalidates all the remember me tokens when the user signs out.
170 | config.expire_all_remember_me_on_sign_out = true
171 |
172 | # If true, extends the user's remember period when remembered via cookie.
173 | # config.extend_remember_period = false
174 |
175 | # Options to be passed to the created cookie. For instance, you can set
176 | # secure: true in order to force SSL only cookies.
177 | # config.rememberable_options = {}
178 |
179 | # ==> Configuration for :validatable
180 | # Range for password length.
181 | config.password_length = 8..128
182 |
183 | # Email regex used to validate email formats. It simply asserts that
184 | # one (and only one) @ exists in the given string. This is mainly
185 | # to give user feedback and not to assert the e-mail validity.
186 | config.email_regexp = /\A[^@\s]+@[^@\s]+\z/
187 |
188 | # ==> Configuration for :timeoutable
189 | # The time you want to timeout the user session without activity. After this
190 | # time the user will be asked for credentials again. Default is 30 minutes.
191 | # config.timeout_in = 30.minutes
192 |
193 | # ==> Configuration for :lockable
194 | # Defines which strategy will be used to lock an account.
195 | # :failed_attempts = Locks an account after a number of failed attempts to sign in.
196 | # :none = No lock strategy. You should handle locking by yourself.
197 | # config.lock_strategy = :failed_attempts
198 |
199 | # Defines which key will be used when locking and unlocking an account
200 | # config.unlock_keys = [:email]
201 |
202 | # Defines which strategy will be used to unlock an account.
203 | # :email = Sends an unlock link to the user email
204 | # :time = Re-enables login after a certain amount of time (see :unlock_in below)
205 | # :both = Enables both strategies
206 | # :none = No unlock strategy. You should handle unlocking by yourself.
207 | # config.unlock_strategy = :both
208 |
209 | # Number of authentication tries before locking an account if lock_strategy
210 | # is failed attempts.
211 | # config.maximum_attempts = 20
212 |
213 | # Time interval to unlock the account if :time is enabled as unlock_strategy.
214 | # config.unlock_in = 1.hour
215 |
216 | # Warn on the last attempt before the account is locked.
217 | # config.last_attempt_warning = true
218 |
219 | # ==> Configuration for :recoverable
220 | #
221 | # Defines which key will be used when recovering the password for an account
222 | # config.reset_password_keys = [:email]
223 |
224 | # Time interval you can reset your password with a reset password key.
225 | # Don't put a too small interval or your users won't have the time to
226 | # change their passwords.
227 | config.reset_password_within = 6.hours
228 |
229 | # When set to false, does not sign a user in automatically after their password is
230 | # reset. Defaults to true, so a user is signed in automatically after a reset.
231 | # config.sign_in_after_reset_password = true
232 |
233 | # ==> Configuration for :encryptable
234 | # Allow you to use another hashing or encryption algorithm besides bcrypt (default).
235 | # You can use :sha1, :sha512 or algorithms from others authentication tools as
236 | # :clearance_sha1, :authlogic_sha512 (then you should set stretches above to 20
237 | # for default behavior) and :restful_authentication_sha1 (then you should set
238 | # stretches to 10, and copy REST_AUTH_SITE_KEY to pepper).
239 | #
240 | # Require the `devise-encryptable` gem when using anything other than bcrypt
241 | # config.encryptor = :sha512
242 |
243 | # ==> Scopes configuration
244 | # Turn scoped views on. Before rendering "sessions/new", it will first check for
245 | # "users/sessions/new". It's turned off by default because it's slower if you
246 | # are using only default views.
247 | # config.scoped_views = false
248 |
249 | # Configure the default scope given to Warden. By default it's the first
250 | # devise role declared in your routes (usually :user).
251 | # config.default_scope = :user
252 |
253 | # Set this configuration to false if you want /users/sign_out to sign out
254 | # only the current scope. By default, Devise signs out all scopes.
255 | # config.sign_out_all_scopes = true
256 |
257 | # ==> Navigation configuration
258 | # Lists the formats that should be treated as navigational. Formats like
259 | # :html, should redirect to the sign in page when the user does not have
260 | # access, but formats like :xml or :json, should return 401.
261 | #
262 | # If you have any extra navigational formats, like :iphone or :mobile, you
263 | # should add them to the navigational formats lists.
264 | #
265 | # The "*/*" below is required to match Internet Explorer requests.
266 | # config.navigational_formats = ['*/*', :html]
267 |
268 | # The default HTTP method used to sign out a resource. Default is :delete.
269 | config.sign_out_via = :delete
270 |
271 | # ==> OmniAuth
272 | # Add a new OmniAuth provider. Check the wiki for more information on setting
273 | # up on your models and hooks.
274 | config.omniauth :facebook, ENV['FACEBOOK_CLIENT_ID'], ENV['FACEBOOK_CLIENT_SECRET']
275 | config.omniauth :github, ENV['GITHUB_CLIENT_ID'], ENV['GITHUB_CLIENT_SECRET']
276 | config.omniauth :google_oauth2, ENV['GOOGLE_CLIENT_ID'], ENV['GOOGLE_CLIENT_SECRET']
277 |
278 | # ==> Warden configuration
279 | # If you want to use other strategies, that are not supported by Devise, or
280 | # change the failure app, you can configure them inside the config.warden block.
281 | #
282 | # config.warden do |manager|
283 | # manager.intercept_401 = false
284 | # manager.default_strategies(scope: :user).unshift :some_external_strategy
285 | # end
286 |
287 | # ==> Mountable engine configurations
288 | # When using Devise inside an engine, let's call it `MyEngine`, and this engine
289 | # is mountable, there are some extra configurations to be taken into account.
290 | # The following options are available, assuming the engine is mounted as:
291 | #
292 | # mount MyEngine, at: '/my_engine'
293 | #
294 | # The router that invoked `devise_for`, in the example above, would be:
295 | # config.router_name = :my_engine
296 | #
297 | # When using OmniAuth, Devise cannot automatically set OmniAuth path,
298 | # so you need to do it manually. For the users scope, it would be:
299 | # config.omniauth_path_prefix = '/my_engine/users/auth'
300 |
301 | # ==> Turbolinks configuration
302 | # If your app is using Turbolinks, Turbolinks::Controller needs to be included to make redirection work correctly:
303 | #
304 | # ActiveSupport.on_load(:devise_failure_app) do
305 | # include Turbolinks::Controller
306 | # end
307 |
308 | # ==> Configuration for :registerable
309 |
310 | # When set to false, does not sign a user in automatically after their password is
311 | # changed. Defaults to true, so a user is signed in automatically after changing a password.
312 | # config.sign_in_after_change_password = true
313 | end
314 |
--------------------------------------------------------------------------------
/config/initializers/filter_parameter_logging.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file.
4 | # Use this to limit dissemination of sensitive information.
5 | # See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors.
6 | Rails.application.config.filter_parameters += [
7 | :passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn
8 | ]
9 |
--------------------------------------------------------------------------------
/config/initializers/heroicon.rb:
--------------------------------------------------------------------------------
1 | Heroicon.configure do |config|
2 | config.variant = :outline
3 | config.default_class = {
4 | outline: "w-5 h-5 inline"
5 | }
6 | end
7 |
--------------------------------------------------------------------------------
/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new inflection rules using the following format. Inflections
4 | # are locale specific, and you may define rules for as many different
5 | # locales as you wish. All of these examples are active by default:
6 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
7 | # inflect.plural /^(ox)$/i, "\\1en"
8 | # inflect.singular /^(ox)en/i, "\\1"
9 | # inflect.irregular "person", "people"
10 | # inflect.uncountable %w( fish sheep )
11 | # end
12 |
13 | # These inflection rules are supported but not enabled by default:
14 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
15 | # inflect.acronym "RESTful"
16 | # end
17 |
--------------------------------------------------------------------------------
/config/initializers/permissions_policy.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Define an application-wide HTTP permissions policy. For further
4 | # information see: https://developers.google.com/web/updates/2018/06/feature-policy
5 |
6 | # Rails.application.config.permissions_policy do |policy|
7 | # policy.camera :none
8 | # policy.gyroscope :none
9 | # policy.microphone :none
10 | # policy.usb :none
11 | # policy.fullscreen :self
12 | # policy.payment :self, "https://secure.example.com"
13 | # end
14 |
--------------------------------------------------------------------------------
/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | # Files in the config/locales directory are used for internationalization
2 | # and are automatically loaded by Rails. If you want to use locales other
3 | # than English, add the necessary files in this directory.
4 | #
5 | # To use the locales, use `I18n.t`:
6 | #
7 | # I18n.t "hello"
8 | #
9 | # In views, this is aliased to just `t`:
10 | #
11 | # <%= t("hello") %>
12 | #
13 | # To use a different locale, set it with `I18n.locale`:
14 | #
15 | # I18n.locale = :es
16 | #
17 | # This would use the information in config/locales/es.yml.
18 | #
19 | # The following keys must be escaped otherwise they will not be retrieved by
20 | # the default I18n backend:
21 | #
22 | # true, false, on, off, yes, no
23 | #
24 | # Instead, surround them with single quotes.
25 | #
26 | # en:
27 | # "true": "foo"
28 | #
29 | # To learn more, please read the Rails Internationalization guide
30 | # available at https://guides.rubyonrails.org/i18n.html.
31 |
32 | en:
33 | hello: "Hello world"
34 |
--------------------------------------------------------------------------------
/config/puma.rb:
--------------------------------------------------------------------------------
1 | # This configuration file will be evaluated by Puma. The top-level methods that
2 | # are invoked here are part of Puma's configuration DSL. For more information
3 | # about methods provided by the DSL, see https://puma.io/puma/Puma/DSL.html.
4 |
5 | # Puma starts a configurable number of processes (workers) and each process
6 | # serves each request in a thread from an internal thread pool.
7 | #
8 | # The ideal number of threads per worker depends both on how much time the
9 | # application spends waiting for IO operations and on how much you wish to
10 | # to prioritize throughput over latency.
11 | #
12 | # As a rule of thumb, increasing the number of threads will increase how much
13 | # traffic a given process can handle (throughput), but due to CRuby's
14 | # Global VM Lock (GVL) it has diminishing returns and will degrade the
15 | # response time (latency) of the application.
16 | #
17 | # The default is set to 3 threads as it's deemed a decent compromise between
18 | # throughput and latency for the average Rails application.
19 | #
20 | # Any libraries that use a connection pool or another resource pool should
21 | # be configured to provide at least as many connections as the number of
22 | # threads. This includes Active Record's `pool` parameter in `database.yml`.
23 | threads_count = ENV.fetch("RAILS_MAX_THREADS", 3)
24 | threads threads_count, threads_count
25 |
26 | # Specifies the `port` that Puma will listen on to receive requests; default is 3000.
27 | port ENV.fetch("PORT", 3000)
28 |
29 | # Allow puma to be restarted by `bin/rails restart` command.
30 | plugin :tmp_restart
31 |
32 | # Specify the PID file. Defaults to tmp/pids/server.pid in development.
33 | # In other environments, only set the PID file if requested.
34 | pidfile ENV["PIDFILE"] if ENV["PIDFILE"]
35 |
--------------------------------------------------------------------------------
/config/routes.rb:
--------------------------------------------------------------------------------
1 | Rails.application.routes.draw do
2 | devise_for :users, controllers: {
3 | omniauth_callbacks: 'users/omniauth_callbacks'
4 | }
5 |
6 | root "home#index"
7 |
8 | resources :articles
9 | resource :user, only: %i[edit update destroy]
10 | resources :users, only: %i[index show]
11 |
12 | get "/pages/:page" => "pages#show", as: :page
13 |
14 | match '/404', to: 'errors#not_found', via: :all
15 | match '/422', to: 'errors#internal_server_error', via: :all
16 | match '/500', to: 'errors#internal_server_error', via: :all
17 | end
18 |
--------------------------------------------------------------------------------
/config/storage.yml:
--------------------------------------------------------------------------------
1 | test:
2 | service: Disk
3 | root: <%= Rails.root.join("tmp/storage") %>
4 |
5 | local:
6 | service: Disk
7 | root: <%= Rails.root.join("storage") %>
8 |
--------------------------------------------------------------------------------
/db/migrate/20220831194622_create_articles.rb:
--------------------------------------------------------------------------------
1 | class CreateArticles < ActiveRecord::Migration[7.0]
2 | def change
3 | create_table :articles do |t|
4 | t.string :title
5 | t.references :user
6 |
7 | t.timestamps
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/db/migrate/20220831213127_devise_create_users.rb:
--------------------------------------------------------------------------------
1 | class DeviseCreateUsers < ActiveRecord::Migration[7.0]
2 | def change
3 | create_table :users do |t|
4 | # Database authenticatable
5 | t.string :email, null: false, default: ""
6 | t.string :encrypted_password, null: false, default: ""
7 |
8 | # Recoverable
9 | t.string :reset_password_token
10 | t.datetime :reset_password_sent_at
11 |
12 | # Rememberable
13 | t.datetime :remember_created_at
14 |
15 | t.timestamps null: false
16 | end
17 |
18 | add_index :users, :email, unique: true
19 | add_index :users, :reset_password_token, unique: true
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/db/migrate/20220831235947_add_name_to_users.rb:
--------------------------------------------------------------------------------
1 | class AddNameToUsers < ActiveRecord::Migration[7.0]
2 | def change
3 | add_column :users, :name, :string
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/db/migrate/20221005175500_create_active_storage_tables.active_storage.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from active_storage (originally 20170806125915)
2 | class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
3 | def change
4 | # Use Active Record's configured type for primary and foreign keys
5 | primary_key_type, foreign_key_type = primary_and_foreign_key_types
6 |
7 | create_table :active_storage_blobs, id: primary_key_type do |t|
8 | t.string :key, null: false
9 | t.string :filename, null: false
10 | t.string :content_type
11 | t.text :metadata
12 | t.string :service_name, null: false
13 | t.bigint :byte_size, null: false
14 | t.string :checksum
15 |
16 | if connection.supports_datetime_with_precision?
17 | t.datetime :created_at, precision: 6, null: false
18 | else
19 | t.datetime :created_at, null: false
20 | end
21 |
22 | t.index [ :key ], unique: true
23 | end
24 |
25 | create_table :active_storage_attachments, id: primary_key_type do |t|
26 | t.string :name, null: false
27 | t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type
28 | t.references :blob, null: false, type: foreign_key_type
29 |
30 | if connection.supports_datetime_with_precision?
31 | t.datetime :created_at, precision: 6, null: false
32 | else
33 | t.datetime :created_at, null: false
34 | end
35 |
36 | t.index [ :record_type, :record_id, :name, :blob_id ], name: :index_active_storage_attachments_uniqueness, unique: true
37 | t.foreign_key :active_storage_blobs, column: :blob_id
38 | end
39 |
40 | create_table :active_storage_variant_records, id: primary_key_type do |t|
41 | t.belongs_to :blob, null: false, index: false, type: foreign_key_type
42 | t.string :variation_digest, null: false
43 |
44 | t.index [ :blob_id, :variation_digest ], name: :index_active_storage_variant_records_uniqueness, unique: true
45 | t.foreign_key :active_storage_blobs, column: :blob_id
46 | end
47 | end
48 |
49 | private
50 | def primary_and_foreign_key_types
51 | config = Rails.configuration.generators
52 | setting = config.options[config.orm][:primary_key_type]
53 | primary_key_type = setting || :primary_key
54 | foreign_key_type = setting || :bigint
55 | [primary_key_type, foreign_key_type]
56 | end
57 | end
58 |
--------------------------------------------------------------------------------
/db/migrate/20230525120314_create_action_text_tables.action_text.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from action_text (originally 20180528164100)
2 | class CreateActionTextTables < ActiveRecord::Migration[6.0]
3 | def change
4 | # Use Active Record's configured type for primary and foreign keys
5 | primary_key_type, foreign_key_type = primary_and_foreign_key_types
6 |
7 | create_table :action_text_rich_texts, id: primary_key_type do |t|
8 | t.string :name, null: false
9 | t.text :body, size: :long
10 | t.references :record, null: false, polymorphic: true, index: false, type: foreign_key_type
11 |
12 | t.timestamps
13 |
14 | t.index [ :record_type, :record_id, :name ], name: "index_action_text_rich_texts_uniqueness", unique: true
15 | end
16 | end
17 |
18 | private
19 | def primary_and_foreign_key_types
20 | config = Rails.configuration.generators
21 | setting = config.options[config.orm][:primary_key_type]
22 | primary_key_type = setting || :primary_key
23 | foreign_key_type = setting || :bigint
24 | [primary_key_type, foreign_key_type]
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/db/schema.rb:
--------------------------------------------------------------------------------
1 | # This file is auto-generated from the current state of the database. Instead
2 | # of editing this file, please use the migrations feature of Active Record to
3 | # incrementally modify your database, and then regenerate this schema definition.
4 | #
5 | # This file is the source Rails uses to define your schema when running `bin/rails
6 | # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
7 | # be faster and is potentially less error prone than running all of your
8 | # migrations from scratch. Old migrations may fail to apply correctly if those
9 | # migrations use external dependencies or application code.
10 | #
11 | # It's strongly recommended that you check this file into your version control system.
12 |
13 | ActiveRecord::Schema[7.2].define(version: 2024_09_27_114004) do
14 | # These are extensions that must be enabled in order to support this database
15 | enable_extension "plpgsql"
16 |
17 | create_table "action_text_rich_texts", force: :cascade do |t|
18 | t.string "name", null: false
19 | t.text "body"
20 | t.string "record_type", null: false
21 | t.bigint "record_id", null: false
22 | t.datetime "created_at", null: false
23 | t.datetime "updated_at", null: false
24 | t.index ["record_type", "record_id", "name"], name: "index_action_text_rich_texts_uniqueness", unique: true
25 | end
26 |
27 | create_table "active_storage_attachments", force: :cascade do |t|
28 | t.string "name", null: false
29 | t.string "record_type", null: false
30 | t.bigint "record_id", null: false
31 | t.bigint "blob_id", null: false
32 | t.datetime "created_at", null: false
33 | t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
34 | t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
35 | end
36 |
37 | create_table "active_storage_blobs", force: :cascade do |t|
38 | t.string "key", null: false
39 | t.string "filename", null: false
40 | t.string "content_type"
41 | t.text "metadata"
42 | t.string "service_name", null: false
43 | t.bigint "byte_size", null: false
44 | t.string "checksum"
45 | t.datetime "created_at", null: false
46 | t.index ["key"], name: "index_active_storage_blobs_on_key", unique: true
47 | end
48 |
49 | create_table "active_storage_variant_records", force: :cascade do |t|
50 | t.bigint "blob_id", null: false
51 | t.string "variation_digest", null: false
52 | t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true
53 | end
54 |
55 | create_table "articles", force: :cascade do |t|
56 | t.string "title"
57 | t.text "body"
58 | t.bigint "user_id"
59 | t.datetime "created_at", null: false
60 | t.datetime "updated_at", null: false
61 | t.index ["user_id"], name: "index_articles_on_user_id"
62 | end
63 |
64 | create_table "users", force: :cascade do |t|
65 | t.string "email", default: "", null: false
66 | t.string "encrypted_password", default: "", null: false
67 | t.string "reset_password_token"
68 | t.datetime "reset_password_sent_at"
69 | t.datetime "remember_created_at"
70 | t.datetime "created_at", null: false
71 | t.datetime "updated_at", null: false
72 | t.string "name"
73 | t.index ["email"], name: "index_users_on_email", unique: true
74 | t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
75 | end
76 |
77 | add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
78 | add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
79 | end
80 |
--------------------------------------------------------------------------------
/db/seeds.rb:
--------------------------------------------------------------------------------
1 | if User.none?
2 | 10.times do
3 | User.create!(
4 | name: Faker::Name.name,
5 | email: Faker::Internet.email,
6 | password: "1234asdf"
7 | )
8 | end
9 | end
10 |
11 | if Article.none?
12 | 20.times do
13 | Article.create!(
14 | title: Faker::Commerce.product_name,
15 | body: Faker::Lorem.paragraphs(number: 5).join,
16 | user: User.all.sample
17 | )
18 | end
19 | end
20 |
--------------------------------------------------------------------------------
/lib/tasks/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ralixjs/rails-ralix-tailwind/f476049dd9c7ef07868148da8615cba4e463da09/lib/tasks/.keep
--------------------------------------------------------------------------------
/log/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ralixjs/rails-ralix-tailwind/f476049dd9c7ef07868148da8615cba4e463da09/log/.keep
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "app",
3 | "private": "true",
4 | "dependencies": {
5 | "@hotwired/turbo-rails": "^8.0.0",
6 | "@rails/actiontext": "^7.2.0",
7 | "@tailwindcss/forms": "^0.5.9",
8 | "esbuild": "^0.25.0",
9 | "micromodal": "^0.4.10",
10 | "ralix": "^1.4.0",
11 | "tailwindcss": "^3.4.13",
12 | "tippy.js": "^6.3.7",
13 | "trix": "^2.1.15"
14 | },
15 | "scripts": {
16 | "build": "esbuild app/javascript/*.* --bundle --sourcemap --outdir=app/assets/builds --public-path=assets",
17 | "build:css": "tailwindcss -i ./app/assets/stylesheets/application.css -o ./app/assets/builds/application.css --minify"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ralixjs/rails-ralix-tailwind/f476049dd9c7ef07868148da8615cba4e463da09/public/favicon.ico
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # See https://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file
2 |
--------------------------------------------------------------------------------
/storage/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ralixjs/rails-ralix-tailwind/f476049dd9c7ef07868148da8615cba4e463da09/storage/.keep
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | content: [
3 | './app/views/**/*.html.erb',
4 | './app/helpers/**/*.rb',
5 | './app/assets/stylesheets/**/*.css',
6 | './app/javascript/**/*.js',
7 | './config/initializers/heroicon.rb'
8 | ],
9 | plugins: [
10 | require('@tailwindcss/forms')
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/tmp/.keep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ralixjs/rails-ralix-tailwind/f476049dd9c7ef07868148da8615cba4e463da09/tmp/.keep
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@alloc/quick-lru@^5.2.0":
6 | version "5.2.0"
7 | resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30"
8 | integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==
9 |
10 | "@esbuild/aix-ppc64@0.25.0":
11 | version "0.25.0"
12 | resolved "https://registry.yarnpkg.com/@esbuild/aix-ppc64/-/aix-ppc64-0.25.0.tgz#499600c5e1757a524990d5d92601f0ac3ce87f64"
13 | integrity sha512-O7vun9Sf8DFjH2UtqK8Ku3LkquL9SZL8OLY1T5NZkA34+wG3OQF7cl4Ql8vdNzM6fzBbYfLaiRLIOZ+2FOCgBQ==
14 |
15 | "@esbuild/android-arm64@0.25.0":
16 | version "0.25.0"
17 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.25.0.tgz#b9b8231561a1dfb94eb31f4ee056b92a985c324f"
18 | integrity sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==
19 |
20 | "@esbuild/android-arm@0.25.0":
21 | version "0.25.0"
22 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.25.0.tgz#ca6e7888942505f13e88ac9f5f7d2a72f9facd2b"
23 | integrity sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==
24 |
25 | "@esbuild/android-x64@0.25.0":
26 | version "0.25.0"
27 | resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.25.0.tgz#e765ea753bac442dfc9cb53652ce8bd39d33e163"
28 | integrity sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==
29 |
30 | "@esbuild/darwin-arm64@0.25.0":
31 | version "0.25.0"
32 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.25.0.tgz#fa394164b0d89d4fdc3a8a21989af70ef579fa2c"
33 | integrity sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==
34 |
35 | "@esbuild/darwin-x64@0.25.0":
36 | version "0.25.0"
37 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.25.0.tgz#91979d98d30ba6e7d69b22c617cc82bdad60e47a"
38 | integrity sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==
39 |
40 | "@esbuild/freebsd-arm64@0.25.0":
41 | version "0.25.0"
42 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.0.tgz#b97e97073310736b430a07b099d837084b85e9ce"
43 | integrity sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==
44 |
45 | "@esbuild/freebsd-x64@0.25.0":
46 | version "0.25.0"
47 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.25.0.tgz#f3b694d0da61d9910ec7deff794d444cfbf3b6e7"
48 | integrity sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==
49 |
50 | "@esbuild/linux-arm64@0.25.0":
51 | version "0.25.0"
52 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.25.0.tgz#f921f699f162f332036d5657cad9036f7a993f73"
53 | integrity sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==
54 |
55 | "@esbuild/linux-arm@0.25.0":
56 | version "0.25.0"
57 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.25.0.tgz#cc49305b3c6da317c900688995a4050e6cc91ca3"
58 | integrity sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==
59 |
60 | "@esbuild/linux-ia32@0.25.0":
61 | version "0.25.0"
62 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.25.0.tgz#3e0736fcfab16cff042dec806247e2c76e109e19"
63 | integrity sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==
64 |
65 | "@esbuild/linux-loong64@0.25.0":
66 | version "0.25.0"
67 | resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.25.0.tgz#ea2bf730883cddb9dfb85124232b5a875b8020c7"
68 | integrity sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==
69 |
70 | "@esbuild/linux-mips64el@0.25.0":
71 | version "0.25.0"
72 | resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.25.0.tgz#4cababb14eede09248980a2d2d8b966464294ff1"
73 | integrity sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==
74 |
75 | "@esbuild/linux-ppc64@0.25.0":
76 | version "0.25.0"
77 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.25.0.tgz#8860a4609914c065373a77242e985179658e1951"
78 | integrity sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==
79 |
80 | "@esbuild/linux-riscv64@0.25.0":
81 | version "0.25.0"
82 | resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.25.0.tgz#baf26e20bb2d38cfb86ee282dff840c04f4ed987"
83 | integrity sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==
84 |
85 | "@esbuild/linux-s390x@0.25.0":
86 | version "0.25.0"
87 | resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.25.0.tgz#8323afc0d6cb1b6dc6e9fd21efd9e1542c3640a4"
88 | integrity sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==
89 |
90 | "@esbuild/linux-x64@0.25.0":
91 | version "0.25.0"
92 | resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.25.0.tgz#08fcf60cb400ed2382e9f8e0f5590bac8810469a"
93 | integrity sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==
94 |
95 | "@esbuild/netbsd-arm64@0.25.0":
96 | version "0.25.0"
97 | resolved "https://registry.yarnpkg.com/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.0.tgz#935c6c74e20f7224918fbe2e6c6fe865b6c6ea5b"
98 | integrity sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==
99 |
100 | "@esbuild/netbsd-x64@0.25.0":
101 | version "0.25.0"
102 | resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.25.0.tgz#414677cef66d16c5a4d210751eb2881bb9c1b62b"
103 | integrity sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==
104 |
105 | "@esbuild/openbsd-arm64@0.25.0":
106 | version "0.25.0"
107 | resolved "https://registry.yarnpkg.com/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.0.tgz#8fd55a4d08d25cdc572844f13c88d678c84d13f7"
108 | integrity sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==
109 |
110 | "@esbuild/openbsd-x64@0.25.0":
111 | version "0.25.0"
112 | resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.25.0.tgz#0c48ddb1494bbc2d6bcbaa1429a7f465fa1dedde"
113 | integrity sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==
114 |
115 | "@esbuild/sunos-x64@0.25.0":
116 | version "0.25.0"
117 | resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.25.0.tgz#86ff9075d77962b60dd26203d7352f92684c8c92"
118 | integrity sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==
119 |
120 | "@esbuild/win32-arm64@0.25.0":
121 | version "0.25.0"
122 | resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.25.0.tgz#849c62327c3229467f5b5cd681bf50588442e96c"
123 | integrity sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==
124 |
125 | "@esbuild/win32-ia32@0.25.0":
126 | version "0.25.0"
127 | resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.25.0.tgz#f62eb480cd7cca088cb65bb46a6db25b725dc079"
128 | integrity sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==
129 |
130 | "@esbuild/win32-x64@0.25.0":
131 | version "0.25.0"
132 | resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.25.0.tgz#c8e119a30a7c8d60b9d2e22d2073722dde3b710b"
133 | integrity sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==
134 |
135 | "@hotwired/turbo-rails@^8.0.0":
136 | version "8.0.10"
137 | resolved "https://registry.yarnpkg.com/@hotwired/turbo-rails/-/turbo-rails-8.0.10.tgz#28b0c1243868d9efc4a71f4a2ff7d97ee9cefbfa"
138 | integrity sha512-BkERfjTbNwMb9/YQi0RL9+f9zkD+dZH2klEONtGwXrIE3O9BE1937Nn9++koZpDryD4XN3zE5U5ibyWoYJAWBg==
139 | dependencies:
140 | "@hotwired/turbo" "^8.0.6"
141 | "@rails/actioncable" "^7.0"
142 |
143 | "@hotwired/turbo@^8.0.6":
144 | version "8.0.10"
145 | resolved "https://registry.yarnpkg.com/@hotwired/turbo/-/turbo-8.0.10.tgz#d95569d259f0daad6e824ee1ada877ff94beb72b"
146 | integrity sha512-xen1YhNQirAHlA8vr/444XsTNITC1Il2l/Vx4w8hAWPpI5nQO78mVHNsmFuayETodzPwh25ob2TgfCEV/Loiog==
147 |
148 | "@isaacs/cliui@^8.0.2":
149 | version "8.0.2"
150 | resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550"
151 | integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==
152 | dependencies:
153 | string-width "^5.1.2"
154 | string-width-cjs "npm:string-width@^4.2.0"
155 | strip-ansi "^7.0.1"
156 | strip-ansi-cjs "npm:strip-ansi@^6.0.1"
157 | wrap-ansi "^8.1.0"
158 | wrap-ansi-cjs "npm:wrap-ansi@^7.0.0"
159 |
160 | "@jridgewell/gen-mapping@^0.3.2":
161 | version "0.3.5"
162 | resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36"
163 | integrity sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==
164 | dependencies:
165 | "@jridgewell/set-array" "^1.2.1"
166 | "@jridgewell/sourcemap-codec" "^1.4.10"
167 | "@jridgewell/trace-mapping" "^0.3.24"
168 |
169 | "@jridgewell/resolve-uri@^3.1.0":
170 | version "3.1.2"
171 | resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6"
172 | integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==
173 |
174 | "@jridgewell/set-array@^1.2.1":
175 | version "1.2.1"
176 | resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.2.1.tgz#558fb6472ed16a4c850b889530e6b36438c49280"
177 | integrity sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==
178 |
179 | "@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.14":
180 | version "1.5.0"
181 | resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a"
182 | integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==
183 |
184 | "@jridgewell/trace-mapping@^0.3.24":
185 | version "0.3.25"
186 | resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0"
187 | integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==
188 | dependencies:
189 | "@jridgewell/resolve-uri" "^3.1.0"
190 | "@jridgewell/sourcemap-codec" "^1.4.14"
191 |
192 | "@nodelib/fs.scandir@2.1.5":
193 | version "2.1.5"
194 | resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
195 | integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==
196 | dependencies:
197 | "@nodelib/fs.stat" "2.0.5"
198 | run-parallel "^1.1.9"
199 |
200 | "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
201 | version "2.0.5"
202 | resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b"
203 | integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
204 |
205 | "@nodelib/fs.walk@^1.2.3":
206 | version "1.2.8"
207 | resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a"
208 | integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==
209 | dependencies:
210 | "@nodelib/fs.scandir" "2.1.5"
211 | fastq "^1.6.0"
212 |
213 | "@pkgjs/parseargs@^0.11.0":
214 | version "0.11.0"
215 | resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33"
216 | integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==
217 |
218 | "@popperjs/core@^2.9.0":
219 | version "2.11.8"
220 | resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f"
221 | integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==
222 |
223 | "@rails/actioncable@^7.0":
224 | version "7.2.100"
225 | resolved "https://registry.yarnpkg.com/@rails/actioncable/-/actioncable-7.2.100.tgz#86ec1c2e00c357cef1e421fd63863d5c34339ce8"
226 | integrity sha512-7xtIENf0Yw59AFDM3+xqxPCZxev3QVAqjPmUzmgsB9eL8S/zTpB0IU9srNc7XknzJI4e09XKNnCaJRx3gfYzXA==
227 |
228 | "@rails/actiontext@^7.2.0":
229 | version "7.2.100"
230 | resolved "https://registry.yarnpkg.com/@rails/actiontext/-/actiontext-7.2.100.tgz#e235c8150d252490902f8b33026bc0a030cce8e4"
231 | integrity sha512-46oDEZdkxpbM/7+3GwSHTRyIkH3LRZRC9OE35rMIt0FcRbjXW+2Q7RL1YYjoy7megqnoCUDZglFISJQxJ/HBZg==
232 | dependencies:
233 | "@rails/activestorage" ">= 7.2.0-alpha"
234 |
235 | "@rails/activestorage@>= 7.2.0-alpha":
236 | version "7.2.100"
237 | resolved "https://registry.yarnpkg.com/@rails/activestorage/-/activestorage-7.2.100.tgz#c1e643d3c35c62c946e6f7c8d812fa567d2ce915"
238 | integrity sha512-gohCilm1E10W51Hc9iT960xX9TP11L5TJ4W1ufs9f3h5Ncsw01S/eHgVUfcdfszqw3G+28Z0MFu999+iSpgdTg==
239 | dependencies:
240 | spark-md5 "^3.0.1"
241 |
242 | "@tailwindcss/forms@^0.5.9":
243 | version "0.5.9"
244 | resolved "https://registry.yarnpkg.com/@tailwindcss/forms/-/forms-0.5.9.tgz#b495c12575d6eae5865b2cbd9876b26d89f16f61"
245 | integrity sha512-tM4XVr2+UVTxXJzey9Twx48c1gcxFStqn1pQz0tRsX8o3DvxhN5oY5pvyAbUx7VTaZxpej4Zzvc6h+1RJBzpIg==
246 | dependencies:
247 | mini-svg-data-uri "^1.2.3"
248 |
249 | "@types/trusted-types@^2.0.7":
250 | version "2.0.7"
251 | resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11"
252 | integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==
253 |
254 | ansi-regex@^5.0.1:
255 | version "5.0.1"
256 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
257 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
258 |
259 | ansi-regex@^6.0.1:
260 | version "6.1.0"
261 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654"
262 | integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==
263 |
264 | ansi-styles@^4.0.0:
265 | version "4.3.0"
266 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
267 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
268 | dependencies:
269 | color-convert "^2.0.1"
270 |
271 | ansi-styles@^6.1.0:
272 | version "6.2.1"
273 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5"
274 | integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==
275 |
276 | any-promise@^1.0.0:
277 | version "1.3.0"
278 | resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
279 | integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==
280 |
281 | anymatch@~3.1.2:
282 | version "3.1.3"
283 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e"
284 | integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==
285 | dependencies:
286 | normalize-path "^3.0.0"
287 | picomatch "^2.0.4"
288 |
289 | arg@^5.0.2:
290 | version "5.0.2"
291 | resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c"
292 | integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==
293 |
294 | balanced-match@^1.0.0:
295 | version "1.0.2"
296 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
297 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
298 |
299 | binary-extensions@^2.0.0:
300 | version "2.3.0"
301 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522"
302 | integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==
303 |
304 | brace-expansion@^2.0.1:
305 | version "2.0.1"
306 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
307 | integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
308 | dependencies:
309 | balanced-match "^1.0.0"
310 |
311 | braces@^3.0.3, braces@~3.0.2:
312 | version "3.0.3"
313 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789"
314 | integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==
315 | dependencies:
316 | fill-range "^7.1.1"
317 |
318 | camelcase-css@^2.0.1:
319 | version "2.0.1"
320 | resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5"
321 | integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==
322 |
323 | chokidar@^3.5.3:
324 | version "3.6.0"
325 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b"
326 | integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==
327 | dependencies:
328 | anymatch "~3.1.2"
329 | braces "~3.0.2"
330 | glob-parent "~5.1.2"
331 | is-binary-path "~2.1.0"
332 | is-glob "~4.0.1"
333 | normalize-path "~3.0.0"
334 | readdirp "~3.6.0"
335 | optionalDependencies:
336 | fsevents "~2.3.2"
337 |
338 | color-convert@^2.0.1:
339 | version "2.0.1"
340 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
341 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
342 | dependencies:
343 | color-name "~1.1.4"
344 |
345 | color-name@~1.1.4:
346 | version "1.1.4"
347 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
348 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
349 |
350 | commander@^4.0.0:
351 | version "4.1.1"
352 | resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
353 | integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
354 |
355 | cross-spawn@^7.0.0:
356 | version "7.0.6"
357 | resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f"
358 | integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==
359 | dependencies:
360 | path-key "^3.1.0"
361 | shebang-command "^2.0.0"
362 | which "^2.0.1"
363 |
364 | cssesc@^3.0.0:
365 | version "3.0.0"
366 | resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
367 | integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
368 |
369 | didyoumean@^1.2.2:
370 | version "1.2.2"
371 | resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
372 | integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==
373 |
374 | dlv@^1.1.3:
375 | version "1.1.3"
376 | resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79"
377 | integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==
378 |
379 | dompurify@^3.2.5:
380 | version "3.2.5"
381 | resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.2.5.tgz#11b108656a5fb72b24d916df17a1421663d7129c"
382 | integrity sha512-mLPd29uoRe9HpvwP2TxClGQBzGXeEC/we/q+bFlmPPmj2p2Ugl3r6ATu/UU1v77DXNcehiBg9zsr1dREyA/dJQ==
383 | optionalDependencies:
384 | "@types/trusted-types" "^2.0.7"
385 |
386 | eastasianwidth@^0.2.0:
387 | version "0.2.0"
388 | resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
389 | integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
390 |
391 | emoji-regex@^8.0.0:
392 | version "8.0.0"
393 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
394 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
395 |
396 | emoji-regex@^9.2.2:
397 | version "9.2.2"
398 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
399 | integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
400 |
401 | esbuild@^0.25.0:
402 | version "0.25.0"
403 | resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.25.0.tgz#0de1787a77206c5a79eeb634a623d39b5006ce92"
404 | integrity sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw==
405 | optionalDependencies:
406 | "@esbuild/aix-ppc64" "0.25.0"
407 | "@esbuild/android-arm" "0.25.0"
408 | "@esbuild/android-arm64" "0.25.0"
409 | "@esbuild/android-x64" "0.25.0"
410 | "@esbuild/darwin-arm64" "0.25.0"
411 | "@esbuild/darwin-x64" "0.25.0"
412 | "@esbuild/freebsd-arm64" "0.25.0"
413 | "@esbuild/freebsd-x64" "0.25.0"
414 | "@esbuild/linux-arm" "0.25.0"
415 | "@esbuild/linux-arm64" "0.25.0"
416 | "@esbuild/linux-ia32" "0.25.0"
417 | "@esbuild/linux-loong64" "0.25.0"
418 | "@esbuild/linux-mips64el" "0.25.0"
419 | "@esbuild/linux-ppc64" "0.25.0"
420 | "@esbuild/linux-riscv64" "0.25.0"
421 | "@esbuild/linux-s390x" "0.25.0"
422 | "@esbuild/linux-x64" "0.25.0"
423 | "@esbuild/netbsd-arm64" "0.25.0"
424 | "@esbuild/netbsd-x64" "0.25.0"
425 | "@esbuild/openbsd-arm64" "0.25.0"
426 | "@esbuild/openbsd-x64" "0.25.0"
427 | "@esbuild/sunos-x64" "0.25.0"
428 | "@esbuild/win32-arm64" "0.25.0"
429 | "@esbuild/win32-ia32" "0.25.0"
430 | "@esbuild/win32-x64" "0.25.0"
431 |
432 | fast-glob@^3.3.0:
433 | version "3.3.2"
434 | resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129"
435 | integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==
436 | dependencies:
437 | "@nodelib/fs.stat" "^2.0.2"
438 | "@nodelib/fs.walk" "^1.2.3"
439 | glob-parent "^5.1.2"
440 | merge2 "^1.3.0"
441 | micromatch "^4.0.4"
442 |
443 | fastq@^1.6.0:
444 | version "1.17.1"
445 | resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.17.1.tgz#2a523f07a4e7b1e81a42b91b8bf2254107753b47"
446 | integrity sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==
447 | dependencies:
448 | reusify "^1.0.4"
449 |
450 | fill-range@^7.1.1:
451 | version "7.1.1"
452 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292"
453 | integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==
454 | dependencies:
455 | to-regex-range "^5.0.1"
456 |
457 | foreground-child@^3.1.0:
458 | version "3.3.0"
459 | resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.0.tgz#0ac8644c06e431439f8561db8ecf29a7b5519c77"
460 | integrity sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==
461 | dependencies:
462 | cross-spawn "^7.0.0"
463 | signal-exit "^4.0.1"
464 |
465 | fsevents@~2.3.2:
466 | version "2.3.3"
467 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6"
468 | integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
469 |
470 | function-bind@^1.1.2:
471 | version "1.1.2"
472 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
473 | integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
474 |
475 | glob-parent@^5.1.2, glob-parent@~5.1.2:
476 | version "5.1.2"
477 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
478 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
479 | dependencies:
480 | is-glob "^4.0.1"
481 |
482 | glob-parent@^6.0.2:
483 | version "6.0.2"
484 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3"
485 | integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==
486 | dependencies:
487 | is-glob "^4.0.3"
488 |
489 | glob@^10.3.10:
490 | version "10.4.5"
491 | resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956"
492 | integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==
493 | dependencies:
494 | foreground-child "^3.1.0"
495 | jackspeak "^3.1.2"
496 | minimatch "^9.0.4"
497 | minipass "^7.1.2"
498 | package-json-from-dist "^1.0.0"
499 | path-scurry "^1.11.1"
500 |
501 | hasown@^2.0.2:
502 | version "2.0.2"
503 | resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
504 | integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
505 | dependencies:
506 | function-bind "^1.1.2"
507 |
508 | is-binary-path@~2.1.0:
509 | version "2.1.0"
510 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09"
511 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==
512 | dependencies:
513 | binary-extensions "^2.0.0"
514 |
515 | is-core-module@^2.13.0:
516 | version "2.15.1"
517 | resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.1.tgz#a7363a25bee942fefab0de13bf6aa372c82dcc37"
518 | integrity sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==
519 | dependencies:
520 | hasown "^2.0.2"
521 |
522 | is-extglob@^2.1.1:
523 | version "2.1.1"
524 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
525 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==
526 |
527 | is-fullwidth-code-point@^3.0.0:
528 | version "3.0.0"
529 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
530 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
531 |
532 | is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1:
533 | version "4.0.3"
534 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
535 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
536 | dependencies:
537 | is-extglob "^2.1.1"
538 |
539 | is-number@^7.0.0:
540 | version "7.0.0"
541 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b"
542 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==
543 |
544 | isexe@^2.0.0:
545 | version "2.0.0"
546 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
547 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
548 |
549 | jackspeak@^3.1.2:
550 | version "3.4.3"
551 | resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a"
552 | integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==
553 | dependencies:
554 | "@isaacs/cliui" "^8.0.2"
555 | optionalDependencies:
556 | "@pkgjs/parseargs" "^0.11.0"
557 |
558 | jiti@^1.21.0:
559 | version "1.21.6"
560 | resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268"
561 | integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==
562 |
563 | lilconfig@^2.1.0:
564 | version "2.1.0"
565 | resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52"
566 | integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==
567 |
568 | lilconfig@^3.0.0:
569 | version "3.1.2"
570 | resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.2.tgz#e4a7c3cb549e3a606c8dcc32e5ae1005e62c05cb"
571 | integrity sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==
572 |
573 | lines-and-columns@^1.1.6:
574 | version "1.2.4"
575 | resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
576 | integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
577 |
578 | lru-cache@^10.2.0:
579 | version "10.4.3"
580 | resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119"
581 | integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==
582 |
583 | merge2@^1.3.0:
584 | version "1.4.1"
585 | resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
586 | integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
587 |
588 | micromatch@^4.0.4, micromatch@^4.0.5:
589 | version "4.0.8"
590 | resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
591 | integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
592 | dependencies:
593 | braces "^3.0.3"
594 | picomatch "^2.3.1"
595 |
596 | micromodal@^0.4.10:
597 | version "0.4.10"
598 | resolved "https://registry.yarnpkg.com/micromodal/-/micromodal-0.4.10.tgz#d6f59c21d2f4a5af480f65909eb9608a1d558c73"
599 | integrity sha512-BUrEnzMPFBwK8nOE4xUDYHLrlGlLULQVjpja99tpJQPSUEWgw3kTLp1n1qv0HmKU29AiHE7Y7sMLiRziDK4ghQ==
600 |
601 | mini-svg-data-uri@^1.2.3:
602 | version "1.4.4"
603 | resolved "https://registry.yarnpkg.com/mini-svg-data-uri/-/mini-svg-data-uri-1.4.4.tgz#8ab0aabcdf8c29ad5693ca595af19dd2ead09939"
604 | integrity sha512-r9deDe9p5FJUPZAk3A59wGH7Ii9YrjjWw0jmw/liSbHl2CHiyXj6FcDXDu2K3TjVAXqiJdaw3xxwlZZr9E6nHg==
605 |
606 | minimatch@^9.0.4:
607 | version "9.0.5"
608 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5"
609 | integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==
610 | dependencies:
611 | brace-expansion "^2.0.1"
612 |
613 | "minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.1.2:
614 | version "7.1.2"
615 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707"
616 | integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==
617 |
618 | mz@^2.7.0:
619 | version "2.7.0"
620 | resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32"
621 | integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==
622 | dependencies:
623 | any-promise "^1.0.0"
624 | object-assign "^4.0.1"
625 | thenify-all "^1.0.0"
626 |
627 | nanoid@^3.3.7:
628 | version "3.3.8"
629 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf"
630 | integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==
631 |
632 | normalize-path@^3.0.0, normalize-path@~3.0.0:
633 | version "3.0.0"
634 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65"
635 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==
636 |
637 | object-assign@^4.0.1:
638 | version "4.1.1"
639 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
640 | integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==
641 |
642 | object-hash@^3.0.0:
643 | version "3.0.0"
644 | resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9"
645 | integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==
646 |
647 | package-json-from-dist@^1.0.0:
648 | version "1.0.1"
649 | resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505"
650 | integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==
651 |
652 | path-key@^3.1.0:
653 | version "3.1.1"
654 | resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
655 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
656 |
657 | path-parse@^1.0.7:
658 | version "1.0.7"
659 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
660 | integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
661 |
662 | path-scurry@^1.11.1:
663 | version "1.11.1"
664 | resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2"
665 | integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==
666 | dependencies:
667 | lru-cache "^10.2.0"
668 | minipass "^5.0.0 || ^6.0.2 || ^7.0.0"
669 |
670 | picocolors@^1.0.0, picocolors@^1.1.0:
671 | version "1.1.0"
672 | resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.0.tgz#5358b76a78cde483ba5cef6a9dc9671440b27d59"
673 | integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==
674 |
675 | picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1:
676 | version "2.3.1"
677 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42"
678 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==
679 |
680 | pify@^2.3.0:
681 | version "2.3.0"
682 | resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c"
683 | integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==
684 |
685 | pirates@^4.0.1:
686 | version "4.0.6"
687 | resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9"
688 | integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==
689 |
690 | postcss-import@^15.1.0:
691 | version "15.1.0"
692 | resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-15.1.0.tgz#41c64ed8cc0e23735a9698b3249ffdbf704adc70"
693 | integrity sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==
694 | dependencies:
695 | postcss-value-parser "^4.0.0"
696 | read-cache "^1.0.0"
697 | resolve "^1.1.7"
698 |
699 | postcss-js@^4.0.1:
700 | version "4.0.1"
701 | resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2"
702 | integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==
703 | dependencies:
704 | camelcase-css "^2.0.1"
705 |
706 | postcss-load-config@^4.0.1:
707 | version "4.0.2"
708 | resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.2.tgz#7159dcf626118d33e299f485d6afe4aff7c4a3e3"
709 | integrity sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==
710 | dependencies:
711 | lilconfig "^3.0.0"
712 | yaml "^2.3.4"
713 |
714 | postcss-nested@^6.0.1:
715 | version "6.2.0"
716 | resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.2.0.tgz#4c2d22ab5f20b9cb61e2c5c5915950784d068131"
717 | integrity sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==
718 | dependencies:
719 | postcss-selector-parser "^6.1.1"
720 |
721 | postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.1.1:
722 | version "6.1.2"
723 | resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de"
724 | integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==
725 | dependencies:
726 | cssesc "^3.0.0"
727 | util-deprecate "^1.0.2"
728 |
729 | postcss-value-parser@^4.0.0:
730 | version "4.2.0"
731 | resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
732 | integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
733 |
734 | postcss@^8.4.23:
735 | version "8.4.47"
736 | resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365"
737 | integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==
738 | dependencies:
739 | nanoid "^3.3.7"
740 | picocolors "^1.1.0"
741 | source-map-js "^1.2.1"
742 |
743 | queue-microtask@^1.2.2:
744 | version "1.2.3"
745 | resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
746 | integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
747 |
748 | ralix@^1.4.0:
749 | version "1.4.0"
750 | resolved "https://registry.yarnpkg.com/ralix/-/ralix-1.4.0.tgz#b38c9c23a1fd6d4bcd4d54e1f19d7a09cbb8e426"
751 | integrity sha512-2wCHeDxgvD9S06qRnxJah6b3y4BbHShmzJ0y6/+GhE0kerg54bF/hQglgPxyjpT1o/2slXwBdPeYc4Pjs/SxaA==
752 |
753 | read-cache@^1.0.0:
754 | version "1.0.0"
755 | resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774"
756 | integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==
757 | dependencies:
758 | pify "^2.3.0"
759 |
760 | readdirp@~3.6.0:
761 | version "3.6.0"
762 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
763 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==
764 | dependencies:
765 | picomatch "^2.2.1"
766 |
767 | resolve@^1.1.7, resolve@^1.22.2:
768 | version "1.22.8"
769 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d"
770 | integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==
771 | dependencies:
772 | is-core-module "^2.13.0"
773 | path-parse "^1.0.7"
774 | supports-preserve-symlinks-flag "^1.0.0"
775 |
776 | reusify@^1.0.4:
777 | version "1.0.4"
778 | resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76"
779 | integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==
780 |
781 | run-parallel@^1.1.9:
782 | version "1.2.0"
783 | resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee"
784 | integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==
785 | dependencies:
786 | queue-microtask "^1.2.2"
787 |
788 | shebang-command@^2.0.0:
789 | version "2.0.0"
790 | resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
791 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
792 | dependencies:
793 | shebang-regex "^3.0.0"
794 |
795 | shebang-regex@^3.0.0:
796 | version "3.0.0"
797 | resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
798 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
799 |
800 | signal-exit@^4.0.1:
801 | version "4.1.0"
802 | resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04"
803 | integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==
804 |
805 | source-map-js@^1.2.1:
806 | version "1.2.1"
807 | resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46"
808 | integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==
809 |
810 | spark-md5@^3.0.1:
811 | version "3.0.2"
812 | resolved "https://registry.yarnpkg.com/spark-md5/-/spark-md5-3.0.2.tgz#7952c4a30784347abcee73268e473b9c0167e3fc"
813 | integrity sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw==
814 |
815 | "string-width-cjs@npm:string-width@^4.2.0":
816 | version "4.2.3"
817 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
818 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
819 | dependencies:
820 | emoji-regex "^8.0.0"
821 | is-fullwidth-code-point "^3.0.0"
822 | strip-ansi "^6.0.1"
823 |
824 | string-width@^4.1.0:
825 | version "4.2.3"
826 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
827 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
828 | dependencies:
829 | emoji-regex "^8.0.0"
830 | is-fullwidth-code-point "^3.0.0"
831 | strip-ansi "^6.0.1"
832 |
833 | string-width@^5.0.1, string-width@^5.1.2:
834 | version "5.1.2"
835 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
836 | integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==
837 | dependencies:
838 | eastasianwidth "^0.2.0"
839 | emoji-regex "^9.2.2"
840 | strip-ansi "^7.0.1"
841 |
842 | "strip-ansi-cjs@npm:strip-ansi@^6.0.1":
843 | version "6.0.1"
844 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
845 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
846 | dependencies:
847 | ansi-regex "^5.0.1"
848 |
849 | strip-ansi@^6.0.0, strip-ansi@^6.0.1:
850 | version "6.0.1"
851 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
852 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
853 | dependencies:
854 | ansi-regex "^5.0.1"
855 |
856 | strip-ansi@^7.0.1:
857 | version "7.1.0"
858 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
859 | integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==
860 | dependencies:
861 | ansi-regex "^6.0.1"
862 |
863 | sucrase@^3.32.0:
864 | version "3.35.0"
865 | resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.35.0.tgz#57f17a3d7e19b36d8995f06679d121be914ae263"
866 | integrity sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==
867 | dependencies:
868 | "@jridgewell/gen-mapping" "^0.3.2"
869 | commander "^4.0.0"
870 | glob "^10.3.10"
871 | lines-and-columns "^1.1.6"
872 | mz "^2.7.0"
873 | pirates "^4.0.1"
874 | ts-interface-checker "^0.1.9"
875 |
876 | supports-preserve-symlinks-flag@^1.0.0:
877 | version "1.0.0"
878 | resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
879 | integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
880 |
881 | tailwindcss@^3.4.13:
882 | version "3.4.13"
883 | resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.13.tgz#3d11e5510660f99df4f1bfb2d78434666cb8f831"
884 | integrity sha512-KqjHOJKogOUt5Bs752ykCeiwvi0fKVkr5oqsFNt/8px/tA8scFPIlkygsf6jXrfCqGHz7VflA6+yytWuM+XhFw==
885 | dependencies:
886 | "@alloc/quick-lru" "^5.2.0"
887 | arg "^5.0.2"
888 | chokidar "^3.5.3"
889 | didyoumean "^1.2.2"
890 | dlv "^1.1.3"
891 | fast-glob "^3.3.0"
892 | glob-parent "^6.0.2"
893 | is-glob "^4.0.3"
894 | jiti "^1.21.0"
895 | lilconfig "^2.1.0"
896 | micromatch "^4.0.5"
897 | normalize-path "^3.0.0"
898 | object-hash "^3.0.0"
899 | picocolors "^1.0.0"
900 | postcss "^8.4.23"
901 | postcss-import "^15.1.0"
902 | postcss-js "^4.0.1"
903 | postcss-load-config "^4.0.1"
904 | postcss-nested "^6.0.1"
905 | postcss-selector-parser "^6.0.11"
906 | resolve "^1.22.2"
907 | sucrase "^3.32.0"
908 |
909 | thenify-all@^1.0.0:
910 | version "1.6.0"
911 | resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726"
912 | integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==
913 | dependencies:
914 | thenify ">= 3.1.0 < 4"
915 |
916 | "thenify@>= 3.1.0 < 4":
917 | version "3.3.1"
918 | resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f"
919 | integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==
920 | dependencies:
921 | any-promise "^1.0.0"
922 |
923 | tippy.js@^6.3.7:
924 | version "6.3.7"
925 | resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.3.7.tgz#8ccfb651d642010ed9a32ff29b0e9e19c5b8c61c"
926 | integrity sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==
927 | dependencies:
928 | "@popperjs/core" "^2.9.0"
929 |
930 | to-regex-range@^5.0.1:
931 | version "5.0.1"
932 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4"
933 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==
934 | dependencies:
935 | is-number "^7.0.0"
936 |
937 | trix@^2.1.15:
938 | version "2.1.15"
939 | resolved "https://registry.yarnpkg.com/trix/-/trix-2.1.15.tgz#fabad796ea779a8ae96522402fbc214cbfc4015f"
940 | integrity sha512-LoaXWczdTUV8+3Box92B9b1iaDVbxD14dYemZRxi3PwY+AuDm97BUJV2aHLBUFPuDABhxp0wzcbf0CxHCVmXiw==
941 | dependencies:
942 | dompurify "^3.2.5"
943 |
944 | ts-interface-checker@^0.1.9:
945 | version "0.1.13"
946 | resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699"
947 | integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==
948 |
949 | util-deprecate@^1.0.2:
950 | version "1.0.2"
951 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
952 | integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==
953 |
954 | which@^2.0.1:
955 | version "2.0.2"
956 | resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
957 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
958 | dependencies:
959 | isexe "^2.0.0"
960 |
961 | "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
962 | version "7.0.0"
963 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
964 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
965 | dependencies:
966 | ansi-styles "^4.0.0"
967 | string-width "^4.1.0"
968 | strip-ansi "^6.0.0"
969 |
970 | wrap-ansi@^8.1.0:
971 | version "8.1.0"
972 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"
973 | integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==
974 | dependencies:
975 | ansi-styles "^6.1.0"
976 | string-width "^5.0.1"
977 | strip-ansi "^7.0.1"
978 |
979 | yaml@^2.3.4:
980 | version "2.5.1"
981 | resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.5.1.tgz#c9772aacf62cb7494a95b0c4f1fb065b563db130"
982 | integrity sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==
983 |
--------------------------------------------------------------------------------