Suggestion for Recipes page

In the http://pythonhosted.org/gpiozero/recipes/#full-colour-led-controlled-by-3-potentiometers example you use both the 'manual way' of doing things, and also a 'cleaner' example connecting the source of an LED to the values of an ADC.
Maybe you could also illustrate a similar thing in the http://pythonhosted.org/gpiozero/recipes/#button-controlled-led example by adding e.g.
from gpiozero import LED, Button
from signal import pause

led = LED(2)
button = Button(3)

led.source = button.values

pause()

(at least, I assume that's the intention for the source and values properties?)

Slightly off-topic:
I'm not very familiar with generators, is the code below the "correct" way to set up an "inverse generator" so that when the button is pressed, the LED is off?
from gpiozero import LED, Button
from signal import pause

led = LED(2)
button = Button(3)

def invert(gen):
    for value in gen:
        yield not value

led.source = invert(button.values)

pause()

(of course in this particular example, the code using when_pressed / when_released would actually be a bit shorter)

Yup, that's the intention of source and values. I really must find some time to write up some good examples of using them, but both your examples are good ones. That invert filter is perfect for boolean valued components (button, LED, etc.) but is a bit "binary" for the more nuanced components like LightSensor which return a value somewhere between 0 (dark) and 1 (light). In that case you might want something like this:
from gpiozero import PWMLED, LightSensor
from signal import pause

sensor = LightSensor(18)
led = PWMLED(2)

def invert(gen):
    for value in gen:
        yield 1 - value

led.source = invert(sensor.values)

Now the LED should be bright when the sensor is dark and dark when the sensor is lit. You can also do neat things like make a "slow" filter, and a "delay" filter:
from time import sleep

def slow(gen):
    for value in gen:
        yield value
        sleep(0.1)

def delay(gen, n=10):
    queue = []
    for value in gen:
        queue.append(value)
        if len(queue) > n:
            yield queue.pop(0)

Now you can have a second LED and have its value set to the same value as the first LED, but a bit delayed:
led2 = PWMLED(3)

led2.source = delay(slow(led.values))

You can also make filters that work like logic gates using zip:
# This is required for python 2 (and does nothing in python 3 which already has an
# iterable zip built in - so you could omit this on python 3)
try:
    from itertools import izip as zip
except ImportError:
    pass

def and_gate(gen1, gen2):
    for v1, v2 in zip(gen1, gen2):
        yield v1 and v2

Now if you had two buttons you could set an LED to come on only if both buttons are pressed:
btn1 = Button(17)
btn2 = Button(18)
led = LED(4)

led.source = and_gate(btn1, btn2)

I used versions of this the other day to demonstrate building a half-adder and a full-adder using some buttons (for the inputs) and a couple of LEDs (for the outputs). You can also extend the and_gate recipe to have as many inputs as you like:
def and_gate(*gens):
    for values in zip(*gens):
        yield all(values)

And similarly you could use any for an n-input or_gate. Anyway, if you fancy doing some doc patches, there's some ideas! I will get around to it at some point but I'm diving into the guts of RPi.GPIO at the moment, so it might be a while before I come up for air!

Thanks for the info and examples! Gives me lots more to experiment with.

Now the LED should be bright when the sensor is dark and dark when the sensor is lit.

Perfect for a "night light" type application :-)

And similarly you could use any for an n-input or_gate.

Perfect for a "burglar alarm" type application :-)
Something else I also noticed while experimenting is that https://github.com/RPi-Distro/python-gpiozero/blob/master/gpiozero/devices.py#L136 seems to be running as fast as possible, which means Python ends up consuming 100% CPU. I guess if you added a very small time.sleep() in there, then it should reduce the CPU usage without introducing any user-visible slowdown? Or if that would be too detrimental, maybe you could provide some method of having the user tell the 'source' property how long it should sleep before fetching the next generator value?

...and for another idea, I guess you could plug the output of a random-value-generator into the source of a PWMLED, to give a "flickering candle" effect? :)

Yup, what actually happens when you assign something to "source"? Behind the scenes, some fairly complex stuff actually goes on:

If there's an existing source, we shut down the thread reading it and wait for it to terminate
If the new source is None, do nothing, exit here
If the new source isn't None, start a new background thread that reads values from the assigned iterable as fast as possible until it's exhausted

If you throw the slow filter above around the new source you'll find it won't eat 100% of the CPU time. So why don't we do that by default? Firstly because it doesn't actually matter that it's eating 100% of CPU time (it's not really keeping the CPU that busy - it's more that CPU time is measure of the number of threads "doing work" - the Pi would be perfectly responsive even if you chained several of those together). Secondly because it's easy to throw in a slow filter if it really bothers anyone, and thirdly because leaving it unfiltered by default gives users the most flexibility.
For example, at the moment one can make nice effects like smoothly fading in and out LEDs using source. But if we introduce a default delay we potentially remove that capability (depending on its length). Could we make the default delay variable in length? Yes, but only by adding another property to the class (and personally I think the filter method is much cleaner and more flexible).
Here's some more interesting filter ideas: one could write a filter which only returns every other value from the source:
def every_other(gen):
    state = True
    for value in gen:
        if state:
              yield value
        state = not state

Or a more subtle one that only yields values on a signal from another component, like a clock sync:
def clocked(gen, clk):
    gen = iter(gen)
    for value in clk:
        if value:
            yield next(gen)

Now you can demonstrate using a clock signal to "copy" values from one LED to another:
led1 = LED(12)
led2 = LED(16)
btn = Button(26)

led2.source = clocked(led1.values, btn.values)

Set led1 on, and led2 won't copy that state until you press the button. Likewise, if you then set led1 off, led2 won't copy that state until you press the button again (the button is the "clock" signal).

Oooh - nice idea on the random values one - I hadn't thought of that!
from random import random

def random_source():
    while True:
        yield random()

And then:
led = PWMLED(12)
led.source = random_source()

Or if you want a binary version:
def random_source():
    while True:
        yield random() > 0.5

led = LED(12)
led.source = random_source()

Okay... I think I'm starting to get the idea :)  But not quite up to writing documentation about it yet ;-)
I guess the idea with the 'slow' filter, is that it's easier to slow down the rate at which the generator emits values, than it is to slow down the rate at which the source requests values? And I guess it'd also be easy to add a 'delaytime' parameter to the 'slow' filter to make it more adjustable, i.e.
def slow(delaytime, gen):
    for value in gen:
        yield value
        sleep(delaytime)

Which, if I've understood things correctly, means you could potentially write the "blink" example as:
from gpiozero import LED
from signal import pause

def slow(delaytime, gen):
    for value in gen:
        yield value
        sleep(delaytime)

def alternate():
    value = False
    while True:
        yield value
        value = not value

led = LED(17)
led.source = slow(1, alternate())
pause()

Lots of experiments with LED-flashing to be done this evening... :+1:

You certainly could write blink that way (as soon as I'd added source and values I started seeing ways to reimplement everything we were doing with events with source and values instead, but we've left events in because they can be clearer sometimes).
Anyway, the one misconception in your comment above is that there is a "rate" at which values produces items. Rather, there is a rate at which source attempts to read values which, by default, is "as fast as possible". However, the magic of generators in python is that the act of source attempting to read something from the provided iterator causes values to read the object's state.
In other words, when values is not connected to anything, it reads nothing. When you ask values for an item, it will produce one in response but won't do any further work unless you ask for another (and so on). The "slow" function works effectively by causing values to take a long time to return an item (source is trying to read as fast as ever but each time it reads a value it takes several milliseconds to get one, but we don't need to worry about queueing anything because values won't read anything more until source asks for the next value).
Hopefully that makes some sense but if not, let me know and I'll try and clarify (probably badly!)

(as soon as I'd added source and values I started seeing ways to reimplement everything we were doing with events with source and values instead, but we've left events in because they can be clearer sometimes).

Yeah, I guess like a lot of simple vs. advanced language features, events are simpler and easier to grok, but generators are more complex but much more powerful ;-)

Hopefully that makes some sense but if not, let me know and I'll try and clarify (probably badly!)

http://stackoverflow.com/questions/231767/what-does-the-yield-keyword-do-in-python provides a few useful tidbits here & there.
Going back to the "slow" filter / function / generator, apart from the very first time that it's called (yields), does it make any difference if it's written as
def slow(delaytime, gen):
    for value in gen:
        yield value
        sleep(delaytime)

or
def slow(delaytime, gen):
    for value in gen:
        sleep(delaytime)
        yield value

?
Presumably the "magic of generators" means that the source reading the generator gets the 'current value' of the generator (e.g. whether the button is pressed or not) at the moment of the source thread getting the value (if you see what I mean - kinda hard to explain!) regardless of how big our delaytime is?

Going back to the "slow" filter / function / generator, apart from the very first time that it's called (yields), does it make any difference if it's written as [sleep before or after]?

You're absolutely right: other than the first time it's called, it makes absolutely no difference which way it's written.

Presumably the "magic of generators" means that the source reading the generator gets the 'current value' of the generator (e.g. whether the button is pressed or not) at the moment of the source thread getting the value (if you see what I mean - kinda hard to explain!) regardless of how big our delaytime is?

Sorry, no that's not quite right. To answer this I'm afraid I'll have to delve into how generators actually work. The trivial method of explaining them is that they're a special case of co-routines where the routine can only be entered at the top, or immediately after the last yield point during iteration. Unfortunately, if you don't know what co-routines are that's probably meaningless, so I'll try an expanded version below...
A normal function has a trivial means of execution:
def foo(a, b):
    result = a + b
    return result

print(foo(1, 2))

