Unable to push images to GCR from non GKE cluster or GKE cluster under different project

Expected Behavior
I can have a build push images to GCR from cluster that is not a GKE cluster within the same project as GCR
Actual Behavior
Getting auth errors. Looks like some GCR Access Control is missing when building and pushing images from non GKE cluster or a GKE cluster that is running under a different project.
Steps to Reproduce the Problem

Apply Kaniko build-remplate:

kubectl apply -f https://raw.githubusercontent.com/knative/build-templates/master/kaniko/kaniko.yaml

Create Cloud IAM service account with 'roles/storage.admin' in the Project used for GCR and json key file

export GCP_PROJECT=$(gcloud config get-value core/project)
gcloud iam service-accounts create push-image
gcloud projects add-iam-policy-binding $GCP_PROJECT \
  --member<EMAIL_ADDRESS>\
  --role roles/storage.admin
gcloud iam service-accounts keys create \
  --iam-account<EMAIL_ADDRESS>\
  $HOME/push-image.json

Create a Kubernetes cluster using a different project and install recent Knative build and serving.

Create secret and k8s service account

kubectl create secret generic kaniko-secret --from-file=$HOME/kaniko.json
kubectl annotate secret kaniko-secret build.knative.dev/docker-0=https://gcr.io
kubectl apply -f kaniko-sa.yaml

where kaniko-sa.yaml is:
apiVersion: v1
kind: ServiceAccount
metadata:
  name: build-bot
secrets:
- name: kaniko-secret

Create the build, I named mine kaniko-square.yaml

apiVersion: build.knative.dev/v1alpha1
kind: Build
metadata:
  name: kaniko-build
spec:
  serviceAccountName: build-bot
  source:
    git:
      url: https://github.com/trisberg/node-kaniko-square.git
      revision: master
  template:
    name: kaniko
    arguments:
    - name: IMAGE
      value: gcr.io/[your-GCR-project]/node-kaniko-square

Apply the build

kubectl apply -f kaniko-square.yaml

and check the build status and logs.
Additional Info
I got this:
$ kubectl logs -c build-step-build-and-push kaniko-build-pngcq
INFO[0000] Downloading base image projectriff/node-function-invoker:0.0.9-snapshot
ERROR: logging before flag.Parse: E1030 19:57:31.499621       1 metadata.go:159] while reading 'google-dockercfg-url' metadata: http status code: 404 while fetching url http://metadata.google.internal./computeMetadata/v1/instance/attributes/google-dockercfg-url
ERROR: logging before flag.Parse: E1030 19:57:31.504745       1 metadata.go:142] while reading 'google-dockercfg' metadata: http status code: 404 while fetching url http://metadata.google.internal./computeMetadata/v1/instance/attributes/google-dockercfg
2018/10/30 19:57:31 No matching credentials were found, falling back on anonymous
INFO[0000] Executing 0 build triggers
INFO[0000] Extracting layer 0
INFO[0000] Extracting layer 1
INFO[0002] Extracting layer 2
INFO[0002] Extracting layer 3
INFO[0002] Extracting layer 4
INFO[0002] Extracting layer 5
INFO[0005] Taking snapshot of full filesystem...
INFO[0008] ENV FUNCTION_URI /functions/square.js
INFO[0008] Using files from context: [/workspace/square.js]
INFO[0008] ADD square.js ${FUNCTION_URI}
INFO[0008] Taking snapshot of files...
error pushing image: failed to push to destination gcr.io/cf-sandbox-trisberg/node-kaniko-square:latest: no token in bearer response:
{"errors":[{"code":"DENIED","message":"Token exchange failed for project 'cf-sandbox-trisberg'. Caller does not have permission 'storage.buckets.get'. To configure permissions, follow instructions at: https://cloud.google.com/container-registry/docs/access-control"}]}

/assign pivotal-nader-ziada

For Kaniko to be able to push to a Google Cloud Registry on a different project, it needs a Kubernetes secret, which contains the auth required to push the final image.
From the Kaniko docs: How to run Kaniko on a Kubernetes cluster
you must first create the secret
kubectl create secret generic kaniko-secret --from-file=<path-to-service-account.json>

And make the Pod look like this
apiVersion: v1
kind: Pod
metadata:
  name: kaniko
spec:
  containers:
  - name: kaniko
    image: gcr.io/kaniko-project/executor:latest
    args: ["--dockerfile=<path to Dockerfile within the build context>",
            "--context=gs://<GCS bucket>/<path to .tar.gz>",
            "--destination=<gcr.io/$PROJECT/$IMAGE:$TAG>"]
    volumeMounts:
      - name: kaniko-secret
        mountPath: /secret
    env:
      - name: GOOGLE_APPLICATION_CREDENTIALS
        value: /secret/kaniko-secret.json
  restartPolicy: Never
  volumes:
    - name: kaniko-secret
      secret:
        secretName: kaniko-secret

but currently in Kaniko build-template, the volume and secret are not supported
we have the following options:

create a 2nd Kaniko template that works with an external Google Cloud Registry
change the ApplyTemplate logic in build to somehow allow the user to append to the template
tell users to build their own custom template?

I'm able to push to a Google Cloud Registry from a PKS cluster using the following custom template: (@trisberg if you need a workaround)
apiVersion: build.knative.dev/v1alpha1
kind: BuildTemplate
metadata:
  name: kaniko-for-external-cluster
spec:
  parameters:
  - name: IMAGE
    description: The name of the image to push
  - name: DOCKERFILE
    description: Path to the Dockerfile to build.
    default: /workspace/Dockerfile

  steps:
  - name: build-and-push
    image: gcr.io/kaniko-project/executor
    args:
    - --dockerfile=${DOCKERFILE}
    - --destination=${IMAGE}
    volumeMounts:
    - name: kaniko-secret
      mountPath: /secret
    env:
    - name: GOOGLE_APPLICATION_CREDENTIALS
      value: /secret/kaniko-secret.json
  volumes:
  - name: kaniko-secret
    secret:
      secretName: kaniko-secret

@ImJasonH @shashwathi wdyt?

We already create a secret for the service account, are you saying that we need an additional secret, that seems like the wrong solution? I'm having same issue using the buildpack template as well, so it seems to be a general problem that the build doesn't use the secret provided to the service account.

The Kaniko build-template doesn't pick up the secret unless its in the format mentioned here: https://github.com/GoogleContainerTools/kaniko#kubernetes-secret
Even if you have the secret, Kaniko doesn't read it.
Using the custom template above, I can push an image to gcr from a pks cluster

It seems to use the service account secret when pushing to Docker Hub, so I wonder why GCR is different.

In the Kaniko docs here https://github.com/GoogleContainerTools/kaniko it says there are different methods of authentication based on the target registry

@trisberg

... I'm having same issue using the buildpack template as well, so it seems to be a general problem that the build doesn't use the secret provided to the service account.

I neither tried Kaniko nor GCR, but had the same issue using the buildpack template on an AWS K8s cluster using ECR as docker registry.
The reason for this behavior is that the buildpack export step uses credential helpers for GCP, AWS, and Azure by default. On AWS this helper then creates a docker configuration based on the IAM role of the EC2 instance that runs the build pod.
Disabling these helpers results in the service account's secret to be used. See https://github.com/knative/build-templates/pull/83


try to use your plugin apex-plugin-apexsignature

i try to use your plugin
apex-plugin-apexsignature
but when i try to save sig to my database i get error
Ajax call returned server error ORA-01403: no data found for Execute PL/SQL Code
this line
l_blob := apex_web_service.clobbase642blob(p_clob => l_clob);
can you help me?:)
APEX 19-ORDS

