@arcware-cloud/pixelstreaming-websdk 1.2.16 → 1.2.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -0
- package/index.cjs.js +147 -78
- package/index.esm.js +170 -99
- package/index.umd.js +147 -78
- package/package.json +2 -2
- package/types/index.d.ts +3 -0
- package/types/lib/ApplyUrlHack.d.ts +2 -0
- package/types/lib/ArcwareApplication.d.ts +48 -0
- package/types/lib/ArcwareConfig.d.ts +35 -0
- package/types/lib/ArcwareInit.d.ts +15 -0
- package/types/lib/ArcwarePixelStreaming.d.ts +98 -0
- package/types/lib/DiagnosticsCollector.d.ts +181 -0
- package/types/lib/MessageTypes.d.ts +4 -0
- package/types/lib/domain/ArcwareSettingsSchema.d.ts +209 -0
- package/types/lib/domain/ConnectionIdentifier.d.ts +27 -0
- package/types/lib/domain/EventHandler.d.ts +11 -0
- package/types/lib/domain/Session.d.ts +29 -0
- package/types/lib/domain/Stats.d.ts +36 -0
- package/types/lib/domain/debounce.d.ts +1 -0
- package/types/lib/index.d.ts +6 -0
- package/types/lib/styles/ArcwarePixelStreamingApplicationStyles.d.ts +478 -0
- package/types/lib/ui/ArcwareLogoLoader/index.d.ts +6 -0
- package/types/lib/ui/AudioButton/AudioIcon.d.ts +7 -0
- package/types/lib/ui/AudioButton/index.d.ts +15 -0
- package/types/lib/ui/LoveLetters/index.d.ts +6 -0
- package/types/lib/ui/MicButton/index.d.ts +14 -0
- package/types/lib/ui/MicIcon/index.d.ts +7 -0
- package/types/lib/ui/MicrophoneOverlay/index.d.ts +11 -0
- package/types/lib/ui/PlayIcon/index.d.ts +5 -0
- package/types/lib/ui/StopButton/index.d.ts +16 -0
- package/types/lib/ui/StopIcon/index.d.ts +5 -0
- package/types/shared/index.d.ts +1 -0
- package/types/shared/lib/Messages/ErrorMessage.d.ts +18 -0
- package/types/shared/lib/Messages/LoveLetter.d.ts +18 -0
- package/types/shared/lib/Messages/Ping.d.ts +15 -0
- package/types/shared/lib/Messages/Queue.d.ts +58 -0
- package/types/shared/lib/Messages/SessionId.d.ts +12 -0
- package/types/shared/lib/Messages/Stats.d.ts +182 -0
- package/types/shared/lib/Messages/StreamInfo.d.ts +338 -0
- package/types/shared/lib/Messages/Version.d.ts +12 -0
- package/types/shared/lib/Messages/WebSdkSettings.d.ts +96 -0
- package/types/shared/lib/Messages/index.d.ts +192 -0
- package/types/shared/lib/index.d.ts +1 -0
- package/.npmiognore +0 -1
package/README.md
CHANGED
|
@@ -80,6 +80,15 @@ For more detailed examples and advanced usage, please refer to our documentation
|
|
|
80
80
|
|
|
81
81
|
# Changelog
|
|
82
82
|
|
|
83
|
+
### 1.2.18
|
|
84
|
+
|
|
85
|
+
- fixed webpack to emit types
|
|
86
|
+
|
|
87
|
+
### 1.2.17 (broken)
|
|
88
|
+
|
|
89
|
+
- fixed diagnostics to interpred user agent and user agent data more accurately
|
|
90
|
+
- webpack did not emit types.d.ts do not use this version!
|
|
91
|
+
|
|
83
92
|
### 1.2.16
|
|
84
93
|
|
|
85
94
|
- Added "diagnostics collector" module
|
package/index.cjs.js
CHANGED
|
@@ -23351,7 +23351,7 @@ class ArcwareConfig extends lib_pixelstreamingfrontend_ue5_5_1.Config {
|
|
|
23351
23351
|
if (!config.initialSettings.ss)
|
|
23352
23352
|
config.initialSettings.ss = exports.DefaultUrl;
|
|
23353
23353
|
super(config);
|
|
23354
|
-
this.VERSION = "1.2.
|
|
23354
|
+
this.VERSION = "1.2.18";
|
|
23355
23355
|
this.settings = settings;
|
|
23356
23356
|
this.session = new Session_1.Session();
|
|
23357
23357
|
this._initialSettings = config.initialSettings;
|
|
@@ -23967,17 +23967,29 @@ exports.ArcwarePixelStreaming = ArcwarePixelStreaming;
|
|
|
23967
23967
|
* Default location: /diag/probe.bin
|
|
23968
23968
|
*/
|
|
23969
23969
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
23970
|
-
exports.DiagnosticsCollector = void 0;
|
|
23970
|
+
exports.DiagnosticsCollector = exports.Type = exports.Orientation = void 0;
|
|
23971
23971
|
const tslib_1 = __webpack_require__(655);
|
|
23972
|
+
var Orientation;
|
|
23973
|
+
(function (Orientation) {
|
|
23974
|
+
Orientation["Landscape"] = "landscape";
|
|
23975
|
+
Orientation["Portrait"] = "portrait";
|
|
23976
|
+
})(Orientation = exports.Orientation || (exports.Orientation = {}));
|
|
23977
|
+
var Type;
|
|
23978
|
+
(function (Type) {
|
|
23979
|
+
Type["Desktop"] = "desktop";
|
|
23980
|
+
Type["Mobile"] = "mobile";
|
|
23981
|
+
Type["Tablet"] = "tablet";
|
|
23982
|
+
})(Type = exports.Type || (exports.Type = {}));
|
|
23972
23983
|
/**
|
|
23973
23984
|
* DiagnosticsCollector
|
|
23974
23985
|
*/
|
|
23975
23986
|
class DiagnosticsCollector {
|
|
23976
23987
|
constructor(opts = {}) {
|
|
23977
23988
|
var _a, _b, _c, _d;
|
|
23989
|
+
this.uaInfoCache = null;
|
|
23978
23990
|
this.opts = {
|
|
23979
23991
|
enableBandwidthProbe: (_a = opts.enableBandwidthProbe) !== null && _a !== void 0 ? _a : true,
|
|
23980
|
-
probeUrl: (_b = opts.probeUrl) !== null && _b !== void 0 ? _b :
|
|
23992
|
+
probeUrl: (_b = opts.probeUrl) !== null && _b !== void 0 ? _b : "/diag/probe.bin",
|
|
23981
23993
|
respectSaveData: (_c = opts.respectSaveData) !== null && _c !== void 0 ? _c : true,
|
|
23982
23994
|
sampleRate: Math.max(0, Math.min(1, (_d = opts.sampleRate) !== null && _d !== void 0 ? _d : 1))
|
|
23983
23995
|
};
|
|
@@ -23990,8 +24002,8 @@ class DiagnosticsCollector {
|
|
|
23990
24002
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
23991
24003
|
if (!this.shouldSample()) {
|
|
23992
24004
|
return {
|
|
23993
|
-
device: { type:
|
|
23994
|
-
runtime: { browser: { family:
|
|
24005
|
+
device: { type: Type.Desktop, touchSupport: false },
|
|
24006
|
+
runtime: { browser: { family: "Unknown", version: null }, os: { family: "Unknown", version: null } },
|
|
23995
24007
|
powerHints: { saveData: null, prefersReducedData: null, prefersReducedMotion: null },
|
|
23996
24008
|
network: { type: null, effectiveType: null, downlinkMbps: null, rttMs: null, measuredDownlinkMbps: null },
|
|
23997
24009
|
timestamps: { collectedAt: Date.now() }
|
|
@@ -24037,9 +24049,9 @@ class DiagnosticsCollector {
|
|
|
24037
24049
|
const stats = yield pc.getStats();
|
|
24038
24050
|
let selected, transport, local, remote;
|
|
24039
24051
|
stats.forEach((r) => {
|
|
24040
|
-
if (r.type ===
|
|
24052
|
+
if (r.type === "transport" && r.selectedCandidatePairId)
|
|
24041
24053
|
transport = r;
|
|
24042
|
-
if (r.type ===
|
|
24054
|
+
if (r.type === "candidate-pair" && (r.selected || r.nominated))
|
|
24043
24055
|
selected = r;
|
|
24044
24056
|
});
|
|
24045
24057
|
if (selected) {
|
|
@@ -24080,16 +24092,16 @@ class DiagnosticsCollector {
|
|
|
24080
24092
|
hasTouch() {
|
|
24081
24093
|
var _a;
|
|
24082
24094
|
const nav = navigator;
|
|
24083
|
-
return
|
|
24095
|
+
return "ontouchstart" in window || ((_a = nav.maxTouchPoints) !== null && _a !== void 0 ? _a : 0) > 0;
|
|
24084
24096
|
}
|
|
24085
24097
|
getOrientation() {
|
|
24086
24098
|
var _a;
|
|
24087
24099
|
try {
|
|
24088
24100
|
if ((_a = screen.orientation) === null || _a === void 0 ? void 0 : _a.type) {
|
|
24089
|
-
return screen.orientation.type.startsWith(
|
|
24101
|
+
return screen.orientation.type.startsWith("portrait") ? Orientation.Portrait : Orientation.Landscape;
|
|
24090
24102
|
}
|
|
24091
24103
|
if (window.matchMedia) {
|
|
24092
|
-
return window.matchMedia(
|
|
24104
|
+
return window.matchMedia("(orientation: portrait)").matches ? Orientation.Portrait : Orientation.Landscape;
|
|
24093
24105
|
}
|
|
24094
24106
|
}
|
|
24095
24107
|
catch (_b) { }
|
|
@@ -24097,8 +24109,8 @@ class DiagnosticsCollector {
|
|
|
24097
24109
|
}
|
|
24098
24110
|
hasWebGL() {
|
|
24099
24111
|
try {
|
|
24100
|
-
const canvas = document.createElement(
|
|
24101
|
-
return !!(canvas.getContext(
|
|
24112
|
+
const canvas = document.createElement("canvas");
|
|
24113
|
+
return !!(canvas.getContext("webgl") || canvas.getContext("experimental-webgl"));
|
|
24102
24114
|
}
|
|
24103
24115
|
catch (_a) {
|
|
24104
24116
|
return false;
|
|
@@ -24106,37 +24118,50 @@ class DiagnosticsCollector {
|
|
|
24106
24118
|
}
|
|
24107
24119
|
/**
|
|
24108
24120
|
* Heuristic device type: best-effort only.
|
|
24121
|
+
* Tries UA-CH, then UA fallback, then touch + screen size heuristics.
|
|
24109
24122
|
*/
|
|
24110
24123
|
inferDeviceType() {
|
|
24111
24124
|
const uaData = navigator.userAgentData;
|
|
24125
|
+
const ua = navigator.userAgent || "";
|
|
24112
24126
|
const isMobileCH = (uaData === null || uaData === void 0 ? void 0 : uaData.mobile) === true;
|
|
24113
24127
|
const minDim = Math.min(screen.width, screen.height);
|
|
24114
|
-
|
|
24115
|
-
|
|
24116
|
-
|
|
24117
|
-
|
|
24118
|
-
|
|
24119
|
-
|
|
24120
|
-
|
|
24121
|
-
|
|
24122
|
-
|
|
24128
|
+
// 1. Explicit iPad / tablet detection via UA (iOS often lies in CH)
|
|
24129
|
+
if (/\b(iPad|Tablet)\b/i.test(ua)) {
|
|
24130
|
+
return Type.Tablet;
|
|
24131
|
+
}
|
|
24132
|
+
// 2. UA-CH mobile hint (Chromium only, often accurate for Android)
|
|
24133
|
+
if (isMobileCH) {
|
|
24134
|
+
if (minDim >= 600)
|
|
24135
|
+
return Type.Tablet;
|
|
24136
|
+
return Type.Mobile;
|
|
24137
|
+
}
|
|
24138
|
+
// 3. UA sniffing fallback for mobile
|
|
24139
|
+
if (/\b(iPhone|Android.*Mobile|Windows Phone)\b/i.test(ua)) {
|
|
24140
|
+
return Type.Mobile;
|
|
24141
|
+
}
|
|
24142
|
+
// 4. Touch-capable with "tablet-like" dimensions
|
|
24143
|
+
if (("ontouchstart" in window || navigator.maxTouchPoints > 0) && minDim >= 600 && minDim <= 1100) {
|
|
24144
|
+
return Type.Tablet;
|
|
24145
|
+
}
|
|
24146
|
+
// 5. Default fallback
|
|
24147
|
+
return Type.Desktop;
|
|
24123
24148
|
}
|
|
24124
24149
|
getPowerHints() {
|
|
24125
24150
|
const conn = navigator.connection;
|
|
24126
|
-
const saveData = typeof (conn === null || conn === void 0 ? void 0 : conn.saveData) ===
|
|
24151
|
+
const saveData = typeof (conn === null || conn === void 0 ? void 0 : conn.saveData) === "boolean" ? conn.saveData : null;
|
|
24127
24152
|
let prefersReducedData = null;
|
|
24128
24153
|
let prefersReducedMotion = null;
|
|
24129
|
-
if (typeof window.matchMedia ===
|
|
24154
|
+
if (typeof window.matchMedia === "function") {
|
|
24130
24155
|
try {
|
|
24131
|
-
const mqData = window.matchMedia(
|
|
24132
|
-
if (typeof mqData.matches ===
|
|
24156
|
+
const mqData = window.matchMedia("(prefers-reduced-data: reduce)");
|
|
24157
|
+
if (typeof mqData.matches === "boolean") {
|
|
24133
24158
|
prefersReducedData = mqData.matches;
|
|
24134
24159
|
}
|
|
24135
24160
|
}
|
|
24136
24161
|
catch (_a) { }
|
|
24137
24162
|
try {
|
|
24138
|
-
const mqMotion = window.matchMedia(
|
|
24139
|
-
if (typeof mqMotion.matches ===
|
|
24163
|
+
const mqMotion = window.matchMedia("(prefers-reduced-motion: reduce)");
|
|
24164
|
+
if (typeof mqMotion.matches === "boolean") {
|
|
24140
24165
|
prefersReducedMotion = mqMotion.matches;
|
|
24141
24166
|
}
|
|
24142
24167
|
}
|
|
@@ -24147,10 +24172,10 @@ class DiagnosticsCollector {
|
|
|
24147
24172
|
getNetworkInfo(measuredDownlinkMbps) {
|
|
24148
24173
|
const conn = navigator.connection;
|
|
24149
24174
|
return {
|
|
24150
|
-
type:
|
|
24151
|
-
effectiveType:
|
|
24152
|
-
downlinkMbps:
|
|
24153
|
-
rttMs:
|
|
24175
|
+
type: typeof (conn === null || conn === void 0 ? void 0 : conn.type) === "string" ? conn.type : null,
|
|
24176
|
+
effectiveType: typeof (conn === null || conn === void 0 ? void 0 : conn.effectiveType) === "string" ? conn.effectiveType : null,
|
|
24177
|
+
downlinkMbps: typeof (conn === null || conn === void 0 ? void 0 : conn.downlink) === "number" ? conn.downlink : null,
|
|
24178
|
+
rttMs: typeof (conn === null || conn === void 0 ? void 0 : conn.rtt) === "number" ? conn.rtt : null,
|
|
24154
24179
|
measuredDownlinkMbps
|
|
24155
24180
|
};
|
|
24156
24181
|
}
|
|
@@ -24165,8 +24190,8 @@ class DiagnosticsCollector {
|
|
|
24165
24190
|
try {
|
|
24166
24191
|
const t0 = performance.now();
|
|
24167
24192
|
const res = yield fetch(this.withCacheBuster(this.opts.probeUrl), {
|
|
24168
|
-
cache:
|
|
24169
|
-
credentials:
|
|
24193
|
+
cache: "no-store",
|
|
24194
|
+
credentials: "omit"
|
|
24170
24195
|
});
|
|
24171
24196
|
const buf = yield res.arrayBuffer();
|
|
24172
24197
|
const t1 = performance.now();
|
|
@@ -24174,7 +24199,7 @@ class DiagnosticsCollector {
|
|
|
24174
24199
|
const seconds = (t1 - t0) / 1000;
|
|
24175
24200
|
if (seconds <= 0.05)
|
|
24176
24201
|
return null; // ignore unstable samples
|
|
24177
|
-
return +(
|
|
24202
|
+
return +(bits / seconds / 1000000).toFixed(2);
|
|
24178
24203
|
}
|
|
24179
24204
|
catch (_a) {
|
|
24180
24205
|
return null;
|
|
@@ -24185,7 +24210,7 @@ class DiagnosticsCollector {
|
|
|
24185
24210
|
var _a, _b;
|
|
24186
24211
|
const u = new URL(url, location.origin);
|
|
24187
24212
|
const token = (_b = (_a = crypto === null || crypto === void 0 ? void 0 : crypto.randomUUID) === null || _a === void 0 ? void 0 : _a.call(crypto)) !== null && _b !== void 0 ? _b : String(Date.now());
|
|
24188
|
-
u.searchParams.set(
|
|
24213
|
+
u.searchParams.set("cb", token);
|
|
24189
24214
|
return u.toString();
|
|
24190
24215
|
}
|
|
24191
24216
|
getCodecSupport() {
|
|
@@ -24200,10 +24225,10 @@ class DiagnosticsCollector {
|
|
|
24200
24225
|
supportsCodec(mime) {
|
|
24201
24226
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
24202
24227
|
try {
|
|
24203
|
-
if (
|
|
24228
|
+
if ("mediaCapabilities" in navigator) {
|
|
24204
24229
|
// @ts-ignore
|
|
24205
24230
|
const res = yield navigator.mediaCapabilities.decodingInfo({
|
|
24206
|
-
type:
|
|
24231
|
+
type: "file",
|
|
24207
24232
|
video: { contentType: mime, width: 1920, height: 1080, bitrate: 5000000, framerate: 30 }
|
|
24208
24233
|
});
|
|
24209
24234
|
return !!(res === null || res === void 0 ? void 0 : res.supported);
|
|
@@ -24211,8 +24236,8 @@ class DiagnosticsCollector {
|
|
|
24211
24236
|
}
|
|
24212
24237
|
catch (_a) { }
|
|
24213
24238
|
try {
|
|
24214
|
-
const v = document.createElement(
|
|
24215
|
-
return v.canPlayType(mime) !==
|
|
24239
|
+
const v = document.createElement("video");
|
|
24240
|
+
return v.canPlayType(mime) !== "";
|
|
24216
24241
|
}
|
|
24217
24242
|
catch (_b) {
|
|
24218
24243
|
return false;
|
|
@@ -24220,60 +24245,104 @@ class DiagnosticsCollector {
|
|
|
24220
24245
|
});
|
|
24221
24246
|
}
|
|
24222
24247
|
getUAInfo() {
|
|
24223
|
-
var _a, _b;
|
|
24224
24248
|
return tslib_1.__awaiter(this, void 0, void 0, function* () {
|
|
24249
|
+
if (this.uaInfoCache)
|
|
24250
|
+
return this.uaInfoCache;
|
|
24225
24251
|
const nav = navigator;
|
|
24226
24252
|
const uaData = nav.userAgentData;
|
|
24227
|
-
|
|
24228
|
-
let
|
|
24229
|
-
let
|
|
24253
|
+
const ua = navigator.userAgent;
|
|
24254
|
+
let browserFamily = "Unknown";
|
|
24255
|
+
let browserVersion = null;
|
|
24256
|
+
let osFamily = "Unknown";
|
|
24257
|
+
let osVersion = null;
|
|
24258
|
+
let model = null;
|
|
24259
|
+
let architecture = null;
|
|
24260
|
+
let bitness = null;
|
|
24261
|
+
// --- UA-CH (modern browsers) ---
|
|
24230
24262
|
if (uaData === null || uaData === void 0 ? void 0 : uaData.getHighEntropyValues) {
|
|
24231
24263
|
try {
|
|
24232
24264
|
const high = yield uaData.getHighEntropyValues([
|
|
24233
|
-
|
|
24265
|
+
"platform",
|
|
24266
|
+
"platformVersion",
|
|
24267
|
+
"model",
|
|
24268
|
+
"architecture",
|
|
24269
|
+
"bitness",
|
|
24270
|
+
"fullVersionList"
|
|
24234
24271
|
]);
|
|
24235
|
-
osFamily = high.platform ||
|
|
24272
|
+
osFamily = high.platform || "Unknown";
|
|
24236
24273
|
osVersion = high.platformVersion || null;
|
|
24237
24274
|
model = high.model || null;
|
|
24238
24275
|
architecture = high.architecture || null;
|
|
24239
24276
|
bitness = high.bitness || null;
|
|
24240
24277
|
const brands = high.fullVersionList || uaData.brands || [];
|
|
24241
|
-
const
|
|
24242
|
-
|
|
24243
|
-
|
|
24244
|
-
|
|
24245
|
-
|
|
24246
|
-
|
|
24247
|
-
|
|
24248
|
-
|
|
24249
|
-
|
|
24250
|
-
|
|
24251
|
-
browserVersion = RegExp.$1;
|
|
24252
|
-
}
|
|
24253
|
-
else if (/Edg\/(\S+)/.test(ua)) {
|
|
24254
|
-
browserFamily = 'Edge';
|
|
24255
|
-
browserVersion = RegExp.$1;
|
|
24278
|
+
const realBrand = brands.find((b) => {
|
|
24279
|
+
if (!b.brand)
|
|
24280
|
+
return false;
|
|
24281
|
+
const normalized = b.brand.replace(/[^a-zA-Z]/g, "").toLowerCase();
|
|
24282
|
+
return !normalized.includes("chromium") && !normalized.includes("notabrand");
|
|
24283
|
+
});
|
|
24284
|
+
if (realBrand) {
|
|
24285
|
+
browserFamily = realBrand.brand;
|
|
24286
|
+
browserVersion = realBrand.version;
|
|
24287
|
+
}
|
|
24256
24288
|
}
|
|
24257
|
-
|
|
24258
|
-
|
|
24259
|
-
browserVersion = RegExp.$1;
|
|
24289
|
+
catch (_a) {
|
|
24290
|
+
// silently fail
|
|
24260
24291
|
}
|
|
24261
|
-
|
|
24262
|
-
|
|
24263
|
-
|
|
24292
|
+
}
|
|
24293
|
+
// --- Fallback to classic UA parsing if browser unknown ---
|
|
24294
|
+
if (!browserFamily || browserFamily === "Unknown") {
|
|
24295
|
+
const browserRegexes = [
|
|
24296
|
+
[/Edg\/(\S+)/, "Edge"],
|
|
24297
|
+
[/OPR\/(\S+)/, "Opera"],
|
|
24298
|
+
[/SamsungBrowser\/(\S+)/, "Samsung Internet"],
|
|
24299
|
+
[/Firefox\/(\S+)/, "Firefox"],
|
|
24300
|
+
[/Chrome\/(\S+)/, "Chrome"],
|
|
24301
|
+
[/Version\/(\S+).*Safari/, "Safari"]
|
|
24302
|
+
];
|
|
24303
|
+
for (const [regex, name] of browserRegexes) {
|
|
24304
|
+
const match = ua.match(regex);
|
|
24305
|
+
if (match) {
|
|
24306
|
+
browserFamily = name;
|
|
24307
|
+
browserVersion = match[1];
|
|
24308
|
+
break;
|
|
24309
|
+
}
|
|
24264
24310
|
}
|
|
24265
|
-
|
|
24266
|
-
|
|
24267
|
-
|
|
24268
|
-
|
|
24269
|
-
|
|
24270
|
-
|
|
24271
|
-
|
|
24272
|
-
|
|
24273
|
-
|
|
24274
|
-
|
|
24275
|
-
}
|
|
24276
|
-
|
|
24311
|
+
}
|
|
24312
|
+
// --- OS detection (always run, iOS first) ---
|
|
24313
|
+
if (/iPhone|iPad|iPod/.test(ua)) {
|
|
24314
|
+
osFamily = "iOS";
|
|
24315
|
+
const match = ua.match(/OS (\d+[_\d]*)/);
|
|
24316
|
+
if (match)
|
|
24317
|
+
osVersion = match[1].replace(/_/g, ".");
|
|
24318
|
+
}
|
|
24319
|
+
else if (uaData === null || uaData === void 0 ? void 0 : uaData.platform) {
|
|
24320
|
+
osFamily = uaData.platform;
|
|
24321
|
+
}
|
|
24322
|
+
else if (/Windows/.test(ua)) {
|
|
24323
|
+
osFamily = "Windows";
|
|
24324
|
+
const match = ua.match(/Windows NT (\d+\.\d+)/);
|
|
24325
|
+
if (match)
|
|
24326
|
+
osVersion = match[1];
|
|
24327
|
+
}
|
|
24328
|
+
else if (/Mac OS X/.test(ua)) {
|
|
24329
|
+
osFamily = "macOS";
|
|
24330
|
+
const match = ua.match(/Mac OS X (\d+[_\d]*)/);
|
|
24331
|
+
if (match)
|
|
24332
|
+
osVersion = match[1].replace(/_/g, ".");
|
|
24333
|
+
}
|
|
24334
|
+
else if (/Android/.test(ua)) {
|
|
24335
|
+
osFamily = "Android";
|
|
24336
|
+
const match = ua.match(/Android (\d+(\.\d+)?)/);
|
|
24337
|
+
if (match)
|
|
24338
|
+
osVersion = match[1];
|
|
24339
|
+
}
|
|
24340
|
+
else if (/Linux/.test(ua)) {
|
|
24341
|
+
osFamily = "Linux";
|
|
24342
|
+
}
|
|
24343
|
+
const result = { browserFamily, browserVersion, osFamily, osVersion, model, architecture, bitness };
|
|
24344
|
+
this.uaInfoCache = result;
|
|
24345
|
+
return result;
|
|
24277
24346
|
});
|
|
24278
24347
|
}
|
|
24279
24348
|
}
|