imageSrcProp set on load from web url but it's going in loop as I have array of Image

hi,
there is problem of image loading again and again. Let me explain the scenario. i have a array of Object in which user can add new Object and Remove any Object. that Object has 3 properties. title, description and Icon (for Image). now we I load the Initial data if user has set them the array is looping and setting the image in imageSrcProp which call's the method imageChanged and there I am updating the state value which is causing the re-render in react. So it's just loading image again and again.

This is the code it's inside map function

Trying using memo for not reseting the state on the component


DLL in NuGet package is not strong-name signed

Please add signing support in project file to allow loading dll from other strong-name signed projects.

See #297


Add 'AllowAddPeople' property to control whether to show 'Add' Button.

Set self.title to navigation title when self.title is not nil when view did loaded.

Thank you!


Fix path of tmp_dir

Hi, can you add a signoff to your commit with git commit --amend -s and repush?

/approve
LGTM

LGTM once tests are happy.  @xcffl TYVM for the fix up!

crud, hit the wrong button, I did not mean to close this.

Fixed

/lgtm

/hold

Looks like the previous problem is fixed dispite some unrelated fatal?

/hold cancel


[ Wait for 1952 ][ Layers ] paralleize Forwarding of conv2d

This patch includes the batch direction parallelization of forwarding
in Conv2D layer.
Self evaluation:

Build test:	 [X]Passed [ ]Failed [ ]Skipped
Run test:	 [X]Passed [ ]Failed [ ]Skipped

Signed-off-by: jijoong.moon<EMAIL_ADDRESS>

:memo: TAOS-CI Version: 1.5.20200925. Thank you for submitting PR #1954. Please a submit 1commit/1PR (one commit per one PR) policy to get comments quickly from reviewers. Your PR must pass all verificiation processes of cibot before starting a review process from reviewers. If you are new member to join this project, please read manuals in documentation folder and wiki page. In order to monitor a progress status of your PR in more detail, visit http://ci.nnstreamer.ai/.

:octocat: cibot: @jijoongmoon, nntrainer/utils/nntr_threads.h does not include Doxygen tags such as @file @brief @author @bug. You must include the Doxygen tags in the source code. Please refer to a Doxygen manual at http://github.com/nnstreamer/TAOS-CI/blob/main/ci/doc/doxygen-documentation.md


chore: remove tsconfig-paths-webpack-plugin dependency

Motivation
In the current project setup, we aren't using TypeScript's path mapping feature, which makes the tsconfig-paths-webpack-plugin package unnecessary. This package is primarily used to resolve TypeScript's path aliases, but since we don't have any aliases defined in our tsconfig.json, we can safely remove this dependency from our project.
Changes

Removed tsconfig-paths-webpack-plugin from package.json dependencies.
Updated all files and scripts where tsconfig-paths-webpack-plugin was used to ensure they function correctly without this package.
Updated webpack to version 5.91.0

QA
I have manually tested all the components, WithRumComponentContext, ErrorBoundary, RumRoute.

/merge

/merge


Fix delegate protocol method examples

Changed class name from MPCoachMarksView to MPCoachMarks in the delegate protocol examples section of README.md

This change it's not relevant


Increasing HTTP timeout for openjdk binary source

What is the purpose of this change? What does it change?

Was the change discussed in an issue?
Blocking the pr [1]. This pr [1] is responsible to run the test on OpenShift 4.2 cluster
[1] https://github.com/openshift/release/pull/4741

How to test changes?
make test-e2e-java

[odo]  ✗  Unable to connect to OpenShift cluster, is it down?

/test integration

Not sure that this is a good approach. Starting binary component shouldn't take that long.  Do we have any clue why it suddenly takes much longer?

Not sure that this is a good approach. Starting binary component shouldn't take that long. Do we have any clue why it suddenly takes much longer?

@kadel TBH i have no idea. I tested it on my aws cluster (OpenShift 4.2) and none of the time i am able to reproduce it out of 5 try, however in OnenShift CI i am seeing this failure consistently due to HTTP response timeout. So thought just by increasing the timeout may fix the issue only if 4.2 cluster is bit slow due to some reason, otherwise the failure need a proper debug.
Java scenario fails on 4.2 cluster - https://github.com/openshift/odo/blob/master/tests/integration/java_test.go#L94
odoJavaE2e odo component creation
  Should be able to deploy a spring boot uberjar file using openjdk
  /go/src/github.com/openshift/odo/tests/integration/java_test.go:94
 Created dir: /tmp/179100610
Creating a new project: xrnoewvudf
Running odo with args [odo project create xrnoewvudf -w -v4]
[odo] I0822 16:36:16.202090   14231 preference.go:116] The preference file is /tmp/179100610/config.yaml
[odo] I0822 16:36:16.202199   14231 occlient.go:478] Trying to connect to server api.ci-op-vyg62dz0-9b5c7.origin-ci-int-aws.dev.rhcloud.com:6443
[odo] I0822 16:36:16.244312   14231 occlient.go:485] Server https://api.ci-op-vyg62dz0-9b5c7.origin-ci-int-aws.dev.rhcloud.com:6443 is up
[odo] I0822 16:36:16.352534   14231 occlient.go:408] isLoggedIn err:  <nil>
[odo]  output: "developer"
[odo] I0822 16:36:16.352571   14231 context.go:371] Ignoring error as it usually means flag wasn't set: flag accessed but not defined: context
[odo] I0822 16:36:16.352584   14231 context.go:371] Ignoring error as it usually means flag wasn't set: flag accessed but not defined: context
[odo] I0822 16:36:16.352643   14231 context.go:371] Ignoring error as it usually means flag wasn't set: flag accessed but not defined: app
[odo] I0822 16:36:16.352651   14231 context.go:371] Ignoring error as it usually means flag wasn't set: flag accessed but not defined: project
[odo]  •  Waiting for project to come up  ...
[odo] I0822 16:36:16.368395   14231 context.go:371] Ignoring error as it usually means flag wasn't set: flag accessed but not defined: app
[odo] I0822 16:36:16.368432   14231 context.go:371] Ignoring error as it usually means flag wasn't set: flag accessed but not defined: output
[odo] I0822 16:36:16.368440   14231 context.go:371] Ignoring error as it usually means flag wasn't set: flag accessed but not defined: component
[odo]  ✓  Waiting for project to come up [437ms]
[odo]  ✓  Project 'xrnoewvudf' is ready for use
[odo]  ✓  New project created and now using project : xrnoewvudf
[odo] I0822 16:36:16.815503   14231 odo.go:70] Could not get the latest release information in time. Never mind, exiting gracefully :)
Running odo with args [odo create java sb-jar-test --project xrnoewvudf --binary /tmp/179100610/sb.jar --context /tmp/179100610]
[odo]  •  Validating component  ...
[odo]  ✓  Validating component [34ms]
[odo] Please use `odo push` command to create the component with source deployed
[odo]
Running odo with args [odo url create uberjaropenjdk --port 8080 --context /tmp/179100610]
[odo]  ✓  URL uberjaropenjdk created for component: sb-jar-test
[odo]
[odo] To create URL on the OpenShift Cluster, please use `odo push`
Running odo with args [odo push --context /tmp/179100610]
[odo] Validation
[odo]  •  Checking component  ...
[odo]  ✓  Checking component [58ms]
[odo]
[odo] Configuration changes
[odo]  •  Creating component  ...
[odo]  ✓  Initializing component
[odo]  ✓  Creating component [252ms]
[odo]  •  Applying configuration  ...
[odo]  ✓  Applying configuration [13631ns]
[odo]
[odo] Applying URL changes
[odo]  ✓  URL uberjaropenjdk: http://uberjaropenjdk-app-xrnoewvudf.apps.ci-op-vyg62dz0-9b5c7.origin-ci-int-aws.dev.rhcloud.com created
[odo]
[odo] Pushing to component sb-jar-test of type binary
[odo]  •  Checking files for pushing  ...
[odo]  ✓  Checking files for pushing [527856ns]
[odo]  •  Waiting for component to start  ...
[odo]  ✓  Waiting for component to start [43s]
[odo]  •  Copying files to component  ...
[odo]  ✓  Copying files to component [7s]
[odo]  •  Building component  ...
[odo]  ✓  Building component [5s]
Running odo with args [odo url list --context /tmp/179100610]
[odo] Found the following URLs for component sb-jar-test in application app:
[odo] NAME               IN CONFIG     URL                                                                                PORT
[odo] uberjaropenjdk     Present       http://uberjaropenjdk-app-xrnoewvudf.apps.ci-op-vyg62dz0-9b5c7.origin-ci-int-aws.dev.rhcloud.com     8080
Checking http://uberjaropenjdk-app-xrnoewvudf.apps.ci-op-vyg62dz0-9b5c7.origin-ci-int-aws.dev.rhcloud.com, for HTTP Booster
try 0 of 90
try 1 of 90
[...]
try 87 of 90
try 88 of 90
try 89 of 90
Last output from http://uberjaropenjdk-app-xrnoewvudf.apps.ci-op-vyg62dz0-9b5c7.origin-ci-int-aws.dev.rhcloud.com:
Deleting project: xrnoewvudf
Running odo with args [odo project delete xrnoewvudf -f]
[...]
 • Failure [156.654 seconds]
odoJavaE2e
/go/src/github.com/openshift/odo/tests/integration/java_test.go:13
  odo component creation
  /go/src/github.com/openshift/odo/tests/integration/java_test.go:41
    Should be able to deploy a spring boot uberjar file using openjdk [It]
    /go/src/github.com/openshift/odo/tests/integration/java_test.go:94
     Failed after 90 retries. Content in http://uberjaropenjdk-app-xrnoewvudf.apps.ci-op-vyg62dz0-9b5c7.origin-ci-int-aws.dev.rhcloud.com doesn't include 'HTTP Booster'.
     /go/src/github.com/openshift/odo/tests/helper/helper_http.go:41

We need to find why is this happening. Just increasing timeout without knowing why is not a good approach.

We need properly debug this. If we are waiting 90seconds for simple applications that there is potentially something wrong. We shouldn't just increase timeout if we don't know what is causing the delay.

We need properly debug this. If we are waiting 90seconds for simple applications that there is potentially something wrong. We shouldn't just increase timeout if we don't know what is causing the delay.

Right, Then need to comment out the test for merging openshift/release#4741 and run each odo pr on 4.2 cluster so that other potential issues if any on 4.2 can be fixed before the code freeze.
Or @girishramnani @mohammedzee1000 @cdrage @mik-dass @dharmit should look into the the issue https://github.com/openshift/odo/pull/2045#issuecomment-525167238 on high priority basis
NOTE: It
unles somebody is quick enough to fix this issue on OpenShift CI

/hold

@kadel TBH i have no idea. I tested it on my aws cluster (OpenShift 4.2) and none of the time i am able to reproduce it out of 5 try, however in OnenShift CI i am seeing this failure consistently due to HTTP response timeout. So thought just by increasing the timeout may fix the issue only if 4.2 cluster is bit slow due to some reason, otherwise the failure need a proper debug.

If you were not able to reproduce this issue on your AWS cluster, how many retries were required for the URL to be available. Also did increasing the timeout help?

Lets track the issue here - #2049


Node-RED crash (SIGSEGV) when any writable file is set as the serial device

Which node-red-contrib-modbus version are you using?
5.25.0
What happened?
Version of node.js? (should be >= 16)
v16.16.0
Version of Node-RED? (should be >= 3)
v3.0.2
Version of node-red-contrib-modbus? (should be >= 5)
v5.25.0
What is your platform? (Linux, macOS, ...)
Linux (Balena OS on Raspberry Pi)
Using the official Docker image
What does DEBUG=contribModbus:,modbus-serial node-red -v log? (log files are welcome)
Welcome to Node-RED
===================

