@oasisomniverse/angular 1.0.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 (118) hide show
  1. package/package.json +37 -0
  2. package/src/components/avatar/avatar-wallet.component.ts +49 -0
  3. package/src/components/avatar/edit-avatar.component.ts +28 -0
  4. package/src/components/avatar/search-avatar.component.ts +45 -0
  5. package/src/components/avatar/view-avatar.component.ts +49 -0
  6. package/src/components/avatar-connect/avatar-connect.component.ts +78 -0
  7. package/src/components/avatar-profile/avatar-profile.component.ts +146 -0
  8. package/src/components/coming-soon/coming-soon.component.ts +27 -0
  9. package/src/components/confirmation/confirmation.component.ts +38 -0
  10. package/src/components/contact/contact.component.ts +64 -0
  11. package/src/components/data-screen/add-data.component.ts +50 -0
  12. package/src/components/data-screen/cross-chain-management.component.ts +28 -0
  13. package/src/components/data-screen/load-data.component.ts +28 -0
  14. package/src/components/data-screen/manage-data.component.ts +50 -0
  15. package/src/components/data-screen/off-chain-management.component.ts +28 -0
  16. package/src/components/data-screen/search-data.component.ts +40 -0
  17. package/src/components/eggs/eggs.component.ts +76 -0
  18. package/src/components/eggs/manage-eggs.component.ts +50 -0
  19. package/src/components/eggs/search-eggs.component.ts +40 -0
  20. package/src/components/eggs/view-eggs.component.ts +49 -0
  21. package/src/components/forgot-password/forgot-password.component.ts +80 -0
  22. package/src/components/game/game.component.ts +58 -0
  23. package/src/components/game/search-profiles.component.ts +36 -0
  24. package/src/components/game/view-achievements.component.ts +48 -0
  25. package/src/components/game/view-leagues.component.ts +48 -0
  26. package/src/components/game/view-tournaments.component.ts +49 -0
  27. package/src/components/hyperdrive/hyperdrive.component.ts +81 -0
  28. package/src/components/karma/search-karma.component.ts +36 -0
  29. package/src/components/karma/view-avatar-karma.component.ts +51 -0
  30. package/src/components/karma/view-karma.component.ts +46 -0
  31. package/src/components/karma/vote-karma.component.ts +48 -0
  32. package/src/components/karma-panel/karma-panel.component.ts +87 -0
  33. package/src/components/karma-toast/karma-toast.component.ts +33 -0
  34. package/src/components/login/login.component.ts +95 -0
  35. package/src/components/map/add-2d-object-map.component.ts +42 -0
  36. package/src/components/map/add-3d-object-map.component.ts +43 -0
  37. package/src/components/map/add-quest-to-map.component.ts +42 -0
  38. package/src/components/map/download-our-world.component.ts +28 -0
  39. package/src/components/map/manage-map.component.ts +28 -0
  40. package/src/components/map/map.component.ts +70 -0
  41. package/src/components/map/plot-route-on-map.component.ts +42 -0
  42. package/src/components/map/search-map.component.ts +44 -0
  43. package/src/components/map/view-global-3d-map.component.ts +28 -0
  44. package/src/components/map/view-halons-on-map.component.ts +28 -0
  45. package/src/components/map/view-oapp-on-map.component.ts +28 -0
  46. package/src/components/map/view-quest-on-map.component.ts +28 -0
  47. package/src/components/menu-message/menu-message.component.ts +69 -0
  48. package/src/components/messages/message.component.ts +59 -0
  49. package/src/components/messaging/messaging.component.ts +89 -0
  50. package/src/components/mission/manage-mission.component.ts +43 -0
  51. package/src/components/mission/mission.component.ts +63 -0
  52. package/src/components/mission/search-mission.component.ts +36 -0
  53. package/src/components/mission/view-mission.component.ts +49 -0
  54. package/src/components/modal/modal.component.ts +28 -0
  55. package/src/components/navbar/navbar.component.ts +64 -0
  56. package/src/components/nft/contact-popup.component.ts +41 -0
  57. package/src/components/nft/manage-oasis-nft.component.ts +43 -0
  58. package/src/components/nft/nft.component.ts +70 -0
  59. package/src/components/nft/purchase-oasis-nft.component.ts +53 -0
  60. package/src/components/nft/purchase-oasis-virtual-land-nft.component.ts +28 -0
  61. package/src/components/nft/search-oasis-nft.component.ts +36 -0
  62. package/src/components/nft/solana.component.ts +28 -0
  63. package/src/components/nft/view-oasis-nft.component.ts +52 -0
  64. package/src/components/oapp/create-oapp.component.ts +43 -0
  65. package/src/components/oapp/deploy-oapp.component.ts +42 -0
  66. package/src/components/oapp/download-our-world.component.ts +28 -0
  67. package/src/components/oapp/edit-oapp.component.ts +41 -0
  68. package/src/components/oapp/install-oapp.component.ts +36 -0
  69. package/src/components/oapp/launch-oapp.component.ts +58 -0
  70. package/src/components/oapp/manage-oapp.component.ts +42 -0
  71. package/src/components/oapp/oapp.component.ts +70 -0
  72. package/src/components/oapp/search-oapp.component.ts +36 -0
  73. package/src/components/oasis-card/oasis-card.component.ts +30 -0
  74. package/src/components/onet/onet.component.ts +77 -0
  75. package/src/components/onode/onode.component.ts +73 -0
  76. package/src/components/provider/activity-pub.component.ts +44 -0
  77. package/src/components/provider/compare-provider-speeds.component.ts +48 -0
  78. package/src/components/provider/eosio.component.ts +44 -0
  79. package/src/components/provider/ethereum.component.ts +44 -0
  80. package/src/components/provider/holochain.component.ts +44 -0
  81. package/src/components/provider/ipfs.component.ts +44 -0
  82. package/src/components/provider/manage-auto-fail-over.component.ts +42 -0
  83. package/src/components/provider/manage-auto-replicaton.component.ts +42 -0
  84. package/src/components/provider/manage-load-balancing.component.ts +42 -0
  85. package/src/components/provider/manage-providers.component.ts +28 -0
  86. package/src/components/provider/mongo-db.component.ts +44 -0
  87. package/src/components/provider/neo4j.component.ts +44 -0
  88. package/src/components/provider/search-providers.component.ts +36 -0
  89. package/src/components/provider/seeds-provider.component.ts +42 -0
  90. package/src/components/provider/solid.component.ts +44 -0
  91. package/src/components/provider/sql-lite.component.ts +44 -0
  92. package/src/components/provider/three-fold.component.ts +44 -0
  93. package/src/components/provider/view-provider-stats.component.ts +61 -0
  94. package/src/components/provider/view-providers.component.ts +54 -0
  95. package/src/components/provider-dropdown/provider-dropdown.component.ts +64 -0
  96. package/src/components/providers/providers.component.ts +60 -0
  97. package/src/components/quest/manage-quest.component.ts +43 -0
  98. package/src/components/quest/quest.component.ts +65 -0
  99. package/src/components/quest/search-quest.component.ts +36 -0
  100. package/src/components/quest/view-quest.component.ts +49 -0
  101. package/src/components/reset-password/reset-password.component.ts +68 -0
  102. package/src/components/search-avatars/search-avatars.component.ts +80 -0
  103. package/src/components/seeds/accept-invite.component.ts +44 -0
  104. package/src/components/seeds/donate-seeds.component.ts +42 -0
  105. package/src/components/seeds/manage-seeds.component.ts +42 -0
  106. package/src/components/seeds/pay-with-seeds.component.ts +41 -0
  107. package/src/components/seeds/reward-seeds.component.ts +41 -0
  108. package/src/components/seeds/search-seeds.component.ts +36 -0
  109. package/src/components/seeds/seeds.component.ts +75 -0
  110. package/src/components/seeds/send-invite.component.ts +41 -0
  111. package/src/components/seeds/view-organizations.component.ts +55 -0
  112. package/src/components/seeds/view-seeds.component.ts +78 -0
  113. package/src/components/settings/settings.component.ts +96 -0
  114. package/src/components/signup/signup.component.ts +118 -0
  115. package/src/components/star-field/star-field.component.ts +44 -0
  116. package/src/components/verify-email/verify-email.component.ts +48 -0
  117. package/src/components/wallet/wallet.component.ts +83 -0
  118. package/src/index.ts +145 -0
