museria 0.2.49 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc +10 -2
- package/.github/workflows/build.yml +3 -3
- package/.github/workflows/publish.yml +3 -3
- package/README.md +55 -59
- package/bin/actions.js +28 -28
- package/bin/index.js +4 -4
- package/bin/runner.js +1 -1
- package/bin/utils.js +6 -2
- package/dist/client/museria.client.js +7 -7
- package/dist/face/45a265d0f07b31cde85f.ttf +0 -0
- package/dist/face/6205fd00fb1b573e9f0f.ttf +0 -0
- package/dist/face/8d3cabfc66809162fb4d.woff2 +0 -0
- package/dist/face/fb8184add5a3101ad0a3.woff2 +0 -0
- package/dist/face/museria.face.js +33 -13
- package/dist/face/style.css +13 -11
- package/package.json +41 -40
- package/src/browser/client/index.js +2 -1
- package/src/browser/face/client.js +2 -1
- package/src/browser/face/controllers/app/app.html +77 -69
- package/src/browser/face/controllers/app/app.js +14 -7
- package/src/browser/face/controllers/app/app.scss +2 -22
- package/src/browser/face/index.js +3 -3
- package/src/browser/face/styles/main.scss +91 -11
- package/src/browser/face/styles/vars.scss +0 -1
- package/src/client.js +73 -74
- package/src/collection/transports/music/index.js +20 -18
- package/src/db/transports/database/index.js +7 -5
- package/src/db/transports/loki/index.js +30 -25
- package/src/errors.js +2 -1
- package/src/index.js +8 -6
- package/src/node.js +312 -323
- package/src/schema.js +27 -29
- package/src/server/transports/express/api/butler/controllers.js +7 -10
- package/src/server/transports/express/api/butler/routes.js +5 -5
- package/src/server/transports/express/api/master/controllers.js +7 -10
- package/src/server/transports/express/api/master/routes.js +5 -5
- package/src/server/transports/express/api/node/controllers.js +52 -61
- package/src/server/transports/express/api/node/routes.js +10 -10
- package/src/server/transports/express/api/routes.js +1 -1
- package/src/server/transports/express/api/slave/controllers.js +7 -10
- package/src/server/transports/express/api/slave/routes.js +6 -6
- package/src/server/transports/express/client/controllers.js +40 -61
- package/src/server/transports/express/client/routes.js +33 -39
- package/src/server/transports/express/controllers.js +10 -21
- package/src/server/transports/express/index.js +23 -20
- package/src/server/transports/express/midds.js +67 -67
- package/src/server/transports/express/routes.js +12 -12
- package/src/utils.js +175 -184
- package/test/client.js +311 -305
- package/test/db/database.js +32 -28
- package/test/db/loki.js +78 -74
- package/test/group.js +161 -156
- package/test/index.js +20 -10
- package/test/node.js +461 -460
- package/test/routes.js +404 -399
- package/test/server/express.js +35 -31
- package/test/services.js +25 -18
- package/test/tools.js +8 -6
- package/test/utils.js +236 -234
- package/webpack.client.js +9 -7
- package/webpack.face.js +8 -6
- package/dist/face/fa-brands-400.eot +0 -0
- package/dist/face/fa-brands-400.svg +0 -3717
- package/dist/face/fa-brands-400.ttf +0 -0
- package/dist/face/fa-brands-400.woff +0 -0
- package/dist/face/fa-brands-400.woff2 +0 -0
- package/dist/face/fa-solid-900.eot +0 -0
- package/dist/face/fa-solid-900.svg +0 -5034
- package/dist/face/fa-solid-900.ttf +0 -0
- package/dist/face/fa-solid-900.woff +0 -0
- package/dist/face/fa-solid-900.woff2 +0 -0
- /package/dist/face/{open-sans.ttf → 17e98b9e5586529b13cc.ttf} +0 -0
- /package/dist/face/{proxima-nova.ttf → 326601dfabd91e3f016c.ttf} +0 -0
- /package/dist/face/{logo.svg → ee9c6af64aa224827cec.svg} +0 -0
package/package.json
CHANGED
@@ -1,8 +1,9 @@
|
|
1
1
|
{
|
2
2
|
"name": "museria",
|
3
|
-
"version": "0.2
|
3
|
+
"version": "0.3.2",
|
4
4
|
"description": "Decentralized music storage",
|
5
5
|
"main": "./src/index.js",
|
6
|
+
"type": "module",
|
6
7
|
"bin": {
|
7
8
|
"museria": "./bin/index.js"
|
8
9
|
},
|
@@ -41,59 +42,59 @@
|
|
41
42
|
],
|
42
43
|
"license": "MIT",
|
43
44
|
"devDependencies": {
|
44
|
-
"@babel/core": "^7.
|
45
|
-
"@babel/eslint-parser": "^7.
|
46
|
-
"@babel/plugin-transform-runtime": "^7.
|
47
|
-
"@babel/preset-env": "^7.
|
48
|
-
"babel-loader": "^
|
49
|
-
"babel-preset-akili": "^2.0.
|
50
|
-
"chai": "^
|
45
|
+
"@babel/core": "^7.23.7",
|
46
|
+
"@babel/eslint-parser": "^7.23.3",
|
47
|
+
"@babel/plugin-transform-runtime": "^7.23.7",
|
48
|
+
"@babel/preset-env": "^7.23.8",
|
49
|
+
"babel-loader": "^9.1.3",
|
50
|
+
"babel-preset-akili": "^2.0.8",
|
51
|
+
"chai": "^5.0.0",
|
51
52
|
"cross-env": "^7.0.3",
|
52
|
-
"css-loader": "^
|
53
|
-
"css-minimizer-webpack-plugin": "^
|
54
|
-
"eslint": "^
|
55
|
-
"eslint-webpack-plugin": "^
|
56
|
-
"
|
57
|
-
"
|
58
|
-
"
|
59
|
-
"mini-css-extract-plugin": "^1.3.9",
|
53
|
+
"css-loader": "^6.9.0",
|
54
|
+
"css-minimizer-webpack-plugin": "^5.0.1",
|
55
|
+
"eslint": "^8.56.0",
|
56
|
+
"eslint-webpack-plugin": "^4.0.1",
|
57
|
+
"html-loader": "^5.0.0",
|
58
|
+
"husky": "^4.0.3",
|
59
|
+
"mini-css-extract-plugin": "^2.7.7",
|
60
60
|
"mocha": "^10.2.0",
|
61
|
-
"node-polyfill-webpack-plugin": "^
|
61
|
+
"node-polyfill-webpack-plugin": "^3.0.0",
|
62
62
|
"resolve-url-loader": "^5.0.0",
|
63
|
-
"sass": "^1.
|
64
|
-
"sass-loader": "^
|
65
|
-
"terser-webpack-plugin": "^5.
|
66
|
-
"webpack": "^5.
|
67
|
-
"webpack-cli": "^
|
68
|
-
"yargs": "^17.0.0"
|
63
|
+
"sass": "^1.69.7",
|
64
|
+
"sass-loader": "^14.0.0",
|
65
|
+
"terser-webpack-plugin": "^5.3.10",
|
66
|
+
"webpack": "^5.89.0",
|
67
|
+
"webpack-cli": "^5.1.4"
|
69
68
|
},
|
70
69
|
"dependencies": {
|
71
|
-
"@fortawesome/fontawesome-free": "^5.
|
72
|
-
"akili": "
|
70
|
+
"@fortawesome/fontawesome-free": "^6.5.1",
|
71
|
+
"akili": "1.2.37",
|
73
72
|
"base64url": "^3.0.1",
|
74
|
-
"bootstrap": "^
|
75
|
-
"chalk": "^
|
73
|
+
"bootstrap": "^5.0.0",
|
74
|
+
"chalk": "^5.3.0",
|
76
75
|
"emoji-strip": "^1.0.1",
|
77
|
-
"express": "^4.
|
78
|
-
"fs-extra": "^
|
79
|
-
"
|
80
|
-
"
|
81
|
-
"
|
82
|
-
"
|
83
|
-
"node-
|
76
|
+
"express": "^4.18.2",
|
77
|
+
"fs-extra": "^11.2.0",
|
78
|
+
"hasha": "^5.0.0",
|
79
|
+
"lodash-es": "^4.17.21",
|
80
|
+
"metastocle": "~0.3.10",
|
81
|
+
"music-metadata": "^7.14.0",
|
82
|
+
"node-fetch": "^3.3.2",
|
83
|
+
"node-id3": "^0.2.6",
|
84
84
|
"sanitize-filename": "^1.6.3",
|
85
85
|
"serve-favicon": "^2.5.0",
|
86
|
-
"sharp": "^0.
|
87
|
-
"splaytree": "^3.1.
|
88
|
-
"spreadable": "
|
89
|
-
"storacle": "
|
90
|
-
"transliteration": "^2.
|
86
|
+
"sharp": "^0.33.2",
|
87
|
+
"splaytree": "^3.1.2",
|
88
|
+
"spreadable": "~0.3.10",
|
89
|
+
"storacle": "~0.3.6",
|
90
|
+
"transliteration": "^2.3.5",
|
91
|
+
"yargs": "^17.7.2"
|
91
92
|
},
|
92
93
|
"repository": {
|
93
94
|
"type": "git",
|
94
95
|
"url": "https://github.com/ortexx/museria"
|
95
96
|
},
|
96
97
|
"engines": {
|
97
|
-
"node": ">=
|
98
|
+
"node": ">=20.0.0"
|
98
99
|
}
|
99
100
|
}
|
@@ -1 +1,2 @@
|
|
1
|
-
|
1
|
+
import client from "../../client.js";
|
2
|
+
export default client();
|
@@ -62,7 +62,7 @@
|
|
62
62
|
</a>
|
63
63
|
</header>
|
64
64
|
<div class="content">
|
65
|
-
<div class="row pt-5 pb-3">
|
65
|
+
<div class="row px-4 px-sm-5 pt-5 pb-3">
|
66
66
|
<div class="song-search col-lg-6 col-12 pl-5 pr-5 pr-lg-4 pt-4">
|
67
67
|
<div class="song-search-input input-group input-group-lg">
|
68
68
|
<i hidden="${ this.isFinding }" class="fas fa-search fa-lg"></i>
|
@@ -135,42 +135,48 @@
|
|
135
135
|
<div class="invalid-feedback">Title must be like "Artist - Title"</div>
|
136
136
|
</div>
|
137
137
|
<div class="form-group mt-3 w-100">
|
138
|
-
<div class="custom-file position-relative">
|
138
|
+
<div class="custom-file input-group position-relative">
|
139
139
|
<input
|
140
140
|
type="file"
|
141
|
-
class="${ utils.class({ '
|
141
|
+
class="form-control ${ utils.class({ 'is-invalid': this.uploadFormFails.cover }) }"
|
142
142
|
id="cover-file"
|
143
143
|
on-change="${ this.prepareCover(event.target.files[0]) }"
|
144
144
|
accept="image/jpeg,image/png"
|
145
145
|
>
|
146
|
-
<
|
146
|
+
<button class="btn btn-outline-secondary px-3" type="button" id="cover-file-button">Browse</button>
|
147
147
|
<img
|
148
148
|
hidden="${ !this.songUploadInfo.cover }"
|
149
149
|
url="${ this.songUploadInfo.cover }"
|
150
150
|
class="cover-img"
|
151
151
|
>
|
152
152
|
<label
|
153
|
-
class="custom-file-label ${ utils.class({'cover-label': true, 'with-img': !!this.songUploadInfo.cover}) }"
|
153
|
+
class="custom-file-label input-group-text ${ utils.class({'cover-label': true, 'with-img': !!this.songUploadInfo.cover}) }"
|
154
154
|
for="cover-file">
|
155
155
|
${ this.songUploadInfo.cover? 'Cover is chosen': 'Choose a cover file' }
|
156
|
-
</label>
|
156
|
+
</label>
|
157
157
|
<i
|
158
158
|
hidden="${ !this.songUploadInfo.cover }"
|
159
159
|
on-click="${ this.removeCover() }"
|
160
160
|
class="close-fa cover-remove fas fa-times fa-lg"
|
161
161
|
title="remove the cover"></i>
|
162
162
|
</div>
|
163
|
+
<div
|
164
|
+
class="invalid-feedback"
|
165
|
+
style="display: ${ this.uploadFormFails.cover? 'block': 'none' };"
|
166
|
+
>
|
167
|
+
Cover must be "jpeg" or "png"
|
168
|
+
</div>
|
163
169
|
</div>
|
164
170
|
<div class="form-group mt-3 w-100">
|
165
|
-
<div class="
|
171
|
+
<div class="form-check my-1 mr-sm-2">
|
166
172
|
<input
|
167
173
|
type="checkbox"
|
168
|
-
class="
|
174
|
+
class="form-check-input"
|
169
175
|
id="songHighPriorityCheckbox"
|
170
176
|
checked="${ this.songUploadInfo.controlled }"
|
171
177
|
on-change="${ this.songUploadInfo.controlled = event.target.checked }"
|
172
178
|
>
|
173
|
-
<label class="
|
179
|
+
<label class="form-check-label" for="songHighPriorityCheckbox">
|
174
180
|
Moderation mode (optional)
|
175
181
|
</label>
|
176
182
|
</div>
|
@@ -183,17 +189,17 @@
|
|
183
189
|
on-radio="${ this.songUploadInfo.priority = event.detail }"
|
184
190
|
class="d-flex song-priority"
|
185
191
|
>
|
186
|
-
<div class="
|
187
|
-
<input type="radio" class="
|
188
|
-
<label class="
|
192
|
+
<div class="form-check form-check-inline pr-4">
|
193
|
+
<input type="radio" class="form-check-input" id="songLowPriority" value="-1">
|
194
|
+
<label class="form-check-label" for="songLowPriority">Low priority</label>
|
189
195
|
</div>
|
190
|
-
<div class="
|
191
|
-
<input type="radio" class="
|
192
|
-
<label class="
|
196
|
+
<div class="form-check form-check-inline pr-4">
|
197
|
+
<input type="radio" class="form-check-input" id="songNormalPriority" value="0">
|
198
|
+
<label class="form-check-label" for="songNormalPriority">Normal priority</label>
|
193
199
|
</div>
|
194
|
-
<div class="
|
195
|
-
<input type="radio" class="
|
196
|
-
<label class="
|
200
|
+
<div class="form-check form-check-inline">
|
201
|
+
<input type="radio" class="form-check-input" id="songHighPriority" value="1">
|
202
|
+
<label class="form-check-label" for="songHighPriority">High priority</label>
|
197
203
|
</div>
|
198
204
|
</radio>
|
199
205
|
</div>
|
@@ -209,10 +215,10 @@
|
|
209
215
|
</div>
|
210
216
|
</div>
|
211
217
|
</div>
|
212
|
-
<div class="container py-
|
218
|
+
<div class="container py-4">
|
213
219
|
<div class="row px-2 pb-5">
|
214
220
|
<div class="col-12 text-center">
|
215
|
-
<ul class="questions">
|
221
|
+
<ul class="questions px-0">
|
216
222
|
<li>
|
217
223
|
<div>What is this?</div>
|
218
224
|
<div>It is a decentralized music storage node.</div>
|
@@ -261,56 +267,58 @@
|
|
261
267
|
</div>
|
262
268
|
</div>
|
263
269
|
<footer class="footer row">
|
264
|
-
<div
|
265
|
-
<div class="
|
266
|
-
<div class="
|
267
|
-
<
|
268
|
-
|
269
|
-
<
|
270
|
-
<
|
271
|
-
|
272
|
-
<
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
<
|
277
|
-
|
278
|
-
<
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
<
|
285
|
-
|
286
|
-
<
|
287
|
-
<
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
<
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
<
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
<
|
302
|
-
|
303
|
-
<
|
304
|
-
<
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
<
|
309
|
-
|
310
|
-
|
311
|
-
|
270
|
+
<div>
|
271
|
+
<div class="container">
|
272
|
+
<div class="row px-4">
|
273
|
+
<div class="col-xl-4 col-lg-6 mt-4 px-0 footer-contacts">
|
274
|
+
<h5>Contacts</h5>
|
275
|
+
<ul class="flex-column nav">
|
276
|
+
<li>
|
277
|
+
<i class="fas fa-envelope" aria-hidden="true"></i>
|
278
|
+
<a href="mailto:storage@museria.com" target="_blank">
|
279
|
+
<span class="pl-1">storage@museria.com</span>
|
280
|
+
</a>
|
281
|
+
</li>
|
282
|
+
<li>
|
283
|
+
<i class="fab fa-github" aria-hidden="true"></i>
|
284
|
+
<a href="https://github.com/ortexx/" target="_blank">
|
285
|
+
<span class="pl-1">ortexx</span>
|
286
|
+
</a>
|
287
|
+
</li>
|
288
|
+
</ul>
|
289
|
+
</div>
|
290
|
+
<div class="col-xl-4 col-lg-6 mt-4 px-0">
|
291
|
+
<h5>Information</h5>
|
292
|
+
<ul class="flex-column nav">
|
293
|
+
<li>
|
294
|
+
<i class="fas fa-book-open" aria-hidden="true"></i>
|
295
|
+
<a href="https://github.com/ortexx/museria/" target="_blank">Documentation</a>
|
296
|
+
</li>
|
297
|
+
<li>
|
298
|
+
<i class="fas fa-globe" aria-hidden="true"></i>
|
299
|
+
<a href="https://github.com/ortexx/museria-global/" target="_blank">Global network</a>
|
300
|
+
</li>
|
301
|
+
<li>
|
302
|
+
<i class="fas fa-play-circle" aria-hidden="true"></i>
|
303
|
+
<a href="https://github.com/ortexx/musiphone/" target="_blank">Decentralized player</a>
|
304
|
+
</li>
|
305
|
+
</ul>
|
306
|
+
</div>
|
307
|
+
<div class="col-xl-4 col-lg-6 mt-4 px-0">
|
308
|
+
<h5>Donate</h5>
|
309
|
+
<ul class="flex-column nav">
|
310
|
+
<li>
|
311
|
+
<i class="fab fa-btc" aria-hidden="true"></i>
|
312
|
+
<span>38dyvCmUadqS2HVFEuDBVC3k1a7h6J5gqU</span>
|
313
|
+
</li>
|
314
|
+
<li>
|
315
|
+
<i class="fab fa-ethereum" aria-hidden="true"></i>
|
316
|
+
<span>0x4e5Ef1b362271523f5c6eDe7a54BDcA9750D81E8</span>
|
317
|
+
</li>
|
318
|
+
</ul>
|
319
|
+
</div>
|
312
320
|
</div>
|
313
321
|
</div>
|
314
|
-
</div>
|
322
|
+
</div>
|
315
323
|
</footer>
|
316
324
|
</div>
|
@@ -1,10 +1,11 @@
|
|
1
1
|
import './app.scss';
|
2
2
|
import Akili from 'akili';
|
3
|
-
import router from 'akili/src/services/router';
|
4
|
-
import client from '../../client';
|
3
|
+
import router from 'akili/src/services/router.js';
|
4
|
+
import client from '../../client.js';
|
5
|
+
import template from './app.html';
|
5
6
|
|
6
7
|
export default class App extends Akili.Component {
|
7
|
-
static template =
|
8
|
+
static template = template;
|
8
9
|
|
9
10
|
static define() {
|
10
11
|
Akili.component('app', this);
|
@@ -171,22 +172,28 @@ export default class App extends Akili.Component {
|
|
171
172
|
if(!file) {
|
172
173
|
return;
|
173
174
|
}
|
174
|
-
|
175
|
+
|
176
|
+
if(!file.type.match('image')) {
|
177
|
+
this.scope.uploadFormFails.cover = true;
|
178
|
+
return;
|
179
|
+
}
|
180
|
+
|
175
181
|
this.scope.songUploadInfo.coverFile = file;
|
176
182
|
this.scope.songUploadInfo.cover = URL.createObjectURL(file)
|
177
183
|
this.scope.songUploadInfo.fileChanged = true;
|
184
|
+
this.scope.uploadFormFails.cover = '';
|
178
185
|
}
|
179
186
|
|
180
187
|
async removeCover() {
|
181
188
|
this.resetCover();
|
182
|
-
this.scope.songUploadInfo.fileChanged = true;
|
189
|
+
this.scope.songUploadInfo.fileChanged = true;
|
183
190
|
}
|
184
191
|
|
185
192
|
async resetCover() {
|
186
|
-
this.scope.uploadFormFails.cover = '';
|
187
193
|
this.scope.songUploadInfo.cover = '';
|
188
194
|
this.scope.songUploadInfo.coverFile = null;
|
189
|
-
this.scope.uploadFormFails.cover && URL.revokeObjectURL(this.scope.uploadFormFails.cover);
|
195
|
+
this.scope.uploadFormFails.cover && URL.revokeObjectURL(this.scope.uploadFormFails.cover);
|
196
|
+
this.scope.uploadFormFails.cover = '';
|
190
197
|
}
|
191
198
|
|
192
199
|
async uploadSong(failed = false) {
|
@@ -111,6 +111,7 @@
|
|
111
111
|
text-transform: uppercase;
|
112
112
|
font-weight: bold;
|
113
113
|
text-align: center;
|
114
|
+
max-width: 50%;
|
114
115
|
|
115
116
|
& b {
|
116
117
|
color: $light;
|
@@ -123,7 +124,7 @@
|
|
123
124
|
text-transform: uppercase;
|
124
125
|
font-weight: bold;
|
125
126
|
text-decoration: none;
|
126
|
-
|
127
|
+
width: unset;
|
127
128
|
|
128
129
|
&-img {
|
129
130
|
display: inline-block;
|
@@ -250,27 +251,6 @@
|
|
250
251
|
}
|
251
252
|
}
|
252
253
|
|
253
|
-
.cover-img {
|
254
|
-
object-fit: cover;
|
255
|
-
height: 2.22em;
|
256
|
-
width: 2.22em;
|
257
|
-
position: absolute;
|
258
|
-
left: 2px;
|
259
|
-
top: 1px;
|
260
|
-
z-index: 2;
|
261
|
-
pointer-events: none;
|
262
|
-
}
|
263
|
-
|
264
|
-
.cover-remove {
|
265
|
-
right: 4.5em;
|
266
|
-
}
|
267
|
-
|
268
|
-
.cover-label {
|
269
|
-
&.with-img {
|
270
|
-
padding-left: 3em;
|
271
|
-
}
|
272
|
-
}
|
273
|
-
|
274
254
|
.upload-preloader-btn {
|
275
255
|
& i {
|
276
256
|
margin-left: 0.3em;
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import './styles/main.scss';
|
2
2
|
import Akili from 'akili';
|
3
|
-
import router from 'akili/src/services/router';
|
4
|
-
import App from './controllers/app/app';
|
5
|
-
import client from './client';
|
3
|
+
import router from 'akili/src/services/router.js';
|
4
|
+
import App from './controllers/app/app.js';
|
5
|
+
import client from './client.js';
|
6
6
|
|
7
7
|
App.define();
|
8
8
|
|
@@ -27,35 +27,109 @@ body {
|
|
27
27
|
color: $pale;
|
28
28
|
}
|
29
29
|
|
30
|
-
.custom-file
|
31
|
-
|
32
|
-
|
33
|
-
|
30
|
+
.custom-file {
|
31
|
+
.cover-img {
|
32
|
+
object-fit: cover;
|
33
|
+
height: 2.22em;
|
34
|
+
width: 2.22em;
|
35
|
+
position: absolute;
|
36
|
+
left: 2px;
|
37
|
+
top: 1px;
|
38
|
+
z-index: 2;
|
39
|
+
pointer-events: none;
|
40
|
+
}
|
34
41
|
|
35
|
-
.
|
36
|
-
|
37
|
-
|
42
|
+
.cover-remove {
|
43
|
+
right: 5em;
|
44
|
+
margin-top: 1px;
|
45
|
+
}
|
38
46
|
|
39
|
-
|
40
|
-
|
47
|
+
.cover-label {
|
48
|
+
position: absolute;
|
49
|
+
background: none;
|
50
|
+
border: none;
|
51
|
+
|
52
|
+
&.with-img {
|
53
|
+
padding-left: 3em;
|
54
|
+
}
|
41
55
|
}
|
56
|
+
|
57
|
+
& input {
|
58
|
+
cursor: pointer;
|
59
|
+
text-indent: -1000px;
|
60
|
+
z-index: 0 !important;
|
61
|
+
|
62
|
+
&:focus + .btn {
|
63
|
+
border-color: $green;
|
64
|
+
}
|
65
|
+
|
66
|
+
&.is-invalid {
|
67
|
+
background-image: unset !important;
|
68
|
+
|
69
|
+
&+ .btn {
|
70
|
+
border-color: $red !important;
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
& .btn {
|
76
|
+
position: absolute;
|
77
|
+
right: 0;
|
78
|
+
height: 100%;
|
79
|
+
pointer-events: none;
|
80
|
+
color: $light;
|
81
|
+
text-transform: none;
|
82
|
+
font-weight: normal;
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
.form-check-input {
|
87
|
+
&[type=checkbox] {
|
88
|
+
border-radius: 2px;
|
89
|
+
}
|
90
|
+
|
91
|
+
&, & + .form-check-label {
|
92
|
+
cursor: pointer;
|
93
|
+
opacity: 0.8;
|
94
|
+
|
95
|
+
&:hover {
|
96
|
+
opacity: 1;
|
97
|
+
}
|
98
|
+
}
|
99
|
+
|
100
|
+
&:focus, &:active {
|
101
|
+
outline: none !important;
|
102
|
+
box-shadow: none !important;
|
103
|
+
}
|
42
104
|
}
|
43
105
|
|
44
106
|
.btn {
|
45
|
-
padding: 0;
|
107
|
+
padding: 0.33em;
|
46
108
|
text-transform: uppercase;
|
47
109
|
font-weight: bold;
|
110
|
+
color: white;
|
48
111
|
|
49
112
|
&:focus, &:active {
|
50
113
|
outline: none !important;
|
51
114
|
box-shadow: none !important;
|
52
|
-
|
115
|
+
color: white;
|
116
|
+
}
|
117
|
+
|
118
|
+
&:hover {
|
119
|
+
color: white;
|
120
|
+
}
|
53
121
|
|
54
122
|
&[disabled] {
|
55
123
|
cursor: not-allowed;
|
56
124
|
}
|
57
125
|
}
|
58
126
|
|
127
|
+
.btn-primary {
|
128
|
+
&:focus, &:active, &:active:focus, &:hover {
|
129
|
+
background: $green !important;
|
130
|
+
}
|
131
|
+
}
|
132
|
+
|
59
133
|
a {
|
60
134
|
color: $pale;
|
61
135
|
text-decoration: underline;
|
@@ -66,6 +140,12 @@ a {
|
|
66
140
|
}
|
67
141
|
}
|
68
142
|
|
143
|
+
input.form-control {
|
144
|
+
&::placeholder {
|
145
|
+
color: $gray;
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
69
149
|
.input-group-lg input[type=text] {
|
70
150
|
padding: 0.42rem 1rem 0.45rem 1rem;
|
71
151
|
height: auto;
|