foo is called with parameters 1 and 2.
The parameter's names are locally bound to the parameter's values (in the function's local state, a=1 and b=2).
The function's instructions are executed from top to bottom (we calculated result, then return it)
Once the function returns, its local state is forgotten.

A generator function is rather different:
def foo(a):
    yield a
    a += 1
    yield a
    a += 1
    yield a

for value in foo(1):
    print(value)

Firstly note that a generator function must be called in the context of an iterable (e.g. a for loop as above, in a list comprehension, or as a parameter of a function that will loop over it, like sum())
The generator function's call starts off like the traditional function above. Parameter values are bound to their names in the function's local state (here a=1)
We start executing the function's body from top to bottom. The first statement is yield a. At this point, the function "yields" the value 1 to the calling loop.
The loop's body now executes with the returned value (1) assigned to the loop variable (value).
Now we're back at the top of the loop, we re-enter the generator function at the point we left it and continue executing.
Note that its local state (a=1) has been preserved. We now add 1 to a (local state is now a=2) and once again yield a value.
The loop's body now executes again with the yielded value (2) assigned to the loop variable.
We're back at the top of the loop and we re-enter the generator function again.
Once again, the function's local state has been preserved. We add 1 to a and yield a final time.
The loop's body now executes again with 3 assigned to the loop variable.
We're back to the top of the loop and we re-enter the generator function.
The generator function is now at the end of the function, which implicitly raises a StopIteration exception. The calling loop catches this and silently terminates.

The points to take away are:

The generator doesn't have a "current value". Whenever a loop calls it, it executes code which eventually either yields another value, or raises StopIteration to terminate the calling loop.
The generator's state is preserved between yields. You can think of it as a slightly odd function which starts at the top, but then "pauses" when it yields and carries on after the yield when the calling loop next iterates.
But note that calling the generator from a different loop creates a new "instance" of that generator which will start at the top (a generator can be in use from multiple loops simultaneously and each loop represents a different runtime state for the generator).
What happens if the calling loop terminates (e.g. break) whilst the generator function has yielded control to it? In that case the generator function's state is terminated too (there's some complexity here if the generator function was in the middle of a try..finally block in which case the finally clause will execute prior to the calling loop's termination, but that's about it).

You can probably guess from all this that the implementation of values in gpiozero is ridiculously trivial:
@property
def values(self):
    while True:
        try:
            yield self.value
        except GPIODeviceClosed:
            break

Although it's just occurred to me I should have written it even more simply:
def values(self):
    try:
        while True:
            yield self.value
    except GPIODeviceClosed:
        pass

The implementation of source is a tad more complex (because it's setting up background threads) but the stuff that reads the source is still trivial:
# ...
for v in source:
    self.value = v
    if self._source_thread.stopping.wait(0):
        break
# ...

So looking at a trivial thing like led.source = btn.values we'd see the following sequence of code:

In source: for v in source starts the values generator
In the values generator we start an infinite while True loop
The values generator yields the button's state (let's call it 0)
0 is assigned to the source for loop's variable v=0
The source loop's body is executed and the value of v is assigned to the target object's value (the led is set off)
We haven't requested the source loop terminate so now we're back at the top of the for loop
We re-enter the generator and we're back in the infinite while loop which loops around and yields another value (let's call it 1 this time)
1 is assigned to the source for loop's variable v=1
The source loop's body is executed and the value of v is assigned to the LED (it switches on)
Now let's say we set source = None which signals the thread to terminate
We notice this in the stopping check and call break on the for-loop
Because the calling loop has terminated, the values generator function (which was in the middle of an infinite while True loop) is also terminated. There's no try..finally statement, so nothing to clear up, and we're all done.

Okay, I've rambled on for far too long - do let me know if anything's not clear! And try working through the sequence of operations when a filter or two is thrown into the mix. The surprising thing is that it's rather easy to write powerful filters and yet when you actually dig into the order of execution, it's horribly complicated with local state lying around all over the place!

Yeah, that's kinda how I understood things working, except I didn't realise you could have multiple yield statements in a single generator function. But now that I better understand how generators work (thanks!) even that makes perfect sense now.
Who would have thought that a library for "simpler GPIO access" would end up teaching me so much about advanced Python features?! :-)
What I meant with my previous (confusing) question, was that given an extreme example of:
from gpiozero import LED, Button
from signal import pause
from time import sleep

def slow(delaytime, gen):
    for value in gen:
        sleep(delaytime)
        yield value

led = LED(17)
button = Button(3)
led.source = slow(10, button.values)
pause()

then when the LED gets "set" does it get set to the state of the button "now", or does it get set to the state of the button 10 seconds ago? Or (in some circumstances) does it actually make a difference if the sleep is before or after the yield? (contrary to your previous answer)

Ahh, I see. From that perspective, yes it can make a difference. Here's a quick walk-through of what will go on in your example above (with the sleep first in the loop):

Setting led.source spawns a background thread that runs the loop we saw previously (for v in source: self.value = v)
In this context, source is a call to your slow generator, so we start your generator
Now within slow we come to for value in gen. In this context, gen is the btn.values property which is itself a generator.
In btn.values we effective have while True: yield self.value so at this point, the button's state is read (let's say it's not currently pushed, so False) and yielded to the slow generator
Now we're into the slow generator's for-loop body. value is False, but the first thing we run across is sleep(10) so we delay for ten-seconds.
For the sake of argument, let's say that some time during that 10 second delay you press (and hold) the button.
Now we yield value. Remember that it's still False because we read it before the delay.
Finally we're back to the source loop. False is assigned to v and subsequently assigned to the LED's value property, leaving the LED off.
Now we're back to the top of the source loop so we re-enter the slow generator function.
The slow generator loops back round to the top of its for-loop and we re-enter the values generator.
This now yields True because the button is pushed.
Now we're back to the slow generator and the value loop variable has been assigned True, but we wait 10 seconds first.
Then we yield True back to the source loop.
And finally we're back in the source loop and the LED turns on.

So, in your example there would be a significant delay between you pushing the button and the LED turning on (assuming you pushed the button in the middle of one of the sleeps which is pretty likely).

Thanks, that makes perfect sense, and is exactly the answer I was hoping you'd give!
I think I understand it all now :-)
So, last question for now... could my example above be re-written as:
from gpiozero import LED, Button
from signal import pause
from time import sleep

def slow(delaytime, gen):
    while True:
        sleep(delaytime)
        yield next(gen)

led = LED(17)
button = Button(3)
led.source = slow(10, button.values)
pause()

...and then it doesn't matter where in the loop the sleep happens?
And I guess if I wanted to stick to using for rather than while (in case the generator is non-infinite) I could 'emulate' the sleep-before-yield version of slow, without introducing a "button lag" by rewriting it as:
def slow(delaytime, gen):
    sleep(delaytime)
    for value in gen:
        yield value
        sleep(delaytime)

I also discovered that you can call print from inside generators (I wasn't sure if that would be allowed) which makes debugging things / working out what's going on a bit easier.

Sure, your while version would indeed work, as would your adjusted for-version.
One minor note: in certain circumstances you may need to call iter() prior to calling next(). You won't with the result of a generator like values but if you passed in a straight-forward list or something similar, you would. This is because next() expects an iterator (i.e. something that provides the special __next__ method), while a list is a collection (which can be iterated over by deriving an iterator from it with iter()). So to work with all iterable inputs you'd need something like:
def slow(delaytime, gen):
    gen = iter(gen)
    while True:
        sleep(delaytime)
        yield next(gen)

Great, thanks.
According to https://wiki.python.org/moin/Iterator I think you meant next rather than __next__ ?
(that page needs to be read very carefully, to distinguish iterable (e.g. a list) from iterator (which I guess you can imagine as sort of like a pointer, which automatically jumps to the next element in the list each time you read its value).)
Presumably if gen is already an iterator (which a generator automatically is), then gen = iter(gen) is effectively a nop?

next was the name under Python 2; Python 3 changed it to __next__ as it's effectively an internal method which isn't usually called directly (only via the next() built-in function). And yeah, it's a hairy area linguistically! Your analogy of a pointer is an excellent one, incidentally. Just consider that each thing returned by iter() is a separate pointer which you then move along with next() and you're there.
I'm not 100% sure if gen = iter(gen) is a no-op in the case that gen is originally an iterator, or whether it winds up wrapping the iterator in another iterator. I could go and dig it out of the source code, but for now I'm happy enough to know that "it just works" (tm).
Incidentally, a while back I ran a workshop for our local Python North West group on infinite iterators (and iterator filters), as I think they're hugely powerful and yet generally unknown.
Anyway, just to demonstrate a truly silly idea, here's an infinite iterator (using the "requests" and "beautiful soup" libraries; sudo apt-get install python3-requests python3-bs4) which polls the BBC News homepage and yields the count of the word "pie" or "pies" which I then feed to an LED to provide a visual indication of the amount of pies in the news:
import re
import requests
from time import sleep
from gpiozero import PWMLED
from bs4 import BeautifulSoup
from signal import pause

def word_count(word, url="http://www.bbc.co.uk/news"):
    while True:
        page = requests.get(url)
        soup = BeautifulSoup(page.content)
        yield len(soup.find_all(text=word))
        sleep(3600) # sleep an hour before hitting the beeb again

def normalize(it):
    m = 1 # got to start somewhere north of 0
    for i in it:
        m = max(m, i)
        yield i / m

# The more pies in the news the more the LED glows!
led = LED(12)
led.source = normalize(word_count(re.compile('pies?', re.IGNORECASE)))
pause()

P.S. Don't ask me how long it took my warped sense of humour to come up with something politically neutral and not massively offensive like "pies" ... and don't ask what I came up with first either ...

next was the name under Python 2; Python 3 changed it to next as it's effectively an internal method which isn't usually called directly (only via the next() built-in function).

Ahhh, that makes sense! I was wondering why next(i) and i.next() worked equally well.
Today seems to be pie-free :-/

Doh, that was meant to be a PWMLED ... just a sec ...

@lurch has your issue been resolved or do you still have a suggestion for change?

Sorry this got so long-winded and slightly off-topic, but I believe my initial suggestion still holds?
I guess this is a "documentation suggestion" reminder issue, but feel free to close if it's not appropriate.

Blame me for getting off-topic - not an un-common occurrence, sorry!

If / when you get round to adding more examples to Recipes, I guess this is a nice example too?
http://raspi.tv/2016/using-mcp3008-to-measure-temperature-with-gpio-zero-and-raspio-pro-hat#comments

I second the temperature proposal. It's something I'm working on right now. How to convert a resistance/voltage to temperature.


[DOC] Qualification docs emphasize cost savings, is that what we still want?

Report incorrect documentation
Location of incorrect documentation
the qualification tool docs emphasize cost savings and speedups, do we want to change this to be top level candidates type wording and say more about tuning and cluster config recommendations

It is hard a call to decide to navigate way from Cost-savings because the requirements change over time.
Previously, the tools CLI went back-and-forth on doing cost-savings by default Vs. give the option to disable it..
We are doing incremental changes to the Qualification Nvidia docs https://docs.nvidia.com/spark-rapids/user-guide/24.04/qualification/overview.html
Eventually, there will be information about

estimation-model (QualX)
TCL. this also requires updates in the output details.

Assigned it to @mattahrens to decide on whether TCO should be pushed down the documentation/removed.

I have merged in changes to the User Guide overview page for the qualification tool to highlight the aspects of qualification related to the list of qualified jobs as well as recommended configs and cluster shape and de-emphasized speedups.

Updated User Guide for qualification tool to remove cost savings references.


Viewport rotation animation

I needed viewport rotation animation since I wanted to animate the rotation including overlays. Rotating the tiled image doesn't also rotate the overlays.
closes #1060 and #1736
Not sure if this should be turned on by default when using the buttons offered by showRotationControl.

I noticed that now getHomeBounds() returns the wrong bounds compared to the non-animated version. I will try to fix this!
I also noticed that the image in the navigator still rotates immediately, so for as long as the duration of the animation it now shows something incorrect.

BTW, it works nicely! :)
I see that the navigator isn't animating. Are you still working on fixing that?

