@jjlmoya/utils-home 1.1.0

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 (77) hide show
  1. package/package.json +62 -0
  2. package/src/category/i18n/en.ts +24 -0
  3. package/src/category/i18n/es.ts +24 -0
  4. package/src/category/i18n/fr.ts +24 -0
  5. package/src/category/index.ts +12 -0
  6. package/src/category/seo.astro +15 -0
  7. package/src/components/PreviewNavSidebar.astro +116 -0
  8. package/src/components/PreviewToolbar.astro +143 -0
  9. package/src/data.ts +11 -0
  10. package/src/env.d.ts +5 -0
  11. package/src/index.ts +26 -0
  12. package/src/layouts/PreviewLayout.astro +117 -0
  13. package/src/pages/[locale]/[slug].astro +146 -0
  14. package/src/pages/[locale].astro +251 -0
  15. package/src/pages/index.astro +4 -0
  16. package/src/tests/faq_count.test.ts +19 -0
  17. package/src/tests/locale_completeness.test.ts +42 -0
  18. package/src/tests/mocks/astro_mock.js +2 -0
  19. package/src/tests/no_h1_in_components.test.ts +48 -0
  20. package/src/tests/seo_length.test.ts +22 -0
  21. package/src/tests/tool_validation.test.ts +17 -0
  22. package/src/tool/dewPointCalculator/bibliography.astro +14 -0
  23. package/src/tool/dewPointCalculator/component.astro +443 -0
  24. package/src/tool/dewPointCalculator/i18n/en.ts +183 -0
  25. package/src/tool/dewPointCalculator/i18n/es.ts +183 -0
  26. package/src/tool/dewPointCalculator/i18n/fr.ts +183 -0
  27. package/src/tool/dewPointCalculator/index.ts +34 -0
  28. package/src/tool/dewPointCalculator/logic.ts +16 -0
  29. package/src/tool/dewPointCalculator/seo.astro +14 -0
  30. package/src/tool/dewPointCalculator/ui.ts +13 -0
  31. package/src/tool/ledSavingCalculator/bibliography.astro +14 -0
  32. package/src/tool/ledSavingCalculator/component.astro +520 -0
  33. package/src/tool/ledSavingCalculator/i18n/en.ts +217 -0
  34. package/src/tool/ledSavingCalculator/i18n/es.ts +217 -0
  35. package/src/tool/ledSavingCalculator/i18n/fr.ts +217 -0
  36. package/src/tool/ledSavingCalculator/index.ts +34 -0
  37. package/src/tool/ledSavingCalculator/logic.ts +31 -0
  38. package/src/tool/ledSavingCalculator/seo.astro +14 -0
  39. package/src/tool/ledSavingCalculator/ui.ts +32 -0
  40. package/src/tool/projectorCalculator/bibliography.astro +14 -0
  41. package/src/tool/projectorCalculator/component.astro +569 -0
  42. package/src/tool/projectorCalculator/i18n/en.ts +181 -0
  43. package/src/tool/projectorCalculator/i18n/es.ts +181 -0
  44. package/src/tool/projectorCalculator/i18n/fr.ts +181 -0
  45. package/src/tool/projectorCalculator/index.ts +34 -0
  46. package/src/tool/projectorCalculator/logic.ts +21 -0
  47. package/src/tool/projectorCalculator/seo.astro +14 -0
  48. package/src/tool/projectorCalculator/ui.ts +16 -0
  49. package/src/tool/qrGenerator/bibliography.astro +14 -0
  50. package/src/tool/qrGenerator/component.astro +499 -0
  51. package/src/tool/qrGenerator/i18n/en.ts +233 -0
  52. package/src/tool/qrGenerator/i18n/es.ts +233 -0
  53. package/src/tool/qrGenerator/i18n/fr.ts +233 -0
  54. package/src/tool/qrGenerator/index.ts +34 -0
  55. package/src/tool/qrGenerator/logic.ts +27 -0
  56. package/src/tool/qrGenerator/seo.astro +14 -0
  57. package/src/tool/qrGenerator/ui.ts +23 -0
  58. package/src/tool/solarCalculator/bibliography.astro +14 -0
  59. package/src/tool/solarCalculator/component.astro +532 -0
  60. package/src/tool/solarCalculator/i18n/en.ts +176 -0
  61. package/src/tool/solarCalculator/i18n/es.ts +176 -0
  62. package/src/tool/solarCalculator/i18n/fr.ts +176 -0
  63. package/src/tool/solarCalculator/index.ts +34 -0
  64. package/src/tool/solarCalculator/logic.ts +31 -0
  65. package/src/tool/solarCalculator/seo.astro +14 -0
  66. package/src/tool/solarCalculator/ui.ts +11 -0
  67. package/src/tool/tariffComparator/bibliography.astro +14 -0
  68. package/src/tool/tariffComparator/component.astro +595 -0
  69. package/src/tool/tariffComparator/i18n/en.ts +192 -0
  70. package/src/tool/tariffComparator/i18n/es.ts +192 -0
  71. package/src/tool/tariffComparator/i18n/fr.ts +192 -0
  72. package/src/tool/tariffComparator/index.ts +34 -0
  73. package/src/tool/tariffComparator/logic.ts +47 -0
  74. package/src/tool/tariffComparator/seo.astro +14 -0
  75. package/src/tool/tariffComparator/ui.ts +25 -0
  76. package/src/tools.ts +9 -0
  77. package/src/types.ts +72 -0
