Can't refine tuple union

First of all I apologize if the issue title is misleading, I don't know how else to put it.
The following is a minimal case of what I'd expect to work. Surprisingly (at least for me), it doesn't type check.
Tested with Flow 0.32
/* @flow */

type Foo = [string, string];
type Bar = [string, number];

type FooBar = Foo | Bar;

const x: FooBar = ["a", 2];
const y: Bar = x;

even adding type casting or explicit checks to typeof x[1] doesn't make the code type check

Here is a more extensive demo, showing that it doesn't work if the to-be-refined type is

an array, it only seems to work with objects (Redux specific? 😜 )
refined based on a typeof check, it only goes as far as refining when a literal is matched

https://flowtype.org/try/#0PQKgBAAgZgNg9gdzCYAoVxhgOpwE4DWAzgDRhwBGAVgKYDGALmAgJYMAWYRDeLAdgHMwMNjTwBDGGAZwwfcXjyIwAE0R8wdcURqoGATwAONMADE4cAExgAvGADeYAF5i4ALjAByKBc9k4fDQefACuALYUYmAAvgDcekYmAEIK1naOLkoenhQKfuSBHty8gjHxCcZmFil4aVVWYAA+YDWW5XQB3NLiBDRE5nCttmAAFAAeHgOtAJS2AHwOqGBgLFCjYwB0mbI2u14+cJ6z9kvLmp1M+pMWdWPxy9GojxhYACJwfXJwTAj4BP7Ueg-NicAyVGRyBRKJBqBAaLQ6ComAYAZmGGVcRR4-AE-kKcnCkTwZSRLQUaPSzkxBIiYjxQS42NKcXQYOR1XJw1RTTJeBR7Qu3V6-Q5fOG42ug3JsxsCxOy1WozZcDWm22tj2nmKOKOizO5z4XSu9QpYDup0ez0wYHenz432YfzIUPE+mYIMZJSEIgYYkk0lk8kUylh8O0ujZ9QALMMANreXxkUK0vAAXXikZqMbs8dyeHy2sE6dZiXqWa5FhjzSzAsNTAYPT6UwU2fWkqzMrlp0V41jAAZUxq7AnDsdTssOnWwMaBq3zQ8nqggA

related to #4556


files extension from turbowarp open a file as block fills up whole screen instead of just the project frame

Expected Behavior
fill the project screen
Actual Behavior
fills the whole editor page instead
Steps to Reproduce
add a new extension and search up files and add it
run the "open a file as text" block
Operating System and Browser
windows 11 microsoft edge

this is most definitely intended, as the files extension is meant to put the popup at the center of the page, not the center of the stage

but it doesnt do that in normal turbowarp though

either way it most definitely is intended to be center of page on pm


Organisation user cannot unsubscribe, return "Not Found"

Right now if trying to unsubscribe an organisation user, the page will show below "Not Found" error.

On and Off both working


[Question] alternative approaches of parameter estimation

Summary of question
We use hyperparameter optimization with Optuna to estimate ODE parameter values with the number of cases.
To improve accuracy and speed, is it possible to develop the following idea?
We know the number of days and initial/final values of the number of cases in each phase,  but we do not know parameter values.

set tau value suggested by Optuna
create a dataset of parameters with random values
solve initial value problems of ODEs using this parameter dataset
learn the relationship of final values calculated by the previous step (X) and parameter values (y)
estimate parameter values with the known (actual) final values
repeat to determine tau and parameter values

It's just an idea, but could be a starting point of discussion to improve our approach. This is related to #698.

In step 4, what method would be used to learn the relationship of X and y? And could you explain step 5 with more detail? For step 5, are you pointing on training a model that could learn from the known actual final values and X?

For step 4 and 5, I considered to use regression models to learn the relationship of X and y. Then, regard the actual final values as X_target, and estimate y_target with the regression models. Yes, it may be too much to apply machine larning for this purpose.

Updated my first idea.
For step 2-5 above, scipy.optimize.minimize could be used. Scipy estimate ODE parameter values and Optuna estimate tau value for the scenario.
When I created Estimator, I selected only Optuna, not Scipy, for parameter estimation because I did not have ideas to calculate initial guesses of kappa and theta. As I said in #698 and #711, initial guesses of kappa and theta can be "(dF/dt)/Infected" and 0 respectively.
I will create an experimental class for that this weekend to try this idea.

I tried scipy.optimize.minimize to minimize RMSLE score with optimizing parameter values, but parameter search did not end. I will try the following approach at this time with a new class.

Optimize tau value with all phases using initial guess of parameters, using Optuna.
Optuna optimize ODE parameters with selected tau value, (10%, 90%) quantiles of initial guess.

With #724, added experimental methods to ODEHandler class. .estimate() calls the following methods internally.

ODEHandler.estimate_tau(): Select tau value [min] which minimize the score of the metric. ODE parameter for each tau value will be guessed by .guess() classmethod of the model (cs.SIR, cs.SIRD, cs.SIRF).
ODEHnadler.estimate_params():  Estimate ODE parameter values of the all phases to minimize the score of the metric, using optuna.

To speed up the process, do you still begin with a range between 0 and 1 for kappa and theta? What happens if you narrow down that range to (0, 0.5) for example? And is it an option to run less trials? For example by checking if RMSLE did not decrease after n trials

The value range of kappa was updated from (0,1) to the range of (0.1, 0.9) quantiles of (dF/dt) / I with #711 and #698. Please refer to covsirphy.SIRF.param_range() (called by covsirphy.ode.param_range_estimator._ParamEstimator(),__init__ and covsirphy.SIRF.guess()`).
The value range of theta is still (0, 1). Yes, we should be narrow down it for speed. Theta is near to 0, but how can we decide the range logically? Sorrry, the exact value range cannot be controlled by users at this time.
Options to run less trials are listed in the docstring of ODEHandler.estimate_params().

timeout (int): timeout of optimization
timeout_iteration (int): timeout of one iteration
tail_n (int): the number of iterations to decide whether score did not change for the last iterations

We controll the number of trials with timeout.

Just to have a clarified updated overview of this, can you describe the new call tree of the Scenario.estimate()? To see how the ODE solver works now and how the parameters and tau are now calculated and in what order. Because I got a little confused. Now is tau calculated first instead of last? Shouldn't all the 4 parameters be optimized at the same time? Can we optimize independently only one since we do not know the others yet?

Also if I understand correctly, currently we assume that theta is fixed 0, not leniently around 0. But the purpose of SIRF (and on the contrary to the SIRD) was to capture such direct deaths and it is very possible these deaths to have been existed or to continue to exist. So we can't totally assume beforehand that theta is always 0. It is okay to use this approximation for calculating kappa's range, but in the .guess() it is wrong to set theta always to 0. We could limit down theta values somehow, close to 0 (but not fixed 0).
But in the first place, I don't know if we should use the approximation "theta is 0" for kappa's formula at all. I know that it is convenient for extracting kappa formula but then we have to use 0 as theta value which is wrong as I explained and here is the dilemma.
These direct deaths mean that they happened too fast and these people while being sick didn't participate in the I compartment, which means that they didn't infect others. This scenario/case seems probable and thus we cannot set theta to 0 as a general rule. Is .guess() used in the current version or is experimental?

Currently, call trees of Scenario.estimate() and Scenario.simulate() are not updated. Please check & update the new strategy with the new experimental class ode.ode_handler.ODEHandler.
With #729, I updated the codes for fixing some bugs. This does not change the strategy, but please use version 2.19.1-beta-fu1.
import covsirphy as cs
cs.__version__
# Data
data_loader = cs.DataLoader()
jhu_data = data_loader.jhu()
population_data = data_loader.population()
country = "Italy"
records_df = jhu_data.records(country, population=population_data.value(country))[0]
# Get change points
trend_detector = cs.TrendDetector(records_df)
_, end_dates = trend_detector.sr().dates()
# Set-up handler
first_date = records_df.Date.min()
handler = cs.ODEHandler(cs.SIRF, first_date)
handler.add(end_dates[0], y0_dict=records_df.iloc[0].to_dict())
_ = [handler.add(date) for date in end_dates[1:]]
# Estimate tau and parameter values
tau, info_dict = handler.estimate(records_df)

ODEHandler.estimate() calls the following methods internally.

ODEHandler.estimate_tau(): Select tau value [min] which minimize the total score of all phases. Theta/kappa/sigma/rho set for each tau value will be guessed by .guess() classmethod of the model (cs.SIR, cs.SIRD, cs.SIRF).
ODEHnadler.estimate_params():  Estimate theta/kappa/sigma/rho value set to minimize the score of each phase, using optuna and fixed tau value (determined by ODEHandler.estimate_tau() in advance). Value ranges of parameters are determined by .param_range(), not by .guess().

currently we assume that theta is fixed 0, not leniently around 0.

Theta is not fixed to 0 because we use param_range() for theta/kappa/sigma/rho estimation. .guess() is only for tau estimation now. The value range of theta is still (0, 1) for theta/kappa/sigma/rho estimation as I replied in my previous comment.

I know that it is convenient for extracting kappa formula but then we have to use 0 as theta value which is wrong as I explained and here is the dilemma.

Why we have to use fixed 0 as theta when the approximation is applied? The estimated kappa value is not always the same as "(dF/dt) / I". The value range of kappa is (10%, 90%) percentiles of "(dF/dt) / I".

.guess() used in the current version or is experimental?

.guess() is only for tau estimation in experimental ODEHander.

Oh so you mean that all this ODEHandler module is only experimental for the moment? When the scenario analysis runs this never gets called yet?

Theta/kappa/sigma/rho set for each tau value will be guessed by .guess() classmethod of the model

Alright so I think what you mean is that during tau estimation in estimate_tau(), the params need to be calculated in a preliminary way necessarily which is done in _score_tau() -> info_dict[phase]["param"] = self._model.guess(df, tau). Then in estimate_params() they are calculated normally as they were supposed to, without use of guess() right? Yes this makes absolutely sense. So in that sense the guess() function serves as a way to estimate the params only in order to find a proper tau value by optimizing the study from the scope of tau?

Why we will have to use fixed 0 as theta when the approximation is applied for kappa value range calculation? The estimated kappa value is not always the same as "(dF/dt) / I". The value range of kappa is (10%, 90%) percentiles of "(dF/dt) / I". Thus, the value range of theta can be (0, 1) or around 0, not exact 0.

In param_range() there is the line:
        # kappa = (dF/dt) / I when theta -> 0
        kappa_series = f.diff() / t.diff() / i

Using that formula we can solve for kappa. But this formula isn't valid only when theta = 0? Not in the general case where theta is (0,1) as we have. The original equation is:
dF/dt = rho*theta*S*I + kappa*I.
In the special case where theta=0 then solving for kappa gives us kappa = (dF/dt) / I.
But when we theta gets all the values in (0,1) this does not apply. That's what I don't understand, what am I missing?