Thanks! Though I did noticed something odd, when one keeps the r or R key pressed, it spins wildly!
The problem with the navigator was that it has its own option for animationTime which is initially set to 0. Shouldn't that be automatically set to the same as the viewport's animationTime?

Thanks! Though I did noticed something odd, when one keeps the r or R key pressed, it spins wildly!

I suppose that makes sense, since there will be many key presses as the result of the "auto key" functionality of holding down a key. It looks like that is already present prior to this patch. I think it's fine to leave it as is if you want, but if you're up for fixing it, you would want to change the key handling so it pays attention to keydown and keyup and does its own auto-repeat that rotates a little each time. You might also make it detect if it was a short key press and then snap it to the nearest 90.

The navigator's rotation isn't animated because it has its own option for animationTime which is initially set to 0. Shouldn't it be automatically set to the same value as the viewport's animationTime?

Interesting... I don't know why it's like that. I would think it would be fine to change it to match the parent viewer's. Maybe give it a try and see how it goes?

BTW, we just merged another PR and now there are merge conflicts here. Please fix those when you get a chance.

I implemented the requested changes. I had to change the internal value from degrees to initialDegrees, otherwise it would throw an error in the jquery extend function, somehow it was already using the setter for degrees while the spring wasn't initiated yet. To be fair, I didn't quite understand it!
Concerning the key strokes behaviour, that seems to be quite a big change, I think I will leave it for now.
However, there is something else I noticed: Since now degree values higher than 360 or lower than 0 are allowed, this could cause some unwanted behaviour. For example in my project, we have overlays with a predefined degree value, and upon clicking those the viewport fits its bounds and rotates accordingly. However, if the viewport has been rotated a few times before via the rotation buttons, it might cause a rotation from for example 900 degrees to 90, which without animation was fine, but now will result into some funny looking spinning. Maybe we could add an argument to setRotation, something like shortestPath or add a new function setRotationShortestPath ?

Good point about the degrees... Makes sense, since the getter is already in the prototype even as the constructor is called.
A thought about allowing numbers outside of 360... I bet we can actually handle that all within getRotation and setRotation... getRotation can do a modulus on the value before returning it, and setRotation can take in values outside of the range and do animation based on those values, but at the end of the animation, reset to inside 360 again. The setRotation with animation will need to set the spring current value to the modulus version, since that's what people will be basing it off of. I think if we do that, we can keep everything within 360 which will probably be easier for developers (especially existing apps). What do you think?

Things are looking good here. What do you think of my suggestion to handle the modulus get/set rotation? I think that's the last thing to deal with here.
Just a note for me: I need to mention in the changelog that the animation is a new behavior.

I did give it a try but ran into some issues:

When rotating to 360 and then to 270, it will effectively rotate from 0 to 270, that is clockwise, when I would have expected a counter-clockwise rotation.
When rotating while a rotation from a value below 360 to a value above 360 is still in process, it can have the effect of rotating in the other direction, for example from 350 all the way to 90 but counter-clockwise. This is probably the same issue.

I think it is valid to allow rotation degrees below 0 and above 360, but should we allow for rotations that do not use the shortest path? Is there ever a use case for that?

I think our built in animations should always use the shortest path. If someone wants to create some sort of multi-revolution spin, or something, they can animate it themselves.
BTW, I had another realization... Using the % doesn't give you what you want for negative values. -10 % 360 gives you -10 when what you really want is 350. What you want instead is the Euclidean modulo:
https://threejs.org/docs/index.html?q=math#api/en/math/MathUtils.euclideanModulo
I guess it's time we have a helper function for that.
Regarding from 360 to 270, I think you want something like this:
var from = 360;
var to = 270;

from = euclideanModulo(from, 360);
to = euclideanModulo(to, 360);
var diff = to - from;
if (diff > 180) {
    to -= 360;
} else if (diff < -180) {
    to += 360;
}

@jonasengelmann Are you still interested in working on this? I understand it has gotten a bit bigger than originally intended. Anyway, just a reminder that it exists :)

@iangilman Sorry for delay, I have been meaning to tackle this. I implemented your suggestion, however there is one remaining issue:
There were situations where the shortest rotation path effectively required a rotation to values above 360, eg. from 359 to 450. After such a rotation the current rotation value was above 360. To fix this, I simply updated the getRotation function to always return the Euclidean modulo of it. So now rotation values are only between 0 and 360. Could this be a problem? I saw that it resulted in one test failing, as it expected a value of -90 and not 270. However, rotation to -90 degrees is still possible, and also getRotation - 90 does what one expects. What do you think?

@jonasengelmann No rush here... Thank you for keeping up with it!
That's an excellent point about the -90. Of course we can just change the unit test, but the fact is we may already have some users out there whose code relies on negative values. You've given me an interesting idea! What if, instead of forcing the degrees to always be 0 - 360, we let them be whatever, but when someone does a setRotation we change the from value to make a smooth animation?
In other words, something like this:
var normalizedFrom = $.euclideanModulo(this.degreesSpring.current.value, 360);
var normalizedTo = $.euclideanModulo(degrees, 360);
var diff = normalizedTo - normalizedFrom;
if (diff > 180) {
    normalizedTo -= 360;
} else if (diff < -180) {
    normalizedTo += 360;
}

var reverseDiff = normalizedFrom - normalizedTo;
this.degreesSpring.resetTo(degrees + reverseDiff);
this.degreesSpring.springTo(degrees);

I don't know, there might be a cleaner way to write that code, but you get the idea.
Anyway, this seems like a nice way to ensure the animation is smooth, but allow the developer to use whatever numbers they want. What do you think?
A couple other observations:

I realize I'm the one who asked you to make a euclideanModulo, but I'm finally realizing that the positiveModulo we have already does the same thing. Probably better to stick with that (and maybe add a comment to it to mention the term "euclidean modulo" to avoid this confusion in the future).
There are a number of places where we are using % 360. Some of them may go away with my above suggestion for setRotation, but the rest should probably be converted to positiveModulo.

I know this is turning into a long road, but I feel we're very close here! Thank you again for sticking with it, and for bringing up all these good points!

@iangilman I finally implemented your suggestions. I agree, I think it is by far the cleanest solution!
I also removed the Euclidean modulo helper function, however, as I am not too familiar with the code base, I wasn't sure in which places % 360 should be replaced with the positive modulo value of it. As far as I can see % 360 is only used in drawer.js in the drawDebugInfo function as well as in tiledimage.js in the _drawTiles function.


low-hanging optimizations for exact lookahead

ground the NSRTs only once per task, rather than on every call to task_plan. this seems to be a 2-3x speedup (based on running the analysis script before vs after).

can we add some comments to task_plan/task_plan_grounding regarding usage?


UpSampling3D Layer does not accept 'None' sized inputs under tensorflow

It appears the UpSampling3D does not support None-sized inputs in Tensorflow
ValueError: Axis 1 of input tensor should have a defined dimension, but is None. Full tensor shape: (None, None, None, None, 1). Typically you need to pass a fully-defined `input_shape` argument to your first layer.

2D case works fine
from keras.models import Sequential
from keras.layers import UpSampling2D, UpSampling3D
twod_model = Sequential()
twod_model.add(UpSampling2D((2,2), input_shape = (None, None, 1)))

3D Case
threed_model = Sequential()
threed_model.add(UpSampling3D((2,2,2), input_shape = (None ,None, None, 1)))

One Dimension
threed_model = Sequential()
threed_model.add(UpSampling3D((2,2,2), input_shape = (1 ,None, None, 1)))

Error
ValueError: Axis 2 of input tensor should have a defined dimension, but is None. Full tensor shape: (None, 2, None, None, 1). Typically you need to pass a fully-defined `input_shape` argument to your first layer.

[x] Check that you are up-to-date with the master branch of Keras. You can update with:
pip install git+git://github.com/fchollet/keras.git --upgrade --no-deps

[x] If running on TensorFlow, check that you are up-to-date with the latest version. The installation instructions can be found here.

[x] Provide a link to a GitHub Gist of a Python script that can reproduce your issue (or just copy the script here if it is short).

I am having this issue as well

Same issue here.


Test fails, if TZ=UTC is not set

Currently the following test fails, if not prefixed by an export TZ=UTC:
============================= test session starts ==============================
platform linux -- Python 3.7.0, pytest-3.6.4, py-1.5.4, pluggy-0.7.1
rootdir: /build/todoman/src/todoman-3.4.0, inifile: setup.cfg
plugins: hypothesis-3.66.24
collected 176 items

tests/test_backend.py .........                                          [  5%]
tests/test_cli.py .............x..........F...........................s. [ 35%]
...........                                                              [ 42%]
tests/test_config.py .......xx......                                     [ 50%]
tests/test_filtering.py .........                                        [ 55%]
tests/test_formatter.py ...............                                  [ 64%]
tests/test_main.py .                                                     [ 64%]
tests/test_model.py ............ss..ss................                   [ 84%]
tests/test_porcelain.py ........                                         [ 88%]
tests/test_ui.py ...........                                             [ 94%]
tests/test_widgets.py .........                                          [100%]

=================================== FAILURES ===================================
______________________________ test_default_due2 _______________________________