hi any body there :(

Sorry but this don't help me a lot, just saying it doesn't work without giving much detail is difficult for me...
Which APEX version do you use, which ORDS version?
I created a issue template just for that (if you click new issue), but you deleted everything in there and just gave very basic information, which don't help me a lot...
How does your PL/SQL code look like? Here's an example:
https://github.com/Dani3lSun/apex-plugin-apexsignature#save-to-db-using-plsql-default-code-of-plugin

Hi Dani3lSun. I can help you over zoom if you'd like. But I also know I am several months too late.


[ES]: Add ES 5.x

From @TamalSaha on March 7, 2017 5:29
Copied from original issue: k8sdb/elasticsearch#8

This issue was moved to kubedb/project#74


Run this project from Wyoming Satellite?

First, thank you for this project, really great! I was thinking if would be possible to send these commands using a Pi running the Wyoming Satellite project? I have set up a pi zero 2w with the respeaker 2mic hat and routed my audio to bluetooth connected to my Ditoo Pro, so I am able to use OWW, send commands, TTS from the pi and listening the responses in the Ditoo Pro. Would be great if was possible to send these Divoom commands directly from the Pi instead of having to use an ESP32 as proxy. Also if you have posted about this integration somewhere, share the link here, thank you.

This project is exclusively for an ESP32 (or compatible microcontrollers), but it was created to give users of my Home Assistant Integration more options and/or more range for their connectivity. Therefore this particular project might not help you, but you are free to have a look into my Home Assistant Integration (specifically this file, which includes most of the communication parts) and use the parts you need. Its written in Python, which is basically the language often used in projects for a Raspberry Pi (like the Wyoming Satellite project you mentioned).

I knew you had already done what I was looking for, and I looked in your integration before, but I missed that file. Thanks for pointing out this file, got it to work on my pi running the wyoming satellite project but your integration in HA will obviously not work. Any chance you could make it work using this way?


Add support for vertical orientation

As mentioned in #12 this commit adds support for vertically-oriented plots.. I've tested it a bit with plot_direction and it seems to behave in a sensible manner, e.g.

You can create a full set of these graphs with
for direction in ('NW', 'SW', 'NE', 'SE'):
    for vertical in [True, False]:
        for rows in [4, 3]:
            fig = plt.figure(
                FigureClass=Waffle, rows=rows, vertical=vertical, plot_direction=direction, values=[5, 3, 2],
                title={
                    'label': f'vertical={vertical}, rows={rows}, plot_direction={direction}',
                    'loc': 'left'
                },
            )
            fig.savefig(f'{vertical}_{rows}_{direction}.png', bbox_inches='tight')
            plt.close('all')

One additional tweak that might be nice to make would be to allow the user to only specify the number of columns required, though I haven't got round to looking at this yet.


Remote logging UX | design

User story
As technical support, I would like to see usage logs of a user so that I can understand where the underlying issue is
Acceptance Criteria
Given a user is experiencing an issue
And is asked by technical support to turn on remote logging
When the user enables remote logging
Then they are presented with the remote logging
And this screen displays the Session ID
And the turn on button is only enabled when the checkbox is checked
Given the user wants to turn on remote logging
When the user turns on remote logging
Then remote logging starts
And a static red banner is displayed underneath the header for that screens that lets people know that remote logging is on
And the red banner has the session ID number displayed

To be reviewed with dev team.


Add this project to the awesome-harbor list

This is an outstanding project. I think it is a perfect candidate to add it to the https://github.com/container-registry/awesome-harbor.

Hey @Vad1mo,
thanks for suggesting our projects! I've prepared a PR right here


ORA-12170

When connecting to a specific oracle database I get

ORA-12170: TNS:Connect timeout occurred

while other databases works fine. However this appears to be an omni-db specific problem since my other applications connect to that database without hassle.
Regards
pgaro

Hi @pgaro ,
Thanks for reaching out. Please let us know more details so we can better understand the issue.

At the moment OmniDB connects to Oracle by using the notation user/pwd@host:port/service. For the release 2.8 we will improve this by also allowing the notation user/pwd@service if the user leaves host and port empty. This notation will allow users to connect to Oracle using client-side tnsnames.ora and sqlnet.ora files. So, how do other applications connect to that database?

For this specific database, by any chance do you have in sqlnet.ora, server side, specific values for SQLNET.INBOUND_CONNECT_TIMEOUT, SQLNET.SEND_TIMEOUT and/or SQLNET.RECV_TIMEOUT?

Regards,
William Ivanski

I always connect with user, host, port and ssid (and pwd ofc, while I type that into omnidb when I connect). I don't have client side tnsnames.ora and sqlnet.ora files on the specific machine.
The specific database has "SQLNET.INBOUND_CONNECT_TIMEOUT =180" set in the sqlnet.ora, while that should be plenty in normal circumstances, shouldn't it? This is the first application that seems to be bothered.
Regards
pgaro

@wind39: I copied the connection data to the server version and the issue doesn't seem to persist.
As you can guess, it's not a serious issue anymore. It's non the less surprising.
Regards
pgaro

Hi @pgaro ,
Thanks for your response. Interesting, I will dig into it some more and I will let you know about my findings here.
Regards,
William Ivanski

@wind39: I just installed the app again on a different machine for testing purposes and it works fine there. So it does seem to be tied to that specific installation rather than the app/server difference. I'll let you know if I'm able to dig up anything meaningful. I'm closing this in the meantime.
Regards
pgaro

Hello
I am having issues connecting OMNIDB via tnsnames.ora file
My omniDB version is 2.14, i have a 12.2 instant client have have placed the tnsnames and sqlnet under network/admin folder
when i don't give the host and port and just give Database field as the connect descriptor i get an error like
ORA-12154: TNS:could not resolve the connect identifier specified
Any help is highly appreciated.


Not listed in Package Control

Trying to install this on a diff. machine and currently Materialize does not show in pkg control on both machines.

That's weird, I haven't heard of anyone else having this issue.

Are you on Sublime Text 3 or Sublime Text 2? This theme requires you to be on ST3. Also, could you make sure you don't already have it installed? Open up the command palette with Ctrl+Shift+P and type in Package Control: List Packages and just make sure it isn't already listed there.

Removed the package and it now shows up again in package control. Must have been a bad install on my part :\ Anyways thanks for the quick reply.

Np, glad it's working :)


PutObjectWithContext() gets stuck if reading an empty file from a progress bar io.Reader

Hi,
We're facing an issue in the Exoscale CLI where objects uploads get stuck at reading if files are empty. At first it looked like an issue in the progress bar we use, but after some practical tests its author is suggesting the issue might be located in your library. Could you please have a look at this problem? Let me know if you need me to run additional tests.
Version used: v6.0.29

So I used progress bar from chegaa/pb
package main

import (
	"bytes"
	"context"
	"log"

	"github.com/cheggaaa/pb/v3"
	"github.com/minio/minio-go/v6"
)

func main() {
	// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-testfile, my-bucketname and
	// my-objectname are dummy values, please replace them with original values.

	// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
	// This boolean value is the last argument for New().

	// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
	// determined based on the Endpoint value.
	s3Client, err := minio.New("play.min.io", "Q3AM3UQ867SPQQA43P2F", "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG", true)
	if err != nil {
		log.Fatalln(err)
	}

	// Progress reader is notified as PutObject makes progress with
	// the Reads inside.
	progress := pb.New64(0)
	progress.Start()
	emptyReader := bytes.NewReader([]byte(""))
	n, err := s3Client.PutObjectWithContext(context.Background(), "testbucket", "my-objectname-progress", emptyReader, emptyReader.Size(), minio.PutObjectOptions{ContentType: "application/octet-stream", Progress: progress.NewProxyReader(emptyReader)})

	if err != nil {
		log.Fatalln(err)
	}
	progress.Finish()
	log.Println("Uploaded", "my-objectname", " of size: ", n, "Successfully.")
}

So I debugged the code to figure out why this is happening. Because we explicitly set req.Body as nil, without any non-nil body - this is an upstream Go bug and has been there historically https://github.com/aws/aws-sdk-go/commit/db7b69949079da41d74f9c6bfb150becb48db1e1
 ---------START-HTTP---------
PUT /testbucket/my-objectname-progress HTTP/1.1
Host: play.min.io
User-Agent: MinIO (linux; amd64) minio-go/v6.0.34
Content-Length: 0
Authorization: AWS4-HMAC-SHA256 Credential=**REDACTED**/20190806/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=**REDACTED**
Content-Type: application/octet-stream
X-Amz-Content-Sha256: UNSIGNED-PAYLOAD
X-Amz-Date: 20190806T234850Z
Accept-Encoding: gzip

HTTP/1.1 200 OK
Content-Length: 0
Accept-Ranges: bytes
Connection: keep-alive
Content-Security-Policy: block-all-mixed-content
Date: Tue, 06 Aug 2019 23:48:50 GMT
Etag: "d41d8cd98f00b204e9800998ecf8427e"
Server: nginx/1.10.3 (Ubuntu)
Vary: Origin
X-Amz-Bucket-Region: us-east-1
X-Amz-Request-Id: 15B87A4A617506C5
X-Amz-Server-Side-Encryption: AES256
X-Xss-Protection: 1; mode=block
---------END-HTTP---------

The object is indeed uploaded since the progress didn't move the progress bar is stuck.
package main

import (
	"bytes"
	"context"
	"log"
	"os"
	"time"

	"github.com/minio/minio-go"
	"github.com/vbauerster/mpb"
	"github.com/vbauerster/mpb/decor"
)

func main() {
	// Note: YOUR-ACCESSKEYID, YOUR-SECRETACCESSKEY, my-testfile, my-bucketname and
	// my-objectname are dummy values, please replace them with original values.

	// Requests are always secure (HTTPS) by default. Set secure=false to enable insecure (HTTP) access.
	// This boolean value is the last argument for New().

	// New returns an Amazon S3 compatible client object. API compatibility (v2 or v4) is automatically
	// determined based on the Endpoint value.
	s3Client, err := minio.New("play.min.io", "Q3AM3UQ867SPQQA43P2F", "zuf+tfteSlswRu7BJ86wekitnifILbZam1KYY3TG", true)
	if err != nil {
		log.Fatalln(err)
	}

	s3Client.TraceOn(os.Stderr)

	p := mpb.New(
		mpb.WithWidth(60),
		mpb.WithRefreshRate(180*time.Millisecond),
	)

	bar := p.AddBar(0, mpb.BarStyle("[=>-|"),
		mpb.PrependDecorators(
			decor.CountersKibiByte("% .2f / % .2f"),
		),
		mpb.AppendDecorators(
			decor.EwmaETA(decor.ET_STYLE_GO, float64(0)/2048),
			decor.Name(" ] "),
			decor.AverageSpeed(decor.UnitKiB, "% .2f"),
		),
	)

	emptyReader := bytes.NewReader([]byte(""))
	proxyReader := bar.ProxyReader(emptyReader)
	defer proxyReader.Close()

	n, err := s3Client.PutObjectWithContext(context.Background(), "testbucket",
		"my-objectname-progress", emptyReader, emptyReader.Size(),
		minio.PutObjectOptions{
			ContentType: "application/octet-stream",
			Progress:    proxyReader,
		})

	if err != nil {
		log.Fatalln(err)
	}
	p.Wait()
	log.Println("Uploaded", "my-objectname", " of size: ", n, "Successfully.")
}

While the object is indeed uploaded since the underlying reader is not reading the progress, the progress reader doesn't see an EOF which leads to a situation where it hangs. But since its a 0-byte file there is no progress bar, to begin with.
Go net/http client is pretty weird about how it handles empty body. So fixing this issue perhaps is going to be a problem, it will expose us again to other workarounds that we had to add to circumvent issues with zero bytes.

Another notorious example is perhaps this
https://golang.org/src/net/http/request.go?h=outgoingLength#L1368
// outgoingLength reports the Content-Length of this outgoing (Client) request.
// It maps 0 into -1 (unknown) when the Body is non-nil.
func (r *Request) outgoingLength() int64 {
	if r.Body == nil || r.Body == NoBody {
		return 0
	}
	if r.ContentLength != 0 {
		return r.ContentLength
	}
	return -1
}

So regardless of what you might have set to req.ContentLength it is auto probed internally and makes it really hard.  Because either the body has to be nil or equals http.NoBody - any wrapping by the caller makes it really hard to handle this.
Meaning if you didn't set this value and req.ContentLength is still set to '0' then the outgoingLength() will auto return "-1" which will fail for calls to AWS S3 since it explicitly requires Content-Length to be set.
At this point, I think the effort required to support this doesn't justify the effort needed on our end as we are as short-handed as you are.
NOTE: This is the same issue with aws-sdk-go as well.

@harshavardhana well thank you for the tests, I'll add the workaround suggested by @vbauerster in https://github.com/vbauerster/mpb/issues/7#issuecomment-518756758

I will perhaps try to persuade upstream to handle this properly in net/http perhaps in go1.13 cycle, because clearly they don't honor what was set by the caller here.
Thanks for using a workaround here @falzm

@falzm Closing the issue now. Please feel free to reach out to us if you have further questions.


Autocomplete allowing a user to select the same option multiple times

In the autocomplete component you are able to select the same option multiple times and it simply appends that option to the list shown.
Reproducing steps:
I selected 3 of the 4 available options in the dropdown, closed the dropdown, reopened it, unselected an option, closed the dropdown, and then when I reopened the dropdown it says that nothing is selected.  If you then go through and make a few selections and close the dropdown it will show more options than are possible as being selected.
In this example, I only have 4 items in the dropdown:

Thanks for the feedback! @AlyseTack  Could you please send us some sample code for investigation? Thanks!

Hi @MaggieMaSS I posted the code snippet in the workflow-olive chat but I'll do the same here. In this issue the component is physically returning the array of selections with duplicates because it's allowing a user to select something that is already selected since the dropdown is clearing out the selected checkboxes if you click around enough.
Here's the code I used to produce it. You have to click around a couple times. I haven't figured out the exact pattern but I've had it happen by having all the options selected, closing the dropdown, reopening the dropdown, and then selecting and unselecting the last option. I've been able to reproduce it a few times.
      <oh-autocomplete
        label="Visit Type"
        multiple={true}
        options={[{
          label: "Hospital Discharge",
          value: "0"
        },{
          label: "Behavioral Health Visit",
          value: "1"
        },{
          label: "ED Visit",
          value: "2"
        },{
          label: "Substance Use Visit",
          value: "3"
        }]}
        onSelect={(_, val) => {console.log(val)}}
        layout={{
          marginBottom: StyleSize.Medium,
        }}
      />

@AlyseTack  Thanks for your detailed description and code snippet! We have created HELPS-2161 to address this issue, and we'll keep you updated! Thanks!

this is getting tested on qa @AlyseTack

This bugfix has been released! Closing the thread

Thank you for the update!!


Deserialize with defaults

hello! would it be possible to add a deserialize_as_with_default function to the library?
for example if i serialize this:
#[derive(Serialize, Deserialize]
struct SaveData {
    property: u32
}

then, later on, I add a new field:
#[derive(Serialize, Deserialize]
struct SaveData {
    property: u32,
    new_property: u64
}

if i deserialize like this:
let save_data = value
    .deserialize_as_with_default(SaveData {
    property: 0,
    new_property: 0
}).unwrap();

it wouldnt give missing field new_property error, but would instead pick the missing property from the default
it is useful for backwards compatibility, currently im achieving something similar by iterating through mappings

I don't think this is possible without a completely custom proc macro. The closest support that I'm aware of from serde is DeserializeSeed, but this is something each type must be able to implement itself rather than something a serialization library adds support for.
With serde, each serialization library is being driven by the serde Serialize/Deserialize derives. The serialization library isn't able to query anything about the types, so there is no way for a library like Pot to use serde to do partial updates or "patch-like" deserialization.
With all this said, serde has a lot of flexible options for dealing with situations like this: for example, annotating a field with #[serde(default)] allows you to avoid missing field errors. There are other attributes listed on that page that can help too. Another option is to deserialize into a more flexible structure that contains Options and other ways to represent the data as loosely as possible, and then convert and validate the data into the desired runtime data structures from that loosely deserialized representation.
Regardless, I don't think there's much that Pot or any specific serde library serialization library can really add here. These features really need to be added directly to serde, and then all libraries can take advantage of them for free.


UNVT Workshop venue

Our colleague from UNGIS Timur has kinly asked me:

Hi Hidenori,

Could you please confirm that you have a room assigned for UNVT workshop on Tuesday 27 June.
If not, We are trying to organize with FOSS4G organizers. In this case please provide the following information:

title of the workshop
short abstract
description
level of the workshop
Requirements for attendants (if there is any)
names and emails for the presenters
I will do the same for UN Open GIS meeting.

Best regards,
Timur

@mapconcierge @ShogoHirasawa could you advise me how we should reply? I understand that the UNVT workshop venue was already secured, but it would be better if we could ask Timur to organize so that we get more convenient place for UN Open GIS participant.

Draft
Hi Timur,
Yes, we have a room assigned as below. It would be extra-great if the UN Open GIS Meeting and UNVT Portable Workshop share the same room.
Information about the UNVT Portable Workshop is also available at http://...

title of the workshop
Development of UNVT Portable, a map server with OpenStreetMap pre-installed using a Raspberry Pi on a local network in offline situations during disasters.

short abstract
UNVT Portable is...

description
...

level of the workshop
...

Requirements for attendants (if there is any)
...

names and emails for the presenters
...

Sent to Timur due to time limitation. Thanks!


Unable to save to gdrive

Error: Service Unavailable
{
  "status": 503,
  "method": "POST",
  "url": "/api/newGoogle/"
}

If you haven't already, try signing out and then back in. The logout button is on www.naturalcrit.com/login

@Galgamins , just following up to see if the above helped and issue resolved?

Sorry, been busy. Just tried it now and I can't seem to log in again with my google account. I get this error
`Error 400: redirect_uri_mismatch
You can't sign in to this app because it doesn't comply with Google's OAuth 2.0 policy. \n\nIf you're the app developer, register the redirect URI in the Google Cloud Console.
redirect_uri=http://www.naturalcrit.com/auth/google/redirect`

Okay, was able to log in again, but the save to gdrive button is missing

Okay even regular saving doesn't seem to work. When I create a new brew and try to save it, it doesn't show up on my profile under brews or unpublished brews.

Does it actually finish saving and redirect you to an edit page? Something with /edit/ in the url? Or does it remain on the homebrewery.naturalcrit.com/new page?

It remains on the /new page

Could you check the console for messages?
Right-click anywhere on the page, select "Inspect" which opens a black pane in the window, then click on "Console" at the top of that pane.

 This will help us track it down. In the mean time, so you can get to brewing, how do you feel about temporarily having me disconnect Google Drive from your account? You can sign in with just a normal username and password until we have this fixed. If that sounds helpful I just need your username for the Homebrewery. Any Google Drive brews won't be accessible during that time but they will still be on your google drive as text documents you can open up and copy/paste over to keep working on them.

Crash is occurring in /new on line 168 after attempting to save, because body is undefined if saving fails:
https://github.com/naturalcrit/homebrewery/blob/3cf5dc74bbb2d8ca010bb822bf67c762d52be6e3/client/homebrew/pages/newPage/newPage.jsx#L156-L168
We need to:

Gracefully handle that error. Exit the function if body is empty and post up a better message to the user without crashing (similar to what we already have in the edit page)

Investigate why the Google brew fails to save in the first place. Doesn't look like a "login" issue otherwise we would get an error 401 and we would see Not signed in!

Relevant errors from the server logs:
Error updating Google Brew because "insufficient permissions to get user's folder"

Click to expand!
2021-08-10T19:55:31.044236+00:00 heroku[router]: at=info method=PUT path="/api/update/k1dM1GRH79tB" host=homebrewery.naturalcrit.com request_id=f814d264-1680-4739-8563-e8b46c9be0ab fwd="<IP_ADDRESS>" dyno=web.1 connect=0ms service=13ms status=200 bytes=21827 protocol=https
2021-08-10T19:55:31.121806+00:00 app[web.1]: Error searching Google Drive Folders
2021-08-10T19:55:31.124253+00:00 app[web.1]: GaxiosError: Insufficient Permission: Request had insufficient authentication scopes.
2021-08-10T19:55:31.124256+00:00 app[web.1]:     at Gaxios._request (/app/node_modules/gaxios/build/src/gaxios.js:129:23)
2021-08-10T19:55:31.124257+00:00 app[web.1]:     at runMicrotasks (<anonymous>)
2021-08-10T19:55:31.124257+00:00 app[web.1]:     at processTicksAndRejections (internal/process/task_queues.js:93:5)
2021-08-10T19:55:31.124259+00:00 app[web.1]:     at async OAuth2Client.requestAsync (/app/node_modules/google-auth-library/build/src/auth/oauth2client.js:345:18)
2021-08-10T19:55:31.124259+00:00 app[web.1]:     at async Object.getGoogleFolder (/app/server/googleActions.js:57:15)
2021-08-10T19:55:31.124259+00:00 app[web.1]:     at async Object.newGoogleBrew (/app/server/googleActions.js:186:20)
2021-08-10T19:55:31.124260+00:00 app[web.1]:     at async newGoogleBrew (/app/server/homebrew.api.js:144:18) {
2021-08-10T19:55:31.124261+00:00 app[web.1]:   response: {
2021-08-10T19:55:31.124261+00:00 app[web.1]:     config: {
2021-08-10T19:55:31.124261+00:00 app[web.1]:       url: 'https://www.googleapis.com/drive/v3/files?q=mimeType%20%3D%20%27application%2Fvnd.google-apps.folder%27',
2021-08-10T19:55:31.124262+00:00 app[web.1]:       method: 'GET',
2021-08-10T19:55:31.124262+00:00 app[web.1]:       userAgentDirectives: [Array],
2021-08-10T19:55:31.124263+00:00 app[web.1]:       paramsSerializer: [Function (anonymous)],
2021-08-10T19:55:31.124263+00:00 app[web.1]:       headers: [Object],
2021-08-10T19:55:31.124263+00:00 app[web.1]:       params: [Object],
2021-08-10T19:55:31.124264+00:00 app[web.1]:       validateStatus: [Function (anonymous)],
2021-08-10T19:55:31.124264+00:00 app[web.1]:       retry: true,
2021-08-10T19:55:31.124264+00:00 app[web.1]:       responseType: 'json',
2021-08-10T19:55:31.124264+00:00 app[web.1]:       retryConfig: [Object]
2021-08-10T19:55:31.124265+00:00 app[web.1]:     },
2021-08-10T19:55:31.124265+00:00 app[web.1]:     data: { error: [Object] },
2021-08-10T19:55:31.124265+00:00 app[web.1]:     headers: {
2021-08-10T19:55:31.124266+00:00 app[web.1]:       'alt-svc': 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"',
2021-08-10T19:55:31.124267+00:00 app[web.1]:       'cache-control': 'private, max-age=0',
2021-08-10T19:55:31.124267+00:00 app[web.1]:       connection: 'close',
2021-08-10T19:55:31.124267+00:00 app[web.1]:       'content-encoding': 'gzip',
2021-08-10T19:55:31.124268+00:00 app[web.1]:       'content-security-policy': "frame-ancestors 'self'",
2021-08-10T19:55:31.124268+00:00 app[web.1]:       'content-type': 'application/json; charset=UTF-8',
2021-08-10T19:55:31.124269+00:00 app[web.1]:       date: 'Tue, 10 Aug 2021 19:55:31 GMT',
2021-08-10T19:55:31.124269+00:00 app[web.1]:       expires: 'Tue, 10 Aug 2021 19:55:31 GMT',
2021-08-10T19:55:31.124269+00:00 app[web.1]:       server: 'GSE',
2021-08-10T19:55:31.124269+00:00 app[web.1]:       'transfer-encoding': 'chunked',
2021-08-10T19:55:31.124270+00:00 app[web.1]:       vary: 'Origin, X-Origin',
2021-08-10T19:55:31.124270+00:00 app[web.1]:       'www-authenticate': 'Bearer realm="https://accounts.google.com/", error=insufficient_scope, scope="https://www.googleapis.com/auth/drive"',
2021-08-10T19:55:31.124271+00:00 app[web.1]:       'x-content-type-options': 'nosniff',
2021-08-10T19:55:31.124271+00:00 app[web.1]:       'x-frame-options': 'SAMEORIGIN',
2021-08-10T19:55:31.124271+00:00 app[web.1]:       'x-xss-protection': '1; mode=block'
2021-08-10T19:55:31.124272+00:00 app[web.1]:     },
2021-08-10T19:55:31.124272+00:00 app[web.1]:     status: 403,
2021-08-10T19:55:31.124272+00:00 app[web.1]:     statusText: 'Forbidden',
2021-08-10T19:55:31.124273+00:00 app[web.1]:     request: {
2021-08-10T19:55:31.124273+00:00 app[web.1]:       responseURL: 'https://www.googleapis.com/drive/v3/files?q=mimeType%20%3D%20%27application%2Fvnd.google-apps.folder%27'
2021-08-10T19:55:31.124273+00:00 app[web.1]:     }
2021-08-10T19:55:31.124273+00:00 app[web.1]:   },
2021-08-10T19:55:31.124274+00:00 app[web.1]:   config: {
2021-08-10T19:55:31.124274+00:00 app[web.1]:     url: 'https://www.googleapis.com/drive/v3/files?q=mimeType%20%3D%20%27application%2Fvnd.google-apps.folder%27',
2021-08-10T19:55:31.124274+00:00 app[web.1]:     method: 'GET',
2021-08-10T19:55:31.124275+00:00 app[web.1]:     userAgentDirectives: [ [Object] ],
2021-08-10T19:55:31.124275+00:00 app[web.1]:     paramsSerializer: [Function (anonymous)],
2021-08-10T19:55:31.124275+00:00 app[web.1]:     headers: {
2021-08-10T19:55:31.124275+00:00 app[web.1]:       'x-goog-api-client': 'gdcl/5.0.2 gl-node/14.15.5 auth/7.1.1',
2021-08-10T19:55:31.124276+00:00 app[web.1]:       'Accept-Encoding': 'gzip',
2021-08-10T19:55:31.124276+00:00 app[web.1]:       'User-Agent': 'google-api-nodejs-client/5.0.2 (gzip)',
2021-08-10T19:55:31.124277+00:00 app[web.1]:       Authorization: 'Bearer ya29.a0ARrdaM9An_scmis0jDaax9txAWsJwB8JHZlRLSvbaRNmL1HrCTOp-6hD8oSresE7UH12P0lQ5zTK-B7j9j9ZNn62Eqja05uHvzB1gm_bqLJt4bdaY7wJtWO7K-RRGG-4saHRL8_JXoqq1K3w0B2s-4gKw0S9DQ',
2021-08-10T19:55:31.124277+00:00 app[web.1]:       Accept: 'application/json'
2021-08-10T19:55:31.124277+00:00 app[web.1]:     },
2021-08-10T19:55:31.124277+00:00 app[web.1]:     params: { q: "mimeType = 'application/vnd.google-apps.folder'" },
2021-08-10T19:55:31.124278+00:00 app[web.1]:     validateStatus: [Function (anonymous)],
2021-08-10T19:55:31.124278+00:00 app[web.1]:     retry: true,
2021-08-10T19:55:31.124278+00:00 app[web.1]:     responseType: 'json',
2021-08-10T19:55:31.124278+00:00 app[web.1]:     retryConfig: {
2021-08-10T19:55:31.124279+00:00 app[web.1]:       currentRetryAttempt: 0,
2021-08-10T19:55:31.124279+00:00 app[web.1]:       retry: 3,
2021-08-10T19:55:31.124279+00:00 app[web.1]:       httpMethodsToRetry: [Array],
2021-08-10T19:55:31.124279+00:00 app[web.1]:       noResponseRetries: 2,
2021-08-10T19:55:31.124279+00:00 app[web.1]:       statusCodesToRetry: [Array]
2021-08-10T19:55:31.124280+00:00 app[web.1]:     }
2021-08-10T19:55:31.124280+00:00 app[web.1]:   },
2021-08-10T19:55:31.124280+00:00 app[web.1]:   code: 403,
2021-08-10T19:55:31.124280+00:00 app[web.1]:   errors: [
2021-08-10T19:55:31.124281+00:00 app[web.1]:     {
2021-08-10T19:55:31.124281+00:00 app[web.1]:       domain: 'global',
2021-08-10T19:55:31.124281+00:00 app[web.1]:       reason: 'insufficientPermissions',
2021-08-10T19:55:31.124282+00:00 app[web.1]:       message: 'Insufficient Permission: Request had insufficient authentication scopes.'
2021-08-10T19:55:31.124282+00:00 app[web.1]:     }
2021-08-10T19:55:31.124282+00:00 app[web.1]:   ]
2021-08-10T19:55:31.124282+00:00 app[web.1]: }
2021-08-10T19:55:31.125121+00:00 app[web.1]: (node:23) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'data' of undefined
2021-08-10T19:55:31.125122+00:00 app[web.1]:     at Object.getGoogleFolder (/app/server/googleActions.js:67:10)
2021-08-10T19:55:31.125122+00:00 app[web.1]:     at runMicrotasks (<anonymous>)
2021-08-10T19:55:31.125122+00:00 app[web.1]:     at processTicksAndRejections (internal/process/task_queues.js:93:5)
2021-08-10T19:55:31.125123+00:00 app[web.1]:     at async Object.newGoogleBrew (/app/server/googleActions.js:186:20)
2021-08-10T19:55:31.125123+00:00 app[web.1]:     at async newGoogleBrew (/app/server/homebrew.api.js:144:18)
2021-08-10T19:55:31.125161+00:00 app[web.1]: (node:23) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 63)

