bt-sensors-plugin-sk 1.2.0-beta.0.1.5 → 1.2.0

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/index.js CHANGED
@@ -88,7 +88,7 @@ class MissingSensor {
88
88
 
89
89
  }
90
90
  module.exports = function (app) {
91
- var deviceConfigs
91
+ var deviceConfigs=[]
92
92
  var starts=0
93
93
 
94
94
  var plugin = {};
@@ -100,6 +100,9 @@ module.exports = function (app) {
100
100
 
101
101
  plugin.schema = {
102
102
  type: "object",
103
+ htmlDescription:
104
+ `<h2><a href="https://github.com/naugehyde/bt-sensors-plugin-sk/tree/1.2.0-beta#configuration" target="_blank">Plugin Documenation</a><p/><a href="https://github.com/naugehyde/bt-sensors-plugin-sk/issues/new/choose" target="_blank">Report an issue</a><p/><a href="https://discord.com/channels/1170433917761892493/1295425963466952725" target="_blank">Discord thread</a></h2>
105
+ `,
103
106
  required:["adapter","discoveryTimeout", "discoveryInterval"],
104
107
  properties: {
105
108
  adapter: {title: "Bluetooth adapter",
@@ -130,21 +133,6 @@ module.exports = function (app) {
130
133
  const classMap = loadClassMap(app)
131
134
  const sensorMap=new Map()
132
135
 
133
-
134
- /* plugin.registerWithRouter = function(router) {
135
- router.get('/sendPluginState', async (req, res) => {
136
-
137
- res.status(200).json({
138
- "state":(plugin.started?"started":"stopped")
139
- })
140
- });
141
- router.get("/sse", async (req, res) => {
142
- const session = await createSession(req, res);
143
- channel.register(session)
144
- });
145
-
146
- }*/
147
-
148
136
  plugin.start = async function (options, restartPlugin) {
149
137
  plugin.started=true
150
138
  var adapterID=options.adapter
@@ -276,6 +264,7 @@ module.exports = function (app) {
276
264
 
277
265
  function getSensorInfo(sensor){
278
266
 
267
+
279
268
  return { mac: sensor.getMacAddress(),
280
269
  name: sensor.getName(),
281
270
  domain: sensor.getDomain().name,
@@ -287,9 +276,11 @@ module.exports = function (app) {
287
276
 
288
277
  function sensorToJSON(sensor){
289
278
  const config = getDeviceConfig(sensor.getMacAddress())
279
+ const schema = sensor.getJSONSchema()
280
+ schema.htmlDescription = sensor.getDescription()
290
281
  return {
291
282
  info: getSensorInfo(sensor),
292
- schema: sensor.getJSONSchema(),
283
+ schema: schema,
293
284
  config: config?config:{}
294
285
  }
295
286
  }
@@ -329,8 +320,7 @@ module.exports = function (app) {
329
320
 
330
321
  function addSensorToList(sensor){
331
322
  app.debug(`adding sensor to list ${sensor.getMacAddress()}`)
332
- if (sensorMap.has(sensor.getMacAddress()) )
333
- debugger
323
+
334
324
  sensorMap.set(sensor.getMacAddress(),sensor)
335
325
  channel.broadcast(sensorToJSON(sensor),"newsensor");
336
326
  }
@@ -349,8 +339,9 @@ module.exports = function (app) {
349
339
  return
350
340
  }
351
341
  s = await instantiateSensor(device,config)
352
- //app.debug(`Instantiated ${config.mac_address}`)
353
-
342
+ if (!s)
343
+ reject("Unable to create sensor")
344
+ else
354
345
  if (s instanceof BLACKLISTED)
355
346
  reject ( `Device is blacklisted (${s.reasonForBlacklisting()}).`)
356
347
  else{
@@ -383,45 +374,47 @@ module.exports = function (app) {
383
374
  }
384
375
  function getDeviceConfig(mac){
385
376
  return deviceConfigs.find((p)=>p.mac_address==mac)
386
- }
387
- async function instantiateSensor(device,config){
388
- try{
377
+ }
378
+ async function getClassFor(device,config){
379
+
380
+ if (config.params?.sensorClass){
381
+ const c = classMap.get(config.params.sensorClass)
382
+ if (c==null)
383
+ throw new Error ("Cannot find class "+config.params.sensorClass)
384
+ return c
385
+ }
389
386
  for (var [clsName, cls] of classMap) {
390
387
  if (clsName.startsWith("_")) continue
391
388
  const c = await cls.identify(device)
392
389
  if (c) {
393
- c.debug=app.debug
394
- const sensor = new c(device,config?.params, config?.gattParams)
395
- sensor.debug=app.debug
396
- sensor.app=app
397
- sensor._adapter=adapter //HACK!
398
-
399
- await sensor.init()
400
- //app.debug(`instantiated ${await BTSensor.getDeviceProp(device,"Address")}`)
401
-
402
- return sensor
390
+ if (Object.hasOwn(config, "params")) {
391
+ config.params.sensorClass=clsName
392
+ }
393
+ return c
403
394
  }
404
- }} catch(error){
395
+ }
396
+ return classMap.get('UNKNOWN')
397
+ }
398
+
399
+ async function instantiateSensor(device,config){
400
+ try{
401
+ const c = await getClassFor(device,config)
402
+ c.debug=app.debug
403
+ const sensor = new c(device, config?.params, config?.gattParams)
404
+ sensor.debug=app.debug
405
+ sensor.app=app
406
+ sensor._adapter=adapter //HACK!
407
+ await sensor.init()
408
+ return sensor
409
+ }
410
+ catch(error){
405
411
  const msg = `Unable to instantiate ${await BTSensor.getDeviceProp(device,"Address")}: ${error.message} `
406
412
  app.debug(msg)
407
413
  app.debug(error)
408
414
  app.setPluginError(msg)
415
+ return null
409
416
  }
410
- //if we're here ain't got no class for the device
411
- var sensor
412
- if (config.params?.sensorClass){
413
- var c = classMap.get(config.params.sensorClass)
414
- } else{
415
- c = classMap.get('UNKNOWN')
416
- }
417
- c.debug=app.debug
418
- sensor = new c(device,config?.params, config?.gattParams)
419
- sensor.debug=app.debug
420
- sensor.app=app
421
- sensor._adapter=adapter //HACK!
422
-
423
- await sensor.init()
424
- return sensor
417
+
425
418
  }
426
419
 
427
420
  function initConfiguredDevice(deviceConfig){
@@ -478,7 +471,7 @@ module.exports = function (app) {
478
471
 
479
472
  if (!deviceConfig) {
480
473
  deviceConfig = {mac_address: mac,
481
- discoveryTimeout: discoveryTimeout*1000,
474
+ discoveryTimeout: discoveryTimeout,
482
475
  active: false, unconfigured: true}
483
476
  initConfiguredDevice(deviceConfig)
484
477
  }
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "bt-sensors-plugin-sk",
3
- "version": "1.2.0-beta.0.1.5",
3
+ "version": "1.2.0",
4
4
  "description": "Bluetooth Sensors for Signalk -- support for Victron devices, RuuviTag, Xiaomi, ATC and Inkbird, Ultrasonic wind meters, Mopeka tank readers, Renogy Battery and Solar Controllers, Aranet4 environment sensors, SwitchBot temp and humidity sensors, KilovaultHLXPlus smart batteries, and Govee GVH51xx temp sensors",
5
5
  "main": "index.js",
6
6
  "dependencies": {
7
- "@rjsf/core": "^5.24.8",
8
- "@rjsf/utils": "^5.24.8",
9
- "@rjsf/validator-ajv8": "^5.24.8",
7
+ "@rjsf/bootstrap-4": "^5.24.11",
8
+ "@rjsf/core": "^5.24.11",
9
+ "@rjsf/utils": "^5.24.11",
10
+ "@rjsf/validator-ajv8": "^5.24.11",
10
11
  "better-sse": "^0.14.1",
11
12
  "dbus-next": "^0.10.2",
12
13
  "int24": "^0.0.1",
@@ -23,7 +24,6 @@
23
24
  "@fortawesome/react-fontawesome": "^0.2.2",
24
25
  "@material-ui/core": "^4.12.4",
25
26
  "@material-ui/icons": "^4.11.3",
26
- "@signalk/server-admin-ui-dependencies": "^1.0.0",
27
27
  "babel-loader": "^8.1.0",
28
28
  "chai": "^4.2.0",
29
29
  "css-loader": "^5.0.0",
@@ -33,7 +33,8 @@
33
33
  "mocha": "^8.0.1",
34
34
  "prettier-standard": "^6.0.0",
35
35
  "react": "^16.13.1",
36
- "react-bootstrap": "^2.10.9",
36
+ "react-html-parser":"^2.0.2",
37
+ "react-bootstrap": "^1.6.5",
37
38
  "react-dom": "^16.13.1",
38
39
  "react-markdown": "^4.3.1",
39
40
  "react-redux": "^5.1.2",
@@ -1,45 +1,52 @@
1
1
  {
2
2
  "params":{
3
3
  "name":{
4
+ "title": "Name",
4
5
  "description": "Sensor name"
5
6
  },
6
7
  "location":{
7
- "description": "Sensor location",
8
+ "title": "Location",
9
+ "description": "Sensor location on boat",
8
10
  "examples": ["inside", "outside", "galley", "freezer", "refrigerator", "head", "cabin", "engine", "deck", "cockpit"]
9
11
  },
10
12
  "zone":{
13
+ "title":"Zone",
11
14
  "description": "Zone where sensor operates on boat AKA location ",
12
15
  "examples": ["inside", "outside", "galley", "freezer", "refrigerator", "head", "cabin", "engine", "deck", "cockpit"]
13
16
  },
14
17
  "batteryID":{
15
- "description": "Battery ID",
18
+ "title": "Battery ID",
16
19
  "examples": ["starter", "house"]
17
20
  },
18
21
  "id":{
22
+ "title": "ID",
19
23
  "description": "Sensor ID"
20
24
  }
21
25
  },
22
26
  "environment":{
23
27
  "temperature":
24
28
  {
25
- "title":"Current zone's temperature",
29
+ "title": "Temperature",
30
+ "description":"Current zone's temperature",
26
31
  "unit":"K",
27
32
  "default": "environment.{zone}.temperature"
28
33
  },
29
34
  "humidity":
30
35
  {
36
+ "title": "Humidity",
37
+ "description":"Current zone's humidity",
31
38
  "unit":"ratio",
32
39
  "default":"environment.{zone}.humidity"
33
40
  },
34
41
  "relativeHumidity":
35
42
  {
36
- "title":"Current zone's relative humidity",
43
+ "description":"Current zone's relative humidity",
37
44
  "unit":"ratio",
38
45
  "default":"environment.{zone}.relativeHumidity"
39
46
  },
40
47
  "pressure":
41
48
  {
42
- "title": "Current zone's ambient air pressure",
49
+ "description": "Current zone's ambient air pressure",
43
50
  "unit":"Pa",
44
51
  "default":"environment.{zone}.pressure"
45
52
  }
@@ -129,6 +136,7 @@
129
136
  },
130
137
  "batteryStrength":
131
138
  {
139
+ "title": "Battery Strength",
132
140
  "unit":"ratio",
133
141
  "default":"sensors.{macAndName}.battery.strength",
134
142
  "description":"Sensor battery strength"
@@ -136,6 +144,7 @@
136
144
 
137
145
  "batteryVoltage":
138
146
  {
147
+ "title":"Battery Voltage",
139
148
  "unit":"V",
140
149
  "default":"sensors.{macAndName}.battery.voltage",
141
150
  "description":"Sensor battery voltage"
package/public/159.js CHANGED
@@ -1 +1,2 @@
1
- "use strict";(self.webpackChunkbt_sensors_plugin_sk=self.webpackChunkbt_sensors_plugin_sk||[]).push([[159],{62995:(e,t,n)=>{n.r(t),n.d(t,{default:()=>A});var a=n(73490),s=n(74810),o=n(86528),r=n.n(o),l=n(27606),c=n(86452),i=n(3768),u=n(71431),g=n(39676),d=n(47041),m=n(86038),f=n(95027),p=n(43540),h=n(24712),E=n(75056),w=n(96890),S=n(23399);const v=e=>console.log.bind(console,e);var y,b={};const A=e=>{const[t,n]=(0,o.useState)({}),[A,D]=(0,o.useState)({}),[$,_]=(0,o.useState)({}),[k,C]=(0,o.useState)({"ui:submitButtonOptions":{props:{disabled:!1,className:"btn btn-info"},norender:!0,submitText:"Submit"}}),[x,T]=(0,o.useState)([]),[j,M]=(0,o.useState)(),[O,N]=(0,o.useState)(new Map),[B,U]=(0,o.useState)({progress:0,maxTimeout:100,deviceCount:0,totalDevices:0}),[J,L]=(0,o.useState)("unknown"),[P,K]=(0,o.useState)();function z(e,t){console.log(`sending ${e}`),console.log(t);const n=new Headers;return n.append("Content-Type","application/json"),fetch(`/plugins/bt-sensors-plugin-sk/${e}`,{credentials:"include",method:"POST",body:JSON.stringify(t),headers:n})}async function H(e){return console.log(`fetching ${e}`),fetch(`/plugins/bt-sensors-plugin-sk/${e}`,{credentials:"include"})}async function I(){console.log("getProgress");const e=await H("getProgress");if(200!=e.status)throw new Error(`Unable get progres: ${e.statusText} (${e.status}) `);const t=await e.json();return console.log(t),t}function R(){console.log("refreshing sensor map"),async function(){console.log("getSensors");const e=await H("getSensors");if(200!=e.status)throw new Error(`Unable get sensor data: ${e.statusText} (${e.status}) `);const t=await e.json();return console.log(t),t}().then((e=>{N(new Map(e.map((e=>[e.info.mac,e]))))})).catch((e=>{K(e)}))}function W(e){return Object.keys(e.config).length>0}function Y(e){const t=W(e);return r().createElement(w.A,{action:!0,onClick:()=>{e.config.mac_address=e.info.mac,_(e.schema),M(e.config)}},r().createElement("div",{class:"d-flex justify-content-between align-items-center",style:t?{fontWeight:"normal"}:{fontStyle:"italic"}},`${e._changesMade?"*":""}${e.info.name} MAC: ${e.info.mac} RSSI: ${n=e.info.RSSI,null==n?NaN:n}`,r().createElement("div",{class:"d-flex justify-content-between "},function(e){return null==e.info.lastContactDelta||e.info.lastContactDelta>e.config.discoveryTimeout?r().createElement(i.A,null):e.info.signalStrength>80?r().createElement(u.A,null):e.info.signalStrength>60?r().createElement(g.A,null):e.info.signalStrength>40?r().createElement(d.A,null):e.info.signalStrength>20?r().createElement(m.A,null):r().createElement(f.A,null)}(e))));var n}return(0,o.useEffect)((()=>{console.log("useEffect([])");let e=null;return H("getPluginState").then((async t=>{if(404==t.status)throw L("unknown"),new Error("unable to get plugin state");const n=await t.json();console.log("Setting up eventsource"),e=new EventSource("/plugins/bt-sensors-plugin-sk/sse",{withCredentials:!0}),L(n.state),await async function(){console.log("getDomains");const e=await H("getDomains");if(200!=e.status)throw new Error(`Unable get domain data: ${e.statusText} (${e.status}) `);const t=await e.json();return console.log(t),t}(),e.addEventListener("newsensor",(e=>{console.log("newsensor");let t=JSON.parse(e.data);y.has(t.info.mac)||(console.log(`New sensor: ${t.info.mac}`),N(new Map(y.set(t.info.mac,t))))})),e.addEventListener("sensorchanged",(e=>{let t=JSON.parse(e.data);if(console.log("sensorchanged"),console.log(t),y.has(t.mac)){let e=y.get(t.mac);Object.assign(e.info,t),N(new Map(y))}})),e.addEventListener("progress",(e=>{console.log("progress");const t=JSON.parse(e.data);U(t),console.log(t)})),e.addEventListener("pluginstate",(e=>{console.log("pluginstate");const t=JSON.parse(e.data);L(t.state)}))})).catch((e=>{K(e)})),()=>{console.log("Closing connection to SSE"),e.close()}}),[]),(0,o.useEffect)((()=>{console.log("useEffect([pluginState])"),"started"==J?(R(),async function(){console.log("getBaseData");const e=await H("getBaseData");if(200!=e.status)throw new Error(`Unable get base data: ${e.statusText} (${e.status}) `);const t=await e.json();return console.log(t),t}().then((e=>{n(e.schema),D(e.data)})).catch((e=>{K(e)})),I().then((e=>{U(e)})).catch((e=>{K(e)}))):(N(new Map),n({}),D({}))}),[J]),(0,o.useEffect)((()=>{console.log("useEffect([sensorMap])"),y=O;const e=new Set(O.entries().map((e=>e[1].info.domain))),t={_configured:Array.from(O.entries()).filter((e=>W(e[1]))).map((e=>Y(O.get(e[0]))))};e.forEach((e=>{var n;t[e]=(n=e,Array.from(O.entries()).filter((e=>e[1].info.domain===n))).map((e=>Y(O.get(e[0]))))})),b=t}),[O]),"stopped"==J||"unknown"==J?r().createElement("h1",null,"Enable plugin to see configuration (if plugin is Enabled and you're seeing this message, restart SignalK)"):r().createElement("div",null,P?r().createElement("h2",{style:"color: red;"},P):"",r().createElement(a.Ay,{schema:t,validator:s.Ay,onChange:e=>D(e.formData),onSubmit:({formData:e},t)=>{var n;n=e,console.log("updateBaseData"),z("updateBaseData",n).then((e=>{200!=e.status?K(new Error(`Unable to update base data: ${e.statusText} (${e.status})`)):(I().then((e=>{U(e)})).catch((e=>{K(e)})),R())})),_({})},onError:v("errors"),formData:A}),r().createElement("p",null),r().createElement("p",null),B.deviceCount<B.totalDevices?r().createElement(S.A,{max:B.maxTimeout,now:B.progress}):"",r().createElement("h2",null,O.size>0?"Bluetooth Devices - Select to configure":""),r().createElement("h2",null,O.size>0?"(* = sensor has unsaved changes)":""),r().createElement("p",null),r().createElement(h.A,{defaultActiveKey:"_configured",id:"domain-tabs",className:"mb-3"},Object.keys(b).map((e=>{return n=(t=e).slice("_"===t.charAt(0)?1:0),r().createElement(E.A,{eventKey:t,title:n.charAt(0).toUpperCase()+n.slice(1)},r().createElement("div",{style:{paddingBottom:20},class:"d-flex flex-wrap justify-content-start align-items-start"},r().createElement(p.A,{style:{maxHeight:"300px",overflowY:"auto"}},function(e){return b[e]}(t)),r().createElement("div",{style:{paddingLeft:10,paddingTop:10,display:0==Object.keys($).length?"none":""}},r().createElement(a.Ay,{schema:$,validator:s.Ay,uiSchema:k,onChange:e=>{O.get(e.formData.mac_address)._changesMade=!0,M(e.formData)},onSubmit:({formData:e},t)=>{var n;console.log(e),n=e,console.log("updateSensorData"),z("updateSensorData",n).then((e=>{if(200!=e.status)throw new Error(e.statusText);O.get(n.mac_address)._changesMade=!1,O.get(n.mac_address).config=n})),_({}),alert("Changes saved")},onError:v("errors"),formData:j},r().createElement("div",null,r().createElement(l.A,{direction:"row",style:{spacing:5}},r().createElement(c.A,{type:"submit",color:"primary",variant:"contained"},"Save"),r().createElement(c.A,{variant:"contained",onClick:()=>{var e;e=j.mac_address,console.log("undoChanges"),O.get(e)._changesMade=!1,M(O.get(e).config)}},"Undo"),r().createElement(c.A,{variant:"contained",color:"secondary",onClick:e=>{return t=j.mac_address,void(window.confirm(`Delete configuration for ${t}?`)&&function(e){console.log("removeSensorData");try{z("removeSensorData",{mac_address:e}).then((e=>{if(200!=e.status)throw new Error(e.statusText)})),y.delete(e),N(new Map(y)),_({})}catch{}}(t));var t}},"Delete")))))));var t,n}))))}}}]);
1
+ /*! For license information please see 159.js.LICENSE.txt */
2
+ "use strict";(self.webpackChunkbt_sensors_plugin_sk=self.webpackChunkbt_sensors_plugin_sk||[]).push([[159,540],{15287:(e,r,t)=>{var n=t(45228),o="function"==typeof Symbol&&Symbol.for,u=o?Symbol.for("react.element"):60103,c=o?Symbol.for("react.portal"):60106,f=o?Symbol.for("react.fragment"):60107,l=o?Symbol.for("react.strict_mode"):60108,i=o?Symbol.for("react.profiler"):60114,a=o?Symbol.for("react.provider"):60109,s=o?Symbol.for("react.context"):60110,p=o?Symbol.for("react.forward_ref"):60112,y=o?Symbol.for("react.suspense"):60113,d=o?Symbol.for("react.memo"):60115,h=o?Symbol.for("react.lazy"):60116,b="function"==typeof Symbol&&Symbol.iterator;function v(e){for(var r="https://reactjs.org/docs/error-decoder.html?invariant="+e,t=1;t<arguments.length;t++)r+="&args[]="+encodeURIComponent(arguments[t]);return"Minified React error #"+e+"; visit "+r+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var m={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},_={};function g(e,r,t){this.props=e,this.context=r,this.refs=_,this.updater=t||m}function S(){}function k(e,r,t){this.props=e,this.context=r,this.refs=_,this.updater=t||m}g.prototype.isReactComponent={},g.prototype.setState=function(e,r){if("object"!=typeof e&&"function"!=typeof e&&null!=e)throw Error(v(85));this.updater.enqueueSetState(this,e,r,"setState")},g.prototype.forceUpdate=function(e){this.updater.enqueueForceUpdate(this,e,"forceUpdate")},S.prototype=g.prototype;var w=k.prototype=new S;w.constructor=k,n(w,g.prototype),w.isPureReactComponent=!0;var j={current:null},O=Object.prototype.hasOwnProperty,C={key:!0,ref:!0,__self:!0,__source:!0};function $(e,r,t){var n,o={},c=null,f=null;if(null!=r)for(n in void 0!==r.ref&&(f=r.ref),void 0!==r.key&&(c=""+r.key),r)O.call(r,n)&&!C.hasOwnProperty(n)&&(o[n]=r[n]);var l=arguments.length-2;if(1===l)o.children=t;else if(1<l){for(var i=Array(l),a=0;a<l;a++)i[a]=arguments[a+2];o.children=i}if(e&&e.defaultProps)for(n in l=e.defaultProps)void 0===o[n]&&(o[n]=l[n]);return{$$typeof:u,type:e,key:c,ref:f,props:o,_owner:j.current}}function E(e){return"object"==typeof e&&null!==e&&e.$$typeof===u}var P=/\/+/g,x=[];function R(e,r,t,n){if(x.length){var o=x.pop();return o.result=e,o.keyPrefix=r,o.func=t,o.context=n,o.count=0,o}return{result:e,keyPrefix:r,func:t,context:n,count:0}}function A(e){e.result=null,e.keyPrefix=null,e.func=null,e.context=null,e.count=0,10>x.length&&x.push(e)}function I(e,r,t,n){var o=typeof e;"undefined"!==o&&"boolean"!==o||(e=null);var f=!1;if(null===e)f=!0;else switch(o){case"string":case"number":f=!0;break;case"object":switch(e.$$typeof){case u:case c:f=!0}}if(f)return t(n,e,""===r?"."+U(e,0):r),1;if(f=0,r=""===r?".":r+":",Array.isArray(e))for(var l=0;l<e.length;l++){var i=r+U(o=e[l],l);f+=I(o,i,t,n)}else if("function"==typeof(i=null===e||"object"!=typeof e?null:"function"==typeof(i=b&&e[b]||e["@@iterator"])?i:null))for(e=i.call(e),l=0;!(o=e.next()).done;)f+=I(o=o.value,i=r+U(o,l++),t,n);else if("object"===o)throw t=""+e,Error(v(31,"[object Object]"===t?"object with keys {"+Object.keys(e).join(", ")+"}":t,""));return f}function q(e,r,t){return null==e?0:I(e,"",r,t)}function U(e,r){return"object"==typeof e&&null!==e&&null!=e.key?function(e){var r={"=":"=0",":":"=2"};return"$"+(""+e).replace(/[=:]/g,(function(e){return r[e]}))}(e.key):r.toString(36)}function F(e,r){e.func.call(e.context,r,e.count++)}function L(e,r,t){var n=e.result,o=e.keyPrefix;e=e.func.call(e.context,r,e.count++),Array.isArray(e)?M(e,n,t,(function(e){return e})):null!=e&&(E(e)&&(e=function(e,r){return{$$typeof:u,type:e.type,key:r,ref:e.ref,props:e.props,_owner:e._owner}}(e,o+(!e.key||r&&r.key===e.key?"":(""+e.key).replace(P,"$&/")+"/")+t)),n.push(e))}function M(e,r,t,n,o){var u="";null!=t&&(u=(""+t).replace(P,"$&/")+"/"),q(e,L,r=R(r,u,n,o)),A(r)}var N={current:null};function D(){var e=N.current;if(null===e)throw Error(v(321));return e}var T={ReactCurrentDispatcher:N,ReactCurrentBatchConfig:{suspense:null},ReactCurrentOwner:j,IsSomeRendererActing:{current:!1},assign:n};r.Children={map:function(e,r,t){if(null==e)return e;var n=[];return M(e,n,null,r,t),n},forEach:function(e,r,t){if(null==e)return e;q(e,F,r=R(null,null,r,t)),A(r)},count:function(e){return q(e,(function(){return null}),null)},toArray:function(e){var r=[];return M(e,r,null,(function(e){return e})),r},only:function(e){if(!E(e))throw Error(v(143));return e}},r.Component=g,r.Fragment=f,r.Profiler=i,r.PureComponent=k,r.StrictMode=l,r.Suspense=y,r.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED=T,r.cloneElement=function(e,r,t){if(null==e)throw Error(v(267,e));var o=n({},e.props),c=e.key,f=e.ref,l=e._owner;if(null!=r){if(void 0!==r.ref&&(f=r.ref,l=j.current),void 0!==r.key&&(c=""+r.key),e.type&&e.type.defaultProps)var i=e.type.defaultProps;for(a in r)O.call(r,a)&&!C.hasOwnProperty(a)&&(o[a]=void 0===r[a]&&void 0!==i?i[a]:r[a])}var a=arguments.length-2;if(1===a)o.children=t;else if(1<a){i=Array(a);for(var s=0;s<a;s++)i[s]=arguments[s+2];o.children=i}return{$$typeof:u,type:e.type,key:c,ref:f,props:o,_owner:l}},r.createContext=function(e,r){return void 0===r&&(r=null),(e={$$typeof:s,_calculateChangedBits:r,_currentValue:e,_currentValue2:e,_threadCount:0,Provider:null,Consumer:null}).Provider={$$typeof:a,_context:e},e.Consumer=e},r.createElement=$,r.createFactory=function(e){var r=$.bind(null,e);return r.type=e,r},r.createRef=function(){return{current:null}},r.forwardRef=function(e){return{$$typeof:p,render:e}},r.isValidElement=E,r.lazy=function(e){return{$$typeof:h,_ctor:e,_status:-1,_result:null}},r.memo=function(e,r){return{$$typeof:d,type:e,compare:void 0===r?null:r}},r.useCallback=function(e,r){return D().useCallback(e,r)},r.useContext=function(e,r){return D().useContext(e,r)},r.useDebugValue=function(){},r.useEffect=function(e,r){return D().useEffect(e,r)},r.useImperativeHandle=function(e,r,t){return D().useImperativeHandle(e,r,t)},r.useLayoutEffect=function(e,r){return D().useLayoutEffect(e,r)},r.useMemo=function(e,r){return D().useMemo(e,r)},r.useReducer=function(e,r,t){return D().useReducer(e,r,t)},r.useRef=function(e){return D().useRef(e)},r.useState=function(e){return D().useState(e)},r.version="16.14.0"},45228:e=>{var r=Object.getOwnPropertySymbols,t=Object.prototype.hasOwnProperty,n=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var r={},t=0;t<10;t++)r["_"+String.fromCharCode(t)]=t;if("0123456789"!==Object.getOwnPropertyNames(r).map((function(e){return r[e]})).join(""))return!1;var n={};return"abcdefghijklmnopqrst".split("").forEach((function(e){n[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},n)).join("")}catch(e){return!1}}()?Object.assign:function(e,o){for(var u,c,f=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),l=1;l<arguments.length;l++){for(var i in u=Object(arguments[l]))t.call(u,i)&&(f[i]=u[i]);if(r){c=r(u);for(var a=0;a<c.length;a++)n.call(u,c[a])&&(f[c[a]]=u[c[a]])}}return f}},96540:(e,r,t)=>{e.exports=t(15287)}}]);