tmpdir = local('/tmp/pytest-of-builduser/pytest-0/test_default_due20')
runner = <conftest.runner.<locals>.SleepyCliRunner object at 0x6fac5c3d2d30>
create = <function create.<locals>.inner at 0x6fac5c466d08>
todos = {'aaa': <todoman.model.Todo object at 0x6fac5c3be438>, 'bbb': <todoman.model.Todo object at 0x6fac5c3be198>, 'ccc': <todoman.model.Todo object at 0x6fac5c3be400>}

    @pyicu_sensitive
    @freeze_time(datetime.datetime.now())
    def test_default_due2(tmpdir, runner, create, todos):
        cfg = tmpdir.join('config')
        cfg.write('default_due = 24\n', 'a')

        r = runner.invoke(cli, ['new', '-ldefault', '-dtomorrow', 'aaa'])
        assert not r.exception
        r = runner.invoke(cli, ['new', '-ldefault', 'bbb'])
        assert not r.exception
        r = runner.invoke(cli, ['new', '-ldefault', '-d', 'one hour', 'ccc'])
        assert not r.exception

        todos = {t.summary: t for t in todos(status='ANY')}
        assert todos['aaa'].due.date() == todos['bbb'].due.date()
>       assert todos['ccc'].due == todos['bbb'].due - datetime.timedelta(hours=23)
E       AssertionError: assert FakeDatetime(2018, 8, 4, 19, 32, 48, tzinfo=tzlocal()) == (FakeDatetime(2018, 8, 5, 19, 32, 48, tzinfo=tzlocal()) - datetime.timedelta(seconds=82800))
E        +  where FakeDatetime(2018, 8, 4, 19, 32, 48, tzinfo=tzlocal()) = <todoman.model.Todo object at 0x6fac5c3be400>.due
E        +  and   FakeDatetime(2018, 8, 5, 19, 32, 48, tzinfo=tzlocal()) = <todoman.model.Todo object at 0x6fac5c3be198>.due
E        +  and   datetime.timedelta(seconds=82800) = <class 'datetime.timedelta'>(hours=23)
E        +    where <class 'datetime.timedelta'> = datetime.timedelta

tests/test_cli.py:302: AssertionError
========= 1 failed, 167 passed, 5 skipped, 3 xfailed in 10.30 seconds ==========

Tests should not depend on a specific timezone to be set.

I just checked the AUR package's history to find out a bit more about this. (link)
This is actually due to a bug in freezegun, and only occurs for some timezones. The AUR package sets TZ=UTC to work around it.
I'll have to dig a bit more to try and find out what the issue with freezegun was though, cause I didn't link to an actual ticket. :(

Actually, it doesn't look like an issue with freezegun. :stuck_out_tongue:
For this test, we spoof the current time, but depending on your timezone and the time, this might mean it's already "tomorrow" UTC.
I'll have to think about this a bit more, but it can probably be fixed on our end. I'm actually tempted to add TZ=UTC to tox.ini though, since this doesn't really reflect any breakage on todoman itself.

Hm, with todoman 3.5.0 I'm not experiencing this issue... but maybe it's flaky behavior?


[Bug] When profile button is clicked, a menu opens which is stuck on loading

Does this issue occur when all extensions are disabled?: Yes

VS Code Version: 1.62.0, b3318bc0524af3d74034b8bb8a64df0ccf35549a, x64
OS Version: Linux saif-latitude 5.16.0-zen1-1-zen #1 ZEN SMP PREEMPT Mon, 10 Jan 2022 20:12:01 +0000 x86_64 GNU/Linux,

Steps to Reproduce:

Fresh installation of vscode on a arch linux based distro (currently using garuda linux) with sudo pacman -S code
Click on the profile button at the bottom left to get this menu as shown in the screenshot attached.

Also, is there anyway I can access the "Turn On Setting Sync" option in there through the Command Platte?

I don't think that's the right package. I think you want this one:
https://aur.archlinux.org/packages/visual-studio-code-bin/?O=10&PP=10


Do not track users who have enabled 'DoNotTrack'

Adds a guard around Google Tag Manager script to prevent it from initialising,
for users who have indicated they do not want to be tracked.
Also removes the <noscript></noscript> include as we can't guard this.
If we were server rendering the site, we could take advantage of the 'DoNotTrack' header.
https://trello.com/c/jHVUmpdx/957-do-not-track-users-with-donottrack-enabled
Fixes #173

You can preview this change here:
Built with commit bfc7f4814c17b243fdacfe713545fced1cf04f84
https://deploy-preview-296--govuk-design-system-preview.netlify.com

Yeah

If we were server rendering the site, we could take advantage of the 'DoNotTrack' header.

ok.
isnt there a requirement for gtm scripts  to be both in head and body (2 parts)?

The body version is only run if the user has JavaScript enabled since it's wrapped with <noscript>.
Since we can't conditionally render this server side, we'd still track users that had DoNotTrack enabled and JavaScript disabled.
It feels reasonable to not track people when JavaScript is disabled. One reason people disable JavaScript is to avoid tracking.

I believe Safari has removed "Do not track" - https://www.macworld.com/article/3338152/apple-safari-removing-do-not-track.html is this still relevant?

The W3C have concluded their work on DNT and are not advancing it to a standard https://www.w3.org/TR/tracking-dnt/

there has not been sufficient deployment of these extensions (as defined) to justify further advancement


Cleanup multipart upload trait

Which issue does this PR close?

Closes #.
Rationale for this change
https://github.com/apache/arrow-rs/pull/4570 made this public, before releasing it and committing to the API we should clean it up

What changes are included in this PR?

Are there any user-facing changes?

fyi @yjshen


"ȚĂNDĂREI" is listed in the drop-down menu

Description:
When user writes "ȚĂNDĂREI" the location appears in the drop-down menu next to the comune and the county which is a part according to the law
Precondition:
The website is up an running.

Step 1
Write in the search bar "ȚĂNDĂREI"

Expected results
The location appears in the drop-down menu as "Oras ȚĂNDĂREI, IALOMIȚA "

Step 2
Press "x" button.

Expected results
The location was deleted from the search bar.

Step 3
Write again in the search bar "ȚĂNDĂREI"

Expected results
The location appears in the drop-down menu as "Oras ȚĂNDĂREI, IALOMIȚA, (ȚĂNDĂREI) "


Gulp + Browserify error

Hi, when I try to import vue-mdl module I get this error:
Cannot find module '!!./../node_modules/css-loader/index.js?sourceMap!./../node_modules/vue-loader/lib/style-rewriter.js!./../node_modules/vue-loader/lib/selector.js?type=style&index=0!./select.vue'

My gulpfile.js
var gulp = require('gulp'),
    browserify = require('browserify'),
    source = require('vinyl-source-stream'),
    buffer = require('vinyl-buffer'),
    uglify = require('gulp-uglify'),
    sass = require('gulp-sass'),
    livereload = require('gulp-livereload'),
    concat = require('gulp-concat'),
    babel = require('gulp-babel');

gulp.task('browserify', function() {
    browserify('src/app.js')
        .transform('babelify', {presets: ['es2015', 'react']})
        // .transform('envify')
        .transform('vueify')
        .bundle()
        .on('error', function(e) {
            console.error(e.message);
        })
        .pipe(source('app.js'))
        .pipe(buffer())
        .pipe(gulp.dest('www/js'))
        .pipe(livereload())
});

You seem to be missing the css loader https://github.com/vuejs/vueify#usage
Also you won't need that if you include the compiled version (that's the default behaviour when doing import VueMdl form 'vue-mdl')

Thanks. I used import VueMdl from 'vue-mdl/dist/vue-mdl.min'; and now everything works perfectly!

That's weird, I must have messed up the package in some commit. Thanks for reporting it, I will take a deeper look

Hi all,
if i import the vue-mdl like import VueMdl from 'vue-mdl/dist/vue-mdl.min', during compiling with browserify it's all ok. But when i try to use some component i get this error:
Uncaught ReferenceError: componentHandler is not defined
I'm using laravel elixir, and i'm usign vue 1.0.20, could be the problem ?

@Mdpproduction I updated the readme. You need to install MDL

Thanks, i've already installed MDL. But i don't know why, the effetc on textfield, ripple ecc ecc, doesn't works yet. But thanks for the update!!

You need to include both, js and css from MDL. You're missing one of them for sure or you're including them in the wrong order. I'm sure you'll find out the issue in very little time 😉

Works :dancers: thanks again man!!

@Mdpproduction How did you end up solving this issue?

Yep. You need to import mdl.min from dist source.


Modify name of file attached to report-mail

The filename is derived from the model_name which might contain characters like ::, which in turn might confuse bad regexes, terminals when using unescaped etc.
Ideally, this is a configuration option with the default to be the old (file name == model name) pattern.

Actually, works fine. Closing. Feel free to object (for reconsideration).


Livedata support

Fixes #133

This would implemented on top of androidx, should this be backported?

@evant if its not too much trouble, back porting would be great, as I'm using you're excellent library on a project with LiveData but still use the pre-androidx supp lib and had to go back to using Observables instead of Livedata for viewpagers and recyclerviews using this lib. On the other hand if it is a lot of work to backport than its not a big concern as I expect it and other users of the support libs will move to androidx sooner or later.
Main thing is it would be great to get this merged and into a shipped version as at the moment, this blocks me from using the library with LiveData.
Thanks again for all your great work and continuing development of this library!

It wasn't too hard to backport (cherry-picked and fixed up the imports). LiveData should be working in 2.3.0-beta2 and 3.0.0-beta2.


Three bar menu oddly gone in Notes mode

Oddly, when one goes into Notes mode, the three bar menu in the upper left disappears. Rather inconsistent.

Same problem with the bullseye icon, I mean gunsite icon. #409.

Yes, the notes mode is different, and this is intended. It will be clear when it's complete — watch #197.


spawn go ENOENT

When I hit run it gives me this error.
Atom Runner: one.go
Error: spawn go ENOENT
at exports._errnoException (util.js:734:11)
at Process.ChildProcess._handle.onexit (child_process.js:1035:32)
at child_process.js:1127:20
at process._tickCallback (node.js:357:13)

Same thing for me !
Error: spawn python ENOENT
at exports._errnoException (util.js:734:11)
at Process.ChildProcess._handle.onexit (child_process.js:1035:32)
at child_process.js:1127:20
at process._tickCallback (node.js:357:13)