Irrelevant errors from Google, but just in case...
Error from Google because couldn't find brew

Click to expand!
2021-08-10T20:18:57.551187+00:00 heroku[router]: at=info method=GET path="/share/btY0jrR%5C_Mqpb" host=homebrewery.naturalcrit.com request_id=51aecc2a-e94d-493f-94fe-8d0734db4efa fwd="<IP_ADDRESS>" dyno=web.1 connect=0ms service=78ms status=500 bytes=3542 protocol=https
2021-08-10T20:18:57.545531+00:00 app[web.1]: Error loading from Google
2021-08-10T20:18:57.550555+00:00 app[web.1]: GaxiosError: File not found: b.
2021-08-10T20:18:57.550556+00:00 app[web.1]:     at Gaxios._request (/app/node_modules/gaxios/build/src/gaxios.js:129:23)
2021-08-10T20:18:57.550557+00:00 app[web.1]:     at runMicrotasks (<anonymous>)
2021-08-10T20:18:57.550557+00:00 app[web.1]:     at processTicksAndRejections (internal/process/task_queues.js:93:5)
2021-08-10T20:18:57.550559+00:00 app[web.1]:     at async Object.readFileMetadata (/app/server/googleActions.js:248:15)
2021-08-10T20:18:57.550559+00:00 app[web.1]:     at async /app/server.js:23:10
2021-08-10T20:18:57.550560+00:00 app[web.1]:     at async /app/server.js:199:15 {
2021-08-10T20:18:57.550560+00:00 app[web.1]:   response: {
2021-08-10T20:18:57.550561+00:00 app[web.1]:     config: {
2021-08-10T20:18:57.550561+00:00 app[web.1]:       url: 'https://www.googleapis.com/drive/v3/files/b?fields=properties%2C%20createdTime%2C%20modifiedTime%2C%20description%2C%20trashed&key=AIzaSyBShL6LLvJPm-tiZm_ffds_SzoaCgdoA4g',
2021-08-10T20:18:57.550561+00:00 app[web.1]:       method: 'GET',
2021-08-10T20:18:57.550562+00:00 app[web.1]:       userAgentDirectives: [Array],
2021-08-10T20:18:57.550568+00:00 app[web.1]:       paramsSerializer: [Function (anonymous)],
2021-08-10T20:18:57.550568+00:00 app[web.1]:       headers: [Object],
2021-08-10T20:18:57.550568+00:00 app[web.1]:       params: [Object],
2021-08-10T20:18:57.550568+00:00 app[web.1]:       validateStatus: [Function (anonymous)],
2021-08-10T20:18:57.550569+00:00 app[web.1]:       retry: true,
2021-08-10T20:18:57.550569+00:00 app[web.1]:       responseType: 'json',
2021-08-10T20:18:57.550569+00:00 app[web.1]:       retryConfig: [Object]
2021-08-10T20:18:57.550569+00:00 app[web.1]:     },
2021-08-10T20:18:57.550570+00:00 app[web.1]:     data: { error: [Object] },
2021-08-10T20:18:57.550570+00:00 app[web.1]:     headers: {
2021-08-10T20:18:57.550571+00:00 app[web.1]:       'alt-svc': 'h3=":443"; ma=2592000,h3-29=":443"; ma=2592000,h3-T051=":443"; ma=2592000,h3-Q050=":443"; ma=2592000,h3-Q046=":443"; ma=2592000,h3-Q043=":443"; ma=2592000,quic=":443"; ma=2592000; v="46,43"',
2021-08-10T20:18:57.550571+00:00 app[web.1]:       'cache-control': 'private, max-age=0',
2021-08-10T20:18:57.550571+00:00 app[web.1]:       connection: 'close',
2021-08-10T20:18:57.550572+00:00 app[web.1]:       'content-encoding': 'gzip',
2021-08-10T20:18:57.550572+00:00 app[web.1]:       'content-security-policy': "frame-ancestors 'self'",
2021-08-10T20:18:57.550572+00:00 app[web.1]:       'content-type': 'application/json; charset=UTF-8',
2021-08-10T20:18:57.550573+00:00 app[web.1]:       date: 'Tue, 10 Aug 2021 20:18:57 GMT',
2021-08-10T20:18:57.550573+00:00 app[web.1]:       expires: 'Tue, 10 Aug 2021 20:18:57 GMT',
2021-08-10T20:18:57.550573+00:00 app[web.1]:       server: 'GSE',
2021-08-10T20:18:57.550573+00:00 app[web.1]:       'transfer-encoding': 'chunked',
2021-08-10T20:18:57.550574+00:00 app[web.1]:       vary: 'Origin, X-Origin',
2021-08-10T20:18:57.550574+00:00 app[web.1]:       'x-content-type-options': 'nosniff',
2021-08-10T20:18:57.550574+00:00 app[web.1]:       'x-frame-options': 'SAMEORIGIN',
2021-08-10T20:18:57.550574+00:00 app[web.1]:       'x-xss-protection': '1; mode=block'
2021-08-10T20:18:57.550574+00:00 app[web.1]:     },
2021-08-10T20:18:57.550575+00:00 app[web.1]:     status: 404,
2021-08-10T20:18:57.550575+00:00 app[web.1]:     statusText: 'Not Found',
2021-08-10T20:18:57.550575+00:00 app[web.1]:     request: {
2021-08-10T20:18:57.550575+00:00 app[web.1]:       responseURL: 'https://www.googleapis.com/drive/v3/files/b?fields=properties%2C%20createdTime%2C%20modifiedTime%2C%20description%2C%20trashed&key=AIzaSyBShL6LLvJPm-tiZm_ffds_SzoaCgdoA4g'
2021-08-10T20:18:57.550576+00:00 app[web.1]:     }
2021-08-10T20:18:57.550576+00:00 app[web.1]:   },
2021-08-10T20:18:57.550576+00:00 app[web.1]:   config: {
2021-08-10T20:18:57.550576+00:00 app[web.1]:     url: 'https://www.googleapis.com/drive/v3/files/b?fields=properties%2C%20createdTime%2C%20modifiedTime%2C%20description%2C%20trashed&key=AIzaSyBShL6LLvJPm-tiZm_ffds_SzoaCgdoA4g',
2021-08-10T20:18:57.550576+00:00 app[web.1]:     method: 'GET',
2021-08-10T20:18:57.550576+00:00 app[web.1]:     userAgentDirectives: [ [Object] ],
2021-08-10T20:18:57.550577+00:00 app[web.1]:     paramsSerializer: [Function (anonymous)],
2021-08-10T20:18:57.550577+00:00 app[web.1]:     headers: {
2021-08-10T20:18:57.550577+00:00 app[web.1]:       'x-goog-api-client': 'gdcl/5.0.2 gl-node/14.15.5 auth/7.1.1',
2021-08-10T20:18:57.550577+00:00 app[web.1]:       'Accept-Encoding': 'gzip',
2021-08-10T20:18:57.550577+00:00 app[web.1]:       'User-Agent': 'google-api-nodejs-client/5.0.2 (gzip)',
2021-08-10T20:18:57.550578+00:00 app[web.1]:       Accept: 'application/json'
2021-08-10T20:18:57.550578+00:00 app[web.1]:     },
2021-08-10T20:18:57.550578+00:00 app[web.1]:     params: {
2021-08-10T20:18:57.550578+00:00 app[web.1]:       fields: 'properties, createdTime, modifiedTime, description, trashed',
2021-08-10T20:18:57.550578+00:00 app[web.1]:       key: 'AIzaSyBShL6LLvJPm-tiZm_ffds_SzoaCgdoA4g'
2021-08-10T20:18:57.550579+00:00 app[web.1]:     },
2021-08-10T20:18:57.550579+00:00 app[web.1]:     validateStatus: [Function (anonymous)],
2021-08-10T20:18:57.550579+00:00 app[web.1]:     retry: true,
2021-08-10T20:18:57.550579+00:00 app[web.1]:     responseType: 'json',
2021-08-10T20:18:57.550579+00:00 app[web.1]:     retryConfig: {
2021-08-10T20:18:57.550579+00:00 app[web.1]:       currentRetryAttempt: 0,
2021-08-10T20:18:57.550580+00:00 app[web.1]:       retry: 3,
2021-08-10T20:18:57.550580+00:00 app[web.1]:       httpMethodsToRetry: [Array],
2021-08-10T20:18:57.550580+00:00 app[web.1]:       noResponseRetries: 2,
2021-08-10T20:18:57.550580+00:00 app[web.1]:       statusCodesToRetry: [Array]
2021-08-10T20:18:57.550580+00:00 app[web.1]:     }
2021-08-10T20:18:57.550580+00:00 app[web.1]:   },
2021-08-10T20:18:57.550580+00:00 app[web.1]:   code: 404,
2021-08-10T20:18:57.550581+00:00 app[web.1]:   errors: [
2021-08-10T20:18:57.550581+00:00 app[web.1]:     {
2021-08-10T20:18:57.550581+00:00 app[web.1]:       domain: 'global',
2021-08-10T20:18:57.550581+00:00 app[web.1]:       reason: 'notFound',
2021-08-10T20:18:57.550581+00:00 app[web.1]:       message: 'File not found: b.',
2021-08-10T20:18:57.550581+00:00 app[web.1]:       locationType: 'parameter',
2021-08-10T20:18:57.550581+00:00 app[web.1]:       location: 'fileId'
2021-08-10T20:18:57.550582+00:00 app[web.1]:     }
2021-08-10T20:18:57.550582+00:00 app[web.1]:   ]
2021-08-10T20:18:57.550582+00:00 app[web.1]: }

