diff --git a/.gitignore b/.gitignore index 564a52a..8bd433d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,8 @@ node_modules/ .DS_Store .rpt2_cache -dist/ config*.json .vs/ .vscode/ coverage/ +dist/ diff --git a/dist/constants.d.ts b/dist/constants.d.ts new file mode 100644 index 0000000..28d06f2 --- /dev/null +++ b/dist/constants.d.ts @@ -0,0 +1,24 @@ +import { CanadianBrandEnvironment } from './constants/canada'; +import { EuropeanBrandEnvironment } from './constants/europe'; +import { ChineseBrandEnvironment } from './constants/china'; +import { AustraliaBrandEnvironment } from './constants/australia'; +import { Brand, VehicleStatusOptions } from './interfaces/common.interfaces'; +export declare const ALL_ENDPOINTS: { + CA: (brand: Brand) => CanadianBrandEnvironment['endpoints']; + EU: (brand: Brand) => EuropeanBrandEnvironment['endpoints']; + CN: (brand: Brand) => ChineseBrandEnvironment['endpoints']; + AU: (brand: Brand) => AustraliaBrandEnvironment['endpoints']; +}; +export declare const GEN2 = 2; +export declare const GEN1 = 1; +export type REGION = 'US' | 'CA' | 'EU' | 'CN' | 'AU'; +export declare enum REGIONS { + US = "US", + CA = "CA", + EU = "EU", + CN = "CN", + AU = "AU" +} +export type ChargeTarget = 50 | 60 | 70 | 80 | 90 | 100; +export declare const POSSIBLE_CHARGE_LIMIT_VALUES: number[]; +export declare const DEFAULT_VEHICLE_STATUS_OPTIONS: VehicleStatusOptions; diff --git a/dist/constants/america.d.ts b/dist/constants/america.d.ts new file mode 100644 index 0000000..66cf95b --- /dev/null +++ b/dist/constants/america.d.ts @@ -0,0 +1,9 @@ +import { Brand } from '../interfaces/common.interfaces'; +export interface AmericaBrandEnvironment { + brand: Brand; + host: string; + baseUrl: string; + clientId: string; + clientSecret: string; +} +export declare const getBrandEnvironment: (brand: Brand) => AmericaBrandEnvironment; diff --git a/dist/constants/australia.cfb.d.ts b/dist/constants/australia.cfb.d.ts new file mode 100644 index 0000000..62dc427 --- /dev/null +++ b/dist/constants/australia.cfb.d.ts @@ -0,0 +1,3 @@ +/// +export declare const kiaCFB: Buffer; +export declare const hyundaiCFB: Buffer; diff --git a/dist/constants/australia.d.ts b/dist/constants/australia.d.ts new file mode 100644 index 0000000..60c15b2 --- /dev/null +++ b/dist/constants/australia.d.ts @@ -0,0 +1,28 @@ +import { AustraliaBlueLinkyConfig } from '../controllers/australia.controller'; +import { Brand } from '../interfaces/common.interfaces'; +import { StampMode } from './stamps'; +export interface AustraliaBrandEnvironment { + brand: Brand; + host: string; + baseUrl: string; + clientId: string; + appId: string; + endpoints: { + integration: string; + silentSignIn: string; + session: string; + login: string; + language: string; + redirectUri: string; + token: string; + }; + basicToken: string; + stamp: () => Promise; +} +type EnvironmentConfig = { + stampMode: StampMode; + stampsFile?: string; +}; +type BrandEnvironmentConfig = Pick & Partial; +export declare const getBrandEnvironment: ({ brand, stampMode, stampsFile, }: BrandEnvironmentConfig) => AustraliaBrandEnvironment; +export {}; diff --git a/dist/constants/canada.d.ts b/dist/constants/canada.d.ts new file mode 100644 index 0000000..908561c --- /dev/null +++ b/dist/constants/canada.d.ts @@ -0,0 +1,28 @@ +import { Brand } from '../interfaces/common.interfaces'; +export interface CanadianBrandEnvironment { + brand: Brand; + host: string; + baseUrl: string; + origin: 'SPA'; + endpoints: { + login: string; + logout: string; + vehicleList: string; + vehicleInfo: string; + status: string; + remoteStatus: string; + lock: string; + unlock: string; + start: string; + stop: string; + locate: string; + hornlight: string; + verifyAccountToken: string; + verifyPin: string; + verifyToken: string; + setChargeTarget: string; + stopCharge: string; + startCharge: string; + }; +} +export declare const getBrandEnvironment: (brand: Brand) => CanadianBrandEnvironment; diff --git a/dist/constants/china.d.ts b/dist/constants/china.d.ts new file mode 100644 index 0000000..15771f9 --- /dev/null +++ b/dist/constants/china.d.ts @@ -0,0 +1,25 @@ +import { ChineseBlueLinkConfig } from '../controllers/chinese.controller'; +import { Brand } from '../interfaces/common.interfaces'; +export interface ChineseBrandEnvironment { + brand: Brand; + host: string; + baseUrl: string; + clientId: string; + appId: string; + endpoints: { + integration: string; + silentSignIn: string; + session: string; + login: string; + language: string; + redirectUri: string; + token: string; + }; + basicToken: string; + GCMSenderID: string; + providerDeviceId: string; + pushRegId: string; +} +type BrandEnvironmentConfig = Pick; +export declare const getBrandEnvironment: ({ brand, }: BrandEnvironmentConfig) => ChineseBrandEnvironment; +export {}; diff --git a/dist/constants/europe.cfb.d.ts b/dist/constants/europe.cfb.d.ts new file mode 100644 index 0000000..62dc427 --- /dev/null +++ b/dist/constants/europe.cfb.d.ts @@ -0,0 +1,3 @@ +/// +export declare const kiaCFB: Buffer; +export declare const hyundaiCFB: Buffer; diff --git a/dist/constants/europe.d.ts b/dist/constants/europe.d.ts new file mode 100644 index 0000000..27d22ac --- /dev/null +++ b/dist/constants/europe.d.ts @@ -0,0 +1,33 @@ +import { EuropeBlueLinkyConfig } from '../controllers/european.controller'; +import { Brand } from '../interfaces/common.interfaces'; +export type EULanguages = 'cs' | 'da' | 'nl' | 'en' | 'fi' | 'fr' | 'de' | 'it' | 'pl' | 'hu' | 'no' | 'sk' | 'es' | 'sv'; +export declare const EU_LANGUAGES: EULanguages[]; +export declare const DEFAULT_LANGUAGE: EULanguages; +export interface EuropeanBrandEnvironment { + brand: Brand; + host: string; + baseUrl: string; + clientId: string; + appId: string; + endpoints: { + integration: string; + silentSignIn: string; + session: string; + login: string; + language: string; + redirectUri: string; + token: string; + }; + basicToken: string; + GCMSenderID: string; + stamp: () => Promise; + brandAuthUrl: (options: { + language: EULanguages; + serviceId: string; + userId: string; + }) => string; +} +type EnvironmentConfig = Required> & Partial>; +type BrandEnvironmentConfig = Pick & Partial; +export declare const getBrandEnvironment: ({ brand, stampMode, stampsFile, }: BrandEnvironmentConfig) => EuropeanBrandEnvironment; +export {}; diff --git a/dist/constants/stamps.d.ts b/dist/constants/stamps.d.ts new file mode 100644 index 0000000..b1ad97d --- /dev/null +++ b/dist/constants/stamps.d.ts @@ -0,0 +1,16 @@ +import { Brand } from '../interfaces/common.interfaces'; +import { REGIONS } from '../constants'; +export declare enum StampMode { + LOCAL = "LOCAL", + DISTANT = "DISTANT" +} +export declare const getStampFromFile: (stampFileKey: string, stampHost: string, stampsFile?: string) => () => Promise; +export declare const getStampFromCFB: (appId: string, brand: Brand, region: REGIONS) => (() => Promise); +export declare const getStampGenerator: ({ appId, brand, mode, region, stampHost, stampsFile, }: { + appId: string; + brand: Brand; + mode: StampMode; + region: REGIONS; + stampHost: string; + stampsFile?: string | undefined; +}) => (() => Promise); diff --git a/dist/controllers/american.controller.d.ts b/dist/controllers/american.controller.d.ts new file mode 100644 index 0000000..6097151 --- /dev/null +++ b/dist/controllers/american.controller.d.ts @@ -0,0 +1,17 @@ +import { BlueLinkyConfig } from './../interfaces/common.interfaces'; +import { Vehicle } from '../vehicles/vehicle'; +import { SessionController } from './controller'; +import { AmericaBrandEnvironment } from '../constants/america'; +export interface AmericanBlueLinkyConfig extends BlueLinkyConfig { + region: 'US'; +} +export declare class AmericanController extends SessionController { + private _environment; + constructor(userConfig: AmericanBlueLinkyConfig); + get environment(): AmericaBrandEnvironment; + private vehicles; + refreshAccessToken(): Promise; + login(): Promise; + logout(): Promise; + getVehicles(): Promise>; +} diff --git a/dist/controllers/australia.controller.d.ts b/dist/controllers/australia.controller.d.ts new file mode 100644 index 0000000..8bf12b9 --- /dev/null +++ b/dist/controllers/australia.controller.d.ts @@ -0,0 +1,28 @@ +import { GotInstance, GotJSONFn } from 'got'; +import { Vehicle } from '../vehicles/vehicle'; +import { AustraliaBrandEnvironment } from './../constants/australia'; +import { BlueLinkyConfig, Session } from './../interfaces/common.interfaces'; +import { SessionController } from './controller'; +import { StampMode } from '../constants/stamps'; +export interface AustraliaBlueLinkyConfig extends BlueLinkyConfig { + region: 'AU'; + stampMode?: StampMode; + stampsFile?: string; +} +export declare class AustraliaController extends SessionController { + private _environment; + private authStrategy; + constructor(userConfig: AustraliaBlueLinkyConfig); + get environment(): AustraliaBrandEnvironment; + session: Session; + private vehicles; + refreshAccessToken(): Promise; + enterPin(): Promise; + login(): Promise; + logout(): Promise; + getVehicles(): Promise>; + private checkControlToken; + getVehicleHttpService(): Promise>; + getApiHttpService(): Promise>; + private get defaultHeaders(); +} diff --git a/dist/controllers/authStrategies/australia.authStrategy.d.ts b/dist/controllers/authStrategies/australia.authStrategy.d.ts new file mode 100644 index 0000000..daa1d0d --- /dev/null +++ b/dist/controllers/authStrategies/australia.authStrategy.d.ts @@ -0,0 +1,17 @@ +import { CookieJar } from 'tough-cookie'; +import { AuthStrategy, Code } from './authStrategy'; +import { AustraliaBrandEnvironment } from '../../constants/australia'; +export declare class AustraliaAuthStrategy implements AuthStrategy { + private readonly environment; + constructor(environment: AustraliaBrandEnvironment); + get name(): string; + login(user: { + username: string; + password: string; + }, options?: { + cookieJar: CookieJar; + }): Promise<{ + code: Code; + cookies: CookieJar; + }>; +} diff --git a/dist/controllers/authStrategies/authStrategy.d.ts b/dist/controllers/authStrategies/authStrategy.d.ts new file mode 100644 index 0000000..842e932 --- /dev/null +++ b/dist/controllers/authStrategies/authStrategy.d.ts @@ -0,0 +1,16 @@ +import { CookieJar } from 'tough-cookie'; +import { EULanguages, EuropeanBrandEnvironment } from '../../constants/europe'; +export type Code = string; +export interface AuthStrategy { + readonly name: string; + login(user: { + username: string; + password: string; + }, options?: { + cookieJar?: CookieJar; + }): Promise<{ + code: Code; + cookies: CookieJar; + }>; +} +export declare function initSession(environment: EuropeanBrandEnvironment, language?: EULanguages, cookies?: CookieJar): Promise; diff --git a/dist/controllers/authStrategies/china.authStrategy.d.ts b/dist/controllers/authStrategies/china.authStrategy.d.ts new file mode 100644 index 0000000..8e4e18e --- /dev/null +++ b/dist/controllers/authStrategies/china.authStrategy.d.ts @@ -0,0 +1,16 @@ +import { CookieJar } from 'tough-cookie'; +import { ChineseBrandEnvironment } from '../../constants/china'; +export type Code = string; +export interface AuthStrategy { + readonly name: string; + login(user: { + username: string; + password: string; + }, options?: { + cookieJar?: CookieJar; + }): Promise<{ + code: Code; + cookies: CookieJar; + }>; +} +export declare function initSession(environment: ChineseBrandEnvironment, cookies?: CookieJar): Promise; diff --git a/dist/controllers/authStrategies/chinese.legacyAuth.strategy.d.ts b/dist/controllers/authStrategies/chinese.legacyAuth.strategy.d.ts new file mode 100644 index 0000000..d675804 --- /dev/null +++ b/dist/controllers/authStrategies/chinese.legacyAuth.strategy.d.ts @@ -0,0 +1,17 @@ +import { CookieJar } from 'tough-cookie'; +import { ChineseBrandEnvironment } from '../../constants/china'; +import { AuthStrategy, Code } from './china.authStrategy'; +export declare class ChineseLegacyAuthStrategy implements AuthStrategy { + private readonly environment; + constructor(environment: ChineseBrandEnvironment); + get name(): string; + login(user: { + username: string; + password: string; + }, options?: { + cookieJar: CookieJar; + }): Promise<{ + code: Code; + cookies: CookieJar; + }>; +} diff --git a/dist/controllers/authStrategies/european.brandAuth.strategy.d.ts b/dist/controllers/authStrategies/european.brandAuth.strategy.d.ts new file mode 100644 index 0000000..f564ece --- /dev/null +++ b/dist/controllers/authStrategies/european.brandAuth.strategy.d.ts @@ -0,0 +1,18 @@ +import { CookieJar } from 'tough-cookie'; +import { EULanguages, EuropeanBrandEnvironment } from '../../constants/europe'; +import { AuthStrategy, Code } from './authStrategy'; +export declare class EuropeanBrandAuthStrategy implements AuthStrategy { + private readonly environment; + private readonly language; + constructor(environment: EuropeanBrandEnvironment, language: EULanguages); + get name(): string; + login(user: { + username: string; + password: string; + }, options?: { + cookieJar?: CookieJar; + }): Promise<{ + code: Code; + cookies: CookieJar; + }>; +} diff --git a/dist/controllers/authStrategies/european.legacyAuth.strategy.d.ts b/dist/controllers/authStrategies/european.legacyAuth.strategy.d.ts new file mode 100644 index 0000000..8df6ccc --- /dev/null +++ b/dist/controllers/authStrategies/european.legacyAuth.strategy.d.ts @@ -0,0 +1,18 @@ +import { CookieJar } from 'tough-cookie'; +import { EULanguages, EuropeanBrandEnvironment } from '../../constants/europe'; +import { AuthStrategy, Code } from './authStrategy'; +export declare class EuropeanLegacyAuthStrategy implements AuthStrategy { + private readonly environment; + private readonly language; + constructor(environment: EuropeanBrandEnvironment, language: EULanguages); + get name(): string; + login(user: { + username: string; + password: string; + }, options?: { + cookieJar: CookieJar; + }): Promise<{ + code: Code; + cookies: CookieJar; + }>; +} diff --git a/dist/controllers/canadian.controller.d.ts b/dist/controllers/canadian.controller.d.ts new file mode 100644 index 0000000..2cd4976 --- /dev/null +++ b/dist/controllers/canadian.controller.d.ts @@ -0,0 +1,19 @@ +import { BlueLinkyConfig } from '../interfaces/common.interfaces'; +import { CanadianBrandEnvironment } from '../constants/canada'; +import { Vehicle } from '../vehicles/vehicle'; +import { SessionController } from './controller'; +export interface CanadianBlueLinkyConfig extends BlueLinkyConfig { + region: 'CA'; +} +export declare class CanadianController extends SessionController { + private _environment; + constructor(userConfig: CanadianBlueLinkyConfig); + get environment(): CanadianBrandEnvironment; + private vehicles; + private timeOffset; + refreshAccessToken(): Promise; + login(): Promise; + logout(): Promise; + getVehicles(): Promise>; + private request; +} diff --git a/dist/controllers/chinese.controller.d.ts b/dist/controllers/chinese.controller.d.ts new file mode 100644 index 0000000..2dc39ed --- /dev/null +++ b/dist/controllers/chinese.controller.d.ts @@ -0,0 +1,26 @@ +import { ChineseBrandEnvironment } from '../constants/china'; +import { BlueLinkyConfig, Session } from '../interfaces/common.interfaces'; +import { GotInstance, GotJSONFn } from 'got'; +import { Vehicle } from '../vehicles/vehicle'; +import { SessionController } from './controller'; +export interface ChineseBlueLinkConfig extends BlueLinkyConfig { + region: 'CN'; +} +export declare class ChineseController extends SessionController { + private _environment; + private authStrategies; + constructor(userConfig: ChineseBlueLinkConfig); + get environment(): ChineseBrandEnvironment; + ß: any; + session: Session; + private vehicles; + refreshAccessToken(): Promise; + enterPin(): Promise; + login(): Promise; + logout(): Promise; + getVehicles(): Promise>; + private checkControlToken; + getVehicleHttpService(): Promise>; + getApiHttpService(): Promise>; + private get defaultHeaders(); +} diff --git a/dist/controllers/controller.d.ts b/dist/controllers/controller.d.ts new file mode 100644 index 0000000..7a9ab00 --- /dev/null +++ b/dist/controllers/controller.d.ts @@ -0,0 +1,12 @@ +import { Vehicle } from '../vehicles/vehicle'; +import { Session } from '../interfaces/common.interfaces'; +import { BlueLinkyConfig } from '../interfaces/common.interfaces'; +export declare abstract class SessionController { + readonly userConfig: T; + abstract login(): Promise; + abstract logout(): Promise; + abstract getVehicles(): Promise>; + abstract refreshAccessToken(): Promise; + session: Session; + constructor(userConfig: T); +} diff --git a/dist/controllers/european.controller.d.ts b/dist/controllers/european.controller.d.ts new file mode 100644 index 0000000..45e1ae5 --- /dev/null +++ b/dist/controllers/european.controller.d.ts @@ -0,0 +1,29 @@ +import { EuropeanBrandEnvironment, EULanguages } from './../constants/europe'; +import { BlueLinkyConfig, Session } from './../interfaces/common.interfaces'; +import { GotInstance, GotJSONFn } from 'got'; +import { Vehicle } from '../vehicles/vehicle'; +import { SessionController } from './controller'; +import { StampMode } from '../constants/stamps'; +export interface EuropeBlueLinkyConfig extends BlueLinkyConfig { + language?: EULanguages; + region: 'EU'; + stampMode?: StampMode; + stampsFile?: string; +} +export declare class EuropeanController extends SessionController { + private _environment; + private authStrategies; + constructor(userConfig: EuropeBlueLinkyConfig); + get environment(): EuropeanBrandEnvironment; + session: Session; + private vehicles; + refreshAccessToken(): Promise; + enterPin(): Promise; + login(): Promise; + logout(): Promise; + getVehicles(): Promise>; + private checkControlToken; + getVehicleHttpService(): Promise>; + getApiHttpService(): Promise>; + private get defaultHeaders(); +} diff --git a/dist/index.cjs b/dist/index.cjs new file mode 100644 index 0000000..62e9c61 --- /dev/null +++ b/dist/index.cjs @@ -0,0 +1,2 @@ +/* @preserve bluelinky / MIT License / https://github.com/Hacksore/bluelinky */ +"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("got"),t=require("winston"),i=require("fs"),o=require("util"),n=require("url"),r=require("tough-cookie"),s=require("node:crypto"),a=require("undici"),d=require("events");function l(e){var t=Object.create(null);return e&&Object.keys(e).forEach((function(i){if("default"!==i){var o=Object.getOwnPropertyDescriptor(e,i);Object.defineProperty(t,i,o.get?o:{enumerable:!0,get:function(){return e[i]}})}})),t.default=e,Object.freeze(t)}var c=l(t);function h(e,t,i,o){return new(i||(i=Promise))((function(n,r){function s(e){try{d(o.next(e))}catch(e){r(e)}}function a(e){try{d(o.throw(e))}catch(e){r(e)}}function d(e){var t;e.done?n(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(s,a)}d((o=o.apply(e,t||[])).next())}))}"function"==typeof SuppressedError&&SuppressedError;const u=process.env.LOG_LEVEL||"info",{colorize:v,json:p,combine:g,timestamp:f,printf:m}=c.format,y=m((({level:e,message:t,timestamp:i})=>(["array","object"].includes(typeof t)&&(t=JSON.stringify(t,null,2)),`[${i}] ${e}: ${t}`))),b=g(f({format:"YYYY-MM-DD HH:mm:ss"}),v(),p(),y),C=c.createLogger({format:b,level:u,transports:[new c.transports.Console({})]}),w=e=>({login:`${e}/tods/api/lgn`,logout:`${e}/tods/api/lgout`,vehicleList:`${e}/tods/api/vhcllst`,vehicleInfo:`${e}/tods/api/sltvhcl`,status:`${e}/tods/api/lstvhclsts`,remoteStatus:`${e}/tods/api/rltmvhclsts`,lock:`${e}/tods/api/drlck`,unlock:`${e}/tods/api/drulck`,start:`${e}/tods/api/evc/rfon`,stop:`${e}/tods/api/evc/rfoff`,startCharge:`${e}/tods/api/evc/rcstrt`,stopCharge:`${e}/tods/api/evc/rcstp`,setChargeTarget:`${e}/tods/api/evc/setsoc`,locate:`${e}/tods/api/fndmcr`,hornlight:`${e}/tods/api/hornlight`,verifyAccountToken:`${e}/tods/api/vrfyacctkn`,verifyPin:`${e}/tods/api/vrfypin`,verifyToken:`${e}/tods/api/vrfytnc`}),k=e=>{const t=`https://${e}`;return{host:e,baseUrl:t,origin:"SPA",endpoints:Object.freeze(w(t))}},S=e=>{switch(e){case"hyundai":return Object.freeze(Object.assign({brand:"hyundai"},k("mybluelink.ca")));case"kia":return Object.freeze(Object.assign({brand:"hyundai"},k("kiaconnect.ca")));default:throw new Error(`Constructor ${e} is not managed.`)}},T=Buffer.from("IDbMgWBXgic4MAyMgf5PFFRAdGX5O3IyC3uvN3scCs0gDpTFDuyvBorlAH9JMM2/hys=","base64"),A=Buffer.from("V60WkEmyRQaAfrBF1623/7QL62MjLVbCHdItGzQ1g5T/hkmKmMVTaMHv4cKGzgD3kfc=","base64"),O=Buffer.from("wLTVxwidmH8CfJYBWSnHD6E0huk0ozdiuygB4hLkM5XCgzAL1Dk5sE36d/bx5PFMQeU=","base64"),$=Buffer.from("RFtoRq/vDXJmRndoZaZQyfOot7OrIqGVFj96iY2WL3yyH5Z/pUvlUhqmCxD2t+D65SQ=","base64");var D;!function(e){e.LOCAL="LOCAL",e.DISTANT="DISTANT"}(D||(D={}));const I=new Map,E=(t,n,r)=>()=>h(void 0,void 0,void 0,(function*(){var s;const{stamps:a,generated:d,frequency:l}=null!==(s=I.get(t))&&void 0!==s?s:yield((t,n,...r)=>h(void 0,[t,n,...r],void 0,(function*(t,n,r=`${n}${t}.v2.json`){if(r.startsWith("file://")){const[,e]=r.split("file://"),t=yield o.promisify(i.readFile)(e);return JSON.parse(t.toString("utf-8"))}const{body:s}=yield e(r,{json:!0});return I.set(t,s),s})))(t,n,r),c=new Date(d),u=Date.now()-c.getTime(),v=Math.floor(u/l);return v/(a.length-1)>=.9&&I.delete(t),a[Math.min(v,a.length-1)]})),L=(e,t,i)=>{const o=((e,t)=>{switch(t){case _.AU:return"kia"===e?T:A;case _.EU:return"kia"===e?O:$;default:throw new Error("Local stamp generation is only supported in Australia and Europe")}})(t,i);return()=>h(void 0,void 0,void 0,(function*(){const t=Buffer.from(`${e}:${Date.now()}`,"utf-8");return Promise.resolve(((e,t)=>{if(e.length!==t.length)throw new Error(`XOR Buffers are not the same size ${e.length} vs ${t.length}`);const i=Buffer.alloc(e.length);for(let o=0;o{switch(i){case D.LOCAL:return L(e,t,o);case D.DISTANT:default:return E(`${t}-${e}`,n,r)}},R=["cs","da","nl","en","fi","fr","de","it","pl","hu","no","sk","es","sv"],M=(e,t)=>({session:`${e}/api/v1/user/oauth2/authorize?response_type=code&state=test&client_id=${t}&redirect_uri=${e}/api/v1/user/oauth2/redirect`,login:`${e}/api/v1/user/signin`,language:`${e}/api/v1/user/language`,redirectUri:`${e}/api/v1/user/oauth2/redirect`,token:`${e}/api/v1/user/oauth2/token`,integration:`${e}/api/v1/user/integrationinfo`,silentSignIn:`${e}/api/v1/user/silentsignin`}),V=({brand:e,stampMode:t=D.DISTANT,stampsFile:i})=>{switch(e){case"hyundai":return Object.freeze((({stampMode:e,stampsFile:t})=>{const i="prd.eu-ccapi.hyundai.com:8080",o=`https://${i}`,n="6d477c38-3ca4-4cf3-9557-2a1929a94654",r="1eba27d2-9a5b-4eba-8ec7-97eb6c62fb51";return{brand:"hyundai",host:i,baseUrl:o,clientId:n,appId:r,endpoints:Object.freeze(M(o,n)),basicToken:"Basic NmQ0NzdjMzgtM2NhNC00Y2YzLTk1NTctMmExOTI5YTk0NjU0OktVeTQ5WHhQekxwTHVvSzB4aEJDNzdXNlZYaG10UVI5aVFobUlGampvWTRJcHhzVg==",GCMSenderID:"414998006775",stamp:P({appId:r,brand:"hyundai",mode:e,region:_.EU,stampHost:"https://raw.githubusercontent.com/neoPix/bluelinky-stamps/master/",stampsFile:t}),brandAuthUrl:({language:e,serviceId:t,userId:i})=>`https://eu-account.hyundai.com/auth/realms/euhyundaiidm/protocol/openid-connect/auth?client_id=64621b96-0f0d-11ec-82a8-0242ac130003&scope=openid%20profile%20email%20phone&response_type=code&hkid_session_reset=true&redirect_uri=${o}/api/v1/user/integration/redirect/login&ui_locales=${e}&state=${t}:${i}`}})({stampMode:t,stampsFile:i}));case"kia":return Object.freeze((({stampMode:e,stampsFile:t})=>{const i="prd.eu-ccapi.kia.com:8080",o=`https://${i}`,n="fdc85c00-0a2f-4c64-bcb4-2cfb1500730a",r="a2b8469b-30a3-4361-8e13-6fceea8fbe74";return{brand:"kia",host:i,baseUrl:o,clientId:n,appId:r,endpoints:Object.freeze(M(o,n)),basicToken:"Basic ZmRjODVjMDAtMGEyZi00YzY0LWJjYjQtMmNmYjE1MDA3MzBhOnNlY3JldA==",GCMSenderID:"345127537656",stamp:P({appId:r,brand:"kia",mode:e,region:_.EU,stampHost:"https://raw.githubusercontent.com/neoPix/bluelinky-stamps/master/",stampsFile:t}),brandAuthUrl:({language:e,serviceId:t,userId:i})=>`https://eu-account.kia.com/auth/realms/eukiaidm/protocol/openid-connect/auth?client_id=572e0304-5f8d-4b4c-9dd5-41aa84eed160&scope=openid%20profile%20email%20phone&response_type=code&hkid_session_reset=true&redirect_uri=${o}/api/v1/user/integration/redirect/login&ui_locales=${e}&state=${t}:${i}`}})({stampMode:t,stampsFile:i}));default:throw new Error(`Constructor ${e} is not managed.`)}},x=(e,t)=>({session:`${e}/api/v1/user/oauth2/authorize?response_type=code&state=test&client_id=${t}&redirect_uri=${e}:443/api/v1/user/oauth2/redirect`,login:`${e}/api/v1/user/signin`,language:`${e}/api/v1/user/language`,redirectUri:`${e}:443/api/v1/user/oauth2/redirect`,token:`${e}/api/v1/user/oauth2/token`,integration:`${e}/api/v1/user/integrationinfo`,silentSignIn:`${e}/api/v1/user/silentsignin`}),U=({brand:e})=>{switch(e){case"hyundai":return Object.freeze((()=>{const e="prd.cn-ccapi.hyundai.com",t=`https://${e}`,i="72b3d019-5bc7-443d-a437-08f307cf06e2";return{brand:"hyundai",host:e,baseUrl:t,clientId:i,appId:"ed01581a-380f-48cd-83d4-ed1490c272d0",endpoints:Object.freeze(x(t,i)),basicToken:"Basic NzJiM2QwMTktNWJjNy00NDNkLWE0MzctMDhmMzA3Y2YwNmUyOnNlY3JldA==",GCMSenderID:"414998006775",providerDeviceId:"59af09e554a9442ab8589c9500d04d2e",pushRegId:"1"}})());case"kia":return Object.freeze((()=>{const e="prd.cn-ccapi.kia.com",t=`https://${e}`,i="9d5df92a-06ae-435f-b459-8304f2efcc67";return{brand:"kia",host:e,baseUrl:t,clientId:i,appId:"eea8762c-adfc-4ee4-8d7a-6e2452ddf342",endpoints:Object.freeze(x(t,i)),basicToken:"Basic OWQ1ZGY5MmEtMDZhZS00MzVmLWI0NTktODMwNGYyZWZjYzY3OnRzWGRrVWcwOEF2MlpaelhPZ1d6Snl4VVQ2eWVTbk5OUWtYWFBSZEtXRUFOd2wxcA==",GCMSenderID:"345127537656",providerDeviceId:"32dedba78045415b92db816e805ed47b",pushRegId:"ogc+GB5gom7zDEQjPhb3lP+bjjM=DG2rQ9Zuq0otwOU7n9y08LKjYpo="}})());default:throw new Error(`Constructor ${e} is not managed.`)}},H=(e,t)=>({session:`${e}/api/v1/user/oauth2/authorize?response_type=code&client_id=${t}&redirect_uri=${encodeURIComponent(`${e}/api/v1/user/oauth2/redirect`)}&lang=en`,login:`${e}/api/v1/user/signin`,language:`${e}/api/v1/user/language`,redirectUri:`${e}/api/v1/user/oauth2/redirect`,token:`${e}/api/v1/user/oauth2/token`,integration:`${e}/api/v1/user/integrationinfo`,silentSignIn:`${e}/api/v1/user/silentsignin`}),j=({brand:e,stampMode:t=D.LOCAL,stampsFile:i})=>{switch(e){case"hyundai":return Object.freeze((({stampMode:e,stampsFile:t})=>{const i="au-apigw.ccs.hyundai.com.au:8080",o=`https://${i}`,n="855c72df-dfd7-4230-ab03-67cbf902bb1c",r="f9ccfdac-a48d-4c57-bd32-9116963c24ed";return{brand:"hyundai",host:i,baseUrl:o,clientId:n,appId:r,endpoints:Object.freeze(H(o,n)),basicToken:"Basic ODU1YzcyZGYtZGZkNy00MjMwLWFiMDMtNjdjYmY5MDJiYjFjOmU2ZmJ3SE0zMllOYmhRbDBwdmlhUHAzcmY0dDNTNms5MWVjZUEzTUpMZGJkVGhDTw==",stamp:P({appId:r,brand:"hyundai",mode:e,region:_.AU,stampHost:"https://raw.githubusercontent.com/neoPix/bluelinky-stamps/master/",stampsFile:t})}})({stampMode:t,stampsFile:i}));case"kia":return Object.freeze((({stampMode:e,stampsFile:t})=>{const i="au-apigw.ccs.kia.com.au:8082",o=`https://${i}`,n="8acb778a-b918-4a8d-8624-73a0beb64289",r="4ad4dcde-be23-48a8-bc1c-91b94f5c06f8";return{brand:"hyundai",host:i,baseUrl:o,clientId:n,appId:r,endpoints:Object.freeze(H(o,n)),basicToken:"Basic OGFjYjc3OGEtYjkxOC00YThkLTg2MjQtNzNhMGJlYjY0Mjg5OjdTY01NbTZmRVlYZGlFUEN4YVBhUW1nZVlkbFVyZndvaDRBZlhHT3pZSVMyQ3U5VA==",stamp:P({appId:r,brand:"kia",mode:e,region:_.AU,stampHost:"https://raw.githubusercontent.com/neoPix/bluelinky-stamps/master/",stampsFile:t})}})({stampMode:t,stampsFile:i}));default:throw new Error(`Constructor ${e} is not managed.`)}};var _;!function(e){e.US="US",e.CA="CA",e.EU="EU",e.CN="CN",e.AU="AU"}(_||(_={}));const N=[50,60,70,80,90,100],F={refresh:!1,parsed:!1};class z{constructor(e,t){this.vehicleConfig=e,this.controller=t,this._fullStatus=null,this._status=null,this._location=null,this._odometer=null,this.userConfig={username:void 0,password:void 0,region:_.EU,brand:"hyundai",autoLogin:!0,pin:void 0,vin:void 0,vehicleId:void 0},this.userConfig=t.userConfig}vin(){return this.vehicleConfig.vin}name(){return this.vehicleConfig.name}nickname(){return this.vehicleConfig.nickname}id(){return this.vehicleConfig.id}brandIndicator(){return this.vehicleConfig.brandIndicator}}class B extends z{constructor(e,t){super(e,t),this.vehicleConfig=e,this.controller=t,this.region=_.US,C.debug(`US Vehicle ${this.vehicleConfig.regId} created`)}getDefaultHeaders(){return{access_token:this.controller.session.accessToken,client_id:this.controller.environment.clientId,Host:this.controller.environment.host,"User-Agent":"okhttp/3.12.0",registrationId:this.vehicleConfig.regId,gen:this.vehicleConfig.generation,username:this.userConfig.username,vin:this.vehicleConfig.vin,"APPCLOUD-VIN":this.vehicleConfig.vin,Language:"0",to:"ISS",encryptFlag:"false",from:"SPA",brandIndicator:this.vehicleConfig.brandIndicator,bluelinkservicepin:this.userConfig.pin,offset:"-5"}}fullStatus(){throw new Error("Method not implemented.")}odometer(){return h(this,void 0,void 0,(function*(){const e=yield this._request(`/ac/v2/enrollment/details/${this.userConfig.username}`,{method:"GET",headers:Object.assign({},this.getDefaultHeaders())});if(200!==e.statusCode)throw"Failed to get odometer reading!";const t=JSON.parse(e.body).enrolledVehicleDetails.find((e=>e.vehicleDetails.vin===this.vin()));return this._odometer={value:t.vehicleDetails.odometer,unit:0},this._odometer}))}location(){return h(this,void 0,void 0,(function*(){const e=yield this._request("/ac/v2/rcs/rfc/findMyCar",{method:"GET",headers:Object.assign({},this.getDefaultHeaders())});if(200!==e.statusCode)throw"Failed to get location!";const t=JSON.parse(e.body);return{latitude:t.coord.lat,longitude:t.coord.lon,altitude:t.coord.alt,speed:{unit:t.speed.unit,value:t.speed.value},heading:t.head}}))}start(e){return h(this,void 0,void 0,(function*(){const t=Object.assign(Object.assign({},{hvac:!1,duration:10,temperature:70,defrost:!1,heatedFeatures:!1,unit:"F"}),e),i={Ims:0,airCtrl:+t.hvac,airTemp:{unit:1,value:`${t.temperature}`},defrost:t.defrost,heating1:+t.heatedFeatures,igniOnDuration:t.duration,seatHeaterVentInfo:null,username:this.userConfig.username,vin:this.vehicleConfig.vin};return 200===(yield this._request("/ac/v2/rcs/rsc/start",{method:"POST",headers:Object.assign(Object.assign({},this.getDefaultHeaders()),{offset:"-4"}),body:i,json:!0})).statusCode?"Vehicle started!":"Failed to start vehicle"}))}stop(){return h(this,void 0,void 0,(function*(){if(200===(yield this._request("/ac/v2/rcs/rsc/stop",{method:"POST",headers:Object.assign(Object.assign({},this.getDefaultHeaders()),{offset:"-4"})})).statusCode)return"Vehicle stopped";throw"Failed to stop vehicle!"}))}status(e){return h(this,void 0,void 0,(function*(){var t,i,o,n,r,s,a,d,l,c,h,u,v,p,g,f,m,y,b;const C=Object.assign(Object.assign({},F),e),w=yield this._request("/ac/v2/rcs/rvs/vehicleStatus",{method:"GET",headers:Object.assign({REFRESH:C.refresh.toString()},this.getDefaultHeaders())}),{vehicleStatus:k}=JSON.parse(w.body),S={chassis:{hoodOpen:null==k?void 0:k.hoodOpen,trunkOpen:null==k?void 0:k.trunkOpen,locked:null==k?void 0:k.doorLock,openDoors:{frontRight:!!(null===(t=null==k?void 0:k.doorOpen)||void 0===t?void 0:t.frontRight),frontLeft:!!(null===(i=null==k?void 0:k.doorOpen)||void 0===i?void 0:i.frontLeft),backLeft:!!(null===(o=null==k?void 0:k.doorOpen)||void 0===o?void 0:o.backLeft),backRight:!!(null===(n=null==k?void 0:k.doorOpen)||void 0===n?void 0:n.backRight)},tirePressureWarningLamp:{rearLeft:!!(null===(r=null==k?void 0:k.tirePressureLamp)||void 0===r?void 0:r.tirePressureWarningLampRearLeft),frontLeft:!!(null===(s=null==k?void 0:k.tirePressureLamp)||void 0===s?void 0:s.tirePressureWarningLampFrontLeft),frontRight:!!(null===(a=null==k?void 0:k.tirePressureLamp)||void 0===a?void 0:a.tirePressureWarningLampFrontRight),rearRight:!!(null===(d=null==k?void 0:k.tirePressureLamp)||void 0===d?void 0:d.tirePressureWarningLampRearRight),all:!!(null===(l=null==k?void 0:k.tirePressureLamp)||void 0===l?void 0:l.tirePressureWarningLampAll)}},climate:{active:null==k?void 0:k.airCtrlOn,steeringwheelHeat:!!(null==k?void 0:k.steerWheelHeat),sideMirrorHeat:!1,rearWindowHeat:!!(null==k?void 0:k.sideBackWindowHeat),defrost:null==k?void 0:k.defrost,temperatureSetpoint:null===(c=null==k?void 0:k.airTemp)||void 0===c?void 0:c.value,temperatureUnit:null===(h=null==k?void 0:k.airTemp)||void 0===h?void 0:h.unit},engine:{ignition:null==k?void 0:k.engine,accessory:null==k?void 0:k.acc,range:(null===(g=null===(p=null===(v=null===(u=null==k?void 0:k.evStatus)||void 0===u?void 0:u.drvDistance[0])||void 0===v?void 0:v.rangeByFuel)||void 0===p?void 0:p.totalAvailableRange)||void 0===g?void 0:g.value)||(null===(f=null==k?void 0:k.dte)||void 0===f?void 0:f.value),charging:null===(m=null==k?void 0:k.evStatus)||void 0===m?void 0:m.batteryCharge,batteryCharge12v:null===(y=null==k?void 0:k.battery)||void 0===y?void 0:y.batSoc,batteryChargeHV:null===(b=null==k?void 0:k.evStatus)||void 0===b?void 0:b.batteryStatus},lastupdate:new Date(null==k?void 0:k.dateTime)};return this._status=C.parsed?S:k,this._status}))}unlock(){return h(this,void 0,void 0,(function*(){const e=new n.URLSearchParams;e.append("userName",this.userConfig.username||""),e.append("vin",this.vehicleConfig.vin);return 200===(yield this._request("/ac/v2/rcs/rdo/on",{method:"POST",headers:Object.assign({},this.getDefaultHeaders()),body:e.toString()})).statusCode?"Unlock successful":"Something went wrong!"}))}lock(){return h(this,void 0,void 0,(function*(){const e=new n.URLSearchParams;e.append("userName",this.userConfig.username||""),e.append("vin",this.vehicleConfig.vin);return 200===(yield this._request("/ac/v2/rcs/rdo/off",{method:"POST",headers:Object.assign({},this.getDefaultHeaders()),body:e.toString()})).statusCode?"Lock successful":"Something went wrong!"}))}startCharge(){return h(this,void 0,void 0,(function*(){if(200===(yield this._request(`/api/v2/spa/vehicles/${this.vehicleConfig.id}/control/charge`,{method:"POST"})).statusCode)return C.debug(`Send start charge command to Vehicle ${this.vehicleConfig.id}`),"Start charge successful";throw"Something went wrong!"}))}stopCharge(){return h(this,void 0,void 0,(function*(){if(200===(yield e(`/api/v2/spa/vehicles/${this.vehicleConfig.id}/control/charge`,{method:"POST"})).statusCode)return C.debug(`Send stop charge command to vehicle ${this.vehicleConfig.id}`),"Stop charge successful";throw"Something went wrong!"}))}_request(t,i){return h(this,void 0,void 0,(function*(){yield this.controller.refreshAccessToken(),i.headers.access_token=this.controller.session.accessToken;const o=yield e(`${this.controller.environment.baseUrl}/${t}`,Object.assign({throwHttpErrors:!1},i));return(null==o?void 0:o.body)&&C.debug(o.body),o}))}}class J{constructor(e){this.userConfig=e,this.session={accessToken:"",refreshToken:"",controlToken:"",deviceId:"",tokenExpiresAt:0}}}class Y extends Error{constructor(e,t){super(e),this.source=t,this.name=Y.ErrorName}}Y.ErrorName="ManagedBluelinkyError";const W=(t,i)=>{var o;return t instanceof e.HTTPError?new Y(`${i?`@${i}: `:""}[${t.statusCode}] ${t.statusMessage} on [${t.method}] ${t.url} - ${JSON.stringify(t.body)}`,t):t instanceof e.ParseError?new Y(`${i?`@${i}: `:""} Parsing error on [${t.method}] ${t.url} - ${JSON.stringify(null===(o=t.response)||void 0===o?void 0:o.body)}`,t):(Error,t)},G=(e,t)=>h(void 0,void 0,void 0,(function*(){const i=[];for(let o=0;o"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(e){const t=16*Math.random()|0;return("x"==e?t:3&t|8).toString(16)}));class Z extends J{constructor(e){super(e),this.vehicles=[],this._environment=(e=>{switch(e){case"hyundai":return Object.freeze((()=>{const e="api.telematics.hyundaiusa.com";return{brand:"hyundai",host:e,baseUrl:`https://${e}`,clientId:"m66129Bb-em93-SPAHYN-bZ91-am4540zp19920",clientSecret:"v558o935-6nne-423i-baa8"}})());case"kia":return Object.freeze((()=>{const e="api.owners.kia.com";return{brand:"kia",host:e,baseUrl:`https://${e}/apigw/v1/`,clientId:"MWAMOBILE",clientSecret:"98er-w34rf-ibf3-3f6h"}})());default:throw new Error(`Constructor ${e} is not managed.`)}})(e.brand),C.debug("US Controller created")}get environment(){return this._environment}refreshAccessToken(){return h(this,void 0,void 0,(function*(){const t=Math.floor(Date.now()/1e3-this.session.tokenExpiresAt)>=-10;try{if(this.session.refreshToken&&t){C.debug("refreshing token");const t=yield e(`${this.environment.baseUrl}/v2/ac/oauth/token/refresh`,{method:"POST",body:{refresh_token:this.session.refreshToken},headers:{"User-Agent":"PostmanRuntime/7.26.10",client_secret:this.environment.clientSecret,client_id:this.environment.clientId},json:!0});return C.debug(t.body),this.session.accessToken=t.body.access_token,this.session.refreshToken=t.body.refresh_token,this.session.tokenExpiresAt=Math.floor(+new Date/1e3+parseInt(t.body.expires_in)),C.debug("Token refreshed"),"Token refreshed"}return C.debug("Token not expired, no need to refresh"),"Token not expired, no need to refresh"}catch(e){throw W(e,"AmericanController.refreshAccessToken")}}))}login(){return h(this,void 0,void 0,(function*(){C.debug("Logging in to the API");try{const t=yield e(`${this.environment.baseUrl}/v2/ac/oauth/token`,{method:"POST",body:{username:this.userConfig.username,password:this.userConfig.password},headers:{"User-Agent":"PostmanRuntime/7.26.10",client_id:this.environment.clientId,client_secret:this.environment.clientSecret},json:!0});return C.debug(t.body),200!==t.statusCode?"login bad":(this.session.accessToken=t.body.access_token,this.session.refreshToken=t.body.refresh_token,this.session.tokenExpiresAt=Math.floor(+new Date/1e3+parseInt(t.body.expires_in)),"login good")}catch(e){throw W(e,"AmericanController.login")}}))}logout(){return h(this,void 0,void 0,(function*(){return"OK"}))}getVehicles(){return h(this,void 0,void 0,(function*(){try{const t=yield e(`${this.environment.baseUrl}/ac/v2/enrollment/details/${this.userConfig.username}`,{method:"GET",headers:{access_token:this.session.accessToken,client_id:this.environment.clientId,Host:this.environment.host,"User-Agent":"okhttp/3.12.0",payloadGenerated:"20200226171938",includeNonConnectedVehicles:"Y"}}),i=JSON.parse(t.body);return void 0===i.enrolledVehicleDetails?(this.vehicles=[],this.vehicles):(this.vehicles=i.enrolledVehicleDetails.map((e=>{const t=e.vehicleDetails,i={nickname:t.nickName,name:t.nickName,vin:t.vin,regDate:t.enrollmentDate,brandIndicator:t.brandIndicator,regId:t.regid,generation:t.modelYear>2016?"2":"1"};return new B(i,this)})),this.vehicles)}catch(e){throw W(e,"AmericanController.getVehicles")}}))}}var K,Q,X;!function(e){e[e.UNPLUGED=0]="UNPLUGED",e[e.FAST=1]="FAST",e[e.PORTABLE=2]="PORTABLE",e[e.STATION=3]="STATION"}(K||(K={})),function(e){e[e.FAST=0]="FAST",e[e.SLOW=1]="SLOW"}(Q||(Q={})),function(e){e[e.CLOSED=0]="CLOSED",e[e.OPEN=1]="OPEN",e[e.VENTILATION=2]="VENTILATION"}(X||(X={}));const ee=(e,t,i)=>{const o=[];for(let n=e;n<=t;n+=i)o.push(n);return o},te={EU:{start:14,end:30,step:.5},CA:{start:16,end:32,step:.5},CN:{start:14,end:30,step:.5},AU:{start:17,end:27,step:.5}},ie=(e,t)=>{const{start:i,end:o,step:n}=te[e],r=ee(i,o,n).indexOf(t);return`${("0x"+r.toString(16).substr(-4).toUpperCase()).split("x")[1].toUpperCase()}H`.padStart(3,"0")},oe=(e,t)=>{const{start:i,end:o,step:n}=te[e];return ee(i,o,n)[parseInt(t,16)]},ne=e=>{const t=parseInt(e.substring(0,4)),i=parseInt(e.substring(4,6));if(e.length<=6)return new Date(t,i-1);const o=parseInt(e.substring(6,8));if(e.length<=8)return new Date(t,i-1,o);const n=parseInt(e.substring(8,10)),r=parseInt(e.substring(10,12)),s=parseInt(e.substring(12,14));return new Date(t,i-1,o,n,r,s)},re=(e,t)=>new Date(e.getTime()+6e4*t);var se,ae;!function(e){e[e.DAY=0]="DAY",e[e.MONTH=1]="MONTH",e[e.ALL=2]="ALL"}(se||(se={})),function(e){e[e.TOTAL=0]="TOTAL",e[e.AVERAGE=1]="AVERAGE",e[e.TODAY=2]="TODAY"}(ae||(ae={}));class de extends z{constructor(e,t){super(e,t),this.vehicleConfig=e,this.controller=t,this.region=_.EU,this.serverRates={max:-1,current:-1},C.debug(`EU Vehicle ${this.vehicleConfig.id} created`)}start(e){return h(this,void 0,void 0,(function*(){const t=yield this.controller.getVehicleHttpService();try{const i=this.updateRates(yield t.post(`/api/v2/spa/vehicles/${this.vehicleConfig.id}/control/temperature`,{body:{action:"start",hvacType:0,options:{defrost:e.defrost,heating1:e.heatedFeatures?1:0},tempCode:ie(_.EU,e.temperature),unit:e.unit}}));return C.info(`Climate started for vehicle ${this.vehicleConfig.id}`),i.body}catch(e){throw W(e,"EuropeVehicle.start")}}))}stop(){return h(this,void 0,void 0,(function*(){const e=yield this.controller.getVehicleHttpService();try{const t=this.updateRates(yield e.post(`/api/v2/spa/vehicles/${this.vehicleConfig.id}/control/temperature`,{body:{action:"stop",hvacType:0,options:{defrost:!0,heating1:1},tempCode:"10H",unit:"C"}}));return C.info(`Climate stopped for vehicle ${this.vehicleConfig.id}`),t.body}catch(e){throw W(e,"EuropeVehicle.stop")}}))}lock(){return h(this,void 0,void 0,(function*(){const e=yield this.controller.getVehicleHttpService();try{return 200===this.updateRates(yield e.post(`/api/v2/spa/vehicles/${this.vehicleConfig.id}/control/door`,{body:{action:"close",deviceId:this.controller.session.deviceId}})).statusCode?(C.debug(`Vehicle ${this.vehicleConfig.id} locked`),"Lock successful"):"Something went wrong!"}catch(e){throw W(e,"EuropeVehicle.lock")}}))}unlock(){return h(this,void 0,void 0,(function*(){const e=yield this.controller.getVehicleHttpService();try{return 200===this.updateRates(yield e.post(`/api/v2/spa/vehicles/${this.vehicleConfig.id}/control/door`,{body:{action:"open",deviceId:this.controller.session.deviceId}})).statusCode?(C.debug(`Vehicle ${this.vehicleConfig.id} unlocked`),"Unlock successful"):"Something went wrong!"}catch(e){throw W(e,"EuropeVehicle.unlock")}}))}fullStatus(e){return h(this,void 0,void 0,(function*(){const t=Object.assign(Object.assign({},F),e),i=yield this.controller.getVehicleHttpService();try{const e=this.updateRates(yield i.get(`/api/v2/spa/vehicles/${this.vehicleConfig.id}/status/latest`)).body.resMsg.vehicleStatusInfo,o=this.updateRates(yield i.get(`/api/v2/spa/vehicles/${this.vehicleConfig.id}/ccs2/carstatus/latest`));if(null!=o.body.resMsg.state.Vehicle&&(e.ccs2Status=o.body.resMsg),t.refresh){const t=this.updateRates(yield i.get(`/api/v2/spa/vehicles/${this.vehicleConfig.id}/status`));e.vehicleStatus=t.body.resMsg;const o=this.updateRates(yield i.get(`/api/v2/spa/vehicles/${this.vehicleConfig.id}/location`));e.vehicleLocation=o.body.resMsg.gpsDetail}return this._fullStatus=e,this._fullStatus}catch(e){throw W(e,"EuropeVehicle.fullStatus")}}))}status(e){return h(this,void 0,void 0,(function*(){var t,i,o,n,r,s,a,d,l,c,h,u,v,p,g,f,m,y,b,C,w,k,S,T,A,O,$,D,I,E,L,P,R,M,V,x,U,H,j,N,z,B,J,Y;const G=Object.assign(Object.assign({},F),e),q=yield this.controller.getVehicleHttpService();try{const e=G.refresh?"":"/latest",F=this.updateRates(yield q.get(`/api/v2/spa/vehicles/${this.vehicleConfig.id}/status${e}`)),W=G.refresh?F.body.resMsg:F.body.resMsg.vehicleStatusInfo.vehicleStatus,Z={chassis:{hoodOpen:null==W?void 0:W.hoodOpen,trunkOpen:null==W?void 0:W.trunkOpen,locked:W.doorLock,openDoors:{frontRight:!!(null===(t=null==W?void 0:W.doorOpen)||void 0===t?void 0:t.frontRight),frontLeft:!!(null===(i=null==W?void 0:W.doorOpen)||void 0===i?void 0:i.frontLeft),backLeft:!!(null===(o=null==W?void 0:W.doorOpen)||void 0===o?void 0:o.backLeft),backRight:!!(null===(n=null==W?void 0:W.doorOpen)||void 0===n?void 0:n.backRight)},tirePressureWarningLamp:{rearLeft:!!(null===(r=null==W?void 0:W.tirePressureLamp)||void 0===r?void 0:r.tirePressureLampRL),frontLeft:!!(null===(s=null==W?void 0:W.tirePressureLamp)||void 0===s?void 0:s.tirePressureLampFL),frontRight:!!(null===(a=null==W?void 0:W.tirePressureLamp)||void 0===a?void 0:a.tirePressureLampFR),rearRight:!!(null===(d=null==W?void 0:W.tirePressureLamp)||void 0===d?void 0:d.tirePressureLampRR),all:!!(null===(l=null==W?void 0:W.tirePressureLamp)||void 0===l?void 0:l.tirePressureWarningLampAll)}},climate:{active:null==W?void 0:W.airCtrlOn,steeringwheelHeat:!!(null==W?void 0:W.steerWheelHeat),sideMirrorHeat:!1,rearWindowHeat:!!(null==W?void 0:W.sideBackWindowHeat),defrost:null==W?void 0:W.defrost,temperatureSetpoint:oe(_.EU,null===(c=null==W?void 0:W.airTemp)||void 0===c?void 0:c.value),temperatureUnit:null===(h=null==W?void 0:W.airTemp)||void 0===h?void 0:h.unit},engine:{ignition:W.engine,accessory:null==W?void 0:W.acc,rangeGas:null!==(f=null===(g=null===(p=null===(v=null===(u=null==W?void 0:W.evStatus)||void 0===u?void 0:u.drvDistance[0])||void 0===v?void 0:v.rangeByFuel)||void 0===p?void 0:p.gasModeRange)||void 0===g?void 0:g.value)&&void 0!==f?f:null===(m=null==W?void 0:W.dte)||void 0===m?void 0:m.value,range:null===(w=null===(C=null===(b=null===(y=null==W?void 0:W.evStatus)||void 0===y?void 0:y.drvDistance[0])||void 0===b?void 0:b.rangeByFuel)||void 0===C?void 0:C.totalAvailableRange)||void 0===w?void 0:w.value,rangeEV:null===(A=null===(T=null===(S=null===(k=null==W?void 0:W.evStatus)||void 0===k?void 0:k.drvDistance[0])||void 0===S?void 0:S.rangeByFuel)||void 0===T?void 0:T.evModeRange)||void 0===A?void 0:A.value,plugedTo:null!==($=null===(O=null==W?void 0:W.evStatus)||void 0===O?void 0:O.batteryPlugin)&&void 0!==$?$:K.UNPLUGED,charging:null===(D=null==W?void 0:W.evStatus)||void 0===D?void 0:D.batteryCharge,estimatedCurrentChargeDuration:null===(L=null===(E=null===(I=null==W?void 0:W.evStatus)||void 0===I?void 0:I.remainTime2)||void 0===E?void 0:E.atc)||void 0===L?void 0:L.value,estimatedFastChargeDuration:null===(M=null===(R=null===(P=null==W?void 0:W.evStatus)||void 0===P?void 0:P.remainTime2)||void 0===R?void 0:R.etc1)||void 0===M?void 0:M.value,estimatedPortableChargeDuration:null===(U=null===(x=null===(V=null==W?void 0:W.evStatus)||void 0===V?void 0:V.remainTime2)||void 0===x?void 0:x.etc2)||void 0===U?void 0:U.value,estimatedStationChargeDuration:null===(N=null===(j=null===(H=null==W?void 0:W.evStatus)||void 0===H?void 0:H.remainTime2)||void 0===j?void 0:j.etc3)||void 0===N?void 0:N.value,batteryCharge12v:null===(z=null==W?void 0:W.battery)||void 0===z?void 0:z.batSoc,batteryChargeHV:null===(B=null==W?void 0:W.evStatus)||void 0===B?void 0:B.batteryStatus},lastupdate:(null==W?void 0:W.time)?ne(null==W?void 0:W.time):null};return Z.engine.range||(Z.engine.rangeEV||Z.engine.rangeGas)&&(Z.engine.range=(null!==(J=Z.engine.rangeEV)&&void 0!==J?J:0)+(null!==(Y=Z.engine.rangeGas)&&void 0!==Y?Y:0)),this._status=G.parsed?Z:W,this._status}catch(e){throw W(e,"EuropeVehicle.status")}}))}odometer(){return h(this,void 0,void 0,(function*(){const e=yield this.controller.getVehicleHttpService();try{const t=this.updateRates(yield e.get(`/api/v2/spa/vehicles/${this.vehicleConfig.id}/status/latest`));return this._odometer=t.body.resMsg.vehicleStatusInfo.odometer,this._odometer}catch(e){throw W(e,"EuropeVehicle.odometer")}}))}location(){return h(this,void 0,void 0,(function*(){var e,t,i,o,n,r,s;const a=yield this.controller.getVehicleHttpService();try{const d=this.updateRates(yield a.get(`/api/v2/spa/vehicles/${this.vehicleConfig.id}/location`)),l=null!==(t=null===(e=d.body.resMsg)||void 0===e?void 0:e.gpsDetail)&&void 0!==t?t:d.body.resMsg;return this._location={latitude:null===(i=null==l?void 0:l.coord)||void 0===i?void 0:i.lat,longitude:null===(o=null==l?void 0:l.coord)||void 0===o?void 0:o.lon,altitude:null===(n=null==l?void 0:l.coord)||void 0===n?void 0:n.alt,speed:{unit:null===(r=null==l?void 0:l.speed)||void 0===r?void 0:r.unit,value:null===(s=null==l?void 0:l.speed)||void 0===s?void 0:s.value},heading:null==l?void 0:l.head},this._location}catch(e){throw W(e,"EuropeVehicle.location")}}))}startCharge(){return h(this,void 0,void 0,(function*(){const e=yield this.controller.getVehicleHttpService();try{if(200===this.updateRates(yield e.post(`/api/v2/spa/vehicles/${this.vehicleConfig.id}/control/charge`,{body:{action:"start",deviceId:this.controller.session.deviceId}})).statusCode)return C.debug(`Send start charge command to Vehicle ${this.vehicleConfig.id}`),"Start charge successful";throw"Something went wrong!"}catch(e){throw W(e,"EuropeVehicle.startCharge")}}))}stopCharge(){return h(this,void 0,void 0,(function*(){const e=yield this.controller.getVehicleHttpService();try{if(200===this.updateRates(yield e.post(`/api/v2/spa/vehicles/${this.vehicleConfig.id}/control/charge`,{body:{action:"stop",deviceId:this.controller.session.deviceId}})).statusCode)return C.debug(`Send stop charge command to Vehicle ${this.vehicleConfig.id}`),"Stop charge successful";throw"Something went wrong!"}catch(e){throw W(e,"EuropeVehicle.stopCharge")}}))}monthlyReport(){return h(this,arguments,void 0,(function*(e={year:(new Date).getFullYear(),month:(new Date).getMonth()+1}){var t,i,o,n,r,s,a,d,l,c,h;const u=yield this.controller.getVehicleHttpService();try{const v=null===(t=this.updateRates(yield u.post(`/api/v2/spa/vehicles/${this.vehicleConfig.id}/monthlyreport`,{body:{setRptMonth:le(e)}})).body.resMsg)||void 0===t?void 0:t.monthlyReport;return v?{start:null===(i=v.ifo)||void 0===i?void 0:i.mvrMonthStart,end:null===(o=v.ifo)||void 0===o?void 0:o.mvrMonthEnd,breakdown:v.breakdown,driving:v.driving?{distance:null===(n=v.driving)||void 0===n?void 0:n.runDistance,startCount:null===(r=v.driving)||void 0===r?void 0:r.engineStartCount,durations:{idle:null===(s=v.driving)||void 0===s?void 0:s.engineIdleTime,drive:null===(a=v.driving)||void 0===a?void 0:a.engineOnTime}}:void 0,vehicleStatus:v.vehicleStatus?{tpms:(null===(d=v.vehicleStatus)||void 0===d?void 0:d.tpmsSupport)?Boolean(null===(l=v.vehicleStatus)||void 0===l?void 0:l.tpmsSupport):void 0,tirePressure:{all:"1"==(null===(h=null===(c=v.vehicleStatus)||void 0===c?void 0:c.tirePressure)||void 0===h?void 0:h.tirePressureLampAll)}}:void 0}:void 0}catch(e){throw W(e,"EuropeVehicle.monthyReports")}}))}tripInfo(){return h(this,arguments,void 0,(function*(e={year:(new Date).getFullYear(),month:(new Date).getMonth()+1}){const t=yield this.controller.getApiHttpService();try{const i=Boolean(e.day),o=this.updateRates(yield t.post(`/api/v1/spa/vehicles/${this.vehicleConfig.id}/tripinfo`,{body:{setTripLatest:10,setTripMonth:i?void 0:le(e),setTripDay:i?ce(e):void 0,tripPeriodType:i?1:0}}));if(!i){const e=o.body.resMsg;return{days:Array.isArray(null==e?void 0:e.tripDayList)?null==e?void 0:e.tripDayList.map((e=>({dayRaw:e.tripDayInMonth,date:e.tripDayInMonth?ne(e.tripDayInMonth):void 0,tripsCount:e.tripCntDay}))):[],durations:{drive:null==e?void 0:e.tripDrvTime,idle:null==e?void 0:e.tripIdleTime},distance:null==e?void 0:e.tripDist,speed:{avg:null==e?void 0:e.tripAvgSpeed,max:null==e?void 0:e.tripMaxSpeed}}}{const e=o.body.resMsg.dayTripList;if(e&&Array.isArray(e))return e.map((e=>({dayRaw:e.tripDay,tripsCount:e.dayTripCnt,distance:e.tripDist,durations:{drive:e.tripDrvTime,idle:e.tripIdleTime},speed:{avg:e.tripAvgSpeed,max:e.tripMaxSpeed},trips:Array.isArray(e.tripList)?e.tripList.map((t=>{const i=ne(`${e.tripDay}${t.tripTime}`);return{timeRaw:t.tripTime,start:i,end:re(i,t.tripDrvTime),durations:{drive:t.tripDrvTime,idle:t.tripIdleTime},speed:{avg:t.tripAvgSpeed,max:t.tripMaxSpeed},distance:t.tripDist}})):[]})))}return}catch(e){throw W(e,"EuropeVehicle.history")}}))}driveHistory(){return h(this,arguments,void 0,(function*(e=se.DAY){var t,i;const o=yield this.controller.getApiHttpService();try{const n=yield o.post(`/api/v1/spa/vehicles/${this.vehicleConfig.id}/drvhistory`,{body:{periodTarget:e}});return{cumulated:null===(t=n.body.resMsg.drivingInfo)||void 0===t?void 0:t.map((e=>({period:e.drivingPeriod,consumption:{total:e.totalPwrCsp,engine:e.motorPwrCsp,climate:e.climatePwrCsp,devices:e.eDPwrCsp,battery:e.batteryMgPwrCsp},regen:e.regenPwr,distance:e.calculativeOdo}))),history:null===(i=n.body.resMsg.drivingInfoDetail)||void 0===i?void 0:i.map((e=>({period:e.drivingPeriod,rawDate:e.drivingDate,date:e.drivingDate?ne(e.drivingDate):void 0,consumption:{total:e.totalPwrCsp,engine:e.motorPwrCsp,climate:e.climatePwrCsp,devices:e.eDPwrCsp,battery:e.batteryMgPwrCsp},regen:e.regenPwr,distance:e.calculativeOdo})))}}catch(e){throw W(e,"EuropeVehicle.history")}}))}getChargeTargets(){return h(this,void 0,void 0,(function*(){var e;const t=yield this.controller.getVehicleHttpService();try{const i=null===(e=this.updateRates(yield t.get(`/api/v2/spa/vehicles/${this.vehicleConfig.id}/charge/target`)).body.resMsg)||void 0===e?void 0:e.targetSOClist;return i&&Array.isArray(i)?i.map((e=>{var t,i;return{distance:null===(i=null===(t=e.drvDistance)||void 0===t?void 0:t.distanceType)||void 0===i?void 0:i.distanceValue,targetLevel:e.targetSOClevel,type:e.plugType}})):void 0}catch(e){throw W(e,"EuropeVehicle.getChargeTargets")}}))}setChargeTargets(e){return h(this,void 0,void 0,(function*(){const t=yield this.controller.getVehicleHttpService();if(!N.includes(e.fast)||!N.includes(e.slow))throw new Y(`Charge target values are limited to ${N.join(", ")}`);try{this.updateRates(yield t.post(`/api/v2/spa/vehicles/${this.vehicleConfig.id}/charge/target`,{body:{targetSOClist:[{plugType:Q.FAST,targetSOClevel:e.fast},{plugType:Q.SLOW,targetSOClevel:e.slow}]}}))}catch(e){throw W(e,"EuropeVehicle.setChargeTargets")}}))}setNavigation(e){return h(this,void 0,void 0,(function*(){const t=yield this.controller.getVehicleHttpService();try{this.updateRates(yield t.post(`/api/v2/spa/vehicles/${this.vehicleConfig.id}/location/routes`,{body:{deviceID:this.controller.session.deviceId,poiInfoList:e}}))}catch(e){throw W(e,"EuropeVehicle.setNavigation")}}))}updateRates(e){var t,i,o,n,r;return(null===(t=e.headers)||void 0===t?void 0:t["x-ratelimit-limit"])&&(this.serverRates.max=Number(null===(i=e.headers)||void 0===i?void 0:i["x-ratelimit-limit"]),this.serverRates.current=Number(null===(o=e.headers)||void 0===o?void 0:o["x-ratelimit-remaining"]),(null===(n=e.headers)||void 0===n?void 0:n["x-ratelimit-reset"])&&(this.serverRates.reset=new Date(Number(`${null===(r=e.headers)||void 0===r?void 0:r["x-ratelimit-reset"]}000`))),this.serverRates.updatedAt=new Date),e}}function le(e){return`${e.year}${e.month.toString().padStart(2,"0")}`}function ce(e){return e.day?`${le(e)}${e.day.toString().padStart(2,"0")}`:le(e)}function he(t){return h(this,arguments,void 0,(function*(t,i="en",o){const n=null!=o?o:new r.CookieJar;return yield e(t.endpoints.session,{cookieJar:n}),yield e(t.endpoints.language,{method:"POST",body:`{"lang":"${i}"}`,cookieJar:n}),n}))}const ue={"User-Agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 11_1 like Mac OS X) AppleWebKit/604.3.5 (KHTML, like Gecko) Version/11.0 Mobile/15B92 Safari/604.1"},ve=e=>e.catch((e=>"HTTPError"===e.name&&302===e.statusCode?e.response:Promise.reject(e)));class pe{constructor(e,t){this.environment=e,this.language=t}get name(){return"EuropeanBrandAuthStrategy"}login(t,i){return h(this,void 0,void 0,(function*(){const o=yield he(this.environment,this.language,null==i?void 0:i.cookieJar),{body:{userId:r,serviceId:s}}=yield e(this.environment.endpoints.integration,{cookieJar:o,json:!0,headers:ue}),a=this.environment.brandAuthUrl({language:this.language,userId:r,serviceId:s}),d=n.parse(a,!0),{body:l}=yield e(a,{cookieJar:o,headers:ue}),c=/action="([a-z0-9:/\-.?_=&;]*)"/gi.exec(l),h=null==c?void 0:c[1].replace(/&/g,"&");if(!h)throw new Error("@EuropeanBrandAuthStrategy.login: cannot found the auth url from the form.");const u=new n.URLSearchParams;u.append("username",t.username),u.append("password",t.password),u.append("credentialId",""),u.append("rememberMe","on");const{headers:{location:v},body:p}=yield ve(e.post(h,{cookieJar:o,body:u.toString(),headers:Object.assign({"Content-Type":"application/x-www-form-urlencoded"},ue),followRedirect:!1}));if(!v){const e=/