Hey, put #!/usr/bin/python like thing for go, that was the solution

//  thing for go //
(aka interpreter directive, aka shebang line)
https://en.wikipedia.org/wiki/Shebang_(Unix)

An alternative is don't use Atom and use VI with the vim-go plugin :D

The real solution here is to ensure that go is in your environment / path when executing Atom.

@isegal actually go is in my PATH variable an env yet atom-runner doesn't run anything

@thewhitetulip are you sure Atom picked up the PATH? See #23 for background info and the updated README for a FAQ. If you're on OSX and running Atom through the launcher or Dock, note that it may not be picking up your path info.
You can verify what the path is by running the following script in atom-runner:
#!/bin/sh
echo $PATH

I think @thewhitetulip got the wrong Segal, but it's a nice discovery. :)

@isegal  Haha true that :)


add 'static bound to ParVec

This fixes breakage on the latest nightly, though another bug in rustc is going to cause the Travis build to fail.

Any idea what's causing the threadpool thing? I can't repro it.

It's rust-lang/rust#22432.


Bug:I thought this was a voice to text converter. Am I wrong?

What happened?
A bug happened!  Nothing. I did see a message: a bug has occurred
Steps to reproduce

step one...
step two...

What OS are you seeing the problem on?
No response
Relevant log output
options: {
  "path": "C:\\Users\\Barbara\\OneDrive\\Documents\\dad\\BLOGs\\NOTES-SCRATCHPAD\\Vibe1.txt",
  "model_path": "C:\\Users\\Barbara\\AppData\\Local\\github.com.thewh1teagle.vibe\\ggml-medium.bin",
  "lang": "en",
  "verbose": false,
  "n_threads": 4,
  "init_prompt": "",
  "temperature": 0.4,
  "translate": null
}

Caused by:
    audio file doesn't exist

Location:
    core\src\model.rs:25:9
App Version: 1.0.8
Commit Hash: 58d7da09915c34694ba0e8f9bcd4a7856d638ced
Arch: x86_64
Platform: windows
Kernel Version: 10.0.19045
OS: windows
OS Version: 10.0.19045
Models: ggml-medium.bin
Default Model: "C:\\Users\\Barbara\\AppData\\Local\\github.com.thewh1teagle.vibe\\ggml-medium.bin"

CPU Features:
AVX: true
AVX2: true
AVX512: false
AVX512-VBMI: false
AVX512-VNNI: false
FMA: true
F16C: true

@0xAp57xN
Thanks for reporting!
Just to clarify, Vibe is designed for transcribing audio files, not for converting text files to speech. So, unfortunately, you can't add text files as input. 😊


Is there a way to get an element from a JSON without throwing an exception on failure?

For example, say j is an nlohmann::json object. I want to try to get a member called "raw" using the following code, but without throwing an exception if it fails -- exceptions seem to be a time bottleneck in my application.
        p.raw = j.at("raw").get<int>();

Is it possible?

It depends on whether you want to know if it's there or not, or if you want to get a default value if it's not.  If you want to know, use find() first.  If you don't care, use value() which takes a default value.

I doubt that exceptions are really a time bottleneck, but you could use:
if (j.find("raw") != j.end() and j.is_number_integer())
{
  p.raw = j["raw"];
}

Changing the code to this:
      p.raw = j.value("raw",0);

seems to have fixed the problem. Before, the code was taking around 12milliseconds to run when the element wasn't available. Now it takes about 6 microseconds even if the element isn't available. Thanks!


Ty improvement

change map year selection from slider to dropdown or similar to remove ambiguity about data range
try to remove tooltips on countries which have no data which show as NA when hovered over
add country borders in leaflet/shiny map


Cannot see labels when added

They are certainly saved because if I double click again I see them

Hello jcelerier,
it sounds pretty like the issue #47 which was already fixed within the latest release.
If you set label policy to "Show always" then all the labels must appear on the screen.

I cannot make the label alwayss show. Please tell me how to make label always show!

Go to "Default properties" window, then select "Graph" tab on the top and set value of "labels.policy" entry to "Always On". This should help.


Claps Health

Project Abstract

Claps is the mobile app that integrates gaming with personal health tracking can be a fun and engaging way to encourage users to track their health on a daily basis and make healthy lifestyle choices.

Grant [3]
Application Checklist

[x] The application template has been copied and aptly renamed (project_name.md).
[x] I have read the application guidelines.
[x] A BTC, Ethereum (USDC/DAI) or Polkadot/Kusama (aUSD/USDT) address for the payment of the milestones is provided in the application.
[x] The software delivered for this grant will be released under an open-source license specified in the application.
[x] The initial PR contains only one commit (squash and force-push if needed).
[x] The grant will only be announced once the first milestone has been accepted (see the announcement guidelines).
[ ] I prefer the discussion of this application to take place in a private Element/Matrix channel. My username is: @_______:matrix.org (change the homeserver if you use a different one)

 Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.You have signed the CLA already but the status is still pending? Let us recheck it.

Yes, we can remove the DID and NFT modules from our proposal development milestones and instead focus on improving the patient management platform development and adding more details about its architecture and technical details with specification. Additionally, we can leverage existing solutions such as the pallet DID or the Uniques Module if need. We will making some modifications in Claps Health proposal soon. Thank you for the advise!

We've removed DID and NFT from milestone 1 and update all of milestone deliverables 1-4 with more technical details. Add use cases and architecture diagram.  Thank you!

Hi David,
On chain:

User ID (anonymous ID)
Credential (User level, for example aggressive user produce high data quality)
User status (To be verify by system or suspend by user)
Data hash code (if required for some situration)

So there are very limited and anonymous data on-chain.
Off-chain data on AWS S3 or IPFS:
User profile (Gender, Birth)
Health Diary (Result of questionnaire)
Dialog with Chatbot (Specific data by user required)
To answer your questions, it is very limited anonymous data on-chain, and all of health data will be encrypted and secured on AWS S3 or IPFS Cluster (Decentralized Storage), allow user to decrypted(access control), authorize, delete..etc. Compliance with HIPAA & GDPR.
We need to do more investigation to see if Substrate can support Decentralized Storage. IPFS and AWS S3 will be backup solution.
By the way, I've check milestone table, can't find the problem, preview mode seems ok, I've updated, can you please check again? Many Thanks!

This is how the table of milestone shows up for me:

I've edit table and move function list column to the right, please check.
For example: all of the sub functions list are belong to no.1.

Hope it will make much more clear.