Okay, was able to log in again, but the save to gdrive button is missing

Did you sign back in using the "sign in with google" button this time around? If the GDrive button is missing that sounds like you may have signed in with just username and password?

It's working now. :)

@Galgamins Are you able to save to Google now?

Hmmm... Now that I look through the logs and user error reports again, I think it is still just a matter of users needing to log out and back in, but they aren't able to do it properly because

If users try to log in to an HTTP version of the site (i.e., by following a link www.naturalcrit.com instead of typing it into their address bar), Google will not like that they are trying to "unsecurely" sign in and it will fail naturalcrit/homebrewery#1515
on /new, the user doesn't get any direction to log back in like we do on /edit. Just an "oop, there is an issue saving". This is hopefully addressed with https://github.com/naturalcrit/homebrewery/commit/7221d693c6f2a8b9c114ad99c8e77ce22daf7055 which has been pushed live
users who previously linked with google can still log in with username and password. This login method won't renew google drive credentials, so they remain "signed in" with Google but are just back to where they started and will have the error again. If they have linked to a google account we probably need to direct to the same Google Account log in popup no matter which way the try to log in.

@Galgamins Are you able to save to Google now?

Yes I am, thanks for the quick solution!


Add confirm before clearing the text

confirm by the user before the clear text.
if the user selects "ok" then only text will be deleted.

