{"_id":"@51degrees/ua-parser-js","_rev":"5-caca0db9d5b2367b4a9a9c61e8896b50","name":"@51degrees/ua-parser-js","dist-tags":{"latest":"2.0.3","2.0.2":"2.0.2"},"versions":{"2.0.0":{"name":"@51degrees/ua-parser-js","version":"2.0.0","description":"User-Agent and User Agent Client Hints parser. Supports the latest Chromium browsers and Apple model detection.","download":"https://raw.github.com/51Degrees/ua-parser-js/main/lib/ua-parser.min.js","main":"lib/ua-parser.js","types":"lib/types/UAParser.d.ts","homepage":"https://github.com/51Degrees/ua-parser-js","demo":"https://51Degrees.github.io/ua-parser-js","repository":{"type":"git","url":"git+https://github.com/51Degrees/ua-parser-js.git"},"license":"MIT","devDependencies":{"@babel/cli":"^7.20.7","@babel/preset-env":"^7.20.2","@babel/preset-typescript":"^7.18.6","@rollup/plugin-babel":"^6.0.3","@rollup/plugin-node-resolve":"^15.0.1","@rollup/plugin-terser":"^0.2.0","@rollup/plugin-typescript":"^10.0.1","@types/jest":"^29.2.4","babel-plugin-add-module-exports":"^1.0.4","cross-env":"^7.0.3","dotenv":"^16.0.3","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","jest-puppeteer":"^6.2.0","npm-run-all":"^4.1.5","prettier":"^2.8.1","puppeteer":"^19.5.0","rimraf":"^3.0.2","rollup":"^2.78","ts-jest":"^29.0.3","tslint":"^6.1.3","tslint-config-prettier":"^1.18.0","typescript":"^4.9.4"},"scripts":{"clean":"rimraf lib","declarations":"tsc -p tsconfig.json","server:start":"node server.js fg","server:stop":"node server.stop.js fg","test":"jest --config jestconfig.json --runInBand --verbose --detectOpenHandles --forceExit","format":"prettier --write \"src/**/*.ts\"","lint":"tslint -p tsconfig.json","build:bundles":"cross-env BABEL_ENV=esmBundled rollup -c","build":"npm-run-all -l clean -p build:bundles declarations","start":"node server.js"},"engines":{"node":">=10.0.0"},"bugs":{"url":"https://github.com/51Degrees/ua-parser-js/issues"},"directories":{"lib":"lib"},"keywords":["device detection","User Agent Client Hints","Client Hints","UA-CH","CH-UA","User-Agent","UAParser"],"author":{"name":"Roman Sertsov","email":"roman.sertsov@postindustria.com"},"publishConfig":{"access":"public"},"gitHead":"cbacb9e495ca41ce35394c09b590dc384e53f856","_id":"@51degrees/ua-parser-js@2.0.0","_nodeVersion":"16.16.0","_npmVersion":"9.4.1","dist":{"integrity":"sha512-az6kEPpNFchFoaRh0CLg2G8SUDctFmqQKVxC6CH2QubdHuJTND38xmVLyoq+b7HZwcfS4cPYajfMukey2aOIMg==","shasum":"cb5f7b2d213db972d66e9ed9a48063d6282bb8b0","tarball":"https://registry.npmjs.org/@51degrees/ua-parser-js/-/ua-parser-js-2.0.0.tgz","fileCount":27,"unpackedSize":79160,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAVi0WF8pAhspWy51FmbZ4tbztDECGsGyGs8kue7JGygAiBFqRNcBUwPk8OGi0NFAdvuGb7WNs9Ah5fLCYD6lN94wA=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj5SjMACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp6ew//SNo615KA9x5yJsgQrEMoeD+eiuOvTkmQGMl1Mzj58BtBSV31\r\nIA96rmccxWQjR7W/zzQwDjR3U5zhQoYP0h+9J7rUrPO0dNJxp1eekPmKuNRg\r\neyoG1k6yPfOXehRMDrWbOpWOuv16L8XmF0bLGdanlz73L80mWs9cqWqu+uQL\r\nTURRf557lQ1ShU90jUPv1a/9aAMuSK3LAofkurgv48AW3n+D+NO5GS6NpCb6\r\nNH44Rce9Ow30i06Zv4fZyQJ/gII33cAeCtFhmaJTWoIoi1LOUfAE9qBS9EkC\r\n+P7e8L9/JnUfkbzaxj9IC48sam6Y5GDHJFE5eR15RMGx5HN6izyXaaZdVACd\r\n3FOpkcPHr+L9LtuiLA1jupQ9HXi5IpXdEVwIPZ/MHs5yg8i7/aOkn6AmzpgA\r\nOKRCRX4KKIyGUyCxi0UaFw8iBWraSWSFn8s1veShd7/WBbGMJOMQCP8zgM9R\r\nvF1lrjZNMhcWSpBafoznuikqEd8YfpZAxrzBSnL9kNR7zGQupDh/RA4cJAcf\r\nlQ29EvDCVOFhn5Xr2ZMNsd208hdAoHklfDSmHKL3KykGzMfeFsTj6oCTNxhZ\r\nKQ79un4ZoqH/fiPl1Sr3tgiCE/U+F7RrD0a5g3bYw6tttkYZZ0sQcR4KAUNi\r\nFjXPDB7uNevIYQd0G0gaeLOmUJaDmJfI+24=\r\n=9l7y\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"roman.s","email":"roman.sertsov@postindustria.com"},"maintainers":[{"name":"roman.s","email":"roman.sertsov@postindustria.com"},{"name":"eugenedorfman","email":"eugene.dorfman@postindustria.com"},{"name":"51d","email":"support@51degrees.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/ua-parser-js_2.0.0_1675962572525_0.1662086788862016"},"_hasShrinkwrap":false},"2.0.2":{"name":"@51degrees/ua-parser-js","version":"2.0.2","description":"User-Agent and User Agent Client Hints parser. Supports the latest Chromium browsers and Apple model detection.","download":"https://raw.github.com/51Degrees/ua-parser-js/main/lib/ua-parser.min.js","main":"lib/ua-parser.js","types":"lib/types/UAParser.d.ts","homepage":"https://51degrees.github.io/ua-parser-js/","demo":"https://51Degrees.github.io/ua-parser-js","repository":{"type":"git","url":"git+https://github.com/51Degrees/ua-parser-js.git"},"license":"MIT","devDependencies":{"@babel/cli":"^7.20.7","@babel/preset-env":"^7.20.2","@babel/preset-typescript":"^7.18.6","@rollup/plugin-babel":"^6.0.3","@rollup/plugin-node-resolve":"^15.0.1","@rollup/plugin-terser":"^0.2.0","@rollup/plugin-typescript":"^10.0.1","@types/jest":"^29.2.4","babel-plugin-add-module-exports":"^1.0.4","cross-env":"^7.0.3","dotenv":"^16.0.3","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","jest-puppeteer":"^6.2.0","npm-run-all":"^4.1.5","prettier":"^2.8.1","puppeteer":"^19.5.0","rimraf":"^3.0.2","rollup":"^2.78","ts-jest":"^29.0.3","tslint":"^6.1.3","tslint-config-prettier":"^1.18.0","typescript":"^4.9.4"},"scripts":{"clean":"rimraf lib","declarations":"tsc -p tsconfig.json","server:start":"node server.js fg","server:stop":"node server.stop.js fg","test":"jest --config jestconfig.json --runInBand --verbose --detectOpenHandles --forceExit","format":"prettier --write \"src/**/*.ts\"","lint":"tslint -p tsconfig.json","build:bundles":"cross-env BABEL_ENV=esmBundled rollup -c","build":"npm-run-all -l clean -p build:bundles declarations","start":"node server.js"},"engines":{"node":">=10.0.0"},"bugs":{"url":"https://github.com/51Degrees/ua-parser-js/issues"},"keywords":["device detection","User Agent Client Hints","Client Hints","UA-CH","CH-UA","User-Agent","UAParser"],"author":{"name":"Roman Sertsov","email":"roman.sertsov@postindustria.com"},"readmeFilename":"README.md","readme":"<!--p align=\"center\">\n    <img src=\"https://raw.githubusercontent.com/faisalman/ua-parser-js/gh-pages/images/logo.png\" width=\"256\" height=\"256\"> \n</p>\n\n<p align=\"center\">\n<a href=\"https://travis-ci.org/faisalman/ua-parser-js\"><img src=\"https://travis-ci.org/faisalman/ua-parser-js.svg?branch=master\"></a>\n<a href=\"https://www.npmjs.com/package/ua-parser-js\"><img src=\"https://img.shields.io/npm/v/ua-parser-js.svg\"></a>\n<a href=\"https://www.npmjs.com/package/ua-parser-js\"><img src=\"https://img.shields.io/npm/dw/ua-parser-js.svg\"></a>\n<a href=\"https://www.jsdelivr.com/package/npm/ua-parser-js\"><img src=\"https://data.jsdelivr.com/v1/package/npm/ua-parser-js/badge\"></a>\n<a href=\"https://cdnjs.com/libraries/UAParser.js\"><img src=\"https://img.shields.io/cdnjs/v/UAParser.js.svg\"></a>\n</p-->\n# 51Degrees UAParser\n\nA lightweight JavaScript library wrapping [51Degrees Device Detection](https://51degrees.com/device-detection) cloud service.  The library provides comprehensive device data based on User-Agent Client Hints and/or the User-Agent.  This package can be used either in a browser (client-side) or in Node.js environment (server-side).  Client-side supports detection of the current client or detection from an arbitrary header map, while server-side supports detection from a header map only.  \n\nThis is a fork of a popular [UAParser.js](https://github.com/faisalman/ua-parser-js) library that relied solely on a deprecated User-Agent for the local device detection.  The current library allows for an easy migration from the original UAParser.js.\n\nFor a more sophisticated solution, check out 51Degrees Device Detection Node Package: https://www.npmjs.com/package/fiftyone.devicedetection \n\n* Author    : Roman Sertsov <roman.sertsov@postindustria.com>\n* Demo      : https://51degrees.github.io/ua-parser-js\n* Source    : https://github.com/51Degrees/ua-parser-js\n\n# Documentation\n\n## Usage\n\nYou can use 51D UAParser in 3 easy steps.\n\n1. **Install the package** using `npm` or other dependency manager such as `yarn`:\n```\nnpm i @51degrees/ua-parser-js\n```\n\n2. **Register and configure a Resource Key** to use with 51Degrees Cloud service [here](https://configure.51degrees.com/S6fGMDKw) - you will need it as a required parameter to pass to UAParser function.\n\n3. **Integrate the device detection code.**  Below there are usage examples for the client and server side:\n\n### Client side (HTML)\nPlease note the `<meta http-equiv=\"Delegate-CH\">` tag needed for the [User-Agent Client Hints delegation](#user-agent-client-hints-delegation).\n\n```html\n<!doctype html>\n<html>\n<head>\n\n    <!-- note the meta tag for User-Agent Client Hint delegation -->\n    <meta http-equiv=\"Delegate-CH\" content=\"Sec-CH-UA-Model https://cloud.51degrees.com; \n    Sec-CH-UA https://cloud.51degrees.com; Sec-CH-UA-Arch https://cloud.51degrees.com; \n    Sec-CH-UA-Full-Version https://cloud.51degrees.com; Sec-CH-UA-Mobile https://cloud.51degrees.com; \n    Sec-CH-UA-Platform https://cloud.51degrees.com; Sec-CH-UA-Platform-Version https://cloud.51degrees.com\" />\n\n    <script src=\"/path/to/@51degrees/ua-parser.min.js>\"></script>\n\n    <script type=\"module\">  \n        // note the type=\"module\" to use the top-level await\n        // this code can also live in a standalone mjs file\n\n        // helper function:\n        function formatDevice (device, sep=\"<br />\") {\n            return [\"DeviceType\", \n              \"PlatformVendor\", \n              \"PlatformName\", \n              \"PlatformVersion\", \n              \"BrowserVendor\", \n              \"BrowserName\", \n              \"BrowserVersion\", \n              \"LayoutEngine\", \n              \"HardwareName\", \n              \"HardwareModel\", \n              \"HardwareVendor\"]\n            // note that device property names are in lower case\n            .map( key => key + \": \" + device[key.toLowerCase()]) \n            .join(sep)\n        }\n\n\n        // obtain a Resource Key at https://configure.51degrees.com/S6fGMDKw\n        const rk = \"<your resource key>\"; \n\n        let result = await UAParser(rk);  // note the top-level await\n        let device = result.device;\n        console.log(device); \n        document.body.innerHTML = formatDevice(device);\n    </script>\n</head>\n<body>\n</body>\n</html>\n```\n\n### Server-side (Node.js)\nThis is a CommonJS example, to use a top-level `await` you need to use [ECMAScript Modules](https://nodejs.org/api/esm.html#modules-ecmascript-modules). \n\nAn example of processing an arbitrary header map on the server:\n```js\n\nconst rk = \"<your resource key>\"; // obtain a Resource Key at https://configure.51degrees.com/S6fGMDKw\n\n// an example of processing an arbitrary header map:\nconst context = async () => {\n  const result = await UAParser(rk,{\n    \"sec-ch-ua\":\n      \"Not_A Brand;v=99, Google Chrome;v=109, Chromium;v=109\",\n    \"sec-ch-ua-arch\": \"x64\",\n    \"sec-ch-ua-full-version\": \"109.0.5414.87\",\n    \"sec-ch-ua-platform\": \"macOS\",\n    \"sec-ch-ua-platform-version\": \"12.2.1\",\n    \"user-agent\":\n      \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36\",\n  })\n  console.log(result.device)\n}\ncontext().then();\n```\n\nAn example of processing client HTTP headers received by the server:\n```js\nvar http = require('http');\nhttp.createServer(async function (req, res) {\n\n  let result = await UAParser(rk,  req.headers);\n  \n  // a list of useful client hints to obtain from the browser\n  ch = 'Sec-CH-UA, Sec-CH-UA-Arch, Sec-CH-Bitness, Sec-CH-UA-Full-Version, \\\n        Sec-CH-UA-Full-Version-List, Sec-CH-UA-Mobile, Sec-CH-UA-Model, Sec-CH-UA-Platform, \\\n        Sec-CH-UA-Platform-Version, Sec-CH-UA-WoW64'\n\n  // requesting UA-CH\n  res.setHeader('Accept-CH', ch)   \n  // asking the browser to do an immediate repetition of the request with the UA-CH sent, \n  // before rendering the page, so we can send a more detailed data in the response\n  res.setHeader('Critical-CH',ch)  \n\n  res.end(JSON.stringify(result.device));\n})\n.listen(1337, '127.0.0.1');\nconsole.log('Server running at http://localhost:1337/');\n```\n### Using TypeScript\n\nTypeScript is supported natively, just use a regular import syntax in TS:\n```js\nimport UAParser from '@51degrees/ua-parser-js';\n```\n\n## API\n```js\nlet result = await UAParser(resource-key[,header map])\n```\n\n- typeof `resource-key` is `string`\n- typeof `header map` is `Map`\n\nUAParser returns a Promise object that resolves to the [Result](#result-object) object.\n\nResource Key is a required parameter. **You must create and [configure a Resource Key](https://configure.51degrees.com/S6fGMDKw).** \n\n**Note:** Following [this link to create a Resource Key](https://configure.51degrees.com/S6fGMDKw) will prepopulate your Key with the recommended minimum properties. The properties included are:\n- `IsMobile`\n- `HardwareVendor`\n- `HardwareModel`\n- `HardwareName`\n- `PlatformVendor`\n- `PlatformName`\n- `PlatformVersion`\n- `LayoutEngine`\n- `BrowserVendor`\n- `BrowserName`\n- `BrowserVersion`\n- `JavascriptHardwareProfile` – the Resource Key must contain the `JavascriptHardwareProfile` property in order to do a reliable detection of Apple devices.\n- `DeviceType`\n- `SetHeaderBrowserAccept-CH`\n- `SetHeaderHardwareAccept-CH`\n- `SetHeaderPlatformAccept-CH`\n\nOther properties are available, but may require the purchase of a [51Degrees pricing plan](https://51degrees.com/pricing). Follow [this guide](https://51degrees.com/documentation/_concepts__configurator.html) to create a Key from scratch if needed. \n\nIn the browser environment you don't need to pass the header map object containing either User-Agent or User-Agent Client Hints.  If not passed 51D UAParser will detect the current device which is executing the script.  \n\nIn the server-side environment the header map is a required parameter. You must pass User-Agent Client Hints and/or the User-Agent as part of it, or simply all headers from the request `request.headers` received by the server - it should contain the needed ones. \n\n**Note** the `await` keyword.  Since the 51D UAParser uses a cloud service internally, the API is inherently asynchronous.\n\n**Note** that for the current client detection in the browser you must implement [User-Agent Client Hints Delegation](#user-agent-client-hints-delegation) either via Permission-Policy header or `<meta http-equiv=\"Delegate-CH\">` tag.\n\n### Result object\nResult object contains the `device` object with all the detected device properties:\n```\nresult.device\n```\n51Degrees maintains the [rigid data model](http://51degrees.com/developers/property-dictionary).  The device data is maintained by a professional team of data analysts and is updated daily Monday through Thursday. \n\n## Migration from original UAParser.js\n\nThe migration from the original [UAParser.js](https://github.com/faisalman/ua-parser-js) comes down to the following steps:\n1. For Node.js: replace the package name from `ua-parser-js` to `@51degrees/ua-parser-js`. For the browser provide the correct path in the src attribute to the new `@51degrees/ua-parser.min.js`. \n2. Call `UAParser` as an `async` function with the `await` keyword, or use `then` to await the Promise.\n3. Use a Resource Key to configure custom device fields. A guide to create this Key can be found [here](https://51degrees.com/documentation/_concepts__configurator.html)\n4. Pass the `header map` containing User-Agent Client Hints headers, instead of the User-Agent string as a parameter.\n5. For the client side / html integration - implement either Accept-CH + Permission-Policy headers on your server or Delegate-CH http-equiv meta tag in order to delegate User-Agent Client Hints to 51Degrees Cloud service as described [here](#user-agent-client-hints-delegation).\n\nThis call\n```js\n    let result = UAParser([user-agent][,extension])\n```\nnow becomes:\n```js\n    let result = await UAParser(resource-key[,header map])\n```\nMake sure the code is running within the async context (async function) or within the ECMAScript module context where top-level `await` is supported.\n\n6. Refrain from using the old UAParser constructor (`new UAParser`) - this approach has been deprecated.  `UAParser` now returns a Promise, that must be `await`ed or `then`ed - thus constructing an object does not make sense.\n\n### Deprecations\n1. Constructor (a call to `new UAParser`) is no longer supported.\n2. Methods `setUA()`, `getUA()`, and `getResult()` are no longer supported and will throw if called on the UAParser Promise object. \n\n### Original UAParser properties mapping\nTo support existing code we made an effort to map the 51Degrees data model to that of the original [UAParser.js](https://github.com/faisalman/ua-parser-js) data model:\n```js\n{\n    ua: '',\n    browser: { name: '', version: '' },\n    cpu: { architecture: '' },\n    device: { model: '', type: '', vendor: '' },\n    engine: { name: '', version: '' },\n    os: { name: '', version: '' }\n}\n```\n\nThe current library makes the best effort to map 51Degrees values to the original value ranges provided by UAParser.js to minimize breaking changes in the updated code. \n\n\n### New data points\n\nBesides maintaining the mappings to the original UAParser properties, 51Degrees significantly expands the set of available data points.  Data points are made available dynamically depending on the Resource Key configuration.  All the data points are keyed as lower case properties within the `device` property of the `result` object, see an example `result` object below:\n\n```js\n{\n    ...\n    device: {\n        batterycapacity: 2770,\n        devicetype: \"SmartPhone\",\n        hardwaremodel: \"Pixel\",\n        hardwarename: [\n            \"Pixel\"\n        ],\n        hardwarerank: 1524,\n        hardwarevendor: \"Google\",\n        hasremovablebattery: false,\n        ismobile: true,\n        supportedchargertypes: [\n            \"Qualcomm Quick Charge 3.0\",\n            \"Wire\"\n        ],\n        model: \"Pixel\",  //original property\n        type: \"mobile\",  //original property\n        vendor: \"Google\" //original property\n    },\n    ...\n}\n```\n\nPlease refer to the [51Degrees Configurator](https://configure.51degrees.com) for a full list of the data points available.\n\n\n## User-Agent Client Hints Delegation\n\nMigrating to User-Agent Client Hints for your web app is well described in many sources, for example, this WICG [draft report on UA-CH](https://wicg.github.io/ua-client-hints/) or this human-readable [article](https://web.dev/migrate-to-ua-ch/).\n\nAny request the web browser sends contains the so-called low-entropy User-Agent Client Hints, namely these three:\n- `Sec-CH-UA`\n- `Sec-CH-UA-Mobile`\n- `Sec-CH-UA-Platform`\n\nTo request additional high-entropy UA-CH headers one must specify them in the `Accept-CH` header, this will tell the browser to send them in the subsequent request to the first-party server.  \n```\nAccept-CH: Sec-CH-UA, Sec-CH-UA-Arch, Sec-CH-Bitness, Sec-CH-UA-Full-Version, Sec-CH-UA-Full-Version-List, \nSec-CH-UA-Mobile, Sec-CH-UA-Model, Sec-CH-UA-Platform, Sec-CH-UA-Platform-Version, Sec-CH-UA-WoW64\n```\n\nThen the browser will send these headers to any URL of the first-party domain, but not to the third-party domain. \n\nIn order for these headers to be sent to the third-party domain, the first-party server must also specify a `Permissions-Policy` header in the response.  Permissions-Policy enables cross-origin User-Agent Client Hints delegation.\n\nSince 51D UAParser just wraps calls to a third-party service hosted at https://cloud.51degrees.com, you must allow delegating hints to that service.\n\nHere is the `Permissions-Policy` header that must be in your first-party server response (serving the original page content):\n\n```\nPermissions-Policy: ch-ua=(\"https://cloud.51degrees.com\"), ch-ua-arch=(\"https://cloud.51degrees.com\"),  \nch-ua-bitness=(\"https://cloud.51degrees.com\"), ch-ua-mobile=(\"https://cloud.51degrees.com\"), \nch-ua-model=(\"https://cloud.51degrees.com\"), ch-ua-platform=(\"https://cloud.51degrees.com\"), \nch-ua-platform-version=(\"https://cloud.51degrees.com\"), ch-ua-full-version=(\"https://cloud.51degrees.com\"), \nch-ua-full-version-list=(\"https://cloud.51degrees.com\"), ch-ua-wow64=(\"https://cloud.51degrees.com\")\n```\n\n**Note:** `Accept-CH` header must also be set. \n\n### User-Agent Client Hints Delegation in HTML\nAlternatively (in case you can't modify your server headers), you can provide a <meta http-equiv=\"Delegate-CH\"> tag in the page header: \n\n```html\n<meta http-equiv=\"Delegate-CH\" content=\"Sec-CH-UA-Model https://cloud.51degrees.com; \nSec-CH-UA https://cloud.51degrees.com; Sec-CH-UA-Arch https://cloud.51degrees.com; \nSec-CH-UA-Full-Version https://cloud.51degrees.com; Sec-CH-UA-Mobile https://cloud.51degrees.com; \nSec-CH-UA-Platform https://cloud.51degrees.com; Sec-CH-UA-Platform-Version https://cloud.51degrees.com\" />\n```\n\n\n","licenseText":"MIT License\n\nCopyright (c) 2023 51Degrees <support@51degrees.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"@51degrees/ua-parser-js@2.0.2","dist":{"shasum":"e62f6236fe2f991fb034e46667e0c1bde1135c1b","integrity":"sha512-Wk39TUWfH0anxKSMwDkCo/0bmIGXXrXksI4Bb3yYxMtBQU5/JH0IebOjEOnWat5KQIVaP54J4/PQhp6ALxPKSw==","tarball":"https://registry.npmjs.org/@51degrees/ua-parser-js/-/ua-parser-js-2.0.2.tgz","fileCount":35,"unpackedSize":77689,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCirE0qZ+3rOVK5K9rK6e5VlPA8iLsw9qYEA0OKB0DlSwIhANJsMqOaDGVl7jEZIBAv2IlrS1N/N2fOnkYbvNTxhMoq"}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj751qACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpu3Q/+JIGuz5otefFMrwUXm0j6b8a0N18Ork7bKxh6gFCt3tuWw6t0\r\nSVGCn/bzyXDqBdoKmoQ36ZVoEksjcyk6vHdjkDBGCUu99PtPrY7HGFgneeVC\r\nBnq7doFrZSZhLQVxRHgU6ttYa2eW02X6Sgp7jxyQMEos+mEe07pylrNjAYCO\r\nvRBiGkUg1MsTX48aeNJ97MKRdvvrxUsvS4l5YBemlAO3JUiq3lDIX2JgTj64\r\n7uwn1o9TZrnBc+NqJuLxYwfQsPm3FUtYi3bCmocM+VSGta/Sjd8awm3QM9P3\r\nRpEjxajlYUO/Bs5h+DaxujwXBxbJqtxDjidC2PxmjcmUNa3Me6tacxspABaL\r\nazAq0aXHXmq+/fCSs6Z6i+VEzq811Rjp42GwS54/hfIrJ2MJ2wlwAvc56mko\r\nk/hvjAXSU9cB9d4ZTKKDyLbp4uDLp+tYsVgBMO14diZErwfhEINW/wRtDK5B\r\nzN+l7pUq7AFkFiTePs0dNnEBqalIqktfLiE0tUUEqgJrnmyoUgONMVk3hhUm\r\nBzXvDIUXBcdxUMtuFPaHMJEK+8hGZsYbSgAtktoG8XdZoR41wBWOHpzUPxfn\r\nUAe3WJnAyrCT5UT+JmxLWqL0BbEe8CZKfUnotEgGJT//hJCjtn3keLTeTv4C\r\n7qoYxcLRXnB8UU6Y0uJqucUfY6KaDURXSjg=\r\n=9fFw\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"roman.s","email":"roman.sertsov@postindustria.com"},"directories":{},"maintainers":[{"name":"roman.s","email":"roman.sertsov@postindustria.com"},{"name":"eugenedorfman","email":"eugene.dorfman@postindustria.com"},{"name":"51d","email":"support@51degrees.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/ua-parser-js_2.0.2_1676647786575_0.8821039092155014"},"_hasShrinkwrap":false},"2.0.3":{"name":"@51degrees/ua-parser-js","version":"2.0.3","description":"User-Agent and User Agent Client Hints parser. Supports the latest Chromium browsers and Apple model detection.","download":"https://raw.github.com/51Degrees/ua-parser-js/main/lib/ua-parser.min.js","main":"lib/ua-parser.js","types":"lib/types/UAParser.d.ts","repository":{"type":"git","url":"https://github.com/51Degrees/ua-parser-js.git"},"homepage":"https://51degrees.github.io/ua-parser-js/","demo":"https://51Degrees.github.io/ua-parser-js","license":"MIT","devDependencies":{"@babel/cli":"^7.20.7","@babel/preset-env":"^7.20.2","@babel/preset-typescript":"^7.18.6","@rollup/plugin-babel":"^6.0.3","@rollup/plugin-node-resolve":"^15.0.1","@rollup/plugin-terser":"^0.2.0","@rollup/plugin-typescript":"^10.0.1","@types/jest":"^29.2.4","babel-plugin-add-module-exports":"^1.0.4","cross-env":"^7.0.3","dotenv":"^16.0.3","jest":"^29.3.1","jest-environment-jsdom":"^29.3.1","jest-puppeteer":"^6.2.0","npm-run-all":"^4.1.5","prettier":"^2.8.1","puppeteer":"^19.5.0","rimraf":"^3.0.2","rollup":"^2.78","ts-jest":"^29.0.3","tslint":"^6.1.3","tslint-config-prettier":"^1.18.0","typescript":"^4.9.4"},"scripts":{"clean":"rimraf lib","declarations":"tsc -p tsconfig.json","server:start":"node server.js fg","server:stop":"node server.stop.js fg","test":"jest --config jestconfig.json --runInBand --verbose --detectOpenHandles --forceExit","format":"prettier --write \"src/**/*.ts\"","lint":"tslint -p tsconfig.json","build:bundles":"cross-env BABEL_ENV=esmBundled rollup -c","build":"npm-run-all -l clean -p build:bundles declarations","start":"node server.js"},"engines":{"node":">=10.0.0"},"bugs":{"url":"https://github.com/51Degrees/ua-parser-js/issues"},"keywords":["device detection","User Agent Client Hints","Client Hints","UA-CH","CH-UA","User-Agent","UAParser"],"author":{"name":"Roman Sertsov","email":"roman.sertsov@postindustria.com"},"licenseText":"MIT License\n\nCopyright (c) 2023 51Degrees <support@51degrees.com>\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n","_id":"@51degrees/ua-parser-js@2.0.3","dist":{"shasum":"5ee2606fbccb176e0aefb76ce1edc3319270f604","integrity":"sha512-GCiDLvLIdpVGW394CFE4hJtykQyHPhU2kx9kRauM9m2RFuqXJr4iitgfspg2REuVcpRXbWi20AqDB8PFo20RwA==","tarball":"https://registry.npmjs.org/@51degrees/ua-parser-js/-/ua-parser-js-2.0.3.tgz","fileCount":35,"unpackedSize":77633,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAy6ivbeIuFKvs/Pawydufx6tUqezvFGv7hI6v908oxRAiBXHL2/AfevXF2psZRpajWpw+6FC1YmEQTpiTA9RTynQQ=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj76eBACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqRhg//fgB1CX/Xzpr/k2JDk8PQ8CcuxWhfa88/gN4v7R/4L94S0EUY\r\nmtl9TfHcLwJXMMSXAoWUflnjOgifMUelCVFMQdEg2y2rQcJSg0HSlTHR4Mtz\r\nkn+EmM8g44BTaOIzP5hmZgQh6b1Fq7SJ9FHdy5FdADSJzBePMwTByxjk7ndI\r\nSi+eaV4s62Y1xITr0Qf5RAZe1b/YF5hdQ9plj3xzOxeUOL/Ly815PoAipCDD\r\nAEwRF8pVL5Xu00Iqdmb3D7GwSME2pMSWP+yL23DDK78Z0Ai21stK0IlwvItl\r\nmQskVoCV52PvePIpnSn467Zs5KrtOmhAAnkAd1xylCD+z0g+8q/NodUIb8dY\r\nMfwqvuT0T33XbPdAFCh05WcKmKUVKBmrDuIw9rBxSl3goVvqBv3VKfbgu+Z9\r\nZtLmhZQ6lzyiibUbkvbVLc6yx7h5q9vHRZA1d94uJIbt3ZMN42EvzgtJj+10\r\n+L+POTDYqZn2QexH+6JjJ8fGO9jvG5KlxOECTpL7vD6X3JsOWPpG5TSzfqxp\r\nC/5mkLg+CQDCuZYpOR0tHKjj1hFkDn8T2yRAni4rBXWT8c0FcnVoaOV2OqNj\r\nt9kvVJZGVooTYoBBQcwkvXEYl04o18XzJus86vam8y7fN/5f/pUOwYP1++Yu\r\nGQMjc2Zr+v+6La78CqYIp0wrz5WF4L3upoA=\r\n=Z3So\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"roman.s","email":"roman.sertsov@postindustria.com"},"directories":{},"maintainers":[{"name":"roman.s","email":"roman.sertsov@postindustria.com"},{"name":"eugenedorfman","email":"eugene.dorfman@postindustria.com"},{"name":"51d","email":"support@51degrees.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/ua-parser-js_2.0.3_1676650369468_0.24907345111240398"},"_hasShrinkwrap":false}},"time":{"created":"2023-02-09T17:09:32.407Z","2.0.0":"2023-02-09T17:09:32.790Z","modified":"2023-02-17T16:12:49.809Z","2.0.1":"2023-02-17T14:34:51.094Z","2.0.2":"2023-02-17T15:29:46.737Z","2.0.3":"2023-02-17T16:12:49.670Z"},"maintainers":[{"name":"roman.s","email":"roman.sertsov@postindustria.com"},{"name":"eugenedorfman","email":"eugene.dorfman@postindustria.com"},{"name":"51d","email":"support@51degrees.com"}],"description":"User-Agent and User Agent Client Hints parser. Supports the latest Chromium browsers and Apple model detection.","homepage":"https://51degrees.github.io/ua-parser-js/","keywords":["device detection","User Agent Client Hints","Client Hints","UA-CH","CH-UA","User-Agent","UAParser"],"repository":{"type":"git","url":"https://github.com/51Degrees/ua-parser-js.git"},"author":{"name":"Roman Sertsov","email":"roman.sertsov@postindustria.com"},"bugs":{"url":"https://github.com/51Degrees/ua-parser-js/issues"},"license":"MIT","readme":"<!--p align=\"center\">\n    <img src=\"https://raw.githubusercontent.com/faisalman/ua-parser-js/gh-pages/images/logo.png\" width=\"256\" height=\"256\"> \n</p>\n\n<p align=\"center\">\n<a href=\"https://travis-ci.org/faisalman/ua-parser-js\"><img src=\"https://travis-ci.org/faisalman/ua-parser-js.svg?branch=master\"></a>\n<a href=\"https://www.npmjs.com/package/ua-parser-js\"><img src=\"https://img.shields.io/npm/v/ua-parser-js.svg\"></a>\n<a href=\"https://www.npmjs.com/package/ua-parser-js\"><img src=\"https://img.shields.io/npm/dw/ua-parser-js.svg\"></a>\n<a href=\"https://www.jsdelivr.com/package/npm/ua-parser-js\"><img src=\"https://data.jsdelivr.com/v1/package/npm/ua-parser-js/badge\"></a>\n<a href=\"https://cdnjs.com/libraries/UAParser.js\"><img src=\"https://img.shields.io/cdnjs/v/UAParser.js.svg\"></a>\n</p-->\n# 51Degrees UAParser\n\nA lightweight JavaScript library wrapping [51Degrees Device Detection](https://51degrees.com/device-detection) cloud service.  The library provides comprehensive device data based on User-Agent Client Hints and/or the User-Agent.  This package can be used either in a browser (client-side) or in Node.js environment (server-side).  Client-side supports detection of the current client or detection from an arbitrary header map, while server-side supports detection from a header map only.  \n\nThis is a fork of a popular [UAParser.js](https://github.com/faisalman/ua-parser-js) library that relied solely on a deprecated User-Agent for the local device detection.  The current library allows for an easy migration from the original UAParser.js.\n\nFor a more sophisticated solution, check out 51Degrees Device Detection Node Package: https://www.npmjs.com/package/fiftyone.devicedetection \n\n* Author    : Roman Sertsov <roman.sertsov@postindustria.com>\n* Demo      : https://51degrees.github.io/ua-parser-js\n* Source    : https://github.com/51Degrees/ua-parser-js\n\n# Documentation\n\n## Usage\n\nYou can use 51D UAParser in 3 easy steps.\n\n1. **Install the package** using `npm` or other dependency manager such as `yarn`:\n```\nnpm i @51degrees/ua-parser-js\n```\n\n2. **Register and configure a Resource Key** to use with 51Degrees Cloud service [here](https://configure.51degrees.com/S6fGMDKw) - you will need it as a required parameter to pass to UAParser function.\n\n3. **Integrate the device detection code.**  Below there are usage examples for the client and server side:\n\n### Client side (HTML)\nPlease note the `<meta http-equiv=\"Delegate-CH\">` tag needed for the [User-Agent Client Hints delegation](#user-agent-client-hints-delegation).\n\n```html\n<!doctype html>\n<html>\n<head>\n\n    <!-- note the meta tag for User-Agent Client Hint delegation -->\n    <meta http-equiv=\"Delegate-CH\" content=\"Sec-CH-UA-Model https://cloud.51degrees.com; \n    Sec-CH-UA https://cloud.51degrees.com; Sec-CH-UA-Arch https://cloud.51degrees.com; \n    Sec-CH-UA-Full-Version https://cloud.51degrees.com; Sec-CH-UA-Mobile https://cloud.51degrees.com; \n    Sec-CH-UA-Platform https://cloud.51degrees.com; Sec-CH-UA-Platform-Version https://cloud.51degrees.com\" />\n\n    <script src=\"/path/to/@51degrees/ua-parser.min.js>\"></script>\n\n    <script type=\"module\">  \n        // note the type=\"module\" to use the top-level await\n        // this code can also live in a standalone mjs file\n\n        // helper function:\n        function formatDevice (device, sep=\"<br />\") {\n            return [\"DeviceType\", \n              \"PlatformVendor\", \n              \"PlatformName\", \n              \"PlatformVersion\", \n              \"BrowserVendor\", \n              \"BrowserName\", \n              \"BrowserVersion\", \n              \"LayoutEngine\", \n              \"HardwareName\", \n              \"HardwareModel\", \n              \"HardwareVendor\"]\n            // note that device property names are in lower case\n            .map( key => key + \": \" + device[key.toLowerCase()]) \n            .join(sep)\n        }\n\n\n        // obtain a Resource Key at https://configure.51degrees.com/S6fGMDKw\n        const rk = \"<your resource key>\"; \n\n        let result = await UAParser(rk);  // note the top-level await\n        let device = result.device;\n        console.log(device); \n        document.body.innerHTML = formatDevice(device);\n    </script>\n</head>\n<body>\n</body>\n</html>\n```\n\n### Server-side (Node.js)\nThis is a CommonJS example, to use a top-level `await` you need to use [ECMAScript Modules](https://nodejs.org/api/esm.html#modules-ecmascript-modules). \n\nAn example of processing an arbitrary header map on the server:\n```js\n\nconst rk = \"<your resource key>\"; // obtain a Resource Key at https://configure.51degrees.com/S6fGMDKw\n\n// an example of processing an arbitrary header map:\nconst context = async () => {\n  const result = await UAParser(rk,{\n    \"sec-ch-ua\":\n      \"Not_A Brand;v=99, Google Chrome;v=109, Chromium;v=109\",\n    \"sec-ch-ua-arch\": \"x64\",\n    \"sec-ch-ua-full-version\": \"109.0.5414.87\",\n    \"sec-ch-ua-platform\": \"macOS\",\n    \"sec-ch-ua-platform-version\": \"12.2.1\",\n    \"user-agent\":\n      \"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36\",\n  })\n  console.log(result.device)\n}\ncontext().then();\n```\n\nAn example of processing client HTTP headers received by the server:\n```js\nvar http = require('http');\nhttp.createServer(async function (req, res) {\n\n  let result = await UAParser(rk,  req.headers);\n  \n  // a list of useful client hints to obtain from the browser\n  ch = 'Sec-CH-UA, Sec-CH-UA-Arch, Sec-CH-Bitness, Sec-CH-UA-Full-Version, \\\n        Sec-CH-UA-Full-Version-List, Sec-CH-UA-Mobile, Sec-CH-UA-Model, Sec-CH-UA-Platform, \\\n        Sec-CH-UA-Platform-Version, Sec-CH-UA-WoW64'\n\n  // requesting UA-CH\n  res.setHeader('Accept-CH', ch)   \n  // asking the browser to do an immediate repetition of the request with the UA-CH sent, \n  // before rendering the page, so we can send a more detailed data in the response\n  res.setHeader('Critical-CH',ch)  \n\n  res.end(JSON.stringify(result.device));\n})\n.listen(1337, '127.0.0.1');\nconsole.log('Server running at http://localhost:1337/');\n```\n### Using TypeScript\n\nTypeScript is supported natively, just use a regular import syntax in TS:\n```js\nimport UAParser from '@51degrees/ua-parser-js';\n```\n\n## API\n```js\nlet result = await UAParser(resource-key[,header map])\n```\n\n- typeof `resource-key` is `string`\n- typeof `header map` is `Map`\n\nUAParser returns a Promise object that resolves to the [Result](#result-object) object.\n\nResource Key is a required parameter. **You must create and [configure a Resource Key](https://configure.51degrees.com/S6fGMDKw).** \n\n**Note:** Following [this link to create a Resource Key](https://configure.51degrees.com/S6fGMDKw) will prepopulate your Key with the recommended minimum properties. The properties included are:\n- `IsMobile`\n- `HardwareVendor`\n- `HardwareModel`\n- `HardwareName`\n- `PlatformVendor`\n- `PlatformName`\n- `PlatformVersion`\n- `LayoutEngine`\n- `BrowserVendor`\n- `BrowserName`\n- `BrowserVersion`\n- `JavascriptHardwareProfile` – the Resource Key must contain the `JavascriptHardwareProfile` property in order to do a reliable detection of Apple devices.\n- `DeviceType`\n- `SetHeaderBrowserAccept-CH`\n- `SetHeaderHardwareAccept-CH`\n- `SetHeaderPlatformAccept-CH`\n\nOther properties are available, but may require the purchase of a [51Degrees pricing plan](https://51degrees.com/pricing). Follow [this guide](https://51degrees.com/documentation/_concepts__configurator.html) to create a Key from scratch if needed. \n\nIn the browser environment you don't need to pass the header map object containing either User-Agent or User-Agent Client Hints.  If not passed 51D UAParser will detect the current device which is executing the script.  \n\nIn the server-side environment the header map is a required parameter. You must pass User-Agent Client Hints and/or the User-Agent as part of it, or simply all headers from the request `request.headers` received by the server - it should contain the needed ones. \n\n**Note** the `await` keyword.  Since the 51D UAParser uses a cloud service internally, the API is inherently asynchronous.\n\n**Note** that for the current client detection in the browser you must implement [User-Agent Client Hints Delegation](#user-agent-client-hints-delegation) either via Permission-Policy header or `<meta http-equiv=\"Delegate-CH\">` tag.\n\n### Result object\nResult object contains the `device` object with all the detected device properties:\n```\nresult.device\n```\n51Degrees maintains the [rigid data model](http://51degrees.com/developers/property-dictionary).  The device data is maintained by a professional team of data analysts and is updated daily Monday through Thursday. \n\n## Migration from original UAParser.js\n\nThe migration from the original [UAParser.js](https://github.com/faisalman/ua-parser-js) comes down to the following steps:\n1. For Node.js: replace the package name from `ua-parser-js` to `@51degrees/ua-parser-js`. For the browser provide the correct path in the src attribute to the new `@51degrees/ua-parser.min.js`. \n2. Call `UAParser` as an `async` function with the `await` keyword, or use `then` to await the Promise.\n3. Use a Resource Key to configure custom device fields. A guide to create this Key can be found [here](https://51degrees.com/documentation/_concepts__configurator.html)\n4. Pass the `header map` containing User-Agent Client Hints headers, instead of the User-Agent string as a parameter.\n5. For the client side / html integration - implement either Accept-CH + Permission-Policy headers on your server or Delegate-CH http-equiv meta tag in order to delegate User-Agent Client Hints to 51Degrees Cloud service as described [here](#user-agent-client-hints-delegation).\n\nThis call\n```js\n    let result = UAParser([user-agent][,extension])\n```\nnow becomes:\n```js\n    let result = await UAParser(resource-key[,header map])\n```\nMake sure the code is running within the async context (async function) or within the ECMAScript module context where top-level `await` is supported.\n\n6. Refrain from using the old UAParser constructor (`new UAParser`) - this approach has been deprecated.  `UAParser` now returns a Promise, that must be `await`ed or `then`ed - thus constructing an object does not make sense.\n\n### Deprecations\n1. Constructor (a call to `new UAParser`) is no longer supported.\n2. Methods `setUA()`, `getUA()`, and `getResult()` are no longer supported and will throw if called on the UAParser Promise object. \n\n### Original UAParser properties mapping\nTo support existing code we made an effort to map the 51Degrees data model to that of the original [UAParser.js](https://github.com/faisalman/ua-parser-js) data model:\n```js\n{\n    ua: '',\n    browser: { name: '', version: '' },\n    cpu: { architecture: '' },\n    device: { model: '', type: '', vendor: '' },\n    engine: { name: '', version: '' },\n    os: { name: '', version: '' }\n}\n```\n\nThe current library makes the best effort to map 51Degrees values to the original value ranges provided by UAParser.js to minimize breaking changes in the updated code. \n\n\n### New data points\n\nBesides maintaining the mappings to the original UAParser properties, 51Degrees significantly expands the set of available data points.  Data points are made available dynamically depending on the Resource Key configuration.  All the data points are keyed as lower case properties within the `device` property of the `result` object, see an example `result` object below:\n\n```js\n{\n    ...\n    device: {\n        batterycapacity: 2770,\n        devicetype: \"SmartPhone\",\n        hardwaremodel: \"Pixel\",\n        hardwarename: [\n            \"Pixel\"\n        ],\n        hardwarerank: 1524,\n        hardwarevendor: \"Google\",\n        hasremovablebattery: false,\n        ismobile: true,\n        supportedchargertypes: [\n            \"Qualcomm Quick Charge 3.0\",\n            \"Wire\"\n        ],\n        model: \"Pixel\",  //original property\n        type: \"mobile\",  //original property\n        vendor: \"Google\" //original property\n    },\n    ...\n}\n```\n\nPlease refer to the [51Degrees Configurator](https://configure.51degrees.com) for a full list of the data points available.\n\n\n## User-Agent Client Hints Delegation\n\nMigrating to User-Agent Client Hints for your web app is well described in many sources, for example, this WICG [draft report on UA-CH](https://wicg.github.io/ua-client-hints/) or this human-readable [article](https://web.dev/migrate-to-ua-ch/).\n\nAny request the web browser sends contains the so-called low-entropy User-Agent Client Hints, namely these three:\n- `Sec-CH-UA`\n- `Sec-CH-UA-Mobile`\n- `Sec-CH-UA-Platform`\n\nTo request additional high-entropy UA-CH headers one must specify them in the `Accept-CH` header, this will tell the browser to send them in the subsequent request to the first-party server.  \n```\nAccept-CH: Sec-CH-UA, Sec-CH-UA-Arch, Sec-CH-Bitness, Sec-CH-UA-Full-Version, Sec-CH-UA-Full-Version-List, \nSec-CH-UA-Mobile, Sec-CH-UA-Model, Sec-CH-UA-Platform, Sec-CH-UA-Platform-Version, Sec-CH-UA-WoW64\n```\n\nThen the browser will send these headers to any URL of the first-party domain, but not to the third-party domain. \n\nIn order for these headers to be sent to the third-party domain, the first-party server must also specify a `Permissions-Policy` header in the response.  Permissions-Policy enables cross-origin User-Agent Client Hints delegation.\n\nSince 51D UAParser just wraps calls to a third-party service hosted at https://cloud.51degrees.com, you must allow delegating hints to that service.\n\nHere is the `Permissions-Policy` header that must be in your first-party server response (serving the original page content):\n\n```\nPermissions-Policy: ch-ua=(\"https://cloud.51degrees.com\"), ch-ua-arch=(\"https://cloud.51degrees.com\"),  \nch-ua-bitness=(\"https://cloud.51degrees.com\"), ch-ua-mobile=(\"https://cloud.51degrees.com\"), \nch-ua-model=(\"https://cloud.51degrees.com\"), ch-ua-platform=(\"https://cloud.51degrees.com\"), \nch-ua-platform-version=(\"https://cloud.51degrees.com\"), ch-ua-full-version=(\"https://cloud.51degrees.com\"), \nch-ua-full-version-list=(\"https://cloud.51degrees.com\"), ch-ua-wow64=(\"https://cloud.51degrees.com\")\n```\n\n**Note:** `Accept-CH` header must also be set. \n\n### User-Agent Client Hints Delegation in HTML\nAlternatively (in case you can't modify your server headers), you can provide a <meta http-equiv=\"Delegate-CH\"> tag in the page header: \n\n```html\n<meta http-equiv=\"Delegate-CH\" content=\"Sec-CH-UA-Model https://cloud.51degrees.com; \nSec-CH-UA https://cloud.51degrees.com; Sec-CH-UA-Arch https://cloud.51degrees.com; \nSec-CH-UA-Full-Version https://cloud.51degrees.com; Sec-CH-UA-Mobile https://cloud.51degrees.com; \nSec-CH-UA-Platform https://cloud.51degrees.com; Sec-CH-UA-Platform-Version https://cloud.51degrees.com\" />\n```\n\n\n","readmeFilename":"README.md"}