Could you clarify what you mentioned above as part of the application? It currently for example doesn’t mention ipfs.
Thanks for the resources, we are interested in Crust Network Storage on Polkadot Substrate. IPFS is an optional service and a future plan for Claps app users who want a more portable solution for their mood tracking data(or Real-word data). However, IPFS is a decentralized public storage solution and may have limitations in terms of accessibility and reliability, industry compliance compared to traditional centralized storage solutions such as AWS S3. So we will not integrate IPFS at this stage.
How is the anti-fraud mechanism going to work (I assume this is part of the substrate module) via twitter or email in an anonymous way?
We are planning to have multiple levels of verification on the Substrate module, such as signing a message and posting it to a social account, email verification, and SMS verification..etc, it can help increase the security of the user registration system and reduce the risk of fraud. (However, it's always possible for fraudsters to find ways to bypass security measures.) SMS depends on the local country service, it will be implemented on the next stage after Claps app product pilot program launch.
There will be user credential verification in an anonymous way (zero-knowledge proof) and “user account quality levels” design to improve anti-fraud mechanism, such as paid account will be level up, some data verified by health practitioners will be level up..etc.(credential by HP)
Could you specify which kind of encryption you are going to use?
We are using Public-key ECIES cryptography to protect the user's data. When users upload their health diary, client side app will help users to perform the AES-256 GCM encryption process when saving the data.
When users share data with health practitioners or pharma on the web backend database, the system uses AES-256 encryption to individually transmit the shared decryption key, and does not disclose the user's public key information to avoid the risk of quantum computers doing brute force cracking.

Thanks for the application @jacobleegithub I have a few initial questions:

I agree that the delivery tables still aren't formatted correctly. Can you get rid of the spaces? You can still make a list but it should be contained in one box. See here for a good example of what the tables should look like.
Are you able to submit any initial mockups/wireframes of the UI? (For the Flutter and Vue front-ends you mentioned). Typically we ask for these for UI focused deliverables.
We usually don't support Solidity development because we aren't experts in the field so it is hard to evaluate. Also in my opinion they don't directly benefit the substrate community. Would you be willing to create ink! smart contracts instead?
As of now, ChatGPT occasionally generates incorrect information. I'm not sure how this would work with risk management within the health systems?
SMS verification is susceptible to man-in-the-middle attacks and in my opinion should be phased out in favor of safer authentication methods.
Why not use existing substrate identity solutions instead of creating your own on-chain verification system?

I agree that the delivery tables still aren't formatted correctly. Can you get rid of the spaces? You can still make a list but it should be contained in one box. See here for a good example of what the tables should look like.

I’ve updated the delivery table, please check.

Are you able to submit any initial mockups/wireframes of the UI? (For the Flutter and Vue front-ends you mentioned). Typically we ask for these for UI focused deliverables.

Yes we are able to submit initial mockups/wireframes of the UI, I will keep you updated in the next 2-3 weeks.

We usually don't support Solidity development because we aren't experts in the field so it is hard to evaluate. Also in my opinion they don't directly benefit the substrate community. Would you be willing to create ink! smart contracts instead?

Yes we are able to code ink! smart contract, it will take some learning curve, it’s fine with us.

As of now, ChatGPT occasionally generates incorrect information. I'm not sure how this would work with risk management within the health systems?

We are using structured indicators or questionnaires with AI only, that can help reduce the risk of providing incorrect information. There is no “free to speak” of AI in this stage.
ChatGPT will not be used to diagnose or treat medical conditions.
Here is an example:
HP design questionnaire for AI and patients:
On a scale of 0 to 3, how often have you been bothered by little interest or pleasure in doing things in the last 2 weeks?
On a scale of 0 to 3, how often have you been feeling down, depressed, or hopeless in the last 2 weeks?
On a scale of 0 to 3, how often have you had trouble falling or staying asleep, or sleeping too much in the last 2 weeks?
Patient answered:
0, 2, 0
ChatGPT respond and report to HP:
Thank you for your response. It is important to monitor your mental health and seek help if you are consistently experiencing symptoms. If your symptoms persist or worsen, it is recommended that you speak with a healthcare professional for further evaluation and treatment options.
HP confirmed message.
Patient received a response.
The idea of AI is to save time for health practitioners, ChatGPT function will be forced input and be monitored output by HP. There is no any personal information to ChatGPT.
In the future development, the AI content will be trained by HP (health education contents provided by HP), it will reduce risk of “google contents learning” for both patients and AI.

SMS verification is susceptible to man-in-the-middle attacks and in my opinion should be phased out in favor of safer authentication methods.

Yes I agree with that. We will find safer authentication methods.

Why not use existing substrate identity solutions instead of creating your own on-chain verification system?

After research of Substrate official website identity related project, we will consider to fork Substrate pallet DID and make it suitable for Claps Health system - both patients  and healthcare service providers.
Others identity project on Substrate website they all have different purpose, it will take too much time and resource for us to try. So pallet DID will be the basic solution for us. Simple is good.

Thanks for the updates @jacobleegithub I appreciate the detailed encryption information and the application looks a lot better now. However I still won't approve the application at this time due to the aforementioned concerns. For example:

I'm not sure that the smart contract modules would be re-used by other projects.
all the various front-end apps would most likely only be useful only for your team and no one else.
Creating a DAO is an endeavor that is not to be taken lightly. Have you looked at any of the DAO tooling already available in the ecosystem? I'm not sure that this should be condensed into one milestone.
I don't know how a DAO would work regarding all the legal complexities that come with healthcare systems. You would likely have to deal with laws in every country the app is operated in.
I agree that the last milestone essentially only benefits your app and isn't useful to the ecosystem.

In my opinion it also seems pretty ambitious to combine AI tech and a DAO into a survey app. Basically, I'm not convinced that this product would actually be used by healthcare companies.

First of all, many thanks for great advice, make us introspection Claps Health project.

I'm not sure that the smart contract modules would be re-used by other projects.
all the various front-end apps would most likely only be useful only for your team and no one else.

Healthcare market is huge, it may not develop smart contract and can be re-use by others project, but it may re-use in healthcare industry, for example:
Personal Health Records: A smart contract that can securely and manage patient health records and allow authorized access to medical professionals. (On chain data are very few but only trust DID list, informed consent, credential(zero-knowledge proof), data hash proof and times stamp..etc)
Clinical Trials Management: A smart contract that can manage the administration of clinical trials, including patient recruitment, randomization, and data management. Connected to regulation & compliance protocols)
Drug Development: A smart contract that can track the progress of new drug development, from research and development to FDA approval. Such as IP sharing, Research & Publication..etc)
Medical Claims Processing: A smart contract that can automate the claims processing process, reducing administrative costs and improving the accuracy of payments.
Health Insurance: A smart contract that can manage the administration of health insurance plans, including claims processing, enrollment, and premium payments.
Patient Incentive Programs: A smart contract that can manage rewards programs for patients who participate in health and wellness programs, track their progress, and reward them for their efforts.
But develop such can widely use health protocols is very difficult, the whole system is now controlled by hospitals, government and pharma companies. There is no way to simply empower patients and get start with web3 based portable health records for every individual.
So Claps Health will be focused on last one, Patient Incentive Programs and Omni-Channels. I believe Patient Incentive Programs can be developed by smart contract and re-use in other utilities. For example the patient groups in every country can just re-use these smart contract to connected with patient in digital way, engage with others local resources and support program. Claps Health Incentive Programs for mental health can not cover all, they can just fork Health Incentive Programs to Oncology patients and others.
The front-end mobile app is for Claps Mental Health Patients, but Backend with Substrate nodes  will be Clients like Phama, Nutrition, Bio company..etc. (I will explain why pharma will be join soon)

Creating a DAO is an endeavor that is not to be taken lightly. Have you looked at any of the DAO tooling already available in the ecosystem? I'm not sure that this should be condensed into one milestone.

We will reconsider removing DAO from milestone deliverables but keep it in Claps Health system. It’s because the Claps DAO functions as a controller(multi-signature) with other Claps Dapps. It’s not like DAO for community governance/voting/secure fund…etc, it’ not  like others defi project.

I don't know how a DAO would work regarding all the legal complexities that come with healthcare systems. You would likely have to deal with laws in every country the app is operated in.

Good question! Clap DAO is a safeguard for other smart contracts. It won’t touch any health records or personal information or even funds. It is part of system security. To landing the local country should be a healthcare service company but not DAO.
I will discuss with team and add more details of Claps DAO function in this proposal.

I agree that the last milestone essentially only benefits your app and isn't useful to the ecosystem.

I will discuss with team and see how we can do. We are sturdy and evaluate with KILT, DOCK and others Substrate DID projects.
To expand Substrate and widely use by healthcare business is hard. I believe Omini-Channels will be the key.
What I mean is we have confident to prove Claps Health Substrate will be use by pharma companies and others. And it can benefit to Substrate ecosystem in middle term.
The new evidence show they are using “WeChat, Line..etc” to manage HP and Patients on their Omni-Channels strategy, The use of messaging apps in the healthcare industry has grown due to strong market demand and the lack of a dedicated secure platform for healthcare communication. and there is an increasing demand for secure and compliant platforms in the healthcare industry. Claps Health Substrate will be the good solution for them.

In my opinion it also seems pretty ambitious to combine AI tech and a DAO into a survey app. Basically, I'm not convinced that this product would actually be used by healthcare companies.

Omini-Channel to mange HP and Patients will be the key to this business. But before that, we need patients. Until we have Claps Health patient group, they won’t talk with us.
I will do some modification about role of AI and DAO in this proposal. Try not to miss leading the core of Claps Health, at least in short to middle term. Thanks for advise.

Thanks for the update. The application looks better now, and I will mark it as ready for review. However, I personally still have some concerns about it.

First, your application currently doesn’t contain anything regarding zero-knowledge proofs. Directly using Twitter or email verification makes it probably very easy to extra personal data, even if you use a different address for the on-chain verification and the health-related data.

Thanks for advice,  we will add zero-knowledge proofs to this proposal and explain how it works with a patient's anonymous ID with verifiable credentials issued by others and it can’t not be traced or connected with the patient's personal info.
Patients will need zero-knowledge proofs of their on-chain ID. We will add it into the proposal.
The alternative way is to use KILT or Dock or other DID solutions. But Claps DID require both individual and business multi ID environments. So we may decide to fork the pallet project and add more functions on it.

Also, this on-chain data can not be deleted (GDPR).

Yes, on-chain data can not be deleted but there is only a public key type of random ID, in the smart contract of ID, there is only hash code, credential with timestamp. When a user chooses to delete personal data, it will delete related data on AWS S3. There is no personal data on-chain.
The on-chain ID can’t be recovered and traced to any person. If this can’t be applied with GDPR, I will say others DID can not too.
Our team already work with ISO27001/ISO27701 PIMS certificated association(TRPMA), we will ask a compliance officer to support this project, make sure we are on the right track.
We will add more data to this proposal about HIPAA/GDPR.

Additionally, some of the deliveries, but especially the last milestone, seems currently to be unrelated to the polkadot ecosystem, and its current form could be implemented for any kind of project.

Thanks for reminding, we will do some modifications with the last milestone.
But please understand that the healthcare market is huge, if we can expand Substrate nodes to healthcare business to the industry, it will be another huge Substrate ecosystem. It also can benefit Polkadot in healthcare industry. And the strategy will be no doubt - patient group and omni-channels, start with Claps Mental Health Substrate.

Dear committee members,
Thank you for considering our proposal for the Claps Health mood tracking app. We understand your concerns regarding the reusability of our smart contract modules, the limited usefulness of the front-end apps, the issues of creating a DAO, and the legal complexities of operating a healthcare system.
In response to your concerns, we have made several changes to our proposal to address these issues and make the Claps Health app a more valuable addition to the ecosystem. We have added Zero-knowledge proof for patient privacy protection, replaced the Claps DAO with a data sharing protocol that can be re-used by other projects, and replaced the web backend design with an omnichannel-ready platform design that we believe will be useful for other industries as well.
Our updated proposal includes an overview that moves the AI from the patient to health practitioners, an updated architecture that includes IPFS swarm for health education content storage and the Claps Health Data Sharing Protocol, a solution that includes a health practitioners AI assistant and omnichannel capabilities, technology that includes Substrate blockchain, SSI, and Zero-knowledge proof for enhanced privacy protection, and milestone deliverables that include Enterprise Registration and the Data Sharing Protocol. Additionally, we have added regulation and compliance with HIPAA/GDPR to ensure that our app is fully compliant with all relevant laws and regulations.
We hope that these changes demonstrate our commitment to making Claps Health a valuable addition to the Substrate ecosystem and we look forward to the opportunity to bring this app to the market. Thank you for your consideration.
P.S. Basic UI to be add by 1-2 weeks. thanks!
Sincerely,
Jacob

While this application contains some interesting ideas, I cannot support it for the following reasons:

It is very sparse on technical details (re zk proofs, end to end encryption plus a data sharing protocol on Substrate, and other things) while containing a ton of very complex topics,
it uses imprecise or incorrect wording in several places (the "pallet" deliverables are specified as "backends" using smart contracts), and
I am skeptical that individuals and companies are willing to put their private and business data on-chain, encrypted or not,
team has no apparent experience writing and maintaining open source software.

While this application contains some interesting ideas, I cannot support it for the following reasons:

It is very sparse on technical details (re zk proofs, end to end encryption plus a data sharing protocol on Substrate, and other things) while containing a ton of very complex topics,
it uses imprecise or incorrect wording in several places (the "pallet" deliverables are specified as "backends" using smart contracts), and
I am skeptical that individuals and companies are willing to put their private and business data on-chain, encrypted or not,
team has no apparent experience writing and maintaining open source software.

