@hestia-earth/ui-components 0.42.27 → 0.42.29
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.
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Injectable, InjectionToken, inject, ElementRef, output, Directive, DestroyRef, input, computed, HostBinding, Component as Component$1, ChangeDetectionStrategy, Pipe, viewChild, HostListener, model, ViewEncapsulation, signal, effect, contentChild, untracked, viewChildren, forwardRef, LOCALE_ID } from '@angular/core';
|
|
2
|
+
import { Injectable, InjectionToken, inject, ElementRef, PLATFORM_ID, output, Directive, DestroyRef, input, computed, HostBinding, Component as Component$1, ChangeDetectionStrategy, Pipe, viewChild, HostListener, model, ViewEncapsulation, signal, effect, contentChild, untracked, viewChildren, forwardRef, LOCALE_ID } from '@angular/core';
|
|
3
3
|
import { toObservable, toSignal, outputFromObservable, takeUntilDestroyed, rxResource } from '@angular/core/rxjs-interop';
|
|
4
4
|
import * as i1 from '@angular/forms';
|
|
5
5
|
import { FormsModule, NG_VALUE_ACCESSOR, UntypedFormBuilder, Validators, ReactiveFormsModule, FormControl } from '@angular/forms';
|
|
6
|
-
import { NgClass, DecimalPipe, NgTemplateOutlet,
|
|
6
|
+
import { isPlatformBrowser, NgClass, DecimalPipe, NgTemplateOutlet, DOCUMENT, KeyValuePipe, PlatformLocation, NgStyle, UpperCasePipe, JsonPipe, DatePipe, AsyncPipe, formatDate as formatDate$1 } from '@angular/common';
|
|
7
7
|
import * as i1$1 from '@ng-bootstrap/ng-bootstrap';
|
|
8
8
|
import { NgbTooltip, NgbDropdown, NgbDropdownMenu, NgbDropdownToggle, NgbActiveModal, NgbHighlight, NgbModal, NgbDropdownItem, NgbTypeahead, NgbPopover, NgbTooltipModule, NgbDropdownModule, NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap';
|
|
9
|
-
import { ReplaySubject, of, mergeMap, shareReplay, delay, map, catchError, distinctUntilChanged, timer, take, first, Subject, combineLatest, filter, fromEvent, startWith, merge, skip, switchMap,
|
|
9
|
+
import { ReplaySubject, of, mergeMap, shareReplay, delay, map, catchError, distinctUntilChanged, timer, take, first, EMPTY, Subject, combineLatest, filter, fromEvent, startWith, merge, skip, switchMap, throttleTime, animationFrameScheduler, debounceTime, takeUntil, lastValueFrom, tap, skipUntil, zip, mergeAll, reduce, forkJoin, throwError, from, firstValueFrom, toArray, distinct, groupBy } from 'rxjs';
|
|
10
10
|
import { HttpClient } from '@angular/common/http';
|
|
11
11
|
import get from 'lodash.get';
|
|
12
12
|
import { SCHEMA_VERSION, SchemaType, NodeType, TermTermType, productTermTermType, nestedSearchableKeys, SiteSiteType, EmissionMethodTier, isExpandable, sortKeysByType, isTypeNode, uniquenessFields, BlankNodesKey, impactAssessmentTermTermType, measurementTermTermType, emissionTermTermType, inputTermTermType, CycleFunctionalUnit, NonBlankNodesKey, jsonldPath, isTypeValid, typeToSchemaType, infrastructureTermTermType, managementTermTermType } from '@hestia-earth/schema';
|
|
@@ -76,16 +76,23 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
76
76
|
|
|
77
77
|
const gitHome = 'https://gitlab.com/hestia-earth';
|
|
78
78
|
const gitBranch = () => (['dev', 'staging'].some(env => baseUrl().includes(env)) ? 'develop' : 'master');
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
/**
|
|
80
|
+
* Access `window` defensively so this module can be evaluated outside the browser
|
|
81
|
+
* (SSR / prerender / Node). On the server there is no location, so callers fall
|
|
82
|
+
* back to production defaults.
|
|
83
|
+
*/
|
|
84
|
+
const windowRef = () => (typeof window === 'undefined' ? undefined : window);
|
|
85
|
+
const origin = () => windowRef()?.location?.origin ?? '';
|
|
86
|
+
const isChrome = () => windowRef()?.navigator?.userAgent?.includes('Chrome') ?? false;
|
|
87
|
+
const baseUrl = (allowLocalhost = true) => origin().includes('localhost')
|
|
81
88
|
? allowLocalhost
|
|
82
|
-
?
|
|
89
|
+
? origin()
|
|
83
90
|
: 'https://www-dev.hestia.earth'
|
|
84
|
-
:
|
|
85
|
-
?
|
|
91
|
+
: origin().includes('hestia.earth')
|
|
92
|
+
? origin()
|
|
86
93
|
: 'https://www.hestia.earth';
|
|
87
94
|
const baseApiUrl = () => baseUrl(false).replace('www', 'api');
|
|
88
|
-
const isExternal = () => baseUrl() !==
|
|
95
|
+
const isExternal = () => baseUrl() !== origin();
|
|
89
96
|
const schemaBaseUrl = (version) => [baseUrl(), 'schema', version].filter(Boolean).join('/');
|
|
90
97
|
const schemaDataBaseUrl = (version) => [baseUrl(false), 'schema-data', version || SCHEMA_VERSION].filter(Boolean).join('/');
|
|
91
98
|
const glossaryBaseUrl = (allowLocalhost = true) => [baseUrl(allowLocalhost), 'glossary'].filter(Boolean).join('/');
|
|
@@ -120,7 +127,11 @@ const filterParams = (obj) => {
|
|
|
120
127
|
});
|
|
121
128
|
return res;
|
|
122
129
|
};
|
|
123
|
-
const waitFor = (variable, callback) =>
|
|
130
|
+
const waitFor = (variable, callback) => typeof window === 'undefined'
|
|
131
|
+
? undefined
|
|
132
|
+
: get(window, variable, false)
|
|
133
|
+
? callback()
|
|
134
|
+
: setTimeout(() => waitFor(variable, callback), 100);
|
|
124
135
|
const bottom = (element) => element.offsetTop + element.getBoundingClientRect().height;
|
|
125
136
|
const isScrolledBelow = (element) => (element ? window.scrollY > bottom(element) : false);
|
|
126
137
|
const scrollToEl = (id, args = {
|
|
@@ -1545,14 +1556,18 @@ class ResizedEvent {
|
|
|
1545
1556
|
class ResizedDirective {
|
|
1546
1557
|
constructor() {
|
|
1547
1558
|
this.element = inject(ElementRef);
|
|
1559
|
+
this.isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
|
|
1548
1560
|
this.resized = output();
|
|
1549
|
-
|
|
1561
|
+
// `ResizeObserver` is browser-only; there are no resize events during SSR.
|
|
1562
|
+
if (this.isBrowser) {
|
|
1563
|
+
this.observer = new ResizeObserver(entries => this.observe(entries));
|
|
1564
|
+
}
|
|
1550
1565
|
}
|
|
1551
1566
|
ngOnInit() {
|
|
1552
|
-
this.observer
|
|
1567
|
+
this.observer?.observe(this.element.nativeElement);
|
|
1553
1568
|
}
|
|
1554
1569
|
ngOnDestroy() {
|
|
1555
|
-
this.observer
|
|
1570
|
+
this.observer?.disconnect();
|
|
1556
1571
|
}
|
|
1557
1572
|
observe(entries) {
|
|
1558
1573
|
const domSize = entries[0];
|
|
@@ -1574,6 +1589,10 @@ const distinctUntilChangedDeep = () => distinctUntilChanged((x, y) => isEqual$1(
|
|
|
1574
1589
|
const takeAfterViewInit = (fn, settings = { take: 10 }) => timer(0, 50).pipe(take(settings.take), map(() => fn()), first(returnItem => !!returnItem));
|
|
1575
1590
|
const injectResizeEvent$ = (elementRef) => {
|
|
1576
1591
|
const destroyRef = inject(DestroyRef);
|
|
1592
|
+
// `ResizeObserver` is browser-only; there are no resize events during SSR.
|
|
1593
|
+
if (!isPlatformBrowser(inject(PLATFORM_ID))) {
|
|
1594
|
+
return EMPTY;
|
|
1595
|
+
}
|
|
1577
1596
|
const resizedEvent$ = new Subject();
|
|
1578
1597
|
let oldRect;
|
|
1579
1598
|
const observer = new ResizeObserver(entries => {
|
|
@@ -1723,7 +1742,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
1723
1742
|
|
|
1724
1743
|
const GUIDE_ENABLED = new InjectionToken('HESTIA_GUIDE_ENABLED');
|
|
1725
1744
|
const guideNamespace = 'he-guide';
|
|
1726
|
-
const postGuideEvent = (data) => window
|
|
1745
|
+
const postGuideEvent = (data) => typeof window === 'undefined'
|
|
1746
|
+
? undefined
|
|
1747
|
+
: window.parent.postMessage({ namespace: guideNamespace, ...data }, '*');
|
|
1727
1748
|
const handleGuideEvent = (handler) => (event) => {
|
|
1728
1749
|
const data = event.data;
|
|
1729
1750
|
if (data.namespace == guideNamespace) {
|
|
@@ -2029,7 +2050,10 @@ const toBreakpoint = ({ min, max }) => [min ? toSize(beakpointWidths[min], 'min'
|
|
|
2029
2050
|
class ResponsiveService {
|
|
2030
2051
|
constructor() {
|
|
2031
2052
|
this.breakPointObserver = inject(BreakpointObserver);
|
|
2032
|
-
this.
|
|
2053
|
+
this.isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
|
|
2054
|
+
this.windowWidth$ = this.isBrowser
|
|
2055
|
+
? fromEvent(window, 'resize').pipe(startWith(window.innerWidth), map(() => window.innerWidth))
|
|
2056
|
+
: of(0);
|
|
2033
2057
|
this.isMobile$ = this.breakPointObserver.observe(toBreakpoint({ max: Breakpoint.tablet })).pipe(map(state => state.matches), distinctUntilChanged());
|
|
2034
2058
|
this.isTablet$ = this.breakPointObserver
|
|
2035
2059
|
.observe(toBreakpoint({ min: Breakpoint.tablet, max: Breakpoint.desktop }))
|
|
@@ -2047,7 +2071,7 @@ class ResponsiveService {
|
|
|
2047
2071
|
*/
|
|
2048
2072
|
this.is1080p$ = this.breakPointObserver.observe(toSize(1920, 'min')).pipe(map(state => state.matches), distinctUntilChanged());
|
|
2049
2073
|
this.isRetinaDisplay = () => {
|
|
2050
|
-
if (window.matchMedia) {
|
|
2074
|
+
if (this.isBrowser && window.matchMedia) {
|
|
2051
2075
|
const mq = window.matchMedia([
|
|
2052
2076
|
'min--moz-device-pixel-ratio: 1.3',
|
|
2053
2077
|
'-o-min-device-pixel-ratio: 2.6/2',
|
|
@@ -2117,6 +2141,8 @@ class DrawerContainerComponent {
|
|
|
2117
2141
|
constructor() {
|
|
2118
2142
|
this.responsiveService = inject(ResponsiveService);
|
|
2119
2143
|
this.localStorage = inject(LocalStorageService);
|
|
2144
|
+
this.document = inject(DOCUMENT);
|
|
2145
|
+
this.isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
|
|
2120
2146
|
this.contentContainer = viewChild('contentContainer', { ...(ngDevMode ? { debugName: "contentContainer" } : {}), read: ElementRef });
|
|
2121
2147
|
this.menuState = signal('close', ...(ngDevMode ? [{ debugName: "menuState" }] : []));
|
|
2122
2148
|
/**
|
|
@@ -2199,7 +2225,9 @@ class DrawerContainerComponent {
|
|
|
2199
2225
|
this.destroy$ = new Subject();
|
|
2200
2226
|
this._updateSidenavEvent$ = toObservable(this.isResizing).pipe(switchMap(listen => (listen ? moveEvent() : EMPTY)), throttleTime(0, animationFrameScheduler));
|
|
2201
2227
|
this._contentContainer$ = toObservable(this.contentContainer).pipe(filter(v => !!v));
|
|
2202
|
-
this._hostComponentWidth$ =
|
|
2228
|
+
this._hostComponentWidth$ = this.isBrowser
|
|
2229
|
+
? fromEvent(window, 'resize').pipe(startWith(window.innerWidth))
|
|
2230
|
+
: of(0);
|
|
2203
2231
|
/**
|
|
2204
2232
|
* we use combineLatest instead of computed to avoid the animation flickering (wait for all sources to emit)
|
|
2205
2233
|
*/
|
|
@@ -2221,13 +2249,13 @@ class DrawerContainerComponent {
|
|
|
2221
2249
|
effect(() => {
|
|
2222
2250
|
const position = this.position();
|
|
2223
2251
|
const width = this.sidenavWidth();
|
|
2224
|
-
document.body.style.setProperty(`--sidenav-${position}-width`, `${width}px`);
|
|
2252
|
+
this.document.body.style.setProperty(`--sidenav-${position}-width`, `${width}px`);
|
|
2225
2253
|
});
|
|
2226
2254
|
effect(() => {
|
|
2227
2255
|
const expanded = this.expanded();
|
|
2228
2256
|
const position = this.position();
|
|
2229
2257
|
const value = this.contentContainerTransform();
|
|
2230
|
-
document.body.style.setProperty(`--content-transition-${position}-x`, `${expanded ? value : 0}px`);
|
|
2258
|
+
this.document.body.style.setProperty(`--content-transition-${position}-x`, `${expanded ? value : 0}px`);
|
|
2231
2259
|
});
|
|
2232
2260
|
// initial load of configuration
|
|
2233
2261
|
effect(() => this.storageKey() && this.storeConfiguration());
|
|
@@ -2304,6 +2332,8 @@ class DrawerContainerComponent {
|
|
|
2304
2332
|
this.menuState.set(didOpen ? 'open' : 'close');
|
|
2305
2333
|
}
|
|
2306
2334
|
_getContentLeftSideSpace(element) {
|
|
2335
|
+
if (!this.isBrowser)
|
|
2336
|
+
return 0;
|
|
2307
2337
|
const position = this.position();
|
|
2308
2338
|
const styles = window.getComputedStyle(element.nativeElement, null);
|
|
2309
2339
|
const padding = styles.getPropertyValue('padding-' + position);
|
|
@@ -3006,6 +3036,12 @@ const loadSvgSprite = () => {
|
|
|
3006
3036
|
const http = inject(HttpClient);
|
|
3007
3037
|
const document = inject(DOCUMENT);
|
|
3008
3038
|
const platformLocation = inject(PlatformLocation);
|
|
3039
|
+
// The sprite is injected into the DOM for the browser to render `<use>` refs.
|
|
3040
|
+
// During SSR/prerender there is no asset server to fetch it from, and the
|
|
3041
|
+
// client re-injects it on hydration, so skip the fetch on the server.
|
|
3042
|
+
if (!isPlatformBrowser(inject(PLATFORM_ID))) {
|
|
3043
|
+
return Promise.resolve();
|
|
3044
|
+
}
|
|
3009
3045
|
const baseUrl = platformLocation.getBaseHrefFromDOM();
|
|
3010
3046
|
return lastValueFrom(http.get(`${baseUrl}assets/svg-icons/icons-sprite.svg`, { responseType: 'text' }).pipe(tap(svgContent => {
|
|
3011
3047
|
const div = document.createElement('div');
|
|
@@ -3464,10 +3500,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
3464
3500
|
class SocialTagsComponent {
|
|
3465
3501
|
constructor() {
|
|
3466
3502
|
this.meta = inject(Meta);
|
|
3503
|
+
this.document = inject(DOCUMENT);
|
|
3467
3504
|
this.config = input({}, ...(ngDevMode ? [{ debugName: "config" }] : []));
|
|
3468
3505
|
this.classes = 'is-hidden';
|
|
3469
3506
|
this.configs = computed(() => ({
|
|
3470
|
-
'og:url':
|
|
3507
|
+
'og:url': this.document.location.href.split('?')[0],
|
|
3471
3508
|
...this.config
|
|
3472
3509
|
}), ...(ngDevMode ? [{ debugName: "configs" }] : []));
|
|
3473
3510
|
this.meta.addTag({ charset: 'UTF-8' });
|
|
@@ -3562,8 +3599,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
3562
3599
|
/* eslint-disable @angular-eslint/directive-selector */
|
|
3563
3600
|
class DocumentClickService {
|
|
3564
3601
|
constructor() {
|
|
3602
|
+
this.document = inject(DOCUMENT);
|
|
3565
3603
|
this.documentClick$ = new Subject();
|
|
3566
|
-
|
|
3604
|
+
// Document click events only exist in the browser; skip on the server (SSR).
|
|
3605
|
+
if (!isPlatformBrowser(inject(PLATFORM_ID))) {
|
|
3606
|
+
return;
|
|
3607
|
+
}
|
|
3608
|
+
fromEvent(this.document, 'click')
|
|
3567
3609
|
.pipe(takeUntilDestroyed(), tap(event => this.documentClick$.next(event)))
|
|
3568
3610
|
.subscribe();
|
|
3569
3611
|
}
|
|
@@ -6796,6 +6838,53 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
6796
6838
|
}]
|
|
6797
6839
|
}] });
|
|
6798
6840
|
|
|
6841
|
+
/**
|
|
6842
|
+
* Sum the values of every item of a group, skipping the items without a value at this index.
|
|
6843
|
+
*
|
|
6844
|
+
* An item has no value when the Node does not contain that Emission at all, which is not the same as a `0` value:
|
|
6845
|
+
* summing it as `NaN` would silently hide the whole group from the chart. When no item of the group has a value,
|
|
6846
|
+
* `undefined` is returned so the chart displays "No data", like it does when the data is not grouped.
|
|
6847
|
+
*
|
|
6848
|
+
* @param values The values of every item of the group, at a single index.
|
|
6849
|
+
* @returns The sum, or `undefined` when no item has a value.
|
|
6850
|
+
*/
|
|
6851
|
+
const sumValues = (values) => {
|
|
6852
|
+
const definedValues = values.filter(value => !isUndefined(value));
|
|
6853
|
+
return definedValues.length ? sum(definedValues) : undefined;
|
|
6854
|
+
};
|
|
6855
|
+
const groupByCategory = (data, category, emissionCategoryValue) => data.reduce((prev, curr) => {
|
|
6856
|
+
const groupKey = emissionCategoryValue(curr.id, category);
|
|
6857
|
+
prev[groupKey] = prev[groupKey] || [];
|
|
6858
|
+
prev[groupKey].push(curr);
|
|
6859
|
+
return prev;
|
|
6860
|
+
}, {});
|
|
6861
|
+
/**
|
|
6862
|
+
* Group the contribution data by Category, summing the values of every Emission of the same Category.
|
|
6863
|
+
*
|
|
6864
|
+
* @param data The contribution data, one item per Emission.
|
|
6865
|
+
* @param labels The labels of the chart, one per Node compared.
|
|
6866
|
+
* @param category The Category to group by. When empty, the data is returned as-is.
|
|
6867
|
+
* @param service Used to resolve the Category of an Emission and its label.
|
|
6868
|
+
* @returns The data grouped by Category, or the original data when grouping is not needed.
|
|
6869
|
+
*/
|
|
6870
|
+
const groupDataByCategory = (data, labels, category, { emissionCategoryValue, categoryLabel }) => {
|
|
6871
|
+
if (!category) {
|
|
6872
|
+
return data;
|
|
6873
|
+
}
|
|
6874
|
+
const groupedData = groupByCategory(data, category, emissionCategoryValue);
|
|
6875
|
+
return Object.keys(groupedData).length === 1
|
|
6876
|
+
? data
|
|
6877
|
+
: Object.entries(groupedData).map(([groupKey, items], index) => ({
|
|
6878
|
+
label: categoryLabel(groupKey),
|
|
6879
|
+
values: labels.map((_, i) => sumValues(items.map(item => item.values[i]))),
|
|
6880
|
+
color: listColor(groupKey, index),
|
|
6881
|
+
includedItems: items.map((item, i) => ({
|
|
6882
|
+
...item,
|
|
6883
|
+
color: listColor(item.id, i)
|
|
6884
|
+
}))
|
|
6885
|
+
}));
|
|
6886
|
+
};
|
|
6887
|
+
|
|
6799
6888
|
const grey = '#4a4a4a';
|
|
6800
6889
|
const barheight = 8; // 8px
|
|
6801
6890
|
const hoverHeight = 10; // 10px
|
|
@@ -6986,30 +7075,7 @@ class ContributionChartComponent {
|
|
|
6986
7075
|
this.exporting = computed(() => this.chart()?.exporting(), ...(ngDevMode ? [{ debugName: "exporting" }] : []));
|
|
6987
7076
|
this.chartHeight = computed(() => this.height() || chartHeight$1(this.minHeight(), this.maxHeight(), this.labels()?.length ?? 0), ...(ngDevMode ? [{ debugName: "chartHeight" }] : []));
|
|
6988
7077
|
this.hasNegativeContributions = computed(() => this.displayData()?.some(value => value.values.some(v => v < 0)), ...(ngDevMode ? [{ debugName: "hasNegativeContributions" }] : []));
|
|
6989
|
-
this.displayData = computed(() => {
|
|
6990
|
-
const category = this.category();
|
|
6991
|
-
const data = this.data();
|
|
6992
|
-
if (!category) {
|
|
6993
|
-
return data;
|
|
6994
|
-
}
|
|
6995
|
-
const groupedData = data.reduce((prev, curr) => {
|
|
6996
|
-
const groupKey = this.emissionCategoryService.emissionCategoryValue(curr.id, category);
|
|
6997
|
-
prev[groupKey] = prev[groupKey] || [];
|
|
6998
|
-
prev[groupKey].push(curr);
|
|
6999
|
-
return prev;
|
|
7000
|
-
}, {});
|
|
7001
|
-
return Object.keys(groupedData).length === 1
|
|
7002
|
-
? data
|
|
7003
|
-
: Object.entries(groupedData).map(([category, items], index) => ({
|
|
7004
|
-
label: this.emissionCategoryService.categoryLabel(category),
|
|
7005
|
-
values: this.labels().map((_, i) => sum(items.map(item => item.values[i]))),
|
|
7006
|
-
color: listColor(category, index),
|
|
7007
|
-
includedItems: items.map((item, i) => ({
|
|
7008
|
-
...item,
|
|
7009
|
-
color: listColor(item.id, i)
|
|
7010
|
-
}))
|
|
7011
|
-
}));
|
|
7012
|
-
}, ...(ngDevMode ? [{ debugName: "displayData" }] : []));
|
|
7078
|
+
this.displayData = computed(() => groupDataByCategory(this.data(), this.labels(), this.category(), this.emissionCategoryService), ...(ngDevMode ? [{ debugName: "displayData" }] : []));
|
|
7013
7079
|
this.defaultConfig = computed(() => ({
|
|
7014
7080
|
options: {
|
|
7015
7081
|
onClick: (event, activeElements, chart) => this.onItemClick(event, activeElements, chart),
|
|
@@ -8933,16 +8999,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
8933
8999
|
|
|
8934
9000
|
class GuideOverlayService {
|
|
8935
9001
|
constructor() {
|
|
9002
|
+
this.isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
|
|
8936
9003
|
this.message = signal(null, ...(ngDevMode ? [{ debugName: "message" }] : []));
|
|
8937
9004
|
this.messageListener = ({ data }) => {
|
|
8938
9005
|
if (data.namespace == guideNamespace) {
|
|
8939
9006
|
this.message.set(data);
|
|
8940
9007
|
}
|
|
8941
9008
|
};
|
|
8942
|
-
|
|
9009
|
+
// `postMessage` communication only exists in the browser; skip on the server (SSR).
|
|
9010
|
+
if (this.isBrowser) {
|
|
9011
|
+
window.addEventListener('message', this.messageListener);
|
|
9012
|
+
}
|
|
8943
9013
|
}
|
|
8944
9014
|
ngOnDestroy() {
|
|
8945
|
-
|
|
9015
|
+
if (this.isBrowser) {
|
|
9016
|
+
window.removeEventListener('message', this.messageListener);
|
|
9017
|
+
}
|
|
8946
9018
|
}
|
|
8947
9019
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: GuideOverlayService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
8948
9020
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: GuideOverlayService, providedIn: 'root' }); }
|
|
@@ -9290,6 +9362,10 @@ const isMissing = (value) => value === undefined || value === null || value ===
|
|
|
9290
9362
|
// the result symbol (left-hand side) - it is the model's output, not an input that "was not logged", so
|
|
9291
9363
|
// it is excluded from the missing-values notice (e.g. a failed model has no result value)
|
|
9292
9364
|
const resultKey = 'value';
|
|
9365
|
+
// the reserved table key a `\sum` over per-contributor products binds to (e.g. `[contributions:value]`).
|
|
9366
|
+
// its rows come from the ImpactAssessment's contribution data (register_contribution), not the jlog, so
|
|
9367
|
+
// these "characterisation = Σ contributions" models render fully without duplicating values into the logs
|
|
9368
|
+
const contributionsKey = 'contributions';
|
|
9293
9369
|
// the "value formula" computes the model's result (`key: "value"`); any others are sub-formulas that
|
|
9294
9370
|
// compute its components (possibly chained: a sub-formula's result feeds another sub-formula)
|
|
9295
9371
|
const isValueFormula = (formula) => formula.bindings.some(binding => binding.key === resultKey);
|
|
@@ -9352,15 +9428,42 @@ class NodeLogsModelsFormulaComponent {
|
|
|
9352
9428
|
// the value the model returned (the recalculated node value): the result symbol (`key: "value"`) is
|
|
9353
9429
|
// usually not logged, so it falls back to this
|
|
9354
9430
|
this.value = input(...(ngDevMode ? [undefined, { debugName: "value" }] : []));
|
|
9431
|
+
// the ImpactAssessment the model ran on: lets a contribution-based `\sum` pull its per-contributor
|
|
9432
|
+
// summands from the stored contribution data instead of duplicating them into the jlog
|
|
9433
|
+
this.node = input(...(ngDevMode ? [undefined, { debugName: "node" }] : []));
|
|
9434
|
+
this.nodeService = inject(HeNodeService);
|
|
9355
9435
|
// show the substituted formula (values in place of symbols) rather than the raw symbolic one
|
|
9356
9436
|
this.substituted = signal(false, ...(ngDevMode ? [{ debugName: "substituted" }] : []));
|
|
9357
9437
|
// a unique id per instance so the switch label only toggles its own checkbox (several popovers can co-exist)
|
|
9358
9438
|
this.toggleId = uuid('formulaSubstituted-');
|
|
9359
9439
|
this.formulas = computed(() => getModelFormulas(this.model()), ...(ngDevMode ? [{ debugName: "formulas" }] : []));
|
|
9440
|
+
// whether any formula sums over per-contributor products (bound to the reserved `contributions` table)
|
|
9441
|
+
this.hasContributionBinding = computed(() => this.formulas().some(formula => formula.bindings.some(binding => binding.key === contributionsKey)), ...(ngDevMode ? [{ debugName: "hasContributionBinding" }] : []));
|
|
9442
|
+
// only fetch contributions when a formula actually needs them and we have an ImpactAssessment to fetch for
|
|
9443
|
+
this.contributionResource = rxResource({
|
|
9444
|
+
params: () => (this.hasContributionBinding() && this.node() ? { node: this.node() } : undefined),
|
|
9445
|
+
stream: ({ params: { node } }) => this.nodeService.getContributions$(node)
|
|
9446
|
+
});
|
|
9447
|
+
// the contributions to this indicator term, grouped by method model (empty until loaded / when N/A)
|
|
9448
|
+
this.termContributions = computed(() => {
|
|
9449
|
+
const node = this.node();
|
|
9450
|
+
const contributions = this.contributionResource.value();
|
|
9451
|
+
if (!node || !contributions)
|
|
9452
|
+
return {};
|
|
9453
|
+
return simplifyContributions(node, contributions)[this.model()?.term ?? ''] ?? {};
|
|
9454
|
+
}, ...(ngDevMode ? [{ debugName: "termContributions" }] : []));
|
|
9455
|
+
// the per-contributor summands for this model, shaped as `\sum` rows: { id: contributor term, value }
|
|
9456
|
+
this.contributionRows = computed(() => {
|
|
9457
|
+
const byIndicator = this.termContributions()[this.model()?.model ?? ''] ?? {};
|
|
9458
|
+
return Object.entries(byIndicator).map(([id, value]) => ({ id, value }));
|
|
9459
|
+
}, ...(ngDevMode ? [{ debugName: "contributionRows" }] : []));
|
|
9360
9460
|
this.values = computed(() => {
|
|
9361
9461
|
const values = logValues(this.logs());
|
|
9362
9462
|
// the result (`value`) is usually the model's returned value rather than a logged field
|
|
9363
|
-
|
|
9463
|
+
const withResult = isMissing(values.value) && !isMissing(this.value()) ? { ...values, value: this.value() } : values;
|
|
9464
|
+
// feed a contribution-based `\sum` from the stored contributions (nothing to merge for other formulas)
|
|
9465
|
+
const rows = this.contributionRows();
|
|
9466
|
+
return rows.length ? { ...withResult, [contributionsKey]: rows } : withResult;
|
|
9364
9467
|
}, ...(ngDevMode ? [{ debugName: "values" }] : []));
|
|
9365
9468
|
this.valueFormula = computed(() => this.formulas().find(isValueFormula), ...(ngDevMode ? [{ debugName: "valueFormula" }] : []));
|
|
9366
9469
|
// the value formula's own symbol keys - kept symbolic in the sub-formulas (they are substituted only in
|
|
@@ -9411,12 +9514,12 @@ class NodeLogsModelsFormulaComponent {
|
|
|
9411
9514
|
this.substituted.update(value => !value);
|
|
9412
9515
|
}
|
|
9413
9516
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NodeLogsModelsFormulaComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
9414
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: NodeLogsModelsFormulaComponent, isStandalone: true, selector: "he-node-logs-models-formula", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: false, transformFunction: null }, logs: { classPropertyName: "logs", publicName: "logs", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (formulas().length) {\n <div class=\"formula-block is-mb-2 has-text-white\">\n <div class=\"is-flex is-align-items-center is-justify-content-space-between is-gap-8 is-mb-1 is-size-8\">\n <span class=\"is-uppercase has-text-weight-semibold\">Formula{{ formulas().length > 1 ? 's' : '' }}</span>\n <div class=\"field\">\n <input\n type=\"checkbox\"\n class=\"switch is-small is-rounded\"\n [id]=\"toggleId\"\n [checked]=\"substituted()\"\n [disabled]=\"!hasSubstitutions()\"\n (change)=\"toggle()\" />\n <label [for]=\"toggleId\" [title]=\"hasSubstitutions() ? '' : 'No logged values to substitute'\">\n <span>{{ substituted() ? 'Substituted' : 'Raw' }}</span>\n </label>\n </div>\n </div>\n\n @for (item of renderedFormulas(); track $index) {\n <div class=\"formula\" [heKatex]=\"item.rendered\"></div>\n\n @if (item.variables.length) {\n <ul class=\"is-size-7 is-mt-1 is-mb-2 is-list-style-disc | formula-variables\">\n @for (variable of item.variables; track $index) {\n <li>\n <div class=\"is-flex is-align-items-baseline is-gap-4\">\n <span class=\"formula-variable-symbol is-nowrap\">\n <span [heKatex]=\"variable.symbol\" [heKatexInline]=\"true\"></span>\n @if (variable.description) {\n <span>:</span>\n }\n </span>\n @if (variable.description) {\n <markdown class=\"is-inline-block is-italic | formula-variable-desc\" [data]=\"variable.description\" />\n }\n @if (variable.missing) {\n <span class=\"has-text-warning\">(missing)</span>\n }\n </div>\n </li>\n }\n </ul>\n }\n }\n </div>\n}\n", styles: [".formula-block{border-bottom:1px solid rgba(255,255,255,.2)}.formula-variable-symbol{flex-shrink:0}.formula-variable-symbol ::ng-deep .katex{font-size:1em}.formula-variable-desc{opacity:.85}.formula-variable-desc ::ng-deep *{display:inline;margin:0}.formula{overflow-x:auto;overflow-y:hidden}.formula ::ng-deep .katex-display{margin:.35rem 0}\n"], dependencies: [{ kind: "directive", type: KatexDirective, selector: "[heKatex]", inputs: ["heKatex", "heKatexInline"] }, { kind: "component", type: MarkdownComponent, selector: "markdown, [markdown]", inputs: ["data", "src", "disableSanitizer", "inline", "clipboard", "clipboardButtonComponent", "clipboardButtonTemplate", "emoji", "katex", "katexOptions", "mermaid", "mermaidOptions", "lineHighlight", "line", "lineOffset", "lineNumbers", "start", "commandLine", "filterOutput", "host", "prompt", "output", "user"], outputs: ["error", "load", "ready"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
9517
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: NodeLogsModelsFormulaComponent, isStandalone: true, selector: "he-node-logs-models-formula", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: false, transformFunction: null }, logs: { classPropertyName: "logs", publicName: "logs", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@if (formulas().length) {\n <div class=\"formula-block is-mb-2 has-text-white\">\n <div class=\"is-flex is-align-items-center is-justify-content-space-between is-gap-8 is-mb-1 is-size-8\">\n <span class=\"is-uppercase has-text-weight-semibold\">Formula{{ formulas().length > 1 ? 's' : '' }}</span>\n <div class=\"field\">\n <input\n type=\"checkbox\"\n class=\"switch is-small is-rounded\"\n [id]=\"toggleId\"\n [checked]=\"substituted()\"\n [disabled]=\"!hasSubstitutions()\"\n (change)=\"toggle()\" />\n <label [for]=\"toggleId\" [title]=\"hasSubstitutions() ? '' : 'No logged values to substitute'\">\n <span>{{ substituted() ? 'Substituted' : 'Raw' }}</span>\n </label>\n </div>\n </div>\n\n @for (item of renderedFormulas(); track $index) {\n <div class=\"formula\" [heKatex]=\"item.rendered\"></div>\n\n @if (item.variables.length) {\n <ul class=\"is-size-7 is-mt-1 is-mb-2 is-list-style-disc | formula-variables\">\n @for (variable of item.variables; track $index) {\n <li>\n <div class=\"is-flex is-align-items-baseline is-gap-4\">\n <span class=\"formula-variable-symbol is-nowrap\">\n <span [heKatex]=\"variable.symbol\" [heKatexInline]=\"true\"></span>\n @if (variable.description) {\n <span>:</span>\n }\n </span>\n @if (variable.description) {\n <markdown class=\"is-inline-block is-italic | formula-variable-desc\" [data]=\"variable.description\" />\n }\n @if (variable.missing) {\n <span class=\"has-text-warning\">(missing)</span>\n }\n </div>\n </li>\n }\n </ul>\n }\n }\n </div>\n}\n", styles: [".formula-block{border-bottom:1px solid rgba(255,255,255,.2)}.formula-variable-symbol{flex-shrink:0}.formula-variable-symbol ::ng-deep .katex{font-size:1em}.formula-variable-desc{opacity:.85}.formula-variable-desc ::ng-deep *{display:inline;margin:0}.formula{overflow-x:auto;overflow-y:hidden}.formula ::ng-deep .katex-display{margin:.35rem 0}\n"], dependencies: [{ kind: "directive", type: KatexDirective, selector: "[heKatex]", inputs: ["heKatex", "heKatexInline"] }, { kind: "component", type: MarkdownComponent, selector: "markdown, [markdown]", inputs: ["data", "src", "disableSanitizer", "inline", "clipboard", "clipboardButtonComponent", "clipboardButtonTemplate", "emoji", "katex", "katexOptions", "mermaid", "mermaidOptions", "lineHighlight", "line", "lineOffset", "lineNumbers", "start", "commandLine", "filterOutput", "host", "prompt", "output", "user"], outputs: ["error", "load", "ready"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
9415
9518
|
}
|
|
9416
9519
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NodeLogsModelsFormulaComponent, decorators: [{
|
|
9417
9520
|
type: Component$1,
|
|
9418
9521
|
args: [{ selector: 'he-node-logs-models-formula', changeDetection: ChangeDetectionStrategy.OnPush, imports: [KatexDirective, MarkdownComponent], template: "@if (formulas().length) {\n <div class=\"formula-block is-mb-2 has-text-white\">\n <div class=\"is-flex is-align-items-center is-justify-content-space-between is-gap-8 is-mb-1 is-size-8\">\n <span class=\"is-uppercase has-text-weight-semibold\">Formula{{ formulas().length > 1 ? 's' : '' }}</span>\n <div class=\"field\">\n <input\n type=\"checkbox\"\n class=\"switch is-small is-rounded\"\n [id]=\"toggleId\"\n [checked]=\"substituted()\"\n [disabled]=\"!hasSubstitutions()\"\n (change)=\"toggle()\" />\n <label [for]=\"toggleId\" [title]=\"hasSubstitutions() ? '' : 'No logged values to substitute'\">\n <span>{{ substituted() ? 'Substituted' : 'Raw' }}</span>\n </label>\n </div>\n </div>\n\n @for (item of renderedFormulas(); track $index) {\n <div class=\"formula\" [heKatex]=\"item.rendered\"></div>\n\n @if (item.variables.length) {\n <ul class=\"is-size-7 is-mt-1 is-mb-2 is-list-style-disc | formula-variables\">\n @for (variable of item.variables; track $index) {\n <li>\n <div class=\"is-flex is-align-items-baseline is-gap-4\">\n <span class=\"formula-variable-symbol is-nowrap\">\n <span [heKatex]=\"variable.symbol\" [heKatexInline]=\"true\"></span>\n @if (variable.description) {\n <span>:</span>\n }\n </span>\n @if (variable.description) {\n <markdown class=\"is-inline-block is-italic | formula-variable-desc\" [data]=\"variable.description\" />\n }\n @if (variable.missing) {\n <span class=\"has-text-warning\">(missing)</span>\n }\n </div>\n </li>\n }\n </ul>\n }\n }\n </div>\n}\n", styles: [".formula-block{border-bottom:1px solid rgba(255,255,255,.2)}.formula-variable-symbol{flex-shrink:0}.formula-variable-symbol ::ng-deep .katex{font-size:1em}.formula-variable-desc{opacity:.85}.formula-variable-desc ::ng-deep *{display:inline;margin:0}.formula{overflow-x:auto;overflow-y:hidden}.formula ::ng-deep .katex-display{margin:.35rem 0}\n"] }]
|
|
9419
|
-
}], propDecorators: { model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: false }] }], logs: [{ type: i0.Input, args: [{ isSignal: true, alias: "logs", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }] } });
|
|
9522
|
+
}], propDecorators: { model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: false }] }], logs: [{ type: i0.Input, args: [{ isSignal: true, alias: "logs", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], node: [{ type: i0.Input, args: [{ isSignal: true, alias: "node", required: false }] }] } });
|
|
9420
9523
|
|
|
9421
9524
|
class NodeLogsModelsDetailsComponent {
|
|
9422
9525
|
constructor() {
|
|
@@ -9460,7 +9563,7 @@ class NodeLogsModelsDetailsComponent {
|
|
|
9460
9563
|
this.openKeys.set(next);
|
|
9461
9564
|
}
|
|
9462
9565
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NodeLogsModelsDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
9463
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: NodeLogsModelsDetailsComponent, isStandalone: true, selector: "he-node-logs-models-details", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: false, transformFunction: null }, nodeKey: { classPropertyName: "nodeKey", publicName: "nodeKey", isSignal: true, isRequired: false, transformFunction: null }, hasContributions: { classPropertyName: "hasContributions", publicName: "hasContributions", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@for (section of sections(); track section.key; let last = $last) {\n <div class=\"log-section\" [class.has-border-bottom]=\"!last || isOpen(section.key)\">\n @if (section.key === 'formula' && isOpen('formula')) {\n <!-- the formula component renders its own \"Formula BETA\" title + Raw/Substituted switch on one\n line, so keep the toggle chevron inline with it rather than adding a duplicate header -->\n <div class=\"log-section-header is-flex is-align-items-flex-start is-gap-4\">\n <a class=\"has-text-white\" (click)=\"toggle('formula')\">\n <he-svg-icon name=\"chevron-down\" size=\"16\" />\n </a>\n <div class=\"is-flex-grow-1\">\n <he-node-logs-models-formula
|
|
9566
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: NodeLogsModelsDetailsComponent, isStandalone: true, selector: "he-node-logs-models-details", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: false, transformFunction: null }, nodeKey: { classPropertyName: "nodeKey", publicName: "nodeKey", isSignal: true, isRequired: false, transformFunction: null }, hasContributions: { classPropertyName: "hasContributions", publicName: "hasContributions", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "@for (section of sections(); track section.key; let last = $last) {\n <div class=\"log-section\" [class.has-border-bottom]=\"!last || isOpen(section.key)\">\n @if (section.key === 'formula' && isOpen('formula')) {\n <!-- the formula component renders its own \"Formula BETA\" title + Raw/Substituted switch on one\n line, so keep the toggle chevron inline with it rather than adding a duplicate header -->\n <div class=\"log-section-header is-flex is-align-items-flex-start is-gap-4\">\n <a class=\"has-text-white\" (click)=\"toggle('formula')\">\n <he-svg-icon name=\"chevron-down\" size=\"16\" />\n </a>\n <div class=\"is-flex-grow-1\">\n <he-node-logs-models-formula\n [model]=\"model().model\"\n [logs]=\"model().logs\"\n [value]=\"value()\"\n [node]=\"node()\" />\n </div>\n </div>\n } @else {\n <a\n class=\"log-section-header is-flex is-align-items-center is-gap-4 has-text-white is-size-8 is-uppercase has-text-weight-semibold\"\n (click)=\"toggle(section.key)\">\n <he-svg-icon [name]=\"isOpen(section.key) ? 'chevron-down' : 'chevron-right'\" size=\"16\" />\n <span>{{ section.label }}</span>\n </a>\n\n @if (isOpen(section.key)) {\n <div class=\"log-section-body is-pb-2\">\n @switch (section.key) {\n @case ('logs') {\n <he-node-logs-models-logs [logs]=\"model().logs\" [renderRaw]=\"false\" />\n }\n @case ('raw') {\n <div class=\"is-flex is-justify-content-flex-end is-mb-1\">\n <he-clipboard clipboardClass=\"is-size-7 is-p-1\" [value]=\"rawJson()\" [hideText]=\"true\" />\n </div>\n <pre class=\"raw-log\">{{ rawJson() }}</pre>\n }\n @case ('contributions') {\n <he-node-logs-models-contributions [node]=\"node()\" [nodeKey]=\"nodeKey()\" [model]=\"model()\" />\n }\n }\n </div>\n }\n }\n </div>\n}\n", styles: [".log-section{border-color:#fff3!important}.log-section-header{cursor:pointer;padding:.5rem 0}.log-section-header ::ng-deep .formula-block{margin-bottom:0;border-bottom:none}.raw-log{max-height:300px;overflow:auto;white-space:pre;font-size:.75rem;background:#00000059;color:inherit;padding:.5rem;border-radius:3px}\n"], dependencies: [{ kind: "component", type: HESvgIconComponent, selector: "he-svg-icon", inputs: ["name", "size", "animation"] }, { kind: "component", type: ClipboardComponent, selector: "he-clipboard", inputs: ["icon", "value", "disabled", "hideText", "hideIcon", "size", "clipboardClass", "tooltipPlacement"] }, { kind: "component", type: NodeLogsModelsFormulaComponent, selector: "he-node-logs-models-formula", inputs: ["model", "logs", "value", "node"] }, { kind: "component", type: NodeLogsModelsLogsComponent, selector: "he-node-logs-models-logs", inputs: ["logs", "renderRaw"] }, { kind: "component", type: NodeLogsModelsContributionsComponent, selector: "he-node-logs-models-contributions", inputs: ["node", "nodeKey", "model"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
9464
9567
|
}
|
|
9465
9568
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NodeLogsModelsDetailsComponent, decorators: [{
|
|
9466
9569
|
type: Component$1,
|
|
@@ -9470,7 +9573,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
9470
9573
|
NodeLogsModelsFormulaComponent,
|
|
9471
9574
|
NodeLogsModelsLogsComponent,
|
|
9472
9575
|
NodeLogsModelsContributionsComponent
|
|
9473
|
-
], template: "@for (section of sections(); track section.key; let last = $last) {\n <div class=\"log-section\" [class.has-border-bottom]=\"!last || isOpen(section.key)\">\n @if (section.key === 'formula' && isOpen('formula')) {\n <!-- the formula component renders its own \"Formula BETA\" title + Raw/Substituted switch on one\n line, so keep the toggle chevron inline with it rather than adding a duplicate header -->\n <div class=\"log-section-header is-flex is-align-items-flex-start is-gap-4\">\n <a class=\"has-text-white\" (click)=\"toggle('formula')\">\n <he-svg-icon name=\"chevron-down\" size=\"16\" />\n </a>\n <div class=\"is-flex-grow-1\">\n <he-node-logs-models-formula
|
|
9576
|
+
], template: "@for (section of sections(); track section.key; let last = $last) {\n <div class=\"log-section\" [class.has-border-bottom]=\"!last || isOpen(section.key)\">\n @if (section.key === 'formula' && isOpen('formula')) {\n <!-- the formula component renders its own \"Formula BETA\" title + Raw/Substituted switch on one\n line, so keep the toggle chevron inline with it rather than adding a duplicate header -->\n <div class=\"log-section-header is-flex is-align-items-flex-start is-gap-4\">\n <a class=\"has-text-white\" (click)=\"toggle('formula')\">\n <he-svg-icon name=\"chevron-down\" size=\"16\" />\n </a>\n <div class=\"is-flex-grow-1\">\n <he-node-logs-models-formula\n [model]=\"model().model\"\n [logs]=\"model().logs\"\n [value]=\"value()\"\n [node]=\"node()\" />\n </div>\n </div>\n } @else {\n <a\n class=\"log-section-header is-flex is-align-items-center is-gap-4 has-text-white is-size-8 is-uppercase has-text-weight-semibold\"\n (click)=\"toggle(section.key)\">\n <he-svg-icon [name]=\"isOpen(section.key) ? 'chevron-down' : 'chevron-right'\" size=\"16\" />\n <span>{{ section.label }}</span>\n </a>\n\n @if (isOpen(section.key)) {\n <div class=\"log-section-body is-pb-2\">\n @switch (section.key) {\n @case ('logs') {\n <he-node-logs-models-logs [logs]=\"model().logs\" [renderRaw]=\"false\" />\n }\n @case ('raw') {\n <div class=\"is-flex is-justify-content-flex-end is-mb-1\">\n <he-clipboard clipboardClass=\"is-size-7 is-p-1\" [value]=\"rawJson()\" [hideText]=\"true\" />\n </div>\n <pre class=\"raw-log\">{{ rawJson() }}</pre>\n }\n @case ('contributions') {\n <he-node-logs-models-contributions [node]=\"node()\" [nodeKey]=\"nodeKey()\" [model]=\"model()\" />\n }\n }\n </div>\n }\n }\n </div>\n}\n", styles: [".log-section{border-color:#fff3!important}.log-section-header{cursor:pointer;padding:.5rem 0}.log-section-header ::ng-deep .formula-block{margin-bottom:0;border-bottom:none}.raw-log{max-height:300px;overflow:auto;white-space:pre;font-size:.75rem;background:#00000059;color:inherit;padding:.5rem;border-radius:3px}\n"] }]
|
|
9474
9577
|
}], propDecorators: { model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: true }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }], node: [{ type: i0.Input, args: [{ isSignal: true, alias: "node", required: false }] }], nodeKey: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeKey", required: false }] }], hasContributions: [{ type: i0.Input, args: [{ isSignal: true, alias: "hasContributions", required: false }] }] } });
|
|
9475
9578
|
|
|
9476
9579
|
/**
|
|
@@ -14234,7 +14337,7 @@ ${JSON.stringify(error)}
|
|
|
14234
14337
|
|
|
14235
14338
|
## Details
|
|
14236
14339
|
|
|
14237
|
-
* Path: [open](${window.location.href})
|
|
14340
|
+
* Path: [open](${typeof window === 'undefined' ? baseUrl() : window.location.href})
|
|
14238
14341
|
* Stage: \`${fileStatus?.replace('Done', '')?.replace('Error', '')}\`
|
|
14239
14342
|
|
|
14240
14343
|
/label ~"Type::bug"
|
|
@@ -14823,7 +14926,7 @@ const mergedNodes = (selection, { tooltipOperator }) => {
|
|
|
14823
14926
|
.attr('stroke-width', '2')
|
|
14824
14927
|
.attr('rx', '3px')
|
|
14825
14928
|
.attr('ry', '3px')
|
|
14826
|
-
.style('user-select', window.innerWidth < 768 ? 'none' : null);
|
|
14929
|
+
.style('user-select', typeof window !== 'undefined' && window.innerWidth < 768 ? 'none' : null);
|
|
14827
14930
|
selection.filter(d => !d.data.group && d.data.id !== nonLCAIndicatorsId).call(addTooltip, { tooltipOperator });
|
|
14828
14931
|
selection
|
|
14829
14932
|
.selectAll('.node-label')
|
|
@@ -16695,5 +16798,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
|
|
|
16695
16798
|
* Generated bundle index. Do not edit.
|
|
16696
16799
|
*/
|
|
16697
16800
|
|
|
16698
|
-
export { ARRAY_DELIMITER, ApplyPurePipe, BarChartComponent, BibliographiesSearchConfirmComponent, BlankNodeStateComponent, BlankNodeStateNoticeComponent, BlankNodeValueDeltaComponent, CapitalizePipe, ChartComponent, ChartConfigurationDirective, ChartExportButtonComponent, ChartTooltipComponent, ClickOutsideDirective, ClipboardComponent, CollapsibleBoxComponent, CollapsibleBoxStyle, ColorPalette, CompoundDirective, CompoundPipe, ContributionChartComponent, ControlValueAccessor, CycleNodesKeyGroup, CyclesCompletenessComponent, CyclesEmissionsCategoryService, CyclesEmissionsChartComponent, CyclesFunctionalUnitMeasureComponent, CyclesMetadataComponent, CyclesNodesComponent, CyclesNodesTimelineComponent, CyclesResultComponent, DataTableComponent, DefaultPipe, DeltaColour, DistributionChartComponent, DrawerContainerComponent, DurationPipe, EllipsisPipe, EngineModelsLinkComponent, EngineModelsLookupInfoComponent, EngineModelsStageComponent, EngineModelsStageDeepComponent, EngineModelsStageDeepService, EngineModelsVersionInfoComponent, EngineModelsVersionLinkComponent, EngineOrchestratorEditComponent, EngineRequirementsFormComponent, FileSizePipe, FileUploadErrorKeys, FilesErrorSummaryComponent, FilesFormComponent, FilesFormEditableComponent, FilesUploadErrorsComponent, FilterAccordionComponent, GUIDE_ENABLED, GetPipe, GlossaryMigrationFormat, GuideOverlayComponent, HESvgIconComponent, HE_API_BASE_URL, HE_CALCULATIONS_BASE_URL, HE_MAP_LOADED, HeAuthService, HeCommonService, HeEngineService, HeGlossaryService, HeMendeleyService, HeNodeCsvService, HeNodeService, HeNodeStoreService, HeSchemaService, HeSearchService, HeToastService, HorizontalBarChartComponent, HorizontalButtonsGroupComponent, ImpactAssessmentsGraphComponent, ImpactAssessmentsIndicatorBreakdownChartComponent, ImpactAssessmentsIndicatorsChartComponent, ImpactAssessmentsProductsComponent, IsArrayPipe, IsObjectPipe, IssueConfirmComponent, KatexDirective, KeyToLabelPipe, Level, LineChartComponent, LinkKeyValueComponent, LogStatus, LongPressDirective, MAX_RESULTS, MapsDrawingComponent, MapsDrawingConfirmComponent, MaxPipe, MeanPipe, MedianPipe, MendeleySearchResult, MinPipe, MobileShellComponent, NavigationMenuComponent, NoExtPipe, NodeAggregatedComponent, NodeAggregatedInfoComponent, NodeAggregatedQualityScoreComponent, NodeCsvExportConfirmComponent, NodeCsvPreviewComponent, NodeCsvSelectHeadersComponent, NodeIconComponent, NodeJLogModelsComponent, NodeJsonldComponent, NodeJsonldSchemaComponent, NodeKeyState, NodeLinkComponent, NodeLogsFileComponent, NodeLogsModelsComponent, NodeLogsTimeComponent, NodeMissingLookupFactorsComponent, NodeQualityScore, NodeRecommendationsComponent, NodeSelectComponent, NodeValueDetailsComponent, PipelineStagesProgressComponent, PluralizePipe, PopoverComponent, PopoverConfirmComponent, PrecisionPipe, RelatedNodeResult, RemoveMarkdownPipe, RepeatPipe, Repository, ResizedDirective, ResizedEvent, ResponsiveService, SchemaInfoComponent, SchemaVersionLinkComponent, SearchExtendComponent, ShelfDialogComponent, ShellComponent, SiteNodesKeyGroup, SitesManagementChartComponent, SitesMapsComponent, SitesNodesComponent, SkeletonTextComponent, SocialTagsComponent, SortByPipe, SortSelectComponent, SumPipe, TagsInputDirective, Template, TermsPropertyContentComponent, TermsSubClassOfContentComponent, TermsUnitsDescriptionComponent, ThousandSuffixesPipe, ThousandsPipe, TimesPipe, ToastComponent, UncapitalizePipe, addPolygonToFeature, afterBarDrawPlugin, allCountriesQuery, allGroups, allOptions, availableProperties, axisHoverPlugin, backgroundHoverPlugin, baseApiUrl, baseUrl, bottom, buildSummary, bytesSize, calculateCycleDuration, calculateCycleDurationEnabled, calculateCycleStartDate, calculateCycleStartDateEnabled, capitalize, changelogUrl, clustererImage, code, colorToRgba, compoundToHtml, computeKeys, computeTerms, contactUsEmail, contactUsLink, convertToSvg, coordinatesToPoint, copyObject, countGroupVisibleNodes, countriesQuery, createMarker, cropsQuery, d3ellipse, d3wrap, dataPathLabel, dataPathToKey, dataVersionHeader, dataVersionHeaderKey, defaultFeature, defaultLabel, defaultSuggestionType, defaultSvgIconSize, defaultTicksFont, definitionToSchemaType, distinctUntilChangedDeep, downloadFile, downloadPng, downloadSvg, ellipsis, engineGitBaseUrl, engineGitUrl, errorText, evaluateSuccess, exportAsSVG, exportFormats, externalLink, externalNodeLink, fillColor, fillStyle, filterBlankNode$1 as filterBlankNode, filterParams, findConfigModels, findMatchingModel, findModels, findNodeModel, findOrchestratorModel, findProperty, findPropertyById, flatFilterData, flatFilterNode, formatCustomErrorMessage, formatDate, formatError, formatPropertyError, formatter, getColor, getDatesBetween, gitBranch, gitHome, gitlabRawUrl, glossaryBaseUrl, glossaryLink, groupChanged, groupJLogByField, groupJLogByTerm, groupLogsByTerm, groupNodesByTerm, groupdLogsByKey, grouppedKeys, grouppedValueKeys, groupsLogsByFields, guideModelUrl, guideNamespace, handleAPIError, handleGuideEvent, hasError, hasValidationError, hasWarning, hexToRgba, iconSizes, icons, ignoreKeys$2 as ignoreKeys, increaseScaleLimits, initialFilterState, injectResizeEvent$, inputGroupsTermTypes, isAddPropertyEnabled, isChrome, isDateBetween, isEqual, isExternal, isKeyClosedVisible, isKeyHidden, isMaxStage, isMethodModelAllowed, isNonNodeModelKey, isSchemaIri, isScrolledBelow, isState, isTermTypeAllowed, isValidKey, jLogModelCount, keyToDataPath, levels, listColor, listColorContinuous, listColorWithAlpha, loadMapApi, loadSvgSprite, locationQuery, logToCsv$2 as logToCsv, logValueArray, logsKey, lollipopChartPlugin, lookupUrl, mapFilterData, mapsUrl, markerIcon, markerPie, matchAggregatedQuery, matchAggregatedValidatedQuery, matchBoolPrefixQuery, matchCountry, matchExactQuery, matchGlobalRegion, matchId, matchNameNormalized, matchNestedKey, matchPhrasePrefixQuery, matchPhraseQuery, matchPrimaryProductQuery, matchQuery, matchRegex, matchRegion, matchTermType, matchType, maxAreaSize, measurementValue, mergeDataWithHeaders, methodTierOrder, migrationErrorMessage, migrationsUrl, modelCount, modelKeyParams, modelParams, models, multiMatchQuery, nestedProperty, nestingEnabled, nestingTypeEnabled, noValue, nodeAvailableProperties, nodeById, nodeColours$1 as nodeColours, nodeDataState, nodeDataStates, nodeDataVersion, nodeId, nodeIdWithoutDataVersion, nodeIds, nodeLink, nodeLinkEnabled, nodeLinkTypeEnabled, nodeLogsUrl, nodeQualityScoreColor, nodeQualityScoreLevel, nodeQualityScoreMaxDefault, nodeQualityScoreOrder, nodeRequestId, nodeSecondaryColours, nodeToAggregationFilename, nodeType, nodeTypeDataState, nodeTypeIcon, nodeTypeIconSchema, nodeUrl, nodeUrlParams, nodeVersion, nodeVersionKey, nodesByState, nodesByType, numberGte, optionsFromGroup, parentKey, parentProperty, parseColor, parseData, parseDataPath, parseLines, parseMessage, parseNewValue, pluralize, pointToCoordinates, polygonBounds, polygonToCoordinates, polygonToMap, polygonsFromFeature, populateWithTrackIdsFilterData, postGuideEvent, primaryProduct, productsQuery, propertyError, propertyId, recursiveProperties, refToSchemaType, refreshPropertyKeys, regionsQuery, registerChart, repeat, reportIssueLink, reportIssueUrl, safeJSONParse, safeJSONStringify, schemaBaseUrl, schemaDataBaseUrl, schemaLink, schemaRequiredProperties, schemaTypeToDefaultValue, scrollToEl, scrollTop, searchFilterData, searchableTypes, siblingProperty, simplifyContributions, singleProperty, siteTooBig, siteTypeToColor, siteTypeToIcon, sortProperties, sortedDates, strokeColor, strokeStyle, subValueKeys, suggestMatchQuery, suggestQuery, takeAfterViewInit, termLocation, termLocationName, termProperties, termTypeLabel, toSnakeCase, toThousands, typeToNewProperty, typeaheadFocus, uncapitalize, uniqueDatesBetween, updateProperties, valueLink, valueToString, valueTypeToDefault, valueValue, waitFor, wildcardQuery };
|
|
16801
|
+
export { ARRAY_DELIMITER, ApplyPurePipe, BarChartComponent, BibliographiesSearchConfirmComponent, BlankNodeStateComponent, BlankNodeStateNoticeComponent, BlankNodeValueDeltaComponent, CapitalizePipe, ChartComponent, ChartConfigurationDirective, ChartExportButtonComponent, ChartTooltipComponent, ClickOutsideDirective, ClipboardComponent, CollapsibleBoxComponent, CollapsibleBoxStyle, ColorPalette, CompoundDirective, CompoundPipe, ContributionChartComponent, ControlValueAccessor, CycleNodesKeyGroup, CyclesCompletenessComponent, CyclesEmissionsCategoryService, CyclesEmissionsChartComponent, CyclesFunctionalUnitMeasureComponent, CyclesMetadataComponent, CyclesNodesComponent, CyclesNodesTimelineComponent, CyclesResultComponent, DataTableComponent, DefaultPipe, DeltaColour, DistributionChartComponent, DrawerContainerComponent, DurationPipe, EllipsisPipe, EngineModelsLinkComponent, EngineModelsLookupInfoComponent, EngineModelsStageComponent, EngineModelsStageDeepComponent, EngineModelsStageDeepService, EngineModelsVersionInfoComponent, EngineModelsVersionLinkComponent, EngineOrchestratorEditComponent, EngineRequirementsFormComponent, FileSizePipe, FileUploadErrorKeys, FilesErrorSummaryComponent, FilesFormComponent, FilesFormEditableComponent, FilesUploadErrorsComponent, FilterAccordionComponent, GUIDE_ENABLED, GetPipe, GlossaryMigrationFormat, GuideOverlayComponent, HESvgIconComponent, HE_API_BASE_URL, HE_CALCULATIONS_BASE_URL, HE_MAP_LOADED, HeAuthService, HeCommonService, HeEngineService, HeGlossaryService, HeMendeleyService, HeNodeCsvService, HeNodeService, HeNodeStoreService, HeSchemaService, HeSearchService, HeToastService, HorizontalBarChartComponent, HorizontalButtonsGroupComponent, ImpactAssessmentsGraphComponent, ImpactAssessmentsIndicatorBreakdownChartComponent, ImpactAssessmentsIndicatorsChartComponent, ImpactAssessmentsProductsComponent, IsArrayPipe, IsObjectPipe, IssueConfirmComponent, KatexDirective, KeyToLabelPipe, Level, LineChartComponent, LinkKeyValueComponent, LogStatus, LongPressDirective, MAX_RESULTS, MapsDrawingComponent, MapsDrawingConfirmComponent, MaxPipe, MeanPipe, MedianPipe, MendeleySearchResult, MinPipe, MobileShellComponent, NavigationMenuComponent, NoExtPipe, NodeAggregatedComponent, NodeAggregatedInfoComponent, NodeAggregatedQualityScoreComponent, NodeCsvExportConfirmComponent, NodeCsvPreviewComponent, NodeCsvSelectHeadersComponent, NodeIconComponent, NodeJLogModelsComponent, NodeJsonldComponent, NodeJsonldSchemaComponent, NodeKeyState, NodeLinkComponent, NodeLogsFileComponent, NodeLogsModelsComponent, NodeLogsTimeComponent, NodeMissingLookupFactorsComponent, NodeQualityScore, NodeRecommendationsComponent, NodeSelectComponent, NodeValueDetailsComponent, PipelineStagesProgressComponent, PluralizePipe, PopoverComponent, PopoverConfirmComponent, PrecisionPipe, RelatedNodeResult, RemoveMarkdownPipe, RepeatPipe, Repository, ResizedDirective, ResizedEvent, ResponsiveService, SchemaInfoComponent, SchemaVersionLinkComponent, SearchExtendComponent, ShelfDialogComponent, ShellComponent, SiteNodesKeyGroup, SitesManagementChartComponent, SitesMapsComponent, SitesNodesComponent, SkeletonTextComponent, SocialTagsComponent, SortByPipe, SortSelectComponent, SumPipe, TagsInputDirective, Template, TermsPropertyContentComponent, TermsSubClassOfContentComponent, TermsUnitsDescriptionComponent, ThousandSuffixesPipe, ThousandsPipe, TimesPipe, ToastComponent, UncapitalizePipe, addPolygonToFeature, afterBarDrawPlugin, allCountriesQuery, allGroups, allOptions, availableProperties, axisHoverPlugin, backgroundHoverPlugin, baseApiUrl, baseUrl, bottom, buildSummary, bytesSize, calculateCycleDuration, calculateCycleDurationEnabled, calculateCycleStartDate, calculateCycleStartDateEnabled, capitalize, changelogUrl, clustererImage, code, colorToRgba, compoundToHtml, computeKeys, computeTerms, contactUsEmail, contactUsLink, convertToSvg, coordinatesToPoint, copyObject, countGroupVisibleNodes, countriesQuery, createMarker, cropsQuery, d3ellipse, d3wrap, dataPathLabel, dataPathToKey, dataVersionHeader, dataVersionHeaderKey, defaultFeature, defaultLabel, defaultSuggestionType, defaultSvgIconSize, defaultTicksFont, definitionToSchemaType, distinctUntilChangedDeep, downloadFile, downloadPng, downloadSvg, ellipsis, engineGitBaseUrl, engineGitUrl, errorText, evaluateSuccess, exportAsSVG, exportFormats, externalLink, externalNodeLink, fillColor, fillStyle, filterBlankNode$1 as filterBlankNode, filterParams, findConfigModels, findMatchingModel, findModels, findNodeModel, findOrchestratorModel, findProperty, findPropertyById, flatFilterData, flatFilterNode, formatCustomErrorMessage, formatDate, formatError, formatPropertyError, formatter, getColor, getDatesBetween, gitBranch, gitHome, gitlabRawUrl, glossaryBaseUrl, glossaryLink, groupChanged, groupDataByCategory, groupJLogByField, groupJLogByTerm, groupLogsByTerm, groupNodesByTerm, groupdLogsByKey, grouppedKeys, grouppedValueKeys, groupsLogsByFields, guideModelUrl, guideNamespace, handleAPIError, handleGuideEvent, hasError, hasValidationError, hasWarning, hexToRgba, iconSizes, icons, ignoreKeys$2 as ignoreKeys, increaseScaleLimits, initialFilterState, injectResizeEvent$, inputGroupsTermTypes, isAddPropertyEnabled, isChrome, isDateBetween, isEqual, isExternal, isKeyClosedVisible, isKeyHidden, isMaxStage, isMethodModelAllowed, isNonNodeModelKey, isSchemaIri, isScrolledBelow, isState, isTermTypeAllowed, isValidKey, jLogModelCount, keyToDataPath, levels, listColor, listColorContinuous, listColorWithAlpha, loadMapApi, loadSvgSprite, locationQuery, logToCsv$2 as logToCsv, logValueArray, logsKey, lollipopChartPlugin, lookupUrl, mapFilterData, mapsUrl, markerIcon, markerPie, matchAggregatedQuery, matchAggregatedValidatedQuery, matchBoolPrefixQuery, matchCountry, matchExactQuery, matchGlobalRegion, matchId, matchNameNormalized, matchNestedKey, matchPhrasePrefixQuery, matchPhraseQuery, matchPrimaryProductQuery, matchQuery, matchRegex, matchRegion, matchTermType, matchType, maxAreaSize, measurementValue, mergeDataWithHeaders, methodTierOrder, migrationErrorMessage, migrationsUrl, modelCount, modelKeyParams, modelParams, models, multiMatchQuery, nestedProperty, nestingEnabled, nestingTypeEnabled, noValue, nodeAvailableProperties, nodeById, nodeColours$1 as nodeColours, nodeDataState, nodeDataStates, nodeDataVersion, nodeId, nodeIdWithoutDataVersion, nodeIds, nodeLink, nodeLinkEnabled, nodeLinkTypeEnabled, nodeLogsUrl, nodeQualityScoreColor, nodeQualityScoreLevel, nodeQualityScoreMaxDefault, nodeQualityScoreOrder, nodeRequestId, nodeSecondaryColours, nodeToAggregationFilename, nodeType, nodeTypeDataState, nodeTypeIcon, nodeTypeIconSchema, nodeUrl, nodeUrlParams, nodeVersion, nodeVersionKey, nodesByState, nodesByType, numberGte, optionsFromGroup, parentKey, parentProperty, parseColor, parseData, parseDataPath, parseLines, parseMessage, parseNewValue, pluralize, pointToCoordinates, polygonBounds, polygonToCoordinates, polygonToMap, polygonsFromFeature, populateWithTrackIdsFilterData, postGuideEvent, primaryProduct, productsQuery, propertyError, propertyId, recursiveProperties, refToSchemaType, refreshPropertyKeys, regionsQuery, registerChart, repeat, reportIssueLink, reportIssueUrl, safeJSONParse, safeJSONStringify, schemaBaseUrl, schemaDataBaseUrl, schemaLink, schemaRequiredProperties, schemaTypeToDefaultValue, scrollToEl, scrollTop, searchFilterData, searchableTypes, siblingProperty, simplifyContributions, singleProperty, siteTooBig, siteTypeToColor, siteTypeToIcon, sortProperties, sortedDates, strokeColor, strokeStyle, subValueKeys, suggestMatchQuery, suggestQuery, sumValues, takeAfterViewInit, termLocation, termLocationName, termProperties, termTypeLabel, toSnakeCase, toThousands, typeToNewProperty, typeaheadFocus, uncapitalize, uniqueDatesBetween, updateProperties, valueLink, valueToString, valueTypeToDefault, valueValue, waitFor, wildcardQuery };
|
|
16699
16802
|
//# sourceMappingURL=hestia-earth-ui-components.mjs.map
|