@ngfly/carousel
Version:
A smooth, customizable carousel component for Angular 17+ applications
206 lines • 24.4 kB
JavaScript
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import * as i0 from "@angular/core";
/**
* Default carousel configuration values
*/
export const CAROUSEL_DEFAULTS = {
NAVIGATION_SIZE: '32px',
CONTENT_PADDING: '10px',
ANIMATION_DURATION: '300ms',
ANIMATION_TIMING: 'ease',
EMPTY_STATE_HEIGHT: '200px',
NAVIGATION_PREV_ICON: '❮',
NAVIGATION_NEXT_ICON: '❯',
INDICATOR_SIZE: '10px',
INDICATOR_SPACING: '5px',
INDICATOR_ACTIVE_COLOR: '#333',
INDICATOR_INACTIVE_COLOR: '#ccc',
INDICATOR_ACTIVE_OPACITY: '1',
INDICATOR_INACTIVE_OPACITY: '0.5',
INDICATOR_ANIMATION_DURATION: '250ms',
INDICATOR_ANIMATION_TIMING: 'ease',
INDICATOR_TRANSITION: 'all 0.3s ease-in-out'
};
/**
* Service for carousel-related functionality and state management
*/
export class CarouselService {
constructor() {
// Visibility state
this.isVisibleSubject = new BehaviorSubject(true);
this.isVisible$ = this.isVisibleSubject.asObservable();
}
/**
* Set carousel visibility
* @param visible Whether carousel is visible
*/
setVisibility(visible) {
this.isVisibleSubject.next(visible);
}
/**
* Get button shape styles based on the configured shape
* @param shape Button shape type
* @returns Style object
*/
getButtonShapeStyles(shape) {
const styles = {};
switch (shape) {
case 'circle':
styles['borderRadius'] = '50%';
break;
case 'rounded':
styles['borderRadius'] = '8px';
break;
case 'square':
default:
styles['borderRadius'] = '0';
}
return styles;
}
/**
* Get indicator styles
* @param config Indicator style configuration
* @param isActive Whether to get active or inactive styles
* @returns Style object
*/
getIndicatorStyles(config, isActive = false) {
// Base styles for both active and inactive
const baseStyles = {
width: CAROUSEL_DEFAULTS.INDICATOR_SIZE,
height: CAROUSEL_DEFAULTS.INDICATOR_SIZE,
display: 'inline-block',
transition: config?.transition || (config?.animation?.timing
? `all ${config.animation.duration || CAROUSEL_DEFAULTS.INDICATOR_ANIMATION_DURATION} ${config.animation.timing}`
: CAROUSEL_DEFAULTS.INDICATOR_TRANSITION),
cursor: 'pointer',
margin: `0 ${config?.spacing || CAROUSEL_DEFAULTS.INDICATOR_SPACING}`,
borderRadius: '50%' // Default circle shape
};
// Active/inactive specific styles
if (isActive) {
baseStyles['backgroundColor'] = CAROUSEL_DEFAULTS.INDICATOR_ACTIVE_COLOR;
baseStyles['opacity'] = CAROUSEL_DEFAULTS.INDICATOR_ACTIVE_OPACITY;
baseStyles['transform'] = 'scale(1.2)';
// Add animation if enabled and not explicitly disabled
const animEnabled = config?.animation?.enabled !== false;
const animType = config?.animation?.type || 'pulse';
if (animEnabled && animType !== 'none') {
if (animType === 'custom' && config?.animation?.custom) {
baseStyles['animation'] = config.animation.custom;
}
else if (animType === 'pulse') {
baseStyles['animation'] = `indicator-pulse 1s infinite alternate`;
}
}
// Apply custom active styles if provided (these override defaults)
if (config?.active) {
Object.assign(baseStyles, config.active);
}
}
else {
baseStyles['backgroundColor'] = CAROUSEL_DEFAULTS.INDICATOR_INACTIVE_COLOR;
baseStyles['opacity'] = CAROUSEL_DEFAULTS.INDICATOR_INACTIVE_OPACITY;
baseStyles['transform'] = 'scale(1)';
// Apply custom inactive styles if provided (these override defaults)
if (config?.inactive) {
Object.assign(baseStyles, config.inactive);
}
}
return baseStyles;
}
/**
* Get indicator container styles based on configuration
* @param config Indicator style configuration
* @returns Style object for container
*/
getIndicatorContainerStyles(config) {
const styles = {
position: 'absolute',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
zIndex: '100',
padding: '10px',
pointerEvents: 'auto'
};
// Default position (bottom center)
styles['bottom'] = config?.position?.bottom || '4px';
styles['left'] = config?.position?.left || '50%';
styles['transform'] = 'translateX(-50%)';
// Override with custom positions if provided
if (config?.position) {
Object.keys(config.position).forEach(key => {
const position = config.position;
if (position[key]) {
styles[key] = position[key];
}
});
// Handle transformations for centered positioning
if (config.position.left === '50%' && !styles['transform']) {
styles['transform'] = 'translateX(-50%)';
}
else if (config.position.top === '50%' && !styles['transform']) {
styles['transform'] = 'translateY(-50%)';
}
}
// Apply custom container styles if provided
if (config?.container) {
Object.assign(styles, config.container);
}
return styles;
}
/**
* Get navigation icons based on orientation
* @param isVertical Whether carousel is vertical
* @param icons Custom icon configuration
* @returns Previous and next icons
*/
getNavigationIcons(isVertical, icons) {
const defaultIcons = {
horizontal: {
prev: CAROUSEL_DEFAULTS.NAVIGATION_PREV_ICON,
next: CAROUSEL_DEFAULTS.NAVIGATION_NEXT_ICON
},
vertical: {
prev: CAROUSEL_DEFAULTS.NAVIGATION_PREV_ICON,
next: CAROUSEL_DEFAULTS.NAVIGATION_NEXT_ICON
}
};
const customIcons = icons || {};
const verticalIcons = customIcons.vertical || {};
return {
prev: isVertical
? (verticalIcons.prev || defaultIcons.vertical.prev)
: (customIcons.prev || defaultIcons.horizontal.prev),
next: isVertical
? (verticalIcons.next || defaultIcons.vertical.next)
: (customIcons.next || defaultIcons.horizontal.next)
};
}
/**
* Parse time string to milliseconds
* @param time Time string (e.g., '300ms', '0.5s')
* @returns Time in milliseconds
*/
parseTimeToMs(time) {
if (!time)
return 300; // Default 300ms
if (time.endsWith('ms')) {
return parseInt(time.slice(0, -2), 10);
}
if (time.endsWith('s')) {
return parseFloat(time.slice(0, -1)) * 1000;
}
return parseInt(time, 10);
}
}
CarouselService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CarouselService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
CarouselService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CarouselService, providedIn: 'root' });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.3.0", ngImport: i0, type: CarouselService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root'
}]
}] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2Fyb3VzZWwuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvc2VydmljZXMvY2Fyb3VzZWwuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxNQUFNLENBQUM7O0FBR3ZDOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUc7SUFDL0IsZUFBZSxFQUFFLE1BQU07SUFDdkIsZUFBZSxFQUFFLE1BQU07SUFDdkIsa0JBQWtCLEVBQUUsT0FBTztJQUMzQixnQkFBZ0IsRUFBRSxNQUFNO0lBQ3hCLGtCQUFrQixFQUFFLE9BQU87SUFDM0Isb0JBQW9CLEVBQUUsR0FBRztJQUN6QixvQkFBb0IsRUFBRSxHQUFHO0lBQ3pCLGNBQWMsRUFBRSxNQUFNO0lBQ3RCLGlCQUFpQixFQUFFLEtBQUs7SUFDeEIsc0JBQXNCLEVBQUUsTUFBTTtJQUM5Qix3QkFBd0IsRUFBRSxNQUFNO0lBQ2hDLHdCQUF3QixFQUFFLEdBQUc7SUFDN0IsMEJBQTBCLEVBQUUsS0FBSztJQUNqQyw0QkFBNEIsRUFBRSxPQUFPO0lBQ3JDLDBCQUEwQixFQUFFLE1BQU07SUFDbEMsb0JBQW9CLEVBQUUsc0JBQXNCO0NBQzdDLENBQUM7QUFFRjs7R0FFRztBQUlILE1BQU0sT0FBTyxlQUFlO0lBSDVCO1FBSUUsbUJBQW1CO1FBQ1gscUJBQWdCLEdBQUcsSUFBSSxlQUFlLENBQVUsSUFBSSxDQUFDLENBQUM7UUFDOUQsZUFBVSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxZQUFZLEVBQUUsQ0FBQztLQXdMbkQ7SUF0TEM7OztPQUdHO0lBQ0gsYUFBYSxDQUFDLE9BQWdCO1FBQzVCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDdEMs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LENBQUMsQ0FBQyxXQUFXLENBQUMsSUFBSSxJQUFJLFlBQVksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDO1NBQ3ZELENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILGFBQWEsQ0FBQyxJQUFZO1FBQ3hCLElBQUksQ0FBQyxJQUFJO1lBQUUsT0FBTyxHQUFHLENBQUMsQ0FBQyxnQkFBZ0I7UUFFdkMsSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFO1lBQ3ZCLE9BQU8sUUFBUSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7U0FDeEM7UUFFRCxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDdEIsT0FBTyxVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQztTQUM3QztRQUVELE9BQU8sUUFBUSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQztJQUM1QixDQUFDOzs0R0ExTFUsZUFBZTtnSEFBZixlQUFlLGNBRmQsTUFBTTsyRkFFUCxlQUFlO2tCQUgzQixVQUFVO21CQUFDO29CQUNWLFVBQVUsRUFBRSxNQUFNO2lCQUNuQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgTmF2QnV0dG9uU2hhcGUsIEluZGljYXRvclN0eWxlIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9jYXJvdXNlbC1jb25maWcuaW50ZXJmYWNlJztcblxuLyoqXG4gKiBEZWZhdWx0IGNhcm91c2VsIGNvbmZpZ3VyYXRpb24gdmFsdWVzXG4gKi9cbmV4cG9ydCBjb25zdCBDQVJPVVNFTF9ERUZBVUxUUyA9IHtcbiAgTkFWSUdBVElPTl9TSVpFOiAnMzJweCcsXG4gIENPTlRFTlRfUEFERElORzogJzEwcHgnLFxuICBBTklNQVRJT05fRFVSQVRJT046ICczMDBtcycsXG4gIEFOSU1BVElPTl9USU1JTkc6ICdlYXNlJyxcbiAgRU1QVFlfU1RBVEVfSEVJR0hUOiAnMjAwcHgnLFxuICBOQVZJR0FUSU9OX1BSRVZfSUNPTjogJ+KdricsXG4gIE5BVklHQVRJT05fTkVYVF9JQ09OOiAn4p2vJyxcbiAgSU5ESUNBVE9SX1NJWkU6ICcxMHB4JyxcbiAgSU5ESUNBVE9SX1NQQUNJTkc6ICc1cHgnLFxuICBJTkRJQ0FUT1JfQUNUSVZFX0NPTE9SOiAnIzMzMycsXG4gIElORElDQVRPUl9JTkFDVElWRV9DT0xPUjogJyNjY2MnLFxuICBJTkRJQ0FUT1JfQUNUSVZFX09QQUNJVFk6ICcxJyxcbiAgSU5ESUNBVE9SX0lOQUNUSVZFX09QQUNJVFk6ICcwLjUnLFxuICBJTkRJQ0FUT1JfQU5JTUFUSU9OX0RVUkFUSU9OOiAnMjUwbXMnLFxuICBJTkRJQ0FUT1JfQU5JTUFUSU9OX1RJTUlORzogJ2Vhc2UnLFxuICBJTkRJQ0FUT1JfVFJBTlNJVElPTjogJ2FsbCAwLjNzIGVhc2UtaW4tb3V0J1xufTtcblxuLyoqXG4gKiBTZXJ2aWNlIGZvciBjYXJvdXNlbC1yZWxhdGVkIGZ1bmN0aW9uYWxpdHkgYW5kIHN0YXRlIG1hbmFnZW1lbnRcbiAqL1xuQEluamVjdGFibGUoe1xuICBwcm92aWRlZEluOiAncm9vdCdcbn0pXG5leHBvcnQgY2xhc3MgQ2Fyb3VzZWxTZXJ2aWNlIHtcbiAgLy8gVmlzaWJpbGl0eSBzdGF0ZVxuICBwcml2YXRlIGlzVmlzaWJsZVN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KHRydWUpO1xuICBpc1Zpc2libGUkID0gdGhpcy5pc1Zpc2libGVTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIC8qKlxuICAgKiBTZXQgY2Fyb3VzZWwgdmlzaWJpbGl0eVxuICAgKiBAcGFyYW0gdmlzaWJsZSBXaGV0aGVyIGNhcm91c2VsIGlzIHZpc2libGVcbiAgICovXG4gIHNldFZpc2liaWxpdHkodmlzaWJsZTogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuaXNWaXNpYmxlU3ViamVjdC5uZXh0KHZpc2libGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBidXR0b24gc2hhcGUgc3R5bGVzIGJhc2VkIG9uIHRoZSBjb25maWd1cmVkIHNoYXBlXG4gICAqIEBwYXJhbSBzaGFwZSBCdXR0b24gc2hhcGUgdHlwZVxuICAgKiBAcmV0dXJucyBTdHlsZSBvYmplY3RcbiAgICovXG4gIGdldEJ1dHRvblNoYXBlU3R5bGVzKHNoYXBlPzogTmF2QnV0dG9uU2hhcGUpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgICBjb25zdCBzdHlsZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgICBcbiAgICBzd2l0Y2ggKHNoYXBlKSB7XG4gICAgICBjYXNlICdjaXJjbGUnOlxuICAgICAgICBzdHlsZXNbJ2JvcmRlclJhZGl1cyddID0gJzUwJSc7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAncm91bmRlZCc6XG4gICAgICAgIHN0eWxlc1snYm9yZGVyUmFkaXVzJ10gPSAnOHB4JztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdzcXVhcmUnOlxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgc3R5bGVzWydib3JkZXJSYWRpdXMnXSA9ICcwJztcbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIHN0eWxlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgaW5kaWNhdG9yIHN0eWxlc1xuICAgKiBAcGFyYW0gY29uZmlnIEluZGljYXRvciBzdHlsZSBjb25maWd1cmF0aW9uXG4gICAqIEBwYXJhbSBpc0FjdGl2ZSBXaGV0aGVyIHRvIGdldCBhY3RpdmUgb3IgaW5hY3RpdmUgc3R5bGVzXG4gICAqIEByZXR1cm5zIFN0eWxlIG9iamVjdFxuICAgKi9cbiAgZ2V0SW5kaWNhdG9yU3R5bGVzKGNvbmZpZz86IEluZGljYXRvclN0eWxlLCBpc0FjdGl2ZSA9IGZhbHNlKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gICAgLy8gQmFzZSBzdHlsZXMgZm9yIGJvdGggYWN0aXZlIGFuZCBpbmFjdGl2ZVxuICAgIGNvbnN0IGJhc2VTdHlsZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICB3aWR0aDogQ0FST1VTRUxfREVGQVVMVFMuSU5ESUNBVE9SX1NJWkUsXG4gICAgICBoZWlnaHQ6IENBUk9VU0VMX0RFRkFVTFRTLklORElDQVRPUl9TSVpFLFxuICAgICAgZGlzcGxheTogJ2lubGluZS1ibG9jaycsXG4gICAgICB0cmFuc2l0aW9uOiBjb25maWc/LnRyYW5zaXRpb24gfHwgKGNvbmZpZz8uYW5pbWF0aW9uPy50aW1pbmcgXG4gICAgICAgID8gYGFsbCAke2NvbmZpZy5hbmltYXRpb24uZHVyYXRpb24gfHwgQ0FST1VTRUxfREVGQVVMVFMuSU5ESUNBVE9SX0FOSU1BVElPTl9EVVJBVElPTn0gJHtjb25maWcuYW5pbWF0aW9uLnRpbWluZ31gXG4gICAgICAgIDogQ0FST1VTRUxfREVGQVVMVFMuSU5ESUNBVE9SX1RSQU5TSVRJT04pLFxuICAgICAgY3Vyc29yOiAncG9pbnRlcicsXG4gICAgICBtYXJnaW46IGAwICR7Y29uZmlnPy5zcGFjaW5nIHx8IENBUk9VU0VMX0RFRkFVTFRTLklORElDQVRPUl9TUEFDSU5HfWAsXG4gICAgICBib3JkZXJSYWRpdXM6ICc1MCUnIC8vIERlZmF1bHQgY2lyY2xlIHNoYXBlXG4gICAgfTtcbiAgICBcbiAgICAvLyBBY3RpdmUvaW5hY3RpdmUgc3BlY2lmaWMgc3R5bGVzXG4gICAgaWYgKGlzQWN0aXZlKSB7XG4gICAgICBiYXNlU3R5bGVzWydiYWNrZ3JvdW5kQ29sb3InXSA9IENBUk9VU0VMX0RFRkFVTFRTLklORElDQVRPUl9BQ1RJVkVfQ09MT1I7XG4gICAgICBiYXNlU3R5bGVzWydvcGFjaXR5J10gPSBDQVJPVVNFTF9ERUZBVUxUUy5JTkRJQ0FUT1JfQUNUSVZFX09QQUNJVFk7XG4gICAgICBiYXNlU3R5bGVzWyd0cmFuc2Zvcm0nXSA9ICdzY2FsZSgxLjIpJztcbiAgICAgIFxuICAgICAgLy8gQWRkIGFuaW1hdGlvbiBpZiBlbmFibGVkIGFuZCBub3QgZXhwbGljaXRseSBkaXNhYmxlZFxuICAgICAgY29uc3QgYW5pbUVuYWJsZWQgPSBjb25maWc/LmFuaW1hdGlvbj8uZW5hYmxlZCAhPT0gZmFsc2U7XG4gICAgICBjb25zdCBhbmltVHlwZSA9IGNvbmZpZz8uYW5pbWF0aW9uPy50eXBlIHx8ICdwdWxzZSc7XG4gICAgICBcbiAgICAgIGlmIChhbmltRW5hYmxlZCAmJiBhbmltVHlwZSAhPT0gJ25vbmUnKSB7XG4gICAgICAgIGlmIChhbmltVHlwZSA9PT0gJ2N1c3RvbScgJiYgY29uZmlnPy5hbmltYXRpb24/LmN1c3RvbSkge1xuICAgICAgICAgIGJhc2VTdHlsZXNbJ2FuaW1hdGlvbiddID0gY29uZmlnLmFuaW1hdGlvbi5jdXN0b207XG4gICAgICAgIH0gZWxzZSBpZiAoYW5pbVR5cGUgPT09ICdwdWxzZScpIHtcbiAgICAgICAgICBiYXNlU3R5bGVzWydhbmltYXRpb24nXSA9IGBpbmRpY2F0b3ItcHVsc2UgMXMgaW5maW5pdGUgYWx0ZXJuYXRlYDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBBcHBseSBjdXN0b20gYWN0aXZlIHN0eWxlcyBpZiBwcm92aWRlZCAodGhlc2Ugb3ZlcnJpZGUgZGVmYXVsdHMpXG4gICAgICBpZiAoY29uZmlnPy5hY3RpdmUpIHtcbiAgICAgICAgT2JqZWN0LmFzc2lnbihiYXNlU3R5bGVzLCBjb25maWcuYWN0aXZlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgYmFzZVN0eWxlc1snYmFja2dyb3VuZENvbG9yJ10gPSBDQVJPVVNFTF9ERUZBVUxUUy5JTkRJQ0FUT1JfSU5BQ1RJVkVfQ09MT1I7XG4gICAgICBiYXNlU3R5bGVzWydvcGFjaXR5J10gPSBDQVJPVVNFTF9ERUZBVUxUUy5JTkRJQ0FUT1JfSU5BQ1RJVkVfT1BBQ0lUWTtcbiAgICAgIGJhc2VTdHlsZXNbJ3RyYW5zZm9ybSddID0gJ3NjYWxlKDEpJztcbiAgICAgIFxuICAgICAgLy8gQXBwbHkgY3VzdG9tIGluYWN0aXZlIHN0eWxlcyBpZiBwcm92aWRlZCAodGhlc2Ugb3ZlcnJpZGUgZGVmYXVsdHMpXG4gICAgICBpZiAoY29uZmlnPy5pbmFjdGl2ZSkge1xuICAgICAgICBPYmplY3QuYXNzaWduKGJhc2VTdHlsZXMsIGNvbmZpZy5pbmFjdGl2ZSk7XG4gICAgICB9XG4gICAgfVxuICAgIFxuICAgIHJldHVybiBiYXNlU3R5bGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBpbmRpY2F0b3IgY29udGFpbmVyIHN0eWxlcyBiYXNlZCBvbiBjb25maWd1cmF0aW9uXG4gICAqIEBwYXJhbSBjb25maWcgSW5kaWNhdG9yIHN0eWxlIGNvbmZpZ3VyYXRpb25cbiAgICogQHJldHVybnMgU3R5bGUgb2JqZWN0IGZvciBjb250YWluZXJcbiAgICovXG4gIGdldEluZGljYXRvckNvbnRhaW5lclN0eWxlcyhjb25maWc/OiBJbmRpY2F0b3JTdHlsZSk6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICAgIGNvbnN0IHN0eWxlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgZGlzcGxheTogJ2ZsZXgnLFxuICAgICAganVzdGlmeUNvbnRlbnQ6ICdjZW50ZXInLFxuICAgICAgYWxpZ25JdGVtczogJ2NlbnRlcicsXG4gICAgICB6SW5kZXg6ICcxMDAnLFxuICAgICAgcGFkZGluZzogJzEwcHgnLFxuICAgICAgcG9pbnRlckV2ZW50czogJ2F1dG8nXG4gICAgfTtcbiAgICBcbiAgICAvLyBEZWZhdWx0IHBvc2l0aW9uIChib3R0b20gY2VudGVyKVxuICAgIHN0eWxlc1snYm90dG9tJ10gPSBjb25maWc/LnBvc2l0aW9uPy5ib3R0b20gfHwgJzRweCc7XG4gICAgc3R5bGVzWydsZWZ0J10gPSBjb25maWc/LnBvc2l0aW9uPy5sZWZ0IHx8ICc1MCUnO1xuICAgIHN0eWxlc1sndHJhbnNmb3JtJ10gPSAndHJhbnNsYXRlWCgtNTAlKSc7XG4gICAgXG4gICAgLy8gT3ZlcnJpZGUgd2l0aCBjdXN0b20gcG9zaXRpb25zIGlmIHByb3ZpZGVkXG4gICAgaWYgKGNvbmZpZz8ucG9zaXRpb24pIHtcbiAgICAgIE9iamVjdC5rZXlzKGNvbmZpZy5wb3NpdGlvbikuZm9yRWFjaChrZXkgPT4ge1xuICAgICAgICBjb25zdCBwb3NpdGlvbiA9IGNvbmZpZy5wb3NpdGlvbiBhcyBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+O1xuICAgICAgICBpZiAocG9zaXRpb25ba2V5XSkge1xuICAgICAgICAgIHN0eWxlc1trZXldID0gcG9zaXRpb25ba2V5XSBhcyBzdHJpbmc7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgXG4gICAgICAvLyBIYW5kbGUgdHJhbnNmb3JtYXRpb25zIGZvciBjZW50ZXJlZCBwb3NpdGlvbmluZ1xuICAgICAgaWYgKGNvbmZpZy5wb3NpdGlvbi5sZWZ0ID09PSAnNTAlJyAmJiAhc3R5bGVzWyd0cmFuc2Zvcm0nXSkge1xuICAgICAgICBzdHlsZXNbJ3RyYW5zZm9ybSddID0gJ3RyYW5zbGF0ZVgoLTUwJSknO1xuICAgICAgfSBlbHNlIGlmIChjb25maWcucG9zaXRpb24udG9wID09PSAnNTAlJyAmJiAhc3R5bGVzWyd0cmFuc2Zvcm0nXSkge1xuICAgICAgICBzdHlsZXNbJ3RyYW5zZm9ybSddID0gJ3RyYW5zbGF0ZVkoLTUwJSknO1xuICAgICAgfVxuICAgIH1cbiAgICBcbiAgICAvLyBBcHBseSBjdXN0b20gY29udGFpbmVyIHN0eWxlcyBpZiBwcm92aWRlZFxuICAgIGlmIChjb25maWc/LmNvbnRhaW5lcikge1xuICAgICAgT2JqZWN0LmFzc2lnbihzdHlsZXMsIGNvbmZpZy5jb250YWluZXIpO1xuICAgIH1cbiAgICBcbiAgICByZXR1cm4gc3R5bGVzO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldCBuYXZpZ2F0aW9uIGljb25zIGJhc2VkIG9uIG9yaWVudGF0aW9uXG4gICAqIEBwYXJhbSBpc1ZlcnRpY2FsIFdoZXRoZXIgY2Fyb3VzZWwgaXMgdmVydGljYWxcbiAgICogQHBhcmFtIGljb25zIEN1c3RvbSBpY29uIGNvbmZpZ3VyYXRpb25cbiAgICogQHJldHVybnMgUHJldmlvdXMgYW5kIG5leHQgaWNvbnNcbiAgICovXG4gIGdldE5hdmlnYXRpb25JY29ucyhpc1ZlcnRpY2FsOiBib29sZWFuLCBpY29ucz86IGFueSk6IHsgcHJldjogc3RyaW5nOyBuZXh0OiBzdHJpbmcgfSB7XG4gICAgY29uc3QgZGVmYXVsdEljb25zID0ge1xuICAgICAgaG9yaXpvbnRhbDoge1xuICAgICAgICBwcmV2OiBDQVJPVVNFTF9ERUZBVUxUUy5OQVZJR0FUSU9OX1BSRVZfSUNPTixcbiAgICAgICAgbmV4dDogQ0FST1VTRUxfREVGQVVMVFMuTkFWSUdBVElPTl9ORVhUX0lDT05cbiAgICAgIH0sXG4gICAgICB2ZXJ0aWNhbDoge1xuICAgICAgICBwcmV2OiBDQVJPVVNFTF9ERUZBVUxUUy5OQVZJR0FUSU9OX1BSRVZfSUNPTiwgXG4gICAgICAgIG5leHQ6IENBUk9VU0VMX0RFRkFVTFRTLk5BVklHQVRJT05fTkVYVF9JQ09OXG4gICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0IGN1c3RvbUljb25zID0gaWNvbnMgfHwge307XG4gICAgY29uc3QgdmVydGljYWxJY29ucyA9IGN1c3RvbUljb25zLnZlcnRpY2FsIHx8IHt9O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHByZXY6IGlzVmVydGljYWxcbiAgICAgICAgPyAodmVydGljYWxJY29ucy5wcmV2IHx8IGRlZmF1bHRJY29ucy52ZXJ0aWNhbC5wcmV2KVxuICAgICAgICA6IChjdXN0b21JY29ucy5wcmV2IHx8IGRlZmF1bHRJY29ucy5ob3Jpem9udGFsLnByZXYpLFxuICAgICAgbmV4dDogaXNWZXJ0aWNhbFxuICAgICAgICA/ICh2ZXJ0aWNhbEljb25zLm5leHQgfHwgZGVmYXVsdEljb25zLnZlcnRpY2FsLm5leHQpXG4gICAgICAgIDogKGN1c3RvbUljb25zLm5leHQgfHwgZGVmYXVsdEljb25zLmhvcml6b250YWwubmV4dClcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFBhcnNlIHRpbWUgc3RyaW5nIHRvIG1pbGxpc2Vjb25kc1xuICAgKiBAcGFyYW0gdGltZSBUaW1lIHN0cmluZyAoZS5nLiwgJzMwMG1zJywgJzAuNXMnKVxuICAgKiBAcmV0dXJucyBUaW1lIGluIG1pbGxpc2Vjb25kc1xuICAgKi9cbiAgcGFyc2VUaW1lVG9Ncyh0aW1lOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIGlmICghdGltZSkgcmV0dXJuIDMwMDsgLy8gRGVmYXVsdCAzMDBtc1xuICAgIFxuICAgIGlmICh0aW1lLmVuZHNXaXRoKCdtcycpKSB7XG4gICAgICByZXR1cm4gcGFyc2VJbnQodGltZS5zbGljZSgwLCAtMiksIDEwKTtcbiAgICB9XG4gICAgXG4gICAgaWYgKHRpbWUuZW5kc1dpdGgoJ3MnKSkge1xuICAgICAgcmV0dXJuIHBhcnNlRmxvYXQodGltZS5zbGljZSgwLCAtMSkpICogMTAwMDtcbiAgICB9XG4gICAgXG4gICAgcmV0dXJuIHBhcnNlSW50KHRpbWUsIDEwKTtcbiAgfVxufSAiXX0=