1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-14 15:23:33 +00:00

edge hates for of loops :(

This commit is contained in:
Kyle Spearrin
2017-11-16 12:49:23 -05:00
parent cc5c7fb879
commit f9b00c6871
11 changed files with 99 additions and 93 deletions

View File

@@ -62,16 +62,16 @@ class CipherData {
if (response.data.Fields != null) { if (response.data.Fields != null) {
this.fields = []; this.fields = [];
for (const field of response.data.Fields) { response.data.Fields.forEach((field: any) => {
this.fields.push(new FieldData(field)); this.fields.push(new FieldData(field));
} });
} }
if (response.attachments != null) { if (response.attachments != null) {
this.attachments = []; this.attachments = [];
for (const attachment of response.attachments) { response.attachments.forEach((attachment) => {
this.attachments.push(new AttachmentData(attachment)); this.attachments.push(new AttachmentData(attachment));
} });
} }
} }
} }

View File

@@ -9,9 +9,9 @@ class DomainsResponse {
this.globalEquivalentDomains = []; this.globalEquivalentDomains = [];
if (response.GlobalEquivalentDomains) { if (response.GlobalEquivalentDomains) {
for (const domain of response.GlobalEquivalentDomains) { response.GlobalEquivalentDomains.forEach((domain: any) => {
this.globalEquivalentDomains.push(new GlobalDomainResponse(domain)); this.globalEquivalentDomains.push(new GlobalDomainResponse(domain));
} });
} }
} }
} }

View File

@@ -28,9 +28,9 @@ class ProfileResponse {
this.securityStamp = response.SecurityStamp; this.securityStamp = response.SecurityStamp;
if (response.Organizations) { if (response.Organizations) {
for (const org of response.Organizations) { response.Organizations.forEach((org: any) => {
this.organizations.push(new ProfileOrganizationResponse(org)); this.organizations.push(new ProfileOrganizationResponse(org));
} });
} }
} }
} }

View File