@@ -0,0 +1,78 @@
1
+ import { Component, Input, Output, EventEmitter, signal } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+
4
+ @Component({
5
+ selector: 'oasis-view-seeds',
6
+ standalone: true,
7
+ imports: [CommonModule],
8
+ template: `
9
+ <div class="vs-shell">
10
+ <div class="vs-header"><span>🌱</span><h2 class="vs-title">View Seeds</h2></div>
11
+ <div class="vs-summary">
12
+ <div class="vs-stat"><div class="vs-stat-val">2,222</div><div class="vs-stat-lbl">Your Seeds</div></div>
13
+ <div class="vs-stat"><div class="vs-stat-val">777</div><div class="vs-stat-lbl">Karma</div></div>
14
+ </div>
15
+ <div class="vs-section">
16
+ <h3 class="vs-section-title">Seeds Sent</h3>
17
+ <div class="vs-table-wrap">
18
+ <table class="vs-table">
19
+ <thead><tr><th>Date</th><th>To Avatar</th><th>Amount</th><th>Type</th><th>Karma Earnt</th></tr></thead>
20
+ <tbody>
21
+ @for (tx of sent(); track tx.date) {
22
+ <tr><td>{{ tx.date }}</td><td>{{ tx.to }}</td><td>{{ tx.amount }}</td><td>{{ tx.type }}</td><td>+{{ tx.karma }}</td></tr>
23
+ }
24
+ </tbody>
25
+ </table>
26
+ </div>
27
+ </div>
28
+ <div class="vs-section">
29
+ <h3 class="vs-section-title">Seeds Received</h3>
30
+ <div class="vs-table-wrap">
31
+ <table class="vs-table">
32
+ <thead><tr><th>Date</th><th>From Avatar</th><th>Amount</th><th>Type</th><th>Karma Earnt</th></tr></thead>
33
+ <tbody>
34
+ @for (tx of received(); track tx.date) {
35
+ <tr><td>{{ tx.date }}</td><td>{{ tx.from }}</td><td>{{ tx.amount }}</td><td>{{ tx.type }}</td><td>+{{ tx.karma }}</td></tr>
36
+ }
37
+ </tbody>
38
+ </table>
39
+ </div>
40
+ </div>
41
+ <div class="vs-actions">
42
+ <button class="vs-action-btn" (click)="close.emit()">Pay with Seeds</button>
43
+ <button class="vs-action-btn" (click)="close.emit()">Donate with Seeds</button>
44
+ <button class="vs-action-btn" (click)="close.emit()">Reward with Seeds</button>
45
+ </div>
46
+ </div>
47
+ `,
48
+ styles: [`
49
+ .vs-shell{display:flex;flex-direction:column;gap:16px;padding:20px}
50
+ .vs-header{display:flex;align-items:center;gap:10px}
51
+ .vs-title{font-family:'Orbitron',sans-serif;font-size:18px;color:#fff;margin:0}
52
+ .vs-summary{display:flex;gap:16px}
53
+ .vs-stat{flex:1;background:rgba(0,200,255,.06);border:1px solid rgba(0,200,255,.15);border-radius:10px;padding:14px;text-align:center}
54
+ .vs-stat-val{font-family:'Orbitron',sans-serif;font-size:24px;font-weight:700;color:#00c8ff}
55
+ .vs-stat-lbl{font-size:11px;color:#7a9bbf;margin-top:4px;text-transform:uppercase;letter-spacing:.06em}
56
+ .vs-section{display:flex;flex-direction:column;gap:8px}
57
+ .vs-section-title{font-family:'Orbitron',sans-serif;font-size:13px;color:#fff;margin:0}
58
+ .vs-table-wrap{overflow-x:auto;border:1px solid rgba(0,200,255,.1);border-radius:8px}
59
+ .vs-table{width:100%;border-collapse:collapse;font-size:12px}
60
+ .vs-table th{background:rgba(0,200,255,.06);color:#00c8ff;font-family:'Orbitron',sans-serif;font-size:9px;font-weight:700;letter-spacing:.06em;padding:8px 10px;text-align:left;border-bottom:1px solid rgba(0,200,255,.1)}
61
+ .vs-table td{color:#c8dff0;padding:7px 10px;border-bottom:1px solid rgba(255,255,255,.04)}
62
+ .vs-table tr:last-child td{border-bottom:none}
63
+ .vs-actions{display:flex;gap:10px;flex-wrap:wrap}
64
+ .vs-action-btn{flex:1;background:linear-gradient(135deg,#00c8ff,#0080ff);border:none;border-radius:8px;color:#fff;font-family:'Orbitron',sans-serif;font-size:11px;font-weight:700;padding:10px;cursor:pointer;white-space:nowrap}
65
+ `]
66
+ })
67
+ export class ViewSeedsComponent {
68
+ @Input() show = false;
69
+ @Output() close = new EventEmitter<void>();
70
+ sent = signal([
71
+ { date:'2026-07-01', to:'StarWalker', amount:'50', type:'Gift', karma:5 },
72
+ { date:'2026-06-28', to:'NebulaDancer', amount:'100', type:'Reward', karma:10 },
73
+ ]);
74
+ received = signal([
75
+ { date:'2026-07-02', from:'CosmicSage', amount:'25', type:'Gift', karma:3 },
76
+ { date:'2026-06-30', from:'VoidWatcher', amount:'200', type:'Quest', karma:20 },
77
+ ]);
78
+ }
@@ -0,0 +1,96 @@
1
+ import { Component, signal } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { FormsModule } from '@angular/forms';
4
+
5
+ @Component({
6
+ selector: 'oasis-settings',
7
+ standalone: true,
8
+ imports: [CommonModule, FormsModule],
9
+ template: `
10
+ <div class="sett-shell">
11
+ <div class="sett-header"><h2 class="sett-title">⚙️ Settings</h2><p class="sett-sub">Manage your OASIS account and preferences.</p></div>
12
+ <div class="sett-sections">
13
+ @for (sec of sections; track sec.label) {
14
+ <div class="sett-section" [class.sett-section--open]="openSection() === sec.label" (click)="openSection.set(openSection() === sec.label ? '' : sec.label)">
15
+ <div class="sett-section-header">
16
+ <span class="sett-section-icon">{{ sec.icon }}</span>
17
+ <span class="sett-section-label">{{ sec.label }}</span>
18
+ <span class="sett-chevron">{{ openSection() === sec.label ? '▲' : '▼' }}</span>
19
+ </div>
20
+ @if (openSection() === sec.label) {
21
+ <div class="sett-section-body">
22
+ @for (opt of sec.options; track opt.key) {
23
+ <div class="sett-opt">
24
+ <div class="sett-opt-info"><div class="sett-opt-name">{{ opt.name }}</div><div class="sett-opt-desc">{{ opt.desc }}</div></div>
25
+ @if (opt.type === 'toggle') {
26
+ <div class="sett-toggle" [class.sett-toggle--on]="prefs[opt.key]" (click)="prefs[opt.key] = !prefs[opt.key]">
27
+ <div class="sett-toggle-knob"></div>
28
+ </div>
29
+ }
30
+ @if (opt.type === 'select') {
31
+ <select class="sett-select" [(ngModel)]="prefs[opt.key]">
32
+ @for (c of opt.choices; track c) { <option [value]="c">{{ c }}</option> }
33
+ </select>
34
+ }
35
+ </div>
36
+ }
37
+ </div>
38
+ }
39
+ </div>
40
+ }
41
+ </div>
42
+ <button class="oasis-btn" (click)="save()">{{ saved() ? '✅ Saved!' : 'Save Settings' }}</button>
43
+ </div>
44
+ `,
45
+ styles: [`
46
+ .sett-shell{display:flex;flex-direction:column;gap:18px}
47
+ .sett-header{text-align:center}
48
+ .sett-title{font-family:'Orbitron',sans-serif;font-size:20px;color:#fff;margin:0 0 6px}
49
+ .sett-sub{font-size:13px;color:#7a9bbf;margin:0}
50
+ .sett-sections{display:flex;flex-direction:column;gap:8px}
51
+ .sett-section{background:rgba(255,255,255,.04);border:1px solid rgba(0,200,255,.12);border-radius:10px;overflow:hidden;transition:border-color .2s}
52
+ .sett-section--open{border-color:rgba(0,200,255,.3)}
53
+ .sett-section-header{display:flex;align-items:center;gap:10px;padding:14px 16px;cursor:pointer;user-select:none}
54
+ .sett-section-icon{font-size:18px}
55
+ .sett-section-label{flex:1;font-family:'Orbitron',sans-serif;font-size:13px;color:#fff}
56
+ .sett-chevron{font-size:10px;color:#7a9bbf}
57
+ .sett-section-body{padding:0 16px 16px;display:flex;flex-direction:column;gap:14px}
58
+ .sett-opt{display:flex;align-items:center;gap:14px}
59
+ .sett-opt-info{flex:1}
60
+ .sett-opt-name{font-size:13px;color:#e0f0ff}
61
+ .sett-opt-desc{font-size:11px;color:#4a6a88;margin-top:2px}
62
+ .sett-toggle{width:44px;height:24px;border-radius:999px;background:rgba(255,255,255,.1);cursor:pointer;transition:background .2s;position:relative;flex-shrink:0}
63
+ .sett-toggle--on{background:linear-gradient(135deg,#00c8ff,#0080ff)}
64
+ .sett-toggle-knob{position:absolute;top:3px;left:3px;width:18px;height:18px;border-radius:50%;background:#fff;transition:transform .2s}
65
+ .sett-toggle--on .sett-toggle-knob{transform:translateX(20px)}
66
+ .sett-select{background:rgba(255,255,255,.05);border:1px solid rgba(0,200,255,.2);border-radius:7px;color:#fff;font-size:12px;padding:6px 10px;outline:none}
67
+ .oasis-btn{background:linear-gradient(135deg,#00c8ff,#0080ff);border:none;border-radius:8px;color:#fff;font-family:'Orbitron',sans-serif;font-size:13px;font-weight:700;letter-spacing:.08em;padding:12px;cursor:pointer;transition:opacity .2s}
68
+ `]
69
+ })
70
+ export class SettingsComponent {
71
+ openSection = signal('');
72
+ saved = signal(false);
73
+ prefs: Record<string, any> = {
74
+ notifications: true, darkMode: true, sound: false, autoSave: true,
75
+ language: 'English', theme: 'Dark Space', currency: 'ETH'
76
+ };
77
+ sections = [
78
+ { icon: '🔔', label: 'Notifications', options: [
79
+ { key: 'notifications', name: 'Enable Notifications', desc: 'Receive alerts for karma, messages and quests.', type: 'toggle' },
80
+ { key: 'sound', name: 'Sound Effects', desc: 'Play sounds for OASIS events.', type: 'toggle' },
81
+ ]},
82
+ { icon: '🎨', label: 'Appearance', options: [
83
+ { key: 'darkMode', name: 'Dark Mode', desc: 'Use the dark space theme.', type: 'toggle' },
84
+ { key: 'theme', name: 'Theme', desc: 'Select your OASIS visual theme.', type: 'select', choices: ['Dark Space', 'Neon City', 'Forest Realm'] },
85
+ ]},
86
+ { icon: '🌐', label: 'Language & Region', options: [
87
+ { key: 'language', name: 'Language', desc: 'Select your preferred language.', type: 'select', choices: ['English', 'Spanish', 'French', 'German', 'Japanese'] },
88
+ { key: 'currency', name: 'Display Currency', desc: 'Currency for prices and values.', type: 'select', choices: ['ETH', 'SOL', 'USD', 'GBP', 'EUR'] },
89
+ ]},
90
+ { icon: '💾', label: 'Data', options: [
91
+ { key: 'autoSave', name: 'Auto-save Progress', desc: 'Automatically save your OASIS progress.', type: 'toggle' },
92
+ ]},
93
+ ];
94
+
95
+ save() { this.saved.set(true); setTimeout(() => this.saved.set(false), 2000); }
96
+ }
@@ -0,0 +1,118 @@
1
+ import { Component, signal, Output, EventEmitter, inject } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { FormsModule } from '@angular/forms';
4
+ import { OasisService } from '../../services/oasis.service';
5
+
6
+ @Component({
7
+ selector: 'oasis-signup',
8
+ standalone: true,
9
+ imports: [CommonModule, FormsModule],
10
+ template: `
11
+ <div class="oasis-auth-form">
12
+ <div class="oasis-auth-header">
13
+ <h2 class="oasis-auth-title">Sign Up</h2>
14
+ <p class="oasis-auth-sub">Already have an account? <a class="oasis-link" (click)="switchTo.emit('login')" href="javascript:void(0)">Beam In</a></p>
15
+ </div>
16
+
17
+ @if (error()) {
18
+ <div class="oasis-auth-error">{{ error() }}</div>
19
+ }
20
+ @if (success()) {
21
+ <div class="oasis-auth-success">Account created! <a class="oasis-link" (click)="switchTo.emit('login')" href="javascript:void(0)">Beam In</a></div>
22
+ }
23
+
24
+ @if (!success()) {
25
+ <div class="oasis-grid-2">
26
+ <div class="oasis-field">
27
+ <label class="oasis-label" for="su-first">First Name</label>
28
+ <input class="oasis-input" id="su-first" type="text" [(ngModel)]="firstName" placeholder="John" required />
29
+ </div>
30
+ <div class="oasis-field">
31
+ <label class="oasis-label" for="su-last">Last Name</label>
32
+ <input class="oasis-input" id="su-last" type="text" [(ngModel)]="lastName" placeholder="Doe" required />
33
+ </div>
34
+ </div>
35
+
36
+ <div class="oasis-grid-2">
37
+ <div class="oasis-field">
38
+ <label class="oasis-label" for="su-username">Username</label>
39
+ <input class="oasis-input" id="su-username" type="text" [(ngModel)]="username" placeholder="johndoe" autocomplete="username" required />
40
+ </div>
41
+ <div class="oasis-field">
42
+ <label class="oasis-label" for="su-email">Email</label>
43
+ <input class="oasis-input" id="su-email" type="email" [(ngModel)]="email" placeholder="name@example.com" autocomplete="email" required />
44
+ </div>
45
+ </div>
46
+
47
+ <div class="oasis-grid-2">
48
+ <div class="oasis-field">
49
+ <label class="oasis-label" for="su-pwd">Password</label>
50
+ <input class="oasis-input" id="su-pwd" type="password" [(ngModel)]="password" placeholder="min 6 characters" minlength="6" autocomplete="new-password" required />
51
+ </div>
52
+ <div class="oasis-field">
53
+ <label class="oasis-label" for="su-cpwd">Confirm Password</label>
54
+ <input class="oasis-input" id="su-cpwd" type="password" [(ngModel)]="confirmPassword" placeholder="••••••••" minlength="6" autocomplete="new-password" required />
55
+ </div>
56
+ </div>
57
+
58
+ <div class="oasis-field oasis-field--row">
59
+ <input class="oasis-checkbox" id="su-terms" type="checkbox" [(ngModel)]="acceptTerms" />
60
+ <label class="oasis-label oasis-label--inline" for="su-terms">I accept the Terms of Service</label>
61
+ </div>
62
+
63
+ <button class="oasis-btn" type="button" [disabled]="loading()" (click)="submit()">
64
+ {{ loading() ? 'Creating account…' : 'Create Account' }}
65
+ </button>
66
+ }
67
+ </div>
68
+ `,
69
+ styles: [`
70
+ .oasis-auth-form { display:flex; flex-direction:column; gap:18px; }
71
+ .oasis-auth-header { text-align:center; }
72
+ .oasis-auth-title { font-family:'Orbitron',sans-serif; font-size:22px; color:#fff; margin:0 0 6px; }
73
+ .oasis-auth-sub { font-size:13px; color:#7a9bbf; margin:0; }
74
+ .oasis-auth-error { background:rgba(255,80,80,.12); border:1px solid rgba(255,80,80,.3); color:#ff6b6b; border-radius:8px; padding:10px 14px; font-size:13px; }
75
+ .oasis-auth-success { background:rgba(72,220,130,.12); border:1px solid rgba(72,220,130,.3); color:#48dc82; border-radius:8px; padding:10px 14px; font-size:13px; }
76
+ .oasis-grid-2 { display:grid; grid-template-columns:1fr 1fr; gap:14px; }
77
+ .oasis-field { display:flex; flex-direction:column; gap:6px; }
78
+ .oasis-field--row { flex-direction:row; align-items:center; gap:10px; }
79
+ .oasis-label { font-size:12px; font-weight:600; letter-spacing:.06em; color:#7a9bbf; text-transform:uppercase; }
80
+ .oasis-label--inline { text-transform:none; font-size:13px; color:#a8bfd8; }
81
+ .oasis-input { width:100%; background:rgba(255,255,255,.05); border:1px solid rgba(0,200,255,.2); border-radius:8px; padding:10px 14px; color:#fff; font-size:14px; outline:none; box-sizing:border-box; transition:border-color .2s; }
82
+ .oasis-input:focus { border-color:rgba(0,200,255,.5); }
83
+ .oasis-checkbox { width:16px; height:16px; accent-color:#00c8ff; cursor:pointer; flex-shrink:0; }
84
+ .oasis-link { color:#00c8ff; text-decoration:none; cursor:pointer; }
85
+ .oasis-btn { background:linear-gradient(135deg,#00c8ff,#0080ff); border:none; border-radius:8px; color:#fff; font-family:'Orbitron',sans-serif; font-size:13px; font-weight:700; letter-spacing:.08em; padding:12px; cursor:pointer; transition:opacity .2s; }
86
+ .oasis-btn:disabled { opacity:.5; cursor:not-allowed; }
87
+ `]
88
+ })
89
+ export class SignupComponent {
90
+ @Output() switchTo = new EventEmitter<'login'>();
91
+
92
+ private oasis = inject(OasisService);
93
+
94
+ firstName = ''; lastName = ''; username = ''; email = '';
95
+ password = ''; confirmPassword = ''; acceptTerms = false;
96
+ loading = signal(false);
97
+ error = signal('');
98
+ success = signal(false);
99
+
100
+ async submit() {
101
+ if (!this.firstName || !this.lastName || !this.username || !this.email || !this.password) {
102
+ this.error.set('Please fill in all fields.'); return;
103
+ }
104
+ if (this.password !== this.confirmPassword) { this.error.set('Passwords do not match.'); return; }
105
+ if (this.password.length < 6) { this.error.set('Password must be at least 6 characters.'); return; }
106
+ if (!this.acceptTerms) { this.error.set('Please accept the Terms of Service.'); return; }
107
+ this.loading.set(true);
108
+ this.error.set('');
109
+ try {
110
+ await this.oasis.register(this.firstName, this.lastName, this.username, this.email, this.password);
111
+ this.success.set(true);
112
+ } catch (e: any) {
113
+ this.error.set(e?.message ?? 'Registration failed. Please try again.');
114
+ } finally {
115
+ this.loading.set(false);
116
+ }
117
+ }
118
+ }
@@ -0,0 +1,44 @@
1
+ import { Component, ElementRef, OnInit, OnDestroy, ViewChild, AfterViewInit } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+
4
+ @Component({
5
+ selector: 'oasis-star-field',
6
+ standalone: true,
7
+ imports: [CommonModule],
8
+ template: `<canvas #canvas class="star-canvas"></canvas>`,
9
+ styles: [`
10
+ :host { position: fixed; inset: 0; z-index: 0; pointer-events: none; }
11
+ .star-canvas { width: 100%; height: 100%; display: block; }
12
+ `]
13
+ })
14
+ export class StarFieldComponent implements AfterViewInit, OnDestroy {
15
+ @ViewChild('canvas') canvasRef!: ElementRef<HTMLCanvasElement>;
16
+ private animId = 0;
17
+ private stars: { x: number; y: number; r: number; o: number; s: number }[] = [];
18
+
19
+ ngAfterViewInit(): void {
20
+ const canvas = this.canvasRef.nativeElement;
21
+ const ctx = canvas.getContext('2d')!;
22
+ const resize = () => { canvas.width = window.innerWidth; canvas.height = window.innerHeight; };
23
+ resize();
24
+ window.addEventListener('resize', resize);
25
+ for (let i = 0; i < 160; i++) {
26
+ this.stars.push({ x: Math.random(), y: Math.random(), r: Math.random() * 1.2 + 0.2, o: Math.random(), s: (Math.random() - 0.5) * 0.002 });
27
+ }
28
+ const draw = () => {
29
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
30
+ for (const s of this.stars) {
31
+ s.o += s.s;
32
+ if (s.o < 0.1 || s.o > 1) s.s = -s.s;
33
+ ctx.beginPath();
34
+ ctx.arc(s.x * canvas.width, s.y * canvas.height, s.r, 0, Math.PI * 2);
35
+ ctx.fillStyle = `rgba(200,220,255,${s.o.toFixed(2)})`;
36
+ ctx.fill();
37
+ }
38
+ this.animId = requestAnimationFrame(draw);
39
+ };
40
+ draw();
41
+ }
42
+
43
+ ngOnDestroy(): void { cancelAnimationFrame(this.animId); }
44
+ }
@@ -0,0 +1,48 @@
1
+ import { Component, signal } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { OASISClient } from '@oasisomniverse/web4-api';
4
+
5
+ @Component({
6
+ selector: 'oasis-verify-email',
7
+ standalone: true,
8
+ imports: [CommonModule],
9
+ template: `
10
+ <div class="oasis-auth-form">
11
+ <div class="oasis-auth-header">
12
+ <div style="font-size:48px;margin-bottom:12px">📧</div>
13
+ <h2 class="oasis-auth-title">Verify Your Email</h2>
14
+ <p class="oasis-auth-sub">We sent a verification link to your email address. Check your inbox and click the link to activate your account.</p>
15
+ </div>
16
+ @if (error()) { <div class="oasis-auth-error">{{ error() }}</div> }
17
+ @if (sent()) { <div class="oasis-auth-success">✅ Verification email resent!</div> }
18
+ <button class="oasis-btn oasis-btn--ghost" type="button" [disabled]="loading()" (click)="resend()">
19
+ {{ loading() ? 'Sending…' : 'Resend Verification Email' }}
20
+ </button>
21
+ </div>
22
+ `,
23
+ styles: [`
24
+ .oasis-auth-form{display:flex;flex-direction:column;gap:20px;text-align:center}
25
+ .oasis-auth-header{display:flex;flex-direction:column;align-items:center}
26
+ .oasis-auth-title{font-family:'Orbitron',sans-serif;font-size:20px;color:#fff;margin:0 0 8px}
27
+ .oasis-auth-sub{font-size:13px;color:#7a9bbf;margin:0;line-height:1.6;max-width:360px}
28
+ .oasis-auth-error{background:rgba(255,80,80,.12);border:1px solid rgba(255,80,80,.3);color:#ff6b6b;border-radius:8px;padding:10px 14px;font-size:13px}
29
+ .oasis-auth-success{background:rgba(72,220,130,.12);border:1px solid rgba(72,220,130,.3);color:#48dc82;border-radius:8px;padding:10px 14px;font-size:13px}
30
+ .oasis-btn{border:none;border-radius:8px;color:#fff;font-family:'Orbitron',sans-serif;font-size:13px;font-weight:700;letter-spacing:.08em;padding:12px;cursor:pointer;transition:opacity .2s}
31
+ .oasis-btn--ghost{background:transparent;border:1px solid rgba(0,200,255,.3);color:#00c8ff}
32
+ .oasis-btn:disabled{opacity:.5;cursor:not-allowed}
33
+ `]
34
+ })
35
+ export class VerifyEmailComponent {
36
+ loading = signal(false); error = signal(''); sent = signal(false);
37
+
38
+ async resend() {
39
+ this.loading.set(true); this.error.set(''); this.sent.set(false);
40
+ try {
41
+ const oasis = new OASISClient({ baseUrl: 'https://api.web4.oasisomniverse.one' });
42
+ await (oasis.auth as any).resendVerificationEmail();
43
+ this.sent.set(true);
44
+ } catch (e: any) {
45
+ this.error.set(e?.message ?? 'Failed to resend. Please try again.');
46
+ } finally { this.loading.set(false); }
47
+ }
48
+ }
@@ -0,0 +1,83 @@
1
+ import { Component, signal } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+
4
+ interface Transaction { id: string; type: 'in' | 'out'; amount: number; currency: string; description: string; date: string }
5
+
6
+ @Component({
7
+ selector: 'oasis-wallet',
8
+ standalone: true,
9
+ imports: [CommonModule],
10
+ template: `
11
+ <div class="wlt-shell">
12
+ <div class="wlt-header"><h2 class="wlt-title">💰 Wallet</h2><p class="wlt-sub">Your OASIS multi-chain wallet.</p></div>
13
+ <div class="wlt-balances">
14
+ @for (b of balances; track b.currency) {
15
+ <div class="wlt-balance-card">
16
+ <div class="wlt-currency-icon">{{ b.icon }}</div>
17
+ <div class="wlt-currency-info">
18
+ <div class="wlt-currency-name">{{ b.currency }}</div>
19
+ <div class="wlt-currency-net">{{ b.network }}</div>
20
+ </div>
21
+ <div class="wlt-amount">{{ b.amount }} <span class="wlt-symbol">{{ b.symbol }}</span></div>
22
+ </div>
23
+ }
24
+ </div>
25
+ <div class="wlt-actions">
26
+ <button class="wlt-action-btn">📤 Send</button>
27
+ <button class="wlt-action-btn">📥 Receive</button>
28
+ <button class="wlt-action-btn">🔄 Swap</button>
29
+ </div>
30
+ <div class="wlt-tx-header">Recent Transactions</div>
31
+ <div class="wlt-tx-list">
32
+ @for (t of transactions; track t.id) {
33
+ <div class="wlt-tx">
34
+ <div class="wlt-tx-icon wlt-tx-icon--{{ t.type }}">{{ t.type === 'in' ? '↓' : '↑' }}</div>
35
+ <div class="wlt-tx-info"><div class="wlt-tx-desc">{{ t.description }}</div><div class="wlt-tx-date">{{ t.date }}</div></div>
36
+ <div class="wlt-tx-amount wlt-tx-amount--{{ t.type }}">{{ t.type === 'in' ? '+' : '-' }}{{ t.amount }} {{ t.currency }}</div>
37
+ </div>
38
+ }
39
+ </div>
40
+ </div>
41
+ `,
42
+ styles: [`
43
+ .wlt-shell{display:flex;flex-direction:column;gap:18px}
44
+ .wlt-header{text-align:center}
45
+ .wlt-title{font-family:'Orbitron',sans-serif;font-size:20px;color:#fff;margin:0 0 6px}
46
+ .wlt-sub{font-size:13px;color:#7a9bbf;margin:0}
47
+ .wlt-balances{display:flex;flex-direction:column;gap:10px}
48
+ .wlt-balance-card{display:flex;align-items:center;gap:14px;background:rgba(255,255,255,.04);border:1px solid rgba(0,200,255,.12);border-radius:10px;padding:14px 16px}
49
+ .wlt-currency-icon{font-size:24px}
50
+ .wlt-currency-info{flex:1}
51
+ .wlt-currency-name{font-family:'Orbitron',sans-serif;font-size:13px;color:#fff}
52
+ .wlt-currency-net{font-size:11px;color:#7a9bbf;margin-top:2px}
53
+ .wlt-amount{font-family:'Share Tech Mono',monospace;font-size:16px;color:#00c8ff;font-weight:600}
54
+ .wlt-symbol{font-size:12px;color:#7a9bbf}
55
+ .wlt-actions{display:flex;gap:10px}
56
+ .wlt-action-btn{flex:1;background:rgba(0,200,255,.08);border:1px solid rgba(0,200,255,.2);border-radius:8px;color:#00c8ff;font-family:'Orbitron',sans-serif;font-size:11px;font-weight:700;letter-spacing:.06em;padding:10px;cursor:pointer;transition:all .2s}
57
+ .wlt-action-btn:hover{background:rgba(0,200,255,.15)}
58
+ .wlt-tx-header{font-family:'Orbitron',sans-serif;font-size:12px;color:#7a9bbf;letter-spacing:.06em;text-transform:uppercase}
59
+ .wlt-tx-list{display:flex;flex-direction:column;gap:8px}
60
+ .wlt-tx{display:flex;align-items:center;gap:12px;padding:10px 14px;background:rgba(255,255,255,.03);border:1px solid rgba(0,200,255,.08);border-radius:8px}
61
+ .wlt-tx-icon{width:28px;height:28px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:700;flex-shrink:0}
62
+ .wlt-tx-icon--in{background:rgba(72,220,130,.15);color:#48dc82}
63
+ .wlt-tx-icon--out{background:rgba(255,107,107,.15);color:#ff6b6b}
64
+ .wlt-tx-info{flex:1}
65
+ .wlt-tx-desc{font-size:13px;color:#e0f0ff}
66
+ .wlt-tx-date{font-size:11px;color:#4a6a88;margin-top:2px}
67
+ .wlt-tx-amount{font-family:'Share Tech Mono',monospace;font-size:13px;font-weight:600;white-space:nowrap}
68
+ .wlt-tx-amount--in{color:#48dc82}
69
+ .wlt-tx-amount--out{color:#ff6b6b}
70
+ `]
71
+ })
72
+ export class WalletComponent {
73
+ balances = [
74
+ { icon: '⟠', currency: 'Ethereum', network: 'Mainnet', amount: '0.4821', symbol: 'ETH' },
75
+ { icon: '◎', currency: 'Solana', network: 'Mainnet', amount: '12.305', symbol: 'SOL' },
76
+ { icon: '⬡', currency: 'Polygon', network: 'Mainnet', amount: '245.00', symbol: 'MATIC' },
77
+ ];
78
+ transactions: Transaction[] = [
79
+ { id: '1', type: 'in', amount: 0.05, currency: 'ETH', description: 'NFT Sale — Cosmic Warrior', date: '2 hours ago' },
80
+ { id: '2', type: 'out', amount: 12, currency: 'SOL', description: 'Quest Reward Conversion', date: '1 day ago' },
81
+ { id: '3', type: 'in', amount: 100, currency: 'MATIC', description: 'Karma Reward Payout', date: '3 days ago' },
82
+ ];
83
+ }
package/src/index.ts ADDED
@@ -0,0 +1,145 @@
1
+ // @oasisomniverse/angular — OASIS Omniverse Angular 17 standalone components
2
+
3
+ // ── Core / layout ────────────────────────────────────────────────────────────
4
+ export { AvatarConnectComponent } from './components/avatar-connect/avatar-connect.component';
5
+ export { AvatarProfileComponent } from './components/avatar-profile/avatar-profile.component';
6
+ export { ComingSoonComponent } from './components/coming-soon/coming-soon.component';
7
+ export { ConfirmationComponent } from './components/confirmation/confirmation.component';
8
+ export { ContactComponent } from './components/contact/contact.component';
9
+ export { ForgotPasswordComponent } from './components/forgot-password/forgot-password.component';
10
+ export { HyperDriveComponent } from './components/hyperdrive/hyperdrive.component';
11
+ export { KarmaPanelComponent } from './components/karma-panel/karma-panel.component';
12
+ export { KarmaToastComponent } from './components/karma-toast/karma-toast.component';
13
+ export { LoginComponent } from './components/login/login.component';
14
+ export { MenuMessageComponent } from './components/menu-message/menu-message.component';
15
+ export { MessagingComponent } from './components/messaging/messaging.component';
16
+ export { ModalComponent } from './components/modal/modal.component';
17
+ export { NavbarComponent } from './components/navbar/navbar.component';
18
+ export { OASISCardComponent } from './components/oasis-card/oasis-card.component';
19
+ export { ONETComponent } from './components/onet/onet.component';
20
+ export { ONODEComponent } from './components/onode/onode.component';
21
+ export { ProviderDropdownComponent } from './components/provider-dropdown/provider-dropdown.component';
22
+ export { ProvidersComponent } from './components/providers/providers.component';
23
+ export { ResetPasswordComponent } from './components/reset-password/reset-password.component';
24
+ export { SearchAvatarsComponent } from './components/search-avatars/search-avatars.component';
25
+ export { SettingsComponent } from './components/settings/settings.component';
26
+ export { SignupComponent } from './components/signup/signup.component';
27
+ export { StarFieldComponent } from './components/star-field/star-field.component';
28
+ export { VerifyEmailComponent } from './components/verify-email/verify-email.component';
29
+ export { WalletComponent } from './components/wallet/wallet.component';
30
+
31
+ // ── Avatar popup sub-components ──────────────────────────────────────────────
32
+ export { AvatarWalletComponent } from './components/avatar/avatar-wallet.component';
33
+ export { EditAvatarComponent } from './components/avatar/edit-avatar.component';
34
+ export { SearchAvatarComponent } from './components/avatar/search-avatar.component';
35
+ export { ViewAvatarComponent } from './components/avatar/view-avatar.component';
36
+
37
+ // ── Data Screen popup sub-components ─────────────────────────────────────────
38
+ export { AddDataComponent } from './components/data-screen/add-data.component';
39
+ export { CrossChainManagementComponent } from './components/data-screen/cross-chain-management.component';
40
+ export { LoadDataComponent } from './components/data-screen/load-data.component';
41
+ export { ManageDataComponent } from './components/data-screen/manage-data.component';
42
+ export { OffChainManagementComponent } from './components/data-screen/off-chain-management.component';
43
+ export { SearchDataComponent } from './components/data-screen/search-data.component';
44
+
45
+ // ── Eggs popup sub-components ─────────────────────────────────────────────────
46
+ export { EggsComponent } from './components/eggs/eggs.component';
47
+ export { ManageEggsComponent } from './components/eggs/manage-eggs.component';
48
+ export { SearchEggsComponent } from './components/eggs/search-eggs.component';
49
+ export { ViewEggsComponent } from './components/eggs/view-eggs.component';
50
+
51
+ // ── Game popup sub-components ─────────────────────────────────────────────────
52
+ export { GameComponent } from './components/game/game.component';
53
+ export { SearchProfilesComponent } from './components/game/search-profiles.component';
54
+ export { ViewAchievementsComponent } from './components/game/view-achievements.component';
55
+ export { ViewLeaguesComponent } from './components/game/view-leagues.component';
56
+ export { ViewTournamentsComponent } from './components/game/view-tournaments.component';
57
+
58
+ // ── Karma popup sub-components ────────────────────────────────────────────────
59
+ export { SearchKarmaComponent } from './components/karma/search-karma.component';
60
+ export { ViewAvatarKarmaComponent } from './components/karma/view-avatar-karma.component';
61
+ export { ViewKarmaComponent } from './components/karma/view-karma.component';
62
+ export { VoteKarmaComponent } from './components/karma/vote-karma.component';
63
+
64
+ // ── Map popup sub-components ──────────────────────────────────────────────────
65
+ export { MapComponent } from './components/map/map.component';
66
+ export { Add2dObjectMapComponent } from './components/map/add-2d-object-map.component';
67
+ export { Add3dObjectMapComponent } from './components/map/add-3d-object-map.component';
68
+ export { AddQuestToMapComponent } from './components/map/add-quest-to-map.component';
69
+ export { DownloadOurWorldComponent } from './components/map/download-our-world.component';
70
+ export { ManageMapComponent } from './components/map/manage-map.component';
71
+ export { PlotRouteOnMapComponent } from './components/map/plot-route-on-map.component';
72
+ export { SearchMapComponent } from './components/map/search-map.component';
73
+ export { ViewGlobal3dMapComponent } from './components/map/view-global-3d-map.component';
74
+ export { ViewHalonsOnMapComponent } from './components/map/view-halons-on-map.component';
75
+ export { ViewOappOnMapComponent } from './components/map/view-oapp-on-map.component';
76
+ export { ViewQuestOnMapComponent } from './components/map/view-quest-on-map.component';
77
+
78
+ // ── Messages popup sub-components ────────────────────────────────────────────
79
+ export { MessageComponent } from './components/messages/message.component';
80
+
81
+ // ── Mission popup sub-components ──────────────────────────────────────────────
82
+ export { MissionComponent } from './components/mission/mission.component';
83
+ export { ManageMissionComponent } from './components/mission/manage-mission.component';
84
+ export { SearchMissionComponent } from './components/mission/search-mission.component';
85
+ export { ViewMissionComponent } from './components/mission/view-mission.component';
86
+
87
+ // ── NFT popup sub-components ──────────────────────────────────────────────────
88
+ export { NFTComponent } from './components/nft/nft.component';
89
+ export { ManageOasisNftComponent } from './components/nft/manage-oasis-nft.component';
90
+ export { PurchaseOasisNftComponent } from './components/nft/purchase-oasis-nft.component';
91
+ export { PurchaseOasisVirtualLandNftComponent } from './components/nft/purchase-oasis-virtual-land-nft.component';
92
+ export { SearchOasisNftComponent } from './components/nft/search-oasis-nft.component';
93
+ export { ViewOasisNftComponent } from './components/nft/view-oasis-nft.component';
94
+ export { NftContactPopupComponent } from './components/nft/contact-popup.component';
95
+ export { SolanaComponent } from './components/nft/solana.component';
96
+
97
+ // ── OAPP popup sub-components ─────────────────────────────────────────────────
98
+ export { OAppComponent } from './components/oapp/oapp.component';
99
+ export { CreateOAPPComponent } from './components/oapp/create-oapp.component';
100
+ export { DeployOAPPComponent } from './components/oapp/deploy-oapp.component';
101
+ export { OAPPDownloadOurWorldComponent } from './components/oapp/download-our-world.component';
102
+ export { EditOAPPComponent } from './components/oapp/edit-oapp.component';
103
+ export { InstallOAPPComponent } from './components/oapp/install-oapp.component';
104
+ export { LaunchOAPPComponent } from './components/oapp/launch-oapp.component';
105
+ export { ManageOAPPComponent } from './components/oapp/manage-oapp.component';
106
+ export { SearchOAPPComponent } from './components/oapp/search-oapp.component';
107
+
108
+ // ── Provider popup sub-components ─────────────────────────────────────────────
109
+ export { ActivityPubComponent } from './components/provider/activity-pub.component';
110
+ export { CompareProviderSpeedsComponent } from './components/provider/compare-provider-speeds.component';
111
+ export { EosioComponent } from './components/provider/eosio.component';
112
+ export { EthereumComponent } from './components/provider/ethereum.component';
113
+ export { HolochainComponent } from './components/provider/holochain.component';
114
+ export { IpfsComponent } from './components/provider/ipfs.component';
115
+ export { ManageAutoFailOverComponent } from './components/provider/manage-auto-fail-over.component';
116
+ export { ManageAutoReplicatonComponent } from './components/provider/manage-auto-replicaton.component';
117
+ export { ManageLoadBalancingComponent } from './components/provider/manage-load-balancing.component';
118
+ export { ManageProvidersComponent } from './components/provider/manage-providers.component';
119
+ export { MongoDbComponent } from './components/provider/mongo-db.component';
120
+ export { Neo4jComponent } from './components/provider/neo4j.component';
121
+ export { SearchProvidersComponent } from './components/provider/search-providers.component';
122
+ export { SeedsProviderComponent } from './components/provider/seeds-provider.component';
123
+ export { SolidComponent } from './components/provider/solid.component';
124
+ export { SqlLiteComponent } from './components/provider/sql-lite.component';
125
+ export { ThreeFoldComponent } from './components/provider/three-fold.component';
126
+ export { ViewProvidersComponent } from './components/provider/view-providers.component';
127
+ export { ViewProviderStatsComponent } from './components/provider/view-provider-stats.component';
128
+
129
+ // ── Quest popup sub-components ────────────────────────────────────────────────
130
+ export { QuestComponent } from './components/quest/quest.component';
131
+ export { ManageQuestComponent } from './components/quest/manage-quest.component';
132
+ export { SearchQuestComponent } from './components/quest/search-quest.component';
133
+ export { ViewQuestComponent } from './components/quest/view-quest.component';
134
+
135
+ // ── Seeds popup sub-components ────────────────────────────────────────────────
136
+ export { SeedsComponent } from './components/seeds/seeds.component';
137
+ export { AcceptInviteComponent } from './components/seeds/accept-invite.component';
138
+ export { DonateSeedsComponent } from './components/seeds/donate-seeds.component';
139
+ export { ManageSeedsComponent } from './components/seeds/manage-seeds.component';
140
+ export { PayWithSeedsComponent } from './components/seeds/pay-with-seeds.component';
141
+ export { RewardSeedsComponent } from './components/seeds/reward-seeds.component';
142
+ export { SearchSeedsComponent } from './components/seeds/search-seeds.component';
143
+ export { SendInviteComponent } from './components/seeds/send-invite.component';
144
+ export { ViewOrganizationsComponent } from './components/seeds/view-organizations.component';
145
+ export { ViewSeedsComponent } from './components/seeds/view-seeds.component';