alimetry-detail-edit 1.0.0 → 1.2.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.
- package/README.md +8 -4
- package/esm2020/lib/detail-edit.component.mjs +68 -55
- package/esm2020/lib/utils.mjs +6 -1
- package/fesm2015/alimetry-detail-edit.mjs +72 -56
- package/fesm2015/alimetry-detail-edit.mjs.map +1 -1
- package/fesm2020/alimetry-detail-edit.mjs +71 -53
- package/fesm2020/alimetry-detail-edit.mjs.map +1 -1
- package/lib/detail-edit.component.d.ts +15 -7
- package/lib/utils.d.ts +8 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alimetry-detail-edit.mjs","sources":["../../../projects/detail-edit/src/lib/detail-edit.service.ts","../../../projects/detail-edit/src/lib/utils.ts","../../../projects/detail-edit/src/lib/validators.ts","../../../projects/detail-edit/src/lib/entries.pipe.ts","../../../projects/detail-edit/src/lib/detail-edit.component.ts","../../../projects/detail-edit/src/lib/detail-edit.component.html","../../../projects/detail-edit/src/lib/detail-edit.module.ts","../../../projects/detail-edit/src/public-api.ts","../../../projects/detail-edit/src/alimetry-detail-edit.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class DetailEditService {\n\n constructor() { }\n}\n","// strip the timezone offset to create format usable by <input>\nexport function localiseDateTime(datetime: string) {\n const date = new Date(datetime);\n\n const year = date.getFullYear(); const month = (date.getMonth() + 1).toString().padStart(2, '0');\n const day = date.getDate().toString().padStart(2, '0');\n const hour = date.getHours().toString().padStart(2, '0');\n const minute = date.getMinutes().toString().padStart(2, '0');\n const second = date.getSeconds().toString().padStart(2, '0');\n\n return `${year}-${month}-${day}T${hour}:${minute}:${second}`;\n}\n\n// reconstruct original ISO format\nexport function globaliseDateTime(datetime: string) {\n const date = new Date(datetime);\n\n const offset = -date.getTimezoneOffset();\n const offsetAbs = Math.abs(offset);\n\n const sign = offset >= 0 ? '+' : '-';\n const hours = String(Math.floor(offsetAbs / 60)).padStart(2, '0');\n const minutes = String(offsetAbs % 60).padStart(2, '0');\n const offsetString = `${sign}${hours}:${minutes}`;\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const hour = String(date.getHours()).padStart(2, '0');\n const minute = String(date.getMinutes()).padStart(2, '0');\n const second = String(date.getSeconds()).padStart(2, '0');\n\n const datePart = `${year}-${month}-${day}`;\n const timePart = `${hour}:${minute}:${second}.000`;\n\n return `${datePart}T${timePart}${offsetString}`;\n}\n\nexport function getAge(dob: string) {\n const then = new Date(dob);\n const now = new Date();\n\n let age = now.getFullYear() - then.getFullYear();\n\n if (now.getMonth() < then.getMonth() ||\n (now.getMonth() === then.getMonth() && now.getDate() < then.getDate())) {\n age--;\n }\n\n return age;\n}\n\nexport function titleise(camel: string) {\n let spaced = camel.replace(/(?=[A-Z])/g, ' ');\n return spaced.toLowerCase().replace(/\\b\\w/g, ch => ch.toUpperCase());\n}\n\nexport function shallowCompare(a: object, b: object) {\n return Object.entries(a).every(([k, v]) => b[k] === v);\n}\n","import { AbstractControl, FormControl, FormGroup, ValidationErrors, ValidatorFn } from \"@angular/forms\";\nimport { titleise } from \"./utils\";\n\nfunction setControlError(control: AbstractControl, errorKey: string, errorValue: any) {\n const currentErrors = control.errors || {};\n if (currentErrors[errorKey]) return;\n control.setErrors({ ...currentErrors, [errorKey]: errorValue });\n}\n\nfunction clearControlError(control: AbstractControl, errorKey: string) {\n const currentErrors = control.errors || {};\n if (!currentErrors[errorKey]) return;\n control.setErrors({ ...currentErrors, [errorKey]: null });\n}\n\nexport function dateComparison(a: string, b: string, comparator: 'before' | 'after') {\n return function(control: AbstractControl<any, any>): ValidationErrors | null {\n if (!(control instanceof FormGroup)) return null;\n\n const formGroup = control as FormGroup;\n\n const aControl = formGroup.get(a);\n const bControl = formGroup.get(b);\n\n if (!aControl?.value || !bControl?.value) {\n clearControlError(aControl, 'dateRange');\n return null;\n }\n\n const aDate = new Date(aControl.value);\n const bDate = new Date(bControl.value);\n\n const hasError = (\n comparator === 'after' && aDate <= bDate ||\n comparator === 'before' && aDate >= bDate\n );\n\n if (hasError) {\n setControlError(aControl, 'dateRange', { against: b, comparator });\n return { dateRange: true };\n }\n\n clearControlError(aControl, 'dateRange');\n return null;\n }\n}\n\nexport function withinNYears(n: number, dir: 'both' | 'before' | 'after' = 'both', of?: Date): ValidatorFn {\n return function(control: AbstractControl): ValidationErrors | null {\n const timestamp = control?.value;\n if (!timestamp || isNaN(new Date(timestamp).getTime())) return null;\n\n const date = new Date(timestamp);\n const against = of ?? new Date();\n\n const min = new Date(against)\n min.setFullYear(against.getFullYear() - n);\n const max = new Date(against)\n max.setFullYear(against.getFullYear() + n);\n\n let isValid = false;\n if (dir === 'after') isValid = date < max && date > against;\n else if (dir === 'before') isValid = date > min && date < against;\n else isValid = date > min && date < max;\n\n return isValid ? null : { notWithinYears: { n, against, dir } };\n }\n}\n\nexport function withinNHours(n: number, dir: 'both' | 'before' | 'after' = 'both', of?: Date): ValidatorFn {\n return function(control: AbstractControl): ValidationErrors | null {\n const timestamp = control?.value;\n if (!timestamp || isNaN(new Date(timestamp).getTime())) return null;\n\n const date = new Date(timestamp);\n const against = of ?? new Date();\n\n const min = new Date(against)\n min.setHours(against.getHours() - n);\n const max = new Date(against)\n max.setHours(against.getHours() + n);\n\n let isValid = false;\n if (dir === 'after') isValid = date < max && date > against;\n else if (dir === 'before') isValid = date > min && date < against;\n else isValid = date > min && date < max;\n\n return isValid ? null : { notWithinHours: { n, against, dir } };\n }\n}\n\n// translate validation errors into human readable strings\nexport function translateError(name: string, control: AbstractControl) {\n const { errors } = control;\n\n if (control.hasError('required'))\n return `${titleise(name)} is a required value.`;\n else if (control.hasError('min'))\n return `${titleise(name)} needs to be a minimum of ${errors.min.min}.`;\n else if (control.hasError('max'))\n return `${titleise(name)} needs to be a maximum of ${errors.max.max}.`;\n else if (control.hasError('future'))\n return `${titleise(name)} needs to be in the past.`;\n else if (control.hasError('dateRange'))\n return `${titleise(name)} needs to be ${errors.dateRange.comparator} ${titleise(errors.dateRange.against)}.`;\n else if (control.hasError('notWithinYears'))\n return `${titleise(name)} needs to be within ${errors.notWithinYears.n} years of ${errors.notWithinYears.against}`;\n else if (control.hasError('notWithinHours'))\n return `${titleise(name)} needs to be within ${errors.notWithinHours.n} hours of ${errors.notWithinHours.against}`;\n\n return null;\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({\n name: 'entries'\n})\nexport class EntriesPipe implements PipeTransform {\n transform(value: object): [string, any][] {\n return Object.entries(value);\n }\n}\n","import { Component, Input } from '@angular/core';\nimport { AbstractControl, FormControl, FormGroup, Validators } from '@angular/forms';\nimport { forkJoin, tap } from 'rxjs';\nimport { Config, SharedService, User } from 'shared';\nimport { getAge, globaliseDateTime, localiseDateTime, shallowCompare } from './utils';\nimport { dateComparison, withinNYears, withinNHours, translateError } from './validators';\n\nconst appDataPropertySetId = '34d46477-ad4b-47b4-b555-06358b92f60c';\nconst deviceDataPropertySetId = '7a32d851-5e89-46a6-a4b6-cca162dace29';\nconst propertyCodes = ['RecordingSession', 'Status', 'UserDetailChangeLog'];\n\n@Component({\n selector: 'lib-detail-edit', templateUrl: './detail-edit.component.html',\n styleUrls: ['./detail-edit.component.css']\n})\nexport class DetailEditComponent {\n @Input() config!: Config;\n\n status: 'error' | 'loading' | 'success' | 'generating' | 'sending' | 'nouser' = 'loading';\n\n // populated by load request\n private deviceDataId: string;\n private recordingSession: object;\n private recordingStart: string;\n private initialFormState: object;\n private detailChangeLog: object[];\n private currentUser: User;\n private owner: User;\n\n formGroup = new FormGroup({\n dob: new FormControl<string>('', [Validators.required, withinNYears(120, 'before')]),\n height: new FormControl<number>(0, [Validators.required, Validators.min(30), Validators.max(272)]),\n weight: new FormControl<number>(0, [Validators.required, Validators.min(1), Validators.max(635)]),\n mealStart: new FormControl<string>('', [Validators.required]),\n mealEnd: new FormControl<string>('', [Validators.required])\n }, [\n dateComparison('mealEnd', 'mealStart', 'after'),\n dateComparison('mealStart', 'dob', 'after'),\n ]);\n\n constructor(private shared: SharedService) { }\n\n parseInputErrors(name: string, control: AbstractControl) {\n return translateError(name, control);\n }\n\n // make sure than modifications that don't actually differ from the current are marked as such\n private monitorFormChanges() {\n this.formGroup.valueChanges.subscribe(current => {\n if (shallowCompare(current, this.initialFormState)) {\n this.formGroup.markAsPristine();\n }\n })\n }\n\n // handle the relevant data from the response body\n private extractFields(recordingSession: Record<string, any>) {\n const { patient, mealStart, mealEnd, recordingStart } = recordingSession;\n this.recordingStart = recordingStart;\n\n return {\n dob: this.owner.dateOfBirth,\n height: patient.height,\n weight: patient.weight,\n mealStart: localiseDateTime(mealStart),\n mealEnd: localiseDateTime(mealEnd)\n }\n }\n\n private initialiseForm(state: object) {\n this.formGroup.patchValue(state);\n this.formGroup.markAsPristine();\n\n this.formGroup.get('mealStart').addValidators(withinNHours(24, 'after', new Date(this.recordingStart)));\n this.formGroup.get('mealEnd').addValidators(withinNHours(24, 'after', new Date(this.recordingStart)));\n\n this.initialFormState = state; // save this for use in resets\n this.monitorFormChanges();\n }\n\n // construct a patch object for the save request\n private integrateFields(mods: typeof this.formGroup.value, recordingSession: Record<string, any>) {\n const { patient } = recordingSession;\n patient.height = mods.height;\n patient.weight = mods.weight;\n patient.age = getAge(mods.dob);\n\n recordingSession.mealStart = globaliseDateTime(mods.mealStart);\n recordingSession.mealEnd = globaliseDateTime(mods.mealEnd);\n\n this.appendChangeLog(mods);\n\n return {\n 'Age': patient.age,\n 'RecordingSession': JSON.stringify(recordingSession),\n 'UserDetailChangeLog': this.detailChangeLog\n }\n }\n\n private postDeviceData(devicePropertySetId: string, data: object) {\n return this.shared.saveDeviceData(\n this.config.deviceDataModelId,\n this.deviceDataId,\n devicePropertySetId,\n this.config.owners[0].userId,\n data\n );\n }\n\n // patch the device data record with the modifications\n saveModifications() {\n const mods = this.formGroup.getRawValue();\n const patchedDeviceData = this.integrateFields(mods, this.recordingSession);\n const patchedUserData = Object.assign(this.config.owners[0], { dateOfBirth: mods.dob });\n\n this.status = 'sending';\n forkJoin([\n this.postDeviceData(appDataPropertySetId, patchedDeviceData),\n this.shared.updateUser(this.config.owners[0].userId, patchedUserData)\n ]).pipe(\n tap(() => this.regenReport())\n ).subscribe();\n }\n\n private appendChangeLog(mods: typeof this.formGroup.value) {\n const prevChangeLog: Partial<typeof this.formGroup.value> = {};\n const newChangeLog: Partial<typeof this.formGroup.value> = {};\n\n // Only include fields that have changed\n for (const key in mods) {\n if (this.initialFormState[key] !== mods[key]) {\n prevChangeLog[key] = this.initialFormState[key];\n newChangeLog[key] = mods[key];\n }\n }\n\n const changeLog = {\n author: this.currentUser.emailAddress,\n prevChangeLog: prevChangeLog,\n newChangeLog: newChangeLog,\n timestamp: new Date().toISOString()\n }\n\n this.detailChangeLog.push(changeLog);\n }\n\n // get the device data record and initialise the form\n private loadDeviceData() {\n this.shared.getDeviceData(\n this.config.deviceDataModelId,\n this.config.owners[0].userId,\n propertyCodes\n ).subscribe({\n next: (res) => {\n this.deviceDataId = res.deviceDataId;\n this.recordingSession = JSON.parse(res.data['RecordingSession'].value);\n this.initialiseForm(this.extractFields(this.recordingSession));\n // checking for undefined in case no changes have been logged yet\n this.detailChangeLog = res.data['UserDetailChangeLog'] === undefined ? [] : res.data['UserDetailChangeLog'].value;\n\n this.status = res.data['Status']?.value === 'Generating Report' ?\n 'generating' :\n 'success';\n },\n error: (err) => {\n console.error(err);\n this.status = \"error\";\n }\n });\n }\n\n regenReport() {\n this.postDeviceData(\n deviceDataPropertySetId,\n { 'Algorithmhasrun': false, 'AlgorithmRun': true }\n ).subscribe(() => {\n this.status = 'generating'; // assume report starts generating immediately\n })\n }\n\n resetModifications() {\n this.formGroup.patchValue(this.initialFormState);\n }\n\n ngOnInit() {\n if (!this.config?.owners?.[0]?.userId) {\n this.status = 'nouser';\n return;\n }\n this.shared.getUser(this.config.currentUser.userId).subscribe(user => {\n this.currentUser = user;\n });\n\n this.shared.getUser(this.config.owners[0].userId).subscribe(owner => {\n this.owner = owner;\n });\n\n this.loadDeviceData();\n }\n}\n","<div class=\"wrapper\">\n <div class=\"status\" *ngIf=\"status === 'error'\">\n An error occured while trying to get the details.\n </div>\n <div class=\"status\" *ngIf=\"status === 'nouser'\">\n There is no user specified as the data owner.\n </div>\n <form *ngIf=\"status !== 'error' && status !== 'nouser'\" [formGroup]=\"formGroup\" (ngSubmit)=\"saveModifications()\">\n <div class=\"inputs\">\n <div class=\"form-row\">\n <label for=\"dob\">Date of Birth:</label>\n <input id=\"dob\" type=\"date\" formControlName=\"dob\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"weight\">Patient Weight (kg):</label>\n <input id=\"weight\" type=\"number\" formControlName=\"weight\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"height\">Patient Height (cm):</label>\n <input id=\"height\" type=\"number\" formControlName=\"height\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"mealStart\">Meal Start Time:</label>\n <input id=\"mealStart\" type=\"datetime-local\" formControlName=\"mealStart\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"mealEnd\">Meal End Time:</label>\n <input id=\"mealEnd\" type=\"datetime-local\" formControlName=\"mealEnd\">\n </div>\n </div>\n\n <div *ngIf=\"!formGroup.valid && formGroup.dirty\" class=\"errors\">\n <div *ngFor=\"let control of formGroup.controls | entries\">\n {{ parseInputErrors(control[0], control[1]) }}\n </div>\n </div>\n\n <div *ngIf=\"status === 'generating'\" class=\"info\">\n <div>The report is generating at the moment, check back later if you need to modify this entry.</div>\n </div>\n\n <div class=\"buttons\">\n <button type=\"button\" (click)=\"regenReport()\" [disabled]=\"status === 'sending' || status === 'generating' || status === 'loading'\">Regenerate Report</button>\n <button type=\"button\" (click)=\"resetModifications()\" [disabled]=\"status === 'sending' || status === 'generating' || formGroup.pristine\">Cancel Modification</button>\n <button type=\"submit\" [disabled]=\"status === 'sending' || status === 'generating' || !formGroup.valid || formGroup.pristine\">Save Details</button>\n </div>\n </form>\n</div>\n","import { CommonModule, JsonPipe } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { DetailEditComponent } from './detail-edit.component';\nimport { EntriesPipe } from './entries.pipe';\n\n\n\n@NgModule({\n declarations: [\n DetailEditComponent,\n EntriesPipe\n ],\n imports: [\n JsonPipe,\n ReactiveFormsModule,\n CommonModule\n ],\n exports: [\n DetailEditComponent\n ]\n})\nexport class DetailEditModule { }\n","/*\n * Public API Surface of detail-edit\n */\n\nexport * from './lib/detail-edit.service';\nexport * from './lib/detail-edit.component';\nexport * from './lib/detail-edit.module';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i4.EntriesPipe"],"mappings":";;;;;;;;;MAKa,iBAAiB,CAAA;AAE5B,IAAA,WAAA,GAAA,GAAiB;;+GAFN,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAjB,iBAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,iBAAiB,cAFhB,MAAM,EAAA,CAAA,CAAA;4FAEP,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAH7B,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;iBACnB,CAAA;;;ACJD;AACM,SAAU,gBAAgB,CAAC,QAAgB,EAAA;AAC/C,IAAA,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;AAEhC,IAAA,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAAC,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACjG,IAAA,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACvD,IAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACzD,IAAA,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC7D,IAAA,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAE7D,IAAA,OAAO,CAAG,EAAA,IAAI,CAAI,CAAA,EAAA,KAAK,CAAI,CAAA,EAAA,GAAG,CAAI,CAAA,EAAA,IAAI,CAAI,CAAA,EAAA,MAAM,CAAI,CAAA,EAAA,MAAM,EAAE,CAAC;AAC/D,CAAC;AAED;AACM,SAAU,iBAAiB,CAAC,QAAgB,EAAA;AAChD,IAAA,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;AAEhC,IAAA,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;IACzC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAEnC,IAAA,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC;IACrC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAClE,IAAA,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACxD,MAAM,YAAY,GAAG,CAAG,EAAA,IAAI,GAAG,KAAK,CAAA,CAAA,EAAI,OAAO,CAAA,CAAE,CAAC;AAClD,IAAA,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;AAChC,IAAA,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC3D,IAAA,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACpD,IAAA,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACtD,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC1D,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAE1D,MAAM,QAAQ,GAAG,CAAG,EAAA,IAAI,IAAI,KAAK,CAAA,CAAA,EAAI,GAAG,CAAA,CAAE,CAAC;IAC3C,MAAM,QAAQ,GAAG,CAAG,EAAA,IAAI,IAAI,MAAM,CAAA,CAAA,EAAI,MAAM,CAAA,IAAA,CAAM,CAAC;AAEnD,IAAA,OAAO,GAAG,QAAQ,CAAA,CAAA,EAAI,QAAQ,CAAG,EAAA,YAAY,EAAE,CAAC;AAClD,CAAC;AAEK,SAAU,MAAM,CAAC,GAAW,EAAA;AAChC,IAAA,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3B,IAAA,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,IAAI,GAAG,GAAG,GAAG,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAEjD,IAAI,GAAG,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE;SACjC,GAAG,CAAC,QAAQ,EAAE,KAAK,IAAI,CAAC,QAAQ,EAAE,IAAI,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;AACxE,QAAA,GAAG,EAAE,CAAC;AACP,KAAA;AAED,IAAA,OAAO,GAAG,CAAC;AACb,CAAC;AAEK,SAAU,QAAQ,CAAC,KAAa,EAAA;IACpC,IAAI,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;AAC9C,IAAA,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;AACvE,CAAC;AAEe,SAAA,cAAc,CAAC,CAAS,EAAE,CAAS,EAAA;IACjD,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AACzD;;ACvDA,SAAS,eAAe,CAAC,OAAwB,EAAE,QAAgB,EAAE,UAAe,EAAA;AAClF,IAAA,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;IAC3C,IAAI,aAAa,CAAC,QAAQ,CAAC;QAAE,OAAO;IACpC,OAAO,CAAC,SAAS,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAAM,aAAa,CAAA,EAAA,EAAE,CAAC,QAAQ,GAAG,UAAU,EAAA,CAAA,CAAG,CAAC;AAClE,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAwB,EAAE,QAAgB,EAAA;AACnE,IAAA,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;AAC3C,IAAA,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC;QAAE,OAAO;IACrC,OAAO,CAAC,SAAS,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAAM,aAAa,CAAA,EAAA,EAAE,CAAC,QAAQ,GAAG,IAAI,EAAA,CAAA,CAAG,CAAC;AAC5D,CAAC;SAEe,cAAc,CAAC,CAAS,EAAE,CAAS,EAAE,UAA8B,EAAA;AACjF,IAAA,OAAO,UAAS,OAAkC,EAAA;AAChD,QAAA,IAAI,EAAE,OAAO,YAAY,SAAS,CAAC;AAAE,YAAA,OAAO,IAAI,CAAC;QAEjD,MAAM,SAAS,GAAG,OAAoB,CAAC;QAEvC,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAElC,IAAI,EAAC,QAAQ,KAAA,IAAA,IAAR,QAAQ,KAAR,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,QAAQ,CAAE,KAAK,CAAA,IAAI,EAAC,QAAQ,KAAR,IAAA,IAAA,QAAQ,uBAAR,QAAQ,CAAE,KAAK,CAAA,EAAE;AACxC,YAAA,iBAAiB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AACzC,YAAA,OAAO,IAAI,CAAC;AACb,SAAA;QAED,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAEvC,MAAM,QAAQ,IACZ,UAAU,KAAK,OAAO,IAAI,KAAK,IAAI,KAAK;AACxC,YAAA,UAAU,KAAK,QAAQ,IAAI,KAAK,IAAI,KAAK,CAC1C,CAAC;AAEF,QAAA,IAAI,QAAQ,EAAE;AACZ,YAAA,eAAe,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;AACnE,YAAA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAC5B,SAAA;AAED,QAAA,iBAAiB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AACzC,QAAA,OAAO,IAAI,CAAC;AACd,KAAC,CAAA;AACH,CAAC;AAEK,SAAU,YAAY,CAAC,CAAS,EAAE,GAAmC,GAAA,MAAM,EAAE,EAAS,EAAA;AAC1F,IAAA,OAAO,UAAS,OAAwB,EAAA;QACtC,MAAM,SAAS,GAAG,OAAO,KAAA,IAAA,IAAP,OAAO,KAAP,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,OAAO,CAAE,KAAK,CAAC;AACjC,QAAA,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;AAAE,YAAA,OAAO,IAAI,CAAC;AAEpE,QAAA,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,EAAE,KAAF,IAAA,IAAA,EAAE,KAAF,KAAA,CAAA,GAAA,EAAE,GAAI,IAAI,IAAI,EAAE,CAAC;AAEjC,QAAA,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAA;QAC7B,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC;AAC3C,QAAA,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAA;QAC7B,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC;QAE3C,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,GAAG,KAAK,OAAO;YAAE,OAAO,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI,GAAG,OAAO,CAAC;aACvD,IAAI,GAAG,KAAK,QAAQ;YAAE,OAAO,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI,GAAG,OAAO,CAAC;;YAC7D,OAAO,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI,GAAG,GAAG,CAAC;AAExC,QAAA,OAAO,OAAO,GAAG,IAAI,GAAG,EAAE,cAAc,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;AAClE,KAAC,CAAA;AACH,CAAC;AAEK,SAAU,YAAY,CAAC,CAAS,EAAE,GAAmC,GAAA,MAAM,EAAE,EAAS,EAAA;AAC1F,IAAA,OAAO,UAAS,OAAwB,EAAA;QACtC,MAAM,SAAS,GAAG,OAAO,KAAA,IAAA,IAAP,OAAO,KAAP,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,OAAO,CAAE,KAAK,CAAC;AACjC,QAAA,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;AAAE,YAAA,OAAO,IAAI,CAAC;AAEpE,QAAA,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,EAAE,KAAF,IAAA,IAAA,EAAE,KAAF,KAAA,CAAA,GAAA,EAAE,GAAI,IAAI,IAAI,EAAE,CAAC;AAEjC,QAAA,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAA;QAC7B,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC;AACrC,QAAA,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAA;QAC7B,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC;QAErC,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,GAAG,KAAK,OAAO;YAAE,OAAO,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI,GAAG,OAAO,CAAC;aACvD,IAAI,GAAG,KAAK,QAAQ;YAAE,OAAO,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI,GAAG,OAAO,CAAC;;YAC7D,OAAO,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI,GAAG,GAAG,CAAC;AAExC,QAAA,OAAO,OAAO,GAAG,IAAI,GAAG,EAAE,cAAc,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;AAClE,KAAC,CAAA;AACH,CAAC;AAED;AACgB,SAAA,cAAc,CAAC,IAAY,EAAE,OAAwB,EAAA;AACnE,IAAA,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;AAE3B,IAAA,IAAI,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;AAC9B,QAAA,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,uBAAuB,CAAC;AAC7C,SAAA,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;AAC9B,QAAA,OAAO,CAAG,EAAA,QAAQ,CAAC,IAAI,CAAC,CAAA,0BAAA,EAA6B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAA,CAAA,CAAG,CAAC;AACpE,SAAA,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;AAC9B,QAAA,OAAO,CAAG,EAAA,QAAQ,CAAC,IAAI,CAAC,CAAA,0BAAA,EAA6B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAA,CAAA,CAAG,CAAC;AACpE,SAAA,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;AACjC,QAAA,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,2BAA2B,CAAC;AACjD,SAAA,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;QACpC,OAAO,CAAA,EAAG,QAAQ,CAAC,IAAI,CAAC,CAAgB,aAAA,EAAA,MAAM,CAAC,SAAS,CAAC,UAAU,CAAI,CAAA,EAAA,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA,CAAA,CAAG,CAAC;AAC1G,SAAA,IAAI,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC;AACzC,QAAA,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA,oBAAA,EAAuB,MAAM,CAAC,cAAc,CAAC,CAAC,aAAa,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;AAChH,SAAA,IAAI,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC;AACzC,QAAA,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA,oBAAA,EAAuB,MAAM,CAAC,cAAc,CAAC,CAAC,aAAa,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;AAErH,IAAA,OAAO,IAAI,CAAC;AACd;;MC1Ga,WAAW,CAAA;AACtB,IAAA,SAAS,CAAC,KAAa,EAAA;AACrB,QAAA,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;KAC9B;;yGAHU,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,IAAA,EAAA,CAAA,CAAA;uGAAX,WAAW,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,CAAA;4FAAX,WAAW,EAAA,UAAA,EAAA,CAAA;kBAHvB,IAAI;AAAC,YAAA,IAAA,EAAA,CAAA;AACJ,oBAAA,IAAI,EAAE,SAAS;iBAChB,CAAA;;;ACGD,MAAM,oBAAoB,GAAG,sCAAsC,CAAC;AACpE,MAAM,uBAAuB,GAAG,sCAAsC,CAAC;AACvE,MAAM,aAAa,GAAG,CAAC,kBAAkB,EAAE,QAAQ,EAAE,qBAAqB,CAAC,CAAC;MAM/D,mBAAmB,CAAA;AAyB9B,IAAA,WAAA,CAAoB,MAAqB,EAAA;AAArB,QAAA,IAAM,CAAA,MAAA,GAAN,MAAM,CAAe;AAtBzC,QAAA,IAAM,CAAA,MAAA,GAA0E,SAAS,CAAC;AAW1F,QAAA,IAAS,CAAA,SAAA,GAAG,IAAI,SAAS,CAAC;AACxB,YAAA,GAAG,EAAE,IAAI,WAAW,CAAS,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,YAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;YACpF,MAAM,EAAE,IAAI,WAAW,CAAS,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YAClG,MAAM,EAAE,IAAI,WAAW,CAAS,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACjG,SAAS,EAAE,IAAI,WAAW,CAAS,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAC7D,OAAO,EAAE,IAAI,WAAW,CAAS,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;SAC5D,EAAE;AACD,YAAA,cAAc,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC;AAC/C,YAAA,cAAc,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC;AAC5C,SAAA,CAAC,CAAC;KAE2C;IAE9C,gBAAgB,CAAC,IAAY,EAAE,OAAwB,EAAA;AACrD,QAAA,OAAO,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;KACtC;;IAGO,kBAAkB,GAAA;QACxB,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,IAAG;YAC9C,IAAI,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,gBAAgB,CAAC,EAAE;AAClD,gBAAA,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC;AACjC,aAAA;AACH,SAAC,CAAC,CAAA;KACH;;AAGO,IAAA,aAAa,CAAC,gBAAqC,EAAA;QACzD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,gBAAgB,CAAC;AACzE,QAAA,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QAErC,OAAO;AACL,YAAA,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW;YAC3B,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,MAAM,EAAE,OAAO,CAAC,MAAM;AACtB,YAAA,SAAS,EAAE,gBAAgB,CAAC,SAAS,CAAC;AACtC,YAAA,OAAO,EAAE,gBAAgB,CAAC,OAAO,CAAC;SACnC,CAAA;KACF;AAEO,IAAA,cAAc,CAAC,KAAa,EAAA;AAClC,QAAA,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AACjC,QAAA,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC;QAEhC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;QACxG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;AAEtG,QAAA,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAC9B,IAAI,CAAC,kBAAkB,EAAE,CAAC;KAC3B;;IAGO,eAAe,CAAC,IAAiC,EAAE,gBAAqC,EAAA;AAC9F,QAAA,MAAM,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC;AACrC,QAAA,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;AAC7B,QAAA,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC7B,OAAO,CAAC,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE/B,gBAAgB,CAAC,SAAS,GAAG,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/D,gBAAgB,CAAC,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAE3D,QAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QAE3B,OAAO;YACL,KAAK,EAAE,OAAO,CAAC,GAAG;AAClB,YAAA,kBAAkB,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;YACpD,qBAAqB,EAAE,IAAI,CAAC,eAAe;SAC5C,CAAA;KACF;IAEO,cAAc,CAAC,mBAA2B,EAAE,IAAY,EAAA;AAC9D,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,cAAc,CAC/B,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAC7B,IAAI,CAAC,YAAY,EACjB,mBAAmB,EACnB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAC5B,IAAI,CACL,CAAC;KACH;;IAGD,iBAAiB,GAAA;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;AAC1C,QAAA,MAAM,iBAAiB,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QAC5E,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;AAExF,QAAA,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;AACxB,QAAA,QAAQ,CAAC;AACP,YAAA,IAAI,CAAC,cAAc,CAAC,oBAAoB,EAAE,iBAAiB,CAAC;AAC5D,YAAA,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,eAAe,CAAC;AACtE,SAAA,CAAC,CAAC,IAAI,CACL,GAAG,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAC9B,CAAC,SAAS,EAAE,CAAC;KACf;AAEO,IAAA,eAAe,CAAC,IAAiC,EAAA;QACvD,MAAM,aAAa,GAAyC,EAAE,CAAC;QAC/D,MAAM,YAAY,GAAyC,EAAE,CAAC;;AAG9D,QAAA,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE;YACtB,IAAI,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE;gBAC5C,aAAa,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC;gBAChD,YAAY,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/B,aAAA;AACF,SAAA;AAED,QAAA,MAAM,SAAS,GAAG;AAChB,YAAA,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,YAAY;AACrC,YAAA,aAAa,EAAE,aAAa;AAC5B,YAAA,YAAY,EAAE,YAAY;AAC1B,YAAA,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAA;AAED,QAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;KACtC;;IAGO,cAAc,GAAA;QACpB,IAAI,CAAC,MAAM,CAAC,aAAa,CACvB,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAC7B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAC5B,aAAa,CACd,CAAC,SAAS,CAAC;AACV,YAAA,IAAI,EAAE,CAAC,GAAG,KAAI;;AACZ,gBAAA,IAAI,CAAC,YAAY,GAAG,GAAG,CAAC,YAAY,CAAC;AACrC,gBAAA,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,KAAK,CAAC,CAAC;AACvE,gBAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;;gBAE/D,IAAI,CAAC,eAAe,GAAG,GAAG,CAAC,IAAI,CAAC,qBAAqB,CAAC,KAAK,SAAS,GAAG,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC,KAAK,CAAC;AAElH,gBAAA,IAAI,CAAC,MAAM,GAAG,CAAA,CAAA,EAAA,GAAA,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,KAAK,MAAK,mBAAmB;AAC7D,oBAAA,YAAY;AACZ,oBAAA,SAAS,CAAC;aACb;AACD,YAAA,KAAK,EAAE,CAAC,GAAG,KAAI;AACb,gBAAA,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACnB,gBAAA,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;aACvB;AACF,SAAA,CAAC,CAAC;KACJ;IAED,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,cAAc,CACjB,uBAAuB,EACvB,EAAE,iBAAiB,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,CACnD,CAAC,SAAS,CAAC,MAAK;AACf,YAAA,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC;AAC7B,SAAC,CAAC,CAAA;KACH;IAED,kBAAkB,GAAA;QAChB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;KAClD;IAED,QAAQ,GAAA;;AACN,QAAA,IAAI,EAAC,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,IAAI,CAAC,MAAM,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,MAAM,0CAAG,CAAC,CAAC,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,MAAM,CAAA,EAAE;AACrC,YAAA,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC;YACvB,OAAO;AACR,SAAA;AACD,QAAA,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,IAAG;AACnE,YAAA,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;AAC1B,SAAC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,KAAK,IAAG;AAClE,YAAA,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;AACrB,SAAC,CAAC,CAAC;QAEH,IAAI,CAAC,cAAc,EAAE,CAAC;KACvB;;iHAvLU,mBAAmB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,aAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAnB,mBAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,mBAAmB,qFCfhC,0wEAoDA,EAAA,MAAA,EAAA,CAAA,kqCAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,8CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,iGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,0FAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,cAAA,EAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,IAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAAA,WAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,EAAA,CAAA,CAAA;4FDrCa,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAJ/B,SAAS;+BACE,iBAAiB,EAAA,QAAA,EAAA,0wEAAA,EAAA,MAAA,EAAA,CAAA,kqCAAA,CAAA,EAAA,CAAA;oGAIlB,MAAM,EAAA,CAAA;sBAAd,KAAK;;;MEMK,gBAAgB,CAAA;;8GAAhB,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA,CAAA;AAAhB,gBAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,gBAAgB,iBAZzB,mBAAmB;AACnB,QAAA,WAAW,aAGX,QAAQ;QACR,mBAAmB;QACnB,YAAY,aAGZ,mBAAmB,CAAA,EAAA,CAAA,CAAA;AAGV,gBAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,gBAAgB,YAPzB,mBAAmB;QACnB,YAAY,CAAA,EAAA,CAAA,CAAA;4FAMH,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAd5B,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,YAAY,EAAE;wBACZ,mBAAmB;wBACnB,WAAW;AACZ,qBAAA;AACD,oBAAA,OAAO,EAAE;wBACP,QAAQ;wBACR,mBAAmB;wBACnB,YAAY;AACb,qBAAA;AACD,oBAAA,OAAO,EAAE;wBACP,mBAAmB;AACpB,qBAAA;iBACF,CAAA;;;ACrBD;;AAEG;;ACFH;;AAEG;;;;"}
|
|
1
|
+
{"version":3,"file":"alimetry-detail-edit.mjs","sources":["../../../projects/detail-edit/src/lib/detail-edit.service.ts","../../../projects/detail-edit/src/lib/utils.ts","../../../projects/detail-edit/src/lib/validators.ts","../../../projects/detail-edit/src/lib/entries.pipe.ts","../../../projects/detail-edit/src/lib/detail-edit.component.ts","../../../projects/detail-edit/src/lib/detail-edit.component.html","../../../projects/detail-edit/src/lib/detail-edit.module.ts","../../../projects/detail-edit/src/public-api.ts","../../../projects/detail-edit/src/alimetry-detail-edit.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class DetailEditService {\n\n constructor() { }\n}\n","// strip the timezone offset to create format usable by <input>\nexport function localiseDateTime(datetime: string) {\n const date = new Date(datetime);\n\n const year = date.getFullYear(); const month = (date.getMonth() + 1).toString().padStart(2, '0');\n const day = date.getDate().toString().padStart(2, '0');\n const hour = date.getHours().toString().padStart(2, '0');\n const minute = date.getMinutes().toString().padStart(2, '0');\n const second = date.getSeconds().toString().padStart(2, '0');\n\n return `${year}-${month}-${day}T${hour}:${minute}:${second}`;\n}\n\n// reconstruct original ISO format\nexport function globaliseDateTime(datetime: string) {\n const date = new Date(datetime);\n\n const offset = -date.getTimezoneOffset();\n const offsetAbs = Math.abs(offset);\n\n const sign = offset >= 0 ? '+' : '-';\n const hours = String(Math.floor(offsetAbs / 60)).padStart(2, '0');\n const minutes = String(offsetAbs % 60).padStart(2, '0');\n const offsetString = `${sign}${hours}:${minutes}`;\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const hour = String(date.getHours()).padStart(2, '0');\n const minute = String(date.getMinutes()).padStart(2, '0');\n const second = String(date.getSeconds()).padStart(2, '0');\n\n const datePart = `${year}-${month}-${day}`;\n const timePart = `${hour}:${minute}:${second}.000`;\n\n return `${datePart}T${timePart}${offsetString}`;\n}\n\nexport function getAge(dob: string) {\n const then = new Date(dob);\n const now = new Date();\n\n let age = now.getFullYear() - then.getFullYear();\n\n if (now.getMonth() < then.getMonth() ||\n (now.getMonth() === then.getMonth() && now.getDate() < then.getDate())) {\n age--;\n }\n\n return age;\n}\n\nexport function titleise(camel: string) {\n let spaced = camel.replace(/(?=[A-Z])/g, ' ');\n return spaced.toLowerCase().replace(/\\b\\w/g, ch => ch.toUpperCase());\n}\n\nexport function shallowCompare(a: object, b: object) {\n return Object.entries(a).every(([k, v]) => b[k] === v);\n}\n\nexport function shallowDiff(a: object, b: object) {\n const from = Object.fromEntries(Object.entries(a).filter(([k, v]) => b[k] !== v));\n const to = Object.fromEntries(Object.entries(b).filter(([k, _]) => from[k]));\n return { from, to };\n}\n","import { AbstractControl, FormControl, FormGroup, ValidationErrors, ValidatorFn } from \"@angular/forms\";\nimport { titleise } from \"./utils\";\n\nfunction setControlError(control: AbstractControl, errorKey: string, errorValue: any) {\n const currentErrors = control.errors || {};\n if (currentErrors[errorKey]) return;\n control.setErrors({ ...currentErrors, [errorKey]: errorValue });\n}\n\nfunction clearControlError(control: AbstractControl, errorKey: string) {\n const currentErrors = control.errors || {};\n if (!currentErrors[errorKey]) return;\n control.setErrors({ ...currentErrors, [errorKey]: null });\n}\n\nexport function dateComparison(a: string, b: string, comparator: 'before' | 'after') {\n return function(control: AbstractControl<any, any>): ValidationErrors | null {\n if (!(control instanceof FormGroup)) return null;\n\n const formGroup = control as FormGroup;\n\n const aControl = formGroup.get(a);\n const bControl = formGroup.get(b);\n\n if (!aControl?.value || !bControl?.value) {\n clearControlError(aControl, 'dateRange');\n return null;\n }\n\n const aDate = new Date(aControl.value);\n const bDate = new Date(bControl.value);\n\n const hasError = (\n comparator === 'after' && aDate <= bDate ||\n comparator === 'before' && aDate >= bDate\n );\n\n if (hasError) {\n setControlError(aControl, 'dateRange', { against: b, comparator });\n return { dateRange: true };\n }\n\n clearControlError(aControl, 'dateRange');\n return null;\n }\n}\n\nexport function withinNYears(n: number, dir: 'both' | 'before' | 'after' = 'both', of?: Date): ValidatorFn {\n return function(control: AbstractControl): ValidationErrors | null {\n const timestamp = control?.value;\n if (!timestamp || isNaN(new Date(timestamp).getTime())) return null;\n\n const date = new Date(timestamp);\n const against = of ?? new Date();\n\n const min = new Date(against)\n min.setFullYear(against.getFullYear() - n);\n const max = new Date(against)\n max.setFullYear(against.getFullYear() + n);\n\n let isValid = false;\n if (dir === 'after') isValid = date < max && date > against;\n else if (dir === 'before') isValid = date > min && date < against;\n else isValid = date > min && date < max;\n\n return isValid ? null : { notWithinYears: { n, against, dir } };\n }\n}\n\nexport function withinNHours(n: number, dir: 'both' | 'before' | 'after' = 'both', of?: Date): ValidatorFn {\n return function(control: AbstractControl): ValidationErrors | null {\n const timestamp = control?.value;\n if (!timestamp || isNaN(new Date(timestamp).getTime())) return null;\n\n const date = new Date(timestamp);\n const against = of ?? new Date();\n\n const min = new Date(against)\n min.setHours(against.getHours() - n);\n const max = new Date(against)\n max.setHours(against.getHours() + n);\n\n let isValid = false;\n if (dir === 'after') isValid = date < max && date > against;\n else if (dir === 'before') isValid = date > min && date < against;\n else isValid = date > min && date < max;\n\n return isValid ? null : { notWithinHours: { n, against, dir } };\n }\n}\n\n// translate validation errors into human readable strings\nexport function translateError(name: string, control: AbstractControl) {\n const { errors } = control;\n\n if (control.hasError('required'))\n return `${titleise(name)} is a required value.`;\n else if (control.hasError('min'))\n return `${titleise(name)} needs to be a minimum of ${errors.min.min}.`;\n else if (control.hasError('max'))\n return `${titleise(name)} needs to be a maximum of ${errors.max.max}.`;\n else if (control.hasError('future'))\n return `${titleise(name)} needs to be in the past.`;\n else if (control.hasError('dateRange'))\n return `${titleise(name)} needs to be ${errors.dateRange.comparator} ${titleise(errors.dateRange.against)}.`;\n else if (control.hasError('notWithinYears'))\n return `${titleise(name)} needs to be within ${errors.notWithinYears.n} years of ${errors.notWithinYears.against}`;\n else if (control.hasError('notWithinHours'))\n return `${titleise(name)} needs to be within ${errors.notWithinHours.n} hours of ${errors.notWithinHours.against}`;\n\n return null;\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({\n name: 'entries'\n})\nexport class EntriesPipe implements PipeTransform {\n transform(value: object): [string, any][] {\n return Object.entries(value);\n }\n}\n","import { Component, DoCheck, Input, KeyValueDiffers, KeyValueDiffer, IterableDiffer, IterableDiffers } from '@angular/core';\nimport { AbstractControl, FormControl, FormGroup, Validators } from '@angular/forms';\nimport { forkJoin, tap } from 'rxjs';\nimport { Config, SharedService, User } from 'alimetry-shared';\nimport { getAge, globaliseDateTime, localiseDateTime, shallowCompare, shallowDiff } from './utils';\nimport { dateComparison, withinNYears, withinNHours, translateError } from './validators';\n\nconst appDataPropertySetId = '34d46477-ad4b-47b4-b555-06358b92f60c';\nconst deviceDataPropertySetId = '7a32d851-5e89-46a6-a4b6-cca162dace29';\nconst propertyCodes = ['RecordingSession', 'Status', 'UserDetailChangeLog'];\n\ninterface FormValue {\n dob: string,\n height: number,\n weight: number,\n mealStart: string,\n mealEnd: string\n}\n\ninterface Change {\n timestamp: string,\n author: string,\n from: Partial<FormValue>,\n to: Partial<FormValue>\n}\n\n@Component({\n selector: 'lib-detail-edit',\n templateUrl: './detail-edit.component.html',\n styleUrls: ['./detail-edit.component.css']\n})\nexport class DetailEditComponent implements DoCheck {\n @Input() config!: Config;\n\n private configDiffer?: KeyValueDiffer<keyof Config, any>;\n private ownersDiffer?: IterableDiffer<string>;\n\n status: 'error' | 'cfgerror' | 'loading' | 'success' | 'generating' | 'sending' | 'nouser' = 'loading';\n\n // device data populated by load request\n private deviceDataId: string;\n private recordingSession: object;\n private recordingStart: string;\n private initialFormState: object;\n\n // user data expanded from ids passed in config\n private currentUser: User;\n private owner: User;\n\n private detailChangeLog: Change[];\n\n formGroup = new FormGroup({\n dob: new FormControl<string>('', [Validators.required, withinNYears(120, 'before')]),\n height: new FormControl<number>(0, [Validators.required, Validators.min(30), Validators.max(272)]),\n weight: new FormControl<number>(0, [Validators.required, Validators.min(1), Validators.max(635)]),\n mealStart: new FormControl<string>('', [Validators.required]),\n mealEnd: new FormControl<string>('', [Validators.required])\n }, [\n dateComparison('mealEnd', 'mealStart', 'after'),\n dateComparison('mealStart', 'dob', 'after'),\n ]);\n\n constructor(private shared: SharedService, private kvDiffers: KeyValueDiffers, private itDiffers: IterableDiffers) { }\n\n parseInputErrors(name: string, control: AbstractControl) {\n return translateError(name, control);\n }\n\n // make sure than modifications that don't actually differ from the current are marked as such\n private monitorFormChanges() {\n this.formGroup.valueChanges.subscribe(current => {\n if (shallowCompare(current, this.initialFormState)) {\n this.formGroup.markAsPristine();\n }\n })\n }\n\n // handle the relevant data from the response body\n private extractFields(recordingSession: Record<string, any>) {\n const { patient, mealStart, mealEnd, recordingStart } = recordingSession;\n this.recordingStart = recordingStart;\n\n return {\n dob: this.owner.dateOfBirth,\n height: patient.height,\n weight: patient.weight,\n mealStart: localiseDateTime(mealStart),\n mealEnd: localiseDateTime(mealEnd)\n }\n }\n\n private initialiseForm(state: object) {\n this.formGroup.patchValue(state);\n this.formGroup.markAsPristine();\n\n this.formGroup.get('mealStart').addValidators(withinNHours(24, 'after', new Date(this.recordingStart)));\n this.formGroup.get('mealEnd').addValidators(withinNHours(24, 'after', new Date(this.recordingStart)));\n\n this.initialFormState = state; // save this for use in resets\n this.monitorFormChanges();\n }\n\n // construct a patch object for the save request\n private integrateFields(mods: FormValue, recordingSession: Record<string, any>) {\n const { patient } = recordingSession;\n patient.height = mods.height;\n patient.weight = mods.weight;\n patient.age = getAge(mods.dob);\n\n recordingSession.mealStart = globaliseDateTime(mods.mealStart);\n recordingSession.mealEnd = globaliseDateTime(mods.mealEnd);\n\n this.logChange(mods);\n\n return {\n 'Age': patient.age,\n 'RecordingSession': JSON.stringify(recordingSession),\n 'UserDetailChangeLog': this.detailChangeLog\n }\n }\n\n private postDeviceData(devicePropertySetId: string, data: object) {\n return this.shared.saveDeviceData(\n this.config.deviceDataModelId,\n this.deviceDataId,\n devicePropertySetId,\n this.config.owners[0],\n data\n );\n }\n\n // patch the device data record with the modifications\n saveModifications() {\n const mods = this.formGroup.getRawValue();\n const patchedDeviceData = this.integrateFields(mods, this.recordingSession);\n const patchedUserData = Object.assign(this.owner, { dateOfBirth: mods.dob });\n\n this.status = 'sending';\n forkJoin([\n this.postDeviceData(appDataPropertySetId, patchedDeviceData),\n this.shared.updateUser(this.config.owners[0], patchedUserData)\n ]).pipe(\n tap(() => this.regenReport())\n ).subscribe();\n }\n\n private logChange(mods: FormValue) {\n const entry = {\n author: this.currentUser.emailAddress,\n timestamp: new Date().toISOString(),\n ...shallowDiff(this.initialFormState, mods)\n }\n\n this.detailChangeLog.push(entry);\n\n console.log(this.detailChangeLog);\n }\n\n regenReport() {\n this.postDeviceData(\n deviceDataPropertySetId,\n { 'Algorithmhasrun': false, 'AlgorithmRun': true }\n ).subscribe(() => {\n this.status = 'generating'; // assume report starts generating immediately\n })\n }\n\n resetModifications() {\n this.formGroup.patchValue(this.initialFormState);\n }\n\n private loadData(currentUserId: string, ownerId: string, deviceDataModelId: string) {\n forkJoin([\n this.shared.getUser(currentUserId),\n this.shared.getUser(ownerId),\n this.shared.getDeviceData(deviceDataModelId, ownerId, propertyCodes)\n ]).subscribe({\n next: ([currentUser, owner, { deviceDataId, data: deviceData }]) => {\n this.currentUser = currentUser;\n this.owner = owner;\n this.deviceDataId = deviceDataId;\n\n this.recordingSession = JSON.parse(deviceData['RecordingSession'].value);\n this.initialiseForm(this.extractFields(this.recordingSession));\n\n // data field uninitialised for unmodified record\n this.detailChangeLog = deviceData['UserDetailChangeLog']?.value ?? [];\n\n this.status = deviceData['Status']?.value === 'Generating Report' ?\n 'generating' : 'success';\n },\n error: (err) => {\n console.error(err);\n this.status = \"error\";\n }\n });\n }\n\n private init() {\n if (!this.config?.currentUserId || !this.config.deviceDataModelId) {\n this.status = 'cfgerror'\n return;\n } else if (!this.config?.owners?.[0]) {\n this.status = 'nouser';\n return;\n }\n\n this.status = 'loading';\n this.loadData(this.config.currentUserId, this.config.owners[0], this.config.deviceDataModelId);\n }\n\n // this should be called from the parent using the ViewChild attr\n refresh() {\n this.init();\n }\n\n // NOTE: there could be something wrong / unusual here but it seems to work ok\n ngOnInit() {\n if (this.config && !this.configDiffer) this.configDiffer = this.kvDiffers.find(this.config).create();\n if (this.config?.owners && !this.ownersDiffer) this.ownersDiffer = this.itDiffers.find(this.config.owners).create();\n }\n\n ngDoCheck() {\n const configChanges = this.configDiffer?.diff(this.config);\n const ownersChanges = this.ownersDiffer?.diff(this.config?.owners);\n\n if (configChanges || ownersChanges) this.init();\n }\n}\n","<div class=\"wrapper\">\n <div class=\"status\" *ngIf=\"status === 'error'\">\n An error occured while trying to get the details.\n </div>\n <div class=\"status\" *ngIf=\"status === 'cfgerror'\">\n The widget has not been configured correctly, or is missing configuration information.\n </div>\n <div class=\"status\" *ngIf=\"status === 'nouser'\">\n There is no user specified as the data owner.\n </div>\n <form *ngIf=\"!status.includes('error') && status !== 'nouser'\" [formGroup]=\"formGroup\" (ngSubmit)=\"saveModifications()\">\n <div class=\"inputs\">\n <div class=\"form-row\">\n <label for=\"dob\">Date of Birth:</label>\n <input id=\"dob\" type=\"date\" formControlName=\"dob\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"weight\">Patient Weight (kg):</label>\n <input id=\"weight\" type=\"number\" formControlName=\"weight\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"height\">Patient Height (cm):</label>\n <input id=\"height\" type=\"number\" formControlName=\"height\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"mealStart\">Meal Start Time:</label>\n <input id=\"mealStart\" type=\"datetime-local\" formControlName=\"mealStart\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"mealEnd\">Meal End Time:</label>\n <input id=\"mealEnd\" type=\"datetime-local\" formControlName=\"mealEnd\">\n </div>\n </div>\n\n <div *ngIf=\"!formGroup.valid && formGroup.dirty\" class=\"errors\">\n <div *ngFor=\"let control of formGroup.controls | entries\">\n {{ parseInputErrors(control[0], control[1]) }}\n </div>\n </div>\n\n <div *ngIf=\"status === 'generating'\" class=\"info\">\n <div>The report is generating at the moment, check back later if you need to modify this entry.</div>\n </div>\n\n <div class=\"buttons\">\n <button type=\"button\" (click)=\"regenReport()\" [disabled]=\"status === 'sending' || status === 'generating' || status === 'loading'\">Regenerate Report</button>\n <button type=\"button\" (click)=\"resetModifications()\" [disabled]=\"status === 'sending' || status === 'generating' || formGroup.pristine\">Cancel Modification</button>\n <button type=\"submit\" [disabled]=\"status === 'sending' || status === 'generating' || !formGroup.valid || formGroup.pristine\">Save Details</button>\n </div>\n </form>\n</div>\n","import { CommonModule, JsonPipe } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { DetailEditComponent } from './detail-edit.component';\nimport { EntriesPipe } from './entries.pipe';\n\n\n\n@NgModule({\n declarations: [\n DetailEditComponent,\n EntriesPipe\n ],\n imports: [\n JsonPipe,\n ReactiveFormsModule,\n CommonModule\n ],\n exports: [\n DetailEditComponent\n ]\n})\nexport class DetailEditModule { }\n","/*\n * Public API Surface of detail-edit\n */\n\nexport * from './lib/detail-edit.service';\nexport * from './lib/detail-edit.component';\nexport * from './lib/detail-edit.module';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i4.EntriesPipe"],"mappings":";;;;;;;;;MAKa,iBAAiB,CAAA;AAE5B,IAAA,WAAA,GAAA,GAAiB;;+GAFN,iBAAiB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,UAAA,EAAA,CAAA,CAAA;AAAjB,iBAAA,CAAA,KAAA,GAAA,EAAA,CAAA,qBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,iBAAiB,cAFhB,MAAM,EAAA,CAAA,CAAA;4FAEP,iBAAiB,EAAA,UAAA,EAAA,CAAA;kBAH7B,UAAU;AAAC,YAAA,IAAA,EAAA,CAAA;AACV,oBAAA,UAAU,EAAE,MAAM;iBACnB,CAAA;;;ACJD;AACM,SAAU,gBAAgB,CAAC,QAAgB,EAAA;AAC/C,IAAA,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;AAEhC,IAAA,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAAC,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACjG,IAAA,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACvD,IAAA,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACzD,IAAA,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC7D,IAAA,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAE7D,IAAA,OAAO,CAAG,EAAA,IAAI,CAAI,CAAA,EAAA,KAAK,CAAI,CAAA,EAAA,GAAG,CAAI,CAAA,EAAA,IAAI,CAAI,CAAA,EAAA,MAAM,CAAI,CAAA,EAAA,MAAM,EAAE,CAAC;AAC/D,CAAC;AAED;AACM,SAAU,iBAAiB,CAAC,QAAgB,EAAA;AAChD,IAAA,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;AAEhC,IAAA,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;IACzC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAEnC,IAAA,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC;IACrC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAClE,IAAA,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACxD,MAAM,YAAY,GAAG,CAAG,EAAA,IAAI,GAAG,KAAK,CAAA,CAAA,EAAI,OAAO,CAAA,CAAE,CAAC;AAClD,IAAA,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;AAChC,IAAA,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC3D,IAAA,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACpD,IAAA,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AACtD,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;AAC1D,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAE1D,MAAM,QAAQ,GAAG,CAAG,EAAA,IAAI,IAAI,KAAK,CAAA,CAAA,EAAI,GAAG,CAAA,CAAE,CAAC;IAC3C,MAAM,QAAQ,GAAG,CAAG,EAAA,IAAI,IAAI,MAAM,CAAA,CAAA,EAAI,MAAM,CAAA,IAAA,CAAM,CAAC;AAEnD,IAAA,OAAO,GAAG,QAAQ,CAAA,CAAA,EAAI,QAAQ,CAAG,EAAA,YAAY,EAAE,CAAC;AAClD,CAAC;AAEK,SAAU,MAAM,CAAC,GAAW,EAAA;AAChC,IAAA,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3B,IAAA,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IAEvB,IAAI,GAAG,GAAG,GAAG,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IAEjD,IAAI,GAAG,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE;SACjC,GAAG,CAAC,QAAQ,EAAE,KAAK,IAAI,CAAC,QAAQ,EAAE,IAAI,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE;AACxE,QAAA,GAAG,EAAE,CAAC;AACP,KAAA;AAED,IAAA,OAAO,GAAG,CAAC;AACb,CAAC;AAEK,SAAU,QAAQ,CAAC,KAAa,EAAA;IACpC,IAAI,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;AAC9C,IAAA,OAAO,MAAM,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC;AACvE,CAAC;AAEe,SAAA,cAAc,CAAC,CAAS,EAAE,CAAS,EAAA;IACjD,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AACzD,CAAC;AAEe,SAAA,WAAW,CAAC,CAAS,EAAE,CAAS,EAAA;AAC9C,IAAA,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAClF,IAAA,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7E,IAAA,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC;AACtB;;AC7DA,SAAS,eAAe,CAAC,OAAwB,EAAE,QAAgB,EAAE,UAAe,EAAA;AAClF,IAAA,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;IAC3C,IAAI,aAAa,CAAC,QAAQ,CAAC;QAAE,OAAO;IACpC,OAAO,CAAC,SAAS,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAAM,aAAa,CAAA,EAAA,EAAE,CAAC,QAAQ,GAAG,UAAU,EAAA,CAAA,CAAG,CAAC;AAClE,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAwB,EAAE,QAAgB,EAAA;AACnE,IAAA,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC;AAC3C,IAAA,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC;QAAE,OAAO;IACrC,OAAO,CAAC,SAAS,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,MAAA,CAAA,EAAA,EAAM,aAAa,CAAA,EAAA,EAAE,CAAC,QAAQ,GAAG,IAAI,EAAA,CAAA,CAAG,CAAC;AAC5D,CAAC;SAEe,cAAc,CAAC,CAAS,EAAE,CAAS,EAAE,UAA8B,EAAA;AACjF,IAAA,OAAO,UAAS,OAAkC,EAAA;AAChD,QAAA,IAAI,EAAE,OAAO,YAAY,SAAS,CAAC;AAAE,YAAA,OAAO,IAAI,CAAC;QAEjD,MAAM,SAAS,GAAG,OAAoB,CAAC;QAEvC,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAElC,IAAI,EAAC,QAAQ,KAAA,IAAA,IAAR,QAAQ,KAAR,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,QAAQ,CAAE,KAAK,CAAA,IAAI,EAAC,QAAQ,KAAR,IAAA,IAAA,QAAQ,uBAAR,QAAQ,CAAE,KAAK,CAAA,EAAE;AACxC,YAAA,iBAAiB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AACzC,YAAA,OAAO,IAAI,CAAC;AACb,SAAA;QAED,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAEvC,MAAM,QAAQ,IACZ,UAAU,KAAK,OAAO,IAAI,KAAK,IAAI,KAAK;AACxC,YAAA,UAAU,KAAK,QAAQ,IAAI,KAAK,IAAI,KAAK,CAC1C,CAAC;AAEF,QAAA,IAAI,QAAQ,EAAE;AACZ,YAAA,eAAe,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;AACnE,YAAA,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAC5B,SAAA;AAED,QAAA,iBAAiB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AACzC,QAAA,OAAO,IAAI,CAAC;AACd,KAAC,CAAA;AACH,CAAC;AAEK,SAAU,YAAY,CAAC,CAAS,EAAE,GAAmC,GAAA,MAAM,EAAE,EAAS,EAAA;AAC1F,IAAA,OAAO,UAAS,OAAwB,EAAA;QACtC,MAAM,SAAS,GAAG,OAAO,KAAA,IAAA,IAAP,OAAO,KAAP,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,OAAO,CAAE,KAAK,CAAC;AACjC,QAAA,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;AAAE,YAAA,OAAO,IAAI,CAAC;AAEpE,QAAA,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,EAAE,KAAF,IAAA,IAAA,EAAE,KAAF,KAAA,CAAA,GAAA,EAAE,GAAI,IAAI,IAAI,EAAE,CAAC;AAEjC,QAAA,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAA;QAC7B,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC;AAC3C,QAAA,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAA;QAC7B,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC;QAE3C,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,GAAG,KAAK,OAAO;YAAE,OAAO,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI,GAAG,OAAO,CAAC;aACvD,IAAI,GAAG,KAAK,QAAQ;YAAE,OAAO,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI,GAAG,OAAO,CAAC;;YAC7D,OAAO,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI,GAAG,GAAG,CAAC;AAExC,QAAA,OAAO,OAAO,GAAG,IAAI,GAAG,EAAE,cAAc,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;AAClE,KAAC,CAAA;AACH,CAAC;AAEK,SAAU,YAAY,CAAC,CAAS,EAAE,GAAmC,GAAA,MAAM,EAAE,EAAS,EAAA;AAC1F,IAAA,OAAO,UAAS,OAAwB,EAAA;QACtC,MAAM,SAAS,GAAG,OAAO,KAAA,IAAA,IAAP,OAAO,KAAP,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,OAAO,CAAE,KAAK,CAAC;AACjC,QAAA,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;AAAE,YAAA,OAAO,IAAI,CAAC;AAEpE,QAAA,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;QACjC,MAAM,OAAO,GAAG,EAAE,KAAF,IAAA,IAAA,EAAE,KAAF,KAAA,CAAA,GAAA,EAAE,GAAI,IAAI,IAAI,EAAE,CAAC;AAEjC,QAAA,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAA;QAC7B,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC;AACrC,QAAA,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAA;QAC7B,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC;QAErC,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,GAAG,KAAK,OAAO;YAAE,OAAO,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI,GAAG,OAAO,CAAC;aACvD,IAAI,GAAG,KAAK,QAAQ;YAAE,OAAO,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI,GAAG,OAAO,CAAC;;YAC7D,OAAO,GAAG,IAAI,GAAG,GAAG,IAAI,IAAI,GAAG,GAAG,CAAC;AAExC,QAAA,OAAO,OAAO,GAAG,IAAI,GAAG,EAAE,cAAc,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,EAAE,CAAC;AAClE,KAAC,CAAA;AACH,CAAC;AAED;AACgB,SAAA,cAAc,CAAC,IAAY,EAAE,OAAwB,EAAA;AACnE,IAAA,MAAM,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;AAE3B,IAAA,IAAI,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC;AAC9B,QAAA,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,uBAAuB,CAAC;AAC7C,SAAA,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;AAC9B,QAAA,OAAO,CAAG,EAAA,QAAQ,CAAC,IAAI,CAAC,CAAA,0BAAA,EAA6B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAA,CAAA,CAAG,CAAC;AACpE,SAAA,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;AAC9B,QAAA,OAAO,CAAG,EAAA,QAAQ,CAAC,IAAI,CAAC,CAAA,0BAAA,EAA6B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAA,CAAA,CAAG,CAAC;AACpE,SAAA,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC;AACjC,QAAA,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,2BAA2B,CAAC;AACjD,SAAA,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC;QACpC,OAAO,CAAA,EAAG,QAAQ,CAAC,IAAI,CAAC,CAAgB,aAAA,EAAA,MAAM,CAAC,SAAS,CAAC,UAAU,CAAI,CAAA,EAAA,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA,CAAA,CAAG,CAAC;AAC1G,SAAA,IAAI,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC;AACzC,QAAA,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA,oBAAA,EAAuB,MAAM,CAAC,cAAc,CAAC,CAAC,aAAa,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;AAChH,SAAA,IAAI,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAC;AACzC,QAAA,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA,oBAAA,EAAuB,MAAM,CAAC,cAAc,CAAC,CAAC,aAAa,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;AAErH,IAAA,OAAO,IAAI,CAAC;AACd;;MC1Ga,WAAW,CAAA;AACtB,IAAA,SAAS,CAAC,KAAa,EAAA;AACrB,QAAA,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;KAC9B;;yGAHU,WAAW,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,IAAA,EAAA,CAAA,CAAA;uGAAX,WAAW,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,CAAA;4FAAX,WAAW,EAAA,UAAA,EAAA,CAAA;kBAHvB,IAAI;AAAC,YAAA,IAAA,EAAA,CAAA;AACJ,oBAAA,IAAI,EAAE,SAAS;iBAChB,CAAA;;;ACGD,MAAM,oBAAoB,GAAG,sCAAsC,CAAC;AACpE,MAAM,uBAAuB,GAAG,sCAAsC,CAAC;AACvE,MAAM,aAAa,GAAG,CAAC,kBAAkB,EAAE,QAAQ,EAAE,qBAAqB,CAAC,CAAC;MAsB/D,mBAAmB,CAAA;AA+B9B,IAAA,WAAA,CAAoB,MAAqB,EAAU,SAA0B,EAAU,SAA0B,EAAA;AAA7F,QAAA,IAAM,CAAA,MAAA,GAAN,MAAM,CAAe;AAAU,QAAA,IAAS,CAAA,SAAA,GAAT,SAAS,CAAiB;AAAU,QAAA,IAAS,CAAA,SAAA,GAAT,SAAS,CAAiB;AAzBjH,QAAA,IAAM,CAAA,MAAA,GAAuF,SAAS,CAAC;AAcvG,QAAA,IAAS,CAAA,SAAA,GAAG,IAAI,SAAS,CAAC;AACxB,YAAA,GAAG,EAAE,IAAI,WAAW,CAAS,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,YAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;YACpF,MAAM,EAAE,IAAI,WAAW,CAAS,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YAClG,MAAM,EAAE,IAAI,WAAW,CAAS,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACjG,SAAS,EAAE,IAAI,WAAW,CAAS,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;YAC7D,OAAO,EAAE,IAAI,WAAW,CAAS,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;SAC5D,EAAE;AACD,YAAA,cAAc,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC;AAC/C,YAAA,cAAc,CAAC,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC;AAC5C,SAAA,CAAC,CAAC;KAEmH;IAEtH,gBAAgB,CAAC,IAAY,EAAE,OAAwB,EAAA;AACrD,QAAA,OAAO,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;KACtC;;IAGO,kBAAkB,GAAA;QACxB,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,IAAG;YAC9C,IAAI,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,gBAAgB,CAAC,EAAE;AAClD,gBAAA,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC;AACjC,aAAA;AACH,SAAC,CAAC,CAAA;KACH;;AAGO,IAAA,aAAa,CAAC,gBAAqC,EAAA;QACzD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,gBAAgB,CAAC;AACzE,QAAA,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QAErC,OAAO;AACL,YAAA,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW;YAC3B,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,MAAM,EAAE,OAAO,CAAC,MAAM;AACtB,YAAA,SAAS,EAAE,gBAAgB,CAAC,SAAS,CAAC;AACtC,YAAA,OAAO,EAAE,gBAAgB,CAAC,OAAO,CAAC;SACnC,CAAA;KACF;AAEO,IAAA,cAAc,CAAC,KAAa,EAAA;AAClC,QAAA,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AACjC,QAAA,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC;QAEhC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;QACxG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,aAAa,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC;AAEtG,QAAA,IAAI,CAAC,gBAAgB,GAAG,KAAK,CAAC;QAC9B,IAAI,CAAC,kBAAkB,EAAE,CAAC;KAC3B;;IAGO,eAAe,CAAC,IAAe,EAAE,gBAAqC,EAAA;AAC5E,QAAA,MAAM,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAAC;AACrC,QAAA,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;AAC7B,QAAA,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC7B,OAAO,CAAC,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE/B,gBAAgB,CAAC,SAAS,GAAG,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC/D,gBAAgB,CAAC,OAAO,GAAG,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAE3D,QAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAErB,OAAO;YACL,KAAK,EAAE,OAAO,CAAC,GAAG;AAClB,YAAA,kBAAkB,EAAE,IAAI,CAAC,SAAS,CAAC,gBAAgB,CAAC;YACpD,qBAAqB,EAAE,IAAI,CAAC,eAAe;SAC5C,CAAA;KACF;IAEO,cAAc,CAAC,mBAA2B,EAAE,IAAY,EAAA;AAC9D,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,cAAc,CAC/B,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAC7B,IAAI,CAAC,YAAY,EACjB,mBAAmB,EACnB,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EACrB,IAAI,CACL,CAAC;KACH;;IAGD,iBAAiB,GAAA;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;AAC1C,QAAA,MAAM,iBAAiB,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;AAC5E,QAAA,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;AAE7E,QAAA,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;AACxB,QAAA,QAAQ,CAAC;AACP,YAAA,IAAI,CAAC,cAAc,CAAC,oBAAoB,EAAE,iBAAiB,CAAC;AAC5D,YAAA,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,eAAe,CAAC;AAC/D,SAAA,CAAC,CAAC,IAAI,CACL,GAAG,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAC9B,CAAC,SAAS,EAAE,CAAC;KACf;AAEO,IAAA,SAAS,CAAC,IAAe,EAAA;AAC/B,QAAA,MAAM,KAAK,GAAA,MAAA,CAAA,MAAA,CAAA,EACT,MAAM,EAAE,IAAI,CAAC,WAAW,CAAC,YAAY,EACrC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAChC,EAAA,WAAW,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAC5C,CAAA;AAED,QAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAEjC,QAAA,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;KACnC;IAED,WAAW,GAAA;AACT,QAAA,IAAI,CAAC,cAAc,CACjB,uBAAuB,EACvB,EAAE,iBAAiB,EAAE,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,CACnD,CAAC,SAAS,CAAC,MAAK;AACf,YAAA,IAAI,CAAC,MAAM,GAAG,YAAY,CAAC;AAC7B,SAAC,CAAC,CAAA;KACH;IAED,kBAAkB,GAAA;QAChB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;KAClD;AAEO,IAAA,QAAQ,CAAC,aAAqB,EAAE,OAAe,EAAE,iBAAyB,EAAA;AAChF,QAAA,QAAQ,CAAC;AACP,YAAA,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC;AAClC,YAAA,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;YAC5B,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,iBAAiB,EAAE,OAAO,EAAE,aAAa,CAAC;SACrE,CAAC,CAAC,SAAS,CAAC;AACX,YAAA,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,KAAK,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,KAAI;;AACjE,gBAAA,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;AAC/B,gBAAA,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;AACnB,gBAAA,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;AAEjC,gBAAA,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAC,KAAK,CAAC,CAAC;AACzE,gBAAA,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC;;AAG/D,gBAAA,IAAI,CAAC,eAAe,GAAG,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,UAAU,CAAC,qBAAqB,CAAC,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAE,KAAK,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,EAAA,GAAI,EAAE,CAAC;AAEtE,gBAAA,IAAI,CAAC,MAAM,GAAG,CAAA,MAAA,UAAU,CAAC,QAAQ,CAAC,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,KAAK,MAAK,mBAAmB;AAC/D,oBAAA,YAAY,GAAG,SAAS,CAAC;aAC5B;AACD,YAAA,KAAK,EAAE,CAAC,GAAG,KAAI;AACb,gBAAA,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACnB,gBAAA,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC;aACvB;AACF,SAAA,CAAC,CAAC;KACJ;IAEO,IAAI,GAAA;;AACV,QAAA,IAAI,EAAC,CAAA,EAAA,GAAA,IAAI,CAAC,MAAM,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,aAAa,CAAA,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE;AACjE,YAAA,IAAI,CAAC,MAAM,GAAG,UAAU,CAAA;YACxB,OAAO;AACR,SAAA;AAAM,aAAA,IAAI,EAAC,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,IAAI,CAAC,MAAM,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAE,MAAM,MAAA,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAG,CAAC,CAAC,CAAA,EAAE;AACpC,YAAA,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC;YACvB,OAAO;AACR,SAAA;AAED,QAAA,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;QACxB,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC;KAChG;;IAGD,OAAO,GAAA;QACL,IAAI,CAAC,IAAI,EAAE,CAAC;KACb;;IAGD,QAAQ,GAAA;;AACN,QAAA,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,YAAY;AAAE,YAAA,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;QACrG,IAAI,CAAA,CAAA,EAAA,GAAA,IAAI,CAAC,MAAM,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,MAAM,KAAI,CAAC,IAAI,CAAC,YAAY;AAAE,YAAA,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;KACrH;IAED,SAAS,GAAA;;AACP,QAAA,MAAM,aAAa,GAAG,CAAA,EAAA,GAAA,IAAI,CAAC,YAAY,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC3D,QAAA,MAAM,aAAa,GAAG,CAAA,EAAA,GAAA,IAAI,CAAC,YAAY,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,IAAI,CAAC,CAAA,EAAA,GAAA,IAAI,CAAC,MAAM,MAAE,IAAA,IAAA,EAAA,KAAA,KAAA,CAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,MAAM,CAAC,CAAC;QAEnE,IAAI,aAAa,IAAI,aAAa;YAAE,IAAI,CAAC,IAAI,EAAE,CAAC;KACjD;;iHApMU,mBAAmB,EAAA,IAAA,EAAA,CAAA,EAAA,KAAA,EAAA,EAAA,CAAA,aAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,eAAA,EAAA,EAAA,EAAA,KAAA,EAAA,EAAA,CAAA,eAAA,EAAA,CAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAnB,mBAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,IAAA,EAAA,mBAAmB,qFC/BhC,i7EAuDA,EAAA,MAAA,EAAA,CAAA,kqCAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,aAAA,EAAA,QAAA,EAAA,8CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,8MAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,mBAAA,EAAA,QAAA,EAAA,iGAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,2CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,oBAAA,EAAA,QAAA,EAAA,0FAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,kBAAA,EAAA,QAAA,EAAA,aAAA,EAAA,MAAA,EAAA,CAAA,WAAA,CAAA,EAAA,OAAA,EAAA,CAAA,UAAA,CAAA,EAAA,QAAA,EAAA,CAAA,QAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,eAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,iBAAA,EAAA,UAAA,EAAA,SAAA,CAAA,EAAA,OAAA,EAAA,CAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,OAAA,EAAA,QAAA,EAAA,kBAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,cAAA,EAAA,eAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAAA,EAAA,CAAA,IAAA,EAAA,QAAA,EAAA,QAAA,EAAA,MAAA,EAAA,CAAA,MAAA,EAAA,UAAA,EAAA,UAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAAA,WAAA,EAAA,IAAA,EAAA,SAAA,EAAA,CAAA,EAAA,CAAA,CAAA;4FDxBa,mBAAmB,EAAA,UAAA,EAAA,CAAA;kBAL/B,SAAS;+BACE,iBAAiB,EAAA,QAAA,EAAA,i7EAAA,EAAA,MAAA,EAAA,CAAA,kqCAAA,CAAA,EAAA,CAAA;gKAKlB,MAAM,EAAA,CAAA;sBAAd,KAAK;;;MEVK,gBAAgB,CAAA;;8GAAhB,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,QAAA,EAAA,CAAA,CAAA;AAAhB,gBAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,gBAAgB,iBAZzB,mBAAmB;AACnB,QAAA,WAAW,aAGX,QAAQ;QACR,mBAAmB;QACnB,YAAY,aAGZ,mBAAmB,CAAA,EAAA,CAAA,CAAA;AAGV,gBAAA,CAAA,IAAA,GAAA,EAAA,CAAA,mBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,SAAA,EAAA,QAAA,EAAA,EAAA,EAAA,IAAA,EAAA,gBAAgB,YAPzB,mBAAmB;QACnB,YAAY,CAAA,EAAA,CAAA,CAAA;4FAMH,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAd5B,QAAQ;AAAC,YAAA,IAAA,EAAA,CAAA;AACR,oBAAA,YAAY,EAAE;wBACZ,mBAAmB;wBACnB,WAAW;AACZ,qBAAA;AACD,oBAAA,OAAO,EAAE;wBACP,QAAQ;wBACR,mBAAmB;wBACnB,YAAY;AACb,qBAAA;AACD,oBAAA,OAAO,EAAE;wBACP,mBAAmB;AACpB,qBAAA;iBACF,CAAA;;;ACrBD;;AAEG;;ACFH;;AAEG;;;;"}
|
|
@@ -3,7 +3,7 @@ import { Injectable, Pipe, Component, Input, NgModule } from '@angular/core';
|
|
|
3
3
|
import * as i2 from '@angular/forms';
|
|
4
4
|
import { FormGroup, FormControl, Validators, ReactiveFormsModule } from '@angular/forms';
|
|
5
5
|
import { forkJoin, tap } from 'rxjs';
|
|
6
|
-
import * as i1 from 'shared';
|
|
6
|
+
import * as i1 from 'alimetry-shared';
|
|
7
7
|
import * as i3 from '@angular/common';
|
|
8
8
|
import { JsonPipe, CommonModule } from '@angular/common';
|
|
9
9
|
|
|
@@ -66,6 +66,11 @@ function titleise(camel) {
|
|
|
66
66
|
function shallowCompare(a, b) {
|
|
67
67
|
return Object.entries(a).every(([k, v]) => b[k] === v);
|
|
68
68
|
}
|
|
69
|
+
function shallowDiff(a, b) {
|
|
70
|
+
const from = Object.fromEntries(Object.entries(a).filter(([k, v]) => b[k] !== v));
|
|
71
|
+
const to = Object.fromEntries(Object.entries(b).filter(([k, _]) => from[k]));
|
|
72
|
+
return { from, to };
|
|
73
|
+
}
|
|
69
74
|
|
|
70
75
|
function setControlError(control, errorKey, errorValue) {
|
|
71
76
|
const currentErrors = control.errors || {};
|
|
@@ -182,8 +187,10 @@ const appDataPropertySetId = '34d46477-ad4b-47b4-b555-06358b92f60c';
|
|
|
182
187
|
const deviceDataPropertySetId = '7a32d851-5e89-46a6-a4b6-cca162dace29';
|
|
183
188
|
const propertyCodes = ['RecordingSession', 'Status', 'UserDetailChangeLog'];
|
|
184
189
|
class DetailEditComponent {
|
|
185
|
-
constructor(shared) {
|
|
190
|
+
constructor(shared, kvDiffers, itDiffers) {
|
|
186
191
|
this.shared = shared;
|
|
192
|
+
this.kvDiffers = kvDiffers;
|
|
193
|
+
this.itDiffers = itDiffers;
|
|
187
194
|
this.status = 'loading';
|
|
188
195
|
this.formGroup = new FormGroup({
|
|
189
196
|
dob: new FormControl('', [Validators.required, withinNYears(120, 'before')]),
|
|
@@ -235,7 +242,7 @@ class DetailEditComponent {
|
|
|
235
242
|
patient.age = getAge(mods.dob);
|
|
236
243
|
recordingSession.mealStart = globaliseDateTime(mods.mealStart);
|
|
237
244
|
recordingSession.mealEnd = globaliseDateTime(mods.mealEnd);
|
|
238
|
-
this.
|
|
245
|
+
this.logChange(mods);
|
|
239
246
|
return {
|
|
240
247
|
'Age': patient.age,
|
|
241
248
|
'RecordingSession': JSON.stringify(recordingSession),
|
|
@@ -243,55 +250,27 @@ class DetailEditComponent {
|
|
|
243
250
|
};
|
|
244
251
|
}
|
|
245
252
|
postDeviceData(devicePropertySetId, data) {
|
|
246
|
-
return this.shared.saveDeviceData(this.config.deviceDataModelId, this.deviceDataId, devicePropertySetId, this.config.owners[0]
|
|
253
|
+
return this.shared.saveDeviceData(this.config.deviceDataModelId, this.deviceDataId, devicePropertySetId, this.config.owners[0], data);
|
|
247
254
|
}
|
|
248
255
|
// patch the device data record with the modifications
|
|
249
256
|
saveModifications() {
|
|
250
257
|
const mods = this.formGroup.getRawValue();
|
|
251
258
|
const patchedDeviceData = this.integrateFields(mods, this.recordingSession);
|
|
252
|
-
const patchedUserData = Object.assign(this.
|
|
259
|
+
const patchedUserData = Object.assign(this.owner, { dateOfBirth: mods.dob });
|
|
253
260
|
this.status = 'sending';
|
|
254
261
|
forkJoin([
|
|
255
262
|
this.postDeviceData(appDataPropertySetId, patchedDeviceData),
|
|
256
|
-
this.shared.updateUser(this.config.owners[0]
|
|
263
|
+
this.shared.updateUser(this.config.owners[0], patchedUserData)
|
|
257
264
|
]).pipe(tap(() => this.regenReport())).subscribe();
|
|
258
265
|
}
|
|
259
|
-
|
|
260
|
-
const
|
|
261
|
-
const newChangeLog = {};
|
|
262
|
-
// Only include fields that have changed
|
|
263
|
-
for (const key in mods) {
|
|
264
|
-
if (this.initialFormState[key] !== mods[key]) {
|
|
265
|
-
prevChangeLog[key] = this.initialFormState[key];
|
|
266
|
-
newChangeLog[key] = mods[key];
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
const changeLog = {
|
|
266
|
+
logChange(mods) {
|
|
267
|
+
const entry = {
|
|
270
268
|
author: this.currentUser.emailAddress,
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
timestamp: new Date().toISOString()
|
|
269
|
+
timestamp: new Date().toISOString(),
|
|
270
|
+
...shallowDiff(this.initialFormState, mods)
|
|
274
271
|
};
|
|
275
|
-
this.detailChangeLog.push(
|
|
276
|
-
|
|
277
|
-
// get the device data record and initialise the form
|
|
278
|
-
loadDeviceData() {
|
|
279
|
-
this.shared.getDeviceData(this.config.deviceDataModelId, this.config.owners[0].userId, propertyCodes).subscribe({
|
|
280
|
-
next: (res) => {
|
|
281
|
-
this.deviceDataId = res.deviceDataId;
|
|
282
|
-
this.recordingSession = JSON.parse(res.data['RecordingSession'].value);
|
|
283
|
-
this.initialiseForm(this.extractFields(this.recordingSession));
|
|
284
|
-
// checking for undefined in case no changes have been logged yet
|
|
285
|
-
this.detailChangeLog = res.data['UserDetailChangeLog'] === undefined ? [] : res.data['UserDetailChangeLog'].value;
|
|
286
|
-
this.status = res.data['Status']?.value === 'Generating Report' ?
|
|
287
|
-
'generating' :
|
|
288
|
-
'success';
|
|
289
|
-
},
|
|
290
|
-
error: (err) => {
|
|
291
|
-
console.error(err);
|
|
292
|
-
this.status = "error";
|
|
293
|
-
}
|
|
294
|
-
});
|
|
272
|
+
this.detailChangeLog.push(entry);
|
|
273
|
+
console.log(this.detailChangeLog);
|
|
295
274
|
}
|
|
296
275
|
regenReport() {
|
|
297
276
|
this.postDeviceData(deviceDataPropertySetId, { 'Algorithmhasrun': false, 'AlgorithmRun': true }).subscribe(() => {
|
|
@@ -301,26 +280,65 @@ class DetailEditComponent {
|
|
|
301
280
|
resetModifications() {
|
|
302
281
|
this.formGroup.patchValue(this.initialFormState);
|
|
303
282
|
}
|
|
304
|
-
|
|
305
|
-
|
|
283
|
+
loadData(currentUserId, ownerId, deviceDataModelId) {
|
|
284
|
+
forkJoin([
|
|
285
|
+
this.shared.getUser(currentUserId),
|
|
286
|
+
this.shared.getUser(ownerId),
|
|
287
|
+
this.shared.getDeviceData(deviceDataModelId, ownerId, propertyCodes)
|
|
288
|
+
]).subscribe({
|
|
289
|
+
next: ([currentUser, owner, { deviceDataId, data: deviceData }]) => {
|
|
290
|
+
this.currentUser = currentUser;
|
|
291
|
+
this.owner = owner;
|
|
292
|
+
this.deviceDataId = deviceDataId;
|
|
293
|
+
this.recordingSession = JSON.parse(deviceData['RecordingSession'].value);
|
|
294
|
+
this.initialiseForm(this.extractFields(this.recordingSession));
|
|
295
|
+
// data field uninitialised for unmodified record
|
|
296
|
+
this.detailChangeLog = deviceData['UserDetailChangeLog']?.value ?? [];
|
|
297
|
+
this.status = deviceData['Status']?.value === 'Generating Report' ?
|
|
298
|
+
'generating' : 'success';
|
|
299
|
+
},
|
|
300
|
+
error: (err) => {
|
|
301
|
+
console.error(err);
|
|
302
|
+
this.status = "error";
|
|
303
|
+
}
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
init() {
|
|
307
|
+
if (!this.config?.currentUserId || !this.config.deviceDataModelId) {
|
|
308
|
+
this.status = 'cfgerror';
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
else if (!this.config?.owners?.[0]) {
|
|
306
312
|
this.status = 'nouser';
|
|
307
313
|
return;
|
|
308
314
|
}
|
|
309
|
-
this.
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
315
|
+
this.status = 'loading';
|
|
316
|
+
this.loadData(this.config.currentUserId, this.config.owners[0], this.config.deviceDataModelId);
|
|
317
|
+
}
|
|
318
|
+
// this should be called from the parent using the ViewChild attr
|
|
319
|
+
refresh() {
|
|
320
|
+
this.init();
|
|
321
|
+
}
|
|
322
|
+
// NOTE: there could be something wrong / unusual here but it seems to work ok
|
|
323
|
+
ngOnInit() {
|
|
324
|
+
if (this.config && !this.configDiffer)
|
|
325
|
+
this.configDiffer = this.kvDiffers.find(this.config).create();
|
|
326
|
+
if (this.config?.owners && !this.ownersDiffer)
|
|
327
|
+
this.ownersDiffer = this.itDiffers.find(this.config.owners).create();
|
|
328
|
+
}
|
|
329
|
+
ngDoCheck() {
|
|
330
|
+
const configChanges = this.configDiffer?.diff(this.config);
|
|
331
|
+
const ownersChanges = this.ownersDiffer?.diff(this.config?.owners);
|
|
332
|
+
if (configChanges || ownersChanges)
|
|
333
|
+
this.init();
|
|
316
334
|
}
|
|
317
335
|
}
|
|
318
|
-
DetailEditComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DetailEditComponent, deps: [{ token: i1.SharedService }], target: i0.ɵɵFactoryTarget.Component });
|
|
319
|
-
DetailEditComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: DetailEditComponent, selector: "lib-detail-edit", inputs: { config: "config" }, ngImport: i0, template: "<div class=\"wrapper\">\n <div class=\"status\" *ngIf=\"status === 'error'\">\n An error occured while trying to get the details.\n </div>\n <div class=\"status\" *ngIf=\"status === 'nouser'\">\n There is no user specified as the data owner.\n </div>\n <form *ngIf=\"status
|
|
336
|
+
DetailEditComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DetailEditComponent, deps: [{ token: i1.SharedService }, { token: i0.KeyValueDiffers }, { token: i0.IterableDiffers }], target: i0.ɵɵFactoryTarget.Component });
|
|
337
|
+
DetailEditComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: DetailEditComponent, selector: "lib-detail-edit", inputs: { config: "config" }, ngImport: i0, template: "<div class=\"wrapper\">\n <div class=\"status\" *ngIf=\"status === 'error'\">\n An error occured while trying to get the details.\n </div>\n <div class=\"status\" *ngIf=\"status === 'cfgerror'\">\n The widget has not been configured correctly, or is missing configuration information.\n </div>\n <div class=\"status\" *ngIf=\"status === 'nouser'\">\n There is no user specified as the data owner.\n </div>\n <form *ngIf=\"!status.includes('error') && status !== 'nouser'\" [formGroup]=\"formGroup\" (ngSubmit)=\"saveModifications()\">\n <div class=\"inputs\">\n <div class=\"form-row\">\n <label for=\"dob\">Date of Birth:</label>\n <input id=\"dob\" type=\"date\" formControlName=\"dob\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"weight\">Patient Weight (kg):</label>\n <input id=\"weight\" type=\"number\" formControlName=\"weight\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"height\">Patient Height (cm):</label>\n <input id=\"height\" type=\"number\" formControlName=\"height\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"mealStart\">Meal Start Time:</label>\n <input id=\"mealStart\" type=\"datetime-local\" formControlName=\"mealStart\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"mealEnd\">Meal End Time:</label>\n <input id=\"mealEnd\" type=\"datetime-local\" formControlName=\"mealEnd\">\n </div>\n </div>\n\n <div *ngIf=\"!formGroup.valid && formGroup.dirty\" class=\"errors\">\n <div *ngFor=\"let control of formGroup.controls | entries\">\n {{ parseInputErrors(control[0], control[1]) }}\n </div>\n </div>\n\n <div *ngIf=\"status === 'generating'\" class=\"info\">\n <div>The report is generating at the moment, check back later if you need to modify this entry.</div>\n </div>\n\n <div class=\"buttons\">\n <button type=\"button\" (click)=\"regenReport()\" [disabled]=\"status === 'sending' || status === 'generating' || status === 'loading'\">Regenerate Report</button>\n <button type=\"button\" (click)=\"resetModifications()\" [disabled]=\"status === 'sending' || status === 'generating' || formGroup.pristine\">Cancel Modification</button>\n <button type=\"submit\" [disabled]=\"status === 'sending' || status === 'generating' || !formGroup.valid || formGroup.pristine\">Save Details</button>\n </div>\n </form>\n</div>\n", styles: [".wrapper{width:100%;height:100%}.status{font-size:2rem;margin:5rem auto;text-align:center}form{display:flex;flex-direction:column;padding:2rem;gap:2rem;font-size:.9rem;max-width:70rem;margin:0 auto}form .inputs{display:flex;flex-flow:row wrap;gap:1rem 3rem}form .inputs .form-row{display:flex;gap:1rem;align-items:center;flex:1 0 calc(50% - 3rem);min-width:400px}form .inputs .form-row label{min-width:9rem}form .inputs .form-row input{background:#f5f5f6;height:36px;border:none;padding-inline:10px;flex-grow:1}form.ng-dirty .form-row .ng-invalid{outline:1px auto red}form .buttons{display:flex;gap:1rem}form .buttons button{padding:.5rem 1rem;height:36px;border:none;font-size:inherit;background:#f5f5f6}form .buttons button:not([disabled]){cursor:pointer}form .buttons button[type=submit]{background:#242C69;color:#fff}form .buttons button[disabled]{background:#fafafa;cursor:not-allowed}form .buttons button[type=submit][disabled]{background:#444C89}form .buttons button:first-child{margin-right:auto}.errors{padding:1rem;background:#fee;border:2px solid red;border-radius:4px;color:red}.info{padding:1rem;background:#eef;border:2px solid #242C69;border-radius:4px;color:#242c69}\n"], dependencies: [{ kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: EntriesPipe, name: "entries" }] });
|
|
320
338
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DetailEditComponent, decorators: [{
|
|
321
339
|
type: Component,
|
|
322
|
-
args: [{ selector: 'lib-detail-edit', template: "<div class=\"wrapper\">\n <div class=\"status\" *ngIf=\"status === 'error'\">\n An error occured while trying to get the details.\n </div>\n <div class=\"status\" *ngIf=\"status === 'nouser'\">\n There is no user specified as the data owner.\n </div>\n <form *ngIf=\"status
|
|
323
|
-
}], ctorParameters: function () { return [{ type: i1.SharedService }]; }, propDecorators: { config: [{
|
|
340
|
+
args: [{ selector: 'lib-detail-edit', template: "<div class=\"wrapper\">\n <div class=\"status\" *ngIf=\"status === 'error'\">\n An error occured while trying to get the details.\n </div>\n <div class=\"status\" *ngIf=\"status === 'cfgerror'\">\n The widget has not been configured correctly, or is missing configuration information.\n </div>\n <div class=\"status\" *ngIf=\"status === 'nouser'\">\n There is no user specified as the data owner.\n </div>\n <form *ngIf=\"!status.includes('error') && status !== 'nouser'\" [formGroup]=\"formGroup\" (ngSubmit)=\"saveModifications()\">\n <div class=\"inputs\">\n <div class=\"form-row\">\n <label for=\"dob\">Date of Birth:</label>\n <input id=\"dob\" type=\"date\" formControlName=\"dob\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"weight\">Patient Weight (kg):</label>\n <input id=\"weight\" type=\"number\" formControlName=\"weight\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"height\">Patient Height (cm):</label>\n <input id=\"height\" type=\"number\" formControlName=\"height\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"mealStart\">Meal Start Time:</label>\n <input id=\"mealStart\" type=\"datetime-local\" formControlName=\"mealStart\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"mealEnd\">Meal End Time:</label>\n <input id=\"mealEnd\" type=\"datetime-local\" formControlName=\"mealEnd\">\n </div>\n </div>\n\n <div *ngIf=\"!formGroup.valid && formGroup.dirty\" class=\"errors\">\n <div *ngFor=\"let control of formGroup.controls | entries\">\n {{ parseInputErrors(control[0], control[1]) }}\n </div>\n </div>\n\n <div *ngIf=\"status === 'generating'\" class=\"info\">\n <div>The report is generating at the moment, check back later if you need to modify this entry.</div>\n </div>\n\n <div class=\"buttons\">\n <button type=\"button\" (click)=\"regenReport()\" [disabled]=\"status === 'sending' || status === 'generating' || status === 'loading'\">Regenerate Report</button>\n <button type=\"button\" (click)=\"resetModifications()\" [disabled]=\"status === 'sending' || status === 'generating' || formGroup.pristine\">Cancel Modification</button>\n <button type=\"submit\" [disabled]=\"status === 'sending' || status === 'generating' || !formGroup.valid || formGroup.pristine\">Save Details</button>\n </div>\n </form>\n</div>\n", styles: [".wrapper{width:100%;height:100%}.status{font-size:2rem;margin:5rem auto;text-align:center}form{display:flex;flex-direction:column;padding:2rem;gap:2rem;font-size:.9rem;max-width:70rem;margin:0 auto}form .inputs{display:flex;flex-flow:row wrap;gap:1rem 3rem}form .inputs .form-row{display:flex;gap:1rem;align-items:center;flex:1 0 calc(50% - 3rem);min-width:400px}form .inputs .form-row label{min-width:9rem}form .inputs .form-row input{background:#f5f5f6;height:36px;border:none;padding-inline:10px;flex-grow:1}form.ng-dirty .form-row .ng-invalid{outline:1px auto red}form .buttons{display:flex;gap:1rem}form .buttons button{padding:.5rem 1rem;height:36px;border:none;font-size:inherit;background:#f5f5f6}form .buttons button:not([disabled]){cursor:pointer}form .buttons button[type=submit]{background:#242C69;color:#fff}form .buttons button[disabled]{background:#fafafa;cursor:not-allowed}form .buttons button[type=submit][disabled]{background:#444C89}form .buttons button:first-child{margin-right:auto}.errors{padding:1rem;background:#fee;border:2px solid red;border-radius:4px;color:red}.info{padding:1rem;background:#eef;border:2px solid #242C69;border-radius:4px;color:#242c69}\n"] }]
|
|
341
|
+
}], ctorParameters: function () { return [{ type: i1.SharedService }, { type: i0.KeyValueDiffers }, { type: i0.IterableDiffers }]; }, propDecorators: { config: [{
|
|
324
342
|
type: Input
|
|
325
343
|
}] } });
|
|
326
344
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alimetry-detail-edit.mjs","sources":["../../../projects/detail-edit/src/lib/detail-edit.service.ts","../../../projects/detail-edit/src/lib/utils.ts","../../../projects/detail-edit/src/lib/validators.ts","../../../projects/detail-edit/src/lib/entries.pipe.ts","../../../projects/detail-edit/src/lib/detail-edit.component.ts","../../../projects/detail-edit/src/lib/detail-edit.component.html","../../../projects/detail-edit/src/lib/detail-edit.module.ts","../../../projects/detail-edit/src/public-api.ts","../../../projects/detail-edit/src/alimetry-detail-edit.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class DetailEditService {\n\n constructor() { }\n}\n","// strip the timezone offset to create format usable by <input>\nexport function localiseDateTime(datetime: string) {\n const date = new Date(datetime);\n\n const year = date.getFullYear(); const month = (date.getMonth() + 1).toString().padStart(2, '0');\n const day = date.getDate().toString().padStart(2, '0');\n const hour = date.getHours().toString().padStart(2, '0');\n const minute = date.getMinutes().toString().padStart(2, '0');\n const second = date.getSeconds().toString().padStart(2, '0');\n\n return `${year}-${month}-${day}T${hour}:${minute}:${second}`;\n}\n\n// reconstruct original ISO format\nexport function globaliseDateTime(datetime: string) {\n const date = new Date(datetime);\n\n const offset = -date.getTimezoneOffset();\n const offsetAbs = Math.abs(offset);\n\n const sign = offset >= 0 ? '+' : '-';\n const hours = String(Math.floor(offsetAbs / 60)).padStart(2, '0');\n const minutes = String(offsetAbs % 60).padStart(2, '0');\n const offsetString = `${sign}${hours}:${minutes}`;\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const hour = String(date.getHours()).padStart(2, '0');\n const minute = String(date.getMinutes()).padStart(2, '0');\n const second = String(date.getSeconds()).padStart(2, '0');\n\n const datePart = `${year}-${month}-${day}`;\n const timePart = `${hour}:${minute}:${second}.000`;\n\n return `${datePart}T${timePart}${offsetString}`;\n}\n\nexport function getAge(dob: string) {\n const then = new Date(dob);\n const now = new Date();\n\n let age = now.getFullYear() - then.getFullYear();\n\n if (now.getMonth() < then.getMonth() ||\n (now.getMonth() === then.getMonth() && now.getDate() < then.getDate())) {\n age--;\n }\n\n return age;\n}\n\nexport function titleise(camel: string) {\n let spaced = camel.replace(/(?=[A-Z])/g, ' ');\n return spaced.toLowerCase().replace(/\\b\\w/g, ch => ch.toUpperCase());\n}\n\nexport function shallowCompare(a: object, b: object) {\n return Object.entries(a).every(([k, v]) => b[k] === v);\n}\n","import { AbstractControl, FormControl, FormGroup, ValidationErrors, ValidatorFn } from \"@angular/forms\";\nimport { titleise } from \"./utils\";\n\nfunction setControlError(control: AbstractControl, errorKey: string, errorValue: any) {\n const currentErrors = control.errors || {};\n if (currentErrors[errorKey]) return;\n control.setErrors({ ...currentErrors, [errorKey]: errorValue });\n}\n\nfunction clearControlError(control: AbstractControl, errorKey: string) {\n const currentErrors = control.errors || {};\n if (!currentErrors[errorKey]) return;\n control.setErrors({ ...currentErrors, [errorKey]: null });\n}\n\nexport function dateComparison(a: string, b: string, comparator: 'before' | 'after') {\n return function(control: AbstractControl<any, any>): ValidationErrors | null {\n if (!(control instanceof FormGroup)) return null;\n\n const formGroup = control as FormGroup;\n\n const aControl = formGroup.get(a);\n const bControl = formGroup.get(b);\n\n if (!aControl?.value || !bControl?.value) {\n clearControlError(aControl, 'dateRange');\n return null;\n }\n\n const aDate = new Date(aControl.value);\n const bDate = new Date(bControl.value);\n\n const hasError = (\n comparator === 'after' && aDate <= bDate ||\n comparator === 'before' && aDate >= bDate\n );\n\n if (hasError) {\n setControlError(aControl, 'dateRange', { against: b, comparator });\n return { dateRange: true };\n }\n\n clearControlError(aControl, 'dateRange');\n return null;\n }\n}\n\nexport function withinNYears(n: number, dir: 'both' | 'before' | 'after' = 'both', of?: Date): ValidatorFn {\n return function(control: AbstractControl): ValidationErrors | null {\n const timestamp = control?.value;\n if (!timestamp || isNaN(new Date(timestamp).getTime())) return null;\n\n const date = new Date(timestamp);\n const against = of ?? new Date();\n\n const min = new Date(against)\n min.setFullYear(against.getFullYear() - n);\n const max = new Date(against)\n max.setFullYear(against.getFullYear() + n);\n\n let isValid = false;\n if (dir === 'after') isValid = date < max && date > against;\n else if (dir === 'before') isValid = date > min && date < against;\n else isValid = date > min && date < max;\n\n return isValid ? null : { notWithinYears: { n, against, dir } };\n }\n}\n\nexport function withinNHours(n: number, dir: 'both' | 'before' | 'after' = 'both', of?: Date): ValidatorFn {\n return function(control: AbstractControl): ValidationErrors | null {\n const timestamp = control?.value;\n if (!timestamp || isNaN(new Date(timestamp).getTime())) return null;\n\n const date = new Date(timestamp);\n const against = of ?? new Date();\n\n const min = new Date(against)\n min.setHours(against.getHours() - n);\n const max = new Date(against)\n max.setHours(against.getHours() + n);\n\n let isValid = false;\n if (dir === 'after') isValid = date < max && date > against;\n else if (dir === 'before') isValid = date > min && date < against;\n else isValid = date > min && date < max;\n\n return isValid ? null : { notWithinHours: { n, against, dir } };\n }\n}\n\n// translate validation errors into human readable strings\nexport function translateError(name: string, control: AbstractControl) {\n const { errors } = control;\n\n if (control.hasError('required'))\n return `${titleise(name)} is a required value.`;\n else if (control.hasError('min'))\n return `${titleise(name)} needs to be a minimum of ${errors.min.min}.`;\n else if (control.hasError('max'))\n return `${titleise(name)} needs to be a maximum of ${errors.max.max}.`;\n else if (control.hasError('future'))\n return `${titleise(name)} needs to be in the past.`;\n else if (control.hasError('dateRange'))\n return `${titleise(name)} needs to be ${errors.dateRange.comparator} ${titleise(errors.dateRange.against)}.`;\n else if (control.hasError('notWithinYears'))\n return `${titleise(name)} needs to be within ${errors.notWithinYears.n} years of ${errors.notWithinYears.against}`;\n else if (control.hasError('notWithinHours'))\n return `${titleise(name)} needs to be within ${errors.notWithinHours.n} hours of ${errors.notWithinHours.against}`;\n\n return null;\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({\n name: 'entries'\n})\nexport class EntriesPipe implements PipeTransform {\n transform(value: object): [string, any][] {\n return Object.entries(value);\n }\n}\n","import { Component, Input } from '@angular/core';\nimport { AbstractControl, FormControl, FormGroup, Validators } from '@angular/forms';\nimport { forkJoin, tap } from 'rxjs';\nimport { Config, SharedService, User } from 'shared';\nimport { getAge, globaliseDateTime, localiseDateTime, shallowCompare } from './utils';\nimport { dateComparison, withinNYears, withinNHours, translateError } from './validators';\n\nconst appDataPropertySetId = '34d46477-ad4b-47b4-b555-06358b92f60c';\nconst deviceDataPropertySetId = '7a32d851-5e89-46a6-a4b6-cca162dace29';\nconst propertyCodes = ['RecordingSession', 'Status', 'UserDetailChangeLog'];\n\n@Component({\n selector: 'lib-detail-edit', templateUrl: './detail-edit.component.html',\n styleUrls: ['./detail-edit.component.css']\n})\nexport class DetailEditComponent {\n @Input() config!: Config;\n\n status: 'error' | 'loading' | 'success' | 'generating' | 'sending' | 'nouser' = 'loading';\n\n // populated by load request\n private deviceDataId: string;\n private recordingSession: object;\n private recordingStart: string;\n private initialFormState: object;\n private detailChangeLog: object[];\n private currentUser: User;\n private owner: User;\n\n formGroup = new FormGroup({\n dob: new FormControl<string>('', [Validators.required, withinNYears(120, 'before')]),\n height: new FormControl<number>(0, [Validators.required, Validators.min(30), Validators.max(272)]),\n weight: new FormControl<number>(0, [Validators.required, Validators.min(1), Validators.max(635)]),\n mealStart: new FormControl<string>('', [Validators.required]),\n mealEnd: new FormControl<string>('', [Validators.required])\n }, [\n dateComparison('mealEnd', 'mealStart', 'after'),\n dateComparison('mealStart', 'dob', 'after'),\n ]);\n\n constructor(private shared: SharedService) { }\n\n parseInputErrors(name: string, control: AbstractControl) {\n return translateError(name, control);\n }\n\n // make sure than modifications that don't actually differ from the current are marked as such\n private monitorFormChanges() {\n this.formGroup.valueChanges.subscribe(current => {\n if (shallowCompare(current, this.initialFormState)) {\n this.formGroup.markAsPristine();\n }\n })\n }\n\n // handle the relevant data from the response body\n private extractFields(recordingSession: Record<string, any>) {\n const { patient, mealStart, mealEnd, recordingStart } = recordingSession;\n this.recordingStart = recordingStart;\n\n return {\n dob: this.owner.dateOfBirth,\n height: patient.height,\n weight: patient.weight,\n mealStart: localiseDateTime(mealStart),\n mealEnd: localiseDateTime(mealEnd)\n }\n }\n\n private initialiseForm(state: object) {\n this.formGroup.patchValue(state);\n this.formGroup.markAsPristine();\n\n this.formGroup.get('mealStart').addValidators(withinNHours(24, 'after', new Date(this.recordingStart)));\n this.formGroup.get('mealEnd').addValidators(withinNHours(24, 'after', new Date(this.recordingStart)));\n\n this.initialFormState = state; // save this for use in resets\n this.monitorFormChanges();\n }\n\n // construct a patch object for the save request\n private integrateFields(mods: typeof this.formGroup.value, recordingSession: Record<string, any>) {\n const { patient } = recordingSession;\n patient.height = mods.height;\n patient.weight = mods.weight;\n patient.age = getAge(mods.dob);\n\n recordingSession.mealStart = globaliseDateTime(mods.mealStart);\n recordingSession.mealEnd = globaliseDateTime(mods.mealEnd);\n\n this.appendChangeLog(mods);\n\n return {\n 'Age': patient.age,\n 'RecordingSession': JSON.stringify(recordingSession),\n 'UserDetailChangeLog': this.detailChangeLog\n }\n }\n\n private postDeviceData(devicePropertySetId: string, data: object) {\n return this.shared.saveDeviceData(\n this.config.deviceDataModelId,\n this.deviceDataId,\n devicePropertySetId,\n this.config.owners[0].userId,\n data\n );\n }\n\n // patch the device data record with the modifications\n saveModifications() {\n const mods = this.formGroup.getRawValue();\n const patchedDeviceData = this.integrateFields(mods, this.recordingSession);\n const patchedUserData = Object.assign(this.config.owners[0], { dateOfBirth: mods.dob });\n\n this.status = 'sending';\n forkJoin([\n this.postDeviceData(appDataPropertySetId, patchedDeviceData),\n this.shared.updateUser(this.config.owners[0].userId, patchedUserData)\n ]).pipe(\n tap(() => this.regenReport())\n ).subscribe();\n }\n\n private appendChangeLog(mods: typeof this.formGroup.value) {\n const prevChangeLog: Partial<typeof this.formGroup.value> = {};\n const newChangeLog: Partial<typeof this.formGroup.value> = {};\n\n // Only include fields that have changed\n for (const key in mods) {\n if (this.initialFormState[key] !== mods[key]) {\n prevChangeLog[key] = this.initialFormState[key];\n newChangeLog[key] = mods[key];\n }\n }\n\n const changeLog = {\n author: this.currentUser.emailAddress,\n prevChangeLog: prevChangeLog,\n newChangeLog: newChangeLog,\n timestamp: new Date().toISOString()\n }\n\n this.detailChangeLog.push(changeLog);\n }\n\n // get the device data record and initialise the form\n private loadDeviceData() {\n this.shared.getDeviceData(\n this.config.deviceDataModelId,\n this.config.owners[0].userId,\n propertyCodes\n ).subscribe({\n next: (res) => {\n this.deviceDataId = res.deviceDataId;\n this.recordingSession = JSON.parse(res.data['RecordingSession'].value);\n this.initialiseForm(this.extractFields(this.recordingSession));\n // checking for undefined in case no changes have been logged yet\n this.detailChangeLog = res.data['UserDetailChangeLog'] === undefined ? [] : res.data['UserDetailChangeLog'].value;\n\n this.status = res.data['Status']?.value === 'Generating Report' ?\n 'generating' :\n 'success';\n },\n error: (err) => {\n console.error(err);\n this.status = \"error\";\n }\n });\n }\n\n regenReport() {\n this.postDeviceData(\n deviceDataPropertySetId,\n { 'Algorithmhasrun': false, 'AlgorithmRun': true }\n ).subscribe(() => {\n this.status = 'generating'; // assume report starts generating immediately\n })\n }\n\n resetModifications() {\n this.formGroup.patchValue(this.initialFormState);\n }\n\n ngOnInit() {\n if (!this.config?.owners?.[0]?.userId) {\n this.status = 'nouser';\n return;\n }\n this.shared.getUser(this.config.currentUser.userId).subscribe(user => {\n this.currentUser = user;\n });\n\n this.shared.getUser(this.config.owners[0].userId).subscribe(owner => {\n this.owner = owner;\n });\n\n this.loadDeviceData();\n }\n}\n","<div class=\"wrapper\">\n <div class=\"status\" *ngIf=\"status === 'error'\">\n An error occured while trying to get the details.\n </div>\n <div class=\"status\" *ngIf=\"status === 'nouser'\">\n There is no user specified as the data owner.\n </div>\n <form *ngIf=\"status !== 'error' && status !== 'nouser'\" [formGroup]=\"formGroup\" (ngSubmit)=\"saveModifications()\">\n <div class=\"inputs\">\n <div class=\"form-row\">\n <label for=\"dob\">Date of Birth:</label>\n <input id=\"dob\" type=\"date\" formControlName=\"dob\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"weight\">Patient Weight (kg):</label>\n <input id=\"weight\" type=\"number\" formControlName=\"weight\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"height\">Patient Height (cm):</label>\n <input id=\"height\" type=\"number\" formControlName=\"height\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"mealStart\">Meal Start Time:</label>\n <input id=\"mealStart\" type=\"datetime-local\" formControlName=\"mealStart\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"mealEnd\">Meal End Time:</label>\n <input id=\"mealEnd\" type=\"datetime-local\" formControlName=\"mealEnd\">\n </div>\n </div>\n\n <div *ngIf=\"!formGroup.valid && formGroup.dirty\" class=\"errors\">\n <div *ngFor=\"let control of formGroup.controls | entries\">\n {{ parseInputErrors(control[0], control[1]) }}\n </div>\n </div>\n\n <div *ngIf=\"status === 'generating'\" class=\"info\">\n <div>The report is generating at the moment, check back later if you need to modify this entry.</div>\n </div>\n\n <div class=\"buttons\">\n <button type=\"button\" (click)=\"regenReport()\" [disabled]=\"status === 'sending' || status === 'generating' || status === 'loading'\">Regenerate Report</button>\n <button type=\"button\" (click)=\"resetModifications()\" [disabled]=\"status === 'sending' || status === 'generating' || formGroup.pristine\">Cancel Modification</button>\n <button type=\"submit\" [disabled]=\"status === 'sending' || status === 'generating' || !formGroup.valid || formGroup.pristine\">Save Details</button>\n </div>\n </form>\n</div>\n","import { CommonModule, JsonPipe } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { DetailEditComponent } from './detail-edit.component';\nimport { EntriesPipe } from './entries.pipe';\n\n\n\n@NgModule({\n declarations: [\n DetailEditComponent,\n EntriesPipe\n ],\n imports: [\n JsonPipe,\n ReactiveFormsModule,\n CommonModule\n ],\n exports: [\n DetailEditComponent\n ]\n})\nexport class DetailEditModule { }\n","/*\n * Public API Surface of detail-edit\n */\n\nexport * from './lib/detail-edit.service';\nexport * from './lib/detail-edit.component';\nexport * from './lib/detail-edit.module';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i4.EntriesPipe"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"alimetry-detail-edit.mjs","sources":["../../../projects/detail-edit/src/lib/detail-edit.service.ts","../../../projects/detail-edit/src/lib/utils.ts","../../../projects/detail-edit/src/lib/validators.ts","../../../projects/detail-edit/src/lib/entries.pipe.ts","../../../projects/detail-edit/src/lib/detail-edit.component.ts","../../../projects/detail-edit/src/lib/detail-edit.component.html","../../../projects/detail-edit/src/lib/detail-edit.module.ts","../../../projects/detail-edit/src/public-api.ts","../../../projects/detail-edit/src/alimetry-detail-edit.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class DetailEditService {\n\n constructor() { }\n}\n","// strip the timezone offset to create format usable by <input>\nexport function localiseDateTime(datetime: string) {\n const date = new Date(datetime);\n\n const year = date.getFullYear(); const month = (date.getMonth() + 1).toString().padStart(2, '0');\n const day = date.getDate().toString().padStart(2, '0');\n const hour = date.getHours().toString().padStart(2, '0');\n const minute = date.getMinutes().toString().padStart(2, '0');\n const second = date.getSeconds().toString().padStart(2, '0');\n\n return `${year}-${month}-${day}T${hour}:${minute}:${second}`;\n}\n\n// reconstruct original ISO format\nexport function globaliseDateTime(datetime: string) {\n const date = new Date(datetime);\n\n const offset = -date.getTimezoneOffset();\n const offsetAbs = Math.abs(offset);\n\n const sign = offset >= 0 ? '+' : '-';\n const hours = String(Math.floor(offsetAbs / 60)).padStart(2, '0');\n const minutes = String(offsetAbs % 60).padStart(2, '0');\n const offsetString = `${sign}${hours}:${minutes}`;\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const hour = String(date.getHours()).padStart(2, '0');\n const minute = String(date.getMinutes()).padStart(2, '0');\n const second = String(date.getSeconds()).padStart(2, '0');\n\n const datePart = `${year}-${month}-${day}`;\n const timePart = `${hour}:${minute}:${second}.000`;\n\n return `${datePart}T${timePart}${offsetString}`;\n}\n\nexport function getAge(dob: string) {\n const then = new Date(dob);\n const now = new Date();\n\n let age = now.getFullYear() - then.getFullYear();\n\n if (now.getMonth() < then.getMonth() ||\n (now.getMonth() === then.getMonth() && now.getDate() < then.getDate())) {\n age--;\n }\n\n return age;\n}\n\nexport function titleise(camel: string) {\n let spaced = camel.replace(/(?=[A-Z])/g, ' ');\n return spaced.toLowerCase().replace(/\\b\\w/g, ch => ch.toUpperCase());\n}\n\nexport function shallowCompare(a: object, b: object) {\n return Object.entries(a).every(([k, v]) => b[k] === v);\n}\n\nexport function shallowDiff(a: object, b: object) {\n const from = Object.fromEntries(Object.entries(a).filter(([k, v]) => b[k] !== v));\n const to = Object.fromEntries(Object.entries(b).filter(([k, _]) => from[k]));\n return { from, to };\n}\n","import { AbstractControl, FormControl, FormGroup, ValidationErrors, ValidatorFn } from \"@angular/forms\";\nimport { titleise } from \"./utils\";\n\nfunction setControlError(control: AbstractControl, errorKey: string, errorValue: any) {\n const currentErrors = control.errors || {};\n if (currentErrors[errorKey]) return;\n control.setErrors({ ...currentErrors, [errorKey]: errorValue });\n}\n\nfunction clearControlError(control: AbstractControl, errorKey: string) {\n const currentErrors = control.errors || {};\n if (!currentErrors[errorKey]) return;\n control.setErrors({ ...currentErrors, [errorKey]: null });\n}\n\nexport function dateComparison(a: string, b: string, comparator: 'before' | 'after') {\n return function(control: AbstractControl<any, any>): ValidationErrors | null {\n if (!(control instanceof FormGroup)) return null;\n\n const formGroup = control as FormGroup;\n\n const aControl = formGroup.get(a);\n const bControl = formGroup.get(b);\n\n if (!aControl?.value || !bControl?.value) {\n clearControlError(aControl, 'dateRange');\n return null;\n }\n\n const aDate = new Date(aControl.value);\n const bDate = new Date(bControl.value);\n\n const hasError = (\n comparator === 'after' && aDate <= bDate ||\n comparator === 'before' && aDate >= bDate\n );\n\n if (hasError) {\n setControlError(aControl, 'dateRange', { against: b, comparator });\n return { dateRange: true };\n }\n\n clearControlError(aControl, 'dateRange');\n return null;\n }\n}\n\nexport function withinNYears(n: number, dir: 'both' | 'before' | 'after' = 'both', of?: Date): ValidatorFn {\n return function(control: AbstractControl): ValidationErrors | null {\n const timestamp = control?.value;\n if (!timestamp || isNaN(new Date(timestamp).getTime())) return null;\n\n const date = new Date(timestamp);\n const against = of ?? new Date();\n\n const min = new Date(against)\n min.setFullYear(against.getFullYear() - n);\n const max = new Date(against)\n max.setFullYear(against.getFullYear() + n);\n\n let isValid = false;\n if (dir === 'after') isValid = date < max && date > against;\n else if (dir === 'before') isValid = date > min && date < against;\n else isValid = date > min && date < max;\n\n return isValid ? null : { notWithinYears: { n, against, dir } };\n }\n}\n\nexport function withinNHours(n: number, dir: 'both' | 'before' | 'after' = 'both', of?: Date): ValidatorFn {\n return function(control: AbstractControl): ValidationErrors | null {\n const timestamp = control?.value;\n if (!timestamp || isNaN(new Date(timestamp).getTime())) return null;\n\n const date = new Date(timestamp);\n const against = of ?? new Date();\n\n const min = new Date(against)\n min.setHours(against.getHours() - n);\n const max = new Date(against)\n max.setHours(against.getHours() + n);\n\n let isValid = false;\n if (dir === 'after') isValid = date < max && date > against;\n else if (dir === 'before') isValid = date > min && date < against;\n else isValid = date > min && date < max;\n\n return isValid ? null : { notWithinHours: { n, against, dir } };\n }\n}\n\n// translate validation errors into human readable strings\nexport function translateError(name: string, control: AbstractControl) {\n const { errors } = control;\n\n if (control.hasError('required'))\n return `${titleise(name)} is a required value.`;\n else if (control.hasError('min'))\n return `${titleise(name)} needs to be a minimum of ${errors.min.min}.`;\n else if (control.hasError('max'))\n return `${titleise(name)} needs to be a maximum of ${errors.max.max}.`;\n else if (control.hasError('future'))\n return `${titleise(name)} needs to be in the past.`;\n else if (control.hasError('dateRange'))\n return `${titleise(name)} needs to be ${errors.dateRange.comparator} ${titleise(errors.dateRange.against)}.`;\n else if (control.hasError('notWithinYears'))\n return `${titleise(name)} needs to be within ${errors.notWithinYears.n} years of ${errors.notWithinYears.against}`;\n else if (control.hasError('notWithinHours'))\n return `${titleise(name)} needs to be within ${errors.notWithinHours.n} hours of ${errors.notWithinHours.against}`;\n\n return null;\n}\n","import { Pipe, PipeTransform } from '@angular/core';\n\n@Pipe({\n name: 'entries'\n})\nexport class EntriesPipe implements PipeTransform {\n transform(value: object): [string, any][] {\n return Object.entries(value);\n }\n}\n","import { Component, DoCheck, Input, KeyValueDiffers, KeyValueDiffer, IterableDiffer, IterableDiffers } from '@angular/core';\nimport { AbstractControl, FormControl, FormGroup, Validators } from '@angular/forms';\nimport { forkJoin, tap } from 'rxjs';\nimport { Config, SharedService, User } from 'alimetry-shared';\nimport { getAge, globaliseDateTime, localiseDateTime, shallowCompare, shallowDiff } from './utils';\nimport { dateComparison, withinNYears, withinNHours, translateError } from './validators';\n\nconst appDataPropertySetId = '34d46477-ad4b-47b4-b555-06358b92f60c';\nconst deviceDataPropertySetId = '7a32d851-5e89-46a6-a4b6-cca162dace29';\nconst propertyCodes = ['RecordingSession', 'Status', 'UserDetailChangeLog'];\n\ninterface FormValue {\n dob: string,\n height: number,\n weight: number,\n mealStart: string,\n mealEnd: string\n}\n\ninterface Change {\n timestamp: string,\n author: string,\n from: Partial<FormValue>,\n to: Partial<FormValue>\n}\n\n@Component({\n selector: 'lib-detail-edit',\n templateUrl: './detail-edit.component.html',\n styleUrls: ['./detail-edit.component.css']\n})\nexport class DetailEditComponent implements DoCheck {\n @Input() config!: Config;\n\n private configDiffer?: KeyValueDiffer<keyof Config, any>;\n private ownersDiffer?: IterableDiffer<string>;\n\n status: 'error' | 'cfgerror' | 'loading' | 'success' | 'generating' | 'sending' | 'nouser' = 'loading';\n\n // device data populated by load request\n private deviceDataId: string;\n private recordingSession: object;\n private recordingStart: string;\n private initialFormState: object;\n\n // user data expanded from ids passed in config\n private currentUser: User;\n private owner: User;\n\n private detailChangeLog: Change[];\n\n formGroup = new FormGroup({\n dob: new FormControl<string>('', [Validators.required, withinNYears(120, 'before')]),\n height: new FormControl<number>(0, [Validators.required, Validators.min(30), Validators.max(272)]),\n weight: new FormControl<number>(0, [Validators.required, Validators.min(1), Validators.max(635)]),\n mealStart: new FormControl<string>('', [Validators.required]),\n mealEnd: new FormControl<string>('', [Validators.required])\n }, [\n dateComparison('mealEnd', 'mealStart', 'after'),\n dateComparison('mealStart', 'dob', 'after'),\n ]);\n\n constructor(private shared: SharedService, private kvDiffers: KeyValueDiffers, private itDiffers: IterableDiffers) { }\n\n parseInputErrors(name: string, control: AbstractControl) {\n return translateError(name, control);\n }\n\n // make sure than modifications that don't actually differ from the current are marked as such\n private monitorFormChanges() {\n this.formGroup.valueChanges.subscribe(current => {\n if (shallowCompare(current, this.initialFormState)) {\n this.formGroup.markAsPristine();\n }\n })\n }\n\n // handle the relevant data from the response body\n private extractFields(recordingSession: Record<string, any>) {\n const { patient, mealStart, mealEnd, recordingStart } = recordingSession;\n this.recordingStart = recordingStart;\n\n return {\n dob: this.owner.dateOfBirth,\n height: patient.height,\n weight: patient.weight,\n mealStart: localiseDateTime(mealStart),\n mealEnd: localiseDateTime(mealEnd)\n }\n }\n\n private initialiseForm(state: object) {\n this.formGroup.patchValue(state);\n this.formGroup.markAsPristine();\n\n this.formGroup.get('mealStart').addValidators(withinNHours(24, 'after', new Date(this.recordingStart)));\n this.formGroup.get('mealEnd').addValidators(withinNHours(24, 'after', new Date(this.recordingStart)));\n\n this.initialFormState = state; // save this for use in resets\n this.monitorFormChanges();\n }\n\n // construct a patch object for the save request\n private integrateFields(mods: FormValue, recordingSession: Record<string, any>) {\n const { patient } = recordingSession;\n patient.height = mods.height;\n patient.weight = mods.weight;\n patient.age = getAge(mods.dob);\n\n recordingSession.mealStart = globaliseDateTime(mods.mealStart);\n recordingSession.mealEnd = globaliseDateTime(mods.mealEnd);\n\n this.logChange(mods);\n\n return {\n 'Age': patient.age,\n 'RecordingSession': JSON.stringify(recordingSession),\n 'UserDetailChangeLog': this.detailChangeLog\n }\n }\n\n private postDeviceData(devicePropertySetId: string, data: object) {\n return this.shared.saveDeviceData(\n this.config.deviceDataModelId,\n this.deviceDataId,\n devicePropertySetId,\n this.config.owners[0],\n data\n );\n }\n\n // patch the device data record with the modifications\n saveModifications() {\n const mods = this.formGroup.getRawValue();\n const patchedDeviceData = this.integrateFields(mods, this.recordingSession);\n const patchedUserData = Object.assign(this.owner, { dateOfBirth: mods.dob });\n\n this.status = 'sending';\n forkJoin([\n this.postDeviceData(appDataPropertySetId, patchedDeviceData),\n this.shared.updateUser(this.config.owners[0], patchedUserData)\n ]).pipe(\n tap(() => this.regenReport())\n ).subscribe();\n }\n\n private logChange(mods: FormValue) {\n const entry = {\n author: this.currentUser.emailAddress,\n timestamp: new Date().toISOString(),\n ...shallowDiff(this.initialFormState, mods)\n }\n\n this.detailChangeLog.push(entry);\n\n console.log(this.detailChangeLog);\n }\n\n regenReport() {\n this.postDeviceData(\n deviceDataPropertySetId,\n { 'Algorithmhasrun': false, 'AlgorithmRun': true }\n ).subscribe(() => {\n this.status = 'generating'; // assume report starts generating immediately\n })\n }\n\n resetModifications() {\n this.formGroup.patchValue(this.initialFormState);\n }\n\n private loadData(currentUserId: string, ownerId: string, deviceDataModelId: string) {\n forkJoin([\n this.shared.getUser(currentUserId),\n this.shared.getUser(ownerId),\n this.shared.getDeviceData(deviceDataModelId, ownerId, propertyCodes)\n ]).subscribe({\n next: ([currentUser, owner, { deviceDataId, data: deviceData }]) => {\n this.currentUser = currentUser;\n this.owner = owner;\n this.deviceDataId = deviceDataId;\n\n this.recordingSession = JSON.parse(deviceData['RecordingSession'].value);\n this.initialiseForm(this.extractFields(this.recordingSession));\n\n // data field uninitialised for unmodified record\n this.detailChangeLog = deviceData['UserDetailChangeLog']?.value ?? [];\n\n this.status = deviceData['Status']?.value === 'Generating Report' ?\n 'generating' : 'success';\n },\n error: (err) => {\n console.error(err);\n this.status = \"error\";\n }\n });\n }\n\n private init() {\n if (!this.config?.currentUserId || !this.config.deviceDataModelId) {\n this.status = 'cfgerror'\n return;\n } else if (!this.config?.owners?.[0]) {\n this.status = 'nouser';\n return;\n }\n\n this.status = 'loading';\n this.loadData(this.config.currentUserId, this.config.owners[0], this.config.deviceDataModelId);\n }\n\n // this should be called from the parent using the ViewChild attr\n refresh() {\n this.init();\n }\n\n // NOTE: there could be something wrong / unusual here but it seems to work ok\n ngOnInit() {\n if (this.config && !this.configDiffer) this.configDiffer = this.kvDiffers.find(this.config).create();\n if (this.config?.owners && !this.ownersDiffer) this.ownersDiffer = this.itDiffers.find(this.config.owners).create();\n }\n\n ngDoCheck() {\n const configChanges = this.configDiffer?.diff(this.config);\n const ownersChanges = this.ownersDiffer?.diff(this.config?.owners);\n\n if (configChanges || ownersChanges) this.init();\n }\n}\n","<div class=\"wrapper\">\n <div class=\"status\" *ngIf=\"status === 'error'\">\n An error occured while trying to get the details.\n </div>\n <div class=\"status\" *ngIf=\"status === 'cfgerror'\">\n The widget has not been configured correctly, or is missing configuration information.\n </div>\n <div class=\"status\" *ngIf=\"status === 'nouser'\">\n There is no user specified as the data owner.\n </div>\n <form *ngIf=\"!status.includes('error') && status !== 'nouser'\" [formGroup]=\"formGroup\" (ngSubmit)=\"saveModifications()\">\n <div class=\"inputs\">\n <div class=\"form-row\">\n <label for=\"dob\">Date of Birth:</label>\n <input id=\"dob\" type=\"date\" formControlName=\"dob\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"weight\">Patient Weight (kg):</label>\n <input id=\"weight\" type=\"number\" formControlName=\"weight\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"height\">Patient Height (cm):</label>\n <input id=\"height\" type=\"number\" formControlName=\"height\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"mealStart\">Meal Start Time:</label>\n <input id=\"mealStart\" type=\"datetime-local\" formControlName=\"mealStart\">\n </div>\n\n <div class=\"form-row\">\n <label for=\"mealEnd\">Meal End Time:</label>\n <input id=\"mealEnd\" type=\"datetime-local\" formControlName=\"mealEnd\">\n </div>\n </div>\n\n <div *ngIf=\"!formGroup.valid && formGroup.dirty\" class=\"errors\">\n <div *ngFor=\"let control of formGroup.controls | entries\">\n {{ parseInputErrors(control[0], control[1]) }}\n </div>\n </div>\n\n <div *ngIf=\"status === 'generating'\" class=\"info\">\n <div>The report is generating at the moment, check back later if you need to modify this entry.</div>\n </div>\n\n <div class=\"buttons\">\n <button type=\"button\" (click)=\"regenReport()\" [disabled]=\"status === 'sending' || status === 'generating' || status === 'loading'\">Regenerate Report</button>\n <button type=\"button\" (click)=\"resetModifications()\" [disabled]=\"status === 'sending' || status === 'generating' || formGroup.pristine\">Cancel Modification</button>\n <button type=\"submit\" [disabled]=\"status === 'sending' || status === 'generating' || !formGroup.valid || formGroup.pristine\">Save Details</button>\n </div>\n </form>\n</div>\n","import { CommonModule, JsonPipe } from '@angular/common';\nimport { NgModule } from '@angular/core';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { DetailEditComponent } from './detail-edit.component';\nimport { EntriesPipe } from './entries.pipe';\n\n\n\n@NgModule({\n declarations: [\n DetailEditComponent,\n EntriesPipe\n ],\n imports: [\n JsonPipe,\n ReactiveFormsModule,\n CommonModule\n ],\n exports: [\n DetailEditComponent\n ]\n})\nexport class DetailEditModule { }\n","/*\n * Public API Surface of detail-edit\n */\n\nexport * from './lib/detail-edit.service';\nexport * from './lib/detail-edit.component';\nexport * from './lib/detail-edit.module';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i4.EntriesPipe"],"mappings":"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"}
|