@massimo-cassandro/minimo 1.11.1 → 1.12.1

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.
Files changed (47) hide show
  1. package/charts/src/node-helpers/create-svg-canvas-node.mjs +37 -0
  2. package/dev-tools/README.md +1 -1
  3. package/dev-tools/create-favicons/src/init-start-text.txt +20 -0
  4. package/dev-tools/update-version/index.mjs +1 -1
  5. package/dev-tools/update-version/src/chooser-inquirer.mjs +1 -1
  6. package/dev-tools/webpack-setup/starter-install.sh +149 -0
  7. package/dev-tools/webpack-setup/templates/__project__.code-workspace +93 -0
  8. package/dev-tools/webpack-setup/templates/_browserslistrc +27 -0
  9. package/dev-tools/webpack-setup/templates/_editorconfig +17 -0
  10. package/dev-tools/webpack-setup/templates/_gitignore +21 -0
  11. package/dev-tools/webpack-setup/templates/_prettierrc +9 -0
  12. package/dev-tools/webpack-setup/templates/eslint.config.mjs +31 -0
  13. package/dev-tools/webpack-setup/templates/jsconfig.json +22 -0
  14. package/dev-tools/webpack-setup/templates/package-tpl.json +37 -0
  15. package/dev-tools/webpack-setup/templates/stylelint.config.mjs +32 -0
  16. package/dev-tools/webpack-setup/webpack-modules/css-rules.mjs +177 -0
  17. package/dev-tools/webpack-setup/webpack-modules/get-jsConfig-aliases.mjs +33 -0
  18. package/dev-tools/webpack-setup/webpack-modules/mini-svg-data-uri-loader.cjs +25 -0
  19. package/dev-tools/webpack-setup/webpack-modules/postcss.config.mjs +77 -0
  20. package/dev-tools/webpack-setup/webpack-modules/svg-rules.mjs +154 -0
  21. package/dev-tools/webpack-setup/webpack-modules/svgo.config.mjs +26 -0
  22. package/dev-tools/webpack-setup/webpack-template.ejs +20 -0
  23. package/dev-tools/webpack-setup/webpack.config.mjs +585 -0
  24. package/package.json +5 -4
  25. package/snippets/ImgViewerController.php +403 -0
  26. package/snippets/UnsplashController.php +74 -0
  27. package/snippets/build-chrome-custom-device-list.mjs +101 -0
  28. package/snippets/config-templates/_env.local +13 -0
  29. package/snippets/config-templates/_github/dependabot.yml +10 -0
  30. package/snippets/config-templates/_hintrc.cjs +35 -0
  31. package/snippets/config-templates/_htaccess +69 -0
  32. package/snippets/config-templates/_npmignore +8 -0
  33. package/snippets/config-templates/_npmrc +1 -0
  34. package/snippets/config-templates/_stylelintignore +5 -0
  35. package/snippets/config-templates/babel.config--react.json +20 -0
  36. package/snippets/config-templates/babel.config--solidJS.json +8 -0
  37. package/snippets/config-templates/react/offcanvas/offcanvas.jsx +89 -0
  38. package/snippets/config-templates/react/offcanvas/offcanvas.module.scss +109 -0
  39. package/snippets/config-templates/robots.txt +5 -0
  40. package/snippets/config-templates/rollup.config.mjs +115 -0
  41. package/snippets/controllo-codice-fiscale-IT.js +48 -0
  42. package/snippets/controllo-partita-iva-IT.js +32 -0
  43. package/snippets/email-antispam.js +108 -0
  44. package/snippets/error-pages/bundles/TwigBundle/Exception/error.html.twig +33 -0
  45. package/snippets/error-pages/error-pages.js +37 -0
  46. package/snippets/festivita.js +101 -0
  47. package/snippets/minimo-form-layout.html.twig +446 -0