Oh so you mean that all this ODEHandler module is only experimental for the moment? When the scenario analysis runs this never gets called yet?

Yes, ODEHandler is not linked to Scenario class at this time. Later in this issue, this will be linked to Scenario, the interface for all users.
On a different note, in the old versions, we need to check all features of covsirphy library via analysis.Scenario class. This made it difficult to find errors because call trees are cross-sectional and complexed (parameter estimation: analysis.Scenario -> analysis.ParamTracker -> phase.PhaseSeries -> phase.MPEstimator > phase.PhaseUnit -> simulation.Estimator -> simulation.Simulator -> ode.SIRF). I'm trying to simplify the call trees by creating handling (user interface) classes for each package, like ODEHandler, TrendDetector, RegressionHandler and DataLoader. ODEHandler works independently without the other packages except for covsirphy.util. Now, ODEHandler perform parameter estimation by ode.ODEHandler -> ode. _ParamEstimator and ode._MultiPhaseODESolver -> ode._ODESolver.

Alright so I think what you mean is that ... So from this perspective the guess() function serves as a way to estimate the params only in order to find a proper tau value by optimizing the study from the scope of tau?

Yes, exactly.

Using that formula we can solve for kappa. But this formula isn't valid only when theta = 0? Not in the general case where theta is (0,1) as we have.

Indeed, kappa is not "equal" to "(dF/dt) / I" when theta -> 0. To be precise, when theta -> 0, kappa is near to "(dF/dt) / I".
We know theta is not equal to 0 because direct fatal cases are observed actually in COVID-19 outbreak, but this is near to 0 because the number of direct fatal cases is relatively smaller than in-direct fatal cases. So, kappa is near to "(dF/dt) / I".

When theta gets all the values in (0,1) the (*) does not apply.

Yes, it is more logical to narrow down the value range of theta as @rebeccadavidsson said in the previous comment so that we can describe the approximation logic with the codes (and improve performance). Do you have any ideas to narrow down it? I set (0, 1) for theta because I did not have logical ideas for that.

Hmm perhaps for theta range we could run some estimations for various countries and check theta what values normally gets. That would give us an idea for limiting the range I think. I would expect it to be less than for example 0.4 though. A safe first upper limit could be 0.5 because for sure indirect fatal cases are way more than direct ones.

It seems difficult to narrow down the value range of theta...We need to directly update cs.SIRF.param_range(), or It may be better to controll the limits of parameter values and percentiles with the arguments of ODEHandler.estimate_params().
(MEMO: for refactoring, I prefer to merge .param_range() and .guess() later because a part of codes are overlaped.)

With #734, for SIR, SIR-D, SIR-F model,

model.guess(data, tau, q=0.5) returns 0.5 quantiles of parameter values
model.guess(data, tau, q=(0.1, 0.9)) returns 0.1 and 0.9 quantiles of parameter values

model.param_range() will not be used in parameter estimation and replaced with model.guess(..., q=(0.1, 0.9)).
Note that cs.SIRF.guess(q=<float>)["theta"] is always 0.0 and  cs.SIRF.guess(q=<tuple(<float>, <float>)>)["theta"] is always (0.0, 0.5), not (0.0, 1.0).

With my testing using ODEHandler, theta << 0.1.
Additional issue for ODEHandler:
RMSLE score of each phase was in (0.001, 0.4) (_dict["RMSLE"] for (phase, _dict) in info_dict.items()]), but cs.line_plot(handler.simulate().set_index("Date").drop("Susceptible", axis=1)) showed un-expected spikes at change points.

model.param_range() will not be used in parameter estimation and replaced with model.guess(..., q=(0.1, 0.9)).

You mean in the future when the experimental class will be merged to scenario or this happens currently?
guess() in sirf.py is used now for calculating the estimated parameters  as well or only for tau as we had concluded two days ago?

Please refer the codes of SIRF.guess() and _ParamEstimator.__init__.
When tau estimation, SIRF.guess(q=0.5) is called and floating value (0.5 quantile) will be returned. On the other hand, when ODE parameter estimation, SIRF.guess(q=(0.1, 0.5)) is called and tuple of foating values (01 quantile and 0.9 quantile) will be returned. The conclusion (specific value for tau estimation, value range for  ODE parameter estimation) is not changed.

On the other hand, when ODE parameter estimation, SIRF.guess(q=(0.1, 0.5)) is called and tuple of foating values (01 quantile and 0.9 quantile)

You meant here SIRF.guess(q=(0.1, 0.9))
All these, guess(), estimate_params() and _ParamEstimator are inside ODEHandler module, which you said for the moment is experimental only.
Also I see that in sirf.py the param_range() function is active and not deprecated yet.
Therefore with the current version, when I call Scenario.estimate(), which one is currently called, guess() or param_range()?

You meant here SIRF.guess(q=(0.1, 0.9)) right? All these, guess(), estimate_params() and _ParamEstimator are inside ODEHandler module, which you said for the moment is experimental only.

Yes.

Also I see that in sirf.py the param_range() function is active and not deprecated yet.

Because .param_range() is used in Scenario ->... -> Estimator, this is not deprecated yet. When this call tree will be repaced with ODEHandler, param_range() will be deprecated.

Therefore with the current version, when I call Scenario.estimate(), which one is currently called, guess() or param_range()?

param_range() is called because the current call tree is not changed.

The line "theta": 0.0 if isinstance(q, float) else pd.Series([0.0, 0.5]).repeat([1, len(q) - 1]) inside guess() what values sets to theta? for q=float -> theta=0 while for q=tuple=(0.1, 0.9) for example -> theta=(0, 0.5)?

Yes, q=float ->  always 0, q=tuple -> always (0.0, 0.5)

The repeat() function means that q could contain more values i.e. q=(0.1, 0.5, 0.9)? Then theta what would be?

q=(0.1, 0.5, 0.9) -> always (0.0, 0.5, 0.5)
q=(0.1, 0.5, 0.9, 1.0) -> always (0.0, 0.5, 0.5, 0.5)
Because pandas.Series.quantile() accepts q=(0.1, 0.5, 0.9, 1.0) etc., I made this specification. In ODEHander, as you know, q is  or <tuple(float, float)>, not <tuple(float, float, float)>.

I said "ODEHandler showed un-expected spikes at change points", but this was due to my mistakes in tesing codes (calculation of initilal values when adding phases). ODEHandler works well.
import covsirphy as cs
cs.__version__
# Data
data_loader = cs.DataLoader()
jhu_data = data_loader.jhu()
population_data = data_loader.population()
country = "Italy"
records_df = jhu_data.records(country, population=population_data.value(country))[0]
# Get change points
trend_detector = cs.TrendDetector(records_df)
start_dates, end_dates = trend_detector.sr().dates()
# Set-up handler
first_date = records_df.Date.min()
handler = cs.ODEHandler(cs.SIRF, first_date)
for (start_date, end_date) in zip(start_dates, end_dates):
    y0_dict = records_df.set_index("Date").loc[start_date].to_dict()
    handler.add(end_date, y0_dict=y0_dict)

# Estimate tau and parameter values
tau, info_dict = handler.estimate(records_df)
# Simulation with estimated tau and parameters
df = handler.simulate()
cs.line_plot(df.set_index("Date").drop("Susceptible", axis=1), title=f"{country}: simulated number of cases")

Becuase new ODEHandler works, I will try to update Scenario to use ODEHandler internally. Do you have any concerns?

Could you first try ODEHandler with a few other countries as well, just to be sure?
I think Greece, USA, India, Brazil, Russia and Japan would do.
So after the merge/update, the Scenario analysis will do exactly the same at user/application level as it does currently right?

I tried ODEHandler for the countires with version 2.19.1-gamma-fu3 and Google Colab. It worked well I think. Please refer to this notebook.
https://gist.github.com/lisphilar/14106fbf1ff0603a5efc27abe04146e7
Scenario will work as the same as it does currently except for Scenario.estimate_history() (pairplot to show the optimization history of Optuna) and Scenario.phase_estimator() (return Estimator class for a phase). They will be removed (raise NotImplementError) because they depend only on simulation.Estimator class.
My plan is as follows.
Will use ODEHandler internally:

[ ] Scenario
[ ] ExampleData
[ ] ModelValidator

Will be deprecated:

[ ] simulation.Estimator
[ ] simulation.Simulator
[ ] phase.MPEstimator
[ ] phase.PhaseSeries
[ ] phase.PhaseUnit
[ ] analysis.ParamTracker: will be replaced with new internal class anlysis._PhaseTracker, directly called by Scenario for each scenario
[ ] worldwide.PolicyMeasures: This class was created for forecasting, but Scenario.fit_predict() took over this role.
[ ] Scenario.estimate_history()
[ ] Scenario.phase_estimator()
[ ] model.param_range(), model.specialize() and model.restore() for SIR, SIRD and SIRF

So I suppose that all the following top level functions remain unchanged at user level, right?
snl = cs.Scenario(jhu_data, population_data, country)
snl.register(extras=[oxcgrt_data])
snl.records()
snl.trend()
snl.estimate(cs.SIRF)
snl.add(name="Main", days=30)
snl.fit_predict(oxcgrt_data=oxcgrt_data, name="Forecast")
snl.simulate(name="Main")
snl.simulate(name="Forecast")
snl.history(target=...)

Yes, internal codes of them will be changed, but we will keep the usage (method names and arguments).
The plan has not been completed. I will try the plan in this week with pull request(s).

Just a quick question about the parameters, in Estimator._compare(), how do we know the actual parameters in order to compare them with the simulated/estimated ones? Do we calculate them somewhere else at a previous point? In param_range()/guess() we determine their range, not their actual values right? That comp_df dataframe in which function is assigned the actual parameters?

Yes, we compare the number of cases, like Scenario.score().

Memo:
New analysis.PhaseTracker will be a public class because Scenario.__get_item__ will return an instance of this object. I updated the to-do list.

And another quick question, param_range() analyses the complete data, from first to last date of pandemic and calculates series of daily parameters and then sets the range for phase parameters that Optuna needs to the percentiles of these series right? Essentially this range is independent from the phases and changes only when source data get updated.

