@financialforcedev/orizuru-auth
Version:
Salesforce authentication for Heroku Node applications.
207 lines • 29.1 kB
JavaScript
"use strict";
/*
* Copyright (c) 2017-2019, FinancialForce.com, inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* - Neither the name of the FinancialForce.com, inc nor the names of its contributors
* may be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Orizuru Auth module
* @module @financialforcedev/orizuru-auth
*/
const cache_1 = require("./index/client/cache");
const jwtBearerToken_1 = require("./index/flow/jwtBearerToken");
const refreshToken_1 = require("./index/flow/refreshToken");
const webServer_1 = require("./index/flow/webServer");
const grant_1 = require("./index/grant/grant");
const introspect_1 = require("./index/introspection/introspect");
const authCallback_1 = require("./index/middleware/authCallback");
const grantChecker_1 = require("./index/middleware/grantChecker");
const identity_1 = require("./index/middleware/identity");
const tokenIntrospection_1 = require("./index/middleware/tokenIntrospection");
const tokenValidator_1 = require("./index/middleware/tokenValidator");
const revoke_1 = require("./index/revocation/revoke");
const userinfo_1 = require("./index/userInfo/userinfo");
var oauth2_1 = require("./index/client/oauth2");
exports.ResponseFormat = oauth2_1.ResponseFormat;
/**
* The event fired when the authorization header is set.
* @event
*/
exports.EVENT_AUTHORIZATION_HEADER_SET = Symbol();
/**
* The event fired for an unauthorized request.
* @event
*/
exports.EVENT_DENIED = Symbol();
/**
* The event fired when the grant has been checked.
* @event
*/
exports.EVENT_GRANT_CHECKED = Symbol();
/**
* The event fired when the identity has been retrieved from Salesforce using the
* [Identity URL](https://help.salesforce.com/articleView?id=remoteaccess_using_openid.htm).
* @event
*/
exports.EVENT_USER_IDENTITY_RETRIEVED = Symbol();
/**
* The event fired when an access token has been introspected.
* @event
*/
exports.EVENT_TOKEN_INTROSPECTED = Symbol();
/**
* The event fired when an access token has been validated.
* @event
*/
exports.EVENT_TOKEN_VALIDATED = Symbol();
const jwtBearerToken = {
/**
* Creates an access token grantor that exchanges a JWT for an access token.
*/
createTokenGrantor: jwtBearerToken_1.createTokenGrantor
};
const refreshToken = {
/**
* Creates an access token grantor that exchanges a refresh token for an access token.
*
* Rather than using the client secret of the Salesforce Connected Application, this
* function creates a signed JWT bearer assertion to validate the user.
*/
createTokenGrantor: refreshToken_1.createTokenGrantor
};
const webServer = {
/**
* Generates URLs required to initialise the [OAuth 2.0 Web Server Authentication Flow](https://help.salesforce.com/articleView?id=remoteaccess_oauth_web_server_flow.htm).
*/
authorizationUrlGenerator: webServer_1.authorizationUrlGenerator,
/**
* Creates an access token grantor that [exchanges a verification code for an access token](https://help.salesforce.com/articleView?id=remoteaccess_oauth_web_server_flow.htm#vc_for_at).
*
* Rather than using the client secret of the Salesforce Connected Application, this
* function creates a signed JWT bearer assertion to validate the user.
*/
createTokenGrantor: webServer_1.createTokenGrantor
};
/**
* Returns the collection of OAuth 2.0 flow functions.
*/
exports.flow = {
/**
* Returns functions to handle the [OAuth 2.0 JWT Bearer Token Flow](https://help.salesforce.com/articleView?id=remoteaccess_oauth_jwt_flow.htm).
*/
jwtBearerToken,
/**
* Returns functions to handle the [OAuth 2.0 Refresh Token Flow](https://help.salesforce.com/articleView?id=remoteaccess_oauth_refresh_token_flow.htm).
*/
refreshToken,
/**
* Returns functions to handle the [OAuth 2.0 Web Server Authentication Flow](https://help.salesforce.com/articleView?id=remoteaccess_oauth_web_server_flow.htm).
*/
webServer
};
/**
* Returns the collection of grant functions.
*/
exports.grant = {
/**
* Returns a function that can obtain a token for the passed user.
*/
getToken: grant_1.getToken
};
/**
* Returns the collection of introspection functions.
*/
exports.introspection = {
/**
* Returns a function that introspects a token.
*/
createTokenIntrospector: introspect_1.createTokenIntrospector
};
/**
* Returns the collection of middleware functions.
*/
exports.middleware = {
/**
* Returns an express middleware that [exchanges a verification code for an access token](https://help.salesforce.com/articleView?id=remoteaccess_oauth_web_server_flow.htm#vc_for_at).
*
* This can be used in tandem with the tokenValidator to set the user on the request.
*/
authCallback: authCallback_1.createMiddleware,
/**
* Returns an express middleware that checks that an access token
* can be retrieved for the user specified on the request.
* Should be used in tandem with the tokenValidator middleware,
* and must be executed after that. This requires that a ConnectedApp
* is configured to pre authorise users and the user is
* authorised.
*/
grantChecker: grantChecker_1.createMiddleware,
/**
* Returns an express middleware that uses the [Identity URL](https://help.salesforce.com/articleView?id=remoteaccess_using_openid.htm) to retrieve information
* about the current Salesforce user.
*/
retrieveIdentityInformation: identity_1.createMiddleware,
/**
* Returns an express middleware that introspects the access token passed in an HTTP
* Authorization header and if successful updates the request object.
*/
tokenIntrospection: tokenIntrospection_1.createMiddleware,
/**
* Returns an express middleware that validates the OpenID Connect
* access token passed in an HTTP Authorization header and if successful
* sets the user object onto the request object.
*/
tokenValidator: tokenValidator_1.createMiddleware
};
/**
* Returns the collection of OpenID client functions.
*/
exports.openIdClient = {
/**
* Clears the OpenID client cache.
*
* This will cause new OpenID clients to be created and the [OpenID provider configuration information](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig)
* to be queried again.
*/
clearCache: cache_1.clear
};
/**
* Returns the collection of revocation functions.
*/
exports.revocation = {
/**
* Returns a function that [revokes access tokens](https://help.salesforce.com/articleView?id=remoteaccess_revoke_token.htm).
*/
createTokenRevoker: revoke_1.createTokenRevoker
};
/**
* Returns the collection of [user information](https://help.salesforce.com/articleView?id=remoteaccess_using_userinfo_endpoint.htm) functions.
*/
exports.userInfo = {
/**
* Returns a function that requests the user information for a given access token.
*/
createUserInfoRequester: userinfo_1.createUserInfoRequester
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F3Qkc7O0FBRUg7OztHQUdHO0FBRUgsZ0RBQTBEO0FBTTFELGdFQUFzRztBQUN0Ryw0REFBa0c7QUFDbEcsc0RBQXNIO0FBQ3RILCtDQUFzRDtBQUN0RCxpRUFBMkU7QUFDM0Usa0VBQW1GO0FBQ25GLGtFQUFtRjtBQUNuRiwwREFBOEY7QUFDOUYsOEVBQStGO0FBQy9GLHNFQUF1RjtBQUN2RixzREFBK0Q7QUFDL0Qsd0RBQW9FO0FBMkdwRSxnREFrQitCO0FBSDlCLGtDQUFBLGNBQWMsQ0FBQTtBQW1EZjs7O0dBR0c7QUFDVSxRQUFBLDhCQUE4QixHQUFHLE1BQU0sRUFBRSxDQUFDO0FBRXZEOzs7R0FHRztBQUNVLFFBQUEsWUFBWSxHQUFHLE1BQU0sRUFBRSxDQUFDO0FBRXJDOzs7R0FHRztBQUNVLFFBQUEsbUJBQW1CLEdBQUcsTUFBTSxFQUFFLENBQUM7QUFFNUM7Ozs7R0FJRztBQUNVLFFBQUEsNkJBQTZCLEdBQUcsTUFBTSxFQUFFLENBQUM7QUFFdEQ7OztHQUdHO0FBQ1UsUUFBQSx3QkFBd0IsR0FBRyxNQUFNLEVBQUUsQ0FBQztBQUVqRDs7O0dBR0c7QUFDVSxRQUFBLHFCQUFxQixHQUFHLE1BQU0sRUFBRSxDQUFDO0FBRTlDLE1BQU0sY0FBYyxHQUFHO0lBRXRCOztPQUVHO0lBQ0gsa0JBQWtCLEVBQUUsbUNBQWlDO0NBRXJELENBQUM7QUFFRixNQUFNLFlBQVksR0FBRztJQUVwQjs7Ozs7T0FLRztJQUNILGtCQUFrQixFQUFFLGlDQUErQjtDQUVuRCxDQUFDO0FBRUYsTUFBTSxTQUFTLEdBQUc7SUFFakI7O09BRUc7SUFDSCx5QkFBeUIsRUFBekIscUNBQXlCO0lBRXpCOzs7OztPQUtHO0lBQ0gsa0JBQWtCLEVBQUUsOEJBQTJCO0NBRS9DLENBQUM7QUFFRjs7R0FFRztBQUNVLFFBQUEsSUFBSSxHQUFHO0lBRW5COztPQUVHO0lBQ0gsY0FBYztJQUVkOztPQUVHO0lBQ0gsWUFBWTtJQUVaOztPQUVHO0lBQ0gsU0FBUztDQUVULENBQUM7QUFFRjs7R0FFRztBQUNVLFFBQUEsS0FBSyxHQUFHO0lBRXBCOztPQUVHO0lBQ0gsUUFBUSxFQUFSLGdCQUFRO0NBRVIsQ0FBQztBQUVGOztHQUVHO0FBQ1UsUUFBQSxhQUFhLEdBQUc7SUFFNUI7O09BRUc7SUFDSCx1QkFBdUIsRUFBdkIsb0NBQXVCO0NBRXZCLENBQUM7QUFFRjs7R0FFRztBQUNVLFFBQUEsVUFBVSxHQUFHO0lBRXpCOzs7O09BSUc7SUFDSCxZQUFZLEVBQVosK0JBQVk7SUFFWjs7Ozs7OztPQU9HO0lBQ0gsWUFBWSxFQUFaLCtCQUFZO0lBRVo7OztPQUdHO0lBQ0gsMkJBQTJCLEVBQTNCLDJCQUEyQjtJQUUzQjs7O09BR0c7SUFDSCxrQkFBa0IsRUFBbEIscUNBQWtCO0lBRWxCOzs7O09BSUc7SUFDSCxjQUFjLEVBQWQsaUNBQWM7Q0FFZCxDQUFDO0FBRUY7O0dBRUc7QUFDVSxRQUFBLFlBQVksR0FBRztJQUUzQjs7Ozs7T0FLRztJQUNILFVBQVUsRUFBRSxhQUFLO0NBRWpCLENBQUM7QUFFRjs7R0FFRztBQUNVLFFBQUEsVUFBVSxHQUFHO0lBRXpCOztPQUVHO0lBQ0gsa0JBQWtCLEVBQWxCLDJCQUFrQjtDQUVsQixDQUFDO0FBRUY7O0dBRUc7QUFDVSxRQUFBLFFBQVEsR0FBRztJQUV2Qjs7T0FFRztJQUNILHVCQUF1QixFQUF2QixrQ0FBdUI7Q0FFdkIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTctMjAxOSwgRmluYW5jaWFsRm9yY2UuY29tLCBpbmNcbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0IG1vZGlmaWNhdGlvbixcbiAqICAgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucyBhcmUgbWV0OlxuICpcbiAqIC0gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlLFxuICogICAgICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyLlxuICogLSBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsXG4gKiAgICAgIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlIGRvY3VtZW50YXRpb25cbiAqICAgICAgYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG4gKiAtIE5laXRoZXIgdGhlIG5hbWUgb2YgdGhlIEZpbmFuY2lhbEZvcmNlLmNvbSwgaW5jIG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9yc1xuICogICAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dFxuICogICAgICBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uXG4gKlxuICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUyBcIkFTIElTXCIgQU5EXG4gKiAgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFU1xuICogIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMXG4gKiAgVEhFIENPUFlSSUdIVCBIT0xERVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsXG4gKiAgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTXG4gKiAgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZXG4gKiAgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpXG4gKiAgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFIE9GIFRISVMgU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4gKi9cblxuLyoqXG4gKiBPcml6dXJ1IEF1dGggbW9kdWxlXG4gKiBAbW9kdWxlIEBmaW5hbmNpYWxmb3JjZWRldi9vcml6dXJ1LWF1dGhcbiAqL1xuXG5pbXBvcnQgeyBjbGVhciwgRW52aXJvbm1lbnQgfSBmcm9tICcuL2luZGV4L2NsaWVudC9jYWNoZSc7XG5pbXBvcnQgeyBBY2Nlc3NUb2tlblJlc3BvbnNlLCBBdXRoT3B0aW9ucywgQXV0aFVybFBhcmFtcywgSW50cm9zcGVjdGlvbk9wdGlvbnMsIEludHJvc3BlY3Rpb25QYXJhbXMsIEludHJvc3BlY3Rpb25SZXNwb25zZSwgT0F1dGgyR3JhbnRPcHRpb25zLCBSZWZyZXNoVG9rZW5HcmFudG9yUGFyYW1zLCBUb2tlbkdyYW50b3JQYXJhbXMgfSBmcm9tICcuL2luZGV4L2NsaWVudC9vYXV0aDInO1xuaW1wb3J0IHsgSnd0R3JhbnRPcHRpb25zLCBKd3RUb2tlbkdyYW50b3JQYXJhbXMsIFVzZXJUb2tlbkdyYW50b3JQYXJhbXMgfSBmcm9tICcuL2luZGV4L2NsaWVudC9vYXV0aDJKd3QnO1xuaW1wb3J0IHsgT3BlbklkR3JhbnRPcHRpb25zLCBPcGVuSURUb2tlbldpdGhTdGFuZGFyZENsYWltcywgVXNlckluZm9PcHRpb25zIH0gZnJvbSAnLi9pbmRleC9jbGllbnQvb3BlbmlkJztcbmltcG9ydCB7IFNhbGVzZm9yY2VHcmFudE9wdGlvbnMsIFNhbGVzZm9yY2VVc2VyIH0gZnJvbSAnLi9pbmRleC9jbGllbnQvc2FsZXNmb3JjZSc7XG5pbXBvcnQgeyBTYWxlc2ZvcmNlSWRlbnRpdHksIFVzZXJJbmZvIH0gZnJvbSAnLi9pbmRleC9jbGllbnQvc2FsZXNmb3JjZS9pZGVudGl0eSc7XG5pbXBvcnQgeyBjcmVhdGVUb2tlbkdyYW50b3IgYXMgY3JlYXRlSnd0QmVhcmVyQWNjZXNzVG9rZW5HcmFudG9yIH0gZnJvbSAnLi9pbmRleC9mbG93L2p3dEJlYXJlclRva2VuJztcbmltcG9ydCB7IGNyZWF0ZVRva2VuR3JhbnRvciBhcyBjcmVhdGVSZWZyZXNoQWNjZXNzVG9rZW5HcmFudG9yIH0gZnJvbSAnLi9pbmRleC9mbG93L3JlZnJlc2hUb2tlbic7XG5pbXBvcnQgeyBhdXRob3JpemF0aW9uVXJsR2VuZXJhdG9yLCBjcmVhdGVUb2tlbkdyYW50b3IgYXMgY3JlYXRlV2ViU2VydmVyVG9rZW5HcmFudG9yIH0gZnJvbSAnLi9pbmRleC9mbG93L3dlYlNlcnZlcic7XG5pbXBvcnQgeyBnZXRUb2tlbiwgR3JhbnQgfSBmcm9tICcuL2luZGV4L2dyYW50L2dyYW50JztcbmltcG9ydCB7IGNyZWF0ZVRva2VuSW50cm9zcGVjdG9yIH0gZnJvbSAnLi9pbmRleC9pbnRyb3NwZWN0aW9uL2ludHJvc3BlY3QnO1xuaW1wb3J0IHsgY3JlYXRlTWlkZGxld2FyZSBhcyBhdXRoQ2FsbGJhY2sgfSBmcm9tICcuL2luZGV4L21pZGRsZXdhcmUvYXV0aENhbGxiYWNrJztcbmltcG9ydCB7IGNyZWF0ZU1pZGRsZXdhcmUgYXMgZ3JhbnRDaGVja2VyIH0gZnJvbSAnLi9pbmRleC9taWRkbGV3YXJlL2dyYW50Q2hlY2tlcic7XG5pbXBvcnQgeyBjcmVhdGVNaWRkbGV3YXJlIGFzIHJldHJpZXZlSWRlbnRpdHlJbmZvcm1hdGlvbiB9IGZyb20gJy4vaW5kZXgvbWlkZGxld2FyZS9pZGVudGl0eSc7XG5pbXBvcnQgeyBjcmVhdGVNaWRkbGV3YXJlIGFzIHRva2VuSW50cm9zcGVjdGlvbiB9IGZyb20gJy4vaW5kZXgvbWlkZGxld2FyZS90b2tlbkludHJvc3BlY3Rpb24nO1xuaW1wb3J0IHsgY3JlYXRlTWlkZGxld2FyZSBhcyB0b2tlblZhbGlkYXRvciB9IGZyb20gJy4vaW5kZXgvbWlkZGxld2FyZS90b2tlblZhbGlkYXRvcic7XG5pbXBvcnQgeyBjcmVhdGVUb2tlblJldm9rZXIgfSBmcm9tICcuL2luZGV4L3Jldm9jYXRpb24vcmV2b2tlJztcbmltcG9ydCB7IGNyZWF0ZVVzZXJJbmZvUmVxdWVzdGVyIH0gZnJvbSAnLi9pbmRleC91c2VySW5mby91c2VyaW5mbyc7XG5cbmRlY2xhcmUgZ2xvYmFsIHtcblxuXHRuYW1lc3BhY2UgRXhwcmVzcyB7XG5cblx0XHRpbnRlcmZhY2UgUmVxdWVzdCB7XG5cblx0XHRcdC8qKlxuXHRcdFx0ICogVGhlIE9yaXp1cnUgY29udGV4dCBmb3IgdGhpcyByZXF1ZXN0LlxuXHRcdFx0ICovXG5cdFx0XHRvcml6dXJ1PzogT3JpenVydS5Db250ZXh0O1xuXG5cdFx0fVxuXG5cdH1cblxuXHRuYW1lc3BhY2UgT3JpenVydSB7XG5cblx0XHRpbnRlcmZhY2UgQ29udGV4dCB7XG5cblx0XHRcdC8qKlxuXHRcdFx0ICogVGhlIGFjY2VzcyB0b2tlbi5cblx0XHRcdCAqL1xuXHRcdFx0YWNjZXNzVG9rZW4/OiBzdHJpbmc7XG5cblx0XHRcdC8qKlxuXHRcdFx0ICogSWYgdHJ1ZSwgdGhlIGdyYW50IGNoZWNrIGhhcyBiZWVuIHBlcmZvcm1lZCBmb3IgdGhpcyB1c2VyOyBhbiBhY2Nlc3MgdG9rZW4gY2FuIGJlXG5cdFx0XHQgKiByZXRyaWV2ZWQgZm9yIHRoZSB1c2VyLlxuXHRcdFx0ICovXG5cdFx0XHRncmFudENoZWNrZWQ/OiBib29sZWFuO1xuXG5cdFx0XHQvKipcblx0XHRcdCAqIFNhbGVzZm9yY2UgcmVsYXRlZCBjb250ZXh0IGluZm9ybWF0aW9uXG5cdFx0XHQgKi9cblx0XHRcdHNhbGVzZm9yY2U/OiB7XG5cblx0XHRcdFx0LyoqXG5cdFx0XHRcdCAqIFRoZSBTYWxlc2ZvcmNlIEluc3RhbmNlIFVSTC5cblx0XHRcdFx0ICovXG5cdFx0XHRcdGluc3RhbmNlVXJsPzogc3RyaW5nO1xuXG5cdFx0XHRcdC8qKlxuXHRcdFx0XHQgKiBUaGUgU2FsZXNmb3JjZSBJZGVudGl0eSBhcyBkZWZpbmVkIGJ5IHRoZSBbSWRlbnRpdHkgVVJMXShodHRwczovL2hlbHAuc2FsZXNmb3JjZS5jb20vYXJ0aWNsZVZpZXc/aWQ9cmVtb3RlYWNjZXNzX3VzaW5nX29wZW5pZC5odG0jcmVzcG9uc2UpIHJlc3BvbnNlLlxuXHRcdFx0XHQgKi9cblx0XHRcdFx0aWRlbnRpdHk/OiBTYWxlc2ZvcmNlSWRlbnRpdHk7XG5cblx0XHRcdFx0LyoqXG5cdFx0XHRcdCAqIFRoZSBTYWxlc2ZvcmNlIHVzZXIgaW5mb3JtYXRpb24gZ2VuZXJhdGVkIHdoZW4gcGFyc2luZyB0aGUgW0lkZW50aXR5IFVSTF0oaHR0cHM6Ly9oZWxwLnNhbGVzZm9yY2UuY29tL2FydGljbGVWaWV3P2lkPXJlbW90ZWFjY2Vzc191c2luZ19vcGVuaWQuaHRtKS5cblx0XHRcdFx0ICovXG5cdFx0XHRcdHVzZXJJbmZvPzogVXNlckluZm87XG5cblx0XHRcdH07XG5cblx0XHRcdC8qKlxuXHRcdFx0ICogVGhlIGluZm9ybWF0aW9uIHJldHJpZXZlZCB3aGVuIGludHJvc3BlY3RpbmcgdGhlIHRva2VuLlxuXHRcdFx0ICovXG5cdFx0XHR0b2tlbkluZm9ybWF0aW9uPzogSW50cm9zcGVjdGlvblJlc3BvbnNlO1xuXG5cdFx0XHQvKipcblx0XHRcdCAqIFRoZSBVc2VyIGNyZWRlbnRpYWxzIHJlcXVpcmVkIHRvIGluaXRpYWxpc2UgdGhlIEpXVCBmbG93LlxuXHRcdFx0ICovXG5cdFx0XHR1c2VyPzogU2FsZXNmb3JjZVVzZXI7XG5cblx0XHR9XG5cblx0XHRpbnRlcmZhY2UgSVNlcnZlciB7XG5cblx0XHRcdC8qKlxuXHRcdFx0ICogVGhlIE9yaXp1cnUgU2VydmVyIE9wdGlvbnMuXG5cdFx0XHQgKi9cblx0XHRcdG9wdGlvbnM6IE9wdGlvbnMuSVNlcnZlcjtcblxuXHRcdH1cblxuXHRcdG5hbWVzcGFjZSBPcHRpb25zIHtcblxuXHRcdFx0aW50ZXJmYWNlIElTZXJ2ZXIge1xuXG5cdFx0XHRcdC8qKlxuXHRcdFx0XHQgKiBBdXRoIFByb3ZpZGVycyByZWdpc3RlcmVkIHdpdGggdGhpcyBzZXJ2ZXIuXG5cdFx0XHRcdCAqXG5cdFx0XHRcdCAqIEEgbWFwIG9mIHByb3ZpZGVyIG5hbWUgdG8gRW52aXJvbm1lbnQuXG5cdFx0XHRcdCAqXG5cdFx0XHRcdCAqIFRoaXMgaXMgcmVmZXJlbmNlZCBieSBlYWNoIG9mIHRoZSBtaWRkbGV3YXJlLCBhbGxvd2luZyBpbnN0YW5jZXMgdG8gYmUgY3JlYXRlZCBmb3Jcblx0XHRcdFx0ICogZGlmZmVyZW50IE9wZW5JRCBwcm92aWRlcnMuXG5cdFx0XHRcdCAqL1xuXHRcdFx0XHRhdXRoUHJvdmlkZXI6IHtcblx0XHRcdFx0XHRbaW5kZXg6IHN0cmluZ106IEVudmlyb25tZW50O1xuXHRcdFx0XHR9O1xuXG5cdFx0XHRcdC8qKlxuXHRcdFx0XHQgKiBPcGVuSUQgY29ubmVjdGVkIGFwcCBpbmZvcm1hdGlvbiByZXF1aXJlZCBmb3IgdGhlIGF1dGhlbnRpY2F0aW9uIG1pZGRsZXdhcmUuXG5cdFx0XHRcdCAqL1xuXHRcdFx0XHRvcGVuaWQ6IHtcblx0XHRcdFx0XHRbaW5kZXg6IHN0cmluZ106IE9wZW5JZE9wdGlvbnM7XG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cblx0XHR9XG5cblx0fVxufVxuXG4vLyBFeHBvcnQgZnJvbSBpbnRlcm5hbCBtb2R1bGVzXG5leHBvcnQgeyBFbnZpcm9ubWVudCB9IGZyb20gJy4vaW5kZXgvY2xpZW50L2NhY2hlJztcblxuZXhwb3J0IHtcblx0QWNjZXNzVG9rZW5SZXNwb25zZSxcblx0QXV0aENsaWVudCxcblx0QXV0aENvZGVHcmFudFBhcmFtcyxcblx0QXV0aE9wdGlvbnMsXG5cdEF1dGhVcmxQYXJhbXMsXG5cdEVycm9yUmVzcG9uc2UsXG5cdEdyYW50UGFyYW1zLFxuXHRIYXNDbGllbnRJZCxcblx0SW50cm9zcGVjdGlvbk9wdGlvbnMsXG5cdEludHJvc3BlY3Rpb25QYXJhbXMsXG5cdEludHJvc3BlY3Rpb25SZXNwb25zZSxcblx0T0F1dGgyR3JhbnRPcHRpb25zLFxuXHRSZWZyZXNoR3JhbnRQYXJhbXMsXG5cdFJlZnJlc2hUb2tlbkdyYW50b3JQYXJhbXMsXG5cdFJlc3BvbnNlRm9ybWF0LFxuXHRSZXZvY2F0aW9uT3B0aW9ucyxcblx0VG9rZW5HcmFudG9yUGFyYW1zXG59IGZyb20gJy4vaW5kZXgvY2xpZW50L29hdXRoMic7XG5cbmV4cG9ydCB7XG5cdEpXVCxcblx0Snd0R3JhbnRPcHRpb25zLFxuXHRKd3RHcmFudFBhcmFtcyxcblx0Snd0VG9rZW5HcmFudG9yUGFyYW1zLFxuXHRVc2VyLFxuXHRVc2VyVG9rZW5HcmFudG9yUGFyYW1zXG59IGZyb20gJy4vaW5kZXgvY2xpZW50L29hdXRoMkp3dCc7XG5cbmV4cG9ydCB7XG5cdE9wZW5JREFjY2Vzc1Rva2VuUmVzcG9uc2UsXG5cdE9wZW5JZEdyYW50T3B0aW9ucyxcblx0T3BlbklEVG9rZW4sXG5cdE9wZW5JRFRva2VuV2l0aFN0YW5kYXJkQ2xhaW1zLFxuXHRPcGVuSWRUb2tlbkFkZHJlc3MsXG5cdFVzZXJJbmZvT3B0aW9uc1xufSBmcm9tICcuL2luZGV4L2NsaWVudC9vcGVuaWQnO1xuXG5leHBvcnQge1xuXHRTYWxlc2ZvcmNlQWNjZXNzVG9rZW5SZXNwb25zZSxcblx0U2FsZXNmb3JjZUdyYW50T3B0aW9ucyxcblx0U2FsZXNmb3JjZVVzZXJcbn0gZnJvbSAnLi9pbmRleC9jbGllbnQvc2FsZXNmb3JjZSc7XG5cbmV4cG9ydCB7IFNhbGVzZm9yY2VJZGVudGl0eSwgVXNlckluZm8gfSBmcm9tICcuL2luZGV4L2NsaWVudC9zYWxlc2ZvcmNlL2lkZW50aXR5JztcblxuZXhwb3J0IHsgTWlkZGxld2FyZU9wdGlvbnMgfSBmcm9tICcuL2luZGV4L21pZGRsZXdhcmUvY29tbW9uL2FjY2Vzc1Rva2VuJztcblxuLy8gVG9rZW4gR3JhbnRvciB0eXBlc1xuZXhwb3J0IHR5cGUgQXV0aENvZGVBY2Nlc3NUb2tlbkdyYW50b3IgPSAocGFyYW1zOiBUb2tlbkdyYW50b3JQYXJhbXMsIG9wdHM/OiBHcmFudE9wdGlvbnMpID0+IFByb21pc2U8QWNjZXNzVG9rZW5SZXNwb25zZT47XG5leHBvcnQgdHlwZSBKd3RCZWFyZXJBY2Nlc3NUb2tlbkdyYW50b3IgPSAocGFyYW1zOiBVc2VyVG9rZW5HcmFudG9yUGFyYW1zLCBvcHRzPzogR3JhbnRPcHRpb25zKSA9PiBQcm9taXNlPEFjY2Vzc1Rva2VuUmVzcG9uc2U+O1xuZXhwb3J0IHR5cGUgVXNlclRva2VuR3JhbnRvciA9IChwYXJhbXM6IFVzZXJUb2tlbkdyYW50b3JQYXJhbXMsIG9wdHM/OiBHcmFudE9wdGlvbnMpID0+IFByb21pc2U8R3JhbnQ+O1xuZXhwb3J0IHR5cGUgUmVmcmVzaEFjY2Vzc1Rva2VuR3JhbnRvciA9IChwYXJhbXM6IFJlZnJlc2hUb2tlbkdyYW50b3JQYXJhbXMsIG9wdHM/OiBHcmFudE9wdGlvbnMpID0+IFByb21pc2U8QWNjZXNzVG9rZW5SZXNwb25zZT47XG5cbmV4cG9ydCB0eXBlIEF1dGhVcmxHZW5lcmF0b3IgPSAocGFyYW1zOiBBdXRoVXJsUGFyYW1zLCBvcHRzPzogQXV0aE9wdGlvbnMpID0+IFByb21pc2U8c3RyaW5nPjtcbmV4cG9ydCB0eXBlIFRva2VuSW50cm9zcGVjdG9yID0gKHRva2VuOiBzdHJpbmcsIHBhcmFtczogSW50cm9zcGVjdGlvblBhcmFtcywgb3B0cz86IEludHJvc3BlY3Rpb25PcHRpb25zKSA9PiBQcm9taXNlPEludHJvc3BlY3Rpb25SZXNwb25zZT47XG5leHBvcnQgdHlwZSBUb2tlblJldm9rZXIgPSAodG9rZW46IHN0cmluZykgPT4gUHJvbWlzZTxib29sZWFuPjtcbmV4cG9ydCB0eXBlIFVzZXJJbmZvUmVxdWVzdGVyID0gKGFjY2Vzc1Rva2VuOiBzdHJpbmcsIG9wdHM/OiBVc2VySW5mb09wdGlvbnMpID0+IFByb21pc2U8T3BlbklEVG9rZW5XaXRoU3RhbmRhcmRDbGFpbXM+O1xuXG5leHBvcnQgdHlwZSBPcHRpb25zID0gQXV0aE9wdGlvbnMgfCBHcmFudE9wdGlvbnMgfCBVc2VySW5mb09wdGlvbnM7XG5leHBvcnQgdHlwZSBHcmFudG9yUGFyYW1zID0gUmVmcmVzaFRva2VuR3JhbnRvclBhcmFtcyB8IFRva2VuR3JhbnRvclBhcmFtcyB8IFVzZXJUb2tlbkdyYW50b3JQYXJhbXM7XG5cbmV4cG9ydCB0eXBlIE9wZW5JZE9wdGlvbnMgPSBBdXRoVXJsUGFyYW1zICYgQXV0aE9wdGlvbnMgJiBHcmFudG9yUGFyYW1zICYgSW50cm9zcGVjdGlvblBhcmFtcyAmIEp3dFRva2VuR3JhbnRvclBhcmFtcyAmIE9wdGlvbnM7XG5cbmV4cG9ydCB0eXBlIEdyYW50T3B0aW9ucyA9IE9BdXRoMkdyYW50T3B0aW9ucyB8IEp3dEdyYW50T3B0aW9ucyB8IE9wZW5JZEdyYW50T3B0aW9ucyB8IFNhbGVzZm9yY2VHcmFudE9wdGlvbnM7XG5cbi8qKlxuICogVGhlIGV2ZW50IGZpcmVkIHdoZW4gdGhlIGF1dGhvcml6YXRpb24gaGVhZGVyIGlzIHNldC5cbiAqIEBldmVudFxuICovXG5leHBvcnQgY29uc3QgRVZFTlRfQVVUSE9SSVpBVElPTl9IRUFERVJfU0VUID0gU3ltYm9sKCk7XG5cbi8qKlxuICogVGhlIGV2ZW50IGZpcmVkIGZvciBhbiB1bmF1dGhvcml6ZWQgcmVxdWVzdC5cbiAqIEBldmVudFxuICovXG5leHBvcnQgY29uc3QgRVZFTlRfREVOSUVEID0gU3ltYm9sKCk7XG5cbi8qKlxuICogVGhlIGV2ZW50IGZpcmVkIHdoZW4gdGhlIGdyYW50IGhhcyBiZWVuIGNoZWNrZWQuXG4gKiBAZXZlbnRcbiAqL1xuZXhwb3J0IGNvbnN0IEVWRU5UX0dSQU5UX0NIRUNLRUQgPSBTeW1ib2woKTtcblxuLyoqXG4gKiBUaGUgZXZlbnQgZmlyZWQgd2hlbiB0aGUgaWRlbnRpdHkgaGFzIGJlZW4gcmV0cmlldmVkIGZyb20gU2FsZXNmb3JjZSB1c2luZyB0aGVcbiAqIFtJZGVudGl0eSBVUkxdKGh0dHBzOi8vaGVscC5zYWxlc2ZvcmNlLmNvbS9hcnRpY2xlVmlldz9pZD1yZW1vdGVhY2Nlc3NfdXNpbmdfb3BlbmlkLmh0bSkuXG4gKiBAZXZlbnRcbiAqL1xuZXhwb3J0IGNvbnN0IEVWRU5UX1VTRVJfSURFTlRJVFlfUkVUUklFVkVEID0gU3ltYm9sKCk7XG5cbi8qKlxuICogVGhlIGV2ZW50IGZpcmVkIHdoZW4gYW4gYWNjZXNzIHRva2VuIGhhcyBiZWVuIGludHJvc3BlY3RlZC5cbiAqIEBldmVudFxuICovXG5leHBvcnQgY29uc3QgRVZFTlRfVE9LRU5fSU5UUk9TUEVDVEVEID0gU3ltYm9sKCk7XG5cbi8qKlxuICogVGhlIGV2ZW50IGZpcmVkIHdoZW4gYW4gYWNjZXNzIHRva2VuIGhhcyBiZWVuIHZhbGlkYXRlZC5cbiAqIEBldmVudFxuICovXG5leHBvcnQgY29uc3QgRVZFTlRfVE9LRU5fVkFMSURBVEVEID0gU3ltYm9sKCk7XG5cbmNvbnN0IGp3dEJlYXJlclRva2VuID0ge1xuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGFuIGFjY2VzcyB0b2tlbiBncmFudG9yIHRoYXQgZXhjaGFuZ2VzIGEgSldUIGZvciBhbiBhY2Nlc3MgdG9rZW4uXG5cdCAqL1xuXHRjcmVhdGVUb2tlbkdyYW50b3I6IGNyZWF0ZUp3dEJlYXJlckFjY2Vzc1Rva2VuR3JhbnRvclxuXG59O1xuXG5jb25zdCByZWZyZXNoVG9rZW4gPSB7XG5cblx0LyoqXG5cdCAqIENyZWF0ZXMgYW4gYWNjZXNzIHRva2VuIGdyYW50b3IgdGhhdCBleGNoYW5nZXMgYSByZWZyZXNoIHRva2VuIGZvciBhbiBhY2Nlc3MgdG9rZW4uXG5cdCAqXG5cdCAqIFJhdGhlciB0aGFuIHVzaW5nIHRoZSBjbGllbnQgc2VjcmV0IG9mIHRoZSBTYWxlc2ZvcmNlIENvbm5lY3RlZCBBcHBsaWNhdGlvbiwgdGhpc1xuXHQgKiBmdW5jdGlvbiBjcmVhdGVzIGEgc2lnbmVkIEpXVCBiZWFyZXIgYXNzZXJ0aW9uIHRvIHZhbGlkYXRlIHRoZSB1c2VyLlxuXHQgKi9cblx0Y3JlYXRlVG9rZW5HcmFudG9yOiBjcmVhdGVSZWZyZXNoQWNjZXNzVG9rZW5HcmFudG9yXG5cbn07XG5cbmNvbnN0IHdlYlNlcnZlciA9IHtcblxuXHQvKipcblx0ICogR2VuZXJhdGVzIFVSTHMgcmVxdWlyZWQgdG8gaW5pdGlhbGlzZSB0aGUgW09BdXRoIDIuMCBXZWIgU2VydmVyIEF1dGhlbnRpY2F0aW9uIEZsb3ddKGh0dHBzOi8vaGVscC5zYWxlc2ZvcmNlLmNvbS9hcnRpY2xlVmlldz9pZD1yZW1vdGVhY2Nlc3Nfb2F1dGhfd2ViX3NlcnZlcl9mbG93Lmh0bSkuXG5cdCAqL1xuXHRhdXRob3JpemF0aW9uVXJsR2VuZXJhdG9yLFxuXG5cdC8qKlxuXHQgKiBDcmVhdGVzIGFuIGFjY2VzcyB0b2tlbiBncmFudG9yIHRoYXQgW2V4Y2hhbmdlcyBhIHZlcmlmaWNhdGlvbiBjb2RlIGZvciBhbiBhY2Nlc3MgdG9rZW5dKGh0dHBzOi8vaGVscC5zYWxlc2ZvcmNlLmNvbS9hcnRpY2xlVmlldz9pZD1yZW1vdGVhY2Nlc3Nfb2F1dGhfd2ViX3NlcnZlcl9mbG93Lmh0bSN2Y19mb3JfYXQpLlxuXHQgKlxuXHQgKiBSYXRoZXIgdGhhbiB1c2luZyB0aGUgY2xpZW50IHNlY3JldCBvZiB0aGUgU2FsZXNmb3JjZSBDb25uZWN0ZWQgQXBwbGljYXRpb24sIHRoaXNcblx0ICogZnVuY3Rpb24gY3JlYXRlcyBhIHNpZ25lZCBKV1QgYmVhcmVyIGFzc2VydGlvbiB0byB2YWxpZGF0ZSB0aGUgdXNlci5cblx0ICovXG5cdGNyZWF0ZVRva2VuR3JhbnRvcjogY3JlYXRlV2ViU2VydmVyVG9rZW5HcmFudG9yXG5cbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgY29sbGVjdGlvbiBvZiBPQXV0aCAyLjAgZmxvdyBmdW5jdGlvbnMuXG4gKi9cbmV4cG9ydCBjb25zdCBmbG93ID0ge1xuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGZ1bmN0aW9ucyB0byBoYW5kbGUgdGhlIFtPQXV0aCAyLjAgSldUIEJlYXJlciBUb2tlbiBGbG93XShodHRwczovL2hlbHAuc2FsZXNmb3JjZS5jb20vYXJ0aWNsZVZpZXc/aWQ9cmVtb3RlYWNjZXNzX29hdXRoX2p3dF9mbG93Lmh0bSkuXG5cdCAqL1xuXHRqd3RCZWFyZXJUb2tlbixcblxuXHQvKipcblx0ICogUmV0dXJucyBmdW5jdGlvbnMgdG8gaGFuZGxlIHRoZSBbT0F1dGggMi4wIFJlZnJlc2ggVG9rZW4gRmxvd10oaHR0cHM6Ly9oZWxwLnNhbGVzZm9yY2UuY29tL2FydGljbGVWaWV3P2lkPXJlbW90ZWFjY2Vzc19vYXV0aF9yZWZyZXNoX3Rva2VuX2Zsb3cuaHRtKS5cblx0ICovXG5cdHJlZnJlc2hUb2tlbixcblxuXHQvKipcblx0ICogUmV0dXJucyBmdW5jdGlvbnMgdG8gaGFuZGxlIHRoZSBbT0F1dGggMi4wIFdlYiBTZXJ2ZXIgQXV0aGVudGljYXRpb24gRmxvd10oaHR0cHM6Ly9oZWxwLnNhbGVzZm9yY2UuY29tL2FydGljbGVWaWV3P2lkPXJlbW90ZWFjY2Vzc19vYXV0aF93ZWJfc2VydmVyX2Zsb3cuaHRtKS5cblx0ICovXG5cdHdlYlNlcnZlclxuXG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGNvbGxlY3Rpb24gb2YgZ3JhbnQgZnVuY3Rpb25zLlxuICovXG5leHBvcnQgY29uc3QgZ3JhbnQgPSB7XG5cblx0LyoqXG5cdCAqIFJldHVybnMgYSBmdW5jdGlvbiB0aGF0IGNhbiBvYnRhaW4gYSB0b2tlbiBmb3IgdGhlIHBhc3NlZCB1c2VyLlxuXHQgKi9cblx0Z2V0VG9rZW5cblxufTtcblxuLyoqXG4gKiBSZXR1cm5zIHRoZSBjb2xsZWN0aW9uIG9mIGludHJvc3BlY3Rpb24gZnVuY3Rpb25zLlxuICovXG5leHBvcnQgY29uc3QgaW50cm9zcGVjdGlvbiA9IHtcblxuXHQvKipcblx0ICogUmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgaW50cm9zcGVjdHMgYSB0b2tlbi5cblx0ICovXG5cdGNyZWF0ZVRva2VuSW50cm9zcGVjdG9yXG5cbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgY29sbGVjdGlvbiBvZiBtaWRkbGV3YXJlIGZ1bmN0aW9ucy5cbiAqL1xuZXhwb3J0IGNvbnN0IG1pZGRsZXdhcmUgPSB7XG5cblx0LyoqXG5cdCAqIFJldHVybnMgYW4gZXhwcmVzcyBtaWRkbGV3YXJlIHRoYXQgW2V4Y2hhbmdlcyBhIHZlcmlmaWNhdGlvbiBjb2RlIGZvciBhbiBhY2Nlc3MgdG9rZW5dKGh0dHBzOi8vaGVscC5zYWxlc2ZvcmNlLmNvbS9hcnRpY2xlVmlldz9pZD1yZW1vdGVhY2Nlc3Nfb2F1dGhfd2ViX3NlcnZlcl9mbG93Lmh0bSN2Y19mb3JfYXQpLlxuXHQgKlxuXHQgKiBUaGlzIGNhbiBiZSB1c2VkIGluIHRhbmRlbSB3aXRoIHRoZSB0b2tlblZhbGlkYXRvciB0byBzZXQgdGhlIHVzZXIgb24gdGhlIHJlcXVlc3QuXG5cdCAqL1xuXHRhdXRoQ2FsbGJhY2ssXG5cblx0LyoqXG5cdCAqIFJldHVybnMgYW4gZXhwcmVzcyBtaWRkbGV3YXJlIHRoYXQgY2hlY2tzIHRoYXQgYW4gYWNjZXNzIHRva2VuXG5cdCAqIGNhbiBiZSByZXRyaWV2ZWQgZm9yIHRoZSB1c2VyIHNwZWNpZmllZCBvbiB0aGUgcmVxdWVzdC5cblx0ICogU2hvdWxkIGJlIHVzZWQgaW4gdGFuZGVtIHdpdGggdGhlIHRva2VuVmFsaWRhdG9yIG1pZGRsZXdhcmUsXG5cdCAqIGFuZCBtdXN0IGJlIGV4ZWN1dGVkIGFmdGVyIHRoYXQuIFRoaXMgcmVxdWlyZXMgdGhhdCBhIENvbm5lY3RlZEFwcFxuXHQgKiBpcyBjb25maWd1cmVkIHRvIHByZSBhdXRob3Jpc2UgdXNlcnMgYW5kIHRoZSB1c2VyIGlzXG5cdCAqIGF1dGhvcmlzZWQuXG5cdCAqL1xuXHRncmFudENoZWNrZXIsXG5cblx0LyoqXG5cdCAqIFJldHVybnMgYW4gZXhwcmVzcyBtaWRkbGV3YXJlIHRoYXQgdXNlcyB0aGUgW0lkZW50aXR5IFVSTF0oaHR0cHM6Ly9oZWxwLnNhbGVzZm9yY2UuY29tL2FydGljbGVWaWV3P2lkPXJlbW90ZWFjY2Vzc191c2luZ19vcGVuaWQuaHRtKSB0byByZXRyaWV2ZSBpbmZvcm1hdGlvblxuXHQgKiBhYm91dCB0aGUgY3VycmVudCBTYWxlc2ZvcmNlIHVzZXIuXG5cdCAqL1xuXHRyZXRyaWV2ZUlkZW50aXR5SW5mb3JtYXRpb24sXG5cblx0LyoqXG5cdCAqIFJldHVybnMgYW4gZXhwcmVzcyBtaWRkbGV3YXJlIHRoYXQgaW50cm9zcGVjdHMgdGhlIGFjY2VzcyB0b2tlbiBwYXNzZWQgaW4gYW4gSFRUUFxuXHQgKiBBdXRob3JpemF0aW9uIGhlYWRlciBhbmQgaWYgc3VjY2Vzc2Z1bCB1cGRhdGVzIHRoZSByZXF1ZXN0IG9iamVjdC5cblx0ICovXG5cdHRva2VuSW50cm9zcGVjdGlvbixcblxuXHQvKipcblx0ICogUmV0dXJucyBhbiBleHByZXNzIG1pZGRsZXdhcmUgdGhhdCB2YWxpZGF0ZXMgdGhlIE9wZW5JRCBDb25uZWN0XG5cdCAqIGFjY2VzcyB0b2tlbiBwYXNzZWQgaW4gYW4gSFRUUCBBdXRob3JpemF0aW9uIGhlYWRlciBhbmQgaWYgc3VjY2Vzc2Z1bFxuXHQgKiBzZXRzIHRoZSB1c2VyIG9iamVjdCBvbnRvIHRoZSByZXF1ZXN0IG9iamVjdC5cblx0ICovXG5cdHRva2VuVmFsaWRhdG9yXG5cbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgY29sbGVjdGlvbiBvZiBPcGVuSUQgY2xpZW50IGZ1bmN0aW9ucy5cbiAqL1xuZXhwb3J0IGNvbnN0IG9wZW5JZENsaWVudCA9IHtcblxuXHQvKipcblx0ICogQ2xlYXJzIHRoZSBPcGVuSUQgY2xpZW50IGNhY2hlLlxuXHQgKlxuXHQgKiBUaGlzIHdpbGwgY2F1c2UgbmV3IE9wZW5JRCBjbGllbnRzIHRvIGJlIGNyZWF0ZWQgYW5kIHRoZSBbT3BlbklEIHByb3ZpZGVyIGNvbmZpZ3VyYXRpb24gaW5mb3JtYXRpb25dKGh0dHBzOi8vb3BlbmlkLm5ldC9zcGVjcy9vcGVuaWQtY29ubmVjdC1kaXNjb3ZlcnktMV8wLmh0bWwjUHJvdmlkZXJDb25maWcpXG5cdCAqIHRvIGJlIHF1ZXJpZWQgYWdhaW4uXG5cdCAqL1xuXHRjbGVhckNhY2hlOiBjbGVhclxuXG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIGNvbGxlY3Rpb24gb2YgcmV2b2NhdGlvbiBmdW5jdGlvbnMuXG4gKi9cbmV4cG9ydCBjb25zdCByZXZvY2F0aW9uID0ge1xuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCBbcmV2b2tlcyBhY2Nlc3MgdG9rZW5zXShodHRwczovL2hlbHAuc2FsZXNmb3JjZS5jb20vYXJ0aWNsZVZpZXc/aWQ9cmVtb3RlYWNjZXNzX3Jldm9rZV90b2tlbi5odG0pLlxuXHQgKi9cblx0Y3JlYXRlVG9rZW5SZXZva2VyXG5cbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgY29sbGVjdGlvbiBvZiBbdXNlciBpbmZvcm1hdGlvbl0oaHR0cHM6Ly9oZWxwLnNhbGVzZm9yY2UuY29tL2FydGljbGVWaWV3P2lkPXJlbW90ZWFjY2Vzc191c2luZ191c2VyaW5mb19lbmRwb2ludC5odG0pIGZ1bmN0aW9ucy5cbiAqL1xuZXhwb3J0IGNvbnN0IHVzZXJJbmZvID0ge1xuXG5cdC8qKlxuXHQgKiBSZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCByZXF1ZXN0cyB0aGUgdXNlciBpbmZvcm1hdGlvbiBmb3IgYSBnaXZlbiBhY2Nlc3MgdG9rZW4uXG5cdCAqL1xuXHRjcmVhdGVVc2VySW5mb1JlcXVlc3RlclxuXG59O1xuIl19