@shubhamdarwante2301 In the aove ss, there's a modal at the center of the page but in the deploy preview, it's showing me an alert box.
Why so? Didn't you made a modal?

@Susmita-Dey  SS is from firefox that's why is showing like this.
it is actually an alert!
did you want a modal?

@shubhamdarwante2301 Oh I see. Okay leave that.


chore(deps): bump  versions

Update  versions
Command run was jx step create pr versions -f jenkins-x/* --images

/test boot-lh-bs

fyi, this is gonna fail a bunch - it needs https://github.com/jenkins-x/jx/pull/5352


Optimize images (9.1MB reduction)

Used these commands:
oxipng --zopfli --opt max --strip all
jpegoptim --all-progressive --strip-all

I'm not sure about the rest, but the RGUI wallpaper images in  rgui/wallpaper cannot be modified in any way. They are very specifically formatted for compatibility reasons.

Please no.
Tools like that are destructive especially on the maximal opt setting.
It was already done several times in the past on more conservative settings.

@jdgleaver

I'm not sure about the rest, but the RGUI wallpaper images in  rgui/wallpaper cannot be modified in any way. They are very specifically formatted for compatibility reasons.

I can remove these if needed.
What specifically is unique with the rgui/wallpaper images?
@Tatsuya79

Tools like that are destructive especially on the maximal opt setting.

How so? They shouldn't be destructive on max settings. The only thing which could be problematic is this iteration's stripping of all metadata. I'll gladly rerun without any stripping if you'd like.
The main difference in this iteration is the use of the zopfli compressor.

All the icons for Automatic, Systematic, Retroactive and Neoactive were run through ImageOptim before submission.  I'm not quite sure if this is necessary for those themes.


chore: Remove redundant JIL test file metrics.test.js - NEWRELIC-9049

Since metrics.e2e.js already covers the same tests, the JIL test file can be removed.
Overview
I verified that metrics.e2e.js covers the same scenarios as the removed JIL file.
Related Issue(s)
NEWRELIC-9049
Testing
npm run wdio -- --retry=false tests/specs/metrics.e2e.js

This file was left in place as a performance comparison of sorts between JIL and WDIO.

The WDIO version has a couple additional tests now. Has it outlived its usefulness as a performance comparison?
If we keep it around I’d like to add a comment in the file about the purpose.

The WDIO version has a couple additional tests now. Has it outlived its usefulness as a performance comparison?

Probably yea. Hell, this is git so we can always recover it.


Add tap-netlify

Migrated from GitLab: https://gitlab.com/meltano/hub/-/issues/137
Originally created by @franloza on 2021-10-17 12:39:27

Tap-toberfest with Meltano
Repo: https://github.com/franloza/tap-netlify

View 2 previous comments from the original issue on GitLab


NET-IP-Injection.ps1 - Ubuntu 18.04 fails

IP injection doesn't work for Ubuntu 18.04 because it uses netplan, any hint/workaround ?

Hi @dragan1979,
In our environment, it doesn't work for below reason. Please have a try, if you still hit issue, let know how you generate the parent disk.
Refer here - https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1766857
Root cause: The binary files about hv-kvp are placed under /usr/sbin/, but the KVP_SCRIPTS_PATH is configured as /usr/libexec/hypervkvpd.
Workaround:
mkdir -p /usr/libexec/hypervkvpd/
cp /usr/sbin/hv_* /usr/libexec/hypervkvpd
systemctl restart hv-kvp-daemon
In addition, the ifdown and ifup are used by the hv_kvp_daemon, so install them by running "apt install ifupdown".

4.15.0-76-generic
yes, i installed it (disabled netplan but issue persist)

Refer here - https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1766857
Root cause: The binary files about hv-kvp are placed under /usr/sbin/, but the KVP_SCRIPTS_PATH is configured as /usr/libexec/hypervkvpd.
Workaround:
# mkdir -p /usr/libexec/hypervkvpd/
# cp /usr/sbin/hv_* /usr/libexec/hypervkvpd
# systemctl restart hv-kvp-daemon

Could you please try this work around before https://github.com/LIS/LISAv2/blob/master/Testscripts/Windows/NET-IP-Injection.ps1#L207

That's it!!, it works, thanks.

You are welcome, your kernel is kind of old, the newer one contains the fix.


Keep punctation in title?

Mark this up without the period as
<title>Social Evolution</title>

or with the period as
<title>Social Evolution.</title>

If we don't want to keep the punctuation in the title (and I would think we don't) what do we do with it? We either have to (1) delete it or (2) allow CDATA in a lot of tags. I think option 2 does least harm.

In accordance with the principles in #9, we need to keep the punctuation and allow CDATA


Expose a push/3 that does not explicitly depend on a transport

Hi:
We created a push/3 function that doesn't require a transport so that we can push items to the channel from other modules. Can you take a look at this, and potentially merge it into your version?
Thanks so much,
Greg

Thank you for this PR!
Unfortunately, I don't think we can accept it in this shape. The main problem is that you now require that the socket client process is a named singleton, which means that we can have at most one socket connection in the entire system, which is definitely not a good general solution.
Another issue is that push/3 is async (cast). If we're adding this support, we'd also need to support the sync version based on a call, which would return :ok or :error, indicating whether the message has been pushed to the socket. In fact, if this was available, I'd most often use the sync version. Another question is: do we then need a "total sync" version, which returns only when the client has responded. As you can see this can get complicated pretty quickly.
On the other hand, implementing an async push from another process is already fairly trivial:
defmodule YourSocket do
  def push(socket, event, payload), do:
    send(socket, {:push, event, payload})

  # ...

  def handle_info({:push, event, payload}, transport, state) do
    GenSocketClient.push(transport, topic, event, payload)
    {:ok, state}
  end
end

And now you can invoke YourSocket.push(socket, event, payload) from an arbitrary process.
If you want to name your socket process, it's as easy as:
defmodule YourSocket do
  @behaviour GenSocketClient

  def start_link(...), do:
    GenSocketClient.start_link(..., name: __MODULE__)

  def push(event, payload), do:
    send(__MODULE__, {:push, event, payload})

  # ...
end

And now you can invoke YourSocket.push(event, payload) from an arbitrary process.
So in my opinion, the proposed push/3 doesn't really solve a complex problem.
One final issue I have with supporting push is that in your proposal, push/3 is an "outside" push (from an external process), while push/4 is an inside push (from within the behaviour process). This seems confusing, so we'd need a better naming distinction.
For all these reasons, I think that push/3 in the proposed form adds more problems than it solves.
All that being said, one thing which is indeed missing is the support for synchronous calls (GenSocketClient.call), which would allow you to implement sync pushes. Currently, it's not obvious how to do that, so I'll see about supporting that scenario.

Just an addendum, that we've pushed 1.1.0 to hex. The new version supports call,  so you can now easily implement an ack-ed push as:
defmodule YourSocket do
  @behaviour GenSocketClient

  def start_link(...), do:
    GenSocketClient.start_link(..., name: __MODULE__)

  def push(topic, event, payload), do:
    GenSocketClient.call(__MODULE__, {:push, topic, event, payload})

  def handle_call({:push, topic, event, payload}, _from, state) do
    res = GenSocketClient.push(transport, topic, event, payload)
    {:reply, res, state}
  end
end

great!  thank you very much for the info about handle_call(); we'll definitely switch out our code to use the approach you've suggested. Thank you for taking the time to consider our request, and for suggesting a better alternative.  :)

No problem. Let us know if this doesn't work for you.

@sasa1977 in the addendum, inside handle_call, there is reference to a transport, do you have any idea where it might come from/ get stored? thank you!

@sasa1977 Thanks again! It worked. We had to change the parameters a bit. The example code in your addendum mentioned a transport. Looking at the docs, the 3rd argument to handle_call/4 provides it.
So, handle_call should be this
def handle_call({:push, topic, event, payload}, _from, transport, state) do
  res = GenSocketClient.push(transport, topic, event, payload)
  {:reply, res, state}
end

Ah, sorry about that, I was live-coding in GH, without trying it out :-)


init - bash it's automatically load auto-completion

Sorry, but what is the purpose of this PR?

I'm just trying to make a script it simpler.

Hi @nwinkler sorry for my answer, but I understand what you mean.
I have already told via commit message that jenv, nodenv, plenv, pyenv, rbenv with the init - bash command that automatically loads auto-completion, you does not need to check whether completions exists or not and then uses  source.

OK, got it - sorry for the confusion. I must confess that I did not understand what you were trying to do from your initial commit message - might have been the language barrier.
Thanks for the additional explanation, that helped a lot.

Yes, maybe because of language barriers.
No problem. :+1:


Fix some bugs when seeking

Thank you for your great library.
When I was using this library, I have found some bugs when seeking audio.
Problems

When seeking started, 'OnStartTrackingTouch' in 'JcPlayerView' immediately call function 'showProgressBar(). So 'OnStopTrackingTouch' can't call function 'dismissProgressBar()' because 'seekBar' is already disabled.

'OnProgressChanged' in 'JcPlayerView' call function 'seekTo' every progress changing even just dragging seek bar.

So I fixed these bugs.
Solutions

I moved functions 'showProgressBar()' and 'seekTo()' to 'OnStopTrackingTouch()'.
And I added new Listener 'OnSeekComplete'. It calls 'dismissProgressBar()' when seeking completed.

Here is before & after
Before

After

@jaeyoonlim Great job! I'll review that.

@jaeyoonlim Please, update your branch with the latest version code master_v2.

@jeancsanchez OK, I'll update my branch.

@jeancsanchez I updated my branch. Please, review this.

@jaeyoonlim  I am tested it, but it not solves the problem yet :/

@jeancsanchez I tested it again but, it wroks pretty well..
I may think you did not edit the file 'sample/build.gradle
Please check the file. (implementation -> api project)

@jaeyoonlim When the player is paused and the progress bar is changed, the player's behavior is weird.

@jeancsanchez Are you saying this?

@jeancsanchez Oh, I understand, When user seek music slowly, Seek bar is still moving.
Is it right?

@jeancsanchez I followed your description and I have a question.
When the player is paused and the progress bar is changed, the player is still paused.
Is it right?

@jaeyoonlim Yes.

@jeancsanchez Please check my branch. I fixed it.

@jeancsanchez I fixed it. Please check my branch.

@jaeyoonlim I've Tested your branch fix_seeking_bug and saw that when I pause an audio and try to seek the seekbar the player is able to continue playing after sometime from the seek position but now I'm unable to use any of the buttons...

This is what i see after moving the seekbar...

This is my sample.gradle file.
I Tried Running the app on Nougat 7.0 and that was what i saw while playing the song.
I tried connecting with my Jelly Beans Phone and compile but I got compilation error - something to do with dex files...

@peace-shillong
Before you run sample app, You have to edit the file like below

Your setting is loading JcPlayer from remote not local.
Please re-check it.

@jaeyoonlim Thank you.. it works!


CDF Budget 2021

[x] Schedule budget committee meeting
[x] Send out materials
[x] 4th December meeting
[x] Board approvals

Budget committee met on 4 Dec and we are ready to prepare materials for board approval in January

Approved for 2021


Kfb/ranking ties

First pass at properly handling ties in the ranking. I don't think this is really ready to be merged just yet, but wanted to make it visible and get some feedback to keep moving forward on issue #16.
Some questions and thoughts.

I agree that consolidating the Curve constructors and build method would be helpful, though for now there are both primitive array and collection versions. Should we just take the plunge and have only primitive arrays for the Curve constructors and allow the Builder to convert from collections as necessary?
I'm currently ignoring any floating point comparison subtleties when detecting ties. Do we want to support an absolute or relative epsilon to detect effective ties even if the double representation is slightly different? My thought is no, and if ties are important, then double should not be the predicteds type and int or some other discrete type should be used.
The code to create the runLenghts array in Curve.Builder.build seems clunky right now. Maybe it is cleaner to not use the for each iterator and have a for loop over indices so the next tuple can be easily checked.
We should probably add some more tests. I have super simple tests of the basic functionality right now and am not sure what corner cases we need to consider.

Thoughts on all of this, @afbarnard?

Effectively closed in commit 1c5c3d4, issue #16.


The Modal POPUP dont disappear on click outside in desktop PC browsers

Hi Partner
The Modal POPUP dont disappear on click outside in desktop PC browsers
allowUserToCloseModal: true,
Best Regards

thanks for report, fixed
https://github.com/philfung/add-to-homescreen/commit/863382ec72f8c375c22d5659e4e3e3ab779f6d87


rtl_light.css: ZOMFG and ROFL

.linkbutton:link, .linkbutton_right:link, .linkbutton_left:link,
.linkbutton:visited, .linkbutton_right:visited, .linkbutton_left:visited {
    border-left: 1px solid #afafaf;
    border-right: 1px solid #bfbfbf;
    box-shadow: -1px 1px 2px #e5e5e5;
}

/* Hover effects. */
.button_submit:hover, .right_submit:hover, .left_submit:hover,
.button_reset:hover,
.linkbutton:hover, .linkbutton_right:hover, .linkbutton_left:hover {
    border-left: 1px solid #ccc;
    border-right: 1px solid #afafaf;
    box-shadow: -2px 1px 1px rgba(0,0,0,0.07) inset;
}