@@ -15,15 +15,15 @@ class SyncResponse {
} }
if (response.Folders) { if (response.Folders) {
for (const folder of response.Folders) { response.Folders.forEach((folder: any) => {
this.folders.push(new FolderResponse(folder)); this.folders.push(new FolderResponse(folder));
} });
} }
if (response.Ciphers) { if (response.Ciphers) {
for (const cipher of response.Ciphers) { response.Ciphers.forEach((cipher: any) => {
this.ciphers.push(new CipherResponse(cipher)); this.ciphers.push(new CipherResponse(cipher));
} });
} }
if (response.Domains) { if (response.Domains) {

View File

@@ -104,7 +104,8 @@ export default class AutofillService {
continue; continue;
} }
for (const pf of passwordFields) { for (let i = 0; i < passwordFields.length; i++) {
const pf = passwordFields[i];
if (formKey !== pf.form) { if (formKey !== pf.form) {
continue; continue;
} }
@@ -135,10 +136,10 @@ export default class AutofillService {
} }
let didAutofill = false; let didAutofill = false;
for (const pd of options.pageDetails) { options.pageDetails.forEach((pd: any) => {
// make sure we're still on correct tab // make sure we're still on correct tab
if (pd.tab.id !== tab.id || pd.tab.url !== tab.url) { if (pd.tab.id !== tab.id || pd.tab.url !== tab.url) {
continue; return;
} }
const fillScript = this.generateFillScript(pd.details, { const fillScript = this.generateFillScript(pd.details, {
@@ -147,7 +148,7 @@ export default class AutofillService {
}); });
if (!fillScript || !fillScript.script || !fillScript.script.length) { if (!fillScript || !fillScript.script || !fillScript.script.length) {
continue; return;
} }
didAutofill = true; didAutofill = true;
@@ -164,7 +165,7 @@ export default class AutofillService {
if (options.cipher.type !== CipherType.Login || totpPromise || if (options.cipher.type !== CipherType.Login || totpPromise ||
(options.fromBackground && this.utilsService.isFirefox()) || options.skipTotp || (options.fromBackground && this.utilsService.isFirefox()) || options.skipTotp ||
!options.cipher.login.totp || !this.tokenService.getPremium()) { !options.cipher.login.totp || !this.tokenService.getPremium()) {
continue; return;
} }
totpPromise = this.totpService.isAutoCopyEnabled().then((enabled) => { totpPromise = this.totpService.isAutoCopyEnabled().then((enabled) => {
@@ -180,7 +181,7 @@ export default class AutofillService {
return code; return code;
}); });
} });
if (didAutofill) { if (didAutofill) {
if (totpPromise != null) { if (totpPromise != null) {
@@ -248,17 +249,17 @@ export default class AutofillService {
if (fields && fields.length) { if (fields && fields.length) {
const fieldNames: string[] = []; const fieldNames: string[] = [];
for (const f of fields) { fields.forEach((f: any) => {
if (f.name && f.name !== '') { if (f.name && f.name !== '') {
fieldNames.push(f.name.toLowerCase()); fieldNames.push(f.name.toLowerCase());
} else { } else {
fieldNames.push(null); fieldNames.push(null);
} }
} });
for (const field of pageDetails.fields) { pageDetails.fields.forEach((field: any) => {
if (filledFields.hasOwnProperty(field.opid) || !field.viewable) { if (filledFields.hasOwnProperty(field.opid) || !field.viewable) {
continue; return;
} }
const matchingIndex = this.findMatchingFieldIndex(field, fieldNames); const matchingIndex = this.findMatchingFieldIndex(field, fieldNames);
@@ -267,7 +268,7 @@ export default class AutofillService {
fillScript.script.push(['click_on_opid', field.opid]); fillScript.script.push(['click_on_opid', field.opid]);
fillScript.script.push(['fill_by_opid', field.opid, fields[matchingIndex].value]); fillScript.script.push(['fill_by_opid', field.opid, fields[matchingIndex].value]);
} }
} });
} }
switch (options.cipher.type) { switch (options.cipher.type) {
@@ -318,13 +319,13 @@ export default class AutofillService {
} }
const passwordFieldsForForm: AutofillField[] = []; const passwordFieldsForForm: AutofillField[] = [];
for (const passField of passwordFields) { passwordFields.forEach((passField) => {
if (formKey === passField.form) { if (formKey === passField.form) {
passwordFieldsForForm.push(passField); passwordFieldsForForm.push(passField);
} }
} });
for (const passField of passwordFields) { passwordFields.forEach((passField) => {
pf = passField; pf = passField;
passwords.push(pf); passwords.push(pf);
@@ -340,7 +341,7 @@ export default class AutofillService {
usernames.push(username); usernames.push(username);
} }
} }
} });
} }
if (passwordFields.length && !passwords.length) { if (passwordFields.length && !passwords.length) {
@@ -366,33 +367,33 @@ export default class AutofillService {
if (!passwordFields.length && !options.skipUsernameOnlyFill) { if (!passwordFields.length && !options.skipUsernameOnlyFill) {
// No password fields on this page. Let's try to just fuzzy fill the username. // No password fields on this page. Let's try to just fuzzy fill the username.
for (const f of pageDetails.fields) { pageDetails.fields.forEach((f: any) => {
if (f.viewable && (f.type === 'text' || f.type === 'email' || f.type === 'tel') && if (f.viewable && (f.type === 'text' || f.type === 'email' || f.type === 'tel') &&
this.fieldIsFuzzyMatch(f, UsernameFieldNames)) { this.fieldIsFuzzyMatch(f, UsernameFieldNames)) {
usernames.push(f); usernames.push(f);
} }
} });
} }
for (const u of usernames) { usernames.forEach((u) => {
if (filledFields.hasOwnProperty(u.opid)) { if (filledFields.hasOwnProperty(u.opid)) {
continue; return;
} }
filledFields[u.opid] = u; filledFields[u.opid] = u;
fillScript.script.push(['click_on_opid', u.opid]); fillScript.script.push(['click_on_opid', u.opid]);
fillScript.script.push(['fill_by_opid', u.opid, login.username]); fillScript.script.push(['fill_by_opid', u.opid, login.username]);
} });
for (const p of passwords) { passwords.forEach((p) => {
if (filledFields.hasOwnProperty(p.opid)) { if (filledFields.hasOwnProperty(p.opid)) {
continue; return;
} }
filledFields[p.opid] = p; filledFields[p.opid] = p;
fillScript.script.push(['click_on_opid', p.opid]); fillScript.script.push(['click_on_opid', p.opid]);
fillScript.script.push(['fill_by_opid', p.opid, login.password]); fillScript.script.push(['fill_by_opid', p.opid, login.password]);
} });
fillScript = this.setFillScriptForFocus(filledFields, fillScript); fillScript = this.setFillScriptForFocus(filledFields, fillScript);
return fillScript; return fillScript;
@@ -407,10 +408,10 @@ export default class AutofillService {
const fillFields: { [id: string]: AutofillField; } = {}; const fillFields: { [id: string]: AutofillField; } = {};
for (const f of pageDetails.fields) { pageDetails.fields.forEach((f: any) => {
for (const attr of CardAttributes) { CardAttributes.forEach((attr) => {
if (!f.hasOwnProperty(attr) || !f[attr] || !f.viewable) { if (!f.hasOwnProperty(attr) || !f[attr] || !f.viewable) {
continue; return;
} }
// ref https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill // ref https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill
@@ -446,8 +447,8 @@ export default class AutofillService {
['cc-type', 'card-type', 'card-brand', 'cc-brand'])) { ['cc-type', 'card-type', 'card-brand', 'cc-brand'])) {
fillFields.brand = f; fillFields.brand = f;
} }
} });
} });
const card = options.cipher.card; const card = options.cipher.card;
this.makeScriptAction(fillScript, card, fillFields, filledFields, 'cardholderName'); this.makeScriptAction(fillScript, card, fillFields, filledFields, 'cardholderName');
@@ -481,10 +482,10 @@ export default class AutofillService {
const fillFields: { [id: string]: AutofillField; } = {}; const fillFields: { [id: string]: AutofillField; } = {};
for (const f of pageDetails.fields) { pageDetails.fields.forEach((f: any) => {
for (const attr of IdentityAttributes) { IdentityAttributes.forEach((attr) => {
if (!f.hasOwnProperty(attr) || !f[attr] || !f.viewable) { if (!f.hasOwnProperty(attr) || !f[attr] || !f.viewable) {
continue; return;
} }
// ref https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill // ref https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#autofill
@@ -544,8 +545,8 @@ export default class AutofillService {
['company', 'company-name', 'organization', 'organization-name'])) { ['company', 'company-name', 'organization', 'organization-name'])) {
fillFields.company = f; fillFields.company = f;
} }
} });
} });
const identity = options.cipher.identity; const identity = options.cipher.identity;
this.makeScriptAction(fillScript, identity, fillFields, filledFields, 'title'); this.makeScriptAction(fillScript, identity, fillFields, filledFields, 'title');
@@ -645,7 +646,8 @@ export default class AutofillService {
private isFieldMatch(value: string, options: string[], containsOptions?: string[]): boolean { private isFieldMatch(value: string, options: string[], containsOptions?: string[]): boolean {
value = value.trim().toLowerCase().replace(/[^a-zA-Z]+/g, ''); value = value.trim().toLowerCase().replace(/[^a-zA-Z]+/g, '');
for (let option of options) { for (let i = 0; i < options.length; i++) {
let option = options[i];
const checkValueContains = containsOptions == null || containsOptions.indexOf(option) > -1; const checkValueContains = containsOptions == null || containsOptions.indexOf(option) > -1;
option = option.replace(/-/g, ''); option = option.replace(/-/g, '');
if (value === option || (checkValueContains && value.indexOf(option) > -1)) { if (value === option || (checkValueContains && value.indexOf(option) > -1)) {
@@ -669,11 +671,11 @@ export default class AutofillService {
private loadPasswordFields(pageDetails: AutofillPageDetails, canBeHidden: boolean) { private loadPasswordFields(pageDetails: AutofillPageDetails, canBeHidden: boolean) {
const arr: AutofillField[] = []; const arr: AutofillField[] = [];
for (const f of pageDetails.fields) { pageDetails.fields.forEach((f: any) => {
if (f.type === 'password' && (canBeHidden || f.viewable)) { if (f.type === 'password' && (canBeHidden || f.viewable)) {
arr.push(f); arr.push(f);
} }
} });
return arr; return arr;
} }
@@ -681,7 +683,8 @@ export default class AutofillService {
private findUsernameField(pageDetails: AutofillPageDetails, passwordField: AutofillField, canBeHidden: boolean, private findUsernameField(pageDetails: AutofillPageDetails, passwordField: AutofillField, canBeHidden: boolean,
withoutForm: boolean) { withoutForm: boolean) {
let usernameField: AutofillField = null; let usernameField: AutofillField = null;
for (const f of pageDetails.fields) { for (let i = 0; i < pageDetails.fields.length; i++) {
const f = pageDetails.fields[i];
if (f.elementNumber >= passwordField.elementNumber) { if (f.elementNumber >= passwordField.elementNumber) {
break; break;
} }
@@ -738,7 +741,8 @@ export default class AutofillService {
const csvParts = name.split('=', 2); const csvParts = name.split('=', 2);
if (csvParts.length === 2) { if (csvParts.length === 2) {
const csvVals = csvParts[1].split(','); const csvVals = csvParts[1].split(',');
for (const val of csvVals) { for (let i = 0; i < csvVals.length; i++) {
const val = csvVals[i];
if (val != null && val.trim().toLowerCase() === fieldVal.toLowerCase()) { if (val != null && val.trim().toLowerCase() === fieldVal.toLowerCase()) {
return true; return true;
} }
@@ -774,8 +778,8 @@ export default class AutofillService {
return false; return false;
} }
for (const o of options) { for (let i = 0; i < options.length; i++) {
if (value.indexOf(o) > -1) { if (value.indexOf(options[i]) > -1) {
return true; return true;
} }
} }

View File

@@ -165,13 +165,13 @@ export default class CipherService {
throw new Error('No key.'); throw new Error('No key.');
} }
const promises = []; const promises: any[] = [];
const ciphers = await this.getAll(); const ciphers = await this.getAll();
for (const cipher of ciphers) { ciphers.forEach((cipher) => {
promises.push(cipher.decrypt().then((c: any) => { promises.push(cipher.decrypt().then((c: any) => {
decCiphers.push(c); decCiphers.push(c);
})); }));
} });
await Promise.all(promises); await Promise.all(promises);
this.decryptedCipherCache = decCiphers; this.decryptedCipherCache = decCiphers;
@@ -180,13 +180,13 @@ export default class CipherService {
async getAllDecryptedForFolder(folderId: string): Promise<any[]> { async getAllDecryptedForFolder(folderId: string): Promise<any[]> {
const ciphers = await this.getAllDecrypted(); const ciphers = await this.getAllDecrypted();
const ciphersToReturn = []; const ciphersToReturn: any[] = [];
for (const cipher of ciphers) { ciphers.forEach((cipher) => {
if (cipher.folderId === folderId) { if (cipher.folderId === folderId) {
ciphersToReturn.push(cipher); ciphersToReturn.push(cipher);
} }
} });
return ciphersToReturn; return ciphersToReturn;
} }
@@ -199,11 +199,11 @@ export default class CipherService {
const eqDomainsPromise = domain == null ? Promise.resolve([]) : const eqDomainsPromise = domain == null ? Promise.resolve([]) :
this.settingsService.getEquivalentDomains().then((eqDomains: any[][]) => { this.settingsService.getEquivalentDomains().then((eqDomains: any[][]) => {
let matches: any[] = []; let matches: any[] = [];
for (const eqDomain of eqDomains) { eqDomains.forEach((eqDomain) => {
if (eqDomain.length && eqDomain.indexOf(domain) >= 0) { if (eqDomain.length && eqDomain.indexOf(domain) >= 0) {
matches = matches.concat(eqDomain); matches = matches.concat(eqDomain);
} }
} });
if (!matches.length) { if (!matches.length) {
matches.push(domain); matches.push(domain);
@@ -215,16 +215,16 @@ export default class CipherService {
const result = await Promise.all([eqDomainsPromise, this.getAllDecrypted()]); const result = await Promise.all([eqDomainsPromise, this.getAllDecrypted()]);
const matchingDomains = result[0]; const matchingDomains = result[0];
const ciphers = result[1]; const ciphers = result[1];
const ciphersToReturn = []; const ciphersToReturn: any[] = [];
for (const cipher of ciphers) { ciphers.forEach((cipher) => {
if (domain && cipher.type === CipherType.Login && cipher.login.domain && if (domain && cipher.type === CipherType.Login && cipher.login.domain &&
matchingDomains.indexOf(cipher.login.domain) > -1) { matchingDomains.indexOf(cipher.login.domain) > -1) {
ciphersToReturn.push(cipher); ciphersToReturn.push(cipher);
} else if (includeOtherTypes && includeOtherTypes.indexOf(cipher.type) > -1) { } else if (includeOtherTypes && includeOtherTypes.indexOf(cipher.type) > -1) {
ciphersToReturn.push(cipher); ciphersToReturn.push(cipher);
} }
} });
return ciphersToReturn; return ciphersToReturn;
} }
@@ -259,7 +259,8 @@ export default class CipherService {
return; return;
} }
for (const cached of this.decryptedCipherCache) { for (let i = 0; i < this.decryptedCipherCache.length; i++) {
const cached = this.decryptedCipherCache[i];
if (cached.id === id) { if (cached.id === id) {
cached.localData = ciphersLocalData[id]; cached.localData = ciphersLocalData[id];
break; break;
@@ -345,9 +346,9 @@ export default class CipherService {
const c = cipher as CipherData; const c = cipher as CipherData;
ciphers[c.id] = c; ciphers[c.id] = c;
} else { } else {
for (const c of (cipher as CipherData[])) { (cipher as CipherData[]).forEach((c) => {
ciphers[c.id] = c; ciphers[c.id] = c;
} });
} }
await UtilsService.saveObjToStorage(Keys.ciphersPrefix + userId, ciphers); await UtilsService.saveObjToStorage(Keys.ciphersPrefix + userId, ciphers);
@@ -377,9 +378,9 @@ export default class CipherService {
const i = id as string; const i = id as string;
delete ciphers[id]; delete ciphers[id];
} else { } else {
for (const i of (id as string[])) { (id as string[]).forEach((i) => {
delete ciphers[i]; delete ciphers[i];
} });
} }
await UtilsService.saveObjToStorage(Keys.ciphersPrefix + userId, ciphers); await UtilsService.saveObjToStorage(Keys.ciphersPrefix + userId, ciphers);

View File

@@ -74,9 +74,9 @@ export default class CryptoService implements CryptoServiceInterface {
setOrgKeys(orgs: ProfileOrganizationResponse[]): Promise<{}> { setOrgKeys(orgs: ProfileOrganizationResponse[]): Promise<{}> {
const orgKeys: any = {}; const orgKeys: any = {};
for (const org of orgs) { orgs.forEach((org) => {
orgKeys[org.id] = org.key; orgKeys[org.id] = org.key;
} });
return UtilsService.saveObjToStorage(Keys.encOrgKeys, orgKeys); return UtilsService.saveObjToStorage(Keys.encOrgKeys, orgKeys);
} }

View File

@@ -20,7 +20,7 @@ export default class FolderService {
decryptedFolderCache: any[]; decryptedFolderCache: any[];
constructor(private cryptoService: CryptoService, private userService: UserService, constructor(private cryptoService: CryptoService, private userService: UserService,
private i18nService: any, private apiService: ApiService) { private i18nService: any, private apiService: ApiService) {
} }
clearCache(): void { clearCache(): void {
@@ -73,13 +73,13 @@ export default class FolderService {
throw new Error('No key.'); throw new Error('No key.');
} }
const promises = []; const promises: Array<Promise<any>> = [];
const folders = await this.getAll(); const folders = await this.getAll();
for (const folder of folders) { folders.forEach((folder) => {
promises.push(folder.decrypt().then((f: any) => { promises.push(folder.decrypt().then((f: any) => {
decFolders.push(f); decFolders.push(f);
})); }));
} });
await Promise.all(promises); await Promise.all(promises);
this.decryptedFolderCache = decFolders; this.decryptedFolderCache = decFolders;
@@ -114,9 +114,9 @@ export default class FolderService {
const f = folder as FolderData; const f = folder as FolderData;
folders[f.id] = f; folders[f.id] = f;
} else { } else {
for (const f of (folder as FolderData[])) { (folder as FolderData[]).forEach((f) => {
folders[f.id] = f; folders[f.id] = f;
} });
} }
await UtilsService.saveObjToStorage(Keys.foldersPrefix + userId, folders); await UtilsService.saveObjToStorage(Keys.foldersPrefix + userId, folders);
@@ -146,9 +146,9 @@ export default class FolderService {
const i = id as string; const i = id as string;
delete folders[id]; delete folders[id];
} else { } else {
for (const i of (id as string[])) { (id as string[]).forEach((i) => {
delete folders[i]; delete folders[i];
} });
} }
await UtilsService.saveObjToStorage(Keys.foldersPrefix + userId, folders); await UtilsService.saveObjToStorage(Keys.foldersPrefix + userId, folders);

View File

@@ -23,9 +23,9 @@ export default class SyncService {
syncInProgress: boolean = false; syncInProgress: boolean = false;
constructor(private userService: UserService, private apiService: ApiService, constructor(private userService: UserService, private apiService: ApiService,
private settingsService: SettingsService, private folderService: FolderService, private settingsService: SettingsService, private folderService: FolderService,
private cipherService: CipherService, private cryptoService: CryptoService, private cipherService: CipherService, private cryptoService: CryptoService,
private logoutCallback: Function) { private logoutCallback: Function) {
} }
async getLastSync() { async getLastSync() {
@@ -135,17 +135,17 @@ export default class SyncService {
private async syncFolders(userId: string, response: FolderResponse[]) { private async syncFolders(userId: string, response: FolderResponse[]) {
const folders: { [id: string]: FolderData; } = {}; const folders: { [id: string]: FolderData; } = {};
for (const f of response) { response.forEach((f) => {
folders[f.id] = new FolderData(f, userId); folders[f.id] = new FolderData(f, userId);
} });
return await this.folderService.replace(folders); return await this.folderService.replace(folders);
} }
private async syncCiphers(userId: string, response: CipherResponse[]) { private async syncCiphers(userId: string, response: CipherResponse[]) {
const ciphers: { [id: string]: CipherData; } = {}; const ciphers: { [id: string]: CipherData; } = {};
for (const c of response) { response.forEach((c) => {
ciphers[c.id] = new CipherData(c, userId); ciphers[c.id] = new CipherData(c, userId);
} });
return await this.cipherService.replace(ciphers); return await this.cipherService.replace(ciphers);
} }
@@ -156,11 +156,11 @@ export default class SyncService {
} }
if (response != null && response.globalEquivalentDomains != null) { if (response != null && response.globalEquivalentDomains != null) {
for (const global of response.globalEquivalentDomains) { response.globalEquivalentDomains.forEach((global) => {
if (global.domains.length > 0) { if (global.domains.length > 0) {
eqDomains.push(global.domains); eqDomains.push(global.domains);
} }
} });
} }
return this.settingsService.setEquivalentDomains(eqDomains); return this.settingsService.setEquivalentDomains(eqDomains);

View File

@@ -62,13 +62,13 @@ export default class TotpService {
private buff2hex(buff: ArrayBuffer): string { private buff2hex(buff: ArrayBuffer): string {
const bytes = new Uint8Array(buff); const bytes = new Uint8Array(buff);
const hex = []; const hex: string[] = [];
for (const b of bytes) { bytes.forEach((b) => {
// tslint:disable-next-line // tslint:disable-next-line
hex.push((b >>> 4).toString(16)); hex.push((b >>> 4).toString(16));
// tslint:disable-next-line // tslint:disable-next-line
hex.push((b & 0xF).toString(16)); hex.push((b & 0xF).toString(16));
} });
return hex.join(''); return hex.join('');
} }
@@ -76,12 +76,12 @@ export default class TotpService {
s = s.toUpperCase(); s = s.toUpperCase();
let cleanedInput = ''; let cleanedInput = '';
for (const c of s) { for (let i = 0; i < s.length; i++) {
if (b32Chars.indexOf(c) < 0) { if (b32Chars.indexOf(s[i]) < 0) {
continue; continue;
} }
cleanedInput += c; cleanedInput += s[i];
} }
s = cleanedInput; s = cleanedInput;

View File

@@ -36,6 +36,7 @@
], ],
"no-empty": [ true, "allow-empty-catch" ], "no-empty": [ true, "allow-empty-catch" ],
"object-literal-sort-keys": false, "object-literal-sort-keys": false,
"prefer-for-of": false,
"quotemark": [ true, "single" ], "quotemark": [ true, "single" ],
"whitespace": [ "whitespace": [
true, true,