aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/+my-account
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2019-12-18 15:31:54 +0100
committerChocobozzz <me@florianbigard.com>2019-12-18 15:40:59 +0100
commitba430d7516bc5b1324b60571ba7594460969b7fb (patch)
treedf5c6952c82f49a94c0a884bbc97d4a0cbd9f867 /client/src/app/+my-account
parent5dfb7c1dec8222b0bbccac5b56ad46da1438747e (diff)
downloadPeerTube-ba430d7516bc5b1324b60571ba7594460969b7fb.tar.gz
PeerTube-ba430d7516bc5b1324b60571ba7594460969b7fb.tar.zst
PeerTube-ba430d7516bc5b1324b60571ba7594460969b7fb.zip
Lazy load static objects
Diffstat (limited to 'client/src/app/+my-account')
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.ts43
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-interface/my-account-interface-settings.component.ts10
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts10
-rw-r--r--client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts6
-rw-r--r--client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts10
-rw-r--r--client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-create.component.ts13
-rw-r--r--client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-update.component.ts14
-rw-r--r--client/src/app/+my-account/my-account.component.ts16
-rw-r--r--client/src/app/+my-account/shared/actor-avatar-info.component.ts17
9 files changed, 86 insertions, 53 deletions
diff --git a/client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.ts b/client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.ts
index ec7cf935c..9d406805f 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-change-email/my-account-change-email.component.ts
@@ -6,6 +6,7 @@ import { FormValidatorService } from '@app/shared/forms/form-validators/form-val
6import { UserValidatorsService } from '@app/shared/forms/form-validators/user-validators.service' 6import { UserValidatorsService } from '@app/shared/forms/form-validators/user-validators.service'
7import { User } from '../../../../../../shared' 7import { User } from '../../../../../../shared'
8import { tap } from 'rxjs/operators' 8import { tap } from 'rxjs/operators'
9import { forkJoin } from 'rxjs'
9 10
10@Component({ 11@Component({
11 selector: 'my-account-change-email', 12 selector: 'my-account-change-email',
@@ -45,29 +46,29 @@ export class MyAccountChangeEmailComponent extends FormReactive implements OnIni
45 const password = this.form.value[ 'password' ] 46 const password = this.form.value[ 'password' ]
46 const email = this.form.value[ 'new-email' ] 47 const email = this.form.value[ 'new-email' ]
47 48
48 this.userService.changeEmail(password, email) 49 forkJoin([
49 .pipe( 50 this.serverService.getConfig(),
50 tap(() => this.authService.refreshUserInformation()) 51 this.userService.changeEmail(password, email)
51 ) 52 ]).pipe(tap(() => this.authService.refreshUserInformation()))
52 .subscribe( 53 .subscribe(
53 () => { 54 ([ config ]) => {
54 this.form.reset() 55 this.form.reset()
55 56
56 if (this.serverService.getConfig().signup.requiresEmailVerification) { 57 if (config.signup.requiresEmailVerification) {
57 this.success = this.i18n('Please check your emails to verify your new email.') 58 this.success = this.i18n('Please check your emails to verify your new email.')
58 } else { 59 } else {
59 this.success = this.i18n('Email updated.') 60 this.success = this.i18n('Email updated.')
60 } 61 }
61 }, 62 },
62
63 err => {
64 if (err.status === 401) {
65 this.error = this.i18n('You current password is invalid.')
66 return
67 }
68 63
69 this.error = err.message 64 err => {
65 if (err.status === 401) {
66 this.error = this.i18n('You current password is invalid.')
67 return
70 } 68 }
71 ) 69
70 this.error = err.message
71 }
72 )
72 } 73 }
73} 74}
diff --git a/client/src/app/+my-account/my-account-settings/my-account-interface/my-account-interface-settings.component.ts b/client/src/app/+my-account/my-account-settings/my-account-interface/my-account-interface-settings.component.ts
index 5ec1c9f8f..441f89f10 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-interface/my-account-interface-settings.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-interface/my-account-interface-settings.component.ts
@@ -1,6 +1,6 @@
1import { Component, Input, OnInit } from '@angular/core' 1import { Component, Input, OnInit } from '@angular/core'
2import { Notifier, ServerService } from '@app/core' 2import { Notifier, ServerService } from '@app/core'
3import { UserUpdateMe } from '../../../../../../shared' 3import { ServerConfig, UserUpdateMe } from '../../../../../../shared'
4import { AuthService } from '../../../core' 4import { AuthService } from '../../../core'
5import { FormReactive, User, UserService } from '../../../shared' 5import { FormReactive, User, UserService } from '../../../shared'
6import { I18n } from '@ngx-translate/i18n-polyfill' 6import { I18n } from '@ngx-translate/i18n-polyfill'
@@ -16,6 +16,8 @@ export class MyAccountInterfaceSettingsComponent extends FormReactive implements
16 @Input() user: User = null 16 @Input() user: User = null
17 @Input() userInformationLoaded: Subject<any> 17 @Input() userInformationLoaded: Subject<any>
18 18
19 private serverConfig: ServerConfig
20
19 constructor ( 21 constructor (
20 protected formValidatorService: FormValidatorService, 22 protected formValidatorService: FormValidatorService,
21 private authService: AuthService, 23 private authService: AuthService,
@@ -28,11 +30,15 @@ export class MyAccountInterfaceSettingsComponent extends FormReactive implements
28 } 30 }
29 31
30 get availableThemes () { 32 get availableThemes () {
31 return this.serverService.getConfig().theme.registered 33 return this.serverConfig.theme.registered
32 .map(t => t.name) 34 .map(t => t.name)
33 } 35 }
34 36
35 ngOnInit () { 37 ngOnInit () {
38 this.serverConfig = this.serverService.getTmpConfig()
39 this.serverService.getConfig()
40 .subscribe(config => this.serverConfig = config)
41
36 this.buildForm({ 42 this.buildForm({
37 theme: null 43 theme: null
38 }) 44 })
diff --git a/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts
index 76fabb19d..6ba1a1020 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-notification-preferences/my-account-notification-preferences.component.ts
@@ -21,7 +21,7 @@ export class MyAccountNotificationPreferencesComponent implements OnInit {
21 webNotifications: { [ id in keyof UserNotificationSetting ]: boolean } = {} as any 21 webNotifications: { [ id in keyof UserNotificationSetting ]: boolean } = {} as any
22 labelNotifications: { [ id in keyof UserNotificationSetting ]: string } = {} as any 22 labelNotifications: { [ id in keyof UserNotificationSetting ]: string } = {} as any
23 rightNotifications: { [ id in keyof Partial<UserNotificationSetting> ]: UserRight } = {} as any 23 rightNotifications: { [ id in keyof Partial<UserNotificationSetting> ]: UserRight } = {} as any
24 emailEnabled: boolean 24 emailEnabled = false
25 25
26 private savePreferences = debounce(this.savePreferencesImpl.bind(this), 500) 26 private savePreferences = debounce(this.savePreferencesImpl.bind(this), 500)
27 27
@@ -31,7 +31,6 @@ export class MyAccountNotificationPreferencesComponent implements OnInit {
31 private serverService: ServerService, 31 private serverService: ServerService,
32 private notifier: Notifier 32 private notifier: Notifier
33 ) { 33 ) {
34
35 this.labelNotifications = { 34 this.labelNotifications = {
36 newVideoFromSubscription: this.i18n('New video from your subscriptions'), 35 newVideoFromSubscription: this.i18n('New video from your subscriptions'),
37 newCommentOnMyVideo: this.i18n('New comment on your video'), 36 newCommentOnMyVideo: this.i18n('New comment on your video'),
@@ -55,11 +54,14 @@ export class MyAccountNotificationPreferencesComponent implements OnInit {
55 newInstanceFollower: UserRight.MANAGE_SERVER_FOLLOW, 54 newInstanceFollower: UserRight.MANAGE_SERVER_FOLLOW,
56 autoInstanceFollowing: UserRight.MANAGE_CONFIGURATION 55 autoInstanceFollowing: UserRight.MANAGE_CONFIGURATION
57 } 56 }
58
59 this.emailEnabled = this.serverService.getConfig().email.enabled
60 } 57 }
61 58
62 ngOnInit () { 59 ngOnInit () {
60 this.serverService.getConfig()
61 .subscribe(config => {
62 this.emailEnabled = config.email.enabled
63 })
64
63 this.userInformationLoaded.subscribe(() => this.loadNotificationSettings()) 65 this.userInformationLoaded.subscribe(() => this.loadNotificationSettings())
64 } 66 }
65 67
diff --git a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts
index 99eee23b8..a66159b3f 100644
--- a/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts
+++ b/client/src/app/+my-account/my-account-settings/my-account-video-settings/my-account-video-settings.component.ts
@@ -41,11 +41,9 @@ export class MyAccountVideoSettingsComponent extends FormReactive implements OnI
41 }) 41 })
42 42
43 forkJoin([ 43 forkJoin([
44 this.serverService.videoLanguagesLoaded.pipe(first()), 44 this.serverService.getVideoLanguages(),
45 this.userInformationLoaded.pipe(first()) 45 this.userInformationLoaded.pipe(first())
46 ]).subscribe(() => { 46 ]).subscribe(([ languages ]) => {
47 const languages = this.serverService.getVideoLanguages()
48
49 this.languageItems = [ { label: this.i18n('Unknown language'), value: '_unknown' } ] 47 this.languageItems = [ { label: this.i18n('Unknown language'), value: '_unknown' } ]
50 this.languageItems = this.languageItems 48 this.languageItems = this.languageItems
51 .concat(languages.map(l => ({ label: l.label, value: l.id }))) 49 .concat(languages.map(l => ({ label: l.label, value: l.id })))
diff --git a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts
index 081e956d2..9c948b367 100644
--- a/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts
+++ b/client/src/app/+my-account/my-account-video-channels/my-account-video-channel-update.component.ts
@@ -9,6 +9,7 @@ import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
9import { I18n } from '@ngx-translate/i18n-polyfill' 9import { I18n } from '@ngx-translate/i18n-polyfill'
10import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 10import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
11import { VideoChannelValidatorsService } from '@app/shared/forms/form-validators/video-channel-validators.service' 11import { VideoChannelValidatorsService } from '@app/shared/forms/form-validators/video-channel-validators.service'
12import { ServerConfig } from '@shared/models'
12 13
13@Component({ 14@Component({
14 selector: 'my-account-video-channel-update', 15 selector: 'my-account-video-channel-update',
@@ -21,6 +22,7 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE
21 22
22 private paramsSub: Subscription 23 private paramsSub: Subscription
23 private oldSupportField: string 24 private oldSupportField: string
25 private serverConfig: ServerConfig
24 26
25 constructor ( 27 constructor (
26 protected formValidatorService: FormValidatorService, 28 protected formValidatorService: FormValidatorService,
@@ -37,6 +39,10 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE
37 } 39 }
38 40
39 ngOnInit () { 41 ngOnInit () {
42 this.serverConfig = this.serverService.getTmpConfig()
43 this.serverService.getConfig()
44 .subscribe(config => this.serverConfig = config)
45
40 this.buildForm({ 46 this.buildForm({
41 'display-name': this.videoChannelValidatorsService.VIDEO_CHANNEL_DISPLAY_NAME, 47 'display-name': this.videoChannelValidatorsService.VIDEO_CHANNEL_DISPLAY_NAME,
42 description: this.videoChannelValidatorsService.VIDEO_CHANNEL_DESCRIPTION, 48 description: this.videoChannelValidatorsService.VIDEO_CHANNEL_DESCRIPTION,
@@ -109,11 +115,11 @@ export class MyAccountVideoChannelUpdateComponent extends MyAccountVideoChannelE
109 } 115 }
110 116
111 get maxAvatarSize () { 117 get maxAvatarSize () {
112 return this.serverService.getConfig().avatar.file.size.max 118 return this.serverConfig.avatar.file.size.max
113 } 119 }
114 120
115 get avatarExtensions () { 121 get avatarExtensions () {
116 return this.serverService.getConfig().avatar.file.extensions.join(',') 122 return this.serverConfig.avatar.file.extensions.join(',')
117 } 123 }
118 124
119 isCreation () { 125 isCreation () {
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-create.component.ts b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-create.component.ts
index 8aed8b513..e47e5f980 100644
--- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-create.component.ts
+++ b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-create.component.ts
@@ -47,15 +47,14 @@ export class MyAccountVideoPlaylistCreateComponent extends MyAccountVideoPlaylis
47 populateAsyncUserVideoChannels(this.authService, this.userVideoChannels) 47 populateAsyncUserVideoChannels(this.authService, this.userVideoChannels)
48 .catch(err => console.error('Cannot populate user video channels.', err)) 48 .catch(err => console.error('Cannot populate user video channels.', err))
49 49
50 this.serverService.videoPlaylistPrivaciesLoaded.subscribe( 50 this.serverService.getVideoPlaylistPrivacies()
51 () => { 51 .subscribe(videoPlaylistPrivacies => {
52 this.videoPlaylistPrivacies = this.serverService.getVideoPlaylistPrivacies() 52 this.videoPlaylistPrivacies = videoPlaylistPrivacies
53 53
54 this.form.patchValue({ 54 this.form.patchValue({
55 privacy: VideoPlaylistPrivacy.PRIVATE 55 privacy: VideoPlaylistPrivacy.PRIVATE
56 })
56 }) 57 })
57 }
58 )
59 } 58 }
60 59
61 formValidated () { 60 formValidated () {
diff --git a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-update.component.ts b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-update.component.ts
index 917ad7258..2f85cdd96 100644
--- a/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-update.component.ts
+++ b/client/src/app/+my-account/my-account-video-playlists/my-account-video-playlist-update.component.ts
@@ -1,7 +1,7 @@
1import { Component, OnDestroy, OnInit } from '@angular/core' 1import { Component, OnDestroy, OnInit } from '@angular/core'
2import { ActivatedRoute, Router } from '@angular/router' 2import { ActivatedRoute, Router } from '@angular/router'
3import { AuthService, Notifier, ServerService } from '@app/core' 3import { AuthService, Notifier, ServerService } from '@app/core'
4import { Subscription } from 'rxjs' 4import { forkJoin, Subscription } from 'rxjs'
5import { I18n } from '@ngx-translate/i18n-polyfill' 5import { I18n } from '@ngx-translate/i18n-polyfill'
6import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service' 6import { FormValidatorService } from '@app/shared/forms/form-validators/form-validator.service'
7import { MyAccountVideoPlaylistEdit } from '@app/+my-account/my-account-video-playlists/my-account-video-playlist-edit' 7import { MyAccountVideoPlaylistEdit } from '@app/+my-account/my-account-video-playlists/my-account-video-playlist-edit'
@@ -56,13 +56,17 @@ export class MyAccountVideoPlaylistUpdateComponent extends MyAccountVideoPlaylis
56 this.paramsSub = this.route.params 56 this.paramsSub = this.route.params
57 .pipe( 57 .pipe(
58 map(routeParams => routeParams['videoPlaylistId']), 58 map(routeParams => routeParams['videoPlaylistId']),
59 switchMap(videoPlaylistId => this.videoPlaylistService.getVideoPlaylist(videoPlaylistId)), 59 switchMap(videoPlaylistId => {
60 delayWhen(() => this.serverService.videoPlaylistPrivaciesLoaded) 60 return forkJoin([
61 this.videoPlaylistService.getVideoPlaylist(videoPlaylistId),
62 this.serverService.getVideoPlaylistPrivacies()
63 ])
64 })
61 ) 65 )
62 .subscribe( 66 .subscribe(
63 videoPlaylistToUpdate => { 67 ([ videoPlaylistToUpdate, videoPlaylistPrivacies]) => {
64 this.videoPlaylistPrivacies = this.serverService.getVideoPlaylistPrivacies()
65 this.videoPlaylistToUpdate = videoPlaylistToUpdate 68 this.videoPlaylistToUpdate = videoPlaylistToUpdate
69 this.videoPlaylistPrivacies = videoPlaylistPrivacies
66 70
67 this.hydrateFormFromPlaylist() 71 this.hydrateFormFromPlaylist()
68 }, 72 },
diff --git a/client/src/app/+my-account/my-account.component.ts b/client/src/app/+my-account/my-account.component.ts
index d98d06f8e..05dcf522d 100644
--- a/client/src/app/+my-account/my-account.component.ts
+++ b/client/src/app/+my-account/my-account.component.ts
@@ -1,20 +1,28 @@
1import { Component } from '@angular/core' 1import { Component, OnInit } from '@angular/core'
2import { ServerService } from '@app/core' 2import { ServerService } from '@app/core'
3import { I18n } from '@ngx-translate/i18n-polyfill' 3import { I18n } from '@ngx-translate/i18n-polyfill'
4import { TopMenuDropdownParam } from '@app/shared/menu/top-menu-dropdown.component' 4import { TopMenuDropdownParam } from '@app/shared/menu/top-menu-dropdown.component'
5import { ServerConfig } from '@shared/models'
5 6
6@Component({ 7@Component({
7 selector: 'my-my-account', 8 selector: 'my-my-account',
8 templateUrl: './my-account.component.html', 9 templateUrl: './my-account.component.html',
9 styleUrls: [ './my-account.component.scss' ] 10 styleUrls: [ './my-account.component.scss' ]
10}) 11})
11export class MyAccountComponent { 12export class MyAccountComponent implements OnInit {
12 menuEntries: TopMenuDropdownParam[] = [] 13 menuEntries: TopMenuDropdownParam[] = []
13 14
15 private serverConfig: ServerConfig
16
14 constructor ( 17 constructor (
15 private serverService: ServerService, 18 private serverService: ServerService,
16 private i18n: I18n 19 private i18n: I18n
17 ) { 20 ) { }
21
22 ngOnInit (): void {
23 this.serverConfig = this.serverService.getTmpConfig()
24 this.serverService.getConfig()
25 .subscribe(config => this.serverConfig = config)
18 26
19 const libraryEntries: TopMenuDropdownParam = { 27 const libraryEntries: TopMenuDropdownParam = {
20 label: this.i18n('My library'), 28 label: this.i18n('My library'),
@@ -91,7 +99,7 @@ export class MyAccountComponent {
91 } 99 }
92 100
93 isVideoImportEnabled () { 101 isVideoImportEnabled () {
94 const importConfig = this.serverService.getConfig().import.videos 102 const importConfig = this.serverConfig.import.videos
95 103
96 return importConfig.http.enabled || importConfig.torrent.enabled 104 return importConfig.http.enabled || importConfig.torrent.enabled
97 } 105 }
diff --git a/client/src/app/+my-account/shared/actor-avatar-info.component.ts b/client/src/app/+my-account/shared/actor-avatar-info.component.ts
index 0289a66c3..101dfa556 100644
--- a/client/src/app/+my-account/shared/actor-avatar-info.component.ts
+++ b/client/src/app/+my-account/shared/actor-avatar-info.component.ts
@@ -1,26 +1,35 @@
1import { Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core' 1import { Component, ElementRef, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core'
2import { ServerService } from '../../core/server' 2import { ServerService } from '../../core/server'
3import { VideoChannel } from '@app/shared/video-channel/video-channel.model' 3import { VideoChannel } from '@app/shared/video-channel/video-channel.model'
4import { Account } from '@app/shared/account/account.model' 4import { Account } from '@app/shared/account/account.model'
5import { Notifier } from '@app/core' 5import { Notifier } from '@app/core'
6import { ServerConfig } from '@shared/models'
6 7
7@Component({ 8@Component({
8 selector: 'my-actor-avatar-info', 9 selector: 'my-actor-avatar-info',
9 templateUrl: './actor-avatar-info.component.html', 10 templateUrl: './actor-avatar-info.component.html',
10 styleUrls: [ './actor-avatar-info.component.scss' ] 11 styleUrls: [ './actor-avatar-info.component.scss' ]
11}) 12})
12export class ActorAvatarInfoComponent { 13export class ActorAvatarInfoComponent implements OnInit {
13 @ViewChild('avatarfileInput', { static: false }) avatarfileInput: ElementRef<HTMLInputElement> 14 @ViewChild('avatarfileInput', { static: false }) avatarfileInput: ElementRef<HTMLInputElement>
14 15
15 @Input() actor: VideoChannel | Account 16 @Input() actor: VideoChannel | Account
16 17
17 @Output() avatarChange = new EventEmitter<FormData>() 18 @Output() avatarChange = new EventEmitter<FormData>()
18 19
20 private serverConfig: ServerConfig
21
19 constructor ( 22 constructor (
20 private serverService: ServerService, 23 private serverService: ServerService,
21 private notifier: Notifier 24 private notifier: Notifier
22 ) {} 25 ) {}
23 26
27 ngOnInit (): void {
28 this.serverConfig = this.serverService.getTmpConfig()
29 this.serverService.getConfig()
30 .subscribe(config => this.serverConfig = config)
31 }
32
24 onAvatarChange () { 33 onAvatarChange () {
25 const avatarfile = this.avatarfileInput.nativeElement.files[ 0 ] 34 const avatarfile = this.avatarfileInput.nativeElement.files[ 0 ]
26 if (avatarfile.size > this.maxAvatarSize) { 35 if (avatarfile.size > this.maxAvatarSize) {
@@ -35,10 +44,10 @@ export class ActorAvatarInfoComponent {
35 } 44 }
36 45
37 get maxAvatarSize () { 46 get maxAvatarSize () {
38 return this.serverService.getConfig().avatar.file.size.max 47 return this.serverConfig.avatar.file.size.max
39 } 48 }
40 49
41 get avatarExtensions () { 50 get avatarExtensions () {
42 return this.serverService.getConfig().avatar.file.extensions.join(',') 51 return this.serverConfig.avatar.file.extensions.join(',')
43 } 52 }
44} 53}