Thank you for your feedback. I understand your concerns, and I agree that zk proofs and other technical details require more in-depth discussion, to make it clear in each one may require many proposals. However, I would like to clarify that this proposal is focused on healthcare applications, and it is based on our experience with blockchain technology from previous projects.
We are interested in Substrate and are hoping to learn and leverage the new technology on Polkadot Substrate. We understand the pallet project they mentioned in they proposal is for DID learning purposes only and not intended for business. At milestones, The backend is a web backend for healthcare businesses, and it will require both individual and multi-user organization decentralized identifiers (DIDs). The user interface will also require a backend to interact with DID smart contracts. I have made some changes to the milestone to hopefully make this clearer.
We believe in the potential of healthcare on Web3, and we have executed many projects in the past few years based on Web3 technology. We have found that both individuals and businesses are looking for secure and useful applications.  Our important data is currently stored on AWS S3 for security reasons. To address your concerns, I would like to clarify that we do not put any data on chain, and we understand the importance of maintaining privacy and security when it comes to sensitive healthcare information.
As for our experience and qualifications, all of our experience is on Gitlab, but we are looking forward to moving to Github.
Anyway, thank you for your feedback, I hope I can provide a UI soon to demonstrate Claps Health potential.

@Noc2
Thank for advise. About “How can an ink! smart contract be part of a substrate module?”
No, it’s separate!
When I define the second column with “Deliverable”, at “Patient registration module”, it’s containing “Substrate API & Dapps”. Let me fix this by using a separate Row. The first Row is for Substrate Rust, the second Row by ink! Smart contract. So it will not mixed together.
Our solution is using a hybrid model, with anonymous on-chain ID and zero-knowledge proofs served by ink! smart contracts and personal profile data managed off-chain through Substrate APIs. This can help ensure the privacy and security of patient data, while still enabling efficient and secure access to healthcare services.
We can start working on details of technical specifications and provide POC on the main Github of Claps Health Official Account.
In the meantime, about spec of milestone 1 - Patients & Healthcare business registration, here is more details explanation for your reference.
For example, we can separate Patient data by:
Anonymous On-chain ID & zk Proof service
Personal profile data manage at off-chain world
The On-chain ID & zk Proof will be served by pure dapp, developed by ink! Smart contract.
Personal profile data will be managed off-chain using Substrate API (written in Rust). For example, the profile data will be stored on AWS S3 and encrypted by the ID holder (patient). The ID holder will hash the profile data and store the resulting hash code on the blockchain along with their ID. Let's jump over this part of profile management.
Here is sequence diagram:
Role play:
Claps Health (Issuer): An actor who makes a claim.
Claps Health Patient (ID Holder): An actor who receives a claim.
Healthcare Service Provider (Verifier): An actor who verifies if the content of a claim is issued by a specific identity and held by another specific identity.
Credential: Data that is needed to prove that a claim is issued by a specific identity and held by another specific identity. This data is composed of a claim and a proof.
Sequence flow:
(The process by client side)

ID Holder generate random ID (BIP39)

(The process with no zk-proof, credential issue by Claps Health trust party)

ID Holder call Substrate API Issuer to makes a claim
Substrate Issuer validate ID Holder and claim credential through dapp

(The process with zk-proof, on-chain)

Verifier challenge ID Holder
ID Holder answer challenge by credential
Verifier verified, allow ID Holder use the service

Our experience is based on EVM and Ethereum Parity, so please correct me if I am wrong.
Substrate = Node = Blockchain SDK, can be customized by developing Rust language (Function as Substrate API).
ink! Smart Contract = Solidity, we can porting EVM smart contract by re-coding smart contract on ink! Deployed on Substrate virtual machine.
That’s why Claps Health Registration Module contains “Developed by Substrate Rust”, and some function list is developed by “ink! Smart Contract”. I will make it with two rows.

Claps Health will provide the following deliverables by March 8:

Basic wireframes for the Claps Health app/web interface.
A POC demo code for the Claps Health data sharing smart contract on Github.
A demo code for the Claps Health AES-256 ECM for health data encryption/decryption on Github.
p.s. The smart contract will initially be based on Solidity and will be ported to !ink as per the official roadmap schedule.

Regarding BIP39, are you aware of https://github.com/paritytech/substrate-bip39 and https://wiki.polkadot.network/docs/learn-accounts#mnemonic-and-address-generation

The Polkadot wiki page on mnemonic and address generation based on the BIP39 provides very good information on how mnemonic phrases can be used to generate a private key and address for a Polkadot account. Yes, we will double check that the algorithm is the same for user’s wallet generated, many thanks for the info.

It would be more useful if you support the polkadot.js extension and polkadot native solutions rather than metamask. I’m not sure you can use metamask to interact with the ink! Smart contracts at this stage.

Definitely need to leverage polkadot.js but not Metamask in this stage. We know there is a limitation of Metamask to support polkadot ecosystem. And it’s pretty fine for us. We prefer to provide a one stop and all-in-one user experience but not rely on third party plug-in like MetaMask. Specially for patients and healthcare industry clients. In mobile devices and web backend.

What kind of Zero-Knowledge Proofs are you going to implement exactly?
As of now, we prefer uses zkSNARKs Groth16, it is “non-interactive” and efficient for verification of Claps Health users. We will add this into tech spec in the next version of the proposal with UI update.

How will the linking to Polkadot Name System work? Are you going to use XCM for it?

Using XCM to connect with the Polkadot Name System with parachain on the Substrate for the name service is a good solution for business clients, the main reason is we are offering a dedicated smart contract for enterprise (Replace smart contract address with meaningful name).  Yes we will use XCM for the future development, since all of Claps Health services are on the Substrate, it's not urgent at this stage. And XCM looks like a good solution for future compatibility.

Feel free to ping me once you integrate the initial mockups/designs.

Yes I will. Many thanks.

@Noc2
Dear Committee Members,
We developed a Personal Health Records system based on Ethereum Parity technology and implemented a pilot program in the Medical Center in 2017. The system provided patient-owned and portable health records for the continued care of patients.
In 2023, my digital health team at the Taiwan Research-based Biopharmaceutical Manufacturers Association is committed to building an easy-to-use mobile app to support patients' lifestyle. This is also inspired by Pharma companies, the demand for AI and omni-channel solutions is strong, and more pharmaceutical companies and healthcare service providers are engaging in digital transformation strategies.
Unfortunately, healthcare service providers are currently relying on social media platforms and unsecured messaging tools. Our market approach is to start with the patient and provide an easy-to-manage lifestyle support on a secure mobile app. We aim to provide real-time data sharing, health education, and communication tools on the Polkadot Substrate for healthcare businesses.
The frontend application may be very specific for Claps Health, the core concept of data sharing and content publishing on the Polkadot web3 ecosystem can be applied to various industries and use cases beyond healthcare.
We have included basic UI in the Claps Health Proposal, which can be found here and here. Additionally, we have provided proof of concept for health data sharing through smart contract code on Claps Health Github Account here.
We are looking for resources to support this project and help us build it up on the Polkadot ecosystem based on Substrate technology, enabling patients to easily record and manage their real-world data and find resources for lifestyle support.
We hope you can see the potential of Claps Health as a simple and useful solution for citizens.
With best regards,
Jacob

Please reload Figma link if you see only one page, I've put all ui on the same page.

@Noc2
Thank you for your feedback and for sharing the proposal with the rest of the team. We understand that some committee members might not be willing to give a level 3 grant immediately, and we are open to applying for a level 2 grant initially and potentially seeking a follow-up grant in the future. We appreciate your consideration and look forward to the next steps.
@randombishop
Thank you for your feedback and for expressing interest in the project. We understand that there are multiple challenges involved in the proposal, and we are willing to simplify the scope and reduce the first iteration to a level 2 grant. We appreciate your support and look forward to building the app.
@keeganquigley
Thank you for your feedback and for evaluating the proposal. We are willing to reduce the scope and cost for some of the milestones and remove the costs for art design, as we understand that the focus should be on software development. We will condense the proposal down to 3 milestones and adjust the delivery tables to match the template. We appreciate your consideration and look forward to the next steps.
Next step, I will reference with standard template and discuss with engineering team and revise the table of milestone in next two days.
Many Thanks!

Phase I - Minimum Viable Product (MVP) Development: (This proposal)
Patient registration
Fixed challenge card
Decentralized applications (dApps)
Health data sharing protocol
Incentive program for patients
Phase II - Full-featured Application Development: (Future Plan)
Enterprise registration
Dynamic challenge card
Health practitioner engagement
Patient groups
Health education content management
Omni-channel backend
Health data analysis backend
Note that the original roadmap has been modified from 4 milestones to 2 milestones for Phase I, as we prioritize the development of the MVP to provide the core functionality of our product as soon as possible.

We are appreciate committee members's no-stop review and support, and thank you for sharing the great news! I'm thrilled to hear that the Claps Health proposal has been approved by the Web3 Foundation committee members. I'm excited to continue working on the Claps Health project and make a positive impact in the healthcare sector and Polkadot ecosystem.
Many Thanks!
With best regards,
Jacob Lee

Hi @jacobleegithub are you able to provide an update on Milestone 1?

Hi @jacobleegithub are you able to provide an update on Milestone 1?

Dear @keeganquigley
Claps Health Progress Report
Date: Aug 13, 2023, Jacob Lee

1. Executive Summary:
Thank you for supporting Claps Health and granting us the opportunity to bring this vision to life. Since initiating the project in April 2023 (approved by middle of March), we've faced unforeseen challenges in the Rust and Substrate Technology learning curve, especially transitioning from a Solidity-based engineer. While we've onboarded experienced Substrate professionals to address this, the Item 3 related to zk-proof still to be develop.
We've achieved about 80% of the functionality in the mobile app frontend, and its progress now rely on Substrate / dapps development to catch thee timeline. And the major challenge is zk-proof.
We deeply regret the delay and sincerely hope for W3F's continued understanding and support. We're committed to navigating through these challenges and delivering on our promises.
Please reference the demo video in here:
https://youtu.be/naMzUGk9lQo
or you can download apk and install on Android phone here:
https://drive.google.com/file/d/11kxSy50M1YchAV8zD5kHuGJedQ5TZt6c/view?usp=sharing
Please find the detailed progress report attached for more insights.

We have made significant progress towards Milestone 1, with delays in items in below:

Number
Deliverable
Progress

0a.
License
Yes

0b.
Documentation
80%

0c.
Testing and Testing Guide
0%

0d.
Docker
0%

0e.
Article
0%

1.
Patient ID creation
100%

2.
Patient profile management module
100%