Umm, what? Why is all this stuff in there? These are just button eye candy, As long as a button looks good, that's all that matters. There's absolutely no need to try and flip every damned style right to left just because the language changes. This applies to most elements.
This file should be almost empty. Rtl.css is just for positioning, and the vast majority of it should be done in the main rtl.css file.

Its April ... 10 years later :D


Integrate luajit2 to replace moonjit

For an explanation of how to fill out the fields, please see the relevant section
in PULL_REQUESTS.md
Commit Message: Integrate luajit2 to replace moonjit which gives envoy lua filter.
Additional Description: Integrate luajit2 to resolve envoy's Lua filter not working on OpenShift Service Mesh 2.x ppc64le. In order to support http.lua on ppc64le.
Risk Level: Medium
Testing: Tested on Power VM TestExecution.txt
Docs Changes: docs/root/configuration/http/http_filters/lua_filter.rst
Release Notes: N/A
Platform Specific Features: Linux ppc64le only
[Optional Runtime guard:]
[Optional Fixes #Issue] https://issues.redhat.com/browse/OSSM-553
[Optional Deprecated:]

Thanks for the PR!
Instead of replacing moonjit, could you add luajit2 as a new dependency? Could you make it configurable, disabled by default, same way moonjit is now (see https://github.com/maistra/envoy/blob/maistra-2.1/source/extensions/filters/common/lua/BUILD#L18 for an example).
I think upstream would be interested in this change as well, would be great if you submitted the PR there too.

Merge conflict. Abandon this PR and create new one to avoid confusions.


Code output not rendered as Jupyter cell

Recently, I see more often output like this:

... where code is not given as code but as text output...

I haven't seen this in a while. I guess it's solved


sensu-0.17.0.beta.1-1 "client must be a hash"

Hello,
Testing the latest build on a Win 2012 R2 server. I get the following error:
{"timestamp":"2015-03-16T13:14:22.871809-0400","level":"fatal","message":"invalid settings"}
{"timestamp":"2015-03-16T13:14:22.949945-0400","level":"fatal","message":"client must be a hash","object":null}
{"timestamp":"2015-03-16T13:14:22.949945-0400","level":"fatal","message":"SENSU NOT RUNNING!"}
sensu-0.14.0-1 is working fine with the same client.json:
{
"client": {
"name": "server_fqdn",
"address": "<IP_ADDRESS>",
"subscriptions": [ "Windows-servers" ]
}
}
Please note I removed the real FQDN.
Also note I did a version upgrade (not fresh install).
For reference, I also posted in sensu-build, so feel free to close one of the 2 issues.
Thank you by advance.

You may need to update your service config (XML), the log event shows the value as null, so it's not being read.

Indeed, I didn't noticed that sensu-client.xml was replaced during the update. Thx for the help.

I have this issue, but just to confirm, what needs to be changed in the XML file?

@julientheriaultlapresse the Sensu CLI arguments in the XML service config file must reflect the location of your Sensu configs etc.

I have a Linux machine running the Sensu server.  Windows is a client only.  The "config.json" file contains the configuration pointing to the server.  This is my current XML file (on Windows), I haven't changed anything since the client installation :

sensu-client
Sensu Client
This service runs a Sensu client
C:\opt\sensu\embedded\bin\ruby
C:\opt\sensu\embedded\bin\sensu-client -l C:\opt\sensu\sensu-client.log

@julientheriaultlapresse it looks like you're missing the config file argument in the XML config, -c C:\opt\sensu\config.json

You can run C:\opt\sensu\embedded\bin\ruby C:\opt\sensu\embedded\bin\sensu-client -h for all available CLI arguments. You may also need -d C:\opt\sensu\conf.d for additional configuration files (directory).


Feature: Jump to object/section

Basically having the possibility to click on an element and jump to another section (or element) of the whiteboard, like with Markdown.
My use case comes from making a summary that is quite big already, with different concepts explained in different parts of the board. I added a topic list on the top and I thought it would be nice to make the topic titles clickable to navigate to a given section.
If you like the idea (and decide on the UI) I can take a shot at implementing it :)

This falls under: https://github.com/excalidraw/excalidraw/issues/1205, with the current consensus being on this solution: https://github.com/excalidraw/excalidraw/issues/1205#issuecomment-723497526
That issue is about text hyperlinks, but as someone mentioned it could work with elements too. Unclear if that would be a good idea, UI-wise. I'd maybe start with whole text elements only (which we'll style as a link — blue color with underline, so it's obvious).
Also, the hyperlinks issue was just about URLs, but linking to objects in the same scene is a good use case too. In fact, I'd start with this use case, and leave the URL linking for a future PR, as there are some security concerns we'd like to figure out first.

I agree that it will be best to start working on jumping to elements first and then, maybe, moving on external links. Will give it a shot this weekend :)
What do you think the UI should be like? I'm thinking about selecting an element, clicking a button to 'pair' or 'link' in the action bar, and then clicking the target element to select that one. Similar behavior to the devtools inspect element feature
What do you think?

What do you think the UI should be like? I'm thinking about selecting an element, clicking a button to 'pair' or 'link' in the action bar, and then clicking the target element to select that one. Similar behavior to the devtools inspect element feature

That would be an ideal workflow. But I'm not sure how hard it would be to implement.
Ok, so to sum up, this feature will consist of 3 mostly separate sub-features:

Support creating hyperlinks between elements:

