@nativescript-community/perms
Advanced tools
Comparing version 2.3.5 to 2.3.6
@@ -1,3 +0,2 @@ | ||
import { CheckOptions, MultiResult, ObjectPermissions, ObjectPermissionsRest, Permissions as PermissionsType, RequestOptions } from '.'; | ||
import { Status } from './index.common'; | ||
import { CheckOptions, MultiResult, ObjectPermissions, ObjectPermissionsRest, Permissions as PermissionsType, RequestOptions, Status } from '.'; | ||
export * from './index.common'; | ||
@@ -8,6 +7,6 @@ export declare function canOpenSettings(): Promise<boolean>; | ||
export declare function getTypes(): PermissionsType[]; | ||
export declare function check(permission: PermissionsType | string, options?: CheckOptions): Promise<Status>; | ||
export declare function request(permission: PermissionsType | string | ObjectPermissions, options?: RequestOptions): Promise<Status | { | ||
export declare function check(permission: PermissionsType | string, options?: CheckOptions): Promise<[Status, boolean]>; | ||
export declare function request(permission: PermissionsType | string | ObjectPermissions, options?: RequestOptions): Promise<[Status, boolean] | { | ||
[permission: string]: Status; | ||
}>; | ||
export declare function checkMultiple<T extends Partial<ObjectPermissionsRest>>(permissions: T): Promise<MultiResult>; |
@@ -1,6 +0,14 @@ | ||
import { Application, Trace, Utils } from '@nativescript/core'; | ||
import { Trace, Utils } from '@nativescript/core'; | ||
import { AndroidApplication, Application, android as androidApp } from '@nativescript/core/application'; | ||
import { getBoolean, setBoolean } from '@nativescript/core/application-settings'; | ||
import { CLog, CLogTypes, Status } from './index.common'; | ||
import { CLog, CLogTypes } from './index.common'; | ||
import { SDK_VERSION } from '@nativescript/core/utils'; | ||
export * from './index.common'; | ||
let ANDROID_SDK = -1; | ||
function getAndroidSDK() { | ||
if (ANDROID_SDK === -1) { | ||
ANDROID_SDK = android.os.Build.VERSION.SDK_INT; | ||
} | ||
return ANDROID_SDK; | ||
} | ||
const MARSHMALLOW = 23; | ||
@@ -35,11 +43,15 @@ const ANDROIDQ = 29; | ||
const result = []; | ||
const theOptions = options; | ||
if ((theOptions?.coarse ?? true) !== false) { | ||
const coarse = options?.coarse ?? true; | ||
const precise = options?.precise ?? true; | ||
if (coarse !== false) { | ||
result.push('android.permission.ACCESS_COARSE_LOCATION'); | ||
} | ||
if ((theOptions?.precise ?? true) !== false) { | ||
if (precise !== false) { | ||
result.push('android.permission.ACCESS_FINE_LOCATION'); | ||
} | ||
if (SDK_VERSION >= ANDROIDQ && (theOptions?.background ?? false) === true) { | ||
result.push('android.permission.ACCESS_BACKGROUND_LOCATION'); | ||
if (getAndroidSDK() >= ANDROIDQ) { | ||
const type = typeof options === 'string' ? options : options?.type; | ||
if (type === 'always') { | ||
result.push('android.permission.ACCESS_BACKGROUND_LOCATION'); | ||
} | ||
} | ||
@@ -52,3 +64,3 @@ return result; | ||
case 'mediaLocation': { | ||
if (SDK_VERSION >= ANDROIDQ) { | ||
if (getAndroidSDK() >= ANDROIDQ) { | ||
return ['android.permission.ACCESS_MEDIA_LOCATION']; | ||
@@ -69,8 +81,9 @@ } | ||
const result = []; | ||
const theOptions = options; | ||
const read = options?.read ?? true; | ||
const write = options?.write ?? true; | ||
// const manage = options?.manage?? true; | ||
if ((theOptions?.read ?? true) !== false) { | ||
if (read !== false) { | ||
result.push('android.permission.READ_EXTERNAL_STORAGE'); | ||
} | ||
if ((theOptions?.write ?? true) !== false) { | ||
if (write !== false) { | ||
result.push('android.permission.WRITE_EXTERNAL_STORAGE'); | ||
@@ -84,3 +97,3 @@ } | ||
case 'photo': { | ||
if (SDK_VERSION >= ANDROID13) { | ||
if (getAndroidSDK() >= ANDROID13) { | ||
return ['android.permission.READ_MEDIA_IMAGES']; | ||
@@ -91,3 +104,3 @@ } | ||
case 'video': { | ||
if (SDK_VERSION >= ANDROID13) { | ||
if (getAndroidSDK() >= ANDROID13) { | ||
return ['android.permission.READ_MEDIA_VIDEO']; | ||
@@ -98,3 +111,3 @@ } | ||
case 'audio': { | ||
if (SDK_VERSION >= ANDROID13) { | ||
if (getAndroidSDK() >= ANDROID13) { | ||
return ['android.permission.READ_MEDIA_AUDIO']; | ||
@@ -114,3 +127,3 @@ } | ||
case 'bluetoothScan': { | ||
if (SDK_VERSION >= ANDROIDS) { | ||
if (getAndroidSDK() >= ANDROIDS) { | ||
return ['android.permission.BLUETOOTH_SCAN']; | ||
@@ -121,3 +134,3 @@ } | ||
case 'bluetoothConnect': { | ||
if (SDK_VERSION >= ANDROIDS) { | ||
if (getAndroidSDK() >= ANDROIDS) { | ||
return ['android.permission.BLUETOOTH_CONNECT']; | ||
@@ -128,3 +141,3 @@ } | ||
case 'bluetooth': { | ||
if (SDK_VERSION >= ANDROIDS) { | ||
if (getAndroidSDK() >= ANDROIDS) { | ||
return ['android.permission.BLUETOOTH_ADVERTISE']; | ||
@@ -135,3 +148,3 @@ } | ||
case 'notification': { | ||
if (SDK_VERSION >= ANDROID13) { | ||
if (getAndroidSDK() >= ANDROID13) { | ||
// @ts-ignore | ||
@@ -150,2 +163,8 @@ return ['android.permission.POST_NOTIFICATIONS']; | ||
const getDidAskOnce = (permission) => Promise.resolve(!!getBoolean(STORAGE_KEY + permission)); | ||
const GRANT_RESULTS = { | ||
UNDETERMINED: 'undetermined', | ||
GRANTED: 'authorized', | ||
DENIED: 'denied', | ||
NEVER_ASK_AGAIN: 'never_ask_again' | ||
}; | ||
var PermissionsAndroid; | ||
@@ -182,2 +201,3 @@ (function (PermissionsAndroid) { | ||
// }; | ||
PermissionsAndroid.RESULTS = GRANT_RESULTS; | ||
/** | ||
@@ -196,3 +216,3 @@ * Returns a promise resolving to a boolean value as to whether the specified | ||
} | ||
if (SDK_VERSION < MARSHMALLOW) { | ||
if (getAndroidSDK() < MARSHMALLOW) { | ||
permission.forEach((p) => (result = result && context.checkPermission(p, android.os.Process.myPid(), android.os.Process.myUid()) === granted)); | ||
@@ -248,9 +268,9 @@ } | ||
const perm = permissions[i]; | ||
if (SDK_VERSION < MARSHMALLOW) { | ||
if (getAndroidSDK() < MARSHMALLOW) { | ||
grantedPermissions[perm] = | ||
context.checkPermission(perm, android.os.Process.myPid(), android.os.Process.myUid()) === android.content.pm.PackageManager.PERMISSION_GRANTED ? Status.Authorized : Status.Denied; | ||
context.checkPermission(perm, android.os.Process.myPid(), android.os.Process.myUid()) === android.content.pm.PackageManager.PERMISSION_GRANTED ? 'authorized' : GRANT_RESULTS.DENIED; | ||
checkedPermissionsCount++; | ||
} | ||
else if (context.checkSelfPermission(perm) === android.content.pm.PackageManager.PERMISSION_GRANTED) { | ||
grantedPermissions[perm] = Status.Authorized; | ||
grantedPermissions[perm] = GRANT_RESULTS.GRANTED; | ||
checkedPermissionsCount++; | ||
@@ -265,3 +285,3 @@ } | ||
} | ||
const activity = Application.android.foregroundActivity || Application.android.startActivity; | ||
const activity = androidApp.foregroundActivity || androidApp.startActivity; | ||
return new Promise((resolve, reject) => { | ||
@@ -276,3 +296,3 @@ try { | ||
if (args.requestCode === requestCode) { | ||
Application.android.off(Application.android.activityRequestPermissionsEvent, onActivityResult); | ||
androidApp.off(AndroidApplication.activityRequestPermissionsEvent, onActivityResult); | ||
const results = args.grantResults; | ||
@@ -285,10 +305,10 @@ if (Trace.isEnabled()) { | ||
if (results.length > j && results[j] === android.content.pm.PackageManager.PERMISSION_GRANTED) { | ||
grantedPermissions[permission] = Status.Authorized; | ||
grantedPermissions[permission] = GRANT_RESULTS.GRANTED; | ||
} | ||
else { | ||
if (activity.shouldShowRequestPermissionRationale(permission)) { | ||
grantedPermissions[permission] = Status.Denied; | ||
grantedPermissions[permission] = GRANT_RESULTS.DENIED; | ||
} | ||
else { | ||
grantedPermissions[permission] = Status.NeverAskAgain; | ||
grantedPermissions[permission] = GRANT_RESULTS.NEVER_ASK_AGAIN; | ||
} | ||
@@ -300,3 +320,3 @@ } | ||
}; | ||
Application.android.on(Application.android.activityRequestPermissionsEvent, onActivityResult); | ||
androidApp.on(AndroidApplication.activityRequestPermissionsEvent, onActivityResult); | ||
} | ||
@@ -309,6 +329,6 @@ catch (e) { | ||
function shouldShowRequestPermissionRationale(permission) { | ||
if (SDK_VERSION < MARSHMALLOW) { | ||
if (getAndroidSDK() < MARSHMALLOW) { | ||
return Promise.resolve(false); | ||
} | ||
const activity = Application.android.foregroundActivity || Application.android.startActivity; | ||
const activity = androidApp.foregroundActivity || androidApp.startActivity; | ||
try { | ||
@@ -329,11 +349,11 @@ if (Array.isArray(permission)) { | ||
export function openSettings() { | ||
const activity = Application.android.foregroundActivity || Application.android.startActivity; | ||
const activity = androidApp.foregroundActivity || androidApp.startActivity; | ||
return new Promise((resolve, reject) => { | ||
const onActivityResultHandler = (data) => { | ||
if (data.requestCode === SETTINGS_REQUEST) { | ||
Application.android.off(Application.android.activityResultEvent, onActivityResultHandler); | ||
if (data.requestCode === 5140) { | ||
androidApp.off(AndroidApplication.activityResultEvent, onActivityResultHandler); | ||
resolve(); | ||
} | ||
}; | ||
Application.android.on(Application.android.activityResultEvent, onActivityResultHandler); | ||
androidApp.on(AndroidApplication.activityResultEvent, onActivityResultHandler); | ||
const intent = new android.content.Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS); | ||
@@ -375,23 +395,23 @@ intent.setData(android.net.Uri.parse('package:' + activity.getPackageName())); | ||
if (Trace.isEnabled()) { | ||
CLog(CLogTypes.info, 'check', permission, options, SDK_VERSION, perms); | ||
CLog(CLogTypes.info, 'check', permission, options, getAndroidSDK(), perms); | ||
} | ||
if (!perms || perms.length === 0) { | ||
return Status.Authorized; | ||
return [GRANT_RESULTS.GRANTED, true]; | ||
} | ||
const isAuthorized = await PermissionsAndroid.check(perms); | ||
if (isAuthorized) { | ||
if (SDK_VERSION >= ANDROIDQ && permission === 'location') { | ||
if (getAndroidSDK() >= ANDROIDQ && permission === 'location') { | ||
const type = typeof options === 'string' ? options : options && options.type; | ||
if (type === 'always') { | ||
const backAuthorized = await PermissionsAndroid.check('android.permission.ACCESS_BACKGROUND_LOCATION'); | ||
return backAuthorized ? Status.Authorized : Status.Denied; | ||
return [GRANT_RESULTS.GRANTED, backAuthorized]; | ||
} | ||
} | ||
return Status.Authorized; | ||
return [GRANT_RESULTS.GRANTED, true]; | ||
} | ||
return getDidAskOnce(permission).then((didAsk) => { | ||
if (didAsk) { | ||
return shouldShowRequestPermissionRationale(perms).then((shouldShow) => (shouldShow ? Status.Denied : Status.Restricted)); | ||
return shouldShowRequestPermissionRationale(perms).then((shouldShow) => [shouldShow ? GRANT_RESULTS.DENIED : 'restricted', true]); | ||
} | ||
return Status.Undetermined; | ||
return [GRANT_RESULTS.UNDETERMINED, true]; | ||
}); | ||
@@ -428,3 +448,3 @@ } | ||
// } | ||
return Promise.resolve(Status.Authorized); | ||
return Promise.resolve([GRANT_RESULTS.GRANTED, true]); | ||
} | ||
@@ -438,8 +458,8 @@ if (types.length > 1) { | ||
if (typeof result === 'boolean') { | ||
return result ? Status.Authorized : Status.Denied; | ||
return [result ? GRANT_RESULTS.GRANTED : GRANT_RESULTS.DENIED, true]; | ||
} | ||
if (permissions.length > 1) { | ||
return Promise.all(permissions.map(setDidAskOnce)).then(() => result); | ||
return Promise.all(permissions.map(setDidAskOnce)).then(() => [result, true]); | ||
} | ||
return setDidAskOnce(permissions[0]).then(() => result); | ||
return setDidAskOnce(permissions[0]).then(() => [result, true]); | ||
}); | ||
@@ -452,3 +472,3 @@ } | ||
return Promise.all(Object.keys(permissions).map((permission) => check(permission, permissions[permission]).then((r) => [permission, r]))).then((result) => result.reduce((acc, value, index) => { | ||
acc[value[0]] = value[1]; | ||
acc[value[0]] = value[1][0]; | ||
return acc; | ||
@@ -455,0 +475,0 @@ }, {})); |
@@ -1,11 +0,3 @@ | ||
import type { MultiResult } from '.'; | ||
import type { MultiResult, Result } from '.'; | ||
export declare const PermsTraceCategory = "NativescriptPerms"; | ||
export declare enum Status { | ||
Undetermined = "undetermined", | ||
Denied = "denied", | ||
Authorized = "authorized", | ||
Limited = "limited", | ||
Restricted = "restricted", | ||
NeverAskAgain = "never_ask_again" | ||
} | ||
export declare enum CLogTypes { | ||
@@ -18,2 +10,2 @@ log = 0, | ||
export declare const CLog: (type: CLogTypes, ...args: any[]) => void; | ||
export declare function isPermResultAuthorized(r: MultiResult | Status): boolean | Status; | ||
export declare function isPermResultAuthorized(r: MultiResult | Result): boolean; |
import { Trace } from '@nativescript/core'; | ||
export const PermsTraceCategory = 'NativescriptPerms'; | ||
export var Status; | ||
(function (Status) { | ||
Status["Undetermined"] = "undetermined"; | ||
Status["Denied"] = "denied"; | ||
Status["Authorized"] = "authorized"; | ||
Status["Limited"] = "limited"; | ||
Status["Restricted"] = "restricted"; | ||
Status["NeverAskAgain"] = "never_ask_again"; | ||
})(Status || (Status = {})); | ||
export var CLogTypes; | ||
@@ -23,8 +14,10 @@ (function (CLogTypes) { | ||
export function isPermResultAuthorized(r) { | ||
if (typeof r === 'object') { | ||
const unauthorized = Object.keys(r).some((s) => r[s] !== Status.Authorized); | ||
if (Array.isArray(r)) { | ||
return r[0] === 'authorized'; | ||
} | ||
else { | ||
const unauthorized = Object.keys(r).some((s) => r[s] !== 'authorized'); | ||
return !unauthorized; | ||
} | ||
return r; | ||
} | ||
//# sourceMappingURL=index.common.js.map |
/* eslint-disable @typescript-eslint/unified-signatures */ | ||
/* eslint-disable no-redeclare */ | ||
export type IStatus = 'authorized' | 'denied' | 'limited' | 'restricted' | 'undetermined' | 'never_ask_again'; | ||
export type Status = 'authorized' | 'denied' | 'limited' | 'restricted' | 'undetermined' | 'never_ask_again'; | ||
@@ -42,3 +42,2 @@ export * from './index.common'; | ||
precise?: boolean; | ||
background?: boolean; | ||
} | ||
@@ -73,12 +72,12 @@ export interface StorageOptions { | ||
export type Result = [Status, boolean]; | ||
export interface MultiResult { | ||
[k: Permissions | string]: Status; | ||
} | ||
export type Result<T> = T extends any[] ? MultipleResult : Status; | ||
export type RequestOptions<T extends Permissions = Permissions> = T extends keyof ObjectPermissions ? ObjectPermissions[T] : any; | ||
export function request<T extends Permissions>(permission: T, options?: RequestOptions<T>): Promise<Status>; | ||
export function request<T extends Permissions>(permission: T, options?: RequestOptions<T>): Promise<Result>; | ||
export function request<T extends Partial<ObjectPermissions | ObjectPermissionsRest>>(permission: T): Promise<MultiResult>; | ||
export function request<T extends string>(permission: T): Promise<Status>; | ||
export function request<T extends string>(permission: T): Promise<Result>; | ||
export function checkMultiple<T extends Partial<ObjectPermissionsRest>>(permissions: T): Promise<MultiResult>; |
@@ -1,5 +0,11 @@ | ||
import { CheckOptions, MultiResult, PermissionOptions, RequestOptions, Result } from '.'; | ||
import { Status } from './index.common'; | ||
import { CheckOptions, PermissionOptions, RequestOptions } from '.'; | ||
export * from './index.common'; | ||
export declare namespace PermissionsIOS { | ||
enum Status { | ||
Undetermined = "undetermined", | ||
Denied = "denied", | ||
Authorized = "authorized", | ||
Limited = "limited", | ||
Restricted = "restricted" | ||
} | ||
enum NSType { | ||
@@ -22,4 +28,4 @@ Location = "location", | ||
function canOpenSettings(): Promise<boolean>; | ||
function getPermissionStatus(type: any, json: any): Promise<Status>; | ||
function requestPermission(type: any, json: any): Promise<Status>; | ||
function getPermissionStatus(type: any, json: any): Promise<[Status, boolean]>; | ||
function requestPermission(type: any, json: any): Promise<[Status, boolean]>; | ||
} | ||
@@ -34,4 +40,9 @@ type IOSPermissionTypes = `${PermissionsIOS.NSType}`; | ||
export declare function getTypes(): ("location" | "camera" | "microphone" | "photo" | "contacts" | "event" | "reminder" | "bluetooth" | "notification" | "backgroundRefresh" | "speechRecognition" | "mediaLibrary" | "motion")[]; | ||
export declare function check(permission: IOSPermissionTypes, options?: CheckOptions): Promise<Status>; | ||
type SingleResult = [PermissionsIOS.Status, boolean]; | ||
interface MultipleResult { | ||
[k: string]: PermissionsIOS.Status; | ||
} | ||
type Result<T> = T extends any[] ? MultipleResult : SingleResult; | ||
export declare function check(permission: IOSPermissionTypes, options?: CheckOptions): Promise<SingleResult>; | ||
export declare function request<T extends IOSPermissionTypes | Record<IOSPermissionTypes, any>>(permission: T, options?: RequestOptions): Promise<Result<T>>; | ||
export declare function checkMultiple<T extends Partial<ObjectIOSPermissionsRest>>(permissions: T): Promise<MultiResult>; | ||
export declare function checkMultiple<T extends Partial<ObjectIOSPermissionsRest>>(permissions: T): Promise<MultipleResult>; |
import { Application, Device, Trace, Utils } from '@nativescript/core'; | ||
import { CLog, CLogTypes, Status } from './index.common'; | ||
import { CLog, CLogTypes } from './index.common'; | ||
export * from './index.common'; | ||
export var PermissionsIOS; | ||
(function (PermissionsIOS) { | ||
let Status; | ||
(function (Status) { | ||
Status["Undetermined"] = "undetermined"; | ||
Status["Denied"] = "denied"; | ||
Status["Authorized"] = "authorized"; | ||
Status["Limited"] = "limited"; | ||
Status["Restricted"] = "restricted"; | ||
})(Status = PermissionsIOS.Status || (PermissionsIOS.Status = {})); | ||
let NSPLocation; | ||
@@ -10,4 +18,6 @@ (function (NSPLocation) { | ||
function getStatusFromCLAuthorizationStatus(lStatus, type) { | ||
let always = false; | ||
switch (lStatus) { | ||
case 3 /* CLAuthorizationStatus.kCLAuthorizationStatusAuthorizedAlways */: | ||
always = true; | ||
status = Status.Authorized; | ||
@@ -28,5 +38,5 @@ break; | ||
if (Trace.isEnabled()) { | ||
CLog(CLogTypes.info, 'NSPLocation getStatusFromCLAuthorizationStatus', lStatus, type, status); | ||
CLog(CLogTypes.info, 'NSPLocation getStatusFromCLAuthorizationStatus', lStatus, type, status, always); | ||
} | ||
return status; | ||
return [status, always]; | ||
} | ||
@@ -156,3 +166,3 @@ function getStatusForType(type) { | ||
} | ||
return status; | ||
return [status, true]; | ||
} | ||
@@ -258,3 +268,3 @@ NSPBluetooth.getStatus = getStatus; | ||
} | ||
return status; | ||
return [status, true]; | ||
} | ||
@@ -287,3 +297,3 @@ NSPAudioVideo.getStatus = getStatus; | ||
} | ||
return status; | ||
return [status, true]; | ||
} | ||
@@ -325,3 +335,3 @@ NSPSpeechRecognition.getStatus = getStatus; | ||
} | ||
return status; | ||
return [status, true]; | ||
} | ||
@@ -354,3 +364,3 @@ NSPPhoto.getStatus = getStatus; | ||
} | ||
return status; | ||
return [status, true]; | ||
} | ||
@@ -407,3 +417,3 @@ NSPMotion.getStatus = getStatus; | ||
} | ||
return status; | ||
return [status, true]; | ||
} | ||
@@ -439,3 +449,3 @@ NSPMediaLibrary.getStatus = getStatus; | ||
} | ||
return status; | ||
return [status, true]; | ||
} | ||
@@ -496,3 +506,3 @@ NSPNotification.getStatus = getStatus; | ||
} | ||
return status; | ||
return [status, true]; | ||
} | ||
@@ -526,3 +536,3 @@ NSPContacts.getStatus = getStatus; | ||
} | ||
return status; | ||
return [status, true]; | ||
} | ||
@@ -533,3 +543,3 @@ NSPBackgroundRefresh.getStatus = getStatus; | ||
const contactStore = CNContactStore.new(); | ||
contactStore.requestAccessForEntityTypeCompletionHandler(0 /* CNEntityType.Contacts */, () => resolve(getStatus())); | ||
contactStore.requestAccessForEntityTypeCompletionHandler(0 /* CNEntityType.Contacts */, () => resolve(getStatus()[0])); | ||
}); | ||
@@ -565,3 +575,3 @@ } | ||
} | ||
return status; | ||
return [status, true]; | ||
} | ||
@@ -791,3 +801,3 @@ NSPEvent.getStatus = getStatus; | ||
} | ||
return Status.Authorized; | ||
return [PermissionsIOS.Status.Authorized, true]; | ||
} | ||
@@ -813,3 +823,3 @@ let type; | ||
const res = await request(perm, permission[perm]); | ||
grantedPermissions[perm] = res; | ||
grantedPermissions[perm] = res[0]; | ||
} | ||
@@ -823,3 +833,4 @@ //@ts-ignore | ||
} | ||
return Status.Authorized; | ||
//@ts-ignore | ||
return [PermissionsIOS.Status.Authorized, true]; | ||
} | ||
@@ -845,3 +856,3 @@ //@ts-ignore | ||
return Promise.all(Object.keys(permissions).map((permission) => check(permission, permissions[permission]).then((r) => [permission, r]))).then((result) => result.reduce((acc, value, index) => { | ||
acc[value[0]] = value[1]; | ||
acc[value[0]] = value[1][0]; | ||
return acc; | ||
@@ -848,0 +859,0 @@ }, {})); |
{ | ||
"name": "@nativescript-community/perms", | ||
"version": "2.3.5", | ||
"version": "2.3.6", | ||
"description": "An unified permissions API for NativeScript on iOS and Android.", | ||
@@ -42,3 +42,3 @@ "main": "./index", | ||
"readmeFilename": "README.md", | ||
"gitHead": "f356007b7680af2cd56f35dc03480f24cb2bb2cc" | ||
"gitHead": "c1ea28edd02254af7266f4bb06c379c22ec620c9" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
126998
1466