package/package.json ADDED
@@ -0,0 +1,62 @@
1
+ {
2
+ "name": "@jjlmoya/utils-home",
3
+ "version": "1.1.0",
4
+ "type": "module",
5
+ "main": "./src/index.ts",
6
+ "types": "./src/index.ts",
7
+ "exports": {
8
+ ".": "./src/index.ts",
9
+ "./data": "./src/data.ts"
10
+ },
11
+ "files": [
12
+ "src"
13
+ ],
14
+ "publishConfig": {
15
+ "access": "public"
16
+ },
17
+ "scripts": {
18
+ "dev": "astro dev",
19
+ "start": "astro dev",
20
+ "build": "astro build",
21
+ "preview": "astro preview",
22
+ "astro": "astro",
23
+ "lint": "eslint src/ --max-warnings 0 && stylelint \"src/**/*.{css,astro}\"",
24
+ "check": "astro check",
25
+ "type-check": "astro check",
26
+ "test": "vitest run",
27
+ "preversion": "npm run lint && npm run test",
28
+ "postversion": "git push && git push --tags",
29
+ "patch": "npm version patch",
30
+ "minor": "npm version minor",
31
+ "major": "npm version major"
32
+ },
33
+ "lint-staged": {
34
+ "*.{ts,tsx,astro}": [
35
+ "eslint --fix"
36
+ ]
37
+ },
38
+ "dependencies": {
39
+ "@iconify-json/mdi": "^1.2.3",
40
+ "@jjlmoya/utils-shared": "^1.1.0",
41
+ "astro": "^6.1.2",
42
+ "astro-icon": "^1.1.0",
43
+ "qrcode": "^1.5.4"
44
+ },
45
+ "devDependencies": {
46
+ "@astrojs/check": "^0.9.8",
47
+ "@types/qrcode": "^1.5.6",
48
+ "eslint": "^9.39.4",
49
+ "eslint-plugin-astro": "^1.6.0",
50
+ "eslint-plugin-no-comments": "^1.1.10",
51
+ "husky": "^9.1.7",
52
+ "lint-staged": "^16.4.0",
53
+ "postcss-html": "^1.8.1",
54
+ "schema-dts": "^1.1.2",
55
+ "stylelint": "^17.6.0",
56
+ "stylelint-config-standard": "^40.0.0",
57
+ "stylelint-declaration-strict-value": "^1.11.1",
58
+ "typescript": "^5.4.0",
59
+ "typescript-eslint": "^8.58.0",
60
+ "vitest": "^4.1.2"
61
+ }
62
+ }
@@ -0,0 +1,24 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'template-category',
5
+ title: 'Template Category',
6
+ description: 'Category description.',
7
+ seo: [
8
+ {
9
+ type: 'summary',
10
+ title: 'Summary',
11
+ items: ['Point 1', 'Point 2', 'Point 3'],
12
+ },
13
+ {
14
+ type: 'title',
15
+ text: 'Section title',
16
+ level: 2,
17
+ },
18
+ {
19
+ type: 'paragraph',
20
+ html: 'Category SEO content.',
21
+ },
22
+ ],
23
+ };
24
+
@@ -0,0 +1,24 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'categoria-template',
5
+ title: 'Categoría Template',
6
+ description: 'Descripción de la categoría.',
7
+ seo: [
8
+ {
9
+ type: 'summary',
10
+ title: 'Resumen',
11
+ items: ['Punto 1', 'Punto 2', 'Punto 3'],
12
+ },
13
+ {
14
+ type: 'title',
15
+ text: 'Título de sección',
16
+ level: 2,
17
+ },
18
+ {
19
+ type: 'paragraph',
20
+ html: 'Contenido SEO de la categoría.',
21
+ },
22
+ ],
23
+ };
24
+
@@ -0,0 +1,24 @@
1
+ import type { CategoryLocaleContent } from '../../types';
2
+
3
+ export const content: CategoryLocaleContent = {
4
+ slug: 'categorie-template',
5
+ title: 'Catégorie Template',
6
+ description: 'Description de la catégorie.',
7
+ seo: [
8
+ {
9
+ type: 'summary',
10
+ title: 'Résumé',
11
+ items: ['Point 1', 'Point 2', 'Point 3'],
12
+ },
13
+ {
14
+ type: 'title',
15
+ text: 'Titre de section',
16
+ level: 2,
17
+ },
18
+ {
19
+ type: 'paragraph',
20
+ html: 'Contenu SEO de la catégorie.',
21
+ },
22
+ ],
23
+ };
24
+
@@ -0,0 +1,12 @@
1
+ import type { HomeCategoryEntry } from '../types';
2
+
3
+ export const homeCategory: HomeCategoryEntry = {
4
+ icon: 'mdi:home',
5
+ tools: [],
6
+ i18n: {
7
+ es: () => import('./i18n/es').then((m) => m.content),
8
+ en: () => import('./i18n/en').then((m) => m.content),
9
+ fr: () => import('./i18n/fr').then((m) => m.content),
10
+ },
11
+ };
12
+
@@ -0,0 +1,15 @@
1
+ ---
2
+ import { SEORenderer } from '@jjlmoya/utils-shared';
3
+ import { homeCategory } from './index';
4
+ import type { KnownLocale } from '../types';
5
+
6
+ interface Props {
7
+ locale?: KnownLocale;
8
+ }
9
+
10
+ const { locale = 'es' } = Astro.props;
11
+ const content = await homeCategory.i18n[locale]?.();
12
+ ---
13
+
14
+ {content && <SEORenderer content={{ locale, sections: content.seo }} />}
15
+
@@ -0,0 +1,116 @@
1
+ ---
2
+ interface NavItem {
3
+ id: string;
4
+ title: string;
5
+ href: string;
6
+ isActive?: boolean;
7
+ }
8
+
9
+ interface Props {
10
+ categoryTitle: string;
11
+ tools?: NavItem[];
12
+ }
13
+
14
+ const { categoryTitle, tools = [] } = Astro.props;
15
+ ---
16
+
17
+ <nav class="preview-nav-sidebar">
18
+ <div class="sidebar-header">
19
+ <h3>{categoryTitle}</h3>
20
+ </div>
21
+
22
+ <ul class="tools-list">
23
+ {tools.map((tool) => (
24
+ <li>
25
+ <a
26
+ href={tool.href}
27
+ class:list={['tool-link', { active: tool.isActive }]}
28
+ >
29
+ <span class="tool-title">{tool.title}</span>
30
+ </a>
31
+ </li>
32
+ ))}
33
+ </ul>
34
+ </nav>
35
+
36
+ <style>
37
+ .preview-nav-sidebar {
38
+ display: flex;
39
+ flex-direction: column;
40
+ height: 100%;
41
+ background: var(--bg-surface, #0f172a);
42
+ }
43
+
44
+ .sidebar-header {
45
+ padding: 2rem 1.5rem 1.5rem;
46
+ border-bottom: 1px solid var(--border-color, #1e293b);
47
+ }
48
+
49
+ .sidebar-header h3 {
50
+ margin: 0;
51
+ font-size: 0.75rem;
52
+ font-weight: 900;
53
+ text-transform: uppercase;
54
+ letter-spacing: 0.1em;
55
+ color: var(--text-muted, #94a3b8);
56
+ }
57
+
58
+ .tools-list {
59
+ list-style: none;
60
+ margin: 0;
61
+ padding: 0.5rem 0;
62
+ display: flex;
63
+ flex-direction: column;
64
+ gap: 0.25rem;
65
+ }
66
+
67
+ .tools-list li {
68
+ margin: 0;
69
+ }
70
+
71
+ .tool-link {
72
+ display: flex;
73
+ align-items: center;
74
+ padding: 0.75rem 1.5rem;
75
+ color: var(--text-muted, #94a3b8);
76
+ text-decoration: none;
77
+ font-size: 0.9375rem;
78
+ font-weight: 500;
79
+ transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
80
+ border-left: 3px solid transparent;
81
+ position: relative;
82
+ }
83
+
84
+ .tool-link:hover {
85
+ color: var(--text-base, #f1f5f9);
86
+ background: rgba(255, 255, 255, 0.08);
87
+ padding-left: 1.75rem;
88
+ }
89
+
90
+ .tool-link.active {
91
+ color: var(--accent, #f43f5e);
92
+ background: rgba(244, 63, 94, 0.15);
93
+ border-left-color: var(--accent, #f43f5e);
94
+ font-weight: 600;
95
+ }
96
+
97
+ .tool-link.active::before {
98
+ content: '';
99
+ position: absolute;
100
+ left: 0;
101
+ top: 50%;
102
+ transform: translateY(-50%);
103
+ width: 3px;
104
+ height: 24px;
105
+ background: var(--accent, #f43f5e);
106
+ border-radius: 0 2px 2px 0;
107
+ }
108
+
109
+ .tool-title {
110
+ display: block;
111
+ overflow: hidden;
112
+ text-overflow: ellipsis;
113
+ white-space: nowrap;
114
+ }
115
+ </style>
116
+
@@ -0,0 +1,143 @@
1
+ ---
2
+ import type { KnownLocale } from '../types';
3
+
4
+ interface Props {
5
+ currentLocale: KnownLocale;
6
+ localeUrls?: Partial<Record<KnownLocale, string>>;
7
+ }
8
+
9
+ const { currentLocale, localeUrls = {} } = Astro.props;
10
+
11
+ const otherLocales = Object.entries(localeUrls).filter(([l]) => l !== currentLocale) as [
12
+ KnownLocale,
13
+ string,
14
+ ][];
15
+ ---
16
+
17
+ <nav class="preview-toolbar">
18
+ {
19
+ otherLocales.length > 0 && (
20
+ <div class="locale-group">
21
+ <span class="locale-current">{currentLocale.toUpperCase()}</span>
22
+ {otherLocales.map(([locale, url]) => (
23
+ <a href={url} class="btn-locale">
24
+ {locale.toUpperCase()}
25
+ </a>
26
+ ))}
27
+ </div>
28
+ )
29
+ }
30
+
31
+ <button id="theme-toggle" class="btn-theme" aria-label="Toggle theme" title="Toggle theme">
32
+ <span class="theme-icon"></span>
33
+ </button>
34
+ </nav>
35
+
36
+ <script>
37
+ function initToolbar() {
38
+ const btn = document.getElementById('theme-toggle');
39
+ if (!btn) return;
40
+
41
+ const applyTheme = (theme: string) => {
42
+ document.documentElement.classList.remove('theme-light', 'theme-dark');
43
+ document.documentElement.classList.add(theme);
44
+ localStorage.setItem('theme', theme);
45
+ };
46
+
47
+ btn.addEventListener('click', () => {
48
+ const next = document.documentElement.classList.contains('theme-dark')
49
+ ? 'theme-light'
50
+ : 'theme-dark';
51
+ applyTheme(next);
52
+ });
53
+ }
54
+
55
+ initToolbar();
56
+ document.addEventListener('astro:after-swap', initToolbar);
57
+ </script>
58
+
59
+ <style>
60
+ .preview-toolbar {
61
+ position: fixed;
62
+ top: 1rem;
63
+ right: 1.5rem;
64
+ display: flex;
65
+ align-items: center;
66
+ gap: 0.5rem;
67
+ z-index: 1000;
68
+ background: var(--bg-surface);
69
+ padding: 0.4rem;
70
+ border-radius: 1rem;
71
+ border: 1px solid var(--border-color);
72
+ backdrop-filter: blur(12px);
73
+ }
74
+
75
+ .locale-group {
76
+ display: flex;
77
+ align-items: center;
78
+ gap: 0.25rem;
79
+ padding-right: 0.5rem;
80
+ border-right: 1px solid var(--border-color);
81
+ }
82
+
83
+ .locale-current {
84
+ font-size: 0.7rem;
85
+ font-weight: 900;
86
+ color: var(--text-muted);
87
+ padding: 0.4rem 0.6rem;
88
+ letter-spacing: 0.08em;
89
+ }
90
+
91
+ .btn-locale {
92
+ background: transparent;
93
+ border: 1px solid var(--border-color);
94
+ color: var(--text-main);
95
+ cursor: pointer;
96
+ padding: 0.4rem 0.7rem;
97
+ border-radius: 0.5rem;
98
+ font-weight: 700;
99
+ font-size: 0.7rem;
100
+ text-decoration: none;
101
+ letter-spacing: 0.08em;
102
+ transition: all 0.2s ease;
103
+ }
104
+
105
+ .btn-locale:hover {
106
+ border-color: var(--accent);
107
+ color: var(--accent);
108
+ }
109
+
110
+ .btn-theme {
111
+ background: transparent;
112
+ border: none;
113
+ cursor: pointer;
114
+ padding: 0.5rem;
115
+ border-radius: 0.6rem;
116
+ display: flex;
117
+ align-items: center;
118
+ justify-content: center;
119
+ transition: background 0.2s ease;
120
+ }
121
+
122
+ .btn-theme:hover {
123
+ background: rgba(255, 255, 255, 0.08);
124
+ }
125
+
126
+ .theme-icon {
127
+ display: block;
128
+ width: 16px;
129
+ height: 16px;
130
+ border-radius: 50%;
131
+ }
132
+
133
+ :global(.theme-light) .theme-icon {
134
+ background: #f59e0b;
135
+ box-shadow: 0 0 8px #fbbf24;
136
+ }
137
+
138
+ :global(.theme-dark) .theme-icon {
139
+ background: #94a3b8;
140
+ box-shadow: inset -4px -2px 0 #1e293b;
141
+ }
142
+ </style>
143
+
package/src/data.ts ADDED
@@ -0,0 +1,11 @@
1
+ export { homeCategory } from './category';
2
+
3
+ export type {
4
+ KnownLocale,
5
+ ToolLocaleContent,
6
+ CategoryLocaleContent,
7
+ LocaleMap,
8
+ HomeToolEntry,
9
+ HomeCategoryEntry,
10
+ } from './types';
11
+
package/src/env.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ declare module '*.astro' {
2
+ const Component: (_props: Record<string, unknown>) => unknown;
3
+ export default Component;
4
+ }
5
+
package/src/index.ts ADDED
@@ -0,0 +1,26 @@
1
+ export { homeCategory } from './category';
2
+ export { default as homeCategorySEO } from './category/seo.astro';
3
+
4
+ export type {
5
+ KnownLocale,
6
+ FAQItem,
7
+ BibliographyEntry,
8
+ HowToStep,
9
+ ToolLocaleContent,
10
+ CategoryLocaleContent,
11
+ LocaleLoader,
12
+ LocaleMap,
13
+ HomeToolEntry,
14
+ HomeCategoryEntry,
15
+ ToolDefinition,
16
+ } from './types';
17
+
18
+ export { ALL_TOOLS } from './tools';
19
+
20
+ export { QRGeneratorComponent, QRGeneratorSEO, QRGeneratorBibliography } from './tool/qrGenerator';
21
+ export { SolarCalculatorComponent, SolarCalculatorSEO, SolarCalculatorBibliography } from './tool/solarCalculator';
22
+ export { ProjectorCalculatorComponent, ProjectorCalculatorSEO, ProjectorCalculatorBibliography } from './tool/projectorCalculator';
23
+ export { DewPointCalculatorComponent, DewPointCalculatorSEO, DewPointCalculatorBibliography } from './tool/dewPointCalculator';
24
+ export { LedSavingCalculatorComponent, LedSavingCalculatorSEO, LedSavingCalculatorBibliography } from './tool/ledSavingCalculator';
25
+ export { TariffComparatorComponent, TariffComparatorSEO, TariffComparatorBibliography } from './tool/tariffComparator';
26
+
@@ -0,0 +1,117 @@
1
+ ---
2
+ import "@jjlmoya/utils-shared/theme.css";
3
+ import PreviewToolbar from "../components/PreviewToolbar.astro";
4
+ import type { KnownLocale } from "../types";
5
+
6
+ interface Props {
7
+ title: string;
8
+ currentLocale?: KnownLocale;
9
+ localeUrls?: Partial<Record<KnownLocale, string>>;
10
+ hasSidebar?: boolean;
11
+ }
12
+
13
+ const { title, currentLocale = "es", localeUrls = {}, hasSidebar = false } = Astro.props;
14
+ ---
15
+
16
+ <!doctype html>
17
+ <html lang={currentLocale}>
18
+ <head>
19
+ <meta charset="UTF-8" />
20
+ <meta name="viewport" content="width=device-width" />
21
+ <title>{title} · preview</title>
22
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
23
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
24
+ <link
25
+ href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&display=swap"
26
+ rel="stylesheet"
27
+ />
28
+
29
+ <script is:inline>
30
+ (function () {
31
+ const saved = localStorage.getItem("theme") || "theme-dark";
32
+ document.documentElement.classList.add(saved);
33
+ })();
34
+ </script>
35
+ <slot name="head" />
36
+ </head>
37
+ <body>
38
+ <PreviewToolbar currentLocale={currentLocale} localeUrls={localeUrls} />
39
+ <div class:list={["page-wrapper", { "with-sidebar": hasSidebar }]}>
40
+ {
41
+ hasSidebar && (
42
+ <aside class="sidebar-area">
43
+ <slot name="sidebar" />
44
+ </aside>
45
+ )
46
+ }
47
+ <main>
48
+ <slot />
49
+ </main>
50
+ </div>
51
+ </body>
52
+ </html>
53
+
54
+ <style is:global>
55
+ :root {
56
+ --accent: #f43f5e;
57
+ --primary-base: #9f1239;
58
+ --cyan: #06b6d4;
59
+ }
60
+
61
+ .theme-dark,
62
+ .theme-light {
63
+ --text-main: var(--text-base);
64
+ --border-color: var(--border-base);
65
+ }
66
+
67
+ *,
68
+ *::before,
69
+ *::after {
70
+ box-sizing: border-box;
71
+ }
72
+
73
+ body {
74
+ background-color: var(--bg-page);
75
+ color: var(--text-base);
76
+ margin: 0;
77
+ min-height: 100vh;
78
+ transition:
79
+ background-color 0.3s ease,
80
+ color 0.3s ease;
81
+ }
82
+
83
+ main {
84
+ padding: 0 2rem;
85
+ }
86
+
87
+ .page-wrapper {
88
+ display: flex;
89
+ flex-direction: column;
90
+ }
91
+
92
+ .page-wrapper.with-sidebar {
93
+ display: grid;
94
+ grid-template-columns: 240px 1fr;
95
+ min-height: 100vh;
96
+ }
97
+
98
+ .sidebar-area {
99
+ position: sticky;
100
+ top: 0;
101
+ height: 100vh;
102
+ overflow-y: auto;
103
+ border-right: 1px solid var(--border-color);
104
+ background: var(--bg-page);
105
+ }
106
+
107
+ @media (max-width: 768px) {
108
+ .page-wrapper.with-sidebar {
109
+ grid-template-columns: 1fr;
110
+ }
111
+
112
+ .sidebar-area {
113
+ display: none;
114
+ }
115
+ }
116
+ </style>
117
+