3.
Patient ID on-chain authentication
0%

4.
Challenge card dapp module
0%

5.
Create database
80%

6.
Database encryption module
0%

7.
Android apk
Please reference download link

8.
Testing
40%

2. Milestones Overview:

Milestone 1: Patient Identity and Security Framework

Status: Delayed due to zk-proof
Estimated Completion Date: Oct 2023

Milestone 2: Patient Engagement and Data Sharing

Status: Delayed due to Milestone 1
Estimated Completion Date: Dec 2023

3. Challenges and Delays:
The Milestone 1, Item 3 - "Patient ID on-chain authentication" (specifically, zkSNARKs Groth16 based on Non-Interactive Zero-Knowledge Proof) is still under research. We are considering the use of Pallet or XCM to implement this function. Alternatively, we're exploring the possibility of using third-party zk-proof on Substrate, if available.

4. Support Required:

Guidance on implementing zk-proof on Substrate if possiable.
Introduction to potential partners of zk-proof if possiable.
Introduction to Substrate developer/engineer if possiable (will share with grant).

5. Conclusion and Forward Look:

Conclusion:

As of August 13, 2023, Claps Health has made significant strides in multiple areas, with the most notable progress in the creation of the Patient ID and the management module, both achieving a completion rate of 100%. However, the adoption and integration of zkSNARKs Groth16 for "Patient ID on-chain authentication" remain a prominent challenge, causing delays in the overall development trajectory.
While the mobile app's frontend boasts 80% functionality completion, its full operation hinges on the advancement of the Substrate / dapps component, particularly the integration of zk-proof. These challenges have, in turn, led to a rescheduling of the estimated completion dates for Milestone 1 and 2 to October and December 2023, respectively.
The team's commitment remains unwavering. We're tirelessly seeking solutions, considering various approaches, including leveraging Pallet, XCM, or third-party zk-proof on Substrate. However, guidance, particularly in zk-proof implementation, and introductions to potential partners for real-world data utilization, would greatly accelerate our progress.
We appreciate the patience, understanding, and continued support of the W3F and remain dedicated to turning the Claps Health vision into a reality.

Thanks for the detailed update @jacobleegithub much appreciated. No worries, we understand that delays and challenges can occur during development; this is normal. We just want to make sure it keeps being worked on.
If you aren't planning on submitting the delivery in the next four weeks or so, I'd recommend submitting an amendment to extend the timeline. If you want to wait a couple weeks before submitting to better measure things, that's fine. Thanks!

Hi @jacobleegithub still planning on submitting an amendment?

Dear @keeganquigley , Should I open a new pull request with new timeline of milestone delivery?
Yes and I will submit an amendment in next 2 days.
Many Thanks!
Jacob

Hi @jacobleegithub still planning on submitting an amendment?

Dear @keeganquigley , Should I open a new pull request with new timeline of milestone delivery?
Yes and I will submit an amendment in next 2 days.
Many Thanks!
Jacob

@jacobleegithub yep exactly, that's perfect. Thank you!

Hi @jacobleegithub are you still planning to submit this? Thanks!

Hi @jacobleegithub please note that if we don't hear from you or see an amendment in the next two weeks, the committee will go ahead and file an amendment to close the grant due to inactivity. Thank you.

@keeganquigley
Hi Web3 Foundation committee members,
First and foremost, I would like to express my deep appreciation for your continued patience and support throughout our project's journey. The Web3 Foundation's commitment to fostering innovation and collaboration in the blockchain space has always been an inspiration to us.
I sincerely apologize for the delays we've experienced and for not being able to meet the milestones as originally planned. As we communicated in our last update, we encountered unforeseen technical challenges, and unfortunately, constraints in engineering resources have further exacerbated the situation.
We understand the importance of accountability and transparency, especially when it comes to community and grant-driven projects. As such, if the committee feels it's in the best interest to close the grant due to our inability to meet the commitments timely, we accept that decision. While we are deeply saddened by the circumstances, we remain committed to the blockchain space and hope for opportunities to collaborate in the future.
Thank you for your understanding, and we are truly grateful for the opportunity you provided us.
With best regards,
Jacob Lee

Thanks @jacobleegithub for the sentiments.
I completely understand that times are hard for everyone at the moment. I appreciate the update and thank you for your efforts and work thus far. In this case, it's probably best to go ahead and close the grant for now, and you can potentially pick it back up in the future should you choose to continue to work on it. I will go ahead and file the PR.


pass getEvent completion handler through

Current coverage is 98.09% (diff: 100%)

Merging #116 into master will decrease coverage by <.01%

@@             master       #116   diff @@
==========================================
  Files            31         31
  Lines          1259       1258     -1
  Methods           0          0
  Messages          0          0
  Branches          0          0
==========================================
- Hits           1235       1234     -1
  Misses           24         24
  Partials          0          0

Powered by Codecov. Last update 3bea4b0...21a1529


[CS] Correctly handle compound-applied functions with property wrappers

Avoid wrapping parameters in the function reference for compound applies, and make sure we consult the parameter label in the compound name if it's present to determine whether to match using the projected value or not. This matches the existing logic in unwrapPropertyWrapperParameterTypes.
While here, factor out Expr::getNameLoc, which enables solver-based cursor info for UnresolvedMemberExprs, which was previously missed.
Resolves #77823
Resolves #77981
rdar://140503460

@swift-ci please test

@swift-ci please test source compatibility


[flutter_tools] Launch DevTools with 'v'

Description
Launch DevTools from the resident runner with 'v' when there is a vm service available.
Related Issues
https://github.com/flutter/flutter/issues/41407
Tests
I added the following tests:
I updated tests of the command help.
Breaking Change
Did any tests fail when you ran them? Please read [Handling breaking changes].

[x] No, no existing tests failed, so this is not a breaking change.

/cc @jonahwilliams for thoughts on testing. One option would be to wrap the devtools_server methods in an inject-able class, and then verify in existing tests that the methods are called when a mock is injected. wdyt?

This is great.
It would be nice to display a link to this URL in the console rather than
"An Observatory debugger and profiler on iPhone 11 Pro Max is available at:
http://<IP_ADDRESS>:56450/asdfasdfw=/"
We could provide a link from DevTools to the observatory as an affordance for advanced users who need functionality not yet in DevTools.


add country-code example

see ... and split into languages..

Split configs, one for each example


Mobile version not working

It appears the mobile version (0.11.8) of this plugin is not working for me. As soon as I click "Refresh Index", I got following error logs in developer tool's console. I set up a test vault with only two notes in it (one as parent and the other as child) and I got the same result. The desktop version works well so I hope the same for mobile version because I have the same vault synced on both platforms.
TypeError: Cannot read property 'types' of undefined
    at eval (eval at <anonymous> (app.js:1), <anonymous>:6408:46)
    at Array.forEach (<anonymous>)
    at getFieldValues (eval at <anonymous> (app.js:1), <anonymous>:6404:23)
    at eval (eval at <anonymous> (app.js:1), <anonymous>:6493:47)
    at Array.forEach (<anonymous>)
    at eval (eval at <anonymous> (app.js:1), <anonymous>:6492:34)
    at Array.forEach (<anonymous>)
    at eval (eval at <anonymous> (app.js:1), <anonymous>:6491:28)
    at Array.forEach (<anonymous>)
    at eval (eval at <anonymous> (app.js:1), <anonymous>:6486:25)

Did another test with version 0.10.75 on mobile (Android) and it's working so I guess it stops working somewhere between 0.10.75 and 0.11.8. Just FYI

Thank you @joellti :)
Indeed, the versions between those two were all filled with bugs! There was a change in the way Dataview returns data, so I had to account for that

No problem, if you need me to collect any additional data feel free to let me know :)

Thanks alot @joellti  :)
I've been working on a whooole bunch of changes in a new beta release.
It would be great to hear your experience if you're willing to try it!
You'll have to manually install from here. You can read the changelog for this branch over here

Yes I tried 1.1.1 yesterday and unfortunately it's still not working on mobile. I didn't capture the console logs this time but the behavior is the same as with 0.11.8.


Tried to initialize ... - disable on production

Hello,

Tried to initialize reveal on an element that already has a Foundation plugin.

This should be able to disable in production mode.
For example:
var webpack = require('webpack')
module.exports = {
  // ...
  plugins: [
    // ...
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: '"production"'
      }
    })
  ]
}

Hi @drozdzynski,
I do not understand. Are you replying to an other issue ?

Even more webpack crap I have to fix with overrides in JSPM 🙈

These warnings are implemented using console.warn; if you wish to disable console warn in production, there are ample mechanisms for doing so (see http://stackoverflow.com/questions/1215392/how-to-quickly-and-conveniently-disable-all-console-log-statements-in-my-code)
Going to close this as wontfix, as at this time I'm pretty confident we should still be warning on usage that can result in unexpected/broken behavior, but if anyone wants to make a proposal for a more pluggable/customizable warning/error system within Foundation we might be interested.


update to fix issues with latest Sublime Linter

I noticed this wasn't working for me. this is a bare-bones fix to make it work.

This fix works for me. Can we get this request merged?


Fix: Avoid completed event when outside image

Please check if the PR fulfills these requirements

[ ] The commit message follows our guidelines
[ ] Tests for the changes have been added (for bug fixes / features)
[ ] Docs have been added / updated (for bug fixes / features)

What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)

What is the current behavior? (You can also link to an open issue here)

What is the new behavior (if this is a feature change)?

Does this PR introduce a breaking change? (What changes might users need to make in their application due to this PR?)

Other information:

:tada: This PR is included in version 4.16.1 :tada:
The release is available on:

npm package (@latest dist-tag)
GitHub release

Your semantic-release bot :package::rocket:


Add support for Ragel

Ragel is a code generator that would be nice for automatically generating state machines. See RazrFalcon/rustybuzz#77 for context.
Unfortunately Ragel doesn't provide a binary release; it only has a source release by default. I'm trying to fix this, but until the author gets back to me I don't think there is a good way to integrate it into here.

cc https://github.com/adrian-thurston/ragel/issues/100

Why not use nix? https://github.com/cachix/install-nix-action
https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/tools/parsing/ragel/default.nix

it seems that https://github.com/adrian-thurston/colm/pull/156 has been closed. So, I will close this for now, but feel free to reopen the issue or open a PR if the upstream situation has improved.