@berry-cloud/ngx-unsplash
Version:
Lightweight Angular wrapper for the Unsplash API.
616 lines • 79.8 kB
JavaScript
import { HttpHeaders, HttpParams } from '@angular/common/http';
import { Inject, Injectable, InjectionToken } from '@angular/core';
import { Observable, of } from 'rxjs';
import { map, mergeMap, tap } from 'rxjs/operators';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common/http";
export const UNSPLASH_CONFIG = new InjectionToken('unsplash.config');
class UnsplashService {
constructor(http, config) {
this.http = http;
this.searchUrl = 'search/photos';
this.photosUrl = 'photos';
this.randomUrl = 'photos/random';
this.collectionsUrl = 'collections';
this.topicsUrl = 'topics';
this.usersUrl = 'users';
const config$ = config instanceof Observable ? config : of(config);
this.config$ = config$.pipe(tap((config) => {
if (!config) {
throw new Error('Unsplash configuration undefined');
}
if (!config.url) {
throw new Error('Unsplash configuration url undefined');
}
if (!config.authorization) {
throw new Error('Unsplash configuration authorization undefined');
}
}));
}
/**
* [List photos](https://unsplash.com/documentation#list-photos).
*
* Get a single page from the list of all photos.
*
* @param options to be used when getting list of photos
*
* @returns Observable containing a {@link Photo} array
*/
photos(options) {
return this.config$.pipe(mergeMap((config) => {
let params = new HttpParams();
if (options?.page) {
params = params.set('page', options.page.toString());
}
if (options?.perPage) {
params = params.set('per_page', options.perPage.toString());
}
if (options?.orderBy) {
params = params.set('order_by', options.orderBy);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(this.photosUrl, config);
return this.http.get(url, { params, headers });
}));
}
/**
* [List photos](https://unsplash.com/documentation#list-photos).
*
* Get a single page from the list of all photos.
*
* @param options to be used when getting list of photos
*
* @returns Observable containing a {@link Photo} array
*
* @deprecated Use {@link photos} instead
*/
list(options) {
return this.photos(options);
}
/**
* [Get a photo](https://unsplash.com/documentation#get-a-photo).
*
* Retrieve a single photo.
*
* @param id of the photo
*
* @returns Observable containing the {@link Photo}
*/
photo(id) {
return this.config$.pipe(mergeMap((config) => {
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.photosUrl}/${id}`, config);
return this.http.get(url, { headers });
}));
}
/**
* [Get a photo](https://unsplash.com/documentation#get-a-photo).
*
* Retrieve a single photo.
*
* @param id of the photo
*
* @returns Observable containing the {@link Photo}
*
* @deprecated Use {@link photo} instead
*/
get(id) {
return this.photo(id);
}
/**
* [Get random photos](https://unsplash.com/documentation#get-a-random-photo).
*
* Retrieve random photos.
*
* @param options to be used when getting random photos
*
* @returns Observable containing a {@link Photo} array
*/
randomPhoto(options) {
return this.config$.pipe(mergeMap((config) => {
let params = new HttpParams();
if (options?.collections) {
params = params.set('collections', options?.collections);
}
if (options?.topics) {
params = params.set('topics', options?.topics);
}
if (options?.username) {
params = params.set('username', options?.username);
}
if (options?.query) {
params = params.set('query', options?.query);
}
if (options?.orientation) {
params = params.set('orientation', options?.orientation);
}
if (options?.contentFilter) {
params = params.set('content_filter', options?.contentFilter);
}
if (options?.count) {
params = params.set('count', options?.count);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(this.randomUrl, config);
return this.http.get(url, { params, headers });
}));
}
/**
* [Get random photos](https://unsplash.com/documentation#get-a-random-photo).
*
* Retrieve random photos.
*
* @param options to be used when getting random photos
*
* @returns Observable containing a {@link Photo} array
*
* @deprecated Use {@link randomPhoto} instead
*/
random(options) {
return this.randomPhoto(options);
}
/**
* [Search photos](https://unsplash.com/documentation#search-photos).
*
* Get a single page of photo results for a query.
*
* @param query to search for
* @param options to be used when searching photos
*
* @returns Observable containing a {@link SearchResult}
*/
searchPhotos(query, options) {
return this.config$.pipe(mergeMap((config) => {
let params = new HttpParams().set('query', query);
if (options?.page) {
params = params.set('page', options?.page);
}
if (options?.perPage) {
params = params.set('per_page', options?.perPage);
}
if (options?.orderBy) {
params = params.set('order_by', options?.orderBy);
}
if (options?.collections) {
params = params.set('collections', options?.collections);
}
if (options?.contentFilter) {
params = params.set('content_filter', options?.contentFilter);
}
if (options?.color) {
params = params.set('color', options?.color);
}
if (options?.orientation) {
params = params.set('orientation', options?.orientation);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(this.searchUrl, config);
return this.http.get(url, { headers, params });
}));
}
/**
* [Search photos](https://unsplash.com/documentation#search-photos).
*
* Get a single page of photo results for a query.
*
* @param query to search for
* @param options to be used when searching photos
*
* @returns Observable containing a {@link SearchResult}
*
* @deprecated Use {@link searchPhotos} instead
*/
search(query, options) {
return this.searchPhotos(query, options);
}
/**
* [Trigger a download](https://help.unsplash.com/en/articles/2511258-guideline-triggering-a-download)
* of a photo.
*
* @param photo to download
*
* @returns Observable containing the {@link Download}
*/
downloadPhoto(photo) {
return this.config$.pipe(mergeMap((config) => {
const headers = this.unsplashHeaders(config);
const photoUrl = new URL(photo.links.download_location);
// Remove the leading slash from the pathname and add the search
const url = this.unsplashUrl(photoUrl.pathname.substring(1) + photoUrl.search, config);
return this.http.get(url, { headers });
}));
}
/**
* [Trigger a download](https://help.unsplash.com/en/articles/2511258-guideline-triggering-a-download)
* of a photo.
*
* @param photo to download
*
* @returns Observable containing the {@link Download}
*
* @deprecated Use {@link downloadPhoto} instead
*/
download(photo) {
return this.downloadPhoto(photo);
}
/**
* [List collections](https://unsplash.com/documentation#list-collections).
* Retrieve a list of collections.
*
* @param options to be used when getting collections
*
* @returns Observable containing a {@link Collection} array
*
* @throws Error if the Unsplash configuration is not provided
*/
collections(options) {
return this.config$.pipe(mergeMap((config) => {
let params = new HttpParams();
if (options?.page) {
params = params.set('page', options?.page);
}
if (options?.perPage) {
params = params.set('per_page', options?.perPage);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(this.collectionsUrl, config);
return this.http.get(url, { headers, params });
}));
}
/**
* [Get a collection](https://unsplash.com/documentation#get-a-collection).
* Retrieve a single collection.
*
* @param id of the collection to retrieve
*
* @returns Observable containing a {@link Collection}
*
* @throws Error if the collection id is not provided
* @throws Error if the Unsplash configuration is not provided
*/
collection(id) {
return this.config$.pipe(mergeMap((config) => {
if (!id) {
throw new Error('Collection id undefined');
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.collectionsUrl}/${id}`, config);
return this.http.get(url, { headers });
}));
}
/**
* [Get a collection's photos](https://unsplash.com/documentation#get-a-collections-photos).
* Retrieve a list of photos in a collection.
*
* @param id of the collection to retrieve photos from
* @param options to be used when getting photos from a collection
*
* @returns Observable containing a {@link Photo} array
*
* @throws Error if the collection id is not provided
* @throws Error if the Unsplash configuration is not provided
*/
collectionPhotos(id, options) {
return this.config$.pipe(mergeMap((config) => {
if (!id) {
throw new Error('Collection id undefined');
}
let params = new HttpParams();
if (options?.page) {
params = params.set('page', options?.page);
}
if (options?.perPage) {
params = params.set('per_page', options?.perPage);
}
if (options?.orientation) {
params = params.set('orientation', options?.orientation);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.collectionsUrl}/${id}/photos`, config);
return this.http.get(url, { headers, params });
}));
}
/**
* [List related collections](https://unsplash.com/documentation#list-a-collections-related-collections).
* Retrieve a list of collections related to a particular one.
*
* @param id of the collection to retrieve related collections from
*
* @returns Observable containing a {@link Collection} array
*
* @throws Error if the collection id is not provided
* @throws Error if the Unsplash configuration is not provided
*/
relatedCollections(id) {
return this.config$.pipe(mergeMap((config) => {
if (!id) {
throw new Error('Collection id undefined');
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.collectionsUrl}/${id}/related`, config);
return this.http.get(url, { headers });
}));
}
/**
* [List topics](https://unsplash.com/documentation#list-topics).
* Retrieve a list of topics.
*
* @param options to be used when getting topics
*
* @returns Observable containing a {@link Topic} array
*/
topics(options) {
return this.config$.pipe(mergeMap((config) => {
let params = new HttpParams();
if (options?.ids) {
params = params.set('ids', options?.ids.join(','));
}
if (options?.page) {
params = params.set('page', options?.page);
}
if (options?.perPage) {
params = params.set('per_page', options?.perPage);
}
if (options?.orderBy) {
params = params.set('order_by', options?.orderBy);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(this.topicsUrl, config);
return this.http.get(url, { headers, params });
}));
}
/**
* [Get a topic](https://unsplash.com/documentation#get-a-topic).
* Retrieve a single topic.
*
* @param id of the topic to retrieve
*
* @returns Observable containing a {@link Topic}
*
* @throws Error if the topic id is not provided
* @throws Error if the Unsplash configuration is not provided
*/
topic(id) {
return this.config$.pipe(mergeMap((config) => {
if (!id) {
throw new Error('Topic id undefined');
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.topicsUrl}/${id}`, config);
return this.http.get(url, { headers });
}));
}
/**
* [Get a topic's photos](https://unsplash.com/documentation#get-a-topics-photos).
* Retrieve a list of photos in a topic.
*
* @param id of the topic to retrieve photos from
* @param options to be used when getting photos from a topic
*
* @returns Observable containing a {@link Photo} array
*
* @throws Error if the topic id is not provided
* @throws Error if the Unsplash configuration is not provided
*/
topicPhotos(id, options) {
return this.config$.pipe(mergeMap((config) => {
if (!id) {
throw new Error('Topic id undefined');
}
let params = new HttpParams();
if (options?.page) {
params = params.set('page', options?.page);
}
if (options?.perPage) {
params = params.set('per_page', options?.perPage);
}
if (options?.orientation) {
params = params.set('orientation', options?.orientation);
}
if (options?.orderBy) {
params = params.set('order_by', options?.orderBy);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.topicsUrl}/${id}/photos`, config);
return this.http.get(url, { headers, params });
}));
}
/**
* [Get a user](https://unsplash.com/documentation#get-a-user).
* Retrieve public details on a given user.
*
* @param username of the user to retrieve
*
* @returns Observable containing a {@link User}
*
* @throws Error if the user username is not provided
* @throws Error if the Unsplash configuration is not provided
*/
user(username) {
return this.config$.pipe(mergeMap((config) => {
if (!username) {
throw new Error('User username undefined');
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.usersUrl}/${username}`, config);
return this.http.get(url, { headers });
}));
}
/**
* [Get a user's portfolio link](https://unsplash.com/documentation#get-a-users-portfolio-link).
* Retrieve a single user’s portfolio link.
*
* @param username of the user to retrieve portfolio link from
*
* @returns Observable containing a {@link User}
*
* @throws Error if the user username is not provided
* @throws Error if the Unsplash configuration is not provided
*/
userPortfolio(username) {
return this.config$.pipe(mergeMap((config) => {
if (!username) {
throw new Error('User username undefined');
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.usersUrl}/${username}/portfolio`, config);
return this.http.get(url, { headers });
}), map((response) => response.url));
}
/**
* [List a user’s photos](https://unsplash.com/documentation#list-a-users-photos).
* Retrieve a list of photos uploaded by a user.
*
* @param username of the user to retrieve photos from
* @param options to be used when getting photos from a user
*
* @returns Observable containing a {@link Photo} array
*
* @throws Error if the user username is not provided
* @throws Error if the Unsplash configuration is not provided
*/
userPhotos(username, options) {
return this.config$.pipe(mergeMap((config) => {
if (!username) {
throw new Error('User username undefined');
}
let params = new HttpParams();
if (options?.page) {
params = params.set('page', options?.page);
}
if (options?.perPage) {
params = params.set('per_page', options?.perPage);
}
if (options?.orderBy) {
params = params.set('order_by', options?.orderBy);
}
if (options?.stats) {
params = params.set('stats', options?.stats);
}
if (options?.resolution) {
params = params.set('resolution', options?.resolution);
}
if (options?.quantity) {
params = params.set('quantity', options?.quantity);
}
if (options?.orientation) {
params = params.set('orientation', options?.orientation);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.usersUrl}/${username}/photos`, config);
return this.http.get(url, { headers, params });
}));
}
/**
* [List a user’s liked photos](https://unsplash.com/documentation#list-a-users-liked-photos).
* Retrieve a list of photos liked by a user.
*
* @param username of the user to retrieve liked photos from
* @param options to be used when getting liked photos from a user
*
* @returns Observable containing a {@link Photo} array
*
* @throws Error if the user username is not provided
* @throws Error if the Unsplash configuration is not provided
*/
userLikes(username, options) {
return this.config$.pipe(mergeMap((config) => {
if (!username) {
throw new Error('User username undefined');
}
let params = new HttpParams();
if (options?.page) {
params = params.set('page', options?.page);
}
if (options?.perPage) {
params = params.set('per_page', options?.perPage);
}
if (options?.orderBy) {
params = params.set('order_by', options?.orderBy);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.usersUrl}/${username}/likes`, config);
return this.http.get(url, { headers, params });
}));
}
/**
* [List a user’s collections](https://unsplash.com/documentation#list-a-users-collections).
* Retrieve a list of collections created by the user.
*
* @param username of the user to retrieve collections from
* @param options to be used when getting collections from a user
*
* @returns Observable containing a {@link Collection} array
*
* @throws Error if the user username is not provided
* @throws Error if the Unsplash configuration is not provided
*/
userCollections(username, options) {
return this.config$.pipe(mergeMap((config) => {
if (!username) {
throw new Error('User username undefined');
}
let params = new HttpParams();
if (options?.page) {
params = params.set('page', options?.page);
}
if (options?.perPage) {
params = params.set('per_page', options?.perPage);
}
if (options?.orderBy) {
params = params.set('order_by', options?.orderBy);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.usersUrl}/${username}/collections`, config);
return this.http.get(url, { headers, params });
}));
}
/**
* [Get a user’s statistics](https://unsplash.com/documentation#get-a-users-statistics).
* Retrieve total number of downloads, views and likes of all user’s photos, as well as the historical breakdown and average of these stats in a specific time frame (default is 30 days).
*
* @param username of the user to retrieve statistics from
* @param options to be used when getting statistics from a user
*
* @returns Observable containing a {@link UserStatistics} object
*
* @throws Error if the user username is not provided
* @throws Error if the Unsplash configuration is not provided
*/
userStatistics(username, options) {
return this.config$.pipe(mergeMap((config) => {
if (!username) {
throw new Error('User username undefined');
}
let params = new HttpParams();
if (options?.resolution) {
params = params.set('resolution', options?.resolution);
}
if (options?.quantity) {
params = params.set('quantity', options?.quantity);
}
const headers = this.unsplashHeaders(config);
const url = this.unsplashUrl(`${this.usersUrl}/${username}/statistics`, config);
return this.http.get(url, { headers, params });
}));
}
unsplashUrl(url, config) {
return new URL(url, config.url.endsWith('/') ? config.url : config.url + '/').toString();
}
unsplashHeaders(config) {
return new HttpHeaders().set('authorization', config.authorization);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: UnsplashService, deps: [{ token: i1.HttpClient }, { token: UNSPLASH_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: UnsplashService, providedIn: 'root' }); }
}
export { UnsplashService };
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.9", ngImport: i0, type: UnsplashService, decorators: [{
type: Injectable,
args: [{
providedIn: 'root',
}]
}], ctorParameters: function () { return [{ type: i1.HttpClient }, { type: undefined, decorators: [{
type: Inject,
args: [UNSPLASH_CONFIG]
}] }]; } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5zcGxhc2guc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC11bnNwbGFzaC9zcmMvbGliL3Vuc3BsYXNoLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFjLFdBQVcsRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUMzRSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxjQUFjLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbkUsT0FBTyxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdEMsT0FBTyxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7OztBQXVCcEQsTUFBTSxDQUFDLE1BQU0sZUFBZSxHQUFHLElBQUksY0FBYyxDQUUvQyxpQkFBaUIsQ0FBQyxDQUFDO0FBUXJCLE1BR2EsZUFBZTtJQVUxQixZQUNVLElBQWdCLEVBRXhCLE1BQW1EO1FBRjNDLFNBQUksR0FBSixJQUFJLENBQVk7UUFWVCxjQUFTLEdBQUcsZUFBZSxDQUFDO1FBQzVCLGNBQVMsR0FBRyxRQUFRLENBQUM7UUFDckIsY0FBUyxHQUFHLGVBQWUsQ0FBQztRQUM1QixtQkFBYyxHQUFHLGFBQWEsQ0FBQztRQUMvQixjQUFTLEdBQUcsUUFBUSxDQUFDO1FBQ3JCLGFBQVEsR0FBRyxPQUFPLENBQUM7UUFTbEMsTUFBTSxPQUFPLEdBQUcsTUFBTSxZQUFZLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUM7UUFFbkUsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUN6QixHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRTtZQUNiLElBQUksQ0FBQyxNQUFNLEVBQUU7Z0JBQ1gsTUFBTSxJQUFJLEtBQUssQ0FB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QyxlQUFlIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSHR0cENsaWVudCwgSHR0cEhlYWRlcnMsIEh0dHBQYXJhbXMgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUsIEluamVjdGlvblRva2VuIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgbWFwLCBtZXJnZU1hcCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgQ29sbGVjdGlvbiB9IGZyb20gJy4vbW9kZWwvY29sbGVjdGlvbic7XG5pbXBvcnQgeyBEb3dubG9hZCB9IGZyb20gJy4vbW9kZWwvZG93bmxvYWQnO1xuaW1wb3J0IHsgUGhvdG8gfSBmcm9tICcuL21vZGVsL3Bob3RvJztcbmltcG9ydCB7IFNlYXJjaFJlc3VsdCB9IGZyb20gJy4vbW9kZWwvc2VhcmNoLXJlc3VsdCc7XG5pbXBvcnQgeyBVc2VyU3RhdGlzdGljcyB9IGZyb20gJy4vbW9kZWwvc3RhdGlzdGljcyc7XG5pbXBvcnQgeyBUb3BpYyB9IGZyb20gJy4vbW9kZWwvdG9waWMnO1xuaW1wb3J0IHtcbiAgVW5zcGxhc2hDb2xvcixcbiAgVW5zcGxhc2hDb250ZW50RmlsdGVyLFxuICBVbnNwbGFzaEZlYXR1cmVkT3JkZXJCeSxcbiAgVW5zcGxhc2hPcmRlckJ5LFxuICBVbnNwbGFzaE9yaWVudGF0aW9uLFxuICBVbnNwbGFzaFJlc29sdXRpb24sXG4gIFVuc3BsYXNoU2VhcmNoT3JkZXJCeSxcbn0gZnJvbSAnLi9tb2RlbC90eXBlcyc7XG5pbXBvcnQgeyBVc2VyIH0gZnJvbSAnLi9tb2RlbC91c2VyJztcblxuZXhwb3J0IGludGVyZmFjZSBVbnNwbGFzaENvbmZpZyB7XG4gIHVybDogc3RyaW5nO1xuICBhdXRob3JpemF0aW9uOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBjb25zdCBVTlNQTEFTSF9DT05GSUcgPSBuZXcgSW5qZWN0aW9uVG9rZW48XG4gIFVuc3BsYXNoQ29uZmlnIHwgT2JzZXJ2YWJsZTxVbnNwbGFzaENvbmZpZz5cbj4oJ3Vuc3BsYXNoLmNvbmZpZycpO1xuXG4vLyBwcmV0dGllci1pZ25vcmVcbmV4cG9ydCB0eXBlIENvdW50ID1cbiAgfCAgMSB8ICAyIHwgIDMgfCAgNCB8ICA1IHwgIDYgfCAgNyB8ICA4IHwgIDkgfCAxMFxuICB8IDExIHwgMTIgfCAxMyB8IDE0IHwgMTUgfCAxNiB8IDE3IHwgMTggfCAxOSB8IDIwXG4gIHwgMjEgfCAyMiB8IDIzIHwgMjQgfCAyNSB8IDI2IHwgMjcgfCAyOCB8IDI5IHwgMzA7XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBVbnNwbGFzaFNlcnZpY2Uge1xuICBwcml2YXRlIHJlYWRvbmx5IHNlYXJjaFVybCA9ICdzZWFyY2gvcGhvdG9zJztcbiAgcHJpdmF0ZSByZWFkb25seSBwaG90b3NVcmwgPSAncGhvdG9zJztcbiAgcHJpdmF0ZSByZWFkb25seSByYW5kb21VcmwgPSAncGhvdG9zL3JhbmRvbSc7XG4gIHByaXZhdGUgcmVhZG9ubHkgY29sbGVjdGlvbnNVcmwgPSAnY29sbGVjdGlvbnMnO1xuICBwcml2YXRlIHJlYWRvbmx5IHRvcGljc1VybCA9ICd0b3BpY3MnO1xuICBwcml2YXRlIHJlYWRvbmx5IHVzZXJzVXJsID0gJ3VzZXJzJztcblxuICBwcml2YXRlIGNvbmZpZyQ6IE9ic2VydmFibGU8VW5zcGxhc2hDb25maWc+O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgaHR0cDogSHR0cENsaWVudCxcbiAgICBASW5qZWN0KFVOU1BMQVNIX0NPTkZJRylcbiAgICBjb25maWc6IFVuc3BsYXNoQ29uZmlnIHwgT2JzZXJ2YWJsZTxVbnNwbGFzaENvbmZpZz5cbiAgKSB7XG4gICAgY29uc3QgY29uZmlnJCA9IGNvbmZpZyBpbnN0YW5jZW9mIE9ic2VydmFibGUgPyBjb25maWcgOiBvZihjb25maWcpO1xuXG4gICAgdGhpcy5jb25maWckID0gY29uZmlnJC5waXBlKFxuICAgICAgdGFwKChjb25maWcpID0+IHtcbiAgICAgICAgaWYgKCFjb25maWcpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3BsYXNoIGNvbmZpZ3VyYXRpb24gdW5kZWZpbmVkJyk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIWNvbmZpZy51cmwpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vuc3BsYXNoIGNvbmZpZ3VyYXRpb24gdXJsIHVuZGVmaW5lZCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFjb25maWcuYXV0aG9yaXphdGlvbikge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5zcGxhc2ggY29uZmlndXJhdGlvbiBhdXRob3JpemF0aW9uIHVuZGVmaW5lZCcpO1xuICAgICAgICB9XG4gICAgICB9KVxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogW0xpc3QgcGhvdG9zXShodHRwczovL3Vuc3BsYXNoLmNvbS9kb2N1bWVudGF0aW9uI2xpc3QtcGhvdG9zKS5cbiAgICpcbiAgICogR2V0IGEgc2luZ2xlIHBhZ2UgZnJvbSB0aGUgbGlzdCBvZiBhbGwgcGhvdG9zLlxuICAgKlxuICAgKiBAcGFyYW0gb3B0aW9ucyB0byBiZSB1c2VkIHdoZW4gZ2V0dGluZyBsaXN0IG9mIHBob3Rvc1xuICAgKlxuICAgKiBAcmV0dXJucyBPYnNlcnZhYmxlIGNvbnRhaW5pbmcgYSB7QGxpbmsgUGhvdG99IGFycmF5XG4gICAqL1xuICBwaG90b3Mob3B0aW9ucz86IHtcbiAgICBwYWdlPzogbnVtYmVyO1xuICAgIHBlclBhZ2U/OiBudW1iZXI7XG4gICAgb3JkZXJCeT86IFVuc3BsYXNoT3JkZXJCeTtcbiAgfSk6IE9ic2VydmFibGU8UGhvdG9bXT4ge1xuICAgIHJldHVybiB0aGlzLmNvbmZpZyQucGlwZShcbiAgICAgIG1lcmdlTWFwKChjb25maWcpID0+IHtcbiAgICAgICAgbGV0IHBhcmFtcyA9IG5ldyBIdHRwUGFyYW1zKCk7XG5cbiAgICAgICAgaWYgKG9wdGlvbnM/LnBhZ2UpIHtcbiAgICAgICAgICBwYXJhbXMgPSBwYXJhbXMuc2V0KCdwYWdlJywgb3B0aW9ucy5wYWdlLnRvU3RyaW5nKCkpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKG9wdGlvbnM/LnBlclBhZ2UpIHtcbiAgICAgICAgICBwYXJhbXMgPSBwYXJhbXMuc2V0KCdwZXJfcGFnZScsIG9wdGlvbnMucGVyUGFnZS50b1N0cmluZygpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvcHRpb25zPy5vcmRlckJ5KSB7XG4gICAgICAgICAgcGFyYW1zID0gcGFyYW1zLnNldCgnb3JkZXJfYnknLCBvcHRpb25zLm9yZGVyQnkpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaGVhZGVycyA9IHRoaXMudW5zcGxhc2hIZWFkZXJzKGNvbmZpZyk7XG5cbiAgICAgICAgY29uc3QgdXJsID0gdGhpcy51bnNwbGFzaFVybCh0aGlzLnBob3Rvc1VybCwgY29uZmlnKTtcblxuICAgICAgICByZXR1cm4gdGhpcy5odHRwLmdldDxQaG90b1tdPih1cmwsIHsgcGFyYW1zLCBoZWFkZXJzIH0pO1xuICAgICAgfSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFtMaXN0IHBob3Rvc10oaHR0cHM6Ly91bnNwbGFzaC5jb20vZG9jdW1lbnRhdGlvbiNsaXN0LXBob3RvcykuXG4gICAqXG4gICAqIEdldCBhIHNpbmdsZSBwYWdlIGZyb20gdGhlIGxpc3Qgb2YgYWxsIHBob3Rvcy5cbiAgICpcbiAgICogQHBhcmFtIG9wdGlvbnMgdG8gYmUgdXNlZCB3aGVuIGdldHRpbmcgbGlzdCBvZiBwaG90b3NcbiAgICpcbiAgICogQHJldHVybnMgT2JzZXJ2YWJsZSBjb250YWluaW5nIGEge0BsaW5rIFBob3RvfSBhcnJheVxuICAgKlxuICAgKiBAZGVwcmVjYXRlZCBVc2Uge0BsaW5rIHBob3Rvc30gaW5zdGVhZFxuICAgKi9cbiAgbGlzdChvcHRpb25zPzoge1xuICAgIHBhZ2U/OiBudW1iZXI7XG4gICAgcGVyUGFnZT86IG51bWJlcjtcbiAgICBvcmRlckJ5PzogVW5zcGxhc2hPcmRlckJ5O1xuICB9KTogT2JzZXJ2YWJsZTxQaG90b1tdPiB7XG4gICAgcmV0dXJuIHRoaXMucGhvdG9zKG9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFtHZXQgYSBwaG90b10oaHR0cHM6Ly91bnNwbGFzaC5jb20vZG9jdW1lbnRhdGlvbiNnZXQtYS1waG90bykuXG4gICAqXG4gICAqIFJldHJpZXZlIGEgc2luZ2xlIHBob3RvLlxuICAgKlxuICAgKiBAcGFyYW0gaWQgb2YgdGhlIHBob3RvXG4gICAqXG4gICAqIEByZXR1cm5zICBPYnNlcnZhYmxlIGNvbnRhaW5pbmcgdGhlIHtAbGluayBQaG90b31cbiAgICovXG4gIHBob3RvKGlkOiBzdHJpbmcpOiBPYnNlcnZhYmxlPFBob3RvPiB7XG4gICAgcmV0dXJuIHRoaXMuY29uZmlnJC5waXBlKFxuICAgICAgbWVyZ2VNYXAoKGNvbmZpZykgPT4ge1xuICAgICAgICBjb25zdCBoZWFkZXJzID0gdGhpcy51bnNwbGFzaEhlYWRlcnMoY29uZmlnKTtcbiAgICAgICAgY29uc3QgdXJsID0gdGhpcy51bnNwbGFzaFVybChgJHt0aGlzLnBob3Rvc1VybH0vJHtpZH1gLCBjb25maWcpO1xuXG4gICAgICAgIHJldHVybiB0aGlzLmh0dHAuZ2V0PFBob3RvPih1cmwsIHsgaGVhZGVycyB9KTtcbiAgICAgIH0p