20 Jan 10:54:50 - [info] Node-RED version: v3.0.2
20 Jan 10:54:50 - [info] Node.js  version: v16.16.0
20 Jan 10:54:50 - [info] Linux 5.10.95-v8 arm64 LE
20 Jan 10:54:54 - [info] Loading palette nodes
20 Jan 10:54:55 - [debug] Module: node-red-contrib-modbus 5.25.0 /data/node_modules/node-red-contrib-modbus
20 Jan 10:54:55 - [debug] Module: node-red-dashboard 3.3.1 /data/node_modules/node-red-dashboard
20 Jan 10:54:55 - [debug] Module: node-red-contrib-stoptimer-varidelay 0.5.2 /usr/src/node-red/node_modules/node-red-contrib-stoptimer-varidelay
20 Jan 10:55:00 - [info] Dashboard version 3.3.1 started at /ui
20 Jan 10:55:00 - [info] Settings file  : /data/settings.js
20 Jan 10:55:00 - [info] Context store  : 'default' [module=memory]
20 Jan 10:55:00 - [info] User directory : /data
20 Jan 10:55:00 - [warn] Projects disabled : set editorTheme.projects.enabled=true to enable
20 Jan 10:55:00 - [info] Flows file     : /data/flows.json
20 Jan 10:55:00 - [info] Server now running at http://<IP_ADDRESS>:1880/
20 Jan 10:55:00 - [debug] loaded flow revision: ca1b2db29b26aac1d5cc662158cbc46c
20 Jan 10:55:00 - [debug] red/runtime/nodes/credentials.load : no user key present
20 Jan 10:55:00 - [debug] red/runtime/nodes/credentials.load : using default key
20 Jan 10:55:00 - [debug] red/runtime/nodes/credentials.load : keyType=system
20 Jan 10:55:00 - [trace] runtime event: {"id":"runtime-state","retain":true}
20 Jan 10:55:00 - [trace] runtime event: {"id":"runtime-deploy","payload":{"revision":"ca1b2db29b26aac1d5cc662158cbc46c"},"retain":true}
20 Jan 10:55:01 - [info] Starting flows
20 Jan 10:55:01 - [debug] red/nodes/flows.start : starting flow : global
20 Jan 10:55:01 - [debug] red/nodes/flows.start : starting flow : 2ce6df32-439c-428e-bc8a-bfc3053d71e7
20 Jan 10:55:01 - [debug] red/nodes/flows.start : starting flow : f2a00bec621417c5
20 Jan 10:55:01 - [trace] [flow:global] start flow [global]
  contribModbus:queue:core queue serial lock command node name: Modbus Server id: 2995c31d.ca614c +0ms
20 Jan 10:55:01 - [info] Started flows
./entrypoint.sh: line 14:     7 Segmentation fault      (core dumped) /usr/local/bin/node $NODEOPTIONS node_modules/node-red/red.js --userDir /data $FLOWS