Only of the current phase because Estimator and _ParamEstimator are called with records for one phase.
theta is fixed 0 in the first case and theta is exact range (0, 0.5) in the second case. theta series is not used. (It could be used as well as kappa/sigma/rho, but I don't know how to get theta series.)

I rerun the analysis locally and tried:
ita_fit_df = ita_scenario.fit_predict(oxcgrt_data=oxcgrt_data, delay=(7,45), metric="R2", limits=(3,50), name="Forecast")
ita_fit_dict_result = ita_fit_df._reghandler_dict["Forecast"].to_dict("R2")

and got:

What is the interpretation of this?

Generalization peformance seems low because there is uneven balance between training score and tes score.
Could you investigate it in a new issue?
 However, this index should be removed from indicators for prediction because this has strong relationships with the other indiators.
I think this could be done automatically with Elastic Net, but this did not work for your result because  l1_ratio and alpha was 0 (calculated by ElasticNetCV).
We need to investigate Elastic Net regression. Or, new machine learing models, including SVR, should be added as regressors.

Tasks completed for parameter estimation. Now Scenario uses ODEHandler internally via PhaseTracker.


Rocky Linux 9.4 support

We do need to consider what to do about the --root-dev-only issue, if it's still a problem.

We do need to consider what to do about the --root-dev-only issue, if it's still a problem.

I have not hit this issue.
Issue in SMS-LAB that Piotr was hitting, was that grub.cfg was completely being removed while upgrading packages from 9.3(older kernel) to 9.3 (newer kernel)
The fix for that was running:
grub2-mkconfig -o /boot/efi/EFI/rocky/grub.cfg
After upgrade, before rebooting hosts

We do need to consider what to do about the --root-dev-only issue, if it's still a problem.

I have not hit this issue.
Issue in SMS-LAB that Piotr was hitting, was that grub.cfg was completely being removed while upgrading packages from 9.3(older kernel) to 9.3 (newer kernel) The fix for that was running: grub2-mkconfig -o /boot/efi/EFI/rocky/grub.cfg After upgrade, before rebooting hosts

Do you still have an environment running 9.4? If so could you check if --root-dev-only is in /boot/efi/EFI/rocky/grub.cfg?

We do need to consider what to do about the --root-dev-only issue, if it's still a problem.

I have not hit this issue.
Issue in SMS-LAB that Piotr was hitting, was that grub.cfg was completely being removed while upgrading packages from 9.3(older kernel) to 9.3 (newer kernel) The fix for that was running: grub2-mkconfig -o /boot/efi/EFI/rocky/grub.cfg After upgrade, before rebooting hosts

Do you still have an environment running 9.4? If so could you check if --root-dev-only is in /boot/efi/EFI/rocky/grub.cfg?

It's there:
[root@gkoper-controller-01 ~]# cat  /boot/efi/EFI/rocky/grub.cfg
search --no-floppy --root-dev-only --fs-uuid --set=dev c209b919-b137-47ad-82ef-bc6cc88323ad
set prefix=($dev)/boot/grub2
export $prefix
configfile $prefix/grub.cfg

[root@gkoper-controller-01 ~]# uname -a
Linux gkoper-controller-01.novalocal 5.14.0-427.22.1.el9_4.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Jun 19 17:35:04 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux

grub.cfg on a non upgraded 9.2 machine (control-host)
#
# DO NOT EDIT THIS FILE
#
# It is automatically generated by grub2-mkconfig using templates
# from /etc/grub.d and settings from /etc/default/grub
#

### BEGIN /etc/grub.d/00_header ###
set pager=1

if [ -f ${config_directory}/grubenv ]; then
  load_env -f ${config_directory}/grubenv
elif [ -s $prefix/grubenv ]; then
  load_env
fi
if [ "${next_entry}" ] ; then
   set default="${next_entry}"
   set next_entry=
   save_env next_entry
   set boot_once=true
else
   set default="0"
fi

if [ x"${feature_menuentry_id}" = xy ]; then
  menuentry_id_option="--id"
else
  menuentry_id_option=""
fi

export menuentry_id_option

if [ "${prev_saved_entry}" ]; then
  set saved_entry="${prev_saved_entry}"
  save_env saved_entry
  set prev_saved_entry=
  save_env prev_saved_entry
  set boot_once=true
fi

function savedefault {
  if [ -z "${boot_once}" ]; then
    saved_entry="${chosen}"
    save_env saved_entry
  fi
}

function load_video {
  if [ x$feature_all_video_module = xy ]; then
    insmod all_video
  else
    insmod efi_gop
    insmod efi_uga
    insmod ieee1275_fb
    insmod vbe
    insmod vga
    insmod video_bochs
    insmod video_cirrus
  fi
}

serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1
terminal_input serial console
terminal_output serial console
if [ x$feature_timeout_style = xy ] ; then
  set timeout_style=menu
  set timeout=5
# Fallback normal timeout code in case the timeout_style feature is
# unavailable.
else
  set timeout=5
fi
### END /etc/grub.d/00_header ###

### BEGIN /etc/grub.d/01_users ###
if [ -f ${prefix}/user.cfg ]; then
  source ${prefix}/user.cfg
  if [ -n "${GRUB2_PASSWORD}" ]; then
    set superusers="root"
    export superusers
    password_pbkdf2 root ${GRUB2_PASSWORD}
  fi
fi
### END /etc/grub.d/01_users ###

### BEGIN /etc/grub.d/08_fallback_counting ###
insmod increment
# Check if boot_counter exists and boot_success=0 to activate this behaviour.
if [ -n "${boot_counter}" -a "${boot_success}" = "0" ]; then
  # if countdown has ended, choose to boot rollback deployment,
  # i.e. default=1 on OSTree-based systems.
  if  [ "${boot_counter}" = "0" -o "${boot_counter}" = "-1" ]; then
    set default=1
    set boot_counter=-1
  # otherwise decrement boot_counter
  else
    decrement boot_counter
  fi
  save_env boot_counter
fi
### END /etc/grub.d/08_fallback_counting ###

### BEGIN /etc/grub.d/10_linux ###
insmod part_gpt
insmod lvm
insmod ext2
set root='lvmid/kdPx7n-cEhR-FwYw-B3cT-G4vT-14fy-Tfocmj/bsOCD3-TKk6-UYY1-3J4j-hfuA-y8g1-ezwNg2'
if [ x$feature_platform_search_hint = xy ]; then
  search --no-floppy --fs-uuid --set=root --hint='lvmid/kdPx7n-cEhR-FwYw-B3cT-G4vT-14fy-Tfocmj/bsOCD3-TKk6-UYY1-3J4j-hfuA-y8g1-ezwNg2'  c209b919-b137-47ad-82ef-bc6cc88323ad
else
  search --no-floppy --fs-uuid --set=root c209b919-b137-47ad-82ef-bc6cc88323ad
fi
insmod part_gpt
insmod lvm
insmod ext2
set boot='lvmid/kdPx7n-cEhR-FwYw-B3cT-G4vT-14fy-Tfocmj/bsOCD3-TKk6-UYY1-3J4j-hfuA-y8g1-ezwNg2'
if [ x$feature_platform_search_hint = xy ]; then
  search --no-floppy --fs-uuid --set=boot --hint='lvmid/kdPx7n-cEhR-FwYw-B3cT-G4vT-14fy-Tfocmj/bsOCD3-TKk6-UYY1-3J4j-hfuA-y8g1-ezwNg2'  c209b919-b137-47ad-82ef-bc6cc88323ad
else
  search --no-floppy --fs-uuid --set=boot c209b919-b137-47ad-82ef-bc6cc88323ad
fi

# This section was generated by a script. Do not modify the generated file - all changes
# will be lost the next time file is regenerated. Instead edit the BootLoaderSpec files.
#
# The blscfg command parses the BootLoaderSpec files stored in /boot/loader/entries and
# populates the boot menu. Please refer to the Boot Loader Specification documentation
# for the files format: https://systemd.io/BOOT_LOADER_SPECIFICATION/.

# The kernelopts variable should be defined in the grubenv file. But to ensure that menu
# entries populated from BootLoaderSpec files that use this variable work correctly even
# without a grubenv file, define a fallback kernelopts variable if this has not been set.
#
# The kernelopts variable in the grubenv file can be modified using the grubby tool or by
# executing the grub2-mkconfig tool. For the latter, the values of the GRUB_CMDLINE_LINUX
# and GRUB_CMDLINE_LINUX_DEFAULT options from /etc/default/grub file are used to set both
# the kernelopts variable in the grubenv file and the fallback kernelopts variable.
if [ -z "${kernelopts}" ]; then
  set kernelopts="root=LABEL=rootfs ro  console=tty0 console=ttyS0,115200 no_timer_check nofb nomodeset gfxpayload=text net.ifnames=1 rd.auto  "
fi

insmod blscfg
blscfg
### END /etc/grub.d/10_linux ###

### BEGIN /etc/grub.d/10_reset_boot_success ###
# Hiding the menu is ok if last boot was ok or if this is a first boot attempt to boot the entry
if [ "${boot_success}" = "1" -o "${boot_indeterminate}" = "1" ]; then
  set menu_hide_ok=1
else
  set menu_hide_ok=0
fi
# Reset boot_indeterminate after a successful boot
if [ "${boot_success}" = "1" ] ; then
  set boot_indeterminate=0
# Avoid boot_indeterminate causing the menu to be hidden more than once
elif [ "${boot_indeterminate}" = "1" ]; then
  set boot_indeterminate=2
fi
# Reset boot_success for current boot
set boot_success=0
save_env boot_success boot_indeterminate
### END /etc/grub.d/10_reset_boot_success ###

### BEGIN /etc/grub.d/12_menu_auto_hide ###
### END /etc/grub.d/12_menu_auto_hide ###

### BEGIN /etc/grub.d/14_menu_show_once ###
if [ x$feature_timeout_style = xy ]; then
  if [ "${menu_show_once_timeout}" ]; then
    set timeout_style=menu
    set timeout="${menu_show_once_timeout}"
    unset menu_show_once_timeout
    save_env menu_show_once_timeout
  fi
fi
### END /etc/grub.d/14_menu_show_once ###

### BEGIN /etc/grub.d/20_linux_xen ###
### END /etc/grub.d/20_linux_xen ###

### BEGIN /etc/grub.d/20_ppc_terminfo ###
### END /etc/grub.d/20_ppc_terminfo ###

### BEGIN /etc/grub.d/30_os-prober ###
### END /etc/grub.d/30_os-prober ###

### BEGIN /etc/grub.d/30_uefi-firmware ###
if [ "$grub_platform" = "efi" ]; then
	menuentry 'UEFI Firmware Settings' $menuentry_id_option 'uefi-firmware' {
		fwsetup
	}
fi
### END /etc/grub.d/30_uefi-firmware ###

### BEGIN /etc/grub.d/35_fwupd ###
### END /etc/grub.d/35_fwupd ###

### BEGIN /etc/grub.d/40_custom ###
# This file provides an easy way to add custom menu entries.  Simply type the
# menu entries you want to add after this comment.  Be careful not to change
# the 'exec tail' line above.
### END /etc/grub.d/40_custom ###

### BEGIN /etc/grub.d/41_custom ###
if [ -f  ${config_directory}/custom.cfg ]; then
  source ${config_directory}/custom.cfg
elif [ -z "${config_directory}" -a -f  $prefix/custom.cfg ]; then
  source $prefix/custom.cfg
fi
### END /etc/grub.d/41_custom ###
[root@gkoper-ansible-control ~]# uname -a
Linux gkoper-ansible-control.novalocal 5.14.0-284.30.1.el9_2.x86_64 #1 SMP PREEMPT_DYNAMIC Sat Sep 16 09:55:41 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux


use type hinting

deepface api and back functions and methods do not have type hinting. will be good for developers in addition to docstrings.

Closed with PR - https://github.com/serengil/deepface/pull/922


Add angular@7 cli tests

Issue: Add angular@7 to cli tests

After bumping the angular versions something broke in react 🤔

Please try merging master

But it's possible that this is the problem with hoisting I mentioned in https://github.com/storybooks/storybook/pull/4405#discussion_r227588713

But it's possible that this is the problem with hoisting I mentioned in #4405 (comment)

Yep, also mentioned it in https://github.com/storybooks/storybook/pull/4405#discussion_r227591829 =)

Friendly reminder: the best way to resolve conflicts in yarn.lock is just to run yarn

TBH, that is what I am doing. If I have conflicts during the merge in yarn.lock, I just take it from the parent and yarn install again 🤷♂

If I have conflicts during the merge in yarn.lock, I just take it from the parent and yarn install again 🤷♂

That's what I did before I knew about this feature =)

Wait, you mean I can run yarn with the broken yarn.lock, and it will fix it ? 😵

Exactly

AFAIK npm@6 does this with package-lock as well

😱


Init Script fails due to custom port

Running the init script it tries do download a configuration:
Downloading lastest configuration...
GET http://repo.mseclab.com:9080/nathan/current...
Impossible to download the file -> <urlopen error [Errno 110] Connection timed out>

The response of the webserver is only one string:
NRL001

In most business environments such ports are blocked, please move to 80/443.
Moreover after the script is restarted the android sdk is downloaded again, the previous download is not reused.

Hi,
The response is correct because in the first request the current version is returned (actually NRL001).
Thanks for your hint: the web server has been moved on port 80.
For the last point, the init command checks if sdk/  folder exists and then checks that emulator command works correctly. Only if the two checks fail, the script restart to download the SDK.
Probably the SDK files were not been completed and the script restarted to download (related to 9080 port?).

Hi,
yes I noticed that the first response is only the version number and downloaded the remaining files manually.
As for buffering the SDK: No, the SDK-Download was complete and also sucessfully extracted but the download started again for each run.
I will see if I can reproduce this issue or if that was related to the custom port.


How the modifications in the UI are passed to the physics simulation ?

Hi,
I'm having a hard time trying to understand how the modifications in the UI are passed to the physics simulation in the boilerplate simulate.cc. I want to add new buttons to the UI to make my robot follow hard coded plans using the joint position actuators.
So far, I understand that the physics loop runs in a background thread and modify the state through the function Simulate::applyforceperturbations, which calls mjv_applyPerturbForce to modify the mjData object using an mjvPerturb object.
I also understand that the render loop runs in the main thread and calls mjui_event and mjui_update when I modify joint positions.
But I can't understand where the connection between the render loop and the physics loop happens. More specifically, what is the mechanism of the render loop that fills the mjvPerturb object so that the physics loop can modify the state of the simulation accordingly ?
A detailed high level detailed explanation would be much appreciated.
Thanks in advance

@yuvaltassa I think my problem for now is mainly with question 1 (although I also don't know the answer for questions 2 and 3). I want to modify the boilerplate simulate.cc to add a new button to the right panel which, when clicked, change the inputs of the positions actuators according a hard coded set of joint positions, wait until the robot goes to the final desired position (in joint space) and print to stdout the final position of the robot end-effector in cartesian space.

Here is a commit where a button was added to simulate 80b4ffdd6acedad2bf0b2def3056de13ea8cc803

@yuvaltassa Thanks for the starting point. I'm trying something similar for my button but I have a doubt. In the case of the commit you showed, the action triggered by the button is a passive one (dump a screenshot to the filesystem). However, the action I need to trigger is an active one (render a robot movement when I modify joints), which I think is more difficult. I'm trying to put prints for some hours in the simulation code to grasp what is happening but it's still obscure to me.
I will try to summarize what I think I understand and what I don't understand.

What I think I understand:

When I modify a joint in the boilerplate UI, the function Simulate::uiEvent is called, which ends up calling mjui_event (mjuiItem* it = mjui_event(&sim->ui1, state, &sim->con);). This seems to be what receives the control input from the UI and transmits to the physics loop.
On the other hand, in the physics loop (running in the background thread and called by the function PhysicsLoop in main.cc), the lines that concretely update the physics state with the new joint positions are:
mju_zero(d->xfrc_applied, 6*m->nbody);
sim.applyforceperturbations();

which ends up calling mjv_applyPerturbForce (mjv_applyPerturbForce(this->m, this->d, &this->pert);).

What I don't understand:

What is the relation between mjui_event and mjv_applyPerturbForce ?
After I give a control input to the position actuator in the GUI, how mjv_applyPerturbForce ends up receiving the right perturbation from mjui_event in order to update the physics state ?
How the modification in the physics state caused by mjv_applyPerturbForce ends up being rendered by the UI ?

@yuvaltassa At a higher level, I guess my question is about the connection between the physics engine and the abstract UI. If you can provide a higher level explanation about what happens from the moment I modify a control input through the slide button in the right panel until the moment the scene is rendered in the central screen, I think would be a big help.

Let's start with some basic clarifications. Watch this video.

In seconds 8-17 you are seeing user perturbations (first in paused mode, the in play mode). This is what mjv_applyPerturb{Pose, Force} are used for, respectively. It is unrelated to the joint/actuator sliders.
Joint/Control sliders, shown in seconds 30-50 do something else, they directly modify mjData. This happens in this line (joints) and this line (controls). When constructing the slider, we give it a pointer, directly into mjData and are effectively saying "the slider should write into this pointer".
The "Clear all" button at the top of the Control section cannot be associated with a pointer, the action that it performs (setting mjData.ctrl to 0) needs to be explicitly handled in the uiEvent function here.

So basically I don't think you need to think about the perturb functions at all. Play with the code a bit more, and see if things make more sense to you. I'll close this issue but will keep following it if you have more questions.

@yuvaltassa Thanks a lot ! I inserted a new button that can make the robot go to a hard coded position when clicked. But I'm not sure if I'm doing it in the idiom expected by MuJoCo. I'm doing it in the following way:
      // Go to a hardcoded position
      if (it->sectionid==SECT_NEW_BUTTON && it->itemid==0) {
          int ctrl_id1 = mj_name2id(m, mjOBJ_ACTUATOR, "joint1");
          int ctrl_id2 = mj_name2id(m, mjOBJ_ACTUATOR, "joint2");
          int ctrl_id3 = mj_name2id(m, mjOBJ_ACTUATOR, "joint3");
          int ctrl_id4 = mj_name2id(m, mjOBJ_ACTUATOR, "joint4");
          int ctrl_id5 = mj_name2id(m, mjOBJ_ACTUATOR, "joint5");
          int ctrl_id6 = mj_name2id(m, mjOBJ_ACTUATOR, "joint6");

          if( ctrl_id1 >= 0 && ctrl_id2 >= 0 && ctrl_id3 >= 0 && ctrl_id4 >= 0 && ctrl_id5 >= 0 && ctrl_id6 >= 0){
              d->ctrl[ctrl_id1] = 0.5;
              d->ctrl[ctrl_id2] = 0.5;
              d->ctrl[ctrl_id3] = 0.5;
              d->ctrl[ctrl_id4] = 0.5;
              d->ctrl[ctrl_id5] = 0.5;
              d->ctrl[ctrl_id6] = 0.5;
          }

          mjui_update(SECT_NEW_BUTTON, -1, &sim->ui1, &sim->uistate, &sim->con);
      }

Is it the right way of modifying d->ctrl ? Also, how can I make it go through a path in the joint space ? I guess now my problem is the question 3 that you mentioned in your first message :)

What you are doing seems perfectly fine. Yes, you are setting ctrl correctly.
The answer to this question is a control callback. This is explained here and you can find an example here. You need to write a function that accepts const mjModel* and mjData*, and writes whatever it wants into ctrl.
If you go this route then you don't need a button since it already exists. Under Physics -> Disable Flags you can switch Actuation on and off which will enable/disable your controller (and the actuators themselves). You can set this flag in XML as well, if you want it disabled at load time.

@yuvaltassa So, if I understood, if I want to set simple controls, like setting hard coded inputs to the position actuators, I can just set d->ctrl in the uiEvent callback directly. But if want a controller that depends on intermediate results of the simulation, then it's mandatory to set a control callback. Is it right ?
I have two doubts:

If I want to go through a hard coded path in the joint space, I would have to sleep a bit between each two consecutive points in the path, right ? Is there some custom cross platform sleep function in MuJoCo for these kind of cases ? I saw that in C, the sleep function for windows is taken from windows.h while for linux it's taken from unistd.h.

f I want to do it with the control callback, I would have to call mjui_update inside the callback, right ? But the callback only takes as arguments mjModel and mjData. How to proceed to have access to the other parameters mjui_update needs inside the control callback ?

Not mandatory. If you hack in simulate you can just read values from the global mjData. But that's not recommended.
No need for that. Just look at mjData.time. simulate will take care of the synchronisation.
Do what with the control callback? Not sure what you are asking but it's easy to pass information to the callback via mjData.userdata, if you need to do that.

@yuvaltassa I'm trying to execute the hard coded path after clicking the added button by playing with mjData.time but the robot gets frozen during the time it should execute the path and only executes the last step of the path. Is it because mjData.time advances too fast compared to the render loop ? How to proceed ? Should I make mjData.time advance slower while I'm executing the hard coded path and then return the advancement rate to what it was before the hard coded path once the path is completed ? How to do that ? Here is my code:
      // Go to a hardcoded position
      if (it->sectionid==SECT_NEW_BUTTON && it->itemid==0) {
          mjtNum path[10][6] = {
                  {0.5, 0.5, 0.5, 0.5, 0.5, 0.5},
                  {1, 1, 1, 1, 1, 1},
                  {0.5, 0.5, 0.5, 0.5, 0.5, 0.5},
                  {1, 1, 1, 1, 1, 1},
                  {0.5, 0.5, 0.5, 0.5, 0.5, 0.5},
                  {1, 1, 1, 1, 1, 1},
                  {0.5, 0.5, 0.5, 0.5, 0.5, 0.5},
                  {1, 1, 1, 1, 1, 1},
                  {0.5, 0.5, 0.5, 0.5, 0.5, 0.5},
                  {1, 1, 1, 1, 1, 1}
          };

          bool finished = false;
          mjtNum start_time = d->time, delta = 1.0;
          int iter = 0;

          while(d->time < start_time + 10*delta){
              if(d->time >= start_time + iter*delta){
                  int ctrl_id1 = mj_name2id(m, mjOBJ_ACTUATOR, "joint1");
                  int ctrl_id2 = mj_name2id(m, mjOBJ_ACTUATOR, "joint2");
                  int ctrl_id3 = mj_name2id(m, mjOBJ_ACTUATOR, "joint3");
                  int ctrl_id4 = mj_name2id(m, mjOBJ_ACTUATOR, "joint4");
                  int ctrl_id5 = mj_name2id(m, mjOBJ_ACTUATOR, "joint5");
                  int ctrl_id6 = mj_name2id(m, mjOBJ_ACTUATOR, "joint6");

                  if( ctrl_id1 >= 0 && ctrl_id2 >= 0 && ctrl_id3 >= 0 && ctrl_id4 >= 0 && ctrl_id5 >= 0 && ctrl_id6 >= 0){
                      d->ctrl[ctrl_id1] = path[iter][0];
                      d->ctrl[ctrl_id2] = path[iter][1];
                      d->ctrl[ctrl_id3] = path[iter][2];
                      d->ctrl[ctrl_id4] = path[iter][3];
                      d->ctrl[ctrl_id5] = path[iter][4];
                      d->ctrl[ctrl_id6] = path[iter][5];
                  }

                  mjui_update(SECT_NEW_BUTTON, -1, &sim->ui1, &sim->uistate, &sim->con);
                  ++iter;

                  if(iter == 10) break;
              }

              mj_step(m, d);
          }
      }

This is inside a control callback?
Where is this code running?

@yuvaltassa This piece of code is in the uiEvent callback of the simulate.cc. It is a slight modification of my previous piece of code (here: https://github.com/deepmind/mujoco/issues/569#issuecomment-1310281607) in order to execute a complete path instead of just one move.

Your code should only look at data.time and write into ctrl. You shouldn't be stepping, that already happens elsewhere.

@yuvaltassa That is what I was trying before. But d->time stays constant for some reason and the loop becomes infinity if I remove the mj_step line.

This is because it only runs when you click the button. Use a control callback as I explained earlier.

@yuvaltassa I see that mjData.userdata has type mjtNum*. How to proceed if I want to pass data that doesn't fit in mjtNum type in the control callback ?
For example, mjui_update is called as mjui_update(SECT_NEW_BUTTON, -1, &sim->ui1, &sim->uistate, &sim->con);. How can I call it inside the control callback ?

@yuvaltassa I got something close to work. But there is still a problem with the memory allocation. The robot executes the hard coded path if I click on the button for the first time but don't execute it for the next times.
Inside the uiEvent callaback I have the following piece of code:
            if (it->sectionid==SECT_NEW_BUTTON && it->itemid==0) {
                mjMARKSTACK
                mjtNum* userdata = mj_stackAlloc(d, 2);
                userdata[0] = d->time;
                userdata[1] = 0;
                d->userdata = userdata;
                mjcb_control = control_callback;

                while(d->userdata[1] < 10){
                    ++d->userdata[1];
                    mjui_update(SECT_NEW_BUTTON, -1, &sim->ui1, &sim->uistate, &sim->con);
                }

                mjFREESTACK
            }

And my control callback is:
void control_callback(const mjModel* m, mjData *d) {
    mjtNum path[10][6] = {
            {0.5, 0.5, 0.5, 0.5, 0.5, 0.5},
            {1, 1, 1, 1, 1, 1},
            {0.5, 0.5, 0.5, 0.5, 0.5, 0.5},
            {1, 1, 1, 1, 1, 1},
            {0.5, 0.5, 0.5, 0.5, 0.5, 0.5},
            {1, 1, 1, 1, 1, 1},
            {0.5, 0.5, 0.5, 0.5, 0.5, 0.5},
            {1, 1, 1, 1, 1, 1},
            {0.5, 0.5, 0.5, 0.5, 0.5, 0.5},
            {1, 1, 1, 1, 1, 1}
    };

    mjtNum start_time = d->userdata[0], delta = 1.0;
    int iter = (int)d->userdata[1];

    if(d->time >= start_time + iter*delta && iter < 10){
        int ctrl_id1 = mj_name2id(m, mjOBJ_ACTUATOR, "joint1");
        int ctrl_id2 = mj_name2id(m, mjOBJ_ACTUATOR, "joint2");
        int ctrl_id3 = mj_name2id(m, mjOBJ_ACTUATOR, "joint3");
        int ctrl_id4 = mj_name2id(m, mjOBJ_ACTUATOR, "joint4");
        int ctrl_id5 = mj_name2id(m, mjOBJ_ACTUATOR, "joint5");
        int ctrl_id6 = mj_name2id(m, mjOBJ_ACTUATOR, "joint6i");

        if( ctrl_id1 >= 0 && ctrl_id2 >= 0 && ctrl_id3 >= 0 && ctrl_id4 >= 0 && ctrl_id5 >= 0 && ctrl_id6 >= 0){
            d->ctrl[ctrl_id1] = path[iter][0];
            d->ctrl[ctrl_id2] = path[iter][1];
            d->ctrl[ctrl_id3] = path[iter][2];
            d->ctrl[ctrl_id4] = path[iter][3];
            d->ctrl[ctrl_id5] = path[iter][4];
            d->ctrl[ctrl_id6] = path[iter][5];
        }
    }
}

Any idea about what I'm doing wrong ?

@yuvaltassa You can ignore my two last messages, I think I got it now. It behaves like I want. Could you indicate me if there is some problem with my approach, please ?
My control callback is:
void control_callback(const mjModel* m, mjData *d) {
    mjtNum path[10][6] = {
            {0.5, 0.5, 0.5, 0.5, 0.5, 0.5},
            {1, 1, 1, 1, 1, 1},
            {0.5, 0.5, 0.5, 0.5, 0.5, 0.5},
            {1, 1, 1, 1, 1, 1},
            {0.5, 0.5, 0.5, 0.5, 0.5, 0.5},
            {1, 1, 1, 1, 1, 1},
            {0.5, 0.5, 0.5, 0.5, 0.5, 0.5},
            {1, 1, 1, 1, 1, 1},
            {0.5, 0.5, 0.5, 0.5, 0.5, 0.5},
            {1, 1, 1, 1, 1, 1}
    };

    mjtNum delta = 1.0;

    if(d->time >= d->userdata[0] + delta * d->userdata[1] && d->userdata[1] < 10){
        int ctrl_id1 = mj_name2id(m, mjOBJ_ACTUATOR, "joint1");
        int ctrl_id2 = mj_name2id(m, mjOBJ_ACTUATOR, "joint2");
        int ctrl_id3 = mj_name2id(m, mjOBJ_ACTUATOR, "joint3");
        int ctrl_id4 = mj_name2id(m, mjOBJ_ACTUATOR, "joint4");
        int ctrl_id5 = mj_name2id(m, mjOBJ_ACTUATOR, "joint5");
        int ctrl_id6 = mj_name2id(m, mjOBJ_ACTUATOR, "joint6");

        if( ctrl_id1 >= 0 && ctrl_id2 >= 0 && ctrl_id3 >= 0 && ctrl_id4 >= 0 && ctrl_id5 >= 0 && ctrl_id6 >= 0){
            d->ctrl[ctrl_id1] = path[(size_t)d->userdata[1]][0];
            d->ctrl[ctrl_id2] = path[(size_t)d->userdata[1]][1];
            d->ctrl[ctrl_id3] = path[(size_t)d->userdata[1]][2];
            d->ctrl[ctrl_id4] = path[(size_t)d->userdata[1]][3];
            d->ctrl[ctrl_id5] = path[(size_t)d->userdata[1]][4];
            d->ctrl[ctrl_id6] = path[(size_t)d->userdata[1]][5];
        }

        ++d->userdata[1];
    }
}

And the piece of code in the uiEvent callback is:
if (it->sectionid==SECT_NEW_BUTTON && it->itemid==0) {
    d->userdata[0] = d->time;
    d->userdata[1] = 0;
    mjcb_control = control_callback;
    mjui_update(SECT_NEW_BUTTON, -1, &sim->ui1, &sim->uistate, &sim->con);
}

You, that makes sense to me :slightly_smiling_face:


Typo 'LHV' -> 'LVH'?

Describe the bug
I saw such code in places like https://github.com/ChainSafe/lodestar/blob/5739caf64cd9b7ec2acff602f6b2d2aa75281c21/packages/beacon-node/src/chain/blocks/index.ts#L87
if (segmentExecStatus.execAborted !== null) {
      if (segmentExecStatus.invalidSegmentLHV !== undefined) {
        this.forkChoice.validateLatestHash(segmentExecStatus.invalidSegmentLHV);
      }
      throw segmentExecStatus.execAborted.execError;
    }

Expected behavior
Could it meant to be 'LVH' instead of 'LHV'?
Steps to reproduce
No response
Additional context
No response
Operating system
Linux
Lodestar version or commit hash
5739caf64cd9b7ec2acff602f6b2d2aa75281c21

thanks @Yc-Chen for reporting this :pray: here is the fix:

https://github.com/ChainSafe/lodestar/pull/5850


Basic navigation logged in

As a logged in user, I want to see the navigation menu on the main page so that I can navigate to other parts of the website from the main page
Acceptance criteria:

Navbar is on top of the page
Navbar is responsive
Items grouped on the left navbar side: App_Name redirects to main view logged out (!!!Stay on main page--Qiao Zhou), Favorites redirects to the page with my favorites, Added by me redirects to page with my content, My profile redirects to my profile page
Items grouped on the right navbar side: Add new item redirects to upload content page, Log out performs the logout action
Active navbar items correspond to displayed page
Logout action implemented as a separate story.

Implementation question:

good to have is fixed navbar, but it produces content overlapping issues
we can start with the static navbar

Verified with Firefox 53.0.3 on Windows 8.1 on devel branch with latest commit e82ae04.


Is this Article Still Valid?

[This is a great article.  It is dated 12/08/2022. But I am reading this in the Admin center for crm online:  The use of Dynamics 365 (deprecated), Salesforce, and SQL Server Data Integration connections is being deprecated. Users will be able to continue to use existing connections, but no new connections can be created after April 29 2022. For Dynamics 365 (deprecated) connections, please update your data integration projects to use the Dataverse (Legacy) connector. For SQL Server and Salesforce, please use Dataflows to replace the data integration projects. All Data Integration connections that use Dynamics 365 (deprecated), Salesforce, or SQL Server connectors will be disabled on July 28th 2022.]

Document Details
⚠ Do not edit this section. It is required for learn.microsoft.com ➟ GitHub issue linking.

ID: 3ead09d9-3e51-04ce-dc6e-ac9bb59816ec
Version Independent ID: 94d19f8d-3c5e-8ed9-53ee-4b6173f49144
Content: Use SQL to query data (Microsoft Dataverse) - Power Apps
Content Source: powerapps-docs/developer/data-platform/dataverse-sql-query.md
Service: powerapps
Sub-service: dataverse-developer
GitHub Login: @RichdiMSFT
Microsoft Alias: richdi

Thanks for your comment, @mjvisintin. This issue has been assigned to the doc author for review.

@mjvisintin Thanks for your comment. The Admin center notice is for Power Automate, Power Apps and Logic Apps.
For the Power BI and Power Query connectors people should use the Dataverse or Dynamics 365 (Dataverse) connectors. The two legacy connectors ( Common Data Service (legacy) and Dynamics 365 online (legacy)) Power BI and Power Query connectors will continue to be available for now. When a deprecation has been determined they will be communicated in the connector documentation with time lines specified.
Sorry for the confusion.
Rich


Add a "reload from 3scale" endpoint to the Management API

Currently the Management API can update the configuration with a JSON configuration file passed as body in POST /config or PUT /config.
It would be good to have a method that would invoke downloading the configuration from 3scale and applying it to the running gateway.

There is POST /boot which does the boot process again.
Reopen if that is not enough.


Error Preventing it

I've been trying to open the focus tree preview for a mod but whenever I try it says 'UserError: In file common/national_focus/Jackal_Land.txt: Expect a '}' at (1498, 2): (EOF)
What does this mean?

Every '{' needs a '}' to close it. You missed a '}' somewhere.
TheSilentKing15 @.***> 于2023年2月8日周三 00:31写道：

I've been trying to open the focus tree preview for a mod but whenever I
try it says 'UserError: In file common/national_focus/Jackal_Land.txt:
Expect a '}' at (1498, 2): (EOF)
What does this mean?
—
Reply to this email directly, view it on GitHub
https://github.com/herbix/hoi4modutilities/issues/56, or unsubscribe
https://github.com/notifications/unsubscribe-auth/ABWICNL3R4M5UT457ZFFIR3WWJ2GNANCNFSM6AAAAAAUUF4QWQ
.
You are receiving this because you are subscribed to this thread.Message
ID: @.***>

--
Chaofan Yang
Tel: (+86)15510769284


Clock does not work in Firefox 3.6

Checked http://ect.bell-labs.com/who/ajeffrey/agda-frp-js/clock.html in
Mozilla/5.0 (X11; U; Linux i686; en-US; rv:<IP_ADDRESS>) Gecko/20110905 Ubuntu/10.10 (maverick) Firefox/3.6.22

At the moment, support for older browsers is quite far down on the priority list. I'm deliberately leaving this issue open to act as a reminder to worry about cross-browser testing at some point down the road.


Feat doctor add codemod

Codemod
This repository also contains a collection of codemod scripts that help update React(ICE) and Rax APIs.
Installation
Install jscodeshift and @iceworks/doctor.
$ npm i -g jscodeshift @iceworks/doctor

Usage (CLI)
iceworks-doctor -c <transform> <path?> [...options?]

transform - name of transform, see available transforms below.
path? - files or directory to transform.
options? - some rule's options.

This will start an interactive wizard, and then run the specified transform.
PS: You can also clone this repository then use jscodeshift's CLI API.
Included Transforms
plugin-rax-component-to-component
Update plugin-rax-component to plugin-component.
See: https://rax.js.org/docs/guide/com-migration
iceworks-doctor -c plugin-rax-component-to-component ./

Codecov Report

Merging #662 (55d4f56) into release/0.13.1 (1e0dd97) will not change coverage.
The diff coverage is n/a.

@@               Coverage Diff               @@
##           release/0.13.1     #662   +/-   ##
===============================================
  Coverage           57.14%   57.14%
===============================================
  Files                   1        1
  Lines                  70       70
  Branches               15       15
===============================================
  Hits                   40       40
  Misses                 30       30

Continue to review full report at Codecov.

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


Fix #16 where this.timeOutT1 is sometimes null

process.hrtime(arg) doesn't accept null as an argument. Checking if this.timeOutT1 is non-null before using process.hrtime(this.timeOutT1) to prevent issue #16

Good catch, thanks.  Though this is strange that my small test case on that issue didn't present this.  I can see why this is happening, and it only occurs when say timerA.clearTimeout is called as a result of timerA's timeout triggering.  In that scenario, clearTimeout should not be getting called at all, because a timeout is a one shot thing and the purpose of clearTimeout is to stop a timeout before it has happened.  So ultimately, I'll be making a change to effectively make clearTimeout do nothing if it is called as a result of the timeout, but I think it'd be good to have your added check in there just incase.


Add npm-shrinkwrap.json

Locks our dependencies at the current working version to prevent any future CI breaks caused by types packages (or others) changing out from under us

You already have package lock for that O_o

Yeah the real problem was the CI server caching. Ignore


[Facebook Messenger] Remote debugging with ngrok and facebook messenger is not working

I aplied every instruction on node facebook example , I get no error, everything seems okay but i can not get respond on facebook messenger.
But when i try to debug locally with localhost url by bot emulator, it is working. Is it a configuration problem related to page or ip identification informations? What can be wrong?
It even does not work for web chat on bot dashboard page.

@wethil can you see any errors on the bot page at botframework website?

No I can not see any error.

Recently there are issues with ngrok, you should try one of the alternatives like localtunnel, see if it works

@wethil Try deploying a basic bot example such as this one, and see if you can get it working on FB, before moving on to troubleshoot the more complex FB example bot.  If the basic bot works, but the FB example bot does not, then we can know the problem is in the example code.


Improvements to GitHub Actions tests

(a) running this from a stashed copy of the kidney table under (something like) src/test/resources. This will buffer against changes to the live tables breaking all builds. The test file can be updated asASCT+B standard changes.
(b) If possible this should run from a test goal in the main MakeFile that builds from src/test/resources/kidney.tsv , rather than duplicating that file. I'm not sure how to do this though - is it possible to set vars in goals?

Would be best to unify test Makefile with main if possible => unified integration test of both Makefile & code.
Maybe skip graphs if container not in place?


Scoped dependencies are not treated as externals

The is_external function is returning false if the request is a scoped dependency.
as example, if request is @scoped/somedep/lib/index
// server configurations.js
let package_name = request
if (package_name.indexOf('/') >= 0)
{
    package_name = package_name.substring(0, package_name.indexOf('/'))
}

package_name will be @scoped rather than @scoped/somedep and it will fail in:
validate_npm_package_path(package_name).validForNewPackages

hmm, almost never heard of scoped packages before.
ok, I'll test a workaround, maybe tomorrow.

Try the new version

Why is universal webpack determining the external packages? We have several packages (React components) that need to be packaged at build time of the consuming app, so that it all works correctly with the CSS. I have a webpack configuration that determines which files are external and which are not. I did not expect universal-webpack to ignore and override this.
For now, I've fixed the version of universal webpack to 0.3.3, but I hope there is a way to get around this issue.

Yes, it's not bundling external packages as part of the server-side build because they're all available in node_modules.
Otherwise a developer can use exclude_from_externals option to make certain dependencies not external and bundle them on server side.

@halt-hammerzeit Thanks, adding a regex to exclude_from_externals fixed the issue!


Event/Variant Confusion

The usage of Event and Variant, while useful to us, might be confusing to end users. There needs to be some cleanup in this regard. Most likely solution is to remove references to what we currently call Variants (since these are essentially non unique row counts) and rename Events with Variants.
This does not need to rename back-end objects, just front-end  terminology.

Still needs to be done for stats.xhtml


Unable to query on two indexed fields with 1 being date [Datastore]

Environment details

OS: Windows 10
Node.js version:  6.11.2
npm version: 3.10.10
google-cloud/datastore: "^1.1.0",

I am unable to pass in multiple query filters if one of them is checking for a date.  It gives the error Your Datastore does not have the composite index (developer-supplied) required for this query.  It also produces this result if I try to sort based on the date.
In the indexes tab inside Google Cloud console there is nothing.  Any information I try to find about this it talks about having your index composites inside index.yaml.  With google-cloud-node I do not have this yaml file, and don't think I need it?  If I do where would I need to connect it.
Query filter by date + _id (both indexed) not working

Querying date alone works

Querying matched _id works

Multiple query filters do work

Check out the Index docs! They will do a better job than I can explaining what a file looks like, when/why you need it, and how to use the gcloud sdk to create them.


How to get message metadata in isolated Azure functions v4 - Queue Trigger

I am following on a possible upgrade of azure function runtime from v3 to v4 with dotnet. While doing so, I am testing out the isolated option for the project. However I am unable to get message metadata such as DequeueCount, MessageId etc in the queue trigger.
Previously with in-process option, I used to bind CloudQueueMessage but that doesn't seem to work in the isolated mode. Doing so, throws and error -
Cannot convert input parameter 'myQueueItem' to type 'Microsoft.WindowsAzure.Storage.Queue.CloudQueueMessage' from type 'System.String'

This was my isolated queue function binding
[Function("TestApp")]
public void Run([QueueTrigger("sample-queue", Connection = "")] CloudQueueMessage myQueueItem, FunctionContext context)

After looking for a while, I think here it says that, in isolated process we can only bind string. Simple JSON - Object also works.

Is there any way to get these message metadata (members of the CloudQueueMessage) in the isolated azure function?
Thanks.

This feature (rich binding) is not yet available in v4 isolated dotnet. We have #1008 which tracks adding support for these features.


ItemsRepeater is broken when used inside a LayoutTransformControl

Describe the bug
I'm having an issue using the ItemsRepeater inside a LayoutTransformControl.
I'm using the LayoutTransformControl to zoom in and out of the items. It seems that doing so breaks the ItemsRepeater. When I zoom out, objects that should be visible are not displayed. When I zoom in and scroll, some items become invisible.
I asked the question on the Avalonia Gitter chat, and another user (Steve) noticed that it also happens with an ItemsControl with a VirtualizingStackPanel but works as expected without virtualization.
To Reproduce
I have created a minimal app to reproduce the issue: https://github.com/BobLd/ItemsRepeaterLayoutTransform/tree/master
Expected behavior
ItemsRepeater should still work as exepected even after LayoutTransform is changed.
Screenshots
If applicable, add screenshots to help explain your problem.
Environment

OS: Windows 10
Avalonia-Version: 11.0.6

Additional context
Might be related to #12432

Also happens on nightly (11.1.999-cibuild0042757-beta).

I managed to find a fix for that: putting the ItemsRepeater inside a Grid fixes the problem I was having with the zooming. I've updated the minimal app to reflect that.
I'm closing the issue as it now works on my side. Thanks @stevemonaco for helping in diagnosing the bug.


dracut: add ignition systemd generator

This generator looks for the flag "coreos.ignition.force" and will
enable ignition.service if found.

Still testing...

Why are you using a generator for this?
Can't we have a unit with ConditionKernelCommandLine=coreos.ignition.force that starts ignition?

Umm, no real reason. I hadn't thought about using another unit. Do you think it's preferable to use your suggestion?

vs. adding a shell script with yet another implementation of /proc/cmdline parsing?  yes.

that's fair

I favor the generator approach, if you want to minimize the the copies of getarg or what not then we can split into a lib file that gets sourced or consolidate the generators into one.
Even when a unit is disabled by a condition it still influences the dependency tree and ordering of units and will activate dependencies like networkd.

We figured that out :/ https://github.com/systemd/systemd/issues/985

Yeah, the generator is preferable given the limitations of the Conditions in systemd units.

LGTM


Added Mixer, Discord, Slack and Reddit (partially)

Description
I've added Mixer, Discord, Slack, and Reddit providers.
The OAuth flow for Reddit is working but I can't get the profile.
It keeps throwing 401 unauthorized and I'm not really sure why yet.
Might look at it later or you can give it a shot (it's probably something small).
I also added a random value to the state parameter because Reddit doesn't work without one... This can be a temporary solution for now. While writing this it crosses my mind that I was maybe also able to add the state parameter to the config object itself. You can edit it however you like.
Type of change
New feature (non-breaking change which adds functionality)

Oh wow, this looks amazing!
Good catch on the state parameter. I hadn't added that as I don't fully understand how it is used by providers and wasn't sure if it's a thing that might need to be tracked for some of them.
It's not currently documented, but an options.secret value is currently auto-generated if not specified and is used as a salt for hashes (etc). We could pass in the 'options' param to the function there (or even just the secret) if need? If this works though then even better!
Wonder what is up with that Reddit profile call. Maybe it wants an extra parameter or something in the header…
I'm not sure why rebasing is disabled for me on this PR, but I can squash and merge this in as if you want, or I can leave it for a bit if you'd like to keep adding stuff to it. I don't expect I'll be touching the oAuth stuff or the providers (as, other than the issue you've addressed, I think it's working okay) so happy either way!

You can merge it if you want it's up to you. I'll add some more providers the coming week and take a look at that Reddit profile error. Maybe you can leave this one open until I've added more providers?

I've sent you an invite to be a maintainer so you can merge them in when you want without having to jump through hoops if you like! 😀
No preferences on other providers - Facebook would be nice maybe? - these are great! I didn't know there was Slack oAuth integration.

^ Sorry about introducing conflicts, I think running npm run lint should magically resolve them.
If not, am happy to take the versions in your repo and discard changes currently in my next-auth-2 branch; it looks like it's just conflicting over formatting (and only actual meaningful code changes are in your branch).
This was slightly annoying of me to do (sorry) but I've found using the linter really helpful, as it found a load of unnecessary promise cruft I'd written in the adapter, and was able to remove about 50 lines from a ~250 line file.

Oh I just realised with the GitHub UI I can amend changes in your commit (somehow, magically) to fix the issues. :D If you don't mind, I would love to merge this in ASAP, even if not complete!
Is that okay with you?
I have other changes I would like to make in providers, and I would hate for it to get out of date :-)

Hi, didn't have time to continue with this yet. You can merge it. I'll add more providers and  some docs  soon 😊

Awesome, thank you!


app thumbnail uploads result in broken links on spee.ch

@billbitt commented on Tue Jul 03 2018
for thumbnail publishes made via the app (from macs?), the thumbnail link appears or is broken on spee.ch.
steps to reproduce:

open the LBRY app
go to publish and select a video
select an image to upload for the thumbnail
when the thumbnail is done being published, click the 'view on spee.ch' link
the page will show a broken image and display the img alt instead of the image

expected outcome:

when clicking the 'view on spee.ch' link, the asset should be displayed on the page.

example: https://spee.ch/4b1567a9015c5d97739970213346bb516a2219a6/rBtfkpiLmVMrUqxTNYcHOe4z.png
notes:

the images do seem to unfurl in slack.  i.e. they appear to be served properly to slack
the image is (sometimes?) served properly to the app after the video is published.  It seems this has varied, and in some trials the thumbnails show, while in others they do not.
this issue does not seem to happen for .jpg files, but only for .gif and .png

@billbitt commented on Tue Jul 03 2018
@tzarebczan @seanyesmunt fyi

@billbitt commented on Tue Jul 03 2018
I'm thinking this has to do with the publish route's middleware parsing the formdata from the publish request.  Perhaps starting the publish before it has all of the file, or something like that.

@billbitt commented on Tue Jul 03 2018
@tzarebczan do you have an example uri for a video that was published from the app and did work correctly? I'd like to compare.  Otherwise, I'll do a test upload from my app.

@tzarebczan commented on Tue Jul 03 2018
Here's a JPG that worked: https://spee.ch/37cd0ab1b52b55b4eb04849fb9f6769c51180184/kCutEbo5xJeeOZLJOPHBVmQT.jpg

@billbitt commented on Tue Jul 03 2018
ugh, I meant to make this issue on lbryio/spee.ch not lbryi/grooming

I'd like to see if attaching the file to the form data as a File rather than a Blob has any impact.  I made a branch here:
If the issue continues, the next step would be to see if there is something going on with Blobs/Files created by Macs (assuming the issue is still located there) and the middleware being used to read the form data: https://www.npmjs.com/package/connect-multiparty.
The next step after that would be to see if there is something with how spee.ch is storing and accessing the file data (like the path), however I doubt that would be an issue if there isn't something else happening upstream.
Lastly, it is possible the file is being uploaded and published successfully but then deleted after the publish is complete.  That could explain why spee.ch has the file records and published successfully, but then was not able to find the file to serve it.  It could also explain why the file showed up later, if something triggered spee.ch to redownload the file.  I would like to look at a specific case of a file that did not appear immediately but then did later.

will do @kauffj.  I've updated the comments above.  At first we thought this was correlated to uploads coming from macs or certain file types, which is why I thought it might be related to the upload process, the middleware processing the uploaded file, or the lbry publishing.  However, this seems to happen across windows & mac, and seems to happen to all file types except jpg.  The files do seem to publish successfully and store on the spee.ch server successfully, so I think this is a much simpler issue that has to do with spee.ch and the serving or displaying of the files.  I've got a couple ideas, but will circle back with @skhameneh if I can't solve quickly.

@kauffj @skhameneh one issue that I am having is that I cannot seem to reproduce the bug when pointing my lbry app to publish via dev1.spee.ch or staging.spee.ch.  When I do so, I can view the images without error.  This should be a clue, but I'm having trouble figuring out what it means.  The servers are running the same spee.ch code, the differences (that come immediately to mind) would be their lbry wallet or the presence of cloudflare on production.  I am not sure how any of those differences would explain this issue, however.
On the other hand, I did narrow down where the bug is occurring on production.
After publishing on production, the file displays fine while viewing from the a shortened direct url (https://spee.ch/7/webapp-png-test.png) or the long details url (https://spee.ch/734f5cb226f7b3796e304c255bfe44d3ccae5aa2/webapp-png-test).

However, once I visit the long direct url, the link breaks for subsequent visits, including the short urls: https://spee.ch/1b99322abcfbf0484582637df20455fce74702c6/webapp-png-test-3.png

https://spee.ch/1/webapp-png-test-3.png

This explains why they are immediately showing as broken from the app, because the app takes the user directly to the long direct url.
Conclusion:
It appears that visiting the long, direct url is what triggers the error and stops spee.ch from subsequently serving the asset to any of the urls that display the asset.  So far, this only happens on production, and not on dev1.spee.ch or staging.spee.ch.  I am not sure what is causing this yet, but perhaps I could do some live debugging with @skhameneh next week.  If either of you have any thoughts DM me or leave them here.

It appears that the URL for the embedded image is returning a full HTML resource rather than just the image.

(Deleted incorrect comment.)

Is the file still on disk?
Don't be afraid to debug in production if production is broken and the only place a bug is happening.
When you figure out what is causing the environment difference, make sure to fix that as well.

Debugged this this morning with @kauffj and @skhameneh.  It seems this was a result of cloud-flare serving an html document instead of an image or video for the long url direct link.  This is a result of using one url for two purposes.


Buy badges

Once #5 is clarified, buy the badges.

I just put in the order. Now we wait for shipping, customs and so on.


[Bug] First tab of TabsWidget doesn't load.

Description
The first tab remains in loading state.
Steps to reproduce the behaviour:

Drop a new tab widget

Important Details

Version: release
OS: N/A
Browser N/A

There's a bug in widget naming code. A new child doesn't account for it's sibling created in the previous run.
As a result, both tabs of the TabsWidget end up getting a CanvasWidget with the name Canvas1.
This bug was getting hidden by the fact that we used to depend on widgetName to lookup widgets from the evaluated tree.
As part of subtree fixes, we'd switched to using widgetId instead of widgetName, which made the bug visible.

To fix this issue, we have to:

correct the naming behaviour
run a migration on existing tabs

Should we enforce uniqueness of widget names across widgets?

There's a bug in widget naming code. A new child doesn't account for it's sibling created in the previous run.
As a result, both tabs of the TabsWidget end up getting a CanvasWidget with the name Canvas1.
This bug was getting hidden by the fact that we used to depend on widgetName to lookup widgets from the evaluated tree.
As part of subtree fixes, we'd switched to using widgetId instead of widgetName, which made the bug visible.

To fix this issue, we have to:

correct the naming behaviour
run a migration on existing tabs

Should we enforce uniqueness of widget names across widgets?


--version info missing when git-xargs is installed via go get

The CircleCI job for git-xargs currently sets the main go package's VERSION variable to the $CIRCLE_TAG which is either the branch name or the tag name.
This means that when we build and publish binaries through CircleCI and programmatically attach them to a new release, they correctly have their internal VERSION value set to the tag of the release and, therefore, when you run git-xargs --version against them you get back the associated tag, e.g., git-xargs version v0.0.5.
However, when you install git-xargs via go get github.com/gruntwork-io/git-xargs, the package is downloaded from Github and then built in your defined or default $GOBIN directory. In this case, the main package's VERSION value remains unset, so running git-xargs with the  --version flag returns an error.
One initial idea would be to update a VERSION file in the repo each time we do a release - so that the HEAD of the default branch contains a VERSION file which always matches the latest release's tag.

Another option is to update the version logic in go-commons to look up the latest Git ref or tag if the version param isn't set.

Another option is to update the version logic in go-commons to look up the latest Git ref or tag if the version param isn't set.

Ah yeah that would probably be easier to maintain going forward than having to thrash on a file in the repo itself.

This remains an issue to my knowledge, but I won't be able to address it myself anytime soon and the issue is stale.


Protocol

@pwnwriter It would be much more useful if it also take screenshots on both protocols http / https and also have flags like retry and flag to define custom ports

Hi, i'm sorry  for the delayed response. But it works with both http(s) protocol, about defining ports. i'll loook into it.
Ex. IMG

@pwnwriter @jaikishantulswani
As I mentioned in the issue #22 hereit looks like chrome upgrades the requests to https if the website's server responds with 301. So even if you try to modify chromium and not upgrade it to https, you wont get any real content of the website, it will just be a page which says 301 a page has been permanently moved to a new location.
So I think we can not do anything on our side/chromium side at all.


Player does not exist error

Hi guys,
I get this error
Player does not exist. It has not been summoned yet into a voice channel.  Use !summon to summon it to your voice channel.
autosummon is enabled (see config below) and the bot is also joining my voice channel. If I want him to play a song the above shown error is dropped
[Credentials]
; The bot needs its own account to run on (not yours)
Username = XX
Password = XX

[Permissions]
; This need to be your id, not the bot's id.  The bot does not own the bot.  You do.
OwnerID = 14XXX01

[Chat]
; Change this if you don't want commands to trigger another bot
CommandPrefix = !

[MusicBot]
; This option is not implemented yet
DaysActive = 0

; Only allow whitelisted users to use commands
WhiteListCheck = no

; Skips required to skip a song.  Whichever is lower will be used.
; Skip ratio refers to the percent of non-deafened, non-owner users
; in the voice channel needed to skip a song.
SkipsRequired = 7
SkipRatio = 0.5

; If no, delete videos after they've played, if the video
; isn't still in the queue, to avoid redownloading it
SaveVideos = yes

; Mentions the user who queued a song when the song plays
NowPlayingMentions = no

; On start up, if the owner is in a voice channel, join that channel
AutoSummon = yes

; Play random songs when nothing is queued
UseAutoPlaylist = yes

You have to give the other account an invite link

Does it work if you turn off autosummon, manually summon it, and play a song?

No, if I manually summon it, it throws the error that multiple servers are not allowed

You bot bot have access to join in voice channel, where you summon it?

You stay in channel and use command?

If you do all right and also need help, try to use my code (currently not work at 100%)
Find bot.py, backup it, open and find this 2 lines:

if self.voice_clients:
            raise CommandError("Multiple servers not supported at this time.")

Then replace it to:
if self.voice_clients:
            server = channel.server #X4: Define server
            channel = None #X4: Set null, because undefined
            for channel in server.channels: #X4: List of channels on the server
                if discord.utils.get(channel.voice_members, id=author.id): #X4: Searching user in channels
                    break #X4: Stop at current seleced channel and go next
            player = await self.get_player(channel, create=True) #X4: Check player
            if channel.server.id in self.players: #X4: Check same server (true) or other (else)
                await self.get_voice_client(channel) #X4: This does not work on same server, need to fix!
            else: #X4: Else
                await self.get_voice_client(channel) #X4: Move bot to other new server and in new channel
            if player.is_stopped: #X4: Check if player stopped (practically almost stopped)
                player.play() #X4: Send "play" state
            if not player.playlist.entries and self.config.auto_playlist: #X4: Check player for tracks. New summoned player is empty.
                song_url = choice(self.backuplist) #X4: Choose random track from auto playlist
                await player.playlist.add_entry(song_url, channel=None, author=None) #X4: Send chosen track to player and start playing music

Now save file, and try to summon again. With this code bot ignore Multiple server warning and have some algorytm to join on server.
But be worry, I don't finish this code and it also does not have exceptions. Bot need to be connected on the same servr, where are you, you need to stay in channel, bot need to be able to join in channel and then you can use command !summon.

Thanks for your code. I will give it a try this evening (Central European Time)
P.S.: It's time to learn Python :D

When I delete this two lines and add the ones you posted, I'm getting this kind of error:
Traceback (most recent call last):
  File "run.py", line 202, in <module>
    main()
  File "run.py", line 181, in main
    from musicbot import MusicBot
  File "/home/daniel/MusicBot-develop/musicbot/__init__.py", line 1, in <module>
    from .bot import MusicBot
  File "/home/daniel/MusicBot-develop/musicbot/bot.py", line 461
    player = await self.get_player(channel, create=True) #X4: Check player

Check agian:
async def handle_summon(self, channel, author):
        """
        Usage {command_prefix}summon
        This command is for summoning the bot into your voice channel [but it should do it automatically the first time]
        """

        if self.voice_clients:
            #raise CommandError("Multiple servers not supported at this time. / X4: In queue to update")

            server = channel.server #X4: Define server
            channel = None #X4: Set null, because undefined
            for channel in server.channels: #X4: List of channels on the server
                if discord.utils.get(channel.voice_members, id=author.id): #X4: Searching user in channels
                    break #X4: Stop at current seleced channel and go next
            player = await self.get_player(channel, create=True) #X4: Check player
            if channel.server.id in self.players: #X4: Check same server (true) or other (else)
                await self.get_voice_client(channel) #X4: This does not work on same server, need to fix!
            else: #X4: Else
                await self.get_voice_client(channel) #X4: Move bot to other new server and in new channel
            if player.is_stopped: #X4: Check if player stopped (practically almost stopped)
                player.play() #X4: Send "play" state
            if not player.playlist.entries and self.config.auto_playlist: #X4: Check player for tracks. New summoned player is empty.
                song_url = choice(self.backuplist) #X4: Choose random track from auto playlist
                await player.playlist.add_entry(song_url, channel=None, author=None) #X4: Send chosen track to player and start playing music

Thanks, with your code it's working

Good to see it, but try to find a root of problem, because I can start bot without this code now. This code only for resummon.


Add branch-based versioning of projects to help us sandbox better as we develop

Fix #255
Projects are hidden in menus if they were created on a different branch than the current one (all projects are still accessible by URL)

How much extra work would it be to mark matching projects with a green checkmark, etc., and non-matching ones with a red X, rather than simply hide all non-matching ones? I ask because I can imagine this causing the opposite problem to the one it solves - someone switches to a new topic branch and suddenly they can't see any projects, even ones that will work because the metadata schema isn't going to change on that topic.

Also, what happens if a user doesn't have git on their path (because, e.g., it isn't installed)?

It would be a little bit of work... actually, it would make sense to include a (tiny) project version compatibility indicator as part of the glyph redesign in #164. For now, to use an old project on a new branch, the URLs will still work for any project—they just won't show up in the menu.
For now, the "version" comes back as master if the branch is actually master, release, or if git status fails for whatever reason (including the case where git isn't installed). In the future, I'm imagining an actual number to come back in these three scenarios.

Handling of nonexistent git sounds good.
Alex and I just discussed in meatspace, and he'll put a crude stopgap version compatibility indicator into the project icons as part of this PR, then rework that as necessary as part of #164. When that's done I can review one more time (since the code as is looks good and I'm just concerned about unconditionally hiding non-matching projects).

Turns out this wasn't as tricky as I thought. Great idea!

[Current coverage][cc-pull] is 63.79%

Merging [#259][cc-pull] into [master][cc-base-branch] will not change coverage

@@             master       #259   diff @@
==========================================
  Files            21         21
  Lines           580        580
  Methods           0          0
  Messages          0          0
  Branches          0          0
==========================================
  Hits            370        370
  Misses          210        210
  Partials          0          0

Powered by Codecov. Last updated by [d9a3383...b13d77c][cc-compare]
[cc-base-branch]: https://codecov.io/gh/Kitware/candela/branch/master?src=pr
[cc-compare]: https://codecov.io/gh/Kitware/candela/compare/d9a3383a2386aedf68dc1c1957584c99755f80e0...b13d77c4db2e59bdecf829d974959d9d3aec4f16
[cc-pull]: https://codecov.io/gh/Kitware/candela/pull/259?src=pr

Very nice!
Do you think it makes more sense to mark the non-conforming projects with a warning, or the conforming ones with a green OK sign? I would think green OK sign because that will be the thing that draws your eye, but since you're getting the most benefit out of this feature I'll defer to you. Just let me know so I can ok this branch.

Ideally, a deployed app shouldn't have to worry about displaying any version information (we'd want to do something more formal like @jeffbaumes proposed to gracefully handle forward/back conversion)—a deployment of master or release should never contain our weird branch projects in the first place. My thoughts are that this indicator adds clutter that we really only care about as we're developing it. So for now I think it's best to just show a warning when there's a potential version conflict.

Oh ok I see. You wouldn't want all projects showing up with the green indicator on master.
Sounds good! LGTM.


refactor(lint): @typescript/prefer-optional-chain

Codecov Report

Merging #65 (39fb826) into master (26a52c6) will increase coverage by 0.15%.
The diff coverage is 66.19%.

@@            Coverage Diff             @@
##           master      #65      +/-   ##
==========================================
+ Coverage   32.83%   32.99%   +0.15%
==========================================
  Files          59       59
  Lines        3170     3167       -3
  Branches      494      491       -3
==========================================
+ Hits         1041     1045       +4
+ Misses       1965     1958       -7
  Partials      164      164

Impacted Files
Coverage Δ

src/WSManProcessor.ts
4.84% <0.00%> (ø)

src/actions/ACMActivator.ts
43.96% <0.00%> (ø)

src/actions/CCMActivator.ts
45.09% <0.00%> (ø)

src/actions/CIRAConfigurator.ts
6.92% <0.00%> (+0.10%)
:arrow_up:

src/repositories/AMTDeviceVaultRepository.ts
10.25% <0.00%> (ø)

src/Validator.ts
56.08% <33.33%> (ø)

src/ProfileManager.ts
63.20% <66.66%> (ø)

src/repositories/CiraConfigDbFactory.ts
46.66% <66.66%> (ø)

src/repositories/NetConfigDbFactory.ts
46.66% <66.66%> (ø)

src/DomainCredentialManager.ts
79.16% <75.00%> (ø)

... and 10 more

Continue to review full report at Codecov.

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

Codecov Report

Merging #65 (39fb826) into master (26a52c6) will increase coverage by 0.15%.
The diff coverage is 66.19%.

@@            Coverage Diff             @@
##           master      #65      +/-   ##
==========================================
+ Coverage   32.83%   32.99%   +0.15%
==========================================
  Files          59       59
  Lines        3170     3167       -3
  Branches      494      491       -3
==========================================
+ Hits         1041     1045       +4
+ Misses       1965     1958       -7
  Partials      164      164

Impacted Files
Coverage Δ

src/WSManProcessor.ts
4.84% <0.00%> (ø)

src/actions/ACMActivator.ts
43.96% <0.00%> (ø)

src/actions/CCMActivator.ts
45.09% <0.00%> (ø)

src/actions/CIRAConfigurator.ts
6.92% <0.00%> (+0.10%)
:arrow_up:

src/repositories/AMTDeviceVaultRepository.ts
10.25% <0.00%> (ø)

src/Validator.ts
56.08% <33.33%> (ø)

src/ProfileManager.ts
63.20% <66.66%> (ø)

src/repositories/CiraConfigDbFactory.ts
46.66% <66.66%> (ø)

src/repositories/NetConfigDbFactory.ts
46.66% <66.66%> (ø)

src/DomainCredentialManager.ts
79.16% <75.00%> (ø)

... and 10 more

Continue to review full report at Codecov.

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