Support workflow on clicking on hyperlinks
(via https://github.com/excalidraw/excalidraw/issues/1205#issuecomment-723497526)
On click/hover show a popup:

Direct click-to-activate could work in view mode though.

Add support for scrolling to element (this can later be adapted to support scrolling to elements via URL).

If the above sounds good, then we should get consensus from the team and you can start working on all or some of the parts.

By adding support for scrolling do you mean instead of snapping to the new position you smoothly transition to it?
One drawback I see with this linking behavior is that if you got a big board you will have to scroll/move across it to find the element to link to, you could be prone to miss clicking some other element. Maybe as a follow-up task, we could have a list of elements to link to.
Also, if you link A with B, clicking A will take you to B, but what about the other way around? In the content of the topic list example I mention before, this would be, click to go to definition and then click back to go to topics

By adding support for scrolling do you mean instead of snapping to the new position you smoothly transition to it?

No, just a quick jump to it is fine. We just need to ensure it's centered properly. Should be simple, I just listed it as a separate task.

One drawback I see with this linking behavior is that if you got a big board you will have to scroll/move across it to find the element to link to, you could be prone to miss clicking some other element. Maybe as a follow-up task, we could have a list of elements to link to.

Yes, that's why I'd add the confirmation step as you can see on the diagrams above. This way you can tinker with the selection until you hit the right element and only then confirm it.

Also, if you link A with B, clicking A will take you to B, but what about the other way around? In the content of the topic list example I mention before, this would be, click to go to definition and then click back to go to topics

Sure. The workflow will be generic so it should allow this easily. I'd only add a check to prevent linking to itself.

I have the same issue because my scenes are too big ... I would like to move more efficiently among different regions. One possible way of implementing this jump feature, using the already existing hyperlink tool, would be if I could get the excalidraw link pointing to the exact position or object id (example: https://app.excalidraw.com/s/94sMb/gwKiL/posic_x=123&posic_y=456). If I had this, it would be enough to paste this URL in the hyperlink placeholder to be clickable and jump to the specified position/object.

Alternatively, we can introduce a new element "Arrow Link" which can snap two elements together and have smooth transition from one to another
I am actually currently using this approach of connecting elements with lines but then following the trajectory of line manually to find it's end connection

After going through suggested approaches, I am coming up with solution of "Pinned Anchors"
The idea to add another action "Pin element" which would be very similar to "Create link" but instead of URL it prompts to enter custom label/alias text
All pinned anchors are visible as a floating list in Island container
Single click on the anchor triggers "select element" action
Double click on the anchor triggers "select and zoom to fit selected element" action

--
Does it make sense to be merged once implemented?

After going through suggested approaches, I am coming up with solution of "Pinned Anchors"
The idea to add another action "Pin element" which would be very similar to "Create link" but instead of URL it prompts to enter custom label/alias text
All pinned anchors are visible as a floating list in Island container
Single click on the anchor triggers "select element" action
Double click on the anchor triggers "select and zoom to fit selected element" action

-- Does it make sense to be merged once implemented?

That sounds like an awesome idea and would be immensely helpful for bigger whiteboards!

Ok will do that
Is it acceptable to include a new field "anchors" next to "elements" and "files", or better just a new field "anchorName" to the element?

I guess a very simple and intuitive way of linking internal objects would be the following way:

Select an object (drawing, text field etc.) you want to link
Press the "interlink" button (we might call it "interlink" to distinguish from the button that links to external sources) or the corresponding keyboard shortcut, like "shift+ctrl+l" (similar to the shortcut that creates external links, i.e. "ctrl+l"), which will show a pop-up that says something like "select another object to link your current selection".
Select the object you want to link with your previously selected object

As a result, both linked objects should now have a small icon on the same place where currently the icon for the external linking appears, but it should be a different icon, to distinguish between internal and external linking. If you click on this interlink icon of one of these linked objects, then you should jump to the other.
It would be tremendously useful to have such a feature, especially for larger whiteboards, because you often want to connect certain objects, but doing it with arrows over a long distance clutters the whole whiteboard after some time.
@7flash what do you think about this approach? Do you think that this is easily implementable?

I guess a very simple and intuitive way of linking internal objects would be the following way:

Select an object (drawing, text field etc.) you want to link
Press the "interlink" button (we might call it "interlink" to distinguish from the button that links to external sources) or the corresponding keyboard shortcut, like "shift+ctrl+k" (similar to the shortcut that creates external links, i.e. "ctrl+k") or just "ctrl+l", which will show a pop-up that says something like "select another object and press the interlink button to link your current selection".
Select the object and press the interlink button or use "shift+ctrl+k" or "ctrl+l" to finally link both objects.

As a result, both linked objects should now have a small icon on the same place where currently the icon for the external linking appears, but it should be a different icon, to distinguish between internal and external linking. If you click on this interlink icon of one of these linked objects, then you should jump to the other object.
It would be tremendously useful to have such a feature, especially for larger whiteboards, because you often want to connect certain objects, but doing it with arrows over a long distance clutters the whole whiteboard after some time.
@7flash what do you think about this approach? Do you think that this is easily implementable?

Totally agree. Visible arrows might clutter the workspace a lot, and showing "internal" links for connected elements is more elegant solution. Perhaps the line might become visble on hovering over the link. Also, your proposal of "Internal links" is fully compatible with mine of "Pinned Anchors". I think I could implement yours approach first to allow linking and jumping, and then additional feature would be to show a table of all linked elements as anchors.
| element1 | <> | element2 |
| element3 | <> | element 4 |

That would be awesome! Can't wait to test this out 🐳

The ability to navigate to one object by clicking on another would be great for my use case. I'm looking to create a high-level system architecture diagram based on the C4 model, where high-level system diagrams are broken down into lower-level container, component, and code diagrams. Having this linking functionality would make it possible to indicate, for example, where (X) system in the system diagram is broken out into containers elsewhere on the canvas.
Here's how this is done in Miro, for reference:

Context & Container Diagrams (Unlinked):

Select "Internet Banking System" object -> Press "Add link". Hover over the object that you'd like to link to and click - this auto-fills the input box on the top left with the objects URL. Pressing "Confirm" will add a blue arrow to the "Internet Banking System" object.

Context & Container Diagrams (linked):

Clicking on the blue arrow will cause the user's window to focus on the linked object:

Is anyone aware  of progress on this?
It it hasn't been  started or or isn't close to be finished i may give it the good ol college try

I am also interested in this feature. Actually I need the very same thing as @quinn-p-mchugh :-)

I would also love to see it working!

Yes bump! would also like a feature that has a clickable button that links to different section within an excalidraw canvas!

@MartinNuc @mindriven @dennisrcao since we have discussed several solutions in this topic, which one you think most convenient in your each case? do you think my proposal with "Pinned Anchors" would work for you?

Bump! would be an amazing feature.

Bump! would be an amazing feature.

Currently I have implementation of anchors based on meta-arrows which are not rendered on the canvas, but still present in the getSceneElements()
It works in addition to macros feature which assumes arrow labels are referencing name of the macros function which accepts input element (start binding) as an argument and updates text of output element (end binding) with result of macro execution.
In scenario above, after connecting two elements with an arrow, you would have to double click the arrow and write "jump" which would be arbitrary name of the function you define in the window and implement it as a function to scroll fit into bounding box of the output element.
Then whichever elements you select on the canvas, it's rendering a list of buttons in the side bar, a button for each label triggering execution of corresponding macro. Also you can have default list of macros showing up buttons when you don't have any elements selected. It's useful to make an index of chapters/sheets of your canvas quickly accessible from any point in this case, or attach any arbitrary functions in general case.
But then again, as mentioned above, I found way too messy to have lots of arrows on the canvas, and came up with solution of meta-arrows, which are still noticed by macros mechanism even though being ignored in rendering loop.
I am currently working on a new meta-editing mode, which actually allows you to draw those meta-arrows and then export it as a canvas with easy navigation & custom functions in view-mode.
And finally, I should mention, what makes me excited about further idea of connecting elements with dynamic meta-arrows, that's an ability to connect elements across multiple whiteboards, - that is referencing elements published in other whiteboards, - either available locally or downloadable remotely, - using those elements non-present in your canvas an an input start bindings binded to arrows in your current canvas.
#5684
https://github.com/zsviczian/obsidian-excalidraw-plugin/pull/1252
https://github.com/excalidraw/excalidraw/issues/253#issuecomment-1844186935


add tasmin and pr yamls

This PR adds more tasmin and pr yamls for DTR and precip runs.

Gonna go ahead and merge this since I need it to resolve another issue (updating the MRI tasmax param file)


Nuxt consumes the same amount of CPU even after prerendering (Nuxthub enabled)

Even after enabling routeRules prerender in some routes nuxt, some routes still consume the same amount of CPU.

Is there any way to enable caching to prevent more CPU usage?

Do you have the deployed website or some infos to share to help debug?

I don't have stats but pre-rendered still counts as a worker request and CPU usage. I have a traffic site where I am facing this issue.
I will try get data from small project

Please check full discussion on discord with mannil - https://discord.com/channels/473401852243869706/1244656036002926645

So, Nitro cannot follow the link as we did not configure the crawlLinks option but we should not in the hybrid mode
One solution is to use the prerenderRoutes()[https://nuxt.com/docs/api/utils/prerender-routes) util in your blog.vue page to list all the other blog post pages.

https://github.com/unjs/nitro/pull/2498


Example import syntax in readme doesn't work for ES6 module users

Hello, just now I started migrating from enzyme 2 to 3, and ran into a pickle here: I found that the typescript import syntax differs from the official enzyme docs, so I'm posting my troubles and solutions to help others in the same situation.
FAIL
import Enzyme from "enzyme"
import Adapter from "enzyme-adapter-react-16"

Enzyme.configure({adapter: new Adapter()})

//> Enzyme is undefined (no default export)
//> Adapter is undefined (no default export)

FAIL
import {configure} from "enzyme"
import {Adapter} from "enzyme-adapter-react-16"

configure({adapter: new Adapter()})

//> configure is undefined
//> Adapter is undefined

SUCCEED
import * as enzyme from "enzyme"
import * as Adapter from "enzyme-adapter-react-16"

enzyme.configure({adapter: new Adapter()})

//> hooray!

side question
Do I really have to do this configure call in every single *.test.ts file? Jest doesn't seem to give me an entrypoint, so I guess so...

the import * as requirement is a bug in TypeScript; that should not be required.
you have to configure it once per test run; since jest runs every file in its own process, you have to do it once per file. However, you don't have to do it in each file - jest has the setupTestFrameworkScriptFile option.

the import * as requirement is a bug in TypeScript; that should not be required.

hmm.. reading issues like this: https://github.com/Microsoft/TypeScript/issues/2719
I find babel quotes like this:

http://babeljs.io/docs/usage/modules/#interop
Interop
In order to encourage the use of CommonJS and ES6 modules, when exporting a default export with no other exports module.exports will be set in addition to exports["default"].
export default test;
exports["default"] = test;
module.exports = exports["default"];
If you don't want this behaviour then you can use the commonStrict module formatter.

I think perhaps when babel said "encourage", they must have meant "confuse"
if I'm reading this right, I'm getting the sense that the import * as requirement of TypeScript is actually the one that's aligned with kosher es6 import standards?
seems like either babel's interop, or typescript generally, has to be on the wrong side of the ES6 module fence here.. and it's not looking like typescript I don't think..
enzyme may be better off using that "commonStrict" module formatter situation that babel mentions?

I'm afraid you're not reading it right; there are no standards about interop, and there's no "wrong side of the module fence" here - there's just "what everyone in JS has been doing for years", and this new weird thing TypeScript is imposing on its users.

there are no standards about interop, and there's no "wrong side of the module fence" here - there's just "what everyone in JS has been doing for years"

@ljharb — this classic blog post is obviously talking about the ratified standard for es6 modules, the details of which are undoubtedly in the full ecma-262 6th edition language specification:

The default export is actually just a named export with the special name default.

I can see it in the enzyme module source code that there is no "export with the special name default":
module.exports = {
  render,
  shallow,
  mount,
  ShallowWrapper,
  ReactWrapper,
  configure,
  EnzymeAdapter,
};

so enzyme is not providing a standard ES6 default export there, right?
interestingly, some of the enzyme source files use default exports correctly, such as render.js:
export default function render(node, options = {}) {
  const adapter = getAdapter(options);
  const renderer = adapter.createRenderer({ mode: 'string', ...options });
  const html = renderer.render(node, options.context);
  return cheerio.load('')(html);
}

now that there, is a proper es6 default export — which can be imported with the proper syntax in typescript, which strives at great length to align with the evolving ecmascript standards
why isn't the enzyme module similar to the render module in that way?

this article did a great job clearing confusion for me: http://www.thedreaming.org/2017/04/28/es6-imports-babel/

there are common js modules, which export any js value
there are es6 modules, with named exports including a possible default
enzyme's module is common js, it does not have an es6 default export
enzyme's render.js is an es6 module, it has an es6 default export

please clarify in the readme usage example, for developers who are using standard es6 modules (totally the new hotness, by the way!):

Finally, you need to configure enzyme to use the adapter you want it to use. To do this, you can use the top level configure(...) API.
import Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new Adapter() });