(excess details like flow logs omitted for brevity as the flow is below, though they can be given if needed)
Flow file
[{"id":"13b3589542b6b0c9","type":"tab","label":"Flow 1","disabled":false,"info":""},{"id":"ec1c1510c31267ba","type":"modbus-read","z":"13b3589542b6b0c9","name":"Register 35","topic":"test","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"4","dataType":"HoldingRegister","adr":"35","quantity":"1","rate":"2","rateUnit":"s","delayOnStart":false,"startDelayTime":"","server":"2995c31d.ca614c","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":250,"y":180,"wires":[["79748a843185534c","27f6aa74102b975f"],["b4fc3298987d3c32"]]},{"id":"8702895103125274","type":"debug","z":"13b3589542b6b0c9","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":810,"y":200,"wires":[]},{"id":"b4fc3298987d3c32","type":"debug","z":"13b3589542b6b0c9","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":500,"y":240,"wires":[]},{"id":"af697262864bf4e7","type":"modbus-read","z":"13b3589542b6b0c9","name":"Register 4","topic":"test","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"4","dataType":"HoldingRegister","adr":"4","quantity":"1","rate":"2","rateUnit":"s","delayOnStart":false,"startDelayTime":"","server":"2995c31d.ca614c","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":320,"y":580,"wires":[["99515002f3069944","23d180926aa53f32"],["a0be5ee50b109ba3"]]},{"id":"781b43de616918a9","type":"debug","z":"13b3589542b6b0c9","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":710,"y":580,"wires":[]},{"id":"a0be5ee50b109ba3","type":"debug","z":"13b3589542b6b0c9","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":580,"y":640,"wires":[]},{"id":"79748a843185534c","type":"function","z":"13b3589542b6b0c9","name":"","func":"msg.payload = \"Register 35: \" + msg.payload; \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":500,"y":180,"wires":[["8702895103125274"]]},{"id":"02b774a462fffc01","type":"modbus-write","z":"13b3589542b6b0c9","name":"Write register 35","showStatusActivities":false,"showErrors":false,"unitid":"4","dataType":"HoldingRegister","adr":"35","quantity":"1","server":"2995c31d.ca614c","emptyMsgOnFail":false,"keepMsgProperties":false,"x":600,"y":380,"wires":[["ed3daaa4a8ac7105"],[]]},{"id":"ed3daaa4a8ac7105","type":"debug","z":"13b3589542b6b0c9","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":790,"y":380,"wires":[]},{"id":"99515002f3069944","type":"function","z":"13b3589542b6b0c9","name":"","func":"msg.payload = \"Register 4: \" + msg.payload; \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":540,"y":580,"wires":[["781b43de616918a9"]]},{"id":"0483cb81e9d3f38c","type":"ui_text_input","z":"13b3589542b6b0c9","name":"Timer","label":"Timer","tooltip":"","group":"2e9652e4.a9280e","order":1,"width":0,"height":0,"passthru":true,"mode":"text","delay":"800","topic":"topic","topicType":"msg","x":230,"y":380,"wires":[["9c220ab025ac2356"]]},{"id":"9c220ab025ac2356","type":"function","z":"13b3589542b6b0c9","name":"Parse to Int","func":"msg.payload = parseInt(msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":410,"y":380,"wires":[["02b774a462fffc01"]]},{"id":"b6de73b7886f2348","type":"ui_text","z":"13b3589542b6b0c9","group":"2e9652e4.a9280e","order":2,"width":0,"height":0,"name":"Register 35 (Timer)","label":"Register 35 (Timer)","format":"{{msg.payload}}","layout":"row-spread","x":770,"y":80,"wires":[]},{"id":"27f6aa74102b975f","type":"function","z":"13b3589542b6b0c9","name":"Parse to Int","func":"msg.payload = parseInt(msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":510,"y":80,"wires":[["b6de73b7886f2348"]]},{"id":"aa4a4429ab779ab9","type":"modbus-write","z":"13b3589542b6b0c9","name":"Write register 4","showStatusActivities":false,"showErrors":false,"unitid":"4","dataType":"HoldingRegister","adr":"4","quantity":"1","server":"2995c31d.ca614c","emptyMsgOnFail":false,"keepMsgProperties":false,"x":560,"y":1120,"wires":[["2ec14b43288c7c88"],["56007b081fd4362c","f8fbfcd73863c590"]]},{"id":"2ec14b43288c7c88","type":"debug","z":"13b3589542b6b0c9","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":790,"y":1060,"wires":[]},{"id":"d4d4914fd15a96d0","type":"ui_text_input","z":"13b3589542b6b0c9","name":"Valve","label":"Valve","tooltip":"","group":"e405fe8f.3d27a","order":1,"width":0,"height":0,"passthru":true,"mode":"text","delay":"800","topic":"topic","sendOnBlur":true,"className":"","topicType":"msg","x":110,"y":1120,"wires":[["86f3485603e93e87","961b4efa4a4118b6"]]},{"id":"86f3485603e93e87","type":"function","z":"13b3589542b6b0c9","name":"Parse to Int","func":"var msg1 = {};\nmsg1.payload = parseInt(msg.payload);\nreturn msg1;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":310,"y":1120,"wires":[["aa4a4429ab779ab9","fe313863b8d149ab"]]},{"id":"6408fcc38d16960f","type":"ui_text","z":"13b3589542b6b0c9","group":"e405fe8f.3d27a","order":2,"width":0,"height":0,"name":"Register 4 (Valve)","label":"Register 4 (Valve)","format":"{{msg.payload}}","layout":"row-spread","x":750,"y":520,"wires":[]},{"id":"23d180926aa53f32","type":"function","z":"13b3589542b6b0c9","name":"Parse to Int","func":"msg.payload = parseInt(msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":520,"wires":[["6408fcc38d16960f"]]},{"id":"2ba4b4f5017f66c2","type":"modbus-read","z":"13b3589542b6b0c9","name":"Register 5","topic":"test","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"","dataType":"HoldingRegister","adr":"5","quantity":"1","rate":"2","rateUnit":"s","delayOnStart":false,"startDelayTime":"","server":"2995c31d.ca614c","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":320,"y":960,"wires":[["f71e3361c6aa9f95","6de9536da3e78eed"],["fcfe96e91b49cddb"]]},{"id":"30d81dc0ba2f15e5","type":"debug","z":"13b3589542b6b0c9","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":710,"y":960,"wires":[]},{"id":"fcfe96e91b49cddb","type":"debug","z":"13b3589542b6b0c9","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":580,"y":1020,"wires":[]},{"id":"f71e3361c6aa9f95","type":"function","z":"13b3589542b6b0c9","name":"","func":"msg.payload = \"Register 4: \" + msg.payload; \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":540,"y":960,"wires":[["30d81dc0ba2f15e5"]]},{"id":"0a11359d81e987ca","type":"ui_text","z":"13b3589542b6b0c9","group":"34e895d.2e9a16a","order":2,"width":0,"height":0,"name":"Register 5 (Outlets)","label":"Register 5 (Outlets)","format":"{{msg.payload}}","layout":"row-spread","x":750,"y":900,"wires":[]},{"id":"6de9536da3e78eed","type":"function","z":"13b3589542b6b0c9","name":"Parse to Int","func":"msg.payload = parseInt(msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":900,"wires":[["0a11359d81e987ca"]]},{"id":"961b4efa4a4118b6","type":"delay","z":"13b3589542b6b0c9","name":"","pauseType":"delay","timeout":"100","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":310,"y":1260,"wires":[["d5a4908348389102"]]},{"id":"d5a4908348389102","type":"function","z":"13b3589542b6b0c9","name":"Parse to Int","func":"msg.payload = parseInt(msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":490,"y":1260,"wires":[["2ea8eb5f043a0a23","f5e0b3f6bd883eae"]]},{"id":"2ea8eb5f043a0a23","type":"switch","z":"13b3589542b6b0c9","name":"Valve on","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"1","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":670,"y":1260,"wires":[["3b4ee2699671e17c"]]},{"id":"3b4ee2699671e17c","type":"change","z":"13b3589542b6b0c9","name":"Turn solenoids on","rules":[{"t":"set","p":"payload","pt":"msg","to":"3","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":880,"y":1260,"wires":[["e1e1020a4b47fa5d"]]},{"id":"f5e0b3f6bd883eae","type":"switch","z":"13b3589542b6b0c9","name":"Valve off","property":"payload","propertyType":"msg","rules":[{"t":"eq","v":"0","vt":"num"}],"checkall":"true","repair":false,"outputs":1,"x":660,"y":1340,"wires":[["6cf28b0a2bfbba8a"]]},{"id":"6cf28b0a2bfbba8a","type":"change","z":"13b3589542b6b0c9","name":"Turn solenoids off","rules":[{"t":"set","p":"payload","pt":"msg","to":"0","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":870,"y":1340,"wires":[[]]},{"id":"e1e1020a4b47fa5d","type":"modbus-write","z":"13b3589542b6b0c9","name":"Write register 5","showStatusActivities":false,"showErrors":false,"unitid":"4","dataType":"HoldingRegister","adr":"5","quantity":"1","server":"2995c31d.ca614c","emptyMsgOnFail":false,"keepMsgProperties":false,"x":1120,"y":1300,"wires":[["dad9ebc6643ebe30"],[]]},{"id":"dad9ebc6643ebe30","type":"debug","z":"13b3589542b6b0c9","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1310,"y":1300,"wires":[]},{"id":"c49e548078f8196c","type":"modbus-read","z":"13b3589542b6b0c9","name":"Register 6","topic":"test","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"","dataType":"HoldingRegister","adr":"6","quantity":"1","rate":"2","rateUnit":"s","delayOnStart":false,"startDelayTime":"","server":"2995c31d.ca614c","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":340,"y":1460,"wires":[["80382d9fa1ec0d8e","598ebcdb67f1afac"],["afae8363cb04efd7"]]},{"id":"90b04f1a993aaac3","type":"debug","z":"13b3589542b6b0c9","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":730,"y":1460,"wires":[]},{"id":"afae8363cb04efd7","type":"debug","z":"13b3589542b6b0c9","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":600,"y":1520,"wires":[]},{"id":"80382d9fa1ec0d8e","type":"function","z":"13b3589542b6b0c9","name":"","func":"msg.payload = \"Register 4: \" + msg.payload; \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":560,"y":1460,"wires":[["90b04f1a993aaac3"]]},{"id":"8d5329e82cf47860","type":"ui_text","z":"13b3589542b6b0c9","group":"34e895d.2e9a16a","order":2,"width":0,"height":0,"name":"Register 6 (Outlet temp)","label":"Register 6(Outlet temp)","format":"{{msg.payload}}","layout":"row-spread","x":910,"y":1400,"wires":[]},{"id":"598ebcdb67f1afac","type":"function","z":"13b3589542b6b0c9","name":"Parse to Int","func":"msg.payload = parseInt(msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":510,"y":1400,"wires":[["3a8d6f8a4d01a182"]]},{"id":"3a8d6f8a4d01a182","type":"function","z":"13b3589542b6b0c9","name":"Parse to Int","func":"msg.payload = msg.payload *0.1;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":690,"y":1400,"wires":[["8d5329e82cf47860"]]},{"id":"602e67728fb6750f","type":"modbus-read","z":"13b3589542b6b0c9","name":"Register 36","topic":"test","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"","dataType":"HoldingRegister","adr":"36","quantity":"1","rate":"2","rateUnit":"s","delayOnStart":false,"startDelayTime":"","server":"2995c31d.ca614c","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":370,"y":1980,"wires":[["5c35a78704a70241","916f53fd266d0471"],["8b6d3d7b3ad716d3"]]},{"id":"6a44b7a31e3ddba3","type":"debug","z":"13b3589542b6b0c9","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":750,"y":1980,"wires":[]},{"id":"8b6d3d7b3ad716d3","type":"debug","z":"13b3589542b6b0c9","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":620,"y":2040,"wires":[]},{"id":"5c35a78704a70241","type":"function","z":"13b3589542b6b0c9","name":"","func":"msg.payload = \"Register 4: \" + msg.payload; \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":580,"y":1980,"wires":[["6a44b7a31e3ddba3"]]},{"id":"c134cde50a018ef8","type":"ui_text","z":"13b3589542b6b0c9","group":"498b6059.f3434","order":2,"width":0,"height":0,"name":"Register 31 (Max SP outlet 1)","label":"Register 36(Max SP outlet 1)","format":"{{msg.payload}}","layout":"row-spread","x":940,"y":1920,"wires":[]},{"id":"916f53fd266d0471","type":"function","z":"13b3589542b6b0c9","name":"Parse to Int","func":"msg.payload = parseInt(msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":530,"y":1920,"wires":[["039c80f110bfa53a"]]},{"id":"039c80f110bfa53a","type":"function","z":"13b3589542b6b0c9","name":"Parse to Int","func":"msg.payload = msg.payload *0.1;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":710,"y":1920,"wires":[["c134cde50a018ef8"]]},{"id":"fdd34a06c5da4c0b","type":"modbus-read","z":"13b3589542b6b0c9","name":"Register 37","topic":"test","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"","dataType":"HoldingRegister","adr":"37","quantity":"1","rate":"2","rateUnit":"s","delayOnStart":false,"startDelayTime":"","server":"2995c31d.ca614c","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":370,"y":2280,"wires":[["08a182a578025494","0d1046fdbcbd3b96"],["f56a8f67183e614f"]]},{"id":"5b7b2815c2f1f176","type":"debug","z":"13b3589542b6b0c9","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":750,"y":2280,"wires":[]},{"id":"f56a8f67183e614f","type":"debug","z":"13b3589542b6b0c9","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":620,"y":2340,"wires":[]},{"id":"08a182a578025494","type":"function","z":"13b3589542b6b0c9","name":"","func":"msg.payload = \"Register 4: \" + msg.payload; \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":580,"y":2280,"wires":[["5b7b2815c2f1f176"]]},{"id":"7b48a967c5a3faef","type":"ui_text","z":"13b3589542b6b0c9","group":"498b6059.f3434","order":2,"width":0,"height":0,"name":"Register 37 (Min SP outlet 1)","label":"Register 37(Min SP outlet 1)","format":"{{msg.payload}}","layout":"row-spread","x":940,"y":2220,"wires":[]},{"id":"0d1046fdbcbd3b96","type":"function","z":"13b3589542b6b0c9","name":"Parse to Int","func":"msg.payload = parseInt(msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":530,"y":2220,"wires":[["e79d5cf24e23d410"]]},{"id":"e79d5cf24e23d410","type":"function","z":"13b3589542b6b0c9","name":"Scale","func":"msg.payload = msg.payload *0.1;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":690,"y":2220,"wires":[["7b48a967c5a3faef"]]},{"id":"e6c6568131dc0022","type":"modbus-read","z":"13b3589542b6b0c9","name":"Register 38","topic":"test","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"","dataType":"HoldingRegister","adr":"38","quantity":"1","rate":"2","rateUnit":"s","delayOnStart":false,"startDelayTime":"","server":"2995c31d.ca614c","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":350,"y":2560,"wires":[["e5e4d0c1b44cfd2c","e64ab030c4aaa097"],["9d2beda4a786b8a8"]]},{"id":"1c996e3a28268235","type":"debug","z":"13b3589542b6b0c9","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":730,"y":2560,"wires":[]},{"id":"9d2beda4a786b8a8","type":"debug","z":"13b3589542b6b0c9","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":600,"y":2620,"wires":[]},{"id":"e5e4d0c1b44cfd2c","type":"function","z":"13b3589542b6b0c9","name":"","func":"msg.payload = \"Register 4: \" + msg.payload; \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":560,"y":2560,"wires":[["1c996e3a28268235"]]},{"id":"697a9160b05553c5","type":"ui_text","z":"13b3589542b6b0c9","group":"498b6059.f3434","order":2,"width":0,"height":0,"name":"Register 38 (Default  SP outlet 1)","label":"Register 38(Default SP outlet 1)","format":"{{msg.payload}}","layout":"row-spread","x":930,"y":2500,"wires":[]},{"id":"e64ab030c4aaa097","type":"function","z":"13b3589542b6b0c9","name":"Parse to Int","func":"msg.payload = parseInt(msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":510,"y":2500,"wires":[["b4cb39e7b2cb4d78"]]},{"id":"b4cb39e7b2cb4d78","type":"function","z":"13b3589542b6b0c9","name":"Parse to Int","func":"msg.payload = msg.payload *0.1;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":690,"y":2500,"wires":[["697a9160b05553c5"]]},{"id":"2e3e2dfef79bf4bb","type":"modbus-write","z":"13b3589542b6b0c9","name":"Write register 36","showStatusActivities":false,"showErrors":false,"unitid":"4","dataType":"HoldingRegister","adr":"36","quantity":"1","server":"2995c31d.ca614c","emptyMsgOnFail":false,"keepMsgProperties":false,"x":920,"y":1840,"wires":[["f08b9073afeb18a0"],[]]},{"id":"f08b9073afeb18a0","type":"debug","z":"13b3589542b6b0c9","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1110,"y":1840,"wires":[]},{"id":"dcbccea1006570fe","type":"ui_text_input","z":"13b3589542b6b0c9","name":"Timer","label":"Register 36 Max SP","tooltip":"","group":"498b6059.f3434","order":1,"width":0,"height":0,"passthru":true,"mode":"text","delay":"800","topic":"topic","topicType":"msg","x":390,"y":1840,"wires":[["22128286cbb76b9f"]]},{"id":"22128286cbb76b9f","type":"function","z":"13b3589542b6b0c9","name":"Parse to Int","func":"msg.payload = parseInt(msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":570,"y":1840,"wires":[["67281a5f2798fbbe"]]},{"id":"236545912026e009","type":"modbus-write","z":"13b3589542b6b0c9","name":"Write register 37","showStatusActivities":false,"showErrors":false,"unitid":"4","dataType":"HoldingRegister","adr":"37","quantity":"1","server":"2995c31d.ca614c","emptyMsgOnFail":false,"keepMsgProperties":false,"x":900,"y":2160,"wires":[["b34dd0490e0f6963"],[]]},{"id":"b34dd0490e0f6963","type":"debug","z":"13b3589542b6b0c9","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1090,"y":2160,"wires":[]},{"id":"af96762a9e9924b9","type":"ui_text_input","z":"13b3589542b6b0c9","name":"Timer","label":"Register 37 Min SP","tooltip":"","group":"498b6059.f3434","order":1,"width":0,"height":0,"passthru":true,"mode":"text","delay":"800","topic":"topic","topicType":"msg","x":390,"y":2160,"wires":[["38429156c9cb197e"]]},{"id":"38429156c9cb197e","type":"function","z":"13b3589542b6b0c9","name":"Parse to Int","func":"msg.payload = parseInt(msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":570,"y":2160,"wires":[["47f17cdeb40e7dc4"]]},{"id":"67281a5f2798fbbe","type":"function","z":"13b3589542b6b0c9","name":"Scale","func":"msg.payload = msg.payload *10;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":730,"y":1840,"wires":[["2e3e2dfef79bf4bb"]]},{"id":"47f17cdeb40e7dc4","type":"function","z":"13b3589542b6b0c9","name":"Scale","func":"msg.payload = msg.payload *10;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":730,"y":2160,"wires":[["236545912026e009"]]},{"id":"c7d5f27e30e769d2","type":"modbus-write","z":"13b3589542b6b0c9","name":"Write register 38","showStatusActivities":false,"showErrors":false,"unitid":"4","dataType":"HoldingRegister","adr":"38","quantity":"1","server":"2995c31d.ca614c","emptyMsgOnFail":false,"keepMsgProperties":false,"x":860,"y":2440,"wires":[["a6e6a12f3a3a28fd"],[]]},{"id":"a6e6a12f3a3a28fd","type":"debug","z":"13b3589542b6b0c9","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1050,"y":2440,"wires":[]},{"id":"6dfc219ccebda1fe","type":"ui_text_input","z":"13b3589542b6b0c9","name":"Timer","label":"Register 38 Default SP","tooltip":"","group":"498b6059.f3434","order":1,"width":0,"height":0,"passthru":true,"mode":"text","delay":"800","topic":"topic","topicType":"msg","x":350,"y":2440,"wires":[["6c188708f622b84f"]]},{"id":"6c188708f622b84f","type":"function","z":"13b3589542b6b0c9","name":"Parse to Int","func":"msg.payload = parseInt(msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":530,"y":2440,"wires":[["2acff7877753a481"]]},{"id":"2acff7877753a481","type":"function","z":"13b3589542b6b0c9","name":"Scale","func":"msg.payload = msg.payload *10;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":690,"y":2440,"wires":[["c7d5f27e30e769d2"]]},{"id":"f3fe3f817af5233f","type":"modbus-read","z":"13b3589542b6b0c9","name":"Register 1","topic":"test","showStatusActivities":false,"logIOActivities":false,"showErrors":false,"unitid":"","dataType":"HoldingRegister","adr":"1","quantity":"1","rate":"2","rateUnit":"s","delayOnStart":false,"startDelayTime":"","server":"2995c31d.ca614c","useIOFile":false,"ioFile":"","useIOForPayload":false,"emptyMsgOnFail":false,"x":340,"y":2840,"wires":[["c9c113363a5b9a71","40639511be0c098b"],["0e1f611e724d812b"]]},{"id":"22e40f84207e037d","type":"debug","z":"13b3589542b6b0c9","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":730,"y":2840,"wires":[]},{"id":"0e1f611e724d812b","type":"debug","z":"13b3589542b6b0c9","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":600,"y":2900,"wires":[]},{"id":"c9c113363a5b9a71","type":"function","z":"13b3589542b6b0c9","name":"","func":"msg.payload = \"Register 4: \" + msg.payload; \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":560,"y":2840,"wires":[["22e40f84207e037d"]]},{"id":"1485fb5caff241bb","type":"ui_text","z":"13b3589542b6b0c9","group":"498b6059.f3434","order":2,"width":0,"height":0,"name":"Register 1 (Setpoint temp)","label":"Register 1 (Setpoint temp)","format":"{{msg.payload}}","layout":"row-spread","x":910,"y":2780,"wires":[]},{"id":"40639511be0c098b","type":"function","z":"13b3589542b6b0c9","name":"Parse to Int","func":"msg.payload = parseInt(msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":510,"y":2780,"wires":[["e9c2e6417fec47cd"]]},{"id":"e9c2e6417fec47cd","type":"function","z":"13b3589542b6b0c9","name":"Parse to Int","func":"msg.payload = msg.payload *0.1;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":690,"y":2780,"wires":[["1485fb5caff241bb"]]},{"id":"2431a4503934eaf2","type":"modbus-write","z":"13b3589542b6b0c9","name":"Write register 1","showStatusActivities":false,"showErrors":false,"unitid":"4","dataType":"HoldingRegister","adr":"1","quantity":"1","server":"2995c31d.ca614c","emptyMsgOnFail":false,"keepMsgProperties":false,"x":860,"y":2720,"wires":[["e8a1eeeff2067dff"],[]]},{"id":"e8a1eeeff2067dff","type":"debug","z":"13b3589542b6b0c9","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1050,"y":2720,"wires":[]},{"id":"0da13681ea3f36c9","type":"ui_text_input","z":"13b3589542b6b0c9","name":"Timer","label":"Register 1 Setpoint Temp","tooltip":"","group":"498b6059.f3434","order":1,"width":0,"height":0,"passthru":true,"mode":"text","delay":"800","topic":"topic","sendOnBlur":true,"className":"","topicType":"msg","x":350,"y":2720,"wires":[["33fa5cc4561cd89b"]]},{"id":"33fa5cc4561cd89b","type":"function","z":"13b3589542b6b0c9","name":"Parse to Int","func":"msg.payload = parseInt(msg.payload);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":530,"y":2720,"wires":[["29a78b4c79325d61"]]},{"id":"29a78b4c79325d61","type":"function","z":"13b3589542b6b0c9","name":"Scale","func":"msg.payload = msg.payload *10;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":690,"y":2720,"wires":[["2431a4503934eaf2"]]},{"id":"248fd6a49d4a56d8","type":"ui_button","z":"13b3589542b6b0c9","name":"","group":"e405fe8f.3d27a","order":4,"width":0,"height":0,"passthru":false,"label":"Valve On","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"1","payloadType":"num","topic":"topic","topicType":"msg","x":120,"y":1060,"wires":[["27fa2a87ab8c7a4f"]]},{"id":"b673ac54a7eebb68","type":"debug","z":"13b3589542b6b0c9","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":390,"y":1020,"wires":[]},{"id":"56007b081fd4362c","type":"modbus-response","z":"13b3589542b6b0c9","name":"","registerShowMax":20,"x":830,"y":1120,"wires":[]},{"id":"27fa2a87ab8c7a4f","type":"change","z":"13b3589542b6b0c9","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"1","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":280,"y":1060,"wires":[["aa4a4429ab779ab9","b673ac54a7eebb68"]]},{"id":"f8fbfcd73863c590","type":"debug","z":"13b3589542b6b0c9","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":810,"y":1160,"wires":[]},{"id":"fe313863b8d149ab","type":"debug","z":"13b3589542b6b0c9","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":540,"y":1080,"wires":[]},{"id":"2995c31d.ca614c","type":"modbus-client","name":"Modbus Server","clienttype":"simpleser","bufferCommands":true,"stateLogEnabled":false,"queueLogEnabled":false,"tcpHost":"<IP_ADDRESS>","tcpPort":"502","tcpType":"DEFAULT","serialPort":"/dev/ttyUSB0","serialType":"RTU-BUFFERD","serialBaudrate":"9600","serialDatabits":"8","serialStopbits":"1","serialParity":"none","serialConnectionDelay":"100","serialAsciiResponseStartDelimiter":"","unit_id":"4","commandDelay":"1","clientTimeout":"3000","reconnectOnTimeout":true,"reconnectTimeout":"1000","parallelUnitIdsAllowed":true},{"id":"2e9652e4.a9280e","type":"ui_group","name":"Temperature","tab":"162d8b7bf252795a","order":1,"disp":true,"width":"18","collapse":false,"className":""},{"id":"e405fe8f.3d27a","type":"ui_group","name":"Valve","tab":"20c87f54.bc8f7","order":2,"disp":true,"width":"6","collapse":false,"className":""},{"id":"34e895d.2e9a16a","type":"ui_group","name":"Outlets","tab":"20c87f54.bc8f7","order":3,"disp":true,"width":"6","collapse":false},{"id":"498b6059.f3434","type":"ui_group","name":"Setpoints","tab":"20c87f54.bc8f7","order":4,"disp":true,"width":"6","collapse":false},{"id":"162d8b7bf252795a","type":"ui_tab","name":"Dashboard","icon":"dashboard","disabled":false,"hidden":false},{"id":"20c87f54.bc8f7","type":"ui_tab","name":"Control","icon":"dashboard","disabled":false,"hidden":false}]

Hi there,
We're having an issue where Node-RED is crashing at startup if the Modbus server is given a serial port to which it has write access. Initially Node-RED was not crashing because we hadn't yet given the Docker container write access to /dev/ttyUSB0. This was solved by adding the node-red user inside the container to the dialout group however it surfaced this crashing issue. Some more investigation showed this same behaviour can be replicated by specifying any file that exists and is writable. E.g., if the serial port is set to /tmp/foobar when it does not exist, Node-RED is fine, but as soon as a regular file is created with that name, Node-RED crashes in the same way.
We have been able to replicate this with v2 and v3 of Node-RED.
Server
Modbus-Server Node
How can this be reproduced?

Import the flow
Set the serial port on the Modbus server to an appropriate device file, or any extant regular file
Deploy the changes and watch the logs for a segfault

What did you expect to happen?
No response
Other Information
No response

Hi there,
To give an update to this: we found the problem actually lies within the https://www.npmjs.com/package/modbus-serial package while running on Alpine Linux. Moving from the official Node-RED Docker Hub package (which uses Alpine) to Debian fixed the issue.
My guess is something in the chain depends on a peculiarity or a non-standard feature within glibc that musl-powered Alpine gets stuck on.
This issue can probably be closed, perhaps with a note somewhere that there may be issues using this package on Alpine?

I'm seeing the same when using the official Node-RED Docker Hub package.
I agree... if this really can't work with those official Docker images, it should probably be noted somewhere since this project is specifically a Node-RED module.

Resolved this issue for me
node-red-contrib-modbus works fine with official Node-RED Docker images if the npm command includes --unsafe-perm --build-from-source.
So in my case, in my Dockerfile I changed...
RUN cd /data && npm install --only=production
...to...
RUN cd /data && npm install --only=production --unsafe-perm --build-from-source
Also, this works for both versions 5.21 and 5.25.

Could you please post the actual dockerfile you are using that works for you ?
thanks

Sure! Here's the basics of what is now working for me:
FROM nodered/node-red:2.2.2-14

# Copy package.json to /data so npm installs the added modules for Node-RED
COPY package.json /data/package.json

# Install inside /data. Doing otherwise may wreck the Node-RED installation
RUN cd /data && npm install --only=production --unsafe-perm --build-from-source

# Copy _your_ Node-RED project files into place
COPY settings.js /data/settings.js
COPY flows.json /data/flows.json

# Start the container normally
CMD ["npm", "start"]


Support of newer Java versions

Hard coded java versions prevents the CLI from starting and using newer versions. The error message shown is the following and only solution is to switch to different Java version.
Invalid Java version '20', please set JAVA_HOME to major version '11' or '17'
https://github.com/ContextMapper/context-mapper-cli/blob/afb29c0300aab82166884dcc83e53f5053f1bb59/src/main/java/org/contextmapper/cli/ContextMapperCLI.java#L28

Thanks for reporting this @gottfriedsz!
You are right, we should improve that check there... Will try to have a look at it as soon as possible. PR's are always welcome as well ;)

HI @stefan-ka
What is the reason that the check even exists?
As Java 21 LTS is now out since september we would like to update our application and the context-mapper is one of the known blockers for us.

Hi @marcomima
You are right, we should at least remove the upper bound. The check should only validate that the Java version is >11. This was introduced during times when Xtext and therefore Context Mapper where not compatible with Java >17.
Of course we would first have to test whether Context Mapper actually works with Java 21 but without the check we would at least not limit it and it "could" work :)
I'll remove it and create a CLI release.

@marcomima @gottfriedsz
Please use the just released version 6.11.1 of the context-mapper-cli. Seems to work with Java 21. Please let me know if you face any issues.


1.92 MergeEditor does NOT load at all

Does this issue occur when all extensions are disabled?: Dunno, N/A.

VS Code Version: 1.92
OS Version: Win 11

Steps to Reproduce:

Upgrade to 1.92
Have a file (merge) conflict
Try to solve merge conflict

My VSCode automatically updated to the latest version (1.92).  After which I was no longer able to solve merge conflicts.  Downgraded back to 1.91 and everything works as per normal.

Nope, was using the latest.

Can you share a screenshot? Thanks!

Hi @BAAAASS, does the issue still occur for you on VS Code 1.96 or later?

Don't know.  I rolled back to an older version and then everything worked as it should.


App Store Location Warning with SwiftPM Integration

Describe the bug
We recently updated from 4.1.1 to 4.2.2 and we got a warning email from Apple because we started using Location APIs without setting a NSLocationWhenInUseUsageDescription string description in the Info.plist file.
Our app doesn't use any Location APIs, and from version 4.2.1 of the SDK a new API has been added to allow Location API usage with SwiftPM. The new API is enableLocation which is not under the CLEVERTAP_LOCATION compilation flag that was not working for SwiftPM.
So, from 4.2.1 the Location code will be compiled even if not used, which was not the case for 4.2.0 and below.
This prevents us from updating the SDK to a newer version and updating to Xcode 14.3 which was fixed by the 4.2.2 SDK version.
The same issue is still present in the 5.0.0 SDK version.
Expected behaviour
The Location code should not be compiled at all if the CleverTap SDK is added via SwiftPM and the CLEVERTAP_LOCATION is not added to the project.
Environment:

Xcode version: 14.3
CleverTap SDK Version: From 4.2.2 to 5.0.0

Thanks for bringing this up. The problem was SPM projects did not work with macros like Cocoapods projects did. We will discuss this internally and come up with a solution for this issue, that suits both SPM and other projects 👍.

We have released a fix for this in our latest release v5.0.1
https://github.com/CleverTap/clevertap-ios-sdk/releases/tag/5.0.1

@akashvercetti Thank you! We will try it and let you know 🙌


Write tests

[ ] Unit tests for kernels and class methods
[ ] Regression test (comparing output to Jim's code for verification)

Done, now submitting pull request.


[TOPIC-GPIO] drivers/wifi: eswifi: Update to new GPIO API

drivers/wifi: eswifi: Update to new GPIO API
Update to new GPIO API.
Tested on disco_l475_iot1
Signed-off-by: Erwan Gouriou<EMAIL_ADDRESS>Based on #21065

@mnkp, I've fixed the reported issues (aside from point discussed in https://github.com/zephyrproject-rtos/zephyr/pull/21066#discussion_r355153984 which belongs to another PR). Feel free to approve.


Statically linked program segfaults

This project uses +crt-static feature to build a statically linked executable.
hyper_segfault.zip
You can run the program with cargo run --target x86_64-unknown-linux-gnu, it will segfault after a minute or so.
$ cargo --version
cargo 1.51.0 (43b129a20 2021-03-16)
$ uname -a
Linux nixos 5.10.15 #1-NixOS SMP Wed Feb 10 08:29:23 UTC 2021 x86_64 GNU/Linux

Correct demo project:
hyper_segfault.zip

Huh... Could you include more debug info? Does it output a message or dump when segfaulting? Could you use something gdb to grab the stack frame before it aborts?

This is the stacktrace: https://gist.github.com/fctorial/2bf62e46da319181bd8c66f155ffac0f
It was generated using this main.rs:
use hyper::{Request, Method, Body};
use hyper::client::Client;
use hyper::header::CONTENT_TYPE;
use hyper::Error;
use std::time::Duration;

static URI : &str = "http://jsonplaceholder.typicode.com/posts";
async fn request() -> Result<String, Error> {
    let req = Request::builder()
        .method(Method::POST)
        .uri(URI)
        .header(CONTENT_TYPE, "application/json")
        .body(Body::from(format!("{{\"n\": {}}}", 1))).unwrap();
    let client = Client::new();
    let resp = client.request(req).await?;
    return Ok(std::str::from_utf8(hyper::body::to_bytes(resp.into_body()).await?.as_ref()).unwrap().to_string());
}

#[tokio::main]
pub async fn main() {
    loop {
        println!("{:?}", request().await);
        std::thread::sleep(Duration::from_secs(10));
    }
}

The glibc version is 2.31-74

Statically linking to glibc is not really supported, particularly for gethostbyname which needs to dynamically link to libnss: https://stackoverflow.com/questions/2725255/create-statically-linked-binary-that-uses-getaddrinfo.
You should build against MUSL libc if you want a fully static binary.


How to obtain header information for a particular channel_index in a stream

@samuelgarcia So using the new BaseRawIO interface with streams containing analog signals and those signals being indexed by a channel_index relative to a stream, how are we supposed to obtain the corresponding elements of the header['signal_channels'] array?
I was looking for a way to do this using the BaseRawIO API and it is not obvious. I need to do this to make the ephyviewer.datasource.neosource.AnalogSignalFromNeoRawIOSource work, particularly its get_gains and get_offsets methods.
It seems frankly like a more general problem that may require a translation method from (stream_id, channel_index) to header offsets (similar to the old meaning of channel_index in BaseRawIO).

Hi Peter,
for ephyviewer have a look to the already started PR here https://github.com/NeuralEnsemble/ephyviewer/pull/151
Given a stream_id, to obtain corresponding header['signal_channels'] I use boolean mask like this
mask = header['signal_channels']['sgtream_id'] == stream_id
channel_in_stream = header['signal_channels'][mask]

Hi Samuel, just created https://github.com/NeuralEnsemble/ephyviewer/pull/152 showing a slightly different approach.
And why not go to Neo 1.0 rather than 0.10 ? I always find that ugly and frankly this has been in use enough that 1.0 does not seem inappropriate.

The plan was to make neo 1.0 two years ago.
But we are too slow.
We have a long list before this 1.0 grail:

merge AnalogSignal and irregularlySampleSignal
make a SpikeTrainList (or similar name)
rework the lazy object
implementation IOs from spikeextractors
totally rewrite the documentation with sphinx gallery
improve integration with NWB and NIX
clean very old code
simplify test suite

We are so lazy that it could take one or two years more.

I know if is just a matter of style with the numbering, but it does seem like Neo has been at a basic functional level for some time, which to me is a 1.0.
But then there is the Linux style of numbering...


Document what kind of data we fetch from the user's system

Can we add a section to the README adding a detailed explanation of what information this module fetches from the user system for each OS?

Closing stale issues


Implement maxDeltaY for PanGestureHandler on (for iOS only currently)

No need to use this exact implementation, it was quick to just get a proof of concept working. It does seem like a valuable prop to add, however. I was able to implement SwipeActions like this:
render() {
  const translateX = this.state._translateX;

  return (
    <View>
      <PanGestureHandler
        id={this.props.gestureId}
        minDeltaX={50}
        maxDeltaY={5}
        onGestureEvent={this._onGestureEvent}
        onHandlerStateChange={this._onHandlerStateChange}>
        <Animated.View
          style={{ transform: [{ translateX: translateX }] }}
          onLayout={this._onLayoutChildren}>
          {this.props.children}
        </Animated.View>
      </PanGestureHandler>

      {this._renderButtons()}
    </View>
  );
}

And on the parent ScrollView I wait for the pan gestures to fail.

There are few small things that require fixing but I want to get this in so will fix this on my own. ty


next-translate isn't working when using pageExtensions

I am having an issue where next-translate doesn't work when I am using pageExtensions and rename the _app file.
ex.
// next.config.js

module.exports = nextTranslate({
pageExtensions:
      process.env.NODE_ENV === "production"
        ? ["production.tsx"]
        : ["production.tsx", "tsx", "ts", "jsx", "js"],
})

_app is named _app.production.tsx

pageExtensions doesn't exist in next-translate. You should use extensionsRgx.
extensionsRgx: /\.production\.(tsx|ts|js|mjs|jsx)$/,

Thank you, that works.


Refactor cache

Replace custom cache w/ functools.cache
Refactor _is_allowed
Switch to functools.lru_cache and limit the cache size.

Thank you!


[license] Multiple license expressions error

Repo: https://github.com/DefectDojo/django-DefectDojo
docker pull ghcr.io/appthreat/cdxgen-python:v10

docker run --rm -e CDXGEN_DEBUG_MODE=debug -v /tmp:/tmp -v $(pwd):/app -it ghcr.io/appthreat/cdxgen-python:v10 -r -o /app/bom.json /app -t python --deep
cdxgen will now attempt to generate an SBOM for 'build' lifecycle phase for Python. This would take some time ...
To speed up this step, invoke cdxgen from within a virtual environment with all the dependencies installed.
Alternatively, pass the argument '--lifecycle pre-build' to generate a faster but less precise SBOM without installing the dependencies in case of any build issues.
Using virtual environment in /tmp/cdxgen-venv-Slusqf
About to construct the pip dependency tree. Please wait ...
Using virtual environment in /tmp/cdxgen-venv-Slusqf
About to construct the pip dependency tree. Please wait ...
Executing node /root/.nvm/versions/node/v22.0.0/lib/node_modules/<EMAIL_ADDRESS>parsedeps -l python -o /tmp/atom-deps-ny6kbj/app.atom --slice-outfile /deps.slices.json /app
Slices have been successfully written to /deps.slices.json

multiple license expressions found [
  { expression: 'GNU Library or Lesser General Public License (LGPL)' },
  { expression: 'LGPL 3' }
]

For scipy
cupy-backends is not found on PyPI.
If this package is available from PyPI or a registry, its name might be different from the module name. Raise a ticket at https://github.com/CycloneDX/cdxgen/issues so that this can be added to the mapping file pypi-pkg-aliases.json
Alternatively, if this is a package that gets installed directly in your environment and offers a python binding, then track such packages manually.
Assuming the version as latest for the package cupy-backends
cupyx is not found on PyPI.
If this package is available from PyPI or a registry, its name might be different from the module name. Raise a ticket at https://github.com/CycloneDX/cdxgen/issues so that this can be added to the mapping file pypi-pkg-aliases.json
Alternatively, if this is a package that gets installed directly in your environment and offers a python binding, then track such packages manually.
Assuming the version as latest for the package cupyx
multiple license expressions found [
  { expression: 'GNU General Public License (GPL)' },
  { expression: 'Public Domain' }
]


Use generic font families

This pull request derives from #387. So needs to be handled after that.

test-report.css specifies ancient fonts in font-family, which disturbs user's preferred fonts.
This pull request removes them and leaves generic font families.

@cirulls
Merged this trivial change in CSS.
Though everybody may have his aesthetic opinion, I merged this change without review because the fonts were clearly old and this change doesn't enforce specific fonts on users.


Update UG errors

Applies the changes in my comment on #242

Codecov Report

Merging #272 (0c95226) into master (46845a4) will not change coverage.
The diff coverage is n/a.

@@            Coverage Diff            @@
##             master     #272   +/-   ##
=========================================
  Coverage     70.81%   70.81%
  Complexity      596      596
=========================================
  Files            85       85
  Lines          1919     1919
  Branches        258      258
=========================================
  Hits           1359     1359
  Misses          443      443
  Partials        117      117

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 46845a4...0c95226. Read the comment docs.


The values do not expire

Description
Hi, I'm a bit confused as I'm not even sure if this is a bug or something else.
We use Redis as a cache, which we add via the setEx command. However, recently, we have started to have some keys that return -1 with the TTL command. It doesn't happen often, but such events do occur. What could be causing this?
The decrBy command is called with the same keys. Can this somehow affect the expire field?
Node.js Version
20
Redis Server Version
7.2.3
Node Redis Version
4.7.0
Platform
alpine
Logs
No response

[INCR|DECR][BY] does not change the key TTL:
> SET key 0 EX 100
OK
> EXPIRETIME key
(integer)<PHONE_NUMBER>
> DECRBY key 1
(integer) -1
> EXPIRETIME key
(integer)<PHONE_NUMBER>

but, depending on your code, you might have a race condition.. assuming your code is doing something like:
> EXISTS key
(integer) 1

then doing some work, and then:
> DECRBY key 1

the key TTL might be in between the EXISTS and the DECRBY, which means EXISTS will return true, but DECRBY will recreate the key, without setting a new TTL on it.

Oh, o, ooo! You've pointed out our logic quite closely and a possible problem. Thank you so much!
We'll write our own LUA script to avoid making a decrBy if there is no value.


Simplify tests setup

What type of PR is this?
/kind cleanup
What this PR does / why we need it:

Only set image name in job wrapper
Obtain scheme from client when building a reconciler
Testing util to build a context with verbose logging

Which issue(s) this PR fixes:

Fixes #
Special notes for your reviewer:
Does this PR introduce a user-facing change?

NONE

/assign @trasc

Created #951 for flaky test
/retest


How to close the Sidebar upon select of a menu item?

Thanks for this cool project!  How can I make the sidebar close when the user selects an option in the menu?

Thanks :wink:
Unfortunately, you can't do that easily using an AngularJs binding or such things. However, you probably can use css classes provided by the original semantic-ui. The sidebar component can accept an optional visible class that keep it shown until you remove it.
I'm not 100% sure if it works
<sidebar class="visible">...

By using a ng-class instead of just a class you'll be able to bind this capability to a ng-click

Thanks I tried using ng-class but could not find the magic formula.  This is simpler and works for me (JQuery required)
$scope.closeSidebar = function() {
    $('.ui.sidebar').sidebar('toggle');
};

corresponding HTML:
<div ng-controller="SidebarCtrl">
    <sidebar-link icon="home" title="Home" href="/" ng-click="closeSidebar()"></sidebar-link>
    <sidebar-link icon="rocket" title="Interests" href="interests" ng-click="closeSidebar()"></sidebar-link>
</div>


Small refactor of Custom Resources topic

Adjusts levels
Removes some obsolete info
Rewrite of some of the intro material

/assign @steveperry-53

Addressed feedback by amending. PTAL :)

/approve

Hi @mistyhacks looks like there are some review comments from @kbhawkey .
Could you please take a look at it.


[SPARK-31030] [DOCS] [FOLLOWUP] Replace HTML Table by Markdown Table

What changes were proposed in this pull request?
This PR is to clean up the markdown file in remaining pages in sql reference. The first one was done by @gatorsmile in this 28415

Replace HTML table by MD table
sql-ref-ansi-compliance.md

sql-ref-datatypes.md (Scala)

sql-ref-datatypes.md (Java)

sql-ref-datatypes.md (Python)

sql-ref-datatypes.md (R)

sql-ref-datatypes.md (SQL)

sql-ref-syntax-qry-select-tvf.md

Why are the changes needed?
Make the doc cleaner and easily editable by MD editors
Does this PR introduce any user-facing change?
No.
How was this patch tested?
Manually using jekyll serve

cc @huaxingao @gatorsmile

Test build #122182 has started for PR 28433 at commit 4debc83.

Merged build finished. Test PASSed.

Test PASSed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder-K8s/26854/
Test PASSed.

Test build #122182 has finished for PR 28433 at commit 4debc83.

This patch passes all tests.
This patch merges cleanly.
This patch adds no public classes.

Merged build finished. Test PASSed.

Test PASSed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/122182/
Test PASSed.

cc @maropu

Test build #122186 has started for PR 28433 at commit c419b93.

Merged build finished. Test PASSed.

Test PASSed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder-K8s/26858/
Test PASSed.

Test build #122186 has finished for PR 28433 at commit c419b93.

This patch passes all tests.
This patch merges cleanly.
This patch adds no public classes.

Merged build finished. Test PASSed.

Test PASSed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/122186/
Test PASSed.

Replace HTML table by MD table

All the fixes in docs/sql-ref-* addressed in this PR? I found the tag in sql-ref-null-semantics.md, too;
$ls sql-ref* | xargs grep "<table " .
sql-ref-ansi-compliance.md:

sql-ref-ansi-compliance.md:

sql-ref-datatypes.md:

sql-ref-datatypes.md:

sql-ref-datatypes.md:

sql-ref-datatypes.md:

sql-ref-datatypes.md:

sql-ref-datetime-pattern.md:

sql-ref-null-semantics.md:

sql-ref-null-semantics.md:

sql-ref-null-semantics.md:

sql-ref-null-semantics.md:

sql-ref-syntax-qry-select-tvf.md:

@maropu sorry, i missed sql-ref-null-semantics.md. I have added it now.

Test build #122193 has started for PR 28433 at commit 15da96c.

Merged build finished. Test PASSed.

Test PASSed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder-K8s/26865/
Test PASSed.

Test build #122193 has finished for PR 28433 at commit 15da96c.

This patch passes all tests.
This patch merges cleanly.
This patch adds no public classes.

Merged build finished. Test PASSed.

Test PASSed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/122193/
Test PASSed.

Test build #122220 has started for PR 28433 at commit 028746b.

Merged build finished. Test PASSed.

Test PASSed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder-K8s/26892/
Test PASSed.

Test build #122220 has finished for PR 28433 at commit 028746b.

This patch passes all tests.
This patch merges cleanly.
This patch adds no public classes.

Merged build finished. Test PASSed.

Test PASSed.
Refer to this link for build results (access rights to CI server needed):
https://amplab.cs.berkeley.edu/jenkins//job/SparkPullRequestBuilder/122220/
Test PASSed.

@maropu @srowen Can this get in now, if there are no other comments ? The reason i ask is @huaxingao has a big PR which is changing a lot of files. If this can get in first then she can rebase and push ?

Looks fine and I'll merge this first.

Thanks a lot @maropu @huaxingao @srowen @gatorsmile

Thanks! Merged to master/3.0. If @srowen has more comments, please ping @huaxingao so that she can include more fixes in her PR (#28451).

Ur, the jira ID is incorrect? @dilipbiswal

@maropu Thanks for fixing the title.


React js warning

Hi,
When I'm running your example code I receive a warning in the error console. "unknow prop formvalue on  tag". This appears to be caused by the value "formValue" in the Fieldset component.
Have you encountered this before? My example code is below..
`class Form extends React.Component {
constructor(props) {
super(props)
let formValue = createValue({
value: props.value,
onChange: this.onChange.bind(this)
})
this.state = {formValue}
}
onChange(formValue) {
this.setState({formValue})
}
render() {
return (

)
}
}
function EditCompany() {
return (

<FormattedMessage {...messages.header} />

<Form value={{firstName: 'Michael', lastName: 'Jackson'}} />

);
}
export default EditCompany;`
Console warning:
warning.js:36 Warning: Unknown propformValueon <div> tag. Remove this prop from the element. For details, see https://fb.me/react-unknown-prop     in div (created by Fieldset)     in Fieldset (created by Form)     in Form (created by EditCompany)     in div (created by Well)     in Well (created by EditCompany)     in div (created by EditCompany)     in EditCompany (created by RouterContext)     in div (created by Col)     in Col (created by App)     in div (created by Row)     in Row (created by App)     in div (created by Grid)     in Grid (created by App)     in App (created by RouterContext)     in RouterContext (created by Router)     in ScrollBehaviorContainer (created by Router)     in Router     in IntlProvider (created by LanguageProvider)     in LanguageProvider (created by Connect(LanguageProvider))     in Connect(LanguageProvider)     in Provider

I seem to be getting the same warning. And only beta version of this is working , the other stable one is not

Getting this warning too with 2.0.0-beta35


Upgrade [Bonus]

Please review the project and update to the latest versions of the project dependencies.

Platzi Master - Rafael León


Corrupted PDF display under Crostini (ChromeOS Linux container)

Attach (recommended) or Link to PDF file here:
Using the demo PDF on the pdf.js website
Configuration:

Chromium Version 79.0.3945.130 (Developer Build) built on Debian 10.2, running on Debian 10.2 (64-bit)
Operating system and its version: Debian Buster running in the ChromeOS Linux default container ("Crostini")
PDF.js version: whatever version the demo on the PDF.js web page uses
Is a browser extension: NO

Steps to reproduce the problem:

Go to the PDF.js webpage
Click "Demo"

What is the expected behavior? (add screenshot)
PDF is displayed correctly
What went wrong? (add screenshot)
Most characters are simply not displayed.

Comments: I originally found out about this problem using the VScode LaTeX Workshop extension, which uses pdf.js to display PDF files produced by LaTeX. I was having the same issue with my own files---most characters just were not displayed. However, as shown above, the exact same behavior occurs when running a browser under Crostini.
If I instead visit the pdf.js website using Chrome, NOT within the Crostini container but under "regular" ChromeOS, everything works perfectly.

This does look more like a <canvas> and/or Font loading bug in the platform/browser itself, rather than a general PDF.js library issue (since otherwise you'd expect it to be broken everywhere).

Hm. Interesting. Indeed things seem to work using Firefox-esr (68.4.1esr 64-bit). See attached screenshot. So this seems to be a Chromium-on-Crostini-specific issue. As I mentioned in the original message, the issue dues not arise with the standard Chrome browser in ChromeOS . It does however arise with Chromium 79, and with the Chromium engine built into VSCode.

This doesn't look like something that can be fixed on the PDF.js side. It's best to report the issue to the Chrostini developers.


Dark Mode

Not as per design

Done,

Verified this issue on  Keeper dev app v 1.1.7(262)


[Suggestion] Use block_all API for block user

Twitter has another API for block user: https://twitter.com/i/users/block_all. (Currently it is using for CSV blocklist import feature)
This API can block many (up to 800)¹  user in single request. It would be great for Twitter-block-chain extension.
Example Usage:
POST /i/users/block_all

authenticity_token=0000000000000
user_ids[]=884033788858085377
user_ids[]=871952445361889280
user_ids[]=1000704020636360706
user_ids[]=831075168193695744

Response(JSON):
{
  "result": {
    "blocked": [
      "884033788858085377",
      "871952445361889280",
      "1000704020636360706",
      "831075168193695744"
    ],
    "failed": []
  }
}

¹ from twitter's code (https://abs.twimg.com/k/ko/2.pages_settings.ko.a848670d33a48950e987.js):
// ...
this.defaultAttrs({
  blockAllEndpoint: "/i/user/block_all",
  chunkSize: 800
}),
this.blockAllUsers = function(t, e) { ... }
// ...

very cool! sounds like it would work well for reducing network usage.

I think this API is not going to be available in the new PWA UI but hopefully they'll re-implement it soon.


Parsing Error in Tableau JDBC Queries

Tableau makes JDBC queries of the form:
'SELECT tableName.columnName AS columnName FROM tableName'
This format currently throws parsing error when the format is 'sql' in Broker Request.

@xiangfu0 aren't queries using this syntax now supported by the multi-stage engine? As long as useMultistageEngine=true this query should work without issue.  Can this be closed?


Draft, don't merge - use pipelinerun instead of jobs

ref: CWFHEALTH-3293

Hey @qixiang, I've tested this on my minikube cluster. I confirm you that this is running correctly. I was able to create a dependencyupdatecheck CR and a new pending pipelinerun was created. I'm working on the tests and then this PR is ready to a final review and to be merged.

@qixiang @FernandesMF @staticf0x @querti @nvtnlucie I think this is now ready for a review

All comments addressed.

Comments addressed.


docker: common/dev/debug/prod configurations

Currently, we advertise how to develop Invenio 2.x via Docker in our documentation, using DEV configuration. However, when somebody goes that way, he/she would find that running test suite reports many failures due to HTTP redirection associated with debugging mode.  This may be a rather surprising default...
I'd rather propose to strive at the defaults whether the following would hold true:
$ git checkout maint-2.0
$ docker-compose build
$ docker-compose up
$ docker exec -i -t invenio_web_1 python setup.py test

[...]

Ran 977 tests in 701.359s

OK (skipped=6)

(This is the case for Invenio 1.x Docker configurations, for our Flask-* and other projects...)
We could achieve this by reconsidering DEV -> DEBUG -> PROD modes, choosing a conservative default, and extending our configurations progressively for various use case scenarios. For example:

COMMON profile: create common Docker Compose configuration as docker-compose-common.yml that will be used as a base for everything;
DEV profile [default]: create docker-compose.yml that will extend COMMON to make Invenio runnable in a DEV friendly mode, without extra debugging and stuff, but mirroring what Travis/Jenkins do; useful for regular CI/kwalitee purposes;
DEBUG profile: if wanted, create another docker-compose-debug.yml that would extend COMMON/DEV with human-related DEBUG capabilities, with Flask-DebugToolbar/Werkzeug and friends on; either create new profile if needed or just pass appropriate environment variables to the DEV profile to achieve the same;
PROD profile: create yet another docker-compose-production.yml that will extend COMMON in a way that will be useful for composing production Invenio environments with overlays. (TBD)

WDYT? CC @crepererum @jirikuncar

Could be useful to have a full prod setup (haproxy, 2 web nodes, cache, mq, db master, db slave, task node).

Can we just improve our testing suite that checks during setUp that current_app.debug is False and if it's not it warns user and set current_app.debug = False.

@jirikuncar This would indeed take care of separate DEV/DEBUG profiles, so that only one configuration is sufficient.  And if we switch defaults to DEV mode, leaving PROD mode aside, then this should do, I think.

For the link that Tibor mentioned in the issue description: extend does not work with link, see:

https://github.com/docker/compose/pull/1088
https://github.com/docker/compose/issues/1495

For prod:

do we really want a full-setup here, because this would involve that we need to extend the mysql and redis base images as well to insure a proper security setup. otherwise, all deployed instances will have the same DB credentials :(
we might want to use another tool than docker-compose which works better on multi-machine setups, like http://kubernetes.io/ Did anyone test swarm?

For DEBUG=True + tests, this is somehow:

tune our test system to handle this
VS
deactivating the redirection debugger of Flask (my vote goes here)

More votes:

Dev. setup should run with DEBUG=True, because it is essential when working with new code. I cannot imagine to work without it and check the server logs for every exception.
I also vote that the dev. setup is quite similar to the production setup, because so devs. can test what happens in that case, which is:
no write access to most parts of the file system
encrypted connections in most places
very limited connections to other hosts
verified broker messages ( #3201 )
at the same time, I do not see any problems making the prod. setup more full-blown. Even on one machine, 8+ containers wouldn't be a problem.

extend does not work with link

Oops!

we might want to use another tool than docker-compose which works better on multi-machine setups, like http://kubernetes.io/ Did anyone test swarm?

Yes, I also see compose configurations as primarily targeted to single-machine systems and  developer-friendly or demo-friendly use cases.  For real scalable production, with haproxy and whatnot, Swarm may come handy. It plays nicely with CERN OpenStack, @jirikuncar tested it.  But when I looked last time at Swarm, only Ubuntu was supported.  Hopefully the support for CC7 is either already there or not too far away...

For DEBUG=True + tests, this is somehow: tune our test system to handle this VS deactivating the redirection debugger of Flask (my vote goes here)

Both options would address the issue at hand.  FWIW I also like the latter option better; it may be useful to have a possibility to run tests both in debug and non-debug modes.  It does not seem to be a very common need to debug redirections, this could be an opt-in switch via DEBUG_TB_INTERCEPT_REDIRECTS and friends.

Dev. setup should run with DEBUG=True

Can we then change default of DEBUG_TB_INTERCEPT_REDIRECTS to False?

@crepererum Please make any changes for maint-2.0, so that we can have the same Docker setup for all our v2.x branches.  Developer-oriented changes of this kind can go to past maintenance branches.


Built-in support for unsupported packages

Description of the new feature / enhancement
To avoid being exposed to security vulnerabilities, the importance of running on the latest versions of software is clear. Winget provides an upgrade command to help with this effort. However, it only has knowledge of new versions of a specific package ID. In some cases, a software vendor offers multiple package IDs for different versions. Examples of this:

Microsoft.DotNet.SDK.5, Microsoft.DotNet.SDK.6
Oracle.JDK.17, Oracle.JDK.18
Python.Python.2, Python.Python.3

Upgrades are limited to the versions available for a given package ID. There's no built-in winget experience to upgrade from one package ID to another. For example, winget doesn't provide an experience to upgrade from Microsoft.DotNet.SDK.5 to Microsoft.DotNet.SDK.6. I'm not suggesting it should provide an experience in this proposal. But I do think there are aspects of versioning that winget can improve upon, specifically when the software associated with such package IDs become unsupported.
Let's use Microsoft.DotNet.SDK.5 as an example. This version of the .NET SDK has been out of support since May 2022. But it still shows up in the default search experience with winget:
> winget search Microsoft.DotNet.SDK
Name                           Id                           Version                   Source
---------------------------------------------------------------------------------------------
Microsoft .NET SDK 7.0 Preview Microsoft.DotNet.SDK.Preview 7.0.100-preview.7.22377.5 winget
Microsoft .NET SDK 6.0         Microsoft.DotNet.SDK.6       6.0.400                   winget
Microsoft .NET SDK 5.0         Microsoft.DotNet.SDK.5       5.0.408                   winget
Microsoft .NET SDK 3.1         Microsoft.DotNet.SDK.3_1     3.1.422                   winget

That's not great. There's nothing here that indicates to the user that this is an unsupported product. And having the software vendor simply delete the unsupported package ID from the winget-pkgs repo doesn't provide a great experience for those still dependent on the package. It unilaterally breaks them without providing a path to a supported product.
The proposal is to provide a better experience for users of winget so that they...

avoid installing unsupported products without being made aware of that fact.
have the necessary information to upgrade/migrate to a supported product.

This would consist of multiple facets:

Provide a means for package authors to indicate when their package is no longer supported.
Provide a means for package authors to include an out of support message for users that provides them with the information to move off the unsupported package.
The default winget search should only show supported packages. Unsupported packages are made visible through the use of an explicit option.
If a user executes winget install on an unsupported package, the package's "out of support" message should be displayed.
If a user executes winget upgrade when they have an unsupported package installed, they should be presented with information indicating that they have unsupported packages installed.

Proposed technical implementation details
EndOfSupportDate Property
The first requirement is for package authors to have some means to indicate whether the package is supported or not. This may or may not be known at package creation time. The proposal is to add an optional property to <package-id>.installer.yaml that indicates when support for the package ends:
EndOfSupportDate: <UTC-value>

EndOfSupportNotes Property
Package authors can provide a message for users that explains the end of support status of the package. The proposal is to add an optional property to <package-id>.locale.<locale>.yaml that contains this message:
EndOfSupportNotes: <text>

Winget Search Experience
With this proposal, the winget search command would only show supported packages by default, determined by the EndOfSupportDate property described above. To show unsupported packages, an additional option is provided:
--show-unsupported-packages   Includes unsupported packages in the search results

In the search output, (unsupported) would be appended to the version for any unsupported packages.
Winget Show Experience
With this proposal, the winget show command would include output that indicates the end of support date and notes.
Winget Install Experience
With this proposal, the winget install command would output warning text provided by the EndOfSupportNotes property described above if they were to install an unsupported package.
Winget Upgrade Experience
With this proposal, the winget upgrade command would, by default, indicate a summary count of any packages that are unsupported. To get more detail, the user would use the --show-unsupported-packages option which displays the end of support details of all unsupported packages.
--show-unsupported-packages   Show unsupported packages

The details would output the text provided by the EndOfSupportNotes property described above.
Example
Let's use the Microsoft.DotNet.SDK.5 package as an example to illustrate this proposal.
In Microsoft.DotNet.SDK.5.installer.yaml, add the following property:
EndOfSupportDate: 2022-05-10T00:00:00Z

In Microsoft.DotNet.SDK.5.locale.en-US.yaml, add the following property:
EndOfSupportNotes: Support for .NET 5 ended on May 10, 2022. Please upgrade to a supported version. You can find supported versions of .NET at https://dotnet.microsoft.com/download/dotnet.

With these settings, the package is appropriately configured to provide a better experience for users when using the winget CLI.
Now when the user attempts to search for .NET SDK with winget, they won't see Microsoft.DotNet.SDK.5 if their system clock is after May 10, 2022:
> winget search Microsoft.DotNet.SDK
Name                           Id                           Version                   Source
---------------------------------------------------------------------------------------------
Microsoft .NET SDK 7.0 Preview Microsoft.DotNet.SDK.Preview 7.0.100-preview.7.22377.5 winget
Microsoft .NET SDK 6.0         Microsoft.DotNet.SDK.6       6.0.400                   winget
Microsoft .NET SDK 3.1         Microsoft.DotNet.SDK.3_1     3.1.422                   winget

But they can get it if they use the --show-unsupported-packages option:
> winget search Microsoft.DotNet.SDK --show-unsupported-packages
Name                           Id                           Version                   Source
---------------------------------------------------------------------------------------------
Microsoft .NET SDK 7.0 Preview Microsoft.DotNet.SDK.Preview 7.0.100-preview.7.22377.5 winget
Microsoft .NET SDK 6.0         Microsoft.DotNet.SDK.6       6.0.400                   winget
Microsoft .NET SDK 5.0         Microsoft.DotNet.SDK.5       5.0.408 (unsupported)     winget
Microsoft .NET SDK 3.1         Microsoft.DotNet.SDK.3_1     3.1.422                   winget

When using winget show, they can see the unsupported status of the package:
❯ winget show Microsoft.DotNet.SDK.5
Found Microsoft .NET SDK 5.0 [Microsoft.DotNet.SDK.5]
Version: 5.0.408
Publisher: Microsoft Corporation
Moniker: dotnet-sdk-5
Description: .NET is a free, cross-platform, open-source developer platform for building many different types of applications.
Homepage: https://dotnet.microsoft.com
License: MIT
Installer:
  Type: burn
  Download Url: https://dotnetcli.azureedge.net/dotnet/Sdk/5.0.408/dotnet-sdk-5.0.408-win-x64.exe
  SHA256: 860f7aec7716141bbc09ce7366feb0f1c96ab330611b4641fea8b068ca7f6cd4
End of support date: 2022-05-10
End of support notes: Support for .NET 5 ended on May 10, 2022. Please upgrade to a supported version. You can find supported versions of .NET at https://dotnet.microsoft.com/download/dotnet.

When attempting to install the package, the user sees the end of support notes:
> winget install Microsoft.DotNet.SDK.5
Found Microsoft .NET SDK 5.0 [Microsoft.DotNet.SDK.5] Version 5.0.408
This application is licensed to you by its owner.
Microsoft is not responsible for, nor does it grant any licenses to, third-party packages.
Downloading https://dotnetcli.azureedge.net/dotnet/Sdk/5.0.408/dotnet-sdk-5.0.408-win-x64.exe
  ██████████████████████████████   147 MB /  147 MB
Successfully verified installer hash
Starting package install...
Successfully installed

WARNING: Support for .NET 5 ended on May 10, 2022. Please upgrade to a supported version. You can find supported versions of .NET at https://dotnet.microsoft.com/download/dotnet.

Now that the user has the package installed, the upgrade experience indicates an unsupported package is installed:
> winget upgrade
Name           Id             Version     Available     Source                                                          --------------------------------------------------------------                                                          Microsoft Edge Microsoft.Edge 90.0.818.66 104.0.1293.54 winget                                                          1 upgrades available.
1 unsupported package installed (use the --show-unsupported-packages option for details).

The user can get details on the unsupported packages using the --show-unsupported-packages option:
> winget upgrade --show-unsupported-packages
Name                   Id                     Version End of Support
--------------------------------------------------------------------
Microsoft .NET SDK 5.0 Microsoft.DotNet.SDK.5 5.0.408 2022-05-10

View the notes for end of support by executing "winget show <Id>"

cc @MichaelSimons, @ashnaga

We should also think about the experience with winget import and consolidation of the notes.
Other potentially related issues:

https://github.com/microsoft/winget-cli/issues/1899
https://github.com/microsoft/winget-cli/issues/1900

I would suggest --include-unsupported instead of --show-unsupported-packages, to better align with --include-unknown


More unit test improvements

Complete

Added new style of tests for Ring, Rope, Segment
Added tests to improve code coverage from 84% to 91%
Added tests where argument FP is Float32 or BigFloat, discovered issues leading to:

Some loss of precision with Float32 (loosened test atol parameter)
Type instability, i.e. Float32 results are promoted to Float64

Documented in Issue #74

Added notes to integral docstring

Future Work (Other PR's)

Add a method for manual tracking of which combinations of integral argument types have tests implemented
Re-consider whether argument FP should be a kwarg, i.e. integral(f, geometry, settings; FP=BigFloat)

@JoshuaLampert do you have time for a review?

I see a lot of commits in the PR, which indicates to me that you don't run the tests locally (?). While that's of course totally fine, it might still be more convenient and probably faster to run the tests during development locally, such that CI doesn't need to be triggered each time again to get some response.

I try not to dev this way, but I've been away from my workstation a lot lately and had to push these commits from GitHub's browser file editor 😅.

If you agree that this is also worth implementing in MeshIntegrals.jl, I can also set up a PR for that. Now that I finished writing this, I just saw you also mention TestItems.jl in https://github.com/mikeingold/MeshIntegrals.jl/issues/67 😅

I'm definitely interested in implementing TestItems.jl soon but was planning to get all of the tests updated first. At some point earlier this year I came up with a scheme for trying to generate @tests on all valid combinations {integral function name, integrand output type, Meshes.Geometry sub-type, IntegrationAlgorithm}. It sounded like a good idea in principle, and provided a big boost in test coverage at a time, but: it relies on Meshes.measure as a benchmark, only covers cases with unit integrand (p -> one(T)), tends to bloat the test run-times with some potentially-redundant coverage, and tended to slightly obscure what actually went wrong when a test might fail. My plan has been to transition toward a style of tests more like what Meshes uses, i.e. modular blocks of concrete tests with analytic solutions.
One of the things I am conflicted about conceptually, though, is how to manage true test coverage this way. For example, pretty much any individual call of the form integral(f, geometry, ::HAdaptiveCubature) now relies on the same method, so one applicable @test is enough to satisfy CodeCov for it. The note in the Future Work block above references a thought I had to manually populate some kind of table-like data structure, with entries in each appropriate @testset to indicate which combinations are exercised. It isn't the most elegant solution, though, so I'm all ears if you have other ideas.

I've noticed periodic issues where the macOS CI alone will error and it's usually something odd not related to the actual package, so I was about to re-run the failing test, but I noticed that this one has a really odd error being thrown seemingly out of Meshes.
This function (inside another function in utils.jl) generates a parametric call (::Ball{3})(rho, theta, phi)
https://github.com/mikeingold/MeshIntegrals.jl/blob/8349dbc64a42712ef151d929337c65ec5e07a848/src/utils.jl#L29-L35
which at this line in Meshes.jl for some reason generates an error trying to convert to an Int
https://github.com/JuliaGeometry/Meshes.jl/blob/c8b2b936808a2b0810bf1c0130a077deb2a10d3c/src/geometries/primitives/ball.jl#L62C3-L62C30

I've seen this error already before in a completely different context here (also only on Mac):
JoshuaLampert/DispersiveShallowWater.jl/actions/runs/10811172112/job/29990016675?pr=150#step:7:8511
This is indeed very weird, but not related to anything we should worry too much about, I think.

I'm definitely interested in implementing TestItems.jl soon but was planning to get all of the tests updated first.

I see, but I think having TestItems.jl running might make the development of the new tests more convenient. Thus, I would think implementing TestItems.jl first and updating the remaining tests after that might be worth considering (assuming, of course, that you use your workstation in future PRs again because otherwise TestItems.jl doesn't make anything more convenient :sweat_smile:).

I've seen this error already before in a completely different context here (also only on Mac): JoshuaLampert/DispersiveShallowWater.jl/actions/runs/10811172112/job/29990016675?pr=150#step:7:8511 This is indeed very weird, but not related to anything we should worry too much about, I think.

Interesting. I wonder if this is some obscure bug in Base. Looks like your example triggers here.
https://github.com/JuliaLang/julia/blob/911e02558d0c145a192facd28808b68e157aa5af/base/special/trig.jl#L841

I'm definitely interested in implementing TestItems.jl soon but was planning to get all of the tests updated first.

I see, but I think having TestItems.jl running might make the development of the new tests more convenient. Thus, I would think implementing TestItems.jl first and updating the remaining tests after that might be worth considering (assuming, of course, that you use your workstation in future PRs again because otherwise TestItems.jl doesn't make anything more convenient 😅).

That was just the order-of-events I was planning to work personally. If you're up for implementing TestItems once this PR is merged, I'm all for it.

I think all reviews have now been addressed. Let me know if I'm missing anything.

Interesting. I wonder if this is some obscure bug in Base. Looks like your example triggers here.
<EMAIL_ADDRESS>
Yes, might be.

LGTM!


feat: open source the cloud abstractions diagram

Open source the cloud abstractions diagram originally shared on LinkedIn:
https://www.linkedin.com/feed/update/urn:li:activity:6844403328449937408/

@desktophero The cloud abstractions diagram is officially open-source under CC0 1.0 Universal license (completely free) https://www.ourchitecture.io/hello-cloud/clouds/#cloud-deployment-types
Diagram source: https://github.com/ourchitecture/hello-cloud/tree/main/src/media/diagrams/cloud-computing-abstractions


Release 1.5.0 to master

Includes all the commits from develop since 1.4.0 release to master.
There is one extra commit only due to leftover 1.4.0 references.

Moved to #1197 due to CI issues (gitlab push mirroring doesn't like / in the names).


unmatched closing tag in example page "Übersichtsseite"

The example page "Übersichtsseite", located at https://swiss.github.io/styleguide/de/pages/03.preview.html has an unmatched closing tag on the line

EN

There are also other issues when using the validator at
https://validator.w3.org/nu/?doc=https%3A%2F%2Fswiss.github.io%2Fstyleguide%2Fde%2Fpages%2F03.preview.html
Since I am using the "Übersichtsseite" as base for a new website under the admin.ch domain I am stumbling over these (admittedly quite minor), and feel the need to report those.


Using together BMI160 + HMC5883L

Hello there!
Please tell me, it is possible use BMI160 + HMC5883L together? BMI160 it is great IMU for cheaper SlimeVR tracking, but all 6DOF IMU's affected to the drift.
It is possible use external magnetometer for drift compensation on BMI160? I saw on official website it working for MPU series IMU.
But on this repository in README.md we can see BMI160 compability section. Аlthough there is mention of a magnetometer. And we don't see any information about how to use it with.
How to do?
How to get working BMI160 + HMC5883L together?

any ideas on latest 0.4.0 firmware?

Found on Discord group:
Solder HMC SDA to BMI160 SDX, and solder HMC SCL to BMI160 SDX. Do not forget solder VCC and GND.
Check chip orientation via datasheet(do not use silkscreen printing on HMC pcb, it maybe can incorrect.
For woking HMC with BMI160 you need download firmware source and build manually(do not use online firmware builders) you need prepare firmware, here is 2 links from official wiki can help you.
Setting up the Environment
Configuring the Firmware Project
After setting building environment and configure firmware you need to go next steps:

Open  debug.h and find

#define USE_6_AXIS true

change to
#define USE_6_AXIS false

Next step you need to go defines_bmi160.h and find this line. Uncomment this :)

#define BMI160_MAG_TYPE BMI160_MAG_TYPE_HMC

These 2 lines enables magnetometer support for HMC5883L and BMI160
3. Build & Flash firmware.
4. After flashing do calibration.
if you feel with wrong magnetometer axes you can remap them:
Open defines.h and find Axis remapping example.
Place this code after example:
  #define BMI160_AXIS_REMAP_PRIMARY AXIS_REMAP_BUILD( \
  AXIS_REMAP_USE_X, \
  AXIS_REMAP_USE_Y, \
  AXIS_REMAP_USE_Z, \
  \
  AXIS_REMAP_USE_XN, \
  AXIS_REMAP_USE_YN, \
  AXIS_REMAP_USE_Z \
)

where AXIS_REMAP_USE_XN used for negation of X axis as example.
If you use default calibration methods(gyro calibrate 5 secs, 6 sided accelerometer calibration) you will have a more one step for calibrate your HMC. This step includes describing the infinity sign in the air for 20 seconds (with a tracker in hand)
if you finished calibration, tracker will be use magnetometer for drift correction.
I will close this issue.

@Tanamichi Hey there, has this significantly improved tracking? Currently as soon as you leave the calibrated position, the drift gets very bad on the chnaged axis...

@C9Glax, Yeah, because magnetic environment is poor at your place. I have same issue, but if i'm stay in place were i'm calibrated i have stable results..
Also i have return to origin rotation were i pressed "Full Reset" in slime server.
For now best way use trackers without HMC or QMC with BMI160.
Cheers.

Just to clarify:
It's better to not use HMC/QMC?
Thanks for the answer :)

@C9Glax Yes. For now do not use it :)

Okay thank you! ❤


Adopt use of black instead of yapf

This change is switching our code-formatter from yapf to black, which
become far more popular, mainly because it is not configurable. This
means that project maintainers no longer have the option to introduce
their own oppionated settings.
Black is now hosted under official Python Foundation GitHub organization
and was already adopted by major projects like pytest and django.
Another serious benefit is speed, black is incomparebly faster than yapf
and can be used as a pre-commit hook.

Please review this, is only reformated by black, the faster we do the switch the easier it will be.

Add a pyproject.toml with the following:
[tool.black]
skip-string-normalization = true

@decentral1se Addressed your concerns but I will make another change to also change the quotes as I think that one would be useful too (for consistency). Still, it makes no sense to delay adopting your suggestion as the first step.
Regarding existing PRs, we have only 30 now and their authors can easily rebase them and re-run linting, not a real deal. We used to have >100 ones so now we are much better.

@decentral1se Addressed your concerns but I will make another change to also change the quotes as I think that one would be useful too (for consistency). Still, it makes no sense to delay adopting your suggestion as the first step.

Huh!? The whole point is to not change the quotes to reduce the diff. I have no idea what you mean by "consistency" in this context. My concern is to address consistency (keep using single quote style we already have) while yours is to break consistency and increase the diff size. Please spare me this purism of "not having a config" because Black's "philopsophy" or whatever..

@decentral1se please re-review, the current code followed all your comments. I just want to merge it ASAP because otherwise I will have to rebase it after each other PR merged.


How to build?

I'm a bit of a C# noob and outside of Unity I'm a bit lost. I've tried building this in Visual Studio and I get as far as this error:
CS0246	The type or namespace name 'SteamVR_WebKit' could not be found (are you missing a using directive or an assembly reference?)

Hm, that's strange and shouldn't happen. @robnewton did you have this problem?

Nope, try deleting the VS solution and grabbing the latest version again.