@@ -0,0 +1,403 @@
1
+ <?php
2
+
3
+ namespace App\Controller;
4
+
5
+ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
6
+ use Symfony\Component\Routing\Annotation\Route;
7
+ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
8
+ use Symfony\Component\HttpFoundation\Request;
9
+ use Symfony\Component\HttpFoundation\Response;
10
+ use Symfony\Component\HttpFoundation\BinaryFileResponse;
11
+ use Symfony\Component\HttpFoundation\JsonResponse;
12
+
13
+
14
+
15
+ class ImgViewerController extends AbstractController
16
+ {
17
+ /**
18
+ *
19
+ * @param src: (string) path immagine
20
+ * @param raw: (bool) nessuna eleborazione (no image magick)
21
+ * @param crop: ritaglia l'immagine originale (prima dell'eventuale ridimensionamento con bb)
22
+ * secondo i parametri forniti: x,y (origine immagine), w,h (dimensioni ritaglio)
23
+ * es: crop=10,10,100,100 -> ritaglia un quadrato di 100px a partire dal punto 10,10
24
+ * @param bb: bounding box dell'area che deve contenere l'immagine ridimensionata
25
+ * @param fd: (bool) forza dimensioni (utilizzato in coppia con bb)
26
+ * @param q: compression quality
27
+ * @param alpha: mantiene la trasparenza nelle png (default 0)
28
+ * @param bg: in combinazione con alpha=1 definisce il bg color della png
29
+ * @param refresh: (bool) forza la rigenerazione dell'immagine
30
+ * @param f: definisce il formato dell'immagine, secondo le chiavi di ALLOWED_FORMATS
31
+ * il valore 'auto' (default) imposta il formato migliore secondo i valori in PREFERRED_AUTO_FORMATS
32
+ * @param ext: lascia inalterato il formato dell'immagine
33
+ * @param d: (bool) forza il download dell'immagine
34
+ */
35
+
36
+ // parametri get del viewer accettati
37
+ const ALLOWED_PARAMS = array('raw', 'bb', 'fd', 'q', 'alpha', 'bg', 'refresh', 'f', 'ext', 'd', 'crop');
38
+ // formati output
39
+ const ALLOWED_FORMATS = array(
40
+ 'avif' => 'image/avif',
41
+ 'pjpeg' => 'image/pjpeg',
42
+ 'jpeg' => 'image/jpeg',
43
+ 'jpg' => 'image/jpeg',
44
+ 'png' => 'image/png',
45
+ 'gif' => 'image/gif',
46
+ 'webp' => 'image/webp',
47
+ 'ico' => 'image/vnd.microsoft.icon'
48
+ );
49
+
50
+ // formati preferiti per la scelta automatica in ordine di preferenza
51
+ // in loro mancanza il formato prefefinito è jpeg
52
+ // (NB: devono essere uguali alle chiavi di ALLOWED_FORMATS)
53
+ const PREFERRED_AUTO_FORMATS = ['avif', 'webp'];
54
+
55
+ // formati input accettati da Imagick (in aggiunta a quelli definiti in ALLOWED_FORMATS)
56
+ const ALLOWED_INPUT = ['bmp', 'tiff', 'tif'];
57
+
58
+ // parametro compression quality di default
59
+ const DEFAULT_COMPRESSION_QUALITY = 60;
60
+
61
+ // src -> percorso assoluto dentro la dir public con gli slash
62
+ #[Route(path: '/iviewer', name: 'img_viewer')]
63
+ public function indexAction(Request $request)
64
+ {
65
+
66
+
67
+ $get = $request->query->all();
68
+ $src = $get['src'];
69
+
70
+ if (!$src)
71
+ throw $this->createNotFoundException('Parametro mancante! (src)');
72
+
73
+ // formati supportati dall'istanza imageMagick
74
+ $supported_formats = array_map("strtolower", \imagick::queryFormats());
75
+
76
+ // formati accettati dal browser
77
+ $accept = $request->server->get('HTTP_ACCEPT');
78
+
79
+ // format 'auto' default
80
+ if(!isset($get['f'])) $get['f'] = 'auto';
81
+
82
+ // format 'auto' -> sceglie il formato migliore per il browser, se disponibile
83
+ if(isset($get['f']) && strtolower($get['f']) == 'auto') {
84
+
85
+ foreach(self::PREFERRED_AUTO_FORMATS as $f) {
86
+ if(strpos($accept, self::ALLOWED_FORMATS[$f]) !== false &&
87
+ in_array($f, array_keys(self::ALLOWED_FORMATS)) &&
88
+ in_array($f, $supported_formats)
89
+ ) {
90
+ $get['f']=$f;
91
+ break;
92
+ }
93
+ }
94
+ }
95
+
96
+
97
+ // durata della cache dei file: 7gg
98
+ $cache_lifetime = 604800;
99
+
100
+ $params = $this->cleanParams($get);
101
+
102
+ $cache_params_str = "";
103
+
104
+ // parte del nome file del cache formata da tutti i parametri concatenati tra loro
105
+ foreach ($params as $kg => $g) {
106
+ if ($kg != 'refresh' && $kg != 'raw')
107
+ $cache_params_str .= '_' . $kg . $g;
108
+ }
109
+ $cache_params_str = str_replace(',', '_', $cache_params_str);
110
+
111
+
112
+ $publicPath = $this->getParameter('kernel.project_dir') . '/public';
113
+ $filePath = $publicPath . $src;
114
+
115
+ $fileExt = strtolower(pathinfo($filePath, PATHINFO_EXTENSION));
116
+ // $fileBasename = strtolower(pathinfo($filePath, PATHINFO_BASENAME));
117
+ // $fileCacheName = $fileBasename; // porzione inziale del nome del file di cache
118
+ $fileCacheName = str_replace('/', '_', $src); // porzione inziale del nome del file di cache
119
+
120
+
121
+ if (isset($params['d'])) {
122
+ $disposition = 'attachment';
123
+ } else {
124
+ $disposition = 'inline';
125
+ }
126
+
127
+
128
+ // elaborazione immagine: se sono presenti parametri, non è settato raw ed è un formato trattabile da imagick
129
+ if (count($params) && !isset($params['raw']) && in_array($fileExt, array_merge(self::ALLOWED_INPUT, array_keys(self::ALLOWED_FORMATS)))) {
130
+
131
+ // se è richiesto un formato deve essere tra quelli permessi
132
+ if (isset($params['f']) &&
133
+ in_array($params['f'], array_keys(self::ALLOWED_FORMATS)) &&
134
+ in_array($params['f'], $supported_formats)
135
+ ) {
136
+
137
+ $format = $params['f'];
138
+
139
+ // se è presente il parametro ext ed è tra quelli permessi
140
+ } else if (isset($params['ext']) && $params['ext'] && in_array(strtolower($fileExt), array_keys(self::ALLOWED_FORMATS))) {
141
+
142
+ $format = strtolower($fileExt);
143
+
144
+ // formato predefinito in assenza di altre impostazioni
145
+ } else {
146
+ $format = 'jpeg';
147
+ }
148
+
149
+ $fileCacheName = $fileCacheName . $cache_params_str . '.' . ($format == 'pjpeg' ? 'jpeg' : $format);
150
+
151
+ $cachefile = $this->getParameter('cache_dir') . $fileCacheName;
152
+
153
+ // definizione della qualità della compressione dell'immagine
154
+ $compressionQuality = !empty($params['q']) ? intval($params['q']) : self::DEFAULT_COMPRESSION_QUALITY;
155
+
156
+
157
+ // elaborazione con imagick per i seguenti casi:
158
+ // 1) non esiste il file nella cartella cache
159
+ // 2) la cache è scaduta
160
+ // 3) è richiesto il refresh
161
+ if (!file_exists($cachefile) || (filemtime($cachefile) + $cache_lifetime) < time() || isset($params['refresh'])) {
162
+
163
+ // inizializzazione imagick
164
+ $img = new \Imagick();
165
+ $img->readImage($filePath);
166
+
167
+ $img->stripImage(); // Strips an image of all profiles and comments
168
+
169
+ if(isset($params['crop']) or isset($params['bb'])) {
170
+ // dimensioni originali
171
+ $ow = $img->getImageWidth();
172
+ $oh = $img->getImageHeight();
173
+ }
174
+
175
+
176
+ if(isset($params['crop'])) {
177
+ $crop_params = array_map( fn($val) => intval(trim($val)), explode(',', $params['crop']));
178
+
179
+ // devono essere presenti tutti e 4 i parametri e devono essere maggiori di zero
180
+ if(count($crop_params) != 4 or min($crop_params) < 0) {
181
+ throw $this->createNotFoundException('Errore di configurazione! (crop 1)');
182
+ }
183
+
184
+ [$x,$y,$crop_w,$crop_h] = $crop_params;
185
+
186
+ // l'area ritagliata non può essere più grande dell'immagine
187
+ if($x + $crop_w > $ow or $y + $crop_h > $oh) {
188
+ throw $this->createNotFoundException('Errore di configurazione! (crop 2)');
189
+ }
190
+
191
+ $img->cropImage($crop_w, $crop_h, $x, $y);
192
+
193
+ // nuove dimensioni dell'immagine (corrispondono a $crop_w e $crop_h)
194
+ $ow = $img->getImageWidth();
195
+ $oh = $img->getImageHeight();
196
+ }
197
+
198
+ if (isset($params['bb'])) {
199
+ $bb_param = strtolower($params['bb']);
200
+ $bb_has_x = strpos($bb_param, 'x') !== false;
201
+
202
+ if ($bb_has_x) {
203
+ // dimensioni richieste
204
+ // se un parametro è mancante viene impostato a 0 e non ha influenza nelle elaborazioni successive
205
+ [$w, $h] = array_map( fn($val) => $val? (int)$val : 0, explode('x', $bb_param));
206
+
207
+ // le dimensioni richieste non possono superare quelle originali
208
+ if ($w > $ow) $w = $ow;
209
+ if ($h > $oh) $h = $oh;
210
+ }
211
+ }
212
+
213
+ // fd => l'immagine deve rispettare con precisione le dimensioni richieste
214
+ // è necessario che siano presenti entrambi i parametri bb
215
+ if (isset($params['bb']) && isset($params['fd']) && $bb_has_x && $w > 0 && $h > 0) {
216
+
217
+ if ($ow < $w && $oh < $h) {
218
+ $nb = $ow;
219
+ $nh = $oh;
220
+
221
+ if ($w > $h) {
222
+ $r = $h / $w;
223
+ } else {
224
+ $r = $w / $h;
225
+ }
226
+
227
+ if ($nb > $nh) {
228
+ $nh = $r * $nb;
229
+ } else {
230
+ $nb = $r * $nh;
231
+ }
232
+
233
+ $w = $nb;
234
+ $h = $nh;
235
+
236
+ }
237
+
238
+ $img->cropThumbnailImage($w, $h);
239
+ // $img->resizeImage($w, $h, \imagick::FILTER_GAUSSIAN, 0);
240
+
241
+ } elseif (isset($params['bb']) && $bb_has_x) {
242
+
243
+ if ($w != 0 || $h != 0) {
244
+ $nb = $ow;
245
+ $nh = $oh;
246
+ if ($w != 0 && $w < $nb) {
247
+ $nh = ($w / $nb) * $nh;
248
+ $nb = $w;
249
+ }
250
+
251
+ if ($h != 0 && $h < $nh) {
252
+ $nb = ($h / $nh) * $nb;
253
+ $nh = $h;
254
+ }
255
+
256
+ $w = $nb;
257
+ $h = $nh;
258
+ }
259
+ $img->thumbnailImage($w, $h, true);
260
+ // $img->resizeImage($w, $h, \imagick::FILTER_GAUSSIAN, 0);
261
+ }
262
+
263
+ // compressione immagine
264
+ if ($compressionQuality) {
265
+ $img->setImageCompressionQuality($compressionQuality);
266
+ }
267
+ //$img->setImageAlphaChannel(\imagick::COMPOSITE_CLEAR);
268
+ //$img->setBackgroundColor(new \ImagickPixel('white'));
269
+
270
+ // formato immagine
271
+
272
+ $img->setImageFormat($format);
273
+
274
+ // $mimeType = $img->getImageMimeType();
275
+ $mimeType = self::ALLOWED_FORMATS[$format];
276
+
277
+
278
+ /*if ($format == 'webp') {
279
+ // per i webp non posso recuperare direttamente il mime type con il metodo
280
+ $mimeType = 'image/webp';
281
+
282
+ //$img->setImageAlphaChannel(\imagick::COMPOSITE_CLEAR);
283
+ //$img->setBackgroundColor(new \ImagickPixel('transparent'));
284
+
285
+ } else if ($format == 'pjpeg') {
286
+ $mimeType = 'image/jpeg';
287
+
288
+ } else */
289
+
290
+ if ($format == 'ico') {
291
+ $img->setImageAlphaChannel(\imagick::COMPOSITE_CLEAR);
292
+ $img->setBackgroundColor(new \ImagickPixel('transparent'));
293
+ $img->cropThumbnailImage(16, 16);
294
+ // $mimeType = self::ALLOWED_FORMATS['ico']; //'image/vnd.microsoft.icon';
295
+
296
+ } else if ($format == 'png') {
297
+ $mimeType = 'png';
298
+ if (isset($params['alpha']) && isset($params['bg']) && preg_match('/[0-9a-f]{6}/i', $params['bg'])) {
299
+ $bgColor = '#' . $params['bg'];
300
+ // elimino la trasparenza
301
+ //$img->setImageAlphaChannel(\imagick::COMPOSITE_CLEAR);
302
+ $img->setImageBackgroundColor($bgColor);
303
+ $img = $img->flattenImages();
304
+
305
+ } else {
306
+ //$bgColor = '#ffffff';
307
+ //$img->setImageAlphaChannel(\imagick::COMPOSITE_CLEAR);
308
+ //$img->setBackgroundColor(new \ImagickPixel('transparent'));
309
+
310
+ $draw = new \ImagickDraw();
311
+ $draw->setStrokeAntialias(false);
312
+ $img->drawImage($draw);
313
+ }
314
+ }
315
+
316
+ $img->writeImage($cachefile);
317
+ $img->clear();
318
+ $img->destroy();
319
+
320
+ } else {
321
+
322
+ $mimeType = self::ALLOWED_FORMATS[$format];
323
+ }
324
+
325
+
326
+
327
+ // nessuna elaborazione richiesta: restituisce il file originale
328
+ } else {
329
+
330
+ $cachefile = $filePath;
331
+ // $fileCacheName = $fileBasename . '.' . $fileExt;
332
+ $fileCacheName = str_replace('/', '_', $src);
333
+
334
+ if ($fileExt == 'svg')
335
+ $mimeType = 'image/svg+xml';
336
+ }
337
+
338
+
339
+ $response = new BinaryFileResponse($cachefile);
340
+ $response->trustXSendfileTypeHeader();
341
+
342
+ if (isset($mimeType)) {
343
+ $response->headers->set('Content-Type', $mimeType);
344
+ }
345
+
346
+ $response->headers->set('Content-Disposition', $disposition . '; filename = ' . $fileCacheName);
347
+
348
+ return $response;
349
+
350
+ //return array();
351
+
352
+ }
353
+
354
+ protected function cleanParams($params) {
355
+
356
+ //compatibilità con vecchio parametro jq
357
+ // if(isset($params['jq']) && !isset($params['q'])) {
358
+ // $params['q'] = $params['jq'];
359
+ // }
360
+
361
+ // array_walk($params, create_function('&$val', '$val = trim($val);'));
362
+ // array_walk($params, function ($val): string {
363
+ // return trim($val);
364
+ // });
365
+
366
+
367
+ foreach ($params as $key => $value) {
368
+ if(!in_array($key, self::ALLOWED_PARAMS)) {
369
+ unset($params[$key]);
370
+ } else if($value) {
371
+ $params[$key] = trim($value);
372
+ }
373
+ }
374
+
375
+ if(isset($params['f'])) {
376
+ $params['f'] = strtolower($params['f']);
377
+ }
378
+
379
+ return $params;
380
+ }
381
+
382
+ // restituisce un json con le info dell'immagine indicata
383
+ #[Route(path: '/iviewer-info', name: 'img_viewer_info')]
384
+ public function iviewerInfo(Request $request)
385
+ {
386
+ $get = $request->query->all();
387
+ $src = $get['src'];
388
+
389
+ if (!$src)
390
+ throw $this->createNotFoundException('iviewer-info: Parametro mancante! (src)');
391
+
392
+ $publicPath = $this->getParameter('kernel.project_dir') . '/public';
393
+ $filePath = $publicPath . $src;
394
+
395
+ $img_info = getimagesize($filePath);
396
+
397
+ $response = new JsonResponse();
398
+ $response->setData($img_info);
399
+
400
+ return $response;
401
+
402
+ }
403
+ }
@@ -0,0 +1,74 @@
1
+ <?php
2
+
3
+ namespace App\Controller;
4
+
5
+ use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
6
+ use Symfony\Component\Routing\Annotation\Route;
7
+ use Symfony\Component\HttpFoundation\Request;
8
+ use Symfony\Component\HttpFoundation\Response;
9
+
10
+ class UnsplashController extends AbstractController
11
+ {
12
+
13
+ #[Route('/get-unsplash', name: 'get_unsplash')]
14
+ public function get(Request $request)
15
+ {
16
+ // $get = $request->query->all();
17
+ // $src = $get['src'];
18
+ $orientation = $request->query->get('orientation', 'landscape'); // landscape, portrait, squarish, null
19
+
20
+ $allowed = ['landscape', 'portrait', 'squarish', null];
21
+ if (!in_array($orientation, $allowed)) {
22
+ $orientation = 'landscape';
23
+ }
24
+
25
+ $unsplash_access_key = 'xxxxxxx';
26
+ $collections_ids = '3660951'; // comma separated list
27
+ $count = null;
28
+
29
+ $url = 'https://api.unsplash.com/photos/random' .
30
+ "?client_id={$unsplash_access_key}" .
31
+ "&collections={$collections_ids}" .
32
+ ($orientation? "&orientation={$orientation}" : '') .
33
+ ($count != null? "&count={$count}" : '');
34
+
35
+ $json = file_get_contents($url);
36
+
37
+
38
+ $response = new Response();
39
+ $response->headers->set('Content-Type', 'application/json; charset=utf-8');
40
+ $response->setContent($json);
41
+
42
+ $env = $this->getParameter('kernel.environment');
43
+
44
+ return $response;
45
+
46
+ }
47
+
48
+ #[Route('/unsplash-browser', name: 'unsplash_browser')]
49
+ public function browse(Request $request)
50
+ {
51
+ $unsplash_access_key = 'xxxxxxx';
52
+
53
+ $get = $request->query->all();
54
+
55
+ $url = 'https://api.unsplash.com/search/photos' .
56
+ "?client_id={$unsplash_access_key}";
57
+
58
+ foreach($get as $key => $value) {
59
+ $url .= '&' . rawurlencode($key) . '=' . rawurlencode($value);
60
+ }
61
+
62
+ $json = file_get_contents($url);
63
+
64
+ $response = new Response();
65
+ $response->headers->set('Content-Type', 'application/json; charset=utf-8');
66
+ $response->setContent($json);
67
+
68
+ $env = $this->getParameter('kernel.environment');
69
+
70
+ return $response;
71
+
72
+ }
73
+
74
+ }
@@ -0,0 +1,101 @@
1
+ /* eslint-disable no-console */
2
+ /* eslint-env node */
3
+
4
+ import fs from 'fs';
5
+
6
+ const device_std_height = 700,
7
+
8
+ breakpoints = [
9
+ {title: 'moto g5', w: 360, h: 512},
10
+
11
+ {title: 'bs5 xs max', w: 575, h: device_std_height},
12
+ {title: 'bs5 sm min', w: 576, h: device_std_height},
13
+ {title: 'bs5 sm max', w: 767, h: device_std_height},
14
+ {title: 'bs5 md min', w: 768, h: device_std_height},
15
+ {title: 'bs5 md max', w: 991, h: device_std_height},
16
+ {title: 'bs5 lg min', w: 992, h: device_std_height},
17
+ {title: 'bs5 lg max', w: 1199, h: device_std_height},
18
+ {title: 'bs5 xl min', w: 1200, h: device_std_height},
19
+ {title: 'bs5 xl max', w: 1399, h: device_std_height},
20
+ {title: 'bs5 xxl min', w: 1400, h: device_std_height},
21
+
22
+
23
+ {title: 'schermo staff BV (1280x960)', w: 1280, h: 960},
24
+ {title: '1366x768', w: 1366, h: 768},
25
+ {title: '1280x720 (HD)', w: 1280, h: 720},
26
+ {title: '1920x1080 (full HD)', w: 1920, h: 1980},
27
+
28
+ ];
29
+
30
+ let device_list = breakpoints.map((item, idx) => {
31
+
32
+ return {
33
+ 'title': ('00' + String(idx+1)).slice(-2) + '. ' + item.title,
34
+ 'type': 'unknown',
35
+ 'user-agent': '',
36
+ 'capabilities': [
37
+ 'mobile'
38
+ ],
39
+ 'screen': {
40
+ 'device-pixel-ratio': 0,
41
+ 'vertical': {
42
+ 'width': item.w,
43
+ 'height': item.h
44
+ },
45
+ 'horizontal': {
46
+ 'width': item.h,
47
+ 'height': item.w
48
+ }
49
+ },
50
+ 'modes': [
51
+ {
52
+ 'title': '',
53
+ 'orientation': 'vertical',
54
+ 'insets': {
55
+ 'left': 0,
56
+ 'top': 0,
57
+ 'right': 0,
58
+ 'bottom': 0
59
+ }
60
+ },
61
+ {
62
+ 'title': '',
63
+ 'orientation': 'horizontal',
64
+ 'insets': {
65
+ 'left': 0,
66
+ 'top': 0,
67
+ 'right': 0,
68
+ 'bottom': 0
69
+ }
70
+ }
71
+ ],
72
+ 'show-by-default': true,
73
+ 'dual-screen': false,
74
+ 'show': 'Default',
75
+ 'user-agent-metadata': {
76
+ 'brands': [
77
+ {
78
+ 'brand': '',
79
+ 'version': ''
80
+ }
81
+ ],
82
+ 'fullVersion': '',
83
+ 'platform': '',
84
+ 'platformVersion': '',
85
+ 'architecture': '',
86
+ 'model': '',
87
+ 'mobile': true
88
+ }
89
+ };
90
+ });
91
+
92
+
93
+ const dest = 'ChromeCustomDeviceList.txt',
94
+ str = '"custom-emulated-device-list":"'+ JSON.stringify(device_list).replace(/"/g, '\\"') + '",';
95
+
96
+ fs.writeFileSync(dest, str);
97
+
98
+ console.log (
99
+ 'copiare all\'interno del file `~/Library/Application Support/Google/Chrome/Default/Preferences` (NB: è un file JSON)\n'+
100
+ 'vedi: https://stackoverflow.com/a/70905335/743443\n'
101
+ );
@@ -0,0 +1,13 @@
1
+ DATABASE_URL=mysql://root:mysql8root@127.0.0.1:3306/xxxx?serverVersion=8.0
2
+
3
+ APP_ENV=dev
4
+ APP_DEBUG=1
5
+
6
+ ### mailHog
7
+ MAILER_DSN=smtp://localhost:1025
8
+
9
+ ### supporto webpack
10
+ # cartella, dentro public, in cui webpack salva js, css immagini ecc
11
+ ASSETS_DIR=_dev
12
+
13
+
@@ -0,0 +1,10 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: "npm" # Indica che stiamo usando NPM
4
+ directory: "/" # Dove si trova il package.json
5
+ schedule:
6
+ interval: "monthly" # Può essere: daily, weekly, monthly
7
+ open-pull-requests-limit: 15 # Massimo 10 PR aperte contemporaneamente
8
+ labels:
9
+ - "dependencies"
10
+ - "javascript"
@@ -0,0 +1,35 @@
1
+ module.exports = {
2
+ "connector": {
3
+ "name": "local",
4
+ "options": {
5
+ "pattern": ["./build/**/*.html"] // Analizza i file HTML generati nella directory di build
6
+ }
7
+ },
8
+ "extends": [
9
+ "development", // Configurazione base per lo sviluppo
10
+ "accessibility", // Regole per l'accessibilità
11
+ "performance", // Regole per le prestazioni
12
+ "security", // Regole per la sicurezza
13
+ "html-checker" // Controllo della validità HTML
14
+ ],
15
+ "hints": {
16
+ "axe": "error", // Controlla l'accessibilità con axe-core
17
+ "content-type": "error", // Verifica i tipi di contenuto corretti
18
+ "disown-opener": "warning", // Consiglia di usare `rel="noopener"`
19
+ "http-cache": ["warning", { "maxAge": 31536000 }], // Suggerisce una cache HTTP ottimale
20
+ "image-optimization-cloudinary": "off", // Disattiva l'ottimizzazione delle immagini
21
+ "meta-viewport": "error", // Verifica la presenza del meta tag viewport
22
+ "no-vulnerable-javascript-libraries": "error", // Controlla librerie JS vulnerabili
23
+ "performance-budget": [
24
+ "warning",
25
+ {
26
+ "resourceTypes": {
27
+ "script": 250, // Limite di 250 KB per gli script
28
+ "image": 500 // Limite di 500 KB per le immagini
29
+ }
30
+ }
31
+ ],
32
+ "strict-transport-security": "error", // Suggerisce l'uso di HSTS
33
+ "validate-set-cookie-header": "error" // Controlla l'uso corretto dell'header Set-Cookie
34
+ }
35
+ };