Developers using es6 modules will need to use the import * as Enzyme from "enzyme" syntax instead:
import * as Enzyme from 'enzyme';
import * as Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({ adapter: new Adapter() });

@ChaseMoskal yes, this is correct for all npm packages - node doesn't support ES Modules natively yet, so everything is transpiled to commonJS. However, babel's interop means that when you use import with it, it will properly have the semantics of ESM.
"Enzyme is provided in Common JS format, so developers using es6 modules will need to use the import * as syntax instead:" is only true for TypeScript. Developers using ES6 Modules with every other tool don't need to do that extra step, because every other tool has chosen an interop method that avoids inflicting burden on users.

I found a relevant typescript compiler option:

--allowSyntheticDefaultImports — Allow default imports from modules with no default export. This does not affect code emit, just typechecking.

I suspect this may allow the readme usage example to work for TypeScript users, I think this is something like the equivalent of Babel's interop
I think it would be useful to add a quip in the readme's usage example:

TypeScript users might need to either use the import * as Enzyme from 'enzyme' syntax, or consider using the --allowSyntheticDefaultImports compiler option.

That one sentence seems much more palatable to me (with the order of the "either"s reversed). Want to make a PR?

Hi.
I just ran into this issue and ended up solving it using the import * as Adapter syntax (did not want to add a lax compiler flag just for one testing utility). However, I agree with you that this syntax does break the spec (as Adapter should effectively be a namespace, not a function).
The real compatible mode would be to simply not use a default export. This way it would work cleanly out of the box for everyone (and only users on very old-school codebases that can use neither ES6 modules nor object destructuring would have a slightly clumsier import).
import { Adapter } from 'enzyme-adapter-react-16'; // babel/TS

const { Adapter } = require('enzyme-adapter-react-16'); // Node 6+ no transpilation

var Adapter = require('enzyme-adapter-react-16').Adapter; // Node 5 or older no transpilation
// A bit clumsy but not broken like the TS "fix"

If I may say so, I think in 2018 supporting Typescript ought to be higher priority than offering a slightly lighter syntax to pre-2016 versions of Node.js. Maybe starting with the next version of React.

I believe TypeScript has fixed their module issues in v2.8; import * as should no longer be needed for this case.
Regardless, “not JavaScript” will never be a higher priority than “JavaScript” :-)


3MB limit is not enforced for $replace rules

Steps to reproduce

Add ||testcases.adguard.com/*/case2-response-over-3mb.txt$replace=/adguard/Test passed/i to the user filter
Open http://testcases.adguard.com/Filters/replace-rules/test-files/case2-response-over-3mb.txt

Expected result
The file stays unchanged
Actual result
$replace rule is applied

core/pull-requests/1422


BigQuery scripts to import/export GeoParquet files

This PR allows:

Export to GeoParquet a dataset (via SQL query) from BigQuery.
Import in BigQuery a dataset.

It doesn't aim to be a production-ready solution, in the future, it will be supported natively by BigQuery. However, in the meantime, it provides a way to work with GeoParquet and BigQuery.
Convert a SQL query to parquet:
poetry run python bigquery_to_parquet.py \
    --input-query "SELECT * FROM carto-do-public-data.carto.geography_usa_blockgroup_2019" \
    --primary-column geom \
    --output geography_usa_blockgroup_2019

Upload a parquet file or folder to BigQuery:
poetry run python parquet_to_bigquery.py \
    --input geography_usa_blockgroup_2019 \
    --output "cartodb-gcp-backend-data-team.alasarr.geography_usa_blockgroup_2019"

I've extracted to a global module some of the code generated at https://github.com/opengeospatial/geoparquet/pull/87

Closing this, as we'll move it over to https://github.com/geoparquet/bigquery-converter and keep the main geoparquet repo more focused on the spec.


Add install script

Existing fisherman installation script installs fisherman into $PWD, which may be undesirable to many people. I think most users will want fisherman to be installed in somewhere of his/her home directory by default.
Maybe http://install.fisherman.sh can point this file in the near future.
Closes #59

Hey @simnalamburt
We want to create the fisherman directory in XDG_DATA_HOME or ~/.local/share/fisherman.
Another thing, I am not sure if we even want the script commited to this repo.
What do you think about creating a new project for Fisherman installers?

@bucaran Agreed with XDG_DATA_HOME. OK about separating Fisherman installer from this repo, but I planned to add uninstall.fish as well as install.fish. Please note that when you create new repo

planned to add uninstall.fish

Good. This is why I think having a separate repo for all install/uninstall scripts is a good idea.
Also, we could offer an alternative install script that even installs fish, similar to what I used to do here.
Just an idae.

OK then please create a new repo under fisherman/ organization, I will send this PR again at there

Thanks. I'll keep you posted as soon as I create it.


Userbar use of rem conflicts with implementation styles

The Userbar font size is fixed at 14px, but the padding is set in rem, which in the case of the site in the screenshot above, is 16px, resulting in the odd padding above.
I think this is one case where em (or at least px) are preferable.

THANK YOU I've been wondering about that inconsistency! Makes perfect sense.
I've recently started using rems and it's pretty interesting how powerful they are, yet you want to use them interchangeably with pixels. Sometimes you have the intention of increasing the size of things when the text size increases, but sometimes you want things to remain static.
It's really interesting and a fun challenge to design sites in such a way that they can look right at any font size. And you also want to make sure you do what the user expects. For instance, if someone is visually impaired, maybe it makes sense to enlarge a logo with text in it when they increase the font size. Etc.

Yep, will change to ems to inherit all sizing from the font-size.


Geospatial methods

Issue
Related to https://github.com/brigade/mock_redis/issues/130
Description
Adds implementation of 4 of 6 geospatial methods including geoadd, geodist, geohash and geopos.

Thanks @rkotov93!


Reduce object allocation during wrap/unwrap while handshake is in progre...

...ss
Motivation:
Unnecessary object allocation is currently done during wrap/unwrap while a handshake is still in progress.
Modifications:
Use static instances when possible.
Result:
Less object creations.

@trustin @Scottmitch please review

LGTM

LGTM

Thanks..
Cherry-picked into 4.0 (d376bf6a58e3e4f0b6a6b5d90b5c88d16c0bf524) , 4.1 (bdfdf3094db00c7bfd610a3fb3e34ecae8e95aba) and master (b63fe25)


Object key signature is not taken into account with destructive assignment on method definition level

TypeScript Version:  2.3.2
Code
interface IMyInterface {
  onChange(changes : {[key : string] : {newValue : any, oldValue : any}})
}

class MyClass implements IMyInterface {
  onChange({config}) {
    console.log(config);
  }
}

class MyAnotherClass implements IMyInterface {
  onChange(changes) {
    const {config} = changes;

    console.log(config);
  }
}

Expected behavior:
compiled without errors
Actual behavior:
test.ts(5,7): error TS2420: Class 'MyClass' incorrectly implements interface 'IMyInterface'.
  Types of property 'onChange' are incompatible.
    Type '({config}: { config: any; }) => void' is not assignable to type '(changes: { [key: string]: { newValue: any; oldValue: any; }; }) => any'.
      Types of parameters '__0' and 'changes' are incompatible.
        Type '{ [key: string]: { newValue: any; oldValue: any; }; }' is not assignable to type '{ config: any; }'.
          Property 'config' is missing in type '{ [key: string]: { newValue: any; oldValue: any; }; }'.

Note: this affects Angular >1.5 users when writing component controllers and implementing $onChanges method

IMyInterface.onChange says it can be called by any object, as long as its properties have a certain type.
MyClass.onChange has a stricter requirement, saying it has to be called with an object with a property called config.
as a result MyClass is not substituatble for IMyInterface.
The second class MyAnotherClass, says it can be called with any arguments, no requirements here..
If MyClass.onChange  does not care if change is not provided, consider making it optional:
class MyClass implements IMyInterface {
  onChange({config = undefined}) {
    console.log(config);
  }
}

or give it an explicit type:
class MyClass implements IMyInterface {
  onChange({config} : any) {
    console.log(config);
  }
}

you can always give type, and you would see a similar error.
class MyAnotherClass implements IMyInterface {
    onChange(changes: { config: number }) {
        const { config } = changes;

        console.log(config);
    }
}

MyClass.onChange has a stricter requirement, saying it has to be called with an object with a property called config.

But this doesn't violate typings, and TS says it does:

Property 'config' is missing in type '{ [key: string]: { newValue: any; oldValue: any; }; }'.

doesn't [key : string] mean that it can be any property there (including config)?

doesn't [key : string] mean that it can be any key there (including config)?

but it can not be there at all. MyClass.onChange says it has to have config.

but again, does it violate typing?
why then const {config} = changes; doesn't say the same Property 'config' is missing in type '{ [key: string]: { newValue: any; oldValue: any; }; }'.?

cause changes is declared as any.... so any thing goes. give it a type like { config: number } and you will start seeing errors. use --noImplicitAny to flag these cases.

ohh, I though in this case changes aren't any, but { [key: string]: { newValue: any; oldValue: any; }; } because that's how IMyInterface says about them.
should this be matched this way? we are implementing specific method, so it's arguments should be matched with types provided in interface - this sounds logical for me

implements clause does not change any thing about your class, it is just an assert that this class has to be assignable to the interface.

so, if type is not specified the method's it is considered to be any and so it makes method compliant with interface definition, right?

so, if type is not specified the method's it is considered to be any and so it makes method compliant with interface definition, right?

correct. you can find more details about this in https://github.com/Microsoft/TypeScript/issues/10570

Looks like we have some issues here that need to be addressed after all...
interface IMyInterface {
  onChange(changes : {[key : string] : {newValue : any, oldValue : any}})
}

class MyClass implements IMyInterface {  // Error
    onChange({ config }) {
    }
}

class MyClass2 implements IMyInterface {   // OK
    onChange({ config }: { config: any }) {
    }
}

Uuufff! Glad that it helped to undercover some real issues at the end. Thanks for detailed explanation. And once again: any is evil :)

@mhegazy, I think this captures the bug you found without any destructuring. Did I understand it correctly?
interface IMyInterface {
  onChange(changes : {[key : string] : {newValue : any, oldValue : any}})
}

class MyClass2 implements IMyInterface {   // OK, but should be error
    onChange(x: { config: any }) {
    }
}

well there are a few issues here we need to understand and find a consistent place for..
these should all behave the same:
interface IMyInterface {
  onChange(changes : {[key : string] : {newValue : any, oldValue : any}})
}

class MyClass1 implements IMyInterface {   // OK, but should be error
    onChange(x: { config: any }) {
    }
}

class MyClass2 implements IMyInterface {   // OK, but should be error
    onChange({ config }) {
    }
}

class MyClass3 implements IMyInterface {   // OK, but should be error
    onChange({ config }: { config: any }) {
    }
}

arguable, remove the error to match things like:
var index: { [key: string]: { newValue: any, oldValue: any } };
var { config } = index;

var tmp = index;
var config = tmp.config;

Since this is comparing assignability of parameters, there is bivariance. So it shouldn't be an error.


Disable Run button until AS compiler is ready

Re-apply fix for https://github.com/nearprotocol/NEARStudio/issues/88

Needs end-to-end test, let's track in https://github.com/nearprotocol/NEARStudio/issues/121